diff --git a/.github/bootstrap.sh b/.github/bootstrap.sh new file mode 100755 index 00000000000..603b4310d66 --- /dev/null +++ b/.github/bootstrap.sh @@ -0,0 +1,173 @@ +#!/bin/bash +# shellcheck disable=SC2164 + +# 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. + +# This is a next-gen bootstrap which skips Python and Java tests, +# and does not use the VTROOT/VTTOP layout. +# +# My original intention was to use the same bootstrap.sh and gate +# for new features, but it has turned out to be difficult to do, +# due to the way that Docker cache works in the CI environment. + +function fail() { + echo "ERROR: $1" + exit 1 +} + +[[ "$(dirname "$0")" = "." ]] || fail "bootstrap.sh must be run from its current directory" + +# Create main directories. + +VTROOT="$PWD" + +mkdir -p dist +mkdir -p bin +mkdir -p lib +mkdir -p vthook + +source ./dev.env + +go version &>/dev/null || fail "Go is not installed or is not on \$PATH" +goversion_min 1.12 || fail "Go is not version 1.12+" + +# Set up required soft links. +# TODO(mberlin): Which of these can be deleted? +ln -snf "$VTROOT/py" "$VTROOT/py-vtdb" +ln -snf "$VTROOT/go/vt/zkctl/zksrv.sh" "$VTROOT/bin/zksrv.sh" +ln -snf "$VTROOT/test/vthook-test.sh" "$VTROOT/vthook/test.sh" +ln -snf "$VTROOT/test/vthook-test_backup_error" "$VTROOT/vthook/test_backup_error" +ln -snf "$VTROOT/test/vthook-test_backup_transform" "$VTROOT/vthook/test_backup_transform" + +# git hooks are only required if someone intends to contribute. + +echo "creating git hooks" +mkdir -p "$VTROOT/.git/hooks" +ln -sf "$VTROOT/misc/git/pre-commit" "$VTROOT/.git/hooks/pre-commit" +ln -sf "$VTROOT/misc/git/commit-msg" "$VTROOT/.git/hooks/commit-msg" +git config core.hooksPath "$VTROOT/.git/hooks" + +# install_dep is a helper function to generalize the download and installation of dependencies. +# +# If the installation is successful, it puts the installed version string into +# the $dist/.installed_version file. If the version has not changed, bootstrap +# will skip future installations. +function install_dep() { + if [[ $# != 4 ]]; then + fail "install_dep function requires exactly 4 parameters (and not $#). Parameters: $*" + fi + local name="$1" + local version="$2" + local dist="$3" + local install_func="$4" + + version_file="$dist/.installed_version" + if [[ -f "$version_file" && "$(cat "$version_file")" == "$version" ]]; then + echo "skipping $name install. remove $dist to force re-install." + return + fi + + echo "installing $name $version" + + # shellcheck disable=SC2064 + trap "fail '$name build failed'; exit 1" ERR + + # Cleanup any existing data and re-create the directory. + rm -rf "$dist" + mkdir -p "$dist" + + # Change $CWD to $dist before calling "install_func". + pushd "$dist" >/dev/null + # -E (same as "set -o errtrace") makes sure that "install_func" inherits the + # trap. If here's an error, the trap will be called which will exit this + # script. + set -E + $install_func "$version" "$dist" + set +E + popd >/dev/null + + trap - ERR + + echo "$version" > "$version_file" +} + + +# +# 1. Installation of dependencies. +# + +# Wrapper around the `arch` command which plays nice with OS X +function get_arch() { + case $(uname) in + Linux) arch;; + Darwin) uname -m;; + esac +} + +# Install protoc. +function install_protoc() { + local version="$1" + local dist="$2" + + case $(uname) in + Linux) local platform=linux;; + Darwin) local platform=osx;; + esac + + case $(get_arch) in + aarch64) local target=aarch_64;; + x86_64) local target=x86_64;; + *) echo "ERROR: unsupported architecture"; exit 1;; + esac + + wget https://github.com/protocolbuffers/protobuf/releases/download/v$version/protoc-$version-$platform-${target}.zip + unzip "protoc-$version-$platform-${target}.zip" + ln -snf "$dist/bin/protoc" "$VTROOT/bin/protoc" +} +protoc_ver=3.6.1 +install_dep "protoc" "$protoc_ver" "$VTROOT/dist/vt-protoc-$protoc_ver" install_protoc + +# Download and install etcd, link etcd binary into our root. +function install_etcd() { + local version="$1" + local dist="$2" + + case $(uname) in + Linux) local platform=linux; local ext=tar.gz;; + Darwin) local platform=darwin; local ext=zip;; + esac + + case $(get_arch) in + aarch64) local target=arm64;; + x86_64) local target=amd64;; + *) echo "ERROR: unsupported architecture"; exit 1;; + esac + + download_url=https://github.com/coreos/etcd/releases/download + file="etcd-${version}-${platform}-${target}.${ext}" + + wget "$download_url/$version/$file" + if [ "$ext" = "tar.gz" ]; then + tar xzf "$file" + else + unzip "$file" + fi + rm "$file" + ln -snf "$dist/etcd-${version}-${platform}-${target}/etcd" "$VTROOT/bin/etcd" +} +install_dep "etcd" "v3.3.10" "$VTROOT/dist/etcd" install_etcd + +echo +echo "bootstrap finished" diff --git a/.github/workflows/local-example.yml b/.github/workflows/local-example.yml new file mode 100644 index 00000000000..03a358d8161 --- /dev/null +++ b/.github/workflows/local-example.yml @@ -0,0 +1,41 @@ +name: Local Example +on: [push, pull_request] +jobs: + + build: + name: Build + runs-on: ubuntu-latest + steps: + + - name: Set up Go + uses: actions/setup-go@v1 + with: + go-version: 1.13 + + - name: Check out code + uses: actions/checkout@v1 + + - name: Get dependencies + run: | + sudo apt-get install -y mysql-server mysql-client make unzip g++ etcd curl git wget + 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 + + - name: Run bootstrap.sh + run: | + echo "Copying new bootstrap over location of legacy one." + cp .github/bootstrap.sh . + ./bootstrap.sh + + - name: Build + run: | + GOBIN=$PWD/bin make build + + - name: Run Local Example + run: | + export PATH=$PWD/bin:$PATH + VTDATAROOT=/tmp/vtdataroot VTTOP=$PWD VTROOT=$PWD test/local_example.sh + diff --git a/.travis.yml b/.travis.yml index 0f65b297ea8..733f8213a21 100644 --- a/.travis.yml +++ b/.travis.yml @@ -17,7 +17,7 @@ # # Open TODOs: # - Re-add travis/check_make_proto.sh, ideally as part of test/config.json. -# - Add a presubmit which checks that vendor/vendor.json is the same as in the Docker image. This will prevent people from making changes to it without pushing new bootstrap Docker images. +# - Add a presubmit which checks that if bootstrap has changed, and docker image is out of date. # sudo is required because we run Docker in our builds. # See: https://docs.travis-ci.com/user/docker/ diff --git a/ADOPTERS.md b/ADOPTERS.md index f56f843a280..871f12640a8 100644 --- a/ADOPTERS.md +++ b/ADOPTERS.md @@ -1,15 +1,21 @@ This is an alphabetical list of known adopters of Vitess. Some have already gone into production, and others are at various stages of testing. -* [YouTube](https://youtube.com) * [Axon](https://axon.com) * [BetterCloud](https://bettercloud.com) +* [CloudSigma](https://www.cloudsigma.com/) * [FlipKart](https://flipkart.com) +* [GitHub](http://github.com/) * [HubSpot](https://product.hubspot.com/) * [JD](https://jd.com/) +* [New Relic](https://newrelic.com) * [Nozzle](https://nozzle.io) +* [opensooq.com](https://www.opensooq.com/) +* [Peak Games](https://peak.com/) * [Pinterest](https://pinterest.com) * [Pixel Federation](https://pixelfederation.com) * [Quiz of Kings](https://quizofkings.com) * [Slack](https://slack.com) * [Square](https://square.com) * [Stitch Labs](https://stitchlabs.com) +* [Weave](https://www.getweave.com) +* [YouTube](https://youtube.com) diff --git a/GOVERNANCE.md b/GOVERNANCE.md index 1a8db8bb2fd..1ddf1df91cc 100644 --- a/GOVERNANCE.md +++ b/GOVERNANCE.md @@ -21,7 +21,7 @@ Users who continue to engage with the project and its community will often becom ## Contributors -Contributors will be added to the [Collaborators list](https://github.com/vitessio/vitess/settings/collaboration). +Contributors will be added to the [Contributors list](https://github.com/vitessio/vitess/graphs/contributors). Contributors are community members who contribute in concrete ways to the project. Anyone can become a contributor. There is no expectation of commitment to the project, no specific skill requirements and no selection process. @@ -42,7 +42,6 @@ Contributors engage with the project through the issue tracker, mailing list, th As contributors gain experience and familiarity with the project, their profile within, and commitment to, the community will increase. At some stage, they may find themselves being nominated for committership. ## Committers -Committers will be added to the [committers list](https://github.com/orgs/youtube/teams/vitess-committers) and the [pullapprove list](https://github.com/vitessio/vitess/blob/master/.pullapprove.yml). Committers are community members who have shown that they are committed to the continued development of the project through ongoing engagement with the community. Committership allows contributors to more easily carry on with their project related activities by giving them direct access to the project’s resources. That is, they can make changes directly to project outputs, without having to submit changes via patches. @@ -66,8 +65,6 @@ A committer who shows an above-average level of contribution to the project, par ## Project management committee -PMC members will be added to the [list of administrators](https://github.com/orgs/youtube/teams/vitess-admin). - The current list of PMC members and their github handles are: * Alain Jobart (alainjobart) diff --git a/MAINTAINERS.md b/MAINTAINERS.md index 7b527586cb0..a11a8e6fc83 100644 --- a/MAINTAINERS.md +++ b/MAINTAINERS.md @@ -2,6 +2,8 @@ This page lists all active maintainers and their areas of expertise. This can be The following is the full list, alphabetically ordered. +* Andres Taylor ([systay](https://github.com/systay)) antaylor@squareup.com +* Anthony Yeh ([enisoc](https://github.com/enisoc)) enisoc@planetscale.com * Dan Kozlowski ([dkhenry](https://github.com/dkhenry)) koz@planetscale.com * David Weitzman ([dweitzman](https://github.com/dweitzman)) dweitzman@pinterest.com * Deepthi Sigireddi ([deepthi](https://github.com/deepthi)) deepthi@planetscale.com @@ -11,28 +13,29 @@ The following is the full list, alphabetically ordered. * Leo X. Lin ([leoxlin](https://github.com/leoxlin)) llin@hubspot.com * Michael Demmer ([demmer](https://github.com/demmer)) mdemmer@slack-corp.com * Michael Pawliszyn ([mpawliszyn](https://github.com/mpawliszyn)) mikepaw@squareup.com +* Morgan Tocker ([morgo](https://github.com/morgo)) morgan@planetscale.com * Rafael Chacon ([rafael](https://github.com/rafael)) rchacon@slack-corp.com * Sugu Sougoumarane ([sougou](https://github.com/sougou)) sougou@planetscale.com ## Areas of expertise ### General Vitess -sougou, demmer, rafael, dweitzman, tirsen +sougou, demmer, rafael, dweitzman, tirsen, morgo, enisoc ### Builds -dkhenry +dkhenry, morgo ### Resharding -sougou, rafael, tirsen, dweitzman +sougou, rafael, tirsen, dweitzman, systay ### Parser -sougou, dweitzman, deepthi +sougou, dweitzman, deepthi, systay -### Backups -deepthi, rafael +### Cluster Management +deepthi, rafael, enisoc ### Java mpawliszyn, leoxlin, harshit-gangal ### Kubernetes -derekperkins, dkhenry +derekperkins, dkhenry, enisoc diff --git a/Makefile b/Makefile index f8ae541f167..d0581272a65 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -# Copyright 2017 Google Inc. +# 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. @@ -18,7 +18,7 @@ MAKEFLAGS = -s # Since we are not using this Makefile for compilation, limiting parallelism will not increase build time. .NOTPARALLEL: -.PHONY: all build build_web test clean unit_test unit_test_cover unit_test_race integration_test proto proto_banner site_test site_integration_test docker_bootstrap docker_test docker_unit_test java_test reshard_tests +.PHONY: all build build_web test clean unit_test unit_test_cover unit_test_race integration_test proto proto_banner site_test site_integration_test docker_bootstrap docker_test docker_unit_test java_test reshard_tests e2e_test e2e_test_race all: build @@ -81,11 +81,6 @@ cleanall: # directories created by bootstrap.sh # - exclude vtdataroot and vthook as they may have data we want rm -rf ../../../../bin ../../../../dist ../../../../lib ../../../../pkg - # keep the vendor.json file but nothing else under the vendor directory as it's not actually part of the Vitess repo - rm -rf vendor/cloud.google.com vendor/github.com vendor/golang.org vendor/google.golang.org vendor/gopkg.in - # other stuff in the go hierarchy that is not under vendor/ - rm -rf ../../../golang.org ../../../honnef.co - rm -rf ../../../github.com/golang ../../../github.com/kardianos ../../../github.com/kisielk # Remind people to run bootstrap.sh again echo "Please run bootstrap.sh again to setup your environment" @@ -93,6 +88,10 @@ unit_test: build echo $$(date): Running unit tests go test $(VT_GO_PARALLEL) ./go/... +e2e_test: build + echo $$(date): Running endtoend tests + go test $(VT_GO_PARALLEL) ./go/.../endtoend/... + # Run the code coverage tools, compute aggregate. # If you want to improve in a directory, run: # go test -coverprofile=coverage.out && go tool cover -html=coverage.out @@ -102,6 +101,9 @@ unit_test_cover: build unit_test_race: build tools/unit_test_race.sh +e2e_test_race: build + tools/e2e_test_race.sh + .ONESHELL: SHELL = /bin/bash @@ -115,13 +117,9 @@ site_integration_test: java_test: go install ./go/cmd/vtgateclienttest ./go/cmd/vtcombo - mvn -f java/pom.xml clean verify + mvn -f java/pom.xml -B clean verify -# TODO(mberlin): Remove the manual copy once govendor supports a way to -# install vendor'd programs: https://github.com/kardianos/govendor/issues/117 install_protoc-gen-go: - mkdir -p $${GOPATH}/src/github.com/golang/ - cp -a vendor/github.com/golang/protobuf $${GOPATH}/src/github.com/golang/ go install github.com/golang/protobuf/protoc-gen-go # Find protoc compiler. @@ -173,7 +171,7 @@ docker_bootstrap_test: flavors='$(DOCKER_IMAGES_FOR_TEST)' && ./test.go -pull=false -parallel=2 -flavor=$${flavors// /,} docker_bootstrap_push: - for i in $(DOCKER_IMAGES); do echo "pushing boostrap image: $$i"; docker push vitess/bootstrap:$$i || exit 1; done + for i in $(DOCKER_IMAGES); do echo "pushing bootstrap image: $$i"; docker push vitess/bootstrap:$$i || exit 1; done # Use this target to update the local copy of your images with the one on Dockerhub. docker_bootstrap_pull: @@ -268,7 +266,6 @@ rebalance_tests: # Release a version. # This will generate a tar.gz file into the releases folder with the current source -# as well as the vendored libs. release: docker_base @if [ -z "$VERSION" ]; then \ echo "Set the env var VERSION with the release version"; exit 1;\ diff --git a/bootstrap.sh b/bootstrap.sh index afcd975ccd6..20fef115453 100755 --- a/bootstrap.sh +++ b/bootstrap.sh @@ -1,7 +1,7 @@ #!/bin/bash # shellcheck disable=SC2164 -# Copyright 2017 Google Inc. +# 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. @@ -19,7 +19,6 @@ # Outline of this file. # 0. Initialization and helper methods. # 1. Installation of dependencies. -# 2. Installation of Go tools and vendored Go dependencies. BUILD_TESTS=${BUILD_TESTS:-1} BUILD_PYTHON=${BUILD_PYTHON:-1} @@ -36,30 +35,25 @@ function fail() { [[ "$(dirname "$0")" = "." ]] || fail "bootstrap.sh must be run from its current directory" -go version &>/dev/null || fail "Go is not installed or is not on \$PATH" -[[ "$(go version 2>&1)" =~ go1\.[1-9][1-9] ]] || fail "Go is not version 1.11+" - # Create main directories. +VTROOT="${VTROOT:-${PWD/\/src\/vitess.io\/vitess/}}" mkdir -p "$VTROOT/dist" mkdir -p "$VTROOT/bin" mkdir -p "$VTROOT/lib" mkdir -p "$VTROOT/vthook" -# Install git hooks. -echo "creating git hooks" -mkdir -p "$VTTOP/.git/hooks" -ln -sf "$VTTOP/misc/git/pre-commit" "$VTTOP/.git/hooks/pre-commit" -ln -sf "$VTTOP/misc/git/commit-msg" "$VTTOP/.git/hooks/commit-msg" -(cd "$VTTOP" && git config core.hooksPath "$VTTOP/.git/hooks") - +# This is required for VIRTUALENV +# Used by Python below -# Set up the proper GOPATH for go get below. if [ "$BUILD_TESTS" == 1 ] ; then source ./dev.env else source ./build.env fi +go version &>/dev/null || fail "Go is not installed or is not on \$PATH" +goversion_min 1.12 || fail "Go is not version 1.12+" + if [ "$BUILD_TESTS" == 1 ] ; then # Set up required soft links. # TODO(mberlin): Which of these can be deleted? @@ -76,6 +70,14 @@ else ln -snf "$VTTOP/go/vt/zkctl/zksrv.sh" "$VTROOT/bin/zksrv.sh" fi +# git hooks are only required if someone intends to contribute. + +echo "creating git hooks" +mkdir -p "$VTTOP/.git/hooks" +ln -sf "$VTTOP/misc/git/pre-commit" "$VTTOP/.git/hooks/pre-commit" +ln -sf "$VTTOP/misc/git/commit-msg" "$VTTOP/.git/hooks/commit-msg" +(cd "$VTTOP" && git config core.hooksPath "$VTTOP/.git/hooks") + # install_dep is a helper function to generalize the download and installation of dependencies. # # If the installation is successful, it puts the installed version string into @@ -125,6 +127,14 @@ function install_dep() { # 1. Installation of dependencies. # +# Wrapper around the `arch` command which plays nice with OS X +function get_arch() { + case $(uname) in + Linux) arch;; + Darwin) uname -m;; + esac +} + # Install the gRPC Python library (grpcio) and the protobuf gRPC Python plugin (grpcio-tools) from PyPI. # Dependencies like the Python protobuf package will be installed automatically. @@ -163,8 +173,14 @@ function install_protoc() { Darwin) local platform=osx;; esac - wget "https://github.com/google/protobuf/releases/download/v$version/protoc-$version-$platform-x86_64.zip" - unzip "protoc-$version-$platform-x86_64.zip" + case $(get_arch) in + aarch64) local target=aarch_64;; + x86_64) local target=x86_64;; + *) echo "ERROR: unsupported architecture"; exit 1;; + esac + + wget https://github.com/protocolbuffers/protobuf/releases/download/v$version/protoc-$version-$platform-${target}.zip + unzip "protoc-$version-$platform-${target}.zip" ln -snf "$dist/bin/protoc" "$VTROOT/bin/protoc" } protoc_ver=3.6.1 @@ -202,8 +218,14 @@ function install_etcd() { Darwin) local platform=darwin; local ext=zip;; esac + case $(get_arch) in + aarch64) local target=arm64;; + x86_64) local target=amd64;; + *) echo "ERROR: unsupported architecture"; exit 1;; + esac + download_url=https://github.com/coreos/etcd/releases/download - file="etcd-${version}-${platform}-amd64.${ext}" + file="etcd-${version}-${platform}-${target}.${ext}" wget "$download_url/$version/$file" if [ "$ext" = "tar.gz" ]; then @@ -212,7 +234,7 @@ function install_etcd() { unzip "$file" fi rm "$file" - ln -snf "$dist/etcd-${version}-${platform}-amd64/etcd" "$VTROOT/bin/etcd" + ln -snf "$dist/etcd-${version}-${platform}-${target}/etcd" "$VTROOT/bin/etcd" } install_dep "etcd" "v3.3.10" "$VTROOT/dist/etcd" install_etcd @@ -227,9 +249,15 @@ function install_consul() { Darwin) local platform=darwin;; esac + case $(get_arch) in + aarch64) local target=arm64;; + x86_64) local target=amd64;; + *) echo "ERROR: unsupported architecture"; exit 1;; + esac + download_url=https://releases.hashicorp.com/consul - wget "${download_url}/${version}/consul_${version}_${platform}_amd64.zip" - unzip "consul_${version}_${platform}_amd64.zip" + wget "${download_url}/${version}/consul_${version}_${platform}_${target}.zip" + unzip "consul_${version}_${platform}_${target}.zip" ln -snf "$dist/consul" "$VTROOT/bin/consul" } install_dep "Consul" "1.4.0" "$VTROOT/dist/consul" install_consul @@ -273,7 +301,6 @@ if [ "$BUILD_PYTHON" == 1 ] ; then install_dep "Selenium" "latest" "$VTROOT/dist/selenium" install_selenium fi - # Download chromedriver (necessary to run test/vtctld_web_test.py). function install_chromedriver() { local version="$1" @@ -291,43 +318,5 @@ if [ "$BUILD_PYTHON" == 1 ] ; then PYTHONPATH='' $PIP install mysql-connector-python fi -# -# 2. Installation of Go tools and vendored Go dependencies. -# - - -# Install third-party Go tools used as part of the development workflow. -# -# DO NOT ADD LIBRARY DEPENDENCIES HERE. Instead use govendor as described below. -# -# Note: We explicitly do not vendor the tools below because a) we want to stay -# on their latest version and b) it's easier to "go install" them this way. -gotools=" \ - github.com/golang/mock/mockgen \ - github.com/kardianos/govendor \ - golang.org/x/lint/golint \ - golang.org/x/tools/cmd/cover \ - golang.org/x/tools/cmd/goimports \ - golang.org/x/tools/cmd/goyacc \ -" -echo "Installing dev tools with 'go get'..." -# shellcheck disable=SC2086 -go get -u $gotools || fail "Failed to download some Go tools with 'go get'. Please re-run bootstrap.sh in case of transient errors." - -# Download dependencies that are version-pinned via govendor. -# -# To add a new dependency, run: -# govendor fetch -# -# Existing dependencies can be updated to the latest version with 'fetch' as well. -# -# Then: -# git add vendor/vendor.json -# git commit -# -# See https://github.com/kardianos/govendor for more options. -echo "Updating govendor dependencies..." -govendor sync || fail "Failed to download/update dependencies with govendor. Please re-run bootstrap.sh in case of transient errors." - echo echo "bootstrap finished - run 'source dev.env' or 'source build.env' in your shell before building." diff --git a/build.env b/build.env index 29e0d992dbb..6bc36b42206 100644 --- a/build.env +++ b/build.env @@ -1,6 +1,6 @@ # No shebang line as this script is sourced from an external shell. -# Copyright 2017 Google Inc. +# 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. @@ -36,3 +36,5 @@ export VTROOT if [[ "$VTTOP" == "${VTTOP/\/src\/vitess.io\/vitess/}" ]]; then echo "WARNING: VTTOP($VTTOP) does not contain src/vitess.io/vitess" fi + +export GO111MODULE=on diff --git a/config/mycnf/backup.cnf b/config/mycnf/backup.cnf deleted file mode 100644 index de33eee9c41..00000000000 --- a/config/mycnf/backup.cnf +++ /dev/null @@ -1 +0,0 @@ -# reserved for future tuning diff --git a/config/mycnf/benchmark.cnf b/config/mycnf/benchmark.cnf deleted file mode 100644 index 5d33db9b15f..00000000000 --- a/config/mycnf/benchmark.cnf +++ /dev/null @@ -1,7 +0,0 @@ -innodb_doublewrite=0 -innodb_flush_log_at_trx_commit=0 -innodb_log_file_size=128M -innodb_buffer_pool_size=1G -max_connections=500 -open_files_limit=8192 -sync_binlog=0 diff --git a/config/mycnf/default-fast.cnf b/config/mycnf/default-fast.cnf index bb7edf6720b..969b51baa34 100644 --- a/config/mycnf/default-fast.cnf +++ b/config/mycnf/default-fast.cnf @@ -1,7 +1,6 @@ # basic config parameters for all db instances in the grid sql_mode = STRICT_TRANS_TABLES -binlog_format = statement character_set_server = utf8 collation_server = utf8_general_ci connect_timeout = 30 diff --git a/config/mycnf/master_mariadb.cnf b/config/mycnf/master_mariadb.cnf deleted file mode 100644 index 1e41cd8f3ce..00000000000 --- a/config/mycnf/master_mariadb.cnf +++ /dev/null @@ -1,12 +0,0 @@ -# This file is auto-included when MariaDB (any version) is detected. - -# enable strict mode so it's safe to compare sequence numbers across different server IDs. -gtid_strict_mode = 1 -innodb_stats_persistent = 0 - -# When semi-sync is enabled, don't allow fallback to async -# if you get no ack, or have no slaves. This is necessary to -# prevent alternate futures when doing a failover in response to -# a master that becomes unresponsive. -rpl_semi_sync_master_timeout = 1000000000000000000 -rpl_semi_sync_master_wait_no_slave = 1 diff --git a/config/mycnf/master_mariadb100.cnf b/config/mycnf/master_mariadb100.cnf index ce85c641c13..3eed4d8ea5f 100644 --- a/config/mycnf/master_mariadb100.cnf +++ b/config/mycnf/master_mariadb100.cnf @@ -10,3 +10,14 @@ innodb_support_xa = 0 # at the proper time when replication is set up, or when masters are # promoted or demoted. plugin-load = rpl_semi_sync_master=semisync_master.so;rpl_semi_sync_slave=semisync_slave.so + +# enable strict mode so it's safe to compare sequence numbers across different server IDs. +gtid_strict_mode = 1 +innodb_stats_persistent = 0 + +# When semi-sync is enabled, don't allow fallback to async +# if you get no ack, or have no slaves. This is necessary to +# prevent alternate futures when doing a failover in response to +# a master that becomes unresponsive. +rpl_semi_sync_master_timeout = 1000000000000000000 +rpl_semi_sync_master_wait_no_slave = 1 diff --git a/config/mycnf/master_mariadb101.cnf b/config/mycnf/master_mariadb101.cnf index d613b155d68..8c5b9e47fac 100644 --- a/config/mycnf/master_mariadb101.cnf +++ b/config/mycnf/master_mariadb101.cnf @@ -10,3 +10,14 @@ innodb_support_xa = 0 # at the proper time when replication is set up, or when masters are # promoted or demoted. plugin-load = rpl_semi_sync_master=semisync_master.so;rpl_semi_sync_slave=semisync_slave.so + +# enable strict mode so it's safe to compare sequence numbers across different server IDs. +gtid_strict_mode = 1 +innodb_stats_persistent = 0 + +# When semi-sync is enabled, don't allow fallback to async +# if you get no ack, or have no slaves. This is necessary to +# prevent alternate futures when doing a failover in response to +# a master that becomes unresponsive. +rpl_semi_sync_master_timeout = 1000000000000000000 +rpl_semi_sync_master_wait_no_slave = 1 diff --git a/config/mycnf/master_mariadb102.cnf b/config/mycnf/master_mariadb102.cnf index 487baa9bf87..1ea39a2a47c 100644 --- a/config/mycnf/master_mariadb102.cnf +++ b/config/mycnf/master_mariadb102.cnf @@ -10,3 +10,14 @@ innodb_support_xa = 0 # at the proper time when replication is set up, or when masters are # promoted or demoted. plugin-load = rpl_semi_sync_master=semisync_master.so;rpl_semi_sync_slave=semisync_slave.so + +# enable strict mode so it's safe to compare sequence numbers across different server IDs. +gtid_strict_mode = 1 +innodb_stats_persistent = 0 + +# When semi-sync is enabled, don't allow fallback to async +# if you get no ack, or have no slaves. This is necessary to +# prevent alternate futures when doing a failover in response to +# a master that becomes unresponsive. +rpl_semi_sync_master_timeout = 1000000000000000000 +rpl_semi_sync_master_wait_no_slave = 1 diff --git a/config/mycnf/production.cnf b/config/mycnf/production.cnf deleted file mode 100644 index 64f8c245035..00000000000 --- a/config/mycnf/production.cnf +++ /dev/null @@ -1,5 +0,0 @@ -# Values for a production vitess deployment -innodb_buffer_pool_size = 1024M -innodb_log_file_size = 512M -innodb_log_buffer_size = 64M -max_connections = 1000 \ No newline at end of file diff --git a/config/mycnf/rdonly.cnf b/config/mycnf/rdonly.cnf deleted file mode 100644 index de33eee9c41..00000000000 --- a/config/mycnf/rdonly.cnf +++ /dev/null @@ -1 +0,0 @@ -# reserved for future tuning diff --git a/dev.env b/dev.env index ca7bc608721..1c0d1ebdd59 100644 --- a/dev.env +++ b/dev.env @@ -1,6 +1,6 @@ # No shebang line as this script is sourced from an external shell. -# Copyright 2017 Google Inc. +# 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. @@ -55,17 +55,6 @@ export PIP command -v virtualenv2 >/dev/null && VIRTUALENV=virtualenv2 || VIRTUALENV=virtualenv export VIRTUALENV -# Add the current GOBIN -if [ "$GOBIN" ]; then - PATH=$(prepend_path "$PATH" "$GOBIN") -fi - -# Many tests rely on "go install" and assume GOBIN is really $VTROOT/bin. -# Make sure these take precedence. -GOBIN=$VTROOT/bin -export GOBIN -PATH=$(prepend_path "$PATH" "$GOBIN") - # Add chromedriver to path for Selenium tests. PATH=$(prepend_path "$PATH" "$VTROOT/dist/chromedriver") @@ -73,16 +62,6 @@ PATH=$(prepend_path "$PATH" "$VTROOT/dist/chromedriver") PATH=$(prepend_path "$PATH" "$VTROOT/dist/node/bin") export PATH -# GOROOT sanity -go_bin=$(which go) -go_env=$(go env | grep GOROOT | cut -f 2 -d\") -if [[ "$go_bin" != "" && "$go_bin" != "$go_env/bin/go" ]]; then - echo "WARNING: \$GOROOT may not be compatible with the used go binary" - echo "Please make sure 'go' comes from \$GOROOT/bin" - echo "go_env: $go_env" - echo "go_bin: $go_bin" -fi - # mysql install location. Please set based on your environment. # Build will not work if this is incorrect. @@ -98,9 +77,6 @@ fi PKG_CONFIG_PATH=$(prepend_path "$PKG_CONFIG_PATH" "$VTROOT/lib") export PKG_CONFIG_PATH -GOPATH=$(prepend_path "$GOPATH" "$VTROOT") -export GOPATH - # Useful aliases. Remove if inconvenient. alias gt='cd $GOTOP' alias pt='cd $PYTOP' diff --git a/doc/ReplicatoinLagBasedThrottlingOfTransactions.md b/doc/ReplicatoinLagBasedThrottlingOfTransactions.md index 49d88978919..3fecbb70879 100644 --- a/doc/ReplicatoinLagBasedThrottlingOfTransactions.md +++ b/doc/ReplicatoinLagBasedThrottlingOfTransactions.md @@ -37,6 +37,6 @@ the non-RDONLY replicas found in these cells for replication lag. the replication lag under the desired limit; as such the desired replication lag limit may occasionally be slightly violated. -* Transactions are considered homogenous. There is currently no support +* Transactions are considered homogeneous. There is currently no support for specifying how `expensive` a transaction is. diff --git a/doc/TwoPhaseCommitDesign.md b/doc/TwoPhaseCommitDesign.md index 14a8efbc8f2..38b93b3f891 100644 --- a/doc/TwoPhaseCommitDesign.md +++ b/doc/TwoPhaseCommitDesign.md @@ -197,7 +197,7 @@ If VTTablet is asked to shut down or change state from master, the code that wai Eventually, a different VTTablet will be transitioned to become the master. At that point, it will recreate the unresolved transactions from redo logs. If the replays fail, we’ll raise an alert and start the query service anyway. -Typically, a replay is not expected to fail because vttablet does not allow writes to the database until the replays are done. Also, no external agent should be allowed to perform writes to MySQL, which is a loosely enforced Vitess requirement. Other vitess processes do write to MySQL directly, but they’re not the kind that interfere with the normal flow of transactions. +Typically, a replay is not expected to fail because vttablet does not allow writing to the database until the replays are done. Also, no external agent should be allowed to perform writes to MySQL, which is a loosely enforced Vitess requirement. Other vitess processes do write to MySQL directly, but they’re not the kind that interfere with the normal flow of transactions. *Unresolved issue: If a resharding happens in the middle of a prepare, such a transaction potentially becomes multiple different transactions in a target shard. For now, this means that a resharding failover has to wait for all prepared transactions to be resolved. Special code has to be written in vttablet to handle this specific workflow.* diff --git a/doc/VTGateSubqueries.md b/doc/VTGateSubqueries.md index 40641bfbf5e..95eedecba05 100644 --- a/doc/VTGateSubqueries.md +++ b/doc/VTGateSubqueries.md @@ -118,7 +118,7 @@ A partially correlated subquery is similar to the completely uncorrelated subque 5. Finish analyzing b. 6. Analyzing b will make it correlated to a (because of c). -The `findOrigin` function can already peform this analysis. +The `findOrigin` function can already perform this analysis. So, in the above case, c cannot be pulled out beyond b. If c was not correlated with a, then we have the opportunity to pull it out further. diff --git a/doc/VitessQueues.md b/doc/VitessQueues.md index 8a0ccd2ec67..20a2b951669 100644 --- a/doc/VitessQueues.md +++ b/doc/VitessQueues.md @@ -107,7 +107,7 @@ ever it is). The Receiver will then either: The easiest implementation is to not guarantee an execution order for the events. Providing ordering would not be too difficult, but has an impact on -performance (when a Receiver does't respond in time, it delays eveybody else, so +performance (when a Receiver doesn't respond in time, it delays eveybody else, so we'd need to timeout quickly and keep going). For ‘old’ events (that have been fired but not acked), we propose to use an old diff --git a/doc/internal/ReleaseInstructions.md b/doc/internal/ReleaseInstructions.md index 327ad442a91..51dd7e3d514 100644 --- a/doc/internal/ReleaseInstructions.md +++ b/doc/internal/ReleaseInstructions.md @@ -1,7 +1,6 @@ # Release Instructions -This page describes the steps for cutting a new [open source release] -(https://github.com/vitessio/vitess/releases). +This page describes the steps for cutting a new [open source release](https://github.com/vitessio/vitess/releases). ## Versioning @@ -14,8 +13,7 @@ backward-incompatible way -- for example, when removing deprecated interfaces. Our public API includes (but is not limited to): -* The VTGate [RPC interfaces] - (https://github.com/vitessio/vitess/tree/master/proto). +* The VTGate [RPC interfaces](https://github.com/vitessio/vitess/tree/master/proto). * The interfaces exposed by the VTGate client library in each language. Care must also be taken when changing the format of any data stored by a live @@ -62,8 +60,7 @@ and tag the following items under it: ## Release Branches -Each minor release level (X.Y) should have a [release branch] -(https://github.com/vitessio/vitess/branches/all?query=release) named +Each minor release level (X.Y) should have a [release branch](https://github.com/vitessio/vitess/branches/all?query=release) named `release-X.Y`. This branch should diverge from `master` when the code freeze for that release is declared, after which point only bugfix PRs should be cherrypicked onto the branch. All other activity on `master` will go out with a @@ -261,8 +258,7 @@ git push upstream vX.Y.Z notes. Use the GitHub [Compare](https://github.com/vitessio/vitess/compare) tool to see all the commits since the last release. -Then send an announcement on the [vitess-announce] -(https://groups.google.com/forum/#!forum/vitess-announce) list. +Then send an announcement on the [vitess-announce](https://groups.google.com/forum/#!forum/vitess-announce) list. ## Bump Java SNAPSHOT version diff --git a/doc/meetups_notes/05-10-2018.md b/doc/meetups_notes/05-10-2018.md deleted file mode 100644 index 4f9b0381055..00000000000 --- a/doc/meetups_notes/05-10-2018.md +++ /dev/null @@ -1,47 +0,0 @@ -# Vitess Monthly Meeting - 05-10-2018 - -## Agenda - -* Vitess 3.0 Plan -* Planet Scale update -* Kubecon update -* Pain points - -## Notes - -### Vitess 3.0 Plan - -* Finish full subquery support. -* Multi shard DML’s support of PR’s that are already opened. -* Getting all the docs done is too big of a project, for the next release we will go through all the pull requests that have been merged and create a release note based on that. -* Once Planet Scale has a team in place, cadence for releases should be every couple months. - -### Planet scale update - -* Most of the requests that planet scale is getting are around helping people deploy vitess in their clusters. In the short in term this what PlanetScale will be focused on. -* In the open source realm, PlanetScale will build and host binaries for vitess. -* Hiring process is ongoing, offers out and interviews are happening. -* First engineer starting on June first. - -### Kubecon update from Sugu: - -* It was awesome. Sugu presented in front of 4000 people. -* Most people have heard about vitess before, but didn’t know exactly what vitess does. After Sugu’s presentation they do! -* Documentation keeps being a big debt on the project. Some ideas that were discussed: - -### Pain points: - -* Should we require to add documentation for features as part of pull requests? - - Not in the short term, it could discourage contributions from new comers. - - We should make easier for new comers to add documentation (add more structure and guidance in how to add documentation). -* We should be able to find a tech writer contractor that helps with editing / copy. -* @zmagg knows tech writers that could help. They are remote. She will be making an intro to @jitten. -* Some queries take a very long time without clear reason. -* Topology scalability issues. Vtgates polls lock server to get information about the tablets. This creates VtgatesNumber*VttabletsNumber of requests to lock server, which will create issues for big installations. -* Vtages not finding out about changes in topology after a reparent and routing to wrong tablets. -10 minutes vitess black hole that created an outage at Slack. The root cause for this have been fixed in: https://github.com/vitessio/vitess/pull/3898 -* Burst of query failures after a reparent. It fixes itself after a few seconds. It would be great to understand why this is happening. -* Building vitess is a painful, running the integration test is hard. (@rafael to provide Vagrantfile to build vitess in a VM) -* Does CNFN provides some funds for technical writing? - Yes, this is a possibility. The main problem is finding the right person. - diff --git a/doc/meetups_notes/06-14-2018.md b/doc/meetups_notes/06-14-2018.md deleted file mode 100644 index cb174fd8a88..00000000000 --- a/doc/meetups_notes/06-14-2018.md +++ /dev/null @@ -1,157 +0,0 @@ -# Vitess Monthly Meeting - 06-14-2018 - -Click [here](#meeting-notes) to jump to meeting notes. - -Date: 06/14/2018, Thursday - -Time: 8.00am PDT - -[Add to your Calendar](https://calendar.google.com/calendar/event?eid=NzJkZXRmOW5wOG83OG1tYjdqaHRtOTg1NWkgcGxhbmV0c2NhbGUuY29tXzkxbXU1cDU5c3Ztbm81MWl0Y25yaGh1MnYwQGc&ctz=America/Los_Angeles) - - -## Access Details - -https://slack.zoom.us/j/196813846 -Description:Hi there, - -mdemmer@slack-corp.com is inviting you to a scheduled Zoom meeting. - -Join from PC, Mac, Linux, iOS or Android: https://slack.zoom.us/j/196813846 - - -Or iPhone one-tap : - - US: +16465588656,,196813846# or +16699006833,,196813846# - -Or join by phone: - - Dial(for higher quality, dial a number based on your current location): - US: +1 646 558 8656 or +1 669 900 6833 or +1 877 369 0926 (Toll Free) or +1 877 853 5247 (Toll Free) - - +1 855 703 8985 (Canada Toll-Free) - +44 80 8189 4088 (United Kingdom Toll-Free) - +61 18 0079 2488 (Australia Toll-Free) - +81 (0) 800 100 5040 (Japan Toll-Free) - - Meeting ID: 196 813 846 - -## Agenda - -* Decide on Logo -* Upcoming topo revamp -* Orchestrator Vitess integration improvements -* Sugu's time on Vitess currently being spent on resharding revamp -* PlanetScale update -* Other roadmap items? -* Any burning issues? -* Vitess meetup around same time as Google Cloud Next (24-26 July 2018) - -Any questions, reach me on [vitess.slack.com](https://vitess.slack.com) — I'm @skinnylatte there too. Also email me: adrianna@planetscale.com. - -## [Meeting Notes](#meeting-notes) - -*Participants:* Guido Iaquinti, Michael Demmer, Sugu Sougouramane, Jiten Vaidya, Alex Charis, Leo Lin, Maggie Zhou, Dan Kozlowski, Adrianna Tan, Derek Perkins, Ameet Kotian, Chris Sullivan - -Meeting started at 8am PDT on Zoom. - -### New Vitess Logo / Logo Changes - -We kicked off the meeting talking about the first agenda item, *Vitess's new logo*. The new logo was mooted in the first place because of its current similarities to [Vivid IT Corp](https://www.vividitcorp.com/). - -Based on [logos](https://docs.google.com/forms/d/e/1FAIpQLScp5hGY98vpRMxs3oRT8c-XJ_b04ei6uCFiYiQe3nDunFbyuw/viewform) created with CNCF's help, logos 1 and 4 got the highest no of votes. - -Demmer raised a point that changing the color would make a bigger difference than changing the shape. We decided to do a new contest based on colors: we will ask for 3 color choices for both logo 4 (the logo with the highest no of votes, and as chosen by Sugu), as well as for the original logo. - -*Action Item:* Ask designers for 3 color combinations, output 6 logos to be entered in a contest (2 logos, 3 colors each). - -### Vitess Meetup & Monthly Meetings - -We discussed a *Vitess meetup on 24 July 2018* (different from monthly meeting) based on Derek's suggestion. Google Cloud Next around Moscone will be a good time / place to *get new users for Vitess*. Beer and pizza type of meetup. Look to ClickHouse's beginner and advanced meetups around Percona Live for reference. Date is tentatively set for 24 July 2018. - -*Action Item:* Organize event. Follow up with companies and other event spaces to see if they can host. - -We keeping Vitess monthly meetings separate from meetups (for international and East Coast folks). For July 2018, Vitess monthly meetup to will be held on 19 July 2018 at 8am PDT. The monthly meeting will be on the third Thursday of every month, for cadence and for *'state of Vitess'* discussions. - -*Action Item:* Send recurring calendar invite for monthly meeting. - -### Upcoming Topo Revamp - -We discussed the *upcoming topo revamp*. As Vitess scales, this affects people in different ways. We have two large users pushing it — a large ecommerce company with over a thousand keyspaces and VSchema that is struggling. Another company has a problem with VTGate. Others are running VTGate as a sidecar, which greatly increases the number of instances. - -Demmer brought up some other bugs and workarounds. But these workarounds don't work if tablets change addresses in their lifetimes. This is in reference to [ticket 3987](https://github.com/vitessio/vitess/issues/3987). - -Sugu talked about how in the early days, we expected different behavior. So some artifacts of old design still linger and have to be fixed. - -Sugu talked about how we need to work on resharding workflow. There are complaints about the general design being non-composable. We need to rework this to more easily use components to do other things like reversing filtered replication, or using filter replication for materialized views. We need to look at how to create alternative workflows. - -Not discussed, but here is a [link](https://github.com/vitessio/vitess/issues/3997) to Sugu's thoughts on topo revamp. Here is link to the filtered replication [issue](https://github.com/vitessio/vitess/issues/4002), for context. - -*Action item:* To be added to roadmap. - -### Orchestrator - Vitess integration - -We discussed how the integration with Orchestrator currently is not clean. This has been weighing down on Sugu's mind. After speaking with Maggie, we have an immediate solution. - -Each shard has a log record. You have to obtain the log record before making changes to the topo. Orchestrator should obtain the same log before it intervenes. - -Maggie is working on this and will get back with more info. - -Demmer suggests that we work on better documentation for someone who wants to run Orchestrator, and what they need for it. - -This segues into the next topic, about improving documentation. - -*Action item:* follow up with Maggie about solution for improving Orchestrator - Vitess integration; add to roadmap discussions. - -### Improving documentation - -The current state of Vitess documentation is hurting Vitess adoption. We have been looking for a technical writer, but no luck so far. - -Technical writers reading this / looking for a gig, please [email Adrianna](mailto:adrianna@planetscale.com) about it. Please pass on to friends / tech writers you have worked with in the past. - -*Action Item:* Keep looking for a technical writer! - -### PlanetScale update - -Jiten, CEO of PlanetScale, gave an update. Dan and Adrianna started with PlanetScale, so now we are 5 (including Lori). Office in downtown Mountain View. Open invitation to the Vitess community to come visit. We provide free wifi. - -We have been talking to several companies with interesting problems. PlanetScale will be offering them solutions around RDS / Aurora with modified Vitess. - -We are looking for 5 engineers. Job scope at [our site](https://planetscale.com/team). Send people to Jiten / Sugu if you think they'd be a good fit. - -*Action Item:* Visit [PlanetScale.com](https://planetscale.com)! Send engineers to us! - -### Roadmap - -We discussed that we need to work on / update official roadmap. - -Question from Ameet about whether there's anything on the roadmap for online backups, because increasingly backups take more time. - -Sugu says there are 500 lines of code re backup. But we will discuss this in our roadmap discussions. - -*Action Item:* Adrianna, product manager at PlanetScale, will work on roadmap and discussions with the Vitess community, together with Sugu and Demmer. - -### Blockers & Burning Issues - -David says that the *outdated roadmap* is a burning issue, hard to see who is working on what, or what changes / features are coming up. Everyone agreed. - -There was a discussion about which tools to adopt. GitHub projects, editable docs, using milestone labels etc. - -Dan says that more than tools, it's what's on the roadmap that needs to be locked down. - -*Action Item:* Adrianna will come up with a proposal in 2-3 weeks regarding updating / improving roadmap. This will follow an in-person discussion between Jiten, Sugu, Adrianna, with Demmer in the city. - -Derek raised a question about needing to figure out average query latency with VTGate when microbursts occur. David shared similar concerns. David also raised a question about tracing. Demmer said you can do that now with manual correlations but it's not hooked up to something that can be parsed and understood by Vitess. - -Sugu agreed that would be a good idea. To be added to roadmap discussions. - -Ameet asked about whether point in time recovery will be supported. - -Sugu says we will be adding point in time recovery, and multiple schema support, to our roadap discussions. - -*Action Item:* Work on roadmap and tools. Follow up with Derek and David on query latency questions. Table point in time recovery, and multiple schema support, in roadmap discussions. - -### Closing Comments - -Jon Tirsen presented on Vitess at Velocity yesterday ([link](https://conferences.oreilly.com/velocity/vl-ca/public/schedule/detail/66494)). Not slides yet, but will hear from him about how it went. Seems to be a lot of interest. PlanetScale will retweet tweets about this on our Twitter account, please follow ([link](https://twitter.com/planetscaledata)). - -Thank you for attending! Watch out for the next calendar invite in your inbox, and more info on our social meetup. diff --git a/doc/meetups_notes/details.md b/doc/meetups_notes/details.md deleted file mode 100644 index 1c67224dd25..00000000000 --- a/doc/meetups_notes/details.md +++ /dev/null @@ -1,32 +0,0 @@ -# Updated Meeting Info - -Until we find the right home for Vitess monthly meeting notes, they live here on [Google Docs](https://docs.google.com/document/d/1d8PcVD-ppnytRXZPOPvhRnnwei7-tYvgopD0UYzbAMs/edit). - -### Vitess Monthly Meeting - -Vitess monthly meetings happen on the 3rd Thursday of every month at 8:00AM Pacific time, unless otherwise stated on vitess.slack.com (click [here](https://vitess.slack.com/join/shared_invite/enQtMzIxMDMyMzA0NzA1LTBjYjY1M2I2Yjg5YmY3ODIwOTk0N2M1YzI4Y2ViODdiNmIxMDdiMDM5YWQ1ZTc0YmJhZDdiOTliMGVkNDY4MjM) to join us on Slack). - -There is a recurring calendar invite that will always have the latest meeting dates, ping Adrianna (@skinnylatte on vitess.slack.com or email adrianna [at] planetscale.com if you would like to be invited to it). - -### How To Dial-In - -Video Link: https://slack.zoom.us/j/314170129 -Joining by phone: - - -Or iPhone one-tap : - - US: +16699006833,,314170129# or +16465588656,,314170129# - -Or other phone: - -Dial(for higher quality, dial a number based on your current location): -US: +1 669 900 6833 or +1 646 558 8656 or +1 877 853 5247 (Toll Free) or +1 877 369 0926 (Toll Free) - -Canada: +1 855 703 8985 (Canada Toll-Free) -UK: +44 80 8189 4088 (United Kingdom Toll-Free) -Australia: +61 18 0079 2488 (Australia Toll-Free) - -Japan: +81 (0) 800 100 5040 (Japan Toll-Free) -China: 400 616 8835, 400 669 9381 -Most other countries: https://zoom.us/zoomconference (not available for some countries) diff --git a/docker/Dockerfile.release b/docker/Dockerfile.release index 40ac308dacd..1c36b503acc 100644 --- a/docker/Dockerfile.release +++ b/docker/Dockerfile.release @@ -1,3 +1,17 @@ +# 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. + # We rely on the base image, as that will re-copy the local # working tree and build it. Because of so, we trust the local # vendor folder is up to data. diff --git a/docker/base/Dockerfile b/docker/base/Dockerfile index ab9a9d4823e..ecab9ab6c42 100644 --- a/docker/base/Dockerfile +++ b/docker/base/Dockerfile @@ -1,3 +1,17 @@ +# 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. + # NOTE: This file is also symlinked as "Dockerfile" in the root of our # repository because the automated build feature on Docker Hub does not # allow to specify a different build context. It always assumes that the diff --git a/docker/bootstrap/Dockerfile.common b/docker/bootstrap/Dockerfile.common index a0300de7958..4b6a21beb49 100644 --- a/docker/bootstrap/Dockerfile.common +++ b/docker/bootstrap/Dockerfile.common @@ -46,31 +46,28 @@ ENV VTDATAROOT $VTROOT/vtdataroot ENV VTPORTSTART 15000 ENV PYTHONPATH $VTROOT/dist/grpc/usr/local/lib/python2.7/site-packages:$VTROOT/dist/py-mock-1.0.1/lib/python2.7/site-packages:$VTROOT/py-vtdb:$VTROOT/dist/selenium/lib/python2.7/site-packages ENV GOBIN $VTROOT/bin -ENV GOPATH $VTROOT ENV PATH $VTROOT/bin:$VTROOT/dist/maven/bin:$VTROOT/dist/chromedriver:$PATH ENV VT_MYSQL_ROOT /usr ENV PKG_CONFIG_PATH $VTROOT/lib ENV USER vitess +ENV GO111MODULE on # Copy files needed for bootstrap -COPY bootstrap.sh dev.env build.env /vt/src/vitess.io/vitess/ +COPY bootstrap.sh dev.env build.env go.mod go.sum /vt/src/vitess.io/vitess/ COPY config /vt/src/vitess.io/vitess/config COPY third_party /vt/src/vitess.io/vitess/third_party COPY tools /vt/src/vitess.io/vitess/tools COPY travis /vt/src/vitess.io/vitess/travis -COPY vendor/vendor.json /vt/src/vitess.io/vitess/vendor/ - -# Download vendored Go dependencies -RUN cd /vt/src/vitess.io/vitess && \ - go get -u github.com/kardianos/govendor && \ - govendor sync && \ - rm -rf /vt/.cache # Create vitess user RUN groupadd -r vitess && useradd -r -g vitess vitess && \ mkdir -p /vt/vtdataroot /home/vitess && \ chown -R vitess:vitess /vt /home/vitess +# Download vendored Go dependencies +RUN cd /vt/src/vitess.io/vitess && \ + su vitess -c "/usr/local/go/bin/go mod download" + # Create mount point for actual data (e.g. MySQL data dir) VOLUME /vt/vtdataroot diff --git a/docker/bootstrap/Dockerfile.mariadb b/docker/bootstrap/Dockerfile.mariadb index 81ee6bb2678..19d5c9973d0 100644 --- a/docker/bootstrap/Dockerfile.mariadb +++ b/docker/bootstrap/Dockerfile.mariadb @@ -1,7 +1,14 @@ FROM vitess/bootstrap:common # Install MariaDB 10 -RUN apt-get update -y \ +RUN for i in $(seq 1 10); do apt-key adv --no-tty --keyserver keys.gnupg.net --recv-keys 9334A25F8507EFA5 && break; done && \ + add-apt-repository 'deb http://repo.percona.com/apt stretch main' && \ + { \ + echo debconf debconf/frontend select Noninteractive; \ + echo percona-server-server-5.7 percona-server-server/root_password password 'unused'; \ + echo percona-server-server-5.7 percona-server-server/root_password_again password 'unused'; \ + } | debconf-set-selections && \ + apt-get update -y \ && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ bzip2 \ mariadb-server \ @@ -9,10 +16,8 @@ RUN apt-get update -y \ libdbd-mysql-perl \ rsync \ libev4 \ - && rm -rf /var/lib/apt/lists/* \ - && wget https://www.percona.com/downloads/XtraBackup/Percona-XtraBackup-2.4.13/binary/debian/stretch/x86_64/percona-xtrabackup-24_2.4.13-1.stretch_amd64.deb \ - && dpkg -i percona-xtrabackup-24_2.4.13-1.stretch_amd64.deb \ - && rm -f percona-xtrabackup-24_2.4.13-1.stretch_amd64.deb + percona-xtrabackup-24 \ + && rm -rf /var/lib/apt/lists/* # Bootstrap Vitess WORKDIR /vt/src/vitess.io/vitess diff --git a/docker/bootstrap/Dockerfile.mysql56 b/docker/bootstrap/Dockerfile.mysql56 index 5da4ec29946..b07fddedb61 100644 --- a/docker/bootstrap/Dockerfile.mysql56 +++ b/docker/bootstrap/Dockerfile.mysql56 @@ -3,12 +3,16 @@ FROM vitess/bootstrap:common # Install MySQL 5.6 RUN for i in $(seq 1 10); do apt-key adv --no-tty --recv-keys --keyserver pool.sks-keyservers.net 5072E1F5 && break; done && \ add-apt-repository 'deb http://repo.mysql.com/apt/debian/ stretch mysql-5.6' && \ + for i in $(seq 1 10); do apt-key adv --no-tty --keyserver keys.gnupg.net --recv-keys 9334A25F8507EFA5 && break; done && \ + echo 'deb http://repo.percona.com/apt stretch main' > /etc/apt/sources.list.d/percona.list && \ + { \ + echo debconf debconf/frontend select Noninteractive; \ + echo percona-server-server-5.6 percona-server-server/root_password password 'unused'; \ + echo percona-server-server-5.6 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 && \ - rm -rf /var/lib/apt/lists/* && \ - wget https://www.percona.com/downloads/XtraBackup/Percona-XtraBackup-2.4.13/binary/debian/stretch/x86_64/percona-xtrabackup-24_2.4.13-1.stretch_amd64.deb && \ - dpkg -i percona-xtrabackup-24_2.4.13-1.stretch_amd64.deb && \ - rm -f percona-xtrabackup-24_2.4.13-1.stretch_amd64.deb + DEBIAN_FRONTEND=noninteractive apt-get install -y mysql-server libmysqlclient-dev libdbd-mysql-perl rsync libev4 percona-xtrabackup-24 && \ + rm -rf /var/lib/apt/lists/* # Bootstrap Vitess WORKDIR /vt/src/vitess.io/vitess diff --git a/docker/bootstrap/Dockerfile.mysql57 b/docker/bootstrap/Dockerfile.mysql57 index a251e03031d..2fb1f4e1aa5 100644 --- a/docker/bootstrap/Dockerfile.mysql57 +++ b/docker/bootstrap/Dockerfile.mysql57 @@ -4,12 +4,16 @@ FROM vitess/bootstrap:common RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends gnupg dirmngr ca-certificates && \ for i in $(seq 1 10); do apt-key adv --no-tty --recv-keys --keyserver ha.pool.sks-keyservers.net 5072E1F5 && break; done && \ add-apt-repository 'deb http://repo.mysql.com/apt/debian/ stretch mysql-5.7' && \ + for i in $(seq 1 10); do apt-key adv --no-tty --keyserver keys.gnupg.net --recv-keys 9334A25F8507EFA5 && break; done && \ + echo 'deb http://repo.percona.com/apt stretch main' > /etc/apt/sources.list.d/percona.list && \ + { \ + echo debconf debconf/frontend select Noninteractive; \ + echo percona-server-server-5.7 percona-server-server/root_password password 'unused'; \ + echo percona-server-server-5.7 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 && \ - rm -rf /var/lib/apt/lists/* && \ - wget https://www.percona.com/downloads/XtraBackup/Percona-XtraBackup-2.4.13/binary/debian/stretch/x86_64/percona-xtrabackup-24_2.4.13-1.stretch_amd64.deb && \ - dpkg -i percona-xtrabackup-24_2.4.13-1.stretch_amd64.deb && \ - rm -f percona-xtrabackup-24_2.4.13-1.stretch_amd64.deb + DEBIAN_FRONTEND=noninteractive apt-get install -y mysql-server libmysqlclient-dev libdbd-mysql-perl rsync libev4 percona-xtrabackup-24 && \ + rm -rf /var/lib/apt/lists/* # Bootstrap Vitess WORKDIR /vt/src/vitess.io/vitess diff --git a/docker/bootstrap/Dockerfile.mysql80 b/docker/bootstrap/Dockerfile.mysql80 index 1d21887d850..ec53895165f 100644 --- a/docker/bootstrap/Dockerfile.mysql80 +++ b/docker/bootstrap/Dockerfile.mysql80 @@ -3,12 +3,16 @@ FROM vitess/bootstrap:common # Install MySQL 8.0 RUN for i in $(seq 1 10); do apt-key adv --no-tty --recv-keys --keyserver ha.pool.sks-keyservers.net 8C718D3B5072E1F5 && break; done && \ add-apt-repository 'deb http://repo.mysql.com/apt/debian/ stretch mysql-8.0' && \ + for i in $(seq 1 10); do apt-key adv --no-tty --keyserver keys.gnupg.net --recv-keys 9334A25F8507EFA5 && break; done && \ + echo 'deb http://repo.percona.com/apt stretch 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'; \ + echo percona-server-server-8.0 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 && \ - rm -rf /var/lib/apt/lists/* && \ - wget https://www.percona.com/downloads/XtraBackup/Percona-XtraBackup-8.0.4/binary/debian/stretch/x86_64/percona-xtrabackup-80_8.0.4-1.stretch_amd64.deb && \ - dpkg -i percona-xtrabackup-80_8.0.4-1.stretch_amd64.deb && \ - rm -f percona-xtrabackup-80_8.0.4-1.stretch_amd64.deb + DEBIAN_FRONTEND=noninteractive apt-get install -y mysql-server libmysqlclient-dev libdbd-mysql-perl rsync libev4 libcurl4-openssl-dev percona-xtrabackup-80 && \ + rm -rf /var/lib/apt/lists/* # Bootstrap Vitess WORKDIR /vt/src/vitess.io/vitess diff --git a/docker/bootstrap/Dockerfile.percona b/docker/bootstrap/Dockerfile.percona index d9f41e4854c..6d13fa4dfb0 100644 --- a/docker/bootstrap/Dockerfile.percona +++ b/docker/bootstrap/Dockerfile.percona @@ -10,11 +10,8 @@ RUN for i in $(seq 1 10); do apt-key adv --no-tty --keyserver keys.gnupg.net --r } | debconf-set-selections && \ apt-get update && \ apt-get install -y --no-install-recommends \ - percona-server-server-5.6 libperconaserverclient18.1-dev rsync libev4 && \ - rm -rf /var/lib/apt/lists/* && \ - wget https://www.percona.com/downloads/XtraBackup/Percona-XtraBackup-2.4.13/binary/debian/stretch/x86_64/percona-xtrabackup-24_2.4.13-1.stretch_amd64.deb && \ - dpkg -i percona-xtrabackup-24_2.4.13-1.stretch_amd64.deb && \ - rm -f percona-xtrabackup-24_2.4.13-1.stretch_amd64.deb + percona-server-server-5.6 libperconaserverclient18.1-dev rsync libev4 percona-xtrabackup-24 && \ + rm -rf /var/lib/apt/lists/* # Bootstrap Vitess WORKDIR /vt/src/vitess.io/vitess diff --git a/docker/bootstrap/Dockerfile.percona57 b/docker/bootstrap/Dockerfile.percona57 index 98fa12518fe..6ed54c76923 100644 --- a/docker/bootstrap/Dockerfile.percona57 +++ b/docker/bootstrap/Dockerfile.percona57 @@ -11,7 +11,7 @@ RUN for i in $(seq 1 10); do apt-key adv --no-tty --keyserver keys.gnupg.net --r apt-get update && \ apt-get install -y --no-install-recommends \ percona-server-server-5.7 \ - libperconaserverclient18.1-dev && \ + libperconaserverclient18.1-dev percona-xtrabackup-24 && \ rm -rf /var/lib/apt/lists/* # Bootstrap Vitess diff --git a/docker/bootstrap/Dockerfile.percona80 b/docker/bootstrap/Dockerfile.percona80 index 8b91905b4b1..1ce9c52103f 100644 --- a/docker/bootstrap/Dockerfile.percona80 +++ b/docker/bootstrap/Dockerfile.percona80 @@ -18,10 +18,16 @@ RUN for i in $(seq 1 10); do apt-key adv --no-tty --keyserver keys.gnupg.net --r libdbd-mysql-perl \ rsync \ libev4 \ - && rm -rf /var/lib/apt/lists/* \ - && wget https://www.percona.com/downloads/XtraBackup/Percona-XtraBackup-8.0.4/binary/debian/stretch/x86_64/percona-xtrabackup-80_8.0.4-1.stretch_amd64.deb \ - && dpkg -i percona-xtrabackup-80_8.0.4-1.stretch_amd64.deb \ - && rm -f percona-xtrabackup-80_8.0.4-1.stretch_amd64.deb +# && rm -f /etc/apt/sources.list.d/percona.list \ + && echo 'deb http://repo.percona.com/apt stretch 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'; \ +# echo percona-server-server-8.0 percona-server-server/root_password_again password 'unused'; \ +# } | debconf-set-selections \ + && apt-get update -y \ + && apt-get install -y --no-install-recommends percona-xtrabackup-80 \ + && rm -rf /var/lib/apt/lists/* # Bootstrap Vitess WORKDIR /vt/src/vitess.io/vitess diff --git a/docker/bootstrap/build.sh b/docker/bootstrap/build.sh index 3774492fb6b..0a3a48c1253 100755 --- a/docker/bootstrap/build.sh +++ b/docker/bootstrap/build.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2017 Google Inc. +# 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. diff --git a/docker/k8s/Dockerfile b/docker/k8s/Dockerfile index 4a037dfcbb0..ddafcd95af7 100644 --- a/docker/k8s/Dockerfile +++ b/docker/k8s/Dockerfile @@ -1,3 +1,17 @@ +# 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. + FROM vitess/base AS base FROM debian:stretch-slim diff --git a/docker/k8s/logrotate/Dockerfile b/docker/k8s/logrotate/Dockerfile index c955e82625d..ba1e53d961c 100644 --- a/docker/k8s/logrotate/Dockerfile +++ b/docker/k8s/logrotate/Dockerfile @@ -1,3 +1,17 @@ +# 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. + FROM debian:stretch-slim ADD logrotate.conf /vt/logrotate.conf diff --git a/docker/k8s/logrotate/rotate.sh b/docker/k8s/logrotate/rotate.sh index 917ae0ec009..bbce1c3dd1e 100644 --- a/docker/k8s/logrotate/rotate.sh +++ b/docker/k8s/logrotate/rotate.sh @@ -1,4 +1,19 @@ #!/bin/bash + +# 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. + set -ex # SIGTERM-handler diff --git a/docker/k8s/logtail/Dockerfile b/docker/k8s/logtail/Dockerfile index 7de51b55ecd..a5428e2bd52 100644 --- a/docker/k8s/logtail/Dockerfile +++ b/docker/k8s/logtail/Dockerfile @@ -1,3 +1,17 @@ +# 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. + FROM debian:stretch-slim ENV TAIL_FILEPATH /dev/null diff --git a/docker/k8s/logtail/tail.sh b/docker/k8s/logtail/tail.sh index 03cb7ffcafd..1ff75b6556b 100644 --- a/docker/k8s/logtail/tail.sh +++ b/docker/k8s/logtail/tail.sh @@ -1,4 +1,19 @@ #!/bin/bash + +# 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. + set -ex # SIGTERM-handler diff --git a/docker/k8s/mysqlctld/Dockerfile b/docker/k8s/mysqlctld/Dockerfile index 59c495de14e..4dafb77bbdb 100644 --- a/docker/k8s/mysqlctld/Dockerfile +++ b/docker/k8s/mysqlctld/Dockerfile @@ -1,3 +1,17 @@ +# 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. + FROM vitess/k8s AS k8s FROM debian:stretch-slim diff --git a/docker/k8s/orchestrator/Dockerfile b/docker/k8s/orchestrator/Dockerfile index f626fee34f8..26ee5922bc5 100644 --- a/docker/k8s/orchestrator/Dockerfile +++ b/docker/k8s/orchestrator/Dockerfile @@ -1,3 +1,17 @@ +# 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. + FROM vitess/k8s AS k8s FROM debian:stretch-slim diff --git a/docker/k8s/pmm-client/Dockerfile b/docker/k8s/pmm-client/Dockerfile index 5c81f180728..db5b1a92119 100644 --- a/docker/k8s/pmm-client/Dockerfile +++ b/docker/k8s/pmm-client/Dockerfile @@ -1,3 +1,17 @@ +# 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. + FROM vitess/k8s AS k8s FROM debian:stretch-slim diff --git a/docker/k8s/vtbackup/Dockerfile b/docker/k8s/vtbackup/Dockerfile index 05d2e9e784d..306911457a2 100644 --- a/docker/k8s/vtbackup/Dockerfile +++ b/docker/k8s/vtbackup/Dockerfile @@ -1,3 +1,17 @@ +# 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. + FROM vitess/k8s AS k8s FROM debian:stretch-slim diff --git a/docker/k8s/vtctl/Dockerfile b/docker/k8s/vtctl/Dockerfile index ea52256e810..b260f167dc4 100644 --- a/docker/k8s/vtctl/Dockerfile +++ b/docker/k8s/vtctl/Dockerfile @@ -1,3 +1,17 @@ +# 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. + FROM vitess/k8s AS k8s FROM debian:stretch-slim diff --git a/docker/k8s/vtctlclient/Dockerfile b/docker/k8s/vtctlclient/Dockerfile index 554fe3e816f..1b1b9be3bc3 100644 --- a/docker/k8s/vtctlclient/Dockerfile +++ b/docker/k8s/vtctlclient/Dockerfile @@ -1,3 +1,17 @@ +# 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. + FROM vitess/k8s AS k8s FROM debian:stretch-slim diff --git a/docker/k8s/vtctld/Dockerfile b/docker/k8s/vtctld/Dockerfile index 2e14365596c..8122e3f4e77 100644 --- a/docker/k8s/vtctld/Dockerfile +++ b/docker/k8s/vtctld/Dockerfile @@ -1,3 +1,17 @@ +# 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. + FROM vitess/k8s AS k8s FROM debian:stretch-slim diff --git a/docker/k8s/vtexplain/Dockerfile b/docker/k8s/vtexplain/Dockerfile index e9aa276d648..1dda593c113 100644 --- a/docker/k8s/vtexplain/Dockerfile +++ b/docker/k8s/vtexplain/Dockerfile @@ -1,3 +1,17 @@ +# 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. + FROM vitess/base AS base FROM debian:stretch-slim diff --git a/docker/k8s/vtgate/Dockerfile b/docker/k8s/vtgate/Dockerfile index d876d0521a2..2734e08f464 100644 --- a/docker/k8s/vtgate/Dockerfile +++ b/docker/k8s/vtgate/Dockerfile @@ -1,3 +1,17 @@ +# 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. + FROM vitess/k8s AS k8s FROM debian:stretch-slim diff --git a/docker/k8s/vttablet/Dockerfile b/docker/k8s/vttablet/Dockerfile index 9af272a84aa..bbc56cebe99 100644 --- a/docker/k8s/vttablet/Dockerfile +++ b/docker/k8s/vttablet/Dockerfile @@ -1,3 +1,17 @@ +# 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. + FROM vitess/k8s AS k8s FROM debian:stretch-slim diff --git a/docker/k8s/vtworker/Dockerfile b/docker/k8s/vtworker/Dockerfile index f1fab9bceb4..d43d00819bb 100644 --- a/docker/k8s/vtworker/Dockerfile +++ b/docker/k8s/vtworker/Dockerfile @@ -1,3 +1,17 @@ +# 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. + FROM vitess/k8s AS k8s FROM debian:stretch-slim diff --git a/docker/lite/Dockerfile b/docker/lite/Dockerfile index aa1ff5b831c..268a68fffce 100644 --- a/docker/lite/Dockerfile +++ b/docker/lite/Dockerfile @@ -1,3 +1,17 @@ +# 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. + FROM vitess/base AS builder FROM debian:stretch-slim AS staging diff --git a/docker/lite/build.sh b/docker/lite/build.sh index 700412f6faf..9524ddb6b98 100755 --- a/docker/lite/build.sh +++ b/docker/lite/build.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2017 Google Inc. +# 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. diff --git a/docker/orchestrator/Dockerfile b/docker/orchestrator/Dockerfile index 06ca9ebce13..8833d644a6a 100644 --- a/docker/orchestrator/Dockerfile +++ b/docker/orchestrator/Dockerfile @@ -1,3 +1,17 @@ +# 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. + FROM debian:jessie # Install Percona XtraDB Cluster (Galera) diff --git a/docker/orchestrator/build.sh b/docker/orchestrator/build.sh index f375ec75725..0f81c7b2dd2 100755 --- a/docker/orchestrator/build.sh +++ b/docker/orchestrator/build.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2017 Google Inc. +# 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. diff --git a/docker/packaging/Dockerfile b/docker/packaging/Dockerfile index 713aa67b72b..576b8ef0e63 100644 --- a/docker/packaging/Dockerfile +++ b/docker/packaging/Dockerfile @@ -1,3 +1,17 @@ +# 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. + FROM vitess/base USER root diff --git a/docker/packaging/package_vitess.sh b/docker/packaging/package_vitess.sh index a90a46d69c8..609fd1447d5 100755 --- a/docker/packaging/package_vitess.sh +++ b/docker/packaging/package_vitess.sh @@ -1,5 +1,19 @@ #!/bin/bash +# 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. + if [ -z "${VERSION}" ]; then echo "Set the env var VERSION with the release version" exit 1 diff --git a/docker/packaging/preinstall.sh b/docker/packaging/preinstall.sh index 1d9c80ca782..e6bfaf537a2 100755 --- a/docker/packaging/preinstall.sh +++ b/docker/packaging/preinstall.sh @@ -1,5 +1,19 @@ #!/bin/bash +# 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. + if ! /usr/bin/getent group vitess >/dev/null ; then groupadd -r vitess fi diff --git a/docker/publish-site/Dockerfile b/docker/publish-site/Dockerfile index 2584f278457..e0a1946996f 100644 --- a/docker/publish-site/Dockerfile +++ b/docker/publish-site/Dockerfile @@ -1,3 +1,17 @@ +# 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. + # This image should be built with $VTTOP as the context dir. # For example: # vitess$ docker build -f docker/publish-site/Dockerfile -t vitess/publish-site . diff --git a/docker/root/Dockerfile b/docker/root/Dockerfile index d3f17bae596..37fc3d24a6c 100644 --- a/docker/root/Dockerfile +++ b/docker/root/Dockerfile @@ -1,3 +1,17 @@ +# 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. + # This is an image that just changes the default user to root. # It's useful for cases when the 'docker run --user' flag can't be used, # for example when running containers through a scheduler like Kubernetes. diff --git a/docker/test/run.sh b/docker/test/run.sh index dc59fad26f4..147663d028b 100755 --- a/docker/test/run.sh +++ b/docker/test/run.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2017 Google Inc. +# 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. @@ -176,12 +176,12 @@ copy_src_cmd="cp -R /tmp/src/!(vendor|bootstrap.sh) ." # Git repository. copy_src_cmd=$(append_cmd "$copy_src_cmd" "cp -R /tmp/src/.git .") -# Copy vendor/vendor.json file if it changed -run_bootstrap_cmd="if [[ \$(diff -w vendor/vendor.json /tmp/src/vendor/vendor.json) ]]; then cp -f /tmp/src/vendor/vendor.json vendor/; sync_vendor=1; fi" +# Enable gomodules +run_bootstrap_cmd="export GO111MODULE=on" # Copy bootstrap.sh if it changed run_bootstrap_cmd=$(append_cmd "$run_bootstrap_cmd" "if [[ \$(diff -w bootstrap.sh /tmp/src/bootstrap.sh) ]]; then cp -f /tmp/src/bootstrap.sh .; bootstrap=1; fi") # run bootstrap.sh if necessary -run_bootstrap_cmd=$(append_cmd "$run_bootstrap_cmd" "if [[ -n \$bootstrap ]]; then ./bootstrap.sh; else if [[ -n \$sync_vendor ]]; then govendor sync; fi; fi") +run_bootstrap_cmd=$(append_cmd "$run_bootstrap_cmd" "if [[ -n \$bootstrap ]]; then ./bootstrap.sh; fi") copy_src_cmd=$(append_cmd "$copy_src_cmd" "$run_bootstrap_cmd") # Construct the command we will actually run. diff --git a/examples/compose/README.md b/examples/compose/README.md index 82528bbde42..eb801a8fcbe 100644 --- a/examples/compose/README.md +++ b/examples/compose/README.md @@ -5,6 +5,59 @@ To understand it better, you can run it. First you will need to [install docker-compose](https://docs.docker.com/compose/install/). +### Before you begin +You will need to create a docker-compose.yml file. There are 2 ways to do this. +1. Run `go run vtcompose/vtcompose.go --args`. [Instructions can be found here](#programatically-create-vitess-configuration-for-docker "Generate docker-compose") +2. Use the `docker-compose.beginners.yml` to generate your `docker-compose.yml` file. Run: +``` +vitess/examples/compose$ cp docker-compose.beginners.yml docker-compose.yml +``` +Create your .env file +``` +vitess/examples/compose$ cp template.env .env +``` + +You can then proceed to the instructions under [`Start the Cluster`](#start-the-cluster "Start the cluster") section. + +### Programatically create Vitess configuration for Docker +To create a configuration to your specifications, run vtcompose. Creates corresponding docker-compose file, vschema files per keyspace, and loads schemas. +``` +vitess/examples/compose$ go run vtcompose/vtcompose.go --args(optional) +``` + +Use `-h` or `--help` to get list of flags with descriptions. + +Flags available: +* **baseDockerComposeFile** - Specifies starting docker-compose yaml file. +* **baseVschemaFile** - Specifies starting vschema json file. +* **topologyFlags** - Specifies Vitess topology flags config +* **webPort** - Specifies web port to be used. +* **gRpcPort** - Specifies gRPC port to be used. +* **mySqlPort** - Specifies mySql port to be used. +* **cell** - `Specifies Vitess cell name to be used. +* **keyspaceData** - List of `keyspace_name:num_of_shards:num_of_replica_tablets:schema_file_names:lookup_keyspace_name` separated by ';'. + * This is where you specify most of the data for the program to build your vSchema and docker-compose files. + * Examples you can run; + * Default + ``` + go run vtcompose/vtcompose.go + ``` + * Use `0` for `num_of_shards` to specify an unsharded keyspace + ``` + go run vtcompose/vtcompose.go -keyspaceData="test_keyspace:0:2:create_messages.sql" + ``` + * Multiple keyspaces with sharded test_keyspace + ``` + go run vtcompose/vtcompose.go -keyspaceData="test_keyspace:2:1:create_messages.sql,create_tokens.sql:lookup_keyspace;lookup_keyspace:1:1:create_tokens_token_lookup.sql,create_messages_message_lookup.sql" + ``` +* **externalDbData** - Specifies which databases/keyspaces are external and provides data along with it to connect to the external db. + List of `,,,,,` seperated by ';'. + When using this, make sure to have the external_db_name/keyspace in the `keyspaceData` flag with no schema_file_names specified. + ``` + go run vtcompose/vtcompose.go -keyspaces="test:0:2::" -externalDbData="test:192.68.99.101:3306:admin:pass:CHARACTER SET utf8 COLLATE utf8_general_ci" + ``` + + ### Start the cluster To start Consul(which saves the topology config), vtctld, vtgate and a few vttablets with MySQL running on them. ``` @@ -12,22 +65,25 @@ vitess/examples/compose$ docker-compose up -d ``` ### Check the status of the containers -You can check the logs of the containers (vtgate, vttablet1, vttablet2, vttablet3) at any time. +You can check the logs of the containers (vtgate, vttablet101, vttablet102, vttablet103) at any time. For example to check vtgate logs, run the following; ``` vitess/examples/compose$ docker-compose logs -f vtgate ``` ### Load the schema -We need to create a few tables into our new cluster. To do that, we can run the `ApplySchema` command. -``` -vitess/examples/compose$ ./lvtctl.sh ApplySchema -sql "$(cat create_test_table.sql)" test_keyspace +***Note: Should not be needed if VtCompose was used.*** + +We need to create a few tables into our new cluster. To do that, we can run the `ApplySchema` command. +``` +vitess/examples/compose$ ./lvtctl.sh ApplySchema -sql "$(cat tables/create_messages.sql)" test_keyspace ``` -### Create Vschema +### Create Vschema +***Note: Should not be needed if VtCompose was used.*** Create Vschema -``` -vitess/examples/compose$ ./lvtctl.sh ApplyVschema -vschema '{"tables": {"messages": {} } }' test_keyspace +``` +vitess/examples/compose$ ./lvtctl.sh ApplyVschema -vschema '{"sharded": false }' test_keyspace ``` ### Run the client to insert and read some data @@ -39,10 +95,12 @@ vitess/examples/compose$ ./client.sh ### Connect to vgate and run queries vtgate responds to the MySQL protocol, so we can connect to it using the default MySQL client command line. +You can also use the `./lmysql.sh` helper script. ``` +vitess/examples/compose$ mysql --port=15306 --host=127.0.0.1 vitess/examples/compose$ ./lmysql.sh --port=15306 --host=127.0.0.1 ``` - +**Note that you may need to replace `127.0.0.1` with `docker ip` or `docker-machine ip`** ### Play around with vtctl commands @@ -56,14 +114,18 @@ vitess/examples/compose$ ./lvtctl.sh Help http://localhost:15000 - vttablets web ui: - http://localhost:15001/debug/status - http://localhost:15002/debug/status - http://localhost:15003/debug/status + http://localhost:15101/debug/status + http://localhost:15102/debug/status + http://localhost:15103/debug/status - vtgate web ui: http://localhost:15099/debug/status - +- Stream querylog + `curl -S localhost:15099/debug/querylog` + +**Note that you may need to replace `localhost` with `docker ip` or `docker-machine ip`** + ## Troubleshooting If the cluster gets in a bad state, you most likely will have to stop and kill the containers. Note: you will lose all the data. ``` @@ -113,15 +175,15 @@ vitess/examples/compose$ ./lfixrepl.sh ``` ### Apply Vschema -Apply Vschema for the unsharded keyspace -``` -vitess/examples/compose$ ./lvtctl.sh ApplyVschema -vschema '{"sharded":false, "tables": {"*": {} } }' external_db_name +Apply Vschema for the unsharded keyspace +``` +vitess/examples/compose$ ./lvtctl.sh ApplyVschema -vschema '{"sharded":false, "tables": {"*": {} } }' external_db_name ``` ### Connect to vgate and run queries vtgate responds to the MySQL protocol, so we can connect to it using the default MySQL client command line. ```sh -vitess/examples/compose$ ./lmysql.sh --port=15306 --host= +vitess/examples/compose$ mysql --port=15306 --host= mysql> show databases; +--------------------+ @@ -157,8 +219,8 @@ mysql> show tables; ## Helper Scripts The following helper scripts are included to help you perform various actions easily * vitess/examples/compose/lvtctl.sh -* vitess/examples/compose/lmysql.sh * vitess/examples/compose/lfixrepl.sh +* vitess/examples/compose/lmysql.sh You may run them as below ``` @@ -168,7 +230,7 @@ vitess/examples/compose$ ./lvtctl.sh To run against a specific compose service/container, use the environment variable **$CS** ``` -vitess/examples/compose$ (export CS=vttablet2; ./lvtctl.sh ) +vitess/examples/compose$ (export CS=vttablet101; ./lvtctl.sh ) ``` ## Common Errors @@ -183,10 +245,10 @@ exit status 1 ``` To resolve use the [SetReadWrite](../../doc/Troubleshooting.md#master-starts-up-read-only) command on master. ```sh -vitess/examples/compose$ ./lvtctl.sh SetReadWrite test-1 +vitess/examples/compose$ ./lvtctl.sh SetReadWrite test-101 ``` - + 2. Running ./lvtctl.sh ApplyVschema -vschema '{"sharded":false }' may result in an error referenced by this [issue](https://github.com/vitessio/vitess/issues/4013 ) @@ -194,3 +256,6 @@ A quick fix for unsharded db is; ``` vitess/examples/compose$ ./lvtctl.sh ApplyVschema -vschema '{"sharded":false, "tables": {"*": {} } }' external_db_name ``` + +This has since been fixed by +https://github.com/vitessio/vitess/pull/4868 & https://github.com/vitessio/vitess/pull/5010 \ No newline at end of file diff --git a/examples/compose/client.go b/examples/compose/client.go index 2267992f5b6..3d97a563f06 100644 --- a/examples/compose/client.go +++ b/examples/compose/client.go @@ -1,18 +1,18 @@ /* -Copyright 2017 Google Inc. + * 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 + * 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 + * http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto 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. -*/ + * 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. + */ // client.go is a sample for using the Vitess Go SQL driver. // diff --git a/examples/compose/dbcli.sh b/examples/compose/dbcli.sh new file mode 100755 index 00000000000..6d56f0b2763 --- /dev/null +++ b/examples/compose/dbcli.sh @@ -0,0 +1,33 @@ +#!/bin/bash + +# 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. + +usage () { + echo "Starts a session on a sideloaded vttablet." + echo "Note that this is a direct MySQL connection; if you actually want to work with Vitess, connect via the vtgate with:" + echo " mysql --port=15306 --host=127.0.0.1" + echo + echo "Usage: $0 []" + echo " Don't forget the 'vt_' before the keyspace!" +} + +if [ $# -lt 1 ]; then + usage + exit -1 +fi + +keyspace=${2:-vt_test_keyspace} +long_alias=`printf "%010d" $1` +docker-compose exec vttablet$1 mysql -uvt_dba -S /vt/vtdataroot/vt_${long_alias}/mysql.sock $keyspace diff --git a/examples/compose/default_vschema.json b/examples/compose/default_vschema.json new file mode 100644 index 00000000000..e0b50a66037 --- /dev/null +++ b/examples/compose/default_vschema.json @@ -0,0 +1,8 @@ +{ + "sharded": false, + "vindexes": { + "hash": { + "type": "hash" + } + } +} diff --git a/examples/compose/docker-compose.yml b/examples/compose/docker-compose.beginners.yml similarity index 72% rename from examples/compose/docker-compose.yml rename to examples/compose/docker-compose.beginners.yml index 561e6620cc7..4f23b688f1a 100644 --- a/examples/compose/docker-compose.yml +++ b/examples/compose/docker-compose.beginners.yml @@ -1,4 +1,4 @@ -version: "2.3" +version: "2.1" services: consul1: image: consul:latest @@ -60,7 +60,7 @@ services: - "15099:$WEB_PORT" - "$GRPC_PORT" - "15306:$MYSQL_PORT" - command: ["sh", "-c", "vtctl $TOPOLOGY_FLAGS SetReadWrite ${CELL}-1 & $$VTROOT/bin/vtgate \ + command: ["sh", "-c", "$$VTROOT/bin/vtgate \ $TOPOLOGY_FLAGS \ -logtostderr=true \ -port $WEB_PORT \ @@ -82,13 +82,37 @@ services: depends_on: - vtctld depends_on: - vttablet1: + vttablet101: condition: service_healthy - vttablet1: + schemaload: + image: vitess/base + command: + - sh + - -c + - /script/schemaload.sh + environment: + - TOPOLOGY_FLAGS + - WEB_PORT + - GRPC_PORT + - CELL + - KEYSPACE + - TARGETTAB + - SLEEPTIME + - VSCHEMA_FILE + - SCHEMA_FILES + - POST_LOAD_FILE + - EXTERNAL_DB + volumes: + - .:/script + depends_on: + vttablet101: + condition: service_healthy + + vttablet101: image: vitess/base ports: - - "15001:$WEB_PORT" + - "15101:$WEB_PORT" - "$GRPC_PORT" - "3306" volumes: @@ -107,18 +131,20 @@ services: - DB_USER - DB_PASS - DB_CHARSET - command: ["sh", "-c", "/script/vttablet-up.sh 1"] + - ROLE=master + command: ["sh", "-c", "/script/vttablet-up.sh 101"] depends_on: - vtctld healthcheck: - test: ["CMD-SHELL","curl localhost:$$WEB_PORT/debug/health"] - interval: 30s - timeout: 10s - retries: 10 - vttablet2: + test: ["CMD-SHELL","curl localhost:$$WEB_PORT/debug/health"] + interval: 30s + timeout: 10s + retries: 15 + + vttablet102: image: vitess/base ports: - - "15002:$WEB_PORT" + - "15102:$WEB_PORT" - "$GRPC_PORT" - "3306" volumes: @@ -135,14 +161,20 @@ services: - DB_USER - DB_PASS - DB_CHARSET - command: ["sh", "-c", "/script/vttablet-up.sh 2"] + command: ["sh", "-c", "/script/vttablet-up.sh 102"] depends_on: - vtctld - - vttablet1 - vttablet3: + - vttablet101 + healthcheck: + test: ["CMD-SHELL","curl localhost:$$WEB_PORT/debug/health"] + interval: 30s + timeout: 10s + retries: 15 + + vttablet103: image: vitess/base ports: - - "15003:$WEB_PORT" + - "15103:$WEB_PORT" - "$GRPC_PORT" - "3306" volumes: @@ -159,7 +191,12 @@ services: - DB_USER - DB_PASS - DB_CHARSET - command: ["sh", "-c", "/script/vttablet-up.sh 3"] + command: ["sh", "-c", "/script/vttablet-up.sh 103"] depends_on: - vtctld - - vttablet1 + - vttablet101 + healthcheck: + test: ["CMD-SHELL","curl localhost:$$WEB_PORT/debug/health"] + interval: 30s + timeout: 10s + retries: 15 \ No newline at end of file diff --git a/examples/compose/external_db/README.md b/examples/compose/external_db/README.md new file mode 100644 index 00000000000..2152c97b548 --- /dev/null +++ b/examples/compose/external_db/README.md @@ -0,0 +1,111 @@ +# Simulate external/remote database for Vitess using docker-compose + +This directory has a docker-compose that will bring up a mysql instance. +You can then point your vitess cluster to it to understand how to use Vitess for your existing database +when you cannot install Vitess on the mysql instance. + +First you will need to [install docker-compose](https://docs.docker.com/compose/install/). + + +### Create new docker-machine +Create a new docker-machine that will run your mysql container. +Creating a new machine allows you to more comprehensively test the remote functionality. +``` +vitess/examples/compose/external_db$ docker-machine create remote-db +``` + +Grab the docker-machine ip +``` +vitess/examples/compose/external_db$ docker-machine ip remote-db +192.168.99.101 +``` + +Set the environment variables for the remote-db machine +``` +vitess/examples/compose/external_db$ eval $(docker-machine ip remote-db) +``` + +### Start mysql +Start the mysql instance +``` +vitess/examples/compose/external_db$ docker-compose up -d +``` +This will do the following; +1. Starts mysql service and exposes it at `:3306` +2. Creates a `commerce` database with `users` table +3. Adds sample data to the users table +4. Starts a lightweight adminer container to interact with the database accessible at `:8081` +5. Default credentials + ``` + MYSQL_DB: commerce + MYSQL_USER: dbuser + MYSQL_PASSWORD: dbpass + MYSQL_ROOT_PASSWORD: pass + ``` + +### Confirm containers are up +Run the following +``` +vitess/examples/compose/external_db$ docker-compose ps +``` + +A valid response should look like below +```sh + Name Command State Ports +--------------------------------------------------------------------------------------------------------- +external_db_adminer_1 entrypoint.sh docker-php-e ... Up 0.0.0.0:8081->8080/tcp +external_db_db_1 docker-entrypoint.sh mysqld Up (healthy) 0.0.0.0:3306->3306/tcp, 33060/tcp +``` +You now have a mysql instance ready to be *migrated* to Vitess. + +### Start Vitess pointed to this remote database +Head on to [vitess compose instructions](../README.md ) + +If using docker-compose.beginners.yml, run; +``` +vitess/examples/compose$ cp docker-compose.beginners.yml docker-compose.yml +``` +Update your `.env` file with these; +``` +KEYSPACE=commerce +DB=commerce +EXTERNAL_DB=1 +DB_HOST= +DB_PORT=3306 +DB_USER=dbuser +DB_PASS=dbpass +DB_CHARSET=CHARACTER SET latin1 COLLATE latin1_swedish_ci +``` + + +If using `vtcompose` command, run; +``` +vitess/examples/compose$ go run vtcompose/vtcompose.go -keyspaceData="commerce:0:2::" -externalDbData="commerce::3306:dbuser:dbpass:CHARACTER SET latin1 COLLATE latin1_swedish_ci" +``` + +**Ensure you start Vitess in a different docker-machine!!** +If not, run; +``` +vitess/examples/compose$ docker-machine create vitess +vitess/examples/compose$ $(docker-machine env vitess) +``` + +Start Vitess +``` +vitess/examples/compose$ docker-compose up -d +``` + +You should now have Vitess running against your external database instance. + +* [Follow this guide for advanced usage](../README.md#advanced-usage "Advanced Usage" ) +* [See this for common issues](../README.md#common-errors "Common Issues" ) + +### Migrating to Vitess +Migrating to Vitess entirely can be done from; +a) The Vitess Control Panel at http://:15000 +b) The `lvtcl.sh` Helper Script; + +The steps are same +1. Do an EmergencyReparentShard to make a replica the new master. +2. Ran InitShardMaster on the new master. +3. If Vitess is wrong about who the MySQL master is, you can update it with TabletExternallyReparented \ No newline at end of file diff --git a/examples/compose/external_db/docker-compose.yml b/examples/compose/external_db/docker-compose.yml new file mode 100644 index 00000000000..5b3b28f1f9e --- /dev/null +++ b/examples/compose/external_db/docker-compose.yml @@ -0,0 +1,35 @@ +version: '2.1' + +volumes: + vol-db: + +services: + db: + build: + context: ./mysql + dockerfile: Dockerfile + restart: always + environment: + MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD:-pass} + MYSQL_DATABASE: ${MYSQL_DB:-commerce} + MYSQL_USER: ${MYSQL_USER:-dbuser} + MYSQL_PASSWORD: ${MYSQL_PASSWORD:-dbpass} + volumes: + - vol-db:/var/lib/mysql + - ./mysql/:/docker-entrypoint-initdb.d/ + - ./mysql/master_mysql56.cnf:/etc/mysql/conf.d/master_mysql56.cnf + - ./mysql/query.log:/var/log/mysql/query.log + - ./mysql/slow.log:/var/log/mysql/slow.log + healthcheck: + test: "/usr/bin/mysql --user=root --password=$${MYSQL_ROOT_PASSWORD} --execute \"SHOW DATABASES;\"" + timeout: 10s + retries: 10 + ports: + - "3306:3306" + + adminer: + image: adminer + environment: + ADMINER_DESIGN: rmsoft + ports: + - "8081:8080" diff --git a/examples/compose/external_db/mysql/Dockerfile b/examples/compose/external_db/mysql/Dockerfile new file mode 100644 index 00000000000..f44c63951e3 --- /dev/null +++ b/examples/compose/external_db/mysql/Dockerfile @@ -0,0 +1,2 @@ +FROM mysql:5.7 +COPY . /docker-entrypoint-initdb.d \ No newline at end of file diff --git a/examples/compose/external_db/mysql/commerce.sql b/examples/compose/external_db/mysql/commerce.sql new file mode 100644 index 00000000000..8154d91e7f5 --- /dev/null +++ b/examples/compose/external_db/mysql/commerce.sql @@ -0,0 +1,20 @@ +CREATE DATABASE IF NOT EXISTS commerce; +USE commerce; +DROP TABLE IF EXISTS users; +CREATE TABLE users ( + device_id BIGINT, + first_name VARCHAR(50), + last_name VARCHAR(50), + telephone BIGINT, + gender VARCHAR(16), + reference_id INT, + confidence INT, + coverage INT, + refstart DATETIME, + refstop DATETIME, + qrystart DATETIME, + qrystop DATETIME); + +LOAD DATA LOCAL INFILE '/docker-entrypoint-initdb.d/dataset.csv' INTO TABLE users FIELDS TERMINATED BY ','; + +ALTER TABLE users ADD id INT NOT NULL AUTO_INCREMENT PRIMARY KEY; \ No newline at end of file diff --git a/examples/compose/external_db/mysql/dataset.csv b/examples/compose/external_db/mysql/dataset.csv new file mode 100644 index 00000000000..f2af8d74ce7 --- /dev/null +++ b/examples/compose/external_db/mysql/dataset.csv @@ -0,0 +1,1000 @@ +1,Elianore,Dunbleton,867-921-5436,Female,1,4,90,2018-11-20 00:23:59,2018-02-11 11:32:09,2018-06-18 23:40:59,2018-07-14 00:59:56 +2,Isa,Gilfoyle,539-533-8647,Male,7,86,65,2018-03-22 18:52:41,2019-01-16 21:08:18,2019-01-03 10:48:54,2018-08-29 14:52:14 +3,Millicent,Jedrys,184-899-3979,Female,5,30,17,2018-06-29 14:14:44,2018-06-07 05:03:57,2018-04-08 03:56:39,2018-02-12 06:41:48 +4,Davey,Sutch,862-838-8206,Male,1,62,94,2018-11-14 06:47:18,2018-08-08 22:44:26,2018-07-12 21:09:27,2018-03-04 16:23:22 +5,Adiana,Strowger,792-848-5008,Female,6,97,75,2018-08-07 01:32:59,2018-08-06 16:19:48,2019-01-20 13:11:37,2018-09-02 22:39:39 +6,Oby,Winthrop,522-736-9711,Male,7,95,11,2018-09-29 06:49:44,2018-02-02 11:07:25,2018-08-17 12:49:31,2018-06-03 13:27:48 +7,Berte,Beldon,947-708-5622,Female,6,3,26,2018-11-21 14:55:27,2018-11-15 17:16:04,2018-01-23 06:12:07,2018-08-30 14:40:37 +8,Logan,Atack,103-849-8439,Male,1,20,86,2019-01-04 01:18:38,2018-09-20 23:59:42,2018-05-10 13:14:24,2018-09-25 10:05:29 +9,Vania,Rosenblum,302-132-8289,Female,5,85,32,2018-03-31 00:24:32,2018-07-28 14:50:39,2018-04-19 12:32:49,2018-04-03 08:31:11 +10,Giffie,Lindblad,312-429-3236,Male,1,52,65,2018-04-15 15:34:57,2018-09-03 05:54:49,2019-01-05 06:42:27,2018-11-05 21:47:08 +11,Bili,Weigh,442-992-2387,Female,5,88,97,2018-12-01 04:31:51,2018-08-22 15:52:23,2018-12-07 23:25:46,2018-08-08 07:47:35 +12,Marlin,Stair,854-643-9633,Male,1,62,61,2018-05-30 14:08:25,2018-03-02 03:34:27,2018-03-21 22:43:12,2018-06-03 18:02:22 +13,Dacey,Corradino,364-281-2170,Female,3,82,19,2018-04-10 01:42:36,2019-01-08 17:42:03,2018-05-20 04:07:33,2018-10-14 03:57:57 +14,Caresse,Santon,221-929-9690,Female,7,97,50,2018-11-20 23:15:03,2019-01-01 18:46:08,2018-04-08 05:49:39,2018-10-04 04:00:37 +15,Trixi,Westphalen,681-738-3653,Female,7,100,87,2018-07-09 18:04:01,2018-11-21 04:36:24,2018-11-25 09:43:50,2018-09-10 07:40:31 +16,Pauline,Breslauer,821-177-6696,Female,6,63,24,2018-11-02 19:56:35,2018-02-09 07:46:00,2019-01-08 03:21:02,2018-09-18 08:18:06 +17,Meridith,Briddock,716-528-7645,Female,3,72,24,2018-11-30 20:13:26,2018-04-04 00:17:34,2018-07-12 04:42:43,2018-07-13 02:53:00 +18,Cordy,Sothern,733-369-1763,Male,6,72,5,2018-08-19 02:02:51,2018-10-01 16:39:38,2019-01-18 12:58:50,2018-04-26 11:01:54 +19,Thom,Swarbrigg,566-424-7472,Male,3,56,29,2018-01-25 19:13:40,2018-09-06 20:39:48,2018-12-23 14:49:40,2018-09-19 13:03:37 +20,Amelina,Ekell,514-321-8056,Female,5,42,43,2018-12-15 14:21:28,2018-08-07 02:53:55,2018-09-30 04:29:03,2018-08-02 18:29:13 +21,Cesare,Lahy,446-382-1825,Male,2,32,10,2018-07-08 01:24:43,2018-03-24 15:25:21,2018-11-15 18:50:17,2018-03-27 19:18:16 +22,Elnora,Cheale,489-718-9700,Female,6,12,73,2018-10-26 17:34:35,2018-12-22 05:44:59,2018-05-09 01:25:04,2018-09-21 18:40:44 +23,Hadrian,Snarie,859-447-4644,Male,1,18,4,2018-08-31 12:15:30,2018-04-16 11:19:30,2018-02-28 10:55:26,2018-10-31 07:05:29 +24,Ravid,Meriott,518-484-9203,Male,1,83,12,2018-12-01 21:38:00,2018-02-12 17:25:00,2018-09-18 16:34:45,2018-09-08 17:32:17 +25,Elenore,De Gowe,180-237-8349,Female,7,75,3,2018-03-20 20:52:00,2018-12-22 19:52:58,2018-07-06 23:18:01,2018-08-12 22:02:21 +26,Juieta,Pridie,278-696-9233,Female,1,93,57,2018-09-04 18:45:44,2018-06-04 17:38:47,2018-11-16 10:31:12,2018-07-15 10:27:10 +27,Neddie,Mosedall,956-605-6537,Male,3,94,19,2018-04-09 13:54:22,2018-04-12 10:58:25,2018-08-21 10:57:27,2018-08-22 20:29:53 +28,Octavius,Fordham,797-217-3886,Male,3,32,82,2018-11-23 16:25:55,2018-11-15 12:08:34,2018-10-28 03:46:45,2018-06-22 03:16:15 +29,Edwin,Tapson,578-261-4030,Male,7,83,39,2018-12-16 01:07:34,2018-12-27 23:39:47,2018-12-03 00:30:10,2018-03-09 18:09:49 +30,Korry,Dyos,108-910-1353,Female,3,80,93,2018-06-14 09:39:58,2018-08-12 21:17:11,2018-09-14 12:22:43,2018-04-08 23:31:12 +31,Kenn,Leist,300-420-7371,Male,5,100,90,2018-11-24 01:42:36,2018-10-27 21:31:19,2019-01-05 02:32:45,2018-11-24 06:45:27 +32,Eldredge,Kemmis,451-974-5763,Male,2,44,42,2018-11-18 11:28:34,2018-02-17 08:01:53,2018-08-21 19:25:26,2018-12-23 12:29:15 +33,Suzanne,Matthiae,560-959-3441,Female,4,56,7,2018-05-04 04:19:19,2018-04-11 11:59:42,2018-02-01 16:22:38,2018-11-15 19:58:02 +34,Josh,Callendar,719-551-3561,Male,4,61,56,2018-10-12 07:20:47,2018-06-14 12:53:31,2018-07-20 09:35:33,2018-03-26 05:54:27 +35,Ian,Thoresby,392-740-5436,Male,7,77,8,2018-03-04 19:37:23,2018-08-07 02:19:40,2018-09-24 07:54:33,2018-07-09 15:36:52 +36,Cordi,Vanichkin,773-231-4509,Female,1,99,90,2018-07-02 02:43:15,2019-01-20 04:28:54,2018-09-05 05:02:38,2019-01-08 04:08:00 +37,Ariel,Le land,917-249-6942,Male,5,9,45,2018-04-29 18:48:49,2018-06-23 08:15:12,2018-01-22 01:29:55,2019-01-03 21:24:23 +38,Delila,Assard,119-780-7155,Female,3,83,70,2018-12-01 01:09:53,2018-05-22 00:23:40,2018-05-19 13:53:02,2018-02-17 03:43:18 +39,Deny,Cullrford,100-298-0840,Female,5,50,39,2018-05-09 23:21:57,2018-05-31 23:46:32,2018-12-03 09:53:47,2019-01-12 10:16:35 +40,Frannie,Sharer,410-855-0951,Male,6,72,43,2018-05-12 06:05:03,2018-04-21 17:15:14,2018-08-30 07:18:18,2018-06-20 04:51:13 +41,Jonis,Lintin,803-933-8038,Female,4,89,84,2018-09-13 20:13:23,2018-08-28 18:20:52,2018-03-13 03:07:16,2018-03-05 07:10:50 +42,Bessie,Hackett,443-436-4804,Female,4,20,36,2018-06-13 07:34:49,2018-06-01 11:23:42,2018-10-19 12:40:14,2018-02-10 12:37:05 +43,Gayel,Tabard,704-527-0263,Female,6,40,44,2019-01-04 14:41:19,2018-04-15 00:21:22,2018-12-30 07:24:38,2018-05-02 21:10:48 +44,Ardisj,Ridder,899-877-7365,Female,1,21,84,2018-06-13 21:09:11,2018-12-02 20:33:23,2018-03-25 07:43:03,2018-10-12 11:26:41 +45,Hammad,Stroband,874-825-9046,Male,3,30,83,2018-09-14 06:04:39,2018-10-23 13:35:20,2018-03-10 08:19:18,2018-07-18 20:31:55 +46,Darius,Sorel,750-599-8665,Male,7,98,76,2018-09-17 22:09:17,2018-06-02 14:07:06,2018-12-08 15:52:18,2018-05-05 12:38:37 +47,Dido,Stockin,339-433-0084,Female,1,89,59,2018-04-30 07:42:06,2018-10-18 22:27:31,2018-11-11 05:06:09,2019-01-01 14:19:17 +48,Sholom,Cobbing,828-431-0433,Male,4,53,86,2018-11-03 23:21:35,2018-10-23 13:33:47,2018-09-03 06:25:27,2019-01-18 06:26:39 +49,Melinde,Hynd,283-446-7128,Female,5,97,84,2018-07-31 06:28:22,2018-10-24 04:00:28,2018-07-28 03:47:24,2018-02-10 19:44:46 +50,Hedvige,Fontenot,534-558-8139,Female,4,94,62,2018-07-15 15:22:39,2018-03-20 18:21:30,2018-03-04 17:34:45,2018-05-25 22:41:39 +51,Killian,Gilmartin,722-114-3059,Male,1,47,8,2018-08-24 01:48:56,2018-07-21 08:24:06,2018-11-05 06:28:14,2018-05-06 13:37:33 +52,Inness,O'Cullinane,630-746-2431,Male,3,71,93,2018-06-14 22:12:56,2018-04-12 23:09:39,2018-02-02 09:42:12,2018-11-14 01:06:15 +53,Doretta,Galiford,528-456-0043,Female,3,84,95,2018-09-09 15:03:41,2018-03-30 03:54:32,2018-10-03 10:51:33,2018-12-15 22:54:24 +54,Alicia,Kemmons,695-461-8136,Female,7,16,82,2018-03-26 20:29:48,2018-03-25 15:58:54,2018-01-30 03:52:35,2018-02-11 04:14:39 +55,Brandea,Nannizzi,215-545-0363,Female,2,86,20,2018-11-05 15:18:22,2018-02-18 13:05:40,2018-11-27 14:37:52,2018-05-04 23:08:00 +56,Jordan,Parkman,473-392-8118,Male,1,41,46,2018-09-27 14:56:49,2018-04-27 06:35:47,2018-02-04 22:54:44,2018-12-06 04:53:24 +57,Bourke,Whittaker,712-907-5729,Male,2,71,6,2018-10-19 17:00:36,2018-12-02 03:28:48,2018-04-13 01:02:14,2018-04-11 23:42:42 +58,Honey,Adriano,822-890-9194,Female,4,31,95,2018-06-18 04:19:51,2018-03-12 03:05:16,2018-02-02 00:52:15,2019-01-07 13:33:51 +59,Tracie,Warrender,617-331-6980,Male,3,69,37,2018-07-09 15:19:55,2018-07-26 13:00:13,2018-03-06 19:39:06,2018-10-05 14:56:58 +60,Billy,Eadmead,556-100-5109,Female,6,16,63,2018-10-04 07:52:43,2018-07-02 07:34:18,2018-05-03 01:03:27,2018-06-03 11:04:04 +61,Jamesy,Mellenby,554-299-7370,Male,6,53,82,2018-10-25 22:03:32,2018-05-03 02:36:00,2018-01-26 21:04:03,2018-09-15 17:06:05 +62,Goober,Mawby,765-918-7080,Male,1,70,20,2018-08-05 15:03:53,2018-09-15 16:38:46,2018-03-02 01:37:07,2018-12-15 23:40:37 +63,Zach,Tompkins,798-498-7252,Male,6,45,65,2018-06-26 09:42:40,2018-04-20 17:05:50,2018-09-18 16:58:53,2018-06-24 00:57:54 +64,Augustine,Cornbill,600-318-2489,Male,7,30,38,2018-02-08 08:08:53,2018-08-14 07:05:17,2018-10-14 01:12:13,2018-09-20 19:42:49 +65,Cort,Rosingdall,915-533-3544,Male,5,81,82,2019-01-18 02:20:54,2018-03-12 08:02:19,2018-05-13 15:10:29,2018-05-16 21:38:26 +66,Broddie,Dziwisz,404-420-5799,Male,7,3,22,2018-08-30 21:01:34,2018-03-13 06:37:11,2018-04-27 16:13:37,2018-12-09 08:39:26 +67,Clarke,Goodge,499-845-2443,Male,2,14,95,2018-04-02 10:32:42,2018-04-27 00:42:32,2018-05-29 08:36:44,2018-04-01 23:40:09 +68,Madelyn,Knight,724-972-4025,Female,6,12,57,2018-04-25 04:45:31,2018-08-13 14:34:24,2018-05-25 09:58:32,2018-09-02 04:03:25 +69,Bibby,Pace,266-593-6853,Female,2,11,87,2018-04-12 22:35:20,2018-03-10 11:28:13,2018-04-12 15:22:53,2018-04-21 18:57:47 +70,Nedi,Tambling,534-778-4478,Female,5,69,95,2018-04-27 15:43:27,2018-07-27 11:55:14,2018-04-05 07:02:04,2018-08-26 01:25:05 +71,Veronica,Alejandro,208-365-2416,Female,1,22,32,2018-04-09 03:42:21,2018-03-30 02:47:59,2018-02-08 16:43:52,2018-03-10 19:51:53 +72,Cecil,Walewicz,133-144-8036,Male,3,58,23,2018-12-26 06:56:13,2018-06-08 09:09:35,2018-02-16 16:39:15,2018-12-21 00:33:53 +73,Salem,Armell,186-906-5312,Male,7,25,47,2018-10-08 00:28:48,2018-09-03 00:55:23,2018-01-31 20:13:21,2018-04-06 20:30:43 +74,Brook,Buckston,714-565-2523,Female,1,13,92,2018-02-12 13:53:51,2019-01-10 22:17:38,2018-08-03 18:27:58,2018-09-06 10:38:45 +75,Benson,MacParlan,881-685-7375,Male,7,95,39,2018-04-07 06:40:34,2018-05-10 22:04:48,2018-10-06 01:07:35,2018-12-25 18:36:48 +76,Lukas,Kittle,845-541-8229,Male,1,52,85,2018-04-14 08:08:32,2018-08-21 12:21:22,2018-11-17 23:14:34,2018-06-21 02:48:31 +77,Jessa,Claus,611-425-9914,Female,7,99,56,2018-10-22 02:50:57,2018-11-25 03:44:27,2018-06-30 15:33:40,2018-07-02 03:59:50 +78,Hieronymus,Schurig,840-630-9703,Male,6,98,77,2018-01-24 18:01:57,2018-06-05 08:22:05,2018-07-12 07:09:14,2018-07-31 08:09:20 +79,Quintilla,Risborough,367-606-2805,Female,4,15,15,2018-10-24 13:48:18,2018-12-16 11:17:17,2018-05-17 19:15:19,2018-06-22 16:46:31 +80,Arv,Billingsley,438-164-1166,Male,3,54,65,2018-07-21 13:35:44,2018-10-07 14:37:53,2018-11-16 15:38:23,2018-10-19 21:07:38 +81,Happy,Rodrigo,427-752-3843,Female,2,28,25,2018-01-28 21:31:16,2018-07-06 04:48:40,2018-02-19 10:50:55,2018-10-20 15:58:59 +82,Cos,Chalfain,609-228-7131,Male,6,12,80,2018-02-24 18:06:52,2018-07-21 03:12:50,2018-02-22 09:53:50,2018-12-04 18:31:35 +83,Dael,Crother,249-141-1807,Male,3,11,86,2018-09-09 23:04:41,2018-02-24 13:19:31,2018-11-05 15:18:33,2018-12-23 18:55:24 +84,Evin,Tettley,974-233-5051,Male,1,57,61,2018-12-26 14:24:36,2018-05-28 19:09:40,2018-09-18 10:01:10,2018-04-04 21:11:05 +85,Bethanne,Hynson,395-152-0590,Female,5,51,39,2018-11-12 01:12:14,2018-07-21 02:07:45,2019-01-06 17:16:22,2018-11-15 16:58:09 +86,Adrian,Sapson,962-473-8077,Female,4,19,63,2018-02-13 14:27:28,2018-06-26 14:23:38,2018-09-17 04:28:22,2018-07-19 18:25:11 +87,Zaneta,Alforde,961-173-4877,Female,2,70,67,2018-11-04 11:27:20,2018-06-09 18:02:24,2018-08-17 03:13:55,2018-09-02 00:28:34 +88,Grady,Kobiera,687-321-5987,Male,1,62,96,2018-06-23 20:06:04,2018-02-08 04:03:21,2018-12-05 23:36:55,2018-10-26 14:17:35 +89,Dominique,Carslake,230-143-4475,Male,4,38,64,2018-05-19 01:14:57,2018-09-24 20:05:20,2018-06-26 12:15:04,2018-10-30 18:21:59 +90,Julietta,Gude,585-759-9173,Female,7,59,75,2018-11-25 20:42:33,2018-08-31 21:59:40,2018-12-31 21:04:44,2018-11-23 04:31:37 +91,Lothaire,Macrow,510-775-2964,Male,1,91,59,2018-04-22 14:12:47,2018-07-05 11:15:49,2018-06-04 12:44:19,2018-10-12 10:28:46 +92,Agneta,Trematick,391-964-4713,Female,6,6,91,2018-01-31 13:00:06,2018-11-24 20:48:15,2018-07-27 00:12:28,2018-02-17 08:41:55 +93,Pet,Padgett,690-476-6060,Female,2,17,84,2018-03-21 11:54:39,2018-03-08 01:51:40,2018-12-21 16:41:23,2018-02-07 14:47:44 +94,Barclay,Binion,516-626-1251,Male,4,49,46,2018-10-19 13:16:50,2018-06-25 01:26:53,2018-02-23 06:44:17,2018-10-08 11:01:59 +95,Dillie,Quilleash,676-581-4684,Male,3,27,14,2019-01-02 01:50:23,2019-01-02 04:16:15,2018-07-21 11:54:44,2018-03-06 02:17:37 +96,Marissa,Twinterman,855-444-0657,Female,6,52,62,2018-07-27 09:41:53,2018-03-18 21:07:51,2018-09-05 04:45:41,2018-05-01 14:08:21 +97,Perl,Braun,639-977-9224,Female,7,93,88,2018-03-12 07:21:26,2018-11-12 18:45:36,2018-09-10 10:45:15,2018-09-30 10:28:01 +98,Gwenette,Jozef,804-642-8405,Female,1,67,64,2018-05-02 20:04:22,2018-05-25 14:26:42,2018-12-22 04:00:00,2018-04-27 17:36:21 +99,Gabbi,Nassey,998-336-4318,Female,3,35,79,2018-11-13 07:58:46,2018-02-23 01:11:32,2018-11-08 17:30:31,2018-07-24 03:14:25 +100,Susana,Ebben,826-329-4492,Female,5,9,98,2018-07-08 08:40:45,2018-07-12 00:41:34,2018-10-12 15:33:58,2018-06-16 15:33:32 +101,Mallorie,Marsters,637-209-9862,Female,5,18,34,2018-07-30 15:18:09,2018-09-23 17:22:45,2018-12-21 17:11:36,2018-07-06 19:42:09 +102,Marley,Bethell,102-272-8411,Female,6,70,7,2018-10-08 12:25:07,2018-04-13 04:50:24,2018-03-01 09:20:29,2018-04-05 02:02:24 +103,Genvieve,McMeekin,679-490-4369,Female,3,7,25,2018-02-25 15:34:48,2018-06-24 16:32:10,2018-07-03 20:04:57,2018-12-11 02:53:30 +104,Bartram,Leahey,830-491-8399,Male,3,100,57,2018-10-18 18:39:57,2018-04-08 02:16:41,2018-07-20 01:10:35,2018-06-20 09:41:56 +105,Livvyy,Thornewell,872-138-4425,Female,6,58,58,2019-01-17 09:36:59,2018-04-13 07:25:55,2018-11-28 12:44:14,2018-07-14 04:05:13 +106,Gabriella,Cornish,202-570-6308,Female,7,79,67,2018-08-25 01:20:02,2018-11-30 22:05:13,2018-10-21 11:47:58,2018-11-20 04:28:53 +107,Humberto,Lanfranchi,636-653-6377,Male,3,18,85,2018-08-21 03:38:03,2018-09-01 07:20:38,2018-04-27 04:23:16,2018-08-15 14:45:48 +108,Othella,Asaaf,386-100-6369,Female,4,59,93,2018-05-20 17:17:26,2018-10-23 01:32:55,2018-09-20 03:27:06,2018-12-17 21:11:18 +109,Mil,Booij,494-405-6566,Female,5,88,97,2018-07-12 19:07:28,2018-02-14 12:57:18,2018-12-11 19:22:18,2018-11-23 12:41:41 +110,Orel,Blaxland,309-372-2193,Female,7,30,93,2018-11-18 23:18:41,2018-06-21 19:30:46,2018-09-15 13:43:25,2018-02-04 09:51:54 +111,Sibeal,Fennelow,543-514-6831,Female,6,92,56,2018-10-09 14:48:56,2018-12-18 22:29:16,2018-04-09 03:30:48,2018-04-04 18:11:19 +112,Sidnee,Thorby,687-609-9785,Male,2,30,12,2018-03-28 10:27:39,2018-07-01 07:12:38,2018-02-16 12:58:34,2018-11-16 01:37:38 +113,Lora,Ridewood,164-690-9005,Female,1,37,55,2018-11-13 21:13:39,2018-09-06 23:00:39,2019-01-17 10:31:22,2018-12-05 22:14:39 +114,Velma,Brolan,359-817-6834,Female,6,26,38,2019-01-16 21:47:15,2018-11-25 16:54:49,2018-10-07 01:07:24,2018-10-11 01:14:02 +115,Vassili,Kirkbride,287-966-8144,Male,6,52,16,2018-12-20 23:23:45,2018-12-21 08:42:29,2018-02-25 02:07:40,2018-06-28 04:39:19 +116,Nettie,Bulmer,357-176-0651,Female,5,16,44,2018-09-19 15:07:17,2018-03-16 17:55:44,2018-09-06 22:48:36,2018-04-28 23:48:07 +117,Elyn,Matthew,176-489-8486,Female,4,25,95,2018-04-10 12:26:47,2019-01-10 03:12:46,2018-07-28 23:51:46,2018-07-07 16:15:50 +118,Nat,Enderlein,480-924-1165,Male,4,94,42,2018-09-10 06:56:16,2018-04-24 02:55:47,2018-03-17 15:48:28,2018-04-30 06:11:27 +119,Allister,Laundon,267-536-1588,Male,6,86,21,2018-08-21 09:06:13,2018-11-26 09:47:45,2018-04-05 15:01:24,2018-01-21 02:29:49 +120,Suzy,Dubery,631-694-1983,Female,5,54,24,2018-07-12 11:08:05,2018-07-21 06:22:14,2018-09-04 03:44:08,2018-11-14 04:59:58 +121,Reinaldo,Assel,927-809-0971,Male,3,4,44,2018-10-17 17:15:04,2018-12-24 21:34:45,2019-01-15 07:39:25,2018-02-06 19:16:38 +122,Claudell,Reckus,196-391-8789,Male,1,34,75,2018-08-12 02:29:09,2018-11-28 02:43:43,2018-08-21 09:11:37,2018-07-14 12:51:48 +123,Kary,Jee,656-508-4636,Female,2,67,47,2018-12-17 10:42:46,2018-05-16 14:59:10,2018-12-23 02:44:31,2018-12-19 01:28:44 +124,Giustino,Tinan,292-383-3412,Male,7,100,96,2018-02-05 08:16:51,2018-04-10 02:46:18,2018-12-07 23:33:47,2018-03-25 18:50:56 +125,Matthew,Palmer,562-655-9301,Male,5,87,100,2018-07-14 00:43:30,2018-01-22 19:53:17,2018-05-18 08:37:49,2018-04-16 10:03:59 +126,Helge,Paradyce,454-788-5166,Female,4,31,87,2018-12-29 12:15:52,2018-02-08 19:33:17,2018-12-29 06:51:56,2018-11-11 03:52:39 +127,Anthe,Cullinan,517-178-4457,Female,4,61,14,2018-07-10 05:46:54,2018-12-22 09:39:32,2018-12-06 16:59:53,2018-12-30 08:24:22 +128,Cindy,Bellie,284-376-7890,Female,6,26,95,2018-02-04 23:09:03,2018-09-06 16:30:50,2018-05-25 00:39:04,2018-12-20 19:03:33 +129,Deva,Branthwaite,272-973-9361,Female,5,4,74,2018-06-05 05:56:15,2018-06-26 03:23:22,2018-06-06 00:42:51,2018-12-01 12:32:06 +130,Karen,Frank,495-748-4715,Female,6,55,54,2018-10-26 02:19:25,2018-04-11 12:50:31,2019-01-12 15:29:42,2018-12-23 04:07:28 +131,Batsheva,Wressell,364-562-3308,Female,2,93,2,2018-12-08 11:50:47,2018-10-05 08:11:01,2018-12-29 23:04:37,2018-10-13 09:59:34 +132,Damian,Devon,617-622-5769,Male,1,81,84,2018-03-03 22:21:45,2018-02-09 02:46:29,2018-02-04 03:39:23,2018-06-24 17:15:50 +133,Mischa,Feldbrin,941-794-4981,Male,2,17,93,2018-07-05 04:20:06,2018-11-22 10:46:44,2018-10-25 23:05:17,2018-08-04 04:19:58 +134,Remus,Mochar,964-251-2864,Male,2,78,88,2018-05-08 23:51:18,2019-01-19 19:38:55,2018-06-13 09:14:44,2019-01-10 12:37:02 +135,Cleon,Ambroise,790-235-3681,Male,3,38,95,2018-08-11 11:07:40,2018-07-06 04:03:45,2018-12-18 09:47:22,2018-03-31 14:59:58 +136,Sidney,Duthy,739-113-2227,Male,4,95,79,2018-09-25 19:41:46,2018-09-05 07:30:26,2018-03-21 18:52:33,2018-04-25 13:58:28 +137,Xavier,Gon,942-422-7024,Male,5,35,47,2018-09-05 22:08:31,2018-05-10 20:19:08,2018-06-25 18:32:07,2018-04-11 04:44:32 +138,Ara,Gwyllt,450-595-4186,Male,4,4,28,2018-10-28 21:12:39,2018-02-13 08:26:45,2018-06-16 21:44:05,2018-08-01 11:08:43 +139,Libbey,Millwall,764-602-4598,Female,7,89,31,2019-01-14 17:04:08,2018-02-22 03:01:08,2018-02-27 08:56:59,2018-11-09 13:18:23 +140,Rosalynd,Wellard,798-378-3350,Female,4,58,44,2018-07-13 19:23:05,2018-11-20 20:46:20,2018-01-31 02:28:58,2018-10-25 13:31:05 +141,Reinaldo,O'Dea,896-868-5961,Male,2,72,69,2018-08-08 04:21:04,2018-06-23 08:34:34,2018-08-31 08:41:08,2018-11-19 09:43:28 +142,Veradis,Holyard,706-725-9446,Female,3,78,56,2018-09-05 17:38:33,2018-05-04 13:04:38,2018-11-05 12:46:29,2018-09-25 08:56:54 +143,Birdie,Collerd,319-380-7196,Female,2,22,1,2018-10-16 19:45:08,2018-08-05 06:38:47,2018-11-22 11:10:39,2018-10-20 09:48:22 +144,Sada,Schout,825-204-2108,Female,7,88,10,2018-04-13 13:44:13,2018-06-06 14:39:37,2018-11-09 10:29:00,2018-09-15 05:38:03 +145,Ambros,Mayoral,819-227-9360,Male,7,50,91,2018-03-27 15:27:05,2018-08-02 02:18:35,2018-06-27 17:10:44,2018-07-21 14:18:29 +146,Emile,Abraham,622-769-6584,Male,6,10,44,2018-09-15 10:24:46,2018-07-10 07:58:58,2018-06-18 22:49:01,2018-04-20 09:07:25 +147,Lira,Reboulet,983-623-7858,Female,4,54,39,2018-06-27 09:11:33,2018-10-01 07:52:19,2018-10-21 09:48:43,2018-09-09 22:17:51 +148,Bucky,Dubery,127-215-3377,Male,1,13,5,2018-02-15 22:03:55,2018-10-15 16:35:39,2018-02-20 10:22:26,2018-11-05 12:56:42 +149,Ced,Meert,482-685-6526,Male,1,85,40,2018-11-09 04:11:10,2019-01-16 14:34:41,2018-05-22 12:18:01,2018-03-13 13:09:46 +150,Hamlen,Boyson,723-641-9907,Male,7,3,25,2018-07-08 10:27:28,2018-09-06 08:34:00,2018-10-19 17:18:48,2018-02-22 19:31:50 +151,Scotty,Bromell,605-116-4137,Male,4,44,83,2018-02-03 11:10:35,2018-03-05 15:14:24,2018-06-20 01:47:46,2018-04-09 17:34:46 +152,Betti,Cuttelar,947-869-1635,Female,7,31,68,2018-07-14 23:35:44,2018-09-07 08:03:02,2018-05-02 15:32:32,2018-02-26 15:33:55 +153,Lothario,Whellams,959-671-9821,Male,3,91,85,2018-12-17 02:20:59,2018-08-31 16:54:24,2018-09-30 18:16:21,2018-06-06 21:30:55 +154,Maurits,Eisenberg,612-730-0598,Male,5,95,2,2018-07-11 05:38:06,2018-01-26 15:01:11,2018-11-11 22:30:48,2018-04-16 07:20:25 +155,Jeffry,Wilprecht,420-521-7374,Male,2,2,19,2018-07-31 12:28:42,2018-03-19 23:14:58,2018-11-29 11:25:28,2018-02-19 02:42:46 +156,Victor,Grinter,303-176-4062,Male,3,28,82,2018-04-15 17:22:33,2018-04-26 11:56:35,2018-10-06 23:26:58,2018-04-05 07:32:13 +157,Sonnie,Lobe,794-424-7798,Male,1,68,99,2018-12-23 13:36:28,2018-11-24 21:42:21,2018-03-23 12:37:58,2018-06-26 15:29:05 +158,Krishna,Fletcher,520-484-4343,Male,5,77,26,2018-05-15 11:17:35,2018-12-22 22:52:12,2018-05-10 22:50:32,2018-05-05 21:38:09 +159,Kerrie,Bartholomieu,654-465-0213,Female,4,7,56,2018-11-02 19:08:33,2018-01-27 09:11:25,2018-12-13 16:53:49,2018-05-06 13:16:06 +160,Rasla,Dibbs,192-692-8022,Female,5,58,38,2018-05-13 16:41:12,2018-12-17 01:00:54,2018-08-19 15:33:37,2019-01-11 00:33:40 +161,Mellisa,Prinn,884-570-1200,Female,3,2,44,2018-06-17 15:55:01,2018-02-09 22:16:46,2018-01-21 11:35:44,2018-03-22 01:43:34 +162,Shandeigh,Prise,284-912-2475,Female,1,24,63,2018-04-16 10:09:01,2018-09-06 02:59:22,2018-05-21 00:23:45,2018-05-18 15:59:58 +163,Aline,Pockey,145-621-3349,Female,5,46,99,2018-07-08 01:50:19,2018-07-23 03:08:04,2018-07-25 04:19:37,2018-08-02 04:28:24 +164,Quinton,Filon,646-285-5370,Male,7,71,90,2018-09-26 09:06:43,2018-09-15 14:33:28,2018-11-23 04:26:39,2019-01-20 06:07:08 +165,Brena,Bentke,336-549-2800,Female,6,52,73,2018-02-07 03:32:01,2018-09-21 09:41:58,2018-08-01 23:49:56,2018-04-24 04:41:42 +166,Kessia,Bentote,261-293-3478,Female,7,34,27,2019-01-03 17:12:12,2018-01-28 01:36:43,2018-09-06 07:29:49,2018-07-16 11:22:52 +167,Serene,Jellett,617-490-3045,Female,4,8,12,2018-08-01 05:18:42,2018-08-21 11:58:23,2018-02-17 11:36:57,2018-12-29 13:38:10 +168,Drugi,Chainey,642-531-9743,Male,1,27,14,2019-01-06 06:11:34,2018-11-02 16:07:48,2019-01-07 21:38:11,2018-10-26 19:58:30 +169,Benjamen,Angric,161-599-1534,Male,6,80,80,2018-03-25 19:49:25,2018-08-23 06:12:13,2018-05-09 05:22:56,2018-04-03 12:50:17 +170,Augustine,de Werk,986-128-9745,Male,7,40,35,2018-09-07 12:55:20,2018-09-15 16:46:53,2018-02-12 14:00:28,2018-02-20 11:54:00 +171,Rorke,Laidlaw,818-603-8046,Male,1,99,95,2018-12-25 21:27:03,2018-12-15 12:30:46,2018-11-06 04:14:51,2018-11-30 18:51:21 +172,Clywd,Cawdron,118-860-8931,Male,3,12,48,2018-10-28 00:46:43,2018-07-04 11:34:45,2018-01-24 04:40:57,2018-11-08 13:52:59 +173,Maudie,Habbijam,781-157-2628,Female,1,79,35,2018-11-30 12:07:21,2018-03-07 00:30:04,2018-11-14 11:01:28,2018-12-25 08:37:17 +174,Gina,Adamovitz,873-120-9534,Female,1,99,41,2018-10-15 08:16:08,2018-02-02 10:04:20,2018-03-11 05:28:50,2018-08-15 16:28:04 +175,Dorey,Berkeley,856-131-2818,Female,5,8,45,2018-06-14 02:47:10,2018-12-04 16:14:29,2018-02-20 02:19:22,2018-04-14 04:00:28 +176,Ashli,Stanistrete,507-365-9155,Female,3,50,85,2019-01-15 15:53:25,2018-09-08 00:21:37,2018-09-08 14:26:57,2018-08-12 18:04:42 +177,Aleta,Jessard,640-184-4123,Female,1,63,42,2018-12-13 11:45:35,2018-07-13 05:43:20,2018-07-19 01:29:59,2018-08-19 10:17:25 +178,Conney,Tansly,619-324-6788,Male,7,18,68,2018-02-06 08:22:33,2018-02-09 16:00:31,2018-02-17 20:35:12,2018-09-01 00:28:07 +179,Chaddie,Curling,967-821-4721,Male,3,50,28,2018-04-18 18:52:52,2018-10-04 03:42:09,2018-11-06 23:55:33,2018-12-23 04:01:13 +180,Skyler,Shard,173-185-5465,Male,7,48,76,2018-03-21 23:42:54,2018-05-22 07:52:04,2018-02-28 18:02:47,2018-08-20 09:21:32 +181,Alair,Bruggen,225-747-4685,Male,5,45,4,2018-03-13 03:01:40,2018-04-30 23:24:34,2018-04-25 03:14:01,2018-07-26 19:41:29 +182,Forester,Rackstraw,111-188-6870,Male,6,11,43,2018-09-26 04:05:12,2018-08-25 04:59:08,2018-02-09 16:50:13,2018-06-10 06:53:15 +183,Stinky,Klassmann,628-447-6394,Male,5,42,77,2018-12-29 18:37:51,2018-01-31 04:16:33,2018-05-27 09:10:31,2018-02-03 20:09:44 +184,Gabriella,Weeds,978-256-0633,Female,3,17,50,2018-10-10 14:56:11,2019-01-19 07:53:13,2018-08-28 10:02:39,2018-05-03 15:01:38 +185,Ingeborg,Swine,765-792-5768,Female,5,39,37,2018-10-13 03:17:12,2018-11-25 20:17:22,2018-08-25 21:54:45,2018-12-04 07:44:58 +186,Kain,Everingham,945-715-9320,Male,7,52,80,2018-10-22 01:58:35,2018-04-16 11:48:35,2018-02-22 17:07:19,2018-12-15 01:59:16 +187,Noble,Swadlinge,928-764-8545,Male,7,24,75,2018-07-02 20:12:53,2018-07-19 00:23:08,2018-08-06 21:50:01,2018-05-04 08:56:30 +188,Amber,Shropshire,983-928-3309,Female,1,100,37,2018-03-18 04:32:13,2018-08-09 03:16:35,2018-11-21 04:25:29,2018-10-03 06:20:54 +189,Hedy,Sapena,301-104-2652,Female,3,37,35,2018-07-04 12:54:06,2018-10-12 20:33:48,2018-04-10 07:32:31,2018-03-17 10:12:03 +190,Nerissa,Jedras,425-605-9508,Female,1,18,31,2019-01-12 14:05:35,2018-10-19 14:28:35,2018-06-14 21:07:02,2018-03-22 05:53:32 +191,Terrel,Kear,681-621-2157,Male,3,98,45,2018-02-20 10:42:05,2018-11-08 04:29:14,2018-03-09 02:33:02,2018-07-04 18:27:00 +192,Dennison,Theodoris,722-911-1627,Male,6,76,32,2018-11-18 05:15:23,2018-05-13 02:02:05,2019-01-15 21:45:30,2018-04-13 17:24:17 +193,Chrystel,Ferentz,497-580-2963,Female,2,96,6,2018-12-11 03:17:23,2018-05-23 04:35:09,2018-11-01 17:51:50,2018-08-02 02:44:29 +194,Devland,Butchers,313-172-9223,Male,6,42,38,2019-01-16 07:17:37,2018-11-09 17:37:48,2018-04-10 08:57:30,2018-05-02 13:47:28 +195,Simon,Astupenas,981-207-6441,Male,2,57,43,2018-11-07 15:02:00,2018-01-25 17:30:33,2018-07-13 05:08:19,2018-10-29 18:37:22 +196,Jordan,Attride,447-912-6034,Female,7,25,37,2018-06-06 14:29:43,2018-06-30 03:49:38,2018-12-09 18:11:23,2018-01-30 19:12:46 +197,Clerissa,Forsard,485-444-1412,Female,2,88,66,2018-09-19 00:56:28,2018-07-23 15:36:37,2018-11-17 11:43:09,2018-11-17 17:11:53 +198,Alastair,Toth,495-980-1189,Male,1,62,59,2018-03-04 17:35:31,2018-06-18 07:02:22,2018-07-30 02:31:33,2018-07-20 14:21:29 +199,Aldo,Bruton,488-482-2130,Male,2,33,99,2018-06-09 23:01:18,2018-08-22 04:11:53,2018-07-17 05:55:24,2018-04-08 10:13:23 +200,Lorin,Mourant,953-195-5245,Male,1,78,78,2018-02-04 07:07:36,2018-08-05 08:03:40,2018-11-22 13:04:30,2018-03-10 12:32:28 +201,Nonnah,Dreini,137-834-9350,Female,1,20,84,2018-11-23 21:47:29,2018-07-02 22:51:42,2018-05-28 23:33:57,2018-06-11 11:55:17 +202,Winnie,Muris,865-681-2171,Female,2,31,76,2018-10-29 21:53:21,2018-10-12 17:59:08,2018-03-21 12:37:41,2018-06-26 05:24:49 +203,Marybelle,Wedmore.,566-812-6518,Female,6,94,20,2018-04-08 17:51:07,2018-01-25 19:29:58,2018-05-29 08:33:21,2018-12-18 09:29:05 +204,Christophorus,La Batie,776-298-7693,Male,2,100,44,2018-11-26 01:22:44,2018-11-28 19:33:42,2018-01-26 20:34:09,2018-10-15 19:29:24 +205,Erhart,Laydon,425-854-5387,Male,7,15,35,2018-11-09 09:53:34,2018-11-11 01:43:14,2019-01-16 12:20:32,2018-08-01 09:34:47 +206,Myrta,Playfair,512-835-4158,Female,4,8,51,2018-05-04 15:28:01,2018-05-11 22:03:31,2018-05-21 02:28:31,2018-03-17 08:25:48 +207,Tybie,McGhee,155-902-0043,Female,5,25,55,2018-03-19 17:19:34,2018-11-11 01:53:03,2018-06-01 16:21:08,2018-08-21 09:39:26 +208,Augusto,Chelam,595-490-1187,Male,2,20,22,2018-02-26 17:51:20,2018-04-15 11:38:21,2018-11-29 19:44:24,2018-05-17 16:31:14 +209,Louisette,Firbanks,365-745-5229,Female,1,51,35,2018-04-17 19:42:14,2018-03-19 09:56:15,2018-04-22 09:48:27,2018-11-20 05:52:44 +210,Brucie,Speers,688-351-7130,Male,3,65,20,2018-09-22 06:54:04,2018-08-14 23:05:08,2018-03-13 17:38:11,2018-12-29 06:47:13 +211,Nathanial,Ayliff,974-831-8727,Male,1,23,95,2018-09-02 06:27:24,2018-06-18 22:51:54,2018-12-25 13:15:52,2018-03-09 05:29:17 +212,Shawnee,McClenan,177-754-4767,Female,4,54,82,2018-04-17 14:01:32,2018-08-15 14:02:31,2019-01-04 03:04:30,2018-10-20 15:25:45 +213,Giavani,Cay,976-869-6321,Male,1,92,27,2018-07-22 17:43:03,2018-02-20 03:19:34,2018-05-06 13:52:36,2018-12-05 18:14:41 +214,Claudia,Fazackerley,454-663-9623,Female,4,26,25,2019-01-07 16:15:34,2018-03-06 15:31:53,2018-02-06 23:08:37,2018-11-13 17:45:22 +215,Nevil,Phelp,255-488-7211,Male,5,22,40,2018-09-11 19:55:44,2018-05-13 12:07:30,2018-08-27 02:20:49,2019-01-17 21:11:30 +216,Elle,Antal,303-999-5794,Female,4,23,5,2018-02-15 19:05:09,2018-10-15 01:01:31,2018-12-31 16:08:16,2018-03-23 15:16:38 +217,Brnaby,Dewsbury,173-850-9221,Male,3,82,22,2018-05-19 14:05:10,2018-12-30 00:25:40,2018-09-27 06:32:26,2018-04-25 02:17:22 +218,Ronda,Dranfield,835-657-5998,Female,5,61,54,2018-10-18 03:51:07,2018-07-20 06:01:19,2018-11-17 15:09:04,2018-12-04 20:06:06 +219,Vania,Brannan,288-990-8986,Female,3,88,25,2018-07-03 11:19:29,2018-11-13 09:44:15,2018-02-28 13:57:43,2018-02-28 05:42:56 +220,Jessy,Baggelley,848-274-4914,Female,7,38,75,2018-12-04 13:44:16,2018-11-20 01:53:14,2018-02-25 03:07:40,2018-06-17 19:02:59 +221,Paxon,Kensall,262-215-6295,Male,1,3,63,2018-08-12 21:30:25,2018-11-24 01:13:12,2018-06-04 19:20:59,2018-08-16 14:48:22 +222,Tana,O'Donohue,514-853-5855,Female,4,99,1,2018-03-21 06:05:58,2018-05-01 00:39:55,2018-03-10 21:55:54,2018-10-31 10:25:10 +223,Thomasina,Gibbons,501-364-8398,Female,3,37,56,2018-11-22 03:07:49,2018-06-30 16:44:00,2018-08-05 18:41:13,2019-01-07 06:21:44 +224,Bellanca,Golston,673-979-3362,Female,1,57,53,2018-05-02 00:04:42,2018-01-21 22:51:57,2018-08-20 18:40:05,2018-02-09 08:22:11 +225,Maureene,Drejer,769-639-6612,Female,7,49,17,2018-02-20 12:00:24,2018-09-01 04:44:08,2018-08-15 22:04:06,2018-09-04 06:40:59 +226,Beatrisa,Blanche,914-368-0909,Female,4,47,77,2018-05-21 06:41:29,2018-10-04 19:21:53,2018-07-11 04:03:32,2018-04-05 01:26:21 +227,Melita,Filipczak,743-692-1202,Female,2,18,45,2018-04-04 09:49:49,2018-03-30 16:30:51,2019-01-09 03:34:15,2018-02-05 00:54:24 +228,Jean,Rzehor,983-469-9959,Male,2,76,95,2018-08-17 14:15:05,2018-09-25 10:05:56,2018-09-04 10:03:08,2018-02-16 04:46:04 +229,Netti,Odeson,140-282-6021,Female,7,46,99,2018-04-08 08:08:21,2018-05-07 06:33:55,2018-03-10 06:30:39,2018-08-27 01:08:06 +230,Lark,Komorowski,889-340-2588,Female,6,36,54,2018-05-27 12:55:35,2018-11-18 05:20:17,2018-11-19 04:18:03,2018-04-24 14:21:19 +231,Mae,Howells,972-510-2059,Female,2,54,97,2019-01-17 19:46:20,2018-07-10 05:29:24,2018-07-06 16:03:28,2018-07-18 17:41:40 +232,Brewer,Wolstencroft,243-516-4986,Male,4,68,84,2018-07-19 01:48:48,2018-12-31 10:44:05,2018-05-25 20:15:52,2018-04-27 22:38:48 +233,Chrystel,Buist,285-587-4608,Female,3,66,90,2018-02-06 05:43:09,2018-06-10 20:45:59,2018-11-27 09:40:02,2018-12-30 22:43:43 +234,Nicola,Feltoe,102-119-8958,Female,6,30,100,2018-05-26 00:46:42,2018-03-17 00:12:12,2019-01-16 18:40:38,2018-01-27 09:20:23 +235,Engelbert,Matveiko,868-192-6148,Male,3,3,6,2018-05-27 06:16:04,2018-12-24 00:22:43,2018-04-18 07:21:59,2018-12-03 08:49:41 +236,Lezley,M'Chirrie,749-737-2204,Male,4,16,17,2018-07-06 21:48:48,2018-02-09 05:08:49,2018-09-05 10:59:16,2018-03-22 01:13:02 +237,Josy,Larkins,826-241-0108,Female,1,8,18,2018-10-26 03:28:37,2018-02-24 22:01:17,2018-12-29 22:31:43,2018-05-23 06:28:27 +238,Armando,Girt,296-631-5842,Male,1,90,62,2018-03-14 20:02:06,2018-02-25 03:43:37,2018-05-29 18:43:28,2018-10-10 16:04:29 +239,Nevins,Boch,243-865-0986,Male,7,87,34,2018-04-27 05:11:05,2018-06-13 18:02:47,2018-04-17 23:28:45,2018-03-11 20:07:50 +240,Gordan,MacHoste,194-807-0099,Male,2,8,10,2018-11-30 11:09:40,2018-03-19 08:40:39,2018-07-07 07:58:57,2018-12-03 15:54:45 +241,Vlad,Urling,756-416-9308,Male,6,44,75,2018-07-01 08:10:44,2018-06-25 11:50:00,2018-02-18 09:41:26,2019-01-20 16:56:43 +242,Karney,Batteson,884-299-0885,Male,3,4,70,2018-04-21 18:15:47,2018-03-17 15:26:35,2018-09-21 06:49:36,2018-03-03 10:02:05 +243,Shep,Croisier,182-249-1703,Male,2,25,64,2018-11-27 15:36:38,2018-03-27 09:16:11,2018-07-27 14:14:49,2018-08-31 21:47:02 +244,Jackelyn,Franschini,203-947-2285,Female,5,93,18,2018-05-11 18:05:34,2018-07-09 02:56:23,2018-05-26 13:31:09,2018-11-12 13:51:54 +245,Kingston,Brazier,388-460-9266,Male,5,67,43,2018-11-17 16:06:03,2018-10-22 21:39:40,2018-11-03 04:17:45,2018-08-23 17:37:21 +246,Derwin,Postin,334-746-9914,Male,2,9,74,2018-04-28 10:39:48,2018-10-16 21:01:17,2019-01-17 12:54:27,2018-09-18 06:08:12 +247,Rustie,Boddington,499-187-3081,Male,7,75,92,2018-07-09 18:05:33,2018-09-15 11:50:52,2018-06-10 05:00:00,2018-09-23 05:52:23 +248,Araldo,MacConnulty,922-950-0398,Male,4,66,28,2018-11-11 12:46:18,2018-09-10 16:05:23,2018-09-21 00:16:24,2018-10-10 19:06:57 +249,Brear,Zuanelli,948-803-5705,Female,7,88,15,2018-03-03 08:12:37,2018-10-06 14:14:00,2018-09-06 21:02:50,2018-04-04 06:13:25 +250,Ruttger,Cartan,503-123-4758,Male,6,8,46,2018-07-02 10:33:15,2018-10-11 08:51:25,2018-02-16 18:01:35,2018-05-15 00:25:35 +251,Leta,Gravenell,798-643-9817,Female,6,19,50,2018-09-26 18:01:14,2018-12-31 01:08:01,2018-08-12 01:18:26,2018-08-12 11:04:31 +252,Nanny,Spellward,298-614-5133,Female,2,78,35,2018-07-31 14:38:53,2018-07-11 11:50:42,2018-06-24 03:47:24,2018-08-23 06:25:24 +253,Garwin,Overil,981-304-0345,Male,1,66,62,2018-02-20 05:57:01,2018-02-04 20:02:37,2018-04-21 16:30:20,2018-07-27 08:45:03 +254,Ancell,Bromidge,677-576-3535,Male,1,54,47,2018-02-27 19:07:09,2018-07-07 17:41:39,2018-03-14 05:31:23,2018-11-18 21:30:30 +255,Harmonia,McIleen,610-808-3838,Female,5,76,7,2018-05-09 14:49:35,2018-04-12 02:30:13,2019-01-17 21:59:23,2018-04-20 05:21:50 +256,Ginni,See,809-189-3574,Female,7,93,45,2018-04-11 20:22:07,2018-08-17 13:12:57,2018-04-20 06:30:33,2018-04-17 00:12:41 +257,Christi,Doorly,614-386-8893,Female,7,23,11,2018-08-09 05:01:14,2018-03-11 21:19:53,2018-05-09 23:37:07,2018-03-27 22:07:11 +258,Perice,Severy,433-906-1030,Male,1,18,5,2018-09-01 12:30:04,2018-09-13 05:34:16,2019-01-16 22:35:35,2019-01-09 20:31:49 +259,Dulsea,Yokel,279-965-4206,Female,2,93,50,2018-10-31 22:48:09,2018-07-13 09:25:20,2018-02-16 09:15:58,2018-05-12 21:55:26 +260,Marge,Cheng,549-350-8693,Female,2,10,68,2018-09-01 18:42:35,2018-04-07 10:58:53,2018-07-30 16:05:15,2018-10-20 05:45:19 +261,Baron,McIlmorow,283-456-4615,Male,2,41,89,2018-11-07 01:23:03,2018-12-20 18:25:28,2018-08-31 12:49:04,2018-05-27 07:39:41 +262,Rabbi,Beaglehole,904-724-1771,Male,2,94,67,2018-11-04 08:21:47,2018-12-28 20:54:40,2018-12-08 10:20:14,2018-11-29 19:47:40 +263,Olvan,Asher,310-502-8368,Male,7,76,67,2018-03-15 22:02:48,2018-07-30 12:08:26,2018-12-06 22:49:46,2018-06-17 22:03:05 +264,Yard,Beldon,209-784-5636,Male,7,90,9,2018-07-24 02:02:11,2018-05-11 03:54:15,2018-08-20 18:46:55,2018-03-10 04:11:33 +265,Enriqueta,Barraclough,332-372-0081,Female,6,75,69,2018-08-18 05:08:19,2018-01-27 11:36:23,2018-05-23 08:59:06,2018-02-11 04:14:36 +266,Alli,Smallcomb,255-741-1276,Female,2,8,1,2018-12-06 01:19:35,2018-07-16 16:10:12,2018-07-16 13:31:05,2018-10-26 07:03:09 +267,Shay,Amsden,816-821-9426,Male,6,25,35,2018-03-15 01:09:39,2018-11-26 05:57:30,2018-10-26 07:54:05,2018-04-14 01:42:13 +268,Jacynth,Boscott,970-121-0282,Female,1,88,89,2018-07-31 16:10:10,2018-05-10 10:28:44,2018-10-02 23:00:23,2018-07-02 13:55:14 +269,Dominique,Farny,782-337-7486,Male,1,17,29,2018-09-09 16:09:20,2018-04-10 15:04:16,2018-03-25 16:40:27,2019-01-04 20:02:55 +270,Keefe,Guerrero,440-254-1961,Male,4,96,29,2018-10-19 10:06:55,2018-07-28 18:31:17,2018-05-05 19:05:12,2018-06-01 05:55:25 +271,Buiron,Anfossi,512-333-8553,Male,2,92,51,2018-09-09 16:00:30,2018-02-20 14:27:22,2018-03-11 07:29:35,2018-07-12 02:19:45 +272,Eleonore,Puller,325-656-5909,Female,4,88,37,2018-12-04 20:39:40,2018-02-13 04:35:07,2018-08-16 18:26:05,2018-06-08 07:45:57 +273,Katuscha,Rasch,427-956-1046,Female,4,68,90,2018-06-19 01:20:15,2018-04-03 01:55:07,2018-04-17 19:09:09,2018-08-15 11:04:06 +274,Hoebart,Linger,972-926-3923,Male,4,74,74,2018-02-19 01:23:42,2018-01-26 15:34:23,2018-09-13 07:10:43,2018-06-07 23:26:33 +275,Patrick,Hryskiewicz,736-622-7490,Male,3,91,1,2019-01-13 09:57:23,2018-05-06 15:42:09,2018-07-01 17:16:14,2018-09-01 02:26:15 +276,Bert,Adrianello,485-126-1547,Female,7,33,12,2018-11-01 06:34:27,2018-09-14 23:29:20,2018-03-11 08:15:03,2018-09-21 21:53:26 +277,Burton,Spittall,570-586-9893,Male,7,46,33,2018-01-28 06:20:39,2018-06-15 19:15:06,2018-06-27 02:36:30,2018-03-24 02:52:03 +278,Tessy,Mitchley,167-983-7021,Female,5,45,26,2018-03-02 16:44:00,2018-12-25 18:48:13,2018-04-01 18:27:41,2018-04-03 20:39:05 +279,Nettle,Hause,489-296-7367,Female,2,99,15,2018-03-18 02:50:49,2018-03-02 01:31:53,2018-10-31 06:40:34,2018-04-28 11:21:14 +280,Pearce,Darwent,801-341-9474,Male,2,24,44,2018-05-28 23:54:50,2018-02-07 18:37:22,2018-09-11 02:48:52,2018-11-09 16:24:17 +281,Kelsey,Suttle,536-591-5133,Female,6,11,76,2018-02-14 19:05:31,2018-07-14 19:32:27,2018-03-26 04:59:22,2018-04-01 20:21:57 +282,Gillie,Sponton,270-390-2110,Female,2,94,57,2018-03-14 11:50:53,2018-03-27 13:10:53,2018-04-23 19:54:11,2018-08-22 21:53:12 +283,Marsha,Dietz,740-837-1891,Female,5,90,95,2018-03-18 04:53:06,2018-06-29 02:28:55,2018-08-10 05:14:09,2018-05-10 04:03:25 +284,Miles,Purchon,413-518-8673,Male,2,57,98,2018-04-02 15:49:11,2018-02-04 16:57:33,2018-09-09 22:23:44,2018-03-16 04:00:43 +285,Collette,Menego,440-637-0309,Female,3,21,56,2018-04-18 04:27:48,2018-05-05 08:32:40,2018-03-17 17:54:26,2018-04-12 00:24:45 +286,Heriberto,Dunkerton,321-657-4492,Male,5,99,91,2018-08-17 12:11:42,2018-10-26 14:33:07,2018-03-10 13:13:28,2018-05-03 02:14:30 +287,Hailee,Remington,671-722-2287,Female,6,69,53,2018-08-01 01:54:04,2018-08-20 04:05:47,2018-04-24 14:22:04,2018-11-02 14:15:55 +288,Ingunna,Errigo,378-401-4671,Female,3,83,66,2018-12-22 21:52:13,2018-12-24 18:41:25,2018-11-11 17:31:47,2018-06-27 14:34:11 +289,Barbie,Grishmanov,184-949-4040,Female,7,93,68,2018-08-14 21:25:04,2018-08-26 18:27:48,2018-04-28 10:50:33,2018-08-06 14:12:21 +290,Anderson,Freeland,842-434-1249,Male,6,22,71,2019-01-05 09:24:32,2018-06-13 07:19:06,2018-04-24 22:20:16,2018-05-31 21:18:59 +291,Olympie,Prantl,988-864-1736,Female,1,39,40,2018-04-06 05:52:26,2018-03-10 03:20:54,2018-02-06 16:53:55,2018-09-03 16:18:27 +292,Amos,Lanyon,552-486-3382,Male,1,17,35,2018-07-03 20:26:09,2018-11-16 06:37:27,2018-08-16 14:36:30,2018-04-07 19:59:08 +293,Gabby,Stockau,753-586-0632,Male,5,19,14,2018-12-10 13:52:07,2018-03-20 20:50:50,2018-04-11 20:54:39,2018-11-13 17:11:21 +294,Uta,Joan,660-241-5130,Female,7,67,41,2018-04-21 18:11:39,2018-07-12 17:47:45,2018-05-20 14:57:17,2018-09-19 10:15:02 +295,Elnar,Manjot,691-939-7359,Male,5,18,86,2018-11-24 20:27:24,2018-04-29 05:45:30,2018-09-06 04:15:04,2018-05-31 17:11:55 +296,Avram,Cowins,471-336-0418,Male,1,18,23,2018-10-07 19:35:52,2018-07-24 19:33:54,2018-05-09 12:43:10,2018-10-08 09:08:37 +297,Kyla,Fines,380-936-0659,Female,7,16,6,2018-12-04 05:02:51,2018-06-13 12:25:14,2018-05-15 10:17:43,2018-07-24 13:06:26 +298,Tymothy,Trevillion,740-586-6434,Male,4,99,5,2018-11-29 03:58:39,2018-07-10 01:02:27,2018-07-05 11:15:40,2018-07-17 11:17:00 +299,Rafaelita,Stiven,313-253-8470,Female,7,94,91,2018-05-11 22:09:50,2018-12-04 03:23:26,2018-06-04 22:13:06,2018-08-02 01:03:16 +300,Stanwood,Bracci,757-577-7619,Male,3,79,15,2018-06-02 08:42:52,2018-05-01 23:25:28,2018-10-27 06:54:40,2019-01-03 19:33:39 +301,Heddie,Pegden,750-484-0458,Female,3,85,74,2018-02-15 15:15:50,2018-08-13 10:31:12,2018-10-22 05:36:44,2018-07-27 21:33:04 +302,Letty,Ipplett,534-461-3389,Female,2,24,58,2018-12-30 15:03:42,2018-12-25 22:41:39,2018-08-06 08:13:19,2018-06-13 08:22:24 +303,Clarke,Buckberry,261-218-0110,Male,4,39,35,2018-11-25 02:26:48,2018-10-01 22:53:26,2019-01-01 07:32:49,2018-06-23 02:36:18 +304,Valina,Bouskill,292-930-7629,Female,2,63,32,2018-03-13 00:24:33,2018-12-08 10:39:51,2019-01-06 10:27:01,2018-07-13 00:19:13 +305,Jeth,Mosedall,326-529-0770,Male,7,44,30,2019-01-17 17:26:19,2018-03-23 23:40:12,2018-12-16 02:11:33,2018-09-08 07:21:24 +306,Mano,Komorowski,467-693-9454,Male,5,63,33,2018-12-05 21:37:13,2018-05-15 16:54:39,2018-11-21 08:06:01,2018-12-25 19:18:03 +307,Libby,Worters,651-420-4117,Female,6,62,73,2018-11-16 15:37:33,2018-04-10 08:47:08,2018-09-25 07:08:44,2018-12-20 18:11:17 +308,Ginnie,Dunnion,884-641-9401,Female,4,15,91,2018-02-25 04:25:07,2018-06-11 12:12:35,2018-12-20 05:03:34,2018-05-12 15:41:13 +309,Addi,Butterfill,454-471-6991,Female,6,45,37,2019-01-14 00:57:24,2018-10-22 12:37:53,2018-11-12 17:11:49,2018-04-13 08:39:20 +310,Eustace,Calway,260-583-1874,Male,3,98,96,2018-12-08 14:19:50,2018-03-09 04:33:52,2018-08-03 22:32:38,2018-12-17 16:12:12 +311,Greta,Tailour,864-452-3785,Female,5,63,78,2018-05-09 23:36:15,2018-09-16 21:21:51,2018-06-17 03:49:40,2018-06-25 12:40:03 +312,Nance,Ruston,102-299-0194,Female,4,66,33,2018-04-19 13:30:14,2018-08-22 20:55:14,2018-03-02 20:03:46,2018-03-23 09:40:10 +313,Harriette,Dicty,498-183-6908,Female,7,1,13,2018-12-31 04:35:08,2018-08-13 12:05:13,2018-04-30 22:42:00,2018-12-03 13:23:45 +314,Merrielle,Mapes,918-608-0262,Female,5,47,45,2018-12-16 07:21:41,2018-10-27 21:05:00,2018-03-23 14:05:12,2018-08-02 11:02:53 +315,Gris,Scurrell,392-726-5529,Male,4,71,95,2018-02-23 03:36:40,2018-04-09 20:52:39,2018-03-07 02:56:27,2018-10-22 11:26:37 +316,Novelia,Newdick,262-887-9640,Female,3,20,97,2018-05-18 12:00:02,2018-02-04 08:00:28,2018-01-28 09:59:37,2018-07-06 05:53:32 +317,Sean,Breton,304-133-1524,Male,4,91,49,2018-07-09 23:07:45,2018-10-27 06:20:49,2018-08-22 21:03:24,2018-06-13 05:33:30 +318,Winston,Springham,259-758-2788,Male,6,86,20,2018-03-20 19:07:57,2018-03-17 14:55:01,2018-08-05 20:39:20,2018-02-11 22:19:58 +319,Clemmie,Saywood,341-505-9072,Male,4,61,30,2018-06-08 02:47:28,2018-07-03 05:59:45,2018-10-28 00:28:02,2018-04-07 23:20:59 +320,Robinia,Vida,537-434-4616,Female,6,19,32,2018-05-03 10:52:24,2018-10-12 00:17:12,2018-11-27 23:47:32,2018-12-17 00:24:59 +321,Findley,Melanaphy,423-892-4436,Male,1,100,31,2018-02-04 19:41:01,2018-08-17 10:08:47,2018-11-04 14:37:46,2018-07-01 11:45:21 +322,Brooks,O'Keenan,840-842-8591,Female,4,82,84,2018-08-21 21:40:21,2018-08-31 04:07:15,2018-02-01 02:25:03,2018-12-09 10:50:21 +323,Caz,Leaf,797-315-7239,Male,6,75,22,2018-10-17 18:51:00,2018-11-22 19:03:52,2018-02-15 06:48:13,2018-04-19 22:25:23 +324,Ad,Harvey,336-617-2629,Male,4,46,5,2018-07-01 18:17:34,2018-05-24 05:31:23,2018-04-05 21:04:43,2018-07-21 06:50:26 +325,Berrie,Robardley,671-363-7428,Female,2,46,55,2018-05-14 01:56:01,2018-09-20 02:21:44,2019-01-14 15:24:34,2018-05-14 15:49:53 +326,Corliss,Halwell,154-276-2412,Female,3,63,16,2018-12-21 10:15:57,2018-11-26 00:14:11,2018-10-24 18:09:31,2018-05-27 11:41:11 +327,Carlina,Laird,357-488-1031,Female,5,59,27,2018-10-24 22:33:19,2018-10-23 00:27:39,2018-10-26 13:59:23,2018-07-19 02:41:32 +328,Rivalee,Bartolomucci,299-435-2483,Female,2,86,75,2018-06-02 23:51:58,2018-10-18 07:08:38,2019-01-11 07:36:58,2018-06-06 22:53:26 +329,Eleen,Girardy,254-561-4781,Female,6,99,58,2018-08-12 03:49:21,2019-01-04 17:17:54,2018-07-07 17:22:19,2018-02-08 00:26:15 +330,Junina,Scarisbrick,668-657-6435,Female,2,82,52,2018-10-08 01:58:04,2019-01-18 08:27:33,2018-10-13 10:36:18,2018-04-09 10:28:35 +331,Mufi,Insole,497-136-1156,Female,1,3,77,2018-07-01 05:18:23,2018-04-25 06:55:14,2018-12-23 07:35:00,2018-09-14 19:25:46 +332,Burk,Sawday,758-694-5610,Male,1,16,37,2018-05-18 17:42:50,2018-09-01 06:27:12,2018-05-06 06:30:31,2018-11-29 12:15:41 +333,Jess,Gully,330-430-8050,Female,5,2,75,2018-04-21 00:37:44,2018-06-12 02:34:07,2018-05-04 05:50:38,2018-11-25 21:02:42 +334,Dayna,Goublier,395-283-7995,Female,1,3,58,2018-03-10 13:08:34,2018-04-01 05:11:59,2018-07-17 13:31:35,2019-01-02 10:31:32 +335,Shandy,Grzegorczyk,271-236-1931,Female,6,32,34,2018-10-24 18:00:50,2018-03-17 19:11:58,2018-07-13 09:20:10,2018-07-07 03:03:48 +336,Alec,Nunnery,471-774-4412,Male,3,85,94,2018-02-15 09:59:45,2018-01-30 12:50:03,2018-03-01 13:47:47,2018-09-28 11:00:16 +337,Marti,Bedboro,799-912-3939,Female,3,88,26,2018-06-25 11:23:21,2018-10-30 08:43:52,2018-01-29 08:37:23,2018-06-06 00:28:49 +338,Malchy,Kobpac,819-568-9360,Male,4,9,14,2018-02-24 04:10:07,2018-10-05 18:35:23,2018-06-15 18:09:22,2018-11-15 08:05:17 +339,Egan,Dobbinson,366-886-7331,Male,5,43,13,2018-03-14 16:50:59,2018-08-08 23:17:17,2018-05-14 23:29:30,2018-08-19 04:54:16 +340,Maisie,Legg,700-620-6322,Female,7,85,21,2018-08-24 21:35:43,2018-08-30 17:01:27,2018-09-26 01:11:55,2018-12-29 12:04:35 +341,Fidel,Cossum,677-926-2862,Male,3,37,35,2018-07-26 05:42:32,2018-03-10 10:55:00,2018-12-22 17:20:15,2018-12-23 18:00:25 +342,Artemis,Beaton,301-959-5912,Male,7,15,26,2019-01-16 02:54:03,2018-10-28 11:08:44,2018-04-03 17:01:17,2018-04-13 04:28:34 +343,Culver,MacShirrie,126-770-5278,Male,4,28,43,2018-04-18 15:27:55,2018-08-01 10:35:51,2018-03-25 11:19:36,2018-06-01 19:23:11 +344,Jessa,Penreth,684-809-2622,Female,7,59,63,2018-08-04 18:24:37,2018-12-16 20:09:17,2018-04-11 13:14:28,2018-04-22 20:10:29 +345,Nydia,Hefner,535-519-6688,Female,3,70,29,2018-07-22 18:53:43,2018-09-02 00:30:03,2018-10-29 22:17:37,2018-05-07 11:46:24 +346,Ber,Naulty,311-674-2440,Male,6,85,70,2018-09-03 15:50:38,2018-07-04 22:30:51,2018-06-29 11:55:09,2018-05-16 11:27:56 +347,Margit,Greder,417-702-7174,Female,3,35,4,2018-04-28 01:58:34,2018-07-07 16:48:11,2018-10-08 13:45:45,2018-07-30 06:54:10 +348,Haroun,Kleynen,447-297-5270,Male,1,91,87,2018-05-14 13:40:54,2018-02-06 20:20:54,2018-04-24 19:09:01,2018-07-08 15:20:39 +349,Aylmer,Hubner,861-836-0360,Male,7,92,93,2018-02-10 06:55:44,2018-05-09 06:47:11,2018-07-09 15:46:54,2018-06-24 16:38:43 +350,Natty,Clemenzo,127-593-4758,Male,2,26,56,2018-02-01 13:02:29,2018-08-21 13:26:29,2018-12-24 09:27:03,2018-12-03 17:23:39 +351,Adriaens,Galier,704-551-4514,Female,1,64,55,2018-02-20 14:06:58,2018-09-17 22:53:46,2018-06-05 21:13:53,2018-02-25 03:51:27 +352,Raphaela,Higounet,493-470-8620,Female,7,72,86,2018-04-06 23:54:14,2018-11-09 00:01:09,2018-04-16 13:28:28,2018-10-15 09:06:54 +353,Nadia,Cureton,243-413-5780,Female,7,16,92,2018-10-20 06:35:07,2018-04-22 20:08:35,2018-04-07 15:26:39,2018-07-12 20:04:06 +354,Elliot,Bursell,301-524-4971,Male,6,59,44,2018-06-15 18:56:07,2018-03-14 21:30:37,2018-04-10 07:08:26,2018-10-03 23:57:13 +355,Miltie,Credland,318-601-5704,Male,3,5,47,2018-11-14 17:21:39,2018-04-18 22:02:24,2018-05-29 11:29:17,2018-08-28 19:44:37 +356,Andre,Dockray,631-438-3562,Male,2,1,36,2018-10-08 05:05:08,2018-10-07 10:51:00,2018-03-15 03:21:37,2018-08-31 02:22:35 +357,Marty,Vannah,864-526-0455,Male,5,32,9,2018-07-24 00:22:10,2018-08-26 02:40:08,2018-06-27 12:17:04,2018-05-23 03:24:49 +358,Timofei,Paddeley,941-127-2852,Male,4,75,28,2018-06-23 03:54:48,2018-06-16 19:23:26,2018-01-22 23:50:44,2018-09-17 11:00:42 +359,Susie,Bister,717-420-9064,Female,2,35,88,2018-08-09 20:57:50,2018-12-31 14:45:14,2018-04-16 17:44:38,2018-04-22 00:14:47 +360,Salvatore,Saenz,433-114-2254,Male,7,20,65,2018-02-14 15:55:26,2018-10-12 01:07:22,2018-11-29 04:17:51,2018-03-26 04:48:55 +361,Orin,Buttler,311-657-3727,Male,6,34,55,2018-04-05 00:11:44,2018-03-18 20:58:52,2018-09-14 10:40:07,2018-08-10 05:15:21 +362,Darbee,Garnam,956-529-4862,Male,1,75,26,2018-04-10 03:09:44,2018-06-29 01:39:43,2018-08-22 22:42:21,2018-09-15 23:23:04 +363,Lynne,Order,955-214-1203,Female,3,7,62,2018-11-15 23:40:31,2019-01-19 17:41:26,2018-02-14 19:18:25,2018-05-13 10:24:56 +364,Quinn,Hickinbottom,161-623-2666,Female,4,55,12,2018-10-24 13:06:05,2018-05-14 12:29:26,2018-10-03 06:49:08,2018-08-31 05:23:27 +365,Fionnula,Lonsbrough,271-974-9269,Female,2,24,86,2018-11-26 13:04:53,2018-04-30 00:03:02,2018-12-10 17:59:39,2018-11-02 17:56:01 +366,Blinni,Bound,991-243-7726,Female,3,34,55,2018-03-15 03:25:08,2018-07-17 18:13:35,2018-01-22 14:47:57,2018-07-03 10:31:07 +367,Joellyn,Duddin,562-523-2225,Female,3,91,7,2018-03-05 16:54:40,2018-07-11 18:24:57,2018-01-27 22:51:59,2018-06-14 14:18:32 +368,Shawn,McCandie,460-327-7535,Male,7,83,25,2018-03-04 04:08:42,2018-02-27 20:23:00,2018-05-03 04:17:09,2018-05-11 02:19:04 +369,Ferdinande,Beckinsall,555-188-2556,Female,1,23,71,2019-01-09 18:09:00,2018-11-05 21:40:44,2018-04-18 11:39:10,2018-05-26 04:58:28 +370,Dex,Hercock,124-933-7494,Male,4,66,59,2018-12-03 18:59:16,2018-08-24 14:54:44,2018-12-04 06:20:22,2018-02-12 20:16:12 +371,Auguste,Kindread,503-140-7531,Female,1,66,99,2018-09-06 02:28:55,2018-06-16 13:03:23,2018-12-18 05:54:52,2018-06-18 08:33:05 +372,Nicolle,McGarvie,977-633-1344,Female,3,80,30,2018-06-27 01:20:37,2019-01-03 07:13:42,2018-08-14 06:50:08,2018-03-11 19:28:21 +373,Meir,Poxson,979-687-3866,Male,4,95,64,2018-07-09 19:27:35,2018-05-02 06:46:01,2018-03-13 19:59:34,2018-02-14 17:37:01 +374,Aurore,Mathe,855-273-0680,Female,1,35,18,2018-12-25 19:52:38,2018-06-27 16:21:30,2018-09-05 07:24:39,2018-07-07 20:33:00 +375,Tara,Kovacs,289-503-0397,Female,1,96,65,2018-02-01 14:13:00,2018-09-13 12:52:31,2018-12-11 12:17:26,2018-01-27 11:08:31 +376,Oliver,Keitch,295-918-1908,Male,2,2,91,2018-04-25 08:41:36,2018-10-26 12:47:17,2018-09-17 07:21:55,2018-05-05 18:27:42 +377,Terrie,Van der Linde,437-439-0685,Female,5,40,86,2018-06-13 19:39:12,2018-09-27 20:24:10,2018-11-29 11:48:24,2018-08-03 10:38:12 +378,Dickie,Rhymes,812-341-6120,Male,1,20,77,2018-02-19 18:11:07,2018-07-04 05:36:40,2018-11-14 00:59:02,2018-11-24 17:13:06 +379,Lynette,Hadland,438-785-0370,Female,1,49,29,2018-04-01 23:24:07,2018-08-21 14:23:03,2018-05-13 18:28:29,2018-12-12 21:59:32 +380,Blanch,Smythin,325-174-1975,Female,1,13,78,2018-11-04 02:34:45,2018-10-22 10:28:57,2018-09-14 10:12:56,2018-10-23 19:59:00 +381,Camellia,Rickeard,681-592-9848,Female,5,53,4,2018-08-25 10:15:49,2018-04-05 06:53:58,2018-02-17 08:17:38,2018-09-11 01:16:02 +382,Muire,Minto,821-124-3681,Female,2,92,71,2018-10-16 14:05:30,2018-05-21 07:22:46,2018-10-26 09:45:10,2018-09-07 09:40:50 +383,Franz,Goullee,650-849-7354,Male,1,19,86,2018-07-14 09:46:05,2018-02-20 08:15:57,2018-06-05 10:37:07,2018-06-14 13:33:38 +384,Ardath,Salaman,542-596-2751,Female,6,3,76,2018-06-07 05:11:01,2018-09-17 09:28:04,2018-04-10 13:00:45,2018-11-27 21:22:09 +385,Graeme,Balshen,286-335-9657,Male,3,44,17,2018-07-18 15:23:20,2018-03-28 07:57:47,2018-11-12 18:58:13,2018-10-11 13:56:49 +386,Lola,Ainsbury,875-341-9340,Female,5,48,71,2018-03-12 03:05:33,2018-11-01 02:55:54,2018-02-15 04:37:51,2018-05-27 04:11:38 +387,Marchelle,Reynoollds,771-436-6596,Female,3,15,98,2018-07-21 06:24:35,2018-10-15 12:19:29,2018-10-21 17:19:01,2018-12-07 00:08:23 +388,Ruddie,Ginger,639-798-1010,Male,6,53,88,2018-10-27 08:25:56,2018-08-05 15:50:59,2018-05-26 08:38:25,2018-03-12 08:36:31 +389,Kathrine,Guiu,822-798-6112,Female,2,31,32,2018-07-21 23:07:18,2018-04-23 18:22:19,2018-12-14 04:50:14,2018-12-17 05:07:54 +390,Bobbie,Peet,321-618-4507,Male,6,40,10,2018-12-07 06:56:32,2018-05-26 07:54:01,2018-02-12 22:14:19,2018-03-02 09:00:13 +391,Waylon,Brignall,721-399-8864,Male,2,29,55,2018-03-05 23:01:40,2018-02-12 20:24:53,2018-10-03 20:50:03,2018-05-27 20:39:09 +392,Randene,M'Chirrie,274-833-8717,Female,7,5,29,2018-11-09 00:26:39,2018-05-08 06:51:45,2018-10-07 04:03:07,2018-07-11 15:11:59 +393,Venus,Burgise,888-311-2349,Female,5,49,10,2018-01-31 18:35:34,2018-06-11 17:52:44,2019-01-18 10:15:45,2018-01-29 11:19:22 +394,Patton,Atkirk,887-990-8528,Male,3,14,48,2018-09-02 04:16:21,2018-12-07 12:14:18,2018-09-11 02:15:29,2018-05-31 08:26:51 +395,Ethelda,Sclater,557-210-5737,Female,2,98,59,2018-10-08 02:45:35,2018-03-07 11:02:12,2018-03-09 22:30:08,2018-07-15 06:00:38 +396,Kerry,Mascall,178-504-3458,Male,3,83,65,2018-08-12 19:58:08,2018-07-06 21:04:42,2018-07-15 00:45:35,2018-11-11 14:30:45 +397,Kelsey,Bohills,477-245-9384,Female,4,23,40,2018-08-31 00:28:52,2018-04-23 15:33:52,2018-08-22 04:21:43,2018-12-27 08:56:06 +398,Brennen,Ahrendsen,666-924-8234,Male,3,47,82,2018-12-10 22:01:21,2018-11-13 15:03:16,2018-01-21 19:47:47,2018-07-28 11:39:10 +399,Carmelina,Mountcastle,871-952-4482,Female,6,14,79,2018-05-25 02:01:07,2018-05-15 19:52:19,2018-07-16 23:16:38,2018-05-22 23:32:19 +400,Dale,Eltone,663-128-1228,Male,1,80,26,2018-10-13 23:51:08,2018-02-19 19:49:01,2018-01-27 11:58:54,2018-07-02 14:05:44 +401,Brianna,Beauchop,922-667-1003,Female,5,12,12,2018-11-05 20:21:33,2018-06-24 22:17:20,2018-06-12 04:34:37,2018-07-09 06:48:22 +402,Guillema,MacKibbon,164-334-7955,Female,3,6,56,2018-06-24 21:01:56,2018-08-15 08:52:58,2018-07-21 21:42:02,2018-02-26 08:29:48 +403,Ettore,Brailsford,231-820-9624,Male,1,92,34,2019-01-17 05:37:42,2018-06-30 12:14:43,2018-04-11 20:55:10,2018-01-21 17:40:14 +404,Shawn,M'cowis,293-256-5912,Male,7,12,87,2018-02-07 20:27:20,2018-08-07 19:48:03,2019-01-01 18:32:27,2018-08-31 20:41:20 +405,Lolly,Rankcom,743-968-5736,Female,2,17,31,2018-11-03 21:37:26,2018-07-18 08:15:01,2018-12-28 23:22:36,2018-09-04 02:20:01 +406,Jeffry,Dingle,194-835-0524,Male,1,6,58,2018-10-21 16:42:07,2018-06-01 21:41:20,2018-06-17 04:34:34,2018-12-29 19:09:29 +407,Marcelle,Molder,766-356-8780,Female,3,85,45,2018-10-18 11:17:27,2018-10-17 20:18:59,2018-09-05 10:30:56,2018-08-10 06:31:09 +408,Binni,Ferney,214-353-4132,Female,6,6,98,2018-02-20 07:18:40,2018-06-24 11:40:51,2018-12-13 02:29:35,2018-10-04 10:52:07 +409,Pat,Whenham,885-713-4885,Male,7,64,5,2018-10-29 12:39:59,2018-11-08 18:24:31,2018-04-17 11:10:35,2018-10-13 22:45:02 +410,Towney,Mizzi,602-556-2702,Male,7,40,94,2018-03-02 22:07:54,2018-08-30 01:11:53,2018-12-21 22:30:09,2018-04-08 21:36:17 +411,Cecil,Bickerdike,577-476-2260,Male,2,2,65,2018-02-25 13:53:37,2018-02-13 04:10:01,2018-05-27 20:30:46,2018-04-11 01:36:56 +412,Franciskus,Thomlinson,539-919-8711,Male,4,69,14,2018-11-12 12:18:44,2018-02-07 14:40:19,2018-08-23 04:04:48,2018-02-11 00:53:06 +413,Valentino,Machent,281-308-6846,Male,6,76,23,2018-10-04 13:04:01,2018-09-13 11:56:13,2018-06-25 21:50:15,2018-06-03 04:08:35 +414,Evelin,Harpham,287-743-1401,Male,7,1,5,2018-06-15 01:25:03,2018-05-17 06:35:54,2018-10-22 08:02:14,2018-08-25 01:58:06 +415,Cassandre,Crum,685-341-7481,Female,3,25,79,2018-07-29 10:09:33,2018-01-30 23:16:22,2019-01-13 15:40:35,2018-07-14 15:57:17 +416,Loren,Leschelle,321-405-9197,Male,3,26,13,2018-04-29 06:52:46,2018-06-21 13:57:41,2018-07-30 18:39:32,2018-09-01 00:31:38 +417,Ilaire,Plose,336-197-4797,Male,1,53,50,2018-07-01 07:52:56,2018-10-30 02:18:43,2018-08-21 23:46:29,2018-08-07 13:03:11 +418,Hannis,Issacof,315-716-3782,Female,2,99,85,2019-01-19 10:40:46,2018-04-26 10:04:56,2018-11-15 02:42:19,2018-08-21 16:50:00 +419,Meggie,Beeke,556-174-4615,Female,1,13,85,2018-03-05 16:12:22,2018-09-19 22:31:27,2018-12-04 04:01:57,2018-04-14 20:14:40 +420,Clemens,Leades,183-447-0091,Male,7,98,12,2018-06-18 06:17:24,2018-04-10 09:59:20,2018-03-20 22:45:02,2018-05-10 17:11:21 +421,Dennis,Chifney,196-548-2180,Male,7,75,98,2018-12-09 00:19:15,2018-06-16 10:29:26,2018-09-12 03:26:46,2018-10-24 16:42:20 +422,Yuri,Laytham,783-967-4260,Male,7,72,60,2018-01-28 20:33:42,2018-11-10 15:59:58,2018-05-07 10:19:43,2018-03-08 01:03:28 +423,Rosaline,Gibbins,376-974-7633,Female,3,22,56,2018-06-26 01:09:00,2018-10-30 23:51:58,2018-07-31 09:43:54,2018-11-23 12:00:53 +424,Yule,Hadwick,795-430-0875,Male,2,99,87,2018-03-09 17:35:22,2018-07-18 20:38:41,2018-08-29 09:29:40,2018-12-12 13:21:09 +425,Albertine,Bernlin,415-360-6554,Female,2,40,34,2018-05-24 10:27:28,2018-10-31 10:36:51,2018-07-04 15:40:42,2018-05-23 02:22:57 +426,Donnell,Stammler,944-379-5489,Male,4,59,41,2018-06-28 16:01:29,2018-05-18 12:55:36,2018-03-07 06:37:32,2018-03-25 12:44:31 +427,Brant,Athy,987-827-3040,Male,5,52,7,2018-01-24 14:17:54,2018-10-06 04:10:01,2018-02-21 04:02:17,2018-05-27 20:44:43 +428,Rose,Barnaby,789-522-4912,Female,7,31,46,2018-11-30 14:09:29,2018-11-06 16:28:33,2018-12-13 23:06:42,2018-09-12 17:39:14 +429,Valina,Ply,729-373-7904,Female,3,65,27,2018-11-15 05:26:26,2018-11-28 15:21:13,2018-05-01 00:56:08,2018-02-05 07:37:50 +430,Berkley,Ferry,484-341-3250,Male,6,47,48,2018-07-26 11:27:11,2018-03-05 19:23:46,2018-08-05 08:09:19,2018-05-30 08:43:28 +431,Jarred,Cunnington,995-170-5820,Male,4,6,1,2018-07-12 11:36:19,2018-10-19 05:16:25,2018-06-28 12:38:16,2018-10-08 06:52:46 +432,Marys,Audry,449-892-8929,Female,2,25,86,2018-11-21 14:36:19,2018-11-26 13:31:27,2018-03-28 15:22:34,2018-01-28 08:07:21 +433,Coreen,Vinnicombe,267-868-6003,Female,6,64,45,2018-10-19 22:09:21,2018-12-08 23:41:39,2018-08-16 05:46:08,2018-11-18 14:46:52 +434,Spense,Sarfati,945-773-9494,Male,4,6,3,2018-03-18 13:44:54,2018-09-04 10:40:58,2019-01-15 18:23:55,2018-06-07 16:02:39 +435,Chandra,Burgin,130-446-4470,Female,4,95,96,2018-09-27 16:48:00,2018-05-20 20:44:56,2018-11-23 04:46:53,2018-01-31 16:31:14 +436,Tomas,Currin,756-279-5643,Male,4,41,4,2018-11-18 07:22:02,2018-11-14 14:03:44,2018-09-18 12:36:39,2018-06-05 09:28:43 +437,Conway,Wesson,754-769-3550,Male,1,52,46,2019-01-02 08:07:04,2018-02-14 00:52:12,2018-02-11 10:52:29,2018-02-16 15:31:25 +438,Stefa,Meese,610-105-6841,Female,7,39,28,2018-04-28 02:21:35,2018-10-21 01:33:19,2018-11-23 21:00:01,2019-01-10 08:36:35 +439,Theadora,Ubee,609-368-9924,Female,6,42,5,2018-04-22 17:02:17,2018-08-21 16:33:25,2018-08-25 04:12:23,2018-02-16 01:13:06 +440,Virginia,Flawn,711-955-7169,Female,3,20,19,2018-08-16 18:01:55,2018-04-18 10:08:19,2018-01-27 09:38:48,2018-05-29 02:29:24 +441,Marv,Mummery,820-192-1452,Male,5,75,95,2018-05-29 15:29:25,2018-03-19 14:00:54,2018-01-22 01:15:38,2018-08-17 08:36:00 +442,Fulton,Zelake,283-584-1765,Male,7,4,3,2019-01-13 23:55:52,2018-08-19 22:29:51,2018-04-16 02:28:54,2018-03-16 16:58:02 +443,Guillemette,Ferretti,776-408-8649,Female,3,24,79,2018-07-31 04:43:48,2018-08-04 15:42:51,2018-04-11 16:00:11,2019-01-07 22:56:20 +444,Egbert,Dureden,698-387-7895,Male,7,54,6,2018-02-25 13:06:41,2018-01-28 14:50:49,2019-01-01 05:38:28,2018-06-19 00:46:05 +445,Trumaine,Canniffe,563-399-5639,Male,1,79,93,2018-11-08 00:30:08,2018-04-07 04:15:13,2018-03-30 14:48:19,2018-04-10 23:29:00 +446,Burr,Goves,451-577-7757,Male,1,27,72,2018-03-16 22:57:50,2018-02-04 21:42:45,2018-06-27 04:37:53,2019-01-16 15:20:56 +447,Juditha,Luebbert,958-685-2937,Female,4,36,87,2018-08-30 23:36:55,2018-06-22 07:04:37,2018-08-23 08:03:08,2018-03-28 04:50:57 +448,Lilly,Smewings,246-392-5467,Female,7,61,65,2018-06-02 21:56:15,2018-09-21 22:08:51,2018-11-29 20:26:34,2018-09-09 13:36:55 +449,Beckie,Curd,239-783-9576,Female,2,18,69,2018-11-20 04:10:54,2018-07-09 08:10:52,2018-03-19 21:04:09,2018-06-19 12:09:53 +450,Cristie,Edmonds,203-875-9153,Female,6,75,68,2018-11-16 10:01:12,2018-08-05 10:10:51,2019-01-11 05:06:49,2018-02-27 23:12:37 +451,Richmound,Machans,259-901-3247,Male,6,7,81,2019-01-12 15:06:01,2018-08-04 16:50:11,2018-12-30 16:16:18,2018-04-24 01:22:55 +452,Murial,Heiss,686-151-1653,Female,6,62,44,2018-05-18 13:49:57,2018-07-31 04:58:55,2018-02-26 22:38:19,2018-06-03 12:20:39 +453,Leonhard,O'Hear,205-401-7116,Male,5,3,1,2018-12-01 20:43:01,2018-06-19 12:45:05,2018-06-17 21:31:22,2018-12-29 20:41:28 +454,Kin,Yakovlev,952-369-5846,Male,1,39,38,2018-03-05 07:22:54,2018-06-20 14:24:43,2018-12-24 17:56:41,2018-07-13 07:55:25 +455,Debee,Fransinelli,230-272-0203,Female,3,64,60,2018-03-28 12:01:56,2018-09-10 13:03:46,2018-05-10 07:50:05,2018-08-10 09:35:31 +456,Nappie,Seaton,809-725-5784,Male,1,67,52,2018-09-13 00:18:51,2018-07-10 10:46:33,2018-04-19 00:56:44,2018-06-17 12:12:31 +457,Adelheid,Wanjek,795-641-9749,Female,1,21,97,2018-03-09 22:00:35,2018-08-09 22:29:44,2018-05-22 14:09:09,2018-03-19 18:49:28 +458,Jeannette,Glanville,377-671-9024,Female,7,84,44,2018-10-05 10:17:32,2018-04-06 12:22:12,2018-05-10 03:19:20,2018-09-30 04:25:01 +459,Adrianna,Blezard,773-598-7742,Female,6,89,62,2018-04-25 21:46:25,2018-05-26 05:44:50,2018-07-14 12:21:26,2018-09-28 10:26:06 +460,Gloria,Keelin,120-823-7944,Female,4,9,68,2018-07-13 21:08:25,2018-03-14 15:55:09,2018-04-02 02:08:40,2019-01-09 11:56:17 +461,Becki,Gatling,845-125-4361,Female,4,1,71,2018-06-24 20:47:16,2018-08-28 04:29:09,2018-05-06 23:04:29,2018-06-01 05:37:42 +462,Gabriellia,Lobley,844-697-7445,Female,2,89,99,2018-09-15 13:57:53,2018-06-14 14:04:36,2018-12-09 22:49:10,2018-02-12 02:07:35 +463,Aaren,McVie,973-286-0455,Female,4,67,14,2018-10-24 23:51:19,2018-04-28 04:48:26,2018-08-01 00:36:09,2018-07-03 13:36:32 +464,Barbara,Luddy,270-772-2682,Female,6,31,58,2018-03-18 11:34:08,2018-11-10 07:14:55,2018-12-12 21:20:10,2018-08-31 00:15:05 +465,Ibrahim,Went,494-197-0863,Male,3,35,42,2018-10-27 09:01:43,2018-05-24 01:03:27,2018-11-12 00:22:15,2018-03-28 09:23:37 +466,Sherry,Meert,142-492-1426,Female,7,30,41,2018-09-05 17:22:28,2019-01-11 02:43:23,2018-08-24 21:28:14,2018-03-23 18:02:50 +467,Marietta,Caulwell,931-150-2069,Male,5,5,93,2018-10-20 06:55:32,2018-08-24 12:59:12,2018-02-05 08:19:35,2018-01-23 22:03:22 +468,Kaiser,Gossage,250-466-8664,Male,6,23,93,2018-08-30 13:38:00,2018-10-27 22:45:24,2018-06-20 08:32:02,2018-01-25 09:32:34 +469,Margie,Fenelon,570-190-5079,Female,7,83,33,2018-12-11 01:27:54,2018-02-18 13:46:59,2018-09-23 21:24:36,2018-09-12 19:05:02 +470,Alvin,Stallan,451-964-7576,Male,6,25,97,2018-10-10 09:53:05,2018-05-12 18:37:24,2018-04-16 18:11:41,2018-12-06 13:37:08 +471,Corbin,Lamport,950-956-7283,Male,2,80,15,2018-10-08 17:14:14,2018-12-03 17:06:55,2018-08-04 22:29:17,2018-12-03 12:04:13 +472,Imelda,Crat,346-373-3643,Female,3,60,21,2018-01-25 18:42:27,2018-02-02 11:29:22,2018-05-12 06:06:53,2018-05-24 14:31:31 +473,Kala,Aikenhead,665-137-0705,Female,3,5,83,2018-03-11 01:11:04,2019-01-18 14:28:39,2018-04-20 06:28:31,2018-06-21 01:18:27 +474,Bastien,Lavell,325-523-0512,Male,7,87,91,2019-01-14 08:13:00,2018-06-08 18:23:51,2018-12-02 08:49:53,2018-12-06 00:24:41 +475,Muriel,Cannon,174-249-0377,Female,7,11,49,2018-06-09 02:06:14,2018-05-19 03:47:34,2018-02-15 07:14:49,2018-03-19 22:10:50 +476,Duane,Presland,616-278-2852,Male,6,49,20,2018-02-10 17:43:55,2018-02-21 00:21:21,2018-10-01 16:17:22,2018-04-06 08:15:06 +477,Emmerich,Baildon,408-829-6965,Male,1,13,29,2018-11-08 20:46:52,2018-07-04 14:45:10,2018-05-22 03:30:35,2018-07-26 23:46:21 +478,El,Seabourne,745-257-4885,Male,6,13,60,2019-01-05 01:40:08,2019-01-07 01:30:58,2018-08-24 00:13:56,2018-08-20 02:39:03 +479,Rivalee,Robertsson,882-741-1264,Female,3,36,70,2018-10-07 07:27:41,2018-05-13 11:32:58,2018-12-07 16:22:21,2018-12-12 19:59:38 +480,Alexis,Lapping,852-596-1033,Female,1,48,44,2018-01-30 22:17:04,2018-08-30 00:34:37,2018-11-04 00:05:38,2018-12-11 02:01:32 +481,Francine,Slatcher,134-351-4974,Female,1,56,91,2018-12-25 00:49:27,2018-10-11 02:42:45,2018-10-09 12:40:08,2018-09-01 13:26:34 +482,Kristen,Petters,440-151-8788,Female,7,19,49,2018-02-17 01:34:14,2018-10-28 03:18:55,2018-09-13 14:14:48,2018-01-22 12:26:05 +483,Riobard,Helin,217-648-4050,Male,6,3,62,2019-01-08 20:13:28,2018-07-10 21:50:12,2018-02-14 10:54:30,2018-07-10 15:21:36 +484,Jere,Marrison,125-522-1752,Male,5,77,48,2018-03-27 12:35:57,2018-08-11 12:06:00,2018-07-10 09:48:33,2018-11-12 18:44:01 +485,Sheila,Edens,296-894-3200,Female,3,99,67,2018-09-02 05:54:01,2018-03-13 04:55:49,2019-01-07 04:42:32,2018-12-12 03:46:51 +486,Georgy,Sallings,860-751-2558,Male,5,42,98,2018-03-04 09:36:14,2018-12-18 03:43:57,2018-05-26 16:22:04,2018-09-02 12:56:41 +487,Marcellina,Ledgister,286-469-6281,Female,6,17,35,2018-07-04 19:56:40,2018-04-13 18:15:53,2018-06-22 16:02:20,2018-02-12 13:24:14 +488,Terra,Dodamead,913-630-9923,Female,1,82,1,2018-12-11 19:54:27,2018-12-11 20:39:38,2018-03-28 15:51:45,2018-08-25 04:08:21 +489,Alia,Morrel,431-923-1395,Female,7,7,38,2018-05-24 06:33:39,2018-03-16 20:23:58,2018-09-11 05:45:02,2018-02-10 15:26:52 +490,Henri,Cullivan,513-315-1874,Male,2,7,65,2018-02-21 12:36:28,2018-02-28 14:01:27,2018-11-04 00:27:37,2018-06-18 18:54:48 +491,Josie,Langrish,674-305-6918,Female,2,79,72,2018-07-26 02:09:25,2018-12-03 14:04:40,2018-10-18 18:24:47,2018-09-01 09:38:00 +492,Brittany,Redwall,197-871-1265,Female,2,98,39,2019-01-15 16:02:18,2018-07-28 14:31:51,2019-01-05 12:31:54,2018-02-17 02:21:53 +493,Phillie,Caulket,276-222-0475,Female,2,92,27,2018-10-19 10:58:15,2018-10-01 05:23:18,2018-10-31 20:41:31,2018-01-23 21:09:13 +494,Clair,Ring,789-696-3129,Female,1,60,89,2018-12-15 04:12:43,2018-03-14 18:18:51,2018-02-01 04:15:54,2018-05-24 23:34:59 +495,Allis,Sunner,601-505-2836,Female,3,37,9,2018-03-16 18:20:34,2018-10-03 23:52:03,2018-09-09 20:19:13,2018-09-12 13:27:03 +496,Madeleine,Haitlie,956-801-4088,Female,4,55,99,2018-05-23 09:24:40,2018-09-25 14:13:54,2018-12-07 06:01:21,2018-08-05 05:36:15 +497,Cirillo,Gronav,571-141-3522,Male,5,81,10,2018-10-11 20:52:40,2018-02-21 03:11:05,2018-09-16 08:35:42,2018-03-26 20:16:43 +498,Arturo,Cowitz,923-926-3273,Male,3,93,12,2018-11-22 05:37:54,2018-02-17 15:11:34,2018-03-31 00:15:46,2018-08-03 14:49:13 +499,Haley,Cartmill,139-891-8155,Female,2,79,56,2018-10-28 03:24:17,2018-09-26 03:42:15,2018-09-16 20:27:43,2018-10-21 06:51:02 +500,Caddric,Eim,386-491-4555,Male,4,88,81,2018-07-27 07:41:11,2018-11-06 13:25:15,2018-04-30 01:01:46,2018-10-27 13:14:40 +501,Sargent,Beart,958-909-4690,Male,1,44,9,2018-07-18 12:02:07,2018-07-23 05:06:07,2018-07-16 15:25:53,2018-08-26 13:12:34 +502,Dane,Gason,502-241-7120,Male,6,79,58,2018-11-17 04:47:55,2018-07-17 16:19:37,2018-12-02 13:39:55,2018-08-07 15:28:47 +503,Humfried,Canelas,275-518-1730,Male,3,82,87,2018-02-02 11:38:29,2018-10-18 04:09:03,2018-02-04 00:47:16,2018-07-23 00:37:30 +504,Sam,Freiberg,757-773-6048,Female,5,89,31,2018-12-01 22:51:12,2018-06-29 03:50:29,2018-07-25 14:13:37,2018-06-11 22:59:09 +505,Goddart,Crossgrove,820-183-6322,Male,3,41,25,2018-11-22 23:25:36,2018-01-29 08:12:28,2018-09-24 21:36:56,2018-03-04 00:40:37 +506,Joela,Bondesen,856-474-9498,Female,5,71,97,2018-05-08 08:23:42,2018-12-20 17:54:27,2018-08-13 11:11:11,2018-08-06 19:06:58 +507,Harrie,Nendick,943-670-9341,Female,3,66,6,2018-05-03 20:18:57,2018-11-06 16:35:09,2018-07-18 17:01:56,2018-03-29 06:23:00 +508,Farlay,Manderson,834-991-0018,Male,4,44,9,2018-08-16 12:51:08,2018-09-19 19:35:31,2018-09-28 07:49:16,2018-11-26 04:15:32 +509,Warren,Pegram,815-768-9711,Male,1,2,70,2018-11-03 16:08:12,2018-09-27 19:07:58,2018-02-15 09:57:42,2018-02-04 05:33:01 +510,Mylo,Haskayne,624-512-7407,Male,3,71,28,2018-11-05 07:00:48,2018-08-22 23:42:06,2018-10-13 09:30:14,2018-12-17 14:14:01 +511,Giacomo,Halsho,976-203-6826,Male,2,59,100,2018-04-11 12:30:03,2018-05-06 11:36:27,2019-01-03 21:44:26,2018-06-13 06:17:36 +512,Aloysia,Stuchburie,466-684-9228,Female,7,15,94,2018-05-05 20:22:16,2018-05-06 16:01:54,2018-11-13 03:57:27,2018-08-05 07:41:19 +513,Brit,Glentz,283-639-7723,Male,4,5,19,2018-04-07 12:25:00,2018-09-26 07:12:01,2018-06-05 14:15:20,2018-06-02 16:59:25 +514,Maddi,Kerfoot,543-438-1531,Female,3,16,67,2018-06-30 07:58:22,2018-12-16 23:14:43,2019-01-03 10:51:10,2018-09-10 17:15:42 +515,Ruy,Townson,801-852-6590,Male,1,31,55,2018-02-22 06:06:31,2019-01-20 20:38:59,2018-09-28 17:23:51,2018-09-30 05:48:30 +516,Rawley,Tatum,634-340-1379,Male,5,32,35,2018-02-14 04:43:24,2018-06-30 10:54:44,2018-11-22 11:23:10,2018-03-01 16:10:00 +517,Teddy,Pickford,404-551-3889,Male,2,82,54,2018-12-29 05:25:46,2018-04-13 05:46:18,2018-10-11 18:14:38,2018-11-07 08:35:59 +518,Randolph,Stealfox,750-802-5940,Male,3,91,11,2018-04-03 20:00:54,2018-11-29 19:15:41,2018-02-20 09:38:24,2018-03-25 15:38:52 +519,Filmer,Sumption,833-713-4339,Male,2,2,8,2018-01-26 04:26:32,2018-03-08 20:23:21,2018-07-27 10:41:05,2018-11-04 20:18:36 +520,Barbee,Salvador,475-228-6268,Female,1,13,71,2018-10-24 00:02:01,2018-01-21 21:29:45,2018-07-03 13:31:36,2019-01-07 14:59:36 +521,Valina,Spillett,588-767-5376,Female,5,27,8,2018-03-03 01:39:51,2018-01-28 01:22:11,2018-04-22 03:30:25,2018-03-08 04:45:22 +522,Taber,Faunt,428-608-8317,Male,5,46,93,2018-06-09 11:17:55,2018-09-01 01:34:32,2018-02-19 13:01:55,2018-08-15 06:00:48 +523,Lilas,Siemons,680-968-7597,Female,6,31,25,2018-11-26 22:08:43,2018-02-15 23:08:21,2018-12-26 05:40:57,2018-02-22 02:08:43 +524,Spence,Vosper,720-164-0499,Male,2,37,73,2018-01-31 08:38:29,2018-07-08 11:20:30,2018-10-31 09:36:46,2018-08-26 13:46:48 +525,Robinett,Le Breton De La Vieuville,690-247-8261,Female,6,47,79,2018-04-02 23:29:51,2018-04-26 14:43:49,2018-09-29 04:02:35,2018-02-22 14:19:00 +526,Pia,Favell,689-639-0553,Female,5,96,86,2018-09-27 09:10:13,2018-02-18 08:18:56,2018-09-16 10:20:42,2018-09-19 19:46:37 +527,Jody,Persich,875-503-4255,Female,5,1,63,2018-12-28 04:07:08,2018-02-19 06:37:40,2018-11-08 19:30:56,2018-04-16 19:36:13 +528,Mimi,Meach,664-906-5485,Female,3,46,59,2018-05-16 02:36:27,2018-02-06 06:52:54,2018-03-16 20:22:46,2018-12-24 10:29:20 +529,Nyssa,Hillborne,493-931-8360,Female,6,70,73,2018-12-08 00:07:34,2018-01-31 21:28:10,2018-04-14 12:33:22,2018-12-18 17:12:16 +530,Chrissie,Jagger,284-506-7117,Male,7,89,53,2018-03-21 21:11:02,2018-09-10 16:42:15,2019-01-17 21:11:31,2018-10-26 07:01:07 +531,Jacqueline,Hebblewhite,313-329-3935,Female,6,70,40,2018-07-29 17:39:44,2018-08-26 14:11:15,2018-12-18 12:39:49,2018-09-04 11:21:47 +532,Gunilla,Frarey,231-521-7913,Female,7,3,44,2018-03-05 06:12:04,2018-06-21 16:09:41,2018-01-27 13:30:18,2018-02-28 16:14:26 +533,Eleni,Fassum,149-906-0502,Female,1,40,27,2018-11-17 06:56:45,2018-06-22 05:04:09,2018-05-07 22:21:42,2018-12-21 21:39:19 +534,Kerr,Kelshaw,729-673-6161,Male,6,94,93,2018-11-23 00:31:03,2018-12-09 03:46:43,2018-02-22 16:54:17,2018-09-09 11:05:13 +535,Lisha,Curgenven,874-739-3351,Female,4,97,18,2018-02-20 18:11:36,2018-10-17 06:38:52,2018-12-26 02:40:15,2018-02-13 09:24:09 +536,Bevin,Jakeman,676-751-7045,Male,1,87,71,2018-02-20 13:08:18,2018-11-21 06:36:13,2018-09-22 09:22:49,2018-10-09 06:21:12 +537,Harland,Sidney,139-828-9659,Male,6,23,85,2018-09-18 02:15:28,2018-04-10 06:49:54,2018-12-05 20:08:51,2018-08-05 09:53:26 +538,Rori,Seys,180-907-6460,Female,5,27,23,2018-02-22 03:55:23,2018-08-01 08:40:28,2018-05-15 12:42:51,2018-10-22 00:24:22 +539,Baxy,Marjanski,580-759-7206,Male,4,95,30,2018-09-01 14:33:22,2018-12-14 23:01:00,2018-12-02 00:20:18,2018-08-25 13:54:47 +540,Martie,Dearsley,102-718-1278,Male,7,89,15,2018-03-15 10:57:25,2018-03-03 03:48:25,2018-07-12 03:48:36,2018-07-22 13:18:47 +541,Erin,Ruddick,969-222-3994,Male,1,97,56,2018-05-18 05:27:05,2018-02-23 12:22:10,2018-04-13 08:34:06,2018-11-25 15:51:09 +542,Tome,Lorne,842-424-5954,Male,4,58,76,2018-12-11 13:20:20,2018-07-29 14:26:59,2018-08-12 08:27:28,2018-04-03 13:46:52 +543,Nell,Borkin,228-448-5895,Female,1,3,1,2018-11-30 16:38:15,2018-07-27 09:33:59,2018-08-23 02:00:10,2018-09-28 00:28:48 +544,Teirtza,Springthorp,538-731-0003,Female,4,8,3,2018-03-28 08:52:40,2018-11-03 18:14:45,2019-01-02 06:05:23,2018-03-22 22:01:00 +545,Arlina,Feighney,977-853-6783,Female,1,18,40,2018-02-08 21:04:46,2018-03-02 23:43:32,2018-03-05 13:33:15,2018-05-12 17:12:38 +546,Melosa,Gifford,804-769-4197,Female,7,55,98,2018-02-04 08:50:49,2018-10-10 06:22:51,2018-06-01 01:45:08,2018-12-24 03:31:15 +547,Charin,Petrello,597-441-0171,Female,6,67,18,2018-09-10 08:11:34,2018-03-15 18:44:45,2018-10-22 23:24:05,2018-07-31 01:37:48 +548,Cristian,Stute,223-959-7392,Male,2,5,69,2018-11-01 17:37:10,2018-05-25 14:21:07,2018-10-09 08:14:38,2018-06-29 13:27:34 +549,Velvet,Morison,848-981-1316,Female,1,20,17,2018-02-14 02:16:51,2018-08-25 23:57:58,2018-04-20 10:47:18,2018-04-04 19:16:45 +550,Vivienne,Taillard,392-626-2926,Female,2,38,47,2019-01-20 11:03:04,2018-06-11 20:42:47,2018-05-13 17:10:39,2018-06-02 20:11:46 +551,Zach,Vials,406-733-0058,Male,1,28,88,2018-12-14 14:36:03,2018-02-25 21:52:58,2018-10-17 02:37:28,2018-02-05 17:26:59 +552,Christie,De Caville,268-836-0470,Male,6,28,91,2018-11-26 14:01:43,2018-06-27 22:05:24,2018-11-10 16:11:15,2018-07-20 12:01:34 +553,Dulce,Walesby,578-217-3628,Female,6,83,40,2018-04-12 08:24:30,2018-10-07 09:32:47,2018-04-10 12:21:16,2018-06-04 11:56:13 +554,Shermy,Martinek,627-924-0370,Male,1,54,86,2018-09-02 00:41:57,2018-09-16 02:42:47,2018-05-10 03:54:12,2018-11-14 17:54:47 +555,Curcio,Cudworth,355-447-1790,Male,2,43,26,2018-05-31 02:31:23,2018-11-18 23:47:19,2018-02-26 10:49:12,2018-08-22 04:36:14 +556,Newton,Zuan,810-756-5844,Male,5,85,20,2018-03-09 16:07:56,2018-10-12 16:45:42,2018-05-02 19:27:29,2018-04-21 12:37:09 +557,Gina,Keyho,566-476-0815,Female,4,8,83,2018-09-21 17:12:16,2018-03-20 10:13:51,2018-05-22 10:29:45,2018-09-23 17:23:36 +558,Emmanuel,Beacham,923-766-7627,Male,4,15,10,2018-10-14 04:16:42,2018-12-12 21:49:16,2018-04-06 14:49:00,2018-02-10 06:29:37 +559,Mel,Deniseau,577-125-8484,Female,3,12,6,2018-06-01 18:43:13,2018-11-09 14:24:38,2018-07-01 23:11:43,2018-11-24 10:28:42 +560,Deena,Knutton,544-886-5072,Female,2,98,57,2018-02-11 05:11:20,2018-08-19 14:06:35,2018-09-06 12:12:59,2018-10-07 13:53:21 +561,Flossy,Antonacci,108-542-7284,Female,2,20,36,2018-05-20 08:28:31,2018-04-01 14:07:20,2018-07-23 02:08:55,2018-08-29 00:40:11 +562,Gabriela,Gravy,565-992-0341,Female,3,54,70,2018-03-14 07:29:51,2018-11-24 05:40:57,2018-06-24 11:53:15,2018-12-13 15:23:43 +563,Emelen,Healey,821-210-6931,Male,7,16,79,2018-03-02 11:53:31,2018-07-04 07:43:45,2018-08-20 22:28:53,2018-08-20 07:13:10 +564,Anne-marie,Peatman,431-777-2495,Female,4,38,1,2018-02-28 18:38:14,2018-08-28 18:58:41,2018-09-01 22:16:42,2018-11-14 23:08:02 +565,Raymond,Truelock,671-694-3305,Male,5,20,76,2018-11-19 18:58:41,2018-10-26 03:22:35,2018-10-13 10:05:37,2018-10-20 00:19:39 +566,Gabriel,Matlock,704-620-9706,Female,1,29,24,2018-07-24 15:56:02,2018-12-23 10:03:48,2018-07-13 22:41:53,2018-06-12 13:42:42 +567,Leontine,Kollasch,793-692-0103,Female,4,68,78,2018-05-05 06:54:44,2018-07-26 19:41:30,2018-04-16 00:46:38,2018-11-20 19:18:17 +568,Amelina,Gullick,674-849-6707,Female,2,75,43,2019-01-01 12:18:11,2018-02-18 10:50:33,2018-09-11 05:30:18,2018-12-28 03:43:14 +569,Matthew,Gateley,450-774-0905,Male,5,93,62,2018-02-17 13:01:16,2018-06-17 01:27:48,2018-12-03 19:17:56,2018-08-31 08:39:46 +570,Alvan,Postance,415-301-3970,Male,5,36,24,2018-02-15 12:09:30,2018-07-26 19:38:06,2018-09-23 03:56:41,2018-09-17 12:13:43 +571,Ethelind,Otteridge,724-398-4832,Female,1,11,20,2019-01-09 07:06:55,2018-08-06 11:24:34,2018-02-04 09:08:33,2018-02-04 10:18:38 +572,Allayne,Pettegre,567-912-1393,Male,5,50,24,2019-01-17 18:14:12,2018-03-20 23:30:29,2018-07-08 17:53:55,2018-03-30 22:34:32 +573,Cindee,MacGill,218-267-2220,Female,3,85,36,2018-03-18 06:24:30,2018-08-12 14:08:59,2018-06-07 00:36:38,2018-07-28 18:35:16 +574,Jeramie,Fante,508-403-4318,Male,6,17,58,2018-09-05 21:09:00,2018-07-16 01:34:59,2018-05-30 20:15:51,2018-10-07 09:23:32 +575,Johannah,Treamayne,670-278-1704,Female,1,44,50,2018-09-01 12:25:07,2018-09-04 03:56:02,2018-03-25 08:47:56,2018-06-27 19:44:57 +576,Dari,Brocklesby,128-823-5176,Female,2,21,47,2018-11-06 21:06:13,2018-11-23 13:57:31,2019-01-01 00:06:22,2018-06-23 04:39:41 +577,Cob,Younglove,589-756-5544,Male,1,34,97,2018-06-06 05:48:43,2019-01-01 02:48:52,2018-09-20 02:52:35,2018-06-29 07:02:35 +578,Genevieve,Benois,718-259-0218,Female,1,83,84,2018-12-29 00:38:58,2019-01-17 14:12:58,2018-08-21 12:35:34,2018-07-15 16:50:51 +579,Demetra,Clineck,537-758-1797,Female,7,58,86,2018-04-18 09:28:08,2018-05-18 03:26:25,2018-02-24 07:51:24,2018-12-11 05:21:46 +580,Edithe,MacNeilage,254-201-0040,Female,5,2,46,2018-12-06 12:01:57,2018-02-16 02:10:30,2018-02-23 14:46:58,2018-12-31 17:43:21 +581,Osbourne,Scranny,682-363-4094,Male,3,29,17,2018-05-10 17:26:21,2018-11-02 03:59:01,2018-04-07 16:21:34,2018-07-31 23:17:47 +582,Con,Shyre,535-646-6697,Male,3,96,16,2018-07-14 00:36:39,2018-12-15 03:20:27,2018-07-23 10:48:18,2018-03-18 15:21:58 +583,Sylvester,Cannicott,456-905-3181,Male,1,2,37,2018-12-19 15:40:57,2018-06-18 08:08:39,2018-05-16 20:50:39,2018-10-02 13:56:35 +584,Any,Hayter,822-858-6900,Male,7,52,26,2018-11-06 13:05:00,2018-12-07 12:10:14,2018-12-30 08:34:38,2018-11-29 15:54:05 +585,Hebert,Casaro,238-642-2667,Male,5,86,80,2018-08-01 13:07:27,2018-11-03 12:14:52,2018-07-26 07:25:57,2019-01-19 03:35:48 +586,Lurlene,Feare,839-313-4455,Female,3,59,51,2018-08-26 04:27:58,2018-10-22 00:35:33,2018-06-26 19:50:51,2018-10-10 07:34:07 +587,Benjy,Mulvenna,623-742-2472,Male,3,63,37,2018-12-05 12:16:12,2018-06-01 06:27:24,2018-05-17 11:06:08,2018-11-03 18:34:32 +588,Odey,Burborough,705-824-5381,Male,7,35,7,2018-11-08 11:17:04,2018-10-02 17:39:13,2018-06-12 17:24:31,2018-11-16 00:36:52 +589,Marin,Piddletown,544-353-3265,Female,6,65,12,2018-06-05 02:00:30,2018-04-15 22:13:49,2018-10-25 08:48:07,2018-02-10 21:14:37 +590,Cyrille,holmes,735-579-6221,Male,7,40,75,2018-04-16 22:04:54,2018-04-25 22:55:07,2018-07-02 18:15:05,2018-08-10 21:27:54 +591,Maurice,Rains,484-638-1467,Male,5,73,91,2018-09-29 20:25:42,2018-05-09 00:14:24,2018-10-31 20:25:12,2018-10-07 19:50:59 +592,Caddric,Styant,859-759-9605,Male,6,10,38,2018-06-20 20:21:02,2018-12-09 17:47:12,2019-01-09 04:06:46,2018-07-19 05:01:01 +593,Vittorio,Straffon,643-403-5013,Male,3,46,7,2018-05-21 05:19:11,2018-12-06 16:33:18,2018-07-03 02:13:34,2018-11-03 12:50:20 +594,Filippo,Adamiak,414-171-7965,Male,5,13,70,2018-03-31 10:48:08,2018-07-07 00:41:10,2018-04-29 13:12:05,2018-08-12 07:32:33 +595,Abran,Blanning,940-243-9117,Male,6,88,72,2018-06-16 02:58:35,2018-08-17 14:00:04,2018-12-23 23:58:31,2018-04-15 17:28:52 +596,Ewart,Van Der Weedenburg,712-866-8225,Male,1,35,99,2018-12-03 12:43:02,2018-08-22 00:51:23,2018-06-03 09:07:10,2018-02-26 12:18:48 +597,Charmion,Toffoletto,139-517-9898,Female,2,60,33,2018-11-24 14:11:52,2018-10-26 03:35:48,2018-12-18 20:13:45,2018-09-23 22:05:26 +598,Marcellus,Casserly,253-327-1311,Male,3,41,81,2018-10-18 22:38:49,2018-03-13 20:31:39,2018-07-25 06:23:51,2018-06-05 20:55:02 +599,Bryant,Woonton,888-556-3681,Male,7,81,99,2018-02-28 09:31:55,2018-05-01 06:19:53,2019-01-09 14:08:26,2018-10-29 15:33:42 +600,Annnora,Beswick,518-587-0261,Female,6,56,22,2018-08-12 21:49:43,2019-01-08 19:34:20,2018-02-14 10:14:40,2018-08-01 03:40:27 +601,Donovan,Stenner,407-562-5695,Male,1,80,76,2018-08-31 07:45:11,2018-12-01 06:25:41,2018-02-28 03:57:11,2018-10-17 16:19:27 +602,Northrup,Limprecht,463-752-6075,Male,5,65,42,2018-11-03 02:27:29,2018-05-05 19:23:48,2018-02-18 06:54:36,2018-08-13 18:47:59 +603,Linoel,Havenhand,896-715-3769,Male,7,7,25,2018-05-10 18:45:39,2018-01-27 18:35:14,2018-06-14 18:17:37,2018-03-26 21:54:40 +604,Gerrilee,Morant,914-846-5569,Female,4,45,66,2018-02-17 20:40:10,2018-01-31 19:47:44,2018-10-09 22:28:47,2018-10-27 15:15:40 +605,Giralda,Daine,952-600-0863,Female,4,28,60,2018-06-15 19:09:55,2018-04-30 04:40:26,2018-09-14 06:48:06,2018-02-10 19:05:33 +606,Joela,Rand,808-932-6875,Female,1,27,3,2018-08-16 15:12:40,2018-09-27 15:12:49,2018-05-27 05:51:56,2018-04-13 14:52:35 +607,Obidiah,Beecham,324-361-0116,Male,7,72,18,2018-10-28 13:32:50,2018-06-20 18:58:47,2018-11-02 11:51:44,2018-03-11 23:29:03 +608,Karlik,Witherington,317-493-1871,Male,4,86,11,2019-01-20 03:58:33,2018-07-21 12:26:45,2018-08-23 20:09:48,2018-11-13 10:55:23 +609,Andras,Buttler,645-159-2747,Male,4,66,45,2018-05-19 10:32:36,2018-12-15 13:10:33,2018-01-31 23:04:41,2019-01-04 22:38:54 +610,Kevan,MacCorkell,902-102-9241,Male,5,35,56,2018-02-09 15:51:27,2018-07-17 04:54:50,2018-01-23 13:03:51,2018-07-12 19:59:05 +611,Dena,Welbelove,824-828-1515,Female,7,30,100,2018-03-13 11:53:11,2018-07-30 19:53:24,2019-01-12 19:12:36,2018-10-23 22:10:25 +612,Susette,Spurman,489-770-6265,Female,5,20,53,2018-05-08 12:17:52,2018-06-18 00:15:28,2018-04-14 14:12:49,2018-09-21 10:34:01 +613,Lisabeth,Clarycott,631-189-3198,Female,7,98,3,2018-08-30 00:26:48,2018-03-16 13:08:16,2018-10-12 07:44:50,2018-10-14 13:12:31 +614,Sheryl,Cicchinelli,508-453-8265,Female,6,77,4,2019-01-04 08:57:07,2018-07-27 00:56:42,2018-07-07 09:59:19,2018-08-03 11:54:06 +615,Milly,Harston,959-484-0888,Female,3,13,88,2018-05-02 06:02:08,2018-05-11 09:34:20,2019-01-11 22:42:26,2018-02-06 01:43:05 +616,Avery,Cant,144-536-3636,Male,5,59,83,2018-04-28 04:40:20,2018-02-20 10:21:26,2018-01-23 14:16:23,2018-06-13 17:25:06 +617,Odelle,Hauxley,311-843-6729,Female,2,15,33,2018-06-09 20:51:56,2018-03-22 15:09:29,2019-01-07 22:47:04,2018-10-30 05:38:26 +618,Symon,Dewi,944-566-4724,Male,6,79,26,2018-10-23 03:09:57,2018-04-20 15:52:10,2018-07-23 05:16:26,2018-09-05 13:15:24 +619,Nora,Ingerson,644-377-6341,Female,7,58,74,2018-12-31 01:35:50,2018-03-08 16:01:54,2018-04-02 13:25:27,2018-08-14 07:54:24 +620,Mariam,Ceschelli,722-520-3029,Female,5,65,57,2018-08-17 21:29:16,2018-11-14 18:13:13,2018-11-22 04:05:56,2018-03-25 21:13:21 +621,Guglielma,Fearey,399-683-0328,Female,2,48,46,2018-12-01 22:21:56,2018-05-05 09:53:28,2018-04-01 03:22:30,2018-10-31 05:13:13 +622,Putnem,Glanton,730-351-4499,Male,3,47,40,2018-05-06 05:22:19,2018-08-03 21:56:51,2018-07-27 03:42:36,2018-09-26 03:10:38 +623,Blancha,Penney,585-209-3640,Female,4,92,1,2018-04-24 13:18:47,2018-06-21 21:42:31,2018-03-11 01:50:30,2018-08-17 20:04:54 +624,Zacherie,Manoelli,211-774-0854,Male,7,41,38,2018-09-29 10:25:00,2018-11-03 11:49:35,2018-06-04 21:41:44,2018-10-24 16:29:50 +625,Seymour,Murphey,840-189-1695,Male,7,27,18,2018-11-22 02:51:55,2018-11-13 09:09:33,2018-04-26 15:24:33,2018-06-10 09:01:11 +626,Kiele,Potte,807-707-7776,Female,5,50,79,2018-12-10 09:07:14,2018-02-09 02:17:04,2018-12-02 09:39:41,2018-06-25 03:58:33 +627,Pascale,Keat,699-216-9743,Male,6,20,78,2018-11-23 01:30:15,2018-04-11 09:12:08,2018-03-14 20:14:59,2018-02-13 23:24:16 +628,Krisha,Sails,162-533-7679,Male,5,91,52,2019-01-17 01:56:16,2018-02-15 14:18:56,2018-03-05 23:19:21,2018-02-24 11:00:50 +629,Justen,McFeat,266-387-8084,Male,4,45,19,2018-10-17 20:09:40,2018-12-29 10:26:10,2018-07-21 12:46:49,2018-02-12 09:50:24 +630,Daloris,Adamson,173-669-4723,Female,4,46,42,2018-02-02 14:26:53,2018-08-15 00:31:20,2018-10-28 08:17:42,2018-04-21 16:28:19 +631,Saleem,Cawood,885-138-1413,Male,6,96,11,2018-09-04 09:51:41,2018-06-12 17:37:20,2018-12-09 22:22:56,2018-11-28 01:06:26 +632,Yettie,Glynn,672-547-0019,Female,3,84,66,2018-11-13 23:39:10,2018-07-14 16:14:12,2018-09-21 13:43:43,2018-09-29 15:57:10 +633,Waite,Smalls,320-394-9058,Male,4,2,55,2018-12-17 16:32:29,2018-11-15 01:45:06,2018-03-17 23:34:19,2018-03-06 15:12:35 +634,Tomkin,Adam,674-394-3276,Male,3,5,48,2018-02-07 03:48:38,2018-07-13 14:23:03,2018-06-02 14:48:09,2018-07-13 06:23:14 +635,Dilly,Strotone,507-532-7349,Male,2,63,15,2018-10-18 04:02:56,2018-08-29 04:49:57,2018-12-04 03:03:45,2018-10-13 05:54:24 +636,Townsend,Eytel,577-285-3662,Male,2,28,15,2018-06-01 12:29:01,2018-09-17 04:48:03,2018-08-12 21:57:59,2018-02-19 20:48:01 +637,Aurel,Taleworth,826-459-6823,Female,4,21,100,2018-08-04 08:00:57,2018-09-17 17:45:32,2018-10-01 19:40:32,2018-09-12 06:23:27 +638,Barnabe,Eldredge,303-934-8908,Male,1,96,66,2018-11-25 12:08:25,2018-09-28 04:15:54,2018-06-11 18:54:23,2018-01-29 01:27:18 +639,Brnaby,Kwietek,319-338-0342,Male,1,99,21,2018-07-11 05:00:49,2018-09-07 18:54:24,2019-01-02 06:20:42,2018-07-12 08:08:28 +640,Thea,Beamont,123-463-1082,Female,4,95,46,2018-03-04 16:30:12,2018-09-20 03:40:11,2018-07-15 14:34:10,2018-08-29 13:50:42 +641,Moyra,MacAne,973-363-3000,Female,3,50,66,2018-06-15 02:19:51,2018-07-18 23:41:04,2018-11-11 08:19:50,2018-07-28 23:40:30 +642,Luce,Hanmer,800-595-2765,Male,4,71,68,2018-12-29 07:24:16,2018-03-30 23:25:56,2018-12-20 17:22:17,2018-07-01 23:50:17 +643,Clement,Gobert,746-653-6801,Male,2,29,39,2018-03-16 20:33:17,2018-12-07 02:34:52,2018-12-12 16:45:55,2018-12-20 02:30:28 +644,Dalenna,Kingsnorth,366-634-1391,Female,5,42,29,2018-04-19 19:41:25,2018-11-24 02:02:50,2018-03-31 05:36:32,2018-07-16 23:22:03 +645,Gigi,MacGilrewy,807-983-4035,Female,2,5,59,2018-11-13 14:20:34,2018-09-08 20:54:02,2018-09-05 14:11:49,2018-06-05 21:12:39 +646,Josi,De Vere,191-357-7492,Female,3,26,63,2018-11-16 05:10:17,2018-05-10 22:27:04,2018-05-04 18:15:10,2018-06-28 04:26:52 +647,Ripley,Pedrozzi,564-644-3142,Male,4,81,64,2018-05-06 05:04:31,2018-09-08 07:15:00,2018-11-12 01:23:19,2018-08-14 01:45:01 +648,Angelina,Henriques,513-742-8132,Female,1,4,93,2018-08-13 00:14:12,2018-03-20 21:24:41,2018-08-07 23:30:14,2018-11-23 00:03:11 +649,Anthia,Dandy,983-456-4556,Female,4,7,96,2018-05-12 17:03:46,2018-12-07 05:19:51,2018-11-20 12:22:28,2018-10-03 06:06:09 +650,Audry,Mourge,237-352-0739,Female,3,87,13,2018-01-25 21:10:18,2018-04-08 08:11:55,2018-01-26 17:58:05,2018-11-22 16:05:01 +651,Konstanze,Skocroft,383-376-4511,Female,5,53,15,2018-07-06 21:47:19,2018-07-21 19:51:01,2019-01-05 19:31:14,2018-12-02 06:51:10 +652,Koo,Arington,553-175-9464,Female,4,51,72,2018-03-12 21:13:34,2018-01-29 22:50:56,2018-07-28 03:59:46,2018-09-08 20:40:26 +653,Mimi,Novakovic,282-495-5519,Female,2,13,7,2019-01-18 17:51:56,2018-03-21 21:03:27,2018-11-26 23:09:59,2018-02-15 16:11:04 +654,Aldus,Aguirrezabal,289-348-2177,Male,2,27,59,2018-11-06 12:55:08,2018-03-03 18:13:31,2018-04-12 18:22:35,2018-08-22 21:43:49 +655,Sullivan,Kelmere,595-312-2528,Male,1,42,45,2018-12-01 16:35:57,2018-10-25 18:48:22,2018-09-07 00:15:27,2018-04-27 11:34:49 +656,Taite,Ruffli,824-778-7852,Male,4,22,46,2018-07-28 22:54:17,2018-10-09 20:45:57,2018-08-03 04:38:39,2018-11-26 15:09:49 +657,Rosene,Missen,922-494-6731,Female,7,91,26,2018-08-17 20:06:33,2018-11-02 02:58:57,2018-03-05 00:03:11,2018-05-31 23:55:38 +658,Ty,Fucher,639-989-4144,Male,3,68,100,2018-07-22 01:36:24,2018-03-08 21:12:38,2018-05-04 21:30:03,2018-09-06 22:32:37 +659,Heddi,Assel,246-263-2031,Female,6,39,92,2018-02-15 08:32:02,2018-02-26 03:11:18,2018-01-27 11:33:06,2018-08-29 02:37:29 +660,Boonie,Djorvic,425-328-7219,Male,7,49,6,2018-02-11 23:21:23,2018-03-07 04:45:35,2019-01-16 02:27:45,2018-10-14 03:27:02 +661,Aurie,Esgate,216-596-1681,Female,4,44,39,2019-01-07 13:40:58,2018-09-29 18:40:04,2018-04-15 01:33:28,2018-11-16 00:59:28 +662,Dana,Edginton,762-855-7796,Male,7,11,7,2018-10-22 11:13:58,2018-02-25 07:53:13,2018-10-26 14:30:34,2018-02-21 08:22:28 +663,Christiana,Haslock(e),322-905-9384,Female,7,66,50,2018-04-08 07:38:08,2018-05-11 05:11:14,2018-03-13 07:31:38,2018-03-24 02:07:40 +664,Lelia,Kimmerling,462-373-6886,Female,2,22,47,2018-07-16 09:28:30,2018-01-31 12:00:37,2018-05-14 00:22:05,2018-04-02 06:04:19 +665,Kaleena,Ferrier,462-635-6827,Female,2,74,81,2018-06-05 11:09:52,2018-02-12 09:02:48,2018-09-11 19:00:25,2018-02-20 13:36:01 +666,Davon,Kroch,646-511-8893,Male,2,79,55,2018-08-11 12:22:33,2018-03-09 12:30:22,2018-10-04 12:31:33,2018-08-30 17:50:16 +667,Agathe,Kingwell,879-547-0641,Female,7,16,34,2018-06-12 18:22:16,2018-08-05 00:55:58,2018-12-27 12:31:25,2018-02-19 01:39:48 +668,Tami,Brum,925-535-6949,Female,6,13,16,2018-08-10 21:16:02,2018-07-10 10:42:55,2018-10-03 09:45:52,2018-09-02 08:04:13 +669,Meghan,Behan,666-973-3081,Female,2,37,72,2018-07-01 22:33:57,2018-12-23 00:46:46,2018-11-15 22:39:02,2018-02-15 12:20:24 +670,Elliott,Gumbley,891-324-8441,Male,3,100,20,2018-05-26 06:24:39,2018-08-24 00:11:20,2018-10-25 08:36:44,2018-03-14 08:39:54 +671,Roosevelt,Headan,845-354-1730,Male,5,3,90,2018-07-01 14:50:49,2018-09-15 12:12:40,2018-12-24 01:35:47,2018-09-20 01:17:08 +672,Judie,Cozins,719-163-5308,Female,6,64,26,2018-02-13 12:22:03,2018-11-17 08:43:37,2018-04-01 06:23:24,2018-09-21 04:32:48 +673,Zebulen,Bulger,201-223-1332,Male,5,98,53,2018-07-16 23:18:20,2018-05-29 12:17:27,2018-04-28 14:52:50,2018-06-12 16:22:23 +674,Lea,Fairpo,372-782-5016,Female,6,19,3,2018-09-03 14:58:22,2018-07-08 18:29:06,2018-05-16 18:23:32,2018-12-29 08:04:07 +675,Mayer,Demead,393-580-8088,Male,4,41,38,2018-09-26 07:35:23,2018-04-11 15:45:52,2018-03-27 15:23:59,2018-06-06 14:21:04 +676,Ana,Cannaway,492-510-5265,Female,7,61,68,2018-02-10 08:21:49,2019-01-17 12:57:29,2018-03-10 19:54:59,2018-05-05 03:55:19 +677,Cathrine,Featonby,618-545-3336,Female,2,13,20,2018-04-06 05:43:01,2018-08-08 21:16:04,2018-09-14 02:33:02,2018-02-21 21:27:00 +678,Wilt,Pitcher,482-827-8133,Male,3,100,4,2018-07-28 21:19:49,2018-05-26 09:01:20,2018-08-20 04:38:04,2018-12-20 10:33:58 +679,Mirabelle,Beric,266-468-3958,Female,5,22,72,2018-05-02 12:06:49,2018-04-08 13:34:02,2018-05-08 04:55:38,2018-04-08 07:43:46 +680,Kitti,Duell,600-603-0212,Female,6,63,11,2018-06-03 10:32:14,2018-02-28 16:15:11,2018-07-14 16:05:36,2018-12-09 20:55:23 +681,Pebrook,Tunuy,901-401-5075,Male,7,43,54,2018-05-03 21:20:23,2018-08-22 11:35:56,2019-01-16 05:29:13,2018-06-03 07:29:48 +682,Maryanna,Eayrs,722-426-6216,Female,1,44,84,2018-09-20 04:29:10,2018-03-25 00:25:02,2018-08-24 07:28:58,2019-01-03 12:51:01 +683,Obadias,Izzatt,379-850-7154,Male,6,6,27,2018-04-26 21:45:09,2018-02-05 01:27:51,2018-12-26 01:14:44,2018-08-29 23:20:18 +684,Cherye,Androletti,524-563-8173,Female,3,68,10,2018-04-21 19:56:00,2018-09-14 22:29:43,2018-12-29 20:14:49,2018-11-16 03:21:36 +685,Joachim,Dimitrescu,795-788-5797,Male,5,76,2,2018-12-11 21:33:57,2018-12-23 19:18:05,2018-11-25 10:00:13,2018-03-10 21:29:53 +686,Wynne,Heyward,438-352-0453,Female,2,24,17,2018-08-16 11:16:51,2018-07-01 06:49:35,2018-10-07 18:27:47,2018-12-09 16:04:47 +687,Renell,Ipwell,436-940-9778,Female,2,20,24,2018-11-20 12:06:05,2018-07-02 02:09:18,2018-09-08 02:49:34,2018-02-07 07:39:15 +688,Ricky,Alderson,299-400-6861,Male,6,41,97,2018-11-21 08:08:46,2018-08-15 09:54:31,2018-12-12 09:05:40,2018-11-13 16:44:40 +689,Rubi,Gail,300-475-1452,Female,4,37,26,2019-01-06 23:27:48,2018-11-12 10:44:21,2018-12-06 15:12:08,2018-03-19 12:15:14 +690,Sherill,Tallent,643-731-0806,Female,5,51,98,2018-10-30 15:13:26,2018-06-09 19:32:29,2018-02-06 16:40:35,2018-09-26 13:31:25 +691,Elia,Hairon,537-738-0445,Male,4,59,64,2018-06-18 11:14:46,2018-08-12 09:09:40,2018-03-22 09:13:44,2018-10-25 02:49:49 +692,Johny,Degoe,380-482-6021,Male,2,89,51,2018-12-18 10:28:50,2018-10-04 06:40:46,2018-05-17 13:11:00,2019-01-18 01:02:48 +693,Kirstin,Hopfer,520-920-5762,Female,7,7,29,2018-03-03 02:44:21,2018-07-08 01:31:26,2018-08-12 04:22:03,2018-10-07 12:47:55 +694,Addie,Hrycek,411-674-4016,Female,1,62,3,2018-08-02 04:43:18,2018-09-19 05:54:13,2018-09-30 17:33:04,2018-10-24 16:39:15 +695,Devinne,Dilrew,876-178-5135,Female,6,97,69,2018-01-22 00:39:19,2018-05-29 02:38:21,2018-10-17 03:17:47,2018-07-28 12:51:30 +696,Violet,Petren,352-136-0037,Female,3,20,80,2018-09-23 03:09:33,2018-05-22 01:24:08,2019-01-06 00:46:41,2018-04-13 04:27:36 +697,Inga,Cahalan,847-549-2394,Female,3,98,26,2018-03-24 12:37:49,2018-10-09 07:41:56,2019-01-07 22:18:43,2018-01-28 07:44:56 +698,Burg,Liepina,736-158-9051,Male,4,89,88,2018-02-04 05:58:15,2018-02-24 08:51:40,2018-12-01 18:20:15,2018-02-20 12:27:18 +699,Winnifred,Yakutin,165-178-2008,Female,1,74,93,2018-12-14 06:11:18,2018-12-23 02:09:43,2018-04-07 06:12:17,2018-08-16 08:12:28 +700,Boone,Walsom,432-415-6784,Male,3,91,63,2018-06-12 09:05:08,2018-09-21 04:24:21,2018-09-18 05:27:12,2018-09-10 10:46:37 +701,Alberto,Steadman,316-988-9996,Male,7,11,32,2019-01-13 23:25:22,2018-04-27 23:46:24,2018-12-07 20:28:14,2018-02-03 17:46:13 +702,Babbie,Ossulton,151-959-6676,Female,5,50,26,2018-08-25 20:54:00,2018-05-14 14:24:06,2019-01-14 14:14:51,2018-08-15 11:39:35 +703,Franni,Sparwell,411-855-1156,Female,6,95,65,2018-07-21 15:32:34,2018-07-03 10:42:20,2018-08-26 02:44:03,2018-04-13 05:52:48 +704,Carlos,MacNair,911-726-0315,Male,1,17,35,2018-12-05 14:25:42,2018-12-12 19:39:25,2018-04-29 02:34:46,2018-10-22 16:34:03 +705,Violetta,Crosbie,334-280-9073,Female,3,9,44,2018-01-30 22:36:27,2018-08-07 22:12:15,2018-11-27 09:47:02,2018-07-24 14:22:36 +706,Malanie,Perico,380-744-7181,Female,6,68,23,2019-01-03 09:08:46,2018-08-26 01:51:30,2018-12-02 23:44:58,2018-02-16 00:13:42 +707,Ivor,Bowcher,940-535-1313,Male,2,79,20,2018-09-05 08:48:25,2018-05-21 21:40:04,2018-05-02 19:33:24,2018-06-22 07:46:47 +708,Hyacinth,Trump,241-552-4852,Female,4,46,7,2018-02-27 17:57:22,2018-11-20 03:54:39,2018-10-27 00:44:50,2018-09-19 14:04:29 +709,Vittorio,Blincko,136-124-8825,Male,5,70,20,2018-12-17 01:45:05,2018-06-06 18:10:29,2018-12-01 18:11:21,2018-04-14 00:43:46 +710,Tadeas,Glendenning,676-274-2212,Male,3,70,6,2018-08-22 07:42:12,2018-07-12 17:41:15,2018-07-24 17:42:26,2018-12-27 05:34:05 +711,Sky,Flew,681-787-4952,Male,3,81,48,2018-11-13 09:16:39,2018-09-14 09:34:51,2018-09-23 01:44:43,2018-11-21 00:50:58 +712,Luise,Olivetti,707-121-6217,Female,4,68,4,2018-03-29 01:36:21,2018-05-06 13:38:59,2018-05-06 09:55:05,2018-02-04 21:27:46 +713,Drusy,Capinetti,432-896-1449,Female,5,94,80,2018-07-31 20:38:50,2018-11-28 22:41:39,2018-04-27 00:57:40,2018-08-30 16:16:05 +714,Miranda,Rissen,700-512-2672,Female,7,29,40,2018-03-15 22:30:44,2018-02-01 02:59:19,2018-11-25 08:02:09,2018-11-05 07:51:59 +715,Ario,Bashford,390-128-4254,Male,2,54,93,2018-06-14 08:22:43,2018-08-12 18:13:42,2018-11-28 21:40:32,2018-12-29 03:09:26 +716,Rochella,Shackesby,103-592-3468,Female,7,41,14,2018-02-12 09:44:28,2018-08-22 10:35:46,2019-01-09 02:25:18,2018-10-10 17:50:44 +717,Wes,Christofides,192-457-7659,Male,1,69,89,2018-05-29 07:31:48,2019-01-06 03:40:33,2018-02-04 22:20:47,2019-01-05 16:01:23 +718,Griselda,Lukes,232-886-4996,Female,2,96,24,2019-01-10 12:54:29,2019-01-16 20:13:57,2018-04-26 08:07:43,2018-10-11 15:19:29 +719,Dredi,Cooksey,432-670-0783,Female,2,24,32,2018-02-28 00:00:07,2018-06-20 03:18:14,2018-07-21 09:03:11,2018-07-06 03:35:06 +720,Coleman,Trudgian,273-535-1414,Male,4,97,47,2018-04-25 23:41:09,2018-03-11 00:03:13,2018-06-03 13:44:14,2018-08-08 09:07:58 +721,Averill,Shilstone,947-108-0865,Male,7,1,64,2018-08-18 22:21:07,2018-04-12 03:24:47,2018-03-10 08:58:27,2018-08-03 14:04:03 +722,Carmen,Syder,954-822-0919,Female,2,47,75,2018-10-09 09:52:34,2018-11-21 01:16:40,2018-02-12 03:27:35,2018-08-12 12:44:55 +723,Morgan,Leband,547-933-1630,Female,5,39,97,2018-03-25 07:19:57,2018-03-28 20:22:12,2018-09-05 13:29:46,2018-10-12 09:04:17 +724,Milzie,Fearnley,589-230-2628,Female,1,44,13,2018-05-17 23:12:31,2018-07-29 21:43:28,2018-07-06 23:27:59,2018-09-14 01:45:16 +725,Deb,Marjot,495-276-5931,Female,2,27,81,2018-09-28 15:27:35,2018-02-05 23:31:12,2018-07-29 04:18:34,2018-03-08 09:45:23 +726,Shayne,Artinstall,628-997-5039,Male,2,23,20,2018-11-19 12:44:15,2018-05-30 23:05:12,2018-11-23 10:18:23,2018-06-08 14:18:23 +727,Annabal,Standbridge,226-314-1568,Female,5,16,5,2018-08-11 00:40:31,2018-12-20 14:06:36,2018-04-15 04:33:53,2018-11-09 16:42:45 +728,Sheffield,Crielly,360-797-0933,Male,7,57,90,2018-03-08 03:32:17,2018-11-07 06:12:46,2019-01-12 22:10:52,2019-01-02 03:16:09 +729,Antonius,Delagua,336-343-1380,Male,2,64,60,2018-10-14 22:56:26,2018-11-13 00:50:03,2018-07-02 11:23:06,2018-08-09 09:29:32 +730,Brana,Cannell,157-563-3935,Female,2,74,73,2019-01-19 15:41:16,2018-04-20 09:34:06,2018-08-02 12:28:32,2018-02-21 06:29:31 +731,Bartram,Praundlin,631-372-3479,Male,2,35,7,2018-10-03 02:00:10,2018-07-31 21:29:22,2019-01-10 21:43:54,2018-08-28 13:29:28 +732,Anthiathia,Goodwins,664-616-3575,Female,7,76,19,2018-04-26 19:57:15,2018-10-28 17:07:05,2018-02-21 16:38:28,2018-04-18 17:58:31 +733,Deborah,Ekell,577-861-9112,Female,5,74,43,2018-10-19 06:10:04,2018-03-12 03:47:48,2018-05-17 13:04:37,2018-02-09 05:48:05 +734,Lauri,Arunowicz,862-427-5257,Female,4,58,81,2018-07-29 04:16:13,2018-04-23 19:30:17,2018-03-19 21:30:18,2018-11-18 20:46:33 +735,Fowler,Markus,496-831-3082,Male,7,18,52,2018-01-26 22:36:43,2019-01-14 00:15:25,2018-03-18 05:45:56,2018-02-27 16:55:19 +736,Klara,Ramme,103-225-9086,Female,7,28,67,2018-05-21 17:32:08,2018-10-05 08:11:16,2018-06-25 15:05:21,2018-03-13 14:44:42 +737,Melisenda,Chitham,158-699-0591,Female,2,49,88,2018-04-16 02:24:00,2018-10-27 14:52:15,2018-12-31 05:39:31,2018-12-09 09:15:25 +738,Hale,Layborn,106-961-8551,Male,3,66,90,2018-04-22 19:39:27,2018-08-12 19:37:50,2018-08-17 10:37:06,2018-09-14 15:17:48 +739,Ferdie,Stubbeley,686-279-8217,Male,7,62,96,2018-09-25 03:29:05,2018-06-27 23:31:12,2018-07-21 18:49:24,2018-06-19 05:08:00 +740,Licha,O' Kelleher,463-395-9023,Female,6,75,16,2018-07-05 08:29:21,2018-09-13 21:32:41,2018-08-26 17:50:16,2018-05-22 11:30:48 +741,Gualterio,Kernar,123-900-7702,Male,2,32,18,2018-12-30 04:11:35,2018-04-15 10:32:33,2018-06-21 01:01:16,2018-11-15 03:34:48 +742,Harley,Lyokhin,664-282-7716,Male,1,42,45,2018-07-26 12:07:21,2018-02-09 02:23:37,2018-05-10 13:39:44,2018-11-25 04:15:16 +743,Kylila,Hukin,726-438-0889,Female,2,2,74,2019-01-02 09:08:44,2018-04-07 07:18:19,2018-04-19 16:12:40,2018-03-03 19:00:47 +744,Natividad,Dahlbom,744-480-5437,Female,5,82,39,2018-12-30 01:10:05,2018-08-01 07:16:39,2018-05-29 02:44:28,2018-11-08 15:02:54 +745,Virgina,Couzens,947-544-5389,Female,6,14,38,2018-11-19 23:03:21,2018-11-21 13:32:21,2018-03-29 02:30:25,2018-12-31 17:15:49 +746,Peyter,Diano,292-294-3875,Male,2,23,76,2018-12-22 18:12:13,2018-09-23 11:29:07,2018-07-12 06:09:06,2018-07-28 01:53:40 +747,Jayme,O'Curneen,225-447-3103,Male,3,10,84,2018-06-20 10:29:48,2018-08-12 10:14:12,2018-04-28 06:15:40,2018-07-19 08:52:24 +748,Frederik,Wilkisson,963-312-1892,Male,3,4,18,2018-09-11 01:05:52,2018-05-17 07:03:54,2018-09-07 08:19:47,2018-12-27 05:51:37 +749,Yankee,Harrower,918-854-5590,Male,7,14,88,2019-01-12 12:01:21,2018-08-24 08:15:58,2018-06-19 00:06:07,2018-06-19 07:16:40 +750,Tamas,MacRinn,856-289-3684,Male,6,83,91,2018-05-18 15:58:10,2018-06-09 14:45:50,2018-06-16 17:21:20,2018-12-18 02:23:35 +751,Valentin,Rawlings,663-758-9646,Male,4,16,34,2018-06-27 02:03:36,2018-12-10 04:32:16,2018-07-07 05:22:18,2018-02-03 06:54:36 +752,Colver,Yarr,382-717-8711,Male,5,23,10,2018-05-13 09:06:22,2018-04-06 13:41:41,2018-05-07 22:03:59,2018-11-12 22:30:08 +753,Alisa,Gaynesford,417-789-3077,Female,2,87,12,2018-07-16 18:03:56,2018-02-06 07:27:34,2018-07-12 08:51:47,2018-02-22 19:25:29 +754,Xavier,Cornwell,777-401-4183,Male,7,12,13,2018-12-03 01:19:40,2018-05-30 23:16:32,2018-10-01 21:33:13,2018-04-13 23:28:08 +755,Hy,Raftery,563-495-4017,Male,7,54,93,2018-03-25 23:10:24,2018-11-20 07:01:06,2018-03-27 13:09:16,2018-08-03 19:07:10 +756,Holt,Rosenfeld,962-871-1674,Male,2,43,35,2018-08-07 04:15:12,2018-05-21 13:42:27,2018-11-13 19:28:52,2018-03-27 10:14:19 +757,Zola,Andreopolos,543-481-8409,Female,4,31,62,2018-02-08 17:26:50,2018-12-12 15:18:24,2018-02-22 22:58:13,2019-01-02 05:55:39 +758,Letty,Scotting,546-656-5808,Female,5,15,94,2018-10-21 18:22:43,2018-05-26 22:09:39,2018-08-04 15:48:15,2018-08-28 06:14:32 +759,Celina,Lauchlan,202-835-6732,Female,7,47,9,2018-02-26 21:58:16,2019-01-10 01:22:46,2018-11-03 06:10:35,2018-04-21 11:00:49 +760,Drusy,Izakov,129-552-5886,Female,1,45,2,2018-10-11 13:12:08,2018-06-26 11:16:28,2018-08-24 23:58:00,2018-09-09 05:46:23 +761,Shana,Ference,915-610-3990,Female,3,1,7,2018-10-31 18:47:12,2018-09-13 14:33:49,2018-10-02 08:57:46,2018-02-18 19:30:28 +762,Colin,Broy,868-631-8529,Male,2,22,32,2018-05-23 19:06:02,2018-09-08 07:49:35,2018-12-13 21:44:07,2018-06-25 07:15:53 +763,Farlay,Cromett,640-335-8081,Male,7,34,25,2018-06-29 00:34:53,2018-12-08 12:49:01,2018-12-03 13:22:54,2018-06-24 16:33:04 +764,Leandra,Hamberstone,786-332-2588,Female,2,37,90,2018-12-22 15:35:04,2018-02-04 16:23:41,2018-01-28 07:51:51,2018-06-01 00:25:34 +765,Gan,McCahey,450-198-7472,Male,2,79,7,2018-06-26 07:22:06,2018-09-27 09:42:20,2018-03-13 20:28:52,2018-02-10 02:05:39 +766,Brose,Gane,302-470-1094,Male,7,27,25,2018-11-05 10:16:11,2018-12-27 12:00:35,2018-12-13 06:00:05,2018-08-30 01:03:46 +767,Mabel,Nurdin,417-183-7374,Female,1,73,62,2018-12-09 01:11:47,2018-06-09 12:03:13,2018-11-30 04:52:49,2018-04-24 11:08:53 +768,Melinda,Belliard,277-126-4396,Female,6,39,83,2018-07-13 11:17:51,2018-08-04 10:46:43,2018-11-19 23:27:57,2018-02-19 10:08:24 +769,Percy,Yakolev,433-703-6347,Male,4,78,23,2018-11-02 23:32:50,2018-12-19 16:21:10,2018-02-17 21:43:15,2018-12-09 00:57:58 +770,Portia,Legonidec,761-180-7070,Female,6,27,1,2018-11-01 18:06:54,2018-05-16 10:56:05,2018-08-06 20:45:16,2018-08-14 23:11:03 +771,Harry,Lapley,950-309-5667,Male,5,8,58,2018-03-01 15:09:46,2018-05-13 05:24:49,2018-03-22 16:01:05,2018-08-18 02:05:37 +772,Cort,Gathwaite,964-902-3053,Male,5,33,89,2018-08-18 20:12:14,2018-01-27 16:39:37,2018-12-26 22:46:04,2018-02-16 22:31:58 +773,Moselle,Davidsson,813-238-6494,Female,4,13,60,2019-01-10 17:47:31,2018-11-04 08:31:17,2018-04-30 12:09:52,2018-04-14 19:47:23 +774,Avril,Britton,340-286-1678,Female,3,4,16,2018-03-18 00:19:38,2018-12-29 06:21:49,2019-01-03 02:03:40,2018-11-29 12:05:59 +775,Linn,Confait,176-807-2635,Female,6,18,70,2018-09-18 15:11:21,2018-05-02 18:32:49,2018-03-25 13:46:21,2018-10-06 04:29:26 +776,Joletta,Fyldes,547-358-7132,Female,3,92,6,2019-01-07 18:53:22,2018-09-07 21:09:08,2018-10-22 08:38:19,2018-07-08 07:01:37 +777,Alvira,Donnersberg,712-756-5926,Female,1,20,77,2018-06-09 12:41:30,2018-12-29 01:15:22,2018-02-11 19:44:50,2018-02-21 21:33:12 +778,Kirbee,Sherer,434-167-9643,Female,4,84,40,2018-10-18 16:54:05,2018-04-02 11:16:17,2018-02-26 17:45:53,2018-10-21 05:24:45 +779,Griffy,Guitton,326-132-8573,Male,4,60,19,2018-06-22 17:59:44,2018-09-11 16:22:32,2018-11-10 19:43:30,2018-02-06 10:06:41 +780,Emmott,Allitt,969-852-2661,Male,2,48,37,2018-04-24 21:17:55,2018-11-01 06:07:42,2018-07-30 22:56:18,2018-11-13 22:12:50 +781,Tailor,Dalman,521-811-9925,Male,5,60,72,2018-12-14 09:37:55,2018-12-26 17:43:11,2018-12-10 03:38:52,2018-04-07 11:21:07 +782,Brennen,Vasilechko,176-109-0551,Male,6,90,55,2018-08-31 12:29:00,2018-05-23 03:06:41,2018-10-10 17:44:50,2018-10-21 00:47:28 +783,Dotty,MacCallam,161-881-1371,Female,1,56,3,2018-03-01 02:18:19,2019-01-06 18:00:59,2018-04-28 10:26:11,2018-02-05 06:43:37 +784,Jedidiah,Guerin,645-152-7671,Male,5,56,83,2018-04-02 15:07:20,2018-08-24 12:42:12,2018-12-21 09:17:44,2018-10-06 00:19:03 +785,Hannie,Danes,716-637-6821,Female,5,40,18,2019-01-08 07:08:18,2019-01-05 20:40:19,2019-01-16 12:16:28,2018-03-23 12:28:41 +786,Galen,Scogin,453-714-4492,Male,6,38,18,2018-10-27 06:54:20,2018-06-19 09:26:07,2019-01-10 20:55:20,2018-10-18 17:04:44 +787,Aleta,Melonby,207-524-3356,Female,3,98,3,2018-04-04 12:13:59,2018-06-06 11:50:34,2018-05-05 17:38:56,2018-03-11 12:56:42 +788,Adlai,Mauchlen,601-977-7616,Male,7,88,64,2018-03-24 04:33:36,2018-03-07 16:46:25,2018-03-16 19:25:21,2018-07-20 14:23:29 +789,Amelie,Le Barre,576-950-1963,Female,5,28,53,2018-08-10 15:52:25,2018-05-07 07:19:32,2018-12-21 21:24:49,2018-07-21 01:11:54 +790,Rodrique,Lestor,723-918-4771,Male,4,26,72,2018-08-29 10:37:42,2018-11-16 09:49:01,2018-08-31 05:08:59,2018-12-18 10:17:32 +791,Gifford,Challoner,411-352-9364,Male,5,63,18,2018-10-16 12:33:24,2018-11-24 23:28:34,2018-05-29 22:33:36,2018-11-06 07:45:09 +792,Dorene,Pogosian,391-363-6103,Female,4,74,78,2018-04-26 20:52:42,2018-08-02 21:57:23,2018-04-29 21:18:02,2018-02-13 20:06:09 +793,Lynnell,De Filippi,418-713-4087,Female,7,78,47,2018-12-03 11:11:47,2019-01-05 12:23:37,2018-05-05 19:10:42,2018-04-22 16:11:38 +794,Tod,Willicott,354-257-4541,Male,5,34,18,2018-07-19 20:11:25,2018-08-12 01:02:55,2018-08-05 23:52:34,2018-02-15 00:20:31 +795,Myrlene,Wornham,331-165-6672,Female,7,51,75,2018-11-24 15:52:43,2018-07-01 06:12:47,2018-08-08 19:45:02,2018-11-19 14:51:56 +796,Sibyl,Burnsyde,981-826-0517,Female,2,24,2,2018-11-01 05:15:20,2018-10-15 22:30:33,2018-05-27 21:38:42,2018-05-08 15:34:52 +797,Barron,Hanrott,700-573-3103,Male,6,81,99,2018-08-12 21:14:38,2018-03-09 17:36:14,2018-06-03 16:23:47,2018-10-13 22:34:58 +798,Marylee,Hunnawill,501-536-2494,Female,7,30,33,2018-10-19 01:54:52,2018-04-12 03:02:28,2018-09-12 02:31:37,2018-06-14 10:58:08 +799,Chip,Hunnaball,249-377-3740,Male,3,98,59,2018-04-25 10:02:32,2019-01-18 16:00:40,2018-02-14 02:06:39,2018-06-17 23:32:24 +800,Major,Milsap,444-230-6774,Male,7,20,23,2018-03-11 15:00:30,2018-01-24 21:48:22,2018-12-27 13:31:21,2018-08-10 23:29:32 +801,Ashli,Romain,886-453-6140,Female,6,12,19,2018-02-24 23:38:53,2018-05-01 04:29:06,2018-06-03 17:41:53,2018-04-21 00:29:25 +802,Keeley,Frankom,894-599-8867,Female,3,30,4,2019-01-05 18:11:47,2018-03-25 21:31:27,2018-05-26 03:52:58,2018-10-23 16:17:28 +803,Curcio,Widmoor,934-987-4248,Male,5,23,84,2018-03-31 07:42:11,2018-10-25 03:00:08,2018-10-18 23:14:42,2018-05-07 19:58:59 +804,Crawford,Ballston,771-623-5016,Male,5,24,48,2018-12-27 07:13:13,2019-01-09 10:21:22,2018-05-20 08:49:26,2018-09-16 08:46:49 +805,Templeton,Snibson,650-275-2922,Male,3,55,83,2018-12-04 05:22:30,2018-09-29 21:23:56,2018-03-08 17:58:24,2018-08-15 02:38:52 +806,Gail,Peachment,906-123-1774,Male,4,59,13,2018-09-21 07:44:03,2018-08-02 22:34:51,2018-03-08 07:11:39,2018-08-25 15:39:59 +807,Adriano,Escale,888-817-1180,Male,3,92,78,2018-07-24 16:32:20,2018-02-22 12:50:50,2018-06-26 12:34:44,2018-06-06 08:04:35 +808,Trista,Tudgay,340-171-5505,Female,5,44,62,2018-09-04 12:09:41,2018-01-31 01:51:09,2018-09-13 08:38:11,2018-06-06 05:49:50 +809,Angie,Carradice,507-239-1908,Female,1,12,69,2018-08-13 18:36:13,2018-11-23 03:57:42,2018-06-17 07:44:13,2018-12-09 16:37:23 +810,Maureen,Perllman,116-299-8383,Female,1,91,1,2018-04-10 06:12:02,2018-08-02 04:31:50,2018-06-18 00:58:20,2018-10-12 02:31:31 +811,Renaud,Roylance,267-492-3743,Male,3,36,85,2018-02-05 00:59:50,2018-11-26 02:06:43,2018-11-16 00:25:18,2018-02-02 08:38:37 +812,Dasi,Rhucroft,505-753-6245,Female,4,96,84,2018-11-10 18:36:26,2018-07-17 05:54:10,2018-07-12 13:34:58,2018-11-10 01:57:49 +813,Arlee,Gerdts,220-186-9711,Female,6,76,30,2018-12-26 11:24:38,2018-11-21 22:09:49,2018-04-16 14:09:09,2018-05-27 06:24:32 +814,Darrel,Maseres,540-324-4576,Male,6,20,52,2018-01-25 13:38:00,2019-01-11 23:26:49,2018-07-10 03:23:20,2018-06-27 20:41:34 +815,Merle,Haggie,867-109-5010,Male,5,96,73,2018-05-11 09:41:28,2018-02-26 23:39:01,2019-01-18 06:20:26,2018-11-24 20:35:34 +816,Jordanna,Slocket,561-552-2274,Female,3,64,28,2018-06-05 00:07:31,2018-10-24 18:30:56,2018-04-11 09:26:10,2018-07-17 15:09:53 +817,Rosa,Naulty,104-742-5724,Female,1,49,36,2018-07-25 05:49:28,2018-12-11 01:12:50,2018-04-02 22:12:09,2019-01-03 01:54:51 +818,Abbott,Nenci,465-121-4813,Male,3,79,57,2018-11-14 21:12:41,2018-03-22 04:16:18,2018-08-26 18:31:33,2018-05-16 10:32:25 +819,Edsel,Brockley,602-592-8501,Male,1,30,96,2018-01-21 00:58:41,2018-12-18 18:52:15,2018-03-18 23:16:05,2018-11-22 00:32:00 +820,Rickie,Tace,237-311-6775,Female,4,14,43,2018-07-28 16:49:11,2018-12-14 07:30:09,2018-02-18 22:51:29,2018-06-05 16:20:34 +821,Shaun,Stagg,356-435-7464,Female,7,54,35,2018-09-08 08:01:19,2018-03-09 16:11:16,2019-01-16 17:00:44,2018-11-30 14:34:15 +822,Alfred,Durden,512-204-4387,Male,2,79,46,2018-12-31 13:42:16,2018-05-24 21:54:26,2018-07-10 23:33:53,2018-08-10 04:33:54 +823,Christoffer,Bolderstone,868-441-3575,Male,6,4,30,2018-11-03 00:46:09,2018-04-30 04:41:20,2018-07-26 23:17:02,2018-04-27 19:17:50 +824,Ellette,Robard,806-623-1247,Female,2,59,70,2018-01-31 22:31:04,2018-01-28 04:26:39,2018-06-10 10:50:30,2018-11-01 17:27:42 +825,Loren,Mitrovic,840-960-0930,Male,7,27,31,2018-11-09 15:53:11,2018-03-25 02:53:57,2018-12-15 15:59:47,2018-06-20 19:00:48 +826,Leigh,Beebee,483-570-2017,Male,5,56,99,2018-03-27 09:56:26,2018-09-05 03:40:42,2018-12-13 03:28:25,2018-11-23 13:45:15 +827,Debby,Beldham,686-330-6591,Female,5,65,17,2018-08-01 18:59:48,2018-03-24 14:20:35,2019-01-10 21:11:42,2018-12-19 08:48:47 +828,Barron,Lowell,115-742-2050,Male,5,85,65,2018-03-03 04:32:02,2018-04-24 11:36:33,2018-09-15 15:08:52,2018-06-25 22:46:54 +829,Randi,Skydall,223-820-2793,Male,2,86,47,2018-07-20 00:15:51,2018-06-26 06:23:43,2018-12-28 12:30:07,2018-08-25 21:27:50 +830,Isabel,Roggerone,927-569-8210,Female,4,85,41,2018-09-23 13:54:09,2018-03-09 05:31:36,2018-06-11 18:42:42,2018-04-13 18:03:27 +831,Alvan,Geake,401-432-6471,Male,5,71,66,2018-03-29 20:49:43,2018-04-25 14:10:14,2018-07-24 01:39:45,2018-12-24 09:39:46 +832,Sophey,Jeandel,338-361-7635,Female,6,60,18,2018-08-05 04:29:15,2018-09-21 05:26:30,2018-06-08 07:30:41,2018-12-27 19:45:07 +833,Howie,Maxsted,197-553-3905,Male,5,94,69,2018-08-25 23:10:38,2019-01-20 02:12:00,2019-01-15 20:11:44,2018-02-13 17:46:32 +834,Padraig,Torr,529-469-0039,Male,1,62,17,2018-03-14 04:21:56,2018-06-08 14:24:59,2018-10-08 09:31:56,2018-08-30 02:59:15 +835,Shirl,Jeratt,713-937-2841,Female,2,18,89,2018-09-25 03:56:45,2018-07-17 02:54:21,2019-01-08 21:13:42,2018-02-20 17:16:17 +836,Durward,Kermott,625-654-9223,Male,6,67,25,2018-02-14 15:04:10,2018-03-23 06:42:12,2018-09-16 13:56:48,2018-03-10 11:02:08 +837,Rici,Francie,992-830-9527,Female,5,75,22,2018-07-21 07:35:59,2018-01-24 21:24:42,2018-12-20 10:46:19,2018-04-27 01:28:33 +838,Vivian,Suddell,715-471-1918,Female,6,81,45,2018-07-29 02:06:46,2018-10-15 14:05:00,2018-06-12 17:01:30,2018-05-12 22:22:36 +839,Eugenia,Tudhope,527-791-1359,Female,2,95,25,2019-01-05 12:54:58,2018-12-12 20:07:15,2018-12-22 12:11:13,2018-12-25 06:49:43 +840,Hamnet,Gateman,792-883-5589,Male,1,84,45,2018-06-26 04:15:53,2018-02-21 14:45:49,2018-08-29 18:01:14,2019-01-15 09:03:43 +841,Laraine,Emma,256-645-5057,Female,3,88,52,2018-05-29 03:26:20,2018-03-10 02:05:24,2018-05-12 21:29:38,2018-12-10 02:39:56 +842,Harley,D'Ruel,359-498-9270,Male,4,16,57,2018-02-15 07:39:22,2018-08-24 22:23:10,2018-07-19 02:07:06,2018-02-13 01:45:52 +843,Theda,Eades,222-998-5683,Female,7,2,71,2018-03-06 07:09:18,2018-09-14 11:46:16,2018-11-23 01:07:59,2018-12-02 03:37:22 +844,Giselbert,Klimentyev,165-127-0115,Male,6,88,93,2018-11-13 03:56:59,2018-04-09 02:33:25,2018-07-04 00:34:57,2018-06-04 05:56:23 +845,Lynnet,Tidd,370-452-0577,Female,6,47,3,2018-08-25 20:45:24,2018-08-27 16:50:01,2018-08-22 21:33:48,2018-06-27 22:32:52 +846,Donetta,Giannassi,913-466-0403,Female,2,39,55,2018-02-26 16:34:20,2018-07-10 03:35:10,2018-09-29 14:23:34,2018-10-10 13:02:02 +847,Conrade,Ruddell,514-722-6544,Male,3,13,100,2018-05-31 18:14:29,2018-10-19 05:51:32,2018-11-22 09:45:08,2018-02-22 05:00:31 +848,Tynan,Ritchie,552-416-9192,Male,4,50,26,2018-02-13 01:36:31,2018-07-24 03:28:00,2018-02-22 16:37:36,2018-02-28 07:16:54 +849,Erv,Huggins,528-946-8385,Male,3,73,82,2018-03-23 14:37:41,2018-08-12 12:26:08,2018-02-09 16:56:21,2018-08-09 06:33:34 +850,Darby,Ambrogini,266-338-3612,Male,6,92,21,2018-04-27 07:57:01,2018-10-19 20:49:49,2018-02-10 16:39:59,2018-09-03 00:53:41 +851,Devondra,Boc,775-193-7341,Female,5,36,51,2018-10-18 04:36:21,2018-10-28 14:06:15,2018-03-25 15:47:47,2018-08-20 22:31:48 +852,Meggy,Paxforde,435-917-5199,Female,2,40,85,2018-08-27 05:39:35,2018-01-23 20:18:58,2018-02-01 16:43:58,2018-08-07 12:15:36 +853,Pattie,Macallam,901-370-6579,Female,1,4,32,2018-07-11 10:30:06,2018-10-01 12:33:55,2018-02-08 02:35:59,2018-11-30 18:29:14 +854,Ray,Thayre,822-459-4971,Male,7,13,79,2018-07-13 03:44:05,2018-07-07 04:47:58,2018-08-28 19:24:34,2018-08-13 10:49:03 +855,Sindee,Gong,919-731-7167,Female,6,23,3,2018-12-08 15:31:48,2018-04-27 17:10:40,2018-07-14 14:10:46,2018-09-23 22:25:52 +856,Giovanni,Elsie,739-171-4273,Male,3,100,20,2018-11-22 21:14:50,2018-09-29 00:12:07,2018-05-17 09:43:48,2018-04-05 15:26:17 +857,Hadley,Davidde,813-908-2619,Male,7,64,65,2018-01-31 19:26:32,2018-11-10 09:08:19,2018-06-20 20:16:01,2018-04-18 19:33:00 +858,Jud,Schleicher,248-874-9513,Male,1,24,8,2018-04-06 16:54:03,2018-12-08 11:46:05,2018-10-02 20:22:44,2018-04-27 09:04:18 +859,Berget,Rasmus,599-370-5265,Female,2,46,8,2018-11-11 16:46:30,2018-11-24 16:42:40,2019-01-05 12:53:51,2018-12-17 18:41:54 +860,Floris,Lelliott,495-754-4852,Female,1,35,72,2019-01-06 22:27:28,2018-06-14 07:45:20,2018-10-25 10:22:56,2018-07-09 00:48:19 +861,Marianna,Huge,136-171-1910,Female,1,92,73,2018-05-04 21:19:28,2018-04-08 18:45:35,2018-02-08 18:06:55,2018-07-12 04:08:00 +862,Federica,Seakings,778-573-1492,Female,5,42,100,2018-02-18 23:40:45,2018-08-29 22:07:35,2018-06-27 21:37:10,2018-06-27 18:13:29 +863,Christophorus,Tett,516-196-0657,Male,3,68,89,2018-09-28 20:37:26,2018-07-03 17:19:03,2018-04-20 09:01:09,2018-06-11 11:31:56 +864,Kathlin,Hubbart,400-384-9734,Female,5,75,62,2018-09-23 11:16:50,2018-11-22 07:00:07,2018-11-12 09:29:23,2018-03-19 17:19:13 +865,Toinette,Christophersen,222-218-6841,Female,4,81,80,2018-06-24 07:27:29,2018-03-08 17:25:42,2018-11-19 23:39:15,2018-04-02 19:04:26 +866,Mei,Dragon,891-366-6658,Female,2,14,22,2018-03-17 07:33:08,2018-06-23 20:11:56,2018-10-30 02:21:14,2018-10-21 08:13:29 +867,Wileen,Guittet,118-965-5819,Female,7,22,73,2018-04-12 00:04:07,2018-08-23 08:56:44,2018-07-09 08:29:36,2018-02-22 06:45:41 +868,Bill,Skechley,531-261-9052,Female,1,93,45,2018-03-25 13:30:53,2018-10-17 03:47:35,2018-10-18 02:26:47,2018-12-08 19:05:40 +869,Chrissy,Rapley,863-731-8995,Female,7,17,8,2018-09-12 01:35:07,2018-07-22 15:02:10,2018-06-18 19:06:47,2018-12-22 20:00:52 +870,Gwynne,Hymers,287-878-7144,Female,4,6,29,2018-08-19 13:41:56,2018-12-10 18:23:35,2018-03-26 01:25:26,2018-07-05 16:38:09 +871,Noland,Hornung,922-794-4200,Male,3,66,82,2018-12-10 23:49:55,2018-09-15 01:16:20,2018-10-24 20:37:00,2018-10-27 07:56:58 +872,Sybila,Caren,883-754-0514,Female,1,40,33,2018-11-01 03:29:07,2018-03-07 23:07:07,2018-09-06 01:46:46,2018-03-17 17:02:04 +873,Arnaldo,Ortelt,648-204-0219,Male,5,24,20,2018-04-19 00:26:30,2018-06-09 12:00:33,2018-09-30 00:21:33,2018-07-12 18:59:39 +874,Sascha,Thurner,504-586-1976,Male,4,9,34,2018-09-03 11:21:47,2018-12-06 09:23:43,2018-11-21 03:43:51,2018-05-28 10:34:36 +875,Janeva,Stallion,168-726-9745,Female,7,66,60,2018-07-05 04:40:09,2018-02-19 12:25:04,2018-05-31 06:47:34,2018-01-24 21:43:59 +876,Imelda,Daintrey,786-279-9676,Female,5,26,12,2018-07-29 01:32:45,2018-05-21 03:09:18,2018-10-03 07:09:16,2018-12-28 16:07:06 +877,Kaia,Pauleit,937-468-0457,Female,5,36,63,2018-08-20 03:23:06,2018-09-20 08:02:05,2018-05-13 23:35:38,2018-03-19 03:48:06 +878,Fons,Coton,673-868-5084,Male,6,51,39,2018-02-28 14:51:40,2018-08-02 02:13:10,2018-02-01 01:38:38,2018-09-22 00:49:46 +879,Amalee,Groneway,336-875-1596,Female,5,19,58,2018-04-12 20:12:37,2018-11-27 06:39:14,2018-09-18 01:05:22,2018-04-22 08:39:02 +880,Paquito,O'Dwyer,324-526-6202,Male,7,99,41,2018-10-12 02:35:53,2018-02-10 00:52:03,2018-02-07 03:12:35,2018-10-18 21:47:13 +881,Shea,Forst,307-995-7972,Female,1,41,41,2018-10-02 02:03:39,2018-10-24 23:10:36,2019-01-09 17:11:05,2018-05-16 22:15:02 +882,Sylvan,McKimm,999-270-7047,Male,1,21,29,2018-04-13 22:42:31,2018-12-10 08:47:39,2018-05-25 01:01:54,2018-04-17 08:03:17 +883,Peyter,Rotte,919-508-2810,Male,3,51,43,2018-05-25 10:20:40,2018-05-07 09:22:17,2018-10-29 16:34:13,2018-05-08 18:00:18 +884,Ernestine,Jankowski,998-337-8068,Female,3,7,44,2018-01-22 22:18:12,2018-11-04 08:03:53,2019-01-14 13:07:45,2018-01-25 10:53:54 +885,Bridget,Pettet,701-799-8814,Female,5,84,73,2018-04-24 13:06:17,2018-09-27 02:37:43,2018-11-23 08:52:31,2018-08-30 18:46:39 +886,Arlana,Wisniowski,321-679-5349,Female,7,1,72,2018-09-20 23:41:45,2018-07-29 00:16:49,2018-02-08 09:55:35,2018-04-07 15:34:38 +887,Darbie,Verzey,936-723-9548,Female,6,95,2,2018-09-15 23:29:11,2018-01-28 09:02:28,2018-12-05 08:05:15,2018-02-08 01:02:29 +888,Quintana,Nutley,896-674-7083,Female,3,38,16,2018-07-22 20:52:42,2018-09-19 19:39:52,2018-04-29 01:58:40,2018-07-30 22:07:46 +889,Padgett,Urwen,141-490-6319,Male,6,32,96,2018-05-09 19:03:45,2018-04-07 12:16:47,2018-07-17 13:53:15,2018-09-19 15:54:14 +890,Beret,Gilchrest,524-146-3660,Female,3,30,45,2018-12-09 18:08:35,2018-02-09 07:44:41,2019-01-09 06:31:54,2018-06-03 05:03:43 +891,Jacquette,McBlain,180-111-2719,Female,5,45,49,2018-08-25 23:50:05,2018-08-14 04:10:24,2018-06-28 01:21:56,2018-05-09 06:07:09 +892,Heriberto,Hardway,934-411-2153,Male,7,100,67,2018-08-12 07:20:08,2018-08-30 23:04:44,2018-08-09 09:18:15,2018-08-21 13:19:44 +893,Charo,Cheeney,934-194-4292,Female,2,79,49,2018-02-19 02:30:34,2018-07-26 21:32:10,2018-03-14 13:44:53,2019-01-02 19:07:53 +894,Barty,Delacour,352-181-7260,Male,7,68,1,2018-02-08 11:54:33,2018-12-22 15:26:11,2018-05-05 05:29:07,2018-01-28 16:34:01 +895,Arel,Qusklay,776-527-2939,Male,6,72,24,2018-02-10 23:05:47,2018-10-31 16:14:34,2018-04-17 06:36:20,2018-09-21 15:13:20 +896,Cleon,Westcarr,735-686-0389,Male,1,56,68,2018-12-14 09:21:13,2018-08-04 15:56:37,2018-09-09 11:38:56,2018-03-19 03:56:38 +897,Nicole,Gorrie,216-361-4858,Female,2,65,77,2018-08-05 12:50:07,2018-03-10 14:07:01,2018-02-15 13:44:04,2019-01-06 01:05:50 +898,Issiah,Patters,901-518-7348,Male,7,40,78,2018-04-27 08:43:08,2018-11-08 01:40:02,2018-02-05 13:31:35,2018-08-05 21:26:55 +899,Kimbell,Torvey,614-432-0846,Male,3,46,34,2018-10-10 17:10:59,2018-04-09 13:30:10,2018-12-26 11:39:55,2018-03-11 23:16:21 +900,Arabel,Reaney,250-158-0650,Female,1,39,42,2018-06-24 20:58:36,2018-06-13 01:05:57,2018-09-21 12:17:09,2018-05-12 01:20:04 +901,Lowrance,Birckmann,707-493-5823,Male,3,40,81,2018-10-30 04:51:25,2018-04-14 15:18:25,2018-11-26 23:12:20,2018-11-19 04:09:43 +902,Sande,Tinson,644-792-0309,Female,1,4,93,2018-06-05 12:30:15,2018-06-05 01:29:00,2018-04-13 08:38:54,2018-12-10 03:36:34 +903,Antonetta,Twelve,506-143-6120,Female,7,95,49,2018-10-15 14:45:58,2018-11-02 11:22:24,2018-02-20 23:03:06,2018-02-13 22:09:09 +904,Marietta,Christensen,356-415-2235,Male,5,80,58,2018-10-22 11:01:49,2018-02-01 17:42:35,2018-11-22 02:54:09,2018-09-30 12:05:18 +905,Jodee,Pietraszek,300-188-3774,Female,4,10,37,2018-10-23 06:33:49,2018-10-21 00:19:46,2018-11-29 18:55:51,2018-11-06 15:41:47 +906,Marthena,Kitson,601-214-9309,Female,4,28,26,2018-07-23 16:23:23,2018-06-22 12:00:30,2018-12-01 12:31:45,2018-12-23 15:09:43 +907,Daron,Mackison,682-377-7219,Female,4,89,96,2018-05-28 03:03:57,2018-03-02 01:25:11,2018-12-01 09:00:59,2018-02-21 02:24:22 +908,Hube,Feldhuhn,942-914-1709,Male,5,24,35,2018-10-02 04:25:27,2018-06-28 02:29:41,2018-02-06 01:40:17,2018-04-23 22:52:35 +909,Loretta,Pritty,613-563-4790,Female,7,75,82,2018-07-08 17:13:07,2018-11-22 22:05:00,2018-10-30 22:21:57,2018-08-13 01:05:15 +910,Cathyleen,McCallion,883-828-7510,Female,2,45,11,2018-09-09 14:13:19,2018-01-31 15:57:37,2018-08-13 04:55:36,2018-09-09 10:40:55 +911,Haleigh,Gleader,682-121-8965,Female,3,8,38,2018-12-20 06:38:29,2019-01-17 01:03:40,2019-01-19 16:23:53,2018-08-17 03:24:51 +912,Charles,Rosengarten,618-810-0078,Male,2,93,36,2018-10-15 16:20:15,2018-12-28 14:31:32,2018-09-12 08:52:44,2018-07-15 21:25:15 +913,Bjorn,Erskine Sandys,529-581-3333,Male,3,75,81,2018-04-14 17:13:49,2018-10-21 15:46:05,2018-05-28 06:44:30,2018-08-10 04:37:46 +914,Darill,Bostock,625-801-8242,Male,2,81,23,2018-10-11 19:47:21,2018-06-12 04:06:41,2019-01-15 07:56:54,2018-04-28 18:50:01 +915,Noellyn,Benwell,722-714-8266,Female,2,11,12,2018-02-15 07:48:35,2018-04-07 17:41:22,2018-05-18 02:39:40,2018-07-22 07:12:38 +916,Dov,Letrange,300-443-5277,Male,5,91,80,2018-12-27 15:44:06,2018-06-01 01:17:13,2018-06-04 08:44:49,2018-05-07 08:43:09 +917,Olympie,Louden,465-432-6397,Female,1,19,13,2018-01-25 05:55:27,2018-06-19 10:44:49,2018-10-06 16:38:12,2018-11-22 20:46:37 +918,Finley,Casbon,425-531-2684,Male,4,85,21,2018-09-04 05:24:44,2018-10-19 21:14:24,2018-09-24 15:11:59,2018-07-02 05:41:48 +919,Dewitt,Krolak,700-648-7734,Male,7,43,3,2018-04-11 09:56:52,2018-07-11 01:42:09,2018-02-28 00:53:56,2018-06-20 15:39:09 +920,Noby,De la Yglesia,405-211-0709,Male,4,1,49,2018-12-05 02:27:53,2018-07-03 10:21:49,2018-09-23 09:16:19,2018-05-12 09:47:56 +921,Aloysius,Baggs,272-379-1280,Male,2,40,53,2018-05-14 22:08:41,2018-12-03 09:03:58,2018-07-15 04:40:33,2018-09-15 06:12:36 +922,Karilynn,Costa,732-871-1192,Female,2,68,76,2018-12-29 05:05:50,2018-12-23 08:00:43,2018-04-13 17:50:47,2018-03-24 11:13:51 +923,Ky,Waggett,413-701-9663,Male,5,7,59,2018-02-05 06:17:54,2018-07-07 03:47:33,2018-09-13 00:11:05,2018-12-21 03:34:37 +924,Leeanne,Neasam,130-573-1360,Female,4,74,77,2018-11-30 04:33:22,2018-03-26 07:40:00,2018-05-03 16:40:09,2018-05-10 20:32:41 +925,Muffin,Eades,789-128-6773,Male,4,84,25,2018-04-19 09:16:22,2018-11-08 03:55:54,2018-02-03 05:36:52,2018-10-21 22:14:13 +926,Iormina,Baudry,644-418-1313,Female,4,72,19,2019-01-16 00:35:47,2018-11-23 14:35:13,2018-04-06 17:59:52,2018-02-24 14:59:31 +927,Fabe,Ziemke,161-651-6080,Male,6,36,12,2019-01-14 08:28:41,2018-10-28 13:42:55,2018-07-07 04:53:18,2018-08-04 15:37:00 +928,Danni,Leese,768-599-1814,Female,7,30,71,2018-11-08 21:26:44,2018-05-01 17:49:56,2018-08-03 00:06:41,2018-10-18 08:20:47 +929,Rycca,Petegre,433-887-8926,Female,4,5,34,2018-07-02 07:56:41,2018-02-10 11:51:30,2018-04-08 10:08:07,2018-06-11 19:43:31 +930,Berkie,Reveland,791-499-2738,Male,1,57,80,2018-07-18 08:14:02,2018-04-15 08:54:18,2018-09-25 23:13:59,2018-08-12 23:49:27 +931,Tommy,Swett,915-667-6497,Male,1,98,11,2018-06-26 21:33:59,2018-07-10 07:15:47,2018-07-15 03:48:37,2018-04-01 11:58:09 +932,Derrek,Perkinson,169-674-1053,Male,4,85,25,2018-08-23 05:51:09,2018-09-17 23:57:57,2018-03-06 01:30:46,2018-05-06 22:10:10 +933,Lonni,Polycote,996-492-4081,Female,2,7,6,2018-06-09 22:12:53,2018-04-09 09:26:53,2018-07-19 03:36:09,2018-12-01 16:50:15 +934,Phyllis,Gallamore,788-489-0287,Female,4,32,71,2018-07-08 11:07:20,2018-05-25 09:24:00,2018-04-23 04:53:35,2019-01-19 16:11:17 +935,Brittne,Caccavari,799-716-9817,Female,2,53,25,2018-12-11 00:47:47,2018-01-22 09:05:30,2018-09-30 14:03:22,2018-08-09 05:13:34 +936,Quinn,Torricina,342-560-9404,Female,3,60,72,2019-01-06 06:26:23,2018-11-21 02:21:54,2018-02-15 20:43:28,2018-08-15 17:59:55 +937,Jacklyn,Bohling,824-878-8873,Female,1,41,34,2018-06-23 18:52:40,2018-05-14 22:58:13,2018-06-08 07:11:42,2018-08-04 15:57:46 +938,Hunfredo,Millam,816-916-1240,Male,1,86,58,2019-01-08 04:02:45,2019-01-12 17:57:33,2019-01-20 14:58:14,2018-12-03 22:29:35 +939,Hymie,Vosse,980-181-0718,Male,4,67,59,2018-12-25 10:58:52,2018-03-09 06:50:03,2018-03-03 04:06:28,2018-07-17 18:26:14 +940,Olia,Wyse,875-970-0069,Female,4,54,96,2018-11-01 03:11:42,2018-12-29 18:01:06,2018-05-01 00:58:58,2018-08-29 17:41:08 +941,Arline,Bierton,582-902-5400,Female,4,36,83,2018-11-19 01:06:41,2018-07-20 08:22:25,2018-02-15 09:56:13,2018-07-07 12:00:06 +942,Nevsa,Jacquot,393-800-6240,Female,3,76,100,2018-12-03 03:10:20,2018-10-05 15:30:34,2018-07-03 08:10:26,2019-01-15 02:21:14 +943,Analise,Bechley,178-276-2761,Female,4,10,4,2018-08-03 05:49:50,2018-12-25 22:04:16,2019-01-18 22:16:01,2018-03-07 14:10:26 +944,Siffre,Cumbridge,484-369-3900,Male,1,30,98,2018-11-08 05:35:17,2018-07-06 03:41:16,2018-03-26 11:58:13,2018-10-05 22:55:01 +945,Berget,Oldred,470-380-7016,Female,2,34,3,2018-12-24 01:06:10,2018-03-01 08:09:07,2018-08-27 19:47:44,2018-07-15 17:16:39 +946,Aaron,Arnison,195-265-7576,Male,4,68,94,2018-06-02 08:58:18,2018-08-03 00:56:00,2018-05-06 14:32:24,2018-02-16 07:54:16 +947,Fay,Sarfas,659-275-5381,Female,6,34,96,2019-01-02 00:06:51,2018-12-05 05:47:36,2018-04-22 03:52:40,2018-09-20 19:16:51 +948,Pennie,Rappaport,851-746-8484,Female,5,74,57,2018-06-13 14:50:19,2018-05-10 00:00:37,2018-05-03 15:48:50,2018-12-06 19:15:10 +949,Ennis,Schindler,685-873-8208,Male,2,9,15,2018-12-06 10:23:57,2018-06-05 08:10:38,2018-08-19 04:20:22,2018-08-31 04:33:19 +950,Sean,Breckwell,511-213-8051,Male,4,65,20,2018-06-20 04:24:36,2018-12-24 06:27:41,2018-07-17 12:13:34,2018-06-02 06:09:01 +951,Carlene,Vials,130-632-1736,Female,2,71,12,2018-03-26 06:16:26,2018-03-25 23:10:14,2018-03-02 15:43:13,2018-06-01 08:30:44 +952,Nerita,Paolinelli,943-836-6191,Female,2,88,24,2018-11-19 20:39:05,2018-09-18 20:22:25,2018-07-16 13:15:28,2018-12-21 02:47:25 +953,Benoite,Gheorghescu,378-772-1101,Female,4,78,44,2018-11-09 02:22:49,2019-01-09 18:23:07,2018-04-05 11:06:02,2018-05-14 05:39:56 +954,Erik,Auchterlonie,766-720-0406,Male,1,17,56,2018-03-01 23:55:26,2018-10-18 17:00:40,2018-07-12 00:30:26,2018-11-30 15:38:30 +955,Jesse,Laurenty,586-274-7629,Female,2,10,63,2018-08-16 12:07:51,2018-05-30 23:14:43,2018-06-19 02:24:42,2018-03-17 09:24:46 +956,Lynnet,Cuel,652-339-4808,Female,1,26,91,2018-11-05 19:14:13,2018-11-22 14:06:17,2018-12-25 13:52:54,2018-10-28 04:14:09 +957,Marge,Adnet,901-394-6344,Female,7,46,51,2018-02-21 02:14:23,2018-12-29 22:39:34,2018-03-27 11:48:32,2019-01-05 10:26:02 +958,Clara,Rangeley,154-876-9501,Female,6,73,50,2018-07-06 13:52:31,2018-05-28 12:09:22,2018-09-08 04:19:54,2018-09-02 19:04:27 +959,Ciel,Ching,205-133-7293,Female,7,26,19,2018-06-13 01:00:22,2018-06-26 05:13:24,2018-03-12 09:15:19,2018-06-29 23:55:03 +960,Phebe,Pentecust,671-551-3717,Female,6,79,26,2018-07-17 05:39:55,2018-05-28 11:52:54,2018-11-17 17:20:32,2018-07-27 07:39:40 +961,Koralle,Doleman,733-411-3555,Female,4,50,86,2018-10-28 12:28:47,2018-04-19 14:24:23,2018-04-19 20:04:57,2018-11-03 19:27:30 +962,Gypsy,Ashard,627-318-6598,Female,4,84,97,2018-10-29 08:41:04,2018-04-12 21:17:30,2019-01-12 05:14:18,2018-08-11 13:20:16 +963,Zebedee,Guilayn,442-936-9333,Male,3,35,49,2018-06-20 19:42:39,2019-01-19 12:44:29,2018-10-03 09:52:26,2018-11-23 22:02:46 +964,Waldemar,Isaak,931-973-9119,Male,4,82,45,2018-04-23 15:37:02,2018-05-09 15:24:30,2018-02-14 08:08:10,2018-07-03 18:15:44 +965,Zackariah,Donaway,407-803-4328,Male,1,89,1,2018-07-08 18:27:27,2018-03-04 22:13:59,2018-12-18 03:57:10,2018-07-07 10:37:23 +966,Amie,Graddon,806-683-2495,Female,7,24,48,2018-08-12 05:59:08,2018-02-02 02:33:10,2018-12-27 15:24:26,2018-09-09 14:21:34 +967,Homere,Hinkes,540-511-8058,Male,2,18,21,2018-02-15 19:40:23,2018-03-12 20:21:06,2018-07-24 20:35:51,2018-11-05 01:00:48 +968,Hildy,Romaint,578-715-3279,Female,1,64,42,2018-08-05 12:04:55,2018-10-30 20:39:13,2018-11-01 10:01:51,2018-10-13 16:01:35 +969,Norbie,Reinhardt,522-463-8856,Male,6,73,39,2018-12-26 16:31:22,2018-05-04 07:05:54,2018-11-01 19:36:06,2018-08-22 23:10:40 +970,Farlee,Robb,921-988-0129,Male,2,92,32,2018-09-25 21:50:48,2018-01-29 06:17:06,2018-12-05 20:31:07,2018-10-13 17:19:53 +971,Husain,Coomes,167-999-0871,Male,7,43,13,2018-06-22 13:30:21,2018-10-26 10:44:10,2019-01-18 20:06:38,2018-12-02 03:52:12 +972,Milo,Ikringill,848-791-7005,Male,6,93,81,2018-04-23 10:40:56,2018-11-16 14:25:18,2018-05-08 11:02:49,2018-09-27 02:14:23 +973,Bendite,Ivan,797-480-5441,Female,4,19,47,2018-03-24 15:48:07,2019-01-18 21:56:06,2018-12-06 11:16:03,2018-03-11 17:19:09 +974,Dall,Hewson,361-271-3138,Male,7,51,12,2018-12-01 16:04:22,2018-07-19 15:52:08,2018-11-26 22:45:09,2018-02-12 13:20:52 +975,Alfonse,Paddell,215-108-6430,Male,3,67,39,2018-07-20 13:46:01,2019-01-09 15:28:08,2018-05-15 18:34:09,2018-09-24 12:02:27 +976,Rachelle,Parysowna,448-408-3939,Female,6,75,37,2019-01-08 01:40:17,2019-01-14 14:50:14,2018-09-08 20:13:56,2018-08-26 17:34:13 +977,Vlad,Massimo,958-382-7108,Male,6,83,50,2019-01-10 14:14:56,2018-04-03 09:05:13,2018-07-12 05:33:43,2018-08-03 07:52:29 +978,Orran,Labarre,603-601-4448,Male,1,62,88,2018-08-02 15:34:45,2018-11-25 10:40:27,2018-02-25 06:26:19,2018-08-02 08:35:57 +979,Goldi,McGaw,418-474-0723,Female,4,92,65,2018-03-02 17:07:20,2018-03-04 17:41:59,2018-08-24 13:07:56,2018-11-04 17:29:39 +980,Ddene,O'Halloran,269-505-5567,Female,5,40,82,2018-07-19 04:42:22,2018-10-21 20:43:40,2018-05-31 18:32:46,2018-05-27 23:48:19 +981,Franciska,Randalston,518-473-9956,Female,2,31,23,2018-08-10 19:43:25,2018-07-27 07:50:34,2018-09-05 22:19:23,2018-07-03 10:32:00 +982,Izak,Aaronson,559-374-9622,Male,3,42,87,2018-08-15 00:25:50,2018-04-15 10:04:12,2018-06-28 14:35:41,2018-01-21 11:06:29 +983,Trey,Battany,836-241-1102,Male,2,15,41,2019-01-10 17:37:08,2018-09-21 17:33:14,2018-10-31 07:41:53,2018-05-02 04:23:23 +984,Monty,Print,851-362-4374,Male,1,72,54,2018-07-29 11:59:40,2018-02-03 04:49:31,2019-01-10 13:05:52,2018-12-15 23:29:32 +985,Ashton,Cunnah,780-629-9147,Male,4,45,20,2018-02-10 13:25:53,2018-12-25 15:32:25,2018-01-23 10:29:44,2018-05-31 16:54:21 +986,Becky,Stavers,700-388-4222,Female,6,10,79,2018-03-04 20:32:59,2018-06-13 23:55:18,2018-06-02 22:41:53,2018-11-04 01:01:48 +987,Udall,Undrell,187-686-5781,Male,3,62,28,2018-07-29 04:00:33,2018-08-10 09:03:52,2018-12-20 19:09:22,2019-01-08 10:29:39 +988,Wait,Kippie,649-986-8035,Male,6,59,99,2018-08-26 01:11:54,2018-11-11 11:43:07,2018-11-26 18:10:23,2018-05-03 06:50:49 +989,Laurence,Dubs,725-348-9456,Male,5,80,78,2018-12-29 16:41:25,2018-03-04 01:25:41,2018-07-24 13:07:42,2018-03-02 01:22:54 +990,Cyrille,Ansley,464-181-4696,Male,7,71,25,2018-10-12 23:36:32,2018-05-18 07:03:48,2018-12-20 18:06:28,2018-09-16 15:37:18 +991,Emory,Manwell,415-640-8797,Male,5,12,56,2018-07-21 03:32:53,2018-11-15 00:05:50,2018-06-11 19:00:20,2018-03-30 06:39:44 +992,Chevalier,Pelosi,210-721-7355,Male,1,3,53,2018-09-10 01:51:52,2018-08-05 09:51:36,2018-07-09 12:50:42,2018-12-20 17:33:50 +993,Vale,Havenhand,885-493-5138,Male,5,37,72,2018-11-01 03:19:32,2018-11-02 06:12:05,2019-01-18 19:09:41,2018-07-29 06:54:36 +994,Shel,Kislingbury,683-829-9112,Female,2,57,75,2018-07-06 02:01:25,2018-11-17 02:11:03,2018-07-20 22:39:14,2018-05-08 16:48:52 +995,Kris,Rodear,296-572-9182,Male,5,24,22,2018-05-21 05:50:41,2018-12-04 14:27:38,2018-09-01 22:26:00,2018-09-05 14:46:56 +996,Jillayne,Mackerel,971-775-5324,Female,4,77,29,2018-08-29 09:36:26,2018-09-18 17:04:42,2018-12-08 03:41:26,2018-11-28 11:52:45 +997,Wilona,Yonnie,985-459-5111,Female,4,36,62,2018-08-07 01:17:54,2018-08-25 03:30:42,2018-02-17 20:26:24,2018-03-09 21:08:39 +998,Herbert,Liver,278-295-4343,Male,1,10,92,2018-04-27 00:14:36,2018-08-27 15:24:57,2018-02-11 18:53:26,2018-05-05 07:57:16 +999,Charmian,Robison,320-515-4401,Female,4,66,52,2018-11-29 19:32:40,2018-09-14 07:10:38,2018-07-04 09:36:16,2018-02-20 20:59:30 +1000,Cad,Alster,344-476-5489,Male,6,50,52,2018-09-12 09:49:44,2018-04-09 17:52:16,2018-12-18 02:15:47,2018-04-22 03:31:11 diff --git a/examples/compose/external_db/mysql/grant.sh b/examples/compose/external_db/mysql/grant.sh new file mode 100644 index 00000000000..897c1b5dcf2 --- /dev/null +++ b/examples/compose/external_db/mysql/grant.sh @@ -0,0 +1,7 @@ + +echo '**********GRANTING PRIVILEGES START*******************' +echo ${mysql[@]} +# PURGE BINARY LOGS BEFORE DATE(NOW()); +mysql --protocol=socket -uroot -hlocalhost --socket=/var/run/mysqld/mysqld.sock -p$MYSQL_ROOT_PASSWORD -e \ +"GRANT ALL PRIVILEGES ON *.* TO '$MYSQL_USER'@'%' IDENTIFIED BY '$MYSQL_PASSWORD'; FLUSH PRIVILEGES;" +echo '*************GRANTING PRIVILEGES END****************' \ No newline at end of file diff --git a/examples/compose/external_db/mysql/master_mysql56.cnf b/examples/compose/external_db/mysql/master_mysql56.cnf new file mode 100644 index 00000000000..7454231c33d --- /dev/null +++ b/examples/compose/external_db/mysql/master_mysql56.cnf @@ -0,0 +1,42 @@ +[mysqld] +# Options for enabling GTID +# https://dev.mysql.com/doc/refman/5.6/en/replication-gtids-howto.html +gtid_mode = ON +log_bin +log_slave_updates +enforce_gtid_consistency + +# Crash-safe replication settings. +master_info_repository = TABLE +relay_log_info_repository = TABLE +relay_log_purge = 1 +relay_log_recovery = 1 + +# Native AIO tends to run into aio-max-nr limit during test startup. +innodb_use_native_aio = 0 + +# Semi-sync replication is required for automated unplanned failover +# (when the master goes away). Here we just load the plugin so it's +# available if desired, but it's disabled at startup. +# +# If the -enable_semi_sync flag is used, VTTablet will enable semi-sync +# at the proper time when replication is set up, or when masters are +# promoted or demoted. +plugin-load = rpl_semi_sync_master=semisync_master.so;rpl_semi_sync_slave=semisync_slave.so + +# When semi-sync is enabled, don't allow fallback to async +# if you get no ack, or have no slaves. This is necessary to +# prevent alternate futures when doing a failover in response to +# a master that becomes unresponsive. +rpl_semi_sync_master_timeout = 1000000000000000000 +rpl_semi_sync_master_wait_no_slave = 1 +server-id = 1 +# Remove ONLY_FULL_GROUP_BY until queries are fixed +sql_mode = "STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION" + +general_log = 1 +general_log_file = /var/log/mysql/query.log + +slow_query_log = 1 +long_query_time = 1 # seconds +slow_query_log_file = /var/log/mysql/slow.log \ No newline at end of file diff --git a/examples/compose/external_db/template.env b/examples/compose/external_db/template.env new file mode 100644 index 00000000000..f2745ff08ef --- /dev/null +++ b/examples/compose/external_db/template.env @@ -0,0 +1,4 @@ +MYSQL_ROOT_PASSWORD=pass +MYSQL_USER=dbuser +MYSQL_PASSWORD=dbpass +MYSQL_DB=commerce \ No newline at end of file diff --git a/examples/compose/fix_replication.sh b/examples/compose/fix_replication.sh index 9df86620725..74f6ceb4d19 100644 --- a/examples/compose/fix_replication.sh +++ b/examples/compose/fix_replication.sh @@ -1,5 +1,19 @@ #!/bin/bash +# 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. + # This is a helper script to sync replicas for mysql. # It handles the special case where the master has purged bin logs that the replica requires. # To use it place a mysql dump of the database on the same directory as this script. diff --git a/examples/compose/lmysql.sh b/examples/compose/lmysql.sh index fb67c619d95..d735e3783a8 100644 --- a/examples/compose/lmysql.sh +++ b/examples/compose/lmysql.sh @@ -21,4 +21,4 @@ if [[ "$OSTYPE" == "msys" ]]; then fi # This is a convenience script to run mysql client against the local example. -exec $tty docker-compose exec ${CS:-vttablet1} mysql "$@" +exec $tty docker-compose exec ${CS:-vttablet101} mysql "$@" diff --git a/examples/compose/lvtctl.sh b/examples/compose/lvtctl.sh index 83d9a7c3c61..64110743073 100755 --- a/examples/compose/lvtctl.sh +++ b/examples/compose/lvtctl.sh @@ -21,4 +21,4 @@ if [[ "$OSTYPE" == "msys" ]]; then fi # This is a convenience script to run vtctlclient against the local example. -exec $tty docker-compose exec ${CS:-vttablet1} vtctlclient -server vtctld:15999 "$@" +exec $tty docker-compose exec ${CS:-vtctld} vtctlclient -server vtctld:15999 "$@" diff --git a/examples/compose/run-forever.sh b/examples/compose/run-forever.sh new file mode 100755 index 00000000000..51e511be77a --- /dev/null +++ b/examples/compose/run-forever.sh @@ -0,0 +1,21 @@ +#!/bin/bash + +# 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. + +while true +do + $@ + sleep 2 +done diff --git a/examples/compose/schemaload.sh b/examples/compose/schemaload.sh new file mode 100755 index 00000000000..d547647c951 --- /dev/null +++ b/examples/compose/schemaload.sh @@ -0,0 +1,59 @@ +#!/bin/bash -e + +# 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. + +sleeptime=${SLEEPTIME:-0} +targettab=${TARGETTAB:-"${CELL}-0000000101"} +schema_files=${SCHEMA_FILES:-'create_messages.sql create_tokens.sql'} +vschema_file=${VSCHEMA_FILE:-'default_vschema.json'} +load_file=${POST_LOAD_FILE:-''} +external_db=${EXTERNAL_DB:-'0'} + +sleep $sleeptime + +if [ ! -f schema_run ]; then + while true; do + vtctlclient -server vtctld:$GRPC_PORT GetTablet $targettab && break + sleep 1 + done + if [ "$external_db" = "0" ]; then + for schema_file in $schema_files; do + echo "Applying Schema ${schema_file} to ${KEYSPACE}" + vtctlclient -server vtctld:$GRPC_PORT ApplySchema -sql-file /script/tables/${schema_file} $KEYSPACE || \ + vtctlclient -server vtctld:$GRPC_PORT ApplySchema -sql "$(cat /script/tables/${schema_file})" $KEYSPACE || true + done + fi + echo "Applying VSchema ${vschema_file} to ${KEYSPACE}" + + vtctlclient -server vtctld:$GRPC_PORT ApplyVSchema -vschema_file /script/${vschema_file} $KEYSPACE || \ + vtctlclient -server vtctld:$GRPC_PORT ApplyVSchema -vschema "$(cat /script/${vschema_file})" $KEYSPACE + + echo "Get Master Tablets" + master_tablets=$(vtctlclient -server vtctld:$GRPC_PORT ListAllTablets | awk '$4 == "master" { print $1 }') + for master_tablet in $master_tablets; do + echo "Setting ReadWrite on master tablet ${master_tablet}" + vtctlclient -server vtctld:$GRPC_PORT SetReadWrite ${master_tablet} + done + + if [ -n "$load_file" ]; then + # vtgate can take a REALLY long time to come up fully + sleep 60 + mysql --port=15306 --host=vtgate < /script/$load_file + fi + + touch schema_run + echo "Time: $(date). SchemaLoad completed at $(date "+%FT%T") " >> schema_run + echo "Done Loading Schema at $(date "+%FT%T")" +fi diff --git a/examples/compose/tables/create_dinosaurs.sql b/examples/compose/tables/create_dinosaurs.sql new file mode 100644 index 00000000000..ee9a5b624da --- /dev/null +++ b/examples/compose/tables/create_dinosaurs.sql @@ -0,0 +1,6 @@ +CREATE TABLE dinosaurs ( + id BIGINT UNSIGNED, + time_created_ns BIGINT UNSIGNED, + name VARCHAR(255), + PRIMARY KEY (id) +) ENGINE=InnoDB; \ No newline at end of file diff --git a/examples/compose/tables/create_eggs.sql b/examples/compose/tables/create_eggs.sql new file mode 100644 index 00000000000..7e74c50b5a1 --- /dev/null +++ b/examples/compose/tables/create_eggs.sql @@ -0,0 +1,6 @@ +CREATE TABLE eggs ( + id BIGINT UNSIGNED, + time_created_ns BIGINT UNSIGNED, + species VARCHAR(255), + PRIMARY KEY (id) +) ENGINE=InnoDB; \ No newline at end of file diff --git a/examples/compose/create_test_table.sql b/examples/compose/tables/create_messages.sql similarity index 90% rename from examples/compose/create_test_table.sql rename to examples/compose/tables/create_messages.sql index bfb24b766ad..44c4cc16e87 100644 --- a/examples/compose/create_test_table.sql +++ b/examples/compose/tables/create_messages.sql @@ -3,5 +3,4 @@ CREATE TABLE messages ( time_created_ns BIGINT(20) UNSIGNED, message VARCHAR(10000), PRIMARY KEY (page, time_created_ns) -) ENGINE=InnoDB - +) ENGINE=InnoDB; \ No newline at end of file diff --git a/examples/compose/tables/create_messages_message_lookup.sql b/examples/compose/tables/create_messages_message_lookup.sql new file mode 100644 index 00000000000..1eb667dac93 --- /dev/null +++ b/examples/compose/tables/create_messages_message_lookup.sql @@ -0,0 +1,7 @@ +CREATE TABLE messages_message_lookup ( + id BIGINT NOT NULL AUTO_INCREMENT, + page BIGINT UNSIGNED, + message VARCHAR(1000), + PRIMARY KEY (id), + UNIQUE KEY idx_message_page (`message`, `page`) +) ENGINE=InnoDB; \ No newline at end of file diff --git a/examples/compose/tables/create_tokens.sql b/examples/compose/tables/create_tokens.sql new file mode 100644 index 00000000000..69f1be03dec --- /dev/null +++ b/examples/compose/tables/create_tokens.sql @@ -0,0 +1,6 @@ +CREATE TABLE tokens ( + page BIGINT(20) UNSIGNED, + time_created_ns BIGINT(20) UNSIGNED, + token VARCHAR(255) DEFAULT NULL, + PRIMARY KEY (page, time_created_ns) +) ENGINE=InnoDB; \ No newline at end of file diff --git a/examples/compose/tables/create_tokens_token_lookup.sql b/examples/compose/tables/create_tokens_token_lookup.sql new file mode 100644 index 00000000000..d3208fdfc41 --- /dev/null +++ b/examples/compose/tables/create_tokens_token_lookup.sql @@ -0,0 +1,7 @@ +CREATE TABLE tokens_token_lookup ( + id BIGINT NOT NULL AUTO_INCREMENT, + page BIGINT UNSIGNED, + token VARCHAR(255) DEFAULT NULL, + PRIMARY KEY (id), + UNIQUE KEY idx_token_page (`token`, `page`) +) ENGINE=InnoDB; \ No newline at end of file diff --git a/examples/compose/.env b/examples/compose/template.env similarity index 100% rename from examples/compose/.env rename to examples/compose/template.env diff --git a/examples/compose/vtcompose/base_vschema.json b/examples/compose/vtcompose/base_vschema.json new file mode 100644 index 00000000000..b867400e5ee --- /dev/null +++ b/examples/compose/vtcompose/base_vschema.json @@ -0,0 +1,10 @@ +{ + "sharded": true, + "vindexes": { + "hash": { + "type": "hash" + } + }, + "tables": { + } +} diff --git a/examples/compose/vtcompose/docker-compose.base.yml b/examples/compose/vtcompose/docker-compose.base.yml new file mode 100644 index 00000000000..eb714d99c0f --- /dev/null +++ b/examples/compose/vtcompose/docker-compose.base.yml @@ -0,0 +1,30 @@ +version: "2.1" +services: + consul1: + image: consul:latest + hostname: "consul1" + ports: + - "8400:8400" + - "8500:8500" + - "8600:8600" + command: "agent -server -bootstrap-expect 3 -ui -disable-host-node-id -client 0.0.0.0" + consul2: + image: consul:latest + hostname: "consul2" + expose: + - "8400" + - "8500" + - "8600" + command: "agent -server -retry-join consul1 -disable-host-node-id" + depends_on: + - consul1 + consul3: + image: consul:latest + hostname: "consul3" + expose: + - "8400" + - "8500" + - "8600" + command: "agent -server -retry-join consul1 -disable-host-node-id" + depends_on: + - consul1 \ No newline at end of file diff --git a/examples/compose/vtcompose/vtcompose.go b/examples/compose/vtcompose/vtcompose.go new file mode 100644 index 00000000000..b88099f3a6c --- /dev/null +++ b/examples/compose/vtcompose/vtcompose.go @@ -0,0 +1,647 @@ +/* + * 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 main + +import ( + "bytes" + "encoding/json" + "flag" + "fmt" + "io/ioutil" + "math" + "os" + "regexp" + "strconv" + "strings" + + jsonpatch "github.com/evanphx/json-patch" + yamlpatch "github.com/krishicks/yaml-patch" + + "vitess.io/vitess/go/vt/log" +) + +var ( + tabletsUsed = 0 + tablesPath = "tables/" + baseDockerComposeFile = flag.String("base_yaml", "vtcompose/docker-compose.base.yml", "Starting docker-compose yaml") + baseVschemaFile = flag.String("base_vschema", "vtcompose/base_vschema.json", "Starting vschema json") + + topologyFlags = flag.String("topologyFlags", + "-topo_implementation consul -topo_global_server_address consul1:8500 -topo_global_root vitess/global", + "Vitess Topology Flags config") + webPort = flag.String("webPort", "8080", "Web port to be used") + gRpcPort = flag.String("gRpcPort", "15999", "gRPC port to be used") + mySqlPort = flag.String("mySqlPort", "15306", "mySql port to be used") + cell = flag.String("cell", "test", "Vitess Cell name") + keyspaceData = flag.String("keyspaceData", "test_keyspace:2:1:create_messages.sql,create_tokens.sql;unsharded_keyspace:0:0:create_dinosaurs.sql,create_eggs.sql", "List of keyspace_name/external_db_name:num_of_shards:num_of_replica_tablets:schema_files:lookup_keyspace_name separated by ';'") + externalDbData = flag.String("externalDbData", "", "List of Data corresponding to external DBs. List of ,,,,, seperated by ';'") +) + +type keyspaceInfo struct { + keyspace string + shards int + replicaTablets int + lookupKeyspace string + useLookups bool + schemaFile *os.File + schemaFileNames []string +} + +type externalDbInfo struct { + dbName string + dbHost string + dbPort string + dbUser string + dbPass string + dbCharset string +} + +func newKeyspaceInfo(keyspace string, shards int, replicaTablets int, schemaFiles []string, lookupKeyspace string) keyspaceInfo { + k := keyspaceInfo{keyspace: keyspace, shards: shards, replicaTablets: replicaTablets, schemaFileNames: schemaFiles, lookupKeyspace: lookupKeyspace} + if len(strings.TrimSpace(lookupKeyspace)) == 0 { + k.useLookups = false + } else { + k.useLookups = true + } + + k.schemaFile = nil + return k +} + +func newExternalDbInfo(dbName, dbHost, dbPort, dbUser, dbPass, dbCharset string) externalDbInfo { + d := externalDbInfo{dbName: dbName, dbHost: dbHost, dbPort: dbPort, dbUser: dbUser, dbPass: dbPass, dbCharset: dbCharset} + return d +} + +func main() { + flag.Parse() + keyspaceInfoMap := make(map[string]keyspaceInfo) + externalDbInfoMap := make(map[string]externalDbInfo) + + for _, v := range strings.Split(*keyspaceData, ";") { + tokens := strings.Split(v, ":") + shards, _ := strconv.Atoi(tokens[1]) + replicaTablets, _ := strconv.Atoi(tokens[2]) + schemaFileNames := strings.Split(tokens[3], ",") + print(shards) + + if len(tokens) > 4 { + keyspaceInfoMap[tokens[0]] = newKeyspaceInfo(tokens[0], shards, replicaTablets, schemaFileNames, tokens[4]) + } else { + keyspaceInfoMap[tokens[0]] = newKeyspaceInfo(tokens[0], shards, replicaTablets, schemaFileNames, "") + } + } + + for _, v := range strings.Split(*externalDbData, ";") { + tokens := strings.Split(v, ":") + if len(tokens) > 1 { + externalDbInfoMap[tokens[0]] = newExternalDbInfo(tokens[0], tokens[1], tokens[2], tokens[3], tokens[4], tokens[5]) + } + } + + for k, v := range keyspaceInfoMap { + if _, ok := externalDbInfoMap[k]; !ok { + v.schemaFile = createFile(fmt.Sprintf("%s%s_schema_file.sql", tablesPath, v.keyspace)) + appendtoSqlFile(v.schemaFileNames, v.schemaFile) + closeFile(v.schemaFile) + } + } + + // Vschema Patching + for k, keyspaceData := range keyspaceInfoMap { + vSchemaFile := readFile(*baseVschemaFile) + if keyspaceData.shards == 0 { + vSchemaFile = applyJsonInMemoryPatch(vSchemaFile, `[{"op": "replace","path": "/sharded", "value": false}]`) + } + + // Check if it is an external_db + if _, ok := externalDbInfoMap[k]; ok { + //This is no longer necessary, but we'll keep it for reference + //https://github.com/vitessio/vitess/pull/4868, https://github.com/vitessio/vitess/pull/5010 + //vSchemaFile = applyJsonInMemoryPatch(vSchemaFile,`[{"op": "add","path": "/tables/*", "value": {}}]`) + } else { + var primaryTableColumns map[string]string + vSchemaFile, primaryTableColumns = addTablesVschemaPatch(vSchemaFile, keyspaceData.schemaFileNames) + + if keyspaceData.useLookups { + lookupKeyspace := keyspaceInfoMap[keyspaceData.lookupKeyspace] + vSchemaFile = addLookupDataToVschema(vSchemaFile, lookupKeyspace.schemaFileNames, primaryTableColumns, lookupKeyspace.keyspace) + } + } + + writeVschemaFile(vSchemaFile, fmt.Sprintf("%s_vschema.json", keyspaceData.keyspace)) + } + + // Docker Compose File Patches + dockerComposeFile := readFile(*baseDockerComposeFile) + dockerComposeFile = applyDockerComposePatches(dockerComposeFile, keyspaceInfoMap, externalDbInfoMap) + writeFile(dockerComposeFile, "docker-compose.yml") +} + +func applyFilePatch(dockerYaml []byte, patchFile string) []byte { + yamlPatch, err := ioutil.ReadFile(patchFile) + if err != nil { + log.Fatalf("reading yaml patch file %s: %s", patchFile, err) + } + + patch, err := yamlpatch.DecodePatch(yamlPatch) + if err != nil { + log.Fatalf("decoding patch failed: %s", err) + } + + bs, err := patch.Apply(dockerYaml) + if err != nil { + log.Fatalf("applying patch failed: %s", err) + } + return bs +} + +func applyJsonInMemoryPatch(vSchemaFile []byte, patchString string) []byte { + patch, err := jsonpatch.DecodePatch([]byte(patchString)) + if err != nil { + log.Fatalf("decoding vschema patch failed: %s", err) + } + + modified, err := patch.Apply(vSchemaFile) + if err != nil { + log.Fatalf("applying vschema patch failed: %s", err) + } + return modified +} + +func applyInMemoryPatch(dockerYaml []byte, patchString string) []byte { + patch, err := yamlpatch.DecodePatch([]byte(patchString)) + if err != nil { + log.Fatalf("decoding patch failed: %s", err) + } + + bs, err := patch.Apply(dockerYaml) + if err != nil { + log.Fatalf("applying patch failed: %s", err) + } + return bs +} + +func createFile(filePath string) *os.File { + f, err := os.Create(filePath) + if err != nil { + log.Fatalf("creating %s %s", filePath, err) + } + return f +} + +func readFile(filePath string) []byte { + file, err := ioutil.ReadFile(filePath) + + if err != nil { + log.Fatalf("reading %s: %s", filePath, err) + } + + return file +} + +func closeFile(file *os.File) { + err := file.Close() + if err != nil { + log.Fatalf("Closing schema_file.sql %s", err) + } +} + +func handleError(err error) { + if err != nil { + log.Fatalf("Error: %s", err) + } +} + +func appendtoSqlFile(schemaFileNames []string, f *os.File) { + for _, file := range schemaFileNames { + data, err := ioutil.ReadFile(tablesPath + file) + _, err = f.Write(data) + handleError(err) + + _, err = f.WriteString("\n\n") + handleError(err) + + err = f.Sync() + handleError(err) + } +} + +func getTableName(sqlFile string) string { + sqlFileData, err := ioutil.ReadFile(sqlFile) + if err != nil { + log.Fatalf("reading sqlFile file %s: %s", sqlFile, err) + } + + r, _ := regexp.Compile("CREATE TABLE ([a-z_-]*) \\(") + rs := r.FindStringSubmatch(string(sqlFileData)) + // replace all ` from table name if exists + return strings.ReplaceAll(rs[1], "`", "") +} + +func getPrimaryKey(sqlFile string) string { + sqlFileData, err := ioutil.ReadFile(sqlFile) + if err != nil { + log.Fatalf("reading sqlFile file %s: %s", sqlFile, err) + } + + r, _ := regexp.Compile("PRIMARY KEY \\((.*)\\).*") + rs := r.FindStringSubmatch(string(sqlFileData)) + + return rs[1] +} + +func getKeyColumns(sqlFile string) string { + sqlFileData, err := ioutil.ReadFile(sqlFile) + if err != nil { + log.Fatalf("reading sqlFile file %s: %s", sqlFile, err) + } + + r, _ := regexp.Compile("[^PRIMARY] (KEY|UNIQUE KEY) .*\\((.*)\\).*") + rs := r.FindStringSubmatch(string(sqlFileData)) + print(rs[2]) + // replace all ` from column names if exists + return strings.ReplaceAll(rs[2], "`", "") +} + +func addTablesVschemaPatch(vSchemaFile []byte, schemaFileNames []string) ([]byte, map[string]string) { + indexedColumns := "" + primaryTableColumns := make(map[string]string) + for _, fileName := range schemaFileNames { + tableName := getTableName(tablesPath + fileName) + indexedColumns = getPrimaryKey(tablesPath + fileName) + firstColumnName := strings.Split(indexedColumns, ", ")[0] + vSchemaFile = applyJsonInMemoryPatch(vSchemaFile, generatePrimaryVIndex(tableName, firstColumnName, "hash")) + primaryTableColumns[tableName] = firstColumnName + } + + return vSchemaFile, primaryTableColumns +} + +func addLookupDataToVschema(vSchemaFile []byte, schemaFileNames []string, primaryTableColumns map[string]string, keyspace string) []byte { + for _, fileName := range schemaFileNames { + tableName := fileName[7 : len(fileName)-4] + lookupTableOwner := "" + + // Find owner of lookup table + for primaryTableName, _ := range primaryTableColumns { + if strings.HasPrefix(tableName, primaryTableName) && len(primaryTableName) > len(lookupTableOwner) { + lookupTableOwner = primaryTableName + } + } + + indexedColumns := getKeyColumns(tablesPath + fileName) + firstColumnName := strings.Split(indexedColumns, ", ")[0] + + // Lookup patch under "tables" + vSchemaFile = applyJsonInMemoryPatch(vSchemaFile, addToColumnVIndexes(lookupTableOwner, firstColumnName, tableName)) + + // Generate Vschema lookup hash types + vSchemaFile = applyJsonInMemoryPatch(vSchemaFile, + generateVschemaLookupHash(tableName, keyspace, firstColumnName, primaryTableColumns[lookupTableOwner], lookupTableOwner)) + } + + return vSchemaFile +} + +func writeVschemaFile(file []byte, fileName string) { + // Format json file + var buf bytes.Buffer + err := json.Indent(&buf, file, "", "\t") + handleError(err) + file = buf.Bytes() + + writeFile(file, fileName) +} + +func writeFile(file []byte, fileName string) { + err := ioutil.WriteFile(fileName, file, 0644) + if err != nil { + log.Fatalf("writing %s %s", fileName, err) + } +} + +func applyKeyspaceDependentPatches(dockerComposeFile []byte, keyspaceData keyspaceInfo, externalDbInfoMap map[string]externalDbInfo) []byte { + var externalDbInfo externalDbInfo + if val, ok := externalDbInfoMap[keyspaceData.keyspace]; ok { + externalDbInfo = val + } + tabAlias := 0 + tabletsUsed*100 + shard := "-" + var masterTablets []string + if tabletsUsed == 0 { + masterTablets = append(masterTablets, "101") + } else { + masterTablets = append(masterTablets, strconv.Itoa((tabletsUsed+1)*100+1)) + } + interval := int(math.Floor(256 / float64(keyspaceData.shards))) + + for i := 1; i < keyspaceData.shards; i++ { + masterTablets = append(masterTablets, strconv.Itoa((i+1)*100+1)) + } + + dockerComposeFile = applyInMemoryPatch(dockerComposeFile, generateSchemaload(masterTablets, "", keyspaceData.keyspace, externalDbInfo)) + + // Append Master and Replica Tablets + if keyspaceData.shards < 2 { + tabAlias = tabAlias + 100 + dockerComposeFile = applyTabletPatches(dockerComposeFile, tabAlias, shard, keyspaceData, externalDbInfoMap) + } else { + // Determine shard range + for i := 0; i < keyspaceData.shards; i++ { + if i == 0 { + shard = fmt.Sprintf("-%x", interval) + } else if i == (keyspaceData.shards - 1) { + shard = fmt.Sprintf("%x-", interval*i) + } else { + shard = fmt.Sprintf("%x-%x", interval*(i), interval*(i+1)) + } + tabAlias = tabAlias + 100 + dockerComposeFile = applyTabletPatches(dockerComposeFile, tabAlias, shard, keyspaceData, externalDbInfoMap) + } + } + + tabletsUsed += len(masterTablets) + return dockerComposeFile +} + +func applyDefaultDockerPatches(dockerComposeFile []byte) []byte { + dockerComposeFile = applyInMemoryPatch(dockerComposeFile, generateVtctld()) + dockerComposeFile = applyInMemoryPatch(dockerComposeFile, generateVtgate()) + dockerComposeFile = applyInMemoryPatch(dockerComposeFile, generateVtwork()) + return dockerComposeFile +} + +func applyDockerComposePatches(dockerComposeFile []byte, keyspaceInfoMap map[string]keyspaceInfo, externalDbInfoMap map[string]externalDbInfo) []byte { + //Vtctld, vtgate, vtwork patches + dockerComposeFile = applyDefaultDockerPatches(dockerComposeFile) + for _, keyspaceData := range keyspaceInfoMap { + dockerComposeFile = applyKeyspaceDependentPatches(dockerComposeFile, keyspaceData, externalDbInfoMap) + } + + return dockerComposeFile +} + +func applyTabletPatches(dockerComposeFile []byte, tabAlias int, shard string, keyspaceData keyspaceInfo, externalDbInfoMap map[string]externalDbInfo) []byte { + var dbInfo externalDbInfo + if val, ok := externalDbInfoMap[keyspaceData.keyspace]; ok { + dbInfo = val + } + dockerComposeFile = applyInMemoryPatch(dockerComposeFile, generateDefaultTablet(strconv.Itoa(tabAlias+1), shard, "master", keyspaceData.keyspace, dbInfo)) + for i := 0; i < keyspaceData.replicaTablets; i++ { + dockerComposeFile = applyInMemoryPatch(dockerComposeFile, generateDefaultTablet(strconv.Itoa(tabAlias+2+i), shard, "replica", keyspaceData.keyspace, dbInfo)) + } + return dockerComposeFile +} + +// Default Tablet +func generateDefaultTablet(tabAlias, shard, role, keyspace string, dbInfo externalDbInfo) string { + externalDb := "0" + if dbInfo.dbName != "" { + externalDb = "1" + } + data := fmt.Sprintf(` +- op: add + path: /services/vttablet%[1]s + value: + image: vitess/base + ports: + - "15%[1]s:%[4]s" + - "%[5]s" + - "3306" + volumes: + - ".:/script" + environment: + - TOPOLOGY_FLAGS=%[7]s + - WEB_PORT=%[4]s + - GRPC_PORT=%[5]s + - CELL=%[8]s + - KEYSPACE=%[6]s + - SHARD=%[2]s + - ROLE=%[3]s + - VTHOST=vttablet%[1]s + - EXTERNAL_DB=%[9]s + - DB_PORT=%[10]s + - DB_HOST=%[11]s + - DB_USER=%[12]s + - DB_PASS=%[13]s + - DB_CHARSET=%[14]s + command: ["sh", "-c", "/script/vttablet-up.sh %[1]s"] + depends_on: + - vtctld + healthcheck: + test: ["CMD-SHELL","curl localhost:%[4]s/debug/health"] + interval: 30s + timeout: 10s + retries: 15 +`, tabAlias, shard, role, *webPort, *gRpcPort, keyspace, *topologyFlags, *cell, externalDb, dbInfo.dbPort, dbInfo.dbHost, dbInfo.dbUser, dbInfo.dbPass, dbInfo.dbCharset) + + return data +} + +// Generate Vtctld +func generateVtctld() string { + data := fmt.Sprintf(` +- op: add + path: /services/vtctld + value: + image: vitess/base + ports: + - "15000:%[1]s" + - "%[2]s" + command: ["sh", "-c", " $$VTROOT/bin/vtctld \ + %[3]s \ + -cell %[4]s \ + -web_dir $$VTTOP/web/vtctld \ + -web_dir2 $$VTTOP/web/vtctld2/app \ + -workflow_manager_init \ + -workflow_manager_use_election \ + -service_map 'grpc-vtctl' \ + -backup_storage_implementation file \ + -file_backup_storage_root $$VTDATAROOT/backups \ + -logtostderr=true \ + -port %[1]s \ + -grpc_port %[2]s \ + -pid_file $$VTDATAROOT/tmp/vtctld.pid + "] + volumes: + - .:/script + depends_on: + - consul1 + - consul2 + - consul3 +`, *webPort, *gRpcPort, *topologyFlags, *cell) + + return data +} + +// Generate Vtgate +func generateVtgate() string { + data := fmt.Sprintf(` +- op: add + path: /services/vtgate + value: + image: vitess/base + ports: + - "15099:%[1]s" + - "%[2]s" + - "15306:%[3]s" + command: ["sh", "-c", "/script/run-forever.sh $$VTROOT/bin/vtgate \ + %[4]s \ + -logtostderr=true \ + -port %[1]s \ + -grpc_port %[2]s \ + -mysql_server_port %[3]s \ + -mysql_auth_server_impl none \ + -cell %[5]s \ + -cells_to_watch %[5]s \ + -tablet_types_to_wait MASTER,REPLICA,RDONLY \ + -gateway_implementation discoverygateway \ + -service_map 'grpc-vtgateservice' \ + -pid_file $$VTDATAROOT/tmp/vtgate.pid \ + -normalize_queries=true \ + "] + volumes: + - .:/script + depends_on: + - vtctld +`, *webPort, *gRpcPort, *mySqlPort, *topologyFlags, *cell) + + return data +} + +func generateVtwork() string { + data := fmt.Sprintf(` +- op: add + path: /services/vtwork + value: + image: vitess/base + ports: + - "15100:%[1]s" + - "%[2]s" + command: ["sh", "-c", "$$VTROOT/bin/vtworker \ + %[3]s \ + -cell %[4]s \ + -logtostderr=true \ + -service_map 'grpc-vtworker' \ + -port %[1]s \ + -grpc_port %[2]s \ + -use_v3_resharding_mode=true \ + -pid_file $$VTDATAROOT/tmp/vtwork.pid \ + "] + depends_on: + - vtctld +`, *webPort, *gRpcPort, *topologyFlags, *cell) + + return data +} + +func generateSchemaload(tabletAliases []string, postLoadFile string, keyspace string, dbInfo externalDbInfo) string { + targetTab := tabletAliases[0] + schemaFileName := fmt.Sprintf("%s_schema_file.sql", keyspace) + externalDb := "0" + + if dbInfo.dbName != "" { + schemaFileName = "" + externalDb = "1" + } + + // Formatting for list in yaml + for i, tabletId := range tabletAliases { + //tabletAliases[i] = "\"vttablet" + tabletId + "\"" + tabletAliases[i] = "vttablet" + tabletId + ": " + "{condition : service_healthy}" + } + //dependsOn := "[" + strings.Join(tabletAliases, ", ") + "]" + dependsOn := "depends_on: {" + strings.Join(tabletAliases, ", ") + "}" + + data := fmt.Sprintf(` +- op: add + path: /services/schemaload_%[7]s + value: + image: vitess/base + volumes: + - ".:/script" + environment: + - TOPOLOGY_FLAGS=%[3]s + - WEB_PORT=%[4]s + - GRPC_PORT=%[5]s + - CELL=%[6]s + - KEYSPACE=%[7]s + - TARGETTAB=%[6]s-0000000%[2]s + - SLEEPTIME=15 + - VSCHEMA_FILE=%[7]s_vschema.json + - SCHEMA_FILES=%[9]s + - POST_LOAD_FILE=%[8]s + - EXTERNAL_DB=%[10]s + command: ["sh", "-c", "/script/schemaload.sh"] + %[1]s +`, dependsOn, targetTab, *topologyFlags, *webPort, *gRpcPort, *cell, keyspace, postLoadFile, schemaFileName, externalDb) + + return data +} + +func generatePrimaryVIndex(tableName, column string, name string) string { + data := fmt.Sprintf(` +[{"op": "add", +"path": "/tables/%[1]s", +"value": + {"column_vindexes": [ + { + "column": "%[2]s", + "name": "%[3]s" + } + ]} +}] +`, tableName, column, name) + + return data +} + +func generateVschemaLookupHash(tableName, tableKeyspace, from, to, owner string) string { + data := fmt.Sprintf(` +[{"op": "add", +"path": "/vindexes/%[1]s", +"value": + {"type": "lookup_hash", + "params": { + "table": "%[2]s.%[1]s", + "from": "%[3]s", + "to": "%[4]s", + "autocommit": "true" + }, + "owner": "%[5]s" + } +}] +`, tableName, tableKeyspace, from, to, owner) + + return data +} + +func addToColumnVIndexes(tableName, column, referenceName string) string { + data := fmt.Sprintf(` +[{"op": "add", +"path": "/tables/%[1]s/column_vindexes/-", +"value": + { + "column": "%[2]s", + "name": "%[3]s" + } +}] +`, tableName, column, referenceName) + + return data +} diff --git a/examples/compose/vttablet-up.sh b/examples/compose/vttablet-up.sh index 568e28684b3..00369ecdd22 100755 --- a/examples/compose/vttablet-up.sh +++ b/examples/compose/vttablet-up.sh @@ -1,45 +1,61 @@ #!/bin/bash +# 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. + set -u keyspace=${KEYSPACE:-'test_keyspace'} shard=${SHARD:-'0'} +grpc_port=${GRPC_PORT:-'15999'} +web_port=${WEB_PORT:-'8080'} +role=${ROLE:-'replica'} +vthost=${VTHOST:-''} +sleeptime=${SLEEPTIME:-'0'} uid=$1 external=${EXTERNAL_DB:-0} -db_name=${DB:-"$keyspace"} +[ $external = 0 ] && db_name=${DB:-"vt_$keyspace"} || db_name=${DB:-"$keyspace"} db_charset=${DB_CHARSET:-''} tablet_hostname='' # Use IPs to simplify connections when testing in docker. # Otherwise, blank hostname means the tablet auto-detects FQDN. if [ $external = 1 ]; then - tablet_hostname=`hostname -i` + vthost=`hostname -i` fi printf -v alias '%s-%010d' $CELL $uid printf -v tablet_dir 'vt_%010d' $uid -tablet_role='replica' +tablet_role=$role tablet_type='replica' -if [ "$uid" = "1" ]; then - tablet_role='master' -fi -if (( $uid % 3 == 0 )) ; then +# Make every 3rd tablet rdonly +if (( $uid % 100 % 3 == 0 )) ; then tablet_type='rdonly' fi init_db_sql_file="$VTROOT/config/init_db.sql" # Create database on master -if [[ "$tablet_role" = "master" ]]; then - echo "Add create database statement for master tablet: $uid..." +if [ $tablet_role = "master" ]; then echo "CREATE DATABASE IF NOT EXISTS $db_name;" >> $init_db_sql_file fi # Create database on replicas -if [[ "$tablet_role" != "master" ]]; then +if [ $tablet_role != "master" ]; then echo "Add create database statement for replicas tablet: $uid..." - if [[ "$external" = "1" ]]; then + if [ "$external" = "1" ]; then # Add master character set and collation to avoid replication errors # Example:CREATE DATABASE IF NOT EXISTS $keyspace CHARACTER SET latin1 COLLATE latin1_swedish_ci echo "CREATE DATABASE IF NOT EXISTS $db_name $db_charset;" >> $init_db_sql_file @@ -52,7 +68,7 @@ if [[ "$tablet_role" != "master" ]]; then echo "CREATE DATABASE IF NOT EXISTS $db_name;" >> $init_db_sql_file fi fi - +# Enforce Row Based Replication export EXTRA_MY_CNF=$VTROOT/config/mycnf/default-fast.cnf:$VTROOT/config/mycnf/rbr.cnf export EXTRA_MY_CNF=$EXTRA_MY_CNF:$VTROOT/config/mycnf/master_mysql56.cnf @@ -78,28 +94,41 @@ export DB_NAME=$db_name # Create mysql instances # Do not create mysql instance for master if connecting to external mysql database -if [[ $uid -gt 1 || $external = 0 ]]; then - echo "Initing mysql for tablet: $uid.. " - $VTROOT/bin/mysqlctl \ - -log_dir $VTDATAROOT/tmp \ - -tablet_uid $uid \ - -mysql_port 3306 \ - $action & - - wait +if [[ $role != "master" || $external = 0 ]]; then + echo "Initing mysql for tablet: $uid.. " + $VTROOT/bin/mysqlctl \ + -log_dir $VTDATAROOT/tmp \ + -tablet_uid $uid \ + -mysql_port 3306 \ + $action & + + wait fi -$VTROOT/bin/vtctl $TOPOLOGY_FLAGS AddCellInfo -root vitess/$CELL -server_address consul1:8500 $CELL +sleep $sleeptime + +# if [ $role != "master" ]; then -$VTROOT/bin/vtctl $TOPOLOGY_FLAGS CreateKeyspace $keyspace -$VTROOT/bin/vtctl $TOPOLOGY_FLAGS CreateShard $keyspace/$shard + # master_uid=${uid:0:1}01 + # master_vttablet=vttablet${master_uid} + # until mysql -h ${master_vttablet} -u root -e "select 0;"; do echo "Polling master mysql at ${master_vttablet}..." && sleep 1; done -$VTROOT/bin/vtctl $TOPOLOGY_FLAGS InitTablet -shard $shard -keyspace $keyspace -allow_master_override $alias $tablet_role + # echo "Restoring mysql dump from ${master_vttablet}..." + # mysql -S $VTDATAROOT/$tablet_dir/mysql.sock -u root -e "FLUSH LOGS; RESET SLAVE;RESET MASTER;" + # mysqldump -h ${master_vttablet} -u root --all-databases --triggers --routines --events --single-transaction --set-gtid-purged=AUTO --default-character-set=utf8mb4 | mysql -S $VTDATAROOT/$tablet_dir/mysql.sock -u root +# fi + +$VTROOT/bin/vtctl $TOPOLOGY_FLAGS AddCellInfo -root vitess/$CELL -server_address consul1:8500 $CELL || true + +$VTROOT/bin/vtctl $TOPOLOGY_FLAGS CreateKeyspace $keyspace || true +$VTROOT/bin/vtctl $TOPOLOGY_FLAGS CreateShard $keyspace/$shard || true + +$VTROOT/bin/vtctl $TOPOLOGY_FLAGS InitTablet -shard $shard -keyspace $keyspace -grpc_port $grpc_port -port $web_port -allow_master_override $alias $tablet_role #Populate external db conditional args -if [[ "$external" = "1" ]]; then - if [[ "$uid" = "1" ]]; then +if [ "$external" = "1" ]; then + if [ $role = "master" ]; then echo "Setting external db args for master: $DB_NAME" external_db_args="-db_host $DB_HOST \ -db_port $DB_PORT \ @@ -137,12 +166,13 @@ exec $VTROOT/bin/vttablet \ $TOPOLOGY_FLAGS \ -logtostderr=true \ -tablet-path $alias \ - -tablet_hostname "$tablet_hostname" \ + -tablet_hostname "$vthost" \ -health_check_interval 5s \ -enable_semi_sync \ -enable_replication_reporter \ - -port $WEB_PORT \ - -grpc_port $GRPC_PORT \ + -port $web_port \ + -grpc_port $grpc_port \ + -binlog_use_v3_resharding_mode=true \ -service_map 'grpc-queryservice,grpc-tabletmanager,grpc-updatestream' \ -pid_file $VTDATAROOT/$tablet_dir/vttablet.pid \ -vtctld_addr "http://vtctld:$WEB_PORT/" \ @@ -152,5 +182,4 @@ exec $VTROOT/bin/vttablet \ -backup_storage_implementation file \ -file_backup_storage_root $VTDATAROOT/backups \ -queryserver-config-schema-reload-time 60 \ - $external_db_args - + $external_db_args \ No newline at end of file diff --git a/examples/demo/cgi-bin/data.py b/examples/demo/cgi-bin/data.py index a5482cef821..39058bc5e76 100755 --- a/examples/demo/cgi-bin/data.py +++ b/examples/demo/cgi-bin/data.py @@ -1,14 +1,14 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- # -# Copyright 2017 Google Inc. -# +# 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. diff --git a/examples/demo/demo.js b/examples/demo/demo.js index c71006d28d6..6803edb68dc 100644 --- a/examples/demo/demo.js +++ b/examples/demo/demo.js @@ -1,6 +1,17 @@ -/** - * Copyright 2015, Google Inc. All rights reserved. Use of this source code is - * governed by a BSD-style license that can be found in the LICENSE file. +/* + * 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. */ 'use strict'; diff --git a/examples/demo/run.py b/examples/demo/run.py index 0fd4778b899..45eb8267ce2 100755 --- a/examples/demo/run.py +++ b/examples/demo/run.py @@ -1,6 +1,6 @@ #!/usr/bin/env python -# Copyright 2017 Google Inc. +# 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. diff --git a/examples/helm/kmysql.sh b/examples/helm/kmysql.sh index 6525448a62e..29ddb2c054f 100755 --- a/examples/helm/kmysql.sh +++ b/examples/helm/kmysql.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2018 The Vitess Authors. +# 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. diff --git a/examples/helm/kvtctld.sh b/examples/helm/kvtctld.sh index a30e77842a6..45f9c796299 100755 --- a/examples/helm/kvtctld.sh +++ b/examples/helm/kvtctld.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2018 The Vitess Authors. +# 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. diff --git a/examples/kubernetes/cluster-down.sh b/examples/kubernetes/cluster-down.sh index 32441ad0248..33ea5891ae5 100755 --- a/examples/kubernetes/cluster-down.sh +++ b/examples/kubernetes/cluster-down.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2017 Google Inc. +# 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. diff --git a/examples/kubernetes/cluster-up.sh b/examples/kubernetes/cluster-up.sh index 23c8054949a..7e4da58946c 100755 --- a/examples/kubernetes/cluster-up.sh +++ b/examples/kubernetes/cluster-up.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2017 Google Inc. +# 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. diff --git a/examples/kubernetes/configure.sh b/examples/kubernetes/configure.sh index ca626b9b079..8ed12fd9587 100755 --- a/examples/kubernetes/configure.sh +++ b/examples/kubernetes/configure.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2017 Google Inc. +# 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. diff --git a/examples/kubernetes/env.sh b/examples/kubernetes/env.sh index 922a3927f59..c644b4de8be 100644 --- a/examples/kubernetes/env.sh +++ b/examples/kubernetes/env.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2017 Google Inc. +# 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. diff --git a/examples/kubernetes/etcd-down.sh b/examples/kubernetes/etcd-down.sh index a7bbee9cb4c..ecc912b63de 100755 --- a/examples/kubernetes/etcd-down.sh +++ b/examples/kubernetes/etcd-down.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2017 Google Inc. +# 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. diff --git a/examples/kubernetes/etcd-up.sh b/examples/kubernetes/etcd-up.sh index 28cf29686a6..f4d4d6118bc 100755 --- a/examples/kubernetes/etcd-up.sh +++ b/examples/kubernetes/etcd-up.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2017 Google Inc. +# 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. diff --git a/examples/kubernetes/guestbook-down.sh b/examples/kubernetes/guestbook-down.sh index bb6daee9884..35186041553 100755 --- a/examples/kubernetes/guestbook-down.sh +++ b/examples/kubernetes/guestbook-down.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2017 Google Inc. +# 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. diff --git a/examples/kubernetes/guestbook-up.sh b/examples/kubernetes/guestbook-up.sh index 69eb1e294db..f246a72e2ec 100755 --- a/examples/kubernetes/guestbook-up.sh +++ b/examples/kubernetes/guestbook-up.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2017 Google Inc. +# 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. diff --git a/examples/kubernetes/guestbook/Dockerfile b/examples/kubernetes/guestbook/Dockerfile index a6a7fe29124..afdd85b4f2e 100644 --- a/examples/kubernetes/guestbook/Dockerfile +++ b/examples/kubernetes/guestbook/Dockerfile @@ -1,3 +1,17 @@ +# 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. + # This Dockerfile should be built from within the accompanying build.sh script. FROM debian:jessie diff --git a/examples/kubernetes/guestbook/build.sh b/examples/kubernetes/guestbook/build.sh index ad568b6164a..712bc8bf123 100755 --- a/examples/kubernetes/guestbook/build.sh +++ b/examples/kubernetes/guestbook/build.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2017 Google Inc. +# 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. diff --git a/examples/kubernetes/guestbook/extract.sh b/examples/kubernetes/guestbook/extract.sh index 068d85e9376..e029df3fc77 100644 --- a/examples/kubernetes/guestbook/extract.sh +++ b/examples/kubernetes/guestbook/extract.sh @@ -1,4 +1,4 @@ -# Copyright 2017 Google Inc. +# 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. @@ -11,7 +11,6 @@ # 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. - # Don't run this. It is only used as part of build.sh. set -e diff --git a/examples/kubernetes/guestbook/main.py b/examples/kubernetes/guestbook/main.py index 3a2a74e824d..9814990b915 100644 --- a/examples/kubernetes/guestbook/main.py +++ b/examples/kubernetes/guestbook/main.py @@ -1,4 +1,4 @@ -# Copyright 2017 Google Inc. +# 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. diff --git a/examples/kubernetes/guestbook/requirements.txt b/examples/kubernetes/guestbook/requirements.txt index b1dae5a2716..eb913c5c387 100644 --- a/examples/kubernetes/guestbook/requirements.txt +++ b/examples/kubernetes/guestbook/requirements.txt @@ -1,3 +1,3 @@ -Flask==0.12.3 +Flask==1.0 grpcio==1.12.0 grpcio-tools==1.12.0 diff --git a/examples/kubernetes/kvtctl.sh b/examples/kubernetes/kvtctl.sh index 347c1f288d7..5dcb6dc3730 100755 --- a/examples/kubernetes/kvtctl.sh +++ b/examples/kubernetes/kvtctl.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2017 Google Inc. +# 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. diff --git a/examples/kubernetes/namespace-down.sh b/examples/kubernetes/namespace-down.sh index bf5314f792e..e5345f412e6 100755 --- a/examples/kubernetes/namespace-down.sh +++ b/examples/kubernetes/namespace-down.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2017 Google Inc. +# 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. diff --git a/examples/kubernetes/namespace-up.sh b/examples/kubernetes/namespace-up.sh index 1de12d9cba2..d5c6e53f030 100755 --- a/examples/kubernetes/namespace-up.sh +++ b/examples/kubernetes/namespace-up.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2017 Google Inc. +# 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. diff --git a/examples/kubernetes/newrelic.sh b/examples/kubernetes/newrelic.sh index f88668ac7d4..9cc2a2d0b96 100755 --- a/examples/kubernetes/newrelic.sh +++ b/examples/kubernetes/newrelic.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2017 Google Inc. +# 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. diff --git a/examples/kubernetes/newrelic_start_agent.sh b/examples/kubernetes/newrelic_start_agent.sh index f68a6b313d6..99b28d1f77f 100755 --- a/examples/kubernetes/newrelic_start_agent.sh +++ b/examples/kubernetes/newrelic_start_agent.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2017 Google Inc. +# 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. diff --git a/examples/kubernetes/newrelic_start_mysql_plugin.sh b/examples/kubernetes/newrelic_start_mysql_plugin.sh index a3a47e147bf..30ab0337401 100755 --- a/examples/kubernetes/newrelic_start_mysql_plugin.sh +++ b/examples/kubernetes/newrelic_start_mysql_plugin.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2017 Google Inc. +# 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. diff --git a/examples/kubernetes/orchestrator-down.sh b/examples/kubernetes/orchestrator-down.sh index eb7b8bf7a1e..7648583d646 100755 --- a/examples/kubernetes/orchestrator-down.sh +++ b/examples/kubernetes/orchestrator-down.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2017 Google Inc. +# 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. diff --git a/examples/kubernetes/orchestrator-up.sh b/examples/kubernetes/orchestrator-up.sh index 17534a21030..af9544bc12c 100755 --- a/examples/kubernetes/orchestrator-up.sh +++ b/examples/kubernetes/orchestrator-up.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2017 Google Inc. +# 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. diff --git a/examples/kubernetes/sharded-vttablet-down.sh b/examples/kubernetes/sharded-vttablet-down.sh index 09b6d907538..9c921dfcb85 100755 --- a/examples/kubernetes/sharded-vttablet-down.sh +++ b/examples/kubernetes/sharded-vttablet-down.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2017 Google Inc. +# 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. diff --git a/examples/kubernetes/sharded-vttablet-up.sh b/examples/kubernetes/sharded-vttablet-up.sh index 6dff9ac51c3..507abfd37bb 100755 --- a/examples/kubernetes/sharded-vttablet-up.sh +++ b/examples/kubernetes/sharded-vttablet-up.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2017 Google Inc. +# 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. diff --git a/examples/kubernetes/sharded-vtworker.sh b/examples/kubernetes/sharded-vtworker.sh index 3d2559122f8..782c8e1c0cb 100755 --- a/examples/kubernetes/sharded-vtworker.sh +++ b/examples/kubernetes/sharded-vtworker.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2017 Google Inc. +# 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. diff --git a/examples/kubernetes/vitess-down.sh b/examples/kubernetes/vitess-down.sh index a303d0297bf..5e26c931234 100755 --- a/examples/kubernetes/vitess-down.sh +++ b/examples/kubernetes/vitess-down.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2017 Google Inc. +# 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. diff --git a/examples/kubernetes/vitess-up.sh b/examples/kubernetes/vitess-up.sh index 28249e748e5..58db653fc8b 100755 --- a/examples/kubernetes/vitess-up.sh +++ b/examples/kubernetes/vitess-up.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2017 Google Inc. +# 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. diff --git a/examples/kubernetes/vtctld-down.sh b/examples/kubernetes/vtctld-down.sh index 9e76b818b5b..a48e803aaf2 100755 --- a/examples/kubernetes/vtctld-down.sh +++ b/examples/kubernetes/vtctld-down.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2017 Google Inc. +# 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. diff --git a/examples/kubernetes/vtctld-up.sh b/examples/kubernetes/vtctld-up.sh index ff381129c10..1e65c6f587d 100755 --- a/examples/kubernetes/vtctld-up.sh +++ b/examples/kubernetes/vtctld-up.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2017 Google Inc. +# 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. diff --git a/examples/kubernetes/vtgate-down.sh b/examples/kubernetes/vtgate-down.sh index 23868fd4c52..96c29c9c33b 100755 --- a/examples/kubernetes/vtgate-down.sh +++ b/examples/kubernetes/vtgate-down.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2017 Google Inc. +# 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. diff --git a/examples/kubernetes/vtgate-up.sh b/examples/kubernetes/vtgate-up.sh index b5c8c8121e4..66ef0667024 100755 --- a/examples/kubernetes/vtgate-up.sh +++ b/examples/kubernetes/vtgate-up.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2017 Google Inc. +# 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. diff --git a/examples/kubernetes/vttablet-down.sh b/examples/kubernetes/vttablet-down.sh index f3281af6720..e3fe9a67b03 100755 --- a/examples/kubernetes/vttablet-down.sh +++ b/examples/kubernetes/vttablet-down.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2017 Google Inc. +# 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. diff --git a/examples/kubernetes/vttablet-up.sh b/examples/kubernetes/vttablet-up.sh index 7ef599f5808..8fbdcfc5ff3 100755 --- a/examples/kubernetes/vttablet-up.sh +++ b/examples/kubernetes/vttablet-up.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2017 Google Inc. +# 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. diff --git a/examples/kubernetes/vtworker-down.sh b/examples/kubernetes/vtworker-down.sh index f8c35b8ab33..d1ab7330b49 100755 --- a/examples/kubernetes/vtworker-down.sh +++ b/examples/kubernetes/vtworker-down.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2017 Google Inc. +# 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. diff --git a/examples/kubernetes/vtworker-up.sh b/examples/kubernetes/vtworker-up.sh index e2085dac5eb..d5cc3e32ccb 100755 --- a/examples/kubernetes/vtworker-up.sh +++ b/examples/kubernetes/vtworker-up.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2017 Google Inc. +# 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. diff --git a/examples/local/101_initial_cluster.sh b/examples/local/101_initial_cluster.sh index 8c254c5bf66..9f018da6b55 100755 --- a/examples/local/101_initial_cluster.sh +++ b/examples/local/101_initial_cluster.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2018 The Vitess Authors. +# 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. @@ -22,6 +22,11 @@ set -e # shellcheck disable=SC2128 script_root=$(dirname "${BASH_SOURCE}") +if [[ $EUID -eq 0 ]]; then + echo "This script refuses to be run as root. Please switch to a regular user." + exit 1 +fi + # start topo server if [ "${TOPO}" = "zk2" ]; then CELL=zone1 "$script_root/zk-up.sh" @@ -34,7 +39,6 @@ CELL=zone1 "$script_root/vtctld-up.sh" # start vttablets for keyspace commerce CELL=zone1 KEYSPACE=commerce UID_BASE=100 "$script_root/vttablet-up.sh" -sleep 15 # set one of the replicas to master ./lvtctl.sh InitShardMaster -force commerce/0 zone1-100 diff --git a/examples/local/201_customer_keyspace.sh b/examples/local/201_customer_keyspace.sh index 210c4eaf5a9..72c415e6527 100755 --- a/examples/local/201_customer_keyspace.sh +++ b/examples/local/201_customer_keyspace.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2018 The Vitess Authors. +# 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. diff --git a/examples/local/202_customer_tablets.sh b/examples/local/202_customer_tablets.sh index 05cc4ff9e6e..9420ba19713 100755 --- a/examples/local/202_customer_tablets.sh +++ b/examples/local/202_customer_tablets.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2018 The Vitess Authors. +# 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. @@ -24,7 +24,7 @@ set -e script_root=$(dirname "${BASH_SOURCE}") CELL=zone1 KEYSPACE=customer UID_BASE=200 "$script_root/vttablet-up.sh" -sleep 15 + ./lvtctl.sh InitShardMaster -force customer/0 zone1-200 ./lvtctl.sh CopySchemaShard -tables customer,corder commerce/0 customer/0 ./lvtctl.sh ApplyVSchema -vschema_file vschema_commerce_vsplit.json commerce diff --git a/examples/local/203_vertical_split.sh b/examples/local/203_vertical_split.sh index 7d00e872c88..99c927dd464 100755 --- a/examples/local/203_vertical_split.sh +++ b/examples/local/203_vertical_split.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2018 The Vitess Authors. +# 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. diff --git a/examples/local/204_vertical_migrate_replicas.sh b/examples/local/204_vertical_migrate_replicas.sh index 3bb6c6dccbf..1e13f62a4b3 100755 --- a/examples/local/204_vertical_migrate_replicas.sh +++ b/examples/local/204_vertical_migrate_replicas.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2018 The Vitess Authors. +# 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. diff --git a/examples/local/205_vertical_migrate_master.sh b/examples/local/205_vertical_migrate_master.sh index 1b42b0cab0d..3aebc52a05c 100755 --- a/examples/local/205_vertical_migrate_master.sh +++ b/examples/local/205_vertical_migrate_master.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2018 The Vitess Authors. +# 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. diff --git a/examples/local/206_clean_commerce.sh b/examples/local/206_clean_commerce.sh index 2aa66b2f91d..6139558c385 100755 --- a/examples/local/206_clean_commerce.sh +++ b/examples/local/206_clean_commerce.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2018 The Vitess Authors. +# 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. diff --git a/examples/local/301_customer_sharded.sh b/examples/local/301_customer_sharded.sh index 2932f5d8776..4d7bacf01d4 100755 --- a/examples/local/301_customer_sharded.sh +++ b/examples/local/301_customer_sharded.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2018 The Vitess Authors. +# 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. diff --git a/examples/local/302_new_shards.sh b/examples/local/302_new_shards.sh index e70c211b847..8475a83f1b2 100755 --- a/examples/local/302_new_shards.sh +++ b/examples/local/302_new_shards.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2018 The Vitess Authors. +# 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. @@ -24,7 +24,7 @@ script_root=$(dirname "${BASH_SOURCE}") SHARD=-80 CELL=zone1 KEYSPACE=customer UID_BASE=300 "$script_root/vttablet-up.sh" SHARD=80- CELL=zone1 KEYSPACE=customer UID_BASE=400 "$script_root/vttablet-up.sh" -sleep 15 + ./lvtctl.sh InitShardMaster -force customer/-80 zone1-300 ./lvtctl.sh InitShardMaster -force customer/80- zone1-400 ./lvtctl.sh CopySchemaShard customer/0 customer/-80 diff --git a/examples/local/303_horizontal_split.sh b/examples/local/303_horizontal_split.sh index 9fb583d9dc1..d53be175c98 100755 --- a/examples/local/303_horizontal_split.sh +++ b/examples/local/303_horizontal_split.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2018 The Vitess Authors. +# 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. diff --git a/examples/local/304_migrate_replicas.sh b/examples/local/304_migrate_replicas.sh index 39c86fe60e2..917d650fdb4 100755 --- a/examples/local/304_migrate_replicas.sh +++ b/examples/local/304_migrate_replicas.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2018 The Vitess Authors. +# 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. diff --git a/examples/local/305_migrate_master.sh b/examples/local/305_migrate_master.sh index f5f1170ebc0..e5ebed81e77 100755 --- a/examples/local/305_migrate_master.sh +++ b/examples/local/305_migrate_master.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2018 The Vitess Authors. +# 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. diff --git a/examples/local/306_down_shard_0.sh b/examples/local/306_down_shard_0.sh index 7b9f589d635..79bdd6f3318 100755 --- a/examples/local/306_down_shard_0.sh +++ b/examples/local/306_down_shard_0.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2018 The Vitess Authors. +# 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. @@ -13,7 +13,6 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. - # this script brings down the tablets for customer/0 keyspace set -e diff --git a/examples/local/307_delete_shard_0.sh b/examples/local/307_delete_shard_0.sh index 284e6aba3ab..6076b0fabbe 100755 --- a/examples/local/307_delete_shard_0.sh +++ b/examples/local/307_delete_shard_0.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2018 The Vitess Authors. +# 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. diff --git a/examples/local/401_teardown.sh b/examples/local/401_teardown.sh index 76431bd684e..b0168ae133d 100755 --- a/examples/local/401_teardown.sh +++ b/examples/local/401_teardown.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2018 The Vitess Authors. +# 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. @@ -14,10 +14,8 @@ # See the License for the specific language governing permissions and # limitations under the License. -# this script brings down zookeeper and all the vitess components -# we brought up in the example -# optionally, you may want to delete everything that was created -# by the example from $VTDATAROOT +# We should not assume that any of the steps have been executed. +# This makes it possible for a user to cleanup at any point. set -e @@ -25,9 +23,11 @@ set -e script_root=$(dirname "${BASH_SOURCE}") ./vtgate-down.sh -CELL=zone1 UID_BASE=100 "$script_root/vttablet-down.sh" -CELL=zone1 UID_BASE=300 "$script_root/vttablet-down.sh" -CELL=zone1 UID_BASE=400 "$script_root/vttablet-down.sh" + +for TABLET in 100 200 300 400; do + ./lvtctl.sh GetTablet zone1-$TABLET >/dev/null 2>&1 && CELL=zone1 UID_BASE=$TABLET "$script_root/vttablet-down.sh" +done; + ./vtctld-down.sh if [ "${TOPO}" = "zk2" ]; then @@ -36,6 +36,20 @@ else CELL=zone1 "$script_root/etcd-down.sh" fi -rm -r $VTDATAROOT/* +# pedantic check: grep for any remaining processes + +if [ ! -z "$VTDATAROOT" ]; then + + if pgrep -f -l "$VTDATAROOT" > /dev/null; then + echo "ERROR: Stale processes detected! It is recommended to manuallly kill them:" + pgrep -f -l "$VTDATAROOT" + else + echo "All good! It looks like every process has shut down" + fi + + # shellcheck disable=SC2086 + rm -r ${VTDATAROOT:?}/* + +fi disown -a diff --git a/examples/local/client.go b/examples/local/client.go index 2267992f5b6..3d97a563f06 100644 --- a/examples/local/client.go +++ b/examples/local/client.go @@ -1,18 +1,18 @@ /* -Copyright 2017 Google Inc. + * 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 + * 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 + * http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto 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. -*/ + * 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. + */ // client.go is a sample for using the Vitess Go SQL driver. // diff --git a/examples/local/client.py b/examples/local/client.py index 1c7e8029b98..1204ce309de 100644 --- a/examples/local/client.py +++ b/examples/local/client.py @@ -1,6 +1,6 @@ #!/usr/bin/env python -# Copyright 2017 Google Inc. +# 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. @@ -21,8 +21,7 @@ It's a script that inserts some random messages on random pages of the guestbook sample app. -Before running this, start up a local example cluster as described in the -README.md file. +Before running this, start up a local example cluster. Then run client.sh, which sets up PYTHONPATH before running client.py: vitess/examples/local$ ./client.sh diff --git a/examples/local/client.sh b/examples/local/client.sh index fd7a6eeb0db..8e1064bb770 100755 --- a/examples/local/client.sh +++ b/examples/local/client.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2017 Google Inc. +# 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. diff --git a/examples/local/client_java.sh b/examples/local/client_java.sh index 7cf5ac91e11..1a87e53f37b 100755 --- a/examples/local/client_java.sh +++ b/examples/local/client_java.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2017 Google Inc. +# 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. diff --git a/examples/local/client_jdbc.sh b/examples/local/client_jdbc.sh index 21b8c2da9ae..720a62fb470 100755 --- a/examples/local/client_jdbc.sh +++ b/examples/local/client_jdbc.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2017 Google Inc. +# 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. diff --git a/examples/local/env.sh b/examples/local/env.sh index 2c84798747f..ef9a0c8538a 100644 --- a/examples/local/env.sh +++ b/examples/local/env.sh @@ -1,12 +1,13 @@ #!/bin/bash -# Copyright 2017 Google Inc. -# + +# 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. @@ -19,11 +20,11 @@ vtctld_web_port=15000 # Set up environment. export VTTOP=${VTTOP-$VTROOT/src/vitess.io/vitess} -# Try to find mysqld_safe on PATH. +# Try to find mysqld on PATH. if [ -z "$VT_MYSQL_ROOT" ]; then - mysql_path=`which mysqld_safe` + mysql_path=`which mysqld` if [ -z "$mysql_path" ]; then - echo "Can't guess location of mysqld_safe. Please set VT_MYSQL_ROOT so it can be found at \$VT_MYSQL_ROOT/bin/mysqld_safe." + echo "Can't guess location of mysqld. Please set VT_MYSQL_ROOT manually." exit 1 fi export VT_MYSQL_ROOT=$(dirname `dirname $mysql_path`) diff --git a/examples/local/etcd-down.sh b/examples/local/etcd-down.sh index 397aca64321..9d05f649c44 100755 --- a/examples/local/etcd-down.sh +++ b/examples/local/etcd-down.sh @@ -1,13 +1,13 @@ #!/bin/bash -# Copyright 2017 Google Inc. -# +# 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. @@ -24,6 +24,6 @@ script_root=$(dirname "${BASH_SOURCE[0]}") # shellcheck disable=SC1091 source "${script_root}/env.sh" -# Stop etcd servers. -echo "Stopping etcd servers..." -kill -9 "$(pgrep -f "${ETCD_BINDIR}/etcd")" +pid=`cat $VTDATAROOT/tmp/etcd.pid` +echo "Stopping etcd..." +kill -9 $pid diff --git a/examples/local/etcd-up.sh b/examples/local/etcd-up.sh index abc09a77723..05d25ab0e28 100755 --- a/examples/local/etcd-up.sh +++ b/examples/local/etcd-up.sh @@ -1,13 +1,13 @@ #!/bin/bash -# Copyright 2017 Google Inc. -# +# 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. @@ -26,6 +26,8 @@ script_root=$(dirname "${BASH_SOURCE[0]}") source "${script_root}/env.sh" ${ETCD_BINDIR}/etcd --data-dir "${VTDATAROOT}/etcd/" --listen-client-urls "http://${ETCD_SERVER}" --advertise-client-urls "http://${ETCD_SERVER}" > "${VTDATAROOT}"/tmp/etcd.out 2>&1 & +PID=$! +echo $PID > "${VTDATAROOT}/tmp/etcd.pid" sleep 5 echo "add /vitess/global" diff --git a/examples/local/lmysql.sh b/examples/local/lmysql.sh index 1382e517b8d..b043ed69b15 100755 --- a/examples/local/lmysql.sh +++ b/examples/local/lmysql.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2018 The Vitess Authors. +# 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. diff --git a/examples/local/lvtctl.sh b/examples/local/lvtctl.sh index 139203e4b82..0197fb79b33 100755 --- a/examples/local/lvtctl.sh +++ b/examples/local/lvtctl.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2017 Google Inc. +# 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. diff --git a/examples/local/topo-etcd2.sh b/examples/local/topo-etcd2.sh index 1423c9c50c0..c61543a806c 100644 --- a/examples/local/topo-etcd2.sh +++ b/examples/local/topo-etcd2.sh @@ -1,5 +1,6 @@ #!/bin/bash -# Copyright 2017 Google Inc. + +# 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. diff --git a/examples/local/topo-zk2.sh b/examples/local/topo-zk2.sh index 268323234a9..29380949d8f 100644 --- a/examples/local/topo-zk2.sh +++ b/examples/local/topo-zk2.sh @@ -1,5 +1,6 @@ #!/bin/bash -# Copyright 2017 Google Inc. + +# 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. diff --git a/examples/local/vtctld-down.sh b/examples/local/vtctld-down.sh index 051c0967b02..398311ca043 100755 --- a/examples/local/vtctld-down.sh +++ b/examples/local/vtctld-down.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2017 Google Inc. +# 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. @@ -23,6 +23,4 @@ source $script_root/env.sh pid=`cat $VTDATAROOT/tmp/vtctld.pid` echo "Stopping vtctld..." -kill $pid - -kill -9 "$(pgrep -f "/bin/vtctld")" +kill -9 $pid diff --git a/examples/local/vtctld-up.sh b/examples/local/vtctld-up.sh index 0fb089718d8..dbd16a8de66 100755 --- a/examples/local/vtctld-up.sh +++ b/examples/local/vtctld-up.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2017 Google Inc. +# 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. diff --git a/examples/local/vtgate-down.sh b/examples/local/vtgate-down.sh index 16e22ed3e0b..d396cceab51 100755 --- a/examples/local/vtgate-down.sh +++ b/examples/local/vtgate-down.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2017 Google Inc. +# 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. diff --git a/examples/local/vtgate-up.sh b/examples/local/vtgate-up.sh index 45bb080e822..4cd155018be 100755 --- a/examples/local/vtgate-up.sh +++ b/examples/local/vtgate-up.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2017 Google Inc. +# 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. @@ -89,6 +89,16 @@ $VTROOT/bin/vtgate \ $optional_tls_args \ > $VTDATAROOT/tmp/vtgate.out 2>&1 & +# Block waiting for vtgate to be listening +# Not the same as healthy + +echo "Waiting for vtgate to be up..." +while true; do + curl -I "http://$hostname:$web_port/debug/status" >/dev/null 2>&1 && break + sleep 0.1 +done; +echo "vtgate is up!" + echo "Access vtgate at http://$hostname:$web_port/debug/status" disown -a diff --git a/examples/local/vttablet-down.sh b/examples/local/vttablet-down.sh index 0a903e5293e..f73f3f4b087 100755 --- a/examples/local/vttablet-down.sh +++ b/examples/local/vttablet-down.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2017 Google Inc. +# 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. diff --git a/examples/local/vttablet-up.sh b/examples/local/vttablet-up.sh index 75c3b191d04..18e56687373 100755 --- a/examples/local/vttablet-up.sh +++ b/examples/local/vttablet-up.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2017 Google Inc. +# 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. @@ -38,11 +38,6 @@ source $script_root/env.sh init_db_sql_file="$VTROOT/config/init_db.sql" -# Previously this file set EXTRA_MY_CNF based on MYSQL_FLAVOR -# It now relies on mysqlctl to autodetect - -export EXTRA_MY_CNF=$VTROOT/config/mycnf/default-fast.cnf:$VTROOT/config/mycnf/rbr.cnf - mkdir -p $VTDATAROOT/backups # Start 3 vttablets by default. @@ -134,4 +129,17 @@ for uid_index in $uids; do echo "Access tablet $alias at http://$hostname:$port/debug/status" done +# Block waiting for all tablets to be listening +# Not the same as healthy + +echo "Waiting for tablets to be listening..." +for uid_index in $uids; do + port=$[$port_base + $uid_index] + while true; do + curl -I "http://$hostname:$port/debug/status" >/dev/null 2>&1 && break + sleep 0.1 + done; +done; +echo "Tablets up!" + disown -a diff --git a/examples/local/vtworker-down.sh b/examples/local/vtworker-down.sh index f7c2dfb6004..0ec047a5638 100755 --- a/examples/local/vtworker-down.sh +++ b/examples/local/vtworker-down.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2017 Google Inc. +# 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. diff --git a/examples/local/vtworker-up.sh b/examples/local/vtworker-up.sh index b13b3dfc48b..520ee89de78 100755 --- a/examples/local/vtworker-up.sh +++ b/examples/local/vtworker-up.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2017 Google Inc. +# 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. diff --git a/examples/local/zk-down.sh b/examples/local/zk-down.sh index a5edc3428af..aa8e29dba4d 100755 --- a/examples/local/zk-down.sh +++ b/examples/local/zk-down.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2017 Google Inc. +# 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. diff --git a/examples/local/zk-up.sh b/examples/local/zk-up.sh index 3cf1bfc97be..76c134583c7 100755 --- a/examples/local/zk-up.sh +++ b/examples/local/zk-up.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2017 Google Inc. +# 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. diff --git a/go.mod b/go.mod new file mode 100644 index 00000000000..ae3b4d9aee4 --- /dev/null +++ b/go.mod @@ -0,0 +1,83 @@ +module vitess.io/vitess + +go 1.12 + +require ( + cloud.google.com/go v0.45.1 + github.com/Bowery/prompt v0.0.0-20190419144237-972d0ceb96f5 // indirect + github.com/armon/go-metrics v0.0.0-20190430140413-ec5e00d3c878 // indirect + github.com/aws/aws-sdk-go v0.0.0-20180223184012-ebef4262e06a + github.com/boltdb/bolt v1.3.1 // indirect + github.com/cockroachdb/cmux v0.0.0-20170110192607-30d10be49292 // indirect + github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd // indirect + github.com/coreos/etcd v0.0.0-20170626015032-703663d1f6ed + github.com/coreos/go-semver v0.3.0 // indirect + github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f // indirect + github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f // indirect + github.com/dchest/safefile v0.0.0-20151022103144-855e8d98f185 // indirect + github.com/dgrijalva/jwt-go v3.2.0+incompatible // indirect + github.com/evanphx/json-patch v4.5.0+incompatible // indirect + github.com/ghodss/yaml v0.0.0-20161207003320-04f313413ffd // indirect + github.com/go-ini/ini v1.12.0 // indirect + github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b + github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6 // indirect + github.com/golang/mock v1.3.1 + github.com/golang/protobuf v1.3.2 + github.com/golang/snappy v0.0.0-20170215233205-553a64147049 + github.com/google/shlex v0.0.0-20181106134648-c34317bd91bf // indirect + github.com/gorilla/websocket v0.0.0-20160912153041-2d1e4548da23 + github.com/grpc-ecosystem/go-grpc-middleware v1.1.0 + github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 + github.com/grpc-ecosystem/grpc-gateway v0.0.0-20161128002007-199c40a060d1 // indirect + github.com/hashicorp/consul v1.4.0 + github.com/hashicorp/go-msgpack v0.5.5 // indirect + github.com/hashicorp/go-rootcerts v0.0.0-20160503143440-6bb64b370b90 // indirect + github.com/hashicorp/go-uuid v1.0.1 // indirect + github.com/hashicorp/golang-lru v0.5.3 // indirect + github.com/hashicorp/memberlist v0.1.4 // indirect + github.com/hashicorp/serf v0.0.0-20161207011743-d3a67ab21bc8 // indirect + github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8 // indirect + github.com/jonboulle/clockwork v0.1.0 // indirect + github.com/klauspost/compress v0.0.0-20180801095237-b50017755d44 // indirect + github.com/klauspost/cpuid v1.2.0 // indirect + github.com/klauspost/crc32 v1.2.0 // indirect + github.com/klauspost/pgzip v1.2.0 + github.com/kr/pretty v0.1.0 // indirect + github.com/krishicks/yaml-patch v0.0.10 // indirect + github.com/mattn/go-runewidth v0.0.1 // indirect + github.com/minio/minio-go v0.0.0-20190131015406-c8a261de75c1 + github.com/mitchellh/go-testing-interface v1.0.0 // indirect + github.com/mitchellh/mapstructure v1.1.2 // indirect + github.com/olekukonko/tablewriter v0.0.0-20160115111002-cca8bbc07984 + github.com/opentracing-contrib/go-grpc v0.0.0-20180928155321-4b5a12d3ff02 + github.com/opentracing/opentracing-go v1.1.0 + github.com/pborman/uuid v0.0.0-20160824210600-b984ec7fa9ff + github.com/prometheus/client_golang v1.1.0 + github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4 // indirect + github.com/prometheus/common v0.7.0 // indirect + github.com/prometheus/procfs v0.0.5 // indirect + github.com/satori/go.uuid v0.0.0-20160713180306-0aa62d5ddceb // indirect + github.com/stretchr/testify v1.4.0 + github.com/tchap/go-patricia v0.0.0-20160729071656-dd168db6051b + github.com/uber-go/atomic v1.4.0 // indirect + github.com/uber/jaeger-client-go v2.16.0+incompatible + github.com/uber/jaeger-lib v2.0.0+incompatible // indirect + github.com/ugorji/go v1.1.7 // indirect + github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 // indirect + github.com/z-division/go-zookeeper v0.0.0-20190128072838-6d7457066b9b + golang.org/x/crypto v0.0.0-20190829043050-9756ffdc2472 + golang.org/x/lint v0.0.0-20190409202823-959b441ac422 + golang.org/x/net v0.0.0-20190926025831-c00fd9afed17 + golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 + golang.org/x/sys v0.0.0-20190926180325-855e68c8590b // indirect + golang.org/x/text v0.3.2 + golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 + golang.org/x/tools v0.0.0-20190830154057-c17b040389b9 + google.golang.org/api v0.9.0 + google.golang.org/genproto v0.0.0-20190926190326-7ee9db18f195 // indirect + google.golang.org/grpc v1.24.0 + gopkg.in/asn1-ber.v1 v1.0.0-20150924051756-4e86f4367175 // indirect + gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect + gopkg.in/ldap.v2 v2.5.0 + honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc +) diff --git a/go.sum b/go.sum new file mode 100644 index 00000000000..ff202019b03 --- /dev/null +++ b/go.sum @@ -0,0 +1,395 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= +cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= +cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= +cloud.google.com/go v0.45.1 h1:lRi0CHyU+ytlvylOlFKKq0af6JncuyoRh1J+QJBqQx0= +cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= +cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= +cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= +github.com/Bowery/prompt v0.0.0-20190419144237-972d0ceb96f5 h1:7tNlRGC3pUEPKS3DwgX5L0s+cBloaq/JBoi9ceN1MCM= +github.com/Bowery/prompt v0.0.0-20190419144237-972d0ceb96f5/go.mod h1:4/6eNcqZ09BZ9wLK3tZOjBA1nDj+B0728nlX5YRlSmQ= +github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/DataDog/datadog-go v2.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= +github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= +github.com/armon/go-metrics v0.0.0-20190430140413-ec5e00d3c878 h1:EFSB7Zo9Eg91v7MJPVsifUysc/wPdN+NOnVe6bWbdBM= +github.com/armon/go-metrics v0.0.0-20190430140413-ec5e00d3c878/go.mod h1:3AMJUQhVx52RsWOnlkpikZr01T/yAVN2gn0861vByNg= +github.com/aws/aws-sdk-go v0.0.0-20180223184012-ebef4262e06a h1:Ed33uJE74ksDaYfdY72gK7Cg//o2FgsqlqUfBW079T8= +github.com/aws/aws-sdk-go v0.0.0-20180223184012-ebef4262e06a/go.mod h1:ZRmQr0FajVIyZ4ZzBYKG5P3ZqPz9IHG41ZoMu1ADI3k= +github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973 h1:xJ4a3vCFaGF/jqvzLMYoU8P317H5OQ+Via4RmuPwCS0= +github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= +github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= +github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/boltdb/bolt v1.3.1 h1:JQmyP4ZBrce+ZQu0dY660FMfatumYDLun9hBCUVIkF4= +github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps= +github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag= +github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cockroachdb/cmux v0.0.0-20170110192607-30d10be49292 h1:dzj1/xcivGjNPwwifh/dWTczkwcuqsXXFHY1X/TZMtw= +github.com/cockroachdb/cmux v0.0.0-20170110192607-30d10be49292/go.mod h1:qRiX68mZX1lGBkTWyp3CLcenw9I94W2dLeRvMzcn9N4= +github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd h1:qMd81Ts1T2OTKmB4acZcyKaMtRnY5Y44NuXGX2GFJ1w= +github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= +github.com/coreos/etcd v0.0.0-20170626015032-703663d1f6ed h1:uycR38QXnpc8YtCCTsNnQfeq6nPQ55F4ld6/WtGAIlM= +github.com/coreos/etcd v0.0.0-20170626015032-703663d1f6ed/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= +github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmfM= +github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f h1:JOrtw2xFKzlg+cbHpyrpLDmnN1HqhBfnX7WDiW7eG2c= +github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f h1:lBNOc5arjvs8E5mO2tbpBpLoyyu8B6e44T7hJy6potg= +github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dchest/safefile v0.0.0-20151022103144-855e8d98f185 h1:3T8ZyTDp5QxTx3NU48JVb2u+75xc040fofcBaN+6jPA= +github.com/dchest/safefile v0.0.0-20151022103144-855e8d98f185/go.mod h1:cFRxtTwTOJkz2x3rQUNCYKWC93yP1VKjR8NUhqFxZNU= +github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM= +github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/evanphx/json-patch v4.5.0+incompatible h1:ouOWdg56aJriqS0huScTkVXPC5IcNrDCXZ6OoTAWu7M= +github.com/evanphx/json-patch v4.5.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/ghodss/yaml v0.0.0-20161207003320-04f313413ffd h1:U3yHrYB7NWH2o3UFzJ1J+TknZqM9QQtF8KVIE6Qzrfs= +github.com/ghodss/yaml v0.0.0-20161207003320-04f313413ffd/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/go-ini/ini v1.12.0 h1:K324HQuOp7fYRWIW84d39Y7MqlH/0JU9fImSXUJ2TWk= +github.com/go-ini/ini v1.12.0/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8= +github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= +github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= +github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6 h1:ZgQEtGgCBiWRM39fZuwSd1LwSqqSW0hOdXCYYDX0R3I= +github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.3.1 h1:qGJ6qTW+x6xX/my+8YUVl4WNpX9B7+/l2tRsHGZ7f2s= +github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/snappy v0.0.0-20170215233205-553a64147049 h1:K9KHZbXKpGydfDN0aZrsoHpLJlZsBrGMFWbgLDGnPZk= +github.com/golang/snappy v0.0.0-20170215233205-553a64147049/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo= +github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPgecwXBIDzw5no= +github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/shlex v0.0.0-20181106134648-c34317bd91bf h1:7+FW5aGwISbqUtkfmIpZJGRgNFg2ioYPvFaUxdqpDsg= +github.com/google/shlex v0.0.0-20181106134648-c34317bd91bf/go.mod h1:RpwtwJQFrIEPstU94h88MWPXP2ektJZ8cZ0YntAmXiE= +github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= +github.com/googleapis/gax-go/v2 v2.0.5 h1:sjZBwGj9Jlw33ImPtvFviGYvseOtDM7hkSKB7+Tv3SM= +github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= +github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e h1:JKmoR8x90Iww1ks85zJ1lfDGgIiMDuIptTOhJq+zKyg= +github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gorilla/websocket v0.0.0-20160912153041-2d1e4548da23 h1:NqeYYy/q+eU5bXzLrVTFSEMp5/VFwp3eJ6nkDsi7wos= +github.com/gorilla/websocket v0.0.0-20160912153041-2d1e4548da23/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/grpc-ecosystem/go-grpc-middleware v1.1.0 h1:THDBEeQ9xZ8JEaCLyLQqXMMdRqNr0QAUJTIkQAUtFjg= +github.com/grpc-ecosystem/go-grpc-middleware v1.1.0/go.mod h1:f5nM7jw/oeRSadq3xCzHAvxcr8HZnzsqU6ILg/0NiiE= +github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho= +github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= +github.com/grpc-ecosystem/grpc-gateway v0.0.0-20161128002007-199c40a060d1 h1:HpW72214zD3cWQsV9DW4Sd9piuuw8rPmE4/TAjTgYIE= +github.com/grpc-ecosystem/grpc-gateway v0.0.0-20161128002007-199c40a060d1/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw= +github.com/hashicorp/consul v1.4.0 h1:PQTW4xCuAExEiSbhrsFsikzbW5gVBoi74BjUvYFyKHw= +github.com/hashicorp/consul v1.4.0/go.mod h1:mFrjN1mfidgJfYP1xrJCF+AfRhr6Eaqhb2+sfyn/OOI= +github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA= +github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-cleanhttp v0.5.0 h1:wvCrVc9TjDls6+YGAF2hAifE1E5U1+b4tH6KdvN3Gig= +github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-immutable-radix v1.0.0 h1:AKDB1HM5PWEA7i4nhcpwOrO2byshxBjXVn/J/3+z5/0= +github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= +github.com/hashicorp/go-msgpack v0.5.5 h1:i9R9JSrqIz0QVLz3sz+i3YJdT7TTSLcfLLzJi9aZTuI= +github.com/hashicorp/go-msgpack v0.5.5/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= +github.com/hashicorp/go-multierror v1.0.0 h1:iVjPR7a6H0tWELX5NxNe7bYopibicUzc7uPribsnS6o= +github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= +github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= +github.com/hashicorp/go-rootcerts v0.0.0-20160503143440-6bb64b370b90 h1:VBj0QYQ0u2MCJzBfeYXGexnAl17GsH1yidnoxCqqD9E= +github.com/hashicorp/go-rootcerts v0.0.0-20160503143440-6bb64b370b90/go.mod h1:o4zcYY1e0GEZI6eSEr+43QDYmuGglw1qSO6qdHUHCgg= +github.com/hashicorp/go-sockaddr v1.0.0 h1:GeH6tui99pF4NJgfnhp+L6+FfobzVW3Ah46sLo0ICXs= +github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= +github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.1 h1:fv1ep09latC32wFoVwnqcnKJGnMSdBanPczbHAYm1BE= +github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.3 h1:YPkqC67at8FYaadspW/6uE0COsBxS2656RLEr8Bppgk= +github.com/hashicorp/golang-lru v0.5.3/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= +github.com/hashicorp/memberlist v0.1.4 h1:gkyML/r71w3FL8gUi74Vk76avkj/9lYAY9lvg0OcoGs= +github.com/hashicorp/memberlist v0.1.4/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= +github.com/hashicorp/serf v0.0.0-20161207011743-d3a67ab21bc8 h1:Vd9tjFEMH3X1AMV1BzVAZRwnjy9MoxOsOl+1pqpCVQs= +github.com/hashicorp/serf v0.0.0-20161207011743-d3a67ab21bc8/go.mod h1:h/Ru6tmZazX7WO/GDmwdpS975F019L4t5ng5IgwbNrE= +github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8 h1:12VvqtR6Aowv3l/EQUlocDHW2Cp4G9WJVH7uyH8QFJE= +github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= +github.com/jonboulle/clockwork v0.1.0 h1:VKV+ZcuP6l3yW9doeqz6ziZGgcynBVQO+obU0+0hcPo= +github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= +github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= +github.com/jtolds/gls v4.2.1+incompatible h1:fSuqC+Gmlu6l/ZYAoZzx2pyucC8Xza35fpRVWLVmUEE= +github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/klauspost/compress v0.0.0-20180801095237-b50017755d44 h1:uDhun+KVSncSm1UeN8A4llsQ6E+xAIBmhh816Q2zeOk= +github.com/klauspost/compress v0.0.0-20180801095237-b50017755d44/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= +github.com/klauspost/cpuid v1.2.0 h1:NMpwD2G9JSFOE1/TJjGSo5zG7Yb2bTe7eq1jH+irmeE= +github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= +github.com/klauspost/crc32 v1.2.0 h1:0VuyqOCruD33/lJ/ojXNvzVyl8Zr5zdTmj9l9qLZ86I= +github.com/klauspost/crc32 v1.2.0/go.mod h1:+ZoRqAPRLkC4NPOvfYeR5KNOrY6TD+/sAC3HXPZgDYg= +github.com/klauspost/pgzip v1.2.0 h1:SPtjjC68wy5g65KwQS4TcYtm6x/O8H4jSxtKZfhN4s0= +github.com/klauspost/pgzip v1.2.0/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= +github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/krishicks/yaml-patch v0.0.10 h1:H4FcHpnNwVmw8u0MjPRjWyIXtco6zM2F78t+57oNM3E= +github.com/krishicks/yaml-patch v0.0.10/go.mod h1:Sm5TchwZS6sm7RJoyg87tzxm2ZcKzdRE4Q7TjNhPrME= +github.com/mattn/go-runewidth v0.0.1 h1:+EiaBVXhogb1Klb4tRJ7hYnuGK6PkKOZlK04D/GMOqk= +github.com/mattn/go-runewidth v0.0.1/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= +github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= +github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/miekg/dns v1.0.14 h1:9jZdLNd/P4+SfEJ0TNyxYpsK8N4GtfylBLqtbYN1sbA= +github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= +github.com/minio/minio-go v0.0.0-20190131015406-c8a261de75c1 h1:jw16EimP5oAEM/2wt+SiEUov/YDyTCTDuPtIKgQIvk0= +github.com/minio/minio-go v0.0.0-20190131015406-c8a261de75c1/go.mod h1:vuvdOZLJuf5HmJAJrKV64MmozrSsk+or0PB5dzdfspg= +github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= +github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-testing-interface v1.0.0 h1:fzU/JVNcaqHQEcVFAKeR41fkiLdIPrefOvVG1VZ96U0= +github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= +github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE= +github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/olekukonko/tablewriter v0.0.0-20160115111002-cca8bbc07984 h1:c9gVtoY8wPlhJIN2V2I1V+Fn9UcXM8mDG8IHv/1c3r8= +github.com/olekukonko/tablewriter v0.0.0-20160115111002-cca8bbc07984/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= +github.com/opentracing-contrib/go-grpc v0.0.0-20180928155321-4b5a12d3ff02 h1:0R5mDLI66Qw13qN80TRz85zthQ2nf2+uDyiV23w6c3Q= +github.com/opentracing-contrib/go-grpc v0.0.0-20180928155321-4b5a12d3ff02/go.mod h1:JNdpVEzCpXBgIiv4ds+TzhN1hrtxq6ClLrTlT9OQRSc= +github.com/opentracing/opentracing-go v1.1.0 h1:pWlfV3Bxv7k65HYwkikxat0+s3pV4bsqf19k25Ur8rU= +github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY= +github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/pborman/uuid v0.0.0-20160824210600-b984ec7fa9ff h1:pTiDfW+iOjIxjZeCm88gKn/AmR09UGZYZdqif2yPRrM= +github.com/pborman/uuid v0.0.0-20160824210600-b984ec7fa9ff/go.mod h1:VyrYX9gd7irzKovcSS6BIIEwPRkP2Wm2m9ufcdFSJ34= +github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v0.9.2 h1:awm861/B8OKDd2I/6o1dy3ra4BamzKhYOiGItCeZ740= +github.com/prometheus/client_golang v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4xf/QclQDMrYNZzcM= +github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= +github.com/prometheus/client_golang v1.1.0 h1:BQ53HtBmfOitExawJ6LokA4x8ov/z0SYYb0+HxJfRI8= +github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g= +github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910 h1:idejC8f05m9MGOsuEi1ATq9shN03HrxNkD/luQvxCv8= +github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4 h1:gQz4mCbXsO+nc9n1hCxHcGA3Zx3Eo+UHZoInFGUIXNM= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/common v0.0.0-20181126121408-4724e9255275 h1:PnBWHBf+6L0jOqq0gIVUe6Yk0/QMZ640k6NvkxcBf+8= +github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= +github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc= +github.com/prometheus/common v0.7.0 h1:L+1lyG48J1zAQXA3RBX/nG/B3gjlHq0zTt2tlbJLyCY= +github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= +github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a h1:9a8MnZMP0X2nLJdBg+pBmGgkJlSaKC2KaQmTCk1XDtE= +github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ= +github.com/prometheus/procfs v0.0.5 h1:3+auTFlqw+ZaQYJARz6ArODtkaIwtvBTx3N2NehQlL8= +github.com/prometheus/procfs v0.0.5/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ= +github.com/satori/go.uuid v0.0.0-20160713180306-0aa62d5ddceb h1:1r/p6yT1FfHR1+qBm7UYBPgfqCmzz/8mpNvfc+iKlfU= +github.com/satori/go.uuid v0.0.0-20160713180306-0aa62d5ddceb/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= +github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUtVbo7ada43DJhG55ua/hjS5I= +github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= +github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/smartystreets/assertions v0.0.0-20190116191733-b6c0e53d7304 h1:Jpy1PXuP99tXNrhbq2BaPz9B+jNAvH1JPQQpG/9GCXY= +github.com/smartystreets/assertions v0.0.0-20190116191733-b6c0e53d7304/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= +github.com/smartystreets/goconvey v0.0.0-20181108003508-044398e4856c h1:Ho+uVpkel/udgjbwB5Lktg9BtvJSh2DT0Hi6LPSyI2w= +github.com/smartystreets/goconvey v0.0.0-20181108003508-044398e4856c/go.mod h1:XDJAKZRPZ1CvBcN2aX5YOUTYGHki24fSF0Iv48Ibg0s= +github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/tchap/go-patricia v0.0.0-20160729071656-dd168db6051b h1:i3lm+BZX5fAaH95wJavMgsSYU95LhSxdNCMa8nLv2gk= +github.com/tchap/go-patricia v0.0.0-20160729071656-dd168db6051b/go.mod h1:bmLyhP68RS6kStMGxByiQ23RP/odRBOTVjwp2cDyi6I= +github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= +github.com/uber-go/atomic v1.4.0 h1:yOuPqEq4ovnhEjpHmfFwsqBXDYbQeT6Nb0bwD6XnD5o= +github.com/uber-go/atomic v1.4.0/go.mod h1:/Ct5t2lcmbJ4OSe/waGBoaVvVqtO0bmtfVNex1PFV8g= +github.com/uber/jaeger-client-go v2.16.0+incompatible h1:Q2Pp6v3QYiocMxomCaJuwQGFt7E53bPYqEgug/AoBtY= +github.com/uber/jaeger-client-go v2.16.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= +github.com/uber/jaeger-lib v2.0.0+incompatible h1:iMSCV0rmXEogjNWPh2D0xk9YVKvrtGoHJNe9ebLu/pw= +github.com/uber/jaeger-lib v2.0.0+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U= +github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo= +github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= +github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs= +github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= +github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 h1:eY9dn8+vbi4tKz5Qo6v2eYzo7kUS51QINcR5jNpbZS8= +github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= +github.com/z-division/go-zookeeper v0.0.0-20190128072838-6d7457066b9b h1:Itr7GbuXoM1PK/eCeNNia4Qd3ib9IgX9g9SpXgo8BwQ= +github.com/z-division/go-zookeeper v0.0.0-20190128072838-6d7457066b9b/go.mod h1:JNALoWa+nCXR8SmgLluHcBNVJgyejzpKPZk9pX2yXXE= +go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= +go.opencensus.io v0.22.0 h1:C9hSCOW830chIVkdja34wa6Ky+IzWllkUinR+BtRZd4= +go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= +go.uber.org/atomic v1.4.0 h1:cxzIVoETapQEqDhQu3QfnvXAV4AlzcvUCxkVUFw3+EU= +go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= +go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190128193316-c7b33c32a30b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190829043050-9756ffdc2472 h1:Gv7RPwsi3eZ2Fgewe3CBsuOebPwO27PoXzRpJPsvSSM= +golang.org/x/crypto v0.0.0-20190829043050-9756ffdc2472/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= +golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190409202823-959b441ac422 h1:QzoH/1pFpZguR8NrRHLcO6jKqfv2zpuSqZLgdm7ZmjI= +golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190926025831-c00fd9afed17 h1:qPnAdmjNA41t3QBTx2mFGf/SD1IoslhYu7AmdsVzCcs= +golang.org/x/net v0.0.0-20190926025831-c00fd9afed17/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0= +golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58 h1:8gQV6CLnAEikrhgkHFbMAEhagSSnXWGV915qUMm9mrU= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190124100055-b90733256f2e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190926180325-855e68c8590b h1:/8GN4qrAmRZQXgjWZHj9z/UJI5vNqQhPtgcw02z2f+8= +golang.org/x/sys v0.0.0-20190926180325-855e68c8590b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 h1:SvFZT6jyqRaOeXpc5h/JSfZenJ2O330aBsf7JfSUXmQ= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190830154057-c17b040389b9 h1:5/jaG/gKlo3xxvUn85ReNyTlN7BvlPPsxC6sHZKjGEE= +golang.org/x/tools v0.0.0-20190830154057-c17b040389b9/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= +google.golang.org/api v0.7.0 h1:9sdfJOzWlkqPltHAuzT2Cp+yrBeY1KRVYgms8soxMwM= +google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= +google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.9.0 h1:jbyannxz0XFD3zdjgrSUsaJbgpH4eTrkdhRChkHPfO8= +google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.6.1 h1:QzqyMA1tlu6CgqCDUtU9V+ZKhLFT2dkJuANu5QaxI3I= +google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64 h1:iKtrH9Y8mcbADOP0YFaEMth7OfuHY9xHOwNj4znpM1A= +google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55 h1:gSJIx1SDwno+2ElGhA4+qG2zF97qiUzTM+rQ0klBOcE= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190926190326-7ee9db18f195 h1:dWzgMaXfaHsnkRKZ1l3iJLDmTEB40JMl/dqRbJX4D/o= +google.golang.org/genproto v0.0.0-20190926190326-7ee9db18f195/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +google.golang.org/grpc v1.21.1 h1:j6XxA85m/6txkUCHvzlV5f+HBNl/1r5cZ2A/3IEFOO8= +google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.24.0 h1:vb/1TCsVn3DcJlQ0Gs1yB1pKI6Do2/QNwxdKqmc/b0s= +google.golang.org/grpc v1.24.0/go.mod h1:XDChyiUovWa60DnaeDeZmSW86xtLtjtZbwvSiRnRtcA= +gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= +gopkg.in/asn1-ber.v1 v1.0.0-20150924051756-4e86f4367175 h1:nn6Zav2sOQHCFJHEspya8KqxhFwKci30UxHy3HXPTyQ= +gopkg.in/asn1-ber.v1 v1.0.0-20150924051756-4e86f4367175/go.mod h1:cuepJuh7vyXfUyUwEgHQXw849cJrilpS5NeIjOWESAw= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/ini.v1 v1.41.0 h1:Ka3ViY6gNYSKiVy71zXBEqKplnV35ImDLVG+8uoIklE= +gopkg.in/ini.v1 v1.41.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/ldap.v2 v2.5.0 h1:1rO3ojzsHUk+gq4ZYhC4Pg+EzWaaKIV8+DJwExS5/QQ= +gopkg.in/ldap.v2 v2.5.0/go.mod h1:oI0cpe/D7HRtBQl8aTg+ZmzFUAvu4lsv3eLXMLGFxWk= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a h1:LJwr7TCTghdatWv40WobzlKXc9c4s8oGa7QKJUtHhWA= +honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc h1:/hemPrYIhOhy8zYrNj+069zDB68us2sMGsfkFJO0iZs= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= diff --git a/go/acl/acl.go b/go/acl/acl.go index 1ea5d245dc7..0d2c070d469 100644 --- a/go/acl/acl.go +++ b/go/acl/acl.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -18,6 +18,21 @@ limitations under the License. // It allows you to register multiple security policies for enforcing // ACLs for users or HTTP requests. The specific policy to use must be // specified from a command line argument and cannot be changed on-the-fly. +// +// For actual authentication and authorization, you would need to implement your +// own policy as a package that calls RegisterPolicy(), and compile it into all +// Vitess binaries that you use. +// +// By default (when no security_policy is specified), everyone is allowed to do +// anything. +// +// For convenience, there are two other built-in policies that also do NOT do +// any authentication, but allow you to globally disable some roles entirely: +// * `deny-all` disallows all roles for everyone. Note that access is still +// allowed to endpoints that are considered "public" (no ACL check at all). +// * `read-only` allows anyone to act as DEBUGGING or MONITORING, but no one +// is allowed to act as ADMIN. It also disallows any other custom roles that +// are requested. package acl import ( @@ -39,7 +54,7 @@ const ( ) var ( - securityPolicy = flag.String("security_policy", "", "security policy to enforce for URLs") + securityPolicy = flag.String("security_policy", "", "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)") policies = make(map[string]Policy) once sync.Once currentPolicy Policy @@ -69,13 +84,16 @@ func RegisterPolicy(name string, policy Policy) { func savePolicy() { if *securityPolicy == "" { + // Setting the policy to nil means Allow All from Anyone. + currentPolicy = nil return } - currentPolicy = policies[*securityPolicy] - if currentPolicy == nil { - log.Warningf("policy %s not found, using fallback policy", *securityPolicy) - currentPolicy = FallbackPolicy{} + if policy, ok := policies[*securityPolicy]; ok { + currentPolicy = policy + return } + log.Warningf("security_policy %q not found; using fallback policy (deny-all)", *securityPolicy) + currentPolicy = denyAllPolicy{} } // CheckAccessActor uses the current security policy to diff --git a/go/acl/acl_test.go b/go/acl/acl_test.go index 614c42bc0f2..680044c1461 100644 --- a/go/acl/acl_test.go +++ b/go/acl/acl_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -40,6 +40,10 @@ func (tp TestPolicy) CheckAccessHTTP(req *http.Request, role string) error { func init() { RegisterPolicy("test", TestPolicy{}) + + // Run the `once` so it doesn't run during testing, + // since we need to override the currentPolicy. + once.Do(savePolicy) } func TestSimplePolicy(t *testing.T) { diff --git a/go/acl/fallback_policy.go b/go/acl/deny_all_policy.go similarity index 61% rename from go/acl/fallback_policy.go rename to go/acl/deny_all_policy.go index e1016d4f52a..4179e25e6ff 100644 --- a/go/acl/fallback_policy.go +++ b/go/acl/deny_all_policy.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -21,19 +21,21 @@ import ( "net/http" ) -var errFallback = errors.New("not allowed: fallback policy") +var errDenyAll = errors.New("not allowed: deny-all security_policy enforced") -// FallbackPolicy is the policy that's used if the -// requested policy cannot be found. It rejects all -// access. -type FallbackPolicy struct{} +// denyAllPolicy rejects all access. +type denyAllPolicy struct{} // CheckAccessActor disallows all actor access. -func (fp FallbackPolicy) CheckAccessActor(actor, role string) error { - return errFallback +func (denyAllPolicy) CheckAccessActor(actor, role string) error { + return errDenyAll } // CheckAccessHTTP disallows all HTTP access. -func (fp FallbackPolicy) CheckAccessHTTP(req *http.Request, role string) error { - return errFallback +func (denyAllPolicy) CheckAccessHTTP(req *http.Request, role string) error { + return errDenyAll +} + +func init() { + RegisterPolicy("deny-all", denyAllPolicy{}) } diff --git a/go/acl/read_only_policy.go b/go/acl/read_only_policy.go new file mode 100644 index 00000000000..e0655242fdf --- /dev/null +++ b/go/acl/read_only_policy.go @@ -0,0 +1,52 @@ +/* +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 acl + +import ( + "errors" + "net/http" +) + +var errReadOnly = errors.New("not allowed: read-only security_policy enforced") + +// readOnlyPolicy allows DEBUGGING and MONITORING roles for everyone, +// while denying any other roles (e.g. ADMIN) for everyone. +type readOnlyPolicy struct{} + +// CheckAccessActor disallows all actor access. +func (readOnlyPolicy) CheckAccessActor(actor, role string) error { + switch role { + case DEBUGGING, MONITORING: + return nil + default: + return errReadOnly + } +} + +// CheckAccessHTTP disallows all HTTP access. +func (readOnlyPolicy) CheckAccessHTTP(req *http.Request, role string) error { + switch role { + case DEBUGGING, MONITORING: + return nil + default: + return errReadOnly + } +} + +func init() { + RegisterPolicy("read-only", readOnlyPolicy{}) +} diff --git a/go/bucketpool/bucketpool_test.go b/go/bucketpool/bucketpool_test.go index 26084e95f27..3d74c3f94ce 100644 --- a/go/bucketpool/bucketpool_test.go +++ b/go/bucketpool/bucketpool_test.go @@ -36,7 +36,7 @@ func TestPool(t *testing.T) { t.Fatalf("unexpected buf length: %d", len(*buf)) } if cap(*buf) != 1024 { - t.Fatalf("unexepected buf cap: %d", cap(*buf)) + t.Fatalf("unexpected buf cap: %d", cap(*buf)) } // get from same pool, check that length is right @@ -45,7 +45,7 @@ func TestPool(t *testing.T) { t.Fatalf("unexpected buf length: %d", len(*buf)) } if cap(*buf) != 1024 { - t.Fatalf("unexepected buf cap: %d", cap(*buf)) + t.Fatalf("unexpected buf cap: %d", cap(*buf)) } pool.Put(buf) @@ -55,7 +55,7 @@ func TestPool(t *testing.T) { t.Fatalf("unexpected buf length: %d", len(*buf)) } if cap(*buf) != 1024 { - t.Fatalf("unexepected buf cap: %d", cap(*buf)) + t.Fatalf("unexpected buf cap: %d", cap(*buf)) } pool.Put(buf) @@ -65,7 +65,7 @@ func TestPool(t *testing.T) { t.Fatalf("unexpected buf length: %d", len(*buf)) } if cap(*buf) != 8192 { - t.Fatalf("unexepected buf cap: %d", cap(*buf)) + t.Fatalf("unexpected buf cap: %d", cap(*buf)) } pool.Put(buf) @@ -75,7 +75,7 @@ func TestPool(t *testing.T) { t.Fatalf("unexpected buf length: %d", len(*buf)) } if cap(*buf) != 16384 { - t.Fatalf("unexepected buf cap: %d", cap(*buf)) + t.Fatalf("unexpected buf cap: %d", cap(*buf)) } pool.Put(buf) @@ -85,7 +85,7 @@ func TestPool(t *testing.T) { t.Fatalf("unexpected buf length: %d", len(*buf)) } if cap(*buf) != 16385 { - t.Fatalf("unexepected buf cap: %d", cap(*buf)) + t.Fatalf("unexpected buf cap: %d", cap(*buf)) } pool.Put(buf) } @@ -101,7 +101,7 @@ func TestPoolOneSize(t *testing.T) { t.Fatalf("unexpected buf length: %d", len(*buf)) } if cap(*buf) != 1024 { - t.Fatalf("unexepected buf cap: %d", cap(*buf)) + t.Fatalf("unexpected buf cap: %d", cap(*buf)) } pool.Put(buf) @@ -110,7 +110,7 @@ func TestPoolOneSize(t *testing.T) { t.Fatalf("unexpected buf length: %d", len(*buf)) } if cap(*buf) != 1025 { - t.Fatalf("unexepected buf cap: %d", cap(*buf)) + t.Fatalf("unexpected buf cap: %d", cap(*buf)) } pool.Put(buf) } @@ -126,7 +126,7 @@ func TestPoolTwoSizeNotMultiplier(t *testing.T) { t.Fatalf("unexpected buf length: %d", len(*buf)) } if cap(*buf) != 1024 { - t.Fatalf("unexepected buf cap: %d", cap(*buf)) + t.Fatalf("unexpected buf cap: %d", cap(*buf)) } pool.Put(buf) @@ -135,7 +135,7 @@ func TestPoolTwoSizeNotMultiplier(t *testing.T) { t.Fatalf("unexpected buf length: %d", len(*buf)) } if cap(*buf) != 2001 { - t.Fatalf("unexepected buf cap: %d", cap(*buf)) + t.Fatalf("unexpected buf cap: %d", cap(*buf)) } pool.Put(buf) } @@ -152,7 +152,7 @@ func TestPoolWeirdMaxSize(t *testing.T) { t.Fatalf("unexpected buf length: %d", len(*buf)) } if cap(*buf) != 15000 { - t.Fatalf("unexepected buf cap: %d", cap(*buf)) + t.Fatalf("unexpected buf cap: %d", cap(*buf)) } pool.Put(buf) @@ -161,7 +161,7 @@ func TestPoolWeirdMaxSize(t *testing.T) { t.Fatalf("unexpected buf length: %d", len(*buf)) } if cap(*buf) != 16383 { - t.Fatalf("unexepected buf cap: %d", cap(*buf)) + t.Fatalf("unexpected buf cap: %d", cap(*buf)) } pool.Put(buf) } diff --git a/go/bytes2/buffer.go b/go/bytes2/buffer.go index 72f8fc6e42a..a7dacf2d04a 100644 --- a/go/bytes2/buffer.go +++ b/go/bytes2/buffer.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/bytes2/buffer_test.go b/go/bytes2/buffer_test.go index 2c44f6a8eab..83cdb346ec9 100644 --- a/go/bytes2/buffer_test.go +++ b/go/bytes2/buffer_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/cache/lru_cache.go b/go/cache/lru_cache.go index 819240ca6f4..cf33235670a 100644 --- a/go/cache/lru_cache.go +++ b/go/cache/lru_cache.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -222,7 +222,7 @@ func (lru *LRUCache) Oldest() (oldest time.Time) { } // Keys returns all the keys for the cache, ordered from most recently -// used to last recently used. +// used to least recently used. func (lru *LRUCache) Keys() []string { lru.mu.Lock() defer lru.mu.Unlock() @@ -235,7 +235,7 @@ func (lru *LRUCache) Keys() []string { } // Items returns all the values for the cache, ordered from most recently -// used to last recently used. +// used to least recently used. func (lru *LRUCache) Items() []Item { lru.mu.Lock() defer lru.mu.Unlock() diff --git a/go/cache/lru_cache_test.go b/go/cache/lru_cache_test.go index cc2c812d0ec..9a7f09232e6 100644 --- a/go/cache/lru_cache_test.go +++ b/go/cache/lru_cache_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/cache/perf_test.go b/go/cache/perf_test.go index 516e6d07926..b5c9a1a8b38 100644 --- a/go/cache/perf_test.go +++ b/go/cache/perf_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/cacheservice/cacheservice.go b/go/cacheservice/cacheservice.go index fe0e48c5e3b..9a7dbcabaec 100644 --- a/go/cacheservice/cacheservice.go +++ b/go/cacheservice/cacheservice.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/cmd/automation_client/automation_client.go b/go/cmd/automation_client/automation_client.go index 1f4b6d965eb..4cea96c83d0 100644 --- a/go/cmd/automation_client/automation_client.go +++ b/go/cmd/automation_client/automation_client.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/cmd/automation_server/automation_server.go b/go/cmd/automation_server/automation_server.go index 21e341d6172..0d0e3aea84a 100644 --- a/go/cmd/automation_server/automation_server.go +++ b/go/cmd/automation_server/automation_server.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -56,5 +56,7 @@ func main() { } scheduler.Run() automationservicepb.RegisterAutomationServer(grpcServer, scheduler) - grpcServer.Serve(listener) + if err := grpcServer.Serve(listener); err != nil { + fmt.Println(err) + } } diff --git a/go/cmd/automation_server/plugin_grpcvtctlclient.go b/go/cmd/automation_server/plugin_grpcvtctlclient.go index 72a36c537b8..6ffff52c5bc 100644 --- a/go/cmd/automation_server/plugin_grpcvtctlclient.go +++ b/go/cmd/automation_server/plugin_grpcvtctlclient.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/cmd/automation_server/plugin_grpcvtworkerclient.go b/go/cmd/automation_server/plugin_grpcvtworkerclient.go index dddaeeae46d..74fa31ef4af 100644 --- a/go/cmd/automation_server/plugin_grpcvtworkerclient.go +++ b/go/cmd/automation_server/plugin_grpcvtworkerclient.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/cmd/mysqlctl/mysqlctl.go b/go/cmd/mysqlctl/mysqlctl.go index 2f39206a003..4e8b0634d29 100644 --- a/go/cmd/mysqlctl/mysqlctl.go +++ b/go/cmd/mysqlctl/mysqlctl.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/cmd/mysqlctl/plugin_prometheusbackend.go b/go/cmd/mysqlctl/plugin_prometheusbackend.go index fa877eabcfe..62853982f11 100644 --- a/go/cmd/mysqlctl/plugin_prometheusbackend.go +++ b/go/cmd/mysqlctl/plugin_prometheusbackend.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Vitess Authors. +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. diff --git a/go/cmd/mysqlctld/mysqlctld.go b/go/cmd/mysqlctld/mysqlctld.go index 5c17ea8131e..85b82f89790 100644 --- a/go/cmd/mysqlctld/mysqlctld.go +++ b/go/cmd/mysqlctld/mysqlctld.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/cmd/mysqlctld/plugin_grpcmysqlctlserver.go b/go/cmd/mysqlctld/plugin_grpcmysqlctlserver.go index 088d1118c10..ee81ab77515 100644 --- a/go/cmd/mysqlctld/plugin_grpcmysqlctlserver.go +++ b/go/cmd/mysqlctld/plugin_grpcmysqlctlserver.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/cmd/mysqlctld/plugin_prometheusbackend.go b/go/cmd/mysqlctld/plugin_prometheusbackend.go index 393208b8017..4ae114ceedd 100644 --- a/go/cmd/mysqlctld/plugin_prometheusbackend.go +++ b/go/cmd/mysqlctld/plugin_prometheusbackend.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Vitess Authors. +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. diff --git a/go/cmd/query_analyzer/query_analyzer.go b/go/cmd/query_analyzer/query_analyzer.go index ecb67da891d..dde5be1cca4 100644 --- a/go/cmd/query_analyzer/query_analyzer.go +++ b/go/cmd/query_analyzer/query_analyzer.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/cmd/tools.go b/go/cmd/tools.go new file mode 100644 index 00000000000..9722dbc267c --- /dev/null +++ b/go/cmd/tools.go @@ -0,0 +1,43 @@ +/* +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 cmd + +import ( + "fmt" + "os" + "os/exec" + "strings" +) + +// DetachFromTerminalAndExit allows a command line program to detach from the terminal and continue running +// even if the parent process is terminated +func DetachFromTerminalAndExit() { + args := os.Args[1:] + i := 0 + for ; i < len(args); i++ { + if strings.HasPrefix(args[i], "-detach") { + args[i] = "-detach=false" + break + } + } + cmd := exec.Command(os.Args[0], args...) + cmd.Stdin = os.Stdin + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + _ = cmd.Start() + fmt.Println("[PID]", cmd.Process.Pid) + os.Exit(0) +} diff --git a/go/cmd/topo2topo/plugin_consultopo.go b/go/cmd/topo2topo/plugin_consultopo.go index 97235405a13..59d6774fdbc 100644 --- a/go/cmd/topo2topo/plugin_consultopo.go +++ b/go/cmd/topo2topo/plugin_consultopo.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/cmd/topo2topo/plugin_etcd2topo.go b/go/cmd/topo2topo/plugin_etcd2topo.go index 46833eb8d7a..d99ef51d4af 100644 --- a/go/cmd/topo2topo/plugin_etcd2topo.go +++ b/go/cmd/topo2topo/plugin_etcd2topo.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/cmd/topo2topo/plugin_zk2topo.go b/go/cmd/topo2topo/plugin_zk2topo.go index 82e91f1a224..62dda455df7 100644 --- a/go/cmd/topo2topo/plugin_zk2topo.go +++ b/go/cmd/topo2topo/plugin_zk2topo.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/cmd/topo2topo/topo2topo.go b/go/cmd/topo2topo/topo2topo.go index 7b25dd6849d..f3f7f731502 100644 --- a/go/cmd/topo2topo/topo2topo.go +++ b/go/cmd/topo2topo/topo2topo.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/cmd/vtaclcheck/vtaclcheck.go b/go/cmd/vtaclcheck/vtaclcheck.go index 6ef80fc8bdb..b6c788599f8 100644 --- a/go/cmd/vtaclcheck/vtaclcheck.go +++ b/go/cmd/vtaclcheck/vtaclcheck.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Vitess Authors +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. diff --git a/go/cmd/vtbackup/vtbackup.go b/go/cmd/vtbackup/vtbackup.go index 690271a0e63..05717c42f87 100644 --- a/go/cmd/vtbackup/vtbackup.go +++ b/go/cmd/vtbackup/vtbackup.go @@ -65,9 +65,12 @@ import ( "math" "math/big" "os" + "os/signal" "strings" + "syscall" "time" + "vitess.io/vitess/go/cmd" "vitess.io/vitess/go/exit" "vitess.io/vitess/go/mysql" "vitess.io/vitess/go/sqlescape" @@ -86,13 +89,18 @@ import ( ) const ( - backupTimestampFormat = "2006-01-02.150405" - manifestFileName = "MANIFEST" + // operationTimeout is the timeout for individual operations like fetching + // the master position. This does not impose an overall timeout on + // long-running processes like taking the backup. It only applies to + // steps along the way that should complete quickly. This ensures we don't + // place a hard cap on the overall time for a backup, while also not waiting + // forever for things that should be quick. + operationTimeout = 1 * time.Minute ) var ( // vtbackup-specific flags - // We used to have timeouts, but these did more harm than good. If a backup + // We used to have overall timeouts, but these did more harm than good. If a backup // has been going for a while, giving up and starting over from scratch is // pretty much never going to help. We should just keep trying and have a // system that alerts a human if it's taking longer than expected. @@ -117,26 +125,39 @@ var ( mysqlSocket = flag.String("mysql_socket", "", "path to the mysql socket") mysqlTimeout = flag.Duration("mysql_timeout", 5*time.Minute, "how long to wait for mysqld startup") initDBSQLFile = flag.String("init_db_sql_file", "", "path to .sql file to run after mysql_install_db") + detachedMode = flag.Bool("detach", false, "detached mode - run backups detached from the terminal") ) func main() { defer exit.Recover() - defer logutil.Flush() - dbconfigs.RegisterFlags(dbconfigs.All...) mysqlctl.RegisterFlags() servenv.ParseFlags("vtbackup") + if *detachedMode { + // this method will call os.Exit and kill this process + cmd.DetachFromTerminalAndExit() + } + + defer logutil.Flush() + if *minRetentionCount < 1 { log.Errorf("min_retention_count must be at least 1 to allow restores to succeed") exit.Return(1) } - ctx := context.Background() + // Catch SIGTERM and SIGINT so we get a chance to clean up. + ctx, cancel := context.WithCancel(context.Background()) + sigChan := make(chan os.Signal, 1) + signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM) + go func() { + sig := <-sigChan + log.Infof("Cancelling due to signal: %v", sig) + cancel() + }() // Open connection backup storage. - backupDir := fmt.Sprintf("%v/%v", *initKeyspace, *initShard) backupStorage, err := backupstorage.GetBackupStorage() if err != nil { log.Errorf("Can't get backup storage: %v", err) @@ -150,13 +171,14 @@ func main() { // Try to take a backup, if it's been long enough since the last one. // Skip pruning if backup wasn't fully successful. We don't want to be // deleting things if the backup process is not healthy. + backupDir := mysqlctl.GetBackupDir(*initKeyspace, *initShard) doBackup, err := shouldBackup(ctx, topoServer, backupStorage, backupDir) if err != nil { log.Errorf("Can't take backup: %v", err) exit.Return(1) } if doBackup { - if err := takeBackup(ctx, topoServer, backupStorage, backupDir); err != nil { + if err := takeBackup(ctx, topoServer, backupStorage); err != nil { log.Errorf("Failed to take backup: %v", err) exit.Return(1) } @@ -169,7 +191,7 @@ func main() { } } -func takeBackup(ctx context.Context, topoServer *topo.Server, backupStorage backupstorage.BackupStorage, backupDir string) error { +func takeBackup(ctx context.Context, topoServer *topo.Server, backupStorage backupstorage.BackupStorage) error { // This is an imaginary tablet alias. The value doesn't matter for anything, // except that we generate a random UID to ensure the target backup // directory is unique if multiple vtbackup instances are launched for the @@ -222,6 +244,17 @@ func takeBackup(ctx context.Context, topoServer *topo.Server, backupStorage back dbName = fmt.Sprintf("vt_%s", *initKeyspace) } + backupParams := mysqlctl.BackupParams{ + Cnf: mycnf, + Mysqld: mysqld, + Logger: logutil.NewConsoleLogger(), + Concurrency: *concurrency, + HookExtraEnv: extraEnv, + TopoServer: topoServer, + Keyspace: *initKeyspace, + Shard: *initShard, + TabletAlias: topoproto.TabletAliasString(tabletAlias), + } // In initial_backup mode, just take a backup of this empty database. if *initialBackup { // Take a backup of this empty DB without restoring anything. @@ -229,26 +262,44 @@ func takeBackup(ctx context.Context, topoServer *topo.Server, backupStorage back // produces a result that can be used to skip InitShardMaster entirely. // This involves resetting replication (to erase any history) and then // creating the main database and some Vitess system tables. - mysqld.ResetReplication(ctx) + if err := mysqld.ResetReplication(ctx); err != nil { + return fmt.Errorf("can't reset replication: %v", err) + } cmds := mysqlctl.CreateReparentJournal() cmds = append(cmds, fmt.Sprintf("CREATE DATABASE IF NOT EXISTS %s", sqlescape.EscapeID(dbName))) if err := mysqld.ExecuteSuperQueryList(ctx, cmds); err != nil { return fmt.Errorf("can't initialize database: %v", err) } + backupParams.BackupTime = time.Now() // Now we're ready to take the backup. - name := backupName(time.Now(), tabletAlias) - if err := mysqlctl.Backup(ctx, mycnf, mysqld, logutil.NewConsoleLogger(), backupDir, name, *concurrency, extraEnv); err != nil { + if err := mysqlctl.Backup(ctx, backupParams); err != nil { return fmt.Errorf("backup failed: %v", err) } log.Info("Initial backup successful.") return nil } + backupDir := mysqlctl.GetBackupDir(*initKeyspace, *initShard) log.Infof("Restoring latest backup from directory %v", backupDir) - restorePos, err := mysqlctl.Restore(ctx, mycnf, mysqld, backupDir, *concurrency, extraEnv, map[string]string{}, logutil.NewConsoleLogger(), true, dbName) + params := mysqlctl.RestoreParams{ + Cnf: mycnf, + Mysqld: mysqld, + Logger: logutil.NewConsoleLogger(), + Concurrency: *concurrency, + HookExtraEnv: extraEnv, + LocalMetadata: map[string]string{}, + DeleteBeforeRestore: true, + DbName: dbName, + Keyspace: *initKeyspace, + Shard: *initShard, + } + backupManifest, err := mysqlctl.Restore(ctx, params) + var restorePos mysql.Position switch err { case nil: log.Infof("Successfully restored from backup at replication position %v", restorePos) + // if err is nil, we expect backupManifest to be non-nil + restorePos = backupManifest.Position case mysqlctl.ErrNoBackup: // There is no backup found, but we may be taking the initial backup of a shard if !*allowFirstBackup { @@ -277,20 +328,37 @@ func takeBackup(ctx context.Context, topoServer *topo.Server, backupStorage back // catch up to live changes, we'd rather take a backup of something rather // than timing out. tmc := tmclient.NewTabletManagerClient() - masterPos, err := getMasterPosition(ctx, tmc, topoServer) + // Keep retrying if we can't contact the master. The master might be + // changing, moving, or down temporarily. + var masterPos mysql.Position + err = retryOnError(ctx, func() error { + // Add a per-operation timeout so we re-read topo if the master is unreachable. + opCtx, cancel := context.WithTimeout(ctx, operationTimeout) + defer cancel() + pos, err := getMasterPosition(opCtx, tmc, topoServer) + if err != nil { + return fmt.Errorf("can't get the master replication position: %v", err) + } + masterPos = pos + return nil + }) if err != nil { - return fmt.Errorf("can't get the master replication position: %v", err) + return err } // Remember the time when we fetched the master position, not when we caught // up to it, so the timestamp on our backup is honest (assuming we make it // to the goal position). - backupTime := time.Now() + backupParams.BackupTime = time.Now() // Wait for replication to catch up. waitStartTime := time.Now() for { - time.Sleep(time.Second) + select { + case <-ctx.Done(): + return ctx.Err() + case <-time.After(time.Second): + } status, statusErr := mysqld.SlaveStatus() if statusErr != nil { @@ -322,8 +390,7 @@ func takeBackup(ctx context.Context, topoServer *topo.Server, backupStorage back } // Now we can take a new backup. - name := backupName(backupTime, tabletAlias) - if err := mysqlctl.Backup(ctx, mycnf, mysqld, logutil.NewConsoleLogger(), backupDir, name, *concurrency, extraEnv); err != nil { + if err := mysqlctl.Backup(ctx, backupParams); err != nil { return fmt.Errorf("error taking backup: %v", err) } @@ -376,8 +443,8 @@ func startReplication(ctx context.Context, mysqld mysqlctl.MysqlDaemon, topoServ return vterrors.Wrapf(err, "Cannot read master tablet %v", si.MasterAlias) } - // Set master and start slave. - if err := mysqld.SetMaster(ctx, topoproto.MysqlHostname(ti.Tablet), int(topoproto.MysqlPort(ti.Tablet)), false /* slaveStopBefore */, true /* slaveStartAfter */); err != nil { + // Stop slave (in case we're restarting), set master, and start slave. + if err := mysqld.SetMaster(ctx, topoproto.MysqlHostname(ti.Tablet), int(topoproto.MysqlPort(ti.Tablet)), true /* slaveStopBefore */, true /* slaveStartAfter */); err != nil { return vterrors.Wrap(err, "MysqlDaemon.SetMaster failed") } return nil @@ -408,8 +475,28 @@ func getMasterPosition(ctx context.Context, tmc tmclient.TabletManagerClient, ts return pos, nil } -func backupName(backupTime time.Time, tabletAlias *topodatapb.TabletAlias) string { - return fmt.Sprintf("%v.%v", backupTime.UTC().Format(backupTimestampFormat), topoproto.TabletAliasString(tabletAlias)) +// retryOnError keeps calling the given function until it succeeds, or the given +// Context is done. It waits an exponentially increasing amount of time between +// retries to avoid hot-looping. The only time this returns an error is if the +// Context is cancelled. +func retryOnError(ctx context.Context, fn func() error) error { + waitTime := 1 * time.Second + + for { + err := fn() + if err == nil { + return nil + } + log.Errorf("Waiting %v to retry after error: %v", waitTime, err) + + select { + case <-ctx.Done(): + log.Errorf("Not retrying after error: %v", ctx.Err()) + return ctx.Err() + case <-time.After(waitTime): + waitTime *= 2 + } + } } func pruneBackups(ctx context.Context, backupStorage backupstorage.BackupStorage, backupDir string) error { @@ -460,7 +547,7 @@ func parseBackupTime(name string) (time.Time, error) { if len(parts) != 3 { return time.Time{}, fmt.Errorf("backup name not in expected format (date.time.tablet-alias): %v", name) } - backupTime, err := time.Parse(backupTimestampFormat, fmt.Sprintf("%s.%s", parts[0], parts[1])) + backupTime, err := time.Parse(mysqlctl.BackupTimestampFormat, fmt.Sprintf("%s.%s", parts[0], parts[1])) if err != nil { return time.Time{}, fmt.Errorf("can't parse timestamp from backup %q: %v", name, err) } @@ -468,13 +555,21 @@ func parseBackupTime(name string) (time.Time, error) { } func shouldBackup(ctx context.Context, topoServer *topo.Server, backupStorage backupstorage.BackupStorage, backupDir string) (bool, error) { + // Look for the most recent, complete backup. backups, err := backupStorage.ListBackups(ctx, backupDir) if err != nil { return false, fmt.Errorf("can't list backups: %v", err) } + lastBackup := lastCompleteBackup(ctx, backups) // Check preconditions for initial_backup mode. if *initialBackup { + // Check if any backups for the shard already exist in this backup storage location. + if lastBackup != nil { + log.Infof("At least one complete backup already exists, so there's no need to seed an empty backup. Doing nothing.") + return false, nil + } + // Check whether the shard exists. _, shardErr := topoServer.GetShard(ctx, *initKeyspace, *initShard) switch { @@ -505,11 +600,6 @@ func shouldBackup(ctx context.Context, topoServer *topo.Server, backupStorage ba return false, fmt.Errorf("failed to check whether shard %v/%v exists before doing initial backup: %v", *initKeyspace, *initShard, err) } - // Check if any backups for the shard exist in this backup storage location. - if len(backups) > 0 { - log.Infof("At least one backup already exists, so there's no need to seed an empty backup. Doing nothing.") - return false, nil - } log.Infof("Shard %v/%v has no existing backups. Creating initial backup.", *initKeyspace, *initShard) return true, nil } @@ -518,8 +608,6 @@ func shouldBackup(ctx context.Context, topoServer *topo.Server, backupStorage ba if len(backups) == 0 && !*allowFirstBackup { return false, fmt.Errorf("no existing backups to restore from; backup is not possible since -initial_backup flag was not enabled") } - // Look for the most recent, complete backup. - lastBackup := lastCompleteBackup(ctx, backups) if lastBackup == nil { if *allowFirstBackup { // There's no complete backup, but we were told to take one from scratch anyway. diff --git a/go/cmd/vtbench/vtbench.go b/go/cmd/vtbench/vtbench.go index 3482995424e..6190b91191c 100644 --- a/go/cmd/vtbench/vtbench.go +++ b/go/cmd/vtbench/vtbench.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Vitess Authors +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. diff --git a/go/cmd/vtclient/plugin_opentracing.go b/go/cmd/vtclient/plugin_opentracing.go index 45d8cfbe349..b48334531a3 100644 --- a/go/cmd/vtclient/plugin_opentracing.go +++ b/go/cmd/vtclient/plugin_opentracing.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Vitess Authors. +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. diff --git a/go/cmd/vtclient/vtclient.go b/go/cmd/vtclient/vtclient.go index 87c6c4dc492..9df55011d97 100644 --- a/go/cmd/vtclient/vtclient.go +++ b/go/cmd/vtclient/vtclient.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/cmd/vtclient/vtclient_test.go b/go/cmd/vtclient/vtclient_test.go index 4b413499565..899f3d1f195 100644 --- a/go/cmd/vtclient/vtclient_test.go +++ b/go/cmd/vtclient/vtclient_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/cmd/vtcombo/main.go b/go/cmd/vtcombo/main.go index f92181861f4..117a6893f09 100644 --- a/go/cmd/vtcombo/main.go +++ b/go/cmd/vtcombo/main.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/cmd/vtcombo/plugin_grpcvtctlserver.go b/go/cmd/vtcombo/plugin_grpcvtctlserver.go index c31cb6f8048..4ec5323b075 100644 --- a/go/cmd/vtcombo/plugin_grpcvtctlserver.go +++ b/go/cmd/vtcombo/plugin_grpcvtctlserver.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/cmd/vtcombo/plugin_grpcvtgateservice.go b/go/cmd/vtcombo/plugin_grpcvtgateservice.go index 73d97eeb2e0..4ee159710ca 100644 --- a/go/cmd/vtcombo/plugin_grpcvtgateservice.go +++ b/go/cmd/vtcombo/plugin_grpcvtgateservice.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/cmd/vtcombo/plugin_opentracing.go b/go/cmd/vtcombo/plugin_opentracing.go index 4ce46a60395..c2ea8325e6a 100644 --- a/go/cmd/vtcombo/plugin_opentracing.go +++ b/go/cmd/vtcombo/plugin_opentracing.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Vitess Authors. +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. diff --git a/go/cmd/vtctl/plugin_cephbackupstorage.go b/go/cmd/vtctl/plugin_cephbackupstorage.go index 8957be34335..6cd2d5619d0 100644 --- a/go/cmd/vtctl/plugin_cephbackupstorage.go +++ b/go/cmd/vtctl/plugin_cephbackupstorage.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/cmd/vtctl/plugin_filebackupstorage.go b/go/cmd/vtctl/plugin_filebackupstorage.go index 38725c0b6ee..cf2ceb5150f 100644 --- a/go/cmd/vtctl/plugin_filebackupstorage.go +++ b/go/cmd/vtctl/plugin_filebackupstorage.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/cmd/vtctl/plugin_gcsbackupstorage.go b/go/cmd/vtctl/plugin_gcsbackupstorage.go index cd569aafb9a..82a22cef1da 100644 --- a/go/cmd/vtctl/plugin_gcsbackupstorage.go +++ b/go/cmd/vtctl/plugin_gcsbackupstorage.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/cmd/vtctl/plugin_grpctabletconn.go b/go/cmd/vtctl/plugin_grpctabletconn.go index e32dc0181ad..08291a7c916 100644 --- a/go/cmd/vtctl/plugin_grpctabletconn.go +++ b/go/cmd/vtctl/plugin_grpctabletconn.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/cmd/vtctl/plugin_grpcthrottlerclient.go b/go/cmd/vtctl/plugin_grpcthrottlerclient.go index 55d134b5827..871eb8e80b5 100644 --- a/go/cmd/vtctl/plugin_grpcthrottlerclient.go +++ b/go/cmd/vtctl/plugin_grpcthrottlerclient.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/cmd/vtctl/plugin_grpctmclient.go b/go/cmd/vtctl/plugin_grpctmclient.go index 7b93f9f1467..ce554da96df 100644 --- a/go/cmd/vtctl/plugin_grpctmclient.go +++ b/go/cmd/vtctl/plugin_grpctmclient.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/cmd/vtctl/plugin_grpcvtgateconn.go b/go/cmd/vtctl/plugin_grpcvtgateconn.go index f30fec4905a..87019ea4260 100644 --- a/go/cmd/vtctl/plugin_grpcvtgateconn.go +++ b/go/cmd/vtctl/plugin_grpcvtgateconn.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/cmd/vtctl/plugin_s3backupstorage.go b/go/cmd/vtctl/plugin_s3backupstorage.go index cf85e6e24e0..a5b5c671ebb 100644 --- a/go/cmd/vtctl/plugin_s3backupstorage.go +++ b/go/cmd/vtctl/plugin_s3backupstorage.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/cmd/vtctl/vtctl.go b/go/cmd/vtctl/vtctl.go index 8365b9c0ab4..3229d8f148d 100644 --- a/go/cmd/vtctl/vtctl.go +++ b/go/cmd/vtctl/vtctl.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -26,6 +26,8 @@ import ( "syscall" "time" + "vitess.io/vitess/go/cmd" + "golang.org/x/net/context" "vitess.io/vitess/go/exit" "vitess.io/vitess/go/trace" @@ -40,7 +42,8 @@ import ( ) var ( - waitTime = flag.Duration("wait-time", 24*time.Hour, "time to wait on an action") + waitTime = flag.Duration("wait-time", 24*time.Hour, "time to wait on an action") + detachedMode = flag.Bool("detach", false, "detached mode - run vtcl detached from the terminal") ) func init() { @@ -70,6 +73,11 @@ func main() { defer exit.RecoverAll() defer logutil.Flush() + if *detachedMode { + // this method will call os.Exit and kill this process + cmd.DetachFromTerminalAndExit() + } + args := servenv.ParseFlagsWithArgs("vtctl") action := args[0] diff --git a/go/cmd/vtctlclient/main.go b/go/cmd/vtctlclient/main.go index f9369632657..4d2fcbee368 100644 --- a/go/cmd/vtctlclient/main.go +++ b/go/cmd/vtctlclient/main.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/cmd/vtctlclient/plugin_grpcvtctlclient.go b/go/cmd/vtctlclient/plugin_grpcvtctlclient.go index 72a36c537b8..6ffff52c5bc 100644 --- a/go/cmd/vtctlclient/plugin_grpcvtctlclient.go +++ b/go/cmd/vtctlclient/plugin_grpcvtctlclient.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/cmd/vtctld/main.go b/go/cmd/vtctld/main.go index ea9be066c8d..82c80a53dba 100644 --- a/go/cmd/vtctld/main.go +++ b/go/cmd/vtctld/main.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/cmd/vtctld/plugin_cephbackupstorage.go b/go/cmd/vtctld/plugin_cephbackupstorage.go index 8957be34335..6cd2d5619d0 100644 --- a/go/cmd/vtctld/plugin_cephbackupstorage.go +++ b/go/cmd/vtctld/plugin_cephbackupstorage.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/cmd/vtctld/plugin_consultopo.go b/go/cmd/vtctld/plugin_consultopo.go index eb9a6778d08..a0c53abe5ea 100644 --- a/go/cmd/vtctld/plugin_consultopo.go +++ b/go/cmd/vtctld/plugin_consultopo.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/cmd/vtctld/plugin_etcd2topo.go b/go/cmd/vtctld/plugin_etcd2topo.go index 893a92b6380..6ec507f910d 100644 --- a/go/cmd/vtctld/plugin_etcd2topo.go +++ b/go/cmd/vtctld/plugin_etcd2topo.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/cmd/vtctld/plugin_filebackupstorage.go b/go/cmd/vtctld/plugin_filebackupstorage.go index 38725c0b6ee..cf2ceb5150f 100644 --- a/go/cmd/vtctld/plugin_filebackupstorage.go +++ b/go/cmd/vtctld/plugin_filebackupstorage.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/cmd/vtctld/plugin_gcsbackupstorage.go b/go/cmd/vtctld/plugin_gcsbackupstorage.go index cd569aafb9a..82a22cef1da 100644 --- a/go/cmd/vtctld/plugin_gcsbackupstorage.go +++ b/go/cmd/vtctld/plugin_gcsbackupstorage.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/cmd/vtctld/plugin_grpctabletconn.go b/go/cmd/vtctld/plugin_grpctabletconn.go index e32dc0181ad..08291a7c916 100644 --- a/go/cmd/vtctld/plugin_grpctabletconn.go +++ b/go/cmd/vtctld/plugin_grpctabletconn.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/cmd/vtctld/plugin_grpcthrottlerclient.go b/go/cmd/vtctld/plugin_grpcthrottlerclient.go index 55d134b5827..871eb8e80b5 100644 --- a/go/cmd/vtctld/plugin_grpcthrottlerclient.go +++ b/go/cmd/vtctld/plugin_grpcthrottlerclient.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/cmd/vtctld/plugin_grpctmclient.go b/go/cmd/vtctld/plugin_grpctmclient.go index 7b93f9f1467..ce554da96df 100644 --- a/go/cmd/vtctld/plugin_grpctmclient.go +++ b/go/cmd/vtctld/plugin_grpctmclient.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/cmd/vtctld/plugin_grpcvtctlserver.go b/go/cmd/vtctld/plugin_grpcvtctlserver.go index c31cb6f8048..4ec5323b075 100644 --- a/go/cmd/vtctld/plugin_grpcvtctlserver.go +++ b/go/cmd/vtctld/plugin_grpcvtctlserver.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/cmd/vtctld/plugin_grpcvtgateconn.go b/go/cmd/vtctld/plugin_grpcvtgateconn.go index f30fec4905a..87019ea4260 100644 --- a/go/cmd/vtctld/plugin_grpcvtgateconn.go +++ b/go/cmd/vtctld/plugin_grpcvtgateconn.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/cmd/vtctld/plugin_grpcvtworkerclient.go b/go/cmd/vtctld/plugin_grpcvtworkerclient.go index dddaeeae46d..74fa31ef4af 100644 --- a/go/cmd/vtctld/plugin_grpcvtworkerclient.go +++ b/go/cmd/vtctld/plugin_grpcvtworkerclient.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/cmd/vtctld/plugin_opentracing.go b/go/cmd/vtctld/plugin_opentracing.go index 829102c0b7a..c35034d42a2 100644 --- a/go/cmd/vtctld/plugin_opentracing.go +++ b/go/cmd/vtctld/plugin_opentracing.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Vitess Authors. +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. diff --git a/go/cmd/vtctld/plugin_opentsdb.go b/go/cmd/vtctld/plugin_opentsdb.go index 3986ee9b209..38f464dd887 100644 --- a/go/cmd/vtctld/plugin_opentsdb.go +++ b/go/cmd/vtctld/plugin_opentsdb.go @@ -1,3 +1,19 @@ +/* +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 main // This plugin imports opentsdb to register the opentsdb stats backend. diff --git a/go/cmd/vtctld/plugin_prometheusbackend.go b/go/cmd/vtctld/plugin_prometheusbackend.go index e8f86bcc1d4..f3c33e5637b 100644 --- a/go/cmd/vtctld/plugin_prometheusbackend.go +++ b/go/cmd/vtctld/plugin_prometheusbackend.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Vitess Authors. +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. diff --git a/go/cmd/vtctld/plugin_s3backupstorage.go b/go/cmd/vtctld/plugin_s3backupstorage.go index cf85e6e24e0..a5b5c671ebb 100644 --- a/go/cmd/vtctld/plugin_s3backupstorage.go +++ b/go/cmd/vtctld/plugin_s3backupstorage.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/cmd/vtctld/plugin_zk2topo.go b/go/cmd/vtctld/plugin_zk2topo.go index 0f5c83c74c8..531d92c4cdd 100644 --- a/go/cmd/vtctld/plugin_zk2topo.go +++ b/go/cmd/vtctld/plugin_zk2topo.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/cmd/vtctld/schema.go b/go/cmd/vtctld/schema.go index 3268e2de1cc..5f508d6e129 100644 --- a/go/cmd/vtctld/schema.go +++ b/go/cmd/vtctld/schema.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/cmd/vtexplain/vtexplain.go b/go/cmd/vtexplain/vtexplain.go index 50dde581071..3d1edb16519 100644 --- a/go/cmd/vtexplain/vtexplain.go +++ b/go/cmd/vtexplain/vtexplain.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/cmd/vtgate/index.go b/go/cmd/vtgate/index.go index 72b2637abf0..be06ed6f10b 100644 --- a/go/cmd/vtgate/index.go +++ b/go/cmd/vtgate/index.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/cmd/vtgate/plugin_auth_clientcert.go b/go/cmd/vtgate/plugin_auth_clientcert.go index 0070d58cf2f..4f3d65ef626 100644 --- a/go/cmd/vtgate/plugin_auth_clientcert.go +++ b/go/cmd/vtgate/plugin_auth_clientcert.go @@ -1,3 +1,19 @@ +/* +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 main // This plugin imports clientcert to register the client certificate implementation of AuthServer. diff --git a/go/cmd/vtgate/plugin_auth_ldap.go b/go/cmd/vtgate/plugin_auth_ldap.go index 0c0b4595463..257f0742733 100644 --- a/go/cmd/vtgate/plugin_auth_ldap.go +++ b/go/cmd/vtgate/plugin_auth_ldap.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/cmd/vtgate/plugin_auth_static.go b/go/cmd/vtgate/plugin_auth_static.go index 5567bf68392..8e4a552cecf 100644 --- a/go/cmd/vtgate/plugin_auth_static.go +++ b/go/cmd/vtgate/plugin_auth_static.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/cmd/vtgate/plugin_consultopo.go b/go/cmd/vtgate/plugin_consultopo.go index 97235405a13..59d6774fdbc 100644 --- a/go/cmd/vtgate/plugin_consultopo.go +++ b/go/cmd/vtgate/plugin_consultopo.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/cmd/vtgate/plugin_etcd2topo.go b/go/cmd/vtgate/plugin_etcd2topo.go index 46833eb8d7a..d99ef51d4af 100644 --- a/go/cmd/vtgate/plugin_etcd2topo.go +++ b/go/cmd/vtgate/plugin_etcd2topo.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/cmd/vtgate/plugin_grpctabletconn.go b/go/cmd/vtgate/plugin_grpctabletconn.go index e32dc0181ad..08291a7c916 100644 --- a/go/cmd/vtgate/plugin_grpctabletconn.go +++ b/go/cmd/vtgate/plugin_grpctabletconn.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/cmd/vtgate/plugin_grpcvtgateservice.go b/go/cmd/vtgate/plugin_grpcvtgateservice.go index 73d97eeb2e0..4ee159710ca 100644 --- a/go/cmd/vtgate/plugin_grpcvtgateservice.go +++ b/go/cmd/vtgate/plugin_grpcvtgateservice.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/cmd/vtgate/plugin_opentracing.go b/go/cmd/vtgate/plugin_opentracing.go index 4792375731e..9a6786d3d64 100644 --- a/go/cmd/vtgate/plugin_opentracing.go +++ b/go/cmd/vtgate/plugin_opentracing.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Vitess Authors. +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. diff --git a/go/cmd/vtgate/plugin_opentsdb.go b/go/cmd/vtgate/plugin_opentsdb.go index e98b97d3d93..0988f3b9a64 100644 --- a/go/cmd/vtgate/plugin_opentsdb.go +++ b/go/cmd/vtgate/plugin_opentsdb.go @@ -1,3 +1,19 @@ +/* +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 main // This plugin imports opentsdb to register the opentsdb stats backend. diff --git a/go/cmd/vtgate/plugin_prometheusbackend.go b/go/cmd/vtgate/plugin_prometheusbackend.go index 529f959f39d..6bffd133332 100644 --- a/go/cmd/vtgate/plugin_prometheusbackend.go +++ b/go/cmd/vtgate/plugin_prometheusbackend.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Vitess Authors. +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. diff --git a/go/cmd/vtgate/plugin_zk2topo.go b/go/cmd/vtgate/plugin_zk2topo.go index 82e91f1a224..d75a1c6bcb4 100644 --- a/go/cmd/vtgate/plugin_zk2topo.go +++ b/go/cmd/vtgate/plugin_zk2topo.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/cmd/vtgate/status.go b/go/cmd/vtgate/status.go index 0c6cad84bb0..0aa168e06d3 100644 --- a/go/cmd/vtgate/status.go +++ b/go/cmd/vtgate/status.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/cmd/vtgate/vtgate.go b/go/cmd/vtgate/vtgate.go index 2a3aa9445d3..ad8148fe429 100644 --- a/go/cmd/vtgate/vtgate.go +++ b/go/cmd/vtgate/vtgate.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/cmd/vtgateclienttest/goclienttest/callerid.go b/go/cmd/vtgateclienttest/goclienttest/callerid.go index 8a236d2d96f..e46ec5e5a92 100644 --- a/go/cmd/vtgateclienttest/goclienttest/callerid.go +++ b/go/cmd/vtgateclienttest/goclienttest/callerid.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/cmd/vtgateclienttest/goclienttest/echo.go b/go/cmd/vtgateclienttest/goclienttest/echo.go index 2c13d2ee625..ba1faef39f6 100644 --- a/go/cmd/vtgateclienttest/goclienttest/echo.go +++ b/go/cmd/vtgateclienttest/goclienttest/echo.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/cmd/vtgateclienttest/goclienttest/errors.go b/go/cmd/vtgateclienttest/goclienttest/errors.go index 809aa2c96e8..ec989698eb4 100644 --- a/go/cmd/vtgateclienttest/goclienttest/errors.go +++ b/go/cmd/vtgateclienttest/goclienttest/errors.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/cmd/vtgateclienttest/goclienttest/main.go b/go/cmd/vtgateclienttest/goclienttest/main.go index e09d0bd9ba3..ab33a400164 100644 --- a/go/cmd/vtgateclienttest/goclienttest/main.go +++ b/go/cmd/vtgateclienttest/goclienttest/main.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/cmd/vtgateclienttest/goclienttest/success.go b/go/cmd/vtgateclienttest/goclienttest/success.go index ade71ba7545..5bbe7439aa6 100644 --- a/go/cmd/vtgateclienttest/goclienttest/success.go +++ b/go/cmd/vtgateclienttest/goclienttest/success.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/cmd/vtgateclienttest/grpcclienttest/grpc_goclient_test.go b/go/cmd/vtgateclienttest/grpcclienttest/grpc_goclient_test.go index 9f7922cfb25..f9ef8110ec9 100644 --- a/go/cmd/vtgateclienttest/grpcclienttest/grpc_goclient_test.go +++ b/go/cmd/vtgateclienttest/grpcclienttest/grpc_goclient_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/cmd/vtgateclienttest/grpcclienttest/import.go b/go/cmd/vtgateclienttest/grpcclienttest/import.go index e608cf32a19..b0bccb047f8 100644 --- a/go/cmd/vtgateclienttest/grpcclienttest/import.go +++ b/go/cmd/vtgateclienttest/grpcclienttest/import.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/cmd/vtgateclienttest/main.go b/go/cmd/vtgateclienttest/main.go index efeba1182af..c97068a8886 100644 --- a/go/cmd/vtgateclienttest/main.go +++ b/go/cmd/vtgateclienttest/main.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/cmd/vtgateclienttest/plugin_grpcvtgateservice.go b/go/cmd/vtgateclienttest/plugin_grpcvtgateservice.go index 73d97eeb2e0..4ee159710ca 100644 --- a/go/cmd/vtgateclienttest/plugin_grpcvtgateservice.go +++ b/go/cmd/vtgateclienttest/plugin_grpcvtgateservice.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/cmd/vtgateclienttest/services/callerid.go b/go/cmd/vtgateclienttest/services/callerid.go index 567aedeb64b..746c6c697b3 100644 --- a/go/cmd/vtgateclienttest/services/callerid.go +++ b/go/cmd/vtgateclienttest/services/callerid.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/cmd/vtgateclienttest/services/echo.go b/go/cmd/vtgateclienttest/services/echo.go index ce7604124a9..f0b175d3d7e 100644 --- a/go/cmd/vtgateclienttest/services/echo.go +++ b/go/cmd/vtgateclienttest/services/echo.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -401,23 +401,23 @@ func (c *echoClient) VStream(ctx context.Context, tabletType topodatapb.TabletTy if strings.HasPrefix(vgtid.ShardGtids[0].Shard, EchoPrefix) { _ = callback([]*binlogdatapb.VEvent{ { - Type: 1, + Type: 1, Timestamp: 1234, - Gtid: "echo-gtid-1", - Ddl: "echo-ddl-1", - Vgtid: vgtid, + Gtid: "echo-gtid-1", + Ddl: "echo-ddl-1", + Vgtid: vgtid, RowEvent: &binlogdatapb.RowEvent{ - TableName:"echo-table-1", + TableName: "echo-table-1", }, }, { - Type: 2, + Type: 2, Timestamp: 4321, - Gtid: "echo-gtid-2", - Ddl: "echo-ddl-2", - Vgtid: vgtid, + Gtid: "echo-gtid-2", + Ddl: "echo-ddl-2", + Vgtid: vgtid, FieldEvent: &binlogdatapb.FieldEvent{ - TableName:"echo-table-2", + TableName: "echo-table-2", }, }, }) diff --git a/go/cmd/vtgateclienttest/services/errors.go b/go/cmd/vtgateclienttest/services/errors.go index f1fdda62bec..4d82fbc83b7 100644 --- a/go/cmd/vtgateclienttest/services/errors.go +++ b/go/cmd/vtgateclienttest/services/errors.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/cmd/vtgateclienttest/services/fallback.go b/go/cmd/vtgateclienttest/services/fallback.go index bbf37ff1022..ca895a0942f 100644 --- a/go/cmd/vtgateclienttest/services/fallback.go +++ b/go/cmd/vtgateclienttest/services/fallback.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/cmd/vtgateclienttest/services/services.go b/go/cmd/vtgateclienttest/services/services.go index 9cf9d5a34c6..f43c1456741 100644 --- a/go/cmd/vtgateclienttest/services/services.go +++ b/go/cmd/vtgateclienttest/services/services.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/cmd/vtgateclienttest/services/success.go b/go/cmd/vtgateclienttest/services/success.go index 0216136bba3..0a78cbdde5d 100644 --- a/go/cmd/vtgateclienttest/services/success.go +++ b/go/cmd/vtgateclienttest/services/success.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/cmd/vtgateclienttest/services/terminal.go b/go/cmd/vtgateclienttest/services/terminal.go index 483f4556cea..7d828c79a38 100644 --- a/go/cmd/vtgateclienttest/services/terminal.go +++ b/go/cmd/vtgateclienttest/services/terminal.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/cmd/vtqueryserver/index.go b/go/cmd/vtqueryserver/index.go index 72b2637abf0..be06ed6f10b 100644 --- a/go/cmd/vtqueryserver/index.go +++ b/go/cmd/vtqueryserver/index.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/cmd/vtqueryserver/plugin_auth_static.go b/go/cmd/vtqueryserver/plugin_auth_static.go index 3b5555f07d8..84cdec6cec0 100644 --- a/go/cmd/vtqueryserver/plugin_auth_static.go +++ b/go/cmd/vtqueryserver/plugin_auth_static.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/cmd/vtqueryserver/plugin_grpcqueryservice.go b/go/cmd/vtqueryserver/plugin_grpcqueryservice.go index 60478f80ad7..0d574f33a5f 100644 --- a/go/cmd/vtqueryserver/plugin_grpcqueryservice.go +++ b/go/cmd/vtqueryserver/plugin_grpcqueryservice.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -24,7 +24,6 @@ import ( "vitess.io/vitess/go/vt/vttablet/tabletserver" ) - func init() { tabletserver.RegisterFunctions = append(tabletserver.RegisterFunctions, func(qsc tabletserver.Controller) { if servenv.GRPCCheckServiceMap("queryservice") { diff --git a/go/cmd/vtqueryserver/plugin_opentracing.go b/go/cmd/vtqueryserver/plugin_opentracing.go index f619214f70e..43cdf6ce589 100644 --- a/go/cmd/vtqueryserver/plugin_opentracing.go +++ b/go/cmd/vtqueryserver/plugin_opentracing.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Vitess Authors. +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. diff --git a/go/cmd/vtqueryserver/vtqueryserver.go b/go/cmd/vtqueryserver/vtqueryserver.go index 2dcb629a60d..705c2bc9c38 100644 --- a/go/cmd/vtqueryserver/vtqueryserver.go +++ b/go/cmd/vtqueryserver/vtqueryserver.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/cmd/vttablet/healthz.go b/go/cmd/vttablet/healthz.go index b38918c1328..09bc92ef748 100644 --- a/go/cmd/vttablet/healthz.go +++ b/go/cmd/vttablet/healthz.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/cmd/vttablet/index.go b/go/cmd/vttablet/index.go index 72b2637abf0..be06ed6f10b 100644 --- a/go/cmd/vttablet/index.go +++ b/go/cmd/vttablet/index.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/cmd/vttablet/plugin_cephbackupstorage.go b/go/cmd/vttablet/plugin_cephbackupstorage.go index 8957be34335..6cd2d5619d0 100644 --- a/go/cmd/vttablet/plugin_cephbackupstorage.go +++ b/go/cmd/vttablet/plugin_cephbackupstorage.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/cmd/vttablet/plugin_consultopo.go b/go/cmd/vttablet/plugin_consultopo.go index 97235405a13..59d6774fdbc 100644 --- a/go/cmd/vttablet/plugin_consultopo.go +++ b/go/cmd/vttablet/plugin_consultopo.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/cmd/vttablet/plugin_etcd2topo.go b/go/cmd/vttablet/plugin_etcd2topo.go index 46833eb8d7a..d99ef51d4af 100644 --- a/go/cmd/vttablet/plugin_etcd2topo.go +++ b/go/cmd/vttablet/plugin_etcd2topo.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/cmd/vttablet/plugin_filebackupstorage.go b/go/cmd/vttablet/plugin_filebackupstorage.go index 38725c0b6ee..cf2ceb5150f 100644 --- a/go/cmd/vttablet/plugin_filebackupstorage.go +++ b/go/cmd/vttablet/plugin_filebackupstorage.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/cmd/vttablet/plugin_filecustomrule.go b/go/cmd/vttablet/plugin_filecustomrule.go index 9c2d5fc3a28..854c484d3c1 100644 --- a/go/cmd/vttablet/plugin_filecustomrule.go +++ b/go/cmd/vttablet/plugin_filecustomrule.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/cmd/vttablet/plugin_filelogger.go b/go/cmd/vttablet/plugin_filelogger.go index b6cd9dca433..bc5d968d2f7 100644 --- a/go/cmd/vttablet/plugin_filelogger.go +++ b/go/cmd/vttablet/plugin_filelogger.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/cmd/vttablet/plugin_gcsbackupstorage.go b/go/cmd/vttablet/plugin_gcsbackupstorage.go index cd569aafb9a..82a22cef1da 100644 --- a/go/cmd/vttablet/plugin_gcsbackupstorage.go +++ b/go/cmd/vttablet/plugin_gcsbackupstorage.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/cmd/vttablet/plugin_grpcbinlogplayer.go b/go/cmd/vttablet/plugin_grpcbinlogplayer.go index b89e2eec012..f8b2380c7c7 100644 --- a/go/cmd/vttablet/plugin_grpcbinlogplayer.go +++ b/go/cmd/vttablet/plugin_grpcbinlogplayer.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/cmd/vttablet/plugin_grpcbinlogstreamer.go b/go/cmd/vttablet/plugin_grpcbinlogstreamer.go index f9806f019e5..26683ea7ccf 100644 --- a/go/cmd/vttablet/plugin_grpcbinlogstreamer.go +++ b/go/cmd/vttablet/plugin_grpcbinlogstreamer.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/cmd/vttablet/plugin_grpcqueryservice.go b/go/cmd/vttablet/plugin_grpcqueryservice.go index 110f69234a6..073c2009151 100644 --- a/go/cmd/vttablet/plugin_grpcqueryservice.go +++ b/go/cmd/vttablet/plugin_grpcqueryservice.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/cmd/vttablet/plugin_grpctabletconn.go b/go/cmd/vttablet/plugin_grpctabletconn.go index e32dc0181ad..08291a7c916 100644 --- a/go/cmd/vttablet/plugin_grpctabletconn.go +++ b/go/cmd/vttablet/plugin_grpctabletconn.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/cmd/vttablet/plugin_grpcthrottlerserver.go b/go/cmd/vttablet/plugin_grpcthrottlerserver.go index c81c64d19d8..40cce4bd51c 100644 --- a/go/cmd/vttablet/plugin_grpcthrottlerserver.go +++ b/go/cmd/vttablet/plugin_grpcthrottlerserver.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/cmd/vttablet/plugin_grpctmclient.go b/go/cmd/vttablet/plugin_grpctmclient.go index 7b93f9f1467..ce554da96df 100644 --- a/go/cmd/vttablet/plugin_grpctmclient.go +++ b/go/cmd/vttablet/plugin_grpctmclient.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/cmd/vttablet/plugin_grpctmserver.go b/go/cmd/vttablet/plugin_grpctmserver.go index 8b70762cbec..094d273fe39 100644 --- a/go/cmd/vttablet/plugin_grpctmserver.go +++ b/go/cmd/vttablet/plugin_grpctmserver.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/cmd/vttablet/plugin_opentracing.go b/go/cmd/vttablet/plugin_opentracing.go index d42d3d81a13..942bb25c895 100644 --- a/go/cmd/vttablet/plugin_opentracing.go +++ b/go/cmd/vttablet/plugin_opentracing.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Vitess Authors. +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. diff --git a/go/cmd/vttablet/plugin_opentsdb.go b/go/cmd/vttablet/plugin_opentsdb.go index 659a15600df..494dbbee20d 100644 --- a/go/cmd/vttablet/plugin_opentsdb.go +++ b/go/cmd/vttablet/plugin_opentsdb.go @@ -1,3 +1,19 @@ +/* +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 main // This plugin imports opentsdb to register the opentsdb stats backend. diff --git a/go/cmd/vttablet/plugin_prometheusbackend.go b/go/cmd/vttablet/plugin_prometheusbackend.go index 7f8a5dc9f2b..4066b5ba6ec 100644 --- a/go/cmd/vttablet/plugin_prometheusbackend.go +++ b/go/cmd/vttablet/plugin_prometheusbackend.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Vitess Authors. +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. diff --git a/go/cmd/vttablet/plugin_s3backupstorage.go b/go/cmd/vttablet/plugin_s3backupstorage.go index cf85e6e24e0..a5b5c671ebb 100644 --- a/go/cmd/vttablet/plugin_s3backupstorage.go +++ b/go/cmd/vttablet/plugin_s3backupstorage.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/cmd/vttablet/plugin_sysloglogger.go b/go/cmd/vttablet/plugin_sysloglogger.go index c72acb1fd36..4c57ad006c3 100644 --- a/go/cmd/vttablet/plugin_sysloglogger.go +++ b/go/cmd/vttablet/plugin_sysloglogger.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/cmd/vttablet/plugin_topocustomrule.go b/go/cmd/vttablet/plugin_topocustomrule.go index d95d99c1961..cef81458155 100644 --- a/go/cmd/vttablet/plugin_topocustomrule.go +++ b/go/cmd/vttablet/plugin_topocustomrule.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/cmd/vttablet/plugin_zk2topo.go b/go/cmd/vttablet/plugin_zk2topo.go index c75a764c432..ebf385ec1af 100644 --- a/go/cmd/vttablet/plugin_zk2topo.go +++ b/go/cmd/vttablet/plugin_zk2topo.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/cmd/vttablet/status.go b/go/cmd/vttablet/status.go index 850904d8afb..fa183bad5ed 100644 --- a/go/cmd/vttablet/status.go +++ b/go/cmd/vttablet/status.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/cmd/vttablet/vttablet.go b/go/cmd/vttablet/vttablet.go index 76493fc881a..837bc49fc89 100644 --- a/go/cmd/vttablet/vttablet.go +++ b/go/cmd/vttablet/vttablet.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/cmd/vttestserver/main.go b/go/cmd/vttestserver/main.go index e6280af194e..f2fd647a18f 100644 --- a/go/cmd/vttestserver/main.go +++ b/go/cmd/vttestserver/main.go @@ -1,3 +1,19 @@ +/* +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. +*/ + // vttestserver is a native Go implementation of `run_local_server.py`. // It allows users to spawn a self-contained Vitess server for local testing/CI package main @@ -154,6 +170,8 @@ func parseFlags() (config vttest.Config, env vttest.Environment, err error) { flag.StringVar(&config.TabletHostName, "tablet_hostname", "localhost", "The hostname to use for the tablet otherwise it will be derived from OS' hostname") + flag.BoolVar(&config.InitWorkflowManager, "workflow_manager_init", false, "Enable workflow manager") + flag.Parse() if basePort != 0 { diff --git a/go/cmd/vttestserver/vttestserver_test.go b/go/cmd/vttestserver/vttestserver_test.go index 79d246efbfa..2e4b4cec91e 100644 --- a/go/cmd/vttestserver/vttestserver_test.go +++ b/go/cmd/vttestserver/vttestserver_test.go @@ -1,3 +1,19 @@ +/* +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 main import ( diff --git a/go/cmd/vttlstest/vttlstest.go b/go/cmd/vttlstest/vttlstest.go index 856be6f49b8..95bfe15c32e 100644 --- a/go/cmd/vttlstest/vttlstest.go +++ b/go/cmd/vttlstest/vttlstest.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/cmd/vtworker/plugin_consultopo.go b/go/cmd/vtworker/plugin_consultopo.go index 97235405a13..59d6774fdbc 100644 --- a/go/cmd/vtworker/plugin_consultopo.go +++ b/go/cmd/vtworker/plugin_consultopo.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/cmd/vtworker/plugin_etcd2topo.go b/go/cmd/vtworker/plugin_etcd2topo.go index 46833eb8d7a..d99ef51d4af 100644 --- a/go/cmd/vtworker/plugin_etcd2topo.go +++ b/go/cmd/vtworker/plugin_etcd2topo.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/cmd/vtworker/plugin_grpctabletconn.go b/go/cmd/vtworker/plugin_grpctabletconn.go index e32dc0181ad..08291a7c916 100644 --- a/go/cmd/vtworker/plugin_grpctabletconn.go +++ b/go/cmd/vtworker/plugin_grpctabletconn.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/cmd/vtworker/plugin_grpcthrottlerserver.go b/go/cmd/vtworker/plugin_grpcthrottlerserver.go index c81c64d19d8..40cce4bd51c 100644 --- a/go/cmd/vtworker/plugin_grpcthrottlerserver.go +++ b/go/cmd/vtworker/plugin_grpcthrottlerserver.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/cmd/vtworker/plugin_grpctmclient.go b/go/cmd/vtworker/plugin_grpctmclient.go index 7b93f9f1467..ce554da96df 100644 --- a/go/cmd/vtworker/plugin_grpctmclient.go +++ b/go/cmd/vtworker/plugin_grpctmclient.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/cmd/vtworker/plugin_grpcvtworkerserver.go b/go/cmd/vtworker/plugin_grpcvtworkerserver.go index 3d0f0115566..20bfd13e9dc 100644 --- a/go/cmd/vtworker/plugin_grpcvtworkerserver.go +++ b/go/cmd/vtworker/plugin_grpcvtworkerserver.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/cmd/vtworker/plugin_opentracing.go b/go/cmd/vtworker/plugin_opentracing.go index 6fd4d9b28dd..f023721be22 100644 --- a/go/cmd/vtworker/plugin_opentracing.go +++ b/go/cmd/vtworker/plugin_opentracing.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Vitess Authors. +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. diff --git a/go/cmd/vtworker/plugin_opentsdb.go b/go/cmd/vtworker/plugin_opentsdb.go index 7c5fb40fc6d..1157cc18f32 100644 --- a/go/cmd/vtworker/plugin_opentsdb.go +++ b/go/cmd/vtworker/plugin_opentsdb.go @@ -1,3 +1,19 @@ +/* +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 main // This plugin imports opentsdb to register the opentsdb stats backend. diff --git a/go/cmd/vtworker/plugin_prometheusbackend.go b/go/cmd/vtworker/plugin_prometheusbackend.go index 27e045b734a..85efd13430e 100644 --- a/go/cmd/vtworker/plugin_prometheusbackend.go +++ b/go/cmd/vtworker/plugin_prometheusbackend.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Vitess Authors. +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. diff --git a/go/cmd/vtworker/plugin_zk2topo.go b/go/cmd/vtworker/plugin_zk2topo.go index c75a764c432..ebf385ec1af 100644 --- a/go/cmd/vtworker/plugin_zk2topo.go +++ b/go/cmd/vtworker/plugin_zk2topo.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/cmd/vtworker/vtworker.go b/go/cmd/vtworker/vtworker.go index c190ff01828..491240443eb 100644 --- a/go/cmd/vtworker/vtworker.go +++ b/go/cmd/vtworker/vtworker.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/cmd/vtworkerclient/plugin_grpcvtworkerclient.go b/go/cmd/vtworkerclient/plugin_grpcvtworkerclient.go index dddaeeae46d..74fa31ef4af 100644 --- a/go/cmd/vtworkerclient/plugin_grpcvtworkerclient.go +++ b/go/cmd/vtworkerclient/plugin_grpcvtworkerclient.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/cmd/vtworkerclient/vtworkerclient.go b/go/cmd/vtworkerclient/vtworkerclient.go index 0e1874453ba..3520f1228a4 100644 --- a/go/cmd/vtworkerclient/vtworkerclient.go +++ b/go/cmd/vtworkerclient/vtworkerclient.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/cmd/zk/zkcmd.go b/go/cmd/zk/zkcmd.go index c6cf45e6b53..67a34773573 100644 --- a/go/cmd/zk/zkcmd.go +++ b/go/cmd/zk/zkcmd.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/cmd/zkctl/zkctl.go b/go/cmd/zkctl/zkctl.go index 57c0750cc29..7e19fd079d2 100644 --- a/go/cmd/zkctl/zkctl.go +++ b/go/cmd/zkctl/zkctl.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/cmd/zkctld/zkctld.go b/go/cmd/zkctld/zkctld.go index e0d198e1ffe..674a6b2d464 100644 --- a/go/cmd/zkctld/zkctld.go +++ b/go/cmd/zkctld/zkctld.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/event/event.go b/go/event/event.go index eb95d49dbd3..27f3cd5d7c0 100644 --- a/go/event/event.go +++ b/go/event/event.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/event/event_test.go b/go/event/event_test.go index 9230e9de9a3..25b42d84a80 100644 --- a/go/event/event_test.go +++ b/go/event/event_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -80,7 +80,7 @@ func TestInterfaceListener(t *testing.T) { triggered := false AddListener(func(testInterface1) { triggered = true }) - AddListener(func(testInterface2) { t.Errorf("interface listener triggerd on non-matching type") }) + AddListener(func(testInterface2) { t.Errorf("interface listener triggered on non-matching type") }) Dispatch(testEvent1{}) if !triggered { diff --git a/go/event/hooks.go b/go/event/hooks.go index b9ad14eb23b..1de4908931f 100644 --- a/go/event/hooks.go +++ b/go/event/hooks.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/event/hooks_test.go b/go/event/hooks_test.go index 254bde7ad18..197dd59a062 100644 --- a/go/event/hooks_test.go +++ b/go/event/hooks_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/event/syslogger/syslogger.go b/go/event/syslogger/syslogger.go index 356b5dd18d5..2c26fee0839 100644 --- a/go/event/syslogger/syslogger.go +++ b/go/event/syslogger/syslogger.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/event/syslogger/syslogger_test.go b/go/event/syslogger/syslogger_test.go index 7180b62604d..111335d41f5 100644 --- a/go/event/syslogger/syslogger_test.go +++ b/go/event/syslogger/syslogger_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/exit/exit.go b/go/exit/exit.go index 195f6580af1..f0e1c97b308 100644 --- a/go/exit/exit.go +++ b/go/exit/exit.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/exit/exit_test.go b/go/exit/exit_test.go index d1132933525..e51a0938534 100644 --- a/go/exit/exit_test.go +++ b/go/exit/exit_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/fileutil/wildcards.go b/go/fileutil/wildcards.go index 4da5365b76a..f9b5667f10a 100644 --- a/go/fileutil/wildcards.go +++ b/go/fileutil/wildcards.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/fileutil/wildcards_test.go b/go/fileutil/wildcards_test.go index a5e011ab0e7..9d332a507db 100644 --- a/go/fileutil/wildcards_test.go +++ b/go/fileutil/wildcards_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/flagutil/flagutil.go b/go/flagutil/flagutil.go index cd04635530a..0b9a449cccf 100644 --- a/go/flagutil/flagutil.go +++ b/go/flagutil/flagutil.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/flagutil/flagutil_test.go b/go/flagutil/flagutil_test.go index 1ae0521a3be..dc0205452f0 100644 --- a/go/flagutil/flagutil_test.go +++ b/go/flagutil/flagutil_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/hack/hack.go b/go/hack/hack.go index 763a180a99b..0ae22575553 100644 --- a/go/hack/hack.go +++ b/go/hack/hack.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/hack/hack_test.go b/go/hack/hack_test.go index d34bb8d2301..862d6bbdde5 100644 --- a/go/hack/hack_test.go +++ b/go/hack/hack_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/history/history.go b/go/history/history.go index 580ab8f6f80..0b942b48f82 100644 --- a/go/history/history.go +++ b/go/history/history.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/history/history_test.go b/go/history/history_test.go index 459123686c4..1b4272553e5 100644 --- a/go/history/history_test.go +++ b/go/history/history_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/ioutil2/ioutil.go b/go/ioutil2/ioutil.go index 21e64294d6b..0b40ea97df6 100644 --- a/go/ioutil2/ioutil.go +++ b/go/ioutil2/ioutil.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/ioutil2/ioutil_test.go b/go/ioutil2/ioutil_test.go index f36f56ef742..664157ff9b2 100644 --- a/go/ioutil2/ioutil_test.go +++ b/go/ioutil2/ioutil_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/json2/marshal.go b/go/json2/marshal.go index 6e981aa5d13..763860b730e 100644 --- a/go/json2/marshal.go +++ b/go/json2/marshal.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/json2/marshal_test.go b/go/json2/marshal_test.go index b8318262c65..cf6841472b3 100644 --- a/go/json2/marshal_test.go +++ b/go/json2/marshal_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/json2/unmarshal.go b/go/json2/unmarshal.go index 5d4992067dd..10584cbaae0 100644 --- a/go/json2/unmarshal.go +++ b/go/json2/unmarshal.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/json2/unmarshal_test.go b/go/json2/unmarshal_test.go index cc8c26e1c81..28a317631f0 100644 --- a/go/json2/unmarshal_test.go +++ b/go/json2/unmarshal_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/jsonutil/json.go b/go/jsonutil/json.go index 2df81a4547b..9c84831b72a 100644 --- a/go/jsonutil/json.go +++ b/go/jsonutil/json.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/memcache/memcache.go b/go/memcache/memcache.go index 3ee2666295c..f645ac80d5f 100644 --- a/go/memcache/memcache.go +++ b/go/memcache/memcache.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/memcache/memcache_test.go b/go/memcache/memcache_test.go index 1449b62051b..a6a50c5e334 100644 --- a/go/memcache/memcache_test.go +++ b/go/memcache/memcache_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/mysql/auth_server.go b/go/mysql/auth_server.go index 91fefbc4893..5df328e1896 100644 --- a/go/mysql/auth_server.go +++ b/go/mysql/auth_server.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/mysql/auth_server_clientcert.go b/go/mysql/auth_server_clientcert.go index 957dd8f494d..e860248efb4 100644 --- a/go/mysql/auth_server_clientcert.go +++ b/go/mysql/auth_server_clientcert.go @@ -1,3 +1,19 @@ +/* +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 mysql import ( diff --git a/go/mysql/auth_server_clientcert_test.go b/go/mysql/auth_server_clientcert_test.go index 81b54d99c11..b812211e784 100644 --- a/go/mysql/auth_server_clientcert_test.go +++ b/go/mysql/auth_server_clientcert_test.go @@ -1,3 +1,19 @@ +/* +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 mysql import ( diff --git a/go/mysql/auth_server_none.go b/go/mysql/auth_server_none.go index b0da00f2763..c560238303b 100644 --- a/go/mysql/auth_server_none.go +++ b/go/mysql/auth_server_none.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/mysql/auth_server_static.go b/go/mysql/auth_server_static.go index e4052e9d38a..cad9cb0573e 100644 --- a/go/mysql/auth_server_static.go +++ b/go/mysql/auth_server_static.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/mysql/auth_server_static_test.go b/go/mysql/auth_server_static_test.go index 327e37bd2f6..eda98ec3ae5 100644 --- a/go/mysql/auth_server_static_test.go +++ b/go/mysql/auth_server_static_test.go @@ -1,5 +1,5 @@ /* -copyright 2017 google inc. +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. @@ -7,7 +7,7 @@ you may obtain a copy of the license at http://www.apache.org/licenses/license-2.0 -unless required by applicable law or agreedto in writing, software +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 diff --git a/go/mysql/binlog_event.go b/go/mysql/binlog_event.go index dd0faa17c9d..014fbc3a62e 100644 --- a/go/mysql/binlog_event.go +++ b/go/mysql/binlog_event.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 @@ -120,7 +120,7 @@ type BinlogEvent interface { // the same event and a nil checksum. StripChecksum(BinlogFormat) (ev BinlogEvent, checksum []byte, err error) - // IsPseudo is for custom implemetations of GTID. + // IsPseudo is for custom implementations of GTID. IsPseudo() bool } diff --git a/go/mysql/binlog_event_common.go b/go/mysql/binlog_event_common.go index 7ee90036d7c..e9f022e0b28 100644 --- a/go/mysql/binlog_event_common.go +++ b/go/mysql/binlog_event_common.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/mysql/binlog_event_common_test.go b/go/mysql/binlog_event_common_test.go index 9007b45a633..939ea441f46 100644 --- a/go/mysql/binlog_event_common_test.go +++ b/go/mysql/binlog_event_common_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/mysql/binlog_event_json.go b/go/mysql/binlog_event_json.go index a14e18188b7..ae42b7e09e4 100644 --- a/go/mysql/binlog_event_json.go +++ b/go/mysql/binlog_event_json.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/mysql/binlog_event_json_test.go b/go/mysql/binlog_event_json_test.go index d9bff262609..ab7ce5efd1e 100644 --- a/go/mysql/binlog_event_json_test.go +++ b/go/mysql/binlog_event_json_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/mysql/binlog_event_make.go b/go/mysql/binlog_event_make.go index 07149079a43..3df5f3fb59d 100644 --- a/go/mysql/binlog_event_make.go +++ b/go/mysql/binlog_event_make.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/mysql/binlog_event_make_test.go b/go/mysql/binlog_event_make_test.go index e2b1ebe56d5..040a0ac77c3 100644 --- a/go/mysql/binlog_event_make_test.go +++ b/go/mysql/binlog_event_make_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/mysql/binlog_event_mariadb.go b/go/mysql/binlog_event_mariadb.go index 7b7548c520d..6e62ac7fb2b 100644 --- a/go/mysql/binlog_event_mariadb.go +++ b/go/mysql/binlog_event_mariadb.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/mysql/binlog_event_mariadb_test.go b/go/mysql/binlog_event_mariadb_test.go index f8286644844..e94820e1624 100644 --- a/go/mysql/binlog_event_mariadb_test.go +++ b/go/mysql/binlog_event_mariadb_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/mysql/binlog_event_mysql56.go b/go/mysql/binlog_event_mysql56.go index c83c196bb09..b957b79c301 100644 --- a/go/mysql/binlog_event_mysql56.go +++ b/go/mysql/binlog_event_mysql56.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/mysql/binlog_event_mysql56_test.go b/go/mysql/binlog_event_mysql56_test.go index b4cd6a05a6a..3e3dd6e88f9 100644 --- a/go/mysql/binlog_event_mysql56_test.go +++ b/go/mysql/binlog_event_mysql56_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/mysql/binlog_event_rbr.go b/go/mysql/binlog_event_rbr.go index 2d12ffc52c9..e29e3f0fabe 100644 --- a/go/mysql/binlog_event_rbr.go +++ b/go/mysql/binlog_event_rbr.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 @@ -94,7 +94,7 @@ func (ev binlogEvent) TableMap(f BinlogFormat) (*TableMap, error) { return nil, vterrors.Errorf(vtrpc.Code_INTERNAL, "unexpected metadata end: got %v was expecting %v (data=%v)", pos, expectedEnd, data) } - // A bit array that says if each colum can be NULL. + // A bit array that says if each column can be NULL. result.CanBeNull, _ = newBitmap(data, pos, columnCount) return result, nil diff --git a/go/mysql/binlog_event_rbr_test.go b/go/mysql/binlog_event_rbr_test.go index 3b7d814b3fc..7d651f38d30 100644 --- a/go/mysql/binlog_event_rbr_test.go +++ b/go/mysql/binlog_event_rbr_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/mysql/binlog_event_test.go b/go/mysql/binlog_event_test.go index 220f2d5909b..3a35b958f9c 100644 --- a/go/mysql/binlog_event_test.go +++ b/go/mysql/binlog_event_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/mysql/charset.go b/go/mysql/charset.go index 8c211385646..61a23cf750e 100644 --- a/go/mysql/charset.go +++ b/go/mysql/charset.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/mysql/client.go b/go/mysql/client.go index 34dcacbc0f2..d91a6fbbbce 100644 --- a/go/mysql/client.go +++ b/go/mysql/client.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 @@ -373,6 +373,16 @@ func (c *Conn) parseInitialHandshakePacket(data []byte) (uint32, []byte, error) if !ok { return 0, nil, NewSQLError(CRVersionError, SSUnknownSQLState, "parseInitialHandshakePacket: packet has no protocol version") } + + // Server is allowed to immediately send ERR packet + if pver == ErrPacket { + errorCode, pos, _ := readUint16(data, pos) + // Normally there would be a 1-byte sql_state_marker field and a 5-byte + // sql_state field here, but docs say these will not be present in this case. + errorMsg, pos, _ := readEOFString(data, pos) + return 0, nil, NewSQLError(CRServerHandshakeErr, SSUnknownSQLState, "immediate error from server errorCode=%v errorMsg=%v", errorCode, errorMsg) + } + if pver != protocolVersion { return 0, nil, NewSQLError(CRVersionError, SSUnknownSQLState, "bad protocol version: %v", pver) } @@ -615,7 +625,7 @@ func (c *Conn) writeHandshakeResponse41(capabilities uint32, scrambledPassword [ // DbName, only if server supports it. if params.DbName != "" && (capabilities&CapabilityClientConnectWithDB != 0) { pos = writeNullString(data, pos, params.DbName) - c.SchemaName = params.DbName + c.schemaName = params.DbName } // Assume native client during response diff --git a/go/mysql/client_test.go b/go/mysql/client_test.go index 13d25073eea..624a470baf4 100644 --- a/go/mysql/client_test.go +++ b/go/mysql/client_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/mysql/conn.go b/go/mysql/conn.go index 42b8215c86c..0d51867bd06 100644 --- a/go/mysql/conn.go +++ b/go/mysql/conn.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 @@ -110,10 +110,12 @@ type Conn struct { // It is set during the initial handshake. UserData Getter - // SchemaName is the default database name to use. It is set + // schemaName is the default database name to use. It is set // during handshake, and by ComInitDb packets. Both client and - // servers maintain it. - SchemaName string + // servers maintain it. This member is private because it's + // non-authoritative: the client can change the schema name + // through the 'USE' statement, which will bypass this variable. + schemaName string // ServerVersion is set during Connect with the server // version. It is not changed afterwards. It is unused for @@ -255,7 +257,7 @@ func (c *Conn) readHeaderFrom(r io.Reader) (int, error) { // Note io.ReadFull will return two different types of errors: // 1. if the socket is already closed, and the go runtime knows it, // then ReadFull will return an error (different than EOF), - // someting like 'read: connection reset by peer'. + // something like 'read: connection reset by peer'. // 2. if the socket is not closed while we start the read, // but gets closed after the read is started, we'll get io.EOF. if _, err := io.ReadFull(r, header[:]); err != nil { @@ -731,7 +733,8 @@ func (c *Conn) handleNextCommand(handler Handler) error { case ComInitDB: db := c.parseComInitDB(data) c.recycleReadPacket() - c.SchemaName = db + c.schemaName = db + handler.ComInitDB(c, db) if err := c.writeOKPacket(0, 0, c.StatusFlags, 0); err != nil { log.Errorf("Error writing ComInitDB result to %s: %v", c, err) return err @@ -1038,6 +1041,18 @@ func (c *Conn) handleNextCommand(handler Handler) error { log.Error("Error writing ComStmtReset OK packet to client %v: %v", c.ConnectionID, err) return err } + + case ComResetConnection: + // Clean up and reset the connection + c.recycleReadPacket() + handler.ComResetConnection(c) + // Reset prepared statements + c.PrepareData = make(map[uint32]*PrepareData) + err = c.writeOKPacket(0, 0, 0, 0) + if err != nil { + c.writeErrorPacketFromError(err) + } + default: log.Errorf("Got unhandled packet (default) from %s, returning error: %v", c, data) c.recycleReadPacket() diff --git a/go/mysql/conn_params.go b/go/mysql/conn_params.go index 5af81b1202a..1bd772f0838 100644 --- a/go/mysql/conn_params.go +++ b/go/mysql/conn_params.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/mysql/conn_test.go b/go/mysql/conn_test.go index 3c3a848cac3..810ffea7a5f 100644 --- a/go/mysql/conn_test.go +++ b/go/mysql/conn_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/mysql/constants.go b/go/mysql/constants.go index b1d4491f637..c9b3865a5b6 100644 --- a/go/mysql/constants.go +++ b/go/mysql/constants.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 @@ -174,6 +174,9 @@ const ( // ComSetOption is COM_SET_OPTION ComSetOption = 0x1b + // ComResetConnection is COM_RESET_CONNECTION + ComResetConnection = 0x1f + // ComBinlogDumpGTID is COM_BINLOG_DUMP_GTID. ComBinlogDumpGTID = 0x1e diff --git a/go/mysql/constants_test.go b/go/mysql/constants_test.go index 226d28f65ef..4a581a4b7d5 100644 --- a/go/mysql/constants_test.go +++ b/go/mysql/constants_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/mysql/doc.go b/go/mysql/doc.go index cdb5b45b4f4..e3be48299ac 100644 --- a/go/mysql/doc.go +++ b/go/mysql/doc.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 @@ -51,7 +51,7 @@ server should ignore it anyway), and then should send a COM_INIT_DB message to set the database. -- -PLUGABLE AUTHENTICATION: +PLUGGABLE AUTHENTICATION: See https://dev.mysql.com/doc/internals/en/authentication-method-mismatch.html for more information on this. diff --git a/go/mysql/encoding.go b/go/mysql/encoding.go index 018da8a8f9b..c9333522cdf 100644 --- a/go/mysql/encoding.go +++ b/go/mysql/encoding.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 @@ -80,6 +80,10 @@ func lenNullString(value string) int { return len(value) + 1 } +func lenEOFString(value string) int { + return len(value) +} + func writeNullString(data []byte, pos int, value string) int { pos += copy(data[pos:], value) data[pos] = 0 @@ -180,6 +184,10 @@ func readNullString(data []byte, pos int) (string, int, bool) { return string(data[pos : pos+end]), pos + end + 1, true } +func readEOFString(data []byte, pos int) (string, int, bool) { + return string(data[pos:]), len(data) - pos, true +} + func readUint16(data []byte, pos int) (uint16, int, bool) { if pos+1 >= len(data) { return 0, 0, false diff --git a/go/mysql/encoding_test.go b/go/mysql/encoding_test.go index 7f56f583c86..2ca9a84c934 100644 --- a/go/mysql/encoding_test.go +++ b/go/mysql/encoding_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 @@ -190,21 +190,25 @@ func TestEncString(t *testing.T) { value string lenEncoded []byte nullEncoded []byte + eofEncoded []byte }{ { "", []byte{0x00}, []byte{0x00}, + []byte{}, }, { "a", []byte{0x01, 'a'}, []byte{'a', 0x00}, + []byte{'a'}, }, { "0123456789", []byte{0x0a, '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'}, []byte{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 0x00}, + []byte{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'}, }, } for _, test := range tests { @@ -220,6 +224,11 @@ func TestEncString(t *testing.T) { t.Errorf("lenNullString returned %v but expected %v for %v", got, len(test.nullEncoded), test.value) } + // Check lenEOFString + if got := lenEOFString(test.value); got != len(test.eofEncoded) { + t.Errorf("lenNullString returned %v but expected %v for %v", got, len(test.eofEncoded), test.value) + } + // Check successful encoding. data := make([]byte, len(test.lenEncoded)) pos := writeLenEncString(data, 0, test.value) @@ -319,16 +328,21 @@ func TestEncString(t *testing.T) { } // EOF encoded tests. - // We use the nullEncoded value, removing the 0 at the end. // Check successful encoding. - data = make([]byte, len(test.nullEncoded)-1) + data = make([]byte, len(test.eofEncoded)) pos = writeEOFString(data, 0, test.value) - if pos != len(test.nullEncoded)-1 { - t.Errorf("unexpected pos %v after writeEOFString(%v), expected %v", pos, test.value, len(test.nullEncoded)-1) + if pos != len(test.eofEncoded) { + t.Errorf("unexpected pos %v after writeEOFString(%v), expected %v", pos, test.value, len(test.eofEncoded)) } - if !bytes.Equal(data, test.nullEncoded[:len(test.nullEncoded)-1]) { - t.Errorf("unexpected nullEncoded value for %v, got %v expected %v", test.value, data, test.nullEncoded) + if !bytes.Equal(data, test.eofEncoded[:len(test.eofEncoded)]) { + t.Errorf("unexpected eofEncoded value for %v, got %v expected %v", test.value, data, test.eofEncoded) + } + + // Check successful decoding. + got, pos, ok = readEOFString(test.eofEncoded, 0) + if !ok || got != test.value || pos != len(test.eofEncoded) { + t.Errorf("readEOFString returned %v/%v/%v but expected %v/%v/%v", got, pos, ok, test.value, len(test.eofEncoded), true) } } } diff --git a/go/mysql/endtoend/client_test.go b/go/mysql/endtoend/client_test.go index ad6a86b1f34..9a734284b8c 100644 --- a/go/mysql/endtoend/client_test.go +++ b/go/mysql/endtoend/client_test.go @@ -1,3 +1,19 @@ +/* +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 endtoend import ( diff --git a/go/mysql/endtoend/endtoend.go b/go/mysql/endtoend/endtoend.go index 063929e3842..99dfd9b1174 100644 --- a/go/mysql/endtoend/endtoend.go +++ b/go/mysql/endtoend/endtoend.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/mysql/endtoend/main_test.go b/go/mysql/endtoend/main_test.go index 11fe835c21e..cc1c858bf71 100644 --- a/go/mysql/endtoend/main_test.go +++ b/go/mysql/endtoend/main_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/mysql/endtoend/query_benchmark_test.go b/go/mysql/endtoend/query_benchmark_test.go index 7d466ef9d88..f9e2e887770 100644 --- a/go/mysql/endtoend/query_benchmark_test.go +++ b/go/mysql/endtoend/query_benchmark_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/mysql/endtoend/query_test.go b/go/mysql/endtoend/query_test.go index ff8abebff3c..cfc3d877d5f 100644 --- a/go/mysql/endtoend/query_test.go +++ b/go/mysql/endtoend/query_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/mysql/endtoend/replication_test.go b/go/mysql/endtoend/replication_test.go index 46b5d3a53f9..fa5697bcbf2 100644 --- a/go/mysql/endtoend/replication_test.go +++ b/go/mysql/endtoend/replication_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/mysql/endtoend/schema_test.go b/go/mysql/endtoend/schema_test.go index 540484a4927..28ce81c0b11 100644 --- a/go/mysql/endtoend/schema_test.go +++ b/go/mysql/endtoend/schema_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/mysql/fakesqldb/server.go b/go/mysql/fakesqldb/server.go index 14d9869095b..df9a49017fe 100644 --- a/go/mysql/fakesqldb/server.go +++ b/go/mysql/fakesqldb/server.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 @@ -307,16 +307,16 @@ func (db *DB) ConnectionClosed(c *mysql.Conn) { db.mu.Lock() defer db.mu.Unlock() - if db.t != nil { - db.t.Logf("ConnectionClosed(%v): client %v", db.name, c.ConnectionID) - } - if _, ok := db.connections[c.ConnectionID]; !ok { - db.t.Fatalf("BUG: Cannot delete connection from list of open connections because it is not registered. ID: %v Conn: %v", c.ConnectionID, c) + panic(fmt.Errorf("BUG: Cannot delete connection from list of open connections because it is not registered. ID: %v Conn: %v", c.ConnectionID, c)) } delete(db.connections, c.ConnectionID) } +// ComInitDB is part of the mysql.Handler interface. +func (db *DB) ComInitDB(c *mysql.Conn, schemaName string) { +} + // ComQuery is part of the mysql.Handler interface. func (db *DB) ComQuery(c *mysql.Conn, query string, callback func(*sqltypes.Result) error) error { return db.Handler.HandleQuery(c, query, callback) @@ -444,6 +444,11 @@ func (db *DB) ComStmtExecute(c *mysql.Conn, prepare *mysql.PrepareData, callback return nil } +// ComResetConnection is part of the mysql.Handler interface. +func (db *DB) ComResetConnection(c *mysql.Conn) { + +} + // // Methods to add expected queries and results. // diff --git a/go/mysql/flavor.go b/go/mysql/flavor.go index 2fdbe315722..eb337e102b5 100644 --- a/go/mysql/flavor.go +++ b/go/mysql/flavor.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/mysql/flavor_mariadb.go b/go/mysql/flavor_mariadb.go index 9167dabba5d..98174aa9b48 100644 --- a/go/mysql/flavor_mariadb.go +++ b/go/mysql/flavor_mariadb.go @@ -1,6 +1,6 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/mysql/flavor_mariadb_binlog_playback.go b/go/mysql/flavor_mariadb_binlog_playback.go index 0590cb17704..c30e39d2787 100644 --- a/go/mysql/flavor_mariadb_binlog_playback.go +++ b/go/mysql/flavor_mariadb_binlog_playback.go @@ -1,6 +1,6 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/mysql/flavor_mariadb_test.go b/go/mysql/flavor_mariadb_test.go index 7bd8b7b61c2..c1f56935d3b 100644 --- a/go/mysql/flavor_mariadb_test.go +++ b/go/mysql/flavor_mariadb_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/mysql/flavor_mysql.go b/go/mysql/flavor_mysql.go index 446e6e95a57..6ef3a34eb38 100644 --- a/go/mysql/flavor_mysql.go +++ b/go/mysql/flavor_mysql.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/mysql/flavor_mysql_test.go b/go/mysql/flavor_mysql_test.go index 83ed8ff82d5..24ffbb1cb07 100644 --- a/go/mysql/flavor_mysql_test.go +++ b/go/mysql/flavor_mysql_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/mysql/gtid.go b/go/mysql/gtid.go index c04f8bfa41f..f7928f057a5 100644 --- a/go/mysql/gtid.go +++ b/go/mysql/gtid.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/mysql/gtid_set.go b/go/mysql/gtid_set.go index 36336a2a66c..7e2542165e6 100644 --- a/go/mysql/gtid_set.go +++ b/go/mysql/gtid_set.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/mysql/gtid_test.go b/go/mysql/gtid_test.go index 443e9e18e23..ff811f6712e 100644 --- a/go/mysql/gtid_test.go +++ b/go/mysql/gtid_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/mysql/handshake_test.go b/go/mysql/handshake_test.go index cb4f3f61d62..c366b5d86f6 100644 --- a/go/mysql/handshake_test.go +++ b/go/mysql/handshake_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/mysql/ldapauthserver/auth_server_ldap.go b/go/mysql/ldapauthserver/auth_server_ldap.go index 513e1c66502..e5e8dab4e62 100644 --- a/go/mysql/ldapauthserver/auth_server_ldap.go +++ b/go/mysql/ldapauthserver/auth_server_ldap.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/mysql/ldapauthserver/auth_server_ldap_test.go b/go/mysql/ldapauthserver/auth_server_ldap_test.go index 983cf1ff13e..8658536d5b2 100644 --- a/go/mysql/ldapauthserver/auth_server_ldap_test.go +++ b/go/mysql/ldapauthserver/auth_server_ldap_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/mysql/mariadb_gtid.go b/go/mysql/mariadb_gtid.go index 4a24c78ab01..2af7a30ed20 100644 --- a/go/mysql/mariadb_gtid.go +++ b/go/mysql/mariadb_gtid.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/mysql/mariadb_gtid_test.go b/go/mysql/mariadb_gtid_test.go index 6bd738c9723..e08c4efb813 100644 --- a/go/mysql/mariadb_gtid_test.go +++ b/go/mysql/mariadb_gtid_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/mysql/mysql56_gtid.go b/go/mysql/mysql56_gtid.go index 0997b137ad5..efe51b88545 100644 --- a/go/mysql/mysql56_gtid.go +++ b/go/mysql/mysql56_gtid.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/mysql/mysql56_gtid_set.go b/go/mysql/mysql56_gtid_set.go index 3d03cdab01a..5c21d071fc8 100644 --- a/go/mysql/mysql56_gtid_set.go +++ b/go/mysql/mysql56_gtid_set.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/mysql/mysql56_gtid_set_test.go b/go/mysql/mysql56_gtid_set_test.go index bd0133f1418..a52dc924349 100644 --- a/go/mysql/mysql56_gtid_set_test.go +++ b/go/mysql/mysql56_gtid_set_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 @@ -69,7 +69,7 @@ func TestParseMysql56GTIDSet(t *testing.T) { "00010203-0405-0607-0809-0a0b0c0d0e0f:1-5:10-20": { sid1: []interval{{1, 5}, {10, 20}}, }, - // Multiple intervals, out of oder + // Multiple intervals, out of order "00010203-0405-0607-0809-0a0b0c0d0e0f:10-20:1-5": { sid1: []interval{{1, 5}, {10, 20}}, }, diff --git a/go/mysql/mysql56_gtid_test.go b/go/mysql/mysql56_gtid_test.go index fb975eb409d..21390dd615b 100644 --- a/go/mysql/mysql56_gtid_test.go +++ b/go/mysql/mysql56_gtid_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/mysql/query.go b/go/mysql/query.go index a9be6dd442c..6ff9d1e9bc0 100644 --- a/go/mysql/query.go +++ b/go/mysql/query.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 @@ -154,7 +154,7 @@ func (c *Conn) readColumnDefinition(field *querypb.Field, index int) error { field.Decimals = uint32(decimals) // If we didn't get column length or character set, - // we assume the orignal row on the other side was encoded from + // we assume the original row on the other side was encoded from // a Field without that data, so we don't return the flags. if field.ColumnLength != 0 || field.Charset != 0 { field.Flags = uint32(flags) diff --git a/go/mysql/query_benchmark_test.go b/go/mysql/query_benchmark_test.go index de3c9c417df..3f63decbf64 100644 --- a/go/mysql/query_benchmark_test.go +++ b/go/mysql/query_benchmark_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/mysql/query_test.go b/go/mysql/query_test.go index 2d4bf7a13e0..77be4940d27 100644 --- a/go/mysql/query_test.go +++ b/go/mysql/query_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 @@ -268,7 +268,7 @@ func TestQueries(t *testing.T) { InsertID: 0x0102030405060708, }) - // Typicall Select with TYPE_AND_NAME. + // Typical Select with TYPE_AND_NAME. // One value is also NULL. checkQuery(t, "type and name", sConn, cConn, &sqltypes.Result{ Fields: []*querypb.Field{ @@ -294,7 +294,7 @@ func TestQueries(t *testing.T) { RowsAffected: 2, }) - // Typicall Select with TYPE_AND_NAME. + // Typical Select with TYPE_AND_NAME. // All types are represented. // One row has all NULL values. checkQuery(t, "all types", sConn, cConn, &sqltypes.Result{ @@ -397,7 +397,7 @@ func TestQueries(t *testing.T) { RowsAffected: 2, }) - // Typicall Select with TYPE_AND_NAME. + // Typical Select with TYPE_AND_NAME. // First value first column is an empty string, so it's encoded as 0. checkQuery(t, "first empty string", sConn, cConn, &sqltypes.Result{ Fields: []*querypb.Field{ @@ -417,7 +417,7 @@ func TestQueries(t *testing.T) { RowsAffected: 2, }) - // Typicall Select with TYPE_ONLY. + // Typical Select with TYPE_ONLY. checkQuery(t, "type only", sConn, cConn, &sqltypes.Result{ Fields: []*querypb.Field{ { @@ -435,7 +435,7 @@ func TestQueries(t *testing.T) { RowsAffected: 2, }) - // Typicall Select with ALL. + // Typical Select with ALL. checkQuery(t, "complete", sConn, cConn, &sqltypes.Result{ Fields: []*querypb.Field{ { diff --git a/go/mysql/replication.go b/go/mysql/replication.go index 2649785a252..e45b31d96e5 100644 --- a/go/mysql/replication.go +++ b/go/mysql/replication.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/mysql/replication_constants.go b/go/mysql/replication_constants.go index cf5f2f8ce32..690f028cbbd 100644 --- a/go/mysql/replication_constants.go +++ b/go/mysql/replication_constants.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/mysql/replication_position.go b/go/mysql/replication_position.go index 8d1ec3f9e08..a103d22af95 100644 --- a/go/mysql/replication_position.go +++ b/go/mysql/replication_position.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/mysql/replication_position_test.go b/go/mysql/replication_position_test.go index 76dce397d00..7162810af34 100644 --- a/go/mysql/replication_position_test.go +++ b/go/mysql/replication_position_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/mysql/replication_test.go b/go/mysql/replication_test.go index a14e859c51f..c84f04bce82 100644 --- a/go/mysql/replication_test.go +++ b/go/mysql/replication_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/mysql/schema.go b/go/mysql/schema.go index 6de7d42b6f7..b44d14f7add 100644 --- a/go/mysql/schema.go +++ b/go/mysql/schema.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/mysql/server.go b/go/mysql/server.go index 5de219ff476..213af75cb90 100644 --- a/go/mysql/server.go +++ b/go/mysql/server.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 @@ -42,7 +42,6 @@ const ( // timing metric keys connectTimingKey = "Connect" queryTimingKey = "Query" - versionSSL30 = "SSL30" versionTLS10 = "TLS10" versionTLS11 = "TLS11" versionTLS12 = "TLS12" @@ -89,6 +88,10 @@ type Handler interface { // ConnectionClosed is called when a connection is closed. ConnectionClosed(c *Conn) + // InitDB is called once at the beginning to set db name, + // and subsequently for every ComInitDB event. + ComInitDB(c *Conn, schemaName string) + // ComQuery is called when a connection receives a query. // Note the contents of the query slice may change after // the first call to callback. So the Handler should not @@ -109,6 +112,8 @@ type Handler interface { // ComQuery callback if the result does not contain any fields, // or after the last ComQuery call completes. WarningCount(c *Conn) uint16 + + ComResetConnection(c *Conn) } // Listener is the MySQL server protocol listener. @@ -296,7 +301,7 @@ func (l *Listener) handle(conn net.Conn, connectionID uint32, acceptTime time.Ti if err != nil { // Don't log EOF errors. They cause too much spam, same as main read loop. if err != io.EOF { - log.Errorf("Cannot read client handshake response from %s: %v", c, err) + log.Infof("Cannot read client handshake response from %s: %v, it may not be a valid MySQL client", c, err) } return } @@ -446,6 +451,9 @@ func (l *Listener) handle(conn net.Conn, connectionID uint32, acceptTime time.Ti log.Warningf("Slow connection from %s: %v", c, connectTime) } + // Set initial db name. + l.handler.ComInitDB(c, c.schemaName) + for { err := c.handleNextCommand(l.handler) if err != nil { @@ -673,7 +681,7 @@ func (l *Listener) parseClientHandshakePacket(c *Conn, firstTime bool, data []by if !ok { return "", "", nil, vterrors.Errorf(vtrpc.Code_INTERNAL, "parseClientHandshakePacket: can't read dbname") } - c.SchemaName = dbname + c.schemaName = dbname } // authMethod (with default) @@ -774,8 +782,6 @@ func (c *Conn) writeAuthSwitchRequest(pluginName string, pluginData []byte) erro // Whenever we move to a new version of go, we will need add any new supported TLS versions here func tlsVersionToString(version uint16) string { switch version { - case tls.VersionSSL30: - return versionSSL30 case tls.VersionTLS10: return versionTLS10 case tls.VersionTLS11: diff --git a/go/mysql/server_test.go b/go/mysql/server_test.go index 49456128c9f..7fc9fddb1c0 100644 --- a/go/mysql/server_test.go +++ b/go/mysql/server_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 @@ -75,7 +75,9 @@ func (th *testHandler) NewConnection(c *Conn) { } func (th *testHandler) ConnectionClosed(c *Conn) { +} +func (th *testHandler) ComInitDB(c *Conn, schemaName string) { } func (th *testHandler) ComQuery(c *Conn, query string, callback func(*sqltypes.Result) error) error { @@ -109,7 +111,7 @@ func (th *testHandler) ComQuery(c *Conn, query string, callback func(*sqltypes.R }, Rows: [][]sqltypes.Value{ { - sqltypes.MakeTrusted(querypb.Type_VARCHAR, []byte(c.SchemaName)), + sqltypes.MakeTrusted(querypb.Type_VARCHAR, []byte(c.schemaName)), }, }, }) @@ -180,6 +182,10 @@ func (th *testHandler) ComStmtExecute(c *Conn, prepare *PrepareData, callback fu return nil } +func (th *testHandler) ComResetConnection(c *Conn) { + +} + func (th *testHandler) WarningCount(c *Conn) uint16 { return th.warnings } @@ -1302,7 +1308,7 @@ func TestParseConnAttrs(t *testing.T) { t.Fatalf("Failed to read connection attributes: %v", err) } if pos != 113 { - t.Fatalf("Unexpeded pos after reading connection attributes: %d intead of 113", pos) + t.Fatalf("Unexpeded pos after reading connection attributes: %d instead of 113", pos) } for k, v := range expected { if val, ok := attrs[k]; ok { diff --git a/go/mysql/slave_status.go b/go/mysql/slave_status.go index 623247d32ae..3b0dcacfdd3 100644 --- a/go/mysql/slave_status.go +++ b/go/mysql/slave_status.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/mysql/slave_status_test.go b/go/mysql/slave_status_test.go index 79334da8008..4a0dc832550 100644 --- a/go/mysql/slave_status_test.go +++ b/go/mysql/slave_status_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/mysql/sql_error.go b/go/mysql/sql_error.go index 233fe49276e..fcbaa8c810b 100644 --- a/go/mysql/sql_error.go +++ b/go/mysql/sql_error.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/mysql/streaming_query.go b/go/mysql/streaming_query.go index c606a20f469..0d8c87eb50a 100644 --- a/go/mysql/streaming_query.go +++ b/go/mysql/streaming_query.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/netutil/conn.go b/go/netutil/conn.go index 90d7a5139f2..e4f8ab7ebe2 100644 --- a/go/netutil/conn.go +++ b/go/netutil/conn.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Vitess Authors. +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 diff --git a/go/netutil/conn_test.go b/go/netutil/conn_test.go index 95068f2a1f8..083df3ba81e 100644 --- a/go/netutil/conn_test.go +++ b/go/netutil/conn_test.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Vitess Authors. +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 diff --git a/go/netutil/netutil.go b/go/netutil/netutil.go index 158a8f2f637..a97be114c81 100644 --- a/go/netutil/netutil.go +++ b/go/netutil/netutil.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/netutil/netutil_test.go b/go/netutil/netutil_test.go index 0e3087a78ef..bd47912443f 100644 --- a/go/netutil/netutil_test.go +++ b/go/netutil/netutil_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/pools/id_pool.go b/go/pools/id_pool.go index 2b44e4b792a..87e5823e49b 100644 --- a/go/pools/id_pool.go +++ b/go/pools/id_pool.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/pools/id_pool_test.go b/go/pools/id_pool_test.go index 4d85835539f..71bb3ecae65 100644 --- a/go/pools/id_pool_test.go +++ b/go/pools/id_pool_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/pools/numbered.go b/go/pools/numbered.go index f9e6107d5cc..ef4e3ea3064 100644 --- a/go/pools/numbered.go +++ b/go/pools/numbered.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/pools/numbered_test.go b/go/pools/numbered_test.go index dfe19cb203c..467e220fed5 100644 --- a/go/pools/numbered_test.go +++ b/go/pools/numbered_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/pools/resource_pool.go b/go/pools/resource_pool.go index 8e92f0bf5ee..81055e4d0cb 100644 --- a/go/pools/resource_pool.go +++ b/go/pools/resource_pool.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -60,6 +60,7 @@ type ResourcePool struct { waitCount sync2.AtomicInt64 waitTime sync2.AtomicDuration idleClosed sync2.AtomicInt64 + exhausted sync2.AtomicInt64 capacity sync2.AtomicInt64 idleTimeout sync2.AtomicDuration @@ -230,7 +231,9 @@ func (rp *ResourcePool) get(ctx context.Context) (resource Resource, err error) } rp.active.Add(1) } - rp.available.Add(-1) + if rp.available.Add(-1) <= 0 { + rp.exhausted.Add(1) + } rp.inUse.Add(1) return wrapper.resource, err } @@ -334,7 +337,7 @@ func (rp *ResourcePool) SetIdleTimeout(idleTimeout time.Duration) { // StatsJSON returns the stats in JSON format. func (rp *ResourcePool) StatsJSON() string { - return fmt.Sprintf(`{"Capacity": %v, "Available": %v, "Active": %v, "InUse": %v, "MaxCapacity": %v, "WaitCount": %v, "WaitTime": %v, "IdleTimeout": %v, "IdleClosed": %v}`, + return fmt.Sprintf(`{"Capacity": %v, "Available": %v, "Active": %v, "InUse": %v, "MaxCapacity": %v, "WaitCount": %v, "WaitTime": %v, "IdleTimeout": %v, "IdleClosed": %v, "Exhausted": %v}`, rp.Capacity(), rp.Available(), rp.Active(), @@ -344,6 +347,7 @@ func (rp *ResourcePool) StatsJSON() string { rp.WaitTime().Nanoseconds(), rp.IdleTimeout().Nanoseconds(), rp.IdleClosed(), + rp.Exhausted(), ) } @@ -392,3 +396,8 @@ func (rp *ResourcePool) IdleTimeout() time.Duration { func (rp *ResourcePool) IdleClosed() int64 { return rp.idleClosed.Get() } + +// Exhausted returns the number of times Available dropped below 1 +func (rp *ResourcePool) Exhausted() int64 { + return rp.exhausted.Get() +} diff --git a/go/pools/resource_pool_test.go b/go/pools/resource_pool_test.go index 15c21c9202e..2ec6f68c8b6 100644 --- a/go/pools/resource_pool_test.go +++ b/go/pools/resource_pool_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -247,7 +247,7 @@ func TestShrinking(t *testing.T) { p.SetCapacity(3) done <- true }() - expected := `{"Capacity": 3, "Available": 0, "Active": 4, "InUse": 4, "MaxCapacity": 5, "WaitCount": 0, "WaitTime": 0, "IdleTimeout": 1000000000, "IdleClosed": 0}` + expected := `{"Capacity": 3, "Available": 0, "Active": 4, "InUse": 4, "MaxCapacity": 5, "WaitCount": 0, "WaitTime": 0, "IdleTimeout": 1000000000, "IdleClosed": 0, "Exhausted": 0}` for i := 0; i < 10; i++ { time.Sleep(10 * time.Millisecond) stats := p.StatsJSON() @@ -266,7 +266,7 @@ func TestShrinking(t *testing.T) { p.Put(resources[i]) } stats := p.StatsJSON() - expected = `{"Capacity": 3, "Available": 3, "Active": 3, "InUse": 0, "MaxCapacity": 5, "WaitCount": 0, "WaitTime": 0, "IdleTimeout": 1000000000, "IdleClosed": 0}` + expected = `{"Capacity": 3, "Available": 3, "Active": 3, "InUse": 0, "MaxCapacity": 5, "WaitCount": 0, "WaitTime": 0, "IdleTimeout": 1000000000, "IdleClosed": 0, "Exhausted": 0}` if stats != expected { t.Errorf(`expecting '%s', received '%s'`, expected, stats) } @@ -389,7 +389,7 @@ func TestClosing(t *testing.T) { // Wait for goroutine to call Close time.Sleep(10 * time.Millisecond) stats := p.StatsJSON() - expected := `{"Capacity": 0, "Available": 0, "Active": 5, "InUse": 5, "MaxCapacity": 5, "WaitCount": 0, "WaitTime": 0, "IdleTimeout": 1000000000, "IdleClosed": 0}` + expected := `{"Capacity": 0, "Available": 0, "Active": 5, "InUse": 5, "MaxCapacity": 5, "WaitCount": 0, "WaitTime": 0, "IdleTimeout": 1000000000, "IdleClosed": 0, "Exhausted": 1}` if stats != expected { t.Errorf(`expecting '%s', received '%s'`, expected, stats) } @@ -409,7 +409,7 @@ func TestClosing(t *testing.T) { } stats = p.StatsJSON() - expected = `{"Capacity": 0, "Available": 0, "Active": 0, "InUse": 0, "MaxCapacity": 5, "WaitCount": 0, "WaitTime": 0, "IdleTimeout": 1000000000, "IdleClosed": 0}` + expected = `{"Capacity": 0, "Available": 0, "Active": 0, "InUse": 0, "MaxCapacity": 5, "WaitCount": 0, "WaitTime": 0, "IdleTimeout": 1000000000, "IdleClosed": 0, "Exhausted": 1}` if stats != expected { t.Errorf(`expecting '%s', received '%s'`, expected, stats) } @@ -563,7 +563,7 @@ func TestCreateFail(t *testing.T) { t.Errorf("Expecting Failed, received %v", err) } stats := p.StatsJSON() - expected := `{"Capacity": 5, "Available": 5, "Active": 0, "InUse": 0, "MaxCapacity": 5, "WaitCount": 0, "WaitTime": 0, "IdleTimeout": 1000000000, "IdleClosed": 0}` + expected := `{"Capacity": 5, "Available": 5, "Active": 0, "InUse": 0, "MaxCapacity": 5, "WaitCount": 0, "WaitTime": 0, "IdleTimeout": 1000000000, "IdleClosed": 0, "Exhausted": 0}` if stats != expected { t.Errorf(`expecting '%s', received '%s'`, expected, stats) } diff --git a/go/proc/counting_listener.go b/go/proc/counting_listener.go index 719ba6daa27..fe29bbccabf 100644 --- a/go/proc/counting_listener.go +++ b/go/proc/counting_listener.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/proc/counting_listener_test.go b/go/proc/counting_listener_test.go index c8151aa62e4..4b4a20a1d42 100644 --- a/go/proc/counting_listener_test.go +++ b/go/proc/counting_listener_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/proc/proc.go b/go/proc/proc.go index d39cbb80313..54152c167aa 100644 --- a/go/proc/proc.go +++ b/go/proc/proc.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/proc/proc_flaky_test.go b/go/proc/proc_flaky_test.go index 14f43c2749e..3058b44859e 100644 --- a/go/proc/proc_flaky_test.go +++ b/go/proc/proc_flaky_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/race/norace.go b/go/race/norace.go index c89dde2649c..9f0a59f6270 100644 --- a/go/race/norace.go +++ b/go/race/norace.go @@ -1,7 +1,7 @@ // +build !race /* -Copyright 2017 Google Inc. +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. @@ -9,7 +9,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/race/race.go b/go/race/race.go index d28e2bedf76..48c776ea883 100644 --- a/go/race/race.go +++ b/go/race/race.go @@ -1,7 +1,7 @@ // +build race /* -Copyright 2017 Google Inc. +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. @@ -9,7 +9,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/ratelimiter/ratelimiter.go b/go/ratelimiter/ratelimiter.go index 33f79a8cbf9..ddadb8659da 100644 --- a/go/ratelimiter/ratelimiter.go +++ b/go/ratelimiter/ratelimiter.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/ratelimiter/ratelimiter_test.go b/go/ratelimiter/ratelimiter_test.go index fe679f105a4..768584b20f7 100644 --- a/go/ratelimiter/ratelimiter_test.go +++ b/go/ratelimiter/ratelimiter_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/sqlescape/ids.go b/go/sqlescape/ids.go index 9289ff977bf..79244b041b9 100644 --- a/go/sqlescape/ids.go +++ b/go/sqlescape/ids.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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 diff --git a/go/sqlescape/ids_test.go b/go/sqlescape/ids_test.go index 8bc9c6f6e90..cc62b5531df 100644 --- a/go/sqlescape/ids_test.go +++ b/go/sqlescape/ids_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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 diff --git a/go/sqltypes/arithmetic.go b/go/sqltypes/arithmetic.go index f5c18dd43a1..6149a58c2c4 100644 --- a/go/sqltypes/arithmetic.go +++ b/go/sqltypes/arithmetic.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -19,7 +19,6 @@ package sqltypes import ( "bytes" "fmt" - "math" "strconv" @@ -28,9 +27,6 @@ import ( "vitess.io/vitess/go/vt/vterrors" ) -// TODO(sougou): change these functions to be more permissive. -// Most string to number conversions should quietly convert to 0. - // numeric represents a numeric value extracted from // a Value, used for arithmetic operations. type numeric struct { @@ -50,8 +46,14 @@ func Add(v1, v2 Value) (Value, error) { } lv1, err := newNumeric(v1) + if err != nil { + return NULL, err + } lv2, err := newNumeric(v2) + if err != nil { + return NULL, err + } lresult, err := addNumericWithError(lv1, lv2) if err != nil { @@ -61,6 +63,83 @@ func Add(v1, v2 Value) (Value, error) { return castFromNumeric(lresult, lresult.typ), nil } +// Subtract takes two values and subtracts them +func Subtract(v1, v2 Value) (Value, error) { + if v1.IsNull() || v2.IsNull() { + return NULL, nil + } + + lv1, err := newNumeric(v1) + if err != nil { + return NULL, err + } + + lv2, err := newNumeric(v2) + if err != nil { + return NULL, err + } + + lresult, err := subtractNumericWithError(lv1, lv2) + if err != nil { + return NULL, err + } + + return castFromNumeric(lresult, lresult.typ), nil +} + +// Multiply takes two values and multiplies it together +func Multiply(v1, v2 Value) (Value, error) { + if v1.IsNull() || v2.IsNull() { + return NULL, nil + } + + lv1, err := newNumeric(v1) + if err != nil { + return NULL, err + } + lv2, err := newNumeric(v2) + if err != nil { + return NULL, err + } + lresult, err := multiplyNumericWithError(lv1, lv2) + if err != nil { + return NULL, err + } + + return castFromNumeric(lresult, lresult.typ), nil +} + +// Float Division for MySQL. Replicates behavior of "/" operator +func Divide(v1, v2 Value) (Value, error) { + if v1.IsNull() || v2.IsNull() { + return NULL, nil + } + + lv2AsFloat, err := ToFloat64(v2) + divisorIsZero := lv2AsFloat == 0 + + if divisorIsZero || err != nil { + return NULL, err + } + + lv1, err := newNumeric(v1) + if err != nil { + return NULL, err + } + + lv2, err := newNumeric(v2) + if err != nil { + return NULL, err + } + + lresult, err := divideNumericWithError(lv1, lv2) + if err != nil { + return NULL, err + } + + return castFromNumeric(lresult, lresult.typ), nil +} + // NullsafeAdd adds two Values in a null-safe manner. A null value // is treated as 0. If both values are null, then a null is returned. // If both values are not null, a numeric value is built @@ -243,7 +322,10 @@ func ToInt64(v Value) (int64, error) { // ToFloat64 converts Value to float64. func ToFloat64(v Value) (float64, error) { - num, _ := newNumeric(v) + num, err := newNumeric(v) + if err != nil { + return 0, err + } switch num.typ { case Int64: return float64(num.ival), nil @@ -373,7 +455,64 @@ func addNumericWithError(v1, v2 numeric) (numeric, error) { return floatPlusAny(v1.fval, v2), nil } panic("unreachable") +} + +func subtractNumericWithError(v1, v2 numeric) (numeric, error) { + switch v1.typ { + case Int64: + switch v2.typ { + case Int64: + return intMinusIntWithError(v1.ival, v2.ival) + case Uint64: + return intMinusUintWithError(v1.ival, v2.uval) + case Float64: + return anyMinusFloat(v1, v2.fval), nil + } + case Uint64: + switch v2.typ { + case Int64: + return uintMinusIntWithError(v1.uval, v2.ival) + case Uint64: + return uintMinusUintWithError(v1.uval, v2.uval) + case Float64: + return anyMinusFloat(v1, v2.fval), nil + } + case Float64: + return floatMinusAny(v1.fval, v2), nil + } + panic("unreachable") +} +func multiplyNumericWithError(v1, v2 numeric) (numeric, error) { + v1, v2 = prioritize(v1, v2) + switch v1.typ { + case Int64: + return intTimesIntWithError(v1.ival, v2.ival) + case Uint64: + switch v2.typ { + case Int64: + return uintTimesIntWithError(v1.uval, v2.ival) + case Uint64: + return uintTimesUintWithError(v1.uval, v2.uval) + } + case Float64: + return floatTimesAny(v1.fval, v2), nil + } + panic("unreachable") +} + +func divideNumericWithError(v1, v2 numeric) (numeric, error) { + switch v1.typ { + case Int64: + return floatDivideAnyWithError(float64(v1.ival), v2) + + case Uint64: + return floatDivideAnyWithError(float64(v1.uval), v2) + + case Float64: + return floatDivideAnyWithError(v1.fval, v2) + } + panic("unreachable") } // prioritize reorders the input parameters @@ -388,7 +527,6 @@ func prioritize(v1, v2 numeric) (altv1, altv2 numeric) { if v2.typ == Float64 { return v2, v1 } - } return v1, v2 } @@ -415,36 +553,92 @@ func intPlusIntWithError(v1, v2 int64) (numeric, error) { return numeric{typ: Int64, ival: result}, nil } +func intMinusIntWithError(v1, v2 int64) (numeric, error) { + result := v1 - v2 + + if (result < v1) != (v2 > 0) { + return numeric{}, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "BIGINT value is out of range in %v - %v", v1, v2) + } + return numeric{typ: Int64, ival: result}, nil +} + +func intTimesIntWithError(v1, v2 int64) (numeric, error) { + result := v1 * v2 + if v1 != 0 && result/v1 != v2 { + return numeric{}, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "BIGINT value is out of range in %v * %v", v1, v2) + } + return numeric{typ: Int64, ival: result}, nil + +} + +func intMinusUintWithError(v1 int64, v2 uint64) (numeric, error) { + if v1 < 0 || v1 < int64(v2) { + return numeric{}, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "BIGINT UNSIGNED value is out of range in %v - %v", v1, v2) + } + return uintMinusUintWithError(uint64(v1), v2) +} + func uintPlusInt(v1 uint64, v2 int64) numeric { return uintPlusUint(v1, uint64(v2)) } func uintPlusIntWithError(v1 uint64, v2 int64) (numeric, error) { - if v2 >= math.MaxInt64 && v1 > 0 { - return numeric{}, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "BIGINT value is out of range in %v + %v", v1, v2) + if v2 < 0 && v1 < uint64(v2) { + return numeric{}, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "BIGINT UNSIGNED value is out of range in %v + %v", v1, v2) } - - //convert to int -> uint is because for numeric operators (such as + or -) - //where one of the operands is an unsigned integer, the result is unsigned by default. + // convert to int -> uint is because for numeric operators (such as + or -) + // where one of the operands is an unsigned integer, the result is unsigned by default. return uintPlusUintWithError(v1, uint64(v2)) } +func uintMinusIntWithError(v1 uint64, v2 int64) (numeric, error) { + if int64(v1) < v2 && v2 > 0 { + return numeric{}, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "BIGINT UNSIGNED value is out of range in %v - %v", v1, v2) + } + // uint - (- int) = uint + int + if v2 < 0 { + return uintPlusIntWithError(v1, -v2) + } + return uintMinusUintWithError(v1, uint64(v2)) +} + +func uintTimesIntWithError(v1 uint64, v2 int64) (numeric, error) { + if v2 < 0 || int64(v1) < 0 { + return numeric{}, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "BIGINT UNSIGNED value is out of range in %v * %v", v1, v2) + } + return uintTimesUintWithError(v1, uint64(v2)) +} + func uintPlusUint(v1, v2 uint64) numeric { result := v1 + v2 if result < v2 { return numeric{typ: Float64, fval: float64(v1) + float64(v2)} - } return numeric{typ: Uint64, uval: result} } func uintPlusUintWithError(v1, v2 uint64) (numeric, error) { result := v1 + v2 - if result < v2 { return numeric{}, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "BIGINT UNSIGNED value is out of range in %v + %v", v1, v2) } + return numeric{typ: Uint64, uval: result}, nil +} + +func uintMinusUintWithError(v1, v2 uint64) (numeric, error) { + result := v1 - v2 + if v2 > v1 { + return numeric{}, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "BIGINT UNSIGNED value is out of range in %v - %v", v1, v2) + } + + return numeric{typ: Uint64, uval: result}, nil +} +func uintTimesUintWithError(v1, v2 uint64) (numeric, error) { + result := v1 * v2 + if result < v2 || result < v1 { + return numeric{}, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "BIGINT UNSIGNED value is out of range in %v * %v", v1, v2) + } return numeric{typ: Uint64, uval: result}, nil } @@ -458,6 +652,54 @@ func floatPlusAny(v1 float64, v2 numeric) numeric { return numeric{typ: Float64, fval: v1 + v2.fval} } +func floatMinusAny(v1 float64, v2 numeric) numeric { + switch v2.typ { + case Int64: + v2.fval = float64(v2.ival) + case Uint64: + v2.fval = float64(v2.uval) + } + return numeric{typ: Float64, fval: v1 - v2.fval} +} + +func floatTimesAny(v1 float64, v2 numeric) numeric { + switch v2.typ { + case Int64: + v2.fval = float64(v2.ival) + case Uint64: + v2.fval = float64(v2.uval) + } + return numeric{typ: Float64, fval: v1 * v2.fval} +} + +func floatDivideAnyWithError(v1 float64, v2 numeric) (numeric, error) { + switch v2.typ { + case Int64: + v2.fval = float64(v2.ival) + case Uint64: + v2.fval = float64(v2.uval) + } + result := v1 / v2.fval + divisorLessThanOne := v2.fval < 1 + resultMismatch := (v2.fval*result != v1) + + if divisorLessThanOne && resultMismatch { + return numeric{}, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "BIGINT is out of range in %v / %v", v1, v2.fval) + } + + return numeric{typ: Float64, fval: v1 / v2.fval}, nil +} + +func anyMinusFloat(v1 numeric, v2 float64) numeric { + switch v1.typ { + case Int64: + v1.fval = float64(v1.ival) + case Uint64: + v1.fval = float64(v1.uval) + } + return numeric{typ: Float64, fval: v1.fval - v2} +} + func castFromNumeric(v numeric, resultType querypb.Type) Value { switch { case IsSigned(resultType): diff --git a/go/sqltypes/arithmetic_test.go b/go/sqltypes/arithmetic_test.go index 81aeba0cf30..d874ea97efd 100644 --- a/go/sqltypes/arithmetic_test.go +++ b/go/sqltypes/arithmetic_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 @@ -29,13 +29,118 @@ import ( "vitess.io/vitess/go/vt/vterrors" ) -func TestAdd(t *testing.T) { +func TestDivide(t *testing.T) { tcases := []struct { v1, v2 Value out Value err error }{{ + //All Nulls + v1: NULL, + v2: NULL, + out: NULL, + }, { + // First value null. + v1: NULL, + v2: NewInt32(1), + out: NULL, + }, { + // Second value null. + v1: NewInt32(1), + v2: NULL, + out: NULL, + }, { + // Second arg 0 + v1: NewInt32(5), + v2: NewInt32(0), + out: NULL, + }, { + // Both arguments zero + v1: NewInt32(0), + v2: NewInt32(0), + out: NULL, + }, { + // case with negative value + v1: NewInt64(-1), + v2: NewInt64(-2), + out: NewFloat64(0.5000), + }, { + // float64 division by zero + v1: NewFloat64(2), + v2: NewFloat64(0), + out: NULL, + }, { + // Lower bound for int64 + v1: NewInt64(math.MinInt64), + v2: NewInt64(1), + out: NewFloat64(math.MinInt64), + }, { + // upper bound for uint64 + v1: NewUint64(math.MaxUint64), + v2: NewUint64(1), + out: NewFloat64(math.MaxUint64), + }, { + // testing for error in types + v1: TestValue(Int64, "1.2"), + v2: NewInt64(2), + err: vterrors.New(vtrpcpb.Code_INVALID_ARGUMENT, "strconv.ParseInt: parsing \"1.2\": invalid syntax"), + }, { + // testing for error in types + v1: NewInt64(2), + v2: TestValue(Int64, "1.2"), + err: vterrors.New(vtrpcpb.Code_INVALID_ARGUMENT, "strconv.ParseInt: parsing \"1.2\": invalid syntax"), + }, { + // testing for uint/int + v1: NewUint64(4), + v2: NewInt64(5), + out: NewFloat64(0.8), + }, { + // testing for uint/uint + v1: NewUint64(1), + v2: NewUint64(2), + out: NewFloat64(0.5), + }, { + // testing for float64/int64 + v1: TestValue(Float64, "1.2"), + v2: NewInt64(-2), + out: NewFloat64(-0.6), + }, { + // testing for float64/uint64 + v1: TestValue(Float64, "1.2"), + v2: NewUint64(2), + out: NewFloat64(0.6), + }, { + // testing for overflow of float64 + v1: NewFloat64(math.MaxFloat64), + v2: NewFloat64(0.5), + err: vterrors.New(vtrpcpb.Code_INVALID_ARGUMENT, "BIGINT is out of range in 1.7976931348623157e+308 / 0.5"), + }} + + for _, tcase := range tcases { + got, err := Divide(tcase.v1, tcase.v2) + + if !vterrors.Equals(err, tcase.err) { + t.Errorf("%v %v %v", printValue(tcase.v1), printValue(tcase.v2), vterrors.Print(err)) + t.Errorf("Divide(%v, %v) error: %v, want %v", printValue(tcase.v1), printValue(tcase.v2), vterrors.Print(err), vterrors.Print(tcase.err)) + } + + if tcase.err != nil { + continue + } + + if !reflect.DeepEqual(got, tcase.out) { + t.Errorf("Divide(%v, %v): %v, want %v", printValue(tcase.v1), printValue(tcase.v2), printValue(got), printValue(tcase.out)) + } + } + +} +func TestMultiply(t *testing.T) { + tcases := []struct { + v1, v2 Value + out Value + err error + }{{ //All Nulls v1: NULL, v2: NULL, @@ -51,24 +156,258 @@ func TestAdd(t *testing.T) { v2: NewInt32(1), out: NULL, }, { + // case with negative value + v1: NewInt64(-1), + v2: NewInt64(-2), + out: NewInt64(2), + }, { + // testing for int64 overflow with min negative value + v1: NewInt64(math.MinInt64), + v2: NewInt64(1), + out: NewInt64(math.MinInt64), + }, { + // testing for error in types + v1: TestValue(Int64, "1.2"), + v2: NewInt64(2), + err: vterrors.New(vtrpcpb.Code_INVALID_ARGUMENT, "strconv.ParseInt: parsing \"1.2\": invalid syntax"), + }, { + // testing for error in types + v1: NewInt64(2), + v2: TestValue(Int64, "1.2"), + err: vterrors.New(vtrpcpb.Code_INVALID_ARGUMENT, "strconv.ParseInt: parsing \"1.2\": invalid syntax"), + }, { + // testing for uint*int + v1: NewUint64(4), + v2: NewInt64(5), + out: NewUint64(20), + }, { + // testing for uint*uint + v1: NewUint64(1), + v2: NewUint64(2), + out: NewUint64(2), + }, { + // testing for float64*int64 + v1: TestValue(Float64, "1.2"), + v2: NewInt64(-2), + out: NewFloat64(-2.4), + }, { + // testing for float64*uint64 + v1: TestValue(Float64, "1.2"), + v2: NewUint64(2), + out: NewFloat64(2.4), + }, { + // testing for overflow of int64 + v1: NewInt64(math.MaxInt64), + v2: NewInt64(2), + err: vterrors.New(vtrpcpb.Code_INVALID_ARGUMENT, "BIGINT value is out of range in 9223372036854775807 * 2"), + }, { + // testing for underflow of uint64*max.uint64 + v1: NewInt64(2), + v2: NewUint64(math.MaxUint64), + err: vterrors.New(vtrpcpb.Code_INVALID_ARGUMENT, "BIGINT UNSIGNED value is out of range in 18446744073709551615 * 2"), + }, { + v1: NewUint64(math.MaxUint64), + v2: NewUint64(1), + out: NewUint64(math.MaxUint64), + }, { + //Checking whether maxInt value can be passed as uint value + v1: NewUint64(math.MaxInt64), + v2: NewInt64(3), + err: vterrors.New(vtrpcpb.Code_INVALID_ARGUMENT, "BIGINT UNSIGNED value is out of range in 9223372036854775807 * 3"), + }} + + for _, tcase := range tcases { + + got, err := Multiply(tcase.v1, tcase.v2) + + if !vterrors.Equals(err, tcase.err) { + t.Errorf("Multiply(%v, %v) error: %v, want %v", printValue(tcase.v1), printValue(tcase.v2), vterrors.Print(err), vterrors.Print(tcase.err)) + } + if tcase.err != nil { + continue + } + + if !reflect.DeepEqual(got, tcase.out) { + t.Errorf("Multiply(%v, %v): %v, want %v", printValue(tcase.v1), printValue(tcase.v2), printValue(got), printValue(tcase.out)) + } + } + +} + +func TestSubtract(t *testing.T) { + tcases := []struct { + v1, v2 Value + out Value + err error + }{{ + // All Nulls + v1: NULL, + v2: NULL, + out: NULL, + }, { + // First value null. + v1: NewInt32(1), + v2: NULL, + out: NULL, + }, { + // Second value null. + v1: NULL, + v2: NewInt32(1), + out: NULL, + }, { + // case with negative value + v1: NewInt64(-1), + v2: NewInt64(-2), + out: NewInt64(1), + }, { + // testing for int64 overflow with min negative value + v1: NewInt64(math.MinInt64), + v2: NewInt64(1), + err: vterrors.New(vtrpcpb.Code_INVALID_ARGUMENT, "BIGINT value is out of range in -9223372036854775808 - 1"), + }, { + v1: NewUint64(4), + v2: NewInt64(5), + err: vterrors.New(vtrpcpb.Code_INVALID_ARGUMENT, "BIGINT UNSIGNED value is out of range in 4 - 5"), + }, { + // testing uint - int + v1: NewUint64(7), + v2: NewInt64(5), + out: NewUint64(2), + }, { + v1: NewUint64(math.MaxUint64), + v2: NewInt64(0), + out: NewUint64(math.MaxUint64), + }, { + // testing for int64 overflow + v1: NewInt64(math.MinInt64), + v2: NewUint64(0), + err: vterrors.New(vtrpcpb.Code_INVALID_ARGUMENT, "BIGINT UNSIGNED value is out of range in -9223372036854775808 - 0"), + }, { + v1: TestValue(VarChar, "c"), + v2: NewInt64(1), + out: NewInt64(-1), + }, { + v1: NewUint64(1), + v2: TestValue(VarChar, "c"), + out: NewUint64(1), + }, { + // testing for error for parsing float value to uint64 + v1: TestValue(Uint64, "1.2"), + v2: NewInt64(2), + err: vterrors.New(vtrpcpb.Code_INVALID_ARGUMENT, "strconv.ParseUint: parsing \"1.2\": invalid syntax"), + }, { + // testing for error for parsing float value to uint64 + v1: NewUint64(2), + v2: TestValue(Uint64, "1.2"), + err: vterrors.New(vtrpcpb.Code_INVALID_ARGUMENT, "strconv.ParseUint: parsing \"1.2\": invalid syntax"), + }, { + // uint64 - uint64 + v1: NewUint64(8), + v2: NewUint64(4), + out: NewUint64(4), + }, { + // testing for float subtraction: float - int + v1: NewFloat64(1.2), + v2: NewInt64(2), + out: NewFloat64(-0.8), + }, { + // testing for float subtraction: float - uint + v1: NewFloat64(1.2), + v2: NewUint64(2), + out: NewFloat64(-0.8), + }, { + v1: NewInt64(-1), + v2: NewUint64(2), + err: vterrors.New(vtrpcpb.Code_INVALID_ARGUMENT, "BIGINT UNSIGNED value is out of range in -1 - 2"), + }, { + v1: NewInt64(2), + v2: NewUint64(1), + out: NewUint64(1), + }, { + // testing int64 - float64 method + v1: NewInt64(-2), + v2: NewFloat64(1.0), + out: NewFloat64(-3.0), + }, { + // testing uint64 - float64 method + v1: NewUint64(1), + v2: NewFloat64(-2.0), + out: NewFloat64(3.0), + }, { + // testing uint - int to return uintplusint + v1: NewUint64(1), + v2: NewInt64(-2), + out: NewUint64(3), + }, { + // testing for float - float + v1: NewFloat64(1.2), + v2: NewFloat64(3.2), + out: NewFloat64(-2), + }, { + // testing uint - uint if v2 > v1 + v1: NewUint64(2), + v2: NewUint64(4), + err: vterrors.New(vtrpcpb.Code_INVALID_ARGUMENT, "BIGINT UNSIGNED value is out of range in 2 - 4"), + }, { + // testing uint - (- int) + v1: NewUint64(1), + v2: NewInt64(-2), + out: NewUint64(3), + }} + + for _, tcase := range tcases { + + got, err := Subtract(tcase.v1, tcase.v2) + + if !vterrors.Equals(err, tcase.err) { + t.Errorf("Subtract(%v, %v) error: %v, want %v", printValue(tcase.v1), printValue(tcase.v2), vterrors.Print(err), vterrors.Print(tcase.err)) + } + if tcase.err != nil { + continue + } + + if !reflect.DeepEqual(got, tcase.out) { + t.Errorf("Subtract(%v, %v): %v, want %v", printValue(tcase.v1), printValue(tcase.v2), printValue(got), printValue(tcase.out)) + } + } + +} +func TestAdd(t *testing.T) { + tcases := []struct { + v1, v2 Value + out Value + err error + }{{ + // All Nulls + v1: NULL, + v2: NULL, + out: NULL, + }, { + // First value null. + v1: NewInt32(1), + v2: NULL, + out: NULL, + }, { + // Second value null. + v1: NULL, + v2: NewInt32(1), + out: NULL, + }, { // case with negatives v1: NewInt64(-1), v2: NewInt64(-2), out: NewInt64(-3), }, { - - // testing for overflow int64 + // testing for overflow int64, result will be unsigned int v1: NewInt64(math.MaxInt64), v2: NewUint64(2), - err: vterrors.New(vtrpcpb.Code_INVALID_ARGUMENT, "BIGINT value is out of range in 2 + 9223372036854775807"), + out: NewUint64(9223372036854775809), }, { - v1: NewInt64(-2), v2: NewUint64(1), - out: NewUint64(math.MaxUint64), + err: vterrors.New(vtrpcpb.Code_INVALID_ARGUMENT, "BIGINT UNSIGNED value is out of range in 1 + -2"), }, { - v1: NewInt64(math.MaxInt64), v2: NewInt64(-2), out: NewInt64(9223372036854775805), @@ -83,30 +422,25 @@ func TestAdd(t *testing.T) { v2: NewUint64(2), err: vterrors.New(vtrpcpb.Code_INVALID_ARGUMENT, "BIGINT UNSIGNED value is out of range in 18446744073709551615 + 2"), }, { - // int64 underflow v1: NewInt64(math.MinInt64), v2: NewInt64(-2), err: vterrors.New(vtrpcpb.Code_INVALID_ARGUMENT, "BIGINT value is out of range in -9223372036854775808 + -2"), }, { - // checking int64 max value can be returned v1: NewInt64(math.MaxInt64), v2: NewUint64(0), out: NewUint64(9223372036854775807), }, { - // testing whether uint64 max value can be returned v1: NewUint64(math.MaxUint64), v2: NewInt64(0), out: NewUint64(math.MaxUint64), }, { - v1: NewUint64(math.MaxInt64), v2: NewInt64(1), out: NewUint64(9223372036854775808), }, { - v1: NewUint64(1), v2: TestValue(VarChar, "c"), out: NewUint64(1), @@ -114,6 +448,19 @@ func TestAdd(t *testing.T) { v1: NewUint64(1), v2: TestValue(VarChar, "1.2"), out: NewFloat64(2.2), + }, { + v1: TestValue(Int64, "1.2"), + v2: NewInt64(2), + err: vterrors.New(vtrpcpb.Code_INVALID_ARGUMENT, "strconv.ParseInt: parsing \"1.2\": invalid syntax"), + }, { + v1: NewInt64(2), + v2: TestValue(Int64, "1.2"), + err: vterrors.New(vtrpcpb.Code_INVALID_ARGUMENT, "strconv.ParseInt: parsing \"1.2\": invalid syntax"), + }, { + // testing for uint64 overflow with max uint64 + int value + v1: NewUint64(math.MaxUint64), + v2: NewInt64(2), + err: vterrors.New(vtrpcpb.Code_INVALID_ARGUMENT, "BIGINT UNSIGNED value is out of range in 18446744073709551615 + 2"), }} for _, tcase := range tcases { @@ -128,7 +475,7 @@ func TestAdd(t *testing.T) { } if !reflect.DeepEqual(got, tcase.out) { - t.Errorf("Addition(%v, %v): %v, want %v", printValue(tcase.v1), printValue(tcase.v2), printValue(got), printValue(tcase.out)) + t.Errorf("Add(%v, %v): %v, want %v", printValue(tcase.v1), printValue(tcase.v2), printValue(got), printValue(tcase.out)) } } @@ -184,7 +531,7 @@ func TestNullsafeAdd(t *testing.T) { got := NullsafeAdd(tcase.v1, tcase.v2, Int64) if !reflect.DeepEqual(got, tcase.out) { - t.Errorf("Add(%v, %v): %v, want %v", printValue(tcase.v1), printValue(tcase.v2), printValue(got), printValue(tcase.out)) + t.Errorf("NullsafeAdd(%v, %v): %v, want %v", printValue(tcase.v1), printValue(tcase.v2), printValue(got), printValue(tcase.out)) } } } @@ -456,6 +803,9 @@ func TestToFloat64(t *testing.T) { }, { v: NewFloat64(1.2), out: 1.2, + }, { + v: TestValue(Int64, "1.2"), + err: vterrors.New(vtrpcpb.Code_INVALID_ARGUMENT, "strconv.ParseInt: parsing \"1.2\": invalid syntax"), }} for _, tcase := range tcases { got, err := ToFloat64(tcase.v) diff --git a/go/sqltypes/bind_variables.go b/go/sqltypes/bind_variables.go index 15d202d83ad..58ac2ad7af4 100644 --- a/go/sqltypes/bind_variables.go +++ b/go/sqltypes/bind_variables.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/sqltypes/bind_variables_test.go b/go/sqltypes/bind_variables_test.go index 44241642402..d5559d07227 100644 --- a/go/sqltypes/bind_variables_test.go +++ b/go/sqltypes/bind_variables_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/sqltypes/event_token.go b/go/sqltypes/event_token.go index d0fa5717901..fa85bbe6be6 100644 --- a/go/sqltypes/event_token.go +++ b/go/sqltypes/event_token.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/sqltypes/event_token_test.go b/go/sqltypes/event_token_test.go index a6b614f3ebe..5a77894889c 100644 --- a/go/sqltypes/event_token_test.go +++ b/go/sqltypes/event_token_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/sqltypes/plan_value.go b/go/sqltypes/plan_value.go index e0f30910362..d3e962d6543 100644 --- a/go/sqltypes/plan_value.go +++ b/go/sqltypes/plan_value.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/sqltypes/plan_value_test.go b/go/sqltypes/plan_value_test.go index e4ba29ae870..2b3dc2c4c76 100644 --- a/go/sqltypes/plan_value_test.go +++ b/go/sqltypes/plan_value_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/sqltypes/proto3.go b/go/sqltypes/proto3.go index c4ccc530f38..88150d6559a 100644 --- a/go/sqltypes/proto3.go +++ b/go/sqltypes/proto3.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/sqltypes/proto3_test.go b/go/sqltypes/proto3_test.go index 720e158658b..0d55fff019d 100644 --- a/go/sqltypes/proto3_test.go +++ b/go/sqltypes/proto3_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/sqltypes/query_response.go b/go/sqltypes/query_response.go index 5ce8e58b765..5547b848054 100644 --- a/go/sqltypes/query_response.go +++ b/go/sqltypes/query_response.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/sqltypes/result.go b/go/sqltypes/result.go index 8c95716895c..8ce92eef36f 100644 --- a/go/sqltypes/result.go +++ b/go/sqltypes/result.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/sqltypes/result_test.go b/go/sqltypes/result_test.go index fa33a8c6fae..3f09f1085c0 100644 --- a/go/sqltypes/result_test.go +++ b/go/sqltypes/result_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/sqltypes/testing.go b/go/sqltypes/testing.go index d56fbcc2cae..932b4b6573c 100644 --- a/go/sqltypes/testing.go +++ b/go/sqltypes/testing.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/sqltypes/type.go b/go/sqltypes/type.go index b123e882d72..79fc5e7b294 100644 --- a/go/sqltypes/type.go +++ b/go/sqltypes/type.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -154,6 +154,7 @@ const ( // If you add to this map, make sure you add a test case // in tabletserver/endtoend. var mysqlToType = map[int64]querypb.Type{ + 0: Decimal, 1: Int8, 2: Int16, 3: Int32, @@ -169,8 +170,13 @@ var mysqlToType = map[int64]querypb.Type{ 13: Year, 15: VarChar, 16: Bit, + 17: Timestamp, + 18: Datetime, + 19: Time, 245: TypeJSON, 246: Decimal, + 247: Enum, + 248: Set, 249: Text, 250: Text, 251: Text, @@ -245,6 +251,24 @@ func MySQLToType(mysqlType, flags int64) (typ querypb.Type, err error) { return modifyType(result, flags), nil } +//TypeEquivalenceCheck returns whether two types are equivalent. +func AreTypesEquivalent(mysqlTypeFromBinlog, mysqlTypeFromSchema querypb.Type) bool { + return (mysqlTypeFromBinlog == mysqlTypeFromSchema) || + (mysqlTypeFromBinlog == VarChar && mysqlTypeFromSchema == VarBinary) || + // Binlog only has base type. But doesn't have per-column-flags to differentiate + // various logical types. For Binary, Enum, Set types, binlog only returns Char + // as data type. + (mysqlTypeFromBinlog == Char && mysqlTypeFromSchema == Binary) || + (mysqlTypeFromBinlog == Char && mysqlTypeFromSchema == Enum) || + (mysqlTypeFromBinlog == Char && mysqlTypeFromSchema == Set) || + (mysqlTypeFromBinlog == Text && mysqlTypeFromSchema == Blob) || + (mysqlTypeFromBinlog == Int8 && mysqlTypeFromSchema == Uint8) || + (mysqlTypeFromBinlog == Int16 && mysqlTypeFromSchema == Uint16) || + (mysqlTypeFromBinlog == Int24 && mysqlTypeFromSchema == Uint24) || + (mysqlTypeFromBinlog == Int32 && mysqlTypeFromSchema == Uint32) || + (mysqlTypeFromBinlog == Int64 && mysqlTypeFromSchema == Uint64) +} + // typeToMySQL is the reverse of mysqlToType. var typeToMySQL = map[querypb.Type]struct { typ int64 diff --git a/go/sqltypes/type_test.go b/go/sqltypes/type_test.go index a4d5ed6f9b0..660d3c87bcd 100644 --- a/go/sqltypes/type_test.go +++ b/go/sqltypes/type_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -406,9 +406,30 @@ func TestMySQLToType(t *testing.T) { } func TestTypeError(t *testing.T) { - _, err := MySQLToType(17, 0) - want := "unsupported type: 17" + _, err := MySQLToType(50, 0) + want := "unsupported type: 50" if err == nil || err.Error() != want { t.Errorf("MySQLToType: %v, want %s", err, want) } } + +func TestTypeEquivalenceCheck(t *testing.T) { + if !AreTypesEquivalent(Int16, Int16) { + t.Errorf("Int16 and Int16 are same types.") + } + if AreTypesEquivalent(Int16, Int24) { + t.Errorf("Int16 and Int24 are not same types.") + } + if !AreTypesEquivalent(VarChar, VarBinary) { + t.Errorf("VarChar in binlog and VarBinary in schema are equivalent types.") + } + if AreTypesEquivalent(VarBinary, VarChar) { + t.Errorf("VarBinary in binlog and VarChar in schema are not equivalent types.") + } + if !AreTypesEquivalent(Int16, Uint16) { + t.Errorf("Int16 in binlog and Uint16 in schema are equivalent types.") + } + if AreTypesEquivalent(Uint16, Int16) { + t.Errorf("Uint16 in binlog and Int16 in schema are not equivalent types.") + } +} diff --git a/go/sqltypes/value.go b/go/sqltypes/value.go index e53419154b5..07a0a58168a 100644 --- a/go/sqltypes/value.go +++ b/go/sqltypes/value.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/sqltypes/value_test.go b/go/sqltypes/value_test.go index 0be764f0fd4..394c9e8167e 100644 --- a/go/sqltypes/value_test.go +++ b/go/sqltypes/value_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/stats/counter.go b/go/stats/counter.go index bf1956089a5..ea102d5cea2 100644 --- a/go/stats/counter.go +++ b/go/stats/counter.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Vitess Authors +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. diff --git a/go/stats/counter_test.go b/go/stats/counter_test.go index 465621acf3e..e13b79da4c1 100644 --- a/go/stats/counter_test.go +++ b/go/stats/counter_test.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Vitess Authors +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. diff --git a/go/stats/counters.go b/go/stats/counters.go index b3bcac4d4b3..6307cf10f2b 100644 --- a/go/stats/counters.go +++ b/go/stats/counters.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/stats/counters_test.go b/go/stats/counters_test.go index 14ccbe8d78d..a9ea7485604 100644 --- a/go/stats/counters_test.go +++ b/go/stats/counters_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/stats/duration.go b/go/stats/duration.go index 3e32054915f..5715ab8f849 100644 --- a/go/stats/duration.go +++ b/go/stats/duration.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Vitess Authors +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. diff --git a/go/stats/duration_test.go b/go/stats/duration_test.go index f661a5be590..cabc79ae77a 100644 --- a/go/stats/duration_test.go +++ b/go/stats/duration_test.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Vitess Authors +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. diff --git a/go/stats/export.go b/go/stats/export.go index 8bac7618c03..54aa38d94d7 100644 --- a/go/stats/export.go +++ b/go/stats/export.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Package stats is a wrapper for expvar. It addtionally +// Package stats is a wrapper for expvar. It additionally // exports new types that can be used to track performance. // It also provides a callback hook that allows a program // to export the variables using methods other than /debug/vars. diff --git a/go/stats/export_test.go b/go/stats/export_test.go index 792902a2cab..86c07064a7d 100644 --- a/go/stats/export_test.go +++ b/go/stats/export_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/stats/histogram.go b/go/stats/histogram.go index c6231998bb5..ce68461ce99 100644 --- a/go/stats/histogram.go +++ b/go/stats/histogram.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/stats/histogram_test.go b/go/stats/histogram_test.go index 91e340b3b29..7a811e3afe4 100644 --- a/go/stats/histogram_test.go +++ b/go/stats/histogram_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/stats/kebab_case_converter.go b/go/stats/kebab_case_converter.go index 59f3ff7cb67..e77e09e37b9 100644 --- a/go/stats/kebab_case_converter.go +++ b/go/stats/kebab_case_converter.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Vitess Authors. +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. diff --git a/go/stats/kebab_case_converter_test.go b/go/stats/kebab_case_converter_test.go index a8617f15ec1..2d40a9fff8a 100644 --- a/go/stats/kebab_case_converter_test.go +++ b/go/stats/kebab_case_converter_test.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Vitess Authors. +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. diff --git a/go/stats/multidimensional.go b/go/stats/multidimensional.go index 0d85c073103..999f22046c8 100644 --- a/go/stats/multidimensional.go +++ b/go/stats/multidimensional.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/stats/multidimensional_test.go b/go/stats/multidimensional_test.go index c52490a7235..84805e00a2e 100644 --- a/go/stats/multidimensional_test.go +++ b/go/stats/multidimensional_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/stats/opentsdb/opentsdb.go b/go/stats/opentsdb/opentsdb.go index 0a75af9d701..70c2ecb8b24 100644 --- a/go/stats/opentsdb/opentsdb.go +++ b/go/stats/opentsdb/opentsdb.go @@ -1,3 +1,19 @@ +/* +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 opentsdb adds support for pushing stats to opentsdb. package opentsdb diff --git a/go/stats/opentsdb/opentsdb_test.go b/go/stats/opentsdb/opentsdb_test.go index 550cd2e273a..07b85afe1ce 100644 --- a/go/stats/opentsdb/opentsdb_test.go +++ b/go/stats/opentsdb/opentsdb_test.go @@ -1,3 +1,19 @@ +/* +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 opentsdb import ( diff --git a/go/stats/prometheusbackend/collectors.go b/go/stats/prometheusbackend/collectors.go index 3001d5b3353..1303520f61c 100644 --- a/go/stats/prometheusbackend/collectors.go +++ b/go/stats/prometheusbackend/collectors.go @@ -1,3 +1,19 @@ +/* +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 prometheusbackend import ( diff --git a/go/stats/prometheusbackend/prometheusbackend.go b/go/stats/prometheusbackend/prometheusbackend.go index 961d88fe01a..fada0aaa4a2 100644 --- a/go/stats/prometheusbackend/prometheusbackend.go +++ b/go/stats/prometheusbackend/prometheusbackend.go @@ -1,3 +1,19 @@ +/* +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 prometheusbackend import ( diff --git a/go/stats/prometheusbackend/prometheusbackend_test.go b/go/stats/prometheusbackend/prometheusbackend_test.go index 0fd906a88d3..bbabe35fe89 100644 --- a/go/stats/prometheusbackend/prometheusbackend_test.go +++ b/go/stats/prometheusbackend/prometheusbackend_test.go @@ -1,3 +1,19 @@ +/* +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 prometheusbackend import ( diff --git a/go/stats/rates.go b/go/stats/rates.go index 7cb7ded97f0..2c7a556d3f0 100644 --- a/go/stats/rates.go +++ b/go/stats/rates.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/stats/rates_test.go b/go/stats/rates_test.go index ba150bb65fa..e37cbbd8af8 100644 --- a/go/stats/rates_test.go +++ b/go/stats/rates_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/stats/ring.go b/go/stats/ring.go index e7b1c8f07c6..269f28675b1 100644 --- a/go/stats/ring.go +++ b/go/stats/ring.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/stats/safe_label.go b/go/stats/safe_label.go index 7bfea4aa13b..a9ca0720f26 100644 --- a/go/stats/safe_label.go +++ b/go/stats/safe_label.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Vitess Authors. +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. diff --git a/go/stats/snake_case_converter.go b/go/stats/snake_case_converter.go index 34dc610216c..80fd1051529 100644 --- a/go/stats/snake_case_converter.go +++ b/go/stats/snake_case_converter.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Vitess Authors. +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. diff --git a/go/stats/snake_case_converter_test.go b/go/stats/snake_case_converter_test.go index 1334f5a82f2..2552ade8df3 100644 --- a/go/stats/snake_case_converter_test.go +++ b/go/stats/snake_case_converter_test.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Vitess Authors. +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. diff --git a/go/stats/timings.go b/go/stats/timings.go index 468f35e8999..8d32ad94bea 100644 --- a/go/stats/timings.go +++ b/go/stats/timings.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/stats/timings_test.go b/go/stats/timings_test.go index ca2d027541f..808d1aa15b5 100644 --- a/go/stats/timings_test.go +++ b/go/stats/timings_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/stats/variable_interface.go b/go/stats/variable_interface.go index 49b9201e4af..1e04d2198fd 100644 --- a/go/stats/variable_interface.go +++ b/go/stats/variable_interface.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Vitess Authors +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. diff --git a/go/streamlog/streamlog.go b/go/streamlog/streamlog.go index 8717898df8b..9c881a877bd 100644 --- a/go/streamlog/streamlog.go +++ b/go/streamlog/streamlog.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/streamlog/streamlog_flaky_test.go b/go/streamlog/streamlog_flaky_test.go index 769dceb6df2..eeef01c8830 100644 --- a/go/streamlog/streamlog_flaky_test.go +++ b/go/streamlog/streamlog_flaky_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/sync2/atomic.go b/go/sync2/atomic.go index 2c56ccfdd76..2d8a532aac7 100644 --- a/go/sync2/atomic.go +++ b/go/sync2/atomic.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -47,7 +47,7 @@ func (i *AtomicInt32) Get() int32 { return atomic.LoadInt32(&i.int32) } -// CompareAndSwap atomatically swaps the old with the new value. +// CompareAndSwap automatically swaps the old with the new value. func (i *AtomicInt32) CompareAndSwap(oldval, newval int32) (swapped bool) { return atomic.CompareAndSwapInt32(&i.int32, oldval, newval) } @@ -77,7 +77,7 @@ func (i *AtomicInt64) Get() int64 { return atomic.LoadInt64(&i.int64) } -// CompareAndSwap atomatically swaps the old with the new value. +// CompareAndSwap automatically swaps the old with the new value. func (i *AtomicInt64) CompareAndSwap(oldval, newval int64) (swapped bool) { return atomic.CompareAndSwapInt64(&i.int64, oldval, newval) } @@ -107,7 +107,7 @@ func (d *AtomicDuration) Get() time.Duration { return time.Duration(atomic.LoadInt64(&d.int64)) } -// CompareAndSwap atomatically swaps the old with the new value. +// CompareAndSwap automatically swaps the old with the new value. func (d *AtomicDuration) CompareAndSwap(oldval, newval time.Duration) (swapped bool) { return atomic.CompareAndSwapInt64(&d.int64, int64(oldval), int64(newval)) } @@ -139,7 +139,7 @@ func (i *AtomicBool) Get() bool { return atomic.LoadInt32(&i.int32) != 0 } -// CompareAndSwap atomatically swaps the old with the new value. +// CompareAndSwap automatically swaps the old with the new value. func (i *AtomicBool) CompareAndSwap(o, n bool) bool { var old, new int32 if o { @@ -174,7 +174,7 @@ func (s *AtomicString) Get() string { return str } -// CompareAndSwap atomatically swaps the old with the new value. +// CompareAndSwap automatically swaps the old with the new value. func (s *AtomicString) CompareAndSwap(oldval, newval string) (swqpped bool) { s.mu.Lock() defer s.mu.Unlock() diff --git a/go/sync2/atomic_test.go b/go/sync2/atomic_test.go index 8547989dcee..6c28fbed47b 100644 --- a/go/sync2/atomic_test.go +++ b/go/sync2/atomic_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/sync2/batcher.go b/go/sync2/batcher.go index 8e9e14434df..8d8254d5712 100644 --- a/go/sync2/batcher.go +++ b/go/sync2/batcher.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/sync2/batcher_test.go b/go/sync2/batcher_test.go index 6e90c338507..e3172ceae2b 100644 --- a/go/sync2/batcher_test.go +++ b/go/sync2/batcher_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/sync2/consolidator.go b/go/sync2/consolidator.go index 1c69d802505..5e7698996c9 100644 --- a/go/sync2/consolidator.go +++ b/go/sync2/consolidator.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/sync2/consolidator_test.go b/go/sync2/consolidator_test.go index 6e8080359db..35d32e94051 100644 --- a/go/sync2/consolidator_test.go +++ b/go/sync2/consolidator_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/sync2/doc.go b/go/sync2/doc.go index f78ad13aba2..4fc32a7e53b 100644 --- a/go/sync2/doc.go +++ b/go/sync2/doc.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/sync2/semaphore.go b/go/sync2/semaphore.go index 0089b292b3b..536399824cc 100644 --- a/go/sync2/semaphore.go +++ b/go/sync2/semaphore.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/sync2/semaphore_flaky_test.go b/go/sync2/semaphore_flaky_test.go index a3bca7ead47..60b287df216 100644 --- a/go/sync2/semaphore_flaky_test.go +++ b/go/sync2/semaphore_flaky_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/tb/error.go b/go/tb/error.go index 9a5f3202a11..645bcadc64e 100644 --- a/go/tb/error.go +++ b/go/tb/error.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/testfiles/ports.go b/go/testfiles/ports.go index 6353c56b4f9..7f2f64ac7df 100644 --- a/go/testfiles/ports.go +++ b/go/testfiles/ports.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/timer/randticker.go b/go/timer/randticker.go index 1a158c94f14..17ab08526d6 100644 --- a/go/timer/randticker.go +++ b/go/timer/randticker.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/timer/randticker_flaky_test.go b/go/timer/randticker_flaky_test.go index 155a9fe2cba..59bcd1d89ea 100644 --- a/go/timer/randticker_flaky_test.go +++ b/go/timer/randticker_flaky_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/timer/timer.go b/go/timer/timer.go index 08076ab48f4..327a2e4d5c0 100644 --- a/go/timer/timer.go +++ b/go/timer/timer.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/timer/timer_flaky_test.go b/go/timer/timer_flaky_test.go index 26c5fbbc7f7..b89998a83f3 100644 --- a/go/timer/timer_flaky_test.go +++ b/go/timer/timer_flaky_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/trace/fake.go b/go/trace/fake.go index f1f8be19dac..26821b96183 100644 --- a/go/trace/fake.go +++ b/go/trace/fake.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -23,25 +23,26 @@ import ( "google.golang.org/grpc" ) -type fakeSpanFactory struct{} +type noopTracingServer struct{} -func (fakeSpanFactory) New(Span, string) Span { return fakeSpan{} } -func (fakeSpanFactory) NewClientSpan(parent Span, serviceName, label string) Span { return fakeSpan{} } -func (fakeSpanFactory) FromContext(context.Context) (Span, bool) { return nil, false } -func (fakeSpanFactory) NewContext(parent context.Context, _ Span) context.Context { return parent } -func (fakeSpanFactory) AddGrpcServerOptions(addInterceptors func(s grpc.StreamServerInterceptor, u grpc.UnaryServerInterceptor)) { +func (noopTracingServer) New(Span, string) Span { return NoopSpan{} } +func (noopTracingServer) NewClientSpan(parent Span, serviceName, label string) Span { return NoopSpan{} } +func (noopTracingServer) FromContext(context.Context) (Span, bool) { return nil, false } +func (noopTracingServer) NewFromString(parent, label string) (Span, error) { return NoopSpan{}, nil } +func (noopTracingServer) NewContext(parent context.Context, _ Span) context.Context { return parent } +func (noopTracingServer) AddGrpcServerOptions(addInterceptors func(s grpc.StreamServerInterceptor, u grpc.UnaryServerInterceptor)) { } -func (fakeSpanFactory) AddGrpcClientOptions(addInterceptors func(s grpc.StreamClientInterceptor, u grpc.UnaryClientInterceptor)) { +func (noopTracingServer) AddGrpcClientOptions(addInterceptors func(s grpc.StreamClientInterceptor, u grpc.UnaryClientInterceptor)) { } -// fakeSpan implements Span with no-op methods. -type fakeSpan struct{} +// NoopSpan implements Span with no-op methods. +type NoopSpan struct{} -func (fakeSpan) Finish() {} -func (fakeSpan) Annotate(string, interface{}) {} +func (NoopSpan) Finish() {} +func (NoopSpan) Annotate(string, interface{}) {} func init() { tracingBackendFactories["noop"] = func(_ string) (tracingService, io.Closer, error) { - return fakeSpanFactory{}, &nilCloser{}, nil + return noopTracingServer{}, &nilCloser{}, nil } } diff --git a/go/trace/opentracing.go b/go/trace/opentracing.go index ea41443de70..28f3e14ae4c 100644 --- a/go/trace/opentracing.go +++ b/go/trace/opentracing.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -16,10 +16,14 @@ limitations under the License. package trace import ( - "github.com/opentracing-contrib/go-grpc" + "strings" + + otgrpc "github.com/opentracing-contrib/go-grpc" "github.com/opentracing/opentracing-go" "golang.org/x/net/context" "google.golang.org/grpc" + "vitess.io/vitess/go/vt/proto/vtrpc" + "vitess.io/vitess/go/vt/vterrors" ) var _ Span = (*openTracingSpan)(nil) @@ -40,18 +44,24 @@ func (js openTracingSpan) Annotate(key string, value interface{}) { var _ tracingService = (*openTracingService)(nil) +type tracer interface { + GetOpenTracingTracer() opentracing.Tracer +} + type openTracingService struct { - Tracer opentracing.Tracer + Tracer tracer } // AddGrpcServerOptions is part of an interface implementation func (jf openTracingService) AddGrpcServerOptions(addInterceptors func(s grpc.StreamServerInterceptor, u grpc.UnaryServerInterceptor)) { - addInterceptors(otgrpc.OpenTracingStreamServerInterceptor(jf.Tracer), otgrpc.OpenTracingServerInterceptor(jf.Tracer)) + ot := jf.Tracer.GetOpenTracingTracer() + addInterceptors(otgrpc.OpenTracingStreamServerInterceptor(ot), otgrpc.OpenTracingServerInterceptor(ot)) } // AddGrpcClientOptions is part of an interface implementation func (jf openTracingService) AddGrpcClientOptions(addInterceptors func(s grpc.StreamClientInterceptor, u grpc.UnaryClientInterceptor)) { - addInterceptors(otgrpc.OpenTracingStreamClientInterceptor(jf.Tracer), otgrpc.OpenTracingClientInterceptor(jf.Tracer)) + ot := jf.Tracer.GetOpenTracingTracer() + addInterceptors(otgrpc.OpenTracingStreamClientInterceptor(ot), otgrpc.OpenTracingClientInterceptor(ot)) } // NewClientSpan is part of an interface implementation @@ -65,24 +75,52 @@ func (jf openTracingService) NewClientSpan(parent Span, serviceName, label strin func (jf openTracingService) New(parent Span, label string) Span { var innerSpan opentracing.Span if parent == nil { - innerSpan = jf.Tracer.StartSpan(label) + innerSpan = jf.Tracer.GetOpenTracingTracer().StartSpan(label) } else { jaegerParent := parent.(openTracingSpan) span := jaegerParent.otSpan - innerSpan = jf.Tracer.StartSpan(label, opentracing.ChildOf(span.Context())) + innerSpan = jf.Tracer.GetOpenTracingTracer().StartSpan(label, opentracing.ChildOf(span.Context())) } return openTracingSpan{otSpan: innerSpan} } +func extractMapFromString(in string) (opentracing.TextMapCarrier, error) { + m := make(opentracing.TextMapCarrier) + items := strings.Split(in, ":") + if len(items) < 2 { + return nil, vterrors.Errorf(vtrpc.Code_INVALID_ARGUMENT, "expected transmitted context to contain at least span id and trace id") + } + for _, v := range items { + idx := strings.Index(v, "=") + if idx < 1 { + return nil, vterrors.Errorf(vtrpc.Code_INVALID_ARGUMENT, "every element in the context string has to be in the form key=value") + } + m[v[0:idx]] = v[idx+1:] + } + return m, nil +} + +func (jf openTracingService) NewFromString(parent, label string) (Span, error) { + carrier, err := extractMapFromString(parent) + if err != nil { + return nil, err + } + spanContext, err := jf.Tracer.GetOpenTracingTracer().Extract(opentracing.TextMap, carrier) + if err != nil { + return nil, vterrors.Wrap(err, "failed to deserialize span context") + } + innerSpan := jf.Tracer.GetOpenTracingTracer().StartSpan(label, opentracing.ChildOf(spanContext)) + return openTracingSpan{otSpan: innerSpan}, nil +} + // FromContext is part of an interface implementation func (jf openTracingService) FromContext(ctx context.Context) (Span, bool) { innerSpan := opentracing.SpanFromContext(ctx) - if innerSpan != nil { - return openTracingSpan{otSpan: innerSpan}, true - } else { + if innerSpan == nil { return nil, false } + return openTracingSpan{otSpan: innerSpan}, true } // NewContext is part of an interface implementation diff --git a/go/trace/opentracing_test.go b/go/trace/opentracing_test.go new file mode 100644 index 00000000000..19bdbce9019 --- /dev/null +++ b/go/trace/opentracing_test.go @@ -0,0 +1,41 @@ +/* +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 trace + +import ( + "testing" + + "github.com/opentracing/opentracing-go" + "github.com/stretchr/testify/assert" +) + +func TestExtractMapFromString(t *testing.T) { + expected := make(opentracing.TextMapCarrier) + expected["apa"] = "12" + expected["banan"] = "x-tracing-backend-12" + result, err := extractMapFromString("apa=12:banan=x-tracing-backend-12") + assert.NoError(t, err) + assert.Equal(t, expected, result) +} + +func TestErrorConditions(t *testing.T) { + _, err := extractMapFromString("") + assert.Error(t, err) + + _, err = extractMapFromString("key=value:keywithnovalue") + assert.Error(t, err) +} diff --git a/go/trace/plugin_jaeger.go b/go/trace/plugin_jaeger.go index 652cb42352c..685fda78e48 100644 --- a/go/trace/plugin_jaeger.go +++ b/go/trace/plugin_jaeger.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -56,6 +56,9 @@ var ( // JAEGER_AGENT_PORT func newJagerTracerFromEnv(serviceName string) (tracingService, io.Closer, error) { cfg, err := config.FromEnv() + if err != nil { + return nil, nil, err + } if cfg.ServiceName == "" { cfg.ServiceName = serviceName } @@ -79,9 +82,19 @@ func newJagerTracerFromEnv(serviceName string) (tracingService, io.Closer, error opentracing.SetGlobalTracer(tracer) - return openTracingService{tracer}, closer, nil + return openTracingService{Tracer: &jaegerTracer{actual: tracer}}, closer, nil } func init() { tracingBackendFactories["opentracing-jaeger"] = newJagerTracerFromEnv } + +var _ tracer = (*jaegerTracer)(nil) + +type jaegerTracer struct { + actual opentracing.Tracer +} + +func (jt *jaegerTracer) GetOpenTracingTracer() opentracing.Tracer { + return jt.actual +} diff --git a/go/trace/trace.go b/go/trace/trace.go index b52c4ceb901..768d98a546e 100644 --- a/go/trace/trace.go +++ b/go/trace/trace.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -45,28 +45,39 @@ type Span interface { // NewSpan creates a new Span with the currently installed tracing plugin. // If no tracing plugin is installed, it returns a fake Span that does nothing. func NewSpan(inCtx context.Context, label string) (Span, context.Context) { - parent, _ := spanFactory.FromContext(inCtx) - span := spanFactory.New(parent, label) - outCtx := spanFactory.NewContext(inCtx, span) + parent, _ := currentTracer.FromContext(inCtx) + span := currentTracer.New(parent, label) + outCtx := currentTracer.NewContext(inCtx, span) return span, outCtx } +// NewFromString creates a new Span with the currently installed tracing plugin, extracting the span context from +// the provided string. +func NewFromString(inCtx context.Context, parent, label string) (Span, context.Context, error) { + span, err := currentTracer.NewFromString(parent, label) + if err != nil { + return nil, nil, err + } + outCtx := currentTracer.NewContext(inCtx, span) + return span, outCtx, nil +} + // AnnotateSQL annotates information about a sql query in the span. This is done in a way // so as to not leak personally identifying information (PII), or sensitive personal information (SPI) func AnnotateSQL(span Span, sql string) { - span.Annotate("sql-statement-type", sqlparser.StmtType(sqlparser.Preview(sql))) + span.Annotate("sql-statement-type", sqlparser.Preview(sql).String()) } // FromContext returns the Span from a Context if present. The bool return // value indicates whether a Span was present in the Context. func FromContext(ctx context.Context) (Span, bool) { - return spanFactory.FromContext(ctx) + return currentTracer.FromContext(ctx) } // NewContext returns a context based on parent with a new Span value. func NewContext(parent context.Context, span Span) context.Context { - return spanFactory.NewContext(parent, span) + return currentTracer.NewContext(parent, span) } // CopySpan creates a new context from parentCtx, with only the trace span @@ -78,12 +89,14 @@ func CopySpan(parentCtx, spanCtx context.Context) context.Context { return parentCtx } +// AddGrpcServerOptions adds GRPC interceptors that read the parent span from the grpc packets func AddGrpcServerOptions(addInterceptors func(s grpc.StreamServerInterceptor, u grpc.UnaryServerInterceptor)) { - spanFactory.AddGrpcServerOptions(addInterceptors) + currentTracer.AddGrpcServerOptions(addInterceptors) } +// AddGrpcClientOptions adds GRPC interceptors that add parent information to outgoing grpc packets func AddGrpcClientOptions(addInterceptors func(s grpc.StreamClientInterceptor, u grpc.UnaryClientInterceptor)) { - spanFactory.AddGrpcClientOptions(addInterceptors) + currentTracer.AddGrpcClientOptions(addInterceptors) } // tracingService is an interface for creating spans or extracting them from Contexts. @@ -91,7 +104,10 @@ type tracingService interface { // New creates a new span from an existing one, if provided. The parent can also be nil New(parent Span, label string) Span - // FromContext extracts a span from a context, making it possible to annotate the span with additional information. + // NewFromString creates a new span and uses the provided string to reconstitute the parent span + NewFromString(parent, label string) (Span, error) + + // FromContext extracts a span from a context, making it possible to annotate the span with additional information FromContext(ctx context.Context) (Span, bool) // NewContext creates a new context containing the provided span @@ -104,12 +120,14 @@ type tracingService interface { AddGrpcClientOptions(addInterceptors func(s grpc.StreamClientInterceptor, u grpc.UnaryClientInterceptor)) } +// TracerFactory creates a tracing service for the service provided. It's important to close the provided io.Closer +// object to make sure that all spans are sent to the backend before the process exits. type TracerFactory func(serviceName string) (tracingService, io.Closer, error) // tracingBackendFactories should be added to by a plugin during init() to install itself var tracingBackendFactories = make(map[string]TracerFactory) -var spanFactory tracingService = fakeSpanFactory{} +var currentTracer tracingService = noopTracingServer{} var ( tracingServer = flag.String("tracer", "noop", "tracing service to use") @@ -128,7 +146,7 @@ func StartTracing(serviceName string) io.Closer { return &nilCloser{} } - spanFactory = tracer + currentTracer = tracer log.Infof("successfully started tracing with [%s]", *tracingServer) diff --git a/go/trace/trace_test.go b/go/trace/trace_test.go index 97cc3b2c2dd..f09cc0864f6 100644 --- a/go/trace/trace_test.go +++ b/go/trace/trace_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -37,7 +37,7 @@ func TestFakeSpan(t *testing.T) { span2.Annotate("key", 42) span2.Finish() - span3, ctx := NewSpan(ctx, "label") + span3, _ := NewSpan(ctx, "label") span3.Annotate("key", 42) span3.Finish() } @@ -93,7 +93,7 @@ type fakeTracer struct { log []string } -func (f *fakeTracer) NewClientSpan(parent Span, serviceName, label string) Span { +func (f *fakeTracer) NewFromString(parent, label string) (Span, error) { panic("implement me") } diff --git a/go/trace/utils.go b/go/trace/utils.go index cf9ec2bcd61..c88bb625035 100644 --- a/go/trace/utils.go +++ b/go/trace/utils.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/automation/cluster_operation_instance.go b/go/vt/automation/cluster_operation_instance.go index 15ad59aaf09..f4c1b604db2 100644 --- a/go/vt/automation/cluster_operation_instance.go +++ b/go/vt/automation/cluster_operation_instance.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/automation/copy_schema_shard_task.go b/go/vt/automation/copy_schema_shard_task.go index 168dea87d65..17df52e65d5 100644 --- a/go/vt/automation/copy_schema_shard_task.go +++ b/go/vt/automation/copy_schema_shard_task.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/automation/copy_schema_shard_task_test.go b/go/vt/automation/copy_schema_shard_task_test.go index b87bb246370..68d9110e860 100644 --- a/go/vt/automation/copy_schema_shard_task_test.go +++ b/go/vt/automation/copy_schema_shard_task_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/automation/horizontal_resharding_task.go b/go/vt/automation/horizontal_resharding_task.go index 9cc629d7266..233c9a39446 100644 --- a/go/vt/automation/horizontal_resharding_task.go +++ b/go/vt/automation/horizontal_resharding_task.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/automation/horizontal_resharding_task_test.go b/go/vt/automation/horizontal_resharding_task_test.go index e1f08a3e08b..589b4811624 100644 --- a/go/vt/automation/horizontal_resharding_task_test.go +++ b/go/vt/automation/horizontal_resharding_task_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/automation/id_generator.go b/go/vt/automation/id_generator.go index 233cf7ca66c..558e8fab11b 100644 --- a/go/vt/automation/id_generator.go +++ b/go/vt/automation/id_generator.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/automation/migrate_served_from_task.go b/go/vt/automation/migrate_served_from_task.go index ef2eb3d3efc..21a4fa99e90 100644 --- a/go/vt/automation/migrate_served_from_task.go +++ b/go/vt/automation/migrate_served_from_task.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/automation/migrate_served_types_task.go b/go/vt/automation/migrate_served_types_task.go index 70d84cbc4f9..316eff1da86 100644 --- a/go/vt/automation/migrate_served_types_task.go +++ b/go/vt/automation/migrate_served_types_task.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/automation/migrate_served_types_task_test.go b/go/vt/automation/migrate_served_types_task_test.go index d22ee52fa85..065f51bcf1c 100644 --- a/go/vt/automation/migrate_served_types_task_test.go +++ b/go/vt/automation/migrate_served_types_task_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/automation/rebuild_keyspace_graph_task.go b/go/vt/automation/rebuild_keyspace_graph_task.go index 6a2293e5c08..068b1d3f3ce 100644 --- a/go/vt/automation/rebuild_keyspace_graph_task.go +++ b/go/vt/automation/rebuild_keyspace_graph_task.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/automation/rebuild_keyspace_graph_task_test.go b/go/vt/automation/rebuild_keyspace_graph_task_test.go index 649fdc1db11..11db634a8d4 100644 --- a/go/vt/automation/rebuild_keyspace_graph_task_test.go +++ b/go/vt/automation/rebuild_keyspace_graph_task_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/automation/scheduler.go b/go/vt/automation/scheduler.go index ddaa1fc4c69..d4dc5533fa1 100644 --- a/go/vt/automation/scheduler.go +++ b/go/vt/automation/scheduler.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/automation/scheduler_test.go b/go/vt/automation/scheduler_test.go index 51b24f104e3..662b263169b 100644 --- a/go/vt/automation/scheduler_test.go +++ b/go/vt/automation/scheduler_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/automation/split_clone_task.go b/go/vt/automation/split_clone_task.go index 508d37a6fef..df60be73ab7 100644 --- a/go/vt/automation/split_clone_task.go +++ b/go/vt/automation/split_clone_task.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/automation/split_clone_task_test.go b/go/vt/automation/split_clone_task_test.go index 8215bcc160c..5184f8f7aec 100644 --- a/go/vt/automation/split_clone_task_test.go +++ b/go/vt/automation/split_clone_task_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/automation/split_diff_task.go b/go/vt/automation/split_diff_task.go index 5840f0a4e51..bce8a6d8a53 100644 --- a/go/vt/automation/split_diff_task.go +++ b/go/vt/automation/split_diff_task.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/automation/task.go b/go/vt/automation/task.go index 2cbdf674990..0966a1b8bac 100644 --- a/go/vt/automation/task.go +++ b/go/vt/automation/task.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/automation/task_containers.go b/go/vt/automation/task_containers.go index 1b7a68ffe7d..e5986f414b6 100644 --- a/go/vt/automation/task_containers.go +++ b/go/vt/automation/task_containers.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/automation/tasks.go b/go/vt/automation/tasks.go index fb9fee20e59..00e4bb99422 100644 --- a/go/vt/automation/tasks.go +++ b/go/vt/automation/tasks.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/automation/testutils_test.go b/go/vt/automation/testutils_test.go index 62ff1023300..da6026d7423 100644 --- a/go/vt/automation/testutils_test.go +++ b/go/vt/automation/testutils_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/automation/vertical_split_clone_task.go b/go/vt/automation/vertical_split_clone_task.go index ef8a892ba1a..b5ed426b2b1 100644 --- a/go/vt/automation/vertical_split_clone_task.go +++ b/go/vt/automation/vertical_split_clone_task.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/automation/vertical_split_clone_task_test.go b/go/vt/automation/vertical_split_clone_task_test.go index ed3420a44dd..6b9fef21c4a 100644 --- a/go/vt/automation/vertical_split_clone_task_test.go +++ b/go/vt/automation/vertical_split_clone_task_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/automation/vertical_split_diff_task.go b/go/vt/automation/vertical_split_diff_task.go index ed5f636e58d..f6247d99dd5 100644 --- a/go/vt/automation/vertical_split_diff_task.go +++ b/go/vt/automation/vertical_split_diff_task.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/automation/vertical_split_task.go b/go/vt/automation/vertical_split_task.go index 7dd8f99ea42..a490b5a25be 100644 --- a/go/vt/automation/vertical_split_task.go +++ b/go/vt/automation/vertical_split_task.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/automation/vertical_split_task_test.go b/go/vt/automation/vertical_split_task_test.go index 0ee3987324e..975cee88abd 100644 --- a/go/vt/automation/vertical_split_task_test.go +++ b/go/vt/automation/vertical_split_task_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/automation/vtctlclient_wrapper.go b/go/vt/automation/vtctlclient_wrapper.go index 99fc74a7ffa..30ef919debf 100644 --- a/go/vt/automation/vtctlclient_wrapper.go +++ b/go/vt/automation/vtctlclient_wrapper.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/automation/vtworkerclient_wrapper.go b/go/vt/automation/vtworkerclient_wrapper.go index d5c8795927c..949941f790c 100644 --- a/go/vt/automation/vtworkerclient_wrapper.go +++ b/go/vt/automation/vtworkerclient_wrapper.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/automation/wait_for_filtered_replication_task.go b/go/vt/automation/wait_for_filtered_replication_task.go index c820a75801c..a7e034899b8 100644 --- a/go/vt/automation/wait_for_filtered_replication_task.go +++ b/go/vt/automation/wait_for_filtered_replication_task.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/binlog/binlog_streamer.go b/go/vt/binlog/binlog_streamer.go index 77b7d02f5d8..9a2dec4c866 100644 --- a/go/vt/binlog/binlog_streamer.go +++ b/go/vt/binlog/binlog_streamer.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/binlog/binlog_streamer_rbr_test.go b/go/vt/binlog/binlog_streamer_rbr_test.go index d30255d4f52..b235373a59f 100644 --- a/go/vt/binlog/binlog_streamer_rbr_test.go +++ b/go/vt/binlog/binlog_streamer_rbr_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/binlog/binlog_streamer_test.go b/go/vt/binlog/binlog_streamer_test.go index 576e7b5620c..d8edb2b7eb3 100644 --- a/go/vt/binlog/binlog_streamer_test.go +++ b/go/vt/binlog/binlog_streamer_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/binlog/binlogplayer/binlog_player.go b/go/vt/binlog/binlogplayer/binlog_player.go index b62522a1ce9..da92a374289 100644 --- a/go/vt/binlog/binlogplayer/binlog_player.go +++ b/go/vt/binlog/binlogplayer/binlog_player.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/binlog/binlogplayer/binlog_player_test.go b/go/vt/binlog/binlogplayer/binlog_player_test.go index dedcfcc0858..f84e2b01b78 100644 --- a/go/vt/binlog/binlogplayer/binlog_player_test.go +++ b/go/vt/binlog/binlogplayer/binlog_player_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/binlog/binlogplayer/client.go b/go/vt/binlog/binlogplayer/client.go index 0da96f56ab2..0d9f2567ade 100644 --- a/go/vt/binlog/binlogplayer/client.go +++ b/go/vt/binlog/binlogplayer/client.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/binlog/binlogplayer/dbclient.go b/go/vt/binlog/binlogplayer/dbclient.go index 8ebf379bba9..83533ddb34a 100644 --- a/go/vt/binlog/binlogplayer/dbclient.go +++ b/go/vt/binlog/binlogplayer/dbclient.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/binlog/binlogplayer/fake_dbclient.go b/go/vt/binlog/binlogplayer/fake_dbclient.go index ec6237073f1..3b794dafd72 100644 --- a/go/vt/binlog/binlogplayer/fake_dbclient.go +++ b/go/vt/binlog/binlogplayer/fake_dbclient.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Vitess Authors. +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. diff --git a/go/vt/binlog/binlogplayer/framework_test.go b/go/vt/binlog/binlogplayer/framework_test.go index 2c761a977ca..1db72bc27da 100644 --- a/go/vt/binlog/binlogplayer/framework_test.go +++ b/go/vt/binlog/binlogplayer/framework_test.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Vitess Authors. +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. diff --git a/go/vt/binlog/binlogplayer/mock_dbclient.go b/go/vt/binlog/binlogplayer/mock_dbclient.go index fd606c7d482..535c432950a 100644 --- a/go/vt/binlog/binlogplayer/mock_dbclient.go +++ b/go/vt/binlog/binlogplayer/mock_dbclient.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/binlog/binlogplayertest/player.go b/go/vt/binlog/binlogplayertest/player.go index 161f16397d7..169bd7b6646 100644 --- a/go/vt/binlog/binlogplayertest/player.go +++ b/go/vt/binlog/binlogplayertest/player.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/binlog/event_streamer.go b/go/vt/binlog/event_streamer.go index 6fd098a78a3..02bbb647cc7 100644 --- a/go/vt/binlog/event_streamer.go +++ b/go/vt/binlog/event_streamer.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/binlog/event_streamer_test.go b/go/vt/binlog/event_streamer_test.go index a04b52ed203..1a487efaf46 100644 --- a/go/vt/binlog/event_streamer_test.go +++ b/go/vt/binlog/event_streamer_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/binlog/eventtoken/compare.go b/go/vt/binlog/eventtoken/compare.go index 9e0d35f3779..2fe908527d2 100644 --- a/go/vt/binlog/eventtoken/compare.go +++ b/go/vt/binlog/eventtoken/compare.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/binlog/eventtoken/compare_test.go b/go/vt/binlog/eventtoken/compare_test.go index 69c963a3b16..bf638602ded 100644 --- a/go/vt/binlog/eventtoken/compare_test.go +++ b/go/vt/binlog/eventtoken/compare_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/binlog/grpcbinlogplayer/player.go b/go/vt/binlog/grpcbinlogplayer/player.go index e52e1a28ed5..21eb81cbb38 100644 --- a/go/vt/binlog/grpcbinlogplayer/player.go +++ b/go/vt/binlog/grpcbinlogplayer/player.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/binlog/grpcbinlogplayer/player_test.go b/go/vt/binlog/grpcbinlogplayer/player_test.go index ffd1c3d101a..b9d29e97301 100644 --- a/go/vt/binlog/grpcbinlogplayer/player_test.go +++ b/go/vt/binlog/grpcbinlogplayer/player_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/binlog/grpcbinlogstreamer/streamer.go b/go/vt/binlog/grpcbinlogstreamer/streamer.go index 0f7e561bd1a..274846247a4 100644 --- a/go/vt/binlog/grpcbinlogstreamer/streamer.go +++ b/go/vt/binlog/grpcbinlogstreamer/streamer.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/binlog/keyrange_filter.go b/go/vt/binlog/keyrange_filter.go index 6d4ae50ff14..f441f4112ed 100644 --- a/go/vt/binlog/keyrange_filter.go +++ b/go/vt/binlog/keyrange_filter.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/binlog/keyrange_filter_test.go b/go/vt/binlog/keyrange_filter_test.go index 623e7844ecc..ee92fb0ddaf 100644 --- a/go/vt/binlog/keyrange_filter_test.go +++ b/go/vt/binlog/keyrange_filter_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/binlog/keyspace_id_resolver.go b/go/vt/binlog/keyspace_id_resolver.go index a590f083754..204960f06ca 100644 --- a/go/vt/binlog/keyspace_id_resolver.go +++ b/go/vt/binlog/keyspace_id_resolver.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/binlog/slave_connection.go b/go/vt/binlog/slave_connection.go index c44d6e87f3b..c38e67af859 100644 --- a/go/vt/binlog/slave_connection.go +++ b/go/vt/binlog/slave_connection.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/binlog/tables_filter.go b/go/vt/binlog/tables_filter.go index 993fc82ff3a..721b6d94a37 100644 --- a/go/vt/binlog/tables_filter.go +++ b/go/vt/binlog/tables_filter.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/binlog/tables_filter_test.go b/go/vt/binlog/tables_filter_test.go index 6d345f7d477..6f849143e0f 100644 --- a/go/vt/binlog/tables_filter_test.go +++ b/go/vt/binlog/tables_filter_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/binlog/updatestream.go b/go/vt/binlog/updatestream.go index fe77e431c30..20829fc257f 100644 --- a/go/vt/binlog/updatestream.go +++ b/go/vt/binlog/updatestream.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/binlog/updatestreamctl.go b/go/vt/binlog/updatestreamctl.go index 3525c28a2b8..142324fd298 100644 --- a/go/vt/binlog/updatestreamctl.go +++ b/go/vt/binlog/updatestreamctl.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/callerid/callerid.go b/go/vt/callerid/callerid.go index e5d3edbcd2f..f5f0d0c2318 100644 --- a/go/vt/callerid/callerid.go +++ b/go/vt/callerid/callerid.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Package callerid stores/retrives CallerIDs (immediate CallerID +// Package callerid stores/retrieves CallerIDs (immediate CallerID // and effective CallerID) to/from the Context package callerid diff --git a/go/vt/callerid/testsuite/callerid_test.go b/go/vt/callerid/testsuite/callerid_test.go index 9a4968e1e68..aa6363a8478 100644 --- a/go/vt/callerid/testsuite/callerid_test.go +++ b/go/vt/callerid/testsuite/callerid_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/callerid/testsuite/testsuite.go b/go/vt/callerid/testsuite/testsuite.go index 3df5e321d1a..2787e31d7b4 100644 --- a/go/vt/callerid/testsuite/testsuite.go +++ b/go/vt/callerid/testsuite/testsuite.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/callinfo/callinfo.go b/go/vt/callinfo/callinfo.go index df2c6272bf7..6ea033ac9c6 100644 --- a/go/vt/callinfo/callinfo.go +++ b/go/vt/callinfo/callinfo.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/callinfo/fakecallinfo/fakecallinfo.go b/go/vt/callinfo/fakecallinfo/fakecallinfo.go index 84a6df9f5d3..902f0723d77 100644 --- a/go/vt/callinfo/fakecallinfo/fakecallinfo.go +++ b/go/vt/callinfo/fakecallinfo/fakecallinfo.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/callinfo/plugin_grpc.go b/go/vt/callinfo/plugin_grpc.go index 558609069d1..c32c4861fb0 100644 --- a/go/vt/callinfo/plugin_grpc.go +++ b/go/vt/callinfo/plugin_grpc.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/callinfo/plugin_mysql.go b/go/vt/callinfo/plugin_mysql.go index d82f1ce1704..e5b5b36da09 100644 --- a/go/vt/callinfo/plugin_mysql.go +++ b/go/vt/callinfo/plugin_mysql.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Vitess Authors +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/concurrency/error_recorder.go b/go/vt/concurrency/error_recorder.go index f0a2015cd32..7daf1a2debd 100644 --- a/go/vt/concurrency/error_recorder.go +++ b/go/vt/concurrency/error_recorder.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/dbconfigs/credentials.go b/go/vt/dbconfigs/credentials.go index 3062e7a2151..f437879e4b9 100644 --- a/go/vt/dbconfigs/credentials.go +++ b/go/vt/dbconfigs/credentials.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -16,7 +16,7 @@ limitations under the License. package dbconfigs -// This file contains logic for a plugable credentials system. +// This file contains logic for a pluggable credentials system. // The default implementation is file based. // The flags are global, but only programs that need to access the database // link with this library, so we should be safe. diff --git a/go/vt/dbconfigs/dbconfigs.go b/go/vt/dbconfigs/dbconfigs.go index c15ad1e6415..2976f05c30d 100644 --- a/go/vt/dbconfigs/dbconfigs.go +++ b/go/vt/dbconfigs/dbconfigs.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/dbconfigs/dbconfigs_test.go b/go/vt/dbconfigs/dbconfigs_test.go index 12b9d672249..54b413b9038 100644 --- a/go/vt/dbconfigs/dbconfigs_test.go +++ b/go/vt/dbconfigs/dbconfigs_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/dbconnpool/connection.go b/go/vt/dbconnpool/connection.go index 921c752e5cb..294a7319233 100644 --- a/go/vt/dbconnpool/connection.go +++ b/go/vt/dbconnpool/connection.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/dbconnpool/connection_pool.go b/go/vt/dbconnpool/connection_pool.go index eedee5ddff9..472f4942cde 100644 --- a/go/vt/dbconnpool/connection_pool.go +++ b/go/vt/dbconnpool/connection_pool.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -84,6 +84,7 @@ func NewConnectionPool(name string, capacity int, idleTimeout time.Duration, dns stats.NewCounterDurationFunc(name+"WaitTime", "Connection pool wait time", cp.WaitTime) stats.NewGaugeDurationFunc(name+"IdleTimeout", "Connection pool idle timeout", cp.IdleTimeout) stats.NewGaugeFunc(name+"IdleClosed", "Connection pool idle closed", cp.IdleClosed) + stats.NewCounterFunc(name+"Exhausted", "Number of times pool had zero available slots", cp.Exhausted) return cp } @@ -355,3 +356,12 @@ func (cp *ConnectionPool) IdleClosed() int64 { } return p.IdleClosed() } + +// Exhausted returns the number of times available went to zero for the pool. +func (cp *ConnectionPool) Exhausted() int64 { + p := cp.pool() + if p == nil { + return 0 + } + return p.Exhausted() +} diff --git a/go/vt/dbconnpool/pooled_connection.go b/go/vt/dbconnpool/pooled_connection.go index 94bf4474655..926b9eea1d6 100644 --- a/go/vt/dbconnpool/pooled_connection.go +++ b/go/vt/dbconnpool/pooled_connection.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/discovery/fake_healthcheck.go b/go/vt/discovery/fake_healthcheck.go index 345ea4a5351..4e9f0369c2f 100644 --- a/go/vt/discovery/fake_healthcheck.go +++ b/go/vt/discovery/fake_healthcheck.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 @@ -21,6 +21,7 @@ import ( "sync" "vitess.io/vitess/go/vt/topo" + "vitess.io/vitess/go/vt/topo/topoproto" "vitess.io/vitess/go/vt/vttablet/queryservice" "vitess.io/vitess/go/vt/vttablet/sandboxconn" @@ -104,6 +105,17 @@ func (fhc *FakeHealthCheck) RemoveTablet(tablet *topodatapb.Tablet) { fhc.mu.Lock() defer fhc.mu.Unlock() key := TabletToMapKey(tablet) + item, ok := fhc.items[key] + if !ok { + return + } + // Make sure the key still corresponds to the tablet we want to delete. + // If it doesn't match, we should do nothing. The tablet we were asked to + // delete is already gone, and some other tablet is using the key + // (host:port) that the original tablet used to use, which is fine. + if !topoproto.TabletAliasEqual(tablet.Alias, item.ts.Tablet.Alias) { + return + } delete(fhc.items, key) } diff --git a/go/vt/discovery/healthcheck.go b/go/vt/discovery/healthcheck.go index 2e5e527b9f8..e7abf1dbbde 100644 --- a/go/vt/discovery/healthcheck.go +++ b/go/vt/discovery/healthcheck.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 @@ -688,6 +688,17 @@ func (hc *HealthCheckImpl) deleteConn(tablet *topodatapb.Tablet) { if !ok { return } + // Make sure the key still corresponds to the tablet we want to delete. + // If it doesn't match, we should do nothing. The tablet we were asked to + // delete is already gone, and some other tablet is using the key + // (host:port) that the original tablet used to use, which is fine. + if !topoproto.TabletAliasEqual(tablet.Alias, th.latestTabletStats.Tablet.Alias) { + return + } + hc.deleteConnLocked(key, th) +} + +func (hc *HealthCheckImpl) deleteConnLocked(key string, th *tabletHealth) { th.latestTabletStats.Up = false th.cancelFunc() delete(hc.addrToHealth, key) @@ -733,10 +744,18 @@ func (hc *HealthCheckImpl) AddTablet(tablet *topodatapb.Tablet, name string) { hc.mu.Unlock() return } - if _, ok := hc.addrToHealth[key]; ok { - hc.mu.Unlock() - log.Warningf("adding duplicate tablet %v for %v: %+v", name, tablet.Alias.Cell, tablet) - return + if th, ok := hc.addrToHealth[key]; ok { + // Something already exists at this key. + // If it's the same tablet, something is wrong. + if topoproto.TabletAliasEqual(th.latestTabletStats.Tablet.Alias, tablet.Alias) { + hc.mu.Unlock() + log.Warningf("refusing to add duplicate tablet %v for %v: %+v", name, tablet.Alias.Cell, tablet) + return + } + // If it's a different tablet, then we trust this new tablet that claims + // it has taken over the host:port that the old tablet used to be on. + // Remove the old tablet to clear the way. + hc.deleteConnLocked(key, th) } hc.addrToHealth[key] = &tabletHealth{ cancelFunc: cancelFunc, @@ -752,15 +771,13 @@ func (hc *HealthCheckImpl) AddTablet(tablet *topodatapb.Tablet, name string) { // RemoveTablet removes the tablet, and stops the health check. // It does not block. func (hc *HealthCheckImpl) RemoveTablet(tablet *topodatapb.Tablet) { - go hc.deleteConn(tablet) + hc.deleteConn(tablet) } // ReplaceTablet removes the old tablet and adds the new tablet. func (hc *HealthCheckImpl) ReplaceTablet(old, new *topodatapb.Tablet, name string) { - go func() { - hc.deleteConn(old) - hc.AddTablet(new, name) - }() + hc.deleteConn(old) + hc.AddTablet(new, name) } // WaitForInitialStatsUpdates waits until all tablets added via AddTablet() call diff --git a/go/vt/discovery/healthcheck_test.go b/go/vt/discovery/healthcheck_test.go index caa61e2d1fd..29afa001aac 100644 --- a/go/vt/discovery/healthcheck_test.go +++ b/go/vt/discovery/healthcheck_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 @@ -656,6 +656,22 @@ func (l *listener) StatsUpdate(ts *TabletStats) { l.output <- ts } +type fakeConn struct { + queryservice.QueryService + tablet *topodatapb.Tablet + // If fixedResult is set, the channels are not used. + fixedResult *querypb.StreamHealthResponse + // hcChan should be an unbuffered channel which holds the tablet's next health response. + hcChan chan *querypb.StreamHealthResponse + // errCh is either an unbuffered channel which holds the stream error to return, or nil. + errCh chan error + // cbErrCh is a channel which receives errors returned from the supplied callback. + cbErrCh chan error + + mu sync.Mutex + canceled bool +} + func createFakeConn(tablet *topodatapb.Tablet, c chan *querypb.StreamHealthResponse) *fakeConn { key := TabletToMapKey(tablet) conn := &fakeConn{ @@ -668,27 +684,27 @@ func createFakeConn(tablet *topodatapb.Tablet, c chan *querypb.StreamHealthRespo return conn } -func discoveryDialer(tablet *topodatapb.Tablet, failFast grpcclient.FailFast) (queryservice.QueryService, error) { +func createFixedHealthConn(tablet *topodatapb.Tablet, fixedResult *querypb.StreamHealthResponse) *fakeConn { key := TabletToMapKey(tablet) - return connMap[key], nil + conn := &fakeConn{ + QueryService: fakes.ErrorQueryService, + tablet: tablet, + fixedResult: fixedResult, + } + connMap[key] = conn + return conn } -type fakeConn struct { - queryservice.QueryService - tablet *topodatapb.Tablet - // hcChan should be an unbuffered channel which holds the tablet's next health response. - hcChan chan *querypb.StreamHealthResponse - // errCh is either an unbuffered channel which holds the stream error to return, or nil. - errCh chan error - // cbErrCh is a channel which receives errors returned from the supplied callback. - cbErrCh chan error - - mu sync.Mutex - canceled bool +func discoveryDialer(tablet *topodatapb.Tablet, failFast grpcclient.FailFast) (queryservice.QueryService, error) { + key := TabletToMapKey(tablet) + return connMap[key], nil } // StreamHealth implements queryservice.QueryService. func (fc *fakeConn) StreamHealth(ctx context.Context, callback func(shr *querypb.StreamHealthResponse) error) error { + if fc.fixedResult != nil { + return callback(fc.fixedResult) + } for { select { case shr := <-fc.hcChan: @@ -696,7 +712,10 @@ func (fc *fakeConn) StreamHealth(ctx context.Context, callback func(shr *querypb if err == io.EOF { return nil } - fc.cbErrCh <- err + select { + case fc.cbErrCh <- err: + case <-ctx.Done(): + } return err } case err := <-fc.errCh: diff --git a/go/vt/discovery/replicationlag.go b/go/vt/discovery/replicationlag.go index 1e8237c8dca..dea0f5f5152 100644 --- a/go/vt/discovery/replicationlag.go +++ b/go/vt/discovery/replicationlag.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 @@ -25,9 +25,10 @@ import ( var ( // lowReplicationLag defines the duration that replication lag is low enough that the VTTablet is considered healthy. - lowReplicationLag = flag.Duration("discovery_low_replication_lag", 30*time.Second, "the replication lag that is considered low enough to be healthy") - highReplicationLagMinServing = flag.Duration("discovery_high_replication_lag_minimum_serving", 2*time.Hour, "the replication lag that is considered too high when selecting the minimum num vttablets for serving") - minNumTablets = flag.Int("min_number_serving_vttablets", 2, "the minimum number of vttablets that will be continue to be used even with low replication lag") + lowReplicationLag = flag.Duration("discovery_low_replication_lag", 30*time.Second, "the replication lag that is considered low enough to be healthy") + highReplicationLagMinServing = flag.Duration("discovery_high_replication_lag_minimum_serving", 2*time.Hour, "the replication lag that is considered too high when selecting the minimum num vttablets for serving") + minNumTablets = flag.Int("min_number_serving_vttablets", 2, "the minimum number of vttablets that will be continue to be used even with low replication lag") + legacyReplicationLagAlgorithm = flag.Bool("legacy_replication_lag_algorithm", true, "use the legacy algorithm when selecting the vttablets for serving") ) // IsReplicationLagHigh verifies that the given TabletStats refers to a tablet with high @@ -43,7 +44,17 @@ func IsReplicationLagVeryHigh(tabletStats *TabletStats) bool { } // FilterByReplicationLag filters the list of TabletStats by TabletStats.Stats.SecondsBehindMaster. -// The algorithm (TabletStats that is non-serving or has error is ignored): +// Note that TabletStats that is non-serving or has error is ignored. +// +// The simplified logic: +// - Return tablets that have lag <= lowReplicationLag. +// - Make sure we return at least minNumTablets tablets, if there are enough one with lag <= highReplicationLagMinServing. +// For example, with the default of 30s / 2h / 2, this means: +// - lags of (5s, 10s, 15s, 120s) return the first three +// - lags of (30m, 35m, 40m, 45m) return the first two +// - lags of (2h, 3h, 4h, 5h) return the first one +// +// The legacy algorithm (default for now): // - Return the list if there is 0 or 1 tablet. // - Return the list if all tablets have <=30s lag. // - Filter by replication lag: for each tablet, if the mean value without it is more than 0.7 of the mean value across all tablets, it is valid. @@ -58,16 +69,46 @@ func IsReplicationLagVeryHigh(tabletStats *TabletStats) bool { // * degraded_threshold: this is only used by vttablet for display. It should match // discovery_low_replication_lag here, so the vttablet status display matches what vtgate will do of it. func FilterByReplicationLag(tabletStatsList []*TabletStats) []*TabletStats { - res := filterByLag(tabletStatsList) + if !*legacyReplicationLagAlgorithm { + return filterByLag(tabletStatsList) + } + + res := filterByLagWithLegacyAlgorithm(tabletStatsList) // run the filter again if exactly one tablet is removed, // and we have spare tablets. if len(res) > *minNumTablets && len(res) == len(tabletStatsList)-1 { - res = filterByLag(res) + res = filterByLagWithLegacyAlgorithm(res) } return res } func filterByLag(tabletStatsList []*TabletStats) []*TabletStats { + list := make([]tabletLagSnapshot, 0, len(tabletStatsList)) + // filter non-serving tablets and those with very high replication lag + for _, ts := range tabletStatsList { + if !ts.Serving || ts.LastError != nil || ts.Stats == nil || IsReplicationLagVeryHigh(ts) { + continue + } + // Pull the current replication lag for a stable sort later. + list = append(list, tabletLagSnapshot{ + ts: ts, + replag: ts.Stats.SecondsBehindMaster}) + } + + // Sort by replication lag. + sort.Sort(byReplag(list)) + + // Pick those with low replication lag, but at least minNumTablets tablets regardless. + res := make([]*TabletStats, 0, len(list)) + for i := 0; i < len(list); i++ { + if !IsReplicationLagHigh(list[i].ts) || i < *minNumTablets { + res = append(res, list[i].ts) + } + } + return res +} + +func filterByLagWithLegacyAlgorithm(tabletStatsList []*TabletStats) []*TabletStats { list := make([]*TabletStats, 0, len(tabletStatsList)) // filter non-serving tablets for _, ts := range tabletStatsList { diff --git a/go/vt/discovery/replicationlag_test.go b/go/vt/discovery/replicationlag_test.go index 2053f60d5b1..40e184fc8b6 100644 --- a/go/vt/discovery/replicationlag_test.go +++ b/go/vt/discovery/replicationlag_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 @@ -29,6 +29,11 @@ func testSetMinNumTablets(newMin int) { *minNumTablets = newMin } +// testSetLegacyReplicationLagAlgorithm is a test helper function, if this is used by a production code path, something is wrong. +func testSetLegacyReplicationLagAlgorithm(newLegacy bool) { + *legacyReplicationLagAlgorithm = newLegacy +} + func TestFilterByReplicationLagUnhealthy(t *testing.T) { // 1 healthy serving tablet, 1 not healhty ts1 := &TabletStats{ @@ -51,6 +56,84 @@ func TestFilterByReplicationLagUnhealthy(t *testing.T) { } func TestFilterByReplicationLag(t *testing.T) { + // Use simplified logic + testSetLegacyReplicationLagAlgorithm(false) + + cases := []struct { + description string + input []uint32 + output []uint32 + }{ + { + "0 tablet", + []uint32{}, + []uint32{}, + }, + { + "lags of (1s) - return all items with low lag.", + []uint32{1}, + []uint32{1}, + }, + { + "lags of (1s, 1s, 1s, 30s) - return all items with low lag.", + []uint32{1, 1, 1, 30}, + []uint32{1, 1, 1, 30}, + }, + { + "lags of (1s, 1s, 1s, 40m, 40m, 40m) - return all items with low lag.", + []uint32{1, 1, 1, 40 * 60, 40 * 60, 40 * 60}, + []uint32{1, 1, 1}, + }, + { + "lags of (1s, 40m, 40m, 40m) - return at least 2 items if they don't have very high lag.", + []uint32{1, 40 * 60, 40 * 60, 40 * 60}, + []uint32{1, 40 * 60}, + }, + { + "lags of (30m, 35m, 40m, 45m) - return at least 2 items if they don't have very high lag.", + []uint32{30 * 60, 35 * 60, 40 * 60, 45 * 60}, + []uint32{30 * 60, 35 * 60}, + }, + { + "lags of (2h, 3h, 4h, 5h) - return <2 items if the others have very high lag.", + []uint32{2 * 60 * 60, 3 * 60 * 60, 4 * 60 * 60, 5 * 60 * 60}, + []uint32{2 * 60 * 60}, + }, + { + "lags of (3h, 30h) - return nothing if all have very high lag.", + []uint32{3 * 60 * 60, 30 * 60 * 60}, + []uint32{}, + }, + } + + for _, tc := range cases { + lts := make([]*TabletStats, len(tc.input)) + for i, lag := range tc.input { + lts[i] = &TabletStats{ + Tablet: topo.NewTablet(uint32(i+1), "cell", fmt.Sprintf("host-%vs-behind", lag)), + Serving: true, + Stats: &querypb.RealtimeStats{SecondsBehindMaster: lag}, + } + } + got := FilterByReplicationLag(lts) + if len(got) != len(tc.output) { + t.Errorf("FilterByReplicationLag(%v) failed: got output:\n%v\nExpected: %v", tc.description, got, tc.output) + continue + } + for i, elag := range tc.output { + if got[i].Stats.SecondsBehindMaster != elag { + t.Errorf("FilterByReplicationLag(%v) failed: got output:\n%v\nExpected value index %v to be %v", tc.description, got, i, elag) + } + } + } + + // Reset to the default + testSetLegacyReplicationLagAlgorithm(true) +} + +func TestFilterByReplicationLagWithLegacyAlgorithm(t *testing.T) { + // Use legacy algorithm by default for now + cases := []struct { description string input []uint32 @@ -106,6 +189,23 @@ func TestFilterByReplicationLag(t *testing.T) { []uint32{3 * 60 * 60, 4 * 60 * 60}, []uint32{3 * 60 * 60, 4 * 60 * 60}, }, + { + "lags of (3h, 3h, 4h) - return 3 as they're all delayed too much, but still in a good group.", + []uint32{3 * 60 * 60, 3 * 60 * 60, 4 * 60 * 60}, + []uint32{3 * 60 * 60, 3 * 60 * 60, 4 * 60 * 60}, + }, + { + "lags of (3h, 15h, 18h) - return 3 as they're all delayed too much, but still in a good group." + + "(different test case than above to show how absurb the good group logic is)", + []uint32{3 * 60 * 60, 15 * 60 * 60, 18 * 60 * 60}, + []uint32{3 * 60 * 60, 15 * 60 * 60, 18 * 60 * 60}, + }, + { + "lags of (3h, 12h, 18h) - return 2 as they're all delayed too much, but 18h is now considered an outlier." + + "(different test case than above to show how absurb the good group logic is)", + []uint32{3 * 60 * 60, 12 * 60 * 60, 18 * 60 * 60}, + []uint32{3 * 60 * 60, 12 * 60 * 60}, + }, { "lags of (3h, 30h) - return 2 as they're all delayed too much." + "(different test case that before, as both tablet stats are" + diff --git a/go/vt/vttablet/tabletmanager/vreplication/tablet_picker.go b/go/vt/discovery/tablet_picker.go similarity index 50% rename from go/vt/vttablet/tabletmanager/vreplication/tablet_picker.go rename to go/vt/discovery/tablet_picker.go index 8a6867b6845..1cd75ab60c2 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/tablet_picker.go +++ b/go/vt/discovery/tablet_picker.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Vitess Authors. +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. @@ -14,55 +14,46 @@ See the License for the specific language governing permissions and limitations under the License. */ -package vreplication +package discovery import ( - "flag" "fmt" "math/rand" "time" - "vitess.io/vitess/go/vt/vterrors" - "golang.org/x/net/context" - - "vitess.io/vitess/go/vt/discovery" + topodatapb "vitess.io/vitess/go/vt/proto/topodata" "vitess.io/vitess/go/vt/topo" "vitess.io/vitess/go/vt/topo/topoproto" - - topodatapb "vitess.io/vitess/go/vt/proto/topodata" -) - -var ( - healthCheckTopologyRefresh = flag.Duration("vreplication_healthcheck_topology_refresh", 30*time.Second, "refresh interval for re-reading the topology") - healthcheckRetryDelay = flag.Duration("vreplication_healthcheck_retry_delay", 5*time.Second, "delay before retrying a failed healthcheck") - healthCheckTimeout = flag.Duration("vreplication_healthcheck_timeout", time.Minute, "the health check timeout period") + "vitess.io/vitess/go/vt/vterrors" ) -type tabletPicker struct { +// TabletPicker gives a simplified API for picking tablets. +type TabletPicker struct { ts *topo.Server cell string keyspace string shard string tabletTypes []topodatapb.TabletType - healthCheck discovery.HealthCheck - watcher *discovery.TopologyWatcher - statsCache *discovery.TabletStatsCache + healthCheck HealthCheck + watcher *TopologyWatcher + statsCache *TabletStatsCache } -func newTabletPicker(ctx context.Context, ts *topo.Server, cell, keyspace, shard, tabletTypesStr string) (*tabletPicker, error) { +// NewTabletPicker returns a TabletPicker. +func NewTabletPicker(ctx context.Context, ts *topo.Server, cell, keyspace, shard, tabletTypesStr string, healthcheckTopologyRefresh, healthcheckRetryDelay, healthcheckTimeout time.Duration) (*TabletPicker, error) { tabletTypes, err := topoproto.ParseTabletTypes(tabletTypesStr) if err != nil { return nil, fmt.Errorf("failed to parse list of tablet types: %v", tabletTypesStr) } // These have to be initialized in the following sequence (watcher must be last). - healthCheck := discovery.NewHealthCheck(*healthcheckRetryDelay, *healthCheckTimeout) - statsCache := discovery.NewTabletStatsCache(healthCheck, ts, cell) - watcher := discovery.NewShardReplicationWatcher(ctx, ts, healthCheck, cell, keyspace, shard, *healthCheckTopologyRefresh, discovery.DefaultTopoReadConcurrency) + healthCheck := NewHealthCheck(healthcheckRetryDelay, healthcheckTimeout) + statsCache := NewTabletStatsCache(healthCheck, ts, cell) + watcher := NewShardReplicationWatcher(ctx, ts, healthCheck, cell, keyspace, shard, healthcheckTopologyRefresh, DefaultTopoReadConcurrency) - return &tabletPicker{ + return &TabletPicker{ ts: ts, cell: cell, keyspace: keyspace, @@ -74,27 +65,28 @@ func newTabletPicker(ctx context.Context, ts *topo.Server, cell, keyspace, shard }, nil } -func (tp *tabletPicker) Pick(ctx context.Context) (*topodatapb.Tablet, error) { +// PickForStreaming picks all healthy tablets including the non-serving ones. +func (tp *TabletPicker) PickForStreaming(ctx context.Context) (*topodatapb.Tablet, error) { // wait for any of required the tablets (useful for the first run at least, fast for next runs) - if err := tp.statsCache.WaitForAnyTablet(ctx, tp.cell, tp.keyspace, tp.shard, tp.tabletTypes); err != nil { + if err := tp.statsCache.WaitByFilter(ctx, tp.keyspace, tp.shard, tp.tabletTypes, RemoveUnhealthyTablets); err != nil { return nil, vterrors.Wrapf(err, "error waiting for tablets for %v %v %v", tp.cell, tp.keyspace, tp.shard) } - // Find the server list from the health check. - // Note: We cannot use statsCache.GetHealthyTabletStats() here because it does - // not return non-serving tablets. We must include non-serving tablets because - // some tablets may not be serving if their traffic was already migrated to the - // destination shards. + // Refilter the tablets list based on the same criteria. + var addrs []TabletStats for _, tabletType := range tp.tabletTypes { - addrs := discovery.RemoveUnhealthyTablets(tp.statsCache.GetTabletStats(tp.keyspace, tp.shard, tabletType)) - if len(addrs) > 0 { - return addrs[rand.Intn(len(addrs))].Tablet, nil - } + list := RemoveUnhealthyTablets(tp.statsCache.GetTabletStats(tp.keyspace, tp.shard, tabletType)) + addrs = append(addrs, list...) + } + if len(addrs) > 0 { + return addrs[rand.Intn(len(addrs))].Tablet, nil } + // Unreachable. return nil, fmt.Errorf("can't find any healthy source tablet for %v %v %v", tp.keyspace, tp.shard, tp.tabletTypes) } -func (tp *tabletPicker) Close() { +// Close shuts down TabletPicker. +func (tp *TabletPicker) Close() { tp.watcher.Stop() tp.healthCheck.Close() } diff --git a/go/vt/discovery/tablet_picker_test.go b/go/vt/discovery/tablet_picker_test.go new file mode 100644 index 00000000000..dcbd84e649d --- /dev/null +++ b/go/vt/discovery/tablet_picker_test.go @@ -0,0 +1,175 @@ +/* +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 discovery + +import ( + "testing" + "time" + + "github.com/golang/protobuf/proto" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "golang.org/x/net/context" + querypb "vitess.io/vitess/go/vt/proto/query" + topodatapb "vitess.io/vitess/go/vt/proto/topodata" + "vitess.io/vitess/go/vt/topo" + "vitess.io/vitess/go/vt/topo/memorytopo" +) + +func TestPickSimple(t *testing.T) { + te := newPickerTestEnv(t) + want := addTablet(te, 100, topodatapb.TabletType_REPLICA, true, true) + defer deleteTablet(te, want) + + tp, err := NewTabletPicker(context.Background(), te.topoServ, te.cell, te.keyspace, te.shard, "replica", 1*time.Second, 1*time.Second, 1*time.Minute) + require.NoError(t, err) + defer tp.Close() + + tablet, err := tp.PickForStreaming(context.Background()) + require.NoError(t, err) + if !proto.Equal(want, tablet) { + t.Errorf("Pick: %v, want %v", tablet, want) + } +} + +func TestPickFromTwoHealthy(t *testing.T) { + te := newPickerTestEnv(t) + want1 := addTablet(te, 100, topodatapb.TabletType_REPLICA, true, true) + defer deleteTablet(te, want1) + want2 := addTablet(te, 101, topodatapb.TabletType_RDONLY, true, true) + defer deleteTablet(te, want2) + + tp, err := NewTabletPicker(context.Background(), te.topoServ, te.cell, te.keyspace, te.shard, "replica,rdonly", 1*time.Second, 1*time.Second, 1*time.Minute) + require.NoError(t, err) + defer tp.Close() + + // In 20 attempts, both tablet types must be picked at least once. + var picked1, picked2 bool + for i := 0; i < 20; i++ { + tablet, err := tp.PickForStreaming(context.Background()) + require.NoError(t, err) + if proto.Equal(tablet, want1) { + picked1 = true + } + if proto.Equal(tablet, want2) { + picked2 = true + } + } + assert.True(t, picked1) + assert.True(t, picked2) +} + +func TestPickFromSomeUnhealthy(t *testing.T) { + te := newPickerTestEnv(t) + defer deleteTablet(te, addTablet(te, 100, topodatapb.TabletType_REPLICA, false, false)) + want := addTablet(te, 101, topodatapb.TabletType_RDONLY, false, true) + defer deleteTablet(te, want) + + tp, err := NewTabletPicker(context.Background(), te.topoServ, te.cell, te.keyspace, te.shard, "replica,rdonly", 1*time.Second, 1*time.Second, 1*time.Minute) + require.NoError(t, err) + defer tp.Close() + + tablet, err := tp.PickForStreaming(context.Background()) + require.NoError(t, err) + if !proto.Equal(tablet, want) { + t.Errorf("Pick:\n%v, want\n%v", tablet, want) + } +} + +func TestPickError(t *testing.T) { + te := newPickerTestEnv(t) + defer deleteTablet(te, addTablet(te, 100, topodatapb.TabletType_REPLICA, false, false)) + + _, err := NewTabletPicker(context.Background(), te.topoServ, te.cell, te.keyspace, te.shard, "badtype", 1*time.Second, 1*time.Second, 1*time.Minute) + assert.EqualError(t, err, "failed to parse list of tablet types: badtype") + + tp, err := NewTabletPicker(context.Background(), te.topoServ, te.cell, te.keyspace, te.shard, "replica,rdonly", 1*time.Second, 1*time.Second, 1*time.Minute) + require.NoError(t, err) + defer tp.Close() + + ctx, cancel := context.WithTimeout(context.Background(), 200*time.Millisecond) + defer cancel() + _, err = tp.PickForStreaming(ctx) + require.Error(t, err) + assert.Contains(t, err.Error(), "error waiting for tablets") +} + +type pickerTestEnv struct { + t *testing.T + keyspace string + shard string + cell string + + topoServ *topo.Server +} + +func newPickerTestEnv(t *testing.T) *pickerTestEnv { + ctx := context.Background() + + te := &pickerTestEnv{ + t: t, + keyspace: "ks", + shard: "0", + cell: "cell", + topoServ: memorytopo.NewServer("cell"), + } + err := te.topoServ.CreateKeyspace(ctx, te.keyspace, &topodatapb.Keyspace{}) + require.NoError(t, err) + err = te.topoServ.CreateShard(ctx, te.keyspace, te.shard) + require.NoError(t, err) + return te +} + +func addTablet(te *pickerTestEnv, id int, tabletType topodatapb.TabletType, serving, healthy bool) *topodatapb.Tablet { + tablet := &topodatapb.Tablet{ + Alias: &topodatapb.TabletAlias{ + Cell: te.cell, + Uid: uint32(id), + }, + Keyspace: te.keyspace, + Shard: te.shard, + KeyRange: &topodatapb.KeyRange{}, + Type: tabletType, + PortMap: map[string]int32{ + "test": int32(id), + }, + } + err := te.topoServ.CreateTablet(context.Background(), tablet) + require.NoError(te.t, err) + + var herr string + if !healthy { + herr = "err" + } + _ = createFixedHealthConn(tablet, &querypb.StreamHealthResponse{ + Serving: serving, + Target: &querypb.Target{ + Keyspace: te.keyspace, + Shard: te.shard, + TabletType: tabletType, + }, + RealtimeStats: &querypb.RealtimeStats{HealthError: herr}, + }) + + return tablet +} + +func deleteTablet(te *pickerTestEnv, tablet *topodatapb.Tablet) { + te.topoServ.DeleteTablet(context.Background(), tablet.Alias) + // This is not automatically removed from shard replication, which results in log spam. + topo.DeleteTabletReplicationData(context.Background(), te.topoServ, tablet) +} diff --git a/go/vt/discovery/tablet_stats_cache.go b/go/vt/discovery/tablet_stats_cache.go index 326e15e2d30..92208266e1c 100644 --- a/go/vt/discovery/tablet_stats_cache.go +++ b/go/vt/discovery/tablet_stats_cache.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/discovery/tablet_stats_cache_test.go b/go/vt/discovery/tablet_stats_cache_test.go index 635d3daca2d..9897d503db7 100644 --- a/go/vt/discovery/tablet_stats_cache_test.go +++ b/go/vt/discovery/tablet_stats_cache_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/discovery/tablet_stats_cache_wait.go b/go/vt/discovery/tablet_stats_cache_wait.go index 6f0761c0a37..1b1123a7439 100644 --- a/go/vt/discovery/tablet_stats_cache_wait.go +++ b/go/vt/discovery/tablet_stats_cache_wait.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 @@ -30,10 +30,10 @@ var ( waitAvailableTabletInterval = 100 * time.Millisecond ) -// WaitForTablets waits for at least one tablet in the given cell / +// WaitForTablets waits for at least one tablet in the given // keyspace / shard / tablet type before returning. The tablets do not // have to be healthy. It will return ctx.Err() if the context is canceled. -func (tc *TabletStatsCache) WaitForTablets(ctx context.Context, cell, keyspace, shard string, tabletType topodatapb.TabletType) error { +func (tc *TabletStatsCache) WaitForTablets(ctx context.Context, keyspace, shard string, tabletType topodatapb.TabletType) error { targets := []*querypb.Target{ { Keyspace: keyspace, @@ -44,12 +44,6 @@ func (tc *TabletStatsCache) WaitForTablets(ctx context.Context, cell, keyspace, return tc.waitForTablets(ctx, targets, false) } -// WaitForAnyTablet waits for a single tablet of any of the types. -// It doesn't have to be serving. -func (tc *TabletStatsCache) WaitForAnyTablet(ctx context.Context, cell, keyspace, shard string, tabletTypes []topodatapb.TabletType) error { - return tc.waitForAnyTablet(ctx, keyspace, shard, tabletTypes) -} - // WaitForAllServingTablets waits for at least one healthy serving tablet in // each given target before returning. // It will return ctx.Err() if the context is canceled. @@ -97,11 +91,12 @@ func (tc *TabletStatsCache) waitForTablets(ctx context.Context, targets []*query } } -// waitForAnyTablet is the internal method that polls for any tablet of required type -func (tc *TabletStatsCache) waitForAnyTablet(ctx context.Context, keyspace, shard string, types []topodatapb.TabletType) error { +// WaitByFilter waits for at least one tablet based on the filter function. +func (tc *TabletStatsCache) WaitByFilter(ctx context.Context, keyspace, shard string, tabletTypes []topodatapb.TabletType, filter func([]TabletStats) []TabletStats) error { for { - for _, tt := range types { + for _, tt := range tabletTypes { stats := tc.GetTabletStats(keyspace, shard, tt) + stats = filter(stats) if len(stats) > 0 { return nil } diff --git a/go/vt/discovery/tablet_stats_cache_wait_test.go b/go/vt/discovery/tablet_stats_cache_wait_test.go index 19933494f0b..0cf309931c1 100644 --- a/go/vt/discovery/tablet_stats_cache_wait_test.go +++ b/go/vt/discovery/tablet_stats_cache_wait_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 @@ -43,14 +43,14 @@ func TestWaitForTablets(t *testing.T) { hc.AddTablet(tablet, "") // this should time out - if err := tsc.WaitForTablets(shortCtx, "cell", "keyspace", "shard", topodatapb.TabletType_REPLICA); err != context.DeadlineExceeded { + if err := tsc.WaitForTablets(shortCtx, "keyspace", "shard", topodatapb.TabletType_REPLICA); err != context.DeadlineExceeded { t.Errorf("got wrong error: %v", err) } // this should fail, but return a non-timeout error cancelledCtx, cancel := context.WithCancel(context.Background()) cancel() - if err := tsc.WaitForTablets(cancelledCtx, "cell", "keyspace", "shard", topodatapb.TabletType_REPLICA); err == nil || err == context.DeadlineExceeded { + if err := tsc.WaitForTablets(cancelledCtx, "keyspace", "shard", topodatapb.TabletType_REPLICA); err == nil || err == context.DeadlineExceeded { t.Errorf("want: non-timeout error, got: %v", err) } @@ -70,7 +70,7 @@ func TestWaitForTablets(t *testing.T) { longCtx, longCancel := context.WithTimeout(context.Background(), 10*time.Second) defer longCancel() waitAvailableTabletInterval = 10 * time.Millisecond - if err := tsc.WaitForTablets(longCtx, "cell", "keyspace", "shard", topodatapb.TabletType_REPLICA); err != nil { + if err := tsc.WaitForTablets(longCtx, "keyspace", "shard", topodatapb.TabletType_REPLICA); err != nil { t.Errorf("got error: %v", err) } } diff --git a/go/vt/discovery/topology_watcher.go b/go/vt/discovery/topology_watcher.go index 429b72f542b..fdf14f11a19 100644 --- a/go/vt/discovery/topology_watcher.go +++ b/go/vt/discovery/topology_watcher.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/discovery/topology_watcher_test.go b/go/vt/discovery/topology_watcher_test.go index 9288cca1bed..c3cd553699a 100644 --- a/go/vt/discovery/topology_watcher_test.go +++ b/go/vt/discovery/topology_watcher_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 @@ -234,6 +234,56 @@ func checkWatcher(t *testing.T, cellTablets, refreshKnownTablets bool) { t.Errorf("fhc.GetAllTablets() = %+v; want %v => %+v", allTablets, key, tablet2) } + // Both tablets restart on different hosts. + // tablet2 happens to land on the host:port that tablet 1 used to be on. + // This can only be tested when we refresh known tablets. + if refreshKnownTablets { + origTablet := *tablet + origTablet2 := *tablet2 + + if _, err := ts.UpdateTabletFields(context.Background(), tablet2.Alias, func(t *topodatapb.Tablet) error { + t.Hostname = tablet.Hostname + t.PortMap = tablet.PortMap + tablet2 = t + return nil + }); err != nil { + t.Fatalf("UpdateTabletFields failed: %v", err) + } + if _, err := ts.UpdateTabletFields(context.Background(), tablet.Alias, func(t *topodatapb.Tablet) error { + t.Hostname = "host3" + tablet = t + return nil + }); err != nil { + t.Fatalf("UpdateTabletFields failed: %v", err) + } + tw.loadTablets() + counts = checkOpCounts(t, tw, counts, map[string]int64{"ListTablets": 1, "GetTablet": 2, "ReplaceTablet": 2}) + allTablets = fhc.GetAllTablets() + key2 := TabletToMapKey(tablet2) + if _, ok := allTablets[key2]; !ok { + t.Fatalf("tablet was lost because it's reusing an address recently used by another tablet: %v", key2) + } + + // Change tablets back to avoid altering later tests. + if _, err := ts.UpdateTabletFields(context.Background(), tablet2.Alias, func(t *topodatapb.Tablet) error { + t.Hostname = origTablet2.Hostname + t.PortMap = origTablet2.PortMap + tablet2 = t + return nil + }); err != nil { + t.Fatalf("UpdateTabletFields failed: %v", err) + } + if _, err := ts.UpdateTabletFields(context.Background(), tablet.Alias, func(t *topodatapb.Tablet) error { + t.Hostname = origTablet.Hostname + tablet = t + return nil + }); err != nil { + t.Fatalf("UpdateTabletFields failed: %v", err) + } + tw.loadTablets() + counts = checkOpCounts(t, tw, counts, map[string]int64{"ListTablets": 1, "GetTablet": 2, "ReplaceTablet": 2}) + } + // Remove the tablet and check that it is detected as being gone. if err := ts.DeleteTablet(context.Background(), tablet.Alias); err != nil { t.Fatalf("DeleteTablet failed: %v", err) diff --git a/go/vt/discovery/utils.go b/go/vt/discovery/utils.go index d09ce1f4eec..07e4642fdf3 100644 --- a/go/vt/discovery/utils.go +++ b/go/vt/discovery/utils.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/dtids/dtids.go b/go/vt/dtids/dtids.go index 4ecf4b690d4..8268535c31c 100644 --- a/go/vt/dtids/dtids.go +++ b/go/vt/dtids/dtids.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/dtids/dtids_test.go b/go/vt/dtids/dtids_test.go index 028e4cc53d3..e5a8fc86750 100644 --- a/go/vt/dtids/dtids_test.go +++ b/go/vt/dtids/dtids_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/env/env.go b/go/vt/env/env.go index 7f639cf7fa5..49b462815be 100644 --- a/go/vt/env/env.go +++ b/go/vt/env/env.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/env/env_test.go b/go/vt/env/env_test.go index d3a1e78b6c0..4aa53a25bed 100644 --- a/go/vt/env/env_test.go +++ b/go/vt/env/env_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/events/status.go b/go/vt/events/status.go index 3142ea3a589..b099376f9fb 100644 --- a/go/vt/events/status.go +++ b/go/vt/events/status.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/events/status_test.go b/go/vt/events/status_test.go index 76746f8202b..743bf23b977 100644 --- a/go/vt/events/status_test.go +++ b/go/vt/events/status_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/grpcclient/client.go b/go/vt/grpcclient/client.go index 2ab77b011a4..2dae863a9a9 100644 --- a/go/vt/grpcclient/client.go +++ b/go/vt/grpcclient/client.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -21,8 +21,8 @@ package grpcclient import ( "flag" - "github.com/grpc-ecosystem/go-grpc-middleware" - "github.com/grpc-ecosystem/go-grpc-prometheus" + grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware" + grpc_prometheus "github.com/grpc-ecosystem/go-grpc-prometheus" "google.golang.org/grpc" "google.golang.org/grpc/credentials" "google.golang.org/grpc/keepalive" diff --git a/go/vt/grpcclient/client_auth_static.go b/go/vt/grpcclient/client_auth_static.go index 95fea1e3dfd..deff20e50d9 100644 --- a/go/vt/grpcclient/client_auth_static.go +++ b/go/vt/grpcclient/client_auth_static.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/grpcclient/client_test.go b/go/vt/grpcclient/client_test.go index 106a0937e85..372e67999a8 100644 --- a/go/vt/grpcclient/client_test.go +++ b/go/vt/grpcclient/client_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/grpcclient/glogger.go b/go/vt/grpcclient/glogger.go index 02b7fa2f20f..58c640b0d28 100644 --- a/go/vt/grpcclient/glogger.go +++ b/go/vt/grpcclient/glogger.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/grpcclient/snappy.go b/go/vt/grpcclient/snappy.go index 03eb2d63113..1935127b9eb 100644 --- a/go/vt/grpcclient/snappy.go +++ b/go/vt/grpcclient/snappy.go @@ -1,3 +1,19 @@ +/* +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 grpcclient import ( diff --git a/go/vt/grpccommon/options.go b/go/vt/grpccommon/options.go index b47f70cb37e..0a37e7d78f2 100644 --- a/go/vt/grpccommon/options.go +++ b/go/vt/grpccommon/options.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/health/health.go b/go/vt/health/health.go index abe803e7c3b..83f87883079 100644 --- a/go/vt/health/health.go +++ b/go/vt/health/health.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/health/health_test.go b/go/vt/health/health_test.go index 7843a6dfd36..309ca8aabe1 100644 --- a/go/vt/health/health_test.go +++ b/go/vt/health/health_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/hook/hook.go b/go/vt/hook/hook.go index 1e44b710c5e..0215a143829 100644 --- a/go/vt/hook/hook.go +++ b/go/vt/hook/hook.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/key/destination.go b/go/vt/key/destination.go index ca7867fa501..66946504978 100644 --- a/go/vt/key/destination.go +++ b/go/vt/key/destination.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -382,7 +382,7 @@ type DestinationAnyShardPicker interface { // DestinationAnyShardPickerRandomShard picks a random shard. type DestinationAnyShardPickerRandomShard struct{} -// PickShard is DestinationAnyShardPickerRandomShard's implmentation. +// PickShard is DestinationAnyShardPickerRandomShard's implementation. func (dp DestinationAnyShardPickerRandomShard) PickShard(shardCount int) int { return rand.Intn(shardCount) } diff --git a/go/vt/key/destination_test.go b/go/vt/key/destination_test.go index 840bb280b07..1f51323c715 100644 --- a/go/vt/key/destination_test.go +++ b/go/vt/key/destination_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/key/key.go b/go/vt/key/key.go index 367311ba5c8..b9ae9698403 100644 --- a/go/vt/key/key.go +++ b/go/vt/key/key.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -22,6 +22,7 @@ import ( "encoding/hex" "fmt" "math" + "regexp" "strings" topodatapb "vitess.io/vitess/go/vt/proto/topodata" @@ -296,3 +297,10 @@ func ParseShardingSpec(spec string) ([]*topodatapb.KeyRange, error) { } return ranges, nil } + +var krRegexp = regexp.MustCompile(`^[0-9a-fA-F]*-[0-9a-fA-F]*$`) + +// IsKeyRange returns true if the string represents a keyrange. +func IsKeyRange(kr string) bool { + return krRegexp.MatchString(kr) +} diff --git a/go/vt/key/key_test.go b/go/vt/key/key_test.go index b6e2229e760..9d88ba19ea3 100644 --- a/go/vt/key/key_test.go +++ b/go/vt/key/key_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -22,6 +22,7 @@ import ( "testing" "github.com/golang/protobuf/proto" + "github.com/stretchr/testify/assert" topodatapb "vitess.io/vitess/go/vt/proto/topodata" ) @@ -381,7 +382,7 @@ func BenchmarkUint64KeyString(b *testing.B) { for i := 0; i < b.N; i++ { for _, key := range keys { - key.String() + _ = key.String() } } } @@ -435,3 +436,44 @@ func BenchmarkKeyRangesOverlap(b *testing.B) { KeyRangesOverlap(kr1, kr2) } } + +func TestIsKeyRange(t *testing.T) { + testcases := []struct { + in string + out bool + }{{ + in: "-", + out: true, + }, { + in: "-80", + out: true, + }, { + in: "40-80", + out: true, + }, { + in: "80-", + out: true, + }, { + in: "a0-", + out: true, + }, { + in: "-A0", + out: true, + }, { + in: "", + out: false, + }, { + in: "x-80", + out: false, + }, { + in: "-80x", + out: false, + }, { + in: "select", + out: false, + }} + + for _, tcase := range testcases { + assert.Equal(t, IsKeyRange(tcase.in), tcase.out, tcase.in) + } +} diff --git a/go/vt/log/log.go b/go/vt/log/log.go index d2d0adf1dfe..a7348311d9a 100644 --- a/go/vt/log/log.go +++ b/go/vt/log/log.go @@ -1,3 +1,19 @@ +/* +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. +*/ + // You can modify this file to hook up a different logging library instead of glog. // If you adapt to a different logging framework, you may need to use that // framework's equivalent of *Depth() functions so the file and line number printed @@ -7,6 +23,7 @@ package log import ( "flag" + "github.com/golang/glog" ) diff --git a/go/vt/logutil/console_logger.go b/go/vt/logutil/console_logger.go index b66def0c6a4..8f8e73607ac 100644 --- a/go/vt/logutil/console_logger.go +++ b/go/vt/logutil/console_logger.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/logutil/console_logger_test.go b/go/vt/logutil/console_logger_test.go index de0371d6976..bf3fd06cf7a 100644 --- a/go/vt/logutil/console_logger_test.go +++ b/go/vt/logutil/console_logger_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/logutil/flush.go b/go/vt/logutil/flush.go index 091408e1858..bb22392ed39 100644 --- a/go/vt/logutil/flush.go +++ b/go/vt/logutil/flush.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/logutil/flush_glog.go b/go/vt/logutil/flush_glog.go index 597b8f6639f..8b7015dd3fe 100644 --- a/go/vt/logutil/flush_glog.go +++ b/go/vt/logutil/flush_glog.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/logutil/level.go b/go/vt/logutil/level.go index 86c61c868ea..6d32e407f88 100644 --- a/go/vt/logutil/level.go +++ b/go/vt/logutil/level.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/logutil/logger.go b/go/vt/logutil/logger.go index 7acb086d698..50e4e16d13f 100644 --- a/go/vt/logutil/logger.go +++ b/go/vt/logutil/logger.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/logutil/logger_test.go b/go/vt/logutil/logger_test.go index 0ba87f0bce0..c34f8cf8ec3 100644 --- a/go/vt/logutil/logger_test.go +++ b/go/vt/logutil/logger_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/logutil/logutil.go b/go/vt/logutil/logutil.go index 6d1aa98edf4..eea87484921 100644 --- a/go/vt/logutil/logutil.go +++ b/go/vt/logutil/logutil.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/logutil/logutil_test.go b/go/vt/logutil/logutil_test.go index 605adad4ffa..72c005a5574 100644 --- a/go/vt/logutil/logutil_test.go +++ b/go/vt/logutil/logutil_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 @@ -103,9 +103,8 @@ func TestPurgeByMtime(t *testing.T) { t.Fatalf("os.Chtimes: %v", err) } } - now := time.Date(2020, 1, 1, 12, 15, 0, 0, time.UTC) + now := time.Date(2020, 1, 1, 12, 0, 0, 0, time.UTC) filenameMtimeMap := map[string]string{ - "vtadam.localhost.vitess.log.INFO.20200101-120000.00000": "2020-01-01T12:00:00.000Z", "vtadam.localhost.vitess.log.INFO.20200101-113000.00000": "2020-01-01T11:30:00.000Z", "vtadam.localhost.vitess.log.INFO.20200101-100000.00000": "2020-01-01T10:00:00.000Z", "vtadam.localhost.vitess.log.INFO.20200101-090000.00000": "2020-01-01T09:00:00.000Z", @@ -114,7 +113,11 @@ func TestPurgeByMtime(t *testing.T) { for filename, mtimeStr := range filenameMtimeMap { createFileWithMtime(filename, mtimeStr) } - if err := os.Symlink("vtadam.localhost.vitess.log.INFO.20200101-120000.00000", path.Join(logDir, "vtadam.INFO")); err != nil { + + // Create vtadam.INFO symlink to 100000. This is a contrived example in that + // current log (100000) is not the latest log (113000). This will not happen + // IRL but it helps us test edge cases of purging by mtime. + if err := os.Symlink("vtadam.localhost.vitess.log.INFO.20200101-100000.00000", path.Join(logDir, "vtadam.INFO")); err != nil { t.Fatalf("os.Symlink: %v", err) } @@ -126,9 +129,9 @@ func TestPurgeByMtime(t *testing.T) { } if len(left) != 3 { - // 20200101-120000 is current - // 20200101-113000 is within 1 hour - // symlink remains + // 1. 113000 is within 1 hour + // 2. 100000 is current (vtadam.INFO) + // 3. vtadam.INFO symlink remains // rest are removed t.Errorf("wrong number of files remain: want %v, got %v", 3, len(left)) } diff --git a/go/vt/logutil/proto3.go b/go/vt/logutil/proto3.go index 950a74ec664..2bde4656dbd 100644 --- a/go/vt/logutil/proto3.go +++ b/go/vt/logutil/proto3.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -20,28 +20,29 @@ import ( "time" logutilpb "vitess.io/vitess/go/vt/proto/logutil" + vttimepb "vitess.io/vitess/go/vt/proto/vttime" ) // This file contains a few functions to help with proto3. -// ProtoToTime converts a logutilpb.Time to a time.Time. +// ProtoToTime converts a vttimepb.Time to a time.Time. // proto3 will eventually support timestamps, at which point we'll retire // this. // // A nil pointer is like the empty timestamp. -func ProtoToTime(ts *logutilpb.Time) time.Time { +func ProtoToTime(ts *vttimepb.Time) time.Time { if ts == nil { // treat nil like the empty Timestamp - return time.Unix(0, 0).UTC() + return time.Time{} } return time.Unix(ts.Seconds, int64(ts.Nanoseconds)).UTC() } -// TimeToProto converts the time.Time to a logutilpb.Time. -func TimeToProto(t time.Time) *logutilpb.Time { +// TimeToProto converts the time.Time to a vttimepb.Time. +func TimeToProto(t time.Time) *vttimepb.Time { seconds := t.Unix() nanos := int64(t.Sub(time.Unix(seconds, 0))) - return &logutilpb.Time{ + return &vttimepb.Time{ Seconds: seconds, Nanoseconds: int32(nanos), } diff --git a/go/vt/logutil/proto3_test.go b/go/vt/logutil/proto3_test.go index 185450f3b20..e957d08ab3b 100644 --- a/go/vt/logutil/proto3_test.go +++ b/go/vt/logutil/proto3_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -22,7 +22,7 @@ import ( "time" "github.com/golang/protobuf/proto" - logutilpb "vitess.io/vitess/go/vt/proto/logutil" + "vitess.io/vitess/go/vt/proto/vttime" ) const ( @@ -39,43 +39,43 @@ func utcDate(year, month, day int) time.Time { } var tests = []struct { - pt *logutilpb.Time + pt *vttime.Time t time.Time }{ // The timestamp representing the Unix epoch date. - {pt: &logutilpb.Time{Seconds: 0, Nanoseconds: 0}, + {pt: &vttime.Time{Seconds: 0, Nanoseconds: 0}, t: utcDate(1970, 1, 1)}, // The smallest representable timestamp with non-negative nanos. - {pt: &logutilpb.Time{Seconds: math.MinInt64, Nanoseconds: 0}, + {pt: &vttime.Time{Seconds: math.MinInt64, Nanoseconds: 0}, t: time.Unix(math.MinInt64, 0).UTC()}, // The earliest valid timestamp. - {pt: &logutilpb.Time{Seconds: minValidSeconds, Nanoseconds: 0}, + {pt: &vttime.Time{Seconds: minValidSeconds, Nanoseconds: 0}, t: utcDate(1, 1, 1)}, // The largest representable timestamp with nanos in range. - {pt: &logutilpb.Time{Seconds: math.MaxInt64, Nanoseconds: 1e9 - 1}, + {pt: &vttime.Time{Seconds: math.MaxInt64, Nanoseconds: 1e9 - 1}, t: time.Unix(math.MaxInt64, 1e9-1).UTC()}, // The largest valid timestamp. - {pt: &logutilpb.Time{Seconds: maxValidSeconds - 1, Nanoseconds: 1e9 - 1}, + {pt: &vttime.Time{Seconds: maxValidSeconds - 1, Nanoseconds: 1e9 - 1}, t: time.Date(9999, 12, 31, 23, 59, 59, 1e9-1, time.UTC)}, // The smallest invalid timestamp that is larger than the valid range. - {pt: &logutilpb.Time{Seconds: maxValidSeconds, Nanoseconds: 0}, + {pt: &vttime.Time{Seconds: maxValidSeconds, Nanoseconds: 0}, t: time.Unix(maxValidSeconds, 0).UTC()}, // A date before the epoch. - {pt: &logutilpb.Time{Seconds: -281836800, Nanoseconds: 0}, + {pt: &vttime.Time{Seconds: -281836800, Nanoseconds: 0}, t: utcDate(1961, 1, 26)}, // A date after the epoch. - {pt: &logutilpb.Time{Seconds: 1296000000, Nanoseconds: 0}, + {pt: &vttime.Time{Seconds: 1296000000, Nanoseconds: 0}, t: utcDate(2011, 1, 26)}, // A date after the epoch, in the middle of the day. - {pt: &logutilpb.Time{Seconds: 1296012345, Nanoseconds: 940483}, + {pt: &vttime.Time{Seconds: 1296012345, Nanoseconds: 940483}, t: time.Date(2011, 1, 26, 3, 25, 45, 940483, time.UTC)}, } diff --git a/go/vt/logutil/purge.go b/go/vt/logutil/purge.go index c7825098a11..a450b0ae2a3 100644 --- a/go/vt/logutil/purge.go +++ b/go/vt/logutil/purge.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 @@ -70,7 +70,13 @@ func purgeLogsOnce(now time.Time, dir, program string, ctimeDelta time.Duration, return } for _, file := range files { - if current[file] { + statInfo, err := os.Lstat(file) + if err != nil { + // Failed to stat file + continue + } + if current[file] || !statInfo.Mode().IsRegular() { + // Do not purge current file or any non-regular files (symlinks etc) continue } purgeFile := false diff --git a/go/vt/logutil/throttled.go b/go/vt/logutil/throttled.go index c90763fdc66..6aa9f960618 100644 --- a/go/vt/logutil/throttled.go +++ b/go/vt/logutil/throttled.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/logutil/throttled_test.go b/go/vt/logutil/throttled_test.go index f7c7097d48b..8d921236f45 100644 --- a/go/vt/logutil/throttled_test.go +++ b/go/vt/logutil/throttled_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/logz/logz_utils.go b/go/vt/logz/logz_utils.go index 77874b6c162..ae50119318d 100644 --- a/go/vt/logz/logz_utils.go +++ b/go/vt/logz/logz_utils.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/mysqlctl/backup.go b/go/vt/mysqlctl/backup.go index 12a7651146c..8a7d1dc0577 100644 --- a/go/vt/mysqlctl/backup.go +++ b/go/vt/mysqlctl/backup.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -19,6 +19,7 @@ package mysqlctl import ( "errors" "flag" + "fmt" "os" "path/filepath" "strings" @@ -28,7 +29,6 @@ import ( "vitess.io/vitess/go/mysql" "vitess.io/vitess/go/sqlescape" "vitess.io/vitess/go/vt/log" - "vitess.io/vitess/go/vt/logutil" "vitess.io/vitess/go/vt/mysqlctl/backupstorage" "vitess.io/vitess/go/vt/proto/vtrpc" "vitess.io/vitess/go/vt/vterrors" @@ -47,6 +47,8 @@ const ( // RestoreState is the name of the sentinel file used to detect whether a previous restore // terminated abnormally RestoreState = "restore_in_progress" + // BackupTimestampFormat is the format in which we save BackupTime and FinishedTime + BackupTimestampFormat = "2006-01-02.150405" ) const ( @@ -90,14 +92,17 @@ var ( // - uses the BackupStorage service to store a new backup // - shuts down Mysqld during the backup // - remember if we were replicating, restore the exact same state -func Backup(ctx context.Context, cnf *Mycnf, mysqld MysqlDaemon, logger logutil.Logger, dir, name string, backupConcurrency int, hookExtraEnv map[string]string) error { +func Backup(ctx context.Context, params BackupParams) error { + + backupDir := GetBackupDir(params.Keyspace, params.Shard) + name := fmt.Sprintf("%v.%v", params.BackupTime.UTC().Format(BackupTimestampFormat), params.TabletAlias) // Start the backup with the BackupStorage. bs, err := backupstorage.GetBackupStorage() if err != nil { return vterrors.Wrap(err, "unable to get backup storage") } defer bs.Close() - bh, err := bs.StartBackup(ctx, dir, name) + bh, err := bs.StartBackup(ctx, backupDir, name) if err != nil { return vterrors.Wrap(err, "StartBackup failed") } @@ -108,7 +113,8 @@ func Backup(ctx context.Context, cnf *Mycnf, mysqld MysqlDaemon, logger logutil. } // Take the backup, and either AbortBackup or EndBackup. - usable, err := be.ExecuteBackup(ctx, cnf, mysqld, logger, bh, backupConcurrency, hookExtraEnv) + usable, err := be.ExecuteBackup(ctx, params, bh) + logger := params.Logger var finishErr error if usable { finishErr = bh.EndBackup(ctx) @@ -215,88 +221,81 @@ func removeExistingFiles(cnf *Mycnf) error { // Restore is the main entry point for backup restore. If there is no // appropriate backup on the BackupStorage, Restore logs an error // and returns ErrNoBackup. Any other error is returned. -func Restore( - ctx context.Context, - cnf *Mycnf, - mysqld MysqlDaemon, - dir string, - restoreConcurrency int, - hookExtraEnv map[string]string, - localMetadata map[string]string, - logger logutil.Logger, - deleteBeforeRestore bool, - dbName string) (mysql.Position, error) { - - rval := mysql.Position{} - - if !deleteBeforeRestore { - logger.Infof("Restore: Checking if a restore is in progress") - if !RestoreWasInterrupted(cnf) { - logger.Infof("Restore: No %v file found, checking no existing data is present", RestoreState) +func Restore(ctx context.Context, params RestoreParams) (*BackupManifest, error) { + + if !params.DeleteBeforeRestore { + params.Logger.Infof("Restore: Checking if a restore is in progress") + if !RestoreWasInterrupted(params.Cnf) { + params.Logger.Infof("Restore: No %v file found, checking no existing data is present", RestoreState) // Wait for mysqld to be ready, in case it was launched in parallel with us. - if err := mysqld.Wait(ctx, cnf); err != nil { - return mysql.Position{}, err + if err := params.Mysqld.Wait(ctx, params.Cnf); err != nil { + return nil, err } - ok, err := checkNoDB(ctx, mysqld, dbName) + ok, err := checkNoDB(ctx, params.Mysqld, params.DbName) if err != nil { - return mysql.Position{}, err + return nil, err } if !ok { - logger.Infof("Auto-restore is enabled, but mysqld already contains data. Assuming vttablet was just restarted.") - if err = PopulateMetadataTables(mysqld, localMetadata, dbName); err == nil { + params.Logger.Infof("Auto-restore is enabled, but mysqld already contains data. Assuming vttablet was just restarted.") + if err = PopulateMetadataTables(params.Mysqld, params.LocalMetadata, params.DbName); err == nil { err = ErrExistingDB } - return mysql.Position{}, err + return nil, err } } } // find the right backup handle: most recent one, with a MANIFEST - logger.Infof("Restore: looking for a suitable backup to restore") + params.Logger.Infof("Restore: looking for a suitable backup to restore") bs, err := backupstorage.GetBackupStorage() if err != nil { - return mysql.Position{}, err + return nil, err } defer bs.Close() - bhs, err := bs.ListBackups(ctx, dir) + // Backups are stored in a directory structure that starts with + // / + backupDir := GetBackupDir(params.Keyspace, params.Shard) + bhs, err := bs.ListBackups(ctx, backupDir) if err != nil { - return mysql.Position{}, vterrors.Wrap(err, "ListBackups failed") + return nil, vterrors.Wrap(err, "ListBackups failed") } if len(bhs) == 0 { // There are no backups (not even broken/incomplete ones). - logger.Errorf("no backup to restore on BackupStorage for directory %v. Starting up empty.", dir) + params.Logger.Errorf("no backup to restore on BackupStorage for directory %v. Starting up empty.", backupDir) // Wait for mysqld to be ready, in case it was launched in parallel with us. - if err = mysqld.Wait(ctx, cnf); err != nil { - logger.Errorf("mysqld is not running: %v", err) - return mysql.Position{}, err + if err = params.Mysqld.Wait(ctx, params.Cnf); err != nil { + params.Logger.Errorf("mysqld is not running: %v", err) + return nil, err } // Since this is an empty database make sure we start replication at the beginning - if err := mysqld.ResetReplication(ctx); err != nil { - logger.Errorf("error reseting slave replication: %v. Continuing", err) + if err := params.Mysqld.ResetReplication(ctx); err != nil { + params.Logger.Errorf("error resetting slave replication: %v. Continuing", err) } - if err := PopulateMetadataTables(mysqld, localMetadata, dbName); err != nil { - logger.Errorf("error populating metadata tables: %v. Continuing", err) + if err := PopulateMetadataTables(params.Mysqld, params.LocalMetadata, params.DbName); err != nil { + params.Logger.Errorf("error populating metadata tables: %v. Continuing", err) } // Always return ErrNoBackup - return mysql.Position{}, ErrNoBackup + return nil, ErrNoBackup } - bh, err := FindBackupToRestore(ctx, cnf, mysqld, logger, dir, bhs) + bh, err := FindBackupToRestore(ctx, params, bhs) if err != nil { - return rval, err + return nil, err } re, err := GetRestoreEngine(ctx, bh) if err != nil { - return mysql.Position{}, vterrors.Wrap(err, "Failed to find restore engine") + return nil, vterrors.Wrap(err, "Failed to find restore engine") } - if rval, err = re.ExecuteRestore(ctx, cnf, mysqld, logger, dir, bh, restoreConcurrency, hookExtraEnv); err != nil { - return rval, err + + manifest, err := re.ExecuteRestore(ctx, params, bh) + if err != nil { + return nil, err } // mysqld needs to be running in order for mysql_upgrade to work. @@ -306,41 +305,45 @@ func Restore( // is executed. And since with --skip-grant-tables anyone can connect to MySQL // without password, we are passing --skip-networking to greatly reduce the set // of those who can connect. - logger.Infof("Restore: starting mysqld for mysql_upgrade") + params.Logger.Infof("Restore: starting mysqld for mysql_upgrade") // Note Start will use dba user for waiting, this is fine, it will be allowed. - err = mysqld.Start(context.Background(), cnf, "--skip-grant-tables", "--skip-networking") + err = params.Mysqld.Start(context.Background(), params.Cnf, "--skip-grant-tables", "--skip-networking") if err != nil { - return mysql.Position{}, err + return nil, err } - logger.Infof("Restore: running mysql_upgrade") - if err := mysqld.RunMysqlUpgrade(); err != nil { - return mysql.Position{}, vterrors.Wrap(err, "mysql_upgrade failed") + params.Logger.Infof("Restore: running mysql_upgrade") + if err := params.Mysqld.RunMysqlUpgrade(); err != nil { + return nil, vterrors.Wrap(err, "mysql_upgrade failed") } + // Add backupTime and restorePosition to LocalMetadata + params.LocalMetadata["RestoredBackupTime"] = manifest.BackupTime + params.LocalMetadata["RestorePosition"] = mysql.EncodePosition(manifest.Position) + // Populate local_metadata before starting without --skip-networking, // so it's there before we start announcing ourselves. - logger.Infof("Restore: populating local_metadata") - err = PopulateMetadataTables(mysqld, localMetadata, dbName) + params.Logger.Infof("Restore: populating local_metadata") + err = PopulateMetadataTables(params.Mysqld, params.LocalMetadata, params.DbName) if err != nil { - return mysql.Position{}, err + return nil, err } // The MySQL manual recommends restarting mysqld after running mysql_upgrade, // so that any changes made to system tables take effect. - logger.Infof("Restore: restarting mysqld after mysql_upgrade") - err = mysqld.Shutdown(context.Background(), cnf, true) + params.Logger.Infof("Restore: restarting mysqld after mysql_upgrade") + err = params.Mysqld.Shutdown(context.Background(), params.Cnf, true) if err != nil { - return mysql.Position{}, err + return nil, err } - err = mysqld.Start(context.Background(), cnf) + err = params.Mysqld.Start(context.Background(), params.Cnf) if err != nil { - return mysql.Position{}, err + return nil, err } - if err = removeStateFile(cnf); err != nil { - return mysql.Position{}, err + if err = removeStateFile(params.Cnf); err != nil { + return nil, err } - return rval, nil + return manifest, nil } diff --git a/go/vt/mysqlctl/backup_test.go b/go/vt/mysqlctl/backup_test.go index 6fa324ae11a..79f197758ca 100644 --- a/go/vt/mysqlctl/backup_test.go +++ b/go/vt/mysqlctl/backup_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -77,7 +77,7 @@ func TestFindFilesToBackup(t *testing.T) { DataDir: dataDir, } - result, err := findFilesToBackup(cnf) + result, totalSize, err := findFilesToBackup(cnf) if err != nil { t.Fatalf("findFilesToBackup failed: %v", err) } @@ -112,6 +112,9 @@ func TestFindFilesToBackup(t *testing.T) { if !reflect.DeepEqual(result, expected) { t.Fatalf("got wrong list of FileEntry %v, expected %v", result, expected) } + if totalSize <= 0 { + t.Fatalf("backup size should be > 0, got %v", totalSize) + } } type forTest []FileEntry diff --git a/go/vt/mysqlctl/backupengine.go b/go/vt/mysqlctl/backupengine.go index 50f07739dab..932fe2c1593 100644 --- a/go/vt/mysqlctl/backupengine.go +++ b/go/vt/mysqlctl/backupengine.go @@ -1,5 +1,5 @@ /* -Copyright 2019 The Vitess Authors +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. @@ -21,14 +21,18 @@ import ( "encoding/json" "flag" "fmt" + "io/ioutil" "os" + "path" "path/filepath" + "strings" + "time" "vitess.io/vitess/go/mysql" - "vitess.io/vitess/go/vt/log" "vitess.io/vitess/go/vt/logutil" "vitess.io/vitess/go/vt/mysqlctl/backupstorage" "vitess.io/vitess/go/vt/proto/vtrpc" + "vitess.io/vitess/go/vt/topo" "vitess.io/vitess/go/vt/vterrors" ) @@ -39,13 +43,61 @@ var ( // BackupEngine is the interface to take a backup with a given engine. type BackupEngine interface { - ExecuteBackup(ctx context.Context, cnf *Mycnf, mysqld MysqlDaemon, logger logutil.Logger, bh backupstorage.BackupHandle, backupConcurrency int, hookExtraEnv map[string]string) (bool, error) + ExecuteBackup(ctx context.Context, params BackupParams, bh backupstorage.BackupHandle) (bool, error) ShouldDrainForBackup() bool } +// BackupParams is the struct that holds all params passed to ExecuteBackup +type BackupParams struct { + Cnf *Mycnf + Mysqld MysqlDaemon + Logger logutil.Logger + // Concurrency is the value of -concurrency flag given to Backup command + // It determines how many files are processed in parallel + Concurrency int + // Extra env variables for pre-backup and post-backup transform hooks + HookExtraEnv map[string]string + // TopoServer, Keyspace and Shard are used to discover master tablet + TopoServer *topo.Server + // Keyspace and Shard are used to infer the directory where backups should be stored + Keyspace string + Shard string + // TabletAlias is used along with backupTime to construct the backup name + TabletAlias string + // BackupTime is the time at which the backup is being started + BackupTime time.Time +} + +// RestoreParams is the struct that holds all params passed to ExecuteRestore +type RestoreParams struct { + Cnf *Mycnf + Mysqld MysqlDaemon + Logger logutil.Logger + // Concurrency is the value of -restore_concurrency flag (init restore parameter) + // It determines how many files are processed in parallel + Concurrency int + // Extra env variables for pre-restore and post-restore transform hooks + HookExtraEnv map[string]string + // Metadata to write into database after restore. See PopulateMetadataTables + LocalMetadata map[string]string + // DeleteBeforeRestore tells us whether existing data should be deleted before + // restoring. This is always set to false when starting a tablet with -restore_from_backup, + // but is set to true when executing a RestoreFromBackup command on an already running vttablet + DeleteBeforeRestore bool + // DbName is the name of the managed database / schema + DbName string + // Keyspace and Shard are used to infer the directory where backups are stored + Keyspace string + Shard string + // StartTime: if non-zero, look for a backup that was taken at or before this time + // Otherwise, find the most recent backup + StartTime time.Time +} + // RestoreEngine is the interface to restore a backup with a given engine. +// Returns the manifest of a backup if successful, otherwise returns an error type RestoreEngine interface { - ExecuteRestore(ctx context.Context, cnf *Mycnf, mysqld MysqlDaemon, logger logutil.Logger, dir string, bh backupstorage.BackupHandle, restoreConcurrency int, hookExtraEnv map[string]string) (mysql.Position, error) + ExecuteRestore(ctx context.Context, params RestoreParams, bh backupstorage.BackupHandle) (*BackupManifest, error) } // BackupRestoreEngine is a combination of BackupEngine and RestoreEngine. @@ -130,6 +182,9 @@ type BackupManifest struct { // Position is the replication position at which the backup was taken. Position mysql.Position + // BackupTime is when the backup was taken in UTC time (RFC 3339 format) + BackupTime string + // FinishedTime is the time (in RFC 3339 format, UTC) at which the backup finished, if known. // Some backups may not set this field if they were created before the field was added. FinishedTime string @@ -138,23 +193,39 @@ type BackupManifest struct { // FindBackupToRestore returns a selected candidate backup to be restored. // It returns the most recent backup that is complete, meaning it has a valid // MANIFEST file. -func FindBackupToRestore(ctx context.Context, cnf *Mycnf, mysqld MysqlDaemon, logger logutil.Logger, dir string, bhs []backupstorage.BackupHandle) (backupstorage.BackupHandle, error) { +func FindBackupToRestore(ctx context.Context, params RestoreParams, bhs []backupstorage.BackupHandle) (backupstorage.BackupHandle, error) { var bh backupstorage.BackupHandle var index int + // if a StartTime is provided in params, then find a backup that was taken at or before that time + checkBackupTime := !params.StartTime.IsZero() + backupDir := GetBackupDir(params.Keyspace, params.Shard) for index = len(bhs) - 1; index >= 0; index-- { bh = bhs[index] // Check that the backup MANIFEST exists and can be successfully decoded. - _, err := GetBackupManifest(ctx, bh) + bm, err := GetBackupManifest(ctx, bh) if err != nil { - log.Warningf("Possibly incomplete backup %v in directory %v on BackupStorage: can't read MANIFEST: %v)", bh.Name(), dir, err) + params.Logger.Warningf("Possibly incomplete backup %v in directory %v on BackupStorage: can't read MANIFEST: %v)", bh.Name(), backupDir, err) continue } - logger.Infof("Restore: found backup %v %v to restore", bh.Directory(), bh.Name()) - break + var backupTime time.Time + if checkBackupTime { + backupTime, err = time.Parse(time.RFC3339, bm.BackupTime) + if err != nil { + params.Logger.Warningf("Restore: skipping backup %v/%v with invalid time %v: %v", backupDir, bh.Name(), bm.BackupTime, err) + continue + } + } + if !checkBackupTime /* not snapshot */ || backupTime.Equal(params.StartTime) || backupTime.Before(params.StartTime) { + params.Logger.Infof("Restore: found backup %v %v to restore", bh.Directory(), bh.Name()) + break + } } if index < 0 { + if checkBackupTime { + params.Logger.Errorf("No valid backup found before time %v", params.StartTime.Format(BackupTimestampFormat)) + } // There is at least one attempted backup, but none could be read. // This implies there is data we ought to have, so it's not safe to start // up empty. @@ -217,3 +288,125 @@ func RestoreWasInterrupted(cnf *Mycnf) bool { _, err := os.Stat(name) return err == nil } + +// GetBackupDir returns the directory where backups for the +// given keyspace/shard are (or will be) stored +func GetBackupDir(keyspace, shard string) string { + return fmt.Sprintf("%v/%v", keyspace, shard) +} + +// isDbDir returns true if the given directory contains a DB +func isDbDir(p string) bool { + // db.opt is there + if _, err := os.Stat(path.Join(p, "db.opt")); err == nil { + return true + } + + // Look for at least one database file + fis, err := ioutil.ReadDir(p) + if err != nil { + return false + } + for _, fi := range fis { + if strings.HasSuffix(fi.Name(), ".frm") { + return true + } + + // the MyRocks engine stores data in RocksDB .sst files + // https://github.com/facebook/rocksdb/wiki/Rocksdb-BlockBasedTable-Format + if strings.HasSuffix(fi.Name(), ".sst") { + return true + } + + // .frm files were removed in MySQL 8, so we need to check for two other file types + // https://dev.mysql.com/doc/refman/8.0/en/data-dictionary-file-removal.html + if strings.HasSuffix(fi.Name(), ".ibd") { + return true + } + // https://dev.mysql.com/doc/refman/8.0/en/serialized-dictionary-information.html + if strings.HasSuffix(fi.Name(), ".sdi") { + return true + } + } + + return false +} + +func addDirectory(fes []FileEntry, base string, baseDir string, subDir string) ([]FileEntry, int64, error) { + p := path.Join(baseDir, subDir) + var size int64 + + fis, err := ioutil.ReadDir(p) + if err != nil { + return nil, 0, err + } + for _, fi := range fis { + fes = append(fes, FileEntry{ + Base: base, + Name: path.Join(subDir, fi.Name()), + }) + size = size + fi.Size() + } + return fes, size, nil +} + +// addMySQL8DataDictionary checks to see if the new data dictionary introduced in MySQL 8 exists +// and adds it to the backup manifest if it does +// https://dev.mysql.com/doc/refman/8.0/en/data-dictionary-transactional-storage.html +func addMySQL8DataDictionary(fes []FileEntry, base string, baseDir string) ([]FileEntry, int64, error) { + filePath := path.Join(baseDir, dataDictionaryFile) + + // no-op if this file doesn't exist + fi, err := os.Stat(filePath) + if os.IsNotExist(err) { + return fes, 0, nil + } + + fes = append(fes, FileEntry{ + Base: base, + Name: dataDictionaryFile, + }) + + return fes, fi.Size(), nil +} + +func findFilesToBackup(cnf *Mycnf) ([]FileEntry, int64, error) { + var err error + var result []FileEntry + var totalSize int64 + + // first add inno db files + result, totalSize, err = addDirectory(result, backupInnodbDataHomeDir, cnf.InnodbDataHomeDir, "") + if err != nil { + return nil, 0, err + } + result, size, err := addDirectory(result, backupInnodbLogGroupHomeDir, cnf.InnodbLogGroupHomeDir, "") + if err != nil { + return nil, 0, err + } + totalSize = totalSize + size + // then add the transactional data dictionary if it exists + result, size, err = addMySQL8DataDictionary(result, backupData, cnf.DataDir) + if err != nil { + return nil, 0, err + } + totalSize = totalSize + size + + // then add DB directories + fis, err := ioutil.ReadDir(cnf.DataDir) + if err != nil { + return nil, 0, err + } + + for _, fi := range fis { + p := path.Join(cnf.DataDir, fi.Name()) + if isDbDir(p) { + result, size, err = addDirectory(result, backupData, cnf.DataDir, fi.Name()) + if err != nil { + return nil, 0, err + } + totalSize = totalSize + size + } + } + return result, totalSize, nil +} diff --git a/go/vt/mysqlctl/backupstorage/interface.go b/go/vt/mysqlctl/backupstorage/interface.go index e6dacb05177..03e7b64949c 100644 --- a/go/vt/mysqlctl/backupstorage/interface.go +++ b/go/vt/mysqlctl/backupstorage/interface.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -49,6 +49,8 @@ type BackupHandle interface { // multiple go routines once a backup has been started. // The context is valid for the duration of the writes, until the // WriteCloser is closed. + // filesize should not be treated as an exact value but rather + // as an approximate value AddFile(ctx context.Context, filename string, filesize int64) (io.WriteCloser, error) // EndBackup stops and closes a backup. The contents should be kept. diff --git a/go/vt/mysqlctl/builtinbackupengine.go b/go/vt/mysqlctl/builtinbackupengine.go index eba829a16bc..5f8af216dc0 100644 --- a/go/vt/mysqlctl/builtinbackupengine.go +++ b/go/vt/mysqlctl/builtinbackupengine.go @@ -1,5 +1,5 @@ /* -Copyright 2019 The Vitess Authors +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. @@ -22,10 +22,8 @@ import ( "encoding/json" "fmt" "io" - "io/ioutil" "os" "path" - "strings" "sync" "time" @@ -35,10 +33,12 @@ import ( "vitess.io/vitess/go/vt/concurrency" "vitess.io/vitess/go/vt/hook" "vitess.io/vitess/go/vt/log" - "vitess.io/vitess/go/vt/logutil" "vitess.io/vitess/go/vt/mysqlctl/backupstorage" "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/tmclient" ) const ( @@ -124,132 +124,22 @@ func (fe *FileEntry) open(cnf *Mycnf, readOnly bool) (*os.File, error) { return fd, nil } -// isDbDir returns true if the given directory contains a DB -func isDbDir(p string) bool { - // db.opt is there - if _, err := os.Stat(path.Join(p, "db.opt")); err == nil { - return true - } - - // Look for at least one database file - fis, err := ioutil.ReadDir(p) - if err != nil { - return false - } - for _, fi := range fis { - if strings.HasSuffix(fi.Name(), ".frm") { - return true - } - - // the MyRocks engine stores data in RocksDB .sst files - // https://github.com/facebook/rocksdb/wiki/Rocksdb-BlockBasedTable-Format - if strings.HasSuffix(fi.Name(), ".sst") { - return true - } - - // .frm files were removed in MySQL 8, so we need to check for two other file types - // https://dev.mysql.com/doc/refman/8.0/en/data-dictionary-file-removal.html - if strings.HasSuffix(fi.Name(), ".ibd") { - return true - } - // https://dev.mysql.com/doc/refman/8.0/en/serialized-dictionary-information.html - if strings.HasSuffix(fi.Name(), ".sdi") { - return true - } - } - - return false -} - -func addDirectory(fes []FileEntry, base string, baseDir string, subDir string) ([]FileEntry, error) { - p := path.Join(baseDir, subDir) - - fis, err := ioutil.ReadDir(p) - if err != nil { - return nil, err - } - for _, fi := range fis { - fes = append(fes, FileEntry{ - Base: base, - Name: path.Join(subDir, fi.Name()), - }) - } - return fes, nil -} - -// addMySQL8DataDictionary checks to see if the new data dictionary introduced in MySQL 8 exists -// and adds it to the backup manifest if it does -// https://dev.mysql.com/doc/refman/8.0/en/data-dictionary-transactional-storage.html -func addMySQL8DataDictionary(fes []FileEntry, base string, baseDir string) ([]FileEntry, error) { - filePath := path.Join(baseDir, dataDictionaryFile) - - // no-op if this file doesn't exist - if _, err := os.Stat(filePath); os.IsNotExist(err) { - return fes, nil - } - - fes = append(fes, FileEntry{ - Base: base, - Name: dataDictionaryFile, - }) - - return fes, nil -} - -func findFilesToBackup(cnf *Mycnf) ([]FileEntry, error) { - var err error - var result []FileEntry - - // first add inno db files - result, err = addDirectory(result, backupInnodbDataHomeDir, cnf.InnodbDataHomeDir, "") - if err != nil { - return nil, err - } - result, err = addDirectory(result, backupInnodbLogGroupHomeDir, cnf.InnodbLogGroupHomeDir, "") - if err != nil { - return nil, err - } - - // then add the transactional data dictionary if it exists - result, err = addMySQL8DataDictionary(result, backupData, cnf.DataDir) - if err != nil { - return nil, err - } - - // then add DB directories - fis, err := ioutil.ReadDir(cnf.DataDir) - if err != nil { - return nil, err - } - - for _, fi := range fis { - p := path.Join(cnf.DataDir, fi.Name()) - if isDbDir(p) { - result, err = addDirectory(result, backupData, cnf.DataDir, fi.Name()) - if err != nil { - return nil, err - } - } - } - return result, nil -} - // ExecuteBackup returns a boolean that indicates if the backup is usable, // and an overall error. -func (be *BuiltinBackupEngine) ExecuteBackup(ctx context.Context, cnf *Mycnf, mysqld MysqlDaemon, logger logutil.Logger, bh backupstorage.BackupHandle, backupConcurrency int, hookExtraEnv map[string]string) (bool, error) { +func (be *BuiltinBackupEngine) ExecuteBackup(ctx context.Context, params BackupParams, bh backupstorage.BackupHandle) (bool, error) { - logger.Infof("Hook: %v, Compress: %v", *backupStorageHook, *backupStorageCompress) + params.Logger.Infof("Hook: %v, Compress: %v", *backupStorageHook, *backupStorageCompress) // Save initial state so we can restore. slaveStartRequired := false sourceIsMaster := false readOnly := true var replicationPosition mysql.Position - semiSyncMaster, semiSyncSlave := mysqld.SemiSyncEnabled() + semiSyncMaster, semiSyncSlave := params.Mysqld.SemiSyncEnabled() // See if we need to restart replication after backup. - logger.Infof("getting current replication status") - slaveStatus, err := mysqld.SlaveStatus() + params.Logger.Infof("getting current replication status") + slaveStatus, err := params.Mysqld.SlaveStatus() switch err { case nil: slaveStartRequired = slaveStatus.SlaveRunning() @@ -261,7 +151,7 @@ func (be *BuiltinBackupEngine) ExecuteBackup(ctx context.Context, cnf *Mycnf, my } // get the read-only flag - readOnly, err = mysqld.IsReadOnly() + readOnly, err = params.Mysqld.IsReadOnly() if err != nil { return false, vterrors.Wrap(err, "can't get read-only status") } @@ -269,87 +159,123 @@ func (be *BuiltinBackupEngine) ExecuteBackup(ctx context.Context, cnf *Mycnf, my // get the replication position if sourceIsMaster { if !readOnly { - logger.Infof("turning master read-only before backup") - if err = mysqld.SetReadOnly(true); err != nil { + params.Logger.Infof("turning master read-only before backup") + if err = params.Mysqld.SetReadOnly(true); err != nil { return false, vterrors.Wrap(err, "can't set read-only status") } } - replicationPosition, err = mysqld.MasterPosition() + replicationPosition, err = params.Mysqld.MasterPosition() if err != nil { return false, vterrors.Wrap(err, "can't get master position") } } else { - if err = mysqld.StopSlave(hookExtraEnv); err != nil { + if err = params.Mysqld.StopSlave(params.HookExtraEnv); err != nil { return false, vterrors.Wrapf(err, "can't stop slave") } var slaveStatus mysql.SlaveStatus - slaveStatus, err = mysqld.SlaveStatus() + slaveStatus, err = params.Mysqld.SlaveStatus() if err != nil { return false, vterrors.Wrap(err, "can't get slave status") } replicationPosition = slaveStatus.Position } - logger.Infof("using replication position: %v", replicationPosition) + params.Logger.Infof("using replication position: %v", replicationPosition) // shutdown mysqld - err = mysqld.Shutdown(ctx, cnf, true) + err = params.Mysqld.Shutdown(ctx, params.Cnf, true) if err != nil { return false, vterrors.Wrap(err, "can't shutdown mysqld") } // Backup everything, capture the error. - backupErr := be.backupFiles(ctx, cnf, mysqld, logger, bh, replicationPosition, backupConcurrency, hookExtraEnv) + backupErr := be.backupFiles(ctx, params, bh, replicationPosition) usable := backupErr == nil // Try to restart mysqld, use background context in case we timed out the original context - err = mysqld.Start(context.Background(), cnf) + err = params.Mysqld.Start(context.Background(), params.Cnf) if err != nil { return usable, vterrors.Wrap(err, "can't restart mysqld") } + // And set read-only mode + params.Logger.Infof("resetting mysqld read-only to %v", readOnly) + if err := params.Mysqld.SetReadOnly(readOnly); err != nil { + return usable, err + } + // Restore original mysqld state that we saved above. if semiSyncMaster || semiSyncSlave { // Only do this if one of them was on, since both being off could mean // the plugin isn't even loaded, and the server variables don't exist. - logger.Infof("restoring semi-sync settings from before backup: master=%v, slave=%v", + params.Logger.Infof("restoring semi-sync settings from before backup: master=%v, slave=%v", semiSyncMaster, semiSyncSlave) - err := mysqld.SetSemiSyncEnabled(semiSyncMaster, semiSyncSlave) + err := params.Mysqld.SetSemiSyncEnabled(semiSyncMaster, semiSyncSlave) if err != nil { return usable, err } } if slaveStartRequired { - logger.Infof("restarting mysql replication") - if err := mysqld.StartSlave(hookExtraEnv); err != nil { + params.Logger.Infof("restarting mysql replication") + if err := params.Mysqld.StartSlave(params.HookExtraEnv); err != nil { return usable, vterrors.Wrap(err, "cannot restart slave") } // this should be quick, but we might as well just wait - if err := WaitForSlaveStart(mysqld, slaveStartDeadline); err != nil { + if err := WaitForSlaveStart(params.Mysqld, slaveStartDeadline); err != nil { return usable, vterrors.Wrap(err, "slave is not restarting") } - } - // And set read-only mode - logger.Infof("resetting mysqld read-only to %v", readOnly) - if err := mysqld.SetReadOnly(readOnly); err != nil { - return usable, err + // Wait for a reliable value for SecondsBehindMaster from SlaveStatus() + + // We know that we stopped at replicationPosition. + // If MasterPosition is the same, that means no writes + // have happened to master, so we are up-to-date. + // Otherwise, we wait for replica's Position to change from + // the saved replicationPosition before proceeding + tmc := tmclient.NewTabletManagerClient() + defer tmc.Close() + remoteCtx, remoteCancel := context.WithTimeout(ctx, *topo.RemoteOperationTimeout) + defer remoteCancel() + + masterPos, err := getMasterPosition(remoteCtx, tmc, params.TopoServer, params.Keyspace, params.Shard) + // If we are unable to get master position, return error. + if err != nil { + return usable, err + } + if !replicationPosition.Equal(masterPos) { + for { + if err := ctx.Err(); err != nil { + return usable, err + } + status, err := params.Mysqld.SlaveStatus() + if err != nil { + return usable, err + } + newPos := status.Position + if !newPos.Equal(replicationPosition) { + break + } + time.Sleep(1 * time.Second) + } + } } return usable, backupErr } // backupFiles finds the list of files to backup, and creates the backup. -func (be *BuiltinBackupEngine) backupFiles(ctx context.Context, cnf *Mycnf, mysqld MysqlDaemon, logger logutil.Logger, bh backupstorage.BackupHandle, replicationPosition mysql.Position, backupConcurrency int, hookExtraEnv map[string]string) (finalErr error) { +func (be *BuiltinBackupEngine) backupFiles(ctx context.Context, params BackupParams, bh backupstorage.BackupHandle, replicationPosition mysql.Position) (finalErr error) { + // Get the files to backup. - fes, err := findFilesToBackup(cnf) + // We don't care about totalSize because we add each file separately. + fes, _, err := findFilesToBackup(params.Cnf) if err != nil { return vterrors.Wrap(err, "can't find files to backup") } - logger.Infof("found %v files to backup", len(fes)) + params.Logger.Infof("found %v files to backup", len(fes)) // Backup with the provided concurrency. - sema := sync2.NewSemaphore(backupConcurrency, 0) + sema := sync2.NewSemaphore(params.Concurrency, 0) rec := concurrency.AllErrorRecorder{} wg := sync.WaitGroup{} for i := range fes { @@ -367,7 +293,7 @@ func (be *BuiltinBackupEngine) backupFiles(ctx context.Context, cnf *Mycnf, mysq // Backup the individual file. name := fmt.Sprintf("%v", i) - rec.RecordError(be.backupFile(ctx, cnf, mysqld, logger, bh, &fes[i], name, hookExtraEnv)) + rec.RecordError(be.backupFile(ctx, params, bh, &fes[i], name)) }(i) } @@ -393,6 +319,7 @@ func (be *BuiltinBackupEngine) backupFiles(ctx context.Context, cnf *Mycnf, mysq BackupManifest: BackupManifest{ BackupMethod: builtinBackupEngineName, Position: replicationPosition, + BackupTime: params.BackupTime.UTC().Format(time.RFC3339), FinishedTime: time.Now().UTC().Format(time.RFC3339), }, @@ -413,9 +340,9 @@ func (be *BuiltinBackupEngine) backupFiles(ctx context.Context, cnf *Mycnf, mysq } // backupFile backs up an individual file. -func (be *BuiltinBackupEngine) backupFile(ctx context.Context, cnf *Mycnf, mysqld MysqlDaemon, logger logutil.Logger, bh backupstorage.BackupHandle, fe *FileEntry, name string, hookExtraEnv map[string]string) (finalErr error) { +func (be *BuiltinBackupEngine) backupFile(ctx context.Context, params BackupParams, bh backupstorage.BackupHandle, fe *FileEntry, name string) (finalErr error) { // Open the source file for reading. - source, err := fe.open(cnf, true) + source, err := fe.open(params.Cnf, true) if err != nil { return err } @@ -426,7 +353,7 @@ func (be *BuiltinBackupEngine) backupFile(ctx context.Context, cnf *Mycnf, mysql return err } - logger.Infof("Backing up file: %v", fe.Name) + params.Logger.Infof("Backing up file: %v", fe.Name) // Open the destination file for writing, and a buffer. wc, err := bh.AddFile(ctx, name, fi.Size()) if err != nil { @@ -436,7 +363,7 @@ func (be *BuiltinBackupEngine) backupFile(ctx context.Context, cnf *Mycnf, mysql if rerr := wc.Close(); rerr != nil { if finalErr != nil { // We already have an error, just log this one. - logger.Errorf2(rerr, "failed to close file %v,%v", name, fe.Name) + params.Logger.Errorf2(rerr, "failed to close file %v,%v", name, fe.Name) } else { finalErr = rerr } @@ -453,7 +380,7 @@ func (be *BuiltinBackupEngine) backupFile(ctx context.Context, cnf *Mycnf, mysql var wait hook.WaitFunc if *backupStorageHook != "" { h := hook.NewHook(*backupStorageHook, []string{"-operation", "write"}) - h.ExtraEnv = hookExtraEnv + h.ExtraEnv = params.HookExtraEnv pipe, wait, _, err = h.ExecuteAsWritePipe(writer) if err != nil { return vterrors.Wrapf(err, "'%v' hook returned error", *backupStorageHook) @@ -493,7 +420,7 @@ func (be *BuiltinBackupEngine) backupFile(ctx context.Context, cnf *Mycnf, mysql } stderr, err := wait() if stderr != "" { - logger.Infof("'%v' hook returned stderr: %v", *backupStorageHook, stderr) + params.Logger.Infof("'%v' hook returned stderr: %v", *backupStorageHook, stderr) } if err != nil { return vterrors.Wrapf(err, "'%v' returned error", *backupStorageHook) @@ -513,47 +440,39 @@ func (be *BuiltinBackupEngine) backupFile(ctx context.Context, cnf *Mycnf, mysql // ExecuteRestore restores from a backup. If the restore is successful // we return the position from which replication should start // otherwise an error is returned -func (be *BuiltinBackupEngine) ExecuteRestore( - ctx context.Context, - cnf *Mycnf, - mysqld MysqlDaemon, - logger logutil.Logger, - dir string, - bh backupstorage.BackupHandle, - restoreConcurrency int, - hookExtraEnv map[string]string) (mysql.Position, error) { - - zeroPosition := mysql.Position{} +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 { - return zeroPosition, err + return nil, err } // mark restore as in progress - if err := createStateFile(cnf); err != nil { - return zeroPosition, err + if err := createStateFile(params.Cnf); err != nil { + return nil, err } - if err := prepareToRestore(ctx, cnf, mysqld, logger); err != nil { - return zeroPosition, err + if err := prepareToRestore(ctx, params.Cnf, params.Mysqld, params.Logger); err != nil { + return nil, err } - logger.Infof("Restore: copying %v files", len(bm.FileEntries)) + params.Logger.Infof("Restore: copying %v files", len(bm.FileEntries)) - if err := be.restoreFiles(context.Background(), cnf, bh, bm.FileEntries, bm.TransformHook, !bm.SkipCompress, restoreConcurrency, hookExtraEnv, logger); err != nil { + if err := be.restoreFiles(context.Background(), params, bh, bm); err != nil { // don't delete the file here because that is how we detect an interrupted restore - return zeroPosition, vterrors.Wrap(err, "failed to restore files") + return nil, vterrors.Wrap(err, "failed to restore files") } - logger.Infof("Restore: returning replication position %v", bm.Position) - return bm.Position, nil + params.Logger.Infof("Restore: returning replication position %v", bm.Position) + return &bm.BackupManifest, nil } // restoreFiles will copy all the files from the BackupStorage to the // right place. -func (be *BuiltinBackupEngine) restoreFiles(ctx context.Context, cnf *Mycnf, bh backupstorage.BackupHandle, fes []FileEntry, transformHook string, compress bool, restoreConcurrency int, hookExtraEnv map[string]string, logger logutil.Logger) error { - sema := sync2.NewSemaphore(restoreConcurrency, 0) +func (be *BuiltinBackupEngine) restoreFiles(ctx context.Context, params RestoreParams, bh backupstorage.BackupHandle, bm builtinBackupManifest) error { + fes := bm.FileEntries + sema := sync2.NewSemaphore(params.Concurrency, 0) rec := concurrency.AllErrorRecorder{} wg := sync.WaitGroup{} for i := range fes { @@ -571,8 +490,8 @@ func (be *BuiltinBackupEngine) restoreFiles(ctx context.Context, cnf *Mycnf, bh // And restore the file. name := fmt.Sprintf("%v", i) - logger.Infof("Copying file %v: %v", name, fes[i].Name) - err := be.restoreFile(ctx, cnf, bh, &fes[i], transformHook, compress, name, hookExtraEnv) + params.Logger.Infof("Copying file %v: %v", name, fes[i].Name) + err := be.restoreFile(ctx, params, bh, &fes[i], bm.TransformHook, !bm.SkipCompress, name) if err != nil { rec.RecordError(vterrors.Wrapf(err, "can't restore file %v to %v", name, fes[i].Name)) } @@ -583,7 +502,7 @@ func (be *BuiltinBackupEngine) restoreFiles(ctx context.Context, cnf *Mycnf, bh } // restoreFile restores an individual file. -func (be *BuiltinBackupEngine) restoreFile(ctx context.Context, cnf *Mycnf, bh backupstorage.BackupHandle, fe *FileEntry, transformHook string, compress bool, name string, hookExtraEnv map[string]string) (finalErr error) { +func (be *BuiltinBackupEngine) restoreFile(ctx context.Context, params RestoreParams, bh backupstorage.BackupHandle, fe *FileEntry, transformHook string, compress bool, name string) (finalErr error) { // Open the source file for reading. source, err := bh.ReadFile(ctx, name) if err != nil { @@ -592,7 +511,7 @@ func (be *BuiltinBackupEngine) restoreFile(ctx context.Context, cnf *Mycnf, bh b defer source.Close() // Open the destination file for writing. - dstFile, err := fe.open(cnf, false) + dstFile, err := fe.open(params.Cnf, false) if err != nil { return vterrors.Wrap(err, "can't open destination file for writing") } @@ -621,7 +540,7 @@ func (be *BuiltinBackupEngine) restoreFile(ctx context.Context, cnf *Mycnf, bh b var wait hook.WaitFunc if transformHook != "" { h := hook.NewHook(transformHook, []string{"-operation", "read"}) - h.ExtraEnv = hookExtraEnv + h.ExtraEnv = params.HookExtraEnv reader, wait, _, err = h.ExecuteAsReadPipe(reader) if err != nil { return vterrors.Wrapf(err, "'%v' hook returned error", transformHook) @@ -683,6 +602,29 @@ func (be *BuiltinBackupEngine) ShouldDrainForBackup() bool { return true } +func getMasterPosition(ctx context.Context, tmc tmclient.TabletManagerClient, ts *topo.Server, keyspace, shard string) (mysql.Position, error) { + si, err := ts.GetShard(ctx, keyspace, shard) + if err != nil { + return mysql.Position{}, vterrors.Wrap(err, "can't read shard") + } + if topoproto.TabletAliasIsZero(si.MasterAlias) { + return mysql.Position{}, fmt.Errorf("shard %v/%v has no master", keyspace, shard) + } + ti, err := ts.GetTablet(ctx, si.MasterAlias) + if err != nil { + return mysql.Position{}, fmt.Errorf("can't get master tablet record %v: %v", topoproto.TabletAliasString(si.MasterAlias), err) + } + posStr, err := tmc.MasterPosition(ctx, ti.Tablet) + if err != nil { + return mysql.Position{}, fmt.Errorf("can't get master replication position: %v", err) + } + pos, err := mysql.DecodePosition(posStr) + if err != nil { + return mysql.Position{}, fmt.Errorf("can't decode master replication position %q: %v", posStr, err) + } + return pos, nil +} + func init() { BackupRestoreEngineMap["builtin"] = &BuiltinBackupEngine{} } diff --git a/go/vt/mysqlctl/capabilityset.go b/go/vt/mysqlctl/capabilityset.go index 68319450f53..909eec70ac3 100644 --- a/go/vt/mysqlctl/capabilityset.go +++ b/go/vt/mysqlctl/capabilityset.go @@ -1,5 +1,5 @@ /* -Copyright 2019 The Vitess Authors +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. @@ -46,24 +46,6 @@ func (c *capabilitySet) hasMySQLUpgradeInServer() bool { func (c *capabilitySet) hasInitializeInServer() bool { return c.isMySQLLike() && c.version.atLeast(serverVersion{Major: 5, Minor: 7, Patch: 0}) } -func (c *capabilitySet) hasMySQLxEnabledByDefault() bool { - return c.isMySQLLike() && c.version.atLeast(serverVersion{Major: 8, Minor: 0, Patch: 11}) -} -func (c *capabilitySet) hasPersistConfig() bool { - return c.isMySQLLike() && c.version.atLeast(serverVersion{Major: 8, Minor: 0, Patch: 0}) -} -func (c *capabilitySet) hasShutdownCommand() bool { - return (c.isMySQLLike() && c.version.atLeast(serverVersion{Major: 5, Minor: 7, Patch: 9})) || (c.isMariaDB() && c.version.atLeast(serverVersion{Major: 10, Minor: 0, Patch: 4})) -} -func (c *capabilitySet) hasBackupLocks() bool { - return c.isMySQLLike() && c.version.atLeast(serverVersion{Major: 8, Minor: 0, Patch: 0}) -} -func (c *capabilitySet) hasDefaultUft8mb4() bool { - return c.isMySQLLike() && c.version.atLeast(serverVersion{Major: 8, Minor: 0, Patch: 0}) -} -func (c *capabilitySet) hasSemiSyncEnabledByDefault() bool { - return c.isMariaDB() && c.version.atLeast(serverVersion{Major: 10, Minor: 3, Patch: 3}) -} // IsMySQLLike tests if the server is either MySQL // or Percona Server. At least currently, Vitess doesn't @@ -71,9 +53,3 @@ func (c *capabilitySet) hasSemiSyncEnabledByDefault() bool { func (c *capabilitySet) isMySQLLike() bool { return c.flavor == flavorMySQL || c.flavor == flavorPercona } - -// IsMariaDB tests if the server is MariaDB. -// IsMySQLLike() and IsMariaDB() are mutually exclusive -func (c *capabilitySet) isMariaDB() bool { - return c.flavor == flavorMariaDB -} diff --git a/go/vt/mysqlctl/cephbackupstorage/ceph.go b/go/vt/mysqlctl/cephbackupstorage/ceph.go index a98e5229d7e..29b76e1b15e 100644 --- a/go/vt/mysqlctl/cephbackupstorage/ceph.go +++ b/go/vt/mysqlctl/cephbackupstorage/ceph.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/mysqlctl/cmd.go b/go/vt/mysqlctl/cmd.go index 7289d999570..7d4a9ea0c96 100644 --- a/go/vt/mysqlctl/cmd.go +++ b/go/vt/mysqlctl/cmd.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/mysqlctl/fakemysqldaemon/fakemysqldaemon.go b/go/vt/mysqlctl/fakemysqldaemon/fakemysqldaemon.go index dcc76a6d945..6759edebeb4 100644 --- a/go/vt/mysqlctl/fakemysqldaemon/fakemysqldaemon.go +++ b/go/vt/mysqlctl/fakemysqldaemon/fakemysqldaemon.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -33,6 +33,7 @@ import ( "vitess.io/vitess/go/vt/mysqlctl" "vitess.io/vitess/go/vt/mysqlctl/tmutils" + querypb "vitess.io/vitess/go/vt/proto/query" tabletmanagerdatapb "vitess.io/vitess/go/vt/proto/tabletmanagerdata" ) @@ -304,7 +305,7 @@ func (fmd *FakeMysqlDaemon) WaitForReparentJournal(ctx context.Context, timeCrea return nil } -// Deprecated: use mysqld.MasterPosition() instead +// DemoteMaster is deprecated: use mysqld.MasterPosition() instead func (fmd *FakeMysqlDaemon) DemoteMaster() (mysql.Position, error) { return fmd.CurrentMasterPosition, nil } @@ -412,8 +413,8 @@ func (fmd *FakeMysqlDaemon) GetSchema(dbName string, tables, excludeTables []str } // GetColumns is part of the MysqlDaemon interface -func (fmd *FakeMysqlDaemon) GetColumns(dbName, table string) ([]string, error) { - return []string{}, nil +func (fmd *FakeMysqlDaemon) GetColumns(dbName, table string) ([]*querypb.Field, []string, error) { + return []*querypb.Field{}, []string{}, nil } // GetPrimaryKeyColumns is part of the MysqlDaemon interface diff --git a/go/vt/mysqlctl/filebackupstorage/file.go b/go/vt/mysqlctl/filebackupstorage/file.go index d2a93ea0ddc..c99a0ee6b0a 100644 --- a/go/vt/mysqlctl/filebackupstorage/file.go +++ b/go/vt/mysqlctl/filebackupstorage/file.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/mysqlctl/filebackupstorage/file_test.go b/go/vt/mysqlctl/filebackupstorage/file_test.go index fe23d949fbc..ac20fe69cf3 100644 --- a/go/vt/mysqlctl/filebackupstorage/file_test.go +++ b/go/vt/mysqlctl/filebackupstorage/file_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/mysqlctl/fileutil.go b/go/vt/mysqlctl/fileutil.go index 331b6378785..4b479eab11c 100644 --- a/go/vt/mysqlctl/fileutil.go +++ b/go/vt/mysqlctl/fileutil.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Vitess Authors. +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. @@ -20,18 +20,9 @@ import ( "encoding/hex" "hash" "hash/crc32" - "os" ) -// Use this to simulate failures in tests -var ( - simulateFailures = false -) - -func init() { - _, statErr := os.Stat("/tmp/vtSimulateFetchFailures") - simulateFailures = statErr == nil -} +// TODO(sougou): this file should be renamed. // our hasher, implemented using crc32 type hasher struct { diff --git a/go/vt/mysqlctl/gcsbackupstorage/gcs.go b/go/vt/mysqlctl/gcsbackupstorage/gcs.go index 54bea5aa3af..513a15ae16c 100644 --- a/go/vt/mysqlctl/gcsbackupstorage/gcs.go +++ b/go/vt/mysqlctl/gcsbackupstorage/gcs.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/mysqlctl/grpcmysqlctlclient/client.go b/go/vt/mysqlctl/grpcmysqlctlclient/client.go index 5fdd18ba04c..0bf8323dc04 100644 --- a/go/vt/mysqlctl/grpcmysqlctlclient/client.go +++ b/go/vt/mysqlctl/grpcmysqlctlclient/client.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/mysqlctl/grpcmysqlctlserver/server.go b/go/vt/mysqlctl/grpcmysqlctlserver/server.go index 72be321923a..94046b1399e 100644 --- a/go/vt/mysqlctl/grpcmysqlctlserver/server.go +++ b/go/vt/mysqlctl/grpcmysqlctlserver/server.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/mysqlctl/metadata_tables.go b/go/vt/mysqlctl/metadata_tables.go index d1607723467..4df32691eac 100644 --- a/go/vt/mysqlctl/metadata_tables.go +++ b/go/vt/mysqlctl/metadata_tables.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -30,7 +30,7 @@ import ( const ( sqlCreateLocalMetadataTable = `CREATE TABLE IF NOT EXISTS _vt.local_metadata ( name VARCHAR(255) NOT NULL, - value VARCHAR(255) NOT NULL, + value MEDIUMBLOB NOT NULL, PRIMARY KEY (name) ) ENGINE=InnoDB` sqlCreateShardMetadataTable = `CREATE TABLE IF NOT EXISTS _vt.shard_metadata ( @@ -46,6 +46,9 @@ var ( sqlAlterLocalMetadataTable = []string{ `ALTER TABLE _vt.local_metadata ADD COLUMN db_name VARBINARY(255) NOT NULL DEFAULT ''`, `ALTER TABLE _vt.local_metadata DROP PRIMARY KEY, ADD PRIMARY KEY(name, db_name)`, + // VARCHAR(255) is not long enough to hold replication positions, hence changing to + // MEDIUMBLOB. + `ALTER TABLE _vt.local_metadata CHANGE value value MEDIUMBLOB NOT NULL`, } sqlAlterShardMetadataTable = []string{ `ALTER TABLE _vt.shard_metadata ADD COLUMN db_name VARBINARY(255) NOT NULL DEFAULT ''`, @@ -88,32 +91,32 @@ func PopulateMetadataTables(mysqld MysqlDaemon, localMetadata map[string]string, } for _, sql := range sqlAlterLocalMetadataTable { if _, err := conn.ExecuteFetch(sql, 0, false); err != nil { - if merr, ok := err.(*mysql.SQLError); ok && merr.Num == mysql.ERDupFieldName { - log.Errorf("Expected error executing %v: %v", sql, err) - } else { - log.Errorf("Unexpected error executing %v: %v", sql, err) + // Ignore "Duplicate column name 'db_name'" errors which can happen on every restart. + if merr, ok := err.(*mysql.SQLError); !ok || merr.Num != mysql.ERDupFieldName { + log.Errorf("Error executing %v: %v", sql, err) return err } } } - if _, err := conn.ExecuteFetch(fmt.Sprintf(sqlUpdateLocalMetadataTable, dbName), 0, false); err != nil { - return err + sql := fmt.Sprintf(sqlUpdateLocalMetadataTable, dbName) + if _, err := conn.ExecuteFetch(sql, 0, false); err != nil { + log.Errorf("Error executing %v: %v, continuing. Please check the data in _vt.local_metadata and take corrective action.", sql, err) } if _, err := conn.ExecuteFetch(sqlCreateShardMetadataTable, 0, false); err != nil { return err } for _, sql := range sqlAlterShardMetadataTable { if _, err := conn.ExecuteFetch(sql, 0, false); err != nil { - if merr, ok := err.(*mysql.SQLError); ok && merr.Num == mysql.ERDupFieldName { - log.Errorf("Expected error executing %v: %v", sql, err) - } else { - log.Errorf("Unexpected error executing %v: %v", sql, err) + // Ignore "Duplicate column name 'db_name'" errors which can happen on every restart. + if merr, ok := err.(*mysql.SQLError); !ok || merr.Num != mysql.ERDupFieldName { + log.Errorf("Error executing %v: %v", sql, err) return err } } } - if _, err := conn.ExecuteFetch(fmt.Sprintf(sqlUpdateShardMetadataTable, dbName), 0, false); err != nil { - return err + sql = fmt.Sprintf(sqlUpdateShardMetadataTable, dbName) + if _, err := conn.ExecuteFetch(sql, 0, false); err != nil { + log.Errorf("Error executing %v: %v, continuing. Please check the data in _vt.shard_metadata and take corrective action.", sql, err) } // Populate local_metadata from the passed list of values. diff --git a/go/vt/mysqlctl/mycnf.go b/go/vt/mysqlctl/mycnf.go index f4dae766bbb..234618e6d55 100644 --- a/go/vt/mysqlctl/mycnf.go +++ b/go/vt/mysqlctl/mycnf.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/mysqlctl/mycnf_flag.go b/go/vt/mysqlctl/mycnf_flag.go index 024be07403d..ac1bc92d715 100644 --- a/go/vt/mysqlctl/mycnf_flag.go +++ b/go/vt/mysqlctl/mycnf_flag.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/mysqlctl/mycnf_gen.go b/go/vt/mysqlctl/mycnf_gen.go index 348260f4627..eda6b5d6f48 100644 --- a/go/vt/mysqlctl/mycnf_gen.go +++ b/go/vt/mysqlctl/mycnf_gen.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/mysqlctl/mycnf_test.go b/go/vt/mysqlctl/mycnf_test.go index 0298b7f8713..e7215f894fe 100644 --- a/go/vt/mysqlctl/mycnf_test.go +++ b/go/vt/mysqlctl/mycnf_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -86,7 +86,6 @@ func TestMycnf(t *testing.T) { // 3. go test // 4. \rm $VTROOT/vthook/make_mycnf // 5. Add No Prefix back -//lint:ignore U1000 Test for Mycnf hook changes func NoTestMycnfHook(t *testing.T) { os.Setenv("MYSQL_FLAVOR", "MariaDB") uid := uint32(11111) diff --git a/go/vt/mysqlctl/mysql_daemon.go b/go/vt/mysqlctl/mysql_daemon.go index 93ba4a718ce..18d6d6816e0 100644 --- a/go/vt/mysqlctl/mysql_daemon.go +++ b/go/vt/mysqlctl/mysql_daemon.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -24,6 +24,7 @@ import ( "vitess.io/vitess/go/vt/dbconnpool" "vitess.io/vitess/go/vt/mysqlctl/tmutils" + querypb "vitess.io/vitess/go/vt/proto/query" tabletmanagerdatapb "vitess.io/vitess/go/vt/proto/tabletmanagerdata" ) @@ -69,7 +70,7 @@ type MysqlDaemon interface { // Schema related methods GetSchema(dbName string, tables, excludeTables []string, includeViews bool) (*tabletmanagerdatapb.SchemaDefinition, error) - GetColumns(dbName, table string) ([]string, error) + GetColumns(dbName, table string) ([]*querypb.Field, []string, error) GetPrimaryKeyColumns(dbName, table string) ([]string, error) PreflightSchemaChange(dbName string, changes []string) ([]*tabletmanagerdatapb.SchemaChangeResult, error) ApplySchemaChange(dbName string, change *tmutils.SchemaChange) (*tabletmanagerdatapb.SchemaChangeResult, error) diff --git a/go/vt/mysqlctl/mysqlctlclient/interface.go b/go/vt/mysqlctl/mysqlctlclient/interface.go index c5ba0be1bbe..d8c26ebe7ec 100644 --- a/go/vt/mysqlctl/mysqlctlclient/interface.go +++ b/go/vt/mysqlctl/mysqlctlclient/interface.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/mysqlctl/mysqld.go b/go/vt/mysqlctl/mysqld.go index e99f63ec33d..3402829441d 100644 --- a/go/vt/mysqlctl/mysqld.go +++ b/go/vt/mysqlctl/mysqld.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -83,6 +83,9 @@ var ( versionRegex = regexp.MustCompile(`Ver ([0-9]+)\.([0-9]+)\.([0-9]+)`) ) +// How many bytes from MySQL error log to sample for error messages +const maxLogFileSampleSize = 4096 + // Mysqld is the object that represents a mysqld daemon running on this server. type Mysqld struct { dbcfgs *dbconfigs.DBConfigs @@ -112,16 +115,56 @@ func NewMysqld(dbcfgs *dbconfigs.DBConfigs) *Mysqld { result.appPool = dbconnpool.NewConnectionPool("AppConnPool", *appPoolSize, *appIdleTimeout, *poolDynamicHostnameResolution) result.appPool.Open(dbcfgs.AppWithDB(), appMysqlStats) + /* + Unmanaged tablets are special because the MYSQL_FLAVOR detection + will not be accurate because the mysqld might not be the same + one as the server started. + + This skips the panic that checks that we can detect a server, + but also relies on none of the flavor detection features being + used at runtime. Currently this assumption is guaranteed true. + */ + if dbconfigs.HasConnectionParams() { + log.Info("mysqld is unmanaged or remote. Skipping flavor detection") + return result + } version, getErr := getVersionString() f, v, err := parseVersionString(version) - // Fallback if required + /* + By default Vitess searches in vtenv.VtMysqlRoot() for a mysqld binary. + This is usually the VT_MYSQL_ROOT env, but if it is unset or empty, it + will substitute VtRoot(). See go/vt/env/env.go. + + A number of subdirs inside vtenv.VtMysqlRoot() will be searched, see + func binaryPath() for context. If no mysqld binary is found (possibly + because it is in a container or both VT_MYSQL_ROOT and VTROOT are set + incorrectly), there will be a fallback to using the MYSQL_FLAVOR env + variable. + + If MYSQL_FLAVOR is not defined, there will be a panic. + + Note: relying on MySQL_FLAVOR is not recommended, since for historical + purposes "MySQL56" actually means MySQL 5.7, which is a very strange + behavior. + */ + if getErr != nil || err != nil { f, v, err = getVersionFromEnv() if err != nil { - panic("could not detect version from mysqld --version or MYSQL_FLAVOR") + vtenvMysqlRoot, _ := vtenv.VtMysqlRoot() + message := fmt.Sprintf(`could not auto-detect MySQL version. You may need to set VT_MYSQL_ROOT so a mysqld binary can be found, or set the environment variable MYSQL_FLAVOR if mysqld is not available locally: + VT_MYSQL_ROOT: %s + VTROOT: %s + vtenv.VtMysqlRoot(): %s + MYSQL_FLAVOR: %s + `, + os.Getenv("VT_MYSQL_ROOT"), + os.Getenv("VTROOT"), + vtenvMysqlRoot, + os.Getenv("MYSQL_FLAVOR")) + panic(message) } - } log.Infof("Using flavor: %v, version: %v", f, v) @@ -607,7 +650,7 @@ func (mysqld *Mysqld) Init(ctx context.Context, cnf *Mycnf, initDBSQLFile string // Start mysqld. We do not use Start, as we have to wait using // the root user. if err = mysqld.startNoWait(ctx, cnf); err != nil { - log.Errorf("failed starting mysqld (check mysql error log %v for more info): %v", cnf.ErrorLogPath, err) + log.Errorf("failed starting mysqld: %v\n%v", err, readTailOfMysqldErrorLog(cnf.ErrorLogPath)) return err } @@ -619,7 +662,7 @@ func (mysqld *Mysqld) Init(ctx context.Context, cnf *Mycnf, initDBSQLFile string UnixSocket: cnf.SocketFile, } if err = mysqld.wait(ctx, cnf, params); err != nil { - log.Errorf("failed starting mysqld in time (check mysyql error log %v for more info): %v", cnf.ErrorLogPath, err) + log.Errorf("failed starting mysqld in time: %v\n%v", err, readTailOfMysqldErrorLog(cnf.ErrorLogPath)) return err } @@ -636,6 +679,36 @@ func (mysqld *Mysqld) Init(ctx context.Context, cnf *Mycnf, initDBSQLFile string return nil } +// For debugging purposes show the last few lines of the MySQL error log. +// Return a suggestion (string) if the file is non regular or can not be opened. +// This helps prevent cases where the error log is symlinked to /dev/stderr etc, +// In which case the user can manually open the file. +func readTailOfMysqldErrorLog(fileName string) string { + fileInfo, err := os.Stat(fileName) + if err != nil { + return fmt.Sprintf("could not stat mysql error log (%v): %v", fileName, err) + } + if !fileInfo.Mode().IsRegular() { + return fmt.Sprintf("mysql error log file is not a regular file: %v", fileName) + } + file, err := os.Open(fileName) + if err != nil { + return fmt.Sprintf("could not open mysql error log (%v): %v", fileName, err) + } + defer file.Close() + startPos := int64(0) + if fileInfo.Size() > maxLogFileSampleSize { + startPos = fileInfo.Size() - maxLogFileSampleSize + } + // Show the last few KB of the MySQL error log. + buf := make([]byte, maxLogFileSampleSize) + flen, err := file.ReadAt(buf, startPos) + if err != nil && err != io.EOF { + return fmt.Sprintf("could not read mysql error log (%v): %v", fileName, err) + } + return fmt.Sprintf("tail of mysql error log (%v):\n%s", fileName, buf[:flen]) +} + func (mysqld *Mysqld) installDataDir(cnf *Mycnf) error { mysqlRoot, err := vtenv.VtMysqlRoot() if err != nil { @@ -658,7 +731,7 @@ func (mysqld *Mysqld) installDataDir(cnf *Mycnf) error { "--initialize-insecure", // Use empty 'root'@'localhost' password. } if _, _, err = execCmd(mysqldPath, args, nil, mysqlRoot, nil); err != nil { - log.Errorf("mysqld --initialize-insecure failed: %v", err) + log.Errorf("mysqld --initialize-insecure failed: %v\n%v", err, readTailOfMysqldErrorLog(cnf.ErrorLogPath)) return err } return nil @@ -674,7 +747,7 @@ func (mysqld *Mysqld) installDataDir(cnf *Mycnf) error { return err } if _, _, err = execCmd(cmdPath, args, nil, mysqlRoot, nil); err != nil { - log.Errorf("mysql_install_db failed: %v", err) + log.Errorf("mysql_install_db failed: %v\n%v", err, readTailOfMysqldErrorLog(cnf.ErrorLogPath)) return err } return nil @@ -731,8 +804,7 @@ func (mysqld *Mysqld) getMycnfTemplates(root string) []string { cnfTemplatePaths = append(cnfTemplatePaths, parts...) } - // Only include these files if they exist. - // master_{flavor}.cnf + // Only include files if they exist. // Percona Server == MySQL in this context f := flavorMariaDB @@ -740,15 +812,9 @@ func (mysqld *Mysqld) getMycnfTemplates(root string) []string { f = flavorMySQL } - p := path.Join(root, fmt.Sprintf("config/mycnf/master_%s.cnf", f)) - _, err := os.Stat(p) - if err == nil && !contains(cnfTemplatePaths, p) { - cnfTemplatePaths = append(cnfTemplatePaths, p) - } - // master_{flavor}{major}{minor}.cnf - p = path.Join(root, fmt.Sprintf("config/mycnf/master_%s%d%d.cnf", f, mysqld.capabilities.version.Major, mysqld.capabilities.version.Minor)) - _, err = os.Stat(p) + p := path.Join(root, fmt.Sprintf("config/mycnf/master_%s%d%d.cnf", f, mysqld.capabilities.version.Major, mysqld.capabilities.version.Minor)) + _, err := os.Stat(p) if err == nil && !contains(cnfTemplatePaths, p) { cnfTemplatePaths = append(cnfTemplatePaths, p) } diff --git a/go/vt/mysqlctl/mysqld_test.go b/go/vt/mysqlctl/mysqld_test.go index f3e45b87e18..3e27b89c7ae 100644 --- a/go/vt/mysqlctl/mysqld_test.go +++ b/go/vt/mysqlctl/mysqld_test.go @@ -1,5 +1,5 @@ /* -Copyright 2019 The Vitess Authors +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. diff --git a/go/vt/mysqlctl/permissions.go b/go/vt/mysqlctl/permissions.go index 18af508f412..149b20612e8 100644 --- a/go/vt/mysqlctl/permissions.go +++ b/go/vt/mysqlctl/permissions.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/mysqlctl/plugin_grpcmysqlctlclient.go b/go/vt/mysqlctl/plugin_grpcmysqlctlclient.go index 11d3d8b7592..c88628ebd0d 100644 --- a/go/vt/mysqlctl/plugin_grpcmysqlctlclient.go +++ b/go/vt/mysqlctl/plugin_grpcmysqlctlclient.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/mysqlctl/query.go b/go/vt/mysqlctl/query.go index 0051f5bd6d5..aab8852d74d 100644 --- a/go/vt/mysqlctl/query.go +++ b/go/vt/mysqlctl/query.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -72,7 +72,7 @@ func (mysqld *Mysqld) executeSuperQueryListConn(ctx context.Context, conn *dbcon for _, query := range queryList { log.Infof("exec %v", redactMasterPassword(query)) if _, err := mysqld.executeFetchContext(ctx, conn, query, 10000, false); err != nil { - return fmt.Errorf("ExecuteFetch(%v) failed: %v", redactMasterPassword(query), err.Error()) + return fmt.Errorf("ExecuteFetch(%v) failed: %v", redactMasterPassword(query), redactMasterPassword(err.Error())) } } return nil diff --git a/go/vt/mysqlctl/reparent.go b/go/vt/mysqlctl/reparent.go index 3510085dfb9..ce865b4e12d 100644 --- a/go/vt/mysqlctl/reparent.go +++ b/go/vt/mysqlctl/reparent.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/mysqlctl/replication.go b/go/vt/mysqlctl/replication.go index 6774918733d..67acf25ff95 100644 --- a/go/vt/mysqlctl/replication.go +++ b/go/vt/mysqlctl/replication.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -181,6 +181,17 @@ func (mysqld *Mysqld) WaitMasterPos(ctx context.Context, targetPos mysql.Positio } defer conn.Recycle() + // If we are the master, WaitUntilPositionCommand will fail. + // But position is most likely reached. So, check the position + // first. + mpos, err := conn.MasterPosition() + if err != nil { + return fmt.Errorf("WaitMasterPos: MasterPosition failed: %v", err) + } + if mpos.AtLeast(targetPos) { + return nil + } + // Find the query to run, run it. query, err := conn.WaitUntilPositionCommand(ctx, targetPos) if err != nil { @@ -285,12 +296,9 @@ func (mysqld *Mysqld) ResetReplication(ctx context.Context) error { // // Array indices for the results of SHOW PROCESSLIST. const ( - //lint:ignore U1000 needed for correct indexing of result columns colConnectionID = iota - //lint:ignore U1000 needed for correct indexing of result columns colUsername colClientAddr - //lint:ignore U1000 needed for correct indexing of result columns colDbName colCommand ) diff --git a/go/vt/mysqlctl/replication_test.go b/go/vt/mysqlctl/replication_test.go index a4aca51574d..ef1d2becb4b 100644 --- a/go/vt/mysqlctl/replication_test.go +++ b/go/vt/mysqlctl/replication_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/mysqlctl/s3backupstorage/s3.go b/go/vt/mysqlctl/s3backupstorage/s3.go index b6e3261b2ef..985c18befaa 100644 --- a/go/vt/mysqlctl/s3backupstorage/s3.go +++ b/go/vt/mysqlctl/s3backupstorage/s3.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 @@ -50,6 +50,9 @@ var ( // AWS API region region = flag.String("s3_backup_aws_region", "us-east-1", "AWS region to use") + // AWS request retries + retryCount = flag.Int("s3_backup_aws_retries", -1, "AWS request retries") + // AWS endpoint, defaults to amazonaws.com but appliances may use a different location endpoint = flag.String("s3_backup_aws_endpoint", "", "endpoint of the S3 backend (region must be provided)") @@ -340,14 +343,20 @@ func (bs *S3BackupStorage) client() (*s3.S3, error) { if err != nil { return nil, err } - bs._client = s3.New(session, - &aws.Config{ - HTTPClient: httpClient, - LogLevel: logLevel, - Endpoint: aws.String(*endpoint), - Region: aws.String(*region), - S3ForcePathStyle: aws.Bool(*forcePath), - }) + + awsConfig := aws.Config{ + HTTPClient: httpClient, + LogLevel: logLevel, + Endpoint: aws.String(*endpoint), + Region: aws.String(*region), + S3ForcePathStyle: aws.Bool(*forcePath), + } + + if *retryCount >= 0 { + awsConfig.WithMaxRetries(*retryCount) + } + + bs._client = s3.New(session, &awsConfig) if len(*bucket) == 0 { return nil, fmt.Errorf("-s3_backup_storage_bucket required") diff --git a/go/vt/mysqlctl/schema.go b/go/vt/mysqlctl/schema.go index 16e114eb625..dd2a91e15d9 100644 --- a/go/vt/mysqlctl/schema.go +++ b/go/vt/mysqlctl/schema.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -29,6 +29,7 @@ import ( "vitess.io/vitess/go/vt/log" "vitess.io/vitess/go/vt/mysqlctl/tmutils" + querypb "vitess.io/vitess/go/vt/proto/query" tabletmanagerdatapb "vitess.io/vitess/go/vt/proto/tabletmanagerdata" ) @@ -122,7 +123,7 @@ func (mysqld *Mysqld) GetSchema(dbName string, tables, excludeTables []string, i td.Name = tableName td.Schema = norm - td.Columns, err = mysqld.GetColumns(dbName, tableName) + td.Fields, td.Columns, err = mysqld.GetColumns(dbName, tableName) if err != nil { return nil, err } @@ -159,21 +160,21 @@ func ResolveTables(mysqld MysqlDaemon, dbName string, tables []string) ([]string } // GetColumns returns the columns of table. -func (mysqld *Mysqld) GetColumns(dbName, table string) ([]string, error) { +func (mysqld *Mysqld) GetColumns(dbName, table string) ([]*querypb.Field, []string, error) { conn, err := getPoolReconnect(context.TODO(), mysqld.dbaPool) if err != nil { - return nil, err + return nil, nil, err } defer conn.Recycle() qr, err := conn.ExecuteFetch(fmt.Sprintf("SELECT * FROM %s.%s WHERE 1=0", sqlescape.EscapeID(dbName), sqlescape.EscapeID(table)), 0, true) if err != nil { - return nil, err + return nil, nil, err } columns := make([]string, len(qr.Fields)) for i, field := range qr.Fields { columns[i] = field.Name } - return columns, nil + return qr.Fields, columns, nil } diff --git a/go/vt/mysqlctl/tmutils/permissions.go b/go/vt/mysqlctl/tmutils/permissions.go index 43b4c8cbcac..8042e6d7a7a 100644 --- a/go/vt/mysqlctl/tmutils/permissions.go +++ b/go/vt/mysqlctl/tmutils/permissions.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/mysqlctl/tmutils/permissions_test.go b/go/vt/mysqlctl/tmutils/permissions_test.go index 9e2d1fe666c..6305772147a 100644 --- a/go/vt/mysqlctl/tmutils/permissions_test.go +++ b/go/vt/mysqlctl/tmutils/permissions_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/mysqlctl/tmutils/schema.go b/go/vt/mysqlctl/tmutils/schema.go index 9f027d2839b..58e547d16a2 100644 --- a/go/vt/mysqlctl/tmutils/schema.go +++ b/go/vt/mysqlctl/tmutils/schema.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -78,8 +78,8 @@ func FilterTables(sd *tabletmanagerdatapb.SchemaDefinition, tables, excludeTable if len(tables) > 0 { tableRegexps = make([]*regexp.Regexp, len(tables)) for i, table := range tables { - if len(table) > 2 && strings.HasPrefix(table, "/") && strings.HasSuffix(table, "/") { - table = table[1 : len(table)-1] + if strings.HasPrefix(table, "/") { + table = strings.Trim(table, "/") var err error tableRegexps[i], err = regexp.Compile(table) if err != nil { @@ -92,8 +92,8 @@ func FilterTables(sd *tabletmanagerdatapb.SchemaDefinition, tables, excludeTable if len(excludeTables) > 0 { excludeTableRegexps = make([]*regexp.Regexp, len(excludeTables)) for i, table := range excludeTables { - if len(table) > 2 && strings.HasPrefix(table, "/") && strings.HasSuffix(table, "/") { - table = table[1 : len(table)-1] + if strings.HasPrefix(table, "/") { + table = strings.Trim(table, "/") var err error excludeTableRegexps[i], err = regexp.Compile(table) if err != nil { diff --git a/go/vt/mysqlctl/tmutils/schema_test.go b/go/vt/mysqlctl/tmutils/schema_test.go index c46d7a1a4e7..1775aae805d 100644 --- a/go/vt/mysqlctl/tmutils/schema_test.go +++ b/go/vt/mysqlctl/tmutils/schema_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/mysqlctl/utils.go b/go/vt/mysqlctl/utils.go index ce147e8250d..cc34be6abfe 100644 --- a/go/vt/mysqlctl/utils.go +++ b/go/vt/mysqlctl/utils.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/mysqlctl/utils_test.go b/go/vt/mysqlctl/utils_test.go index 4c17759305f..0fdcae92bfa 100644 --- a/go/vt/mysqlctl/utils_test.go +++ b/go/vt/mysqlctl/utils_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/mysqlctl/version.go b/go/vt/mysqlctl/version.go index 05bb18c20ef..d543680883c 100644 --- a/go/vt/mysqlctl/version.go +++ b/go/vt/mysqlctl/version.go @@ -1,5 +1,5 @@ /* -Copyright 2019 The Vitess Authors +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. diff --git a/go/vt/mysqlctl/xtrabackupengine.go b/go/vt/mysqlctl/xtrabackupengine.go index 31158dba7d9..fc9e27e2523 100644 --- a/go/vt/mysqlctl/xtrabackupengine.go +++ b/go/vt/mysqlctl/xtrabackupengine.go @@ -1,5 +1,5 @@ /* -Copyright 2019 The Vitess Authors +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. @@ -66,6 +66,9 @@ const ( xtrabackupBinaryName = "xtrabackup" xtrabackupEngineName = "xtrabackup" xbstream = "xbstream" + + // closeTimeout is the timeout for closing backup files after writing. + closeTimeout = 10 * time.Minute ) // xtraBackupManifest represents a backup. @@ -106,14 +109,25 @@ func (be *XtrabackupEngine) backupFileName() string { return fileName } +func closeFile(wc io.WriteCloser, fileName string, logger logutil.Logger, finalErr *error) { + logger.Infof("Closing backup file %v", fileName) + if closeErr := wc.Close(); *finalErr == nil { + *finalErr = closeErr + } else if closeErr != nil { + // since we already have an error just log this + logger.Errorf("error closing file %v: %v", fileName, closeErr) + } +} + // ExecuteBackup returns a boolean that indicates if the backup is usable, // and an overall error. -func (be *XtrabackupEngine) ExecuteBackup(ctx context.Context, cnf *Mycnf, mysqld MysqlDaemon, logger logutil.Logger, bh backupstorage.BackupHandle, backupConcurrency int, hookExtraEnv map[string]string) (complete bool, finalErr error) { +func (be *XtrabackupEngine) ExecuteBackup(ctx context.Context, params BackupParams, bh backupstorage.BackupHandle) (complete bool, finalErr error) { + if *xtrabackupUser == "" { return false, vterrors.New(vtrpc.Code_INVALID_ARGUMENT, "xtrabackupUser must be specified.") } // use a mysql connection to detect flavor at runtime - conn, err := mysqld.GetDbaConnection() + conn, err := params.Mysqld.GetDbaConnection() if conn != nil && err == nil { defer conn.Close() } @@ -126,54 +140,129 @@ func (be *XtrabackupEngine) ExecuteBackup(ctx context.Context, cnf *Mycnf, mysql return false, vterrors.Wrap(err, "unable to obtain master position") } flavor := pos.GTIDSet.Flavor() - logger.Infof("Detected MySQL flavor: %v", flavor) + params.Logger.Infof("Detected MySQL flavor: %v", flavor) - backupProgram := path.Join(*xtrabackupEnginePath, xtrabackupBinaryName) + backupFileName := be.backupFileName() + numStripes := int(*xtrabackupStripes) - flagsToExec := []string{"--defaults-file=" + cnf.path, + // Perform backups in a separate function, so deferred calls to Close() are + // all done before we continue to write the MANIFEST. This ensures that we + // do not write the MANIFEST unless all files were closed successfully, + // maintaining the contract that a MANIFEST file should only exist if the + // backup was created successfully. + params.Logger.Infof("Starting backup with %v stripe(s)", numStripes) + replicationPosition, err := be.backupFiles(ctx, params, bh, backupFileName, numStripes, flavor) + if err != nil { + return false, err + } + + // open the MANIFEST + params.Logger.Infof("Writing backup MANIFEST") + mwc, err := bh.AddFile(ctx, backupManifestFileName, 0) + if err != nil { + return false, vterrors.Wrapf(err, "cannot add %v to backup", backupManifestFileName) + } + defer closeFile(mwc, backupManifestFileName, params.Logger, &finalErr) + + // JSON-encode and write the MANIFEST + bm := &xtraBackupManifest{ + // Common base fields + BackupManifest: BackupManifest{ + BackupMethod: xtrabackupEngineName, + Position: replicationPosition, + BackupTime: params.BackupTime.UTC().Format(time.RFC3339), + FinishedTime: time.Now().UTC().Format(time.RFC3339), + }, + + // XtraBackup-specific fields + FileName: backupFileName, + StreamMode: *xtrabackupStreamMode, + SkipCompress: !*backupStorageCompress, + Params: *xtrabackupBackupFlags, + NumStripes: int32(numStripes), + StripeBlockSize: int32(*xtrabackupStripeBlockSize), + } + + data, err := json.MarshalIndent(bm, "", " ") + if err != nil { + return false, vterrors.Wrapf(err, "cannot JSON encode %v", backupManifestFileName) + } + if _, err := mwc.Write([]byte(data)); err != nil { + return false, vterrors.Wrapf(err, "cannot write %v", backupManifestFileName) + } + + params.Logger.Infof("Backup completed") + return true, nil +} + +func (be *XtrabackupEngine) backupFiles(ctx context.Context, params BackupParams, bh backupstorage.BackupHandle, backupFileName string, numStripes int, flavor string) (replicationPosition mysql.Position, finalErr error) { + + backupProgram := path.Join(*xtrabackupEnginePath, xtrabackupBinaryName) + flagsToExec := []string{"--defaults-file=" + params.Cnf.path, "--backup", - "--socket=" + cnf.SocketFile, + "--socket=" + params.Cnf.SocketFile, "--slave-info", "--user=" + *xtrabackupUser, - "--target-dir=" + cnf.TmpDir, + "--target-dir=" + params.Cnf.TmpDir, } if *xtrabackupStreamMode != "" { flagsToExec = append(flagsToExec, "--stream="+*xtrabackupStreamMode) } - if *xtrabackupBackupFlags != "" { flagsToExec = append(flagsToExec, strings.Fields(*xtrabackupBackupFlags)...) } - backupFileName := be.backupFileName() - numStripes := int(*xtrabackupStripes) - - destFiles, err := addStripeFiles(ctx, bh, backupFileName, numStripes, logger) + // Create a cancellable Context for calls to bh.AddFile(). + // This allows us to decide later if we need to cancel an attempt to Close() + // the file returned from AddFile(), since Close() itself does not accept a + // Context value. We can't use a context.WithTimeout() here because that + // would impose a timeout that starts counting right now, so it would + // include the time spent uploading the file content. We only want to impose + // a timeout on the final Close() step. + addFilesCtx, cancelAddFiles := context.WithCancel(ctx) + defer cancelAddFiles() + destFiles, err := addStripeFiles(addFilesCtx, params, bh, backupFileName, numStripes) if err != nil { - return false, vterrors.Wrapf(err, "cannot create backup file %v", backupFileName) - } - closeFile := func(wc io.WriteCloser, fileName string) { - if closeErr := wc.Close(); finalErr == nil { - finalErr = closeErr - } else if closeErr != nil { - // since we already have an error just log this - logger.Errorf("error closing file %v: %v", fileName, closeErr) - } + return replicationPosition, vterrors.Wrapf(err, "cannot create backup file %v", backupFileName) } defer func() { - for _, file := range destFiles { - closeFile(file, backupFileName) + // Impose a timeout on the process of closing files. + go func() { + timer := time.NewTimer(closeTimeout) + + select { + case <-addFilesCtx.Done(): + timer.Stop() + return + case <-timer.C: + params.Logger.Errorf("Timed out waiting for Close() on backup file to complete") + // Cancelling the Context that was originally passed to bh.AddFile() + // should hopefully cause Close() calls on the file that AddFile() + // returned to abort. If the underlying implementation doesn't + // respect cancellation of the AddFile() Context while inside + // Close(), then we just hang because it's unsafe to return and + // leave Close() running indefinitely in the background. + cancelAddFiles() + } + }() + + filename := backupFileName + for i, file := range destFiles { + if numStripes > 1 { + filename = stripeFileName(backupFileName, i) + } + closeFile(file, filename, params.Logger, &finalErr) } }() backupCmd := exec.CommandContext(ctx, backupProgram, flagsToExec...) backupOut, err := backupCmd.StdoutPipe() if err != nil { - return false, vterrors.Wrap(err, "cannot create stdout pipe") + return replicationPosition, vterrors.Wrap(err, "cannot create stdout pipe") } backupErr, err := backupCmd.StderrPipe() if err != nil { - return false, vterrors.Wrap(err, "cannot create stderr pipe") + return replicationPosition, vterrors.Wrap(err, "cannot create stderr pipe") } destWriters := []io.Writer{} @@ -188,7 +277,7 @@ func (be *XtrabackupEngine) ExecuteBackup(ctx context.Context, cnf *Mycnf, mysql if *backupStorageCompress { compressor, err := pgzip.NewWriterLevel(writer, pgzip.BestSpeed) if err != nil { - return false, vterrors.Wrap(err, "cannot create gzip compressor") + return replicationPosition, vterrors.Wrap(err, "cannot create gzip compressor") } compressor.SetConcurrency(*backupCompressBlockSize, *backupCompressBlocks) writer = compressor @@ -199,7 +288,7 @@ func (be *XtrabackupEngine) ExecuteBackup(ctx context.Context, cnf *Mycnf, mysql } if err = backupCmd.Start(); err != nil { - return false, vterrors.Wrap(err, "unable to start backup") + return replicationPosition, vterrors.Wrap(err, "unable to start backup") } // Read stderr in the background, so we can log progress as xtrabackup runs. @@ -215,7 +304,7 @@ func (be *XtrabackupEngine) ExecuteBackup(ctx context.Context, cnf *Mycnf, mysql capture := false for scanner.Scan() { line := scanner.Text() - logger.Infof("xtrabackup stderr: %s", line) + params.Logger.Infof("xtrabackup stderr: %s", line) // Wait until we see the first line of the binlog position. // Then capture all subsequent lines. We need multiple lines since @@ -229,7 +318,7 @@ func (be *XtrabackupEngine) ExecuteBackup(ctx context.Context, cnf *Mycnf, mysql fmt.Fprintln(stderrBuilder, line) } if err := scanner.Err(); err != nil { - logger.Errorf("error reading from xtrabackup stderr: %v", err) + params.Logger.Errorf("error reading from xtrabackup stderr: %v", err) } }() @@ -240,20 +329,20 @@ func (be *XtrabackupEngine) ExecuteBackup(ctx context.Context, cnf *Mycnf, mysql blockSize = 1024 } if _, err := copyToStripes(destWriters, backupOut, blockSize); err != nil { - return false, vterrors.Wrap(err, "cannot copy output from xtrabackup command") + return replicationPosition, vterrors.Wrap(err, "cannot copy output from xtrabackup command") } // Close compressor to flush it. After that all data is sent to the buffer. for _, compressor := range destCompressors { if err := compressor.Close(); err != nil { - return false, vterrors.Wrap(err, "cannot close gzip compressor") + return replicationPosition, vterrors.Wrap(err, "cannot close gzip compressor") } } // Flush the buffer to finish writing on destination. for _, buffer := range destBuffers { if err = buffer.Flush(); err != nil { - return false, vterrors.Wrapf(err, "cannot flush destination: %v", backupFileName) + return replicationPosition, vterrors.Wrapf(err, "cannot flush destination: %v", backupFileName) } } @@ -263,86 +352,45 @@ func (be *XtrabackupEngine) ExecuteBackup(ctx context.Context, cnf *Mycnf, mysql sterrOutput := stderrBuilder.String() if err := backupCmd.Wait(); err != nil { - return false, vterrors.Wrap(err, "xtrabackup failed with error") + return replicationPosition, vterrors.Wrap(err, "xtrabackup failed with error") } - replicationPosition, rerr := findReplicationPosition(sterrOutput, flavor, logger) + replicationPosition, rerr := findReplicationPosition(sterrOutput, flavor, params.Logger) if rerr != nil { - return false, vterrors.Wrap(rerr, "backup failed trying to find replication position") - } - // open the MANIFEST - mwc, err := bh.AddFile(ctx, backupManifestFileName, 0) - if err != nil { - return false, vterrors.Wrapf(err, "cannot add %v to backup", backupManifestFileName) - } - defer closeFile(mwc, backupManifestFileName) - - // JSON-encode and write the MANIFEST - bm := &xtraBackupManifest{ - // Common base fields - BackupManifest: BackupManifest{ - BackupMethod: xtrabackupEngineName, - Position: replicationPosition, - FinishedTime: time.Now().UTC().Format(time.RFC3339), - }, - - // XtraBackup-specific fields - FileName: backupFileName, - StreamMode: *xtrabackupStreamMode, - SkipCompress: !*backupStorageCompress, - Params: *xtrabackupBackupFlags, - NumStripes: int32(numStripes), - StripeBlockSize: int32(*xtrabackupStripeBlockSize), - } - - data, err := json.MarshalIndent(bm, "", " ") - if err != nil { - return false, vterrors.Wrapf(err, "cannot JSON encode %v", backupManifestFileName) - } - if _, err := mwc.Write([]byte(data)); err != nil { - return false, vterrors.Wrapf(err, "cannot write %v", backupManifestFileName) + return replicationPosition, vterrors.Wrap(rerr, "backup failed trying to find replication position") } - return true, nil + return replicationPosition, nil } // ExecuteRestore restores from a backup. Any error is returned. -func (be *XtrabackupEngine) ExecuteRestore( - ctx context.Context, - cnf *Mycnf, - mysqld MysqlDaemon, - logger logutil.Logger, - dir string, - bh backupstorage.BackupHandle, - restoreConcurrency int, - hookExtraEnv map[string]string) (mysql.Position, error) { - - zeroPosition := mysql.Position{} +func (be *XtrabackupEngine) ExecuteRestore(ctx context.Context, params RestoreParams, bh backupstorage.BackupHandle) (*BackupManifest, error) { + var bm xtraBackupManifest if err := getBackupManifestInto(ctx, bh, &bm); err != nil { - return zeroPosition, err + return nil, err } // mark restore as in progress - if err := createStateFile(cnf); err != nil { - return zeroPosition, err + if err := createStateFile(params.Cnf); err != nil { + return nil, err } - if err := prepareToRestore(ctx, cnf, mysqld, logger); err != nil { - return zeroPosition, err + if err := prepareToRestore(ctx, params.Cnf, params.Mysqld, params.Logger); err != nil { + return nil, err } // copy / extract files - logger.Infof("Restore: Extracting files from %v", bm.FileName) + params.Logger.Infof("Restore: Extracting files from %v", bm.FileName) - if err := be.restoreFromBackup(ctx, cnf, bh, bm, logger); err != nil { + if err := be.restoreFromBackup(ctx, params.Cnf, bh, bm, params.Logger); err != nil { // don't delete the file here because that is how we detect an interrupted restore - return zeroPosition, err + return nil, err } // now find the slave position and return that - logger.Infof("Restore: returning replication position %v", bm.Position) - return bm.Position, nil + params.Logger.Infof("Restore: returning replication position %v", bm.Position) + return &bm.BackupManifest, nil } func (be *XtrabackupEngine) restoreFromBackup(ctx context.Context, cnf *Mycnf, bh backupstorage.BackupHandle, bm xtraBackupManifest, logger logutil.Logger) error { @@ -354,6 +402,13 @@ func (be *XtrabackupEngine) restoreFromBackup(ctx context.Context, cnf *Mycnf, b if err := os.MkdirAll(tempDir, os.ModePerm); err != nil { return err } + // delete tempDir once we are done + defer func(dir string, l logutil.Logger) { + err := os.RemoveAll(dir) + if err != nil { + l.Errorf("error deleting tempDir(%v): %v", dir, err) + } + }(tempDir, logger) if err := be.extractFiles(ctx, logger, bh, bm, tempDir); err != nil { logger.Errorf("error extracting backup files: %v", err) @@ -459,7 +514,7 @@ func (be *XtrabackupEngine) extractFiles(ctx context.Context, logger logutil.Log for _, file := range srcFiles { reader := io.Reader(file) - // Create the decompresser if needed. + // Create the decompressor if needed. if compressed { decompressor, err := pgzip.NewReader(reader) if err != nil { @@ -599,21 +654,35 @@ func stripeFileName(baseFileName string, index int) string { return fmt.Sprintf("%s-%03d", baseFileName, index) } -func addStripeFiles(ctx context.Context, backupHandle backupstorage.BackupHandle, baseFileName string, numStripes int, logger logutil.Logger) ([]io.WriteCloser, error) { +func addStripeFiles(ctx context.Context, params BackupParams, backupHandle backupstorage.BackupHandle, baseFileName string, numStripes int) ([]io.WriteCloser, error) { + // Compute total size of all files we will backup. + // We delegate the actual backing up to xtrabackup which streams + // the files as a single archive (tar / xbstream), which might + // further be compressed using gzip. + // This approximate total size is passed in to AddFile so that + // storage plugins can make appropriate choices for parameters + // like partSize in multi-part uploads + _, totalSize, err := findFilesToBackup(params.Cnf) + if err != nil { + return nil, err + } + if numStripes <= 1 { // No striping. - file, err := backupHandle.AddFile(ctx, baseFileName, 0) + file, err := backupHandle.AddFile(ctx, baseFileName, totalSize) return []io.WriteCloser{file}, err } files := []io.WriteCloser{} for i := 0; i < numStripes; i++ { - file, err := backupHandle.AddFile(ctx, stripeFileName(baseFileName, i), 0) + filename := stripeFileName(baseFileName, i) + params.Logger.Infof("Opening backup stripe file %v", filename) + file, err := backupHandle.AddFile(ctx, filename, totalSize/int64(numStripes)) if err != nil { // Close any files we already opened and clear them from the result. for _, file := range files { if err := file.Close(); err != nil { - logger.Warningf("error closing backup stripe file: %v", err) + params.Logger.Warningf("error closing backup stripe file: %v", err) } } return nil, err diff --git a/go/vt/mysqlctl/xtrabackupengine_test.go b/go/vt/mysqlctl/xtrabackupengine_test.go index d8587176164..26e53c6c949 100644 --- a/go/vt/mysqlctl/xtrabackupengine_test.go +++ b/go/vt/mysqlctl/xtrabackupengine_test.go @@ -1,3 +1,19 @@ +/* +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 mysqlctl import ( diff --git a/go/vt/mysqlproxy/mysqlproxy.go b/go/vt/mysqlproxy/mysqlproxy.go index 9172316ca24..a58ba59eb16 100644 --- a/go/vt/mysqlproxy/mysqlproxy.go +++ b/go/vt/mysqlproxy/mysqlproxy.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/proto/automation/automation.pb.go b/go/vt/proto/automation/automation.pb.go index e810986daee..fe039ca84ef 100644 --- a/go/vt/proto/automation/automation.pb.go +++ b/go/vt/proto/automation/automation.pb.go @@ -1,11 +1,14 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // source: automation.proto -package automation // import "vitess.io/vitess/go/vt/proto/automation" +package automation -import proto "github.com/golang/protobuf/proto" -import fmt "fmt" -import math "math" +import ( + fmt "fmt" + math "math" + + proto "github.com/golang/protobuf/proto" +) // Reference imports to suppress errors if they are not otherwise used. var _ = proto.Marshal @@ -16,7 +19,7 @@ var _ = math.Inf // is compatible with the proto package it is being compiled against. // A compilation error at this line likely means your copy of the // proto package needs to be updated. -const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package +const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package type ClusterOperationState int32 @@ -33,6 +36,7 @@ var ClusterOperationState_name = map[int32]string{ 2: "CLUSTER_OPERATION_RUNNING", 3: "CLUSTER_OPERATION_DONE", } + var ClusterOperationState_value = map[string]int32{ "UNKNOWN_CLUSTER_OPERATION_STATE": 0, "CLUSTER_OPERATION_NOT_STARTED": 1, @@ -43,8 +47,9 @@ var ClusterOperationState_value = map[string]int32{ func (x ClusterOperationState) String() string { return proto.EnumName(ClusterOperationState_name, int32(x)) } + func (ClusterOperationState) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_automation_4d7d55680fa173cc, []int{0} + return fileDescriptor_06e15ad07c41cb38, []int{0} } type TaskState int32 @@ -62,6 +67,7 @@ var TaskState_name = map[int32]string{ 2: "RUNNING", 3: "DONE", } + var TaskState_value = map[string]int32{ "UNKNOWN_TASK_STATE": 0, "NOT_STARTED": 1, @@ -72,8 +78,9 @@ var TaskState_value = map[string]int32{ func (x TaskState) String() string { return proto.EnumName(TaskState_name, int32(x)) } + func (TaskState) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_automation_4d7d55680fa173cc, []int{1} + return fileDescriptor_06e15ad07c41cb38, []int{1} } type ClusterOperation struct { @@ -93,16 +100,17 @@ func (m *ClusterOperation) Reset() { *m = ClusterOperation{} } func (m *ClusterOperation) String() string { return proto.CompactTextString(m) } func (*ClusterOperation) ProtoMessage() {} func (*ClusterOperation) Descriptor() ([]byte, []int) { - return fileDescriptor_automation_4d7d55680fa173cc, []int{0} + return fileDescriptor_06e15ad07c41cb38, []int{0} } + func (m *ClusterOperation) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ClusterOperation.Unmarshal(m, b) } func (m *ClusterOperation) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_ClusterOperation.Marshal(b, m, deterministic) } -func (dst *ClusterOperation) XXX_Merge(src proto.Message) { - xxx_messageInfo_ClusterOperation.Merge(dst, src) +func (m *ClusterOperation) XXX_Merge(src proto.Message) { + xxx_messageInfo_ClusterOperation.Merge(m, src) } func (m *ClusterOperation) XXX_Size() int { return xxx_messageInfo_ClusterOperation.Size(m) @@ -155,16 +163,17 @@ func (m *TaskContainer) Reset() { *m = TaskContainer{} } func (m *TaskContainer) String() string { return proto.CompactTextString(m) } func (*TaskContainer) ProtoMessage() {} func (*TaskContainer) Descriptor() ([]byte, []int) { - return fileDescriptor_automation_4d7d55680fa173cc, []int{1} + return fileDescriptor_06e15ad07c41cb38, []int{1} } + func (m *TaskContainer) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_TaskContainer.Unmarshal(m, b) } func (m *TaskContainer) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_TaskContainer.Marshal(b, m, deterministic) } -func (dst *TaskContainer) XXX_Merge(src proto.Message) { - xxx_messageInfo_TaskContainer.Merge(dst, src) +func (m *TaskContainer) XXX_Merge(src proto.Message) { + xxx_messageInfo_TaskContainer.Merge(m, src) } func (m *TaskContainer) XXX_Size() int { return xxx_messageInfo_TaskContainer.Size(m) @@ -210,16 +219,17 @@ func (m *Task) Reset() { *m = Task{} } func (m *Task) String() string { return proto.CompactTextString(m) } func (*Task) ProtoMessage() {} func (*Task) Descriptor() ([]byte, []int) { - return fileDescriptor_automation_4d7d55680fa173cc, []int{2} + return fileDescriptor_06e15ad07c41cb38, []int{2} } + func (m *Task) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Task.Unmarshal(m, b) } func (m *Task) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_Task.Marshal(b, m, deterministic) } -func (dst *Task) XXX_Merge(src proto.Message) { - xxx_messageInfo_Task.Merge(dst, src) +func (m *Task) XXX_Merge(src proto.Message) { + xxx_messageInfo_Task.Merge(m, src) } func (m *Task) XXX_Size() int { return xxx_messageInfo_Task.Size(m) @@ -284,16 +294,17 @@ func (m *EnqueueClusterOperationRequest) Reset() { *m = EnqueueClusterOp func (m *EnqueueClusterOperationRequest) String() string { return proto.CompactTextString(m) } func (*EnqueueClusterOperationRequest) ProtoMessage() {} func (*EnqueueClusterOperationRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_automation_4d7d55680fa173cc, []int{3} + return fileDescriptor_06e15ad07c41cb38, []int{3} } + func (m *EnqueueClusterOperationRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_EnqueueClusterOperationRequest.Unmarshal(m, b) } func (m *EnqueueClusterOperationRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_EnqueueClusterOperationRequest.Marshal(b, m, deterministic) } -func (dst *EnqueueClusterOperationRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_EnqueueClusterOperationRequest.Merge(dst, src) +func (m *EnqueueClusterOperationRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_EnqueueClusterOperationRequest.Merge(m, src) } func (m *EnqueueClusterOperationRequest) XXX_Size() int { return xxx_messageInfo_EnqueueClusterOperationRequest.Size(m) @@ -329,16 +340,17 @@ func (m *EnqueueClusterOperationResponse) Reset() { *m = EnqueueClusterO func (m *EnqueueClusterOperationResponse) String() string { return proto.CompactTextString(m) } func (*EnqueueClusterOperationResponse) ProtoMessage() {} func (*EnqueueClusterOperationResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_automation_4d7d55680fa173cc, []int{4} + return fileDescriptor_06e15ad07c41cb38, []int{4} } + func (m *EnqueueClusterOperationResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_EnqueueClusterOperationResponse.Unmarshal(m, b) } func (m *EnqueueClusterOperationResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_EnqueueClusterOperationResponse.Marshal(b, m, deterministic) } -func (dst *EnqueueClusterOperationResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_EnqueueClusterOperationResponse.Merge(dst, src) +func (m *EnqueueClusterOperationResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_EnqueueClusterOperationResponse.Merge(m, src) } func (m *EnqueueClusterOperationResponse) XXX_Size() int { return xxx_messageInfo_EnqueueClusterOperationResponse.Size(m) @@ -367,16 +379,17 @@ func (m *GetClusterOperationStateRequest) Reset() { *m = GetClusterOpera func (m *GetClusterOperationStateRequest) String() string { return proto.CompactTextString(m) } func (*GetClusterOperationStateRequest) ProtoMessage() {} func (*GetClusterOperationStateRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_automation_4d7d55680fa173cc, []int{5} + return fileDescriptor_06e15ad07c41cb38, []int{5} } + func (m *GetClusterOperationStateRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_GetClusterOperationStateRequest.Unmarshal(m, b) } func (m *GetClusterOperationStateRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_GetClusterOperationStateRequest.Marshal(b, m, deterministic) } -func (dst *GetClusterOperationStateRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_GetClusterOperationStateRequest.Merge(dst, src) +func (m *GetClusterOperationStateRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_GetClusterOperationStateRequest.Merge(m, src) } func (m *GetClusterOperationStateRequest) XXX_Size() int { return xxx_messageInfo_GetClusterOperationStateRequest.Size(m) @@ -405,16 +418,17 @@ func (m *GetClusterOperationStateResponse) Reset() { *m = GetClusterOper func (m *GetClusterOperationStateResponse) String() string { return proto.CompactTextString(m) } func (*GetClusterOperationStateResponse) ProtoMessage() {} func (*GetClusterOperationStateResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_automation_4d7d55680fa173cc, []int{6} + return fileDescriptor_06e15ad07c41cb38, []int{6} } + func (m *GetClusterOperationStateResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_GetClusterOperationStateResponse.Unmarshal(m, b) } func (m *GetClusterOperationStateResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_GetClusterOperationStateResponse.Marshal(b, m, deterministic) } -func (dst *GetClusterOperationStateResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_GetClusterOperationStateResponse.Merge(dst, src) +func (m *GetClusterOperationStateResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_GetClusterOperationStateResponse.Merge(m, src) } func (m *GetClusterOperationStateResponse) XXX_Size() int { return xxx_messageInfo_GetClusterOperationStateResponse.Size(m) @@ -443,16 +457,17 @@ func (m *GetClusterOperationDetailsRequest) Reset() { *m = GetClusterOpe func (m *GetClusterOperationDetailsRequest) String() string { return proto.CompactTextString(m) } func (*GetClusterOperationDetailsRequest) ProtoMessage() {} func (*GetClusterOperationDetailsRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_automation_4d7d55680fa173cc, []int{7} + return fileDescriptor_06e15ad07c41cb38, []int{7} } + func (m *GetClusterOperationDetailsRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_GetClusterOperationDetailsRequest.Unmarshal(m, b) } func (m *GetClusterOperationDetailsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_GetClusterOperationDetailsRequest.Marshal(b, m, deterministic) } -func (dst *GetClusterOperationDetailsRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_GetClusterOperationDetailsRequest.Merge(dst, src) +func (m *GetClusterOperationDetailsRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_GetClusterOperationDetailsRequest.Merge(m, src) } func (m *GetClusterOperationDetailsRequest) XXX_Size() int { return xxx_messageInfo_GetClusterOperationDetailsRequest.Size(m) @@ -482,16 +497,17 @@ func (m *GetClusterOperationDetailsResponse) Reset() { *m = GetClusterOp func (m *GetClusterOperationDetailsResponse) String() string { return proto.CompactTextString(m) } func (*GetClusterOperationDetailsResponse) ProtoMessage() {} func (*GetClusterOperationDetailsResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_automation_4d7d55680fa173cc, []int{8} + return fileDescriptor_06e15ad07c41cb38, []int{8} } + func (m *GetClusterOperationDetailsResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_GetClusterOperationDetailsResponse.Unmarshal(m, b) } func (m *GetClusterOperationDetailsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_GetClusterOperationDetailsResponse.Marshal(b, m, deterministic) } -func (dst *GetClusterOperationDetailsResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_GetClusterOperationDetailsResponse.Merge(dst, src) +func (m *GetClusterOperationDetailsResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_GetClusterOperationDetailsResponse.Merge(m, src) } func (m *GetClusterOperationDetailsResponse) XXX_Size() int { return xxx_messageInfo_GetClusterOperationDetailsResponse.Size(m) @@ -510,6 +526,8 @@ func (m *GetClusterOperationDetailsResponse) GetClusterOp() *ClusterOperation { } func init() { + proto.RegisterEnum("automation.ClusterOperationState", ClusterOperationState_name, ClusterOperationState_value) + proto.RegisterEnum("automation.TaskState", TaskState_name, TaskState_value) proto.RegisterType((*ClusterOperation)(nil), "automation.ClusterOperation") proto.RegisterType((*TaskContainer)(nil), "automation.TaskContainer") proto.RegisterType((*Task)(nil), "automation.Task") @@ -521,13 +539,11 @@ func init() { proto.RegisterType((*GetClusterOperationStateResponse)(nil), "automation.GetClusterOperationStateResponse") proto.RegisterType((*GetClusterOperationDetailsRequest)(nil), "automation.GetClusterOperationDetailsRequest") proto.RegisterType((*GetClusterOperationDetailsResponse)(nil), "automation.GetClusterOperationDetailsResponse") - proto.RegisterEnum("automation.ClusterOperationState", ClusterOperationState_name, ClusterOperationState_value) - proto.RegisterEnum("automation.TaskState", TaskState_name, TaskState_value) } -func init() { proto.RegisterFile("automation.proto", fileDescriptor_automation_4d7d55680fa173cc) } +func init() { proto.RegisterFile("automation.proto", fileDescriptor_06e15ad07c41cb38) } -var fileDescriptor_automation_4d7d55680fa173cc = []byte{ +var fileDescriptor_06e15ad07c41cb38 = []byte{ // 588 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x94, 0xdd, 0x6e, 0xd3, 0x3e, 0x18, 0xc6, 0xff, 0x49, 0xdb, 0xfd, 0xe9, 0x1b, 0xb6, 0x45, 0x16, 0x9b, 0xb2, 0x89, 0xb1, 0x2c, diff --git a/go/vt/proto/automationservice/automationservice.pb.go b/go/vt/proto/automationservice/automationservice.pb.go index 61ac349af85..bc2062f6620 100644 --- a/go/vt/proto/automationservice/automationservice.pb.go +++ b/go/vt/proto/automationservice/automationservice.pb.go @@ -1,16 +1,18 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // source: automationservice.proto -package automationservice // import "vitess.io/vitess/go/vt/proto/automationservice" - -import proto "github.com/golang/protobuf/proto" -import fmt "fmt" -import math "math" -import automation "vitess.io/vitess/go/vt/proto/automation" +package automationservice import ( - context "golang.org/x/net/context" + context "context" + fmt "fmt" + math "math" + + proto "github.com/golang/protobuf/proto" grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + automation "vitess.io/vitess/go/vt/proto/automation" ) // Reference imports to suppress errors if they are not otherwise used. @@ -22,7 +24,25 @@ var _ = math.Inf // is compatible with the proto package it is being compiled against. // A compilation error at this line likely means your copy of the // proto package needs to be updated. -const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package +const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package + +func init() { proto.RegisterFile("automationservice.proto", fileDescriptor_c03abdd2a71b5164) } + +var fileDescriptor_c03abdd2a71b5164 = []byte{ + // 178 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x12, 0x4f, 0x2c, 0x2d, 0xc9, + 0xcf, 0x4d, 0x2c, 0xc9, 0xcc, 0xcf, 0x2b, 0x4e, 0x2d, 0x2a, 0xcb, 0x4c, 0x4e, 0xd5, 0x2b, 0x28, + 0xca, 0x2f, 0xc9, 0x17, 0x12, 0xc4, 0x90, 0x90, 0x12, 0x40, 0x08, 0x41, 0x14, 0x19, 0x35, 0x32, + 0x71, 0x71, 0x39, 0xc2, 0x05, 0x85, 0x4a, 0xb8, 0xc4, 0x5d, 0xf3, 0x0a, 0x4b, 0x53, 0x4b, 0x53, + 0x9d, 0x73, 0x4a, 0x8b, 0x4b, 0x52, 0x8b, 0xfc, 0x0b, 0x52, 0x8b, 0x20, 0x52, 0x5a, 0x7a, 0x48, + 0x9a, 0x71, 0x28, 0x0a, 0x4a, 0x2d, 0x2c, 0x4d, 0x2d, 0x2e, 0x91, 0xd2, 0x26, 0x4a, 0x6d, 0x71, + 0x01, 0xc8, 0x65, 0x4a, 0x0c, 0x42, 0xb5, 0x5c, 0x52, 0xee, 0xa9, 0x25, 0xe8, 0x0a, 0x5c, 0x52, + 0x4b, 0x12, 0x33, 0x73, 0x8a, 0x85, 0x74, 0x91, 0x0d, 0xc3, 0xad, 0x0e, 0x66, 0xb7, 0x1e, 0xb1, + 0xca, 0x61, 0xd6, 0x3b, 0x19, 0x44, 0xe9, 0x95, 0x65, 0x96, 0xa4, 0x16, 0x17, 0xeb, 0x65, 0xe6, + 0xeb, 0x43, 0x58, 0xfa, 0xe9, 0xf9, 0xfa, 0x65, 0x25, 0xfa, 0xe0, 0x30, 0xd2, 0xc7, 0x08, 0xc7, + 0x24, 0x36, 0xb0, 0x84, 0x31, 0x20, 0x00, 0x00, 0xff, 0xff, 0x8f, 0x4a, 0x9d, 0xc0, 0x7c, 0x01, + 0x00, 0x00, +} // Reference imports to suppress errors if they are not otherwise used. var _ context.Context @@ -78,6 +98,17 @@ type AutomationServer interface { GetClusterOperationDetails(context.Context, *automation.GetClusterOperationDetailsRequest) (*automation.GetClusterOperationDetailsResponse, error) } +// UnimplementedAutomationServer can be embedded to have forward compatible implementations. +type UnimplementedAutomationServer struct { +} + +func (*UnimplementedAutomationServer) EnqueueClusterOperation(ctx context.Context, req *automation.EnqueueClusterOperationRequest) (*automation.EnqueueClusterOperationResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method EnqueueClusterOperation not implemented") +} +func (*UnimplementedAutomationServer) GetClusterOperationDetails(ctx context.Context, req *automation.GetClusterOperationDetailsRequest) (*automation.GetClusterOperationDetailsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetClusterOperationDetails not implemented") +} + func RegisterAutomationServer(s *grpc.Server, srv AutomationServer) { s.RegisterService(&_Automation_serviceDesc, srv) } @@ -134,23 +165,3 @@ var _Automation_serviceDesc = grpc.ServiceDesc{ Streams: []grpc.StreamDesc{}, Metadata: "automationservice.proto", } - -func init() { - proto.RegisterFile("automationservice.proto", fileDescriptor_automationservice_5369cb995212ce22) -} - -var fileDescriptor_automationservice_5369cb995212ce22 = []byte{ - // 178 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x12, 0x4f, 0x2c, 0x2d, 0xc9, - 0xcf, 0x4d, 0x2c, 0xc9, 0xcc, 0xcf, 0x2b, 0x4e, 0x2d, 0x2a, 0xcb, 0x4c, 0x4e, 0xd5, 0x2b, 0x28, - 0xca, 0x2f, 0xc9, 0x17, 0x12, 0xc4, 0x90, 0x90, 0x12, 0x40, 0x08, 0x41, 0x14, 0x19, 0x35, 0x32, - 0x71, 0x71, 0x39, 0xc2, 0x05, 0x85, 0x4a, 0xb8, 0xc4, 0x5d, 0xf3, 0x0a, 0x4b, 0x53, 0x4b, 0x53, - 0x9d, 0x73, 0x4a, 0x8b, 0x4b, 0x52, 0x8b, 0xfc, 0x0b, 0x52, 0x8b, 0x20, 0x52, 0x5a, 0x7a, 0x48, - 0x9a, 0x71, 0x28, 0x0a, 0x4a, 0x2d, 0x2c, 0x4d, 0x2d, 0x2e, 0x91, 0xd2, 0x26, 0x4a, 0x6d, 0x71, - 0x01, 0xc8, 0x65, 0x4a, 0x0c, 0x42, 0xb5, 0x5c, 0x52, 0xee, 0xa9, 0x25, 0xe8, 0x0a, 0x5c, 0x52, - 0x4b, 0x12, 0x33, 0x73, 0x8a, 0x85, 0x74, 0x91, 0x0d, 0xc3, 0xad, 0x0e, 0x66, 0xb7, 0x1e, 0xb1, - 0xca, 0x61, 0xd6, 0x3b, 0x19, 0x44, 0xe9, 0x95, 0x65, 0x96, 0xa4, 0x16, 0x17, 0xeb, 0x65, 0xe6, - 0xeb, 0x43, 0x58, 0xfa, 0xe9, 0xf9, 0xfa, 0x65, 0x25, 0xfa, 0xe0, 0x30, 0xd2, 0xc7, 0x08, 0xc7, - 0x24, 0x36, 0xb0, 0x84, 0x31, 0x20, 0x00, 0x00, 0xff, 0xff, 0x8f, 0x4a, 0x9d, 0xc0, 0x7c, 0x01, - 0x00, 0x00, -} diff --git a/go/vt/proto/binlogdata/binlogdata.pb.go b/go/vt/proto/binlogdata/binlogdata.pb.go index 24983945643..904d001d423 100644 --- a/go/vt/proto/binlogdata/binlogdata.pb.go +++ b/go/vt/proto/binlogdata/binlogdata.pb.go @@ -1,14 +1,17 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // source: binlogdata.proto -package binlogdata // import "vitess.io/vitess/go/vt/proto/binlogdata" +package binlogdata -import proto "github.com/golang/protobuf/proto" -import fmt "fmt" -import math "math" -import query "vitess.io/vitess/go/vt/proto/query" -import topodata "vitess.io/vitess/go/vt/proto/topodata" -import vtrpc "vitess.io/vitess/go/vt/proto/vtrpc" +import ( + fmt "fmt" + math "math" + + proto "github.com/golang/protobuf/proto" + query "vitess.io/vitess/go/vt/proto/query" + topodata "vitess.io/vitess/go/vt/proto/topodata" + vtrpc "vitess.io/vitess/go/vt/proto/vtrpc" +) // Reference imports to suppress errors if they are not otherwise used. var _ = proto.Marshal @@ -19,7 +22,7 @@ var _ = math.Inf // is compatible with the proto package it is being compiled against. // A compilation error at this line likely means your copy of the // proto package needs to be updated. -const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package +const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package // OnDDLAction lists the possible actions for DDLs. type OnDDLAction int32 @@ -37,6 +40,7 @@ var OnDDLAction_name = map[int32]string{ 2: "EXEC", 3: "EXEC_IGNORE", } + var OnDDLAction_value = map[string]int32{ "IGNORE": 0, "STOP": 1, @@ -47,8 +51,9 @@ var OnDDLAction_value = map[string]int32{ func (x OnDDLAction) String() string { return proto.EnumName(OnDDLAction_name, int32(x)) } + func (OnDDLAction) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_binlogdata_db2d20dd0016de21, []int{0} + return fileDescriptor_5fd02bcb2e350dad, []int{0} } // VEventType enumerates the event types. @@ -95,6 +100,7 @@ var VEventType_name = map[int32]string{ 15: "VGTID", 16: "JOURNAL", } + var VEventType_value = map[string]int32{ "UNKNOWN": 0, "GTID": 1, @@ -118,8 +124,9 @@ var VEventType_value = map[string]int32{ func (x VEventType) String() string { return proto.EnumName(VEventType_name, int32(x)) } + func (VEventType) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_binlogdata_db2d20dd0016de21, []int{1} + return fileDescriptor_5fd02bcb2e350dad, []int{1} } // MigrationType specifies the type of migration for the Journal. @@ -134,6 +141,7 @@ var MigrationType_name = map[int32]string{ 0: "TABLES", 1: "SHARDS", } + var MigrationType_value = map[string]int32{ "TABLES": 0, "SHARDS": 1, @@ -142,8 +150,9 @@ var MigrationType_value = map[string]int32{ func (x MigrationType) String() string { return proto.EnumName(MigrationType_name, int32(x)) } + func (MigrationType) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_binlogdata_db2d20dd0016de21, []int{2} + return fileDescriptor_5fd02bcb2e350dad, []int{2} } type BinlogTransaction_Statement_Category int32 @@ -174,6 +183,7 @@ var BinlogTransaction_Statement_Category_name = map[int32]string{ 8: "BL_UPDATE", 9: "BL_DELETE", } + var BinlogTransaction_Statement_Category_value = map[string]int32{ "BL_UNRECOGNIZED": 0, "BL_BEGIN": 1, @@ -190,8 +200,34 @@ var BinlogTransaction_Statement_Category_value = map[string]int32{ func (x BinlogTransaction_Statement_Category) String() string { return proto.EnumName(BinlogTransaction_Statement_Category_name, int32(x)) } + func (BinlogTransaction_Statement_Category) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_binlogdata_db2d20dd0016de21, []int{1, 0, 0} + return fileDescriptor_5fd02bcb2e350dad, []int{1, 0, 0} +} + +type Filter_FieldEventMode int32 + +const ( + Filter_ERR_ON_MISMATCH Filter_FieldEventMode = 0 + Filter_BEST_EFFORT Filter_FieldEventMode = 1 +) + +var Filter_FieldEventMode_name = map[int32]string{ + 0: "ERR_ON_MISMATCH", + 1: "BEST_EFFORT", +} + +var Filter_FieldEventMode_value = map[string]int32{ + "ERR_ON_MISMATCH": 0, + "BEST_EFFORT": 1, +} + +func (x Filter_FieldEventMode) String() string { + return proto.EnumName(Filter_FieldEventMode_name, int32(x)) +} + +func (Filter_FieldEventMode) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_5fd02bcb2e350dad, []int{7, 0} } // Charset is the per-statement charset info from a QUERY_EVENT binlog entry. @@ -211,16 +247,17 @@ func (m *Charset) Reset() { *m = Charset{} } func (m *Charset) String() string { return proto.CompactTextString(m) } func (*Charset) ProtoMessage() {} func (*Charset) Descriptor() ([]byte, []int) { - return fileDescriptor_binlogdata_db2d20dd0016de21, []int{0} + return fileDescriptor_5fd02bcb2e350dad, []int{0} } + func (m *Charset) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Charset.Unmarshal(m, b) } func (m *Charset) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_Charset.Marshal(b, m, deterministic) } -func (dst *Charset) XXX_Merge(src proto.Message) { - xxx_messageInfo_Charset.Merge(dst, src) +func (m *Charset) XXX_Merge(src proto.Message) { + xxx_messageInfo_Charset.Merge(m, src) } func (m *Charset) XXX_Size() int { return xxx_messageInfo_Charset.Size(m) @@ -268,16 +305,17 @@ func (m *BinlogTransaction) Reset() { *m = BinlogTransaction{} } func (m *BinlogTransaction) String() string { return proto.CompactTextString(m) } func (*BinlogTransaction) ProtoMessage() {} func (*BinlogTransaction) Descriptor() ([]byte, []int) { - return fileDescriptor_binlogdata_db2d20dd0016de21, []int{1} + return fileDescriptor_5fd02bcb2e350dad, []int{1} } + func (m *BinlogTransaction) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_BinlogTransaction.Unmarshal(m, b) } func (m *BinlogTransaction) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_BinlogTransaction.Marshal(b, m, deterministic) } -func (dst *BinlogTransaction) XXX_Merge(src proto.Message) { - xxx_messageInfo_BinlogTransaction.Merge(dst, src) +func (m *BinlogTransaction) XXX_Merge(src proto.Message) { + xxx_messageInfo_BinlogTransaction.Merge(m, src) } func (m *BinlogTransaction) XXX_Size() int { return xxx_messageInfo_BinlogTransaction.Size(m) @@ -318,16 +356,17 @@ func (m *BinlogTransaction_Statement) Reset() { *m = BinlogTransaction_S func (m *BinlogTransaction_Statement) String() string { return proto.CompactTextString(m) } func (*BinlogTransaction_Statement) ProtoMessage() {} func (*BinlogTransaction_Statement) Descriptor() ([]byte, []int) { - return fileDescriptor_binlogdata_db2d20dd0016de21, []int{1, 0} + return fileDescriptor_5fd02bcb2e350dad, []int{1, 0} } + func (m *BinlogTransaction_Statement) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_BinlogTransaction_Statement.Unmarshal(m, b) } func (m *BinlogTransaction_Statement) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_BinlogTransaction_Statement.Marshal(b, m, deterministic) } -func (dst *BinlogTransaction_Statement) XXX_Merge(src proto.Message) { - xxx_messageInfo_BinlogTransaction_Statement.Merge(dst, src) +func (m *BinlogTransaction_Statement) XXX_Merge(src proto.Message) { + xxx_messageInfo_BinlogTransaction_Statement.Merge(m, src) } func (m *BinlogTransaction_Statement) XXX_Size() int { return xxx_messageInfo_BinlogTransaction_Statement.Size(m) @@ -376,16 +415,17 @@ func (m *StreamKeyRangeRequest) Reset() { *m = StreamKeyRangeRequest{} } func (m *StreamKeyRangeRequest) String() string { return proto.CompactTextString(m) } func (*StreamKeyRangeRequest) ProtoMessage() {} func (*StreamKeyRangeRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_binlogdata_db2d20dd0016de21, []int{2} + return fileDescriptor_5fd02bcb2e350dad, []int{2} } + func (m *StreamKeyRangeRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_StreamKeyRangeRequest.Unmarshal(m, b) } func (m *StreamKeyRangeRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_StreamKeyRangeRequest.Marshal(b, m, deterministic) } -func (dst *StreamKeyRangeRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_StreamKeyRangeRequest.Merge(dst, src) +func (m *StreamKeyRangeRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_StreamKeyRangeRequest.Merge(m, src) } func (m *StreamKeyRangeRequest) XXX_Size() int { return xxx_messageInfo_StreamKeyRangeRequest.Size(m) @@ -429,16 +469,17 @@ func (m *StreamKeyRangeResponse) Reset() { *m = StreamKeyRangeResponse{} func (m *StreamKeyRangeResponse) String() string { return proto.CompactTextString(m) } func (*StreamKeyRangeResponse) ProtoMessage() {} func (*StreamKeyRangeResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_binlogdata_db2d20dd0016de21, []int{3} + return fileDescriptor_5fd02bcb2e350dad, []int{3} } + func (m *StreamKeyRangeResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_StreamKeyRangeResponse.Unmarshal(m, b) } func (m *StreamKeyRangeResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_StreamKeyRangeResponse.Marshal(b, m, deterministic) } -func (dst *StreamKeyRangeResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_StreamKeyRangeResponse.Merge(dst, src) +func (m *StreamKeyRangeResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_StreamKeyRangeResponse.Merge(m, src) } func (m *StreamKeyRangeResponse) XXX_Size() int { return xxx_messageInfo_StreamKeyRangeResponse.Size(m) @@ -473,16 +514,17 @@ func (m *StreamTablesRequest) Reset() { *m = StreamTablesRequest{} } func (m *StreamTablesRequest) String() string { return proto.CompactTextString(m) } func (*StreamTablesRequest) ProtoMessage() {} func (*StreamTablesRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_binlogdata_db2d20dd0016de21, []int{4} + return fileDescriptor_5fd02bcb2e350dad, []int{4} } + func (m *StreamTablesRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_StreamTablesRequest.Unmarshal(m, b) } func (m *StreamTablesRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_StreamTablesRequest.Marshal(b, m, deterministic) } -func (dst *StreamTablesRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_StreamTablesRequest.Merge(dst, src) +func (m *StreamTablesRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_StreamTablesRequest.Merge(m, src) } func (m *StreamTablesRequest) XXX_Size() int { return xxx_messageInfo_StreamTablesRequest.Size(m) @@ -526,16 +568,17 @@ func (m *StreamTablesResponse) Reset() { *m = StreamTablesResponse{} } func (m *StreamTablesResponse) String() string { return proto.CompactTextString(m) } func (*StreamTablesResponse) ProtoMessage() {} func (*StreamTablesResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_binlogdata_db2d20dd0016de21, []int{5} + return fileDescriptor_5fd02bcb2e350dad, []int{5} } + func (m *StreamTablesResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_StreamTablesResponse.Unmarshal(m, b) } func (m *StreamTablesResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_StreamTablesResponse.Marshal(b, m, deterministic) } -func (dst *StreamTablesResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_StreamTablesResponse.Merge(dst, src) +func (m *StreamTablesResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_StreamTablesResponse.Merge(m, src) } func (m *StreamTablesResponse) XXX_Size() int { return xxx_messageInfo_StreamTablesResponse.Size(m) @@ -571,16 +614,17 @@ func (m *Rule) Reset() { *m = Rule{} } func (m *Rule) String() string { return proto.CompactTextString(m) } func (*Rule) ProtoMessage() {} func (*Rule) Descriptor() ([]byte, []int) { - return fileDescriptor_binlogdata_db2d20dd0016de21, []int{6} + return fileDescriptor_5fd02bcb2e350dad, []int{6} } + func (m *Rule) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Rule.Unmarshal(m, b) } func (m *Rule) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_Rule.Marshal(b, m, deterministic) } -func (dst *Rule) XXX_Merge(src proto.Message) { - xxx_messageInfo_Rule.Merge(dst, src) +func (m *Rule) XXX_Merge(src proto.Message) { + xxx_messageInfo_Rule.Merge(m, src) } func (m *Rule) XXX_Size() int { return xxx_messageInfo_Rule.Size(m) @@ -608,26 +652,28 @@ func (m *Rule) GetFilter() string { // Filter represents a list of ordered rules. First match // wins. type Filter struct { - Rules []*Rule `protobuf:"bytes,1,rep,name=rules,proto3" json:"rules,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + Rules []*Rule `protobuf:"bytes,1,rep,name=rules,proto3" json:"rules,omitempty"` + FieldEventMode Filter_FieldEventMode `protobuf:"varint,2,opt,name=fieldEventMode,proto3,enum=binlogdata.Filter_FieldEventMode" json:"fieldEventMode,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *Filter) Reset() { *m = Filter{} } func (m *Filter) String() string { return proto.CompactTextString(m) } func (*Filter) ProtoMessage() {} func (*Filter) Descriptor() ([]byte, []int) { - return fileDescriptor_binlogdata_db2d20dd0016de21, []int{7} + return fileDescriptor_5fd02bcb2e350dad, []int{7} } + func (m *Filter) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Filter.Unmarshal(m, b) } func (m *Filter) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_Filter.Marshal(b, m, deterministic) } -func (dst *Filter) XXX_Merge(src proto.Message) { - xxx_messageInfo_Filter.Merge(dst, src) +func (m *Filter) XXX_Merge(src proto.Message) { + xxx_messageInfo_Filter.Merge(m, src) } func (m *Filter) XXX_Size() int { return xxx_messageInfo_Filter.Size(m) @@ -645,6 +691,13 @@ func (m *Filter) GetRules() []*Rule { return nil } +func (m *Filter) GetFieldEventMode() Filter_FieldEventMode { + if m != nil { + return m.FieldEventMode + } + return Filter_ERR_ON_MISMATCH +} + // BinlogSource specifies the source and filter parameters for // Filtered Replication. It currently supports a keyrange // or a list of tables. @@ -673,16 +726,17 @@ func (m *BinlogSource) Reset() { *m = BinlogSource{} } func (m *BinlogSource) String() string { return proto.CompactTextString(m) } func (*BinlogSource) ProtoMessage() {} func (*BinlogSource) Descriptor() ([]byte, []int) { - return fileDescriptor_binlogdata_db2d20dd0016de21, []int{8} + return fileDescriptor_5fd02bcb2e350dad, []int{8} } + func (m *BinlogSource) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_BinlogSource.Unmarshal(m, b) } func (m *BinlogSource) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_BinlogSource.Marshal(b, m, deterministic) } -func (dst *BinlogSource) XXX_Merge(src proto.Message) { - xxx_messageInfo_BinlogSource.Merge(dst, src) +func (m *BinlogSource) XXX_Merge(src proto.Message) { + xxx_messageInfo_BinlogSource.Merge(m, src) } func (m *BinlogSource) XXX_Size() int { return xxx_messageInfo_BinlogSource.Size(m) @@ -755,16 +809,17 @@ func (m *RowChange) Reset() { *m = RowChange{} } func (m *RowChange) String() string { return proto.CompactTextString(m) } func (*RowChange) ProtoMessage() {} func (*RowChange) Descriptor() ([]byte, []int) { - return fileDescriptor_binlogdata_db2d20dd0016de21, []int{9} + return fileDescriptor_5fd02bcb2e350dad, []int{9} } + func (m *RowChange) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_RowChange.Unmarshal(m, b) } func (m *RowChange) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_RowChange.Marshal(b, m, deterministic) } -func (dst *RowChange) XXX_Merge(src proto.Message) { - xxx_messageInfo_RowChange.Merge(dst, src) +func (m *RowChange) XXX_Merge(src proto.Message) { + xxx_messageInfo_RowChange.Merge(m, src) } func (m *RowChange) XXX_Size() int { return xxx_messageInfo_RowChange.Size(m) @@ -802,16 +857,17 @@ func (m *RowEvent) Reset() { *m = RowEvent{} } func (m *RowEvent) String() string { return proto.CompactTextString(m) } func (*RowEvent) ProtoMessage() {} func (*RowEvent) Descriptor() ([]byte, []int) { - return fileDescriptor_binlogdata_db2d20dd0016de21, []int{10} + return fileDescriptor_5fd02bcb2e350dad, []int{10} } + func (m *RowEvent) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_RowEvent.Unmarshal(m, b) } func (m *RowEvent) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_RowEvent.Marshal(b, m, deterministic) } -func (dst *RowEvent) XXX_Merge(src proto.Message) { - xxx_messageInfo_RowEvent.Merge(dst, src) +func (m *RowEvent) XXX_Merge(src proto.Message) { + xxx_messageInfo_RowEvent.Merge(m, src) } func (m *RowEvent) XXX_Size() int { return xxx_messageInfo_RowEvent.Size(m) @@ -848,16 +904,17 @@ func (m *FieldEvent) Reset() { *m = FieldEvent{} } func (m *FieldEvent) String() string { return proto.CompactTextString(m) } func (*FieldEvent) ProtoMessage() {} func (*FieldEvent) Descriptor() ([]byte, []int) { - return fileDescriptor_binlogdata_db2d20dd0016de21, []int{11} + return fileDescriptor_5fd02bcb2e350dad, []int{11} } + func (m *FieldEvent) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_FieldEvent.Unmarshal(m, b) } func (m *FieldEvent) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_FieldEvent.Marshal(b, m, deterministic) } -func (dst *FieldEvent) XXX_Merge(src proto.Message) { - xxx_messageInfo_FieldEvent.Merge(dst, src) +func (m *FieldEvent) XXX_Merge(src proto.Message) { + xxx_messageInfo_FieldEvent.Merge(m, src) } func (m *FieldEvent) XXX_Size() int { return xxx_messageInfo_FieldEvent.Size(m) @@ -895,16 +952,17 @@ func (m *ShardGtid) Reset() { *m = ShardGtid{} } func (m *ShardGtid) String() string { return proto.CompactTextString(m) } func (*ShardGtid) ProtoMessage() {} func (*ShardGtid) Descriptor() ([]byte, []int) { - return fileDescriptor_binlogdata_db2d20dd0016de21, []int{12} + return fileDescriptor_5fd02bcb2e350dad, []int{12} } + func (m *ShardGtid) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ShardGtid.Unmarshal(m, b) } func (m *ShardGtid) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_ShardGtid.Marshal(b, m, deterministic) } -func (dst *ShardGtid) XXX_Merge(src proto.Message) { - xxx_messageInfo_ShardGtid.Merge(dst, src) +func (m *ShardGtid) XXX_Merge(src proto.Message) { + xxx_messageInfo_ShardGtid.Merge(m, src) } func (m *ShardGtid) XXX_Size() int { return xxx_messageInfo_ShardGtid.Size(m) @@ -947,16 +1005,17 @@ func (m *VGtid) Reset() { *m = VGtid{} } func (m *VGtid) String() string { return proto.CompactTextString(m) } func (*VGtid) ProtoMessage() {} func (*VGtid) Descriptor() ([]byte, []int) { - return fileDescriptor_binlogdata_db2d20dd0016de21, []int{13} + return fileDescriptor_5fd02bcb2e350dad, []int{13} } + func (m *VGtid) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_VGtid.Unmarshal(m, b) } func (m *VGtid) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_VGtid.Marshal(b, m, deterministic) } -func (dst *VGtid) XXX_Merge(src proto.Message) { - xxx_messageInfo_VGtid.Merge(dst, src) +func (m *VGtid) XXX_Merge(src proto.Message) { + xxx_messageInfo_VGtid.Merge(m, src) } func (m *VGtid) XXX_Size() int { return xxx_messageInfo_VGtid.Size(m) @@ -986,16 +1045,17 @@ func (m *KeyspaceShard) Reset() { *m = KeyspaceShard{} } func (m *KeyspaceShard) String() string { return proto.CompactTextString(m) } func (*KeyspaceShard) ProtoMessage() {} func (*KeyspaceShard) Descriptor() ([]byte, []int) { - return fileDescriptor_binlogdata_db2d20dd0016de21, []int{14} + return fileDescriptor_5fd02bcb2e350dad, []int{14} } + func (m *KeyspaceShard) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_KeyspaceShard.Unmarshal(m, b) } func (m *KeyspaceShard) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_KeyspaceShard.Marshal(b, m, deterministic) } -func (dst *KeyspaceShard) XXX_Merge(src proto.Message) { - xxx_messageInfo_KeyspaceShard.Merge(dst, src) +func (m *KeyspaceShard) XXX_Merge(src proto.Message) { + xxx_messageInfo_KeyspaceShard.Merge(m, src) } func (m *KeyspaceShard) XXX_Size() int { return xxx_messageInfo_KeyspaceShard.Size(m) @@ -1027,7 +1087,7 @@ type Journal struct { LocalPosition string `protobuf:"bytes,4,opt,name=local_position,json=localPosition,proto3" json:"local_position,omitempty"` ShardGtids []*ShardGtid `protobuf:"bytes,5,rep,name=shard_gtids,json=shardGtids,proto3" json:"shard_gtids,omitempty"` Participants []*KeyspaceShard `protobuf:"bytes,6,rep,name=participants,proto3" json:"participants,omitempty"` - ReversedIds []int64 `protobuf:"varint,7,rep,packed,name=reversed_ids,json=reversedIds,proto3" json:"reversed_ids,omitempty"` + SourceWorkflows []string `protobuf:"bytes,7,rep,name=source_workflows,json=sourceWorkflows,proto3" json:"source_workflows,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -1037,16 +1097,17 @@ func (m *Journal) Reset() { *m = Journal{} } func (m *Journal) String() string { return proto.CompactTextString(m) } func (*Journal) ProtoMessage() {} func (*Journal) Descriptor() ([]byte, []int) { - return fileDescriptor_binlogdata_db2d20dd0016de21, []int{15} + return fileDescriptor_5fd02bcb2e350dad, []int{15} } + func (m *Journal) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Journal.Unmarshal(m, b) } func (m *Journal) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_Journal.Marshal(b, m, deterministic) } -func (dst *Journal) XXX_Merge(src proto.Message) { - xxx_messageInfo_Journal.Merge(dst, src) +func (m *Journal) XXX_Merge(src proto.Message) { + xxx_messageInfo_Journal.Merge(m, src) } func (m *Journal) XXX_Size() int { return xxx_messageInfo_Journal.Size(m) @@ -1099,9 +1160,9 @@ func (m *Journal) GetParticipants() []*KeyspaceShard { return nil } -func (m *Journal) GetReversedIds() []int64 { +func (m *Journal) GetSourceWorkflows() []string { if m != nil { - return m.ReversedIds + return m.SourceWorkflows } return nil } @@ -1127,16 +1188,17 @@ func (m *VEvent) Reset() { *m = VEvent{} } func (m *VEvent) String() string { return proto.CompactTextString(m) } func (*VEvent) ProtoMessage() {} func (*VEvent) Descriptor() ([]byte, []int) { - return fileDescriptor_binlogdata_db2d20dd0016de21, []int{16} + return fileDescriptor_5fd02bcb2e350dad, []int{16} } + func (m *VEvent) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_VEvent.Unmarshal(m, b) } func (m *VEvent) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_VEvent.Marshal(b, m, deterministic) } -func (dst *VEvent) XXX_Merge(src proto.Message) { - xxx_messageInfo_VEvent.Merge(dst, src) +func (m *VEvent) XXX_Merge(src proto.Message) { + xxx_messageInfo_VEvent.Merge(m, src) } func (m *VEvent) XXX_Size() int { return xxx_messageInfo_VEvent.Size(m) @@ -1226,16 +1288,17 @@ func (m *VStreamRequest) Reset() { *m = VStreamRequest{} } func (m *VStreamRequest) String() string { return proto.CompactTextString(m) } func (*VStreamRequest) ProtoMessage() {} func (*VStreamRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_binlogdata_db2d20dd0016de21, []int{17} + return fileDescriptor_5fd02bcb2e350dad, []int{17} } + func (m *VStreamRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_VStreamRequest.Unmarshal(m, b) } func (m *VStreamRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_VStreamRequest.Marshal(b, m, deterministic) } -func (dst *VStreamRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_VStreamRequest.Merge(dst, src) +func (m *VStreamRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_VStreamRequest.Merge(m, src) } func (m *VStreamRequest) XXX_Size() int { return xxx_messageInfo_VStreamRequest.Size(m) @@ -1293,16 +1356,17 @@ func (m *VStreamResponse) Reset() { *m = VStreamResponse{} } func (m *VStreamResponse) String() string { return proto.CompactTextString(m) } func (*VStreamResponse) ProtoMessage() {} func (*VStreamResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_binlogdata_db2d20dd0016de21, []int{18} + return fileDescriptor_5fd02bcb2e350dad, []int{18} } + func (m *VStreamResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_VStreamResponse.Unmarshal(m, b) } func (m *VStreamResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_VStreamResponse.Marshal(b, m, deterministic) } -func (dst *VStreamResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_VStreamResponse.Merge(dst, src) +func (m *VStreamResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_VStreamResponse.Merge(m, src) } func (m *VStreamResponse) XXX_Size() int { return xxx_messageInfo_VStreamResponse.Size(m) @@ -1336,16 +1400,17 @@ func (m *VStreamRowsRequest) Reset() { *m = VStreamRowsRequest{} } func (m *VStreamRowsRequest) String() string { return proto.CompactTextString(m) } func (*VStreamRowsRequest) ProtoMessage() {} func (*VStreamRowsRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_binlogdata_db2d20dd0016de21, []int{19} + return fileDescriptor_5fd02bcb2e350dad, []int{19} } + func (m *VStreamRowsRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_VStreamRowsRequest.Unmarshal(m, b) } func (m *VStreamRowsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_VStreamRowsRequest.Marshal(b, m, deterministic) } -func (dst *VStreamRowsRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_VStreamRowsRequest.Merge(dst, src) +func (m *VStreamRowsRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_VStreamRowsRequest.Merge(m, src) } func (m *VStreamRowsRequest) XXX_Size() int { return xxx_messageInfo_VStreamRowsRequest.Size(m) @@ -1407,16 +1472,17 @@ func (m *VStreamRowsResponse) Reset() { *m = VStreamRowsResponse{} } func (m *VStreamRowsResponse) String() string { return proto.CompactTextString(m) } func (*VStreamRowsResponse) ProtoMessage() {} func (*VStreamRowsResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_binlogdata_db2d20dd0016de21, []int{20} + return fileDescriptor_5fd02bcb2e350dad, []int{20} } + func (m *VStreamRowsResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_VStreamRowsResponse.Unmarshal(m, b) } func (m *VStreamRowsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_VStreamRowsResponse.Marshal(b, m, deterministic) } -func (dst *VStreamRowsResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_VStreamRowsResponse.Merge(dst, src) +func (m *VStreamRowsResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_VStreamRowsResponse.Merge(m, src) } func (m *VStreamRowsResponse) XXX_Size() int { return xxx_messageInfo_VStreamRowsResponse.Size(m) @@ -1462,7 +1528,134 @@ func (m *VStreamRowsResponse) GetLastpk() *query.Row { return nil } +// VStreamResultsRequest is the payload for VStreamResults +// The ids match VStreamRows, in case we decide to merge the two. +type VStreamResultsRequest struct { + EffectiveCallerId *vtrpc.CallerID `protobuf:"bytes,1,opt,name=effective_caller_id,json=effectiveCallerId,proto3" json:"effective_caller_id,omitempty"` + ImmediateCallerId *query.VTGateCallerID `protobuf:"bytes,2,opt,name=immediate_caller_id,json=immediateCallerId,proto3" json:"immediate_caller_id,omitempty"` + Target *query.Target `protobuf:"bytes,3,opt,name=target,proto3" json:"target,omitempty"` + Query string `protobuf:"bytes,4,opt,name=query,proto3" json:"query,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *VStreamResultsRequest) Reset() { *m = VStreamResultsRequest{} } +func (m *VStreamResultsRequest) String() string { return proto.CompactTextString(m) } +func (*VStreamResultsRequest) ProtoMessage() {} +func (*VStreamResultsRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_5fd02bcb2e350dad, []int{21} +} + +func (m *VStreamResultsRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_VStreamResultsRequest.Unmarshal(m, b) +} +func (m *VStreamResultsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_VStreamResultsRequest.Marshal(b, m, deterministic) +} +func (m *VStreamResultsRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_VStreamResultsRequest.Merge(m, src) +} +func (m *VStreamResultsRequest) XXX_Size() int { + return xxx_messageInfo_VStreamResultsRequest.Size(m) +} +func (m *VStreamResultsRequest) XXX_DiscardUnknown() { + xxx_messageInfo_VStreamResultsRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_VStreamResultsRequest proto.InternalMessageInfo + +func (m *VStreamResultsRequest) GetEffectiveCallerId() *vtrpc.CallerID { + if m != nil { + return m.EffectiveCallerId + } + return nil +} + +func (m *VStreamResultsRequest) GetImmediateCallerId() *query.VTGateCallerID { + if m != nil { + return m.ImmediateCallerId + } + return nil +} + +func (m *VStreamResultsRequest) GetTarget() *query.Target { + if m != nil { + return m.Target + } + return nil +} + +func (m *VStreamResultsRequest) GetQuery() string { + if m != nil { + return m.Query + } + return "" +} + +// VStreamResultsResponse is the response from VStreamResults +// The ids match VStreamRows, in case we decide to merge the two. +type VStreamResultsResponse struct { + Fields []*query.Field `protobuf:"bytes,1,rep,name=fields,proto3" json:"fields,omitempty"` + Gtid string `protobuf:"bytes,3,opt,name=gtid,proto3" json:"gtid,omitempty"` + Rows []*query.Row `protobuf:"bytes,4,rep,name=rows,proto3" json:"rows,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *VStreamResultsResponse) Reset() { *m = VStreamResultsResponse{} } +func (m *VStreamResultsResponse) String() string { return proto.CompactTextString(m) } +func (*VStreamResultsResponse) ProtoMessage() {} +func (*VStreamResultsResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_5fd02bcb2e350dad, []int{22} +} + +func (m *VStreamResultsResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_VStreamResultsResponse.Unmarshal(m, b) +} +func (m *VStreamResultsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_VStreamResultsResponse.Marshal(b, m, deterministic) +} +func (m *VStreamResultsResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_VStreamResultsResponse.Merge(m, src) +} +func (m *VStreamResultsResponse) XXX_Size() int { + return xxx_messageInfo_VStreamResultsResponse.Size(m) +} +func (m *VStreamResultsResponse) XXX_DiscardUnknown() { + xxx_messageInfo_VStreamResultsResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_VStreamResultsResponse proto.InternalMessageInfo + +func (m *VStreamResultsResponse) GetFields() []*query.Field { + if m != nil { + return m.Fields + } + return nil +} + +func (m *VStreamResultsResponse) GetGtid() string { + if m != nil { + return m.Gtid + } + return "" +} + +func (m *VStreamResultsResponse) GetRows() []*query.Row { + if m != nil { + return m.Rows + } + return nil +} + func init() { + proto.RegisterEnum("binlogdata.OnDDLAction", OnDDLAction_name, OnDDLAction_value) + proto.RegisterEnum("binlogdata.VEventType", VEventType_name, VEventType_value) + proto.RegisterEnum("binlogdata.MigrationType", MigrationType_name, MigrationType_value) + proto.RegisterEnum("binlogdata.BinlogTransaction_Statement_Category", BinlogTransaction_Statement_Category_name, BinlogTransaction_Statement_Category_value) + proto.RegisterEnum("binlogdata.Filter_FieldEventMode", Filter_FieldEventMode_name, Filter_FieldEventMode_value) proto.RegisterType((*Charset)(nil), "binlogdata.Charset") proto.RegisterType((*BinlogTransaction)(nil), "binlogdata.BinlogTransaction") proto.RegisterType((*BinlogTransaction_Statement)(nil), "binlogdata.BinlogTransaction.Statement") @@ -1485,112 +1678,115 @@ func init() { proto.RegisterType((*VStreamResponse)(nil), "binlogdata.VStreamResponse") proto.RegisterType((*VStreamRowsRequest)(nil), "binlogdata.VStreamRowsRequest") proto.RegisterType((*VStreamRowsResponse)(nil), "binlogdata.VStreamRowsResponse") - proto.RegisterEnum("binlogdata.OnDDLAction", OnDDLAction_name, OnDDLAction_value) - proto.RegisterEnum("binlogdata.VEventType", VEventType_name, VEventType_value) - proto.RegisterEnum("binlogdata.MigrationType", MigrationType_name, MigrationType_value) - proto.RegisterEnum("binlogdata.BinlogTransaction_Statement_Category", BinlogTransaction_Statement_Category_name, BinlogTransaction_Statement_Category_value) -} - -func init() { proto.RegisterFile("binlogdata.proto", fileDescriptor_binlogdata_db2d20dd0016de21) } - -var fileDescriptor_binlogdata_db2d20dd0016de21 = []byte{ - // 1558 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x57, 0xcb, 0x72, 0xdb, 0xca, - 0x11, 0x35, 0x09, 0xf0, 0xd5, 0x90, 0x28, 0x68, 0xf4, 0x08, 0xa3, 0x8a, 0x53, 0x0a, 0x2a, 0x8e, - 0x14, 0x55, 0x85, 0x72, 0x98, 0xc4, 0x59, 0x39, 0x0e, 0x1f, 0xb0, 0x4c, 0x09, 0x22, 0xe5, 0x21, - 0x24, 0xa7, 0xbc, 0x41, 0x41, 0xc4, 0x48, 0x42, 0x04, 0x02, 0x34, 0x30, 0xa4, 0xa2, 0x0f, 0x48, - 0xe5, 0x03, 0xb2, 0xcd, 0x0f, 0x64, 0x9f, 0x6d, 0xb6, 0xd9, 0xe7, 0x0b, 0xb2, 0xca, 0x7f, 0xdc, - 0x9a, 0x07, 0x40, 0x42, 0xf6, 0xb5, 0xe5, 0x5b, 0x75, 0x17, 0x77, 0xc3, 0xea, 0xe9, 0xe9, 0xe7, - 0x41, 0x4f, 0x77, 0x13, 0xf4, 0x4b, 0x3f, 0x0c, 0xa2, 0x6b, 0xcf, 0xa5, 0x6e, 0x73, 0x1a, 0x47, - 0x34, 0x42, 0xb0, 0xe0, 0xec, 0x68, 0x73, 0x1a, 0x4f, 0xc7, 0xe2, 0x62, 0x47, 0xfb, 0x30, 0x23, - 0xf1, 0xbd, 0x3c, 0xd4, 0x69, 0x34, 0x8d, 0x16, 0x5a, 0xc6, 0x29, 0x54, 0xba, 0x37, 0x6e, 0x9c, - 0x10, 0x8a, 0xb6, 0xa1, 0x3c, 0x0e, 0x7c, 0x12, 0xd2, 0x46, 0x61, 0xb7, 0xb0, 0x5f, 0xc2, 0xf2, - 0x84, 0x10, 0xa8, 0xe3, 0x28, 0x0c, 0x1b, 0x45, 0xce, 0xe5, 0x34, 0x93, 0x4d, 0x48, 0x3c, 0x27, - 0x71, 0x43, 0x11, 0xb2, 0xe2, 0x64, 0xfc, 0x5f, 0x81, 0xf5, 0x0e, 0x8f, 0xc3, 0x8e, 0xdd, 0x30, - 0x71, 0xc7, 0xd4, 0x8f, 0x42, 0x74, 0x04, 0x90, 0x50, 0x97, 0x92, 0x09, 0x09, 0x69, 0xd2, 0x28, - 0xec, 0x2a, 0xfb, 0x5a, 0x6b, 0xaf, 0xb9, 0x94, 0xc1, 0x47, 0x2a, 0xcd, 0x51, 0x2a, 0x8f, 0x97, - 0x54, 0x51, 0x0b, 0x34, 0x32, 0x27, 0x21, 0x75, 0x68, 0x74, 0x4b, 0xc2, 0x86, 0xba, 0x5b, 0xd8, - 0xd7, 0x5a, 0xeb, 0x4d, 0x91, 0xa0, 0xc9, 0x6e, 0x6c, 0x76, 0x81, 0x81, 0x64, 0xf4, 0xce, 0x7f, - 0x8a, 0x50, 0xcb, 0xac, 0x21, 0x0b, 0xaa, 0x63, 0x97, 0x92, 0xeb, 0x28, 0xbe, 0xe7, 0x69, 0xd6, - 0x5b, 0xcf, 0x1f, 0x19, 0x48, 0xb3, 0x2b, 0xf5, 0x70, 0x66, 0x01, 0xfd, 0x0a, 0x2a, 0x63, 0x81, - 0x1e, 0x47, 0x47, 0x6b, 0x6d, 0x2c, 0x1b, 0x93, 0xc0, 0xe2, 0x54, 0x06, 0xe9, 0xa0, 0x24, 0x1f, - 0x02, 0x0e, 0xd9, 0x0a, 0x66, 0xa4, 0xf1, 0xcf, 0x02, 0x54, 0x53, 0xbb, 0x68, 0x03, 0xd6, 0x3a, - 0x96, 0x73, 0x3e, 0xc0, 0x66, 0x77, 0x78, 0x34, 0xe8, 0xbf, 0x37, 0x7b, 0xfa, 0x13, 0xb4, 0x02, - 0xd5, 0x8e, 0xe5, 0x74, 0xcc, 0xa3, 0xfe, 0x40, 0x2f, 0xa0, 0x55, 0xa8, 0x75, 0x2c, 0xa7, 0x3b, - 0x3c, 0x3d, 0xed, 0xdb, 0x7a, 0x11, 0xad, 0x81, 0xd6, 0xb1, 0x1c, 0x3c, 0xb4, 0xac, 0x4e, 0xbb, - 0x7b, 0xa2, 0x2b, 0x68, 0x0b, 0xd6, 0x3b, 0x96, 0xd3, 0x3b, 0xb5, 0x9c, 0x9e, 0x79, 0x86, 0xcd, - 0x6e, 0xdb, 0x36, 0x7b, 0xba, 0x8a, 0x00, 0xca, 0x8c, 0xdd, 0xb3, 0xf4, 0x92, 0xa4, 0x47, 0xa6, - 0xad, 0x97, 0xa5, 0xb9, 0xfe, 0x60, 0x64, 0x62, 0x5b, 0xaf, 0xc8, 0xe3, 0xf9, 0x59, 0xaf, 0x6d, - 0x9b, 0x7a, 0x55, 0x1e, 0x7b, 0xa6, 0x65, 0xda, 0xa6, 0x5e, 0x3b, 0x56, 0xab, 0x45, 0x5d, 0x39, - 0x56, 0xab, 0x8a, 0xae, 0x1a, 0x7f, 0x2f, 0xc0, 0xd6, 0x88, 0xc6, 0xc4, 0x9d, 0x9c, 0x90, 0x7b, - 0xec, 0x86, 0xd7, 0x04, 0x93, 0x0f, 0x33, 0x92, 0x50, 0xb4, 0x03, 0xd5, 0x69, 0x94, 0xf8, 0x0c, - 0x3b, 0x0e, 0x70, 0x0d, 0x67, 0x67, 0x74, 0x08, 0xb5, 0x5b, 0x72, 0xef, 0xc4, 0x4c, 0x5e, 0x02, - 0x86, 0x9a, 0x59, 0x41, 0x66, 0x96, 0xaa, 0xb7, 0x92, 0x5a, 0xc6, 0x57, 0xf9, 0x32, 0xbe, 0xc6, - 0x15, 0x6c, 0x3f, 0x0c, 0x2a, 0x99, 0x46, 0x61, 0x42, 0x90, 0x05, 0x48, 0x28, 0x3a, 0x74, 0xf1, - 0x6d, 0x79, 0x7c, 0x5a, 0xeb, 0xe9, 0x67, 0x0b, 0x00, 0xaf, 0x5f, 0x3e, 0x64, 0x19, 0x7f, 0x81, - 0x0d, 0xe1, 0xc7, 0x76, 0x2f, 0x03, 0x92, 0x3c, 0x26, 0xf5, 0x6d, 0x28, 0x53, 0x2e, 0xdc, 0x28, - 0xee, 0x2a, 0xfb, 0x35, 0x2c, 0x4f, 0x5f, 0x9b, 0xa1, 0x07, 0x9b, 0x79, 0xcf, 0xdf, 0x4b, 0x7e, - 0xbf, 0x05, 0x15, 0xcf, 0x02, 0x82, 0x36, 0xa1, 0x34, 0x71, 0xe9, 0xf8, 0x46, 0x66, 0x23, 0x0e, - 0x2c, 0x95, 0x2b, 0x3f, 0xa0, 0x24, 0xe6, 0x9f, 0xb0, 0x86, 0xe5, 0xc9, 0x78, 0x0e, 0xe5, 0xd7, - 0x9c, 0x42, 0xbf, 0x80, 0x52, 0x3c, 0x63, 0xb9, 0x8a, 0xa7, 0xae, 0x2f, 0x07, 0xc0, 0x0c, 0x63, - 0x71, 0x6d, 0xfc, 0xa3, 0x08, 0x2b, 0x22, 0xa0, 0x51, 0x34, 0x8b, 0xc7, 0x84, 0x21, 0x78, 0x4b, - 0xee, 0x93, 0xa9, 0x3b, 0x26, 0x29, 0x82, 0xe9, 0x99, 0x05, 0x93, 0xdc, 0xb8, 0xb1, 0x27, 0xbd, - 0x8a, 0x03, 0xfa, 0x1d, 0x68, 0x1c, 0x49, 0xea, 0xd0, 0xfb, 0x29, 0xe1, 0x18, 0xd6, 0x5b, 0x9b, - 0x8b, 0xa2, 0xe2, 0x38, 0x51, 0xfb, 0x7e, 0x4a, 0x30, 0xd0, 0x8c, 0xce, 0x57, 0xa2, 0xfa, 0x88, - 0x4a, 0x5c, 0x7c, 0xbf, 0x52, 0xee, 0xfb, 0x1d, 0x64, 0x60, 0x94, 0xa5, 0x95, 0xa5, 0x5c, 0x05, - 0x1c, 0x29, 0x40, 0xa8, 0x09, 0xe5, 0x28, 0x74, 0x3c, 0x2f, 0x68, 0x54, 0x78, 0x98, 0x3f, 0x5a, - 0x96, 0x1d, 0x86, 0xbd, 0x9e, 0xd5, 0x16, 0x9f, 0xa4, 0x14, 0x85, 0x3d, 0x2f, 0x30, 0xde, 0x42, - 0x0d, 0x47, 0x77, 0xdd, 0x1b, 0x1e, 0x80, 0x01, 0xe5, 0x4b, 0x72, 0x15, 0xc5, 0x44, 0x7e, 0x55, - 0x90, 0x5d, 0x0f, 0x47, 0x77, 0x58, 0xde, 0xa0, 0x5d, 0x28, 0xb9, 0x57, 0xe9, 0x87, 0xc9, 0x8b, - 0x88, 0x0b, 0xc3, 0x85, 0x2a, 0x8e, 0xee, 0x78, 0xa7, 0x44, 0x4f, 0x41, 0x20, 0xe2, 0x84, 0xee, - 0x24, 0x85, 0xbb, 0xc6, 0x39, 0x03, 0x77, 0x42, 0xd0, 0x0b, 0xd0, 0xe2, 0xe8, 0xce, 0x19, 0x73, - 0xf7, 0xa2, 0x6c, 0xb5, 0xd6, 0x56, 0xee, 0x53, 0xa6, 0xc1, 0x61, 0x88, 0x53, 0x32, 0x31, 0xde, - 0x02, 0xbc, 0xf6, 0x49, 0xe0, 0x3d, 0xca, 0xc9, 0xcf, 0x19, 0x7c, 0x24, 0xf0, 0x52, 0xfb, 0x2b, - 0x32, 0x64, 0x6e, 0x01, 0xcb, 0x3b, 0x06, 0xc4, 0x88, 0x7d, 0xed, 0x23, 0xea, 0x7b, 0xdf, 0xa1, - 0x46, 0x10, 0xa8, 0xd7, 0xd4, 0xf7, 0x78, 0x71, 0xd4, 0x30, 0xa7, 0x8d, 0x57, 0x50, 0xba, 0xe0, - 0xe6, 0x5e, 0x80, 0xc6, 0xa5, 0x1c, 0xc6, 0x4e, 0x2b, 0x36, 0x97, 0x66, 0xe6, 0x1a, 0x43, 0x92, - 0x92, 0x89, 0xd1, 0x86, 0xd5, 0x13, 0xe9, 0x96, 0x0b, 0x7c, 0x7d, 0x5c, 0xc6, 0xbf, 0x8a, 0x50, - 0x39, 0x8e, 0x66, 0x71, 0xe8, 0x06, 0xa8, 0x0e, 0x45, 0xdf, 0xe3, 0x7a, 0x0a, 0x2e, 0xfa, 0x1e, - 0xfa, 0x23, 0xd4, 0x27, 0xfe, 0x75, 0xec, 0xb2, 0x7a, 0x10, 0xa5, 0x5d, 0xe4, 0x35, 0xf3, 0xe3, - 0xe5, 0xc8, 0x4e, 0x53, 0x09, 0x5e, 0xdf, 0xab, 0x93, 0xe5, 0xe3, 0x52, 0xc5, 0x2a, 0xb9, 0x8a, - 0x7d, 0x06, 0xf5, 0x20, 0x1a, 0xbb, 0x81, 0x93, 0xf5, 0x2a, 0x95, 0x07, 0xb5, 0xca, 0xb9, 0x67, - 0x69, 0xc3, 0x7a, 0x80, 0x4b, 0xe9, 0x91, 0xb8, 0xa0, 0x97, 0xb0, 0x32, 0x75, 0x63, 0xea, 0x8f, - 0xfd, 0xa9, 0xcb, 0xa6, 0x7d, 0x99, 0x2b, 0xe6, 0xc2, 0xce, 0xe1, 0x86, 0x73, 0xe2, 0xe8, 0x67, - 0xb0, 0x12, 0x93, 0x39, 0x89, 0x13, 0xe2, 0x39, 0xcc, 0x6f, 0x65, 0x57, 0xd9, 0x57, 0xb0, 0x96, - 0xf2, 0xfa, 0x5e, 0x62, 0xfc, 0xaf, 0x08, 0xe5, 0x0b, 0x51, 0x5d, 0x07, 0xa0, 0x72, 0x6c, 0xc4, - 0x24, 0xdf, 0x5e, 0x76, 0x22, 0x24, 0x38, 0x30, 0x5c, 0x06, 0xfd, 0x04, 0x6a, 0xd4, 0x9f, 0x90, - 0x84, 0xba, 0x93, 0x29, 0x07, 0x53, 0xc1, 0x0b, 0xc6, 0xa7, 0x6a, 0x84, 0x8d, 0x6b, 0xf6, 0x58, - 0x05, 0x3c, 0x8c, 0x44, 0xbf, 0x86, 0x1a, 0x7b, 0x13, 0x7c, 0xbb, 0x68, 0x94, 0xf8, 0x23, 0xdb, - 0x7c, 0xf0, 0x22, 0xb8, 0x5b, 0x5c, 0x8d, 0xd3, 0x57, 0xf6, 0x7b, 0xd0, 0x78, 0x15, 0x4b, 0x25, - 0xd1, 0x25, 0xb6, 0xf3, 0x5d, 0x22, 0x7d, 0x2d, 0x18, 0xae, 0x16, 0x2f, 0x67, 0x0f, 0x4a, 0x73, - 0x1e, 0x52, 0x45, 0x6e, 0x39, 0xcb, 0xc9, 0x71, 0xd8, 0xc5, 0x3d, 0x1b, 0x21, 0x7f, 0x16, 0x55, - 0xd4, 0xa8, 0x7e, 0x3c, 0x42, 0x64, 0x81, 0xe1, 0x54, 0x86, 0x21, 0x3c, 0x9e, 0xc5, 0x31, 0xdf, - 0xa2, 0xfc, 0x09, 0x69, 0x6c, 0x72, 0x28, 0x34, 0xc9, 0xb3, 0xfd, 0x09, 0x31, 0xfe, 0x56, 0x84, - 0xfa, 0x85, 0x98, 0x33, 0xe9, 0x6c, 0x7b, 0x05, 0x1b, 0xe4, 0xea, 0x8a, 0x8c, 0xa9, 0x3f, 0x27, - 0xce, 0xd8, 0x0d, 0x02, 0x12, 0x3b, 0xb2, 0x60, 0xb5, 0xd6, 0x5a, 0x53, 0xec, 0x9b, 0x5d, 0xce, - 0xef, 0xf7, 0xf0, 0x7a, 0x26, 0x2b, 0x59, 0x1e, 0x32, 0x61, 0xc3, 0x9f, 0x4c, 0x88, 0xe7, 0xbb, - 0x74, 0xd9, 0x80, 0xe8, 0x54, 0x5b, 0xf2, 0xd9, 0x5f, 0xd8, 0x47, 0x2e, 0x25, 0x0b, 0x33, 0x99, - 0x46, 0x66, 0xe6, 0x19, 0xab, 0xea, 0xf8, 0x3a, 0x1b, 0x97, 0xab, 0x52, 0xd3, 0xe6, 0x4c, 0x2c, - 0x2f, 0x73, 0xa3, 0x58, 0x7d, 0x30, 0x8a, 0x17, 0x2d, 0xbb, 0xf4, 0xa5, 0x96, 0x6d, 0xbc, 0x84, - 0xb5, 0x0c, 0x08, 0x39, 0x6a, 0x0f, 0xa0, 0xcc, 0x3f, 0x65, 0xda, 0x2b, 0xd0, 0xc7, 0x55, 0x87, - 0xa5, 0x84, 0xf1, 0xd7, 0x22, 0xa0, 0x54, 0x3f, 0xba, 0x4b, 0x7e, 0xa0, 0x60, 0x6e, 0x42, 0x89, - 0xf3, 0x25, 0x92, 0xe2, 0xc0, 0x70, 0x08, 0xdc, 0x84, 0x4e, 0x6f, 0x33, 0x18, 0x85, 0xf2, 0x5b, - 0xf6, 0x8b, 0x49, 0x32, 0x0b, 0x28, 0x96, 0x12, 0xc6, 0xbf, 0x0b, 0xb0, 0x91, 0xc3, 0x41, 0x62, - 0xb9, 0x68, 0xff, 0x85, 0x6f, 0x6f, 0xff, 0x68, 0x1f, 0xaa, 0xd3, 0xdb, 0xcf, 0x8c, 0x89, 0xec, - 0xf6, 0x93, 0xaf, 0xf8, 0xa7, 0xa0, 0xc6, 0xd1, 0x5d, 0xd2, 0x50, 0xb9, 0xe6, 0xf2, 0x4c, 0xe4, - 0x7c, 0x36, 0x58, 0x73, 0x79, 0xe4, 0x06, 0xab, 0xb8, 0x39, 0xf8, 0x03, 0x68, 0x4b, 0xf3, 0x99, - 0xad, 0xd0, 0xfd, 0xa3, 0xc1, 0x10, 0x9b, 0xfa, 0x13, 0x54, 0x05, 0x75, 0x64, 0x0f, 0xcf, 0xf4, - 0x02, 0xa3, 0xcc, 0x3f, 0x99, 0x5d, 0xb1, 0x96, 0x33, 0xca, 0x91, 0x42, 0xca, 0xc1, 0x7f, 0x0b, - 0x00, 0x8b, 0x86, 0x84, 0x34, 0xa8, 0x9c, 0x0f, 0x4e, 0x06, 0xc3, 0x77, 0x03, 0x61, 0xe0, 0xc8, - 0xee, 0xf7, 0xf4, 0x02, 0xaa, 0x41, 0x49, 0xec, 0xf9, 0x45, 0xe6, 0x41, 0x2e, 0xf9, 0x0a, 0xfb, - 0x07, 0x90, 0x6d, 0xf8, 0x2a, 0xaa, 0x80, 0x92, 0xed, 0xf1, 0x72, 0x71, 0x2f, 0x33, 0x83, 0xd8, - 0x3c, 0xb3, 0xda, 0x5d, 0x53, 0xaf, 0xb0, 0x8b, 0x6c, 0x85, 0x07, 0x28, 0xa7, 0xfb, 0x3b, 0xd3, - 0x64, 0x5b, 0x3f, 0x30, 0x3f, 0x43, 0xfb, 0x8d, 0x89, 0x75, 0x8d, 0xf1, 0xf0, 0xf0, 0x9d, 0xbe, - 0xc2, 0x78, 0xaf, 0xfb, 0xa6, 0xd5, 0xd3, 0x57, 0xd9, 0xda, 0xff, 0xc6, 0x6c, 0x63, 0xbb, 0x63, - 0xb6, 0x6d, 0xbd, 0xce, 0x6e, 0x2e, 0x78, 0x80, 0x6b, 0xcc, 0xcd, 0xf1, 0xf0, 0x1c, 0x0f, 0xda, - 0x96, 0xae, 0x1f, 0xec, 0xc1, 0x6a, 0x6e, 0xfe, 0x30, 0x5f, 0x76, 0xbb, 0x63, 0x99, 0x23, 0xfd, - 0x09, 0xa3, 0x47, 0x6f, 0xda, 0xb8, 0x37, 0xd2, 0x0b, 0x9d, 0x5f, 0xbe, 0xdf, 0x9b, 0xfb, 0x94, - 0x24, 0x49, 0xd3, 0x8f, 0x0e, 0x05, 0x75, 0x78, 0x1d, 0x1d, 0xce, 0xe9, 0x21, 0xff, 0x0b, 0x7a, - 0xb8, 0x78, 0x3e, 0x97, 0x65, 0xce, 0xf9, 0xcd, 0x37, 0x01, 0x00, 0x00, 0xff, 0xff, 0x2e, 0xb4, - 0x72, 0xde, 0xde, 0x0e, 0x00, 0x00, + proto.RegisterType((*VStreamResultsRequest)(nil), "binlogdata.VStreamResultsRequest") + proto.RegisterType((*VStreamResultsResponse)(nil), "binlogdata.VStreamResultsResponse") +} + +func init() { proto.RegisterFile("binlogdata.proto", fileDescriptor_5fd02bcb2e350dad) } + +var fileDescriptor_5fd02bcb2e350dad = []byte{ + // 1648 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xdc, 0x58, 0x4b, 0x73, 0xe3, 0x4a, + 0x15, 0x8e, 0x6c, 0xf9, 0x75, 0x94, 0x38, 0x4a, 0xe7, 0x81, 0x49, 0x71, 0xa9, 0x5c, 0x15, 0x97, + 0xe4, 0xa6, 0x0a, 0x07, 0x0c, 0x0c, 0xab, 0xcb, 0xc5, 0x0f, 0x25, 0x71, 0x22, 0xdb, 0x99, 0xb6, + 0x92, 0xa1, 0x66, 0xa3, 0x52, 0xec, 0x76, 0x22, 0x22, 0x4b, 0x1e, 0xa9, 0x9d, 0x90, 0x1f, 0x40, + 0xf1, 0x03, 0xd8, 0xf2, 0x07, 0x58, 0xb3, 0x85, 0x2d, 0x7b, 0xf6, 0x54, 0xb1, 0xe2, 0x7f, 0x50, + 0xfd, 0x90, 0x6c, 0x25, 0xc3, 0x4c, 0x66, 0xaa, 0x58, 0xc0, 0xc6, 0x75, 0xfa, 0xf4, 0x39, 0xa7, + 0xcf, 0xf9, 0xce, 0xa3, 0xd5, 0x06, 0xfd, 0xda, 0x0b, 0xfc, 0xf0, 0x66, 0xec, 0x52, 0xb7, 0x3e, + 0x8b, 0x42, 0x1a, 0x22, 0x58, 0x70, 0x76, 0xb5, 0x7b, 0x1a, 0xcd, 0x46, 0x62, 0x63, 0x57, 0x7b, + 0x37, 0x27, 0xd1, 0xa3, 0x5c, 0x54, 0x69, 0x38, 0x0b, 0x17, 0x5a, 0x46, 0x0f, 0x4a, 0xed, 0x5b, + 0x37, 0x8a, 0x09, 0x45, 0x3b, 0x50, 0x1c, 0xf9, 0x1e, 0x09, 0x68, 0x4d, 0xd9, 0x53, 0x0e, 0x0a, + 0x58, 0xae, 0x10, 0x02, 0x75, 0x14, 0x06, 0x41, 0x2d, 0xc7, 0xb9, 0x9c, 0x66, 0xb2, 0x31, 0x89, + 0xee, 0x49, 0x54, 0xcb, 0x0b, 0x59, 0xb1, 0x32, 0xfe, 0x95, 0x87, 0x8d, 0x16, 0xf7, 0xc3, 0x8e, + 0xdc, 0x20, 0x76, 0x47, 0xd4, 0x0b, 0x03, 0x74, 0x02, 0x10, 0x53, 0x97, 0x92, 0x29, 0x09, 0x68, + 0x5c, 0x53, 0xf6, 0xf2, 0x07, 0x5a, 0x63, 0xbf, 0xbe, 0x14, 0xc1, 0x33, 0x95, 0xfa, 0x30, 0x91, + 0xc7, 0x4b, 0xaa, 0xa8, 0x01, 0x1a, 0xb9, 0x27, 0x01, 0x75, 0x68, 0x78, 0x47, 0x82, 0x9a, 0xba, + 0xa7, 0x1c, 0x68, 0x8d, 0x8d, 0xba, 0x08, 0xd0, 0x64, 0x3b, 0x36, 0xdb, 0xc0, 0x40, 0x52, 0x7a, + 0xf7, 0x6f, 0x39, 0xa8, 0xa4, 0xd6, 0x90, 0x05, 0xe5, 0x91, 0x4b, 0xc9, 0x4d, 0x18, 0x3d, 0xf2, + 0x30, 0xab, 0x8d, 0x1f, 0xbf, 0xd0, 0x91, 0x7a, 0x5b, 0xea, 0xe1, 0xd4, 0x02, 0xfa, 0x11, 0x94, + 0x46, 0x02, 0x3d, 0x8e, 0x8e, 0xd6, 0xd8, 0x5c, 0x36, 0x26, 0x81, 0xc5, 0x89, 0x0c, 0xd2, 0x21, + 0x1f, 0xbf, 0xf3, 0x39, 0x64, 0xab, 0x98, 0x91, 0xc6, 0x9f, 0x14, 0x28, 0x27, 0x76, 0xd1, 0x26, + 0xac, 0xb7, 0x2c, 0xe7, 0xb2, 0x8f, 0xcd, 0xf6, 0xe0, 0xa4, 0xdf, 0x7d, 0x6b, 0x76, 0xf4, 0x15, + 0xb4, 0x0a, 0xe5, 0x96, 0xe5, 0xb4, 0xcc, 0x93, 0x6e, 0x5f, 0x57, 0xd0, 0x1a, 0x54, 0x5a, 0x96, + 0xd3, 0x1e, 0xf4, 0x7a, 0x5d, 0x5b, 0xcf, 0xa1, 0x75, 0xd0, 0x5a, 0x96, 0x83, 0x07, 0x96, 0xd5, + 0x6a, 0xb6, 0xcf, 0xf5, 0x3c, 0xda, 0x86, 0x8d, 0x96, 0xe5, 0x74, 0x7a, 0x96, 0xd3, 0x31, 0x2f, + 0xb0, 0xd9, 0x6e, 0xda, 0x66, 0x47, 0x57, 0x11, 0x40, 0x91, 0xb1, 0x3b, 0x96, 0x5e, 0x90, 0xf4, + 0xd0, 0xb4, 0xf5, 0xa2, 0x34, 0xd7, 0xed, 0x0f, 0x4d, 0x6c, 0xeb, 0x25, 0xb9, 0xbc, 0xbc, 0xe8, + 0x34, 0x6d, 0x53, 0x2f, 0xcb, 0x65, 0xc7, 0xb4, 0x4c, 0xdb, 0xd4, 0x2b, 0x67, 0x6a, 0x39, 0xa7, + 0xe7, 0xcf, 0xd4, 0x72, 0x5e, 0x57, 0x8d, 0x3f, 0x28, 0xb0, 0x3d, 0xa4, 0x11, 0x71, 0xa7, 0xe7, + 0xe4, 0x11, 0xbb, 0xc1, 0x0d, 0xc1, 0xe4, 0xdd, 0x9c, 0xc4, 0x14, 0xed, 0x42, 0x79, 0x16, 0xc6, + 0x1e, 0xc3, 0x8e, 0x03, 0x5c, 0xc1, 0xe9, 0x1a, 0x1d, 0x41, 0xe5, 0x8e, 0x3c, 0x3a, 0x11, 0x93, + 0x97, 0x80, 0xa1, 0x7a, 0x5a, 0x90, 0xa9, 0xa5, 0xf2, 0x9d, 0xa4, 0x96, 0xf1, 0xcd, 0x7f, 0x1c, + 0x5f, 0x63, 0x02, 0x3b, 0x4f, 0x9d, 0x8a, 0x67, 0x61, 0x10, 0x13, 0x64, 0x01, 0x12, 0x8a, 0x0e, + 0x5d, 0xe4, 0x96, 0xfb, 0xa7, 0x35, 0xbe, 0xf8, 0x60, 0x01, 0xe0, 0x8d, 0xeb, 0xa7, 0x2c, 0xe3, + 0xb7, 0xb0, 0x29, 0xce, 0xb1, 0xdd, 0x6b, 0x9f, 0xc4, 0x2f, 0x09, 0x7d, 0x07, 0x8a, 0x94, 0x0b, + 0xd7, 0x72, 0x7b, 0xf9, 0x83, 0x0a, 0x96, 0xab, 0x4f, 0x8d, 0x70, 0x0c, 0x5b, 0xd9, 0x93, 0xff, + 0x2b, 0xf1, 0xfd, 0x0c, 0x54, 0x3c, 0xf7, 0x09, 0xda, 0x82, 0xc2, 0xd4, 0xa5, 0xa3, 0x5b, 0x19, + 0x8d, 0x58, 0xb0, 0x50, 0x26, 0x9e, 0x4f, 0x49, 0xc4, 0x53, 0x58, 0xc1, 0x72, 0x65, 0xfc, 0x59, + 0x81, 0xe2, 0x31, 0x27, 0xd1, 0x0f, 0xa1, 0x10, 0xcd, 0x59, 0xb0, 0xa2, 0xd7, 0xf5, 0x65, 0x0f, + 0x98, 0x65, 0x2c, 0xb6, 0x51, 0x17, 0xaa, 0x13, 0x8f, 0xf8, 0x63, 0xde, 0xba, 0xbd, 0x70, 0x2c, + 0xaa, 0xa2, 0xda, 0xf8, 0x72, 0x59, 0x41, 0xd8, 0xac, 0x1f, 0x67, 0x04, 0xf1, 0x13, 0x45, 0xe3, + 0x15, 0x54, 0xb3, 0x12, 0xac, 0x9d, 0x4c, 0x8c, 0x9d, 0x41, 0xdf, 0xe9, 0x75, 0x87, 0xbd, 0xa6, + 0xdd, 0x3e, 0xd5, 0x57, 0x78, 0xc7, 0x98, 0x43, 0xdb, 0x31, 0x8f, 0x8f, 0x07, 0xd8, 0xd6, 0x15, + 0xe3, 0x8f, 0x39, 0x58, 0x15, 0xa0, 0x0c, 0xc3, 0x79, 0x34, 0x22, 0x2c, 0x8b, 0x77, 0xe4, 0x31, + 0x9e, 0xb9, 0x23, 0x92, 0x64, 0x31, 0x59, 0x33, 0x40, 0xe2, 0x5b, 0x37, 0x1a, 0xcb, 0xc8, 0xc5, + 0x02, 0xfd, 0x1c, 0x34, 0x9e, 0x4d, 0xea, 0xd0, 0xc7, 0x19, 0xe1, 0x79, 0xac, 0x36, 0xb6, 0x16, + 0x85, 0xcd, 0x73, 0x45, 0xed, 0xc7, 0x19, 0xc1, 0x40, 0x53, 0x3a, 0xdb, 0x0d, 0xea, 0x0b, 0xba, + 0x61, 0x51, 0x43, 0x85, 0x4c, 0x0d, 0x1d, 0xa6, 0x09, 0x29, 0x4a, 0x2b, 0xcf, 0xd0, 0x4b, 0x92, + 0x84, 0xea, 0x50, 0x0c, 0x03, 0x67, 0x3c, 0xf6, 0x6b, 0x25, 0xee, 0xe6, 0x77, 0x96, 0x65, 0x07, + 0x41, 0xa7, 0x63, 0x35, 0x45, 0x59, 0x14, 0xc2, 0xa0, 0x33, 0xf6, 0x8d, 0xd7, 0x50, 0xc1, 0xe1, + 0x43, 0xfb, 0x96, 0x3b, 0x60, 0x40, 0xf1, 0x9a, 0x4c, 0xc2, 0x88, 0xc8, 0xca, 0x02, 0x39, 0x79, + 0x71, 0xf8, 0x80, 0xe5, 0x0e, 0xda, 0x83, 0x82, 0x3b, 0x49, 0x8a, 0x23, 0x2b, 0x22, 0x36, 0x0c, + 0x17, 0xca, 0x38, 0x7c, 0xe0, 0x79, 0x42, 0x5f, 0x80, 0x40, 0xc4, 0x09, 0xdc, 0x69, 0x02, 0x77, + 0x85, 0x73, 0xfa, 0xee, 0x94, 0xa0, 0x57, 0xa0, 0x45, 0xe1, 0x83, 0x33, 0xe2, 0xc7, 0x8b, 0xd6, + 0xd1, 0x1a, 0xdb, 0x99, 0x6a, 0x4a, 0x9c, 0xc3, 0x10, 0x25, 0x64, 0x6c, 0xbc, 0x06, 0x58, 0x14, + 0xc3, 0xc7, 0x0e, 0xf9, 0x01, 0x83, 0x8f, 0xf8, 0xe3, 0xc4, 0xfe, 0xaa, 0x74, 0x99, 0x5b, 0xc0, + 0x72, 0x8f, 0x01, 0x31, 0x64, 0xd9, 0x3e, 0xa1, 0xde, 0xf8, 0x33, 0x6a, 0x04, 0x81, 0x7a, 0x43, + 0xbd, 0x31, 0x2f, 0x8e, 0x0a, 0xe6, 0xb4, 0xf1, 0x2d, 0x14, 0xae, 0xb8, 0xb9, 0x57, 0xa0, 0x71, + 0x29, 0x87, 0xb1, 0x93, 0xa6, 0xc9, 0x84, 0x99, 0x1e, 0x8d, 0x21, 0x4e, 0xc8, 0xd8, 0x68, 0xc2, + 0xda, 0xb9, 0x3c, 0x96, 0x0b, 0x7c, 0xba, 0x5f, 0xc6, 0x5f, 0x72, 0x50, 0x3a, 0x0b, 0xe7, 0x51, + 0xe0, 0xfa, 0xa8, 0x0a, 0x39, 0x6f, 0xcc, 0xf5, 0xf2, 0x38, 0xe7, 0x8d, 0xd1, 0xaf, 0xa0, 0x3a, + 0xf5, 0x6e, 0x22, 0x97, 0xd5, 0x83, 0x28, 0x6d, 0xd1, 0x9d, 0xdf, 0x5d, 0xf6, 0xac, 0x97, 0x48, + 0xf0, 0xfa, 0x5e, 0x9b, 0x2e, 0x2f, 0x97, 0x2a, 0x36, 0x9f, 0xa9, 0xd8, 0xaf, 0xa0, 0xea, 0x87, + 0x23, 0xd7, 0x77, 0xd2, 0x79, 0xa9, 0x72, 0xa7, 0xd6, 0x38, 0xf7, 0x22, 0x19, 0x9a, 0x4f, 0x70, + 0x29, 0xbc, 0x10, 0x17, 0xf4, 0x0d, 0xac, 0xce, 0xdc, 0x88, 0x7a, 0x23, 0x6f, 0xe6, 0xb2, 0x2f, + 0x8e, 0x22, 0x57, 0xcc, 0xb8, 0x9d, 0xc1, 0x0d, 0x67, 0xc4, 0xd1, 0xd7, 0xa0, 0xc7, 0x7c, 0x16, + 0x38, 0x0f, 0x61, 0x74, 0x37, 0xf1, 0xc3, 0x87, 0xb8, 0x56, 0xe2, 0xfe, 0xaf, 0x0b, 0xfe, 0x9b, + 0x84, 0x6d, 0xfc, 0x33, 0x07, 0xc5, 0x2b, 0x51, 0x65, 0x87, 0xa0, 0x72, 0x8c, 0xc4, 0x57, 0xc5, + 0xce, 0xf2, 0x61, 0x42, 0x82, 0x03, 0xc4, 0x65, 0xd0, 0xf7, 0xa0, 0x42, 0xbd, 0x29, 0x89, 0xa9, + 0x3b, 0x9d, 0x71, 0x50, 0xf3, 0x78, 0xc1, 0x78, 0x5f, 0xad, 0xb0, 0x4f, 0x07, 0xd6, 0xb4, 0x02, + 0x26, 0x46, 0xa2, 0x9f, 0x40, 0x85, 0xf5, 0x06, 0xff, 0xd2, 0xa9, 0x15, 0x78, 0xb3, 0x6d, 0x3d, + 0xe9, 0x0c, 0x7e, 0x2c, 0x2e, 0x47, 0x49, 0xb7, 0xfd, 0x02, 0x34, 0x5e, 0xcd, 0x52, 0x49, 0x4c, + 0x8b, 0x9d, 0xec, 0xb4, 0x48, 0xba, 0x06, 0xc3, 0x62, 0xc0, 0xa2, 0x7d, 0x28, 0xdc, 0x73, 0x97, + 0x4a, 0xf2, 0x8b, 0x6b, 0x39, 0x38, 0x0e, 0xbf, 0xd8, 0x67, 0xd7, 0xd9, 0x6f, 0x44, 0x35, 0xd5, + 0xca, 0xcf, 0xaf, 0x33, 0x59, 0x68, 0x38, 0x91, 0x41, 0x5f, 0xc2, 0xea, 0x68, 0x1e, 0x45, 0xfc, + 0x8b, 0xce, 0x9b, 0x92, 0xda, 0x16, 0x87, 0x42, 0x93, 0x3c, 0xdb, 0x9b, 0x12, 0xe3, 0xf7, 0x39, + 0xa8, 0x5e, 0x89, 0x3b, 0x2f, 0xb9, 0x67, 0xbf, 0x85, 0x4d, 0x32, 0x99, 0x90, 0x11, 0xf5, 0xee, + 0x89, 0x33, 0x72, 0x7d, 0x9f, 0x44, 0x8e, 0x2c, 0x5c, 0xad, 0xb1, 0x5e, 0x17, 0xdf, 0xbe, 0x6d, + 0xce, 0xef, 0x76, 0xf0, 0x46, 0x2a, 0x2b, 0x59, 0x63, 0x64, 0xc2, 0xa6, 0x37, 0x9d, 0x92, 0xb1, + 0xe7, 0xd2, 0x65, 0x03, 0x62, 0x62, 0x6d, 0xcb, 0xf6, 0xbf, 0xb2, 0x4f, 0x5c, 0x4a, 0x16, 0x66, + 0x52, 0x8d, 0xd4, 0xcc, 0x57, 0xac, 0xba, 0xa3, 0x9b, 0xf4, 0xea, 0x5e, 0x93, 0x9a, 0x36, 0x67, + 0x62, 0xb9, 0x99, 0xf9, 0x2c, 0x50, 0x9f, 0x7c, 0x16, 0x2c, 0x46, 0x77, 0xe1, 0x63, 0xa3, 0xdb, + 0xf8, 0x06, 0xd6, 0x53, 0x20, 0xe4, 0xb5, 0x7f, 0x08, 0x45, 0x9e, 0xca, 0x64, 0x66, 0xa0, 0xe7, + 0x55, 0x87, 0xa5, 0x84, 0xf1, 0xbb, 0x1c, 0xa0, 0x44, 0x3f, 0x7c, 0x88, 0xff, 0x47, 0xc1, 0xdc, + 0x82, 0x02, 0xe7, 0x4b, 0x24, 0xc5, 0x82, 0xe1, 0xe0, 0xbb, 0x31, 0x9d, 0xdd, 0xa5, 0x30, 0x0a, + 0xe5, 0xd7, 0xec, 0x17, 0x93, 0x78, 0xee, 0x53, 0x2c, 0x25, 0x8c, 0xbf, 0x2a, 0xb0, 0x99, 0xc1, + 0x41, 0x62, 0xb9, 0xb8, 0x06, 0x94, 0xff, 0x7c, 0x0d, 0xa0, 0x03, 0x28, 0xcf, 0xee, 0x3e, 0x70, + 0x5d, 0xa4, 0xbb, 0xef, 0xed, 0xe2, 0xef, 0x83, 0x1a, 0xb1, 0x69, 0xa2, 0x72, 0xcd, 0xe5, 0xbb, + 0x91, 0xf3, 0xd9, 0x05, 0x9b, 0x89, 0x23, 0x73, 0xc1, 0x4a, 0xff, 0xff, 0xa1, 0xc0, 0xf6, 0xa2, + 0x0e, 0xe6, 0x3e, 0xfd, 0xbf, 0x4a, 0xa5, 0x11, 0xc1, 0xce, 0xd3, 0xe8, 0x3e, 0x29, 0x41, 0x9f, + 0x01, 0xfb, 0xe1, 0x2f, 0x41, 0x5b, 0xfa, 0xf4, 0x61, 0x2f, 0xa4, 0xee, 0x49, 0x7f, 0x80, 0x4d, + 0x7d, 0x05, 0x95, 0x41, 0x1d, 0xda, 0x83, 0x0b, 0x5d, 0x61, 0x94, 0xf9, 0x6b, 0xb3, 0x2d, 0x5e, + 0x5d, 0x8c, 0x72, 0xa4, 0x50, 0xfe, 0xf0, 0xef, 0x0a, 0xc0, 0x62, 0xc6, 0x23, 0x0d, 0x4a, 0x97, + 0xfd, 0xf3, 0xfe, 0xe0, 0x4d, 0x5f, 0x18, 0x38, 0xb1, 0xbb, 0x1d, 0x5d, 0x41, 0x15, 0x28, 0x88, + 0x67, 0x5c, 0x8e, 0x9d, 0x20, 0xdf, 0x70, 0x79, 0xf6, 0xc0, 0x4b, 0x1f, 0x70, 0x2a, 0x2a, 0x41, + 0x3e, 0x7d, 0xa6, 0xc9, 0x77, 0x59, 0x91, 0x19, 0xc4, 0xe6, 0x85, 0xd5, 0x6c, 0x9b, 0x7a, 0x89, + 0x6d, 0xa4, 0x2f, 0x34, 0x80, 0x62, 0xf2, 0x3c, 0x63, 0x9a, 0xec, 0x51, 0x07, 0xec, 0x9c, 0x81, + 0x7d, 0x6a, 0x62, 0x5d, 0x63, 0x3c, 0x3c, 0x78, 0xa3, 0xaf, 0x32, 0xde, 0x71, 0xd7, 0xb4, 0x3a, + 0xfa, 0x1a, 0x7b, 0xd5, 0x9d, 0x9a, 0x4d, 0x6c, 0xb7, 0xcc, 0xa6, 0xad, 0x57, 0xd9, 0xce, 0x15, + 0x77, 0x70, 0x9d, 0x1d, 0x73, 0x36, 0xb8, 0xc4, 0xfd, 0xa6, 0xa5, 0xeb, 0x87, 0xfb, 0xb0, 0x96, + 0xb9, 0xda, 0xd9, 0x59, 0x76, 0xb3, 0x65, 0x99, 0x43, 0x7d, 0x85, 0xd1, 0xc3, 0xd3, 0x26, 0xee, + 0x0c, 0x75, 0xa5, 0xf5, 0xf5, 0xdb, 0xfd, 0x7b, 0x8f, 0x92, 0x38, 0xae, 0x7b, 0xe1, 0x91, 0xa0, + 0x8e, 0x6e, 0xc2, 0xa3, 0x7b, 0x7a, 0xc4, 0xff, 0x61, 0x38, 0x5a, 0x4c, 0xa4, 0xeb, 0x22, 0xe7, + 0xfc, 0xf4, 0xdf, 0x01, 0x00, 0x00, 0xff, 0xff, 0xe4, 0x09, 0xf3, 0xd7, 0xbd, 0x10, 0x00, 0x00, } diff --git a/go/vt/proto/binlogservice/binlogservice.pb.go b/go/vt/proto/binlogservice/binlogservice.pb.go index 790a92f4a2b..77312b91234 100644 --- a/go/vt/proto/binlogservice/binlogservice.pb.go +++ b/go/vt/proto/binlogservice/binlogservice.pb.go @@ -1,16 +1,18 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // source: binlogservice.proto -package binlogservice // import "vitess.io/vitess/go/vt/proto/binlogservice" - -import proto "github.com/golang/protobuf/proto" -import fmt "fmt" -import math "math" -import binlogdata "vitess.io/vitess/go/vt/proto/binlogdata" +package binlogservice import ( - context "golang.org/x/net/context" + context "context" + fmt "fmt" + math "math" + + proto "github.com/golang/protobuf/proto" grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + binlogdata "vitess.io/vitess/go/vt/proto/binlogdata" ) // Reference imports to suppress errors if they are not otherwise used. @@ -22,7 +24,25 @@ var _ = math.Inf // is compatible with the proto package it is being compiled against. // A compilation error at this line likely means your copy of the // proto package needs to be updated. -const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package +const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package + +func init() { proto.RegisterFile("binlogservice.proto", fileDescriptor_4ccdea02fd9c8d58) } + +var fileDescriptor_4ccdea02fd9c8d58 = []byte{ + // 177 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x12, 0x4e, 0xca, 0xcc, 0xcb, + 0xc9, 0x4f, 0x2f, 0x4e, 0x2d, 0x2a, 0xcb, 0x4c, 0x4e, 0xd5, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, + 0xe2, 0x45, 0x11, 0x94, 0x12, 0x80, 0x70, 0x53, 0x12, 0x4b, 0x12, 0x21, 0x0a, 0x8c, 0x0e, 0x31, + 0x72, 0xf1, 0x84, 0x16, 0xa4, 0x24, 0x96, 0xa4, 0x06, 0x97, 0x14, 0xa5, 0x26, 0xe6, 0x0a, 0x45, + 0x73, 0xf1, 0x41, 0x58, 0xde, 0xa9, 0x95, 0x41, 0x89, 0x79, 0xe9, 0xa9, 0x42, 0x8a, 0x7a, 0x48, + 0xba, 0x50, 0xe5, 0x82, 0x52, 0x0b, 0x4b, 0x53, 0x8b, 0x4b, 0xa4, 0x94, 0xf0, 0x29, 0x29, 0x2e, + 0xc8, 0xcf, 0x2b, 0x4e, 0x55, 0x62, 0x30, 0x60, 0x14, 0x0a, 0xe5, 0xe2, 0x81, 0xc8, 0x86, 0x24, + 0x26, 0xe5, 0xa4, 0x16, 0x0b, 0xc9, 0x63, 0xea, 0x83, 0xc8, 0xc0, 0x0c, 0x56, 0xc0, 0xad, 0x00, + 0x61, 0xac, 0x93, 0x4e, 0x94, 0x56, 0x59, 0x66, 0x49, 0x6a, 0x71, 0xb1, 0x5e, 0x66, 0xbe, 0x3e, + 0x84, 0xa5, 0x9f, 0x9e, 0xaf, 0x5f, 0x56, 0xa2, 0x0f, 0xf6, 0xa4, 0x3e, 0x4a, 0x20, 0x24, 0xb1, + 0x81, 0x05, 0x8d, 0x01, 0x01, 0x00, 0x00, 0xff, 0xff, 0x4a, 0xf4, 0x0a, 0x9c, 0x31, 0x01, 0x00, + 0x00, +} // Reference imports to suppress errors if they are not otherwise used. var _ context.Context @@ -126,6 +146,17 @@ type UpdateStreamServer interface { StreamTables(*binlogdata.StreamTablesRequest, UpdateStream_StreamTablesServer) error } +// UnimplementedUpdateStreamServer can be embedded to have forward compatible implementations. +type UnimplementedUpdateStreamServer struct { +} + +func (*UnimplementedUpdateStreamServer) StreamKeyRange(req *binlogdata.StreamKeyRangeRequest, srv UpdateStream_StreamKeyRangeServer) error { + return status.Errorf(codes.Unimplemented, "method StreamKeyRange not implemented") +} +func (*UnimplementedUpdateStreamServer) StreamTables(req *binlogdata.StreamTablesRequest, srv UpdateStream_StreamTablesServer) error { + return status.Errorf(codes.Unimplemented, "method StreamTables not implemented") +} + func RegisterUpdateStreamServer(s *grpc.Server, srv UpdateStreamServer) { s.RegisterService(&_UpdateStream_serviceDesc, srv) } @@ -190,21 +221,3 @@ var _UpdateStream_serviceDesc = grpc.ServiceDesc{ }, Metadata: "binlogservice.proto", } - -func init() { proto.RegisterFile("binlogservice.proto", fileDescriptor_binlogservice_bfebf84e565603b8) } - -var fileDescriptor_binlogservice_bfebf84e565603b8 = []byte{ - // 177 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x12, 0x4e, 0xca, 0xcc, 0xcb, - 0xc9, 0x4f, 0x2f, 0x4e, 0x2d, 0x2a, 0xcb, 0x4c, 0x4e, 0xd5, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, - 0xe2, 0x45, 0x11, 0x94, 0x12, 0x80, 0x70, 0x53, 0x12, 0x4b, 0x12, 0x21, 0x0a, 0x8c, 0x0e, 0x31, - 0x72, 0xf1, 0x84, 0x16, 0xa4, 0x24, 0x96, 0xa4, 0x06, 0x97, 0x14, 0xa5, 0x26, 0xe6, 0x0a, 0x45, - 0x73, 0xf1, 0x41, 0x58, 0xde, 0xa9, 0x95, 0x41, 0x89, 0x79, 0xe9, 0xa9, 0x42, 0x8a, 0x7a, 0x48, - 0xba, 0x50, 0xe5, 0x82, 0x52, 0x0b, 0x4b, 0x53, 0x8b, 0x4b, 0xa4, 0x94, 0xf0, 0x29, 0x29, 0x2e, - 0xc8, 0xcf, 0x2b, 0x4e, 0x55, 0x62, 0x30, 0x60, 0x14, 0x0a, 0xe5, 0xe2, 0x81, 0xc8, 0x86, 0x24, - 0x26, 0xe5, 0xa4, 0x16, 0x0b, 0xc9, 0x63, 0xea, 0x83, 0xc8, 0xc0, 0x0c, 0x56, 0xc0, 0xad, 0x00, - 0x61, 0xac, 0x93, 0x4e, 0x94, 0x56, 0x59, 0x66, 0x49, 0x6a, 0x71, 0xb1, 0x5e, 0x66, 0xbe, 0x3e, - 0x84, 0xa5, 0x9f, 0x9e, 0xaf, 0x5f, 0x56, 0xa2, 0x0f, 0xf6, 0xa4, 0x3e, 0x4a, 0x20, 0x24, 0xb1, - 0x81, 0x05, 0x8d, 0x01, 0x01, 0x00, 0x00, 0xff, 0xff, 0x4a, 0xf4, 0x0a, 0x9c, 0x31, 0x01, 0x00, - 0x00, -} diff --git a/go/vt/proto/logutil/logutil.pb.go b/go/vt/proto/logutil/logutil.pb.go index f1202173262..16f34fa049c 100644 --- a/go/vt/proto/logutil/logutil.pb.go +++ b/go/vt/proto/logutil/logutil.pb.go @@ -1,11 +1,15 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // source: logutil.proto -package logutil // import "vitess.io/vitess/go/vt/proto/logutil" +package logutil -import proto "github.com/golang/protobuf/proto" -import fmt "fmt" -import math "math" +import ( + fmt "fmt" + math "math" + + proto "github.com/golang/protobuf/proto" + vttime "vitess.io/vitess/go/vt/proto/vttime" +) // Reference imports to suppress errors if they are not otherwise used. var _ = proto.Marshal @@ -16,7 +20,7 @@ var _ = math.Inf // is compatible with the proto package it is being compiled against. // A compilation error at this line likely means your copy of the // proto package needs to be updated. -const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package +const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package // Level is the level of the log messages. type Level int32 @@ -38,6 +42,7 @@ var Level_name = map[int32]string{ 2: "ERROR", 3: "CONSOLE", } + var Level_value = map[string]int32{ "INFO": 0, "WARNING": 1, @@ -48,84 +53,38 @@ var Level_value = map[string]int32{ func (x Level) String() string { return proto.EnumName(Level_name, int32(x)) } -func (Level) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_logutil_1922c06158165cc5, []int{0} -} - -// Time represents a time stamp in nanoseconds. In go, use logutil library -// to convert times. -type Time struct { - Seconds int64 `protobuf:"varint,1,opt,name=seconds,proto3" json:"seconds,omitempty"` - Nanoseconds int32 `protobuf:"varint,2,opt,name=nanoseconds,proto3" json:"nanoseconds,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *Time) Reset() { *m = Time{} } -func (m *Time) String() string { return proto.CompactTextString(m) } -func (*Time) ProtoMessage() {} -func (*Time) Descriptor() ([]byte, []int) { - return fileDescriptor_logutil_1922c06158165cc5, []int{0} -} -func (m *Time) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Time.Unmarshal(m, b) -} -func (m *Time) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Time.Marshal(b, m, deterministic) -} -func (dst *Time) XXX_Merge(src proto.Message) { - xxx_messageInfo_Time.Merge(dst, src) -} -func (m *Time) XXX_Size() int { - return xxx_messageInfo_Time.Size(m) -} -func (m *Time) XXX_DiscardUnknown() { - xxx_messageInfo_Time.DiscardUnknown(m) -} -var xxx_messageInfo_Time proto.InternalMessageInfo - -func (m *Time) GetSeconds() int64 { - if m != nil { - return m.Seconds - } - return 0 -} - -func (m *Time) GetNanoseconds() int32 { - if m != nil { - return m.Nanoseconds - } - return 0 +func (Level) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_31f5dd3702a8edf9, []int{0} } // Event is a single logging event type Event struct { - Time *Time `protobuf:"bytes,1,opt,name=time,proto3" json:"time,omitempty"` - Level Level `protobuf:"varint,2,opt,name=level,proto3,enum=logutil.Level" json:"level,omitempty"` - File string `protobuf:"bytes,3,opt,name=file,proto3" json:"file,omitempty"` - Line int64 `protobuf:"varint,4,opt,name=line,proto3" json:"line,omitempty"` - Value string `protobuf:"bytes,5,opt,name=value,proto3" json:"value,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + Time *vttime.Time `protobuf:"bytes,1,opt,name=time,proto3" json:"time,omitempty"` + Level Level `protobuf:"varint,2,opt,name=level,proto3,enum=logutil.Level" json:"level,omitempty"` + File string `protobuf:"bytes,3,opt,name=file,proto3" json:"file,omitempty"` + Line int64 `protobuf:"varint,4,opt,name=line,proto3" json:"line,omitempty"` + Value string `protobuf:"bytes,5,opt,name=value,proto3" json:"value,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *Event) Reset() { *m = Event{} } func (m *Event) String() string { return proto.CompactTextString(m) } func (*Event) ProtoMessage() {} func (*Event) Descriptor() ([]byte, []int) { - return fileDescriptor_logutil_1922c06158165cc5, []int{1} + return fileDescriptor_31f5dd3702a8edf9, []int{0} } + func (m *Event) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Event.Unmarshal(m, b) } func (m *Event) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_Event.Marshal(b, m, deterministic) } -func (dst *Event) XXX_Merge(src proto.Message) { - xxx_messageInfo_Event.Merge(dst, src) +func (m *Event) XXX_Merge(src proto.Message) { + xxx_messageInfo_Event.Merge(m, src) } func (m *Event) XXX_Size() int { return xxx_messageInfo_Event.Size(m) @@ -136,7 +95,7 @@ func (m *Event) XXX_DiscardUnknown() { var xxx_messageInfo_Event proto.InternalMessageInfo -func (m *Event) GetTime() *Time { +func (m *Event) GetTime() *vttime.Time { if m != nil { return m.Time } @@ -172,30 +131,27 @@ func (m *Event) GetValue() string { } func init() { - proto.RegisterType((*Time)(nil), "logutil.Time") - proto.RegisterType((*Event)(nil), "logutil.Event") proto.RegisterEnum("logutil.Level", Level_name, Level_value) + proto.RegisterType((*Event)(nil), "logutil.Event") } -func init() { proto.RegisterFile("logutil.proto", fileDescriptor_logutil_1922c06158165cc5) } - -var fileDescriptor_logutil_1922c06158165cc5 = []byte{ - // 260 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x4c, 0x90, 0x41, 0x4b, 0xfb, 0x40, - 0x10, 0xc5, 0xff, 0xdb, 0x64, 0xff, 0xb1, 0x13, 0x5a, 0xc2, 0xe0, 0x21, 0xc7, 0x58, 0x8a, 0x04, - 0x0f, 0x09, 0x54, 0xf0, 0x6e, 0x25, 0x4a, 0xa1, 0x24, 0xb0, 0x0a, 0x82, 0xb7, 0xaa, 0x63, 0x59, - 0xd8, 0x66, 0xc5, 0x6c, 0xf7, 0x63, 0xf8, 0x99, 0x25, 0x93, 0x46, 0xbc, 0xbd, 0xf7, 0x7b, 0xc3, - 0x9b, 0x61, 0x60, 0x66, 0xec, 0xfe, 0xe8, 0xb4, 0x29, 0x3e, 0xbf, 0xac, 0xb3, 0x18, 0x9d, 0xec, - 0x62, 0x0d, 0xe1, 0x93, 0x3e, 0x10, 0xa6, 0x10, 0x75, 0xf4, 0x66, 0xdb, 0xf7, 0x2e, 0x15, 0x99, - 0xc8, 0x03, 0x35, 0x5a, 0xcc, 0x20, 0x6e, 0x77, 0xad, 0x1d, 0xd3, 0x49, 0x26, 0x72, 0xa9, 0xfe, - 0xa2, 0xc5, 0xb7, 0x00, 0x59, 0x79, 0x6a, 0x1d, 0x5e, 0x40, 0xe8, 0xf4, 0x81, 0xb8, 0x22, 0x5e, - 0xcd, 0x8a, 0x71, 0x69, 0xbf, 0x42, 0x71, 0x84, 0x4b, 0x90, 0x86, 0x3c, 0x19, 0x2e, 0x9a, 0xaf, - 0xe6, 0xbf, 0x33, 0xdb, 0x9e, 0xaa, 0x21, 0x44, 0x84, 0xf0, 0x43, 0x1b, 0x4a, 0x83, 0x4c, 0xe4, - 0x53, 0xc5, 0xba, 0x67, 0x46, 0xb7, 0x94, 0x86, 0x7c, 0x1f, 0x6b, 0x3c, 0x07, 0xe9, 0x77, 0xe6, - 0x48, 0xa9, 0xe4, 0xc1, 0xc1, 0x5c, 0xdd, 0x80, 0xe4, 0x36, 0x3c, 0x83, 0x70, 0x53, 0xdf, 0x37, - 0xc9, 0x3f, 0x8c, 0x21, 0x7a, 0xbe, 0x55, 0xf5, 0xa6, 0x7e, 0x48, 0x04, 0x4e, 0x41, 0x56, 0x4a, - 0x35, 0x2a, 0x99, 0xf4, 0xfc, 0xae, 0xa9, 0x1f, 0x9b, 0x6d, 0x95, 0x04, 0xeb, 0xcb, 0x97, 0xa5, - 0xd7, 0x8e, 0xba, 0xae, 0xd0, 0xb6, 0x1c, 0x54, 0xb9, 0xb7, 0xa5, 0x77, 0x25, 0x7f, 0xad, 0x3c, - 0x9d, 0xfa, 0xfa, 0x9f, 0xed, 0xf5, 0x4f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x27, 0x02, 0xa1, 0x99, - 0x55, 0x01, 0x00, 0x00, +func init() { proto.RegisterFile("logutil.proto", fileDescriptor_31f5dd3702a8edf9) } + +var fileDescriptor_31f5dd3702a8edf9 = []byte{ + // 235 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x34, 0x8f, 0x41, 0x4b, 0x03, 0x31, + 0x10, 0x85, 0x4d, 0x77, 0x63, 0xed, 0x54, 0xcb, 0x32, 0x78, 0x08, 0x9e, 0x82, 0x14, 0x59, 0x3c, + 0x6c, 0xa0, 0x82, 0x77, 0x95, 0x55, 0x0a, 0x65, 0x17, 0xa2, 0x20, 0x78, 0x53, 0x18, 0x4b, 0x20, + 0x6d, 0xc4, 0xa6, 0xf9, 0x17, 0xfe, 0x67, 0xd9, 0x49, 0x7b, 0x7b, 0xef, 0x7b, 0x8f, 0xc7, 0x0c, + 0x5c, 0xf8, 0xb0, 0xde, 0x47, 0xe7, 0x9b, 0x9f, 0xdf, 0x10, 0x03, 0x8e, 0x0f, 0xf6, 0x0a, 0xa2, + 0xdb, 0x50, 0x86, 0xd7, 0x7f, 0x02, 0x64, 0x9b, 0x68, 0x1b, 0x51, 0x43, 0x39, 0x70, 0x25, 0xb4, + 0xa8, 0xa7, 0x8b, 0xf3, 0x26, 0x45, 0xae, 0xbd, 0xb9, 0x0d, 0x59, 0x4e, 0x70, 0x0e, 0xd2, 0x53, + 0x22, 0xaf, 0x46, 0x5a, 0xd4, 0xb3, 0xc5, 0xac, 0x39, 0xee, 0xaf, 0x06, 0x6a, 0x73, 0x88, 0x08, + 0xe5, 0xb7, 0xf3, 0xa4, 0x0a, 0x2d, 0xea, 0x89, 0x65, 0x3d, 0x30, 0xef, 0xb6, 0xa4, 0x4a, 0x2d, + 0xea, 0xc2, 0xb2, 0xc6, 0x4b, 0x90, 0xe9, 0xd3, 0xef, 0x49, 0x49, 0x2e, 0x66, 0x73, 0x7b, 0x0f, + 0x92, 0xd7, 0xf0, 0x0c, 0xca, 0x65, 0xf7, 0xdc, 0x57, 0x27, 0x38, 0x85, 0xf1, 0xfb, 0x83, 0xed, + 0x96, 0xdd, 0x4b, 0x25, 0x70, 0x02, 0xb2, 0xb5, 0xb6, 0xb7, 0xd5, 0x68, 0xe0, 0x4f, 0x7d, 0xf7, + 0xda, 0xaf, 0xda, 0xaa, 0x78, 0xbc, 0xf9, 0x98, 0x27, 0x17, 0x69, 0xb7, 0x6b, 0x5c, 0x30, 0x59, + 0x99, 0x75, 0x30, 0x29, 0x1a, 0xfe, 0xd3, 0x1c, 0x4e, 0xfd, 0x3a, 0x65, 0x7b, 0xf7, 0x1f, 0x00, + 0x00, 0xff, 0xff, 0xdd, 0xfa, 0x9b, 0x9a, 0x1c, 0x01, 0x00, 0x00, } diff --git a/go/vt/proto/mysqlctl/mysqlctl.pb.go b/go/vt/proto/mysqlctl/mysqlctl.pb.go index b75568fd4b2..2b80a9971d9 100644 --- a/go/vt/proto/mysqlctl/mysqlctl.pb.go +++ b/go/vt/proto/mysqlctl/mysqlctl.pb.go @@ -1,15 +1,17 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // source: mysqlctl.proto -package mysqlctl // import "vitess.io/vitess/go/vt/proto/mysqlctl" - -import proto "github.com/golang/protobuf/proto" -import fmt "fmt" -import math "math" +package mysqlctl import ( - context "golang.org/x/net/context" + context "context" + fmt "fmt" + math "math" + + proto "github.com/golang/protobuf/proto" grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" ) // Reference imports to suppress errors if they are not otherwise used. @@ -21,7 +23,7 @@ var _ = math.Inf // is compatible with the proto package it is being compiled against. // A compilation error at this line likely means your copy of the // proto package needs to be updated. -const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package +const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package type StartRequest struct { MysqldArgs []string `protobuf:"bytes,1,rep,name=mysqld_args,json=mysqldArgs,proto3" json:"mysqld_args,omitempty"` @@ -34,16 +36,17 @@ func (m *StartRequest) Reset() { *m = StartRequest{} } func (m *StartRequest) String() string { return proto.CompactTextString(m) } func (*StartRequest) ProtoMessage() {} func (*StartRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_mysqlctl_6cf72a3618d6fe7c, []int{0} + return fileDescriptor_cd8c110e42f9cbb9, []int{0} } + func (m *StartRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_StartRequest.Unmarshal(m, b) } func (m *StartRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_StartRequest.Marshal(b, m, deterministic) } -func (dst *StartRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_StartRequest.Merge(dst, src) +func (m *StartRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_StartRequest.Merge(m, src) } func (m *StartRequest) XXX_Size() int { return xxx_messageInfo_StartRequest.Size(m) @@ -71,16 +74,17 @@ func (m *StartResponse) Reset() { *m = StartResponse{} } func (m *StartResponse) String() string { return proto.CompactTextString(m) } func (*StartResponse) ProtoMessage() {} func (*StartResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_mysqlctl_6cf72a3618d6fe7c, []int{1} + return fileDescriptor_cd8c110e42f9cbb9, []int{1} } + func (m *StartResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_StartResponse.Unmarshal(m, b) } func (m *StartResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_StartResponse.Marshal(b, m, deterministic) } -func (dst *StartResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_StartResponse.Merge(dst, src) +func (m *StartResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_StartResponse.Merge(m, src) } func (m *StartResponse) XXX_Size() int { return xxx_messageInfo_StartResponse.Size(m) @@ -102,16 +106,17 @@ func (m *ShutdownRequest) Reset() { *m = ShutdownRequest{} } func (m *ShutdownRequest) String() string { return proto.CompactTextString(m) } func (*ShutdownRequest) ProtoMessage() {} func (*ShutdownRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_mysqlctl_6cf72a3618d6fe7c, []int{2} + return fileDescriptor_cd8c110e42f9cbb9, []int{2} } + func (m *ShutdownRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ShutdownRequest.Unmarshal(m, b) } func (m *ShutdownRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_ShutdownRequest.Marshal(b, m, deterministic) } -func (dst *ShutdownRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_ShutdownRequest.Merge(dst, src) +func (m *ShutdownRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_ShutdownRequest.Merge(m, src) } func (m *ShutdownRequest) XXX_Size() int { return xxx_messageInfo_ShutdownRequest.Size(m) @@ -139,16 +144,17 @@ func (m *ShutdownResponse) Reset() { *m = ShutdownResponse{} } func (m *ShutdownResponse) String() string { return proto.CompactTextString(m) } func (*ShutdownResponse) ProtoMessage() {} func (*ShutdownResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_mysqlctl_6cf72a3618d6fe7c, []int{3} + return fileDescriptor_cd8c110e42f9cbb9, []int{3} } + func (m *ShutdownResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ShutdownResponse.Unmarshal(m, b) } func (m *ShutdownResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_ShutdownResponse.Marshal(b, m, deterministic) } -func (dst *ShutdownResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_ShutdownResponse.Merge(dst, src) +func (m *ShutdownResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_ShutdownResponse.Merge(m, src) } func (m *ShutdownResponse) XXX_Size() int { return xxx_messageInfo_ShutdownResponse.Size(m) @@ -169,16 +175,17 @@ func (m *RunMysqlUpgradeRequest) Reset() { *m = RunMysqlUpgradeRequest{} func (m *RunMysqlUpgradeRequest) String() string { return proto.CompactTextString(m) } func (*RunMysqlUpgradeRequest) ProtoMessage() {} func (*RunMysqlUpgradeRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_mysqlctl_6cf72a3618d6fe7c, []int{4} + return fileDescriptor_cd8c110e42f9cbb9, []int{4} } + func (m *RunMysqlUpgradeRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_RunMysqlUpgradeRequest.Unmarshal(m, b) } func (m *RunMysqlUpgradeRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_RunMysqlUpgradeRequest.Marshal(b, m, deterministic) } -func (dst *RunMysqlUpgradeRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_RunMysqlUpgradeRequest.Merge(dst, src) +func (m *RunMysqlUpgradeRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_RunMysqlUpgradeRequest.Merge(m, src) } func (m *RunMysqlUpgradeRequest) XXX_Size() int { return xxx_messageInfo_RunMysqlUpgradeRequest.Size(m) @@ -199,16 +206,17 @@ func (m *RunMysqlUpgradeResponse) Reset() { *m = RunMysqlUpgradeResponse func (m *RunMysqlUpgradeResponse) String() string { return proto.CompactTextString(m) } func (*RunMysqlUpgradeResponse) ProtoMessage() {} func (*RunMysqlUpgradeResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_mysqlctl_6cf72a3618d6fe7c, []int{5} + return fileDescriptor_cd8c110e42f9cbb9, []int{5} } + func (m *RunMysqlUpgradeResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_RunMysqlUpgradeResponse.Unmarshal(m, b) } func (m *RunMysqlUpgradeResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_RunMysqlUpgradeResponse.Marshal(b, m, deterministic) } -func (dst *RunMysqlUpgradeResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_RunMysqlUpgradeResponse.Merge(dst, src) +func (m *RunMysqlUpgradeResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_RunMysqlUpgradeResponse.Merge(m, src) } func (m *RunMysqlUpgradeResponse) XXX_Size() int { return xxx_messageInfo_RunMysqlUpgradeResponse.Size(m) @@ -229,16 +237,17 @@ func (m *ReinitConfigRequest) Reset() { *m = ReinitConfigRequest{} } func (m *ReinitConfigRequest) String() string { return proto.CompactTextString(m) } func (*ReinitConfigRequest) ProtoMessage() {} func (*ReinitConfigRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_mysqlctl_6cf72a3618d6fe7c, []int{6} + return fileDescriptor_cd8c110e42f9cbb9, []int{6} } + func (m *ReinitConfigRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ReinitConfigRequest.Unmarshal(m, b) } func (m *ReinitConfigRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_ReinitConfigRequest.Marshal(b, m, deterministic) } -func (dst *ReinitConfigRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_ReinitConfigRequest.Merge(dst, src) +func (m *ReinitConfigRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_ReinitConfigRequest.Merge(m, src) } func (m *ReinitConfigRequest) XXX_Size() int { return xxx_messageInfo_ReinitConfigRequest.Size(m) @@ -259,16 +268,17 @@ func (m *ReinitConfigResponse) Reset() { *m = ReinitConfigResponse{} } func (m *ReinitConfigResponse) String() string { return proto.CompactTextString(m) } func (*ReinitConfigResponse) ProtoMessage() {} func (*ReinitConfigResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_mysqlctl_6cf72a3618d6fe7c, []int{7} + return fileDescriptor_cd8c110e42f9cbb9, []int{7} } + func (m *ReinitConfigResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ReinitConfigResponse.Unmarshal(m, b) } func (m *ReinitConfigResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_ReinitConfigResponse.Marshal(b, m, deterministic) } -func (dst *ReinitConfigResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_ReinitConfigResponse.Merge(dst, src) +func (m *ReinitConfigResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_ReinitConfigResponse.Merge(m, src) } func (m *ReinitConfigResponse) XXX_Size() int { return xxx_messageInfo_ReinitConfigResponse.Size(m) @@ -289,16 +299,17 @@ func (m *RefreshConfigRequest) Reset() { *m = RefreshConfigRequest{} } func (m *RefreshConfigRequest) String() string { return proto.CompactTextString(m) } func (*RefreshConfigRequest) ProtoMessage() {} func (*RefreshConfigRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_mysqlctl_6cf72a3618d6fe7c, []int{8} + return fileDescriptor_cd8c110e42f9cbb9, []int{8} } + func (m *RefreshConfigRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_RefreshConfigRequest.Unmarshal(m, b) } func (m *RefreshConfigRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_RefreshConfigRequest.Marshal(b, m, deterministic) } -func (dst *RefreshConfigRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_RefreshConfigRequest.Merge(dst, src) +func (m *RefreshConfigRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_RefreshConfigRequest.Merge(m, src) } func (m *RefreshConfigRequest) XXX_Size() int { return xxx_messageInfo_RefreshConfigRequest.Size(m) @@ -319,16 +330,17 @@ func (m *RefreshConfigResponse) Reset() { *m = RefreshConfigResponse{} } func (m *RefreshConfigResponse) String() string { return proto.CompactTextString(m) } func (*RefreshConfigResponse) ProtoMessage() {} func (*RefreshConfigResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_mysqlctl_6cf72a3618d6fe7c, []int{9} + return fileDescriptor_cd8c110e42f9cbb9, []int{9} } + func (m *RefreshConfigResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_RefreshConfigResponse.Unmarshal(m, b) } func (m *RefreshConfigResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_RefreshConfigResponse.Marshal(b, m, deterministic) } -func (dst *RefreshConfigResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_RefreshConfigResponse.Merge(dst, src) +func (m *RefreshConfigResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_RefreshConfigResponse.Merge(m, src) } func (m *RefreshConfigResponse) XXX_Size() int { return xxx_messageInfo_RefreshConfigResponse.Size(m) @@ -352,6 +364,34 @@ func init() { proto.RegisterType((*RefreshConfigResponse)(nil), "mysqlctl.RefreshConfigResponse") } +func init() { proto.RegisterFile("mysqlctl.proto", fileDescriptor_cd8c110e42f9cbb9) } + +var fileDescriptor_cd8c110e42f9cbb9 = []byte{ + // 339 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x92, 0x4d, 0x4f, 0xfa, 0x30, + 0x1c, 0xc7, 0xff, 0x84, 0xfc, 0xcd, 0xfc, 0x09, 0xce, 0x54, 0x79, 0x6a, 0xa2, 0xe0, 0x12, 0x95, + 0x13, 0x4d, 0xf4, 0xa4, 0x37, 0x25, 0xf1, 0x66, 0x4c, 0x4a, 0x4c, 0x8c, 0x17, 0x32, 0xa5, 0x8c, + 0x26, 0xb8, 0x42, 0x5b, 0x20, 0xbe, 0x05, 0x5f, 0xb5, 0xb1, 0x6b, 0xc7, 0xc6, 0xc0, 0xdb, 0xfa, + 0x7d, 0x6a, 0xf6, 0xd9, 0xe0, 0xf0, 0xf3, 0x4b, 0xcd, 0xa7, 0x1f, 0x7a, 0xda, 0x9b, 0x49, 0xa1, + 0x05, 0xf2, 0xdc, 0x39, 0x20, 0x50, 0x19, 0xe8, 0x50, 0x6a, 0xca, 0xe6, 0x0b, 0xa6, 0x34, 0x6a, + 0xc3, 0x81, 0xf1, 0x46, 0xc3, 0x50, 0x46, 0xaa, 0x59, 0xea, 0x94, 0xbb, 0xfb, 0x14, 0x12, 0xe9, + 0x5e, 0x46, 0x2a, 0xf0, 0xa1, 0x6a, 0x0b, 0x6a, 0x26, 0x62, 0xc5, 0x82, 0x5b, 0xf0, 0x07, 0x93, + 0x85, 0x1e, 0x89, 0x55, 0xec, 0x46, 0x2e, 0xc1, 0x5f, 0x85, 0x5c, 0x0f, 0xc7, 0x42, 0x0e, 0x93, + 0x6a, 0xb3, 0xd4, 0x29, 0x75, 0x3d, 0x5a, 0xfd, 0x95, 0x1f, 0x85, 0x7c, 0x32, 0x62, 0x80, 0xe0, + 0x68, 0x5d, 0xb5, 0x73, 0x4d, 0xa8, 0xd3, 0x45, 0x6c, 0x02, 0x2f, 0xb3, 0x48, 0x86, 0x23, 0x66, + 0x57, 0x83, 0x16, 0x34, 0x0a, 0x8e, 0x2d, 0xd5, 0xe0, 0x98, 0x32, 0x1e, 0x73, 0xdd, 0x17, 0xf1, + 0x98, 0x47, 0xae, 0x51, 0x87, 0x93, 0xbc, 0x6c, 0xe3, 0x46, 0x1f, 0x4b, 0xa6, 0x26, 0xf9, 0x7c, + 0x03, 0x6a, 0x1b, 0x7a, 0x52, 0xb8, 0xfe, 0x2e, 0x83, 0x67, 0x2e, 0xee, 0xeb, 0x29, 0xba, 0x83, + 0xff, 0x86, 0x00, 0xaa, 0xf7, 0x52, 0xac, 0x59, 0x86, 0xb8, 0x51, 0xd0, 0xed, 0xbd, 0xff, 0x50, + 0x1f, 0x3c, 0xf7, 0xc6, 0xa8, 0x95, 0x89, 0xe5, 0x01, 0x62, 0xbc, 0xcd, 0x4a, 0x47, 0x5e, 0xc1, + 0xdf, 0x00, 0x81, 0x3a, 0xeb, 0xc2, 0x76, 0x7a, 0xf8, 0xfc, 0x8f, 0x44, 0xba, 0xfc, 0x0c, 0x95, + 0x2c, 0x30, 0x74, 0x9a, 0x29, 0x15, 0xf9, 0xe2, 0xb3, 0x5d, 0x76, 0x3a, 0x48, 0xa1, 0x9a, 0x23, + 0x8a, 0x72, 0x95, 0xe2, 0x27, 0xc0, 0xed, 0x9d, 0xbe, 0xdb, 0x7c, 0xb8, 0x7a, 0xbb, 0x58, 0x72, + 0xcd, 0x94, 0xea, 0x71, 0x41, 0x92, 0x27, 0x12, 0x09, 0xb2, 0xd4, 0xc4, 0xfc, 0xdc, 0xc4, 0x0d, + 0xbc, 0xef, 0x99, 0xf3, 0xcd, 0x4f, 0x00, 0x00, 0x00, 0xff, 0xff, 0xb8, 0xe2, 0x15, 0x86, 0xfe, + 0x02, 0x00, 0x00, +} + // Reference imports to suppress errors if they are not otherwise used. var _ context.Context var _ grpc.ClientConn @@ -433,6 +473,26 @@ type MysqlCtlServer interface { RefreshConfig(context.Context, *RefreshConfigRequest) (*RefreshConfigResponse, error) } +// UnimplementedMysqlCtlServer can be embedded to have forward compatible implementations. +type UnimplementedMysqlCtlServer struct { +} + +func (*UnimplementedMysqlCtlServer) Start(ctx context.Context, req *StartRequest) (*StartResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Start not implemented") +} +func (*UnimplementedMysqlCtlServer) Shutdown(ctx context.Context, req *ShutdownRequest) (*ShutdownResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Shutdown not implemented") +} +func (*UnimplementedMysqlCtlServer) RunMysqlUpgrade(ctx context.Context, req *RunMysqlUpgradeRequest) (*RunMysqlUpgradeResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method RunMysqlUpgrade not implemented") +} +func (*UnimplementedMysqlCtlServer) ReinitConfig(ctx context.Context, req *ReinitConfigRequest) (*ReinitConfigResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ReinitConfig not implemented") +} +func (*UnimplementedMysqlCtlServer) RefreshConfig(ctx context.Context, req *RefreshConfigRequest) (*RefreshConfigResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method RefreshConfig not implemented") +} + func RegisterMysqlCtlServer(s *grpc.Server, srv MysqlCtlServer) { s.RegisterService(&_MysqlCtl_serviceDesc, srv) } @@ -555,31 +615,3 @@ var _MysqlCtl_serviceDesc = grpc.ServiceDesc{ Streams: []grpc.StreamDesc{}, Metadata: "mysqlctl.proto", } - -func init() { proto.RegisterFile("mysqlctl.proto", fileDescriptor_mysqlctl_6cf72a3618d6fe7c) } - -var fileDescriptor_mysqlctl_6cf72a3618d6fe7c = []byte{ - // 339 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x92, 0x4d, 0x4f, 0xfa, 0x30, - 0x1c, 0xc7, 0xff, 0x84, 0xfc, 0xcd, 0xfc, 0x09, 0xce, 0x54, 0x79, 0x6a, 0xa2, 0xe0, 0x12, 0x95, - 0x13, 0x4d, 0xf4, 0xa4, 0x37, 0x25, 0xf1, 0x66, 0x4c, 0x4a, 0x4c, 0x8c, 0x17, 0x32, 0xa5, 0x8c, - 0x26, 0xb8, 0x42, 0x5b, 0x20, 0xbe, 0x05, 0x5f, 0xb5, 0xb1, 0x6b, 0xc7, 0xc6, 0xc0, 0xdb, 0xfa, - 0x7d, 0x6a, 0xf6, 0xd9, 0xe0, 0xf0, 0xf3, 0x4b, 0xcd, 0xa7, 0x1f, 0x7a, 0xda, 0x9b, 0x49, 0xa1, - 0x05, 0xf2, 0xdc, 0x39, 0x20, 0x50, 0x19, 0xe8, 0x50, 0x6a, 0xca, 0xe6, 0x0b, 0xa6, 0x34, 0x6a, - 0xc3, 0x81, 0xf1, 0x46, 0xc3, 0x50, 0x46, 0xaa, 0x59, 0xea, 0x94, 0xbb, 0xfb, 0x14, 0x12, 0xe9, - 0x5e, 0x46, 0x2a, 0xf0, 0xa1, 0x6a, 0x0b, 0x6a, 0x26, 0x62, 0xc5, 0x82, 0x5b, 0xf0, 0x07, 0x93, - 0x85, 0x1e, 0x89, 0x55, 0xec, 0x46, 0x2e, 0xc1, 0x5f, 0x85, 0x5c, 0x0f, 0xc7, 0x42, 0x0e, 0x93, - 0x6a, 0xb3, 0xd4, 0x29, 0x75, 0x3d, 0x5a, 0xfd, 0x95, 0x1f, 0x85, 0x7c, 0x32, 0x62, 0x80, 0xe0, - 0x68, 0x5d, 0xb5, 0x73, 0x4d, 0xa8, 0xd3, 0x45, 0x6c, 0x02, 0x2f, 0xb3, 0x48, 0x86, 0x23, 0x66, - 0x57, 0x83, 0x16, 0x34, 0x0a, 0x8e, 0x2d, 0xd5, 0xe0, 0x98, 0x32, 0x1e, 0x73, 0xdd, 0x17, 0xf1, - 0x98, 0x47, 0xae, 0x51, 0x87, 0x93, 0xbc, 0x6c, 0xe3, 0x46, 0x1f, 0x4b, 0xa6, 0x26, 0xf9, 0x7c, - 0x03, 0x6a, 0x1b, 0x7a, 0x52, 0xb8, 0xfe, 0x2e, 0x83, 0x67, 0x2e, 0xee, 0xeb, 0x29, 0xba, 0x83, - 0xff, 0x86, 0x00, 0xaa, 0xf7, 0x52, 0xac, 0x59, 0x86, 0xb8, 0x51, 0xd0, 0xed, 0xbd, 0xff, 0x50, - 0x1f, 0x3c, 0xf7, 0xc6, 0xa8, 0x95, 0x89, 0xe5, 0x01, 0x62, 0xbc, 0xcd, 0x4a, 0x47, 0x5e, 0xc1, - 0xdf, 0x00, 0x81, 0x3a, 0xeb, 0xc2, 0x76, 0x7a, 0xf8, 0xfc, 0x8f, 0x44, 0xba, 0xfc, 0x0c, 0x95, - 0x2c, 0x30, 0x74, 0x9a, 0x29, 0x15, 0xf9, 0xe2, 0xb3, 0x5d, 0x76, 0x3a, 0x48, 0xa1, 0x9a, 0x23, - 0x8a, 0x72, 0x95, 0xe2, 0x27, 0xc0, 0xed, 0x9d, 0xbe, 0xdb, 0x7c, 0xb8, 0x7a, 0xbb, 0x58, 0x72, - 0xcd, 0x94, 0xea, 0x71, 0x41, 0x92, 0x27, 0x12, 0x09, 0xb2, 0xd4, 0xc4, 0xfc, 0xdc, 0xc4, 0x0d, - 0xbc, 0xef, 0x99, 0xf3, 0xcd, 0x4f, 0x00, 0x00, 0x00, 0xff, 0xff, 0xb8, 0xe2, 0x15, 0x86, 0xfe, - 0x02, 0x00, 0x00, -} diff --git a/go/vt/proto/query/query.pb.go b/go/vt/proto/query/query.pb.go index ec8b4f71ab7..d536cc1c24c 100644 --- a/go/vt/proto/query/query.pb.go +++ b/go/vt/proto/query/query.pb.go @@ -1,13 +1,16 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // source: query.proto -package query // import "vitess.io/vitess/go/vt/proto/query" +package query -import proto "github.com/golang/protobuf/proto" -import fmt "fmt" -import math "math" -import topodata "vitess.io/vitess/go/vt/proto/topodata" -import vtrpc "vitess.io/vitess/go/vt/proto/vtrpc" +import ( + fmt "fmt" + math "math" + + proto "github.com/golang/protobuf/proto" + topodata "vitess.io/vitess/go/vt/proto/topodata" + vtrpc "vitess.io/vitess/go/vt/proto/vtrpc" +) // Reference imports to suppress errors if they are not otherwise used. var _ = proto.Marshal @@ -18,7 +21,7 @@ var _ = math.Inf // is compatible with the proto package it is being compiled against. // A compilation error at this line likely means your copy of the // proto package needs to be updated. -const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package +const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package // Flags sent from the MySQL C API type MySqlFlag int32 @@ -68,6 +71,7 @@ var MySqlFlag_name = map[int32]string{ 65536: "UNIQUE_FLAG", 131072: "BINCMP_FLAG", } + var MySqlFlag_value = map[string]int32{ "EMPTY": 0, "NOT_NULL_FLAG": 1, @@ -94,8 +98,9 @@ var MySqlFlag_value = map[string]int32{ func (x MySqlFlag) String() string { return proto.EnumName(MySqlFlag_name, int32(x)) } + func (MySqlFlag) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_query_1f9acea6b6c417bb, []int{0} + return fileDescriptor_5c6ac9b241082464, []int{0} } // Flag allows us to qualify types by their common properties. @@ -120,6 +125,7 @@ var Flag_name = map[int32]string{ 4096: "ISTEXT", 8192: "ISBINARY", } + var Flag_value = map[string]int32{ "NONE": 0, "ISINTEGRAL": 256, @@ -133,8 +139,9 @@ var Flag_value = map[string]int32{ func (x Flag) String() string { return proto.EnumName(Flag_name, int32(x)) } + func (Flag) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_query_1f9acea6b6c417bb, []int{1} + return fileDescriptor_5c6ac9b241082464, []int{1} } // Type defines the various supported data types in bind vars @@ -276,6 +283,7 @@ var Type_name = map[int32]string{ 2078: "JSON", 31: "EXPRESSION", } + var Type_value = map[string]int32{ "NULL_TYPE": 0, "INT8": 257, @@ -314,8 +322,9 @@ var Type_value = map[string]int32{ func (x Type) String() string { return proto.EnumName(Type_name, int32(x)) } + func (Type) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_query_1f9acea6b6c417bb, []int{2} + return fileDescriptor_5c6ac9b241082464, []int{2} } // TransactionState represents the state of a distributed transaction. @@ -334,6 +343,7 @@ var TransactionState_name = map[int32]string{ 2: "COMMIT", 3: "ROLLBACK", } + var TransactionState_value = map[string]int32{ "UNKNOWN": 0, "PREPARE": 1, @@ -344,8 +354,9 @@ var TransactionState_value = map[string]int32{ func (x TransactionState) String() string { return proto.EnumName(TransactionState_name, int32(x)) } + func (TransactionState) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_query_1f9acea6b6c417bb, []int{3} + return fileDescriptor_5c6ac9b241082464, []int{3} } type ExecuteOptions_IncludedFields int32 @@ -361,6 +372,7 @@ var ExecuteOptions_IncludedFields_name = map[int32]string{ 1: "TYPE_ONLY", 2: "ALL", } + var ExecuteOptions_IncludedFields_value = map[string]int32{ "TYPE_AND_NAME": 0, "TYPE_ONLY": 1, @@ -370,8 +382,9 @@ var ExecuteOptions_IncludedFields_value = map[string]int32{ func (x ExecuteOptions_IncludedFields) String() string { return proto.EnumName(ExecuteOptions_IncludedFields_name, int32(x)) } + func (ExecuteOptions_IncludedFields) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_query_1f9acea6b6c417bb, []int{6, 0} + return fileDescriptor_5c6ac9b241082464, []int{6, 0} } type ExecuteOptions_Workload int32 @@ -389,6 +402,7 @@ var ExecuteOptions_Workload_name = map[int32]string{ 2: "OLAP", 3: "DBA", } + var ExecuteOptions_Workload_value = map[string]int32{ "UNSPECIFIED": 0, "OLTP": 1, @@ -399,8 +413,9 @@ var ExecuteOptions_Workload_value = map[string]int32{ func (x ExecuteOptions_Workload) String() string { return proto.EnumName(ExecuteOptions_Workload_name, int32(x)) } + func (ExecuteOptions_Workload) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_query_1f9acea6b6c417bb, []int{6, 1} + return fileDescriptor_5c6ac9b241082464, []int{6, 1} } type ExecuteOptions_TransactionIsolation int32 @@ -428,6 +443,7 @@ var ExecuteOptions_TransactionIsolation_name = map[int32]string{ 5: "CONSISTENT_SNAPSHOT_READ_ONLY", 6: "AUTOCOMMIT", } + var ExecuteOptions_TransactionIsolation_value = map[string]int32{ "DEFAULT": 0, "REPEATABLE_READ": 1, @@ -441,8 +457,9 @@ var ExecuteOptions_TransactionIsolation_value = map[string]int32{ func (x ExecuteOptions_TransactionIsolation) String() string { return proto.EnumName(ExecuteOptions_TransactionIsolation_name, int32(x)) } + func (ExecuteOptions_TransactionIsolation) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_query_1f9acea6b6c417bb, []int{6, 2} + return fileDescriptor_5c6ac9b241082464, []int{6, 2} } // The category of one statement. @@ -459,6 +476,7 @@ var StreamEvent_Statement_Category_name = map[int32]string{ 1: "DML", 2: "DDL", } + var StreamEvent_Statement_Category_value = map[string]int32{ "Error": 0, "DML": 1, @@ -468,8 +486,9 @@ var StreamEvent_Statement_Category_value = map[string]int32{ func (x StreamEvent_Statement_Category) String() string { return proto.EnumName(StreamEvent_Statement_Category_name, int32(x)) } + func (StreamEvent_Statement_Category) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_query_1f9acea6b6c417bb, []int{12, 0, 0} + return fileDescriptor_5c6ac9b241082464, []int{12, 0, 0} } type SplitQueryRequest_Algorithm int32 @@ -483,6 +502,7 @@ var SplitQueryRequest_Algorithm_name = map[int32]string{ 0: "EQUAL_SPLITS", 1: "FULL_SCAN", } + var SplitQueryRequest_Algorithm_value = map[string]int32{ "EQUAL_SPLITS": 0, "FULL_SCAN": 1, @@ -491,8 +511,9 @@ var SplitQueryRequest_Algorithm_value = map[string]int32{ func (x SplitQueryRequest_Algorithm) String() string { return proto.EnumName(SplitQueryRequest_Algorithm_name, int32(x)) } + func (SplitQueryRequest_Algorithm) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_query_1f9acea6b6c417bb, []int{50, 0} + return fileDescriptor_5c6ac9b241082464, []int{50, 0} } // Target describes what the client expects the tablet is. @@ -513,16 +534,17 @@ func (m *Target) Reset() { *m = Target{} } func (m *Target) String() string { return proto.CompactTextString(m) } func (*Target) ProtoMessage() {} func (*Target) Descriptor() ([]byte, []int) { - return fileDescriptor_query_1f9acea6b6c417bb, []int{0} + return fileDescriptor_5c6ac9b241082464, []int{0} } + func (m *Target) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Target.Unmarshal(m, b) } func (m *Target) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_Target.Marshal(b, m, deterministic) } -func (dst *Target) XXX_Merge(src proto.Message) { - xxx_messageInfo_Target.Merge(dst, src) +func (m *Target) XXX_Merge(src proto.Message) { + xxx_messageInfo_Target.Merge(m, src) } func (m *Target) XXX_Size() int { return xxx_messageInfo_Target.Size(m) @@ -581,16 +603,17 @@ func (m *VTGateCallerID) Reset() { *m = VTGateCallerID{} } func (m *VTGateCallerID) String() string { return proto.CompactTextString(m) } func (*VTGateCallerID) ProtoMessage() {} func (*VTGateCallerID) Descriptor() ([]byte, []int) { - return fileDescriptor_query_1f9acea6b6c417bb, []int{1} + return fileDescriptor_5c6ac9b241082464, []int{1} } + func (m *VTGateCallerID) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_VTGateCallerID.Unmarshal(m, b) } func (m *VTGateCallerID) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_VTGateCallerID.Marshal(b, m, deterministic) } -func (dst *VTGateCallerID) XXX_Merge(src proto.Message) { - xxx_messageInfo_VTGateCallerID.Merge(dst, src) +func (m *VTGateCallerID) XXX_Merge(src proto.Message) { + xxx_messageInfo_VTGateCallerID.Merge(m, src) } func (m *VTGateCallerID) XXX_Size() int { return xxx_messageInfo_VTGateCallerID.Size(m) @@ -637,16 +660,17 @@ func (m *EventToken) Reset() { *m = EventToken{} } func (m *EventToken) String() string { return proto.CompactTextString(m) } func (*EventToken) ProtoMessage() {} func (*EventToken) Descriptor() ([]byte, []int) { - return fileDescriptor_query_1f9acea6b6c417bb, []int{2} + return fileDescriptor_5c6ac9b241082464, []int{2} } + func (m *EventToken) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_EventToken.Unmarshal(m, b) } func (m *EventToken) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_EventToken.Marshal(b, m, deterministic) } -func (dst *EventToken) XXX_Merge(src proto.Message) { - xxx_messageInfo_EventToken.Merge(dst, src) +func (m *EventToken) XXX_Merge(src proto.Message) { + xxx_messageInfo_EventToken.Merge(m, src) } func (m *EventToken) XXX_Size() int { return xxx_messageInfo_EventToken.Size(m) @@ -691,16 +715,17 @@ func (m *Value) Reset() { *m = Value{} } func (m *Value) String() string { return proto.CompactTextString(m) } func (*Value) ProtoMessage() {} func (*Value) Descriptor() ([]byte, []int) { - return fileDescriptor_query_1f9acea6b6c417bb, []int{3} + return fileDescriptor_5c6ac9b241082464, []int{3} } + func (m *Value) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Value.Unmarshal(m, b) } func (m *Value) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_Value.Marshal(b, m, deterministic) } -func (dst *Value) XXX_Merge(src proto.Message) { - xxx_messageInfo_Value.Merge(dst, src) +func (m *Value) XXX_Merge(src proto.Message) { + xxx_messageInfo_Value.Merge(m, src) } func (m *Value) XXX_Size() int { return xxx_messageInfo_Value.Size(m) @@ -740,16 +765,17 @@ func (m *BindVariable) Reset() { *m = BindVariable{} } func (m *BindVariable) String() string { return proto.CompactTextString(m) } func (*BindVariable) ProtoMessage() {} func (*BindVariable) Descriptor() ([]byte, []int) { - return fileDescriptor_query_1f9acea6b6c417bb, []int{4} + return fileDescriptor_5c6ac9b241082464, []int{4} } + func (m *BindVariable) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_BindVariable.Unmarshal(m, b) } func (m *BindVariable) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_BindVariable.Marshal(b, m, deterministic) } -func (dst *BindVariable) XXX_Merge(src proto.Message) { - xxx_messageInfo_BindVariable.Merge(dst, src) +func (m *BindVariable) XXX_Merge(src proto.Message) { + xxx_messageInfo_BindVariable.Merge(m, src) } func (m *BindVariable) XXX_Size() int { return xxx_messageInfo_BindVariable.Size(m) @@ -797,16 +823,17 @@ func (m *BoundQuery) Reset() { *m = BoundQuery{} } func (m *BoundQuery) String() string { return proto.CompactTextString(m) } func (*BoundQuery) ProtoMessage() {} func (*BoundQuery) Descriptor() ([]byte, []int) { - return fileDescriptor_query_1f9acea6b6c417bb, []int{5} + return fileDescriptor_5c6ac9b241082464, []int{5} } + func (m *BoundQuery) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_BoundQuery.Unmarshal(m, b) } func (m *BoundQuery) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_BoundQuery.Marshal(b, m, deterministic) } -func (dst *BoundQuery) XXX_Merge(src proto.Message) { - xxx_messageInfo_BoundQuery.Merge(dst, src) +func (m *BoundQuery) XXX_Merge(src proto.Message) { + xxx_messageInfo_BoundQuery.Merge(m, src) } func (m *BoundQuery) XXX_Size() int { return xxx_messageInfo_BoundQuery.Size(m) @@ -871,16 +898,17 @@ func (m *ExecuteOptions) Reset() { *m = ExecuteOptions{} } func (m *ExecuteOptions) String() string { return proto.CompactTextString(m) } func (*ExecuteOptions) ProtoMessage() {} func (*ExecuteOptions) Descriptor() ([]byte, []int) { - return fileDescriptor_query_1f9acea6b6c417bb, []int{6} + return fileDescriptor_5c6ac9b241082464, []int{6} } + func (m *ExecuteOptions) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ExecuteOptions.Unmarshal(m, b) } func (m *ExecuteOptions) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_ExecuteOptions.Marshal(b, m, deterministic) } -func (dst *ExecuteOptions) XXX_Merge(src proto.Message) { - xxx_messageInfo_ExecuteOptions.Merge(dst, src) +func (m *ExecuteOptions) XXX_Merge(src proto.Message) { + xxx_messageInfo_ExecuteOptions.Merge(m, src) } func (m *ExecuteOptions) XXX_Size() int { return xxx_messageInfo_ExecuteOptions.Size(m) @@ -977,16 +1005,17 @@ func (m *Field) Reset() { *m = Field{} } func (m *Field) String() string { return proto.CompactTextString(m) } func (*Field) ProtoMessage() {} func (*Field) Descriptor() ([]byte, []int) { - return fileDescriptor_query_1f9acea6b6c417bb, []int{7} + return fileDescriptor_5c6ac9b241082464, []int{7} } + func (m *Field) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Field.Unmarshal(m, b) } func (m *Field) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_Field.Marshal(b, m, deterministic) } -func (dst *Field) XXX_Merge(src proto.Message) { - xxx_messageInfo_Field.Merge(dst, src) +func (m *Field) XXX_Merge(src proto.Message) { + xxx_messageInfo_Field.Merge(m, src) } func (m *Field) XXX_Size() int { return xxx_messageInfo_Field.Size(m) @@ -1085,16 +1114,17 @@ func (m *Row) Reset() { *m = Row{} } func (m *Row) String() string { return proto.CompactTextString(m) } func (*Row) ProtoMessage() {} func (*Row) Descriptor() ([]byte, []int) { - return fileDescriptor_query_1f9acea6b6c417bb, []int{8} + return fileDescriptor_5c6ac9b241082464, []int{8} } + func (m *Row) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Row.Unmarshal(m, b) } func (m *Row) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_Row.Marshal(b, m, deterministic) } -func (dst *Row) XXX_Merge(src proto.Message) { - xxx_messageInfo_Row.Merge(dst, src) +func (m *Row) XXX_Merge(src proto.Message) { + xxx_messageInfo_Row.Merge(m, src) } func (m *Row) XXX_Size() int { return xxx_messageInfo_Row.Size(m) @@ -1137,16 +1167,17 @@ func (m *ResultExtras) Reset() { *m = ResultExtras{} } func (m *ResultExtras) String() string { return proto.CompactTextString(m) } func (*ResultExtras) ProtoMessage() {} func (*ResultExtras) Descriptor() ([]byte, []int) { - return fileDescriptor_query_1f9acea6b6c417bb, []int{9} + return fileDescriptor_5c6ac9b241082464, []int{9} } + func (m *ResultExtras) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ResultExtras.Unmarshal(m, b) } func (m *ResultExtras) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_ResultExtras.Marshal(b, m, deterministic) } -func (dst *ResultExtras) XXX_Merge(src proto.Message) { - xxx_messageInfo_ResultExtras.Merge(dst, src) +func (m *ResultExtras) XXX_Merge(src proto.Message) { + xxx_messageInfo_ResultExtras.Merge(m, src) } func (m *ResultExtras) XXX_Size() int { return xxx_messageInfo_ResultExtras.Size(m) @@ -1195,16 +1226,17 @@ func (m *QueryResult) Reset() { *m = QueryResult{} } func (m *QueryResult) String() string { return proto.CompactTextString(m) } func (*QueryResult) ProtoMessage() {} func (*QueryResult) Descriptor() ([]byte, []int) { - return fileDescriptor_query_1f9acea6b6c417bb, []int{10} + return fileDescriptor_5c6ac9b241082464, []int{10} } + func (m *QueryResult) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_QueryResult.Unmarshal(m, b) } func (m *QueryResult) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_QueryResult.Marshal(b, m, deterministic) } -func (dst *QueryResult) XXX_Merge(src proto.Message) { - xxx_messageInfo_QueryResult.Merge(dst, src) +func (m *QueryResult) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryResult.Merge(m, src) } func (m *QueryResult) XXX_Size() int { return xxx_messageInfo_QueryResult.Size(m) @@ -1264,16 +1296,17 @@ func (m *QueryWarning) Reset() { *m = QueryWarning{} } func (m *QueryWarning) String() string { return proto.CompactTextString(m) } func (*QueryWarning) ProtoMessage() {} func (*QueryWarning) Descriptor() ([]byte, []int) { - return fileDescriptor_query_1f9acea6b6c417bb, []int{11} + return fileDescriptor_5c6ac9b241082464, []int{11} } + func (m *QueryWarning) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_QueryWarning.Unmarshal(m, b) } func (m *QueryWarning) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_QueryWarning.Marshal(b, m, deterministic) } -func (dst *QueryWarning) XXX_Merge(src proto.Message) { - xxx_messageInfo_QueryWarning.Merge(dst, src) +func (m *QueryWarning) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryWarning.Merge(m, src) } func (m *QueryWarning) XXX_Size() int { return xxx_messageInfo_QueryWarning.Size(m) @@ -1315,16 +1348,17 @@ func (m *StreamEvent) Reset() { *m = StreamEvent{} } func (m *StreamEvent) String() string { return proto.CompactTextString(m) } func (*StreamEvent) ProtoMessage() {} func (*StreamEvent) Descriptor() ([]byte, []int) { - return fileDescriptor_query_1f9acea6b6c417bb, []int{12} + return fileDescriptor_5c6ac9b241082464, []int{12} } + func (m *StreamEvent) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_StreamEvent.Unmarshal(m, b) } func (m *StreamEvent) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_StreamEvent.Marshal(b, m, deterministic) } -func (dst *StreamEvent) XXX_Merge(src proto.Message) { - xxx_messageInfo_StreamEvent.Merge(dst, src) +func (m *StreamEvent) XXX_Merge(src proto.Message) { + xxx_messageInfo_StreamEvent.Merge(m, src) } func (m *StreamEvent) XXX_Size() int { return xxx_messageInfo_StreamEvent.Size(m) @@ -1368,16 +1402,17 @@ func (m *StreamEvent_Statement) Reset() { *m = StreamEvent_Statement{} } func (m *StreamEvent_Statement) String() string { return proto.CompactTextString(m) } func (*StreamEvent_Statement) ProtoMessage() {} func (*StreamEvent_Statement) Descriptor() ([]byte, []int) { - return fileDescriptor_query_1f9acea6b6c417bb, []int{12, 0} + return fileDescriptor_5c6ac9b241082464, []int{12, 0} } + func (m *StreamEvent_Statement) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_StreamEvent_Statement.Unmarshal(m, b) } func (m *StreamEvent_Statement) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_StreamEvent_Statement.Marshal(b, m, deterministic) } -func (dst *StreamEvent_Statement) XXX_Merge(src proto.Message) { - xxx_messageInfo_StreamEvent_Statement.Merge(dst, src) +func (m *StreamEvent_Statement) XXX_Merge(src proto.Message) { + xxx_messageInfo_StreamEvent_Statement.Merge(m, src) } func (m *StreamEvent_Statement) XXX_Size() int { return xxx_messageInfo_StreamEvent_Statement.Size(m) @@ -1440,16 +1475,17 @@ func (m *ExecuteRequest) Reset() { *m = ExecuteRequest{} } func (m *ExecuteRequest) String() string { return proto.CompactTextString(m) } func (*ExecuteRequest) ProtoMessage() {} func (*ExecuteRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_query_1f9acea6b6c417bb, []int{13} + return fileDescriptor_5c6ac9b241082464, []int{13} } + func (m *ExecuteRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ExecuteRequest.Unmarshal(m, b) } func (m *ExecuteRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_ExecuteRequest.Marshal(b, m, deterministic) } -func (dst *ExecuteRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_ExecuteRequest.Merge(dst, src) +func (m *ExecuteRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_ExecuteRequest.Merge(m, src) } func (m *ExecuteRequest) XXX_Size() int { return xxx_messageInfo_ExecuteRequest.Size(m) @@ -1514,16 +1550,17 @@ func (m *ExecuteResponse) Reset() { *m = ExecuteResponse{} } func (m *ExecuteResponse) String() string { return proto.CompactTextString(m) } func (*ExecuteResponse) ProtoMessage() {} func (*ExecuteResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_query_1f9acea6b6c417bb, []int{14} + return fileDescriptor_5c6ac9b241082464, []int{14} } + func (m *ExecuteResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ExecuteResponse.Unmarshal(m, b) } func (m *ExecuteResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_ExecuteResponse.Marshal(b, m, deterministic) } -func (dst *ExecuteResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_ExecuteResponse.Merge(dst, src) +func (m *ExecuteResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_ExecuteResponse.Merge(m, src) } func (m *ExecuteResponse) XXX_Size() int { return xxx_messageInfo_ExecuteResponse.Size(m) @@ -1558,16 +1595,17 @@ func (m *ResultWithError) Reset() { *m = ResultWithError{} } func (m *ResultWithError) String() string { return proto.CompactTextString(m) } func (*ResultWithError) ProtoMessage() {} func (*ResultWithError) Descriptor() ([]byte, []int) { - return fileDescriptor_query_1f9acea6b6c417bb, []int{15} + return fileDescriptor_5c6ac9b241082464, []int{15} } + func (m *ResultWithError) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ResultWithError.Unmarshal(m, b) } func (m *ResultWithError) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_ResultWithError.Marshal(b, m, deterministic) } -func (dst *ResultWithError) XXX_Merge(src proto.Message) { - xxx_messageInfo_ResultWithError.Merge(dst, src) +func (m *ResultWithError) XXX_Merge(src proto.Message) { + xxx_messageInfo_ResultWithError.Merge(m, src) } func (m *ResultWithError) XXX_Size() int { return xxx_messageInfo_ResultWithError.Size(m) @@ -1610,16 +1648,17 @@ func (m *ExecuteBatchRequest) Reset() { *m = ExecuteBatchRequest{} } func (m *ExecuteBatchRequest) String() string { return proto.CompactTextString(m) } func (*ExecuteBatchRequest) ProtoMessage() {} func (*ExecuteBatchRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_query_1f9acea6b6c417bb, []int{16} + return fileDescriptor_5c6ac9b241082464, []int{16} } + func (m *ExecuteBatchRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ExecuteBatchRequest.Unmarshal(m, b) } func (m *ExecuteBatchRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_ExecuteBatchRequest.Marshal(b, m, deterministic) } -func (dst *ExecuteBatchRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_ExecuteBatchRequest.Merge(dst, src) +func (m *ExecuteBatchRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_ExecuteBatchRequest.Merge(m, src) } func (m *ExecuteBatchRequest) XXX_Size() int { return xxx_messageInfo_ExecuteBatchRequest.Size(m) @@ -1691,16 +1730,17 @@ func (m *ExecuteBatchResponse) Reset() { *m = ExecuteBatchResponse{} } func (m *ExecuteBatchResponse) String() string { return proto.CompactTextString(m) } func (*ExecuteBatchResponse) ProtoMessage() {} func (*ExecuteBatchResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_query_1f9acea6b6c417bb, []int{17} + return fileDescriptor_5c6ac9b241082464, []int{17} } + func (m *ExecuteBatchResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ExecuteBatchResponse.Unmarshal(m, b) } func (m *ExecuteBatchResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_ExecuteBatchResponse.Marshal(b, m, deterministic) } -func (dst *ExecuteBatchResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_ExecuteBatchResponse.Merge(dst, src) +func (m *ExecuteBatchResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_ExecuteBatchResponse.Merge(m, src) } func (m *ExecuteBatchResponse) XXX_Size() int { return xxx_messageInfo_ExecuteBatchResponse.Size(m) @@ -1735,16 +1775,17 @@ func (m *StreamExecuteRequest) Reset() { *m = StreamExecuteRequest{} } func (m *StreamExecuteRequest) String() string { return proto.CompactTextString(m) } func (*StreamExecuteRequest) ProtoMessage() {} func (*StreamExecuteRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_query_1f9acea6b6c417bb, []int{18} + return fileDescriptor_5c6ac9b241082464, []int{18} } + func (m *StreamExecuteRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_StreamExecuteRequest.Unmarshal(m, b) } func (m *StreamExecuteRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_StreamExecuteRequest.Marshal(b, m, deterministic) } -func (dst *StreamExecuteRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_StreamExecuteRequest.Merge(dst, src) +func (m *StreamExecuteRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_StreamExecuteRequest.Merge(m, src) } func (m *StreamExecuteRequest) XXX_Size() int { return xxx_messageInfo_StreamExecuteRequest.Size(m) @@ -1809,16 +1850,17 @@ func (m *StreamExecuteResponse) Reset() { *m = StreamExecuteResponse{} } func (m *StreamExecuteResponse) String() string { return proto.CompactTextString(m) } func (*StreamExecuteResponse) ProtoMessage() {} func (*StreamExecuteResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_query_1f9acea6b6c417bb, []int{19} + return fileDescriptor_5c6ac9b241082464, []int{19} } + func (m *StreamExecuteResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_StreamExecuteResponse.Unmarshal(m, b) } func (m *StreamExecuteResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_StreamExecuteResponse.Marshal(b, m, deterministic) } -func (dst *StreamExecuteResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_StreamExecuteResponse.Merge(dst, src) +func (m *StreamExecuteResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_StreamExecuteResponse.Merge(m, src) } func (m *StreamExecuteResponse) XXX_Size() int { return xxx_messageInfo_StreamExecuteResponse.Size(m) @@ -1851,16 +1893,17 @@ func (m *BeginRequest) Reset() { *m = BeginRequest{} } func (m *BeginRequest) String() string { return proto.CompactTextString(m) } func (*BeginRequest) ProtoMessage() {} func (*BeginRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_query_1f9acea6b6c417bb, []int{20} + return fileDescriptor_5c6ac9b241082464, []int{20} } + func (m *BeginRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_BeginRequest.Unmarshal(m, b) } func (m *BeginRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_BeginRequest.Marshal(b, m, deterministic) } -func (dst *BeginRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_BeginRequest.Merge(dst, src) +func (m *BeginRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_BeginRequest.Merge(m, src) } func (m *BeginRequest) XXX_Size() int { return xxx_messageInfo_BeginRequest.Size(m) @@ -1911,16 +1954,17 @@ func (m *BeginResponse) Reset() { *m = BeginResponse{} } func (m *BeginResponse) String() string { return proto.CompactTextString(m) } func (*BeginResponse) ProtoMessage() {} func (*BeginResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_query_1f9acea6b6c417bb, []int{21} + return fileDescriptor_5c6ac9b241082464, []int{21} } + func (m *BeginResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_BeginResponse.Unmarshal(m, b) } func (m *BeginResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_BeginResponse.Marshal(b, m, deterministic) } -func (dst *BeginResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_BeginResponse.Merge(dst, src) +func (m *BeginResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_BeginResponse.Merge(m, src) } func (m *BeginResponse) XXX_Size() int { return xxx_messageInfo_BeginResponse.Size(m) @@ -1953,16 +1997,17 @@ func (m *CommitRequest) Reset() { *m = CommitRequest{} } func (m *CommitRequest) String() string { return proto.CompactTextString(m) } func (*CommitRequest) ProtoMessage() {} func (*CommitRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_query_1f9acea6b6c417bb, []int{22} + return fileDescriptor_5c6ac9b241082464, []int{22} } + func (m *CommitRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_CommitRequest.Unmarshal(m, b) } func (m *CommitRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_CommitRequest.Marshal(b, m, deterministic) } -func (dst *CommitRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_CommitRequest.Merge(dst, src) +func (m *CommitRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_CommitRequest.Merge(m, src) } func (m *CommitRequest) XXX_Size() int { return xxx_messageInfo_CommitRequest.Size(m) @@ -2012,16 +2057,17 @@ func (m *CommitResponse) Reset() { *m = CommitResponse{} } func (m *CommitResponse) String() string { return proto.CompactTextString(m) } func (*CommitResponse) ProtoMessage() {} func (*CommitResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_query_1f9acea6b6c417bb, []int{23} + return fileDescriptor_5c6ac9b241082464, []int{23} } + func (m *CommitResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_CommitResponse.Unmarshal(m, b) } func (m *CommitResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_CommitResponse.Marshal(b, m, deterministic) } -func (dst *CommitResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_CommitResponse.Merge(dst, src) +func (m *CommitResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_CommitResponse.Merge(m, src) } func (m *CommitResponse) XXX_Size() int { return xxx_messageInfo_CommitResponse.Size(m) @@ -2047,16 +2093,17 @@ func (m *RollbackRequest) Reset() { *m = RollbackRequest{} } func (m *RollbackRequest) String() string { return proto.CompactTextString(m) } func (*RollbackRequest) ProtoMessage() {} func (*RollbackRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_query_1f9acea6b6c417bb, []int{24} + return fileDescriptor_5c6ac9b241082464, []int{24} } + func (m *RollbackRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_RollbackRequest.Unmarshal(m, b) } func (m *RollbackRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_RollbackRequest.Marshal(b, m, deterministic) } -func (dst *RollbackRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_RollbackRequest.Merge(dst, src) +func (m *RollbackRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_RollbackRequest.Merge(m, src) } func (m *RollbackRequest) XXX_Size() int { return xxx_messageInfo_RollbackRequest.Size(m) @@ -2106,16 +2153,17 @@ func (m *RollbackResponse) Reset() { *m = RollbackResponse{} } func (m *RollbackResponse) String() string { return proto.CompactTextString(m) } func (*RollbackResponse) ProtoMessage() {} func (*RollbackResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_query_1f9acea6b6c417bb, []int{25} + return fileDescriptor_5c6ac9b241082464, []int{25} } + func (m *RollbackResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_RollbackResponse.Unmarshal(m, b) } func (m *RollbackResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_RollbackResponse.Marshal(b, m, deterministic) } -func (dst *RollbackResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_RollbackResponse.Merge(dst, src) +func (m *RollbackResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_RollbackResponse.Merge(m, src) } func (m *RollbackResponse) XXX_Size() int { return xxx_messageInfo_RollbackResponse.Size(m) @@ -2142,16 +2190,17 @@ func (m *PrepareRequest) Reset() { *m = PrepareRequest{} } func (m *PrepareRequest) String() string { return proto.CompactTextString(m) } func (*PrepareRequest) ProtoMessage() {} func (*PrepareRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_query_1f9acea6b6c417bb, []int{26} + return fileDescriptor_5c6ac9b241082464, []int{26} } + func (m *PrepareRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_PrepareRequest.Unmarshal(m, b) } func (m *PrepareRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_PrepareRequest.Marshal(b, m, deterministic) } -func (dst *PrepareRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_PrepareRequest.Merge(dst, src) +func (m *PrepareRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_PrepareRequest.Merge(m, src) } func (m *PrepareRequest) XXX_Size() int { return xxx_messageInfo_PrepareRequest.Size(m) @@ -2208,16 +2257,17 @@ func (m *PrepareResponse) Reset() { *m = PrepareResponse{} } func (m *PrepareResponse) String() string { return proto.CompactTextString(m) } func (*PrepareResponse) ProtoMessage() {} func (*PrepareResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_query_1f9acea6b6c417bb, []int{27} + return fileDescriptor_5c6ac9b241082464, []int{27} } + func (m *PrepareResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_PrepareResponse.Unmarshal(m, b) } func (m *PrepareResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_PrepareResponse.Marshal(b, m, deterministic) } -func (dst *PrepareResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_PrepareResponse.Merge(dst, src) +func (m *PrepareResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_PrepareResponse.Merge(m, src) } func (m *PrepareResponse) XXX_Size() int { return xxx_messageInfo_PrepareResponse.Size(m) @@ -2243,16 +2293,17 @@ func (m *CommitPreparedRequest) Reset() { *m = CommitPreparedRequest{} } func (m *CommitPreparedRequest) String() string { return proto.CompactTextString(m) } func (*CommitPreparedRequest) ProtoMessage() {} func (*CommitPreparedRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_query_1f9acea6b6c417bb, []int{28} + return fileDescriptor_5c6ac9b241082464, []int{28} } + func (m *CommitPreparedRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_CommitPreparedRequest.Unmarshal(m, b) } func (m *CommitPreparedRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_CommitPreparedRequest.Marshal(b, m, deterministic) } -func (dst *CommitPreparedRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_CommitPreparedRequest.Merge(dst, src) +func (m *CommitPreparedRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_CommitPreparedRequest.Merge(m, src) } func (m *CommitPreparedRequest) XXX_Size() int { return xxx_messageInfo_CommitPreparedRequest.Size(m) @@ -2302,16 +2353,17 @@ func (m *CommitPreparedResponse) Reset() { *m = CommitPreparedResponse{} func (m *CommitPreparedResponse) String() string { return proto.CompactTextString(m) } func (*CommitPreparedResponse) ProtoMessage() {} func (*CommitPreparedResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_query_1f9acea6b6c417bb, []int{29} + return fileDescriptor_5c6ac9b241082464, []int{29} } + func (m *CommitPreparedResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_CommitPreparedResponse.Unmarshal(m, b) } func (m *CommitPreparedResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_CommitPreparedResponse.Marshal(b, m, deterministic) } -func (dst *CommitPreparedResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_CommitPreparedResponse.Merge(dst, src) +func (m *CommitPreparedResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_CommitPreparedResponse.Merge(m, src) } func (m *CommitPreparedResponse) XXX_Size() int { return xxx_messageInfo_CommitPreparedResponse.Size(m) @@ -2338,16 +2390,17 @@ func (m *RollbackPreparedRequest) Reset() { *m = RollbackPreparedRequest func (m *RollbackPreparedRequest) String() string { return proto.CompactTextString(m) } func (*RollbackPreparedRequest) ProtoMessage() {} func (*RollbackPreparedRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_query_1f9acea6b6c417bb, []int{30} + return fileDescriptor_5c6ac9b241082464, []int{30} } + func (m *RollbackPreparedRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_RollbackPreparedRequest.Unmarshal(m, b) } func (m *RollbackPreparedRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_RollbackPreparedRequest.Marshal(b, m, deterministic) } -func (dst *RollbackPreparedRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_RollbackPreparedRequest.Merge(dst, src) +func (m *RollbackPreparedRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_RollbackPreparedRequest.Merge(m, src) } func (m *RollbackPreparedRequest) XXX_Size() int { return xxx_messageInfo_RollbackPreparedRequest.Size(m) @@ -2404,16 +2457,17 @@ func (m *RollbackPreparedResponse) Reset() { *m = RollbackPreparedRespon func (m *RollbackPreparedResponse) String() string { return proto.CompactTextString(m) } func (*RollbackPreparedResponse) ProtoMessage() {} func (*RollbackPreparedResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_query_1f9acea6b6c417bb, []int{31} + return fileDescriptor_5c6ac9b241082464, []int{31} } + func (m *RollbackPreparedResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_RollbackPreparedResponse.Unmarshal(m, b) } func (m *RollbackPreparedResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_RollbackPreparedResponse.Marshal(b, m, deterministic) } -func (dst *RollbackPreparedResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_RollbackPreparedResponse.Merge(dst, src) +func (m *RollbackPreparedResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_RollbackPreparedResponse.Merge(m, src) } func (m *RollbackPreparedResponse) XXX_Size() int { return xxx_messageInfo_RollbackPreparedResponse.Size(m) @@ -2440,16 +2494,17 @@ func (m *CreateTransactionRequest) Reset() { *m = CreateTransactionReque func (m *CreateTransactionRequest) String() string { return proto.CompactTextString(m) } func (*CreateTransactionRequest) ProtoMessage() {} func (*CreateTransactionRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_query_1f9acea6b6c417bb, []int{32} + return fileDescriptor_5c6ac9b241082464, []int{32} } + func (m *CreateTransactionRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_CreateTransactionRequest.Unmarshal(m, b) } func (m *CreateTransactionRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_CreateTransactionRequest.Marshal(b, m, deterministic) } -func (dst *CreateTransactionRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_CreateTransactionRequest.Merge(dst, src) +func (m *CreateTransactionRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_CreateTransactionRequest.Merge(m, src) } func (m *CreateTransactionRequest) XXX_Size() int { return xxx_messageInfo_CreateTransactionRequest.Size(m) @@ -2506,16 +2561,17 @@ func (m *CreateTransactionResponse) Reset() { *m = CreateTransactionResp func (m *CreateTransactionResponse) String() string { return proto.CompactTextString(m) } func (*CreateTransactionResponse) ProtoMessage() {} func (*CreateTransactionResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_query_1f9acea6b6c417bb, []int{33} + return fileDescriptor_5c6ac9b241082464, []int{33} } + func (m *CreateTransactionResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_CreateTransactionResponse.Unmarshal(m, b) } func (m *CreateTransactionResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_CreateTransactionResponse.Marshal(b, m, deterministic) } -func (dst *CreateTransactionResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_CreateTransactionResponse.Merge(dst, src) +func (m *CreateTransactionResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_CreateTransactionResponse.Merge(m, src) } func (m *CreateTransactionResponse) XXX_Size() int { return xxx_messageInfo_CreateTransactionResponse.Size(m) @@ -2542,16 +2598,17 @@ func (m *StartCommitRequest) Reset() { *m = StartCommitRequest{} } func (m *StartCommitRequest) String() string { return proto.CompactTextString(m) } func (*StartCommitRequest) ProtoMessage() {} func (*StartCommitRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_query_1f9acea6b6c417bb, []int{34} + return fileDescriptor_5c6ac9b241082464, []int{34} } + func (m *StartCommitRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_StartCommitRequest.Unmarshal(m, b) } func (m *StartCommitRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_StartCommitRequest.Marshal(b, m, deterministic) } -func (dst *StartCommitRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_StartCommitRequest.Merge(dst, src) +func (m *StartCommitRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_StartCommitRequest.Merge(m, src) } func (m *StartCommitRequest) XXX_Size() int { return xxx_messageInfo_StartCommitRequest.Size(m) @@ -2608,16 +2665,17 @@ func (m *StartCommitResponse) Reset() { *m = StartCommitResponse{} } func (m *StartCommitResponse) String() string { return proto.CompactTextString(m) } func (*StartCommitResponse) ProtoMessage() {} func (*StartCommitResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_query_1f9acea6b6c417bb, []int{35} + return fileDescriptor_5c6ac9b241082464, []int{35} } + func (m *StartCommitResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_StartCommitResponse.Unmarshal(m, b) } func (m *StartCommitResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_StartCommitResponse.Marshal(b, m, deterministic) } -func (dst *StartCommitResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_StartCommitResponse.Merge(dst, src) +func (m *StartCommitResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_StartCommitResponse.Merge(m, src) } func (m *StartCommitResponse) XXX_Size() int { return xxx_messageInfo_StartCommitResponse.Size(m) @@ -2644,16 +2702,17 @@ func (m *SetRollbackRequest) Reset() { *m = SetRollbackRequest{} } func (m *SetRollbackRequest) String() string { return proto.CompactTextString(m) } func (*SetRollbackRequest) ProtoMessage() {} func (*SetRollbackRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_query_1f9acea6b6c417bb, []int{36} + return fileDescriptor_5c6ac9b241082464, []int{36} } + func (m *SetRollbackRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_SetRollbackRequest.Unmarshal(m, b) } func (m *SetRollbackRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_SetRollbackRequest.Marshal(b, m, deterministic) } -func (dst *SetRollbackRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_SetRollbackRequest.Merge(dst, src) +func (m *SetRollbackRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_SetRollbackRequest.Merge(m, src) } func (m *SetRollbackRequest) XXX_Size() int { return xxx_messageInfo_SetRollbackRequest.Size(m) @@ -2710,16 +2769,17 @@ func (m *SetRollbackResponse) Reset() { *m = SetRollbackResponse{} } func (m *SetRollbackResponse) String() string { return proto.CompactTextString(m) } func (*SetRollbackResponse) ProtoMessage() {} func (*SetRollbackResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_query_1f9acea6b6c417bb, []int{37} + return fileDescriptor_5c6ac9b241082464, []int{37} } + func (m *SetRollbackResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_SetRollbackResponse.Unmarshal(m, b) } func (m *SetRollbackResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_SetRollbackResponse.Marshal(b, m, deterministic) } -func (dst *SetRollbackResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_SetRollbackResponse.Merge(dst, src) +func (m *SetRollbackResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_SetRollbackResponse.Merge(m, src) } func (m *SetRollbackResponse) XXX_Size() int { return xxx_messageInfo_SetRollbackResponse.Size(m) @@ -2745,16 +2805,17 @@ func (m *ConcludeTransactionRequest) Reset() { *m = ConcludeTransactionR func (m *ConcludeTransactionRequest) String() string { return proto.CompactTextString(m) } func (*ConcludeTransactionRequest) ProtoMessage() {} func (*ConcludeTransactionRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_query_1f9acea6b6c417bb, []int{38} + return fileDescriptor_5c6ac9b241082464, []int{38} } + func (m *ConcludeTransactionRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ConcludeTransactionRequest.Unmarshal(m, b) } func (m *ConcludeTransactionRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_ConcludeTransactionRequest.Marshal(b, m, deterministic) } -func (dst *ConcludeTransactionRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_ConcludeTransactionRequest.Merge(dst, src) +func (m *ConcludeTransactionRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_ConcludeTransactionRequest.Merge(m, src) } func (m *ConcludeTransactionRequest) XXX_Size() int { return xxx_messageInfo_ConcludeTransactionRequest.Size(m) @@ -2804,16 +2865,17 @@ func (m *ConcludeTransactionResponse) Reset() { *m = ConcludeTransaction func (m *ConcludeTransactionResponse) String() string { return proto.CompactTextString(m) } func (*ConcludeTransactionResponse) ProtoMessage() {} func (*ConcludeTransactionResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_query_1f9acea6b6c417bb, []int{39} + return fileDescriptor_5c6ac9b241082464, []int{39} } + func (m *ConcludeTransactionResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ConcludeTransactionResponse.Unmarshal(m, b) } func (m *ConcludeTransactionResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_ConcludeTransactionResponse.Marshal(b, m, deterministic) } -func (dst *ConcludeTransactionResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_ConcludeTransactionResponse.Merge(dst, src) +func (m *ConcludeTransactionResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_ConcludeTransactionResponse.Merge(m, src) } func (m *ConcludeTransactionResponse) XXX_Size() int { return xxx_messageInfo_ConcludeTransactionResponse.Size(m) @@ -2839,16 +2901,17 @@ func (m *ReadTransactionRequest) Reset() { *m = ReadTransactionRequest{} func (m *ReadTransactionRequest) String() string { return proto.CompactTextString(m) } func (*ReadTransactionRequest) ProtoMessage() {} func (*ReadTransactionRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_query_1f9acea6b6c417bb, []int{40} + return fileDescriptor_5c6ac9b241082464, []int{40} } + func (m *ReadTransactionRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ReadTransactionRequest.Unmarshal(m, b) } func (m *ReadTransactionRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_ReadTransactionRequest.Marshal(b, m, deterministic) } -func (dst *ReadTransactionRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_ReadTransactionRequest.Merge(dst, src) +func (m *ReadTransactionRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_ReadTransactionRequest.Merge(m, src) } func (m *ReadTransactionRequest) XXX_Size() int { return xxx_messageInfo_ReadTransactionRequest.Size(m) @@ -2899,16 +2962,17 @@ func (m *ReadTransactionResponse) Reset() { *m = ReadTransactionResponse func (m *ReadTransactionResponse) String() string { return proto.CompactTextString(m) } func (*ReadTransactionResponse) ProtoMessage() {} func (*ReadTransactionResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_query_1f9acea6b6c417bb, []int{41} + return fileDescriptor_5c6ac9b241082464, []int{41} } + func (m *ReadTransactionResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ReadTransactionResponse.Unmarshal(m, b) } func (m *ReadTransactionResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_ReadTransactionResponse.Marshal(b, m, deterministic) } -func (dst *ReadTransactionResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_ReadTransactionResponse.Merge(dst, src) +func (m *ReadTransactionResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_ReadTransactionResponse.Merge(m, src) } func (m *ReadTransactionResponse) XXX_Size() int { return xxx_messageInfo_ReadTransactionResponse.Size(m) @@ -2942,16 +3006,17 @@ func (m *BeginExecuteRequest) Reset() { *m = BeginExecuteRequest{} } func (m *BeginExecuteRequest) String() string { return proto.CompactTextString(m) } func (*BeginExecuteRequest) ProtoMessage() {} func (*BeginExecuteRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_query_1f9acea6b6c417bb, []int{42} + return fileDescriptor_5c6ac9b241082464, []int{42} } + func (m *BeginExecuteRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_BeginExecuteRequest.Unmarshal(m, b) } func (m *BeginExecuteRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_BeginExecuteRequest.Marshal(b, m, deterministic) } -func (dst *BeginExecuteRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_BeginExecuteRequest.Merge(dst, src) +func (m *BeginExecuteRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_BeginExecuteRequest.Merge(m, src) } func (m *BeginExecuteRequest) XXX_Size() int { return xxx_messageInfo_BeginExecuteRequest.Size(m) @@ -3015,16 +3080,17 @@ func (m *BeginExecuteResponse) Reset() { *m = BeginExecuteResponse{} } func (m *BeginExecuteResponse) String() string { return proto.CompactTextString(m) } func (*BeginExecuteResponse) ProtoMessage() {} func (*BeginExecuteResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_query_1f9acea6b6c417bb, []int{43} + return fileDescriptor_5c6ac9b241082464, []int{43} } + func (m *BeginExecuteResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_BeginExecuteResponse.Unmarshal(m, b) } func (m *BeginExecuteResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_BeginExecuteResponse.Marshal(b, m, deterministic) } -func (dst *BeginExecuteResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_BeginExecuteResponse.Merge(dst, src) +func (m *BeginExecuteResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_BeginExecuteResponse.Merge(m, src) } func (m *BeginExecuteResponse) XXX_Size() int { return xxx_messageInfo_BeginExecuteResponse.Size(m) @@ -3073,16 +3139,17 @@ func (m *BeginExecuteBatchRequest) Reset() { *m = BeginExecuteBatchReque func (m *BeginExecuteBatchRequest) String() string { return proto.CompactTextString(m) } func (*BeginExecuteBatchRequest) ProtoMessage() {} func (*BeginExecuteBatchRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_query_1f9acea6b6c417bb, []int{44} + return fileDescriptor_5c6ac9b241082464, []int{44} } + func (m *BeginExecuteBatchRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_BeginExecuteBatchRequest.Unmarshal(m, b) } func (m *BeginExecuteBatchRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_BeginExecuteBatchRequest.Marshal(b, m, deterministic) } -func (dst *BeginExecuteBatchRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_BeginExecuteBatchRequest.Merge(dst, src) +func (m *BeginExecuteBatchRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_BeginExecuteBatchRequest.Merge(m, src) } func (m *BeginExecuteBatchRequest) XXX_Size() int { return xxx_messageInfo_BeginExecuteBatchRequest.Size(m) @@ -3153,16 +3220,17 @@ func (m *BeginExecuteBatchResponse) Reset() { *m = BeginExecuteBatchResp func (m *BeginExecuteBatchResponse) String() string { return proto.CompactTextString(m) } func (*BeginExecuteBatchResponse) ProtoMessage() {} func (*BeginExecuteBatchResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_query_1f9acea6b6c417bb, []int{45} + return fileDescriptor_5c6ac9b241082464, []int{45} } + func (m *BeginExecuteBatchResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_BeginExecuteBatchResponse.Unmarshal(m, b) } func (m *BeginExecuteBatchResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_BeginExecuteBatchResponse.Marshal(b, m, deterministic) } -func (dst *BeginExecuteBatchResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_BeginExecuteBatchResponse.Merge(dst, src) +func (m *BeginExecuteBatchResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_BeginExecuteBatchResponse.Merge(m, src) } func (m *BeginExecuteBatchResponse) XXX_Size() int { return xxx_messageInfo_BeginExecuteBatchResponse.Size(m) @@ -3210,16 +3278,17 @@ func (m *MessageStreamRequest) Reset() { *m = MessageStreamRequest{} } func (m *MessageStreamRequest) String() string { return proto.CompactTextString(m) } func (*MessageStreamRequest) ProtoMessage() {} func (*MessageStreamRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_query_1f9acea6b6c417bb, []int{46} + return fileDescriptor_5c6ac9b241082464, []int{46} } + func (m *MessageStreamRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_MessageStreamRequest.Unmarshal(m, b) } func (m *MessageStreamRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_MessageStreamRequest.Marshal(b, m, deterministic) } -func (dst *MessageStreamRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_MessageStreamRequest.Merge(dst, src) +func (m *MessageStreamRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_MessageStreamRequest.Merge(m, src) } func (m *MessageStreamRequest) XXX_Size() int { return xxx_messageInfo_MessageStreamRequest.Size(m) @@ -3270,16 +3339,17 @@ func (m *MessageStreamResponse) Reset() { *m = MessageStreamResponse{} } func (m *MessageStreamResponse) String() string { return proto.CompactTextString(m) } func (*MessageStreamResponse) ProtoMessage() {} func (*MessageStreamResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_query_1f9acea6b6c417bb, []int{47} + return fileDescriptor_5c6ac9b241082464, []int{47} } + func (m *MessageStreamResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_MessageStreamResponse.Unmarshal(m, b) } func (m *MessageStreamResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_MessageStreamResponse.Marshal(b, m, deterministic) } -func (dst *MessageStreamResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_MessageStreamResponse.Merge(dst, src) +func (m *MessageStreamResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_MessageStreamResponse.Merge(m, src) } func (m *MessageStreamResponse) XXX_Size() int { return xxx_messageInfo_MessageStreamResponse.Size(m) @@ -3314,16 +3384,17 @@ func (m *MessageAckRequest) Reset() { *m = MessageAckRequest{} } func (m *MessageAckRequest) String() string { return proto.CompactTextString(m) } func (*MessageAckRequest) ProtoMessage() {} func (*MessageAckRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_query_1f9acea6b6c417bb, []int{48} + return fileDescriptor_5c6ac9b241082464, []int{48} } + func (m *MessageAckRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_MessageAckRequest.Unmarshal(m, b) } func (m *MessageAckRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_MessageAckRequest.Marshal(b, m, deterministic) } -func (dst *MessageAckRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_MessageAckRequest.Merge(dst, src) +func (m *MessageAckRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_MessageAckRequest.Merge(m, src) } func (m *MessageAckRequest) XXX_Size() int { return xxx_messageInfo_MessageAckRequest.Size(m) @@ -3384,16 +3455,17 @@ func (m *MessageAckResponse) Reset() { *m = MessageAckResponse{} } func (m *MessageAckResponse) String() string { return proto.CompactTextString(m) } func (*MessageAckResponse) ProtoMessage() {} func (*MessageAckResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_query_1f9acea6b6c417bb, []int{49} + return fileDescriptor_5c6ac9b241082464, []int{49} } + func (m *MessageAckResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_MessageAckResponse.Unmarshal(m, b) } func (m *MessageAckResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_MessageAckResponse.Marshal(b, m, deterministic) } -func (dst *MessageAckResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_MessageAckResponse.Merge(dst, src) +func (m *MessageAckResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_MessageAckResponse.Merge(m, src) } func (m *MessageAckResponse) XXX_Size() int { return xxx_messageInfo_MessageAckResponse.Size(m) @@ -3432,16 +3504,17 @@ func (m *SplitQueryRequest) Reset() { *m = SplitQueryRequest{} } func (m *SplitQueryRequest) String() string { return proto.CompactTextString(m) } func (*SplitQueryRequest) ProtoMessage() {} func (*SplitQueryRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_query_1f9acea6b6c417bb, []int{50} + return fileDescriptor_5c6ac9b241082464, []int{50} } + func (m *SplitQueryRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_SplitQueryRequest.Unmarshal(m, b) } func (m *SplitQueryRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_SplitQueryRequest.Marshal(b, m, deterministic) } -func (dst *SplitQueryRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_SplitQueryRequest.Merge(dst, src) +func (m *SplitQueryRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_SplitQueryRequest.Merge(m, src) } func (m *SplitQueryRequest) XXX_Size() int { return xxx_messageInfo_SplitQueryRequest.Size(m) @@ -3523,16 +3596,17 @@ func (m *QuerySplit) Reset() { *m = QuerySplit{} } func (m *QuerySplit) String() string { return proto.CompactTextString(m) } func (*QuerySplit) ProtoMessage() {} func (*QuerySplit) Descriptor() ([]byte, []int) { - return fileDescriptor_query_1f9acea6b6c417bb, []int{51} + return fileDescriptor_5c6ac9b241082464, []int{51} } + func (m *QuerySplit) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_QuerySplit.Unmarshal(m, b) } func (m *QuerySplit) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_QuerySplit.Marshal(b, m, deterministic) } -func (dst *QuerySplit) XXX_Merge(src proto.Message) { - xxx_messageInfo_QuerySplit.Merge(dst, src) +func (m *QuerySplit) XXX_Merge(src proto.Message) { + xxx_messageInfo_QuerySplit.Merge(m, src) } func (m *QuerySplit) XXX_Size() int { return xxx_messageInfo_QuerySplit.Size(m) @@ -3570,16 +3644,17 @@ func (m *SplitQueryResponse) Reset() { *m = SplitQueryResponse{} } func (m *SplitQueryResponse) String() string { return proto.CompactTextString(m) } func (*SplitQueryResponse) ProtoMessage() {} func (*SplitQueryResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_query_1f9acea6b6c417bb, []int{52} + return fileDescriptor_5c6ac9b241082464, []int{52} } + func (m *SplitQueryResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_SplitQueryResponse.Unmarshal(m, b) } func (m *SplitQueryResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_SplitQueryResponse.Marshal(b, m, deterministic) } -func (dst *SplitQueryResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_SplitQueryResponse.Merge(dst, src) +func (m *SplitQueryResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_SplitQueryResponse.Merge(m, src) } func (m *SplitQueryResponse) XXX_Size() int { return xxx_messageInfo_SplitQueryResponse.Size(m) @@ -3608,16 +3683,17 @@ func (m *StreamHealthRequest) Reset() { *m = StreamHealthRequest{} } func (m *StreamHealthRequest) String() string { return proto.CompactTextString(m) } func (*StreamHealthRequest) ProtoMessage() {} func (*StreamHealthRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_query_1f9acea6b6c417bb, []int{53} + return fileDescriptor_5c6ac9b241082464, []int{53} } + func (m *StreamHealthRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_StreamHealthRequest.Unmarshal(m, b) } func (m *StreamHealthRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_StreamHealthRequest.Marshal(b, m, deterministic) } -func (dst *StreamHealthRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_StreamHealthRequest.Merge(dst, src) +func (m *StreamHealthRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_StreamHealthRequest.Merge(m, src) } func (m *StreamHealthRequest) XXX_Size() int { return xxx_messageInfo_StreamHealthRequest.Size(m) @@ -3667,16 +3743,17 @@ func (m *RealtimeStats) Reset() { *m = RealtimeStats{} } func (m *RealtimeStats) String() string { return proto.CompactTextString(m) } func (*RealtimeStats) ProtoMessage() {} func (*RealtimeStats) Descriptor() ([]byte, []int) { - return fileDescriptor_query_1f9acea6b6c417bb, []int{54} + return fileDescriptor_5c6ac9b241082464, []int{54} } + func (m *RealtimeStats) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_RealtimeStats.Unmarshal(m, b) } func (m *RealtimeStats) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_RealtimeStats.Marshal(b, m, deterministic) } -func (dst *RealtimeStats) XXX_Merge(src proto.Message) { - xxx_messageInfo_RealtimeStats.Merge(dst, src) +func (m *RealtimeStats) XXX_Merge(src proto.Message) { + xxx_messageInfo_RealtimeStats.Merge(m, src) } func (m *RealtimeStats) XXX_Size() int { return xxx_messageInfo_RealtimeStats.Size(m) @@ -3755,16 +3832,17 @@ func (m *AggregateStats) Reset() { *m = AggregateStats{} } func (m *AggregateStats) String() string { return proto.CompactTextString(m) } func (*AggregateStats) ProtoMessage() {} func (*AggregateStats) Descriptor() ([]byte, []int) { - return fileDescriptor_query_1f9acea6b6c417bb, []int{55} + return fileDescriptor_5c6ac9b241082464, []int{55} } + func (m *AggregateStats) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_AggregateStats.Unmarshal(m, b) } func (m *AggregateStats) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_AggregateStats.Marshal(b, m, deterministic) } -func (dst *AggregateStats) XXX_Merge(src proto.Message) { - xxx_messageInfo_AggregateStats.Merge(dst, src) +func (m *AggregateStats) XXX_Merge(src proto.Message) { + xxx_messageInfo_AggregateStats.Merge(m, src) } func (m *AggregateStats) XXX_Size() int { return xxx_messageInfo_AggregateStats.Size(m) @@ -3850,7 +3928,7 @@ type StreamHealthResponse struct { // realtime_stats contains information about the tablet status. // It is only filled in if the information is about a tablet. RealtimeStats *RealtimeStats `protobuf:"bytes,4,opt,name=realtime_stats,json=realtimeStats,proto3" json:"realtime_stats,omitempty"` - // AggregateStats constains information about the group of tablet status. + // AggregateStats constrains information about the group of tablet status. // It is only filled in if the information is about a group of tablets. AggregateStats *AggregateStats `protobuf:"bytes,6,opt,name=aggregate_stats,json=aggregateStats,proto3" json:"aggregate_stats,omitempty"` // tablet_alias is the alias of the sending tablet. The discovery/healthcheck.go @@ -3867,16 +3945,17 @@ func (m *StreamHealthResponse) Reset() { *m = StreamHealthResponse{} } func (m *StreamHealthResponse) String() string { return proto.CompactTextString(m) } func (*StreamHealthResponse) ProtoMessage() {} func (*StreamHealthResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_query_1f9acea6b6c417bb, []int{56} + return fileDescriptor_5c6ac9b241082464, []int{56} } + func (m *StreamHealthResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_StreamHealthResponse.Unmarshal(m, b) } func (m *StreamHealthResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_StreamHealthResponse.Marshal(b, m, deterministic) } -func (dst *StreamHealthResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_StreamHealthResponse.Merge(dst, src) +func (m *StreamHealthResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_StreamHealthResponse.Merge(m, src) } func (m *StreamHealthResponse) XXX_Size() int { return xxx_messageInfo_StreamHealthResponse.Size(m) @@ -3951,16 +4030,17 @@ func (m *UpdateStreamRequest) Reset() { *m = UpdateStreamRequest{} } func (m *UpdateStreamRequest) String() string { return proto.CompactTextString(m) } func (*UpdateStreamRequest) ProtoMessage() {} func (*UpdateStreamRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_query_1f9acea6b6c417bb, []int{57} + return fileDescriptor_5c6ac9b241082464, []int{57} } + func (m *UpdateStreamRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_UpdateStreamRequest.Unmarshal(m, b) } func (m *UpdateStreamRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_UpdateStreamRequest.Marshal(b, m, deterministic) } -func (dst *UpdateStreamRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_UpdateStreamRequest.Merge(dst, src) +func (m *UpdateStreamRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_UpdateStreamRequest.Merge(m, src) } func (m *UpdateStreamRequest) XXX_Size() int { return xxx_messageInfo_UpdateStreamRequest.Size(m) @@ -4018,16 +4098,17 @@ func (m *UpdateStreamResponse) Reset() { *m = UpdateStreamResponse{} } func (m *UpdateStreamResponse) String() string { return proto.CompactTextString(m) } func (*UpdateStreamResponse) ProtoMessage() {} func (*UpdateStreamResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_query_1f9acea6b6c417bb, []int{58} + return fileDescriptor_5c6ac9b241082464, []int{58} } + func (m *UpdateStreamResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_UpdateStreamResponse.Unmarshal(m, b) } func (m *UpdateStreamResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_UpdateStreamResponse.Marshal(b, m, deterministic) } -func (dst *UpdateStreamResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_UpdateStreamResponse.Merge(dst, src) +func (m *UpdateStreamResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_UpdateStreamResponse.Merge(m, src) } func (m *UpdateStreamResponse) XXX_Size() int { return xxx_messageInfo_UpdateStreamResponse.Size(m) @@ -4060,16 +4141,17 @@ func (m *TransactionMetadata) Reset() { *m = TransactionMetadata{} } func (m *TransactionMetadata) String() string { return proto.CompactTextString(m) } func (*TransactionMetadata) ProtoMessage() {} func (*TransactionMetadata) Descriptor() ([]byte, []int) { - return fileDescriptor_query_1f9acea6b6c417bb, []int{59} + return fileDescriptor_5c6ac9b241082464, []int{59} } + func (m *TransactionMetadata) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_TransactionMetadata.Unmarshal(m, b) } func (m *TransactionMetadata) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_TransactionMetadata.Marshal(b, m, deterministic) } -func (dst *TransactionMetadata) XXX_Merge(src proto.Message) { - xxx_messageInfo_TransactionMetadata.Merge(dst, src) +func (m *TransactionMetadata) XXX_Merge(src proto.Message) { + xxx_messageInfo_TransactionMetadata.Merge(m, src) } func (m *TransactionMetadata) XXX_Size() int { return xxx_messageInfo_TransactionMetadata.Size(m) @@ -4109,6 +4191,15 @@ func (m *TransactionMetadata) GetParticipants() []*Target { } func init() { + proto.RegisterEnum("query.MySqlFlag", MySqlFlag_name, MySqlFlag_value) + proto.RegisterEnum("query.Flag", Flag_name, Flag_value) + proto.RegisterEnum("query.Type", Type_name, Type_value) + proto.RegisterEnum("query.TransactionState", TransactionState_name, TransactionState_value) + proto.RegisterEnum("query.ExecuteOptions_IncludedFields", ExecuteOptions_IncludedFields_name, ExecuteOptions_IncludedFields_value) + proto.RegisterEnum("query.ExecuteOptions_Workload", ExecuteOptions_Workload_name, ExecuteOptions_Workload_value) + proto.RegisterEnum("query.ExecuteOptions_TransactionIsolation", ExecuteOptions_TransactionIsolation_name, ExecuteOptions_TransactionIsolation_value) + proto.RegisterEnum("query.StreamEvent_Statement_Category", StreamEvent_Statement_Category_name, StreamEvent_Statement_Category_value) + proto.RegisterEnum("query.SplitQueryRequest_Algorithm", SplitQueryRequest_Algorithm_name, SplitQueryRequest_Algorithm_value) proto.RegisterType((*Target)(nil), "query.Target") proto.RegisterType((*VTGateCallerID)(nil), "query.VTGateCallerID") proto.RegisterType((*EventToken)(nil), "query.EventToken") @@ -4171,20 +4262,11 @@ func init() { proto.RegisterType((*UpdateStreamRequest)(nil), "query.UpdateStreamRequest") proto.RegisterType((*UpdateStreamResponse)(nil), "query.UpdateStreamResponse") proto.RegisterType((*TransactionMetadata)(nil), "query.TransactionMetadata") - proto.RegisterEnum("query.MySqlFlag", MySqlFlag_name, MySqlFlag_value) - proto.RegisterEnum("query.Flag", Flag_name, Flag_value) - proto.RegisterEnum("query.Type", Type_name, Type_value) - proto.RegisterEnum("query.TransactionState", TransactionState_name, TransactionState_value) - proto.RegisterEnum("query.ExecuteOptions_IncludedFields", ExecuteOptions_IncludedFields_name, ExecuteOptions_IncludedFields_value) - proto.RegisterEnum("query.ExecuteOptions_Workload", ExecuteOptions_Workload_name, ExecuteOptions_Workload_value) - proto.RegisterEnum("query.ExecuteOptions_TransactionIsolation", ExecuteOptions_TransactionIsolation_name, ExecuteOptions_TransactionIsolation_value) - proto.RegisterEnum("query.StreamEvent_Statement_Category", StreamEvent_Statement_Category_name, StreamEvent_Statement_Category_value) - proto.RegisterEnum("query.SplitQueryRequest_Algorithm", SplitQueryRequest_Algorithm_name, SplitQueryRequest_Algorithm_value) } -func init() { proto.RegisterFile("query.proto", fileDescriptor_query_1f9acea6b6c417bb) } +func init() { proto.RegisterFile("query.proto", fileDescriptor_5c6ac9b241082464) } -var fileDescriptor_query_1f9acea6b6c417bb = []byte{ +var fileDescriptor_5c6ac9b241082464 = []byte{ // 3270 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x5a, 0xcb, 0x73, 0x1b, 0xc9, 0x79, 0xd7, 0xe0, 0x45, 0xe0, 0x03, 0x01, 0x36, 0x1b, 0xa4, 0x84, 0xe5, 0xbe, 0xe8, 0xb1, 0xd7, diff --git a/go/vt/proto/queryservice/queryservice.pb.go b/go/vt/proto/queryservice/queryservice.pb.go index ac8303d162a..74b816b4ede 100644 --- a/go/vt/proto/queryservice/queryservice.pb.go +++ b/go/vt/proto/queryservice/queryservice.pb.go @@ -1,17 +1,19 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // source: queryservice.proto -package queryservice // import "vitess.io/vitess/go/vt/proto/queryservice" - -import proto "github.com/golang/protobuf/proto" -import fmt "fmt" -import math "math" -import binlogdata "vitess.io/vitess/go/vt/proto/binlogdata" -import query "vitess.io/vitess/go/vt/proto/query" +package queryservice import ( - context "golang.org/x/net/context" + context "context" + fmt "fmt" + math "math" + + proto "github.com/golang/protobuf/proto" grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + binlogdata "vitess.io/vitess/go/vt/proto/binlogdata" + query "vitess.io/vitess/go/vt/proto/query" ) // Reference imports to suppress errors if they are not otherwise used. @@ -23,7 +25,50 @@ var _ = math.Inf // is compatible with the proto package it is being compiled against. // A compilation error at this line likely means your copy of the // proto package needs to be updated. -const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package +const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package + +func init() { proto.RegisterFile("queryservice.proto", fileDescriptor_4bd2dde8711f22e3) } + +var fileDescriptor_4bd2dde8711f22e3 = []byte{ + // 582 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x95, 0xdf, 0x6f, 0xd3, 0x30, + 0x10, 0xc7, 0xe1, 0x61, 0x2b, 0xba, 0x96, 0x32, 0x3c, 0x06, 0x2c, 0x1b, 0xdd, 0x8f, 0x37, 0x84, + 0xd4, 0x22, 0x40, 0x42, 0x9a, 0xc4, 0xc3, 0x5a, 0x31, 0x81, 0x26, 0x7e, 0xb5, 0x6c, 0x42, 0x20, + 0x21, 0xb9, 0xa9, 0x55, 0xa2, 0xa5, 0x71, 0x16, 0x3b, 0x1d, 0xfc, 0x37, 0xfc, 0xa9, 0xd3, 0xe2, + 0xdc, 0xc5, 0x76, 0x93, 0xbd, 0xcd, 0xdf, 0xef, 0xdd, 0x67, 0x17, 0x5f, 0xef, 0x0c, 0xec, 0x32, + 0x17, 0xd9, 0x3f, 0x25, 0xb2, 0x65, 0x14, 0x8a, 0x7e, 0x9a, 0x49, 0x2d, 0x59, 0xc7, 0xd6, 0x82, + 0x76, 0x71, 0x32, 0x56, 0xb0, 0x31, 0x8d, 0x92, 0x58, 0xce, 0x67, 0x5c, 0x73, 0xa3, 0xbc, 0xfa, + 0xdf, 0x85, 0xb5, 0x6f, 0x37, 0x11, 0xec, 0x08, 0x5a, 0xef, 0xff, 0x8a, 0x30, 0xd7, 0x82, 0x6d, + 0xf5, 0x4d, 0x52, 0x79, 0x1e, 0x8b, 0xcb, 0x5c, 0x28, 0x1d, 0x3c, 0xf6, 0x65, 0x95, 0xca, 0x44, + 0x89, 0xc3, 0x3b, 0xec, 0x23, 0x74, 0x4a, 0x71, 0xc8, 0x75, 0xf8, 0x87, 0x05, 0x6e, 0x64, 0x21, + 0x22, 0x65, 0xa7, 0xd6, 0x23, 0xd4, 0x67, 0xb8, 0x3f, 0xd1, 0x99, 0xe0, 0x0b, 0x2c, 0x06, 0xe3, + 0x1d, 0x15, 0x61, 0xbb, 0xf5, 0x26, 0xd2, 0x5e, 0xde, 0x65, 0x6f, 0x60, 0x6d, 0x28, 0xe6, 0x51, + 0xc2, 0x36, 0xcb, 0xd0, 0xe2, 0x84, 0xf9, 0x8f, 0x5c, 0x91, 0xaa, 0x78, 0x0b, 0xeb, 0x23, 0xb9, + 0x58, 0x44, 0x9a, 0x61, 0x84, 0x39, 0x62, 0xde, 0x96, 0xa7, 0x52, 0xe2, 0x3b, 0xb8, 0x37, 0x96, + 0x71, 0x3c, 0xe5, 0xe1, 0x05, 0xc3, 0xfb, 0x42, 0x01, 0x93, 0x9f, 0xac, 0xe8, 0x94, 0x7e, 0x04, + 0xad, 0xaf, 0x99, 0x48, 0x79, 0x56, 0x35, 0xa1, 0x3c, 0xfb, 0x4d, 0x20, 0x99, 0x72, 0xbf, 0x40, + 0xd7, 0x94, 0x53, 0x5a, 0x33, 0xb6, 0xeb, 0x54, 0x89, 0x32, 0x92, 0x9e, 0x35, 0xb8, 0x04, 0x3c, + 0x83, 0x0d, 0x2c, 0x91, 0x90, 0x3d, 0xaf, 0x76, 0x1f, 0xba, 0xd7, 0xe8, 0x13, 0xf6, 0x07, 0x3c, + 0x1c, 0x65, 0x82, 0x6b, 0xf1, 0x3d, 0xe3, 0x89, 0xe2, 0xa1, 0x8e, 0x64, 0xc2, 0x30, 0x6f, 0xc5, + 0x41, 0xf0, 0x7e, 0x73, 0x00, 0x91, 0x4f, 0xa0, 0x3d, 0xd1, 0x3c, 0xd3, 0x65, 0xeb, 0xb6, 0xe9, + 0xc7, 0x41, 0x1a, 0xd2, 0x82, 0x3a, 0xcb, 0xe1, 0x08, 0x4d, 0x7d, 0x24, 0x4e, 0xa5, 0xad, 0x70, + 0x6c, 0x8b, 0x38, 0xbf, 0x61, 0x73, 0x24, 0x93, 0x30, 0xce, 0x67, 0xce, 0xb7, 0x1e, 0xd0, 0xc5, + 0xaf, 0x78, 0xc8, 0x3d, 0xbc, 0x2d, 0x84, 0xf8, 0x63, 0x78, 0x30, 0x16, 0x7c, 0x66, 0xb3, 0xb1, + 0xa9, 0x9e, 0x8e, 0xdc, 0x5e, 0x93, 0x6d, 0x8f, 0x72, 0x31, 0x0c, 0x38, 0x7e, 0x81, 0x3d, 0x21, + 0xde, 0xf4, 0xed, 0xd4, 0x7a, 0x76, 0xa3, 0x6d, 0xc7, 0xac, 0x86, 0xbd, 0x9a, 0x1c, 0x67, 0x3f, + 0xec, 0x37, 0x07, 0xd8, 0x4b, 0xe2, 0x93, 0x50, 0x8a, 0xcf, 0x85, 0x19, 0x7c, 0x5a, 0x12, 0x8e, + 0xea, 0x2f, 0x09, 0xcf, 0xb4, 0x96, 0xc4, 0x08, 0xa0, 0x34, 0x8f, 0xc3, 0x0b, 0xf6, 0xd4, 0x8d, + 0x3f, 0xae, 0xda, 0xbd, 0x5d, 0xe3, 0x50, 0x51, 0x23, 0x80, 0x49, 0x1a, 0x47, 0xda, 0xac, 0x53, + 0x84, 0x54, 0x92, 0x0f, 0xb1, 0x1d, 0x82, 0x9c, 0x42, 0xc7, 0xd4, 0xf7, 0x41, 0xf0, 0x58, 0x57, + 0x9b, 0xd4, 0x16, 0xfd, 0xeb, 0x77, 0x3d, 0xeb, 0xb3, 0x4e, 0xa1, 0x73, 0x96, 0xce, 0xb8, 0xc6, + 0x5b, 0x42, 0x98, 0x2d, 0xfa, 0x30, 0xd7, 0xb3, 0x60, 0x27, 0xd0, 0x3a, 0x27, 0x8e, 0xf5, 0x8e, + 0x9c, 0xfb, 0x9c, 0x3a, 0xcf, 0xe2, 0x8c, 0xa1, 0x8d, 0xb2, 0xbc, 0x52, 0xac, 0x57, 0x17, 0x2f, + 0xaf, 0x54, 0xb5, 0x50, 0x9a, 0x7c, 0x8b, 0xf9, 0x0b, 0xba, 0xd5, 0xbf, 0xca, 0x63, 0xad, 0xd8, + 0x41, 0x7d, 0x19, 0x37, 0x5e, 0x35, 0x63, 0xb7, 0x84, 0x54, 0xf0, 0xe1, 0x8b, 0x9f, 0xcf, 0x97, + 0x91, 0x16, 0x4a, 0xf5, 0x23, 0x39, 0x30, 0x7f, 0x0d, 0xe6, 0x72, 0xb0, 0xd4, 0x83, 0xe2, 0x09, + 0x1d, 0xd8, 0xcf, 0xed, 0x74, 0xbd, 0xd0, 0x5e, 0x5f, 0x07, 0x00, 0x00, 0xff, 0xff, 0xbe, 0xb4, + 0xc0, 0x34, 0x99, 0x07, 0x00, 0x00, +} // Reference imports to suppress errors if they are not otherwise used. var _ context.Context @@ -90,6 +135,8 @@ type QueryClient interface { VStream(ctx context.Context, in *binlogdata.VStreamRequest, opts ...grpc.CallOption) (Query_VStreamClient, error) // VStreamRows streams rows from the specified starting point. VStreamRows(ctx context.Context, in *binlogdata.VStreamRowsRequest, opts ...grpc.CallOption) (Query_VStreamRowsClient, error) + // VStreamResults streams results along with the gtid of the snapshot. + VStreamResults(ctx context.Context, in *binlogdata.VStreamResultsRequest, opts ...grpc.CallOption) (Query_VStreamResultsClient, error) } type queryClient struct { @@ -445,6 +492,38 @@ func (x *queryVStreamRowsClient) Recv() (*binlogdata.VStreamRowsResponse, error) return m, nil } +func (c *queryClient) VStreamResults(ctx context.Context, in *binlogdata.VStreamResultsRequest, opts ...grpc.CallOption) (Query_VStreamResultsClient, error) { + stream, err := c.cc.NewStream(ctx, &_Query_serviceDesc.Streams[6], "/queryservice.Query/VStreamResults", opts...) + if err != nil { + return nil, err + } + x := &queryVStreamResultsClient{stream} + if err := x.ClientStream.SendMsg(in); err != nil { + return nil, err + } + if err := x.ClientStream.CloseSend(); err != nil { + return nil, err + } + return x, nil +} + +type Query_VStreamResultsClient interface { + Recv() (*binlogdata.VStreamResultsResponse, error) + grpc.ClientStream +} + +type queryVStreamResultsClient struct { + grpc.ClientStream +} + +func (x *queryVStreamResultsClient) Recv() (*binlogdata.VStreamResultsResponse, error) { + m := new(binlogdata.VStreamResultsResponse) + if err := x.ClientStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + // QueryServer is the server API for Query service. type QueryServer interface { // Execute executes the specified SQL query (might be in a @@ -500,6 +579,85 @@ type QueryServer interface { VStream(*binlogdata.VStreamRequest, Query_VStreamServer) error // VStreamRows streams rows from the specified starting point. VStreamRows(*binlogdata.VStreamRowsRequest, Query_VStreamRowsServer) error + // VStreamResults streams results along with the gtid of the snapshot. + VStreamResults(*binlogdata.VStreamResultsRequest, Query_VStreamResultsServer) error +} + +// UnimplementedQueryServer can be embedded to have forward compatible implementations. +type UnimplementedQueryServer struct { +} + +func (*UnimplementedQueryServer) Execute(ctx context.Context, req *query.ExecuteRequest) (*query.ExecuteResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Execute not implemented") +} +func (*UnimplementedQueryServer) ExecuteBatch(ctx context.Context, req *query.ExecuteBatchRequest) (*query.ExecuteBatchResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ExecuteBatch not implemented") +} +func (*UnimplementedQueryServer) StreamExecute(req *query.StreamExecuteRequest, srv Query_StreamExecuteServer) error { + return status.Errorf(codes.Unimplemented, "method StreamExecute not implemented") +} +func (*UnimplementedQueryServer) Begin(ctx context.Context, req *query.BeginRequest) (*query.BeginResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Begin not implemented") +} +func (*UnimplementedQueryServer) Commit(ctx context.Context, req *query.CommitRequest) (*query.CommitResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Commit not implemented") +} +func (*UnimplementedQueryServer) Rollback(ctx context.Context, req *query.RollbackRequest) (*query.RollbackResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Rollback not implemented") +} +func (*UnimplementedQueryServer) Prepare(ctx context.Context, req *query.PrepareRequest) (*query.PrepareResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Prepare not implemented") +} +func (*UnimplementedQueryServer) CommitPrepared(ctx context.Context, req *query.CommitPreparedRequest) (*query.CommitPreparedResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method CommitPrepared not implemented") +} +func (*UnimplementedQueryServer) RollbackPrepared(ctx context.Context, req *query.RollbackPreparedRequest) (*query.RollbackPreparedResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method RollbackPrepared not implemented") +} +func (*UnimplementedQueryServer) CreateTransaction(ctx context.Context, req *query.CreateTransactionRequest) (*query.CreateTransactionResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method CreateTransaction not implemented") +} +func (*UnimplementedQueryServer) StartCommit(ctx context.Context, req *query.StartCommitRequest) (*query.StartCommitResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method StartCommit not implemented") +} +func (*UnimplementedQueryServer) SetRollback(ctx context.Context, req *query.SetRollbackRequest) (*query.SetRollbackResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method SetRollback not implemented") +} +func (*UnimplementedQueryServer) ConcludeTransaction(ctx context.Context, req *query.ConcludeTransactionRequest) (*query.ConcludeTransactionResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ConcludeTransaction not implemented") +} +func (*UnimplementedQueryServer) ReadTransaction(ctx context.Context, req *query.ReadTransactionRequest) (*query.ReadTransactionResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ReadTransaction not implemented") +} +func (*UnimplementedQueryServer) BeginExecute(ctx context.Context, req *query.BeginExecuteRequest) (*query.BeginExecuteResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method BeginExecute not implemented") +} +func (*UnimplementedQueryServer) BeginExecuteBatch(ctx context.Context, req *query.BeginExecuteBatchRequest) (*query.BeginExecuteBatchResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method BeginExecuteBatch not implemented") +} +func (*UnimplementedQueryServer) MessageStream(req *query.MessageStreamRequest, srv Query_MessageStreamServer) error { + return status.Errorf(codes.Unimplemented, "method MessageStream not implemented") +} +func (*UnimplementedQueryServer) MessageAck(ctx context.Context, req *query.MessageAckRequest) (*query.MessageAckResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method MessageAck not implemented") +} +func (*UnimplementedQueryServer) SplitQuery(ctx context.Context, req *query.SplitQueryRequest) (*query.SplitQueryResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method SplitQuery not implemented") +} +func (*UnimplementedQueryServer) StreamHealth(req *query.StreamHealthRequest, srv Query_StreamHealthServer) error { + return status.Errorf(codes.Unimplemented, "method StreamHealth not implemented") +} +func (*UnimplementedQueryServer) UpdateStream(req *query.UpdateStreamRequest, srv Query_UpdateStreamServer) error { + return status.Errorf(codes.Unimplemented, "method UpdateStream not implemented") +} +func (*UnimplementedQueryServer) VStream(req *binlogdata.VStreamRequest, srv Query_VStreamServer) error { + return status.Errorf(codes.Unimplemented, "method VStream not implemented") +} +func (*UnimplementedQueryServer) VStreamRows(req *binlogdata.VStreamRowsRequest, srv Query_VStreamRowsServer) error { + return status.Errorf(codes.Unimplemented, "method VStreamRows not implemented") +} +func (*UnimplementedQueryServer) VStreamResults(req *binlogdata.VStreamResultsRequest, srv Query_VStreamResultsServer) error { + return status.Errorf(codes.Unimplemented, "method VStreamResults not implemented") } func RegisterQueryServer(s *grpc.Server, srv QueryServer) { @@ -938,6 +1096,27 @@ func (x *queryVStreamRowsServer) Send(m *binlogdata.VStreamRowsResponse) error { return x.ServerStream.SendMsg(m) } +func _Query_VStreamResults_Handler(srv interface{}, stream grpc.ServerStream) error { + m := new(binlogdata.VStreamResultsRequest) + if err := stream.RecvMsg(m); err != nil { + return err + } + return srv.(QueryServer).VStreamResults(m, &queryVStreamResultsServer{stream}) +} + +type Query_VStreamResultsServer interface { + Send(*binlogdata.VStreamResultsResponse) error + grpc.ServerStream +} + +type queryVStreamResultsServer struct { + grpc.ServerStream +} + +func (x *queryVStreamResultsServer) Send(m *binlogdata.VStreamResultsResponse) error { + return x.ServerStream.SendMsg(m) +} + var _Query_serviceDesc = grpc.ServiceDesc{ ServiceName: "queryservice.Query", HandlerType: (*QueryServer)(nil), @@ -1042,48 +1221,11 @@ var _Query_serviceDesc = grpc.ServiceDesc{ Handler: _Query_VStreamRows_Handler, ServerStreams: true, }, + { + StreamName: "VStreamResults", + Handler: _Query_VStreamResults_Handler, + ServerStreams: true, + }, }, Metadata: "queryservice.proto", } - -func init() { proto.RegisterFile("queryservice.proto", fileDescriptor_queryservice_98b01c0566d3f32e) } - -var fileDescriptor_queryservice_98b01c0566d3f32e = []byte{ - // 563 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x95, 0x4f, 0x6f, 0xd3, 0x4c, - 0x10, 0xc6, 0xdf, 0xf7, 0xd0, 0x06, 0x4d, 0x52, 0x28, 0x5b, 0x0a, 0xd4, 0x2d, 0x69, 0xe9, 0x0d, - 0x21, 0x25, 0x08, 0x90, 0x90, 0x2a, 0x71, 0x68, 0x2c, 0x2a, 0x50, 0xc5, 0x3f, 0x87, 0x56, 0x88, - 0x03, 0xd2, 0xc6, 0x5e, 0x05, 0xab, 0x8e, 0xd7, 0xf5, 0x6e, 0x52, 0xf8, 0x7c, 0x7c, 0x31, 0x84, - 0xd7, 0x33, 0xde, 0xdd, 0xd8, 0xdc, 0xb2, 0xcf, 0x33, 0xf3, 0xd3, 0x78, 0x27, 0x33, 0x0b, 0xec, - 0x7a, 0x29, 0xca, 0x5f, 0x4a, 0x94, 0xab, 0x34, 0x16, 0xa3, 0xa2, 0x94, 0x5a, 0xb2, 0x81, 0xad, - 0x05, 0xfd, 0xea, 0x64, 0xac, 0x60, 0x7b, 0x96, 0xe6, 0x99, 0x9c, 0x27, 0x5c, 0x73, 0xa3, 0x3c, - 0xff, 0xbd, 0x05, 0x1b, 0x9f, 0xff, 0x46, 0xb0, 0x13, 0xe8, 0xbd, 0xf9, 0x29, 0xe2, 0xa5, 0x16, - 0x6c, 0x77, 0x64, 0x92, 0xea, 0x73, 0x24, 0xae, 0x97, 0x42, 0xe9, 0xe0, 0xbe, 0x2f, 0xab, 0x42, - 0xe6, 0x4a, 0x1c, 0xff, 0xc7, 0xde, 0xc1, 0xa0, 0x16, 0x27, 0x5c, 0xc7, 0x3f, 0x58, 0xe0, 0x46, - 0x56, 0x22, 0x52, 0xf6, 0x5b, 0x3d, 0x42, 0x7d, 0x80, 0xad, 0xa9, 0x2e, 0x05, 0x5f, 0x60, 0x31, - 0x18, 0xef, 0xa8, 0x08, 0x3b, 0x68, 0x37, 0x91, 0xf6, 0xec, 0x7f, 0xf6, 0x12, 0x36, 0x26, 0x62, - 0x9e, 0xe6, 0x6c, 0xa7, 0x0e, 0xad, 0x4e, 0x98, 0x7f, 0xcf, 0x15, 0xa9, 0x8a, 0x57, 0xb0, 0x19, - 0xca, 0xc5, 0x22, 0xd5, 0x0c, 0x23, 0xcc, 0x11, 0xf3, 0x76, 0x3d, 0x95, 0x12, 0x5f, 0xc3, 0xad, - 0x48, 0x66, 0xd9, 0x8c, 0xc7, 0x57, 0x0c, 0xef, 0x0b, 0x05, 0x4c, 0x7e, 0xb0, 0xa6, 0x53, 0xfa, - 0x09, 0xf4, 0x3e, 0x95, 0xa2, 0xe0, 0x65, 0xd3, 0x84, 0xfa, 0xec, 0x37, 0x81, 0x64, 0xca, 0xfd, - 0x08, 0xb7, 0x4d, 0x39, 0xb5, 0x95, 0xb0, 0x03, 0xa7, 0x4a, 0x94, 0x91, 0xf4, 0xa8, 0xc3, 0x25, - 0xe0, 0x05, 0x6c, 0x63, 0x89, 0x84, 0x1c, 0x7a, 0xb5, 0xfb, 0xd0, 0xc3, 0x4e, 0x9f, 0xb0, 0x5f, - 0xe1, 0x6e, 0x58, 0x0a, 0xae, 0xc5, 0x97, 0x92, 0xe7, 0x8a, 0xc7, 0x3a, 0x95, 0x39, 0xc3, 0xbc, - 0x35, 0x07, 0xc1, 0x47, 0xdd, 0x01, 0x44, 0x3e, 0x83, 0xfe, 0x54, 0xf3, 0x52, 0xd7, 0xad, 0xdb, - 0xa3, 0x3f, 0x07, 0x69, 0x48, 0x0b, 0xda, 0x2c, 0x87, 0x23, 0x34, 0xf5, 0x91, 0x38, 0x8d, 0xb6, - 0xc6, 0xb1, 0x2d, 0xe2, 0x7c, 0x87, 0x9d, 0x50, 0xe6, 0x71, 0xb6, 0x4c, 0x9c, 0x6f, 0x7d, 0x4c, - 0x17, 0xbf, 0xe6, 0x21, 0xf7, 0xf8, 0x5f, 0x21, 0xc4, 0x8f, 0xe0, 0x4e, 0x24, 0x78, 0x62, 0xb3, - 0xb1, 0xa9, 0x9e, 0x8e, 0xdc, 0x61, 0x97, 0x6d, 0x8f, 0x72, 0x35, 0x0c, 0x38, 0x7e, 0x81, 0x3d, - 0x21, 0xde, 0xf4, 0xed, 0xb7, 0x7a, 0x76, 0xa3, 0x6d, 0xc7, 0xac, 0x86, 0xc3, 0x96, 0x1c, 0x67, - 0x3f, 0x1c, 0x75, 0x07, 0xd8, 0x4b, 0xe2, 0xbd, 0x50, 0x8a, 0xcf, 0x85, 0x19, 0x7c, 0x5a, 0x12, - 0x8e, 0xea, 0x2f, 0x09, 0xcf, 0xb4, 0x96, 0x44, 0x08, 0x50, 0x9b, 0xa7, 0xf1, 0x15, 0x7b, 0xe8, - 0xc6, 0x9f, 0x36, 0xed, 0xde, 0x6b, 0x71, 0xa8, 0xa8, 0x10, 0x60, 0x5a, 0x64, 0xa9, 0x36, 0xeb, - 0x14, 0x21, 0x8d, 0xe4, 0x43, 0x6c, 0x87, 0x20, 0xe7, 0x30, 0x30, 0xf5, 0xbd, 0x15, 0x3c, 0xd3, - 0xcd, 0x26, 0xb5, 0x45, 0xff, 0xfa, 0x5d, 0xcf, 0xfa, 0xac, 0x73, 0x18, 0x5c, 0x14, 0x09, 0xd7, - 0x78, 0x4b, 0x08, 0xb3, 0x45, 0x1f, 0xe6, 0x7a, 0x16, 0xec, 0x0c, 0x7a, 0x97, 0xc4, 0xb1, 0xde, - 0x91, 0x4b, 0x9f, 0xd3, 0xe6, 0x59, 0x9c, 0x08, 0xfa, 0x28, 0xcb, 0x1b, 0xc5, 0x86, 0x6d, 0xf1, - 0xf2, 0x46, 0x35, 0x0b, 0xa5, 0xcb, 0x6f, 0x98, 0x93, 0xa7, 0xdf, 0x9e, 0xac, 0x52, 0x2d, 0x94, - 0x1a, 0xa5, 0x72, 0x6c, 0x7e, 0x8d, 0xe7, 0x72, 0xbc, 0xd2, 0xe3, 0xea, 0x95, 0x1b, 0xdb, 0x2f, - 0xe2, 0x6c, 0xb3, 0xd2, 0x5e, 0xfc, 0x09, 0x00, 0x00, 0xff, 0xff, 0xdd, 0x23, 0x8f, 0x51, 0x3c, - 0x07, 0x00, 0x00, -} diff --git a/go/vt/proto/replicationdata/replicationdata.pb.go b/go/vt/proto/replicationdata/replicationdata.pb.go index 5104477b7c0..3924d47bb4f 100644 --- a/go/vt/proto/replicationdata/replicationdata.pb.go +++ b/go/vt/proto/replicationdata/replicationdata.pb.go @@ -1,11 +1,14 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // source: replicationdata.proto -package replicationdata // import "vitess.io/vitess/go/vt/proto/replicationdata" +package replicationdata -import proto "github.com/golang/protobuf/proto" -import fmt "fmt" -import math "math" +import ( + fmt "fmt" + math "math" + + proto "github.com/golang/protobuf/proto" +) // Reference imports to suppress errors if they are not otherwise used. var _ = proto.Marshal @@ -16,7 +19,7 @@ var _ = math.Inf // is compatible with the proto package it is being compiled against. // A compilation error at this line likely means your copy of the // proto package needs to be updated. -const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package +const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package // Status is the replication status for MySQL (returned by 'show slave status' // and parsed into a Position and fields). @@ -37,16 +40,17 @@ func (m *Status) Reset() { *m = Status{} } func (m *Status) String() string { return proto.CompactTextString(m) } func (*Status) ProtoMessage() {} func (*Status) Descriptor() ([]byte, []int) { - return fileDescriptor_replicationdata_1dfa1a45cfa5e522, []int{0} + return fileDescriptor_ee8ee22b8c4b9d06, []int{0} } + func (m *Status) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Status.Unmarshal(m, b) } func (m *Status) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_Status.Marshal(b, m, deterministic) } -func (dst *Status) XXX_Merge(src proto.Message) { - xxx_messageInfo_Status.Merge(dst, src) +func (m *Status) XXX_Merge(src proto.Message) { + xxx_messageInfo_Status.Merge(m, src) } func (m *Status) XXX_Size() int { return xxx_messageInfo_Status.Size(m) @@ -110,11 +114,9 @@ func init() { proto.RegisterType((*Status)(nil), "replicationdata.Status") } -func init() { - proto.RegisterFile("replicationdata.proto", fileDescriptor_replicationdata_1dfa1a45cfa5e522) -} +func init() { proto.RegisterFile("replicationdata.proto", fileDescriptor_ee8ee22b8c4b9d06) } -var fileDescriptor_replicationdata_1dfa1a45cfa5e522 = []byte{ +var fileDescriptor_ee8ee22b8c4b9d06 = []byte{ // 264 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x5c, 0x90, 0xc1, 0x4a, 0x03, 0x31, 0x10, 0x86, 0xd9, 0x6a, 0xd7, 0x1a, 0xd1, 0x6a, 0xb4, 0x10, 0xbc, 0xb8, 0x78, 0x5a, 0x44, 0x36, diff --git a/go/vt/proto/tableacl/tableacl.pb.go b/go/vt/proto/tableacl/tableacl.pb.go index 917663e342b..5fbfc778baa 100644 --- a/go/vt/proto/tableacl/tableacl.pb.go +++ b/go/vt/proto/tableacl/tableacl.pb.go @@ -1,11 +1,14 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // source: tableacl.proto -package tableacl // import "vitess.io/vitess/go/vt/proto/tableacl" +package tableacl -import proto "github.com/golang/protobuf/proto" -import fmt "fmt" -import math "math" +import ( + fmt "fmt" + math "math" + + proto "github.com/golang/protobuf/proto" +) // Reference imports to suppress errors if they are not otherwise used. var _ = proto.Marshal @@ -16,7 +19,7 @@ var _ = math.Inf // is compatible with the proto package it is being compiled against. // A compilation error at this line likely means your copy of the // proto package needs to be updated. -const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package +const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package // TableGroupSpec defines ACLs for a group of tables. type TableGroupSpec struct { @@ -35,16 +38,17 @@ func (m *TableGroupSpec) Reset() { *m = TableGroupSpec{} } func (m *TableGroupSpec) String() string { return proto.CompactTextString(m) } func (*TableGroupSpec) ProtoMessage() {} func (*TableGroupSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_tableacl_82b5f1376534b35e, []int{0} + return fileDescriptor_7d0bedb248a1632e, []int{0} } + func (m *TableGroupSpec) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_TableGroupSpec.Unmarshal(m, b) } func (m *TableGroupSpec) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_TableGroupSpec.Marshal(b, m, deterministic) } -func (dst *TableGroupSpec) XXX_Merge(src proto.Message) { - xxx_messageInfo_TableGroupSpec.Merge(dst, src) +func (m *TableGroupSpec) XXX_Merge(src proto.Message) { + xxx_messageInfo_TableGroupSpec.Merge(m, src) } func (m *TableGroupSpec) XXX_Size() int { return xxx_messageInfo_TableGroupSpec.Size(m) @@ -101,16 +105,17 @@ func (m *Config) Reset() { *m = Config{} } func (m *Config) String() string { return proto.CompactTextString(m) } func (*Config) ProtoMessage() {} func (*Config) Descriptor() ([]byte, []int) { - return fileDescriptor_tableacl_82b5f1376534b35e, []int{1} + return fileDescriptor_7d0bedb248a1632e, []int{1} } + func (m *Config) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Config.Unmarshal(m, b) } func (m *Config) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_Config.Marshal(b, m, deterministic) } -func (dst *Config) XXX_Merge(src proto.Message) { - xxx_messageInfo_Config.Merge(dst, src) +func (m *Config) XXX_Merge(src proto.Message) { + xxx_messageInfo_Config.Merge(m, src) } func (m *Config) XXX_Size() int { return xxx_messageInfo_Config.Size(m) @@ -133,9 +138,9 @@ func init() { proto.RegisterType((*Config)(nil), "tableacl.Config") } -func init() { proto.RegisterFile("tableacl.proto", fileDescriptor_tableacl_82b5f1376534b35e) } +func init() { proto.RegisterFile("tableacl.proto", fileDescriptor_7d0bedb248a1632e) } -var fileDescriptor_tableacl_82b5f1376534b35e = []byte{ +var fileDescriptor_7d0bedb248a1632e = []byte{ // 232 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x54, 0x90, 0xc1, 0x4b, 0xc3, 0x30, 0x14, 0xc6, 0x89, 0x9d, 0xd5, 0xbd, 0xc9, 0x0e, 0x41, 0x34, 0xc7, 0x32, 0x10, 0x7b, 0x6a, 0x40, diff --git a/go/vt/proto/tabletmanagerdata/tabletmanagerdata.pb.go b/go/vt/proto/tabletmanagerdata/tabletmanagerdata.pb.go index c574ee39be7..fd1f76410e8 100644 --- a/go/vt/proto/tabletmanagerdata/tabletmanagerdata.pb.go +++ b/go/vt/proto/tabletmanagerdata/tabletmanagerdata.pb.go @@ -1,15 +1,17 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // source: tabletmanagerdata.proto -package tabletmanagerdata // import "vitess.io/vitess/go/vt/proto/tabletmanagerdata" - -import proto "github.com/golang/protobuf/proto" -import fmt "fmt" -import math "math" -import logutil "vitess.io/vitess/go/vt/proto/logutil" -import query "vitess.io/vitess/go/vt/proto/query" -import replicationdata "vitess.io/vitess/go/vt/proto/replicationdata" -import topodata "vitess.io/vitess/go/vt/proto/topodata" +package tabletmanagerdata + +import ( + fmt "fmt" + proto "github.com/golang/protobuf/proto" + math "math" + logutil "vitess.io/vitess/go/vt/proto/logutil" + query "vitess.io/vitess/go/vt/proto/query" + replicationdata "vitess.io/vitess/go/vt/proto/replicationdata" + topodata "vitess.io/vitess/go/vt/proto/topodata" +) // Reference imports to suppress errors if they are not otherwise used. var _ = proto.Marshal @@ -20,7 +22,7 @@ var _ = math.Inf // is compatible with the proto package it is being compiled against. // A compilation error at this line likely means your copy of the // proto package needs to be updated. -const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package +const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package type TableDefinition struct { // the table name @@ -36,26 +38,30 @@ type TableDefinition struct { // how much space the data file takes. DataLength uint64 `protobuf:"varint,6,opt,name=data_length,json=dataLength,proto3" json:"data_length,omitempty"` // approximate number of rows - RowCount uint64 `protobuf:"varint,7,opt,name=row_count,json=rowCount,proto3" json:"row_count,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + RowCount uint64 `protobuf:"varint,7,opt,name=row_count,json=rowCount,proto3" json:"row_count,omitempty"` + // column names along with their types. + // NOTE: this is a superset of columns. + Fields []*query.Field `protobuf:"bytes,8,rep,name=fields,proto3" json:"fields,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *TableDefinition) Reset() { *m = TableDefinition{} } func (m *TableDefinition) String() string { return proto.CompactTextString(m) } func (*TableDefinition) ProtoMessage() {} func (*TableDefinition) Descriptor() ([]byte, []int) { - return fileDescriptor_tabletmanagerdata_3063cd7e973e1b02, []int{0} + return fileDescriptor_ff9ac4f89e61ffa4, []int{0} } + func (m *TableDefinition) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_TableDefinition.Unmarshal(m, b) } func (m *TableDefinition) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_TableDefinition.Marshal(b, m, deterministic) } -func (dst *TableDefinition) XXX_Merge(src proto.Message) { - xxx_messageInfo_TableDefinition.Merge(dst, src) +func (m *TableDefinition) XXX_Merge(src proto.Message) { + xxx_messageInfo_TableDefinition.Merge(m, src) } func (m *TableDefinition) XXX_Size() int { return xxx_messageInfo_TableDefinition.Size(m) @@ -115,6 +121,13 @@ func (m *TableDefinition) GetRowCount() uint64 { return 0 } +func (m *TableDefinition) GetFields() []*query.Field { + if m != nil { + return m.Fields + } + return nil +} + type SchemaDefinition struct { DatabaseSchema string `protobuf:"bytes,1,opt,name=database_schema,json=databaseSchema,proto3" json:"database_schema,omitempty"` TableDefinitions []*TableDefinition `protobuf:"bytes,2,rep,name=table_definitions,json=tableDefinitions,proto3" json:"table_definitions,omitempty"` @@ -128,16 +141,17 @@ func (m *SchemaDefinition) Reset() { *m = SchemaDefinition{} } func (m *SchemaDefinition) String() string { return proto.CompactTextString(m) } func (*SchemaDefinition) ProtoMessage() {} func (*SchemaDefinition) Descriptor() ([]byte, []int) { - return fileDescriptor_tabletmanagerdata_3063cd7e973e1b02, []int{1} + return fileDescriptor_ff9ac4f89e61ffa4, []int{1} } + func (m *SchemaDefinition) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_SchemaDefinition.Unmarshal(m, b) } func (m *SchemaDefinition) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_SchemaDefinition.Marshal(b, m, deterministic) } -func (dst *SchemaDefinition) XXX_Merge(src proto.Message) { - xxx_messageInfo_SchemaDefinition.Merge(dst, src) +func (m *SchemaDefinition) XXX_Merge(src proto.Message) { + xxx_messageInfo_SchemaDefinition.Merge(m, src) } func (m *SchemaDefinition) XXX_Size() int { return xxx_messageInfo_SchemaDefinition.Size(m) @@ -183,16 +197,17 @@ func (m *SchemaChangeResult) Reset() { *m = SchemaChangeResult{} } func (m *SchemaChangeResult) String() string { return proto.CompactTextString(m) } func (*SchemaChangeResult) ProtoMessage() {} func (*SchemaChangeResult) Descriptor() ([]byte, []int) { - return fileDescriptor_tabletmanagerdata_3063cd7e973e1b02, []int{2} + return fileDescriptor_ff9ac4f89e61ffa4, []int{2} } + func (m *SchemaChangeResult) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_SchemaChangeResult.Unmarshal(m, b) } func (m *SchemaChangeResult) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_SchemaChangeResult.Marshal(b, m, deterministic) } -func (dst *SchemaChangeResult) XXX_Merge(src proto.Message) { - xxx_messageInfo_SchemaChangeResult.Merge(dst, src) +func (m *SchemaChangeResult) XXX_Merge(src proto.Message) { + xxx_messageInfo_SchemaChangeResult.Merge(m, src) } func (m *SchemaChangeResult) XXX_Size() int { return xxx_messageInfo_SchemaChangeResult.Size(m) @@ -234,16 +249,17 @@ func (m *UserPermission) Reset() { *m = UserPermission{} } func (m *UserPermission) String() string { return proto.CompactTextString(m) } func (*UserPermission) ProtoMessage() {} func (*UserPermission) Descriptor() ([]byte, []int) { - return fileDescriptor_tabletmanagerdata_3063cd7e973e1b02, []int{3} + return fileDescriptor_ff9ac4f89e61ffa4, []int{3} } + func (m *UserPermission) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_UserPermission.Unmarshal(m, b) } func (m *UserPermission) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_UserPermission.Marshal(b, m, deterministic) } -func (dst *UserPermission) XXX_Merge(src proto.Message) { - xxx_messageInfo_UserPermission.Merge(dst, src) +func (m *UserPermission) XXX_Merge(src proto.Message) { + xxx_messageInfo_UserPermission.Merge(m, src) } func (m *UserPermission) XXX_Size() int { return xxx_messageInfo_UserPermission.Size(m) @@ -298,16 +314,17 @@ func (m *DbPermission) Reset() { *m = DbPermission{} } func (m *DbPermission) String() string { return proto.CompactTextString(m) } func (*DbPermission) ProtoMessage() {} func (*DbPermission) Descriptor() ([]byte, []int) { - return fileDescriptor_tabletmanagerdata_3063cd7e973e1b02, []int{4} + return fileDescriptor_ff9ac4f89e61ffa4, []int{4} } + func (m *DbPermission) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_DbPermission.Unmarshal(m, b) } func (m *DbPermission) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_DbPermission.Marshal(b, m, deterministic) } -func (dst *DbPermission) XXX_Merge(src proto.Message) { - xxx_messageInfo_DbPermission.Merge(dst, src) +func (m *DbPermission) XXX_Merge(src proto.Message) { + xxx_messageInfo_DbPermission.Merge(m, src) } func (m *DbPermission) XXX_Size() int { return xxx_messageInfo_DbPermission.Size(m) @@ -360,16 +377,17 @@ func (m *Permissions) Reset() { *m = Permissions{} } func (m *Permissions) String() string { return proto.CompactTextString(m) } func (*Permissions) ProtoMessage() {} func (*Permissions) Descriptor() ([]byte, []int) { - return fileDescriptor_tabletmanagerdata_3063cd7e973e1b02, []int{5} + return fileDescriptor_ff9ac4f89e61ffa4, []int{5} } + func (m *Permissions) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Permissions.Unmarshal(m, b) } func (m *Permissions) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_Permissions.Marshal(b, m, deterministic) } -func (dst *Permissions) XXX_Merge(src proto.Message) { - xxx_messageInfo_Permissions.Merge(dst, src) +func (m *Permissions) XXX_Merge(src proto.Message) { + xxx_messageInfo_Permissions.Merge(m, src) } func (m *Permissions) XXX_Size() int { return xxx_messageInfo_Permissions.Size(m) @@ -405,16 +423,17 @@ func (m *PingRequest) Reset() { *m = PingRequest{} } func (m *PingRequest) String() string { return proto.CompactTextString(m) } func (*PingRequest) ProtoMessage() {} func (*PingRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_tabletmanagerdata_3063cd7e973e1b02, []int{6} + return fileDescriptor_ff9ac4f89e61ffa4, []int{6} } + func (m *PingRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_PingRequest.Unmarshal(m, b) } func (m *PingRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_PingRequest.Marshal(b, m, deterministic) } -func (dst *PingRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_PingRequest.Merge(dst, src) +func (m *PingRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_PingRequest.Merge(m, src) } func (m *PingRequest) XXX_Size() int { return xxx_messageInfo_PingRequest.Size(m) @@ -443,16 +462,17 @@ func (m *PingResponse) Reset() { *m = PingResponse{} } func (m *PingResponse) String() string { return proto.CompactTextString(m) } func (*PingResponse) ProtoMessage() {} func (*PingResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_tabletmanagerdata_3063cd7e973e1b02, []int{7} + return fileDescriptor_ff9ac4f89e61ffa4, []int{7} } + func (m *PingResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_PingResponse.Unmarshal(m, b) } func (m *PingResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_PingResponse.Marshal(b, m, deterministic) } -func (dst *PingResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_PingResponse.Merge(dst, src) +func (m *PingResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_PingResponse.Merge(m, src) } func (m *PingResponse) XXX_Size() int { return xxx_messageInfo_PingResponse.Size(m) @@ -482,16 +502,17 @@ func (m *SleepRequest) Reset() { *m = SleepRequest{} } func (m *SleepRequest) String() string { return proto.CompactTextString(m) } func (*SleepRequest) ProtoMessage() {} func (*SleepRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_tabletmanagerdata_3063cd7e973e1b02, []int{8} + return fileDescriptor_ff9ac4f89e61ffa4, []int{8} } + func (m *SleepRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_SleepRequest.Unmarshal(m, b) } func (m *SleepRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_SleepRequest.Marshal(b, m, deterministic) } -func (dst *SleepRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_SleepRequest.Merge(dst, src) +func (m *SleepRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_SleepRequest.Merge(m, src) } func (m *SleepRequest) XXX_Size() int { return xxx_messageInfo_SleepRequest.Size(m) @@ -519,16 +540,17 @@ func (m *SleepResponse) Reset() { *m = SleepResponse{} } func (m *SleepResponse) String() string { return proto.CompactTextString(m) } func (*SleepResponse) ProtoMessage() {} func (*SleepResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_tabletmanagerdata_3063cd7e973e1b02, []int{9} + return fileDescriptor_ff9ac4f89e61ffa4, []int{9} } + func (m *SleepResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_SleepResponse.Unmarshal(m, b) } func (m *SleepResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_SleepResponse.Marshal(b, m, deterministic) } -func (dst *SleepResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_SleepResponse.Merge(dst, src) +func (m *SleepResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_SleepResponse.Merge(m, src) } func (m *SleepResponse) XXX_Size() int { return xxx_messageInfo_SleepResponse.Size(m) @@ -552,16 +574,17 @@ func (m *ExecuteHookRequest) Reset() { *m = ExecuteHookRequest{} } func (m *ExecuteHookRequest) String() string { return proto.CompactTextString(m) } func (*ExecuteHookRequest) ProtoMessage() {} func (*ExecuteHookRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_tabletmanagerdata_3063cd7e973e1b02, []int{10} + return fileDescriptor_ff9ac4f89e61ffa4, []int{10} } + func (m *ExecuteHookRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ExecuteHookRequest.Unmarshal(m, b) } func (m *ExecuteHookRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_ExecuteHookRequest.Marshal(b, m, deterministic) } -func (dst *ExecuteHookRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_ExecuteHookRequest.Merge(dst, src) +func (m *ExecuteHookRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_ExecuteHookRequest.Merge(m, src) } func (m *ExecuteHookRequest) XXX_Size() int { return xxx_messageInfo_ExecuteHookRequest.Size(m) @@ -606,16 +629,17 @@ func (m *ExecuteHookResponse) Reset() { *m = ExecuteHookResponse{} } func (m *ExecuteHookResponse) String() string { return proto.CompactTextString(m) } func (*ExecuteHookResponse) ProtoMessage() {} func (*ExecuteHookResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_tabletmanagerdata_3063cd7e973e1b02, []int{11} + return fileDescriptor_ff9ac4f89e61ffa4, []int{11} } + func (m *ExecuteHookResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ExecuteHookResponse.Unmarshal(m, b) } func (m *ExecuteHookResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_ExecuteHookResponse.Marshal(b, m, deterministic) } -func (dst *ExecuteHookResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_ExecuteHookResponse.Merge(dst, src) +func (m *ExecuteHookResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_ExecuteHookResponse.Merge(m, src) } func (m *ExecuteHookResponse) XXX_Size() int { return xxx_messageInfo_ExecuteHookResponse.Size(m) @@ -660,16 +684,17 @@ func (m *GetSchemaRequest) Reset() { *m = GetSchemaRequest{} } func (m *GetSchemaRequest) String() string { return proto.CompactTextString(m) } func (*GetSchemaRequest) ProtoMessage() {} func (*GetSchemaRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_tabletmanagerdata_3063cd7e973e1b02, []int{12} + return fileDescriptor_ff9ac4f89e61ffa4, []int{12} } + func (m *GetSchemaRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_GetSchemaRequest.Unmarshal(m, b) } func (m *GetSchemaRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_GetSchemaRequest.Marshal(b, m, deterministic) } -func (dst *GetSchemaRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_GetSchemaRequest.Merge(dst, src) +func (m *GetSchemaRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_GetSchemaRequest.Merge(m, src) } func (m *GetSchemaRequest) XXX_Size() int { return xxx_messageInfo_GetSchemaRequest.Size(m) @@ -712,16 +737,17 @@ func (m *GetSchemaResponse) Reset() { *m = GetSchemaResponse{} } func (m *GetSchemaResponse) String() string { return proto.CompactTextString(m) } func (*GetSchemaResponse) ProtoMessage() {} func (*GetSchemaResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_tabletmanagerdata_3063cd7e973e1b02, []int{13} + return fileDescriptor_ff9ac4f89e61ffa4, []int{13} } + func (m *GetSchemaResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_GetSchemaResponse.Unmarshal(m, b) } func (m *GetSchemaResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_GetSchemaResponse.Marshal(b, m, deterministic) } -func (dst *GetSchemaResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_GetSchemaResponse.Merge(dst, src) +func (m *GetSchemaResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_GetSchemaResponse.Merge(m, src) } func (m *GetSchemaResponse) XXX_Size() int { return xxx_messageInfo_GetSchemaResponse.Size(m) @@ -749,16 +775,17 @@ func (m *GetPermissionsRequest) Reset() { *m = GetPermissionsRequest{} } func (m *GetPermissionsRequest) String() string { return proto.CompactTextString(m) } func (*GetPermissionsRequest) ProtoMessage() {} func (*GetPermissionsRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_tabletmanagerdata_3063cd7e973e1b02, []int{14} + return fileDescriptor_ff9ac4f89e61ffa4, []int{14} } + func (m *GetPermissionsRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_GetPermissionsRequest.Unmarshal(m, b) } func (m *GetPermissionsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_GetPermissionsRequest.Marshal(b, m, deterministic) } -func (dst *GetPermissionsRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_GetPermissionsRequest.Merge(dst, src) +func (m *GetPermissionsRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_GetPermissionsRequest.Merge(m, src) } func (m *GetPermissionsRequest) XXX_Size() int { return xxx_messageInfo_GetPermissionsRequest.Size(m) @@ -780,16 +807,17 @@ func (m *GetPermissionsResponse) Reset() { *m = GetPermissionsResponse{} func (m *GetPermissionsResponse) String() string { return proto.CompactTextString(m) } func (*GetPermissionsResponse) ProtoMessage() {} func (*GetPermissionsResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_tabletmanagerdata_3063cd7e973e1b02, []int{15} + return fileDescriptor_ff9ac4f89e61ffa4, []int{15} } + func (m *GetPermissionsResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_GetPermissionsResponse.Unmarshal(m, b) } func (m *GetPermissionsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_GetPermissionsResponse.Marshal(b, m, deterministic) } -func (dst *GetPermissionsResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_GetPermissionsResponse.Merge(dst, src) +func (m *GetPermissionsResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_GetPermissionsResponse.Merge(m, src) } func (m *GetPermissionsResponse) XXX_Size() int { return xxx_messageInfo_GetPermissionsResponse.Size(m) @@ -817,16 +845,17 @@ func (m *SetReadOnlyRequest) Reset() { *m = SetReadOnlyRequest{} } func (m *SetReadOnlyRequest) String() string { return proto.CompactTextString(m) } func (*SetReadOnlyRequest) ProtoMessage() {} func (*SetReadOnlyRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_tabletmanagerdata_3063cd7e973e1b02, []int{16} + return fileDescriptor_ff9ac4f89e61ffa4, []int{16} } + func (m *SetReadOnlyRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_SetReadOnlyRequest.Unmarshal(m, b) } func (m *SetReadOnlyRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_SetReadOnlyRequest.Marshal(b, m, deterministic) } -func (dst *SetReadOnlyRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_SetReadOnlyRequest.Merge(dst, src) +func (m *SetReadOnlyRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_SetReadOnlyRequest.Merge(m, src) } func (m *SetReadOnlyRequest) XXX_Size() int { return xxx_messageInfo_SetReadOnlyRequest.Size(m) @@ -847,16 +876,17 @@ func (m *SetReadOnlyResponse) Reset() { *m = SetReadOnlyResponse{} } func (m *SetReadOnlyResponse) String() string { return proto.CompactTextString(m) } func (*SetReadOnlyResponse) ProtoMessage() {} func (*SetReadOnlyResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_tabletmanagerdata_3063cd7e973e1b02, []int{17} + return fileDescriptor_ff9ac4f89e61ffa4, []int{17} } + func (m *SetReadOnlyResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_SetReadOnlyResponse.Unmarshal(m, b) } func (m *SetReadOnlyResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_SetReadOnlyResponse.Marshal(b, m, deterministic) } -func (dst *SetReadOnlyResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_SetReadOnlyResponse.Merge(dst, src) +func (m *SetReadOnlyResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_SetReadOnlyResponse.Merge(m, src) } func (m *SetReadOnlyResponse) XXX_Size() int { return xxx_messageInfo_SetReadOnlyResponse.Size(m) @@ -877,16 +907,17 @@ func (m *SetReadWriteRequest) Reset() { *m = SetReadWriteRequest{} } func (m *SetReadWriteRequest) String() string { return proto.CompactTextString(m) } func (*SetReadWriteRequest) ProtoMessage() {} func (*SetReadWriteRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_tabletmanagerdata_3063cd7e973e1b02, []int{18} + return fileDescriptor_ff9ac4f89e61ffa4, []int{18} } + func (m *SetReadWriteRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_SetReadWriteRequest.Unmarshal(m, b) } func (m *SetReadWriteRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_SetReadWriteRequest.Marshal(b, m, deterministic) } -func (dst *SetReadWriteRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_SetReadWriteRequest.Merge(dst, src) +func (m *SetReadWriteRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_SetReadWriteRequest.Merge(m, src) } func (m *SetReadWriteRequest) XXX_Size() int { return xxx_messageInfo_SetReadWriteRequest.Size(m) @@ -907,16 +938,17 @@ func (m *SetReadWriteResponse) Reset() { *m = SetReadWriteResponse{} } func (m *SetReadWriteResponse) String() string { return proto.CompactTextString(m) } func (*SetReadWriteResponse) ProtoMessage() {} func (*SetReadWriteResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_tabletmanagerdata_3063cd7e973e1b02, []int{19} + return fileDescriptor_ff9ac4f89e61ffa4, []int{19} } + func (m *SetReadWriteResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_SetReadWriteResponse.Unmarshal(m, b) } func (m *SetReadWriteResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_SetReadWriteResponse.Marshal(b, m, deterministic) } -func (dst *SetReadWriteResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_SetReadWriteResponse.Merge(dst, src) +func (m *SetReadWriteResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_SetReadWriteResponse.Merge(m, src) } func (m *SetReadWriteResponse) XXX_Size() int { return xxx_messageInfo_SetReadWriteResponse.Size(m) @@ -938,16 +970,17 @@ func (m *ChangeTypeRequest) Reset() { *m = ChangeTypeRequest{} } func (m *ChangeTypeRequest) String() string { return proto.CompactTextString(m) } func (*ChangeTypeRequest) ProtoMessage() {} func (*ChangeTypeRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_tabletmanagerdata_3063cd7e973e1b02, []int{20} + return fileDescriptor_ff9ac4f89e61ffa4, []int{20} } + func (m *ChangeTypeRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ChangeTypeRequest.Unmarshal(m, b) } func (m *ChangeTypeRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_ChangeTypeRequest.Marshal(b, m, deterministic) } -func (dst *ChangeTypeRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_ChangeTypeRequest.Merge(dst, src) +func (m *ChangeTypeRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_ChangeTypeRequest.Merge(m, src) } func (m *ChangeTypeRequest) XXX_Size() int { return xxx_messageInfo_ChangeTypeRequest.Size(m) @@ -975,16 +1008,17 @@ func (m *ChangeTypeResponse) Reset() { *m = ChangeTypeResponse{} } func (m *ChangeTypeResponse) String() string { return proto.CompactTextString(m) } func (*ChangeTypeResponse) ProtoMessage() {} func (*ChangeTypeResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_tabletmanagerdata_3063cd7e973e1b02, []int{21} + return fileDescriptor_ff9ac4f89e61ffa4, []int{21} } + func (m *ChangeTypeResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ChangeTypeResponse.Unmarshal(m, b) } func (m *ChangeTypeResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_ChangeTypeResponse.Marshal(b, m, deterministic) } -func (dst *ChangeTypeResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_ChangeTypeResponse.Merge(dst, src) +func (m *ChangeTypeResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_ChangeTypeResponse.Merge(m, src) } func (m *ChangeTypeResponse) XXX_Size() int { return xxx_messageInfo_ChangeTypeResponse.Size(m) @@ -1005,16 +1039,17 @@ func (m *RefreshStateRequest) Reset() { *m = RefreshStateRequest{} } func (m *RefreshStateRequest) String() string { return proto.CompactTextString(m) } func (*RefreshStateRequest) ProtoMessage() {} func (*RefreshStateRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_tabletmanagerdata_3063cd7e973e1b02, []int{22} + return fileDescriptor_ff9ac4f89e61ffa4, []int{22} } + func (m *RefreshStateRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_RefreshStateRequest.Unmarshal(m, b) } func (m *RefreshStateRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_RefreshStateRequest.Marshal(b, m, deterministic) } -func (dst *RefreshStateRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_RefreshStateRequest.Merge(dst, src) +func (m *RefreshStateRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_RefreshStateRequest.Merge(m, src) } func (m *RefreshStateRequest) XXX_Size() int { return xxx_messageInfo_RefreshStateRequest.Size(m) @@ -1035,16 +1070,17 @@ func (m *RefreshStateResponse) Reset() { *m = RefreshStateResponse{} } func (m *RefreshStateResponse) String() string { return proto.CompactTextString(m) } func (*RefreshStateResponse) ProtoMessage() {} func (*RefreshStateResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_tabletmanagerdata_3063cd7e973e1b02, []int{23} + return fileDescriptor_ff9ac4f89e61ffa4, []int{23} } + func (m *RefreshStateResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_RefreshStateResponse.Unmarshal(m, b) } func (m *RefreshStateResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_RefreshStateResponse.Marshal(b, m, deterministic) } -func (dst *RefreshStateResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_RefreshStateResponse.Merge(dst, src) +func (m *RefreshStateResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_RefreshStateResponse.Merge(m, src) } func (m *RefreshStateResponse) XXX_Size() int { return xxx_messageInfo_RefreshStateResponse.Size(m) @@ -1065,16 +1101,17 @@ func (m *RunHealthCheckRequest) Reset() { *m = RunHealthCheckRequest{} } func (m *RunHealthCheckRequest) String() string { return proto.CompactTextString(m) } func (*RunHealthCheckRequest) ProtoMessage() {} func (*RunHealthCheckRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_tabletmanagerdata_3063cd7e973e1b02, []int{24} + return fileDescriptor_ff9ac4f89e61ffa4, []int{24} } + func (m *RunHealthCheckRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_RunHealthCheckRequest.Unmarshal(m, b) } func (m *RunHealthCheckRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_RunHealthCheckRequest.Marshal(b, m, deterministic) } -func (dst *RunHealthCheckRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_RunHealthCheckRequest.Merge(dst, src) +func (m *RunHealthCheckRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_RunHealthCheckRequest.Merge(m, src) } func (m *RunHealthCheckRequest) XXX_Size() int { return xxx_messageInfo_RunHealthCheckRequest.Size(m) @@ -1095,16 +1132,17 @@ func (m *RunHealthCheckResponse) Reset() { *m = RunHealthCheckResponse{} func (m *RunHealthCheckResponse) String() string { return proto.CompactTextString(m) } func (*RunHealthCheckResponse) ProtoMessage() {} func (*RunHealthCheckResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_tabletmanagerdata_3063cd7e973e1b02, []int{25} + return fileDescriptor_ff9ac4f89e61ffa4, []int{25} } + func (m *RunHealthCheckResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_RunHealthCheckResponse.Unmarshal(m, b) } func (m *RunHealthCheckResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_RunHealthCheckResponse.Marshal(b, m, deterministic) } -func (dst *RunHealthCheckResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_RunHealthCheckResponse.Merge(dst, src) +func (m *RunHealthCheckResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_RunHealthCheckResponse.Merge(m, src) } func (m *RunHealthCheckResponse) XXX_Size() int { return xxx_messageInfo_RunHealthCheckResponse.Size(m) @@ -1126,16 +1164,17 @@ func (m *IgnoreHealthErrorRequest) Reset() { *m = IgnoreHealthErrorReque func (m *IgnoreHealthErrorRequest) String() string { return proto.CompactTextString(m) } func (*IgnoreHealthErrorRequest) ProtoMessage() {} func (*IgnoreHealthErrorRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_tabletmanagerdata_3063cd7e973e1b02, []int{26} + return fileDescriptor_ff9ac4f89e61ffa4, []int{26} } + func (m *IgnoreHealthErrorRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_IgnoreHealthErrorRequest.Unmarshal(m, b) } func (m *IgnoreHealthErrorRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_IgnoreHealthErrorRequest.Marshal(b, m, deterministic) } -func (dst *IgnoreHealthErrorRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_IgnoreHealthErrorRequest.Merge(dst, src) +func (m *IgnoreHealthErrorRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_IgnoreHealthErrorRequest.Merge(m, src) } func (m *IgnoreHealthErrorRequest) XXX_Size() int { return xxx_messageInfo_IgnoreHealthErrorRequest.Size(m) @@ -1163,16 +1202,17 @@ func (m *IgnoreHealthErrorResponse) Reset() { *m = IgnoreHealthErrorResp func (m *IgnoreHealthErrorResponse) String() string { return proto.CompactTextString(m) } func (*IgnoreHealthErrorResponse) ProtoMessage() {} func (*IgnoreHealthErrorResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_tabletmanagerdata_3063cd7e973e1b02, []int{27} + return fileDescriptor_ff9ac4f89e61ffa4, []int{27} } + func (m *IgnoreHealthErrorResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_IgnoreHealthErrorResponse.Unmarshal(m, b) } func (m *IgnoreHealthErrorResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_IgnoreHealthErrorResponse.Marshal(b, m, deterministic) } -func (dst *IgnoreHealthErrorResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_IgnoreHealthErrorResponse.Merge(dst, src) +func (m *IgnoreHealthErrorResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_IgnoreHealthErrorResponse.Merge(m, src) } func (m *IgnoreHealthErrorResponse) XXX_Size() int { return xxx_messageInfo_IgnoreHealthErrorResponse.Size(m) @@ -1197,16 +1237,17 @@ func (m *ReloadSchemaRequest) Reset() { *m = ReloadSchemaRequest{} } func (m *ReloadSchemaRequest) String() string { return proto.CompactTextString(m) } func (*ReloadSchemaRequest) ProtoMessage() {} func (*ReloadSchemaRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_tabletmanagerdata_3063cd7e973e1b02, []int{28} + return fileDescriptor_ff9ac4f89e61ffa4, []int{28} } + func (m *ReloadSchemaRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ReloadSchemaRequest.Unmarshal(m, b) } func (m *ReloadSchemaRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_ReloadSchemaRequest.Marshal(b, m, deterministic) } -func (dst *ReloadSchemaRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_ReloadSchemaRequest.Merge(dst, src) +func (m *ReloadSchemaRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_ReloadSchemaRequest.Merge(m, src) } func (m *ReloadSchemaRequest) XXX_Size() int { return xxx_messageInfo_ReloadSchemaRequest.Size(m) @@ -1234,16 +1275,17 @@ func (m *ReloadSchemaResponse) Reset() { *m = ReloadSchemaResponse{} } func (m *ReloadSchemaResponse) String() string { return proto.CompactTextString(m) } func (*ReloadSchemaResponse) ProtoMessage() {} func (*ReloadSchemaResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_tabletmanagerdata_3063cd7e973e1b02, []int{29} + return fileDescriptor_ff9ac4f89e61ffa4, []int{29} } + func (m *ReloadSchemaResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ReloadSchemaResponse.Unmarshal(m, b) } func (m *ReloadSchemaResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_ReloadSchemaResponse.Marshal(b, m, deterministic) } -func (dst *ReloadSchemaResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_ReloadSchemaResponse.Merge(dst, src) +func (m *ReloadSchemaResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_ReloadSchemaResponse.Merge(m, src) } func (m *ReloadSchemaResponse) XXX_Size() int { return xxx_messageInfo_ReloadSchemaResponse.Size(m) @@ -1265,16 +1307,17 @@ func (m *PreflightSchemaRequest) Reset() { *m = PreflightSchemaRequest{} func (m *PreflightSchemaRequest) String() string { return proto.CompactTextString(m) } func (*PreflightSchemaRequest) ProtoMessage() {} func (*PreflightSchemaRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_tabletmanagerdata_3063cd7e973e1b02, []int{30} + return fileDescriptor_ff9ac4f89e61ffa4, []int{30} } + func (m *PreflightSchemaRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_PreflightSchemaRequest.Unmarshal(m, b) } func (m *PreflightSchemaRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_PreflightSchemaRequest.Marshal(b, m, deterministic) } -func (dst *PreflightSchemaRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_PreflightSchemaRequest.Merge(dst, src) +func (m *PreflightSchemaRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_PreflightSchemaRequest.Merge(m, src) } func (m *PreflightSchemaRequest) XXX_Size() int { return xxx_messageInfo_PreflightSchemaRequest.Size(m) @@ -1305,16 +1348,17 @@ func (m *PreflightSchemaResponse) Reset() { *m = PreflightSchemaResponse func (m *PreflightSchemaResponse) String() string { return proto.CompactTextString(m) } func (*PreflightSchemaResponse) ProtoMessage() {} func (*PreflightSchemaResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_tabletmanagerdata_3063cd7e973e1b02, []int{31} + return fileDescriptor_ff9ac4f89e61ffa4, []int{31} } + func (m *PreflightSchemaResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_PreflightSchemaResponse.Unmarshal(m, b) } func (m *PreflightSchemaResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_PreflightSchemaResponse.Marshal(b, m, deterministic) } -func (dst *PreflightSchemaResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_PreflightSchemaResponse.Merge(dst, src) +func (m *PreflightSchemaResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_PreflightSchemaResponse.Merge(m, src) } func (m *PreflightSchemaResponse) XXX_Size() int { return xxx_messageInfo_PreflightSchemaResponse.Size(m) @@ -1347,16 +1391,17 @@ func (m *ApplySchemaRequest) Reset() { *m = ApplySchemaRequest{} } func (m *ApplySchemaRequest) String() string { return proto.CompactTextString(m) } func (*ApplySchemaRequest) ProtoMessage() {} func (*ApplySchemaRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_tabletmanagerdata_3063cd7e973e1b02, []int{32} + return fileDescriptor_ff9ac4f89e61ffa4, []int{32} } + func (m *ApplySchemaRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ApplySchemaRequest.Unmarshal(m, b) } func (m *ApplySchemaRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_ApplySchemaRequest.Marshal(b, m, deterministic) } -func (dst *ApplySchemaRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_ApplySchemaRequest.Merge(dst, src) +func (m *ApplySchemaRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_ApplySchemaRequest.Merge(m, src) } func (m *ApplySchemaRequest) XXX_Size() int { return xxx_messageInfo_ApplySchemaRequest.Size(m) @@ -1414,16 +1459,17 @@ func (m *ApplySchemaResponse) Reset() { *m = ApplySchemaResponse{} } func (m *ApplySchemaResponse) String() string { return proto.CompactTextString(m) } func (*ApplySchemaResponse) ProtoMessage() {} func (*ApplySchemaResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_tabletmanagerdata_3063cd7e973e1b02, []int{33} + return fileDescriptor_ff9ac4f89e61ffa4, []int{33} } + func (m *ApplySchemaResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ApplySchemaResponse.Unmarshal(m, b) } func (m *ApplySchemaResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_ApplySchemaResponse.Marshal(b, m, deterministic) } -func (dst *ApplySchemaResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_ApplySchemaResponse.Merge(dst, src) +func (m *ApplySchemaResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_ApplySchemaResponse.Merge(m, src) } func (m *ApplySchemaResponse) XXX_Size() int { return xxx_messageInfo_ApplySchemaResponse.Size(m) @@ -1458,16 +1504,17 @@ func (m *LockTablesRequest) Reset() { *m = LockTablesRequest{} } func (m *LockTablesRequest) String() string { return proto.CompactTextString(m) } func (*LockTablesRequest) ProtoMessage() {} func (*LockTablesRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_tabletmanagerdata_3063cd7e973e1b02, []int{34} + return fileDescriptor_ff9ac4f89e61ffa4, []int{34} } + func (m *LockTablesRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_LockTablesRequest.Unmarshal(m, b) } func (m *LockTablesRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_LockTablesRequest.Marshal(b, m, deterministic) } -func (dst *LockTablesRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_LockTablesRequest.Merge(dst, src) +func (m *LockTablesRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_LockTablesRequest.Merge(m, src) } func (m *LockTablesRequest) XXX_Size() int { return xxx_messageInfo_LockTablesRequest.Size(m) @@ -1488,16 +1535,17 @@ func (m *LockTablesResponse) Reset() { *m = LockTablesResponse{} } func (m *LockTablesResponse) String() string { return proto.CompactTextString(m) } func (*LockTablesResponse) ProtoMessage() {} func (*LockTablesResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_tabletmanagerdata_3063cd7e973e1b02, []int{35} + return fileDescriptor_ff9ac4f89e61ffa4, []int{35} } + func (m *LockTablesResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_LockTablesResponse.Unmarshal(m, b) } func (m *LockTablesResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_LockTablesResponse.Marshal(b, m, deterministic) } -func (dst *LockTablesResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_LockTablesResponse.Merge(dst, src) +func (m *LockTablesResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_LockTablesResponse.Merge(m, src) } func (m *LockTablesResponse) XXX_Size() int { return xxx_messageInfo_LockTablesResponse.Size(m) @@ -1518,16 +1566,17 @@ func (m *UnlockTablesRequest) Reset() { *m = UnlockTablesRequest{} } func (m *UnlockTablesRequest) String() string { return proto.CompactTextString(m) } func (*UnlockTablesRequest) ProtoMessage() {} func (*UnlockTablesRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_tabletmanagerdata_3063cd7e973e1b02, []int{36} + return fileDescriptor_ff9ac4f89e61ffa4, []int{36} } + func (m *UnlockTablesRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_UnlockTablesRequest.Unmarshal(m, b) } func (m *UnlockTablesRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_UnlockTablesRequest.Marshal(b, m, deterministic) } -func (dst *UnlockTablesRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_UnlockTablesRequest.Merge(dst, src) +func (m *UnlockTablesRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_UnlockTablesRequest.Merge(m, src) } func (m *UnlockTablesRequest) XXX_Size() int { return xxx_messageInfo_UnlockTablesRequest.Size(m) @@ -1548,16 +1597,17 @@ func (m *UnlockTablesResponse) Reset() { *m = UnlockTablesResponse{} } func (m *UnlockTablesResponse) String() string { return proto.CompactTextString(m) } func (*UnlockTablesResponse) ProtoMessage() {} func (*UnlockTablesResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_tabletmanagerdata_3063cd7e973e1b02, []int{37} + return fileDescriptor_ff9ac4f89e61ffa4, []int{37} } + func (m *UnlockTablesResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_UnlockTablesResponse.Unmarshal(m, b) } func (m *UnlockTablesResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_UnlockTablesResponse.Marshal(b, m, deterministic) } -func (dst *UnlockTablesResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_UnlockTablesResponse.Merge(dst, src) +func (m *UnlockTablesResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_UnlockTablesResponse.Merge(m, src) } func (m *UnlockTablesResponse) XXX_Size() int { return xxx_messageInfo_UnlockTablesResponse.Size(m) @@ -1583,16 +1633,17 @@ func (m *ExecuteFetchAsDbaRequest) Reset() { *m = ExecuteFetchAsDbaReque func (m *ExecuteFetchAsDbaRequest) String() string { return proto.CompactTextString(m) } func (*ExecuteFetchAsDbaRequest) ProtoMessage() {} func (*ExecuteFetchAsDbaRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_tabletmanagerdata_3063cd7e973e1b02, []int{38} + return fileDescriptor_ff9ac4f89e61ffa4, []int{38} } + func (m *ExecuteFetchAsDbaRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ExecuteFetchAsDbaRequest.Unmarshal(m, b) } func (m *ExecuteFetchAsDbaRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_ExecuteFetchAsDbaRequest.Marshal(b, m, deterministic) } -func (dst *ExecuteFetchAsDbaRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_ExecuteFetchAsDbaRequest.Merge(dst, src) +func (m *ExecuteFetchAsDbaRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_ExecuteFetchAsDbaRequest.Merge(m, src) } func (m *ExecuteFetchAsDbaRequest) XXX_Size() int { return xxx_messageInfo_ExecuteFetchAsDbaRequest.Size(m) @@ -1649,16 +1700,17 @@ func (m *ExecuteFetchAsDbaResponse) Reset() { *m = ExecuteFetchAsDbaResp func (m *ExecuteFetchAsDbaResponse) String() string { return proto.CompactTextString(m) } func (*ExecuteFetchAsDbaResponse) ProtoMessage() {} func (*ExecuteFetchAsDbaResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_tabletmanagerdata_3063cd7e973e1b02, []int{39} + return fileDescriptor_ff9ac4f89e61ffa4, []int{39} } + func (m *ExecuteFetchAsDbaResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ExecuteFetchAsDbaResponse.Unmarshal(m, b) } func (m *ExecuteFetchAsDbaResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_ExecuteFetchAsDbaResponse.Marshal(b, m, deterministic) } -func (dst *ExecuteFetchAsDbaResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_ExecuteFetchAsDbaResponse.Merge(dst, src) +func (m *ExecuteFetchAsDbaResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_ExecuteFetchAsDbaResponse.Merge(m, src) } func (m *ExecuteFetchAsDbaResponse) XXX_Size() int { return xxx_messageInfo_ExecuteFetchAsDbaResponse.Size(m) @@ -1690,16 +1742,17 @@ func (m *ExecuteFetchAsAllPrivsRequest) Reset() { *m = ExecuteFetchAsAll func (m *ExecuteFetchAsAllPrivsRequest) String() string { return proto.CompactTextString(m) } func (*ExecuteFetchAsAllPrivsRequest) ProtoMessage() {} func (*ExecuteFetchAsAllPrivsRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_tabletmanagerdata_3063cd7e973e1b02, []int{40} + return fileDescriptor_ff9ac4f89e61ffa4, []int{40} } + func (m *ExecuteFetchAsAllPrivsRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ExecuteFetchAsAllPrivsRequest.Unmarshal(m, b) } func (m *ExecuteFetchAsAllPrivsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_ExecuteFetchAsAllPrivsRequest.Marshal(b, m, deterministic) } -func (dst *ExecuteFetchAsAllPrivsRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_ExecuteFetchAsAllPrivsRequest.Merge(dst, src) +func (m *ExecuteFetchAsAllPrivsRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_ExecuteFetchAsAllPrivsRequest.Merge(m, src) } func (m *ExecuteFetchAsAllPrivsRequest) XXX_Size() int { return xxx_messageInfo_ExecuteFetchAsAllPrivsRequest.Size(m) @@ -1749,16 +1802,17 @@ func (m *ExecuteFetchAsAllPrivsResponse) Reset() { *m = ExecuteFetchAsAl func (m *ExecuteFetchAsAllPrivsResponse) String() string { return proto.CompactTextString(m) } func (*ExecuteFetchAsAllPrivsResponse) ProtoMessage() {} func (*ExecuteFetchAsAllPrivsResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_tabletmanagerdata_3063cd7e973e1b02, []int{41} + return fileDescriptor_ff9ac4f89e61ffa4, []int{41} } + func (m *ExecuteFetchAsAllPrivsResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ExecuteFetchAsAllPrivsResponse.Unmarshal(m, b) } func (m *ExecuteFetchAsAllPrivsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_ExecuteFetchAsAllPrivsResponse.Marshal(b, m, deterministic) } -func (dst *ExecuteFetchAsAllPrivsResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_ExecuteFetchAsAllPrivsResponse.Merge(dst, src) +func (m *ExecuteFetchAsAllPrivsResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_ExecuteFetchAsAllPrivsResponse.Merge(m, src) } func (m *ExecuteFetchAsAllPrivsResponse) XXX_Size() int { return xxx_messageInfo_ExecuteFetchAsAllPrivsResponse.Size(m) @@ -1788,16 +1842,17 @@ func (m *ExecuteFetchAsAppRequest) Reset() { *m = ExecuteFetchAsAppReque func (m *ExecuteFetchAsAppRequest) String() string { return proto.CompactTextString(m) } func (*ExecuteFetchAsAppRequest) ProtoMessage() {} func (*ExecuteFetchAsAppRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_tabletmanagerdata_3063cd7e973e1b02, []int{42} + return fileDescriptor_ff9ac4f89e61ffa4, []int{42} } + func (m *ExecuteFetchAsAppRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ExecuteFetchAsAppRequest.Unmarshal(m, b) } func (m *ExecuteFetchAsAppRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_ExecuteFetchAsAppRequest.Marshal(b, m, deterministic) } -func (dst *ExecuteFetchAsAppRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_ExecuteFetchAsAppRequest.Merge(dst, src) +func (m *ExecuteFetchAsAppRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_ExecuteFetchAsAppRequest.Merge(m, src) } func (m *ExecuteFetchAsAppRequest) XXX_Size() int { return xxx_messageInfo_ExecuteFetchAsAppRequest.Size(m) @@ -1833,16 +1888,17 @@ func (m *ExecuteFetchAsAppResponse) Reset() { *m = ExecuteFetchAsAppResp func (m *ExecuteFetchAsAppResponse) String() string { return proto.CompactTextString(m) } func (*ExecuteFetchAsAppResponse) ProtoMessage() {} func (*ExecuteFetchAsAppResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_tabletmanagerdata_3063cd7e973e1b02, []int{43} + return fileDescriptor_ff9ac4f89e61ffa4, []int{43} } + func (m *ExecuteFetchAsAppResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ExecuteFetchAsAppResponse.Unmarshal(m, b) } func (m *ExecuteFetchAsAppResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_ExecuteFetchAsAppResponse.Marshal(b, m, deterministic) } -func (dst *ExecuteFetchAsAppResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_ExecuteFetchAsAppResponse.Merge(dst, src) +func (m *ExecuteFetchAsAppResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_ExecuteFetchAsAppResponse.Merge(m, src) } func (m *ExecuteFetchAsAppResponse) XXX_Size() int { return xxx_messageInfo_ExecuteFetchAsAppResponse.Size(m) @@ -1870,16 +1926,17 @@ func (m *SlaveStatusRequest) Reset() { *m = SlaveStatusRequest{} } func (m *SlaveStatusRequest) String() string { return proto.CompactTextString(m) } func (*SlaveStatusRequest) ProtoMessage() {} func (*SlaveStatusRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_tabletmanagerdata_3063cd7e973e1b02, []int{44} + return fileDescriptor_ff9ac4f89e61ffa4, []int{44} } + func (m *SlaveStatusRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_SlaveStatusRequest.Unmarshal(m, b) } func (m *SlaveStatusRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_SlaveStatusRequest.Marshal(b, m, deterministic) } -func (dst *SlaveStatusRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_SlaveStatusRequest.Merge(dst, src) +func (m *SlaveStatusRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_SlaveStatusRequest.Merge(m, src) } func (m *SlaveStatusRequest) XXX_Size() int { return xxx_messageInfo_SlaveStatusRequest.Size(m) @@ -1901,16 +1958,17 @@ func (m *SlaveStatusResponse) Reset() { *m = SlaveStatusResponse{} } func (m *SlaveStatusResponse) String() string { return proto.CompactTextString(m) } func (*SlaveStatusResponse) ProtoMessage() {} func (*SlaveStatusResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_tabletmanagerdata_3063cd7e973e1b02, []int{45} + return fileDescriptor_ff9ac4f89e61ffa4, []int{45} } + func (m *SlaveStatusResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_SlaveStatusResponse.Unmarshal(m, b) } func (m *SlaveStatusResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_SlaveStatusResponse.Marshal(b, m, deterministic) } -func (dst *SlaveStatusResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_SlaveStatusResponse.Merge(dst, src) +func (m *SlaveStatusResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_SlaveStatusResponse.Merge(m, src) } func (m *SlaveStatusResponse) XXX_Size() int { return xxx_messageInfo_SlaveStatusResponse.Size(m) @@ -1938,16 +1996,17 @@ func (m *MasterPositionRequest) Reset() { *m = MasterPositionRequest{} } func (m *MasterPositionRequest) String() string { return proto.CompactTextString(m) } func (*MasterPositionRequest) ProtoMessage() {} func (*MasterPositionRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_tabletmanagerdata_3063cd7e973e1b02, []int{46} + return fileDescriptor_ff9ac4f89e61ffa4, []int{46} } + func (m *MasterPositionRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_MasterPositionRequest.Unmarshal(m, b) } func (m *MasterPositionRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_MasterPositionRequest.Marshal(b, m, deterministic) } -func (dst *MasterPositionRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_MasterPositionRequest.Merge(dst, src) +func (m *MasterPositionRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_MasterPositionRequest.Merge(m, src) } func (m *MasterPositionRequest) XXX_Size() int { return xxx_messageInfo_MasterPositionRequest.Size(m) @@ -1969,16 +2028,17 @@ func (m *MasterPositionResponse) Reset() { *m = MasterPositionResponse{} func (m *MasterPositionResponse) String() string { return proto.CompactTextString(m) } func (*MasterPositionResponse) ProtoMessage() {} func (*MasterPositionResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_tabletmanagerdata_3063cd7e973e1b02, []int{47} + return fileDescriptor_ff9ac4f89e61ffa4, []int{47} } + func (m *MasterPositionResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_MasterPositionResponse.Unmarshal(m, b) } func (m *MasterPositionResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_MasterPositionResponse.Marshal(b, m, deterministic) } -func (dst *MasterPositionResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_MasterPositionResponse.Merge(dst, src) +func (m *MasterPositionResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_MasterPositionResponse.Merge(m, src) } func (m *MasterPositionResponse) XXX_Size() int { return xxx_messageInfo_MasterPositionResponse.Size(m) @@ -1996,6 +2056,76 @@ func (m *MasterPositionResponse) GetPosition() string { return "" } +type WaitForPositionRequest struct { + Position string `protobuf:"bytes,1,opt,name=position,proto3" json:"position,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *WaitForPositionRequest) Reset() { *m = WaitForPositionRequest{} } +func (m *WaitForPositionRequest) String() string { return proto.CompactTextString(m) } +func (*WaitForPositionRequest) ProtoMessage() {} +func (*WaitForPositionRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_ff9ac4f89e61ffa4, []int{48} +} + +func (m *WaitForPositionRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_WaitForPositionRequest.Unmarshal(m, b) +} +func (m *WaitForPositionRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_WaitForPositionRequest.Marshal(b, m, deterministic) +} +func (m *WaitForPositionRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_WaitForPositionRequest.Merge(m, src) +} +func (m *WaitForPositionRequest) XXX_Size() int { + return xxx_messageInfo_WaitForPositionRequest.Size(m) +} +func (m *WaitForPositionRequest) XXX_DiscardUnknown() { + xxx_messageInfo_WaitForPositionRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_WaitForPositionRequest proto.InternalMessageInfo + +func (m *WaitForPositionRequest) GetPosition() string { + if m != nil { + return m.Position + } + return "" +} + +type WaitForPositionResponse struct { + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *WaitForPositionResponse) Reset() { *m = WaitForPositionResponse{} } +func (m *WaitForPositionResponse) String() string { return proto.CompactTextString(m) } +func (*WaitForPositionResponse) ProtoMessage() {} +func (*WaitForPositionResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_ff9ac4f89e61ffa4, []int{49} +} + +func (m *WaitForPositionResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_WaitForPositionResponse.Unmarshal(m, b) +} +func (m *WaitForPositionResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_WaitForPositionResponse.Marshal(b, m, deterministic) +} +func (m *WaitForPositionResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_WaitForPositionResponse.Merge(m, src) +} +func (m *WaitForPositionResponse) XXX_Size() int { + return xxx_messageInfo_WaitForPositionResponse.Size(m) +} +func (m *WaitForPositionResponse) XXX_DiscardUnknown() { + xxx_messageInfo_WaitForPositionResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_WaitForPositionResponse proto.InternalMessageInfo + type StopSlaveRequest struct { XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` @@ -2006,16 +2136,17 @@ func (m *StopSlaveRequest) Reset() { *m = StopSlaveRequest{} } func (m *StopSlaveRequest) String() string { return proto.CompactTextString(m) } func (*StopSlaveRequest) ProtoMessage() {} func (*StopSlaveRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_tabletmanagerdata_3063cd7e973e1b02, []int{48} + return fileDescriptor_ff9ac4f89e61ffa4, []int{50} } + func (m *StopSlaveRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_StopSlaveRequest.Unmarshal(m, b) } func (m *StopSlaveRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_StopSlaveRequest.Marshal(b, m, deterministic) } -func (dst *StopSlaveRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_StopSlaveRequest.Merge(dst, src) +func (m *StopSlaveRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_StopSlaveRequest.Merge(m, src) } func (m *StopSlaveRequest) XXX_Size() int { return xxx_messageInfo_StopSlaveRequest.Size(m) @@ -2036,16 +2167,17 @@ func (m *StopSlaveResponse) Reset() { *m = StopSlaveResponse{} } func (m *StopSlaveResponse) String() string { return proto.CompactTextString(m) } func (*StopSlaveResponse) ProtoMessage() {} func (*StopSlaveResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_tabletmanagerdata_3063cd7e973e1b02, []int{49} + return fileDescriptor_ff9ac4f89e61ffa4, []int{51} } + func (m *StopSlaveResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_StopSlaveResponse.Unmarshal(m, b) } func (m *StopSlaveResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_StopSlaveResponse.Marshal(b, m, deterministic) } -func (dst *StopSlaveResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_StopSlaveResponse.Merge(dst, src) +func (m *StopSlaveResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_StopSlaveResponse.Merge(m, src) } func (m *StopSlaveResponse) XXX_Size() int { return xxx_messageInfo_StopSlaveResponse.Size(m) @@ -2068,16 +2200,17 @@ func (m *StopSlaveMinimumRequest) Reset() { *m = StopSlaveMinimumRequest func (m *StopSlaveMinimumRequest) String() string { return proto.CompactTextString(m) } func (*StopSlaveMinimumRequest) ProtoMessage() {} func (*StopSlaveMinimumRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_tabletmanagerdata_3063cd7e973e1b02, []int{50} + return fileDescriptor_ff9ac4f89e61ffa4, []int{52} } + func (m *StopSlaveMinimumRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_StopSlaveMinimumRequest.Unmarshal(m, b) } func (m *StopSlaveMinimumRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_StopSlaveMinimumRequest.Marshal(b, m, deterministic) } -func (dst *StopSlaveMinimumRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_StopSlaveMinimumRequest.Merge(dst, src) +func (m *StopSlaveMinimumRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_StopSlaveMinimumRequest.Merge(m, src) } func (m *StopSlaveMinimumRequest) XXX_Size() int { return xxx_messageInfo_StopSlaveMinimumRequest.Size(m) @@ -2113,16 +2246,17 @@ func (m *StopSlaveMinimumResponse) Reset() { *m = StopSlaveMinimumRespon func (m *StopSlaveMinimumResponse) String() string { return proto.CompactTextString(m) } func (*StopSlaveMinimumResponse) ProtoMessage() {} func (*StopSlaveMinimumResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_tabletmanagerdata_3063cd7e973e1b02, []int{51} + return fileDescriptor_ff9ac4f89e61ffa4, []int{53} } + func (m *StopSlaveMinimumResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_StopSlaveMinimumResponse.Unmarshal(m, b) } func (m *StopSlaveMinimumResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_StopSlaveMinimumResponse.Marshal(b, m, deterministic) } -func (dst *StopSlaveMinimumResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_StopSlaveMinimumResponse.Merge(dst, src) +func (m *StopSlaveMinimumResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_StopSlaveMinimumResponse.Merge(m, src) } func (m *StopSlaveMinimumResponse) XXX_Size() int { return xxx_messageInfo_StopSlaveMinimumResponse.Size(m) @@ -2150,16 +2284,17 @@ func (m *StartSlaveRequest) Reset() { *m = StartSlaveRequest{} } func (m *StartSlaveRequest) String() string { return proto.CompactTextString(m) } func (*StartSlaveRequest) ProtoMessage() {} func (*StartSlaveRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_tabletmanagerdata_3063cd7e973e1b02, []int{52} + return fileDescriptor_ff9ac4f89e61ffa4, []int{54} } + func (m *StartSlaveRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_StartSlaveRequest.Unmarshal(m, b) } func (m *StartSlaveRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_StartSlaveRequest.Marshal(b, m, deterministic) } -func (dst *StartSlaveRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_StartSlaveRequest.Merge(dst, src) +func (m *StartSlaveRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_StartSlaveRequest.Merge(m, src) } func (m *StartSlaveRequest) XXX_Size() int { return xxx_messageInfo_StartSlaveRequest.Size(m) @@ -2180,16 +2315,17 @@ func (m *StartSlaveResponse) Reset() { *m = StartSlaveResponse{} } func (m *StartSlaveResponse) String() string { return proto.CompactTextString(m) } func (*StartSlaveResponse) ProtoMessage() {} func (*StartSlaveResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_tabletmanagerdata_3063cd7e973e1b02, []int{53} + return fileDescriptor_ff9ac4f89e61ffa4, []int{55} } + func (m *StartSlaveResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_StartSlaveResponse.Unmarshal(m, b) } func (m *StartSlaveResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_StartSlaveResponse.Marshal(b, m, deterministic) } -func (dst *StartSlaveResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_StartSlaveResponse.Merge(dst, src) +func (m *StartSlaveResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_StartSlaveResponse.Merge(m, src) } func (m *StartSlaveResponse) XXX_Size() int { return xxx_messageInfo_StartSlaveResponse.Size(m) @@ -2212,16 +2348,17 @@ func (m *StartSlaveUntilAfterRequest) Reset() { *m = StartSlaveUntilAfte func (m *StartSlaveUntilAfterRequest) String() string { return proto.CompactTextString(m) } func (*StartSlaveUntilAfterRequest) ProtoMessage() {} func (*StartSlaveUntilAfterRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_tabletmanagerdata_3063cd7e973e1b02, []int{54} + return fileDescriptor_ff9ac4f89e61ffa4, []int{56} } + func (m *StartSlaveUntilAfterRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_StartSlaveUntilAfterRequest.Unmarshal(m, b) } func (m *StartSlaveUntilAfterRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_StartSlaveUntilAfterRequest.Marshal(b, m, deterministic) } -func (dst *StartSlaveUntilAfterRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_StartSlaveUntilAfterRequest.Merge(dst, src) +func (m *StartSlaveUntilAfterRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_StartSlaveUntilAfterRequest.Merge(m, src) } func (m *StartSlaveUntilAfterRequest) XXX_Size() int { return xxx_messageInfo_StartSlaveUntilAfterRequest.Size(m) @@ -2256,16 +2393,17 @@ func (m *StartSlaveUntilAfterResponse) Reset() { *m = StartSlaveUntilAft func (m *StartSlaveUntilAfterResponse) String() string { return proto.CompactTextString(m) } func (*StartSlaveUntilAfterResponse) ProtoMessage() {} func (*StartSlaveUntilAfterResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_tabletmanagerdata_3063cd7e973e1b02, []int{55} + return fileDescriptor_ff9ac4f89e61ffa4, []int{57} } + func (m *StartSlaveUntilAfterResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_StartSlaveUntilAfterResponse.Unmarshal(m, b) } func (m *StartSlaveUntilAfterResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_StartSlaveUntilAfterResponse.Marshal(b, m, deterministic) } -func (dst *StartSlaveUntilAfterResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_StartSlaveUntilAfterResponse.Merge(dst, src) +func (m *StartSlaveUntilAfterResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_StartSlaveUntilAfterResponse.Merge(m, src) } func (m *StartSlaveUntilAfterResponse) XXX_Size() int { return xxx_messageInfo_StartSlaveUntilAfterResponse.Size(m) @@ -2290,16 +2428,17 @@ func (m *TabletExternallyReparentedRequest) Reset() { *m = TabletExterna func (m *TabletExternallyReparentedRequest) String() string { return proto.CompactTextString(m) } func (*TabletExternallyReparentedRequest) ProtoMessage() {} func (*TabletExternallyReparentedRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_tabletmanagerdata_3063cd7e973e1b02, []int{56} + return fileDescriptor_ff9ac4f89e61ffa4, []int{58} } + func (m *TabletExternallyReparentedRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_TabletExternallyReparentedRequest.Unmarshal(m, b) } func (m *TabletExternallyReparentedRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_TabletExternallyReparentedRequest.Marshal(b, m, deterministic) } -func (dst *TabletExternallyReparentedRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_TabletExternallyReparentedRequest.Merge(dst, src) +func (m *TabletExternallyReparentedRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_TabletExternallyReparentedRequest.Merge(m, src) } func (m *TabletExternallyReparentedRequest) XXX_Size() int { return xxx_messageInfo_TabletExternallyReparentedRequest.Size(m) @@ -2327,16 +2466,17 @@ func (m *TabletExternallyReparentedResponse) Reset() { *m = TabletExtern func (m *TabletExternallyReparentedResponse) String() string { return proto.CompactTextString(m) } func (*TabletExternallyReparentedResponse) ProtoMessage() {} func (*TabletExternallyReparentedResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_tabletmanagerdata_3063cd7e973e1b02, []int{57} + return fileDescriptor_ff9ac4f89e61ffa4, []int{59} } + func (m *TabletExternallyReparentedResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_TabletExternallyReparentedResponse.Unmarshal(m, b) } func (m *TabletExternallyReparentedResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_TabletExternallyReparentedResponse.Marshal(b, m, deterministic) } -func (dst *TabletExternallyReparentedResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_TabletExternallyReparentedResponse.Merge(dst, src) +func (m *TabletExternallyReparentedResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_TabletExternallyReparentedResponse.Merge(m, src) } func (m *TabletExternallyReparentedResponse) XXX_Size() int { return xxx_messageInfo_TabletExternallyReparentedResponse.Size(m) @@ -2357,16 +2497,17 @@ func (m *TabletExternallyElectedRequest) Reset() { *m = TabletExternally func (m *TabletExternallyElectedRequest) String() string { return proto.CompactTextString(m) } func (*TabletExternallyElectedRequest) ProtoMessage() {} func (*TabletExternallyElectedRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_tabletmanagerdata_3063cd7e973e1b02, []int{58} + return fileDescriptor_ff9ac4f89e61ffa4, []int{60} } + func (m *TabletExternallyElectedRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_TabletExternallyElectedRequest.Unmarshal(m, b) } func (m *TabletExternallyElectedRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_TabletExternallyElectedRequest.Marshal(b, m, deterministic) } -func (dst *TabletExternallyElectedRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_TabletExternallyElectedRequest.Merge(dst, src) +func (m *TabletExternallyElectedRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_TabletExternallyElectedRequest.Merge(m, src) } func (m *TabletExternallyElectedRequest) XXX_Size() int { return xxx_messageInfo_TabletExternallyElectedRequest.Size(m) @@ -2387,16 +2528,17 @@ func (m *TabletExternallyElectedResponse) Reset() { *m = TabletExternall func (m *TabletExternallyElectedResponse) String() string { return proto.CompactTextString(m) } func (*TabletExternallyElectedResponse) ProtoMessage() {} func (*TabletExternallyElectedResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_tabletmanagerdata_3063cd7e973e1b02, []int{59} + return fileDescriptor_ff9ac4f89e61ffa4, []int{61} } + func (m *TabletExternallyElectedResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_TabletExternallyElectedResponse.Unmarshal(m, b) } func (m *TabletExternallyElectedResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_TabletExternallyElectedResponse.Marshal(b, m, deterministic) } -func (dst *TabletExternallyElectedResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_TabletExternallyElectedResponse.Merge(dst, src) +func (m *TabletExternallyElectedResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_TabletExternallyElectedResponse.Merge(m, src) } func (m *TabletExternallyElectedResponse) XXX_Size() int { return xxx_messageInfo_TabletExternallyElectedResponse.Size(m) @@ -2417,16 +2559,17 @@ func (m *GetSlavesRequest) Reset() { *m = GetSlavesRequest{} } func (m *GetSlavesRequest) String() string { return proto.CompactTextString(m) } func (*GetSlavesRequest) ProtoMessage() {} func (*GetSlavesRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_tabletmanagerdata_3063cd7e973e1b02, []int{60} + return fileDescriptor_ff9ac4f89e61ffa4, []int{62} } + func (m *GetSlavesRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_GetSlavesRequest.Unmarshal(m, b) } func (m *GetSlavesRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_GetSlavesRequest.Marshal(b, m, deterministic) } -func (dst *GetSlavesRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_GetSlavesRequest.Merge(dst, src) +func (m *GetSlavesRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_GetSlavesRequest.Merge(m, src) } func (m *GetSlavesRequest) XXX_Size() int { return xxx_messageInfo_GetSlavesRequest.Size(m) @@ -2448,16 +2591,17 @@ func (m *GetSlavesResponse) Reset() { *m = GetSlavesResponse{} } func (m *GetSlavesResponse) String() string { return proto.CompactTextString(m) } func (*GetSlavesResponse) ProtoMessage() {} func (*GetSlavesResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_tabletmanagerdata_3063cd7e973e1b02, []int{61} + return fileDescriptor_ff9ac4f89e61ffa4, []int{63} } + func (m *GetSlavesResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_GetSlavesResponse.Unmarshal(m, b) } func (m *GetSlavesResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_GetSlavesResponse.Marshal(b, m, deterministic) } -func (dst *GetSlavesResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_GetSlavesResponse.Merge(dst, src) +func (m *GetSlavesResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_GetSlavesResponse.Merge(m, src) } func (m *GetSlavesResponse) XXX_Size() int { return xxx_messageInfo_GetSlavesResponse.Size(m) @@ -2485,16 +2629,17 @@ func (m *ResetReplicationRequest) Reset() { *m = ResetReplicationRequest func (m *ResetReplicationRequest) String() string { return proto.CompactTextString(m) } func (*ResetReplicationRequest) ProtoMessage() {} func (*ResetReplicationRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_tabletmanagerdata_3063cd7e973e1b02, []int{62} + return fileDescriptor_ff9ac4f89e61ffa4, []int{64} } + func (m *ResetReplicationRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ResetReplicationRequest.Unmarshal(m, b) } func (m *ResetReplicationRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_ResetReplicationRequest.Marshal(b, m, deterministic) } -func (dst *ResetReplicationRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_ResetReplicationRequest.Merge(dst, src) +func (m *ResetReplicationRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_ResetReplicationRequest.Merge(m, src) } func (m *ResetReplicationRequest) XXX_Size() int { return xxx_messageInfo_ResetReplicationRequest.Size(m) @@ -2515,16 +2660,17 @@ func (m *ResetReplicationResponse) Reset() { *m = ResetReplicationRespon func (m *ResetReplicationResponse) String() string { return proto.CompactTextString(m) } func (*ResetReplicationResponse) ProtoMessage() {} func (*ResetReplicationResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_tabletmanagerdata_3063cd7e973e1b02, []int{63} + return fileDescriptor_ff9ac4f89e61ffa4, []int{65} } + func (m *ResetReplicationResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ResetReplicationResponse.Unmarshal(m, b) } func (m *ResetReplicationResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_ResetReplicationResponse.Marshal(b, m, deterministic) } -func (dst *ResetReplicationResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_ResetReplicationResponse.Merge(dst, src) +func (m *ResetReplicationResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_ResetReplicationResponse.Merge(m, src) } func (m *ResetReplicationResponse) XXX_Size() int { return xxx_messageInfo_ResetReplicationResponse.Size(m) @@ -2546,16 +2692,17 @@ func (m *VReplicationExecRequest) Reset() { *m = VReplicationExecRequest func (m *VReplicationExecRequest) String() string { return proto.CompactTextString(m) } func (*VReplicationExecRequest) ProtoMessage() {} func (*VReplicationExecRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_tabletmanagerdata_3063cd7e973e1b02, []int{64} + return fileDescriptor_ff9ac4f89e61ffa4, []int{66} } + func (m *VReplicationExecRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_VReplicationExecRequest.Unmarshal(m, b) } func (m *VReplicationExecRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_VReplicationExecRequest.Marshal(b, m, deterministic) } -func (dst *VReplicationExecRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_VReplicationExecRequest.Merge(dst, src) +func (m *VReplicationExecRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_VReplicationExecRequest.Merge(m, src) } func (m *VReplicationExecRequest) XXX_Size() int { return xxx_messageInfo_VReplicationExecRequest.Size(m) @@ -2584,16 +2731,17 @@ func (m *VReplicationExecResponse) Reset() { *m = VReplicationExecRespon func (m *VReplicationExecResponse) String() string { return proto.CompactTextString(m) } func (*VReplicationExecResponse) ProtoMessage() {} func (*VReplicationExecResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_tabletmanagerdata_3063cd7e973e1b02, []int{65} + return fileDescriptor_ff9ac4f89e61ffa4, []int{67} } + func (m *VReplicationExecResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_VReplicationExecResponse.Unmarshal(m, b) } func (m *VReplicationExecResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_VReplicationExecResponse.Marshal(b, m, deterministic) } -func (dst *VReplicationExecResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_VReplicationExecResponse.Merge(dst, src) +func (m *VReplicationExecResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_VReplicationExecResponse.Merge(m, src) } func (m *VReplicationExecResponse) XXX_Size() int { return xxx_messageInfo_VReplicationExecResponse.Size(m) @@ -2623,16 +2771,17 @@ func (m *VReplicationWaitForPosRequest) Reset() { *m = VReplicationWaitF func (m *VReplicationWaitForPosRequest) String() string { return proto.CompactTextString(m) } func (*VReplicationWaitForPosRequest) ProtoMessage() {} func (*VReplicationWaitForPosRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_tabletmanagerdata_3063cd7e973e1b02, []int{66} + return fileDescriptor_ff9ac4f89e61ffa4, []int{68} } + func (m *VReplicationWaitForPosRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_VReplicationWaitForPosRequest.Unmarshal(m, b) } func (m *VReplicationWaitForPosRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_VReplicationWaitForPosRequest.Marshal(b, m, deterministic) } -func (dst *VReplicationWaitForPosRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_VReplicationWaitForPosRequest.Merge(dst, src) +func (m *VReplicationWaitForPosRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_VReplicationWaitForPosRequest.Merge(m, src) } func (m *VReplicationWaitForPosRequest) XXX_Size() int { return xxx_messageInfo_VReplicationWaitForPosRequest.Size(m) @@ -2667,16 +2816,17 @@ func (m *VReplicationWaitForPosResponse) Reset() { *m = VReplicationWait func (m *VReplicationWaitForPosResponse) String() string { return proto.CompactTextString(m) } func (*VReplicationWaitForPosResponse) ProtoMessage() {} func (*VReplicationWaitForPosResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_tabletmanagerdata_3063cd7e973e1b02, []int{67} + return fileDescriptor_ff9ac4f89e61ffa4, []int{69} } + func (m *VReplicationWaitForPosResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_VReplicationWaitForPosResponse.Unmarshal(m, b) } func (m *VReplicationWaitForPosResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_VReplicationWaitForPosResponse.Marshal(b, m, deterministic) } -func (dst *VReplicationWaitForPosResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_VReplicationWaitForPosResponse.Merge(dst, src) +func (m *VReplicationWaitForPosResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_VReplicationWaitForPosResponse.Merge(m, src) } func (m *VReplicationWaitForPosResponse) XXX_Size() int { return xxx_messageInfo_VReplicationWaitForPosResponse.Size(m) @@ -2697,16 +2847,17 @@ func (m *InitMasterRequest) Reset() { *m = InitMasterRequest{} } func (m *InitMasterRequest) String() string { return proto.CompactTextString(m) } func (*InitMasterRequest) ProtoMessage() {} func (*InitMasterRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_tabletmanagerdata_3063cd7e973e1b02, []int{68} + return fileDescriptor_ff9ac4f89e61ffa4, []int{70} } + func (m *InitMasterRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_InitMasterRequest.Unmarshal(m, b) } func (m *InitMasterRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_InitMasterRequest.Marshal(b, m, deterministic) } -func (dst *InitMasterRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_InitMasterRequest.Merge(dst, src) +func (m *InitMasterRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_InitMasterRequest.Merge(m, src) } func (m *InitMasterRequest) XXX_Size() int { return xxx_messageInfo_InitMasterRequest.Size(m) @@ -2728,16 +2879,17 @@ func (m *InitMasterResponse) Reset() { *m = InitMasterResponse{} } func (m *InitMasterResponse) String() string { return proto.CompactTextString(m) } func (*InitMasterResponse) ProtoMessage() {} func (*InitMasterResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_tabletmanagerdata_3063cd7e973e1b02, []int{69} + return fileDescriptor_ff9ac4f89e61ffa4, []int{71} } + func (m *InitMasterResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_InitMasterResponse.Unmarshal(m, b) } func (m *InitMasterResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_InitMasterResponse.Marshal(b, m, deterministic) } -func (dst *InitMasterResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_InitMasterResponse.Merge(dst, src) +func (m *InitMasterResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_InitMasterResponse.Merge(m, src) } func (m *InitMasterResponse) XXX_Size() int { return xxx_messageInfo_InitMasterResponse.Size(m) @@ -2769,16 +2921,17 @@ func (m *PopulateReparentJournalRequest) Reset() { *m = PopulateReparent func (m *PopulateReparentJournalRequest) String() string { return proto.CompactTextString(m) } func (*PopulateReparentJournalRequest) ProtoMessage() {} func (*PopulateReparentJournalRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_tabletmanagerdata_3063cd7e973e1b02, []int{70} + return fileDescriptor_ff9ac4f89e61ffa4, []int{72} } + func (m *PopulateReparentJournalRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_PopulateReparentJournalRequest.Unmarshal(m, b) } func (m *PopulateReparentJournalRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_PopulateReparentJournalRequest.Marshal(b, m, deterministic) } -func (dst *PopulateReparentJournalRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_PopulateReparentJournalRequest.Merge(dst, src) +func (m *PopulateReparentJournalRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_PopulateReparentJournalRequest.Merge(m, src) } func (m *PopulateReparentJournalRequest) XXX_Size() int { return xxx_messageInfo_PopulateReparentJournalRequest.Size(m) @@ -2827,16 +2980,17 @@ func (m *PopulateReparentJournalResponse) Reset() { *m = PopulateReparen func (m *PopulateReparentJournalResponse) String() string { return proto.CompactTextString(m) } func (*PopulateReparentJournalResponse) ProtoMessage() {} func (*PopulateReparentJournalResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_tabletmanagerdata_3063cd7e973e1b02, []int{71} + return fileDescriptor_ff9ac4f89e61ffa4, []int{73} } + func (m *PopulateReparentJournalResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_PopulateReparentJournalResponse.Unmarshal(m, b) } func (m *PopulateReparentJournalResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_PopulateReparentJournalResponse.Marshal(b, m, deterministic) } -func (dst *PopulateReparentJournalResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_PopulateReparentJournalResponse.Merge(dst, src) +func (m *PopulateReparentJournalResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_PopulateReparentJournalResponse.Merge(m, src) } func (m *PopulateReparentJournalResponse) XXX_Size() int { return xxx_messageInfo_PopulateReparentJournalResponse.Size(m) @@ -2860,16 +3014,17 @@ func (m *InitSlaveRequest) Reset() { *m = InitSlaveRequest{} } func (m *InitSlaveRequest) String() string { return proto.CompactTextString(m) } func (*InitSlaveRequest) ProtoMessage() {} func (*InitSlaveRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_tabletmanagerdata_3063cd7e973e1b02, []int{72} + return fileDescriptor_ff9ac4f89e61ffa4, []int{74} } + func (m *InitSlaveRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_InitSlaveRequest.Unmarshal(m, b) } func (m *InitSlaveRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_InitSlaveRequest.Marshal(b, m, deterministic) } -func (dst *InitSlaveRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_InitSlaveRequest.Merge(dst, src) +func (m *InitSlaveRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_InitSlaveRequest.Merge(m, src) } func (m *InitSlaveRequest) XXX_Size() int { return xxx_messageInfo_InitSlaveRequest.Size(m) @@ -2911,16 +3066,17 @@ func (m *InitSlaveResponse) Reset() { *m = InitSlaveResponse{} } func (m *InitSlaveResponse) String() string { return proto.CompactTextString(m) } func (*InitSlaveResponse) ProtoMessage() {} func (*InitSlaveResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_tabletmanagerdata_3063cd7e973e1b02, []int{73} + return fileDescriptor_ff9ac4f89e61ffa4, []int{75} } + func (m *InitSlaveResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_InitSlaveResponse.Unmarshal(m, b) } func (m *InitSlaveResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_InitSlaveResponse.Marshal(b, m, deterministic) } -func (dst *InitSlaveResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_InitSlaveResponse.Merge(dst, src) +func (m *InitSlaveResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_InitSlaveResponse.Merge(m, src) } func (m *InitSlaveResponse) XXX_Size() int { return xxx_messageInfo_InitSlaveResponse.Size(m) @@ -2941,16 +3097,17 @@ func (m *DemoteMasterRequest) Reset() { *m = DemoteMasterRequest{} } func (m *DemoteMasterRequest) String() string { return proto.CompactTextString(m) } func (*DemoteMasterRequest) ProtoMessage() {} func (*DemoteMasterRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_tabletmanagerdata_3063cd7e973e1b02, []int{74} + return fileDescriptor_ff9ac4f89e61ffa4, []int{76} } + func (m *DemoteMasterRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_DemoteMasterRequest.Unmarshal(m, b) } func (m *DemoteMasterRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_DemoteMasterRequest.Marshal(b, m, deterministic) } -func (dst *DemoteMasterRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_DemoteMasterRequest.Merge(dst, src) +func (m *DemoteMasterRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_DemoteMasterRequest.Merge(m, src) } func (m *DemoteMasterRequest) XXX_Size() int { return xxx_messageInfo_DemoteMasterRequest.Size(m) @@ -2972,16 +3129,17 @@ func (m *DemoteMasterResponse) Reset() { *m = DemoteMasterResponse{} } func (m *DemoteMasterResponse) String() string { return proto.CompactTextString(m) } func (*DemoteMasterResponse) ProtoMessage() {} func (*DemoteMasterResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_tabletmanagerdata_3063cd7e973e1b02, []int{75} + return fileDescriptor_ff9ac4f89e61ffa4, []int{77} } + func (m *DemoteMasterResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_DemoteMasterResponse.Unmarshal(m, b) } func (m *DemoteMasterResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_DemoteMasterResponse.Marshal(b, m, deterministic) } -func (dst *DemoteMasterResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_DemoteMasterResponse.Merge(dst, src) +func (m *DemoteMasterResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_DemoteMasterResponse.Merge(m, src) } func (m *DemoteMasterResponse) XXX_Size() int { return xxx_messageInfo_DemoteMasterResponse.Size(m) @@ -3009,16 +3167,17 @@ func (m *UndoDemoteMasterRequest) Reset() { *m = UndoDemoteMasterRequest func (m *UndoDemoteMasterRequest) String() string { return proto.CompactTextString(m) } func (*UndoDemoteMasterRequest) ProtoMessage() {} func (*UndoDemoteMasterRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_tabletmanagerdata_3063cd7e973e1b02, []int{76} + return fileDescriptor_ff9ac4f89e61ffa4, []int{78} } + func (m *UndoDemoteMasterRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_UndoDemoteMasterRequest.Unmarshal(m, b) } func (m *UndoDemoteMasterRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_UndoDemoteMasterRequest.Marshal(b, m, deterministic) } -func (dst *UndoDemoteMasterRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_UndoDemoteMasterRequest.Merge(dst, src) +func (m *UndoDemoteMasterRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_UndoDemoteMasterRequest.Merge(m, src) } func (m *UndoDemoteMasterRequest) XXX_Size() int { return xxx_messageInfo_UndoDemoteMasterRequest.Size(m) @@ -3039,16 +3198,17 @@ func (m *UndoDemoteMasterResponse) Reset() { *m = UndoDemoteMasterRespon func (m *UndoDemoteMasterResponse) String() string { return proto.CompactTextString(m) } func (*UndoDemoteMasterResponse) ProtoMessage() {} func (*UndoDemoteMasterResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_tabletmanagerdata_3063cd7e973e1b02, []int{77} + return fileDescriptor_ff9ac4f89e61ffa4, []int{79} } + func (m *UndoDemoteMasterResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_UndoDemoteMasterResponse.Unmarshal(m, b) } func (m *UndoDemoteMasterResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_UndoDemoteMasterResponse.Marshal(b, m, deterministic) } -func (dst *UndoDemoteMasterResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_UndoDemoteMasterResponse.Merge(dst, src) +func (m *UndoDemoteMasterResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_UndoDemoteMasterResponse.Merge(m, src) } func (m *UndoDemoteMasterResponse) XXX_Size() int { return xxx_messageInfo_UndoDemoteMasterResponse.Size(m) @@ -3070,16 +3230,17 @@ func (m *PromoteSlaveWhenCaughtUpRequest) Reset() { *m = PromoteSlaveWhe func (m *PromoteSlaveWhenCaughtUpRequest) String() string { return proto.CompactTextString(m) } func (*PromoteSlaveWhenCaughtUpRequest) ProtoMessage() {} func (*PromoteSlaveWhenCaughtUpRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_tabletmanagerdata_3063cd7e973e1b02, []int{78} + return fileDescriptor_ff9ac4f89e61ffa4, []int{80} } + func (m *PromoteSlaveWhenCaughtUpRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_PromoteSlaveWhenCaughtUpRequest.Unmarshal(m, b) } func (m *PromoteSlaveWhenCaughtUpRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_PromoteSlaveWhenCaughtUpRequest.Marshal(b, m, deterministic) } -func (dst *PromoteSlaveWhenCaughtUpRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_PromoteSlaveWhenCaughtUpRequest.Merge(dst, src) +func (m *PromoteSlaveWhenCaughtUpRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_PromoteSlaveWhenCaughtUpRequest.Merge(m, src) } func (m *PromoteSlaveWhenCaughtUpRequest) XXX_Size() int { return xxx_messageInfo_PromoteSlaveWhenCaughtUpRequest.Size(m) @@ -3108,16 +3269,17 @@ func (m *PromoteSlaveWhenCaughtUpResponse) Reset() { *m = PromoteSlaveWh func (m *PromoteSlaveWhenCaughtUpResponse) String() string { return proto.CompactTextString(m) } func (*PromoteSlaveWhenCaughtUpResponse) ProtoMessage() {} func (*PromoteSlaveWhenCaughtUpResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_tabletmanagerdata_3063cd7e973e1b02, []int{79} + return fileDescriptor_ff9ac4f89e61ffa4, []int{81} } + func (m *PromoteSlaveWhenCaughtUpResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_PromoteSlaveWhenCaughtUpResponse.Unmarshal(m, b) } func (m *PromoteSlaveWhenCaughtUpResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_PromoteSlaveWhenCaughtUpResponse.Marshal(b, m, deterministic) } -func (dst *PromoteSlaveWhenCaughtUpResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_PromoteSlaveWhenCaughtUpResponse.Merge(dst, src) +func (m *PromoteSlaveWhenCaughtUpResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_PromoteSlaveWhenCaughtUpResponse.Merge(m, src) } func (m *PromoteSlaveWhenCaughtUpResponse) XXX_Size() int { return xxx_messageInfo_PromoteSlaveWhenCaughtUpResponse.Size(m) @@ -3145,16 +3307,17 @@ func (m *SlaveWasPromotedRequest) Reset() { *m = SlaveWasPromotedRequest func (m *SlaveWasPromotedRequest) String() string { return proto.CompactTextString(m) } func (*SlaveWasPromotedRequest) ProtoMessage() {} func (*SlaveWasPromotedRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_tabletmanagerdata_3063cd7e973e1b02, []int{80} + return fileDescriptor_ff9ac4f89e61ffa4, []int{82} } + func (m *SlaveWasPromotedRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_SlaveWasPromotedRequest.Unmarshal(m, b) } func (m *SlaveWasPromotedRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_SlaveWasPromotedRequest.Marshal(b, m, deterministic) } -func (dst *SlaveWasPromotedRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_SlaveWasPromotedRequest.Merge(dst, src) +func (m *SlaveWasPromotedRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_SlaveWasPromotedRequest.Merge(m, src) } func (m *SlaveWasPromotedRequest) XXX_Size() int { return xxx_messageInfo_SlaveWasPromotedRequest.Size(m) @@ -3175,16 +3338,17 @@ func (m *SlaveWasPromotedResponse) Reset() { *m = SlaveWasPromotedRespon func (m *SlaveWasPromotedResponse) String() string { return proto.CompactTextString(m) } func (*SlaveWasPromotedResponse) ProtoMessage() {} func (*SlaveWasPromotedResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_tabletmanagerdata_3063cd7e973e1b02, []int{81} + return fileDescriptor_ff9ac4f89e61ffa4, []int{83} } + func (m *SlaveWasPromotedResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_SlaveWasPromotedResponse.Unmarshal(m, b) } func (m *SlaveWasPromotedResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_SlaveWasPromotedResponse.Marshal(b, m, deterministic) } -func (dst *SlaveWasPromotedResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_SlaveWasPromotedResponse.Merge(dst, src) +func (m *SlaveWasPromotedResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_SlaveWasPromotedResponse.Merge(m, src) } func (m *SlaveWasPromotedResponse) XXX_Size() int { return xxx_messageInfo_SlaveWasPromotedResponse.Size(m) @@ -3198,6 +3362,7 @@ var xxx_messageInfo_SlaveWasPromotedResponse proto.InternalMessageInfo type SetMasterRequest struct { Parent *topodata.TabletAlias `protobuf:"bytes,1,opt,name=parent,proto3" json:"parent,omitempty"` TimeCreatedNs int64 `protobuf:"varint,2,opt,name=time_created_ns,json=timeCreatedNs,proto3" json:"time_created_ns,omitempty"` + WaitPosition string `protobuf:"bytes,4,opt,name=wait_position,json=waitPosition,proto3" json:"wait_position,omitempty"` ForceStartSlave bool `protobuf:"varint,3,opt,name=force_start_slave,json=forceStartSlave,proto3" json:"force_start_slave,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` @@ -3208,16 +3373,17 @@ func (m *SetMasterRequest) Reset() { *m = SetMasterRequest{} } func (m *SetMasterRequest) String() string { return proto.CompactTextString(m) } func (*SetMasterRequest) ProtoMessage() {} func (*SetMasterRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_tabletmanagerdata_3063cd7e973e1b02, []int{82} + return fileDescriptor_ff9ac4f89e61ffa4, []int{84} } + func (m *SetMasterRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_SetMasterRequest.Unmarshal(m, b) } func (m *SetMasterRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_SetMasterRequest.Marshal(b, m, deterministic) } -func (dst *SetMasterRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_SetMasterRequest.Merge(dst, src) +func (m *SetMasterRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_SetMasterRequest.Merge(m, src) } func (m *SetMasterRequest) XXX_Size() int { return xxx_messageInfo_SetMasterRequest.Size(m) @@ -3242,6 +3408,13 @@ func (m *SetMasterRequest) GetTimeCreatedNs() int64 { return 0 } +func (m *SetMasterRequest) GetWaitPosition() string { + if m != nil { + return m.WaitPosition + } + return "" +} + func (m *SetMasterRequest) GetForceStartSlave() bool { if m != nil { return m.ForceStartSlave @@ -3259,16 +3432,17 @@ func (m *SetMasterResponse) Reset() { *m = SetMasterResponse{} } func (m *SetMasterResponse) String() string { return proto.CompactTextString(m) } func (*SetMasterResponse) ProtoMessage() {} func (*SetMasterResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_tabletmanagerdata_3063cd7e973e1b02, []int{83} + return fileDescriptor_ff9ac4f89e61ffa4, []int{85} } + func (m *SetMasterResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_SetMasterResponse.Unmarshal(m, b) } func (m *SetMasterResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_SetMasterResponse.Marshal(b, m, deterministic) } -func (dst *SetMasterResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_SetMasterResponse.Merge(dst, src) +func (m *SetMasterResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_SetMasterResponse.Merge(m, src) } func (m *SetMasterResponse) XXX_Size() int { return xxx_messageInfo_SetMasterResponse.Size(m) @@ -3291,16 +3465,17 @@ func (m *SlaveWasRestartedRequest) Reset() { *m = SlaveWasRestartedReque func (m *SlaveWasRestartedRequest) String() string { return proto.CompactTextString(m) } func (*SlaveWasRestartedRequest) ProtoMessage() {} func (*SlaveWasRestartedRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_tabletmanagerdata_3063cd7e973e1b02, []int{84} + return fileDescriptor_ff9ac4f89e61ffa4, []int{86} } + func (m *SlaveWasRestartedRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_SlaveWasRestartedRequest.Unmarshal(m, b) } func (m *SlaveWasRestartedRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_SlaveWasRestartedRequest.Marshal(b, m, deterministic) } -func (dst *SlaveWasRestartedRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_SlaveWasRestartedRequest.Merge(dst, src) +func (m *SlaveWasRestartedRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_SlaveWasRestartedRequest.Merge(m, src) } func (m *SlaveWasRestartedRequest) XXX_Size() int { return xxx_messageInfo_SlaveWasRestartedRequest.Size(m) @@ -3328,16 +3503,17 @@ func (m *SlaveWasRestartedResponse) Reset() { *m = SlaveWasRestartedResp func (m *SlaveWasRestartedResponse) String() string { return proto.CompactTextString(m) } func (*SlaveWasRestartedResponse) ProtoMessage() {} func (*SlaveWasRestartedResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_tabletmanagerdata_3063cd7e973e1b02, []int{85} + return fileDescriptor_ff9ac4f89e61ffa4, []int{87} } + func (m *SlaveWasRestartedResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_SlaveWasRestartedResponse.Unmarshal(m, b) } func (m *SlaveWasRestartedResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_SlaveWasRestartedResponse.Marshal(b, m, deterministic) } -func (dst *SlaveWasRestartedResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_SlaveWasRestartedResponse.Merge(dst, src) +func (m *SlaveWasRestartedResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_SlaveWasRestartedResponse.Merge(m, src) } func (m *SlaveWasRestartedResponse) XXX_Size() int { return xxx_messageInfo_SlaveWasRestartedResponse.Size(m) @@ -3358,16 +3534,17 @@ func (m *StopReplicationAndGetStatusRequest) Reset() { *m = StopReplicat func (m *StopReplicationAndGetStatusRequest) String() string { return proto.CompactTextString(m) } func (*StopReplicationAndGetStatusRequest) ProtoMessage() {} func (*StopReplicationAndGetStatusRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_tabletmanagerdata_3063cd7e973e1b02, []int{86} + return fileDescriptor_ff9ac4f89e61ffa4, []int{88} } + func (m *StopReplicationAndGetStatusRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_StopReplicationAndGetStatusRequest.Unmarshal(m, b) } func (m *StopReplicationAndGetStatusRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_StopReplicationAndGetStatusRequest.Marshal(b, m, deterministic) } -func (dst *StopReplicationAndGetStatusRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_StopReplicationAndGetStatusRequest.Merge(dst, src) +func (m *StopReplicationAndGetStatusRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_StopReplicationAndGetStatusRequest.Merge(m, src) } func (m *StopReplicationAndGetStatusRequest) XXX_Size() int { return xxx_messageInfo_StopReplicationAndGetStatusRequest.Size(m) @@ -3389,16 +3566,17 @@ func (m *StopReplicationAndGetStatusResponse) Reset() { *m = StopReplica func (m *StopReplicationAndGetStatusResponse) String() string { return proto.CompactTextString(m) } func (*StopReplicationAndGetStatusResponse) ProtoMessage() {} func (*StopReplicationAndGetStatusResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_tabletmanagerdata_3063cd7e973e1b02, []int{87} + return fileDescriptor_ff9ac4f89e61ffa4, []int{89} } + func (m *StopReplicationAndGetStatusResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_StopReplicationAndGetStatusResponse.Unmarshal(m, b) } func (m *StopReplicationAndGetStatusResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_StopReplicationAndGetStatusResponse.Marshal(b, m, deterministic) } -func (dst *StopReplicationAndGetStatusResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_StopReplicationAndGetStatusResponse.Merge(dst, src) +func (m *StopReplicationAndGetStatusResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_StopReplicationAndGetStatusResponse.Merge(m, src) } func (m *StopReplicationAndGetStatusResponse) XXX_Size() int { return xxx_messageInfo_StopReplicationAndGetStatusResponse.Size(m) @@ -3426,16 +3604,17 @@ func (m *PromoteSlaveRequest) Reset() { *m = PromoteSlaveRequest{} } func (m *PromoteSlaveRequest) String() string { return proto.CompactTextString(m) } func (*PromoteSlaveRequest) ProtoMessage() {} func (*PromoteSlaveRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_tabletmanagerdata_3063cd7e973e1b02, []int{88} + return fileDescriptor_ff9ac4f89e61ffa4, []int{90} } + func (m *PromoteSlaveRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_PromoteSlaveRequest.Unmarshal(m, b) } func (m *PromoteSlaveRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_PromoteSlaveRequest.Marshal(b, m, deterministic) } -func (dst *PromoteSlaveRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_PromoteSlaveRequest.Merge(dst, src) +func (m *PromoteSlaveRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_PromoteSlaveRequest.Merge(m, src) } func (m *PromoteSlaveRequest) XXX_Size() int { return xxx_messageInfo_PromoteSlaveRequest.Size(m) @@ -3457,16 +3636,17 @@ func (m *PromoteSlaveResponse) Reset() { *m = PromoteSlaveResponse{} } func (m *PromoteSlaveResponse) String() string { return proto.CompactTextString(m) } func (*PromoteSlaveResponse) ProtoMessage() {} func (*PromoteSlaveResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_tabletmanagerdata_3063cd7e973e1b02, []int{89} + return fileDescriptor_ff9ac4f89e61ffa4, []int{91} } + func (m *PromoteSlaveResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_PromoteSlaveResponse.Unmarshal(m, b) } func (m *PromoteSlaveResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_PromoteSlaveResponse.Marshal(b, m, deterministic) } -func (dst *PromoteSlaveResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_PromoteSlaveResponse.Merge(dst, src) +func (m *PromoteSlaveResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_PromoteSlaveResponse.Merge(m, src) } func (m *PromoteSlaveResponse) XXX_Size() int { return xxx_messageInfo_PromoteSlaveResponse.Size(m) @@ -3496,16 +3676,17 @@ func (m *BackupRequest) Reset() { *m = BackupRequest{} } func (m *BackupRequest) String() string { return proto.CompactTextString(m) } func (*BackupRequest) ProtoMessage() {} func (*BackupRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_tabletmanagerdata_3063cd7e973e1b02, []int{90} + return fileDescriptor_ff9ac4f89e61ffa4, []int{92} } + func (m *BackupRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_BackupRequest.Unmarshal(m, b) } func (m *BackupRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_BackupRequest.Marshal(b, m, deterministic) } -func (dst *BackupRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_BackupRequest.Merge(dst, src) +func (m *BackupRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_BackupRequest.Merge(m, src) } func (m *BackupRequest) XXX_Size() int { return xxx_messageInfo_BackupRequest.Size(m) @@ -3541,16 +3722,17 @@ func (m *BackupResponse) Reset() { *m = BackupResponse{} } func (m *BackupResponse) String() string { return proto.CompactTextString(m) } func (*BackupResponse) ProtoMessage() {} func (*BackupResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_tabletmanagerdata_3063cd7e973e1b02, []int{91} + return fileDescriptor_ff9ac4f89e61ffa4, []int{93} } + func (m *BackupResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_BackupResponse.Unmarshal(m, b) } func (m *BackupResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_BackupResponse.Marshal(b, m, deterministic) } -func (dst *BackupResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_BackupResponse.Merge(dst, src) +func (m *BackupResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_BackupResponse.Merge(m, src) } func (m *BackupResponse) XXX_Size() int { return xxx_messageInfo_BackupResponse.Size(m) @@ -3578,16 +3760,17 @@ func (m *RestoreFromBackupRequest) Reset() { *m = RestoreFromBackupReque func (m *RestoreFromBackupRequest) String() string { return proto.CompactTextString(m) } func (*RestoreFromBackupRequest) ProtoMessage() {} func (*RestoreFromBackupRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_tabletmanagerdata_3063cd7e973e1b02, []int{92} + return fileDescriptor_ff9ac4f89e61ffa4, []int{94} } + func (m *RestoreFromBackupRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_RestoreFromBackupRequest.Unmarshal(m, b) } func (m *RestoreFromBackupRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_RestoreFromBackupRequest.Marshal(b, m, deterministic) } -func (dst *RestoreFromBackupRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_RestoreFromBackupRequest.Merge(dst, src) +func (m *RestoreFromBackupRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_RestoreFromBackupRequest.Merge(m, src) } func (m *RestoreFromBackupRequest) XXX_Size() int { return xxx_messageInfo_RestoreFromBackupRequest.Size(m) @@ -3609,16 +3792,17 @@ func (m *RestoreFromBackupResponse) Reset() { *m = RestoreFromBackupResp func (m *RestoreFromBackupResponse) String() string { return proto.CompactTextString(m) } func (*RestoreFromBackupResponse) ProtoMessage() {} func (*RestoreFromBackupResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_tabletmanagerdata_3063cd7e973e1b02, []int{93} + return fileDescriptor_ff9ac4f89e61ffa4, []int{95} } + func (m *RestoreFromBackupResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_RestoreFromBackupResponse.Unmarshal(m, b) } func (m *RestoreFromBackupResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_RestoreFromBackupResponse.Marshal(b, m, deterministic) } -func (dst *RestoreFromBackupResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_RestoreFromBackupResponse.Merge(dst, src) +func (m *RestoreFromBackupResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_RestoreFromBackupResponse.Merge(m, src) } func (m *RestoreFromBackupResponse) XXX_Size() int { return xxx_messageInfo_RestoreFromBackupResponse.Size(m) @@ -3688,6 +3872,8 @@ func init() { proto.RegisterType((*SlaveStatusResponse)(nil), "tabletmanagerdata.SlaveStatusResponse") proto.RegisterType((*MasterPositionRequest)(nil), "tabletmanagerdata.MasterPositionRequest") proto.RegisterType((*MasterPositionResponse)(nil), "tabletmanagerdata.MasterPositionResponse") + proto.RegisterType((*WaitForPositionRequest)(nil), "tabletmanagerdata.WaitForPositionRequest") + proto.RegisterType((*WaitForPositionResponse)(nil), "tabletmanagerdata.WaitForPositionResponse") proto.RegisterType((*StopSlaveRequest)(nil), "tabletmanagerdata.StopSlaveRequest") proto.RegisterType((*StopSlaveResponse)(nil), "tabletmanagerdata.StopSlaveResponse") proto.RegisterType((*StopSlaveMinimumRequest)(nil), "tabletmanagerdata.StopSlaveMinimumRequest") @@ -3736,140 +3922,140 @@ func init() { proto.RegisterType((*RestoreFromBackupResponse)(nil), "tabletmanagerdata.RestoreFromBackupResponse") } -func init() { - proto.RegisterFile("tabletmanagerdata.proto", fileDescriptor_tabletmanagerdata_3063cd7e973e1b02) -} +func init() { proto.RegisterFile("tabletmanagerdata.proto", fileDescriptor_ff9ac4f89e61ffa4) } -var fileDescriptor_tabletmanagerdata_3063cd7e973e1b02 = []byte{ - // 2074 bytes of a gzipped FileDescriptorProto +var fileDescriptor_ff9ac4f89e61ffa4 = []byte{ + // 2108 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x59, 0x5b, 0x6f, 0x1b, 0xc7, - 0xf5, 0x07, 0x49, 0x49, 0x96, 0x0e, 0x2f, 0x22, 0x97, 0x94, 0x48, 0xc9, 0xff, 0x48, 0xf2, 0xda, - 0xf9, 0xc7, 0x75, 0x51, 0x2a, 0x51, 0xd2, 0x20, 0x48, 0x91, 0xa2, 0xb2, 0x2e, 0xb6, 0x13, 0x25, - 0x56, 0x56, 0x96, 0x5d, 0x04, 0x05, 0x16, 0x43, 0xee, 0x88, 0x5c, 0x68, 0xb9, 0xb3, 0x9e, 0x99, - 0xa5, 0xc4, 0x2f, 0xd1, 0xb7, 0xbe, 0xf5, 0xad, 0x40, 0xfb, 0xde, 0x0f, 0x93, 0xa2, 0x9f, 0xa4, - 0x0f, 0x7d, 0x29, 0xe6, 0xb2, 0xe4, 0x2c, 0xb9, 0xb4, 0x25, 0xc1, 0x05, 0xfa, 0x22, 0xf0, 0xfc, - 0xce, 0x99, 0x73, 0x9b, 0x73, 0xce, 0x9c, 0x85, 0xa0, 0xc9, 0x51, 0x27, 0xc0, 0x7c, 0x80, 0x42, - 0xd4, 0xc3, 0xd4, 0x43, 0x1c, 0xb5, 0x23, 0x4a, 0x38, 0xb1, 0x6a, 0x33, 0x8c, 0xcd, 0xe2, 0xdb, - 0x18, 0xd3, 0x91, 0xe2, 0x6f, 0x56, 0x38, 0x89, 0xc8, 0x44, 0x7e, 0x73, 0x8d, 0xe2, 0x28, 0xf0, - 0xbb, 0x88, 0xfb, 0x24, 0x34, 0xe0, 0x72, 0x40, 0x7a, 0x31, 0xf7, 0x03, 0x45, 0xda, 0xff, 0xcc, - 0xc1, 0xea, 0x2b, 0xa1, 0xf8, 0x10, 0x5f, 0xf8, 0xa1, 0x2f, 0x84, 0x2d, 0x0b, 0x16, 0x42, 0x34, - 0xc0, 0xad, 0xdc, 0x4e, 0xee, 0xf1, 0x8a, 0x23, 0x7f, 0x5b, 0xeb, 0xb0, 0xc4, 0xba, 0x7d, 0x3c, - 0x40, 0xad, 0xbc, 0x44, 0x35, 0x65, 0xb5, 0xe0, 0x5e, 0x97, 0x04, 0xf1, 0x20, 0x64, 0xad, 0xc2, - 0x4e, 0xe1, 0xf1, 0x8a, 0x93, 0x90, 0x56, 0x1b, 0xea, 0x11, 0xf5, 0x07, 0x88, 0x8e, 0xdc, 0x4b, - 0x3c, 0x72, 0x13, 0xa9, 0x05, 0x29, 0x55, 0xd3, 0xac, 0xef, 0xf0, 0xe8, 0x40, 0xcb, 0x5b, 0xb0, - 0xc0, 0x47, 0x11, 0x6e, 0x2d, 0x2a, 0xab, 0xe2, 0xb7, 0xb5, 0x0d, 0x45, 0xe1, 0xba, 0x1b, 0xe0, - 0xb0, 0xc7, 0xfb, 0xad, 0xa5, 0x9d, 0xdc, 0xe3, 0x05, 0x07, 0x04, 0x74, 0x22, 0x11, 0xeb, 0x3e, - 0xac, 0x50, 0x72, 0xe5, 0x76, 0x49, 0x1c, 0xf2, 0xd6, 0x3d, 0xc9, 0x5e, 0xa6, 0xe4, 0xea, 0x40, - 0xd0, 0xf6, 0x5f, 0x73, 0x50, 0x3d, 0x93, 0x6e, 0x1a, 0xc1, 0x7d, 0x02, 0xab, 0xe2, 0x7c, 0x07, - 0x31, 0xec, 0xea, 0x88, 0x54, 0x9c, 0x95, 0x04, 0x56, 0x47, 0xac, 0x97, 0xa0, 0x32, 0xee, 0x7a, - 0xe3, 0xc3, 0xac, 0x95, 0xdf, 0x29, 0x3c, 0x2e, 0xee, 0xd9, 0xed, 0xd9, 0x4b, 0x9a, 0x4a, 0xa2, - 0x53, 0xe5, 0x69, 0x80, 0x89, 0x54, 0x0d, 0x31, 0x65, 0x3e, 0x09, 0x5b, 0x05, 0x69, 0x31, 0x21, - 0x85, 0xa3, 0x96, 0xb2, 0x7a, 0xd0, 0x47, 0x61, 0x0f, 0x3b, 0x98, 0xc5, 0x01, 0xb7, 0x9e, 0x43, - 0xb9, 0x83, 0x2f, 0x08, 0x4d, 0x39, 0x5a, 0xdc, 0x7b, 0x98, 0x61, 0x7d, 0x3a, 0x4c, 0xa7, 0xa4, - 0x4e, 0xea, 0x58, 0x8e, 0xa1, 0x84, 0x2e, 0x38, 0xa6, 0xae, 0x71, 0x87, 0x37, 0x54, 0x54, 0x94, - 0x07, 0x15, 0x6c, 0xff, 0x2b, 0x07, 0x95, 0x73, 0x86, 0xe9, 0x29, 0xa6, 0x03, 0x9f, 0x31, 0x5d, - 0x2c, 0x7d, 0xc2, 0x78, 0x52, 0x2c, 0xe2, 0xb7, 0xc0, 0x62, 0x86, 0xa9, 0x2e, 0x15, 0xf9, 0xdb, - 0xfa, 0x25, 0xd4, 0x22, 0xc4, 0xd8, 0x15, 0xa1, 0x9e, 0xdb, 0xed, 0xe3, 0xee, 0x25, 0x8b, 0x07, - 0x32, 0x0f, 0x0b, 0x4e, 0x35, 0x61, 0x1c, 0x68, 0xdc, 0xfa, 0x11, 0x20, 0xa2, 0xfe, 0xd0, 0x0f, - 0x70, 0x0f, 0xab, 0x92, 0x29, 0xee, 0x7d, 0x96, 0xe1, 0x6d, 0xda, 0x97, 0xf6, 0xe9, 0xf8, 0xcc, - 0x51, 0xc8, 0xe9, 0xc8, 0x31, 0x94, 0x6c, 0x7e, 0x03, 0xab, 0x53, 0x6c, 0xab, 0x0a, 0x85, 0x4b, - 0x3c, 0xd2, 0x9e, 0x8b, 0x9f, 0x56, 0x03, 0x16, 0x87, 0x28, 0x88, 0xb1, 0xf6, 0x5c, 0x11, 0x5f, - 0xe7, 0xbf, 0xca, 0xd9, 0x3f, 0xe7, 0xa0, 0x74, 0xd8, 0x79, 0x4f, 0xdc, 0x15, 0xc8, 0x7b, 0x1d, - 0x7d, 0x36, 0xef, 0x75, 0xc6, 0x79, 0x28, 0x18, 0x79, 0x78, 0x99, 0x11, 0xda, 0x6e, 0x46, 0x68, - 0xa6, 0xb1, 0xff, 0x66, 0x60, 0x7f, 0xc9, 0x41, 0x71, 0x62, 0x89, 0x59, 0x27, 0x50, 0x15, 0x7e, - 0xba, 0xd1, 0x04, 0x6b, 0xe5, 0xa4, 0x97, 0x0f, 0xde, 0x7b, 0x01, 0xce, 0x6a, 0x9c, 0xa2, 0x99, - 0x75, 0x0c, 0x15, 0xaf, 0x93, 0xd2, 0xa5, 0x3a, 0x68, 0xfb, 0x3d, 0x11, 0x3b, 0x65, 0xcf, 0xa0, - 0x98, 0xfd, 0x09, 0x14, 0x4f, 0xfd, 0xb0, 0xe7, 0xe0, 0xb7, 0x31, 0x66, 0x5c, 0xb4, 0x52, 0x84, - 0x46, 0x01, 0x41, 0x9e, 0x0e, 0x32, 0x21, 0xed, 0xc7, 0x50, 0x52, 0x82, 0x2c, 0x22, 0x21, 0xc3, - 0xef, 0x90, 0x7c, 0x02, 0xa5, 0xb3, 0x00, 0xe3, 0x28, 0xd1, 0xb9, 0x09, 0xcb, 0x5e, 0x4c, 0xe5, - 0xb8, 0x94, 0xa2, 0x05, 0x67, 0x4c, 0xdb, 0xab, 0x50, 0xd6, 0xb2, 0x4a, 0xad, 0xfd, 0x8f, 0x1c, - 0x58, 0x47, 0xd7, 0xb8, 0x1b, 0x73, 0xfc, 0x9c, 0x90, 0xcb, 0x44, 0x47, 0xd6, 0xe4, 0xdc, 0x02, - 0x88, 0x10, 0x45, 0x03, 0xcc, 0x31, 0x55, 0xe1, 0xaf, 0x38, 0x06, 0x62, 0x9d, 0xc2, 0x0a, 0xbe, - 0xe6, 0x14, 0xb9, 0x38, 0x1c, 0xca, 0x19, 0x5a, 0xdc, 0xfb, 0x3c, 0x23, 0x3b, 0xb3, 0xd6, 0xda, - 0x47, 0xe2, 0xd8, 0x51, 0x38, 0x54, 0x35, 0xb1, 0x8c, 0x35, 0xb9, 0xf9, 0x1b, 0x28, 0xa7, 0x58, - 0xb7, 0xaa, 0x87, 0x0b, 0xa8, 0xa7, 0x4c, 0xe9, 0x3c, 0x6e, 0x43, 0x11, 0x5f, 0xfb, 0xdc, 0x65, - 0x1c, 0xf1, 0x98, 0xe9, 0x04, 0x81, 0x80, 0xce, 0x24, 0x22, 0x1f, 0x08, 0xee, 0x91, 0x98, 0x8f, - 0x1f, 0x08, 0x49, 0x69, 0x1c, 0xd3, 0xa4, 0x0b, 0x34, 0x65, 0x0f, 0xa1, 0xfa, 0x0c, 0x73, 0x35, - 0x57, 0x92, 0xf4, 0xad, 0xc3, 0x92, 0x0c, 0x5c, 0x55, 0xdc, 0x8a, 0xa3, 0x29, 0xeb, 0x21, 0x94, - 0xfd, 0xb0, 0x1b, 0xc4, 0x1e, 0x76, 0x87, 0x3e, 0xbe, 0x62, 0xd2, 0xc4, 0xb2, 0x53, 0xd2, 0xe0, - 0x6b, 0x81, 0x59, 0x1f, 0x43, 0x05, 0x5f, 0x2b, 0x21, 0xad, 0x44, 0x3d, 0x48, 0x65, 0x8d, 0xca, - 0x01, 0xcd, 0x6c, 0x0c, 0x35, 0xc3, 0xae, 0x8e, 0xee, 0x14, 0x6a, 0x6a, 0x32, 0x1a, 0xc3, 0xfe, - 0x36, 0xd3, 0xb6, 0xca, 0xa6, 0x10, 0xbb, 0x09, 0x6b, 0xcf, 0x30, 0x37, 0x4a, 0x58, 0xc7, 0x68, - 0xff, 0x04, 0xeb, 0xd3, 0x0c, 0xed, 0xc4, 0xef, 0xa0, 0x98, 0x6e, 0x3a, 0x61, 0x7e, 0x2b, 0xc3, - 0xbc, 0x79, 0xd8, 0x3c, 0x62, 0x37, 0xc0, 0x3a, 0xc3, 0xdc, 0xc1, 0xc8, 0x7b, 0x19, 0x06, 0xa3, - 0xc4, 0xe2, 0x1a, 0xd4, 0x53, 0xa8, 0x2e, 0xe1, 0x09, 0xfc, 0x86, 0xfa, 0x1c, 0x27, 0xd2, 0xeb, - 0xd0, 0x48, 0xc3, 0x5a, 0xfc, 0x5b, 0xa8, 0xa9, 0xc7, 0xe9, 0xd5, 0x28, 0x4a, 0x84, 0xad, 0x5f, - 0x43, 0x51, 0xb9, 0xe7, 0xca, 0xa7, 0x5b, 0xb8, 0x5c, 0xd9, 0x6b, 0xb4, 0xc7, 0x9b, 0x88, 0xcc, - 0x39, 0x97, 0x27, 0x80, 0x8f, 0x7f, 0x0b, 0x3f, 0x4d, 0x5d, 0x13, 0x87, 0x1c, 0x7c, 0x41, 0x31, - 0xeb, 0x8b, 0x92, 0x32, 0x1d, 0x4a, 0xc3, 0x5a, 0xbc, 0x09, 0x6b, 0x4e, 0x1c, 0x3e, 0xc7, 0x28, - 0xe0, 0x7d, 0xf9, 0x70, 0x24, 0x07, 0x5a, 0xb0, 0x3e, 0xcd, 0xd0, 0x47, 0xbe, 0x80, 0xd6, 0x8b, - 0x5e, 0x48, 0x28, 0x56, 0xcc, 0x23, 0x4a, 0x09, 0x4d, 0x8d, 0x14, 0xce, 0x31, 0x0d, 0x27, 0x83, - 0x42, 0x92, 0xf6, 0x7d, 0xd8, 0xc8, 0x38, 0xa5, 0x55, 0x7e, 0x2d, 0x9c, 0x16, 0xf3, 0x24, 0x5d, - 0xc9, 0x0f, 0xa1, 0x7c, 0x85, 0x7c, 0xee, 0x46, 0x84, 0x4d, 0x8a, 0x69, 0xc5, 0x29, 0x09, 0xf0, - 0x54, 0x63, 0x2a, 0x32, 0xf3, 0xac, 0xd6, 0xb9, 0x07, 0xeb, 0xa7, 0x14, 0x5f, 0x04, 0x7e, 0xaf, - 0x3f, 0xd5, 0x20, 0x62, 0xdb, 0x92, 0x89, 0x4b, 0x3a, 0x24, 0x21, 0xed, 0x1e, 0x34, 0x67, 0xce, - 0xe8, 0xba, 0x3a, 0x81, 0x8a, 0x92, 0x72, 0xa9, 0xdc, 0x2b, 0x92, 0x79, 0xfe, 0xf1, 0xdc, 0xca, - 0x36, 0xb7, 0x10, 0xa7, 0xdc, 0x35, 0x28, 0x66, 0xff, 0x3b, 0x07, 0xd6, 0x7e, 0x14, 0x05, 0xa3, - 0xb4, 0x67, 0x55, 0x28, 0xb0, 0xb7, 0x41, 0x32, 0x62, 0xd8, 0xdb, 0x40, 0x8c, 0x98, 0x0b, 0x42, - 0xbb, 0x58, 0x37, 0xab, 0x22, 0xc4, 0x1a, 0x80, 0x82, 0x80, 0x5c, 0xb9, 0xc6, 0x76, 0x2a, 0x27, - 0xc3, 0xb2, 0x53, 0x95, 0x0c, 0x67, 0x82, 0xcf, 0x2e, 0x40, 0x0b, 0x1f, 0x6a, 0x01, 0x5a, 0xbc, - 0xe3, 0x02, 0xf4, 0xb7, 0x1c, 0xd4, 0x53, 0xd1, 0xeb, 0x1c, 0xff, 0xef, 0xad, 0x6a, 0x75, 0xa8, - 0x9d, 0x90, 0xee, 0xa5, 0x9a, 0x7a, 0x49, 0x6b, 0x34, 0xc0, 0x32, 0xc1, 0x49, 0xe3, 0x9d, 0x87, - 0xc1, 0x8c, 0xf0, 0x3a, 0x34, 0xd2, 0xb0, 0x16, 0xff, 0x7b, 0x0e, 0x5a, 0xfa, 0x89, 0x38, 0xc6, - 0xbc, 0xdb, 0xdf, 0x67, 0x87, 0x9d, 0x71, 0x1d, 0x34, 0x60, 0x51, 0x7e, 0x94, 0xc8, 0x04, 0x94, - 0x1c, 0x45, 0x58, 0x4d, 0xb8, 0xe7, 0x75, 0x5c, 0xf9, 0x34, 0xea, 0xd7, 0xc1, 0xeb, 0xfc, 0x20, - 0x1e, 0xc7, 0x0d, 0x58, 0x1e, 0xa0, 0x6b, 0x97, 0x92, 0x2b, 0xa6, 0x97, 0xc1, 0x7b, 0x03, 0x74, - 0xed, 0x90, 0x2b, 0x26, 0x17, 0x75, 0x9f, 0xc9, 0x0d, 0xbc, 0xe3, 0x87, 0x01, 0xe9, 0x31, 0x79, - 0xfd, 0xcb, 0x4e, 0x45, 0xc3, 0x4f, 0x15, 0x2a, 0x7a, 0x8d, 0xca, 0x36, 0x32, 0x2f, 0x77, 0xd9, - 0x29, 0x51, 0xa3, 0xb7, 0xec, 0x67, 0xb0, 0x91, 0xe1, 0xb3, 0xbe, 0xbd, 0x27, 0xb0, 0xa4, 0x5a, - 0x43, 0x5f, 0x9b, 0xd5, 0x56, 0x1f, 0x56, 0x3f, 0x8a, 0xbf, 0xba, 0x0d, 0xb4, 0x84, 0xfd, 0xc7, - 0x1c, 0x7c, 0x94, 0xd6, 0xb4, 0x1f, 0x04, 0x62, 0x01, 0x63, 0x1f, 0x3e, 0x05, 0x33, 0x91, 0x2d, - 0x64, 0x44, 0x76, 0x02, 0x5b, 0xf3, 0xfc, 0xb9, 0x43, 0x78, 0xdf, 0x4d, 0xdf, 0xed, 0x7e, 0x14, - 0xbd, 0x3b, 0x30, 0xd3, 0xff, 0x7c, 0xca, 0xff, 0xd9, 0xa4, 0x4b, 0x65, 0x77, 0xf0, 0x4a, 0x3c, - 0x6c, 0x01, 0x1a, 0x62, 0xb5, 0x6b, 0x24, 0x05, 0x7a, 0x0c, 0xf5, 0x14, 0xaa, 0x15, 0xef, 0x8a, - 0x8d, 0x63, 0xbc, 0xa5, 0x14, 0xf7, 0x9a, 0xed, 0xe9, 0x2f, 0x61, 0x7d, 0x40, 0x8b, 0x89, 0x97, - 0xe4, 0x7b, 0xc4, 0x38, 0xa6, 0xc9, 0x64, 0x4e, 0x0c, 0x7c, 0x01, 0xeb, 0xd3, 0x0c, 0x6d, 0x63, - 0x13, 0x96, 0xa7, 0x46, 0xfb, 0x98, 0xb6, 0x2d, 0xa8, 0x9e, 0x71, 0x12, 0x49, 0xd7, 0x12, 0x4d, - 0x75, 0xa8, 0x19, 0x98, 0x6e, 0xa4, 0xdf, 0x43, 0x73, 0x0c, 0x7e, 0xef, 0x87, 0xfe, 0x20, 0x1e, - 0x18, 0xcb, 0xe8, 0x3c, 0xfd, 0xd6, 0x03, 0x90, 0xcf, 0x88, 0xcb, 0xfd, 0x01, 0x4e, 0xf6, 0xad, - 0x82, 0x53, 0x14, 0xd8, 0x2b, 0x05, 0xd9, 0x5f, 0x42, 0x6b, 0x56, 0xf3, 0x0d, 0x5c, 0x97, 0x6e, - 0x22, 0xca, 0x53, 0xbe, 0x8b, 0xe4, 0x1b, 0xa0, 0x76, 0xfe, 0x0f, 0x70, 0x7f, 0x82, 0x9e, 0x87, - 0xdc, 0x0f, 0xf6, 0xc5, 0xf4, 0xf9, 0x40, 0x01, 0x6c, 0xc1, 0xff, 0x65, 0x6b, 0xd7, 0xd6, 0x0f, - 0xe1, 0x81, 0xda, 0x2d, 0x8e, 0xae, 0xc5, 0x1b, 0x8d, 0x02, 0xb1, 0xd8, 0x44, 0x88, 0xe2, 0x90, - 0x63, 0x2f, 0xf1, 0x41, 0xee, 0xac, 0x8a, 0xed, 0xfa, 0xc9, 0xfe, 0x0f, 0x09, 0xf4, 0xc2, 0xb3, - 0x1f, 0x81, 0xfd, 0x2e, 0x2d, 0xda, 0xd6, 0x0e, 0x6c, 0x4d, 0x4b, 0x1d, 0x05, 0xb8, 0x3b, 0x31, - 0x64, 0x3f, 0x80, 0xed, 0xb9, 0x12, 0x5a, 0x89, 0xa5, 0xd6, 0x5d, 0x11, 0xce, 0xb8, 0x7e, 0x7f, - 0xa1, 0x56, 0x51, 0x8d, 0xe9, 0xeb, 0x69, 0xc0, 0x22, 0xf2, 0x3c, 0x9a, 0x3c, 0xf0, 0x8a, 0xb0, - 0x37, 0xa0, 0xe9, 0x60, 0x26, 0xf6, 0xb2, 0x71, 0x25, 0x27, 0x5a, 0x36, 0xa1, 0x35, 0xcb, 0xd2, - 0x56, 0x77, 0xa1, 0xf9, 0xda, 0xc0, 0x45, 0x33, 0x66, 0x36, 0xf3, 0x8a, 0x6e, 0x66, 0xfb, 0x18, - 0x5a, 0xb3, 0x07, 0xee, 0x34, 0x46, 0x3e, 0x32, 0xf5, 0xbc, 0x41, 0x3e, 0x3f, 0x26, 0xa2, 0x8d, - 0x12, 0xf3, 0x15, 0xc8, 0xeb, 0x2b, 0x29, 0x38, 0x79, 0xdf, 0x4b, 0xd5, 0x4b, 0x7e, 0xaa, 0x2a, - 0x77, 0x60, 0x6b, 0x9e, 0x32, 0x1d, 0x67, 0x1d, 0x6a, 0x2f, 0x42, 0x9f, 0xab, 0x66, 0x4d, 0x12, - 0xf3, 0x29, 0x58, 0x26, 0x78, 0x83, 0xf2, 0xff, 0x39, 0x07, 0x5b, 0xa7, 0x24, 0x8a, 0x03, 0xb9, - 0x67, 0xaa, 0x42, 0xf8, 0x96, 0xc4, 0xe2, 0x46, 0x13, 0xbf, 0xff, 0x1f, 0x56, 0x45, 0xd9, 0xba, - 0x5d, 0x8a, 0x11, 0xc7, 0x9e, 0x1b, 0x26, 0xdf, 0x42, 0x65, 0x01, 0x1f, 0x28, 0xf4, 0x07, 0x26, - 0x6a, 0x0f, 0x75, 0x85, 0x52, 0x73, 0xe4, 0x83, 0x82, 0xe4, 0xd8, 0xff, 0x0a, 0x4a, 0x03, 0xe9, - 0x99, 0x8b, 0x02, 0x1f, 0xa9, 0xd1, 0x5f, 0xdc, 0x5b, 0x9b, 0xde, 0x9d, 0xf7, 0x05, 0xd3, 0x29, - 0x2a, 0x51, 0x49, 0x58, 0x9f, 0x41, 0xc3, 0x18, 0x68, 0x93, 0x15, 0x73, 0x41, 0xda, 0xa8, 0x1b, - 0xbc, 0xf1, 0xa6, 0xf9, 0x00, 0xb6, 0xe7, 0xc6, 0xa5, 0x53, 0xf8, 0xe7, 0x1c, 0x54, 0x45, 0xba, - 0xcc, 0xd6, 0xb7, 0x7e, 0x05, 0x4b, 0x4a, 0x5a, 0x5f, 0xf9, 0x1c, 0xf7, 0xb4, 0xd0, 0x5c, 0xcf, - 0xf2, 0x73, 0x3d, 0xcb, 0xca, 0x67, 0x21, 0x23, 0x9f, 0xc9, 0x0d, 0xa7, 0x67, 0xd0, 0x1a, 0xd4, - 0x0f, 0xf1, 0x80, 0x70, 0x9c, 0xbe, 0xf8, 0x3d, 0x68, 0xa4, 0xe1, 0x1b, 0x5c, 0xfd, 0x06, 0x34, - 0xcf, 0x43, 0x8f, 0x64, 0xa9, 0xdb, 0x84, 0xd6, 0x2c, 0x4b, 0x7b, 0xf0, 0x0d, 0x6c, 0x9f, 0x52, - 0x22, 0x18, 0xd2, 0xb3, 0x37, 0x7d, 0x1c, 0x1e, 0xa0, 0xb8, 0xd7, 0xe7, 0xe7, 0xd1, 0x0d, 0x26, - 0xa1, 0xfd, 0x5b, 0xd8, 0x99, 0x7f, 0xfc, 0x66, 0x5e, 0xab, 0x83, 0x88, 0x69, 0x3d, 0x9e, 0xe1, - 0xf5, 0x2c, 0x4b, 0x7b, 0xfd, 0xa7, 0x1c, 0x54, 0xcf, 0x70, 0xba, 0x5d, 0x6e, 0x7b, 0xd7, 0x19, - 0x17, 0x97, 0xcf, 0x6a, 0x84, 0x27, 0x50, 0x93, 0x9b, 0xbf, 0xcb, 0xc4, 0x3c, 0x77, 0x99, 0xf0, - 0x49, 0x2f, 0xfc, 0xab, 0x92, 0x31, 0x99, 0xf3, 0xf2, 0xf9, 0xc1, 0x53, 0x0d, 0x6b, 0xbf, 0x98, - 0x04, 0xe2, 0x60, 0xa9, 0x64, 0x32, 0xe1, 0x6f, 0xe7, 0xb3, 0xf8, 0x92, 0xcb, 0x50, 0xa5, 0xed, - 0x3c, 0x02, 0x5b, 0xbc, 0x99, 0xc6, 0xa0, 0xd9, 0x0f, 0x3d, 0x31, 0x9f, 0x53, 0x3b, 0xc7, 0x6b, - 0x78, 0xf8, 0x4e, 0xa9, 0xbb, 0xee, 0x20, 0x6b, 0x50, 0x37, 0x2b, 0xc1, 0x28, 0xe5, 0x34, 0x7c, - 0x83, 0xa2, 0x38, 0x83, 0xf2, 0x53, 0xd4, 0xbd, 0x8c, 0xc7, 0x15, 0xb8, 0x03, 0xc5, 0x2e, 0x09, - 0xbb, 0x31, 0xa5, 0x38, 0xec, 0x8e, 0xf4, 0xbc, 0x32, 0x21, 0x21, 0x21, 0x3f, 0xbe, 0x54, 0xea, - 0xf5, 0x17, 0x9b, 0x09, 0xd9, 0x5f, 0x42, 0x25, 0x51, 0xaa, 0x5d, 0x78, 0x04, 0x8b, 0x78, 0x38, - 0x49, 0x7d, 0xa5, 0x9d, 0xfc, 0x63, 0xe1, 0x48, 0xa0, 0x8e, 0x62, 0xea, 0xd7, 0x89, 0x13, 0x8a, - 0x8f, 0x29, 0x19, 0xa4, 0xfc, 0xb2, 0xf7, 0x61, 0x23, 0x83, 0x77, 0x1b, 0xf5, 0x4f, 0x3f, 0xfd, - 0xa9, 0x3d, 0xf4, 0x39, 0x66, 0xac, 0xed, 0x93, 0x5d, 0xf5, 0x6b, 0xb7, 0x47, 0x76, 0x87, 0x7c, - 0x57, 0xfe, 0x7b, 0x63, 0x77, 0xe6, 0xab, 0xa9, 0xb3, 0x24, 0x19, 0x9f, 0xff, 0x27, 0x00, 0x00, - 0xff, 0xff, 0x62, 0x6b, 0xcc, 0xed, 0x68, 0x19, 0x00, 0x00, + 0x15, 0x06, 0x49, 0x49, 0xa6, 0x0e, 0x2f, 0x22, 0x97, 0x94, 0x48, 0xc9, 0x8d, 0x2e, 0x6b, 0xa7, + 0x51, 0x5d, 0x94, 0x4a, 0x94, 0x34, 0x08, 0x52, 0xa4, 0xa8, 0xac, 0x8b, 0xed, 0x44, 0x89, 0x95, + 0x95, 0x65, 0x17, 0x41, 0x81, 0xc5, 0x90, 0x3b, 0x22, 0x17, 0x5a, 0xee, 0xac, 0x67, 0x66, 0x29, + 0xf1, 0x4f, 0xf4, 0x17, 0xf4, 0xad, 0x40, 0xfb, 0xde, 0xc7, 0xfe, 0x10, 0xf7, 0xa7, 0xf4, 0xa1, + 0x0f, 0x2d, 0xe6, 0xb2, 0xe4, 0x2c, 0x49, 0xc9, 0x92, 0xe0, 0x02, 0x79, 0x11, 0x38, 0xdf, 0x39, + 0x73, 0x6e, 0x73, 0x6e, 0x0b, 0x41, 0x83, 0xa3, 0x76, 0x80, 0x79, 0x1f, 0x85, 0xa8, 0x8b, 0xa9, + 0x87, 0x38, 0x6a, 0x45, 0x94, 0x70, 0x62, 0x55, 0xa7, 0x08, 0x6b, 0x85, 0xb7, 0x31, 0xa6, 0x43, + 0x45, 0x5f, 0x2b, 0x73, 0x12, 0x91, 0x31, 0xff, 0xda, 0x32, 0xc5, 0x51, 0xe0, 0x77, 0x10, 0xf7, + 0x49, 0x68, 0xc0, 0xa5, 0x80, 0x74, 0x63, 0xee, 0x07, 0xea, 0x68, 0xff, 0x37, 0x03, 0x4b, 0xaf, + 0x84, 0xe0, 0x03, 0x7c, 0xee, 0x87, 0xbe, 0x60, 0xb6, 0x2c, 0x98, 0x0b, 0x51, 0x1f, 0x37, 0x33, + 0x9b, 0x99, 0xed, 0x45, 0x47, 0xfe, 0xb6, 0x56, 0x60, 0x81, 0x75, 0x7a, 0xb8, 0x8f, 0x9a, 0x59, + 0x89, 0xea, 0x93, 0xd5, 0x84, 0x07, 0x1d, 0x12, 0xc4, 0xfd, 0x90, 0x35, 0x73, 0x9b, 0xb9, 0xed, + 0x45, 0x27, 0x39, 0x5a, 0x2d, 0xa8, 0x45, 0xd4, 0xef, 0x23, 0x3a, 0x74, 0x2f, 0xf0, 0xd0, 0x4d, + 0xb8, 0xe6, 0x24, 0x57, 0x55, 0x93, 0xbe, 0xc3, 0xc3, 0x7d, 0xcd, 0x6f, 0xc1, 0x1c, 0x1f, 0x46, + 0xb8, 0x39, 0xaf, 0xb4, 0x8a, 0xdf, 0xd6, 0x06, 0x14, 0x84, 0xe9, 0x6e, 0x80, 0xc3, 0x2e, 0xef, + 0x35, 0x17, 0x36, 0x33, 0xdb, 0x73, 0x0e, 0x08, 0xe8, 0x58, 0x22, 0xd6, 0x43, 0x58, 0xa4, 0xe4, + 0xd2, 0xed, 0x90, 0x38, 0xe4, 0xcd, 0x07, 0x92, 0x9c, 0xa7, 0xe4, 0x72, 0x5f, 0x9c, 0xad, 0xc7, + 0xb0, 0x70, 0xee, 0xe3, 0xc0, 0x63, 0xcd, 0xfc, 0x66, 0x6e, 0xbb, 0xb0, 0x5b, 0x6c, 0xa9, 0x78, + 0x1d, 0x09, 0xd0, 0xd1, 0x34, 0xfb, 0x6f, 0x19, 0xa8, 0x9c, 0x4a, 0x67, 0x8c, 0x10, 0x7c, 0x02, + 0x4b, 0x42, 0x4b, 0x1b, 0x31, 0xec, 0x6a, 0xbf, 0x55, 0x34, 0xca, 0x09, 0xac, 0xae, 0x58, 0x2f, + 0x41, 0xbd, 0x8b, 0xeb, 0x8d, 0x2e, 0xb3, 0x66, 0x56, 0xaa, 0xb3, 0x5b, 0xd3, 0x4f, 0x39, 0x11, + 0x6a, 0xa7, 0xc2, 0xd3, 0x00, 0x13, 0x01, 0x1d, 0x60, 0xca, 0x7c, 0x12, 0x36, 0x73, 0x52, 0x63, + 0x72, 0x14, 0x86, 0x5a, 0x4a, 0xeb, 0x7e, 0x0f, 0x85, 0x5d, 0xec, 0x60, 0x16, 0x07, 0xdc, 0x7a, + 0x0e, 0xa5, 0x36, 0x3e, 0x27, 0x34, 0x65, 0x68, 0x61, 0xf7, 0xd1, 0x0c, 0xed, 0x93, 0x6e, 0x3a, + 0x45, 0x75, 0x53, 0xfb, 0x72, 0x04, 0x45, 0x74, 0xce, 0x31, 0x75, 0x8d, 0x97, 0xbe, 0xa5, 0xa0, + 0x82, 0xbc, 0xa8, 0x60, 0xfb, 0xdf, 0x19, 0x28, 0x9f, 0x31, 0x4c, 0x4f, 0x30, 0xed, 0xfb, 0x8c, + 0xe9, 0x94, 0xea, 0x11, 0xc6, 0x93, 0x94, 0x12, 0xbf, 0x05, 0x16, 0x33, 0x4c, 0x75, 0x42, 0xc9, + 0xdf, 0xd6, 0xaf, 0xa1, 0x1a, 0x21, 0xc6, 0x2e, 0x09, 0xf5, 0xdc, 0x4e, 0x0f, 0x77, 0x2e, 0x58, + 0xdc, 0x97, 0x71, 0x98, 0x73, 0x2a, 0x09, 0x61, 0x5f, 0xe3, 0xd6, 0x8f, 0x00, 0x11, 0xf5, 0x07, + 0x7e, 0x80, 0xbb, 0x58, 0x25, 0x56, 0x61, 0xf7, 0xb3, 0x19, 0xd6, 0xa6, 0x6d, 0x69, 0x9d, 0x8c, + 0xee, 0x1c, 0x86, 0x9c, 0x0e, 0x1d, 0x43, 0xc8, 0xda, 0x37, 0xb0, 0x34, 0x41, 0xb6, 0x2a, 0x90, + 0xbb, 0xc0, 0x43, 0x6d, 0xb9, 0xf8, 0x69, 0xd5, 0x61, 0x7e, 0x80, 0x82, 0x18, 0x6b, 0xcb, 0xd5, + 0xe1, 0xeb, 0xec, 0x57, 0x19, 0xfb, 0x5d, 0x06, 0x8a, 0x07, 0xed, 0xf7, 0xf8, 0x5d, 0x86, 0xac, + 0xd7, 0xd6, 0x77, 0xb3, 0x5e, 0x7b, 0x14, 0x87, 0x9c, 0x11, 0x87, 0x97, 0x33, 0x5c, 0xdb, 0x99, + 0xe1, 0x9a, 0xa9, 0xec, 0xff, 0xe9, 0xd8, 0x5f, 0x33, 0x50, 0x18, 0x6b, 0x62, 0xd6, 0x31, 0x54, + 0x84, 0x9d, 0x6e, 0x34, 0xc6, 0x9a, 0x19, 0x69, 0xe5, 0xd6, 0x7b, 0x1f, 0xc0, 0x59, 0x8a, 0x53, + 0x67, 0x66, 0x1d, 0x41, 0xd9, 0x6b, 0xa7, 0x64, 0xa9, 0x0a, 0xda, 0x78, 0x8f, 0xc7, 0x4e, 0xc9, + 0x33, 0x4e, 0xcc, 0xfe, 0x04, 0x0a, 0x27, 0x7e, 0xd8, 0x75, 0xf0, 0xdb, 0x18, 0x33, 0x2e, 0x4a, + 0x29, 0x42, 0xc3, 0x80, 0x20, 0x4f, 0x3b, 0x99, 0x1c, 0xed, 0x6d, 0x28, 0x2a, 0x46, 0x16, 0x91, + 0x90, 0xe1, 0x1b, 0x38, 0x9f, 0x40, 0xf1, 0x34, 0xc0, 0x38, 0x4a, 0x64, 0xae, 0x41, 0xde, 0x8b, + 0xa9, 0x6c, 0xaa, 0x92, 0x35, 0xe7, 0x8c, 0xce, 0xf6, 0x12, 0x94, 0x34, 0xaf, 0x12, 0x6b, 0xff, + 0x2b, 0x03, 0xd6, 0xe1, 0x15, 0xee, 0xc4, 0x1c, 0x3f, 0x27, 0xe4, 0x22, 0x91, 0x31, 0xab, 0xbf, + 0xae, 0x03, 0x44, 0x88, 0xa2, 0x3e, 0xe6, 0x98, 0x2a, 0xf7, 0x17, 0x1d, 0x03, 0xb1, 0x4e, 0x60, + 0x11, 0x5f, 0x71, 0x8a, 0x5c, 0x1c, 0x0e, 0x64, 0xa7, 0x2d, 0xec, 0x7e, 0x3e, 0x23, 0x3a, 0xd3, + 0xda, 0x5a, 0x87, 0xe2, 0xda, 0x61, 0x38, 0x50, 0x39, 0x91, 0xc7, 0xfa, 0xb8, 0xf6, 0x3b, 0x28, + 0xa5, 0x48, 0x77, 0xca, 0x87, 0x73, 0xa8, 0xa5, 0x54, 0xe9, 0x38, 0x6e, 0x40, 0x01, 0x5f, 0xf9, + 0xdc, 0x65, 0x1c, 0xf1, 0x98, 0xe9, 0x00, 0x81, 0x80, 0x4e, 0x25, 0x22, 0xc7, 0x08, 0xf7, 0x48, + 0xcc, 0x47, 0x63, 0x44, 0x9e, 0x34, 0x8e, 0x69, 0x52, 0x05, 0xfa, 0x64, 0x0f, 0xa0, 0xf2, 0x0c, + 0x73, 0xd5, 0x57, 0x92, 0xf0, 0xad, 0xc0, 0x82, 0x74, 0x5c, 0x65, 0xdc, 0xa2, 0xa3, 0x4f, 0xd6, + 0x23, 0x28, 0xf9, 0x61, 0x27, 0x88, 0x3d, 0xec, 0x0e, 0x7c, 0x7c, 0xc9, 0xa4, 0x8a, 0xbc, 0x53, + 0xd4, 0xe0, 0x6b, 0x81, 0x59, 0x1f, 0x43, 0x19, 0x5f, 0x29, 0x26, 0x2d, 0x44, 0x8d, 0xad, 0x92, + 0x46, 0x65, 0x83, 0x66, 0x36, 0x86, 0xaa, 0xa1, 0x57, 0x7b, 0x77, 0x02, 0x55, 0xd5, 0x19, 0x8d, + 0x66, 0x7f, 0x97, 0x6e, 0x5b, 0x61, 0x13, 0x88, 0xdd, 0x80, 0xe5, 0x67, 0x98, 0x1b, 0x29, 0xac, + 0x7d, 0xb4, 0x7f, 0x82, 0x95, 0x49, 0x82, 0x36, 0xe2, 0x0f, 0x50, 0x48, 0x17, 0x9d, 0x50, 0xbf, + 0x3e, 0x43, 0xbd, 0x79, 0xd9, 0xbc, 0x62, 0xd7, 0xc1, 0x3a, 0xc5, 0xdc, 0xc1, 0xc8, 0x7b, 0x19, + 0x06, 0xc3, 0x44, 0xe3, 0x32, 0xd4, 0x52, 0xa8, 0x4e, 0xe1, 0x31, 0xfc, 0x86, 0xfa, 0x1c, 0x27, + 0xdc, 0x2b, 0x50, 0x4f, 0xc3, 0x9a, 0xfd, 0x5b, 0xa8, 0xaa, 0xe1, 0xf4, 0x6a, 0x18, 0x25, 0xcc, + 0xd6, 0x6f, 0xa1, 0xa0, 0xcc, 0x73, 0xe5, 0x80, 0x17, 0x26, 0x97, 0x77, 0xeb, 0xad, 0xd1, 0xbe, + 0x22, 0x63, 0xce, 0xe5, 0x0d, 0xe0, 0xa3, 0xdf, 0xc2, 0x4e, 0x53, 0xd6, 0xd8, 0x20, 0x07, 0x9f, + 0x53, 0xcc, 0x7a, 0x22, 0xa5, 0x4c, 0x83, 0xd2, 0xb0, 0x66, 0x6f, 0xc0, 0xb2, 0x13, 0x87, 0xcf, + 0x31, 0x0a, 0x78, 0x4f, 0x0e, 0x8e, 0xe4, 0x42, 0x13, 0x56, 0x26, 0x09, 0xfa, 0xca, 0x17, 0xd0, + 0x7c, 0xd1, 0x0d, 0x09, 0xc5, 0x8a, 0x78, 0x48, 0x29, 0xa1, 0xa9, 0x96, 0xc2, 0x39, 0xa6, 0xe1, + 0xb8, 0x51, 0xc8, 0xa3, 0xfd, 0x10, 0x56, 0x67, 0xdc, 0xd2, 0x22, 0xbf, 0x16, 0x46, 0x8b, 0x7e, + 0x92, 0xce, 0xe4, 0x47, 0x50, 0xba, 0x44, 0x3e, 0x77, 0x23, 0xc2, 0xc6, 0xc9, 0xb4, 0xe8, 0x14, + 0x05, 0x78, 0xa2, 0x31, 0xe5, 0x99, 0x79, 0x57, 0xcb, 0xdc, 0x85, 0x95, 0x13, 0x8a, 0xcf, 0x03, + 0xbf, 0xdb, 0x9b, 0x28, 0x10, 0xb1, 0x93, 0xc9, 0xc0, 0x25, 0x15, 0x92, 0x1c, 0xed, 0x2e, 0x34, + 0xa6, 0xee, 0xe8, 0xbc, 0x3a, 0x86, 0xb2, 0xe2, 0x72, 0xa9, 0xdc, 0x2b, 0x92, 0x7e, 0xfe, 0xf1, + 0xb5, 0x99, 0x6d, 0x6e, 0x21, 0x4e, 0xa9, 0x63, 0x9c, 0x98, 0xfd, 0x9f, 0x0c, 0x58, 0x7b, 0x51, + 0x14, 0x0c, 0xd3, 0x96, 0x55, 0x20, 0xc7, 0xde, 0x06, 0x49, 0x8b, 0x61, 0x6f, 0x03, 0xd1, 0x62, + 0xce, 0x09, 0xed, 0x60, 0x5d, 0xac, 0xea, 0x20, 0xd6, 0x00, 0x14, 0x04, 0xe4, 0xd2, 0x35, 0x76, + 0x58, 0xd9, 0x19, 0xf2, 0x4e, 0x45, 0x12, 0x9c, 0x31, 0x3e, 0xbd, 0x00, 0xcd, 0x7d, 0xa8, 0x05, + 0x68, 0xfe, 0x9e, 0x0b, 0xd0, 0xdf, 0x33, 0x50, 0x4b, 0x79, 0xaf, 0x63, 0xfc, 0xf3, 0x5b, 0xd5, + 0x6a, 0x50, 0x3d, 0x26, 0x9d, 0x0b, 0xd5, 0xf5, 0x92, 0xd2, 0xa8, 0x83, 0x65, 0x82, 0xe3, 0xc2, + 0x3b, 0x0b, 0x83, 0x29, 0xe6, 0x15, 0xa8, 0xa7, 0x61, 0xcd, 0xfe, 0x8f, 0x0c, 0x34, 0xf5, 0x88, + 0x38, 0xc2, 0xbc, 0xd3, 0xdb, 0x63, 0x07, 0xed, 0x51, 0x1e, 0xd4, 0x61, 0x5e, 0xae, 0xe2, 0x32, + 0x00, 0x45, 0x47, 0x1d, 0xac, 0x06, 0x3c, 0xf0, 0xda, 0xae, 0x1c, 0x8d, 0x7a, 0x3a, 0x78, 0xed, + 0x1f, 0xc4, 0x70, 0x5c, 0x85, 0x7c, 0x1f, 0x5d, 0xb9, 0x94, 0x5c, 0x32, 0xbd, 0x0c, 0x3e, 0xe8, + 0xa3, 0x2b, 0x87, 0x5c, 0x32, 0xb9, 0xa8, 0xfb, 0x4c, 0x6e, 0xe0, 0x6d, 0x3f, 0x0c, 0x48, 0x97, + 0xc9, 0xe7, 0xcf, 0x3b, 0x65, 0x0d, 0x3f, 0x55, 0xa8, 0xa8, 0x35, 0x2a, 0xcb, 0xc8, 0x7c, 0xdc, + 0xbc, 0x53, 0xa4, 0x46, 0x6d, 0xd9, 0xcf, 0x60, 0x75, 0x86, 0xcd, 0xfa, 0xf5, 0x9e, 0xc0, 0x82, + 0x2a, 0x0d, 0xfd, 0x6c, 0x96, 0xfe, 0x9c, 0xf8, 0x51, 0xfc, 0xd5, 0x65, 0xa0, 0x39, 0xec, 0x3f, + 0x67, 0xe0, 0xa3, 0xb4, 0xa4, 0xbd, 0x20, 0x10, 0x0b, 0x18, 0xfb, 0xf0, 0x21, 0x98, 0xf2, 0x6c, + 0x6e, 0x86, 0x67, 0xc7, 0xb0, 0x7e, 0x9d, 0x3d, 0xf7, 0x70, 0xef, 0xbb, 0xc9, 0xb7, 0xdd, 0x8b, + 0xa2, 0x9b, 0x1d, 0x33, 0xed, 0xcf, 0xa6, 0xec, 0x9f, 0x0e, 0xba, 0x14, 0x76, 0x0f, 0xab, 0xc4, + 0x60, 0x0b, 0xd0, 0x00, 0xab, 0x5d, 0x23, 0x49, 0xd0, 0x23, 0xa8, 0xa5, 0x50, 0x2d, 0x78, 0x47, + 0x6c, 0x1c, 0xa3, 0x2d, 0xa5, 0xb0, 0xdb, 0x68, 0x4d, 0x7e, 0x2f, 0xeb, 0x0b, 0x9a, 0x4d, 0x4c, + 0x92, 0xef, 0x11, 0xe3, 0x98, 0x26, 0x9d, 0x39, 0x51, 0xf0, 0x05, 0xac, 0x4c, 0x12, 0xb4, 0x8e, + 0x35, 0xc8, 0x4f, 0xb4, 0xf6, 0xd1, 0x59, 0xdc, 0x7a, 0x83, 0x7c, 0x7e, 0x44, 0x26, 0xe5, 0xdd, + 0x78, 0x6b, 0x15, 0x1a, 0x53, 0xb7, 0x74, 0xc1, 0x59, 0x50, 0x39, 0xe5, 0x24, 0x92, 0xbe, 0x26, + 0xa6, 0xd5, 0xa0, 0x6a, 0x60, 0x9a, 0xf1, 0x8f, 0xd0, 0x18, 0x81, 0xdf, 0xfb, 0xa1, 0xdf, 0x8f, + 0xfb, 0xb7, 0x50, 0x6d, 0x6d, 0x81, 0x9c, 0x4b, 0x2e, 0xf7, 0xfb, 0x38, 0x59, 0xe0, 0x72, 0x4e, + 0x41, 0x60, 0xaf, 0x14, 0x64, 0x7f, 0x09, 0xcd, 0x69, 0xc9, 0xb7, 0x88, 0x85, 0x34, 0x13, 0x51, + 0x9e, 0xb2, 0x5d, 0xbc, 0xa6, 0x01, 0x6a, 0xe3, 0xff, 0x04, 0x0f, 0xc7, 0xe8, 0x59, 0xc8, 0xfd, + 0x60, 0x4f, 0xb4, 0xb3, 0x0f, 0xe4, 0xc0, 0x3a, 0xfc, 0x62, 0xb6, 0x74, 0xad, 0xfd, 0x00, 0xb6, + 0xd4, 0xb2, 0x72, 0x78, 0x25, 0x86, 0x3e, 0x0a, 0xc4, 0xa6, 0x14, 0x21, 0x8a, 0x43, 0x8e, 0xbd, + 0xc4, 0x06, 0xb9, 0x04, 0x2b, 0xb2, 0xeb, 0x27, 0x1f, 0x14, 0x90, 0x40, 0x2f, 0x3c, 0xfb, 0x31, + 0xd8, 0x37, 0x49, 0xd1, 0xba, 0x36, 0x61, 0x7d, 0x92, 0xeb, 0x30, 0xc0, 0x9d, 0xb1, 0x22, 0x7b, + 0x0b, 0x36, 0xae, 0xe5, 0x18, 0x27, 0x85, 0xd8, 0x63, 0x85, 0x3b, 0xa3, 0x82, 0xf8, 0x95, 0xda, + 0x6d, 0x35, 0xa6, 0x9f, 0xa7, 0x0e, 0xf3, 0xc8, 0xf3, 0x68, 0xb2, 0x31, 0xa8, 0x83, 0x48, 0x37, + 0x07, 0x33, 0xb1, 0xe8, 0x8d, 0x4a, 0x23, 0x91, 0xb2, 0x06, 0xcd, 0x69, 0x92, 0xd6, 0xba, 0x03, + 0x8d, 0xd7, 0x06, 0x2e, 0xaa, 0x7b, 0x66, 0x77, 0x58, 0xd4, 0xdd, 0xc1, 0x3e, 0x82, 0xe6, 0xf4, + 0x85, 0x7b, 0xf5, 0xa5, 0x8f, 0x4c, 0x39, 0xe3, 0x52, 0x49, 0xd4, 0x97, 0x21, 0xab, 0x9f, 0x24, + 0xe7, 0x64, 0x7d, 0x2f, 0x95, 0x2f, 0xd9, 0x89, 0xac, 0xdc, 0x84, 0xf5, 0xeb, 0x84, 0x69, 0x3f, + 0x6b, 0x50, 0x7d, 0x11, 0xfa, 0x5c, 0x55, 0x7f, 0x12, 0x98, 0x4f, 0xc1, 0x32, 0xc1, 0x5b, 0xa4, + 0xff, 0xbb, 0x0c, 0xac, 0x9f, 0x90, 0x28, 0x0e, 0xe4, 0xe2, 0xaa, 0x12, 0xe1, 0x5b, 0x12, 0x8b, + 0x17, 0x4d, 0xec, 0xfe, 0x25, 0x2c, 0x89, 0xb4, 0x75, 0x3b, 0x14, 0x23, 0x8e, 0x3d, 0x37, 0x4c, + 0x3e, 0xae, 0x4a, 0x02, 0xde, 0x57, 0xe8, 0x0f, 0x4c, 0xe4, 0x1e, 0xea, 0x08, 0xa1, 0xe6, 0x0c, + 0x01, 0x05, 0xc9, 0x39, 0xf2, 0x15, 0x14, 0xfb, 0xd2, 0x32, 0x17, 0x05, 0x3e, 0x52, 0xb3, 0xa4, + 0xb0, 0xbb, 0x3c, 0xb9, 0x8c, 0xef, 0x09, 0xa2, 0x53, 0x50, 0xac, 0xf2, 0x60, 0x7d, 0x06, 0x75, + 0xa3, 0x43, 0x8e, 0x77, 0xd6, 0x39, 0xa9, 0xa3, 0x66, 0xd0, 0x46, 0xab, 0xeb, 0x16, 0x6c, 0x5c, + 0xeb, 0x97, 0x0e, 0xe1, 0x5f, 0x32, 0x50, 0x11, 0xe1, 0x32, 0x4b, 0xdf, 0xfa, 0x0d, 0x2c, 0x28, + 0x6e, 0xfd, 0xe4, 0xd7, 0x98, 0xa7, 0x99, 0xae, 0xb5, 0x2c, 0x7b, 0xad, 0x65, 0xb3, 0xe2, 0x99, + 0x9b, 0x11, 0xcf, 0xe4, 0x85, 0xd3, 0x3d, 0x68, 0x19, 0x6a, 0x07, 0xb8, 0x4f, 0x38, 0x4e, 0x3f, + 0xfc, 0x2e, 0xd4, 0xd3, 0xf0, 0x2d, 0x9e, 0x7e, 0x15, 0x1a, 0x67, 0xa1, 0x47, 0x66, 0x89, 0x5b, + 0x83, 0xe6, 0x34, 0x49, 0x5b, 0xf0, 0x0d, 0x6c, 0x9c, 0x50, 0x22, 0x08, 0xd2, 0xb2, 0x37, 0x3d, + 0x1c, 0xee, 0xa3, 0xb8, 0xdb, 0xe3, 0x67, 0xd1, 0x6d, 0xa6, 0xc8, 0xef, 0x61, 0xf3, 0xfa, 0xeb, + 0xb7, 0xb3, 0x5a, 0x5d, 0x44, 0x4c, 0xcb, 0xf1, 0x0c, 0xab, 0xa7, 0x49, 0xda, 0xea, 0x7f, 0x66, + 0xa0, 0x72, 0x8a, 0xd3, 0xe5, 0x72, 0xd7, 0xb7, 0x9e, 0xf1, 0x70, 0xd9, 0x59, 0x85, 0x30, 0xf5, + 0x69, 0x35, 0x37, 0xfd, 0x69, 0x65, 0x3d, 0x81, 0xaa, 0xfc, 0xde, 0x70, 0x99, 0x68, 0xfa, 0x2e, + 0x13, 0x86, 0xeb, 0xcf, 0x8c, 0x25, 0x49, 0x18, 0x0f, 0x03, 0x39, 0xa3, 0xf0, 0x44, 0x55, 0xdb, + 0x2f, 0xc6, 0xde, 0x3a, 0x58, 0x0a, 0x19, 0x8f, 0x81, 0xbb, 0x39, 0x26, 0xbe, 0x1f, 0x67, 0x88, + 0xd2, 0x7a, 0x1e, 0x83, 0x2d, 0x06, 0xab, 0xd1, 0x8d, 0xf6, 0x42, 0x4f, 0x34, 0xf1, 0xd4, 0xa6, + 0xf3, 0x1a, 0x1e, 0xdd, 0xc8, 0x75, 0xdf, 0xcd, 0x67, 0x19, 0x6a, 0x66, 0xba, 0x18, 0xf9, 0x9e, + 0x86, 0x6f, 0x91, 0x39, 0xa7, 0x50, 0x7a, 0x8a, 0x3a, 0x17, 0xf1, 0x28, 0x4d, 0x37, 0xa1, 0xd0, + 0x21, 0x61, 0x27, 0xa6, 0x14, 0x87, 0x9d, 0xa1, 0x6e, 0x6a, 0x26, 0x24, 0x38, 0xe4, 0x27, 0x9f, + 0x0a, 0xbd, 0xfe, 0x4e, 0x34, 0x21, 0xfb, 0x4b, 0x28, 0x27, 0x42, 0xb5, 0x09, 0x8f, 0x61, 0x1e, + 0x0f, 0xc6, 0xa1, 0x2f, 0xb7, 0x92, 0x7f, 0x7a, 0x1c, 0x0a, 0xd4, 0x51, 0x44, 0x3d, 0xc2, 0x38, + 0xa1, 0xf8, 0x88, 0x92, 0x7e, 0xca, 0x2e, 0x7b, 0x0f, 0x56, 0x67, 0xd0, 0xee, 0x22, 0xfe, 0xe9, + 0xa7, 0x3f, 0xb5, 0x06, 0x3e, 0xc7, 0x8c, 0xb5, 0x7c, 0xb2, 0xa3, 0x7e, 0xed, 0x74, 0xc9, 0xce, + 0x80, 0xef, 0xc8, 0x7f, 0xbd, 0xec, 0x4c, 0x7d, 0xab, 0xb5, 0x17, 0x24, 0xe1, 0xf3, 0xff, 0x05, + 0x00, 0x00, 0xff, 0xff, 0x05, 0x80, 0x1f, 0x06, 0x04, 0x1a, 0x00, 0x00, } diff --git a/go/vt/proto/tabletmanagerservice/tabletmanagerservice.pb.go b/go/vt/proto/tabletmanagerservice/tabletmanagerservice.pb.go index 686c293a382..1f494400a18 100644 --- a/go/vt/proto/tabletmanagerservice/tabletmanagerservice.pb.go +++ b/go/vt/proto/tabletmanagerservice/tabletmanagerservice.pb.go @@ -1,16 +1,18 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // source: tabletmanagerservice.proto -package tabletmanagerservice // import "vitess.io/vitess/go/vt/proto/tabletmanagerservice" - -import proto "github.com/golang/protobuf/proto" -import fmt "fmt" -import math "math" -import tabletmanagerdata "vitess.io/vitess/go/vt/proto/tabletmanagerdata" +package tabletmanagerservice import ( - context "golang.org/x/net/context" + context "context" + fmt "fmt" + math "math" + + proto "github.com/golang/protobuf/proto" grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + tabletmanagerdata "vitess.io/vitess/go/vt/proto/tabletmanagerdata" ) // Reference imports to suppress errors if they are not otherwise used. @@ -22,7 +24,79 @@ var _ = math.Inf // is compatible with the proto package it is being compiled against. // A compilation error at this line likely means your copy of the // proto package needs to be updated. -const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package +const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package + +func init() { proto.RegisterFile("tabletmanagerservice.proto", fileDescriptor_9ee75fe63cfd9360) } + +var fileDescriptor_9ee75fe63cfd9360 = []byte{ + // 1041 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x98, 0x6d, 0x6f, 0x1b, 0x45, + 0x10, 0xc7, 0xb1, 0x04, 0x95, 0x58, 0x1e, 0xbb, 0xaa, 0x28, 0x0a, 0x12, 0x4f, 0x6d, 0x78, 0x48, + 0x51, 0xdc, 0x34, 0x94, 0xf7, 0x6e, 0x9a, 0xb4, 0x41, 0x8d, 0x30, 0x76, 0x43, 0x10, 0x48, 0x48, + 0x1b, 0x7b, 0x62, 0x1f, 0x39, 0xef, 0x1e, 0xbb, 0x7b, 0x56, 0xf3, 0x0a, 0x09, 0x89, 0x57, 0x48, + 0x7c, 0x11, 0xbe, 0x24, 0xba, 0x87, 0xdd, 0x9b, 0x3d, 0xcf, 0xad, 0xed, 0x77, 0x91, 0xff, 0xbf, + 0x99, 0xd9, 0x87, 0x99, 0xd9, 0xc9, 0xb1, 0x1d, 0x2b, 0x2e, 0x53, 0xb0, 0x0b, 0x21, 0xc5, 0x0c, + 0xb4, 0x01, 0xbd, 0x4c, 0x26, 0xb0, 0x9f, 0x69, 0x65, 0x15, 0xbf, 0x43, 0x69, 0x3b, 0x77, 0x83, + 0x5f, 0xa7, 0xc2, 0x8a, 0x0a, 0x7f, 0xf4, 0xdf, 0x2e, 0x7b, 0xe7, 0x65, 0xa9, 0x9d, 0x55, 0x1a, + 0x3f, 0x65, 0xaf, 0x0f, 0x13, 0x39, 0xe3, 0x1f, 0xef, 0xaf, 0xda, 0x14, 0xc2, 0x08, 0xfe, 0xc8, + 0xc1, 0xd8, 0x9d, 0x4f, 0x3a, 0x75, 0x93, 0x29, 0x69, 0xe0, 0xf3, 0xd7, 0xf8, 0x0b, 0xf6, 0xc6, + 0x38, 0x05, 0xc8, 0x38, 0xc5, 0x96, 0x8a, 0x73, 0xf6, 0x69, 0x37, 0xe0, 0xbd, 0xfd, 0xc6, 0xde, + 0x3a, 0x7e, 0x05, 0x93, 0xdc, 0xc2, 0x73, 0xa5, 0xae, 0xf9, 0x2e, 0x61, 0x82, 0x74, 0xe7, 0xf9, + 0x8b, 0x75, 0x98, 0xf7, 0xff, 0x33, 0x7b, 0xf3, 0x19, 0xd8, 0xf1, 0x64, 0x0e, 0x0b, 0xc1, 0xef, + 0x11, 0x66, 0x5e, 0x75, 0xbe, 0xef, 0xc7, 0x21, 0xef, 0x79, 0xc6, 0xde, 0x7d, 0x06, 0x76, 0x08, + 0x7a, 0x91, 0x18, 0x93, 0x28, 0x69, 0xf8, 0x57, 0xb4, 0x25, 0x42, 0x5c, 0x8c, 0xaf, 0x37, 0x20, + 0xf1, 0x11, 0x8d, 0xc1, 0x8e, 0x40, 0x4c, 0x7f, 0x90, 0xe9, 0x0d, 0x79, 0x44, 0x48, 0x8f, 0x1d, + 0x51, 0x80, 0x79, 0xff, 0x82, 0xbd, 0x5d, 0x0b, 0x17, 0x3a, 0xb1, 0xc0, 0x23, 0x96, 0x25, 0xe0, + 0x22, 0x7c, 0xb9, 0x96, 0xf3, 0x21, 0x7e, 0x65, 0xec, 0x68, 0x2e, 0xe4, 0x0c, 0x5e, 0xde, 0x64, + 0xc0, 0xa9, 0x13, 0x6e, 0x64, 0xe7, 0x7e, 0x77, 0x0d, 0x85, 0xd7, 0x3f, 0x82, 0x2b, 0x0d, 0x66, + 0x3e, 0xb6, 0xa2, 0x63, 0xfd, 0x18, 0x88, 0xad, 0x3f, 0xe4, 0xf0, 0x5d, 0x8f, 0x72, 0xf9, 0x1c, + 0x44, 0x6a, 0xe7, 0x47, 0x73, 0x98, 0x5c, 0x93, 0x77, 0x1d, 0x22, 0xb1, 0xbb, 0x6e, 0x93, 0x3e, + 0x50, 0xc6, 0x6e, 0x9f, 0xce, 0xa4, 0xd2, 0x50, 0xc9, 0xc7, 0x5a, 0x2b, 0xcd, 0x1f, 0x10, 0x1e, + 0x56, 0x28, 0x17, 0xee, 0x9b, 0xcd, 0xe0, 0xf0, 0xf4, 0x52, 0x25, 0xa6, 0x75, 0x8d, 0xd0, 0xa7, + 0xd7, 0x00, 0xf1, 0xd3, 0xc3, 0x9c, 0x0f, 0xf1, 0x3b, 0x7b, 0x6f, 0xa8, 0xe1, 0x2a, 0x4d, 0x66, + 0x73, 0x57, 0x89, 0xd4, 0xa1, 0xb4, 0x18, 0x17, 0x68, 0x6f, 0x13, 0x14, 0x17, 0xcb, 0x20, 0xcb, + 0xd2, 0x9b, 0x3a, 0x0e, 0x95, 0x44, 0x48, 0x8f, 0x15, 0x4b, 0x80, 0xe1, 0x4c, 0x7e, 0xa1, 0x26, + 0xd7, 0x65, 0x77, 0x35, 0x64, 0x26, 0x37, 0x72, 0x2c, 0x93, 0x31, 0x85, 0xef, 0xe2, 0x5c, 0xa6, + 0x8d, 0x7b, 0x6a, 0x59, 0x18, 0x88, 0xdd, 0x45, 0xc8, 0xe1, 0x04, 0xab, 0x1b, 0xe5, 0x09, 0xd8, + 0xc9, 0x7c, 0x60, 0x9e, 0x5e, 0x0a, 0x32, 0xc1, 0x56, 0xa8, 0x58, 0x82, 0x11, 0xb0, 0x8f, 0xf8, + 0x27, 0xfb, 0x20, 0x94, 0x07, 0x69, 0x3a, 0xd4, 0xc9, 0xd2, 0xf0, 0x87, 0x6b, 0x3d, 0x39, 0xd4, + 0xc5, 0x3e, 0xd8, 0xc2, 0xa2, 0x7b, 0xcb, 0x83, 0x2c, 0xdb, 0x60, 0xcb, 0x83, 0x2c, 0xdb, 0x7c, + 0xcb, 0x25, 0x1c, 0x74, 0xec, 0x54, 0x2c, 0xa1, 0x68, 0x23, 0xb9, 0xa1, 0x3b, 0x76, 0xa3, 0x47, + 0x3b, 0x36, 0xc6, 0x70, 0x3b, 0x3a, 0x13, 0xc6, 0x82, 0x1e, 0x2a, 0x93, 0xd8, 0x44, 0x49, 0xb2, + 0x1d, 0x85, 0x48, 0xac, 0x1d, 0xb5, 0x49, 0x5c, 0xb9, 0x17, 0x22, 0xb1, 0x27, 0xaa, 0x89, 0x44, + 0xd9, 0xb7, 0x98, 0x58, 0xe5, 0xae, 0xa0, 0xf8, 0xa5, 0x1e, 0x5b, 0x95, 0x95, 0x3b, 0x26, 0x5f, + 0x6a, 0xaf, 0xc6, 0x5e, 0x6a, 0x04, 0x79, 0xcf, 0x0b, 0xf6, 0xbe, 0xff, 0xf9, 0x2c, 0x91, 0xc9, + 0x22, 0x5f, 0xf0, 0xbd, 0x98, 0x6d, 0x0d, 0xb9, 0x38, 0x0f, 0x36, 0x62, 0x71, 0x8b, 0x18, 0x5b, + 0xa1, 0x6d, 0xb5, 0x13, 0x7a, 0x91, 0x4e, 0x8e, 0xb5, 0x08, 0x4c, 0x79, 0xe7, 0x37, 0xec, 0x4e, + 0xf3, 0xfb, 0xb9, 0xb4, 0x49, 0x3a, 0xb8, 0xb2, 0xa0, 0xf9, 0x7e, 0xd4, 0x41, 0x03, 0xba, 0x80, + 0xfd, 0x8d, 0x79, 0x1f, 0xfa, 0x9f, 0x1e, 0xdb, 0xa9, 0xa6, 0xca, 0xe3, 0x57, 0x16, 0xb4, 0x14, + 0x69, 0x31, 0x46, 0x64, 0x42, 0x83, 0xb4, 0x30, 0xe5, 0xdf, 0x12, 0x1e, 0xbb, 0x71, 0xb7, 0x8e, + 0xc7, 0x5b, 0x5a, 0xf9, 0xd5, 0xfc, 0xd5, 0x63, 0x77, 0xdb, 0xe0, 0x71, 0x0a, 0x93, 0x62, 0x29, + 0x07, 0x1b, 0x38, 0xad, 0x59, 0xb7, 0x8e, 0x47, 0xdb, 0x98, 0xb4, 0xa7, 0xcb, 0xe2, 0xc8, 0x4c, + 0xe7, 0x74, 0x59, 0xaa, 0xeb, 0xa6, 0xcb, 0x1a, 0xc2, 0x39, 0xfb, 0xd3, 0x08, 0xb2, 0x34, 0x99, + 0x88, 0xa2, 0x4e, 0x8a, 0x6e, 0x43, 0xe6, 0x6c, 0x1b, 0x8a, 0xe5, 0xec, 0x2a, 0x8b, 0x9b, 0x34, + 0x56, 0x9b, 0x2a, 0x25, 0x9b, 0x34, 0x8d, 0xc6, 0x9a, 0x74, 0x97, 0x05, 0xde, 0xef, 0x08, 0x4c, + 0x31, 0x3d, 0x7a, 0x8e, 0xdc, 0x6f, 0x1b, 0x8a, 0xed, 0x77, 0x95, 0xc5, 0x35, 0x7a, 0x2a, 0x13, + 0x5b, 0x35, 0x3e, 0xb2, 0x46, 0x1b, 0x39, 0x56, 0xa3, 0x98, 0x0a, 0x52, 0x73, 0xa8, 0xb2, 0x3c, + 0x2d, 0x87, 0xc8, 0x2a, 0x77, 0xbf, 0x57, 0x79, 0x91, 0x44, 0x64, 0x6a, 0x76, 0xb0, 0xb1, 0xd4, + 0xec, 0x34, 0xc1, 0xa9, 0x59, 0x2c, 0xae, 0xbb, 0x9d, 0x7a, 0x35, 0x96, 0x9a, 0x08, 0xc2, 0x53, + 0xca, 0x53, 0x58, 0x28, 0x0b, 0xf5, 0xe9, 0x51, 0xef, 0x16, 0x06, 0x62, 0x53, 0x4a, 0xc8, 0xe1, + 0x6c, 0x38, 0x97, 0x53, 0x15, 0x84, 0xd9, 0x23, 0x87, 0x9c, 0x10, 0x8a, 0x65, 0xc3, 0x2a, 0xeb, + 0xc3, 0xfd, 0xdd, 0x63, 0x1f, 0x0e, 0xb5, 0x2a, 0xb4, 0x72, 0xb3, 0x17, 0x73, 0x90, 0x47, 0x22, + 0x9f, 0xcd, 0xed, 0x79, 0xc6, 0xc9, 0xe3, 0xef, 0x80, 0x5d, 0xfc, 0xc3, 0xad, 0x6c, 0x82, 0x87, + 0xaa, 0x94, 0x85, 0xa9, 0xe9, 0x29, 0xfd, 0x50, 0xb5, 0xa0, 0xe8, 0x43, 0xb5, 0xc2, 0x06, 0x2f, + 0x2e, 0xb8, 0x1a, 0xb8, 0x47, 0xff, 0x37, 0x17, 0x9e, 0xeb, 0xfd, 0x38, 0x84, 0x47, 0x2e, 0x17, + 0x77, 0x04, 0xa6, 0x78, 0x56, 0x60, 0xca, 0x63, 0xab, 0xf3, 0x54, 0x6c, 0xe4, 0x22, 0x60, 0x1f, + 0xf1, 0xdf, 0x1e, 0xfb, 0xa8, 0x78, 0x93, 0x51, 0xb9, 0x0f, 0xe4, 0xb4, 0xe8, 0xac, 0xd5, 0x0c, + 0xf6, 0xb8, 0xe3, 0x0d, 0xef, 0xe0, 0xdd, 0x32, 0xbe, 0xdb, 0xd6, 0x0c, 0x57, 0x09, 0xbe, 0x71, + 0xb2, 0x4a, 0x30, 0x10, 0xab, 0x92, 0x90, 0xf3, 0x21, 0x7e, 0x64, 0xb7, 0x9e, 0x88, 0xc9, 0x75, + 0x9e, 0x71, 0xea, 0x4b, 0x4b, 0x25, 0x39, 0xb7, 0x9f, 0x45, 0x08, 0xe7, 0xf0, 0x61, 0x8f, 0x6b, + 0x76, 0xbb, 0x38, 0x5d, 0xa5, 0xe1, 0x44, 0xab, 0x45, 0xed, 0xbd, 0xa3, 0xb7, 0x86, 0x54, 0xec, + 0xe2, 0x08, 0xb8, 0x89, 0xf9, 0xe4, 0xf0, 0x97, 0x83, 0x65, 0x62, 0xc1, 0x98, 0xfd, 0x44, 0xf5, + 0xab, 0xbf, 0xfa, 0x33, 0xd5, 0x5f, 0xda, 0x7e, 0xf9, 0x35, 0xab, 0x4f, 0x7d, 0xfb, 0xba, 0xbc, + 0x55, 0x6a, 0x87, 0xff, 0x07, 0x00, 0x00, 0xff, 0xff, 0xcf, 0xa2, 0x81, 0x89, 0x36, 0x13, 0x00, + 0x00, +} // Reference imports to suppress errors if they are not otherwise used. var _ context.Context @@ -65,6 +139,8 @@ type TabletManagerClient interface { SlaveStatus(ctx context.Context, in *tabletmanagerdata.SlaveStatusRequest, opts ...grpc.CallOption) (*tabletmanagerdata.SlaveStatusResponse, error) // MasterPosition returns the current master position MasterPosition(ctx context.Context, in *tabletmanagerdata.MasterPositionRequest, opts ...grpc.CallOption) (*tabletmanagerdata.MasterPositionResponse, error) + // WaitForPosition waits for the position to be reached + WaitForPosition(ctx context.Context, in *tabletmanagerdata.WaitForPositionRequest, opts ...grpc.CallOption) (*tabletmanagerdata.WaitForPositionResponse, error) // StopSlave makes mysql stop its replication StopSlave(ctx context.Context, in *tabletmanagerdata.StopSlaveRequest, opts ...grpc.CallOption) (*tabletmanagerdata.StopSlaveResponse, error) // StopSlaveMinimum stops the mysql replication after it reaches @@ -335,6 +411,15 @@ func (c *tabletManagerClient) MasterPosition(ctx context.Context, in *tabletmana return out, nil } +func (c *tabletManagerClient) WaitForPosition(ctx context.Context, in *tabletmanagerdata.WaitForPositionRequest, opts ...grpc.CallOption) (*tabletmanagerdata.WaitForPositionResponse, error) { + out := new(tabletmanagerdata.WaitForPositionResponse) + err := c.cc.Invoke(ctx, "/tabletmanagerservice.TabletManager/WaitForPosition", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *tabletManagerClient) StopSlave(ctx context.Context, in *tabletmanagerdata.StopSlaveRequest, opts ...grpc.CallOption) (*tabletmanagerdata.StopSlaveResponse, error) { out := new(tabletmanagerdata.StopSlaveResponse) err := c.cc.Invoke(ctx, "/tabletmanagerservice.TabletManager/StopSlave", in, out, opts...) @@ -619,6 +704,8 @@ type TabletManagerServer interface { SlaveStatus(context.Context, *tabletmanagerdata.SlaveStatusRequest) (*tabletmanagerdata.SlaveStatusResponse, error) // MasterPosition returns the current master position MasterPosition(context.Context, *tabletmanagerdata.MasterPositionRequest) (*tabletmanagerdata.MasterPositionResponse, error) + // WaitForPosition waits for the position to be reached + WaitForPosition(context.Context, *tabletmanagerdata.WaitForPositionRequest) (*tabletmanagerdata.WaitForPositionResponse, error) // StopSlave makes mysql stop its replication StopSlave(context.Context, *tabletmanagerdata.StopSlaveRequest) (*tabletmanagerdata.StopSlaveResponse, error) // StopSlaveMinimum stops the mysql replication after it reaches @@ -692,6 +779,146 @@ type TabletManagerServer interface { RestoreFromBackup(*tabletmanagerdata.RestoreFromBackupRequest, TabletManager_RestoreFromBackupServer) error } +// UnimplementedTabletManagerServer can be embedded to have forward compatible implementations. +type UnimplementedTabletManagerServer struct { +} + +func (*UnimplementedTabletManagerServer) Ping(ctx context.Context, req *tabletmanagerdata.PingRequest) (*tabletmanagerdata.PingResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Ping not implemented") +} +func (*UnimplementedTabletManagerServer) Sleep(ctx context.Context, req *tabletmanagerdata.SleepRequest) (*tabletmanagerdata.SleepResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Sleep not implemented") +} +func (*UnimplementedTabletManagerServer) ExecuteHook(ctx context.Context, req *tabletmanagerdata.ExecuteHookRequest) (*tabletmanagerdata.ExecuteHookResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ExecuteHook not implemented") +} +func (*UnimplementedTabletManagerServer) GetSchema(ctx context.Context, req *tabletmanagerdata.GetSchemaRequest) (*tabletmanagerdata.GetSchemaResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetSchema not implemented") +} +func (*UnimplementedTabletManagerServer) GetPermissions(ctx context.Context, req *tabletmanagerdata.GetPermissionsRequest) (*tabletmanagerdata.GetPermissionsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetPermissions not implemented") +} +func (*UnimplementedTabletManagerServer) SetReadOnly(ctx context.Context, req *tabletmanagerdata.SetReadOnlyRequest) (*tabletmanagerdata.SetReadOnlyResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method SetReadOnly not implemented") +} +func (*UnimplementedTabletManagerServer) SetReadWrite(ctx context.Context, req *tabletmanagerdata.SetReadWriteRequest) (*tabletmanagerdata.SetReadWriteResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method SetReadWrite not implemented") +} +func (*UnimplementedTabletManagerServer) ChangeType(ctx context.Context, req *tabletmanagerdata.ChangeTypeRequest) (*tabletmanagerdata.ChangeTypeResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ChangeType not implemented") +} +func (*UnimplementedTabletManagerServer) RefreshState(ctx context.Context, req *tabletmanagerdata.RefreshStateRequest) (*tabletmanagerdata.RefreshStateResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method RefreshState not implemented") +} +func (*UnimplementedTabletManagerServer) RunHealthCheck(ctx context.Context, req *tabletmanagerdata.RunHealthCheckRequest) (*tabletmanagerdata.RunHealthCheckResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method RunHealthCheck not implemented") +} +func (*UnimplementedTabletManagerServer) IgnoreHealthError(ctx context.Context, req *tabletmanagerdata.IgnoreHealthErrorRequest) (*tabletmanagerdata.IgnoreHealthErrorResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method IgnoreHealthError not implemented") +} +func (*UnimplementedTabletManagerServer) ReloadSchema(ctx context.Context, req *tabletmanagerdata.ReloadSchemaRequest) (*tabletmanagerdata.ReloadSchemaResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ReloadSchema not implemented") +} +func (*UnimplementedTabletManagerServer) PreflightSchema(ctx context.Context, req *tabletmanagerdata.PreflightSchemaRequest) (*tabletmanagerdata.PreflightSchemaResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method PreflightSchema not implemented") +} +func (*UnimplementedTabletManagerServer) ApplySchema(ctx context.Context, req *tabletmanagerdata.ApplySchemaRequest) (*tabletmanagerdata.ApplySchemaResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ApplySchema not implemented") +} +func (*UnimplementedTabletManagerServer) LockTables(ctx context.Context, req *tabletmanagerdata.LockTablesRequest) (*tabletmanagerdata.LockTablesResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method LockTables not implemented") +} +func (*UnimplementedTabletManagerServer) UnlockTables(ctx context.Context, req *tabletmanagerdata.UnlockTablesRequest) (*tabletmanagerdata.UnlockTablesResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method UnlockTables not implemented") +} +func (*UnimplementedTabletManagerServer) ExecuteFetchAsDba(ctx context.Context, req *tabletmanagerdata.ExecuteFetchAsDbaRequest) (*tabletmanagerdata.ExecuteFetchAsDbaResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ExecuteFetchAsDba not implemented") +} +func (*UnimplementedTabletManagerServer) ExecuteFetchAsAllPrivs(ctx context.Context, req *tabletmanagerdata.ExecuteFetchAsAllPrivsRequest) (*tabletmanagerdata.ExecuteFetchAsAllPrivsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ExecuteFetchAsAllPrivs not implemented") +} +func (*UnimplementedTabletManagerServer) ExecuteFetchAsApp(ctx context.Context, req *tabletmanagerdata.ExecuteFetchAsAppRequest) (*tabletmanagerdata.ExecuteFetchAsAppResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ExecuteFetchAsApp not implemented") +} +func (*UnimplementedTabletManagerServer) SlaveStatus(ctx context.Context, req *tabletmanagerdata.SlaveStatusRequest) (*tabletmanagerdata.SlaveStatusResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method SlaveStatus not implemented") +} +func (*UnimplementedTabletManagerServer) MasterPosition(ctx context.Context, req *tabletmanagerdata.MasterPositionRequest) (*tabletmanagerdata.MasterPositionResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method MasterPosition not implemented") +} +func (*UnimplementedTabletManagerServer) WaitForPosition(ctx context.Context, req *tabletmanagerdata.WaitForPositionRequest) (*tabletmanagerdata.WaitForPositionResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method WaitForPosition not implemented") +} +func (*UnimplementedTabletManagerServer) StopSlave(ctx context.Context, req *tabletmanagerdata.StopSlaveRequest) (*tabletmanagerdata.StopSlaveResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method StopSlave not implemented") +} +func (*UnimplementedTabletManagerServer) StopSlaveMinimum(ctx context.Context, req *tabletmanagerdata.StopSlaveMinimumRequest) (*tabletmanagerdata.StopSlaveMinimumResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method StopSlaveMinimum not implemented") +} +func (*UnimplementedTabletManagerServer) StartSlave(ctx context.Context, req *tabletmanagerdata.StartSlaveRequest) (*tabletmanagerdata.StartSlaveResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method StartSlave not implemented") +} +func (*UnimplementedTabletManagerServer) StartSlaveUntilAfter(ctx context.Context, req *tabletmanagerdata.StartSlaveUntilAfterRequest) (*tabletmanagerdata.StartSlaveUntilAfterResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method StartSlaveUntilAfter not implemented") +} +func (*UnimplementedTabletManagerServer) TabletExternallyReparented(ctx context.Context, req *tabletmanagerdata.TabletExternallyReparentedRequest) (*tabletmanagerdata.TabletExternallyReparentedResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method TabletExternallyReparented not implemented") +} +func (*UnimplementedTabletManagerServer) TabletExternallyElected(ctx context.Context, req *tabletmanagerdata.TabletExternallyElectedRequest) (*tabletmanagerdata.TabletExternallyElectedResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method TabletExternallyElected not implemented") +} +func (*UnimplementedTabletManagerServer) GetSlaves(ctx context.Context, req *tabletmanagerdata.GetSlavesRequest) (*tabletmanagerdata.GetSlavesResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetSlaves not implemented") +} +func (*UnimplementedTabletManagerServer) VReplicationExec(ctx context.Context, req *tabletmanagerdata.VReplicationExecRequest) (*tabletmanagerdata.VReplicationExecResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method VReplicationExec not implemented") +} +func (*UnimplementedTabletManagerServer) VReplicationWaitForPos(ctx context.Context, req *tabletmanagerdata.VReplicationWaitForPosRequest) (*tabletmanagerdata.VReplicationWaitForPosResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method VReplicationWaitForPos not implemented") +} +func (*UnimplementedTabletManagerServer) ResetReplication(ctx context.Context, req *tabletmanagerdata.ResetReplicationRequest) (*tabletmanagerdata.ResetReplicationResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ResetReplication not implemented") +} +func (*UnimplementedTabletManagerServer) InitMaster(ctx context.Context, req *tabletmanagerdata.InitMasterRequest) (*tabletmanagerdata.InitMasterResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method InitMaster not implemented") +} +func (*UnimplementedTabletManagerServer) PopulateReparentJournal(ctx context.Context, req *tabletmanagerdata.PopulateReparentJournalRequest) (*tabletmanagerdata.PopulateReparentJournalResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method PopulateReparentJournal not implemented") +} +func (*UnimplementedTabletManagerServer) InitSlave(ctx context.Context, req *tabletmanagerdata.InitSlaveRequest) (*tabletmanagerdata.InitSlaveResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method InitSlave not implemented") +} +func (*UnimplementedTabletManagerServer) DemoteMaster(ctx context.Context, req *tabletmanagerdata.DemoteMasterRequest) (*tabletmanagerdata.DemoteMasterResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method DemoteMaster not implemented") +} +func (*UnimplementedTabletManagerServer) UndoDemoteMaster(ctx context.Context, req *tabletmanagerdata.UndoDemoteMasterRequest) (*tabletmanagerdata.UndoDemoteMasterResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method UndoDemoteMaster not implemented") +} +func (*UnimplementedTabletManagerServer) PromoteSlaveWhenCaughtUp(ctx context.Context, req *tabletmanagerdata.PromoteSlaveWhenCaughtUpRequest) (*tabletmanagerdata.PromoteSlaveWhenCaughtUpResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method PromoteSlaveWhenCaughtUp not implemented") +} +func (*UnimplementedTabletManagerServer) SlaveWasPromoted(ctx context.Context, req *tabletmanagerdata.SlaveWasPromotedRequest) (*tabletmanagerdata.SlaveWasPromotedResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method SlaveWasPromoted not implemented") +} +func (*UnimplementedTabletManagerServer) SetMaster(ctx context.Context, req *tabletmanagerdata.SetMasterRequest) (*tabletmanagerdata.SetMasterResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method SetMaster not implemented") +} +func (*UnimplementedTabletManagerServer) SlaveWasRestarted(ctx context.Context, req *tabletmanagerdata.SlaveWasRestartedRequest) (*tabletmanagerdata.SlaveWasRestartedResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method SlaveWasRestarted not implemented") +} +func (*UnimplementedTabletManagerServer) StopReplicationAndGetStatus(ctx context.Context, req *tabletmanagerdata.StopReplicationAndGetStatusRequest) (*tabletmanagerdata.StopReplicationAndGetStatusResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method StopReplicationAndGetStatus not implemented") +} +func (*UnimplementedTabletManagerServer) PromoteSlave(ctx context.Context, req *tabletmanagerdata.PromoteSlaveRequest) (*tabletmanagerdata.PromoteSlaveResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method PromoteSlave not implemented") +} +func (*UnimplementedTabletManagerServer) Backup(req *tabletmanagerdata.BackupRequest, srv TabletManager_BackupServer) error { + return status.Errorf(codes.Unimplemented, "method Backup not implemented") +} +func (*UnimplementedTabletManagerServer) RestoreFromBackup(req *tabletmanagerdata.RestoreFromBackupRequest, srv TabletManager_RestoreFromBackupServer) error { + return status.Errorf(codes.Unimplemented, "method RestoreFromBackup not implemented") +} + func RegisterTabletManagerServer(s *grpc.Server, srv TabletManagerServer) { s.RegisterService(&_TabletManager_serviceDesc, srv) } @@ -1074,6 +1301,24 @@ func _TabletManager_MasterPosition_Handler(srv interface{}, ctx context.Context, return interceptor(ctx, in, info, handler) } +func _TabletManager_WaitForPosition_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(tabletmanagerdata.WaitForPositionRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(TabletManagerServer).WaitForPosition(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/tabletmanagerservice.TabletManager/WaitForPosition", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(TabletManagerServer).WaitForPosition(ctx, req.(*tabletmanagerdata.WaitForPositionRequest)) + } + return interceptor(ctx, in, info, handler) +} + func _TabletManager_StopSlave_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(tabletmanagerdata.StopSlaveRequest) if err := dec(in); err != nil { @@ -1582,6 +1827,10 @@ var _TabletManager_serviceDesc = grpc.ServiceDesc{ MethodName: "MasterPosition", Handler: _TabletManager_MasterPosition_Handler, }, + { + MethodName: "WaitForPosition", + Handler: _TabletManager_WaitForPosition_Handler, + }, { MethodName: "StopSlave", Handler: _TabletManager_StopSlave_Handler, @@ -1681,76 +1930,3 @@ var _TabletManager_serviceDesc = grpc.ServiceDesc{ }, Metadata: "tabletmanagerservice.proto", } - -func init() { - proto.RegisterFile("tabletmanagerservice.proto", fileDescriptor_tabletmanagerservice_0dc181478a076ccc) -} - -var fileDescriptor_tabletmanagerservice_0dc181478a076ccc = []byte{ - // 1030 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x98, 0x6d, 0x6f, 0x1b, 0x45, - 0x10, 0xc7, 0xb1, 0x04, 0x95, 0x58, 0x1e, 0xbb, 0xaa, 0x28, 0x0a, 0x12, 0x4f, 0x4d, 0x79, 0x48, - 0x51, 0xdc, 0x34, 0x94, 0xf7, 0x6e, 0x9a, 0xb4, 0x41, 0x8d, 0x30, 0x76, 0x43, 0x10, 0x48, 0x48, - 0x1b, 0x7b, 0xe2, 0x3b, 0x72, 0xde, 0x3d, 0x76, 0xf7, 0xac, 0xe6, 0x15, 0x12, 0x12, 0xaf, 0x90, - 0xf8, 0x4a, 0x7c, 0x35, 0x74, 0x0f, 0xbb, 0x37, 0x6b, 0xcf, 0xad, 0xed, 0x77, 0x91, 0xff, 0xbf, - 0x9d, 0x99, 0x9d, 0x9d, 0x99, 0xdd, 0x1c, 0xdb, 0xb1, 0xe2, 0x32, 0x03, 0x3b, 0x17, 0x52, 0xcc, - 0x40, 0x1b, 0xd0, 0x8b, 0x74, 0x02, 0xfb, 0xb9, 0x56, 0x56, 0xf1, 0x3b, 0x94, 0xb6, 0x73, 0x37, - 0xf8, 0x75, 0x2a, 0xac, 0xa8, 0xf1, 0x47, 0xff, 0xed, 0xb2, 0x77, 0x5e, 0x56, 0xda, 0x59, 0xad, - 0xf1, 0x53, 0xf6, 0xfa, 0x30, 0x95, 0x33, 0xfe, 0xf1, 0xfe, 0xea, 0x9a, 0x52, 0x18, 0xc1, 0x1f, - 0x05, 0x18, 0xbb, 0xf3, 0x49, 0xa7, 0x6e, 0x72, 0x25, 0x0d, 0x7c, 0xfe, 0x1a, 0x7f, 0xc1, 0xde, - 0x18, 0x67, 0x00, 0x39, 0xa7, 0xd8, 0x4a, 0x71, 0xc6, 0x3e, 0xed, 0x06, 0xbc, 0xb5, 0xdf, 0xd8, - 0x5b, 0xc7, 0xaf, 0x60, 0x52, 0x58, 0x78, 0xae, 0xd4, 0x35, 0xbf, 0x4f, 0x2c, 0x41, 0xba, 0xb3, - 0xfc, 0xc5, 0x3a, 0xcc, 0xdb, 0xff, 0x99, 0xbd, 0xf9, 0x0c, 0xec, 0x78, 0x92, 0xc0, 0x5c, 0xf0, - 0x7b, 0xc4, 0x32, 0xaf, 0x3a, 0xdb, 0xbb, 0x71, 0xc8, 0x5b, 0x9e, 0xb1, 0x77, 0x9f, 0x81, 0x1d, - 0x82, 0x9e, 0xa7, 0xc6, 0xa4, 0x4a, 0x1a, 0xfe, 0x15, 0xbd, 0x12, 0x21, 0xce, 0xc7, 0xd7, 0x1b, - 0x90, 0x38, 0x45, 0x63, 0xb0, 0x23, 0x10, 0xd3, 0x1f, 0x64, 0x76, 0x43, 0xa6, 0x08, 0xe9, 0xb1, - 0x14, 0x05, 0x98, 0xb7, 0x2f, 0xd8, 0xdb, 0x8d, 0x70, 0xa1, 0x53, 0x0b, 0x3c, 0xb2, 0xb2, 0x02, - 0x9c, 0x87, 0x2f, 0xd7, 0x72, 0xde, 0xc5, 0xaf, 0x8c, 0x1d, 0x25, 0x42, 0xce, 0xe0, 0xe5, 0x4d, - 0x0e, 0x9c, 0xca, 0x70, 0x2b, 0x3b, 0xf3, 0xf7, 0xd7, 0x50, 0x38, 0xfe, 0x11, 0x5c, 0x69, 0x30, - 0xc9, 0xd8, 0x8a, 0x8e, 0xf8, 0x31, 0x10, 0x8b, 0x3f, 0xe4, 0xf0, 0x59, 0x8f, 0x0a, 0xf9, 0x1c, - 0x44, 0x66, 0x93, 0xa3, 0x04, 0x26, 0xd7, 0xe4, 0x59, 0x87, 0x48, 0xec, 0xac, 0x97, 0x49, 0xef, - 0x28, 0x67, 0xb7, 0x4f, 0x67, 0x52, 0x69, 0xa8, 0xe5, 0x63, 0xad, 0x95, 0xe6, 0x0f, 0x08, 0x0b, - 0x2b, 0x94, 0x73, 0xf7, 0xcd, 0x66, 0x70, 0x98, 0xbd, 0x4c, 0x89, 0x69, 0xd3, 0x23, 0x74, 0xf6, - 0x5a, 0x20, 0x9e, 0x3d, 0xcc, 0x79, 0x17, 0xbf, 0xb3, 0xf7, 0x86, 0x1a, 0xae, 0xb2, 0x74, 0x96, - 0xb8, 0x4e, 0xa4, 0x92, 0xb2, 0xc4, 0x38, 0x47, 0x7b, 0x9b, 0xa0, 0xb8, 0x59, 0x06, 0x79, 0x9e, - 0xdd, 0x34, 0x7e, 0xa8, 0x22, 0x42, 0x7a, 0xac, 0x59, 0x02, 0x0c, 0x57, 0xf2, 0x0b, 0x35, 0xb9, - 0xae, 0xa6, 0xab, 0x21, 0x2b, 0xb9, 0x95, 0x63, 0x95, 0x8c, 0x29, 0x7c, 0x16, 0xe7, 0x32, 0x6b, - 0xcd, 0x53, 0x61, 0x61, 0x20, 0x76, 0x16, 0x21, 0x87, 0x0b, 0xac, 0x19, 0x94, 0x27, 0x60, 0x27, - 0xc9, 0xc0, 0x3c, 0xbd, 0x14, 0x64, 0x81, 0xad, 0x50, 0xb1, 0x02, 0x23, 0x60, 0xef, 0xf1, 0x4f, - 0xf6, 0x41, 0x28, 0x0f, 0xb2, 0x6c, 0xa8, 0xd3, 0x85, 0xe1, 0x0f, 0xd7, 0x5a, 0x72, 0xa8, 0xf3, - 0x7d, 0xb0, 0xc5, 0x8a, 0xee, 0x2d, 0x0f, 0xf2, 0x7c, 0x83, 0x2d, 0x0f, 0xf2, 0x7c, 0xf3, 0x2d, - 0x57, 0x70, 0x30, 0xb1, 0x33, 0xb1, 0x80, 0x72, 0x8c, 0x14, 0x86, 0x9e, 0xd8, 0xad, 0x1e, 0x9d, - 0xd8, 0x18, 0xc3, 0xe3, 0xe8, 0x4c, 0x18, 0x0b, 0x7a, 0xa8, 0x4c, 0x6a, 0x53, 0x25, 0xc9, 0x71, - 0x14, 0x22, 0xb1, 0x71, 0xb4, 0x4c, 0xe2, 0xdb, 0x73, 0x6c, 0x55, 0x5e, 0x45, 0x41, 0xde, 0x9e, - 0x5e, 0x8d, 0xdd, 0x9e, 0x08, 0xf2, 0x96, 0xe7, 0xec, 0x7d, 0xff, 0xf3, 0x59, 0x2a, 0xd3, 0x79, - 0x31, 0xe7, 0x7b, 0xb1, 0xb5, 0x0d, 0xe4, 0xfc, 0x3c, 0xd8, 0x88, 0xc5, 0x6d, 0x3b, 0xb6, 0x42, - 0xdb, 0x7a, 0x27, 0x74, 0x90, 0x4e, 0x8e, 0xb5, 0x2d, 0xa6, 0xbc, 0xf1, 0x1b, 0x76, 0xa7, 0xfd, - 0xfd, 0x5c, 0xda, 0x34, 0x1b, 0x5c, 0x59, 0xd0, 0x7c, 0x3f, 0x6a, 0xa0, 0x05, 0x9d, 0xc3, 0xfe, - 0xc6, 0xbc, 0x77, 0xfd, 0x4f, 0x8f, 0xed, 0xd4, 0x2f, 0xbd, 0xe3, 0x57, 0x16, 0xb4, 0x14, 0x59, - 0x79, 0xb5, 0xe7, 0x42, 0x83, 0xb4, 0x30, 0xe5, 0xdf, 0x12, 0x16, 0xbb, 0x71, 0x17, 0xc7, 0xe3, - 0x2d, 0x57, 0xf9, 0x68, 0xfe, 0xea, 0xb1, 0xbb, 0xcb, 0xe0, 0x71, 0x06, 0x93, 0x32, 0x94, 0x83, - 0x0d, 0x8c, 0x36, 0xac, 0x8b, 0xe3, 0xd1, 0x36, 0x4b, 0x96, 0x5f, 0x7c, 0x65, 0xca, 0x4c, 0xe7, - 0x8b, 0xaf, 0x52, 0xd7, 0xbd, 0xf8, 0x1a, 0x08, 0xd7, 0xec, 0x4f, 0x23, 0xc8, 0xb3, 0x74, 0x22, - 0xca, 0x3e, 0x29, 0x27, 0x00, 0x59, 0xb3, 0xcb, 0x50, 0xac, 0x66, 0x57, 0x59, 0x3c, 0x38, 0xb1, - 0x7a, 0x21, 0x52, 0x7b, 0xa2, 0xca, 0x2e, 0x25, 0x07, 0x27, 0x8d, 0xc6, 0x06, 0x67, 0xd7, 0x0a, - 0xbc, 0xdf, 0x11, 0x98, 0xf2, 0x45, 0xe7, 0x39, 0x72, 0xbf, 0xcb, 0x50, 0x6c, 0xbf, 0xab, 0x2c, - 0xee, 0xd1, 0x53, 0x99, 0xda, 0x7a, 0x18, 0x91, 0x3d, 0xda, 0xca, 0xb1, 0x1e, 0xc5, 0x54, 0x50, - 0x9a, 0x43, 0x95, 0x17, 0x59, 0xf5, 0xb0, 0xab, 0x6b, 0xf7, 0x7b, 0x55, 0x94, 0x45, 0x44, 0x96, - 0x66, 0x07, 0x1b, 0x2b, 0xcd, 0xce, 0x25, 0xb8, 0x34, 0xcb, 0xe0, 0xba, 0xc7, 0xa9, 0x57, 0x63, - 0xa5, 0x89, 0x20, 0xfc, 0x72, 0x78, 0x0a, 0x73, 0x65, 0xa1, 0xc9, 0x1e, 0x75, 0x97, 0x60, 0x20, - 0xf6, 0x72, 0x08, 0x39, 0x5c, 0x0d, 0xe7, 0x72, 0xaa, 0x02, 0x37, 0x7b, 0xe4, 0xc3, 0x23, 0x84, - 0x62, 0xd5, 0xb0, 0xca, 0x7a, 0x77, 0x7f, 0xf7, 0xd8, 0x87, 0x43, 0xad, 0x4a, 0xad, 0xda, 0xec, - 0x45, 0x02, 0xf2, 0x48, 0x14, 0xb3, 0xc4, 0x9e, 0xe7, 0x9c, 0x4c, 0x7f, 0x07, 0xec, 0xfc, 0x1f, - 0x6e, 0xb5, 0x26, 0xb8, 0xa8, 0x2a, 0x59, 0x98, 0x86, 0x9e, 0xd2, 0x17, 0xd5, 0x12, 0x14, 0xbd, - 0xa8, 0x56, 0xd8, 0xe0, 0xc6, 0x05, 0xd7, 0x03, 0xf7, 0xe8, 0xff, 0xb0, 0xc2, 0xbc, 0xee, 0xc6, - 0x21, 0xfc, 0x0c, 0x72, 0x7e, 0x47, 0x60, 0xca, 0x6b, 0x05, 0xa6, 0x3c, 0x16, 0x9d, 0xa7, 0x62, - 0xcf, 0x20, 0x02, 0xf6, 0x1e, 0xff, 0xed, 0xb1, 0x8f, 0xca, 0x3b, 0x19, 0xb5, 0xfb, 0x40, 0x4e, - 0xcb, 0xc9, 0x5a, 0xbf, 0x8b, 0x1e, 0x77, 0xdc, 0xe1, 0x1d, 0xbc, 0x0b, 0xe3, 0xbb, 0x6d, 0x97, - 0xe1, 0x2e, 0xc1, 0x27, 0x4e, 0x76, 0x09, 0x06, 0x62, 0x5d, 0x12, 0x72, 0xde, 0xc5, 0x8f, 0xec, - 0xd6, 0x13, 0x31, 0xb9, 0x2e, 0x72, 0x4e, 0x7d, 0xfd, 0xa8, 0x25, 0x67, 0xf6, 0xb3, 0x08, 0xe1, - 0x0c, 0x3e, 0xec, 0x71, 0xcd, 0x6e, 0x97, 0xd9, 0x55, 0x1a, 0x4e, 0xb4, 0x9a, 0x37, 0xd6, 0x3b, - 0x66, 0x6b, 0x48, 0xc5, 0x0e, 0x8e, 0x80, 0x5b, 0x9f, 0x4f, 0x0e, 0x7f, 0x39, 0x58, 0xa4, 0x16, - 0x8c, 0xd9, 0x4f, 0x55, 0xbf, 0xfe, 0xab, 0x3f, 0x53, 0xfd, 0x85, 0xed, 0x57, 0x5f, 0x98, 0xfa, - 0xd4, 0xf7, 0xa8, 0xcb, 0x5b, 0x95, 0x76, 0xf8, 0x7f, 0x00, 0x00, 0x00, 0xff, 0xff, 0xae, 0x75, - 0xbb, 0x5f, 0xca, 0x12, 0x00, 0x00, -} diff --git a/go/vt/proto/throttlerdata/throttlerdata.pb.go b/go/vt/proto/throttlerdata/throttlerdata.pb.go index 74788363a48..fad03c327e7 100644 --- a/go/vt/proto/throttlerdata/throttlerdata.pb.go +++ b/go/vt/proto/throttlerdata/throttlerdata.pb.go @@ -1,11 +1,14 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // source: throttlerdata.proto -package throttlerdata // import "vitess.io/vitess/go/vt/proto/throttlerdata" +package throttlerdata -import proto "github.com/golang/protobuf/proto" -import fmt "fmt" -import math "math" +import ( + fmt "fmt" + math "math" + + proto "github.com/golang/protobuf/proto" +) // Reference imports to suppress errors if they are not otherwise used. var _ = proto.Marshal @@ -16,7 +19,7 @@ var _ = math.Inf // is compatible with the proto package it is being compiled against. // A compilation error at this line likely means your copy of the // proto package needs to be updated. -const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package +const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package // MaxRatesRequest is the payload for the MaxRates RPC. type MaxRatesRequest struct { @@ -29,16 +32,17 @@ func (m *MaxRatesRequest) Reset() { *m = MaxRatesRequest{} } func (m *MaxRatesRequest) String() string { return proto.CompactTextString(m) } func (*MaxRatesRequest) ProtoMessage() {} func (*MaxRatesRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_throttlerdata_d10a8d735853021e, []int{0} + return fileDescriptor_b67db2b008a2453d, []int{0} } + func (m *MaxRatesRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_MaxRatesRequest.Unmarshal(m, b) } func (m *MaxRatesRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_MaxRatesRequest.Marshal(b, m, deterministic) } -func (dst *MaxRatesRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_MaxRatesRequest.Merge(dst, src) +func (m *MaxRatesRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_MaxRatesRequest.Merge(m, src) } func (m *MaxRatesRequest) XXX_Size() int { return xxx_messageInfo_MaxRatesRequest.Size(m) @@ -63,16 +67,17 @@ func (m *MaxRatesResponse) Reset() { *m = MaxRatesResponse{} } func (m *MaxRatesResponse) String() string { return proto.CompactTextString(m) } func (*MaxRatesResponse) ProtoMessage() {} func (*MaxRatesResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_throttlerdata_d10a8d735853021e, []int{1} + return fileDescriptor_b67db2b008a2453d, []int{1} } + func (m *MaxRatesResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_MaxRatesResponse.Unmarshal(m, b) } func (m *MaxRatesResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_MaxRatesResponse.Marshal(b, m, deterministic) } -func (dst *MaxRatesResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_MaxRatesResponse.Merge(dst, src) +func (m *MaxRatesResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_MaxRatesResponse.Merge(m, src) } func (m *MaxRatesResponse) XXX_Size() int { return xxx_messageInfo_MaxRatesResponse.Size(m) @@ -102,16 +107,17 @@ func (m *SetMaxRateRequest) Reset() { *m = SetMaxRateRequest{} } func (m *SetMaxRateRequest) String() string { return proto.CompactTextString(m) } func (*SetMaxRateRequest) ProtoMessage() {} func (*SetMaxRateRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_throttlerdata_d10a8d735853021e, []int{2} + return fileDescriptor_b67db2b008a2453d, []int{2} } + func (m *SetMaxRateRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_SetMaxRateRequest.Unmarshal(m, b) } func (m *SetMaxRateRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_SetMaxRateRequest.Marshal(b, m, deterministic) } -func (dst *SetMaxRateRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_SetMaxRateRequest.Merge(dst, src) +func (m *SetMaxRateRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_SetMaxRateRequest.Merge(m, src) } func (m *SetMaxRateRequest) XXX_Size() int { return xxx_messageInfo_SetMaxRateRequest.Size(m) @@ -142,16 +148,17 @@ func (m *SetMaxRateResponse) Reset() { *m = SetMaxRateResponse{} } func (m *SetMaxRateResponse) String() string { return proto.CompactTextString(m) } func (*SetMaxRateResponse) ProtoMessage() {} func (*SetMaxRateResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_throttlerdata_d10a8d735853021e, []int{3} + return fileDescriptor_b67db2b008a2453d, []int{3} } + func (m *SetMaxRateResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_SetMaxRateResponse.Unmarshal(m, b) } func (m *SetMaxRateResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_SetMaxRateResponse.Marshal(b, m, deterministic) } -func (dst *SetMaxRateResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_SetMaxRateResponse.Merge(dst, src) +func (m *SetMaxRateResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_SetMaxRateResponse.Merge(m, src) } func (m *SetMaxRateResponse) XXX_Size() int { return xxx_messageInfo_SetMaxRateResponse.Size(m) @@ -259,16 +266,17 @@ func (m *Configuration) Reset() { *m = Configuration{} } func (m *Configuration) String() string { return proto.CompactTextString(m) } func (*Configuration) ProtoMessage() {} func (*Configuration) Descriptor() ([]byte, []int) { - return fileDescriptor_throttlerdata_d10a8d735853021e, []int{4} + return fileDescriptor_b67db2b008a2453d, []int{4} } + func (m *Configuration) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Configuration.Unmarshal(m, b) } func (m *Configuration) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_Configuration.Marshal(b, m, deterministic) } -func (dst *Configuration) XXX_Merge(src proto.Message) { - xxx_messageInfo_Configuration.Merge(dst, src) +func (m *Configuration) XXX_Merge(src proto.Message) { + xxx_messageInfo_Configuration.Merge(m, src) } func (m *Configuration) XXX_Size() int { return xxx_messageInfo_Configuration.Size(m) @@ -391,16 +399,17 @@ func (m *GetConfigurationRequest) Reset() { *m = GetConfigurationRequest func (m *GetConfigurationRequest) String() string { return proto.CompactTextString(m) } func (*GetConfigurationRequest) ProtoMessage() {} func (*GetConfigurationRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_throttlerdata_d10a8d735853021e, []int{5} + return fileDescriptor_b67db2b008a2453d, []int{5} } + func (m *GetConfigurationRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_GetConfigurationRequest.Unmarshal(m, b) } func (m *GetConfigurationRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_GetConfigurationRequest.Marshal(b, m, deterministic) } -func (dst *GetConfigurationRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_GetConfigurationRequest.Merge(dst, src) +func (m *GetConfigurationRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_GetConfigurationRequest.Merge(m, src) } func (m *GetConfigurationRequest) XXX_Size() int { return xxx_messageInfo_GetConfigurationRequest.Size(m) @@ -432,16 +441,17 @@ func (m *GetConfigurationResponse) Reset() { *m = GetConfigurationRespon func (m *GetConfigurationResponse) String() string { return proto.CompactTextString(m) } func (*GetConfigurationResponse) ProtoMessage() {} func (*GetConfigurationResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_throttlerdata_d10a8d735853021e, []int{6} + return fileDescriptor_b67db2b008a2453d, []int{6} } + func (m *GetConfigurationResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_GetConfigurationResponse.Unmarshal(m, b) } func (m *GetConfigurationResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_GetConfigurationResponse.Marshal(b, m, deterministic) } -func (dst *GetConfigurationResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_GetConfigurationResponse.Merge(dst, src) +func (m *GetConfigurationResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_GetConfigurationResponse.Merge(m, src) } func (m *GetConfigurationResponse) XXX_Size() int { return xxx_messageInfo_GetConfigurationResponse.Size(m) @@ -478,16 +488,17 @@ func (m *UpdateConfigurationRequest) Reset() { *m = UpdateConfigurationR func (m *UpdateConfigurationRequest) String() string { return proto.CompactTextString(m) } func (*UpdateConfigurationRequest) ProtoMessage() {} func (*UpdateConfigurationRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_throttlerdata_d10a8d735853021e, []int{7} + return fileDescriptor_b67db2b008a2453d, []int{7} } + func (m *UpdateConfigurationRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_UpdateConfigurationRequest.Unmarshal(m, b) } func (m *UpdateConfigurationRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_UpdateConfigurationRequest.Marshal(b, m, deterministic) } -func (dst *UpdateConfigurationRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_UpdateConfigurationRequest.Merge(dst, src) +func (m *UpdateConfigurationRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_UpdateConfigurationRequest.Merge(m, src) } func (m *UpdateConfigurationRequest) XXX_Size() int { return xxx_messageInfo_UpdateConfigurationRequest.Size(m) @@ -532,16 +543,17 @@ func (m *UpdateConfigurationResponse) Reset() { *m = UpdateConfiguration func (m *UpdateConfigurationResponse) String() string { return proto.CompactTextString(m) } func (*UpdateConfigurationResponse) ProtoMessage() {} func (*UpdateConfigurationResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_throttlerdata_d10a8d735853021e, []int{8} + return fileDescriptor_b67db2b008a2453d, []int{8} } + func (m *UpdateConfigurationResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_UpdateConfigurationResponse.Unmarshal(m, b) } func (m *UpdateConfigurationResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_UpdateConfigurationResponse.Marshal(b, m, deterministic) } -func (dst *UpdateConfigurationResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_UpdateConfigurationResponse.Merge(dst, src) +func (m *UpdateConfigurationResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_UpdateConfigurationResponse.Merge(m, src) } func (m *UpdateConfigurationResponse) XXX_Size() int { return xxx_messageInfo_UpdateConfigurationResponse.Size(m) @@ -573,16 +585,17 @@ func (m *ResetConfigurationRequest) Reset() { *m = ResetConfigurationReq func (m *ResetConfigurationRequest) String() string { return proto.CompactTextString(m) } func (*ResetConfigurationRequest) ProtoMessage() {} func (*ResetConfigurationRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_throttlerdata_d10a8d735853021e, []int{9} + return fileDescriptor_b67db2b008a2453d, []int{9} } + func (m *ResetConfigurationRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ResetConfigurationRequest.Unmarshal(m, b) } func (m *ResetConfigurationRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_ResetConfigurationRequest.Marshal(b, m, deterministic) } -func (dst *ResetConfigurationRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_ResetConfigurationRequest.Merge(dst, src) +func (m *ResetConfigurationRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_ResetConfigurationRequest.Merge(m, src) } func (m *ResetConfigurationRequest) XXX_Size() int { return xxx_messageInfo_ResetConfigurationRequest.Size(m) @@ -613,16 +626,17 @@ func (m *ResetConfigurationResponse) Reset() { *m = ResetConfigurationRe func (m *ResetConfigurationResponse) String() string { return proto.CompactTextString(m) } func (*ResetConfigurationResponse) ProtoMessage() {} func (*ResetConfigurationResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_throttlerdata_d10a8d735853021e, []int{10} + return fileDescriptor_b67db2b008a2453d, []int{10} } + func (m *ResetConfigurationResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ResetConfigurationResponse.Unmarshal(m, b) } func (m *ResetConfigurationResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_ResetConfigurationResponse.Marshal(b, m, deterministic) } -func (dst *ResetConfigurationResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_ResetConfigurationResponse.Merge(dst, src) +func (m *ResetConfigurationResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_ResetConfigurationResponse.Merge(m, src) } func (m *ResetConfigurationResponse) XXX_Size() int { return xxx_messageInfo_ResetConfigurationResponse.Size(m) @@ -656,9 +670,9 @@ func init() { proto.RegisterType((*ResetConfigurationResponse)(nil), "throttlerdata.ResetConfigurationResponse") } -func init() { proto.RegisterFile("throttlerdata.proto", fileDescriptor_throttlerdata_d10a8d735853021e) } +func init() { proto.RegisterFile("throttlerdata.proto", fileDescriptor_b67db2b008a2453d) } -var fileDescriptor_throttlerdata_d10a8d735853021e = []byte{ +var fileDescriptor_b67db2b008a2453d = []byte{ // 734 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x55, 0x5f, 0x4f, 0x03, 0x45, 0x10, 0xcf, 0x51, 0x8a, 0x30, 0xa5, 0x40, 0x17, 0x84, 0xa3, 0x18, 0x53, 0x2f, 0x31, 0x36, 0x8d, diff --git a/go/vt/proto/throttlerservice/throttlerservice.pb.go b/go/vt/proto/throttlerservice/throttlerservice.pb.go index 988d592e406..a9270a8df55 100644 --- a/go/vt/proto/throttlerservice/throttlerservice.pb.go +++ b/go/vt/proto/throttlerservice/throttlerservice.pb.go @@ -1,16 +1,18 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // source: throttlerservice.proto -package throttlerservice // import "vitess.io/vitess/go/vt/proto/throttlerservice" - -import proto "github.com/golang/protobuf/proto" -import fmt "fmt" -import math "math" -import throttlerdata "vitess.io/vitess/go/vt/proto/throttlerdata" +package throttlerservice import ( - context "golang.org/x/net/context" + context "context" + fmt "fmt" + math "math" + + proto "github.com/golang/protobuf/proto" grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + throttlerdata "vitess.io/vitess/go/vt/proto/throttlerdata" ) // Reference imports to suppress errors if they are not otherwise used. @@ -22,7 +24,29 @@ var _ = math.Inf // is compatible with the proto package it is being compiled against. // A compilation error at this line likely means your copy of the // proto package needs to be updated. -const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package +const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package + +func init() { proto.RegisterFile("throttlerservice.proto", fileDescriptor_33af55db6d07f810) } + +var fileDescriptor_33af55db6d07f810 = []byte{ + // 241 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x92, 0x3d, 0x4b, 0xc4, 0x40, + 0x10, 0x86, 0x05, 0x41, 0x74, 0xaa, 0x63, 0x0f, 0x2c, 0xae, 0xf0, 0xab, 0x50, 0x4f, 0x30, 0x0b, + 0xfa, 0x0f, 0xb4, 0xb0, 0xba, 0x26, 0xa7, 0x8d, 0xdd, 0xea, 0x8d, 0x71, 0x51, 0x76, 0xe2, 0xce, + 0x24, 0xf8, 0xbf, 0xfd, 0x03, 0x42, 0xe2, 0xae, 0x64, 0xfc, 0xb8, 0x74, 0xe1, 0x7d, 0x9f, 0x7d, + 0x1f, 0x02, 0x03, 0xbb, 0xf2, 0x1c, 0x49, 0xe4, 0x15, 0x23, 0x63, 0x6c, 0xfd, 0x23, 0x16, 0x75, + 0x24, 0x21, 0x33, 0xd1, 0xf9, 0x6c, 0x9a, 0x93, 0x95, 0x13, 0xd7, 0x63, 0x17, 0x1f, 0x9b, 0xb0, + 0x73, 0x9b, 0x72, 0xb3, 0x80, 0xed, 0x85, 0x7b, 0x2f, 0x9d, 0x20, 0x9b, 0xbd, 0x62, 0xc8, 0xa7, + 0xa2, 0xc4, 0xb7, 0x06, 0x59, 0x66, 0xfb, 0x7f, 0xf6, 0x5c, 0x53, 0x60, 0x3c, 0xda, 0x30, 0x4b, + 0x80, 0x25, 0xca, 0x57, 0x61, 0x0e, 0xd4, 0x83, 0xef, 0x2a, 0x4d, 0x1e, 0xfe, 0x43, 0xe4, 0x51, + 0x84, 0xc9, 0x0d, 0xca, 0x35, 0x85, 0x27, 0x5f, 0x35, 0xd1, 0x89, 0xa7, 0x60, 0x8e, 0xd5, 0x43, + 0x0d, 0x24, 0xc1, 0xc9, 0x5a, 0x2e, 0x6b, 0x02, 0x4c, 0xef, 0xea, 0x95, 0x13, 0x1c, 0x9a, 0xe6, + 0x6a, 0xe1, 0x17, 0x26, 0xc9, 0xce, 0xc6, 0xa0, 0xd9, 0xf7, 0x02, 0xa6, 0x44, 0xd6, 0x3f, 0x76, + 0xaa, 0x36, 0x7e, 0x22, 0xc9, 0x36, 0x1f, 0x41, 0x26, 0xd9, 0x95, 0xbd, 0x3f, 0x6f, 0xbd, 0x20, + 0x73, 0xe1, 0xc9, 0xf6, 0x5f, 0xb6, 0x22, 0xdb, 0x8a, 0xed, 0xae, 0xc2, 0xea, 0xdb, 0x79, 0xd8, + 0xea, 0xf2, 0xcb, 0xcf, 0x00, 0x00, 0x00, 0xff, 0xff, 0x49, 0x64, 0xc0, 0xd9, 0x6e, 0x02, 0x00, + 0x00, +} // Reference imports to suppress errors if they are not otherwise used. var _ context.Context @@ -131,6 +155,26 @@ type ThrottlerServer interface { ResetConfiguration(context.Context, *throttlerdata.ResetConfigurationRequest) (*throttlerdata.ResetConfigurationResponse, error) } +// UnimplementedThrottlerServer can be embedded to have forward compatible implementations. +type UnimplementedThrottlerServer struct { +} + +func (*UnimplementedThrottlerServer) MaxRates(ctx context.Context, req *throttlerdata.MaxRatesRequest) (*throttlerdata.MaxRatesResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method MaxRates not implemented") +} +func (*UnimplementedThrottlerServer) SetMaxRate(ctx context.Context, req *throttlerdata.SetMaxRateRequest) (*throttlerdata.SetMaxRateResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method SetMaxRate not implemented") +} +func (*UnimplementedThrottlerServer) GetConfiguration(ctx context.Context, req *throttlerdata.GetConfigurationRequest) (*throttlerdata.GetConfigurationResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetConfiguration not implemented") +} +func (*UnimplementedThrottlerServer) UpdateConfiguration(ctx context.Context, req *throttlerdata.UpdateConfigurationRequest) (*throttlerdata.UpdateConfigurationResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method UpdateConfiguration not implemented") +} +func (*UnimplementedThrottlerServer) ResetConfiguration(ctx context.Context, req *throttlerdata.ResetConfigurationRequest) (*throttlerdata.ResetConfigurationResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ResetConfiguration not implemented") +} + func RegisterThrottlerServer(s *grpc.Server, srv ThrottlerServer) { s.RegisterService(&_Throttler_serviceDesc, srv) } @@ -253,27 +297,3 @@ var _Throttler_serviceDesc = grpc.ServiceDesc{ Streams: []grpc.StreamDesc{}, Metadata: "throttlerservice.proto", } - -func init() { - proto.RegisterFile("throttlerservice.proto", fileDescriptor_throttlerservice_8b1d9f2a5de89835) -} - -var fileDescriptor_throttlerservice_8b1d9f2a5de89835 = []byte{ - // 241 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x92, 0x3d, 0x4b, 0xc4, 0x40, - 0x10, 0x86, 0x05, 0x41, 0x74, 0xaa, 0x63, 0x0f, 0x2c, 0xae, 0xf0, 0xab, 0x50, 0x4f, 0x30, 0x0b, - 0xfa, 0x0f, 0xb4, 0xb0, 0xba, 0x26, 0xa7, 0x8d, 0xdd, 0xea, 0x8d, 0x71, 0x51, 0x76, 0xe2, 0xce, - 0x24, 0xf8, 0xbf, 0xfd, 0x03, 0x42, 0xe2, 0xae, 0x64, 0xfc, 0xb8, 0x74, 0xe1, 0x7d, 0x9f, 0x7d, - 0x1f, 0x02, 0x03, 0xbb, 0xf2, 0x1c, 0x49, 0xe4, 0x15, 0x23, 0x63, 0x6c, 0xfd, 0x23, 0x16, 0x75, - 0x24, 0x21, 0x33, 0xd1, 0xf9, 0x6c, 0x9a, 0x93, 0x95, 0x13, 0xd7, 0x63, 0x17, 0x1f, 0x9b, 0xb0, - 0x73, 0x9b, 0x72, 0xb3, 0x80, 0xed, 0x85, 0x7b, 0x2f, 0x9d, 0x20, 0x9b, 0xbd, 0x62, 0xc8, 0xa7, - 0xa2, 0xc4, 0xb7, 0x06, 0x59, 0x66, 0xfb, 0x7f, 0xf6, 0x5c, 0x53, 0x60, 0x3c, 0xda, 0x30, 0x4b, - 0x80, 0x25, 0xca, 0x57, 0x61, 0x0e, 0xd4, 0x83, 0xef, 0x2a, 0x4d, 0x1e, 0xfe, 0x43, 0xe4, 0x51, - 0x84, 0xc9, 0x0d, 0xca, 0x35, 0x85, 0x27, 0x5f, 0x35, 0xd1, 0x89, 0xa7, 0x60, 0x8e, 0xd5, 0x43, - 0x0d, 0x24, 0xc1, 0xc9, 0x5a, 0x2e, 0x6b, 0x02, 0x4c, 0xef, 0xea, 0x95, 0x13, 0x1c, 0x9a, 0xe6, - 0x6a, 0xe1, 0x17, 0x26, 0xc9, 0xce, 0xc6, 0xa0, 0xd9, 0xf7, 0x02, 0xa6, 0x44, 0xd6, 0x3f, 0x76, - 0xaa, 0x36, 0x7e, 0x22, 0xc9, 0x36, 0x1f, 0x41, 0x26, 0xd9, 0x95, 0xbd, 0x3f, 0x6f, 0xbd, 0x20, - 0x73, 0xe1, 0xc9, 0xf6, 0x5f, 0xb6, 0x22, 0xdb, 0x8a, 0xed, 0xae, 0xc2, 0xea, 0xdb, 0x79, 0xd8, - 0xea, 0xf2, 0xcb, 0xcf, 0x00, 0x00, 0x00, 0xff, 0xff, 0x49, 0x64, 0xc0, 0xd9, 0x6e, 0x02, 0x00, - 0x00, -} diff --git a/go/vt/proto/topodata/topodata.pb.go b/go/vt/proto/topodata/topodata.pb.go index 9d59160d863..b5a704f817b 100644 --- a/go/vt/proto/topodata/topodata.pb.go +++ b/go/vt/proto/topodata/topodata.pb.go @@ -1,11 +1,15 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // source: topodata.proto -package topodata // import "vitess.io/vitess/go/vt/proto/topodata" +package topodata -import proto "github.com/golang/protobuf/proto" -import fmt "fmt" -import math "math" +import ( + fmt "fmt" + math "math" + + proto "github.com/golang/protobuf/proto" + vttime "vitess.io/vitess/go/vt/proto/vttime" +) // Reference imports to suppress errors if they are not otherwise used. var _ = proto.Marshal @@ -16,7 +20,35 @@ var _ = math.Inf // is compatible with the proto package it is being compiled against. // A compilation error at this line likely means your copy of the // proto package needs to be updated. -const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package +const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package + +// KeyspaceType describes the type of the keyspace +type KeyspaceType int32 + +const ( + // NORMAL is the default value + KeyspaceType_NORMAL KeyspaceType = 0 + // SNAPSHOT is when we are creating a snapshot keyspace + KeyspaceType_SNAPSHOT KeyspaceType = 1 +) + +var KeyspaceType_name = map[int32]string{ + 0: "NORMAL", + 1: "SNAPSHOT", +} + +var KeyspaceType_value = map[string]int32{ + "NORMAL": 0, + "SNAPSHOT": 1, +} + +func (x KeyspaceType) String() string { + return proto.EnumName(KeyspaceType_name, int32(x)) +} + +func (KeyspaceType) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_52c350cb619f972e, []int{0} +} // KeyspaceIdType describes the type of the sharding key for a // range-based sharded keyspace. @@ -38,6 +70,7 @@ var KeyspaceIdType_name = map[int32]string{ 1: "UINT64", 2: "BYTES", } + var KeyspaceIdType_value = map[string]int32{ "UNSET": 0, "UINT64": 1, @@ -47,8 +80,9 @@ var KeyspaceIdType_value = map[string]int32{ func (x KeyspaceIdType) String() string { return proto.EnumName(KeyspaceIdType_name, int32(x)) } + func (KeyspaceIdType) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_topodata_5ff7209b363fe950, []int{0} + return fileDescriptor_52c350cb619f972e, []int{1} } // TabletType represents the type of a given tablet. @@ -100,6 +134,7 @@ var TabletType_name = map[int32]string{ 7: "RESTORE", 8: "DRAINED", } + var TabletType_value = map[string]int32{ "UNKNOWN": 0, "MASTER": 1, @@ -116,8 +151,9 @@ var TabletType_value = map[string]int32{ func (x TabletType) String() string { return proto.EnumName(TabletType_name, int32(x)) } + func (TabletType) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_topodata_5ff7209b363fe950, []int{1} + return fileDescriptor_52c350cb619f972e, []int{2} } // KeyRange describes a range of sharding keys, when range-based @@ -134,16 +170,17 @@ func (m *KeyRange) Reset() { *m = KeyRange{} } func (m *KeyRange) String() string { return proto.CompactTextString(m) } func (*KeyRange) ProtoMessage() {} func (*KeyRange) Descriptor() ([]byte, []int) { - return fileDescriptor_topodata_5ff7209b363fe950, []int{0} + return fileDescriptor_52c350cb619f972e, []int{0} } + func (m *KeyRange) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_KeyRange.Unmarshal(m, b) } func (m *KeyRange) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_KeyRange.Marshal(b, m, deterministic) } -func (dst *KeyRange) XXX_Merge(src proto.Message) { - xxx_messageInfo_KeyRange.Merge(dst, src) +func (m *KeyRange) XXX_Merge(src proto.Message) { + xxx_messageInfo_KeyRange.Merge(m, src) } func (m *KeyRange) XXX_Size() int { return xxx_messageInfo_KeyRange.Size(m) @@ -184,16 +221,17 @@ func (m *TabletAlias) Reset() { *m = TabletAlias{} } func (m *TabletAlias) String() string { return proto.CompactTextString(m) } func (*TabletAlias) ProtoMessage() {} func (*TabletAlias) Descriptor() ([]byte, []int) { - return fileDescriptor_topodata_5ff7209b363fe950, []int{1} + return fileDescriptor_52c350cb619f972e, []int{1} } + func (m *TabletAlias) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_TabletAlias.Unmarshal(m, b) } func (m *TabletAlias) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_TabletAlias.Marshal(b, m, deterministic) } -func (dst *TabletAlias) XXX_Merge(src proto.Message) { - xxx_messageInfo_TabletAlias.Merge(dst, src) +func (m *TabletAlias) XXX_Merge(src proto.Message) { + xxx_messageInfo_TabletAlias.Merge(m, src) } func (m *TabletAlias) XXX_Size() int { return xxx_messageInfo_TabletAlias.Size(m) @@ -250,26 +288,37 @@ type Tablet struct { // MySQL port. Use topoproto.MysqlPort and topoproto.SetMysqlPort // to access this variable. The functions provide support // for legacy behavior. - MysqlPort int32 `protobuf:"varint,13,opt,name=mysql_port,json=mysqlPort,proto3" json:"mysql_port,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + MysqlPort int32 `protobuf:"varint,13,opt,name=mysql_port,json=mysqlPort,proto3" json:"mysql_port,omitempty"` + // master_term_start_time is the time (in UTC) at which the current term of + // the current tablet began as master. If this tablet is not currently the + // master, this value is ignored. + // + // A new master term begins any time an authoritative decision is communicated + // about which tablet should be the master, such as via Vitess + // replication-management commands like PlannedReparentShard, + // EmergencyReparentShard, and TabletExternallyReparented. + // + MasterTermStartTime *vttime.Time `protobuf:"bytes,14,opt,name=master_term_start_time,json=masterTermStartTime,proto3" json:"master_term_start_time,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *Tablet) Reset() { *m = Tablet{} } func (m *Tablet) String() string { return proto.CompactTextString(m) } func (*Tablet) ProtoMessage() {} func (*Tablet) Descriptor() ([]byte, []int) { - return fileDescriptor_topodata_5ff7209b363fe950, []int{2} + return fileDescriptor_52c350cb619f972e, []int{2} } + func (m *Tablet) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Tablet.Unmarshal(m, b) } func (m *Tablet) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_Tablet.Marshal(b, m, deterministic) } -func (dst *Tablet) XXX_Merge(src proto.Message) { - xxx_messageInfo_Tablet.Merge(dst, src) +func (m *Tablet) XXX_Merge(src proto.Message) { + xxx_messageInfo_Tablet.Merge(m, src) } func (m *Tablet) XXX_Size() int { return xxx_messageInfo_Tablet.Size(m) @@ -357,14 +406,36 @@ func (m *Tablet) GetMysqlPort() int32 { return 0 } +func (m *Tablet) GetMasterTermStartTime() *vttime.Time { + if m != nil { + return m.MasterTermStartTime + } + return nil +} + // A Shard contains data about a subset of the data whithin a keyspace. type Shard struct { + // master_alias is the tablet alias of the master for the shard. + // If it is unset, then there is no master in this shard yet. // No lock is necessary to update this field, when for instance // TabletExternallyReparented updates this. However, we lock the // shard for reparenting operations (InitShardMaster, // PlannedReparentShard,EmergencyReparentShard), to guarantee // exclusive operation. MasterAlias *TabletAlias `protobuf:"bytes,1,opt,name=master_alias,json=masterAlias,proto3" json:"master_alias,omitempty"` + // master_term_start_time is the time (in UTC) at which the current term of + // the master specified in master_alias began. + // + // A new master term begins any time an authoritative decision is communicated + // about which tablet should be the master, such as via Vitess + // replication-management commands like PlannedReparentShard, + // EmergencyReparentShard, and TabletExternallyReparented. + // + // The master_alias should only ever be changed if the new master's term began + // at a later time than this. Note that a new term can start for the tablet + // that is already the master. In that case, the master_term_start_time would + // be increased without changing the master_alias. + MasterTermStartTime *vttime.Time `protobuf:"bytes,8,opt,name=master_term_start_time,json=masterTermStartTime,proto3" json:"master_term_start_time,omitempty"` // key_range is the KeyRange for this shard. It can be unset if: // - we are not using range-based sharding in this shard. // - the shard covers the entire keyrange. @@ -395,16 +466,17 @@ func (m *Shard) Reset() { *m = Shard{} } func (m *Shard) String() string { return proto.CompactTextString(m) } func (*Shard) ProtoMessage() {} func (*Shard) Descriptor() ([]byte, []int) { - return fileDescriptor_topodata_5ff7209b363fe950, []int{3} + return fileDescriptor_52c350cb619f972e, []int{3} } + func (m *Shard) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Shard.Unmarshal(m, b) } func (m *Shard) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_Shard.Marshal(b, m, deterministic) } -func (dst *Shard) XXX_Merge(src proto.Message) { - xxx_messageInfo_Shard.Merge(dst, src) +func (m *Shard) XXX_Merge(src proto.Message) { + xxx_messageInfo_Shard.Merge(m, src) } func (m *Shard) XXX_Size() int { return xxx_messageInfo_Shard.Size(m) @@ -422,6 +494,13 @@ func (m *Shard) GetMasterAlias() *TabletAlias { return nil } +func (m *Shard) GetMasterTermStartTime() *vttime.Time { + if m != nil { + return m.MasterTermStartTime + } + return nil +} + func (m *Shard) GetKeyRange() *KeyRange { if m != nil { return m.KeyRange @@ -470,16 +549,17 @@ func (m *Shard_ServedType) Reset() { *m = Shard_ServedType{} } func (m *Shard_ServedType) String() string { return proto.CompactTextString(m) } func (*Shard_ServedType) ProtoMessage() {} func (*Shard_ServedType) Descriptor() ([]byte, []int) { - return fileDescriptor_topodata_5ff7209b363fe950, []int{3, 0} + return fileDescriptor_52c350cb619f972e, []int{3, 0} } + func (m *Shard_ServedType) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Shard_ServedType.Unmarshal(m, b) } func (m *Shard_ServedType) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_Shard_ServedType.Marshal(b, m, deterministic) } -func (dst *Shard_ServedType) XXX_Merge(src proto.Message) { - xxx_messageInfo_Shard_ServedType.Merge(dst, src) +func (m *Shard_ServedType) XXX_Merge(src proto.Message) { + xxx_messageInfo_Shard_ServedType.Merge(m, src) } func (m *Shard_ServedType) XXX_Size() int { return xxx_messageInfo_Shard_ServedType.Size(m) @@ -527,16 +607,17 @@ func (m *Shard_SourceShard) Reset() { *m = Shard_SourceShard{} } func (m *Shard_SourceShard) String() string { return proto.CompactTextString(m) } func (*Shard_SourceShard) ProtoMessage() {} func (*Shard_SourceShard) Descriptor() ([]byte, []int) { - return fileDescriptor_topodata_5ff7209b363fe950, []int{3, 1} + return fileDescriptor_52c350cb619f972e, []int{3, 1} } + func (m *Shard_SourceShard) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Shard_SourceShard.Unmarshal(m, b) } func (m *Shard_SourceShard) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_Shard_SourceShard.Marshal(b, m, deterministic) } -func (dst *Shard_SourceShard) XXX_Merge(src proto.Message) { - xxx_messageInfo_Shard_SourceShard.Merge(dst, src) +func (m *Shard_SourceShard) XXX_Merge(src proto.Message) { + xxx_messageInfo_Shard_SourceShard.Merge(m, src) } func (m *Shard_SourceShard) XXX_Size() int { return xxx_messageInfo_Shard_SourceShard.Size(m) @@ -600,16 +681,17 @@ func (m *Shard_TabletControl) Reset() { *m = Shard_TabletControl{} } func (m *Shard_TabletControl) String() string { return proto.CompactTextString(m) } func (*Shard_TabletControl) ProtoMessage() {} func (*Shard_TabletControl) Descriptor() ([]byte, []int) { - return fileDescriptor_topodata_5ff7209b363fe950, []int{3, 2} + return fileDescriptor_52c350cb619f972e, []int{3, 2} } + func (m *Shard_TabletControl) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Shard_TabletControl.Unmarshal(m, b) } func (m *Shard_TabletControl) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_Shard_TabletControl.Marshal(b, m, deterministic) } -func (dst *Shard_TabletControl) XXX_Merge(src proto.Message) { - xxx_messageInfo_Shard_TabletControl.Merge(dst, src) +func (m *Shard_TabletControl) XXX_Merge(src proto.Message) { + xxx_messageInfo_Shard_TabletControl.Merge(m, src) } func (m *Shard_TabletControl) XXX_Size() int { return xxx_messageInfo_Shard_TabletControl.Size(m) @@ -658,26 +740,39 @@ type Keyspace struct { ShardingColumnType KeyspaceIdType `protobuf:"varint,2,opt,name=sharding_column_type,json=shardingColumnType,proto3,enum=topodata.KeyspaceIdType" json:"sharding_column_type,omitempty"` // ServedFrom will redirect the appropriate traffic to // another keyspace. - ServedFroms []*Keyspace_ServedFrom `protobuf:"bytes,4,rep,name=served_froms,json=servedFroms,proto3" json:"served_froms,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + ServedFroms []*Keyspace_ServedFrom `protobuf:"bytes,4,rep,name=served_froms,json=servedFroms,proto3" json:"served_froms,omitempty"` + // keyspace_type will determine how this keyspace is treated by + // vtgate / vschema. Normal keyspaces are routable by + // any query. Snapshot keyspaces are only accessible + // by explicit addresssing or by calling "use keyspace" first + KeyspaceType KeyspaceType `protobuf:"varint,5,opt,name=keyspace_type,json=keyspaceType,proto3,enum=topodata.KeyspaceType" json:"keyspace_type,omitempty"` + // base_keyspace is the base keyspace from which a snapshot + // keyspace is created. empty for normal keyspaces + BaseKeyspace string `protobuf:"bytes,6,opt,name=base_keyspace,json=baseKeyspace,proto3" json:"base_keyspace,omitempty"` + // snapshot_time (in UTC) is a property of snapshot + // keyspaces which tells us what point in time + // the snapshot is of + SnapshotTime *vttime.Time `protobuf:"bytes,7,opt,name=snapshot_time,json=snapshotTime,proto3" json:"snapshot_time,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *Keyspace) Reset() { *m = Keyspace{} } func (m *Keyspace) String() string { return proto.CompactTextString(m) } func (*Keyspace) ProtoMessage() {} func (*Keyspace) Descriptor() ([]byte, []int) { - return fileDescriptor_topodata_5ff7209b363fe950, []int{4} + return fileDescriptor_52c350cb619f972e, []int{4} } + func (m *Keyspace) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Keyspace.Unmarshal(m, b) } func (m *Keyspace) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_Keyspace.Marshal(b, m, deterministic) } -func (dst *Keyspace) XXX_Merge(src proto.Message) { - xxx_messageInfo_Keyspace.Merge(dst, src) +func (m *Keyspace) XXX_Merge(src proto.Message) { + xxx_messageInfo_Keyspace.Merge(m, src) } func (m *Keyspace) XXX_Size() int { return xxx_messageInfo_Keyspace.Size(m) @@ -709,6 +804,27 @@ func (m *Keyspace) GetServedFroms() []*Keyspace_ServedFrom { return nil } +func (m *Keyspace) GetKeyspaceType() KeyspaceType { + if m != nil { + return m.KeyspaceType + } + return KeyspaceType_NORMAL +} + +func (m *Keyspace) GetBaseKeyspace() string { + if m != nil { + return m.BaseKeyspace + } + return "" +} + +func (m *Keyspace) GetSnapshotTime() *vttime.Time { + if m != nil { + return m.SnapshotTime + } + return nil +} + // ServedFrom indicates a relationship between a TabletType and the // keyspace name that's serving it. type Keyspace_ServedFrom struct { @@ -727,16 +843,17 @@ func (m *Keyspace_ServedFrom) Reset() { *m = Keyspace_ServedFrom{} } func (m *Keyspace_ServedFrom) String() string { return proto.CompactTextString(m) } func (*Keyspace_ServedFrom) ProtoMessage() {} func (*Keyspace_ServedFrom) Descriptor() ([]byte, []int) { - return fileDescriptor_topodata_5ff7209b363fe950, []int{4, 0} + return fileDescriptor_52c350cb619f972e, []int{4, 0} } + func (m *Keyspace_ServedFrom) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Keyspace_ServedFrom.Unmarshal(m, b) } func (m *Keyspace_ServedFrom) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_Keyspace_ServedFrom.Marshal(b, m, deterministic) } -func (dst *Keyspace_ServedFrom) XXX_Merge(src proto.Message) { - xxx_messageInfo_Keyspace_ServedFrom.Merge(dst, src) +func (m *Keyspace_ServedFrom) XXX_Merge(src proto.Message) { + xxx_messageInfo_Keyspace_ServedFrom.Merge(m, src) } func (m *Keyspace_ServedFrom) XXX_Size() int { return xxx_messageInfo_Keyspace_ServedFrom.Size(m) @@ -783,16 +900,17 @@ func (m *ShardReplication) Reset() { *m = ShardReplication{} } func (m *ShardReplication) String() string { return proto.CompactTextString(m) } func (*ShardReplication) ProtoMessage() {} func (*ShardReplication) Descriptor() ([]byte, []int) { - return fileDescriptor_topodata_5ff7209b363fe950, []int{5} + return fileDescriptor_52c350cb619f972e, []int{5} } + func (m *ShardReplication) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ShardReplication.Unmarshal(m, b) } func (m *ShardReplication) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_ShardReplication.Marshal(b, m, deterministic) } -func (dst *ShardReplication) XXX_Merge(src proto.Message) { - xxx_messageInfo_ShardReplication.Merge(dst, src) +func (m *ShardReplication) XXX_Merge(src proto.Message) { + xxx_messageInfo_ShardReplication.Merge(m, src) } func (m *ShardReplication) XXX_Size() int { return xxx_messageInfo_ShardReplication.Size(m) @@ -822,16 +940,17 @@ func (m *ShardReplication_Node) Reset() { *m = ShardReplication_Node{} } func (m *ShardReplication_Node) String() string { return proto.CompactTextString(m) } func (*ShardReplication_Node) ProtoMessage() {} func (*ShardReplication_Node) Descriptor() ([]byte, []int) { - return fileDescriptor_topodata_5ff7209b363fe950, []int{5, 0} + return fileDescriptor_52c350cb619f972e, []int{5, 0} } + func (m *ShardReplication_Node) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ShardReplication_Node.Unmarshal(m, b) } func (m *ShardReplication_Node) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_ShardReplication_Node.Marshal(b, m, deterministic) } -func (dst *ShardReplication_Node) XXX_Merge(src proto.Message) { - xxx_messageInfo_ShardReplication_Node.Merge(dst, src) +func (m *ShardReplication_Node) XXX_Merge(src proto.Message) { + xxx_messageInfo_ShardReplication_Node.Merge(m, src) } func (m *ShardReplication_Node) XXX_Size() int { return xxx_messageInfo_ShardReplication_Node.Size(m) @@ -863,16 +982,17 @@ func (m *ShardReference) Reset() { *m = ShardReference{} } func (m *ShardReference) String() string { return proto.CompactTextString(m) } func (*ShardReference) ProtoMessage() {} func (*ShardReference) Descriptor() ([]byte, []int) { - return fileDescriptor_topodata_5ff7209b363fe950, []int{6} + return fileDescriptor_52c350cb619f972e, []int{6} } + func (m *ShardReference) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ShardReference.Unmarshal(m, b) } func (m *ShardReference) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_ShardReference.Marshal(b, m, deterministic) } -func (dst *ShardReference) XXX_Merge(src proto.Message) { - xxx_messageInfo_ShardReference.Merge(dst, src) +func (m *ShardReference) XXX_Merge(src proto.Message) { + xxx_messageInfo_ShardReference.Merge(m, src) } func (m *ShardReference) XXX_Size() int { return xxx_messageInfo_ShardReference.Size(m) @@ -913,16 +1033,17 @@ func (m *ShardTabletControl) Reset() { *m = ShardTabletControl{} } func (m *ShardTabletControl) String() string { return proto.CompactTextString(m) } func (*ShardTabletControl) ProtoMessage() {} func (*ShardTabletControl) Descriptor() ([]byte, []int) { - return fileDescriptor_topodata_5ff7209b363fe950, []int{7} + return fileDescriptor_52c350cb619f972e, []int{7} } + func (m *ShardTabletControl) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ShardTabletControl.Unmarshal(m, b) } func (m *ShardTabletControl) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_ShardTabletControl.Marshal(b, m, deterministic) } -func (dst *ShardTabletControl) XXX_Merge(src proto.Message) { - xxx_messageInfo_ShardTabletControl.Merge(dst, src) +func (m *ShardTabletControl) XXX_Merge(src proto.Message) { + xxx_messageInfo_ShardTabletControl.Merge(m, src) } func (m *ShardTabletControl) XXX_Size() int { return xxx_messageInfo_ShardTabletControl.Size(m) @@ -971,16 +1092,17 @@ func (m *SrvKeyspace) Reset() { *m = SrvKeyspace{} } func (m *SrvKeyspace) String() string { return proto.CompactTextString(m) } func (*SrvKeyspace) ProtoMessage() {} func (*SrvKeyspace) Descriptor() ([]byte, []int) { - return fileDescriptor_topodata_5ff7209b363fe950, []int{8} + return fileDescriptor_52c350cb619f972e, []int{8} } + func (m *SrvKeyspace) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_SrvKeyspace.Unmarshal(m, b) } func (m *SrvKeyspace) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_SrvKeyspace.Marshal(b, m, deterministic) } -func (dst *SrvKeyspace) XXX_Merge(src proto.Message) { - xxx_messageInfo_SrvKeyspace.Merge(dst, src) +func (m *SrvKeyspace) XXX_Merge(src proto.Message) { + xxx_messageInfo_SrvKeyspace.Merge(m, src) } func (m *SrvKeyspace) XXX_Size() int { return xxx_messageInfo_SrvKeyspace.Size(m) @@ -1035,16 +1157,17 @@ func (m *SrvKeyspace_KeyspacePartition) Reset() { *m = SrvKeyspace_Keysp func (m *SrvKeyspace_KeyspacePartition) String() string { return proto.CompactTextString(m) } func (*SrvKeyspace_KeyspacePartition) ProtoMessage() {} func (*SrvKeyspace_KeyspacePartition) Descriptor() ([]byte, []int) { - return fileDescriptor_topodata_5ff7209b363fe950, []int{8, 0} + return fileDescriptor_52c350cb619f972e, []int{8, 0} } + func (m *SrvKeyspace_KeyspacePartition) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_SrvKeyspace_KeyspacePartition.Unmarshal(m, b) } func (m *SrvKeyspace_KeyspacePartition) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_SrvKeyspace_KeyspacePartition.Marshal(b, m, deterministic) } -func (dst *SrvKeyspace_KeyspacePartition) XXX_Merge(src proto.Message) { - xxx_messageInfo_SrvKeyspace_KeyspacePartition.Merge(dst, src) +func (m *SrvKeyspace_KeyspacePartition) XXX_Merge(src proto.Message) { + xxx_messageInfo_SrvKeyspace_KeyspacePartition.Merge(m, src) } func (m *SrvKeyspace_KeyspacePartition) XXX_Size() int { return xxx_messageInfo_SrvKeyspace_KeyspacePartition.Size(m) @@ -1092,16 +1215,17 @@ func (m *SrvKeyspace_ServedFrom) Reset() { *m = SrvKeyspace_ServedFrom{} func (m *SrvKeyspace_ServedFrom) String() string { return proto.CompactTextString(m) } func (*SrvKeyspace_ServedFrom) ProtoMessage() {} func (*SrvKeyspace_ServedFrom) Descriptor() ([]byte, []int) { - return fileDescriptor_topodata_5ff7209b363fe950, []int{8, 1} + return fileDescriptor_52c350cb619f972e, []int{8, 1} } + func (m *SrvKeyspace_ServedFrom) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_SrvKeyspace_ServedFrom.Unmarshal(m, b) } func (m *SrvKeyspace_ServedFrom) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_SrvKeyspace_ServedFrom.Marshal(b, m, deterministic) } -func (dst *SrvKeyspace_ServedFrom) XXX_Merge(src proto.Message) { - xxx_messageInfo_SrvKeyspace_ServedFrom.Merge(dst, src) +func (m *SrvKeyspace_ServedFrom) XXX_Merge(src proto.Message) { + xxx_messageInfo_SrvKeyspace_ServedFrom.Merge(m, src) } func (m *SrvKeyspace_ServedFrom) XXX_Size() int { return xxx_messageInfo_SrvKeyspace_ServedFrom.Size(m) @@ -1147,16 +1271,17 @@ func (m *CellInfo) Reset() { *m = CellInfo{} } func (m *CellInfo) String() string { return proto.CompactTextString(m) } func (*CellInfo) ProtoMessage() {} func (*CellInfo) Descriptor() ([]byte, []int) { - return fileDescriptor_topodata_5ff7209b363fe950, []int{9} + return fileDescriptor_52c350cb619f972e, []int{9} } + func (m *CellInfo) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_CellInfo.Unmarshal(m, b) } func (m *CellInfo) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_CellInfo.Marshal(b, m, deterministic) } -func (dst *CellInfo) XXX_Merge(src proto.Message) { - xxx_messageInfo_CellInfo.Merge(dst, src) +func (m *CellInfo) XXX_Merge(src proto.Message) { + xxx_messageInfo_CellInfo.Merge(m, src) } func (m *CellInfo) XXX_Size() int { return xxx_messageInfo_CellInfo.Size(m) @@ -1194,16 +1319,17 @@ func (m *CellsAlias) Reset() { *m = CellsAlias{} } func (m *CellsAlias) String() string { return proto.CompactTextString(m) } func (*CellsAlias) ProtoMessage() {} func (*CellsAlias) Descriptor() ([]byte, []int) { - return fileDescriptor_topodata_5ff7209b363fe950, []int{10} + return fileDescriptor_52c350cb619f972e, []int{10} } + func (m *CellsAlias) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_CellsAlias.Unmarshal(m, b) } func (m *CellsAlias) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_CellsAlias.Marshal(b, m, deterministic) } -func (dst *CellsAlias) XXX_Merge(src proto.Message) { - xxx_messageInfo_CellsAlias.Merge(dst, src) +func (m *CellsAlias) XXX_Merge(src proto.Message) { + xxx_messageInfo_CellsAlias.Merge(m, src) } func (m *CellsAlias) XXX_Size() int { return xxx_messageInfo_CellsAlias.Size(m) @@ -1222,6 +1348,9 @@ func (m *CellsAlias) GetCells() []string { } func init() { + proto.RegisterEnum("topodata.KeyspaceType", KeyspaceType_name, KeyspaceType_value) + proto.RegisterEnum("topodata.KeyspaceIdType", KeyspaceIdType_name, KeyspaceIdType_value) + proto.RegisterEnum("topodata.TabletType", TabletType_name, TabletType_value) proto.RegisterType((*KeyRange)(nil), "topodata.KeyRange") proto.RegisterType((*TabletAlias)(nil), "topodata.TabletAlias") proto.RegisterType((*Tablet)(nil), "topodata.Tablet") @@ -1242,89 +1371,95 @@ func init() { proto.RegisterType((*SrvKeyspace_ServedFrom)(nil), "topodata.SrvKeyspace.ServedFrom") proto.RegisterType((*CellInfo)(nil), "topodata.CellInfo") proto.RegisterType((*CellsAlias)(nil), "topodata.CellsAlias") - proto.RegisterEnum("topodata.KeyspaceIdType", KeyspaceIdType_name, KeyspaceIdType_value) - proto.RegisterEnum("topodata.TabletType", TabletType_name, TabletType_value) } -func init() { proto.RegisterFile("topodata.proto", fileDescriptor_topodata_5ff7209b363fe950) } - -var fileDescriptor_topodata_5ff7209b363fe950 = []byte{ - // 1218 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x57, 0xe1, 0x6e, 0x1b, 0x45, - 0x10, 0xe6, 0xec, 0xb3, 0x63, 0x8f, 0x1d, 0xe7, 0xba, 0xa4, 0xd5, 0xe9, 0xa0, 0x22, 0xb2, 0x54, - 0x11, 0x15, 0xe1, 0xa0, 0xb4, 0x85, 0xa8, 0x12, 0x52, 0x5d, 0xc7, 0xa5, 0x69, 0x1a, 0xc7, 0x5a, - 0x3b, 0x82, 0xf2, 0xe7, 0x74, 0xf1, 0x6d, 0xd2, 0x53, 0xce, 0xb7, 0xee, 0xee, 0x26, 0x92, 0x79, - 0x05, 0x7e, 0x00, 0x7f, 0x79, 0x03, 0x1e, 0x81, 0x27, 0xe0, 0x39, 0xe0, 0x49, 0xd0, 0xce, 0xde, - 0xd9, 0x67, 0xbb, 0x2d, 0x29, 0xca, 0xbf, 0x99, 0xdd, 0x99, 0xb9, 0x99, 0x6f, 0xe6, 0x9b, 0xb5, - 0xa1, 0xa1, 0xf8, 0x84, 0x87, 0x81, 0x0a, 0x5a, 0x13, 0xc1, 0x15, 0x27, 0x95, 0x4c, 0x6f, 0xee, - 0x42, 0xe5, 0x90, 0x4d, 0x69, 0x90, 0x9c, 0x33, 0xb2, 0x09, 0x25, 0xa9, 0x02, 0xa1, 0x5c, 0x6b, - 0xcb, 0xda, 0xae, 0x53, 0xa3, 0x10, 0x07, 0x8a, 0x2c, 0x09, 0xdd, 0x02, 0x9e, 0x69, 0xb1, 0xf9, - 0x00, 0x6a, 0xc3, 0xe0, 0x34, 0x66, 0xaa, 0x1d, 0x47, 0x81, 0x24, 0x04, 0xec, 0x11, 0x8b, 0x63, - 0xf4, 0xaa, 0x52, 0x94, 0xb5, 0xd3, 0x65, 0x64, 0x9c, 0xd6, 0xa9, 0x16, 0x9b, 0x7f, 0xda, 0x50, - 0x36, 0x5e, 0xe4, 0x0b, 0x28, 0x05, 0xda, 0x13, 0x3d, 0x6a, 0xbb, 0xb7, 0x5b, 0xb3, 0xec, 0x72, - 0x61, 0xa9, 0xb1, 0x21, 0x1e, 0x54, 0x5e, 0x73, 0xa9, 0x92, 0x60, 0xcc, 0x30, 0x5c, 0x95, 0xce, - 0x74, 0xb2, 0x07, 0x95, 0x09, 0x17, 0xca, 0x1f, 0x07, 0x13, 0xd7, 0xde, 0x2a, 0x6e, 0xd7, 0x76, - 0xef, 0x2e, 0xc7, 0x6a, 0xf5, 0xb9, 0x50, 0x47, 0xc1, 0xa4, 0x9b, 0x28, 0x31, 0xa5, 0x6b, 0x13, - 0xa3, 0xe9, 0xa8, 0x17, 0x6c, 0x2a, 0x27, 0xc1, 0x88, 0xb9, 0x25, 0x13, 0x35, 0xd3, 0x11, 0x86, - 0xd7, 0x81, 0x08, 0xdd, 0x32, 0x5e, 0x18, 0x85, 0xec, 0x40, 0xf5, 0x82, 0x4d, 0x7d, 0xa1, 0x91, - 0x72, 0xd7, 0x30, 0x71, 0x32, 0xff, 0x58, 0x86, 0x21, 0x86, 0x31, 0x68, 0x6e, 0x83, 0xad, 0xa6, - 0x13, 0xe6, 0x56, 0xb6, 0xac, 0xed, 0xc6, 0xee, 0xe6, 0x72, 0x62, 0xc3, 0xe9, 0x84, 0x51, 0xb4, - 0x20, 0xdb, 0xe0, 0x84, 0xa7, 0xbe, 0xae, 0xc8, 0xe7, 0x57, 0x4c, 0x88, 0x28, 0x64, 0x6e, 0x15, - 0xbf, 0xdd, 0x08, 0x4f, 0x7b, 0xc1, 0x98, 0x1d, 0xa7, 0xa7, 0xa4, 0x05, 0xb6, 0x0a, 0xce, 0xa5, - 0x0b, 0x58, 0xac, 0xb7, 0x52, 0xec, 0x30, 0x38, 0x97, 0xa6, 0x52, 0xb4, 0x23, 0xf7, 0xa0, 0x31, - 0x9e, 0xca, 0x37, 0xb1, 0x3f, 0x83, 0xb0, 0x8e, 0x71, 0xd7, 0xf1, 0xf4, 0x79, 0x86, 0xe3, 0x5d, - 0x00, 0x63, 0xa6, 0xe1, 0x71, 0xd7, 0xb7, 0xac, 0xed, 0x12, 0xad, 0xe2, 0x89, 0x46, 0xcf, 0x7b, - 0x0c, 0xf5, 0x3c, 0x8a, 0xba, 0xb9, 0x17, 0x6c, 0x9a, 0xf6, 0x5b, 0x8b, 0x1a, 0xb2, 0xab, 0x20, - 0xbe, 0x34, 0x1d, 0x2a, 0x51, 0xa3, 0x3c, 0x2e, 0xec, 0x59, 0xde, 0x37, 0x50, 0x9d, 0x25, 0xf5, - 0x5f, 0x8e, 0xd5, 0x9c, 0xe3, 0x0b, 0xbb, 0x52, 0x74, 0xec, 0x17, 0x76, 0xa5, 0xe6, 0xd4, 0x9b, - 0xbf, 0x95, 0xa1, 0x34, 0xc0, 0x2e, 0xec, 0x41, 0x7d, 0x1c, 0x48, 0xc5, 0x84, 0x7f, 0x8d, 0x09, - 0xaa, 0x19, 0x53, 0x33, 0xa5, 0x0b, 0xfd, 0x2b, 0x5c, 0xa3, 0x7f, 0xdf, 0x42, 0x5d, 0x32, 0x71, - 0xc5, 0x42, 0x5f, 0x37, 0x49, 0xba, 0xc5, 0x65, 0xcc, 0x31, 0xa3, 0xd6, 0x00, 0x6d, 0xb0, 0x9b, - 0x35, 0x39, 0x93, 0x25, 0x79, 0x02, 0xeb, 0x92, 0x5f, 0x8a, 0x11, 0xf3, 0x71, 0x7e, 0x64, 0x3a, - 0xa0, 0x9f, 0xac, 0xf8, 0xa3, 0x11, 0xca, 0xb4, 0x2e, 0xe7, 0x8a, 0x24, 0xcf, 0x60, 0x43, 0x61, - 0x35, 0xfe, 0x88, 0x27, 0x4a, 0xf0, 0x58, 0xba, 0xe5, 0xe5, 0x21, 0x37, 0x31, 0x4c, 0xd1, 0x1d, - 0x63, 0x45, 0x1b, 0x2a, 0xaf, 0x4a, 0x72, 0x1f, 0x6e, 0x45, 0xd2, 0x4f, 0x61, 0xd3, 0x29, 0x46, - 0xc9, 0x39, 0x4e, 0x70, 0x85, 0x6e, 0x44, 0xf2, 0x08, 0xcf, 0x07, 0xe6, 0xd8, 0x7b, 0x05, 0x30, - 0x2f, 0x88, 0x3c, 0x82, 0x5a, 0x9a, 0x01, 0x4e, 0xb2, 0xf5, 0x9e, 0x49, 0x06, 0x35, 0x93, 0x75, - 0x53, 0xf5, 0x12, 0x90, 0x6e, 0x61, 0xab, 0xa8, 0x9b, 0x8a, 0x8a, 0xf7, 0xbb, 0x05, 0xb5, 0x5c, - 0xb1, 0xd9, 0x8a, 0xb0, 0x66, 0x2b, 0x62, 0x81, 0x94, 0x85, 0x77, 0x91, 0xb2, 0xf8, 0x4e, 0x52, - 0xda, 0xd7, 0x68, 0xea, 0x1d, 0x28, 0x63, 0xa2, 0xd2, 0x2d, 0x61, 0x6e, 0xa9, 0xe6, 0xfd, 0x61, - 0xc1, 0xfa, 0x02, 0x8a, 0x37, 0x5a, 0x3b, 0xf9, 0x12, 0xc8, 0x69, 0x1c, 0x8c, 0x2e, 0xe2, 0x48, - 0x2a, 0x3d, 0x50, 0x26, 0x05, 0x1b, 0x4d, 0x6e, 0xe5, 0x6e, 0x30, 0xa8, 0xd4, 0x59, 0x9e, 0x09, - 0xfe, 0x13, 0x4b, 0x70, 0x37, 0x55, 0x68, 0xaa, 0xcd, 0x38, 0x51, 0x72, 0xca, 0xcd, 0xbf, 0x0a, - 0xb8, 0xb9, 0x0d, 0x3a, 0x5f, 0xc1, 0x26, 0x02, 0x12, 0x25, 0xe7, 0xfe, 0x88, 0xc7, 0x97, 0xe3, - 0x04, 0xd7, 0x49, 0xca, 0x34, 0x92, 0xdd, 0x75, 0xf0, 0x4a, 0x6f, 0x14, 0xf2, 0x62, 0xd5, 0x03, - 0xeb, 0x2c, 0x60, 0x9d, 0xee, 0x02, 0x88, 0xf8, 0x8d, 0x03, 0x33, 0xe3, 0x4b, 0xb1, 0xb0, 0xe6, - 0x27, 0x33, 0xa6, 0x9c, 0x09, 0x3e, 0x96, 0xab, 0xab, 0x38, 0x8b, 0x91, 0x92, 0xe5, 0x99, 0xe0, - 0xe3, 0x8c, 0x2c, 0x5a, 0x96, 0xde, 0x65, 0x36, 0x76, 0x5a, 0xbd, 0x59, 0xe8, 0xf3, 0x43, 0x55, - 0x5c, 0x1c, 0x2a, 0x83, 0x67, 0xf3, 0x67, 0x0b, 0x1c, 0xc3, 0x3f, 0x36, 0x89, 0xa3, 0x51, 0xa0, - 0x22, 0x9e, 0x90, 0x47, 0x50, 0x4a, 0x78, 0xc8, 0xf4, 0x86, 0xd1, 0xc5, 0x7c, 0xb6, 0x44, 0xb9, - 0x9c, 0x69, 0xab, 0xc7, 0x43, 0x46, 0x8d, 0xb5, 0xf7, 0x04, 0x6c, 0xad, 0xea, 0x3d, 0x95, 0x96, - 0x70, 0x9d, 0x3d, 0xa5, 0xe6, 0x4a, 0xf3, 0x04, 0x1a, 0xe9, 0x17, 0xce, 0x98, 0x60, 0xc9, 0x88, - 0xe9, 0xf7, 0x35, 0xd7, 0x4c, 0x94, 0x3f, 0x78, 0x9b, 0x35, 0x7f, 0xb1, 0x80, 0x60, 0xdc, 0xc5, - 0x29, 0xbf, 0x89, 0xd8, 0xe4, 0x21, 0xdc, 0x79, 0x73, 0xc9, 0xc4, 0xd4, 0x2c, 0x97, 0x11, 0xf3, - 0xc3, 0x48, 0xea, 0xaf, 0x18, 0xb2, 0x56, 0xe8, 0x26, 0xde, 0x0e, 0xcc, 0xe5, 0x7e, 0x7a, 0xd7, - 0xfc, 0xc7, 0x86, 0xda, 0x40, 0x5c, 0xcd, 0x66, 0xf8, 0x3b, 0x80, 0x49, 0x20, 0x54, 0xa4, 0x31, - 0xcd, 0x60, 0xff, 0x3c, 0x07, 0xfb, 0xdc, 0x74, 0x36, 0x4f, 0xfd, 0xcc, 0x9e, 0xe6, 0x5c, 0xdf, - 0x49, 0x86, 0xc2, 0x07, 0x93, 0xa1, 0xf8, 0x3f, 0xc8, 0xd0, 0x86, 0x5a, 0x8e, 0x0c, 0x29, 0x17, - 0xb6, 0xde, 0x5e, 0x47, 0x8e, 0x0e, 0x30, 0xa7, 0x83, 0xf7, 0xb7, 0x05, 0xb7, 0x56, 0x4a, 0xd4, - 0xac, 0xc8, 0xbd, 0x47, 0xef, 0x67, 0xc5, 0xfc, 0x21, 0x22, 0x1d, 0x70, 0x30, 0x4b, 0x5f, 0x64, - 0x03, 0x65, 0x08, 0x52, 0xcb, 0xd7, 0xb5, 0x38, 0x71, 0x74, 0x43, 0x2e, 0xe8, 0x92, 0xf4, 0xe1, - 0xb6, 0x09, 0xb2, 0xfc, 0x20, 0x99, 0x47, 0xf1, 0xd3, 0xa5, 0x48, 0x8b, 0xef, 0xd1, 0xc7, 0x72, - 0xe5, 0x4c, 0x7a, 0xfe, 0x4d, 0x30, 0xfe, 0x3d, 0x0f, 0x46, 0xba, 0x25, 0x0f, 0xa1, 0xd2, 0x61, - 0x71, 0x7c, 0x90, 0x9c, 0x71, 0xfd, 0x63, 0x08, 0x71, 0x11, 0x7e, 0x10, 0x86, 0x82, 0x49, 0x99, - 0x4e, 0xfd, 0xba, 0x39, 0x6d, 0x9b, 0x43, 0x4d, 0x09, 0xc1, 0xb9, 0x4a, 0x03, 0xa2, 0x9c, 0x2e, - 0x8a, 0x26, 0x80, 0x0e, 0x26, 0xcd, 0x0f, 0x8a, 0xb7, 0xae, 0x9b, 0xfb, 0xbb, 0xd0, 0x58, 0x1c, - 0x12, 0x52, 0x85, 0xd2, 0x49, 0x6f, 0xd0, 0x1d, 0x3a, 0x1f, 0x11, 0x80, 0xf2, 0xc9, 0x41, 0x6f, - 0xf8, 0xf5, 0x43, 0xc7, 0xd2, 0xc7, 0x4f, 0x5f, 0x0d, 0xbb, 0x03, 0xa7, 0x70, 0xff, 0x57, 0x0b, - 0x60, 0x5e, 0x21, 0xa9, 0xc1, 0xda, 0x49, 0xef, 0xb0, 0x77, 0xfc, 0x7d, 0xcf, 0xb8, 0x1c, 0xb5, - 0x07, 0xc3, 0x2e, 0x75, 0x2c, 0x7d, 0x41, 0xbb, 0xfd, 0x97, 0x07, 0x9d, 0xb6, 0x53, 0xd0, 0x17, - 0x74, 0xff, 0xb8, 0xf7, 0xf2, 0x95, 0x53, 0xc4, 0x58, 0xed, 0x61, 0xe7, 0xb9, 0x11, 0x07, 0xfd, - 0x36, 0xed, 0x3a, 0x36, 0x71, 0xa0, 0xde, 0xfd, 0xa1, 0xdf, 0xa5, 0x07, 0x47, 0xdd, 0xde, 0xb0, - 0xfd, 0xd2, 0x29, 0x69, 0x9f, 0xa7, 0xed, 0xce, 0xe1, 0x49, 0xdf, 0x29, 0x9b, 0x60, 0x83, 0xe1, - 0x31, 0xed, 0x3a, 0x6b, 0x5a, 0xd9, 0xa7, 0xed, 0x83, 0x5e, 0x77, 0xdf, 0xa9, 0x78, 0x05, 0xc7, - 0x7a, 0xba, 0x07, 0x1b, 0x11, 0x6f, 0x5d, 0x45, 0x8a, 0x49, 0x69, 0xfe, 0x33, 0xfc, 0x78, 0x2f, - 0xd5, 0x22, 0xbe, 0x63, 0xa4, 0x9d, 0x73, 0xbe, 0x73, 0xa5, 0x76, 0xf0, 0x76, 0x27, 0x6b, 0xd5, - 0x69, 0x19, 0xf5, 0x07, 0xff, 0x06, 0x00, 0x00, 0xff, 0xff, 0x89, 0xf4, 0xf5, 0x28, 0x73, 0x0c, - 0x00, 0x00, +func init() { proto.RegisterFile("topodata.proto", fileDescriptor_52c350cb619f972e) } + +var fileDescriptor_52c350cb619f972e = []byte{ + // 1349 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x57, 0xcf, 0x6e, 0xdb, 0x46, + 0x13, 0x0f, 0xf5, 0xcf, 0xd4, 0x88, 0x92, 0x99, 0x8d, 0x63, 0x10, 0xfa, 0xbe, 0xa0, 0x86, 0x8a, + 0xa0, 0x82, 0x8b, 0xca, 0xad, 0x93, 0xb4, 0x46, 0x8a, 0x02, 0x51, 0x64, 0xa5, 0x71, 0x6c, 0xcb, + 0xc2, 0x4a, 0x46, 0x9b, 0x5e, 0x08, 0x5a, 0x5a, 0x3b, 0x84, 0x25, 0x52, 0xd9, 0x5d, 0x0b, 0x50, + 0x5f, 0xa1, 0x87, 0xf6, 0xdc, 0x37, 0xe8, 0xfb, 0xf4, 0xd8, 0x4b, 0xfb, 0x1c, 0x3d, 0x14, 0x3b, + 0x4b, 0x52, 0x94, 0x14, 0xa7, 0x4e, 0xe1, 0xdb, 0xcc, 0xec, 0xcc, 0x70, 0xe6, 0xb7, 0xbf, 0x99, + 0x95, 0xa0, 0x22, 0xc3, 0x49, 0x38, 0xf4, 0xa4, 0xd7, 0x98, 0xf0, 0x50, 0x86, 0xc4, 0x8c, 0xf5, + 0x2a, 0x48, 0x7f, 0xcc, 0xb4, 0xb5, 0xb6, 0x0b, 0xe6, 0x21, 0x9b, 0x51, 0x2f, 0xb8, 0x60, 0x64, + 0x03, 0xf2, 0x42, 0x7a, 0x5c, 0x3a, 0xc6, 0x96, 0x51, 0xb7, 0xa8, 0x56, 0x88, 0x0d, 0x59, 0x16, + 0x0c, 0x9d, 0x0c, 0xda, 0x94, 0x58, 0x7b, 0x04, 0xa5, 0xbe, 0x77, 0x36, 0x62, 0xb2, 0x39, 0xf2, + 0x3d, 0x41, 0x08, 0xe4, 0x06, 0x6c, 0x34, 0xc2, 0xa8, 0x22, 0x45, 0x59, 0x05, 0x5d, 0xf9, 0x3a, + 0xa8, 0x4c, 0x95, 0x58, 0xfb, 0x3b, 0x07, 0x05, 0x1d, 0x45, 0x3e, 0x85, 0xbc, 0xa7, 0x22, 0x31, + 0xa2, 0xb4, 0x7b, 0xbf, 0x91, 0x54, 0x9a, 0x4a, 0x4b, 0xb5, 0x0f, 0xa9, 0x82, 0xf9, 0x26, 0x14, + 0x32, 0xf0, 0xc6, 0x0c, 0xd3, 0x15, 0x69, 0xa2, 0x93, 0x3d, 0x30, 0x27, 0x21, 0x97, 0xee, 0xd8, + 0x9b, 0x38, 0xb9, 0xad, 0x6c, 0xbd, 0xb4, 0xfb, 0x60, 0x39, 0x57, 0xa3, 0x1b, 0x72, 0x79, 0xec, + 0x4d, 0xda, 0x81, 0xe4, 0x33, 0xba, 0x36, 0xd1, 0x9a, 0xca, 0x7a, 0xc9, 0x66, 0x62, 0xe2, 0x0d, + 0x98, 0x93, 0xd7, 0x59, 0x63, 0x1d, 0x61, 0x78, 0xe3, 0xf1, 0xa1, 0x53, 0xc0, 0x03, 0xad, 0x90, + 0x1d, 0x28, 0x5e, 0xb2, 0x99, 0xcb, 0x15, 0x52, 0xce, 0x1a, 0x16, 0x4e, 0xe6, 0x1f, 0x8b, 0x31, + 0xc4, 0x34, 0x1a, 0xcd, 0x3a, 0xe4, 0xe4, 0x6c, 0xc2, 0x1c, 0x73, 0xcb, 0xa8, 0x57, 0x76, 0x37, + 0x96, 0x0b, 0xeb, 0xcf, 0x26, 0x8c, 0xa2, 0x07, 0xa9, 0x83, 0x3d, 0x3c, 0x73, 0x55, 0x47, 0x6e, + 0x38, 0x65, 0x9c, 0xfb, 0x43, 0xe6, 0x14, 0xf1, 0xdb, 0x95, 0xe1, 0x59, 0xc7, 0x1b, 0xb3, 0x93, + 0xc8, 0x4a, 0x1a, 0x90, 0x93, 0xde, 0x85, 0x70, 0x00, 0x9b, 0xad, 0xae, 0x34, 0xdb, 0xf7, 0x2e, + 0x84, 0xee, 0x14, 0xfd, 0xc8, 0x43, 0xa8, 0x8c, 0x67, 0xe2, 0xed, 0xc8, 0x4d, 0x20, 0xb4, 0x30, + 0x6f, 0x19, 0xad, 0x2f, 0x63, 0x1c, 0x1f, 0x00, 0x68, 0x37, 0x05, 0x8f, 0x53, 0xde, 0x32, 0xea, + 0x79, 0x5a, 0x44, 0x8b, 0x42, 0x8f, 0x34, 0x61, 0x73, 0xec, 0x09, 0xc9, 0xb8, 0x2b, 0x19, 0x1f, + 0xbb, 0x48, 0x0b, 0x57, 0x71, 0xc8, 0xa9, 0x20, 0x0e, 0x56, 0x63, 0x2a, 0x91, 0x52, 0x7d, 0x7f, + 0xcc, 0xe8, 0x3d, 0xed, 0xdb, 0x67, 0x7c, 0xdc, 0x53, 0x9e, 0xca, 0x58, 0x7d, 0x0a, 0x56, 0xfa, + 0x22, 0x14, 0x3f, 0x2e, 0xd9, 0x2c, 0xa2, 0x8c, 0x12, 0x15, 0xea, 0x53, 0x6f, 0x74, 0xa5, 0x2f, + 0x39, 0x4f, 0xb5, 0xf2, 0x34, 0xb3, 0x67, 0x54, 0xbf, 0x82, 0x62, 0xd2, 0xd7, 0xbf, 0x05, 0x16, + 0x53, 0x81, 0xaf, 0x72, 0x66, 0xd6, 0xce, 0xbd, 0xca, 0x99, 0x25, 0xdb, 0xaa, 0xfd, 0x5e, 0x80, + 0x7c, 0x0f, 0x2f, 0x72, 0x0f, 0xac, 0xa8, 0x9b, 0x1b, 0x90, 0xb0, 0xa4, 0x5d, 0x35, 0xd1, 0xaf, + 0xc7, 0xc1, 0xbc, 0x21, 0x0e, 0x8b, 0x2c, 0xca, 0xdc, 0x80, 0x45, 0xdf, 0x80, 0x25, 0x18, 0x9f, + 0xb2, 0xa1, 0xab, 0xa8, 0x22, 0x9c, 0xec, 0xf2, 0xcd, 0x63, 0x53, 0x8d, 0x1e, 0xfa, 0x20, 0xa7, + 0x4a, 0x22, 0x91, 0x05, 0x79, 0x06, 0x65, 0x11, 0x5e, 0xf1, 0x01, 0x73, 0x91, 0xc5, 0x22, 0x1a, + 0x93, 0xff, 0xad, 0xc4, 0xa3, 0x13, 0xca, 0xd4, 0x12, 0x73, 0x45, 0x90, 0x17, 0xb0, 0x2e, 0x11, + 0x10, 0x77, 0x10, 0x06, 0x92, 0x87, 0x23, 0xe1, 0x14, 0x96, 0x47, 0x4d, 0xe7, 0xd0, 0xb8, 0xb5, + 0xb4, 0x17, 0xad, 0xc8, 0xb4, 0x2a, 0xc8, 0x36, 0xdc, 0xf5, 0x85, 0x1b, 0xe1, 0xa7, 0x4a, 0xf4, + 0x83, 0x0b, 0x9c, 0x23, 0x93, 0xae, 0xfb, 0xe2, 0x18, 0xed, 0x3d, 0x6d, 0xae, 0xbe, 0x06, 0x98, + 0x37, 0x44, 0x9e, 0x40, 0x29, 0xaa, 0x00, 0xe7, 0xc9, 0x78, 0xcf, 0x3c, 0x81, 0x4c, 0x64, 0xc5, + 0x0b, 0xb5, 0x8a, 0x84, 0x93, 0xd9, 0xca, 0x2a, 0x5e, 0xa0, 0x52, 0xfd, 0xd5, 0x80, 0x52, 0xaa, + 0xd9, 0x78, 0x51, 0x19, 0xc9, 0xa2, 0x5a, 0x58, 0x0d, 0x99, 0xeb, 0x56, 0x43, 0xf6, 0xda, 0xd5, + 0x90, 0xbb, 0xc1, 0xa5, 0x6e, 0x42, 0x01, 0x0b, 0x15, 0x4e, 0x1e, 0x6b, 0x8b, 0xb4, 0xea, 0x6f, + 0x06, 0x94, 0x17, 0x50, 0xbc, 0xd5, 0xde, 0xc9, 0x67, 0x40, 0xce, 0x46, 0xde, 0xe0, 0x72, 0xe4, + 0x0b, 0xa9, 0x08, 0xa5, 0x4b, 0xc8, 0xa1, 0xcb, 0xdd, 0xd4, 0x09, 0x26, 0x15, 0xaa, 0xca, 0x73, + 0x1e, 0xfe, 0xc8, 0x02, 0xdc, 0x90, 0x26, 0x8d, 0xb4, 0x64, 0xac, 0xf2, 0x76, 0xa1, 0xf6, 0x47, + 0x16, 0xdf, 0x0f, 0x8d, 0xce, 0xe7, 0xb0, 0x81, 0x80, 0xf8, 0xc1, 0x85, 0x3b, 0x08, 0x47, 0x57, + 0xe3, 0x00, 0x97, 0x5a, 0x34, 0xac, 0x24, 0x3e, 0x6b, 0xe1, 0x91, 0xda, 0x6b, 0xe4, 0xd5, 0x6a, + 0x04, 0xf6, 0x99, 0xc1, 0x3e, 0x9d, 0x05, 0x10, 0xf1, 0x1b, 0x07, 0x9a, 0xe3, 0x4b, 0xb9, 0xb0, + 0xe7, 0x67, 0xc9, 0xa4, 0x9c, 0xf3, 0x70, 0x2c, 0x56, 0x1f, 0x84, 0x38, 0x47, 0x34, 0x2c, 0x2f, + 0x78, 0x38, 0x8e, 0x87, 0x45, 0xc9, 0x82, 0x7c, 0x0d, 0xe5, 0xf8, 0xa6, 0x75, 0x19, 0x79, 0x2c, + 0x63, 0x73, 0x35, 0x05, 0x16, 0x61, 0x5d, 0xa6, 0x34, 0xf2, 0x31, 0x94, 0xcf, 0x3c, 0xc1, 0xdc, + 0x84, 0x3b, 0xfa, 0xf5, 0xb0, 0x94, 0x31, 0x41, 0xe8, 0x0b, 0x28, 0x8b, 0xc0, 0x9b, 0x88, 0x37, + 0x61, 0xb4, 0x38, 0xd6, 0xde, 0xb1, 0x38, 0xac, 0xd8, 0x05, 0x37, 0xe7, 0x55, 0x3c, 0x0b, 0xaa, + 0xc6, 0xdb, 0xe5, 0x43, 0x9a, 0xe9, 0xd9, 0x45, 0xa6, 0xeb, 0x4b, 0xae, 0xfd, 0x64, 0x80, 0xad, + 0x97, 0x02, 0x9b, 0x8c, 0xfc, 0x81, 0x27, 0xfd, 0x30, 0x20, 0x4f, 0x20, 0x1f, 0x84, 0x43, 0xa6, + 0x36, 0xa7, 0x42, 0xf8, 0xa3, 0xa5, 0x3d, 0x90, 0x72, 0x6d, 0x74, 0xc2, 0x21, 0xa3, 0xda, 0xbb, + 0xfa, 0x0c, 0x72, 0x4a, 0x55, 0xfb, 0x37, 0x6a, 0xe1, 0x26, 0xfb, 0x57, 0xce, 0x95, 0xda, 0x29, + 0x54, 0xa2, 0x2f, 0x9c, 0x33, 0xce, 0x82, 0x01, 0x53, 0x3f, 0x3d, 0x52, 0x0c, 0x43, 0xf9, 0x83, + 0x57, 0x6c, 0xed, 0x67, 0x03, 0x08, 0xe6, 0x5d, 0x1c, 0xbd, 0xdb, 0xc8, 0x4d, 0x1e, 0xc3, 0xe6, + 0xdb, 0x2b, 0xc6, 0x67, 0x7a, 0xe3, 0x0d, 0x98, 0x3b, 0xf4, 0x85, 0xfa, 0x8a, 0xde, 0x20, 0x26, + 0xdd, 0xc0, 0xd3, 0x9e, 0x3e, 0xdc, 0x8f, 0xce, 0x6a, 0x7f, 0xe5, 0xa0, 0xd4, 0xe3, 0xd3, 0x84, + 0x36, 0xdf, 0x02, 0x4c, 0x3c, 0x2e, 0x7d, 0x85, 0x69, 0x0c, 0xfb, 0x27, 0x29, 0xd8, 0xe7, 0xae, + 0x09, 0x43, 0xbb, 0xb1, 0x3f, 0x4d, 0x85, 0x5e, 0x3b, 0xa1, 0x99, 0x0f, 0x9e, 0xd0, 0xec, 0x7f, + 0x98, 0xd0, 0x26, 0x94, 0x52, 0x13, 0x1a, 0x0d, 0xe8, 0xd6, 0xbb, 0xfb, 0x48, 0xcd, 0x28, 0xcc, + 0x67, 0xb4, 0xfa, 0xa7, 0x01, 0x77, 0x57, 0x5a, 0x54, 0x53, 0x91, 0x7a, 0x24, 0xdf, 0x3f, 0x15, + 0xf3, 0xd7, 0x91, 0xb4, 0xc0, 0xc6, 0x2a, 0x5d, 0x1e, 0x13, 0x4a, 0x0f, 0x48, 0x29, 0xdd, 0xd7, + 0x22, 0xe3, 0xe8, 0xba, 0x58, 0xd0, 0x05, 0xe9, 0xc2, 0x7d, 0x9d, 0x64, 0xf9, 0x95, 0xd4, 0x2f, + 0xf5, 0xff, 0x97, 0x32, 0x2d, 0x3e, 0x92, 0xf7, 0xc4, 0x8a, 0x4d, 0x54, 0xdd, 0xdb, 0x98, 0xf8, + 0xf7, 0xbc, 0x62, 0xd1, 0xea, 0x3e, 0x04, 0xb3, 0xc5, 0x46, 0xa3, 0x83, 0xe0, 0x3c, 0x54, 0xbf, + 0x13, 0x11, 0x17, 0xee, 0x7a, 0xc3, 0x21, 0x67, 0x42, 0x44, 0xac, 0x2f, 0x6b, 0x6b, 0x53, 0x1b, + 0xd5, 0x48, 0xf0, 0x30, 0x94, 0x51, 0x42, 0x94, 0xa3, 0x45, 0x51, 0x03, 0x50, 0xc9, 0x84, 0xfe, + 0xa1, 0xf4, 0xce, 0x75, 0xb3, 0x5d, 0x07, 0x2b, 0xbd, 0x3f, 0x09, 0x40, 0xa1, 0x73, 0x42, 0x8f, + 0x9b, 0x47, 0xf6, 0x1d, 0x62, 0x81, 0xd9, 0xeb, 0x34, 0xbb, 0xbd, 0x97, 0x27, 0x7d, 0xdb, 0xd8, + 0xde, 0x85, 0xca, 0x22, 0x9d, 0x48, 0x11, 0xf2, 0xa7, 0x9d, 0x5e, 0xbb, 0x6f, 0xdf, 0x51, 0x61, + 0xa7, 0x07, 0x9d, 0xfe, 0x97, 0x8f, 0x6d, 0x43, 0x99, 0x9f, 0xbf, 0xee, 0xb7, 0x7b, 0x76, 0x66, + 0xfb, 0x17, 0x03, 0x60, 0x8e, 0x05, 0x29, 0xc1, 0xda, 0x69, 0xe7, 0xb0, 0x73, 0xf2, 0x5d, 0x47, + 0x87, 0x1c, 0x37, 0x7b, 0xfd, 0x36, 0xb5, 0x0d, 0x75, 0x40, 0xdb, 0xdd, 0xa3, 0x83, 0x56, 0xd3, + 0xce, 0xa8, 0x03, 0xba, 0x7f, 0xd2, 0x39, 0x7a, 0x6d, 0x67, 0x31, 0x57, 0xb3, 0xdf, 0x7a, 0xa9, + 0xc5, 0x5e, 0xb7, 0x49, 0xdb, 0x76, 0x8e, 0xd8, 0x60, 0xb5, 0xbf, 0xef, 0xb6, 0xe9, 0xc1, 0x71, + 0xbb, 0xd3, 0x6f, 0x1e, 0xd9, 0x79, 0x15, 0xf3, 0xbc, 0xd9, 0x3a, 0x3c, 0xed, 0xda, 0x05, 0x9d, + 0xac, 0xd7, 0x3f, 0xa1, 0x6d, 0x7b, 0x4d, 0x29, 0xfb, 0xb4, 0x79, 0xd0, 0x69, 0xef, 0xdb, 0x66, + 0x35, 0x63, 0x1b, 0xcf, 0xf7, 0x60, 0xdd, 0x0f, 0x1b, 0x53, 0x5f, 0x32, 0x21, 0xf4, 0xdf, 0xad, + 0x1f, 0x1e, 0x46, 0x9a, 0x1f, 0xee, 0x68, 0x69, 0xe7, 0x22, 0xdc, 0x99, 0xca, 0x1d, 0x3c, 0xdd, + 0x89, 0x2f, 0xf5, 0xac, 0x80, 0xfa, 0xa3, 0x7f, 0x02, 0x00, 0x00, 0xff, 0xff, 0xe2, 0xab, 0xbe, + 0xeb, 0xc4, 0x0d, 0x00, 0x00, } diff --git a/go/vt/proto/vschema/vschema.pb.go b/go/vt/proto/vschema/vschema.pb.go index d052ef272b4..05ba4a37e84 100644 --- a/go/vt/proto/vschema/vschema.pb.go +++ b/go/vt/proto/vschema/vschema.pb.go @@ -1,12 +1,15 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // source: vschema.proto -package vschema // import "vitess.io/vitess/go/vt/proto/vschema" +package vschema -import proto "github.com/golang/protobuf/proto" -import fmt "fmt" -import math "math" -import query "vitess.io/vitess/go/vt/proto/query" +import ( + fmt "fmt" + math "math" + + proto "github.com/golang/protobuf/proto" + query "vitess.io/vitess/go/vt/proto/query" +) // Reference imports to suppress errors if they are not otherwise used. var _ = proto.Marshal @@ -17,7 +20,7 @@ var _ = math.Inf // is compatible with the proto package it is being compiled against. // A compilation error at this line likely means your copy of the // proto package needs to be updated. -const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package +const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package // RoutingRules specify the high level routing rules for the VSchema. type RoutingRules struct { @@ -34,16 +37,17 @@ func (m *RoutingRules) Reset() { *m = RoutingRules{} } func (m *RoutingRules) String() string { return proto.CompactTextString(m) } func (*RoutingRules) ProtoMessage() {} func (*RoutingRules) Descriptor() ([]byte, []int) { - return fileDescriptor_vschema_13414422c846e850, []int{0} + return fileDescriptor_3f6849254fea3e77, []int{0} } + func (m *RoutingRules) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_RoutingRules.Unmarshal(m, b) } func (m *RoutingRules) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_RoutingRules.Marshal(b, m, deterministic) } -func (dst *RoutingRules) XXX_Merge(src proto.Message) { - xxx_messageInfo_RoutingRules.Merge(dst, src) +func (m *RoutingRules) XXX_Merge(src proto.Message) { + xxx_messageInfo_RoutingRules.Merge(m, src) } func (m *RoutingRules) XXX_Size() int { return xxx_messageInfo_RoutingRules.Size(m) @@ -74,16 +78,17 @@ func (m *RoutingRule) Reset() { *m = RoutingRule{} } func (m *RoutingRule) String() string { return proto.CompactTextString(m) } func (*RoutingRule) ProtoMessage() {} func (*RoutingRule) Descriptor() ([]byte, []int) { - return fileDescriptor_vschema_13414422c846e850, []int{1} + return fileDescriptor_3f6849254fea3e77, []int{1} } + func (m *RoutingRule) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_RoutingRule.Unmarshal(m, b) } func (m *RoutingRule) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_RoutingRule.Marshal(b, m, deterministic) } -func (dst *RoutingRule) XXX_Merge(src proto.Message) { - xxx_messageInfo_RoutingRule.Merge(dst, src) +func (m *RoutingRule) XXX_Merge(src proto.Message) { + xxx_messageInfo_RoutingRule.Merge(m, src) } func (m *RoutingRule) XXX_Size() int { return xxx_messageInfo_RoutingRule.Size(m) @@ -111,28 +116,31 @@ func (m *RoutingRule) GetToTables() []string { // Keyspace is the vschema for a keyspace. type Keyspace struct { // If sharded is false, vindexes and tables are ignored. - Sharded bool `protobuf:"varint,1,opt,name=sharded,proto3" json:"sharded,omitempty"` - Vindexes map[string]*Vindex `protobuf:"bytes,2,rep,name=vindexes,proto3" json:"vindexes,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` - Tables map[string]*Table `protobuf:"bytes,3,rep,name=tables,proto3" json:"tables,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + Sharded bool `protobuf:"varint,1,opt,name=sharded,proto3" json:"sharded,omitempty"` + Vindexes map[string]*Vindex `protobuf:"bytes,2,rep,name=vindexes,proto3" json:"vindexes,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + Tables map[string]*Table `protobuf:"bytes,3,rep,name=tables,proto3" json:"tables,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + // If require_explicit_routing is true, vindexes and tables are not added to global routing + RequireExplicitRouting bool `protobuf:"varint,4,opt,name=require_explicit_routing,json=requireExplicitRouting,proto3" json:"require_explicit_routing,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *Keyspace) Reset() { *m = Keyspace{} } func (m *Keyspace) String() string { return proto.CompactTextString(m) } func (*Keyspace) ProtoMessage() {} func (*Keyspace) Descriptor() ([]byte, []int) { - return fileDescriptor_vschema_13414422c846e850, []int{2} + return fileDescriptor_3f6849254fea3e77, []int{2} } + func (m *Keyspace) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Keyspace.Unmarshal(m, b) } func (m *Keyspace) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_Keyspace.Marshal(b, m, deterministic) } -func (dst *Keyspace) XXX_Merge(src proto.Message) { - xxx_messageInfo_Keyspace.Merge(dst, src) +func (m *Keyspace) XXX_Merge(src proto.Message) { + xxx_messageInfo_Keyspace.Merge(m, src) } func (m *Keyspace) XXX_Size() int { return xxx_messageInfo_Keyspace.Size(m) @@ -164,6 +172,13 @@ func (m *Keyspace) GetTables() map[string]*Table { return nil } +func (m *Keyspace) GetRequireExplicitRouting() bool { + if m != nil { + return m.RequireExplicitRouting + } + return false +} + // Vindex is the vindex info for a Keyspace. type Vindex struct { // The type must match one of the predefined @@ -188,16 +203,17 @@ func (m *Vindex) Reset() { *m = Vindex{} } func (m *Vindex) String() string { return proto.CompactTextString(m) } func (*Vindex) ProtoMessage() {} func (*Vindex) Descriptor() ([]byte, []int) { - return fileDescriptor_vschema_13414422c846e850, []int{3} + return fileDescriptor_3f6849254fea3e77, []int{3} } + func (m *Vindex) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Vindex.Unmarshal(m, b) } func (m *Vindex) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_Vindex.Marshal(b, m, deterministic) } -func (dst *Vindex) XXX_Merge(src proto.Message) { - xxx_messageInfo_Vindex.Merge(dst, src) +func (m *Vindex) XXX_Merge(src proto.Message) { + xxx_messageInfo_Vindex.Merge(m, src) } func (m *Vindex) XXX_Size() int { return xxx_messageInfo_Vindex.Size(m) @@ -259,16 +275,17 @@ func (m *Table) Reset() { *m = Table{} } func (m *Table) String() string { return proto.CompactTextString(m) } func (*Table) ProtoMessage() {} func (*Table) Descriptor() ([]byte, []int) { - return fileDescriptor_vschema_13414422c846e850, []int{4} + return fileDescriptor_3f6849254fea3e77, []int{4} } + func (m *Table) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Table.Unmarshal(m, b) } func (m *Table) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_Table.Marshal(b, m, deterministic) } -func (dst *Table) XXX_Merge(src proto.Message) { - xxx_messageInfo_Table.Merge(dst, src) +func (m *Table) XXX_Merge(src proto.Message) { + xxx_messageInfo_Table.Merge(m, src) } func (m *Table) XXX_Size() int { return xxx_messageInfo_Table.Size(m) @@ -323,7 +340,7 @@ func (m *Table) GetColumnListAuthoritative() bool { // ColumnVindex is used to associate a column to a vindex. type ColumnVindex struct { - // Legacy implemenation, moving forward all vindexes should define a list of columns. + // Legacy implementation, moving forward all vindexes should define a list of columns. Column string `protobuf:"bytes,1,opt,name=column,proto3" json:"column,omitempty"` // The name must match a vindex defined in Keyspace. Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` @@ -338,16 +355,17 @@ func (m *ColumnVindex) Reset() { *m = ColumnVindex{} } func (m *ColumnVindex) String() string { return proto.CompactTextString(m) } func (*ColumnVindex) ProtoMessage() {} func (*ColumnVindex) Descriptor() ([]byte, []int) { - return fileDescriptor_vschema_13414422c846e850, []int{5} + return fileDescriptor_3f6849254fea3e77, []int{5} } + func (m *ColumnVindex) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ColumnVindex.Unmarshal(m, b) } func (m *ColumnVindex) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_ColumnVindex.Marshal(b, m, deterministic) } -func (dst *ColumnVindex) XXX_Merge(src proto.Message) { - xxx_messageInfo_ColumnVindex.Merge(dst, src) +func (m *ColumnVindex) XXX_Merge(src proto.Message) { + xxx_messageInfo_ColumnVindex.Merge(m, src) } func (m *ColumnVindex) XXX_Size() int { return xxx_messageInfo_ColumnVindex.Size(m) @@ -393,16 +411,17 @@ func (m *AutoIncrement) Reset() { *m = AutoIncrement{} } func (m *AutoIncrement) String() string { return proto.CompactTextString(m) } func (*AutoIncrement) ProtoMessage() {} func (*AutoIncrement) Descriptor() ([]byte, []int) { - return fileDescriptor_vschema_13414422c846e850, []int{6} + return fileDescriptor_3f6849254fea3e77, []int{6} } + func (m *AutoIncrement) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_AutoIncrement.Unmarshal(m, b) } func (m *AutoIncrement) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_AutoIncrement.Marshal(b, m, deterministic) } -func (dst *AutoIncrement) XXX_Merge(src proto.Message) { - xxx_messageInfo_AutoIncrement.Merge(dst, src) +func (m *AutoIncrement) XXX_Merge(src proto.Message) { + xxx_messageInfo_AutoIncrement.Merge(m, src) } func (m *AutoIncrement) XXX_Size() int { return xxx_messageInfo_AutoIncrement.Size(m) @@ -440,16 +459,17 @@ func (m *Column) Reset() { *m = Column{} } func (m *Column) String() string { return proto.CompactTextString(m) } func (*Column) ProtoMessage() {} func (*Column) Descriptor() ([]byte, []int) { - return fileDescriptor_vschema_13414422c846e850, []int{7} + return fileDescriptor_3f6849254fea3e77, []int{7} } + func (m *Column) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Column.Unmarshal(m, b) } func (m *Column) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_Column.Marshal(b, m, deterministic) } -func (dst *Column) XXX_Merge(src proto.Message) { - xxx_messageInfo_Column.Merge(dst, src) +func (m *Column) XXX_Merge(src proto.Message) { + xxx_messageInfo_Column.Merge(m, src) } func (m *Column) XXX_Size() int { return xxx_messageInfo_Column.Size(m) @@ -488,16 +508,17 @@ func (m *SrvVSchema) Reset() { *m = SrvVSchema{} } func (m *SrvVSchema) String() string { return proto.CompactTextString(m) } func (*SrvVSchema) ProtoMessage() {} func (*SrvVSchema) Descriptor() ([]byte, []int) { - return fileDescriptor_vschema_13414422c846e850, []int{8} + return fileDescriptor_3f6849254fea3e77, []int{8} } + func (m *SrvVSchema) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_SrvVSchema.Unmarshal(m, b) } func (m *SrvVSchema) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_SrvVSchema.Marshal(b, m, deterministic) } -func (dst *SrvVSchema) XXX_Merge(src proto.Message) { - xxx_messageInfo_SrvVSchema.Merge(dst, src) +func (m *SrvVSchema) XXX_Merge(src proto.Message) { + xxx_messageInfo_SrvVSchema.Merge(m, src) } func (m *SrvVSchema) XXX_Size() int { return xxx_messageInfo_SrvVSchema.Size(m) @@ -538,49 +559,51 @@ func init() { proto.RegisterMapType((map[string]*Keyspace)(nil), "vschema.SrvVSchema.KeyspacesEntry") } -func init() { proto.RegisterFile("vschema.proto", fileDescriptor_vschema_13414422c846e850) } - -var fileDescriptor_vschema_13414422c846e850 = []byte{ - // 643 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x54, 0xdd, 0x6e, 0xd3, 0x30, - 0x14, 0x56, 0xda, 0x35, 0x6b, 0x4f, 0xd6, 0x0e, 0xac, 0x6d, 0x84, 0x4e, 0xd3, 0xaa, 0x68, 0x40, - 0xe1, 0xa2, 0x95, 0x3a, 0x21, 0x41, 0xd1, 0x10, 0x63, 0xe2, 0x62, 0x62, 0x12, 0x28, 0x9b, 0x76, - 0xc1, 0x4d, 0xe5, 0xb5, 0x66, 0x8b, 0xd6, 0xc6, 0x99, 0xed, 0x04, 0xf2, 0x28, 0xdc, 0xf2, 0x06, - 0x3c, 0x0f, 0x2f, 0x83, 0xe2, 0x9f, 0xcc, 0xe9, 0xca, 0x9d, 0x3f, 0x9f, 0xf3, 0x7d, 0xe7, 0xf3, - 0xb1, 0x7d, 0xa0, 0x9d, 0xf1, 0xe9, 0x0d, 0x59, 0xe0, 0x41, 0xc2, 0xa8, 0xa0, 0x68, 0x5d, 0xc3, - 0xae, 0x77, 0x97, 0x12, 0x96, 0xab, 0xdd, 0x60, 0x0c, 0x1b, 0x21, 0x4d, 0x45, 0x14, 0x5f, 0x87, - 0xe9, 0x9c, 0x70, 0xf4, 0x0a, 0x1a, 0xac, 0x58, 0xf8, 0x4e, 0xaf, 0xde, 0xf7, 0x46, 0x5b, 0x03, - 0x23, 0x62, 0x65, 0x85, 0x2a, 0x25, 0x38, 0x05, 0xcf, 0xda, 0x45, 0x7b, 0x00, 0xdf, 0x19, 0x5d, - 0x4c, 0x04, 0xbe, 0x9a, 0x13, 0xdf, 0xe9, 0x39, 0xfd, 0x56, 0xd8, 0x2a, 0x76, 0x2e, 0x8a, 0x0d, - 0xb4, 0x0b, 0x2d, 0x41, 0x55, 0x90, 0xfb, 0xb5, 0x5e, 0xbd, 0xdf, 0x0a, 0x9b, 0x82, 0xca, 0x18, - 0x0f, 0xfe, 0xd4, 0xa0, 0xf9, 0x99, 0xe4, 0x3c, 0xc1, 0x53, 0x82, 0x7c, 0x58, 0xe7, 0x37, 0x98, - 0xcd, 0xc8, 0x4c, 0xaa, 0x34, 0x43, 0x03, 0xd1, 0x3b, 0x68, 0x66, 0x51, 0x3c, 0x23, 0x3f, 0xb5, - 0x84, 0x37, 0xda, 0x2f, 0x0d, 0x1a, 0xfa, 0xe0, 0x52, 0x67, 0x7c, 0x8a, 0x05, 0xcb, 0xc3, 0x92, - 0x80, 0x5e, 0x83, 0xab, 0xab, 0xd7, 0x25, 0x75, 0xef, 0x21, 0x55, 0xb9, 0x51, 0x44, 0x9d, 0xdc, - 0x3d, 0x83, 0x76, 0x45, 0x11, 0x3d, 0x82, 0xfa, 0x2d, 0xc9, 0xf5, 0x01, 0x8b, 0x25, 0x7a, 0x06, - 0x8d, 0x0c, 0xcf, 0x53, 0xe2, 0xd7, 0x7a, 0x4e, 0xdf, 0x1b, 0x6d, 0x96, 0xc2, 0x8a, 0x18, 0xaa, - 0xe8, 0xb8, 0xf6, 0xc6, 0xe9, 0x9e, 0x82, 0x67, 0x15, 0x59, 0xa1, 0x75, 0x50, 0xd5, 0xea, 0x94, - 0x5a, 0x92, 0x66, 0x49, 0x05, 0xbf, 0x1d, 0x70, 0x55, 0x01, 0x84, 0x60, 0x4d, 0xe4, 0x89, 0x69, - 0xba, 0x5c, 0xa3, 0x43, 0x70, 0x13, 0xcc, 0xf0, 0xc2, 0x74, 0x6a, 0x77, 0xc9, 0xd5, 0xe0, 0xab, - 0x8c, 0xea, 0xc3, 0xaa, 0x54, 0xb4, 0x05, 0x0d, 0xfa, 0x23, 0x26, 0xcc, 0xaf, 0x4b, 0x25, 0x05, - 0xba, 0x6f, 0xc1, 0xb3, 0x92, 0x57, 0x98, 0xde, 0xb2, 0x4d, 0xb7, 0x6c, 0x93, 0xbf, 0x6a, 0xd0, - 0x50, 0xf7, 0xbf, 0xca, 0xe3, 0x7b, 0xd8, 0x9c, 0xd2, 0x79, 0xba, 0x88, 0x27, 0x4b, 0xd7, 0xba, - 0x5d, 0x9a, 0x3d, 0x91, 0x71, 0xdd, 0xc8, 0xce, 0xd4, 0x42, 0x84, 0xa3, 0x23, 0xe8, 0xe0, 0x54, - 0xd0, 0x49, 0x14, 0x4f, 0x19, 0x59, 0x90, 0x58, 0x48, 0xdf, 0xde, 0x68, 0xa7, 0xa4, 0x1f, 0xa7, - 0x82, 0x9e, 0x9a, 0x68, 0xd8, 0xc6, 0x36, 0x44, 0x2f, 0x61, 0x5d, 0x09, 0x72, 0x7f, 0x4d, 0x96, - 0xdd, 0x5c, 0x2a, 0x1b, 0x9a, 0x38, 0xda, 0x01, 0x37, 0x89, 0xe2, 0x98, 0xcc, 0xfc, 0x86, 0xf4, - 0xaf, 0x11, 0x1a, 0xc3, 0x53, 0x7d, 0x82, 0x79, 0xc4, 0xc5, 0x04, 0xa7, 0xe2, 0x86, 0xb2, 0x48, - 0x60, 0x11, 0x65, 0xc4, 0x77, 0xe5, 0xeb, 0x7d, 0xa2, 0x12, 0xce, 0x22, 0x2e, 0x8e, 0xed, 0x70, - 0x70, 0x01, 0x1b, 0xf6, 0xe9, 0x8a, 0x1a, 0x2a, 0x55, 0xf7, 0x48, 0xa3, 0xa2, 0x73, 0x31, 0x5e, - 0x98, 0xe6, 0xca, 0x75, 0xf1, 0x47, 0x8c, 0xf5, 0xba, 0xfc, 0x4b, 0x06, 0x06, 0x27, 0xd0, 0xae, - 0x1c, 0xfa, 0xbf, 0xb2, 0x5d, 0x68, 0x72, 0x72, 0x97, 0x92, 0x78, 0x6a, 0xa4, 0x4b, 0x1c, 0x1c, - 0x81, 0x7b, 0x52, 0x2d, 0xee, 0x58, 0xc5, 0xf7, 0xf5, 0x55, 0x16, 0xac, 0xce, 0xc8, 0x1b, 0xa8, - 0x81, 0x72, 0x91, 0x27, 0x44, 0xdd, 0x6b, 0xf0, 0xd7, 0x01, 0x38, 0x67, 0xd9, 0xe5, 0xb9, 0x6c, - 0x26, 0xfa, 0x00, 0xad, 0x5b, 0xfd, 0xc5, 0xcc, 0x60, 0x09, 0xca, 0x4e, 0xdf, 0xe7, 0x95, 0xff, - 0x50, 0x3f, 0xca, 0x7b, 0x12, 0x1a, 0x43, 0x9b, 0xa9, 0x51, 0x33, 0x51, 0xe3, 0x49, 0xfd, 0x8e, - 0xed, 0x55, 0xe3, 0x89, 0x87, 0x1b, 0xcc, 0x42, 0xdd, 0x2f, 0xd0, 0xa9, 0x0a, 0xaf, 0x78, 0xc0, - 0x2f, 0xaa, 0xbf, 0xee, 0xf1, 0x83, 0xd1, 0x60, 0xbd, 0xe9, 0x8f, 0xcf, 0xbf, 0x1d, 0x64, 0x91, - 0x20, 0x9c, 0x0f, 0x22, 0x3a, 0x54, 0xab, 0xe1, 0x35, 0x1d, 0x66, 0x62, 0x28, 0x67, 0xea, 0x50, - 0x73, 0xaf, 0x5c, 0x09, 0x0f, 0xff, 0x05, 0x00, 0x00, 0xff, 0xff, 0xc8, 0x0d, 0x93, 0x48, 0x89, - 0x05, 0x00, 0x00, +func init() { proto.RegisterFile("vschema.proto", fileDescriptor_3f6849254fea3e77) } + +var fileDescriptor_3f6849254fea3e77 = []byte{ + // 673 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x54, 0xcf, 0x4e, 0xdb, 0x4e, + 0x10, 0x96, 0x13, 0x62, 0x92, 0x31, 0x09, 0xbf, 0xdf, 0x0a, 0xa8, 0x1b, 0x84, 0x88, 0x2c, 0xda, + 0xa6, 0x3d, 0x24, 0x52, 0x50, 0x25, 0x9a, 0x8a, 0xaa, 0x14, 0x71, 0x40, 0x45, 0x6a, 0x65, 0x10, + 0x87, 0x5e, 0x2c, 0xe3, 0x6c, 0x61, 0x45, 0xe2, 0x35, 0xbb, 0x6b, 0x97, 0x3c, 0x4a, 0xaf, 0x7d, + 0xad, 0x3e, 0x42, 0x5f, 0xa2, 0xf2, 0xfe, 0x31, 0x1b, 0x48, 0x6f, 0x3b, 0x3b, 0xf3, 0x7d, 0xf3, + 0xed, 0xec, 0xcc, 0x40, 0xbb, 0xe0, 0xc9, 0x0d, 0x9e, 0xc5, 0x83, 0x8c, 0x51, 0x41, 0xd1, 0xaa, + 0x36, 0xbb, 0xde, 0x5d, 0x8e, 0xd9, 0x5c, 0xdd, 0x06, 0x63, 0x58, 0x0b, 0x69, 0x2e, 0x48, 0x7a, + 0x1d, 0xe6, 0x53, 0xcc, 0xd1, 0x1b, 0x68, 0xb0, 0xf2, 0xe0, 0x3b, 0xbd, 0x7a, 0xdf, 0x1b, 0x6d, + 0x0c, 0x0c, 0x89, 0x15, 0x15, 0xaa, 0x90, 0xe0, 0x14, 0x3c, 0xeb, 0x16, 0xed, 0x00, 0x7c, 0x67, + 0x74, 0x16, 0x89, 0xf8, 0x6a, 0x8a, 0x7d, 0xa7, 0xe7, 0xf4, 0x5b, 0x61, 0xab, 0xbc, 0xb9, 0x28, + 0x2f, 0xd0, 0x36, 0xb4, 0x04, 0x55, 0x4e, 0xee, 0xd7, 0x7a, 0xf5, 0x7e, 0x2b, 0x6c, 0x0a, 0x2a, + 0x7d, 0x3c, 0xf8, 0x53, 0x83, 0xe6, 0x67, 0x3c, 0xe7, 0x59, 0x9c, 0x60, 0xe4, 0xc3, 0x2a, 0xbf, + 0x89, 0xd9, 0x04, 0x4f, 0x24, 0x4b, 0x33, 0x34, 0x26, 0x7a, 0x0f, 0xcd, 0x82, 0xa4, 0x13, 0x7c, + 0xaf, 0x29, 0xbc, 0xd1, 0x6e, 0x25, 0xd0, 0xc0, 0x07, 0x97, 0x3a, 0xe2, 0x24, 0x15, 0x6c, 0x1e, + 0x56, 0x00, 0xf4, 0x16, 0x5c, 0x9d, 0xbd, 0x2e, 0xa1, 0x3b, 0x4f, 0xa1, 0x4a, 0x8d, 0x02, 0xea, + 0x60, 0x74, 0x00, 0x3e, 0xc3, 0x77, 0x39, 0x61, 0x38, 0xc2, 0xf7, 0xd9, 0x94, 0x24, 0x44, 0x44, + 0x4c, 0x3d, 0xdb, 0x5f, 0x91, 0xf2, 0xb6, 0xb4, 0xff, 0x44, 0xbb, 0x75, 0x51, 0xba, 0x67, 0xd0, + 0x5e, 0xd0, 0x82, 0xfe, 0x83, 0xfa, 0x2d, 0x9e, 0xeb, 0xd2, 0x94, 0x47, 0xf4, 0x02, 0x1a, 0x45, + 0x3c, 0xcd, 0xb1, 0x5f, 0xeb, 0x39, 0x7d, 0x6f, 0xb4, 0x5e, 0x49, 0x52, 0xc0, 0x50, 0x79, 0xc7, + 0xb5, 0x03, 0xa7, 0x7b, 0x0a, 0x9e, 0x25, 0x6f, 0x09, 0xd7, 0xde, 0x22, 0x57, 0xa7, 0xe2, 0x92, + 0x30, 0x8b, 0x2a, 0xf8, 0xe5, 0x80, 0xab, 0x12, 0x20, 0x04, 0x2b, 0x62, 0x9e, 0x99, 0xef, 0x92, + 0x67, 0xb4, 0x0f, 0x6e, 0x16, 0xb3, 0x78, 0x66, 0x6a, 0xbc, 0xfd, 0x48, 0xd5, 0xe0, 0xab, 0xf4, + 0xea, 0x32, 0xa9, 0x50, 0xb4, 0x01, 0x0d, 0xfa, 0x23, 0xc5, 0xcc, 0xaf, 0x4b, 0x26, 0x65, 0x74, + 0xdf, 0x81, 0x67, 0x05, 0x2f, 0x11, 0xbd, 0x61, 0x8b, 0x6e, 0xd9, 0x22, 0x7f, 0xd6, 0xa0, 0xa1, + 0x3a, 0x67, 0x99, 0xc6, 0x0f, 0xb0, 0x9e, 0xd0, 0x69, 0x3e, 0x4b, 0xa3, 0x47, 0x0d, 0xb1, 0x59, + 0x89, 0x3d, 0x96, 0x7e, 0x5d, 0xc8, 0x4e, 0x62, 0x59, 0x98, 0xa3, 0x43, 0xe8, 0xc4, 0xb9, 0xa0, + 0x11, 0x49, 0x13, 0x86, 0x67, 0x38, 0x15, 0x52, 0xb7, 0x37, 0xda, 0xaa, 0xe0, 0x47, 0xb9, 0xa0, + 0xa7, 0xc6, 0x1b, 0xb6, 0x63, 0xdb, 0x44, 0xaf, 0x61, 0x55, 0x11, 0x72, 0x7f, 0x45, 0xa6, 0x5d, + 0x7f, 0x94, 0x36, 0x34, 0x7e, 0xb4, 0x05, 0x6e, 0x46, 0xd2, 0x14, 0x4f, 0xfc, 0x86, 0xd4, 0xaf, + 0x2d, 0x34, 0x86, 0xe7, 0xfa, 0x05, 0x53, 0xc2, 0x45, 0x14, 0xe7, 0xe2, 0x86, 0x32, 0x22, 0x62, + 0x41, 0x0a, 0xec, 0xbb, 0xb2, 0xb1, 0x9e, 0xa9, 0x80, 0x33, 0xc2, 0xc5, 0x91, 0xed, 0x0e, 0x2e, + 0x60, 0xcd, 0x7e, 0x5d, 0x99, 0x43, 0x85, 0xea, 0x1a, 0x69, 0xab, 0xac, 0x5c, 0x1a, 0xcf, 0x4c, + 0x71, 0xe5, 0xb9, 0x9c, 0x2e, 0x23, 0xbd, 0x2e, 0xa7, 0xd0, 0x98, 0xc1, 0x31, 0xb4, 0x17, 0x1e, + 0xfd, 0x4f, 0xda, 0x2e, 0x34, 0x39, 0xbe, 0xcb, 0x71, 0x9a, 0x18, 0xea, 0xca, 0x0e, 0x0e, 0xc1, + 0x3d, 0x5e, 0x4c, 0xee, 0x58, 0xc9, 0x77, 0xf5, 0x57, 0x96, 0xa8, 0xce, 0xc8, 0x1b, 0xa8, 0x55, + 0x74, 0x31, 0xcf, 0xb0, 0xfa, 0xd7, 0xe0, 0xb7, 0x03, 0x70, 0xce, 0x8a, 0xcb, 0x73, 0x59, 0x4c, + 0xf4, 0x11, 0x5a, 0xb7, 0x7a, 0x38, 0xcd, 0x4a, 0x0a, 0xaa, 0x4a, 0x3f, 0xc4, 0x55, 0x13, 0xac, + 0x9b, 0xf2, 0x01, 0x84, 0xc6, 0xd0, 0xd6, 0xd3, 0x1a, 0xa9, 0xc5, 0xa6, 0xa6, 0x63, 0x73, 0xd9, + 0x62, 0xe3, 0xe1, 0x1a, 0xb3, 0xac, 0xee, 0x17, 0xe8, 0x2c, 0x12, 0x2f, 0x69, 0xe0, 0x57, 0x8b, + 0x53, 0xf7, 0xff, 0x93, 0xa5, 0x62, 0xf5, 0xf4, 0xa7, 0x97, 0xdf, 0xf6, 0x0a, 0x22, 0x30, 0xe7, + 0x03, 0x42, 0x87, 0xea, 0x34, 0xbc, 0xa6, 0xc3, 0x42, 0x0c, 0xe5, 0x36, 0x1e, 0x6a, 0xec, 0x95, + 0x2b, 0xcd, 0xfd, 0xbf, 0x01, 0x00, 0x00, 0xff, 0xff, 0xb8, 0xa7, 0x99, 0x19, 0xc3, 0x05, 0x00, + 0x00, } diff --git a/go/vt/proto/vtctldata/vtctldata.pb.go b/go/vt/proto/vtctldata/vtctldata.pb.go index 6f3860b8efc..0b7171a412a 100644 --- a/go/vt/proto/vtctldata/vtctldata.pb.go +++ b/go/vt/proto/vtctldata/vtctldata.pb.go @@ -1,12 +1,15 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // source: vtctldata.proto -package vtctldata // import "vitess.io/vitess/go/vt/proto/vtctldata" +package vtctldata -import proto "github.com/golang/protobuf/proto" -import fmt "fmt" -import math "math" -import logutil "vitess.io/vitess/go/vt/proto/logutil" +import ( + fmt "fmt" + math "math" + + proto "github.com/golang/protobuf/proto" + logutil "vitess.io/vitess/go/vt/proto/logutil" +) // Reference imports to suppress errors if they are not otherwise used. var _ = proto.Marshal @@ -17,7 +20,7 @@ var _ = math.Inf // is compatible with the proto package it is being compiled against. // A compilation error at this line likely means your copy of the // proto package needs to be updated. -const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package +const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package // ExecuteVtctlCommandRequest is the payload for ExecuteVtctlCommand. // timeouts are in nanoseconds. @@ -33,16 +36,17 @@ func (m *ExecuteVtctlCommandRequest) Reset() { *m = ExecuteVtctlCommandR func (m *ExecuteVtctlCommandRequest) String() string { return proto.CompactTextString(m) } func (*ExecuteVtctlCommandRequest) ProtoMessage() {} func (*ExecuteVtctlCommandRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_vtctldata_116d6c451a061272, []int{0} + return fileDescriptor_f41247b323a1ab2e, []int{0} } + func (m *ExecuteVtctlCommandRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ExecuteVtctlCommandRequest.Unmarshal(m, b) } func (m *ExecuteVtctlCommandRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_ExecuteVtctlCommandRequest.Marshal(b, m, deterministic) } -func (dst *ExecuteVtctlCommandRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_ExecuteVtctlCommandRequest.Merge(dst, src) +func (m *ExecuteVtctlCommandRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_ExecuteVtctlCommandRequest.Merge(m, src) } func (m *ExecuteVtctlCommandRequest) XXX_Size() int { return xxx_messageInfo_ExecuteVtctlCommandRequest.Size(m) @@ -79,16 +83,17 @@ func (m *ExecuteVtctlCommandResponse) Reset() { *m = ExecuteVtctlCommand func (m *ExecuteVtctlCommandResponse) String() string { return proto.CompactTextString(m) } func (*ExecuteVtctlCommandResponse) ProtoMessage() {} func (*ExecuteVtctlCommandResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_vtctldata_116d6c451a061272, []int{1} + return fileDescriptor_f41247b323a1ab2e, []int{1} } + func (m *ExecuteVtctlCommandResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ExecuteVtctlCommandResponse.Unmarshal(m, b) } func (m *ExecuteVtctlCommandResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_ExecuteVtctlCommandResponse.Marshal(b, m, deterministic) } -func (dst *ExecuteVtctlCommandResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_ExecuteVtctlCommandResponse.Merge(dst, src) +func (m *ExecuteVtctlCommandResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_ExecuteVtctlCommandResponse.Merge(m, src) } func (m *ExecuteVtctlCommandResponse) XXX_Size() int { return xxx_messageInfo_ExecuteVtctlCommandResponse.Size(m) @@ -111,9 +116,9 @@ func init() { proto.RegisterType((*ExecuteVtctlCommandResponse)(nil), "vtctldata.ExecuteVtctlCommandResponse") } -func init() { proto.RegisterFile("vtctldata.proto", fileDescriptor_vtctldata_116d6c451a061272) } +func init() { proto.RegisterFile("vtctldata.proto", fileDescriptor_f41247b323a1ab2e) } -var fileDescriptor_vtctldata_116d6c451a061272 = []byte{ +var fileDescriptor_f41247b323a1ab2e = []byte{ // 200 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0xcf, 0xd1, 0x4a, 0x87, 0x30, 0x14, 0x06, 0x70, 0xd6, 0xbf, 0x82, 0xff, 0x42, 0x83, 0x5d, 0x89, 0xdd, 0x88, 0x54, 0xec, 0xca, diff --git a/go/vt/proto/vtctlservice/vtctlservice.pb.go b/go/vt/proto/vtctlservice/vtctlservice.pb.go index 9dd938fd48b..d661e476922 100644 --- a/go/vt/proto/vtctlservice/vtctlservice.pb.go +++ b/go/vt/proto/vtctlservice/vtctlservice.pb.go @@ -1,16 +1,18 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // source: vtctlservice.proto -package vtctlservice // import "vitess.io/vitess/go/vt/proto/vtctlservice" - -import proto "github.com/golang/protobuf/proto" -import fmt "fmt" -import math "math" -import vtctldata "vitess.io/vitess/go/vt/proto/vtctldata" +package vtctlservice import ( - context "golang.org/x/net/context" + context "context" + fmt "fmt" + math "math" + + proto "github.com/golang/protobuf/proto" grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + vtctldata "vitess.io/vitess/go/vt/proto/vtctldata" ) // Reference imports to suppress errors if they are not otherwise used. @@ -22,7 +24,23 @@ var _ = math.Inf // is compatible with the proto package it is being compiled against. // A compilation error at this line likely means your copy of the // proto package needs to be updated. -const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package +const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package + +func init() { proto.RegisterFile("vtctlservice.proto", fileDescriptor_27055cdbb1148d2b) } + +var fileDescriptor_27055cdbb1148d2b = []byte{ + // 146 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x12, 0x2a, 0x2b, 0x49, 0x2e, + 0xc9, 0x29, 0x4e, 0x2d, 0x2a, 0xcb, 0x4c, 0x4e, 0xd5, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0xe2, + 0x41, 0x16, 0x93, 0xe2, 0x07, 0xf3, 0x52, 0x12, 0x4b, 0x12, 0x21, 0xd2, 0x46, 0x85, 0x5c, 0xac, + 0x61, 0x20, 0x21, 0xa1, 0x0c, 0x2e, 0x61, 0xd7, 0x8a, 0xd4, 0xe4, 0xd2, 0x92, 0x54, 0x30, 0xdf, + 0x39, 0x3f, 0x37, 0x37, 0x31, 0x2f, 0x45, 0x48, 0x55, 0x0f, 0xa1, 0x03, 0x8b, 0x7c, 0x50, 0x6a, + 0x61, 0x69, 0x6a, 0x71, 0x89, 0x94, 0x1a, 0x21, 0x65, 0xc5, 0x05, 0xf9, 0x79, 0xc5, 0xa9, 0x4a, + 0x0c, 0x06, 0x8c, 0x4e, 0xda, 0x51, 0x9a, 0x65, 0x99, 0x25, 0xa9, 0xc5, 0xc5, 0x7a, 0x99, 0xf9, + 0xfa, 0x10, 0x96, 0x7e, 0x7a, 0xbe, 0x7e, 0x59, 0x89, 0x3e, 0xd8, 0x49, 0xfa, 0xc8, 0x0e, 0x4e, + 0x62, 0x03, 0x8b, 0x19, 0x03, 0x02, 0x00, 0x00, 0xff, 0xff, 0x9d, 0xb5, 0x06, 0x92, 0xdb, 0x00, + 0x00, 0x00, +} // Reference imports to suppress errors if they are not otherwise used. var _ context.Context @@ -84,6 +102,14 @@ type VtctlServer interface { ExecuteVtctlCommand(*vtctldata.ExecuteVtctlCommandRequest, Vtctl_ExecuteVtctlCommandServer) error } +// UnimplementedVtctlServer can be embedded to have forward compatible implementations. +type UnimplementedVtctlServer struct { +} + +func (*UnimplementedVtctlServer) ExecuteVtctlCommand(req *vtctldata.ExecuteVtctlCommandRequest, srv Vtctl_ExecuteVtctlCommandServer) error { + return status.Errorf(codes.Unimplemented, "method ExecuteVtctlCommand not implemented") +} + func RegisterVtctlServer(s *grpc.Server, srv VtctlServer) { s.RegisterService(&_Vtctl_serviceDesc, srv) } @@ -122,19 +148,3 @@ var _Vtctl_serviceDesc = grpc.ServiceDesc{ }, Metadata: "vtctlservice.proto", } - -func init() { proto.RegisterFile("vtctlservice.proto", fileDescriptor_vtctlservice_af4114a311e29c50) } - -var fileDescriptor_vtctlservice_af4114a311e29c50 = []byte{ - // 146 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x12, 0x2a, 0x2b, 0x49, 0x2e, - 0xc9, 0x29, 0x4e, 0x2d, 0x2a, 0xcb, 0x4c, 0x4e, 0xd5, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0xe2, - 0x41, 0x16, 0x93, 0xe2, 0x07, 0xf3, 0x52, 0x12, 0x4b, 0x12, 0x21, 0xd2, 0x46, 0x85, 0x5c, 0xac, - 0x61, 0x20, 0x21, 0xa1, 0x0c, 0x2e, 0x61, 0xd7, 0x8a, 0xd4, 0xe4, 0xd2, 0x92, 0x54, 0x30, 0xdf, - 0x39, 0x3f, 0x37, 0x37, 0x31, 0x2f, 0x45, 0x48, 0x55, 0x0f, 0xa1, 0x03, 0x8b, 0x7c, 0x50, 0x6a, - 0x61, 0x69, 0x6a, 0x71, 0x89, 0x94, 0x1a, 0x21, 0x65, 0xc5, 0x05, 0xf9, 0x79, 0xc5, 0xa9, 0x4a, - 0x0c, 0x06, 0x8c, 0x4e, 0xda, 0x51, 0x9a, 0x65, 0x99, 0x25, 0xa9, 0xc5, 0xc5, 0x7a, 0x99, 0xf9, - 0xfa, 0x10, 0x96, 0x7e, 0x7a, 0xbe, 0x7e, 0x59, 0x89, 0x3e, 0xd8, 0x49, 0xfa, 0xc8, 0x0e, 0x4e, - 0x62, 0x03, 0x8b, 0x19, 0x03, 0x02, 0x00, 0x00, 0xff, 0xff, 0x9d, 0xb5, 0x06, 0x92, 0xdb, 0x00, - 0x00, 0x00, -} diff --git a/go/vt/proto/vtgate/vtgate.pb.go b/go/vt/proto/vtgate/vtgate.pb.go index fdfcd7e51ee..48186096d68 100644 --- a/go/vt/proto/vtgate/vtgate.pb.go +++ b/go/vt/proto/vtgate/vtgate.pb.go @@ -1,15 +1,18 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // source: vtgate.proto -package vtgate // import "vitess.io/vitess/go/vt/proto/vtgate" +package vtgate -import proto "github.com/golang/protobuf/proto" -import fmt "fmt" -import math "math" -import binlogdata "vitess.io/vitess/go/vt/proto/binlogdata" -import query "vitess.io/vitess/go/vt/proto/query" -import topodata "vitess.io/vitess/go/vt/proto/topodata" -import vtrpc "vitess.io/vitess/go/vt/proto/vtrpc" +import ( + fmt "fmt" + math "math" + + proto "github.com/golang/protobuf/proto" + binlogdata "vitess.io/vitess/go/vt/proto/binlogdata" + query "vitess.io/vitess/go/vt/proto/query" + topodata "vitess.io/vitess/go/vt/proto/topodata" + vtrpc "vitess.io/vitess/go/vt/proto/vtrpc" +) // Reference imports to suppress errors if they are not otherwise used. var _ = proto.Marshal @@ -20,7 +23,7 @@ var _ = math.Inf // is compatible with the proto package it is being compiled against. // A compilation error at this line likely means your copy of the // proto package needs to be updated. -const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package +const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package // TransactionMode controls the execution of distributed transaction // across multiple shards. @@ -43,6 +46,7 @@ var TransactionMode_name = map[int32]string{ 2: "MULTI", 3: "TWOPC", } + var TransactionMode_value = map[string]int32{ "UNSPECIFIED": 0, "SINGLE": 1, @@ -53,8 +57,9 @@ var TransactionMode_value = map[string]int32{ func (x TransactionMode) String() string { return proto.EnumName(TransactionMode_name, int32(x)) } + func (TransactionMode) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_vtgate_339c92b13a08c8a7, []int{0} + return fileDescriptor_aab96496ceaf1ebb, []int{0} } // CommitOrder is used to designate which of the ShardSessions @@ -78,6 +83,7 @@ var CommitOrder_name = map[int32]string{ 2: "POST", 3: "AUTOCOMMIT", } + var CommitOrder_value = map[string]int32{ "NORMAL": 0, "PRE": 1, @@ -88,8 +94,9 @@ var CommitOrder_value = map[string]int32{ func (x CommitOrder) String() string { return proto.EnumName(CommitOrder_name, int32(x)) } + func (CommitOrder) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_vtgate_339c92b13a08c8a7, []int{1} + return fileDescriptor_aab96496ceaf1ebb, []int{1} } // Session objects are exchanged like cookies through various @@ -138,16 +145,17 @@ func (m *Session) Reset() { *m = Session{} } func (m *Session) String() string { return proto.CompactTextString(m) } func (*Session) ProtoMessage() {} func (*Session) Descriptor() ([]byte, []int) { - return fileDescriptor_vtgate_339c92b13a08c8a7, []int{0} + return fileDescriptor_aab96496ceaf1ebb, []int{0} } + func (m *Session) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Session.Unmarshal(m, b) } func (m *Session) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_Session.Marshal(b, m, deterministic) } -func (dst *Session) XXX_Merge(src proto.Message) { - xxx_messageInfo_Session.Merge(dst, src) +func (m *Session) XXX_Merge(src proto.Message) { + xxx_messageInfo_Session.Merge(m, src) } func (m *Session) XXX_Size() int { return xxx_messageInfo_Session.Size(m) @@ -240,16 +248,17 @@ func (m *Session_ShardSession) Reset() { *m = Session_ShardSession{} } func (m *Session_ShardSession) String() string { return proto.CompactTextString(m) } func (*Session_ShardSession) ProtoMessage() {} func (*Session_ShardSession) Descriptor() ([]byte, []int) { - return fileDescriptor_vtgate_339c92b13a08c8a7, []int{0, 0} + return fileDescriptor_aab96496ceaf1ebb, []int{0, 0} } + func (m *Session_ShardSession) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Session_ShardSession.Unmarshal(m, b) } func (m *Session_ShardSession) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_Session_ShardSession.Marshal(b, m, deterministic) } -func (dst *Session_ShardSession) XXX_Merge(src proto.Message) { - xxx_messageInfo_Session_ShardSession.Merge(dst, src) +func (m *Session_ShardSession) XXX_Merge(src proto.Message) { + xxx_messageInfo_Session_ShardSession.Merge(m, src) } func (m *Session_ShardSession) XXX_Size() int { return xxx_messageInfo_Session_ShardSession.Size(m) @@ -298,16 +307,17 @@ func (m *ExecuteRequest) Reset() { *m = ExecuteRequest{} } func (m *ExecuteRequest) String() string { return proto.CompactTextString(m) } func (*ExecuteRequest) ProtoMessage() {} func (*ExecuteRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_vtgate_339c92b13a08c8a7, []int{1} + return fileDescriptor_aab96496ceaf1ebb, []int{1} } + func (m *ExecuteRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ExecuteRequest.Unmarshal(m, b) } func (m *ExecuteRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_ExecuteRequest.Marshal(b, m, deterministic) } -func (dst *ExecuteRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_ExecuteRequest.Merge(dst, src) +func (m *ExecuteRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_ExecuteRequest.Merge(m, src) } func (m *ExecuteRequest) XXX_Size() int { return xxx_messageInfo_ExecuteRequest.Size(m) @@ -386,16 +396,17 @@ func (m *ExecuteResponse) Reset() { *m = ExecuteResponse{} } func (m *ExecuteResponse) String() string { return proto.CompactTextString(m) } func (*ExecuteResponse) ProtoMessage() {} func (*ExecuteResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_vtgate_339c92b13a08c8a7, []int{2} + return fileDescriptor_aab96496ceaf1ebb, []int{2} } + func (m *ExecuteResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ExecuteResponse.Unmarshal(m, b) } func (m *ExecuteResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_ExecuteResponse.Marshal(b, m, deterministic) } -func (dst *ExecuteResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_ExecuteResponse.Merge(dst, src) +func (m *ExecuteResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_ExecuteResponse.Merge(m, src) } func (m *ExecuteResponse) XXX_Size() int { return xxx_messageInfo_ExecuteResponse.Size(m) @@ -456,16 +467,17 @@ func (m *ExecuteShardsRequest) Reset() { *m = ExecuteShardsRequest{} } func (m *ExecuteShardsRequest) String() string { return proto.CompactTextString(m) } func (*ExecuteShardsRequest) ProtoMessage() {} func (*ExecuteShardsRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_vtgate_339c92b13a08c8a7, []int{3} + return fileDescriptor_aab96496ceaf1ebb, []int{3} } + func (m *ExecuteShardsRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ExecuteShardsRequest.Unmarshal(m, b) } func (m *ExecuteShardsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_ExecuteShardsRequest.Marshal(b, m, deterministic) } -func (dst *ExecuteShardsRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_ExecuteShardsRequest.Merge(dst, src) +func (m *ExecuteShardsRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_ExecuteShardsRequest.Merge(m, src) } func (m *ExecuteShardsRequest) XXX_Size() int { return xxx_messageInfo_ExecuteShardsRequest.Size(m) @@ -551,16 +563,17 @@ func (m *ExecuteShardsResponse) Reset() { *m = ExecuteShardsResponse{} } func (m *ExecuteShardsResponse) String() string { return proto.CompactTextString(m) } func (*ExecuteShardsResponse) ProtoMessage() {} func (*ExecuteShardsResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_vtgate_339c92b13a08c8a7, []int{4} + return fileDescriptor_aab96496ceaf1ebb, []int{4} } + func (m *ExecuteShardsResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ExecuteShardsResponse.Unmarshal(m, b) } func (m *ExecuteShardsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_ExecuteShardsResponse.Marshal(b, m, deterministic) } -func (dst *ExecuteShardsResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_ExecuteShardsResponse.Merge(dst, src) +func (m *ExecuteShardsResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_ExecuteShardsResponse.Merge(m, src) } func (m *ExecuteShardsResponse) XXX_Size() int { return xxx_messageInfo_ExecuteShardsResponse.Size(m) @@ -622,16 +635,17 @@ func (m *ExecuteKeyspaceIdsRequest) Reset() { *m = ExecuteKeyspaceIdsReq func (m *ExecuteKeyspaceIdsRequest) String() string { return proto.CompactTextString(m) } func (*ExecuteKeyspaceIdsRequest) ProtoMessage() {} func (*ExecuteKeyspaceIdsRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_vtgate_339c92b13a08c8a7, []int{5} + return fileDescriptor_aab96496ceaf1ebb, []int{5} } + func (m *ExecuteKeyspaceIdsRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ExecuteKeyspaceIdsRequest.Unmarshal(m, b) } func (m *ExecuteKeyspaceIdsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_ExecuteKeyspaceIdsRequest.Marshal(b, m, deterministic) } -func (dst *ExecuteKeyspaceIdsRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_ExecuteKeyspaceIdsRequest.Merge(dst, src) +func (m *ExecuteKeyspaceIdsRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_ExecuteKeyspaceIdsRequest.Merge(m, src) } func (m *ExecuteKeyspaceIdsRequest) XXX_Size() int { return xxx_messageInfo_ExecuteKeyspaceIdsRequest.Size(m) @@ -717,16 +731,17 @@ func (m *ExecuteKeyspaceIdsResponse) Reset() { *m = ExecuteKeyspaceIdsRe func (m *ExecuteKeyspaceIdsResponse) String() string { return proto.CompactTextString(m) } func (*ExecuteKeyspaceIdsResponse) ProtoMessage() {} func (*ExecuteKeyspaceIdsResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_vtgate_339c92b13a08c8a7, []int{6} + return fileDescriptor_aab96496ceaf1ebb, []int{6} } + func (m *ExecuteKeyspaceIdsResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ExecuteKeyspaceIdsResponse.Unmarshal(m, b) } func (m *ExecuteKeyspaceIdsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_ExecuteKeyspaceIdsResponse.Marshal(b, m, deterministic) } -func (dst *ExecuteKeyspaceIdsResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_ExecuteKeyspaceIdsResponse.Merge(dst, src) +func (m *ExecuteKeyspaceIdsResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_ExecuteKeyspaceIdsResponse.Merge(m, src) } func (m *ExecuteKeyspaceIdsResponse) XXX_Size() int { return xxx_messageInfo_ExecuteKeyspaceIdsResponse.Size(m) @@ -788,16 +803,17 @@ func (m *ExecuteKeyRangesRequest) Reset() { *m = ExecuteKeyRangesRequest func (m *ExecuteKeyRangesRequest) String() string { return proto.CompactTextString(m) } func (*ExecuteKeyRangesRequest) ProtoMessage() {} func (*ExecuteKeyRangesRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_vtgate_339c92b13a08c8a7, []int{7} + return fileDescriptor_aab96496ceaf1ebb, []int{7} } + func (m *ExecuteKeyRangesRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ExecuteKeyRangesRequest.Unmarshal(m, b) } func (m *ExecuteKeyRangesRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_ExecuteKeyRangesRequest.Marshal(b, m, deterministic) } -func (dst *ExecuteKeyRangesRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_ExecuteKeyRangesRequest.Merge(dst, src) +func (m *ExecuteKeyRangesRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_ExecuteKeyRangesRequest.Merge(m, src) } func (m *ExecuteKeyRangesRequest) XXX_Size() int { return xxx_messageInfo_ExecuteKeyRangesRequest.Size(m) @@ -883,16 +899,17 @@ func (m *ExecuteKeyRangesResponse) Reset() { *m = ExecuteKeyRangesRespon func (m *ExecuteKeyRangesResponse) String() string { return proto.CompactTextString(m) } func (*ExecuteKeyRangesResponse) ProtoMessage() {} func (*ExecuteKeyRangesResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_vtgate_339c92b13a08c8a7, []int{8} + return fileDescriptor_aab96496ceaf1ebb, []int{8} } + func (m *ExecuteKeyRangesResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ExecuteKeyRangesResponse.Unmarshal(m, b) } func (m *ExecuteKeyRangesResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_ExecuteKeyRangesResponse.Marshal(b, m, deterministic) } -func (dst *ExecuteKeyRangesResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_ExecuteKeyRangesResponse.Merge(dst, src) +func (m *ExecuteKeyRangesResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_ExecuteKeyRangesResponse.Merge(m, src) } func (m *ExecuteKeyRangesResponse) XXX_Size() int { return xxx_messageInfo_ExecuteKeyRangesResponse.Size(m) @@ -956,16 +973,17 @@ func (m *ExecuteEntityIdsRequest) Reset() { *m = ExecuteEntityIdsRequest func (m *ExecuteEntityIdsRequest) String() string { return proto.CompactTextString(m) } func (*ExecuteEntityIdsRequest) ProtoMessage() {} func (*ExecuteEntityIdsRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_vtgate_339c92b13a08c8a7, []int{9} + return fileDescriptor_aab96496ceaf1ebb, []int{9} } + func (m *ExecuteEntityIdsRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ExecuteEntityIdsRequest.Unmarshal(m, b) } func (m *ExecuteEntityIdsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_ExecuteEntityIdsRequest.Marshal(b, m, deterministic) } -func (dst *ExecuteEntityIdsRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_ExecuteEntityIdsRequest.Merge(dst, src) +func (m *ExecuteEntityIdsRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_ExecuteEntityIdsRequest.Merge(m, src) } func (m *ExecuteEntityIdsRequest) XXX_Size() int { return xxx_messageInfo_ExecuteEntityIdsRequest.Size(m) @@ -1055,16 +1073,17 @@ func (m *ExecuteEntityIdsRequest_EntityId) Reset() { *m = ExecuteEntityI func (m *ExecuteEntityIdsRequest_EntityId) String() string { return proto.CompactTextString(m) } func (*ExecuteEntityIdsRequest_EntityId) ProtoMessage() {} func (*ExecuteEntityIdsRequest_EntityId) Descriptor() ([]byte, []int) { - return fileDescriptor_vtgate_339c92b13a08c8a7, []int{9, 0} + return fileDescriptor_aab96496ceaf1ebb, []int{9, 0} } + func (m *ExecuteEntityIdsRequest_EntityId) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ExecuteEntityIdsRequest_EntityId.Unmarshal(m, b) } func (m *ExecuteEntityIdsRequest_EntityId) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_ExecuteEntityIdsRequest_EntityId.Marshal(b, m, deterministic) } -func (dst *ExecuteEntityIdsRequest_EntityId) XXX_Merge(src proto.Message) { - xxx_messageInfo_ExecuteEntityIdsRequest_EntityId.Merge(dst, src) +func (m *ExecuteEntityIdsRequest_EntityId) XXX_Merge(src proto.Message) { + xxx_messageInfo_ExecuteEntityIdsRequest_EntityId.Merge(m, src) } func (m *ExecuteEntityIdsRequest_EntityId) XXX_Size() int { return xxx_messageInfo_ExecuteEntityIdsRequest_EntityId.Size(m) @@ -1115,16 +1134,17 @@ func (m *ExecuteEntityIdsResponse) Reset() { *m = ExecuteEntityIdsRespon func (m *ExecuteEntityIdsResponse) String() string { return proto.CompactTextString(m) } func (*ExecuteEntityIdsResponse) ProtoMessage() {} func (*ExecuteEntityIdsResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_vtgate_339c92b13a08c8a7, []int{10} + return fileDescriptor_aab96496ceaf1ebb, []int{10} } + func (m *ExecuteEntityIdsResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ExecuteEntityIdsResponse.Unmarshal(m, b) } func (m *ExecuteEntityIdsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_ExecuteEntityIdsResponse.Marshal(b, m, deterministic) } -func (dst *ExecuteEntityIdsResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_ExecuteEntityIdsResponse.Merge(dst, src) +func (m *ExecuteEntityIdsResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_ExecuteEntityIdsResponse.Merge(m, src) } func (m *ExecuteEntityIdsResponse) XXX_Size() int { return xxx_messageInfo_ExecuteEntityIdsResponse.Size(m) @@ -1180,16 +1200,17 @@ func (m *ExecuteBatchRequest) Reset() { *m = ExecuteBatchRequest{} } func (m *ExecuteBatchRequest) String() string { return proto.CompactTextString(m) } func (*ExecuteBatchRequest) ProtoMessage() {} func (*ExecuteBatchRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_vtgate_339c92b13a08c8a7, []int{11} + return fileDescriptor_aab96496ceaf1ebb, []int{11} } + func (m *ExecuteBatchRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ExecuteBatchRequest.Unmarshal(m, b) } func (m *ExecuteBatchRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_ExecuteBatchRequest.Marshal(b, m, deterministic) } -func (dst *ExecuteBatchRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_ExecuteBatchRequest.Merge(dst, src) +func (m *ExecuteBatchRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_ExecuteBatchRequest.Merge(m, src) } func (m *ExecuteBatchRequest) XXX_Size() int { return xxx_messageInfo_ExecuteBatchRequest.Size(m) @@ -1268,16 +1289,17 @@ func (m *ExecuteBatchResponse) Reset() { *m = ExecuteBatchResponse{} } func (m *ExecuteBatchResponse) String() string { return proto.CompactTextString(m) } func (*ExecuteBatchResponse) ProtoMessage() {} func (*ExecuteBatchResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_vtgate_339c92b13a08c8a7, []int{12} + return fileDescriptor_aab96496ceaf1ebb, []int{12} } + func (m *ExecuteBatchResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ExecuteBatchResponse.Unmarshal(m, b) } func (m *ExecuteBatchResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_ExecuteBatchResponse.Marshal(b, m, deterministic) } -func (dst *ExecuteBatchResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_ExecuteBatchResponse.Merge(dst, src) +func (m *ExecuteBatchResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_ExecuteBatchResponse.Merge(m, src) } func (m *ExecuteBatchResponse) XXX_Size() int { return xxx_messageInfo_ExecuteBatchResponse.Size(m) @@ -1328,16 +1350,17 @@ func (m *BoundShardQuery) Reset() { *m = BoundShardQuery{} } func (m *BoundShardQuery) String() string { return proto.CompactTextString(m) } func (*BoundShardQuery) ProtoMessage() {} func (*BoundShardQuery) Descriptor() ([]byte, []int) { - return fileDescriptor_vtgate_339c92b13a08c8a7, []int{13} + return fileDescriptor_aab96496ceaf1ebb, []int{13} } + func (m *BoundShardQuery) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_BoundShardQuery.Unmarshal(m, b) } func (m *BoundShardQuery) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_BoundShardQuery.Marshal(b, m, deterministic) } -func (dst *BoundShardQuery) XXX_Merge(src proto.Message) { - xxx_messageInfo_BoundShardQuery.Merge(dst, src) +func (m *BoundShardQuery) XXX_Merge(src proto.Message) { + xxx_messageInfo_BoundShardQuery.Merge(m, src) } func (m *BoundShardQuery) XXX_Size() int { return xxx_messageInfo_BoundShardQuery.Size(m) @@ -1396,16 +1419,17 @@ func (m *ExecuteBatchShardsRequest) Reset() { *m = ExecuteBatchShardsReq func (m *ExecuteBatchShardsRequest) String() string { return proto.CompactTextString(m) } func (*ExecuteBatchShardsRequest) ProtoMessage() {} func (*ExecuteBatchShardsRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_vtgate_339c92b13a08c8a7, []int{14} + return fileDescriptor_aab96496ceaf1ebb, []int{14} } + func (m *ExecuteBatchShardsRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ExecuteBatchShardsRequest.Unmarshal(m, b) } func (m *ExecuteBatchShardsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_ExecuteBatchShardsRequest.Marshal(b, m, deterministic) } -func (dst *ExecuteBatchShardsRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_ExecuteBatchShardsRequest.Merge(dst, src) +func (m *ExecuteBatchShardsRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_ExecuteBatchShardsRequest.Merge(m, src) } func (m *ExecuteBatchShardsRequest) XXX_Size() int { return xxx_messageInfo_ExecuteBatchShardsRequest.Size(m) @@ -1477,16 +1501,17 @@ func (m *ExecuteBatchShardsResponse) Reset() { *m = ExecuteBatchShardsRe func (m *ExecuteBatchShardsResponse) String() string { return proto.CompactTextString(m) } func (*ExecuteBatchShardsResponse) ProtoMessage() {} func (*ExecuteBatchShardsResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_vtgate_339c92b13a08c8a7, []int{15} + return fileDescriptor_aab96496ceaf1ebb, []int{15} } + func (m *ExecuteBatchShardsResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ExecuteBatchShardsResponse.Unmarshal(m, b) } func (m *ExecuteBatchShardsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_ExecuteBatchShardsResponse.Marshal(b, m, deterministic) } -func (dst *ExecuteBatchShardsResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_ExecuteBatchShardsResponse.Merge(dst, src) +func (m *ExecuteBatchShardsResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_ExecuteBatchShardsResponse.Merge(m, src) } func (m *ExecuteBatchShardsResponse) XXX_Size() int { return xxx_messageInfo_ExecuteBatchShardsResponse.Size(m) @@ -1538,16 +1563,17 @@ func (m *BoundKeyspaceIdQuery) Reset() { *m = BoundKeyspaceIdQuery{} } func (m *BoundKeyspaceIdQuery) String() string { return proto.CompactTextString(m) } func (*BoundKeyspaceIdQuery) ProtoMessage() {} func (*BoundKeyspaceIdQuery) Descriptor() ([]byte, []int) { - return fileDescriptor_vtgate_339c92b13a08c8a7, []int{16} + return fileDescriptor_aab96496ceaf1ebb, []int{16} } + func (m *BoundKeyspaceIdQuery) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_BoundKeyspaceIdQuery.Unmarshal(m, b) } func (m *BoundKeyspaceIdQuery) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_BoundKeyspaceIdQuery.Marshal(b, m, deterministic) } -func (dst *BoundKeyspaceIdQuery) XXX_Merge(src proto.Message) { - xxx_messageInfo_BoundKeyspaceIdQuery.Merge(dst, src) +func (m *BoundKeyspaceIdQuery) XXX_Merge(src proto.Message) { + xxx_messageInfo_BoundKeyspaceIdQuery.Merge(m, src) } func (m *BoundKeyspaceIdQuery) XXX_Size() int { return xxx_messageInfo_BoundKeyspaceIdQuery.Size(m) @@ -1605,16 +1631,17 @@ func (m *ExecuteBatchKeyspaceIdsRequest) Reset() { *m = ExecuteBatchKeys func (m *ExecuteBatchKeyspaceIdsRequest) String() string { return proto.CompactTextString(m) } func (*ExecuteBatchKeyspaceIdsRequest) ProtoMessage() {} func (*ExecuteBatchKeyspaceIdsRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_vtgate_339c92b13a08c8a7, []int{17} + return fileDescriptor_aab96496ceaf1ebb, []int{17} } + func (m *ExecuteBatchKeyspaceIdsRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ExecuteBatchKeyspaceIdsRequest.Unmarshal(m, b) } func (m *ExecuteBatchKeyspaceIdsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_ExecuteBatchKeyspaceIdsRequest.Marshal(b, m, deterministic) } -func (dst *ExecuteBatchKeyspaceIdsRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_ExecuteBatchKeyspaceIdsRequest.Merge(dst, src) +func (m *ExecuteBatchKeyspaceIdsRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_ExecuteBatchKeyspaceIdsRequest.Merge(m, src) } func (m *ExecuteBatchKeyspaceIdsRequest) XXX_Size() int { return xxx_messageInfo_ExecuteBatchKeyspaceIdsRequest.Size(m) @@ -1686,16 +1713,17 @@ func (m *ExecuteBatchKeyspaceIdsResponse) Reset() { *m = ExecuteBatchKey func (m *ExecuteBatchKeyspaceIdsResponse) String() string { return proto.CompactTextString(m) } func (*ExecuteBatchKeyspaceIdsResponse) ProtoMessage() {} func (*ExecuteBatchKeyspaceIdsResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_vtgate_339c92b13a08c8a7, []int{18} + return fileDescriptor_aab96496ceaf1ebb, []int{18} } + func (m *ExecuteBatchKeyspaceIdsResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ExecuteBatchKeyspaceIdsResponse.Unmarshal(m, b) } func (m *ExecuteBatchKeyspaceIdsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_ExecuteBatchKeyspaceIdsResponse.Marshal(b, m, deterministic) } -func (dst *ExecuteBatchKeyspaceIdsResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_ExecuteBatchKeyspaceIdsResponse.Merge(dst, src) +func (m *ExecuteBatchKeyspaceIdsResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_ExecuteBatchKeyspaceIdsResponse.Merge(m, src) } func (m *ExecuteBatchKeyspaceIdsResponse) XXX_Size() int { return xxx_messageInfo_ExecuteBatchKeyspaceIdsResponse.Size(m) @@ -1750,16 +1778,17 @@ func (m *StreamExecuteRequest) Reset() { *m = StreamExecuteRequest{} } func (m *StreamExecuteRequest) String() string { return proto.CompactTextString(m) } func (*StreamExecuteRequest) ProtoMessage() {} func (*StreamExecuteRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_vtgate_339c92b13a08c8a7, []int{19} + return fileDescriptor_aab96496ceaf1ebb, []int{19} } + func (m *StreamExecuteRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_StreamExecuteRequest.Unmarshal(m, b) } func (m *StreamExecuteRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_StreamExecuteRequest.Marshal(b, m, deterministic) } -func (dst *StreamExecuteRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_StreamExecuteRequest.Merge(dst, src) +func (m *StreamExecuteRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_StreamExecuteRequest.Merge(m, src) } func (m *StreamExecuteRequest) XXX_Size() int { return xxx_messageInfo_StreamExecuteRequest.Size(m) @@ -1829,16 +1858,17 @@ func (m *StreamExecuteResponse) Reset() { *m = StreamExecuteResponse{} } func (m *StreamExecuteResponse) String() string { return proto.CompactTextString(m) } func (*StreamExecuteResponse) ProtoMessage() {} func (*StreamExecuteResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_vtgate_339c92b13a08c8a7, []int{20} + return fileDescriptor_aab96496ceaf1ebb, []int{20} } + func (m *StreamExecuteResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_StreamExecuteResponse.Unmarshal(m, b) } func (m *StreamExecuteResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_StreamExecuteResponse.Marshal(b, m, deterministic) } -func (dst *StreamExecuteResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_StreamExecuteResponse.Merge(dst, src) +func (m *StreamExecuteResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_StreamExecuteResponse.Merge(m, src) } func (m *StreamExecuteResponse) XXX_Size() int { return xxx_messageInfo_StreamExecuteResponse.Size(m) @@ -1880,16 +1910,17 @@ func (m *StreamExecuteShardsRequest) Reset() { *m = StreamExecuteShardsR func (m *StreamExecuteShardsRequest) String() string { return proto.CompactTextString(m) } func (*StreamExecuteShardsRequest) ProtoMessage() {} func (*StreamExecuteShardsRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_vtgate_339c92b13a08c8a7, []int{21} + return fileDescriptor_aab96496ceaf1ebb, []int{21} } + func (m *StreamExecuteShardsRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_StreamExecuteShardsRequest.Unmarshal(m, b) } func (m *StreamExecuteShardsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_StreamExecuteShardsRequest.Marshal(b, m, deterministic) } -func (dst *StreamExecuteShardsRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_StreamExecuteShardsRequest.Merge(dst, src) +func (m *StreamExecuteShardsRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_StreamExecuteShardsRequest.Merge(m, src) } func (m *StreamExecuteShardsRequest) XXX_Size() int { return xxx_messageInfo_StreamExecuteShardsRequest.Size(m) @@ -1957,16 +1988,17 @@ func (m *StreamExecuteShardsResponse) Reset() { *m = StreamExecuteShards func (m *StreamExecuteShardsResponse) String() string { return proto.CompactTextString(m) } func (*StreamExecuteShardsResponse) ProtoMessage() {} func (*StreamExecuteShardsResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_vtgate_339c92b13a08c8a7, []int{22} + return fileDescriptor_aab96496ceaf1ebb, []int{22} } + func (m *StreamExecuteShardsResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_StreamExecuteShardsResponse.Unmarshal(m, b) } func (m *StreamExecuteShardsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_StreamExecuteShardsResponse.Marshal(b, m, deterministic) } -func (dst *StreamExecuteShardsResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_StreamExecuteShardsResponse.Merge(dst, src) +func (m *StreamExecuteShardsResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_StreamExecuteShardsResponse.Merge(m, src) } func (m *StreamExecuteShardsResponse) XXX_Size() int { return xxx_messageInfo_StreamExecuteShardsResponse.Size(m) @@ -2009,16 +2041,17 @@ func (m *StreamExecuteKeyspaceIdsRequest) Reset() { *m = StreamExecuteKe func (m *StreamExecuteKeyspaceIdsRequest) String() string { return proto.CompactTextString(m) } func (*StreamExecuteKeyspaceIdsRequest) ProtoMessage() {} func (*StreamExecuteKeyspaceIdsRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_vtgate_339c92b13a08c8a7, []int{23} + return fileDescriptor_aab96496ceaf1ebb, []int{23} } + func (m *StreamExecuteKeyspaceIdsRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_StreamExecuteKeyspaceIdsRequest.Unmarshal(m, b) } func (m *StreamExecuteKeyspaceIdsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_StreamExecuteKeyspaceIdsRequest.Marshal(b, m, deterministic) } -func (dst *StreamExecuteKeyspaceIdsRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_StreamExecuteKeyspaceIdsRequest.Merge(dst, src) +func (m *StreamExecuteKeyspaceIdsRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_StreamExecuteKeyspaceIdsRequest.Merge(m, src) } func (m *StreamExecuteKeyspaceIdsRequest) XXX_Size() int { return xxx_messageInfo_StreamExecuteKeyspaceIdsRequest.Size(m) @@ -2086,16 +2119,17 @@ func (m *StreamExecuteKeyspaceIdsResponse) Reset() { *m = StreamExecuteK func (m *StreamExecuteKeyspaceIdsResponse) String() string { return proto.CompactTextString(m) } func (*StreamExecuteKeyspaceIdsResponse) ProtoMessage() {} func (*StreamExecuteKeyspaceIdsResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_vtgate_339c92b13a08c8a7, []int{24} + return fileDescriptor_aab96496ceaf1ebb, []int{24} } + func (m *StreamExecuteKeyspaceIdsResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_StreamExecuteKeyspaceIdsResponse.Unmarshal(m, b) } func (m *StreamExecuteKeyspaceIdsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_StreamExecuteKeyspaceIdsResponse.Marshal(b, m, deterministic) } -func (dst *StreamExecuteKeyspaceIdsResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_StreamExecuteKeyspaceIdsResponse.Merge(dst, src) +func (m *StreamExecuteKeyspaceIdsResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_StreamExecuteKeyspaceIdsResponse.Merge(m, src) } func (m *StreamExecuteKeyspaceIdsResponse) XXX_Size() int { return xxx_messageInfo_StreamExecuteKeyspaceIdsResponse.Size(m) @@ -2138,16 +2172,17 @@ func (m *StreamExecuteKeyRangesRequest) Reset() { *m = StreamExecuteKeyR func (m *StreamExecuteKeyRangesRequest) String() string { return proto.CompactTextString(m) } func (*StreamExecuteKeyRangesRequest) ProtoMessage() {} func (*StreamExecuteKeyRangesRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_vtgate_339c92b13a08c8a7, []int{25} + return fileDescriptor_aab96496ceaf1ebb, []int{25} } + func (m *StreamExecuteKeyRangesRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_StreamExecuteKeyRangesRequest.Unmarshal(m, b) } func (m *StreamExecuteKeyRangesRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_StreamExecuteKeyRangesRequest.Marshal(b, m, deterministic) } -func (dst *StreamExecuteKeyRangesRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_StreamExecuteKeyRangesRequest.Merge(dst, src) +func (m *StreamExecuteKeyRangesRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_StreamExecuteKeyRangesRequest.Merge(m, src) } func (m *StreamExecuteKeyRangesRequest) XXX_Size() int { return xxx_messageInfo_StreamExecuteKeyRangesRequest.Size(m) @@ -2215,16 +2250,17 @@ func (m *StreamExecuteKeyRangesResponse) Reset() { *m = StreamExecuteKey func (m *StreamExecuteKeyRangesResponse) String() string { return proto.CompactTextString(m) } func (*StreamExecuteKeyRangesResponse) ProtoMessage() {} func (*StreamExecuteKeyRangesResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_vtgate_339c92b13a08c8a7, []int{26} + return fileDescriptor_aab96496ceaf1ebb, []int{26} } + func (m *StreamExecuteKeyRangesResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_StreamExecuteKeyRangesResponse.Unmarshal(m, b) } func (m *StreamExecuteKeyRangesResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_StreamExecuteKeyRangesResponse.Marshal(b, m, deterministic) } -func (dst *StreamExecuteKeyRangesResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_StreamExecuteKeyRangesResponse.Merge(dst, src) +func (m *StreamExecuteKeyRangesResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_StreamExecuteKeyRangesResponse.Merge(m, src) } func (m *StreamExecuteKeyRangesResponse) XXX_Size() int { return xxx_messageInfo_StreamExecuteKeyRangesResponse.Size(m) @@ -2261,16 +2297,17 @@ func (m *BeginRequest) Reset() { *m = BeginRequest{} } func (m *BeginRequest) String() string { return proto.CompactTextString(m) } func (*BeginRequest) ProtoMessage() {} func (*BeginRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_vtgate_339c92b13a08c8a7, []int{27} + return fileDescriptor_aab96496ceaf1ebb, []int{27} } + func (m *BeginRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_BeginRequest.Unmarshal(m, b) } func (m *BeginRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_BeginRequest.Marshal(b, m, deterministic) } -func (dst *BeginRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_BeginRequest.Merge(dst, src) +func (m *BeginRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_BeginRequest.Merge(m, src) } func (m *BeginRequest) XXX_Size() int { return xxx_messageInfo_BeginRequest.Size(m) @@ -2308,16 +2345,17 @@ func (m *BeginResponse) Reset() { *m = BeginResponse{} } func (m *BeginResponse) String() string { return proto.CompactTextString(m) } func (*BeginResponse) ProtoMessage() {} func (*BeginResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_vtgate_339c92b13a08c8a7, []int{28} + return fileDescriptor_aab96496ceaf1ebb, []int{28} } + func (m *BeginResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_BeginResponse.Unmarshal(m, b) } func (m *BeginResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_BeginResponse.Marshal(b, m, deterministic) } -func (dst *BeginResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_BeginResponse.Merge(dst, src) +func (m *BeginResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_BeginResponse.Merge(m, src) } func (m *BeginResponse) XXX_Size() int { return xxx_messageInfo_BeginResponse.Size(m) @@ -2356,16 +2394,17 @@ func (m *CommitRequest) Reset() { *m = CommitRequest{} } func (m *CommitRequest) String() string { return proto.CompactTextString(m) } func (*CommitRequest) ProtoMessage() {} func (*CommitRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_vtgate_339c92b13a08c8a7, []int{29} + return fileDescriptor_aab96496ceaf1ebb, []int{29} } + func (m *CommitRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_CommitRequest.Unmarshal(m, b) } func (m *CommitRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_CommitRequest.Marshal(b, m, deterministic) } -func (dst *CommitRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_CommitRequest.Merge(dst, src) +func (m *CommitRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_CommitRequest.Merge(m, src) } func (m *CommitRequest) XXX_Size() int { return xxx_messageInfo_CommitRequest.Size(m) @@ -2408,16 +2447,17 @@ func (m *CommitResponse) Reset() { *m = CommitResponse{} } func (m *CommitResponse) String() string { return proto.CompactTextString(m) } func (*CommitResponse) ProtoMessage() {} func (*CommitResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_vtgate_339c92b13a08c8a7, []int{30} + return fileDescriptor_aab96496ceaf1ebb, []int{30} } + func (m *CommitResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_CommitResponse.Unmarshal(m, b) } func (m *CommitResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_CommitResponse.Marshal(b, m, deterministic) } -func (dst *CommitResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_CommitResponse.Merge(dst, src) +func (m *CommitResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_CommitResponse.Merge(m, src) } func (m *CommitResponse) XXX_Size() int { return xxx_messageInfo_CommitResponse.Size(m) @@ -2444,16 +2484,17 @@ func (m *RollbackRequest) Reset() { *m = RollbackRequest{} } func (m *RollbackRequest) String() string { return proto.CompactTextString(m) } func (*RollbackRequest) ProtoMessage() {} func (*RollbackRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_vtgate_339c92b13a08c8a7, []int{31} + return fileDescriptor_aab96496ceaf1ebb, []int{31} } + func (m *RollbackRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_RollbackRequest.Unmarshal(m, b) } func (m *RollbackRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_RollbackRequest.Marshal(b, m, deterministic) } -func (dst *RollbackRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_RollbackRequest.Merge(dst, src) +func (m *RollbackRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_RollbackRequest.Merge(m, src) } func (m *RollbackRequest) XXX_Size() int { return xxx_messageInfo_RollbackRequest.Size(m) @@ -2489,16 +2530,17 @@ func (m *RollbackResponse) Reset() { *m = RollbackResponse{} } func (m *RollbackResponse) String() string { return proto.CompactTextString(m) } func (*RollbackResponse) ProtoMessage() {} func (*RollbackResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_vtgate_339c92b13a08c8a7, []int{32} + return fileDescriptor_aab96496ceaf1ebb, []int{32} } + func (m *RollbackResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_RollbackResponse.Unmarshal(m, b) } func (m *RollbackResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_RollbackResponse.Marshal(b, m, deterministic) } -func (dst *RollbackResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_RollbackResponse.Merge(dst, src) +func (m *RollbackResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_RollbackResponse.Merge(m, src) } func (m *RollbackResponse) XXX_Size() int { return xxx_messageInfo_RollbackResponse.Size(m) @@ -2525,16 +2567,17 @@ func (m *ResolveTransactionRequest) Reset() { *m = ResolveTransactionReq func (m *ResolveTransactionRequest) String() string { return proto.CompactTextString(m) } func (*ResolveTransactionRequest) ProtoMessage() {} func (*ResolveTransactionRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_vtgate_339c92b13a08c8a7, []int{33} + return fileDescriptor_aab96496ceaf1ebb, []int{33} } + func (m *ResolveTransactionRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ResolveTransactionRequest.Unmarshal(m, b) } func (m *ResolveTransactionRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_ResolveTransactionRequest.Marshal(b, m, deterministic) } -func (dst *ResolveTransactionRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_ResolveTransactionRequest.Merge(dst, src) +func (m *ResolveTransactionRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_ResolveTransactionRequest.Merge(m, src) } func (m *ResolveTransactionRequest) XXX_Size() int { return xxx_messageInfo_ResolveTransactionRequest.Size(m) @@ -2581,16 +2624,17 @@ func (m *MessageStreamRequest) Reset() { *m = MessageStreamRequest{} } func (m *MessageStreamRequest) String() string { return proto.CompactTextString(m) } func (*MessageStreamRequest) ProtoMessage() {} func (*MessageStreamRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_vtgate_339c92b13a08c8a7, []int{34} + return fileDescriptor_aab96496ceaf1ebb, []int{34} } + func (m *MessageStreamRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_MessageStreamRequest.Unmarshal(m, b) } func (m *MessageStreamRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_MessageStreamRequest.Marshal(b, m, deterministic) } -func (dst *MessageStreamRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_MessageStreamRequest.Merge(dst, src) +func (m *MessageStreamRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_MessageStreamRequest.Merge(m, src) } func (m *MessageStreamRequest) XXX_Size() int { return xxx_messageInfo_MessageStreamRequest.Size(m) @@ -2656,16 +2700,17 @@ func (m *MessageAckRequest) Reset() { *m = MessageAckRequest{} } func (m *MessageAckRequest) String() string { return proto.CompactTextString(m) } func (*MessageAckRequest) ProtoMessage() {} func (*MessageAckRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_vtgate_339c92b13a08c8a7, []int{35} + return fileDescriptor_aab96496ceaf1ebb, []int{35} } + func (m *MessageAckRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_MessageAckRequest.Unmarshal(m, b) } func (m *MessageAckRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_MessageAckRequest.Marshal(b, m, deterministic) } -func (dst *MessageAckRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_MessageAckRequest.Merge(dst, src) +func (m *MessageAckRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_MessageAckRequest.Merge(m, src) } func (m *MessageAckRequest) XXX_Size() int { return xxx_messageInfo_MessageAckRequest.Size(m) @@ -2720,16 +2765,17 @@ func (m *IdKeyspaceId) Reset() { *m = IdKeyspaceId{} } func (m *IdKeyspaceId) String() string { return proto.CompactTextString(m) } func (*IdKeyspaceId) ProtoMessage() {} func (*IdKeyspaceId) Descriptor() ([]byte, []int) { - return fileDescriptor_vtgate_339c92b13a08c8a7, []int{36} + return fileDescriptor_aab96496ceaf1ebb, []int{36} } + func (m *IdKeyspaceId) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_IdKeyspaceId.Unmarshal(m, b) } func (m *IdKeyspaceId) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_IdKeyspaceId.Marshal(b, m, deterministic) } -func (dst *IdKeyspaceId) XXX_Merge(src proto.Message) { - xxx_messageInfo_IdKeyspaceId.Merge(dst, src) +func (m *IdKeyspaceId) XXX_Merge(src proto.Message) { + xxx_messageInfo_IdKeyspaceId.Merge(m, src) } func (m *IdKeyspaceId) XXX_Size() int { return xxx_messageInfo_IdKeyspaceId.Size(m) @@ -2773,16 +2819,17 @@ func (m *MessageAckKeyspaceIdsRequest) Reset() { *m = MessageAckKeyspace func (m *MessageAckKeyspaceIdsRequest) String() string { return proto.CompactTextString(m) } func (*MessageAckKeyspaceIdsRequest) ProtoMessage() {} func (*MessageAckKeyspaceIdsRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_vtgate_339c92b13a08c8a7, []int{37} + return fileDescriptor_aab96496ceaf1ebb, []int{37} } + func (m *MessageAckKeyspaceIdsRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_MessageAckKeyspaceIdsRequest.Unmarshal(m, b) } func (m *MessageAckKeyspaceIdsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_MessageAckKeyspaceIdsRequest.Marshal(b, m, deterministic) } -func (dst *MessageAckKeyspaceIdsRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_MessageAckKeyspaceIdsRequest.Merge(dst, src) +func (m *MessageAckKeyspaceIdsRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_MessageAckKeyspaceIdsRequest.Merge(m, src) } func (m *MessageAckKeyspaceIdsRequest) XXX_Size() int { return xxx_messageInfo_MessageAckKeyspaceIdsRequest.Size(m) @@ -2832,16 +2879,17 @@ func (m *ResolveTransactionResponse) Reset() { *m = ResolveTransactionRe func (m *ResolveTransactionResponse) String() string { return proto.CompactTextString(m) } func (*ResolveTransactionResponse) ProtoMessage() {} func (*ResolveTransactionResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_vtgate_339c92b13a08c8a7, []int{38} + return fileDescriptor_aab96496ceaf1ebb, []int{38} } + func (m *ResolveTransactionResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ResolveTransactionResponse.Unmarshal(m, b) } func (m *ResolveTransactionResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_ResolveTransactionResponse.Marshal(b, m, deterministic) } -func (dst *ResolveTransactionResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_ResolveTransactionResponse.Merge(dst, src) +func (m *ResolveTransactionResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_ResolveTransactionResponse.Merge(m, src) } func (m *ResolveTransactionResponse) XXX_Size() int { return xxx_messageInfo_ResolveTransactionResponse.Size(m) @@ -2950,16 +2998,17 @@ func (m *SplitQueryRequest) Reset() { *m = SplitQueryRequest{} } func (m *SplitQueryRequest) String() string { return proto.CompactTextString(m) } func (*SplitQueryRequest) ProtoMessage() {} func (*SplitQueryRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_vtgate_339c92b13a08c8a7, []int{39} + return fileDescriptor_aab96496ceaf1ebb, []int{39} } + func (m *SplitQueryRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_SplitQueryRequest.Unmarshal(m, b) } func (m *SplitQueryRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_SplitQueryRequest.Marshal(b, m, deterministic) } -func (dst *SplitQueryRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_SplitQueryRequest.Merge(dst, src) +func (m *SplitQueryRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_SplitQueryRequest.Merge(m, src) } func (m *SplitQueryRequest) XXX_Size() int { return xxx_messageInfo_SplitQueryRequest.Size(m) @@ -3039,16 +3088,17 @@ func (m *SplitQueryResponse) Reset() { *m = SplitQueryResponse{} } func (m *SplitQueryResponse) String() string { return proto.CompactTextString(m) } func (*SplitQueryResponse) ProtoMessage() {} func (*SplitQueryResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_vtgate_339c92b13a08c8a7, []int{40} + return fileDescriptor_aab96496ceaf1ebb, []int{40} } + func (m *SplitQueryResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_SplitQueryResponse.Unmarshal(m, b) } func (m *SplitQueryResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_SplitQueryResponse.Marshal(b, m, deterministic) } -func (dst *SplitQueryResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_SplitQueryResponse.Merge(dst, src) +func (m *SplitQueryResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_SplitQueryResponse.Merge(m, src) } func (m *SplitQueryResponse) XXX_Size() int { return xxx_messageInfo_SplitQueryResponse.Size(m) @@ -3080,16 +3130,17 @@ func (m *SplitQueryResponse_KeyRangePart) Reset() { *m = SplitQueryRespo func (m *SplitQueryResponse_KeyRangePart) String() string { return proto.CompactTextString(m) } func (*SplitQueryResponse_KeyRangePart) ProtoMessage() {} func (*SplitQueryResponse_KeyRangePart) Descriptor() ([]byte, []int) { - return fileDescriptor_vtgate_339c92b13a08c8a7, []int{40, 0} + return fileDescriptor_aab96496ceaf1ebb, []int{40, 0} } + func (m *SplitQueryResponse_KeyRangePart) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_SplitQueryResponse_KeyRangePart.Unmarshal(m, b) } func (m *SplitQueryResponse_KeyRangePart) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_SplitQueryResponse_KeyRangePart.Marshal(b, m, deterministic) } -func (dst *SplitQueryResponse_KeyRangePart) XXX_Merge(src proto.Message) { - xxx_messageInfo_SplitQueryResponse_KeyRangePart.Merge(dst, src) +func (m *SplitQueryResponse_KeyRangePart) XXX_Merge(src proto.Message) { + xxx_messageInfo_SplitQueryResponse_KeyRangePart.Merge(m, src) } func (m *SplitQueryResponse_KeyRangePart) XXX_Size() int { return xxx_messageInfo_SplitQueryResponse_KeyRangePart.Size(m) @@ -3128,16 +3179,17 @@ func (m *SplitQueryResponse_ShardPart) Reset() { *m = SplitQueryResponse func (m *SplitQueryResponse_ShardPart) String() string { return proto.CompactTextString(m) } func (*SplitQueryResponse_ShardPart) ProtoMessage() {} func (*SplitQueryResponse_ShardPart) Descriptor() ([]byte, []int) { - return fileDescriptor_vtgate_339c92b13a08c8a7, []int{40, 1} + return fileDescriptor_aab96496ceaf1ebb, []int{40, 1} } + func (m *SplitQueryResponse_ShardPart) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_SplitQueryResponse_ShardPart.Unmarshal(m, b) } func (m *SplitQueryResponse_ShardPart) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_SplitQueryResponse_ShardPart.Marshal(b, m, deterministic) } -func (dst *SplitQueryResponse_ShardPart) XXX_Merge(src proto.Message) { - xxx_messageInfo_SplitQueryResponse_ShardPart.Merge(dst, src) +func (m *SplitQueryResponse_ShardPart) XXX_Merge(src proto.Message) { + xxx_messageInfo_SplitQueryResponse_ShardPart.Merge(m, src) } func (m *SplitQueryResponse_ShardPart) XXX_Size() int { return xxx_messageInfo_SplitQueryResponse_ShardPart.Size(m) @@ -3181,16 +3233,17 @@ func (m *SplitQueryResponse_Part) Reset() { *m = SplitQueryResponse_Part func (m *SplitQueryResponse_Part) String() string { return proto.CompactTextString(m) } func (*SplitQueryResponse_Part) ProtoMessage() {} func (*SplitQueryResponse_Part) Descriptor() ([]byte, []int) { - return fileDescriptor_vtgate_339c92b13a08c8a7, []int{40, 2} + return fileDescriptor_aab96496ceaf1ebb, []int{40, 2} } + func (m *SplitQueryResponse_Part) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_SplitQueryResponse_Part.Unmarshal(m, b) } func (m *SplitQueryResponse_Part) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_SplitQueryResponse_Part.Marshal(b, m, deterministic) } -func (dst *SplitQueryResponse_Part) XXX_Merge(src proto.Message) { - xxx_messageInfo_SplitQueryResponse_Part.Merge(dst, src) +func (m *SplitQueryResponse_Part) XXX_Merge(src proto.Message) { + xxx_messageInfo_SplitQueryResponse_Part.Merge(m, src) } func (m *SplitQueryResponse_Part) XXX_Size() int { return xxx_messageInfo_SplitQueryResponse_Part.Size(m) @@ -3242,16 +3295,17 @@ func (m *GetSrvKeyspaceRequest) Reset() { *m = GetSrvKeyspaceRequest{} } func (m *GetSrvKeyspaceRequest) String() string { return proto.CompactTextString(m) } func (*GetSrvKeyspaceRequest) ProtoMessage() {} func (*GetSrvKeyspaceRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_vtgate_339c92b13a08c8a7, []int{41} + return fileDescriptor_aab96496ceaf1ebb, []int{41} } + func (m *GetSrvKeyspaceRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_GetSrvKeyspaceRequest.Unmarshal(m, b) } func (m *GetSrvKeyspaceRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_GetSrvKeyspaceRequest.Marshal(b, m, deterministic) } -func (dst *GetSrvKeyspaceRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_GetSrvKeyspaceRequest.Merge(dst, src) +func (m *GetSrvKeyspaceRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_GetSrvKeyspaceRequest.Merge(m, src) } func (m *GetSrvKeyspaceRequest) XXX_Size() int { return xxx_messageInfo_GetSrvKeyspaceRequest.Size(m) @@ -3282,16 +3336,17 @@ func (m *GetSrvKeyspaceResponse) Reset() { *m = GetSrvKeyspaceResponse{} func (m *GetSrvKeyspaceResponse) String() string { return proto.CompactTextString(m) } func (*GetSrvKeyspaceResponse) ProtoMessage() {} func (*GetSrvKeyspaceResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_vtgate_339c92b13a08c8a7, []int{42} + return fileDescriptor_aab96496ceaf1ebb, []int{42} } + func (m *GetSrvKeyspaceResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_GetSrvKeyspaceResponse.Unmarshal(m, b) } func (m *GetSrvKeyspaceResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_GetSrvKeyspaceResponse.Marshal(b, m, deterministic) } -func (dst *GetSrvKeyspaceResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_GetSrvKeyspaceResponse.Merge(dst, src) +func (m *GetSrvKeyspaceResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_GetSrvKeyspaceResponse.Merge(m, src) } func (m *GetSrvKeyspaceResponse) XXX_Size() int { return xxx_messageInfo_GetSrvKeyspaceResponse.Size(m) @@ -3327,16 +3382,17 @@ func (m *VStreamRequest) Reset() { *m = VStreamRequest{} } func (m *VStreamRequest) String() string { return proto.CompactTextString(m) } func (*VStreamRequest) ProtoMessage() {} func (*VStreamRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_vtgate_339c92b13a08c8a7, []int{43} + return fileDescriptor_aab96496ceaf1ebb, []int{43} } + func (m *VStreamRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_VStreamRequest.Unmarshal(m, b) } func (m *VStreamRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_VStreamRequest.Marshal(b, m, deterministic) } -func (dst *VStreamRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_VStreamRequest.Merge(dst, src) +func (m *VStreamRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_VStreamRequest.Merge(m, src) } func (m *VStreamRequest) XXX_Size() int { return xxx_messageInfo_VStreamRequest.Size(m) @@ -3387,16 +3443,17 @@ func (m *VStreamResponse) Reset() { *m = VStreamResponse{} } func (m *VStreamResponse) String() string { return proto.CompactTextString(m) } func (*VStreamResponse) ProtoMessage() {} func (*VStreamResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_vtgate_339c92b13a08c8a7, []int{44} + return fileDescriptor_aab96496ceaf1ebb, []int{44} } + func (m *VStreamResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_VStreamResponse.Unmarshal(m, b) } func (m *VStreamResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_VStreamResponse.Marshal(b, m, deterministic) } -func (dst *VStreamResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_VStreamResponse.Merge(dst, src) +func (m *VStreamResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_VStreamResponse.Merge(m, src) } func (m *VStreamResponse) XXX_Size() int { return xxx_messageInfo_VStreamResponse.Size(m) @@ -3445,16 +3502,17 @@ func (m *UpdateStreamRequest) Reset() { *m = UpdateStreamRequest{} } func (m *UpdateStreamRequest) String() string { return proto.CompactTextString(m) } func (*UpdateStreamRequest) ProtoMessage() {} func (*UpdateStreamRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_vtgate_339c92b13a08c8a7, []int{45} + return fileDescriptor_aab96496ceaf1ebb, []int{45} } + func (m *UpdateStreamRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_UpdateStreamRequest.Unmarshal(m, b) } func (m *UpdateStreamRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_UpdateStreamRequest.Marshal(b, m, deterministic) } -func (dst *UpdateStreamRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_UpdateStreamRequest.Merge(dst, src) +func (m *UpdateStreamRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_UpdateStreamRequest.Merge(m, src) } func (m *UpdateStreamRequest) XXX_Size() int { return xxx_messageInfo_UpdateStreamRequest.Size(m) @@ -3533,16 +3591,17 @@ func (m *UpdateStreamResponse) Reset() { *m = UpdateStreamResponse{} } func (m *UpdateStreamResponse) String() string { return proto.CompactTextString(m) } func (*UpdateStreamResponse) ProtoMessage() {} func (*UpdateStreamResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_vtgate_339c92b13a08c8a7, []int{46} + return fileDescriptor_aab96496ceaf1ebb, []int{46} } + func (m *UpdateStreamResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_UpdateStreamResponse.Unmarshal(m, b) } func (m *UpdateStreamResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_UpdateStreamResponse.Marshal(b, m, deterministic) } -func (dst *UpdateStreamResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_UpdateStreamResponse.Merge(dst, src) +func (m *UpdateStreamResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_UpdateStreamResponse.Merge(m, src) } func (m *UpdateStreamResponse) XXX_Size() int { return xxx_messageInfo_UpdateStreamResponse.Size(m) @@ -3568,6 +3627,8 @@ func (m *UpdateStreamResponse) GetResumeTimestamp() int64 { } func init() { + proto.RegisterEnum("vtgate.TransactionMode", TransactionMode_name, TransactionMode_value) + proto.RegisterEnum("vtgate.CommitOrder", CommitOrder_name, CommitOrder_value) proto.RegisterType((*Session)(nil), "vtgate.Session") proto.RegisterType((*Session_ShardSession)(nil), "vtgate.Session.ShardSession") proto.RegisterType((*ExecuteRequest)(nil), "vtgate.ExecuteRequest") @@ -3620,13 +3681,11 @@ func init() { proto.RegisterType((*VStreamResponse)(nil), "vtgate.VStreamResponse") proto.RegisterType((*UpdateStreamRequest)(nil), "vtgate.UpdateStreamRequest") proto.RegisterType((*UpdateStreamResponse)(nil), "vtgate.UpdateStreamResponse") - proto.RegisterEnum("vtgate.TransactionMode", TransactionMode_name, TransactionMode_value) - proto.RegisterEnum("vtgate.CommitOrder", CommitOrder_name, CommitOrder_value) } -func init() { proto.RegisterFile("vtgate.proto", fileDescriptor_vtgate_339c92b13a08c8a7) } +func init() { proto.RegisterFile("vtgate.proto", fileDescriptor_aab96496ceaf1ebb) } -var fileDescriptor_vtgate_339c92b13a08c8a7 = []byte{ +var fileDescriptor_aab96496ceaf1ebb = []byte{ // 2041 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x5a, 0xcd, 0x8f, 0x23, 0x47, 0x15, 0x4f, 0x77, 0xfb, 0xf3, 0xf9, 0x73, 0x6b, 0xbc, 0x1b, 0xc7, 0x19, 0x76, 0x26, 0x1d, 0x46, diff --git a/go/vt/proto/vtgateservice/vtgateservice.pb.go b/go/vt/proto/vtgateservice/vtgateservice.pb.go index 73b93cde931..2f82480284e 100644 --- a/go/vt/proto/vtgateservice/vtgateservice.pb.go +++ b/go/vt/proto/vtgateservice/vtgateservice.pb.go @@ -1,17 +1,19 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // source: vtgateservice.proto -package vtgateservice // import "vitess.io/vitess/go/vt/proto/vtgateservice" - -import proto "github.com/golang/protobuf/proto" -import fmt "fmt" -import math "math" -import query "vitess.io/vitess/go/vt/proto/query" -import vtgate "vitess.io/vitess/go/vt/proto/vtgate" +package vtgateservice import ( - context "golang.org/x/net/context" + context "context" + fmt "fmt" + math "math" + + proto "github.com/golang/protobuf/proto" grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + query "vitess.io/vitess/go/vt/proto/query" + vtgate "vitess.io/vitess/go/vt/proto/vtgate" ) // Reference imports to suppress errors if they are not otherwise used. @@ -23,7 +25,51 @@ var _ = math.Inf // is compatible with the proto package it is being compiled against. // A compilation error at this line likely means your copy of the // proto package needs to be updated. -const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package +const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package + +func init() { proto.RegisterFile("vtgateservice.proto", fileDescriptor_601ae27c95081e0f) } + +var fileDescriptor_601ae27c95081e0f = []byte{ + // 594 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x95, 0x5f, 0x6f, 0xd3, 0x30, + 0x14, 0xc5, 0xe1, 0x81, 0x0e, 0x5d, 0x5a, 0x40, 0xde, 0xd6, 0x6e, 0xe5, 0xef, 0x0a, 0x6c, 0x88, + 0x87, 0x16, 0x81, 0x84, 0x84, 0x84, 0x40, 0x2d, 0x54, 0x08, 0x4d, 0x03, 0xd6, 0x42, 0x91, 0x26, + 0xf1, 0xe0, 0xa6, 0x57, 0x59, 0xd4, 0x36, 0x49, 0x63, 0x37, 0xa2, 0x5f, 0x80, 0xcf, 0x3d, 0x2d, + 0xb1, 0x1d, 0xdb, 0x71, 0xdb, 0xb7, 0xe4, 0x9c, 0xe3, 0x9f, 0xed, 0xeb, 0x2b, 0x1b, 0x76, 0x53, + 0xee, 0x53, 0x8e, 0x0c, 0x93, 0x34, 0xf0, 0xb0, 0x1d, 0x27, 0x11, 0x8f, 0x48, 0xcd, 0x10, 0x9b, + 0xd5, 0xfc, 0x37, 0x37, 0x9b, 0x77, 0x16, 0x4b, 0x4c, 0x56, 0xf9, 0xcf, 0x9b, 0xff, 0xf7, 0xa0, + 0x32, 0x0a, 0x38, 0x32, 0x46, 0x3e, 0xc0, 0x4e, 0xff, 0x1f, 0x7a, 0x4b, 0x8e, 0xa4, 0xde, 0x16, + 0x23, 0x84, 0x30, 0xc0, 0xc5, 0x12, 0x19, 0x6f, 0x36, 0x4a, 0x3a, 0x8b, 0xa3, 0x90, 0x61, 0xeb, + 0x06, 0x39, 0x85, 0xaa, 0x10, 0x7b, 0x94, 0x7b, 0x97, 0xe4, 0x81, 0x15, 0xcd, 0x54, 0xc9, 0x79, + 0xe8, 0x36, 0x15, 0xec, 0x27, 0xd4, 0x86, 0x3c, 0x41, 0x3a, 0x97, 0x0b, 0x52, 0x03, 0x0c, 0x59, + 0xe2, 0x1e, 0xad, 0x71, 0x25, 0xef, 0xf5, 0x4d, 0xf2, 0x1d, 0x6a, 0x42, 0x1e, 0x5e, 0xd2, 0x64, + 0xc2, 0x88, 0xbd, 0x84, 0x5c, 0x2e, 0x11, 0x2d, 0x57, 0xad, 0xf0, 0x2f, 0x10, 0x61, 0x9d, 0xe2, + 0x8a, 0xc5, 0xd4, 0xc3, 0x6f, 0x13, 0x46, 0x8e, 0xac, 0x61, 0x9a, 0x27, 0xc9, 0xad, 0x4d, 0x11, + 0x85, 0xff, 0x03, 0xf7, 0x0b, 0x7f, 0x40, 0x43, 0x1f, 0x19, 0x79, 0x52, 0x1e, 0x99, 0x3b, 0x12, + 0xfd, 0x74, 0x7d, 0xc0, 0x01, 0xee, 0x87, 0x3c, 0xe0, 0xab, 0xeb, 0x55, 0xdb, 0x60, 0xe5, 0xac, + 0x03, 0x6b, 0x01, 0x47, 0x41, 0xb2, 0xc3, 0x14, 0x55, 0x3e, 0x72, 0x1d, 0xb4, 0x59, 0xea, 0xd6, + 0xa6, 0x88, 0xc2, 0xcf, 0xa0, 0xa1, 0xfb, 0x7a, 0xd1, 0x8f, 0x5d, 0x00, 0x47, 0xe5, 0x4f, 0xb6, + 0xe6, 0xd4, 0x6c, 0x63, 0xd8, 0x35, 0x5a, 0x49, 0xec, 0xa6, 0xe5, 0xec, 0x33, 0x73, 0x3b, 0xcf, + 0x36, 0x66, 0xb4, 0x8e, 0x5c, 0xc0, 0x81, 0x11, 0xd1, 0xb7, 0x74, 0xe2, 0x84, 0x38, 0xf6, 0xf4, + 0x72, 0x7b, 0x50, 0x9b, 0x72, 0x0a, 0x75, 0x3b, 0x27, 0x7a, 0xeb, 0xc5, 0x3a, 0x8e, 0xd9, 0x61, + 0xc7, 0xdb, 0x62, 0xda, 0x64, 0xef, 0xe0, 0x56, 0x0f, 0xfd, 0x20, 0x24, 0x7b, 0x72, 0x50, 0xf6, + 0x2b, 0x51, 0xfb, 0x96, 0xaa, 0x6a, 0xff, 0x1e, 0x2a, 0x9f, 0xa3, 0xf9, 0x3c, 0xe0, 0x44, 0x45, + 0xf2, 0x7f, 0x39, 0xb2, 0x6e, 0xcb, 0x6a, 0xe8, 0x27, 0xb8, 0x3d, 0x88, 0x66, 0xb3, 0x31, 0xf5, + 0xa6, 0x44, 0x5d, 0x55, 0x52, 0x91, 0xc3, 0x0f, 0xca, 0x86, 0xde, 0xc4, 0x03, 0x64, 0xd1, 0x2c, + 0xc5, 0x5f, 0x09, 0x0d, 0x19, 0xf5, 0x78, 0x10, 0x85, 0x45, 0x13, 0x97, 0xbd, 0x52, 0x13, 0xbb, + 0x22, 0x0a, 0xff, 0x03, 0x6a, 0x67, 0xc8, 0x18, 0xf5, 0x31, 0xaf, 0x5f, 0x71, 0x09, 0x19, 0x72, + 0x71, 0x4b, 0xe6, 0x37, 0xb5, 0x65, 0x6a, 0x35, 0xfe, 0x02, 0x20, 0xcc, 0xae, 0x37, 0x25, 0x87, + 0x16, 0xad, 0x5b, 0x6c, 0xfa, 0xd0, 0x44, 0x75, 0x8d, 0x5d, 0x5f, 0xc0, 0x7e, 0xa1, 0xeb, 0x6d, + 0xf8, 0xbc, 0x0c, 0x74, 0xf4, 0xe0, 0x46, 0x76, 0x1f, 0x60, 0x18, 0xcf, 0x02, 0x7e, 0x7e, 0x1d, + 0x29, 0x56, 0x58, 0x68, 0x92, 0xd2, 0x74, 0x59, 0x0a, 0x73, 0x0e, 0x77, 0xbf, 0x22, 0x1f, 0x26, + 0xa9, 0x9c, 0x9f, 0xa8, 0x1b, 0xda, 0xd4, 0x25, 0xee, 0xf1, 0x3a, 0x5b, 0x21, 0x3f, 0xc2, 0xce, + 0x48, 0x1c, 0x83, 0xea, 0xa8, 0x91, 0x79, 0x00, 0x8d, 0x92, 0xae, 0xd5, 0xfe, 0x0c, 0xaa, 0xbf, + 0xe3, 0x09, 0xe5, 0xf2, 0x2c, 0xd5, 0x83, 0xa7, 0xab, 0xa5, 0x07, 0xcf, 0x34, 0x0b, 0x5c, 0xaf, + 0x07, 0x7b, 0x41, 0xd4, 0x4e, 0xb3, 0xa7, 0x38, 0x7f, 0x9b, 0xdb, 0x7e, 0x12, 0x7b, 0x17, 0xaf, + 0x84, 0x14, 0x44, 0x9d, 0xfc, 0xab, 0xe3, 0x47, 0x9d, 0x94, 0x77, 0xb2, 0x48, 0xc7, 0x78, 0xe7, + 0xc7, 0x95, 0x4c, 0x7c, 0x7b, 0x15, 0x00, 0x00, 0xff, 0xff, 0x98, 0xf7, 0xf0, 0x85, 0x14, 0x08, + 0x00, 0x00, +} // Reference imports to suppress errors if they are not otherwise used. var _ context.Context @@ -583,6 +629,80 @@ type VitessServer interface { UpdateStream(*vtgate.UpdateStreamRequest, Vitess_UpdateStreamServer) error } +// UnimplementedVitessServer can be embedded to have forward compatible implementations. +type UnimplementedVitessServer struct { +} + +func (*UnimplementedVitessServer) Execute(ctx context.Context, req *vtgate.ExecuteRequest) (*vtgate.ExecuteResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Execute not implemented") +} +func (*UnimplementedVitessServer) ExecuteBatch(ctx context.Context, req *vtgate.ExecuteBatchRequest) (*vtgate.ExecuteBatchResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ExecuteBatch not implemented") +} +func (*UnimplementedVitessServer) StreamExecute(req *vtgate.StreamExecuteRequest, srv Vitess_StreamExecuteServer) error { + return status.Errorf(codes.Unimplemented, "method StreamExecute not implemented") +} +func (*UnimplementedVitessServer) ExecuteShards(ctx context.Context, req *vtgate.ExecuteShardsRequest) (*vtgate.ExecuteShardsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ExecuteShards not implemented") +} +func (*UnimplementedVitessServer) ExecuteKeyspaceIds(ctx context.Context, req *vtgate.ExecuteKeyspaceIdsRequest) (*vtgate.ExecuteKeyspaceIdsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ExecuteKeyspaceIds not implemented") +} +func (*UnimplementedVitessServer) ExecuteKeyRanges(ctx context.Context, req *vtgate.ExecuteKeyRangesRequest) (*vtgate.ExecuteKeyRangesResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ExecuteKeyRanges not implemented") +} +func (*UnimplementedVitessServer) ExecuteEntityIds(ctx context.Context, req *vtgate.ExecuteEntityIdsRequest) (*vtgate.ExecuteEntityIdsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ExecuteEntityIds not implemented") +} +func (*UnimplementedVitessServer) ExecuteBatchShards(ctx context.Context, req *vtgate.ExecuteBatchShardsRequest) (*vtgate.ExecuteBatchShardsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ExecuteBatchShards not implemented") +} +func (*UnimplementedVitessServer) ExecuteBatchKeyspaceIds(ctx context.Context, req *vtgate.ExecuteBatchKeyspaceIdsRequest) (*vtgate.ExecuteBatchKeyspaceIdsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ExecuteBatchKeyspaceIds not implemented") +} +func (*UnimplementedVitessServer) StreamExecuteShards(req *vtgate.StreamExecuteShardsRequest, srv Vitess_StreamExecuteShardsServer) error { + return status.Errorf(codes.Unimplemented, "method StreamExecuteShards not implemented") +} +func (*UnimplementedVitessServer) StreamExecuteKeyspaceIds(req *vtgate.StreamExecuteKeyspaceIdsRequest, srv Vitess_StreamExecuteKeyspaceIdsServer) error { + return status.Errorf(codes.Unimplemented, "method StreamExecuteKeyspaceIds not implemented") +} +func (*UnimplementedVitessServer) StreamExecuteKeyRanges(req *vtgate.StreamExecuteKeyRangesRequest, srv Vitess_StreamExecuteKeyRangesServer) error { + return status.Errorf(codes.Unimplemented, "method StreamExecuteKeyRanges not implemented") +} +func (*UnimplementedVitessServer) Begin(ctx context.Context, req *vtgate.BeginRequest) (*vtgate.BeginResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Begin not implemented") +} +func (*UnimplementedVitessServer) Commit(ctx context.Context, req *vtgate.CommitRequest) (*vtgate.CommitResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Commit not implemented") +} +func (*UnimplementedVitessServer) Rollback(ctx context.Context, req *vtgate.RollbackRequest) (*vtgate.RollbackResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Rollback not implemented") +} +func (*UnimplementedVitessServer) ResolveTransaction(ctx context.Context, req *vtgate.ResolveTransactionRequest) (*vtgate.ResolveTransactionResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ResolveTransaction not implemented") +} +func (*UnimplementedVitessServer) MessageStream(req *vtgate.MessageStreamRequest, srv Vitess_MessageStreamServer) error { + return status.Errorf(codes.Unimplemented, "method MessageStream not implemented") +} +func (*UnimplementedVitessServer) MessageAck(ctx context.Context, req *vtgate.MessageAckRequest) (*query.MessageAckResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method MessageAck not implemented") +} +func (*UnimplementedVitessServer) MessageAckKeyspaceIds(ctx context.Context, req *vtgate.MessageAckKeyspaceIdsRequest) (*query.MessageAckResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method MessageAckKeyspaceIds not implemented") +} +func (*UnimplementedVitessServer) SplitQuery(ctx context.Context, req *vtgate.SplitQueryRequest) (*vtgate.SplitQueryResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method SplitQuery not implemented") +} +func (*UnimplementedVitessServer) GetSrvKeyspace(ctx context.Context, req *vtgate.GetSrvKeyspaceRequest) (*vtgate.GetSrvKeyspaceResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetSrvKeyspace not implemented") +} +func (*UnimplementedVitessServer) VStream(req *vtgate.VStreamRequest, srv Vitess_VStreamServer) error { + return status.Errorf(codes.Unimplemented, "method VStream not implemented") +} +func (*UnimplementedVitessServer) UpdateStream(req *vtgate.UpdateStreamRequest, srv Vitess_UpdateStreamServer) error { + return status.Errorf(codes.Unimplemented, "method UpdateStream not implemented") +} + func RegisterVitessServer(s *grpc.Server, srv VitessServer) { s.RegisterService(&_Vitess_serviceDesc, srv) } @@ -1130,47 +1250,3 @@ var _Vitess_serviceDesc = grpc.ServiceDesc{ }, Metadata: "vtgateservice.proto", } - -func init() { proto.RegisterFile("vtgateservice.proto", fileDescriptor_vtgateservice_b8d4a07f11e6fc8a) } - -var fileDescriptor_vtgateservice_b8d4a07f11e6fc8a = []byte{ - // 594 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x95, 0x5f, 0x6f, 0xd3, 0x30, - 0x14, 0xc5, 0xe1, 0x81, 0x0e, 0x5d, 0x5a, 0x40, 0xde, 0xd6, 0x6e, 0xe5, 0xef, 0x0a, 0x6c, 0x88, - 0x87, 0x16, 0x81, 0x84, 0x84, 0x84, 0x40, 0x2d, 0x54, 0x08, 0x4d, 0x03, 0xd6, 0x42, 0x91, 0x26, - 0xf1, 0xe0, 0xa6, 0x57, 0x59, 0xd4, 0x36, 0x49, 0x63, 0x37, 0xa2, 0x5f, 0x80, 0xcf, 0x3d, 0x2d, - 0xb1, 0x1d, 0xdb, 0x71, 0xdb, 0xb7, 0xe4, 0x9c, 0xe3, 0x9f, 0xed, 0xeb, 0x2b, 0x1b, 0x76, 0x53, - 0xee, 0x53, 0x8e, 0x0c, 0x93, 0x34, 0xf0, 0xb0, 0x1d, 0x27, 0x11, 0x8f, 0x48, 0xcd, 0x10, 0x9b, - 0xd5, 0xfc, 0x37, 0x37, 0x9b, 0x77, 0x16, 0x4b, 0x4c, 0x56, 0xf9, 0xcf, 0x9b, 0xff, 0xf7, 0xa0, - 0x32, 0x0a, 0x38, 0x32, 0x46, 0x3e, 0xc0, 0x4e, 0xff, 0x1f, 0x7a, 0x4b, 0x8e, 0xa4, 0xde, 0x16, - 0x23, 0x84, 0x30, 0xc0, 0xc5, 0x12, 0x19, 0x6f, 0x36, 0x4a, 0x3a, 0x8b, 0xa3, 0x90, 0x61, 0xeb, - 0x06, 0x39, 0x85, 0xaa, 0x10, 0x7b, 0x94, 0x7b, 0x97, 0xe4, 0x81, 0x15, 0xcd, 0x54, 0xc9, 0x79, - 0xe8, 0x36, 0x15, 0xec, 0x27, 0xd4, 0x86, 0x3c, 0x41, 0x3a, 0x97, 0x0b, 0x52, 0x03, 0x0c, 0x59, - 0xe2, 0x1e, 0xad, 0x71, 0x25, 0xef, 0xf5, 0x4d, 0xf2, 0x1d, 0x6a, 0x42, 0x1e, 0x5e, 0xd2, 0x64, - 0xc2, 0x88, 0xbd, 0x84, 0x5c, 0x2e, 0x11, 0x2d, 0x57, 0xad, 0xf0, 0x2f, 0x10, 0x61, 0x9d, 0xe2, - 0x8a, 0xc5, 0xd4, 0xc3, 0x6f, 0x13, 0x46, 0x8e, 0xac, 0x61, 0x9a, 0x27, 0xc9, 0xad, 0x4d, 0x11, - 0x85, 0xff, 0x03, 0xf7, 0x0b, 0x7f, 0x40, 0x43, 0x1f, 0x19, 0x79, 0x52, 0x1e, 0x99, 0x3b, 0x12, - 0xfd, 0x74, 0x7d, 0xc0, 0x01, 0xee, 0x87, 0x3c, 0xe0, 0xab, 0xeb, 0x55, 0xdb, 0x60, 0xe5, 0xac, - 0x03, 0x6b, 0x01, 0x47, 0x41, 0xb2, 0xc3, 0x14, 0x55, 0x3e, 0x72, 0x1d, 0xb4, 0x59, 0xea, 0xd6, - 0xa6, 0x88, 0xc2, 0xcf, 0xa0, 0xa1, 0xfb, 0x7a, 0xd1, 0x8f, 0x5d, 0x00, 0x47, 0xe5, 0x4f, 0xb6, - 0xe6, 0xd4, 0x6c, 0x63, 0xd8, 0x35, 0x5a, 0x49, 0xec, 0xa6, 0xe5, 0xec, 0x33, 0x73, 0x3b, 0xcf, - 0x36, 0x66, 0xb4, 0x8e, 0x5c, 0xc0, 0x81, 0x11, 0xd1, 0xb7, 0x74, 0xe2, 0x84, 0x38, 0xf6, 0xf4, - 0x72, 0x7b, 0x50, 0x9b, 0x72, 0x0a, 0x75, 0x3b, 0x27, 0x7a, 0xeb, 0xc5, 0x3a, 0x8e, 0xd9, 0x61, - 0xc7, 0xdb, 0x62, 0xda, 0x64, 0xef, 0xe0, 0x56, 0x0f, 0xfd, 0x20, 0x24, 0x7b, 0x72, 0x50, 0xf6, - 0x2b, 0x51, 0xfb, 0x96, 0xaa, 0x6a, 0xff, 0x1e, 0x2a, 0x9f, 0xa3, 0xf9, 0x3c, 0xe0, 0x44, 0x45, - 0xf2, 0x7f, 0x39, 0xb2, 0x6e, 0xcb, 0x6a, 0xe8, 0x27, 0xb8, 0x3d, 0x88, 0x66, 0xb3, 0x31, 0xf5, - 0xa6, 0x44, 0x5d, 0x55, 0x52, 0x91, 0xc3, 0x0f, 0xca, 0x86, 0xde, 0xc4, 0x03, 0x64, 0xd1, 0x2c, - 0xc5, 0x5f, 0x09, 0x0d, 0x19, 0xf5, 0x78, 0x10, 0x85, 0x45, 0x13, 0x97, 0xbd, 0x52, 0x13, 0xbb, - 0x22, 0x0a, 0xff, 0x03, 0x6a, 0x67, 0xc8, 0x18, 0xf5, 0x31, 0xaf, 0x5f, 0x71, 0x09, 0x19, 0x72, - 0x71, 0x4b, 0xe6, 0x37, 0xb5, 0x65, 0x6a, 0x35, 0xfe, 0x02, 0x20, 0xcc, 0xae, 0x37, 0x25, 0x87, - 0x16, 0xad, 0x5b, 0x6c, 0xfa, 0xd0, 0x44, 0x75, 0x8d, 0x5d, 0x5f, 0xc0, 0x7e, 0xa1, 0xeb, 0x6d, - 0xf8, 0xbc, 0x0c, 0x74, 0xf4, 0xe0, 0x46, 0x76, 0x1f, 0x60, 0x18, 0xcf, 0x02, 0x7e, 0x7e, 0x1d, - 0x29, 0x56, 0x58, 0x68, 0x92, 0xd2, 0x74, 0x59, 0x0a, 0x73, 0x0e, 0x77, 0xbf, 0x22, 0x1f, 0x26, - 0xa9, 0x9c, 0x9f, 0xa8, 0x1b, 0xda, 0xd4, 0x25, 0xee, 0xf1, 0x3a, 0x5b, 0x21, 0x3f, 0xc2, 0xce, - 0x48, 0x1c, 0x83, 0xea, 0xa8, 0x91, 0x79, 0x00, 0x8d, 0x92, 0xae, 0xd5, 0xfe, 0x0c, 0xaa, 0xbf, - 0xe3, 0x09, 0xe5, 0xf2, 0x2c, 0xd5, 0x83, 0xa7, 0xab, 0xa5, 0x07, 0xcf, 0x34, 0x0b, 0x5c, 0xaf, - 0x07, 0x7b, 0x41, 0xd4, 0x4e, 0xb3, 0xa7, 0x38, 0x7f, 0x9b, 0xdb, 0x7e, 0x12, 0x7b, 0x17, 0xaf, - 0x84, 0x14, 0x44, 0x9d, 0xfc, 0xab, 0xe3, 0x47, 0x9d, 0x94, 0x77, 0xb2, 0x48, 0xc7, 0x78, 0xe7, - 0xc7, 0x95, 0x4c, 0x7c, 0x7b, 0x15, 0x00, 0x00, 0xff, 0xff, 0x98, 0xf7, 0xf0, 0x85, 0x14, 0x08, - 0x00, 0x00, -} diff --git a/go/vt/proto/vtrpc/vtrpc.pb.go b/go/vt/proto/vtrpc/vtrpc.pb.go index 6881f6ed3ae..8a673537d9a 100644 --- a/go/vt/proto/vtrpc/vtrpc.pb.go +++ b/go/vt/proto/vtrpc/vtrpc.pb.go @@ -1,11 +1,14 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // source: vtrpc.proto -package vtrpc // import "vitess.io/vitess/go/vt/proto/vtrpc" +package vtrpc -import proto "github.com/golang/protobuf/proto" -import fmt "fmt" -import math "math" +import ( + fmt "fmt" + math "math" + + proto "github.com/golang/protobuf/proto" +) // Reference imports to suppress errors if they are not otherwise used. var _ = proto.Marshal @@ -16,7 +19,7 @@ var _ = math.Inf // is compatible with the proto package it is being compiled against. // A compilation error at this line likely means your copy of the // proto package needs to be updated. -const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package +const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package // Code represents canonical error codes. The names, numbers and comments // must match the ones defined by grpc: @@ -144,6 +147,7 @@ var Code_name = map[int32]string{ 14: "UNAVAILABLE", 15: "DATA_LOSS", } + var Code_value = map[string]int32{ "OK": 0, "CANCELED": 1, @@ -167,8 +171,9 @@ var Code_value = map[string]int32{ func (x Code) String() string { return proto.EnumName(Code_name, int32(x)) } + func (Code) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_vtrpc_88a14d8f1bc03cf5, []int{0} + return fileDescriptor_750b4cf641561858, []int{0} } // LegacyErrorCode is the enum values for Errors. This type is deprecated. @@ -256,6 +261,7 @@ var LegacyErrorCode_name = map[int32]string{ 11: "TRANSIENT_ERROR_LEGACY", 12: "UNAUTHENTICATED_LEGACY", } + var LegacyErrorCode_value = map[string]int32{ "SUCCESS_LEGACY": 0, "CANCELLED_LEGACY": 1, @@ -275,8 +281,9 @@ var LegacyErrorCode_value = map[string]int32{ func (x LegacyErrorCode) String() string { return proto.EnumName(LegacyErrorCode_name, int32(x)) } + func (LegacyErrorCode) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_vtrpc_88a14d8f1bc03cf5, []int{1} + return fileDescriptor_750b4cf641561858, []int{1} } // CallerID is passed along RPCs to identify the originating client @@ -311,16 +318,17 @@ func (m *CallerID) Reset() { *m = CallerID{} } func (m *CallerID) String() string { return proto.CompactTextString(m) } func (*CallerID) ProtoMessage() {} func (*CallerID) Descriptor() ([]byte, []int) { - return fileDescriptor_vtrpc_88a14d8f1bc03cf5, []int{0} + return fileDescriptor_750b4cf641561858, []int{0} } + func (m *CallerID) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_CallerID.Unmarshal(m, b) } func (m *CallerID) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_CallerID.Marshal(b, m, deterministic) } -func (dst *CallerID) XXX_Merge(src proto.Message) { - xxx_messageInfo_CallerID.Merge(dst, src) +func (m *CallerID) XXX_Merge(src proto.Message) { + xxx_messageInfo_CallerID.Merge(m, src) } func (m *CallerID) XXX_Size() int { return xxx_messageInfo_CallerID.Size(m) @@ -369,16 +377,17 @@ func (m *RPCError) Reset() { *m = RPCError{} } func (m *RPCError) String() string { return proto.CompactTextString(m) } func (*RPCError) ProtoMessage() {} func (*RPCError) Descriptor() ([]byte, []int) { - return fileDescriptor_vtrpc_88a14d8f1bc03cf5, []int{1} + return fileDescriptor_750b4cf641561858, []int{1} } + func (m *RPCError) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_RPCError.Unmarshal(m, b) } func (m *RPCError) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_RPCError.Marshal(b, m, deterministic) } -func (dst *RPCError) XXX_Merge(src proto.Message) { - xxx_messageInfo_RPCError.Merge(dst, src) +func (m *RPCError) XXX_Merge(src proto.Message) { + xxx_messageInfo_RPCError.Merge(m, src) } func (m *RPCError) XXX_Size() int { return xxx_messageInfo_RPCError.Size(m) @@ -411,15 +420,15 @@ func (m *RPCError) GetCode() Code { } func init() { - proto.RegisterType((*CallerID)(nil), "vtrpc.CallerID") - proto.RegisterType((*RPCError)(nil), "vtrpc.RPCError") proto.RegisterEnum("vtrpc.Code", Code_name, Code_value) proto.RegisterEnum("vtrpc.LegacyErrorCode", LegacyErrorCode_name, LegacyErrorCode_value) + proto.RegisterType((*CallerID)(nil), "vtrpc.CallerID") + proto.RegisterType((*RPCError)(nil), "vtrpc.RPCError") } -func init() { proto.RegisterFile("vtrpc.proto", fileDescriptor_vtrpc_88a14d8f1bc03cf5) } +func init() { proto.RegisterFile("vtrpc.proto", fileDescriptor_750b4cf641561858) } -var fileDescriptor_vtrpc_88a14d8f1bc03cf5 = []byte{ +var fileDescriptor_750b4cf641561858 = []byte{ // 605 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x64, 0x93, 0x4d, 0x4f, 0x1b, 0x3b, 0x14, 0x86, 0xc9, 0x07, 0xf9, 0x38, 0x13, 0x88, 0x31, 0x5f, 0xe1, 0x5e, 0xae, 0xee, 0x55, 0x56, diff --git a/go/vt/proto/vttest/vttest.pb.go b/go/vt/proto/vttest/vttest.pb.go index b53058b7dc2..7dad543bdfc 100644 --- a/go/vt/proto/vttest/vttest.pb.go +++ b/go/vt/proto/vttest/vttest.pb.go @@ -1,11 +1,14 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // source: vttest.proto -package vttest // import "vitess.io/vitess/go/vt/proto/vttest" +package vttest -import proto "github.com/golang/protobuf/proto" -import fmt "fmt" -import math "math" +import ( + fmt "fmt" + math "math" + + proto "github.com/golang/protobuf/proto" +) // Reference imports to suppress errors if they are not otherwise used. var _ = proto.Marshal @@ -16,7 +19,7 @@ var _ = math.Inf // is compatible with the proto package it is being compiled against. // A compilation error at this line likely means your copy of the // proto package needs to be updated. -const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package +const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package // Shard describes a single shard in a keyspace. type Shard struct { @@ -37,16 +40,17 @@ func (m *Shard) Reset() { *m = Shard{} } func (m *Shard) String() string { return proto.CompactTextString(m) } func (*Shard) ProtoMessage() {} func (*Shard) Descriptor() ([]byte, []int) { - return fileDescriptor_vttest_6aca346ef34e15cf, []int{0} + return fileDescriptor_b9b3dc07179a1ec9, []int{0} } + func (m *Shard) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Shard.Unmarshal(m, b) } func (m *Shard) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_Shard.Marshal(b, m, deterministic) } -func (dst *Shard) XXX_Merge(src proto.Message) { - xxx_messageInfo_Shard.Merge(dst, src) +func (m *Shard) XXX_Merge(src proto.Message) { + xxx_messageInfo_Shard.Merge(m, src) } func (m *Shard) XXX_Size() int { return xxx_messageInfo_Shard.Size(m) @@ -96,16 +100,17 @@ func (m *Keyspace) Reset() { *m = Keyspace{} } func (m *Keyspace) String() string { return proto.CompactTextString(m) } func (*Keyspace) ProtoMessage() {} func (*Keyspace) Descriptor() ([]byte, []int) { - return fileDescriptor_vttest_6aca346ef34e15cf, []int{1} + return fileDescriptor_b9b3dc07179a1ec9, []int{1} } + func (m *Keyspace) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Keyspace.Unmarshal(m, b) } func (m *Keyspace) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_Keyspace.Marshal(b, m, deterministic) } -func (dst *Keyspace) XXX_Merge(src proto.Message) { - xxx_messageInfo_Keyspace.Merge(dst, src) +func (m *Keyspace) XXX_Merge(src proto.Message) { + xxx_messageInfo_Keyspace.Merge(m, src) } func (m *Keyspace) XXX_Size() int { return xxx_messageInfo_Keyspace.Size(m) @@ -180,16 +185,17 @@ func (m *VTTestTopology) Reset() { *m = VTTestTopology{} } func (m *VTTestTopology) String() string { return proto.CompactTextString(m) } func (*VTTestTopology) ProtoMessage() {} func (*VTTestTopology) Descriptor() ([]byte, []int) { - return fileDescriptor_vttest_6aca346ef34e15cf, []int{2} + return fileDescriptor_b9b3dc07179a1ec9, []int{2} } + func (m *VTTestTopology) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_VTTestTopology.Unmarshal(m, b) } func (m *VTTestTopology) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_VTTestTopology.Marshal(b, m, deterministic) } -func (dst *VTTestTopology) XXX_Merge(src proto.Message) { - xxx_messageInfo_VTTestTopology.Merge(dst, src) +func (m *VTTestTopology) XXX_Merge(src proto.Message) { + xxx_messageInfo_VTTestTopology.Merge(m, src) } func (m *VTTestTopology) XXX_Size() int { return xxx_messageInfo_VTTestTopology.Size(m) @@ -220,9 +226,9 @@ func init() { proto.RegisterType((*VTTestTopology)(nil), "vttest.VTTestTopology") } -func init() { proto.RegisterFile("vttest.proto", fileDescriptor_vttest_6aca346ef34e15cf) } +func init() { proto.RegisterFile("vttest.proto", fileDescriptor_b9b3dc07179a1ec9) } -var fileDescriptor_vttest_6aca346ef34e15cf = []byte{ +var fileDescriptor_b9b3dc07179a1ec9 = []byte{ // 322 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x51, 0xcb, 0x6a, 0xe3, 0x40, 0x10, 0x44, 0xb6, 0xa5, 0x5d, 0xb7, 0x1f, 0x98, 0xc1, 0x87, 0xb9, 0xad, 0xd7, 0xc6, 0xa0, 0x93, diff --git a/go/vt/proto/vttime/time.pb.go b/go/vt/proto/vttime/time.pb.go new file mode 100644 index 00000000000..449cd23197b --- /dev/null +++ b/go/vt/proto/vttime/time.pb.go @@ -0,0 +1,89 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: time.proto + +package vttime + +import ( + fmt "fmt" + math "math" + + proto "github.com/golang/protobuf/proto" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package + +// Time represents a time stamp in nanoseconds. In go, use logutil library +// to convert times. +type Time struct { + Seconds int64 `protobuf:"varint,1,opt,name=seconds,proto3" json:"seconds,omitempty"` + Nanoseconds int32 `protobuf:"varint,2,opt,name=nanoseconds,proto3" json:"nanoseconds,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Time) Reset() { *m = Time{} } +func (m *Time) String() string { return proto.CompactTextString(m) } +func (*Time) ProtoMessage() {} +func (*Time) Descriptor() ([]byte, []int) { + return fileDescriptor_49a92d779a28c7fd, []int{0} +} + +func (m *Time) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Time.Unmarshal(m, b) +} +func (m *Time) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Time.Marshal(b, m, deterministic) +} +func (m *Time) XXX_Merge(src proto.Message) { + xxx_messageInfo_Time.Merge(m, src) +} +func (m *Time) XXX_Size() int { + return xxx_messageInfo_Time.Size(m) +} +func (m *Time) XXX_DiscardUnknown() { + xxx_messageInfo_Time.DiscardUnknown(m) +} + +var xxx_messageInfo_Time proto.InternalMessageInfo + +func (m *Time) GetSeconds() int64 { + if m != nil { + return m.Seconds + } + return 0 +} + +func (m *Time) GetNanoseconds() int32 { + if m != nil { + return m.Nanoseconds + } + return 0 +} + +func init() { + proto.RegisterType((*Time)(nil), "vttime.Time") +} + +func init() { proto.RegisterFile("time.proto", fileDescriptor_49a92d779a28c7fd) } + +var fileDescriptor_49a92d779a28c7fd = []byte{ + // 120 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x2a, 0xc9, 0xcc, 0x4d, + 0xd5, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0x2b, 0x2b, 0x01, 0xf1, 0x94, 0x9c, 0xb8, 0x58, + 0x42, 0x32, 0x73, 0x53, 0x85, 0x24, 0xb8, 0xd8, 0x8b, 0x53, 0x93, 0xf3, 0xf3, 0x52, 0x8a, 0x25, + 0x18, 0x15, 0x18, 0x35, 0x98, 0x83, 0x60, 0x5c, 0x21, 0x05, 0x2e, 0xee, 0xbc, 0xc4, 0xbc, 0x7c, + 0x98, 0x2c, 0x93, 0x02, 0xa3, 0x06, 0x6b, 0x10, 0xb2, 0x90, 0x93, 0x6a, 0x94, 0x72, 0x59, 0x66, + 0x49, 0x6a, 0x71, 0xb1, 0x5e, 0x66, 0xbe, 0x3e, 0x84, 0xa5, 0x9f, 0x9e, 0xaf, 0x5f, 0x56, 0xa2, + 0x0f, 0xb6, 0x4b, 0x1f, 0x62, 0x55, 0x12, 0x1b, 0x98, 0x67, 0x0c, 0x08, 0x00, 0x00, 0xff, 0xff, + 0xb4, 0x42, 0xf5, 0xf7, 0x87, 0x00, 0x00, 0x00, +} diff --git a/go/vt/proto/vtworkerdata/vtworkerdata.pb.go b/go/vt/proto/vtworkerdata/vtworkerdata.pb.go index 42135571576..986447754bc 100644 --- a/go/vt/proto/vtworkerdata/vtworkerdata.pb.go +++ b/go/vt/proto/vtworkerdata/vtworkerdata.pb.go @@ -1,12 +1,15 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // source: vtworkerdata.proto -package vtworkerdata // import "vitess.io/vitess/go/vt/proto/vtworkerdata" +package vtworkerdata -import proto "github.com/golang/protobuf/proto" -import fmt "fmt" -import math "math" -import logutil "vitess.io/vitess/go/vt/proto/logutil" +import ( + fmt "fmt" + math "math" + + proto "github.com/golang/protobuf/proto" + logutil "vitess.io/vitess/go/vt/proto/logutil" +) // Reference imports to suppress errors if they are not otherwise used. var _ = proto.Marshal @@ -17,7 +20,7 @@ var _ = math.Inf // is compatible with the proto package it is being compiled against. // A compilation error at this line likely means your copy of the // proto package needs to be updated. -const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package +const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package // ExecuteVtworkerCommandRequest is the payload for ExecuteVtworkerCommand. type ExecuteVtworkerCommandRequest struct { @@ -31,16 +34,17 @@ func (m *ExecuteVtworkerCommandRequest) Reset() { *m = ExecuteVtworkerCo func (m *ExecuteVtworkerCommandRequest) String() string { return proto.CompactTextString(m) } func (*ExecuteVtworkerCommandRequest) ProtoMessage() {} func (*ExecuteVtworkerCommandRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_vtworkerdata_cae0940479e6aeb1, []int{0} + return fileDescriptor_32a791ab99179e8e, []int{0} } + func (m *ExecuteVtworkerCommandRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ExecuteVtworkerCommandRequest.Unmarshal(m, b) } func (m *ExecuteVtworkerCommandRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_ExecuteVtworkerCommandRequest.Marshal(b, m, deterministic) } -func (dst *ExecuteVtworkerCommandRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_ExecuteVtworkerCommandRequest.Merge(dst, src) +func (m *ExecuteVtworkerCommandRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_ExecuteVtworkerCommandRequest.Merge(m, src) } func (m *ExecuteVtworkerCommandRequest) XXX_Size() int { return xxx_messageInfo_ExecuteVtworkerCommandRequest.Size(m) @@ -70,16 +74,17 @@ func (m *ExecuteVtworkerCommandResponse) Reset() { *m = ExecuteVtworkerC func (m *ExecuteVtworkerCommandResponse) String() string { return proto.CompactTextString(m) } func (*ExecuteVtworkerCommandResponse) ProtoMessage() {} func (*ExecuteVtworkerCommandResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_vtworkerdata_cae0940479e6aeb1, []int{1} + return fileDescriptor_32a791ab99179e8e, []int{1} } + func (m *ExecuteVtworkerCommandResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ExecuteVtworkerCommandResponse.Unmarshal(m, b) } func (m *ExecuteVtworkerCommandResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_ExecuteVtworkerCommandResponse.Marshal(b, m, deterministic) } -func (dst *ExecuteVtworkerCommandResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_ExecuteVtworkerCommandResponse.Merge(dst, src) +func (m *ExecuteVtworkerCommandResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_ExecuteVtworkerCommandResponse.Merge(m, src) } func (m *ExecuteVtworkerCommandResponse) XXX_Size() int { return xxx_messageInfo_ExecuteVtworkerCommandResponse.Size(m) @@ -102,9 +107,9 @@ func init() { proto.RegisterType((*ExecuteVtworkerCommandResponse)(nil), "vtworkerdata.ExecuteVtworkerCommandResponse") } -func init() { proto.RegisterFile("vtworkerdata.proto", fileDescriptor_vtworkerdata_cae0940479e6aeb1) } +func init() { proto.RegisterFile("vtworkerdata.proto", fileDescriptor_32a791ab99179e8e) } -var fileDescriptor_vtworkerdata_cae0940479e6aeb1 = []byte{ +var fileDescriptor_32a791ab99179e8e = []byte{ // 175 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x12, 0x2a, 0x2b, 0x29, 0xcf, 0x2f, 0xca, 0x4e, 0x2d, 0x4a, 0x49, 0x2c, 0x49, 0xd4, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0xe2, diff --git a/go/vt/proto/vtworkerservice/vtworkerservice.pb.go b/go/vt/proto/vtworkerservice/vtworkerservice.pb.go index bc38e2eca4c..22a1a03e8aa 100644 --- a/go/vt/proto/vtworkerservice/vtworkerservice.pb.go +++ b/go/vt/proto/vtworkerservice/vtworkerservice.pb.go @@ -1,16 +1,18 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // source: vtworkerservice.proto -package vtworkerservice // import "vitess.io/vitess/go/vt/proto/vtworkerservice" - -import proto "github.com/golang/protobuf/proto" -import fmt "fmt" -import math "math" -import vtworkerdata "vitess.io/vitess/go/vt/proto/vtworkerdata" +package vtworkerservice import ( - context "golang.org/x/net/context" + context "context" + fmt "fmt" + math "math" + + proto "github.com/golang/protobuf/proto" grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + vtworkerdata "vitess.io/vitess/go/vt/proto/vtworkerdata" ) // Reference imports to suppress errors if they are not otherwise used. @@ -22,7 +24,23 @@ var _ = math.Inf // is compatible with the proto package it is being compiled against. // A compilation error at this line likely means your copy of the // proto package needs to be updated. -const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package +const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package + +func init() { proto.RegisterFile("vtworkerservice.proto", fileDescriptor_884fe2c3e67151b3) } + +var fileDescriptor_884fe2c3e67151b3 = []byte{ + // 151 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x12, 0x2d, 0x2b, 0x29, 0xcf, + 0x2f, 0xca, 0x4e, 0x2d, 0x2a, 0x4e, 0x2d, 0x2a, 0xcb, 0x4c, 0x4e, 0xd5, 0x2b, 0x28, 0xca, 0x2f, + 0xc9, 0x17, 0xe2, 0x47, 0x13, 0x96, 0x12, 0x82, 0x09, 0xa4, 0x24, 0x96, 0x24, 0x42, 0x14, 0x19, + 0x35, 0x33, 0x72, 0x71, 0x84, 0x41, 0x85, 0x85, 0xca, 0xb9, 0xc4, 0x5c, 0x2b, 0x52, 0x93, 0x4b, + 0x4b, 0x52, 0x61, 0x42, 0xce, 0xf9, 0xb9, 0xb9, 0x89, 0x79, 0x29, 0x42, 0xda, 0x7a, 0x28, 0x7a, + 0xb1, 0xab, 0x0a, 0x4a, 0x2d, 0x2c, 0x4d, 0x2d, 0x2e, 0x91, 0xd2, 0x21, 0x4e, 0x71, 0x71, 0x41, + 0x7e, 0x5e, 0x71, 0xaa, 0x12, 0x83, 0x01, 0xa3, 0x93, 0x5e, 0x94, 0x4e, 0x59, 0x66, 0x49, 0x6a, + 0x71, 0xb1, 0x5e, 0x66, 0xbe, 0x3e, 0x84, 0xa5, 0x9f, 0x9e, 0xaf, 0x5f, 0x56, 0xa2, 0x0f, 0x76, + 0xa5, 0x3e, 0x9a, 0x4f, 0x92, 0xd8, 0xc0, 0xc2, 0xc6, 0x80, 0x00, 0x00, 0x00, 0xff, 0xff, 0x1c, + 0x01, 0x4d, 0x17, 0xfa, 0x00, 0x00, 0x00, +} // Reference imports to suppress errors if they are not otherwise used. var _ context.Context @@ -88,6 +106,14 @@ type VtworkerServer interface { ExecuteVtworkerCommand(*vtworkerdata.ExecuteVtworkerCommandRequest, Vtworker_ExecuteVtworkerCommandServer) error } +// UnimplementedVtworkerServer can be embedded to have forward compatible implementations. +type UnimplementedVtworkerServer struct { +} + +func (*UnimplementedVtworkerServer) ExecuteVtworkerCommand(req *vtworkerdata.ExecuteVtworkerCommandRequest, srv Vtworker_ExecuteVtworkerCommandServer) error { + return status.Errorf(codes.Unimplemented, "method ExecuteVtworkerCommand not implemented") +} + func RegisterVtworkerServer(s *grpc.Server, srv VtworkerServer) { s.RegisterService(&_Vtworker_serviceDesc, srv) } @@ -126,21 +152,3 @@ var _Vtworker_serviceDesc = grpc.ServiceDesc{ }, Metadata: "vtworkerservice.proto", } - -func init() { - proto.RegisterFile("vtworkerservice.proto", fileDescriptor_vtworkerservice_4efa3310356e3c00) -} - -var fileDescriptor_vtworkerservice_4efa3310356e3c00 = []byte{ - // 151 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x12, 0x2d, 0x2b, 0x29, 0xcf, - 0x2f, 0xca, 0x4e, 0x2d, 0x2a, 0x4e, 0x2d, 0x2a, 0xcb, 0x4c, 0x4e, 0xd5, 0x2b, 0x28, 0xca, 0x2f, - 0xc9, 0x17, 0xe2, 0x47, 0x13, 0x96, 0x12, 0x82, 0x09, 0xa4, 0x24, 0x96, 0x24, 0x42, 0x14, 0x19, - 0x35, 0x33, 0x72, 0x71, 0x84, 0x41, 0x85, 0x85, 0xca, 0xb9, 0xc4, 0x5c, 0x2b, 0x52, 0x93, 0x4b, - 0x4b, 0x52, 0x61, 0x42, 0xce, 0xf9, 0xb9, 0xb9, 0x89, 0x79, 0x29, 0x42, 0xda, 0x7a, 0x28, 0x7a, - 0xb1, 0xab, 0x0a, 0x4a, 0x2d, 0x2c, 0x4d, 0x2d, 0x2e, 0x91, 0xd2, 0x21, 0x4e, 0x71, 0x71, 0x41, - 0x7e, 0x5e, 0x71, 0xaa, 0x12, 0x83, 0x01, 0xa3, 0x93, 0x5e, 0x94, 0x4e, 0x59, 0x66, 0x49, 0x6a, - 0x71, 0xb1, 0x5e, 0x66, 0xbe, 0x3e, 0x84, 0xa5, 0x9f, 0x9e, 0xaf, 0x5f, 0x56, 0xa2, 0x0f, 0x76, - 0xa5, 0x3e, 0x9a, 0x4f, 0x92, 0xd8, 0xc0, 0xc2, 0xc6, 0x80, 0x00, 0x00, 0x00, 0xff, 0xff, 0x1c, - 0x01, 0x4d, 0x17, 0xfa, 0x00, 0x00, 0x00, -} diff --git a/go/vt/proto/workflow/workflow.pb.go b/go/vt/proto/workflow/workflow.pb.go index 8c173f294b2..44e4c451786 100644 --- a/go/vt/proto/workflow/workflow.pb.go +++ b/go/vt/proto/workflow/workflow.pb.go @@ -1,11 +1,14 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // source: workflow.proto -package workflow // import "vitess.io/vitess/go/vt/proto/workflow" +package workflow -import proto "github.com/golang/protobuf/proto" -import fmt "fmt" -import math "math" +import ( + fmt "fmt" + math "math" + + proto "github.com/golang/protobuf/proto" +) // Reference imports to suppress errors if they are not otherwise used. var _ = proto.Marshal @@ -16,7 +19,7 @@ var _ = math.Inf // is compatible with the proto package it is being compiled against. // A compilation error at this line likely means your copy of the // proto package needs to be updated. -const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package +const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package // WorkflowState describes the state of a workflow. // This constant should match the Node object described in @@ -35,6 +38,7 @@ var WorkflowState_name = map[int32]string{ 1: "Running", 2: "Done", } + var WorkflowState_value = map[string]int32{ "NotStarted": 0, "Running": 1, @@ -44,8 +48,9 @@ var WorkflowState_value = map[string]int32{ func (x WorkflowState) String() string { return proto.EnumName(WorkflowState_name, int32(x)) } + func (WorkflowState) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_workflow_daba593a7423a6c7, []int{0} + return fileDescriptor_892c7f566756b0be, []int{0} } type TaskState int32 @@ -61,6 +66,7 @@ var TaskState_name = map[int32]string{ 1: "TaskRunning", 2: "TaskDone", } + var TaskState_value = map[string]int32{ "TaskNotStarted": 0, "TaskRunning": 1, @@ -70,8 +76,9 @@ var TaskState_value = map[string]int32{ func (x TaskState) String() string { return proto.EnumName(TaskState_name, int32(x)) } + func (TaskState) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_workflow_daba593a7423a6c7, []int{1} + return fileDescriptor_892c7f566756b0be, []int{1} } // Workflow is the persisted state of a long-running workflow. @@ -119,16 +126,17 @@ func (m *Workflow) Reset() { *m = Workflow{} } func (m *Workflow) String() string { return proto.CompactTextString(m) } func (*Workflow) ProtoMessage() {} func (*Workflow) Descriptor() ([]byte, []int) { - return fileDescriptor_workflow_daba593a7423a6c7, []int{0} + return fileDescriptor_892c7f566756b0be, []int{0} } + func (m *Workflow) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Workflow.Unmarshal(m, b) } func (m *Workflow) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_Workflow.Marshal(b, m, deterministic) } -func (dst *Workflow) XXX_Merge(src proto.Message) { - xxx_messageInfo_Workflow.Merge(dst, src) +func (m *Workflow) XXX_Merge(src proto.Message) { + xxx_messageInfo_Workflow.Merge(m, src) } func (m *Workflow) XXX_Size() int { return xxx_messageInfo_Workflow.Size(m) @@ -223,16 +231,17 @@ func (m *WorkflowCheckpoint) Reset() { *m = WorkflowCheckpoint{} } func (m *WorkflowCheckpoint) String() string { return proto.CompactTextString(m) } func (*WorkflowCheckpoint) ProtoMessage() {} func (*WorkflowCheckpoint) Descriptor() ([]byte, []int) { - return fileDescriptor_workflow_daba593a7423a6c7, []int{1} + return fileDescriptor_892c7f566756b0be, []int{1} } + func (m *WorkflowCheckpoint) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_WorkflowCheckpoint.Unmarshal(m, b) } func (m *WorkflowCheckpoint) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_WorkflowCheckpoint.Marshal(b, m, deterministic) } -func (dst *WorkflowCheckpoint) XXX_Merge(src proto.Message) { - xxx_messageInfo_WorkflowCheckpoint.Merge(dst, src) +func (m *WorkflowCheckpoint) XXX_Merge(src proto.Message) { + xxx_messageInfo_WorkflowCheckpoint.Merge(m, src) } func (m *WorkflowCheckpoint) XXX_Size() int { return xxx_messageInfo_WorkflowCheckpoint.Size(m) @@ -279,16 +288,17 @@ func (m *Task) Reset() { *m = Task{} } func (m *Task) String() string { return proto.CompactTextString(m) } func (*Task) ProtoMessage() {} func (*Task) Descriptor() ([]byte, []int) { - return fileDescriptor_workflow_daba593a7423a6c7, []int{2} + return fileDescriptor_892c7f566756b0be, []int{2} } + func (m *Task) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Task.Unmarshal(m, b) } func (m *Task) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_Task.Marshal(b, m, deterministic) } -func (dst *Task) XXX_Merge(src proto.Message) { - xxx_messageInfo_Task.Merge(dst, src) +func (m *Task) XXX_Merge(src proto.Message) { + xxx_messageInfo_Task.Merge(m, src) } func (m *Task) XXX_Size() int { return xxx_messageInfo_Task.Size(m) @@ -328,19 +338,19 @@ func (m *Task) GetError() string { } func init() { + proto.RegisterEnum("workflow.WorkflowState", WorkflowState_name, WorkflowState_value) + proto.RegisterEnum("workflow.TaskState", TaskState_name, TaskState_value) proto.RegisterType((*Workflow)(nil), "workflow.Workflow") proto.RegisterType((*WorkflowCheckpoint)(nil), "workflow.WorkflowCheckpoint") proto.RegisterMapType((map[string]string)(nil), "workflow.WorkflowCheckpoint.SettingsEntry") proto.RegisterMapType((map[string]*Task)(nil), "workflow.WorkflowCheckpoint.TasksEntry") proto.RegisterType((*Task)(nil), "workflow.Task") proto.RegisterMapType((map[string]string)(nil), "workflow.Task.AttributesEntry") - proto.RegisterEnum("workflow.WorkflowState", WorkflowState_name, WorkflowState_value) - proto.RegisterEnum("workflow.TaskState", TaskState_name, TaskState_value) } -func init() { proto.RegisterFile("workflow.proto", fileDescriptor_workflow_daba593a7423a6c7) } +func init() { proto.RegisterFile("workflow.proto", fileDescriptor_892c7f566756b0be) } -var fileDescriptor_workflow_daba593a7423a6c7 = []byte{ +var fileDescriptor_892c7f566756b0be = []byte{ // 517 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x53, 0x6f, 0x8b, 0xd3, 0x4e, 0x10, 0xfe, 0x25, 0x6d, 0xae, 0xe9, 0xa4, 0x97, 0x2b, 0xf3, 0x3b, 0x30, 0x16, 0xd4, 0x5a, 0x94, diff --git a/go/vt/schemamanager/local_controller.go b/go/vt/schemamanager/local_controller.go index fb1fabc4744..a087c4d7915 100644 --- a/go/vt/schemamanager/local_controller.go +++ b/go/vt/schemamanager/local_controller.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/schemamanager/local_controller_test.go b/go/vt/schemamanager/local_controller_test.go index cd48fd30d18..3df9affeba6 100644 --- a/go/vt/schemamanager/local_controller_test.go +++ b/go/vt/schemamanager/local_controller_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/schemamanager/plain_controller.go b/go/vt/schemamanager/plain_controller.go index b4709b1e2a2..80e9c31e658 100644 --- a/go/vt/schemamanager/plain_controller.go +++ b/go/vt/schemamanager/plain_controller.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/schemamanager/plain_controller_test.go b/go/vt/schemamanager/plain_controller_test.go index a73ef716753..28b5c9d87e0 100644 --- a/go/vt/schemamanager/plain_controller_test.go +++ b/go/vt/schemamanager/plain_controller_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/schemamanager/schemamanager.go b/go/vt/schemamanager/schemamanager.go index 47a270cbe2f..6a43f3ffc13 100644 --- a/go/vt/schemamanager/schemamanager.go +++ b/go/vt/schemamanager/schemamanager.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/schemamanager/schemamanager_test.go b/go/vt/schemamanager/schemamanager_test.go index fa392012964..852b47e6e87 100644 --- a/go/vt/schemamanager/schemamanager_test.go +++ b/go/vt/schemamanager/schemamanager_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/schemamanager/schemaswap/schema_swap.go b/go/vt/schemamanager/schemaswap/schema_swap.go index 4aa4d3816a2..ded32dc9be3 100644 --- a/go/vt/schemamanager/schemaswap/schema_swap.go +++ b/go/vt/schemamanager/schemaswap/schema_swap.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/schemamanager/tablet_executor.go b/go/vt/schemamanager/tablet_executor.go index 6346e6f913b..865ce3cede8 100644 --- a/go/vt/schemamanager/tablet_executor.go +++ b/go/vt/schemamanager/tablet_executor.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/schemamanager/tablet_executor_test.go b/go/vt/schemamanager/tablet_executor_test.go index 13cae66fdb1..579f4bd794c 100644 --- a/go/vt/schemamanager/tablet_executor_test.go +++ b/go/vt/schemamanager/tablet_executor_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/schemamanager/ui_controller.go b/go/vt/schemamanager/ui_controller.go index 909693a4a05..da84c06cf95 100644 --- a/go/vt/schemamanager/ui_controller.go +++ b/go/vt/schemamanager/ui_controller.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/schemamanager/ui_controller_test.go b/go/vt/schemamanager/ui_controller_test.go index 7f3d0506039..7d486588906 100644 --- a/go/vt/schemamanager/ui_controller_test.go +++ b/go/vt/schemamanager/ui_controller_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/servenv/buildinfo.go b/go/vt/servenv/buildinfo.go index 2a6f4cbc904..97834a794d8 100644 --- a/go/vt/servenv/buildinfo.go +++ b/go/vt/servenv/buildinfo.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/servenv/flush_logutil.go b/go/vt/servenv/flush_logutil.go index 3869aa5e2c8..bfe06a10a23 100644 --- a/go/vt/servenv/flush_logutil.go +++ b/go/vt/servenv/flush_logutil.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/servenv/flushlogs.go b/go/vt/servenv/flushlogs.go index 78b249834bb..6b88e137654 100644 --- a/go/vt/servenv/flushlogs.go +++ b/go/vt/servenv/flushlogs.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/servenv/grpc_auth.go b/go/vt/servenv/grpc_auth.go index 4008cf6c542..a88f8967f3c 100644 --- a/go/vt/servenv/grpc_auth.go +++ b/go/vt/servenv/grpc_auth.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/servenv/grpc_server.go b/go/vt/servenv/grpc_server.go index 48be5b816dc..382686809d8 100644 --- a/go/vt/servenv/grpc_server.go +++ b/go/vt/servenv/grpc_server.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/servenv/grpc_server_auth_static.go b/go/vt/servenv/grpc_server_auth_static.go index e8b982fc4c5..92f5e0eddd1 100644 --- a/go/vt/servenv/grpc_server_auth_static.go +++ b/go/vt/servenv/grpc_server_auth_static.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/servenv/grpc_server_test.go b/go/vt/servenv/grpc_server_test.go index 8c611cf2233..b078e6ec093 100644 --- a/go/vt/servenv/grpc_server_test.go +++ b/go/vt/servenv/grpc_server_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -17,62 +17,62 @@ limitations under the License. package servenv import ( - "testing" + "testing" - "golang.org/x/net/context" + "golang.org/x/net/context" - "google.golang.org/grpc" + "google.golang.org/grpc" ) func TestEmpty(t *testing.T) { - interceptors := &serverInterceptorBuilder{} - if len(interceptors.Build()) > 0 { - t.Fatalf("expected empty builder to report as empty") - } + interceptors := &serverInterceptorBuilder{} + if len(interceptors.Build()) > 0 { + t.Fatalf("expected empty builder to report as empty") + } } func TestSingleInterceptor(t *testing.T) { - interceptors := &serverInterceptorBuilder{} - fake := &FakeInterceptor{} + interceptors := &serverInterceptorBuilder{} + fake := &FakeInterceptor{} - interceptors.Add(fake.StreamServerInterceptor, fake.UnaryServerInterceptor) + interceptors.Add(fake.StreamServerInterceptor, fake.UnaryServerInterceptor) - if len(interceptors.streamInterceptors) != 1 { - t.Fatalf("expected 1 server options to be available") - } - if len(interceptors.unaryInterceptors) != 1 { - t.Fatalf("expected 1 server options to be available") - } + if len(interceptors.streamInterceptors) != 1 { + t.Fatalf("expected 1 server options to be available") + } + if len(interceptors.unaryInterceptors) != 1 { + t.Fatalf("expected 1 server options to be available") + } } func TestDoubleInterceptor(t *testing.T) { - interceptors := &serverInterceptorBuilder{} - fake1 := &FakeInterceptor{name: "ettan"} - fake2 := &FakeInterceptor{name: "tvaon"} - - interceptors.Add(fake1.StreamServerInterceptor, fake1.UnaryServerInterceptor) - interceptors.Add(fake2.StreamServerInterceptor, fake2.UnaryServerInterceptor) - - if len(interceptors.streamInterceptors) != 2 { - t.Fatalf("expected 1 server options to be available") - } - if len(interceptors.unaryInterceptors) != 2 { - t.Fatalf("expected 1 server options to be available") - } + interceptors := &serverInterceptorBuilder{} + fake1 := &FakeInterceptor{name: "ettan"} + fake2 := &FakeInterceptor{name: "tvaon"} + + interceptors.Add(fake1.StreamServerInterceptor, fake1.UnaryServerInterceptor) + interceptors.Add(fake2.StreamServerInterceptor, fake2.UnaryServerInterceptor) + + if len(interceptors.streamInterceptors) != 2 { + t.Fatalf("expected 1 server options to be available") + } + if len(interceptors.unaryInterceptors) != 2 { + t.Fatalf("expected 1 server options to be available") + } } type FakeInterceptor struct { - name string - streamSeen interface{} - unarySeen interface{} + name string + streamSeen interface{} + unarySeen interface{} } func (fake *FakeInterceptor) StreamServerInterceptor(value interface{}, stream grpc.ServerStream, _ *grpc.StreamServerInfo, handler grpc.StreamHandler) error { - fake.streamSeen = value - return handler(value, stream) + fake.streamSeen = value + return handler(value, stream) } func (fake *FakeInterceptor) UnaryServerInterceptor(ctx context.Context, value interface{}, _ *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (resp interface{}, err error) { - fake.unarySeen = value - return handler(ctx, value) + fake.unarySeen = value + return handler(ctx, value) } diff --git a/go/vt/servenv/jquery.go b/go/vt/servenv/jquery.go index acca446b472..70fa0133929 100644 --- a/go/vt/servenv/jquery.go +++ b/go/vt/servenv/jquery.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/servenv/pid_file.go b/go/vt/servenv/pid_file.go index 45678ab15a2..7c2fa57d3f7 100644 --- a/go/vt/servenv/pid_file.go +++ b/go/vt/servenv/pid_file.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/servenv/pprof.go b/go/vt/servenv/pprof.go index 99a179e8e51..28c31dee347 100644 --- a/go/vt/servenv/pprof.go +++ b/go/vt/servenv/pprof.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/servenv/purgelogs.go b/go/vt/servenv/purgelogs.go index de461742b38..e5edc9e7be2 100644 --- a/go/vt/servenv/purgelogs.go +++ b/go/vt/servenv/purgelogs.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/servenv/rpc_utils.go b/go/vt/servenv/rpc_utils.go index fb7319f2124..19a9fb1a6a7 100644 --- a/go/vt/servenv/rpc_utils.go +++ b/go/vt/servenv/rpc_utils.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/servenv/run.go b/go/vt/servenv/run.go index 1faf5af05ea..db69c6214bb 100644 --- a/go/vt/servenv/run.go +++ b/go/vt/servenv/run.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/servenv/servenv.go b/go/vt/servenv/servenv.go index fa1488d1e6d..de3165a7233 100644 --- a/go/vt/servenv/servenv.go +++ b/go/vt/servenv/servenv.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/servenv/servenv_test.go b/go/vt/servenv/servenv_test.go index ec267302f86..2c3509a2228 100644 --- a/go/vt/servenv/servenv_test.go +++ b/go/vt/servenv/servenv_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/servenv/service_map.go b/go/vt/servenv/service_map.go index 94b71d0dcd4..15c219ef555 100644 --- a/go/vt/servenv/service_map.go +++ b/go/vt/servenv/service_map.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/servenv/status.go b/go/vt/servenv/status.go index a8ca2562fdf..f391bf470a6 100644 --- a/go/vt/servenv/status.go +++ b/go/vt/servenv/status.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/servenv/status_test.go b/go/vt/servenv/status_test.go index 0a9f7e2203b..39a1cb6961b 100644 --- a/go/vt/servenv/status_test.go +++ b/go/vt/servenv/status_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/servenv/unix_socket.go b/go/vt/servenv/unix_socket.go index ad247fd063b..0fa35027e0f 100644 --- a/go/vt/servenv/unix_socket.go +++ b/go/vt/servenv/unix_socket.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/sqlannotation/sqlannotation.go b/go/vt/sqlannotation/sqlannotation.go index 5cebc2dd728..5ddc16f9b0c 100644 --- a/go/vt/sqlannotation/sqlannotation.go +++ b/go/vt/sqlannotation/sqlannotation.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/sqlannotation/sqlannotation_test.go b/go/vt/sqlannotation/sqlannotation_test.go index 831639d62af..c7c332ee00a 100644 --- a/go/vt/sqlannotation/sqlannotation_test.go +++ b/go/vt/sqlannotation/sqlannotation_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/sqlparser/Makefile b/go/vt/sqlparser/Makefile index 215f422e624..1ca0af6755e 100644 --- a/go/vt/sqlparser/Makefile +++ b/go/vt/sqlparser/Makefile @@ -1,4 +1,4 @@ -# Copyright 2017 Google Inc. +# 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. @@ -15,7 +15,7 @@ MAKEFLAGS = -s sql.go: sql.y - goyacc -o sql.go sql.y + go run golang.org/x/tools/cmd/goyacc -o sql.go sql.y gofmt -w sql.go clean: diff --git a/go/vt/sqlparser/analyzer.go b/go/vt/sqlparser/analyzer.go index 6d4db548ad0..534903e9a71 100644 --- a/go/vt/sqlparser/analyzer.go +++ b/go/vt/sqlparser/analyzer.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -30,10 +30,13 @@ import ( vtrpcpb "vitess.io/vitess/go/vt/proto/vtrpc" ) +// StatementType encodes the type of a SQL statement +type StatementType int + // These constants are used to identify the SQL statement type. // Changing this list will require reviewing all calls to Preview. const ( - StmtSelect = iota + StmtSelect StatementType = iota StmtStream StmtInsert StmtReplace @@ -53,14 +56,19 @@ const ( // Preview analyzes the beginning of the query using a simpler and faster // textual comparison to identify the statement type. -func Preview(sql string) int { +func Preview(sql string) StatementType { trimmed := StripLeadingComments(sql) - firstWord := trimmed - if end := strings.IndexFunc(trimmed, unicode.IsSpace); end != -1 { - firstWord = trimmed[:end] + if strings.Index(trimmed, "/*!") == 0 { + return StmtComment + } + + isNotLetter := func(r rune) bool { return !unicode.IsLetter(r) } + firstWord := strings.TrimLeftFunc(trimmed, isNotLetter) + + if end := strings.IndexFunc(firstWord, unicode.IsSpace); end != -1 { + firstWord = firstWord[:end] } - firstWord = strings.TrimLeftFunc(firstWord, func(r rune) bool { return !unicode.IsLetter(r) }) // Comparison is done in order of priority. loweredFirstWord := strings.ToLower(firstWord) switch loweredFirstWord { @@ -103,15 +111,11 @@ func Preview(sql string) int { case "analyze", "describe", "desc", "explain", "repair", "optimize": return StmtOther } - if strings.Index(trimmed, "/*!") == 0 { - return StmtComment - } return StmtUnknown } -// StmtType returns the statement type as a string -func StmtType(stmtType int) string { - switch stmtType { +func (s StatementType) String() string { + switch s { case StmtSelect: return "SELECT" case StmtStream: @@ -154,6 +158,23 @@ func IsDML(sql string) bool { return false } +// SplitAndExpression breaks up the Expr into AND-separated conditions +// and appends them to filters. Outer parenthesis are removed. Precedence +// should be taken into account if expressions are recombined. +func SplitAndExpression(filters []Expr, node Expr) []Expr { + if node == nil { + return filters + } + switch node := node.(type) { + case *AndExpr: + filters = SplitAndExpression(filters, node.Left) + return SplitAndExpression(filters, node.Right) + case *ParenExpr: + return SplitAndExpression(filters, node.Expr) + } + return append(filters, node) +} + // GetTableName returns the table name from the SimpleTableExpr // only if it's a simple expression. Otherwise, it returns "". func GetTableName(node SimpleTableExpr) TableIdent { @@ -285,6 +306,9 @@ func ExtractSetValues(sql string) (keyValues map[SetKey]interface{}, scope strin case strings.HasPrefix(key, "@@session."): scope = SessionStr key = strings.TrimPrefix(key, "@@session.") + case strings.HasPrefix(key, "@@vitess_metadata."): + scope = VitessMetadataStr + key = strings.TrimPrefix(key, "@@vitess_metadata.") case strings.HasPrefix(key, "@@"): key = strings.TrimPrefix(key, "@@") } diff --git a/go/vt/sqlparser/analyzer_test.go b/go/vt/sqlparser/analyzer_test.go index 68e24d75ca5..8ecc3ce0dba 100644 --- a/go/vt/sqlparser/analyzer_test.go +++ b/go/vt/sqlparser/analyzer_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -21,17 +21,19 @@ import ( "strings" "testing" + "github.com/stretchr/testify/assert" "vitess.io/vitess/go/sqltypes" ) func TestPreview(t *testing.T) { testcases := []struct { sql string - want int + want StatementType }{ {"select ...", StmtSelect}, {" select ...", StmtSelect}, {"(select ...", StmtSelect}, + {"( select ...", StmtSelect}, {"insert ...", StmtInsert}, {"replace ....", StmtReplace}, {" update ...", StmtUpdate}, @@ -110,6 +112,51 @@ func TestIsDML(t *testing.T) { } } +func TestSplitAndExpression(t *testing.T) { + testcases := []struct { + sql string + out []string + }{{ + sql: "select * from t", + out: nil, + }, { + sql: "select * from t where a = 1", + out: []string{"a = 1"}, + }, { + sql: "select * from t where a = 1 and b = 1", + out: []string{"a = 1", "b = 1"}, + }, { + sql: "select * from t where a = 1 and (b = 1 and c = 1)", + out: []string{"a = 1", "b = 1", "c = 1"}, + }, { + sql: "select * from t where a = 1 and (b = 1 or c = 1)", + out: []string{"a = 1", "b = 1 or c = 1"}, + }, { + sql: "select * from t where a = 1 and b = 1 or c = 1", + out: []string{"a = 1 and b = 1 or c = 1"}, + }, { + sql: "select * from t where a = 1 and b = 1 + (c = 1)", + out: []string{"a = 1", "b = 1 + (c = 1)"}, + }, { + sql: "select * from t where (a = 1 and ((b = 1 and c = 1)))", + out: []string{"a = 1", "b = 1", "c = 1"}, + }} + for _, tcase := range testcases { + stmt, err := Parse(tcase.sql) + assert.NoError(t, err) + var expr Expr + if where := stmt.(*Select).Where; where != nil { + expr = where.Expr + } + splits := SplitAndExpression(nil, expr) + var got []string + for _, split := range splits { + got = append(got, String(split)) + } + assert.Equal(t, tcase.out, got) + } +} + func TestGetTableName(t *testing.T) { testcases := []struct { in, out string diff --git a/go/vt/sqlparser/ast.go b/go/vt/sqlparser/ast.go index 2ea7762ac31..cb74aff4f2a 100644 --- a/go/vt/sqlparser/ast.go +++ b/go/vt/sqlparser/ast.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -662,9 +662,10 @@ type Set struct { // Set.Scope or Show.Scope const ( - SessionStr = "session" - GlobalStr = "global" - ImplicitStr = "" + SessionStr = "session" + GlobalStr = "global" + VitessMetadataStr = "vitess_metadata" + ImplicitStr = "" ) // Format formats the node. @@ -796,9 +797,9 @@ func (node *DDL) Format(buf *TrackedBuffer) { case FlushStr: buf.Myprintf("%s", node.Action) case CreateVindexStr: - buf.Myprintf("alter vschema create vindex %v %v", node.VindexSpec.Name, node.VindexSpec) + buf.Myprintf("alter vschema create vindex %v %v", node.Table, node.VindexSpec) case DropVindexStr: - buf.Myprintf("alter vschema drop vindex %v", node.VindexSpec.Name) + buf.Myprintf("alter vschema drop vindex %v", node.Table) case AddVschemaTableStr: buf.Myprintf("alter vschema add table %v", node.Table) case DropVschemaTableStr: @@ -2006,7 +2007,7 @@ func (node TableName) walkSubtree(visit Visit) error { // IsEmpty returns true if TableName is nil or empty. func (node TableName) IsEmpty() bool { - // If Name is empty, Qualifer is also empty. + // If Name is empty, Qualifier is also empty. return node.Name.IsEmpty() } diff --git a/go/vt/sqlparser/ast_test.go b/go/vt/sqlparser/ast_test.go index f717b7add48..1f18bcb07fa 100644 --- a/go/vt/sqlparser/ast_test.go +++ b/go/vt/sqlparser/ast_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/sqlparser/comments.go b/go/vt/sqlparser/comments.go index 06f6307da5c..26c664cf916 100644 --- a/go/vt/sqlparser/comments.go +++ b/go/vt/sqlparser/comments.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/sqlparser/comments_test.go b/go/vt/sqlparser/comments_test.go index e45a8b4ce00..bd9c26f9b8d 100644 --- a/go/vt/sqlparser/comments_test.go +++ b/go/vt/sqlparser/comments_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/sqlparser/encodable.go b/go/vt/sqlparser/encodable.go index 2c74c6bbeaf..60700248e7c 100644 --- a/go/vt/sqlparser/encodable.go +++ b/go/vt/sqlparser/encodable.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/sqlparser/encodable_test.go b/go/vt/sqlparser/encodable_test.go index 222ecb99726..a27ebf6e4b5 100644 --- a/go/vt/sqlparser/encodable_test.go +++ b/go/vt/sqlparser/encodable_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/sqlparser/impossible_query.go b/go/vt/sqlparser/impossible_query.go index 1179b61120c..785cb36bebb 100644 --- a/go/vt/sqlparser/impossible_query.go +++ b/go/vt/sqlparser/impossible_query.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/sqlparser/like_filter.go b/go/vt/sqlparser/like_filter.go new file mode 100644 index 00000000000..b4219ca66db --- /dev/null +++ b/go/vt/sqlparser/like_filter.go @@ -0,0 +1,50 @@ +/* +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 sqlparser + +import ( + "fmt" + "regexp" + "strings" +) + +var ( + re = regexp.MustCompile(`([^\\]?|[\\]{2})[%_]`) +) + +func replacer(s string) string { + if strings.HasPrefix(s, `\\`) { + return s[2:] + } + + result := strings.Replace(s, "%", ".*", -1) + result = strings.Replace(result, "_", ".", -1) + + return result +} + +// LikeToRegexp converts a like sql expression to regular expression +func LikeToRegexp(likeExpr string) *regexp.Regexp { + if likeExpr == "" { + return regexp.MustCompile("^.*$") // Can never fail + } + + keyPattern := regexp.QuoteMeta(likeExpr) + keyPattern = re.ReplaceAllStringFunc(keyPattern, replacer) + keyPattern = fmt.Sprintf("^%s$", keyPattern) + return regexp.MustCompile(keyPattern) // Can never fail +} diff --git a/go/vt/sqlparser/like_filter_test.go b/go/vt/sqlparser/like_filter_test.go new file mode 100644 index 00000000000..fa7d3d46929 --- /dev/null +++ b/go/vt/sqlparser/like_filter_test.go @@ -0,0 +1,90 @@ +/* +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 sqlparser + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestEmptyLike(t *testing.T) { + want := "^.*$" + got := LikeToRegexp("").String() + + assert.Equal(t, want, got) +} + +func TestLikePrefixRegexp(t *testing.T) { + show, e := Parse("show vitess_metadata variables like 'key%'") + if e != nil { + t.Error(e) + } + + want := "^key.*$" + got := LikeToRegexp(show.(*Show).ShowTablesOpt.Filter.Like).String() + + assert.Equal(t, want, got) +} + +func TestLikeAnyCharsRegexp(t *testing.T) { + show, e := Parse("show vitess_metadata variables like '%val1%val2%'") + if e != nil { + t.Error(e) + } + + want := "^.*val1.*val2.*$" + got := LikeToRegexp(show.(*Show).ShowTablesOpt.Filter.Like).String() + + assert.Equal(t, want, got) +} + +func TestSingleAndMultipleCharsRegexp(t *testing.T) { + show, e := Parse("show vitess_metadata variables like '_val1_val2%'") + if e != nil { + t.Error(e) + } + + want := "^.val1.val2.*$" + got := LikeToRegexp(show.(*Show).ShowTablesOpt.Filter.Like).String() + + assert.Equal(t, want, got) +} + +func TestSpecialCharactersRegexp(t *testing.T) { + show, e := Parse("show vitess_metadata variables like '?.*?'") + if e != nil { + t.Error(e) + } + + want := "^\\?\\.\\*\\?$" + got := LikeToRegexp(show.(*Show).ShowTablesOpt.Filter.Like).String() + + assert.Equal(t, want, got) +} + +func TestQuoteLikeSpecialCharacters(t *testing.T) { + show, e := Parse(`show vitess_metadata variables like 'part1_part2\\%part3_part4\\_part5%'`) + if e != nil { + t.Error(e) + } + + want := "^part1.part2%part3.part4_part5.*$" + got := LikeToRegexp(show.(*Show).ShowTablesOpt.Filter.Like).String() + + assert.Equal(t, want, got) +} diff --git a/go/vt/sqlparser/normalizer.go b/go/vt/sqlparser/normalizer.go index ac223477e27..f715c8f4620 100644 --- a/go/vt/sqlparser/normalizer.go +++ b/go/vt/sqlparser/normalizer.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/sqlparser/normalizer_test.go b/go/vt/sqlparser/normalizer_test.go index b102b0ec2ad..196f2a5d02f 100644 --- a/go/vt/sqlparser/normalizer_test.go +++ b/go/vt/sqlparser/normalizer_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/sqlparser/parse_next_test.go b/go/vt/sqlparser/parse_next_test.go index 98f94f26b84..9f4e9c486d9 100644 --- a/go/vt/sqlparser/parse_next_test.go +++ b/go/vt/sqlparser/parse_next_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/sqlparser/parse_test.go b/go/vt/sqlparser/parse_test.go index d321b2bc932..564edccefc5 100644 --- a/go/vt/sqlparser/parse_test.go +++ b/go/vt/sqlparser/parse_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -17,9 +17,11 @@ limitations under the License. package sqlparser import ( + "bufio" "bytes" "fmt" "math/rand" + "os" "strings" "sync" "testing" @@ -938,6 +940,12 @@ var ( }, { input: "alter table a drop spatial index idx (id)", output: "alter table a", + }, { + input: "alter table a add check ch_1", + output: "alter table a", + }, { + input: "alter table a drop check ch_1", + output: "alter table a", }, { input: "alter table a drop foreign key", output: "alter table a", @@ -971,25 +979,42 @@ var ( output: "create table a (\n\tb1 bool not null primary key,\n\tb2 boolean not null\n)", }, { input: "alter vschema create vindex hash_vdx using hash", + }, { + input: "alter vschema create vindex keyspace.hash_vdx using hash", }, { input: "alter vschema create vindex lookup_vdx using lookup with owner=user, table=name_user_idx, from=name, to=user_id", }, { input: "alter vschema create vindex xyz_vdx using xyz with param1=hello, param2='world', param3=123", }, { input: "alter vschema drop vindex hash_vdx", + }, { + input: "alter vschema drop vindex ks.hash_vdx", }, { input: "alter vschema add table a", + }, { + input: "alter vschema add table ks.a", }, { input: "alter vschema add sequence a_seq", + }, { + input: "alter vschema add sequence ks.a_seq", }, { input: "alter vschema on a add auto_increment id using a_seq", + }, { + input: "alter vschema on ks.a add auto_increment id using a_seq", }, { input: "alter vschema drop table a", + }, { + input: "alter vschema drop table ks.a", }, { input: "alter vschema on a add vindex hash (id)", + }, { + input: "alter vschema on ks.a add vindex hash (id)", }, { input: "alter vschema on a add vindex `hash` (`id`)", output: "alter vschema on a add vindex hash (id)", + }, { + input: "alter vschema on `ks`.a add vindex `hash` (`id`)", + output: "alter vschema on ks.a add vindex hash (id)", }, { input: "alter vschema on a add vindex hash (id) using `hash`", output: "alter vschema on a add vindex hash (id) using hash", @@ -1007,6 +1032,8 @@ var ( output: "alter vschema on user2 add vindex name_lastname_lookup_vdx (name, lastname) using lookup with owner=user, table=name_lastname_keyspace_id_map, from=name,lastname, to=keyspace_id", }, { input: "alter vschema on a drop vindex hash", + }, { + input: "alter vschema on ks.a drop vindex hash", }, { input: "alter vschema on a drop vindex `hash`", output: "alter vschema on a drop vindex hash", @@ -2517,6 +2544,25 @@ func TestSkipToEnd(t *testing.T) { } } +func TestParseDjangoQueries(t *testing.T) { + + file, err := os.Open("./test_queries/django_queries.txt") + defer file.Close() + if err != nil { + t.Errorf(" Error: %v", err) + } + scanner := bufio.NewScanner(file) + + for scanner.Scan() { + + _, err := Parse(string(scanner.Text())) + if err != nil { + t.Error(scanner.Text()) + t.Errorf(" Error: %v", err) + } + } +} + // Benchmark run on 6/23/17, prior to improvements: // BenchmarkParse1-4 100000 16334 ns/op // BenchmarkParse2-4 30000 44121 ns/op diff --git a/go/vt/sqlparser/parsed_query.go b/go/vt/sqlparser/parsed_query.go index 2f6c4e705e7..821ef02494e 100644 --- a/go/vt/sqlparser/parsed_query.go +++ b/go/vt/sqlparser/parsed_query.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/sqlparser/parsed_query_test.go b/go/vt/sqlparser/parsed_query_test.go index 0ea21507ab7..7064c1d01d5 100644 --- a/go/vt/sqlparser/parsed_query_test.go +++ b/go/vt/sqlparser/parsed_query_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/sqlparser/precedence_test.go b/go/vt/sqlparser/precedence_test.go index f6a1c93fc39..1fdd74ada3f 100644 --- a/go/vt/sqlparser/precedence_test.go +++ b/go/vt/sqlparser/precedence_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/sqlparser/redact_query.go b/go/vt/sqlparser/redact_query.go index 60aef071db3..55b760178f8 100644 --- a/go/vt/sqlparser/redact_query.go +++ b/go/vt/sqlparser/redact_query.go @@ -1,3 +1,19 @@ +/* +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 sqlparser import querypb "vitess.io/vitess/go/vt/proto/query" diff --git a/go/vt/sqlparser/redact_query_test.go b/go/vt/sqlparser/redact_query_test.go index 553e6ee0f30..1921b52e5f1 100644 --- a/go/vt/sqlparser/redact_query_test.go +++ b/go/vt/sqlparser/redact_query_test.go @@ -1,3 +1,19 @@ +/* +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 sqlparser import ( diff --git a/go/vt/sqlparser/sql.go b/go/vt/sqlparser/sql.go index 94b2965fc5b..ab9a9ad7337 100644 --- a/go/vt/sqlparser/sql.go +++ b/go/vt/sqlparser/sql.go @@ -221,135 +221,218 @@ const COLUMN = 57456 const SPATIAL = 57457 const FULLTEXT = 57458 const KEY_BLOCK_SIZE = 57459 -const ACTION = 57460 -const CASCADE = 57461 -const CONSTRAINT = 57462 -const FOREIGN = 57463 -const NO = 57464 -const REFERENCES = 57465 -const RESTRICT = 57466 -const SHOW = 57467 -const DESCRIBE = 57468 -const EXPLAIN = 57469 -const DATE = 57470 -const ESCAPE = 57471 -const REPAIR = 57472 -const OPTIMIZE = 57473 -const TRUNCATE = 57474 -const MAXVALUE = 57475 -const PARTITION = 57476 -const REORGANIZE = 57477 -const LESS = 57478 -const THAN = 57479 -const PROCEDURE = 57480 -const TRIGGER = 57481 -const VINDEX = 57482 -const VINDEXES = 57483 -const STATUS = 57484 -const VARIABLES = 57485 -const WARNINGS = 57486 -const SEQUENCE = 57487 -const BEGIN = 57488 -const START = 57489 -const TRANSACTION = 57490 -const COMMIT = 57491 -const ROLLBACK = 57492 -const BIT = 57493 -const TINYINT = 57494 -const SMALLINT = 57495 -const MEDIUMINT = 57496 -const INT = 57497 -const INTEGER = 57498 -const BIGINT = 57499 -const INTNUM = 57500 -const REAL = 57501 -const DOUBLE = 57502 -const FLOAT_TYPE = 57503 -const DECIMAL = 57504 -const NUMERIC = 57505 -const TIME = 57506 -const TIMESTAMP = 57507 -const DATETIME = 57508 -const YEAR = 57509 -const CHAR = 57510 -const VARCHAR = 57511 -const BOOL = 57512 -const CHARACTER = 57513 -const VARBINARY = 57514 -const NCHAR = 57515 -const TEXT = 57516 -const TINYTEXT = 57517 -const MEDIUMTEXT = 57518 -const LONGTEXT = 57519 -const BLOB = 57520 -const TINYBLOB = 57521 -const MEDIUMBLOB = 57522 -const LONGBLOB = 57523 -const JSON = 57524 -const ENUM = 57525 -const GEOMETRY = 57526 -const POINT = 57527 -const LINESTRING = 57528 -const POLYGON = 57529 -const GEOMETRYCOLLECTION = 57530 -const MULTIPOINT = 57531 -const MULTILINESTRING = 57532 -const MULTIPOLYGON = 57533 -const NULLX = 57534 -const AUTO_INCREMENT = 57535 -const APPROXNUM = 57536 -const SIGNED = 57537 -const UNSIGNED = 57538 -const ZEROFILL = 57539 -const COLLATION = 57540 -const DATABASES = 57541 -const TABLES = 57542 -const VSCHEMA = 57543 -const FULL = 57544 -const PROCESSLIST = 57545 -const COLUMNS = 57546 -const FIELDS = 57547 -const ENGINES = 57548 -const PLUGINS = 57549 -const NAMES = 57550 -const CHARSET = 57551 -const GLOBAL = 57552 -const SESSION = 57553 -const ISOLATION = 57554 -const LEVEL = 57555 -const READ = 57556 -const WRITE = 57557 -const ONLY = 57558 -const REPEATABLE = 57559 -const COMMITTED = 57560 -const UNCOMMITTED = 57561 -const SERIALIZABLE = 57562 -const CURRENT_TIMESTAMP = 57563 -const DATABASE = 57564 -const CURRENT_DATE = 57565 -const CURRENT_TIME = 57566 -const LOCALTIME = 57567 -const LOCALTIMESTAMP = 57568 -const UTC_DATE = 57569 -const UTC_TIME = 57570 -const UTC_TIMESTAMP = 57571 -const REPLACE = 57572 -const CONVERT = 57573 -const CAST = 57574 -const SUBSTR = 57575 -const SUBSTRING = 57576 -const GROUP_CONCAT = 57577 -const SEPARATOR = 57578 -const TIMESTAMPADD = 57579 -const TIMESTAMPDIFF = 57580 -const MATCH = 57581 -const AGAINST = 57582 -const BOOLEAN = 57583 -const LANGUAGE = 57584 -const WITH = 57585 -const QUERY = 57586 -const EXPANSION = 57587 -const UNUSED = 57588 +const CHECK = 57460 +const ACTION = 57461 +const CASCADE = 57462 +const CONSTRAINT = 57463 +const FOREIGN = 57464 +const NO = 57465 +const REFERENCES = 57466 +const RESTRICT = 57467 +const SHOW = 57468 +const DESCRIBE = 57469 +const EXPLAIN = 57470 +const DATE = 57471 +const ESCAPE = 57472 +const REPAIR = 57473 +const OPTIMIZE = 57474 +const TRUNCATE = 57475 +const MAXVALUE = 57476 +const PARTITION = 57477 +const REORGANIZE = 57478 +const LESS = 57479 +const THAN = 57480 +const PROCEDURE = 57481 +const TRIGGER = 57482 +const VINDEX = 57483 +const VINDEXES = 57484 +const STATUS = 57485 +const VARIABLES = 57486 +const WARNINGS = 57487 +const SEQUENCE = 57488 +const BEGIN = 57489 +const START = 57490 +const TRANSACTION = 57491 +const COMMIT = 57492 +const ROLLBACK = 57493 +const BIT = 57494 +const TINYINT = 57495 +const SMALLINT = 57496 +const MEDIUMINT = 57497 +const INT = 57498 +const INTEGER = 57499 +const BIGINT = 57500 +const INTNUM = 57501 +const REAL = 57502 +const DOUBLE = 57503 +const FLOAT_TYPE = 57504 +const DECIMAL = 57505 +const NUMERIC = 57506 +const TIME = 57507 +const TIMESTAMP = 57508 +const DATETIME = 57509 +const YEAR = 57510 +const CHAR = 57511 +const VARCHAR = 57512 +const BOOL = 57513 +const CHARACTER = 57514 +const VARBINARY = 57515 +const NCHAR = 57516 +const TEXT = 57517 +const TINYTEXT = 57518 +const MEDIUMTEXT = 57519 +const LONGTEXT = 57520 +const BLOB = 57521 +const TINYBLOB = 57522 +const MEDIUMBLOB = 57523 +const LONGBLOB = 57524 +const JSON = 57525 +const ENUM = 57526 +const GEOMETRY = 57527 +const POINT = 57528 +const LINESTRING = 57529 +const POLYGON = 57530 +const GEOMETRYCOLLECTION = 57531 +const MULTIPOINT = 57532 +const MULTILINESTRING = 57533 +const MULTIPOLYGON = 57534 +const NULLX = 57535 +const AUTO_INCREMENT = 57536 +const APPROXNUM = 57537 +const SIGNED = 57538 +const UNSIGNED = 57539 +const ZEROFILL = 57540 +const COLLATION = 57541 +const DATABASES = 57542 +const TABLES = 57543 +const VITESS_METADATA = 57544 +const VSCHEMA = 57545 +const FULL = 57546 +const PROCESSLIST = 57547 +const COLUMNS = 57548 +const FIELDS = 57549 +const ENGINES = 57550 +const PLUGINS = 57551 +const NAMES = 57552 +const CHARSET = 57553 +const GLOBAL = 57554 +const SESSION = 57555 +const ISOLATION = 57556 +const LEVEL = 57557 +const READ = 57558 +const WRITE = 57559 +const ONLY = 57560 +const REPEATABLE = 57561 +const COMMITTED = 57562 +const UNCOMMITTED = 57563 +const SERIALIZABLE = 57564 +const CURRENT_TIMESTAMP = 57565 +const DATABASE = 57566 +const CURRENT_DATE = 57567 +const CURRENT_TIME = 57568 +const LOCALTIME = 57569 +const LOCALTIMESTAMP = 57570 +const UTC_DATE = 57571 +const UTC_TIME = 57572 +const UTC_TIMESTAMP = 57573 +const REPLACE = 57574 +const CONVERT = 57575 +const CAST = 57576 +const SUBSTR = 57577 +const SUBSTRING = 57578 +const GROUP_CONCAT = 57579 +const SEPARATOR = 57580 +const TIMESTAMPADD = 57581 +const TIMESTAMPDIFF = 57582 +const MATCH = 57583 +const AGAINST = 57584 +const BOOLEAN = 57585 +const LANGUAGE = 57586 +const WITH = 57587 +const QUERY = 57588 +const EXPANSION = 57589 +const UNUSED = 57590 +const ARRAY = 57591 +const CUME_DIST = 57592 +const DESCRIPTION = 57593 +const DENSE_RANK = 57594 +const EMPTY = 57595 +const EXCEPT = 57596 +const FIRST_VALUE = 57597 +const GROUPING = 57598 +const GROUPS = 57599 +const JSON_TABLE = 57600 +const LAG = 57601 +const LAST_VALUE = 57602 +const LATERAL = 57603 +const LEAD = 57604 +const MEMBER = 57605 +const NTH_VALUE = 57606 +const NTILE = 57607 +const OF = 57608 +const OVER = 57609 +const PERCENT_RANK = 57610 +const RANK = 57611 +const RECURSIVE = 57612 +const ROW_NUMBER = 57613 +const SYSTEM = 57614 +const WINDOW = 57615 +const ACTIVE = 57616 +const ADMIN = 57617 +const BUCKETS = 57618 +const CLONE = 57619 +const COMPONENT = 57620 +const DEFINITION = 57621 +const ENFORCED = 57622 +const EXCLUDE = 57623 +const FOLLOWING = 57624 +const GEOMCOLLECTION = 57625 +const GET_MASTER_PUBLIC_KEY = 57626 +const HISTOGRAM = 57627 +const HISTORY = 57628 +const INACTIVE = 57629 +const INVISIBLE = 57630 +const LOCKED = 57631 +const MASTER_COMPRESSION_ALGORITHMS = 57632 +const MASTER_PUBLIC_KEY_PATH = 57633 +const MASTER_TLS_CIPHERSUITES = 57634 +const MASTER_ZSTD_COMPRESSION_LEVEL = 57635 +const NESTED = 57636 +const NETWORK_NAMESPACE = 57637 +const NOWAIT = 57638 +const NULLS = 57639 +const OJ = 57640 +const OLD = 57641 +const OPTIONAL = 57642 +const ORDINALITY = 57643 +const ORGANIZATION = 57644 +const OTHERS = 57645 +const PATH = 57646 +const PERSIST = 57647 +const PERSIST_ONLY = 57648 +const PRECEDING = 57649 +const PRIVILEGE_CHECKS_USER = 57650 +const PROCESS = 57651 +const RANDOM = 57652 +const REFERENCE = 57653 +const REQUIRE_ROW_FORMAT = 57654 +const RESOURCE = 57655 +const RESPECT = 57656 +const RESTART = 57657 +const RETAIN = 57658 +const REUSE = 57659 +const ROLE = 57660 +const SECONDARY = 57661 +const SECONDARY_ENGINE = 57662 +const SECONDARY_LOAD = 57663 +const SECONDARY_UNLOAD = 57664 +const SKIP = 57665 +const SRID = 57666 +const THREAD_PRIORITY = 57667 +const TIES = 57668 +const UNBOUNDED = 57669 +const VCPU = 57670 +const VISIBLE = 57671 var yyToknames = [...]string{ "$end", @@ -486,6 +569,7 @@ var yyToknames = [...]string{ "SPATIAL", "FULLTEXT", "KEY_BLOCK_SIZE", + "CHECK", "ACTION", "CASCADE", "CONSTRAINT", @@ -569,6 +653,7 @@ var yyToknames = [...]string{ "COLLATION", "DATABASES", "TABLES", + "VITESS_METADATA", "VSCHEMA", "FULL", "PROCESSLIST", @@ -615,6 +700,87 @@ var yyToknames = [...]string{ "QUERY", "EXPANSION", "UNUSED", + "ARRAY", + "CUME_DIST", + "DESCRIPTION", + "DENSE_RANK", + "EMPTY", + "EXCEPT", + "FIRST_VALUE", + "GROUPING", + "GROUPS", + "JSON_TABLE", + "LAG", + "LAST_VALUE", + "LATERAL", + "LEAD", + "MEMBER", + "NTH_VALUE", + "NTILE", + "OF", + "OVER", + "PERCENT_RANK", + "RANK", + "RECURSIVE", + "ROW_NUMBER", + "SYSTEM", + "WINDOW", + "ACTIVE", + "ADMIN", + "BUCKETS", + "CLONE", + "COMPONENT", + "DEFINITION", + "ENFORCED", + "EXCLUDE", + "FOLLOWING", + "GEOMCOLLECTION", + "GET_MASTER_PUBLIC_KEY", + "HISTOGRAM", + "HISTORY", + "INACTIVE", + "INVISIBLE", + "LOCKED", + "MASTER_COMPRESSION_ALGORITHMS", + "MASTER_PUBLIC_KEY_PATH", + "MASTER_TLS_CIPHERSUITES", + "MASTER_ZSTD_COMPRESSION_LEVEL", + "NESTED", + "NETWORK_NAMESPACE", + "NOWAIT", + "NULLS", + "OJ", + "OLD", + "OPTIONAL", + "ORDINALITY", + "ORGANIZATION", + "OTHERS", + "PATH", + "PERSIST", + "PERSIST_ONLY", + "PRECEDING", + "PRIVILEGE_CHECKS_USER", + "PROCESS", + "RANDOM", + "REFERENCE", + "REQUIRE_ROW_FORMAT", + "RESOURCE", + "RESPECT", + "RESTART", + "RETAIN", + "REUSE", + "ROLE", + "SECONDARY", + "SECONDARY_ENGINE", + "SECONDARY_LOAD", + "SECONDARY_UNLOAD", + "SKIP", + "SRID", + "THREAD_PRIORITY", + "TIES", + "UNBOUNDED", + "VCPU", + "VISIBLE", "';'", } var yyStatenames = [...]string{} @@ -632,1358 +798,1757 @@ var yyExca = [...]int{ 5, 29, -2, 4, -1, 37, - 159, 296, - 160, 296, - -2, 286, - -1, 260, - 112, 636, - -2, 632, - -1, 261, - 112, 637, - -2, 633, - -1, 329, - 82, 811, + 160, 300, + 161, 300, + -2, 288, + -1, 320, + 112, 640, + -2, 636, + -1, 321, + 112, 641, + -2, 637, + -1, 389, + 82, 888, -2, 63, - -1, 330, - 82, 767, + -1, 390, + 82, 806, -2, 64, - -1, 335, - 82, 746, - -2, 598, - -1, 337, - 82, 788, - -2, 600, - -1, 606, - 1, 348, - 5, 348, - 12, 348, - 13, 348, - 14, 348, - 15, 348, - 17, 348, - 19, 348, - 30, 348, - 31, 348, - 42, 348, - 43, 348, - 44, 348, - 45, 348, - 46, 348, - 48, 348, - 49, 348, - 52, 348, - 53, 348, - 55, 348, - 56, 348, - 264, 348, - -2, 366, - -1, 609, + -1, 395, + 82, 775, + -2, 602, + -1, 397, + 82, 836, + -2, 604, + -1, 689, + 1, 352, + 5, 352, + 12, 352, + 13, 352, + 14, 352, + 15, 352, + 17, 352, + 19, 352, + 30, 352, + 31, 352, + 42, 352, + 43, 352, + 44, 352, + 45, 352, + 46, 352, + 48, 352, + 49, 352, + 52, 352, + 53, 352, + 55, 352, + 56, 352, + 347, 352, + -2, 370, + -1, 692, 53, 44, 55, 44, -2, 48, - -1, 755, - 112, 639, - -2, 635, - -1, 983, + -1, 840, + 112, 643, + -2, 639, + -1, 1069, 5, 30, - -2, 433, - -1, 1013, + -2, 437, + -1, 1099, 5, 29, - -2, 572, - -1, 1257, + -2, 576, + -1, 1344, 5, 30, - -2, 573, - -1, 1310, + -2, 577, + -1, 1397, 5, 29, - -2, 575, - -1, 1388, + -2, 579, + -1, 1475, 5, 30, - -2, 576, + -2, 580, } const yyPrivate = 57344 -const yyLast = 12651 +const yyLast = 16596 var yyAct = [...]int{ - 261, 1412, 1219, 1422, 1322, 1376, 1107, 265, 1016, 1277, - 562, 1290, 1034, 868, 1159, 278, 1193, 841, 239, 897, - 891, 57, 291, 864, 839, 1156, 1017, 1160, 911, 948, - 1040, 1166, 81, 230, 867, 877, 205, 1061, 1172, 205, - 706, 1131, 334, 780, 790, 561, 3, 622, 975, 1087, - 843, 1078, 787, 881, 500, 828, 808, 757, 720, 494, - 621, 292, 51, 328, 907, 435, 603, 205, 81, 514, - 248, 602, 205, 323, 205, 821, 506, 263, 231, 232, - 233, 234, 320, 611, 237, 56, 1415, 325, 1399, 1410, - 1386, 1407, 608, 1220, 1398, 577, 1385, 238, 930, 1148, - 267, 1249, 440, 1049, 1188, 1189, 1048, 468, 252, 1050, - 859, 860, 929, 51, 1187, 576, 200, 196, 197, 198, - 623, 244, 624, 858, 192, 236, 194, 303, 202, 309, - 310, 307, 308, 306, 305, 304, 488, 235, 1069, 890, - 934, 1109, 61, 311, 312, 1280, 898, 484, 453, 928, - 485, 482, 483, 1297, 1240, 1238, 229, 1111, 695, 322, - 477, 478, 692, 1409, 437, 1406, 439, 1377, 63, 64, - 65, 66, 67, 470, 464, 472, 1351, 527, 526, 536, - 537, 529, 530, 531, 532, 533, 534, 535, 528, 694, - 1106, 538, 822, 205, 1110, 487, 205, 696, 1369, 925, - 922, 923, 205, 921, 1430, 469, 471, 1094, 205, 882, - 454, 81, 1331, 81, 1323, 81, 81, 193, 81, 442, - 81, 1035, 1037, 693, 1103, 81, 1426, 1325, 194, 1112, - 1105, 699, 685, 199, 932, 935, 1092, 1182, 527, 526, - 536, 537, 529, 530, 531, 532, 533, 534, 535, 528, - 1181, 1180, 538, 438, 884, 81, 445, 884, 207, 195, - 942, 550, 551, 941, 502, 1358, 1260, 1118, 1045, 490, - 491, 927, 465, 450, 465, 1002, 465, 465, 969, 465, - 992, 465, 989, 1062, 898, 446, 465, 729, 452, 467, - 503, 976, 617, 926, 459, 1324, 865, 518, 1036, 460, - 461, 528, 538, 1093, 538, 1384, 51, 854, 1098, 1095, - 1088, 1096, 1091, 1332, 1330, 726, 1089, 1090, 205, 205, - 205, 547, 512, 511, 549, 513, 1104, 81, 1102, 1152, - 1097, 931, 1424, 81, 721, 1425, 447, 1423, 448, 513, - 1205, 449, 1367, 601, 1352, 1340, 933, 456, 457, 458, - 883, 1150, 560, 883, 564, 565, 566, 567, 568, 569, - 570, 571, 572, 548, 575, 578, 578, 578, 584, 578, - 578, 584, 578, 592, 593, 594, 595, 596, 597, 884, - 607, 764, 550, 551, 550, 551, 988, 473, 504, 474, - 475, 1206, 476, 1170, 479, 762, 763, 761, 950, 489, - 580, 582, 610, 586, 588, 615, 591, 70, 436, 436, - 600, 511, 609, 789, 619, 722, 512, 511, 625, 606, - 579, 581, 583, 585, 587, 589, 590, 513, 809, 987, - 999, 986, 466, 513, 441, 205, 512, 511, 809, 687, - 81, 1067, 434, 71, 1372, 205, 205, 81, 512, 511, - 887, 205, 191, 513, 205, 1392, 888, 205, 966, 967, - 968, 205, 508, 81, 81, 513, 1431, 258, 81, 81, - 81, 205, 81, 81, 1390, 883, 949, 54, 81, 81, - 880, 878, 1286, 879, 747, 749, 750, 760, 876, 882, - 748, 1132, 529, 530, 531, 532, 533, 534, 535, 528, - 331, 465, 538, 708, 1285, 1432, 81, 781, 465, 782, - 205, 443, 444, 1082, 1081, 1070, 81, 317, 318, 22, - 1368, 734, 732, 733, 465, 465, 1304, 633, 1134, 465, - 465, 465, 1283, 465, 465, 728, 700, 689, 690, 465, - 465, 1115, 1079, 697, 758, 1051, 322, 1052, 1365, 703, - 531, 532, 533, 534, 535, 528, 1328, 1408, 538, 753, - 81, 755, 1136, 714, 1140, 1222, 1135, 1062, 1133, 1057, - 512, 511, 727, 1138, 493, 736, 783, 799, 802, 243, - 1394, 493, 1137, 810, 705, 751, 704, 513, 688, 512, - 511, 1328, 1380, 81, 81, 1139, 1141, 1328, 493, 1337, - 205, 813, 743, 1328, 1359, 1336, 513, 686, 205, 205, - 794, 51, 205, 205, 684, 683, 205, 205, 205, 81, - 462, 691, 759, 1328, 1327, 1202, 564, 455, 784, 785, - 1275, 1274, 81, 1262, 493, 885, 849, 709, 710, 848, - 851, 612, 711, 712, 713, 1169, 715, 716, 818, 806, - 1259, 493, 717, 718, 1212, 1211, 1208, 1209, 1208, 1207, - 708, 792, 893, 894, 895, 896, 899, 900, 901, 840, - 981, 493, 1041, 607, 825, 493, 1041, 607, 904, 905, - 906, 856, 855, 792, 493, 847, 205, 81, 613, 81, - 852, 613, 823, 81, 81, 205, 205, 205, 872, 205, - 205, 632, 631, 205, 81, 850, 1157, 58, 606, 1169, - 1255, 913, 606, 1339, 1121, 825, 606, 825, 24, 1169, - 205, 24, 205, 205, 1210, 205, 824, 1053, 857, 1005, - 614, 1004, 616, 614, 981, 612, 552, 553, 554, 555, - 556, 557, 558, 559, 909, 910, 1309, 981, 465, 54, - 465, 825, 281, 280, 283, 284, 285, 286, 981, 331, - 493, 282, 287, 612, 618, 465, 54, 245, 730, 54, - 957, 698, 755, 830, 833, 834, 835, 831, 916, 832, - 836, 1400, 1292, 892, 758, 958, 24, 938, 939, 940, - 1267, 943, 944, 912, 959, 945, 1198, 527, 526, 536, - 537, 529, 530, 531, 532, 533, 534, 535, 528, 1056, - 1011, 538, 947, 908, 1012, 54, 970, 953, 903, 971, - 1173, 1174, 1417, 902, 1108, 1293, 205, 205, 205, 205, - 205, 915, 1018, 1413, 54, 1200, 1176, 1157, 205, 1083, - 492, 205, 724, 702, 742, 205, 1028, 1026, 1179, 205, - 1178, 1029, 1027, 1030, 1025, 834, 835, 1024, 249, 250, - 1404, 917, 759, 919, 998, 1397, 1117, 1013, 81, 954, - 507, 1402, 964, 1042, 290, 963, 1074, 630, 946, 1066, - 1043, 1054, 1044, 1014, 1015, 505, 794, 607, 607, 607, - 607, 607, 1031, 1020, 1021, 1039, 1023, 1019, 463, 495, - 1022, 1374, 840, 1373, 1038, 1046, 79, 1307, 1288, 1064, - 607, 496, 1058, 1071, 1072, 1253, 81, 81, 918, 1063, - 701, 1073, 838, 1075, 1076, 1077, 606, 606, 606, 606, - 606, 246, 247, 1059, 1060, 962, 507, 240, 1345, 241, - 58, 606, 333, 961, 1344, 1295, 81, 1041, 486, 606, - 993, 754, 990, 254, 1086, 1080, 830, 833, 834, 835, - 831, 205, 832, 836, 1419, 1418, 1173, 1174, 719, 509, - 81, 1419, 1099, 1355, 1281, 725, 60, 62, 465, 795, - 796, 55, 1, 801, 804, 805, 1411, 1221, 756, 1289, - 924, 765, 766, 767, 768, 769, 770, 771, 772, 773, - 774, 775, 776, 777, 778, 779, 1114, 465, 817, 1375, - 819, 820, 1321, 1192, 875, 81, 81, 866, 1149, 1018, - 1158, 1125, 69, 1124, 433, 68, 1130, 1366, 874, 873, - 1143, 1142, 1329, 1279, 886, 1161, 1068, 889, 1199, 81, - 1065, 1371, 638, 957, 636, 755, 814, 1168, 637, 635, - 640, 331, 639, 1119, 81, 634, 81, 81, 218, 326, - 1163, 1177, 1184, 837, 869, 626, 914, 510, 72, 1191, - 1183, 1101, 1100, 1186, 1162, 920, 51, 480, 481, 220, - 546, 960, 1047, 332, 205, 333, 1164, 333, 1190, 333, - 333, 1085, 333, 1195, 333, 1203, 1204, 1196, 1197, 333, - 731, 205, 499, 1343, 1294, 735, 997, 81, 573, 807, - 81, 81, 81, 205, 266, 746, 279, 276, 277, 81, - 1113, 1214, 205, 737, 1010, 520, 264, 256, 605, 516, - 598, 829, 827, 1215, 826, 1217, 321, 1175, 1171, 604, - 1120, 1248, 1350, 741, 1227, 26, 1229, 59, 251, 19, - 18, 1228, 17, 1233, 1234, 965, 1235, 20, 16, 1237, - 15, 1239, 754, 791, 793, 1236, 536, 537, 529, 530, - 531, 532, 533, 534, 535, 528, 1213, 1018, 538, 14, - 451, 30, 21, 607, 1254, 13, 12, 11, 10, 9, - 1263, 81, 8, 1216, 497, 501, 1264, 7, 6, 81, - 5, 333, 980, 1273, 1054, 1226, 4, 627, 242, 23, - 1247, 519, 2, 0, 81, 1276, 0, 0, 0, 0, - 996, 81, 606, 0, 0, 0, 0, 1282, 0, 1284, - 972, 973, 974, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1269, 1270, 1271, 0, 563, 0, 0, 0, - 0, 0, 0, 0, 1296, 574, 0, 0, 0, 0, - 81, 81, 0, 81, 0, 0, 0, 0, 81, 0, - 81, 81, 81, 205, 0, 465, 81, 1316, 1161, 1317, - 1318, 1319, 1315, 1308, 0, 0, 0, 0, 0, 0, - 1320, 0, 1326, 81, 205, 0, 0, 1333, 0, 0, - 869, 0, 1341, 0, 1310, 0, 1334, 0, 1335, 0, - 0, 0, 0, 0, 333, 0, 0, 1162, 0, 0, - 1311, 333, 0, 0, 1356, 0, 1364, 0, 0, 81, - 0, 0, 1161, 1363, 0, 0, 0, 333, 333, 0, - 81, 81, 333, 333, 333, 0, 333, 333, 0, 0, - 1338, 1378, 333, 333, 1379, 0, 1382, 1357, 0, 81, - 0, 0, 0, 1018, 1387, 0, 0, 0, 0, 0, - 205, 1162, 0, 51, 0, 0, 0, 0, 81, 0, - 738, 0, 0, 0, 0, 978, 1342, 1396, 1287, 979, - 516, 0, 0, 333, 0, 0, 983, 984, 985, 1403, - 1401, 81, 1123, 991, 0, 0, 994, 995, 0, 0, - 1405, 0, 1001, 1416, 0, 0, 1003, 0, 0, 1006, - 1007, 1008, 1009, 1427, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 786, 1153, 0, 0, 0, 0, - 723, 1033, 0, 0, 1127, 1128, 0, 0, 0, 0, - 811, 0, 0, 0, 0, 0, 0, 1144, 1145, 0, - 1146, 1147, 1391, 0, 0, 744, 745, 815, 816, 0, - 0, 1414, 1154, 1155, 0, 24, 25, 52, 27, 28, - 0, 0, 0, 0, 0, 0, 869, 0, 869, 0, - 0, 0, 0, 333, 43, 0, 0, 1252, 0, 29, - 48, 49, 0, 0, 0, 0, 333, 526, 536, 537, - 529, 530, 531, 532, 533, 534, 535, 528, 563, 38, - 538, 797, 798, 54, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1201, 527, 526, 536, 537, 529, - 530, 531, 532, 533, 534, 535, 528, 0, 0, 538, - 0, 1123, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 333, 0, 333, 0, 0, 0, 936, 937, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 333, 863, - 0, 0, 1129, 0, 31, 32, 34, 33, 36, 0, - 50, 0, 0, 0, 1231, 1246, 0, 0, 0, 0, - 0, 0, 1251, 0, 333, 0, 0, 0, 0, 0, - 0, 37, 44, 45, 0, 215, 46, 47, 35, 0, - 0, 0, 0, 869, 0, 0, 0, 0, 0, 498, - 0, 0, 39, 40, 0, 41, 42, 0, 0, 224, - 527, 526, 536, 537, 529, 530, 531, 532, 533, 534, - 535, 528, 0, 1291, 538, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 203, 0, 0, 228, 527, - 526, 536, 537, 529, 530, 531, 532, 533, 534, 535, - 528, 955, 956, 538, 501, 0, 0, 0, 0, 0, - 208, 0, 0, 255, 0, 0, 324, 211, 0, 811, - 0, 203, 0, 203, 0, 219, 214, 0, 0, 0, - 0, 1298, 1299, 1300, 1301, 1302, 53, 0, 0, 1305, - 1306, 0, 0, 0, 0, 0, 1230, 1126, 0, 0, - 0, 0, 0, 1232, 0, 0, 0, 217, 0, 0, - 0, 0, 333, 223, 1241, 1242, 982, 527, 526, 536, - 537, 529, 530, 531, 532, 533, 534, 535, 528, 0, - 0, 538, 0, 1000, 1256, 1257, 1258, 0, 1261, 0, - 209, 0, 1291, 869, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1272, 0, 0, 0, 0, - 1084, 333, 0, 0, 0, 0, 0, 221, 212, 0, - 222, 227, 0, 0, 0, 213, 216, 0, 210, 226, - 225, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 333, 0, 203, 0, 0, 203, 0, 0, 0, 0, - 0, 203, 0, 0, 0, 0, 0, 203, 0, 0, - 0, 0, 0, 522, 333, 525, 0, 0, 0, 0, - 1303, 539, 540, 541, 542, 543, 544, 545, 1245, 523, - 524, 521, 527, 526, 536, 537, 529, 530, 531, 532, - 533, 534, 535, 528, 0, 0, 538, 333, 0, 0, - 0, 0, 1420, 0, 0, 0, 811, 1244, 0, 1165, - 1167, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1346, 1347, 1348, 1349, 1116, 0, 0, 1353, 1354, 0, - 0, 0, 0, 1167, 0, 0, 0, 0, 0, 1360, - 1361, 1362, 1243, 0, 0, 0, 0, 0, 333, 0, - 333, 1194, 527, 526, 536, 537, 529, 530, 531, 532, - 533, 534, 535, 528, 0, 0, 538, 203, 203, 203, - 0, 0, 1383, 1151, 0, 0, 0, 0, 0, 1388, - 0, 527, 526, 536, 537, 529, 530, 531, 532, 533, - 534, 535, 528, 0, 0, 538, 0, 1393, 0, 0, - 0, 1218, 0, 0, 1223, 1224, 1225, 0, 0, 0, - 0, 0, 0, 333, 0, 1185, 527, 526, 536, 537, - 529, 530, 531, 532, 533, 534, 535, 528, 977, 0, - 538, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1428, 1429, 0, 0, 0, 0, 527, 526, - 536, 537, 529, 530, 531, 532, 533, 534, 535, 528, - 0, 0, 538, 0, 811, 527, 526, 536, 537, 529, - 530, 531, 532, 533, 534, 535, 528, 0, 0, 538, - 0, 0, 0, 0, 203, 333, 0, 0, 0, 0, - 0, 0, 0, 1278, 203, 203, 0, 0, 0, 0, - 203, 0, 0, 203, 0, 0, 203, 0, 333, 0, - 707, 0, 0, 0, 0, 333, 0, 0, 0, 0, - 203, 0, 0, 0, 0, 0, 1250, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 563, 0, 0, 0, - 0, 0, 0, 0, 1265, 0, 0, 1266, 0, 0, - 1268, 0, 0, 0, 1312, 1313, 0, 1314, 0, 203, - 0, 0, 1278, 0, 1278, 1278, 1278, 0, 707, 0, - 1194, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1278, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 255, 0, 0, 0, 0, 255, 255, 0, 0, 255, - 255, 255, 0, 1370, 0, 812, 0, 0, 0, 0, - 0, 0, 0, 0, 333, 333, 0, 0, 0, 0, - 0, 0, 0, 0, 255, 255, 255, 255, 0, 203, - 811, 0, 0, 1389, 0, 0, 0, 203, 845, 0, - 0, 203, 203, 0, 0, 203, 853, 707, 0, 0, - 0, 0, 1395, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1278, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1381, 563, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 203, 0, 0, 0, 0, - 0, 0, 0, 0, 203, 203, 203, 0, 203, 203, - 0, 0, 203, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 203, - 0, 951, 952, 0, 203, 0, 0, 0, 0, 707, - 0, 0, 0, 0, 0, 139, 0, 0, 0, 844, - 0, 255, 0, 0, 103, 0, 0, 0, 0, 0, - 120, 0, 122, 0, 0, 160, 131, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 204, 0, 846, 0, 0, 0, - 0, 0, 0, 96, 0, 0, 0, 0, 255, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 812, 203, 203, 203, 203, 203, - 0, 0, 0, 0, 0, 0, 0, 1032, 109, 0, - 203, 0, 206, 0, 845, 0, 0, 146, 203, 163, - 111, 119, 83, 90, 0, 110, 137, 151, 155, 0, - 0, 0, 99, 0, 153, 141, 176, 0, 142, 152, - 123, 168, 147, 175, 183, 184, 165, 182, 186, 157, - 84, 164, 174, 97, 156, 86, 172, 162, 129, 115, - 116, 85, 0, 150, 102, 107, 101, 138, 169, 170, - 100, 189, 91, 181, 88, 92, 180, 136, 167, 173, - 130, 127, 87, 171, 128, 126, 118, 105, 112, 144, - 125, 145, 113, 133, 132, 134, 0, 0, 0, 161, - 178, 190, 94, 0, 166, 185, 0, 0, 95, 108, - 104, 143, 135, 93, 114, 158, 117, 124, 149, 188, - 140, 154, 98, 177, 159, 0, 0, 0, 0, 0, - 203, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 255, 0, 0, 0, 82, 89, 121, 187, 148, 106, - 179, 255, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 707, 0, 0, 0, 0, 0, 0, 0, - 0, 812, 139, 0, 0, 0, 0, 262, 0, 0, - 0, 103, 0, 259, 0, 0, 0, 120, 302, 122, - 0, 0, 160, 131, 0, 0, 0, 0, 293, 294, - 0, 0, 0, 0, 0, 0, 861, 0, 54, 0, - 0, 260, 281, 280, 283, 284, 285, 286, 0, 0, - 96, 282, 287, 288, 289, 862, 0, 0, 257, 274, - 0, 301, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 203, 0, 0, 0, 0, 0, 0, - 0, 271, 272, 0, 0, 0, 0, 315, 0, 273, - 203, 0, 268, 269, 270, 275, 0, 0, 0, 0, - 0, 0, 203, 0, 0, 109, 0, 0, 0, 206, - 0, 203, 313, 0, 146, 0, 163, 111, 119, 83, - 90, 0, 110, 137, 151, 155, 0, 0, 0, 99, - 0, 153, 141, 176, 0, 142, 152, 123, 168, 147, - 175, 183, 184, 165, 182, 186, 157, 84, 164, 174, - 97, 156, 86, 172, 162, 129, 115, 116, 85, 812, - 150, 102, 107, 101, 138, 169, 170, 100, 189, 91, - 181, 88, 92, 180, 136, 167, 173, 130, 127, 87, - 171, 128, 126, 118, 105, 112, 144, 125, 145, 113, - 133, 132, 134, 0, 0, 0, 161, 178, 190, 94, - 0, 166, 185, 0, 0, 95, 108, 104, 143, 135, - 93, 114, 158, 117, 124, 149, 188, 140, 154, 98, - 177, 159, 303, 314, 309, 310, 307, 308, 306, 305, - 304, 316, 295, 296, 297, 298, 300, 0, 311, 312, - 299, 82, 89, 121, 187, 148, 106, 179, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 845, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 203, 0, 0, 0, 0, 0, 421, - 410, 0, 381, 424, 359, 373, 432, 374, 375, 403, - 345, 389, 139, 371, 0, 362, 340, 368, 341, 360, - 383, 103, 386, 358, 412, 392, 423, 120, 430, 122, - 397, 0, 160, 131, 0, 0, 385, 414, 387, 408, - 380, 404, 350, 396, 425, 372, 401, 426, 0, 0, - 0, 80, 0, 870, 871, 812, 0, 0, 0, 0, - 96, 0, 399, 420, 370, 400, 402, 339, 398, 203, - 343, 346, 431, 416, 365, 366, 1055, 0, 0, 0, - 0, 0, 0, 384, 388, 405, 378, 0, 0, 0, - 0, 0, 0, 0, 0, 363, 0, 395, 0, 0, - 0, 347, 344, 0, 0, 382, 0, 0, 0, 349, - 0, 364, 406, 0, 338, 109, 409, 415, 379, 206, - 419, 377, 376, 422, 146, 0, 163, 111, 119, 83, - 90, 0, 110, 137, 151, 155, 413, 361, 369, 99, - 367, 153, 141, 176, 394, 142, 152, 123, 168, 147, - 175, 183, 184, 165, 182, 186, 157, 84, 164, 174, - 97, 156, 86, 172, 162, 129, 115, 116, 85, 0, - 150, 102, 107, 101, 138, 169, 170, 100, 189, 91, - 181, 88, 92, 180, 136, 167, 173, 130, 127, 87, - 171, 128, 126, 118, 105, 112, 144, 125, 145, 113, - 133, 132, 134, 0, 342, 0, 161, 178, 190, 94, - 357, 166, 185, 0, 0, 95, 108, 104, 143, 135, - 93, 114, 158, 117, 124, 149, 188, 140, 154, 98, - 177, 159, 353, 356, 351, 352, 390, 391, 427, 428, - 429, 407, 348, 0, 354, 355, 0, 411, 417, 418, - 393, 82, 89, 121, 187, 148, 106, 179, 421, 410, - 0, 381, 424, 359, 373, 432, 374, 375, 403, 345, - 389, 139, 371, 0, 362, 340, 368, 341, 360, 383, - 103, 386, 358, 412, 392, 423, 120, 430, 122, 397, - 0, 160, 131, 0, 0, 385, 414, 387, 408, 380, - 404, 350, 396, 425, 372, 401, 426, 0, 0, 0, - 80, 0, 870, 871, 0, 0, 0, 0, 0, 96, - 0, 399, 420, 370, 400, 402, 339, 398, 0, 343, - 346, 431, 416, 365, 366, 0, 0, 0, 0, 0, - 0, 0, 384, 388, 405, 378, 0, 0, 0, 0, - 0, 0, 0, 0, 363, 0, 395, 0, 0, 0, - 347, 344, 0, 0, 382, 0, 0, 0, 349, 0, - 364, 406, 0, 338, 109, 409, 415, 379, 206, 419, - 377, 376, 422, 146, 0, 163, 111, 119, 83, 90, - 0, 110, 137, 151, 155, 413, 361, 369, 99, 367, - 153, 141, 176, 394, 142, 152, 123, 168, 147, 175, - 183, 184, 165, 182, 186, 157, 84, 164, 174, 97, - 156, 86, 172, 162, 129, 115, 116, 85, 0, 150, - 102, 107, 101, 138, 169, 170, 100, 189, 91, 181, - 88, 92, 180, 136, 167, 173, 130, 127, 87, 171, - 128, 126, 118, 105, 112, 144, 125, 145, 113, 133, - 132, 134, 0, 342, 0, 161, 178, 190, 94, 357, - 166, 185, 0, 0, 95, 108, 104, 143, 135, 93, - 114, 158, 117, 124, 149, 188, 140, 154, 98, 177, - 159, 353, 356, 351, 352, 390, 391, 427, 428, 429, - 407, 348, 0, 354, 355, 0, 411, 417, 418, 393, - 82, 89, 121, 187, 148, 106, 179, 421, 410, 0, - 381, 424, 359, 373, 432, 374, 375, 403, 345, 389, - 139, 371, 0, 362, 340, 368, 341, 360, 383, 103, - 386, 358, 412, 392, 423, 120, 430, 122, 397, 0, - 160, 131, 0, 0, 385, 414, 387, 408, 380, 404, - 350, 396, 425, 372, 401, 426, 54, 0, 0, 80, - 0, 0, 0, 0, 0, 0, 0, 0, 96, 0, - 399, 420, 370, 400, 402, 339, 398, 0, 343, 346, - 431, 416, 365, 366, 0, 0, 0, 0, 0, 0, - 0, 384, 388, 405, 378, 0, 0, 0, 0, 0, - 0, 0, 0, 363, 0, 395, 0, 0, 0, 347, - 344, 0, 0, 382, 0, 0, 0, 349, 0, 364, - 406, 0, 338, 109, 409, 415, 379, 206, 419, 377, - 376, 422, 146, 0, 163, 111, 119, 83, 90, 0, - 110, 137, 151, 155, 413, 361, 369, 99, 367, 153, - 141, 176, 394, 142, 152, 123, 168, 147, 175, 183, - 184, 165, 182, 186, 157, 84, 164, 174, 97, 156, - 86, 172, 162, 129, 115, 116, 85, 0, 150, 102, - 107, 101, 138, 169, 170, 100, 189, 91, 181, 88, - 92, 180, 136, 167, 173, 130, 127, 87, 171, 128, - 126, 118, 105, 112, 144, 125, 145, 113, 133, 132, - 134, 0, 342, 0, 161, 178, 190, 94, 357, 166, - 185, 0, 0, 95, 108, 104, 143, 135, 93, 114, - 158, 117, 124, 149, 188, 140, 154, 98, 177, 159, - 353, 356, 351, 352, 390, 391, 427, 428, 429, 407, - 348, 0, 354, 355, 0, 411, 417, 418, 393, 82, - 89, 121, 187, 148, 106, 179, 421, 410, 0, 381, - 424, 359, 373, 432, 374, 375, 403, 345, 389, 139, - 371, 0, 362, 340, 368, 341, 360, 383, 103, 386, - 358, 412, 392, 423, 120, 430, 122, 397, 0, 160, - 131, 0, 0, 385, 414, 387, 408, 380, 404, 350, - 396, 425, 372, 401, 426, 0, 0, 0, 80, 0, - 0, 0, 0, 0, 0, 0, 0, 96, 0, 399, - 420, 370, 400, 402, 339, 398, 0, 343, 346, 431, - 416, 365, 366, 0, 0, 0, 0, 0, 0, 0, - 384, 388, 405, 378, 0, 0, 0, 0, 0, 0, - 1122, 0, 363, 0, 395, 0, 0, 0, 347, 344, - 0, 0, 382, 0, 0, 0, 349, 0, 364, 406, - 0, 338, 109, 409, 415, 379, 206, 419, 377, 376, - 422, 146, 0, 163, 111, 119, 83, 90, 0, 110, - 137, 151, 155, 413, 361, 369, 99, 367, 153, 141, - 176, 394, 142, 152, 123, 168, 147, 175, 183, 184, - 165, 182, 186, 157, 84, 164, 174, 97, 156, 86, - 172, 162, 129, 115, 116, 85, 0, 150, 102, 107, - 101, 138, 169, 170, 100, 189, 91, 181, 88, 92, - 180, 136, 167, 173, 130, 127, 87, 171, 128, 126, - 118, 105, 112, 144, 125, 145, 113, 133, 132, 134, - 0, 342, 0, 161, 178, 190, 94, 357, 166, 185, - 0, 0, 95, 108, 104, 143, 135, 93, 114, 158, - 117, 124, 149, 188, 140, 154, 98, 177, 159, 353, - 356, 351, 352, 390, 391, 427, 428, 429, 407, 348, - 0, 354, 355, 0, 411, 417, 418, 393, 82, 89, - 121, 187, 148, 106, 179, 421, 410, 0, 381, 424, - 359, 373, 432, 374, 375, 403, 345, 389, 139, 371, - 0, 362, 340, 368, 341, 360, 383, 103, 386, 358, - 412, 392, 423, 120, 430, 122, 397, 0, 160, 131, - 0, 0, 385, 414, 387, 408, 380, 404, 350, 396, - 425, 372, 401, 426, 0, 0, 0, 204, 0, 0, - 0, 0, 0, 0, 0, 0, 96, 0, 399, 420, - 370, 400, 402, 339, 398, 0, 343, 346, 431, 416, - 365, 366, 0, 0, 0, 0, 0, 0, 0, 384, - 388, 405, 378, 0, 0, 0, 0, 0, 0, 854, - 0, 363, 0, 395, 0, 0, 0, 347, 344, 0, - 0, 382, 0, 0, 0, 349, 0, 364, 406, 0, - 338, 109, 409, 415, 379, 206, 419, 377, 376, 422, - 146, 0, 163, 111, 119, 83, 90, 0, 110, 137, - 151, 155, 413, 361, 369, 99, 367, 153, 141, 176, - 394, 142, 152, 123, 168, 147, 175, 183, 184, 165, - 182, 186, 157, 84, 164, 174, 97, 156, 86, 172, - 162, 129, 115, 116, 85, 0, 150, 102, 107, 101, - 138, 169, 170, 100, 189, 91, 181, 88, 92, 180, - 136, 167, 173, 130, 127, 87, 171, 128, 126, 118, - 105, 112, 144, 125, 145, 113, 133, 132, 134, 0, - 342, 0, 161, 178, 190, 94, 357, 166, 185, 0, - 0, 95, 108, 104, 143, 135, 93, 114, 158, 117, - 124, 149, 188, 140, 154, 98, 177, 159, 353, 356, - 351, 352, 390, 391, 427, 428, 429, 407, 348, 0, - 354, 355, 0, 411, 417, 418, 393, 82, 89, 121, - 187, 148, 106, 179, 421, 410, 0, 381, 424, 359, - 373, 432, 374, 375, 403, 345, 389, 139, 371, 0, - 362, 340, 368, 341, 360, 383, 103, 386, 358, 412, - 392, 423, 120, 430, 122, 397, 0, 160, 131, 0, - 0, 385, 414, 387, 408, 380, 404, 350, 396, 425, - 372, 401, 426, 0, 0, 0, 260, 0, 0, 0, - 0, 0, 0, 0, 0, 96, 0, 399, 420, 370, - 400, 402, 339, 398, 0, 343, 346, 431, 416, 365, - 366, 0, 0, 0, 0, 0, 0, 0, 384, 388, - 405, 378, 0, 0, 0, 0, 0, 0, 752, 0, - 363, 0, 395, 0, 0, 0, 347, 344, 0, 0, - 382, 0, 0, 0, 349, 0, 364, 406, 0, 338, - 109, 409, 415, 379, 206, 419, 377, 376, 422, 146, - 0, 163, 111, 119, 83, 90, 0, 110, 137, 151, - 155, 413, 361, 369, 99, 367, 153, 141, 176, 394, - 142, 152, 123, 168, 147, 175, 183, 184, 165, 182, - 186, 157, 84, 164, 174, 97, 156, 86, 172, 162, - 129, 115, 116, 85, 0, 150, 102, 107, 101, 138, - 169, 170, 100, 189, 91, 181, 88, 92, 180, 136, - 167, 173, 130, 127, 87, 171, 128, 126, 118, 105, - 112, 144, 125, 145, 113, 133, 132, 134, 0, 342, - 0, 161, 178, 190, 94, 357, 166, 185, 0, 0, - 95, 108, 104, 143, 135, 93, 114, 158, 117, 124, - 149, 188, 140, 154, 98, 177, 159, 353, 356, 351, - 352, 390, 391, 427, 428, 429, 407, 348, 0, 354, - 355, 0, 411, 417, 418, 393, 82, 89, 121, 187, - 148, 106, 179, 421, 410, 0, 381, 424, 359, 373, - 432, 374, 375, 403, 345, 389, 139, 371, 0, 362, - 340, 368, 341, 360, 383, 103, 386, 358, 412, 392, - 423, 120, 430, 122, 397, 0, 160, 131, 0, 0, - 385, 414, 387, 408, 380, 404, 350, 396, 425, 372, - 401, 426, 0, 0, 0, 80, 0, 0, 0, 0, - 0, 0, 0, 0, 96, 0, 399, 420, 370, 400, - 402, 339, 398, 0, 343, 346, 431, 416, 365, 366, - 0, 0, 0, 0, 0, 0, 0, 384, 388, 405, - 378, 0, 0, 0, 0, 0, 0, 0, 0, 363, - 0, 395, 0, 0, 0, 347, 344, 0, 0, 382, - 0, 0, 0, 349, 0, 364, 406, 0, 338, 109, - 409, 415, 379, 206, 419, 377, 376, 422, 146, 0, - 163, 111, 119, 83, 90, 0, 110, 137, 151, 155, - 413, 361, 369, 99, 367, 153, 141, 176, 394, 142, - 152, 123, 168, 147, 175, 183, 184, 165, 182, 186, - 157, 84, 164, 174, 97, 156, 86, 172, 162, 129, - 115, 116, 85, 0, 150, 102, 107, 101, 138, 169, - 170, 100, 189, 91, 181, 88, 92, 180, 136, 167, - 173, 130, 127, 87, 171, 128, 126, 118, 105, 112, - 144, 125, 145, 113, 133, 132, 134, 0, 342, 0, - 161, 178, 190, 94, 357, 166, 185, 0, 0, 95, - 108, 104, 143, 135, 93, 114, 158, 117, 124, 149, - 188, 140, 154, 98, 177, 159, 353, 356, 351, 352, - 390, 391, 427, 428, 429, 407, 348, 0, 354, 355, - 0, 411, 417, 418, 393, 82, 89, 121, 187, 148, - 106, 179, 421, 410, 0, 381, 424, 359, 373, 432, - 374, 375, 403, 345, 389, 139, 371, 0, 362, 340, - 368, 341, 360, 383, 103, 386, 358, 412, 392, 423, - 120, 430, 122, 397, 0, 160, 131, 0, 0, 385, - 414, 387, 408, 380, 404, 350, 396, 425, 372, 401, - 426, 0, 0, 0, 260, 0, 0, 0, 0, 0, - 0, 0, 0, 96, 0, 399, 420, 370, 400, 402, - 339, 398, 0, 343, 346, 431, 416, 365, 366, 0, - 0, 0, 0, 0, 0, 0, 384, 388, 405, 378, - 0, 0, 0, 0, 0, 0, 0, 0, 363, 0, - 395, 0, 0, 0, 347, 344, 0, 0, 382, 0, - 0, 0, 349, 0, 364, 406, 0, 338, 109, 409, - 415, 379, 206, 419, 377, 376, 422, 146, 0, 163, - 111, 119, 83, 90, 0, 110, 137, 151, 155, 413, - 361, 369, 99, 367, 153, 141, 176, 394, 142, 152, - 123, 168, 147, 175, 183, 184, 165, 182, 186, 157, - 84, 164, 174, 97, 156, 86, 172, 162, 129, 115, - 116, 85, 0, 150, 102, 107, 101, 138, 169, 170, - 100, 189, 91, 181, 88, 92, 180, 136, 167, 173, - 130, 127, 87, 171, 128, 126, 118, 105, 112, 144, - 125, 145, 113, 133, 132, 134, 0, 342, 0, 161, - 178, 190, 94, 357, 166, 185, 0, 0, 95, 108, - 104, 143, 135, 93, 114, 158, 117, 124, 149, 188, - 140, 154, 98, 177, 159, 353, 356, 351, 352, 390, - 391, 427, 428, 429, 407, 348, 0, 354, 355, 0, - 411, 417, 418, 393, 82, 89, 121, 187, 148, 106, - 179, 421, 410, 0, 381, 424, 359, 373, 432, 374, - 375, 403, 345, 389, 139, 371, 0, 362, 340, 368, - 341, 360, 383, 103, 386, 358, 412, 392, 423, 120, - 430, 122, 397, 0, 160, 131, 0, 0, 385, 414, - 387, 408, 380, 404, 350, 396, 425, 372, 401, 426, - 0, 0, 0, 80, 0, 0, 0, 0, 0, 0, - 0, 0, 96, 0, 399, 420, 370, 400, 402, 339, - 398, 0, 343, 346, 431, 416, 365, 366, 0, 0, - 0, 0, 0, 0, 0, 384, 388, 405, 378, 0, - 0, 0, 0, 0, 0, 0, 0, 363, 0, 395, - 0, 0, 0, 347, 344, 0, 0, 382, 0, 0, - 0, 349, 0, 364, 406, 0, 338, 109, 409, 415, - 379, 206, 419, 377, 376, 422, 146, 0, 163, 111, - 119, 83, 90, 0, 110, 137, 151, 155, 413, 361, - 369, 99, 367, 153, 141, 176, 394, 142, 152, 123, - 168, 147, 175, 183, 184, 165, 182, 186, 157, 84, - 164, 174, 97, 156, 86, 172, 162, 129, 115, 116, - 85, 0, 150, 102, 107, 101, 138, 169, 170, 100, - 189, 91, 181, 88, 336, 180, 136, 167, 173, 130, - 127, 87, 171, 128, 126, 118, 105, 112, 144, 125, - 145, 113, 133, 132, 134, 0, 342, 0, 161, 178, - 190, 94, 357, 166, 185, 0, 0, 95, 108, 104, - 143, 337, 335, 114, 158, 117, 124, 149, 188, 140, - 154, 98, 177, 159, 353, 356, 351, 352, 390, 391, - 427, 428, 429, 407, 348, 0, 354, 355, 0, 411, - 417, 418, 393, 82, 89, 121, 187, 148, 106, 179, - 421, 410, 0, 381, 424, 359, 373, 432, 374, 375, - 403, 345, 389, 139, 371, 0, 362, 340, 368, 341, - 360, 383, 103, 386, 358, 412, 392, 423, 120, 430, - 122, 397, 0, 160, 131, 0, 0, 385, 414, 387, - 408, 380, 404, 350, 396, 425, 372, 401, 426, 0, - 0, 0, 204, 0, 0, 0, 0, 0, 0, 0, - 0, 96, 0, 399, 420, 370, 400, 402, 339, 398, - 0, 343, 346, 431, 416, 365, 366, 0, 0, 0, - 0, 0, 0, 0, 384, 388, 405, 378, 0, 0, - 0, 0, 0, 0, 0, 0, 363, 0, 395, 0, - 0, 0, 347, 344, 0, 0, 382, 0, 0, 0, - 349, 0, 364, 406, 0, 338, 109, 409, 415, 379, - 206, 419, 377, 376, 422, 146, 0, 163, 111, 119, - 83, 90, 0, 110, 137, 151, 155, 413, 361, 369, - 99, 367, 153, 141, 176, 394, 142, 152, 123, 168, - 147, 175, 183, 184, 165, 182, 186, 157, 84, 164, - 174, 97, 156, 86, 172, 162, 129, 115, 116, 85, - 0, 150, 102, 107, 101, 138, 169, 170, 100, 189, - 91, 181, 88, 92, 180, 136, 167, 173, 130, 127, - 87, 171, 128, 126, 118, 105, 112, 144, 125, 145, - 113, 133, 132, 134, 0, 342, 0, 161, 178, 190, - 94, 357, 166, 185, 0, 0, 95, 108, 104, 143, - 135, 93, 114, 158, 117, 124, 149, 188, 140, 154, - 98, 177, 159, 353, 356, 351, 352, 390, 391, 427, - 428, 429, 407, 348, 0, 354, 355, 0, 411, 417, - 418, 393, 82, 89, 121, 187, 148, 106, 179, 421, - 410, 0, 381, 424, 359, 373, 432, 374, 375, 403, - 345, 389, 139, 371, 0, 362, 340, 368, 341, 360, - 383, 103, 386, 358, 412, 392, 423, 120, 430, 122, - 397, 0, 160, 131, 0, 0, 385, 414, 387, 408, - 380, 404, 350, 396, 425, 372, 401, 426, 0, 0, - 0, 80, 0, 0, 0, 0, 0, 0, 0, 0, - 96, 0, 399, 420, 370, 400, 402, 339, 398, 0, - 343, 346, 431, 416, 365, 366, 0, 0, 0, 0, - 0, 0, 0, 384, 388, 405, 378, 0, 0, 0, - 0, 0, 0, 0, 0, 363, 0, 395, 0, 0, - 0, 347, 344, 0, 0, 382, 0, 0, 0, 349, - 0, 364, 406, 0, 338, 109, 409, 415, 379, 206, - 419, 377, 376, 422, 146, 0, 163, 111, 119, 83, - 90, 0, 110, 137, 151, 155, 413, 361, 369, 99, - 367, 153, 141, 176, 394, 142, 152, 123, 168, 147, - 175, 183, 184, 165, 182, 186, 157, 84, 164, 620, - 97, 156, 86, 172, 162, 129, 115, 116, 85, 0, - 150, 102, 107, 101, 138, 169, 170, 100, 189, 91, - 181, 88, 336, 180, 136, 167, 173, 130, 127, 87, - 171, 128, 126, 118, 105, 112, 144, 125, 145, 113, - 133, 132, 134, 0, 342, 0, 161, 178, 190, 94, - 357, 166, 185, 0, 0, 95, 108, 104, 143, 337, - 335, 114, 158, 117, 124, 149, 188, 140, 154, 98, - 177, 159, 353, 356, 351, 352, 390, 391, 427, 428, - 429, 407, 348, 0, 354, 355, 0, 411, 417, 418, - 393, 82, 89, 121, 187, 148, 106, 179, 421, 410, - 0, 381, 424, 359, 373, 432, 374, 375, 403, 345, - 389, 139, 371, 0, 362, 340, 368, 341, 360, 383, - 103, 386, 358, 412, 392, 423, 120, 430, 122, 397, - 0, 160, 131, 0, 0, 385, 414, 387, 408, 380, - 404, 350, 396, 425, 372, 401, 426, 0, 0, 0, - 80, 0, 0, 0, 0, 0, 0, 0, 0, 96, - 0, 399, 420, 370, 400, 402, 339, 398, 0, 343, - 346, 431, 416, 365, 366, 0, 0, 0, 0, 0, - 0, 0, 384, 388, 405, 378, 0, 0, 0, 0, - 0, 0, 0, 0, 363, 0, 395, 0, 0, 0, - 347, 344, 0, 0, 382, 0, 0, 0, 349, 0, - 364, 406, 0, 338, 109, 409, 415, 379, 206, 419, - 377, 376, 422, 146, 0, 163, 111, 119, 83, 90, - 0, 110, 137, 151, 155, 413, 361, 369, 99, 367, - 153, 141, 176, 394, 142, 152, 123, 168, 147, 175, - 183, 184, 165, 182, 186, 157, 84, 164, 327, 97, - 156, 86, 172, 162, 129, 115, 116, 85, 0, 150, - 102, 107, 101, 138, 169, 170, 100, 189, 91, 181, - 88, 336, 180, 136, 167, 173, 130, 127, 87, 171, - 128, 126, 118, 105, 112, 144, 125, 145, 113, 133, - 132, 134, 0, 342, 0, 161, 178, 190, 94, 357, - 166, 185, 0, 0, 95, 108, 104, 143, 337, 335, - 330, 329, 117, 124, 149, 188, 140, 154, 98, 177, - 159, 353, 356, 351, 352, 390, 391, 427, 428, 429, - 407, 348, 0, 354, 355, 0, 411, 417, 418, 393, - 82, 89, 121, 187, 148, 106, 179, 139, 0, 0, - 788, 0, 262, 0, 0, 0, 103, 0, 259, 0, - 0, 0, 120, 302, 122, 0, 0, 160, 131, 0, - 0, 0, 0, 293, 294, 0, 0, 0, 0, 0, - 0, 0, 0, 54, 0, 0, 260, 281, 280, 283, - 284, 285, 286, 0, 0, 96, 282, 287, 288, 289, - 0, 0, 0, 257, 274, 0, 301, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 271, 272, 253, 0, - 0, 0, 315, 0, 273, 0, 0, 268, 269, 270, - 275, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 109, 0, 0, 0, 206, 0, 0, 313, 0, 146, - 0, 163, 111, 119, 83, 90, 0, 110, 137, 151, - 155, 0, 0, 0, 99, 0, 153, 141, 176, 0, - 142, 152, 123, 168, 147, 175, 183, 184, 165, 182, - 186, 157, 84, 164, 174, 97, 156, 86, 172, 162, - 129, 115, 116, 85, 0, 150, 102, 107, 101, 138, - 169, 170, 100, 189, 91, 181, 88, 92, 180, 136, - 167, 173, 130, 127, 87, 171, 128, 126, 118, 105, - 112, 144, 125, 145, 113, 133, 132, 134, 0, 0, - 0, 161, 178, 190, 94, 0, 166, 185, 0, 0, - 95, 108, 104, 143, 135, 93, 114, 158, 117, 124, - 149, 188, 140, 154, 98, 177, 159, 303, 314, 309, - 310, 307, 308, 306, 305, 304, 316, 295, 296, 297, - 298, 300, 0, 311, 312, 299, 82, 89, 121, 187, - 148, 106, 179, 139, 0, 0, 0, 0, 262, 0, - 0, 0, 103, 0, 259, 0, 0, 0, 120, 302, - 122, 0, 0, 160, 131, 0, 0, 0, 0, 293, - 294, 0, 0, 0, 0, 0, 0, 0, 0, 54, - 0, 493, 260, 281, 280, 283, 284, 285, 286, 0, - 0, 96, 282, 287, 288, 289, 0, 0, 0, 257, - 274, 0, 301, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 271, 272, 0, 0, 0, 0, 315, 0, - 273, 0, 0, 268, 269, 270, 275, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 109, 0, 0, 0, - 206, 0, 0, 313, 0, 146, 0, 163, 111, 119, - 83, 90, 0, 110, 137, 151, 155, 0, 0, 0, - 99, 0, 153, 141, 176, 0, 142, 152, 123, 168, - 147, 175, 183, 184, 165, 182, 186, 157, 84, 164, - 174, 97, 156, 86, 172, 162, 129, 115, 116, 85, - 0, 150, 102, 107, 101, 138, 169, 170, 100, 189, - 91, 181, 88, 92, 180, 136, 167, 173, 130, 127, - 87, 171, 128, 126, 118, 105, 112, 144, 125, 145, - 113, 133, 132, 134, 0, 0, 0, 161, 178, 190, - 94, 0, 166, 185, 0, 0, 95, 108, 104, 143, - 135, 93, 114, 158, 117, 124, 149, 188, 140, 154, - 98, 177, 159, 303, 314, 309, 310, 307, 308, 306, - 305, 304, 316, 295, 296, 297, 298, 300, 0, 311, - 312, 299, 82, 89, 121, 187, 148, 106, 179, 139, - 0, 0, 0, 0, 262, 0, 0, 0, 103, 0, - 259, 0, 0, 0, 120, 302, 122, 0, 0, 160, - 131, 0, 0, 0, 0, 293, 294, 0, 0, 0, - 0, 0, 0, 0, 0, 54, 0, 0, 260, 281, - 280, 283, 284, 285, 286, 0, 0, 96, 282, 287, - 288, 289, 0, 0, 0, 257, 274, 0, 301, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 271, 272, - 253, 0, 0, 0, 315, 0, 273, 0, 0, 268, - 269, 270, 275, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 109, 0, 0, 0, 206, 0, 0, 313, - 0, 146, 0, 163, 111, 119, 83, 90, 0, 110, - 137, 151, 155, 0, 0, 0, 99, 0, 153, 141, - 176, 0, 142, 152, 123, 168, 147, 175, 183, 184, - 165, 182, 186, 157, 84, 164, 174, 97, 156, 86, - 172, 162, 129, 115, 116, 85, 0, 150, 102, 107, - 101, 138, 169, 170, 100, 189, 91, 181, 88, 92, - 180, 136, 167, 173, 130, 127, 87, 171, 128, 126, - 118, 105, 112, 144, 125, 145, 113, 133, 132, 134, - 0, 0, 0, 161, 178, 190, 94, 0, 166, 185, - 0, 0, 95, 108, 104, 143, 135, 93, 114, 158, - 117, 124, 149, 188, 140, 154, 98, 177, 159, 303, - 314, 309, 310, 307, 308, 306, 305, 304, 316, 295, - 296, 297, 298, 300, 0, 311, 312, 299, 82, 89, - 121, 187, 148, 106, 179, 139, 0, 0, 0, 0, - 262, 0, 0, 0, 103, 0, 259, 0, 0, 0, - 120, 302, 122, 0, 0, 160, 131, 0, 0, 0, - 0, 293, 294, 0, 0, 0, 0, 0, 0, 0, - 0, 54, 0, 0, 260, 281, 803, 283, 284, 285, - 286, 0, 0, 96, 282, 287, 288, 289, 0, 0, - 0, 257, 274, 0, 301, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 271, 272, 253, 0, 0, 0, - 315, 0, 273, 0, 0, 268, 269, 270, 275, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 109, 0, - 0, 0, 206, 0, 0, 313, 0, 146, 0, 163, - 111, 119, 83, 90, 0, 110, 137, 151, 155, 0, - 0, 0, 99, 0, 153, 141, 176, 0, 142, 152, - 123, 168, 147, 175, 183, 184, 165, 182, 186, 157, - 84, 164, 174, 97, 156, 86, 172, 162, 129, 115, - 116, 85, 0, 150, 102, 107, 101, 138, 169, 170, - 100, 189, 91, 181, 88, 92, 180, 136, 167, 173, - 130, 127, 87, 171, 128, 126, 118, 105, 112, 144, - 125, 145, 113, 133, 132, 134, 0, 0, 0, 161, - 178, 190, 94, 0, 166, 185, 0, 0, 95, 108, - 104, 143, 135, 93, 114, 158, 117, 124, 149, 188, - 140, 154, 98, 177, 159, 303, 314, 309, 310, 307, - 308, 306, 305, 304, 316, 295, 296, 297, 298, 300, - 0, 311, 312, 299, 82, 89, 121, 187, 148, 106, - 179, 139, 0, 0, 0, 0, 262, 0, 0, 0, - 103, 0, 259, 0, 0, 0, 120, 302, 122, 0, - 0, 160, 131, 0, 0, 0, 0, 293, 294, 0, + 321, 1509, 1499, 1306, 1463, 1102, 1194, 645, 1377, 1364, + 953, 1120, 1280, 351, 1246, 1409, 338, 926, 299, 982, + 546, 1243, 1247, 996, 1103, 325, 924, 57, 1033, 1147, + 962, 952, 81, 1253, 1218, 1259, 264, 865, 789, 264, + 1061, 872, 803, 1126, 1173, 875, 686, 1164, 966, 705, + 842, 992, 394, 290, 928, 644, 3, 913, 893, 577, + 388, 352, 51, 704, 583, 517, 589, 264, 81, 597, + 323, 685, 264, 383, 264, 385, 694, 659, 906, 949, + 56, 308, 1502, 1486, 660, 1497, 1473, 1494, 380, 1307, + 1485, 1015, 691, 1472, 1235, 1336, 61, 535, 291, 292, + 293, 294, 522, 1274, 297, 1014, 943, 298, 1135, 312, + 1155, 1134, 550, 51, 1136, 571, 976, 259, 255, 256, + 257, 304, 63, 64, 65, 66, 67, 296, 261, 1275, + 1276, 944, 945, 1019, 706, 566, 707, 548, 295, 567, + 564, 565, 1013, 1438, 610, 609, 619, 620, 612, 613, + 614, 615, 616, 617, 618, 611, 975, 1196, 621, 382, + 1367, 251, 983, 253, 519, 363, 521, 369, 370, 367, + 368, 366, 365, 364, 570, 1384, 1327, 1325, 552, 289, + 554, 371, 372, 778, 559, 560, 569, 777, 1198, 775, + 1496, 1493, 1010, 1007, 1008, 1464, 1006, 1193, 907, 1456, + 967, 1517, 1410, 536, 253, 391, 1219, 1513, 524, 1199, + 1197, 551, 553, 1121, 1123, 1412, 782, 768, 1269, 1418, + 1190, 1268, 776, 779, 1267, 520, 1192, 969, 1017, 1020, + 527, 969, 266, 254, 1027, 1445, 258, 1026, 532, 1347, + 1078, 633, 634, 1205, 1221, 1131, 1088, 1055, 814, 1075, + 700, 601, 264, 542, 950, 264, 252, 1292, 621, 611, + 1148, 264, 621, 939, 811, 1012, 808, 264, 596, 518, + 81, 1454, 81, 804, 81, 81, 1427, 81, 1223, 81, + 1227, 969, 1222, 1411, 1220, 81, 1257, 1011, 708, 1225, + 1122, 1237, 555, 894, 556, 557, 549, 558, 1224, 561, + 594, 529, 516, 530, 1471, 572, 531, 983, 1293, 70, + 518, 1226, 1228, 1439, 1511, 81, 596, 1512, 770, 1510, + 1419, 1417, 1191, 968, 1189, 1035, 1016, 968, 1153, 318, + 585, 547, 894, 547, 1085, 547, 547, 1459, 547, 591, + 547, 1018, 633, 634, 528, 71, 547, 534, 849, 573, + 574, 633, 634, 541, 805, 538, 539, 540, 1477, 543, + 586, 972, 847, 848, 846, 1373, 51, 973, 614, 615, + 616, 617, 618, 611, 1518, 1181, 621, 968, 264, 264, + 264, 630, 965, 963, 632, 964, 1372, 81, 523, 595, + 594, 961, 967, 81, 595, 594, 1239, 1052, 1053, 1054, + 54, 1168, 587, 1034, 1179, 684, 596, 22, 817, 818, + 845, 596, 643, 1519, 647, 648, 649, 650, 651, 652, + 653, 654, 655, 1167, 658, 661, 661, 661, 667, 661, + 661, 667, 661, 675, 676, 677, 678, 679, 680, 866, + 690, 867, 662, 664, 666, 668, 670, 672, 673, 663, + 665, 1156, 669, 671, 1479, 674, 595, 594, 698, 1137, + 250, 1138, 702, 1455, 813, 525, 526, 303, 693, 1391, + 683, 1180, 692, 596, 1370, 1202, 1185, 1182, 1175, 1183, + 1178, 1074, 1174, 1165, 1038, 1176, 1177, 1415, 1495, 350, + 612, 613, 614, 615, 616, 617, 618, 611, 1452, 1184, + 621, 812, 610, 609, 619, 620, 612, 613, 614, 615, + 616, 617, 618, 611, 1309, 1148, 621, 264, 595, 594, + 1143, 79, 81, 868, 391, 377, 378, 264, 264, 81, + 788, 595, 594, 264, 787, 596, 264, 1481, 576, 264, + 1415, 1467, 767, 264, 771, 81, 81, 769, 596, 774, + 81, 81, 81, 264, 81, 81, 1062, 393, 1415, 576, + 81, 81, 832, 834, 835, 792, 793, 1073, 833, 1072, + 794, 795, 796, 766, 798, 799, 1415, 1446, 1415, 1414, + 800, 801, 544, 547, 1362, 1361, 595, 594, 537, 81, + 547, 1349, 576, 264, 576, 791, 1346, 576, 1424, 81, + 1299, 1298, 1423, 596, 819, 1244, 547, 547, 1256, 716, + 1289, 547, 547, 547, 970, 547, 547, 1256, 843, 772, + 773, 547, 547, 898, 783, 780, 1295, 1296, 382, 1195, + 877, 786, 341, 340, 343, 344, 345, 346, 1295, 1294, + 838, 342, 347, 81, 1127, 797, 915, 918, 919, 920, + 916, 1342, 917, 921, 840, 1127, 1260, 1261, 635, 636, + 637, 638, 639, 640, 641, 642, 1067, 576, 836, 821, + 910, 576, 877, 576, 715, 714, 81, 81, 884, 887, + 1208, 1426, 909, 264, 895, 828, 910, 910, 54, 576, + 24, 264, 264, 24, 51, 264, 264, 1297, 1256, 264, + 264, 264, 81, 879, 869, 870, 58, 910, 933, 647, + 695, 1139, 942, 696, 1097, 81, 1091, 24, 1098, 1090, + 903, 934, 891, 1067, 1067, 936, 610, 609, 619, 620, + 612, 613, 614, 615, 616, 617, 618, 611, 54, 839, + 621, 54, 1504, 695, 701, 1396, 1067, 815, 781, 984, + 985, 986, 925, 791, 696, 697, 690, 699, 1487, 393, + 690, 393, 940, 393, 393, 54, 393, 941, 393, 264, + 81, 932, 81, 937, 393, 908, 264, 264, 264, 264, + 264, 957, 264, 264, 305, 1379, 264, 81, 935, 998, + 1002, 977, 1004, 1354, 997, 1285, 697, 1380, 695, 1260, + 1261, 1500, 1142, 264, 599, 264, 264, 1031, 993, 988, + 264, 987, 1000, 1287, 994, 995, 609, 619, 620, 612, + 613, 614, 615, 616, 617, 618, 611, 314, 1263, 621, + 827, 547, 54, 547, 1244, 1169, 809, 785, 1266, 391, + 1114, 978, 979, 980, 981, 1115, 1112, 1116, 547, 919, + 920, 1113, 954, 1043, 1265, 1111, 1110, 989, 990, 991, + 843, 1001, 309, 310, 1491, 1484, 1204, 840, 1021, 1022, + 1023, 1024, 1025, 1040, 1028, 1029, 393, 1489, 1030, 1045, + 1044, 1050, 710, 590, 619, 620, 612, 613, 614, 615, + 616, 617, 618, 611, 1049, 1032, 621, 1057, 588, 1160, + 713, 1056, 1039, 545, 578, 1152, 327, 1461, 1460, 1394, + 1150, 264, 264, 264, 264, 264, 579, 1144, 874, 1340, + 1375, 1003, 575, 264, 784, 923, 264, 306, 307, 590, + 264, 300, 1432, 841, 264, 1104, 850, 851, 852, 853, + 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, + 864, 1084, 839, 81, 301, 58, 1048, 1431, 1106, 1107, + 1128, 1109, 1099, 1140, 1047, 1382, 1127, 568, 1100, 1101, + 1079, 1076, 690, 690, 690, 690, 690, 802, 1129, 1117, + 1130, 879, 1105, 592, 1125, 1108, 1506, 925, 1442, 1124, + 1368, 899, 1132, 1506, 1505, 690, 1149, 810, 1157, 1158, + 60, 81, 81, 915, 918, 919, 920, 916, 62, 917, + 921, 393, 55, 1145, 1146, 1, 1498, 1308, 393, 1376, + 1009, 1462, 1171, 1408, 1279, 960, 951, 69, 515, 68, + 1453, 81, 959, 958, 393, 393, 1166, 1416, 1366, 393, + 393, 393, 971, 393, 393, 1154, 974, 264, 1286, 393, + 393, 1200, 1186, 1151, 1458, 721, 81, 719, 720, 1172, + 718, 723, 1159, 547, 1161, 1162, 1163, 722, 717, 277, + 386, 922, 709, 999, 593, 1201, 72, 1188, 823, 1187, + 1005, 807, 562, 563, 279, 629, 1046, 1133, 599, 392, + 954, 393, 547, 1251, 816, 582, 1430, 1381, 1211, 1212, + 1083, 81, 81, 1245, 656, 892, 326, 831, 339, 1230, + 1236, 1229, 1248, 1217, 336, 337, 822, 1096, 603, 324, + 316, 688, 681, 1104, 914, 81, 912, 1043, 580, 584, + 911, 381, 871, 1262, 1258, 687, 1207, 1335, 1437, 1206, + 81, 840, 81, 81, 1264, 602, 1255, 826, 896, 26, + 59, 311, 1278, 19, 1271, 18, 1250, 17, 1270, 20, + 1249, 16, 51, 15, 14, 900, 901, 533, 30, 21, + 264, 1277, 1273, 1339, 1282, 1283, 1284, 1058, 1059, 1060, + 646, 13, 12, 11, 10, 9, 8, 7, 264, 657, + 6, 393, 5, 1210, 81, 4, 302, 81, 81, 81, + 264, 23, 2, 0, 393, 0, 81, 0, 0, 264, + 820, 610, 609, 619, 620, 612, 613, 614, 615, 616, + 617, 618, 611, 0, 0, 621, 1240, 1301, 0, 631, + 1314, 0, 0, 0, 0, 1316, 0, 1290, 1291, 0, + 1302, 0, 1304, 0, 0, 0, 0, 1323, 0, 0, + 0, 1315, 0, 0, 0, 0, 0, 0, 0, 393, + 0, 393, 1300, 0, 0, 0, 0, 1341, 876, 878, + 690, 0, 0, 0, 0, 0, 393, 954, 81, 954, + 1303, 1351, 1104, 1350, 0, 689, 81, 0, 1140, 0, + 1360, 0, 1313, 0, 0, 0, 0, 1334, 0, 0, + 0, 81, 0, 0, 393, 0, 0, 0, 81, 0, + 0, 0, 0, 0, 1369, 0, 1371, 0, 0, 0, + 0, 1374, 0, 0, 0, 0, 0, 0, 0, 1356, + 1357, 1358, 0, 0, 0, 0, 1320, 1321, 0, 1322, + 0, 1383, 1324, 1210, 1326, 0, 0, 81, 81, 0, + 81, 0, 0, 0, 0, 81, 1248, 81, 81, 81, + 264, 0, 547, 81, 1403, 1395, 1404, 1405, 1406, 1402, + 0, 0, 0, 0, 0, 1413, 0, 1407, 0, 0, + 81, 264, 0, 0, 0, 1420, 0, 0, 0, 1428, + 0, 0, 1214, 1215, 0, 0, 806, 0, 1363, 896, + 0, 1397, 0, 0, 1249, 1231, 1232, 1398, 1233, 1234, + 1248, 1443, 0, 0, 0, 954, 81, 0, 0, 1450, + 1241, 1242, 829, 830, 1451, 0, 0, 81, 81, 0, + 0, 0, 0, 0, 0, 1465, 0, 1425, 1466, 0, + 1469, 0, 393, 0, 0, 1378, 81, 0, 1474, 1421, + 0, 1422, 0, 0, 1444, 0, 0, 264, 1249, 0, + 51, 0, 0, 0, 0, 81, 0, 0, 1104, 0, + 0, 0, 0, 1429, 1483, 646, 0, 0, 882, 883, + 0, 0, 1288, 0, 0, 0, 1488, 1490, 81, 0, + 1170, 393, 1064, 0, 0, 0, 1065, 1492, 0, 0, + 0, 1503, 0, 1069, 1070, 1071, 0, 0, 1514, 0, + 1077, 844, 0, 1080, 1081, 0, 0, 0, 0, 1087, + 393, 581, 0, 1089, 0, 0, 1092, 1093, 1094, 1095, + 0, 0, 0, 0, 0, 0, 948, 0, 0, 0, + 0, 0, 0, 1318, 0, 393, 0, 0, 1119, 1478, + 0, 0, 0, 0, 0, 274, 0, 262, 1501, 0, + 288, 0, 0, 0, 1378, 954, 0, 880, 881, 0, + 0, 886, 889, 890, 0, 0, 0, 0, 393, 284, + 0, 0, 0, 0, 0, 315, 0, 896, 384, 0, + 1252, 1254, 0, 262, 0, 262, 902, 689, 904, 905, + 0, 689, 0, 0, 0, 689, 0, 0, 0, 0, + 0, 0, 0, 0, 1254, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 393, + 267, 393, 1281, 0, 0, 0, 0, 270, 0, 0, + 1041, 1042, 0, 584, 0, 278, 273, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1385, 1386, 1387, 1388, 1389, 0, 0, 0, 1392, 1393, + 0, 0, 0, 0, 0, 0, 0, 0, 276, 0, + 0, 0, 0, 1305, 283, 0, 1310, 1311, 1312, 0, + 1216, 0, 0, 0, 0, 393, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1068, 0, 605, 0, 608, + 0, 268, 0, 0, 0, 622, 623, 624, 625, 626, + 627, 628, 1086, 606, 607, 604, 610, 609, 619, 620, + 612, 613, 614, 615, 616, 617, 618, 611, 280, 271, + 621, 281, 282, 287, 0, 1051, 896, 272, 275, 0, + 269, 286, 285, 844, 0, 0, 0, 0, 0, 0, + 1338, 0, 0, 0, 0, 0, 0, 393, 0, 0, + 0, 0, 0, 262, 0, 1365, 262, 0, 0, 0, + 0, 0, 262, 0, 0, 0, 0, 0, 262, 0, + 393, 0, 1066, 0, 0, 0, 0, 393, 610, 609, + 619, 620, 612, 613, 614, 615, 616, 617, 618, 611, + 1082, 0, 621, 0, 0, 0, 0, 689, 689, 689, + 689, 689, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1507, 689, 0, 0, 1317, 1399, 1400, 0, 1401, + 689, 0, 1319, 0, 1365, 0, 1365, 1365, 1365, 0, + 0, 0, 1281, 1328, 1329, 0, 0, 0, 0, 0, + 0, 0, 1333, 1203, 0, 0, 0, 0, 0, 1365, + 0, 0, 0, 1343, 1344, 1345, 0, 1348, 0, 0, + 0, 0, 0, 24, 25, 52, 27, 28, 1332, 0, + 0, 0, 0, 0, 1359, 0, 0, 0, 0, 262, + 262, 262, 43, 0, 0, 1457, 0, 29, 48, 49, + 0, 0, 0, 1238, 0, 0, 393, 393, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, + 0, 54, 896, 0, 0, 1476, 610, 609, 619, 620, + 612, 613, 614, 615, 616, 617, 618, 611, 0, 0, + 621, 0, 0, 0, 1482, 1272, 0, 0, 0, 1390, + 0, 0, 610, 609, 619, 620, 612, 613, 614, 615, + 616, 617, 618, 611, 0, 0, 621, 1365, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 31, 32, 34, 33, 36, 0, 50, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1433, + 1434, 1435, 1436, 0, 0, 0, 1440, 1441, 1331, 0, + 37, 44, 45, 0, 0, 46, 47, 35, 1447, 1448, + 1449, 0, 0, 0, 0, 0, 0, 0, 262, 0, + 0, 39, 40, 0, 41, 42, 0, 0, 262, 262, + 0, 0, 0, 0, 262, 0, 0, 262, 0, 1330, + 262, 1470, 0, 0, 790, 0, 0, 1337, 1475, 0, + 0, 0, 0, 0, 262, 0, 0, 646, 0, 0, + 0, 0, 0, 0, 0, 1352, 1480, 0, 1353, 0, + 0, 1355, 610, 609, 619, 620, 612, 613, 614, 615, + 616, 617, 618, 611, 0, 0, 621, 0, 0, 0, + 0, 0, 0, 0, 262, 689, 0, 0, 0, 0, + 0, 0, 0, 790, 0, 0, 53, 0, 1213, 0, + 0, 1515, 1516, 610, 609, 619, 620, 612, 613, 614, + 615, 616, 617, 618, 611, 0, 0, 621, 610, 609, + 619, 620, 612, 613, 614, 615, 616, 617, 618, 611, + 0, 1063, 621, 0, 0, 315, 0, 0, 0, 0, + 315, 315, 0, 0, 315, 315, 315, 0, 0, 0, + 897, 610, 609, 619, 620, 612, 613, 614, 615, 616, + 617, 618, 611, 0, 0, 621, 0, 0, 0, 315, + 315, 315, 315, 0, 262, 0, 0, 0, 0, 0, + 0, 0, 262, 930, 0, 0, 262, 262, 0, 0, + 262, 938, 790, 610, 609, 619, 620, 612, 613, 614, + 615, 616, 617, 618, 611, 0, 0, 621, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1468, + 646, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 262, 0, 0, 0, 0, 0, 0, 262, 262, 262, + 262, 262, 0, 262, 262, 0, 0, 262, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 738, 0, 0, 262, 0, 1036, 1037, 0, 0, + 0, 262, 0, 0, 0, 0, 790, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 315, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 315, 0, 0, 0, 726, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 315, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 897, 262, 262, 262, 262, 262, 739, 0, 0, + 0, 0, 0, 0, 1118, 0, 0, 262, 0, 0, + 0, 930, 0, 0, 0, 262, 0, 0, 0, 0, + 752, 755, 756, 757, 758, 759, 760, 0, 761, 762, + 763, 764, 765, 740, 741, 742, 743, 724, 725, 753, + 0, 727, 0, 728, 729, 730, 731, 732, 733, 734, + 735, 736, 737, 744, 745, 746, 747, 748, 749, 750, + 751, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 754, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 262, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 315, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 315, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 790, 0, 0, 0, 0, 0, 0, 0, 0, 897, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 262, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 262, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 262, 0, 0, 0, 0, 0, 0, 0, 0, + 262, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 897, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 930, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 262, 0, 0, 0, 0, 0, 502, 490, + 0, 447, 505, 421, 437, 513, 438, 441, 478, 406, + 460, 165, 435, 0, 425, 401, 431, 402, 423, 449, + 111, 453, 420, 492, 463, 504, 137, 511, 139, 469, + 0, 211, 153, 0, 0, 451, 494, 458, 487, 446, + 479, 411, 468, 506, 436, 476, 507, 0, 0, 0, + 80, 0, 955, 956, 897, 0, 0, 0, 0, 101, + 0, 473, 501, 433, 475, 477, 400, 470, 262, 404, + 407, 512, 497, 428, 429, 1141, 0, 0, 0, 0, + 0, 0, 450, 459, 484, 444, 0, 0, 0, 0, + 0, 0, 0, 0, 426, 0, 467, 0, 0, 0, + 408, 405, 0, 0, 448, 0, 0, 0, 410, 0, + 427, 485, 0, 398, 119, 489, 496, 445, 265, 500, + 443, 442, 503, 184, 0, 215, 122, 136, 97, 83, + 93, 0, 121, 162, 191, 195, 493, 424, 432, 105, + 430, 193, 172, 231, 466, 174, 192, 140, 221, 185, + 230, 240, 241, 218, 238, 245, 208, 86, 217, 229, + 102, 203, 88, 227, 214, 151, 131, 132, 87, 0, + 189, 110, 117, 107, 164, 224, 225, 106, 248, 94, + 237, 90, 95, 236, 158, 220, 228, 152, 145, 89, + 226, 150, 144, 135, 114, 124, 182, 142, 183, 125, + 155, 154, 156, 0, 403, 0, 212, 234, 249, 99, + 419, 219, 243, 244, 0, 0, 100, 118, 113, 181, + 157, 96, 127, 209, 134, 141, 188, 247, 171, 194, + 103, 233, 210, 415, 418, 413, 414, 461, 462, 508, + 509, 510, 486, 409, 0, 416, 417, 0, 491, 498, + 499, 465, 82, 91, 138, 246, 186, 116, 235, 399, + 412, 109, 422, 0, 0, 434, 439, 440, 452, 454, + 455, 456, 457, 464, 471, 472, 474, 480, 481, 482, + 483, 488, 495, 514, 84, 85, 92, 98, 104, 108, + 112, 115, 120, 123, 126, 128, 129, 130, 133, 143, + 146, 147, 148, 149, 159, 160, 161, 163, 166, 167, + 168, 169, 170, 173, 175, 176, 177, 178, 179, 180, + 187, 190, 196, 197, 198, 199, 200, 201, 202, 204, + 205, 206, 207, 213, 216, 222, 223, 232, 239, 242, + 502, 490, 0, 447, 505, 421, 437, 513, 438, 441, + 478, 406, 460, 165, 435, 0, 425, 401, 431, 402, + 423, 449, 111, 453, 420, 492, 463, 504, 137, 511, + 139, 469, 0, 211, 153, 0, 0, 451, 494, 458, + 487, 446, 479, 411, 468, 506, 436, 476, 507, 0, + 0, 0, 80, 0, 955, 956, 0, 0, 0, 0, + 0, 101, 0, 473, 501, 433, 475, 477, 400, 470, + 0, 404, 407, 512, 497, 428, 429, 0, 0, 0, + 0, 0, 0, 0, 450, 459, 484, 444, 0, 0, + 0, 0, 0, 0, 0, 0, 426, 0, 467, 0, + 0, 0, 408, 405, 0, 0, 448, 0, 0, 0, + 410, 0, 427, 485, 0, 398, 119, 489, 496, 445, + 265, 500, 443, 442, 503, 184, 0, 215, 122, 136, + 97, 83, 93, 0, 121, 162, 191, 195, 493, 424, + 432, 105, 430, 193, 172, 231, 466, 174, 192, 140, + 221, 185, 230, 240, 241, 218, 238, 245, 208, 86, + 217, 229, 102, 203, 88, 227, 214, 151, 131, 132, + 87, 0, 189, 110, 117, 107, 164, 224, 225, 106, + 248, 94, 237, 90, 95, 236, 158, 220, 228, 152, + 145, 89, 226, 150, 144, 135, 114, 124, 182, 142, + 183, 125, 155, 154, 156, 0, 403, 0, 212, 234, + 249, 99, 419, 219, 243, 244, 0, 0, 100, 118, + 113, 181, 157, 96, 127, 209, 134, 141, 188, 247, + 171, 194, 103, 233, 210, 415, 418, 413, 414, 461, + 462, 508, 509, 510, 486, 409, 0, 416, 417, 0, + 491, 498, 499, 465, 82, 91, 138, 246, 186, 116, + 235, 399, 412, 109, 422, 0, 0, 434, 439, 440, + 452, 454, 455, 456, 457, 464, 471, 472, 474, 480, + 481, 482, 483, 488, 495, 514, 84, 85, 92, 98, + 104, 108, 112, 115, 120, 123, 126, 128, 129, 130, + 133, 143, 146, 147, 148, 149, 159, 160, 161, 163, + 166, 167, 168, 169, 170, 173, 175, 176, 177, 178, + 179, 180, 187, 190, 196, 197, 198, 199, 200, 201, + 202, 204, 205, 206, 207, 213, 216, 222, 223, 232, + 239, 242, 502, 490, 0, 447, 505, 421, 437, 513, + 438, 441, 478, 406, 460, 165, 435, 0, 425, 401, + 431, 402, 423, 449, 111, 453, 420, 492, 463, 504, + 137, 511, 139, 469, 0, 211, 153, 0, 0, 451, + 494, 458, 487, 446, 479, 411, 468, 506, 436, 476, + 507, 54, 0, 0, 80, 0, 0, 0, 0, 0, + 0, 0, 0, 101, 0, 473, 501, 433, 475, 477, + 400, 470, 0, 404, 407, 512, 497, 428, 429, 0, + 0, 0, 0, 0, 0, 0, 450, 459, 484, 444, + 0, 0, 0, 0, 0, 0, 0, 0, 426, 0, + 467, 0, 0, 0, 408, 405, 0, 0, 448, 0, + 0, 0, 410, 0, 427, 485, 0, 398, 119, 489, + 496, 445, 265, 500, 443, 442, 503, 184, 0, 215, + 122, 136, 97, 83, 93, 0, 121, 162, 191, 195, + 493, 424, 432, 105, 430, 193, 172, 231, 466, 174, + 192, 140, 221, 185, 230, 240, 241, 218, 238, 245, + 208, 86, 217, 229, 102, 203, 88, 227, 214, 151, + 131, 132, 87, 0, 189, 110, 117, 107, 164, 224, + 225, 106, 248, 94, 237, 90, 95, 236, 158, 220, + 228, 152, 145, 89, 226, 150, 144, 135, 114, 124, + 182, 142, 183, 125, 155, 154, 156, 0, 403, 0, + 212, 234, 249, 99, 419, 219, 243, 244, 0, 0, + 100, 118, 113, 181, 157, 96, 127, 209, 134, 141, + 188, 247, 171, 194, 103, 233, 210, 415, 418, 413, + 414, 461, 462, 508, 509, 510, 486, 409, 0, 416, + 417, 0, 491, 498, 499, 465, 82, 91, 138, 246, + 186, 116, 235, 399, 412, 109, 422, 0, 0, 434, + 439, 440, 452, 454, 455, 456, 457, 464, 471, 472, + 474, 480, 481, 482, 483, 488, 495, 514, 84, 85, + 92, 98, 104, 108, 112, 115, 120, 123, 126, 128, + 129, 130, 133, 143, 146, 147, 148, 149, 159, 160, + 161, 163, 166, 167, 168, 169, 170, 173, 175, 176, + 177, 178, 179, 180, 187, 190, 196, 197, 198, 199, + 200, 201, 202, 204, 205, 206, 207, 213, 216, 222, + 223, 232, 239, 242, 502, 490, 0, 447, 505, 421, + 437, 513, 438, 441, 478, 406, 460, 165, 435, 0, + 425, 401, 431, 402, 423, 449, 111, 453, 420, 492, + 463, 504, 137, 511, 139, 469, 0, 211, 153, 0, + 0, 451, 494, 458, 487, 446, 479, 411, 468, 506, + 436, 476, 507, 0, 0, 0, 80, 0, 0, 0, + 0, 0, 0, 0, 0, 101, 0, 473, 501, 433, + 475, 477, 400, 470, 0, 404, 407, 512, 497, 428, + 429, 0, 0, 0, 0, 0, 0, 0, 450, 459, + 484, 444, 0, 0, 0, 0, 0, 0, 1209, 0, + 426, 0, 467, 0, 0, 0, 408, 405, 0, 0, + 448, 0, 0, 0, 410, 0, 427, 485, 0, 398, + 119, 489, 496, 445, 265, 500, 443, 442, 503, 184, + 0, 215, 122, 136, 97, 83, 93, 0, 121, 162, + 191, 195, 493, 424, 432, 105, 430, 193, 172, 231, + 466, 174, 192, 140, 221, 185, 230, 240, 241, 218, + 238, 245, 208, 86, 217, 229, 102, 203, 88, 227, + 214, 151, 131, 132, 87, 0, 189, 110, 117, 107, + 164, 224, 225, 106, 248, 94, 237, 90, 95, 236, + 158, 220, 228, 152, 145, 89, 226, 150, 144, 135, + 114, 124, 182, 142, 183, 125, 155, 154, 156, 0, + 403, 0, 212, 234, 249, 99, 419, 219, 243, 244, + 0, 0, 100, 118, 113, 181, 157, 96, 127, 209, + 134, 141, 188, 247, 171, 194, 103, 233, 210, 415, + 418, 413, 414, 461, 462, 508, 509, 510, 486, 409, + 0, 416, 417, 0, 491, 498, 499, 465, 82, 91, + 138, 246, 186, 116, 235, 399, 412, 109, 422, 0, + 0, 434, 439, 440, 452, 454, 455, 456, 457, 464, + 471, 472, 474, 480, 481, 482, 483, 488, 495, 514, + 84, 85, 92, 98, 104, 108, 112, 115, 120, 123, + 126, 128, 129, 130, 133, 143, 146, 147, 148, 149, + 159, 160, 161, 163, 166, 167, 168, 169, 170, 173, + 175, 176, 177, 178, 179, 180, 187, 190, 196, 197, + 198, 199, 200, 201, 202, 204, 205, 206, 207, 213, + 216, 222, 223, 232, 239, 242, 502, 490, 0, 447, + 505, 421, 437, 513, 438, 441, 478, 406, 460, 165, + 435, 0, 425, 401, 431, 402, 423, 449, 111, 453, + 420, 492, 463, 504, 137, 511, 139, 469, 0, 211, + 153, 0, 0, 451, 494, 458, 487, 446, 479, 411, + 468, 506, 436, 476, 507, 0, 0, 0, 263, 0, + 0, 0, 0, 0, 0, 0, 0, 101, 0, 473, + 501, 433, 475, 477, 400, 470, 0, 404, 407, 512, + 497, 428, 429, 0, 0, 0, 0, 0, 0, 0, + 450, 459, 484, 444, 0, 0, 0, 0, 0, 0, + 939, 0, 426, 0, 467, 0, 0, 0, 408, 405, + 0, 0, 448, 0, 0, 0, 410, 0, 427, 485, + 0, 398, 119, 489, 496, 445, 265, 500, 443, 442, + 503, 184, 0, 215, 122, 136, 97, 83, 93, 0, + 121, 162, 191, 195, 493, 424, 432, 105, 430, 193, + 172, 231, 466, 174, 192, 140, 221, 185, 230, 240, + 241, 218, 238, 245, 208, 86, 217, 229, 102, 203, + 88, 227, 214, 151, 131, 132, 87, 0, 189, 110, + 117, 107, 164, 224, 225, 106, 248, 94, 237, 90, + 95, 236, 158, 220, 228, 152, 145, 89, 226, 150, + 144, 135, 114, 124, 182, 142, 183, 125, 155, 154, + 156, 0, 403, 0, 212, 234, 249, 99, 419, 219, + 243, 244, 0, 0, 100, 118, 113, 181, 157, 96, + 127, 209, 134, 141, 188, 247, 171, 194, 103, 233, + 210, 415, 418, 413, 414, 461, 462, 508, 509, 510, + 486, 409, 0, 416, 417, 0, 491, 498, 499, 465, + 82, 91, 138, 246, 186, 116, 235, 399, 412, 109, + 422, 0, 0, 434, 439, 440, 452, 454, 455, 456, + 457, 464, 471, 472, 474, 480, 481, 482, 483, 488, + 495, 514, 84, 85, 92, 98, 104, 108, 112, 115, + 120, 123, 126, 128, 129, 130, 133, 143, 146, 147, + 148, 149, 159, 160, 161, 163, 166, 167, 168, 169, + 170, 173, 175, 176, 177, 178, 179, 180, 187, 190, + 196, 197, 198, 199, 200, 201, 202, 204, 205, 206, + 207, 213, 216, 222, 223, 232, 239, 242, 502, 490, + 0, 447, 505, 421, 437, 513, 438, 441, 478, 406, + 460, 165, 435, 0, 425, 401, 431, 402, 423, 449, + 111, 453, 420, 492, 463, 504, 137, 511, 139, 469, + 0, 211, 153, 0, 0, 451, 494, 458, 487, 446, + 479, 411, 468, 506, 436, 476, 507, 0, 0, 0, + 320, 0, 0, 0, 0, 0, 0, 0, 0, 101, + 0, 473, 501, 433, 475, 477, 400, 470, 0, 404, + 407, 512, 497, 428, 429, 0, 0, 0, 0, 0, + 0, 0, 450, 459, 484, 444, 0, 0, 0, 0, + 0, 0, 837, 0, 426, 0, 467, 0, 0, 0, + 408, 405, 0, 0, 448, 0, 0, 0, 410, 0, + 427, 485, 0, 398, 119, 489, 496, 445, 265, 500, + 443, 442, 503, 184, 0, 215, 122, 136, 97, 83, + 93, 0, 121, 162, 191, 195, 493, 424, 432, 105, + 430, 193, 172, 231, 466, 174, 192, 140, 221, 185, + 230, 240, 241, 218, 238, 245, 208, 86, 217, 229, + 102, 203, 88, 227, 214, 151, 131, 132, 87, 0, + 189, 110, 117, 107, 164, 224, 225, 106, 248, 94, + 237, 90, 95, 236, 158, 220, 228, 152, 145, 89, + 226, 150, 144, 135, 114, 124, 182, 142, 183, 125, + 155, 154, 156, 0, 403, 0, 212, 234, 249, 99, + 419, 219, 243, 244, 0, 0, 100, 118, 113, 181, + 157, 96, 127, 209, 134, 141, 188, 247, 171, 194, + 103, 233, 210, 415, 418, 413, 414, 461, 462, 508, + 509, 510, 486, 409, 0, 416, 417, 0, 491, 498, + 499, 465, 82, 91, 138, 246, 186, 116, 235, 399, + 412, 109, 422, 0, 0, 434, 439, 440, 452, 454, + 455, 456, 457, 464, 471, 472, 474, 480, 481, 482, + 483, 488, 495, 514, 84, 85, 92, 98, 104, 108, + 112, 115, 120, 123, 126, 128, 129, 130, 133, 143, + 146, 147, 148, 149, 159, 160, 161, 163, 166, 167, + 168, 169, 170, 173, 175, 176, 177, 178, 179, 180, + 187, 190, 196, 197, 198, 199, 200, 201, 202, 204, + 205, 206, 207, 213, 216, 222, 223, 232, 239, 242, + 502, 490, 0, 447, 505, 421, 437, 513, 438, 441, + 478, 406, 460, 165, 435, 0, 425, 401, 431, 402, + 423, 449, 111, 453, 420, 492, 463, 504, 137, 511, + 139, 469, 0, 211, 153, 0, 0, 451, 494, 458, + 487, 446, 479, 411, 468, 506, 436, 476, 507, 0, + 0, 0, 80, 0, 0, 0, 0, 0, 0, 0, + 0, 101, 0, 473, 501, 433, 475, 477, 400, 470, + 0, 404, 407, 512, 497, 428, 429, 0, 0, 0, + 0, 0, 0, 0, 450, 459, 484, 444, 0, 0, + 0, 0, 0, 0, 0, 0, 426, 0, 467, 0, + 0, 0, 408, 405, 0, 0, 448, 0, 0, 0, + 410, 0, 427, 485, 0, 398, 119, 489, 496, 445, + 265, 500, 443, 442, 503, 184, 0, 215, 122, 136, + 97, 83, 93, 0, 121, 162, 191, 195, 493, 424, + 432, 105, 430, 193, 172, 231, 466, 174, 192, 140, + 221, 185, 230, 240, 241, 218, 238, 245, 208, 86, + 217, 229, 102, 203, 88, 227, 214, 151, 131, 132, + 87, 0, 189, 110, 117, 107, 164, 224, 225, 106, + 248, 94, 237, 90, 95, 236, 158, 220, 228, 152, + 145, 89, 226, 150, 144, 135, 114, 124, 182, 142, + 183, 125, 155, 154, 156, 0, 403, 0, 212, 234, + 249, 99, 419, 219, 243, 244, 0, 0, 100, 118, + 113, 181, 157, 96, 127, 209, 134, 141, 188, 247, + 171, 194, 103, 233, 210, 415, 418, 413, 414, 461, + 462, 508, 509, 510, 486, 409, 0, 416, 417, 0, + 491, 498, 499, 465, 82, 91, 138, 246, 186, 116, + 235, 399, 412, 109, 422, 0, 0, 434, 439, 440, + 452, 454, 455, 456, 457, 464, 471, 472, 474, 480, + 481, 482, 483, 488, 495, 514, 84, 85, 92, 98, + 104, 108, 112, 115, 120, 123, 126, 128, 129, 130, + 133, 143, 146, 147, 148, 149, 159, 160, 161, 163, + 166, 167, 168, 169, 170, 173, 175, 176, 177, 178, + 179, 180, 187, 190, 196, 197, 198, 199, 200, 201, + 202, 204, 205, 206, 207, 213, 216, 222, 223, 232, + 239, 242, 502, 490, 0, 447, 505, 421, 437, 513, + 438, 441, 478, 406, 460, 165, 435, 0, 425, 401, + 431, 402, 423, 449, 111, 453, 420, 492, 463, 504, + 137, 511, 139, 469, 0, 211, 153, 0, 0, 451, + 494, 458, 487, 446, 479, 411, 468, 506, 436, 476, + 507, 0, 0, 0, 320, 0, 0, 0, 0, 0, + 0, 0, 0, 101, 0, 473, 501, 433, 475, 477, + 400, 470, 0, 404, 407, 512, 497, 428, 429, 0, + 0, 0, 0, 0, 0, 0, 450, 459, 484, 444, + 0, 0, 0, 0, 0, 0, 0, 0, 426, 0, + 467, 0, 0, 0, 408, 405, 0, 0, 448, 0, + 0, 0, 410, 0, 427, 485, 0, 398, 119, 489, + 496, 445, 265, 500, 443, 442, 503, 184, 0, 215, + 122, 136, 97, 83, 93, 0, 121, 162, 191, 195, + 493, 424, 432, 105, 430, 193, 172, 231, 466, 174, + 192, 140, 221, 185, 230, 240, 241, 218, 238, 245, + 208, 86, 217, 229, 102, 203, 88, 227, 214, 151, + 131, 132, 87, 0, 189, 110, 117, 107, 164, 224, + 225, 106, 248, 94, 237, 90, 95, 236, 158, 220, + 228, 152, 145, 89, 226, 150, 144, 135, 114, 124, + 182, 142, 183, 125, 155, 154, 156, 0, 403, 0, + 212, 234, 249, 99, 419, 219, 243, 244, 0, 0, + 100, 118, 113, 181, 157, 96, 127, 209, 134, 141, + 188, 247, 171, 194, 103, 233, 210, 415, 418, 413, + 414, 461, 462, 508, 509, 510, 486, 409, 0, 416, + 417, 0, 491, 498, 499, 465, 82, 91, 138, 246, + 186, 116, 235, 399, 412, 109, 422, 0, 0, 434, + 439, 440, 452, 454, 455, 456, 457, 464, 471, 472, + 474, 480, 481, 482, 483, 488, 495, 514, 84, 85, + 92, 98, 104, 108, 112, 115, 120, 123, 126, 128, + 129, 130, 133, 143, 146, 147, 148, 149, 159, 160, + 161, 163, 166, 167, 168, 169, 170, 173, 175, 176, + 177, 178, 179, 180, 187, 190, 196, 197, 198, 199, + 200, 201, 202, 204, 205, 206, 207, 213, 216, 222, + 223, 232, 239, 242, 502, 490, 0, 447, 505, 421, + 437, 513, 438, 441, 478, 406, 460, 165, 435, 0, + 425, 401, 431, 402, 423, 449, 111, 453, 420, 492, + 463, 504, 137, 511, 139, 469, 0, 211, 153, 0, + 0, 451, 494, 458, 487, 446, 479, 411, 468, 506, + 436, 476, 507, 0, 0, 0, 80, 0, 0, 0, + 0, 0, 0, 0, 0, 101, 0, 473, 501, 433, + 475, 477, 400, 470, 0, 404, 407, 512, 497, 428, + 429, 0, 0, 0, 0, 0, 0, 0, 450, 459, + 484, 444, 0, 0, 0, 0, 0, 0, 0, 0, + 426, 0, 467, 0, 0, 0, 408, 405, 0, 0, + 448, 0, 0, 0, 410, 0, 427, 485, 0, 398, + 119, 489, 496, 445, 265, 500, 443, 442, 503, 184, + 0, 215, 122, 136, 97, 83, 93, 0, 121, 162, + 191, 195, 493, 424, 432, 105, 430, 193, 172, 231, + 466, 174, 192, 140, 221, 185, 230, 240, 241, 218, + 238, 245, 208, 86, 217, 229, 102, 203, 88, 227, + 214, 151, 131, 132, 87, 0, 189, 110, 117, 107, + 164, 224, 225, 106, 248, 94, 237, 90, 396, 236, + 158, 220, 228, 152, 145, 89, 226, 150, 144, 135, + 114, 124, 182, 142, 183, 125, 155, 154, 156, 0, + 403, 0, 212, 234, 249, 99, 419, 219, 243, 244, + 0, 0, 100, 118, 113, 181, 397, 395, 127, 209, + 134, 141, 188, 247, 171, 194, 103, 233, 210, 415, + 418, 413, 414, 461, 462, 508, 509, 510, 486, 409, + 0, 416, 417, 0, 491, 498, 499, 465, 82, 91, + 138, 246, 186, 116, 235, 399, 412, 109, 422, 0, + 0, 434, 439, 440, 452, 454, 455, 456, 457, 464, + 471, 472, 474, 480, 481, 482, 483, 488, 495, 514, + 84, 85, 92, 98, 104, 108, 112, 115, 120, 123, + 126, 128, 129, 130, 133, 143, 146, 147, 148, 149, + 159, 160, 161, 163, 166, 167, 168, 169, 170, 173, + 175, 176, 177, 178, 179, 180, 187, 190, 196, 197, + 198, 199, 200, 201, 202, 204, 205, 206, 207, 213, + 216, 222, 223, 232, 239, 242, 502, 490, 0, 447, + 505, 421, 437, 513, 438, 441, 478, 406, 460, 165, + 435, 0, 425, 401, 431, 402, 423, 449, 111, 453, + 420, 492, 463, 504, 137, 511, 139, 469, 0, 211, + 153, 0, 0, 451, 494, 458, 487, 446, 479, 411, + 468, 506, 436, 476, 507, 0, 0, 0, 263, 0, + 0, 0, 0, 0, 0, 0, 0, 101, 0, 473, + 501, 433, 475, 477, 400, 470, 0, 404, 407, 512, + 497, 428, 429, 0, 0, 0, 0, 0, 0, 0, + 450, 459, 484, 444, 0, 0, 0, 0, 0, 0, + 0, 0, 426, 0, 467, 0, 0, 0, 408, 405, + 0, 0, 448, 0, 0, 0, 410, 0, 427, 485, + 0, 398, 119, 489, 496, 445, 265, 500, 443, 442, + 503, 184, 0, 215, 122, 136, 97, 83, 93, 0, + 121, 162, 191, 195, 493, 424, 432, 105, 430, 193, + 172, 231, 466, 174, 192, 140, 221, 185, 230, 240, + 241, 218, 238, 245, 208, 86, 217, 229, 102, 203, + 88, 227, 214, 151, 131, 132, 87, 0, 189, 110, + 117, 107, 164, 224, 225, 106, 248, 94, 237, 90, + 95, 236, 158, 220, 228, 152, 145, 89, 226, 150, + 144, 135, 114, 124, 182, 142, 183, 125, 155, 154, + 156, 0, 403, 0, 212, 234, 249, 99, 419, 219, + 243, 244, 0, 0, 100, 118, 113, 181, 157, 96, + 127, 209, 134, 141, 188, 247, 171, 194, 103, 233, + 210, 415, 418, 413, 414, 461, 462, 508, 509, 510, + 486, 409, 0, 416, 417, 0, 491, 498, 499, 465, + 82, 91, 138, 246, 186, 116, 235, 399, 412, 109, + 422, 0, 0, 434, 439, 440, 452, 454, 455, 456, + 457, 464, 471, 472, 474, 480, 481, 482, 483, 488, + 495, 514, 84, 85, 92, 98, 104, 108, 112, 115, + 120, 123, 126, 128, 129, 130, 133, 143, 146, 147, + 148, 149, 159, 160, 161, 163, 166, 167, 168, 169, + 170, 173, 175, 176, 177, 178, 179, 180, 187, 190, + 196, 197, 198, 199, 200, 201, 202, 204, 205, 206, + 207, 213, 216, 222, 223, 232, 239, 242, 502, 490, + 0, 447, 505, 421, 437, 513, 438, 441, 478, 406, + 460, 165, 435, 0, 425, 401, 431, 402, 423, 449, + 111, 453, 420, 492, 463, 504, 137, 511, 139, 469, + 0, 211, 153, 0, 0, 451, 494, 458, 487, 446, + 479, 411, 468, 506, 436, 476, 507, 0, 0, 0, + 80, 0, 0, 0, 0, 0, 0, 0, 0, 101, + 0, 473, 501, 433, 475, 477, 400, 470, 0, 404, + 407, 512, 497, 428, 429, 0, 0, 0, 0, 0, + 0, 0, 450, 459, 484, 444, 0, 0, 0, 0, + 0, 0, 0, 0, 426, 0, 467, 0, 0, 0, + 408, 405, 0, 0, 448, 0, 0, 0, 410, 0, + 427, 485, 0, 398, 119, 489, 496, 445, 265, 500, + 443, 442, 503, 184, 0, 215, 122, 136, 97, 83, + 93, 0, 121, 162, 191, 195, 493, 424, 432, 105, + 430, 193, 172, 231, 466, 174, 192, 140, 221, 185, + 230, 240, 241, 218, 238, 245, 208, 86, 217, 703, + 102, 203, 88, 227, 214, 151, 131, 132, 87, 0, + 189, 110, 117, 107, 164, 224, 225, 106, 248, 94, + 237, 90, 396, 236, 158, 220, 228, 152, 145, 89, + 226, 150, 144, 135, 114, 124, 182, 142, 183, 125, + 155, 154, 156, 0, 403, 0, 212, 234, 249, 99, + 419, 219, 243, 244, 0, 0, 100, 118, 113, 181, + 397, 395, 127, 209, 134, 141, 188, 247, 171, 194, + 103, 233, 210, 415, 418, 413, 414, 461, 462, 508, + 509, 510, 486, 409, 0, 416, 417, 0, 491, 498, + 499, 465, 82, 91, 138, 246, 186, 116, 235, 399, + 412, 109, 422, 0, 0, 434, 439, 440, 452, 454, + 455, 456, 457, 464, 471, 472, 474, 480, 481, 482, + 483, 488, 495, 514, 84, 85, 92, 98, 104, 108, + 112, 115, 120, 123, 126, 128, 129, 130, 133, 143, + 146, 147, 148, 149, 159, 160, 161, 163, 166, 167, + 168, 169, 170, 173, 175, 176, 177, 178, 179, 180, + 187, 190, 196, 197, 198, 199, 200, 201, 202, 204, + 205, 206, 207, 213, 216, 222, 223, 232, 239, 242, + 502, 490, 0, 447, 505, 421, 437, 513, 438, 441, + 478, 406, 460, 165, 435, 0, 425, 401, 431, 402, + 423, 449, 111, 453, 420, 492, 463, 504, 137, 511, + 139, 469, 0, 211, 153, 0, 0, 451, 494, 458, + 487, 446, 479, 411, 468, 506, 436, 476, 507, 0, + 0, 0, 80, 0, 0, 0, 0, 0, 0, 0, + 0, 101, 0, 473, 501, 433, 475, 477, 400, 470, + 0, 404, 407, 512, 497, 428, 429, 0, 0, 0, + 0, 0, 0, 0, 450, 459, 484, 444, 0, 0, + 0, 0, 0, 0, 0, 0, 426, 0, 467, 0, + 0, 0, 408, 405, 0, 0, 448, 0, 0, 0, + 410, 0, 427, 485, 0, 398, 119, 489, 496, 445, + 265, 500, 443, 442, 503, 184, 0, 215, 122, 136, + 97, 83, 93, 0, 121, 162, 191, 195, 493, 424, + 432, 105, 430, 193, 172, 231, 466, 174, 192, 140, + 221, 185, 230, 240, 241, 218, 238, 245, 208, 86, + 217, 387, 102, 203, 88, 227, 214, 151, 131, 132, + 87, 0, 189, 110, 117, 107, 164, 224, 225, 106, + 248, 94, 237, 90, 396, 236, 158, 220, 228, 152, + 145, 89, 226, 150, 144, 135, 114, 124, 182, 142, + 183, 125, 155, 154, 156, 0, 403, 0, 212, 234, + 249, 99, 419, 219, 243, 244, 0, 0, 100, 118, + 113, 181, 397, 395, 390, 389, 134, 141, 188, 247, + 171, 194, 103, 233, 210, 415, 418, 413, 414, 461, + 462, 508, 509, 510, 486, 409, 0, 416, 417, 0, + 491, 498, 499, 465, 82, 91, 138, 246, 186, 116, + 235, 399, 412, 109, 422, 0, 0, 434, 439, 440, + 452, 454, 455, 456, 457, 464, 471, 472, 474, 480, + 481, 482, 483, 488, 495, 514, 84, 85, 92, 98, + 104, 108, 112, 115, 120, 123, 126, 128, 129, 130, + 133, 143, 146, 147, 148, 149, 159, 160, 161, 163, + 166, 167, 168, 169, 170, 173, 175, 176, 177, 178, + 179, 180, 187, 190, 196, 197, 198, 199, 200, 201, + 202, 204, 205, 206, 207, 213, 216, 222, 223, 232, + 239, 242, 165, 0, 0, 0, 0, 322, 0, 0, + 0, 111, 0, 319, 0, 0, 0, 137, 362, 139, + 0, 0, 211, 153, 0, 0, 0, 0, 353, 354, + 0, 0, 0, 0, 0, 0, 946, 0, 54, 0, + 0, 320, 341, 340, 343, 344, 345, 346, 0, 0, + 101, 342, 347, 348, 349, 947, 0, 0, 317, 334, + 0, 361, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 331, 332, 0, 0, 0, 0, 375, 0, 333, + 0, 0, 328, 329, 330, 335, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 119, 0, 0, 0, 265, + 0, 0, 373, 0, 184, 0, 215, 122, 136, 97, + 83, 93, 0, 121, 162, 191, 195, 0, 0, 0, + 105, 0, 193, 172, 231, 0, 174, 192, 140, 221, + 185, 230, 240, 241, 218, 238, 245, 208, 86, 217, + 229, 102, 203, 88, 227, 214, 151, 131, 132, 87, + 0, 189, 110, 117, 107, 164, 224, 225, 106, 248, + 94, 237, 90, 95, 236, 158, 220, 228, 152, 145, + 89, 226, 150, 144, 135, 114, 124, 182, 142, 183, + 125, 155, 154, 156, 0, 0, 0, 212, 234, 249, + 99, 0, 219, 243, 244, 0, 0, 100, 118, 113, + 181, 157, 96, 127, 209, 134, 141, 188, 247, 171, + 194, 103, 233, 210, 363, 374, 369, 370, 367, 368, + 366, 365, 364, 376, 355, 356, 357, 358, 360, 0, + 371, 372, 359, 82, 91, 138, 246, 186, 116, 235, + 0, 0, 109, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 84, 85, 92, 98, 104, + 108, 112, 115, 120, 123, 126, 128, 129, 130, 133, + 143, 146, 147, 148, 149, 159, 160, 161, 163, 166, + 167, 168, 169, 170, 173, 175, 176, 177, 178, 179, + 180, 187, 190, 196, 197, 198, 199, 200, 201, 202, + 204, 205, 206, 207, 213, 216, 222, 223, 232, 239, + 242, 165, 0, 0, 873, 0, 322, 0, 0, 0, + 111, 0, 319, 0, 0, 0, 137, 362, 139, 0, + 0, 211, 153, 0, 0, 0, 0, 353, 354, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, - 260, 281, 800, 283, 284, 285, 286, 0, 0, 96, - 282, 287, 288, 289, 0, 0, 0, 257, 274, 0, - 301, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 271, 272, 253, 0, 0, 0, 315, 0, 273, 0, - 0, 268, 269, 270, 275, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 109, 0, 0, 0, 206, 0, - 0, 313, 0, 146, 0, 163, 111, 119, 83, 90, - 0, 110, 137, 151, 155, 0, 0, 0, 99, 0, - 153, 141, 176, 0, 142, 152, 123, 168, 147, 175, - 183, 184, 165, 182, 186, 157, 84, 164, 174, 97, - 156, 86, 172, 162, 129, 115, 116, 85, 0, 150, - 102, 107, 101, 138, 169, 170, 100, 189, 91, 181, - 88, 92, 180, 136, 167, 173, 130, 127, 87, 171, - 128, 126, 118, 105, 112, 144, 125, 145, 113, 133, - 132, 134, 0, 0, 0, 161, 178, 190, 94, 0, - 166, 185, 0, 0, 95, 108, 104, 143, 135, 93, - 114, 158, 117, 124, 149, 188, 140, 154, 98, 177, - 159, 303, 314, 309, 310, 307, 308, 306, 305, 304, - 316, 295, 296, 297, 298, 300, 24, 311, 312, 299, - 82, 89, 121, 187, 148, 106, 179, 0, 139, 0, - 0, 0, 0, 262, 0, 0, 0, 103, 0, 259, - 0, 0, 0, 120, 302, 122, 0, 0, 160, 131, - 0, 0, 0, 0, 293, 294, 0, 0, 0, 0, - 0, 0, 0, 0, 54, 0, 0, 260, 281, 280, - 283, 284, 285, 286, 0, 0, 96, 282, 287, 288, - 289, 0, 0, 0, 257, 274, 0, 301, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 271, 272, 0, - 0, 0, 0, 315, 0, 273, 0, 0, 268, 269, - 270, 275, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 109, 0, 0, 0, 206, 0, 0, 313, 0, - 146, 0, 163, 111, 119, 83, 90, 0, 110, 137, - 151, 155, 0, 0, 0, 99, 0, 153, 141, 176, - 0, 142, 152, 123, 168, 147, 175, 183, 184, 165, - 182, 186, 157, 84, 164, 174, 97, 156, 86, 172, - 162, 129, 115, 116, 85, 0, 150, 102, 107, 101, - 138, 169, 170, 100, 189, 91, 181, 88, 92, 180, - 136, 167, 173, 130, 127, 87, 171, 128, 126, 118, - 105, 112, 144, 125, 145, 113, 133, 132, 134, 0, - 0, 0, 161, 178, 190, 94, 0, 166, 185, 0, - 0, 95, 108, 104, 143, 135, 93, 114, 158, 117, - 124, 149, 188, 140, 154, 98, 177, 159, 303, 314, - 309, 310, 307, 308, 306, 305, 304, 316, 295, 296, - 297, 298, 300, 0, 311, 312, 299, 82, 89, 121, - 187, 148, 106, 179, 139, 0, 0, 0, 0, 262, - 0, 0, 0, 103, 0, 259, 0, 0, 0, 120, - 302, 122, 0, 0, 160, 131, 0, 0, 0, 0, - 293, 294, 0, 0, 0, 0, 0, 0, 0, 0, - 54, 0, 0, 260, 281, 280, 283, 284, 285, 286, - 0, 0, 96, 282, 287, 288, 289, 0, 0, 0, - 257, 274, 0, 301, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 271, 272, 0, 0, 0, 0, 315, - 0, 273, 0, 0, 268, 269, 270, 275, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 109, 0, 0, - 0, 206, 0, 0, 313, 0, 146, 0, 163, 111, - 119, 83, 90, 0, 110, 137, 151, 155, 0, 0, - 0, 99, 0, 153, 141, 176, 0, 142, 152, 123, - 168, 147, 175, 183, 184, 165, 182, 186, 157, 84, - 164, 174, 97, 156, 86, 172, 162, 129, 115, 116, - 85, 0, 150, 102, 107, 101, 138, 169, 170, 100, - 189, 91, 181, 88, 92, 180, 136, 167, 173, 130, - 127, 87, 171, 128, 126, 118, 105, 112, 144, 125, - 145, 113, 133, 132, 134, 0, 0, 0, 161, 178, - 190, 94, 0, 166, 185, 0, 0, 95, 108, 104, - 143, 135, 93, 114, 158, 117, 124, 149, 188, 140, - 154, 98, 177, 159, 303, 314, 309, 310, 307, 308, - 306, 305, 304, 316, 295, 296, 297, 298, 300, 0, - 311, 312, 299, 82, 89, 121, 187, 148, 106, 179, - 139, 0, 0, 0, 0, 0, 0, 0, 0, 103, - 0, 0, 0, 0, 0, 120, 302, 122, 0, 0, - 160, 131, 0, 0, 0, 0, 293, 294, 0, 0, - 0, 0, 0, 0, 0, 0, 54, 0, 0, 260, - 281, 280, 283, 284, 285, 286, 0, 0, 96, 282, - 287, 288, 289, 0, 0, 0, 0, 274, 0, 301, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 271, - 272, 0, 0, 0, 0, 315, 0, 273, 0, 0, - 268, 269, 270, 275, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 109, 0, 0, 0, 206, 0, 0, - 313, 0, 146, 0, 163, 111, 119, 83, 90, 0, - 110, 137, 151, 155, 0, 0, 0, 99, 0, 153, - 141, 176, 1421, 142, 152, 123, 168, 147, 175, 183, - 184, 165, 182, 186, 157, 84, 164, 174, 97, 156, - 86, 172, 162, 129, 115, 116, 85, 0, 150, 102, - 107, 101, 138, 169, 170, 100, 189, 91, 181, 88, - 92, 180, 136, 167, 173, 130, 127, 87, 171, 128, - 126, 118, 105, 112, 144, 125, 145, 113, 133, 132, - 134, 0, 0, 0, 161, 178, 190, 94, 0, 166, - 185, 0, 0, 95, 108, 104, 143, 135, 93, 114, - 158, 117, 124, 149, 188, 140, 154, 98, 177, 159, - 303, 314, 309, 310, 307, 308, 306, 305, 304, 316, - 295, 296, 297, 298, 300, 0, 311, 312, 299, 82, - 89, 121, 187, 148, 106, 179, 139, 0, 0, 0, - 0, 0, 0, 0, 0, 103, 0, 0, 0, 0, - 0, 120, 302, 122, 0, 0, 160, 131, 0, 0, - 0, 0, 293, 294, 0, 0, 0, 0, 0, 0, - 0, 0, 54, 0, 493, 260, 281, 280, 283, 284, - 285, 286, 0, 0, 96, 282, 287, 288, 289, 0, - 0, 0, 0, 274, 0, 301, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 271, 272, 0, 0, 0, - 0, 315, 0, 273, 0, 0, 268, 269, 270, 275, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, - 0, 0, 0, 206, 0, 0, 313, 0, 146, 0, - 163, 111, 119, 83, 90, 0, 110, 137, 151, 155, - 0, 0, 0, 99, 0, 153, 141, 176, 0, 142, - 152, 123, 168, 147, 175, 183, 184, 165, 182, 186, - 157, 84, 164, 174, 97, 156, 86, 172, 162, 129, - 115, 116, 85, 0, 150, 102, 107, 101, 138, 169, - 170, 100, 189, 91, 181, 88, 92, 180, 136, 167, - 173, 130, 127, 87, 171, 128, 126, 118, 105, 112, - 144, 125, 145, 113, 133, 132, 134, 0, 0, 0, - 161, 178, 190, 94, 0, 166, 185, 0, 0, 95, - 108, 104, 143, 135, 93, 114, 158, 117, 124, 149, - 188, 140, 154, 98, 177, 159, 303, 314, 309, 310, - 307, 308, 306, 305, 304, 316, 295, 296, 297, 298, - 300, 0, 311, 312, 299, 82, 89, 121, 187, 148, - 106, 179, 139, 0, 0, 0, 0, 0, 0, 0, - 0, 103, 0, 0, 0, 0, 0, 120, 302, 122, - 0, 0, 160, 131, 0, 0, 0, 0, 293, 294, - 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, - 0, 260, 281, 280, 283, 284, 285, 286, 0, 0, - 96, 282, 287, 288, 289, 0, 0, 0, 0, 274, - 0, 301, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 271, 272, 0, 0, 0, 0, 315, 0, 273, - 0, 0, 268, 269, 270, 275, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 109, 0, 0, 0, 206, - 0, 0, 313, 0, 146, 0, 163, 111, 119, 83, - 90, 0, 110, 137, 151, 155, 0, 0, 0, 99, - 0, 153, 141, 176, 0, 142, 152, 123, 168, 147, - 175, 183, 184, 165, 182, 186, 157, 84, 164, 174, - 97, 156, 86, 172, 162, 129, 115, 116, 85, 0, - 150, 102, 107, 101, 138, 169, 170, 100, 189, 91, - 181, 88, 92, 180, 136, 167, 173, 130, 127, 87, - 171, 128, 126, 118, 105, 112, 144, 125, 145, 113, - 133, 132, 134, 0, 0, 0, 161, 178, 190, 94, - 0, 166, 185, 0, 0, 95, 108, 104, 143, 135, - 93, 114, 158, 117, 124, 149, 188, 140, 154, 98, - 177, 159, 303, 314, 309, 310, 307, 308, 306, 305, - 304, 316, 295, 296, 297, 298, 300, 0, 311, 312, - 299, 82, 89, 121, 187, 148, 106, 179, 139, 0, - 0, 0, 0, 0, 0, 0, 0, 103, 0, 0, - 0, 0, 0, 120, 0, 122, 0, 0, 160, 131, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 80, 0, 0, - 0, 0, 0, 0, 0, 0, 96, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 527, 526, 536, 537, 529, 530, 531, - 532, 533, 534, 535, 528, 0, 0, 538, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 109, 0, 0, 0, 206, 0, 0, 0, 0, - 146, 0, 163, 111, 119, 83, 90, 0, 110, 137, - 151, 155, 0, 0, 0, 99, 0, 153, 141, 176, - 0, 142, 152, 123, 168, 147, 175, 183, 184, 165, - 182, 186, 157, 84, 164, 174, 97, 156, 86, 172, - 162, 129, 115, 116, 85, 0, 150, 102, 107, 101, - 138, 169, 170, 100, 189, 91, 181, 88, 92, 180, - 136, 167, 173, 130, 127, 87, 171, 128, 126, 118, - 105, 112, 144, 125, 145, 113, 133, 132, 134, 0, - 0, 0, 161, 178, 190, 94, 0, 166, 185, 0, - 0, 95, 108, 104, 143, 135, 93, 114, 158, 117, - 124, 149, 188, 140, 154, 98, 177, 159, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 82, 89, 121, - 187, 148, 106, 179, 139, 0, 0, 0, 515, 0, - 0, 0, 0, 103, 0, 0, 0, 0, 0, 120, - 0, 122, 0, 0, 160, 131, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 80, 0, 517, 0, 0, 0, 0, - 0, 0, 96, 0, 0, 0, 0, 0, 512, 511, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 513, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 109, 0, 0, - 0, 206, 0, 0, 0, 0, 146, 0, 163, 111, - 119, 83, 90, 0, 110, 137, 151, 155, 0, 0, - 0, 99, 0, 153, 141, 176, 0, 142, 152, 123, - 168, 147, 175, 183, 184, 165, 182, 186, 157, 84, - 164, 174, 97, 156, 86, 172, 162, 129, 115, 116, - 85, 0, 150, 102, 107, 101, 138, 169, 170, 100, - 189, 91, 181, 88, 92, 180, 136, 167, 173, 130, - 127, 87, 171, 128, 126, 118, 105, 112, 144, 125, - 145, 113, 133, 132, 134, 0, 0, 0, 161, 178, - 190, 94, 0, 166, 185, 0, 0, 95, 108, 104, - 143, 135, 93, 114, 158, 117, 124, 149, 188, 140, - 154, 98, 177, 159, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 139, 0, 82, 89, 121, 187, 148, 106, 179, - 103, 0, 0, 0, 0, 0, 120, 0, 122, 0, - 0, 160, 131, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 80, 0, 0, 0, 0, 0, 0, 0, 0, 96, - 0, 0, 0, 0, 0, 74, 0, 0, 0, 0, + 320, 341, 340, 343, 344, 345, 346, 0, 0, 101, + 342, 347, 348, 349, 0, 0, 0, 317, 334, 0, + 361, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 331, 332, 313, 0, 0, 0, 375, 0, 333, 0, + 0, 328, 329, 330, 335, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 119, 0, 0, 0, 265, 0, + 0, 373, 0, 184, 0, 215, 122, 136, 97, 83, + 93, 0, 121, 162, 191, 195, 0, 0, 0, 105, + 0, 193, 172, 231, 0, 174, 192, 140, 221, 185, + 230, 240, 241, 218, 238, 245, 208, 86, 217, 229, + 102, 203, 88, 227, 214, 151, 131, 132, 87, 0, + 189, 110, 117, 107, 164, 224, 225, 106, 248, 94, + 237, 90, 95, 236, 158, 220, 228, 152, 145, 89, + 226, 150, 144, 135, 114, 124, 182, 142, 183, 125, + 155, 154, 156, 0, 0, 0, 212, 234, 249, 99, + 0, 219, 243, 244, 0, 0, 100, 118, 113, 181, + 157, 96, 127, 209, 134, 141, 188, 247, 171, 194, + 103, 233, 210, 363, 374, 369, 370, 367, 368, 366, + 365, 364, 376, 355, 356, 357, 358, 360, 0, 371, + 372, 359, 82, 91, 138, 246, 186, 116, 235, 0, + 0, 109, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 84, 85, 92, 98, 104, 108, + 112, 115, 120, 123, 126, 128, 129, 130, 133, 143, + 146, 147, 148, 149, 159, 160, 161, 163, 166, 167, + 168, 169, 170, 173, 175, 176, 177, 178, 179, 180, + 187, 190, 196, 197, 198, 199, 200, 201, 202, 204, + 205, 206, 207, 213, 216, 222, 223, 232, 239, 242, + 165, 0, 0, 0, 0, 322, 0, 0, 0, 111, + 0, 319, 0, 0, 0, 137, 362, 139, 0, 0, + 211, 153, 0, 0, 0, 0, 353, 354, 0, 0, + 0, 0, 0, 0, 0, 0, 54, 0, 576, 320, + 341, 340, 343, 344, 345, 346, 0, 0, 101, 342, + 347, 348, 349, 0, 0, 0, 317, 334, 0, 361, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 331, + 332, 0, 0, 0, 0, 375, 0, 333, 0, 0, + 328, 329, 330, 335, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 119, 0, 0, 0, 265, 0, 0, + 373, 0, 184, 0, 215, 122, 136, 97, 83, 93, + 0, 121, 162, 191, 195, 0, 0, 0, 105, 0, + 193, 172, 231, 0, 174, 192, 140, 221, 185, 230, + 240, 241, 218, 238, 245, 208, 86, 217, 229, 102, + 203, 88, 227, 214, 151, 131, 132, 87, 0, 189, + 110, 117, 107, 164, 224, 225, 106, 248, 94, 237, + 90, 95, 236, 158, 220, 228, 152, 145, 89, 226, + 150, 144, 135, 114, 124, 182, 142, 183, 125, 155, + 154, 156, 0, 0, 0, 212, 234, 249, 99, 0, + 219, 243, 244, 0, 0, 100, 118, 113, 181, 157, + 96, 127, 209, 134, 141, 188, 247, 171, 194, 103, + 233, 210, 363, 374, 369, 370, 367, 368, 366, 365, + 364, 376, 355, 356, 357, 358, 360, 0, 371, 372, + 359, 82, 91, 138, 246, 186, 116, 235, 0, 0, + 109, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 84, 85, 92, 98, 104, 108, 112, + 115, 120, 123, 126, 128, 129, 130, 133, 143, 146, + 147, 148, 149, 159, 160, 161, 163, 166, 167, 168, + 169, 170, 173, 175, 176, 177, 178, 179, 180, 187, + 190, 196, 197, 198, 199, 200, 201, 202, 204, 205, + 206, 207, 213, 216, 222, 223, 232, 239, 242, 165, + 0, 0, 0, 0, 322, 0, 0, 0, 111, 0, + 319, 0, 0, 0, 137, 362, 139, 0, 0, 211, + 153, 0, 0, 0, 0, 353, 354, 0, 0, 0, + 0, 0, 0, 0, 0, 54, 0, 0, 320, 341, + 340, 343, 344, 345, 346, 0, 0, 101, 342, 347, + 348, 349, 0, 0, 0, 317, 334, 0, 361, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 331, 332, + 313, 0, 0, 0, 375, 0, 333, 0, 0, 328, + 329, 330, 335, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 119, 0, 0, 0, 265, 0, 0, 373, + 0, 184, 0, 215, 122, 136, 97, 83, 93, 0, + 121, 162, 191, 195, 0, 0, 0, 105, 0, 193, + 172, 231, 0, 174, 192, 140, 221, 185, 230, 240, + 241, 218, 238, 245, 208, 86, 217, 229, 102, 203, + 88, 227, 214, 151, 131, 132, 87, 0, 189, 110, + 117, 107, 164, 224, 225, 106, 248, 94, 237, 90, + 95, 236, 158, 220, 228, 152, 145, 89, 226, 150, + 144, 135, 114, 124, 182, 142, 183, 125, 155, 154, + 156, 0, 0, 0, 212, 234, 249, 99, 0, 219, + 243, 244, 0, 0, 100, 118, 113, 181, 157, 96, + 127, 209, 134, 141, 188, 247, 171, 194, 103, 233, + 210, 363, 374, 369, 370, 367, 368, 366, 365, 364, + 376, 355, 356, 357, 358, 360, 0, 371, 372, 359, + 82, 91, 138, 246, 186, 116, 235, 0, 0, 109, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 84, 85, 92, 98, 104, 108, 112, 115, + 120, 123, 126, 128, 129, 130, 133, 143, 146, 147, + 148, 149, 159, 160, 161, 163, 166, 167, 168, 169, + 170, 173, 175, 176, 177, 178, 179, 180, 187, 190, + 196, 197, 198, 199, 200, 201, 202, 204, 205, 206, + 207, 213, 216, 222, 223, 232, 239, 242, 165, 0, + 0, 0, 0, 322, 0, 0, 0, 111, 0, 319, + 0, 0, 0, 137, 362, 139, 0, 0, 211, 153, + 0, 0, 0, 0, 353, 354, 0, 0, 0, 0, + 0, 0, 0, 0, 54, 0, 0, 320, 341, 888, + 343, 344, 345, 346, 0, 0, 101, 342, 347, 348, + 349, 0, 0, 0, 317, 334, 0, 361, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 331, 332, 313, + 0, 0, 0, 375, 0, 333, 0, 0, 328, 329, + 330, 335, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 119, 0, 0, 0, 265, 0, 0, 373, 0, + 184, 0, 215, 122, 136, 97, 83, 93, 0, 121, + 162, 191, 195, 0, 0, 0, 105, 0, 193, 172, + 231, 0, 174, 192, 140, 221, 185, 230, 240, 241, + 218, 238, 245, 208, 86, 217, 229, 102, 203, 88, + 227, 214, 151, 131, 132, 87, 0, 189, 110, 117, + 107, 164, 224, 225, 106, 248, 94, 237, 90, 95, + 236, 158, 220, 228, 152, 145, 89, 226, 150, 144, + 135, 114, 124, 182, 142, 183, 125, 155, 154, 156, + 0, 0, 0, 212, 234, 249, 99, 0, 219, 243, + 244, 0, 0, 100, 118, 113, 181, 157, 96, 127, + 209, 134, 141, 188, 247, 171, 194, 103, 233, 210, + 363, 374, 369, 370, 367, 368, 366, 365, 364, 376, + 355, 356, 357, 358, 360, 0, 371, 372, 359, 82, + 91, 138, 246, 186, 116, 235, 0, 0, 109, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 84, 85, 92, 98, 104, 108, 112, 115, 120, + 123, 126, 128, 129, 130, 133, 143, 146, 147, 148, + 149, 159, 160, 161, 163, 166, 167, 168, 169, 170, + 173, 175, 176, 177, 178, 179, 180, 187, 190, 196, + 197, 198, 199, 200, 201, 202, 204, 205, 206, 207, + 213, 216, 222, 223, 232, 239, 242, 165, 0, 0, + 0, 0, 322, 0, 0, 0, 111, 0, 319, 0, + 0, 0, 137, 362, 139, 0, 0, 211, 153, 0, + 0, 0, 0, 353, 354, 0, 0, 0, 0, 0, + 0, 0, 0, 54, 0, 0, 320, 341, 885, 343, + 344, 345, 346, 0, 0, 101, 342, 347, 348, 349, + 0, 0, 0, 317, 334, 0, 361, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 331, 332, 313, 0, + 0, 0, 375, 0, 333, 0, 0, 328, 329, 330, + 335, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 119, 0, 0, 0, 265, 0, 0, 373, 0, 184, + 0, 215, 122, 136, 97, 83, 93, 0, 121, 162, + 191, 195, 0, 0, 0, 105, 0, 193, 172, 231, + 0, 174, 192, 140, 221, 185, 230, 240, 241, 218, + 238, 245, 208, 86, 217, 229, 102, 203, 88, 227, + 214, 151, 131, 132, 87, 0, 189, 110, 117, 107, + 164, 224, 225, 106, 248, 94, 237, 90, 95, 236, + 158, 220, 228, 152, 145, 89, 226, 150, 144, 135, + 114, 124, 182, 142, 183, 125, 155, 154, 156, 0, + 0, 0, 212, 234, 249, 99, 0, 219, 243, 244, + 0, 0, 100, 118, 113, 181, 157, 96, 127, 209, + 134, 141, 188, 247, 171, 194, 103, 233, 210, 363, + 374, 369, 370, 367, 368, 366, 365, 364, 376, 355, + 356, 357, 358, 360, 0, 371, 372, 359, 82, 91, + 138, 246, 186, 116, 235, 0, 0, 109, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 84, 85, 92, 98, 104, 108, 112, 115, 120, 123, + 126, 128, 129, 130, 133, 143, 146, 147, 148, 149, + 159, 160, 161, 163, 166, 167, 168, 169, 170, 173, + 175, 176, 177, 178, 179, 180, 187, 190, 196, 197, + 198, 199, 200, 201, 202, 204, 205, 206, 207, 213, + 216, 222, 223, 232, 239, 242, 24, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 165, 0, + 0, 0, 0, 322, 0, 0, 0, 111, 0, 319, + 0, 0, 0, 137, 362, 139, 0, 0, 211, 153, + 0, 0, 0, 0, 353, 354, 0, 0, 0, 0, + 0, 0, 0, 0, 54, 0, 0, 320, 341, 340, + 343, 344, 345, 346, 0, 0, 101, 342, 347, 348, + 349, 0, 0, 0, 317, 334, 0, 361, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 331, 332, 0, + 0, 0, 0, 375, 0, 333, 0, 0, 328, 329, + 330, 335, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 119, 0, 0, 0, 265, 0, 0, 373, 0, + 184, 0, 215, 122, 136, 97, 83, 93, 0, 121, + 162, 191, 195, 0, 0, 0, 105, 0, 193, 172, + 231, 0, 174, 192, 140, 221, 185, 230, 240, 241, + 218, 238, 245, 208, 86, 217, 229, 102, 203, 88, + 227, 214, 151, 131, 132, 87, 0, 189, 110, 117, + 107, 164, 224, 225, 106, 248, 94, 237, 90, 95, + 236, 158, 220, 228, 152, 145, 89, 226, 150, 144, + 135, 114, 124, 182, 142, 183, 125, 155, 154, 156, + 0, 0, 0, 212, 234, 249, 99, 0, 219, 243, + 244, 0, 0, 100, 118, 113, 181, 157, 96, 127, + 209, 134, 141, 188, 247, 171, 194, 103, 233, 210, + 363, 374, 369, 370, 367, 368, 366, 365, 364, 376, + 355, 356, 357, 358, 360, 0, 371, 372, 359, 82, + 91, 138, 246, 186, 116, 235, 0, 0, 109, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 84, 85, 92, 98, 104, 108, 112, 115, 120, + 123, 126, 128, 129, 130, 133, 143, 146, 147, 148, + 149, 159, 160, 161, 163, 166, 167, 168, 169, 170, + 173, 175, 176, 177, 178, 179, 180, 187, 190, 196, + 197, 198, 199, 200, 201, 202, 204, 205, 206, 207, + 213, 216, 222, 223, 232, 239, 242, 165, 0, 0, + 0, 0, 322, 0, 0, 0, 111, 0, 319, 0, + 0, 0, 137, 362, 139, 0, 0, 211, 153, 0, + 0, 0, 0, 353, 354, 0, 0, 0, 0, 0, + 0, 0, 0, 54, 0, 0, 320, 341, 340, 343, + 344, 345, 346, 0, 0, 101, 342, 347, 348, 349, + 0, 0, 0, 317, 334, 0, 361, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 331, 332, 0, 0, + 0, 0, 375, 0, 333, 0, 0, 328, 329, 330, + 335, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 119, 0, 0, 0, 265, 0, 0, 373, 0, 184, + 0, 215, 122, 136, 97, 83, 93, 0, 121, 162, + 191, 195, 0, 0, 0, 105, 0, 193, 172, 231, + 0, 174, 192, 140, 221, 185, 230, 240, 241, 218, + 238, 245, 208, 86, 217, 229, 102, 203, 88, 227, + 214, 151, 131, 132, 87, 0, 189, 110, 117, 107, + 164, 224, 225, 106, 248, 94, 237, 90, 95, 236, + 158, 220, 228, 152, 145, 89, 226, 150, 144, 135, + 114, 124, 182, 142, 183, 125, 155, 154, 156, 0, + 0, 0, 212, 234, 249, 99, 0, 219, 243, 244, + 0, 0, 100, 118, 113, 181, 157, 96, 127, 209, + 134, 141, 188, 247, 171, 194, 103, 233, 210, 363, + 374, 369, 370, 367, 368, 366, 365, 364, 376, 355, + 356, 357, 358, 360, 0, 371, 372, 359, 82, 91, + 138, 246, 186, 116, 235, 0, 0, 109, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 84, 85, 92, 98, 104, 108, 112, 115, 120, 123, + 126, 128, 129, 130, 133, 143, 146, 147, 148, 149, + 159, 160, 161, 163, 166, 167, 168, 169, 170, 173, + 175, 176, 177, 178, 179, 180, 187, 190, 196, 197, + 198, 199, 200, 201, 202, 204, 205, 206, 207, 213, + 216, 222, 223, 232, 239, 242, 165, 0, 0, 0, + 0, 0, 0, 0, 0, 111, 0, 0, 0, 0, + 0, 137, 362, 139, 0, 0, 211, 153, 0, 0, + 0, 0, 353, 354, 0, 0, 0, 0, 0, 0, + 0, 0, 54, 0, 0, 320, 341, 340, 343, 344, + 345, 346, 0, 0, 101, 342, 347, 348, 349, 0, + 0, 0, 0, 334, 0, 361, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 331, 332, 0, 0, 0, + 0, 375, 0, 333, 0, 0, 328, 329, 330, 335, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 119, + 0, 0, 0, 265, 0, 0, 373, 0, 184, 0, + 215, 122, 136, 97, 83, 93, 0, 121, 162, 191, + 195, 0, 0, 0, 105, 0, 193, 172, 231, 1508, + 174, 192, 140, 221, 185, 230, 240, 241, 218, 238, + 245, 208, 86, 217, 229, 102, 203, 88, 227, 214, + 151, 131, 132, 87, 0, 189, 110, 117, 107, 164, + 224, 225, 106, 248, 94, 237, 90, 95, 236, 158, + 220, 228, 152, 145, 89, 226, 150, 144, 135, 114, + 124, 182, 142, 183, 125, 155, 154, 156, 0, 0, + 0, 212, 234, 249, 99, 0, 219, 243, 244, 0, + 0, 100, 118, 113, 181, 157, 96, 127, 209, 134, + 141, 188, 247, 171, 194, 103, 233, 210, 363, 374, + 369, 370, 367, 368, 366, 365, 364, 376, 355, 356, + 357, 358, 360, 0, 371, 372, 359, 82, 91, 138, + 246, 186, 116, 235, 0, 0, 109, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 84, + 85, 92, 98, 104, 108, 112, 115, 120, 123, 126, + 128, 129, 130, 133, 143, 146, 147, 148, 149, 159, + 160, 161, 163, 166, 167, 168, 169, 170, 173, 175, + 176, 177, 178, 179, 180, 187, 190, 196, 197, 198, + 199, 200, 201, 202, 204, 205, 206, 207, 213, 216, + 222, 223, 232, 239, 242, 165, 0, 0, 0, 0, + 0, 0, 0, 0, 111, 0, 0, 0, 0, 0, + 137, 362, 139, 0, 0, 211, 153, 0, 0, 0, + 0, 353, 354, 0, 0, 0, 0, 0, 0, 0, + 0, 54, 0, 576, 320, 341, 340, 343, 344, 345, + 346, 0, 0, 101, 342, 347, 348, 349, 0, 0, + 0, 0, 334, 0, 361, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 109, 76, 77, 0, 73, 0, - 0, 0, 78, 146, 0, 163, 111, 119, 83, 90, - 0, 110, 137, 151, 155, 0, 0, 0, 99, 0, - 153, 141, 176, 0, 142, 152, 123, 168, 147, 175, - 183, 184, 165, 182, 186, 157, 84, 164, 174, 97, - 156, 86, 172, 162, 129, 115, 116, 85, 0, 150, - 102, 107, 101, 138, 169, 170, 100, 189, 91, 181, - 88, 92, 180, 136, 167, 173, 130, 127, 87, 171, - 128, 126, 118, 105, 112, 144, 125, 145, 113, 133, - 132, 134, 0, 0, 0, 161, 178, 190, 94, 0, - 166, 185, 0, 0, 95, 108, 104, 143, 135, 93, - 114, 158, 117, 124, 149, 188, 140, 154, 98, 177, - 159, 0, 75, 0, 0, 0, 24, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 139, 0, - 82, 89, 121, 187, 148, 106, 179, 103, 0, 0, - 0, 0, 0, 120, 0, 122, 0, 0, 160, 131, + 0, 0, 0, 0, 331, 332, 0, 0, 0, 0, + 375, 0, 333, 0, 0, 328, 329, 330, 335, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 119, 0, + 0, 0, 265, 0, 0, 373, 0, 184, 0, 215, + 122, 136, 97, 83, 93, 0, 121, 162, 191, 195, + 0, 0, 0, 105, 0, 193, 172, 231, 0, 174, + 192, 140, 221, 185, 230, 240, 241, 218, 238, 245, + 208, 86, 217, 229, 102, 203, 88, 227, 214, 151, + 131, 132, 87, 0, 189, 110, 117, 107, 164, 224, + 225, 106, 248, 94, 237, 90, 95, 236, 158, 220, + 228, 152, 145, 89, 226, 150, 144, 135, 114, 124, + 182, 142, 183, 125, 155, 154, 156, 0, 0, 0, + 212, 234, 249, 99, 0, 219, 243, 244, 0, 0, + 100, 118, 113, 181, 157, 96, 127, 209, 134, 141, + 188, 247, 171, 194, 103, 233, 210, 363, 374, 369, + 370, 367, 368, 366, 365, 364, 376, 355, 356, 357, + 358, 360, 0, 371, 372, 359, 82, 91, 138, 246, + 186, 116, 235, 0, 0, 109, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 54, 0, 0, 80, 0, 0, - 0, 0, 0, 0, 0, 0, 96, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 84, 85, + 92, 98, 104, 108, 112, 115, 120, 123, 126, 128, + 129, 130, 133, 143, 146, 147, 148, 149, 159, 160, + 161, 163, 166, 167, 168, 169, 170, 173, 175, 176, + 177, 178, 179, 180, 187, 190, 196, 197, 198, 199, + 200, 201, 202, 204, 205, 206, 207, 213, 216, 222, + 223, 232, 239, 242, 165, 0, 0, 0, 0, 0, + 0, 0, 0, 111, 0, 0, 0, 0, 0, 137, + 362, 139, 0, 0, 211, 153, 0, 0, 0, 0, + 353, 354, 0, 0, 0, 0, 0, 0, 0, 0, + 54, 0, 0, 320, 341, 340, 343, 344, 345, 346, + 0, 0, 101, 342, 347, 348, 349, 0, 0, 0, + 0, 334, 0, 361, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 331, 332, 0, 0, 0, 0, 375, + 0, 333, 0, 0, 328, 329, 330, 335, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 119, 0, 0, + 0, 265, 0, 0, 373, 0, 184, 0, 215, 122, + 136, 97, 83, 93, 0, 121, 162, 191, 195, 0, + 0, 0, 105, 0, 193, 172, 231, 0, 174, 192, + 140, 221, 185, 230, 240, 241, 218, 238, 245, 208, + 86, 217, 229, 102, 203, 88, 227, 214, 151, 131, + 132, 87, 0, 189, 110, 117, 107, 164, 224, 225, + 106, 248, 94, 237, 90, 95, 236, 158, 220, 228, + 152, 145, 89, 226, 150, 144, 135, 114, 124, 182, + 142, 183, 125, 155, 154, 156, 0, 0, 0, 212, + 234, 249, 99, 0, 219, 243, 244, 0, 0, 100, + 118, 113, 181, 157, 96, 127, 209, 134, 141, 188, + 247, 171, 194, 103, 233, 210, 363, 374, 369, 370, + 367, 368, 366, 365, 364, 376, 355, 356, 357, 358, + 360, 0, 371, 372, 359, 82, 91, 138, 246, 186, + 116, 235, 0, 0, 109, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 84, 85, 92, + 98, 104, 108, 112, 115, 120, 123, 126, 128, 129, + 130, 133, 143, 146, 147, 148, 149, 159, 160, 161, + 163, 166, 167, 168, 169, 170, 173, 175, 176, 177, + 178, 179, 180, 187, 190, 196, 197, 198, 199, 200, + 201, 202, 204, 205, 206, 207, 213, 216, 222, 223, + 232, 239, 242, 165, 0, 0, 0, 0, 0, 0, + 0, 0, 111, 0, 0, 0, 0, 0, 137, 0, + 139, 0, 0, 211, 153, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 80, 0, 0, 0, 0, 0, 0, 0, + 0, 101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 610, 609, + 619, 620, 612, 613, 614, 615, 616, 617, 618, 611, + 0, 0, 621, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 119, 0, 0, 0, + 265, 0, 0, 0, 0, 184, 0, 215, 122, 136, + 97, 83, 93, 0, 121, 162, 191, 195, 0, 0, + 0, 105, 0, 193, 172, 231, 0, 174, 192, 140, + 221, 185, 230, 240, 241, 218, 238, 245, 208, 86, + 217, 229, 102, 203, 88, 227, 214, 151, 131, 132, + 87, 0, 189, 110, 117, 107, 164, 224, 225, 106, + 248, 94, 237, 90, 95, 236, 158, 220, 228, 152, + 145, 89, 226, 150, 144, 135, 114, 124, 182, 142, + 183, 125, 155, 154, 156, 0, 0, 0, 212, 234, + 249, 99, 0, 219, 243, 244, 0, 0, 100, 118, + 113, 181, 157, 96, 127, 209, 134, 141, 188, 247, + 171, 194, 103, 233, 210, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 109, 0, 0, 0, 206, 0, 0, 0, 0, - 146, 0, 163, 111, 119, 83, 90, 0, 110, 137, - 151, 155, 0, 0, 0, 99, 0, 153, 141, 176, - 0, 142, 152, 123, 168, 147, 175, 183, 184, 165, - 182, 186, 157, 84, 164, 174, 97, 156, 86, 172, - 162, 129, 115, 116, 85, 0, 150, 102, 107, 101, - 138, 169, 170, 100, 189, 91, 181, 88, 92, 180, - 136, 167, 173, 130, 127, 87, 171, 128, 126, 118, - 105, 112, 144, 125, 145, 113, 133, 132, 134, 0, - 0, 0, 161, 178, 190, 94, 0, 166, 185, 0, - 0, 95, 108, 104, 143, 135, 93, 114, 158, 117, - 124, 149, 188, 140, 154, 98, 177, 159, 0, 0, - 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 139, 0, 82, 89, 121, - 187, 148, 106, 179, 103, 0, 0, 0, 0, 0, - 120, 0, 122, 0, 0, 160, 131, 0, 0, 0, + 0, 0, 0, 0, 82, 91, 138, 246, 186, 116, + 235, 0, 0, 109, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 54, 0, 0, 204, 0, 0, 0, 0, 0, - 0, 0, 0, 96, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 84, 85, 92, 98, + 104, 108, 112, 115, 120, 123, 126, 128, 129, 130, + 133, 143, 146, 147, 148, 149, 159, 160, 161, 163, + 166, 167, 168, 169, 170, 173, 175, 176, 177, 178, + 179, 180, 187, 190, 196, 197, 198, 199, 200, 201, + 202, 204, 205, 206, 207, 213, 216, 222, 223, 232, + 239, 242, 165, 0, 0, 0, 598, 0, 0, 0, + 0, 111, 0, 0, 0, 0, 0, 137, 0, 139, + 0, 0, 211, 153, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 80, 0, 600, 0, 0, 0, 0, 0, 0, + 101, 0, 0, 0, 0, 0, 595, 594, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 596, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 109, 0, - 0, 0, 206, 0, 0, 0, 0, 146, 0, 163, - 111, 119, 83, 90, 0, 110, 137, 151, 155, 0, - 0, 0, 99, 0, 153, 141, 176, 0, 142, 152, - 123, 168, 147, 175, 183, 184, 165, 182, 186, 157, - 84, 164, 174, 97, 156, 86, 172, 162, 129, 115, - 116, 85, 0, 150, 102, 107, 101, 138, 169, 170, - 100, 189, 91, 181, 88, 92, 180, 136, 167, 173, - 130, 127, 87, 171, 128, 126, 118, 105, 112, 144, - 125, 145, 113, 133, 132, 134, 0, 0, 0, 161, - 178, 190, 94, 0, 166, 185, 0, 0, 95, 108, - 104, 143, 135, 93, 114, 158, 117, 124, 149, 188, - 140, 154, 98, 177, 159, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 119, 0, 0, 0, 265, + 0, 0, 0, 0, 184, 0, 215, 122, 136, 97, + 83, 93, 0, 121, 162, 191, 195, 0, 0, 0, + 105, 0, 193, 172, 231, 0, 174, 192, 140, 221, + 185, 230, 240, 241, 218, 238, 245, 208, 86, 217, + 229, 102, 203, 88, 227, 214, 151, 131, 132, 87, + 0, 189, 110, 117, 107, 164, 224, 225, 106, 248, + 94, 237, 90, 95, 236, 158, 220, 228, 152, 145, + 89, 226, 150, 144, 135, 114, 124, 182, 142, 183, + 125, 155, 154, 156, 0, 0, 0, 212, 234, 249, + 99, 0, 219, 243, 244, 0, 0, 100, 118, 113, + 181, 157, 96, 127, 209, 134, 141, 188, 247, 171, + 194, 103, 233, 210, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 82, 91, 138, 246, 186, 116, 235, + 0, 0, 109, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 84, 85, 92, 98, 104, + 108, 112, 115, 120, 123, 126, 128, 129, 130, 133, + 143, 146, 147, 148, 149, 159, 160, 161, 163, 166, + 167, 168, 169, 170, 173, 175, 176, 177, 178, 179, + 180, 187, 190, 196, 197, 198, 199, 200, 201, 202, + 204, 205, 206, 207, 213, 216, 222, 223, 232, 239, + 242, 165, 0, 0, 0, 0, 0, 0, 0, 0, + 111, 0, 0, 0, 0, 0, 137, 0, 139, 0, + 0, 211, 153, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 80, 0, 0, 0, 0, 0, 0, 0, 0, 101, + 0, 0, 0, 0, 0, 74, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 82, 89, 121, 187, 148, 106, - 179, 139, 0, 0, 0, 844, 0, 0, 0, 0, - 103, 0, 0, 0, 0, 0, 120, 0, 122, 0, - 0, 160, 131, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 204, 0, 846, 0, 0, 0, 0, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 119, 76, 77, 0, 73, 0, + 0, 0, 78, 184, 0, 215, 122, 136, 97, 83, + 93, 0, 121, 162, 191, 195, 0, 0, 0, 105, + 0, 193, 172, 231, 0, 174, 192, 140, 221, 185, + 230, 240, 241, 218, 238, 245, 208, 86, 217, 229, + 102, 203, 88, 227, 214, 151, 131, 132, 87, 0, + 189, 110, 117, 107, 164, 224, 225, 106, 248, 94, + 237, 90, 95, 236, 158, 220, 228, 152, 145, 89, + 226, 150, 144, 135, 114, 124, 182, 142, 183, 125, + 155, 154, 156, 0, 0, 0, 212, 234, 249, 99, + 0, 219, 243, 244, 0, 0, 100, 118, 113, 181, + 157, 96, 127, 209, 134, 141, 188, 247, 171, 194, + 103, 233, 210, 0, 75, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 82, 91, 138, 246, 186, 116, 235, 0, + 0, 109, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 84, 85, 92, 98, 104, 108, + 112, 115, 120, 123, 126, 128, 129, 130, 133, 143, + 146, 147, 148, 149, 159, 160, 161, 163, 166, 167, + 168, 169, 170, 173, 175, 176, 177, 178, 179, 180, + 187, 190, 196, 197, 198, 199, 200, 201, 202, 204, + 205, 206, 207, 213, 216, 222, 223, 232, 239, 242, + 165, 0, 0, 0, 929, 0, 0, 0, 0, 111, + 0, 0, 0, 0, 0, 137, 0, 139, 0, 0, + 211, 153, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 263, + 0, 931, 0, 0, 0, 0, 0, 0, 101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 109, 0, 0, 0, 206, 0, - 0, 0, 0, 146, 0, 163, 111, 119, 83, 90, - 0, 110, 137, 151, 155, 0, 0, 0, 99, 0, - 153, 141, 176, 0, 842, 152, 123, 168, 147, 175, - 183, 184, 165, 182, 186, 157, 84, 164, 174, 97, - 156, 86, 172, 162, 129, 115, 116, 85, 0, 150, - 102, 107, 101, 138, 169, 170, 100, 189, 91, 181, - 88, 92, 180, 136, 167, 173, 130, 127, 87, 171, - 128, 126, 118, 105, 112, 144, 125, 145, 113, 133, - 132, 134, 0, 0, 0, 161, 178, 190, 94, 0, - 166, 185, 0, 0, 95, 108, 104, 143, 135, 93, - 114, 158, 117, 124, 149, 188, 140, 154, 98, 177, - 159, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 139, 0, - 82, 89, 121, 187, 148, 106, 179, 103, 0, 0, - 0, 0, 0, 120, 0, 122, 0, 0, 160, 131, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 80, 0, 0, - 739, 0, 0, 740, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 119, 0, 0, 0, 265, 0, 0, + 0, 0, 184, 0, 215, 122, 136, 97, 83, 93, + 0, 121, 162, 191, 195, 0, 0, 0, 105, 0, + 193, 172, 231, 0, 174, 192, 140, 221, 185, 230, + 240, 241, 218, 238, 245, 208, 86, 217, 229, 102, + 203, 88, 227, 214, 151, 131, 132, 87, 0, 189, + 110, 117, 107, 164, 224, 225, 106, 248, 94, 237, + 90, 95, 236, 158, 220, 228, 152, 145, 89, 226, + 150, 144, 135, 114, 124, 182, 142, 183, 125, 155, + 154, 156, 0, 0, 0, 212, 234, 249, 99, 0, + 219, 243, 244, 0, 0, 100, 118, 113, 181, 157, + 96, 127, 209, 134, 141, 188, 247, 171, 194, 103, + 233, 210, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 82, 91, 138, 246, 186, 116, 235, 0, 0, + 109, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 84, 85, 92, 98, 104, 108, 112, + 115, 120, 123, 126, 128, 129, 130, 133, 143, 146, + 147, 148, 149, 159, 160, 161, 163, 166, 167, 168, + 169, 170, 173, 175, 176, 177, 178, 179, 180, 187, + 190, 196, 197, 198, 199, 200, 201, 202, 204, 205, + 206, 207, 213, 216, 222, 223, 232, 239, 242, 24, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 165, 0, 0, 0, 0, 0, 0, 0, 0, + 111, 0, 0, 0, 0, 0, 137, 0, 139, 0, + 0, 211, 153, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, + 80, 0, 0, 0, 0, 0, 0, 0, 0, 101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 109, 0, 0, 0, 206, 0, 0, 0, 0, - 146, 0, 163, 111, 119, 83, 90, 0, 110, 137, - 151, 155, 0, 0, 0, 99, 0, 153, 141, 176, - 0, 142, 152, 123, 168, 147, 175, 183, 184, 165, - 182, 186, 157, 84, 164, 174, 97, 156, 86, 172, - 162, 129, 115, 116, 85, 0, 150, 102, 107, 101, - 138, 169, 170, 100, 189, 91, 181, 88, 92, 180, - 136, 167, 173, 130, 127, 87, 171, 128, 126, 118, - 105, 112, 144, 125, 145, 113, 133, 132, 134, 0, - 0, 0, 161, 178, 190, 94, 0, 166, 185, 0, - 0, 95, 108, 104, 143, 135, 93, 114, 158, 117, - 124, 149, 188, 140, 154, 98, 177, 159, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 139, 0, 82, 89, 121, - 187, 148, 106, 179, 103, 0, 629, 0, 0, 0, - 120, 0, 122, 0, 0, 160, 131, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 80, 0, 628, 0, 0, 0, - 0, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 119, 0, 0, 0, 265, 0, + 0, 0, 0, 184, 0, 215, 122, 136, 97, 83, + 93, 0, 121, 162, 191, 195, 0, 0, 0, 105, + 0, 193, 172, 231, 0, 174, 192, 140, 221, 185, + 230, 240, 241, 218, 238, 245, 208, 86, 217, 229, + 102, 203, 88, 227, 214, 151, 131, 132, 87, 0, + 189, 110, 117, 107, 164, 224, 225, 106, 248, 94, + 237, 90, 95, 236, 158, 220, 228, 152, 145, 89, + 226, 150, 144, 135, 114, 124, 182, 142, 183, 125, + 155, 154, 156, 0, 0, 0, 212, 234, 249, 99, + 0, 219, 243, 244, 0, 0, 100, 118, 113, 181, + 157, 96, 127, 209, 134, 141, 188, 247, 171, 194, + 103, 233, 210, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 82, 91, 138, 246, 186, 116, 235, 0, + 0, 109, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 109, 0, - 0, 0, 206, 0, 0, 0, 0, 146, 0, 163, - 111, 119, 83, 90, 0, 110, 137, 151, 155, 0, - 0, 0, 99, 0, 153, 141, 176, 0, 142, 152, - 123, 168, 147, 175, 183, 184, 165, 182, 186, 157, - 84, 164, 174, 97, 156, 86, 172, 162, 129, 115, - 116, 85, 0, 150, 102, 107, 101, 138, 169, 170, - 100, 189, 91, 181, 88, 92, 180, 136, 167, 173, - 130, 127, 87, 171, 128, 126, 118, 105, 112, 144, - 125, 145, 113, 133, 132, 134, 0, 0, 0, 161, - 178, 190, 94, 0, 166, 185, 0, 0, 95, 108, - 104, 143, 135, 93, 114, 158, 117, 124, 149, 188, - 140, 154, 98, 177, 159, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 139, 0, 82, 89, 121, 187, 148, 106, - 179, 103, 0, 0, 0, 0, 0, 120, 0, 122, - 0, 0, 160, 131, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 84, 85, 92, 98, 104, 108, + 112, 115, 120, 123, 126, 128, 129, 130, 133, 143, + 146, 147, 148, 149, 159, 160, 161, 163, 166, 167, + 168, 169, 170, 173, 175, 176, 177, 178, 179, 180, + 187, 190, 196, 197, 198, 199, 200, 201, 202, 204, + 205, 206, 207, 213, 216, 222, 223, 232, 239, 242, + 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 165, 0, 0, 0, 0, 0, 0, 0, + 0, 111, 0, 0, 0, 0, 0, 137, 0, 139, + 0, 0, 211, 153, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, - 0, 204, 0, 0, 0, 0, 0, 0, 0, 0, - 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 263, 0, 0, 0, 0, 0, 0, 0, 0, + 101, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 119, 0, 0, 0, 265, + 0, 0, 0, 0, 184, 0, 215, 122, 136, 97, + 83, 93, 0, 121, 162, 191, 195, 0, 0, 0, + 105, 0, 193, 172, 231, 0, 174, 192, 140, 221, + 185, 230, 240, 241, 218, 238, 245, 208, 86, 217, + 229, 102, 203, 88, 227, 214, 151, 131, 132, 87, + 0, 189, 110, 117, 107, 164, 224, 225, 106, 248, + 94, 237, 90, 95, 236, 158, 220, 228, 152, 145, + 89, 226, 150, 144, 135, 114, 124, 182, 142, 183, + 125, 155, 154, 156, 0, 0, 0, 212, 234, 249, + 99, 0, 219, 243, 244, 0, 0, 100, 118, 113, + 181, 157, 96, 127, 209, 134, 141, 188, 247, 171, + 194, 103, 233, 210, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 82, 91, 138, 246, 186, 116, 235, + 0, 0, 109, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 84, 85, 92, 98, 104, + 108, 112, 115, 120, 123, 126, 128, 129, 130, 133, + 143, 146, 147, 148, 149, 159, 160, 161, 163, 166, + 167, 168, 169, 170, 173, 175, 176, 177, 178, 179, + 180, 187, 190, 196, 197, 198, 199, 200, 201, 202, + 204, 205, 206, 207, 213, 216, 222, 223, 232, 239, + 242, 165, 0, 0, 0, 929, 0, 0, 0, 0, + 111, 0, 0, 0, 0, 0, 137, 0, 139, 0, + 0, 211, 153, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 263, 0, 931, 0, 0, 0, 0, 0, 0, 101, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 119, 0, 0, 0, 265, 0, + 0, 0, 0, 184, 0, 215, 122, 136, 97, 83, + 93, 0, 121, 162, 191, 195, 0, 0, 0, 105, + 0, 193, 172, 231, 0, 927, 192, 140, 221, 185, + 230, 240, 241, 218, 238, 245, 208, 86, 217, 229, + 102, 203, 88, 227, 214, 151, 131, 132, 87, 0, + 189, 110, 117, 107, 164, 224, 225, 106, 248, 94, + 237, 90, 95, 236, 158, 220, 228, 152, 145, 89, + 226, 150, 144, 135, 114, 124, 182, 142, 183, 125, + 155, 154, 156, 0, 0, 0, 212, 234, 249, 99, + 0, 219, 243, 244, 0, 0, 100, 118, 113, 181, + 157, 96, 127, 209, 134, 141, 188, 247, 171, 194, + 103, 233, 210, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 82, 91, 138, 246, 186, 116, 235, 0, + 0, 109, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 84, 85, 92, 98, 104, 108, + 112, 115, 120, 123, 126, 128, 129, 130, 133, 143, + 146, 147, 148, 149, 159, 160, 161, 163, 166, 167, + 168, 169, 170, 173, 175, 176, 177, 178, 179, 180, + 187, 190, 196, 197, 198, 199, 200, 201, 202, 204, + 205, 206, 207, 213, 216, 222, 223, 232, 239, 242, + 165, 0, 0, 0, 0, 0, 0, 0, 0, 111, + 0, 0, 0, 0, 0, 137, 0, 139, 0, 0, + 211, 153, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, + 0, 0, 824, 0, 0, 825, 0, 0, 101, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 119, 0, 0, 0, 265, 0, 0, + 0, 0, 184, 0, 215, 122, 136, 97, 83, 93, + 0, 121, 162, 191, 195, 0, 0, 0, 105, 0, + 193, 172, 231, 0, 174, 192, 140, 221, 185, 230, + 240, 241, 218, 238, 245, 208, 86, 217, 229, 102, + 203, 88, 227, 214, 151, 131, 132, 87, 0, 189, + 110, 117, 107, 164, 224, 225, 106, 248, 94, 237, + 90, 95, 236, 158, 220, 228, 152, 145, 89, 226, + 150, 144, 135, 114, 124, 182, 142, 183, 125, 155, + 154, 156, 0, 0, 0, 212, 234, 249, 99, 0, + 219, 243, 244, 0, 0, 100, 118, 113, 181, 157, + 96, 127, 209, 134, 141, 188, 247, 171, 194, 103, + 233, 210, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 82, 91, 138, 246, 186, 116, 235, 0, 0, + 109, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 84, 85, 92, 98, 104, 108, 112, + 115, 120, 123, 126, 128, 129, 130, 133, 143, 146, + 147, 148, 149, 159, 160, 161, 163, 166, 167, 168, + 169, 170, 173, 175, 176, 177, 178, 179, 180, 187, + 190, 196, 197, 198, 199, 200, 201, 202, 204, 205, + 206, 207, 213, 216, 222, 223, 232, 239, 242, 165, + 0, 0, 0, 0, 0, 0, 0, 0, 111, 0, + 712, 0, 0, 0, 137, 0, 139, 0, 0, 211, + 153, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 80, 0, + 711, 0, 0, 0, 0, 0, 0, 101, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 119, 0, 0, 0, 265, 0, 0, 0, + 0, 184, 0, 215, 122, 136, 97, 83, 93, 0, + 121, 162, 191, 195, 0, 0, 0, 105, 0, 193, + 172, 231, 0, 174, 192, 140, 221, 185, 230, 240, + 241, 218, 238, 245, 208, 86, 217, 229, 102, 203, + 88, 227, 214, 151, 131, 132, 87, 0, 189, 110, + 117, 107, 164, 224, 225, 106, 248, 94, 237, 90, + 95, 236, 158, 220, 228, 152, 145, 89, 226, 150, + 144, 135, 114, 124, 182, 142, 183, 125, 155, 154, + 156, 0, 0, 0, 212, 234, 249, 99, 0, 219, + 243, 244, 0, 0, 100, 118, 113, 181, 157, 96, + 127, 209, 134, 141, 188, 247, 171, 194, 103, 233, + 210, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 82, 91, 138, 246, 186, 116, 235, 0, 0, 109, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 109, 0, 0, 0, 206, - 0, 0, 0, 0, 146, 0, 163, 111, 119, 83, - 90, 0, 110, 137, 151, 155, 0, 0, 0, 99, - 0, 153, 141, 176, 0, 142, 152, 123, 168, 147, - 175, 183, 184, 165, 182, 186, 157, 84, 164, 174, - 97, 156, 86, 172, 162, 129, 115, 116, 85, 0, - 150, 102, 107, 101, 138, 169, 170, 100, 189, 91, - 181, 88, 92, 180, 136, 167, 173, 130, 127, 87, - 171, 128, 126, 118, 105, 112, 144, 125, 145, 113, - 133, 132, 134, 0, 0, 0, 161, 178, 190, 94, - 0, 166, 185, 0, 0, 95, 108, 104, 143, 135, - 93, 114, 158, 117, 124, 149, 188, 140, 154, 98, - 177, 159, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 139, - 0, 82, 89, 121, 187, 148, 106, 179, 103, 0, - 0, 0, 0, 0, 120, 0, 122, 0, 0, 160, - 131, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 204, 0, - 846, 0, 0, 0, 0, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 84, 85, 92, 98, 104, 108, 112, 115, + 120, 123, 126, 128, 129, 130, 133, 143, 146, 147, + 148, 149, 159, 160, 161, 163, 166, 167, 168, 169, + 170, 173, 175, 176, 177, 178, 179, 180, 187, 190, + 196, 197, 198, 199, 200, 201, 202, 204, 205, 206, + 207, 213, 216, 222, 223, 232, 239, 242, 165, 0, + 0, 0, 0, 0, 0, 0, 0, 111, 0, 0, + 0, 0, 0, 137, 0, 139, 0, 0, 211, 153, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 54, 0, 0, 263, 0, 0, + 0, 0, 0, 0, 0, 0, 101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 109, 0, 0, 0, 206, 0, 0, 0, - 0, 146, 0, 163, 111, 119, 83, 90, 0, 110, - 137, 151, 155, 0, 0, 0, 99, 0, 153, 141, - 176, 0, 142, 152, 123, 168, 147, 175, 183, 184, - 165, 182, 186, 157, 84, 164, 174, 97, 156, 86, - 172, 162, 129, 115, 116, 85, 0, 150, 102, 107, - 101, 138, 169, 170, 100, 189, 91, 181, 88, 92, - 180, 136, 167, 173, 130, 127, 87, 171, 128, 126, - 118, 105, 112, 144, 125, 145, 113, 133, 132, 134, - 0, 0, 0, 161, 178, 190, 94, 0, 166, 185, - 0, 0, 95, 108, 104, 143, 135, 93, 114, 158, - 117, 124, 149, 188, 140, 154, 98, 177, 159, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 139, 0, 82, 89, - 121, 187, 148, 106, 179, 103, 0, 0, 0, 0, - 0, 120, 0, 122, 0, 0, 160, 131, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 80, 0, 517, 0, 0, - 0, 0, 0, 0, 96, 0, 0, 0, 0, 0, + 0, 119, 0, 0, 0, 265, 0, 0, 0, 0, + 184, 0, 215, 122, 136, 97, 83, 93, 0, 121, + 162, 191, 195, 0, 0, 0, 105, 0, 193, 172, + 231, 0, 174, 192, 140, 221, 185, 230, 240, 241, + 218, 238, 245, 208, 86, 217, 229, 102, 203, 88, + 227, 214, 151, 131, 132, 87, 0, 189, 110, 117, + 107, 164, 224, 225, 106, 248, 94, 237, 90, 95, + 236, 158, 220, 228, 152, 145, 89, 226, 150, 144, + 135, 114, 124, 182, 142, 183, 125, 155, 154, 156, + 0, 0, 0, 212, 234, 249, 99, 0, 219, 243, + 244, 0, 0, 100, 118, 113, 181, 157, 96, 127, + 209, 134, 141, 188, 247, 171, 194, 103, 233, 210, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, + 91, 138, 246, 186, 116, 235, 0, 0, 109, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 84, 85, 92, 98, 104, 108, 112, 115, 120, + 123, 126, 128, 129, 130, 133, 143, 146, 147, 148, + 149, 159, 160, 161, 163, 166, 167, 168, 169, 170, + 173, 175, 176, 177, 178, 179, 180, 187, 190, 196, + 197, 198, 199, 200, 201, 202, 204, 205, 206, 207, + 213, 216, 222, 223, 232, 239, 242, 165, 0, 0, + 0, 0, 0, 0, 0, 0, 111, 0, 0, 0, + 0, 0, 137, 0, 139, 0, 0, 211, 153, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, - 0, 0, 0, 206, 0, 0, 0, 0, 146, 0, - 163, 111, 119, 83, 90, 0, 110, 137, 151, 155, - 0, 0, 0, 99, 0, 153, 141, 176, 0, 142, - 152, 123, 168, 147, 175, 183, 184, 165, 182, 186, - 157, 84, 164, 174, 97, 156, 86, 172, 162, 129, - 115, 116, 85, 0, 150, 102, 107, 101, 138, 169, - 170, 100, 189, 91, 181, 88, 92, 180, 136, 167, - 173, 130, 127, 87, 171, 128, 126, 118, 105, 112, - 144, 125, 145, 113, 133, 132, 134, 0, 0, 0, - 161, 178, 190, 94, 0, 166, 185, 0, 0, 95, - 108, 104, 143, 135, 93, 114, 158, 117, 124, 149, - 188, 140, 154, 98, 177, 159, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 263, 0, 931, 0, + 0, 0, 0, 0, 0, 101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 139, 82, 89, 121, 187, 148, - 106, 179, 599, 103, 0, 0, 0, 0, 0, 120, - 0, 122, 0, 0, 160, 131, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 204, 0, 0, 0, 0, 0, 0, - 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 119, 0, 0, 0, 265, 0, 0, 0, 0, 184, + 0, 215, 122, 136, 97, 83, 93, 0, 121, 162, + 191, 195, 0, 0, 0, 105, 0, 193, 172, 231, + 0, 174, 192, 140, 221, 185, 230, 240, 241, 218, + 238, 245, 208, 86, 217, 229, 102, 203, 88, 227, + 214, 151, 131, 132, 87, 0, 189, 110, 117, 107, + 164, 224, 225, 106, 248, 94, 237, 90, 95, 236, + 158, 220, 228, 152, 145, 89, 226, 150, 144, 135, + 114, 124, 182, 142, 183, 125, 155, 154, 156, 0, + 0, 0, 212, 234, 249, 99, 0, 219, 243, 244, + 0, 0, 100, 118, 113, 181, 157, 96, 127, 209, + 134, 141, 188, 247, 171, 194, 103, 233, 210, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 109, 0, 0, - 0, 206, 0, 0, 0, 0, 146, 0, 163, 111, - 119, 83, 90, 0, 110, 137, 151, 155, 0, 0, - 0, 99, 0, 153, 141, 176, 0, 142, 152, 123, - 168, 147, 175, 183, 184, 165, 182, 186, 157, 84, - 164, 174, 97, 156, 86, 172, 162, 129, 115, 116, - 85, 0, 150, 102, 107, 101, 138, 169, 170, 100, - 189, 91, 181, 88, 92, 180, 136, 167, 173, 130, - 127, 87, 171, 128, 126, 118, 105, 112, 144, 125, - 145, 113, 133, 132, 134, 0, 0, 0, 161, 178, - 190, 94, 0, 166, 185, 0, 0, 95, 108, 104, - 143, 135, 93, 114, 158, 117, 124, 149, 188, 140, - 154, 98, 177, 159, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 319, 0, 0, 0, 0, 0, - 0, 139, 0, 82, 89, 121, 187, 148, 106, 179, - 103, 0, 0, 0, 0, 0, 120, 0, 122, 0, - 0, 160, 131, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 82, 91, + 138, 246, 186, 116, 235, 0, 0, 109, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 204, 0, 0, 0, 0, 0, 0, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 84, 85, 92, 98, 104, 108, 112, 115, 120, 123, + 126, 128, 129, 130, 133, 143, 146, 147, 148, 149, + 159, 160, 161, 163, 166, 167, 168, 169, 170, 173, + 175, 176, 177, 178, 179, 180, 187, 190, 196, 197, + 198, 199, 200, 201, 202, 204, 205, 206, 207, 213, + 216, 222, 223, 232, 239, 242, 165, 0, 0, 0, + 0, 0, 0, 0, 0, 111, 0, 0, 0, 0, + 0, 137, 0, 139, 0, 0, 211, 153, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 80, 0, 600, 0, 0, + 0, 0, 0, 0, 101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 109, 0, 0, 0, 206, 0, - 0, 0, 0, 146, 0, 163, 111, 119, 83, 90, - 0, 110, 137, 151, 155, 0, 0, 0, 99, 0, - 153, 141, 176, 0, 142, 152, 123, 168, 147, 175, - 183, 184, 165, 182, 186, 157, 84, 164, 174, 97, - 156, 86, 172, 162, 129, 115, 116, 85, 0, 150, - 102, 107, 101, 138, 169, 170, 100, 189, 91, 181, - 88, 92, 180, 136, 167, 173, 130, 127, 87, 171, - 128, 126, 118, 105, 112, 144, 125, 145, 113, 133, - 132, 134, 0, 0, 0, 161, 178, 190, 94, 0, - 166, 185, 0, 0, 95, 108, 104, 143, 135, 93, - 114, 158, 117, 124, 149, 188, 140, 154, 98, 177, - 159, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 139, 0, - 82, 89, 121, 187, 148, 106, 179, 103, 0, 0, - 0, 0, 0, 120, 0, 122, 0, 0, 160, 131, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 204, 0, 0, - 0, 0, 0, 0, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 119, + 0, 0, 0, 265, 0, 0, 0, 0, 184, 0, + 215, 122, 136, 97, 83, 93, 0, 121, 162, 191, + 195, 0, 0, 0, 105, 0, 193, 172, 231, 0, + 174, 192, 140, 221, 185, 230, 240, 241, 218, 238, + 245, 208, 86, 217, 229, 102, 203, 88, 227, 214, + 151, 131, 132, 87, 0, 189, 110, 117, 107, 164, + 224, 225, 106, 248, 94, 237, 90, 95, 236, 158, + 220, 228, 152, 145, 89, 226, 150, 144, 135, 114, + 124, 182, 142, 183, 125, 155, 154, 156, 0, 0, + 0, 212, 234, 249, 99, 0, 219, 243, 244, 0, + 0, 100, 118, 113, 181, 157, 96, 127, 209, 134, + 141, 188, 247, 171, 194, 103, 233, 210, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 82, 91, 138, + 246, 186, 116, 235, 0, 0, 109, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 84, + 85, 92, 98, 104, 108, 112, 115, 120, 123, 126, + 128, 129, 130, 133, 143, 146, 147, 148, 149, 159, + 160, 161, 163, 166, 167, 168, 169, 170, 173, 175, + 176, 177, 178, 179, 180, 187, 190, 196, 197, 198, + 199, 200, 201, 202, 204, 205, 206, 207, 213, 216, + 222, 223, 232, 239, 242, 165, 0, 0, 0, 0, + 0, 0, 0, 682, 111, 0, 0, 0, 0, 0, + 137, 0, 139, 0, 0, 211, 153, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 263, 0, 0, 0, 0, 0, + 0, 0, 0, 101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 109, 0, 201, 0, 206, 0, 0, 0, 0, - 146, 0, 163, 111, 119, 83, 90, 0, 110, 137, - 151, 155, 0, 0, 0, 99, 0, 153, 141, 176, - 0, 142, 152, 123, 168, 147, 175, 183, 184, 165, - 182, 186, 157, 84, 164, 174, 97, 156, 86, 172, - 162, 129, 115, 116, 85, 0, 150, 102, 107, 101, - 138, 169, 170, 100, 189, 91, 181, 88, 92, 180, - 136, 167, 173, 130, 127, 87, 171, 128, 126, 118, - 105, 112, 144, 125, 145, 113, 133, 132, 134, 0, - 0, 0, 161, 178, 190, 94, 0, 166, 185, 0, - 0, 95, 108, 104, 143, 135, 93, 114, 158, 117, - 124, 149, 188, 140, 154, 98, 177, 159, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 139, 0, 82, 89, 121, - 187, 148, 106, 179, 103, 0, 0, 0, 0, 0, - 120, 0, 122, 0, 0, 160, 131, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 80, 0, 0, 0, 0, 0, - 0, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 119, 0, + 0, 0, 265, 0, 0, 0, 0, 184, 0, 215, + 122, 136, 97, 83, 93, 0, 121, 162, 191, 195, + 0, 0, 0, 105, 0, 193, 172, 231, 0, 174, + 192, 140, 221, 185, 230, 240, 241, 218, 238, 245, + 208, 86, 217, 229, 102, 203, 88, 227, 214, 151, + 131, 132, 87, 0, 189, 110, 117, 107, 164, 224, + 225, 106, 248, 94, 237, 90, 95, 236, 158, 220, + 228, 152, 145, 89, 226, 150, 144, 135, 114, 124, + 182, 142, 183, 125, 155, 154, 156, 0, 0, 0, + 212, 234, 249, 99, 0, 219, 243, 244, 0, 0, + 100, 118, 113, 181, 157, 96, 127, 209, 134, 141, + 188, 247, 171, 194, 103, 233, 210, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 82, 91, 138, 246, + 186, 116, 235, 0, 0, 109, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 109, 0, - 0, 0, 206, 0, 0, 0, 0, 146, 0, 163, - 111, 119, 83, 90, 0, 110, 137, 151, 155, 0, - 0, 0, 99, 0, 153, 141, 176, 0, 142, 152, - 123, 168, 147, 175, 183, 184, 165, 182, 186, 157, - 84, 164, 174, 97, 156, 86, 172, 162, 129, 115, - 116, 85, 0, 150, 102, 107, 101, 138, 169, 170, - 100, 189, 91, 181, 88, 92, 180, 136, 167, 173, - 130, 127, 87, 171, 128, 126, 118, 105, 112, 144, - 125, 145, 113, 133, 132, 134, 0, 0, 0, 161, - 178, 190, 94, 0, 166, 185, 0, 0, 95, 108, - 104, 143, 135, 93, 114, 158, 117, 124, 149, 188, - 140, 154, 98, 177, 159, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 139, 0, 82, 89, 121, 187, 148, 106, - 179, 103, 0, 0, 0, 0, 0, 120, 0, 122, - 0, 0, 160, 131, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 84, 85, + 92, 98, 104, 108, 112, 115, 120, 123, 126, 128, + 129, 130, 133, 143, 146, 147, 148, 149, 159, 160, + 161, 163, 166, 167, 168, 169, 170, 173, 175, 176, + 177, 178, 179, 180, 187, 190, 196, 197, 198, 199, + 200, 201, 202, 204, 205, 206, 207, 213, 216, 222, + 223, 232, 239, 242, 379, 0, 0, 0, 0, 0, + 0, 165, 0, 0, 0, 0, 0, 0, 0, 0, + 111, 0, 0, 0, 0, 0, 137, 0, 139, 0, + 0, 211, 153, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 204, 0, 0, 0, 0, 0, 0, 0, 0, - 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 263, 0, 0, 0, 0, 0, 0, 0, 0, 101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 109, 0, 0, 0, 206, - 0, 0, 0, 0, 146, 0, 163, 111, 119, 83, - 90, 0, 110, 137, 151, 155, 0, 0, 0, 99, - 0, 153, 141, 176, 0, 142, 152, 123, 168, 147, - 175, 183, 184, 165, 182, 186, 157, 84, 164, 174, - 97, 156, 86, 172, 162, 129, 115, 116, 85, 0, - 150, 102, 107, 101, 138, 169, 170, 100, 189, 91, - 181, 88, 92, 180, 136, 167, 173, 130, 127, 87, - 171, 128, 126, 118, 105, 112, 144, 125, 145, 113, - 133, 132, 134, 0, 0, 0, 161, 178, 190, 94, - 0, 166, 185, 0, 0, 95, 108, 104, 143, 135, - 93, 114, 158, 117, 124, 149, 188, 140, 154, 98, - 177, 159, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 139, - 0, 82, 89, 121, 187, 148, 106, 179, 103, 0, - 0, 0, 0, 0, 120, 0, 122, 0, 0, 160, - 131, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 260, 0, - 0, 0, 0, 0, 0, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 119, 0, 0, 0, 265, 0, + 0, 0, 0, 184, 0, 215, 122, 136, 97, 83, + 93, 0, 121, 162, 191, 195, 0, 0, 0, 105, + 0, 193, 172, 231, 0, 174, 192, 140, 221, 185, + 230, 240, 241, 218, 238, 245, 208, 86, 217, 229, + 102, 203, 88, 227, 214, 151, 131, 132, 87, 0, + 189, 110, 117, 107, 164, 224, 225, 106, 248, 94, + 237, 90, 95, 236, 158, 220, 228, 152, 145, 89, + 226, 150, 144, 135, 114, 124, 182, 142, 183, 125, + 155, 154, 156, 0, 0, 0, 212, 234, 249, 99, + 0, 219, 243, 244, 0, 0, 100, 118, 113, 181, + 157, 96, 127, 209, 134, 141, 188, 247, 171, 194, + 103, 233, 210, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 82, 91, 138, 246, 186, 116, 235, 0, + 0, 109, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 84, 85, 92, 98, 104, 108, + 112, 115, 120, 123, 126, 128, 129, 130, 133, 143, + 146, 147, 148, 149, 159, 160, 161, 163, 166, 167, + 168, 169, 170, 173, 175, 176, 177, 178, 179, 180, + 187, 190, 196, 197, 198, 199, 200, 201, 202, 204, + 205, 206, 207, 213, 216, 222, 223, 232, 239, 242, + 165, 0, 0, 0, 0, 0, 0, 0, 0, 111, + 0, 0, 0, 0, 0, 137, 0, 139, 0, 0, + 211, 153, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 263, + 0, 0, 0, 0, 0, 0, 0, 0, 101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 109, 0, 0, 0, 206, 0, 0, 0, - 0, 146, 655, 163, 111, 119, 83, 90, 0, 110, - 137, 151, 155, 0, 0, 0, 99, 0, 153, 141, - 176, 0, 142, 152, 123, 168, 147, 175, 183, 184, - 165, 182, 186, 157, 84, 164, 174, 97, 156, 86, - 172, 162, 129, 115, 116, 85, 0, 150, 102, 107, - 101, 138, 169, 170, 100, 189, 91, 181, 88, 92, - 180, 136, 167, 173, 130, 127, 87, 171, 128, 126, - 118, 105, 112, 144, 125, 145, 113, 133, 132, 134, - 643, 0, 0, 161, 178, 190, 94, 0, 166, 185, - 0, 0, 95, 108, 104, 143, 135, 93, 114, 158, - 117, 124, 149, 188, 140, 154, 98, 177, 159, 0, - 0, 0, 0, 0, 0, 0, 0, 656, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 82, 89, - 121, 187, 148, 106, 179, 0, 0, 0, 0, 0, - 669, 672, 673, 674, 675, 676, 677, 0, 678, 679, - 680, 681, 682, 657, 658, 659, 660, 641, 642, 670, - 0, 644, 0, 645, 646, 647, 648, 649, 650, 651, - 652, 653, 654, 661, 662, 663, 664, 665, 666, 667, - 668, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 119, 0, 260, 0, 265, 0, 0, + 0, 0, 184, 0, 215, 122, 136, 97, 83, 93, + 0, 121, 162, 191, 195, 0, 0, 0, 105, 0, + 193, 172, 231, 0, 174, 192, 140, 221, 185, 230, + 240, 241, 218, 238, 245, 208, 86, 217, 229, 102, + 203, 88, 227, 214, 151, 131, 132, 87, 0, 189, + 110, 117, 107, 164, 224, 225, 106, 248, 94, 237, + 90, 95, 236, 158, 220, 228, 152, 145, 89, 226, + 150, 144, 135, 114, 124, 182, 142, 183, 125, 155, + 154, 156, 0, 0, 0, 212, 234, 249, 99, 0, + 219, 243, 244, 0, 0, 100, 118, 113, 181, 157, + 96, 127, 209, 134, 141, 188, 247, 171, 194, 103, + 233, 210, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 671, + 0, 82, 91, 138, 246, 186, 116, 235, 0, 0, + 109, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 84, 85, 92, 98, 104, 108, 112, + 115, 120, 123, 126, 128, 129, 130, 133, 143, 146, + 147, 148, 149, 159, 160, 161, 163, 166, 167, 168, + 169, 170, 173, 175, 176, 177, 178, 179, 180, 187, + 190, 196, 197, 198, 199, 200, 201, 202, 204, 205, + 206, 207, 213, 216, 222, 223, 232, 239, 242, 165, + 0, 0, 0, 0, 0, 0, 0, 0, 111, 0, + 0, 0, 0, 0, 137, 0, 139, 0, 0, 211, + 153, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 80, 0, + 0, 0, 0, 0, 0, 0, 0, 101, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 119, 0, 0, 0, 265, 0, 0, 0, + 0, 184, 0, 215, 122, 136, 97, 83, 93, 0, + 121, 162, 191, 195, 0, 0, 0, 105, 0, 193, + 172, 231, 0, 174, 192, 140, 221, 185, 230, 240, + 241, 218, 238, 245, 208, 86, 217, 229, 102, 203, + 88, 227, 214, 151, 131, 132, 87, 0, 189, 110, + 117, 107, 164, 224, 225, 106, 248, 94, 237, 90, + 95, 236, 158, 220, 228, 152, 145, 89, 226, 150, + 144, 135, 114, 124, 182, 142, 183, 125, 155, 154, + 156, 0, 0, 0, 212, 234, 249, 99, 0, 219, + 243, 244, 0, 0, 100, 118, 113, 181, 157, 96, + 127, 209, 134, 141, 188, 247, 171, 194, 103, 233, + 210, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 82, 91, 138, 246, 186, 116, 235, 0, 0, 109, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 84, 85, 92, 98, 104, 108, 112, 115, + 120, 123, 126, 128, 129, 130, 133, 143, 146, 147, + 148, 149, 159, 160, 161, 163, 166, 167, 168, 169, + 170, 173, 175, 176, 177, 178, 179, 180, 187, 190, + 196, 197, 198, 199, 200, 201, 202, 204, 205, 206, + 207, 213, 216, 222, 223, 232, 239, 242, 165, 0, + 0, 0, 0, 0, 0, 0, 0, 111, 0, 0, + 0, 0, 0, 137, 0, 139, 0, 0, 211, 153, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 263, 0, 0, + 0, 0, 0, 0, 0, 0, 101, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 119, 0, 0, 0, 265, 0, 0, 0, 0, + 184, 0, 215, 122, 136, 97, 83, 93, 0, 121, + 162, 191, 195, 0, 0, 0, 105, 0, 193, 172, + 231, 0, 174, 192, 140, 221, 185, 230, 240, 241, + 218, 238, 245, 208, 86, 217, 229, 102, 203, 88, + 227, 214, 151, 131, 132, 87, 0, 189, 110, 117, + 107, 164, 224, 225, 106, 248, 94, 237, 90, 95, + 236, 158, 220, 228, 152, 145, 89, 226, 150, 144, + 135, 114, 124, 182, 142, 183, 125, 155, 154, 156, + 0, 0, 0, 212, 234, 249, 99, 0, 219, 243, + 244, 0, 0, 100, 118, 113, 181, 157, 96, 127, + 209, 134, 141, 188, 247, 171, 194, 103, 233, 210, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, + 91, 138, 246, 186, 116, 235, 0, 0, 109, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 84, 85, 92, 98, 104, 108, 112, 115, 120, + 123, 126, 128, 129, 130, 133, 143, 146, 147, 148, + 149, 159, 160, 161, 163, 166, 167, 168, 169, 170, + 173, 175, 176, 177, 178, 179, 180, 187, 190, 196, + 197, 198, 199, 200, 201, 202, 204, 205, 206, 207, + 213, 216, 222, 223, 232, 239, 242, 165, 0, 0, + 0, 0, 0, 0, 0, 0, 111, 0, 0, 0, + 0, 0, 137, 0, 139, 0, 0, 211, 153, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 320, 0, 0, 0, + 0, 0, 0, 0, 0, 101, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 119, 0, 0, 0, 265, 0, 0, 0, 0, 184, + 0, 215, 122, 136, 97, 83, 93, 0, 121, 162, + 191, 195, 0, 0, 0, 105, 0, 193, 172, 231, + 0, 174, 192, 140, 221, 185, 230, 240, 241, 218, + 238, 245, 208, 86, 217, 229, 102, 203, 88, 227, + 214, 151, 131, 132, 87, 0, 189, 110, 117, 107, + 164, 224, 225, 106, 248, 94, 237, 90, 95, 236, + 158, 220, 228, 152, 145, 89, 226, 150, 144, 135, + 114, 124, 182, 142, 183, 125, 155, 154, 156, 0, + 0, 0, 212, 234, 249, 99, 0, 219, 243, 244, + 0, 0, 100, 118, 113, 181, 157, 96, 127, 209, + 134, 141, 188, 247, 171, 194, 103, 233, 210, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 82, 91, + 138, 246, 186, 116, 235, 0, 0, 109, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 84, 85, 92, 98, 104, 108, 112, 115, 120, 123, + 126, 128, 129, 130, 133, 143, 146, 147, 148, 149, + 159, 160, 161, 163, 166, 167, 168, 169, 170, 173, + 175, 176, 177, 178, 179, 180, 187, 190, 196, 197, + 198, 199, 200, 201, 202, 204, 205, 206, 207, 213, + 216, 222, 223, 232, 239, 242, } var yyPact = [...]int{ - 1469, -1000, -179, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + 1877, -1000, -267, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, 940, 995, -1000, -1000, -1000, -1000, -1000, -1000, + 255, 11283, 36, 110, -5, 15262, 109, 1522, 15920, -1000, + 13, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -80, -91, + -1000, 687, -1000, -1000, -1000, -1000, -1000, 914, 938, 778, + 907, 822, -1000, 7981, 77, 77, 14933, 6665, -1000, -1000, + 212, 15920, 101, 15920, -147, 80, 80, 80, -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, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, 925, 971, -1000, -1000, -1000, -1000, -1000, -1000, - 353, 8963, -1, 136, -6, 11580, 135, 1582, 12054, -1000, - -9, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -80, -92, - -1000, 715, -1000, -1000, -1000, -1000, -1000, 920, 923, 761, - 911, 818, -1000, 6511, 101, 101, 11343, 5773, -1000, -1000, - 352, 12054, 129, 12054, -145, 91, 91, 91, -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, @@ -1995,22 +2560,22 @@ 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, 133, 12054, 221, -1000, 12054, 82, 570, 82, 82, - 82, 12054, -1000, 187, -1000, -1000, -1000, 12054, 563, 868, - 3442, 50, 3442, -1000, 3442, 3442, -1000, 3442, 1, 3442, - -70, 936, -22, -1000, 3442, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 518, 880, - 7496, 7496, 925, -1000, 715, -1000, -1000, -1000, 849, -1000, - -1000, 397, 958, -1000, 8726, 185, -1000, 7496, 1769, 695, - -1000, -1000, 695, -1000, -1000, 148, -1000, -1000, 8234, 8234, - 8234, 8234, 8234, 8234, 8234, 8234, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - 695, -1000, 7250, 695, 695, 695, 695, 695, 695, 695, - 695, 7496, 695, 695, 695, 695, 695, 695, 695, 695, - 695, 695, 695, 695, 695, 695, 695, 11106, 10394, 12054, - 680, 677, -1000, -1000, 180, 709, 5514, -109, -1000, -1000, - -1000, 336, 10157, -1000, -1000, -1000, 847, -1000, -1000, -1000, + 107, 15920, 186, -1000, 15920, 75, 531, 75, 75, 75, + 15920, -1000, 141, -1000, -1000, -1000, 15920, 525, 873, 3587, + 55, 3587, -1000, 3587, 3587, -1000, 3587, 24, 3587, -83, + 955, 25, -44, -1000, 3587, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 538, 885, + 9309, 9309, 940, -1000, 687, -1000, -1000, -1000, 862, -1000, + -1000, 274, 972, -1000, 10954, 139, -1000, 9309, 1633, 634, + -1000, -1000, 634, -1000, -1000, 128, -1000, -1000, 10296, 10296, + 10296, 10296, 10296, 10296, 10296, 10296, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + 634, -1000, 8980, 634, 634, 634, 634, 634, 634, 634, + 634, 9309, 634, 634, 634, 634, 634, 634, 634, 634, + 634, 634, 634, 634, 634, 634, 634, 14597, 13610, 15920, + 743, 702, -1000, -1000, 138, 689, 6323, -97, -1000, -1000, + -1000, 206, 13281, -1000, -1000, -1000, 870, -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, @@ -2019,207 +2584,201 @@ 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, 646, 12054, -1000, 12392, -1000, 558, 3442, - 107, 550, 365, 531, 12054, 12054, 3442, 5, 66, 35, - 12054, 716, 105, 12054, 897, 791, 12054, 529, 527, -1000, - 5255, -1000, 3442, 3442, -1000, -1000, -1000, 3442, 3442, 3442, - 12054, 3442, 3442, -1000, -1000, -1000, -1000, 3442, 3442, -1000, - 957, 323, -1000, -1000, -1000, -1000, 7496, -1000, 790, -1000, - -1000, -1000, -1000, -1000, -1000, 966, 223, 517, 175, 713, - -1000, 498, 920, 518, 818, 9920, 801, -1000, -1000, 12054, - -1000, 7496, 7496, 416, -1000, 10868, -1000, -1000, 4219, 236, - 8234, 423, 305, 8234, 8234, 8234, 8234, 8234, 8234, 8234, - 8234, 8234, 8234, 8234, 8234, 8234, 8234, 8234, 450, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, -1000, 519, -1000, 715, - 694, 694, 195, 195, 195, 195, 195, 195, 195, 8480, - 6019, 518, 628, 344, 7250, 6511, 6511, 7496, 7496, 7003, - 6757, 6511, 915, 360, 344, 12291, -1000, -1000, 7988, -1000, - -1000, -1000, -1000, -1000, 518, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, 11817, 11817, 6511, 6511, 6511, 6511, 41, 12054, - -1000, 696, 731, -1000, -1000, -1000, 900, 9437, 9683, 41, - 586, 10394, 12054, -1000, -1000, 10394, 12054, 3960, 4996, 709, - -109, 673, -1000, -107, -122, 2624, 189, -1000, -1000, -1000, - -1000, 3183, 351, 579, 382, -74, -1000, -1000, -1000, 729, - -1000, 729, 729, 729, 729, -42, -42, -42, -42, -1000, - -1000, -1000, -1000, -1000, 769, 764, -1000, 729, 729, 729, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 759, 759, - 759, 739, 739, 778, -1000, 12054, 3442, 895, 3442, -1000, - 83, -1000, 11817, 11817, 12054, 12054, 12054, 143, 12054, 12054, - 708, -1000, 12054, 3442, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 12054, - 386, 12054, 12054, 344, 12054, -1000, 831, 7496, 7496, 4737, - 7496, -1000, -1000, -1000, 880, -1000, 915, 924, -1000, 841, - 838, 6511, -1000, -1000, 236, 338, -1000, -1000, 390, -1000, - -1000, -1000, -1000, 166, 695, -1000, 1952, -1000, -1000, -1000, - -1000, 423, 8234, 8234, 8234, 145, 1952, 1935, 1071, 1413, - 195, 451, 451, 197, 197, 197, 197, 197, 395, 395, - -1000, -1000, -1000, 518, -1000, -1000, -1000, 518, 6511, 679, - -1000, -1000, 7496, -1000, 518, 615, 615, 376, 364, 271, - 941, 615, 269, 939, 615, 615, 6511, 350, -1000, 7496, - 518, -1000, 163, -1000, 704, 676, 674, 615, 518, 615, - 615, 780, 695, -1000, 12291, 10394, 10394, 10394, 10394, 10394, - -1000, 815, 812, -1000, 805, 804, 811, 12054, -1000, 619, - 9437, 171, 695, -1000, 10631, -1000, -1000, 935, 10394, 660, - -1000, 660, -1000, 156, -1000, -1000, 673, -109, -128, -1000, - -1000, -1000, -1000, 344, -1000, 488, 672, 2924, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, 755, 512, -1000, 884, 229, - 226, 510, 881, -1000, -1000, -1000, 850, -1000, 373, -76, - -1000, -1000, 455, -42, -42, -1000, -1000, 189, 846, 189, - 189, 189, 483, 483, -1000, -1000, -1000, -1000, 454, -1000, - -1000, -1000, 453, -1000, 787, 11817, 3442, -1000, -1000, -1000, - -1000, 179, 179, 202, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, 39, 771, -1000, -1000, -1000, - -1000, -16, 0, 103, -1000, 3442, -1000, 323, -1000, 482, - 7496, -1000, -1000, -1000, 827, 344, 344, 155, -1000, -1000, - 12054, -1000, -1000, -1000, -1000, 703, -1000, -1000, -1000, 3701, - 6511, -1000, 145, 1952, 1654, -1000, 8234, 8234, -1000, -1000, - 615, 6511, 344, -1000, -1000, -1000, 383, 450, 383, 8234, - 8234, -1000, 8234, 8234, -1000, -158, 692, 270, -1000, 7496, - 250, -1000, 4737, -1000, 8234, 8234, -1000, -1000, -1000, -1000, - 785, 12291, 695, -1000, 9200, 11817, 664, -1000, 311, 731, - 768, 784, 914, -1000, -1000, -1000, -1000, 808, -1000, 806, - -1000, -1000, -1000, -1000, -1000, 127, 126, 113, 11817, -1000, - 925, 7496, 660, -1000, -1000, 208, -1000, -1000, -117, -131, - -1000, -1000, -1000, 3183, -1000, 3183, 11817, 71, -1000, 510, - 510, -1000, -1000, -1000, 742, 783, 8234, -1000, -1000, -1000, - 569, 189, 189, -1000, 283, -1000, -1000, -1000, 603, -1000, - 601, 669, 599, 12054, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - 12054, -1000, -1000, -1000, -1000, -1000, 11817, -167, 508, 11817, - 11817, 11817, 12054, -1000, 386, -1000, 344, -1000, 4478, -1000, - 935, 10394, -1000, -1000, 518, -1000, 8234, 1952, 1952, -1000, - -1000, 518, 729, 729, -1000, 729, 739, -1000, 729, -18, - 729, -19, 518, 518, 1903, 1868, 1839, 1576, 695, -152, - -1000, 344, 7496, -1000, 1547, 1442, -1000, 888, 654, 655, - -1000, -1000, 6265, 518, 595, 154, 578, -1000, 925, 12291, - 7496, -1000, -1000, 7496, 736, -1000, 7496, -1000, -1000, -1000, - 695, 695, 695, 578, 920, 344, -1000, -1000, -1000, -1000, - 2924, -1000, 575, -1000, 729, -1000, -1000, -1000, 11817, -65, - 965, 1952, -1000, -1000, -1000, -1000, -1000, -42, 473, -42, - 444, -1000, 422, 3442, -1000, -1000, -1000, -1000, 882, -1000, - 4478, -1000, -1000, 728, 772, -1000, -1000, -1000, 932, 662, - -1000, 1952, -1000, -1000, 96, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, 8234, 8234, 8234, 8234, 8234, 518, 467, - 344, 8234, 8234, 879, -1000, 695, -1000, -1000, 712, 11817, - 11817, -1000, 11817, 920, -1000, 344, 344, 11817, 344, 11817, - 11817, 11817, 2347, -1000, 161, 11817, -1000, 568, -1000, 184, - -1000, -111, 189, -1000, 189, 549, 543, -1000, 695, 658, - -1000, 263, 11817, 12054, 930, 922, -1000, -1000, 704, 704, - 704, 704, 84, -1000, -1000, 704, 704, 964, -1000, 695, - -1000, 715, 153, -1000, -1000, -1000, 548, 542, 542, 542, - 171, 161, -1000, 491, 260, 461, -1000, 58, 11817, 378, - 875, -1000, 873, -1000, -1000, -1000, -1000, -1000, 16, 4478, - 3183, 536, -1000, -1000, 7496, 7496, -1000, -1000, -1000, -1000, - 518, 47, -171, -1000, -1000, 12291, 655, 518, 11817, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, 414, -1000, -1000, 12054, - -1000, -1000, 396, -1000, -1000, 525, -1000, 11817, -1000, -1000, - 771, 344, 606, -1000, 826, -165, -174, 590, -1000, -1000, - -1000, 727, -1000, -1000, 16, 837, -167, -1000, 821, -1000, - 11817, -1000, 12, -1000, -169, 501, 9, -172, 781, 695, - -176, 770, -1000, 955, 7742, -1000, -1000, 962, 196, 196, - 704, 518, -1000, -1000, -1000, 69, 437, -1000, -1000, -1000, - -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, 619, 15920, -1000, 2291, -1000, + 516, 3587, 92, 490, 244, 487, 15920, 15920, 3587, 31, + 64, 60, 15920, 693, 90, 15920, 901, 785, 15920, 477, + 473, -1000, 5981, -1000, 3587, 3587, -1000, -1000, -1000, 3587, + 3587, 3587, 15920, 3587, 3587, -1000, -1000, -1000, -1000, 3587, + 3587, -1000, 966, 262, -1000, -1000, -1000, -1000, 9309, 176, + -1000, 784, -1000, -1000, -1000, -1000, -1000, -1000, 988, 172, + 446, 136, 692, -1000, 384, 914, 538, 822, 12952, 787, + -1000, -1000, 15920, -1000, 9309, 9309, 494, -1000, 14268, -1000, + -1000, 4613, 179, 10296, 346, 272, 10296, 10296, 10296, 10296, + 10296, 10296, 10296, 10296, 10296, 10296, 10296, 10296, 10296, 10296, + 10296, 382, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + 466, -1000, 687, 574, 574, 151, 151, 151, 151, 151, + 151, 151, 10625, 7323, 538, 617, 322, 8980, 7981, 7981, + 9309, 9309, 8639, 8310, 7981, 908, 215, 322, 16249, -1000, + -1000, 9967, -1000, -1000, -1000, -1000, -1000, 538, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, 15591, 15591, 7981, 7981, 7981, + 7981, 46, 15920, -1000, 652, 961, -1000, -1000, -1000, 903, + 12294, 12623, 46, 655, 13610, 15920, -1000, -1000, 13610, 15920, + 4271, 5639, 689, -97, 657, -1000, -126, -103, 6994, 147, + -1000, -1000, -1000, -1000, 3245, 253, 558, 293, -58, -1000, + -1000, -1000, 737, -1000, 737, 737, 737, 737, -27, -27, + -27, -27, -1000, -1000, -1000, -1000, -1000, 757, 755, -1000, + 737, 737, 737, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, 754, 754, 754, 740, 740, 759, -1000, 15920, 3587, + 898, 3587, -1000, 76, -1000, 15920, 15920, 15920, 15920, 15920, + 117, 15920, 15920, 688, -1000, 15920, 3587, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, 15920, 313, 15920, 15920, 322, -1000, 425, 15920, + -1000, 835, 9309, 9309, 5297, 9309, -1000, -1000, -1000, 885, + -1000, 908, 945, -1000, 860, 847, 7981, -1000, -1000, 179, + 227, -1000, -1000, 329, -1000, -1000, -1000, -1000, 135, 634, + -1000, 2130, -1000, -1000, -1000, -1000, 346, 10296, 10296, 10296, + 409, 2130, 2088, 789, 722, 151, 269, 269, 155, 155, + 155, 155, 155, 393, 393, -1000, -1000, -1000, 538, -1000, + -1000, -1000, 538, 7981, 668, -1000, -1000, 9309, -1000, 538, + 611, 611, 514, 459, 238, 960, 611, 229, 959, 611, + 611, 7981, 254, -1000, 9309, 538, -1000, 134, -1000, 633, + 664, 661, 611, 538, 611, 611, 684, 634, -1000, 16249, + 13610, 13610, 13610, 13610, 13610, -1000, 814, 813, -1000, 804, + 798, 805, 15920, -1000, 615, 12294, 163, 634, -1000, 13939, + -1000, -1000, 954, 13610, 632, -1000, 632, -1000, 133, -1000, + -1000, 657, -97, -125, -1000, -1000, -1000, -1000, 322, -1000, + 402, 656, 2903, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + 748, 463, -1000, 889, 199, 203, 458, 882, -1000, -1000, + -1000, 876, -1000, 260, -105, -1000, -1000, 391, -27, -27, + -1000, -1000, 147, 869, 147, 147, 147, 424, 424, -1000, + -1000, -1000, -1000, 363, -1000, -1000, -1000, 341, -1000, 783, + 15591, 3587, -1000, -1000, -1000, -1000, 347, 347, 198, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + 45, 576, -1000, -1000, -1000, -1000, -1, 30, 83, -1000, + 3587, -1000, 262, -1000, 416, 9309, -1000, -1000, -1000, -1000, + 827, 322, 322, 131, -1000, -1000, 15920, -1000, -1000, -1000, + -1000, 669, -1000, -1000, -1000, 3929, 7981, -1000, 409, 2130, + 2055, -1000, 10296, 10296, -1000, -1000, 611, 7981, 322, -1000, + -1000, -1000, 98, 382, 98, 10296, 10296, -1000, 10296, 10296, + -1000, -165, 691, 210, -1000, 9309, 317, -1000, 5297, -1000, + 10296, 10296, -1000, -1000, -1000, -1000, 782, 16249, 634, -1000, + 11953, 15591, 643, -1000, 204, 961, 747, 776, 604, -1000, + -1000, -1000, -1000, 812, -1000, 796, -1000, -1000, -1000, -1000, + -1000, 100, 97, 94, 15591, -1000, 940, 9309, 632, -1000, + -1000, 164, -1000, -1000, -130, -108, -1000, -1000, -1000, 3245, + -1000, 3245, 15591, 61, -1000, 458, 458, -1000, -1000, -1000, + 741, 761, 10296, -1000, -1000, -1000, 554, 147, 147, -1000, + 200, -1000, -1000, -1000, 583, -1000, 571, 642, 545, 15920, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, 15920, -1000, -1000, + -1000, -1000, -1000, 15591, -173, 457, 15591, 15591, 15591, 15920, + -1000, 313, -1000, 322, -1000, 4955, -1000, 954, 13610, -1000, + -1000, 538, -1000, 10296, 2130, 2130, -1000, -1000, 538, 737, + 737, -1000, 737, 740, -1000, 737, 3, 737, 2, 538, + 538, 2040, 1999, 1869, 1843, 634, -160, -1000, 322, 9309, + -1000, 1705, 1118, -1000, 892, 553, 596, -1000, -1000, 7652, + 538, 541, 127, 536, -1000, 940, 16249, 9309, -1000, -1000, + 9309, 739, -1000, 9309, -1000, -1000, -1000, 634, 634, 634, + 536, 914, 322, -1000, -1000, -1000, -1000, 2903, -1000, 529, + -1000, 737, -1000, -1000, -1000, 15591, -51, 981, 2130, -1000, + -1000, -1000, -1000, -1000, -27, 415, -27, 326, -1000, 305, + 3587, -1000, -1000, -1000, -1000, 894, -1000, 4955, -1000, -1000, + 731, 744, -1000, -1000, -1000, 952, 631, -1000, 2130, -1000, + -1000, 118, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + 10296, 10296, 10296, 10296, 10296, 538, 410, 322, 10296, 10296, + 881, -1000, 634, -1000, -1000, 711, 15591, 15591, -1000, 15591, + 914, -1000, 322, 322, 15591, 322, 15591, 15591, 15591, 11612, + -1000, 149, 15591, -1000, 523, -1000, 191, -1000, -75, 147, + -1000, 147, 546, 542, -1000, 634, 626, -1000, 194, 15591, + 15920, 943, 916, -1000, -1000, 633, 633, 633, 633, 51, + -1000, -1000, 633, 633, 979, -1000, 634, -1000, 687, 123, + -1000, -1000, -1000, 521, 503, 503, 503, 163, 149, -1000, + 441, 189, 404, -1000, 58, 15591, 271, 880, -1000, 879, + -1000, -1000, -1000, -1000, -1000, 43, 4955, 3245, 485, -1000, + -1000, 9309, 9309, -1000, -1000, -1000, -1000, 538, 44, -177, + -1000, -1000, 16249, 596, 538, 15591, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, 298, -1000, -1000, 15920, -1000, -1000, 395, + -1000, -1000, 482, -1000, 15591, -1000, -1000, 576, 322, 575, + -1000, 826, -171, -181, 562, -1000, -1000, -1000, 704, -1000, + -1000, 43, 843, -173, -1000, 825, -1000, 15591, -1000, 37, + -1000, -175, 432, 35, -178, 749, 634, -182, 690, -1000, + 984, 9638, -1000, -1000, 977, 177, 177, 633, 538, -1000, + -1000, -1000, 65, 345, -1000, -1000, -1000, -1000, -1000, -1000, } var yyPgo = [...]int{ - 0, 1212, 45, 519, 1209, 1208, 1206, 1200, 1198, 1197, - 1192, 1189, 1188, 1187, 1186, 1185, 1182, 1181, 1180, 1179, - 1160, 1158, 1157, 1152, 1150, 1149, 142, 1148, 1147, 1145, - 76, 1143, 70, 1142, 1141, 48, 413, 52, 44, 953, - 1140, 24, 71, 66, 1139, 38, 1138, 1137, 82, 1136, - 1134, 55, 1132, 1131, 92, 1130, 73, 1128, 12, 30, - 1127, 1126, 1125, 1124, 77, 467, 1123, 1118, 15, 1117, - 1116, 95, 1115, 57, 10, 14, 22, 27, 1114, 100, - 7, 1109, 56, 1108, 1106, 1104, 1103, 21, 1102, 54, - 1100, 18, 59, 1086, 9, 75, 31, 25, 8, 87, - 60, 1083, 26, 63, 47, 1082, 1081, 452, 1080, 1079, - 58, 1078, 1077, 29, 148, 434, 1075, 1072, 1071, 1068, - 42, 0, 874, 432, 69, 1067, 1066, 1065, 1629, 40, - 50, 17, 1063, 33, 174, 43, 1059, 1058, 41, 1055, - 1052, 1050, 1049, 1048, 1044, 1042, 20, 1041, 1040, 1038, - 19, 23, 1037, 1036, 64, 28, 1034, 1033, 1032, 51, - 65, 1029, 1028, 53, 37, 1027, 1025, 1024, 1022, 1017, - 34, 13, 1014, 16, 1013, 4, 1012, 35, 1009, 5, - 990, 11, 989, 2, 987, 6, 49, 3, 986, 1, - 982, 981, 61, 601, 83, 977, 115, + 0, 1202, 55, 407, 1201, 1196, 1195, 1192, 1190, 1187, + 1186, 1185, 1184, 1183, 1182, 1181, 1169, 1168, 1167, 1164, + 1163, 1161, 1159, 1157, 1155, 1153, 96, 1151, 1150, 1149, + 66, 1147, 81, 1138, 1137, 40, 918, 41, 45, 827, + 1136, 26, 71, 46, 1135, 35, 1134, 1133, 88, 1131, + 1130, 57, 1126, 1124, 92, 1122, 73, 1121, 11, 43, + 1120, 1119, 1118, 1117, 70, 329, 1116, 1115, 16, 1114, + 1108, 84, 1107, 50, 7, 14, 13, 22, 1106, 906, + 25, 1105, 58, 1104, 1100, 1097, 1096, 27, 1095, 64, + 1094, 18, 59, 1093, 9, 78, 33, 21, 5, 75, + 63, 1089, 24, 60, 49, 1087, 1086, 460, 1085, 1084, + 42, 1083, 1082, 28, 1081, 97, 388, 1080, 1079, 1077, + 1076, 52, 0, 489, 137, 69, 1074, 1073, 1072, 1521, + 38, 54, 17, 1071, 53, 20, 37, 1070, 1069, 34, + 1068, 1067, 1061, 1060, 1058, 1057, 1055, 116, 1054, 1053, + 1048, 19, 79, 1046, 1045, 51, 23, 1042, 1038, 1037, + 47, 65, 1033, 1032, 48, 29, 1030, 1029, 1028, 1027, + 1026, 31, 10, 1025, 12, 1024, 15, 1023, 30, 1021, + 4, 1020, 8, 1019, 3, 1017, 6, 44, 1, 1016, + 2, 1015, 1012, 61, 623, 76, 1008, 77, } var yyR1 = [...]int{ - 0, 190, 191, 191, 1, 1, 1, 1, 1, 1, + 0, 191, 192, 192, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 6, 3, 4, 4, 5, 5, 7, 7, 29, 29, 8, 9, 9, - 9, 9, 194, 194, 48, 48, 49, 49, 95, 95, + 9, 9, 195, 195, 48, 48, 49, 49, 95, 95, 10, 10, 10, 10, 100, 100, 104, 104, 104, 105, - 105, 105, 105, 136, 136, 11, 11, 11, 11, 11, - 11, 11, 185, 185, 184, 183, 183, 182, 182, 181, - 17, 166, 168, 168, 167, 167, 167, 167, 160, 139, - 139, 139, 139, 142, 142, 140, 140, 140, 140, 140, - 140, 140, 140, 140, 141, 141, 141, 141, 141, 143, - 143, 143, 143, 143, 144, 144, 144, 144, 144, 144, - 144, 144, 144, 144, 144, 144, 144, 144, 144, 145, - 145, 145, 145, 145, 145, 145, 145, 159, 159, 146, - 146, 154, 154, 155, 155, 155, 152, 152, 153, 153, - 156, 156, 156, 148, 148, 149, 149, 157, 157, 150, - 150, 150, 151, 151, 151, 158, 158, 158, 158, 158, - 147, 147, 161, 161, 176, 176, 175, 175, 175, 165, - 165, 172, 172, 172, 172, 172, 163, 163, 164, 164, - 174, 174, 173, 162, 162, 177, 177, 177, 177, 188, - 189, 187, 187, 187, 187, 187, 169, 169, 169, 170, - 170, 170, 171, 171, 171, 12, 12, 12, 12, 12, + 105, 105, 105, 137, 137, 11, 11, 11, 11, 11, + 11, 11, 186, 186, 185, 184, 184, 183, 183, 182, + 17, 167, 169, 169, 168, 168, 168, 168, 161, 140, + 140, 140, 140, 143, 143, 141, 141, 141, 141, 141, + 141, 141, 141, 141, 142, 142, 142, 142, 142, 144, + 144, 144, 144, 144, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 146, + 146, 146, 146, 146, 146, 146, 146, 160, 160, 147, + 147, 155, 155, 156, 156, 156, 153, 153, 154, 154, + 157, 157, 157, 149, 149, 150, 150, 158, 158, 151, + 151, 151, 152, 152, 152, 159, 159, 159, 159, 159, + 148, 148, 162, 162, 177, 177, 176, 176, 176, 166, + 166, 173, 173, 173, 173, 173, 164, 164, 165, 165, + 175, 175, 174, 163, 163, 178, 178, 178, 178, 189, + 190, 188, 188, 188, 188, 188, 170, 170, 170, 171, + 171, 171, 172, 172, 172, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, - 186, 180, 178, 178, 179, 179, 13, 18, 18, 14, - 14, 14, 14, 14, 15, 15, 19, 20, 20, 20, + 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, + 187, 187, 181, 179, 179, 180, 180, 13, 18, 18, + 14, 14, 14, 14, 14, 15, 15, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 111, 111, 109, 109, 112, 112, - 110, 110, 110, 113, 113, 113, 137, 137, 137, 21, - 21, 23, 23, 24, 25, 22, 22, 22, 22, 22, - 22, 22, 16, 195, 26, 27, 27, 28, 28, 28, - 32, 32, 32, 30, 30, 31, 31, 37, 37, 36, - 36, 38, 38, 38, 38, 125, 125, 125, 124, 124, - 40, 40, 41, 41, 42, 42, 43, 43, 43, 43, - 57, 57, 94, 94, 96, 96, 44, 44, 44, 44, - 45, 45, 46, 46, 47, 47, 132, 132, 131, 131, - 131, 130, 130, 50, 50, 50, 52, 51, 51, 51, - 51, 53, 53, 55, 55, 54, 54, 56, 58, 58, - 58, 58, 59, 59, 39, 39, 39, 39, 39, 39, - 39, 108, 108, 61, 61, 60, 60, 60, 60, 60, - 60, 60, 60, 60, 60, 72, 72, 72, 72, 72, - 72, 62, 62, 62, 62, 62, 62, 62, 35, 35, - 73, 73, 73, 79, 74, 74, 65, 65, 65, 65, + 20, 20, 20, 20, 20, 20, 111, 111, 109, 109, + 112, 112, 110, 110, 110, 113, 113, 113, 114, 114, + 138, 138, 138, 21, 21, 23, 23, 24, 25, 22, + 22, 22, 22, 22, 22, 22, 16, 196, 26, 27, + 27, 28, 28, 28, 32, 32, 32, 30, 30, 31, + 31, 37, 37, 36, 36, 38, 38, 38, 38, 126, + 126, 126, 125, 125, 40, 40, 41, 41, 42, 42, + 43, 43, 43, 43, 57, 57, 94, 94, 96, 96, + 44, 44, 44, 44, 45, 45, 46, 46, 47, 47, + 133, 133, 132, 132, 132, 131, 131, 50, 50, 50, + 52, 51, 51, 51, 51, 53, 53, 55, 55, 54, + 54, 56, 58, 58, 58, 58, 59, 59, 39, 39, + 39, 39, 39, 39, 39, 108, 108, 61, 61, 60, + 60, 60, 60, 60, 60, 60, 60, 60, 60, 72, + 72, 72, 72, 72, 72, 62, 62, 62, 62, 62, + 62, 62, 35, 35, 73, 73, 73, 79, 74, 74, + 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, 69, 69, - 69, 67, 67, 67, 67, 67, 67, 67, 67, 67, - 67, 67, 67, 67, 68, 68, 68, 68, 68, 68, + 65, 65, 69, 69, 69, 67, 67, 67, 67, 67, + 67, 67, 67, 67, 67, 67, 67, 67, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, - 196, 196, 71, 70, 70, 70, 70, 70, 70, 33, - 33, 33, 33, 33, 135, 135, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 83, - 83, 34, 34, 81, 81, 82, 84, 84, 80, 80, - 80, 64, 64, 64, 64, 64, 64, 64, 64, 66, - 66, 66, 85, 85, 86, 86, 87, 87, 88, 88, - 89, 90, 90, 90, 91, 91, 91, 91, 92, 92, - 92, 63, 63, 63, 63, 63, 63, 93, 93, 93, - 93, 97, 97, 75, 75, 77, 77, 76, 78, 98, - 98, 102, 99, 99, 103, 103, 103, 103, 101, 101, - 101, 127, 127, 127, 106, 106, 114, 114, 115, 115, - 107, 107, 116, 116, 116, 116, 116, 116, 116, 116, - 116, 116, 117, 117, 117, 118, 118, 119, 119, 119, - 126, 126, 122, 122, 123, 123, 128, 128, 129, 129, - 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, - 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, - 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, - 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, - 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, - 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, - 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, - 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, - 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, - 120, 120, 120, 120, 120, 121, 121, 121, 121, 121, + 68, 68, 68, 68, 197, 197, 71, 70, 70, 70, + 70, 70, 70, 33, 33, 33, 33, 33, 136, 136, + 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, + 139, 139, 139, 83, 83, 34, 34, 81, 81, 82, + 84, 84, 80, 80, 80, 64, 64, 64, 64, 64, + 64, 64, 64, 66, 66, 66, 85, 85, 86, 86, + 87, 87, 88, 88, 89, 90, 90, 90, 91, 91, + 91, 91, 92, 92, 92, 63, 63, 63, 63, 63, + 63, 93, 93, 93, 93, 97, 97, 75, 75, 77, + 77, 76, 78, 98, 98, 102, 99, 99, 103, 103, + 103, 103, 101, 101, 101, 128, 128, 128, 106, 106, + 115, 115, 116, 116, 107, 107, 117, 117, 117, 117, + 117, 117, 117, 117, 117, 117, 118, 118, 118, 119, + 119, 120, 120, 120, 127, 127, 123, 123, 124, 124, + 129, 129, 130, 130, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, @@ -2230,8 +2789,25 @@ var yyR1 = [...]int{ 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 192, 193, 133, 134, 134, - 134, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 122, 122, 122, 122, 122, 122, 122, 122, 122, + 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, + 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, + 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, + 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, + 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, + 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, + 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, + 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, + 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, + 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, + 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, + 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, + 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, + 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, + 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, + 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, + 193, 194, 134, 135, 135, 135, } var yyR2 = [...]int{ @@ -2259,46 +2835,53 @@ var yyR2 = [...]int{ 2, 3, 1, 1, 1, 6, 7, 7, 7, 7, 4, 5, 7, 5, 5, 5, 12, 7, 5, 9, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 7, 1, 3, 8, 8, 3, 3, 5, 4, - 6, 5, 4, 4, 3, 2, 3, 4, 4, 3, - 4, 4, 4, 4, 4, 4, 3, 2, 3, 3, - 2, 3, 4, 3, 7, 5, 4, 2, 4, 3, - 3, 5, 2, 3, 1, 1, 0, 1, 1, 1, - 0, 2, 2, 0, 2, 2, 0, 1, 1, 2, - 1, 1, 2, 1, 1, 2, 2, 2, 2, 2, - 3, 3, 2, 0, 2, 0, 2, 1, 2, 2, - 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, - 3, 1, 2, 3, 5, 0, 1, 2, 1, 1, - 0, 2, 1, 3, 1, 1, 1, 3, 1, 3, - 3, 7, 1, 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, 5, - 5, 5, 0, 2, 1, 3, 3, 2, 3, 1, - 2, 0, 3, 1, 1, 3, 3, 4, 4, 5, - 3, 4, 5, 6, 2, 1, 2, 1, 2, 1, - 2, 1, 1, 1, 1, 1, 1, 1, 0, 2, - 1, 1, 1, 3, 1, 3, 1, 1, 1, 1, - 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, - 2, 2, 2, 3, 1, 1, 1, 1, 4, 5, - 6, 4, 4, 6, 6, 6, 8, 8, 8, 8, - 9, 7, 5, 4, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 8, 8, - 0, 2, 3, 4, 4, 4, 4, 4, 4, 0, - 3, 4, 7, 3, 1, 1, 2, 3, 3, 1, - 2, 2, 1, 2, 1, 2, 2, 1, 2, 0, - 1, 0, 2, 1, 2, 4, 0, 2, 1, 3, - 5, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 2, 2, 0, 3, 0, 2, 0, 3, 1, 3, - 2, 0, 1, 1, 0, 2, 4, 4, 0, 2, - 4, 2, 1, 3, 5, 4, 6, 1, 3, 3, - 5, 0, 5, 1, 3, 1, 2, 3, 1, 1, - 3, 3, 1, 3, 3, 3, 3, 3, 1, 2, - 1, 1, 1, 1, 1, 1, 0, 2, 0, 3, - 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, - 0, 2, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 7, 1, 3, 8, 8, 3, 3, 5, + 4, 6, 5, 4, 4, 3, 2, 3, 4, 4, + 3, 4, 4, 4, 4, 4, 4, 3, 2, 3, + 3, 2, 3, 4, 3, 7, 5, 4, 2, 4, + 4, 3, 3, 5, 2, 3, 1, 1, 0, 1, + 1, 1, 0, 2, 2, 0, 2, 2, 0, 2, + 0, 1, 1, 2, 1, 1, 2, 1, 1, 2, + 2, 2, 2, 2, 3, 3, 2, 0, 2, 0, + 2, 1, 2, 2, 0, 1, 1, 0, 1, 0, + 1, 0, 1, 1, 3, 1, 2, 3, 5, 0, + 1, 2, 1, 1, 0, 2, 1, 3, 1, 1, + 1, 3, 1, 3, 3, 7, 1, 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, 5, 5, 5, 0, 2, 1, 3, + 3, 2, 3, 1, 2, 0, 3, 1, 1, 3, + 3, 4, 4, 5, 3, 4, 5, 6, 2, 1, + 2, 1, 2, 1, 2, 1, 1, 1, 1, 1, + 1, 1, 0, 2, 1, 1, 1, 3, 1, 3, + 1, 1, 1, 1, 1, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 2, 2, 2, 2, 2, 2, 2, 3, 1, 1, + 1, 1, 4, 5, 6, 4, 4, 6, 6, 6, + 8, 8, 8, 8, 9, 7, 5, 4, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 8, 8, 0, 2, 3, 4, 4, 4, + 4, 4, 4, 0, 3, 4, 7, 3, 1, 1, + 2, 3, 3, 1, 2, 2, 1, 2, 1, 2, + 2, 1, 2, 0, 1, 0, 2, 1, 2, 4, + 0, 2, 1, 3, 5, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 2, 2, 0, 3, 0, 2, + 0, 3, 1, 3, 2, 0, 1, 1, 0, 2, + 4, 4, 0, 2, 4, 2, 1, 3, 5, 4, + 6, 1, 3, 3, 5, 0, 5, 1, 3, 1, + 2, 3, 1, 1, 3, 3, 1, 3, 3, 3, + 3, 3, 1, 2, 1, 1, 1, 1, 1, 1, + 0, 2, 0, 3, 0, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, + 1, 0, 1, 1, 0, 2, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 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, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -2319,302 +2902,319 @@ 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, 1, 1, 0, 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, 0, 0, 1, 1, } var yyChk = [...]int{ - -1000, -190, -1, -2, -6, -7, -8, -9, -10, -11, + -1000, -191, -1, -2, -6, -7, -8, -9, -10, -11, -12, -13, -14, -15, -19, -20, -21, -23, -24, -25, -22, -16, -3, -4, 6, 7, -29, 9, 10, 30, - -17, 115, 116, 118, 117, 149, 119, 142, 50, 163, - 164, 166, 167, 25, 143, 144, 147, 148, 31, 32, - 121, -192, 8, 247, 54, -191, 264, -87, 15, -28, - 5, -26, -195, -26, -26, -26, -26, -26, -166, -168, - 54, 90, -119, 125, 72, 239, 122, 123, 129, -122, - 57, -121, 257, 135, 163, 174, 168, 195, 187, 258, - 136, 185, 188, 226, 215, 221, 66, 166, 235, 145, - 183, 179, 177, 27, 223, 200, 262, 178, 222, 121, - 138, 133, 201, 205, 227, 172, 173, 229, 199, 134, - 33, 259, 35, 153, 230, 203, 198, 194, 197, 171, - 193, 39, 207, 206, 208, 225, 190, 139, 180, 18, - 233, 148, 151, 224, 202, 204, 130, 155, 261, 231, - 176, 140, 152, 147, 234, 141, 167, 162, 228, 237, - 38, 212, 170, 132, 164, 159, 217, 191, 154, 181, - 182, 196, 169, 192, 165, 156, 149, 236, 213, 263, - 189, 186, 160, 157, 158, 218, 161, 260, 232, 184, - 214, -107, 125, 218, 127, 123, 123, 124, 125, 239, - 122, 123, -54, -128, 57, -121, 125, 123, 108, 188, - 226, 115, 216, 223, 124, 33, 224, 155, -137, 123, - -109, 215, 218, 161, 57, 228, 227, 219, -128, 165, - -133, -133, -133, -133, -133, 217, 217, -133, -2, -91, - 17, 16, -5, -3, -192, 6, 20, 21, -32, 40, - 41, -27, -38, 99, -39, -128, -60, 74, -65, 29, - 57, -121, 23, -64, -61, -80, -78, -79, 108, 109, + -17, 115, 116, 118, 117, 150, 119, 143, 50, 164, + 165, 167, 168, 25, 144, 145, 148, 149, 31, 32, + 121, -193, 8, 249, 54, -192, 347, -87, 15, -28, + 5, -26, -196, -26, -26, -26, -26, -26, -167, -169, + 54, 90, -120, 125, 72, 241, 122, 123, 129, -123, + 57, -122, 259, 136, 291, 292, 164, 175, 169, 196, + 188, 260, 293, 137, 186, 189, 228, 135, 294, 216, + 223, 66, 167, 237, 295, 146, 184, 180, 296, 268, + 178, 27, 297, 225, 201, 298, 264, 179, 224, 121, + 299, 139, 133, 300, 202, 206, 301, 229, 302, 303, + 304, 173, 174, 305, 231, 200, 134, 33, 261, 35, + 154, 232, 204, 306, 199, 195, 307, 308, 309, 310, + 198, 172, 194, 39, 208, 207, 209, 227, 191, 311, + 312, 313, 140, 314, 181, 18, 315, 316, 317, 318, + 319, 235, 149, 320, 152, 321, 322, 323, 324, 325, + 326, 226, 203, 205, 130, 156, 263, 327, 233, 177, + 328, 141, 153, 148, 236, 142, 329, 330, 331, 332, + 333, 334, 335, 168, 336, 337, 338, 339, 163, 230, + 239, 38, 213, 340, 171, 132, 341, 165, 160, 218, + 192, 155, 342, 343, 182, 183, 197, 170, 193, 166, + 157, 150, 344, 238, 214, 265, 190, 187, 161, 345, + 158, 159, 346, 219, 220, 162, 262, 234, 185, 215, + -107, 125, 220, 127, 123, 123, 124, 125, 241, 122, + 123, -54, -129, 57, -122, 125, 123, 108, 189, 228, + 115, 217, 225, 124, 33, 226, 156, -138, 123, -109, + 216, 219, 220, 162, 57, 230, 229, 221, -129, 166, + -134, -134, -134, -134, -134, 218, 218, -134, -2, -91, + 17, 16, -5, -3, -193, 6, 20, 21, -32, 40, + 41, -27, -38, 99, -39, -129, -60, 74, -65, 29, + 57, -122, 23, -64, -61, -80, -78, -79, 108, 109, 110, 97, 98, 105, 75, 111, -69, -67, -68, -70, 59, 58, 67, 60, 61, 62, 63, 68, 69, 70, - -122, -76, -192, 44, 45, 248, 249, 250, 251, 256, - 252, 77, 34, 238, 246, 245, 244, 242, 243, 240, - 241, 254, 255, 128, 239, 103, 247, -107, -107, 11, - -48, -49, -54, -56, -128, -99, -136, 165, -103, 228, - 227, -123, -101, -122, -120, 226, 188, 225, 120, 73, - 22, 24, 210, 76, 108, 16, 77, 107, 248, 115, - 48, 240, 241, 238, 250, 251, 239, 216, 29, 10, - 25, 143, 21, 101, 117, 80, 81, 146, 23, 144, - 70, 19, 51, 11, 13, 14, 128, 127, 92, 124, - 46, 8, 111, 26, 89, 42, 28, 44, 90, 17, - 242, 243, 31, 256, 150, 103, 49, 36, 74, 68, - 71, 52, 72, 15, 47, 91, 118, 247, 45, 122, - 6, 253, 30, 142, 43, 123, 79, 254, 255, 126, - 69, 5, 129, 32, 9, 50, 53, 244, 245, 246, - 34, 78, 12, -167, 90, -160, 57, -54, 124, -54, - 247, -115, 128, -115, -115, 123, -54, 115, 117, 120, - 52, -18, -54, -114, 128, 57, -114, -114, -114, -54, - 112, -54, 57, 30, -134, -192, -123, 239, 57, 155, - 123, 156, 125, -134, -134, -134, -134, 159, 160, -134, - -112, -111, 221, 222, 217, 220, 12, 217, 158, -134, - -133, -133, -193, 56, -92, 19, 31, -39, -128, -88, - -89, -39, -87, -2, -26, 36, -30, 21, 65, 11, - -125, 73, 72, 89, -124, 22, -122, 59, 112, -39, - -62, 92, 74, 90, 91, 76, 94, 93, 104, 97, - 98, 99, 100, 101, 102, 103, 95, 96, 107, 82, - 83, 84, 85, 86, 87, 88, -108, -192, -79, -192, - 113, 114, -65, -65, -65, -65, -65, -65, -65, -65, - -192, -2, -74, -39, -192, -192, -192, -192, -192, -192, - -192, -192, -192, -83, -39, -192, -196, -71, -192, -196, - -71, -196, -71, -196, -192, -196, -71, -196, -71, -196, - -196, -71, -192, -192, -192, -192, -192, -192, -55, 26, - -54, -41, -42, -43, -44, -57, -79, -192, -54, -54, - -48, -194, 55, 11, 53, -194, 55, 112, 55, -99, - 165, -100, -104, 229, 231, 82, -127, -122, 59, 29, - 30, 56, 55, -54, -139, -142, -144, -143, -145, -140, - -141, 185, 186, 108, 189, 191, 192, 193, 194, 195, - 196, 197, 198, 199, 200, 30, 145, 181, 182, 183, - 184, 201, 202, 203, 204, 205, 206, 207, 208, 168, - 187, 258, 169, 170, 171, 172, 173, 174, 176, 177, - 178, 179, 180, 57, -134, 125, 57, 74, 57, -54, - -54, -134, 157, 157, 123, 123, 162, -54, 55, 126, - -48, 23, 52, -54, 57, 57, -129, -128, -120, -134, - -134, -134, -134, -134, -54, -134, -134, -134, -134, 11, - -110, 11, 92, -39, 52, 9, 92, 55, 18, 112, - 55, -90, 24, 25, -91, -193, -32, -66, -122, 60, - 63, -31, 43, -54, -39, -39, -72, 68, 74, 69, - 70, -124, 99, -129, -123, -120, -65, -73, -76, -79, - 64, 92, 90, 91, 76, -65, -65, -65, -65, -65, + -123, -76, -193, 44, 45, 250, 251, 252, 253, 258, + 254, 77, 34, 240, 248, 247, 246, 244, 245, 242, + 243, 256, 257, 128, 241, 103, 249, -107, -107, 11, + -48, -49, -54, -56, -129, -99, -137, 166, -103, 230, + 229, -124, -101, -123, -121, 228, 189, 227, 120, 266, + 73, 22, 24, 211, 76, 108, 16, 77, 107, 250, + 115, 48, 267, 242, 243, 240, 252, 253, 241, 217, + 29, 10, 269, 25, 144, 21, 101, 117, 80, 81, + 147, 23, 145, 70, 272, 19, 51, 11, 13, 273, + 274, 14, 128, 127, 92, 124, 46, 8, 111, 26, + 89, 42, 275, 28, 276, 277, 278, 279, 44, 90, + 17, 244, 245, 31, 280, 258, 151, 103, 49, 36, + 74, 281, 282, 68, 283, 71, 52, 72, 15, 47, + 284, 285, 286, 287, 91, 118, 249, 45, 288, 122, + 6, 255, 30, 143, 43, 289, 123, 79, 256, 257, + 126, 69, 5, 129, 32, 9, 50, 53, 246, 247, + 248, 34, 78, 12, 290, -168, 90, -161, 57, -54, + 124, -54, 249, -116, 128, -116, -116, 123, -54, 115, + 117, 120, 52, -18, -54, -115, 128, 57, -115, -115, + -115, -54, 112, -54, 57, 30, -135, -193, -124, 241, + 57, 156, 123, 157, 125, -135, -135, -135, -135, 160, + 161, -135, -112, -111, 223, 224, 218, 222, 12, 161, + 218, 159, -135, -134, -134, -194, 56, -92, 19, 31, + -39, -129, -88, -89, -39, -87, -2, -26, 36, -30, + 21, 65, 11, -126, 73, 72, 89, -125, 22, -123, + 59, 112, -39, -62, 92, 74, 90, 91, 76, 94, + 93, 104, 97, 98, 99, 100, 101, 102, 103, 95, + 96, 107, 82, 83, 84, 85, 86, 87, 88, -108, + -193, -79, -193, 113, 114, -65, -65, -65, -65, -65, + -65, -65, -65, -193, -2, -74, -39, -193, -193, -193, + -193, -193, -193, -193, -193, -193, -83, -39, -193, -197, + -71, -193, -197, -71, -197, -71, -197, -193, -197, -71, + -197, -71, -197, -197, -71, -193, -193, -193, -193, -193, + -193, -55, 26, -54, -41, -42, -43, -44, -57, -79, + -193, -54, -54, -48, -195, 55, 11, 53, -195, 55, + 112, 55, -99, 166, -100, -104, 231, 233, 82, -128, + -123, 59, 29, 30, 56, 55, -54, -140, -143, -145, + -144, -146, -141, -142, 186, 187, 108, 190, 192, 193, + 194, 195, 196, 197, 198, 199, 200, 201, 30, 146, + 182, 183, 184, 185, 202, 203, 204, 205, 206, 207, + 208, 209, 169, 188, 260, 170, 171, 172, 173, 174, + 175, 177, 178, 179, 180, 181, 57, -135, 125, 57, + 74, 57, -54, -54, -135, 158, 158, 123, 123, 163, + -54, 55, 126, -48, 23, 52, -54, 57, 57, -130, + -129, -121, -135, -135, -135, -135, -135, -54, -135, -135, + -135, -135, 11, -110, 11, 92, -39, -114, 90, 52, + 9, 92, 55, 18, 112, 55, -90, 24, 25, -91, + -194, -32, -66, -123, 60, 63, -31, 43, -54, -39, + -39, -72, 68, 74, 69, 70, -125, 99, -130, -124, + -121, -65, -73, -76, -79, 64, 92, 90, 91, 76, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, - -135, 57, 59, 57, -64, -64, -122, -37, 21, -36, - -38, -193, 55, -193, -2, -36, -36, -39, -39, -80, - 59, -36, -80, 59, -36, -36, -30, -81, -82, 78, - -80, -122, -128, -193, -65, -122, -122, -36, -37, -36, - -36, -95, 151, -54, 30, 55, -50, -52, -51, -53, - 42, 46, 48, 43, 44, 45, 49, -132, 22, -41, - -192, -131, 151, -130, 22, -128, 59, -95, 53, -41, - -54, -41, -56, -128, 99, -103, -100, 55, 230, 232, - 233, 52, 71, -39, -151, 107, -169, -170, -171, -123, - 59, 60, -160, -161, -162, -172, 137, -177, 130, 132, - 129, -163, 138, 124, 28, 56, -156, 68, 74, -152, - 213, -146, 54, -146, -146, -146, -146, -150, 188, -150, - -150, -150, 54, 54, -146, -146, -146, -154, 54, -154, - -154, -155, 54, -155, -126, 53, -54, -134, 23, -134, - -116, 120, 117, 118, -180, 116, 210, 188, 66, 29, - 15, 248, 151, 263, 57, 152, -122, -122, -54, -54, - -54, 120, 117, -54, -54, -54, -134, -54, -113, 90, - 12, -128, -128, -54, 38, -39, -39, -129, -89, -92, - -106, 19, 11, 34, 34, -36, 68, 69, 70, 112, - -192, -73, -65, -65, -65, -35, 146, 73, -193, -193, - -36, 55, -39, -193, -193, -193, 55, 53, 22, 11, - 11, -193, 11, 11, -193, -193, -36, -84, -82, 80, - -39, -193, 112, -193, 55, 55, -193, -193, -193, -193, - -63, 30, 34, -2, -192, -192, -98, -102, -80, -42, - -43, -43, -42, -43, 42, 42, 42, 47, 42, 47, - 42, -51, -128, -193, -58, 50, 127, 51, -192, -130, - -59, 12, -41, -59, -59, 112, -104, -105, 234, 231, - 237, 57, 59, 55, -171, 82, 54, 57, 28, -163, - -163, -164, 57, -164, 28, -148, 29, 68, -153, 214, - 60, -150, -150, -151, 30, -151, -151, -151, -159, 59, - -159, 60, 60, 52, -122, -134, -133, -186, 131, 137, - 138, 133, 57, 124, 28, 130, 132, 151, 129, -186, - -117, -118, 126, 22, 124, 28, 151, -185, 53, 157, - 210, 157, 126, -134, -110, 59, -39, 39, 112, -54, - -40, 11, 99, -123, -37, -35, 73, -65, -65, -193, - -38, -138, 108, 185, 145, 183, 179, 199, 190, 212, - 181, 213, -135, -138, -65, -65, -65, -65, 257, -87, - 81, -39, 79, -123, -65, -65, -97, 52, -98, -75, - -77, -76, -192, -2, -93, -122, -96, -122, -59, 55, - 82, -46, -45, 52, 53, -47, 52, -45, 42, 42, - 124, 124, 124, -96, -87, -39, -59, 231, 235, 236, - -170, -171, -174, -173, -122, -177, -164, -164, 54, -149, - 52, -65, 56, -151, -151, 57, 108, 56, 55, 56, - 55, 56, 55, -54, -133, -133, -54, -133, -122, -183, - 260, -184, 57, -122, -122, -122, -54, -113, -59, -41, - -193, -65, -193, -146, -146, -146, -155, -146, 173, -146, - 173, -193, -193, 19, 19, 19, 19, -192, -34, 253, - -39, 55, 55, 27, -97, 55, -193, -193, -193, 55, - 112, -193, 55, -87, -102, -39, -39, 54, -39, -192, - -192, -192, -193, -91, 56, 55, -146, -94, -122, -157, - 210, 9, -150, 59, -150, 60, 60, -134, 26, -182, - -181, -123, 54, 53, -85, 13, -150, 57, -65, -65, - -65, -65, -65, -193, 59, -65, -65, 28, -77, 34, - -2, -192, -122, -122, -122, -91, -94, -94, -94, -94, - -131, -176, -175, 53, 134, 66, -173, 56, 55, -158, - 130, 28, 129, -68, -151, -151, 56, 56, -192, 55, - 82, -94, -54, -86, 14, 16, -193, -193, -193, -193, - -33, 92, 260, -193, -193, 9, -75, -2, 112, 56, - -193, -193, -193, -58, -175, 57, -165, 82, 59, 140, - -122, -147, 66, 28, 28, -178, -179, 151, -181, -171, - 56, -39, -74, -193, 258, 49, 261, -98, -193, -122, - 60, -54, 59, -193, 55, -122, -185, 39, 259, 262, - 54, -179, 34, -183, 39, -94, 153, 260, 56, 154, - 261, -188, -189, 52, -192, 262, -189, 52, 10, 9, - -65, 150, -187, 141, 136, 139, 30, -187, -193, -193, - 135, 29, 68, + -65, -65, -65, -65, -65, -136, 57, 59, 57, -64, + -64, -123, -37, 21, -36, -38, -194, 55, -194, -2, + -36, -36, -39, -39, -80, 59, -36, -80, 59, -36, + -36, -30, -81, -82, 78, -80, -123, -129, -194, -65, + -123, -123, -36, -37, -36, -36, -95, 152, -54, 30, + 55, -50, -52, -51, -53, 42, 46, 48, 43, 44, + 45, 49, -133, 22, -41, -193, -132, 152, -131, 22, + -129, 59, -95, 53, -41, -54, -41, -56, -129, 99, + -103, -100, 55, 232, 234, 235, 52, 71, -39, -152, + 107, -170, -171, -172, -124, 59, 60, -161, -162, -163, + -173, 138, -178, 130, 132, 129, -164, 139, 124, 28, + 56, -157, 68, 74, -153, 214, -147, 54, -147, -147, + -147, -147, -151, 189, -151, -151, -151, 54, 54, -147, + -147, -147, -155, 54, -155, -155, -156, 54, -156, -127, + 53, -54, -135, 23, -135, -117, 120, 117, 118, -181, + 116, 211, 189, 66, 29, 15, 250, 152, 265, 57, + 153, -54, -54, -54, -54, -54, 120, 117, -54, -54, + -54, -135, -54, -113, 90, 12, -129, -129, 59, -54, + 38, -39, -39, -130, -89, -92, -106, 19, 11, 34, + 34, -36, 68, 69, 70, 112, -193, -73, -65, -65, + -65, -35, 147, 73, -194, -194, -36, 55, -39, -194, + -194, -194, 55, 53, 22, 11, 11, -194, 11, 11, + -194, -194, -36, -84, -82, 80, -39, -194, 112, -194, + 55, 55, -194, -194, -194, -194, -63, 30, 34, -2, + -193, -193, -98, -102, -80, -42, -43, -43, -42, -43, + 42, 42, 42, 47, 42, 47, 42, -51, -129, -194, + -58, 50, 127, 51, -193, -131, -59, 12, -41, -59, + -59, 112, -104, -105, 236, 233, 239, 57, 59, 55, + -172, 82, 54, 57, 28, -164, -164, -165, 57, -165, + 28, -149, 29, 68, -154, 215, 60, -151, -151, -152, + 30, -152, -152, -152, -160, 59, -160, 60, 60, 52, + -123, -135, -134, -187, 135, 131, 138, 139, 133, 57, + 124, 28, 130, 132, 152, 129, -187, -118, -119, 126, + 22, 124, 28, 152, -186, 53, 158, 211, 158, 126, + -135, -110, 59, -39, 39, 112, -54, -40, 11, 99, + -124, -37, -35, 73, -65, -65, -194, -38, -139, 108, + 186, 146, 184, 180, 200, 191, 213, 182, 214, -136, + -139, -65, -65, -65, -65, 259, -87, 81, -39, 79, + -124, -65, -65, -97, 52, -98, -75, -77, -76, -193, + -2, -93, -123, -96, -123, -59, 55, 82, -46, -45, + 52, 53, -47, 52, -45, 42, 42, 124, 124, 124, + -96, -87, -39, -59, 233, 237, 238, -171, -172, -175, + -174, -123, -178, -165, -165, 54, -150, 52, -65, 56, + -152, -152, 57, 108, 56, 55, 56, 55, 56, 55, + -54, -134, -134, -54, -134, -123, -184, 262, -185, 57, + -123, -123, -123, -54, -113, -59, -41, -194, -65, -194, + -147, -147, -147, -156, -147, 174, -147, 174, -194, -194, + 19, 19, 19, 19, -193, -34, 255, -39, 55, 55, + 27, -97, 55, -194, -194, -194, 55, 112, -194, 55, + -87, -102, -39, -39, 54, -39, -193, -193, -193, -194, + -91, 56, 55, -147, -94, -123, -158, 211, 9, -151, + 59, -151, 60, 60, -135, 26, -183, -182, -124, 54, + 53, -85, 13, -151, 57, -65, -65, -65, -65, -65, + -194, 59, -65, -65, 28, -77, 34, -2, -193, -123, + -123, -123, -91, -94, -94, -94, -94, -132, -177, -176, + 53, 134, 66, -174, 56, 55, -159, 130, 28, 129, + -68, -152, -152, 56, 56, -193, 55, 82, -94, -54, + -86, 14, 16, -194, -194, -194, -194, -33, 92, 262, + -194, -194, 9, -75, -2, 112, 56, -194, -194, -194, + -58, -176, 57, -166, 82, 59, 141, -123, -148, 66, + 28, 28, -179, -180, 152, -182, -172, 56, -39, -74, + -194, 260, 49, 263, -98, -194, -123, 60, -54, 59, + -194, 55, -123, -186, 39, 261, 264, 54, -180, 34, + -184, 39, -94, 154, 262, 56, 155, 263, -189, -190, + 52, -193, 264, -190, 52, 10, 9, -65, 151, -188, + 142, 137, 140, 30, -188, -194, -194, 136, 29, 68, } var yyDef = [...]int{ 23, -2, 2, -2, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, - 21, 22, 556, 0, 313, 313, 313, 313, 313, 313, - 0, 627, 610, 0, 0, 0, 0, -2, 300, 301, - 0, 303, 304, 847, 847, 847, 847, 847, 0, 0, - 847, 0, 35, 36, 845, 1, 3, 564, 0, 0, - 317, 320, 315, 0, 610, 610, 0, 0, 65, 66, - 0, 0, 0, 836, 0, 608, 608, 608, 628, 629, - 632, 633, 735, 736, 737, 738, 739, 740, 741, 742, - 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, - 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, - 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, - 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, - 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, - 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, - 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, - 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, - 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, - 833, 834, 835, 837, 838, 839, 840, 841, 842, 843, - 844, 0, 0, 0, 611, 0, 606, 0, 606, 606, - 606, 0, 255, 385, 636, 637, 836, 0, 0, 0, - 848, 0, 848, 267, 848, 848, 270, 848, 0, 848, - 0, 277, 0, 282, 848, 297, 298, 287, 299, 302, - 305, 306, 307, 308, 309, 847, 847, 312, 29, 568, - 0, 0, 556, 31, 0, 313, 318, 319, 323, 321, - 322, 314, 0, 331, 335, 0, 394, 0, 399, 401, - -2, -2, 0, 436, 437, 438, 439, 440, 0, 0, - 0, 0, 0, 0, 0, 0, 464, 465, 466, 467, - 541, 542, 543, 544, 545, 546, 547, 548, 403, 404, - 538, 588, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 529, 0, 500, 500, 500, 500, 500, 500, 500, - 500, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 44, 46, 385, 50, 0, 827, 592, -2, - -2, 0, 0, 634, 635, -2, 745, -2, 640, 641, - 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, - 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, - 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, - 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, - 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, - 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, - 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, - 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, - 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, - 732, 733, 734, 0, 0, 84, 0, 82, 0, 848, - 0, 0, 0, 0, 0, 0, 848, 0, 0, 0, - 0, 246, 0, 0, 0, 0, 0, 0, 0, 254, - 0, 256, 848, 848, 259, 849, 850, 848, 848, 848, - 0, 848, 848, 266, 268, 269, 271, 848, 848, 273, - 0, 290, 288, 289, 284, 285, 0, 279, 280, 283, - 310, 311, 30, 846, 24, 0, 0, 565, 0, 557, - 558, 561, 564, 29, 320, 0, 325, 324, 316, 0, - 332, 0, 0, 0, 336, 0, 338, 339, 0, 397, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 421, - 422, 423, 424, 425, 426, 427, 400, 0, 414, 0, - 0, 0, 456, 457, 458, 459, 460, 461, 462, 0, - 327, 29, 0, 434, 0, 0, 0, 0, 0, 0, - 0, 0, 323, 0, 530, 0, 484, 492, 0, 485, - 493, 486, 494, 487, 0, 488, 495, 489, 496, 490, - 491, 497, 0, 0, 0, 327, 0, 0, 48, 0, - 384, 0, 342, 344, 345, 346, -2, 0, 368, -2, - 0, 0, 0, 42, 43, 0, 0, 0, 0, 51, - 827, 53, 54, 0, 0, 0, 162, 601, 602, 603, - 599, 206, 0, 0, 150, 146, 90, 91, 92, 139, - 94, 139, 139, 139, 139, 159, 159, 159, 159, 122, - 123, 124, 125, 126, 0, 0, 109, 139, 139, 139, - 113, 129, 130, 131, 132, 133, 134, 135, 136, 95, - 96, 97, 98, 99, 100, 101, 102, 103, 141, 141, - 141, 143, 143, 630, 68, 0, 848, 0, 848, 80, - 0, 220, 0, 0, 0, 0, 0, 0, 0, 0, - 249, 607, 0, 848, 252, 253, 386, 638, 639, 257, - 258, 260, 261, 262, 263, 264, 265, 272, 276, 0, - 293, 0, 0, 278, 0, 569, 0, 0, 0, 0, - 0, 560, 562, 563, 568, 32, 323, 0, 549, 0, - 0, 0, 326, 27, 395, 396, 398, 415, 0, 417, - 419, 337, 333, 0, 539, -2, 405, 406, 430, 431, - 432, 0, 0, 0, 0, 428, 410, 0, 441, 442, - 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, - 455, 514, 515, 0, 453, 454, 463, 0, 0, 328, - 329, 433, 0, 587, 29, 0, 0, 0, 0, 438, - 541, 0, 438, 541, 0, 0, 0, 536, 533, 0, - 0, 538, 0, 501, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 383, 0, 0, 0, 0, 0, 0, - 373, 0, 0, 376, 0, 0, 0, 0, 367, 0, - 0, 388, 795, 369, 0, 371, 372, 392, 0, 392, - 45, 392, 47, 0, 387, 593, 52, 0, 0, 57, - 58, 594, 595, 596, 597, 0, 81, 207, 209, 212, - 213, 214, 85, 86, 87, 0, 0, 194, 0, 0, - 188, 188, 0, 186, 187, 83, 153, 151, 0, 148, - 147, 93, 0, 159, 159, 116, 117, 162, 0, 162, - 162, 162, 0, 0, 110, 111, 112, 104, 0, 105, - 106, 107, 0, 108, 0, 0, 848, 70, 609, 71, - 847, 0, 0, 622, 221, 612, 613, 614, 615, 616, - 617, 618, 619, 620, 621, 0, 72, 223, 225, 224, - 228, 0, 0, 0, 247, 848, 251, 290, 275, 0, - 0, 291, 292, 281, 0, 566, 567, 0, 559, 25, - 0, 604, 605, 550, 551, 340, 416, 418, 420, 0, - 327, 407, 428, 411, 0, 408, 0, 0, 402, 468, - 0, 0, 435, -2, 471, 472, 0, 0, 0, 0, - 0, 507, 0, 0, 508, 0, 556, 0, 534, 0, - 0, 483, 0, 502, 0, 0, 503, 504, 505, 506, - 581, 0, 0, -2, 0, 0, 392, 589, 0, 343, - 362, 364, 0, 359, 374, 375, 377, 0, 379, 0, - 381, 382, 347, 349, 350, 0, 0, 0, 0, 370, - 556, 0, 392, 40, 41, 0, 55, 56, 0, 0, - 62, 163, 164, 0, 210, 0, 0, 0, 181, 188, - 188, 184, 189, 185, 0, 155, 0, 152, 89, 149, - 0, 162, 162, 118, 0, 119, 120, 121, 0, 137, - 0, 0, 0, 0, 631, 69, 215, 847, 230, 231, - 232, 233, 234, 235, 236, 237, 238, 239, 240, 847, - 0, 847, 623, 624, 625, 626, 0, 75, 0, 0, - 0, 0, 0, 250, 293, 294, 295, 570, 0, 26, - 392, 0, 334, 540, 0, 409, 0, 429, 412, 469, - 330, 0, 139, 139, 519, 139, 143, 522, 139, 524, - 139, 527, 0, 0, 0, 0, 0, 0, 0, 531, - 482, 537, 0, 539, 0, 0, 33, 0, 581, 571, - 583, 585, 0, 29, 0, 577, 0, 354, 556, 0, - 0, 356, 363, 0, 0, 357, 0, 358, 378, 380, - 0, 0, 0, 0, 564, 393, 39, 59, 60, 61, - 208, 211, 0, 190, 139, 193, 182, 183, 0, 157, - 0, 154, 140, 114, 115, 160, 161, 159, 0, 159, - 0, 144, 0, 848, 216, 217, 218, 219, 0, 222, - 0, 73, 74, 0, 0, 227, 248, 274, 552, 341, - 470, 413, 473, 516, 159, 520, 521, 523, 525, 526, - 528, 475, 474, 0, 0, 0, 0, 0, 0, 0, - 535, 0, 0, 0, 34, 0, 586, -2, 0, 0, - 0, 49, 0, 564, 590, 591, 360, 0, 365, 0, - 0, 0, 368, 38, 173, 0, 192, 0, 352, 165, - 158, 0, 162, 138, 162, 0, 0, 67, 0, 76, - 77, 0, 0, 0, 554, 0, 517, 518, 0, 0, - 0, 0, 509, 481, 532, 0, 0, 0, 584, 0, - -2, 0, 579, 578, 355, 37, 0, 0, 0, 0, - 388, 172, 174, 0, 179, 0, 191, 0, 0, 170, - 0, 167, 169, 156, 127, 128, 142, 145, 0, 0, - 0, 0, 229, 28, 0, 0, 476, 478, 477, 479, - 0, 0, 0, 498, 499, 0, 574, 29, 0, 361, - 389, 390, 391, 351, 175, 176, 0, 180, 178, 0, - 353, 88, 0, 166, 168, 0, 242, 0, 78, 79, - 72, 555, 553, 480, 0, 0, 0, 582, -2, 580, - 177, 0, 171, 241, 0, 0, 75, 510, 0, 513, - 0, 243, 0, 226, 511, 0, 0, 0, 195, 0, - 0, 196, 197, 0, 0, 512, 198, 0, 0, 0, - 0, 0, 199, 201, 202, 0, 0, 200, 244, 245, - 203, 204, 205, + 21, 22, 560, 0, 317, 317, 317, 317, 317, 317, + 0, 631, 614, 0, 0, 0, 0, -2, 304, 305, + 0, 307, 308, 932, 932, 932, 932, 932, 0, 0, + 932, 0, 35, 36, 930, 1, 3, 568, 0, 0, + 321, 324, 319, 0, 614, 614, 0, 0, 65, 66, + 0, 0, 0, 919, 0, 612, 612, 612, 632, 633, + 636, 637, 761, 762, 763, 764, 765, 766, 767, 768, + 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, + 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, + 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, + 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, + 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, + 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, + 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, + 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, + 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, + 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, + 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, + 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, + 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, + 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, + 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, + 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, + 0, 0, 0, 615, 0, 610, 0, 610, 610, 610, + 0, 256, 389, 640, 641, 919, 0, 0, 0, 933, + 0, 933, 268, 933, 933, 271, 933, 0, 933, 0, + 278, 0, 0, 284, 933, 301, 302, 289, 303, 306, + 309, 310, 311, 312, 313, 932, 932, 316, 29, 572, + 0, 0, 560, 31, 0, 317, 322, 323, 327, 325, + 326, 318, 0, 335, 339, 0, 398, 0, 403, 405, + -2, -2, 0, 440, 441, 442, 443, 444, 0, 0, + 0, 0, 0, 0, 0, 0, 468, 469, 470, 471, + 545, 546, 547, 548, 549, 550, 551, 552, 407, 408, + 542, 592, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 533, 0, 504, 504, 504, 504, 504, 504, 504, + 504, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 44, 46, 389, 50, 0, 908, 596, -2, + -2, 0, 0, 638, 639, -2, 774, -2, 644, 645, + 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, + 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, + 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, + 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, + 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, + 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, + 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, + 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, + 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, + 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, + 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, + 756, 757, 758, 759, 760, 0, 0, 84, 0, 82, + 0, 933, 0, 0, 0, 0, 0, 0, 933, 0, + 0, 0, 0, 247, 0, 0, 0, 0, 0, 0, + 0, 255, 0, 257, 933, 933, 260, 934, 935, 933, + 933, 933, 0, 933, 933, 267, 269, 270, 272, 933, + 933, 274, 0, 292, 290, 291, 286, 287, 0, 298, + 281, 282, 285, 314, 315, 30, 931, 24, 0, 0, + 569, 0, 561, 562, 565, 568, 29, 324, 0, 329, + 328, 320, 0, 336, 0, 0, 0, 340, 0, 342, + 343, 0, 401, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 425, 426, 427, 428, 429, 430, 431, 404, + 0, 418, 0, 0, 0, 460, 461, 462, 463, 464, + 465, 466, 0, 331, 29, 0, 438, 0, 0, 0, + 0, 0, 0, 0, 0, 327, 0, 534, 0, 488, + 496, 0, 489, 497, 490, 498, 491, 0, 492, 499, + 493, 500, 494, 495, 501, 0, 0, 0, 331, 0, + 0, 48, 0, 388, 0, 346, 348, 349, 350, -2, + 0, 372, -2, 0, 0, 0, 42, 43, 0, 0, + 0, 0, 51, 908, 53, 54, 0, 0, 0, 162, + 605, 606, 607, 603, 206, 0, 0, 150, 146, 90, + 91, 92, 139, 94, 139, 139, 139, 139, 159, 159, + 159, 159, 122, 123, 124, 125, 126, 0, 0, 109, + 139, 139, 139, 113, 129, 130, 131, 132, 133, 134, + 135, 136, 95, 96, 97, 98, 99, 100, 101, 102, + 103, 141, 141, 141, 143, 143, 634, 68, 0, 933, + 0, 933, 80, 0, 220, 0, 0, 0, 0, 0, + 0, 0, 0, 250, 611, 0, 933, 253, 254, 390, + 642, 643, 258, 259, 261, 262, 263, 264, 265, 266, + 273, 277, 0, 295, 0, 0, 279, 280, 0, 0, + 573, 0, 0, 0, 0, 0, 564, 566, 567, 572, + 32, 327, 0, 553, 0, 0, 0, 330, 27, 399, + 400, 402, 419, 0, 421, 423, 341, 337, 0, 543, + -2, 409, 410, 434, 435, 436, 0, 0, 0, 0, + 432, 414, 0, 445, 446, 447, 448, 449, 450, 451, + 452, 453, 454, 455, 456, 459, 518, 519, 0, 457, + 458, 467, 0, 0, 332, 333, 437, 0, 591, 29, + 0, 0, 0, 0, 442, 545, 0, 442, 545, 0, + 0, 0, 540, 537, 0, 0, 542, 0, 505, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 387, 0, + 0, 0, 0, 0, 0, 377, 0, 0, 380, 0, + 0, 0, 0, 371, 0, 0, 392, 853, 373, 0, + 375, 376, 396, 0, 396, 45, 396, 47, 0, 391, + 597, 52, 0, 0, 57, 58, 598, 599, 600, 601, + 0, 81, 207, 209, 212, 213, 214, 85, 86, 87, + 0, 0, 194, 0, 0, 188, 188, 0, 186, 187, + 83, 153, 151, 0, 148, 147, 93, 0, 159, 159, + 116, 117, 162, 0, 162, 162, 162, 0, 0, 110, + 111, 112, 104, 0, 105, 106, 107, 0, 108, 0, + 0, 933, 70, 613, 71, 932, 0, 0, 626, 221, + 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, + 0, 72, 223, 225, 224, 228, 0, 0, 0, 248, + 933, 252, 292, 276, 0, 0, 293, 294, 299, 283, + 0, 570, 571, 0, 563, 25, 0, 608, 609, 554, + 555, 344, 420, 422, 424, 0, 331, 411, 432, 415, + 0, 412, 0, 0, 406, 472, 0, 0, 439, -2, + 475, 476, 0, 0, 0, 0, 0, 511, 0, 0, + 512, 0, 560, 0, 538, 0, 0, 487, 0, 506, + 0, 0, 507, 508, 509, 510, 585, 0, 0, -2, + 0, 0, 396, 593, 0, 347, 366, 368, 0, 363, + 378, 379, 381, 0, 383, 0, 385, 386, 351, 353, + 354, 0, 0, 0, 0, 374, 560, 0, 396, 40, + 41, 0, 55, 56, 0, 0, 62, 163, 164, 0, + 210, 0, 0, 0, 181, 188, 188, 184, 189, 185, + 0, 155, 0, 152, 89, 149, 0, 162, 162, 118, + 0, 119, 120, 121, 0, 137, 0, 0, 0, 0, + 635, 69, 215, 932, 230, 231, 232, 233, 234, 235, + 236, 237, 238, 239, 240, 241, 932, 0, 932, 627, + 628, 629, 630, 0, 75, 0, 0, 0, 0, 0, + 251, 295, 296, 297, 574, 0, 26, 396, 0, 338, + 544, 0, 413, 0, 433, 416, 473, 334, 0, 139, + 139, 523, 139, 143, 526, 139, 528, 139, 531, 0, + 0, 0, 0, 0, 0, 0, 535, 486, 541, 0, + 543, 0, 0, 33, 0, 585, 575, 587, 589, 0, + 29, 0, 581, 0, 358, 560, 0, 0, 360, 367, + 0, 0, 361, 0, 362, 382, 384, 0, 0, 0, + 0, 568, 397, 39, 59, 60, 61, 208, 211, 0, + 190, 139, 193, 182, 183, 0, 157, 0, 154, 140, + 114, 115, 160, 161, 159, 0, 159, 0, 144, 0, + 933, 216, 217, 218, 219, 0, 222, 0, 73, 74, + 0, 0, 227, 249, 275, 556, 345, 474, 417, 477, + 520, 159, 524, 525, 527, 529, 530, 532, 479, 478, + 0, 0, 0, 0, 0, 0, 0, 539, 0, 0, + 0, 34, 0, 590, -2, 0, 0, 0, 49, 0, + 568, 594, 595, 364, 0, 369, 0, 0, 0, 372, + 38, 173, 0, 192, 0, 356, 165, 158, 0, 162, + 138, 162, 0, 0, 67, 0, 76, 77, 0, 0, + 0, 558, 0, 521, 522, 0, 0, 0, 0, 513, + 485, 536, 0, 0, 0, 588, 0, -2, 0, 583, + 582, 359, 37, 0, 0, 0, 0, 392, 172, 174, + 0, 179, 0, 191, 0, 0, 170, 0, 167, 169, + 156, 127, 128, 142, 145, 0, 0, 0, 0, 229, + 28, 0, 0, 480, 482, 481, 483, 0, 0, 0, + 502, 503, 0, 578, 29, 0, 365, 393, 394, 395, + 355, 175, 176, 0, 180, 178, 0, 357, 88, 0, + 166, 168, 0, 243, 0, 78, 79, 72, 559, 557, + 484, 0, 0, 0, 586, -2, 584, 177, 0, 171, + 242, 0, 0, 75, 514, 0, 517, 0, 244, 0, + 226, 515, 0, 0, 0, 195, 0, 0, 196, 197, + 0, 0, 516, 198, 0, 0, 0, 0, 0, 199, + 201, 202, 0, 0, 200, 245, 246, 203, 204, 205, } var yyTok1 = [...]int{ @@ -2623,7 +3223,7 @@ var yyTok1 = [...]int{ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 75, 3, 3, 3, 102, 94, 3, 54, 56, 99, 97, 55, 98, 112, 100, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 264, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 347, 83, 82, 84, 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, @@ -2658,10 +3258,25 @@ var yyTok2 = [...]int{ 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, - 259, 260, 261, 262, 263, + 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, + 269, 270, 271, 272, 273, 274, } var yyTok3 = [...]int{ - 0, + 57600, 275, 57601, 276, 57602, 277, 57603, 278, 57604, 279, + 57605, 280, 57606, 281, 57607, 282, 57608, 283, 57609, 284, + 57610, 285, 57611, 286, 57612, 287, 57613, 288, 57614, 289, + 57615, 290, 57616, 291, 57617, 292, 57618, 293, 57619, 294, + 57620, 295, 57621, 296, 57622, 297, 57623, 298, 57624, 299, + 57625, 300, 57626, 301, 57627, 302, 57628, 303, 57629, 304, + 57630, 305, 57631, 306, 57632, 307, 57633, 308, 57634, 309, + 57635, 310, 57636, 311, 57637, 312, 57638, 313, 57639, 314, + 57640, 315, 57641, 316, 57642, 317, 57643, 318, 57644, 319, + 57645, 320, 57646, 321, 57647, 322, 57648, 323, 57649, 324, + 57650, 325, 57651, 326, 57652, 327, 57653, 328, 57654, 329, + 57655, 330, 57656, 331, 57657, 332, 57658, 333, 57659, 334, + 57660, 335, 57661, 336, 57662, 337, 57663, 338, 57664, 339, + 57665, 340, 57666, 341, 57667, 342, 57668, 343, 57669, 344, + 57670, 345, 57671, 346, 0, } var yyErrorMessages = [...]struct { @@ -3003,35 +3618,35 @@ yydefault: case 1: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:317 +//line sql.y:323 { setParseTree(yylex, yyDollar[1].statement) } case 2: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:322 +//line sql.y:328 { } case 3: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:323 +//line sql.y:329 { } case 4: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:327 +//line sql.y:333 { yyVAL.statement = yyDollar[1].selStmt } case 23: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:349 +//line sql.y:355 { setParseTree(yylex, nil) } case 24: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:355 +//line sql.y:361 { sel := yyDollar[1].selStmt.(*Select) sel.OrderBy = yyDollar[2].orderBy @@ -3041,55 +3656,55 @@ yydefault: } case 25: yyDollar = yyS[yypt-6 : yypt+1] -//line sql.y:363 +//line sql.y:369 { yyVAL.selStmt = &Union{Type: yyDollar[2].str, Left: yyDollar[1].selStmt, Right: yyDollar[3].selStmt, OrderBy: yyDollar[4].orderBy, Limit: yyDollar[5].limit, Lock: yyDollar[6].str} } case 26: yyDollar = yyS[yypt-7 : yypt+1] -//line sql.y:367 +//line sql.y:373 { yyVAL.selStmt = &Select{Comments: Comments(yyDollar[2].bytes2), Cache: yyDollar[3].str, SelectExprs: SelectExprs{Nextval{Expr: yyDollar[5].expr}}, From: TableExprs{&AliasedTableExpr{Expr: yyDollar[7].tableName}}} } case 27: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:373 +//line sql.y:379 { yyVAL.statement = &Stream{Comments: Comments(yyDollar[2].bytes2), SelectExpr: yyDollar[3].selectExpr, Table: yyDollar[5].tableName} } case 28: yyDollar = yyS[yypt-10 : yypt+1] -//line sql.y:380 +//line sql.y:386 { yyVAL.selStmt = &Select{Comments: Comments(yyDollar[2].bytes2), Cache: yyDollar[3].str, Distinct: yyDollar[4].str, Hints: yyDollar[5].str, SelectExprs: yyDollar[6].selectExprs, From: yyDollar[7].tableExprs, Where: NewWhere(WhereStr, yyDollar[8].expr), GroupBy: GroupBy(yyDollar[9].exprs), Having: NewWhere(HavingStr, yyDollar[10].expr)} } case 29: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:386 +//line sql.y:392 { yyVAL.selStmt = yyDollar[1].selStmt } case 30: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:390 +//line sql.y:396 { yyVAL.selStmt = &ParenSelect{Select: yyDollar[2].selStmt} } case 31: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:396 +//line sql.y:402 { yyVAL.selStmt = yyDollar[1].selStmt } case 32: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:400 +//line sql.y:406 { yyVAL.selStmt = &ParenSelect{Select: yyDollar[2].selStmt} } case 33: yyDollar = yyS[yypt-7 : yypt+1] -//line sql.y:407 +//line sql.y:413 { // insert_data returns a *Insert pre-filled with Columns & Values ins := yyDollar[6].ins @@ -3103,7 +3718,7 @@ yydefault: } case 34: yyDollar = yyS[yypt-8 : yypt+1] -//line sql.y:419 +//line sql.y:425 { cols := make(Columns, 0, len(yyDollar[7].updateExprs)) vals := make(ValTuple, 0, len(yyDollar[8].updateExprs)) @@ -3115,192 +3730,192 @@ yydefault: } case 35: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:431 +//line sql.y:437 { yyVAL.str = InsertStr } case 36: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:435 +//line sql.y:441 { yyVAL.str = ReplaceStr } case 37: yyDollar = yyS[yypt-9 : yypt+1] -//line sql.y:441 +//line sql.y:447 { yyVAL.statement = &Update{Comments: Comments(yyDollar[2].bytes2), Ignore: yyDollar[3].str, TableExprs: yyDollar[4].tableExprs, Exprs: yyDollar[6].updateExprs, Where: NewWhere(WhereStr, yyDollar[7].expr), OrderBy: yyDollar[8].orderBy, Limit: yyDollar[9].limit} } case 38: yyDollar = yyS[yypt-8 : yypt+1] -//line sql.y:447 +//line sql.y:453 { yyVAL.statement = &Delete{Comments: Comments(yyDollar[2].bytes2), TableExprs: TableExprs{&AliasedTableExpr{Expr: yyDollar[4].tableName}}, Partitions: yyDollar[5].partitions, Where: NewWhere(WhereStr, yyDollar[6].expr), OrderBy: yyDollar[7].orderBy, Limit: yyDollar[8].limit} } case 39: yyDollar = yyS[yypt-7 : yypt+1] -//line sql.y:451 +//line sql.y:457 { yyVAL.statement = &Delete{Comments: Comments(yyDollar[2].bytes2), Targets: yyDollar[4].tableNames, TableExprs: yyDollar[6].tableExprs, Where: NewWhere(WhereStr, yyDollar[7].expr)} } case 40: yyDollar = yyS[yypt-6 : yypt+1] -//line sql.y:455 +//line sql.y:461 { yyVAL.statement = &Delete{Comments: Comments(yyDollar[2].bytes2), Targets: yyDollar[3].tableNames, TableExprs: yyDollar[5].tableExprs, Where: NewWhere(WhereStr, yyDollar[6].expr)} } case 41: yyDollar = yyS[yypt-6 : yypt+1] -//line sql.y:459 +//line sql.y:465 { yyVAL.statement = &Delete{Comments: Comments(yyDollar[2].bytes2), Targets: yyDollar[3].tableNames, TableExprs: yyDollar[5].tableExprs, Where: NewWhere(WhereStr, yyDollar[6].expr)} } case 42: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:464 +//line sql.y:470 { } case 43: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:465 +//line sql.y:471 { } case 44: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:469 +//line sql.y:475 { yyVAL.tableNames = TableNames{yyDollar[1].tableName} } case 45: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:473 +//line sql.y:479 { yyVAL.tableNames = append(yyVAL.tableNames, yyDollar[3].tableName) } case 46: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:479 +//line sql.y:485 { yyVAL.tableNames = TableNames{yyDollar[1].tableName} } case 47: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:483 +//line sql.y:489 { yyVAL.tableNames = append(yyVAL.tableNames, yyDollar[3].tableName) } case 48: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:488 +//line sql.y:494 { yyVAL.partitions = nil } case 49: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:492 +//line sql.y:498 { yyVAL.partitions = yyDollar[3].partitions } case 50: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:498 +//line sql.y:504 { yyVAL.statement = &Set{Comments: Comments(yyDollar[2].bytes2), Exprs: yyDollar[3].setExprs} } case 51: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:502 +//line sql.y:508 { yyVAL.statement = &Set{Comments: Comments(yyDollar[2].bytes2), Scope: yyDollar[3].str, Exprs: yyDollar[4].setExprs} } case 52: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:506 +//line sql.y:512 { yyVAL.statement = &Set{Comments: Comments(yyDollar[2].bytes2), Scope: yyDollar[3].str, Exprs: yyDollar[5].setExprs} } case 53: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:510 +//line sql.y:516 { yyVAL.statement = &Set{Comments: Comments(yyDollar[2].bytes2), Exprs: yyDollar[4].setExprs} } case 54: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:516 +//line sql.y:522 { yyVAL.setExprs = SetExprs{yyDollar[1].setExpr} } case 55: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:520 +//line sql.y:526 { yyVAL.setExprs = append(yyVAL.setExprs, yyDollar[3].setExpr) } case 56: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:526 +//line sql.y:532 { yyVAL.setExpr = &SetExpr{Name: NewColIdent(TransactionStr), Expr: NewStrVal([]byte(yyDollar[3].str))} } case 57: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:530 +//line sql.y:536 { yyVAL.setExpr = &SetExpr{Name: NewColIdent(TransactionStr), Expr: NewStrVal([]byte(TxReadWrite))} } case 58: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:534 +//line sql.y:540 { yyVAL.setExpr = &SetExpr{Name: NewColIdent(TransactionStr), Expr: NewStrVal([]byte(TxReadOnly))} } case 59: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:540 +//line sql.y:546 { yyVAL.str = IsolationLevelRepeatableRead } case 60: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:544 +//line sql.y:550 { yyVAL.str = IsolationLevelReadCommitted } case 61: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:548 +//line sql.y:554 { yyVAL.str = IsolationLevelReadUncommitted } case 62: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:552 +//line sql.y:558 { yyVAL.str = IsolationLevelSerializable } case 63: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:558 +//line sql.y:564 { yyVAL.str = SessionStr } case 64: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:562 +//line sql.y:568 { yyVAL.str = GlobalStr } case 65: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:568 +//line sql.y:574 { yyDollar[1].ddl.TableSpec = yyDollar[2].TableSpec yyVAL.statement = yyDollar[1].ddl } case 66: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:573 +//line sql.y:579 { // Create table [name] like [name] yyDollar[1].ddl.OptLike = yyDollar[2].optLike @@ -3308,139 +3923,139 @@ yydefault: } case 67: yyDollar = yyS[yypt-8 : yypt+1] -//line sql.y:579 +//line sql.y:585 { // Change this to an alter statement yyVAL.statement = &DDL{Action: AlterStr, Table: yyDollar[7].tableName} } case 68: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:584 +//line sql.y:590 { yyVAL.statement = &DDL{Action: CreateStr, Table: yyDollar[3].tableName.ToViewName()} } case 69: yyDollar = yyS[yypt-6 : yypt+1] -//line sql.y:588 +//line sql.y:594 { yyVAL.statement = &DDL{Action: CreateStr, Table: yyDollar[5].tableName.ToViewName()} } case 70: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:592 +//line sql.y:598 { yyVAL.statement = &DBDDL{Action: CreateStr, DBName: string(yyDollar[4].bytes)} } case 71: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:596 +//line sql.y:602 { yyVAL.statement = &DBDDL{Action: CreateStr, DBName: string(yyDollar[4].bytes)} } case 72: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:601 +//line sql.y:607 { yyVAL.colIdent = NewColIdent("") } case 73: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:605 +//line sql.y:611 { yyVAL.colIdent = yyDollar[2].colIdent } case 74: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:611 +//line sql.y:617 { yyVAL.colIdent = NewColIdent(string(yyDollar[1].bytes)) } case 75: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:616 +//line sql.y:622 { var v []VindexParam yyVAL.vindexParams = v } case 76: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:621 +//line sql.y:627 { yyVAL.vindexParams = yyDollar[2].vindexParams } case 77: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:627 +//line sql.y:633 { yyVAL.vindexParams = make([]VindexParam, 0, 4) yyVAL.vindexParams = append(yyVAL.vindexParams, yyDollar[1].vindexParam) } case 78: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:632 +//line sql.y:638 { yyVAL.vindexParams = append(yyVAL.vindexParams, yyDollar[3].vindexParam) } case 79: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:638 +//line sql.y:644 { yyVAL.vindexParam = VindexParam{Key: yyDollar[1].colIdent, Val: yyDollar[3].str} } case 80: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:644 +//line sql.y:650 { yyVAL.ddl = &DDL{Action: CreateStr, Table: yyDollar[4].tableName} setDDL(yylex, yyVAL.ddl) } case 81: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:651 +//line sql.y:657 { yyVAL.TableSpec = yyDollar[2].TableSpec yyVAL.TableSpec.Options = yyDollar[4].str } case 82: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:658 +//line sql.y:664 { yyVAL.optLike = &OptLike{LikeTable: yyDollar[2].tableName} } case 83: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:662 +//line sql.y:668 { yyVAL.optLike = &OptLike{LikeTable: yyDollar[3].tableName} } case 84: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:668 +//line sql.y:674 { yyVAL.TableSpec = &TableSpec{} yyVAL.TableSpec.AddColumn(yyDollar[1].columnDefinition) } case 85: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:673 +//line sql.y:679 { yyVAL.TableSpec.AddColumn(yyDollar[3].columnDefinition) } case 86: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:677 +//line sql.y:683 { yyVAL.TableSpec.AddIndex(yyDollar[3].indexDefinition) } case 87: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:681 +//line sql.y:687 { yyVAL.TableSpec.AddConstraint(yyDollar[3].constraintDefinition) } case 88: yyDollar = yyS[yypt-8 : yypt+1] -//line sql.y:687 +//line sql.y:693 { yyDollar[2].columnType.NotNull = yyDollar[3].boolVal yyDollar[2].columnType.Default = yyDollar[4].optVal @@ -3452,7 +4067,7 @@ yydefault: } case 89: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:698 +//line sql.y:704 { yyVAL.columnType = yyDollar[1].columnType yyVAL.columnType.Unsigned = yyDollar[2].boolVal @@ -3460,74 +4075,74 @@ yydefault: } case 93: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:709 +//line sql.y:715 { yyVAL.columnType = yyDollar[1].columnType yyVAL.columnType.Length = yyDollar[2].sqlVal } case 94: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:714 +//line sql.y:720 { yyVAL.columnType = yyDollar[1].columnType } case 95: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:720 +//line sql.y:726 { yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} } case 96: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:724 +//line sql.y:730 { yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} } case 97: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:728 +//line sql.y:734 { yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} } case 98: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:732 +//line sql.y:738 { yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} } case 99: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:736 +//line sql.y:742 { yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} } case 100: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:740 +//line sql.y:746 { yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} } case 101: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:744 +//line sql.y:750 { yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} } case 102: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:748 +//line sql.y:754 { yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} } case 103: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:752 +//line sql.y:758 { yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} } case 104: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:758 +//line sql.y:764 { yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} yyVAL.columnType.Length = yyDollar[2].LengthScaleOption.Length @@ -3535,7 +4150,7 @@ yydefault: } case 105: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:764 +//line sql.y:770 { yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} yyVAL.columnType.Length = yyDollar[2].LengthScaleOption.Length @@ -3543,7 +4158,7 @@ yydefault: } case 106: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:770 +//line sql.y:776 { yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} yyVAL.columnType.Length = yyDollar[2].LengthScaleOption.Length @@ -3551,7 +4166,7 @@ yydefault: } case 107: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:776 +//line sql.y:782 { yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} yyVAL.columnType.Length = yyDollar[2].LengthScaleOption.Length @@ -3559,7 +4174,7 @@ yydefault: } case 108: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:782 +//line sql.y:788 { yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} yyVAL.columnType.Length = yyDollar[2].LengthScaleOption.Length @@ -3567,206 +4182,206 @@ yydefault: } case 109: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:790 +//line sql.y:796 { yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} } case 110: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:794 +//line sql.y:800 { yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes), Length: yyDollar[2].sqlVal} } case 111: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:798 +//line sql.y:804 { yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes), Length: yyDollar[2].sqlVal} } case 112: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:802 +//line sql.y:808 { yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes), Length: yyDollar[2].sqlVal} } case 113: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:806 +//line sql.y:812 { yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} } case 114: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:812 +//line sql.y:818 { yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes), Length: yyDollar[2].sqlVal, Charset: yyDollar[3].str, Collate: yyDollar[4].str} } case 115: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:816 +//line sql.y:822 { yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes), Length: yyDollar[2].sqlVal, Charset: yyDollar[3].str, Collate: yyDollar[4].str} } case 116: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:820 +//line sql.y:826 { yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes), Length: yyDollar[2].sqlVal} } case 117: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:824 +//line sql.y:830 { yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes), Length: yyDollar[2].sqlVal} } case 118: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:828 +//line sql.y:834 { yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes), Charset: yyDollar[2].str, Collate: yyDollar[3].str} } case 119: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:832 +//line sql.y:838 { yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes), Charset: yyDollar[2].str, Collate: yyDollar[3].str} } case 120: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:836 +//line sql.y:842 { yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes), Charset: yyDollar[2].str, Collate: yyDollar[3].str} } case 121: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:840 +//line sql.y:846 { yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes), Charset: yyDollar[2].str, Collate: yyDollar[3].str} } case 122: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:844 +//line sql.y:850 { yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} } case 123: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:848 +//line sql.y:854 { yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} } case 124: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:852 +//line sql.y:858 { yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} } case 125: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:856 +//line sql.y:862 { yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} } case 126: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:860 +//line sql.y:866 { yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} } case 127: yyDollar = yyS[yypt-6 : yypt+1] -//line sql.y:864 +//line sql.y:870 { yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes), EnumValues: yyDollar[3].strs, Charset: yyDollar[5].str, Collate: yyDollar[6].str} } case 128: yyDollar = yyS[yypt-6 : yypt+1] -//line sql.y:869 +//line sql.y:875 { yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes), EnumValues: yyDollar[3].strs, Charset: yyDollar[5].str, Collate: yyDollar[6].str} } case 129: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:875 +//line sql.y:881 { yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} } case 130: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:879 +//line sql.y:885 { yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} } case 131: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:883 +//line sql.y:889 { yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} } case 132: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:887 +//line sql.y:893 { yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} } case 133: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:891 +//line sql.y:897 { yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} } case 134: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:895 +//line sql.y:901 { yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} } case 135: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:899 +//line sql.y:905 { yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} } case 136: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:903 +//line sql.y:909 { yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} } case 137: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:909 +//line sql.y:915 { yyVAL.strs = make([]string, 0, 4) yyVAL.strs = append(yyVAL.strs, "'"+string(yyDollar[1].bytes)+"'") } case 138: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:914 +//line sql.y:920 { yyVAL.strs = append(yyDollar[1].strs, "'"+string(yyDollar[3].bytes)+"'") } case 139: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:919 +//line sql.y:925 { yyVAL.sqlVal = nil } case 140: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:923 +//line sql.y:929 { yyVAL.sqlVal = NewIntVal(yyDollar[2].bytes) } case 141: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:928 +//line sql.y:934 { yyVAL.LengthScaleOption = LengthScaleOption{} } case 142: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:932 +//line sql.y:938 { yyVAL.LengthScaleOption = LengthScaleOption{ Length: NewIntVal(yyDollar[2].bytes), @@ -3775,13 +4390,13 @@ yydefault: } case 143: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:940 +//line sql.y:946 { yyVAL.LengthScaleOption = LengthScaleOption{} } case 144: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:944 +//line sql.y:950 { yyVAL.LengthScaleOption = LengthScaleOption{ Length: NewIntVal(yyDollar[2].bytes), @@ -3789,7 +4404,7 @@ yydefault: } case 145: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:950 +//line sql.y:956 { yyVAL.LengthScaleOption = LengthScaleOption{ Length: NewIntVal(yyDollar[2].bytes), @@ -3798,496 +4413,504 @@ yydefault: } case 146: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:958 +//line sql.y:964 { yyVAL.boolVal = BoolVal(false) } case 147: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:962 +//line sql.y:968 { yyVAL.boolVal = BoolVal(true) } case 148: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:967 +//line sql.y:973 { yyVAL.boolVal = BoolVal(false) } case 149: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:971 +//line sql.y:977 { yyVAL.boolVal = BoolVal(true) } case 150: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:977 +//line sql.y:983 { yyVAL.boolVal = BoolVal(false) } case 151: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:981 +//line sql.y:987 { yyVAL.boolVal = BoolVal(false) } case 152: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:985 +//line sql.y:991 { yyVAL.boolVal = BoolVal(true) } case 153: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:990 +//line sql.y:996 { yyVAL.optVal = nil } case 154: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:994 +//line sql.y:1000 { yyVAL.optVal = yyDollar[2].expr } case 155: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:999 +//line sql.y:1005 { yyVAL.optVal = nil } case 156: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1003 +//line sql.y:1009 { yyVAL.optVal = yyDollar[3].expr } case 157: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:1008 +//line sql.y:1014 { yyVAL.boolVal = BoolVal(false) } case 158: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1012 +//line sql.y:1018 { yyVAL.boolVal = BoolVal(true) } case 159: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:1017 +//line sql.y:1023 { yyVAL.str = "" } case 160: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1021 +//line sql.y:1027 { yyVAL.str = string(yyDollar[3].bytes) } case 161: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1025 +//line sql.y:1031 { yyVAL.str = string(yyDollar[3].bytes) } case 162: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:1030 +//line sql.y:1036 { yyVAL.str = "" } case 163: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1034 +//line sql.y:1040 { yyVAL.str = string(yyDollar[2].bytes) } case 164: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1038 +//line sql.y:1044 { yyVAL.str = string(yyDollar[2].bytes) } case 165: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:1043 +//line sql.y:1049 { yyVAL.colKeyOpt = colKeyNone } case 166: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1047 +//line sql.y:1053 { yyVAL.colKeyOpt = colKeyPrimary } case 167: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1051 +//line sql.y:1057 { yyVAL.colKeyOpt = colKey } case 168: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1055 +//line sql.y:1061 { yyVAL.colKeyOpt = colKeyUniqueKey } case 169: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1059 +//line sql.y:1065 { yyVAL.colKeyOpt = colKeyUnique } case 170: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:1064 +//line sql.y:1070 { yyVAL.sqlVal = nil } case 171: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1068 +//line sql.y:1074 { yyVAL.sqlVal = NewStrVal(yyDollar[2].bytes) } case 172: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:1074 +//line sql.y:1080 { yyVAL.indexDefinition = &IndexDefinition{Info: yyDollar[1].indexInfo, Columns: yyDollar[3].indexColumns, Options: yyDollar[5].indexOptions} } case 173: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:1078 +//line sql.y:1084 { yyVAL.indexDefinition = &IndexDefinition{Info: yyDollar[1].indexInfo, Columns: yyDollar[3].indexColumns} } case 174: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1084 +//line sql.y:1090 { yyVAL.indexOptions = []*IndexOption{yyDollar[1].indexOption} } case 175: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1088 +//line sql.y:1094 { yyVAL.indexOptions = append(yyVAL.indexOptions, yyDollar[2].indexOption) } case 176: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1094 +//line sql.y:1100 { yyVAL.indexOption = &IndexOption{Name: string(yyDollar[1].bytes), Using: string(yyDollar[2].bytes)} } case 177: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1098 +//line sql.y:1104 { // should not be string yyVAL.indexOption = &IndexOption{Name: string(yyDollar[1].bytes), Value: NewIntVal(yyDollar[3].bytes)} } case 178: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1103 +//line sql.y:1109 { yyVAL.indexOption = &IndexOption{Name: string(yyDollar[1].bytes), Value: NewStrVal(yyDollar[2].bytes)} } case 179: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:1109 +//line sql.y:1115 { yyVAL.str = "" } case 180: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1113 +//line sql.y:1119 { yyVAL.str = string(yyDollar[1].bytes) } case 181: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1119 +//line sql.y:1125 { yyVAL.indexInfo = &IndexInfo{Type: string(yyDollar[1].bytes) + " " + string(yyDollar[2].bytes), Name: NewColIdent("PRIMARY"), Primary: true, Unique: true} } case 182: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1123 +//line sql.y:1129 { yyVAL.indexInfo = &IndexInfo{Type: string(yyDollar[1].bytes) + " " + string(yyDollar[2].str), Name: NewColIdent(yyDollar[3].str), Spatial: true, Unique: false} } case 183: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1127 +//line sql.y:1133 { yyVAL.indexInfo = &IndexInfo{Type: string(yyDollar[1].bytes) + " " + string(yyDollar[2].str), Name: NewColIdent(yyDollar[3].str), Unique: true} } case 184: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1131 +//line sql.y:1137 { yyVAL.indexInfo = &IndexInfo{Type: string(yyDollar[1].bytes), Name: NewColIdent(yyDollar[2].str), Unique: true} } case 185: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1135 +//line sql.y:1141 { yyVAL.indexInfo = &IndexInfo{Type: string(yyDollar[1].str), Name: NewColIdent(yyDollar[2].str), Unique: false} } case 186: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1141 +//line sql.y:1147 { yyVAL.str = string(yyDollar[1].bytes) } case 187: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1145 +//line sql.y:1151 { yyVAL.str = string(yyDollar[1].bytes) } case 188: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:1150 +//line sql.y:1156 { yyVAL.str = "" } case 189: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1154 +//line sql.y:1160 { yyVAL.str = string(yyDollar[1].bytes) } case 190: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1160 +//line sql.y:1166 { yyVAL.indexColumns = []*IndexColumn{yyDollar[1].indexColumn} } case 191: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1164 +//line sql.y:1170 { yyVAL.indexColumns = append(yyVAL.indexColumns, yyDollar[3].indexColumn) } case 192: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1170 +//line sql.y:1176 { yyVAL.indexColumn = &IndexColumn{Column: yyDollar[1].colIdent, Length: yyDollar[2].sqlVal} } case 193: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1176 +//line sql.y:1182 { yyVAL.constraintDefinition = &ConstraintDefinition{Name: string(yyDollar[2].bytes), Details: yyDollar[3].constraintInfo} } case 194: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1180 +//line sql.y:1186 { yyVAL.constraintDefinition = &ConstraintDefinition{Details: yyDollar[1].constraintInfo} } case 195: yyDollar = yyS[yypt-10 : yypt+1] -//line sql.y:1187 +//line sql.y:1193 { yyVAL.constraintInfo = &ForeignKeyDefinition{Source: yyDollar[4].columns, ReferencedTable: yyDollar[7].tableName, ReferencedColumns: yyDollar[9].columns} } case 196: yyDollar = yyS[yypt-11 : yypt+1] -//line sql.y:1191 +//line sql.y:1197 { yyVAL.constraintInfo = &ForeignKeyDefinition{Source: yyDollar[4].columns, ReferencedTable: yyDollar[7].tableName, ReferencedColumns: yyDollar[9].columns, OnDelete: yyDollar[11].ReferenceAction} } case 197: yyDollar = yyS[yypt-11 : yypt+1] -//line sql.y:1195 +//line sql.y:1201 { yyVAL.constraintInfo = &ForeignKeyDefinition{Source: yyDollar[4].columns, ReferencedTable: yyDollar[7].tableName, ReferencedColumns: yyDollar[9].columns, OnUpdate: yyDollar[11].ReferenceAction} } case 198: yyDollar = yyS[yypt-12 : yypt+1] -//line sql.y:1199 +//line sql.y:1205 { yyVAL.constraintInfo = &ForeignKeyDefinition{Source: yyDollar[4].columns, ReferencedTable: yyDollar[7].tableName, ReferencedColumns: yyDollar[9].columns, OnDelete: yyDollar[11].ReferenceAction, OnUpdate: yyDollar[12].ReferenceAction} } case 199: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1205 +//line sql.y:1211 { yyVAL.ReferenceAction = yyDollar[3].ReferenceAction } case 200: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1211 +//line sql.y:1217 { yyVAL.ReferenceAction = yyDollar[3].ReferenceAction } case 201: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1217 +//line sql.y:1223 { yyVAL.ReferenceAction = Restrict } case 202: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1221 +//line sql.y:1227 { yyVAL.ReferenceAction = Cascade } case 203: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1225 +//line sql.y:1231 { yyVAL.ReferenceAction = NoAction } case 204: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1229 +//line sql.y:1235 { yyVAL.ReferenceAction = SetDefault } case 205: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1233 +//line sql.y:1239 { yyVAL.ReferenceAction = SetNull } case 206: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:1238 +//line sql.y:1244 { yyVAL.str = "" } case 207: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1242 +//line sql.y:1248 { yyVAL.str = " " + string(yyDollar[1].str) } case 208: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1246 +//line sql.y:1252 { yyVAL.str = string(yyDollar[1].str) + ", " + string(yyDollar[3].str) } case 209: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1254 +//line sql.y:1260 { yyVAL.str = yyDollar[1].str } case 210: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1258 +//line sql.y:1264 { yyVAL.str = yyDollar[1].str + " " + yyDollar[2].str } case 211: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1262 +//line sql.y:1268 { yyVAL.str = yyDollar[1].str + "=" + yyDollar[3].str } case 212: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1268 +//line sql.y:1274 { yyVAL.str = yyDollar[1].colIdent.String() } case 213: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1272 +//line sql.y:1278 { yyVAL.str = "'" + string(yyDollar[1].bytes) + "'" } case 214: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1276 +//line sql.y:1282 { yyVAL.str = string(yyDollar[1].bytes) } case 215: yyDollar = yyS[yypt-6 : yypt+1] -//line sql.y:1282 +//line sql.y:1288 { yyVAL.statement = &DDL{Action: AlterStr, Table: yyDollar[4].tableName} } case 216: yyDollar = yyS[yypt-7 : yypt+1] -//line sql.y:1286 +//line sql.y:1292 { yyVAL.statement = &DDL{Action: AlterStr, Table: yyDollar[4].tableName} } case 217: yyDollar = yyS[yypt-7 : yypt+1] -//line sql.y:1290 +//line sql.y:1296 { yyVAL.statement = &DDL{Action: AlterStr, Table: yyDollar[4].tableName} } case 218: yyDollar = yyS[yypt-7 : yypt+1] -//line sql.y:1294 +//line sql.y:1300 { // Change this to a rename statement yyVAL.statement = &DDL{Action: RenameStr, FromTables: TableNames{yyDollar[4].tableName}, ToTables: TableNames{yyDollar[7].tableName}} } case 219: yyDollar = yyS[yypt-7 : yypt+1] -//line sql.y:1299 +//line sql.y:1305 { // Rename an index can just be an alter yyVAL.statement = &DDL{Action: AlterStr, Table: yyDollar[4].tableName} } case 220: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:1304 +//line sql.y:1310 { yyVAL.statement = &DDL{Action: AlterStr, Table: yyDollar[3].tableName.ToViewName()} } case 221: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:1308 +//line sql.y:1314 { yyVAL.statement = &DDL{Action: AlterStr, Table: yyDollar[4].tableName, PartitionSpec: yyDollar[5].partSpec} } case 222: yyDollar = yyS[yypt-7 : yypt+1] -//line sql.y:1312 +//line sql.y:1318 { - yyVAL.statement = &DDL{Action: CreateVindexStr, VindexSpec: &VindexSpec{ - Name: yyDollar[5].colIdent, - Type: yyDollar[6].colIdent, - Params: yyDollar[7].vindexParams, - }} + yyVAL.statement = &DDL{ + Action: CreateVindexStr, + Table: yyDollar[5].tableName, + VindexSpec: &VindexSpec{ + Name: NewColIdent(yyDollar[5].tableName.Name.String()), + Type: yyDollar[6].colIdent, + Params: yyDollar[7].vindexParams, + }, + } } case 223: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:1320 +//line sql.y:1330 { - yyVAL.statement = &DDL{Action: DropVindexStr, VindexSpec: &VindexSpec{ - Name: yyDollar[5].colIdent, - }} + yyVAL.statement = &DDL{ + Action: DropVindexStr, + Table: yyDollar[5].tableName, + VindexSpec: &VindexSpec{ + Name: NewColIdent(yyDollar[5].tableName.Name.String()), + }, + } } case 224: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:1326 +//line sql.y:1340 { yyVAL.statement = &DDL{Action: AddVschemaTableStr, Table: yyDollar[5].tableName} } case 225: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:1330 +//line sql.y:1344 { yyVAL.statement = &DDL{Action: DropVschemaTableStr, Table: yyDollar[5].tableName} } case 226: yyDollar = yyS[yypt-12 : yypt+1] -//line sql.y:1334 +//line sql.y:1348 { yyVAL.statement = &DDL{ Action: AddColVindexStr, @@ -4302,7 +4925,7 @@ yydefault: } case 227: yyDollar = yyS[yypt-7 : yypt+1] -//line sql.y:1347 +//line sql.y:1361 { yyVAL.statement = &DDL{ Action: DropColVindexStr, @@ -4314,13 +4937,13 @@ yydefault: } case 228: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:1357 +//line sql.y:1371 { yyVAL.statement = &DDL{Action: AddSequenceStr, Table: yyDollar[5].tableName} } case 229: yyDollar = yyS[yypt-9 : yypt+1] -//line sql.y:1361 +//line sql.y:1375 { yyVAL.statement = &DDL{ Action: AddAutoIncStr, @@ -4331,59 +4954,59 @@ yydefault: }, } } - case 241: + case 242: yyDollar = yyS[yypt-7 : yypt+1] -//line sql.y:1387 +//line sql.y:1402 { yyVAL.partSpec = &PartitionSpec{Action: ReorganizeStr, Name: yyDollar[3].colIdent, Definitions: yyDollar[6].partDefs} } - case 242: + case 243: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1393 +//line sql.y:1408 { yyVAL.partDefs = []*PartitionDefinition{yyDollar[1].partDef} } - case 243: + case 244: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1397 +//line sql.y:1412 { yyVAL.partDefs = append(yyDollar[1].partDefs, yyDollar[3].partDef) } - case 244: + case 245: yyDollar = yyS[yypt-8 : yypt+1] -//line sql.y:1403 +//line sql.y:1418 { yyVAL.partDef = &PartitionDefinition{Name: yyDollar[2].colIdent, Limit: yyDollar[7].expr} } - case 245: + case 246: yyDollar = yyS[yypt-8 : yypt+1] -//line sql.y:1407 +//line sql.y:1422 { yyVAL.partDef = &PartitionDefinition{Name: yyDollar[2].colIdent, Maxvalue: true} } - case 246: + case 247: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1413 +//line sql.y:1428 { yyVAL.statement = yyDollar[3].ddl } - case 247: + case 248: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1419 +//line sql.y:1434 { yyVAL.ddl = &DDL{Action: RenameStr, FromTables: TableNames{yyDollar[1].tableName}, ToTables: TableNames{yyDollar[3].tableName}} } - case 248: + case 249: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:1423 +//line sql.y:1438 { yyVAL.ddl = yyDollar[1].ddl yyVAL.ddl.FromTables = append(yyVAL.ddl.FromTables, yyDollar[3].tableName) yyVAL.ddl.ToTables = append(yyVAL.ddl.ToTables, yyDollar[5].tableName) } - case 249: + case 250: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:1431 +//line sql.y:1446 { var exists bool if yyDollar[3].byt != 0 { @@ -4391,16 +5014,16 @@ yydefault: } yyVAL.statement = &DDL{Action: DropStr, FromTables: yyDollar[4].tableNames, IfExists: exists} } - case 250: + case 251: yyDollar = yyS[yypt-6 : yypt+1] -//line sql.y:1439 +//line sql.y:1454 { // Change this to an alter statement yyVAL.statement = &DDL{Action: AlterStr, Table: yyDollar[5].tableName} } - case 251: + case 252: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:1444 +//line sql.y:1459 { var exists bool if yyDollar[3].byt != 0 { @@ -4408,148 +5031,148 @@ yydefault: } yyVAL.statement = &DDL{Action: DropStr, FromTables: TableNames{yyDollar[4].tableName.ToViewName()}, IfExists: exists} } - case 252: + case 253: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:1452 +//line sql.y:1467 { yyVAL.statement = &DBDDL{Action: DropStr, DBName: string(yyDollar[4].bytes)} } - case 253: + case 254: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:1456 +//line sql.y:1471 { yyVAL.statement = &DBDDL{Action: DropStr, DBName: string(yyDollar[4].bytes)} } - case 254: + case 255: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1462 +//line sql.y:1477 { yyVAL.statement = &DDL{Action: TruncateStr, Table: yyDollar[3].tableName} } - case 255: + case 256: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1466 +//line sql.y:1481 { yyVAL.statement = &DDL{Action: TruncateStr, Table: yyDollar[2].tableName} } - case 256: + case 257: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1471 +//line sql.y:1486 { yyVAL.statement = &DDL{Action: AlterStr, Table: yyDollar[3].tableName} } - case 257: + case 258: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:1477 +//line sql.y:1492 { yyVAL.statement = &Show{Type: string(yyDollar[2].bytes) + " " + string(yyDollar[3].bytes)} } - case 258: + case 259: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:1482 +//line sql.y:1497 { yyVAL.statement = &Show{Type: CharsetStr} } - case 259: + case 260: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1486 +//line sql.y:1501 { yyVAL.statement = &Show{Type: string(yyDollar[2].bytes)} } - case 260: - yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:1490 - { - yyVAL.statement = &Show{Type: string(yyDollar[2].bytes) + " " + string(yyDollar[3].bytes)} - } case 261: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:1495 +//line sql.y:1505 { yyVAL.statement = &Show{Type: string(yyDollar[2].bytes) + " " + string(yyDollar[3].bytes)} } case 262: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:1499 +//line sql.y:1510 { yyVAL.statement = &Show{Type: string(yyDollar[2].bytes) + " " + string(yyDollar[3].bytes)} } case 263: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:1503 +//line sql.y:1514 { - yyVAL.statement = &Show{Type: string(yyDollar[2].bytes) + " " + string(yyDollar[3].bytes), Table: yyDollar[4].tableName} + yyVAL.statement = &Show{Type: string(yyDollar[2].bytes) + " " + string(yyDollar[3].bytes)} } case 264: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:1507 +//line sql.y:1518 { - yyVAL.statement = &Show{Type: string(yyDollar[2].bytes) + " " + string(yyDollar[3].bytes)} + yyVAL.statement = &Show{Type: string(yyDollar[2].bytes) + " " + string(yyDollar[3].bytes), Table: yyDollar[4].tableName} } case 265: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:1511 +//line sql.y:1522 { yyVAL.statement = &Show{Type: string(yyDollar[2].bytes) + " " + string(yyDollar[3].bytes)} } case 266: - yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1515 + yyDollar = yyS[yypt-4 : yypt+1] +//line sql.y:1526 { - yyVAL.statement = &Show{Type: string(yyDollar[2].bytes)} + yyVAL.statement = &Show{Type: string(yyDollar[2].bytes) + " " + string(yyDollar[3].bytes)} } case 267: - yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1519 + yyDollar = yyS[yypt-3 : yypt+1] +//line sql.y:1530 { yyVAL.statement = &Show{Type: string(yyDollar[2].bytes)} } case 268: - yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1523 + yyDollar = yyS[yypt-2 : yypt+1] +//line sql.y:1534 { yyVAL.statement = &Show{Type: string(yyDollar[2].bytes)} } case 269: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1527 +//line sql.y:1538 { yyVAL.statement = &Show{Type: string(yyDollar[2].bytes)} } case 270: - yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1531 + yyDollar = yyS[yypt-3 : yypt+1] +//line sql.y:1542 { yyVAL.statement = &Show{Type: string(yyDollar[2].bytes)} } case 271: - yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1535 + yyDollar = yyS[yypt-2 : yypt+1] +//line sql.y:1546 { yyVAL.statement = &Show{Type: string(yyDollar[2].bytes)} } case 272: + yyDollar = yyS[yypt-3 : yypt+1] +//line sql.y:1550 + { + yyVAL.statement = &Show{Type: string(yyDollar[2].bytes)} + } + case 273: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:1539 +//line sql.y:1554 { yyVAL.statement = &Show{Scope: yyDollar[2].str, Type: string(yyDollar[3].bytes)} } - case 273: + case 274: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1543 +//line sql.y:1558 { yyVAL.statement = &Show{Type: string(yyDollar[2].bytes)} } - case 274: + case 275: yyDollar = yyS[yypt-7 : yypt+1] -//line sql.y:1547 +//line sql.y:1562 { showTablesOpt := &ShowTablesOpt{Full: yyDollar[2].str, DbName: yyDollar[6].str, Filter: yyDollar[7].showFilter} yyVAL.statement = &Show{Type: string(yyDollar[3].str), ShowTablesOpt: showTablesOpt, OnTable: yyDollar[5].tableName} } - case 275: + case 276: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:1552 +//line sql.y:1567 { // this is ugly, but I couldn't find a better way for now if yyDollar[3].str == "processlist" { @@ -4559,626 +5182,645 @@ yydefault: yyVAL.statement = &Show{Type: yyDollar[3].str, ShowTablesOpt: showTablesOpt} } } - case 276: + case 277: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:1562 +//line sql.y:1577 { yyVAL.statement = &Show{Scope: yyDollar[2].str, Type: string(yyDollar[3].bytes)} } - case 277: + case 278: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1566 +//line sql.y:1581 { yyVAL.statement = &Show{Type: string(yyDollar[2].bytes)} } - case 278: + case 279: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:1570 +//line sql.y:1585 { // Cannot dereference $4 directly, or else the parser stackcannot be pooled. See yyParsePooled showCollationFilterOpt := yyDollar[4].expr yyVAL.statement = &Show{Type: string(yyDollar[2].bytes), ShowCollationFilterOpt: &showCollationFilterOpt} } - case 279: + case 280: + yyDollar = yyS[yypt-4 : yypt+1] +//line sql.y:1591 + { + showTablesOpt := &ShowTablesOpt{Filter: yyDollar[4].showFilter} + yyVAL.statement = &Show{Scope: string(yyDollar[2].bytes), Type: string(yyDollar[3].bytes), ShowTablesOpt: showTablesOpt} + } + case 281: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1576 +//line sql.y:1596 { yyVAL.statement = &Show{Type: string(yyDollar[2].bytes) + " " + string(yyDollar[3].bytes)} } - case 280: + case 282: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1580 +//line sql.y:1600 { yyVAL.statement = &Show{Type: string(yyDollar[2].bytes) + " " + string(yyDollar[3].bytes)} } - case 281: + case 283: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:1584 +//line sql.y:1604 { yyVAL.statement = &Show{Type: string(yyDollar[2].bytes) + " " + string(yyDollar[3].bytes), OnTable: yyDollar[5].tableName} } - case 282: + case 284: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1588 +//line sql.y:1608 { yyVAL.statement = &Show{Type: string(yyDollar[2].bytes)} } - case 283: + case 285: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1602 +//line sql.y:1622 { yyVAL.statement = &Show{Type: string(yyDollar[2].bytes)} } - case 284: + case 286: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1608 +//line sql.y:1628 { yyVAL.str = string(yyDollar[1].bytes) } - case 285: + case 287: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1612 +//line sql.y:1632 { yyVAL.str = string(yyDollar[1].bytes) } - case 286: + case 288: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:1618 +//line sql.y:1638 { yyVAL.str = "" } - case 287: + case 289: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1622 +//line sql.y:1642 { yyVAL.str = "full " } - case 288: + case 290: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1628 +//line sql.y:1648 { yyVAL.str = string(yyDollar[1].bytes) } - case 289: + case 291: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1632 +//line sql.y:1652 { yyVAL.str = string(yyDollar[1].bytes) } - case 290: + case 292: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:1638 +//line sql.y:1658 { yyVAL.str = "" } - case 291: + case 293: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1642 +//line sql.y:1662 { yyVAL.str = yyDollar[2].tableIdent.v } - case 292: + case 294: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1646 +//line sql.y:1666 { yyVAL.str = yyDollar[2].tableIdent.v } - case 293: + case 295: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:1652 +//line sql.y:1672 { yyVAL.showFilter = nil } - case 294: + case 296: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1656 +//line sql.y:1676 { yyVAL.showFilter = &ShowFilter{Like: string(yyDollar[2].bytes)} } - case 295: + case 297: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1660 +//line sql.y:1680 { yyVAL.showFilter = &ShowFilter{Filter: yyDollar[2].expr} } - case 296: + case 298: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:1666 +//line sql.y:1686 + { + yyVAL.showFilter = nil + } + case 299: + yyDollar = yyS[yypt-2 : yypt+1] +//line sql.y:1690 + { + yyVAL.showFilter = &ShowFilter{Like: string(yyDollar[2].bytes)} + } + case 300: + yyDollar = yyS[yypt-0 : yypt+1] +//line sql.y:1696 { yyVAL.str = "" } - case 297: + case 301: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1670 +//line sql.y:1700 { yyVAL.str = SessionStr } - case 298: + case 302: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1674 +//line sql.y:1704 { yyVAL.str = GlobalStr } - case 299: + case 303: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1680 +//line sql.y:1710 { yyVAL.statement = &Use{DBName: yyDollar[2].tableIdent} } - case 300: + case 304: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1684 +//line sql.y:1714 { yyVAL.statement = &Use{DBName: TableIdent{v: ""}} } - case 301: + case 305: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1690 +//line sql.y:1720 { yyVAL.statement = &Begin{} } - case 302: + case 306: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1694 +//line sql.y:1724 { yyVAL.statement = &Begin{} } - case 303: + case 307: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1700 +//line sql.y:1730 { yyVAL.statement = &Commit{} } - case 304: + case 308: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1706 +//line sql.y:1736 { yyVAL.statement = &Rollback{} } - case 305: + case 309: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1712 +//line sql.y:1742 { yyVAL.statement = &OtherRead{} } - case 306: + case 310: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1716 +//line sql.y:1746 { yyVAL.statement = &OtherRead{} } - case 307: + case 311: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1720 +//line sql.y:1750 { yyVAL.statement = &OtherRead{} } - case 308: + case 312: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1724 +//line sql.y:1754 { yyVAL.statement = &OtherAdmin{} } - case 309: + case 313: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1728 +//line sql.y:1758 { yyVAL.statement = &OtherAdmin{} } - case 310: + case 314: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1732 +//line sql.y:1762 { yyVAL.statement = &OtherAdmin{} } - case 311: + case 315: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1736 +//line sql.y:1766 { yyVAL.statement = &OtherAdmin{} } - case 312: + case 316: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1742 +//line sql.y:1772 { yyVAL.statement = &DDL{Action: FlushStr} } - case 313: + case 317: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:1746 +//line sql.y:1776 { setAllowComments(yylex, true) } - case 314: + case 318: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1750 +//line sql.y:1780 { yyVAL.bytes2 = yyDollar[2].bytes2 setAllowComments(yylex, false) } - case 315: + case 319: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:1756 +//line sql.y:1786 { yyVAL.bytes2 = nil } - case 316: + case 320: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1760 +//line sql.y:1790 { yyVAL.bytes2 = append(yyDollar[1].bytes2, yyDollar[2].bytes) } - case 317: + case 321: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1766 +//line sql.y:1796 { yyVAL.str = UnionStr } - case 318: + case 322: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1770 +//line sql.y:1800 { yyVAL.str = UnionAllStr } - case 319: + case 323: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1774 +//line sql.y:1804 { yyVAL.str = UnionDistinctStr } - case 320: + case 324: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:1779 +//line sql.y:1809 { yyVAL.str = "" } - case 321: + case 325: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1783 +//line sql.y:1813 { yyVAL.str = SQLNoCacheStr } - case 322: + case 326: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1787 +//line sql.y:1817 { yyVAL.str = SQLCacheStr } - case 323: + case 327: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:1792 +//line sql.y:1822 { yyVAL.str = "" } - case 324: + case 328: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1796 +//line sql.y:1826 { yyVAL.str = DistinctStr } - case 325: + case 329: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:1801 +//line sql.y:1831 { yyVAL.str = "" } - case 326: + case 330: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1805 +//line sql.y:1835 { yyVAL.str = StraightJoinHint } - case 327: + case 331: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:1810 +//line sql.y:1840 { yyVAL.selectExprs = nil } - case 328: + case 332: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1814 +//line sql.y:1844 { yyVAL.selectExprs = yyDollar[1].selectExprs } - case 329: + case 333: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1820 +//line sql.y:1850 { yyVAL.selectExprs = SelectExprs{yyDollar[1].selectExpr} } - case 330: + case 334: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1824 +//line sql.y:1854 { yyVAL.selectExprs = append(yyVAL.selectExprs, yyDollar[3].selectExpr) } - case 331: + case 335: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1830 +//line sql.y:1860 { yyVAL.selectExpr = &StarExpr{} } - case 332: + case 336: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1834 +//line sql.y:1864 { yyVAL.selectExpr = &AliasedExpr{Expr: yyDollar[1].expr, As: yyDollar[2].colIdent} } - case 333: + case 337: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1838 +//line sql.y:1868 { yyVAL.selectExpr = &StarExpr{TableName: TableName{Name: yyDollar[1].tableIdent}} } - case 334: + case 338: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:1842 +//line sql.y:1872 { yyVAL.selectExpr = &StarExpr{TableName: TableName{Qualifier: yyDollar[1].tableIdent, Name: yyDollar[3].tableIdent}} } - case 335: + case 339: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:1847 +//line sql.y:1877 { yyVAL.colIdent = ColIdent{} } - case 336: + case 340: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1851 +//line sql.y:1881 { yyVAL.colIdent = yyDollar[1].colIdent } - case 337: + case 341: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1855 +//line sql.y:1885 { yyVAL.colIdent = yyDollar[2].colIdent } - case 339: + case 343: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1862 +//line sql.y:1892 { yyVAL.colIdent = NewColIdent(string(yyDollar[1].bytes)) } - case 340: + case 344: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:1867 +//line sql.y:1897 { yyVAL.tableExprs = TableExprs{&AliasedTableExpr{Expr: TableName{Name: NewTableIdent("dual")}}} } - case 341: + case 345: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1871 +//line sql.y:1901 { yyVAL.tableExprs = yyDollar[2].tableExprs } - case 342: + case 346: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1877 +//line sql.y:1907 { yyVAL.tableExprs = TableExprs{yyDollar[1].tableExpr} } - case 343: + case 347: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1881 +//line sql.y:1911 { yyVAL.tableExprs = append(yyVAL.tableExprs, yyDollar[3].tableExpr) } - case 346: + case 350: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1891 +//line sql.y:1921 { yyVAL.tableExpr = yyDollar[1].aliasedTableName } - case 347: + case 351: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1895 +//line sql.y:1925 { yyVAL.tableExpr = &AliasedTableExpr{Expr: yyDollar[1].subquery, As: yyDollar[3].tableIdent} } - case 348: + case 352: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1899 +//line sql.y:1929 { // missed alias for subquery yylex.Error("Every derived table must have its own alias") return 1 } - case 349: + case 353: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1905 +//line sql.y:1935 { yyVAL.tableExpr = &ParenTableExpr{Exprs: yyDollar[2].tableExprs} } - case 350: + case 354: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1911 +//line sql.y:1941 { yyVAL.aliasedTableName = &AliasedTableExpr{Expr: yyDollar[1].tableName, As: yyDollar[2].tableIdent, Hints: yyDollar[3].indexHints} } - case 351: + case 355: yyDollar = yyS[yypt-7 : yypt+1] -//line sql.y:1915 +//line sql.y:1945 { yyVAL.aliasedTableName = &AliasedTableExpr{Expr: yyDollar[1].tableName, Partitions: yyDollar[4].partitions, As: yyDollar[6].tableIdent, Hints: yyDollar[7].indexHints} } - case 352: + case 356: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1921 +//line sql.y:1951 { yyVAL.columns = Columns{yyDollar[1].colIdent} } - case 353: + case 357: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1925 +//line sql.y:1955 { yyVAL.columns = append(yyVAL.columns, yyDollar[3].colIdent) } - case 354: + case 358: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1931 +//line sql.y:1961 { yyVAL.partitions = Partitions{yyDollar[1].colIdent} } - case 355: + case 359: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1935 +//line sql.y:1965 { yyVAL.partitions = append(yyVAL.partitions, yyDollar[3].colIdent) } - case 356: + case 360: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:1948 +//line sql.y:1978 { yyVAL.tableExpr = &JoinTableExpr{LeftExpr: yyDollar[1].tableExpr, Join: yyDollar[2].str, RightExpr: yyDollar[3].tableExpr, Condition: yyDollar[4].joinCondition} } - case 357: + case 361: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:1952 +//line sql.y:1982 { yyVAL.tableExpr = &JoinTableExpr{LeftExpr: yyDollar[1].tableExpr, Join: yyDollar[2].str, RightExpr: yyDollar[3].tableExpr, Condition: yyDollar[4].joinCondition} } - case 358: + case 362: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:1956 +//line sql.y:1986 { yyVAL.tableExpr = &JoinTableExpr{LeftExpr: yyDollar[1].tableExpr, Join: yyDollar[2].str, RightExpr: yyDollar[3].tableExpr, Condition: yyDollar[4].joinCondition} } - case 359: + case 363: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1960 +//line sql.y:1990 { yyVAL.tableExpr = &JoinTableExpr{LeftExpr: yyDollar[1].tableExpr, Join: yyDollar[2].str, RightExpr: yyDollar[3].tableExpr} } - case 360: + case 364: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1966 +//line sql.y:1996 { yyVAL.joinCondition = JoinCondition{On: yyDollar[2].expr} } - case 361: + case 365: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:1968 +//line sql.y:1998 { yyVAL.joinCondition = JoinCondition{Using: yyDollar[3].columns} } - case 362: + case 366: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:1972 +//line sql.y:2002 { yyVAL.joinCondition = JoinCondition{} } - case 363: + case 367: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1974 +//line sql.y:2004 { yyVAL.joinCondition = yyDollar[1].joinCondition } - case 364: + case 368: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:1978 +//line sql.y:2008 { yyVAL.joinCondition = JoinCondition{} } - case 365: + case 369: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1980 +//line sql.y:2010 { yyVAL.joinCondition = JoinCondition{On: yyDollar[2].expr} } - case 366: + case 370: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:1983 +//line sql.y:2013 { yyVAL.empty = struct{}{} } - case 367: + case 371: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1985 +//line sql.y:2015 { yyVAL.empty = struct{}{} } - case 368: + case 372: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:1988 +//line sql.y:2018 { yyVAL.tableIdent = NewTableIdent("") } - case 369: + case 373: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1992 +//line sql.y:2022 { yyVAL.tableIdent = yyDollar[1].tableIdent } - case 370: + case 374: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1996 +//line sql.y:2026 { yyVAL.tableIdent = yyDollar[2].tableIdent } - case 372: + case 376: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2003 +//line sql.y:2033 { yyVAL.tableIdent = NewTableIdent(string(yyDollar[1].bytes)) } - case 373: + case 377: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2009 +//line sql.y:2039 { yyVAL.str = JoinStr } - case 374: + case 378: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2013 +//line sql.y:2043 { yyVAL.str = JoinStr } - case 375: + case 379: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2017 +//line sql.y:2047 { yyVAL.str = JoinStr } - case 376: + case 380: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2023 +//line sql.y:2053 { yyVAL.str = StraightJoinStr } - case 377: + case 381: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2029 +//line sql.y:2059 { yyVAL.str = LeftJoinStr } - case 378: + case 382: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2033 +//line sql.y:2063 { yyVAL.str = LeftJoinStr } - case 379: + case 383: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2037 +//line sql.y:2067 { yyVAL.str = RightJoinStr } - case 380: + case 384: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2041 +//line sql.y:2071 { yyVAL.str = RightJoinStr } - case 381: + case 385: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2047 +//line sql.y:2077 { yyVAL.str = NaturalJoinStr } - case 382: + case 386: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2051 +//line sql.y:2081 { if yyDollar[2].str == LeftJoinStr { yyVAL.str = NaturalLeftJoinStr @@ -5186,465 +5828,465 @@ yydefault: yyVAL.str = NaturalRightJoinStr } } - case 383: + case 387: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2061 +//line sql.y:2091 { yyVAL.tableName = yyDollar[2].tableName } - case 384: + case 388: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2065 +//line sql.y:2095 { yyVAL.tableName = yyDollar[1].tableName } - case 385: + case 389: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2071 +//line sql.y:2101 { yyVAL.tableName = TableName{Name: yyDollar[1].tableIdent} } - case 386: + case 390: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2075 +//line sql.y:2105 { yyVAL.tableName = TableName{Qualifier: yyDollar[1].tableIdent, Name: yyDollar[3].tableIdent} } - case 387: + case 391: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2081 +//line sql.y:2111 { yyVAL.tableName = TableName{Name: yyDollar[1].tableIdent} } - case 388: + case 392: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:2086 +//line sql.y:2116 { yyVAL.indexHints = nil } - case 389: + case 393: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:2090 +//line sql.y:2120 { yyVAL.indexHints = &IndexHints{Type: UseStr, Indexes: yyDollar[4].columns} } - case 390: + case 394: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:2094 +//line sql.y:2124 { yyVAL.indexHints = &IndexHints{Type: IgnoreStr, Indexes: yyDollar[4].columns} } - case 391: + case 395: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:2098 +//line sql.y:2128 { yyVAL.indexHints = &IndexHints{Type: ForceStr, Indexes: yyDollar[4].columns} } - case 392: + case 396: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:2103 +//line sql.y:2133 { yyVAL.expr = nil } - case 393: + case 397: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2107 +//line sql.y:2137 { yyVAL.expr = yyDollar[2].expr } - case 394: + case 398: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2113 +//line sql.y:2143 { yyVAL.expr = yyDollar[1].expr } - case 395: + case 399: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2117 +//line sql.y:2147 { yyVAL.expr = &AndExpr{Left: yyDollar[1].expr, Right: yyDollar[3].expr} } - case 396: + case 400: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2121 +//line sql.y:2151 { yyVAL.expr = &OrExpr{Left: yyDollar[1].expr, Right: yyDollar[3].expr} } - case 397: + case 401: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2125 +//line sql.y:2155 { yyVAL.expr = &NotExpr{Expr: yyDollar[2].expr} } - case 398: + case 402: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2129 +//line sql.y:2159 { yyVAL.expr = &IsExpr{Operator: yyDollar[3].str, Expr: yyDollar[1].expr} } - case 399: + case 403: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2133 +//line sql.y:2163 { yyVAL.expr = yyDollar[1].expr } - case 400: + case 404: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2137 +//line sql.y:2167 { yyVAL.expr = &Default{ColName: yyDollar[2].str} } - case 401: + case 405: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:2143 +//line sql.y:2173 { yyVAL.str = "" } - case 402: + case 406: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2147 +//line sql.y:2177 { yyVAL.str = string(yyDollar[2].bytes) } - case 403: + case 407: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2153 +//line sql.y:2183 { yyVAL.boolVal = BoolVal(true) } - case 404: + case 408: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2157 +//line sql.y:2187 { yyVAL.boolVal = BoolVal(false) } - case 405: + case 409: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2163 +//line sql.y:2193 { yyVAL.expr = &ComparisonExpr{Left: yyDollar[1].expr, Operator: yyDollar[2].str, Right: yyDollar[3].expr} } - case 406: + case 410: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2167 +//line sql.y:2197 { yyVAL.expr = &ComparisonExpr{Left: yyDollar[1].expr, Operator: InStr, Right: yyDollar[3].colTuple} } - case 407: + case 411: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:2171 +//line sql.y:2201 { yyVAL.expr = &ComparisonExpr{Left: yyDollar[1].expr, Operator: NotInStr, Right: yyDollar[4].colTuple} } - case 408: + case 412: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:2175 +//line sql.y:2205 { yyVAL.expr = &ComparisonExpr{Left: yyDollar[1].expr, Operator: LikeStr, Right: yyDollar[3].expr, Escape: yyDollar[4].expr} } - case 409: + case 413: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:2179 +//line sql.y:2209 { yyVAL.expr = &ComparisonExpr{Left: yyDollar[1].expr, Operator: NotLikeStr, Right: yyDollar[4].expr, Escape: yyDollar[5].expr} } - case 410: + case 414: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2183 +//line sql.y:2213 { yyVAL.expr = &ComparisonExpr{Left: yyDollar[1].expr, Operator: RegexpStr, Right: yyDollar[3].expr} } - case 411: + case 415: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:2187 +//line sql.y:2217 { yyVAL.expr = &ComparisonExpr{Left: yyDollar[1].expr, Operator: NotRegexpStr, Right: yyDollar[4].expr} } - case 412: + case 416: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:2191 +//line sql.y:2221 { yyVAL.expr = &RangeCond{Left: yyDollar[1].expr, Operator: BetweenStr, From: yyDollar[3].expr, To: yyDollar[5].expr} } - case 413: + case 417: yyDollar = yyS[yypt-6 : yypt+1] -//line sql.y:2195 +//line sql.y:2225 { yyVAL.expr = &RangeCond{Left: yyDollar[1].expr, Operator: NotBetweenStr, From: yyDollar[4].expr, To: yyDollar[6].expr} } - case 414: + case 418: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2199 +//line sql.y:2229 { yyVAL.expr = &ExistsExpr{Subquery: yyDollar[2].subquery} } - case 415: + case 419: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2205 +//line sql.y:2235 { yyVAL.str = IsNullStr } - case 416: + case 420: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2209 +//line sql.y:2239 { yyVAL.str = IsNotNullStr } - case 417: + case 421: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2213 +//line sql.y:2243 { yyVAL.str = IsTrueStr } - case 418: + case 422: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2217 +//line sql.y:2247 { yyVAL.str = IsNotTrueStr } - case 419: + case 423: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2221 +//line sql.y:2251 { yyVAL.str = IsFalseStr } - case 420: + case 424: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2225 +//line sql.y:2255 { yyVAL.str = IsNotFalseStr } - case 421: + case 425: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2231 +//line sql.y:2261 { yyVAL.str = EqualStr } - case 422: + case 426: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2235 +//line sql.y:2265 { yyVAL.str = LessThanStr } - case 423: + case 427: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2239 +//line sql.y:2269 { yyVAL.str = GreaterThanStr } - case 424: + case 428: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2243 +//line sql.y:2273 { yyVAL.str = LessEqualStr } - case 425: + case 429: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2247 +//line sql.y:2277 { yyVAL.str = GreaterEqualStr } - case 426: + case 430: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2251 +//line sql.y:2281 { yyVAL.str = NotEqualStr } - case 427: + case 431: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2255 +//line sql.y:2285 { yyVAL.str = NullSafeEqualStr } - case 428: + case 432: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:2260 +//line sql.y:2290 { yyVAL.expr = nil } - case 429: + case 433: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2264 +//line sql.y:2294 { yyVAL.expr = yyDollar[2].expr } - case 430: + case 434: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2270 +//line sql.y:2300 { yyVAL.colTuple = yyDollar[1].valTuple } - case 431: + case 435: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2274 +//line sql.y:2304 { yyVAL.colTuple = yyDollar[1].subquery } - case 432: + case 436: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2278 +//line sql.y:2308 { yyVAL.colTuple = ListArg(yyDollar[1].bytes) } - case 433: + case 437: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2284 +//line sql.y:2314 { yyVAL.subquery = &Subquery{yyDollar[2].selStmt} } - case 434: + case 438: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2290 +//line sql.y:2320 { yyVAL.exprs = Exprs{yyDollar[1].expr} } - case 435: + case 439: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2294 +//line sql.y:2324 { yyVAL.exprs = append(yyDollar[1].exprs, yyDollar[3].expr) } - case 436: + case 440: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2300 +//line sql.y:2330 { yyVAL.expr = yyDollar[1].expr } - case 437: + case 441: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2304 +//line sql.y:2334 { yyVAL.expr = yyDollar[1].boolVal } - case 438: + case 442: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2308 +//line sql.y:2338 { yyVAL.expr = yyDollar[1].colName } - case 439: + case 443: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2312 +//line sql.y:2342 { yyVAL.expr = yyDollar[1].expr } - case 440: + case 444: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2316 +//line sql.y:2346 { yyVAL.expr = yyDollar[1].subquery } - case 441: + case 445: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2320 +//line sql.y:2350 { yyVAL.expr = &BinaryExpr{Left: yyDollar[1].expr, Operator: BitAndStr, Right: yyDollar[3].expr} } - case 442: + case 446: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2324 +//line sql.y:2354 { yyVAL.expr = &BinaryExpr{Left: yyDollar[1].expr, Operator: BitOrStr, Right: yyDollar[3].expr} } - case 443: + case 447: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2328 +//line sql.y:2358 { yyVAL.expr = &BinaryExpr{Left: yyDollar[1].expr, Operator: BitXorStr, Right: yyDollar[3].expr} } - case 444: + case 448: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2332 +//line sql.y:2362 { yyVAL.expr = &BinaryExpr{Left: yyDollar[1].expr, Operator: PlusStr, Right: yyDollar[3].expr} } - case 445: + case 449: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2336 +//line sql.y:2366 { yyVAL.expr = &BinaryExpr{Left: yyDollar[1].expr, Operator: MinusStr, Right: yyDollar[3].expr} } - case 446: + case 450: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2340 +//line sql.y:2370 { yyVAL.expr = &BinaryExpr{Left: yyDollar[1].expr, Operator: MultStr, Right: yyDollar[3].expr} } - case 447: + case 451: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2344 +//line sql.y:2374 { yyVAL.expr = &BinaryExpr{Left: yyDollar[1].expr, Operator: DivStr, Right: yyDollar[3].expr} } - case 448: + case 452: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2348 +//line sql.y:2378 { yyVAL.expr = &BinaryExpr{Left: yyDollar[1].expr, Operator: IntDivStr, Right: yyDollar[3].expr} } - case 449: + case 453: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2352 +//line sql.y:2382 { yyVAL.expr = &BinaryExpr{Left: yyDollar[1].expr, Operator: ModStr, Right: yyDollar[3].expr} } - case 450: + case 454: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2356 +//line sql.y:2386 { yyVAL.expr = &BinaryExpr{Left: yyDollar[1].expr, Operator: ModStr, Right: yyDollar[3].expr} } - case 451: + case 455: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2360 +//line sql.y:2390 { yyVAL.expr = &BinaryExpr{Left: yyDollar[1].expr, Operator: ShiftLeftStr, Right: yyDollar[3].expr} } - case 452: + case 456: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2364 +//line sql.y:2394 { yyVAL.expr = &BinaryExpr{Left: yyDollar[1].expr, Operator: ShiftRightStr, Right: yyDollar[3].expr} } - case 453: + case 457: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2368 +//line sql.y:2398 { yyVAL.expr = &BinaryExpr{Left: yyDollar[1].colName, Operator: JSONExtractOp, Right: yyDollar[3].expr} } - case 454: + case 458: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2372 +//line sql.y:2402 { yyVAL.expr = &BinaryExpr{Left: yyDollar[1].colName, Operator: JSONUnquoteExtractOp, Right: yyDollar[3].expr} } - case 455: + case 459: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2376 +//line sql.y:2406 { yyVAL.expr = &CollateExpr{Expr: yyDollar[1].expr, Charset: yyDollar[3].str} } - case 456: + case 460: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2380 +//line sql.y:2410 { yyVAL.expr = &UnaryExpr{Operator: BinaryStr, Expr: yyDollar[2].expr} } - case 457: + case 461: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2384 +//line sql.y:2414 { yyVAL.expr = &UnaryExpr{Operator: UBinaryStr, Expr: yyDollar[2].expr} } - case 458: + case 462: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2388 +//line sql.y:2418 { yyVAL.expr = &UnaryExpr{Operator: Utf8mb4Str, Expr: yyDollar[2].expr} } - case 459: + case 463: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2392 +//line sql.y:2422 { if num, ok := yyDollar[2].expr.(*SQLVal); ok && num.Type == IntVal { yyVAL.expr = num @@ -5652,9 +6294,9 @@ yydefault: yyVAL.expr = &UnaryExpr{Operator: UPlusStr, Expr: yyDollar[2].expr} } } - case 460: + case 464: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2400 +//line sql.y:2430 { if num, ok := yyDollar[2].expr.(*SQLVal); ok && num.Type == IntVal { // Handle double negative @@ -5668,21 +6310,21 @@ yydefault: yyVAL.expr = &UnaryExpr{Operator: UMinusStr, Expr: yyDollar[2].expr} } } - case 461: + case 465: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2414 +//line sql.y:2444 { yyVAL.expr = &UnaryExpr{Operator: TildaStr, Expr: yyDollar[2].expr} } - case 462: + case 466: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2418 +//line sql.y:2448 { yyVAL.expr = &UnaryExpr{Operator: BangStr, Expr: yyDollar[2].expr} } - case 463: + case 467: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2422 +//line sql.y:2452 { // This rule prevents the usage of INTERVAL // as a function. If support is needed for that, @@ -5690,485 +6332,485 @@ yydefault: // will be non-trivial because of grammar conflicts. yyVAL.expr = &IntervalExpr{Expr: yyDollar[2].expr, Unit: yyDollar[3].colIdent.String()} } - case 468: + case 472: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:2440 +//line sql.y:2470 { yyVAL.expr = &FuncExpr{Name: yyDollar[1].colIdent, Exprs: yyDollar[3].selectExprs} } - case 469: + case 473: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:2444 +//line sql.y:2474 { yyVAL.expr = &FuncExpr{Name: yyDollar[1].colIdent, Distinct: true, Exprs: yyDollar[4].selectExprs} } - case 470: + case 474: yyDollar = yyS[yypt-6 : yypt+1] -//line sql.y:2448 +//line sql.y:2478 { yyVAL.expr = &FuncExpr{Qualifier: yyDollar[1].tableIdent, Name: yyDollar[3].colIdent, Exprs: yyDollar[5].selectExprs} } - case 471: + case 475: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:2458 +//line sql.y:2488 { yyVAL.expr = &FuncExpr{Name: NewColIdent("left"), Exprs: yyDollar[3].selectExprs} } - case 472: + case 476: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:2462 +//line sql.y:2492 { yyVAL.expr = &FuncExpr{Name: NewColIdent("right"), Exprs: yyDollar[3].selectExprs} } - case 473: + case 477: yyDollar = yyS[yypt-6 : yypt+1] -//line sql.y:2466 +//line sql.y:2496 { yyVAL.expr = &ConvertExpr{Expr: yyDollar[3].expr, Type: yyDollar[5].convertType} } - case 474: + case 478: yyDollar = yyS[yypt-6 : yypt+1] -//line sql.y:2470 +//line sql.y:2500 { yyVAL.expr = &ConvertExpr{Expr: yyDollar[3].expr, Type: yyDollar[5].convertType} } - case 475: + case 479: yyDollar = yyS[yypt-6 : yypt+1] -//line sql.y:2474 +//line sql.y:2504 { yyVAL.expr = &ConvertUsingExpr{Expr: yyDollar[3].expr, Type: yyDollar[5].str} } - case 476: + case 480: yyDollar = yyS[yypt-8 : yypt+1] -//line sql.y:2478 +//line sql.y:2508 { yyVAL.expr = &SubstrExpr{Name: yyDollar[3].colName, From: yyDollar[5].expr, To: yyDollar[7].expr} } - case 477: + case 481: yyDollar = yyS[yypt-8 : yypt+1] -//line sql.y:2482 +//line sql.y:2512 { yyVAL.expr = &SubstrExpr{Name: yyDollar[3].colName, From: yyDollar[5].expr, To: yyDollar[7].expr} } - case 478: + case 482: yyDollar = yyS[yypt-8 : yypt+1] -//line sql.y:2486 +//line sql.y:2516 { yyVAL.expr = &SubstrExpr{StrVal: NewStrVal(yyDollar[3].bytes), From: yyDollar[5].expr, To: yyDollar[7].expr} } - case 479: + case 483: yyDollar = yyS[yypt-8 : yypt+1] -//line sql.y:2490 +//line sql.y:2520 { yyVAL.expr = &SubstrExpr{StrVal: NewStrVal(yyDollar[3].bytes), From: yyDollar[5].expr, To: yyDollar[7].expr} } - case 480: + case 484: yyDollar = yyS[yypt-9 : yypt+1] -//line sql.y:2494 +//line sql.y:2524 { yyVAL.expr = &MatchExpr{Columns: yyDollar[3].selectExprs, Expr: yyDollar[7].expr, Option: yyDollar[8].str} } - case 481: + case 485: yyDollar = yyS[yypt-7 : yypt+1] -//line sql.y:2498 +//line sql.y:2528 { yyVAL.expr = &GroupConcatExpr{Distinct: yyDollar[3].str, Exprs: yyDollar[4].selectExprs, OrderBy: yyDollar[5].orderBy, Separator: yyDollar[6].str} } - case 482: + case 486: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:2502 +//line sql.y:2532 { yyVAL.expr = &CaseExpr{Expr: yyDollar[2].expr, Whens: yyDollar[3].whens, Else: yyDollar[4].expr} } - case 483: + case 487: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:2506 +//line sql.y:2536 { yyVAL.expr = &ValuesFuncExpr{Name: yyDollar[3].colName} } - case 484: + case 488: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2516 +//line sql.y:2546 { yyVAL.expr = &FuncExpr{Name: NewColIdent("current_timestamp")} } - case 485: + case 489: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2520 +//line sql.y:2550 { yyVAL.expr = &FuncExpr{Name: NewColIdent("utc_timestamp")} } - case 486: + case 490: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2524 +//line sql.y:2554 { yyVAL.expr = &FuncExpr{Name: NewColIdent("utc_time")} } - case 487: + case 491: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2529 +//line sql.y:2559 { yyVAL.expr = &FuncExpr{Name: NewColIdent("utc_date")} } - case 488: + case 492: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2534 +//line sql.y:2564 { yyVAL.expr = &FuncExpr{Name: NewColIdent("localtime")} } - case 489: + case 493: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2539 +//line sql.y:2569 { yyVAL.expr = &FuncExpr{Name: NewColIdent("localtimestamp")} } - case 490: + case 494: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2545 +//line sql.y:2575 { yyVAL.expr = &FuncExpr{Name: NewColIdent("current_date")} } - case 491: + case 495: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2550 +//line sql.y:2580 { yyVAL.expr = &FuncExpr{Name: NewColIdent("current_time")} } - case 492: + case 496: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2555 +//line sql.y:2585 { yyVAL.expr = &CurTimeFuncExpr{Name: NewColIdent("current_timestamp"), Fsp: yyDollar[2].expr} } - case 493: + case 497: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2559 +//line sql.y:2589 { yyVAL.expr = &CurTimeFuncExpr{Name: NewColIdent("utc_timestamp"), Fsp: yyDollar[2].expr} } - case 494: + case 498: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2563 +//line sql.y:2593 { yyVAL.expr = &CurTimeFuncExpr{Name: NewColIdent("utc_time"), Fsp: yyDollar[2].expr} } - case 495: + case 499: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2568 +//line sql.y:2598 { yyVAL.expr = &CurTimeFuncExpr{Name: NewColIdent("localtime"), Fsp: yyDollar[2].expr} } - case 496: + case 500: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2573 +//line sql.y:2603 { yyVAL.expr = &CurTimeFuncExpr{Name: NewColIdent("localtimestamp"), Fsp: yyDollar[2].expr} } - case 497: + case 501: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2578 +//line sql.y:2608 { yyVAL.expr = &CurTimeFuncExpr{Name: NewColIdent("current_time"), Fsp: yyDollar[2].expr} } - case 498: + case 502: yyDollar = yyS[yypt-8 : yypt+1] -//line sql.y:2582 +//line sql.y:2612 { yyVAL.expr = &TimestampFuncExpr{Name: string("timestampadd"), Unit: yyDollar[3].colIdent.String(), Expr1: yyDollar[5].expr, Expr2: yyDollar[7].expr} } - case 499: + case 503: yyDollar = yyS[yypt-8 : yypt+1] -//line sql.y:2586 +//line sql.y:2616 { yyVAL.expr = &TimestampFuncExpr{Name: string("timestampdiff"), Unit: yyDollar[3].colIdent.String(), Expr1: yyDollar[5].expr, Expr2: yyDollar[7].expr} } - case 502: + case 506: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2596 +//line sql.y:2626 { yyVAL.expr = yyDollar[2].expr } - case 503: + case 507: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:2606 +//line sql.y:2636 { yyVAL.expr = &FuncExpr{Name: NewColIdent("if"), Exprs: yyDollar[3].selectExprs} } - case 504: + case 508: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:2610 +//line sql.y:2640 { yyVAL.expr = &FuncExpr{Name: NewColIdent("database"), Exprs: yyDollar[3].selectExprs} } - case 505: + case 509: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:2614 +//line sql.y:2644 { yyVAL.expr = &FuncExpr{Name: NewColIdent("mod"), Exprs: yyDollar[3].selectExprs} } - case 506: + case 510: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:2618 +//line sql.y:2648 { yyVAL.expr = &FuncExpr{Name: NewColIdent("replace"), Exprs: yyDollar[3].selectExprs} } - case 507: + case 511: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:2622 +//line sql.y:2652 { yyVAL.expr = &FuncExpr{Name: NewColIdent("substr"), Exprs: yyDollar[3].selectExprs} } - case 508: + case 512: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:2626 +//line sql.y:2656 { yyVAL.expr = &FuncExpr{Name: NewColIdent("substr"), Exprs: yyDollar[3].selectExprs} } - case 509: + case 513: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:2632 +//line sql.y:2662 { yyVAL.str = "" } - case 510: + case 514: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2636 +//line sql.y:2666 { yyVAL.str = BooleanModeStr } - case 511: + case 515: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:2640 +//line sql.y:2670 { yyVAL.str = NaturalLanguageModeStr } - case 512: + case 516: yyDollar = yyS[yypt-7 : yypt+1] -//line sql.y:2644 +//line sql.y:2674 { yyVAL.str = NaturalLanguageModeWithQueryExpansionStr } - case 513: + case 517: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2648 +//line sql.y:2678 { yyVAL.str = QueryExpansionStr } - case 514: + case 518: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2654 +//line sql.y:2684 { yyVAL.str = string(yyDollar[1].bytes) } - case 515: + case 519: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2658 +//line sql.y:2688 { yyVAL.str = string(yyDollar[1].bytes) } - case 516: + case 520: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2664 +//line sql.y:2694 { yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes), Length: yyDollar[2].sqlVal} } - case 517: + case 521: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2668 +//line sql.y:2698 { yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes), Length: yyDollar[2].sqlVal, Charset: yyDollar[3].str, Operator: CharacterSetStr} } - case 518: + case 522: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2672 +//line sql.y:2702 { yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes), Length: yyDollar[2].sqlVal, Charset: string(yyDollar[3].bytes)} } - case 519: + case 523: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2676 +//line sql.y:2706 { yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes)} } - case 520: + case 524: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2680 +//line sql.y:2710 { yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes), Length: yyDollar[2].sqlVal} } - case 521: + case 525: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2684 +//line sql.y:2714 { yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes)} yyVAL.convertType.Length = yyDollar[2].LengthScaleOption.Length yyVAL.convertType.Scale = yyDollar[2].LengthScaleOption.Scale } - case 522: + case 526: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2690 +//line sql.y:2720 { yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes)} } - case 523: + case 527: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2694 +//line sql.y:2724 { yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes), Length: yyDollar[2].sqlVal} } - case 524: + case 528: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2698 +//line sql.y:2728 { yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes)} } - case 525: + case 529: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2702 +//line sql.y:2732 { yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes)} } - case 526: + case 530: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2706 +//line sql.y:2736 { yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes), Length: yyDollar[2].sqlVal} } - case 527: + case 531: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2710 +//line sql.y:2740 { yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes)} } - case 528: + case 532: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2714 +//line sql.y:2744 { yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes)} } - case 529: + case 533: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:2719 +//line sql.y:2749 { yyVAL.expr = nil } - case 530: + case 534: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2723 +//line sql.y:2753 { yyVAL.expr = yyDollar[1].expr } - case 531: + case 535: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:2728 +//line sql.y:2758 { yyVAL.str = string("") } - case 532: + case 536: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2732 +//line sql.y:2762 { yyVAL.str = " separator '" + string(yyDollar[2].bytes) + "'" } - case 533: + case 537: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2738 +//line sql.y:2768 { yyVAL.whens = []*When{yyDollar[1].when} } - case 534: + case 538: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2742 +//line sql.y:2772 { yyVAL.whens = append(yyDollar[1].whens, yyDollar[2].when) } - case 535: + case 539: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:2748 +//line sql.y:2778 { yyVAL.when = &When{Cond: yyDollar[2].expr, Val: yyDollar[4].expr} } - case 536: + case 540: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:2753 +//line sql.y:2783 { yyVAL.expr = nil } - case 537: + case 541: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2757 +//line sql.y:2787 { yyVAL.expr = yyDollar[2].expr } - case 538: + case 542: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2763 +//line sql.y:2793 { yyVAL.colName = &ColName{Name: yyDollar[1].colIdent} } - case 539: + case 543: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2767 +//line sql.y:2797 { yyVAL.colName = &ColName{Qualifier: TableName{Name: yyDollar[1].tableIdent}, Name: yyDollar[3].colIdent} } - case 540: + case 544: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:2771 +//line sql.y:2801 { yyVAL.colName = &ColName{Qualifier: TableName{Qualifier: yyDollar[1].tableIdent, Name: yyDollar[3].tableIdent}, Name: yyDollar[5].colIdent} } - case 541: + case 545: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2777 +//line sql.y:2807 { yyVAL.expr = NewStrVal(yyDollar[1].bytes) } - case 542: + case 546: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2781 +//line sql.y:2811 { yyVAL.expr = NewHexVal(yyDollar[1].bytes) } - case 543: + case 547: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2785 +//line sql.y:2815 { yyVAL.expr = NewBitVal(yyDollar[1].bytes) } - case 544: + case 548: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2789 +//line sql.y:2819 { yyVAL.expr = NewIntVal(yyDollar[1].bytes) } - case 545: + case 549: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2793 +//line sql.y:2823 { yyVAL.expr = NewFloatVal(yyDollar[1].bytes) } - case 546: + case 550: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2797 +//line sql.y:2827 { yyVAL.expr = NewHexNum(yyDollar[1].bytes) } - case 547: + case 551: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2801 +//line sql.y:2831 { yyVAL.expr = NewValArg(yyDollar[1].bytes) } - case 548: + case 552: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2805 +//line sql.y:2835 { yyVAL.expr = &NullVal{} } - case 549: + case 553: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2811 +//line sql.y:2841 { // TODO(sougou): Deprecate this construct. if yyDollar[1].colIdent.Lowered() != "value" { @@ -6177,239 +6819,239 @@ yydefault: } yyVAL.expr = NewIntVal([]byte("1")) } - case 550: + case 554: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2820 +//line sql.y:2850 { yyVAL.expr = NewIntVal(yyDollar[1].bytes) } - case 551: + case 555: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2824 +//line sql.y:2854 { yyVAL.expr = NewValArg(yyDollar[1].bytes) } - case 552: + case 556: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:2829 +//line sql.y:2859 { yyVAL.exprs = nil } - case 553: + case 557: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2833 +//line sql.y:2863 { yyVAL.exprs = yyDollar[3].exprs } - case 554: + case 558: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:2838 +//line sql.y:2868 { yyVAL.expr = nil } - case 555: + case 559: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2842 +//line sql.y:2872 { yyVAL.expr = yyDollar[2].expr } - case 556: + case 560: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:2847 +//line sql.y:2877 { yyVAL.orderBy = nil } - case 557: + case 561: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2851 +//line sql.y:2881 { yyVAL.orderBy = yyDollar[3].orderBy } - case 558: + case 562: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2857 +//line sql.y:2887 { yyVAL.orderBy = OrderBy{yyDollar[1].order} } - case 559: + case 563: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2861 +//line sql.y:2891 { yyVAL.orderBy = append(yyDollar[1].orderBy, yyDollar[3].order) } - case 560: + case 564: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2867 +//line sql.y:2897 { yyVAL.order = &Order{Expr: yyDollar[1].expr, Direction: yyDollar[2].str} } - case 561: + case 565: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:2872 +//line sql.y:2902 { yyVAL.str = AscScr } - case 562: + case 566: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2876 +//line sql.y:2906 { yyVAL.str = AscScr } - case 563: + case 567: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2880 +//line sql.y:2910 { yyVAL.str = DescScr } - case 564: + case 568: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:2885 +//line sql.y:2915 { yyVAL.limit = nil } - case 565: + case 569: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2889 +//line sql.y:2919 { yyVAL.limit = &Limit{Rowcount: yyDollar[2].expr} } - case 566: + case 570: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:2893 +//line sql.y:2923 { yyVAL.limit = &Limit{Offset: yyDollar[2].expr, Rowcount: yyDollar[4].expr} } - case 567: + case 571: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:2897 +//line sql.y:2927 { yyVAL.limit = &Limit{Offset: yyDollar[4].expr, Rowcount: yyDollar[2].expr} } - case 568: + case 572: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:2902 +//line sql.y:2932 { yyVAL.str = "" } - case 569: + case 573: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2906 +//line sql.y:2936 { yyVAL.str = ForUpdateStr } - case 570: + case 574: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:2910 +//line sql.y:2940 { yyVAL.str = ShareModeStr } - case 571: + case 575: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2923 +//line sql.y:2953 { yyVAL.ins = &Insert{Rows: yyDollar[2].values} } - case 572: + case 576: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2927 +//line sql.y:2957 { yyVAL.ins = &Insert{Rows: yyDollar[1].selStmt} } - case 573: + case 577: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2931 +//line sql.y:2961 { // Drop the redundant parenthesis. yyVAL.ins = &Insert{Rows: yyDollar[2].selStmt} } - case 574: + case 578: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:2936 +//line sql.y:2966 { yyVAL.ins = &Insert{Columns: yyDollar[2].columns, Rows: yyDollar[5].values} } - case 575: + case 579: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:2940 +//line sql.y:2970 { yyVAL.ins = &Insert{Columns: yyDollar[2].columns, Rows: yyDollar[4].selStmt} } - case 576: + case 580: yyDollar = yyS[yypt-6 : yypt+1] -//line sql.y:2944 +//line sql.y:2974 { // Drop the redundant parenthesis. yyVAL.ins = &Insert{Columns: yyDollar[2].columns, Rows: yyDollar[5].selStmt} } - case 577: + case 581: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2951 +//line sql.y:2981 { yyVAL.columns = Columns{yyDollar[1].colIdent} } - case 578: + case 582: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2955 +//line sql.y:2985 { yyVAL.columns = Columns{yyDollar[3].colIdent} } - case 579: + case 583: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2959 +//line sql.y:2989 { yyVAL.columns = append(yyVAL.columns, yyDollar[3].colIdent) } - case 580: + case 584: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:2963 +//line sql.y:2993 { yyVAL.columns = append(yyVAL.columns, yyDollar[5].colIdent) } - case 581: + case 585: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:2968 +//line sql.y:2998 { yyVAL.updateExprs = nil } - case 582: + case 586: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:2972 +//line sql.y:3002 { yyVAL.updateExprs = yyDollar[5].updateExprs } - case 583: + case 587: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2978 +//line sql.y:3008 { yyVAL.values = Values{yyDollar[1].valTuple} } - case 584: + case 588: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2982 +//line sql.y:3012 { yyVAL.values = append(yyDollar[1].values, yyDollar[3].valTuple) } - case 585: + case 589: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2988 +//line sql.y:3018 { yyVAL.valTuple = yyDollar[1].valTuple } - case 586: + case 590: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2992 +//line sql.y:3022 { yyVAL.valTuple = ValTuple{} } - case 587: + case 591: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2998 +//line sql.y:3028 { yyVAL.valTuple = ValTuple(yyDollar[2].exprs) } - case 588: + case 592: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3004 +//line sql.y:3034 { if len(yyDollar[1].valTuple) == 1 { yyVAL.expr = &ParenExpr{yyDollar[1].valTuple[0]} @@ -6417,312 +7059,312 @@ yydefault: yyVAL.expr = yyDollar[1].valTuple } } - case 589: + case 593: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3014 +//line sql.y:3044 { yyVAL.updateExprs = UpdateExprs{yyDollar[1].updateExpr} } - case 590: + case 594: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:3018 +//line sql.y:3048 { yyVAL.updateExprs = append(yyDollar[1].updateExprs, yyDollar[3].updateExpr) } - case 591: + case 595: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:3024 +//line sql.y:3054 { yyVAL.updateExpr = &UpdateExpr{Name: yyDollar[1].colName, Expr: yyDollar[3].expr} } - case 592: + case 596: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3030 +//line sql.y:3060 { yyVAL.setExprs = SetExprs{yyDollar[1].setExpr} } - case 593: + case 597: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:3034 +//line sql.y:3064 { yyVAL.setExprs = append(yyDollar[1].setExprs, yyDollar[3].setExpr) } - case 594: + case 598: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:3040 +//line sql.y:3070 { yyVAL.setExpr = &SetExpr{Name: yyDollar[1].colIdent, Expr: NewStrVal([]byte("on"))} } - case 595: + case 599: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:3044 +//line sql.y:3074 { yyVAL.setExpr = &SetExpr{Name: yyDollar[1].colIdent, Expr: NewStrVal([]byte("off"))} } - case 596: + case 600: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:3048 +//line sql.y:3078 { yyVAL.setExpr = &SetExpr{Name: yyDollar[1].colIdent, Expr: yyDollar[3].expr} } - case 597: + case 601: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:3052 +//line sql.y:3082 { yyVAL.setExpr = &SetExpr{Name: NewColIdent(string(yyDollar[1].bytes)), Expr: yyDollar[2].expr} } - case 599: + case 603: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:3059 +//line sql.y:3089 { yyVAL.bytes = []byte("charset") } - case 601: + case 605: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3066 +//line sql.y:3096 { yyVAL.expr = NewStrVal([]byte(yyDollar[1].colIdent.String())) } - case 602: + case 606: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3070 +//line sql.y:3100 { yyVAL.expr = NewStrVal(yyDollar[1].bytes) } - case 603: + case 607: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3074 +//line sql.y:3104 { yyVAL.expr = &Default{} } - case 606: + case 610: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:3083 +//line sql.y:3113 { yyVAL.byt = 0 } - case 607: + case 611: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:3085 +//line sql.y:3115 { yyVAL.byt = 1 } - case 608: + case 612: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:3088 +//line sql.y:3118 { yyVAL.empty = struct{}{} } - case 609: + case 613: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:3090 +//line sql.y:3120 { yyVAL.empty = struct{}{} } - case 610: + case 614: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:3093 +//line sql.y:3123 { yyVAL.str = "" } - case 611: + case 615: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3095 +//line sql.y:3125 { yyVAL.str = IgnoreStr } - case 612: + case 616: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3099 +//line sql.y:3129 { yyVAL.empty = struct{}{} } - case 613: + case 617: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3101 +//line sql.y:3131 { yyVAL.empty = struct{}{} } - case 614: + case 618: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3103 +//line sql.y:3133 { yyVAL.empty = struct{}{} } - case 615: + case 619: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3105 +//line sql.y:3135 { yyVAL.empty = struct{}{} } - case 616: + case 620: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3107 +//line sql.y:3137 { yyVAL.empty = struct{}{} } - case 617: + case 621: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3109 +//line sql.y:3139 { yyVAL.empty = struct{}{} } - case 618: + case 622: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3111 +//line sql.y:3141 { yyVAL.empty = struct{}{} } - case 619: + case 623: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3113 +//line sql.y:3143 { yyVAL.empty = struct{}{} } - case 620: + case 624: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3115 +//line sql.y:3145 { yyVAL.empty = struct{}{} } - case 621: + case 625: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3117 +//line sql.y:3147 { yyVAL.empty = struct{}{} } - case 622: + case 626: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:3120 +//line sql.y:3150 { yyVAL.empty = struct{}{} } - case 623: + case 627: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3122 +//line sql.y:3152 { yyVAL.empty = struct{}{} } - case 624: + case 628: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3124 +//line sql.y:3154 { yyVAL.empty = struct{}{} } - case 625: + case 629: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3128 +//line sql.y:3158 { yyVAL.empty = struct{}{} } - case 626: + case 630: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3130 +//line sql.y:3160 { yyVAL.empty = struct{}{} } - case 627: + case 631: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:3133 +//line sql.y:3163 { yyVAL.empty = struct{}{} } - case 628: + case 632: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3135 +//line sql.y:3165 { yyVAL.empty = struct{}{} } - case 629: + case 633: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3137 +//line sql.y:3167 { yyVAL.empty = struct{}{} } - case 630: + case 634: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:3140 +//line sql.y:3170 { yyVAL.colIdent = ColIdent{} } - case 631: + case 635: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:3142 +//line sql.y:3172 { yyVAL.colIdent = yyDollar[2].colIdent } - case 632: + case 636: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3146 +//line sql.y:3176 { yyVAL.colIdent = NewColIdent(string(yyDollar[1].bytes)) } - case 633: + case 637: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3150 +//line sql.y:3180 { yyVAL.colIdent = NewColIdent(string(yyDollar[1].bytes)) } - case 635: + case 639: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3157 +//line sql.y:3187 { yyVAL.colIdent = NewColIdent(string(yyDollar[1].bytes)) } - case 636: + case 640: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3163 +//line sql.y:3193 { yyVAL.tableIdent = NewTableIdent(string(yyDollar[1].bytes)) } - case 637: + case 641: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3167 +//line sql.y:3197 { yyVAL.tableIdent = NewTableIdent(string(yyDollar[1].bytes)) } - case 639: + case 643: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3174 +//line sql.y:3204 { yyVAL.tableIdent = NewTableIdent(string(yyDollar[1].bytes)) } - case 845: + case 930: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3405 +//line sql.y:3516 { if incNesting(yylex) { yylex.Error("max nesting level reached") return 1 } } - case 846: + case 931: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3414 +//line sql.y:3525 { decNesting(yylex) } - case 847: + case 932: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:3419 +//line sql.y:3530 { skipToEnd(yylex) } - case 848: + case 933: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:3424 +//line sql.y:3535 { skipToEnd(yylex) } - case 849: + case 934: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3428 +//line sql.y:3539 { skipToEnd(yylex) } - case 850: + case 935: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3432 +//line sql.y:3543 { skipToEnd(yylex) } diff --git a/go/vt/sqlparser/sql.y b/go/vt/sqlparser/sql.y index ed5fda40263..10b363b3065 100644 --- a/go/vt/sqlparser/sql.y +++ b/go/vt/sqlparser/sql.y @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -158,7 +158,7 @@ func skipToEnd(yylex interface{}) { // DDL Tokens %token CREATE ALTER DROP RENAME ANALYZE ADD FLUSH -%token SCHEMA TABLE INDEX VIEW TO IGNORE IF UNIQUE PRIMARY COLUMN SPATIAL FULLTEXT KEY_BLOCK_SIZE +%token SCHEMA TABLE INDEX VIEW TO IGNORE IF UNIQUE PRIMARY COLUMN SPATIAL FULLTEXT KEY_BLOCK_SIZE CHECK %token ACTION CASCADE CONSTRAINT FOREIGN NO REFERENCES RESTRICT %token SHOW DESCRIBE EXPLAIN DATE ESCAPE REPAIR OPTIMIZE TRUNCATE %token MAXVALUE PARTITION REORGANIZE LESS THAN PROCEDURE TRIGGER @@ -173,7 +173,7 @@ func skipToEnd(yylex interface{}) { %token BIT TINYINT SMALLINT MEDIUMINT INT INTEGER BIGINT INTNUM %token REAL DOUBLE FLOAT_TYPE DECIMAL NUMERIC %token TIME TIMESTAMP DATETIME YEAR -%token CHAR VARCHAR BOOL CHARACTER VARBINARY NCHAR +%token CHAR VARCHAR BOOL CHARACTER VARBINARY NCHAR %token TEXT TINYTEXT MEDIUMTEXT LONGTEXT %token BLOB TINYBLOB MEDIUMBLOB LONGBLOB JSON ENUM %token GEOMETRY POINT LINESTRING POLYGON GEOMETRYCOLLECTION MULTIPOINT MULTILINESTRING MULTIPOLYGON @@ -182,7 +182,7 @@ func skipToEnd(yylex interface{}) { %token NULLX AUTO_INCREMENT APPROXNUM SIGNED UNSIGNED ZEROFILL // Supported SHOW tokens -%token COLLATION DATABASES TABLES VSCHEMA FULL PROCESSLIST COLUMNS FIELDS ENGINES PLUGINS +%token COLLATION DATABASES TABLES VITESS_METADATA VSCHEMA FULL PROCESSLIST COLUMNS FIELDS ENGINES PLUGINS // SET tokens %token NAMES CHARSET GLOBAL SESSION ISOLATION LEVEL READ WRITE ONLY REPEATABLE COMMITTED UNCOMMITTED SERIALIZABLE @@ -201,7 +201,13 @@ func skipToEnd(yylex interface{}) { %token MATCH AGAINST BOOLEAN LANGUAGE WITH QUERY EXPANSION // MySQL reserved words that are unused by this grammar will map to this token. -%token UNUSED +%token UNUSED ARRAY CUME_DIST DESCRIPTION DENSE_RANK EMPTY EXCEPT FIRST_VALUE GROUPING GROUPS JSON_TABLE LAG LAST_VALUE LATERAL LEAD MEMBER +%token NTH_VALUE NTILE OF OVER PERCENT_RANK RANK RECURSIVE ROW_NUMBER SYSTEM WINDOW +%token ACTIVE ADMIN BUCKETS CLONE COMPONENT DEFINITION ENFORCED EXCLUDE FOLLOWING GEOMCOLLECTION GET_MASTER_PUBLIC_KEY HISTOGRAM HISTORY +%token INACTIVE INVISIBLE LOCKED MASTER_COMPRESSION_ALGORITHMS MASTER_PUBLIC_KEY_PATH MASTER_TLS_CIPHERSUITES MASTER_ZSTD_COMPRESSION_LEVEL +%token NESTED NETWORK_NAMESPACE NOWAIT NULLS OJ OLD OPTIONAL ORDINALITY ORGANIZATION OTHERS 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_LOAD SECONDARY_UNLOAD SKIP SRID +%token THREAD_PRIORITY TIES UNBOUNDED VCPU VISIBLE %type command %type select_statement base_select union_lhs union_rhs @@ -262,7 +268,7 @@ func skipToEnd(yylex interface{}) { %type for_from %type ignore_opt default_opt %type full_opt from_database_opt tables_or_processlist columns_or_fields -%type like_or_where_opt +%type like_or_where_opt like_opt %type exists_opt %type not_exists_opt non_add_drop_or_rename_operation to_opt index_opt constraint_opt %type reserved_keyword non_reserved_keyword @@ -1308,19 +1314,27 @@ alter_statement: { $$ = &DDL{Action: AlterStr, Table: $4, PartitionSpec: $5} } -| ALTER VSCHEMA CREATE VINDEX sql_id vindex_type_opt vindex_params_opt +| ALTER VSCHEMA CREATE VINDEX table_name vindex_type_opt vindex_params_opt { - $$ = &DDL{Action: CreateVindexStr, VindexSpec: &VindexSpec{ - Name: $5, - Type: $6, - Params: $7, - }} + $$ = &DDL{ + Action: CreateVindexStr, + Table: $5, + VindexSpec: &VindexSpec{ + Name: NewColIdent($5.Name.String()), + Type: $6, + Params: $7, + }, + } } -| ALTER VSCHEMA DROP VINDEX sql_id +| ALTER VSCHEMA DROP VINDEX table_name { - $$ = &DDL{Action: DropVindexStr, VindexSpec: &VindexSpec{ - Name: $5, - }} + $$ = &DDL{ + Action: DropVindexStr, + Table: $5, + VindexSpec: &VindexSpec{ + Name: NewColIdent($5.Name.String()), + }, + } } | ALTER VSCHEMA ADD TABLE table_name { @@ -1370,7 +1384,8 @@ alter_statement: } alter_object_type: - COLUMN + CHECK +| COLUMN | CONSTRAINT | FOREIGN | FULLTEXT @@ -1572,6 +1587,11 @@ show_statement: showCollationFilterOpt := $4 $$ = &Show{Type: string($2), ShowCollationFilterOpt: &showCollationFilterOpt} } +| SHOW VITESS_METADATA VARIABLES like_opt + { + showTablesOpt := &ShowTablesOpt{Filter: $4} + $$ = &Show{Scope: string($2), Type: string($3), ShowTablesOpt: showTablesOpt} + } | SHOW VSCHEMA TABLES { $$ = &Show{Type: string($2) + " " + string($3)} @@ -1661,6 +1681,16 @@ like_or_where_opt: $$ = &ShowFilter{Filter:$2} } +like_opt: + /* empty */ + { + $$ = nil + } + | LIKE STRING + { + $$ = &ShowFilter{Like:string($2)} + } + show_session_or_global: /* empty */ { @@ -3186,6 +3216,7 @@ reserved_table_id: */ reserved_keyword: ADD +| ARRAY | AND | AS | ASC @@ -3198,6 +3229,7 @@ reserved_keyword: | CONVERT | CREATE | CROSS +| CUME_DIST | CURRENT_DATE | CURRENT_TIME | CURRENT_TIMESTAMP @@ -3207,6 +3239,7 @@ reserved_keyword: | DATABASES | DEFAULT | DELETE +| DENSE_RANK | DESC | DESCRIBE | DISTINCT @@ -3218,10 +3251,13 @@ reserved_keyword: | EXISTS | EXPLAIN | FALSE +| FIRST_VALUE | FOR | FORCE | FROM | GROUP +| GROUPING +| GROUPS | HAVING | IF | IGNORE @@ -3233,35 +3269,50 @@ reserved_keyword: | INTO | IS | JOIN +| JSON_TABLE | KEY +| LAG +| LAST_VALUE +| LATERAL +| LEAD | LEFT | LIKE | LIMIT | LOCALTIME | LOCALTIMESTAMP | LOCK +| MEMBER | MATCH | MAXVALUE | MOD | NATURAL | NEXT // next should be doable as non-reserved, but is not due to the special `select next num_val` query that vitess supports | NOT +| NTH_VALUE +| NTILE | NULL +| OF | OFF | ON | OR | ORDER | OUTER +| OVER +| PERCENT_RANK +| RANK +| RECURSIVE | REGEXP | RENAME | REPLACE | RIGHT +| ROW_NUMBER | SCHEMA | SELECT | SEPARATOR | SET | SHOW | STRAIGHT_JOIN +| SYSTEM | TABLE | THEN | TIMESTAMPADD @@ -3280,6 +3331,7 @@ reserved_keyword: | VALUES | WHEN | WHERE +| WINDOW /* These are non-reserved Vitess, because they don't cause conflicts in the grammar. @@ -3291,39 +3343,56 @@ reserved_keyword: non_reserved_keyword: AGAINST | ACTION +| ACTIVE +| ADMIN | BEGIN | BIGINT | BIT | BLOB | BOOL | BOOLEAN +| BUCKETS | CASCADE | CHAR | CHARACTER | CHARSET +| CHECK +| CLONE | COLLATION | COLUMNS | COMMENT_KEYWORD | COMMIT | COMMITTED +| COMPONENT | DATE | DATETIME | DECIMAL +| DEFINITION +| DESCRIPTION | DOUBLE | DUPLICATE +| ENFORCED | ENGINES | ENUM +| EXCLUDE | EXPANSION | FLOAT_TYPE | FIELDS | FLUSH +| FOLLOWING | FOREIGN | FULLTEXT +| GEOMCOLLECTION | GEOMETRY | GEOMETRYCOLLECTION +| GET_MASTER_PUBLIC_KEY | GLOBAL +| HISTOGRAM +| HISTORY +| INACTIVE | INT | INTEGER +| INVISIBLE | ISOLATION | JSON | KEY_BLOCK_SIZE @@ -3333,8 +3402,13 @@ non_reserved_keyword: | LESS | LEVEL | LINESTRING +| LOCKED | LONGBLOB | LONGTEXT +| MASTER_COMPRESSION_ALGORITHMS +| MASTER_PUBLIC_KEY_PATH +| MASTER_TLS_CIPHERSUITES +| MASTER_ZSTD_COMPRESSION_LEVEL | MEDIUMBLOB | MEDIUMINT | MEDIUMTEXT @@ -3344,38 +3418,71 @@ non_reserved_keyword: | MULTIPOLYGON | NAMES | NCHAR +| NESTED +| NETWORK_NAMESPACE +| NOWAIT | NO +| NULLS | NUMERIC | OFFSET +| OJ +| OLD +| OPTIONAL +| ORDINALITY +| ORGANIZATION | ONLY | OPTIMIZE +| OTHERS | PARTITION +| PATH +| PERSIST +| PERSIST_ONLY +| PRECEDING +| PRIVILEGE_CHECKS_USER +| PROCESS | PLUGINS | POINT | POLYGON | PRIMARY | PROCEDURE | QUERY +| RANDOM | READ | REAL +| REFERENCE | REFERENCES | REORGANIZE | REPAIR | REPEATABLE | RESTRICT +| REQUIRE_ROW_FORMAT +| RESOURCE +| RESPECT +| RESTART +| RETAIN +| REUSE +| ROLE | ROLLBACK +| SECONDARY +| SECONDARY_ENGINE +| SECONDARY_LOAD +| SECONDARY_UNLOAD | SEQUENCE | SESSION | SERIALIZABLE | SHARE | SIGNED +| SKIP | SMALLINT | SPATIAL +| SRID | START | STATUS | TABLES | TEXT | THAN +| THREAD_PRIORITY +| TIES | TIME | TIMESTAMP | TINYBLOB @@ -3384,15 +3491,19 @@ non_reserved_keyword: | TRANSACTION | TRIGGER | TRUNCATE +| UNBOUNDED | UNCOMMITTED | UNSIGNED | UNUSED | VARBINARY | VARCHAR | VARIABLES +| VCPU | VIEW | VINDEX | VINDEXES +| VISIBLE +| VITESS_METADATA | VSCHEMA | WARNINGS | WITH diff --git a/go/vt/sqlparser/test_queries/django_queries.txt b/go/vt/sqlparser/test_queries/django_queries.txt new file mode 100644 index 00000000000..6b6588beaea --- /dev/null +++ b/go/vt/sqlparser/test_queries/django_queries.txt @@ -0,0 +1,290 @@ +set autocommit=1 +SELECT @@SQL_AUTO_IS_NULL +SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED +SELECT @@sql_mode +SHOW FULL TABLES +SHOW FULL TABLES +SHOW FULL TABLES +CREATE TABLE `django_migrations` (`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY, `app` varchar(255) NOT NULL, `name` varchar(255) NOT NULL, `applied` datetime(6) NOT NULL) +SELECT engine FROM information_schema.tables WHERE table_name = 'django_migrations' +SELECT engine FROM information_schema.tables WHERE table_name = 'django_migrations' +SELECT engine FROM information_schema.tables WHERE table_name = 'django_migrations' +SELECT engine FROM information_schema.tables WHERE table_name = 'django_migrations' +CREATE TABLE `accounts_userprofile` (`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY, `password` varchar(128) NOT NULL, `last_login` datetime(6) NULL, `email` varchar(255) NOT NULL UNIQUE, `first_name` varchar(255) NULL, `last_name` varchar(255) NULL, `active` bool NOT NULL, `staff` bool NOT NULL, `admin` bool NOT NULL, `timestamp` datetime(6) NOT NULL) +SELECT engine FROM information_schema.tables WHERE table_name = 'accounts_userprofile' +SELECT engine FROM information_schema.tables WHERE table_name = 'accounts_userprofile' +SELECT engine FROM information_schema.tables WHERE table_name = 'accounts_userprofile' +SELECT engine FROM information_schema.tables WHERE table_name = 'accounts_userprofile' +SELECT engine FROM information_schema.tables WHERE table_name = 'accounts_userprofile' +SELECT engine FROM information_schema.tables WHERE table_name = 'accounts_userprofile' +SELECT engine FROM information_schema.tables WHERE table_name = 'accounts_userprofile' +SELECT engine FROM information_schema.tables WHERE table_name = 'accounts_userprofile' +SELECT engine FROM information_schema.tables WHERE table_name = 'accounts_userprofile' +SELECT engine FROM information_schema.tables WHERE table_name = 'accounts_userprofile' +SHOW FULL TABLES +INSERT INTO `django_migrations` (`app`, `name`, `applied`) VALUES ('accounts', '0001_initial', '2019-09-11 20:08:24.240837') +ALTER TABLE `accounts_userprofile` ADD COLUMN `uid` varchar(8) DEFAULT 'bfghjkl' NOT NULL UNIQUE +ALTER TABLE `accounts_userprofile` ALTER COLUMN `uid` DROP DEFAULT +SELECT engine FROM information_schema.tables WHERE table_name = 'accounts_userprofile' +SHOW FULL TABLES +INSERT INTO `django_migrations` (`app`, `name`, `applied`) VALUES ('accounts', '0002_userprofile_uid', '2019-09-11 20:08:24.390839') +ALTER TABLE `accounts_userprofile` ADD COLUMN `bio` varchar(255) NULL +SELECT engine FROM information_schema.tables WHERE table_name = 'accounts_userprofile' +SHOW FULL TABLES +INSERT INTO `django_migrations` (`app`, `name`, `applied`) VALUES ('accounts', '0003_userprofile_bio', '2019-09-11 20:08:24.521784') +CREATE TABLE `django_content_type` (`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY, `name` varchar(100) NOT NULL, `app_label` varchar(100) NOT NULL, `model` varchar(100) NOT NULL) +SELECT engine FROM information_schema.tables WHERE table_name = 'django_content_type' +SELECT engine FROM information_schema.tables WHERE table_name = 'django_content_type' +SELECT engine FROM information_schema.tables WHERE table_name = 'django_content_type' +SELECT engine FROM information_schema.tables WHERE table_name = 'django_content_type' +ALTER TABLE `django_content_type` ADD CONSTRAINT `django_content_type_app_label_model_76bd3d3b_uniq` UNIQUE (`app_label`, `model`) +SHOW FULL TABLES +INSERT INTO `django_migrations` (`app`, `name`, `applied`) VALUES ('contenttypes', '0001_initial', '2019-09-11 20:08:24.640638') +CREATE TABLE `django_admin_log` (`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY, `action_time` datetime(6) NOT NULL, `object_id` longtext NULL, `object_repr` varchar(200) NOT NULL, `action_flag` smallint UNSIGNED NOT NULL, `change_message` longtext NOT NULL, `content_type_id` integer NULL, `user_id` integer NOT NULL) +SELECT engine FROM information_schema.tables WHERE table_name = 'django_admin_log' +SELECT engine FROM information_schema.tables WHERE table_name = 'django_admin_log' +SELECT engine FROM information_schema.tables WHERE table_name = 'django_admin_log' +SELECT engine FROM information_schema.tables WHERE table_name = 'django_admin_log' +SELECT engine FROM information_schema.tables WHERE table_name = 'django_admin_log' +SELECT engine FROM information_schema.tables WHERE table_name = 'django_admin_log' +SELECT engine FROM information_schema.tables WHERE table_name = 'django_admin_log' +SELECT engine FROM information_schema.tables WHERE table_name = 'django_admin_log' +SHOW FULL TABLES +INSERT INTO `django_migrations` (`app`, `name`, `applied`) VALUES ('admin', '0001_initial', '2019-09-11 20:08:24.711570') +ALTER TABLE `django_admin_log` ADD CONSTRAINT `django_admin_log_content_type_id_c4bce8eb_fk_django_co` FOREIGN KEY (`content_type_id`) REFERENCES `django_content_type` (`id`) +ALTER TABLE `django_admin_log` ADD CONSTRAINT `django_admin_log_user_id_c564eba6_fk_accounts_userprofile_id` FOREIGN KEY (`user_id`) REFERENCES `accounts_userprofile` (`id`) +SHOW FULL TABLES +INSERT INTO `django_migrations` (`app`, `name`, `applied`) VALUES ('admin', '0002_logentry_remove_auto_add', '2019-09-11 20:08:24.993999') +SHOW FULL TABLES +INSERT INTO `django_migrations` (`app`, `name`, `applied`) VALUES ('admin', '0003_logentry_add_action_flag_choices', '2019-09-11 20:08:25.005500') +ALTER TABLE `django_content_type` MODIFY `name` varchar(100) NULL +set autocommit=0 +commit +set autocommit=1 +ALTER TABLE `django_content_type` DROP COLUMN `name` +SHOW FULL TABLES +INSERT INTO `django_migrations` (`app`, `name`, `applied`) VALUES ('contenttypes', '0002_remove_content_type_name', '2019-09-11 20:08:25.195532') +CREATE TABLE `auth_permission` (`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY, `name` varchar(50) NOT NULL, `content_type_id` integer NOT NULL, `codename` varchar(100) NOT NULL) +SELECT engine FROM information_schema.tables WHERE table_name = 'auth_permission' +SELECT engine FROM information_schema.tables WHERE table_name = 'auth_permission' +SELECT engine FROM information_schema.tables WHERE table_name = 'auth_permission' +SELECT engine FROM information_schema.tables WHERE table_name = 'auth_permission' +CREATE TABLE `auth_group` (`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY, `name` varchar(80) NOT NULL UNIQUE) +SELECT engine FROM information_schema.tables WHERE table_name = 'auth_group' +SELECT engine FROM information_schema.tables WHERE table_name = 'auth_group' +CREATE TABLE `auth_group_permissions` (`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY, `group_id` integer NOT NULL, `permission_id` integer NOT NULL) +SELECT engine FROM information_schema.tables WHERE table_name = 'auth_group_permissions' +SELECT engine FROM information_schema.tables WHERE table_name = 'auth_group_permissions' +SELECT engine FROM information_schema.tables WHERE table_name = 'auth_group_permissions' +SHOW FULL TABLES +INSERT INTO `django_migrations` (`app`, `name`, `applied`) VALUES ('auth', '0001_initial', '2019-09-11 20:08:25.380981') +ALTER TABLE `auth_permission` ADD CONSTRAINT `auth_permission_content_type_id_2f476e4b_fk_django_co` FOREIGN KEY (`content_type_id`) REFERENCES `django_content_type` (`id`) +ALTER TABLE `auth_permission` ADD CONSTRAINT `auth_permission_content_type_id_codename_01ab375a_uniq` UNIQUE (`content_type_id`, `codename`) +ALTER TABLE `auth_group_permissions` ADD CONSTRAINT `auth_group_permissions_group_id_b120cbf9_fk_auth_group_id` FOREIGN KEY (`group_id`) REFERENCES `auth_group` (`id`) +ALTER TABLE `auth_group_permissions` ADD CONSTRAINT `auth_group_permissio_permission_id_84c5c92e_fk_auth_perm` FOREIGN KEY (`permission_id`) REFERENCES `auth_permission` (`id`) +ALTER TABLE `auth_group_permissions` ADD CONSTRAINT `auth_group_permissions_group_id_permission_id_0cd325b0_uniq` UNIQUE (`group_id`, `permission_id`) +ALTER TABLE `auth_permission` MODIFY `name` varchar(255) NOT NULL +SHOW FULL TABLES +INSERT INTO `django_migrations` (`app`, `name`, `applied`) VALUES ('auth', '0002_alter_permission_name_max_length', '2019-09-11 20:08:25.927116') +SHOW FULL TABLES +INSERT INTO `django_migrations` (`app`, `name`, `applied`) VALUES ('auth', '0003_alter_user_email_max_length', '2019-09-11 20:08:25.944751') +SHOW FULL TABLES +INSERT INTO `django_migrations` (`app`, `name`, `applied`) VALUES ('auth', '0004_alter_user_username_opts', '2019-09-11 20:08:25.954957') +SHOW FULL TABLES +INSERT INTO `django_migrations` (`app`, `name`, `applied`) VALUES ('auth', '0005_alter_user_last_login_null', '2019-09-11 20:08:25.966743') +SHOW FULL TABLES +INSERT INTO `django_migrations` (`app`, `name`, `applied`) VALUES ('auth', '0006_require_contenttypes_0002', '2019-09-11 20:08:25.970363') +SHOW FULL TABLES +INSERT INTO `django_migrations` (`app`, `name`, `applied`) VALUES ('auth', '0007_alter_validators_add_error_messages', '2019-09-11 20:08:25.977706') +SHOW FULL TABLES +INSERT INTO `django_migrations` (`app`, `name`, `applied`) VALUES ('auth', '0008_alter_user_username_max_length', '2019-09-11 20:08:25.988202') +SHOW FULL TABLES +INSERT INTO `django_migrations` (`app`, `name`, `applied`) VALUES ('auth', '0009_alter_user_last_name_max_length', '2019-09-11 20:08:25.996464') +ALTER TABLE `auth_group` MODIFY `name` varchar(150) NOT NULL +SHOW FULL TABLES +INSERT INTO `django_migrations` (`app`, `name`, `applied`) VALUES ('auth', '0010_alter_group_name_max_length', '2019-09-11 20:08:26.006057') +set autocommit=0 +commit +set autocommit=1 +SHOW FULL TABLES +INSERT INTO `django_migrations` (`app`, `name`, `applied`) VALUES ('auth', '0011_update_proxy_permissions', '2019-09-11 20:08:26.019693') +CREATE TABLE `post_post` (`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY, `title` varchar(250) NOT NULL, `body` longtext NOT NULL, `slug` varchar(8) NOT NULL UNIQUE, `pub_date` datetime(6) NOT NULL, `thumbnail` varchar(100) NOT NULL, `author_id` integer NOT NULL) +SELECT engine FROM information_schema.tables WHERE table_name = 'post_post' +SELECT engine FROM information_schema.tables WHERE table_name = 'post_post' +SELECT engine FROM information_schema.tables WHERE table_name = 'post_post' +SELECT engine FROM information_schema.tables WHERE table_name = 'post_post' +SELECT engine FROM information_schema.tables WHERE table_name = 'post_post' +SELECT engine FROM information_schema.tables WHERE table_name = 'post_post' +SELECT engine FROM information_schema.tables WHERE table_name = 'post_post' +SHOW FULL TABLES +INSERT INTO `django_migrations` (`app`, `name`, `applied`) VALUES ('post', '0001_initial', '2019-09-11 20:08:26.078601') +ALTER TABLE `post_post` ADD CONSTRAINT `post_post_author_id_99d134d5_fk_accounts_userprofile_id` FOREIGN KEY (`author_id`) REFERENCES `accounts_userprofile` (`id`) +SHOW FULL TABLES +INSERT INTO `django_migrations` (`app`, `name`, `applied`) VALUES ('post', '0002_auto_20180225_1142', '2019-09-11 20:08:26.223293') +SHOW FULL TABLES +INSERT INTO `django_migrations` (`app`, `name`, `applied`) VALUES ('post', '0003_auto_20180225_1154', '2019-09-11 20:08:26.231490') +SHOW FULL TABLES +INSERT INTO `django_migrations` (`app`, `name`, `applied`) VALUES ('post', '0004_auto_20180225_1256', '2019-09-11 20:08:26.241872') +CREATE TABLE `bookmark_post` (`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY, `obj_id` integer NOT NULL, `user_id` integer NOT NULL) +SELECT engine FROM information_schema.tables WHERE table_name = 'bookmark_post' +SELECT engine FROM information_schema.tables WHERE table_name = 'bookmark_post' +SELECT engine FROM information_schema.tables WHERE table_name = 'bookmark_post' +SHOW FULL TABLES +INSERT INTO `django_migrations` (`app`, `name`, `applied`) VALUES ('bookmarks', '0001_initial', '2019-09-11 20:08:26.303419') +ALTER TABLE `bookmark_post` ADD CONSTRAINT `bookmark_post_obj_id_cff442ed_fk_post_post_id` FOREIGN KEY (`obj_id`) REFERENCES `post_post` (`id`) +ALTER TABLE `bookmark_post` ADD CONSTRAINT `bookmark_post_user_id_ecbdae36_fk_accounts_userprofile_id` FOREIGN KEY (`user_id`) REFERENCES `accounts_userprofile` (`id`) +SELECT kc.`constraint_name`, kc.`column_name`, kc.`referenced_table_name`, kc.`referenced_column_name` FROM information_schema.key_column_usage AS kc WHERE kc.table_schema = DATABASE() AND kc.table_name = 'bookmark_post' ORDER BY kc.`ordinal_position` +SELECT c.constraint_name, c.constraint_type FROM information_schema.table_constraints AS c WHERE c.table_schema = DATABASE() AND c.table_name = 'bookmark_post' +SHOW INDEX FROM `bookmark_post` +ALTER TABLE `bookmark_post` DROP FOREIGN KEY `bookmark_post_obj_id_cff442ed_fk_post_post_id` +ALTER TABLE `bookmark_post` ADD CONSTRAINT `bookmark_post_obj_id_cff442ed_fk_post_post_id` FOREIGN KEY (`obj_id`) REFERENCES `post_post` (`id`) +SHOW FULL TABLES +INSERT INTO `django_migrations` (`app`, `name`, `applied`) VALUES ('bookmarks', '0002_auto_20180307_0102', '2019-09-11 20:08:26.751223') +CREATE TABLE `comments_comment` (`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY, `object_id` integer UNSIGNED NOT NULL, `content` longtext NOT NULL, `timestamp` datetime(6) NOT NULL, `content_type_id` integer NOT NULL, `user_id` integer NOT NULL) +SELECT engine FROM information_schema.tables WHERE table_name = 'comments_comment' +SELECT engine FROM information_schema.tables WHERE table_name = 'comments_comment' +SELECT engine FROM information_schema.tables WHERE table_name = 'comments_comment' +SELECT engine FROM information_schema.tables WHERE table_name = 'comments_comment' +SELECT engine FROM information_schema.tables WHERE table_name = 'comments_comment' +SELECT engine FROM information_schema.tables WHERE table_name = 'comments_comment' +SHOW FULL TABLES +INSERT INTO `django_migrations` (`app`, `name`, `applied`) VALUES ('comments', '0001_initial', '2019-09-11 20:08:26.827533') +ALTER TABLE `comments_comment` ADD CONSTRAINT `comments_comment_content_type_id_72fd5dbe_fk_django_co` FOREIGN KEY (`content_type_id`) REFERENCES `django_content_type` (`id`) +ALTER TABLE `comments_comment` ADD CONSTRAINT `comments_comment_user_id_a1db4881_fk_accounts_userprofile_id` FOREIGN KEY (`user_id`) REFERENCES `accounts_userprofile` (`id`) +ALTER TABLE `comments_comment` ADD COLUMN `parent_comment_id` integer NULL +SELECT engine FROM information_schema.tables WHERE table_name = 'comments_comment' +SHOW FULL TABLES +INSERT INTO `django_migrations` (`app`, `name`, `applied`) VALUES ('comments', '0002_comment_parent_comment', '2019-09-11 20:08:27.232388') +ALTER TABLE `comments_comment` ADD CONSTRAINT `comments_comment_parent_comment_id_71289d4a_fk_comments_` FOREIGN KEY (`parent_comment_id`) REFERENCES `comments_comment` (`id`) +SHOW FULL TABLES +INSERT INTO `django_migrations` (`app`, `name`, `applied`) VALUES ('comments', '0003_auto_20180227_2159', '2019-09-11 20:08:27.408413') +CREATE TABLE `likesdislikes_likedislike` (`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY, `vote` smallint NOT NULL, `object_id` integer UNSIGNED NOT NULL, `content_type_id` integer NOT NULL, `user_id` integer NOT NULL) +SELECT engine FROM information_schema.tables WHERE table_name = 'likesdislikes_likedislike' +SELECT engine FROM information_schema.tables WHERE table_name = 'likesdislikes_likedislike' +SELECT engine FROM information_schema.tables WHERE table_name = 'likesdislikes_likedislike' +SELECT engine FROM information_schema.tables WHERE table_name = 'likesdislikes_likedislike' +SELECT engine FROM information_schema.tables WHERE table_name = 'likesdislikes_likedislike' +SHOW FULL TABLES +INSERT INTO `django_migrations` (`app`, `name`, `applied`) VALUES ('likesdislikes', '0001_initial', '2019-09-11 20:08:27.471337') +ALTER TABLE `likesdislikes_likedislike` ADD CONSTRAINT `likesdislikes_likedi_content_type_id_1bd751d8_fk_django_co` FOREIGN KEY (`content_type_id`) REFERENCES `django_content_type` (`id`) +ALTER TABLE `likesdislikes_likedislike` ADD CONSTRAINT `likesdislikes_likedi_user_id_fbedd04e_fk_accounts_` FOREIGN KEY (`user_id`) REFERENCES `accounts_userprofile` (`id`) +CREATE TABLE `django_session` (`session_key` varchar(40) NOT NULL PRIMARY KEY, `session_data` longtext NOT NULL, `expire_date` datetime(6) NOT NULL) +SELECT engine FROM information_schema.tables WHERE table_name = 'django_session' +SELECT engine FROM information_schema.tables WHERE table_name = 'django_session' +SELECT engine FROM information_schema.tables WHERE table_name = 'django_session' +SHOW FULL TABLES +INSERT INTO `django_migrations` (`app`, `name`, `applied`) VALUES ('sessions', '0001_initial', '2019-09-11 20:08:27.790749') +CREATE INDEX `django_session_expire_date_a5c62663` ON `django_session` (`expire_date`) +SHOW FULL TABLES +SELECT `django_migrations`.`app`, `django_migrations`.`name` FROM `django_migrations` +SELECT `django_content_type`.`id`, `django_content_type`.`app_label`, `django_content_type`.`model` FROM `django_content_type` WHERE `django_content_type`.`app_label` = 'admin' +set autocommit=0 +INSERT INTO `django_content_type` (`app_label`, `model`) VALUES ('admin', 'logentry') +commit +set autocommit=1 +SELECT `django_content_type`.`id`, `django_content_type`.`app_label`, `django_content_type`.`model` FROM `django_content_type` WHERE (`django_content_type`.`app_label` = 'admin' AND `django_content_type`.`model` = 'logentry') +SELECT `auth_permission`.`content_type_id`, `auth_permission`.`codename` FROM `auth_permission` INNER JOIN `django_content_type` ON (`auth_permission`.`content_type_id` = `django_content_type`.`id`) WHERE `auth_permission`.`content_type_id` IN (1) ORDER BY `django_content_type`.`app_label` ASC, `django_content_type`.`model` ASC, `auth_permission`.`codename` ASC +set autocommit=0 +INSERT INTO `auth_permission` (`name`, `content_type_id`, `codename`) VALUES ('Can add log entry', 1, 'add_logentry'), ('Can change log entry', 1, 'change_logentry'), ('Can delete log entry', 1, 'delete_logentry'), ('Can view log entry', 1, 'view_logentry') +commit +set autocommit=1 +SELECT `django_content_type`.`id`, `django_content_type`.`app_label`, `django_content_type`.`model` FROM `django_content_type` WHERE `django_content_type`.`app_label` = 'admin' +SELECT `django_content_type`.`id`, `django_content_type`.`app_label`, `django_content_type`.`model` FROM `django_content_type` WHERE `django_content_type`.`app_label` = 'auth' +set autocommit=0 +INSERT INTO `django_content_type` (`app_label`, `model`) VALUES ('auth', 'permission'), ('auth', 'group') +commit +set autocommit=1 +SELECT `django_content_type`.`id`, `django_content_type`.`app_label`, `django_content_type`.`model` FROM `django_content_type` WHERE (`django_content_type`.`app_label` = 'auth' AND `django_content_type`.`model` = 'permission') +SELECT `django_content_type`.`id`, `django_content_type`.`app_label`, `django_content_type`.`model` FROM `django_content_type` WHERE (`django_content_type`.`app_label` = 'auth' AND `django_content_type`.`model` = 'group') +SELECT `auth_permission`.`content_type_id`, `auth_permission`.`codename` FROM `auth_permission` INNER JOIN `django_content_type` ON (`auth_permission`.`content_type_id` = `django_content_type`.`id`) WHERE `auth_permission`.`content_type_id` IN (2, 3) ORDER BY `django_content_type`.`app_label` ASC, `django_content_type`.`model` ASC, `auth_permission`.`codename` ASC +set autocommit=0 +INSERT INTO `auth_permission` (`name`, `content_type_id`, `codename`) VALUES ('Can add permission', 2, 'add_permission'), ('Can change permission', 2, 'change_permission'), ('Can delete permission', 2, 'delete_permission'), ('Can view permission', 2, 'view_permission'), ('Can add group', 3, 'add_group'), ('Can change group', 3, 'change_group'), ('Can delete group', 3, 'delete_group'), ('Can view group', 3, 'view_group') +commit +set autocommit=1 +SELECT `django_content_type`.`id`, `django_content_type`.`app_label`, `django_content_type`.`model` FROM `django_content_type` WHERE `django_content_type`.`app_label` = 'auth' +SELECT `django_content_type`.`id`, `django_content_type`.`app_label`, `django_content_type`.`model` FROM `django_content_type` WHERE `django_content_type`.`app_label` = 'contenttypes' +set autocommit=0 +INSERT INTO `django_content_type` (`app_label`, `model`) VALUES ('contenttypes', 'contenttype') +commit +set autocommit=1 +SELECT `django_content_type`.`id`, `django_content_type`.`app_label`, `django_content_type`.`model` FROM `django_content_type` WHERE (`django_content_type`.`app_label` = 'contenttypes' AND `django_content_type`.`model` = 'contenttype') +SELECT `auth_permission`.`content_type_id`, `auth_permission`.`codename` FROM `auth_permission` INNER JOIN `django_content_type` ON (`auth_permission`.`content_type_id` = `django_content_type`.`id`) WHERE `auth_permission`.`content_type_id` IN (4) ORDER BY `django_content_type`.`app_label` ASC, `django_content_type`.`model` ASC, `auth_permission`.`codename` ASC +set autocommit=0 +INSERT INTO `auth_permission` (`name`, `content_type_id`, `codename`) VALUES ('Can add content type', 4, 'add_contenttype'), ('Can change content type', 4, 'change_contenttype'), ('Can delete content type', 4, 'delete_contenttype'), ('Can view content type', 4, 'view_contenttype') +commit +set autocommit=1 +SELECT `django_content_type`.`id`, `django_content_type`.`app_label`, `django_content_type`.`model` FROM `django_content_type` WHERE `django_content_type`.`app_label` = 'contenttypes' +SELECT `django_content_type`.`id`, `django_content_type`.`app_label`, `django_content_type`.`model` FROM `django_content_type` WHERE `django_content_type`.`app_label` = 'sessions' +set autocommit=0 +INSERT INTO `django_content_type` (`app_label`, `model`) VALUES ('sessions', 'session') +commit +set autocommit=1 +SELECT `django_content_type`.`id`, `django_content_type`.`app_label`, `django_content_type`.`model` FROM `django_content_type` WHERE (`django_content_type`.`app_label` = 'sessions' AND `django_content_type`.`model` = 'session') +SELECT `auth_permission`.`content_type_id`, `auth_permission`.`codename` FROM `auth_permission` INNER JOIN `django_content_type` ON (`auth_permission`.`content_type_id` = `django_content_type`.`id`) WHERE `auth_permission`.`content_type_id` IN (5) ORDER BY `django_content_type`.`app_label` ASC, `django_content_type`.`model` ASC, `auth_permission`.`codename` ASC +set autocommit=0 +INSERT INTO `auth_permission` (`name`, `content_type_id`, `codename`) VALUES ('Can add session', 5, 'add_session'), ('Can change session', 5, 'change_session'), ('Can delete session', 5, 'delete_session'), ('Can view session', 5, 'view_session') +commit +set autocommit=1 +SELECT `django_content_type`.`id`, `django_content_type`.`app_label`, `django_content_type`.`model` FROM `django_content_type` WHERE `django_content_type`.`app_label` = 'sessions' +SELECT `django_content_type`.`id`, `django_content_type`.`app_label`, `django_content_type`.`model` FROM `django_content_type` WHERE `django_content_type`.`app_label` = 'post' +set autocommit=0 +INSERT INTO `django_content_type` (`app_label`, `model`) VALUES ('post', 'post') +commit +set autocommit=1 +SELECT `django_content_type`.`id`, `django_content_type`.`app_label`, `django_content_type`.`model` FROM `django_content_type` WHERE (`django_content_type`.`app_label` = 'post' AND `django_content_type`.`model` = 'post') +SELECT `auth_permission`.`content_type_id`, `auth_permission`.`codename` FROM `auth_permission` INNER JOIN `django_content_type` ON (`auth_permission`.`content_type_id` = `django_content_type`.`id`) WHERE `auth_permission`.`content_type_id` IN (6) ORDER BY `django_content_type`.`app_label` ASC, `django_content_type`.`model` ASC, `auth_permission`.`codename` ASC +set autocommit=0 +INSERT INTO `auth_permission` (`name`, `content_type_id`, `codename`) VALUES ('Can add post', 6, 'add_post'), ('Can change post', 6, 'change_post'), ('Can delete post', 6, 'delete_post'), ('Can view post', 6, 'view_post') +commit +set autocommit=1 +SELECT `django_content_type`.`id`, `django_content_type`.`app_label`, `django_content_type`.`model` FROM `django_content_type` WHERE `django_content_type`.`app_label` = 'post' +SELECT `django_content_type`.`id`, `django_content_type`.`app_label`, `django_content_type`.`model` FROM `django_content_type` WHERE `django_content_type`.`app_label` = 'accounts' +set autocommit=0 +INSERT INTO `django_content_type` (`app_label`, `model`) VALUES ('accounts', 'userprofile') +commit +set autocommit=1 +SELECT `django_content_type`.`id`, `django_content_type`.`app_label`, `django_content_type`.`model` FROM `django_content_type` WHERE (`django_content_type`.`app_label` = 'accounts' AND `django_content_type`.`model` = 'userprofile') +SELECT `auth_permission`.`content_type_id`, `auth_permission`.`codename` FROM `auth_permission` INNER JOIN `django_content_type` ON (`auth_permission`.`content_type_id` = `django_content_type`.`id`) WHERE `auth_permission`.`content_type_id` IN (7) ORDER BY `django_content_type`.`app_label` ASC, `django_content_type`.`model` ASC, `auth_permission`.`codename` ASC +set autocommit=0 +INSERT INTO `auth_permission` (`name`, `content_type_id`, `codename`) VALUES ('Can add user profile', 7, 'add_userprofile'), ('Can change user profile', 7, 'change_userprofile'), ('Can delete user profile', 7, 'delete_userprofile'), ('Can view user profile', 7, 'view_userprofile') +commit +set autocommit=1 +SELECT `django_content_type`.`id`, `django_content_type`.`app_label`, `django_content_type`.`model` FROM `django_content_type` WHERE `django_content_type`.`app_label` = 'accounts' +SELECT `django_content_type`.`id`, `django_content_type`.`app_label`, `django_content_type`.`model` FROM `django_content_type` WHERE `django_content_type`.`app_label` = 'comments' +set autocommit=0 +INSERT INTO `django_content_type` (`app_label`, `model`) VALUES ('comments', 'comment') +commit +set autocommit=1 +SELECT `django_content_type`.`id`, `django_content_type`.`app_label`, `django_content_type`.`model` FROM `django_content_type` WHERE (`django_content_type`.`app_label` = 'comments' AND `django_content_type`.`model` = 'comment') +SELECT `auth_permission`.`content_type_id`, `auth_permission`.`codename` FROM `auth_permission` INNER JOIN `django_content_type` ON (`auth_permission`.`content_type_id` = `django_content_type`.`id`) WHERE `auth_permission`.`content_type_id` IN (8) ORDER BY `django_content_type`.`app_label` ASC, `django_content_type`.`model` ASC, `auth_permission`.`codename` ASC +set autocommit=0 +INSERT INTO `auth_permission` (`name`, `content_type_id`, `codename`) VALUES ('Can add comment', 8, 'add_comment'), ('Can change comment', 8, 'change_comment'), ('Can delete comment', 8, 'delete_comment'), ('Can view comment', 8, 'view_comment') +commit +set autocommit=1 +SELECT `django_content_type`.`id`, `django_content_type`.`app_label`, `django_content_type`.`model` FROM `django_content_type` WHERE `django_content_type`.`app_label` = 'comments' +SELECT `django_content_type`.`id`, `django_content_type`.`app_label`, `django_content_type`.`model` FROM `django_content_type` WHERE `django_content_type`.`app_label` = 'likesdislikes' +set autocommit=0 +INSERT INTO `django_content_type` (`app_label`, `model`) VALUES ('likesdislikes', 'likedislike') +commit +set autocommit=1 +SELECT `django_content_type`.`id`, `django_content_type`.`app_label`, `django_content_type`.`model` FROM `django_content_type` WHERE (`django_content_type`.`app_label` = 'likesdislikes' AND `django_content_type`.`model` = 'likedislike') +SELECT `auth_permission`.`content_type_id`, `auth_permission`.`codename` FROM `auth_permission` INNER JOIN `django_content_type` ON (`auth_permission`.`content_type_id` = `django_content_type`.`id`) WHERE `auth_permission`.`content_type_id` IN (9) ORDER BY `django_content_type`.`app_label` ASC, `django_content_type`.`model` ASC, `auth_permission`.`codename` ASC +set autocommit=0 +INSERT INTO `auth_permission` (`name`, `content_type_id`, `codename`) VALUES ('Can add like dislike', 9, 'add_likedislike'), ('Can change like dislike', 9, 'change_likedislike'), ('Can delete like dislike', 9, 'delete_likedislike'), ('Can view like dislike', 9, 'view_likedislike') +commit +set autocommit=1 +SELECT `django_content_type`.`id`, `django_content_type`.`app_label`, `django_content_type`.`model` FROM `django_content_type` WHERE `django_content_type`.`app_label` = 'likesdislikes' +SELECT `django_content_type`.`id`, `django_content_type`.`app_label`, `django_content_type`.`model` FROM `django_content_type` WHERE `django_content_type`.`app_label` = 'bookmarks' +set autocommit=0 +INSERT INTO `django_content_type` (`app_label`, `model`) VALUES ('bookmarks', 'bookmarkpost') +commit +set autocommit=1 +SELECT `django_content_type`.`id`, `django_content_type`.`app_label`, `django_content_type`.`model` FROM `django_content_type` WHERE (`django_content_type`.`app_label` = 'bookmarks' AND `django_content_type`.`model` = 'bookmarkpost') +SELECT `auth_permission`.`content_type_id`, `auth_permission`.`codename` FROM `auth_permission` INNER JOIN `django_content_type` ON (`auth_permission`.`content_type_id` = `django_content_type`.`id`) WHERE `auth_permission`.`content_type_id` IN (10) ORDER BY `django_content_type`.`app_label` ASC, `django_content_type`.`model` ASC, `auth_permission`.`codename` ASC +set autocommit=0 +INSERT INTO `auth_permission` (`name`, `content_type_id`, `codename`) VALUES ('Can add bookmark post', 10, 'add_bookmarkpost'), ('Can change bookmark post', 10, 'change_bookmarkpost'), ('Can delete bookmark post', 10, 'delete_bookmarkpost'), ('Can view bookmark post', 10, 'view_bookmarkpost') +commit +set autocommit=1 +SELECT `django_content_type`.`id`, `django_content_type`.`app_label`, `django_content_type`.`model` FROM `django_content_type` WHERE `django_content_type`.`app_label` = 'bookmarks' +SELECT `django_content_type`.`id`, `django_content_type`.`app_label`, `django_content_type`.`model` FROM `django_content_type` WHERE `django_content_type`.`app_label` = 'pagedown' +SELECT `django_content_type`.`id`, `django_content_type`.`app_label`, `django_content_type`.`model` FROM `django_content_type` WHERE `django_content_type`.`app_label` = 'pagedown' \ No newline at end of file diff --git a/go/vt/sqlparser/token.go b/go/vt/sqlparser/token.go index 0247cbf3cc6..f7fd4850f30 100644 --- a/go/vt/sqlparser/token.go +++ b/go/vt/sqlparser/token.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -117,7 +117,7 @@ var keywords = map[string]int{ "char": CHAR, "character": CHARACTER, "charset": CHARSET, - "check": UNUSED, + "check": CHECK, "collate": COLLATE, "collation": COLLATION, "column": COLUMN, @@ -391,6 +391,7 @@ var keywords = map[string]int{ "vindex": VINDEX, "vindexes": VINDEXES, "view": VIEW, + "vitess_metadata": VITESS_METADATA, "vschema": VSCHEMA, "warnings": WARNINGS, "when": WHEN, diff --git a/go/vt/sqlparser/token_test.go b/go/vt/sqlparser/token_test.go index 93543545178..531696d37e9 100644 --- a/go/vt/sqlparser/token_test.go +++ b/go/vt/sqlparser/token_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/sqlparser/tracked_buffer.go b/go/vt/sqlparser/tracked_buffer.go index f14751f96be..5e5383ed0f1 100644 --- a/go/vt/sqlparser/tracked_buffer.go +++ b/go/vt/sqlparser/tracked_buffer.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/sqlparser/truncate_query.go b/go/vt/sqlparser/truncate_query.go index fd12ae25c4b..a441c812aed 100644 --- a/go/vt/sqlparser/truncate_query.go +++ b/go/vt/sqlparser/truncate_query.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/srvtopo/discover.go b/go/vt/srvtopo/discover.go index e2a3a8530d1..f30f78e1bf2 100644 --- a/go/vt/srvtopo/discover.go +++ b/go/vt/srvtopo/discover.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/srvtopo/discover_test.go b/go/vt/srvtopo/discover_test.go index 56a07a6af4c..b9ee29ddd61 100644 --- a/go/vt/srvtopo/discover_test.go +++ b/go/vt/srvtopo/discover_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/srvtopo/keyspace_filtering_server.go b/go/vt/srvtopo/keyspace_filtering_server.go index 6e272cf1939..07d38e01d1e 100644 --- a/go/vt/srvtopo/keyspace_filtering_server.go +++ b/go/vt/srvtopo/keyspace_filtering_server.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Vitess Authors. +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. diff --git a/go/vt/srvtopo/keyspace_filtering_server_test.go b/go/vt/srvtopo/keyspace_filtering_server_test.go index 8c0560dfbe0..f2c3e282362 100644 --- a/go/vt/srvtopo/keyspace_filtering_server_test.go +++ b/go/vt/srvtopo/keyspace_filtering_server_test.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Vitess Authors. +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. diff --git a/go/vt/srvtopo/resilient_server.go b/go/vt/srvtopo/resilient_server.go index 6340bfe6551..dce6f3dccda 100644 --- a/go/vt/srvtopo/resilient_server.go +++ b/go/vt/srvtopo/resilient_server.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/srvtopo/resilient_server_flaky_test.go b/go/vt/srvtopo/resilient_server_flaky_test.go index e40d9500c32..ed0cd2bca00 100644 --- a/go/vt/srvtopo/resilient_server_flaky_test.go +++ b/go/vt/srvtopo/resilient_server_flaky_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/srvtopo/resolver.go b/go/vt/srvtopo/resolver.go index e67cebe5d7c..a7a5043cf3a 100644 --- a/go/vt/srvtopo/resolver.go +++ b/go/vt/srvtopo/resolver.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/srvtopo/resolver_test.go b/go/vt/srvtopo/resolver_test.go index f58e069a2a5..18b0d0cd6e7 100644 --- a/go/vt/srvtopo/resolver_test.go +++ b/go/vt/srvtopo/resolver_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/srvtopo/server.go b/go/vt/srvtopo/server.go index b783c78d3f8..69b883297c2 100644 --- a/go/vt/srvtopo/server.go +++ b/go/vt/srvtopo/server.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/srvtopo/srvtopotest/passthrough.go b/go/vt/srvtopo/srvtopotest/passthrough.go index 09b0bae2fa7..3aa4dc86ff5 100644 --- a/go/vt/srvtopo/srvtopotest/passthrough.go +++ b/go/vt/srvtopo/srvtopotest/passthrough.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Vitess Authors. +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. diff --git a/go/vt/srvtopo/target_stats.go b/go/vt/srvtopo/target_stats.go index 6af44eedb81..8dd11763647 100644 --- a/go/vt/srvtopo/target_stats.go +++ b/go/vt/srvtopo/target_stats.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/status/status.go b/go/vt/status/status.go index 670f890ef58..db15fd34146 100644 --- a/go/vt/status/status.go +++ b/go/vt/status/status.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/tableacl/acl/acl.go b/go/vt/tableacl/acl/acl.go index cae56fa2c78..abff749384c 100644 --- a/go/vt/tableacl/acl/acl.go +++ b/go/vt/tableacl/acl/acl.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/tableacl/role.go b/go/vt/tableacl/role.go index 5d87387352e..f83f1b8afc3 100644 --- a/go/vt/tableacl/role.go +++ b/go/vt/tableacl/role.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/tableacl/role_test.go b/go/vt/tableacl/role_test.go index c6f501f5272..9e3f0bf9359 100644 --- a/go/vt/tableacl/role_test.go +++ b/go/vt/tableacl/role_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/tableacl/simpleacl/simpleacl.go b/go/vt/tableacl/simpleacl/simpleacl.go index 84e06f590d2..70303a3dbab 100644 --- a/go/vt/tableacl/simpleacl/simpleacl.go +++ b/go/vt/tableacl/simpleacl/simpleacl.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/tableacl/simpleacl/simpleacl_test.go b/go/vt/tableacl/simpleacl/simpleacl_test.go index 8549eb6e5e2..56ee83441e1 100644 --- a/go/vt/tableacl/simpleacl/simpleacl_test.go +++ b/go/vt/tableacl/simpleacl/simpleacl_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/tableacl/tableacl.go b/go/vt/tableacl/tableacl.go index dd15c7eb708..03459be892b 100644 --- a/go/vt/tableacl/tableacl.go +++ b/go/vt/tableacl/tableacl.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/tableacl/tableacl_test.go b/go/vt/tableacl/tableacl_test.go index 68e319508f1..0b652c24bc2 100644 --- a/go/vt/tableacl/tableacl_test.go +++ b/go/vt/tableacl/tableacl_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/tableacl/testlib/testlib.go b/go/vt/tableacl/testlib/testlib.go index f5addf01e81..3c30c43d8dc 100644 --- a/go/vt/tableacl/testlib/testlib.go +++ b/go/vt/tableacl/testlib/testlib.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/throttler/aggregated_interval_history.go b/go/vt/throttler/aggregated_interval_history.go index 5816f0aa60a..5426d1d0e9f 100644 --- a/go/vt/throttler/aggregated_interval_history.go +++ b/go/vt/throttler/aggregated_interval_history.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/throttler/aggregated_interval_history_test.go b/go/vt/throttler/aggregated_interval_history_test.go index 4ba5adec631..6a77d57af07 100644 --- a/go/vt/throttler/aggregated_interval_history_test.go +++ b/go/vt/throttler/aggregated_interval_history_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/throttler/demo/throttler_demo.go b/go/vt/throttler/demo/throttler_demo.go index 77d61e1fcdd..783a27b8afd 100644 --- a/go/vt/throttler/demo/throttler_demo.go +++ b/go/vt/throttler/demo/throttler_demo.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/throttler/fake_rates_history_test.go b/go/vt/throttler/fake_rates_history_test.go index 14c1d3eddcd..1028f898173 100644 --- a/go/vt/throttler/fake_rates_history_test.go +++ b/go/vt/throttler/fake_rates_history_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/throttler/grpcthrottlerclient/grpcthrottlerclient.go b/go/vt/throttler/grpcthrottlerclient/grpcthrottlerclient.go index 41238fed2e4..3921375327d 100644 --- a/go/vt/throttler/grpcthrottlerclient/grpcthrottlerclient.go +++ b/go/vt/throttler/grpcthrottlerclient/grpcthrottlerclient.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/throttler/grpcthrottlerclient/grpcthrottlerclient_test.go b/go/vt/throttler/grpcthrottlerclient/grpcthrottlerclient_test.go index c85d9efe923..8bb468e1538 100644 --- a/go/vt/throttler/grpcthrottlerclient/grpcthrottlerclient_test.go +++ b/go/vt/throttler/grpcthrottlerclient/grpcthrottlerclient_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/throttler/grpcthrottlerserver/grpcthrottlerserver.go b/go/vt/throttler/grpcthrottlerserver/grpcthrottlerserver.go index adc77c5932d..62fabff7642 100644 --- a/go/vt/throttler/grpcthrottlerserver/grpcthrottlerserver.go +++ b/go/vt/throttler/grpcthrottlerserver/grpcthrottlerserver.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/throttler/interval_history.go b/go/vt/throttler/interval_history.go index bac4d560f83..174f7581aaf 100644 --- a/go/vt/throttler/interval_history.go +++ b/go/vt/throttler/interval_history.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/throttler/interval_history_test.go b/go/vt/throttler/interval_history_test.go index 36536df1fa9..7bad56e41c1 100644 --- a/go/vt/throttler/interval_history_test.go +++ b/go/vt/throttler/interval_history_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/throttler/manager.go b/go/vt/throttler/manager.go index bbc3f987d98..32790a9d601 100644 --- a/go/vt/throttler/manager.go +++ b/go/vt/throttler/manager.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/throttler/manager_test.go b/go/vt/throttler/manager_test.go index 47c969bb3b1..2eaea444276 100644 --- a/go/vt/throttler/manager_test.go +++ b/go/vt/throttler/manager_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/throttler/max_rate_module.go b/go/vt/throttler/max_rate_module.go index 9c7efaf4531..2b2cb246212 100644 --- a/go/vt/throttler/max_rate_module.go +++ b/go/vt/throttler/max_rate_module.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/throttler/max_replication_lag_module.go b/go/vt/throttler/max_replication_lag_module.go index 8881f59d302..e0219d40b76 100644 --- a/go/vt/throttler/max_replication_lag_module.go +++ b/go/vt/throttler/max_replication_lag_module.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/throttler/max_replication_lag_module_config.go b/go/vt/throttler/max_replication_lag_module_config.go index a2abb3c2382..d86ed773147 100644 --- a/go/vt/throttler/max_replication_lag_module_config.go +++ b/go/vt/throttler/max_replication_lag_module_config.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/throttler/max_replication_lag_module_test.go b/go/vt/throttler/max_replication_lag_module_test.go index 4d2eef4263c..100a76f7726 100644 --- a/go/vt/throttler/max_replication_lag_module_test.go +++ b/go/vt/throttler/max_replication_lag_module_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/throttler/memory.go b/go/vt/throttler/memory.go index 9344c8e7ce5..e139890d3a7 100644 --- a/go/vt/throttler/memory.go +++ b/go/vt/throttler/memory.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/throttler/memory_test.go b/go/vt/throttler/memory_test.go index 5ffb323af2e..cb5cba582a2 100644 --- a/go/vt/throttler/memory_test.go +++ b/go/vt/throttler/memory_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/throttler/module.go b/go/vt/throttler/module.go index d5d83c9abb4..9f86f66584f 100644 --- a/go/vt/throttler/module.go +++ b/go/vt/throttler/module.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/throttler/record.go b/go/vt/throttler/record.go index 308e5dfb6fb..b981144c6ba 100644 --- a/go/vt/throttler/record.go +++ b/go/vt/throttler/record.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/throttler/replication_lag_cache.go b/go/vt/throttler/replication_lag_cache.go index 4354ea49610..5e14f5b86b6 100644 --- a/go/vt/throttler/replication_lag_cache.go +++ b/go/vt/throttler/replication_lag_cache.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/throttler/replication_lag_cache_test.go b/go/vt/throttler/replication_lag_cache_test.go index e3e06896aa7..c2381f05246 100644 --- a/go/vt/throttler/replication_lag_cache_test.go +++ b/go/vt/throttler/replication_lag_cache_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/throttler/replication_lag_record.go b/go/vt/throttler/replication_lag_record.go index d4b3107ed83..bd233ec8803 100644 --- a/go/vt/throttler/replication_lag_record.go +++ b/go/vt/throttler/replication_lag_record.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/throttler/result.go b/go/vt/throttler/result.go index 1266a40cf37..31824574a05 100644 --- a/go/vt/throttler/result.go +++ b/go/vt/throttler/result.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/throttler/result_test.go b/go/vt/throttler/result_test.go index b76a6b4d4e1..b4377ff48ae 100644 --- a/go/vt/throttler/result_test.go +++ b/go/vt/throttler/result_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/throttler/thread_throttler.go b/go/vt/throttler/thread_throttler.go index e831652a77f..957f726fe48 100644 --- a/go/vt/throttler/thread_throttler.go +++ b/go/vt/throttler/thread_throttler.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/throttler/thread_throttler_test.go b/go/vt/throttler/thread_throttler_test.go index 4485f336d83..7cb27e76487 100644 --- a/go/vt/throttler/thread_throttler_test.go +++ b/go/vt/throttler/thread_throttler_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/throttler/throttler.go b/go/vt/throttler/throttler.go index 4db59307ede..7de6ca65fdc 100644 --- a/go/vt/throttler/throttler.go +++ b/go/vt/throttler/throttler.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/throttler/throttler_test.go b/go/vt/throttler/throttler_test.go index 6aacf7b67b4..dcd752697a1 100644 --- a/go/vt/throttler/throttler_test.go +++ b/go/vt/throttler/throttler_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/throttler/throttlerclient/throttlerclient.go b/go/vt/throttler/throttlerclient/throttlerclient.go index cfcbd05ef8e..4e97c2dad62 100644 --- a/go/vt/throttler/throttlerclient/throttlerclient.go +++ b/go/vt/throttler/throttlerclient/throttlerclient.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/throttler/throttlerclienttest/throttlerclient_testsuite.go b/go/vt/throttler/throttlerclienttest/throttlerclient_testsuite.go index 676396646f4..feeeb8ca196 100644 --- a/go/vt/throttler/throttlerclienttest/throttlerclient_testsuite.go +++ b/go/vt/throttler/throttlerclienttest/throttlerclient_testsuite.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/throttler/throttlerlogz.go b/go/vt/throttler/throttlerlogz.go index ad46bd156e0..71d5f211931 100644 --- a/go/vt/throttler/throttlerlogz.go +++ b/go/vt/throttler/throttlerlogz.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/throttler/throttlerlogz_test.go b/go/vt/throttler/throttlerlogz_test.go index a7651f883fd..82ebb77e7a1 100644 --- a/go/vt/throttler/throttlerlogz_test.go +++ b/go/vt/throttler/throttlerlogz_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/throttler/throttlerz.go b/go/vt/throttler/throttlerz.go index 28c105b7b1c..9e3dbf544ed 100644 --- a/go/vt/throttler/throttlerz.go +++ b/go/vt/throttler/throttlerz.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/throttler/throttlerz_test.go b/go/vt/throttler/throttlerz_test.go index 84fb847dc8b..be40598468a 100644 --- a/go/vt/throttler/throttlerz_test.go +++ b/go/vt/throttler/throttlerz_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/tlstest/tlstest.go b/go/vt/tlstest/tlstest.go index 295dddcb017..89b715cf523 100644 --- a/go/vt/tlstest/tlstest.go +++ b/go/vt/tlstest/tlstest.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/tlstest/tlstest_test.go b/go/vt/tlstest/tlstest_test.go index b8bd0039d6f..112fd493c41 100644 --- a/go/vt/tlstest/tlstest_test.go +++ b/go/vt/tlstest/tlstest_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/topo/cell_info.go b/go/vt/topo/cell_info.go index 7549705a1d3..c07b8db0b76 100644 --- a/go/vt/topo/cell_info.go +++ b/go/vt/topo/cell_info.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/topo/cells_aliases_test.go b/go/vt/topo/cells_aliases_test.go index fe500f1d344..2dbf50aac89 100644 --- a/go/vt/topo/cells_aliases_test.go +++ b/go/vt/topo/cells_aliases_test.go @@ -1,3 +1,19 @@ +/* +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 topo import ( diff --git a/go/vt/topo/conn.go b/go/vt/topo/conn.go index 2e55e9fb026..7f768d5a703 100644 --- a/go/vt/topo/conn.go +++ b/go/vt/topo/conn.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/topo/consultopo/config.go b/go/vt/topo/consultopo/config.go index 9c4fc5fe1bc..da3e7f44fb4 100644 --- a/go/vt/topo/consultopo/config.go +++ b/go/vt/topo/consultopo/config.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/topo/consultopo/directory.go b/go/vt/topo/consultopo/directory.go index 66e0473e9f1..843835523d4 100644 --- a/go/vt/topo/consultopo/directory.go +++ b/go/vt/topo/consultopo/directory.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/topo/consultopo/election.go b/go/vt/topo/consultopo/election.go index bacbbac8d58..87c2363387c 100644 --- a/go/vt/topo/consultopo/election.go +++ b/go/vt/topo/consultopo/election.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/topo/consultopo/error.go b/go/vt/topo/consultopo/error.go index 218fd6b9058..f8aad4d1c61 100644 --- a/go/vt/topo/consultopo/error.go +++ b/go/vt/topo/consultopo/error.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/topo/consultopo/file.go b/go/vt/topo/consultopo/file.go index cdb64463427..4cce43c9d4e 100644 --- a/go/vt/topo/consultopo/file.go +++ b/go/vt/topo/consultopo/file.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/topo/consultopo/lock.go b/go/vt/topo/consultopo/lock.go index 49556fa3404..c8a5636b3f3 100644 --- a/go/vt/topo/consultopo/lock.go +++ b/go/vt/topo/consultopo/lock.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 @@ -136,7 +136,7 @@ func (s *Server) unlock(ctx context.Context, lockPath string) error { close(li.done) // Then try to remove the lock entirely. This will only work if - // noone else has the lock. + // no one else has the lock. if err := li.lock.Destroy(); err != nil { // If someone else has the lock, we can't remove it, // but we don't need to. diff --git a/go/vt/topo/consultopo/server.go b/go/vt/topo/consultopo/server.go index b68185bd00c..d141116cbf6 100644 --- a/go/vt/topo/consultopo/server.go +++ b/go/vt/topo/consultopo/server.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/topo/consultopo/server_test.go b/go/vt/topo/consultopo/server_test.go index c914d116be5..ab641309ac9 100644 --- a/go/vt/topo/consultopo/server_test.go +++ b/go/vt/topo/consultopo/server_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/topo/consultopo/version.go b/go/vt/topo/consultopo/version.go index 920b31750a6..49071136024 100644 --- a/go/vt/topo/consultopo/version.go +++ b/go/vt/topo/consultopo/version.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/topo/consultopo/watch.go b/go/vt/topo/consultopo/watch.go index 8021738ca4c..e97aaf9d106 100644 --- a/go/vt/topo/consultopo/watch.go +++ b/go/vt/topo/consultopo/watch.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/topo/errors.go b/go/vt/topo/errors.go index 9b34035f214..85158e358b8 100644 --- a/go/vt/topo/errors.go +++ b/go/vt/topo/errors.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Vitess Authors. +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. diff --git a/go/vt/topo/etcd2topo/config.go b/go/vt/topo/etcd2topo/config.go index bfe9e61e3a8..196f6a9ecae 100644 --- a/go/vt/topo/etcd2topo/config.go +++ b/go/vt/topo/etcd2topo/config.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/topo/etcd2topo/directory.go b/go/vt/topo/etcd2topo/directory.go index 343c20af1bc..4eb92e448b4 100644 --- a/go/vt/topo/etcd2topo/directory.go +++ b/go/vt/topo/etcd2topo/directory.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/topo/etcd2topo/election.go b/go/vt/topo/etcd2topo/election.go index 354c5e49932..5473bd1c27a 100644 --- a/go/vt/topo/etcd2topo/election.go +++ b/go/vt/topo/etcd2topo/election.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/topo/etcd2topo/error.go b/go/vt/topo/etcd2topo/error.go index 0344711d468..99758b350b3 100644 --- a/go/vt/topo/etcd2topo/error.go +++ b/go/vt/topo/etcd2topo/error.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/topo/etcd2topo/file.go b/go/vt/topo/etcd2topo/file.go index 0ba1581d710..ba481093ef8 100644 --- a/go/vt/topo/etcd2topo/file.go +++ b/go/vt/topo/etcd2topo/file.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/topo/etcd2topo/lock.go b/go/vt/topo/etcd2topo/lock.go index 27928cf3e25..9827a6af4e3 100644 --- a/go/vt/topo/etcd2topo/lock.go +++ b/go/vt/topo/etcd2topo/lock.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/topo/etcd2topo/server.go b/go/vt/topo/etcd2topo/server.go index 9aae349cd1a..8e6b2588a48 100644 --- a/go/vt/topo/etcd2topo/server.go +++ b/go/vt/topo/etcd2topo/server.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/topo/etcd2topo/server_test.go b/go/vt/topo/etcd2topo/server_test.go index beccd612b67..c782e9638a3 100644 --- a/go/vt/topo/etcd2topo/server_test.go +++ b/go/vt/topo/etcd2topo/server_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/topo/etcd2topo/version.go b/go/vt/topo/etcd2topo/version.go index 192bfa236e3..5fc0a704af8 100644 --- a/go/vt/topo/etcd2topo/version.go +++ b/go/vt/topo/etcd2topo/version.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/topo/etcd2topo/watch.go b/go/vt/topo/etcd2topo/watch.go index 706fd994eb1..f6f45f9d616 100644 --- a/go/vt/topo/etcd2topo/watch.go +++ b/go/vt/topo/etcd2topo/watch.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 @@ -74,7 +74,7 @@ func (s *Server) Watch(ctx context.Context, filePath string) (*topo.WatchData, < select { case <-watchCtx.Done(): - // This includes context cancelation errors. + // This includes context cancellation errors. notifications <- &topo.WatchData{ Err: convertError(watchCtx.Err(), nodePath), } diff --git a/go/vt/topo/events/doc.go b/go/vt/topo/events/doc.go index d6c19e67251..eadbbd0dcd6 100644 --- a/go/vt/topo/events/doc.go +++ b/go/vt/topo/events/doc.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/topo/events/keyspace_change.go b/go/vt/topo/events/keyspace_change.go index 99d58345398..c03518d8c80 100644 --- a/go/vt/topo/events/keyspace_change.go +++ b/go/vt/topo/events/keyspace_change.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/topo/events/keyspace_change_syslog.go b/go/vt/topo/events/keyspace_change_syslog.go index 68df0db3426..d7f456ae6b8 100644 --- a/go/vt/topo/events/keyspace_change_syslog.go +++ b/go/vt/topo/events/keyspace_change_syslog.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/topo/events/keyspace_change_syslog_test.go b/go/vt/topo/events/keyspace_change_syslog_test.go index ddb3dcea708..f068ff26266 100644 --- a/go/vt/topo/events/keyspace_change_syslog_test.go +++ b/go/vt/topo/events/keyspace_change_syslog_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/topo/events/metadata_change.go b/go/vt/topo/events/metadata_change.go new file mode 100644 index 00000000000..0322e8ea95a --- /dev/null +++ b/go/vt/topo/events/metadata_change.go @@ -0,0 +1,23 @@ +/* +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 events + +// MetadataChange is an event that describes changes to topology metadata +type MetadataChange struct { + Key string + Status string +} diff --git a/go/vt/topo/events/shard_change.go b/go/vt/topo/events/shard_change.go index 7d208f33b91..29331d87947 100644 --- a/go/vt/topo/events/shard_change.go +++ b/go/vt/topo/events/shard_change.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/topo/events/shard_change_syslog.go b/go/vt/topo/events/shard_change_syslog.go index f79fffa6bbe..3f6422a9175 100644 --- a/go/vt/topo/events/shard_change_syslog.go +++ b/go/vt/topo/events/shard_change_syslog.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/topo/events/shard_change_syslog_test.go b/go/vt/topo/events/shard_change_syslog_test.go index 0ae9bb99760..6653bd9171e 100644 --- a/go/vt/topo/events/shard_change_syslog_test.go +++ b/go/vt/topo/events/shard_change_syslog_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/topo/events/tablet_change.go b/go/vt/topo/events/tablet_change.go index 2ba092525f9..a0ef2e61b8b 100644 --- a/go/vt/topo/events/tablet_change.go +++ b/go/vt/topo/events/tablet_change.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/topo/events/tablet_change_syslog.go b/go/vt/topo/events/tablet_change_syslog.go index 6669a82ebdc..e2dae020c8e 100644 --- a/go/vt/topo/events/tablet_change_syslog.go +++ b/go/vt/topo/events/tablet_change_syslog.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/topo/events/tablet_change_syslog_test.go b/go/vt/topo/events/tablet_change_syslog_test.go index 043d0ff153c..1ae6a23038e 100644 --- a/go/vt/topo/events/tablet_change_syslog_test.go +++ b/go/vt/topo/events/tablet_change_syslog_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/topo/helpers/compare.go b/go/vt/topo/helpers/compare.go index f14844f01c5..2009e6fce0f 100644 --- a/go/vt/topo/helpers/compare.go +++ b/go/vt/topo/helpers/compare.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Vitess Authors +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. diff --git a/go/vt/topo/helpers/compare_test.go b/go/vt/topo/helpers/compare_test.go index 45ea73adab1..d4c16e58382 100644 --- a/go/vt/topo/helpers/compare_test.go +++ b/go/vt/topo/helpers/compare_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/topo/helpers/copy.go b/go/vt/topo/helpers/copy.go index f23101a79c7..9bd89908674 100644 --- a/go/vt/topo/helpers/copy.go +++ b/go/vt/topo/helpers/copy.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/topo/helpers/copy_test.go b/go/vt/topo/helpers/copy_test.go index 870ad2d3847..b70ea19a2c2 100644 --- a/go/vt/topo/helpers/copy_test.go +++ b/go/vt/topo/helpers/copy_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/topo/helpers/tee.go b/go/vt/topo/helpers/tee.go index 54d57d8235c..f9fa10cefc7 100644 --- a/go/vt/topo/helpers/tee.go +++ b/go/vt/topo/helpers/tee.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/topo/helpers/tee_test.go b/go/vt/topo/helpers/tee_test.go index ac50fe6485a..75837dfa76f 100644 --- a/go/vt/topo/helpers/tee_test.go +++ b/go/vt/topo/helpers/tee_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/topo/helpers/tee_topo_test.go b/go/vt/topo/helpers/tee_topo_test.go index 5da3e897f96..de7dc603b82 100644 --- a/go/vt/topo/helpers/tee_topo_test.go +++ b/go/vt/topo/helpers/tee_topo_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/topo/keyspace.go b/go/vt/topo/keyspace.go index 7c0361cc1ff..a22d2b4f5f4 100755 --- a/go/vt/topo/keyspace.go +++ b/go/vt/topo/keyspace.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/topo/keyspace_test.go b/go/vt/topo/keyspace_test.go index e8883ec7baf..e9e5d8a2f55 100644 --- a/go/vt/topo/keyspace_test.go +++ b/go/vt/topo/keyspace_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/topo/locks.go b/go/vt/topo/locks.go index f9f15a479ac..cdebbe4c03c 100644 --- a/go/vt/topo/locks.go +++ b/go/vt/topo/locks.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -106,7 +106,7 @@ type locksInfo struct { // lock different things. mu sync.Mutex - // info contans all the locks we took. It is indexed by + // info contains all the locks we took. It is indexed by // keyspace (for keyspaces) or keyspace/shard (for shards). info map[string]*lockInfo } diff --git a/go/vt/topo/memorytopo/directory.go b/go/vt/topo/memorytopo/directory.go index 90640ef7302..f86c88f5e49 100644 --- a/go/vt/topo/memorytopo/directory.go +++ b/go/vt/topo/memorytopo/directory.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/topo/memorytopo/election.go b/go/vt/topo/memorytopo/election.go index f66154a02de..8d5c733ea8c 100644 --- a/go/vt/topo/memorytopo/election.go +++ b/go/vt/topo/memorytopo/election.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/topo/memorytopo/file.go b/go/vt/topo/memorytopo/file.go index 807d725b204..f7dda922e48 100644 --- a/go/vt/topo/memorytopo/file.go +++ b/go/vt/topo/memorytopo/file.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/topo/memorytopo/lock.go b/go/vt/topo/memorytopo/lock.go index d3e8e525597..bda6da13fa3 100644 --- a/go/vt/topo/memorytopo/lock.go +++ b/go/vt/topo/memorytopo/lock.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 @@ -70,7 +70,7 @@ func (c *Conn) Lock(ctx context.Context, dirPath, contents string) (topo.LockDes } } - // Noone has the lock, grab it. + // No one has the lock, grab it. n.lock = make(chan struct{}) n.lockContents = contents c.factory.mu.Unlock() diff --git a/go/vt/topo/memorytopo/memorytopo.go b/go/vt/topo/memorytopo/memorytopo.go index 2c8908692e5..060f1cf6688 100644 --- a/go/vt/topo/memorytopo/memorytopo.go +++ b/go/vt/topo/memorytopo/memorytopo.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/topo/memorytopo/server_test.go b/go/vt/topo/memorytopo/server_test.go index eca00632782..ea979ea2922 100644 --- a/go/vt/topo/memorytopo/server_test.go +++ b/go/vt/topo/memorytopo/server_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/topo/memorytopo/version.go b/go/vt/topo/memorytopo/version.go index ed691cf593c..468ef6f2110 100644 --- a/go/vt/topo/memorytopo/version.go +++ b/go/vt/topo/memorytopo/version.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/topo/memorytopo/watch.go b/go/vt/topo/memorytopo/watch.go index 5d247764637..9d7aa28ed04 100644 --- a/go/vt/topo/memorytopo/watch.go +++ b/go/vt/topo/memorytopo/watch.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/topo/metadata.go b/go/vt/topo/metadata.go new file mode 100644 index 00000000000..4d24630a309 --- /dev/null +++ b/go/vt/topo/metadata.go @@ -0,0 +1,106 @@ +/* +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 topo + +import ( + "context" + "path" + + "vitess.io/vitess/go/vt/sqlparser" + + "vitess.io/vitess/go/event" + "vitess.io/vitess/go/vt/topo/events" +) + +// UpsertMetadata sets the key/value in the metadata if it doesn't exist, otherwise it updates the content +func (ts *Server) UpsertMetadata(ctx context.Context, key string, val string) error { + keyPath := path.Join(MetadataPath, key) + + _, _, err := ts.globalCell.Get(ctx, keyPath) + status := "updated" + + if err != nil { + if !IsErrType(err, NoNode) { + return err + } + + status = "created" + } + + // nil version means that it will insert if keyPath does not exist + if _, err := ts.globalCell.Update(ctx, keyPath, []byte(val), nil); err != nil { + return err + } + + dispatchEvent(keyPath, status) + return nil +} + +// GetMetadata retrieves all metadata value that matches the given key regular expression. If empty all values are returned. +func (ts *Server) GetMetadata(ctx context.Context, keyFilter string) (map[string]string, error) { + keys, err := ts.globalCell.ListDir(ctx, MetadataPath, false) + if err != nil { + return nil, err + } + + re := sqlparser.LikeToRegexp(keyFilter) + + result := make(map[string]string) + for _, k := range keys { + if !re.MatchString(k.Name) { + continue + } + + val, err := ts.getMetadata(ctx, k.Name) + if err != nil { + return nil, err + } + result[k.Name] = val + } + + return result, nil +} + +// DeleteMetadata deletes the key in the metadata +func (ts *Server) DeleteMetadata(ctx context.Context, key string) error { + keyPath := path.Join(MetadataPath, key) + + // nil version means that it will insert if keyPath does not exist + if err := ts.globalCell.Delete(ctx, keyPath, nil); err != nil { + return err + } + + dispatchEvent(keyPath, "deleted") + return nil +} + +func (ts *Server) getMetadata(ctx context.Context, key string) (string, error) { + keyPath := path.Join(MetadataPath, key) + contents, _, err := ts.globalCell.Get(ctx, keyPath) + if err != nil { + return "", err + } + + return string(contents), nil +} + +func dispatchEvent(key string, status string) { + event.Dispatch(&events.MetadataChange{ + Key: key, + Status: status, + }) +} diff --git a/go/vt/topo/replication.go b/go/vt/topo/replication.go index b17acb0b46c..d4e40831b48 100644 --- a/go/vt/topo/replication.go +++ b/go/vt/topo/replication.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/topo/server.go b/go/vt/topo/server.go index e28facc0486..4e913d431de 100644 --- a/go/vt/topo/server.go +++ b/go/vt/topo/server.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -84,6 +84,7 @@ const ( KeyspacesPath = "keyspaces" ShardsPath = "shards" TabletsPath = "tablets" + MetadataPath = "metadata" ) // Factory is a factory interface to create Conn objects. diff --git a/go/vt/topo/shard.go b/go/vt/topo/shard.go index 2dcf4448ba4..49d75847cf4 100644 --- a/go/vt/topo/shard.go +++ b/go/vt/topo/shard.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -24,8 +24,10 @@ import ( "sort" "strings" "sync" + "time" "golang.org/x/net/context" + "vitess.io/vitess/go/vt/logutil" "vitess.io/vitess/go/vt/proto/vtrpc" "vitess.io/vitess/go/vt/vterrors" @@ -174,6 +176,16 @@ func (si *ShardInfo) HasMaster() bool { return !topoproto.TabletAliasIsZero(si.Shard.MasterAlias) } +// GetMasterTermStartTime returns the shard's master term start time as a Time value. +func (si *ShardInfo) GetMasterTermStartTime() time.Time { + return logutil.ProtoToTime(si.Shard.MasterTermStartTime) +} + +// SetMasterTermStartTime sets the shard's master term start time as a Time value. +func (si *ShardInfo) SetMasterTermStartTime(t time.Time) { + si.Shard.MasterTermStartTime = logutil.TimeToProto(t) +} + // GetShard is a high level function to read shard data. // It generates trace spans. func (ts *Server) GetShard(ctx context.Context, keyspace, shard string) (*ShardInfo, error) { @@ -182,7 +194,7 @@ func (ts *Server) GetShard(ctx context.Context, keyspace, shard string) (*ShardI span.Annotate("shard", shard) defer span.Finish() - shardPath := path.Join(KeyspacesPath, keyspace, ShardsPath, shard, ShardFile) + shardPath := shardFilePath(keyspace, shard) data, version, err := ts.globalCell.Get(ctx, shardPath) if err != nil { return nil, err @@ -212,7 +224,7 @@ func (ts *Server) updateShard(ctx context.Context, si *ShardInfo) error { if err != nil { return err } - shardPath := path.Join(KeyspacesPath, si.keyspace, ShardsPath, si.shardName, ShardFile) + shardPath := shardFilePath(si.keyspace, si.shardName) newVersion, err := ts.globalCell.Update(ctx, shardPath, data, si.version) if err != nil { return err @@ -302,7 +314,7 @@ func (ts *Server) CreateShard(ctx context.Context, keyspace, shard string) (err if err != nil { return err } - shardPath := path.Join(KeyspacesPath, keyspace, ShardsPath, shard, ShardFile) + shardPath := shardFilePath(keyspace, shard) if _, err := ts.globalCell.Create(ctx, shardPath, data); err != nil { // Return error as is, we need to propagate // ErrNodeExists for instance. @@ -349,7 +361,7 @@ func (ts *Server) GetOrCreateShard(ctx context.Context, keyspace, shard string) // DeleteShard wraps the underlying conn.Delete // and dispatches the event. func (ts *Server) DeleteShard(ctx context.Context, keyspace, shard string) error { - shardPath := path.Join(KeyspacesPath, keyspace, ShardsPath, shard, ShardFile) + shardPath := shardFilePath(keyspace, shard) if err := ts.globalCell.Delete(ctx, shardPath, nil); err != nil { return err } @@ -578,3 +590,66 @@ func (ts *Server) GetTabletMapForShardByCell(ctx context.Context, keyspace, shar } return result, gerr } + +func shardFilePath(keyspace, shard string) string { + return path.Join(KeyspacesPath, keyspace, ShardsPath, shard, ShardFile) +} + +// WatchShardData wraps the data we receive on the watch channel +// The WatchShard API guarantees exactly one of Value or Err will be set. +type WatchShardData struct { + Value *topodatapb.Shard + Err error +} + +// WatchShard will set a watch on the Shard object. +// It has the same contract as conn.Watch, but it also unpacks the +// contents into a Shard object +func (ts *Server) WatchShard(ctx context.Context, keyspace, shard string) (*WatchShardData, <-chan *WatchShardData, CancelFunc) { + shardPath := shardFilePath(keyspace, shard) + current, wdChannel, cancel := ts.globalCell.Watch(ctx, shardPath) + if current.Err != nil { + return &WatchShardData{Err: current.Err}, nil, nil + } + value := &topodatapb.Shard{} + if err := proto.Unmarshal(current.Contents, value); err != nil { + // Cancel the watch, drain channel. + cancel() + for range wdChannel { + } + return &WatchShardData{Err: vterrors.Wrapf(err, "error unpacking initial Shard object")}, nil, nil + } + + changes := make(chan *WatchShardData, 10) + // The background routine reads any event from the watch channel, + // translates it, and sends it to the caller. + // If cancel() is called, the underlying Watch() code will + // send an ErrInterrupted and then close the channel. We'll + // just propagate that back to our caller. + go func() { + defer close(changes) + + for wd := range wdChannel { + if wd.Err != nil { + // Last error value, we're done. + // wdChannel will be closed right after + // this, no need to do anything. + changes <- &WatchShardData{Err: wd.Err} + return + } + + value := &topodatapb.Shard{} + if err := proto.Unmarshal(wd.Contents, value); err != nil { + cancel() + for range wdChannel { + } + changes <- &WatchShardData{Err: vterrors.Wrapf(err, "error unpacking Shard object")} + return + } + + changes <- &WatchShardData{Value: value} + } + }() + + return &WatchShardData{Value: value}, changes, cancel +} diff --git a/go/vt/topo/shard_test.go b/go/vt/topo/shard_test.go index cd7e843f1e2..c72b7689209 100644 --- a/go/vt/topo/shard_test.go +++ b/go/vt/topo/shard_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/topo/srv_keyspace.go b/go/vt/topo/srv_keyspace.go index 4a43d87eeb5..5471828080a 100644 --- a/go/vt/topo/srv_keyspace.go +++ b/go/vt/topo/srv_keyspace.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/topo/srv_vschema.go b/go/vt/topo/srv_vschema.go index eda97ecd2f9..e9ed11aec6f 100644 --- a/go/vt/topo/srv_vschema.go +++ b/go/vt/topo/srv_vschema.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/topo/stats_conn.go b/go/vt/topo/stats_conn.go index dadef0e1861..33ad58f300f 100644 --- a/go/vt/topo/stats_conn.go +++ b/go/vt/topo/stats_conn.go @@ -1,10 +1,13 @@ /* -Copyright 2018 The Vitess Authors - Licensed under the Apache License, Version 2.0 (the "License"); +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 + +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 diff --git a/go/vt/topo/stats_conn_test.go b/go/vt/topo/stats_conn_test.go index 6b7f57c5559..5148be26f48 100644 --- a/go/vt/topo/stats_conn_test.go +++ b/go/vt/topo/stats_conn_test.go @@ -1,9 +1,12 @@ /* -Copyright 2018 The Vitess Authors - Licensed under the Apache License, Version 2.0 (the "License"); +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. diff --git a/go/vt/topo/tablet.go b/go/vt/topo/tablet.go index 22803bc3002..22ae93a2928 100644 --- a/go/vt/topo/tablet.go +++ b/go/vt/topo/tablet.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -20,6 +20,7 @@ import ( "fmt" "path" "sync" + "time" "golang.org/x/net/context" "vitess.io/vitess/go/vt/proto/vtrpc" @@ -30,6 +31,7 @@ import ( "vitess.io/vitess/go/netutil" "vitess.io/vitess/go/trace" "vitess.io/vitess/go/vt/log" + "vitess.io/vitess/go/vt/logutil" topodatapb "vitess.io/vitess/go/vt/proto/topodata" "vitess.io/vitess/go/vt/topo/events" @@ -207,6 +209,16 @@ func (ti *TabletInfo) IsSlaveType() bool { return IsSlaveType(ti.Type) } +// GetMasterTermStartTime returns the tablet's master term start time as a Time value. +func (ti *TabletInfo) GetMasterTermStartTime() time.Time { + return logutil.ProtoToTime(ti.Tablet.MasterTermStartTime) +} + +// SetMasterTermStartTime sets the tablet's master term start time as a Time value. +func (ti *TabletInfo) SetMasterTermStartTime(t time.Time) { + ti.Tablet.MasterTermStartTime = logutil.TimeToProto(t) +} + // NewTabletInfo returns a TabletInfo basing on tablet with the // version set. This function should be only used by Server // implementations. diff --git a/go/vt/topo/test/directory.go b/go/vt/topo/test/directory.go index ee358a8c2e8..540dec5b20f 100644 --- a/go/vt/topo/test/directory.go +++ b/go/vt/topo/test/directory.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/topo/test/election.go b/go/vt/topo/test/election.go index b994e831851..65c2ec7d83b 100644 --- a/go/vt/topo/test/election.go +++ b/go/vt/topo/test/election.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/topo/test/file.go b/go/vt/topo/test/file.go index bdbc2749c00..9c661db48da 100644 --- a/go/vt/topo/test/file.go +++ b/go/vt/topo/test/file.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/topo/test/keyspace.go b/go/vt/topo/test/keyspace.go index 27a90e82e93..df8c4750744 100644 --- a/go/vt/topo/test/keyspace.go +++ b/go/vt/topo/test/keyspace.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/topo/test/lock.go b/go/vt/topo/test/lock.go index 315653ff000..05c1d0b808b 100644 --- a/go/vt/topo/test/lock.go +++ b/go/vt/topo/test/lock.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/topo/test/replication.go b/go/vt/topo/test/replication.go index 3437c86595e..a4d42a896b4 100644 --- a/go/vt/topo/test/replication.go +++ b/go/vt/topo/test/replication.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/topo/test/serving.go b/go/vt/topo/test/serving.go index 0ba335655e3..fa8511d1ebf 100644 --- a/go/vt/topo/test/serving.go +++ b/go/vt/topo/test/serving.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/topo/test/shard.go b/go/vt/topo/test/shard.go index 58ee4034c50..5ddd0b7db35 100644 --- a/go/vt/topo/test/shard.go +++ b/go/vt/topo/test/shard.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/topo/test/tablet.go b/go/vt/topo/test/tablet.go index 83f6f285ef2..d7fdf6f0c88 100644 --- a/go/vt/topo/test/tablet.go +++ b/go/vt/topo/test/tablet.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/topo/test/testing.go b/go/vt/topo/test/testing.go index 9cc2f035ec0..941666aa7a5 100644 --- a/go/vt/topo/test/testing.go +++ b/go/vt/topo/test/testing.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/topo/test/vschema.go b/go/vt/topo/test/vschema.go index 220f12c5888..e86cb3df2f6 100644 --- a/go/vt/topo/test/vschema.go +++ b/go/vt/topo/test/vschema.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/topo/test/watch.go b/go/vt/topo/test/watch.go index 30aab3ecaae..5ab22b82944 100644 --- a/go/vt/topo/test/watch.go +++ b/go/vt/topo/test/watch.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/topo/topoproto/destination.go b/go/vt/topo/topoproto/destination.go index f4886fdd6ef..c86affd1569 100644 --- a/go/vt/topo/topoproto/destination.go +++ b/go/vt/topo/topoproto/destination.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Vitess Authors. +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. @@ -27,7 +27,7 @@ import ( vtrpcpb "vitess.io/vitess/go/vt/proto/vtrpc" ) -// ParseDestination parses the string representation of a Destionation +// ParseDestination parses the string representation of a Destination // of the form keyspace:shard@tablet_type. You can use a / instead of a :. func ParseDestination(targetString string, defaultTabletType topodatapb.TabletType) (string, topodatapb.TabletType, key.Destination, error) { var dest key.Destination diff --git a/go/vt/topo/topoproto/destination_test.go b/go/vt/topo/topoproto/destination_test.go index 3fdddaf0a01..59bfc95f669 100644 --- a/go/vt/topo/topoproto/destination_test.go +++ b/go/vt/topo/topoproto/destination_test.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Vitess Authors. +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. diff --git a/go/vt/topo/topoproto/flag.go b/go/vt/topo/topoproto/flag.go index bcd1fa5d56e..cc7cdc1692f 100644 --- a/go/vt/topo/topoproto/flag.go +++ b/go/vt/topo/topoproto/flag.go @@ -1,3 +1,19 @@ +/* +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 topoproto import ( diff --git a/go/vt/topo/topoproto/keyspace.go b/go/vt/topo/topoproto/keyspace.go new file mode 100644 index 00000000000..e409f763fd7 --- /dev/null +++ b/go/vt/topo/topoproto/keyspace.go @@ -0,0 +1,34 @@ +/* +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 topoproto + +import ( + "fmt" + "strings" + + topodatapb "vitess.io/vitess/go/vt/proto/topodata" +) + +// ParseKeyspaceType parses a string into a KeyspaceType +func ParseKeyspaceType(param string) (topodatapb.KeyspaceType, error) { + value, ok := topodatapb.KeyspaceType_value[strings.ToUpper(param)] + if !ok { + // default + return topodatapb.KeyspaceType_NORMAL, fmt.Errorf("unknown keyspace type: %v", value) + } + return topodatapb.KeyspaceType(value), nil +} diff --git a/go/vt/topo/topoproto/shard.go b/go/vt/topo/topoproto/shard.go index b412cf180d2..75c892ce96e 100644 --- a/go/vt/topo/topoproto/shard.go +++ b/go/vt/topo/topoproto/shard.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/topo/topoproto/shard_test.go b/go/vt/topo/topoproto/shard_test.go index f03af83f2a0..3f44549f39d 100644 --- a/go/vt/topo/topoproto/shard_test.go +++ b/go/vt/topo/topoproto/shard_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/topo/topoproto/srvkeyspace.go b/go/vt/topo/topoproto/srvkeyspace.go index 206a7f85b7d..24618233fb2 100644 --- a/go/vt/topo/topoproto/srvkeyspace.go +++ b/go/vt/topo/topoproto/srvkeyspace.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/topo/topoproto/tablet.go b/go/vt/topo/topoproto/tablet.go index 97dd1263c04..a72d4595cfa 100644 --- a/go/vt/topo/topoproto/tablet.go +++ b/go/vt/topo/topoproto/tablet.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -34,8 +34,8 @@ import ( // This file contains the topodata.Tablet utility functions. const ( - // Default name for databases is the prefix plus keyspace - vtDbPrefix = "vt_" + // VtDbPrefix + keyspace is the default name for databases. + VtDbPrefix = "vt_" ) // cache the conversion from tablet type enum to lower case string. @@ -258,7 +258,7 @@ func TabletDbName(tablet *topodatapb.Tablet) string { if tablet.Keyspace == "" { return "" } - return vtDbPrefix + tablet.Keyspace + return VtDbPrefix + tablet.Keyspace } // TabletIsAssigned returns if this tablet is assigned to a keyspace and shard. diff --git a/go/vt/topo/topotests/cell_info_test.go b/go/vt/topo/topotests/cell_info_test.go index 715e66fe5f5..848e869fa35 100644 --- a/go/vt/topo/topotests/cell_info_test.go +++ b/go/vt/topo/topotests/cell_info_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/topo/topotests/cells_aliases_test.go b/go/vt/topo/topotests/cells_aliases_test.go index 110890d2955..6f749665869 100644 --- a/go/vt/topo/topotests/cells_aliases_test.go +++ b/go/vt/topo/topotests/cells_aliases_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/topo/topotests/doc.go b/go/vt/topo/topotests/doc.go index cb2c3bf9c4d..652e1b02008 100644 --- a/go/vt/topo/topotests/doc.go +++ b/go/vt/topo/topotests/doc.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/topo/topotests/replication_test.go b/go/vt/topo/topotests/replication_test.go index 8b4dcbc8a02..be0768435ce 100644 --- a/go/vt/topo/topotests/replication_test.go +++ b/go/vt/topo/topotests/replication_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/topo/topotests/shard_watch_test.go b/go/vt/topo/topotests/shard_watch_test.go new file mode 100644 index 00000000000..bdc2eab1db9 --- /dev/null +++ b/go/vt/topo/topotests/shard_watch_test.go @@ -0,0 +1,260 @@ +/* +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 agreedto 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 topotests + +import ( + "strings" + "testing" + "time" + + "github.com/golang/protobuf/proto" + "golang.org/x/net/context" + topodatapb "vitess.io/vitess/go/vt/proto/topodata" + "vitess.io/vitess/go/vt/topo" + "vitess.io/vitess/go/vt/topo/memorytopo" +) + +// waitForInitialShard waits for the initial Shard to appear. +func waitForInitialShard(t *testing.T, ts *topo.Server, keyspace, shard string) (current *topo.WatchShardData, changes <-chan *topo.WatchShardData, cancel topo.CancelFunc) { + ctx := context.Background() + start := time.Now() + for { + current, changes, cancel = ts.WatchShard(ctx, keyspace, shard) + switch { + case topo.IsErrType(current.Err, topo.NoNode): + // hasn't appeared yet + if time.Since(start) > 10*time.Second { + t.Fatalf("time out waiting for file to appear") + } + time.Sleep(10 * time.Millisecond) + continue + case current.Err == nil: + return + default: + t.Fatalf("watch failed: %v", current.Err) + } + } +} + +func TestWatchShardNoNode(t *testing.T) { + keyspace := "ks1" + shard := "0" + ctx := context.Background() + ts := memorytopo.NewServer("cell1") + + // No Shard -> ErrNoNode + current, _, _ := ts.WatchShard(ctx, keyspace, shard) + if !topo.IsErrType(current.Err, topo.NoNode) { + t.Errorf("Got invalid result from WatchShard(not there): %v", current.Err) + } +} + +func TestWatchShard(t *testing.T) { + cell := "cell1" + keyspace := "ks1" + shard := "0" + ctx := context.Background() + ts := memorytopo.NewServer(cell) + + // Create keyspace + if err := ts.CreateKeyspace(ctx, keyspace, &topodatapb.Keyspace{}); err != nil { + t.Fatalf("CreateKeyspace %v failed: %v", keyspace, err) + } + + // Create initial value + if err := ts.CreateShard(ctx, keyspace, shard); err != nil { + t.Fatalf("Create(/keyspaces/ks1/shards/0/Shard) failed: %v", err) + } + + // Starting the watch should now work, and return an empty + // Shard. + // Shards are always created with IsMasterServing true + wanted := &topodatapb.Shard{IsMasterServing: true} + current, changes, cancel := waitForInitialShard(t, ts, keyspace, shard) + if !proto.Equal(current.Value, wanted) { + t.Fatalf("got bad data: %v expected: %v", current.Value, wanted) + } + + // Update the value with good data, wait until we see it + wanted.IsMasterServing = false + if _, err := ts.UpdateShardFields(ctx, keyspace, shard, func(si *topo.ShardInfo) error { + si.IsMasterServing = false + return nil + }); err != nil { + t.Fatalf("Update(/keyspaces/ks1/shards/0/Shard) failed: %v", err) + } + for { + wd, ok := <-changes + if !ok { + t.Fatalf("watch channel unexpectedly closed") + } + if wd.Err != nil { + t.Fatalf("watch channel unexpectedly got error: %v", wd.Err) + } + if proto.Equal(wd.Value, wanted) { + break + } + if proto.Equal(wd.Value, &topodatapb.Shard{}) { + t.Log("got duplicate empty value, skipping.") + } + t.Fatalf("got bad data: %v expected: %v", wd.Value, wanted) + } + + conn, err := ts.ConnForCell(ctx, "global") + if err != nil { + t.Fatalf("ConnForCell failed: %v", err) + } + // Update the value with bad data, wait until error. + if _, err := conn.Update(ctx, "/keyspaces/"+keyspace+"/shards/"+shard+"/Shard", []byte("BAD PROTO DATA"), nil); err != nil { + t.Fatalf("Update(/keyspaces/ks1/shards/0/Shard) failed: %v", err) + } + for { + wd, ok := <-changes + if !ok { + t.Fatalf("watch channel unexpectedly closed") + } + if wd.Err != nil { + if strings.Contains(wd.Err.Error(), "error unpacking Shard object") { + break + } + t.Fatalf("watch channel unexpectedly got unknown error: %v", wd.Err) + } + if !proto.Equal(wd.Value, wanted) { + t.Fatalf("got bad data: %v expected: %v", wd.Value, wanted) + } + t.Log("got duplicate right value, skipping.") + } + + // Cancel should still work here, although it does nothing. + cancel() + + // Bad data in topo, setting the watch should now fail. + current, _, _ = ts.WatchShard(ctx, keyspace, shard) + if current.Err == nil || !strings.Contains(current.Err.Error(), "error unpacking initial Shard object") { + t.Fatalf("expected an initial error setting watch on bad content, but got: %v", current.Err) + } + + data, err := proto.Marshal(wanted) + if err != nil { + t.Fatalf("error marshalling proto data: %v", err) + } + // Update content, wait until Watch works again + if _, err := conn.Update(ctx, "/keyspaces/"+keyspace+"/shards/"+shard+"/Shard", data, nil); err != nil { + t.Fatalf("Update(/keyspaces/ks1/shards/0/Shard) failed: %v", err) + } + start := time.Now() + for { + current, changes, _ = ts.WatchShard(ctx, keyspace, shard) + if current.Err != nil { + if strings.Contains(current.Err.Error(), "error unpacking initial Shard object") { + // hasn't changed yet + if time.Since(start) > 10*time.Second { + t.Fatalf("time out waiting for file to appear") + } + time.Sleep(10 * time.Millisecond) + continue + } + t.Fatalf("got unexpected error while setting watch: %v", err) + } + if !proto.Equal(current.Value, wanted) { + t.Fatalf("got bad data: %v expected: %v", current.Value, wanted) + } + break + } + + // Delete node, wait for error (skip any duplicate). + if err := ts.DeleteShard(ctx, keyspace, shard); err != nil { + t.Fatalf("DeleteShard() failed: %v", err) + } + for { + wd, ok := <-changes + if !ok { + t.Fatalf("watch channel unexpectedly closed") + } + if topo.IsErrType(wd.Err, topo.NoNode) { + break + } + if wd.Err != nil { + t.Fatalf("watch channel unexpectedly got unknown error: %v", wd.Err) + } + if !proto.Equal(wd.Value, wanted) { + t.Fatalf("got bad data: %v expected: %v", wd.Value, wanted) + } + t.Log("got duplicate right value, skipping.") + } +} + +func TestWatchShardCancel(t *testing.T) { + cell := "cell1" + keyspace := "ks1" + shard := "0" + ctx := context.Background() + ts := memorytopo.NewServer(cell) + + // No Shard -> ErrNoNode + current, _, _ := ts.WatchShard(ctx, keyspace, shard) + if !topo.IsErrType(current.Err, topo.NoNode) { + t.Errorf("Got invalid result from WatchShard(not there): %v", current.Err) + } + + // Create keyspace + if err := ts.CreateKeyspace(ctx, keyspace, &topodatapb.Keyspace{}); err != nil { + t.Fatalf("CreateKeyspace %v failed: %v", keyspace, err) + } + + // Create initial value + if err := ts.CreateShard(ctx, keyspace, shard); err != nil { + t.Fatalf("Create(/keyspaces/ks1/shards/0/Shard) failed: %v", err) + } + wanted := &topodatapb.Shard{ + IsMasterServing: false, + } + if _, err := ts.UpdateShardFields(ctx, keyspace, shard, func(si *topo.ShardInfo) error { + si.IsMasterServing = false + return nil + }); err != nil { + t.Fatalf("UpdateShardFields() failed: %v", err) + } + + // Starting the watch should now work. + current, changes, cancel := waitForInitialShard(t, ts, keyspace, shard) + if !proto.Equal(current.Value, wanted) { + t.Fatalf("got bad data: %v expected: %v", current.Value, wanted) + } + + // Cancel watch, wait for error. + cancel() + for { + wd, ok := <-changes + if !ok { + t.Fatalf("watch channel unexpectedly closed") + } + if topo.IsErrType(wd.Err, topo.Interrupted) { + break + } + if wd.Err != nil { + t.Fatalf("watch channel unexpectedly got unknown error: %v", wd.Err) + } + if !proto.Equal(wd.Value, wanted) { + t.Fatalf("got bad data: %v expected: %v", wd.Value, wanted) + } + t.Log("got duplicate right value, skipping.") + } + + // Cancel should still work here, although it does nothing. + cancel() +} diff --git a/go/vt/topo/topotests/srv_keyspace_test.go b/go/vt/topo/topotests/srv_keyspace_test.go index 31c0106701f..cba89d3043c 100644 --- a/go/vt/topo/topotests/srv_keyspace_test.go +++ b/go/vt/topo/topotests/srv_keyspace_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/topo/topotests/srv_vschema_test.go b/go/vt/topo/topotests/srv_vschema_test.go index 1d3913779c3..0ada0db2048 100644 --- a/go/vt/topo/topotests/srv_vschema_test.go +++ b/go/vt/topo/topotests/srv_vschema_test.go @@ -1,5 +1,5 @@ /* -Copyright 2019 The Vitess Authors +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. diff --git a/go/vt/topo/topotests/tablet_test.go b/go/vt/topo/topotests/tablet_test.go index cc307a0badb..585632beb72 100644 --- a/go/vt/topo/topotests/tablet_test.go +++ b/go/vt/topo/topotests/tablet_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/topo/topotests/wildcards_test.go b/go/vt/topo/topotests/wildcards_test.go index e639864284f..73ad1dbded2 100644 --- a/go/vt/topo/topotests/wildcards_test.go +++ b/go/vt/topo/topotests/wildcards_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/topo/vschema.go b/go/vt/topo/vschema.go index fcd7990b007..2ea8d507716 100644 --- a/go/vt/topo/vschema.go +++ b/go/vt/topo/vschema.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/topo/wildcards.go b/go/vt/topo/wildcards.go index 92d76a0187c..740d062611e 100644 --- a/go/vt/topo/wildcards.go +++ b/go/vt/topo/wildcards.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/topo/workflow.go b/go/vt/topo/workflow.go index 596c46cacd9..a3a3bd09397 100644 --- a/go/vt/topo/workflow.go +++ b/go/vt/topo/workflow.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/topo/zk2topo/directory.go b/go/vt/topo/zk2topo/directory.go index 2480399e2b6..b4199c8fb5e 100644 --- a/go/vt/topo/zk2topo/directory.go +++ b/go/vt/topo/zk2topo/directory.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/topo/zk2topo/election.go b/go/vt/topo/zk2topo/election.go index 15975a00f88..aaa11b31fa8 100644 --- a/go/vt/topo/zk2topo/election.go +++ b/go/vt/topo/zk2topo/election.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/topo/zk2topo/error.go b/go/vt/topo/zk2topo/error.go index f1d2fe43a89..6ce81c0632a 100644 --- a/go/vt/topo/zk2topo/error.go +++ b/go/vt/topo/zk2topo/error.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/topo/zk2topo/file.go b/go/vt/topo/zk2topo/file.go index a177e8834bd..9eac1b114c7 100644 --- a/go/vt/topo/zk2topo/file.go +++ b/go/vt/topo/zk2topo/file.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/topo/zk2topo/lock.go b/go/vt/topo/zk2topo/lock.go index 89b9ff9c8c3..6f4138f2a14 100644 --- a/go/vt/topo/zk2topo/lock.go +++ b/go/vt/topo/zk2topo/lock.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/topo/zk2topo/server.go b/go/vt/topo/zk2topo/server.go index 355fa81b98a..6ecf7aeaab4 100644 --- a/go/vt/topo/zk2topo/server.go +++ b/go/vt/topo/zk2topo/server.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/topo/zk2topo/server_test.go b/go/vt/topo/zk2topo/server_test.go index e0d57b24edc..4f97b921c1d 100644 --- a/go/vt/topo/zk2topo/server_test.go +++ b/go/vt/topo/zk2topo/server_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/topo/zk2topo/utils.go b/go/vt/topo/zk2topo/utils.go index 1feb85fb5a7..ffa1a6cabb7 100644 --- a/go/vt/topo/zk2topo/utils.go +++ b/go/vt/topo/zk2topo/utils.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/topo/zk2topo/version.go b/go/vt/topo/zk2topo/version.go index 84014bdef67..791a2c2a999 100644 --- a/go/vt/topo/zk2topo/version.go +++ b/go/vt/topo/zk2topo/version.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/topo/zk2topo/watch.go b/go/vt/topo/zk2topo/watch.go index 6d291451de1..f7569e8aa35 100644 --- a/go/vt/topo/zk2topo/watch.go +++ b/go/vt/topo/zk2topo/watch.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/topo/zk2topo/zk_conn.go b/go/vt/topo/zk2topo/zk_conn.go index b6890273e7e..f4dd9404f5b 100644 --- a/go/vt/topo/zk2topo/zk_conn.go +++ b/go/vt/topo/zk2topo/zk_conn.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -340,7 +340,7 @@ func (c *ZkConn) handleSessionEvents(conn *zk.Conn, session <-chan zk.Event) { // dialZk dials the server, and waits until connection. func dialZk(ctx context.Context, addr string) (*zk.Conn, <-chan zk.Event, error) { servers := strings.Split(addr, ",") - options := zk.WithDialer(net.DialTimeout) + dialer := zk.WithDialer(net.DialTimeout) // If TLS is enabled use a TLS enabled dialer option if *certPath != "" && *keyPath != "" { if strings.Contains(addr, ",") { @@ -371,15 +371,18 @@ func dialZk(ctx context.Context, addr string) (*zk.Conn, <-chan zk.Event, error) tlsConfig.BuildNameToCertificate() - options = zk.WithDialer(func(network, address string, timeout time.Duration) (net.Conn, error) { + dialer = zk.WithDialer(func(network, address string, timeout time.Duration) (net.Conn, error) { d := net.Dialer{Timeout: timeout} return tls.DialWithDialer(&d, network, address, tlsConfig) }) } + // Make sure we re-resolve the DNS name every time we reconnect to a server + // In environments where DNS changes such as Kubernetes we can't cache the IP address + hostProvider := zk.WithHostProvider(&zk.SimpleDNSHostProvider{}) // zk.Connect automatically shuffles the servers - zconn, session, err := zk.Connect(servers, *baseTimeout, options) + zconn, session, err := zk.Connect(servers, *baseTimeout, dialer, hostProvider) if err != nil { return nil, nil, err } diff --git a/go/vt/topotools/events/migrate.go b/go/vt/topotools/events/migrate.go index b2278c15cec..d91f211c222 100644 --- a/go/vt/topotools/events/migrate.go +++ b/go/vt/topotools/events/migrate.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/topotools/events/migrate_syslog.go b/go/vt/topotools/events/migrate_syslog.go index 613ebde03b0..ae1da2d2006 100644 --- a/go/vt/topotools/events/migrate_syslog.go +++ b/go/vt/topotools/events/migrate_syslog.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/topotools/events/migrate_syslog_test.go b/go/vt/topotools/events/migrate_syslog_test.go index 276f909b3bf..01e25415d28 100644 --- a/go/vt/topotools/events/migrate_syslog_test.go +++ b/go/vt/topotools/events/migrate_syslog_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/topotools/events/reparent.go b/go/vt/topotools/events/reparent.go index 595e716edb6..eb7782fe5ba 100644 --- a/go/vt/topotools/events/reparent.go +++ b/go/vt/topotools/events/reparent.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/topotools/events/reparent_syslog.go b/go/vt/topotools/events/reparent_syslog.go index 7dabc87c559..0557ae5bb63 100644 --- a/go/vt/topotools/events/reparent_syslog.go +++ b/go/vt/topotools/events/reparent_syslog.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/topotools/events/reparent_syslog_test.go b/go/vt/topotools/events/reparent_syslog_test.go index cfbb75fbb07..9466da7ca1f 100644 --- a/go/vt/topotools/events/reparent_syslog_test.go +++ b/go/vt/topotools/events/reparent_syslog_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/topotools/rebuild_keyspace.go b/go/vt/topotools/rebuild_keyspace.go index fcf4f52d45b..1d2b907a1d6 100644 --- a/go/vt/topotools/rebuild_keyspace.go +++ b/go/vt/topotools/rebuild_keyspace.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/topotools/shard_test.go b/go/vt/topotools/shard_test.go index a2622709b59..521d163d378 100644 --- a/go/vt/topotools/shard_test.go +++ b/go/vt/topotools/shard_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/topotools/split.go b/go/vt/topotools/split.go index 4055eccbdfa..98c93e0eb6b 100644 --- a/go/vt/topotools/split.go +++ b/go/vt/topotools/split.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/topotools/split_test.go b/go/vt/topotools/split_test.go index 02903ea3001..7ee34a15946 100644 --- a/go/vt/topotools/split_test.go +++ b/go/vt/topotools/split_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/topotools/tablet.go b/go/vt/topotools/tablet.go index a5527045187..b8fc57b1130 100644 --- a/go/vt/topotools/tablet.go +++ b/go/vt/topotools/tablet.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -37,6 +37,7 @@ import ( "errors" "fmt" + "github.com/golang/protobuf/proto" "golang.org/x/net/context" "vitess.io/vitess/go/vt/hook" @@ -46,6 +47,7 @@ import ( querypb "vitess.io/vitess/go/vt/proto/query" topodatapb "vitess.io/vitess/go/vt/proto/topodata" + "vitess.io/vitess/go/vt/proto/vttime" ) // ConfigureTabletHook configures the right parameters for a hook @@ -61,11 +63,27 @@ func ConfigureTabletHook(hk *hook.Hook, tabletAlias *topodatapb.TabletAlias) { // transitions need to be forced from time to time. // // If successful, the updated tablet record is returned. -func ChangeType(ctx context.Context, ts *topo.Server, tabletAlias *topodatapb.TabletAlias, newType topodatapb.TabletType) (*topodatapb.Tablet, error) { - return ts.UpdateTabletFields(ctx, tabletAlias, func(tablet *topodatapb.Tablet) error { +func ChangeType(ctx context.Context, ts *topo.Server, tabletAlias *topodatapb.TabletAlias, newType topodatapb.TabletType, masterTermStartTime *vttime.Time) (*topodatapb.Tablet, error) { + var result *topodatapb.Tablet + // Always clear out the master timestamp if not master. + if newType != topodatapb.TabletType_MASTER { + masterTermStartTime = nil + } + _, err := ts.UpdateTabletFields(ctx, tabletAlias, func(tablet *topodatapb.Tablet) error { + // Save the most recent tablet value so we can return it + // either if the update succeeds or if no update is needed. + result = tablet + if tablet.Type == newType && proto.Equal(tablet.MasterTermStartTime, masterTermStartTime) { + return topo.NewError(topo.NoUpdateNeeded, topoproto.TabletAliasString(tabletAlias)) + } tablet.Type = newType + tablet.MasterTermStartTime = masterTermStartTime return nil }) + if err != nil { + return nil, err + } + return result, nil } // CheckOwnership returns nil iff the Hostname and port match on oldTablet and diff --git a/go/vt/topotools/tablet_test.go b/go/vt/topotools/tablet_test.go index b404d3492c7..274772767b8 100644 --- a/go/vt/topotools/tablet_test.go +++ b/go/vt/topotools/tablet_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/topotools/utils.go b/go/vt/topotools/utils.go index a94ec67f745..d7fae67d929 100644 --- a/go/vt/topotools/utils.go +++ b/go/vt/topotools/utils.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -119,7 +119,7 @@ func SortedTabletMap(tabletMap map[string]*topo.TabletInfo) (map[string]*topo.Ta return slaveMap, masterMap } -// CopyMapKeys copies keys from from map m into a new slice with the +// CopyMapKeys copies keys from map m into a new slice with the // type specified by typeHint. Reflection can't make a new slice type // just based on the key type AFAICT. func CopyMapKeys(m interface{}, typeHint interface{}) interface{} { @@ -131,7 +131,7 @@ func CopyMapKeys(m interface{}, typeHint interface{}) interface{} { return keys.Interface() } -// CopyMapValues copies values from from map m into a new slice with the +// CopyMapValues copies values from map m into a new slice with the // type specified by typeHint. Reflection can't make a new slice type // just based on the key type AFAICT. func CopyMapValues(m interface{}, typeHint interface{}) interface{} { diff --git a/go/vt/topotools/vschema_ddl.go b/go/vt/topotools/vschema_ddl.go index d9b1330021a..54858aa1f8c 100644 --- a/go/vt/topotools/vschema_ddl.go +++ b/go/vt/topotools/vschema_ddl.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Vitess Authors +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. diff --git a/go/vt/vitessdriver/convert.go b/go/vt/vitessdriver/convert.go index ca5544c31c6..3a0e875b0d9 100644 --- a/go/vt/vitessdriver/convert.go +++ b/go/vt/vitessdriver/convert.go @@ -1,5 +1,5 @@ /* -Copyright 2017 GitHub Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/vitessdriver/convert_test.go b/go/vt/vitessdriver/convert_test.go index 07e9f0428e5..a8ccc6ffab1 100644 --- a/go/vt/vitessdriver/convert_test.go +++ b/go/vt/vitessdriver/convert_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 GitHub Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/vitessdriver/doc.go b/go/vt/vitessdriver/doc.go index 9641aa00ca6..a3e2770b8ac 100644 --- a/go/vt/vitessdriver/doc.go +++ b/go/vt/vitessdriver/doc.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/vitessdriver/driver.go b/go/vt/vitessdriver/driver.go index 776e82d4aff..720f13f5bc6 100644 --- a/go/vt/vitessdriver/driver.go +++ b/go/vt/vitessdriver/driver.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vitessdriver/driver_test.go b/go/vt/vitessdriver/driver_test.go index 4c9d5b8c85d..57e1d9fb6db 100644 --- a/go/vt/vitessdriver/driver_test.go +++ b/go/vt/vitessdriver/driver_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vitessdriver/fakeserver_test.go b/go/vt/vitessdriver/fakeserver_test.go index d0ddecad194..e47103b2696 100644 --- a/go/vt/vitessdriver/fakeserver_test.go +++ b/go/vt/vitessdriver/fakeserver_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/vitessdriver/plugin_grpcvtgateconn.go b/go/vt/vitessdriver/plugin_grpcvtgateconn.go index 0e4e4f95a7a..e4b650f360f 100644 --- a/go/vt/vitessdriver/plugin_grpcvtgateconn.go +++ b/go/vt/vitessdriver/plugin_grpcvtgateconn.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vitessdriver/rows.go b/go/vt/vitessdriver/rows.go index b0a7fc99f6b..d2ace7bdfad 100644 --- a/go/vt/vitessdriver/rows.go +++ b/go/vt/vitessdriver/rows.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vitessdriver/rows_test.go b/go/vt/vitessdriver/rows_test.go index 30be0f0c074..6a40402dbea 100644 --- a/go/vt/vitessdriver/rows_test.go +++ b/go/vt/vitessdriver/rows_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/vitessdriver/streaming_rows.go b/go/vt/vitessdriver/streaming_rows.go index e35f67f0ec5..18aac422e5a 100644 --- a/go/vt/vitessdriver/streaming_rows.go +++ b/go/vt/vitessdriver/streaming_rows.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vitessdriver/streaming_rows_test.go b/go/vt/vitessdriver/streaming_rows_test.go index f128828ab44..d084f0755b8 100644 --- a/go/vt/vitessdriver/streaming_rows_test.go +++ b/go/vt/vitessdriver/streaming_rows_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vitessdriver/time.go b/go/vt/vitessdriver/time.go index 2ff81e7bdc9..aaf34331e87 100644 --- a/go/vt/vitessdriver/time.go +++ b/go/vt/vitessdriver/time.go @@ -1,5 +1,5 @@ /* -Copyright 2017 GitHub Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/vitessdriver/time_test.go b/go/vt/vitessdriver/time_test.go index 2b2cfbb15fe..d2924fa343a 100644 --- a/go/vt/vitessdriver/time_test.go +++ b/go/vt/vitessdriver/time_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 GitHub Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/vtaclcheck/vtaclcheck.go b/go/vt/vtaclcheck/vtaclcheck.go index f9a4f7ab74f..6b84e594e4b 100644 --- a/go/vt/vtaclcheck/vtaclcheck.go +++ b/go/vt/vtaclcheck/vtaclcheck.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Vitess Authors +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. diff --git a/go/vt/vtcombo/tablet_map.go b/go/vt/vtcombo/tablet_map.go index a4cd2baab50..49d0454270d 100644 --- a/go/vt/vtcombo/tablet_map.go +++ b/go/vt/vtcombo/tablet_map.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 @@ -111,6 +111,14 @@ func InitTabletMap(ts *topo.Server, tpb *vttestpb.VTTestTopology, mysqld mysqlct ctx := context.Background() + // Register the tablet manager client factory for tablet manager + // Do this before any tablets are created so that they respect the protocol, + // otherwise it defaults to grpc + tmclient.RegisterTabletManagerClientFactory("internal", func() tmclient.TabletManagerClient { + return &internalTabletManagerClient{} + }) + *tmclient.TabletManagerProtocol = "internal" + // iterate through the keyspaces wr := wrangler.New(logutil.NewConsoleLogger(), ts, nil) var uid uint32 = 1 @@ -246,12 +254,6 @@ func InitTabletMap(ts *topo.Server, tpb *vttestpb.VTTestTopology, mysqld mysqlct tabletconn.RegisterDialer("internal", dialer) *tabletconn.TabletProtocol = "internal" - // Register the tablet manager client factory for tablet manager - tmclient.RegisterTabletManagerClientFactory("internal", func() tmclient.TabletManagerClient { - return &internalTabletManagerClient{} - }) - *tmclient.TabletManagerProtocol = "internal" - // run healthcheck on all vttablets tmc := tmclient.NewTabletManagerClient() for _, tablet := range tabletMap { @@ -488,6 +490,12 @@ func (itc *internalTabletConn) VStreamRows(ctx context.Context, target *querypb. return tabletconn.ErrorFromGRPC(vterrors.ToGRPC(err)) } +// VStreamResults is part of the QueryService interface. +func (itc *internalTabletConn) VStreamResults(ctx context.Context, target *querypb.Target, query string, send func(*binlogdatapb.VStreamResultsResponse) error) error { + err := itc.tablet.qsc.QueryService().VStreamResults(ctx, target, query, send) + return tabletconn.ErrorFromGRPC(vterrors.ToGRPC(err)) +} + // // TabletManagerClient implementation // @@ -628,6 +636,10 @@ func (itmc *internalTabletManagerClient) MasterPosition(ctx context.Context, tab return "", fmt.Errorf("not implemented in vtcombo") } +func (itmc *internalTabletManagerClient) WaitForPosition(ctx context.Context, tablet *topodatapb.Tablet, pos string) error { + return fmt.Errorf("not implemented in vtcombo") +} + func (itmc *internalTabletManagerClient) StopSlave(ctx context.Context, tablet *topodatapb.Tablet) error { return fmt.Errorf("not implemented in vtcombo") } @@ -692,7 +704,7 @@ func (itmc *internalTabletManagerClient) SlaveWasPromoted(ctx context.Context, t return fmt.Errorf("not implemented in vtcombo") } -func (itmc *internalTabletManagerClient) SetMaster(ctx context.Context, tablet *topodatapb.Tablet, parent *topodatapb.TabletAlias, timeCreatedNS int64, forceStartSlave bool) error { +func (itmc *internalTabletManagerClient) SetMaster(ctx context.Context, tablet *topodatapb.Tablet, parent *topodatapb.TabletAlias, timeCreatedNS int64, waitPosition string, forceStartSlave bool) error { return fmt.Errorf("not implemented in vtcombo") } diff --git a/go/vt/vtctl/backup.go b/go/vt/vtctl/backup.go index 61fd0231e9b..89b6b1ed434 100644 --- a/go/vt/vtctl/backup.go +++ b/go/vt/vtctl/backup.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vtctl/cell_info.go b/go/vt/vtctl/cell_info.go index c1917c8934c..7819cb8b45d 100644 --- a/go/vt/vtctl/cell_info.go +++ b/go/vt/vtctl/cell_info.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/vtctl/fakevtctlclient/fake_loggerevent_streamingclient.go b/go/vt/vtctl/fakevtctlclient/fake_loggerevent_streamingclient.go index 15689624e76..54f757ab60b 100644 --- a/go/vt/vtctl/fakevtctlclient/fake_loggerevent_streamingclient.go +++ b/go/vt/vtctl/fakevtctlclient/fake_loggerevent_streamingclient.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vtctl/fakevtctlclient/fake_loggerevent_streamingclient_test.go b/go/vt/vtctl/fakevtctlclient/fake_loggerevent_streamingclient_test.go index 785a1605023..04a0ad5e03d 100644 --- a/go/vt/vtctl/fakevtctlclient/fake_loggerevent_streamingclient_test.go +++ b/go/vt/vtctl/fakevtctlclient/fake_loggerevent_streamingclient_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vtctl/fakevtctlclient/fakevtctlclient.go b/go/vt/vtctl/fakevtctlclient/fakevtctlclient.go index 3d9ac18b6a5..a8baad6ba7a 100644 --- a/go/vt/vtctl/fakevtctlclient/fakevtctlclient.go +++ b/go/vt/vtctl/fakevtctlclient/fakevtctlclient.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vtctl/grpcvtctlclient/client.go b/go/vt/vtctl/grpcvtctlclient/client.go index a1defa54c5e..62f5c5d00eb 100644 --- a/go/vt/vtctl/grpcvtctlclient/client.go +++ b/go/vt/vtctl/grpcvtctlclient/client.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vtctl/grpcvtctlclient/client_test.go b/go/vt/vtctl/grpcvtctlclient/client_test.go index eae78dc814e..c48930eefff 100644 --- a/go/vt/vtctl/grpcvtctlclient/client_test.go +++ b/go/vt/vtctl/grpcvtctlclient/client_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vtctl/grpcvtctlserver/server.go b/go/vt/vtctl/grpcvtctlserver/server.go index f3628894f62..c3630e3f848 100644 --- a/go/vt/vtctl/grpcvtctlserver/server.go +++ b/go/vt/vtctl/grpcvtctlserver/server.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vtctl/plugin_consultopo.go b/go/vt/vtctl/plugin_consultopo.go index 725a2dd57e5..53c7e929995 100644 --- a/go/vt/vtctl/plugin_consultopo.go +++ b/go/vt/vtctl/plugin_consultopo.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/vtctl/plugin_etcd2topo.go b/go/vt/vtctl/plugin_etcd2topo.go index 2e8a6c6cbb2..5e796b64e9b 100644 --- a/go/vt/vtctl/plugin_etcd2topo.go +++ b/go/vt/vtctl/plugin_etcd2topo.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/vtctl/plugin_zk2topo.go b/go/vt/vtctl/plugin_zk2topo.go index 72640b2ae93..76fa5bd5d1f 100644 --- a/go/vt/vtctl/plugin_zk2topo.go +++ b/go/vt/vtctl/plugin_zk2topo.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/vtctl/query.go b/go/vt/vtctl/query.go index a4cc9655246..b6f068fedc5 100644 --- a/go/vt/vtctl/query.go +++ b/go/vt/vtctl/query.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vtctl/query_test.go b/go/vt/vtctl/query_test.go index 61e22997cb6..12ffcd411b1 100644 --- a/go/vt/vtctl/query_test.go +++ b/go/vt/vtctl/query_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vtctl/reparent.go b/go/vt/vtctl/reparent.go index d66ec73426b..e8ba700b36d 100644 --- a/go/vt/vtctl/reparent.go +++ b/go/vt/vtctl/reparent.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -45,13 +45,19 @@ func init() { addCommand("Shards", command{ "PlannedReparentShard", commandPlannedReparentShard, - "-keyspace_shard= [-new_master=] [-avoid_master=]", + "-keyspace_shard= [-new_master=] [-avoid_master=] [-wait_slave_timeout=]", "Reparents the shard to the new master, or away from old master. Both old and new master need to be up and running."}) addCommand("Shards", command{ "EmergencyReparentShard", commandEmergencyReparentShard, "-keyspace_shard= -new_master=", "Reparents the shard to the new master. Assumes the old master is dead and not responsding."}) + addCommand("Shards", command{ + "TabletExternallyReparented", + commandTabletExternallyReparented, + "", + "Changes metadata in the topology server to acknowledge a shard master change performed by an external tool. See the Reparenting guide for more information:" + + "https://vitess.io/docs/user-guides/reparenting/#external-reparenting"}) } func commandReparentTablet(ctx context.Context, wr *wrangler.Wrangler, subFlags *flag.FlagSet, args []string) error { @@ -101,7 +107,7 @@ func commandPlannedReparentShard(ctx context.Context, wr *wrangler.Wrangler, sub return fmt.Errorf("active reparent commands disabled (unset the -disable_active_reparents flag to enable)") } - waitSlaveTimeout := subFlags.Duration("wait_slave_timeout", *topo.RemoteOperationTimeout, "time to wait for slaves to catch up in reparenting") + waitSlaveTimeout := subFlags.Duration("wait_slave_timeout", *topo.RemoteOperationTimeout, "time to wait for replicas to catch up on replication before and after reparenting") keyspaceShard := subFlags.String("keyspace_shard", "", "keyspace/shard of the shard that needs to be reparented") newMaster := subFlags.String("new_master", "", "alias of a tablet that should be the new master") avoidMaster := subFlags.String("avoid_master", "", "alias of a tablet that should not be the master, i.e. reparent to any other tablet if this one is the master") @@ -171,3 +177,18 @@ func commandEmergencyReparentShard(ctx context.Context, wr *wrangler.Wrangler, s } return wr.EmergencyReparentShard(ctx, keyspace, shard, tabletAlias, *waitSlaveTimeout) } + +func commandTabletExternallyReparented(ctx context.Context, wr *wrangler.Wrangler, subFlags *flag.FlagSet, args []string) error { + if err := subFlags.Parse(args); err != nil { + return err + } + if subFlags.NArg() != 1 { + return fmt.Errorf("action TabletExternallyReparented requires ") + } + + tabletAlias, err := topoproto.ParseTabletAlias(subFlags.Arg(0)) + if err != nil { + return err + } + return wr.TabletExternallyReparented(ctx, tabletAlias) +} diff --git a/go/vt/vtctl/throttler.go b/go/vt/vtctl/throttler.go index 1e8452e577b..dfdfe4e061b 100644 --- a/go/vt/vtctl/throttler.go +++ b/go/vt/vtctl/throttler.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vtctl/topo.go b/go/vt/vtctl/topo.go index eaabedaf227..65728af656e 100644 --- a/go/vt/vtctl/topo.go +++ b/go/vt/vtctl/topo.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vtctl/vtctl.go b/go/vt/vtctl/vtctl.go index 94cb8744a61..d8cd3d18e75 100644 --- a/go/vt/vtctl/vtctl.go +++ b/go/vt/vtctl/vtctl.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -120,11 +120,14 @@ 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/vterrors" "vitess.io/vitess/go/vt/wrangler" replicationdatapb "vitess.io/vitess/go/vt/proto/replicationdata" topodatapb "vitess.io/vitess/go/vt/proto/topodata" vschemapb "vitess.io/vitess/go/vt/proto/vschema" + vtrpcpb "vitess.io/vitess/go/vt/proto/vtrpc" + "vitess.io/vitess/go/vt/proto/vttime" ) var ( @@ -228,10 +231,6 @@ var commands = []commandGroup{ {"GetShard", commandGetShard, "", "Outputs a JSON structure that contains information about the Shard."}, - {"TabletExternallyReparented", commandTabletExternallyReparented, - "", - "Changes metadata in the topology server to acknowledge a shard master change performed by an external tool. See the Reparenting guide for more information:" + - "https://github.com/vitessio/vitess/blob/master/doc/Reparenting.md#external-reparents."}, {"ValidateShard", commandValidateShard, "[-ping-tablets] ", "Validates that all nodes that are reachable from this shard are consistent."}, @@ -282,8 +281,8 @@ var commands = []commandGroup{ { "Keyspaces", []command{ {"CreateKeyspace", commandCreateKeyspace, - "[-sharding_column_name=name] [-sharding_column_type=type] [-served_from=tablettype1:ks1,tablettype2:ks2,...] [-force] ", - "Creates the specified keyspace."}, + "[-sharding_column_name=name] [-sharding_column_type=type] [-served_from=tablettype1:ks1,tablettype2:ks2,...] [-force] [-keyspace_type=type] [-base_keyspace=base_keyspace] [-snapshot_time=time] ", + "Creates the specified keyspace. keyspace_type can be NORMAL or SNAPSHOT. For a SNAPSHOT keyspace you must specify the name of a base_keyspace, and a snapshot_time in UTC, in RFC3339 time format, e.g. 2006-01-02T15:04:05+00:00"}, {"DeleteKeyspace", commandDeleteKeyspace, "[-recursive] ", "Deletes the specified keyspace. In recursive mode, it also recursively deletes all shards in the keyspace. Otherwise, there must be no shards left in the keyspace."}, @@ -314,6 +313,9 @@ var commands = []commandGroup{ {"VerticalSplitClone", commandVerticalSplitClone, " ", "Start the VerticalSplitClone process to perform vertical resharding. Example: SplitClone from_ks to_ks 'a,/b.*/'"}, + {"VDiff", commandVDiff, + "-workflow= [-source_cell=] [-target_cell=] [-tablet_types=REPLICA] [-filtered_replication_wait_time=30s]", + "Perform a diff of all tables in the workflow"}, {"MigrateServedTypes", commandMigrateServedTypes, "[-cells=c1,c2,...] [-reverse] [-skip-refresh-state] ", "Migrates a serving type from the source shard to the shards that it replicates to. This command also rebuilds the serving graph. The argument can specify any of the shards involved in the migration."}, @@ -324,7 +326,7 @@ var commands = []commandGroup{ "[-cells=c1,c2,...] [-reverse] -workflow=workflow ", "Migrate read traffic for the specified workflow."}, {"MigrateWrites", commandMigrateWrites, - "[-filtered_replication_wait_time=30s] -workflow=workflow ", + "[-filtered_replication_wait_time=30s] [-cancel] [-reverse_replication=false] -workflow=workflow ", "Migrate write traffic for the specified workflow."}, {"CancelResharding", commandCancelResharding, "", @@ -1156,7 +1158,7 @@ func commandExecuteHook(ctx context.Context, wr *wrangler.Wrangler, subFlags *fl } func commandCreateShard(ctx context.Context, wr *wrangler.Wrangler, subFlags *flag.FlagSet, args []string) error { - force := subFlags.Bool("force", false, "Proceeds with the command even if the keyspace already exists") + force := subFlags.Bool("force", false, "Proceeds with the command even if the shard already exists") parent := subFlags.Bool("parent", false, "Creates the parent keyspace if it doesn't already exist") if err := subFlags.Parse(args); err != nil { return err @@ -1203,25 +1205,6 @@ func commandGetShard(ctx context.Context, wr *wrangler.Wrangler, subFlags *flag. return printJSON(wr.Logger(), shardInfo.Shard) } -func commandTabletExternallyReparented(ctx context.Context, wr *wrangler.Wrangler, subFlags *flag.FlagSet, args []string) error { - if err := subFlags.Parse(args); err != nil { - return err - } - if subFlags.NArg() != 1 { - return fmt.Errorf("the argument is required for the TabletExternallyReparented command") - } - - tabletAlias, err := topoproto.ParseTabletAlias(subFlags.Arg(0)) - if err != nil { - return err - } - ti, err := wr.TopoServer().GetTablet(ctx, tabletAlias) - if err != nil { - return err - } - return wr.TabletManagerClient().TabletExternallyReparented(ctx, ti.Tablet, "") -} - func commandValidateShard(ctx context.Context, wr *wrangler.Wrangler, subFlags *flag.FlagSet, args []string) error { pingTablets := subFlags.Bool("ping-tablets", true, "Indicates whether all tablets should be pinged during the validation process") if err := subFlags.Parse(args); err != nil { @@ -1552,6 +1535,9 @@ func commandCreateKeyspace(ctx context.Context, wr *wrangler.Wrangler, subFlags var servedFrom flagutil.StringMapValue subFlags.Var(&servedFrom, "served_from", "Specifies a comma-separated list of dbtype:keyspace pairs used to serve traffic") + 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") if err := subFlags.Parse(args); err != nil { return err } @@ -1564,9 +1550,40 @@ func commandCreateKeyspace(ctx context.Context, wr *wrangler.Wrangler, subFlags if err != nil { return err } + ktype := topodatapb.KeyspaceType_NORMAL + if *keyspaceType != "" { + kt, err := topoproto.ParseKeyspaceType(*keyspaceType) + if err != nil { + wr.Logger().Infof("error parsing keyspace type %v, defaulting to NORMAL", *keyspaceType) + } else { + ktype = kt + } + } + + var snapshotTime *vttime.Time + if ktype == topodatapb.KeyspaceType_SNAPSHOT { + if *baseKeyspace == "" { + return vterrors.New(vtrpcpb.Code_INVALID_ARGUMENT, "base_keyspace must be specified while creating a snapshot keyspace") + } + if _, err := wr.TopoServer().GetKeyspace(ctx, *baseKeyspace); err != nil { + return vterrors.Wrapf(err, "Cannot find base_keyspace: %v", *baseKeyspace) + } + // process snapshot_time + if *timestampStr == "" { + return vterrors.New(vtrpcpb.Code_INVALID_ARGUMENT, "snapshot_time must be specified when creating a snapshot keyspace") + } + timeTime, err := time.Parse(time.RFC3339, *timestampStr) + if err != nil { + return err + } + snapshotTime = logutil.TimeToProto(timeTime) + } ki := &topodatapb.Keyspace{ ShardingColumnName: *shardingColumnName, ShardingColumnType: kit, + KeyspaceType: ktype, + BaseKeyspace: *baseKeyspace, + SnapshotTime: snapshotTime, } if len(servedFrom) > 0 { for name, value := range servedFrom { @@ -1590,7 +1607,36 @@ func commandCreateKeyspace(ctx context.Context, wr *wrangler.Wrangler, subFlags err = wr.TopoServer().EnsureVSchema(ctx, keyspace) } - return err + if err != nil { + return err + } + + if ktype == topodatapb.KeyspaceType_SNAPSHOT { + // copy vschema from base keyspace + vs, err := wr.TopoServer().GetVSchema(ctx, *baseKeyspace) + 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, + } + } 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) + return err + } + return wr.TopoServer().RebuildSrvVSchema(ctx, []string{} /* cells */) + } + return nil } func commandDeleteKeyspace(ctx context.Context, wr *wrangler.Wrangler, subFlags *flag.FlagSet, args []string) error { @@ -1764,6 +1810,25 @@ func commandVerticalSplitClone(ctx context.Context, wr *wrangler.Wrangler, subFl return wr.VerticalSplitClone(ctx, fromKeyspace, toKeyspace, tables) } +func commandVDiff(ctx context.Context, wr *wrangler.Wrangler, subFlags *flag.FlagSet, args []string) error { + workflow := subFlags.String("workflow", "", "Specifies the workflow name") + sourceCell := subFlags.String("source_cell", "", "The source cell to compare from") + targetCell := subFlags.String("target_cell", "", "The target cell to compare with") + tabletTypes := subFlags.String("tablet_types", "", "Tablet types for source and target") + filteredReplicationWaitTime := subFlags.Duration("filtered_replication_wait_time", 30*time.Second, "Specifies the maximum time to wait, in seconds, for filtered replication to catch up on master migrations. The migration will be aborted on timeout.") + if err := subFlags.Parse(args); err != nil { + return err + } + if subFlags.NArg() != 1 { + return fmt.Errorf("the is required") + } + + targetKeyspace := subFlags.Arg(0) + _, err := wr.VDiff(ctx, targetKeyspace, *workflow, *sourceCell, *targetCell, *tabletTypes, *filteredReplicationWaitTime, + *HealthCheckTopologyRefresh, *HealthcheckRetryDelay, *HealthCheckTimeout) + return err +} + func commandMigrateServedTypes(ctx context.Context, wr *wrangler.Wrangler, subFlags *flag.FlagSet, args []string) error { cellsStr := subFlags.String("cells", "", "Specifies a comma-separated list of cells to update") reverse := subFlags.Bool("reverse", false, "Moves the served tablet type backward instead of forward.") @@ -1853,6 +1918,8 @@ func commandMigrateReads(ctx context.Context, wr *wrangler.Wrangler, subFlags *f func commandMigrateWrites(ctx context.Context, wr *wrangler.Wrangler, subFlags *flag.FlagSet, args []string) error { filteredReplicationWaitTime := subFlags.Duration("filtered_replication_wait_time", 30*time.Second, "Specifies the maximum time to wait, in seconds, for filtered replication to catch up on master migrations. The migration will be aborted on timeout.") + reverseReplication := subFlags.Bool("reverse_replication", true, "Also reverse the replication") + cancelMigrate := subFlags.Bool("cancel", false, "Cancel the failed migration and serve from source") workflow := subFlags.String("workflow", "", "Specifies the workflow name") if err := subFlags.Parse(args); err != nil { return err @@ -1865,7 +1932,7 @@ func commandMigrateWrites(ctx context.Context, wr *wrangler.Wrangler, subFlags * if *workflow == "" { return fmt.Errorf("a -workflow=workflow argument is required") } - journalID, err := wr.MigrateWrites(ctx, keyspace, *workflow, *filteredReplicationWaitTime) + journalID, err := wr.MigrateWrites(ctx, keyspace, *workflow, *filteredReplicationWaitTime, *cancelMigrate, *reverseReplication) if err != nil { return err } diff --git a/go/vt/vtctl/vtctlclient/interface.go b/go/vt/vtctl/vtctlclient/interface.go index 1626505e9a7..b46f0639e72 100644 --- a/go/vt/vtctl/vtctlclient/interface.go +++ b/go/vt/vtctl/vtctlclient/interface.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vtctl/vtctlclient/wrapper.go b/go/vt/vtctl/vtctlclient/wrapper.go index cc1b9500652..34cfeb89083 100644 --- a/go/vt/vtctl/vtctlclient/wrapper.go +++ b/go/vt/vtctl/vtctlclient/wrapper.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vtctl/vtctlclienttest/client.go b/go/vt/vtctl/vtctlclienttest/client.go index ca43317996f..9ec2684dbad 100644 --- a/go/vt/vtctl/vtctlclienttest/client.go +++ b/go/vt/vtctl/vtctlclienttest/client.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vtctl/workflow.go b/go/vt/vtctl/workflow.go index 5e91e7304cc..426f373fbb6 100644 --- a/go/vt/vtctl/workflow.go +++ b/go/vt/vtctl/workflow.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/vtctld/action_repository.go b/go/vt/vtctld/action_repository.go index 7b484707eae..3659e5939c1 100644 --- a/go/vt/vtctld/action_repository.go +++ b/go/vt/vtctld/action_repository.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/vtctld/api.go b/go/vt/vtctld/api.go index e2657720f77..9519d630cfa 100644 --- a/go/vt/vtctld/api.go +++ b/go/vt/vtctld/api.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/vtctld/api_test.go b/go/vt/vtctld/api_test.go index 57d4e77a0e3..a968e8f4697 100644 --- a/go/vt/vtctld/api_test.go +++ b/go/vt/vtctld/api_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 @@ -31,6 +31,7 @@ import ( "vitess.io/vitess/go/vt/wrangler" topodatapb "vitess.io/vitess/go/vt/proto/topodata" + vschemapb "vitess.io/vitess/go/vt/proto/vschema" ) func compactJSON(in []byte) string { @@ -50,9 +51,29 @@ func TestAPI(t *testing.T) { // Populate topo. Remove ServedTypes from shards to avoid ordering issues. ts.CreateKeyspace(ctx, "ks1", &topodatapb.Keyspace{ShardingColumnName: "shardcol"}) ts.CreateShard(ctx, "ks1", "-80") - ts.CreateShard(ctx, "ks1", "80-") + // SaveVSchema to test that creating a snapshot keyspace copies VSchema + vs := &vschemapb.Keyspace{ + Sharded: true, + Vindexes: map[string]*vschemapb.Vindex{ + "name1": { + Type: "hash", + }, + }, + Tables: map[string]*vschemapb.Table{ + "table1": { + ColumnVindexes: []*vschemapb.ColumnVindex{ + { + Column: "column1", + Name: "name1", + }, + }, + }, + }, + } + ts.SaveVSchema(ctx, "ks1", vs) + tablet1 := topodatapb.Tablet{ Alias: &topodatapb.TabletAlias{Cell: "cell1", Uid: 100}, Keyspace: "ks1", @@ -109,15 +130,24 @@ func TestAPI(t *testing.T) { table := []struct { method, path, body, want string }{ + // Create snapshot keyspace using API + {"POST", "vtctl/", `["CreateKeyspace", "-keyspace_type=SNAPSHOT", "-base_keyspace=ks1", "-snapshot_time=2006-01-02T15:04:05+00:00", "ks3"]`, `{ + "Error": "", + "Output": "" + }`}, + // Cells {"GET", "cells", "", `["cell1","cell2"]`}, // Keyspaces - {"GET", "keyspaces", "", `["ks1"]`}, + {"GET", "keyspaces", "", `["ks1", "ks3"]`}, {"GET", "keyspaces/ks1", "", `{ "sharding_column_name": "shardcol", "sharding_column_type": 0, - "served_froms": [] + "served_froms": [], + "keyspace_type":0, + "base_keyspace":"", + "snapshot_time":null }`}, {"GET", "keyspaces/nonexistent", "", "404 page not found"}, {"POST", "keyspaces/ks1?action=TestKeyspaceAction", "", `{ @@ -131,6 +161,7 @@ func TestAPI(t *testing.T) { {"GET", "shards/ks1/", "", `["-80","80-"]`}, {"GET", "shards/ks1/-80", "", `{ "master_alias": null, + "master_term_start_time":null, "key_range": { "start": null, "end":"gA==" @@ -174,7 +205,8 @@ func TestAPI(t *testing.T) { "db_name_override": "", "tags": {}, "mysql_hostname":"", - "mysql_port":0 + "mysql_port":0, + "master_term_start_time":null }`}, {"GET", "tablets/nonexistent-999", "", "404 page not found"}, {"POST", "tablets/cell1-100?action=TestTabletAction", "", `{ @@ -254,7 +286,15 @@ func TestAPI(t *testing.T) { // vtctl RunCommand {"POST", "vtctl/", `["GetKeyspace","ks1"]`, `{ "Error": "", - "Output": "{\n \"sharding_column_name\": \"shardcol\",\n \"sharding_column_type\": 0,\n \"served_froms\": [\n ]\n}\n\n" + "Output": "{\n \"sharding_column_name\": \"shardcol\",\n \"sharding_column_type\": 0,\n \"served_froms\": [\n ],\n \"keyspace_type\": 0,\n \"base_keyspace\": \"\",\n \"snapshot_time\": null\n}\n\n" + }`}, + {"POST", "vtctl/", `["GetKeyspace","ks3"]`, `{ + "Error": "", + "Output": "{\n \"sharding_column_name\": \"\",\n \"sharding_column_type\": 0,\n \"served_froms\": [\n ],\n \"keyspace_type\": 1,\n \"base_keyspace\": \"ks1\",\n \"snapshot_time\": {\n \"seconds\": \"1136214245\",\n \"nanoseconds\": 0\n }\n}\n\n" + }`}, + {"POST", "vtctl/", `["GetVSchema","ks3"]`, `{ + "Error": "", + "Output": "{\n \"sharded\": true,\n \"vindexes\": {\n \"name1\": {\n \"type\": \"hash\"\n }\n },\n \"tables\": {\n \"table1\": {\n \"columnVindexes\": [\n {\n \"column\": \"column1\",\n \"name\": \"name1\"\n }\n ]\n }\n },\n \"requireExplicitRouting\": true\n}\n\n" }`}, {"POST", "vtctl/", `["GetKeyspace","does_not_exist"]`, `{ "Error": "node doesn't exist: keyspaces/does_not_exist/Keyspace", diff --git a/go/vt/vtctld/debug_health.go b/go/vt/vtctld/debug_health.go index 272e2346152..c0fc6fb4888 100644 --- a/go/vt/vtctld/debug_health.go +++ b/go/vt/vtctld/debug_health.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/vtctld/explorer.go b/go/vt/vtctld/explorer.go index 2dd4275563d..6ba2ae81898 100644 --- a/go/vt/vtctld/explorer.go +++ b/go/vt/vtctld/explorer.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/vtctld/explorer_test.go b/go/vt/vtctld/explorer_test.go index 3ecb0633d75..942025d32b6 100644 --- a/go/vt/vtctld/explorer_test.go +++ b/go/vt/vtctld/explorer_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/vtctld/realtime_status.go b/go/vt/vtctld/realtime_status.go index 8f9b3786115..c3e04dfcb0c 100644 --- a/go/vt/vtctld/realtime_status.go +++ b/go/vt/vtctld/realtime_status.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/vtctld/realtime_status_test.go b/go/vt/vtctld/realtime_status_test.go index d7fc17a7485..4df601a955e 100644 --- a/go/vt/vtctld/realtime_status_test.go +++ b/go/vt/vtctld/realtime_status_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/vtctld/tablet_data.go b/go/vt/vtctld/tablet_data.go index 07a3529b50c..3db00ad97be 100644 --- a/go/vt/vtctld/tablet_data.go +++ b/go/vt/vtctld/tablet_data.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/vtctld/tablet_data_test.go b/go/vt/vtctld/tablet_data_test.go index edc69d985a1..649bed081cb 100644 --- a/go/vt/vtctld/tablet_data_test.go +++ b/go/vt/vtctld/tablet_data_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/vtctld/tablet_stats_cache.go b/go/vt/vtctld/tablet_stats_cache.go index 26323010895..9e7e0fa5dbd 100644 --- a/go/vt/vtctld/tablet_stats_cache.go +++ b/go/vt/vtctld/tablet_stats_cache.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/vtctld/tablet_stats_cache_test.go b/go/vt/vtctld/tablet_stats_cache_test.go index 9209fd8dbd3..781d0c98f77 100644 --- a/go/vt/vtctld/tablet_stats_cache_test.go +++ b/go/vt/vtctld/tablet_stats_cache_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/vtctld/vtctld.go b/go/vt/vtctld/vtctld.go index 96c7f13fc1a..ea66db4d8c5 100644 --- a/go/vt/vtctld/vtctld.go +++ b/go/vt/vtctld/vtctld.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/vtctld/workflow.go b/go/vt/vtctld/workflow.go index 1982e9093d3..f9527409cdb 100644 --- a/go/vt/vtctld/workflow.go +++ b/go/vt/vtctld/workflow.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/vterrors/aggregate.go b/go/vt/vterrors/aggregate.go index e55767e123a..232d778908b 100644 --- a/go/vt/vterrors/aggregate.go +++ b/go/vt/vterrors/aggregate.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vterrors/aggregate_test.go b/go/vt/vterrors/aggregate_test.go index 6f7841282ac..76985b1cdb8 100644 --- a/go/vt/vterrors/aggregate_test.go +++ b/go/vt/vterrors/aggregate_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vterrors/errors_test.go b/go/vt/vterrors/errors_test.go index f0498ee3306..ed716392521 100644 --- a/go/vt/vterrors/errors_test.go +++ b/go/vt/vterrors/errors_test.go @@ -1,3 +1,19 @@ +/* +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 vterrors import ( diff --git a/go/vt/vterrors/grpc.go b/go/vt/vterrors/grpc.go index a1a416155c6..640e37c6d13 100644 --- a/go/vt/vterrors/grpc.go +++ b/go/vt/vterrors/grpc.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vterrors/proto3.go b/go/vt/vterrors/proto3.go index e88bd6ba50c..1f59eabd6a2 100644 --- a/go/vt/vterrors/proto3.go +++ b/go/vt/vterrors/proto3.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vterrors/proto3_test.go b/go/vt/vterrors/proto3_test.go index c2b8395969e..502346bd2d2 100644 --- a/go/vt/vterrors/proto3_test.go +++ b/go/vt/vterrors/proto3_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vterrors/stack.go b/go/vt/vterrors/stack.go index 3b81c0fda83..ba9264290da 100644 --- a/go/vt/vterrors/stack.go +++ b/go/vt/vterrors/stack.go @@ -1,3 +1,19 @@ +/* +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 vterrors /* This file is copied from https://github.com/pkg/errors/blob/v0.8.0/stack.go */ diff --git a/go/vt/vterrors/vterrors.go b/go/vt/vterrors/vterrors.go index e5afae1c66c..e50cd6706ed 100644 --- a/go/vt/vterrors/vterrors.go +++ b/go/vt/vterrors/vterrors.go @@ -1,3 +1,19 @@ +/* +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 vterrors provides simple error handling primitives for Vitess // // In all Vitess code, errors should be propagated using vterrors.Wrapf() diff --git a/go/vt/vtexplain/testdata/multi-output/selectsharded-output.txt b/go/vt/vtexplain/testdata/multi-output/selectsharded-output.txt index 6f458bdd8b5..fa6637e58ce 100644 --- a/go/vt/vtexplain/testdata/multi-output/selectsharded-output.txt +++ b/go/vt/vtexplain/testdata/multi-output/selectsharded-output.txt @@ -126,3 +126,43 @@ select * from name_info order by info /* select * and order by varchar column */ 1 ks_sharded/c0-: select name, info, weight_string(info) from name_info order by info asc limit 10001 /* select * and order by varchar column */ ---------------------------------------------------------------------- +select distinct(name) from user where id = 1 /* select distinct */ + +1 ks_sharded/-40: select distinct (name) from user where id = 1 limit 10001 /* select distinct */ + +---------------------------------------------------------------------- +select distinct name from user where id = 1 /* select distinct */ + +1 ks_sharded/-40: select distinct name from user where id = 1 limit 10001 /* select distinct */ + +---------------------------------------------------------------------- +select id, substring(name, 1, -1) from user where id = 123 /* select substring */ + +1 ks_sharded/-40: select id, substr(name, 1, -1) from user where id = 123 limit 10001 /* select substring */ + +---------------------------------------------------------------------- +select id, substring_index(name, '123456', -1) from user where id = 123 /* select substring_index */ + +1 ks_sharded/-40: select id, substring_index(name, '123456', -1) from user where id = 123 limit 10001 /* select substring_index */ + +---------------------------------------------------------------------- +select id, case when name = 'alice' then 'ALICE' when name = 'bob' then 'BOB' end as name from user where id = 1 /* select case */ + +1 ks_sharded/-40: select id, case when name = 'alice' then 'ALICE' when name = 'bob' then 'BOB' end as name from user where id = 1 limit 10001 /* select case */ + +---------------------------------------------------------------------- +select id, case when name = 'alice' then 'ALICE' when name = 'bob' then 'BOB' else 'OTHER' end as name from user where id = 1 /* select case */ + +1 ks_sharded/-40: select id, case when name = 'alice' then 'ALICE' when name = 'bob' then 'BOB' else 'OTHER' end as name from user where id = 1 limit 10001 /* select case */ + +---------------------------------------------------------------------- +select id, case when substr(name, 1, 5) = 'alice' then 'ALICE' when name = 'bob' then 'BOB' else 'OTHER' end as name from user where id = 1 /* select case */ + +1 ks_sharded/-40: select id, case when substr(name, 1, 5) = 'alice' then 'ALICE' when name = 'bob' then 'BOB' else 'OTHER' end as name from user where id = 1 limit 10001 /* select case */ + +---------------------------------------------------------------------- +select id, 'abc' as test from user where id = 1 union all select id, 'def' as test from user where id = 1 union all select id, 'ghi' as test from user where id = 1 /* union all */ + +1 ks_sharded/-40: select id, 'abc' as test from user where id = 1 union all select id, 'def' as test from user where id = 1 union all select id, 'ghi' as test from user where id = 1 limit 10001 /* union all */ + +---------------------------------------------------------------------- diff --git a/go/vt/vtexplain/testdata/selectsharded-queries.sql b/go/vt/vtexplain/testdata/selectsharded-queries.sql index a51570ca833..b9c42e3f05d 100644 --- a/go/vt/vtexplain/testdata/selectsharded-queries.sql +++ b/go/vt/vtexplain/testdata/selectsharded-queries.sql @@ -19,4 +19,16 @@ select name from user where id in (select id from t1) /* non-correlated subquery select name from user where id not in (select id from t1) /* non-correlated subquery in NOT IN clause */; select name from user where exists (select id from t1) /* non-correlated subquery as EXISTS */; -select * from name_info order by info /* select * and order by varchar column */ +select * from name_info order by info /* select * and order by varchar column */; + +select distinct(name) from user where id = 1 /* select distinct */; +select distinct name from user where id = 1 /* select distinct */; + +select id, substring(name, 1, -1) from user where id = 123 /* select substring */; +select id, substring_index(name, '123456', -1) from user where id = 123 /* select substring_index */; + +select id, case when name = 'alice' then 'ALICE' when name = 'bob' then 'BOB' end as name from user where id = 1 /* select case */; +select id, case when name = 'alice' then 'ALICE' when name = 'bob' then 'BOB' else 'OTHER' end as name from user where id = 1 /* select case */; +select id, case when substr(name, 1, 5) = 'alice' then 'ALICE' when name = 'bob' then 'BOB' else 'OTHER' end as name from user where id = 1 /* select case */; + +select id, 'abc' as test from user where id = 1 union all select id, 'def' as test from user where id = 1 union all select id, 'ghi' as test from user where id = 1 /* union all */; \ No newline at end of file diff --git a/go/vt/vtexplain/vtexplain.go b/go/vt/vtexplain/vtexplain.go index 0023dc4acc1..1887fb241a0 100644 --- a/go/vt/vtexplain/vtexplain.go +++ b/go/vt/vtexplain/vtexplain.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vtexplain/vtexplain_flaky_test.go b/go/vt/vtexplain/vtexplain_flaky_test.go index f0948dc717f..05bd0c003f2 100644 --- a/go/vt/vtexplain/vtexplain_flaky_test.go +++ b/go/vt/vtexplain/vtexplain_flaky_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vtexplain/vtexplain_topo.go b/go/vt/vtexplain/vtexplain_topo.go index e4e0f374969..10c3b8f0ee9 100644 --- a/go/vt/vtexplain/vtexplain_topo.go +++ b/go/vt/vtexplain/vtexplain_topo.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vtexplain/vtexplain_vtgate.go b/go/vt/vtexplain/vtexplain_vtgate.go index ff26eca35e8..158baa5ddd3 100644 --- a/go/vt/vtexplain/vtexplain_vtgate.go +++ b/go/vt/vtexplain/vtexplain_vtgate.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vtexplain/vtexplain_vttablet.go b/go/vt/vtexplain/vtexplain_vttablet.go index 7c00864f2c8..de607b11deb 100644 --- a/go/vt/vtexplain/vtexplain_vttablet.go +++ b/go/vt/vtexplain/vtexplain_vttablet.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -19,6 +19,7 @@ package vtexplain import ( "encoding/json" "fmt" + "reflect" "strings" "sync" @@ -408,7 +409,7 @@ func initTabletEnvironment(ddls []*sqlparser.DDL, opts *Options) error { if ddl.OptLike != nil { likeTable := ddl.OptLike.LikeTable.Name.String() if _, ok := schemaQueries["describe "+likeTable]; !ok { - return fmt.Errorf("check your schema, table[%s] doesnt exist", likeTable) + return fmt.Errorf("check your schema, table[%s] doesn't exist", likeTable) } schemaQueries["show index from "+table] = schemaQueries["show index from "+likeTable] schemaQueries["describe "+table] = schemaQueries["describe "+likeTable] @@ -501,7 +502,15 @@ func (t *explainTablet) HandleQuery(c *mysql.Conn, query string, callback func(* return err } - selStmt := stmt.(*sqlparser.Select) + var selStmt *sqlparser.Select + switch stmt.(type) { + case *sqlparser.Select: + selStmt = stmt.(*sqlparser.Select) + case *sqlparser.Union: + selStmt = stmt.(*sqlparser.Union).Right.(*sqlparser.Select) + default: + return fmt.Errorf("vtexplain: unsupported statement type +%v", reflect.TypeOf(stmt)) + } if len(selStmt.From) != 1 { return fmt.Errorf("unsupported select with multiple from clauses") @@ -531,40 +540,7 @@ func (t *explainTablet) HandleQuery(c *mysql.Conn, query string, callback func(* for _, node := range selStmt.SelectExprs { switch node := node.(type) { case *sqlparser.AliasedExpr: - switch node := node.Expr.(type) { - case *sqlparser.ColName: - col := strings.ToLower(node.Name.String()) - colType := colTypeMap[col] - if colType == querypb.Type_NULL_TYPE { - return fmt.Errorf("invalid column %s", col) - } - colNames = append(colNames, col) - colTypes = append(colTypes, colType) - case *sqlparser.FuncExpr: - // As a shortcut, functions are integral types - colNames = append(colNames, sqlparser.String(node)) - colTypes = append(colTypes, querypb.Type_INT32) - case *sqlparser.SQLVal: - colNames = append(colNames, sqlparser.String(node)) - switch node.Type { - case sqlparser.IntVal: - fallthrough - case sqlparser.HexNum: - fallthrough - case sqlparser.HexVal: - fallthrough - case sqlparser.BitVal: - colTypes = append(colTypes, querypb.Type_INT32) - case sqlparser.StrVal: - colTypes = append(colTypes, querypb.Type_VARCHAR) - case sqlparser.FloatVal: - colTypes = append(colTypes, querypb.Type_FLOAT64) - default: - return fmt.Errorf("unsupported sql value %s", sqlparser.String(node)) - } - default: - return fmt.Errorf("unsupported select expression %s", sqlparser.String(node)) - } + colNames, colTypes = inferColTypeFromExpr(node.Expr, colTypeMap, colNames, colTypes) case *sqlparser.StarExpr: for col, colType := range colTypeMap { colNames = append(colNames, col) @@ -615,3 +591,46 @@ func (t *explainTablet) HandleQuery(c *mysql.Conn, query string, callback func(* return callback(result) } + +func inferColTypeFromExpr(node sqlparser.Expr, colTypeMap map[string]querypb.Type, colNames []string, colTypes []querypb.Type) ([]string, []querypb.Type) { + switch node := node.(type) { + case *sqlparser.ColName: + col := strings.ToLower(node.Name.String()) + colType := colTypeMap[col] + if colType == querypb.Type_NULL_TYPE { + log.Errorf("vtexplain: invalid column %s, typeMap +%v", col, colTypeMap) + } + colNames = append(colNames, col) + colTypes = append(colTypes, colType) + case *sqlparser.FuncExpr: + // As a shortcut, functions are integral types + colNames = append(colNames, sqlparser.String(node)) + colTypes = append(colTypes, querypb.Type_INT32) + case *sqlparser.SQLVal: + colNames = append(colNames, sqlparser.String(node)) + switch node.Type { + case sqlparser.IntVal: + fallthrough + case sqlparser.HexNum: + fallthrough + case sqlparser.HexVal: + fallthrough + case sqlparser.BitVal: + colTypes = append(colTypes, querypb.Type_INT32) + case sqlparser.StrVal: + colTypes = append(colTypes, querypb.Type_VARCHAR) + case sqlparser.FloatVal: + colTypes = append(colTypes, querypb.Type_FLOAT64) + default: + log.Errorf("vtexplain: unsupported sql value %s", sqlparser.String(node)) + } + case *sqlparser.ParenExpr: + colNames, colTypes = inferColTypeFromExpr(node.Expr, colTypeMap, colNames, colTypes) + case *sqlparser.CaseExpr: + colNames, colTypes = inferColTypeFromExpr(node.Whens[0].Val, colTypeMap, colNames, colTypes) + default: + log.Errorf("vtexplain: unsupported select expression type +%v node %s", reflect.TypeOf(node), sqlparser.String(node)) + } + + return colNames, colTypes +} diff --git a/go/vt/vtexplain/vtexplain_vttablet_test.go b/go/vt/vtexplain/vtexplain_vttablet_test.go index 06e1438cfbd..77b4f501946 100644 --- a/go/vt/vtexplain/vtexplain_vttablet_test.go +++ b/go/vt/vtexplain/vtexplain_vttablet_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -109,7 +109,7 @@ func TestErrParseSchema(t *testing.T) { testSchema := ` create table t1 like t2; ` - expected := "check your schema, table[t2] doesnt exist" + expected := "check your schema, table[t2] doesn't exist" ddl, err := parseSchema(testSchema, &Options{StrictDDL: true}) if err != nil { t.Fatalf("parseSchema: %v", err) diff --git a/go/vt/vtgate/api.go b/go/vt/vtgate/api.go index 51ea913e0b2..c2a6f36e747 100644 --- a/go/vt/vtgate/api.go +++ b/go/vt/vtgate/api.go @@ -1,5 +1,5 @@ /* -Copyright 2018 GitHub Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/vtgate/autocommit_test.go b/go/vt/vtgate/autocommit_test.go index 0464db6783e..0ec8fffd862 100644 --- a/go/vt/vtgate/autocommit_test.go +++ b/go/vt/vtgate/autocommit_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vtgate/bench_test.go b/go/vt/vtgate/bench_test.go index 3f6c848866f..afa3ad0cd25 100644 --- a/go/vt/vtgate/bench_test.go +++ b/go/vt/vtgate/bench_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vtgate/buffer/buffer.go b/go/vt/vtgate/buffer/buffer.go index 9967e1b701c..3cfe150930b 100644 --- a/go/vt/vtgate/buffer/buffer.go +++ b/go/vt/vtgate/buffer/buffer.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/vtgate/buffer/buffer_test.go b/go/vt/vtgate/buffer/buffer_test.go index 5951ebb658f..59a2d79ed95 100644 --- a/go/vt/vtgate/buffer/buffer_test.go +++ b/go/vt/vtgate/buffer/buffer_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/vtgate/buffer/flags.go b/go/vt/vtgate/buffer/flags.go index d93e49f16b8..c0a9560de08 100644 --- a/go/vt/vtgate/buffer/flags.go +++ b/go/vt/vtgate/buffer/flags.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/vtgate/buffer/flags_test.go b/go/vt/vtgate/buffer/flags_test.go index f0d6efff794..5a21d21b0c4 100644 --- a/go/vt/vtgate/buffer/flags_test.go +++ b/go/vt/vtgate/buffer/flags_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/vtgate/buffer/shard_buffer.go b/go/vt/vtgate/buffer/shard_buffer.go index 0916b225be9..07ed6447d3f 100644 --- a/go/vt/vtgate/buffer/shard_buffer.go +++ b/go/vt/vtgate/buffer/shard_buffer.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/vtgate/buffer/timeout_thread.go b/go/vt/vtgate/buffer/timeout_thread.go index 69b3974f111..33904e1d666 100644 --- a/go/vt/vtgate/buffer/timeout_thread.go +++ b/go/vt/vtgate/buffer/timeout_thread.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/vtgate/buffer/variables.go b/go/vt/vtgate/buffer/variables.go index 6adfbda7755..854e112084f 100644 --- a/go/vt/vtgate/buffer/variables.go +++ b/go/vt/vtgate/buffer/variables.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/vtgate/buffer/variables_test.go b/go/vt/vtgate/buffer/variables_test.go index 8890b208d6b..af99ad7e5ea 100644 --- a/go/vt/vtgate/buffer/variables_test.go +++ b/go/vt/vtgate/buffer/variables_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/vtgate/endtoend/lookup_test.go b/go/vt/vtgate/endtoend/lookup_test.go index 46d8e189aae..5adad26a1c4 100644 --- a/go/vt/vtgate/endtoend/lookup_test.go +++ b/go/vt/vtgate/endtoend/lookup_test.go @@ -220,7 +220,7 @@ func TestConsistentLookupMultiInsert(t *testing.T) { exec(t, conn, "delete from t1_id2_idx where id2=4") } -func TestHashLookupMultiInsertIgnore(t *testing.T) { +func TestLookupMultiInsertIgnore(t *testing.T) { ctx := context.Background() conn, err := mysql.Connect(ctx, &vtParams) if err != nil { @@ -260,6 +260,46 @@ func TestHashLookupMultiInsertIgnore(t *testing.T) { } } +func TestConsistentLookupMultiInsertIgnore(t *testing.T) { + ctx := context.Background() + conn, err := mysql.Connect(ctx, &vtParams) + if err != nil { + t.Fatal(err) + } + defer conn.Close() + // conn2 is for queries that target shards. + conn2, err := mysql.Connect(ctx, &vtParams) + if err != nil { + t.Fatal(err) + } + defer conn2.Close() + + // DB should start out clean + qr := exec(t, conn, "select count(*) from t1_id2_idx") + if got, want := fmt.Sprintf("%v", qr.Rows), "[[INT64(0)]]"; got != want { + t.Errorf("select:\n%v want\n%v", got, want) + } + qr = exec(t, conn, "select count(*) from t1") + if got, want := fmt.Sprintf("%v", qr.Rows), "[[INT64(0)]]"; got != want { + t.Errorf("select:\n%v want\n%v", got, want) + } + + // Try inserting a bunch of ids at once + exec(t, conn, "begin") + exec(t, conn, "insert ignore into t1(id1, id2) values(50,60), (30,40), (10,20)") + exec(t, conn, "commit") + + // Verify + qr = exec(t, conn, "select id1, id2 from t1 order by id1") + if got, want := fmt.Sprintf("%v", qr.Rows), "[[INT64(10) INT64(20)] [INT64(30) INT64(40)] [INT64(50) INT64(60)]]"; got != want { + t.Errorf("select:\n%v want\n%v", got, want) + } + qr = exec(t, conn, "select id2 from t1_id2_idx order by id2") + if got, want := fmt.Sprintf("%v", qr.Rows), "[[INT64(20)] [INT64(40)] [INT64(60)]]"; got != want { + t.Errorf("select:\n%v want\n%v", got, want) + } +} + func exec(t *testing.T, conn *mysql.Conn, query string) *sqltypes.Result { t.Helper() qr, err := conn.ExecuteFetch(query, 1000, true) diff --git a/go/vt/vtgate/engine/delete.go b/go/vt/vtgate/engine/delete.go index b2260be4a1f..9d59c69181e 100644 --- a/go/vt/vtgate/engine/delete.go +++ b/go/vt/vtgate/engine/delete.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Vitess Authors. +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. diff --git a/go/vt/vtgate/engine/delete_test.go b/go/vt/vtgate/engine/delete_test.go index 87d78a63f38..a61dcc702e7 100644 --- a/go/vt/vtgate/engine/delete_test.go +++ b/go/vt/vtgate/engine/delete_test.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Vitess Authors. +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. diff --git a/go/vt/vtgate/engine/fake_primitive_test.go b/go/vt/vtgate/engine/fake_primitive_test.go index 250d1206029..2d00e3e735a 100644 --- a/go/vt/vtgate/engine/fake_primitive_test.go +++ b/go/vt/vtgate/engine/fake_primitive_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vtgate/engine/fake_vcursor_test.go b/go/vt/vtgate/engine/fake_vcursor_test.go index ba7c5b30ada..28bd7b20d2c 100644 --- a/go/vt/vtgate/engine/fake_vcursor_test.go +++ b/go/vt/vtgate/engine/fake_vcursor_test.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Vitess Authors. +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. diff --git a/go/vt/vtgate/engine/insert.go b/go/vt/vtgate/engine/insert.go index 72dc3dedbc8..bf1de16defb 100644 --- a/go/vt/vtgate/engine/insert.go +++ b/go/vt/vtgate/engine/insert.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Vitess Authors. +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. @@ -390,34 +390,49 @@ func (ins *Insert) getInsertShardedRoute(vcursor VCursor, bindVars map[string]*q // The output from the following 'process' functions is a list of // keyspace ids. For regular inserts, a failure to find a route // results in an error. For 'ignore' type inserts, the keyspace - // id is returned as nil, which is used later to drop such rows. - keyspaceIDs, err := ins.processPrimary(vcursor, vindexRowsValues[0], ins.Table.ColumnVindexes[0], bindVars) + // id is returned as nil, which is used later to drop the corresponding rows. + colVindex := ins.Table.ColumnVindexes[0] + keyspaceIDs, err := ins.processPrimary(vcursor, vindexRowsValues[0], colVindex) if err != nil { return nil, nil, vterrors.Wrap(err, "getInsertShardedRoute") } + // Primary vindex can be owned. If so, go through the processOwned flow. + // If not owned, we don't do processUnowned because there's no need to verify + // the keyspace ids we just generated. + if colVindex.Owned { + if err := ins.processOwned(vcursor, vindexRowsValues[0], colVindex, keyspaceIDs); err != nil { + return nil, nil, vterrors.Wrap(err, "getInsertShardedRoute") + } + } - for vIdx := 1; vIdx < len(vindexRowsValues); vIdx++ { + for vIdx := 1; vIdx < len(ins.Table.ColumnVindexes); vIdx++ { colVindex := ins.Table.ColumnVindexes[vIdx] var err error if colVindex.Owned { - switch ins.Opcode { - case InsertSharded: - err = ins.processOwned(vcursor, vindexRowsValues[vIdx], colVindex, bindVars, keyspaceIDs) - case InsertShardedIgnore: - // For InsertShardedIgnore, the work is substantially different. - // So, we use a separate function. - err = ins.processOwnedIgnore(vcursor, vindexRowsValues[vIdx], colVindex, bindVars, keyspaceIDs) - default: - err = vterrors.Errorf(vtrpcpb.Code_INTERNAL, "BUG: unexpected opcode: %v", ins.Opcode) - } + err = ins.processOwned(vcursor, vindexRowsValues[vIdx], colVindex, keyspaceIDs) } else { - err = ins.processUnowned(vcursor, vindexRowsValues[vIdx], colVindex, bindVars, keyspaceIDs) + err = ins.processUnowned(vcursor, vindexRowsValues[vIdx], colVindex, keyspaceIDs) } if err != nil { return nil, nil, vterrors.Wrap(err, "getInsertShardedRoute") } } + // Build 3-d bindvars. Skip rows with nil keyspace ids in case + // we're executing an insert ignore. + for vIdx, colVindex := range ins.Table.ColumnVindexes { + for rowNum, rowColumnKeys := range vindexRowsValues[vIdx] { + if keyspaceIDs[rowNum] == nil { + // InsertShardedIgnore: skip the row. + continue + } + for colIdx, vindexKey := range rowColumnKeys { + col := colVindex.Columns[colIdx] + bindVars[insertVarName(col, rowNum)] = sqltypes.ValueBindVariable(vindexKey) + } + } + } + // We need to know the keyspace ids and the Mids associated with // each RSS. So we pass the ksid indexes in as ids, and get them back // as values. We also skip nil KeyspaceIds, no need to resolve them. @@ -465,14 +480,8 @@ func (ins *Insert) getInsertShardedRoute(vcursor VCursor, bindVars map[string]*q } // processPrimary maps the primary vindex values to the keyspace ids. -func (ins *Insert) processPrimary(vcursor VCursor, vindexKeys [][]sqltypes.Value, colVindex *vindexes.ColumnVindex, bv map[string]*querypb.BindVariable) ([][]byte, error) { - var flattenedVindexKeys []sqltypes.Value - // TODO: @rafael - this will change once vindex Primary keys also support multicolumns - for _, val := range vindexKeys { - flattenedVindexKeys = append(flattenedVindexKeys, val...) - } - - destinations, err := colVindex.Vindex.Map(vcursor, flattenedVindexKeys) +func (ins *Insert) processPrimary(vcursor VCursor, vindexColumnsKeys [][]sqltypes.Value, colVindex *vindexes.ColumnVindex) ([][]byte, error) { + destinations, err := vindexes.Map(colVindex.Vindex, vcursor, vindexColumnsKeys) if err != nil { return nil, err } @@ -486,56 +495,34 @@ func (ins *Insert) processPrimary(vcursor VCursor, vindexKeys [][]sqltypes.Value case key.DestinationNone: // No valid keyspace id, we may return an error. if ins.Opcode != InsertShardedIgnore { - return nil, fmt.Errorf("could not map %v to a keyspace id", flattenedVindexKeys[i]) + return nil, fmt.Errorf("could not map %v to a keyspace id", vindexColumnsKeys[i]) } default: - return nil, fmt.Errorf("could not map %v to a unique keyspace id: %v", flattenedVindexKeys[i], destination) + return nil, fmt.Errorf("could not map %v to a unique keyspace id: %v", vindexColumnsKeys[i], destination) } } - for rowNum, vindexKey := range flattenedVindexKeys { - if keyspaceIDs[rowNum] == nil { - // InsertShardedIgnore: skip the row. - continue - } - for _, col := range colVindex.Columns { - bv[insertVarName(col, rowNum)] = sqltypes.ValueBindVariable(vindexKey) - } - } return keyspaceIDs, nil } -// processOwned creates vindex entries for the values of an owned column for InsertSharded. -func (ins *Insert) processOwned(vcursor VCursor, vindexColumnsKeys [][]sqltypes.Value, colVindex *vindexes.ColumnVindex, bv map[string]*querypb.BindVariable, ksids [][]byte) error { - for rowNum, rowColumnKeys := range vindexColumnsKeys { - for colIdx, vindexKey := range rowColumnKeys { - col := colVindex.Columns[colIdx] - bv[insertVarName(col, rowNum)] = sqltypes.ValueBindVariable(vindexKey) - } +// processOwned creates vindex entries for the values of an owned column. +func (ins *Insert) processOwned(vcursor VCursor, vindexColumnsKeys [][]sqltypes.Value, colVindex *vindexes.ColumnVindex, ksids [][]byte) error { + if ins.Opcode == InsertSharded { + return colVindex.Vindex.(vindexes.Lookup).Create(vcursor, vindexColumnsKeys, ksids, false /* ignoreMode */) } - return colVindex.Vindex.(vindexes.Lookup).Create(vcursor, vindexColumnsKeys, ksids, false /* ignoreMode */) -} -// processOwnedIgnore creates vindex entries for the values of an owned column for InsertShardedIgnore. -func (ins *Insert) processOwnedIgnore(vcursor VCursor, vindexColumnsKeys [][]sqltypes.Value, colVindex *vindexes.ColumnVindex, bv map[string]*querypb.BindVariable, ksids [][]byte) error { + // InsertShardedIgnore var createIndexes []int var createKeys [][]sqltypes.Value var createKsids [][]byte for rowNum, rowColumnKeys := range vindexColumnsKeys { - var rowKeys []sqltypes.Value if ksids[rowNum] == nil { continue } createIndexes = append(createIndexes, rowNum) + createKeys = append(createKeys, rowColumnKeys) createKsids = append(createKsids, ksids[rowNum]) - - for colIdx, vindexKey := range rowColumnKeys { - rowKeys = append(rowKeys, vindexKey) - col := colVindex.Columns[colIdx] - bv[insertVarName(col, rowNum)] = sqltypes.ValueBindVariable(vindexKey) - } - createKeys = append(createKeys, rowKeys) } if createKeys == nil { return nil @@ -547,12 +534,7 @@ func (ins *Insert) processOwnedIgnore(vcursor VCursor, vindexColumnsKeys [][]sql } // After creation, verify that the keys map to the keyspace ids. If not, remove // those that don't map. - // If values were supplied, we validate against keyspace id. - var ids []sqltypes.Value - for _, vindexValues := range createKeys { - ids = append(ids, vindexValues[0]) - } - verified, err := colVindex.Vindex.Verify(vcursor, ids, createKsids) + verified, err := vindexes.Verify(colVindex.Vindex, vcursor, createKeys, createKsids) if err != nil { return err } @@ -565,26 +547,26 @@ func (ins *Insert) processOwnedIgnore(vcursor VCursor, vindexColumnsKeys [][]sql } // processUnowned either reverse maps or validates the values for an unowned column. -func (ins *Insert) processUnowned(vcursor VCursor, vindexColumnsKeys [][]sqltypes.Value, colVindex *vindexes.ColumnVindex, bv map[string]*querypb.BindVariable, ksids [][]byte) error { +func (ins *Insert) processUnowned(vcursor VCursor, vindexColumnsKeys [][]sqltypes.Value, colVindex *vindexes.ColumnVindex, ksids [][]byte) error { var reverseIndexes []int var reverseKsids [][]byte var verifyIndexes []int - var verifyKeys []sqltypes.Value + var verifyKeys [][]sqltypes.Value var verifyKsids [][]byte for rowNum, rowColumnKeys := range vindexColumnsKeys { // Right now, we only validate against the first column of a colvindex. - // TODO(sougou): address this when we add multicolumn Map support. - vindexKey := rowColumnKeys[0] if ksids[rowNum] == nil { continue } - if vindexKey.IsNull() { + // Perform reverse map only for non-multi-column vindexes. + _, isMulti := colVindex.Vindex.(vindexes.MultiColumn) + if rowColumnKeys[0].IsNull() && !isMulti { reverseIndexes = append(reverseIndexes, rowNum) reverseKsids = append(reverseKsids, ksids[rowNum]) } else { verifyIndexes = append(verifyIndexes, rowNum) - verifyKeys = append(verifyKeys, vindexKey) + verifyKeys = append(verifyKeys, rowColumnKeys) verifyKsids = append(verifyKsids, ksids[rowNum]) } } @@ -601,38 +583,26 @@ func (ins *Insert) processUnowned(vcursor VCursor, vindexColumnsKeys [][]sqltype return err } for i, reverseKey := range reverseKeys { - rowNum := reverseIndexes[i] - for colIdx, col := range colVindex.Columns { - if colIdx == 0 { - // Fill the first column with the reverse-mapped value. - bv[insertVarName(col, rowNum)] = sqltypes.ValueBindVariable(reverseKey) - } else { - // Fill other columns with supplied values. - bv[insertVarName(col, rowNum)] = sqltypes.ValueBindVariable(vindexColumnsKeys[rowNum][colIdx]) - } - } + // Fill the first column with the reverse-mapped value. + vindexColumnsKeys[reverseIndexes[i]][0] = reverseKey } } if verifyKsids != nil { // If values were supplied, we validate against keyspace id. - verified, err := colVindex.Vindex.Verify(vcursor, verifyKeys, verifyKsids) + verified, err := vindexes.Verify(colVindex.Vindex, vcursor, verifyKeys, verifyKsids) if err != nil { return err } for i, v := range verified { - rowNum := verifyIndexes[i] if !v { if ins.Opcode != InsertShardedIgnore { return fmt.Errorf("values %v for column %v does not map to keyspace ids", vindexColumnsKeys, colVindex.Columns) } // InsertShardedIgnore: skip the row. - ksids[rowNum] = nil + ksids[verifyIndexes[i]] = nil continue } - for colIdx, col := range colVindex.Columns { - bv[insertVarName(col, rowNum)] = sqltypes.ValueBindVariable(vindexColumnsKeys[rowNum][colIdx]) - } } } return nil diff --git a/go/vt/vtgate/engine/insert_test.go b/go/vt/vtgate/engine/insert_test.go index 1a329364817..d8373863f93 100644 --- a/go/vt/vtgate/engine/insert_test.go +++ b/go/vt/vtgate/engine/insert_test.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Vitess Authors. +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. @@ -20,6 +20,7 @@ import ( "errors" "testing" + "github.com/stretchr/testify/assert" "vitess.io/vitess/go/sqltypes" "vitess.io/vitess/go/vt/vtgate/vindexes" @@ -318,7 +319,7 @@ func TestInsertShardedFail(t *testing.T) { // The lookup will fail to map to a keyspace id. _, err = ins.Execute(vc, map[string]*querypb.BindVariable{}, false) - expectError(t, "Execute", err, "execInsertSharded: getInsertShardedRoute: could not map INT64(1) to a keyspace id") + expectError(t, "Execute", err, "execInsertSharded: getInsertShardedRoute: could not map [INT64(1)] to a keyspace id") } func TestInsertShardedGenerate(t *testing.T) { @@ -644,6 +645,92 @@ func TestInsertShardedOwnedWithNull(t *testing.T) { }) } +func TestInsertShardedGeo(t *testing.T) { + invschema := &vschemapb.SrvVSchema{ + Keyspaces: map[string]*vschemapb.Keyspace{ + "sharded": { + Sharded: true, + Vindexes: map[string]*vschemapb.Vindex{ + "geo": { + Type: "region_experimental", + Params: map[string]string{ + "region_bytes": "1", + "table": "lkp", + "from": "id,region", + "to": "toc", + }, + Owner: "t1", + }, + }, + Tables: map[string]*vschemapb.Table{ + "t1": { + ColumnVindexes: []*vschemapb.ColumnVindex{{ + Name: "geo", + Columns: []string{"id", "region"}, + }}, + }, + }, + }, + }, + } + vs, err := vindexes.BuildVSchema(invschema) + if err != nil { + t.Fatal(err) + } + ks := vs.Keyspaces["sharded"] + + ins := NewInsert( + InsertSharded, + ks.Keyspace, + []sqltypes.PlanValue{{ + // colVindex columns: id, region + Values: []sqltypes.PlanValue{{ + // rows for id + Values: []sqltypes.PlanValue{{ + Value: sqltypes.NewInt64(1), + }, { + Value: sqltypes.NewInt64(1), + }}, + }, { + // rows for region + Values: []sqltypes.PlanValue{{ + Value: sqltypes.NewInt64(1), + }, { + Value: sqltypes.NewInt64(255), + }}, + }}, + }}, + ks.Tables["t1"], + "prefix", + []string{" mid1", " mid2"}, + " suffix", + ) + + vc := &loggingVCursor{ + shards: []string{"-20", "20-"}, + shardForKsid: []string{"20-", "-20"}, + } + _, err = ins.Execute(vc, map[string]*querypb.BindVariable{}, false) + if err != nil { + t.Fatal(err) + } + vc.ExpectLog(t, []string{ + // ExecutePre proves that keyspace ids are generated, and that they are inserted into the lookup. + `ExecutePre insert into lkp(id, region, toc) values(:id0, :region0, :toc0), (:id1, :region1, :toc1) ` + + `id0: type:INT64 value:"1" id1: type:INT64 value:"1" ` + + `region0: type:INT64 value:"1" region1: type:INT64 value:"255" ` + + `toc0: type:VARBINARY value:"\001\026k@\264J\272K\326" toc1: type:VARBINARY value:"\377\026k@\264J\272K\326" true`, + `ResolveDestinations sharded [value:"0" value:"1" ] Destinations:DestinationKeyspaceID(01166b40b44aba4bd6),DestinationKeyspaceID(ff166b40b44aba4bd6)`, + `ExecuteMultiShard sharded.20-: prefix mid1 suffix /* vtgate:: keyspace_id:01166b40b44aba4bd6 */ ` + + `{_id0: type:INT64 value:"1" _id1: type:INT64 value:"1" ` + + `_region0: type:INT64 value:"1" _region1: type:INT64 value:"255" } ` + + `sharded.-20: prefix mid2 suffix /* vtgate:: keyspace_id:ff166b40b44aba4bd6 */ ` + + `{_id0: type:INT64 value:"1" _id1: type:INT64 value:"1" ` + + `_region0: type:INT64 value:"1" _region1: type:INT64 value:"255" } ` + + `true false`, + }) +} + func TestInsertShardedIgnoreOwned(t *testing.T) { invschema := &vschemapb.SrvVSchema{ Keyspaces: map[string]*vschemapb.Keyspace{ @@ -822,19 +909,117 @@ func TestInsertShardedIgnoreOwned(t *testing.T) { // Bind vars for rows 2 & 3 may be missing because they were not sent. `ExecuteMultiShard ` + `sharded.20-: prefix mid1 suffix /* vtgate:: keyspace_id:00 */ ` + - `{_c10: type:INT64 value:"5" _c12: type:INT64 value:"7" _c13: type:INT64 value:"8" ` + - `_c20: type:INT64 value:"9" _c22: type:INT64 value:"11" _c23: type:INT64 value:"12" ` + + `{_c10: type:INT64 value:"5" _c13: type:INT64 value:"8" ` + + `_c20: type:INT64 value:"9" _c23: type:INT64 value:"12" ` + `_c30: type:INT64 value:"13" _c33: type:INT64 value:"16" ` + - `_id0: type:INT64 value:"1" _id2: type:INT64 value:"3" _id3: type:INT64 value:"4" } ` + + `_id0: type:INT64 value:"1" _id3: type:INT64 value:"4" } ` + `sharded.-20: prefix mid4 suffix /* vtgate:: keyspace_id:00 */ ` + - `{_c10: type:INT64 value:"5" _c12: type:INT64 value:"7" _c13: type:INT64 value:"8" ` + - `_c20: type:INT64 value:"9" _c22: type:INT64 value:"11" _c23: type:INT64 value:"12" ` + + `{_c10: type:INT64 value:"5" _c13: type:INT64 value:"8" ` + + `_c20: type:INT64 value:"9" _c23: type:INT64 value:"12" ` + `_c30: type:INT64 value:"13" _c33: type:INT64 value:"16" ` + - `_id0: type:INT64 value:"1" _id2: type:INT64 value:"3" _id3: type:INT64 value:"4" } ` + + `_id0: type:INT64 value:"1" _id3: type:INT64 value:"4" } ` + `true false`, }) } +func TestInsertIgnoreGeo(t *testing.T) { + invschema := &vschemapb.SrvVSchema{ + Keyspaces: map[string]*vschemapb.Keyspace{ + "sharded": { + Sharded: true, + Vindexes: map[string]*vschemapb.Vindex{ + "geo": { + Type: "region_experimental", + Params: map[string]string{ + "region_bytes": "1", + "table": "lkp", + "from": "id,region", + "to": "toc", + }, + Owner: "t1", + }, + }, + Tables: map[string]*vschemapb.Table{ + "t1": { + ColumnVindexes: []*vschemapb.ColumnVindex{{ + Name: "geo", + Columns: []string{"id", "region"}, + }}, + }, + }, + }, + }, + } + vs, err := vindexes.BuildVSchema(invschema) + if err != nil { + t.Fatal(err) + } + ks := vs.Keyspaces["sharded"] + + ins := NewInsert( + InsertShardedIgnore, + ks.Keyspace, + []sqltypes.PlanValue{{ + // colVindex columns: id, region + Values: []sqltypes.PlanValue{{ + // rows for id + Values: []sqltypes.PlanValue{{ + Value: sqltypes.NewInt64(1), + }, { + Value: sqltypes.NewInt64(2), + }}, + }, { + // rows for region + Values: []sqltypes.PlanValue{{ + Value: sqltypes.NewInt64(1), + }, { + Value: sqltypes.NewInt64(2), + }}, + }}, + }}, + ks.Tables["t1"], + "prefix", + []string{" mid1", " mid2"}, + " suffix", + ) + + ksid0 := sqltypes.MakeTestResult( + sqltypes.MakeTestFields( + "to", + "varbinary", + ), + "\x00", + ) + noresult := &sqltypes.Result{} + vc := &loggingVCursor{ + shards: []string{"-20", "20-"}, + shardForKsid: []string{"20-", "-20"}, + results: []*sqltypes.Result{ + // insert lkp + noresult, + // fail one verification (row 2) + ksid0, + noresult, + }, + } + _, err = ins.Execute(vc, map[string]*querypb.BindVariable{}, false) + if err != nil { + t.Fatal(err) + } + vc.ExpectLog(t, []string{ + `ExecutePre insert ignore into lkp(id, region, toc) values(:id0, :region0, :toc0), (:id1, :region1, :toc1) ` + + `id0: type:INT64 value:"1" id1: type:INT64 value:"2" ` + + `region0: type:INT64 value:"1" region1: type:INT64 value:"2" ` + + `toc0: type:VARBINARY value:"\001\026k@\264J\272K\326" toc1: type:VARBINARY value:"\002\006\347\352\"\316\222p\217" true`, + // Row 2 will fail verification. This is what we're testing. The second row should not get inserted. + `ExecutePre select id from lkp where id = :id and toc = :toc id: type:INT64 value:"1" toc: type:VARBINARY value:"\001\026k@\264J\272K\326" false`, + `ExecutePre select id from lkp where id = :id and toc = :toc id: type:INT64 value:"2" toc: type:VARBINARY value:"\002\006\347\352\"\316\222p\217" false`, + `ResolveDestinations sharded [value:"0" ] Destinations:DestinationKeyspaceID(01166b40b44aba4bd6)`, + `ExecuteMultiShard sharded.20-: prefix mid1 suffix /* vtgate:: keyspace_id:01166b40b44aba4bd6 */ ` + + `{_id0: type:INT64 value:"1" _region0: type:INT64 value:"1" } true true`, + }) +} + func TestInsertShardedIgnoreOwnedWithNull(t *testing.T) { invschema := &vschemapb.SrvVSchema{ Keyspaces: map[string]*vschemapb.Keyspace{ @@ -907,7 +1092,6 @@ func TestInsertShardedIgnoreOwnedWithNull(t *testing.T) { ), "\x00", ) - //noresult := &sqltypes.Result{} vc := &loggingVCursor{ shards: []string{"-20", "20-"}, shardForKsid: []string{"-20", "20-"}, @@ -1086,6 +1270,91 @@ func TestInsertShardedUnownedVerify(t *testing.T) { }) } +func TestInsertUnownedGeo(t *testing.T) { + invschema := &vschemapb.SrvVSchema{ + Keyspaces: map[string]*vschemapb.Keyspace{ + "sharded": { + Sharded: true, + Vindexes: map[string]*vschemapb.Vindex{ + "primary": { + Type: "hash", + }, + "geo": { + Type: "region_experimental", + Params: map[string]string{ + "region_bytes": "1", + "table": "lkp", + "from": "other_id,region", + "to": "toc", + }, + }, + }, + Tables: map[string]*vschemapb.Table{ + "t1": { + ColumnVindexes: []*vschemapb.ColumnVindex{{ + Name: "primary", + Columns: []string{"id"}, + }, { + Name: "geo", + Columns: []string{"other_id", "region"}, + }}, + }, + }, + }, + }, + } + vs, err := vindexes.BuildVSchema(invschema) + if err != nil { + t.Fatal(err) + } + ks := vs.Keyspaces["sharded"] + + ins := NewInsert( + InsertSharded, + ks.Keyspace, + []sqltypes.PlanValue{{ + // colVindex columns: id + Values: []sqltypes.PlanValue{{ + // rows for id + Values: []sqltypes.PlanValue{{ + Value: sqltypes.NewInt64(1), + }}, + }}, + }, { + // colVindex columns: other_id, region + Values: []sqltypes.PlanValue{{ + // rows for other_id + Values: []sqltypes.PlanValue{{ + Value: sqltypes.NewInt64(2), + }}, + }, { + // rows for region + Values: []sqltypes.PlanValue{{ + Value: sqltypes.NewInt64(3), + }}, + }}, + }}, + ks.Tables["t1"], + "prefix", + []string{" mid1"}, + " suffix", + ) + + noresult := &sqltypes.Result{} + vc := &loggingVCursor{ + shards: []string{"-20", "20-"}, + results: []*sqltypes.Result{ + // fail verification + noresult, + }, + } + _, err = ins.Execute(vc, map[string]*querypb.BindVariable{}, false) + assert.EqualError(t, err, "execInsertSharded: getInsertShardedRoute: values [[INT64(2) INT64(3)]] for column [other_id region] does not map to keyspace ids") + vc.ExpectLog(t, []string{ + `ExecutePre select other_id from lkp where other_id = :other_id and toc = :toc other_id: type:INT64 value:"2" toc: type:VARBINARY value:"\026k@\264J\272K\326" false`, + }) +} + func TestInsertShardedIgnoreUnownedVerify(t *testing.T) { invschema := &vschemapb.SrvVSchema{ Keyspaces: map[string]*vschemapb.Keyspace{ @@ -1192,10 +1461,10 @@ func TestInsertShardedIgnoreUnownedVerify(t *testing.T) { `ExecuteMultiShard ` + `sharded.20-: prefix mid1 suffix /* vtgate:: keyspace_id:166b40b44aba4bd6 */ ` + `{_c30: type:INT64 value:"10" _c32: type:INT64 value:"12" ` + - `_id0: type:INT64 value:"1" _id1: type:INT64 value:"2" _id2: type:INT64 value:"3" } ` + + `_id0: type:INT64 value:"1" _id2: type:INT64 value:"3" } ` + `sharded.-20: prefix mid3 suffix /* vtgate:: keyspace_id:4eb190c9a2fa169c */ ` + `{_c30: type:INT64 value:"10" _c32: type:INT64 value:"12" ` + - `_id0: type:INT64 value:"1" _id1: type:INT64 value:"2" _id2: type:INT64 value:"3" } ` + + `_id0: type:INT64 value:"1" _id2: type:INT64 value:"3" } ` + `true false`, }) } diff --git a/go/vt/vtgate/engine/join.go b/go/vt/vtgate/engine/join.go index b62e54a5960..3cfb25e7a18 100644 --- a/go/vt/vtgate/engine/join.go +++ b/go/vt/vtgate/engine/join.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vtgate/engine/join_test.go b/go/vt/vtgate/engine/join_test.go index 26bacfe7c60..7ae4582f106 100644 --- a/go/vt/vtgate/engine/join_test.go +++ b/go/vt/vtgate/engine/join_test.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Vitess Authors. +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. diff --git a/go/vt/vtgate/engine/limit.go b/go/vt/vtgate/engine/limit.go index 0d0570cd9c5..65b6b39da3b 100644 --- a/go/vt/vtgate/engine/limit.go +++ b/go/vt/vtgate/engine/limit.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vtgate/engine/limit_test.go b/go/vt/vtgate/engine/limit_test.go index 890458fde53..146171e1b99 100644 --- a/go/vt/vtgate/engine/limit_test.go +++ b/go/vt/vtgate/engine/limit_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vtgate/engine/merge_sort.go b/go/vt/vtgate/engine/merge_sort.go index ee5c9cf1d67..e55f213b89d 100644 --- a/go/vt/vtgate/engine/merge_sort.go +++ b/go/vt/vtgate/engine/merge_sort.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -30,13 +30,13 @@ import ( "vitess.io/vitess/go/vt/srvtopo" ) -// mergeSort performs a merge-sort of rows returned by a streaming scatter query. +// MergeSort performs a merge-sort of rows returned by a streaming scatter query. // Each shard of the scatter query is treated as a stream. One row from each stream // is added to the merge-sorter heap. Every time a value is pulled out of the heap, // a new value is added to it from the stream that was the source of the value that // was pulled out. Since the input streams are sorted the same way that the heap is // sorted, this guarantees that the merged stream will also be sorted the same way. -func mergeSort(vcursor VCursor, query string, orderBy []OrderbyParams, rss []*srvtopo.ResolvedShard, bvs []map[string]*querypb.BindVariable, callback func(*sqltypes.Result) error) error { +func MergeSort(vcursor VCursor, query string, orderBy []OrderbyParams, rss []*srvtopo.ResolvedShard, bvs []map[string]*querypb.BindVariable, callback func(*sqltypes.Result) error) error { ctx, cancel := context.WithCancel(vcursor.Context()) defer cancel() @@ -123,7 +123,7 @@ func mergeSort(vcursor VCursor, query string, orderBy []OrderbyParams, rss []*sr // The fields channel is used by the stream to transmit the field info, which // is the first packet. Following this, the stream sends each row to the row // channel. At the end of the stream, fields and row are closed. If there -// was an error, err is set before the channels are closed. The mergeSort +// was an error, err is set before the channels are closed. The MergeSort // routine that pulls the rows out of each streamHandle can abort the stream // by calling canceling the context. type streamHandle struct { diff --git a/go/vt/vtgate/engine/merge_sort_test.go b/go/vt/vtgate/engine/merge_sort_test.go index 9ef8dfbfd9d..b1c74c903b2 100644 --- a/go/vt/vtgate/engine/merge_sort_test.go +++ b/go/vt/vtgate/engine/merge_sort_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -65,7 +65,7 @@ func TestMergeSortNormal(t *testing.T) { bvs := []map[string]*querypb.BindVariable{nil, nil, nil, nil} var results []*sqltypes.Result - err := mergeSort(vc, "", orderBy, rss, bvs, func(qr *sqltypes.Result) error { + err := MergeSort(vc, "", orderBy, rss, bvs, func(qr *sqltypes.Result) error { results = append(results, qr) return nil }) @@ -73,7 +73,7 @@ func TestMergeSortNormal(t *testing.T) { t.Error(err) } - // Results are retuned one row at a time. + // Results are returned one row at a time. wantResults := sqltypes.MakeTestStreamingResults(idColFields, "1|a", "---", @@ -92,7 +92,7 @@ func TestMergeSortNormal(t *testing.T) { "8|h", ) if !reflect.DeepEqual(results, wantResults) { - t.Errorf("mergeSort:\n%s, want\n%s", sqltypes.PrintResults(results), sqltypes.PrintResults(wantResults)) + t.Errorf("MergeSort:\n%s, want\n%s", sqltypes.PrintResults(results), sqltypes.PrintResults(wantResults)) } } @@ -135,7 +135,7 @@ func TestMergeSortDescending(t *testing.T) { bvs := []map[string]*querypb.BindVariable{nil, nil, nil, nil} var results []*sqltypes.Result - err := mergeSort(vc, "", orderBy, rss, bvs, func(qr *sqltypes.Result) error { + err := MergeSort(vc, "", orderBy, rss, bvs, func(qr *sqltypes.Result) error { results = append(results, qr) return nil }) @@ -143,7 +143,7 @@ func TestMergeSortDescending(t *testing.T) { t.Error(err) } - // Results are retuned one row at a time. + // Results are returned one row at a time. wantResults := sqltypes.MakeTestStreamingResults(idColFields, "8|h", "---", @@ -162,7 +162,7 @@ func TestMergeSortDescending(t *testing.T) { "1|a", ) if !reflect.DeepEqual(results, wantResults) { - t.Errorf("mergeSort:\n%s, want\n%s", sqltypes.PrintResults(results), sqltypes.PrintResults(wantResults)) + t.Errorf("MergeSort:\n%s, want\n%s", sqltypes.PrintResults(results), sqltypes.PrintResults(wantResults)) } } @@ -194,7 +194,7 @@ func TestMergeSortEmptyResults(t *testing.T) { bvs := []map[string]*querypb.BindVariable{nil, nil, nil, nil} var results []*sqltypes.Result - err := mergeSort(vc, "", orderBy, rss, bvs, func(qr *sqltypes.Result) error { + err := MergeSort(vc, "", orderBy, rss, bvs, func(qr *sqltypes.Result) error { results = append(results, qr) return nil }) @@ -202,7 +202,7 @@ func TestMergeSortEmptyResults(t *testing.T) { t.Error(err) } - // Results are retuned one row at a time. + // Results are returned one row at a time. wantResults := sqltypes.MakeTestStreamingResults(idColFields, "1|a", "---", @@ -213,7 +213,7 @@ func TestMergeSortEmptyResults(t *testing.T) { "7|g", ) if !reflect.DeepEqual(results, wantResults) { - t.Errorf("mergeSort:\n%s, want\n%s", sqltypes.PrintResults(results), sqltypes.PrintResults(wantResults)) + t.Errorf("MergeSort:\n%s, want\n%s", sqltypes.PrintResults(results), sqltypes.PrintResults(wantResults)) } } @@ -235,10 +235,10 @@ func TestMergeSortResultFailures(t *testing.T) { vc.shardResults["0"] = &shardResult{ sendErr: errors.New("early error"), } - err := mergeSort(vc, "", orderBy, rss, bvs, func(qr *sqltypes.Result) error { return nil }) + err := MergeSort(vc, "", orderBy, rss, bvs, func(qr *sqltypes.Result) error { return nil }) want := "early error" if err == nil || err.Error() != want { - t.Errorf("mergeSort(): %v, want %v", err, want) + t.Errorf("MergeSort(): %v, want %v", err, want) } // Test fail after fields. @@ -247,10 +247,10 @@ func TestMergeSortResultFailures(t *testing.T) { results: sqltypes.MakeTestStreamingResults(idFields), sendErr: errors.New("fail after fields"), } - err = mergeSort(vc, "", orderBy, rss, bvs, func(qr *sqltypes.Result) error { return nil }) + err = MergeSort(vc, "", orderBy, rss, bvs, func(qr *sqltypes.Result) error { return nil }) want = "fail after fields" if err == nil || err.Error() != want { - t.Errorf("mergeSort(): %v, want %v", err, want) + t.Errorf("MergeSort(): %v, want %v", err, want) } // Test fail after first row. @@ -258,10 +258,10 @@ func TestMergeSortResultFailures(t *testing.T) { results: sqltypes.MakeTestStreamingResults(idFields, "1"), sendErr: errors.New("fail after first row"), } - err = mergeSort(vc, "", orderBy, rss, bvs, func(qr *sqltypes.Result) error { return nil }) + err = MergeSort(vc, "", orderBy, rss, bvs, func(qr *sqltypes.Result) error { return nil }) want = "fail after first row" if err == nil || err.Error() != want { - t.Errorf("mergeSort(): %v, want %v", err, want) + t.Errorf("MergeSort(): %v, want %v", err, want) } } @@ -288,13 +288,13 @@ func TestMergeSortDataFailures(t *testing.T) { } bvs := []map[string]*querypb.BindVariable{nil, nil} - err := mergeSort(vc, "", orderBy, rss, bvs, func(qr *sqltypes.Result) error { return nil }) + err := MergeSort(vc, "", orderBy, rss, bvs, func(qr *sqltypes.Result) error { return nil }) want := `strconv.ParseInt: parsing "2.1": invalid syntax` if err == nil || err.Error() != want { - t.Errorf("mergeSort(): %v, want %v", err, want) + t.Errorf("MergeSort(): %v, want %v", err, want) } - // Create a new VCursor because the previous mergeSort will still + // Create a new VCursor because the previous MergeSort will still // have lingering goroutines that can cause data race. vc = &streamVCursor{ shardResults: map[string]*shardResult{ @@ -307,10 +307,10 @@ func TestMergeSortDataFailures(t *testing.T) { )}, }, } - err = mergeSort(vc, "", orderBy, rss, bvs, func(qr *sqltypes.Result) error { return nil }) + err = MergeSort(vc, "", orderBy, rss, bvs, func(qr *sqltypes.Result) error { return nil }) want = `strconv.ParseInt: parsing "1.1": invalid syntax` if err == nil || err.Error() != want { - t.Errorf("mergeSort(): %v, want %v", err, want) + t.Errorf("MergeSort(): %v, want %v", err, want) } } diff --git a/go/vt/vtgate/engine/ordered_aggregate.go b/go/vt/vtgate/engine/ordered_aggregate.go index 9e652727ec8..9abe441921a 100644 --- a/go/vt/vtgate/engine/ordered_aggregate.go +++ b/go/vt/vtgate/engine/ordered_aggregate.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -255,21 +255,21 @@ func (oa *OrderedAggregate) StreamExecute(vcursor VCursor, bindVars map[string]* return nil } -func (oa *OrderedAggregate) convertFields(fields []*querypb.Field) (newFields []*querypb.Field) { +func (oa *OrderedAggregate) convertFields(fields []*querypb.Field) []*querypb.Field { if !oa.HasDistinct { return fields } - newFields = append(newFields, fields...) + for _, aggr := range oa.Aggregates { if !aggr.isDistinct() { continue } - newFields[aggr.Col] = &querypb.Field{ + fields[aggr.Col] = &querypb.Field{ Name: aggr.Alias, Type: opcodeType[aggr.Opcode], } } - return newFields + return fields } func (oa *OrderedAggregate) convertRow(row []sqltypes.Value) (newRow []sqltypes.Value, curDistinct sqltypes.Value) { @@ -375,10 +375,17 @@ func (oa *OrderedAggregate) createEmptyRow() ([]sqltypes.Value, error) { func createEmptyValueFor(opcode AggregateOpcode) (sqltypes.Value, error) { switch opcode { - case AggregateCountDistinct: + case + AggregateCountDistinct, + AggregateCount: return countZero, nil - case AggregateSumDistinct: + case + AggregateSumDistinct, + AggregateSum, + AggregateMin, + AggregateMax: return sqltypes.NULL, nil + } return sqltypes.NULL, vterrors.Errorf(vtrpc.Code_INVALID_ARGUMENT, "unknown aggregation %v", opcode) } diff --git a/go/vt/vtgate/engine/ordered_aggregate_test.go b/go/vt/vtgate/engine/ordered_aggregate_test.go index d4201fad66c..46384625709 100644 --- a/go/vt/vtgate/engine/ordered_aggregate_test.go +++ b/go/vt/vtgate/engine/ordered_aggregate_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -666,42 +666,79 @@ func TestMerge(t *testing.T) { assert.Equal(want, merged) } -func TestNoInputAndNoGroupingKeys(t *testing.T) { - assert := assert.New(t) - fp := &fakePrimitive{ - results: []*sqltypes.Result{sqltypes.MakeTestResult( - sqltypes.MakeTestFields( - "col1|col2", - "int64|int64", - ), - // Empty input table - )}, +func TestNoInputAndNoGroupingKeys(outer *testing.T) { + testCases := []struct { + name string + opcode AggregateOpcode + expectedVal string + expectedTyp string + }{{ + "count(distinct col1)", + AggregateCountDistinct, + "0", + "int64", + }, { + "col1", + AggregateCount, + "0", + "int64", + }, { + "sum(distinct col1)", + AggregateSumDistinct, + "null", + "decimal", + }, { + "col1", + AggregateSum, + "null", + "int64", + }, { + "col1", + AggregateMax, + "null", + "int64", + }, { + "col1", + AggregateMin, + "null", + "int64", + }} + + for _, test := range testCases { + outer.Run(test.name, func(t *testing.T) { + assert := assert.New(t) + fp := &fakePrimitive{ + results: []*sqltypes.Result{sqltypes.MakeTestResult( + sqltypes.MakeTestFields( + "col1", + "int64", + ), + // Empty input table + )}, + } + + oa := &OrderedAggregate{ + HasDistinct: true, + Aggregates: []AggregateParams{{ + Opcode: test.opcode, + Col: 0, + Alias: test.name, + }}, + Keys: []int{}, + Input: fp, + } + + result, err := oa.Execute(nil, nil, false) + assert.NoError(err) + + wantResult := sqltypes.MakeTestResult( + sqltypes.MakeTestFields( + test.name, + test.expectedTyp, + ), + test.expectedVal, + ) + assert.Equal(wantResult, result) + }) } - - oa := &OrderedAggregate{ - HasDistinct: true, - Aggregates: []AggregateParams{{ - Opcode: AggregateCountDistinct, - Col: 0, - Alias: "count(distinct col2)", - }, { - Opcode: AggregateSumDistinct, - Col: 1, - Alias: "sum(distinct col2)", - }}, - Keys: []int{}, - Input: fp, - } - - result, err := oa.Execute(nil, nil, false) - assert.NoError(err) - - wantResult := sqltypes.MakeTestResult( - sqltypes.MakeTestFields( - "count(distinct col2)|sum(distinct col2)", - "int64|decimal", - ), - "0|null", - ) - assert.Equal(wantResult, result) } diff --git a/go/vt/vtgate/engine/primitive.go b/go/vt/vtgate/engine/primitive.go index c559d3bbaeb..cb9c9161187 100644 --- a/go/vt/vtgate/engine/primitive.go +++ b/go/vt/vtgate/engine/primitive.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vtgate/engine/pullout_subquery.go b/go/vt/vtgate/engine/pullout_subquery.go index da5d3535c96..b632d373593 100644 --- a/go/vt/vtgate/engine/pullout_subquery.go +++ b/go/vt/vtgate/engine/pullout_subquery.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Vitess Authors. +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. diff --git a/go/vt/vtgate/engine/pullout_subquery_test.go b/go/vt/vtgate/engine/pullout_subquery_test.go index 778101b93b9..273e667836a 100644 --- a/go/vt/vtgate/engine/pullout_subquery_test.go +++ b/go/vt/vtgate/engine/pullout_subquery_test.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Vitess Authors. +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. @@ -162,7 +162,7 @@ func TestPulloutSubqueryInNotinGood(t *testing.T) { sfp.ExpectLog(t, []string{`Execute false`}) ufp.ExpectLog(t, []string{`Execute has_values: type:INT64 value:"1" sq: type:TUPLE values: values: false`}) - // Test the NOT IN case just once eventhough it's common code. + // Test the NOT IN case just once even though it's common code. sfp.rewind() ufp.rewind() ps.Opcode = PulloutNotIn diff --git a/go/vt/vtgate/engine/route.go b/go/vt/vtgate/engine/route.go index 1ba1ce859d6..2ad95038820 100644 --- a/go/vt/vtgate/engine/route.go +++ b/go/vt/vtgate/engine/route.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -331,7 +331,7 @@ func (route *Route) StreamExecute(vcursor VCursor, bindVars map[string]*querypb. }) } - return mergeSort(vcursor, route.Query, route.OrderBy, rss, bvs, func(qr *sqltypes.Result) error { + return MergeSort(vcursor, route.Query, route.OrderBy, rss, bvs, func(qr *sqltypes.Result) error { return callback(qr.Truncate(route.TruncateColumnCount)) }) } diff --git a/go/vt/vtgate/engine/route_test.go b/go/vt/vtgate/engine/route_test.go index 63b779bf18b..5e34bb5f4ce 100644 --- a/go/vt/vtgate/engine/route_test.go +++ b/go/vt/vtgate/engine/route_test.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Vitess Authors. +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. diff --git a/go/vt/vtgate/engine/subquery.go b/go/vt/vtgate/engine/subquery.go index 48073dae8dc..b9e28885dd8 100644 --- a/go/vt/vtgate/engine/subquery.go +++ b/go/vt/vtgate/engine/subquery.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vtgate/engine/subquery_test.go b/go/vt/vtgate/engine/subquery_test.go index dda90dc4fa0..4c24ff9fbe5 100644 --- a/go/vt/vtgate/engine/subquery_test.go +++ b/go/vt/vtgate/engine/subquery_test.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Vitess Authors. +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. diff --git a/go/vt/vtgate/engine/update.go b/go/vt/vtgate/engine/update.go index d71a6729396..075a5a8c93c 100644 --- a/go/vt/vtgate/engine/update.go +++ b/go/vt/vtgate/engine/update.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Vitess Authors. +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. @@ -58,7 +58,7 @@ type Update struct { // ChangedVindexValues contains values for updated Vindexes during an update statement. ChangedVindexValues map[string][]sqltypes.PlanValue - // Table sepcifies the table for the update. + // Table specifies the table for the update. Table *vindexes.Table // OwnedVindexQuery is used for updating changes in lookup vindexes. diff --git a/go/vt/vtgate/engine/update_test.go b/go/vt/vtgate/engine/update_test.go index dd2576ccc9d..fcd51942ffa 100644 --- a/go/vt/vtgate/engine/update_test.go +++ b/go/vt/vtgate/engine/update_test.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Vitess Authors. +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. diff --git a/go/vt/vtgate/engine/vindex_func.go b/go/vt/vtgate/engine/vindex_func.go index 5f88d93062c..99c0a153195 100644 --- a/go/vt/vtgate/engine/vindex_func.go +++ b/go/vt/vtgate/engine/vindex_func.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vtgate/engine/vindex_func_test.go b/go/vt/vtgate/engine/vindex_func_test.go index ea5912502a0..917fc73f1b8 100644 --- a/go/vt/vtgate/engine/vindex_func_test.go +++ b/go/vt/vtgate/engine/vindex_func_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -30,10 +30,9 @@ import ( // uvindex is Unique. type uvindex struct{ matchid, matchkr bool } -func (*uvindex) String() string { return "uvindex" } -func (*uvindex) Cost() int { return 1 } -func (*uvindex) IsUnique() bool { return true } -func (*uvindex) IsFunctional() bool { return false } +func (*uvindex) String() string { return "uvindex" } +func (*uvindex) Cost() int { return 1 } +func (*uvindex) IsUnique() bool { return true } func (*uvindex) Verify(vindexes.VCursor, []sqltypes.Value, [][]byte) ([]bool, error) { panic("unimplemented") } @@ -60,10 +59,9 @@ func (v *uvindex) Map(cursor vindexes.VCursor, ids []sqltypes.Value) ([]key.Dest // nvindex is NonUnique. type nvindex struct{ matchid, matchkr bool } -func (*nvindex) String() string { return "nvindex" } -func (*nvindex) Cost() int { return 1 } -func (*nvindex) IsUnique() bool { return false } -func (*nvindex) IsFunctional() bool { return false } +func (*nvindex) String() string { return "nvindex" } +func (*nvindex) Cost() int { return 1 } +func (*nvindex) IsUnique() bool { return false } func (*nvindex) Verify(vindexes.VCursor, []sqltypes.Value, [][]byte) ([]bool, error) { panic("unimplemented") } diff --git a/go/vt/vtgate/executor.go b/go/vt/vtgate/executor.go index cf38a9dec55..51440ed5308 100644 --- a/go/vt/vtgate/executor.go +++ b/go/vt/vtgate/executor.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -167,7 +167,7 @@ func (e *Executor) execute(ctx context.Context, safeSession *SafeSession, sql st } stmtType := sqlparser.Preview(sql) - logStats.StmtType = sqlparser.StmtType(stmtType) + logStats.StmtType = stmtType.String() // Mysql warnings are scoped to the current session, but are // cleared when a "non-diagnostic statement" is executed: @@ -462,9 +462,13 @@ func (e *Executor) handleSet(ctx context.Context, safeSession *SafeSession, sql } for k, v := range vals { - if k.Scope == sqlparser.GlobalStr { + switch k.Scope { + case sqlparser.GlobalStr: return &sqltypes.Result{}, vterrors.New(vtrpcpb.Code_INVALID_ARGUMENT, "unsupported in set: global") + case sqlparser.VitessMetadataStr: + return e.handleSetVitessMetadata(ctx, safeSession, k, v) } + switch k.Key { case "autocommit": val, err := validateSetOnOff(v, k.Key) @@ -624,7 +628,7 @@ func (e *Executor) handleSet(ctx context.Context, safeSession *SafeSession, sql if !ok { return nil, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "unexpected value type for wait_timeout: %T", v) } - case "sql_mode", "net_write_timeout", "net_read_timeout", "lc_messages", "collation_connection": + case "sql_mode", "net_write_timeout", "net_read_timeout", "lc_messages", "collation_connection", "foreign_key_checks": log.Warningf("Ignored inapplicable SET %v = %v", k, v) warnings.Add("IgnoredSet", 1) case "charset", "names": @@ -645,6 +649,69 @@ func (e *Executor) handleSet(ctx context.Context, safeSession *SafeSession, sql return &sqltypes.Result{}, nil } +func (e *Executor) handleSetVitessMetadata(ctx context.Context, session *SafeSession, k sqlparser.SetKey, v interface{}) (*sqltypes.Result, error) { + //TODO(kalfonso): move to its own acl check and consolidate into an acl component that can handle multiple operations (vschema, metadata) + allowed := vschemaacl.Authorized(callerid.ImmediateCallerIDFromContext(ctx)) + if !allowed { + return nil, vterrors.Errorf(vtrpcpb.Code_PERMISSION_DENIED, "not authorized to perform vitess metadata operations") + + } + + val, ok := v.(string) + if !ok { + return nil, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "unexpected value type for charset: %T", v) + } + + ts, err := e.serv.GetTopoServer() + if err != nil { + return nil, err + } + + if val == "" { + err = ts.DeleteMetadata(ctx, k.Key) + } else { + err = ts.UpsertMetadata(ctx, k.Key, val) + } + + if err != nil { + return nil, err + } + + return &sqltypes.Result{RowsAffected: 1}, nil +} + +func (e *Executor) handleShowVitessMetadata(ctx context.Context, session *SafeSession, opt *sqlparser.ShowTablesOpt) (*sqltypes.Result, error) { + ts, err := e.serv.GetTopoServer() + if err != nil { + return nil, err + } + + var metadata map[string]string + if opt.Filter == nil { + metadata, err = ts.GetMetadata(ctx, "") + if err != nil { + return nil, err + } + } else { + metadata, err = ts.GetMetadata(ctx, opt.Filter.Like) + if err != nil { + return nil, err + } + } + + rows := make([][]sqltypes.Value, 0, len(metadata)) + for k, v := range metadata { + row := buildVarCharRow(k, v) + rows = append(rows, row) + } + + return &sqltypes.Result{ + Fields: buildVarCharFields("Key", "Value"), + Rows: rows, + RowsAffected: uint64(len(rows)), + }, nil +} + func validateSetOnOff(v interface{}, typ string) (int64, error) { var val int64 switch v := v.(type) { @@ -680,6 +747,10 @@ func (e *Executor) handleShow(ctx context.Context, safeSession *SafeSession, sql switch strings.ToLower(show.Type) { case sqlparser.KeywordString(sqlparser.COLLATION), sqlparser.KeywordString(sqlparser.VARIABLES): + if show.Scope == sqlparser.VitessMetadataStr { + return e.handleShowVitessMetadata(ctx, safeSession, show.ShowTablesOpt) + } + if destKeyspace == "" { keyspaces, err := e.resolver.resolver.GetAllKeyspaces(ctx) if err != nil { @@ -1055,7 +1126,7 @@ func (e *Executor) handleComment(sql string) (*sqltypes.Result, error) { // StreamExecute executes a streaming query. func (e *Executor) StreamExecute(ctx context.Context, method string, safeSession *SafeSession, sql string, bindVars map[string]*querypb.BindVariable, target querypb.Target, callback func(*sqltypes.Result) error) (err error) { logStats := NewLogStats(ctx, method, sql, bindVars) - logStats.StmtType = sqlparser.StmtType(sqlparser.Preview(sql)) + logStats.StmtType = sqlparser.Preview(sql).String() defer logStats.Send() if bindVars == nil { @@ -1066,7 +1137,7 @@ func (e *Executor) StreamExecute(ctx context.Context, method string, safeSession // check if this is a stream statement for messaging // TODO: support keyRange syntax - if logStats.StmtType == sqlparser.StmtType(sqlparser.StmtStream) { + if logStats.StmtType == sqlparser.StmtStream.String() { return e.handleMessageStream(ctx, safeSession, sql, target, callback, vcursor, logStats) } @@ -1345,20 +1416,15 @@ func (e *Executor) ServeHTTP(response http.ResponseWriter, request *http.Request return } if request.URL.Path == "/debug/query_plans" { - keys := e.plans.Keys() - response.Header().Set("Content-Type", "text/plain") - response.Write([]byte(fmt.Sprintf("Length: %d\n", len(keys)))) - for _, v := range keys { - response.Write([]byte(fmt.Sprintf("%#v\n", sqlparser.TruncateForUI(v)))) - if plan, ok := e.plans.Peek(v); ok { - if b, err := json.MarshalIndent(plan, "", " "); err != nil { - response.Write([]byte(err.Error())) - } else { - response.Write(b) - } - response.Write(([]byte)("\n\n")) - } + response.Header().Set("Content-Type", "application/json; charset=utf-8") + buf, err := json.MarshalIndent(e.plans.Items(), "", " ") + if err != nil { + response.Write([]byte(err.Error())) + return } + ebuf := bytes.NewBuffer(nil) + json.HTMLEscape(ebuf, buf) + response.Write(ebuf.Bytes()) } else if request.URL.Path == "/debug/vschema" { response.Header().Set("Content-Type", "application/json; charset=utf-8") b, err := json.MarshalIndent(e.VSchema(), "", " ") @@ -1384,7 +1450,6 @@ func (e *Executor) updateQueryCounts(planType, keyspace, tableName string, shard queriesRouted.Add(planType, shardQueries) queriesProcessedByTable.Add([]string{planType, keyspace, tableName}, 1) queriesRoutedByTable.Add([]string{planType, keyspace, tableName}, shardQueries) - return } // VSchemaStats returns the loaded vschema stats. @@ -1456,7 +1521,7 @@ func (e *Executor) prepare(ctx context.Context, safeSession *SafeSession, sql st } stmtType := sqlparser.Preview(sql) - logStats.StmtType = sqlparser.StmtType(stmtType) + logStats.StmtType = stmtType.String() // Mysql warnings are scoped to the current session, but are // cleared when a "non-diagnostic statement" is executed: @@ -1508,9 +1573,9 @@ func (e *Executor) handlePrepare(ctx context.Context, safeSession *SafeSession, if err != nil { logStats.Error = err errCount = 1 - } else { - logStats.RowsAffected = qr.RowsAffected + return nil, err } + logStats.RowsAffected = qr.RowsAffected plan.AddStats(1, time.Since(logStats.StartTime), uint64(logStats.ShardQueries), logStats.RowsAffected, errCount) diff --git a/go/vt/vtgate/executor_dml_test.go b/go/vt/vtgate/executor_dml_test.go index b6f266b7bc8..f492e8e3c08 100644 --- a/go/vt/vtgate/executor_dml_test.go +++ b/go/vt/vtgate/executor_dml_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -654,7 +654,7 @@ func TestInsertShardedKeyrange(t *testing.T) { // If a unique vindex returns a keyrange, we fail the insert _, err := executorExec(executor, "insert into keyrange_table(krcol_unique, krcol) values(1, 1)", nil) - want := "execInsertSharded: getInsertShardedRoute: could not map INT64(1) to a unique keyspace id: DestinationKeyRange(-10)" + want := "execInsertSharded: getInsertShardedRoute: could not map [INT64(1)] to a unique keyspace id: DestinationKeyRange(-10)" if err == nil || err.Error() != want { t.Errorf("executorExec error: %v, want %s", err, want) } @@ -786,13 +786,9 @@ func TestInsertShardedIgnore(t *testing.T) { Sql: "insert ignore into insert_ignore_test(pv, owned, verify) values (:_pv0, :_owned0, :_verify0),(:_pv4, :_owned4, :_verify4) /* vtgate:: keyspace_id:166b40b44aba4bd6,166b40b44aba4bd6 */", BindVariables: map[string]*querypb.BindVariable{ "_pv0": sqltypes.Int64BindVariable(1), - "_pv2": sqltypes.Int64BindVariable(3), - "_pv3": sqltypes.Int64BindVariable(4), "_pv4": sqltypes.Int64BindVariable(5), "_pv5": sqltypes.Int64BindVariable(6), "_owned0": sqltypes.Int64BindVariable(1), - "_owned2": sqltypes.Int64BindVariable(3), - "_owned3": sqltypes.Int64BindVariable(4), "_owned4": sqltypes.Int64BindVariable(5), "_owned5": sqltypes.Int64BindVariable(6), "_verify0": sqltypes.Int64BindVariable(1), @@ -807,13 +803,9 @@ func TestInsertShardedIgnore(t *testing.T) { Sql: "insert ignore into insert_ignore_test(pv, owned, verify) values (:_pv5, :_owned5, :_verify5) /* vtgate:: keyspace_id:4eb190c9a2fa169c */", BindVariables: map[string]*querypb.BindVariable{ "_pv0": sqltypes.Int64BindVariable(1), - "_pv2": sqltypes.Int64BindVariable(3), - "_pv3": sqltypes.Int64BindVariable(4), "_pv4": sqltypes.Int64BindVariable(5), "_pv5": sqltypes.Int64BindVariable(6), "_owned0": sqltypes.Int64BindVariable(1), - "_owned2": sqltypes.Int64BindVariable(3), - "_owned3": sqltypes.Int64BindVariable(4), "_owned4": sqltypes.Int64BindVariable(5), "_owned5": sqltypes.Int64BindVariable(6), "_verify0": sqltypes.Int64BindVariable(1), diff --git a/go/vt/vtgate/executor_framework_test.go b/go/vt/vtgate/executor_framework_test.go index 88073f32f69..1478144e5b5 100644 --- a/go/vt/vtgate/executor_framework_test.go +++ b/go/vt/vtgate/executor_framework_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -282,10 +282,9 @@ func (dp DestinationAnyShardPickerFirstShard) PickShard(shardCount int) int { type keyRangeLookuper struct { } -func (v *keyRangeLookuper) String() string { return "keyrange_lookuper" } -func (*keyRangeLookuper) Cost() int { return 0 } -func (*keyRangeLookuper) IsUnique() bool { return false } -func (*keyRangeLookuper) IsFunctional() bool { return false } +func (v *keyRangeLookuper) String() string { return "keyrange_lookuper" } +func (*keyRangeLookuper) Cost() int { return 0 } +func (*keyRangeLookuper) IsUnique() bool { return false } func (*keyRangeLookuper) Verify(vindexes.VCursor, []sqltypes.Value, [][]byte) ([]bool, error) { return []bool{}, nil } @@ -307,10 +306,9 @@ func newKeyRangeLookuper(name string, params map[string]string) (vindexes.Vindex type keyRangeLookuperUnique struct { } -func (v *keyRangeLookuperUnique) String() string { return "keyrange_lookuper" } -func (*keyRangeLookuperUnique) Cost() int { return 0 } -func (*keyRangeLookuperUnique) IsUnique() bool { return true } -func (*keyRangeLookuperUnique) IsFunctional() bool { return false } +func (v *keyRangeLookuperUnique) String() string { return "keyrange_lookuper" } +func (*keyRangeLookuperUnique) Cost() int { return 0 } +func (*keyRangeLookuperUnique) IsUnique() bool { return true } func (*keyRangeLookuperUnique) Verify(vindexes.VCursor, []sqltypes.Value, [][]byte) ([]bool, error) { return []bool{}, nil } diff --git a/go/vt/vtgate/executor_select_test.go b/go/vt/vtgate/executor_select_test.go index 8edf443fee9..8909d8ac530 100644 --- a/go/vt/vtgate/executor_select_test.go +++ b/go/vt/vtgate/executor_select_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vtgate/executor_stats.go b/go/vt/vtgate/executor_stats.go index 6fd6170ca5c..ffbc8412c1c 100644 --- a/go/vt/vtgate/executor_stats.go +++ b/go/vt/vtgate/executor_stats.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vtgate/executor_stream_test.go b/go/vt/vtgate/executor_stream_test.go index ea41aa88c50..65c2e773705 100644 --- a/go/vt/vtgate/executor_stream_test.go +++ b/go/vt/vtgate/executor_stream_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vtgate/executor_test.go b/go/vt/vtgate/executor_test.go index f66ed617d90..8767cd0928c 100644 --- a/go/vt/vtgate/executor_test.go +++ b/go/vt/vtgate/executor_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 @@ -29,6 +29,9 @@ import ( "testing" "time" + "vitess.io/vitess/go/vt/topo" + "vitess.io/vitess/go/vt/vterrors" + "context" "github.com/golang/protobuf/proto" @@ -44,6 +47,8 @@ import ( vschemapb "vitess.io/vitess/go/vt/proto/vschema" vtgatepb "vitess.io/vitess/go/vt/proto/vtgate" vtrpcpb "vitess.io/vitess/go/vt/proto/vtrpc" + + "github.com/stretchr/testify/assert" ) func TestExecutorResultsExceeded(t *testing.T) { @@ -432,6 +437,9 @@ func TestExecutorSet(t *testing.T) { }, { in: "set net_read_timeout = 600", out: &vtgatepb.Session{Autocommit: true}, + }, { + in: "set foreign_key_checks = 0", + out: &vtgatepb.Session{Autocommit: true}, }, { in: "set skip_query_plan_cache = 1", out: &vtgatepb.Session{Autocommit: true, Options: &querypb.ExecuteOptions{SkipQueryPlanCache: true}}, @@ -468,6 +476,98 @@ func TestExecutorSet(t *testing.T) { } } } + +func TestExecutorSetMetadata(t *testing.T) { + executor, _, _, _ := createExecutorEnv() + session := NewSafeSession(&vtgatepb.Session{TargetString: "@master", Autocommit: true}) + + set := "set @@vitess_metadata.app_keyspace_v1= '1'" + _, err := executor.Execute(context.Background(), "TestExecute", session, set, nil) + assert.Equalf(t, vtrpcpb.Code_PERMISSION_DENIED, vterrors.Code(err), "expected error %v, got error: %v", vtrpcpb.Code_PERMISSION_DENIED, err) + + *vschemaacl.AuthorizedDDLUsers = "%" + defer func() { + *vschemaacl.AuthorizedDDLUsers = "" + }() + + executor, _, _, _ = createExecutorEnv() + session = NewSafeSession(&vtgatepb.Session{TargetString: "@master", Autocommit: true}) + + set = "set @@vitess_metadata.app_keyspace_v1= '1'" + _, err = executor.Execute(context.Background(), "TestExecute", session, set, nil) + assert.NoError(t, err, "%s error: %v", set, err) + + show := `show vitess_metadata variables like 'app\\_keyspace\\_v_'` + result, err := executor.Execute(context.Background(), "TestExecute", session, show, nil) + assert.NoError(t, err) + + want := "1" + got := string(result.Rows[0][1].ToString()) + assert.Equalf(t, want, got, "want migrations %s, result %s", want, got) + + // Update metadata + set = "set @@vitess_metadata.app_keyspace_v2='2'" + _, err = executor.Execute(context.Background(), "TestExecute", session, set, nil) + assert.NoError(t, err, "%s error: %v", set, err) + + show = `show vitess_metadata variables like 'app\\_keyspace\\_v%'` + gotqr, err := executor.Execute(context.Background(), "TestExecute", session, show, nil) + assert.NoError(t, err) + + wantqr := &sqltypes.Result{ + Fields: buildVarCharFields("Key", "Value"), + Rows: [][]sqltypes.Value{ + buildVarCharRow("app_keyspace_v1", "1"), + buildVarCharRow("app_keyspace_v2", "2"), + }, + RowsAffected: 2, + } + + assert.Equal(t, wantqr.Fields, gotqr.Fields) + assert.ElementsMatch(t, wantqr.Rows, gotqr.Rows) + + show = "show vitess_metadata variables" + gotqr, err = executor.Execute(context.Background(), "TestExecute", session, show, nil) + if err != nil { + t.Error(err) + } + + assert.Equal(t, wantqr.Fields, gotqr.Fields) + assert.ElementsMatch(t, wantqr.Rows, gotqr.Rows) +} + +func TestExecutorDeleteMetadata(t *testing.T) { + *vschemaacl.AuthorizedDDLUsers = "%" + defer func() { + *vschemaacl.AuthorizedDDLUsers = "" + }() + + executor, _, _, _ := createExecutorEnv() + session := NewSafeSession(&vtgatepb.Session{TargetString: "@master", Autocommit: true}) + + set := "set @@vitess_metadata.app_v1= '1'" + _, err := executor.Execute(context.Background(), "TestExecute", session, set, nil) + assert.NoError(t, err, "%s error: %v", set, err) + + show := `show vitess_metadata variables like 'app\\_%'` + result, _ := executor.Execute(context.Background(), "TestExecute", session, show, nil) + assert.Len(t, result.Rows, 1) + + // Fails if deleting key that doesn't exist + delete := "set @@vitess_metadata.doesn't_exist=''" + _, err = executor.Execute(context.Background(), "TestExecute", session, delete, nil) + assert.True(t, topo.IsErrType(err, topo.NoNode)) + + // Delete existing key, show should fail given the node doesn't exist + delete = "set @@vitess_metadata.app_v1=''" + _, err = executor.Execute(context.Background(), "TestExecute", session, delete, nil) + assert.NoError(t, err) + + show = `show vitess_metadata variables like 'app\\_%'` + result, err = executor.Execute(context.Background(), "TestExecute", session, show, nil) + assert.True(t, topo.IsErrType(err, topo.NoNode)) +} + func TestExecutorAutocommit(t *testing.T) { executor, _, _, sbclookup := createExecutorEnv() session := NewSafeSession(&vtgatepb.Session{TargetString: "@master"}) @@ -1312,6 +1412,35 @@ func waitForColVindexes(t *testing.T, ks, table string, names []string, executor return nil } +func TestExecutorAlterVSchemaKeyspace(t *testing.T) { + *vschemaacl.AuthorizedDDLUsers = "%" + defer func() { + *vschemaacl.AuthorizedDDLUsers = "" + }() + executor, _, _, _ := createExecutorEnv() + session := NewSafeSession(&vtgatepb.Session{TargetString: "@master", Autocommit: true}) + + vschemaUpdates := make(chan *vschemapb.SrvVSchema, 2) + executor.serv.WatchSrvVSchema(context.Background(), "aa", func(vschema *vschemapb.SrvVSchema, err error) { + vschemaUpdates <- vschema + }) + + vschema := <-vschemaUpdates + _, ok := vschema.Keyspaces["TestExecutor"].Vindexes["test_vindex"] + if ok { + t.Fatalf("test_vindex should not exist in original vschema") + } + + stmt := "alter vschema create vindex TestExecutor.test_vindex using hash" + _, err := executor.Execute(context.Background(), "TestExecute", session, stmt, nil) + if err != nil { + t.Error(err) + } + + _, vindex := waitForVindex(t, "TestExecutor", "test_vindex", vschemaUpdates, executor) + assert.Equal(t, vindex.Type, "hash") +} + func TestExecutorCreateVindexDDL(t *testing.T) { *vschemaacl.AuthorizedDDLUsers = "%" defer func() { diff --git a/go/vt/vtgate/fakerpcvtgateconn/conn.go b/go/vt/vtgate/fakerpcvtgateconn/conn.go index 53711971092..2edfebef6f1 100644 --- a/go/vt/vtgate/fakerpcvtgateconn/conn.go +++ b/go/vt/vtgate/fakerpcvtgateconn/conn.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vtgate/gateway/discoverygateway.go b/go/vt/vtgate/gateway/discoverygateway.go index aff4a4bac80..e793096dcf8 100644 --- a/go/vt/vtgate/gateway/discoverygateway.go +++ b/go/vt/vtgate/gateway/discoverygateway.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vtgate/gateway/discoverygateway_test.go b/go/vt/vtgate/gateway/discoverygateway_test.go index 85138ab15b8..d47c3400ff9 100644 --- a/go/vt/vtgate/gateway/discoverygateway_test.go +++ b/go/vt/vtgate/gateway/discoverygateway_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 @@ -170,7 +170,7 @@ func TestShuffleTablets(t *testing.T) { sameCellTablets := []discovery.TabletStats{ts1, ts2} diffCellTablets := []discovery.TabletStats{ts3, ts4} mixedTablets := []discovery.TabletStats{ts1, ts2, ts3, ts4} - // repeat shuffling 10 times and everytime the same cell tablets should be in the front + // repeat shuffling 10 times and every time the same cell tablets should be in the front for i := 0; i < 10; i++ { shuffleTablets("cell1", sameCellTablets) if (len(sameCellTablets) != 2) || diff --git a/go/vt/vtgate/gateway/gateway.go b/go/vt/vtgate/gateway/gateway.go index 7b458332fac..5f5bb6a6b14 100644 --- a/go/vt/vtgate/gateway/gateway.go +++ b/go/vt/vtgate/gateway/gateway.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -106,7 +106,7 @@ func GetCreator() Creator { // Note it has the same name as the Gateway's interface method, as it // just calls it. func WaitForTablets(gw Gateway, tabletTypesToWait []topodatapb.TabletType) error { - log.Infof("Gateway waiting for serving tablets...") + log.Infof("Gateway waiting for serving tablets of types %v ...", tabletTypesToWait) ctx, cancel := context.WithTimeout(context.Background(), *initialTabletTimeout) defer cancel() @@ -119,7 +119,7 @@ func WaitForTablets(gw Gateway, tabletTypesToWait []topodatapb.TabletType) error // In this scenario, we were able to reach the // topology service, but some tablets may not be // ready. We just warn and keep going. - log.Warningf("Timeout waiting for all keyspaces / shards to have healthy tablets, may be in degraded mode") + log.Warningf("Timeout waiting for all keyspaces / shards to have healthy tablets of types %v, may be in degraded mode", tabletTypesToWait) err = nil default: // Nothing to do here, the caller will log.Fatalf. diff --git a/go/vt/vtgate/gateway/shard_error.go b/go/vt/vtgate/gateway/shard_error.go index 27fb0bc752e..15057f4c955 100644 --- a/go/vt/vtgate/gateway/shard_error.go +++ b/go/vt/vtgate/gateway/shard_error.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vtgate/gateway/status.go b/go/vt/vtgate/gateway/status.go index 8bd4ab736d9..c6d6eb30752 100644 --- a/go/vt/vtgate/gateway/status.go +++ b/go/vt/vtgate/gateway/status.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vtgate/gateway/status_test.go b/go/vt/vtgate/gateway/status_test.go index 257c3996d1f..ce61c2893f4 100644 --- a/go/vt/vtgate/gateway/status_test.go +++ b/go/vt/vtgate/gateway/status_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vtgate/gatewaytest/grpc_discovery_test.go b/go/vt/vtgate/gatewaytest/grpc_discovery_test.go index c3259b9e63d..c52b105f6e7 100644 --- a/go/vt/vtgate/gatewaytest/grpc_discovery_test.go +++ b/go/vt/vtgate/gatewaytest/grpc_discovery_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/vtgate/gatewaytest/suite.go b/go/vt/vtgate/gatewaytest/suite.go index 138de99d295..0f00fd53832 100644 --- a/go/vt/vtgate/gatewaytest/suite.go +++ b/go/vt/vtgate/gatewaytest/suite.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/vtgate/grpcvtgateconn/conn.go b/go/vt/vtgate/grpcvtgateconn/conn.go index f5d884f7826..27a238d88c7 100644 --- a/go/vt/vtgate/grpcvtgateconn/conn.go +++ b/go/vt/vtgate/grpcvtgateconn/conn.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vtgate/grpcvtgateconn/conn_rpc_test.go b/go/vt/vtgate/grpcvtgateconn/conn_rpc_test.go index c115bf0484d..3a774554f5a 100644 --- a/go/vt/vtgate/grpcvtgateconn/conn_rpc_test.go +++ b/go/vt/vtgate/grpcvtgateconn/conn_rpc_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vtgate/grpcvtgateservice/no_test.go b/go/vt/vtgate/grpcvtgateservice/no_test.go index e244e2e8abd..6500ae8ae93 100644 --- a/go/vt/vtgate/grpcvtgateservice/no_test.go +++ b/go/vt/vtgate/grpcvtgateservice/no_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/vtgate/grpcvtgateservice/server.go b/go/vt/vtgate/grpcvtgateservice/server.go index fd283bbefaa..aa568905d3d 100644 --- a/go/vt/vtgate/grpcvtgateservice/server.go +++ b/go/vt/vtgate/grpcvtgateservice/server.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vtgate/logstats.go b/go/vt/vtgate/logstats.go index 02b4d46b5b0..2e9f8a3588b 100644 --- a/go/vt/vtgate/logstats.go +++ b/go/vt/vtgate/logstats.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vtgate/logstats_test.go b/go/vt/vtgate/logstats_test.go index 4720d5c7cfd..b81f73ace8c 100644 --- a/go/vt/vtgate/logstats_test.go +++ b/go/vt/vtgate/logstats_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vtgate/mysql_protocol_test.go b/go/vt/vtgate/mysql_protocol_test.go index b8f420c888b..4cccfeaebfb 100644 --- a/go/vt/vtgate/mysql_protocol_test.go +++ b/go/vt/vtgate/mysql_protocol_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -22,6 +22,9 @@ import ( "strconv" "testing" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "golang.org/x/net/context" "github.com/golang/protobuf/proto" @@ -92,6 +95,51 @@ func TestMySQLProtocolStreamExecute(t *testing.T) { } } +func TestMySQLProtocolExecuteUseStatement(t *testing.T) { + createSandbox(KsTestUnsharded) + hcVTGateTest.Reset() + hcVTGateTest.AddTestTablet("aa", "1.1.1.1", 1001, KsTestUnsharded, "0", topodatapb.TabletType_MASTER, true, 1, nil) + + c, err := mysqlConnect(&mysql.ConnParams{DbName: "@master"}) + if err != nil { + t.Fatal(err) + } + defer c.Close() + + qr, err := c.ExecuteFetch("select id from t1", 10, true /* wantfields */) + require.NoError(t, err) + require.Equal(t, sandboxconn.SingleRowResult, qr) + + qr, err = c.ExecuteFetch("show vitess_target", 1, false) + require.NoError(t, err) + assert.Equal(t, "VARCHAR(\"@master\")", qr.Rows[0][0].String()) + + _, err = c.ExecuteFetch("use TestUnsharded", 0, false) + require.NoError(t, err) + + qr, err = c.ExecuteFetch("select id from t1", 10, true /* wantfields */) + require.NoError(t, err) + assert.Equal(t, sandboxconn.SingleRowResult, qr) + + // No such keyspace this will fail + _, err = c.ExecuteFetch("use InvalidKeyspace", 0, false) + require.Error(t, err) + assert.Contains(t, err.Error(), "invalid keyspace provided: InvalidKeyspace") + + // That doesn't reset the vitess_target + qr, err = c.ExecuteFetch("show vitess_target", 1, false) + require.NoError(t, err) + assert.Equal(t, "VARCHAR(\"TestUnsharded\")", qr.Rows[0][0].String()) + + _, err = c.ExecuteFetch("use @replica", 0, false) + require.NoError(t, err) + + // No replica tablets, this should also fail + qr, err = c.ExecuteFetch("select id from t1", 10, true /* wantfields */) + require.Error(t, err) + assert.Contains(t, err.Error(), "no valid tablet") +} + func TestMysqlProtocolInvalidDB(t *testing.T) { c, err := mysqlConnect(&mysql.ConnParams{DbName: "invalidDB"}) if err != nil { diff --git a/go/vt/vtgate/planbuilder/builder.go b/go/vt/vtgate/planbuilder/builder.go index 1a5aeaa6bf5..23167793e98 100644 --- a/go/vt/vtgate/planbuilder/builder.go +++ b/go/vt/vtgate/planbuilder/builder.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vtgate/planbuilder/delete.go b/go/vt/vtgate/planbuilder/delete.go index 6fd807c0dc7..8dfa35baf18 100644 --- a/go/vt/vtgate/planbuilder/delete.go +++ b/go/vt/vtgate/planbuilder/delete.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vtgate/planbuilder/doc.go b/go/vt/vtgate/planbuilder/doc.go index 348154aca59..44a7edab0d7 100644 --- a/go/vt/vtgate/planbuilder/doc.go +++ b/go/vt/vtgate/planbuilder/doc.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -68,7 +68,7 @@ to eventually validate such references. Every 'builder' primitive must satisfy the builder interface. This allows the planbuilder to outsource -primitive-specific handling into those implementaions. +primitive-specific handling into those implementations. Variable naming: The AST, planbuilder and engine are three different worlds that use overloaded diff --git a/go/vt/vtgate/planbuilder/expr.go b/go/vt/vtgate/planbuilder/expr.go index 0447fa9dde8..2e4bd4baeaa 100644 --- a/go/vt/vtgate/planbuilder/expr.go +++ b/go/vt/vtgate/planbuilder/expr.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vtgate/planbuilder/expr_test.go b/go/vt/vtgate/planbuilder/expr_test.go index 9b845b7ada4..9aca7b9596f 100644 --- a/go/vt/vtgate/planbuilder/expr_test.go +++ b/go/vt/vtgate/planbuilder/expr_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vtgate/planbuilder/from.go b/go/vt/vtgate/planbuilder/from.go index 203146683ca..7f919ca21c0 100644 --- a/go/vt/vtgate/planbuilder/from.go +++ b/go/vt/vtgate/planbuilder/from.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -242,7 +242,7 @@ func (pb *primitiveBuilder) buildTablePrimitive(tableExpr *sqlparser.AliasedTabl default: // Pinned tables have their keyspace ids already assigned. // Use the Binary vindex, which is the identity function - // for keyspace id. Currently only dual tables are pinned. + // for keyspace id. eroute = engine.NewSimpleRoute(engine.SelectEqualUnique, vst.Keyspace) eroute.Vindex, _ = vindexes.NewBinary("binary", nil) eroute.Values = []sqltypes.PlanValue{{Value: sqltypes.MakeTrusted(sqltypes.VarBinary, vst.Pinned)}} diff --git a/go/vt/vtgate/planbuilder/insert.go b/go/vt/vtgate/planbuilder/insert.go index 569ebaea699..bcbd9b86515 100644 --- a/go/vt/vtgate/planbuilder/insert.go +++ b/go/vt/vtgate/planbuilder/insert.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -211,13 +211,23 @@ func generateInsertShardedQuery(node *sqlparser.Insert, eins *engine.Insert, val // modifyForAutoinc modfies the AST and the plan to generate // necessary autoinc values. It must be called only if eins.Table.AutoIncrement -// is set. +// is set. Bind variable names are generated using baseName. func modifyForAutoinc(ins *sqlparser.Insert, eins *engine.Insert) error { - pos := findOrAddColumn(ins, eins.Table.AutoIncrement.Column) - autoIncValues, err := swapBindVariables(ins.Rows.(sqlparser.Values), pos, ":"+engine.SeqVarName) - if err != nil { - return err + colNum := findOrAddColumn(ins, eins.Table.AutoIncrement.Column) + autoIncValues := sqltypes.PlanValue{} + for rowNum, row := range ins.Rows.(sqlparser.Values) { + // Support the DEFAULT keyword by treating it as null + if _, ok := row[colNum].(*sqlparser.Default); ok { + row[colNum] = &sqlparser.NullVal{} + } + pv, err := sqlparser.NewPlanValue(row[colNum]) + if err != nil { + return fmt.Errorf("could not compute value for vindex or auto-inc column: %v", err) + } + autoIncValues.Values = append(autoIncValues.Values, pv) + row[colNum] = sqlparser.NewValArg([]byte(":" + engine.SeqVarName + strconv.Itoa(rowNum))) } + eins.Generate = &engine.Generate{ Keyspace: eins.Table.AutoIncrement.Sequence.Keyspace, Query: fmt.Sprintf("select next :n values from %s", sqlparser.String(eins.Table.AutoIncrement.Sequence.Name)), @@ -226,22 +236,6 @@ func modifyForAutoinc(ins *sqlparser.Insert, eins *engine.Insert) error { return nil } -// swapBindVariables swaps in bind variable names at the specified -// column position in the AST values and returns the converted values back. -// Bind variable names are generated using baseName. -func swapBindVariables(rows sqlparser.Values, colNum int, baseName string) (sqltypes.PlanValue, error) { - pv := sqltypes.PlanValue{} - for rowNum, row := range rows { - innerpv, err := sqlparser.NewPlanValue(row[colNum]) - if err != nil { - return pv, fmt.Errorf("could not compute value for vindex or auto-inc column: %v", err) - } - pv.Values = append(pv.Values, innerpv) - row[colNum] = sqlparser.NewValArg([]byte(baseName + strconv.Itoa(rowNum))) - } - return pv, nil -} - // findOrAddColumn finds the position of a column in the insert. If it's // absent it appends it to the with NULL values and returns that position. func findOrAddColumn(ins *sqlparser.Insert, col sqlparser.ColIdent) int { diff --git a/go/vt/vtgate/planbuilder/join.go b/go/vt/vtgate/planbuilder/join.go index 86a99d9357a..6ec4abffce4 100644 --- a/go/vt/vtgate/planbuilder/join.go +++ b/go/vt/vtgate/planbuilder/join.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vtgate/planbuilder/jointab.go b/go/vt/vtgate/planbuilder/jointab.go index fea57a44add..107df0e07b0 100644 --- a/go/vt/vtgate/planbuilder/jointab.go +++ b/go/vt/vtgate/planbuilder/jointab.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vtgate/planbuilder/jointab_test.go b/go/vt/vtgate/planbuilder/jointab_test.go index a255de5bd35..9a601097093 100644 --- a/go/vt/vtgate/planbuilder/jointab_test.go +++ b/go/vt/vtgate/planbuilder/jointab_test.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Vitess Authors. +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. diff --git a/go/vt/vtgate/planbuilder/limit.go b/go/vt/vtgate/planbuilder/limit.go index 5dbc9a967a5..c6830400a05 100644 --- a/go/vt/vtgate/planbuilder/limit.go +++ b/go/vt/vtgate/planbuilder/limit.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vtgate/planbuilder/ordered_aggregate.go b/go/vt/vtgate/planbuilder/ordered_aggregate.go index b345298addb..d7c76dd0f5a 100644 --- a/go/vt/vtgate/planbuilder/ordered_aggregate.go +++ b/go/vt/vtgate/planbuilder/ordered_aggregate.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vtgate/planbuilder/plan_test.go b/go/vt/vtgate/planbuilder/plan_test.go index 6067ad082d9..9e0e72ed305 100644 --- a/go/vt/vtgate/planbuilder/plan_test.go +++ b/go/vt/vtgate/planbuilder/plan_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -39,10 +39,9 @@ import ( // hashIndex is a functional, unique Vindex. type hashIndex struct{ name string } -func (v *hashIndex) String() string { return v.name } -func (*hashIndex) Cost() int { return 1 } -func (*hashIndex) IsUnique() bool { return true } -func (*hashIndex) IsFunctional() bool { return true } +func (v *hashIndex) String() string { return v.name } +func (*hashIndex) Cost() int { return 1 } +func (*hashIndex) IsUnique() bool { return true } func (*hashIndex) Verify(vindexes.VCursor, []sqltypes.Value, [][]byte) ([]bool, error) { return []bool{}, nil } @@ -57,10 +56,9 @@ func newHashIndex(name string, _ map[string]string) (vindexes.Vindex, error) { // lookupIndex is a unique Vindex, and satisfies Lookup. type lookupIndex struct{ name string } -func (v *lookupIndex) String() string { return v.name } -func (*lookupIndex) Cost() int { return 2 } -func (*lookupIndex) IsUnique() bool { return true } -func (*lookupIndex) IsFunctional() bool { return false } +func (v *lookupIndex) String() string { return v.name } +func (*lookupIndex) Cost() int { return 2 } +func (*lookupIndex) IsUnique() bool { return true } func (*lookupIndex) Verify(vindexes.VCursor, []sqltypes.Value, [][]byte) ([]bool, error) { return []bool{}, nil } @@ -82,10 +80,9 @@ var _ vindexes.Lookup = (*lookupIndex)(nil) // multiIndex satisfies Lookup, NonUnique. type multiIndex struct{ name string } -func (v *multiIndex) String() string { return v.name } -func (*multiIndex) Cost() int { return 3 } -func (*multiIndex) IsUnique() bool { return false } -func (*multiIndex) IsFunctional() bool { return false } +func (v *multiIndex) String() string { return v.name } +func (*multiIndex) Cost() int { return 3 } +func (*multiIndex) IsUnique() bool { return false } func (*multiIndex) Verify(vindexes.VCursor, []sqltypes.Value, [][]byte) ([]bool, error) { return []bool{}, nil } @@ -108,10 +105,9 @@ var _ vindexes.Lookup = (*multiIndex)(nil) // costlyIndex satisfies Lookup, NonUnique. type costlyIndex struct{ name string } -func (v *costlyIndex) String() string { return v.name } -func (*costlyIndex) Cost() int { return 10 } -func (*costlyIndex) IsUnique() bool { return false } -func (*costlyIndex) IsFunctional() bool { return false } +func (v *costlyIndex) String() string { return v.name } +func (*costlyIndex) Cost() int { return 10 } +func (*costlyIndex) IsUnique() bool { return false } func (*costlyIndex) Verify(vindexes.VCursor, []sqltypes.Value, [][]byte) ([]bool, error) { return []bool{}, nil } diff --git a/go/vt/vtgate/planbuilder/postprocess.go b/go/vt/vtgate/planbuilder/postprocess.go index 95d88c6e11a..d3e6b93653d 100644 --- a/go/vt/vtgate/planbuilder/postprocess.go +++ b/go/vt/vtgate/planbuilder/postprocess.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vtgate/planbuilder/primitive_builder.go b/go/vt/vtgate/planbuilder/primitive_builder.go index 42804045e7a..bed53cf8c0a 100644 --- a/go/vt/vtgate/planbuilder/primitive_builder.go +++ b/go/vt/vtgate/planbuilder/primitive_builder.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Vitess Authors. +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. diff --git a/go/vt/vtgate/planbuilder/pullout_subquery.go b/go/vt/vtgate/planbuilder/pullout_subquery.go index 109b205c147..35d189df8b1 100644 --- a/go/vt/vtgate/planbuilder/pullout_subquery.go +++ b/go/vt/vtgate/planbuilder/pullout_subquery.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Vitess Authors. +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. diff --git a/go/vt/vtgate/planbuilder/route.go b/go/vt/vtgate/planbuilder/route.go index c8e58cf6bdd..1f58eadbda8 100644 --- a/go/vt/vtgate/planbuilder/route.go +++ b/go/vt/vtgate/planbuilder/route.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vtgate/planbuilder/select.go b/go/vt/vtgate/planbuilder/select.go index f1ec12fba2f..0e0981fa621 100644 --- a/go/vt/vtgate/planbuilder/select.go +++ b/go/vt/vtgate/planbuilder/select.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vtgate/planbuilder/subquery.go b/go/vt/vtgate/planbuilder/subquery.go index 5aecd4aafe5..98c5772d73e 100644 --- a/go/vt/vtgate/planbuilder/subquery.go +++ b/go/vt/vtgate/planbuilder/subquery.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vtgate/planbuilder/symtab.go b/go/vt/vtgate/planbuilder/symtab.go index bc2744bb8ac..fb9ad2301c2 100644 --- a/go/vt/vtgate/planbuilder/symtab.go +++ b/go/vt/vtgate/planbuilder/symtab.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vtgate/planbuilder/symtab_test.go b/go/vt/vtgate/planbuilder/symtab_test.go index 4a4c55cf8b5..34006ff4b2e 100644 --- a/go/vt/vtgate/planbuilder/symtab_test.go +++ b/go/vt/vtgate/planbuilder/symtab_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vtgate/planbuilder/testdata/dml_cases.txt b/go/vt/vtgate/planbuilder/testdata/dml_cases.txt index 7d43fb8f9f0..0c31cc937ec 100644 --- a/go/vt/vtgate/planbuilder/testdata/dml_cases.txt +++ b/go/vt/vtgate/planbuilder/testdata/dml_cases.txt @@ -993,6 +993,32 @@ } } +# insert with default seq +"insert into user(id, nonid) values (default, 2)" +{ + "Original": "insert into user(id, nonid) values (default, 2)", + "Instructions": { + "Opcode": "InsertSharded", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "Query": "insert into user(id, nonid, Name, Costly) values (:_Id0, 2, :_Name0, :_Costly0)", + "Values": [[[":__seq0"]],[[null]],[[null]]], + "Table": "user", + "Generate": { + "Keyspace": { + "Name": "main", + "Sharded": false + }, + "Query": "select next :n values from seq", + "Values": [null] + }, + "Prefix": "insert into user(id, nonid, Name, Costly) values ", + "Mid": ["(:_Id0, 2, :_Name0, :_Costly0)"] + } +} + # insert with non vindex bool value "insert into user(nonid) values (true)" { diff --git a/go/vt/vtgate/planbuilder/testdata/select_cases.txt b/go/vt/vtgate/planbuilder/testdata/select_cases.txt index da728217844..bf0ce701b1c 100644 --- a/go/vt/vtgate/planbuilder/testdata/select_cases.txt +++ b/go/vt/vtgate/planbuilder/testdata/select_cases.txt @@ -154,6 +154,32 @@ } } +# select aggregation with partial scatter directive - added comments to try to confuse the hint extraction +"/*VT_SPAN_CONTEXT=123*/select /*vt+ SCATTER_ERRORS_AS_WARNINGS=1 */ count(*) from user" +{ + "Original": "/*VT_SPAN_CONTEXT=123*/select /*vt+ SCATTER_ERRORS_AS_WARNINGS=1 */ count(*) from user", + "Instructions": { + "Aggregates": [ + { + "Opcode": "count", + "Col": 0 + } + ], + "Keys": null, + "Input": { + "Opcode": "SelectScatter", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "Query": "select /*vt+ SCATTER_ERRORS_AS_WARNINGS=1 */ count(*) from user", + "FieldQuery": "select count(*) from user where 1 != 1", + "ScatterErrorsAsWarnings": true, + "Table": "user" + } + } +} + # select limit with partial scatter directive "select /*vt+ SCATTER_ERRORS_AS_WARNINGS=1 */ * from user limit 10" { @@ -350,7 +376,7 @@ { "Original": "select database() from dual", "Instructions": { - "Opcode": "SelectUnsharded", + "Opcode": "SelectReference", "Keyspace": { "Name": "main", "Sharded": false @@ -366,18 +392,18 @@ "NEXT used on a non-sequence table" # last_insert_id for unsharded route -"select last_insert_id() from main.dual" +"select last_insert_id() from main.unsharded" { - "Original": "select last_insert_id() from main.dual", + "Original": "select last_insert_id() from main.unsharded", "Instructions": { "Opcode": "SelectUnsharded", "Keyspace": { "Name": "main", "Sharded": false }, - "Query": "select last_insert_id() from dual", - "FieldQuery": "select last_insert_id() from dual where 1 != 1", - "Table": "dual" + "Query": "select last_insert_id() from unsharded", + "FieldQuery": "select last_insert_id() from unsharded where 1 != 1", + "Table": "unsharded" } } @@ -386,7 +412,7 @@ { "Original": "select @@session.auto_increment_increment from dual", "Instructions": { - "Opcode": "SelectUnsharded", + "Opcode": "SelectReference", "Keyspace": { "Name": "main", "Sharded": false @@ -423,15 +449,13 @@ { "Original": "select @@session.auto_increment_increment from user.dual", "Instructions": { - "Opcode": "SelectEqualUnique", + "Opcode": "SelectReference", "Keyspace": { "Name": "user", "Sharded": true }, "Query": "select @@session.auto_increment_increment from dual", "FieldQuery": "select @@session.auto_increment_increment from dual where 1 != 1", - "Vindex": "binary", - "Values": ["\u0000"], "Table": "dual" } } diff --git a/go/vt/vtgate/planbuilder/testdata/unsupported_cases.txt b/go/vt/vtgate/planbuilder/testdata/unsupported_cases.txt index c10604dfa72..77cee7da742 100644 --- a/go/vt/vtgate/planbuilder/testdata/unsupported_cases.txt +++ b/go/vt/vtgate/planbuilder/testdata/unsupported_cases.txt @@ -71,6 +71,10 @@ "select last_insert_id() from user" "unsupported: LAST_INSERT_ID is only allowed for unsharded keyspaces" +# last_insert_id for dual +"select last_insert_id()" +"unsupported: LAST_INSERT_ID is only allowed for unsharded keyspaces" + # natural join "select * from user natural join user_extra" "unsupported: natural join" diff --git a/go/vt/vtgate/planbuilder/testdata/wireup_cases.txt b/go/vt/vtgate/planbuilder/testdata/wireup_cases.txt index 6cda6f1750d..df5433d2349 100644 --- a/go/vt/vtgate/planbuilder/testdata/wireup_cases.txt +++ b/go/vt/vtgate/planbuilder/testdata/wireup_cases.txt @@ -538,7 +538,7 @@ } } -# Wire-up in in underlying primitive after pullout +# Wire-up in underlying primitive after pullout "select u.id, e.id, (select col from user) from user u join user_extra e where e.id = u.col limit 10" { "Original": "select u.id, e.id, (select col from user) from user u join user_extra e where e.id = u.col limit 10", diff --git a/go/vt/vtgate/planbuilder/union.go b/go/vt/vtgate/planbuilder/union.go index e762f1d4a67..ef3fb541d98 100644 --- a/go/vt/vtgate/planbuilder/union.go +++ b/go/vt/vtgate/planbuilder/union.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/vtgate/planbuilder/update.go b/go/vt/vtgate/planbuilder/update.go index e537e4f88f3..78a8f7a14ae 100644 --- a/go/vt/vtgate/planbuilder/update.go +++ b/go/vt/vtgate/planbuilder/update.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vtgate/planbuilder/vindex_func.go b/go/vt/vtgate/planbuilder/vindex_func.go index 21f36d74000..6135338c120 100644 --- a/go/vt/vtgate/planbuilder/vindex_func.go +++ b/go/vt/vtgate/planbuilder/vindex_func.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vtgate/plugin_mysql_server.go b/go/vt/vtgate/plugin_mysql_server.go index 85240db4804..7ec55adf17e 100644 --- a/go/vt/vtgate/plugin_mysql_server.go +++ b/go/vt/vtgate/plugin_mysql_server.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 @@ -21,10 +21,14 @@ import ( "fmt" "net" "os" + "regexp" "sync/atomic" "syscall" "time" + "vitess.io/vitess/go/vt/sqlparser" + "vitess.io/vitess/go/vt/vterrors" + "golang.org/x/net/context" "vitess.io/vitess/go/trace" @@ -65,8 +69,7 @@ var ( ) // vtgateHandler implements the Listener interface. -// It stores the Session in the ClientData of a Connection, if a transaction -// is in progress. +// It stores the Session in the ClientData of a Connection. type vtgateHandler struct { vtg *VTGate } @@ -80,6 +83,18 @@ func newVtgateHandler(vtg *VTGate) *vtgateHandler { func (vh *vtgateHandler) NewConnection(c *mysql.Conn) { } +func (vh *vtgateHandler) ComResetConnection(c *mysql.Conn) { + ctx := context.Background() + session := vh.session(c) + if session.InTransaction { + defer atomic.AddInt32(&busyConnections, -1) + } + _, _, err := vh.vtg.Execute(ctx, session, "rollback", make(map[string]*querypb.BindVariable)) + if err != nil { + log.Errorf("Error happened in transaction rollback: %v", err) + } +} + func (vh *vtgateHandler) ConnectionClosed(c *mysql.Conn) { // Rollback if there is an ongoing transaction. Ignore error. var ctx context.Context @@ -90,13 +105,44 @@ func (vh *vtgateHandler) ConnectionClosed(c *mysql.Conn) { } else { ctx = context.Background() } - session, _ := c.ClientData.(*vtgatepb.Session) - if session != nil { - if session.InTransaction { - defer atomic.AddInt32(&busyConnections, -1) + session := vh.session(c) + if session.InTransaction { + defer atomic.AddInt32(&busyConnections, -1) + } + _, _, _ = vh.vtg.Execute(ctx, session, "rollback", make(map[string]*querypb.BindVariable)) +} + +// Regexp to extract parent span id over the sql query +var r = regexp.MustCompile(`/\*VT_SPAN_CONTEXT=(.*)\*/`) + +// this function is here to make this logic easy to test by decoupling the logic from the `trace.NewSpan` and `trace.NewFromString` functions +func startSpanTestable(ctx context.Context, query, label string, + newSpan func(context.Context, string) (trace.Span, context.Context), + newSpanFromString func(context.Context, string, string) (trace.Span, context.Context, error)) (trace.Span, context.Context, error) { + _, comments := sqlparser.SplitMarginComments(query) + match := r.FindStringSubmatch(comments.Leading) + var span trace.Span + if len(match) == 0 { + span, ctx = newSpan(ctx, label) + } else { + var err error + span, ctx, err = newSpanFromString(ctx, match[1], label) + if err != nil { + return nil, nil, err } - _, _, _ = vh.vtg.Execute(ctx, session, "rollback", make(map[string]*querypb.BindVariable)) } + + trace.AnnotateSQL(span, query) + + return span, ctx, nil +} + +func startSpan(ctx context.Context, query, label string) (trace.Span, context.Context, error) { + return startSpanTestable(ctx, query, label, trace.NewSpan, trace.NewFromString) +} + +func (vh *vtgateHandler) ComInitDB(c *mysql.Conn, schemaName string) { + vh.session(c).TargetString = schemaName } func (vh *vtgateHandler) ComQuery(c *mysql.Conn, query string, callback func(*sqltypes.Result) error) error { @@ -106,8 +152,11 @@ func (vh *vtgateHandler) ComQuery(c *mysql.Conn, query string, callback func(*sq ctx, cancel = context.WithTimeout(ctx, *mysqlQueryTimeout) defer cancel() } - span, ctx := trace.NewSpan(ctx, "vtgateHandler.ComQuery") - trace.AnnotateSQL(span, query) + + span, ctx, err := startSpan(ctx, query, "vtgateHandler.ComQuery") + if err != nil { + return vterrors.Wrap(err, "failed to extract span") + } defer span.Finish() ctx = callinfo.MysqlCallInfo(ctx, c) @@ -124,19 +173,7 @@ func (vh *vtgateHandler) ComQuery(c *mysql.Conn, query string, callback func(*sq "VTGate MySQL Connector" /* subcomponent: part of the client */) ctx = callerid.NewContext(ctx, ef, im) - session, _ := c.ClientData.(*vtgatepb.Session) - if session == nil { - session = &vtgatepb.Session{ - Options: &querypb.ExecuteOptions{ - IncludedFields: querypb.ExecuteOptions_ALL, - }, - Autocommit: true, - } - if c.Capabilities&mysql.CapabilityClientFoundRows != 0 { - session.Options.ClientFoundRows = true - } - } - + session := vh.session(c) if !session.InTransaction { atomic.AddInt32(&busyConnections, 1) } @@ -146,15 +183,11 @@ func (vh *vtgateHandler) ComQuery(c *mysql.Conn, query string, callback func(*sq } }() - if c.SchemaName != "" { - session.TargetString = c.SchemaName - } if session.Options.Workload == querypb.ExecuteOptions_OLAP { err := vh.vtg.StreamExecute(ctx, session, query, make(map[string]*querypb.BindVariable), callback) return mysql.NewSQLErrorFromError(err) } session, result, err := vh.vtg.Execute(ctx, session, query, make(map[string]*querypb.BindVariable)) - c.ClientData = session err = mysql.NewSQLErrorFromError(err) if err != nil { return err @@ -187,19 +220,7 @@ func (vh *vtgateHandler) ComPrepare(c *mysql.Conn, query string) ([]*querypb.Fie "VTGate MySQL Connector" /* subcomponent: part of the client */) ctx = callerid.NewContext(ctx, ef, im) - session, _ := c.ClientData.(*vtgatepb.Session) - if session == nil { - session = &vtgatepb.Session{ - Options: &querypb.ExecuteOptions{ - IncludedFields: querypb.ExecuteOptions_ALL, - }, - Autocommit: true, - } - if c.Capabilities&mysql.CapabilityClientFoundRows != 0 { - session.Options.ClientFoundRows = true - } - } - + session := vh.session(c) if !session.InTransaction { atomic.AddInt32(&busyConnections, 1) } @@ -209,12 +230,7 @@ func (vh *vtgateHandler) ComPrepare(c *mysql.Conn, query string) ([]*querypb.Fie } }() - if c.SchemaName != "" { - session.TargetString = c.SchemaName - } - session, fld, err := vh.vtg.Prepare(ctx, session, query, make(map[string]*querypb.BindVariable)) - c.ClientData = session err = mysql.NewSQLErrorFromError(err) if err != nil { return nil, err @@ -246,19 +262,7 @@ func (vh *vtgateHandler) ComStmtExecute(c *mysql.Conn, prepare *mysql.PrepareDat "VTGate MySQL Connector" /* subcomponent: part of the client */) ctx = callerid.NewContext(ctx, ef, im) - session, _ := c.ClientData.(*vtgatepb.Session) - if session == nil { - session = &vtgatepb.Session{ - Options: &querypb.ExecuteOptions{ - IncludedFields: querypb.ExecuteOptions_ALL, - }, - Autocommit: true, - } - if c.Capabilities&mysql.CapabilityClientFoundRows != 0 { - session.Options.ClientFoundRows = true - } - } - + session := vh.session(c) if !session.InTransaction { atomic.AddInt32(&busyConnections, 1) } @@ -268,9 +272,6 @@ func (vh *vtgateHandler) ComStmtExecute(c *mysql.Conn, prepare *mysql.PrepareDat } }() - if c.SchemaName != "" { - session.TargetString = c.SchemaName - } if session.Options.Workload == querypb.ExecuteOptions_OLAP { err := vh.vtg.StreamExecute(ctx, session, prepare.PrepareStmt, prepare.BindVars, callback) return mysql.NewSQLErrorFromError(err) @@ -285,11 +286,24 @@ func (vh *vtgateHandler) ComStmtExecute(c *mysql.Conn, prepare *mysql.PrepareDat } func (vh *vtgateHandler) WarningCount(c *mysql.Conn) uint16 { + return uint16(len(vh.session(c).GetWarnings())) +} + +func (vh *vtgateHandler) session(c *mysql.Conn) *vtgatepb.Session { session, _ := c.ClientData.(*vtgatepb.Session) - if session != nil { - return uint16(len(session.GetWarnings())) + if session == nil { + session = &vtgatepb.Session{ + Options: &querypb.ExecuteOptions{ + IncludedFields: querypb.ExecuteOptions_ALL, + }, + Autocommit: true, + } + if c.Capabilities&mysql.CapabilityClientFoundRows != 0 { + session.Options.ClientFoundRows = true + } + c.ClientData = session } - return 0 + return session } var mysqlListener *mysql.Listener diff --git a/go/vt/vtgate/plugin_mysql_server_test.go b/go/vt/vtgate/plugin_mysql_server_test.go index c190f053e83..94633720801 100644 --- a/go/vt/vtgate/plugin_mysql_server_test.go +++ b/go/vt/vtgate/plugin_mysql_server_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 @@ -22,6 +22,9 @@ import ( "strings" "testing" + "github.com/stretchr/testify/assert" + "vitess.io/vitess/go/trace" + "golang.org/x/net/context" "vitess.io/vitess/go/mysql" @@ -40,6 +43,9 @@ func (th *testHandler) NewConnection(c *mysql.Conn) { func (th *testHandler) ConnectionClosed(c *mysql.Conn) { } +func (th *testHandler) ComInitDB(c *mysql.Conn, schemaName string) { +} + func (th *testHandler) ComQuery(c *mysql.Conn, q string, callback func(*sqltypes.Result) error) error { return nil } @@ -48,6 +54,9 @@ func (th *testHandler) ComPrepare(c *mysql.Conn, q string) ([]*querypb.Field, er return nil, nil } +func (th *testHandler) ComResetConnection(c *mysql.Conn) { +} + func (th *testHandler) ComStmtExecute(c *mysql.Conn, prepare *mysql.PrepareData, callback func(*sqltypes.Result) error) error { return nil } @@ -168,3 +177,54 @@ func TestConnectionRespectsExistingUnixSocket(t *testing.T) { t.Errorf("Error: %v, want prefix %s", err, want) } } + +var newSpanOK = func(ctx context.Context, label string) (trace.Span, context.Context) { + return trace.NoopSpan{}, context.Background() +} + +var newFromStringOK = func(ctx context.Context, spanContext, label string) (trace.Span, context.Context, error) { + return trace.NoopSpan{}, context.Background(), nil +} + +func newFromStringFail(t *testing.T) func(ctx context.Context, parentSpan string, label string) (trace.Span, context.Context, error) { + return func(ctx context.Context, parentSpan string, label string) (trace.Span, context.Context, error) { + t.Fatalf("we didn't provide a parent span in the sql query. this should not have been called. got: %v", parentSpan) + return trace.NoopSpan{}, context.Background(), nil + } +} + +func newFromStringExpect(t *testing.T, expected string) func(ctx context.Context, parentSpan string, label string) (trace.Span, context.Context, error) { + return func(ctx context.Context, parentSpan string, label string) (trace.Span, context.Context, error) { + assert.Equal(t, expected, parentSpan) + return trace.NoopSpan{}, context.Background(), nil + } +} + +func newSpanFail(t *testing.T) func(ctx context.Context, label string) (trace.Span, context.Context) { + return func(ctx context.Context, label string) (trace.Span, context.Context) { + t.Fatalf("we provided a span context but newFromString was not used as expected") + return trace.NoopSpan{}, context.Background() + } +} + +func TestNoSpanContextPassed(t *testing.T) { + _, _, err := startSpanTestable(context.Background(), "sql without comments", "someLabel", newSpanOK, newFromStringFail(t)) + assert.NoError(t, err) +} + +func TestSpanContextNoPassedInButExistsInString(t *testing.T) { + _, _, err := startSpanTestable(context.Background(), "SELECT * FROM SOMETABLE WHERE COL = \"/*VT_SPAN_CONTEXT=123*/", "someLabel", newSpanOK, newFromStringFail(t)) + assert.NoError(t, err) +} + +func TestSpanContextPassedIn(t *testing.T) { + _, _, err := startSpanTestable(context.Background(), "/*VT_SPAN_CONTEXT=123*/SQL QUERY", "someLabel", newSpanFail(t), newFromStringOK) + assert.NoError(t, err) +} + +func TestSpanContextPassedInEvenAroundOtherComments(t *testing.T) { + _, _, err := startSpanTestable(context.Background(), "/*VT_SPAN_CONTEXT=123*/SELECT /*vt+ SCATTER_ERRORS_AS_WARNINGS */ col1, col2 FROM TABLE ", "someLabel", + newSpanFail(t), + newFromStringExpect(t, "123")) + assert.NoError(t, err) +} diff --git a/go/vt/vtgate/querylog.go b/go/vt/vtgate/querylog.go index a1fdc61f11d..8ec0a190b91 100644 --- a/go/vt/vtgate/querylog.go +++ b/go/vt/vtgate/querylog.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vtgate/querylogz.go b/go/vt/vtgate/querylogz.go index 45ea0eca669..69a319d8b1c 100644 --- a/go/vt/vtgate/querylogz.go +++ b/go/vt/vtgate/querylogz.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vtgate/querylogz_test.go b/go/vt/vtgate/querylogz_test.go index 65abb9b8642..cf68f7abed9 100644 --- a/go/vt/vtgate/querylogz_test.go +++ b/go/vt/vtgate/querylogz_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vtgate/queryz.go b/go/vt/vtgate/queryz.go index 53833cadb40..19298574988 100644 --- a/go/vt/vtgate/queryz.go +++ b/go/vt/vtgate/queryz.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vtgate/queryz_test.go b/go/vt/vtgate/queryz_test.go index c6cc3c62fdd..1c1d0af4384 100644 --- a/go/vt/vtgate/queryz_test.go +++ b/go/vt/vtgate/queryz_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vtgate/resolver.go b/go/vt/vtgate/resolver.go index be535df3897..f7bae5e9a7d 100644 --- a/go/vt/vtgate/resolver.go +++ b/go/vt/vtgate/resolver.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -242,7 +242,7 @@ func (res *Resolver) ExecuteBatch( // one shard since it cannot merge-sort the results to guarantee ordering of // response which is needed for checkpointing. // Note we guarantee the callback will not be called concurrently -// by mutiple go routines. +// by multiple go routines. func (res *Resolver) StreamExecute( ctx context.Context, sql string, diff --git a/go/vt/vtgate/resolver_test.go b/go/vt/vtgate/resolver_test.go index e26a77e5eaa..5a8c473db18 100644 --- a/go/vt/vtgate/resolver_test.go +++ b/go/vt/vtgate/resolver_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vtgate/safe_session.go b/go/vt/vtgate/safe_session.go index 7657a9654ab..7e0e7b87aac 100644 --- a/go/vt/vtgate/safe_session.go +++ b/go/vt/vtgate/safe_session.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vtgate/sandbox_test.go b/go/vt/vtgate/sandbox_test.go index 52384a429a7..c97f1255daf 100644 --- a/go/vt/vtgate/sandbox_test.go +++ b/go/vt/vtgate/sandbox_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vtgate/scatter_conn.go b/go/vt/vtgate/scatter_conn.go index 3bc5cb796e8..b64402c7beb 100644 --- a/go/vt/vtgate/scatter_conn.go +++ b/go/vt/vtgate/scatter_conn.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -458,7 +458,7 @@ func (stc *ScatterConn) processOneStreamingResult(mu *sync.Mutex, fieldSent *boo // StreamExecute executes a streaming query on vttablet. The retry rules are the same. // Note we guarantee the callback will not be called concurrently -// by mutiple go routines, through processOneStreamingResult. +// by multiple go routines, through processOneStreamingResult. func (stc *ScatterConn) StreamExecute( ctx context.Context, query string, @@ -485,7 +485,7 @@ func (stc *ScatterConn) StreamExecute( // but each shard gets its own bindVars. If len(shards) is not equal to // len(bindVars), the function panics. // Note we guarantee the callback will not be called concurrently -// by mutiple go routines, through processOneStreamingResult. +// by multiple go routines, through processOneStreamingResult. func (stc *ScatterConn) StreamExecuteMulti( ctx context.Context, query string, @@ -542,7 +542,7 @@ func (tt *timeTracker) Record(target *querypb.Target) time.Time { // MessageStream streams messages from the specified shards. // Note we guarantee the callback will not be called concurrently -// by mutiple go routines, through processOneStreamingResult. +// by multiple go routines, through processOneStreamingResult. func (stc *ScatterConn) MessageStream(ctx context.Context, rss []*srvtopo.ResolvedShard, name string, callback func(*sqltypes.Result) error) error { // The cancelable context is used for handling errors // from individual streams. diff --git a/go/vt/vtgate/scatter_conn_test.go b/go/vt/vtgate/scatter_conn_test.go index a07161f07f0..9eafc852113 100644 --- a/go/vt/vtgate/scatter_conn_test.go +++ b/go/vt/vtgate/scatter_conn_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vtgate/tx_conn.go b/go/vt/vtgate/tx_conn.go index 68c7062091d..2089500237f 100644 --- a/go/vt/vtgate/tx_conn.go +++ b/go/vt/vtgate/tx_conn.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -47,7 +47,7 @@ func NewTxConn(gw gateway.Gateway, txMode vtgatepb.TransactionMode) *TxConn { } } -// Begin begins a new transaction. If one is already in progress, it commmits it +// Begin begins a new transaction. If one is already in progress, it commits it // and starts a new one. func (txc *TxConn) Begin(ctx context.Context, session *SafeSession) error { if session.InTransaction() { diff --git a/go/vt/vtgate/tx_conn_test.go b/go/vt/vtgate/tx_conn_test.go index e8ffa3f3ea4..d05e98abd12 100644 --- a/go/vt/vtgate/tx_conn_test.go +++ b/go/vt/vtgate/tx_conn_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vtgate/vcursor_impl.go b/go/vt/vtgate/vcursor_impl.go index 8da8069b3a9..4d6ef1cb5e8 100644 --- a/go/vt/vtgate/vcursor_impl.go +++ b/go/vt/vtgate/vcursor_impl.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vtgate/vindexes/binary.go b/go/vt/vtgate/vindexes/binary.go index 2d437835bc1..1d9e2bf132e 100644 --- a/go/vt/vtgate/vindexes/binary.go +++ b/go/vt/vtgate/vindexes/binary.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 @@ -54,11 +54,6 @@ func (vind *Binary) IsUnique() bool { return true } -// IsFunctional returns true since the Vindex is functional. -func (vind *Binary) IsFunctional() bool { - return true -} - // Verify returns true if ids maps to ksids. func (vind *Binary) Verify(_ VCursor, ids []sqltypes.Value, ksids [][]byte) ([]bool, error) { out := make([]bool, len(ids)) diff --git a/go/vt/vtgate/vindexes/binary_test.go b/go/vt/vtgate/vindexes/binary_test.go index 15b5d517a3e..a6fe555558a 100644 --- a/go/vt/vtgate/vindexes/binary_test.go +++ b/go/vt/vtgate/vindexes/binary_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/vtgate/vindexes/binarymd5.go b/go/vt/vtgate/vindexes/binarymd5.go index b3cb1f95e39..a75326e276e 100644 --- a/go/vt/vtgate/vindexes/binarymd5.go +++ b/go/vt/vtgate/vindexes/binarymd5.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 @@ -53,11 +53,6 @@ func (vind *BinaryMD5) IsUnique() bool { return true } -// IsFunctional returns true since the Vindex is functional. -func (vind *BinaryMD5) IsFunctional() bool { - return true -} - // Verify returns true if ids maps to ksids. func (vind *BinaryMD5) Verify(_ VCursor, ids []sqltypes.Value, ksids [][]byte) ([]bool, error) { out := make([]bool, len(ids)) diff --git a/go/vt/vtgate/vindexes/binarymd5_test.go b/go/vt/vtgate/vindexes/binarymd5_test.go index e1ad70f4049..e3a133c1fac 100644 --- a/go/vt/vtgate/vindexes/binarymd5_test.go +++ b/go/vt/vtgate/vindexes/binarymd5_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/vtgate/vindexes/consistent_lookup.go b/go/vt/vtgate/vindexes/consistent_lookup.go index f040947a7f4..546b70c244e 100644 --- a/go/vt/vtgate/vindexes/consistent_lookup.go +++ b/go/vt/vtgate/vindexes/consistent_lookup.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 @@ -25,6 +25,7 @@ import ( "vitess.io/vitess/go/sqltypes" "vitess.io/vitess/go/vt/key" querypb "vitess.io/vitess/go/vt/proto/query" + "vitess.io/vitess/go/vt/proto/vtgate" vtgatepb "vitess.io/vitess/go/vt/proto/vtgate" vtrpcpb "vitess.io/vitess/go/vt/proto/vtrpc" "vitess.io/vitess/go/vt/sqlparser" @@ -198,14 +199,9 @@ func (lu *clCommon) String() string { return lu.name } -// IsFunctional returns false since the Vindex is not functional. -func (lu *clCommon) IsFunctional() bool { - return false -} - // Verify returns true if ids maps to ksids. func (lu *clCommon) Verify(vcursor VCursor, ids []sqltypes.Value, ksids [][]byte) ([]bool, error) { - return lu.lkp.Verify(vcursor, ids, ksidsToValues(ksids)) + return lu.lkp.VerifyCustom(vcursor, ids, ksidsToValues(ksids), vtgate.CommitOrder_PRE) } // Create reserves the id by inserting it into the vindex table. diff --git a/go/vt/vtgate/vindexes/consistent_lookup_test.go b/go/vt/vtgate/vindexes/consistent_lookup_test.go index 51a4261402d..e1e571d07ec 100644 --- a/go/vt/vtgate/vindexes/consistent_lookup_test.go +++ b/go/vt/vtgate/vindexes/consistent_lookup_test.go @@ -55,9 +55,6 @@ func TestConsistentLookupInfo(t *testing.T) { if lookup.IsUnique() { t.Errorf("IsUnique(): %v, want false", lookup.IsUnique()) } - if lookup.IsFunctional() { - t.Errorf("IsFunctional(): %v, want false", lookup.IsFunctional()) - } } func TestConsistentLookupUniqueInfo(t *testing.T) { @@ -71,9 +68,6 @@ func TestConsistentLookupUniqueInfo(t *testing.T) { if !lookup.IsUnique() { t.Errorf("IsUnique(): %v, want true", lookup.IsUnique()) } - if lookup.IsFunctional() { - t.Errorf("IsFunctional(): %v, want false", lookup.IsFunctional()) - } } func TestConsistentLookupMap(t *testing.T) { @@ -178,8 +172,8 @@ func TestConsistentLookupVerify(t *testing.T) { t.Error(err) } vc.verifyLog(t, []string{ - "Execute select fromc1 from t where fromc1 = :fromc1 and toc = :toc [{fromc1 1} {toc test1}] false", - "Execute select fromc1 from t where fromc1 = :fromc1 and toc = :toc [{fromc1 2} {toc test2}] false", + "ExecutePre select fromc1 from t where fromc1 = :fromc1 and toc = :toc [{fromc1 1} {toc test1}] false", + "ExecutePre select fromc1 from t where fromc1 = :fromc1 and toc = :toc [{fromc1 2} {toc test2}] false", }) // Test query fail. @@ -499,7 +493,7 @@ func (vc *loggingVCursor) verifyLog(t *testing.T, want []string) { t.Fatalf("index exceeded: %v", vc.log[i:]) } if got != want[i] { - t.Errorf("log(%d):\n%s, want\n%s", i, got, want[i]) + t.Errorf("log(%d):\n%q, want\n%q", i, got, want[i]) } } if len(want) > len(vc.log) { diff --git a/go/vt/vtgate/vindexes/hash.go b/go/vt/vtgate/vindexes/hash.go index edd47e101ff..43859e4f38a 100644 --- a/go/vt/vtgate/vindexes/hash.go +++ b/go/vt/vtgate/vindexes/hash.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -62,11 +62,6 @@ func (vind *Hash) IsUnique() bool { return true } -// IsFunctional returns true since the Vindex is functional. -func (vind *Hash) IsFunctional() bool { - return true -} - // Map can map ids to key.Destination objects. func (vind *Hash) Map(cursor VCursor, ids []sqltypes.Value) ([]key.Destination, error) { out := make([]key.Destination, len(ids)) diff --git a/go/vt/vtgate/vindexes/hash_test.go b/go/vt/vtgate/vindexes/hash_test.go index 40ea714745a..c0e811a3616 100644 --- a/go/vt/vtgate/vindexes/hash_test.go +++ b/go/vt/vtgate/vindexes/hash_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vtgate/vindexes/lookup.go b/go/vt/vtgate/vindexes/lookup.go index fd4b816235e..a6869066e4c 100644 --- a/go/vt/vtgate/vindexes/lookup.go +++ b/go/vt/vtgate/vindexes/lookup.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 @@ -61,11 +61,6 @@ func (ln *LookupNonUnique) IsUnique() bool { return false } -// IsFunctional returns false since the Vindex is not functional. -func (ln *LookupNonUnique) IsFunctional() bool { - return false -} - // Map can map ids to key.Destination objects. func (ln *LookupNonUnique) Map(vcursor VCursor, ids []sqltypes.Value) ([]key.Destination, error) { out := make([]key.Destination, 0, len(ids)) @@ -216,11 +211,6 @@ func (lu *LookupUnique) IsUnique() bool { return true } -// IsFunctional returns false since the Vindex is not functional. -func (lu *LookupUnique) IsFunctional() bool { - return false -} - // Map can map ids to key.Destination objects. func (lu *LookupUnique) Map(vcursor VCursor, ids []sqltypes.Value) ([]key.Destination, error) { out := make([]key.Destination, 0, len(ids)) diff --git a/go/vt/vtgate/vindexes/lookup_hash.go b/go/vt/vtgate/vindexes/lookup_hash.go index 330ef13e408..30118bd274a 100644 --- a/go/vt/vtgate/vindexes/lookup_hash.go +++ b/go/vt/vtgate/vindexes/lookup_hash.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -93,11 +93,6 @@ func (lh *LookupHash) IsUnique() bool { return false } -// IsFunctional returns false since the Vindex is not functional. -func (lh *LookupHash) IsFunctional() bool { - return false -} - // Map can map ids to key.Destination objects. func (lh *LookupHash) Map(vcursor VCursor, ids []sqltypes.Value) ([]key.Destination, error) { out := make([]key.Destination, 0, len(ids)) @@ -249,11 +244,6 @@ func (lhu *LookupHashUnique) IsUnique() bool { return true } -// IsFunctional returns false since the Vindex is not functional. -func (lhu *LookupHashUnique) IsFunctional() bool { - return false -} - // Map can map ids to key.Destination objects. func (lhu *LookupHashUnique) Map(vcursor VCursor, ids []sqltypes.Value) ([]key.Destination, error) { out := make([]key.Destination, 0, len(ids)) diff --git a/go/vt/vtgate/vindexes/lookup_hash_test.go b/go/vt/vtgate/vindexes/lookup_hash_test.go index f717d9d9c75..414c86ca939 100644 --- a/go/vt/vtgate/vindexes/lookup_hash_test.go +++ b/go/vt/vtgate/vindexes/lookup_hash_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vtgate/vindexes/lookup_hash_unique_test.go b/go/vt/vtgate/vindexes/lookup_hash_unique_test.go index 536e4a7d4a9..bd67e77523d 100644 --- a/go/vt/vtgate/vindexes/lookup_hash_unique_test.go +++ b/go/vt/vtgate/vindexes/lookup_hash_unique_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vtgate/vindexes/lookup_internal.go b/go/vt/vtgate/vindexes/lookup_internal.go index 1eae733425e..bfcc38a2c17 100644 --- a/go/vt/vtgate/vindexes/lookup_internal.go +++ b/go/vt/vtgate/vindexes/lookup_internal.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 @@ -62,6 +62,9 @@ func (lkp *lookupInternal) Init(lookupQueryParams map[string]string, autocommit, // Lookup performs a lookup for the ids. func (lkp *lookupInternal) Lookup(vcursor VCursor, ids []sqltypes.Value) ([]*sqltypes.Result, error) { + if vcursor == nil { + return nil, fmt.Errorf("cannot perform lookup: no vcursor provided") + } results := make([]*sqltypes.Result, 0, len(ids)) for _, id := range ids { bindVars := map[string]*querypb.BindVariable{ @@ -84,19 +87,21 @@ func (lkp *lookupInternal) Lookup(vcursor VCursor, ids []sqltypes.Value) ([]*sql // Verify returns true if ids map to values. func (lkp *lookupInternal) Verify(vcursor VCursor, ids, values []sqltypes.Value) ([]bool, error) { + co := vtgatepb.CommitOrder_NORMAL + if lkp.Autocommit { + co = vtgatepb.CommitOrder_AUTOCOMMIT + } + return lkp.VerifyCustom(vcursor, ids, values, co) +} + +func (lkp *lookupInternal) VerifyCustom(vcursor VCursor, ids, values []sqltypes.Value, co vtgatepb.CommitOrder) ([]bool, error) { out := make([]bool, len(ids)) for i, id := range ids { bindVars := map[string]*querypb.BindVariable{ lkp.FromColumns[0]: sqltypes.ValueBindVariable(id), lkp.To: sqltypes.ValueBindVariable(values[i]), } - var err error - var result *sqltypes.Result - co := vtgatepb.CommitOrder_NORMAL - if lkp.Autocommit { - co = vtgatepb.CommitOrder_AUTOCOMMIT - } - result, err = vcursor.Execute("VindexVerify", lkp.ver, bindVars, false /* isDML */, co) + result, err := vcursor.Execute("VindexVerify", lkp.ver, bindVars, false /* isDML */, co) if err != nil { return nil, fmt.Errorf("lookup.Verify: %v", err) } diff --git a/go/vt/vtgate/vindexes/lookup_test.go b/go/vt/vtgate/vindexes/lookup_test.go index e1a58e45bf1..ca26ce61e9d 100644 --- a/go/vt/vtgate/vindexes/lookup_test.go +++ b/go/vt/vtgate/vindexes/lookup_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 @@ -127,6 +127,16 @@ func TestLookupNonUniqueString(t *testing.T) { } } +func TestLookupNilVCursor(t *testing.T) { + lookupNonUnique := createLookup(t, "lookup", false) + + _, err := lookupNonUnique.Map(nil, []sqltypes.Value{sqltypes.NewInt64(1), sqltypes.NewInt64(2)}) + want := "cannot perform lookup: no vcursor provided" + if err == nil || err.Error() != want { + t.Errorf("Map(nil vcursor) err: %v, want %v", err, want) + } +} + func TestLookupNonUniqueMap(t *testing.T) { lookupNonUnique := createLookup(t, "lookup", false) vc := &vcursor{numRows: 2} diff --git a/go/vt/vtgate/vindexes/lookup_unicodeloosemd5_hash.go b/go/vt/vtgate/vindexes/lookup_unicodeloosemd5_hash.go index ebf52a6caf8..30b12a33f30 100644 --- a/go/vt/vtgate/vindexes/lookup_unicodeloosemd5_hash.go +++ b/go/vt/vtgate/vindexes/lookup_unicodeloosemd5_hash.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -94,11 +94,6 @@ func (lh *LookupUnicodeLooseMD5Hash) IsUnique() bool { return false } -// IsFunctional returns false since the Vindex is not functional. -func (lh *LookupUnicodeLooseMD5Hash) IsFunctional() bool { - return false -} - // Map can map ids to key.Destination objects. func (lh *LookupUnicodeLooseMD5Hash) Map(vcursor VCursor, ids []sqltypes.Value) ([]key.Destination, error) { out := make([]key.Destination, 0, len(ids)) @@ -261,11 +256,6 @@ func (lhu *LookupUnicodeLooseMD5HashUnique) IsUnique() bool { return true } -// IsFunctional returns false since the Vindex is not functional. -func (lhu *LookupUnicodeLooseMD5HashUnique) IsFunctional() bool { - return false -} - // Map can map ids to key.Destination objects. func (lhu *LookupUnicodeLooseMD5HashUnique) Map(vcursor VCursor, ids []sqltypes.Value) ([]key.Destination, error) { out := make([]key.Destination, 0, len(ids)) diff --git a/go/vt/vtgate/vindexes/lookup_unicodeloosemd5_hash_test.go b/go/vt/vtgate/vindexes/lookup_unicodeloosemd5_hash_test.go index 5e91ce583cc..dc87eaf6aa9 100644 --- a/go/vt/vtgate/vindexes/lookup_unicodeloosemd5_hash_test.go +++ b/go/vt/vtgate/vindexes/lookup_unicodeloosemd5_hash_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/vtgate/vindexes/lookup_unique_test.go b/go/vt/vtgate/vindexes/lookup_unique_test.go index 7c15e240bc7..5e33bf370a9 100644 --- a/go/vt/vtgate/vindexes/lookup_unique_test.go +++ b/go/vt/vtgate/vindexes/lookup_unique_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/vtgate/vindexes/null.go b/go/vt/vtgate/vindexes/null.go index ade93ae474f..d3fc3fc56bf 100644 --- a/go/vt/vtgate/vindexes/null.go +++ b/go/vt/vtgate/vindexes/null.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -58,11 +58,6 @@ func (vind *Null) IsUnique() bool { return true } -// IsFunctional returns true since the Vindex is functional. -func (vind *Null) IsFunctional() bool { - return true -} - // Map can map ids to key.Destination objects. func (vind *Null) Map(cursor VCursor, ids []sqltypes.Value) ([]key.Destination, error) { out := make([]key.Destination, 0, len(ids)) diff --git a/go/vt/vtgate/vindexes/null_test.go b/go/vt/vtgate/vindexes/null_test.go index 1c0cd9facec..f92855edca5 100644 --- a/go/vt/vtgate/vindexes/null_test.go +++ b/go/vt/vtgate/vindexes/null_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vtgate/vindexes/numeric.go b/go/vt/vtgate/vindexes/numeric.go index 66ffc5c92de..1b0b5c2a071 100644 --- a/go/vt/vtgate/vindexes/numeric.go +++ b/go/vt/vtgate/vindexes/numeric.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -57,11 +57,6 @@ func (*Numeric) IsUnique() bool { return true } -// IsFunctional returns true since the Vindex is functional. -func (*Numeric) IsFunctional() bool { - return true -} - // Verify returns true if ids and ksids match. func (*Numeric) Verify(_ VCursor, ids []sqltypes.Value, ksids [][]byte) ([]bool, error) { out := make([]bool, len(ids)) diff --git a/go/vt/vtgate/vindexes/numeric_static_map.go b/go/vt/vtgate/vindexes/numeric_static_map.go index 42f49f2d780..9f51a80a888 100644 --- a/go/vt/vtgate/vindexes/numeric_static_map.go +++ b/go/vt/vtgate/vindexes/numeric_static_map.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -80,11 +80,6 @@ func (vind *NumericStaticMap) IsUnique() bool { return true } -// IsFunctional returns true since the Vindex is functional. -func (vind *NumericStaticMap) IsFunctional() bool { - return true -} - // Verify returns true if ids and ksids match. func (vind *NumericStaticMap) Verify(_ VCursor, ids []sqltypes.Value, ksids [][]byte) ([]bool, error) { out := make([]bool, len(ids)) diff --git a/go/vt/vtgate/vindexes/numeric_static_map_test.go b/go/vt/vtgate/vindexes/numeric_static_map_test.go index 78829c6d68c..e81abe331db 100644 --- a/go/vt/vtgate/vindexes/numeric_static_map_test.go +++ b/go/vt/vtgate/vindexes/numeric_static_map_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vtgate/vindexes/numeric_test.go b/go/vt/vtgate/vindexes/numeric_test.go index eacc6f79e7d..7ad9a357f69 100644 --- a/go/vt/vtgate/vindexes/numeric_test.go +++ b/go/vt/vtgate/vindexes/numeric_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vtgate/vindexes/region_experimental.go b/go/vt/vtgate/vindexes/region_experimental.go new file mode 100644 index 00000000000..15159517dd9 --- /dev/null +++ b/go/vt/vtgate/vindexes/region_experimental.go @@ -0,0 +1,135 @@ +/* +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 vindexes + +import ( + "bytes" + "encoding/binary" + "fmt" + + "vitess.io/vitess/go/sqltypes" + "vitess.io/vitess/go/vt/key" +) + +var ( + _ Vindex = (*RegionExperimental)(nil) + _ Lookup = (*RegionExperimental)(nil) + _ WantOwnerInfo = (*RegionExperimental)(nil) + _ MultiColumn = (*RegionExperimental)(nil) +) + +func init() { + Register("region_experimental", NewRegionExperimental) +} + +// RegionExperimental defines a vindex that uses a lookup table. +// The table is expected to define the id column as unique. It's +// Unique and a Lookup. +type RegionExperimental struct { + regionBytes int + *ConsistentLookupUnique +} + +// NewRegionExperimental creates a RegionExperimental vindex. +// The supplied map requires all the fields of "consistent_lookup_unique". +// Additionally, it requires a region_bytes argument whose value can be "1", or "2". +func NewRegionExperimental(name string, m map[string]string) (Vindex, error) { + rbs, ok := m["region_bytes"] + if !ok { + return nil, fmt.Errorf("region_experimental missing region_bytes param") + } + var rb int + switch rbs { + case "1": + rb = 1 + case "2": + rb = 2 + default: + return nil, fmt.Errorf("region_bits must be 1 or 2: %v", rbs) + } + vindex, err := NewConsistentLookupUnique(name, m) + if err != nil { + // Unreachable. + return nil, err + } + cl := vindex.(*ConsistentLookupUnique) + if len(cl.lkp.FromColumns) != 2 { + return nil, fmt.Errorf("two columns are required for region_experimental: %v", cl.lkp.FromColumns) + } + return &RegionExperimental{ + regionBytes: rb, + ConsistentLookupUnique: cl, + }, nil +} + +// MapMulti satisfies MultiColumn. +func (ge *RegionExperimental) MapMulti(vcursor VCursor, rowsColValues [][]sqltypes.Value) ([]key.Destination, error) { + destinations := make([]key.Destination, 0, len(rowsColValues)) + for _, row := range rowsColValues { + if len(row) != 2 { + destinations = append(destinations, key.DestinationNone{}) + continue + } + // Compute hash. + hn, err := sqltypes.ToUint64(row[0]) + if err != nil { + destinations = append(destinations, key.DestinationNone{}) + continue + } + h := vhash(hn) + + // Compute region prefix. + rn, err := sqltypes.ToUint64(row[1]) + if err != nil { + destinations = append(destinations, key.DestinationNone{}) + continue + } + r := make([]byte, 2) + binary.BigEndian.PutUint16(r, uint16(rn)) + + // Concatenate and add to destinations. + if ge.regionBytes == 1 { + r = r[1:] + } + dest := append(r, h...) + destinations = append(destinations, key.DestinationKeyspaceID(dest)) + } + return destinations, nil +} + +// VerifyMulti satisfies MultiColumn. +func (ge *RegionExperimental) VerifyMulti(vcursor VCursor, rowsColValues [][]sqltypes.Value, ksids [][]byte) ([]bool, error) { + result := make([]bool, len(rowsColValues)) + destinations, _ := ge.MapMulti(vcursor, rowsColValues) + for i, dest := range destinations { + destksid, ok := dest.(key.DestinationKeyspaceID) + if !ok { + continue + } + result[i] = bytes.Equal([]byte(destksid), ksids[i]) + } + // We also need to verify from the lookup. + // TODO(sougou): we should only verify true values from previous result. + lresult, err := Verify(ge.ConsistentLookupUnique, vcursor, rowsColValues, ksids) + if err != nil { + return nil, err + } + for i := range result { + result[i] = result[i] && lresult[i] + } + return result, nil +} diff --git a/go/vt/vtgate/vindexes/region_experimental_test.go b/go/vt/vtgate/vindexes/region_experimental_test.go new file mode 100644 index 00000000000..ef85c65b90e --- /dev/null +++ b/go/vt/vtgate/vindexes/region_experimental_test.go @@ -0,0 +1,141 @@ +/* +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 vindexes + +import ( + "strconv" + "testing" + + "github.com/stretchr/testify/assert" + "vitess.io/vitess/go/sqltypes" + "vitess.io/vitess/go/vt/key" +) + +func TestRegionExperimentalMapMulti1(t *testing.T) { + ge, err := createRegionVindex(t, "region_experimental", "f1,f2", 1) + assert.NoError(t, err) + got, err := ge.(MultiColumn).MapMulti(nil, [][]sqltypes.Value{{ + sqltypes.NewInt64(1), sqltypes.NewInt64(1), + }, { + sqltypes.NewInt64(1), sqltypes.NewInt64(255), + }, { + sqltypes.NewInt64(1), sqltypes.NewInt64(256), + }, { + // Invalid length. + sqltypes.NewInt64(1), + }, { + // Invalid id. + sqltypes.NewVarBinary("abcd"), sqltypes.NewInt64(256), + }, { + // Invalid region. + sqltypes.NewInt64(1), sqltypes.NewVarBinary("abcd"), + }}) + assert.NoError(t, err) + + want := []key.Destination{ + key.DestinationKeyspaceID([]byte("\x01\x16k@\xb4J\xbaK\xd6")), + key.DestinationKeyspaceID([]byte("\xff\x16k@\xb4J\xbaK\xd6")), + key.DestinationKeyspaceID([]byte("\x00\x16k@\xb4J\xbaK\xd6")), + key.DestinationNone{}, + key.DestinationNone{}, + key.DestinationNone{}, + } + assert.Equal(t, want, got) +} + +func TestRegionExperimentalMapMulti2(t *testing.T) { + ge, err := createRegionVindex(t, "region_experimental", "f1,f2", 2) + assert.NoError(t, err) + got, err := ge.(MultiColumn).MapMulti(nil, [][]sqltypes.Value{{ + sqltypes.NewInt64(1), sqltypes.NewInt64(1), + }, { + sqltypes.NewInt64(1), sqltypes.NewInt64(255), + }, { + sqltypes.NewInt64(1), sqltypes.NewInt64(256), + }, { + sqltypes.NewInt64(1), sqltypes.NewInt64(0x10000), + }}) + assert.NoError(t, err) + + want := []key.Destination{ + key.DestinationKeyspaceID([]byte("\x00\x01\x16k@\xb4J\xbaK\xd6")), + key.DestinationKeyspaceID([]byte("\x00\xff\x16k@\xb4J\xbaK\xd6")), + key.DestinationKeyspaceID([]byte("\x01\x00\x16k@\xb4J\xbaK\xd6")), + key.DestinationKeyspaceID([]byte("\x00\x00\x16k@\xb4J\xbaK\xd6")), + } + assert.Equal(t, want, got) +} + +func TestRegionExperimentalVerifyMulti(t *testing.T) { + + ge, err := createRegionVindex(t, "region_experimental", "f1,f2", 1) + assert.NoError(t, err) + vals := [][]sqltypes.Value{{ + // One for match + sqltypes.NewInt64(1), sqltypes.NewInt64(1), + }, { + // One for mismatch by lookup + sqltypes.NewInt64(1), sqltypes.NewInt64(1), + }, { + // One for mismatch + sqltypes.NewInt64(1), sqltypes.NewInt64(1), + }, { + // One invalid value + sqltypes.NewInt64(1), + }} + ksids := [][]byte{ + []byte("\x01\x16k@\xb4J\xbaK\xd6"), + []byte("\x01\x16k@\xb4J\xbaK\xd6"), + []byte("no match"), + []byte(""), + } + vc := &loggingVCursor{} + vc.AddResult(makeTestResult(1), nil) + // The second value should return a mismatch. + vc.AddResult(&sqltypes.Result{}, nil) + vc.AddResult(makeTestResult(1), nil) + vc.AddResult(makeTestResult(1), nil) + + want := []bool{true, false, false, false} + got, err := ge.(MultiColumn).VerifyMulti(vc, vals, ksids) + assert.NoError(t, err) + vc.verifyLog(t, []string{ + "ExecutePre select f1 from t where f1 = :f1 and toc = :toc [{f1 1} {toc \x01\x16k@\xb4J\xbaK\xd6}] false", + "ExecutePre select f1 from t where f1 = :f1 and toc = :toc [{f1 1} {toc \x01\x16k@\xb4J\xbaK\xd6}] false", + "ExecutePre select f1 from t where f1 = :f1 and toc = :toc [{f1 1} {toc no match}] false", + "ExecutePre select f1 from t where f1 = :f1 and toc = :toc [{f1 1} {toc }] false", + }) + assert.Equal(t, want, got) +} + +func TestRegionExperimentalCreateErrors(t *testing.T) { + _, err := createRegionVindex(t, "region_experimental", "f1,f2", 3) + assert.EqualError(t, err, "region_bits must be 1 or 2: 3") + _, err = CreateVindex("region_experimental", "region_experimental", nil) + assert.EqualError(t, err, "region_experimental missing region_bytes param") + _, err = createRegionVindex(t, "region_experimental", "f1", 2) + assert.EqualError(t, err, "two columns are required for region_experimental: [f1]") +} + +func createRegionVindex(t *testing.T, name, from string, rb int) (Vindex, error) { + return CreateVindex(name, name, map[string]string{ + "region_bytes": strconv.Itoa(rb), + "table": "t", + "from": from, + "to": "toc", + }) +} diff --git a/go/vt/vtgate/vindexes/reverse_bits.go b/go/vt/vtgate/vindexes/reverse_bits.go index fcc661d294d..9957988fe58 100644 --- a/go/vt/vtgate/vindexes/reverse_bits.go +++ b/go/vt/vtgate/vindexes/reverse_bits.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -59,11 +59,6 @@ func (vind *ReverseBits) IsUnique() bool { return true } -// IsFunctional returns true since the Vindex is functional. -func (vind *ReverseBits) IsFunctional() bool { - return true -} - // Map returns the corresponding KeyspaceId values for the given ids. func (vind *ReverseBits) Map(cursor VCursor, ids []sqltypes.Value) ([]key.Destination, error) { out := make([]key.Destination, len(ids)) diff --git a/go/vt/vtgate/vindexes/reverse_bits_test.go b/go/vt/vtgate/vindexes/reverse_bits_test.go index ca44242aaf6..bfd5a1c8b33 100644 --- a/go/vt/vtgate/vindexes/reverse_bits_test.go +++ b/go/vt/vtgate/vindexes/reverse_bits_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vtgate/vindexes/unicodeloosemd5.go b/go/vt/vtgate/vindexes/unicodeloosemd5.go index 1a0c63f4151..8264ebfe912 100644 --- a/go/vt/vtgate/vindexes/unicodeloosemd5.go +++ b/go/vt/vtgate/vindexes/unicodeloosemd5.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 @@ -62,11 +62,6 @@ func (vind *UnicodeLooseMD5) IsUnique() bool { return true } -// IsFunctional returns true since the Vindex is functional. -func (vind *UnicodeLooseMD5) IsFunctional() bool { - return true -} - // Verify returns true if ids maps to ksids. func (vind *UnicodeLooseMD5) Verify(_ VCursor, ids []sqltypes.Value, ksids [][]byte) ([]bool, error) { out := make([]bool, len(ids)) diff --git a/go/vt/vtgate/vindexes/unicodeloosemd5_test.go b/go/vt/vtgate/vindexes/unicodeloosemd5_test.go index a5b614dddff..9c51f178b1e 100644 --- a/go/vt/vtgate/vindexes/unicodeloosemd5_test.go +++ b/go/vt/vtgate/vindexes/unicodeloosemd5_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/vtgate/vindexes/vindex.go b/go/vt/vtgate/vindexes/vindex.go index 190a4c4481a..35ab8c853e2 100644 --- a/go/vt/vtgate/vindexes/vindex.go +++ b/go/vt/vtgate/vindexes/vindex.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -57,16 +57,6 @@ type Vindex interface { // Which means Map() maps to either a KeyRange or a single KeyspaceID. IsUnique() bool - // IsFunctional returns true if the Vindex can compute - // the keyspace id from the id without a lookup. - // A Functional vindex is also required to be Unique. - // Which means Map() maps to either a KeyRange or a single KeyspaceID. - IsFunctional() bool - - // Verify must be implented by all vindexes. It should return - // true if the ids can be mapped to the keyspace ids. - Verify(cursor VCursor, ids []sqltypes.Value, ksids [][]byte) ([]bool, error) - // Map can map ids to key.Destination objects. // If the Vindex is unique, each id would map to either // a KeyRange, or a single KeyspaceID. @@ -74,7 +64,18 @@ type Vindex interface { // a KeyRange, or a list of KeyspaceID. // If the error returned if nil, then the array len of the // key.Destination array must match len(ids). - Map(cursor VCursor, ids []sqltypes.Value) ([]key.Destination, error) + Map(vcursor VCursor, ids []sqltypes.Value) ([]key.Destination, error) + + // Verify must be implented by all vindexes. It should return + // true if the ids can be mapped to the keyspace ids. + Verify(vcursor VCursor, ids []sqltypes.Value, ksids [][]byte) ([]bool, error) +} + +// MultiColumn defines the interface for vindexes that can +// support multi-column vindexes. +type MultiColumn interface { + MapMulti(vcursor VCursor, rowsColValues [][]sqltypes.Value) ([]key.Destination, error) + VerifyMulti(vcursor VCursor, rowsColValues [][]sqltypes.Value, ksids [][]byte) ([]bool, error) } // A Reversible vindex is one that can perform a @@ -82,7 +83,7 @@ type Vindex interface { // is optional. If present, VTGate can use it to // fill column values based on the target keyspace id. type Reversible interface { - ReverseMap(cursor VCursor, ks [][]byte) ([]sqltypes.Value, error) + ReverseMap(vcursor VCursor, ks [][]byte) ([]sqltypes.Value, error) } // A Lookup vindex is one that needs to lookup @@ -138,3 +139,27 @@ func CreateVindex(vindexType, name string, params map[string]string) (Vindex, er } return f(name, params) } + +// Map invokes MapMulti or Map depending on which is available. +func Map(vindex Vindex, vcursor VCursor, rowsColValues [][]sqltypes.Value) ([]key.Destination, error) { + if multi, ok := vindex.(MultiColumn); ok { + return multi.MapMulti(vcursor, rowsColValues) + } + return vindex.Map(vcursor, firstColsOnly(rowsColValues)) +} + +// Verify invokes VerifyMulti or Verify depending on which is available. +func Verify(vindex Vindex, vcursor VCursor, rowsColValues [][]sqltypes.Value, ksids [][]byte) ([]bool, error) { + if multi, ok := vindex.(MultiColumn); ok { + return multi.VerifyMulti(vcursor, rowsColValues, ksids) + } + return vindex.Verify(vcursor, firstColsOnly(rowsColValues), ksids) +} + +func firstColsOnly(rowsColValues [][]sqltypes.Value) []sqltypes.Value { + firstCols := make([]sqltypes.Value, 0, len(rowsColValues)) + for _, val := range rowsColValues { + firstCols = append(firstCols, val[0]) + } + return firstCols +} diff --git a/go/vt/vtgate/vindexes/vindex_test.go b/go/vt/vtgate/vindexes/vindex_test.go new file mode 100644 index 00000000000..1c85f83a1fd --- /dev/null +++ b/go/vt/vtgate/vindexes/vindex_test.go @@ -0,0 +1,85 @@ +/* +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 vindexes + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "vitess.io/vitess/go/sqltypes" + "vitess.io/vitess/go/vt/key" +) + +func TestVindexMap(t *testing.T) { + ge, err := createRegionVindex(t, "region_experimental", "f1,f2", 1) + assert.NoError(t, err) + + got, err := Map(ge, nil, [][]sqltypes.Value{{ + sqltypes.NewInt64(1), sqltypes.NewInt64(1), + }}) + assert.NoError(t, err) + + want := []key.Destination{ + key.DestinationKeyspaceID([]byte("\x01\x16k@\xb4J\xbaK\xd6")), + } + assert.Equal(t, want, got) + + hash, err := CreateVindex("hash", "hash", nil) + assert.NoError(t, err) + got, err = Map(hash, nil, [][]sqltypes.Value{{ + sqltypes.NewInt64(1), + }}) + assert.NoError(t, err) + want = []key.Destination{ + key.DestinationKeyspaceID([]byte("\x16k@\xb4J\xbaK\xd6")), + } + assert.Equal(t, want, got) +} + +func TestVindexVerify(t *testing.T) { + vc := &loggingVCursor{} + vc.AddResult(makeTestResult(1), nil) + ge, err := createRegionVindex(t, "region_experimental", "f1,f2", 1) + assert.NoError(t, err) + + got, err := Verify(ge, vc, [][]sqltypes.Value{{ + sqltypes.NewInt64(1), sqltypes.NewInt64(1), + }}, + [][]byte{ + []byte("\x01\x16k@\xb4J\xbaK\xd6"), + }, + ) + assert.NoError(t, err) + vc.verifyLog(t, []string{ + "ExecutePre select f1 from t where f1 = :f1 and toc = :toc [{f1 1} {toc \x01\x16k@\xb4J\xbaK\xd6}] false", + }) + + want := []bool{true} + assert.Equal(t, want, got) + + hash, err := CreateVindex("hash", "hash", nil) + assert.NoError(t, err) + got, err = Verify(hash, nil, [][]sqltypes.Value{{ + sqltypes.NewInt64(1), + }}, + [][]byte{ + []byte("\x16k@\xb4J\xbaK\xd6"), + }, + ) + assert.NoError(t, err) + assert.Equal(t, want, got) +} diff --git a/go/vt/vtgate/vindexes/vschema.go b/go/vt/vtgate/vindexes/vschema.go index 3cf5c9a2bb4..8f519fb7093 100644 --- a/go/vt/vtgate/vindexes/vschema.go +++ b/go/vt/vtgate/vindexes/vschema.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -224,10 +224,14 @@ func buildTables(ks *vschemapb.Keyspace, vschema *VSchema, ksvschema *KeyspaceSc if err != nil { return err } - if _, ok := vschema.uniqueVindexes[vname]; ok { - vschema.uniqueVindexes[vname] = nil - } else { - vschema.uniqueVindexes[vname] = vindex + + // If the keyspace requires explicit routing, don't include it in global routing + if !ks.RequireExplicitRouting { + if _, ok := vschema.uniqueVindexes[vname]; ok { + vschema.uniqueVindexes[vname] = nil + } else { + vschema.uniqueVindexes[vname] = vindex + } } ksvschema.Vindexes[vname] = vindex } @@ -309,9 +313,6 @@ func buildTables(ks *vschemapb.Keyspace, vschema *VSchema, ksvschema *KeyspaceSc if !columnVindex.Vindex.IsUnique() { return fmt.Errorf("primary vindex %s is not Unique for table %s", ind.Name, tname) } - if owned { - return fmt.Errorf("primary vindex %s cannot be owned for table %s", ind.Name, tname) - } } t.ColumnVindexes = append(t.ColumnVindexes, columnVindex) if owned { @@ -326,10 +327,13 @@ func buildTables(ks *vschemapb.Keyspace, vschema *VSchema, ksvschema *KeyspaceSc t.Ordered = colVindexSorted(t.ColumnVindexes) // Add the table to the map entries. - if _, ok := vschema.uniqueTables[tname]; ok { - vschema.uniqueTables[tname] = nil - } else { - vschema.uniqueTables[tname] = t + // If the keyspace requires explicit routing, don't include it in global routing + if !ks.RequireExplicitRouting { + if _, ok := vschema.uniqueTables[tname]; ok { + vschema.uniqueTables[tname] = nil + } else { + vschema.uniqueTables[tname] = t + } } ksvschema.Tables[tname] = t } @@ -363,9 +367,7 @@ func addDual(vschema *VSchema) { t := &Table{ Name: sqlparser.NewTableIdent("dual"), Keyspace: ks.Keyspace, - } - if ks.Keyspace.Sharded { - t.Pinned = []byte{0} + Type: TypeReference, } ks.Tables["dual"] = t if first == "" || first > ksname { diff --git a/go/vt/vtgate/vindexes/vschema_test.go b/go/vt/vtgate/vindexes/vschema_test.go index 38045cd05ad..200636c2388 100644 --- a/go/vt/vtgate/vindexes/vschema_test.go +++ b/go/vt/vtgate/vindexes/vschema_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -45,7 +45,6 @@ type stFU struct { func (v *stFU) String() string { return v.name } func (*stFU) Cost() int { return 1 } func (*stFU) IsUnique() bool { return true } -func (*stFU) IsFunctional() bool { return true } func (*stFU) Verify(VCursor, []sqltypes.Value, [][]byte) ([]bool, error) { return []bool{}, nil } func (*stFU) Map(cursor VCursor, ids []sqltypes.Value) ([]key.Destination, error) { return nil, nil } @@ -64,7 +63,6 @@ type stLN struct { func (v *stLN) String() string { return v.name } func (*stLN) Cost() int { return 0 } func (*stLN) IsUnique() bool { return false } -func (*stLN) IsFunctional() bool { return false } func (*stLN) Verify(VCursor, []sqltypes.Value, [][]byte) ([]bool, error) { return []bool{}, nil } func (*stLN) Map(cursor VCursor, ids []sqltypes.Value) ([]key.Destination, error) { return nil, nil } func (*stLN) Create(VCursor, [][]sqltypes.Value, [][]byte, bool) error { return nil } @@ -87,7 +85,6 @@ type stLU struct { func (v *stLU) String() string { return v.name } func (*stLU) Cost() int { return 2 } func (*stLU) IsUnique() bool { return true } -func (*stLU) IsFunctional() bool { return false } func (*stLU) Verify(VCursor, []sqltypes.Value, [][]byte) ([]bool, error) { return []bool{}, nil } func (*stLU) Map(cursor VCursor, ids []sqltypes.Value) ([]key.Destination, error) { return nil, nil } func (*stLU) Create(VCursor, [][]sqltypes.Value, [][]byte, bool) error { return nil } @@ -113,7 +110,6 @@ type stLO struct { func (v *stLO) String() string { return v.name } func (*stLO) Cost() int { return 2 } func (*stLO) IsUnique() bool { return true } -func (*stLO) IsFunctional() bool { return false } func (*stLO) Verify(VCursor, []sqltypes.Value, [][]byte) ([]bool, error) { return []bool{}, nil } func (*stLO) Map(cursor VCursor, ids []sqltypes.Value) ([]key.Destination, error) { return nil, nil } func (*stLO) Create(VCursor, [][]sqltypes.Value, [][]byte, bool) error { return nil } @@ -176,6 +172,7 @@ func TestUnshardedVSchema(t *testing.T) { dual := &Table{ Name: sqlparser.NewTableIdent("dual"), Keyspace: ks, + Type: TypeReference, } want := &VSchema{ RoutingRules: map[string]*RoutingRule{}, @@ -239,6 +236,7 @@ func TestVSchemaColumns(t *testing.T) { dual := &Table{ Name: sqlparser.NewTableIdent("dual"), Keyspace: ks, + Type: TypeReference, } want := &VSchema{ RoutingRules: map[string]*RoutingRule{}, @@ -305,6 +303,7 @@ func TestVSchemaColumnListAuthoritative(t *testing.T) { dual := &Table{ Name: sqlparser.NewTableIdent("dual"), Keyspace: ks, + Type: TypeReference, } want := &VSchema{ RoutingRules: map[string]*RoutingRule{}, @@ -385,7 +384,7 @@ func TestVSchemaPinned(t *testing.T) { dual := &Table{ Name: sqlparser.NewTableIdent("dual"), Keyspace: ks, - Pinned: []byte{0}, + Type: TypeReference, } want := &VSchema{ RoutingRules: map[string]*RoutingRule{}, @@ -489,7 +488,7 @@ func TestShardedVSchemaOwned(t *testing.T) { dual := &Table{ Name: sqlparser.NewTableIdent("dual"), Keyspace: ks, - Pinned: []byte{0}, + Type: TypeReference, } want := &VSchema{ RoutingRules: map[string]*RoutingRule{}, @@ -706,11 +705,12 @@ func TestVSchemaRoutingRules(t *testing.T) { dual1 := &Table{ Name: sqlparser.NewTableIdent("dual"), Keyspace: ks1, - Pinned: []byte{0}, + Type: TypeReference, } dual2 := &Table{ Name: sqlparser.NewTableIdent("dual"), Keyspace: ks2, + Type: TypeReference, } want := &VSchema{ RoutingRules: map[string]*RoutingRule{ @@ -948,7 +948,7 @@ func TestShardedVSchemaMultiColumnVindex(t *testing.T) { dual := &Table{ Name: sqlparser.NewTableIdent("dual"), Keyspace: ks, - Pinned: []byte{0}, + Type: TypeReference, } want := &VSchema{ RoutingRules: map[string]*RoutingRule{}, @@ -1048,7 +1048,7 @@ func TestShardedVSchemaNotOwned(t *testing.T) { dual := &Table{ Name: sqlparser.NewTableIdent("dual"), Keyspace: ks, - Pinned: []byte{0}, + Type: TypeReference, } want := &VSchema{ RoutingRules: map[string]*RoutingRule{}, @@ -1175,10 +1175,12 @@ func TestBuildVSchemaDupSeq(t *testing.T) { duala := &Table{ Name: sqlparser.NewTableIdent("dual"), Keyspace: ksa, + Type: TypeReference, } dualb := &Table{ Name: sqlparser.NewTableIdent("dual"), Keyspace: ksb, + Type: TypeReference, } want := &VSchema{ RoutingRules: map[string]*RoutingRule{}, @@ -1246,10 +1248,12 @@ func TestBuildVSchemaDupTable(t *testing.T) { duala := &Table{ Name: sqlparser.NewTableIdent("dual"), Keyspace: ksa, + Type: TypeReference, } dualb := &Table{ Name: sqlparser.NewTableIdent("dual"), Keyspace: ksb, + Type: TypeReference, } want := &VSchema{ RoutingRules: map[string]*RoutingRule{}, @@ -1380,12 +1384,12 @@ func TestBuildVSchemaDupVindex(t *testing.T) { duala := &Table{ Name: sqlparser.NewTableIdent("dual"), Keyspace: ksa, - Pinned: []byte{0}, + Type: TypeReference, } dualb := &Table{ Name: sqlparser.NewTableIdent("dual"), Keyspace: ksb, - Pinned: []byte{0}, + Type: TypeReference, } want := &VSchema{ RoutingRules: map[string]*RoutingRule{}, @@ -1550,38 +1554,6 @@ func TestBuildVSchemaNotUniqueFail(t *testing.T) { } } -func TestBuildVSchemaPrimaryNonFunctionalFail(t *testing.T) { - bad := vschemapb.SrvVSchema{ - Keyspaces: map[string]*vschemapb.Keyspace{ - "sharded": { - Sharded: true, - Vindexes: map[string]*vschemapb.Vindex{ - "stlu": { - Type: "stlu", - Owner: "t1", - }, - }, - Tables: map[string]*vschemapb.Table{ - "t1": { - ColumnVindexes: []*vschemapb.ColumnVindex{ - { - Column: "c1", - Name: "stlu", - }, - }, - }, - }, - }, - }, - } - got, _ := BuildVSchema(&bad) - err := got.Keyspaces["sharded"].Error - want := "primary vindex stlu cannot be owned for table t1" - if err == nil || err.Error() != want { - t.Errorf("BuildVSchema: %v, want %v", err, want) - } -} - func TestSequence(t *testing.T) { good := vschemapb.SrvVSchema{ Keyspaces: map[string]*vschemapb.Keyspace{ @@ -1699,11 +1671,12 @@ func TestSequence(t *testing.T) { duala := &Table{ Name: sqlparser.NewTableIdent("dual"), Keyspace: ksu, + Type: TypeReference, } dualb := &Table{ Name: sqlparser.NewTableIdent("dual"), Keyspace: kss, - Pinned: []byte{0}, + Type: TypeReference, } want := &VSchema{ RoutingRules: map[string]*RoutingRule{}, diff --git a/go/vt/vtgate/vschema_manager.go b/go/vt/vtgate/vschema_manager.go index d99d440813b..45d8b61f613 100644 --- a/go/vt/vtgate/vschema_manager.go +++ b/go/vt/vtgate/vschema_manager.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vtgate/vschema_stats.go b/go/vt/vtgate/vschema_stats.go index adc1fd897ec..8e7126ca1d6 100644 --- a/go/vt/vtgate/vschema_stats.go +++ b/go/vt/vtgate/vschema_stats.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vtgate/vschemaacl/vschemaacl.go b/go/vt/vtgate/vschemaacl/vschemaacl.go index 92fc6daa69d..c7080478a32 100644 --- a/go/vt/vtgate/vschemaacl/vschemaacl.go +++ b/go/vt/vtgate/vschemaacl/vschemaacl.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Vitess Authors. +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. diff --git a/go/vt/vtgate/vschemaacl/vschemaacl_test.go b/go/vt/vtgate/vschemaacl/vschemaacl_test.go index f4644aef213..3486702ac56 100644 --- a/go/vt/vtgate/vschemaacl/vschemaacl_test.go +++ b/go/vt/vtgate/vschemaacl/vschemaacl_test.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Vitess Authors. +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. diff --git a/go/vt/vtgate/vtgate.go b/go/vt/vtgate/vtgate.go index 5b5094d9626..1f2c8e418f3 100644 --- a/go/vt/vtgate/vtgate.go +++ b/go/vt/vtgate/vtgate.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -331,7 +331,7 @@ func (vtg *VTGate) ExecuteBatch(ctx context.Context, session *vtgatepb.Session, // StreamExecute executes a streaming query. This is a V3 function. // Note we guarantee the callback will not be called concurrently -// by mutiple go routines. +// by multiple go routines. func (vtg *VTGate) StreamExecute(ctx context.Context, session *vtgatepb.Session, sql string, bindVariables map[string]*querypb.BindVariable, callback func(*sqltypes.Result) error) error { // In this context, we don't care if we can't fully parse destination destKeyspace, destTabletType, dest, _ := vtg.executor.ParseDestinationTarget(session.TargetString) @@ -663,7 +663,7 @@ handleError: // response which is needed for checkpointing. // The api supports supplying multiple KeyspaceIds to make it future proof. This is a legacy function. // Note we guarantee the callback will not be called concurrently -// by mutiple go routines. +// by multiple go routines. func (vtg *VTGate) StreamExecuteKeyspaceIds(ctx context.Context, sql string, bindVariables map[string]*querypb.BindVariable, keyspace string, keyspaceIds [][]byte, tabletType topodatapb.TabletType, options *querypb.ExecuteOptions, callback func(*sqltypes.Result) error) error { startTime := time.Now() ltt := topoproto.TabletTypeLString(tabletType) @@ -712,7 +712,7 @@ handleError: // response which is needed for checkpointing. // The api supports supplying multiple keyranges to make it future proof. This is a legacy function. // Note we guarantee the callback will not be called concurrently -// by mutiple go routines. +// by multiple go routines. func (vtg *VTGate) StreamExecuteKeyRanges(ctx context.Context, sql string, bindVariables map[string]*querypb.BindVariable, keyspace string, keyRanges []*topodatapb.KeyRange, tabletType topodatapb.TabletType, options *querypb.ExecuteOptions, callback func(*sqltypes.Result) error) error { startTime := time.Now() ltt := topoproto.TabletTypeLString(tabletType) @@ -756,7 +756,7 @@ handleError: // StreamExecuteShards executes a streaming query on the specified shards. This is a legacy function. // Note we guarantee the callback will not be called concurrently -// by mutiple go routines. +// by multiple go routines. func (vtg *VTGate) StreamExecuteShards(ctx context.Context, sql string, bindVariables map[string]*querypb.BindVariable, keyspace string, shards []string, tabletType topodatapb.TabletType, options *querypb.ExecuteOptions, callback func(*sqltypes.Result) error) error { startTime := time.Now() ltt := topoproto.TabletTypeLString(tabletType) @@ -973,7 +973,7 @@ func (vtg *VTGate) GetSrvKeyspace(ctx context.Context, keyspace string) (*topoda // MessageStream is part of the vtgate service API. This is a V2 level API // that's sent to the Resolver. // Note we guarantee the callback will not be called concurrently -// by mutiple go routines. +// by multiple go routines. func (vtg *VTGate) MessageStream(ctx context.Context, keyspace string, shard string, keyRange *topodatapb.KeyRange, name string, callback func(*sqltypes.Result) error) error { startTime := time.Now() ltt := topoproto.TabletTypeLString(topodatapb.TabletType_MASTER) @@ -1041,7 +1041,7 @@ func (vtg *VTGate) MessageAckKeyspaceIds(ctx context.Context, keyspace string, n // UpdateStream is part of the vtgate service API. // Note we guarantee the callback will not be called concurrently -// by mutiple go routines, as the current implementation can only target +// by multiple go routines, as the current implementation can only target // one shard. func (vtg *VTGate) UpdateStream(ctx context.Context, keyspace string, shard string, keyRange *topodatapb.KeyRange, tabletType topodatapb.TabletType, timestamp int64, event *querypb.EventToken, callback func(*querypb.StreamEvent, int64) error) error { startTime := time.Now() diff --git a/go/vt/vtgate/vtgate_test.go b/go/vt/vtgate/vtgate_test.go index 8a80936666b..9d66ae2233c 100644 --- a/go/vt/vtgate/vtgate_test.go +++ b/go/vt/vtgate/vtgate_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vtgate/vtgateconn/vtgateconn.go b/go/vt/vtgate/vtgateconn/vtgateconn.go index f398bce9db4..81c6cb74bf7 100644 --- a/go/vt/vtgate/vtgateconn/vtgateconn.go +++ b/go/vt/vtgate/vtgateconn/vtgateconn.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vtgate/vtgateconn/vtgateconn_test.go b/go/vt/vtgate/vtgateconn/vtgateconn_test.go index a8eb7b34a12..9d0e8e7b99b 100644 --- a/go/vt/vtgate/vtgateconn/vtgateconn_test.go +++ b/go/vt/vtgate/vtgateconn/vtgateconn_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vtgate/vtgateconntest/client.go b/go/vt/vtgate/vtgateconntest/client.go index 313b7e30240..f6f0ab9325c 100644 --- a/go/vt/vtgate/vtgateconntest/client.go +++ b/go/vt/vtgate/vtgateconntest/client.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vtgate/vtgateservice/interface.go b/go/vt/vtgate/vtgateservice/interface.go index b3e806c48e5..69f14553804 100644 --- a/go/vt/vtgate/vtgateservice/interface.go +++ b/go/vt/vtgate/vtgateservice/interface.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vtqueryserver/endtoend_test.go b/go/vt/vtqueryserver/endtoend_test.go index fce6827ccc9..4e981967a02 100644 --- a/go/vt/vtqueryserver/endtoend_test.go +++ b/go/vt/vtqueryserver/endtoend_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vtqueryserver/plugin_mysql_server.go b/go/vt/vtqueryserver/plugin_mysql_server.go index a900472d6bf..189eddbe6fa 100644 --- a/go/vt/vtqueryserver/plugin_mysql_server.go +++ b/go/vt/vtqueryserver/plugin_mysql_server.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 @@ -86,6 +86,10 @@ func (mh *proxyHandler) ConnectionClosed(c *mysql.Conn) { } } +func (mh *proxyHandler) ComInitDB(c *mysql.Conn, schemaName string) { + mh.session(c).TargetString = schemaName +} + func (mh *proxyHandler) ComQuery(c *mysql.Conn, query string, callback func(*sqltypes.Result) error) error { var ctx context.Context var cancel context.CancelFunc @@ -107,23 +111,8 @@ func (mh *proxyHandler) ComQuery(c *mysql.Conn, query string, callback func(*sql "mysqlproxy MySQL Connector" /* subcomponent: part of the client */) ctx = callerid.NewContext(ctx, ef, im) - session, _ := c.ClientData.(*mysqlproxy.ProxySession) - if session == nil { - session = &mysqlproxy.ProxySession{ - Options: &querypb.ExecuteOptions{ - IncludedFields: querypb.ExecuteOptions_ALL, - }, - Autocommit: true, - } - if c.Capabilities&mysql.CapabilityClientFoundRows != 0 { - session.Options.ClientFoundRows = true - } - } - if c.SchemaName != "" { - session.TargetString = c.SchemaName - } + session := mh.session(c) session, result, err := mh.mp.Execute(ctx, session, query, make(map[string]*querypb.BindVariable)) - c.ClientData = session err = mysql.NewSQLErrorFromError(err) if err != nil { return err @@ -144,6 +133,26 @@ func (mh *proxyHandler) ComStmtExecute(c *mysql.Conn, prepare *mysql.PrepareData return nil } +func (mh *proxyHandler) ComResetConnection(c *mysql.Conn) { +} + +func (mh *proxyHandler) session(c *mysql.Conn) *mysqlproxy.ProxySession { + session, _ := c.ClientData.(*mysqlproxy.ProxySession) + if session == nil { + session = &mysqlproxy.ProxySession{ + Options: &querypb.ExecuteOptions{ + IncludedFields: querypb.ExecuteOptions_ALL, + }, + Autocommit: true, + } + if c.Capabilities&mysql.CapabilityClientFoundRows != 0 { + session.Options.ClientFoundRows = true + } + c.ClientData = session + } + return session +} + var mysqlListener *mysql.Listener var mysqlUnixListener *mysql.Listener diff --git a/go/vt/vtqueryserver/plugin_mysql_server_test.go b/go/vt/vtqueryserver/plugin_mysql_server_test.go index 6c538b80a37..646eac5687c 100644 --- a/go/vt/vtqueryserver/plugin_mysql_server_test.go +++ b/go/vt/vtqueryserver/plugin_mysql_server_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 @@ -40,6 +40,9 @@ func (th *testHandler) NewConnection(c *mysql.Conn) { func (th *testHandler) ConnectionClosed(c *mysql.Conn) { } +func (th *testHandler) ComInitDB(c *mysql.Conn, schemaName string) { +} + func (th *testHandler) ComQuery(c *mysql.Conn, q string, callback func(*sqltypes.Result) error) error { return nil } @@ -52,6 +55,10 @@ func (th *testHandler) ComStmtExecute(c *mysql.Conn, prepare *mysql.PrepareData, return nil } +func (th *testHandler) ComResetConnection(c *mysql.Conn) { + +} + func (th *testHandler) WarningCount(c *mysql.Conn) uint16 { return 0 } diff --git a/go/vt/vtqueryserver/status.go b/go/vt/vtqueryserver/status.go index ffd09dda370..42db438f351 100644 --- a/go/vt/vtqueryserver/status.go +++ b/go/vt/vtqueryserver/status.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/vtqueryserver/vtqueryserver.go b/go/vt/vtqueryserver/vtqueryserver.go index b300c463130..66b9c4b6038 100644 --- a/go/vt/vtqueryserver/vtqueryserver.go +++ b/go/vt/vtqueryserver/vtqueryserver.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vttablet/agentrpctest/test_agent_rpc.go b/go/vt/vttablet/agentrpctest/test_agent_rpc.go index 5632b66ae01..de059c9ee5c 100644 --- a/go/vt/vttablet/agentrpctest/test_agent_rpc.go +++ b/go/vt/vttablet/agentrpctest/test_agent_rpc.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -728,6 +728,10 @@ func (fra *fakeRPCAgent) MasterPosition(ctx context.Context) (string, error) { return testReplicationPosition, nil } +func (fra *fakeRPCAgent) WaitForPosition(ctx context.Context, pos string) error { + panic("unimplemented") +} + func agentRPCTestMasterPosition(ctx context.Context, t *testing.T, client tmclient.TabletManagerClient, tablet *topodatapb.Tablet) { rs, err := client.MasterPosition(ctx, tablet) compareError(t, "MasterPosition", err, rs, testReplicationPosition) @@ -940,6 +944,7 @@ func agentRPCTestInitMasterPanic(ctx context.Context, t *testing.T, client tmcli var testPopulateReparentJournalCalled = false var testTimeCreatedNS int64 = 4569900 +var testWaitPosition string = "test wait position" var testActionName = "TestActionName" var testMasterAlias = &topodatapb.TabletAlias{ Cell: "ce", @@ -1071,24 +1076,25 @@ func agentRPCTestSlaveWasPromotedPanic(ctx context.Context, t *testing.T, client var testSetMasterCalled = false var testForceStartSlave = true -func (fra *fakeRPCAgent) SetMaster(ctx context.Context, parent *topodatapb.TabletAlias, timeCreatedNS int64, forceStartSlave bool) error { +func (fra *fakeRPCAgent) SetMaster(ctx context.Context, parent *topodatapb.TabletAlias, timeCreatedNS int64, waitPosition string, forceStartSlave bool) error { if fra.panics { panic(fmt.Errorf("test-triggered panic")) } compare(fra.t, "SetMaster parent", parent, testMasterAlias) compare(fra.t, "SetMaster timeCreatedNS", timeCreatedNS, testTimeCreatedNS) + compare(fra.t, "SetMaster waitPosition", waitPosition, testWaitPosition) compare(fra.t, "SetMaster forceStartSlave", forceStartSlave, testForceStartSlave) testSetMasterCalled = true return nil } func agentRPCTestSetMaster(ctx context.Context, t *testing.T, client tmclient.TabletManagerClient, tablet *topodatapb.Tablet) { - err := client.SetMaster(ctx, tablet, testMasterAlias, testTimeCreatedNS, testForceStartSlave) + err := client.SetMaster(ctx, tablet, testMasterAlias, testTimeCreatedNS, testWaitPosition, testForceStartSlave) compareError(t, "SetMaster", err, true, testSetMasterCalled) } func agentRPCTestSetMasterPanic(ctx context.Context, t *testing.T, client tmclient.TabletManagerClient, tablet *topodatapb.Tablet) { - err := client.SetMaster(ctx, tablet, testMasterAlias, testTimeCreatedNS, testForceStartSlave) + err := client.SetMaster(ctx, tablet, testMasterAlias, testTimeCreatedNS, testWaitPosition, testForceStartSlave) expectHandleRPCPanic(t, "SetMaster", true /*verbose*/, err) } diff --git a/go/vt/vttablet/customrule/filecustomrule/filecustomrule.go b/go/vt/vttablet/customrule/filecustomrule/filecustomrule.go index f19e5bcfb2d..caa35a9a998 100644 --- a/go/vt/vttablet/customrule/filecustomrule/filecustomrule.go +++ b/go/vt/vttablet/customrule/filecustomrule/filecustomrule.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vttablet/customrule/filecustomrule/filecustomrule_test.go b/go/vt/vttablet/customrule/filecustomrule/filecustomrule_test.go index 7ef9c5ac2b3..b1162a4c9c0 100644 --- a/go/vt/vttablet/customrule/filecustomrule/filecustomrule_test.go +++ b/go/vt/vttablet/customrule/filecustomrule/filecustomrule_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vttablet/customrule/topocustomrule/topocustomrule.go b/go/vt/vttablet/customrule/topocustomrule/topocustomrule.go index aa355a96cfe..bd6966e8d7e 100644 --- a/go/vt/vttablet/customrule/topocustomrule/topocustomrule.go +++ b/go/vt/vttablet/customrule/topocustomrule/topocustomrule.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vttablet/customrule/topocustomrule/topocustomrule_test.go b/go/vt/vttablet/customrule/topocustomrule/topocustomrule_test.go index 748b64173be..2f7090e5450 100644 --- a/go/vt/vttablet/customrule/topocustomrule/topocustomrule_test.go +++ b/go/vt/vttablet/customrule/topocustomrule/topocustomrule_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vttablet/endtoend/acl_test.go b/go/vt/vttablet/endtoend/acl_test.go index 16700931128..f86229fea5f 100644 --- a/go/vt/vttablet/endtoend/acl_test.go +++ b/go/vt/vttablet/endtoend/acl_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vttablet/endtoend/batch_test.go b/go/vt/vttablet/endtoend/batch_test.go index e8338d369c9..40118d1e6c0 100644 --- a/go/vt/vttablet/endtoend/batch_test.go +++ b/go/vt/vttablet/endtoend/batch_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vttablet/endtoend/compatibility_test.go b/go/vt/vttablet/endtoend/compatibility_test.go index 1bf90904633..31974eaf841 100644 --- a/go/vt/vttablet/endtoend/compatibility_test.go +++ b/go/vt/vttablet/endtoend/compatibility_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vttablet/endtoend/config_test.go b/go/vt/vttablet/endtoend/config_test.go index cb47068c47d..74828da4fa6 100644 --- a/go/vt/vttablet/endtoend/config_test.go +++ b/go/vt/vttablet/endtoend/config_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -51,9 +51,6 @@ func TestConfigVars(t *testing.T) { tag string val int }{{ - tag: "BeginTimeout", - val: int(tabletenv.Config.TxPoolTimeout * 1e9), - }, { tag: "ConnPoolAvailable", val: tabletenv.Config.PoolSize, }, { @@ -115,6 +112,9 @@ func TestConfigVars(t *testing.T) { val: tabletenv.Config.TransactionCap, }, { tag: "TransactionPoolTimeout", + val: int(tabletenv.Config.TxPoolTimeout * 1e9), + }, { + tag: "TransactionTimeout", val: int(tabletenv.Config.TransactionTimeout * 1e9), }} for _, tcase := range cases { diff --git a/go/vt/vttablet/endtoend/endtoend.go b/go/vt/vttablet/endtoend/endtoend.go index e259d286406..34979356639 100644 --- a/go/vt/vttablet/endtoend/endtoend.go +++ b/go/vt/vttablet/endtoend/endtoend.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vttablet/endtoend/framework/client.go b/go/vt/vttablet/endtoend/framework/client.go index a590e08bad7..bb494440a80 100644 --- a/go/vt/vttablet/endtoend/framework/client.go +++ b/go/vt/vttablet/endtoend/framework/client.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vttablet/endtoend/framework/debugschema.go b/go/vt/vttablet/endtoend/framework/debugschema.go index d2ba0c7be14..7964832882d 100644 --- a/go/vt/vttablet/endtoend/framework/debugschema.go +++ b/go/vt/vttablet/endtoend/framework/debugschema.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vttablet/endtoend/framework/debugvars.go b/go/vt/vttablet/endtoend/framework/debugvars.go index 9de8b95a885..e107b15d839 100644 --- a/go/vt/vttablet/endtoend/framework/debugvars.go +++ b/go/vt/vttablet/endtoend/framework/debugvars.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vttablet/endtoend/framework/eventcatcher.go b/go/vt/vttablet/endtoend/framework/eventcatcher.go index 3465bce8e88..3579709b807 100644 --- a/go/vt/vttablet/endtoend/framework/eventcatcher.go +++ b/go/vt/vttablet/endtoend/framework/eventcatcher.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vttablet/endtoend/framework/querystats.go b/go/vt/vttablet/endtoend/framework/querystats.go index 028c67295e1..e1ad29f7cd3 100644 --- a/go/vt/vttablet/endtoend/framework/querystats.go +++ b/go/vt/vttablet/endtoend/framework/querystats.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vttablet/endtoend/framework/server.go b/go/vt/vttablet/endtoend/framework/server.go index d267c231f41..707a2f9db67 100644 --- a/go/vt/vttablet/endtoend/framework/server.go +++ b/go/vt/vttablet/endtoend/framework/server.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vttablet/endtoend/framework/streamqueryz.go b/go/vt/vttablet/endtoend/framework/streamqueryz.go index 8fee1033c2a..b3d33a2c0bb 100644 --- a/go/vt/vttablet/endtoend/framework/streamqueryz.go +++ b/go/vt/vttablet/endtoend/framework/streamqueryz.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vttablet/endtoend/framework/testcase.go b/go/vt/vttablet/endtoend/framework/testcase.go index 765e8ca0ec5..61ec7713034 100644 --- a/go/vt/vttablet/endtoend/framework/testcase.go +++ b/go/vt/vttablet/endtoend/framework/testcase.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vttablet/endtoend/main_test.go b/go/vt/vttablet/endtoend/main_test.go index 8bba8fc6db7..1dda49412ba 100644 --- a/go/vt/vttablet/endtoend/main_test.go +++ b/go/vt/vttablet/endtoend/main_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vttablet/endtoend/message_test.go b/go/vt/vttablet/endtoend/message_test.go index 6a908c3582d..a6d3f768cf4 100644 --- a/go/vt/vttablet/endtoend/message_test.go +++ b/go/vt/vttablet/endtoend/message_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vttablet/endtoend/metadata_test.go b/go/vt/vttablet/endtoend/metadata_test.go index a010350f421..dc39ec3f239 100644 --- a/go/vt/vttablet/endtoend/metadata_test.go +++ b/go/vt/vttablet/endtoend/metadata_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/vttablet/endtoend/misc_test.go b/go/vt/vttablet/endtoend/misc_test.go index 39af7ba1675..f58e900e3b5 100644 --- a/go/vt/vttablet/endtoend/misc_test.go +++ b/go/vt/vttablet/endtoend/misc_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vttablet/endtoend/queries_test.go b/go/vt/vttablet/endtoend/queries_test.go index f407e08b91f..55fd20561e8 100644 --- a/go/vt/vttablet/endtoend/queries_test.go +++ b/go/vt/vttablet/endtoend/queries_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vttablet/endtoend/sequence_test.go b/go/vt/vttablet/endtoend/sequence_test.go index 80cabfbc190..f779aaf47f1 100644 --- a/go/vt/vttablet/endtoend/sequence_test.go +++ b/go/vt/vttablet/endtoend/sequence_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vttablet/endtoend/stream_test.go b/go/vt/vttablet/endtoend/stream_test.go index 0d4e22f0c1b..d9c374412ba 100644 --- a/go/vt/vttablet/endtoend/stream_test.go +++ b/go/vt/vttablet/endtoend/stream_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vttablet/endtoend/transaction_test.go b/go/vt/vttablet/endtoend/transaction_test.go index ae15d5da92d..691e474e9c7 100644 --- a/go/vt/vttablet/endtoend/transaction_test.go +++ b/go/vt/vttablet/endtoend/transaction_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -329,9 +329,6 @@ func TestTxPoolSize(t *testing.T) { defer framework.Server.SetTxPoolSize(framework.Server.TxPoolSize()) framework.Server.SetTxPoolSize(1) - defer framework.Server.BeginTimeout.Set(framework.Server.BeginTimeout.Get()) - timeout := 1 * time.Millisecond - framework.Server.BeginTimeout.Set(timeout) vend := framework.DebugVars() if err := verifyIntValue(vend, "TransactionPoolAvailable", 0); err != nil { t.Error(err) @@ -339,9 +336,6 @@ func TestTxPoolSize(t *testing.T) { if err := verifyIntValue(vend, "TransactionPoolCapacity", 1); err != nil { t.Error(err) } - if err := verifyIntValue(vend, "BeginTimeout", int(timeout)); err != nil { - t.Error(err) - } client2 := framework.NewClient() err = client2.Begin(false) @@ -358,8 +352,16 @@ func TestTxTimeout(t *testing.T) { vstart := framework.DebugVars() defer framework.Server.SetTxTimeout(framework.Server.TxTimeout()) - framework.Server.SetTxTimeout(1 * time.Millisecond) - if err := verifyIntValue(framework.DebugVars(), "TransactionPoolTimeout", int(1*time.Millisecond)); err != nil { + txTimeout := 1 * time.Millisecond + framework.Server.SetTxTimeout(txTimeout) + if err := verifyIntValue(framework.DebugVars(), "TransactionTimeout", int(txTimeout)); err != nil { + t.Error(err) + } + + defer framework.Server.SetTxPoolTimeout(framework.Server.TxPoolTimeout()) + txPoolTimeout := 2 * time.Millisecond + framework.Server.SetTxPoolTimeout(txPoolTimeout) + if err := verifyIntValue(framework.DebugVars(), "TransactionPoolTimeout", int(txPoolTimeout)); err != nil { t.Error(err) } diff --git a/go/vt/vttablet/faketmclient/fake_client.go b/go/vt/vttablet/faketmclient/fake_client.go index 64c27104051..60658787f72 100644 --- a/go/vt/vttablet/faketmclient/fake_client.go +++ b/go/vt/vttablet/faketmclient/fake_client.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -181,6 +181,11 @@ func (client *FakeTabletManagerClient) MasterPosition(ctx context.Context, table return "", nil } +// WaitForPosition is part of the tmclient.TabletManagerClient interface. +func (client *FakeTabletManagerClient) WaitForPosition(ctx context.Context, tablet *topodatapb.Tablet, pos string) error { + return nil +} + // StopSlave is part of the tmclient.TabletManagerClient interface. func (client *FakeTabletManagerClient) StopSlave(ctx context.Context, tablet *topodatapb.Tablet) error { return nil @@ -271,7 +276,7 @@ func (client *FakeTabletManagerClient) SlaveWasPromoted(ctx context.Context, tab } // SetMaster is part of the tmclient.TabletManagerClient interface. -func (client *FakeTabletManagerClient) SetMaster(ctx context.Context, tablet *topodatapb.Tablet, parent *topodatapb.TabletAlias, timeCreatedNS int64, forceStartSlave bool) error { +func (client *FakeTabletManagerClient) SetMaster(ctx context.Context, tablet *topodatapb.Tablet, parent *topodatapb.TabletAlias, timeCreatedNS int64, waitPosition string, forceStartSlave bool) error { return nil } diff --git a/go/vt/vttablet/filelogger/filelogger.go b/go/vt/vttablet/filelogger/filelogger.go index 19421486136..77feaf71cec 100644 --- a/go/vt/vttablet/filelogger/filelogger.go +++ b/go/vt/vttablet/filelogger/filelogger.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/vttablet/filelogger/filelogger_test.go b/go/vt/vttablet/filelogger/filelogger_test.go index a9f89bbf6a1..b952496cc3b 100644 --- a/go/vt/vttablet/filelogger/filelogger_test.go +++ b/go/vt/vttablet/filelogger/filelogger_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/vttablet/grpcqueryservice/server.go b/go/vt/vttablet/grpcqueryservice/server.go index d0f55351516..7e56b983926 100644 --- a/go/vt/vttablet/grpcqueryservice/server.go +++ b/go/vt/vttablet/grpcqueryservice/server.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -393,6 +393,17 @@ func (q *query) VStreamRows(request *binlogdatapb.VStreamRowsRequest, stream que return vterrors.ToGRPC(err) } +// VStreamResults is part of the queryservice.QueryServer interface +func (q *query) VStreamResults(request *binlogdatapb.VStreamResultsRequest, stream queryservicepb.Query_VStreamResultsServer) (err error) { + defer q.server.HandlePanic(&err) + ctx := callerid.NewContext(callinfo.GRPCCallInfo(stream.Context()), + request.EffectiveCallerId, + request.ImmediateCallerId, + ) + err = q.server.VStreamResults(ctx, request.Target, request.Query, stream.Send) + return vterrors.ToGRPC(err) +} + // Register registers the implementation on the provide gRPC Server. func Register(s *grpc.Server, server queryservice.QueryService) { queryservicepb.RegisterQueryServer(s, &query{server}) diff --git a/go/vt/vttablet/grpctabletconn/conn.go b/go/vt/vttablet/grpctabletconn/conn.go index aae4da11ac8..a10ba36320c 100644 --- a/go/vt/vttablet/grpctabletconn/conn.go +++ b/go/vt/vttablet/grpctabletconn/conn.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -755,6 +755,46 @@ func (conn *gRPCQueryClient) VStreamRows(ctx context.Context, target *querypb.Ta } } +// VStreamResults streams rows of a query from the specified starting point. +func (conn *gRPCQueryClient) VStreamResults(ctx context.Context, target *querypb.Target, query string, send func(*binlogdatapb.VStreamResultsResponse) error) error { + stream, err := func() (queryservicepb.Query_VStreamResultsClient, error) { + conn.mu.RLock() + defer conn.mu.RUnlock() + if conn.cc == nil { + return nil, tabletconn.ConnClosed + } + + req := &binlogdatapb.VStreamResultsRequest{ + Target: target, + EffectiveCallerId: callerid.EffectiveCallerIDFromContext(ctx), + ImmediateCallerId: callerid.ImmediateCallerIDFromContext(ctx), + Query: query, + } + stream, err := conn.c.VStreamResults(ctx, req) + if err != nil { + return nil, tabletconn.ErrorFromGRPC(err) + } + return stream, nil + }() + if err != nil { + return err + } + for { + r, err := stream.Recv() + if err != nil { + return tabletconn.ErrorFromGRPC(err) + } + select { + case <-ctx.Done(): + return ctx.Err() + default: + } + if err := send(r); err != nil { + return err + } + } +} + // HandlePanic is a no-op. func (conn *gRPCQueryClient) HandlePanic(err *error) { } diff --git a/go/vt/vttablet/grpctabletconn/conn_test.go b/go/vt/vttablet/grpctabletconn/conn_test.go index d93b783e377..943cbdd134c 100644 --- a/go/vt/vttablet/grpctabletconn/conn_test.go +++ b/go/vt/vttablet/grpctabletconn/conn_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vttablet/grpctmclient/client.go b/go/vt/vttablet/grpctmclient/client.go index e921ca3275e..d79e8003da3 100644 --- a/go/vt/vttablet/grpctmclient/client.go +++ b/go/vt/vttablet/grpctmclient/client.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -482,6 +482,17 @@ func (client *Client) MasterPosition(ctx context.Context, tablet *topodatapb.Tab return response.Position, nil } +// WaitForPosition is part of the tmclient.TabletManagerClient interface. +func (client *Client) WaitForPosition(ctx context.Context, tablet *topodatapb.Tablet, pos string) error { + cc, c, err := client.dial(tablet) + if err != nil { + return err + } + defer cc.Close() + _, err = c.WaitForPosition(ctx, &tabletmanagerdatapb.WaitForPositionRequest{Position: pos}) + return err +} + // StopSlave is part of the tmclient.TabletManagerClient interface. func (client *Client) StopSlave(ctx context.Context, tablet *topodatapb.Tablet) error { cc, c, err := client.dial(tablet) @@ -702,7 +713,7 @@ func (client *Client) SlaveWasPromoted(ctx context.Context, tablet *topodatapb.T } // SetMaster is part of the tmclient.TabletManagerClient interface. -func (client *Client) SetMaster(ctx context.Context, tablet *topodatapb.Tablet, parent *topodatapb.TabletAlias, timeCreatedNS int64, forceStartSlave bool) error { +func (client *Client) SetMaster(ctx context.Context, tablet *topodatapb.Tablet, parent *topodatapb.TabletAlias, timeCreatedNS int64, waitPosition string, forceStartSlave bool) error { cc, c, err := client.dial(tablet) if err != nil { return err @@ -711,6 +722,7 @@ func (client *Client) SetMaster(ctx context.Context, tablet *topodatapb.Tablet, _, err = c.SetMaster(ctx, &tabletmanagerdatapb.SetMasterRequest{ Parent: parent, TimeCreatedNs: timeCreatedNS, + WaitPosition: waitPosition, ForceStartSlave: forceStartSlave, }) return err diff --git a/go/vt/vttablet/grpctmserver/server.go b/go/vt/vttablet/grpctmserver/server.go index 90deda35ccd..8d2d6b0c297 100644 --- a/go/vt/vttablet/grpctmserver/server.go +++ b/go/vt/vttablet/grpctmserver/server.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -256,6 +256,13 @@ func (s *server) MasterPosition(ctx context.Context, request *tabletmanagerdatap return response, err } +func (s *server) WaitForPosition(ctx context.Context, request *tabletmanagerdatapb.WaitForPositionRequest) (response *tabletmanagerdatapb.WaitForPositionResponse, err error) { + defer s.agent.HandleRPCPanic(ctx, "WaitForPosition", request, response, false /*verbose*/, &err) + ctx = callinfo.GRPCCallInfo(ctx) + response = &tabletmanagerdatapb.WaitForPositionResponse{} + return response, s.agent.WaitForPosition(ctx, request.Position) +} + func (s *server) StopSlave(ctx context.Context, request *tabletmanagerdatapb.StopSlaveRequest) (response *tabletmanagerdatapb.StopSlaveResponse, err error) { defer s.agent.HandleRPCPanic(ctx, "StopSlave", request, response, true /*verbose*/, &err) ctx = callinfo.GRPCCallInfo(ctx) @@ -402,7 +409,7 @@ func (s *server) SetMaster(ctx context.Context, request *tabletmanagerdatapb.Set defer s.agent.HandleRPCPanic(ctx, "SetMaster", request, response, true /*verbose*/, &err) ctx = callinfo.GRPCCallInfo(ctx) response = &tabletmanagerdatapb.SetMasterResponse{} - return response, s.agent.SetMaster(ctx, request.Parent, request.TimeCreatedNs, request.ForceStartSlave) + return response, s.agent.SetMaster(ctx, request.Parent, request.TimeCreatedNs, request.WaitPosition, request.ForceStartSlave) } func (s *server) SlaveWasRestarted(ctx context.Context, request *tabletmanagerdatapb.SlaveWasRestartedRequest) (response *tabletmanagerdatapb.SlaveWasRestartedResponse, err error) { diff --git a/go/vt/vttablet/grpctmserver/server_test.go b/go/vt/vttablet/grpctmserver/server_test.go index 4a63237b19e..82fb9cbd3a6 100644 --- a/go/vt/vttablet/grpctmserver/server_test.go +++ b/go/vt/vttablet/grpctmserver/server_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vttablet/heartbeat/heartbeat.go b/go/vt/vttablet/heartbeat/heartbeat.go index 2d13e93fc4b..365549801a3 100644 --- a/go/vt/vttablet/heartbeat/heartbeat.go +++ b/go/vt/vttablet/heartbeat/heartbeat.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/vttablet/heartbeat/reader.go b/go/vt/vttablet/heartbeat/reader.go index 54dbc72b8bd..90de44261b1 100644 --- a/go/vt/vttablet/heartbeat/reader.go +++ b/go/vt/vttablet/heartbeat/reader.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/vttablet/heartbeat/reader_test.go b/go/vt/vttablet/heartbeat/reader_test.go index ede891a810b..3e9a97e1f4a 100644 --- a/go/vt/vttablet/heartbeat/reader_test.go +++ b/go/vt/vttablet/heartbeat/reader_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/vttablet/heartbeat/writer.go b/go/vt/vttablet/heartbeat/writer.go index e84f75920fb..9bc75128e61 100644 --- a/go/vt/vttablet/heartbeat/writer.go +++ b/go/vt/vttablet/heartbeat/writer.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/vttablet/heartbeat/writer_test.go b/go/vt/vttablet/heartbeat/writer_test.go index f0f6b6acae1..df85ef83a2c 100644 --- a/go/vt/vttablet/heartbeat/writer_test.go +++ b/go/vt/vttablet/heartbeat/writer_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/vttablet/queryservice/fakes/error_query_service.go b/go/vt/vttablet/queryservice/fakes/error_query_service.go index f32febf6fd4..ac959982720 100644 --- a/go/vt/vttablet/queryservice/fakes/error_query_service.go +++ b/go/vt/vttablet/queryservice/fakes/error_query_service.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/vttablet/queryservice/fakes/stream_health_query_service.go b/go/vt/vttablet/queryservice/fakes/stream_health_query_service.go index 117726625fc..09d93232f3c 100644 --- a/go/vt/vttablet/queryservice/fakes/stream_health_query_service.go +++ b/go/vt/vttablet/queryservice/fakes/stream_health_query_service.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/vttablet/queryservice/queryservice.go b/go/vt/vttablet/queryservice/queryservice.go index 7dbdd8a59cb..4182161a294 100644 --- a/go/vt/vttablet/queryservice/queryservice.go +++ b/go/vt/vttablet/queryservice/queryservice.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -73,7 +73,7 @@ type QueryService interface { // essentially resolving it. ConcludeTransaction(ctx context.Context, target *querypb.Target, dtid string) (err error) - // ReadTransaction returns the metadata for the sepcified dtid. + // ReadTransaction returns the metadata for the specified dtid. ReadTransaction(ctx context.Context, target *querypb.Target, dtid string) (metadata *querypb.TransactionMetadata, err error) // Query execution @@ -106,6 +106,9 @@ type QueryService interface { // VStreamRows streams rows of a table from the specified starting point. VStreamRows(ctx context.Context, target *querypb.Target, query string, lastpk *querypb.QueryResult, send func(*binlogdatapb.VStreamRowsResponse) error) error + // VStreamResults streams results along with the gtid of the snapshot. + VStreamResults(ctx context.Context, target *querypb.Target, query string, send func(*binlogdatapb.VStreamResultsResponse) error) error + // StreamHealth streams health status. StreamHealth(ctx context.Context, callback func(*querypb.StreamHealthResponse) error) error diff --git a/go/vt/vttablet/queryservice/wrapped.go b/go/vt/vttablet/queryservice/wrapped.go index 2d9a434314c..202dd0a3213 100644 --- a/go/vt/vttablet/queryservice/wrapped.go +++ b/go/vt/vttablet/queryservice/wrapped.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -265,6 +265,13 @@ func (ws *wrappedService) VStreamRows(ctx context.Context, target *querypb.Targe }) } +func (ws *wrappedService) VStreamResults(ctx context.Context, target *querypb.Target, query string, send func(*binlogdatapb.VStreamResultsResponse) error) error { + return ws.wrapper(ctx, target, ws.impl, "VStreamResults", false, func(ctx context.Context, target *querypb.Target, conn QueryService) (bool, error) { + innerErr := conn.VStreamResults(ctx, target, query, send) + return false, innerErr + }) +} + func (ws *wrappedService) StreamHealth(ctx context.Context, callback func(*querypb.StreamHealthResponse) error) error { return ws.wrapper(ctx, nil, ws.impl, "StreamHealth", false, func(ctx context.Context, target *querypb.Target, conn QueryService) (bool, error) { innerErr := conn.StreamHealth(ctx, callback) diff --git a/go/vt/vttablet/sandboxconn/sandboxconn.go b/go/vt/vttablet/sandboxconn/sandboxconn.go index ed99d21442d..5c460c180f7 100644 --- a/go/vt/vttablet/sandboxconn/sandboxconn.go +++ b/go/vt/vttablet/sandboxconn/sandboxconn.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -391,6 +391,11 @@ func (sbc *SandboxConn) VStreamRows(ctx context.Context, target *querypb.Target, return fmt.Errorf("not implemented in test") } +// VStreamResults is part of the QueryService interface. +func (sbc *SandboxConn) VStreamResults(ctx context.Context, target *querypb.Target, query string, send func(*binlogdatapb.VStreamResultsResponse) error) error { + return fmt.Errorf("not implemented in test") +} + // HandlePanic is part of the QueryService interface. func (sbc *SandboxConn) HandlePanic(err *error) { } diff --git a/go/vt/vttablet/sysloglogger/sysloglogger.go b/go/vt/vttablet/sysloglogger/sysloglogger.go index 328c327f621..9a2c9b71365 100644 --- a/go/vt/vttablet/sysloglogger/sysloglogger.go +++ b/go/vt/vttablet/sysloglogger/sysloglogger.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/vttablet/sysloglogger/sysloglogger_test.go b/go/vt/vttablet/sysloglogger/sysloglogger_test.go index 8f4993703a2..9529619c466 100644 --- a/go/vt/vttablet/sysloglogger/sysloglogger_test.go +++ b/go/vt/vttablet/sysloglogger/sysloglogger_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/vttablet/tabletconn/grpc_error.go b/go/vt/vttablet/tabletconn/grpc_error.go index 966171ed270..63fe85c21a2 100644 --- a/go/vt/vttablet/tabletconn/grpc_error.go +++ b/go/vt/vttablet/tabletconn/grpc_error.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/vttablet/tabletconn/grpc_error_test.go b/go/vt/vttablet/tabletconn/grpc_error_test.go index f0c7564d5f9..2fb864d8511 100644 --- a/go/vt/vttablet/tabletconn/grpc_error_test.go +++ b/go/vt/vttablet/tabletconn/grpc_error_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vttablet/tabletconn/tablet_conn.go b/go/vt/vttablet/tabletconn/tablet_conn.go index 20fa7081427..2f1fdc40863 100644 --- a/go/vt/vttablet/tabletconn/tablet_conn.go +++ b/go/vt/vttablet/tabletconn/tablet_conn.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vttablet/tabletconntest/fakequeryservice.go b/go/vt/vttablet/tabletconntest/fakequeryservice.go index 1d01be25e4c..32ea47b3c26 100644 --- a/go/vt/vttablet/tabletconntest/fakequeryservice.go +++ b/go/vt/vttablet/tabletconntest/fakequeryservice.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 @@ -863,6 +863,11 @@ func (f *FakeQueryService) VStreamRows(ctx context.Context, target *querypb.Targ panic("not implemented") } +// VStreamResults is part of the QueryService interface. +func (f *FakeQueryService) VStreamResults(ctx context.Context, target *querypb.Target, query string, send func(*binlogdatapb.VStreamResultsResponse) error) error { + panic("not implemented") +} + // CreateFakeServer returns the fake server for the tests func CreateFakeServer(t *testing.T) *FakeQueryService { return &FakeQueryService{ diff --git a/go/vt/vttablet/tabletconntest/tabletconntest.go b/go/vt/vttablet/tabletconntest/tabletconntest.go index 8b25182816e..c29cecca15f 100644 --- a/go/vt/vttablet/tabletconntest/tabletconntest.go +++ b/go/vt/vttablet/tabletconntest/tabletconntest.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vttablet/tabletmanager/action_agent.go b/go/vt/vttablet/tabletmanager/action_agent.go index 7fe05a7b5b3..f30ef256128 100644 --- a/go/vt/vttablet/tabletmanager/action_agent.go +++ b/go/vt/vttablet/tabletmanager/action_agent.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -151,6 +151,11 @@ type ActionAgent struct { // It is protected by actionMutex. gotMysqlPort bool + // mysqlAdvertisePort is the port to publish for our own mysqld in the + // tablet record. If this is greater than 0, we simply advertise this value + // instead of asking mysqld what port it's serving on. + mysqlAdvertisePort int32 + // initReplication remembers whether an action has initialized // replication. It is protected by actionMutex. initReplication bool @@ -169,6 +174,16 @@ type ActionAgent struct { // only hold the mutex to update the fields, nothing else. mutex sync.Mutex + // _shardSyncChan is a channel for informing the shard sync goroutine that + // it should wake up and recheck the tablet state, to make sure it and the + // shard record are in sync. + // + // Call agent.notifyShardSync() instead of sending directly to this channel. + _shardSyncChan chan struct{} + + // _shardSyncCancel is the function to stop the background shard sync goroutine. + _shardSyncCancel context.CancelFunc + // _tablet has the Tablet record we last read from the topology server. _tablet *topodatapb.Tablet @@ -199,8 +214,8 @@ type ActionAgent struct { // replication delay the last time we got it _replicationDelay time.Duration - // last time we ran TabletExternallyReparented - _tabletExternallyReparentedTime time.Time + // _masterTermStartTime is the time at which our term as master began. + _masterTermStartTime time.Time // _ignoreHealthErrorExpr can be set by RPC to selectively disable certain // healthcheck errors. It should only be accessed while holding actionMutex. @@ -273,6 +288,12 @@ func NewActionAgent( if appConfig := dbcfgs.AppWithDB(); appConfig.Host != "" { mysqlHost = appConfig.Host mysqlPort = int32(appConfig.Port) + + // Remember this port as the advertise port. When we're connecting over + // host:port, it doesn't make sense to ask mysqld for its port after + // connecting. We should just tell others to use the same port we were + // told to use, in case it's a proxy. + agent.mysqlAdvertisePort = mysqlPort } else { // Assume unix socket was specified and try to get the port from mysqld var err error @@ -438,6 +459,9 @@ func (agent *ActionAgent) setTablet(tablet *topodatapb.Tablet) { agent.mutex.Lock() agent._tablet = proto.Clone(tablet).(*topodatapb.Tablet) agent.mutex.Unlock() + + // Notify the shard sync loop that the tablet state changed. + agent.notifyShardSync() } // Tablet reads the stored Tablet from the agent, protected by mutex. @@ -672,6 +696,10 @@ func (agent *ActionAgent) Start(ctx context.Context, mysqlHost string, mysqlPort startingTablet.Type = topodatapb.TabletType_UNKNOWN agent.setTablet(startingTablet) + // Start a background goroutine to watch and update the shard record, + // to make sure it and our tablet record are in sync. + agent.startShardSync() + return nil } @@ -699,6 +727,7 @@ func (agent *ActionAgent) Close() { // while taking lameduck into account. However, this may be useful for tests, // when you want to clean up an agent immediately. func (agent *ActionAgent) Stop() { + agent.stopShardSync() if agent.UpdateStream != nil { agent.UpdateStream.Disable() } @@ -724,14 +753,24 @@ func (agent *ActionAgent) hookExtraEnv() map[string]string { // The actionMutex lock must be held when calling this function. func (agent *ActionAgent) checkTabletMysqlPort(ctx context.Context, tablet *topodatapb.Tablet) *topodatapb.Tablet { agent.checkLock() - mport, err := agent.MysqlDaemon.GetMysqlPort() - if err != nil { - // Only log the first time, so we don't spam the logs. - if !agent.waitingForMysql { - log.Warningf("Cannot get current mysql port, not checking it (will retry at healthcheck interval): %v", err) - agent.waitingForMysql = true + + var mport int32 + + // If we have stored an advertise port, just assume that. + // Otherwise, ask mysqld (presumably over unix socket) what its port is. + if agent.mysqlAdvertisePort > 0 { + mport = agent.mysqlAdvertisePort + } else { + var err error + mport, err = agent.MysqlDaemon.GetMysqlPort() + if err != nil { + // Only log the first time, so we don't spam the logs. + if !agent.waitingForMysql { + log.Warningf("Cannot get current mysql port, not checking it (will retry at healthcheck interval): %v", err) + agent.waitingForMysql = true + } + return nil } - return nil } if mport == topoproto.MysqlPort(tablet) { diff --git a/go/vt/vttablet/tabletmanager/events/state_change.go b/go/vt/vttablet/tabletmanager/events/state_change.go index bb75982b9a1..58be9d4ccac 100644 --- a/go/vt/vttablet/tabletmanager/events/state_change.go +++ b/go/vt/vttablet/tabletmanager/events/state_change.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vttablet/tabletmanager/healthcheck.go b/go/vt/vttablet/tabletmanager/healthcheck.go index d3a4343e2d6..3bbb9992b71 100644 --- a/go/vt/vttablet/tabletmanager/healthcheck.go +++ b/go/vt/vttablet/tabletmanager/healthcheck.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -238,7 +238,7 @@ func (agent *ActionAgent) runHealthCheckLocked() { // // We don't care if the QueryService state actually // changed because we'll broadcast the latest health - // status after this immediately anway. + // status after this immediately anyway. _ /* state changed */, healthErr = agent.QueryServiceControl.SetServingType(tablet.Type, true, nil) if healthErr == nil { @@ -266,7 +266,7 @@ func (agent *ActionAgent) runHealthCheckLocked() { // We don't care if the QueryService state actually // changed because we'll broadcast the latest health - // status after this immediately anway. + // status after this immediately anyway. log.Infof("Disabling query service because of health-check failure: %v", healthErr) if _ /* state changed */, err := agent.QueryServiceControl.SetServingType(tablet.Type, false, nil); err != nil { log.Errorf("SetServingType(serving=false) failed: %v", err) diff --git a/go/vt/vttablet/tabletmanager/healthcheck_test.go b/go/vt/vttablet/tabletmanager/healthcheck_test.go index 5f59d0e6173..88389cdb71c 100644 --- a/go/vt/vttablet/tabletmanager/healthcheck_test.go +++ b/go/vt/vttablet/tabletmanager/healthcheck_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -38,6 +38,9 @@ import ( "vitess.io/vitess/go/vt/vttablet/tabletservermock" topodatapb "vitess.io/vitess/go/vt/proto/topodata" + + // needed so that grpc client is registered + _ "vitess.io/vitess/go/vt/vttablet/grpctmclient" ) func TestHealthRecordDeduplication(t *testing.T) { @@ -173,7 +176,7 @@ func TestHealthCheckControlsQueryService(t *testing.T) { ctx := context.Background() agent := createTestAgent(ctx, t, nil) - /// Consume the first health broadcast triggered by ActionAgent.Start(): + // Consume the first health broadcast triggered by ActionAgent.Start(): // (REPLICA, NOT_SERVING) goes to (REPLICA, SERVING). And we // should be serving. if _, err := expectBroadcastData(agent.QueryServiceControl, true, "healthcheck not run yet", 0); err != nil { @@ -281,7 +284,7 @@ func TestErrSlaveNotRunningIsHealthy(t *testing.T) { ctx := context.Background() agent := createTestAgent(ctx, t, nil) - /// Consume the first health broadcast triggered by ActionAgent.Start(): + // Consume the first health broadcast triggered by ActionAgent.Start(): // (REPLICA, NOT_SERVING) goes to (REPLICA, SERVING). And we // should be serving. if _, err := expectBroadcastData(agent.QueryServiceControl, true, "healthcheck not run yet", 0); err != nil { @@ -390,7 +393,7 @@ func TestQueryServiceStopped(t *testing.T) { ctx := context.Background() agent := createTestAgent(ctx, t, nil) - /// Consume the first health broadcast triggered by ActionAgent.Start(): + // Consume the first health broadcast triggered by ActionAgent.Start(): // (REPLICA, NOT_SERVING) goes to (REPLICA, SERVING). And we // should be serving. if _, err := expectBroadcastData(agent.QueryServiceControl, true, "healthcheck not run yet", 0); err != nil { @@ -488,7 +491,7 @@ func TestTabletControl(t *testing.T) { ctx := context.Background() agent := createTestAgent(ctx, t, nil) - /// Consume the first health broadcast triggered by ActionAgent.Start(): + // Consume the first health broadcast triggered by ActionAgent.Start(): // (REPLICA, NOT_SERVING) goes to (REPLICA, SERVING). And we // should be serving. if _, err := expectBroadcastData(agent.QueryServiceControl, true, "healthcheck not run yet", 0); err != nil { @@ -691,7 +694,7 @@ func TestStateChangeImmediateHealthBroadcast(t *testing.T) { ctx := context.Background() agent := createTestAgent(ctx, t, nil) - /// Consume the first health broadcast triggered by ActionAgent.Start(): + // Consume the first health broadcast triggered by ActionAgent.Start(): // (REPLICA, NOT_SERVING) goes to (REPLICA, SERVING). And we // should be serving. if _, err := expectBroadcastData(agent.QueryServiceControl, true, "healthcheck not run yet", 0); err != nil { @@ -717,9 +720,32 @@ func TestStateChangeImmediateHealthBroadcast(t *testing.T) { // Run TER to turn us into a proper master, wait for it to finish. agent.HealthReporter.(*fakeHealthCheck).reportReplicationDelay = 19 * time.Second if err := agent.TabletExternallyReparented(ctx, "unused_id"); err != nil { - t.Fatal(err) + t.Fatalf("TabletExternallyReparented failed: %v", err) } <-agent.finalizeReparentCtx.Done() + // It is not enough to wait for finalizeReparentCtx to be done, we have to wait for shard_sync to finish + startTime := time.Now() + for { + if time.Since(startTime) > 10*time.Second /* timeout */ { + si, err := agent.TopoServer.GetShard(ctx, agent.Tablet().Keyspace, agent.Tablet().Shard) + if err != nil { + t.Fatalf("GetShard(%v, %v) failed: %v", agent.Tablet().Keyspace, agent.Tablet().Shard, err) + } + if !topoproto.TabletAliasEqual(si.MasterAlias, agent.Tablet().Alias) { + t.Fatalf("ShardInfo should have MasterAlias %v but has %v", topoproto.TabletAliasString(agent.Tablet().Alias), topoproto.TabletAliasString(si.MasterAlias)) + } + } + si, err := agent.TopoServer.GetShard(ctx, agent.Tablet().Keyspace, agent.Tablet().Shard) + if err != nil { + t.Fatalf("GetShard(%v, %v) failed: %v", agent.Tablet().Keyspace, agent.Tablet().Shard, err) + } + if topoproto.TabletAliasEqual(si.MasterAlias, agent.Tablet().Alias) { + break + } else { + time.Sleep(100 * time.Millisecond /* interval at which to re-check the shard record */) + } + } + ti, err := agent.TopoServer.GetTablet(ctx, tabletAlias) if err != nil { t.Fatalf("GetTablet failed: %v", err) @@ -792,9 +818,8 @@ func TestStateChangeImmediateHealthBroadcast(t *testing.T) { } // Consume health broadcast sent out due to QueryService state change from // (MASTER, SERVING) to (MASTER, NOT_SERVING). - // Since we didn't run healthcheck again yet, the broadcast data contains the - // cached replication lag of 20 instead of 21. - if _, err := expectBroadcastData(agent.QueryServiceControl, false, "", 20); err != nil { + // RefreshState on MASTER always sets the replicationDelay to 0 + if _, err := expectBroadcastData(agent.QueryServiceControl, false, "", 0); err != nil { t.Fatal(err) } if err := expectStateChange(agent.QueryServiceControl, false, topodatapb.TabletType_MASTER); err != nil { @@ -842,8 +867,9 @@ func TestStateChangeImmediateHealthBroadcast(t *testing.T) { t.Errorf("Query service should not be running") } // Since we didn't run healthcheck again yet, the broadcast data contains the - // cached replication lag of 22 instead of 23. - if _, err := expectBroadcastData(agent.QueryServiceControl, true, "", 22); err != nil { + // cached replication lag of 0. This is because + // RefreshState on MASTER always sets the replicationDelay to 0 + if _, err := expectBroadcastData(agent.QueryServiceControl, true, "", 0); err != nil { t.Fatal(err) } if err := expectStateChange(agent.QueryServiceControl, true, topodatapb.TabletType_MASTER); err != nil { @@ -885,6 +911,114 @@ func TestOldHealthCheck(t *testing.T) { } } +// TestBackupStateChange verifies that after backup we check +// the replication delay before setting REPLICA tablet to SERVING +func TestBackupStateChange(t *testing.T) { + ctx := context.Background() + agent := createTestAgent(ctx, t, nil) + + *degradedThreshold = 7 * time.Second + *unhealthyThreshold = 15 * time.Second + + if _, err := expectBroadcastData(agent.QueryServiceControl, true, "healthcheck not run yet", 0); err != nil { + t.Fatal(err) + } + if err := expectStateChange(agent.QueryServiceControl, true, topodatapb.TabletType_REPLICA); err != nil { + t.Fatal(err) + } + + agent.HealthReporter.(*fakeHealthCheck).reportReplicationDelay = 16 * time.Second + + // change to BACKUP, query service will turn off + if _, err := topotools.ChangeType(ctx, agent.TopoServer, agent.TabletAlias, topodatapb.TabletType_BACKUP, nil); err != nil { + t.Fatal(err) + } + if err := agent.RefreshState(ctx); err != nil { + t.Fatal(err) + } + if agent.QueryServiceControl.IsServing() { + t.Errorf("Query service should NOT be running") + } + if err := expectStateChange(agent.QueryServiceControl, false, topodatapb.TabletType_BACKUP); err != nil { + t.Fatal(err) + } + // change back to REPLICA, query service should not start + // because replication delay > unhealthyThreshold + if _, err := topotools.ChangeType(ctx, agent.TopoServer, agent.TabletAlias, topodatapb.TabletType_REPLICA, nil); err != nil { + t.Fatal(err) + } + if err := agent.RefreshState(ctx); err != nil { + t.Fatal(err) + } + if agent.QueryServiceControl.IsServing() { + t.Errorf("Query service should NOT be running") + } + if err := expectStateChange(agent.QueryServiceControl, false, topodatapb.TabletType_REPLICA); err != nil { + t.Fatal(err) + } + + // run healthcheck + // now query service should still be OFF + agent.runHealthCheck() + if agent.QueryServiceControl.IsServing() { + t.Errorf("Query service should NOT be running") + } +} + +// TestRestoreStateChange verifies that after restore we check +// the replication delay before setting REPLICA tablet to SERVING +func TestRestoreStateChange(t *testing.T) { + ctx := context.Background() + agent := createTestAgent(ctx, t, nil) + + *degradedThreshold = 7 * time.Second + *unhealthyThreshold = 15 * time.Second + + if _, err := expectBroadcastData(agent.QueryServiceControl, true, "healthcheck not run yet", 0); err != nil { + t.Fatal(err) + } + if err := expectStateChange(agent.QueryServiceControl, true, topodatapb.TabletType_REPLICA); err != nil { + t.Fatal(err) + } + + agent.HealthReporter.(*fakeHealthCheck).reportReplicationDelay = 16 * time.Second + + // change to RESTORE, query service will turn off + if _, err := topotools.ChangeType(ctx, agent.TopoServer, agent.TabletAlias, topodatapb.TabletType_RESTORE, nil); err != nil { + t.Fatal(err) + } + if err := agent.RefreshState(ctx); err != nil { + t.Fatal(err) + } + if agent.QueryServiceControl.IsServing() { + t.Errorf("Query service should NOT be running") + } + if err := expectStateChange(agent.QueryServiceControl, false, topodatapb.TabletType_RESTORE); err != nil { + t.Fatal(err) + } + // change back to REPLICA, query service should not start + // because replication delay > unhealthyThreshold + if _, err := topotools.ChangeType(ctx, agent.TopoServer, agent.TabletAlias, topodatapb.TabletType_REPLICA, nil); err != nil { + t.Fatal(err) + } + if err := agent.RefreshState(ctx); err != nil { + t.Fatal(err) + } + if agent.QueryServiceControl.IsServing() { + t.Errorf("Query service should NOT be running") + } + if err := expectStateChange(agent.QueryServiceControl, false, topodatapb.TabletType_REPLICA); err != nil { + t.Fatal(err) + } + + // run healthcheck + // now query service should still be OFF + agent.runHealthCheck() + if agent.QueryServiceControl.IsServing() { + t.Errorf("Query service should NOT be running") + } +} + // expectBroadcastData checks that runHealthCheck() broadcasted the expected // stats (going the value for secondsBehindMaster). func expectBroadcastData(qsc tabletserver.Controller, serving bool, healthError string, secondsBehindMaster uint32) (*tabletservermock.BroadcastData, error) { @@ -922,7 +1056,7 @@ func expectStateChange(qsc tabletserver.Controller, serving bool, tabletType top } got := <-qsc.(*tabletservermock.Controller).StateChanges if !reflect.DeepEqual(got, want) { - return fmt.Errorf("unexpected state change. got: %v want: %v got", got, want) + return fmt.Errorf("unexpected state change. got: %v want: %v", got, want) } return nil } diff --git a/go/vt/vttablet/tabletmanager/heartbeat_reporter.go b/go/vt/vttablet/tabletmanager/heartbeat_reporter.go index 6f338c35f1c..8fadc459f7e 100644 --- a/go/vt/vttablet/tabletmanager/heartbeat_reporter.go +++ b/go/vt/vttablet/tabletmanager/heartbeat_reporter.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/vttablet/tabletmanager/init_tablet.go b/go/vt/vttablet/tabletmanager/init_tablet.go index 47e5c00917f..24ec839e767 100644 --- a/go/vt/vttablet/tabletmanager/init_tablet.go +++ b/go/vt/vttablet/tabletmanager/init_tablet.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -108,17 +108,42 @@ func (agent *ActionAgent) InitTablet(port, gRPCPort int32) error { // There's no existing tablet record, so we can assume // no one has left us a message to step down. tabletType = topodatapb.TabletType_MASTER - // Update the TER timestamp (current value is 0) because we + // Update the master term start time (current value is 0) because we // assume that we are actually the MASTER and in case of a tiebreak, // vtgate should prefer us. - agent.setExternallyReparentedTime(time.Now()) + agent.setMasterTermStartTime(time.Now()) case err == nil: if oldTablet.Type == topodatapb.TabletType_MASTER { // We're marked as master in the shard record, // and our existing tablet record agrees. tabletType = topodatapb.TabletType_MASTER - // Same comment as above. Update tiebreaking timestamp to now. - agent.setExternallyReparentedTime(time.Now()) + // Read the master term start time from tablet. + // If it is nil, it might mean that we are upgrading, so use current time instead + if oldTablet.MasterTermStartTime != nil { + agent.setMasterTermStartTime(oldTablet.GetMasterTermStartTime()) + } else { + agent.setMasterTermStartTime(time.Now()) + } + } + default: + return vterrors.Wrap(err, "InitTablet failed to read existing tablet record") + } + } else { + oldTablet, err := agent.TopoServer.GetTablet(ctx, agent.TabletAlias) + switch { + case topo.IsErrType(err, topo.NoNode): + // There's no existing tablet record, so there is nothing to do + case err == nil: + if oldTablet.Type == topodatapb.TabletType_MASTER { + // Our existing tablet type is master, but the shard record does not agree. + // Only take over if our master_term_start_time is after what is in the shard record + oldMasterTermStartTime := oldTablet.GetMasterTermStartTime() + currentShardTime := si.GetMasterTermStartTime() + if oldMasterTermStartTime.After(currentShardTime) { + tabletType = topodatapb.TabletType_MASTER + // read the master term start time from tablet + agent.setMasterTermStartTime(oldMasterTermStartTime) + } } default: return vterrors.Wrap(err, "InitTablet failed to read existing tablet record") @@ -151,6 +176,19 @@ func (agent *ActionAgent) InitTablet(port, gRPCPort int32) error { log.Infof("Using detected machine hostname: %v To change this, fix your machine network configuration or override it with -tablet_hostname.", hostname) } + // if we are recovering from a snapshot we set initDbNameOverride + // but only if it not already set + if *initDbNameOverride == "" { + keyspaceInfo, err := agent.TopoServer.GetKeyspace(ctx, *initKeyspace) + if err != nil { + return vterrors.Wrapf(err, "Error getting keyspace: %v", *initKeyspace) + } + baseKeyspace := keyspaceInfo.Keyspace.BaseKeyspace + if baseKeyspace != "" { + *initDbNameOverride = topoproto.VtDbPrefix + baseKeyspace + } + } + // create and populate tablet record tablet := &topodatapb.Tablet{ Alias: agent.TabletAlias, @@ -163,6 +201,9 @@ func (agent *ActionAgent) InitTablet(port, gRPCPort int32) error { DbNameOverride: *initDbNameOverride, Tags: initTags, } + if !agent.masterTermStartTime().IsZero() { + tablet.MasterTermStartTime = logutil.TimeToProto(agent.masterTermStartTime()) + } if port != 0 { tablet.PortMap["vt"] = port } @@ -195,7 +236,7 @@ func (agent *ActionAgent) InitTablet(port, gRPCPort int32) error { // instance of a startup timeout). Upon running this code // again, we want to fix ShardReplication. if updateErr := topo.UpdateTabletReplicationData(ctx, agent.TopoServer, tablet); updateErr != nil { - return updateErr + return vterrors.Wrap(updateErr, "UpdateTabletReplicationData failed") } // Then overwrite everything, ignoring version mismatch. @@ -206,9 +247,9 @@ func (agent *ActionAgent) InitTablet(port, gRPCPort int32) error { return vterrors.Wrap(err, "CreateTablet failed") } + agent.setTablet(tablet) // optionally populate metadata records if *initPopulateMetadata { - agent.setTablet(tablet) localMetadata := agent.getLocalMetadataValues(tablet.Type) err := mysqlctl.PopulateMetadataTables(agent.MysqlDaemon, localMetadata, topoproto.TabletDbName(tablet)) if err != nil { diff --git a/go/vt/vttablet/tabletmanager/init_tablet_test.go b/go/vt/vttablet/tabletmanager/init_tablet_test.go index b19db6af3a1..cac9c0a0673 100644 --- a/go/vt/vttablet/tabletmanager/init_tablet_test.go +++ b/go/vt/vttablet/tabletmanager/init_tablet_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -262,8 +262,8 @@ func TestInitTablet(t *testing.T) { if string(ti.KeyRange.Start) != "" || string(ti.KeyRange.End) != "\xc0" { t.Errorf("wrong KeyRange for tablet: %v", ti.KeyRange) } - if got := agent._tabletExternallyReparentedTime; !got.IsZero() { - t.Fatalf("REPLICA tablet should not have an ExternallyReparentedTimestamp set: %v", got) + if got := agent._masterTermStartTime; !got.IsZero() { + t.Fatalf("REPLICA tablet should not have a MasterTermStartTime set: %v", got) } // 2. Update shard's master to our alias, then try to init again. @@ -288,8 +288,8 @@ func TestInitTablet(t *testing.T) { if ti.Type != topodatapb.TabletType_REPLICA { t.Errorf("wrong tablet type: %v", ti.Type) } - if got := agent._tabletExternallyReparentedTime; !got.IsZero() { - t.Fatalf("REPLICA tablet should not have an ExternallyReparentedTimestamp set: %v", got) + if got := agent._masterTermStartTime; !got.IsZero() { + t.Fatalf("REPLICA tablet should not have a masterTermStartTime set: %v", got) } // 3. Delete the tablet record. The shard record still says that we are the @@ -308,9 +308,9 @@ func TestInitTablet(t *testing.T) { if ti.Type != topodatapb.TabletType_MASTER { t.Errorf("wrong tablet type: %v", ti.Type) } - ter1 := agent._tabletExternallyReparentedTime + ter1 := agent._masterTermStartTime if ter1.IsZero() { - t.Fatalf("MASTER tablet should have an ExternallyReparentedTimestamp set") + t.Fatalf("MASTER tablet should have a masterTermStartTime set") } // 4. Fix the tablet record to agree that we're master. @@ -330,9 +330,9 @@ func TestInitTablet(t *testing.T) { if ti.Type != topodatapb.TabletType_MASTER { t.Errorf("wrong tablet type: %v", ti.Type) } - ter2 := agent._tabletExternallyReparentedTime - if ter2.IsZero() || !ter2.After(ter1) { - t.Fatalf("After a restart, ExternallyReparentedTimestamp must be set to the current time. Previous timestamp: %v current timestamp: %v", ter1, ter2) + ter2 := agent._masterTermStartTime + if ter2.IsZero() || !ter2.Equal(ter1) { + t.Fatalf("After a restart, masterTermStartTime must be equal to the previous time saved in the tablet record. Previous timestamp: %v current timestamp: %v", ter1, ter2) } // 5. Subsequent inits will still start the vttablet as MASTER. @@ -355,8 +355,8 @@ func TestInitTablet(t *testing.T) { if len(ti.Tags) != 1 || ti.Tags["aaa"] != "bbb" { t.Errorf("wrong tablet tags: %v", ti.Tags) } - ter3 := agent._tabletExternallyReparentedTime - if ter3.IsZero() || !ter3.After(ter2) { - t.Fatalf("After a restart, ExternallyReparentedTimestamp must be set to the current time. Previous timestamp: %v current timestamp: %v", ter2, ter3) + ter3 := agent._masterTermStartTime + if ter3.IsZero() || !ter3.Equal(ter2) { + t.Fatalf("After a restart, masterTermStartTime must be set to the previous time saved in the tablet record. Previous timestamp: %v current timestamp: %v", ter2, ter3) } } diff --git a/go/vt/vttablet/tabletmanager/initial_rebuild.go b/go/vt/vttablet/tabletmanager/initial_rebuild.go index 65ad7a1e390..b376b6eace5 100644 --- a/go/vt/vttablet/tabletmanager/initial_rebuild.go +++ b/go/vt/vttablet/tabletmanager/initial_rebuild.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vttablet/tabletmanager/orchestrator.go b/go/vt/vttablet/tabletmanager/orchestrator.go index 66d8222d221..73f2e2fcb2d 100644 --- a/go/vt/vttablet/tabletmanager/orchestrator.go +++ b/go/vt/vttablet/tabletmanager/orchestrator.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -37,6 +37,8 @@ import ( var ( orcAddr = flag.String("orc_api_url", "", "Address of Orchestrator's HTTP API (e.g. http://host:port/api/). Leave empty to disable Orchestrator integration.") + orcUser = flag.String("orc_api_user", "", "(Optional) Basic auth username to authenticate with Orchestrator's HTTP API. Leave empty to disable basic auth.") + orcPassword = flag.String("orc_api_password", "", "(Optional) Basic auth password to authenticate with Orchestrator's HTTP API.") orcTimeout = flag.Duration("orc_timeout", 30*time.Second, "Timeout for calls to Orchestrator's HTTP API") orcInterval = flag.Duration("orc_discover_interval", 0, "How often to ping Orchestrator's HTTP API endpoint to tell it we exist. 0 means never.") ) @@ -183,7 +185,14 @@ func (orc *orcClient) apiGet(pathParts ...string) ([]byte, error) { url.Path = path.Join(fullPath...) // Note that url.String() will URL-escape the path we gave it above. - resp, err := orc.httpClient.Get(url.String()) + req, err := http.NewRequest("GET", url.String(), nil) + if err != nil { + return nil, err + } + if *orcUser != "" { + req.SetBasicAuth(*orcUser, *orcPassword) + } + resp, err := orc.httpClient.Do(req) if err != nil { return nil, err } diff --git a/go/vt/vttablet/tabletmanager/replication_reporter.go b/go/vt/vttablet/tabletmanager/replication_reporter.go index 027a11f6bfd..9c4f60b7db8 100644 --- a/go/vt/vttablet/tabletmanager/replication_reporter.go +++ b/go/vt/vttablet/tabletmanager/replication_reporter.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -30,6 +30,7 @@ import ( "vitess.io/vitess/go/vt/health" "vitess.io/vitess/go/vt/log" "vitess.io/vitess/go/vt/mysqlctl" + "vitess.io/vitess/go/vt/topo/topoproto" ) var ( @@ -126,6 +127,14 @@ func repairReplication(ctx context.Context, agent *ActionAgent) error { return fmt.Errorf("no master tablet for shard %v/%v", tablet.Keyspace, tablet.Shard) } + if topoproto.TabletAliasEqual(si.MasterAlias, tablet.Alias) { + // The shard record says we are master, but we disagree; we wouldn't + // reach this point unless we were told to check replication as a slave + // type. Hopefully someone is working on fixing that, but in any case, + // we should not try to reparent to ourselves. + return fmt.Errorf("shard %v/%v record claims tablet %v is master, but its type is %v", tablet.Keyspace, tablet.Shard, topoproto.TabletAliasString(tablet.Alias), tablet.Type) + } + // If Orchestrator is configured and if Orchestrator is actively reparenting, we should not repairReplication if agent.orc != nil { re, err := agent.orc.InActiveShardRecovery(tablet) @@ -144,7 +153,7 @@ func repairReplication(ctx context.Context, agent *ActionAgent) error { } } - return agent.setMasterRepairReplication(ctx, si.MasterAlias, 0, true) + return agent.setMasterRepairReplication(ctx, si.MasterAlias, 0, "", true) } func registerReplicationReporter(agent *ActionAgent) { diff --git a/go/vt/vttablet/tabletmanager/replication_reporter_test.go b/go/vt/vttablet/tabletmanager/replication_reporter_test.go index d1a030f4369..4140f0a2f4c 100644 --- a/go/vt/vttablet/tabletmanager/replication_reporter_test.go +++ b/go/vt/vttablet/tabletmanager/replication_reporter_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/vttablet/tabletmanager/restore.go b/go/vt/vttablet/tabletmanager/restore.go index d01a3ad4fd6..b1ae16391ba 100644 --- a/go/vt/vttablet/tabletmanager/restore.go +++ b/go/vt/vttablet/tabletmanager/restore.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -21,7 +21,9 @@ import ( "fmt" "time" + "vitess.io/vitess/go/vt/topo" "vitess.io/vitess/go/vt/vterrors" + "vitess.io/vitess/go/vt/vttablet/tmclient" "golang.org/x/net/context" "vitess.io/vitess/go/vt/log" @@ -32,6 +34,7 @@ import ( "vitess.io/vitess/go/vt/topo/topoproto" topodatapb "vitess.io/vitess/go/vt/proto/topodata" + vtrpcpb "vitess.io/vitess/go/vt/proto/vtrpc" ) // This file handles the initial backup restore upon startup. @@ -81,13 +84,40 @@ func (agent *ActionAgent) restoreDataLocked(ctx context.Context, logger logutil. // Record local metadata values based on the original type. localMetadata := agent.getLocalMetadataValues(originalType) tablet := agent.Tablet() - dir := fmt.Sprintf("%v/%v", tablet.Keyspace, tablet.Shard) + + keyspace := tablet.Keyspace + keyspaceInfo, err := agent.TopoServer.GetKeyspace(ctx, keyspace) + if err != nil { + return err + } + // For a SNAPSHOT keyspace, we have to look for backups of BaseKeyspace + // so we will pass the BaseKeyspace in RestoreParams instead of tablet.Keyspace + if keyspaceInfo.KeyspaceType == topodatapb.KeyspaceType_SNAPSHOT { + if keyspaceInfo.BaseKeyspace == "" { + return vterrors.New(vtrpcpb.Code_INVALID_ARGUMENT, fmt.Sprintf("snapshot keyspace %v has no base_keyspace set", tablet.Keyspace)) + } + keyspace = keyspaceInfo.BaseKeyspace + log.Infof("Using base_keyspace %v to restore keyspace %v", keyspace, tablet.Keyspace) + } + + params := mysqlctl.RestoreParams{ + Cnf: agent.Cnf, + Mysqld: agent.MysqlDaemon, + Logger: logger, + Concurrency: *restoreConcurrency, + HookExtraEnv: agent.hookExtraEnv(), + LocalMetadata: localMetadata, + DeleteBeforeRestore: deleteBeforeRestore, + DbName: topoproto.TabletDbName(tablet), + Keyspace: keyspace, + Shard: tablet.Shard, + StartTime: logutil.ProtoToTime(keyspaceInfo.SnapshotTime), + } // Loop until a backup exists, unless we were told to give up immediately. - var pos mysql.Position - var err error + var backupManifest *mysqlctl.BackupManifest for { - pos, err = mysqlctl.Restore(ctx, agent.Cnf, agent.MysqlDaemon, dir, *restoreConcurrency, agent.hookExtraEnv(), localMetadata, logger, deleteBeforeRestore, topoproto.TabletDbName(tablet)) + backupManifest, err = mysqlctl.Restore(ctx, params) if waitForBackupInterval == 0 { break } @@ -104,14 +134,19 @@ func (agent *ActionAgent) restoreDataLocked(ctx context.Context, logger logutil. } } + var pos mysql.Position + if backupManifest != nil { + pos = backupManifest.Position + } switch err { case nil: // Starting from here we won't be able to recover if we get stopped by a cancelled // context. Thus we use the background context to get through to the finish. - - // Reconnect to master. - if err := agent.startReplication(context.Background(), pos, originalType); err != nil { - return err + if keyspaceInfo.KeyspaceType == topodatapb.KeyspaceType_NORMAL { + // Reconnect to master only for "NORMAL" keyspaces + if err := agent.startReplication(context.Background(), pos, originalType); err != nil { + return err + } } case mysqlctl.ErrNoBackup: // No-op, starting with empty database. @@ -205,6 +240,48 @@ func (agent *ActionAgent) startReplication(ctx context.Context, pos mysql.Positi if err := agent.MysqlDaemon.SetMaster(ctx, topoproto.MysqlHostname(ti.Tablet), int(topoproto.MysqlPort(ti.Tablet)), false /* slaveStopBefore */, true /* slaveStartAfter */); err != nil { return vterrors.Wrap(err, "MysqlDaemon.SetMaster failed") } + + // wait for reliable seconds behind master + // we have pos where we want to resume from + // if MasterPosition is the same, that means no writes + // have happened to master, so we are up-to-date + // otherwise, wait for replica's Position to change from + // the initial pos before proceeding + tmc := tmclient.NewTabletManagerClient() + defer tmc.Close() + remoteCtx, remoteCancel := context.WithTimeout(ctx, *topo.RemoteOperationTimeout) + defer remoteCancel() + posStr, err := tmc.MasterPosition(remoteCtx, ti.Tablet) + if err != nil { + // It is possible that though MasterAlias is set, the master tablet is unreachable + // Log a warning and let tablet restore in that case + // If we had instead considered this fatal, all tablets would crash-loop + // until a master appears, which would make it impossible to elect a master. + log.Warningf("Can't get master replication position after restore: %v", err) + return nil + } + masterPos, err := mysql.DecodePosition(posStr) + if err != nil { + return vterrors.Wrapf(err, "can't decode master replication position: %q", posStr) + } + + if !pos.Equal(masterPos) { + for { + if err := ctx.Err(); err != nil { + return err + } + status, err := agent.MysqlDaemon.SlaveStatus() + if err != nil { + return vterrors.Wrap(err, "can't get slave status") + } + newPos := status.Position + if !newPos.Equal(pos) { + break + } + time.Sleep(1 * time.Second) + } + } + return nil } diff --git a/go/vt/vttablet/tabletmanager/rpc_actions.go b/go/vt/vttablet/tabletmanager/rpc_actions.go index 67f1aaab471..f8c5750377c 100644 --- a/go/vt/vttablet/tabletmanager/rpc_actions.go +++ b/go/vt/vttablet/tabletmanager/rpc_actions.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -21,6 +21,7 @@ import ( "regexp" "time" + "vitess.io/vitess/go/vt/logutil" "vitess.io/vitess/go/vt/vterrors" "golang.org/x/net/context" @@ -70,11 +71,23 @@ func (agent *ActionAgent) ChangeType(ctx context.Context, tabletType topodatapb. if tabletType == topodatapb.TabletType_DRAINED && agent.Tablet().Type == topodatapb.TabletType_DRAINED { return fmt.Errorf("Tablet: %v, is already drained", agent.TabletAlias) } - // change our type in the topology - _, err := topotools.ChangeType(ctx, agent.TopoServer, agent.TabletAlias, tabletType) + + agentMasterTermStartTime := time.Time{} + // If we have been told we're master, set master term start time to Now + if tabletType == topodatapb.TabletType_MASTER { + agentMasterTermStartTime = time.Now() + } + // change our type in the topology, and set masterTermStartTime on tablet record if applicable + _, err := topotools.ChangeType(ctx, agent.TopoServer, agent.TabletAlias, tabletType, logutil.TimeToProto(agentMasterTermStartTime)) if err != nil { return err } + // We only update agent's masterTermStartTime if we were able to update the topo. + // This ensures that in case of a failure, we are never in a situation where the + // tablet's timestamp is ahead of the topo's timestamp. + if tabletType == topodatapb.TabletType_MASTER { + agent.setMasterTermStartTime(agentMasterTermStartTime) + } // let's update our internal state (stop query service and other things) if err := agent.refreshTablet(ctx, "ChangeType"); err != nil { diff --git a/go/vt/vttablet/tabletmanager/rpc_agent.go b/go/vt/vttablet/tabletmanager/rpc_agent.go index c5ac21285e5..eedcbf96c17 100644 --- a/go/vt/vttablet/tabletmanager/rpc_agent.go +++ b/go/vt/vttablet/tabletmanager/rpc_agent.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -82,6 +82,8 @@ type RPCAgent interface { MasterPosition(ctx context.Context) (string, error) + WaitForPosition(ctx context.Context, pos string) error + StopSlave(ctx context.Context) error StopSlaveMinimum(ctx context.Context, position string, waitTime time.Duration) (string, error) @@ -116,7 +118,7 @@ type RPCAgent interface { SlaveWasPromoted(ctx context.Context) error - SetMaster(ctx context.Context, parent *topodatapb.TabletAlias, timeCreatedNS int64, forceStartSlave bool) error + SetMaster(ctx context.Context, parent *topodatapb.TabletAlias, timeCreatedNS int64, waitPosition string, forceStartSlave bool) error SlaveWasRestarted(ctx context.Context, parent *topodatapb.TabletAlias) error diff --git a/go/vt/vttablet/tabletmanager/rpc_backup.go b/go/vt/vttablet/tabletmanager/rpc_backup.go index d7387b7c941..ac5361b5c7c 100644 --- a/go/vt/vttablet/tabletmanager/rpc_backup.go +++ b/go/vt/vttablet/tabletmanager/rpc_backup.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -84,7 +84,7 @@ func (agent *ActionAgent) Backup(ctx context.Context, concurrency int, logger lo } originalType = tablet.Type // update our type to BACKUP - if _, err := topotools.ChangeType(ctx, agent.TopoServer, tablet.Alias, topodatapb.TabletType_BACKUP); err != nil { + if _, err := topotools.ChangeType(ctx, agent.TopoServer, tablet.Alias, topodatapb.TabletType_BACKUP, nil); err != nil { return err } @@ -97,9 +97,20 @@ func (agent *ActionAgent) Backup(ctx context.Context, concurrency int, logger lo l := logutil.NewTeeLogger(logutil.NewConsoleLogger(), logger) // now we can run the backup - dir := fmt.Sprintf("%v/%v", tablet.Keyspace, tablet.Shard) - name := fmt.Sprintf("%v.%v", time.Now().UTC().Format("2006-01-02.150405"), topoproto.TabletAliasString(tablet.Alias)) - returnErr := mysqlctl.Backup(ctx, agent.Cnf, agent.MysqlDaemon, l, dir, name, concurrency, agent.hookExtraEnv()) + backupParams := mysqlctl.BackupParams{ + Cnf: agent.Cnf, + Mysqld: agent.MysqlDaemon, + Logger: l, + Concurrency: concurrency, + HookExtraEnv: agent.hookExtraEnv(), + TopoServer: agent.TopoServer, + Keyspace: tablet.Keyspace, + Shard: tablet.Shard, + TabletAlias: topoproto.TabletAliasString(tablet.Alias), + BackupTime: time.Now(), + } + + returnErr := mysqlctl.Backup(ctx, backupParams) if engine.ShouldDrainForBackup() { bgCtx := context.Background() @@ -107,8 +118,9 @@ func (agent *ActionAgent) Backup(ctx context.Context, concurrency int, logger lo // context. It is also possible that the context already timed out during the // above call to Backup. Thus we use the background context to get through to the finish. - // change our type back to the original value - _, err = topotools.ChangeType(bgCtx, agent.TopoServer, tablet.Alias, originalType) + // Change our type back to the original value. + // Original type could be master so pass in a real value for masterTermStartTime + _, err = topotools.ChangeType(bgCtx, agent.TopoServer, tablet.Alias, originalType, tablet.Tablet.MasterTermStartTime) if err != nil { // failure in changing the topology type is probably worse, // so returning that (we logged the snapshot error anyway) diff --git a/go/vt/vttablet/tabletmanager/rpc_external_reparent.go b/go/vt/vttablet/tabletmanager/rpc_external_reparent.go index 7b066ed1e1a..5b64f94840f 100644 --- a/go/vt/vttablet/tabletmanager/rpc_external_reparent.go +++ b/go/vt/vttablet/tabletmanager/rpc_external_reparent.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -28,8 +28,10 @@ import ( "vitess.io/vitess/go/trace" "vitess.io/vitess/go/vt/concurrency" "vitess.io/vitess/go/vt/log" + "vitess.io/vitess/go/vt/logutil" "vitess.io/vitess/go/vt/topo" "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/vttablet/tmclient" @@ -77,16 +79,9 @@ func (agent *ActionAgent) TabletExternallyReparented(ctx context.Context, extern return err } - // The external failover tool told us that we are still the MASTER. Update the - // timestamp to the current time. - agent.setExternallyReparentedTime(startTime) - - if topoproto.TabletAliasEqual(si.MasterAlias, tablet.Alias) { - // We may get called on the current master even when nothing has changed. - // If the global shard record is already updated, it means we successfully - // finished a previous reparent to this tablet. - return nil - } + // The external failover tool told us that we are still the MASTER. + // Update the timestamp to the current time (start a new term). + agent.setMasterTermStartTime(startTime) // Create a reusable Reparent event with available info. ev := &events.Reparent{ @@ -105,16 +100,19 @@ func (agent *ActionAgent) TabletExternallyReparented(ctx context.Context, extern }() event.DispatchUpdate(ev, "starting external from tablet (fast)") - // Execute state change to master by force-updating only the local copy of the - // tablet record. The actual record in topo will be updated later. - log.Infof("fastTabletExternallyReparented: executing change callback for state change to MASTER") - newTablet := proto.Clone(tablet).(*topodatapb.Tablet) - newTablet.Type = topodatapb.TabletType_MASTER - - // This is where updateState will block for gracePeriod, while it gives - // vtgate a chance to stop sending replica queries. - agent.updateState(ctx, newTablet, "fastTabletExternallyReparented") - + // We may get called on the current master multiple times in order to fix incomplete external reparents. + // We update the tablet here only if it is not currently master + if tablet.Type != topodatapb.TabletType_MASTER { + log.Infof("fastTabletExternallyReparented: executing change callback for state change to MASTER") + // Execute state change to master by force-updating only the local copy of the + // tablet record. The actual record in topo will be updated later. + newTablet := proto.Clone(tablet).(*topodatapb.Tablet) + newTablet.Type = topodatapb.TabletType_MASTER + newTablet.MasterTermStartTime = logutil.TimeToProto(agent.masterTermStartTime()) + // This is where updateState will block for gracePeriod, while it gives + // vtgate a chance to stop sending replica queries. + agent.updateState(ctx, newTablet, "fastTabletExternallyReparented") + } // Start the finalize stage with a background context, but connect the trace. bgCtx, cancel := context.WithTimeout(agent.batchCtx, *finalizeReparentTimeout) bgCtx = trace.CopySpan(bgCtx, ctx) @@ -135,56 +133,57 @@ func (agent *ActionAgent) TabletExternallyReparented(ctx context.Context, extern } // finalizeTabletExternallyReparented performs slow, synchronized reconciliation -// tasks that ensure topology is self-consistent, and then marks the reparent as -// finished by updating the global shard record. +// tasks that ensure topology is self-consistent. +// It first updates new and old master tablet records, then updates +// the global shard record, then refreshes the old master. +// After that it attempts to detect and clean up any lingering old masters. +// Note that an up-to-date shard record does not necessarily mean that +// the reparent completed all the actions successfully func (agent *ActionAgent) finalizeTabletExternallyReparented(ctx context.Context, si *topo.ShardInfo, ev *events.Reparent) (err error) { var wg sync.WaitGroup var errs concurrency.AllErrorRecorder var oldMasterTablet *topodatapb.Tablet oldMasterAlias := si.MasterAlias - // Update the tablet records concurrently. + // Update the new and old master tablet records concurrently. event.DispatchUpdate(ev, "updating old and new master tablet records") log.Infof("finalizeTabletExternallyReparented: updating tablet records") wg.Add(1) go func() { defer wg.Done() - // Update our own record to master. - _, err := agent.TopoServer.UpdateTabletFields(ctx, agent.TabletAlias, - func(tablet *topodatapb.Tablet) error { - tablet.Type = topodatapb.TabletType_MASTER - return nil - }) + log.Infof("finalizeTabletExternallyReparented: updating tablet record for new master: %v", agent.TabletAlias) + // Update our own record to master if needed + _, err := topotools.ChangeType(ctx, agent.TopoServer, agent.TabletAlias, topodatapb.TabletType_MASTER, logutil.TimeToProto(agent.masterTermStartTime())) if err != nil { errs.RecordError(err) } }() - if !topoproto.TabletAliasIsZero(oldMasterAlias) { + // If TER is called twice, then oldMasterAlias is the same as agent.TabletAlias + if !topoproto.TabletAliasIsZero(oldMasterAlias) && !topoproto.TabletAliasEqual(oldMasterAlias, agent.TabletAlias) { wg.Add(1) go func() { defer wg.Done() + log.Infof("finalizeTabletExternallyReparented: updating tablet record for old master: %v", oldMasterAlias) // Forcibly demote the old master in topology, since we can't rely on the // old master to be up to change its own record. + // Call UpdateTabletFields instead of ChangeType so that we can check the type + // before changing it and avoid unnecessary topo updates var err error - oldMasterTablet, err = agent.TopoServer.UpdateTabletFields(ctx, oldMasterAlias, - func(tablet *topodatapb.Tablet) error { - tablet.Type = topodatapb.TabletType_REPLICA - return nil - }) + oldMasterTablet, err = topotools.ChangeType(ctx, agent.TopoServer, oldMasterAlias, topodatapb.TabletType_REPLICA, nil) if err != nil { errs.RecordError(err) return } // We now know more about the old master, so add it to event data. - ev.OldMaster = *oldMasterTablet + // oldMasterTablet will be nil if no update was needed + if oldMasterTablet != nil { + ev.OldMaster = *oldMasterTablet + } }() } - - tablet := agent.Tablet() - // Wait for the tablet records to be updated. At that point, any rebuild will // see the new master, so we're ready to mark the reparent as done in the // global shard record. @@ -193,44 +192,48 @@ func (agent *ActionAgent) finalizeTabletExternallyReparented(ctx context.Context return errs.Error() } + masterTablet := agent.Tablet() + + event.DispatchUpdate(ev, "updating global shard record") + log.Infof("finalizeTabletExternallyReparented: updating global shard record if needed") wg.Add(1) go func() { defer wg.Done() - // Update the master field in the global shard record. We don't use a lock // here anymore. The lock was only to ensure that the global shard record // didn't get modified between the time when we read it and the time when we // write it back. Now we use an update loop pattern to do that instead. - event.DispatchUpdate(ev, "updating global shard record") - log.Infof("finalizeTabletExternallyReparented: updating global shard record if needed") - _, err = agent.TopoServer.UpdateShardFields(ctx, tablet.Keyspace, tablet.Shard, func(currentSi *topo.ShardInfo) error { - if topoproto.TabletAliasEqual(currentSi.MasterAlias, tablet.Alias) { - return topo.NewError(topo.NoUpdateNeeded, tablet.Alias.String()) + _, err = agent.TopoServer.UpdateShardFields(ctx, masterTablet.Keyspace, masterTablet.Shard, func(currentSi *topo.ShardInfo) error { + if topoproto.TabletAliasEqual(currentSi.MasterAlias, masterTablet.Alias) { + // returning NoUpdateNeeded avoids unnecessary calls to UpdateTablet + return topo.NewError(topo.NoUpdateNeeded, masterTablet.Alias.String()) } if !topoproto.TabletAliasEqual(currentSi.MasterAlias, oldMasterAlias) { log.Warningf("old master alias (%v) not found in the global Shard record i.e. it has changed in the meantime."+ " We're not overwriting the value with the new master (%v) because the current value is probably newer."+ " (initial Shard record = %#v, current Shard record = %#v)", - oldMasterAlias, tablet.Alias, si, currentSi) + oldMasterAlias, masterTablet.Alias, si, currentSi) + // returning NoUpdateNeeded avoids unnecessary calls to UpdateTablet return topo.NewError(topo.NoUpdateNeeded, oldMasterAlias.String()) } - currentSi.MasterAlias = tablet.Alias + currentSi.MasterAlias = masterTablet.Alias return nil }) if err != nil { errs.RecordError(err) } }() - if !topoproto.TabletAliasIsZero(oldMasterAlias) { + + tmc := tmclient.NewTabletManagerClient() + defer tmc.Close() + if !topoproto.TabletAliasIsZero(oldMasterAlias) && !topoproto.TabletAliasEqual(oldMasterAlias, agent.TabletAlias) && oldMasterTablet != nil { wg.Add(1) go func() { defer wg.Done() - // Tell the old master to re-read its tablet record and change its state. // We don't need to put error into errs if this fails, but we need to wait // for it to make sure that old master tablet is not stuck in the MASTER // state. - tmc := tmclient.NewTabletManagerClient() if err := tmc.RefreshState(ctx, oldMasterTablet); err != nil { log.Warningf("Error calling RefreshState on old master %v: %v", topoproto.TabletAliasString(oldMasterTablet.Alias), err) } @@ -242,18 +245,40 @@ func (agent *ActionAgent) finalizeTabletExternallyReparented(ctx context.Context return errs.Error() } - event.DispatchUpdate(ev, "finished") - return nil -} + // Look for any other tablets claiming to be master and fix them up on a best-effort basis + tabletMap, err := agent.TopoServer.GetTabletMapForShard(ctx, masterTablet.Keyspace, masterTablet.Shard) + if err != nil { + log.Errorf("ignoring error %v from GetTabletMapForShard so that we can process any partial results", err) + } -// setExternallyReparentedTime remembers the last time when we were told we're -// the master. -// If another tablet claims to be master and offers a more recent time, -// that tablet will be trusted over us. -func (agent *ActionAgent) setExternallyReparentedTime(t time.Time) { - agent.mutex.Lock() - defer agent.mutex.Unlock() + for _, tabletInfo := range tabletMap { + alias := tabletInfo.Tablet.Alias + if !topoproto.TabletAliasEqual(alias, agent.TabletAlias) && !topoproto.TabletAliasEqual(alias, oldMasterAlias) && tabletInfo.Tablet.Type == topodatapb.TabletType_MASTER { + log.Infof("finalizeTabletExternallyReparented: updating tablet record for another old master: %v", alias) + wg.Add(1) + go func(alias *topodatapb.TabletAlias) { + defer wg.Done() + var err error + tab, err := topotools.ChangeType(ctx, agent.TopoServer, alias, topodatapb.TabletType_REPLICA, nil) + if err != nil { + errs.RecordError(err) + return + } + // tab will be nil if no update was needed + if tab != nil { + log.Infof("finalizeTabletExternallyReparented: Refresh state for tablet: %v", topoproto.TabletAliasString(tab.Alias)) + if err := tmc.RefreshState(ctx, tab); err != nil { + log.Warningf("Error calling RefreshState on old master %v: %v", topoproto.TabletAliasString(tab.Alias), err) + } + } + }(alias) + } + } + wg.Wait() + if errs.HasErrors() { + return errs.Error() + } - agent._tabletExternallyReparentedTime = t - agent._replicationDelay = 0 + event.DispatchUpdate(ev, "finished") + return nil } diff --git a/go/vt/vttablet/tabletmanager/rpc_external_reparent_test.go b/go/vt/vttablet/tabletmanager/rpc_external_reparent_test.go index 05cf42110b6..1d50454108b 100644 --- a/go/vt/vttablet/tabletmanager/rpc_external_reparent_test.go +++ b/go/vt/vttablet/tabletmanager/rpc_external_reparent_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -29,17 +29,17 @@ func TestTabletExternallyReparentedAlwaysUpdatesTimestamp(t *testing.T) { if err := agent.TabletExternallyReparented(ctx, "unused_id"); err != nil { t.Fatal(err) } - if agent._tabletExternallyReparentedTime.IsZero() { - t.Fatalf("externally_reparented_time should have been updated") + if agent._masterTermStartTime.IsZero() { + t.Fatalf("master_term_start_time should have been updated") } // Run RPC again and verify that the timestamp was updated. - ter1 := agent._tabletExternallyReparentedTime + ter1 := agent._masterTermStartTime if err := agent.TabletExternallyReparented(ctx, "unused_id"); err != nil { t.Fatal(err) } - ter2 := agent._tabletExternallyReparentedTime + ter2 := agent._masterTermStartTime if ter1 == ter2 { - t.Fatalf("subsequent TER call did not update the timestamp: %v = %v", ter1, ter2) + t.Fatalf("subsequent TER call did not update the master_term_start_time: %v = %v", ter1, ter2) } } diff --git a/go/vt/vttablet/tabletmanager/rpc_lock_tables.go b/go/vt/vttablet/tabletmanager/rpc_lock_tables.go index 1fdc47ddebd..30a0fabeb3e 100644 --- a/go/vt/vttablet/tabletmanager/rpc_lock_tables.go +++ b/go/vt/vttablet/tabletmanager/rpc_lock_tables.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vttablet/tabletmanager/rpc_query.go b/go/vt/vttablet/tabletmanager/rpc_query.go index 672f631a8f2..c09a8f43178 100644 --- a/go/vt/vttablet/tabletmanager/rpc_query.go +++ b/go/vt/vttablet/tabletmanager/rpc_query.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vttablet/tabletmanager/rpc_replication.go b/go/vt/vttablet/tabletmanager/rpc_replication.go index 9ef1439791b..f0eea772f6f 100644 --- a/go/vt/vttablet/tabletmanager/rpc_replication.go +++ b/go/vt/vttablet/tabletmanager/rpc_replication.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -21,6 +21,8 @@ import ( "fmt" "time" + "vitess.io/vitess/go/vt/logutil" + "vitess.io/vitess/go/vt/topo" "vitess.io/vitess/go/vt/vterrors" "golang.org/x/net/context" @@ -28,7 +30,6 @@ import ( "vitess.io/vitess/go/mysql" "vitess.io/vitess/go/vt/log" "vitess.io/vitess/go/vt/mysqlctl" - "vitess.io/vitess/go/vt/topo" "vitess.io/vitess/go/vt/topo/topoproto" "vitess.io/vitess/go/vt/topotools" @@ -59,6 +60,15 @@ func (agent *ActionAgent) MasterPosition(ctx context.Context) (string, error) { return mysql.EncodePosition(pos), nil } +// WaitForPosition returns the master position +func (agent *ActionAgent) WaitForPosition(ctx context.Context, pos string) error { + mpos, err := mysql.DecodePosition(pos) + if err != nil { + return err + } + return agent.MysqlDaemon.WaitMasterPos(ctx, mpos) +} + // StopSlave will stop the mysql. Works both when Vitess manages // replication or not (using hook if not). func (agent *ActionAgent) StopSlave(ctx context.Context) error { @@ -216,16 +226,16 @@ func (agent *ActionAgent) InitMaster(ctx context.Context) (string, error) { if err := agent.MysqlDaemon.SetReadOnly(false); err != nil { return "", err } - agent.setExternallyReparentedTime(startTime) // Change our type to master if not already - if _, err := agent.TopoServer.UpdateTabletFields(ctx, agent.TabletAlias, func(tablet *topodatapb.Tablet) error { - tablet.Type = topodatapb.TabletType_MASTER - return nil - }); err != nil { + _, err = topotools.ChangeType(ctx, agent.TopoServer, agent.TabletAlias, topodatapb.TabletType_MASTER, logutil.TimeToProto(startTime)) + if err != nil { return "", err } - + // We only update agent's masterTermStartTime if we were able to update the topo. + // This ensures that in case of a failure, we are never in a situation where the + // tablet's timestamp is ahead of the topo's timestamp. + agent.setMasterTermStartTime(startTime) // and refresh our state agent.initReplication = true if err := agent.refreshTablet(ctx, "InitMaster"); err != nil { @@ -288,7 +298,7 @@ func (agent *ActionAgent) InitSlave(ctx context.Context, parent *topodatapb.Tabl // is used on the old master when using InitShardMaster with // -force, and the new master is different from the old master. if agent.Tablet().Type == topodatapb.TabletType_MASTER { - if _, err := topotools.ChangeType(ctx, agent.TopoServer, agent.TabletAlias, topodatapb.TabletType_REPLICA); err != nil { + if _, err := topotools.ChangeType(ctx, agent.TopoServer, agent.TabletAlias, topodatapb.TabletType_REPLICA, nil); err != nil { return err } @@ -301,92 +311,121 @@ func (agent *ActionAgent) InitSlave(ctx context.Context, parent *topodatapb.Tabl return agent.MysqlDaemon.WaitForReparentJournal(ctx, timeCreatedNS) } -// DemoteMaster marks the server read-only, wait until it is done with -// its current transactions, and returns its master position. +// DemoteMaster prepares a MASTER tablet to give up mastership to another tablet. +// +// It attemps to idempotently ensure the following guarantees upon returning +// successfully: +// * No future writes will be accepted. +// * No writes are in-flight. +// * MySQL is in read-only mode. +// * Semi-sync settings are consistent with a REPLICA tablet. +// +// If necessary, it waits for all in-flight writes to complete or time out. +// +// It should be safe to call this on a MASTER tablet that was already demoted, +// or on a tablet that already transitioned to REPLICA. +// +// If a step fails in the middle, it will try to undo any changes it made. func (agent *ActionAgent) DemoteMaster(ctx context.Context) (string, error) { + // The public version always reverts on partial failure. + return agent.demoteMaster(ctx, true /* revertPartialFailure */) +} + +// demoteMaster implements DemoteMaster with an additional, private option. +// +// If revertPartialFailure is true, and a step fails in the middle, it will try +// to undo any changes it made. +func (agent *ActionAgent) demoteMaster(ctx context.Context, revertPartialFailure bool) (replicationPosition string, finalErr error) { if err := agent.lock(ctx); err != nil { return "", err } defer agent.unlock() - // Tell Orchestrator we're stopped on purpose the demotion. - // This is a best effort task, so run it in a goroutine. - go func() { - if agent.orc == nil { - return - } - if err := agent.orc.BeginMaintenance(agent.Tablet(), "vttablet has been told to DemoteMaster"); err != nil { - log.Warningf("Orchestrator BeginMaintenance failed: %v", err) - } - }() - - // First, disallow queries, to make sure nobody is writing to the - // database. tablet := agent.Tablet() - // We don't care if the QueryService state actually changed because we'll - // let vtgate keep serving read traffic from this master (see comment below). - log.Infof("DemoteMaster disabling query service") - if _ /* state changed */, err := agent.QueryServiceControl.SetServingType(tablet.Type, false, nil); err != nil { - return "", vterrors.Wrap(err, "SetServingType(serving=false) failed") + wasMaster := tablet.Type == topodatapb.TabletType_MASTER + wasServing := agent.QueryServiceControl.IsServing() + wasReadOnly, err := agent.MysqlDaemon.IsReadOnly() + if err != nil { + return "", err + } + + // If we are a master tablet and not yet read-only, stop accepting new + // queries and wait for in-flight queries to complete. If we are not master, + // or if we are already read-only, there's no need to stop the queryservice + // in order to ensure the guarantee we are being asked to provide, which is + // that no writes are occurring. + if wasMaster && !wasReadOnly { + // Tell Orchestrator we're stopped on purpose for demotion. + // This is a best effort task, so run it in a goroutine. + go func() { + if agent.orc == nil { + return + } + if err := agent.orc.BeginMaintenance(agent.Tablet(), "vttablet has been told to DemoteMaster"); err != nil { + log.Warningf("Orchestrator BeginMaintenance failed: %v", err) + } + }() + + // Note that this may block until the transaction timeout if clients + // don't finish their transactions in time. Even if some transactions + // have to be killed at the end of their timeout, this will be + // considered successful. If we are already not serving, this will be + // idempotent. + log.Infof("DemoteMaster disabling query service") + if _ /* state changed */, err := agent.QueryServiceControl.SetServingType(tablet.Type, false, nil); err != nil { + return "", vterrors.Wrap(err, "SetServingType(serving=false) failed") + } + defer func() { + if finalErr != nil && revertPartialFailure && wasServing { + if _ /* state changed */, err := agent.QueryServiceControl.SetServingType(tablet.Type, true, nil); err != nil { + log.Warningf("SetServingType(serving=true) failed during revert: %v", err) + } + } + }() } - // Now, set the server read-only. Note all active connections are not - // affected. + // Now that we know no writes are in-flight and no new writes can occur, + // set MySQL to read-only mode. If we are already read-only because of a + // previous demotion, or because we are not master anyway, this should be + // idempotent. if *setSuperReadOnly { // Setting super_read_only also sets read_only if err := agent.MysqlDaemon.SetSuperReadOnly(true); err != nil { - // if this failed, revert the change to serving - if _ /* state changed */, err1 := agent.QueryServiceControl.SetServingType(tablet.Type, true, nil); err1 != nil { - log.Warningf("SetServingType(serving=true) failed after failed SetSuperReadOnly %v", err1) - } return "", err } } else { if err := agent.MysqlDaemon.SetReadOnly(true); err != nil { - // if this failed, revert the change to serving - if _ /* state changed */, err1 := agent.QueryServiceControl.SetServingType(tablet.Type, true, nil); err1 != nil { - log.Warningf("SetServingType(serving=true) failed after failed SetReadOnly %v", err1) - } return "", err } } + defer func() { + if finalErr != nil && revertPartialFailure && !wasReadOnly { + // setting read_only OFF will also set super_read_only OFF if it was set + if err := agent.MysqlDaemon.SetReadOnly(false); err != nil { + log.Warningf("SetReadOnly(false) failed during revert: %v", err) + } + } + }() // If using semi-sync, we need to disable master-side. if err := agent.fixSemiSync(topodatapb.TabletType_REPLICA); err != nil { - // if this failed, set server read-only back to false, set tablet back to serving - // setting read_only OFF will also set super_read_only OFF if it was set - if err1 := agent.MysqlDaemon.SetReadOnly(false); err1 != nil { - log.Warningf("SetReadOnly(false) failed after failed fixSemiSync %v", err1) - } - if _ /* state changed */, err1 := agent.QueryServiceControl.SetServingType(tablet.Type, true, nil); err1 != nil { - log.Warningf("SetServingType(serving=true) failed after failed fixSemiSync %v", err1) - } return "", err } + defer func() { + if finalErr != nil && revertPartialFailure && wasMaster { + // enable master-side semi-sync again + if err := agent.fixSemiSync(topodatapb.TabletType_MASTER); err != nil { + log.Warningf("fixSemiSync(MASTER) failed during revert: %v", err) + } + } + }() + // Return the current replication position. pos, err := agent.MysqlDaemon.MasterPosition() if err != nil { - // if MasterPosition failed, undo all the steps before - // 1. set server back to read-only false - // setting read_only OFF will also set super_read_only OFF if it was set - if err1 := agent.MysqlDaemon.SetReadOnly(false); err1 != nil { - log.Warningf("SetReadOnly(false) failed after failed DemoteMaster %v", err1) - } - // 2. set tablet back to serving - if _ /* state changed */, err1 := agent.QueryServiceControl.SetServingType(tablet.Type, true, nil); err1 != nil { - log.Warningf("SetServingType(serving=true) failed after failed DemoteMaster %v", err1) - } - // 3. enable master side again - if err1 := agent.fixSemiSync(topodatapb.TabletType_MASTER); err1 != nil { - log.Warningf("fixSemiSync(MASTER) failed after failed DemoteMaster %v", err1) - } return "", err } return mysql.EncodePosition(pos), nil - // There is no serving graph update - the master tablet will - // be replaced. Even though writes may fail, reads will - // succeed. It will be less noisy to simply leave the entry - // until we'll promote the master. } // UndoDemoteMaster reverts a previous call to DemoteMaster @@ -450,11 +489,15 @@ func (agent *ActionAgent) PromoteSlaveWhenCaughtUp(ctx context.Context, position if err := agent.MysqlDaemon.SetReadOnly(false); err != nil { return "", err } - agent.setExternallyReparentedTime(startTime) - if _, err := topotools.ChangeType(ctx, agent.TopoServer, agent.TabletAlias, topodatapb.TabletType_MASTER); err != nil { + _, err = topotools.ChangeType(ctx, agent.TopoServer, agent.TabletAlias, topodatapb.TabletType_MASTER, logutil.TimeToProto(startTime)) + if err != nil { return "", err } + // We only update agent's masterTermStartTime if we were able to update the topo. + // This ensures that in case of a failure, we are never in a situation where the + // tablet's timestamp is ahead of the topo's timestamp. + agent.setMasterTermStartTime(startTime) if err := agent.refreshTablet(ctx, "PromoteSlaveWhenCaughtUp"); err != nil { return "", err @@ -469,10 +512,15 @@ func (agent *ActionAgent) SlaveWasPromoted(ctx context.Context) error { return err } defer agent.unlock() + startTime := time.Now() - if _, err := topotools.ChangeType(ctx, agent.TopoServer, agent.TabletAlias, topodatapb.TabletType_MASTER); err != nil { + if _, err := topotools.ChangeType(ctx, agent.TopoServer, agent.TabletAlias, topodatapb.TabletType_MASTER, logutil.TimeToProto(startTime)); err != nil { return err } + // We only update agent's masterTermStartTime if we were able to update the topo. + // This ensures that in case of a failure, we are never in a situation where the + // tablet's timestamp is ahead of the topo's timestamp. + agent.setMasterTermStartTime(startTime) if err := agent.refreshTablet(ctx, "SlaveWasPromoted"); err != nil { return err @@ -483,16 +531,28 @@ func (agent *ActionAgent) SlaveWasPromoted(ctx context.Context) error { // SetMaster sets replication master, and waits for the // reparent_journal table entry up to context timeout -func (agent *ActionAgent) SetMaster(ctx context.Context, parentAlias *topodatapb.TabletAlias, timeCreatedNS int64, forceStartSlave bool) error { +func (agent *ActionAgent) SetMaster(ctx context.Context, parentAlias *topodatapb.TabletAlias, timeCreatedNS int64, waitPosition string, forceStartSlave bool) error { if err := agent.lock(ctx); err != nil { return err } defer agent.unlock() - return agent.setMasterLocked(ctx, parentAlias, timeCreatedNS, forceStartSlave) + if err := agent.setMasterLocked(ctx, parentAlias, timeCreatedNS, waitPosition, forceStartSlave); err != nil { + return err + } + + // Always refresh the tablet, even if we may not have changed it. + // It's possible that we changed it earlier but failed to refresh. + // Note that we do this outside setMasterLocked() because this should never + // be done as part of setMasterRepairReplication(). + if err := agent.refreshTablet(ctx, "SetMaster"); err != nil { + return err + } + + return nil } -func (agent *ActionAgent) setMasterRepairReplication(ctx context.Context, parentAlias *topodatapb.TabletAlias, timeCreatedNS int64, forceStartSlave bool) (err error) { +func (agent *ActionAgent) setMasterRepairReplication(ctx context.Context, parentAlias *topodatapb.TabletAlias, timeCreatedNS int64, waitPosition string, forceStartSlave bool) (err error) { parent, err := agent.TopoServer.GetTablet(ctx, parentAlias) if err != nil { return err @@ -505,15 +565,10 @@ func (agent *ActionAgent) setMasterRepairReplication(ctx context.Context, parent defer unlock(&err) - return agent.setMasterLocked(ctx, parentAlias, timeCreatedNS, forceStartSlave) + return agent.setMasterLocked(ctx, parentAlias, timeCreatedNS, waitPosition, forceStartSlave) } -func (agent *ActionAgent) setMasterLocked(ctx context.Context, parentAlias *topodatapb.TabletAlias, timeCreatedNS int64, forceStartSlave bool) (err error) { - parent, err := agent.TopoServer.GetTablet(ctx, parentAlias) - if err != nil { - return err - } - +func (agent *ActionAgent) setMasterLocked(ctx context.Context, parentAlias *topodatapb.TabletAlias, timeCreatedNS int64, waitPosition string, forceStartSlave bool) (err error) { // End orchestrator maintenance at the end of fixing replication. // This is a best effort operation, so it should happen in a goroutine defer func() { @@ -527,11 +582,42 @@ func (agent *ActionAgent) setMasterLocked(ctx context.Context, parentAlias *topo }() }() - // See if we were replicating at all, and should be replicating + // Change our type to REPLICA if we used to be MASTER. + // Being sent SetMaster means another MASTER has been successfully promoted, + // so we convert to REPLICA first, since we want to do it even if other + // steps fail below. + // Note it is important to check for MASTER here so that we don't + // unintentionally change the type of RDONLY tablets + _, err = agent.TopoServer.UpdateTabletFields(ctx, agent.TabletAlias, func(tablet *topodatapb.Tablet) error { + if tablet.Type == topodatapb.TabletType_MASTER { + tablet.Type = topodatapb.TabletType_REPLICA + tablet.MasterTermStartTime = nil + return nil + } + return topo.NewError(topo.NoUpdateNeeded, agent.TabletAlias.String()) + }) + if err != nil { + return err + } + + // See if we were replicating at all, and should be replicating. wasReplicating := false shouldbeReplicating := false - rs, err := agent.MysqlDaemon.SlaveStatus() - if err == nil && (rs.SlaveIORunning || rs.SlaveSQLRunning) { + status, err := agent.MysqlDaemon.SlaveStatus() + if err == mysql.ErrNotSlave { + // This is a special error that means we actually succeeded in reading + // the status, but the status is empty because replication is not + // configured. We assume this means we used to be a master, so we always + // try to start replicating once we are told who the new master is. + shouldbeReplicating = true + // Since we continue in the case of this error, make sure 'status' is + // in a known, empty state. + status = mysql.SlaveStatus{} + } else if err != nil { + // Abort on any other non-nil error. + return err + } + if status.SlaveIORunning || status.SlaveSQLRunning { wasReplicating = true shouldbeReplicating = true } @@ -540,49 +626,58 @@ func (agent *ActionAgent) setMasterLocked(ctx context.Context, parentAlias *topo } // If using semi-sync, we need to enable it before connecting to master. - if *enableSemiSync { - tt := agent.Tablet().Type - if tt == topodatapb.TabletType_MASTER { - tt = topodatapb.TabletType_REPLICA - } - if err := agent.fixSemiSync(tt); err != nil { - return err - } + // If we are currently MASTER, assume we are about to become REPLICA. + tabletType := agent.Tablet().Type + if tabletType == topodatapb.TabletType_MASTER { + tabletType = topodatapb.TabletType_REPLICA } - - // Sets the master. - if err := agent.MysqlDaemon.SetMaster(ctx, topoproto.MysqlHostname(parent.Tablet), int(topoproto.MysqlPort(parent.Tablet)), wasReplicating, shouldbeReplicating); err != nil { + if err := agent.fixSemiSync(tabletType); err != nil { return err } - // change our type to REPLICA if we used to be the master - typeChanged := false - _, err = agent.TopoServer.UpdateTabletFields(ctx, agent.TabletAlias, func(tablet *topodatapb.Tablet) error { - if tablet.Type == topodatapb.TabletType_MASTER { - tablet.Type = topodatapb.TabletType_REPLICA - typeChanged = true - return nil - } - return topo.NewError(topo.NoUpdateNeeded, agent.TabletAlias.String()) - }) + // Update the master address only if needed. + // We don't want to interrupt replication for no reason. + parent, err := agent.TopoServer.GetTablet(ctx, parentAlias) if err != nil { return err } - - // if needed, wait until we get the replicated row, or our - // context times out - if !shouldbeReplicating || timeCreatedNS == 0 { - return nil - } - if err := agent.MysqlDaemon.WaitForReparentJournal(ctx, timeCreatedNS); err != nil { - return err - } - if typeChanged { - if err := agent.refreshTablet(ctx, "SetMaster"); err != nil { + masterHost := topoproto.MysqlHostname(parent.Tablet) + masterPort := int(topoproto.MysqlPort(parent.Tablet)) + if status.MasterHost != masterHost || status.MasterPort != masterPort { + // This handles both changing the address and starting replication. + if err := agent.MysqlDaemon.SetMaster(ctx, masterHost, masterPort, wasReplicating, shouldbeReplicating); err != nil { return err } - agent.runHealthCheckLocked() + } else if shouldbeReplicating { + // The address is correct. Just start replication if needed. + if !status.SlaveRunning() { + if err := agent.MysqlDaemon.StartSlave(agent.hookExtraEnv()); err != nil { + return err + } + } + } + + // If needed, wait until we replicate to the specified point, or our context + // times out. Callers can specify the point to wait for as either a + // GTID-based replication position or a Vitess reparent journal entry, + // or both. + if shouldbeReplicating { + if waitPosition != "" { + pos, err := mysql.DecodePosition(waitPosition) + if err != nil { + return err + } + if err := agent.MysqlDaemon.WaitMasterPos(ctx, pos); err != nil { + return err + } + } + if timeCreatedNS != 0 { + if err := agent.MysqlDaemon.WaitForReparentJournal(ctx, timeCreatedNS); err != nil { + return err + } + } } + return nil } @@ -593,12 +688,13 @@ func (agent *ActionAgent) SlaveWasRestarted(ctx context.Context, parent *topodat } defer agent.unlock() + // Only change type of former MASTER tablets. + // Don't change type of RDONLY typeChanged := false - - // Once this action completes, update authoritative tablet node first. if _, err := agent.TopoServer.UpdateTabletFields(ctx, agent.TabletAlias, func(tablet *topodatapb.Tablet) error { if tablet.Type == topodatapb.TabletType_MASTER { tablet.Type = topodatapb.TabletType_REPLICA + tablet.MasterTermStartTime = nil typeChanged = true return nil } @@ -666,11 +762,14 @@ func (agent *ActionAgent) PromoteSlave(ctx context.Context) (string, error) { if err := agent.MysqlDaemon.SetReadOnly(false); err != nil { return "", err } - agent.setExternallyReparentedTime(startTime) - if _, err := topotools.ChangeType(ctx, agent.TopoServer, agent.TabletAlias, topodatapb.TabletType_MASTER); err != nil { + if _, err := topotools.ChangeType(ctx, agent.TopoServer, agent.TabletAlias, topodatapb.TabletType_MASTER, logutil.TimeToProto(startTime)); err != nil { return "", err } + // We only update agent's masterTermStartTime if we were able to update the topo. + // This ensures that in case of a failure, we are never in a situation where the + // tablet's timestamp is ahead of the topo's timestamp. + agent.setMasterTermStartTime(startTime) if err := agent.refreshTablet(ctx, "PromoteSlave"); err != nil { return "", err diff --git a/go/vt/vttablet/tabletmanager/rpc_schema.go b/go/vt/vttablet/tabletmanager/rpc_schema.go index de6f802f23a..62e009f6916 100644 --- a/go/vt/vttablet/tabletmanager/rpc_schema.go +++ b/go/vt/vttablet/tabletmanager/rpc_schema.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vttablet/tabletmanager/rpc_server.go b/go/vt/vttablet/tabletmanager/rpc_server.go index de903e30d75..8a074a602f3 100644 --- a/go/vt/vttablet/tabletmanager/rpc_server.go +++ b/go/vt/vttablet/tabletmanager/rpc_server.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vttablet/tabletmanager/shard_sync.go b/go/vt/vttablet/tabletmanager/shard_sync.go new file mode 100644 index 00000000000..0d4684c588f --- /dev/null +++ b/go/vt/vttablet/tabletmanager/shard_sync.go @@ -0,0 +1,291 @@ +/* +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 tabletmanager + +import ( + "flag" + "time" + + "golang.org/x/net/context" + + "vitess.io/vitess/go/vt/log" + "vitess.io/vitess/go/vt/logutil" + "vitess.io/vitess/go/vt/mysqlctl" + 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/vterrors" +) + +var ( + shardSyncRetryDelay = flag.Duration("shard_sync_retry_delay", 30*time.Second, "delay between retries of updates to keep the tablet and its shard record in sync") +) + +// shardSyncLoop is a loop that tries to keep the tablet state and the +// shard record in sync. +// +// It is launched as a background goroutine in the tablet because it may need to +// initiate a tablet state change in response to an incoming watch event for the +// shard record, and it may need to continually retry updating the shard record +// if it's out of sync with the tablet state. At steady state, when the tablet +// and shard record are in sync, this goroutine goes to sleep waiting for +// something to change in either the tablet state or in the shard record. +// +// This goroutine gets woken up for shard record changes by maintaining a +// topo watch on the shard record. It gets woken up for tablet state changes by +// a notification signal from setTablet(). +func (agent *ActionAgent) shardSyncLoop(ctx context.Context) { + // Make a copy of the channel so we don't race when stopShardSync() clears it. + agent.mutex.Lock() + notifyChan := agent._shardSyncChan + agent.mutex.Unlock() + + // retryChan is how we wake up after going to sleep between retries. + // If no retry is pending, this channel will be nil, which means it's fine + // to always select on it -- a nil channel is never ready. + var retryChan <-chan time.Time + + // shardWatch is how we get notified when the shard record is updated. + // We only watch the shard record while we are master. + shardWatch := &shardWatcher{} + defer shardWatch.stop() + + // This loop sleeps until it's notified that something may have changed. + // Then it wakes up to check if anything needs to be synchronized. + for { + select { + case <-notifyChan: + // Something may have changed in the tablet state. + log.Info("Change to tablet state") + case <-retryChan: + // It's time to retry a previous failed sync attempt. + log.Info("Retry sync") + case event := <-shardWatch.watchChan: + // Something may have changed in the shard record. + // We don't use the watch event except to know that we should + // re-read the shard record, and to know if the watch dies. + log.Info("Change in shard record") + if event.Err != nil { + // The watch failed. Stop it so we start a new one if needed. + log.Errorf("Shard watch failed: %v", event.Err) + shardWatch.stop() + } + case <-ctx.Done(): + // Our context was cancelled. Terminate the loop. + return + } + + // Disconnect any pending retry timer since we're already retrying for + // another reason. + retryChan = nil + + // Get the latest internal tablet value, representing what we think we are. + tablet := agent.Tablet() + + switch tablet.Type { + case topodatapb.TabletType_MASTER: + // If we think we're master, check if we need to update the shard record. + masterAlias, err := syncShardMaster(ctx, agent.TopoServer, tablet, agent.masterTermStartTime()) + if err != nil { + log.Errorf("Failed to sync shard record: %v", err) + // Start retry timer and go back to sleep. + retryChan = time.After(*shardSyncRetryDelay) + continue + } + if !topoproto.TabletAliasEqual(masterAlias, tablet.Alias) { + // Another master has taken over while we still think we're master. + if err := agent.abortMasterTerm(ctx, masterAlias); err != nil { + log.Errorf("Failed to abort master term: %v", err) + // Start retry timer and go back to sleep. + retryChan = time.After(*shardSyncRetryDelay) + continue + } + // We're not master anymore, so stop watching the shard record. + shardWatch.stop() + continue + } + + // As long as we're master, watch the shard record so we'll be + // notified if another master takes over. + if shardWatch.active() { + // We already have an active watch. Nothing to do. + continue + } + if err := shardWatch.start(ctx, agent.TopoServer, tablet.Keyspace, tablet.Shard); err != nil { + log.Errorf("Failed to start shard watch: %v", err) + // Start retry timer and go back to sleep. + retryChan = time.After(*shardSyncRetryDelay) + continue + } + default: + // If we're not master, stop watching the shard record, + // so only masters contribute to global topo watch load. + shardWatch.stop() + } + } +} + +// syncShardMaster is called when we think we're master. +// It checks that the shard record agrees, and updates it if possible. +// +// If the returned error is nil, the returned masterAlias indicates the current +// master tablet according to the shard record. +// +// If the shard record indicates a new master has taken over, this returns +// success (we successfully synchronized), but the returned masterAlias will be +// different from the input tablet.Alias. +func syncShardMaster(ctx context.Context, ts *topo.Server, tablet *topodatapb.Tablet, masterTermStartTime time.Time) (masterAlias *topodatapb.TabletAlias, err error) { + ctx, cancel := context.WithTimeout(ctx, *topo.RemoteOperationTimeout) + defer cancel() + + var shardInfo *topo.ShardInfo + _, err = ts.UpdateShardFields(ctx, tablet.Keyspace, tablet.Shard, func(si *topo.ShardInfo) error { + lastTerm := si.GetMasterTermStartTime() + + // Save the ShardInfo so we can check it afterward. + // We can't use the return value of UpdateShardFields because it might be nil. + shardInfo = si + + // Only attempt an update if our term is more recent. + if !masterTermStartTime.After(lastTerm) { + return topo.NewError(topo.NoUpdateNeeded, si.ShardName()) + } + + aliasStr := topoproto.TabletAliasString(tablet.Alias) + log.Infof("Updating shard record: master_alias=%v, master_term_start_time=%v", aliasStr, masterTermStartTime) + si.MasterAlias = tablet.Alias + si.MasterTermStartTime = logutil.TimeToProto(masterTermStartTime) + return nil + }) + if err != nil { + return nil, err + } + + return shardInfo.MasterAlias, nil +} + +// abortMasterTerm is called when we unexpectedly lost mastership. +// +// Under normal circumstances, we should be gracefully demoted before a new +// master appears. This function is only reached when that graceful demotion +// failed or was skipped, so we only found out we're no longer master after the +// new master started advertising itself. +// +// If active reparents are enabled, we demote our own MySQL to a replica and +// update our tablet type to REPLICA. +// +// If active reparents are disabled, we don't touch our MySQL. +// We just directly update our tablet type to REPLICA. +func (agent *ActionAgent) abortMasterTerm(ctx context.Context, masterAlias *topodatapb.TabletAlias) error { + masterAliasStr := topoproto.TabletAliasString(masterAlias) + log.Warningf("Another tablet (%v) has won master election. Stepping down to REPLICA.", masterAliasStr) + + if *mysqlctl.DisableActiveReparents { + // Don't touch anything at the MySQL level. Just update tablet state. + log.Infof("Active reparents are disabled; updating tablet state only.") + changeTypeCtx, cancel := context.WithTimeout(ctx, *topo.RemoteOperationTimeout) + defer cancel() + if err := agent.ChangeType(changeTypeCtx, topodatapb.TabletType_REPLICA); err != nil { + return vterrors.Wrap(err, "failed to change type to REPLICA") + } + return nil + } + + // Do a full demotion to convert MySQL into a replica. + // We do not revert on partial failure here because this code path only + // triggers after a new master has taken over, so we are past the point of + // no return. Instead, we should leave partial results and retry the rest + // later. + log.Infof("Active reparents are enabled; converting MySQL to replica.") + demoteMasterCtx, cancelDemoteMaster := context.WithTimeout(ctx, *topo.RemoteOperationTimeout) + defer cancelDemoteMaster() + if _, err := agent.demoteMaster(demoteMasterCtx, false /* revertPartialFailure */); err != nil { + return vterrors.Wrap(err, "failed to demote master") + } + setMasterCtx, cancelSetMaster := context.WithTimeout(ctx, *topo.RemoteOperationTimeout) + defer cancelSetMaster() + log.Infof("Attempting to reparent self to new master %v.", masterAliasStr) + if err := agent.SetMaster(setMasterCtx, masterAlias, 0, "", true); err != nil { + return vterrors.Wrap(err, "failed to reparent self to new master") + } + return nil +} + +func (agent *ActionAgent) startShardSync() { + // Use a buffer size of 1 so we can remember we need to check the state + // even if the receiver is busy. We can drop any additional send attempts + // if the buffer is full because all we care about is that the receiver will + // be told it needs to recheck the state. + agent.mutex.Lock() + agent._shardSyncChan = make(chan struct{}, 1) + ctx, cancel := context.WithCancel(context.Background()) + agent._shardSyncCancel = cancel + agent.mutex.Unlock() + + // Queue up a pending notification to force the loop to run once at startup. + agent.notifyShardSync() + + // Start the sync loop in the background. + go agent.shardSyncLoop(ctx) +} + +func (agent *ActionAgent) stopShardSync() { + agent.mutex.Lock() + if agent._shardSyncCancel != nil { + agent._shardSyncCancel() + agent._shardSyncCancel = nil + agent._shardSyncChan = nil + } + agent.mutex.Unlock() +} + +func (agent *ActionAgent) notifyShardSync() { + // If this is called before the shard sync is started, do nothing. + agent.mutex.Lock() + defer agent.mutex.Unlock() + + if agent._shardSyncChan == nil { + return + } + + // Try to send. If the channel buffer is full, it means a notification is + // already pending, so we don't need to do anything. + select { + case agent._shardSyncChan <- struct{}{}: + default: + } +} + +// setMasterTermStartTime remembers the time when our term as master began. +// +// If another tablet claims to be master and offers a more recent time, +// that tablet will be trusted over us. +func (agent *ActionAgent) setMasterTermStartTime(t time.Time) { + agent.mutex.Lock() + agent._masterTermStartTime = t + agent._replicationDelay = 0 + agent.mutex.Unlock() + + // Notify the shard sync loop that the tablet state changed. + agent.notifyShardSync() +} + +func (agent *ActionAgent) masterTermStartTime() time.Time { + agent.mutex.Lock() + defer agent.mutex.Unlock() + return agent._masterTermStartTime +} diff --git a/go/vt/vttablet/tabletmanager/shard_watcher.go b/go/vt/vttablet/tabletmanager/shard_watcher.go new file mode 100644 index 00000000000..1688c1a27f2 --- /dev/null +++ b/go/vt/vttablet/tabletmanager/shard_watcher.go @@ -0,0 +1,65 @@ +/* +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 tabletmanager + +import ( + "golang.org/x/net/context" + + "vitess.io/vitess/go/vt/log" + "vitess.io/vitess/go/vt/topo" +) + +type shardWatcher struct { + watchChan <-chan *topo.WatchShardData + watchCancel topo.CancelFunc +} + +func (sw *shardWatcher) active() bool { + return sw.watchChan != nil +} + +func (sw *shardWatcher) start(ctx context.Context, ts *topo.Server, keyspace, shard string) error { + ctx, cancel := context.WithTimeout(ctx, *topo.RemoteOperationTimeout) + defer cancel() + + log.Infof("Starting shard watch of %v/%v", keyspace, shard) + + event, c, watchCancel := ts.WatchShard(ctx, keyspace, shard) + if event.Err != nil { + return event.Err + } + + sw.watchChan = c + sw.watchCancel = watchCancel + return nil +} + +func (sw *shardWatcher) stop() { + if !sw.active() { + return + } + + sw.watchCancel() + + // Drain all remaining watch events. + log.Infof("Stopping shard watch...") + for range sw.watchChan { + } + + sw.watchChan = nil + sw.watchCancel = nil +} diff --git a/go/vt/vttablet/tabletmanager/state_change.go b/go/vt/vttablet/tabletmanager/state_change.go index 4654f8f32c2..620335277c6 100644 --- a/go/vt/vttablet/tabletmanager/state_change.go +++ b/go/vt/vttablet/tabletmanager/state_change.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -29,6 +29,7 @@ import ( "vitess.io/vitess/go/trace" "vitess.io/vitess/go/vt/key" "vitess.io/vitess/go/vt/log" + "vitess.io/vitess/go/vt/logutil" "vitess.io/vitess/go/vt/mysqlctl" querypb "vitess.io/vitess/go/vt/proto/query" topodatapb "vitess.io/vitess/go/vt/proto/topodata" @@ -101,7 +102,7 @@ func (agent *ActionAgent) broadcastHealth() { agent.mutex.Lock() replicationDelay := agent._replicationDelay healthError := agent._healthy - terTime := agent._tabletExternallyReparentedTime + terTime := agent._masterTermStartTime healthyTime := agent._healthyTime agent.mutex.Unlock() @@ -153,7 +154,10 @@ func (agent *ActionAgent) refreshTablet(ctx context.Context, reason string) erro if updatedTablet := agent.checkTabletMysqlPort(ctx, tablet); updatedTablet != nil { tablet = updatedTablet } - + // Also refresh masterTermStartTime + if tablet.MasterTermStartTime != nil { + agent.setMasterTermStartTime(logutil.ProtoToTime(tablet.MasterTermStartTime)) + } agent.updateState(ctx, tablet, reason) log.Infof("Done with post-action state refresh") return nil @@ -203,7 +207,10 @@ func (agent *ActionAgent) changeCallback(ctx context.Context, oldTablet, newTabl // we're going to use it. var shardInfo *topo.ShardInfo var err error + // this is just for logging var disallowQueryReason string + // this is actually used to set state + var disallowQueryService string var blacklistedTables []string updateBlacklistedTables := true if allowQuery { @@ -212,10 +219,35 @@ func (agent *ActionAgent) changeCallback(ctx context.Context, oldTablet, newTabl log.Errorf("Cannot read shard for this tablet %v, might have inaccurate SourceShards and TabletControls: %v", newTablet.Alias, err) updateBlacklistedTables = false } else { - if newTablet.Type == topodatapb.TabletType_MASTER { - if len(shardInfo.SourceShards) > 0 { - allowQuery = false - disallowQueryReason = "master tablet with filtered replication on" + if oldTablet.Type == topodatapb.TabletType_RESTORE { + // always start as NON-SERVING after a restore because + // healthcheck has not been initialized yet + allowQuery = false + // setting disallowQueryService permanently turns off query service + // since we want it to be temporary (until tablet is healthy) we don't set it + // disallowQueryReason is only used for logging + disallowQueryReason = "after restore from backup" + } else { + if newTablet.Type == topodatapb.TabletType_MASTER { + if len(shardInfo.SourceShards) > 0 { + allowQuery = false + disallowQueryReason = "master tablet with filtered replication on" + disallowQueryService = disallowQueryReason + } + } else { + replicationDelay, healthErr := agent.HealthReporter.Report(true, true) + if healthErr != nil { + allowQuery = false + disallowQueryReason = "unable to get health" + } else { + agent.mutex.Lock() + agent._replicationDelay = replicationDelay + agent.mutex.Unlock() + if agent._replicationDelay > *unhealthyThreshold { + allowQuery = false + disallowQueryReason = "replica tablet with unhealthy replication lag" + } + } } } srvKeyspace, err := agent.TopoServer.GetSrvKeyspace(ctx, newTablet.Alias.Cell, newTablet.Keyspace) @@ -233,6 +265,7 @@ func (agent *ActionAgent) changeCallback(ctx context.Context, oldTablet, newTabl if tabletControl.QueryServiceDisabled { allowQuery = false disallowQueryReason = "TabletControl.DisableQueryService set" + disallowQueryService = disallowQueryReason } break } @@ -248,8 +281,9 @@ func (agent *ActionAgent) changeCallback(ctx context.Context, oldTablet, newTabl } } else { disallowQueryReason = fmt.Sprintf("not a serving tablet type(%v)", newTablet.Type) + disallowQueryService = disallowQueryReason } - agent.setServicesDesiredState(disallowQueryReason, runUpdateStream) + agent.setServicesDesiredState(disallowQueryService, runUpdateStream) if updateBlacklistedTables { if err := agent.loadBlacklistRules(newTablet, blacklistedTables); err != nil { // FIXME(alainjobart) how to handle this error? diff --git a/go/vt/vttablet/tabletmanager/vreplication.go b/go/vt/vttablet/tabletmanager/vreplication.go index 091b5ea1ec8..d8dd142abdf 100644 --- a/go/vt/vttablet/tabletmanager/vreplication.go +++ b/go/vt/vttablet/tabletmanager/vreplication.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Vitess Authors. +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. diff --git a/go/vt/vttablet/tabletmanager/vreplication/controller.go b/go/vt/vttablet/tabletmanager/vreplication/controller.go index 41c333aa9f5..85c957ecb3f 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/controller.go +++ b/go/vt/vttablet/tabletmanager/vreplication/controller.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Vitess Authors. +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. @@ -22,6 +22,7 @@ import ( "strconv" "time" + "vitess.io/vitess/go/vt/discovery" "vitess.io/vitess/go/vt/vterrors" "github.com/golang/protobuf/proto" @@ -37,7 +38,12 @@ import ( binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" ) -var retryDelay = flag.Duration("vreplication_retry_delay", 5*time.Second, "delay before retrying a failed binlog connection") +var ( + healthcheckTopologyRefresh = flag.Duration("vreplication_healthcheck_topology_refresh", 30*time.Second, "refresh interval for re-reading the topology") + healthcheckRetryDelay = flag.Duration("vreplication_healthcheck_retry_delay", 5*time.Second, "healthcheck retry delay") + healthcheckTimeout = flag.Duration("vreplication_healthcheck_timeout", 1*time.Minute, "healthcheck retry delay") + retryDelay = flag.Duration("vreplication_retry_delay", 5*time.Second, "delay before retrying a failed binlog connection") +) // controller is created by Engine. Members are initialized upfront. // There is no mutex within a controller becaust its members are @@ -50,7 +56,7 @@ type controller struct { id uint32 source binlogdatapb.BinlogSource stopPos string - tabletPicker *tabletPicker + tabletPicker *discovery.TabletPicker cancel context.CancelFunc done chan struct{} @@ -99,7 +105,7 @@ func newController(ctx context.Context, params map[string]string, dbClientFactor if v, ok := params["tablet_types"]; ok { tabletTypesStr = v } - tp, err := newTabletPicker(ctx, ts, cell, ct.source.Keyspace, ct.source.Shard, tabletTypesStr) + tp, err := discovery.NewTabletPicker(ctx, ts, cell, ct.source.Keyspace, ct.source.Shard, tabletTypesStr, *healthcheckTopologyRefresh, *healthcheckRetryDelay, *healthcheckTimeout) if err != nil { return nil, err } @@ -169,7 +175,7 @@ func (ct *controller) runBlp(ctx context.Context) (err error) { } defer dbClient.Close() - tablet, err := ct.tabletPicker.Pick(ctx) + tablet, err := ct.tabletPicker.PickForStreaming(ctx) if err != nil { return err } diff --git a/go/vt/vttablet/tabletmanager/vreplication/controller_plan.go b/go/vt/vttablet/tabletmanager/vreplication/controller_plan.go index e3c73415a1f..d8688ac1ee1 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/controller_plan.go +++ b/go/vt/vttablet/tabletmanager/vreplication/controller_plan.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Vitess Authors. +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. @@ -18,18 +18,24 @@ package vreplication import ( "fmt" - "strconv" "vitess.io/vitess/go/vt/sqlparser" ) // controllerPlan is the plan for vreplication control statements. type controllerPlan struct { - opcode int query string - // delCopySate is set for deletes. - delCopyState string - id int + opcode int + + // numInserts is set for insertQuery. + numInserts int + + // selector and applier are set for updateQuery and deleteQuery. + selector string + applier *sqlparser.ParsedQuery + + // delCopyState is set of deletes. + delCopyState *sqlparser.ParsedQuery } const ( @@ -46,18 +52,24 @@ func buildControllerPlan(query string) (*controllerPlan, error) { if err != nil { return nil, err } + var plan *controllerPlan switch stmt := stmt.(type) { case *sqlparser.Insert: - return buildInsertPlan(stmt) + plan, err = buildInsertPlan(stmt) case *sqlparser.Update: - return buildUpdatePlan(stmt) + plan, err = buildUpdatePlan(stmt) case *sqlparser.Delete: - return buildDeletePlan(stmt) + plan, err = buildDeletePlan(stmt) case *sqlparser.Select: - return buildSelectPlan(stmt) + plan, err = buildSelectPlan(stmt) default: return nil, fmt.Errorf("unsupported construct: %s", sqlparser.String(stmt)) } + if err != nil { + return nil, err + } + plan.query = query + return plan, nil } func buildInsertPlan(ins *sqlparser.Insert) (*controllerPlan, error) { @@ -65,7 +77,6 @@ func buildInsertPlan(ins *sqlparser.Insert) (*controllerPlan, error) { case reshardingJournalTableName: return &controllerPlan{ opcode: reshardingJournalQuery, - query: sqlparser.String(ins), }, nil case vreplicationTableName: // no-op @@ -88,15 +99,8 @@ func buildInsertPlan(ins *sqlparser.Insert) (*controllerPlan, error) { if !ok { return nil, fmt.Errorf("unsupported construct: %v", sqlparser.String(ins)) } - if len(rows) != 1 { - return nil, fmt.Errorf("unsupported construct: %v", sqlparser.String(ins)) - } - row := rows[0] idPos := 0 if len(ins.Columns) != 0 { - if len(ins.Columns) != len(row) { - return nil, fmt.Errorf("malformed statement: %v", sqlparser.String(ins)) - } idPos = -1 for i, col := range ins.Columns { if col.EqualString("id") { @@ -106,13 +110,18 @@ func buildInsertPlan(ins *sqlparser.Insert) (*controllerPlan, error) { } } if idPos >= 0 { - if _, ok := row[idPos].(*sqlparser.NullVal); !ok { - return nil, fmt.Errorf("id should not have a value: %v", sqlparser.String(ins)) + for _, row := range rows { + if idPos >= len(row) { + return nil, fmt.Errorf("malformed statement: %v", sqlparser.String(ins)) + } + if _, ok := row[idPos].(*sqlparser.NullVal); !ok { + return nil, fmt.Errorf("id should not have a value: %v", sqlparser.String(ins)) + } } } return &controllerPlan{ - opcode: insertQuery, - query: sqlparser.String(ins), + opcode: insertQuery, + numInserts: len(rows), }, nil } @@ -121,7 +130,6 @@ func buildUpdatePlan(upd *sqlparser.Update) (*controllerPlan, error) { case reshardingJournalTableName: return &controllerPlan{ opcode: reshardingJournalQuery, - query: sqlparser.String(upd), }, nil case vreplicationTableName: // no-op @@ -137,15 +145,24 @@ func buildUpdatePlan(upd *sqlparser.Update) (*controllerPlan, error) { } } - id, err := extractID(upd.Where) - if err != nil { - return nil, err + buf1 := sqlparser.NewTrackedBuffer(nil) + buf1.Myprintf("select id from %s%v", vreplicationTableName, upd.Where) + upd.Where = &sqlparser.Where{ + Type: sqlparser.WhereStr, + Expr: &sqlparser.ComparisonExpr{ + Left: &sqlparser.ColName{Name: sqlparser.NewColIdent("id")}, + Operator: sqlparser.InStr, + Right: sqlparser.ListArg("::ids"), + }, } + buf2 := sqlparser.NewTrackedBuffer(nil) + buf2.Myprintf("%v", upd) + return &controllerPlan{ - opcode: updateQuery, - query: sqlparser.String(upd), - id: id, + opcode: updateQuery, + selector: buf1.String(), + applier: buf2.ParsedQuery(), }, nil } @@ -154,7 +171,6 @@ func buildDeletePlan(del *sqlparser.Delete) (*controllerPlan, error) { case reshardingJournalTableName: return &controllerPlan{ opcode: reshardingJournalQuery, - query: sqlparser.String(del), }, nil case vreplicationTableName: // no-op @@ -171,49 +187,46 @@ func buildDeletePlan(del *sqlparser.Delete) (*controllerPlan, error) { return nil, fmt.Errorf("unsupported construct: %v", sqlparser.String(del)) } - id, err := extractID(del.Where) - if err != nil { - return nil, err + buf1 := sqlparser.NewTrackedBuffer(nil) + buf1.Myprintf("select id from %s%v", vreplicationTableName, del.Where) + del.Where = &sqlparser.Where{ + Type: sqlparser.WhereStr, + Expr: &sqlparser.ComparisonExpr{ + Left: &sqlparser.ColName{Name: sqlparser.NewColIdent("id")}, + Operator: sqlparser.InStr, + Right: sqlparser.ListArg("::ids"), + }, + } + + buf2 := sqlparser.NewTrackedBuffer(nil) + buf2.Myprintf("%v", del) + + copyStateWhere := &sqlparser.Where{ + Type: sqlparser.WhereStr, + Expr: &sqlparser.ComparisonExpr{ + Left: &sqlparser.ColName{Name: sqlparser.NewColIdent("vrepl_id")}, + Operator: sqlparser.InStr, + Right: sqlparser.ListArg("::ids"), + }, } + buf3 := sqlparser.NewTrackedBuffer(nil) + buf3.Myprintf("delete from %s%v", copyStateTableName, copyStateWhere) return &controllerPlan{ opcode: deleteQuery, - query: sqlparser.String(del), - delCopyState: fmt.Sprintf("delete from %s where vrepl_id = %d", copySateTableName, id), - id: id, + selector: buf1.String(), + applier: buf2.ParsedQuery(), + delCopyState: buf3.ParsedQuery(), }, nil } func buildSelectPlan(sel *sqlparser.Select) (*controllerPlan, error) { switch sqlparser.String(sel.From) { - case vreplicationTableName, reshardingJournalTableName, copySateTableName: + case vreplicationTableName, reshardingJournalTableName, copyStateTableName: return &controllerPlan{ opcode: selectQuery, - query: sqlparser.String(sel), }, nil default: return nil, fmt.Errorf("invalid table name: %v", sqlparser.String(sel.From)) } } - -func extractID(where *sqlparser.Where) (int, error) { - if where == nil { - return 0, fmt.Errorf("invalid where clause:%v", sqlparser.String(where)) - } - comp, ok := where.Expr.(*sqlparser.ComparisonExpr) - if !ok { - return 0, fmt.Errorf("invalid where clause:%v", sqlparser.String(where)) - } - if sqlparser.String(comp.Left) != "id" { - return 0, fmt.Errorf("invalid where clause:%v", sqlparser.String(where)) - } - if comp.Operator != sqlparser.EqualStr { - return 0, fmt.Errorf("invalid where clause:%v", sqlparser.String(where)) - } - - id, err := strconv.Atoi(sqlparser.String(comp.Right)) - if err != nil { - return 0, fmt.Errorf("invalid where clause:%v", sqlparser.String(where)) - } - return id, nil -} diff --git a/go/vt/vttablet/tabletmanager/vreplication/controller_plan_test.go b/go/vt/vttablet/tabletmanager/vreplication/controller_plan_test.go index ecdb32e6483..58b7b2ef2b3 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/controller_plan_test.go +++ b/go/vt/vttablet/tabletmanager/vreplication/controller_plan_test.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Vitess Authors. +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. @@ -21,35 +21,54 @@ import ( "testing" ) +type testControllerPlan struct { + query string + opcode int + numInserts int + selector string + applier string + delCopyState string +} + func TestControllerPlan(t *testing.T) { tcases := []struct { in string - plan *controllerPlan + plan *testControllerPlan err string }{{ // Insert in: "insert into _vt.vreplication values(null)", - plan: &controllerPlan{ - opcode: insertQuery, - query: "insert into _vt.vreplication values (null)", + plan: &testControllerPlan{ + query: "insert into _vt.vreplication values(null)", + opcode: insertQuery, + numInserts: 1, }, }, { in: "insert into _vt.vreplication(id) values(null)", - plan: &controllerPlan{ - opcode: insertQuery, - query: "insert into _vt.vreplication(id) values (null)", + plan: &testControllerPlan{ + query: "insert into _vt.vreplication(id) values(null)", + opcode: insertQuery, + numInserts: 1, }, }, { in: "insert into _vt.vreplication(workflow, id) values('', null)", - plan: &controllerPlan{ - opcode: insertQuery, - query: "insert into _vt.vreplication(workflow, id) values ('', null)", + plan: &testControllerPlan{ + query: "insert into _vt.vreplication(workflow, id) values('', null)", + opcode: insertQuery, + numInserts: 1, + }, + }, { + in: "insert into _vt.vreplication values(null), (null)", + plan: &testControllerPlan{ + query: "insert into _vt.vreplication values(null), (null)", + opcode: insertQuery, + numInserts: 2, }, }, { in: "insert into _vt.resharding_journal values (1)", - plan: &controllerPlan{ - opcode: reshardingJournalQuery, + plan: &testControllerPlan{ query: "insert into _vt.resharding_journal values (1)", + opcode: reshardingJournalQuery, }, }, { in: "replace into _vt.vreplication values(null)", @@ -70,11 +89,8 @@ func TestControllerPlan(t *testing.T) { in: "insert into _vt.vreplication select * from a", err: "unsupported construct: insert into _vt.vreplication select * from a", }, { - in: "insert into _vt.vreplication values(null), (null)", - err: "unsupported construct: insert into _vt.vreplication values (null), (null)", - }, { - in: "insert into _vt.vreplication(a, b, c) values(null)", - err: "malformed statement: insert into _vt.vreplication(a, b, c) values (null)", + in: "insert into _vt.vreplication(a, b, id) values(null)", + err: "malformed statement: insert into _vt.vreplication(a, b, id) values (null)", }, { in: "insert into _vt.vreplication(workflow, id) values('aa', 1)", err: "id should not have a value: insert into _vt.vreplication(workflow, id) values ('aa', 1)", @@ -85,16 +101,33 @@ func TestControllerPlan(t *testing.T) { // Update }, { in: "update _vt.vreplication set state='Running' where id = 1", - plan: &controllerPlan{ - opcode: updateQuery, - query: "update _vt.vreplication set state = 'Running' where id = 1", - id: 1, + plan: &testControllerPlan{ + query: "update _vt.vreplication set state='Running' where id = 1", + opcode: updateQuery, + selector: "select id from _vt.vreplication where id = 1", + applier: "update _vt.vreplication set state = 'Running' where id in ::ids", + }, + }, { + in: "update _vt.vreplication set state='Running'", + plan: &testControllerPlan{ + query: "update _vt.vreplication set state='Running'", + opcode: updateQuery, + selector: "select id from _vt.vreplication", + applier: "update _vt.vreplication set state = 'Running' where id in ::ids", + }, + }, { + in: "update _vt.vreplication set state='Running' where a = 1", + plan: &testControllerPlan{ + query: "update _vt.vreplication set state='Running' where a = 1", + opcode: updateQuery, + selector: "select id from _vt.vreplication where a = 1", + applier: "update _vt.vreplication set state = 'Running' where id in ::ids", }, }, { in: "update _vt.resharding_journal set col = 1", - plan: &controllerPlan{ - opcode: reshardingJournalQuery, + plan: &testControllerPlan{ query: "update _vt.resharding_journal set col = 1", + opcode: reshardingJournalQuery, }, }, { in: "update a set state='Running' where id = 1", @@ -108,36 +141,40 @@ func TestControllerPlan(t *testing.T) { }, { in: "update _vt.vreplication set state='Running', id = 2 where id = 1", err: "id cannot be changed: id = 2", - }, { - in: "update _vt.vreplication set state='Running'", - err: "invalid where clause:", - }, { - in: "update _vt.vreplication set state='Running' where a = 1 and id = 2", - err: "invalid where clause: where a = 1 and id = 2", - }, { - in: "update _vt.vreplication set state='Running' where a = 1", - err: "invalid where clause: where a = 1", - }, { - in: "update _vt.vreplication set state='Running' where id > 1", - err: "invalid where clause: where id > 1", - }, { - in: "update _vt.vreplication set state='Running' where id = 1.1", - err: "invalid where clause: where id = 1.1", // Delete }, { in: "delete from _vt.vreplication where id = 1", - plan: &controllerPlan{ - opcode: deleteQuery, + plan: &testControllerPlan{ query: "delete from _vt.vreplication where id = 1", - delCopyState: "delete from _vt.copy_state where vrepl_id = 1", - id: 1, + opcode: deleteQuery, + selector: "select id from _vt.vreplication where id = 1", + applier: "delete from _vt.vreplication where id in ::ids", + delCopyState: "delete from _vt.copy_state where vrepl_id in ::ids", + }, + }, { + in: "delete from _vt.vreplication", + plan: &testControllerPlan{ + query: "delete from _vt.vreplication", + opcode: deleteQuery, + selector: "select id from _vt.vreplication", + applier: "delete from _vt.vreplication where id in ::ids", + delCopyState: "delete from _vt.copy_state where vrepl_id in ::ids", + }, + }, { + in: "delete from _vt.vreplication where a = 1", + plan: &testControllerPlan{ + query: "delete from _vt.vreplication where a = 1", + opcode: deleteQuery, + selector: "select id from _vt.vreplication where a = 1", + applier: "delete from _vt.vreplication where id in ::ids", + delCopyState: "delete from _vt.copy_state where vrepl_id in ::ids", }, }, { in: "delete from _vt.resharding_journal where id = 1", - plan: &controllerPlan{ - opcode: reshardingJournalQuery, + plan: &testControllerPlan{ query: "delete from _vt.resharding_journal where id = 1", + opcode: reshardingJournalQuery, }, }, { in: "delete from a where id = 1", @@ -154,38 +191,23 @@ func TestControllerPlan(t *testing.T) { }, { in: "delete from _vt.vreplication partition (a) where id = 1 limit 1", err: "unsupported construct: delete from _vt.vreplication partition (a) where id = 1 limit 1", - }, { - in: "delete from _vt.vreplication", - err: "invalid where clause:", - }, { - in: "delete from _vt.vreplication where a = 1 and id = 2", - err: "invalid where clause: where a = 1 and id = 2", - }, { - in: "delete from _vt.vreplication where a = 1", - err: "invalid where clause: where a = 1", - }, { - in: "delete from _vt.vreplication where id > 1", - err: "invalid where clause: where id > 1", - }, { - in: "delete from _vt.vreplication where id = 1.1", - err: "invalid where clause: where id = 1.1", // Select }, { in: "select * from _vt.vreplication", - plan: &controllerPlan{ + plan: &testControllerPlan{ opcode: selectQuery, query: "select * from _vt.vreplication", }, }, { in: "select * from _vt.resharding_journal", - plan: &controllerPlan{ + plan: &testControllerPlan{ opcode: selectQuery, query: "select * from _vt.resharding_journal", }, }, { in: "select * from _vt.copy_state", - plan: &controllerPlan{ + plan: &testControllerPlan{ opcode: selectQuery, query: "select * from _vt.copy_state", }, @@ -213,8 +235,20 @@ func TestControllerPlan(t *testing.T) { t.Errorf("getPlan(%v) error:\n%v, want\n%v", tcase.in, err, tcase.err) continue } - if !reflect.DeepEqual(pl, tcase.plan) { - t.Errorf("getPlan(%v):\n%+v, want\n%+v", tcase.in, pl, tcase.plan) + gotPlan := &testControllerPlan{ + query: pl.query, + opcode: pl.opcode, + numInserts: pl.numInserts, + selector: pl.selector, + } + if pl.applier != nil { + gotPlan.applier = pl.applier.Query + } + if pl.delCopyState != nil { + gotPlan.delCopyState = pl.delCopyState.Query + } + if !reflect.DeepEqual(gotPlan, tcase.plan) { + t.Errorf("getPlan(%v):\n%+v, want\n%+v", tcase.in, gotPlan, tcase.plan) } } } diff --git a/go/vt/vttablet/tabletmanager/vreplication/controller_test.go b/go/vt/vttablet/tabletmanager/vreplication/controller_test.go index ba858cf04d3..b6cf8a3ba11 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/controller_test.go +++ b/go/vt/vttablet/tabletmanager/vreplication/controller_test.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Vitess Authors. +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. @@ -48,13 +48,15 @@ var ( }, }, } - testDMLResponse = &sqltypes.Result{RowsAffected: 1} - testPos = "MariaDB/0-1-1083" + testSelectorResponse1 = &sqltypes.Result{Rows: [][]sqltypes.Value{{sqltypes.NewInt64(1)}}} + testSelectorResponse2 = &sqltypes.Result{Rows: [][]sqltypes.Value{{sqltypes.NewInt64(1)}, {sqltypes.NewInt64(2)}}} + testDMLResponse = &sqltypes.Result{RowsAffected: 1} + testPos = "MariaDB/0-1-1083" ) func TestControllerKeyRange(t *testing.T) { resetBinlogClient() - wantTablet := addTablet(100, "0", topodatapb.TabletType_REPLICA, true, true) + wantTablet := addTablet(100) defer deleteTablet(wantTablet) params := map[string]string{ @@ -88,7 +90,7 @@ func TestControllerKeyRange(t *testing.T) { } func TestControllerTables(t *testing.T) { - wantTablet := addTablet(100, "0", topodatapb.TabletType_REPLICA, true, true) + wantTablet := addTablet(100) defer deleteTablet(wantTablet) resetBinlogClient() @@ -179,7 +181,7 @@ func TestControllerStopped(t *testing.T) { func TestControllerOverrides(t *testing.T) { resetBinlogClient() - wantTablet := addTablet(100, "0", topodatapb.TabletType_REPLICA, true, true) + wantTablet := addTablet(100) defer deleteTablet(wantTablet) params := map[string]string{ @@ -215,7 +217,7 @@ func TestControllerOverrides(t *testing.T) { } func TestControllerCanceledContext(t *testing.T) { - defer deleteTablet(addTablet(100, "0", topodatapb.TabletType_REPLICA, true, true)) + defer deleteTablet(addTablet(100)) params := map[string]string{ "id": "1", @@ -244,7 +246,7 @@ func TestControllerRetry(t *testing.T) { *retryDelay = 10 * time.Millisecond resetBinlogClient() - defer deleteTablet(addTablet(100, "0", topodatapb.TabletType_REPLICA, true, true)) + defer deleteTablet(addTablet(100)) params := map[string]string{ "id": "1", @@ -278,7 +280,7 @@ func TestControllerRetry(t *testing.T) { func TestControllerStopPosition(t *testing.T) { resetBinlogClient() - wantTablet := addTablet(100, "0", topodatapb.TabletType_REPLICA, true, true) + wantTablet := addTablet(100) defer deleteTablet(wantTablet) params := map[string]string{ diff --git a/go/vt/vttablet/tabletmanager/vreplication/engine.go b/go/vt/vttablet/tabletmanager/vreplication/engine.go index 9a08a974696..3cea952a16e 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/engine.go +++ b/go/vt/vttablet/tabletmanager/vreplication/engine.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Vitess Authors. +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. @@ -29,13 +29,14 @@ import ( "vitess.io/vitess/go/vt/binlog/binlogplayer" "vitess.io/vitess/go/vt/log" "vitess.io/vitess/go/vt/mysqlctl" + querypb "vitess.io/vitess/go/vt/proto/query" "vitess.io/vitess/go/vt/topo" ) const ( reshardingJournalTableName = "_vt.resharding_journal" vreplicationTableName = "_vt.vreplication" - copySateTableName = "_vt.copy_state" + copyStateTableName = "_vt.copy_state" createReshardingJournalTable = `create table if not exists _vt.resharding_journal( id bigint, @@ -269,54 +270,92 @@ func (vre *Engine) Exec(query string) (*sqltypes.Result, error) { if qr.InsertID == 0 { return nil, fmt.Errorf("insert failed to generate an id") } - params, err := readRow(dbClient, int(qr.InsertID)) - if err != nil { - return nil, err - } - // Create a controller for the newly created row. - ct, err := newController(vre.ctx, params, vre.dbClientFactory, vre.mysqld, vre.ts, vre.cell, *tabletTypesStr, nil) - if err != nil { - return nil, err + for id := int(qr.InsertID); id < int(qr.InsertID)+plan.numInserts; id++ { + if ct := vre.controllers[id]; ct != nil { + // Unreachable. Just a failsafe. + ct.Stop() + delete(vre.controllers, id) + } + params, err := readRow(dbClient, id) + if err != nil { + return nil, err + } + ct, err := newController(vre.ctx, params, vre.dbClientFactory, vre.mysqld, vre.ts, vre.cell, *tabletTypesStr, nil) + if err != nil { + return nil, err + } + vre.controllers[id] = ct } - vre.controllers[int(qr.InsertID)] = ct return qr, nil case updateQuery: - var blpStats *binlogplayer.Stats - if ct := vre.controllers[plan.id]; ct != nil { - // Stop the current controller. - ct.Stop() - blpStats = ct.blpStats - } - qr, err := vre.executeFetchMaybeCreateTable(dbClient, plan.query, 1) + ids, bv, err := vre.fetchIDs(dbClient, plan.selector) if err != nil { return nil, err } - params, err := readRow(dbClient, plan.id) + if len(ids) == 0 { + return &sqltypes.Result{}, nil + } + blpStats := make(map[int]*binlogplayer.Stats) + for _, id := range ids { + if ct := vre.controllers[id]; ct != nil { + // Stop the current controller. + ct.Stop() + blpStats[id] = ct.blpStats + } + } + query, err := plan.applier.GenerateQuery(bv, nil) if err != nil { return nil, err } - // Create a new controller in place of the old one. - // For continuity, the new controller inherits the previous stats. - ct, err := newController(vre.ctx, params, vre.dbClientFactory, vre.mysqld, vre.ts, vre.cell, *tabletTypesStr, blpStats) + qr, err := vre.executeFetchMaybeCreateTable(dbClient, query, 1) if err != nil { return nil, err } - vre.controllers[plan.id] = ct + for _, id := range ids { + params, err := readRow(dbClient, id) + if err != nil { + return nil, err + } + // Create a new controller in place of the old one. + // For continuity, the new controller inherits the previous stats. + ct, err := newController(vre.ctx, params, vre.dbClientFactory, vre.mysqld, vre.ts, vre.cell, *tabletTypesStr, blpStats[id]) + if err != nil { + return nil, err + } + vre.controllers[id] = ct + } return qr, nil case deleteQuery: - // Stop and delete the current controller. - if ct := vre.controllers[plan.id]; ct != nil { - ct.Stop() - delete(vre.controllers, plan.id) + ids, bv, err := vre.fetchIDs(dbClient, plan.selector) + if err != nil { + return nil, err + } + if len(ids) == 0 { + return &sqltypes.Result{}, nil + } + // Stop and delete the current controllers. + for _, id := range ids { + if ct := vre.controllers[id]; ct != nil { + ct.Stop() + delete(vre.controllers, id) + } } if err := dbClient.Begin(); err != nil { return nil, err } - qr, err := dbClient.ExecuteFetch(plan.query, 10000) + query, err := plan.applier.GenerateQuery(bv, nil) + if err != nil { + return nil, err + } + qr, err := vre.executeFetchMaybeCreateTable(dbClient, query, 1) + if err != nil { + return nil, err + } + delQuery, err := plan.delCopyState.GenerateQuery(bv, nil) if err != nil { return nil, err } - if _, err := dbClient.ExecuteFetch(plan.delCopyState, 10000); err != nil { + if _, err := dbClient.ExecuteFetch(delQuery, 10000); err != nil { // Legacy vreplication won't create this table. So, ignore table not found error. merr, isSQLErr := err.(*mysql.SQLError) if !isSQLErr || !(merr.Num == mysql.ERNoSuchTable) { @@ -334,8 +373,30 @@ func (vre *Engine) Exec(query string) (*sqltypes.Result, error) { panic("unreachable") } +func (vre *Engine) fetchIDs(dbClient binlogplayer.DBClient, selector string) (ids []int, bv map[string]*querypb.BindVariable, err error) { + qr, err := dbClient.ExecuteFetch(selector, 10000) + if err != nil { + return nil, nil, err + } + for _, row := range qr.Rows { + id, err := sqltypes.ToInt64(row[0]) + if err != nil { + return nil, nil, err + } + ids = append(ids, int(id)) + } + bvval, err := sqltypes.BuildBindVariable(ids) + if err != nil { + // Unreachable. + return nil, nil, err + } + bv = map[string]*querypb.BindVariable{"ids": bvval} + return ids, bv, nil +} + // WaitForPos waits for the replication to reach the specified position. func (vre *Engine) WaitForPos(ctx context.Context, id int, pos string) error { + start := time.Now() mPos, err := mysql.DecodePosition(pos) if err != nil { return err @@ -380,6 +441,7 @@ func (vre *Engine) WaitForPos(ctx context.Context, id int, pos string) error { } if current.AtLeast(mPos) { + log.Infof("position: %s reached, wait time: %v", pos, time.Since(start)) return nil } @@ -389,7 +451,8 @@ func (vre *Engine) WaitForPos(ctx context.Context, id int, pos string) error { select { case <-ctx.Done(): - return ctx.Err() + log.Errorf("Error waiting for pos: %s, last pos: %s: %v, wait time: %v", pos, qr.Rows[0][0].ToString(), ctx.Err(), time.Since(start)) + return fmt.Errorf("error waiting for pos: %s, last pos: %s: %v, wait time: %v", pos, qr.Rows[0][0].ToString(), ctx.Err(), time.Since(start)) case <-vre.ctx.Done(): return fmt.Errorf("vreplication is closing: %v", vre.ctx.Err()) case <-tkr.C: diff --git a/go/vt/vttablet/tabletmanager/vreplication/engine_test.go b/go/vt/vttablet/tabletmanager/vreplication/engine_test.go index 27f2d31d676..6377be170a1 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/engine_test.go +++ b/go/vt/vttablet/tabletmanager/vreplication/engine_test.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Vitess Authors. +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. @@ -19,6 +19,7 @@ package vreplication import ( "fmt" "reflect" + "strings" "testing" "time" @@ -27,13 +28,12 @@ import ( "vitess.io/vitess/go/sqltypes" "vitess.io/vitess/go/vt/binlog/binlogplayer" "vitess.io/vitess/go/vt/mysqlctl/fakemysqldaemon" - topodatapb "vitess.io/vitess/go/vt/proto/topodata" ) func TestEngineOpen(t *testing.T) { defer func() { globalStats = &vrStats{} }() - defer deleteTablet(addTablet(100, "0", topodatapb.TabletType_REPLICA, true, true)) + defer deleteTablet(addTablet(100)) resetBinlogClient() dbClient := binlogplayer.NewMockDBClient(t) dbClientFactory := func() binlogplayer.DBClient { return dbClient } @@ -81,7 +81,7 @@ func TestEngineOpen(t *testing.T) { func TestEngineExec(t *testing.T) { defer func() { globalStats = &vrStats{} }() - defer deleteTablet(addTablet(100, "0", topodatapb.TabletType_REPLICA, true, true)) + defer deleteTablet(addTablet(100)) resetBinlogClient() dbClient := binlogplayer.NewMockDBClient(t) dbClientFactory := func() binlogplayer.DBClient { return dbClient } @@ -98,7 +98,7 @@ func TestEngineExec(t *testing.T) { defer vre.Close() dbClient.ExpectRequest("use _vt", &sqltypes.Result{}, nil) - dbClient.ExpectRequest("insert into _vt.vreplication values (null)", &sqltypes.Result{InsertID: 1}, nil) + dbClient.ExpectRequest("insert into _vt.vreplication values(null)", &sqltypes.Result{InsertID: 1}, nil) dbClient.ExpectRequest("select * from _vt.vreplication where id = 1", sqltypes.MakeTestResult( sqltypes.MakeTestFields( "id|state|source", @@ -138,7 +138,8 @@ func TestEngineExec(t *testing.T) { savedBlp := ct.blpStats dbClient.ExpectRequest("use _vt", &sqltypes.Result{}, nil) - dbClient.ExpectRequest("update _vt.vreplication set pos = 'MariaDB/0-1-1084', state = 'Running' where id = 1", testDMLResponse, nil) + dbClient.ExpectRequest("select id from _vt.vreplication where id = 1", testSelectorResponse1, nil) + dbClient.ExpectRequest("update _vt.vreplication set pos = 'MariaDB/0-1-1084', state = 'Running' where id in (1)", testDMLResponse, nil) dbClient.ExpectRequest("select * from _vt.vreplication where id = 1", sqltypes.MakeTestResult( sqltypes.MakeTestFields( "id|state|source", @@ -175,16 +176,25 @@ func TestEngineExec(t *testing.T) { t.Errorf("stats are mismatched: %v, want %v", globalStats.controllers, vre.controllers) } + // Test no update + dbClient.ExpectRequest("use _vt", &sqltypes.Result{}, nil) + dbClient.ExpectRequest("select id from _vt.vreplication where id = 2", &sqltypes.Result{}, nil) + _, err = vre.Exec("update _vt.vreplication set pos = 'MariaDB/0-1-1084', state = 'Running' where id = 2") + if err != nil { + t.Fatal(err) + } + dbClient.Wait() + // Test Delete dbClient.ExpectRequest("use _vt", &sqltypes.Result{}, nil) - delQuery := "delete from _vt.vreplication where id = 1" + dbClient.ExpectRequest("select id from _vt.vreplication where id = 1", testSelectorResponse1, nil) dbClient.ExpectRequest("begin", nil, nil) - dbClient.ExpectRequest(delQuery, testDMLResponse, nil) - dbClient.ExpectRequest("delete from _vt.copy_state where vrepl_id = 1", nil, nil) + dbClient.ExpectRequest("delete from _vt.vreplication where id in (1)", testDMLResponse, nil) + dbClient.ExpectRequest("delete from _vt.copy_state where vrepl_id in (1)", nil, nil) dbClient.ExpectRequest("commit", nil, nil) - qr, err = vre.Exec(delQuery) + qr, err = vre.Exec("delete from _vt.vreplication where id = 1") if err != nil { t.Fatal(err) } @@ -203,12 +213,36 @@ func TestEngineExec(t *testing.T) { if !reflect.DeepEqual(globalStats.controllers, vre.controllers) { t.Errorf("stats are mismatched: %v, want %v", globalStats.controllers, vre.controllers) } + + // Test Delete of multiple rows + + dbClient.ExpectRequest("use _vt", &sqltypes.Result{}, nil) + dbClient.ExpectRequest("select id from _vt.vreplication where id > 1", testSelectorResponse2, nil) + dbClient.ExpectRequest("begin", nil, nil) + dbClient.ExpectRequest("delete from _vt.vreplication where id in (1, 2)", testDMLResponse, nil) + dbClient.ExpectRequest("delete from _vt.copy_state where vrepl_id in (1, 2)", nil, nil) + dbClient.ExpectRequest("commit", nil, nil) + + _, err = vre.Exec("delete from _vt.vreplication where id > 1") + if err != nil { + t.Fatal(err) + } + dbClient.Wait() + + // Test no delete + dbClient.ExpectRequest("use _vt", &sqltypes.Result{}, nil) + dbClient.ExpectRequest("select id from _vt.vreplication where id = 3", &sqltypes.Result{}, nil) + _, err = vre.Exec("delete from _vt.vreplication where id = 3") + if err != nil { + t.Fatal(err) + } + dbClient.Wait() } func TestEngineBadInsert(t *testing.T) { defer func() { globalStats = &vrStats{} }() - defer deleteTablet(addTablet(100, "0", topodatapb.TabletType_REPLICA, true, true)) + defer deleteTablet(addTablet(100)) resetBinlogClient() dbClient := binlogplayer.NewMockDBClient(t) @@ -224,7 +258,7 @@ func TestEngineBadInsert(t *testing.T) { defer vre.Close() dbClient.ExpectRequest("use _vt", &sqltypes.Result{}, nil) - dbClient.ExpectRequest("insert into _vt.vreplication values (null)", &sqltypes.Result{}, nil) + dbClient.ExpectRequest("insert into _vt.vreplication values(null)", &sqltypes.Result{}, nil) _, err := vre.Exec("insert into _vt.vreplication values(null)") want := "insert failed to generate an id" if err == nil || err.Error() != want { @@ -238,7 +272,7 @@ func TestEngineBadInsert(t *testing.T) { } func TestEngineSelect(t *testing.T) { - defer deleteTablet(addTablet(100, "0", topodatapb.TabletType_REPLICA, true, true)) + defer deleteTablet(addTablet(100)) resetBinlogClient() dbClient := binlogplayer.NewMockDBClient(t) @@ -367,8 +401,9 @@ func TestWaitForPosCancel(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) cancel() err := vre.WaitForPos(ctx, 1, "MariaDB/0-1-1084") - if err == nil || err != context.Canceled { - t.Errorf("WaitForPos: %v, want %v", err, context.Canceled) + want := "error waiting for pos: MariaDB/0-1-1084, last pos: MariaDB/0-1-1083: context canceled" + if err == nil || !strings.Contains(err.Error(), want) { + t.Errorf("WaitForPos: %v, must contain %v", err, want) } dbClient.Wait() @@ -382,7 +417,7 @@ func TestWaitForPosCancel(t *testing.T) { sqltypes.NewVarBinary(""), }}}, nil) err = vre.WaitForPos(context.Background(), 1, "MariaDB/0-1-1084") - want := "vreplication is closing: context canceled" + want = "vreplication is closing: context canceled" if err == nil || err.Error() != want { t.Errorf("WaitForPos: %v, want %v", err, want) } @@ -391,7 +426,7 @@ func TestWaitForPosCancel(t *testing.T) { func TestCreateDBAndTable(t *testing.T) { defer func() { globalStats = &vrStats{} }() - defer deleteTablet(addTablet(100, "0", topodatapb.TabletType_REPLICA, true, true)) + defer deleteTablet(addTablet(100)) resetBinlogClient() dbClient := binlogplayer.NewMockDBClient(t) dbClientFactory := func() binlogplayer.DBClient { return dbClient } @@ -424,14 +459,14 @@ func TestCreateDBAndTable(t *testing.T) { // Missing table. Statement should get retried after creating everything. dbClient.ExpectRequest("use _vt", &sqltypes.Result{}, nil) - dbClient.ExpectRequest("insert into _vt.vreplication values (null)", &sqltypes.Result{}, &tableNotFound) + dbClient.ExpectRequest("insert into _vt.vreplication values(null)", &sqltypes.Result{}, &tableNotFound) dbClient.ExpectRequest("CREATE DATABASE IF NOT EXISTS _vt", &sqltypes.Result{}, nil) dbClient.ExpectRequest("DROP TABLE IF EXISTS _vt.blp_checkpoint", &sqltypes.Result{}, nil) dbClient.ExpectRequestRE("CREATE TABLE IF NOT EXISTS _vt.vreplication.*", &sqltypes.Result{}, nil) dbClient.ExpectRequestRE("create table if not exists _vt.resharding_journal.*", &sqltypes.Result{}, nil) - dbClient.ExpectRequest("insert into _vt.vreplication values (null)", &sqltypes.Result{InsertID: 1}, nil) + dbClient.ExpectRequest("insert into _vt.vreplication values(null)", &sqltypes.Result{InsertID: 1}, nil) // The rest of this test is normal with no db errors or extra queries. diff --git a/go/vt/vttablet/tabletmanager/vreplication/framework_test.go b/go/vt/vttablet/tabletmanager/vreplication/framework_test.go index 825e6e3ea63..36b3e55c693 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/framework_test.go +++ b/go/vt/vttablet/tabletmanager/vreplication/framework_test.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Vitess Authors. +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. @@ -125,50 +125,30 @@ func resetBinlogClient() { //-------------------------------------- // Topos and tablets -func addTablet(id int, shard string, tabletType topodatapb.TabletType, serving, healthy bool) *topodatapb.Tablet { - t := newTablet(id, shard, tabletType, serving, healthy) - if err := env.TopoServ.CreateTablet(context.Background(), t); err != nil { - panic(err) - } - return t -} - -func deleteTablet(t *topodatapb.Tablet) { - env.TopoServ.DeleteTablet(context.Background(), t.Alias) - // This is not automatically removed from shard replication, which results in log spam. - topo.DeleteTabletReplicationData(context.Background(), env.TopoServ, t) -} - -func newTablet(id int, shard string, tabletType topodatapb.TabletType, serving, healthy bool) *topodatapb.Tablet { - stag := "not_serving" - if serving { - stag = "serving" - } - htag := "not_healthy" - if healthy { - htag = "healthy" - } - _, kr, err := topo.ValidateShardName(shard) - if err != nil { - panic(err) - } - return &topodatapb.Tablet{ +func addTablet(id int) *topodatapb.Tablet { + tablet := &topodatapb.Tablet{ Alias: &topodatapb.TabletAlias{ Cell: env.Cells[0], Uid: uint32(id), }, Keyspace: env.KeyspaceName, Shard: env.ShardName, - KeyRange: kr, - Type: tabletType, - Tags: map[string]string{ - "serving": stag, - "healthy": htag, - }, + KeyRange: &topodatapb.KeyRange{}, + Type: topodatapb.TabletType_REPLICA, PortMap: map[string]int32{ "test": int32(id), }, } + if err := env.TopoServ.CreateTablet(context.Background(), tablet); err != nil { + panic(err) + } + return tablet +} + +func deleteTablet(tablet *topodatapb.Tablet) { + env.TopoServ.DeleteTablet(context.Background(), tablet.Alias) + // This is not automatically removed from shard replication, which results in log spam. + topo.DeleteTabletReplicationData(context.Background(), env.TopoServ, tablet) } // fakeTabletConn implement TabletConn interface. We only care about the @@ -181,24 +161,15 @@ type fakeTabletConn struct { // StreamHealth is part of queryservice.QueryService. func (ftc *fakeTabletConn) StreamHealth(ctx context.Context, callback func(*querypb.StreamHealthResponse) error) error { - serving := true - if s, ok := ftc.tablet.Tags["serving"]; ok { - serving = (s == "serving") - } - var herr string - if s, ok := ftc.tablet.Tags["healthy"]; ok && s != "healthy" { - herr = "err" - } - callback(&querypb.StreamHealthResponse{ - Serving: serving, + return callback(&querypb.StreamHealthResponse{ + Serving: true, Target: &querypb.Target{ Keyspace: ftc.tablet.Keyspace, Shard: ftc.tablet.Shard, TabletType: ftc.tablet.Type, }, - RealtimeStats: &querypb.RealtimeStats{HealthError: herr}, + RealtimeStats: &querypb.RealtimeStats{}, }) - return nil } // VStream directly calls into the pre-initialized engine. @@ -274,9 +245,9 @@ type btStream struct { sent bool } -func (t *btStream) Recv() (*binlogdatapb.BinlogTransaction, error) { - if !t.sent { - t.sent = true +func (bts *btStream) Recv() (*binlogdatapb.BinlogTransaction, error) { + if !bts.sent { + bts.sent = true return &binlogdatapb.BinlogTransaction{ Statements: []*binlogdatapb.BinlogTransaction_Statement{ { @@ -290,8 +261,8 @@ func (t *btStream) Recv() (*binlogdatapb.BinlogTransaction, error) { }, }, nil } - <-t.ctx.Done() - return nil, t.ctx.Err() + <-bts.ctx.Done() + return nil, bts.ctx.Err() } func expectFBCRequest(t *testing.T, tablet *topodatapb.Tablet, pos string, tables []string, kr *topodatapb.KeyRange) { diff --git a/go/vt/vttablet/tabletmanager/vreplication/replicator_plan_test.go b/go/vt/vttablet/tabletmanager/vreplication/replicator_plan_test.go index 4474b305129..215f769155b 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/replicator_plan_test.go +++ b/go/vt/vttablet/tabletmanager/vreplication/replicator_plan_test.go @@ -18,8 +18,10 @@ package vreplication import ( "encoding/json" + "strings" "testing" + "github.com/stretchr/testify/assert" "vitess.io/vitess/go/sqltypes" binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" ) @@ -85,6 +87,44 @@ func TestBuildPlayerPlan(t *testing.T) { }, }, }, + }, { + // Regular with keyrange + input: &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{{ + Match: "/.*", + Filter: "-80", + }}, + }, + plan: &TestReplicatorPlan{ + VStreamFilter: &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{{ + Match: "t1", + Filter: "select * from t1 where in_keyrange('-80')", + }}, + }, + TargetTables: []string{"t1"}, + TablePlans: map[string]*TestTablePlan{ + "t1": { + TargetName: "t1", + SendRule: "t1", + }, + }, + }, + planpk: &TestReplicatorPlan{ + VStreamFilter: &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{{ + Match: "t1", + Filter: "select * from t1 where in_keyrange('-80')", + }}, + }, + TargetTables: []string{"t1"}, + TablePlans: map[string]*TestTablePlan{ + "t1": { + TargetName: "t1", + SendRule: "t1", + }, + }, + }, }, { // '*' expression input: &binlogdatapb.Filter{ @@ -616,3 +656,62 @@ func TestBuildPlayerPlan(t *testing.T) { } } } + +func TestBuildPlayerPlanNoDup(t *testing.T) { + tableKeys := map[string][]string{ + "t1": {"c1"}, + "t2": {"c2"}, + } + input := &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{{ + Match: "t1", + Filter: "select * from t", + }, { + Match: "t2", + Filter: "select * from t", + }}, + } + _, err := buildReplicatorPlan(input, tableKeys, nil) + want := "more than one target for source table t" + if err == nil || !strings.Contains(err.Error(), want) { + t.Errorf("buildReplicatorPlan err: %v, must contain: %v", err, want) + } +} + +func TestBuildPlayerPlanExclude(t *testing.T) { + tableKeys := map[string][]string{ + "t1": {"c1"}, + "t2": {"c2"}, + } + input := &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{{ + Match: "t2", + Filter: "exclude", + }, { + Match: "/.*", + Filter: "", + }}, + } + plan, err := buildReplicatorPlan(input, tableKeys, nil) + assert.NoError(t, err) + + want := &TestReplicatorPlan{ + VStreamFilter: &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{{ + Match: "t1", + Filter: "select * from t1", + }}, + }, + TargetTables: []string{"t1"}, + TablePlans: map[string]*TestTablePlan{ + "t1": { + TargetName: "t1", + SendRule: "t1", + }, + }, + } + + gotPlan, _ := json.Marshal(plan) + wantPlan, _ := json.Marshal(want) + assert.Equal(t, string(gotPlan), string(wantPlan)) +} diff --git a/go/vt/vttablet/tabletmanager/vreplication/stats.go b/go/vt/vttablet/tabletmanager/vreplication/stats.go index b80e6de4ad5..e6a2039bb2f 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/stats.go +++ b/go/vt/vttablet/tabletmanager/vreplication/stats.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Vitess Authors. +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. diff --git a/go/vt/vttablet/tabletmanager/vreplication/stats_test.go b/go/vt/vttablet/tabletmanager/vreplication/stats_test.go index a047ede7955..b46e1c4c4d5 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/stats_test.go +++ b/go/vt/vttablet/tabletmanager/vreplication/stats_test.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Vitess Authors. +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. diff --git a/go/vt/vttablet/tabletmanager/vreplication/table_plan_builder.go b/go/vt/vttablet/tabletmanager/vreplication/table_plan_builder.go index 3c8d3bc27a4..eed3576ff80 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/table_plan_builder.go +++ b/go/vt/vttablet/tabletmanager/vreplication/table_plan_builder.go @@ -23,10 +23,14 @@ import ( "strings" "vitess.io/vitess/go/sqltypes" + "vitess.io/vitess/go/vt/key" binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" "vitess.io/vitess/go/vt/sqlparser" ) +// ExcludeStr is the filter value for excluding tables that match a rule. +const ExcludeStr = "exclude" + type tablePlanBuilder struct { name sqlparser.TableIdent sendSelect *sqlparser.Select @@ -83,75 +87,76 @@ const ( // buildExecutionPlan is the function that builds the full plan. func buildReplicatorPlan(filter *binlogdatapb.Filter, tableKeys map[string][]string, copyState map[string]*sqltypes.Result) (*ReplicatorPlan, error) { plan := &ReplicatorPlan{ - VStreamFilter: &binlogdatapb.Filter{}, + VStreamFilter: &binlogdatapb.Filter{FieldEventMode: filter.FieldEventMode}, TargetTables: make(map[string]*TablePlan), TablePlans: make(map[string]*TablePlan), tableKeys: tableKeys, } -nextTable: for tableName := range tableKeys { lastpk, ok := copyState[tableName] if ok && lastpk == nil { // Don't replicate uncopied tables. continue } - for _, rule := range filter.Rules { - switch { - case strings.HasPrefix(rule.Match, "/"): - expr := strings.Trim(rule.Match, "/") - result, err := regexp.MatchString(expr, tableName) - if err != nil { - return nil, err - } - if !result { - continue - } - sendRule := &binlogdatapb.Rule{ - Match: tableName, - Filter: buildQuery(tableName, rule.Filter), - } - plan.VStreamFilter.Rules = append(plan.VStreamFilter.Rules, sendRule) - tablePlan := &TablePlan{ - TargetName: tableName, - SendRule: sendRule, - Lastpk: lastpk, - } - plan.TargetTables[tableName] = tablePlan - plan.TablePlans[tableName] = tablePlan - continue nextTable - case rule.Match == tableName: - tablePlan, err := buildTablePlan(rule, tableKeys, lastpk) - if err != nil { - return nil, err - } - if _, ok := plan.TablePlans[tablePlan.SendRule.Match]; ok { - continue - } - plan.VStreamFilter.Rules = append(plan.VStreamFilter.Rules, tablePlan.SendRule) - plan.TargetTables[tableName] = tablePlan - plan.TablePlans[tablePlan.SendRule.Match] = tablePlan - continue nextTable - } + rule, err := MatchTable(tableName, filter) + if err != nil { + return nil, err + } + if rule == nil { + continue + } + tablePlan, err := buildTablePlan(tableName, rule.Filter, tableKeys, lastpk) + if err != nil { + return nil, err + } + if tablePlan == nil { + // Table was excluded. + continue + } + if dup, ok := plan.TablePlans[tablePlan.SendRule.Match]; ok { + return nil, fmt.Errorf("more than one target for source table %s: %s and %s", tablePlan.SendRule.Match, dup.TargetName, tableName) } + plan.VStreamFilter.Rules = append(plan.VStreamFilter.Rules, tablePlan.SendRule) + plan.TargetTables[tableName] = tablePlan + plan.TablePlans[tablePlan.SendRule.Match] = tablePlan } return plan, nil } -func buildQuery(tableName, filter string) string { - buf := sqlparser.NewTrackedBuffer(nil) - buf.Myprintf("select * from %v", sqlparser.NewTableIdent(tableName)) - if filter != "" { - buf.Myprintf(" where in_keyrange(%v)", sqlparser.NewStrVal([]byte(filter))) +// MatchTable is similar to tableMatches defined in vstreamer. +func MatchTable(tableName string, filter *binlogdatapb.Filter) (*binlogdatapb.Rule, error) { + for _, rule := range filter.Rules { + switch { + case strings.HasPrefix(rule.Match, "/"): + expr := strings.Trim(rule.Match, "/") + result, err := regexp.MatchString(expr, tableName) + if err != nil { + return nil, err + } + if !result { + continue + } + return rule, nil + case tableName == rule.Match: + return rule, nil + } } - return buf.String() + return nil, nil } -func buildTablePlan(rule *binlogdatapb.Rule, tableKeys map[string][]string, lastpk *sqltypes.Result) (*TablePlan, error) { - query := rule.Filter - if query == "" { +func buildTablePlan(tableName, filter string, tableKeys map[string][]string, lastpk *sqltypes.Result) (*TablePlan, error) { + query := filter + switch { + case filter == "": + buf := sqlparser.NewTrackedBuffer(nil) + buf.Myprintf("select * from %v", sqlparser.NewTableIdent(tableName)) + query = buf.String() + case key.IsKeyRange(filter): buf := sqlparser.NewTrackedBuffer(nil) - buf.Myprintf("select * from %v", sqlparser.NewTableIdent(rule.Match)) + buf.Myprintf("select * from %v where in_keyrange(%v)", sqlparser.NewTableIdent(tableName), sqlparser.NewStrVal([]byte(filter))) query = buf.String() + case filter == ExcludeStr: + return nil, nil } sel, fromTable, err := analyzeSelectFrom(query) if err != nil { @@ -170,7 +175,7 @@ func buildTablePlan(rule *binlogdatapb.Rule, tableKeys map[string][]string, last } sendRule.Filter = query tablePlan := &TablePlan{ - TargetName: rule.Match, + TargetName: tableName, SendRule: sendRule, Lastpk: lastpk, } @@ -178,7 +183,7 @@ func buildTablePlan(rule *binlogdatapb.Rule, tableKeys map[string][]string, last } tpb := &tablePlanBuilder{ - name: sqlparser.NewTableIdent(rule.Match), + name: sqlparser.NewTableIdent(tableName), sendSelect: &sqlparser.Select{ From: sel.From, Where: sel.Where, diff --git a/go/vt/vttablet/tabletmanager/vreplication/tablet_picker_test.go b/go/vt/vttablet/tabletmanager/vreplication/tablet_picker_test.go deleted file mode 100644 index b01486c84a6..00000000000 --- a/go/vt/vttablet/tabletmanager/vreplication/tablet_picker_test.go +++ /dev/null @@ -1,122 +0,0 @@ -/* -Copyright 2018 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" - "testing" - - "github.com/golang/protobuf/proto" - "golang.org/x/net/context" - topodatapb "vitess.io/vitess/go/vt/proto/topodata" -) - -func TestPickSimple(t *testing.T) { - want := addTablet(100, "0", topodatapb.TabletType_REPLICA, true, true) - defer deleteTablet(want) - - tp, err := newTabletPicker(context.Background(), env.TopoServ, env.Cells[0], env.KeyspaceName, env.ShardName, "replica") - if err != nil { - t.Fatal(err) - } - defer tp.Close() - - tablet, err := tp.Pick(context.Background()) - if err != nil { - t.Fatal(err) - } - if !proto.Equal(want, tablet) { - t.Errorf("Pick: %v, want %v", tablet, want) - } -} - -func TestPickFromTwoHealthy(t *testing.T) { - want1 := addTablet(100, "0", topodatapb.TabletType_REPLICA, true, true) - defer deleteTablet(want1) - want2 := addTablet(101, "0", topodatapb.TabletType_RDONLY, true, true) - defer deleteTablet(want2) - - tp, err := newTabletPicker(context.Background(), env.TopoServ, env.Cells[0], env.KeyspaceName, env.ShardName, "replica,rdonly") - if err != nil { - t.Fatal(err) - } - defer tp.Close() - - tablet, err := tp.Pick(context.Background()) - if err != nil { - t.Fatal(err) - } - if !proto.Equal(tablet, want1) { - t.Errorf("Pick:\n%v, want\n%v", tablet, want1) - } - - tp, err = newTabletPicker(context.Background(), env.TopoServ, env.Cells[0], env.KeyspaceName, env.ShardName, "rdonly,replica") - if err != nil { - t.Fatal(err) - } - defer tp.Close() - - tablet, err = tp.Pick(context.Background()) - if err != nil { - t.Fatal(err) - } - if !proto.Equal(tablet, want2) { - t.Errorf("Pick:\n%v, want\n%v", tablet, want2) - } -} - -func TestPickFromSomeUnhealthy(t *testing.T) { - defer deleteTablet(addTablet(100, "0", topodatapb.TabletType_REPLICA, false, false)) - want := addTablet(101, "0", topodatapb.TabletType_RDONLY, false, true) - defer deleteTablet(want) - - tp, err := newTabletPicker(context.Background(), env.TopoServ, env.Cells[0], env.KeyspaceName, env.ShardName, "replica,rdonly") - if err != nil { - t.Fatal(err) - } - defer tp.Close() - - tablet, err := tp.Pick(context.Background()) - if err != nil { - t.Fatal(err) - } - if !proto.Equal(tablet, want) { - t.Errorf("Pick:\n%v, want\n%v", tablet, want) - } -} - -func TestPickError(t *testing.T) { - defer deleteTablet(addTablet(100, "0", topodatapb.TabletType_REPLICA, false, false)) - - _, err := newTabletPicker(context.Background(), env.TopoServ, env.Cells[0], env.KeyspaceName, env.ShardName, "badtype") - want := "failed to parse list of tablet types: badtype" - if err == nil || err.Error() != want { - t.Errorf("newTabletPicker err: %v, want %v", err, want) - } - - tp, err := newTabletPicker(context.Background(), env.TopoServ, env.Cells[0], env.KeyspaceName, env.ShardName, "replica,rdonly") - if err != nil { - t.Fatal(err) - } - defer tp.Close() - - _, err = tp.Pick(context.Background()) - want = fmt.Sprintf("can't find any healthy source tablet for %s 0 [REPLICA RDONLY]", env.KeyspaceName) - if err == nil || err.Error() != want { - t.Errorf("Pick err: %v, want %v", err, want) - } -} diff --git a/go/vt/vttablet/tabletmanager/vreplication/vcopier_test.go b/go/vt/vttablet/tabletmanager/vreplication/vcopier_test.go index a22adca9590..c0d2cf10326 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/vcopier_test.go +++ b/go/vt/vttablet/tabletmanager/vreplication/vcopier_test.go @@ -26,12 +26,11 @@ import ( "vitess.io/vitess/go/sqltypes" "vitess.io/vitess/go/vt/binlog/binlogplayer" binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" - topodatapb "vitess.io/vitess/go/vt/proto/topodata" "vitess.io/vitess/go/vt/vttablet/tabletserver/vstreamer" ) func TestPlayerCopyTables(t *testing.T) { - defer deleteTablet(addTablet(100, "0", topodatapb.TabletType_REPLICA, true, true)) + defer deleteTablet(addTablet(100)) execStatements(t, []string{ "create table src1(id int, val varbinary(128), primary key(id))", @@ -114,7 +113,7 @@ func TestPlayerCopyTables(t *testing.T) { // TestPlayerCopyBigTable ensures the copy-catchup back-and-forth loop works correctly. func TestPlayerCopyBigTable(t *testing.T) { - defer deleteTablet(addTablet(100, "0", topodatapb.TabletType_REPLICA, true, true)) + defer deleteTablet(addTablet(100)) savedPacketSize := *vstreamer.PacketSize // PacketSize of 1 byte will send at most one row at a time. @@ -245,7 +244,7 @@ func TestPlayerCopyBigTable(t *testing.T) { // TestPlayerCopyWildcardRule ensures the copy-catchup back-and-forth loop works correctly // when the filter uses a wildcard rule func TestPlayerCopyWildcardRule(t *testing.T) { - defer deleteTablet(addTablet(100, "0", topodatapb.TabletType_REPLICA, true, true)) + defer deleteTablet(addTablet(100)) savedPacketSize := *vstreamer.PacketSize // PacketSize of 1 byte will send at most one row at a time. @@ -375,7 +374,7 @@ func TestPlayerCopyWildcardRule(t *testing.T) { // TestPlayerCopyTableContinuation tests the copy workflow where tables have been partially copied. func TestPlayerCopyTableContinuation(t *testing.T) { - defer deleteTablet(addTablet(100, "0", topodatapb.TabletType_REPLICA, true, true)) + defer deleteTablet(addTablet(100)) execStatements(t, []string{ // src1 is initialized as partially copied. @@ -513,7 +512,7 @@ func TestPlayerCopyTableContinuation(t *testing.T) { "/delete from _vt.copy_state.*not_copied", "rollback", }) - // Explicitly eat the Running state query. You cant' make expectNontxQueries + // Explicitly eat the Running state query. You can't make expectNontxQueries // wait for it because it ignores _vt.vreplication events. expectDBClientQueries(t, []string{ "/update _vt.vreplication set state='Running'", @@ -539,7 +538,7 @@ func TestPlayerCopyTableContinuation(t *testing.T) { // TestPlayerCopyWildcardTableContinuation tests the copy workflow where tables have been partially copied. func TestPlayerCopyWildcardTableContinuation(t *testing.T) { - defer deleteTablet(addTablet(100, "0", topodatapb.TabletType_REPLICA, true, true)) + defer deleteTablet(addTablet(100)) execStatements(t, []string{ // src is initialized as partially copied. @@ -609,7 +608,7 @@ func TestPlayerCopyWildcardTableContinuation(t *testing.T) { "/delete from _vt.copy_state.*dst", "rollback", }) - // Explicitly eat the Running state query. You cant' make expectNontxQueries + // Explicitly eat the Running state query. You can't make expectNontxQueries // wait for it because it ignores _vt.vreplication events. expectDBClientQueries(t, []string{ "/update _vt.vreplication set state='Running'", @@ -622,7 +621,7 @@ func TestPlayerCopyWildcardTableContinuation(t *testing.T) { } func TestPlayerCopyTablesNone(t *testing.T) { - defer deleteTablet(addTablet(100, "0", topodatapb.TabletType_REPLICA, true, true)) + defer deleteTablet(addTablet(100)) filter := &binlogdatapb.Filter{ Rules: []*binlogdatapb.Rule{{ @@ -660,7 +659,7 @@ func TestPlayerCopyTablesNone(t *testing.T) { } func TestPlayerCopyTableCancel(t *testing.T) { - defer deleteTablet(addTablet(100, "0", topodatapb.TabletType_REPLICA, true, true)) + defer deleteTablet(addTablet(100)) execStatements(t, []string{ "create table src1(id int, val varbinary(128), primary key(id))", diff --git a/go/vt/vttablet/tabletmanager/vreplication/vplayer_test.go b/go/vt/vttablet/tabletmanager/vreplication/vplayer_test.go index e2c0e80c9b1..10f66487e05 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/vplayer_test.go +++ b/go/vt/vttablet/tabletmanager/vreplication/vplayer_test.go @@ -20,6 +20,7 @@ import ( "flag" "fmt" "strings" + "sync" "testing" "time" @@ -30,11 +31,10 @@ import ( "vitess.io/vitess/go/vt/binlog/binlogplayer" binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" - topodatapb "vitess.io/vitess/go/vt/proto/topodata" ) func TestPlayerFilters(t *testing.T) { - defer deleteTablet(addTablet(100, "0", topodatapb.TabletType_REPLICA, true, true)) + defer deleteTablet(addTablet(100)) execStatements(t, []string{ "create table src1(id int, val varbinary(128), primary key(id))", @@ -282,7 +282,7 @@ func TestPlayerFilters(t *testing.T) { } func TestPlayerKeywordNames(t *testing.T) { - defer deleteTablet(addTablet(100, "0", topodatapb.TabletType_REPLICA, true, true)) + defer deleteTablet(addTablet(100)) execStatements(t, []string{ "create table `begin`(`primary` int, `column` varbinary(128), primary key(`primary`))", @@ -448,7 +448,7 @@ func TestPlayerKeywordNames(t *testing.T) { } } func TestUnicode(t *testing.T) { - defer deleteTablet(addTablet(100, "0", topodatapb.TabletType_REPLICA, true, true)) + defer deleteTablet(addTablet(100)) execStatements(t, []string{ "create table src1(id int, val varchar(128) COLLATE utf8_unicode_ci, primary key(id))", @@ -515,7 +515,7 @@ func TestUnicode(t *testing.T) { } func TestPlayerUpdates(t *testing.T) { - defer deleteTablet(addTablet(100, "0", topodatapb.TabletType_REPLICA, true, true)) + defer deleteTablet(addTablet(100)) execStatements(t, []string{ "create table t1(id int, grouped int, ungrouped int, summed int, primary key(id))", @@ -624,7 +624,7 @@ func TestPlayerUpdates(t *testing.T) { } func TestPlayerRowMove(t *testing.T) { - defer deleteTablet(addTablet(100, "0", topodatapb.TabletType_REPLICA, true, true)) + defer deleteTablet(addTablet(100)) execStatements(t, []string{ "create table src(id int, val1 int, val2 int, primary key(id))", @@ -678,7 +678,7 @@ func TestPlayerRowMove(t *testing.T) { } func TestPlayerTypes(t *testing.T) { - defer deleteTablet(addTablet(100, "0", topodatapb.TabletType_REPLICA, true, true)) + defer deleteTablet(addTablet(100)) execStatements(t, []string{ "create table vitess_ints(tiny tinyint, tinyu tinyint unsigned, small smallint, smallu smallint unsigned, medium mediumint, mediumu mediumint unsigned, normal int, normalu int unsigned, big bigint, bigu bigint unsigned, y year, primary key(tiny))", @@ -792,7 +792,7 @@ func TestPlayerTypes(t *testing.T) { } func TestPlayerDDL(t *testing.T) { - defer deleteTablet(addTablet(100, "0", topodatapb.TabletType_REPLICA, true, true)) + defer deleteTablet(addTablet(100)) execStatements(t, []string{ "create table t1(id int, primary key(id))", fmt.Sprintf("create table %s.t1(id int, primary key(id))", vrepldb), @@ -894,7 +894,7 @@ func TestPlayerDDL(t *testing.T) { } func TestPlayerStopPos(t *testing.T) { - defer deleteTablet(addTablet(100, "0", topodatapb.TabletType_REPLICA, true, true)) + defer deleteTablet(addTablet(100)) execStatements(t, []string{ "create table yes(id int, val varbinary(128), primary key(id))", @@ -991,7 +991,7 @@ func TestPlayerStopPos(t *testing.T) { } func TestPlayerIdleUpdate(t *testing.T) { - defer deleteTablet(addTablet(100, "0", topodatapb.TabletType_REPLICA, true, true)) + defer deleteTablet(addTablet(100)) savedIdleTimeout := idleTimeout defer func() { idleTimeout = savedIdleTimeout }() @@ -1039,7 +1039,7 @@ func TestPlayerIdleUpdate(t *testing.T) { } func TestPlayerSplitTransaction(t *testing.T) { - defer deleteTablet(addTablet(100, "0", topodatapb.TabletType_REPLICA, true, true)) + defer deleteTablet(addTablet(100)) flag.Set("vstream_packet_size", "10") defer flag.Set("vstream_packet_size", "10000") @@ -1079,7 +1079,7 @@ func TestPlayerSplitTransaction(t *testing.T) { } func TestPlayerLockErrors(t *testing.T) { - defer deleteTablet(addTablet(100, "0", topodatapb.TabletType_REPLICA, true, true)) + defer deleteTablet(addTablet(100)) execStatements(t, []string{ "create table t1(id int, val varbinary(128), primary key(id))", @@ -1153,7 +1153,7 @@ func TestPlayerLockErrors(t *testing.T) { } func TestPlayerCancelOnLock(t *testing.T) { - defer deleteTablet(addTablet(100, "0", topodatapb.TabletType_REPLICA, true, true)) + defer deleteTablet(addTablet(100)) execStatements(t, []string{ "create table t1(id int, val varbinary(128), primary key(id))", @@ -1225,7 +1225,7 @@ func TestPlayerCancelOnLock(t *testing.T) { } func TestPlayerBatching(t *testing.T) { - defer deleteTablet(addTablet(100, "0", topodatapb.TabletType_REPLICA, true, true)) + defer deleteTablet(addTablet(100)) execStatements(t, []string{ "create table t1(id int, val varbinary(128), primary key(id))", @@ -1308,7 +1308,7 @@ func TestPlayerBatching(t *testing.T) { } func TestPlayerRelayLogMaxSize(t *testing.T) { - defer deleteTablet(addTablet(100, "0", topodatapb.TabletType_REPLICA, true, true)) + defer deleteTablet(addTablet(100)) for i := 0; i < 2; i++ { // First iteration checks max size, second checks max items @@ -1407,7 +1407,7 @@ func TestPlayerRelayLogMaxSize(t *testing.T) { } func TestRestartOnVStreamEnd(t *testing.T) { - defer deleteTablet(addTablet(100, "0", topodatapb.TabletType_REPLICA, true, true)) + defer deleteTablet(addTablet(100)) savedDelay := *retryDelay defer func() { *retryDelay = savedDelay }() @@ -1462,7 +1462,7 @@ func TestRestartOnVStreamEnd(t *testing.T) { } func TestTimestamp(t *testing.T) { - defer deleteTablet(addTablet(100, "0", topodatapb.TabletType_REPLICA, true, true)) + defer deleteTablet(addTablet(100)) execStatements(t, []string{ "create table t1(id int, ts timestamp, dt datetime)", @@ -1532,13 +1532,17 @@ func startVReplication(t *testing.T, filter *binlogdatapb.Filter, onddl binlogda "/insert into _vt.vreplication", "/update _vt.vreplication set state='Running'", }) + + var once sync.Once return func() { t.Helper() - query := fmt.Sprintf("delete from _vt.vreplication where id = %d", qr.InsertID) - if _, err := playerEngine.Exec(query); err != nil { - t.Fatal(err) - } - expectDeleteQueries(t) + once.Do(func() { + query := fmt.Sprintf("delete from _vt.vreplication where id = %d", qr.InsertID) + if _, err := playerEngine.Exec(query); err != nil { + t.Fatal(err) + } + expectDeleteQueries(t) + }) }, int(qr.InsertID) } diff --git a/go/vt/vttablet/tabletserver/bench_test.go b/go/vt/vttablet/tabletserver/bench_test.go index af9d9cc4aa6..328b685038a 100644 --- a/go/vt/vttablet/tabletserver/bench_test.go +++ b/go/vt/vttablet/tabletserver/bench_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vttablet/tabletserver/codex.go b/go/vt/vttablet/tabletserver/codex.go index 559140fffaf..de3b6bf7dfd 100644 --- a/go/vt/vttablet/tabletserver/codex.go +++ b/go/vt/vttablet/tabletserver/codex.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vttablet/tabletserver/codex_test.go b/go/vt/vttablet/tabletserver/codex_test.go index 1393ccbef57..f8ee20f5c3f 100644 --- a/go/vt/vttablet/tabletserver/codex_test.go +++ b/go/vt/vttablet/tabletserver/codex_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vttablet/tabletserver/connpool/dbconn.go b/go/vt/vttablet/tabletserver/connpool/dbconn.go index f505dff7d76..668dda6c6c2 100644 --- a/go/vt/vttablet/tabletserver/connpool/dbconn.go +++ b/go/vt/vttablet/tabletserver/connpool/dbconn.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vttablet/tabletserver/connpool/dbconn_test.go b/go/vt/vttablet/tabletserver/connpool/dbconn_test.go index aad986ee70d..df9b7528ccf 100644 --- a/go/vt/vttablet/tabletserver/connpool/dbconn_test.go +++ b/go/vt/vttablet/tabletserver/connpool/dbconn_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vttablet/tabletserver/connpool/pool.go b/go/vt/vttablet/tabletserver/connpool/pool.go index eee178b36f7..1c32929e91d 100644 --- a/go/vt/vttablet/tabletserver/connpool/pool.go +++ b/go/vt/vttablet/tabletserver/connpool/pool.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -98,6 +98,7 @@ func New( stats.NewCounterDurationFunc(name+"WaitTime", "Tablet server wait time", cp.WaitTime) stats.NewGaugeDurationFunc(name+"IdleTimeout", "Tablet server idle timeout", cp.IdleTimeout) stats.NewCounterFunc(name+"IdleClosed", "Tablet server conn pool idle closed", cp.IdleClosed) + stats.NewCounterFunc(name+"Exhausted", "Number of times pool had zero available slots", cp.Exhausted) return cp } @@ -296,6 +297,15 @@ func (cp *Pool) IdleClosed() int64 { return p.IdleClosed() } +// Exhausted returns the number of times available went to zero for the pool. +func (cp *Pool) Exhausted() int64 { + p := cp.pool() + if p == nil { + return 0 + } + return p.Exhausted() +} + func (cp *Pool) isCallerIDAppDebug(ctx context.Context) bool { if cp.appDebugParams == nil || cp.appDebugParams.Uname == "" { return false diff --git a/go/vt/vttablet/tabletserver/connpool/pool_test.go b/go/vt/vttablet/tabletserver/connpool/pool_test.go index 1647abe8ee6..4920450402c 100644 --- a/go/vt/vttablet/tabletserver/connpool/pool_test.go +++ b/go/vt/vttablet/tabletserver/connpool/pool_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vttablet/tabletserver/controller.go b/go/vt/vttablet/tabletserver/controller.go index 2d7a8c10fce..bb9095e49de 100644 --- a/go/vt/vttablet/tabletserver/controller.go +++ b/go/vt/vttablet/tabletserver/controller.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vttablet/tabletserver/messager/cache.go b/go/vt/vttablet/tabletserver/messager/cache.go index d69311fd2f6..7137e6bcb78 100644 --- a/go/vt/vttablet/tabletserver/messager/cache.go +++ b/go/vt/vttablet/tabletserver/messager/cache.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vttablet/tabletserver/messager/cache_test.go b/go/vt/vttablet/tabletserver/messager/cache_test.go index 5bc03806520..41277d80f23 100644 --- a/go/vt/vttablet/tabletserver/messager/cache_test.go +++ b/go/vt/vttablet/tabletserver/messager/cache_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vttablet/tabletserver/messager/engine.go b/go/vt/vttablet/tabletserver/messager/engine.go index f22d0243479..58c048835f3 100644 --- a/go/vt/vttablet/tabletserver/messager/engine.go +++ b/go/vt/vttablet/tabletserver/messager/engine.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vttablet/tabletserver/messager/engine_test.go b/go/vt/vttablet/tabletserver/messager/engine_test.go index 9ac4abed76b..698380651ad 100644 --- a/go/vt/vttablet/tabletserver/messager/engine_test.go +++ b/go/vt/vttablet/tabletserver/messager/engine_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vttablet/tabletserver/messager/message_manager.go b/go/vt/vttablet/tabletserver/messager/message_manager.go index 2b8b93e4d83..8585eaf0537 100644 --- a/go/vt/vttablet/tabletserver/messager/message_manager.go +++ b/go/vt/vttablet/tabletserver/messager/message_manager.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -297,7 +297,7 @@ func (mm *messageManager) Close() { // Subscribe registers the send function as a receiver of messages // and returns a 'done' channel that will be closed when the subscription -// ends. There are many reaons for a subscription to end: a grpc context +// ends. There are many reasons for a subscription to end: a grpc context // cancel or timeout, or tabletserver shutdown, etc. func (mm *messageManager) Subscribe(ctx context.Context, send func(*sqltypes.Result) error) <-chan struct{} { receiver, done := newMessageReceiver(ctx, send) diff --git a/go/vt/vttablet/tabletserver/messager/message_manager_test.go b/go/vt/vttablet/tabletserver/messager/message_manager_test.go index aa43af69e2f..d895d7d719d 100644 --- a/go/vt/vttablet/tabletserver/messager/message_manager_test.go +++ b/go/vt/vttablet/tabletserver/messager/message_manager_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vttablet/tabletserver/planbuilder/ddl.go b/go/vt/vttablet/tabletserver/planbuilder/ddl.go index c6c055f5595..68b0449db19 100644 --- a/go/vt/vttablet/tabletserver/planbuilder/ddl.go +++ b/go/vt/vttablet/tabletserver/planbuilder/ddl.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vttablet/tabletserver/planbuilder/dml.go b/go/vt/vttablet/tabletserver/planbuilder/dml.go index 3b5f35c155c..6b1aba64e14 100644 --- a/go/vt/vttablet/tabletserver/planbuilder/dml.go +++ b/go/vt/vttablet/tabletserver/planbuilder/dml.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vttablet/tabletserver/planbuilder/permission.go b/go/vt/vttablet/tabletserver/planbuilder/permission.go index b2adb0612ec..5fe98438d95 100644 --- a/go/vt/vttablet/tabletserver/planbuilder/permission.go +++ b/go/vt/vttablet/tabletserver/planbuilder/permission.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Vitess Authors. +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. diff --git a/go/vt/vttablet/tabletserver/planbuilder/permission_test.go b/go/vt/vttablet/tabletserver/planbuilder/permission_test.go index 1273600a959..222e9b718cb 100644 --- a/go/vt/vttablet/tabletserver/planbuilder/permission_test.go +++ b/go/vt/vttablet/tabletserver/planbuilder/permission_test.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Vitess Authors. +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. diff --git a/go/vt/vttablet/tabletserver/planbuilder/plan.go b/go/vt/vttablet/tabletserver/planbuilder/plan.go index b332c67dcf6..87e119f3c52 100644 --- a/go/vt/vttablet/tabletserver/planbuilder/plan.go +++ b/go/vt/vttablet/tabletserver/planbuilder/plan.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vttablet/tabletserver/planbuilder/plan_test.go b/go/vt/vttablet/tabletserver/planbuilder/plan_test.go index 9f8b95debc6..3d0ecaf1a3e 100644 --- a/go/vt/vttablet/tabletserver/planbuilder/plan_test.go +++ b/go/vt/vttablet/tabletserver/planbuilder/plan_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vttablet/tabletserver/planbuilder/query_gen.go b/go/vt/vttablet/tabletserver/planbuilder/query_gen.go index 7e6536e64a5..0418d2bb969 100644 --- a/go/vt/vttablet/tabletserver/planbuilder/query_gen.go +++ b/go/vt/vttablet/tabletserver/planbuilder/query_gen.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vttablet/tabletserver/query_engine.go b/go/vt/vttablet/tabletserver/query_engine.go index f2994f784a5..7f17ab87c73 100644 --- a/go/vt/vttablet/tabletserver/query_engine.go +++ b/go/vt/vttablet/tabletserver/query_engine.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vttablet/tabletserver/query_engine_test.go b/go/vt/vttablet/tabletserver/query_engine_test.go index 739d823982c..0e7ec722e62 100644 --- a/go/vt/vttablet/tabletserver/query_engine_test.go +++ b/go/vt/vttablet/tabletserver/query_engine_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vttablet/tabletserver/query_executor.go b/go/vt/vttablet/tabletserver/query_executor.go index f5e7558389a..4d161e9b246 100644 --- a/go/vt/vttablet/tabletserver/query_executor.go +++ b/go/vt/vttablet/tabletserver/query_executor.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vttablet/tabletserver/query_executor_test.go b/go/vt/vttablet/tabletserver/query_executor_test.go index ecfb187fc71..c6404f5fefb 100644 --- a/go/vt/vttablet/tabletserver/query_executor_test.go +++ b/go/vt/vttablet/tabletserver/query_executor_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vttablet/tabletserver/query_list.go b/go/vt/vttablet/tabletserver/query_list.go index 1f801fae5ff..7b0f722ab88 100644 --- a/go/vt/vttablet/tabletserver/query_list.go +++ b/go/vt/vttablet/tabletserver/query_list.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/vttablet/tabletserver/query_list_test.go b/go/vt/vttablet/tabletserver/query_list_test.go index 807bee88e0a..dcdfdbd9e4c 100644 --- a/go/vt/vttablet/tabletserver/query_list_test.go +++ b/go/vt/vttablet/tabletserver/query_list_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/vttablet/tabletserver/querylogz.go b/go/vt/vttablet/tabletserver/querylogz.go index 7eab0b7fe16..a3736c68a3e 100644 --- a/go/vt/vttablet/tabletserver/querylogz.go +++ b/go/vt/vttablet/tabletserver/querylogz.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vttablet/tabletserver/querylogz_test.go b/go/vt/vttablet/tabletserver/querylogz_test.go index d94f355eaa3..e829b23a144 100644 --- a/go/vt/vttablet/tabletserver/querylogz_test.go +++ b/go/vt/vttablet/tabletserver/querylogz_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vttablet/tabletserver/queryz.go b/go/vt/vttablet/tabletserver/queryz.go index 21b5c482e25..dea2b1dfd0a 100644 --- a/go/vt/vttablet/tabletserver/queryz.go +++ b/go/vt/vttablet/tabletserver/queryz.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vttablet/tabletserver/queryz_test.go b/go/vt/vttablet/tabletserver/queryz_test.go index 43cc7d384f3..f639ed7f061 100644 --- a/go/vt/vttablet/tabletserver/queryz_test.go +++ b/go/vt/vttablet/tabletserver/queryz_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vttablet/tabletserver/replication_watcher.go b/go/vt/vttablet/tabletserver/replication_watcher.go index da3bfd9dfaa..e97e37c7d43 100644 --- a/go/vt/vttablet/tabletserver/replication_watcher.go +++ b/go/vt/vttablet/tabletserver/replication_watcher.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vttablet/tabletserver/rules/map.go b/go/vt/vttablet/tabletserver/rules/map.go index 8159507c5fb..687669d4802 100644 --- a/go/vt/vttablet/tabletserver/rules/map.go +++ b/go/vt/vttablet/tabletserver/rules/map.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vttablet/tabletserver/rules/map_test.go b/go/vt/vttablet/tabletserver/rules/map_test.go index b47715612cc..ffb533cf5b8 100644 --- a/go/vt/vttablet/tabletserver/rules/map_test.go +++ b/go/vt/vttablet/tabletserver/rules/map_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -136,7 +136,7 @@ func TestMapGetSetQueryRules(t *testing.T) { t.Errorf("Failed to set custom Rules: %s", err) } - // Test if we can successfully retrive rules that've been set + // Test if we can successfully retrieve rules that've been set qrs, err = qri.Get(blacklistQueryRules) if err != nil { t.Errorf("GetRules failed to retrieve blacklistQueryRules that has been set: %s", err) diff --git a/go/vt/vttablet/tabletserver/rules/rules.go b/go/vt/vttablet/tabletserver/rules/rules.go index d934046bbe3..b641b2e55ce 100644 --- a/go/vt/vttablet/tabletserver/rules/rules.go +++ b/go/vt/vttablet/tabletserver/rules/rules.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vttablet/tabletserver/rules/rules_test.go b/go/vt/vttablet/tabletserver/rules/rules_test.go index 1a389f10e30..31eb8f2cf1c 100644 --- a/go/vt/vttablet/tabletserver/rules/rules_test.go +++ b/go/vt/vttablet/tabletserver/rules/rules_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vttablet/tabletserver/schema/engine.go b/go/vt/vttablet/tabletserver/schema/engine.go index 2afa16c8f53..202495e231c 100644 --- a/go/vt/vttablet/tabletserver/schema/engine.go +++ b/go/vt/vttablet/tabletserver/schema/engine.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -113,7 +113,7 @@ func (se *Engine) Open() error { return nil } start := time.Now() - defer log.Infof("Time taken to load the schema: %v", time.Since(start)) + defer func() { log.Infof("Time taken to load the schema: %v", time.Since(start)) }() ctx := tabletenv.LocalContext() dbaParams := se.dbconfigs.DbaWithDB() se.conns.Open(dbaParams, dbaParams, dbaParams) diff --git a/go/vt/vttablet/tabletserver/schema/engine_test.go b/go/vt/vttablet/tabletserver/schema/engine_test.go index dcf3c4d8fc8..259140a84f6 100644 --- a/go/vt/vttablet/tabletserver/schema/engine_test.go +++ b/go/vt/vttablet/tabletserver/schema/engine_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vttablet/tabletserver/schema/load_table.go b/go/vt/vttablet/tabletserver/schema/load_table.go index af57966d6ab..273b41a89db 100644 --- a/go/vt/vttablet/tabletserver/schema/load_table.go +++ b/go/vt/vttablet/tabletserver/schema/load_table.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vttablet/tabletserver/schema/load_table_test.go b/go/vt/vttablet/tabletserver/schema/load_table_test.go index 7d1a583defb..d29f1c3b148 100644 --- a/go/vt/vttablet/tabletserver/schema/load_table_test.go +++ b/go/vt/vttablet/tabletserver/schema/load_table_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vttablet/tabletserver/schema/schema.go b/go/vt/vttablet/tabletserver/schema/schema.go index 6748545af4c..b60fae0a466 100644 --- a/go/vt/vttablet/tabletserver/schema/schema.go +++ b/go/vt/vttablet/tabletserver/schema/schema.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -217,10 +217,7 @@ func (ta *Table) HasPrimary() bool { // IsTopic returns true if TopicInfo is not nil. func (ta *Table) IsTopic() bool { - if ta.TopicInfo == nil { - return false - } - return true + return ta.TopicInfo != nil } // UniqueIndexes returns the number of unique indexes on the table diff --git a/go/vt/vttablet/tabletserver/schema/schema_test.go b/go/vt/vttablet/tabletserver/schema/schema_test.go index b76102f18b4..acb950fe61b 100644 --- a/go/vt/vttablet/tabletserver/schema/schema_test.go +++ b/go/vt/vttablet/tabletserver/schema/schema_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/vttablet/tabletserver/schema/schematest/schematest.go b/go/vt/vttablet/tabletserver/schema/schematest/schematest.go index b30792f29ec..7ba71c07336 100644 --- a/go/vt/vttablet/tabletserver/schema/schematest/schematest.go +++ b/go/vt/vttablet/tabletserver/schema/schematest/schematest.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vttablet/tabletserver/schema/schemaz.go b/go/vt/vttablet/tabletserver/schema/schemaz.go index 5356fa16c64..2d3da8facb7 100644 --- a/go/vt/vttablet/tabletserver/schema/schemaz.go +++ b/go/vt/vttablet/tabletserver/schema/schemaz.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vttablet/tabletserver/schema/schemaz_test.go b/go/vt/vttablet/tabletserver/schema/schemaz_test.go index 880bd7d15c4..412b112c1fc 100644 --- a/go/vt/vttablet/tabletserver/schema/schemaz_test.go +++ b/go/vt/vttablet/tabletserver/schema/schemaz_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vttablet/tabletserver/splitquery/doc.go b/go/vt/vttablet/tabletserver/splitquery/doc.go index 292bc62dddd..25a0ac2f1cf 100644 --- a/go/vt/vttablet/tabletserver/splitquery/doc.go +++ b/go/vt/vttablet/tabletserver/splitquery/doc.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/vttablet/tabletserver/splitquery/equal_splits_algorithm.go b/go/vt/vttablet/tabletserver/splitquery/equal_splits_algorithm.go index eadf3f3c812..2e4e4fc22f1 100644 --- a/go/vt/vttablet/tabletserver/splitquery/equal_splits_algorithm.go +++ b/go/vt/vttablet/tabletserver/splitquery/equal_splits_algorithm.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/vttablet/tabletserver/splitquery/equal_splits_algorithm_test.go b/go/vt/vttablet/tabletserver/splitquery/equal_splits_algorithm_test.go index 522fbfb7fb1..94c6dca74f1 100644 --- a/go/vt/vttablet/tabletserver/splitquery/equal_splits_algorithm_test.go +++ b/go/vt/vttablet/tabletserver/splitquery/equal_splits_algorithm_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/vttablet/tabletserver/splitquery/example_test.go b/go/vt/vttablet/tabletserver/splitquery/example_test.go index 56b055f8ad3..64638d87cd2 100644 --- a/go/vt/vttablet/tabletserver/splitquery/example_test.go +++ b/go/vt/vttablet/tabletserver/splitquery/example_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/vttablet/tabletserver/splitquery/full_scan_algorithm.go b/go/vt/vttablet/tabletserver/splitquery/full_scan_algorithm.go index 7ed8dd1816b..d81762d4a21 100644 --- a/go/vt/vttablet/tabletserver/splitquery/full_scan_algorithm.go +++ b/go/vt/vttablet/tabletserver/splitquery/full_scan_algorithm.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/vttablet/tabletserver/splitquery/full_scan_algorithm_test.go b/go/vt/vttablet/tabletserver/splitquery/full_scan_algorithm_test.go index b47d6cf9bde..f5a9393e941 100644 --- a/go/vt/vttablet/tabletserver/splitquery/full_scan_algorithm_test.go +++ b/go/vt/vttablet/tabletserver/splitquery/full_scan_algorithm_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/vttablet/tabletserver/splitquery/split_algorithm_interface.go b/go/vt/vttablet/tabletserver/splitquery/split_algorithm_interface.go index aac496d2669..b97cb2c5eb7 100644 --- a/go/vt/vttablet/tabletserver/splitquery/split_algorithm_interface.go +++ b/go/vt/vttablet/tabletserver/splitquery/split_algorithm_interface.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/vttablet/tabletserver/splitquery/split_params.go b/go/vt/vttablet/tabletserver/splitquery/split_params.go index 2cc020bcf15..bcd062364c5 100644 --- a/go/vt/vttablet/tabletserver/splitquery/split_params.go +++ b/go/vt/vttablet/tabletserver/splitquery/split_params.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/vttablet/tabletserver/splitquery/split_params_test.go b/go/vt/vttablet/tabletserver/splitquery/split_params_test.go index 758f4d16882..b5400128177 100644 --- a/go/vt/vttablet/tabletserver/splitquery/split_params_test.go +++ b/go/vt/vttablet/tabletserver/splitquery/split_params_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/vttablet/tabletserver/splitquery/splitter.go b/go/vt/vttablet/tabletserver/splitquery/splitter.go index 9f884176622..ee516197a22 100644 --- a/go/vt/vttablet/tabletserver/splitquery/splitter.go +++ b/go/vt/vttablet/tabletserver/splitquery/splitter.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/vttablet/tabletserver/splitquery/splitter_test.go b/go/vt/vttablet/tabletserver/splitquery/splitter_test.go index 0f23abdfad9..f0b91bb6e92 100644 --- a/go/vt/vttablet/tabletserver/splitquery/splitter_test.go +++ b/go/vt/vttablet/tabletserver/splitquery/splitter_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/vttablet/tabletserver/splitquery/sql_executer_interface.go b/go/vt/vttablet/tabletserver/splitquery/sql_executer_interface.go index 69133efe806..cc393fccb0b 100644 --- a/go/vt/vttablet/tabletserver/splitquery/sql_executer_interface.go +++ b/go/vt/vttablet/tabletserver/splitquery/sql_executer_interface.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/vttablet/tabletserver/splitquery/testutils_test.go b/go/vt/vttablet/tabletserver/splitquery/testutils_test.go index 84eafc9abb8..746bc18aa43 100644 --- a/go/vt/vttablet/tabletserver/splitquery/testutils_test.go +++ b/go/vt/vttablet/tabletserver/splitquery/testutils_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/vttablet/tabletserver/splitquery/utils.go b/go/vt/vttablet/tabletserver/splitquery/utils.go index b60e812ab38..a626fab59a9 100644 --- a/go/vt/vttablet/tabletserver/splitquery/utils.go +++ b/go/vt/vttablet/tabletserver/splitquery/utils.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/vttablet/tabletserver/status.go b/go/vt/vttablet/tabletserver/status.go index 5bea9a5e5c1..01271609e3d 100644 --- a/go/vt/vttablet/tabletserver/status.go +++ b/go/vt/vttablet/tabletserver/status.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/vttablet/tabletserver/stream_queryz.go b/go/vt/vttablet/tabletserver/stream_queryz.go index 79449817f03..a9f3bba9cb9 100644 --- a/go/vt/vttablet/tabletserver/stream_queryz.go +++ b/go/vt/vttablet/tabletserver/stream_queryz.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vttablet/tabletserver/stream_queryz_test.go b/go/vt/vttablet/tabletserver/stream_queryz_test.go index 19109c7d44d..2b7381b5c43 100644 --- a/go/vt/vttablet/tabletserver/stream_queryz_test.go +++ b/go/vt/vttablet/tabletserver/stream_queryz_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vttablet/tabletserver/tabletenv/config.go b/go/vt/vttablet/tabletserver/tabletenv/config.go index 2c3cad42d13..24eb1e5d7fe 100644 --- a/go/vt/vttablet/tabletserver/tabletenv/config.go +++ b/go/vt/vttablet/tabletserver/tabletenv/config.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vttablet/tabletserver/tabletenv/local_context.go b/go/vt/vttablet/tabletserver/tabletenv/local_context.go index 69ce6efa084..fc18c91bea7 100644 --- a/go/vt/vttablet/tabletserver/tabletenv/local_context.go +++ b/go/vt/vttablet/tabletserver/tabletenv/local_context.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vttablet/tabletserver/tabletenv/logstats.go b/go/vt/vttablet/tabletserver/tabletenv/logstats.go index c8967c4596c..8849b833651 100644 --- a/go/vt/vttablet/tabletserver/tabletenv/logstats.go +++ b/go/vt/vttablet/tabletserver/tabletenv/logstats.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vttablet/tabletserver/tabletenv/logstats_test.go b/go/vt/vttablet/tabletserver/tabletenv/logstats_test.go index 9f5dbe05047..f3865fd00b7 100644 --- a/go/vt/vttablet/tabletserver/tabletenv/logstats_test.go +++ b/go/vt/vttablet/tabletserver/tabletenv/logstats_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -192,12 +192,12 @@ func TestLogStatsFormatQuerySources(t *testing.T) { logStats.QuerySources |= QuerySourceMySQL if !strings.Contains(logStats.FmtQuerySources(), "mysql") { - t.Fatalf("'mysql' should be in formated query sources") + t.Fatalf("'mysql' should be in formatted query sources") } logStats.QuerySources |= QuerySourceConsolidator if !strings.Contains(logStats.FmtQuerySources(), "consolidator") { - t.Fatalf("'consolidator' should be in formated query sources") + t.Fatalf("'consolidator' should be in formatted query sources") } } diff --git a/go/vt/vttablet/tabletserver/tabletenv/tabletenv.go b/go/vt/vttablet/tabletserver/tabletenv/tabletenv.go index 0fd1dfc774b..d3945dafee4 100644 --- a/go/vt/vttablet/tabletserver/tabletenv/tabletenv.go +++ b/go/vt/vttablet/tabletserver/tabletenv/tabletenv.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vttablet/tabletserver/tabletserver.go b/go/vt/vttablet/tabletserver/tabletserver.go index 64711af9b83..1de6dbfa8dd 100644 --- a/go/vt/vttablet/tabletserver/tabletserver.go +++ b/go/vt/vttablet/tabletserver/tabletserver.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -137,7 +137,6 @@ func stateInfo(state int64) string { // a subcomponent. These should also be idempotent. type TabletServer struct { QueryTimeout sync2.AtomicDuration - BeginTimeout sync2.AtomicDuration TerseErrors bool enableHotRowProtection bool @@ -265,7 +264,6 @@ func NewTabletServerWithNilTopoServer(config tabletenv.TabletConfig) *TabletServ func NewTabletServer(config tabletenv.TabletConfig, topoServer *topo.Server, alias topodatapb.TabletAlias) *TabletServer { tsv := &TabletServer{ QueryTimeout: sync2.NewAtomicDuration(time.Duration(config.QueryTimeout * 1e9)), - BeginTimeout: sync2.NewAtomicDuration(time.Duration(config.TxPoolTimeout * 1e9)), TerseErrors: config.TerseErrors, enableHotRowProtection: config.EnableHotRowProtection || config.EnableHotRowProtectionDryRun, checkMySQLThrottler: sync2.NewSemaphore(1, 0), @@ -304,7 +302,6 @@ func NewTabletServer(config tabletenv.TabletConfig, topoServer *topo.Server, ali }) stats.NewGaugeDurationFunc("QueryTimeout", "Tablet server query timeout", tsv.QueryTimeout.Get) stats.NewGaugeDurationFunc("QueryPoolTimeout", "Tablet server timeout to get a connection from the query pool", tsv.qe.connTimeout.Get) - stats.NewGaugeDurationFunc("BeginTimeout", "Tablet server begin timeout", tsv.BeginTimeout.Get) }) // TODO(sougou): move this up once the stats naming problem is fixed. tsv.vstreamer = vstreamer.NewEngine(srvTopoServer, tsv.se) @@ -772,7 +769,7 @@ func (tsv *TabletServer) SchemaEngine() *schema.Engine { // Begin starts a new transaction. This is allowed only if the state is StateServing. func (tsv *TabletServer) Begin(ctx context.Context, target *querypb.Target, options *querypb.ExecuteOptions) (transactionID int64, err error) { err = tsv.execRequest( - ctx, tsv.BeginTimeout.Get(), + ctx, tsv.QueryTimeout.Get(), "Begin", "begin", nil, target, options, true /* isBegin */, false, /* allowOnShutdown */ func(ctx context.Context, logStats *tabletenv.LogStats) error { @@ -970,7 +967,7 @@ func (tsv *TabletServer) ConcludeTransaction(ctx context.Context, target *queryp ) } -// ReadTransaction returns the metadata for the sepcified dtid. +// ReadTransaction returns the metadata for the specified dtid. func (tsv *TabletServer) ReadTransaction(ctx context.Context, target *querypb.Target, dtid string) (metadata *querypb.TransactionMetadata, err error) { err = tsv.execRequest( ctx, tsv.QueryTimeout.Get(), @@ -1409,6 +1406,14 @@ func (tsv *TabletServer) VStreamRows(ctx context.Context, target *querypb.Target return tsv.vstreamer.StreamRows(ctx, query, row, send) } +// VStreamResults streams rows from the specified starting point. +func (tsv *TabletServer) VStreamResults(ctx context.Context, target *querypb.Target, query string, send func(*binlogdatapb.VStreamResultsResponse) error) error { + if err := tsv.verifyTarget(ctx, target); err != nil { + return err + } + return tsv.vstreamer.StreamResults(ctx, query, send) +} + // SplitQuery splits a query + bind variables into smaller queries that return a // subset of rows from the original query. This is the new version that supports multiple // split columns and multiple split algorithms. @@ -2180,6 +2185,17 @@ func (tsv *TabletServer) TxTimeout() time.Duration { return tsv.te.txPool.Timeout() } +// SetTxPoolTimeout changes the transaction pool timeout to the specified value. +// This function should only be used for testing. +func (tsv *TabletServer) SetTxPoolTimeout(val time.Duration) { + tsv.te.txPool.SetPoolTimeout(val) +} + +// TxPoolTimeout returns the transaction pool timeout. +func (tsv *TabletServer) TxPoolTimeout() time.Duration { + return tsv.te.txPool.PoolTimeout() +} + // SetQueryPlanCacheCap changes the pool size to the specified value. // This function should only be used for testing. func (tsv *TabletServer) SetQueryPlanCacheCap(val int) { diff --git a/go/vt/vttablet/tabletserver/tabletserver_test.go b/go/vt/vttablet/tabletserver/tabletserver_test.go index ca5d2c38dc7..b8fd1a3d204 100644 --- a/go/vt/vttablet/tabletserver/tabletserver_test.go +++ b/go/vt/vttablet/tabletserver/tabletserver_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vttablet/tabletserver/testutils_test.go b/go/vt/vttablet/tabletserver/testutils_test.go index 54259c67c08..ef3afb94438 100644 --- a/go/vt/vttablet/tabletserver/testutils_test.go +++ b/go/vt/vttablet/tabletserver/testutils_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vttablet/tabletserver/twopc.go b/go/vt/vttablet/tabletserver/twopc.go index 79be25c59f5..68bf9949e56 100644 --- a/go/vt/vttablet/tabletserver/twopc.go +++ b/go/vt/vttablet/tabletserver/twopc.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vttablet/tabletserver/twopc_test.go b/go/vt/vttablet/tabletserver/twopc_test.go index 330e17c3f80..c64231be73b 100644 --- a/go/vt/vttablet/tabletserver/twopc_test.go +++ b/go/vt/vttablet/tabletserver/twopc_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vttablet/tabletserver/twopcz.go b/go/vt/vttablet/tabletserver/twopcz.go index 1d16ece1245..6f93d05e580 100644 --- a/go/vt/vttablet/tabletserver/twopcz.go +++ b/go/vt/vttablet/tabletserver/twopcz.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vttablet/tabletserver/tx_engine.go b/go/vt/vttablet/tabletserver/tx_engine.go index 148569a022f..7b663df5899 100644 --- a/go/vt/vttablet/tabletserver/tx_engine.go +++ b/go/vt/vttablet/tabletserver/tx_engine.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -118,6 +118,7 @@ func NewTxEngine(checker connpool.MySQLChecker, config tabletenv.TabletConfig) * config.FoundRowsPoolSize, config.TxPoolPrefillParallelism, time.Duration(config.TransactionTimeout*1e9), + time.Duration(config.TxPoolTimeout*1e9), time.Duration(config.IdleTimeout*1e9), config.TxPoolWaiterCap, checker, diff --git a/go/vt/vttablet/tabletserver/tx_engine_test.go b/go/vt/vttablet/tabletserver/tx_engine_test.go index 6cc412a96a9..710d1c9f5d6 100644 --- a/go/vt/vttablet/tabletserver/tx_engine_test.go +++ b/go/vt/vttablet/tabletserver/tx_engine_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vttablet/tabletserver/tx_executor.go b/go/vt/vttablet/tabletserver/tx_executor.go index e485174745f..69d3018c97f 100644 --- a/go/vt/vttablet/tabletserver/tx_executor.go +++ b/go/vt/vttablet/tabletserver/tx_executor.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vttablet/tabletserver/tx_executor_test.go b/go/vt/vttablet/tabletserver/tx_executor_test.go index 4635d0d9a39..75c0517bb99 100644 --- a/go/vt/vttablet/tabletserver/tx_executor_test.go +++ b/go/vt/vttablet/tabletserver/tx_executor_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vttablet/tabletserver/tx_pool.go b/go/vt/vttablet/tabletserver/tx_pool.go index aaa74dbcac0..e7ecfcc513d 100644 --- a/go/vt/vttablet/tabletserver/tx_pool.go +++ b/go/vt/vttablet/tabletserver/tx_pool.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -88,13 +88,14 @@ type TxPool struct { // connections with CLIENT_FOUND_ROWS flag set. A separate // pool is needed because this option can only be set at // connection time. - foundRowsPool *connpool.Pool - activePool *pools.Numbered - lastID sync2.AtomicInt64 - timeout sync2.AtomicDuration - ticks *timer.Timer - checker connpool.MySQLChecker - limiter txlimiter.TxLimiter + foundRowsPool *connpool.Pool + activePool *pools.Numbered + lastID sync2.AtomicInt64 + transactionTimeout sync2.AtomicDuration + transactionPoolTimeout sync2.AtomicDuration + ticks *timer.Timer + checker connpool.MySQLChecker + limiter txlimiter.TxLimiter // Tracking culprits that cause tx pool full errors. logMu sync.Mutex lastLog time.Time @@ -108,27 +109,30 @@ func NewTxPool( capacity int, foundRowsCapacity int, prefillParallelism int, - timeout time.Duration, + transactionTimeout time.Duration, + transactionPoolTimeout time.Duration, idleTimeout time.Duration, waiterCap int, checker connpool.MySQLChecker, limiter txlimiter.TxLimiter) *TxPool { axp := &TxPool{ - conns: connpool.New(prefix+"TransactionPool", capacity, prefillParallelism, idleTimeout, checker), - foundRowsPool: connpool.New(prefix+"FoundRowsPool", foundRowsCapacity, prefillParallelism, idleTimeout, checker), - activePool: pools.NewNumbered(), - lastID: sync2.NewAtomicInt64(time.Now().UnixNano()), - timeout: sync2.NewAtomicDuration(timeout), - waiterCap: sync2.NewAtomicInt64(int64(waiterCap)), - waiters: sync2.NewAtomicInt64(0), - ticks: timer.NewTimer(timeout / 10), - checker: checker, - limiter: limiter, + conns: connpool.New(prefix+"TransactionPool", capacity, prefillParallelism, idleTimeout, checker), + foundRowsPool: connpool.New(prefix+"FoundRowsPool", foundRowsCapacity, prefillParallelism, idleTimeout, checker), + activePool: pools.NewNumbered(), + lastID: sync2.NewAtomicInt64(time.Now().UnixNano()), + transactionTimeout: sync2.NewAtomicDuration(transactionTimeout), + transactionPoolTimeout: sync2.NewAtomicDuration(transactionPoolTimeout), + waiterCap: sync2.NewAtomicInt64(int64(waiterCap)), + waiters: sync2.NewAtomicInt64(0), + ticks: timer.NewTimer(transactionTimeout / 10), + checker: checker, + limiter: limiter, } txOnce.Do(func() { // Careful: conns also exports name+"xxx" vars, // but we know it doesn't export Timeout. - stats.NewGaugeDurationFunc(prefix+"TransactionPoolTimeout", "Transaction pool timeout", axp.timeout.Get) + stats.NewGaugeDurationFunc(prefix+"TransactionTimeout", "Transaction timeout", axp.transactionTimeout.Get) + stats.NewGaugeDurationFunc(prefix+"TransactionPoolTimeout", "Timeout to get a connection from the transaction pool", axp.transactionPoolTimeout.Get) stats.NewGaugeFunc(prefix+"TransactionPoolWaiters", "Transaction pool waiters", axp.waiters.Get) }) return axp @@ -230,10 +234,12 @@ func (axp *TxPool) Begin(ctx context.Context, options *querypb.ExecuteOptions) ( axp.limiter.Release(immediateCaller, effectiveCaller) }() + poolCtx, poolCancel := context.WithTimeout(ctx, axp.transactionPoolTimeout.Get()) + defer poolCancel() if options.GetClientFoundRows() { - conn, err = axp.foundRowsPool.Get(ctx) + conn, err = axp.foundRowsPool.Get(poolCtx) } else { - conn, err = axp.conns.Get(ctx) + conn, err = axp.conns.Get(poolCtx) } if err != nil { switch err { @@ -388,15 +394,25 @@ func (axp *TxPool) LogActive() { // Timeout returns the transaction timeout. func (axp *TxPool) Timeout() time.Duration { - return axp.timeout.Get() + return axp.transactionTimeout.Get() } // SetTimeout sets the transaction timeout. func (axp *TxPool) SetTimeout(timeout time.Duration) { - axp.timeout.Set(timeout) + axp.transactionTimeout.Set(timeout) axp.ticks.SetInterval(timeout / 10) } +// PoolTimeout returns the transaction pool timeout. +func (axp *TxPool) PoolTimeout() time.Duration { + return axp.transactionPoolTimeout.Get() +} + +// SetPoolTimeout sets the transaction pool timeout. +func (axp *TxPool) SetPoolTimeout(timeout time.Duration) { + axp.transactionPoolTimeout.Set(timeout) +} + // TxConnection is meant for executing transactions. It can return itself to // the tx pool correctly. It also does not retry statements if there // are failures. diff --git a/go/vt/vttablet/tabletserver/tx_pool_test.go b/go/vt/vttablet/tabletserver/tx_pool_test.go index 5310cb2226e..cdd11cac5a0 100644 --- a/go/vt/vttablet/tabletserver/tx_pool_test.go +++ b/go/vt/vttablet/tabletserver/tx_pool_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -693,6 +693,7 @@ func newTxPool() *TxPool { poolName := fmt.Sprintf("TestTransactionPool-%d", randID) transactionCap := 300 transactionTimeout := time.Duration(30 * time.Second) + transactionPoolTimeout := time.Duration(40 * time.Second) waiterCap := 500000 idleTimeout := time.Duration(30 * time.Second) limiter := &txlimiter.TxAllowAll{} @@ -702,6 +703,7 @@ func newTxPool() *TxPool { transactionCap, 0, transactionTimeout, + transactionPoolTimeout, idleTimeout, waiterCap, DummyChecker, diff --git a/go/vt/vttablet/tabletserver/tx_prep_pool.go b/go/vt/vttablet/tabletserver/tx_prep_pool.go index 184431cc450..0ec7d51c3c0 100644 --- a/go/vt/vttablet/tabletserver/tx_prep_pool.go +++ b/go/vt/vttablet/tabletserver/tx_prep_pool.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -24,7 +24,7 @@ import ( var ( errPrepCommitting = errors.New("committing") - errPrepFailed = errors.New("failed") + errPrepFailed = errors.New("failed") ) // TxPreparedPool manages connections for prepared transactions. diff --git a/go/vt/vttablet/tabletserver/tx_prep_pool_test.go b/go/vt/vttablet/tabletserver/tx_prep_pool_test.go index d3313d809b8..9716d57a54a 100644 --- a/go/vt/vttablet/tabletserver/tx_prep_pool_test.go +++ b/go/vt/vttablet/tabletserver/tx_prep_pool_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vttablet/tabletserver/txlimiter/tx_limiter.go b/go/vt/vttablet/tabletserver/txlimiter/tx_limiter.go index f68d01e7bce..a8fe9b64f02 100644 --- a/go/vt/vttablet/tabletserver/txlimiter/tx_limiter.go +++ b/go/vt/vttablet/tabletserver/txlimiter/tx_limiter.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vttablet/tabletserver/txlimiter/tx_limiter_test.go b/go/vt/vttablet/tabletserver/txlimiter/tx_limiter_test.go index e56b093e093..09616fe8948 100644 --- a/go/vt/vttablet/tabletserver/txlimiter/tx_limiter_test.go +++ b/go/vt/vttablet/tabletserver/txlimiter/tx_limiter_test.go @@ -1,3 +1,19 @@ +/* +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 txlimiter import ( diff --git a/go/vt/vttablet/tabletserver/txlogz.go b/go/vt/vttablet/tabletserver/txlogz.go index 843994bdd7e..f393941add4 100644 --- a/go/vt/vttablet/tabletserver/txlogz.go +++ b/go/vt/vttablet/tabletserver/txlogz.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vttablet/tabletserver/txlogz_test.go b/go/vt/vttablet/tabletserver/txlogz_test.go index 66db0c633a4..2f3564c9dd8 100644 --- a/go/vt/vttablet/tabletserver/txlogz_test.go +++ b/go/vt/vttablet/tabletserver/txlogz_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vttablet/tabletserver/txserializer/tx_serializer.go b/go/vt/vttablet/tabletserver/txserializer/tx_serializer.go index f0c5e2f49cb..a7c0accffdf 100644 --- a/go/vt/vttablet/tabletserver/txserializer/tx_serializer.go +++ b/go/vt/vttablet/tabletserver/txserializer/tx_serializer.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/vttablet/tabletserver/txserializer/tx_serializer_test.go b/go/vt/vttablet/tabletserver/txserializer/tx_serializer_test.go index bc64e396a66..e6443a9eee4 100644 --- a/go/vt/vttablet/tabletserver/txserializer/tx_serializer_test.go +++ b/go/vt/vttablet/tabletserver/txserializer/tx_serializer_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/vttablet/tabletserver/txthrottler/tx_throttler.go b/go/vt/vttablet/tabletserver/txthrottler/tx_throttler.go index 401125fbde3..e5c5b532021 100644 --- a/go/vt/vttablet/tabletserver/txthrottler/tx_throttler.go +++ b/go/vt/vttablet/tabletserver/txthrottler/tx_throttler.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vttablet/tabletserver/txthrottler/tx_throttler_test.go b/go/vt/vttablet/tabletserver/txthrottler/tx_throttler_test.go index a470573583d..25eddda0cbc 100644 --- a/go/vt/vttablet/tabletserver/txthrottler/tx_throttler_test.go +++ b/go/vt/vttablet/tabletserver/txthrottler/tx_throttler_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vttablet/tabletserver/vstreamer/engine.go b/go/vt/vttablet/tabletserver/vstreamer/engine.go index 7147289fa20..67ae75be8c0 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/engine.go +++ b/go/vt/vttablet/tabletserver/vstreamer/engine.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Vitess Authors. +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. @@ -56,10 +56,11 @@ type Engine struct { isOpen bool // wg is incremented for every Stream, and decremented on end. // Close waits for all current streams to end by waiting on wg. - wg sync.WaitGroup - streamers map[int]*vstreamer - rowStreamers map[int]*rowStreamer - streamIdx int + wg sync.WaitGroup + streamers map[int]*vstreamer + rowStreamers map[int]*rowStreamer + resultStreamers map[int]*resultStreamer + streamIdx int // watcherOnce is used for initializing kschema // and setting up the vschema watch. It's guaranteed that @@ -80,11 +81,12 @@ type Engine struct { // Open and Close can be called multiple times and are idempotent. func NewEngine(ts srvtopo.Server, se *schema.Engine) *Engine { vse := &Engine{ - streamers: make(map[int]*vstreamer), - rowStreamers: make(map[int]*rowStreamer), - kschema: &vindexes.KeyspaceSchema{}, - ts: ts, - se: se, + streamers: make(map[int]*vstreamer), + rowStreamers: make(map[int]*rowStreamer), + resultStreamers: make(map[int]*resultStreamer), + kschema: &vindexes.KeyspaceSchema{}, + ts: ts, + se: se, } once.Do(func() { vschemaErrors = stats.NewCounter("VSchemaErrors", "Count of VSchema errors") @@ -120,12 +122,14 @@ func (vse *Engine) Close() { if !vse.isOpen { return } + // cancels are non-blocking. for _, s := range vse.streamers { - // cancel is non-blocking. s.Cancel() } for _, s := range vse.rowStreamers { - // cancel is non-blocking. + s.Cancel() + } + for _, s := range vse.resultStreamers { s.Cancel() } vse.isOpen = false @@ -221,6 +225,40 @@ func (vse *Engine) StreamRows(ctx context.Context, query string, lastpk []sqltyp return rowStreamer.Stream() } +// StreamResults streams results of the query with the gtid. +func (vse *Engine) StreamResults(ctx context.Context, query string, send func(*binlogdatapb.VStreamResultsResponse) error) error { + // Create stream and add it to the map. + resultStreamer, idx, err := func() (*resultStreamer, int, error) { + vse.mu.Lock() + defer vse.mu.Unlock() + if !vse.isOpen { + return nil, 0, errors.New("VStreamer is not open") + } + resultStreamer := newResultStreamer(ctx, vse.cp, query, send) + idx := vse.streamIdx + vse.resultStreamers[idx] = resultStreamer + vse.streamIdx++ + // Now that we've added the stream, increment wg. + // This must be done before releasing the lock. + vse.wg.Add(1) + return resultStreamer, idx, nil + }() + if err != nil { + return err + } + + // Remove stream from map and decrement wg when it ends. + defer func() { + vse.mu.Lock() + defer vse.mu.Unlock() + delete(vse.resultStreamers, idx) + vse.wg.Done() + }() + + // No lock is held while streaming, but wg is incremented. + return resultStreamer.Stream() +} + // ServeHTTP shows the current VSchema. func (vse *Engine) ServeHTTP(response http.ResponseWriter, request *http.Request) { if err := acl.CheckAccessHTTP(request, acl.DEBUGGING); err != nil { diff --git a/go/vt/vttablet/tabletserver/vstreamer/engine_test.go b/go/vt/vttablet/tabletserver/vstreamer/engine_test.go index c88a9aeef40..575b146b6e0 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/engine_test.go +++ b/go/vt/vttablet/tabletserver/vstreamer/engine_test.go @@ -62,7 +62,7 @@ func TestUpdateVSchema(t *testing.T) { }}, } - _ = startStream(ctx, t, filter) + _ = startStream(ctx, t, filter, "") cancel() startCount := expectUpdateCount(t, 1) diff --git a/go/vt/vttablet/tabletserver/vstreamer/main_test.go b/go/vt/vttablet/tabletserver/vstreamer/main_test.go index 224091078f0..0b5acf7017b 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/main_test.go +++ b/go/vt/vttablet/tabletserver/vstreamer/main_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vttablet/tabletserver/vstreamer/planbuilder.go b/go/vt/vttablet/tabletserver/vstreamer/planbuilder.go index a9e593c0136..43affd74d35 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/planbuilder.go +++ b/go/vt/vttablet/tabletserver/vstreamer/planbuilder.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Vitess Authors. +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. @@ -72,6 +72,9 @@ func (plan *Plan) fields() []*querypb.Field { func (plan *Plan) filter(values []sqltypes.Value) (bool, []sqltypes.Value, error) { result := make([]sqltypes.Value, len(plan.ColExprs)) for i, colExpr := range plan.ColExprs { + if colExpr.ColNum >= len(values) { + return false, nil, fmt.Errorf("index out of range, colExpr.ColNum: %d, len(values): %d", colExpr.ColNum, len(values)) + } result[i] = values[colExpr.ColNum] } if plan.Vindex == nil { @@ -128,6 +131,7 @@ func mustSendDDL(query mysql.Query, dbname string, filter *binlogdatapb.Filter) return true } +// tableMatches is similar to the one defined in vreplication. func tableMatches(table sqlparser.TableName, dbname string, filter *binlogdatapb.Filter) bool { if !table.Qualifier.IsEmpty() && table.Qualifier.String() != dbname { return false @@ -356,8 +360,8 @@ func (plan *Plan) analyzeInKeyRange(kschema *vindexes.KeyspaceSchema, exprs sqlp if err != nil { return err } - if !plan.Vindex.IsUnique() || !plan.Vindex.IsFunctional() { - return fmt.Errorf("vindex must be Unique and Functional to be used for VReplication: %s", vtype) + if !plan.Vindex.IsUnique() { + return fmt.Errorf("vindex must be Unique to be used for VReplication: %s", vtype) } krExpr = exprs[2] default: diff --git a/go/vt/vttablet/tabletserver/vstreamer/planbuilder_test.go b/go/vt/vttablet/tabletserver/vstreamer/planbuilder_test.go index 5d46fb2eede..731de846b9c 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/planbuilder_test.go +++ b/go/vt/vttablet/tabletserver/vstreamer/planbuilder_test.go @@ -362,7 +362,7 @@ func TestPlanbuilder(t *testing.T) { }, { inTable: t1, inRule: &binlogdatapb.Rule{Match: "t1", Filter: "select id, val from t1 where in_keyrange(id, 'lookup', '-80')"}, - outErr: `vindex must be Unique and Functional to be used for VReplication: lookup`, + outErr: `vindex must be Unique to be used for VReplication: lookup`, }, { inTable: t1, inRule: &binlogdatapb.Rule{Match: "t1", Filter: "select id, val from t1 where in_keyrange(id, 'hash', '80')"}, diff --git a/go/vt/vttablet/tabletserver/vstreamer/resultstreamer.go b/go/vt/vttablet/tabletserver/vstreamer/resultstreamer.go new file mode 100644 index 00000000000..e79b1076434 --- /dev/null +++ b/go/vt/vttablet/tabletserver/vstreamer/resultstreamer.go @@ -0,0 +1,168 @@ +/* +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 vstreamer + +import ( + "context" + "fmt" + + "vitess.io/vitess/go/mysql" + "vitess.io/vitess/go/sqltypes" + "vitess.io/vitess/go/vt/dbconfigs" + "vitess.io/vitess/go/vt/log" + binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" + "vitess.io/vitess/go/vt/sqlparser" +) + +type resultStreamer struct { + ctx context.Context + cancel func() + + cp *mysql.ConnParams + query string + tableName sqlparser.TableIdent + send func(*binlogdatapb.VStreamResultsResponse) error +} + +func newResultStreamer(ctx context.Context, cp *mysql.ConnParams, query string, send func(*binlogdatapb.VStreamResultsResponse) error) *resultStreamer { + ctx, cancel := context.WithCancel(ctx) + return &resultStreamer{ + ctx: ctx, + cancel: cancel, + cp: cp, + query: query, + send: send, + } +} + +func (rs *resultStreamer) Cancel() { + rs.cancel() +} + +func (rs *resultStreamer) Stream() error { + _, fromTable, err := analyzeSelect(rs.query) + if err != nil { + return err + } + rs.tableName = fromTable + + conn, err := rs.mysqlConnect() + if err != nil { + return err + } + defer conn.Close() + gtid, err := rs.startStreaming(conn) + if err != nil { + return err + } + + // first call the callback with the fields + flds, err := conn.Fields() + if err != nil { + return err + } + + err = rs.send(&binlogdatapb.VStreamResultsResponse{ + Fields: flds, + Gtid: gtid, + }) + if err != nil { + return fmt.Errorf("stream send error: %v", err) + } + + response := &binlogdatapb.VStreamResultsResponse{} + byteCount := 0 + for { + select { + case <-rs.ctx.Done(): + return fmt.Errorf("stream ended: %v", rs.ctx.Err()) + default: + } + + row, err := conn.FetchNext() + if err != nil { + return err + } + if row == nil { + break + } + response.Rows = append(response.Rows, sqltypes.RowToProto3(row)) + for _, s := range row { + byteCount += s.Len() + } + + if byteCount >= *PacketSize { + err = rs.send(response) + if err != nil { + return err + } + // empty the rows so we start over, but we keep the + // same capacity + response.Rows = response.Rows[:0] + byteCount = 0 + } + } + + if len(response.Rows) > 0 { + err = rs.send(response) + if err != nil { + return err + } + } + + return nil +} + +func (rs *resultStreamer) startStreaming(conn *mysql.Conn) (string, error) { + lockConn, err := rs.mysqlConnect() + if err != nil { + return "", err + } + // To be safe, always unlock tables, even if lock tables might fail. + defer func() { + _, err := lockConn.ExecuteFetch("unlock tables", 0, false) + if err != nil { + log.Warning("Unlock tables failed: %v", err) + } else { + log.Infof("Tables unlocked", rs.tableName) + } + lockConn.Close() + }() + + log.Infof("Locking table %s for copying", rs.tableName) + if _, err := lockConn.ExecuteFetch(fmt.Sprintf("lock tables %s read", sqlparser.String(rs.tableName)), 0, false); err != nil { + return "", err + } + pos, err := lockConn.MasterPosition() + if err != nil { + return "", err + } + + if err := conn.ExecuteStreamFetch(rs.query); err != nil { + return "", err + } + + return mysql.EncodePosition(pos), nil +} + +func (rs *resultStreamer) mysqlConnect() (*mysql.Conn, error) { + cp, err := dbconfigs.WithCredentials(rs.cp) + if err != nil { + return nil, err + } + return mysql.Connect(rs.ctx, cp) +} diff --git a/go/vt/vttablet/tabletserver/vstreamer/resultstreamer_test.go b/go/vt/vttablet/tabletserver/vstreamer/resultstreamer_test.go new file mode 100644 index 00000000000..b84915a08f6 --- /dev/null +++ b/go/vt/vttablet/tabletserver/vstreamer/resultstreamer_test.go @@ -0,0 +1,78 @@ +/* +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 vstreamer + +import ( + "context" + "fmt" + "testing" + + binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" +) + +func TestStreamResults(t *testing.T) { + if testing.Short() { + t.Skip() + } + + execStatements(t, []string{ + "create table t1(id int, val varbinary(128), primary key(id))", + "insert into t1 values (1, 'aaa'), (2, 'bbb')", + }) + defer execStatements(t, []string{ + "drop table t1", + }) + engine.se.Reload(context.Background()) + + query := "select id, val from t1 order by id" + wantStream := []string{ + `rows: rows: `, + } + i := 0 + ch := make(chan error) + // We don't want to report errors inside callback functions because + // line numbers come out wrong. + go func() { + first := true + defer close(ch) + err := engine.StreamResults(context.Background(), query, func(rows *binlogdatapb.VStreamResultsResponse) error { + if first { + first = false + if rows.Gtid == "" { + ch <- fmt.Errorf("stream gtid is empty") + } + return nil + } + if i >= len(wantStream) { + ch <- fmt.Errorf("unexpected stream rows: %v", rows) + return nil + } + srows := fmt.Sprintf("%v", rows) + if srows != wantStream[i] { + ch <- fmt.Errorf("stream %d:\n%s, want\n%s", i, srows, wantStream[i]) + } + i++ + return nil + }) + if err != nil { + ch <- err + } + }() + for err := range ch { + t.Error(err) + } +} diff --git a/go/vt/vttablet/tabletserver/vstreamer/rowstreamer.go b/go/vt/vttablet/tabletserver/vstreamer/rowstreamer.go index 82d3b04ad5b..c4114d451c0 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/rowstreamer.go +++ b/go/vt/vttablet/tabletserver/vstreamer/rowstreamer.go @@ -147,20 +147,20 @@ func (rs *rowStreamer) buildSelect() (string, error) { if len(rs.lastpk) != len(rs.pkColumns) { return "", fmt.Errorf("primary key values don't match length: %v vs %v", rs.lastpk, rs.pkColumns) } - buf.WriteString(" where (") + buf.WriteString(" where ") prefix := "" - for _, pk := range rs.pkColumns { - buf.Myprintf("%s%v", prefix, rs.plan.Table.Columns[pk].Name) - prefix = "," - } - buf.WriteString(") > (") - prefix = "" - for _, val := range rs.lastpk { - buf.WriteString(prefix) - prefix = "," - val.EncodeSQL(buf) + for lastcol := len(rs.pkColumns) - 1; lastcol >= 0; lastcol-- { + buf.Myprintf("%s(", prefix) + prefix = " or " + for i, pk := range rs.pkColumns[:lastcol] { + buf.Myprintf("%v = ", rs.plan.Table.Columns[pk].Name) + rs.lastpk[i].EncodeSQL(buf) + buf.Myprintf(" and ") + } + buf.Myprintf("%v > ", rs.plan.Table.Columns[rs.pkColumns[lastcol]].Name) + rs.lastpk[lastcol].EncodeSQL(buf) + buf.Myprintf(")") } - buf.WriteString(")") } buf.Myprintf(" order by ", sqlparser.NewTableIdent(rs.plan.Table.Name)) prefix = "" @@ -271,10 +271,6 @@ func (rs *rowStreamer) startStreaming(conn *mysql.Conn) (string, error) { }() log.Infof("Locking table %s for copying", rs.plan.Table.Name) - // mysql recommends this before locking tables. - if _, err := lockConn.ExecuteFetch("set autocommit=0", 0, false); err != nil { - return "", err - } if _, err := lockConn.ExecuteFetch(fmt.Sprintf("lock tables %s read", sqlparser.String(sqlparser.NewTableIdent(rs.plan.Table.Name))), 0, false); err != nil { return "", err } diff --git a/go/vt/vttablet/tabletserver/vstreamer/rowstreamer_test.go b/go/vt/vttablet/tabletserver/vstreamer/rowstreamer_test.go index 5266b3fe864..c57135f4d12 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/rowstreamer_test.go +++ b/go/vt/vttablet/tabletserver/vstreamer/rowstreamer_test.go @@ -42,11 +42,15 @@ func TestStreamRowsScan(t *testing.T) { // No PK "create table t3(id int, val varbinary(128))", "insert into t3 values (1, 'aaa'), (2, 'bbb')", + // Three-column PK + "create table t4(id1 int, id2 int, id3 int, val varbinary(128), primary key(id1, id2, id3))", + "insert into t4 values (1, 2, 3, 'aaa'), (2, 3, 4, 'bbb')", }) defer execStatements(t, []string{ "drop table t1", "drop table t2", "drop table t3", + "drop table t4", }) engine.se.Reload(context.Background()) @@ -63,7 +67,7 @@ func TestStreamRowsScan(t *testing.T) { `fields: fields: pkfields: `, `rows: lastpk: `, } - wantQuery = "select id, val from t1 where (id) > (1) order by id" + wantQuery = "select id, val from t1 where (id > 1) order by id" checkStream(t, "select * from t1", []sqltypes.Value{sqltypes.NewInt64(1)}, wantQuery, wantStream) // t1: different column ordering @@ -87,7 +91,7 @@ func TestStreamRowsScan(t *testing.T) { `fields: fields: fields: pkfields: pkfields: `, `rows: lastpk: `, } - wantQuery = "select id1, id2, val from t2 where (id1,id2) > (1,2) order by id1, id2" + wantQuery = "select id1, id2, val from t2 where (id1 = 1 and id2 > 2) or (id1 > 1) order by id1, id2" checkStream(t, "select * from t2", []sqltypes.Value{sqltypes.NewInt64(1), sqltypes.NewInt64(2)}, wantQuery, wantStream) // t3: all rows @@ -103,8 +107,24 @@ func TestStreamRowsScan(t *testing.T) { `fields: fields: pkfields: pkfields: `, `rows: lastpk: `, } - wantQuery = "select id, val from t3 where (id,val) > (1,'aaa') order by id, val" + wantQuery = "select id, val from t3 where (id = 1 and val > 'aaa') or (id > 1) order by id, val" checkStream(t, "select * from t3", []sqltypes.Value{sqltypes.NewInt64(1), sqltypes.NewVarBinary("aaa")}, wantQuery, wantStream) + + // t4: all rows + wantStream = []string{ + `fields: fields: fields: fields: pkfields: pkfields: pkfields: `, + `rows: rows: lastpk: `, + } + wantQuery = "select id1, id2, id3, val from t4 order by id1, id2, id3" + checkStream(t, "select * from t4", nil, wantQuery, wantStream) + + // t4: lastpk: 1,2,3 + wantStream = []string{ + `fields: fields: fields: fields: pkfields: pkfields: pkfields: `, + `rows: lastpk: `, + } + wantQuery = "select id1, id2, id3, val from t4 where (id1 = 1 and id2 = 2 and id3 > 3) or (id1 = 1 and id2 > 2) or (id1 > 1) order by id1, id2, id3" + checkStream(t, "select * from t4", []sqltypes.Value{sqltypes.NewInt64(1), sqltypes.NewInt64(2), sqltypes.NewInt64(3)}, wantQuery, wantStream) } func TestStreamRowsUnicode(t *testing.T) { diff --git a/go/vt/vttablet/tabletserver/vstreamer/vstreamer.go b/go/vt/vttablet/tabletserver/vstreamer/vstreamer.go index 91e09e8f330..791ee38e757 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/vstreamer.go +++ b/go/vt/vttablet/tabletserver/vstreamer/vstreamer.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Vitess Authors. +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. @@ -325,7 +325,7 @@ func (vs *vstreamer) parseEvent(ev mysql.BinlogEvent) ([]*binlogdatapb.VEvent, e case sqlparser.StmtOther: // These are DBA statements like REPAIR that can be ignored. default: - return nil, fmt.Errorf("unexpected statement type %s in row-based replication: %q", sqlparser.StmtType(cat), q.SQL) + return nil, fmt.Errorf("unexpected statement type %s in row-based replication: %q", cat, q.SQL) } case ev.IsTableMap(): // This is very frequent. It precedes every row event. @@ -342,17 +342,50 @@ func (vs *vstreamer) parseEvent(ev mysql.BinlogEvent) ([]*binlogdatapb.VEvent, e vs.plans[id] = nil return nil, nil } + tableName := tm.Name + var cols []schema.TableColumn + for i, typ := range tm.Types { + t, err := sqltypes.MySQLToType(int64(typ), 0) + if err != nil { + return nil, fmt.Errorf("unsupported type: %d, position: %d", typ, i) + } + cols = append(cols, schema.TableColumn{ + Name: sqlparser.NewColIdent(fmt.Sprintf("@%d", i+1)), + Type: t, + }) + } st := vs.se.GetTable(sqlparser.NewTableIdent(tm.Name)) if st == nil { - return nil, fmt.Errorf("unknown table %v in schema", tm.Name) - } - if len(st.Columns) < len(tm.Types) { - return nil, fmt.Errorf("cannot determine table columns for %s: event has %d columns, current schema has %d: %#v", tm.Name, len(tm.Types), len(st.Columns), ev) + if vs.filter.FieldEventMode == binlogdatapb.Filter_ERR_ON_MISMATCH { + return nil, fmt.Errorf("unknown table %v in schema", tm.Name) + } + } else { + if len(st.Columns) < len(tm.Types) && vs.filter.FieldEventMode == binlogdatapb.Filter_ERR_ON_MISMATCH { + return nil, fmt.Errorf("cannot determine table columns for %s: event has %d columns, current schema has %d: %#v", tm.Name, len(tm.Types), len(st.Columns), ev) + } + tableName = st.Name.String() + // check if the schema returned by schema.Engine matches with row. + schemaMatch := true + if len(tm.Types) <= len(st.Columns) { + for i := range tm.Types { + t := cols[i].Type + if !sqltypes.AreTypesEquivalent(t, st.Columns[i].Type) { + schemaMatch = false + break + } + } + } else { + schemaMatch = false + } + if schemaMatch { + // Columns should be truncated to match those in tm. + cols = st.Columns[:len(tm.Types)] + } } + table := &Table{ - Name: st.Name.String(), - // Columns should be truncated to match those in tm. - Columns: st.Columns[:len(tm.Types)], + Name: tableName, + Columns: cols, } plan, err := buildPlan(table, vs.kschema, vs.filter) if err != nil { diff --git a/go/vt/vttablet/tabletserver/vstreamer/vstreamer_test.go b/go/vt/vttablet/tabletserver/vstreamer/vstreamer_test.go index baa49af74e8..efe84b69573 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/vstreamer_test.go +++ b/go/vt/vttablet/tabletserver/vstreamer/vstreamer_test.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Vitess Authors. +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. @@ -130,7 +130,7 @@ func TestStatements(t *testing.T) { }, { input: "describe stream1", }} - runCases(t, nil, testcases) + runCases(t, nil, testcases, "") } func TestRegexp(t *testing.T) { @@ -172,7 +172,7 @@ func TestRegexp(t *testing.T) { `commit`, }}, }} - runCases(t, filter, testcases) + runCases(t, filter, testcases, "") } func TestREKeyRange(t *testing.T) { @@ -202,7 +202,7 @@ func TestREKeyRange(t *testing.T) { Filter: "-80", }}, } - ch := startStream(ctx, t, filter) + ch := startStream(ctx, t, filter, "") // 1, 2, 3 and 5 are in shard -80. // 4 and 6 are in shard 80-. @@ -306,7 +306,7 @@ func TestSelectFilter(t *testing.T) { `commit`, }}, }} - runCases(t, filter, testcases) + runCases(t, filter, testcases, "") } func TestDDLAddColumn(t *testing.T) { @@ -446,7 +446,7 @@ func TestUnsentDDL(t *testing.T) { Match: "/none/", }}, } - runCases(t, filter, testcases) + runCases(t, filter, testcases, "") } func TestBuffering(t *testing.T) { @@ -546,7 +546,57 @@ func TestBuffering(t *testing.T) { `type:DDL ddl:"alter table packet_test change val val varchar(128)" `, }}, }} - runCases(t, nil, testcases) + runCases(t, nil, testcases, "") +} + +func TestBestEffortNameInFieldEvent(t *testing.T) { + if testing.Short() { + t.Skip() + } + filter := &binlogdatapb.Filter{ + FieldEventMode: binlogdatapb.Filter_BEST_EFFORT, + Rules: []*binlogdatapb.Rule{{ + Match: "/.*/", + }}, + } + // Modeled after vttablet endtoend compatibility tests. + execStatements(t, []string{ + "create table vitess_test(id int, val varbinary(128), primary key(id))", + }) + position := masterPosition(t) + execStatements(t, []string{ + "insert into vitess_test values(1, 'abc')", + "rename table vitess_test to vitess_test_new", + }) + + defer execStatements(t, []string{ + "drop table vitess_test_new", + }) + engine.se.Reload(context.Background()) + testcases := []testcase{{ + input: []string{ + "insert into vitess_test_new values(2, 'abc')", + }, + // In this case, we don't have information about vitess_test since it was renamed to vitess_test_test. + // information returned by binlog for val column == varchar (rather than varbinary). + output: [][]string{{ + `gtid|begin`, + `gtid|begin`, + `type:FIELD field_event: fields: > `, + `type:ROW row_event: > > `, + `commit`, + }, { + `gtid|begin`, + `type:DDL ddl:"rename table vitess_test to vitess_test_new" `, + }, { + `gtid|begin`, + `gtid|begin`, + `type:FIELD field_event: fields: > `, + `type:ROW row_event: > > `, + `commit`, + }}, + }} + runCases(t, filter, testcases, position) } func TestTypes(t *testing.T) { @@ -687,7 +737,7 @@ func TestTypes(t *testing.T) { `commit`, }}, }} - runCases(t, nil, testcases) + runCases(t, nil, testcases, "") } func TestJSON(t *testing.T) { @@ -716,7 +766,7 @@ func TestJSON(t *testing.T) { `commit`, }}, }} - runCases(t, nil, testcases) + runCases(t, nil, testcases, "") } func TestExternalTable(t *testing.T) { @@ -746,7 +796,7 @@ func TestExternalTable(t *testing.T) { `commit`, }}, }} - runCases(t, nil, testcases) + runCases(t, nil, testcases, "") } func TestMinimalMode(t *testing.T) { @@ -827,12 +877,11 @@ func TestStatementMode(t *testing.T) { } } -func runCases(t *testing.T, filter *binlogdatapb.Filter, testcases []testcase) { +func runCases(t *testing.T, filter *binlogdatapb.Filter, testcases []testcase, postion string) { t.Helper() ctx, cancel := context.WithCancel(context.Background()) defer cancel() - - ch := startStream(ctx, t, filter) + ch := startStream(ctx, t, filter, postion) for _, tcase := range testcases { switch input := tcase.input.(type) { @@ -853,7 +902,6 @@ func runCases(t *testing.T, filter *binlogdatapb.Filter, testcases []testcase) { func expectLog(ctx context.Context, t *testing.T, input interface{}, ch <-chan []*binlogdatapb.VEvent, output [][]string) { t.Helper() - for _, wantset := range output { var evs []*binlogdatapb.VEvent var ok bool @@ -897,13 +945,15 @@ func expectLog(ctx context.Context, t *testing.T, input interface{}, ch <-chan [ } } -func startStream(ctx context.Context, t *testing.T, filter *binlogdatapb.Filter) <-chan []*binlogdatapb.VEvent { - pos := masterPosition(t) +func startStream(ctx context.Context, t *testing.T, filter *binlogdatapb.Filter, position string) <-chan []*binlogdatapb.VEvent { + if position == "" { + position = masterPosition(t) + } ch := make(chan []*binlogdatapb.VEvent) go func() { defer close(ch) - if err := vstream(ctx, t, pos, filter, ch); err != nil { + if err := vstream(ctx, t, position, filter, ch); err != nil { t.Error(err) } }() diff --git a/go/vt/vttablet/tabletservermock/controller.go b/go/vt/vttablet/tabletservermock/controller.go index f6f7ee99649..978f7980024 100644 --- a/go/vt/vttablet/tabletservermock/controller.go +++ b/go/vt/vttablet/tabletservermock/controller.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/vttablet/tmclient/rpc_client_api.go b/go/vt/vttablet/tmclient/rpc_client_api.go index 8b3b0927c2c..6e2ed4e4f20 100644 --- a/go/vt/vttablet/tmclient/rpc_client_api.go +++ b/go/vt/vttablet/tmclient/rpc_client_api.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -116,6 +116,9 @@ type TabletManagerClient interface { // MasterPosition returns the tablet's master position MasterPosition(ctx context.Context, tablet *topodatapb.Tablet) (string, error) + // WaitForPosition waits for the position to be reached + WaitForPosition(ctx context.Context, tablet *topodatapb.Tablet, pos string) error + // StopSlave stops the mysql replication StopSlave(ctx context.Context, tablet *topodatapb.Tablet) error @@ -167,7 +170,7 @@ type TabletManagerClient interface { // reparent_journal table. InitSlave(ctx context.Context, tablet *topodatapb.Tablet, parent *topodatapb.TabletAlias, replicationPosition string, timeCreatedNS int64) error - // DemoteMaster tells the soon-to-be-former master it's gonna change, + // DemoteMaster tells the soon-to-be-former master it's going to change, // and it should go read-only and return its current position. DemoteMaster(ctx context.Context, tablet *topodatapb.Tablet) (string, error) @@ -184,7 +187,7 @@ type TabletManagerClient interface { // SetMaster tells a tablet to make itself a slave to the // passed in master tablet alias, and wait for the row in the // reparent_journal table (if timeCreatedNS is non-zero). - SetMaster(ctx context.Context, tablet *topodatapb.Tablet, parent *topodatapb.TabletAlias, timeCreatedNS int64, forceStartSlave bool) error + SetMaster(ctx context.Context, tablet *topodatapb.Tablet, parent *topodatapb.TabletAlias, timeCreatedNS int64, waitPosition string, forceStartSlave bool) error // SlaveWasRestarted tells the remote tablet its master has changed SlaveWasRestarted(ctx context.Context, tablet *topodatapb.Tablet, parent *topodatapb.TabletAlias) error diff --git a/go/vt/vttest/environment.go b/go/vt/vttest/environment.go index 970465b9cbd..336e92c3b06 100644 --- a/go/vt/vttest/environment.go +++ b/go/vt/vttest/environment.go @@ -1,6 +1,5 @@ /* -Copyright 2017 Google Inc. -Copyright 2017 GitHub Inc. +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. @@ -123,15 +122,13 @@ func GetMySQLOptions(flavor string) (string, []string, error) { mycnf = append(mycnf, "config/mycnf/master_mariadb103.cnf") case "MariaDB": mycnf = append(mycnf, "config/mycnf/default-fast.cnf") - mycnf = append(mycnf, "config/mycnf/master_mariadb.cnf") - + mycnf = append(mycnf, "config/mycnf/master_mariadb100.cnf") case "MySQL80": mycnf = append(mycnf, "config/mycnf/default-fast.cnf") mycnf = append(mycnf, "config/mycnf/master_mysql80.cnf") case "MySQL56": mycnf = append(mycnf, "config/mycnf/default-fast.cnf") mycnf = append(mycnf, "config/mycnf/master_mysql56.cnf") - default: return "", nil, fmt.Errorf("unknown mysql flavor: %s", flavor) } diff --git a/go/vt/vttest/local_cluster.go b/go/vt/vttest/local_cluster.go index 8532052dded..85291d8e021 100644 --- a/go/vt/vttest/local_cluster.go +++ b/go/vt/vttest/local_cluster.go @@ -1,5 +1,5 @@ /* -Copyright 2017 GitHub Inc. +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. @@ -110,6 +110,9 @@ type Config struct { // The host name to use for the table otherwise it will be resolved from the local hostname TabletHostName string + + // Whether to enable/disable workflow manager + InitWorkflowManager bool } // InitSchemas is a shortcut for tests that just want to setup a single diff --git a/go/vt/vttest/mysqlctl.go b/go/vt/vttest/mysqlctl.go index d7e135dbfa4..8824d66b541 100644 --- a/go/vt/vttest/mysqlctl.go +++ b/go/vt/vttest/mysqlctl.go @@ -1,5 +1,5 @@ /* -Copyright 2017 GitHub Inc. +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. diff --git a/go/vt/vttest/randomdata.go b/go/vt/vttest/randomdata.go index 3f6356c9123..19eaeb98fb0 100644 --- a/go/vt/vttest/randomdata.go +++ b/go/vt/vttest/randomdata.go @@ -1,5 +1,5 @@ /* -Copyright 2017 GitHub Inc. +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. diff --git a/go/vt/vttest/shard_name.go b/go/vt/vttest/shard_name.go index 8befe92b1cc..05ae2fbfc2e 100644 --- a/go/vt/vttest/shard_name.go +++ b/go/vt/vttest/shard_name.go @@ -1,3 +1,19 @@ +/* +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 vttest import ( diff --git a/go/vt/vttest/vtprocess.go b/go/vt/vttest/vtprocess.go index 1e917282102..b9f5a164b9a 100644 --- a/go/vt/vttest/vtprocess.go +++ b/go/vt/vttest/vtprocess.go @@ -1,5 +1,5 @@ /* -Copyright 2017 GitHub Inc. +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. @@ -243,6 +243,9 @@ func VtcomboProcess(env Environment, args *Config, mysql MySQLManager) *VtProces if args.TabletHostName != "" { vt.ExtraArgs = append(vt.ExtraArgs, []string{"-tablet_hostname", args.TabletHostName}...) } + if args.InitWorkflowManager { + vt.ExtraArgs = append(vt.ExtraArgs, []string{"-workflow_manager_init"}...) + } if socket != "" { vt.ExtraArgs = append(vt.ExtraArgs, []string{ diff --git a/go/vt/vttime/clock.go b/go/vt/vttime/clock.go index b648b3ab4fc..1177be2f285 100644 --- a/go/vt/vttime/clock.go +++ b/go/vt/vttime/clock.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/vttime/doc.go b/go/vt/vttime/doc.go index 6d87317fd63..c7c6b621b27 100644 --- a/go/vt/vttime/doc.go +++ b/go/vt/vttime/doc.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/vttime/interval.go b/go/vt/vttime/interval.go index f06ea111b82..9446c17edb0 100644 --- a/go/vt/vttime/interval.go +++ b/go/vt/vttime/interval.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/vttime/interval_test.go b/go/vt/vttime/interval_test.go index db1db930f2e..0fa6fcb2421 100644 --- a/go/vt/vttime/interval_test.go +++ b/go/vt/vttime/interval_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/vttime/test_clock.go b/go/vt/vttime/test_clock.go index c817dcd61d2..16d16eb113a 100644 --- a/go/vt/vttime/test_clock.go +++ b/go/vt/vttime/test_clock.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/vttime/time_clock.go b/go/vt/vttime/time_clock.go index 7cb78248934..4af32ae1f2d 100644 --- a/go/vt/vttime/time_clock.go +++ b/go/vt/vttime/time_clock.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/vttime/time_clock_test.go b/go/vt/vttime/time_clock_test.go index 0a07d096af0..a42fb3321ed 100644 --- a/go/vt/vttime/time_clock_test.go +++ b/go/vt/vttime/time_clock_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/vttls/vttls.go b/go/vt/vttls/vttls.go index ebec9382da9..1b24192e797 100644 --- a/go/vt/vttls/vttls.go +++ b/go/vt/vttls/vttls.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/worker/block.go b/go/vt/worker/block.go index 9753e7c9f20..32b15717f56 100644 --- a/go/vt/worker/block.go +++ b/go/vt/worker/block.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/worker/block_cmd.go b/go/vt/worker/block_cmd.go index 9356fd9d728..2b8f24ebdb5 100644 --- a/go/vt/worker/block_cmd.go +++ b/go/vt/worker/block_cmd.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/worker/chunk.go b/go/vt/worker/chunk.go index 4b775b47018..89abd95383e 100644 --- a/go/vt/worker/chunk.go +++ b/go/vt/worker/chunk.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/worker/clone_utils.go b/go/vt/worker/clone_utils.go index 1107116222c..cbe431ed516 100644 --- a/go/vt/worker/clone_utils.go +++ b/go/vt/worker/clone_utils.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/worker/command.go b/go/vt/worker/command.go index 9b2c052cf79..d03f67a1713 100644 --- a/go/vt/worker/command.go +++ b/go/vt/worker/command.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/worker/defaults.go b/go/vt/worker/defaults.go index adf2ccf3546..4caedf93509 100644 --- a/go/vt/worker/defaults.go +++ b/go/vt/worker/defaults.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/worker/diff_utils.go b/go/vt/worker/diff_utils.go index 19d2dcbca3a..132fed84575 100644 --- a/go/vt/worker/diff_utils.go +++ b/go/vt/worker/diff_utils.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/worker/diff_utils_test.go b/go/vt/worker/diff_utils_test.go index cbc85298c03..6d43bd1ff49 100644 --- a/go/vt/worker/diff_utils_test.go +++ b/go/vt/worker/diff_utils_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/worker/events/split.go b/go/vt/worker/events/split.go index 6ba419f6e99..a96d6fe3ab1 100644 --- a/go/vt/worker/events/split.go +++ b/go/vt/worker/events/split.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/worker/events/split_syslog.go b/go/vt/worker/events/split_syslog.go index d3f7f9de988..5703bd62fca 100644 --- a/go/vt/worker/events/split_syslog.go +++ b/go/vt/worker/events/split_syslog.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/worker/events/split_syslog_test.go b/go/vt/worker/events/split_syslog_test.go index 8df2dd954aa..9e13c8ad19f 100644 --- a/go/vt/worker/events/split_syslog_test.go +++ b/go/vt/worker/events/split_syslog_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/worker/executor.go b/go/vt/worker/executor.go index 07ec11d132b..f0e14db21de 100644 --- a/go/vt/worker/executor.go +++ b/go/vt/worker/executor.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/worker/fakevtworkerclient/fakevtworkerclient.go b/go/vt/worker/fakevtworkerclient/fakevtworkerclient.go index b6133bb7f27..2ca2673e193 100644 --- a/go/vt/worker/fakevtworkerclient/fakevtworkerclient.go +++ b/go/vt/worker/fakevtworkerclient/fakevtworkerclient.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/worker/grpcvtworkerclient/client.go b/go/vt/worker/grpcvtworkerclient/client.go index db633e07a14..6f34dd8b69b 100644 --- a/go/vt/worker/grpcvtworkerclient/client.go +++ b/go/vt/worker/grpcvtworkerclient/client.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/worker/grpcvtworkerclient/client_test.go b/go/vt/worker/grpcvtworkerclient/client_test.go index 11d932cdbfa..27d37f778c8 100644 --- a/go/vt/worker/grpcvtworkerclient/client_test.go +++ b/go/vt/worker/grpcvtworkerclient/client_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/worker/grpcvtworkerserver/server.go b/go/vt/worker/grpcvtworkerserver/server.go index 29891f65bdc..9af3e3980f0 100644 --- a/go/vt/worker/grpcvtworkerserver/server.go +++ b/go/vt/worker/grpcvtworkerserver/server.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/worker/instance.go b/go/vt/worker/instance.go index 371ff734efc..e2fafd961ec 100644 --- a/go/vt/worker/instance.go +++ b/go/vt/worker/instance.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/worker/interactive.go b/go/vt/worker/interactive.go index dc4a7cba5ac..e7b322bc617 100644 --- a/go/vt/worker/interactive.go +++ b/go/vt/worker/interactive.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/worker/key_resolver.go b/go/vt/worker/key_resolver.go index 09d77c6dee7..bc53eafd1c3 100644 --- a/go/vt/worker/key_resolver.go +++ b/go/vt/worker/key_resolver.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/worker/legacy_row_splitter.go b/go/vt/worker/legacy_row_splitter.go index 5baa4f4efe5..4b0d9f0b5b0 100644 --- a/go/vt/worker/legacy_row_splitter.go +++ b/go/vt/worker/legacy_row_splitter.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/worker/legacy_row_splitter_test.go b/go/vt/worker/legacy_row_splitter_test.go index 3bf09a1ff71..54aac362134 100644 --- a/go/vt/worker/legacy_row_splitter_test.go +++ b/go/vt/worker/legacy_row_splitter_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/worker/legacy_split_clone.go b/go/vt/worker/legacy_split_clone.go index a191a1b79d3..dd9e568e47a 100644 --- a/go/vt/worker/legacy_split_clone.go +++ b/go/vt/worker/legacy_split_clone.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -400,7 +400,7 @@ func (scw *LegacySplitCloneWorker) findTargets(ctx context.Context) error { for _, si := range scw.destinationShards { waitCtx, waitCancel := context.WithTimeout(ctx, 10*time.Second) defer waitCancel() - if err := scw.tsc.WaitForTablets(waitCtx, scw.cell, si.Keyspace(), si.ShardName(), topodatapb.TabletType_MASTER); err != nil { + if err := scw.tsc.WaitForTablets(waitCtx, si.Keyspace(), si.ShardName(), topodatapb.TabletType_MASTER); err != nil { return vterrors.Wrapf(err, "cannot find MASTER tablet for destination shard for %v/%v", si.Keyspace(), si.ShardName()) } masters := scw.tsc.GetHealthyTabletStats(si.Keyspace(), si.ShardName(), topodatapb.TabletType_MASTER) diff --git a/go/vt/worker/legacy_split_clone_cmd.go b/go/vt/worker/legacy_split_clone_cmd.go index ab73cca3903..42caf35f2f4 100644 --- a/go/vt/worker/legacy_split_clone_cmd.go +++ b/go/vt/worker/legacy_split_clone_cmd.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/worker/legacy_split_clone_test.go b/go/vt/worker/legacy_split_clone_test.go index 65494ade261..9125bd8674b 100644 --- a/go/vt/worker/legacy_split_clone_test.go +++ b/go/vt/worker/legacy_split_clone_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -198,7 +198,7 @@ func (tc *legacySplitCloneTestCase) setUp(v3 bool) { tc.rightMasterFakeDb.AddExpectedQuery("INSERT INTO `vt_ks`.`table1` (`id`, `msg`, `keyspace_id`) VALUES (*", nil) } - // Fake stream health reponses because vtworker needs them to find the master. + // Fake stream health responses because vtworker needs them to find the master. tc.leftMasterQs = fakes.NewStreamHealthQueryService(leftMaster.Target()) tc.leftMasterQs.AddDefaultHealthResponse() tc.leftReplicaQs = fakes.NewStreamHealthQueryService(leftReplica.Target()) diff --git a/go/vt/worker/multi_split_diff.go b/go/vt/worker/multi_split_diff.go index 9a93ca1e192..3aeea35526e 100644 --- a/go/vt/worker/multi_split_diff.go +++ b/go/vt/worker/multi_split_diff.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/worker/multi_split_diff_cmd.go b/go/vt/worker/multi_split_diff_cmd.go index 5a6b880c545..8c77b0daf96 100644 --- a/go/vt/worker/multi_split_diff_cmd.go +++ b/go/vt/worker/multi_split_diff_cmd.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/worker/multi_split_diff_test.go b/go/vt/worker/multi_split_diff_test.go index 90316e22a05..0b9c0b85f96 100644 --- a/go/vt/worker/multi_split_diff_test.go +++ b/go/vt/worker/multi_split_diff_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/worker/panic.go b/go/vt/worker/panic.go index 8b6ee2f7f8e..f0a8b088cfe 100644 --- a/go/vt/worker/panic.go +++ b/go/vt/worker/panic.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/worker/panic_cmd.go b/go/vt/worker/panic_cmd.go index efe1f6a8b2d..8874ae34f8c 100644 --- a/go/vt/worker/panic_cmd.go +++ b/go/vt/worker/panic_cmd.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/worker/ping.go b/go/vt/worker/ping.go index 698227ffdc0..40ff8f66c41 100644 --- a/go/vt/worker/ping.go +++ b/go/vt/worker/ping.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/worker/ping_cmd.go b/go/vt/worker/ping_cmd.go index 784587a3f23..db191ef016c 100644 --- a/go/vt/worker/ping_cmd.go +++ b/go/vt/worker/ping_cmd.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/worker/restartable_result_reader.go b/go/vt/worker/restartable_result_reader.go index 04f95695fc6..a2ca2b03ed8 100644 --- a/go/vt/worker/restartable_result_reader.go +++ b/go/vt/worker/restartable_result_reader.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/worker/restartable_result_reader_test.go b/go/vt/worker/restartable_result_reader_test.go index 2e1d301f1ff..9129d7e1706 100644 --- a/go/vt/worker/restartable_result_reader_test.go +++ b/go/vt/worker/restartable_result_reader_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/worker/result_merger.go b/go/vt/worker/result_merger.go index 2f298594726..ebfc182ae43 100644 --- a/go/vt/worker/result_merger.go +++ b/go/vt/worker/result_merger.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/worker/result_merger_test.go b/go/vt/worker/result_merger_test.go index 4fe9dd19c66..9e91e9a64ad 100644 --- a/go/vt/worker/result_merger_test.go +++ b/go/vt/worker/result_merger_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/worker/result_reader.go b/go/vt/worker/result_reader.go index efc0fc1f7bb..2f6283b0902 100644 --- a/go/vt/worker/result_reader.go +++ b/go/vt/worker/result_reader.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/worker/row_aggregator.go b/go/vt/worker/row_aggregator.go index 8df872cd78a..9bba285ad09 100644 --- a/go/vt/worker/row_aggregator.go +++ b/go/vt/worker/row_aggregator.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/worker/row_differ.go b/go/vt/worker/row_differ.go index 4d575be8767..98e1c02997d 100644 --- a/go/vt/worker/row_differ.go +++ b/go/vt/worker/row_differ.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/worker/split_clone.go b/go/vt/worker/split_clone.go index 8b8cd2d00ef..ce042c7d351 100644 --- a/go/vt/worker/split_clone.go +++ b/go/vt/worker/split_clone.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -844,7 +844,7 @@ func (scw *SplitCloneWorker) findDestinationMasters(ctx context.Context) error { scw.wr.Logger().Infof("Finding a MASTER tablet for each destination shard...") for _, si := range scw.destinationShards { waitCtx, waitCancel := context.WithTimeout(ctx, *waitForHealthyTabletsTimeout) - err := scw.tsc.WaitForTablets(waitCtx, scw.cell, si.Keyspace(), si.ShardName(), topodatapb.TabletType_MASTER) + err := scw.tsc.WaitForTablets(waitCtx, si.Keyspace(), si.ShardName(), topodatapb.TabletType_MASTER) waitCancel() if err != nil { return vterrors.Wrapf(err, "cannot find MASTER tablet for destination shard for %v/%v (in cell: %v)", si.Keyspace(), si.ShardName(), scw.cell) diff --git a/go/vt/worker/split_clone_cmd.go b/go/vt/worker/split_clone_cmd.go index 4cf6b8795fb..34a3b70da65 100644 --- a/go/vt/worker/split_clone_cmd.go +++ b/go/vt/worker/split_clone_cmd.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/worker/split_clone_test.go b/go/vt/worker/split_clone_test.go index 88a83ae6e18..716741da36d 100644 --- a/go/vt/worker/split_clone_test.go +++ b/go/vt/worker/split_clone_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -252,7 +252,7 @@ func (tc *splitCloneTestCase) setUpWithConcurrency(v3 bool, concurrency, writeQu tc.rightMasterFakeDb.AddExpectedQuery("INSERT INTO `vt_ks`.`table1` (`id`, `msg`, `keyspace_id`) VALUES (*", nil) } - // Fake stream health reponses because vtworker needs them to find the master. + // Fake stream health responses because vtworker needs them to find the master. shqs := fakes.NewStreamHealthQueryService(leftMaster.Target()) shqs.AddDefaultHealthResponse() tc.leftMasterQs = newTestQueryService(tc.t, leftMaster.Target(), shqs, 0, 2, topoproto.TabletAliasString(leftMaster.Tablet.Alias), false /* omitKeyspaceID */) diff --git a/go/vt/worker/split_diff.go b/go/vt/worker/split_diff.go index 55b5c084f33..22e851b83fe 100644 --- a/go/vt/worker/split_diff.go +++ b/go/vt/worker/split_diff.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/worker/split_diff_cmd.go b/go/vt/worker/split_diff_cmd.go index 5ece6f5dce4..d018c4d7d31 100644 --- a/go/vt/worker/split_diff_cmd.go +++ b/go/vt/worker/split_diff_cmd.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/worker/split_diff_test.go b/go/vt/worker/split_diff_test.go index 5fb1ed37ca4..5c587fa0158 100644 --- a/go/vt/worker/split_diff_test.go +++ b/go/vt/worker/split_diff_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/worker/status.go b/go/vt/worker/status.go index f2ace057642..44164087115 100644 --- a/go/vt/worker/status.go +++ b/go/vt/worker/status.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/worker/status_worker.go b/go/vt/worker/status_worker.go index 81c7e61feec..8649e3d3985 100644 --- a/go/vt/worker/status_worker.go +++ b/go/vt/worker/status_worker.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/worker/table_status.go b/go/vt/worker/table_status.go index 026a1790109..2fb32800646 100644 --- a/go/vt/worker/table_status.go +++ b/go/vt/worker/table_status.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/worker/tablet_provider.go b/go/vt/worker/tablet_provider.go index 2d42bcb7fc6..2eaddf9e8b3 100644 --- a/go/vt/worker/tablet_provider.go +++ b/go/vt/worker/tablet_provider.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/worker/tablet_tracker.go b/go/vt/worker/tablet_tracker.go index c9f59433066..ba85e4ab092 100644 --- a/go/vt/worker/tablet_tracker.go +++ b/go/vt/worker/tablet_tracker.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/worker/tablet_tracker_test.go b/go/vt/worker/tablet_tracker_test.go index 6a5c2d89ae9..cf91138cbce 100644 --- a/go/vt/worker/tablet_tracker_test.go +++ b/go/vt/worker/tablet_tracker_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/worker/topo_utils.go b/go/vt/worker/topo_utils.go index 4dcc52a1daa..c83f90a2fa1 100644 --- a/go/vt/worker/topo_utils.go +++ b/go/vt/worker/topo_utils.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -77,7 +77,7 @@ func waitForHealthyTablets(ctx context.Context, wr *wrangler.Wrangler, tsc *disc cell, keyspace, shard, minHealthyRdonlyTablets, time.Until(deadlineForLog).Seconds()) // Wait for at least one RDONLY tablet initially before checking the list. - if err := tsc.WaitForTablets(busywaitCtx, cell, keyspace, shard, tabletType); err != nil { + if err := tsc.WaitForTablets(busywaitCtx, keyspace, shard, tabletType); err != nil { return nil, vterrors.Wrapf(err, "error waiting for %v tablets for (%v,%v/%v)", tabletType, cell, keyspace, shard) } diff --git a/go/vt/worker/utils_test.go b/go/vt/worker/utils_test.go index 98bdd416e7f..947ad45a287 100644 --- a/go/vt/worker/utils_test.go +++ b/go/vt/worker/utils_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/worker/vertical_split_clone_cmd.go b/go/vt/worker/vertical_split_clone_cmd.go index 7045fb3e620..8235ddadc5a 100644 --- a/go/vt/worker/vertical_split_clone_cmd.go +++ b/go/vt/worker/vertical_split_clone_cmd.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/worker/vertical_split_clone_test.go b/go/vt/worker/vertical_split_clone_test.go index 3656f405b1d..6dc5e98ba11 100644 --- a/go/vt/worker/vertical_split_clone_test.go +++ b/go/vt/worker/vertical_split_clone_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/worker/vertical_split_diff.go b/go/vt/worker/vertical_split_diff.go index fb5a8e3a06f..2a40574ed7a 100644 --- a/go/vt/worker/vertical_split_diff.go +++ b/go/vt/worker/vertical_split_diff.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/worker/vertical_split_diff_cmd.go b/go/vt/worker/vertical_split_diff_cmd.go index e4cfd4d34c4..47c208ffd05 100644 --- a/go/vt/worker/vertical_split_diff_cmd.go +++ b/go/vt/worker/vertical_split_diff_cmd.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/worker/vertical_split_diff_test.go b/go/vt/worker/vertical_split_diff_test.go index 826e965700e..ab286da6e97 100644 --- a/go/vt/worker/vertical_split_diff_test.go +++ b/go/vt/worker/vertical_split_diff_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/worker/vtworkerclient/interface.go b/go/vt/worker/vtworkerclient/interface.go index b35766b0540..f8efc20c71d 100644 --- a/go/vt/worker/vtworkerclient/interface.go +++ b/go/vt/worker/vtworkerclient/interface.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/worker/vtworkerclient/wrapper.go b/go/vt/worker/vtworkerclient/wrapper.go index 23633f3cf40..fc5cf09af8f 100644 --- a/go/vt/worker/vtworkerclient/wrapper.go +++ b/go/vt/worker/vtworkerclient/wrapper.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/worker/vtworkerclienttest/client_testsuite.go b/go/vt/worker/vtworkerclienttest/client_testsuite.go index b5ff551d5a9..67b856488f3 100644 --- a/go/vt/worker/vtworkerclienttest/client_testsuite.go +++ b/go/vt/worker/vtworkerclienttest/client_testsuite.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -129,10 +129,17 @@ func commandErrorsBecauseBusy(t *testing.T, client vtworkerclient.Client, server blockCommandStarted := make(chan struct{}) var errorCodeCheck error wg.Add(1) + errChan := make(chan error, 1) + defer close(errChan) go func() { + defer wg.Done() stream, err := client.ExecuteVtworkerCommand(ctx, []string{"Block"}) if err != nil { - t.Fatalf("Block command should not have failed: %v", err) + errChan <- err + close(blockCommandStarted) + return + } else { + errChan <- nil } firstLineReceived := false @@ -154,7 +161,6 @@ func commandErrorsBecauseBusy(t *testing.T, client vtworkerclient.Client, server close(blockCommandStarted) } } - wg.Done() }() // Try to run a second, concurrent vtworker command. @@ -177,6 +183,9 @@ func commandErrorsBecauseBusy(t *testing.T, client vtworkerclient.Client, server cancel() wg.Wait() + if err := <-errChan; err != nil { + t.Fatalf("Block command should not have failed: %v", err) + } if errorCodeCheck != nil { t.Fatalf("Block command did not return the CANCELED error code: %v", errorCodeCheck) } diff --git a/go/vt/worker/worker.go b/go/vt/worker/worker.go index aed603e4e10..bc78ba2a7d7 100644 --- a/go/vt/worker/worker.go +++ b/go/vt/worker/worker.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/workflow/checkpoint.go b/go/vt/workflow/checkpoint.go index ee888579f5a..107c95fd088 100644 --- a/go/vt/workflow/checkpoint.go +++ b/go/vt/workflow/checkpoint.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/workflow/long_polling.go b/go/vt/workflow/long_polling.go index ce5fca33e01..85463a71a7d 100644 --- a/go/vt/workflow/long_polling.go +++ b/go/vt/workflow/long_polling.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/workflow/long_polling_test.go b/go/vt/workflow/long_polling_test.go index eeeb6c3a388..691a7a145bd 100644 --- a/go/vt/workflow/long_polling_test.go +++ b/go/vt/workflow/long_polling_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/workflow/manager.go b/go/vt/workflow/manager.go index f3f94d39f81..2bb728e47dc 100644 --- a/go/vt/workflow/manager.go +++ b/go/vt/workflow/manager.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/workflow/manager_test.go b/go/vt/workflow/manager_test.go index 0620b882838..baf9dd836a8 100644 --- a/go/vt/workflow/manager_test.go +++ b/go/vt/workflow/manager_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/workflow/node.go b/go/vt/workflow/node.go index b1087bc3993..7043370aeef 100644 --- a/go/vt/workflow/node.go +++ b/go/vt/workflow/node.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/workflow/node_test.go b/go/vt/workflow/node_test.go index fec0b518b88..1fbe20fd25e 100644 --- a/go/vt/workflow/node_test.go +++ b/go/vt/workflow/node_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/workflow/parallel_runner.go b/go/vt/workflow/parallel_runner.go index d42ebc0d9e9..248ed34285f 100644 --- a/go/vt/workflow/parallel_runner.go +++ b/go/vt/workflow/parallel_runner.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/workflow/parallel_runner_test.go b/go/vt/workflow/parallel_runner_test.go index e796f0c3b08..b59218ca275 100644 --- a/go/vt/workflow/parallel_runner_test.go +++ b/go/vt/workflow/parallel_runner_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/workflow/resharding/resharding_wrangler.go b/go/vt/workflow/resharding/resharding_wrangler.go index c06405df2b9..db16ca24b18 100644 --- a/go/vt/workflow/resharding/resharding_wrangler.go +++ b/go/vt/workflow/resharding/resharding_wrangler.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/workflow/resharding/tasks.go b/go/vt/workflow/resharding/tasks.go index c5fc64aa357..244fcfe5801 100644 --- a/go/vt/workflow/resharding/tasks.go +++ b/go/vt/workflow/resharding/tasks.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 @@ -41,10 +41,17 @@ func createTaskID(phase workflow.PhaseType, shardName string) string { func (hw *horizontalReshardingWorkflow) GetTasks(phase workflow.PhaseType) []*workflowpb.Task { var shards []string switch phase { - case phaseCopySchema, phaseWaitForFilteredReplication, phaseDiff: + case phaseCopySchema, phaseWaitForFilteredReplication: shards = strings.Split(hw.checkpoint.Settings["destination_shards"], ",") case phaseClone, phaseMigrateRdonly, phaseMigrateReplica, phaseMigrateMaster: shards = strings.Split(hw.checkpoint.Settings["source_shards"], ",") + case phaseDiff: + switch hw.checkpoint.Settings["split_diff_cmd"] { + case "SplitDiff": + shards = strings.Split(hw.checkpoint.Settings["destination_shards"], ",") + case "MultiSplitDiff": + shards = strings.Split(hw.checkpoint.Settings["source_shards"], ",") + } default: log.Fatalf("BUG: unknown phase type: %v", phase) } @@ -61,7 +68,8 @@ func (hw *horizontalReshardingWorkflow) runCopySchema(ctx context.Context, t *wo keyspace := t.Attributes["keyspace"] sourceShard := t.Attributes["source_shard"] destShard := t.Attributes["destination_shard"] - return hw.wr.CopySchemaShardFromShard(ctx, nil /* tableArray*/, nil /* excludeTableArray */, true, /*includeViews*/ + excludeTables := strings.Split(t.Attributes["exclude_tables"], ",") + return hw.wr.CopySchemaShardFromShard(ctx, nil /* tableArray*/, excludeTables /* excludeTableArray */, true, /*includeViews*/ keyspace, sourceShard, keyspace, destShard, wrangler.DefaultWaitSlaveTimeout) } @@ -74,16 +82,24 @@ func (hw *horizontalReshardingWorkflow) runSplitClone(ctx context.Context, t *wo useConsistentSnapshot := t.Attributes["use_consistent_snapshot"] sourceKeyspaceShard := topoproto.KeyspaceShardString(keyspace, sourceShard) + excludeTables := t.Attributes["exclude_tables"] // Reset the vtworker to avoid error if vtworker command has been called elsewhere. // This is because vtworker class doesn't cleanup the environment after execution. if _, err := automation.ExecuteVtworker(ctx, worker, []string{"Reset"}); err != nil { return err } - args := []string{splitCmd, "--min_healthy_rdonly_tablets=" + minHealthyRdonlyTablets, sourceKeyspaceShard} + args := []string{splitCmd, "--min_healthy_rdonly_tablets=" + minHealthyRdonlyTablets} if useConsistentSnapshot != "" { args = append(args, "--use_consistent_snapshot") } + + if excludeTables != "" { + args = append(args, fmt.Sprintf("--exclude_tables=%s", excludeTables)) + } + + args = append(args, sourceKeyspaceShard) + _, err := automation.ExecuteVtworker(hw.ctx, worker, args) return err } @@ -96,18 +112,34 @@ func (hw *horizontalReshardingWorkflow) runWaitForFilteredReplication(ctx contex func (hw *horizontalReshardingWorkflow) runSplitDiff(ctx context.Context, t *workflowpb.Task) error { keyspace := t.Attributes["keyspace"] + splitDiffCmd := t.Attributes["split_diff_cmd"] destShard := t.Attributes["destination_shard"] + sourceShard := t.Attributes["source_shard"] destinationTabletType := t.Attributes["dest_tablet_type"] worker := t.Attributes["vtworker"] useConsistentSnapshot := t.Attributes["use_consistent_snapshot"] + excludeTables := t.Attributes["exclude_tables"] if _, err := automation.ExecuteVtworker(hw.ctx, worker, []string{"Reset"}); err != nil { return err } - args := []string{"SplitDiff", "--min_healthy_rdonly_tablets=1", "--dest_tablet_type=" + destinationTabletType, topoproto.KeyspaceShardString(keyspace, destShard)} + args := []string{splitDiffCmd} + if useConsistentSnapshot != "" { args = append(args, "--use_consistent_snapshot") } + + if excludeTables != "" { + args = append(args, fmt.Sprintf("--exclude_tables=%s", excludeTables)) + } + + switch splitDiffCmd { + case "SplitDiff": + args = append(args, "--min_healthy_rdonly_tablets=1", "--dest_tablet_type="+destinationTabletType, topoproto.KeyspaceShardString(keyspace, destShard)) + case "MultiSplitDiff": + args = append(args, "--min_healthy_tablets=1", "--tablet_type="+destinationTabletType, topoproto.KeyspaceShardString(keyspace, sourceShard)) + } + _, err := automation.ExecuteVtworker(ctx, worker, args) return err } diff --git a/go/vt/workflow/resharding/workflow.go b/go/vt/workflow/resharding/workflow.go index dedd4f7989b..c1c94a683dd 100644 --- a/go/vt/workflow/resharding/workflow.go +++ b/go/vt/workflow/resharding/workflow.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 @@ -68,10 +68,13 @@ func (*Factory) Init(m *workflow.Manager, w *workflowpb.Workflow, args []string) subFlags := flag.NewFlagSet(horizontalReshardingFactoryName, flag.ContinueOnError) keyspace := subFlags.String("keyspace", "", "Name of keyspace to perform horizontal resharding") vtworkersStr := subFlags.String("vtworkers", "", "A comma-separated list of vtworker addresses") + excludeTablesStr := subFlags.String("exclude_tables", "", "A comma-separated list of tables to exclude") sourceShardsStr := subFlags.String("source_shards", "", "A comma-separated list of source shards") destinationShardsStr := subFlags.String("destination_shards", "", "A comma-separated list of destination shards") minHealthyRdonlyTablets := subFlags.String("min_healthy_rdonly_tablets", "1", "Minimum number of healthy RDONLY tablets required in source shards") + skipSplitRatioCheck := subFlags.Bool("skip_split_ratio_check", false, "Skip validation on minimum number of healthy RDONLY tablets") splitCmd := subFlags.String("split_cmd", "SplitClone", "Split command to use to perform horizontal resharding (either SplitClone or LegacySplitClone)") + splitDiffCmd := subFlags.String("split_diff_cmd", "SplitDiff", "Split diff command to use to perform horizontal resharding (either SplitDiff or MultiSplitDiff)") splitDiffDestTabletType := subFlags.String("split_diff_dest_tablet_type", "RDONLY", "Specifies tablet type to use in destination shards while performing SplitDiff operation") phaseEnaableApprovalsDesc := fmt.Sprintf("Comma separated phases that require explicit approval in the UI to execute. Phase names are: %v", strings.Join(WorkflowPhases(), ",")) phaseEnableApprovalsStr := subFlags.String("phase_enable_approvals", strings.Join(WorkflowPhases(), ","), phaseEnaableApprovalsDesc) @@ -80,11 +83,12 @@ func (*Factory) Init(m *workflow.Manager, w *workflowpb.Workflow, args []string) if err := subFlags.Parse(args); err != nil { return err } - if *keyspace == "" || *vtworkersStr == "" || *minHealthyRdonlyTablets == "" || *splitCmd == "" { + if *keyspace == "" || *vtworkersStr == "" || *minHealthyRdonlyTablets == "" || *splitCmd == "" || *splitDiffCmd == "" { return fmt.Errorf("keyspace name, min healthy rdonly tablets, split command, and vtworkers information must be provided for horizontal resharding") } vtworkers := strings.Split(*vtworkersStr, ",") + excludeTables := strings.Split(*excludeTablesStr, ",") sourceShards := strings.Split(*sourceShardsStr, ",") destinationShards := strings.Split(*destinationShardsStr, ",") phaseEnableApprovals := parsePhaseEnableApprovals(*phaseEnableApprovalsStr) @@ -104,13 +108,13 @@ func (*Factory) Init(m *workflow.Manager, w *workflowpb.Workflow, args []string) useConsistentSnapshotArg = "true" } - err := validateWorkflow(m, *keyspace, vtworkers, sourceShards, destinationShards, *minHealthyRdonlyTablets) + err := validateWorkflow(m, *keyspace, vtworkers, sourceShards, destinationShards, *minHealthyRdonlyTablets, *skipSplitRatioCheck) if err != nil { return err } w.Name = fmt.Sprintf("Reshard shards %v into shards %v of keyspace %v.", *keyspace, *sourceShardsStr, *destinationShardsStr) - checkpoint, err := initCheckpoint(*keyspace, vtworkers, sourceShards, destinationShards, *minHealthyRdonlyTablets, *splitCmd, *splitDiffDestTabletType, useConsistentSnapshotArg) + checkpoint, err := initCheckpoint(*keyspace, vtworkers, excludeTables, sourceShards, destinationShards, *minHealthyRdonlyTablets, *splitCmd, *splitDiffCmd, *splitDiffDestTabletType, useConsistentSnapshotArg) if err != nil { return err } @@ -159,10 +163,12 @@ func (*Factory) Instantiate(m *workflow.Manager, w *workflowpb.Workflow, rootNod Name: "WaitForFilteredReplication", PathName: string(phaseWaitForFilteredReplication), } + diffUINode := &workflow.Node{ - Name: "SplitDiff", + Name: checkpoint.Settings["split_diff_cmd"], PathName: string(phaseDiff), } + migrateRdonlyUINode := &workflow.Node{ Name: "MigrateServedTypeRDONLY", PathName: string(phaseMigrateRdonly), @@ -198,9 +204,19 @@ func (*Factory) Instantiate(m *workflow.Manager, w *workflowpb.Workflow, rootNod if err := createUINodes(hw.rootUINode, phaseWaitForFilteredReplication, destinationShards); err != nil { return hw, err } - if err := createUINodes(hw.rootUINode, phaseDiff, destinationShards); err != nil { + var shardsToUseForDiff []string + + switch hw.checkpoint.Settings["split_diff_cmd"] { + case "SplitDiff": + shardsToUseForDiff = destinationShards + case "MultiSplitDiff": + shardsToUseForDiff = sourceShards + } + + if err := createUINodes(hw.rootUINode, phaseDiff, shardsToUseForDiff); err != nil { return hw, err } + if err := createUINodes(hw.rootUINode, phaseMigrateRdonly, sourceShards); err != nil { return hw, err } @@ -231,7 +247,7 @@ func createUINodes(rootNode *workflow.Node, phaseName workflow.PhaseType, shards } // validateWorkflow validates that workflow has valid input parameters. -func validateWorkflow(m *workflow.Manager, keyspace string, vtworkers, sourceShards, destinationShards []string, minHealthyRdonlyTablets string) error { +func validateWorkflow(m *workflow.Manager, keyspace string, vtworkers, sourceShards, destinationShards []string, minHealthyRdonlyTablets string, skipSplitRatioCheck bool) error { if len(sourceShards) == 0 || len(destinationShards) == 0 { return fmt.Errorf("invalid source or destination shards") } @@ -240,7 +256,7 @@ func validateWorkflow(m *workflow.Manager, keyspace string, vtworkers, sourceSha } splitRatio := len(destinationShards) / len(sourceShards) - if minHealthyRdonlyTabletsVal, err := strconv.Atoi(minHealthyRdonlyTablets); err != nil || minHealthyRdonlyTabletsVal < splitRatio { + if minHealthyRdonlyTabletsVal, err := strconv.Atoi(minHealthyRdonlyTablets); err != nil || (!skipSplitRatioCheck && minHealthyRdonlyTabletsVal < splitRatio) { return fmt.Errorf("there are not enough rdonly tablets in source shards. You need at least %v, it got: %v", splitRatio, minHealthyRdonlyTablets) } @@ -269,13 +285,14 @@ func validateWorkflow(m *workflow.Manager, keyspace string, vtworkers, sourceSha } // initCheckpoint initialize the checkpoint for the horizontal workflow. -func initCheckpoint(keyspace string, vtworkers, sourceShards, destinationShards []string, minHealthyRdonlyTablets, splitCmd, splitDiffDestTabletType string, useConsistentSnapshot string) (*workflowpb.WorkflowCheckpoint, error) { +func initCheckpoint(keyspace string, vtworkers, excludeTables, sourceShards, destinationShards []string, minHealthyRdonlyTablets, splitCmd, splitDiffCmd, splitDiffDestTabletType string, useConsistentSnapshot string) (*workflowpb.WorkflowCheckpoint, error) { tasks := make(map[string]*workflowpb.Task) initTasks(tasks, phaseCopySchema, destinationShards, func(i int, shard string) map[string]string { return map[string]string{ "keyspace": keyspace, "source_shard": sourceShards[0], "destination_shard": shard, + "exclude_tables": strings.Join(excludeTables, ","), } }) initTasks(tasks, phaseClone, sourceShards, func(i int, shard string) map[string]string { @@ -286,6 +303,7 @@ func initCheckpoint(keyspace string, vtworkers, sourceShards, destinationShards "split_cmd": splitCmd, "vtworker": vtworkers[i], "use_consistent_snapshot": useConsistentSnapshot, + "exclude_tables": strings.Join(excludeTables, ","), } }) initTasks(tasks, phaseWaitForFilteredReplication, destinationShards, func(i int, shard string) map[string]string { @@ -294,15 +312,34 @@ func initCheckpoint(keyspace string, vtworkers, sourceShards, destinationShards "destination_shard": shard, } }) - initTasks(tasks, phaseDiff, destinationShards, func(i int, shard string) map[string]string { - return map[string]string{ - "keyspace": keyspace, - "destination_shard": shard, - "dest_tablet_type": splitDiffDestTabletType, - "vtworker": vtworkers[i], - "use_consistent_snapshot": useConsistentSnapshot, - } - }) + + switch splitDiffCmd { + case "SplitDiff": + initTasks(tasks, phaseDiff, destinationShards, func(i int, shard string) map[string]string { + return map[string]string{ + "keyspace": keyspace, + "destination_shard": shard, + "dest_tablet_type": splitDiffDestTabletType, + "split_diff_cmd": splitDiffCmd, + "vtworker": vtworkers[i], + "use_consistent_snapshot": useConsistentSnapshot, + "exclude_tables": strings.Join(excludeTables, ","), + } + }) + case "MultiSplitDiff": + initTasks(tasks, phaseDiff, sourceShards, func(i int, shard string) map[string]string { + return map[string]string{ + "keyspace": keyspace, + "source_shard": shard, + "dest_tablet_type": splitDiffDestTabletType, + "split_diff_cmd": splitDiffCmd, + "vtworker": vtworkers[i], + "use_consistent_snapshot": useConsistentSnapshot, + "exclude_tables": strings.Join(excludeTables, ","), + } + }) + } + initTasks(tasks, phaseMigrateRdonly, sourceShards, func(i int, shard string) map[string]string { return map[string]string{ "keyspace": keyspace, @@ -331,6 +368,7 @@ func initCheckpoint(keyspace string, vtworkers, sourceShards, destinationShards Settings: map[string]string{ "source_shards": strings.Join(sourceShards, ","), "destination_shards": strings.Join(destinationShards, ","), + "split_diff_cmd": splitDiffCmd, }, }, nil } diff --git a/go/vt/workflow/resharding/workflow_test.go b/go/vt/workflow/resharding/workflow_test.go index bc3d7478240..5224804db09 100644 --- a/go/vt/workflow/resharding/workflow_test.go +++ b/go/vt/workflow/resharding/workflow_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 @@ -55,7 +55,7 @@ func TestSourceDestShards(t *testing.T) { defer ctrl.Finish() // Set up the fakeworkerclient. It is used at SplitClone and SplitDiff phase. - fakeVtworkerClient := setupFakeVtworker(testKeyspace, testVtworkers, false) + fakeVtworkerClient := setupFakeVtworker(testKeyspace, testVtworkers, false, "", "SplitDiff") vtworkerclient.RegisterFactory("fake", fakeVtworkerClient.FakeVtworkerClientFactory) defer vtworkerclient.UnregisterFactoryForTest("fake") @@ -90,15 +90,24 @@ func TestSourceDestShards(t *testing.T) { // TestHorizontalResharding runs the happy path of HorizontalReshardingWorkflow. func TestHorizontalResharding(t *testing.T) { - testHorizontalReshardingWorkflow(t, false) + testHorizontalReshardingWorkflow(t, false, "", "SplitDiff") } // TestHorizontalReshardingWithConsistentSnapshot runs the happy path of HorizontalReshardingWorkflow with consistent snapshot. func TestHorizontalReshardingWithConsistentSnapshot(t *testing.T) { - testHorizontalReshardingWorkflow(t, true) + testHorizontalReshardingWorkflow(t, true, "", "SplitDiff") } -func testHorizontalReshardingWorkflow(t *testing.T, useConsistentSnapshot bool) { +// TestHorizontalReshardingWithExcludedTables runs the happy path of HorizontalReshardingWorkflow with excluded tables. +func TestHorizontalReshardingWithExcludedTables(t *testing.T) { + testHorizontalReshardingWorkflow(t, true, "table_a,table_b", "SplitDiff") +} + +func TestHorizontalReshardingWithMultiDiffCommand(t *testing.T) { + testHorizontalReshardingWorkflow(t, true, "table_a,table_b", "MultiSplitDiff") +} + +func testHorizontalReshardingWorkflow(t *testing.T, useConsistentSnapshot bool, excludeTables, splitDiffCommand string) { ctx := context.Background() // Set up the mock wrangler. It is used for the CopySchema, // WaitforFilteredReplication and Migrate phase. @@ -106,7 +115,7 @@ func testHorizontalReshardingWorkflow(t *testing.T, useConsistentSnapshot bool) defer ctrl.Finish() mockWranglerInterface := setupMockWrangler(ctrl, testKeyspace) // Set up the fakeworkerclient. It is used at SplitClone and SplitDiff phase. - fakeVtworkerClient := setupFakeVtworker(testKeyspace, testVtworkers, useConsistentSnapshot) + fakeVtworkerClient := setupFakeVtworker(testKeyspace, testVtworkers, useConsistentSnapshot, excludeTables, splitDiffCommand) vtworkerclient.RegisterFactory("fake", fakeVtworkerClient.FakeVtworkerClientFactory) defer vtworkerclient.UnregisterFactoryForTest("fake") // Initialize the topology. @@ -116,10 +125,14 @@ func testHorizontalReshardingWorkflow(t *testing.T, useConsistentSnapshot bool) wg, _, cancel := workflow.StartManager(m) // Create the workflow. vtworkersParameter := testVtworkers + "," + testVtworkers - args := []string{"-keyspace=" + testKeyspace, "-vtworkers=" + vtworkersParameter, "-phase_enable_approvals=", "-min_healthy_rdonly_tablets=2", "-source_shards=0", "-destination_shards=-80,80-"} + args := []string{"-keyspace=" + testKeyspace, "-vtworkers=" + vtworkersParameter, "-phase_enable_approvals=", "-min_healthy_rdonly_tablets=2"} if useConsistentSnapshot { args = append(args, "-use_consistent_snapshot") } + if excludeTables != "" { + args = append(args, "-exclude_tables="+excludeTables) + } + args = append(args, "-source_shards=0", "-destination_shards=-80,80-", "-split_diff_cmd="+splitDiffCommand) uuid, err := m.Create(ctx, horizontalReshardingFactoryName, args) if err != nil { t.Fatalf("cannot create resharding workflow: %v", err) @@ -148,15 +161,22 @@ func testHorizontalReshardingWorkflow(t *testing.T, useConsistentSnapshot bool) wg.Wait() } -func setupFakeVtworker(keyspace, vtworkers string, useConsistentSnapshot bool) *fakevtworkerclient.FakeVtworkerClient { +func setupFakeVtworker(keyspace, vtworkers string, useConsistentSnapshot bool, excludeTables, splitDiffCmd string) *fakevtworkerclient.FakeVtworkerClient { flag.Set("vtworker_client_protocol", "fake") fakeVtworkerClient := fakevtworkerclient.NewFakeVtworkerClient() fakeVtworkerClient.RegisterResultForAddr(vtworkers, resetCommand(), "", nil) - fakeVtworkerClient.RegisterResultForAddr(vtworkers, splitCloneCommand(keyspace, useConsistentSnapshot), "", nil) + fakeVtworkerClient.RegisterResultForAddr(vtworkers, splitCloneCommand(keyspace, useConsistentSnapshot, excludeTables), "", nil) fakeVtworkerClient.RegisterResultForAddr(vtworkers, resetCommand(), "", nil) - fakeVtworkerClient.RegisterResultForAddr(vtworkers, splitDiffCommand(keyspace, "-80", useConsistentSnapshot), "", nil) fakeVtworkerClient.RegisterResultForAddr(vtworkers, resetCommand(), "", nil) - fakeVtworkerClient.RegisterResultForAddr(vtworkers, splitDiffCommand(keyspace, "80-", useConsistentSnapshot), "", nil) + + switch splitDiffCmd { + case "SplitDiff": + fakeVtworkerClient.RegisterResultForAddr(vtworkers, splitDiffCommand(keyspace, "-80", useConsistentSnapshot, excludeTables, splitDiffCmd), "", nil) + fakeVtworkerClient.RegisterResultForAddr(vtworkers, splitDiffCommand(keyspace, "80-", useConsistentSnapshot, excludeTables, splitDiffCmd), "", nil) + case "MultiSplitDiff": + fakeVtworkerClient.RegisterResultForAddr(vtworkers, splitDiffCommand(keyspace, "0", useConsistentSnapshot, excludeTables, splitDiffCmd), "", nil) + fakeVtworkerClient.RegisterResultForAddr(vtworkers, splitDiffCommand(keyspace, "0", useConsistentSnapshot, excludeTables, splitDiffCmd), "", nil) + } return fakeVtworkerClient } @@ -164,27 +184,43 @@ func resetCommand() []string { return []string{"Reset"} } -func splitCloneCommand(keyspace string, useConsistentSnapshot bool) []string { - args := []string{"SplitClone", "--min_healthy_rdonly_tablets=2", keyspace + "/0"} +func splitCloneCommand(keyspace string, useConsistentSnapshot bool, excludeTables string) []string { + args := []string{"SplitClone", "--min_healthy_rdonly_tablets=2"} if useConsistentSnapshot { args = append(args, "--use_consistent_snapshot") } + if excludeTables != "" { + args = append(args, "--exclude_tables="+excludeTables) + } + + args = append(args, keyspace+"/0") return args } -func splitDiffCommand(keyspace string, shardId string, useConsistentSnapshot bool) []string { - args := []string{"SplitDiff", "--min_healthy_rdonly_tablets=1", "--dest_tablet_type=RDONLY", keyspace + "/" + shardId} +func splitDiffCommand(keyspace string, shardId string, useConsistentSnapshot bool, excludeTables, splitDiffCommand string) []string { + args := []string{splitDiffCommand} if useConsistentSnapshot { args = append(args, "--use_consistent_snapshot") } + if excludeTables != "" { + args = append(args, "--exclude_tables="+excludeTables) + } + + switch splitDiffCommand { + case "SplitDiff": + args = append(args, "--min_healthy_rdonly_tablets=1", "--dest_tablet_type=RDONLY", keyspace+"/"+shardId) + case "MultiSplitDiff": + args = append(args, "--min_healthy_tablets=1", "--tablet_type=RDONLY", keyspace+"/"+shardId) + } + return args } func setupMockWrangler(ctrl *gomock.Controller, keyspace string) *MockReshardingWrangler { mockWranglerInterface := NewMockReshardingWrangler(ctrl) // Set the expected behaviors for mock wrangler. - mockWranglerInterface.EXPECT().CopySchemaShardFromShard(gomock.Any(), nil /* tableArray*/, nil /* excludeTableArray */, true /*includeViews*/, keyspace, "0", keyspace, "-80", wrangler.DefaultWaitSlaveTimeout).Return(nil) - mockWranglerInterface.EXPECT().CopySchemaShardFromShard(gomock.Any(), nil /* tableArray*/, nil /* excludeTableArray */, true /*includeViews*/, keyspace, "0", keyspace, "80-", wrangler.DefaultWaitSlaveTimeout).Return(nil) + mockWranglerInterface.EXPECT().CopySchemaShardFromShard(gomock.Any(), nil /* tableArray*/, gomock.Any() /* excludeTableArray */, true /*includeViews*/, keyspace, "0", keyspace, "-80", wrangler.DefaultWaitSlaveTimeout).Return(nil) + mockWranglerInterface.EXPECT().CopySchemaShardFromShard(gomock.Any(), nil /* tableArray*/, gomock.Any() /* excludeTableArray */, true /*includeViews*/, keyspace, "0", keyspace, "80-", wrangler.DefaultWaitSlaveTimeout).Return(nil) mockWranglerInterface.EXPECT().WaitForFilteredReplication(gomock.Any(), keyspace, "-80", wrangler.DefaultWaitForFilteredReplicationMaxDelay).Return(nil) mockWranglerInterface.EXPECT().WaitForFilteredReplication(gomock.Any(), keyspace, "80-", wrangler.DefaultWaitForFilteredReplicationMaxDelay).Return(nil) diff --git a/go/vt/workflow/reshardingworkflowgen/workflow.go b/go/vt/workflow/reshardingworkflowgen/workflow.go index 00e6c9949d0..cec2cc6842f 100644 --- a/go/vt/workflow/reshardingworkflowgen/workflow.go +++ b/go/vt/workflow/reshardingworkflowgen/workflow.go @@ -1,10 +1,13 @@ /* -Copyright 2018 The Vitess Authors - Licensed under the Apache License, Version 2.0 (the "License"); +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 agreedto in writing, software + +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 @@ -58,21 +61,26 @@ func (*Factory) Init(m *workflow.Manager, w *workflowpb.Workflow, args []string) subFlags := flag.NewFlagSet(keyspaceReshardingFactoryName, flag.ContinueOnError) keyspace := subFlags.String("keyspace", "", "Name of keyspace to perform horizontal resharding") vtworkersStr := subFlags.String("vtworkers", "", "A comma-separated list of vtworker addresses") + excludeTablesStr := subFlags.String("exclude_tables", "", "A comma-separated list of tables to exclude") minHealthyRdonlyTablets := subFlags.String("min_healthy_rdonly_tablets", "1", "Minimum number of healthy RDONLY tablets required in source shards") + skipSplitRatioCheck := subFlags.Bool("skip_split_ratio_check", false, "Skip validation on minimum number of healthy RDONLY tablets") splitCmd := subFlags.String("split_cmd", "SplitClone", "Split command to use to perform horizontal resharding (either SplitClone or LegacySplitClone)") + splitDiffCmd := subFlags.String("split_diff_cmd", "SplitDiff", "Split diff command to use to perform horizontal resharding (either SplitDiff or MultiSplitDiff)") splitDiffDestTabletType := subFlags.String("split_diff_dest_tablet_type", "RDONLY", "Specifies tablet type to use in destination shards while performing SplitDiff operation") skipStartWorkflows := subFlags.Bool("skip_start_workflows", true, "If true, newly created workflows will have skip_start set") phaseEnableApprovalsDesc := fmt.Sprintf("Comma separated phases that require explicit approval in the UI to execute. Phase names are: %v", strings.Join(resharding.WorkflowPhases(), ",")) phaseEnableApprovalsStr := subFlags.String("phase_enable_approvals", strings.Join(resharding.WorkflowPhases(), ","), phaseEnableApprovalsDesc) + useConsistentSnapshot := subFlags.Bool("use_consistent_snapshot", false, "Instead of pausing replication on the source, uses transactions with consistent snapshot to have a stable view of the data.") if err := subFlags.Parse(args); err != nil { return err } - if *keyspace == "" || *vtworkersStr == "" || *minHealthyRdonlyTablets == "" || *splitCmd == "" { + if *keyspace == "" || *vtworkersStr == "" || *minHealthyRdonlyTablets == "" || *splitCmd == "" || *splitDiffCmd == "" { return fmt.Errorf("keyspace name, min healthy rdonly tablets, split command, and vtworkers information must be provided for horizontal resharding") } vtworkers := strings.Split(*vtworkersStr, ",") + excludeTables := strings.Split(*excludeTablesStr, ",") w.Name = fmt.Sprintf("Keyspace reshard on %s", *keyspace) shardsToSplit, err := findSourceAndDestinationShards(m.TopoServer(), *keyspace) @@ -83,12 +91,16 @@ func (*Factory) Init(m *workflow.Manager, w *workflowpb.Workflow, args []string) checkpoint, err := initCheckpoint( *keyspace, vtworkers, + excludeTables, shardsToSplit, *minHealthyRdonlyTablets, *splitCmd, + *splitDiffCmd, *splitDiffDestTabletType, *phaseEnableApprovalsStr, *skipStartWorkflows, + *useConsistentSnapshot, + *skipSplitRatioCheck, ) if err != nil { return err @@ -127,6 +139,10 @@ func (*Factory) Instantiate(m *workflow.Manager, w *workflowpb.Workflow, rootNod keyspaceParam: checkpoint.Settings["keyspace"], splitDiffDestTabletTypeParam: checkpoint.Settings["split_diff_dest_tablet_type"], splitCmdParam: checkpoint.Settings["split_cmd"], + splitDiffCmdParam: checkpoint.Settings["split_diff_cmd"], + useConsistentSnapshot: checkpoint.Settings["use_consistent_snapshot"], + excludeTablesParam: checkpoint.Settings["exclude_tables"], + skipSplitRatioCheckParam: checkpoint.Settings["skip_split_ratio_check"], workflowsCount: workflowsCount, } createWorkflowsUINode := &workflow.Node{ @@ -188,7 +204,7 @@ func findSourceAndDestinationShards(ts *topo.Server, keyspace string) ([][][]str } // initCheckpoint initialize the checkpoint for keyspace reshard -func initCheckpoint(keyspace string, vtworkers []string, shardsToSplit [][][]string, minHealthyRdonlyTablets, splitCmd, splitDiffDestTabletType, phaseEnableApprovals string, skipStartWorkflows bool) (*workflowpb.WorkflowCheckpoint, error) { +func initCheckpoint(keyspace string, vtworkers, excludeTables []string, shardsToSplit [][][]string, minHealthyRdonlyTablets, splitCmd, splitDiffCmd, splitDiffDestTabletType, phaseEnableApprovals string, skipStartWorkflows, useConsistentSnapshot, skipSplitRatioCheck bool) (*workflowpb.WorkflowCheckpoint, error) { sourceShards := 0 destShards := 0 for _, shardToSplit := range shardsToSplit { @@ -203,7 +219,7 @@ func initCheckpoint(keyspace string, vtworkers []string, shardsToSplit [][][]str } splitRatio := destShards / sourceShards - if minHealthyRdonlyTabletsVal, err := strconv.Atoi(minHealthyRdonlyTablets); err != nil || minHealthyRdonlyTabletsVal < splitRatio { + if minHealthyRdonlyTabletsVal, err := strconv.Atoi(minHealthyRdonlyTablets); err != nil || (!skipSplitRatioCheck && minHealthyRdonlyTabletsVal < splitRatio) { return nil, fmt.Errorf("there are not enough rdonly tablets in source shards. You need at least %v, it got: %v", splitRatio, minHealthyRdonlyTablets) } @@ -229,11 +245,15 @@ func initCheckpoint(keyspace string, vtworkers []string, shardsToSplit [][][]str "vtworkers": strings.Join(vtworkers, ","), "min_healthy_rdonly_tablets": minHealthyRdonlyTablets, "split_cmd": splitCmd, + "split_diff_cmd": splitDiffCmd, "split_diff_dest_tablet_type": splitDiffDestTabletType, "phase_enable_approvals": phaseEnableApprovals, "skip_start_workflows": fmt.Sprintf("%v", skipStartWorkflows), "workflows_count": fmt.Sprintf("%v", len(shardsToSplit)), "keyspace": keyspace, + "use_consistent_snapshot": fmt.Sprintf("%v", useConsistentSnapshot), + "exclude_tables": strings.Join(excludeTables, ","), + "skip_split_ratio_check": fmt.Sprintf("%v", skipSplitRatioCheck), }, }, nil } @@ -262,7 +282,11 @@ type reshardingWorkflowGen struct { keyspaceParam string splitDiffDestTabletTypeParam string splitCmdParam string + splitDiffCmdParam string skipStartWorkflowParam string + useConsistentSnapshot string + excludeTablesParam string + skipSplitRatioCheckParam string } // Run implements workflow.Workflow interface. It creates one horizontal resharding workflow per shard to split @@ -296,12 +320,16 @@ func (hw *reshardingWorkflowGen) workflowCreator(ctx context.Context, task *work horizontalReshardingParams := []string{ "-keyspace=" + hw.keyspaceParam, "-vtworkers=" + task.Attributes["vtworkers"], + "-exclude_tables=" + hw.excludeTablesParam, + "-skip_split_ratio_check=" + hw.skipSplitRatioCheckParam, "-split_cmd=" + hw.splitCmdParam, + "-split_diff_cmd=" + hw.splitDiffCmdParam, "-split_diff_dest_tablet_type=" + hw.splitDiffDestTabletTypeParam, "-min_healthy_rdonly_tablets=" + hw.minHealthyRdonlyTabletsParam, "-source_shards=" + task.Attributes["source_shards"], "-destination_shards=" + task.Attributes["destination_shards"], "-phase_enable_approvals=" + hw.phaseEnableApprovalsParam, + "-use_consistent_snapshot=" + hw.useConsistentSnapshot, } skipStart, err := strconv.ParseBool(hw.skipStartWorkflowParam) diff --git a/go/vt/workflow/reshardingworkflowgen/workflow_flaky_test.go b/go/vt/workflow/reshardingworkflowgen/workflow_flaky_test.go index 2291d28afb5..e65220d22aa 100644 --- a/go/vt/workflow/reshardingworkflowgen/workflow_flaky_test.go +++ b/go/vt/workflow/reshardingworkflowgen/workflow_flaky_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 @@ -53,7 +53,7 @@ func TestWorfklowGenerator(t *testing.T) { workflow.StartManager(m) // Create the workflow. vtworkersParameter := testVtworkers + "," + testVtworkers - uuid, err := m.Create(ctx, keyspaceReshardingFactoryName, []string{"-keyspace=" + testKeyspace, "-vtworkers=" + vtworkersParameter, "-min_healthy_rdonly_tablets=2"}) + uuid, err := m.Create(ctx, keyspaceReshardingFactoryName, []string{"-keyspace=" + testKeyspace, "-vtworkers=" + vtworkersParameter, "-min_healthy_rdonly_tablets=2", "-use_consistent_snapshot=true", "-exclude_tables=table_a,table_b"}) if err != nil { t.Fatalf("cannot create resharding workflow: %v", err) } diff --git a/go/vt/workflow/sleep_workflow.go b/go/vt/workflow/sleep_workflow.go index b4b4f9f56ac..9d7c462af55 100644 --- a/go/vt/workflow/sleep_workflow.go +++ b/go/vt/workflow/sleep_workflow.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/workflow/topovalidator/keyspace.go b/go/vt/workflow/topovalidator/keyspace.go index 6fa92429d4a..343d9247a75 100644 --- a/go/vt/workflow/topovalidator/keyspace.go +++ b/go/vt/workflow/topovalidator/keyspace.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/workflow/topovalidator/keyspace_test.go b/go/vt/workflow/topovalidator/keyspace_test.go index a2b062ff90f..d1b809e0eef 100644 --- a/go/vt/workflow/topovalidator/keyspace_test.go +++ b/go/vt/workflow/topovalidator/keyspace_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/workflow/topovalidator/shard.go b/go/vt/workflow/topovalidator/shard.go index c277c755ea7..07bd918d309 100644 --- a/go/vt/workflow/topovalidator/shard.go +++ b/go/vt/workflow/topovalidator/shard.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/workflow/topovalidator/shard_test.go b/go/vt/workflow/topovalidator/shard_test.go index d30583c5282..2a9909a7786 100644 --- a/go/vt/workflow/topovalidator/shard_test.go +++ b/go/vt/workflow/topovalidator/shard_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/workflow/topovalidator/ui.go b/go/vt/workflow/topovalidator/ui.go index 38a5158df2f..ae69a2c5197 100644 --- a/go/vt/workflow/topovalidator/ui.go +++ b/go/vt/workflow/topovalidator/ui.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/workflow/topovalidator/validator.go b/go/vt/workflow/topovalidator/validator.go index 1564e539282..35ab61c8db7 100644 --- a/go/vt/workflow/topovalidator/validator.go +++ b/go/vt/workflow/topovalidator/validator.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/workflow/websocket.go b/go/vt/workflow/websocket.go index 49ab4c9d4cf..de110b1bcaf 100644 --- a/go/vt/workflow/websocket.go +++ b/go/vt/workflow/websocket.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/workflow/websocket_test.go b/go/vt/workflow/websocket_test.go index ca13e5cfd27..573b94afaee 100644 --- a/go/vt/workflow/websocket_test.go +++ b/go/vt/workflow/websocket_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/workflow/workflow_test.go b/go/vt/workflow/workflow_test.go index 9b3e3c2b8c2..1d362302c3c 100644 --- a/go/vt/workflow/workflow_test.go +++ b/go/vt/workflow/workflow_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/wrangler/cleaner.go b/go/vt/wrangler/cleaner.go index e40b9c08d35..7a0fd4c7d4a 100644 --- a/go/vt/wrangler/cleaner.go +++ b/go/vt/wrangler/cleaner.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/wrangler/fake_dbclient_test.go b/go/vt/wrangler/fake_dbclient_test.go index 1f2ca1f54a7..6c05ff5015e 100644 --- a/go/vt/wrangler/fake_dbclient_test.go +++ b/go/vt/wrangler/fake_dbclient_test.go @@ -25,40 +25,75 @@ import ( ) func verifyQueries(t *testing.T, dcs []*fakeDBClient) { + t.Helper() for _, dc := range dcs { dc.verifyQueries(t) } } +type dbResults struct { + index int + results []*dbResult + err error +} + type dbResult struct { result *sqltypes.Result err error - called bool +} + +func (dbrs *dbResults) next(query string) (*sqltypes.Result, error) { + if dbrs.exhausted() { + return nil, fmt.Errorf("query results exhausted: %s", query) + } + i := dbrs.index + dbrs.index++ + return dbrs.results[i].result, dbrs.results[i].err +} + +func (dbrs *dbResults) exhausted() bool { + return dbrs.index == len(dbrs.results) } // fakeDBClient fakes a binlog_player.DBClient. type fakeDBClient struct { - queries map[string]*dbResult - queriesRE map[string]*dbResult + queries map[string]*dbResults + queriesRE map[string]*dbResults + invariants map[string]*sqltypes.Result } // NewfakeDBClient returns a new DBClientMock. func newFakeDBClient() *fakeDBClient { return &fakeDBClient{ - queries: map[string]*dbResult{ - "use _vt": {result: &sqltypes.Result{}, called: true}, - "select * from _vt.vreplication where db_name='db'": {result: &sqltypes.Result{}}, + queries: make(map[string]*dbResults), + queriesRE: make(map[string]*dbResults), + invariants: map[string]*sqltypes.Result{ + "use _vt": {}, + "select * from _vt.vreplication where db_name='db'": {}, }, - queriesRE: make(map[string]*dbResult), } } func (dc *fakeDBClient) addQuery(query string, result *sqltypes.Result, err error) { - dc.queries[query] = &dbResult{result: result, err: err} + dbr := &dbResult{result: result, err: err} + if dbrs, ok := dc.queries[query]; ok { + dbrs.results = append(dbrs.results, dbr) + return + } + dc.queries[query] = &dbResults{results: []*dbResult{dbr}, err: err} } func (dc *fakeDBClient) addQueryRE(query string, result *sqltypes.Result, err error) { - dc.queriesRE[query] = &dbResult{result: result, err: err} + dbr := &dbResult{result: result, err: err} + if dbrs, ok := dc.queriesRE[query]; ok { + dbrs.results = append(dbrs.results, dbr) + return + } + dc.queriesRE[query] = &dbResults{results: []*dbResult{dbr}, err: err} +} + +func (dc *fakeDBClient) addInvariant(query string, result *sqltypes.Result) { + dc.invariants[query] = result } // DBName is part of the DBClient interface @@ -92,29 +127,30 @@ func (dc *fakeDBClient) Close() { // ExecuteFetch is part of the DBClient interface func (dc *fakeDBClient) ExecuteFetch(query string, maxrows int) (qr *sqltypes.Result, err error) { - if dbr := dc.queries[query]; dbr != nil { - dbr.called = true - return dbr.result, dbr.err + if dbrs := dc.queries[query]; dbrs != nil { + return dbrs.next(query) } - for re, dbr := range dc.queriesRE { + for re, dbrs := range dc.queriesRE { if regexp.MustCompile(re).MatchString(query) { - dbr.called = true - return dbr.result, dbr.err + return dbrs.next(query) } } + if result := dc.invariants[query]; result != nil { + return result, nil + } return nil, fmt.Errorf("unexpected query: %s", query) } func (dc *fakeDBClient) verifyQueries(t *testing.T) { t.Helper() - for query, dbr := range dc.queries { - if !dbr.called { - t.Errorf("query: %v was not called", query) + for query, dbrs := range dc.queries { + if !dbrs.exhausted() { + t.Errorf("query: %v has unreturned results", query) } } - for query, dbr := range dc.queriesRE { - if !dbr.called { - t.Errorf("query: %v was not called", query) + for query, dbrs := range dc.queriesRE { + if !dbrs.exhausted() { + t.Errorf("query: %v has unreturned results", query) } } } diff --git a/go/vt/wrangler/hook.go b/go/vt/wrangler/hook.go index bad0ce701ff..2cee6f0903d 100644 --- a/go/vt/wrangler/hook.go +++ b/go/vt/wrangler/hook.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/wrangler/keyspace.go b/go/vt/wrangler/keyspace.go index a95672f227f..25e266df0dd 100644 --- a/go/vt/wrangler/keyspace.go +++ b/go/vt/wrangler/keyspace.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -641,11 +641,22 @@ func (wr *Wrangler) masterMigrateServedType(ctx context.Context, keyspace string }() // Phase 1 + // - check topology service can successfully refresh both source and target master // - switch the source shards to read-only by disabling query service // - gather all replication points // - wait for filtered replication to catch up // - mark source shards as frozen event.DispatchUpdate(ev, "disabling query service on all source masters") + // making sure the refreshMaster on both source and target are working before turning off query service on source + if err := wr.refreshMasters(ctx, sourceShards); err != nil { + wr.cancelMasterMigrateServedTypes(ctx, keyspace, sourceShards) + return err + } + if err := wr.refreshMasters(ctx, destinationShards); err != nil { + wr.cancelMasterMigrateServedTypes(ctx, keyspace, sourceShards) + return err + } + if err := wr.updateShardRecords(ctx, keyspace, sourceShards, nil, topodatapb.TabletType_MASTER, true, false); err != nil { wr.cancelMasterMigrateServedTypes(ctx, keyspace, sourceShards) return err @@ -947,7 +958,7 @@ func (wr *Wrangler) waitForDrainInCell(ctx context.Context, cell, keyspace, shar defer watcher.Stop() // Wait for at least one tablet. - if err := tsc.WaitForTablets(ctx, cell, keyspace, shard, servedType); err != nil { + if err := tsc.WaitForTablets(ctx, keyspace, shard, servedType); err != nil { return fmt.Errorf("%v: error waiting for initial %v tablets for %v/%v: %v", cell, servedType, keyspace, shard, err) } diff --git a/go/vt/wrangler/migrater.go b/go/vt/wrangler/migrater.go index 4832d85965f..6e3470cce7c 100644 --- a/go/vt/wrangler/migrater.go +++ b/go/vt/wrangler/migrater.go @@ -29,7 +29,6 @@ import ( "github.com/golang/protobuf/proto" "golang.org/x/net/context" "vitess.io/vitess/go/sqltypes" - "vitess.io/vitess/go/sync2" "vitess.io/vitess/go/vt/binlog/binlogplayer" "vitess.io/vitess/go/vt/concurrency" "vitess.io/vitess/go/vt/key" @@ -42,6 +41,10 @@ import ( "vitess.io/vitess/go/vt/vtgate/vindexes" ) +const ( + frozenStr = "FROZEN" +) + // MigrateDirection specifies the migration direction. type MigrateDirection int @@ -62,14 +65,20 @@ const ( // migrater contains the metadata for migrating read and write traffic // for vreplication streams. type migrater struct { - migrationType binlogdatapb.MigrationType - wr *Wrangler - id int64 - sources map[string]*miSource - targets map[string]*miTarget - sourceKeyspace string - targetKeyspace string - tables []string + migrationType binlogdatapb.MigrationType + wr *Wrangler + workflow string + + // if frozen is true, the rest of the fields are not set. + frozen bool + reverseWorkflow string + id int64 + sources map[string]*miSource + targets map[string]*miTarget + sourceKeyspace string + targetKeyspace string + tables []string + sourceKSSchema *vindexes.KeyspaceSchema } // miTarget contains the metadata for each migration target. @@ -95,102 +104,188 @@ func (wr *Wrangler) MigrateReads(ctx context.Context, targetKeyspace, workflow s } mi, err := wr.buildMigrater(ctx, targetKeyspace, workflow) if err != nil { + wr.Logger().Errorf("buildMigrater failed: %v", err) return err } + if mi.frozen { + return fmt.Errorf("cannot migrate reads while MigrateWrites is in progress") + } if err := mi.validate(ctx, false /* isWrite */); err != nil { + mi.wr.Logger().Errorf("validate failed: %v", err) return err } // For reads, locking the source keyspace is sufficient. ctx, unlock, lockErr := wr.ts.LockKeyspace(ctx, mi.sourceKeyspace, "MigrateReads") if lockErr != nil { + mi.wr.Logger().Errorf("LockKeyspace failed: %v", lockErr) return lockErr } defer unlock(&err) if mi.migrationType == binlogdatapb.MigrationType_TABLES { - return mi.migrateTableReads(ctx, cells, servedType, direction) + if err := mi.migrateTableReads(ctx, cells, servedType, direction); err != nil { + mi.wr.Logger().Errorf("migrateTableReads failed: %v", err) + return err + } + return nil } - return mi.migrateShardReads(ctx, cells, servedType, direction) + if err := mi.migrateShardReads(ctx, cells, servedType, direction); err != nil { + mi.wr.Logger().Errorf("migrateShardReads failed: %v", err) + return err + } + return nil } // MigrateWrites is a generic way of migrating write traffic for a resharding workflow. -func (wr *Wrangler) MigrateWrites(ctx context.Context, targetKeyspace, workflow string, filteredReplicationWaitTime time.Duration) (journalID int64, err error) { +func (wr *Wrangler) MigrateWrites(ctx context.Context, targetKeyspace, workflow string, filteredReplicationWaitTime time.Duration, cancelMigrate, reverseReplication bool) (journalID int64, err error) { mi, err := wr.buildMigrater(ctx, targetKeyspace, workflow) if err != nil { + wr.Logger().Errorf("buildMigrater failed: %v", err) return 0, err } + if mi.frozen { + mi.wr.Logger().Infof("Replication has been frozen already. Deleting left-over streams") + if err := mi.deleteTargetVReplication(ctx); err != nil { + mi.wr.Logger().Errorf("deleteTargetVReplication failed: %v", err) + return 0, err + } + return 0, nil + } + mi.wr.Logger().Infof("Built migration metadata: %+v", mi) if err := mi.validate(ctx, true /* isWrite */); err != nil { + mi.wr.Logger().Errorf("validate failed: %v", err) return 0, err } // Need to lock both source and target keyspaces. ctx, sourceUnlock, lockErr := wr.ts.LockKeyspace(ctx, mi.sourceKeyspace, "MigrateWrites") if lockErr != nil { + mi.wr.Logger().Errorf("LockKeyspace failed: %v", lockErr) return 0, lockErr } defer sourceUnlock(&err) if mi.targetKeyspace != mi.sourceKeyspace { tctx, targetUnlock, lockErr := wr.ts.LockKeyspace(ctx, mi.targetKeyspace, "MigrateWrites") if lockErr != nil { + mi.wr.Logger().Errorf("LockKeyspace failed: %v", lockErr) return 0, lockErr } ctx = tctx defer targetUnlock(&err) } - journalsExist, err := mi.checkJournals(ctx) + // If no journals exist, sourceWorkflows will be initialized by sm.MigrateStreams. + journalsExist, sourceWorkflows, err := mi.checkJournals(ctx) if err != nil { + mi.wr.Logger().Errorf("checkJournals failed: %v", err) return 0, err } if !journalsExist { mi.wr.Logger().Infof("No previous journals were found. Proceeding normally.") + sm, err := buildStreamMigrater(ctx, mi, cancelMigrate) + if err != nil { + mi.wr.Logger().Errorf("buildStreamMigrater failed: %v", err) + return 0, err + } + if cancelMigrate { + mi.wr.Logger().Infof("Cancel was requested.") + mi.cancelMigration(ctx, sm) + return 0, nil + } + sourceWorkflows, err = sm.stopStreams(ctx) + if err != nil { + mi.wr.Logger().Errorf("stopStreams failed: %v", err) + mi.cancelMigration(ctx, sm) + return 0, err + } if err := mi.stopSourceWrites(ctx); err != nil { - mi.cancelMigration(ctx) + mi.wr.Logger().Errorf("stopSourceWrites failed: %v", err) + mi.cancelMigration(ctx, sm) return 0, err } if err := mi.waitForCatchup(ctx, filteredReplicationWaitTime); err != nil { - mi.cancelMigration(ctx) + mi.wr.Logger().Errorf("waitForCatchup failed: %v", err) + mi.cancelMigration(ctx, sm) + return 0, err + } + if err := sm.migrateStreams(ctx); err != nil { + mi.wr.Logger().Errorf("migrateStreams failed: %v", err) + mi.cancelMigration(ctx, sm) + return 0, err + } + if err := mi.createReverseVReplication(ctx); err != nil { + mi.wr.Logger().Errorf("createReverseVReplication failed: %v", err) + mi.cancelMigration(ctx, sm) return 0, err } } else { + if cancelMigrate { + err := fmt.Errorf("migration has reached the point of no return, cannot cancel") + mi.wr.Logger().Errorf("%v", err) + return 0, err + } mi.wr.Logger().Infof("Journals were found. Completing the left over steps.") // Need to gather positions in case all journals were not created. if err := mi.gatherPositions(ctx); err != nil { + mi.wr.Logger().Errorf("gatherPositions failed: %v", err) return 0, err } } // This is the point of no return. Once a journal is created, // traffic can be redirected to target shards. - if err := mi.createJournals(ctx); err != nil { - return 0, err - } - if err := mi.createReverseReplication(ctx); err != nil { + if err := mi.createJournals(ctx, sourceWorkflows); err != nil { + mi.wr.Logger().Errorf("createJournals failed: %v", err) return 0, err } if err := mi.allowTargetWrites(ctx); err != nil { + mi.wr.Logger().Errorf("allowTargetWrites failed: %v", err) return 0, err } if err := mi.changeRouting(ctx); err != nil { + mi.wr.Logger().Errorf("changeRouting failed: %v", err) + return 0, err + } + if err := streamMigraterfinalize(ctx, mi, sourceWorkflows); err != nil { + mi.wr.Logger().Errorf("finalize failed: %v", err) + return 0, err + } + if reverseReplication { + if err := mi.startReverseVReplication(ctx); err != nil { + mi.wr.Logger().Errorf("startReverseVReplication failed: %v", err) + return 0, err + } + } + if err := mi.deleteTargetVReplication(ctx); err != nil { + mi.wr.Logger().Errorf("deleteTargetVReplication failed: %v", err) return 0, err } - mi.deleteTargetVReplication(ctx) return mi.id, nil } func (wr *Wrangler) buildMigrater(ctx context.Context, targetKeyspace, workflow string) (*migrater, error) { - targets, err := wr.buildMigrationTargets(ctx, targetKeyspace, workflow) + targets, frozen, err := wr.buildMigrationTargets(ctx, targetKeyspace, workflow) if err != nil { return nil, err } + if frozen { + return &migrater{ + wr: wr, + workflow: workflow, + targets: targets, + frozen: true, + }, nil + } mi := &migrater{ - wr: wr, - id: hashStreams(targetKeyspace, targets), - targets: targets, - sources: make(map[string]*miSource), - targetKeyspace: targetKeyspace, + wr: wr, + workflow: workflow, + reverseWorkflow: reverseName(workflow), + id: hashStreams(targetKeyspace, targets), + targets: targets, + sources: make(map[string]*miSource), + targetKeyspace: targetKeyspace, } mi.wr.Logger().Infof("Migration ID for workflow %s: %d", workflow, mi.id) @@ -202,22 +297,6 @@ func (wr *Wrangler) buildMigrater(ctx context.Context, targetKeyspace, workflow } else if mi.sourceKeyspace != bls.Keyspace { return nil, fmt.Errorf("source keyspaces are mismatched across streams: %v vs %v", mi.sourceKeyspace, bls.Keyspace) } - if _, ok := mi.sources[bls.Shard]; ok { - continue - } - - sourcesi, err := mi.wr.ts.GetShard(ctx, bls.Keyspace, bls.Shard) - if err != nil { - return nil, err - } - sourceMaster, err := mi.wr.ts.GetTablet(ctx, sourcesi.MasterAlias) - if err != nil { - return nil, err - } - mi.sources[bls.Shard] = &miSource{ - si: sourcesi, - master: sourceMaster, - } if mi.tables == nil { for _, rule := range bls.Filter.Rules { @@ -234,21 +313,54 @@ func (wr *Wrangler) buildMigrater(ctx context.Context, targetKeyspace, workflow return nil, fmt.Errorf("table lists are mismatched across streams: %v vs %v", mi.tables, tables) } } + + if _, ok := mi.sources[bls.Shard]; ok { + continue + } + sourcesi, err := mi.wr.ts.GetShard(ctx, bls.Keyspace, bls.Shard) + if err != nil { + return nil, err + } + sourceMaster, err := mi.wr.ts.GetTablet(ctx, sourcesi.MasterAlias) + if err != nil { + return nil, err + } + mi.sources[bls.Shard] = &miSource{ + si: sourcesi, + master: sourceMaster, + } } } if mi.sourceKeyspace != mi.targetKeyspace { mi.migrationType = binlogdatapb.MigrationType_TABLES } else { + // TODO(sougou): for shard migration, validate that source and target combined + // keyranges match. mi.migrationType = binlogdatapb.MigrationType_SHARDS + for sourceShard := range mi.sources { + if _, ok := mi.targets[sourceShard]; ok { + // If shards are overlapping, then this is a table migration. + mi.migrationType = binlogdatapb.MigrationType_TABLES + break + } + } + } + vs, err := mi.wr.ts.GetVSchema(ctx, mi.sourceKeyspace) + if err != nil { + return nil, err + } + mi.sourceKSSchema, err = vindexes.BuildKeyspaceSchema(vs, mi.sourceKeyspace) + if err != nil { + return nil, err } return mi, nil } -func (wr *Wrangler) buildMigrationTargets(ctx context.Context, targetKeyspace, workflow string) (targets map[string]*miTarget, err error) { +func (wr *Wrangler) buildMigrationTargets(ctx context.Context, targetKeyspace, workflow string) (targets map[string]*miTarget, frozen bool, err error) { targets = make(map[string]*miTarget) targetShards, err := wr.ts.GetShardNames(ctx, targetKeyspace) if err != nil { - return nil, err + return nil, false, err } // We check all target shards. All of them may not have a stream. // For example, if we're splitting -80 to -40,40-80, only those @@ -256,15 +368,15 @@ func (wr *Wrangler) buildMigrationTargets(ctx context.Context, targetKeyspace, w for _, targetShard := range targetShards { targetsi, err := wr.ts.GetShard(ctx, targetKeyspace, targetShard) if err != nil { - return nil, err + return nil, false, err } targetMaster, err := wr.ts.GetTablet(ctx, targetsi.MasterAlias) if err != nil { - return nil, err + return nil, false, err } - p3qr, err := wr.tmc.VReplicationExec(ctx, targetMaster.Tablet, fmt.Sprintf("select id, source from _vt.vreplication where workflow='%s' and db_name='%s'", workflow, targetMaster.DbName())) + p3qr, err := wr.tmc.VReplicationExec(ctx, targetMaster.Tablet, fmt.Sprintf("select id, source, message from _vt.vreplication where workflow=%s and db_name=%s", encodeString(workflow), encodeString(targetMaster.DbName()))) if err != nil { - return nil, err + return nil, false, err } // If there's no vreplication stream, check the next target. if len(p3qr.Rows) < 1 { @@ -280,19 +392,24 @@ func (wr *Wrangler) buildMigrationTargets(ctx context.Context, targetKeyspace, w for _, row := range qr.Rows { id, err := sqltypes.ToInt64(row[0]) if err != nil { - return nil, err + return nil, false, err } + var bls binlogdatapb.BinlogSource if err := proto.UnmarshalText(row[1].ToString(), &bls); err != nil { - return nil, err + return nil, false, err } targets[targetShard].sources[uint32(id)] = &bls + + if row[2].ToString() == frozenStr { + frozen = true + } } } if len(targets) == 0 { - return nil, fmt.Errorf("no streams found in keyspace %s for: %s", targetKeyspace, workflow) + return nil, false, fmt.Errorf("no streams found in keyspace %s for: %s", targetKeyspace, workflow) } - return targets, nil + return targets, frozen, nil } // hashStreams produces a reproducible hash based on the input parameters. @@ -332,12 +449,6 @@ func (mi *migrater) validate(ctx context.Context, isWrite bool) error { return mi.validateTableForWrite(ctx) } } else { // binlogdatapb.MigrationType_SHARDS - // Source and target shards must not match. - for sourceShard := range mi.sources { - if _, ok := mi.targets[sourceShard]; ok { - return fmt.Errorf("target shard matches a source shard: %v", sourceShard) - } - } if isWrite { return mi.validateShardForWrite(ctx) } @@ -455,21 +566,34 @@ func (mi *migrater) migrateShardReads(ctx context.Context, cells []string, serve return mi.wr.ts.MigrateServedType(ctx, mi.sourceKeyspace, toShards, fromShards, servedType, cells) } -func (mi *migrater) checkJournals(ctx context.Context) (journalsExist bool, err error) { - var exist sync2.AtomicBool +// checkJournals returns true if at least one journal has been created. +// If so, it also returns the list of sourceWorkflows that need to be migrated. +func (mi *migrater) checkJournals(ctx context.Context) (journalsExist bool, sourceWorkflows []string, err error) { + var mu sync.Mutex + journal := &binlogdatapb.Journal{} + var exists bool err = mi.forAllSources(func(source *miSource) error { - statement := fmt.Sprintf("select 1 from _vt.resharding_journal where id=%v", mi.id) + statement := fmt.Sprintf("select val from _vt.resharding_journal where id=%v", mi.id) p3qr, err := mi.wr.tmc.VReplicationExec(ctx, source.master.Tablet, statement) if err != nil { return err } - if len(p3qr.Rows) >= 1 { - exist.Set(true) + if len(p3qr.Rows) != 0 { + qr := sqltypes.Proto3ToResult(p3qr) + mu.Lock() + defer mu.Unlock() + + if !exists { + if err := proto.UnmarshalText(qr.Rows[0][0].ToString(), journal); err != nil { + return err + } + exists = true + } source.journaled = true } return nil }) - return exist.Get(), err + return exists, journal.SourceWorkflows, err } func (mi *migrater) stopSourceWrites(ctx context.Context) error { @@ -509,9 +633,11 @@ func (mi *migrater) waitForCatchup(ctx context.Context, filteredReplicationWaitT return mi.forAllUids(func(target *miTarget, uid uint32) error { bls := target.sources[uid] source := mi.sources[bls.Shard] + mi.wr.Logger().Infof("waiting for keyspace:shard: %v:%v, position %v", mi.targetKeyspace, target.si.ShardName(), source.position) if err := mi.wr.tmc.VReplicationWaitForPos(ctx, target.master.Tablet, int(uid), source.position); err != nil { return err } + mi.wr.Logger().Infof("position for keyspace:shard: %v:%v reached", mi.targetKeyspace, target.si.ShardName()) if _, err := mi.wr.tmc.VReplicationExec(ctx, target.master.Tablet, binlogplayer.StopVReplication(uid, "stopped for cutover")); err != nil { return err } @@ -529,7 +655,7 @@ func (mi *migrater) waitForCatchup(ctx context.Context, filteredReplicationWaitT }) } -func (mi *migrater) cancelMigration(ctx context.Context) { +func (mi *migrater) cancelMigration(ctx context.Context, sm *streamMigrater) { var err error if mi.migrationType == binlogdatapb.MigrationType_TABLES { err = mi.changeTableSourceWrites(ctx, allowWrites) @@ -540,15 +666,21 @@ func (mi *migrater) cancelMigration(ctx context.Context) { mi.wr.Logger().Errorf("Cancel migration failed:", err) } - err = mi.forAllUids(func(target *miTarget, uid uint32) error { - if _, err := mi.wr.tmc.VReplicationExec(ctx, target.master.Tablet, binlogplayer.StartVReplication(uid)); err != nil { - return err - } - return nil + sm.cancelMigration(ctx) + + err = mi.forAllTargets(func(target *miTarget) error { + query := fmt.Sprintf("update _vt.vreplication set state='Running', message='' where db_name=%s and workflow=%s", encodeString(target.master.DbName()), encodeString(mi.workflow)) + _, err := mi.wr.tmc.VReplicationExec(ctx, target.master.Tablet, query) + return err }) if err != nil { mi.wr.Logger().Errorf("Cancel migration failed: could not restart vreplication: %v", err) } + + err = mi.deleteReverseVReplication(ctx) + if err != nil { + mi.wr.Logger().Errorf("Cancel migration failed: could not delete revers vreplication entries: %v", err) + } } func (mi *migrater) gatherPositions(ctx context.Context) error { @@ -569,7 +701,60 @@ func (mi *migrater) gatherPositions(ctx context.Context) error { }) } -func (mi *migrater) createJournals(ctx context.Context) error { +func (mi *migrater) createReverseVReplication(ctx context.Context) error { + if err := mi.deleteReverseVReplication(ctx); err != nil { + return err + } + err := mi.forAllUids(func(target *miTarget, uid uint32) error { + bls := target.sources[uid] + source := mi.sources[bls.Shard] + reverseBls := &binlogdatapb.BinlogSource{ + Keyspace: mi.targetKeyspace, + Shard: target.si.ShardName(), + TabletType: bls.TabletType, + Filter: &binlogdatapb.Filter{}, + OnDdl: bls.OnDdl, + } + for _, rule := range bls.Filter.Rules { + var filter string + if strings.HasPrefix(rule.Match, "/") { + if mi.sourceKSSchema.Keyspace.Sharded { + filter = key.KeyRangeString(source.si.KeyRange) + } + } else { + var inKeyrange string + if mi.sourceKSSchema.Keyspace.Sharded { + vtable, ok := mi.sourceKSSchema.Tables[rule.Match] + if !ok { + return fmt.Errorf("table %s not found in vschema", rule.Match) + } + // TODO(sougou): handle degenerate cases like sequence, etc. + // We currently assume the primary vindex is the best way to filter, which may not be true. + inKeyrange = fmt.Sprintf(" where in_keyrange(%s, '%s', '%s')", sqlparser.String(vtable.ColumnVindexes[0].Columns[0]), vtable.ColumnVindexes[0].Type, key.KeyRangeString(source.si.KeyRange)) + } + filter = fmt.Sprintf("select * from %s%s", rule.Match, inKeyrange) + } + reverseBls.Filter.Rules = append(reverseBls.Filter.Rules, &binlogdatapb.Rule{ + Match: rule.Match, + Filter: filter, + }) + } + + _, err := mi.wr.VReplicationExec(ctx, source.master.Alias, binlogplayer.CreateVReplicationState(mi.reverseWorkflow, reverseBls, target.position, binlogplayer.BlpStopped, source.master.DbName())) + return err + }) + return err +} + +func (mi *migrater) deleteReverseVReplication(ctx context.Context) error { + return mi.forAllSources(func(source *miSource) error { + query := fmt.Sprintf("delete from _vt.vreplication where db_name=%s and workflow=%s", encodeString(source.master.DbName()), encodeString(mi.reverseWorkflow)) + _, err := mi.wr.tmc.VReplicationExec(ctx, source.master.Tablet, query) + return err + }) +} + +func (mi *migrater) createJournals(ctx context.Context, sourceWorkflows []string) error { var participants []*binlogdatapb.KeyspaceShard for sourceShard := range mi.sources { participants = append(participants, &binlogdatapb.KeyspaceShard{ @@ -582,11 +767,12 @@ func (mi *migrater) createJournals(ctx context.Context) error { return nil } journal := &binlogdatapb.Journal{ - Id: mi.id, - MigrationType: mi.migrationType, - Tables: mi.tables, - LocalPosition: source.position, - Participants: participants, + Id: mi.id, + MigrationType: mi.migrationType, + Tables: mi.tables, + LocalPosition: source.position, + Participants: participants, + SourceWorkflows: sourceWorkflows, } for targetShard, target := range mi.targets { found := false @@ -617,54 +803,6 @@ func (mi *migrater) createJournals(ctx context.Context) error { }) } -func (mi *migrater) createReverseReplication(ctx context.Context) error { - vs, err := mi.wr.ts.GetVSchema(ctx, mi.sourceKeyspace) - if err != nil { - return err - } - ksschema, err := vindexes.BuildKeyspaceSchema(vs, mi.sourceKeyspace) - if err != nil { - return err - } - return mi.forAllUids(func(target *miTarget, uid uint32) error { - bls := target.sources[uid] - source := mi.sources[bls.Shard] - reverseBls := &binlogdatapb.BinlogSource{ - Keyspace: mi.targetKeyspace, - Shard: target.si.ShardName(), - TabletType: bls.TabletType, - Filter: &binlogdatapb.Filter{}, - } - for _, rule := range bls.Filter.Rules { - var filter string - if strings.HasPrefix(rule.Match, "/") { - if ksschema.Keyspace.Sharded { - filter = bls.Shard - } - } else { - var inKeyrange string - if ksschema.Keyspace.Sharded { - vtable, ok := ksschema.Tables[rule.Match] - if !ok { - return fmt.Errorf("table %s not found in vschema", rule.Match) - } - // TODO(sougou): handle degenerate cases like sequence, etc. - // We currently assume the primary vindex is the best way to filter, which may not be true. - inKeyrange = fmt.Sprintf(" where in_keyrange(%s, '%s', '%s')", sqlparser.String(vtable.ColumnVindexes[0].Columns[0]), vs.Vindexes[vtable.ColumnVindexes[0].Name].Type, bls.Shard) - } - filter = fmt.Sprintf("select * from %s%s", rule.Match, inKeyrange) - } - reverseBls.Filter.Rules = append(reverseBls.Filter.Rules, &binlogdatapb.Rule{ - Match: rule.Match, - Filter: filter, - }) - } - - _, err := mi.wr.VReplicationExec(ctx, source.master.Alias, binlogplayer.CreateVReplicationState("ReversedResharding", reverseBls, target.position, binlogplayer.BlpStopped, source.master.DbName())) - return err - }) -} - func (mi *migrater) allowTargetWrites(ctx context.Context) error { if mi.migrationType == binlogdatapb.MigrationType_TABLES { return mi.allowTableTargetWrites(ctx) @@ -748,12 +886,30 @@ func (mi *migrater) changeShardRouting(ctx context.Context) error { return mi.wr.ts.MigrateServedType(ctx, mi.targetKeyspace, mi.targetShards(), mi.sourceShards(), topodatapb.TabletType_MASTER, nil) } -func (mi *migrater) deleteTargetVReplication(ctx context.Context) { - _ = mi.forAllUids(func(target *miTarget, uid uint32) error { - if _, err := mi.wr.tmc.VReplicationExec(ctx, target.master.Tablet, binlogplayer.DeleteVReplication(uid)); err != nil { - mi.wr.Logger().Errorf("Final cleanup: could not delete vreplication, please delete stopped streams manually: %v", err) - } - return nil +func (mi *migrater) startReverseVReplication(ctx context.Context) error { + return mi.forAllSources(func(source *miSource) error { + query := fmt.Sprintf("update _vt.vreplication set state='Running', message='' where db_name=%s", encodeString(source.master.DbName())) + _, err := mi.wr.VReplicationExec(ctx, source.master.Alias, query) + return err + }) +} + +func (mi *migrater) deleteTargetVReplication(ctx context.Context) error { + // Mark target streams as frozen before deleting. If MigrateWrites gets + // re-invoked after a freeze, it will skip all the previous steps and + // jump directly here for the final cleanup. + err := mi.forAllTargets(func(target *miTarget) error { + query := fmt.Sprintf("update _vt.vreplication set message = '%s' where db_name=%s and workflow=%s", frozenStr, encodeString(target.master.DbName()), encodeString(mi.workflow)) + _, err := mi.wr.tmc.VReplicationExec(ctx, target.master.Tablet, query) + return err + }) + if err != nil { + return err + } + return mi.forAllTargets(func(target *miTarget) error { + query := fmt.Sprintf("delete from _vt.vreplication where db_name=%s and workflow=%s", encodeString(target.master.DbName()), encodeString(mi.workflow)) + _, err := mi.wr.tmc.VReplicationExec(ctx, target.master.Tablet, query) + return err }) } @@ -855,3 +1011,11 @@ func (wr *Wrangler) saveRoutingRules(ctx context.Context, rules map[string][]str } return wr.ts.SaveRoutingRules(ctx, rrs) } + +func reverseName(workflow string) string { + const reverse = "_reverse" + if strings.HasSuffix(workflow, reverse) { + return workflow[:len(workflow)-len(reverse)] + } + return workflow + reverse +} diff --git a/go/vt/wrangler/migrater_env_test.go b/go/vt/wrangler/migrater_env_test.go index 5384591ba48..5ead8aea8cb 100644 --- a/go/vt/wrangler/migrater_env_test.go +++ b/go/vt/wrangler/migrater_env_test.go @@ -24,9 +24,11 @@ import ( "vitess.io/vitess/go/mysql" "vitess.io/vitess/go/sqltypes" "vitess.io/vitess/go/vt/binlog/binlogplayer" + "vitess.io/vitess/go/vt/key" "vitess.io/vitess/go/vt/logutil" binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" topodatapb "vitess.io/vitess/go/vt/proto/topodata" + "vitess.io/vitess/go/vt/proto/vschema" vschemapb "vitess.io/vitess/go/vt/proto/vschema" "vitess.io/vitess/go/vt/topo" "vitess.io/vitess/go/vt/topo/memorytopo" @@ -35,44 +37,72 @@ import ( "vitess.io/vitess/go/vt/vttablet/tmclient" ) -const vreplQueryks = "select id, source from _vt.vreplication where workflow = 'test' and db_name = 'vt_ks'" -const vreplQueryks2 = "select id, source from _vt.vreplication where workflow = 'test' and db_name = 'vt_ks2'" +const vreplQueryks = "select id, source, message from _vt.vreplication where workflow='test' and db_name='vt_ks'" +const vreplQueryks2 = "select id, source, message from _vt.vreplication where workflow='test' and db_name='vt_ks2'" type testMigraterEnv struct { - ts *topo.Server - wr *Wrangler - source1Master, source1Replica, source1Rdonly *fakeTablet - source2Master, source2Replica, source2Rdonly *fakeTablet - dest1Master, dest1Replica, dest1Rdonly *fakeTablet - dest2Master, dest2Replica, dest2Rdonly *fakeTablet - dbSource1Client, dbSource2Client *fakeDBClient - dbDest1Client, dbDest2Client *fakeDBClient - allDBClients []*fakeDBClient - targetKeyspace string - streams map[string][]uint32 + ts *topo.Server + wr *Wrangler + sourceMasters []*fakeTablet + targetMasters []*fakeTablet + dbSourceClients []*fakeDBClient + dbTargetClients []*fakeDBClient + allDBClients []*fakeDBClient + targetKeyspace string + sourceShards []string + targetShards []string + sourceKeyRanges []*topodatapb.KeyRange + targetKeyRanges []*topodatapb.KeyRange +} + +// testShardMigraterEnv has some convenience functions for adding expected queries. +// They are approximate and should be only used to test other features like stream migration. +// Use explicit queries for testing the actual shard migration. +type testShardMigraterEnv struct { + testMigraterEnv } func newTestTableMigrater(ctx context.Context, t *testing.T) *testMigraterEnv { + return newTestTableMigraterCustom(ctx, t, []string{"-40", "40-"}, []string{"-80", "80-"}, "select * %s") +} + +// newTestTableMigraterCustom creates a customized test tablet migrater. +// fmtQuery should be of the form: 'select a, b %s group by a'. +// The test will Sprintf a from clause and where clause as needed. +func newTestTableMigraterCustom(ctx context.Context, t *testing.T, sourceShards, targetShards []string, fmtQuery string) *testMigraterEnv { tme := &testMigraterEnv{} tme.ts = memorytopo.NewServer("cell1", "cell2") tme.wr = New(logutil.NewConsoleLogger(), tme.ts, tmclient.NewTabletManagerClient()) - - // Create cluster: ks1:-40,40- and ks2:-80,80-. - tme.source1Master = newFakeTablet(t, tme.wr, "cell1", 10, topodatapb.TabletType_MASTER, nil, TabletKeyspaceShard(t, "ks1", "-40")) - tme.source1Replica = newFakeTablet(t, tme.wr, "cell1", 11, topodatapb.TabletType_REPLICA, nil, TabletKeyspaceShard(t, "ks1", "-40")) - tme.source1Rdonly = newFakeTablet(t, tme.wr, "cell1", 12, topodatapb.TabletType_RDONLY, nil, TabletKeyspaceShard(t, "ks1", "-40")) - - tme.source2Master = newFakeTablet(t, tme.wr, "cell1", 20, topodatapb.TabletType_MASTER, nil, TabletKeyspaceShard(t, "ks1", "40-")) - tme.source2Replica = newFakeTablet(t, tme.wr, "cell1", 21, topodatapb.TabletType_REPLICA, nil, TabletKeyspaceShard(t, "ks1", "40-")) - tme.source2Rdonly = newFakeTablet(t, tme.wr, "cell1", 22, topodatapb.TabletType_RDONLY, nil, TabletKeyspaceShard(t, "ks1", "40-")) - - tme.dest1Master = newFakeTablet(t, tme.wr, "cell1", 30, topodatapb.TabletType_MASTER, nil, TabletKeyspaceShard(t, "ks2", "-80")) - tme.dest1Replica = newFakeTablet(t, tme.wr, "cell1", 31, topodatapb.TabletType_REPLICA, nil, TabletKeyspaceShard(t, "ks2", "-80")) - tme.dest1Rdonly = newFakeTablet(t, tme.wr, "cell1", 32, topodatapb.TabletType_RDONLY, nil, TabletKeyspaceShard(t, "ks2", "-80")) - - tme.dest2Master = newFakeTablet(t, tme.wr, "cell1", 40, topodatapb.TabletType_MASTER, nil, TabletKeyspaceShard(t, "ks2", "80-")) - tme.dest2Replica = newFakeTablet(t, tme.wr, "cell1", 41, topodatapb.TabletType_REPLICA, nil, TabletKeyspaceShard(t, "ks2", "80-")) - tme.dest2Rdonly = newFakeTablet(t, tme.wr, "cell1", 42, topodatapb.TabletType_RDONLY, nil, TabletKeyspaceShard(t, "ks2", "80-")) + tme.sourceShards = sourceShards + tme.targetShards = targetShards + + tabletID := 10 + for _, shard := range sourceShards { + tme.sourceMasters = append(tme.sourceMasters, newFakeTablet(t, tme.wr, "cell1", uint32(tabletID), topodatapb.TabletType_MASTER, nil, TabletKeyspaceShard(t, "ks1", shard))) + tabletID += 10 + + _, sourceKeyRange, err := topo.ValidateShardName(shard) + if err != nil { + t.Fatal(err) + } + if sourceKeyRange == nil { + sourceKeyRange = &topodatapb.KeyRange{} + } + tme.sourceKeyRanges = append(tme.sourceKeyRanges, sourceKeyRange) + } + for _, shard := range targetShards { + tme.targetMasters = append(tme.targetMasters, newFakeTablet(t, tme.wr, "cell1", uint32(tabletID), topodatapb.TabletType_MASTER, nil, TabletKeyspaceShard(t, "ks2", shard))) + tabletID += 10 + + _, targetKeyRange, err := topo.ValidateShardName(shard) + if err != nil { + t.Fatal(err) + } + if targetKeyRange == nil { + targetKeyRange = &topodatapb.KeyRange{} + } + tme.targetKeyRanges = append(tme.targetKeyRanges, targetKeyRange) + } vs := &vschemapb.Keyspace{ Sharded: true, @@ -96,11 +126,15 @@ func newTestTableMigrater(ctx context.Context, t *testing.T) *testMigraterEnv { }, }, } - if err := tme.ts.SaveVSchema(ctx, "ks1", vs); err != nil { - t.Fatal(err) + if len(sourceShards) != 1 { + if err := tme.ts.SaveVSchema(ctx, "ks1", vs); err != nil { + t.Fatal(err) + } } - if err := tme.ts.SaveVSchema(ctx, "ks2", vs); err != nil { - t.Fatal(err) + if len(targetShards) != 1 { + if err := tme.ts.SaveVSchema(ctx, "ks2", vs); err != nil { + t.Fatal(err) + } } if err := tme.ts.RebuildSrvVSchema(ctx, nil); err != nil { t.Fatal(err) @@ -118,61 +152,30 @@ func newTestTableMigrater(ctx context.Context, t *testing.T) *testMigraterEnv { tme.createDBClients(ctx, t) tme.setMasterPositions() - // Emulate the following replication streams (many-to-many table migration): - // -40 -> -80 - // 40- -> -80 - // 40- -> 80- - // -40 will only have one target, and 80- will have only one source. - bls1 := &binlogdatapb.BinlogSource{ - Keyspace: "ks1", - Shard: "-40", - Filter: &binlogdatapb.Filter{ - Rules: []*binlogdatapb.Rule{{ - Match: "t1", - Filter: "select * from t1 where in_keyrange('-80')", - }, { - Match: "t2", - Filter: "select * from t2 where in_keyrange('-80')", - }}, - }, - } - bls2 := &binlogdatapb.BinlogSource{ - Keyspace: "ks1", - Shard: "40-", - Filter: &binlogdatapb.Filter{ - Rules: []*binlogdatapb.Rule{{ - Match: "t1", - Filter: "select * from t1 where in_keyrange('-80')", - }, { - Match: "t2", - Filter: "select * from t2 where in_keyrange('-80')", - }}, - }, + for i, targetShard := range targetShards { + var rows []string + for j, sourceShard := range sourceShards { + bls := &binlogdatapb.BinlogSource{ + Keyspace: "ks1", + Shard: sourceShard, + Filter: &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{{ + Match: "t1", + Filter: fmt.Sprintf(fmtQuery, fmt.Sprintf("from t1 where in_keyrange('%s')", targetShard)), + }, { + Match: "t2", + Filter: fmt.Sprintf(fmtQuery, fmt.Sprintf("from t2 where in_keyrange('%s')", targetShard)), + }}, + }, + } + rows = append(rows, fmt.Sprintf("%d|%v|", j+1, bls)) + } + tme.dbTargetClients[i].addInvariant(vreplQueryks2, sqltypes.MakeTestResult(sqltypes.MakeTestFields( + "id|source|message", + "int64|varchar|varchar"), + rows...), + ) } - tme.dbDest1Client.addQuery(vreplQueryks2, sqltypes.MakeTestResult(sqltypes.MakeTestFields( - "id|source", - "int64|varchar"), - fmt.Sprintf("1|%v", bls1), - fmt.Sprintf("2|%v", bls2), - ), nil) - bls3 := &binlogdatapb.BinlogSource{ - Keyspace: "ks1", - Shard: "40-", - Filter: &binlogdatapb.Filter{ - Rules: []*binlogdatapb.Rule{{ - Match: "t1", - Filter: "select * from t1 where in_keyrange('80-')", - }, { - Match: "t2", - Filter: "select * from t2 where in_keyrange('80-')", - }}, - }, - } - tme.dbDest2Client.addQuery(vreplQueryks2, sqltypes.MakeTestResult(sqltypes.MakeTestFields( - "id|source", - "int64|varchar"), - fmt.Sprintf("1|%v", bls3), - ), nil) if err := tme.wr.saveRoutingRules(ctx, map[string][]string{ "t1": {"ks1.t1"}, @@ -187,36 +190,72 @@ func newTestTableMigrater(ctx context.Context, t *testing.T) *testMigraterEnv { } tme.targetKeyspace = "ks2" - tme.streams = map[string][]uint32{ - "-80": {1, 2}, - "80-": {1}, - } return tme } -func newTestShardMigrater(ctx context.Context, t *testing.T) *testMigraterEnv { - tme := &testMigraterEnv{} +func newTestShardMigrater(ctx context.Context, t *testing.T, sourceShards, targetShards []string) *testShardMigraterEnv { + tme := &testShardMigraterEnv{} tme.ts = memorytopo.NewServer("cell1", "cell2") tme.wr = New(logutil.NewConsoleLogger(), tme.ts, tmclient.NewTabletManagerClient()) + tme.sourceShards = sourceShards + tme.targetShards = targetShards + + tabletID := 10 + for _, shard := range sourceShards { + tme.sourceMasters = append(tme.sourceMasters, newFakeTablet(t, tme.wr, "cell1", uint32(tabletID), topodatapb.TabletType_MASTER, nil, TabletKeyspaceShard(t, "ks", shard))) + tabletID += 10 + + _, sourceKeyRange, err := topo.ValidateShardName(shard) + if err != nil { + t.Fatal(err) + } + if sourceKeyRange == nil { + sourceKeyRange = &topodatapb.KeyRange{} + } + tme.sourceKeyRanges = append(tme.sourceKeyRanges, sourceKeyRange) + } + for _, shard := range targetShards { + tme.targetMasters = append(tme.targetMasters, newFakeTablet(t, tme.wr, "cell1", uint32(tabletID), topodatapb.TabletType_MASTER, nil, TabletKeyspaceShard(t, "ks", shard))) + tabletID += 10 + + _, targetKeyRange, err := topo.ValidateShardName(shard) + if err != nil { + t.Fatal(err) + } + if targetKeyRange == nil { + targetKeyRange = &topodatapb.KeyRange{} + } + tme.targetKeyRanges = append(tme.targetKeyRanges, targetKeyRange) + } - // Create cluster with "ks" as keyspace. -40,40- as serving, -80,80- as non-serving. - tme.source1Master = newFakeTablet(t, tme.wr, "cell1", 10, topodatapb.TabletType_MASTER, nil, TabletKeyspaceShard(t, "ks", "-40")) - tme.source1Replica = newFakeTablet(t, tme.wr, "cell1", 11, topodatapb.TabletType_REPLICA, nil, TabletKeyspaceShard(t, "ks", "-40")) - tme.source1Rdonly = newFakeTablet(t, tme.wr, "cell1", 12, topodatapb.TabletType_RDONLY, nil, TabletKeyspaceShard(t, "ks", "-40")) - - tme.source2Master = newFakeTablet(t, tme.wr, "cell1", 20, topodatapb.TabletType_MASTER, nil, TabletKeyspaceShard(t, "ks", "40-")) - tme.source2Replica = newFakeTablet(t, tme.wr, "cell1", 21, topodatapb.TabletType_REPLICA, nil, TabletKeyspaceShard(t, "ks", "40-")) - tme.source2Rdonly = newFakeTablet(t, tme.wr, "cell1", 22, topodatapb.TabletType_RDONLY, nil, TabletKeyspaceShard(t, "ks", "40-")) - - tme.dest1Master = newFakeTablet(t, tme.wr, "cell1", 30, topodatapb.TabletType_MASTER, nil, TabletKeyspaceShard(t, "ks", "-80")) - tme.dest1Replica = newFakeTablet(t, tme.wr, "cell1", 31, topodatapb.TabletType_REPLICA, nil, TabletKeyspaceShard(t, "ks", "-80")) - tme.dest1Rdonly = newFakeTablet(t, tme.wr, "cell1", 32, topodatapb.TabletType_RDONLY, nil, TabletKeyspaceShard(t, "ks", "-80")) - - tme.dest2Master = newFakeTablet(t, tme.wr, "cell1", 40, topodatapb.TabletType_MASTER, nil, TabletKeyspaceShard(t, "ks", "80-")) - tme.dest2Replica = newFakeTablet(t, tme.wr, "cell1", 41, topodatapb.TabletType_REPLICA, nil, TabletKeyspaceShard(t, "ks", "80-")) - tme.dest2Rdonly = newFakeTablet(t, tme.wr, "cell1", 42, topodatapb.TabletType_RDONLY, nil, TabletKeyspaceShard(t, "ks", "80-")) - - vs := &vschemapb.Keyspace{Sharded: true} + vs := &vschemapb.Keyspace{ + Sharded: true, + Vindexes: map[string]*vschema.Vindex{ + "thash": { + Type: "hash", + }, + }, + Tables: map[string]*vschema.Table{ + "t1": { + ColumnVindexes: []*vschema.ColumnVindex{{ + Columns: []string{"c1"}, + Name: "thash", + }}, + }, + "t2": { + ColumnVindexes: []*vschema.ColumnVindex{{ + Columns: []string{"c1"}, + Name: "thash", + }}, + }, + "t3": { + ColumnVindexes: []*vschema.ColumnVindex{{ + Columns: []string{"c1"}, + Name: "thash", + }}, + }, + }, + } if err := tme.ts.SaveVSchema(ctx, "ks", vs); err != nil { t.Fatal(err) } @@ -232,166 +271,192 @@ func newTestShardMigrater(ctx context.Context, t *testing.T) *testMigraterEnv { tme.createDBClients(ctx, t) tme.setMasterPositions() - // Emulate the following replication streams (simultaneous split and merge): - // -40 -> -80 - // 40- -> -80 - // 40- -> 80- - // -40 will only have one target, and 80- will have only one source. - bls1 := &binlogdatapb.BinlogSource{ - Keyspace: "ks", - Shard: "-40", - Filter: &binlogdatapb.Filter{ - Rules: []*binlogdatapb.Rule{{ - Match: "/.*", - Filter: "-80", - }}, - }, - } - bls2 := &binlogdatapb.BinlogSource{ - Keyspace: "ks", - Shard: "40-", - Filter: &binlogdatapb.Filter{ - Rules: []*binlogdatapb.Rule{{ - Match: "/.*", - Filter: "-80", - }}, - }, - } - tme.dbDest1Client.addQuery(vreplQueryks, sqltypes.MakeTestResult(sqltypes.MakeTestFields( - "id|source", - "int64|varchar"), - fmt.Sprintf("1|%v", bls1), - fmt.Sprintf("2|%v", bls2), - ), nil) - bls3 := &binlogdatapb.BinlogSource{ - Keyspace: "ks", - Shard: "40-", - Filter: &binlogdatapb.Filter{ - Rules: []*binlogdatapb.Rule{{ - Match: "/.*", - Filter: "80-", - }}, - }, + for i, targetShard := range targetShards { + var rows []string + for j, sourceShard := range sourceShards { + if !key.KeyRangesIntersect(tme.targetKeyRanges[i], tme.sourceKeyRanges[j]) { + continue + } + bls := &binlogdatapb.BinlogSource{ + Keyspace: "ks", + Shard: sourceShard, + Filter: &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{{ + Match: "/.*", + Filter: targetShard, + }}, + }, + } + rows = append(rows, fmt.Sprintf("%d|%v|", j+1, bls)) + } + tme.dbTargetClients[i].addInvariant(vreplQueryks, sqltypes.MakeTestResult(sqltypes.MakeTestFields( + "id|source|message", + "int64|varchar|varchar"), + rows...), + ) } - tme.dbDest2Client.addQuery(vreplQueryks, sqltypes.MakeTestResult(sqltypes.MakeTestFields( - "id|source", - "int64|varchar"), - fmt.Sprintf("1|%v", bls3), - ), nil) tme.targetKeyspace = "ks" - tme.streams = map[string][]uint32{ - "-80": {1, 2}, - "80-": {1}, + for _, dbclient := range tme.dbSourceClients { + dbclient.addInvariant(vreplQueryks, &sqltypes.Result{}) } - tme.dbSource1Client.addQuery(vreplQueryks, &sqltypes.Result{}, nil) - tme.dbSource2Client.addQuery(vreplQueryks, &sqltypes.Result{}, nil) return tme } func (tme *testMigraterEnv) startTablets(t *testing.T) { - tme.source1Replica.StartActionLoop(t, tme.wr) - tme.source1Rdonly.StartActionLoop(t, tme.wr) - tme.source1Master.StartActionLoop(t, tme.wr) - - tme.source2Replica.StartActionLoop(t, tme.wr) - tme.source2Rdonly.StartActionLoop(t, tme.wr) - tme.source2Master.StartActionLoop(t, tme.wr) - - tme.dest1Replica.StartActionLoop(t, tme.wr) - tme.dest1Rdonly.StartActionLoop(t, tme.wr) - tme.dest1Master.StartActionLoop(t, tme.wr) - - tme.dest2Replica.StartActionLoop(t, tme.wr) - tme.dest2Rdonly.StartActionLoop(t, tme.wr) - tme.dest2Master.StartActionLoop(t, tme.wr) + for _, master := range tme.sourceMasters { + master.StartActionLoop(t, tme.wr) + } + for _, master := range tme.targetMasters { + master.StartActionLoop(t, tme.wr) + } } func (tme *testMigraterEnv) stopTablets(t *testing.T) { - tme.source1Replica.StopActionLoop(t) - tme.source1Rdonly.StopActionLoop(t) - tme.source1Master.StopActionLoop(t) - - tme.source2Replica.StopActionLoop(t) - tme.source2Rdonly.StopActionLoop(t) - tme.source2Master.StopActionLoop(t) - - tme.dest1Replica.StopActionLoop(t) - tme.dest1Rdonly.StopActionLoop(t) - tme.dest1Master.StopActionLoop(t) - - tme.dest2Replica.StopActionLoop(t) - tme.dest2Rdonly.StopActionLoop(t) - tme.dest2Master.StopActionLoop(t) + for _, master := range tme.sourceMasters { + master.StopActionLoop(t) + } + for _, master := range tme.targetMasters { + master.StopActionLoop(t) + } } func (tme *testMigraterEnv) createDBClients(ctx context.Context, t *testing.T) { - tme.dbDest1Client = newFakeDBClient() - dbClientFactory1 := func() binlogplayer.DBClient { return tme.dbDest1Client } - tme.dest1Master.Agent.VREngine = vreplication.NewEngine(tme.ts, "", tme.dest1Master.FakeMysqlDaemon, dbClientFactory1, tme.dbDest1Client.DBName()) - if err := tme.dest1Master.Agent.VREngine.Open(ctx); err != nil { - t.Fatal(err) + for _, master := range tme.sourceMasters { + dbclient := newFakeDBClient() + tme.dbSourceClients = append(tme.dbSourceClients, dbclient) + dbClientFactory := func() binlogplayer.DBClient { return dbclient } + master.Agent.VREngine = vreplication.NewEngine(tme.ts, "", master.FakeMysqlDaemon, dbClientFactory, dbclient.DBName()) + if err := master.Agent.VREngine.Open(ctx); err != nil { + t.Fatal(err) + } } + for _, master := range tme.targetMasters { + dbclient := newFakeDBClient() + tme.dbTargetClients = append(tme.dbTargetClients, dbclient) + dbClientFactory := func() binlogplayer.DBClient { return dbclient } + master.Agent.VREngine = vreplication.NewEngine(tme.ts, "", master.FakeMysqlDaemon, dbClientFactory, dbclient.DBName()) + if err := master.Agent.VREngine.Open(ctx); err != nil { + t.Fatal(err) + } + } + tme.allDBClients = append(tme.dbSourceClients, tme.dbTargetClients...) +} - tme.dbDest2Client = newFakeDBClient() - dbClientFactory2 := func() binlogplayer.DBClient { return tme.dbDest2Client } - tme.dest2Master.Agent.VREngine = vreplication.NewEngine(tme.ts, "", tme.dest2Master.FakeMysqlDaemon, dbClientFactory2, tme.dbDest2Client.DBName()) - if err := tme.dest2Master.Agent.VREngine.Open(ctx); err != nil { - t.Fatal(err) +func (tme *testMigraterEnv) setMasterPositions() { + for _, master := range tme.sourceMasters { + master.FakeMysqlDaemon.CurrentMasterPosition = mysql.Position{ + GTIDSet: mysql.MariadbGTIDSet{ + mysql.MariadbGTID{ + Domain: 5, + Server: 456, + Sequence: 892, + }, + }, + } } + for _, master := range tme.targetMasters { + master.FakeMysqlDaemon.CurrentMasterPosition = mysql.Position{ + GTIDSet: mysql.MariadbGTIDSet{ + mysql.MariadbGTID{ + Domain: 5, + Server: 456, + Sequence: 893, + }, + }, + } + } +} - tme.dbSource1Client = newFakeDBClient() - dbClientFactory3 := func() binlogplayer.DBClient { return tme.dbSource1Client } - tme.source1Master.Agent.VREngine = vreplication.NewEngine(tme.ts, "", tme.source1Master.FakeMysqlDaemon, dbClientFactory3, tme.dbSource1Client.DBName()) - if err := tme.source1Master.Agent.VREngine.Open(ctx); err != nil { - t.Fatal(err) +func (tme *testShardMigraterEnv) forAllStreams(f func(i, j int)) { + for i := range tme.targetShards { + for j := range tme.sourceShards { + if !key.KeyRangesIntersect(tme.targetKeyRanges[i], tme.sourceKeyRanges[j]) { + continue + } + f(i, j) + } } +} - tme.dbSource2Client = newFakeDBClient() - dbClientFactory4 := func() binlogplayer.DBClient { return tme.dbSource2Client } - tme.source2Master.Agent.VREngine = vreplication.NewEngine(tme.ts, "", tme.source2Master.FakeMysqlDaemon, dbClientFactory4, tme.dbSource2Client.DBName()) - if err := tme.source2Master.Agent.VREngine.Open(ctx); err != nil { - t.Fatal(err) +func (tme *testShardMigraterEnv) expectCheckJournals() { + for _, dbclient := range tme.dbSourceClients { + dbclient.addQueryRE("select val from _vt.resharding_journal where id=.*", &sqltypes.Result{}, nil) } +} - tme.allDBClients = []*fakeDBClient{tme.dbDest1Client, tme.dbDest2Client, tme.dbSource1Client, tme.dbSource2Client} +func (tme *testShardMigraterEnv) expectWaitForCatchup() { + state := sqltypes.MakeTestResult(sqltypes.MakeTestFields( + "pos|state|message", + "varchar|varchar|varchar"), + "MariaDB/5-456-892|Running", + ) + tme.forAllStreams(func(i, j int) { + tme.dbTargetClients[i].addQuery(fmt.Sprintf("select pos, state, message from _vt.vreplication where id=%d", j+1), state, nil) + + // mi.waitForCatchup-> mi.wr.tmc.VReplicationExec('stopped for cutover') + tme.dbTargetClients[i].addQuery(fmt.Sprintf("select id from _vt.vreplication where id = %d", j+1), &sqltypes.Result{Rows: [][]sqltypes.Value{{sqltypes.NewInt64(int64(j + 1))}}}, nil) + tme.dbTargetClients[i].addQuery(fmt.Sprintf("update _vt.vreplication set state = 'Stopped', message = 'stopped for cutover' where id in (%d)", j+1), &sqltypes.Result{}, nil) + tme.dbTargetClients[i].addQuery(fmt.Sprintf("select * from _vt.vreplication where id = %d", j+1), stoppedResult(j+1), nil) + }) } -func (tme *testMigraterEnv) setMasterPositions() { - tme.source1Master.FakeMysqlDaemon.CurrentMasterPosition = mysql.Position{ - GTIDSet: mysql.MariadbGTIDSet{ - mysql.MariadbGTID{ - Domain: 5, - Server: 456, - Sequence: 892, - }, - }, +func (tme *testShardMigraterEnv) expectDeleteReverseVReplication() { + // NOTE: this is not a faithful reproduction of what should happen. + // The ids returned are not accurate. + for _, dbclient := range tme.dbSourceClients { + dbclient.addQuery("select id from _vt.vreplication where db_name = 'vt_ks' and workflow = 'test_reverse'", resultid12, nil) + dbclient.addQuery("delete from _vt.vreplication where id in (1, 2)", &sqltypes.Result{}, nil) + dbclient.addQuery("delete from _vt.copy_state where vrepl_id in (1, 2)", &sqltypes.Result{}, nil) } - tme.source2Master.FakeMysqlDaemon.CurrentMasterPosition = mysql.Position{ - GTIDSet: mysql.MariadbGTIDSet{ - mysql.MariadbGTID{ - Domain: 5, - Server: 456, - Sequence: 892, - }, - }, +} + +func (tme *testShardMigraterEnv) expectCreateReverseVReplication() { + tme.expectDeleteReverseVReplication() + tme.forAllStreams(func(i, j int) { + tme.dbSourceClients[j].addQueryRE(fmt.Sprintf("insert into _vt.vreplication.*%s.*%s.*MariaDB/5-456-893.*Stopped", tme.targetShards[i], key.KeyRangeString(tme.sourceKeyRanges[j])), &sqltypes.Result{InsertID: uint64(j + 1)}, nil) + tme.dbSourceClients[j].addQuery(fmt.Sprintf("select * from _vt.vreplication where id = %d", j+1), stoppedResult(j+1), nil) + }) +} + +func (tme *testShardMigraterEnv) expectCreateJournals() { + for _, dbclient := range tme.dbSourceClients { + dbclient.addQueryRE("insert into _vt.resharding_journal.*", &sqltypes.Result{}, nil) } - tme.dest1Master.FakeMysqlDaemon.CurrentMasterPosition = mysql.Position{ - GTIDSet: mysql.MariadbGTIDSet{ - mysql.MariadbGTID{ - Domain: 5, - Server: 456, - Sequence: 893, - }, - }, +} + +func (tme *testShardMigraterEnv) expectStartReverseVReplication() { + // NOTE: this is not a faithful reproduction of what should happen. + // The ids returned are not accurate. + for _, dbclient := range tme.dbSourceClients { + dbclient.addQuery("select id from _vt.vreplication where db_name = 'vt_ks'", resultid34, nil) + dbclient.addQuery("update _vt.vreplication set state = 'Running', message = '' where id in (3, 4)", &sqltypes.Result{}, nil) + dbclient.addQuery("select * from _vt.vreplication where id = 3", runningResult(3), nil) + dbclient.addQuery("select * from _vt.vreplication where id = 4", runningResult(4), nil) } - tme.dest2Master.FakeMysqlDaemon.CurrentMasterPosition = mysql.Position{ - GTIDSet: mysql.MariadbGTIDSet{ - mysql.MariadbGTID{ - Domain: 5, - Server: 456, - Sequence: 893, - }, - }, +} + +func (tme *testShardMigraterEnv) expectDeleteTargetVReplication() { + // NOTE: this is not a faithful reproduction of what should happen. + // The ids returned are not accurate. + for _, dbclient := range tme.dbTargetClients { + dbclient.addQuery("select id from _vt.vreplication where db_name = 'vt_ks' and workflow = 'test'", resultid12, nil) + dbclient.addQuery("update _vt.vreplication set message = 'FROZEN' where id in (1, 2)", &sqltypes.Result{}, nil) + dbclient.addQuery("select * from _vt.vreplication where id = 1", stoppedResult(1), nil) + dbclient.addQuery("select * from _vt.vreplication where id = 2", stoppedResult(2), nil) + + dbclient.addQuery("select id from _vt.vreplication where db_name = 'vt_ks' and workflow = 'test'", resultid12, nil) + dbclient.addQuery("delete from _vt.vreplication where id in (1, 2)", &sqltypes.Result{}, nil) + dbclient.addQuery("delete from _vt.copy_state where vrepl_id in (1, 2)", &sqltypes.Result{}, nil) + } +} + +func (tme *testShardMigraterEnv) expectCancelMigration() { + for _, dbclient := range tme.dbTargetClients { + dbclient.addQuery("select id from _vt.vreplication where db_name = 'vt_ks' and workflow = 'test'", &sqltypes.Result{}, nil) + } + for _, dbclient := range tme.dbSourceClients { + dbclient.addQuery("select id from _vt.vreplication where db_name = 'vt_ks' and workflow != 'test_reverse'", &sqltypes.Result{}, nil) } + tme.expectDeleteReverseVReplication() } diff --git a/go/vt/wrangler/migrater_test.go b/go/vt/wrangler/migrater_test.go index 0e9f25995de..042d5ad09f2 100644 --- a/go/vt/wrangler/migrater_test.go +++ b/go/vt/wrangler/migrater_test.go @@ -31,9 +31,39 @@ import ( "vitess.io/vitess/go/vt/topo" ) +var ( + resultid1 = &sqltypes.Result{Rows: [][]sqltypes.Value{{sqltypes.NewInt64(1)}}} + resultid2 = &sqltypes.Result{Rows: [][]sqltypes.Value{{sqltypes.NewInt64(2)}}} + resultid3 = &sqltypes.Result{Rows: [][]sqltypes.Value{{sqltypes.NewInt64(3)}}} + resultid12 = &sqltypes.Result{Rows: [][]sqltypes.Value{{sqltypes.NewInt64(1)}, {sqltypes.NewInt64(2)}}} + resultid1234 = &sqltypes.Result{ + Rows: [][]sqltypes.Value{{ + sqltypes.NewInt64(1), + }, { + sqltypes.NewInt64(2), + }, { + sqltypes.NewInt64(3), + }, { + sqltypes.NewInt64(4), + }}, + } + resultid34 = &sqltypes.Result{Rows: [][]sqltypes.Value{{sqltypes.NewInt64(3)}, {sqltypes.NewInt64(4)}}} + resultid3456 = &sqltypes.Result{ + Rows: [][]sqltypes.Value{{ + sqltypes.NewInt64(3), + }, { + sqltypes.NewInt64(4), + }, { + sqltypes.NewInt64(5), + }, { + sqltypes.NewInt64(6), + }}, + } +) + // TestTableMigrate tests table mode migrations. // This has to be kept in sync with TestShardMigrate. -func TestTableMigrate(t *testing.T) { +func TestTableMigrateMainflow(t *testing.T) { ctx := context.Background() tme := newTestTableMigrater(ctx, t) defer tme.stopTablets(t) @@ -204,7 +234,7 @@ func TestTableMigrate(t *testing.T) { //------------------------------------------------------------------------------------------------------------------- // Can't migrate writes if REPLICA and RDONLY have not fully migrated yet. - _, err = tme.wr.MigrateWrites(ctx, tme.targetKeyspace, "test", 1*time.Second) + _, err = tme.wr.MigrateWrites(ctx, tme.targetKeyspace, "test", 1*time.Second, false, true) want = "missing tablet type specific routing, read-only traffic must be migrated before migrating writes" if err == nil || !strings.Contains(err.Error(), want) { t.Errorf("MigrateWrites err: %v, want %v", err, want) @@ -242,43 +272,40 @@ func TestTableMigrate(t *testing.T) { "ks1.t2@rdonly": {"ks2.t2"}, }) - // Check for journals. - tme.dbSource1Client.addQuery("select 1 from _vt.resharding_journal where id = 9113431017721636330", &sqltypes.Result{}, nil) - tme.dbSource2Client.addQuery("select 1 from _vt.resharding_journal where id = 9113431017721636330", &sqltypes.Result{}, nil) + checkJournals := func() { + tme.dbSourceClients[0].addQuery("select val from _vt.resharding_journal where id=7672494164556733923", &sqltypes.Result{}, nil) + tme.dbSourceClients[1].addQuery("select val from _vt.resharding_journal where id=7672494164556733923", &sqltypes.Result{}, nil) + } + checkJournals() - // Wait for position: Reads current state, updates to Stopped, and re-reads. - state := sqltypes.MakeTestResult(sqltypes.MakeTestFields( - "pos|state|message", - "varchar|varchar|varchar"), - "MariaDB/5-456-892|Running|", - ) - tme.dbDest1Client.addQuery("select pos, state, message from _vt.vreplication where id=1", state, nil) - tme.dbDest2Client.addQuery("select pos, state, message from _vt.vreplication where id=1", state, nil) - tme.dbDest1Client.addQuery("select pos, state, message from _vt.vreplication where id=2", state, nil) - tme.dbDest1Client.addQuery("update _vt.vreplication set state = 'Stopped', message = 'stopped for cutover' where id = 1", &sqltypes.Result{}, nil) - tme.dbDest2Client.addQuery("update _vt.vreplication set state = 'Stopped', message = 'stopped for cutover' where id = 1", &sqltypes.Result{}, nil) - tme.dbDest1Client.addQuery("update _vt.vreplication set state = 'Stopped', message = 'stopped for cutover' where id = 2", &sqltypes.Result{}, nil) - stopped := sqltypes.MakeTestResult(sqltypes.MakeTestFields( - "id|state", - "int64|varchar"), - "1|Stopped", - ) - tme.dbDest1Client.addQuery("select * from _vt.vreplication where id = 1", stopped, nil) - tme.dbDest2Client.addQuery("select * from _vt.vreplication where id = 1", stopped, nil) - tme.dbDest1Client.addQuery("select * from _vt.vreplication where id = 2", stopped, nil) - - // Cancel Migration - cancel1 := "update _vt.vreplication set state = 'Running', stop_pos = null where id = 1" - cancel2 := "update _vt.vreplication set state = 'Running', stop_pos = null where id = 2" - tme.dbDest1Client.addQuery(cancel1, &sqltypes.Result{}, nil) - tme.dbDest2Client.addQuery(cancel1, &sqltypes.Result{}, nil) - tme.dbDest1Client.addQuery(cancel2, &sqltypes.Result{}, nil) - - _, err = tme.wr.MigrateWrites(ctx, tme.targetKeyspace, "test", 0*time.Second) + deleteReverseReplicaion := func() { + tme.dbSourceClients[0].addQuery("select id from _vt.vreplication where db_name = 'vt_ks1' and workflow = 'test_reverse'", resultid34, nil) + tme.dbSourceClients[1].addQuery("select id from _vt.vreplication where db_name = 'vt_ks1' and workflow = 'test_reverse'", resultid34, nil) + tme.dbSourceClients[0].addQuery("delete from _vt.vreplication where id in (3, 4)", &sqltypes.Result{}, nil) + tme.dbSourceClients[1].addQuery("delete from _vt.vreplication where id in (3, 4)", &sqltypes.Result{}, nil) + tme.dbSourceClients[0].addQuery("delete from _vt.copy_state where vrepl_id in (3, 4)", &sqltypes.Result{}, nil) + tme.dbSourceClients[1].addQuery("delete from _vt.copy_state where vrepl_id in (3, 4)", &sqltypes.Result{}, nil) + } + cancelMigration := func() { + tme.dbTargetClients[0].addQuery("select id from _vt.vreplication where db_name = 'vt_ks2' and workflow = 'test'", resultid12, nil) + tme.dbTargetClients[1].addQuery("select id from _vt.vreplication where db_name = 'vt_ks2' and workflow = 'test'", resultid12, nil) + tme.dbTargetClients[0].addQuery("update _vt.vreplication set state = 'Running', message = '' where id in (1, 2)", &sqltypes.Result{}, nil) + tme.dbTargetClients[1].addQuery("update _vt.vreplication set state = 'Running', message = '' where id in (1, 2)", &sqltypes.Result{}, nil) + tme.dbTargetClients[0].addQuery("select * from _vt.vreplication where id = 1", runningResult(1), nil) + tme.dbTargetClients[0].addQuery("select * from _vt.vreplication where id = 2", runningResult(2), nil) + tme.dbTargetClients[1].addQuery("select * from _vt.vreplication where id = 1", runningResult(1), nil) + tme.dbTargetClients[1].addQuery("select * from _vt.vreplication where id = 2", runningResult(2), nil) + + deleteReverseReplicaion() + } + cancelMigration() + + _, err = tme.wr.MigrateWrites(ctx, tme.targetKeyspace, "test", 0*time.Second, false, true) want = "DeadlineExceeded" if err == nil || !strings.Contains(err.Error(), want) { t.Errorf("MigrateWrites(0 timeout) err: %v, must contain %v", err, want) } + verifyQueries(t, tme.allDBClients) checkRouting(t, tme.wr, map[string][]string{ "t1": {"ks1.t1"}, "ks2.t1": {"ks1.t1"}, @@ -305,31 +332,95 @@ func TestTableMigrate(t *testing.T) { //------------------------------------------------------------------------------------------------------------------- // Test successful MigrateWrites. - // Create journals. - journal1 := "insert into _vt.resharding_journal.*9113431017721636330.*tables.*t1.*t2.*local_position.*MariaDB/5-456-892.*shard_gtids.*-80.*MariaDB/5-456-893.*participants.*40.*40" - tme.dbSource1Client.addQueryRE(journal1, &sqltypes.Result{}, nil) - journal2 := "insert into _vt.resharding_journal.*9113431017721636330.*tables.*t1.*t2.*local_position.*MariaDB/5-456-892.*shard_gtids.*80.*MariaDB/5-456-893.*80.*participants.*40.*40" - tme.dbSource2Client.addQueryRE(journal2, &sqltypes.Result{}, nil) - - // Create backward replicaions. - tme.dbSource1Client.addQueryRE("insert into _vt.vreplication.*ks2.*-80.*t1.*in_keyrange.*c1.*hash.*-40.*t2.*-40.*MariaDB/5-456-893.*Stopped", &sqltypes.Result{InsertID: 1}, nil) - tme.dbSource2Client.addQueryRE("insert into _vt.vreplication.*ks2.*-80.*t1.*in_keyrange.*c1.*hash.*40-.*t2.*40-.*MariaDB/5-456-893.*Stopped", &sqltypes.Result{InsertID: 1}, nil) - tme.dbSource2Client.addQueryRE("insert into _vt.vreplication.*ks2.*80-.*t1.*in_keyrange.*c1.*hash.*40-.*t2.*40-.*MariaDB/5-456-893.*Stopped", &sqltypes.Result{InsertID: 2}, nil) - tme.dbSource1Client.addQuery("select * from _vt.vreplication where id = 1", stopped, nil) - tme.dbSource2Client.addQuery("select * from _vt.vreplication where id = 1", stopped, nil) - tme.dbSource2Client.addQuery("select * from _vt.vreplication where id = 2", stopped, nil) - - // Delete the target replications. - tme.dbDest1Client.addQuery("delete from _vt.vreplication where id = 1", &sqltypes.Result{}, nil) - tme.dbDest2Client.addQuery("delete from _vt.vreplication where id = 1", &sqltypes.Result{}, nil) - tme.dbDest1Client.addQuery("delete from _vt.vreplication where id = 2", &sqltypes.Result{}, nil) - - journalID, err := tme.wr.MigrateWrites(ctx, tme.targetKeyspace, "test", 1*time.Second) + checkJournals() + + waitForCatchup := func() { + // mi.waitForCatchup-> mi.wr.tmc.VReplicationWaitForPos + state := sqltypes.MakeTestResult(sqltypes.MakeTestFields( + "pos|state|message", + "varchar|varchar|varchar"), + "MariaDB/5-456-892|Running", + ) + tme.dbTargetClients[0].addQuery("select pos, state, message from _vt.vreplication where id=1", state, nil) + tme.dbTargetClients[0].addQuery("select pos, state, message from _vt.vreplication where id=2", state, nil) + tme.dbTargetClients[1].addQuery("select pos, state, message from _vt.vreplication where id=1", state, nil) + tme.dbTargetClients[1].addQuery("select pos, state, message from _vt.vreplication where id=2", state, nil) + + // mi.waitForCatchup-> mi.wr.tmc.VReplicationExec('Stopped') + tme.dbTargetClients[0].addQuery("select id from _vt.vreplication where id = 1", resultid1, nil) + tme.dbTargetClients[0].addQuery("update _vt.vreplication set state = 'Stopped', message = 'stopped for cutover' where id in (1)", &sqltypes.Result{}, nil) + tme.dbTargetClients[0].addQuery("select id from _vt.vreplication where id = 2", resultid2, nil) + tme.dbTargetClients[0].addQuery("update _vt.vreplication set state = 'Stopped', message = 'stopped for cutover' where id in (2)", &sqltypes.Result{}, nil) + tme.dbTargetClients[1].addQuery("select id from _vt.vreplication where id = 1", resultid1, nil) + tme.dbTargetClients[1].addQuery("update _vt.vreplication set state = 'Stopped', message = 'stopped for cutover' where id in (1)", &sqltypes.Result{}, nil) + tme.dbTargetClients[1].addQuery("select id from _vt.vreplication where id = 2", resultid2, nil) + tme.dbTargetClients[1].addQuery("update _vt.vreplication set state = 'Stopped', message = 'stopped for cutover' where id in (2)", &sqltypes.Result{}, nil) + tme.dbTargetClients[0].addQuery("select * from _vt.vreplication where id = 1", stoppedResult(1), nil) + tme.dbTargetClients[0].addQuery("select * from _vt.vreplication where id = 2", stoppedResult(2), nil) + tme.dbTargetClients[1].addQuery("select * from _vt.vreplication where id = 1", stoppedResult(1), nil) + tme.dbTargetClients[1].addQuery("select * from _vt.vreplication where id = 2", stoppedResult(2), nil) + } + waitForCatchup() + + createReverseVReplication := func() { + deleteReverseReplicaion() + + tme.dbSourceClients[0].addQueryRE("insert into _vt.vreplication.*test_reverse.*ks2.*-80.*t1.*in_keyrange.*c1.*hash.*-40.*t2.*-40.*MariaDB/5-456-893.*Stopped", &sqltypes.Result{InsertID: 1}, nil) + tme.dbSourceClients[0].addQueryRE("insert into _vt.vreplication.*test_reverse.*ks2.*80-.*t1.*in_keyrange.*c1.*hash.*-40.*t2.*-40.*MariaDB/5-456-893.*Stopped", &sqltypes.Result{InsertID: 2}, nil) + tme.dbSourceClients[1].addQueryRE("insert into _vt.vreplication.*test_reverse.*ks2.*-80.*t1.*in_keyrange.*c1.*hash.*40-.*t2.*40-.*MariaDB/5-456-893.*Stopped", &sqltypes.Result{InsertID: 1}, nil) + tme.dbSourceClients[1].addQueryRE("insert into _vt.vreplication.*test_reverse.*ks2.*80-.*t1.*in_keyrange.*c1.*hash.*40-.*t2.*40-.*MariaDB/5-456-893.*Stopped", &sqltypes.Result{InsertID: 2}, nil) + tme.dbSourceClients[0].addQuery("select * from _vt.vreplication where id = 1", stoppedResult(1), nil) + tme.dbSourceClients[0].addQuery("select * from _vt.vreplication where id = 2", stoppedResult(2), nil) + tme.dbSourceClients[1].addQuery("select * from _vt.vreplication where id = 1", stoppedResult(1), nil) + tme.dbSourceClients[1].addQuery("select * from _vt.vreplication where id = 2", stoppedResult(2), nil) + } + createReverseVReplication() + + createJournals := func() { + journal1 := "insert into _vt.resharding_journal.*7672494164556733923,.*tables.*t1.*t2.*local_position.*MariaDB/5-456-892.*shard_gtids.*-80.*MariaDB/5-456-893.*participants.*40.*40" + tme.dbSourceClients[0].addQueryRE(journal1, &sqltypes.Result{}, nil) + journal2 := "insert into _vt.resharding_journal.*7672494164556733923,.*tables.*t1.*t2.*local_position.*MariaDB/5-456-892.*shard_gtids.*80.*MariaDB/5-456-893.*80.*participants.*40.*40" + tme.dbSourceClients[1].addQueryRE(journal2, &sqltypes.Result{}, nil) + } + createJournals() + + startReverseVReplication := func() { + tme.dbSourceClients[0].addQuery("select id from _vt.vreplication where db_name = 'vt_ks1'", resultid34, nil) + tme.dbSourceClients[0].addQuery("update _vt.vreplication set state = 'Running', message = '' where id in (3, 4)", &sqltypes.Result{}, nil) + tme.dbSourceClients[0].addQuery("select * from _vt.vreplication where id = 3", runningResult(3), nil) + tme.dbSourceClients[0].addQuery("select * from _vt.vreplication where id = 4", runningResult(4), nil) + tme.dbSourceClients[1].addQuery("select id from _vt.vreplication where db_name = 'vt_ks1'", resultid34, nil) + tme.dbSourceClients[1].addQuery("update _vt.vreplication set state = 'Running', message = '' where id in (3, 4)", &sqltypes.Result{}, nil) + tme.dbSourceClients[1].addQuery("select * from _vt.vreplication where id = 3", runningResult(3), nil) + tme.dbSourceClients[1].addQuery("select * from _vt.vreplication where id = 4", runningResult(4), nil) + } + startReverseVReplication() + + deleteTargetVReplication := func() { + tme.dbTargetClients[0].addQuery("select id from _vt.vreplication where db_name = 'vt_ks2' and workflow = 'test'", resultid12, nil) + tme.dbTargetClients[1].addQuery("select id from _vt.vreplication where db_name = 'vt_ks2' and workflow = 'test'", resultid12, nil) + tme.dbTargetClients[0].addQuery("update _vt.vreplication set message = 'FROZEN' where id in (1, 2)", &sqltypes.Result{}, nil) + tme.dbTargetClients[0].addQuery("select * from _vt.vreplication where id = 1", stoppedResult(1), nil) + tme.dbTargetClients[0].addQuery("select * from _vt.vreplication where id = 2", stoppedResult(2), nil) + tme.dbTargetClients[1].addQuery("update _vt.vreplication set message = 'FROZEN' where id in (1, 2)", &sqltypes.Result{}, nil) + tme.dbTargetClients[1].addQuery("select * from _vt.vreplication where id = 1", stoppedResult(1), nil) + tme.dbTargetClients[1].addQuery("select * from _vt.vreplication where id = 2", stoppedResult(2), nil) + + tme.dbTargetClients[0].addQuery("select id from _vt.vreplication where db_name = 'vt_ks2' and workflow = 'test'", resultid12, nil) + tme.dbTargetClients[1].addQuery("select id from _vt.vreplication where db_name = 'vt_ks2' and workflow = 'test'", resultid12, nil) + tme.dbTargetClients[0].addQuery("delete from _vt.vreplication where id in (1, 2)", &sqltypes.Result{}, nil) + tme.dbTargetClients[0].addQuery("delete from _vt.copy_state where vrepl_id in (1, 2)", &sqltypes.Result{}, nil) + tme.dbTargetClients[1].addQuery("delete from _vt.vreplication where id in (1, 2)", &sqltypes.Result{}, nil) + tme.dbTargetClients[1].addQuery("delete from _vt.copy_state where vrepl_id in (1, 2)", &sqltypes.Result{}, nil) + } + deleteTargetVReplication() + + journalID, err := tme.wr.MigrateWrites(ctx, tme.targetKeyspace, "test", 1*time.Second, false, true) if err != nil { t.Fatal(err) } - if journalID != 9113431017721636330 { - t.Errorf("journal id: %d, want 9113431017721636330", journalID) + if journalID != 7672494164556733923 { + t.Errorf("journal id: %d, want 7672494164556733923", journalID) } checkRouting(t, tme.wr, map[string][]string{ @@ -348,9 +439,9 @@ func TestTableMigrate(t *testing.T) { // TestShardMigrate tests table mode migrations. // This has to be kept in sync with TestTableMigrate. -func TestShardMigrate(t *testing.T) { +func TestShardMigrateMainflow(t *testing.T) { ctx := context.Background() - tme := newTestShardMigrater(ctx, t) + tme := newTestShardMigrater(ctx, t, []string{"-40", "40-"}, []string{"-80", "80-"}) defer tme.stopTablets(t) // Initial check @@ -457,7 +548,7 @@ func TestShardMigrate(t *testing.T) { //------------------------------------------------------------------------------------------------------------------- // Can't migrate writes if REPLICA and RDONLY have not fully migrated yet. - _, err = tme.wr.MigrateWrites(ctx, tme.targetKeyspace, "test", 1*time.Second) + _, err = tme.wr.MigrateWrites(ctx, tme.targetKeyspace, "test", 1*time.Second, false, true) want = "cannot migrate MASTER away" if err == nil || !strings.Contains(err.Error(), want) { t.Errorf("MigrateWrites err: %v, want %v", err, want) @@ -481,43 +572,52 @@ func TestShardMigrate(t *testing.T) { checkIsMasterServing(t, tme.ts, "ks:-80", false) checkIsMasterServing(t, tme.ts, "ks:80-", false) - // Check for journals. - tme.dbSource1Client.addQuery("select 1 from _vt.resharding_journal where id = 6432976123657117098", &sqltypes.Result{}, nil) - tme.dbSource2Client.addQuery("select 1 from _vt.resharding_journal where id = 6432976123657117098", &sqltypes.Result{}, nil) + checkJournals := func() { + tme.dbSourceClients[0].addQuery("select val from _vt.resharding_journal where id=6432976123657117097", &sqltypes.Result{}, nil) + tme.dbSourceClients[1].addQuery("select val from _vt.resharding_journal where id=6432976123657117097", &sqltypes.Result{}, nil) + } + checkJournals() - // Wait for position: Reads current state, updates to Stopped, and re-reads. - state := sqltypes.MakeTestResult(sqltypes.MakeTestFields( - "pos|state|message", - "varchar|varchar|varchar"), - "MariaDB/5-456-892|Running|", - ) - tme.dbDest1Client.addQuery("select pos, state, message from _vt.vreplication where id=1", state, nil) - tme.dbDest2Client.addQuery("select pos, state, message from _vt.vreplication where id=1", state, nil) - tme.dbDest1Client.addQuery("select pos, state, message from _vt.vreplication where id=2", state, nil) - tme.dbDest1Client.addQuery("update _vt.vreplication set state = 'Stopped', message = 'stopped for cutover' where id = 1", &sqltypes.Result{}, nil) - tme.dbDest2Client.addQuery("update _vt.vreplication set state = 'Stopped', message = 'stopped for cutover' where id = 1", &sqltypes.Result{}, nil) - tme.dbDest1Client.addQuery("update _vt.vreplication set state = 'Stopped', message = 'stopped for cutover' where id = 2", &sqltypes.Result{}, nil) - stopped := sqltypes.MakeTestResult(sqltypes.MakeTestFields( - "id|state", - "int64|varchar"), - "1|Stopped", - ) - tme.dbDest1Client.addQuery("select * from _vt.vreplication where id = 1", stopped, nil) - tme.dbDest2Client.addQuery("select * from _vt.vreplication where id = 1", stopped, nil) - tme.dbDest1Client.addQuery("select * from _vt.vreplication where id = 2", stopped, nil) - - // Cancel Migration - cancel1 := "update _vt.vreplication set state = 'Running', stop_pos = null where id = 1" - cancel2 := "update _vt.vreplication set state = 'Running', stop_pos = null where id = 2" - tme.dbDest1Client.addQuery(cancel1, &sqltypes.Result{}, nil) - tme.dbDest2Client.addQuery(cancel1, &sqltypes.Result{}, nil) - tme.dbDest1Client.addQuery(cancel2, &sqltypes.Result{}, nil) - - _, err = tme.wr.MigrateWrites(ctx, tme.targetKeyspace, "test", 0*time.Second) + stopStreams := func() { + tme.dbSourceClients[0].addQuery("select id, workflow, source, pos from _vt.vreplication where db_name='vt_ks' and workflow != 'test_reverse' and state = 'Stopped'", &sqltypes.Result{}, nil) + tme.dbSourceClients[1].addQuery("select id, workflow, source, pos from _vt.vreplication where db_name='vt_ks' and workflow != 'test_reverse' and state = 'Stopped'", &sqltypes.Result{}, nil) + tme.dbSourceClients[0].addQuery("select id, workflow, source, pos from _vt.vreplication where db_name='vt_ks' and workflow != 'test_reverse'", &sqltypes.Result{}, nil) + tme.dbSourceClients[1].addQuery("select id, workflow, source, pos from _vt.vreplication where db_name='vt_ks' and workflow != 'test_reverse'", &sqltypes.Result{}, nil) + } + stopStreams() + + deleteReverseReplicaion := func() { + tme.dbSourceClients[0].addQuery("select id from _vt.vreplication where db_name = 'vt_ks' and workflow = 'test_reverse'", resultid3, nil) + tme.dbSourceClients[1].addQuery("select id from _vt.vreplication where db_name = 'vt_ks' and workflow = 'test_reverse'", resultid34, nil) + tme.dbSourceClients[0].addQuery("delete from _vt.vreplication where id in (3)", &sqltypes.Result{}, nil) + tme.dbSourceClients[1].addQuery("delete from _vt.vreplication where id in (3, 4)", &sqltypes.Result{}, nil) + tme.dbSourceClients[0].addQuery("delete from _vt.copy_state where vrepl_id in (3)", &sqltypes.Result{}, nil) + tme.dbSourceClients[1].addQuery("delete from _vt.copy_state where vrepl_id in (3, 4)", &sqltypes.Result{}, nil) + } + cancelMigration := func() { + tme.dbSourceClients[0].addQuery("select id from _vt.vreplication where db_name = 'vt_ks' and workflow != 'test_reverse'", &sqltypes.Result{}, nil) + tme.dbSourceClients[1].addQuery("select id from _vt.vreplication where db_name = 'vt_ks' and workflow != 'test_reverse'", &sqltypes.Result{}, nil) + + tme.dbTargetClients[0].addQuery("select id from _vt.vreplication where db_name = 'vt_ks' and workflow = 'test'", resultid12, nil) + tme.dbTargetClients[1].addQuery("select id from _vt.vreplication where db_name = 'vt_ks' and workflow = 'test'", resultid2, nil) + tme.dbTargetClients[0].addQuery("update _vt.vreplication set state = 'Running', message = '' where id in (1, 2)", &sqltypes.Result{}, nil) + tme.dbTargetClients[1].addQuery("update _vt.vreplication set state = 'Running', message = '' where id in (2)", &sqltypes.Result{}, nil) + tme.dbTargetClients[0].addQuery("select * from _vt.vreplication where id = 1", runningResult(1), nil) + tme.dbTargetClients[0].addQuery("select * from _vt.vreplication where id = 2", runningResult(2), nil) + tme.dbTargetClients[1].addQuery("select * from _vt.vreplication where id = 2", runningResult(2), nil) + + deleteReverseReplicaion() + } + cancelMigration() + + _, err = tme.wr.MigrateWrites(ctx, tme.targetKeyspace, "test", 0*time.Second, false, true) want = "DeadlineExceeded" if err == nil || !strings.Contains(err.Error(), want) { t.Errorf("MigrateWrites(0 timeout) err: %v, must contain %v", err, want) } + + verifyQueries(t, tme.allDBClients) + checkServedTypes(t, tme.ts, "ks:-40", 1) checkServedTypes(t, tme.ts, "ks:40-", 1) checkServedTypes(t, tme.ts, "ks:-80", 2) @@ -530,33 +630,93 @@ func TestShardMigrate(t *testing.T) { //------------------------------------------------------------------------------------------------------------------- // Test successful MigrateWrites. - // Create journals. - journal1 := "insert into _vt.resharding_journal.*6432976123657117098.*migration_type:SHARDS.*local_position.*MariaDB/5-456-892.*shard_gtids.*-80.*MariaDB/5-456-893.*participants.*40.*40" - tme.dbSource1Client.addQueryRE(journal1, &sqltypes.Result{}, nil) - journal2 := "insert into _vt.resharding_journal.*6432976123657117098.*migration_type:SHARDS.*local_position.*MariaDB/5-456-892.*shard_gtids.*80.*MariaDB/5-456-893.*shard_gtids.*80.*MariaDB/5-456-893.*participants.*40.*40" - tme.dbSource2Client.addQueryRE(journal2, &sqltypes.Result{}, nil) - - // Create backward replicaions. - tme.dbSource1Client.addQueryRE("insert into _vt.vreplication.*-80.*-40.*MariaDB/5-456-893.*Stopped", &sqltypes.Result{InsertID: 1}, nil) - tme.dbSource2Client.addQueryRE("insert into _vt.vreplication.*-80.*40-.*MariaDB/5-456-893.*Stopped", &sqltypes.Result{InsertID: 1}, nil) - tme.dbSource2Client.addQueryRE("insert into _vt.vreplication.*80-.*40-.*MariaDB/5-456-893.*Stopped", &sqltypes.Result{InsertID: 2}, nil) - tme.dbSource1Client.addQuery("select * from _vt.vreplication where id = 1", stopped, nil) - tme.dbSource2Client.addQuery("select * from _vt.vreplication where id = 1", stopped, nil) - tme.dbSource2Client.addQuery("select * from _vt.vreplication where id = 2", stopped, nil) - - // Delete the target replications. - tme.dbDest1Client.addQuery("delete from _vt.vreplication where id = 1", &sqltypes.Result{}, nil) - tme.dbDest2Client.addQuery("delete from _vt.vreplication where id = 1", &sqltypes.Result{}, nil) - tme.dbDest1Client.addQuery("delete from _vt.vreplication where id = 2", &sqltypes.Result{}, nil) - - journalID, err := tme.wr.MigrateWrites(ctx, tme.targetKeyspace, "test", 1*time.Second) + checkJournals() + stopStreams() + + waitForCatchup := func() { + // mi.waitForCatchup-> mi.wr.tmc.VReplicationWaitForPos + state := sqltypes.MakeTestResult(sqltypes.MakeTestFields( + "pos|state|message", + "varchar|varchar|varchar"), + "MariaDB/5-456-892|Running", + ) + tme.dbTargetClients[0].addQuery("select pos, state, message from _vt.vreplication where id=1", state, nil) + tme.dbTargetClients[1].addQuery("select pos, state, message from _vt.vreplication where id=2", state, nil) + tme.dbTargetClients[0].addQuery("select pos, state, message from _vt.vreplication where id=2", state, nil) + + // mi.waitForCatchup-> mi.wr.tmc.VReplicationExec('stopped for cutover') + tme.dbTargetClients[0].addQuery("select id from _vt.vreplication where id = 1", resultid1, nil) + tme.dbTargetClients[0].addQuery("update _vt.vreplication set state = 'Stopped', message = 'stopped for cutover' where id in (1)", &sqltypes.Result{}, nil) + tme.dbTargetClients[0].addQuery("select id from _vt.vreplication where id = 2", resultid2, nil) + tme.dbTargetClients[0].addQuery("update _vt.vreplication set state = 'Stopped', message = 'stopped for cutover' where id in (2)", &sqltypes.Result{}, nil) + tme.dbTargetClients[1].addQuery("select id from _vt.vreplication where id = 2", resultid2, nil) + tme.dbTargetClients[1].addQuery("update _vt.vreplication set state = 'Stopped', message = 'stopped for cutover' where id in (2)", &sqltypes.Result{}, nil) + tme.dbTargetClients[0].addQuery("select * from _vt.vreplication where id = 1", stoppedResult(1), nil) + tme.dbTargetClients[1].addQuery("select * from _vt.vreplication where id = 2", stoppedResult(2), nil) + tme.dbTargetClients[0].addQuery("select * from _vt.vreplication where id = 2", stoppedResult(2), nil) + } + waitForCatchup() + + createReverseVReplication := func() { + deleteReverseReplicaion() + + tme.dbSourceClients[0].addQueryRE("insert into _vt.vreplication.*-80.*-40.*MariaDB/5-456-893.*Stopped", &sqltypes.Result{InsertID: 1}, nil) + tme.dbSourceClients[1].addQueryRE("insert into _vt.vreplication.*-80.*40-.*MariaDB/5-456-893.*Stopped", &sqltypes.Result{InsertID: 1}, nil) + tme.dbSourceClients[1].addQueryRE("insert into _vt.vreplication.*80-.*40-.*MariaDB/5-456-893.*Stopped", &sqltypes.Result{InsertID: 2}, nil) + tme.dbSourceClients[0].addQuery("select * from _vt.vreplication where id = 1", stoppedResult(1), nil) + tme.dbSourceClients[1].addQuery("select * from _vt.vreplication where id = 1", stoppedResult(1), nil) + tme.dbSourceClients[1].addQuery("select * from _vt.vreplication where id = 2", stoppedResult(2), nil) + } + createReverseVReplication() + + createJournals := func() { + journal1 := "insert into _vt.resharding_journal.*6432976123657117097.*migration_type:SHARDS.*local_position.*MariaDB/5-456-892.*shard_gtids.*-80.*MariaDB/5-456-893.*participants.*40.*40" + tme.dbSourceClients[0].addQueryRE(journal1, &sqltypes.Result{}, nil) + journal2 := "insert into _vt.resharding_journal.*6432976123657117097.*migration_type:SHARDS.*local_position.*MariaDB/5-456-892.*shard_gtids.*80.*MariaDB/5-456-893.*shard_gtids.*80.*MariaDB/5-456-893.*participants.*40.*40" + tme.dbSourceClients[1].addQueryRE(journal2, &sqltypes.Result{}, nil) + } + createJournals() + + startReverseVReplication := func() { + tme.dbSourceClients[0].addQuery("select id from _vt.vreplication where db_name = 'vt_ks'", resultid34, nil) + tme.dbSourceClients[0].addQuery("update _vt.vreplication set state = 'Running', message = '' where id in (3, 4)", &sqltypes.Result{}, nil) + tme.dbSourceClients[0].addQuery("select * from _vt.vreplication where id = 3", runningResult(3), nil) + tme.dbSourceClients[0].addQuery("select * from _vt.vreplication where id = 4", runningResult(4), nil) + tme.dbSourceClients[1].addQuery("select id from _vt.vreplication where db_name = 'vt_ks'", resultid34, nil) + tme.dbSourceClients[1].addQuery("update _vt.vreplication set state = 'Running', message = '' where id in (3, 4)", &sqltypes.Result{}, nil) + tme.dbSourceClients[1].addQuery("select * from _vt.vreplication where id = 3", runningResult(3), nil) + tme.dbSourceClients[1].addQuery("select * from _vt.vreplication where id = 4", runningResult(4), nil) + } + startReverseVReplication() + + deleteTargetVReplication := func() { + tme.dbTargetClients[0].addQuery("select id from _vt.vreplication where db_name = 'vt_ks' and workflow = 'test'", resultid12, nil) + tme.dbTargetClients[0].addQuery("update _vt.vreplication set message = 'FROZEN' where id in (1, 2)", &sqltypes.Result{}, nil) + tme.dbTargetClients[0].addQuery("select * from _vt.vreplication where id = 1", stoppedResult(1), nil) + tme.dbTargetClients[0].addQuery("select * from _vt.vreplication where id = 2", stoppedResult(2), nil) + tme.dbTargetClients[1].addQuery("select id from _vt.vreplication where db_name = 'vt_ks' and workflow = 'test'", resultid2, nil) + tme.dbTargetClients[1].addQuery("update _vt.vreplication set message = 'FROZEN' where id in (2)", &sqltypes.Result{}, nil) + tme.dbTargetClients[1].addQuery("select * from _vt.vreplication where id = 2", stoppedResult(2), nil) + + tme.dbTargetClients[0].addQuery("select id from _vt.vreplication where db_name = 'vt_ks' and workflow = 'test'", resultid12, nil) + tme.dbTargetClients[1].addQuery("select id from _vt.vreplication where db_name = 'vt_ks' and workflow = 'test'", resultid2, nil) + tme.dbTargetClients[0].addQuery("delete from _vt.vreplication where id in (1, 2)", &sqltypes.Result{}, nil) + tme.dbTargetClients[0].addQuery("delete from _vt.copy_state where vrepl_id in (1, 2)", &sqltypes.Result{}, nil) + tme.dbTargetClients[1].addQuery("delete from _vt.vreplication where id in (2)", &sqltypes.Result{}, nil) + tme.dbTargetClients[1].addQuery("delete from _vt.copy_state where vrepl_id in (2)", &sqltypes.Result{}, nil) + } + deleteTargetVReplication() + + journalID, err := tme.wr.MigrateWrites(ctx, tme.targetKeyspace, "test", 1*time.Second, false, true) if err != nil { t.Fatal(err) } - if journalID != 6432976123657117098 { - t.Errorf("journal id: %d, want 6432976123657117098", journalID) + if journalID != 6432976123657117097 { + t.Errorf("journal id: %d, want 6432976123657117097", journalID) } + verifyQueries(t, tme.allDBClients) + checkServedTypes(t, tme.ts, "ks:-40", 0) checkServedTypes(t, tme.ts, "ks:40-", 0) checkServedTypes(t, tme.ts, "ks:-80", 3) @@ -566,7 +726,173 @@ func TestShardMigrate(t *testing.T) { checkIsMasterServing(t, tme.ts, "ks:40-", false) checkIsMasterServing(t, tme.ts, "ks:-80", true) checkIsMasterServing(t, tme.ts, "ks:80-", true) +} + +func TestTableMigrateOneToMany(t *testing.T) { + ctx := context.Background() + tme := newTestTableMigraterCustom(ctx, t, []string{"0"}, []string{"-80", "80-"}, "select * %s") + defer tme.stopTablets(t) + + err := tme.wr.MigrateReads(ctx, tme.targetKeyspace, "test", topodatapb.TabletType_RDONLY, nil, DirectionForward) + if err != nil { + t.Fatal(err) + } + err = tme.wr.MigrateReads(ctx, tme.targetKeyspace, "test", topodatapb.TabletType_REPLICA, nil, DirectionForward) + if err != nil { + t.Fatal(err) + } + + // checkJournals + tme.dbSourceClients[0].addQueryRE("select val from _vt.resharding_journal.*", &sqltypes.Result{}, nil) + + waitForCatchup := func() { + // mi.waitForCatchup-> mi.wr.tmc.VReplicationWaitForPos + state := sqltypes.MakeTestResult(sqltypes.MakeTestFields( + "pos|state|message", + "varchar|varchar|varchar"), + "MariaDB/5-456-892|Running", + ) + tme.dbTargetClients[0].addQuery("select pos, state, message from _vt.vreplication where id=1", state, nil) + tme.dbTargetClients[1].addQuery("select pos, state, message from _vt.vreplication where id=1", state, nil) + + // mi.waitForCatchup-> mi.wr.tmc.VReplicationExec('Stopped') + tme.dbTargetClients[0].addQuery("select id from _vt.vreplication where id = 1", resultid1, nil) + tme.dbTargetClients[0].addQuery("update _vt.vreplication set state = 'Stopped', message = 'stopped for cutover' where id in (1)", &sqltypes.Result{}, nil) + tme.dbTargetClients[1].addQuery("select id from _vt.vreplication where id = 1", resultid1, nil) + tme.dbTargetClients[1].addQuery("update _vt.vreplication set state = 'Stopped', message = 'stopped for cutover' where id in (1)", &sqltypes.Result{}, nil) + tme.dbTargetClients[0].addQuery("select * from _vt.vreplication where id = 1", stoppedResult(1), nil) + tme.dbTargetClients[1].addQuery("select * from _vt.vreplication where id = 1", stoppedResult(1), nil) + } + waitForCatchup() + + deleteReverseReplicaion := func() { + tme.dbSourceClients[0].addQuery("select id from _vt.vreplication where db_name = 'vt_ks1' and workflow = 'test_reverse'", resultid34, nil) + tme.dbSourceClients[0].addQuery("delete from _vt.vreplication where id in (3, 4)", &sqltypes.Result{}, nil) + tme.dbSourceClients[0].addQuery("delete from _vt.copy_state where vrepl_id in (3, 4)", &sqltypes.Result{}, nil) + } + + createReverseVReplication := func() { + deleteReverseReplicaion() + + tme.dbSourceClients[0].addQueryRE(`insert into _vt.vreplication.*test_reverse.*ks2.*-80.*t1.*from t1\\".*t2.*from t2\\"`, &sqltypes.Result{InsertID: 1}, nil) + tme.dbSourceClients[0].addQueryRE(`insert into _vt.vreplication.*test_reverse.*ks2.*80-.*t1.*from t1\\".*t2.*from t2\\"`, &sqltypes.Result{InsertID: 2}, nil) + tme.dbSourceClients[0].addQuery("select * from _vt.vreplication where id = 1", stoppedResult(1), nil) + tme.dbSourceClients[0].addQuery("select * from _vt.vreplication where id = 2", stoppedResult(2), nil) + } + createReverseVReplication() + + createJournals := func() { + journal1 := "insert into _vt.resharding_journal.*tables.*t1.*t2.*local_position.*MariaDB/5-456-892.*shard_gtids.*80.*MariaDB/5-456-893.*80.*MariaDB/5-456-893.*participants.*0" + tme.dbSourceClients[0].addQueryRE(journal1, &sqltypes.Result{}, nil) + } + createJournals() + + deleteTargetVReplication := func() { + tme.dbTargetClients[0].addQuery("select id from _vt.vreplication where db_name = 'vt_ks2' and workflow = 'test'", resultid1, nil) + tme.dbTargetClients[1].addQuery("select id from _vt.vreplication where db_name = 'vt_ks2' and workflow = 'test'", resultid1, nil) + tme.dbTargetClients[0].addQuery("update _vt.vreplication set message = 'FROZEN' where id in (1)", &sqltypes.Result{}, nil) + tme.dbTargetClients[0].addQuery("select * from _vt.vreplication where id = 1", stoppedResult(1), nil) + tme.dbTargetClients[1].addQuery("update _vt.vreplication set message = 'FROZEN' where id in (1)", &sqltypes.Result{}, nil) + tme.dbTargetClients[1].addQuery("select * from _vt.vreplication where id = 1", stoppedResult(1), nil) + + tme.dbTargetClients[0].addQuery("select id from _vt.vreplication where db_name = 'vt_ks2' and workflow = 'test'", resultid1, nil) + tme.dbTargetClients[1].addQuery("select id from _vt.vreplication where db_name = 'vt_ks2' and workflow = 'test'", resultid1, nil) + tme.dbTargetClients[0].addQuery("delete from _vt.vreplication where id in (1)", &sqltypes.Result{}, nil) + tme.dbTargetClients[0].addQuery("delete from _vt.copy_state where vrepl_id in (1)", &sqltypes.Result{}, nil) + tme.dbTargetClients[1].addQuery("delete from _vt.vreplication where id in (1)", &sqltypes.Result{}, nil) + tme.dbTargetClients[1].addQuery("delete from _vt.copy_state where vrepl_id in (1)", &sqltypes.Result{}, nil) + } + deleteTargetVReplication() + _, err = tme.wr.MigrateWrites(ctx, tme.targetKeyspace, "test", 1*time.Second, false, false) + if err != nil { + t.Fatal(err) + } + verifyQueries(t, tme.allDBClients) +} + +func TestTableMigrateManyToOne(t *testing.T) { + ctx := context.Background() + tme := newTestTableMigraterCustom(ctx, t, []string{"-80", "80-"}, []string{"0"}, "select * %s") + defer tme.stopTablets(t) + + err := tme.wr.MigrateReads(ctx, tme.targetKeyspace, "test", topodatapb.TabletType_RDONLY, nil, DirectionForward) + if err != nil { + t.Fatal(err) + } + err = tme.wr.MigrateReads(ctx, tme.targetKeyspace, "test", topodatapb.TabletType_REPLICA, nil, DirectionForward) + if err != nil { + t.Fatal(err) + } + + checkJournals := func() { + tme.dbSourceClients[0].addQueryRE("select val from _vt.resharding_journal.*", &sqltypes.Result{}, nil) + tme.dbSourceClients[1].addQueryRE("select val from _vt.resharding_journal.*", &sqltypes.Result{}, nil) + } + checkJournals() + + waitForCatchup := func() { + // mi.waitForCatchup-> mi.wr.tmc.VReplicationWaitForPos + state := sqltypes.MakeTestResult(sqltypes.MakeTestFields( + "pos|state|message", + "varchar|varchar|varchar"), + "MariaDB/5-456-892|Running", + ) + tme.dbTargetClients[0].addQuery("select pos, state, message from _vt.vreplication where id=1", state, nil) + tme.dbTargetClients[0].addQuery("select pos, state, message from _vt.vreplication where id=2", state, nil) + + // mi.waitForCatchup-> mi.wr.tmc.VReplicationExec('Stopped') + tme.dbTargetClients[0].addQuery("select id from _vt.vreplication where id = 1", resultid1, nil) + tme.dbTargetClients[0].addQuery("update _vt.vreplication set state = 'Stopped', message = 'stopped for cutover' where id in (1)", &sqltypes.Result{}, nil) + tme.dbTargetClients[0].addQuery("select id from _vt.vreplication where id = 2", resultid2, nil) + tme.dbTargetClients[0].addQuery("update _vt.vreplication set state = 'Stopped', message = 'stopped for cutover' where id in (2)", &sqltypes.Result{}, nil) + tme.dbTargetClients[0].addQuery("select * from _vt.vreplication where id = 1", stoppedResult(1), nil) + tme.dbTargetClients[0].addQuery("select * from _vt.vreplication where id = 2", stoppedResult(2), nil) + } + waitForCatchup() + + deleteReverseReplicaion := func() { + tme.dbSourceClients[0].addQuery("select id from _vt.vreplication where db_name = 'vt_ks1' and workflow = 'test_reverse'", resultid3, nil) + tme.dbSourceClients[1].addQuery("select id from _vt.vreplication where db_name = 'vt_ks1' and workflow = 'test_reverse'", resultid3, nil) + tme.dbSourceClients[0].addQuery("delete from _vt.vreplication where id in (3)", &sqltypes.Result{}, nil) + tme.dbSourceClients[1].addQuery("delete from _vt.vreplication where id in (3)", &sqltypes.Result{}, nil) + tme.dbSourceClients[0].addQuery("delete from _vt.copy_state where vrepl_id in (3)", &sqltypes.Result{}, nil) + tme.dbSourceClients[1].addQuery("delete from _vt.copy_state where vrepl_id in (3)", &sqltypes.Result{}, nil) + } + + createReverseVReplication := func() { + deleteReverseReplicaion() + + tme.dbSourceClients[0].addQueryRE(`insert into _vt.vreplication.*test_reverse.*ks2.*0.*t1.*in_keyrange.*c1.*hash.*-80.*t2.*in_keyrange.*c1.*-80`, &sqltypes.Result{InsertID: 1}, nil) + tme.dbSourceClients[1].addQueryRE(`insert into _vt.vreplication.*test_reverse.*ks2.*0.*t1.*in_keyrange.*c1.*hash.*80-.*t2.*in_keyrange.*c1.*80-`, &sqltypes.Result{InsertID: 1}, nil) + tme.dbSourceClients[0].addQuery("select * from _vt.vreplication where id = 1", stoppedResult(1), nil) + tme.dbSourceClients[1].addQuery("select * from _vt.vreplication where id = 1", stoppedResult(1), nil) + } + createReverseVReplication() + + createJournals := func() { + journal := "insert into _vt.resharding_journal.*shard_gtids.*ks2.*0.*participants.*ks1.*80.*participants.*80" + tme.dbSourceClients[0].addQueryRE(journal, &sqltypes.Result{}, nil) + tme.dbSourceClients[1].addQueryRE(journal, &sqltypes.Result{}, nil) + } + createJournals() + + deleteTargetVReplication := func() { + tme.dbTargetClients[0].addQuery("select id from _vt.vreplication where db_name = 'vt_ks2' and workflow = 'test'", resultid12, nil) + tme.dbTargetClients[0].addQuery("update _vt.vreplication set message = 'FROZEN' where id in (1, 2)", &sqltypes.Result{}, nil) + tme.dbTargetClients[0].addQuery("select * from _vt.vreplication where id = 1", stoppedResult(1), nil) + tme.dbTargetClients[0].addQuery("select * from _vt.vreplication where id = 2", stoppedResult(2), nil) + + tme.dbTargetClients[0].addQuery("select id from _vt.vreplication where db_name = 'vt_ks2' and workflow = 'test'", resultid12, nil) + tme.dbTargetClients[0].addQuery("delete from _vt.vreplication where id in (1, 2)", &sqltypes.Result{}, nil) + tme.dbTargetClients[0].addQuery("delete from _vt.copy_state where vrepl_id in (1, 2)", &sqltypes.Result{}, nil) + } + deleteTargetVReplication() + + _, err = tme.wr.MigrateWrites(ctx, tme.targetKeyspace, "test", 1*time.Second, false, false) + if err != nil { + t.Fatal(err) + } verifyQueries(t, tme.allDBClients) } @@ -586,57 +912,85 @@ func TestMigrateFailJournal(t *testing.T) { t.Fatal(err) } - // Check for journals. - tme.dbSource1Client.addQuery("select 1 from _vt.resharding_journal where id = 9113431017721636330", &sqltypes.Result{}, nil) - tme.dbSource2Client.addQuery("select 1 from _vt.resharding_journal where id = 9113431017721636330", &sqltypes.Result{}, nil) + // mi.checkJournals + tme.dbSourceClients[0].addQuery("select val from _vt.resharding_journal where id=7672494164556733923", &sqltypes.Result{}, nil) + tme.dbSourceClients[1].addQuery("select val from _vt.resharding_journal where id=7672494164556733923", &sqltypes.Result{}, nil) - // Wait for position: Reads current state, updates to Stopped, and re-reads. + // mi.waitForCatchup-> mi.wr.tmc.VReplicationWaitForPos state := sqltypes.MakeTestResult(sqltypes.MakeTestFields( "pos|state|message", "varchar|varchar|varchar"), - "MariaDB/5-456-892|Running|", + "MariaDB/5-456-892|Running", ) - tme.dbDest1Client.addQuery("select pos, state, message from _vt.vreplication where id=1", state, nil) - tme.dbDest2Client.addQuery("select pos, state, message from _vt.vreplication where id=1", state, nil) - tme.dbDest1Client.addQuery("select pos, state, message from _vt.vreplication where id=2", state, nil) - tme.dbDest1Client.addQuery("update _vt.vreplication set state = 'Stopped', message = 'stopped for cutover' where id = 1", &sqltypes.Result{}, nil) - tme.dbDest2Client.addQuery("update _vt.vreplication set state = 'Stopped', message = 'stopped for cutover' where id = 1", &sqltypes.Result{}, nil) - tme.dbDest1Client.addQuery("update _vt.vreplication set state = 'Stopped', message = 'stopped for cutover' where id = 2", &sqltypes.Result{}, nil) - stopped := sqltypes.MakeTestResult(sqltypes.MakeTestFields( - "id|state", - "int64|varchar"), - "1|Stopped", - ) - tme.dbDest1Client.addQuery("select * from _vt.vreplication where id = 1", stopped, nil) - tme.dbDest2Client.addQuery("select * from _vt.vreplication where id = 1", stopped, nil) - tme.dbDest1Client.addQuery("select * from _vt.vreplication where id = 2", stopped, nil) - - // Cancel Migration: these must not get called. - cancel1 := "update _vt.vreplication set state = 'Running', stop_pos = null where id = 1" - cancel2 := "update _vt.vreplication set state = 'Running', stop_pos = null where id = 2" - tme.dbDest1Client.addQuery(cancel1, &sqltypes.Result{}, nil) - tme.dbDest2Client.addQuery(cancel1, &sqltypes.Result{}, nil) - tme.dbDest1Client.addQuery(cancel2, &sqltypes.Result{}, nil) + tme.dbTargetClients[0].addQuery("select pos, state, message from _vt.vreplication where id=1", state, nil) + tme.dbTargetClients[0].addQuery("select pos, state, message from _vt.vreplication where id=2", state, nil) + tme.dbTargetClients[1].addQuery("select pos, state, message from _vt.vreplication where id=1", state, nil) + tme.dbTargetClients[1].addQuery("select pos, state, message from _vt.vreplication where id=2", state, nil) + + // mi.waitForCatchup-> mi.wr.tmc.VReplicationExec('stopped for cutover') + tme.dbTargetClients[0].addQuery("select id from _vt.vreplication where id = 1", resultid1, nil) + tme.dbTargetClients[0].addQuery("update _vt.vreplication set state = 'Stopped', message = 'stopped for cutover' where id in (1)", &sqltypes.Result{}, nil) + tme.dbTargetClients[0].addQuery("select id from _vt.vreplication where id = 2", resultid2, nil) + tme.dbTargetClients[0].addQuery("update _vt.vreplication set state = 'Stopped', message = 'stopped for cutover' where id in (2)", &sqltypes.Result{}, nil) + tme.dbTargetClients[1].addQuery("select id from _vt.vreplication where id = 1", resultid1, nil) + tme.dbTargetClients[1].addQuery("update _vt.vreplication set state = 'Stopped', message = 'stopped for cutover' where id in (1)", &sqltypes.Result{}, nil) + tme.dbTargetClients[1].addQuery("select id from _vt.vreplication where id = 2", resultid2, nil) + tme.dbTargetClients[1].addQuery("update _vt.vreplication set state = 'Stopped', message = 'stopped for cutover' where id in (2)", &sqltypes.Result{}, nil) + tme.dbTargetClients[0].addQuery("select * from _vt.vreplication where id = 1", stoppedResult(1), nil) + tme.dbTargetClients[0].addQuery("select * from _vt.vreplication where id = 2", stoppedResult(2), nil) + tme.dbTargetClients[1].addQuery("select * from _vt.vreplication where id = 1", stoppedResult(1), nil) + tme.dbTargetClients[1].addQuery("select * from _vt.vreplication where id = 2", stoppedResult(2), nil) + + // mi.cancelMigration: these must not get called. + cancel1 := "update _vt.vreplication set state = 'Running', stop_pos = null where id in (1)" + cancel2 := "update _vt.vreplication set state = 'Running', stop_pos = null where id in (2)" + tme.dbTargetClients[0].addQuery(cancel1, &sqltypes.Result{}, nil) + tme.dbTargetClients[0].addQuery(cancel2, &sqltypes.Result{}, nil) + tme.dbTargetClients[1].addQuery(cancel1, &sqltypes.Result{}, nil) + tme.dbTargetClients[1].addQuery(cancel2, &sqltypes.Result{}, nil) + + deleteReverseReplicaion := func() { + tme.dbSourceClients[0].addQuery("select id from _vt.vreplication where db_name = 'vt_ks1' and workflow = 'test_reverse'", resultid34, nil) + tme.dbSourceClients[1].addQuery("select id from _vt.vreplication where db_name = 'vt_ks1' and workflow = 'test_reverse'", resultid34, nil) + tme.dbSourceClients[0].addQuery("delete from _vt.vreplication where id in (3, 4)", &sqltypes.Result{}, nil) + tme.dbSourceClients[1].addQuery("delete from _vt.vreplication where id in (3, 4)", &sqltypes.Result{}, nil) + tme.dbSourceClients[0].addQuery("delete from _vt.copy_state where vrepl_id in (3, 4)", &sqltypes.Result{}, nil) + tme.dbSourceClients[1].addQuery("delete from _vt.copy_state where vrepl_id in (3, 4)", &sqltypes.Result{}, nil) + } + + createReverseVReplication := func() { + deleteReverseReplicaion() + + tme.dbSourceClients[0].addQueryRE("insert into _vt.vreplication.*test_reverse.*ks2.*-80.*t1.*in_keyrange.*c1.*hash.*-40.*t2.*-40.*MariaDB/5-456-893.*Stopped", &sqltypes.Result{InsertID: 1}, nil) + tme.dbSourceClients[0].addQueryRE("insert into _vt.vreplication.*test_reverse.*ks2.*80-.*t1.*in_keyrange.*c1.*hash.*-40.*t2.*-40.*MariaDB/5-456-893.*Stopped", &sqltypes.Result{InsertID: 2}, nil) + tme.dbSourceClients[1].addQueryRE("insert into _vt.vreplication.*test_reverse.*ks2.*-80.*t1.*in_keyrange.*c1.*hash.*40-.*t2.*40-.*MariaDB/5-456-893.*Stopped", &sqltypes.Result{InsertID: 1}, nil) + tme.dbSourceClients[1].addQueryRE("insert into _vt.vreplication.*test_reverse.*ks2.*80-.*t1.*in_keyrange.*c1.*hash.*40-.*t2.*40-.*MariaDB/5-456-893.*Stopped", &sqltypes.Result{InsertID: 2}, nil) + tme.dbSourceClients[0].addQuery("select * from _vt.vreplication where id = 1", stoppedResult(1), nil) + tme.dbSourceClients[0].addQuery("select * from _vt.vreplication where id = 2", stoppedResult(2), nil) + tme.dbSourceClients[1].addQuery("select * from _vt.vreplication where id = 1", stoppedResult(1), nil) + tme.dbSourceClients[1].addQuery("select * from _vt.vreplication where id = 2", stoppedResult(2), nil) + } + createReverseVReplication() // Make the journal call fail. - tme.dbSource1Client.addQueryRE("insert into _vt.resharding_journal", nil, errors.New("journaling intentionally failed")) - tme.dbSource2Client.addQueryRE("insert into _vt.resharding_journal", nil, errors.New("journaling intentionally failed")) + tme.dbSourceClients[0].addQueryRE("insert into _vt.resharding_journal", nil, errors.New("journaling intentionally failed")) + tme.dbSourceClients[1].addQueryRE("insert into _vt.resharding_journal", nil, errors.New("journaling intentionally failed")) - _, err = tme.wr.MigrateWrites(ctx, tme.targetKeyspace, "test", 1*time.Second) + _, err = tme.wr.MigrateWrites(ctx, tme.targetKeyspace, "test", 1*time.Second, false, true) want := "journaling intentionally failed" if err == nil || !strings.Contains(err.Error(), want) { t.Errorf("MigrateWrites(0 timeout) err: %v, must contain %v", err, want) } // Verify that cancel didn't happen. - if tme.dbDest1Client.queries[cancel1].called { - t.Errorf("tme.dbDest1Client.queries[cancel1].called: %v, want false", tme.dbDest1Client.queries[cancel1]) + if tme.dbTargetClients[0].queries[cancel1].exhausted() { + t.Errorf("tme.dbTargetClients[0].queries[cancel1].exhausted: %v, want false", tme.dbTargetClients[0].queries[cancel1]) } - if tme.dbDest2Client.queries[cancel1].called { - t.Errorf("tme.dbDest1Client.queries[cancel1].called: %v, want false", tme.dbDest1Client.queries[cancel1]) + if tme.dbTargetClients[1].queries[cancel1].exhausted() { + t.Errorf("tme.dbTargetClients[0].queries[cancel1].exhausted: %v, want false", tme.dbTargetClients[0].queries[cancel1]) } - if tme.dbDest1Client.queries[cancel2].called { - t.Errorf("tme.dbDest1Client.queries[cancel1].called: %v, want false", tme.dbDest1Client.queries[cancel1]) + if tme.dbTargetClients[0].queries[cancel2].exhausted() { + t.Errorf("tme.dbTargetClients[0].queries[cancel1].exhausted: %v, want false", tme.dbTargetClients[0].queries[cancel1]) } } @@ -654,33 +1008,42 @@ func TestTableMigrateJournalExists(t *testing.T) { t.Fatal(err) } - // Show one journal as created. - tme.dbSource1Client.addQuery("select 1 from _vt.resharding_journal where id = 9113431017721636330", sqltypes.MakeTestResult(sqltypes.MakeTestFields("1", "int64"), "1"), nil) - tme.dbSource2Client.addQuery("select 1 from _vt.resharding_journal where id = 9113431017721636330", &sqltypes.Result{}, nil) - - // Create the missing journal. - journal2 := "insert into _vt.resharding_journal.*9113431017721636330.*tables.*t1.*t2.*local_position.*MariaDB/5-456-892.*shard_gtids.*80.*MariaDB/5-456-893.*80.*participants.*40.*40" - tme.dbSource2Client.addQueryRE(journal2, &sqltypes.Result{}, nil) - - // Create backward replicaions. - tme.dbSource1Client.addQueryRE("insert into _vt.vreplication.*ks2.*-80.*t1.*in_keyrange.*c1.*hash.*-40.*t2.*-40.*MariaDB/5-456-893.*Stopped", &sqltypes.Result{InsertID: 1}, nil) - tme.dbSource2Client.addQueryRE("insert into _vt.vreplication.*ks2.*-80.*t1.*in_keyrange.*c1.*hash.*40-.*t2.*40-.*MariaDB/5-456-893.*Stopped", &sqltypes.Result{InsertID: 1}, nil) - tme.dbSource2Client.addQueryRE("insert into _vt.vreplication.*ks2.*80-.*t1.*in_keyrange.*c1.*hash.*40-.*t2.*40-.*MariaDB/5-456-893.*Stopped", &sqltypes.Result{InsertID: 2}, nil) - stopped := sqltypes.MakeTestResult(sqltypes.MakeTestFields( - "id|state", - "int64|varchar"), - "1|Stopped", - ) - tme.dbSource1Client.addQuery("select * from _vt.vreplication where id = 1", stopped, nil) - tme.dbSource2Client.addQuery("select * from _vt.vreplication where id = 1", stopped, nil) - tme.dbSource2Client.addQuery("select * from _vt.vreplication where id = 2", stopped, nil) - - // Delete the target replications. - tme.dbDest1Client.addQuery("delete from _vt.vreplication where id = 1", &sqltypes.Result{}, nil) - tme.dbDest2Client.addQuery("delete from _vt.vreplication where id = 1", &sqltypes.Result{}, nil) - tme.dbDest1Client.addQuery("delete from _vt.vreplication where id = 2", &sqltypes.Result{}, nil) - - _, err = tme.wr.MigrateWrites(ctx, tme.targetKeyspace, "test", 1*time.Second) + // mi.checkJournals: Show one journal as created. + tme.dbSourceClients[0].addQuery("select val from _vt.resharding_journal where id=7672494164556733923", sqltypes.MakeTestResult(sqltypes.MakeTestFields("val", "varbinary"), ""), nil) + tme.dbSourceClients[1].addQuery("select val from _vt.resharding_journal where id=7672494164556733923", &sqltypes.Result{}, nil) + + // mi.createJournals: Create the missing journal. + journal2 := "insert into _vt.resharding_journal.*7672494164556733923,.*tables.*t1.*t2.*local_position.*MariaDB/5-456-892.*shard_gtids.*80.*MariaDB/5-456-893.*80.*participants.*40.*40" + tme.dbSourceClients[1].addQueryRE(journal2, &sqltypes.Result{}, nil) + + // mi.startReverseVReplication + tme.dbSourceClients[0].addQuery("select id from _vt.vreplication where db_name = 'vt_ks1'", resultid34, nil) + tme.dbSourceClients[0].addQuery("update _vt.vreplication set state = 'Running', message = '' where id in (3, 4)", &sqltypes.Result{}, nil) + tme.dbSourceClients[0].addQuery("select * from _vt.vreplication where id = 3", runningResult(3), nil) + tme.dbSourceClients[0].addQuery("select * from _vt.vreplication where id = 4", runningResult(4), nil) + tme.dbSourceClients[1].addQuery("select id from _vt.vreplication where db_name = 'vt_ks1'", resultid34, nil) + tme.dbSourceClients[1].addQuery("update _vt.vreplication set state = 'Running', message = '' where id in (3, 4)", &sqltypes.Result{}, nil) + tme.dbSourceClients[1].addQuery("select * from _vt.vreplication where id = 3", runningResult(3), nil) + tme.dbSourceClients[1].addQuery("select * from _vt.vreplication where id = 4", runningResult(4), nil) + + // mi.deleteTargetVReplication + tme.dbTargetClients[0].addQuery("select id from _vt.vreplication where db_name = 'vt_ks2' and workflow = 'test'", resultid12, nil) + tme.dbTargetClients[1].addQuery("select id from _vt.vreplication where db_name = 'vt_ks2' and workflow = 'test'", resultid12, nil) + tme.dbTargetClients[0].addQuery("update _vt.vreplication set message = 'FROZEN' where id in (1, 2)", &sqltypes.Result{}, nil) + tme.dbTargetClients[0].addQuery("select * from _vt.vreplication where id = 1", stoppedResult(1), nil) + tme.dbTargetClients[0].addQuery("select * from _vt.vreplication where id = 2", stoppedResult(2), nil) + tme.dbTargetClients[1].addQuery("update _vt.vreplication set message = 'FROZEN' where id in (1, 2)", &sqltypes.Result{}, nil) + tme.dbTargetClients[1].addQuery("select * from _vt.vreplication where id = 1", stoppedResult(1), nil) + tme.dbTargetClients[1].addQuery("select * from _vt.vreplication where id = 2", stoppedResult(2), nil) + + tme.dbTargetClients[0].addQuery("select id from _vt.vreplication where db_name = 'vt_ks2' and workflow = 'test'", resultid12, nil) + tme.dbTargetClients[1].addQuery("select id from _vt.vreplication where db_name = 'vt_ks2' and workflow = 'test'", resultid12, nil) + tme.dbTargetClients[0].addQuery("delete from _vt.vreplication where id in (1, 2)", &sqltypes.Result{}, nil) + tme.dbTargetClients[0].addQuery("delete from _vt.copy_state where vrepl_id in (1, 2)", &sqltypes.Result{}, nil) + tme.dbTargetClients[1].addQuery("delete from _vt.vreplication where id in (1, 2)", &sqltypes.Result{}, nil) + tme.dbTargetClients[1].addQuery("delete from _vt.copy_state where vrepl_id in (1, 2)", &sqltypes.Result{}, nil) + + _, err = tme.wr.MigrateWrites(ctx, tme.targetKeyspace, "test", 1*time.Second, false, true) if err != nil { t.Fatal(err) } @@ -704,7 +1067,7 @@ func TestTableMigrateJournalExists(t *testing.T) { func TestShardMigrateJournalExists(t *testing.T) { ctx := context.Background() - tme := newTestShardMigrater(ctx, t) + tme := newTestShardMigrater(ctx, t, []string{"-40", "40-"}, []string{"-80", "80-"}) defer tme.stopTablets(t) err := tme.wr.MigrateReads(ctx, tme.targetKeyspace, "test", topodatapb.TabletType_RDONLY, nil, DirectionForward) @@ -716,33 +1079,41 @@ func TestShardMigrateJournalExists(t *testing.T) { t.Fatal(err) } - // Show one journal as created. - tme.dbSource1Client.addQuery("select 1 from _vt.resharding_journal where id = 6432976123657117098", sqltypes.MakeTestResult(sqltypes.MakeTestFields("1", "int64"), "1"), nil) - tme.dbSource2Client.addQuery("select 1 from _vt.resharding_journal where id = 6432976123657117098", &sqltypes.Result{}, nil) - - // Create the missing journal. - journal2 := "insert into _vt.resharding_journal.*6432976123657117098.*migration_type:SHARDS.*local_position.*MariaDB/5-456-892.*shard_gtids.*80.*MariaDB/5-456-893.*shard_gtids.*80.*MariaDB/5-456-893.*participants.*40.*40" - tme.dbSource2Client.addQueryRE(journal2, &sqltypes.Result{}, nil) - - // Create backward replicaions. - tme.dbSource1Client.addQueryRE("insert into _vt.vreplication.*-80.*-40.*MariaDB/5-456-893.*Stopped", &sqltypes.Result{InsertID: 1}, nil) - tme.dbSource2Client.addQueryRE("insert into _vt.vreplication.*-80.*40-.*MariaDB/5-456-893.*Stopped", &sqltypes.Result{InsertID: 1}, nil) - tme.dbSource2Client.addQueryRE("insert into _vt.vreplication.*80-.*40-.*MariaDB/5-456-893.*Stopped", &sqltypes.Result{InsertID: 2}, nil) - stopped := sqltypes.MakeTestResult(sqltypes.MakeTestFields( - "id|state", - "int64|varchar"), - "1|Stopped", - ) - tme.dbSource1Client.addQuery("select * from _vt.vreplication where id = 1", stopped, nil) - tme.dbSource2Client.addQuery("select * from _vt.vreplication where id = 1", stopped, nil) - tme.dbSource2Client.addQuery("select * from _vt.vreplication where id = 2", stopped, nil) - - // Delete the target replications. - tme.dbDest1Client.addQuery("delete from _vt.vreplication where id = 1", &sqltypes.Result{}, nil) - tme.dbDest2Client.addQuery("delete from _vt.vreplication where id = 1", &sqltypes.Result{}, nil) - tme.dbDest1Client.addQuery("delete from _vt.vreplication where id = 2", &sqltypes.Result{}, nil) - - _, err = tme.wr.MigrateWrites(ctx, tme.targetKeyspace, "test", 1*time.Second) + // mi.checkJournals + tme.dbSourceClients[0].addQuery("select val from _vt.resharding_journal where id=6432976123657117097", sqltypes.MakeTestResult(sqltypes.MakeTestFields("val", "varbinary"), ""), nil) + tme.dbSourceClients[1].addQuery("select val from _vt.resharding_journal where id=6432976123657117097", &sqltypes.Result{}, nil) + + // mi.creaetJournals: Create the missing journal. + journal2 := "insert into _vt.resharding_journal.*6432976123657117097.*migration_type:SHARDS.*local_position.*MariaDB/5-456-892.*shard_gtids.*80.*MariaDB/5-456-893.*shard_gtids.*80.*MariaDB/5-456-893.*participants.*40.*40" + tme.dbSourceClients[1].addQueryRE(journal2, &sqltypes.Result{}, nil) + + // mi.startReverseVReplication + tme.dbSourceClients[0].addQuery("select id from _vt.vreplication where db_name = 'vt_ks'", resultid34, nil) + tme.dbSourceClients[0].addQuery("update _vt.vreplication set state = 'Running', message = '' where id in (3, 4)", &sqltypes.Result{}, nil) + tme.dbSourceClients[0].addQuery("select * from _vt.vreplication where id = 3", runningResult(3), nil) + tme.dbSourceClients[0].addQuery("select * from _vt.vreplication where id = 4", runningResult(4), nil) + tme.dbSourceClients[1].addQuery("select id from _vt.vreplication where db_name = 'vt_ks'", resultid34, nil) + tme.dbSourceClients[1].addQuery("update _vt.vreplication set state = 'Running', message = '' where id in (3, 4)", &sqltypes.Result{}, nil) + tme.dbSourceClients[1].addQuery("select * from _vt.vreplication where id = 3", runningResult(3), nil) + tme.dbSourceClients[1].addQuery("select * from _vt.vreplication where id = 4", runningResult(4), nil) + + // mi.deleteTargetVReplication + tme.dbTargetClients[0].addQuery("select id from _vt.vreplication where db_name = 'vt_ks' and workflow = 'test'", resultid12, nil) + tme.dbTargetClients[0].addQuery("update _vt.vreplication set message = 'FROZEN' where id in (1, 2)", &sqltypes.Result{}, nil) + tme.dbTargetClients[0].addQuery("select * from _vt.vreplication where id = 1", stoppedResult(1), nil) + tme.dbTargetClients[0].addQuery("select * from _vt.vreplication where id = 2", stoppedResult(2), nil) + tme.dbTargetClients[1].addQuery("select id from _vt.vreplication where db_name = 'vt_ks' and workflow = 'test'", resultid2, nil) + tme.dbTargetClients[1].addQuery("update _vt.vreplication set message = 'FROZEN' where id in (2)", &sqltypes.Result{}, nil) + tme.dbTargetClients[1].addQuery("select * from _vt.vreplication where id = 2", stoppedResult(2), nil) + + tme.dbTargetClients[0].addQuery("select id from _vt.vreplication where db_name = 'vt_ks' and workflow = 'test'", resultid12, nil) + tme.dbTargetClients[1].addQuery("select id from _vt.vreplication where db_name = 'vt_ks' and workflow = 'test'", resultid2, nil) + tme.dbTargetClients[0].addQuery("delete from _vt.vreplication where id in (1, 2)", &sqltypes.Result{}, nil) + tme.dbTargetClients[0].addQuery("delete from _vt.copy_state where vrepl_id in (1, 2)", &sqltypes.Result{}, nil) + tme.dbTargetClients[1].addQuery("delete from _vt.vreplication where id in (2)", &sqltypes.Result{}, nil) + tme.dbTargetClients[1].addQuery("delete from _vt.copy_state where vrepl_id in (2)", &sqltypes.Result{}, nil) + + _, err = tme.wr.MigrateWrites(ctx, tme.targetKeyspace, "test", 1*time.Second, false, true) if err != nil { t.Fatal(err) } @@ -760,13 +1131,230 @@ func TestShardMigrateJournalExists(t *testing.T) { verifyQueries(t, tme.allDBClients) } +func TestTableMigrateCancel(t *testing.T) { + ctx := context.Background() + tme := newTestTableMigrater(ctx, t) + defer tme.stopTablets(t) + + err := tme.wr.MigrateReads(ctx, tme.targetKeyspace, "test", topodatapb.TabletType_RDONLY, nil, DirectionForward) + if err != nil { + t.Fatal(err) + } + err = tme.wr.MigrateReads(ctx, tme.targetKeyspace, "test", topodatapb.TabletType_REPLICA, nil, DirectionForward) + if err != nil { + t.Fatal(err) + } + + checkJournals := func() { + tme.dbSourceClients[0].addQuery("select val from _vt.resharding_journal where id=7672494164556733923", &sqltypes.Result{}, nil) + tme.dbSourceClients[1].addQuery("select val from _vt.resharding_journal where id=7672494164556733923", &sqltypes.Result{}, nil) + } + checkJournals() + + deleteReverseReplicaion := func() { + tme.dbSourceClients[0].addQuery("select id from _vt.vreplication where db_name = 'vt_ks1' and workflow = 'test_reverse'", resultid34, nil) + tme.dbSourceClients[1].addQuery("select id from _vt.vreplication where db_name = 'vt_ks1' and workflow = 'test_reverse'", resultid34, nil) + tme.dbSourceClients[0].addQuery("delete from _vt.vreplication where id in (3, 4)", &sqltypes.Result{}, nil) + tme.dbSourceClients[1].addQuery("delete from _vt.vreplication where id in (3, 4)", &sqltypes.Result{}, nil) + tme.dbSourceClients[0].addQuery("delete from _vt.copy_state where vrepl_id in (3, 4)", &sqltypes.Result{}, nil) + tme.dbSourceClients[1].addQuery("delete from _vt.copy_state where vrepl_id in (3, 4)", &sqltypes.Result{}, nil) + } + cancelMigration := func() { + tme.dbTargetClients[0].addQuery("select id from _vt.vreplication where db_name = 'vt_ks2' and workflow = 'test'", resultid12, nil) + tme.dbTargetClients[1].addQuery("select id from _vt.vreplication where db_name = 'vt_ks2' and workflow = 'test'", resultid12, nil) + tme.dbTargetClients[0].addQuery("update _vt.vreplication set state = 'Running', message = '' where id in (1, 2)", &sqltypes.Result{}, nil) + tme.dbTargetClients[1].addQuery("update _vt.vreplication set state = 'Running', message = '' where id in (1, 2)", &sqltypes.Result{}, nil) + tme.dbTargetClients[0].addQuery("select * from _vt.vreplication where id = 1", runningResult(1), nil) + tme.dbTargetClients[0].addQuery("select * from _vt.vreplication where id = 2", runningResult(2), nil) + tme.dbTargetClients[1].addQuery("select * from _vt.vreplication where id = 1", runningResult(1), nil) + tme.dbTargetClients[1].addQuery("select * from _vt.vreplication where id = 2", runningResult(2), nil) + + deleteReverseReplicaion() + } + cancelMigration() + + _, err = tme.wr.MigrateWrites(ctx, tme.targetKeyspace, "test", 1*time.Second, true, false) + if err != nil { + t.Fatal(err) + } + verifyQueries(t, tme.allDBClients) +} + +func TestTableMigrateNoReverse(t *testing.T) { + ctx := context.Background() + tme := newTestTableMigrater(ctx, t) + defer tme.stopTablets(t) + + err := tme.wr.MigrateReads(ctx, tme.targetKeyspace, "test", topodatapb.TabletType_RDONLY, nil, DirectionForward) + if err != nil { + t.Fatal(err) + } + err = tme.wr.MigrateReads(ctx, tme.targetKeyspace, "test", topodatapb.TabletType_REPLICA, nil, DirectionForward) + if err != nil { + t.Fatal(err) + } + + checkJournals := func() { + tme.dbSourceClients[0].addQuery("select val from _vt.resharding_journal where id=7672494164556733923", &sqltypes.Result{}, nil) + tme.dbSourceClients[1].addQuery("select val from _vt.resharding_journal where id=7672494164556733923", &sqltypes.Result{}, nil) + } + checkJournals() + + waitForCatchup := func() { + // mi.waitForCatchup-> mi.wr.tmc.VReplicationWaitForPos + state := sqltypes.MakeTestResult(sqltypes.MakeTestFields( + "pos|state|message", + "varchar|varchar|varchar"), + "MariaDB/5-456-892|Running", + ) + tme.dbTargetClients[0].addQuery("select pos, state, message from _vt.vreplication where id=1", state, nil) + tme.dbTargetClients[0].addQuery("select pos, state, message from _vt.vreplication where id=2", state, nil) + tme.dbTargetClients[1].addQuery("select pos, state, message from _vt.vreplication where id=1", state, nil) + tme.dbTargetClients[1].addQuery("select pos, state, message from _vt.vreplication where id=2", state, nil) + + // mi.waitForCatchup-> mi.wr.tmc.VReplicationExec('Stopped') + tme.dbTargetClients[0].addQuery("select id from _vt.vreplication where id = 1", resultid1, nil) + tme.dbTargetClients[0].addQuery("update _vt.vreplication set state = 'Stopped', message = 'stopped for cutover' where id in (1)", &sqltypes.Result{}, nil) + tme.dbTargetClients[0].addQuery("select id from _vt.vreplication where id = 2", resultid2, nil) + tme.dbTargetClients[0].addQuery("update _vt.vreplication set state = 'Stopped', message = 'stopped for cutover' where id in (2)", &sqltypes.Result{}, nil) + tme.dbTargetClients[1].addQuery("select id from _vt.vreplication where id = 1", resultid1, nil) + tme.dbTargetClients[1].addQuery("update _vt.vreplication set state = 'Stopped', message = 'stopped for cutover' where id in (1)", &sqltypes.Result{}, nil) + tme.dbTargetClients[1].addQuery("select id from _vt.vreplication where id = 2", resultid2, nil) + tme.dbTargetClients[1].addQuery("update _vt.vreplication set state = 'Stopped', message = 'stopped for cutover' where id in (2)", &sqltypes.Result{}, nil) + tme.dbTargetClients[0].addQuery("select * from _vt.vreplication where id = 1", stoppedResult(1), nil) + tme.dbTargetClients[0].addQuery("select * from _vt.vreplication where id = 2", stoppedResult(2), nil) + tme.dbTargetClients[1].addQuery("select * from _vt.vreplication where id = 1", stoppedResult(1), nil) + tme.dbTargetClients[1].addQuery("select * from _vt.vreplication where id = 2", stoppedResult(2), nil) + } + waitForCatchup() + + deleteReverseReplicaion := func() { + tme.dbSourceClients[0].addQuery("select id from _vt.vreplication where db_name = 'vt_ks1' and workflow = 'test_reverse'", resultid34, nil) + tme.dbSourceClients[1].addQuery("select id from _vt.vreplication where db_name = 'vt_ks1' and workflow = 'test_reverse'", resultid34, nil) + tme.dbSourceClients[0].addQuery("delete from _vt.vreplication where id in (3, 4)", &sqltypes.Result{}, nil) + tme.dbSourceClients[1].addQuery("delete from _vt.vreplication where id in (3, 4)", &sqltypes.Result{}, nil) + tme.dbSourceClients[0].addQuery("delete from _vt.copy_state where vrepl_id in (3, 4)", &sqltypes.Result{}, nil) + tme.dbSourceClients[1].addQuery("delete from _vt.copy_state where vrepl_id in (3, 4)", &sqltypes.Result{}, nil) + } + + createReverseVReplication := func() { + deleteReverseReplicaion() + + tme.dbSourceClients[0].addQueryRE("insert into _vt.vreplication.*test_reverse.*ks2.*-80.*t1.*in_keyrange.*c1.*hash.*-40.*t2.*-40.*MariaDB/5-456-893.*Stopped", &sqltypes.Result{InsertID: 1}, nil) + tme.dbSourceClients[0].addQueryRE("insert into _vt.vreplication.*test_reverse.*ks2.*80-.*t1.*in_keyrange.*c1.*hash.*-40.*t2.*-40.*MariaDB/5-456-893.*Stopped", &sqltypes.Result{InsertID: 2}, nil) + tme.dbSourceClients[1].addQueryRE("insert into _vt.vreplication.*test_reverse.*ks2.*-80.*t1.*in_keyrange.*c1.*hash.*40-.*t2.*40-.*MariaDB/5-456-893.*Stopped", &sqltypes.Result{InsertID: 1}, nil) + tme.dbSourceClients[1].addQueryRE("insert into _vt.vreplication.*test_reverse.*ks2.*80-.*t1.*in_keyrange.*c1.*hash.*40-.*t2.*40-.*MariaDB/5-456-893.*Stopped", &sqltypes.Result{InsertID: 2}, nil) + tme.dbSourceClients[0].addQuery("select * from _vt.vreplication where id = 1", stoppedResult(1), nil) + tme.dbSourceClients[0].addQuery("select * from _vt.vreplication where id = 2", stoppedResult(2), nil) + tme.dbSourceClients[1].addQuery("select * from _vt.vreplication where id = 1", stoppedResult(1), nil) + tme.dbSourceClients[1].addQuery("select * from _vt.vreplication where id = 2", stoppedResult(2), nil) + } + createReverseVReplication() + + createJournals := func() { + journal1 := "insert into _vt.resharding_journal.*7672494164556733923,.*tables.*t1.*t2.*local_position.*MariaDB/5-456-892.*shard_gtids.*-80.*MariaDB/5-456-893.*participants.*40.*40" + tme.dbSourceClients[0].addQueryRE(journal1, &sqltypes.Result{}, nil) + journal2 := "insert into _vt.resharding_journal.*7672494164556733923,.*tables.*t1.*t2.*local_position.*MariaDB/5-456-892.*shard_gtids.*80.*MariaDB/5-456-893.*80.*participants.*40.*40" + tme.dbSourceClients[1].addQueryRE(journal2, &sqltypes.Result{}, nil) + } + createJournals() + + deleteTargetVReplication := func() { + tme.dbTargetClients[0].addQuery("select id from _vt.vreplication where db_name = 'vt_ks2' and workflow = 'test'", resultid12, nil) + tme.dbTargetClients[1].addQuery("select id from _vt.vreplication where db_name = 'vt_ks2' and workflow = 'test'", resultid12, nil) + tme.dbTargetClients[0].addQuery("update _vt.vreplication set message = 'FROZEN' where id in (1, 2)", &sqltypes.Result{}, nil) + tme.dbTargetClients[0].addQuery("select * from _vt.vreplication where id = 1", stoppedResult(1), nil) + tme.dbTargetClients[0].addQuery("select * from _vt.vreplication where id = 2", stoppedResult(2), nil) + tme.dbTargetClients[1].addQuery("update _vt.vreplication set message = 'FROZEN' where id in (1, 2)", &sqltypes.Result{}, nil) + tme.dbTargetClients[1].addQuery("select * from _vt.vreplication where id = 1", stoppedResult(1), nil) + tme.dbTargetClients[1].addQuery("select * from _vt.vreplication where id = 2", stoppedResult(2), nil) + + tme.dbTargetClients[0].addQuery("select id from _vt.vreplication where db_name = 'vt_ks2' and workflow = 'test'", resultid12, nil) + tme.dbTargetClients[1].addQuery("select id from _vt.vreplication where db_name = 'vt_ks2' and workflow = 'test'", resultid12, nil) + tme.dbTargetClients[0].addQuery("delete from _vt.vreplication where id in (1, 2)", &sqltypes.Result{}, nil) + tme.dbTargetClients[0].addQuery("delete from _vt.copy_state where vrepl_id in (1, 2)", &sqltypes.Result{}, nil) + tme.dbTargetClients[1].addQuery("delete from _vt.vreplication where id in (1, 2)", &sqltypes.Result{}, nil) + tme.dbTargetClients[1].addQuery("delete from _vt.copy_state where vrepl_id in (1, 2)", &sqltypes.Result{}, nil) + } + deleteTargetVReplication() + + _, err = tme.wr.MigrateWrites(ctx, tme.targetKeyspace, "test", 1*time.Second, false, false) + if err != nil { + t.Fatal(err) + } + verifyQueries(t, tme.allDBClients) +} + +func TestMigrateFrozen(t *testing.T) { + ctx := context.Background() + tme := newTestTableMigrater(ctx, t) + defer tme.stopTablets(t) + + err := tme.wr.MigrateReads(ctx, tme.targetKeyspace, "test", topodatapb.TabletType_RDONLY, nil, DirectionForward) + if err != nil { + t.Fatal(err) + } + + err = tme.wr.MigrateReads(ctx, tme.targetKeyspace, "test", topodatapb.TabletType_REPLICA, nil, DirectionForward) + if err != nil { + t.Fatal(err) + } + + bls1 := &binlogdatapb.BinlogSource{ + Keyspace: "ks1", + Shard: "-40", + Filter: &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{{ + Match: "/.*", + Filter: "", + }}, + }, + } + tme.dbTargetClients[0].addQuery(vreplQueryks2, sqltypes.MakeTestResult(sqltypes.MakeTestFields( + "id|source|message", + "int64|varchar|varchar"), + fmt.Sprintf("1|%v|FROZEN", bls1), + ), nil) + tme.dbTargetClients[1].addQuery(vreplQueryks2, &sqltypes.Result{}, nil) + + err = tme.wr.MigrateReads(ctx, tme.targetKeyspace, "test", topodatapb.TabletType_REPLICA, nil, DirectionForward) + want := "cannot migrate reads while MigrateWrites is in progress" + if err == nil || err.Error() != want { + t.Errorf("MigrateReads(frozen) err: %v, want %v", err, want) + } + + tme.dbTargetClients[0].addQuery(vreplQueryks2, sqltypes.MakeTestResult(sqltypes.MakeTestFields( + "id|source|message", + "int64|varchar|varchar"), + fmt.Sprintf("1|%v|FROZEN", bls1), + ), nil) + tme.dbTargetClients[1].addQuery(vreplQueryks2, &sqltypes.Result{}, nil) + + deleteTargetVReplication := func() { + tme.dbTargetClients[0].addQuery("select id from _vt.vreplication where db_name = 'vt_ks2' and workflow = 'test'", resultid1, nil) + tme.dbTargetClients[0].addQuery("update _vt.vreplication set message = 'FROZEN' where id in (1)", &sqltypes.Result{}, nil) + tme.dbTargetClients[0].addQuery("select * from _vt.vreplication where id = 1", stoppedResult(1), nil) + + tme.dbTargetClients[0].addQuery("select id from _vt.vreplication where db_name = 'vt_ks2' and workflow = 'test'", resultid1, nil) + tme.dbTargetClients[0].addQuery("delete from _vt.vreplication where id in (1)", &sqltypes.Result{}, nil) + tme.dbTargetClients[0].addQuery("delete from _vt.copy_state where vrepl_id in (1)", &sqltypes.Result{}, nil) + } + deleteTargetVReplication() + + _, err = tme.wr.MigrateWrites(ctx, tme.targetKeyspace, "test", 0*time.Second, false, true) + if err != nil { + t.Fatal(err) + } + verifyQueries(t, tme.allDBClients) +} + func TestMigrateNoStreamsFound(t *testing.T) { ctx := context.Background() tme := newTestTableMigrater(ctx, t) defer tme.stopTablets(t) - tme.dbDest1Client.addQuery(vreplQueryks2, &sqltypes.Result{}, nil) - tme.dbDest2Client.addQuery(vreplQueryks2, &sqltypes.Result{}, nil) + tme.dbTargetClients[0].addQuery(vreplQueryks2, &sqltypes.Result{}, nil) + tme.dbTargetClients[1].addQuery(vreplQueryks2, &sqltypes.Result{}, nil) err := tme.wr.MigrateReads(ctx, tme.targetKeyspace, "test", topodatapb.TabletType_RDONLY, nil, DirectionForward) want := "no streams found in keyspace ks2 for: test" @@ -793,10 +1381,10 @@ func TestMigrateDistinctSources(t *testing.T) { }}, }, } - tme.dbDest1Client.addQuery(vreplQueryks2, sqltypes.MakeTestResult(sqltypes.MakeTestFields( - "id|source", - "int64|varchar"), - fmt.Sprintf("1|%v", bls), + tme.dbTargetClients[0].addQuery(vreplQueryks2, sqltypes.MakeTestResult(sqltypes.MakeTestFields( + "id|source|message", + "int64|varchar|varchar"), + fmt.Sprintf("1|%v|", bls), ), nil) err := tme.wr.MigrateReads(ctx, tme.targetKeyspace, "test", topodatapb.TabletType_RDONLY, nil, DirectionForward) @@ -821,11 +1409,12 @@ func TestMigrateMismatchedTables(t *testing.T) { }}, }, } - tme.dbDest1Client.addQuery(vreplQueryks2, sqltypes.MakeTestResult(sqltypes.MakeTestFields( - "id|source", - "int64|varchar"), - fmt.Sprintf("1|%v", bls), - ), nil) + tme.dbTargetClients[0].addQuery(vreplQueryks2, sqltypes.MakeTestResult(sqltypes.MakeTestFields( + "id|source|message", + "int64|varchar|varchar"), + fmt.Sprintf("1|%v|", bls)), + nil, + ) err := tme.wr.MigrateReads(ctx, tme.targetKeyspace, "test", topodatapb.TabletType_RDONLY, nil, DirectionForward) want := "table lists are mismatched across streams" @@ -839,7 +1428,7 @@ func TestTableMigrateAllShardsNotPresent(t *testing.T) { tme := newTestTableMigrater(ctx, t) defer tme.stopTablets(t) - tme.dbDest1Client.addQuery(vreplQueryks2, &sqltypes.Result{}, nil) + tme.dbTargetClients[0].addQuery(vreplQueryks2, &sqltypes.Result{}, nil) err := tme.wr.MigrateReads(ctx, tme.targetKeyspace, "test", topodatapb.TabletType_RDONLY, nil, DirectionForward) want := "mismatched shards for keyspace" @@ -873,11 +1462,11 @@ func TestMigrateNoTableWildcards(t *testing.T) { }}, }, } - tme.dbDest1Client.addQuery(vreplQueryks2, sqltypes.MakeTestResult(sqltypes.MakeTestFields( - "id|source", - "int64|varchar"), - fmt.Sprintf("1|%v", bls1), - fmt.Sprintf("2|%v", bls2), + tme.dbTargetClients[0].addQuery(vreplQueryks2, sqltypes.MakeTestResult(sqltypes.MakeTestFields( + "id|source|message", + "int64|varchar|varchar"), + fmt.Sprintf("1|%v|", bls1), + fmt.Sprintf("2|%v|", bls2), ), nil) bls3 := &binlogdatapb.BinlogSource{ Keyspace: "ks1", @@ -889,10 +1478,10 @@ func TestMigrateNoTableWildcards(t *testing.T) { }}, }, } - tme.dbDest2Client.addQuery(vreplQueryks2, sqltypes.MakeTestResult(sqltypes.MakeTestFields( - "id|source", - "int64|varchar"), - fmt.Sprintf("1|%v", bls3), + tme.dbTargetClients[1].addQuery(vreplQueryks2, sqltypes.MakeTestResult(sqltypes.MakeTestFields( + "id|source|message", + "int64|varchar|varchar"), + fmt.Sprintf("1|%v|", bls3), ), nil) err := tme.wr.MigrateReads(ctx, tme.targetKeyspace, "test", topodatapb.TabletType_RDONLY, nil, DirectionForward) @@ -902,31 +1491,20 @@ func TestMigrateNoTableWildcards(t *testing.T) { } } -func TestShardMigrateTargetMatchesSource(t *testing.T) { - ctx := context.Background() - tme := newTestShardMigrater(ctx, t) - defer tme.stopTablets(t) - - bls := &binlogdatapb.BinlogSource{ - Keyspace: "ks", - Shard: "-80", - Filter: &binlogdatapb.Filter{ - Rules: []*binlogdatapb.Rule{{ - Match: "/.*", - Filter: "-80", - }}, - }, - } - tme.dbDest1Client.addQuery(vreplQueryks, sqltypes.MakeTestResult(sqltypes.MakeTestFields( - "id|source", - "int64|varchar"), - fmt.Sprintf("1|%v", bls), - ), nil) - - err := tme.wr.MigrateReads(ctx, tme.targetKeyspace, "test", topodatapb.TabletType_RDONLY, nil, DirectionForward) - want := "target shard matches a source shard" - if err == nil || !strings.Contains(err.Error(), want) { - t.Errorf("MigrateReads: %v, must contain %v", err, want) +func TestReverseName(t *testing.T) { + tests := []struct { + in, out string + }{{ + in: "aa", + out: "aa_reverse", + }, { + in: "aa_reverse", + out: "aa", + }} + for _, test := range tests { + if got, want := reverseName(test.in), test.out; got != want { + t.Errorf("reverseName(%s): %s, want %s", test.in, got, test.out) + } } } @@ -1037,3 +1615,19 @@ func checkIsMasterServing(t *testing.T, ts *topo.Server, keyspaceShard string, w t.Errorf("IsMasterServing(%v): %v, want %v", keyspaceShard, si.IsMasterServing, want) } } + +func stoppedResult(id int) *sqltypes.Result { + return sqltypes.MakeTestResult(sqltypes.MakeTestFields( + "id|state", + "int64|varchar"), + fmt.Sprintf("%d|Stopped", id), + ) +} + +func runningResult(id int) *sqltypes.Result { + return sqltypes.MakeTestResult(sqltypes.MakeTestFields( + "id|state", + "int64|varchar"), + fmt.Sprintf("%d|Running", id), + ) +} diff --git a/go/vt/wrangler/permissions.go b/go/vt/wrangler/permissions.go index a00e99398e9..c9e490d774c 100644 --- a/go/vt/wrangler/permissions.go +++ b/go/vt/wrangler/permissions.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/wrangler/rebuild.go b/go/vt/wrangler/rebuild.go index d9b0d05d7a1..f942f1d5823 100644 --- a/go/vt/wrangler/rebuild.go +++ b/go/vt/wrangler/rebuild.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/wrangler/reparent.go b/go/vt/wrangler/reparent.go index 06b99e21f32..1d63aa748a3 100644 --- a/go/vt/wrangler/reparent.go +++ b/go/vt/wrangler/reparent.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -35,15 +35,18 @@ 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/vterrors" replicationdatapb "vitess.io/vitess/go/vt/proto/replicationdata" topodatapb "vitess.io/vitess/go/vt/proto/topodata" + vtrpcpb "vitess.io/vitess/go/vt/proto/vtrpc" ) const ( - initShardMasterOperation = "InitShardMaster" - plannedReparentShardOperation = "PlannedReparentShard" - emergencyReparentShardOperation = "EmergencyReparentShard" + initShardMasterOperation = "InitShardMaster" + plannedReparentShardOperation = "PlannedReparentShard" + emergencyReparentShardOperation = "EmergencyReparentShard" + tabletExternallyReparentedOperation = "TabletExternallyReparented" ) // ShardReplicationStatuses returns the ReplicationStatus for each tablet in a shard. @@ -127,11 +130,11 @@ func (wr *Wrangler) ReparentTablet(ctx context.Context, tabletAlias *topodatapb. } // and do the remote command - return wr.tmc.SetMaster(ctx, ti.Tablet, shardInfo.MasterAlias, 0, false) + return wr.tmc.SetMaster(ctx, ti.Tablet, shardInfo.MasterAlias, 0, "", false) } // InitShardMaster will make the provided tablet the master for the shard. -func (wr *Wrangler) InitShardMaster(ctx context.Context, keyspace, shard string, masterElectTabletAlias *topodatapb.TabletAlias, force bool, waitSlaveTimeout time.Duration) (err error) { +func (wr *Wrangler) InitShardMaster(ctx context.Context, keyspace, shard string, masterElectTabletAlias *topodatapb.TabletAlias, force bool, waitReplicasTimeout time.Duration) (err error) { // lock the shard ctx, unlock, lockErr := wr.ts.LockShard(ctx, keyspace, shard, fmt.Sprintf("InitShardMaster(%v)", topoproto.TabletAliasString(masterElectTabletAlias))) if lockErr != nil { @@ -143,7 +146,7 @@ func (wr *Wrangler) InitShardMaster(ctx context.Context, keyspace, shard string, ev := &events.Reparent{} // do the work - err = wr.initShardMasterLocked(ctx, ev, keyspace, shard, masterElectTabletAlias, force, waitSlaveTimeout) + err = wr.initShardMasterLocked(ctx, ev, keyspace, shard, masterElectTabletAlias, force, waitReplicasTimeout) if err != nil { event.DispatchUpdate(ev, "failed InitShardMaster: "+err.Error()) } else { @@ -152,7 +155,7 @@ func (wr *Wrangler) InitShardMaster(ctx context.Context, keyspace, shard string, return err } -func (wr *Wrangler) initShardMasterLocked(ctx context.Context, ev *events.Reparent, keyspace, shard string, masterElectTabletAlias *topodatapb.TabletAlias, force bool, waitSlaveTimeout time.Duration) error { +func (wr *Wrangler) initShardMasterLocked(ctx context.Context, ev *events.Reparent, keyspace, shard string, masterElectTabletAlias *topodatapb.TabletAlias, force bool, waitReplicasTimeout time.Duration) error { shardInfo, err := wr.ts.GetShard(ctx, keyspace, shard) if err != nil { return err @@ -205,8 +208,8 @@ func (wr *Wrangler) initShardMasterLocked(ctx context.Context, ev *events.Repare // an unstable database process in the mix, with a database daemon // at a wrong replication spot. - // Create a context for the following RPCs that respects waitSlaveTimeout - resetCtx, resetCancel := context.WithTimeout(ctx, waitSlaveTimeout) + // Create a context for the following RPCs that respects waitReplicasTimeout + resetCtx, resetCancel := context.WithTimeout(ctx, waitReplicasTimeout) defer resetCancel() event.DispatchUpdate(ev, "resetting replication on all tablets") @@ -249,7 +252,7 @@ func (wr *Wrangler) initShardMasterLocked(ctx context.Context, ev *events.Repare // Create a cancelable context for the following RPCs. // If error conditions happen, we can cancel all outgoing RPCs. - replCtx, replCancel := context.WithTimeout(ctx, waitSlaveTimeout) + replCtx, replCancel := context.WithTimeout(ctx, waitReplicasTimeout) defer replCancel() // Now tell the new master to insert the reparent_journal row, @@ -328,7 +331,7 @@ func (wr *Wrangler) initShardMasterLocked(ctx context.Context, ev *events.Repare // PlannedReparentShard will make the provided tablet the master for the shard, // when both the current and new master are reachable and in good shape. -func (wr *Wrangler) PlannedReparentShard(ctx context.Context, keyspace, shard string, masterElectTabletAlias, avoidMasterAlias *topodatapb.TabletAlias, waitSlaveTimeout time.Duration) (err error) { +func (wr *Wrangler) PlannedReparentShard(ctx context.Context, keyspace, shard string, masterElectTabletAlias, avoidMasterAlias *topodatapb.TabletAlias, waitReplicasTimeout time.Duration) (err error) { // lock the shard lockAction := fmt.Sprintf( "PlannedReparentShard(%v, avoid_master=%v)", @@ -353,7 +356,7 @@ func (wr *Wrangler) PlannedReparentShard(ctx context.Context, keyspace, shard st } // do the work - err = wr.plannedReparentShardLocked(ctx, ev, keyspace, shard, masterElectTabletAlias, avoidMasterAlias, waitSlaveTimeout) + err = wr.plannedReparentShardLocked(ctx, ev, keyspace, shard, masterElectTabletAlias, avoidMasterAlias, waitReplicasTimeout) if err != nil { event.DispatchUpdate(ev, "failed PlannedReparentShard: "+err.Error()) } else { @@ -362,7 +365,7 @@ func (wr *Wrangler) PlannedReparentShard(ctx context.Context, keyspace, shard st return err } -func (wr *Wrangler) plannedReparentShardLocked(ctx context.Context, ev *events.Reparent, keyspace, shard string, masterElectTabletAlias, avoidMasterTabletAlias *topodatapb.TabletAlias, waitSlaveTimeout time.Duration) error { +func (wr *Wrangler) plannedReparentShardLocked(ctx context.Context, ev *events.Reparent, keyspace, shard string, masterElectTabletAlias, avoidMasterTabletAlias *topodatapb.TabletAlias, waitReplicasTimeout time.Duration) error { shardInfo, err := wr.ts.GetShard(ctx, keyspace, shard) if err != nil { return err @@ -375,7 +378,7 @@ func (wr *Wrangler) plannedReparentShardLocked(ctx context.Context, ev *events.R return err } - // Check corner cases we're going to depend on + // Check invariants we're going to depend on. if topoproto.TabletAliasEqual(masterElectTabletAlias, avoidMasterTabletAlias) { return fmt.Errorf("master-elect tablet %v is the same as the tablet to avoid", topoproto.TabletAliasString(masterElectTabletAlias)) } @@ -385,7 +388,7 @@ func (wr *Wrangler) plannedReparentShardLocked(ctx context.Context, ev *events.R return nil } event.DispatchUpdate(ev, "searching for master candidate") - masterElectTabletAlias, err = wr.chooseNewMaster(ctx, shardInfo, tabletMap, avoidMasterTabletAlias, waitSlaveTimeout) + masterElectTabletAlias, err = wr.chooseNewMaster(ctx, shardInfo, tabletMap, avoidMasterTabletAlias, waitReplicasTimeout) if err != nil { return err } @@ -401,139 +404,353 @@ func (wr *Wrangler) plannedReparentShardLocked(ctx context.Context, ev *events.R return fmt.Errorf("master-elect tablet %v is not in the shard", masterElectTabletAliasStr) } ev.NewMaster = *masterElectTabletInfo.Tablet - if topoproto.TabletAliasEqual(shardInfo.MasterAlias, masterElectTabletAlias) { - return fmt.Errorf("master-elect tablet %v is already the master", masterElectTabletAliasStr) - } if topoproto.TabletAliasIsZero(shardInfo.MasterAlias) { return fmt.Errorf("the shard has no master, use EmergencyReparentShard") } - oldMasterTabletInfo, ok := tabletMap[topoproto.TabletAliasString(shardInfo.MasterAlias)] - if !ok { - return fmt.Errorf("old master tablet %v is not in the shard", topoproto.TabletAliasString(shardInfo.MasterAlias)) - } - ev.OldMaster = *oldMasterTabletInfo.Tablet - // create a new context for the short running remote operations - remoteCtx, remoteCancel := context.WithTimeout(ctx, *topo.RemoteOperationTimeout) - defer remoteCancel() + // Find the current master (if any) based on the tablet states. We no longer + // trust the shard record for this, because it is updated asynchronously. + currentMaster := wr.findCurrentMaster(tabletMap) - // Demote the current master, get its replication position - wr.logger.Infof("demote current master %v", shardInfo.MasterAlias) - event.DispatchUpdate(ev, "demoting old master") - rp, err := wr.tmc.DemoteMaster(remoteCtx, oldMasterTabletInfo.Tablet) - if err != nil { - return fmt.Errorf("old master tablet %v DemoteMaster failed: %v", topoproto.TabletAliasString(shardInfo.MasterAlias), err) - } + var reparentJournalPos string - remoteCtx, remoteCancel = context.WithTimeout(ctx, waitSlaveTimeout) - defer remoteCancel() + if currentMaster == nil { + // We don't know who the current master is. Either there is no current + // master at all (no tablet claims to be MASTER), or there is no clear + // winner (multiple MASTER tablets with the same timestamp). + // Check if it's safe to promote the selected master candidate. + wr.logger.Infof("No clear winner found for current master term; checking if it's safe to recover by electing %v", masterElectTabletAliasStr) - // Wait on the master-elect tablet until it reaches that position, - // then promote it - wr.logger.Infof("promote slave %v", masterElectTabletAliasStr) - event.DispatchUpdate(ev, "promoting slave") - rp, err = wr.tmc.PromoteSlaveWhenCaughtUp(remoteCtx, masterElectTabletInfo.Tablet, rp) - if err != nil || (ctx.Err() != nil && ctx.Err() == context.DeadlineExceeded) { - remoteCancel() - // if this fails it is not enough to return an error. we should rollback all the changes made by DemoteMaster - remoteCtx, remoteCancel = context.WithTimeout(ctx, *topo.RemoteOperationTimeout) - defer remoteCancel() - if err1 := wr.tmc.UndoDemoteMaster(remoteCtx, oldMasterTabletInfo.Tablet); err1 != nil { - log.Warningf("Encountered error %v while trying to undo DemoteMaster", err1) + // As we contact each tablet, we'll send its replication position here. + type tabletPos struct { + tabletAliasStr string + tablet *topodatapb.Tablet + pos mysql.Position + } + positions := make(chan tabletPos, len(tabletMap)) + + // First stop the world, to ensure no writes are happening anywhere. + // Since we don't trust that we know which tablets might be acting as + // masters, we simply demote everyone. + // + // Unlike the normal, single-master case, we don't try to undo this if + // we bail out. If we're here, it means there is no clear master, so we + // don't know that it's safe to roll back to the previous state. + // Leaving everything read-only is probably safer than whatever weird + // state we were in before. + // + // If any tablets are unreachable, we can't be sure it's safe, because + // one of the unreachable ones might have a replication position farther + // ahead than the candidate master. + wgStopAll := sync.WaitGroup{} + rec := concurrency.AllErrorRecorder{} + + stopAllCtx, stopAllCancel := context.WithTimeout(ctx, *topo.RemoteOperationTimeout) + defer stopAllCancel() + + for tabletAliasStr, tablet := range tabletMap { + wgStopAll.Add(1) + go func(tabletAliasStr string, tablet *topodatapb.Tablet) { + defer wgStopAll.Done() + + // Regardless of what type this tablet thinks it is, we always + // call DemoteMaster to ensure the underlying MySQL is read-only + // and to check its replication position. DemoteMaster is + // idempotent so it's fine to call it on a replica that's + // already read-only. + wr.logger.Infof("demote tablet %v", tabletAliasStr) + posStr, err := wr.tmc.DemoteMaster(stopAllCtx, tablet) + if err != nil { + rec.RecordError(vterrors.Wrapf(err, "DemoteMaster failed on contested master %v", tabletAliasStr)) + return + } + pos, err := mysql.DecodePosition(posStr) + if err != nil { + rec.RecordError(vterrors.Wrapf(err, "can't decode replication position for tablet %v", tabletAliasStr)) + return + } + positions <- tabletPos{ + tabletAliasStr: tabletAliasStr, + tablet: tablet, + pos: pos, + } + }(tabletAliasStr, tablet.Tablet) + } + wgStopAll.Wait() + close(positions) + if rec.HasErrors() { + return vterrors.Wrap(rec.Error(), "failed to demote all tablets") + } + + // Make a map of tablet positions. + tabletPosMap := make(map[string]tabletPos, len(tabletMap)) + for tp := range positions { + tabletPosMap[tp.tabletAliasStr] = tp + } + + // Make sure no tablet has a replication position farther ahead than the + // candidate master. It's up to our caller to choose a suitable + // candidate, and to choose another one if this check fails. + // + // Note that we still allow replication to run during this time, but we + // assume that no new high water mark can appear because we demoted all + // tablets to read-only. + // + // TODO: Consider temporarily replicating from another tablet to catch up. + tp, ok := tabletPosMap[masterElectTabletAliasStr] + if !ok { + return vterrors.Errorf(vtrpcpb.Code_FAILED_PRECONDITION, "master-elect tablet %v not found in tablet map", masterElectTabletAliasStr) + } + masterElectPos := tp.pos + for _, tp := range tabletPosMap { + // The master elect pos has to be at least as far as every tablet. + if !masterElectPos.AtLeast(tp.pos) { + return vterrors.Errorf(vtrpcpb.Code_FAILED_PRECONDITION, "tablet %v position (%v) contains transactions not found in master-elect %v position (%v)", + tp.tabletAliasStr, tp.pos, masterElectTabletAliasStr, masterElectPos) + } + } + + // Check we still have the topology lock. + if err := topo.CheckShardLocked(ctx, keyspace, shard); err != nil { + return vterrors.Wrap(err, "lost topology lock; aborting") + } + + // Promote the selected candidate to master. + promoteCtx, promoteCancel := context.WithTimeout(ctx, *topo.RemoteOperationTimeout) + defer promoteCancel() + rp, err := wr.tmc.PromoteSlave(promoteCtx, masterElectTabletInfo.Tablet) + if err != nil { + return vterrors.Wrapf(err, "failed to promote %v to master", masterElectTabletAliasStr) + } + reparentJournalPos = rp + } else if topoproto.TabletAliasEqual(currentMaster.Alias, masterElectTabletAlias) { + refreshCtx, refreshCancel := context.WithTimeout(ctx, *topo.RemoteOperationTimeout) + defer refreshCancel() + + // The master is already the one we want according to its tablet record. + // Refresh it to make sure the tablet has read its record recently. + if err := wr.tmc.RefreshState(refreshCtx, masterElectTabletInfo.Tablet); err != nil { + return vterrors.Wrapf(err, "failed to RefreshState on current master %v", masterElectTabletAliasStr) + } + + // Then get the position so we can try to fix replicas (below). + rp, err := wr.tmc.MasterPosition(refreshCtx, masterElectTabletInfo.Tablet) + if err != nil { + return vterrors.Wrapf(err, "failed to get replication position of current master %v", masterElectTabletAliasStr) } - return fmt.Errorf("master-elect tablet %v failed to catch up with replication or be upgraded to master: %v", masterElectTabletAliasStr, err) + reparentJournalPos = rp + } else { + // There is already a master and it's not the one we want. + oldMasterTabletInfo := currentMaster + ev.OldMaster = *oldMasterTabletInfo.Tablet + + // Before demoting the old master, first make sure replication is + // working from the old master to the candidate master. If it's not + // working, we can't do a planned reparent because the candidate won't + // catch up. + wr.logger.Infof("Checking replication on master-elect %v", masterElectTabletAliasStr) + + // First we find the position of the current master. Note that this is + // just a snapshot of the position since we let it keep accepting new + // writes until we're sure we're going to proceed. + snapshotCtx, snapshotCancel := context.WithTimeout(ctx, *topo.RemoteOperationTimeout) + defer snapshotCancel() + + snapshotPos, err := wr.tmc.MasterPosition(snapshotCtx, currentMaster.Tablet) + if err != nil { + return vterrors.Wrapf(err, "can't get replication position on current master %v; current master must be healthy to perform planned reparent", currentMaster.AliasString()) + } + + // Now wait for the master-elect to catch up to that snapshot point. + // If it catches up to that point within the waitReplicasTimeout, + // we can be fairly confident it will catch up on everything that's + // happened in the meantime once we demote the master to stop writes. + // + // We do this as an idempotent SetMaster to make sure the replica knows + // who the current master is. + setMasterCtx, setMasterCancel := context.WithTimeout(ctx, waitReplicasTimeout) + defer setMasterCancel() + + err = wr.tmc.SetMaster(setMasterCtx, masterElectTabletInfo.Tablet, currentMaster.Alias, 0, snapshotPos, true) + if err != nil { + return vterrors.Wrapf(err, "replication on master-elect %v did not catch up in time; replication must be healthy to perform planned reparent", masterElectTabletAliasStr) + } + + // Check we still have the topology lock. + if err := topo.CheckShardLocked(ctx, keyspace, shard); err != nil { + return vterrors.Wrap(err, "lost topology lock; aborting") + } + + // Demote the old master and get its replication position. It's fine if + // the old master was already demoted, since DemoteMaster is idempotent. + wr.logger.Infof("demote current master %v", oldMasterTabletInfo.Alias) + event.DispatchUpdate(ev, "demoting old master") + + demoteCtx, demoteCancel := context.WithTimeout(ctx, *topo.RemoteOperationTimeout) + defer demoteCancel() + + rp, err := wr.tmc.DemoteMaster(demoteCtx, oldMasterTabletInfo.Tablet) + if err != nil { + return fmt.Errorf("old master tablet %v DemoteMaster failed: %v", topoproto.TabletAliasString(shardInfo.MasterAlias), err) + } + + // Wait on the master-elect tablet until it reaches that position, + // then promote it. + wr.logger.Infof("promote replica %v", masterElectTabletAliasStr) + event.DispatchUpdate(ev, "promoting replica") + + promoteCtx, promoteCancel := context.WithTimeout(ctx, waitReplicasTimeout) + defer promoteCancel() + + rp, err = wr.tmc.PromoteSlaveWhenCaughtUp(promoteCtx, masterElectTabletInfo.Tablet, rp) + if err != nil || (ctx.Err() != nil && ctx.Err() == context.DeadlineExceeded) { + // If we fail to promote the new master, try to roll back to the + // original master before aborting. + undoCtx, undoCancel := context.WithTimeout(ctx, *topo.RemoteOperationTimeout) + defer undoCancel() + if err1 := wr.tmc.UndoDemoteMaster(undoCtx, oldMasterTabletInfo.Tablet); err1 != nil { + log.Warningf("Encountered error %v while trying to undo DemoteMaster", err1) + } + return fmt.Errorf("master-elect tablet %v failed to catch up with replication or be upgraded to master: %v", masterElectTabletAliasStr, err) + } + reparentJournalPos = rp } - // Check we stil have the topology lock. + // Check we still have the topology lock. if err := topo.CheckShardLocked(ctx, keyspace, shard); err != nil { return fmt.Errorf("lost topology lock, aborting: %v", err) } // Create a cancelable context for the following RPCs. // If error conditions happen, we can cancel all outgoing RPCs. - replCtx, replCancel := context.WithTimeout(ctx, waitSlaveTimeout) + replCtx, replCancel := context.WithTimeout(ctx, waitReplicasTimeout) defer replCancel() // Go through all the tablets: // - new master: populate the reparent journal // - everybody else: reparent to new master, wait for row event.DispatchUpdate(ev, "reparenting all tablets") - now := time.Now().UnixNano() - wgMaster := sync.WaitGroup{} - wgSlaves := sync.WaitGroup{} + + // We add a (hopefully) unique record to the reparent journal table on the + // new master so we can check if replicas got it through replication. + reparentJournalTimestamp := time.Now().UnixNano() + + // Point all replicas at the new master and check that they receive the + // reparent journal entry, proving they are replicating from the new master. + // We do this concurrently with adding the journal entry (below), because + // if semi-sync is enabled, the update to the journal table can't succeed + // until at least one replica is successfully attached to the new master. + wgReplicas := sync.WaitGroup{} rec := concurrency.AllErrorRecorder{} - var masterErr error - oldMasterTabletInfoAliasStr := topoproto.TabletAliasString(oldMasterTabletInfo.Alias) for alias, tabletInfo := range tabletMap { if alias == masterElectTabletAliasStr { - wgMaster.Add(1) - go func(alias string, tabletInfo *topo.TabletInfo) { - defer wgMaster.Done() - wr.logger.Infof("populating reparent journal on new master %v", alias) - masterErr = wr.tmc.PopulateReparentJournal(replCtx, tabletInfo.Tablet, now, plannedReparentShardOperation, masterElectTabletAlias, rp) - }(alias, tabletInfo) - } else { - wgSlaves.Add(1) - go func(alias string, tabletInfo *topo.TabletInfo) { - defer wgSlaves.Done() - wr.logger.Infof("setting new master on slave %v", alias) - // also restart replication on old master - forceStartSlave := alias == oldMasterTabletInfoAliasStr - if err := wr.tmc.SetMaster(replCtx, tabletInfo.Tablet, masterElectTabletAlias, now, forceStartSlave); err != nil { - rec.RecordError(fmt.Errorf("tablet %v SetMaster failed: %v", alias, err)) - return - } - }(alias, tabletInfo) + continue } + wgReplicas.Add(1) + go func(alias string, tabletInfo *topo.TabletInfo) { + defer wgReplicas.Done() + wr.logger.Infof("setting new master on replica %v", alias) + + // We used to force slave start on the old master, but now that + // we support "resuming" a PRS attempt that failed, we can no + // longer assume that we know who the old master was. + // Instead, we rely on the old master to remember that it needs + // to start replication after being converted to a replica. + forceStartReplication := false + + if err := wr.tmc.SetMaster(replCtx, tabletInfo.Tablet, masterElectTabletAlias, reparentJournalTimestamp, "", forceStartReplication); err != nil { + rec.RecordError(fmt.Errorf("tablet %v SetMaster failed: %v", alias, err)) + return + } + }(alias, tabletInfo) } - // After the master is done, we can update the shard record - // (note with semi-sync, it also means at least one slave is done) - wgMaster.Wait() - if masterErr != nil { - // The master failed, there is no way the - // slaves will work. So we cancel them all. - wr.logger.Warningf("master failed to PopulateReparentJournal, canceling slaves") + // Add a reparent journal entry on the new master. + wr.logger.Infof("populating reparent journal on new master %v", masterElectTabletAliasStr) + err = wr.tmc.PopulateReparentJournal(replCtx, masterElectTabletInfo.Tablet, reparentJournalTimestamp, plannedReparentShardOperation, masterElectTabletAlias, reparentJournalPos) + if err != nil { + // The master failed. There's no way the replicas will work, so cancel them all. + wr.logger.Warningf("master failed to PopulateReparentJournal, canceling replica reparent attempts") replCancel() - wgSlaves.Wait() - return fmt.Errorf("failed to PopulateReparentJournal on master: %v", masterErr) - } - wr.logger.Infof("updating shard record with new master %v", masterElectTabletAlias) - if _, err := wr.ts.UpdateShardFields(ctx, keyspace, shard, func(si *topo.ShardInfo) error { - si.MasterAlias = masterElectTabletAlias - return nil - }); err != nil { - wgSlaves.Wait() - return fmt.Errorf("failed to update shard master record: %v", err) + wgReplicas.Wait() + return fmt.Errorf("failed to PopulateReparentJournal on master: %v", err) } - // Wait for the slaves to complete. - wgSlaves.Wait() + // Wait for the replicas to complete. + wgReplicas.Wait() if err := rec.Error(); err != nil { - wr.Logger().Errorf2(err, "some slaves failed to reparent") + wr.Logger().Errorf2(err, "some replicas failed to reparent; retry PlannedReparentShard with the same new master alias to retry failed replicas") return err } return nil } +// findCurrentMaster returns the current master of a shard, if any. +// +// The tabletMap must be a complete map (not a partial result) for the shard. +// +// The current master is whichever MASTER tablet (if any) has the highest +// MasterTermStartTime, which is the same rule that vtgate uses to route master +// traffic. +// +// The return value is nil if the current master can't be definitively +// determined. This can happen either if no tablet claims to be MASTER, or if +// multiple MASTER tablets claim to have the same timestamp (a tie). +func (wr *Wrangler) findCurrentMaster(tabletMap map[string]*topo.TabletInfo) *topo.TabletInfo { + var currentMaster *topo.TabletInfo + var currentMasterTime time.Time + + for _, tablet := range tabletMap { + // Only look at masters. + if tablet.Type != topodatapb.TabletType_MASTER { + continue + } + // Fill in first master we find. + if currentMaster == nil { + currentMaster = tablet + currentMasterTime = tablet.GetMasterTermStartTime() + continue + } + // If we find any other masters, compare timestamps. + newMasterTime := tablet.GetMasterTermStartTime() + if newMasterTime.After(currentMasterTime) { + currentMaster = tablet + currentMasterTime = newMasterTime + continue + } + if newMasterTime.Equal(currentMasterTime) { + // A tie shouldn't happen unless the upgrade order was violated + // (some vttablets have not yet been upgraded) or if we get really + // unlucky. However, if it does happen, we need to be safe and not + // assume we know who the true master is. + wr.logger.Warningf("Multiple masters (%v and %v) are tied for MasterTermStartTime; can't determine the true master.", + topoproto.TabletAliasString(currentMaster.Alias), + topoproto.TabletAliasString(tablet.Alias)) + return nil + } + } + + return currentMaster +} + // maxReplPosSearch is a struct helping to search for a tablet with the largest replication // position querying status from all tablets in parallel. type maxReplPosSearch struct { - wrangler *Wrangler - ctx context.Context - waitSlaveTimeout time.Duration - waitGroup sync.WaitGroup - maxPosLock sync.Mutex - maxPos mysql.Position - maxPosTablet *topodatapb.Tablet + wrangler *Wrangler + ctx context.Context + waitReplicasTimeout time.Duration + waitGroup sync.WaitGroup + maxPosLock sync.Mutex + maxPos mysql.Position + maxPosTablet *topodatapb.Tablet } func (maxPosSearch *maxReplPosSearch) processTablet(tablet *topodatapb.Tablet) { defer maxPosSearch.waitGroup.Done() maxPosSearch.wrangler.logger.Infof("getting replication position from %v", topoproto.TabletAliasString(tablet.Alias)) - slaveStatusCtx, cancelSlaveStatus := context.WithTimeout(maxPosSearch.ctx, maxPosSearch.waitSlaveTimeout) + slaveStatusCtx, cancelSlaveStatus := context.WithTimeout(maxPosSearch.ctx, maxPosSearch.waitReplicasTimeout) defer cancelSlaveStatus() status, err := maxPosSearch.wrangler.tmc.SlaveStatus(slaveStatusCtx, tablet) @@ -567,7 +784,7 @@ func (wr *Wrangler) chooseNewMaster( shardInfo *topo.ShardInfo, tabletMap map[string]*topo.TabletInfo, avoidMasterTabletAlias *topodatapb.TabletAlias, - waitSlaveTimeout time.Duration) (*topodatapb.TabletAlias, error) { + waitReplicasTimeout time.Duration) (*topodatapb.TabletAlias, error) { if avoidMasterTabletAlias == nil { return nil, fmt.Errorf("tablet to avoid for reparent is not provided, cannot choose new master") @@ -578,11 +795,11 @@ func (wr *Wrangler) chooseNewMaster( } maxPosSearch := maxReplPosSearch{ - wrangler: wr, - ctx: ctx, - waitSlaveTimeout: waitSlaveTimeout, - waitGroup: sync.WaitGroup{}, - maxPosLock: sync.Mutex{}, + wrangler: wr, + ctx: ctx, + waitReplicasTimeout: waitReplicasTimeout, + waitGroup: sync.WaitGroup{}, + maxPosLock: sync.Mutex{}, } for _, tabletInfo := range tabletMap { if (masterCell != "" && tabletInfo.Alias.Cell != masterCell) || @@ -603,7 +820,7 @@ func (wr *Wrangler) chooseNewMaster( // EmergencyReparentShard will make the provided tablet the master for // the shard, when the old master is completely unreachable. -func (wr *Wrangler) EmergencyReparentShard(ctx context.Context, keyspace, shard string, masterElectTabletAlias *topodatapb.TabletAlias, waitSlaveTimeout time.Duration) (err error) { +func (wr *Wrangler) EmergencyReparentShard(ctx context.Context, keyspace, shard string, masterElectTabletAlias *topodatapb.TabletAlias, waitReplicasTimeout time.Duration) (err error) { // lock the shard ctx, unlock, lockErr := wr.ts.LockShard(ctx, keyspace, shard, fmt.Sprintf("EmergencyReparentShard(%v)", topoproto.TabletAliasString(masterElectTabletAlias))) if lockErr != nil { @@ -615,7 +832,7 @@ func (wr *Wrangler) EmergencyReparentShard(ctx context.Context, keyspace, shard ev := &events.Reparent{} // do the work - err = wr.emergencyReparentShardLocked(ctx, ev, keyspace, shard, masterElectTabletAlias, waitSlaveTimeout) + err = wr.emergencyReparentShardLocked(ctx, ev, keyspace, shard, masterElectTabletAlias, waitReplicasTimeout) if err != nil { event.DispatchUpdate(ev, "failed EmergencyReparentShard: "+err.Error()) } else { @@ -624,7 +841,7 @@ func (wr *Wrangler) EmergencyReparentShard(ctx context.Context, keyspace, shard return err } -func (wr *Wrangler) emergencyReparentShardLocked(ctx context.Context, ev *events.Reparent, keyspace, shard string, masterElectTabletAlias *topodatapb.TabletAlias, waitSlaveTimeout time.Duration) error { +func (wr *Wrangler) emergencyReparentShardLocked(ctx context.Context, ev *events.Reparent, keyspace, shard string, masterElectTabletAlias *topodatapb.TabletAlias, waitReplicasTimeout time.Duration) error { shardInfo, err := wr.ts.GetShard(ctx, keyspace, shard) if err != nil { return err @@ -637,7 +854,7 @@ func (wr *Wrangler) emergencyReparentShardLocked(ctx context.Context, ev *events return err } - // Check corner cases we're going to depend on + // Check invariants we're going to depend on. masterElectTabletAliasStr := topoproto.TabletAliasString(masterElectTabletAlias) masterElectTabletInfo, ok := tabletMap[masterElectTabletAliasStr] if !ok { @@ -668,7 +885,7 @@ func (wr *Wrangler) emergencyReparentShardLocked(ctx context.Context, ev *events ev.OldMaster = *oldMasterTabletInfo.Tablet wr.logger.Infof("deleting old master %v", shardInfoMasterAliasStr) - ctx, cancel := context.WithTimeout(ctx, waitSlaveTimeout) + ctx, cancel := context.WithTimeout(ctx, waitReplicasTimeout) defer cancel() if err := topotools.DeleteTablet(ctx, wr.ts, oldMasterTabletInfo.Tablet); err != nil { @@ -688,7 +905,7 @@ func (wr *Wrangler) emergencyReparentShardLocked(ctx context.Context, ev *events go func(alias string, tabletInfo *topo.TabletInfo) { defer wg.Done() wr.logger.Infof("getting replication position from %v", alias) - ctx, cancel := context.WithTimeout(ctx, waitSlaveTimeout) + ctx, cancel := context.WithTimeout(ctx, waitReplicasTimeout) defer cancel() rp, err := wr.tmc.StopReplicationAndGetStatus(ctx, tabletInfo.Tablet) if err != nil { @@ -775,15 +992,13 @@ func (wr *Wrangler) emergencyReparentShardLocked(ctx context.Context, ev *events if status, ok := statusMap[alias]; ok { forceStartSlave = status.SlaveIoRunning || status.SlaveSqlRunning } - if err := wr.tmc.SetMaster(replCtx, tabletInfo.Tablet, masterElectTabletAlias, now, forceStartSlave); err != nil { + if err := wr.tmc.SetMaster(replCtx, tabletInfo.Tablet, masterElectTabletAlias, now, "", forceStartSlave); err != nil { rec.RecordError(fmt.Errorf("tablet %v SetMaster failed: %v", alias, err)) } }(alias, tabletInfo) } } - // After the master is done, we can update the shard record - // (note with semi-sync, it also means at least one slave is done) wgMaster.Wait() if masterErr != nil { // The master failed, there is no way the @@ -793,14 +1008,6 @@ func (wr *Wrangler) emergencyReparentShardLocked(ctx context.Context, ev *events wgSlaves.Wait() return fmt.Errorf("failed to PopulateReparentJournal on master: %v", masterErr) } - wr.logger.Infof("updating shard record with new master %v", topoproto.TabletAliasString(masterElectTabletAlias)) - if _, err := wr.ts.UpdateShardFields(ctx, keyspace, shard, func(si *topo.ShardInfo) error { - si.MasterAlias = masterElectTabletAlias - return nil - }); err != nil { - wgSlaves.Wait() - return fmt.Errorf("failed to update shard master record: %v", err) - } // Wait for the slaves to complete. If some of them fail, we // will rebuild the shard serving graph anyway @@ -812,3 +1019,51 @@ func (wr *Wrangler) emergencyReparentShardLocked(ctx context.Context, ev *events return nil } + +// TabletExternallyReparented changes the type of new master for this shard to MASTER +// and updates it's tablet record in the topo. Updating the shard record is handled +// by the new master tablet +func (wr *Wrangler) TabletExternallyReparented(ctx context.Context, newMasterAlias *topodatapb.TabletAlias) error { + + tabletInfo, err := wr.ts.GetTablet(ctx, newMasterAlias) + if err != nil { + log.Warningf("TabletExternallyReparented: failed to read tablet record for %v: %v", newMasterAlias, err) + return err + } + + // Check the global shard record. + tablet := tabletInfo.Tablet + si, err := wr.ts.GetShard(ctx, tablet.Keyspace, tablet.Shard) + if err != nil { + log.Warningf("TabletExternallyReparented: failed to read global shard record for %v/%v: %v", tablet.Keyspace, tablet.Shard, err) + return err + } + + // We update the tablet only if it is not currently master + if tablet.Type != topodatapb.TabletType_MASTER { + log.Infof("TabletExternallyReparented: executing tablet type change to MASTER") + + // Create a reusable Reparent event with available info. + ev := &events.Reparent{ + ShardInfo: *si, + NewMaster: *tablet, + OldMaster: topodatapb.Tablet{ + Alias: si.MasterAlias, + Type: topodatapb.TabletType_MASTER, + }, + } + defer func() { + if err != nil { + event.DispatchUpdate(ev, "failed: "+err.Error()) + } + }() + event.DispatchUpdate(ev, "starting external reparent") + + if err := wr.tmc.ChangeType(ctx, tablet, topodatapb.TabletType_MASTER); err != nil { + log.Warningf("Error calling ChangeType on new master %v: %v", topoproto.TabletAliasString(newMasterAlias), err) + return err + } + event.DispatchUpdate(ev, "finished") + } + return nil +} diff --git a/go/vt/wrangler/schema.go b/go/vt/wrangler/schema.go index fd041172797..9044da86bb6 100644 --- a/go/vt/wrangler/schema.go +++ b/go/vt/wrangler/schema.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/wrangler/shard.go b/go/vt/wrangler/shard.go index e58ae3618db..fb67c5bbc2b 100644 --- a/go/vt/wrangler/shard.go +++ b/go/vt/wrangler/shard.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -28,40 +28,6 @@ import ( // shard related methods for Wrangler -// updateShardCellsAndMaster will update the 'Cells' and possibly -// MasterAlias records for the shard, if needed. -func (wr *Wrangler) updateShardMaster(ctx context.Context, si *topo.ShardInfo, tabletAlias *topodatapb.TabletAlias, tabletType topodatapb.TabletType, allowMasterOverride bool) error { - // See if we need to update the Shard: - // - add the tablet's cell to the shard's Cells if needed - // - change the master if needed - shardUpdateRequired := false - if tabletType == topodatapb.TabletType_MASTER && !topoproto.TabletAliasEqual(si.MasterAlias, tabletAlias) { - shardUpdateRequired = true - } - if !shardUpdateRequired { - return nil - } - - // run the update - _, err := wr.ts.UpdateShardFields(ctx, si.Keyspace(), si.ShardName(), func(s *topo.ShardInfo) error { - wasUpdated := false - - if tabletType == topodatapb.TabletType_MASTER && !topoproto.TabletAliasEqual(s.MasterAlias, tabletAlias) { - if !topoproto.TabletAliasIsZero(s.MasterAlias) && !allowMasterOverride { - return fmt.Errorf("creating this tablet would override old master %v in shard %v/%v", topoproto.TabletAliasString(s.MasterAlias), si.Keyspace(), si.ShardName()) - } - s.MasterAlias = tabletAlias - wasUpdated = true - } - - if !wasUpdated { - return topo.NewError(topo.NoUpdateNeeded, si.Keyspace()+"/"+si.ShardName()) - } - return nil - }) - return err -} - // SetShardIsMasterServing changes the IsMasterServing parameter of a shard. // It does not rebuild any serving graph or do any consistency check. // This is an emergency manual operation. diff --git a/go/vt/wrangler/split.go b/go/vt/wrangler/split.go index 718bfd19ab4..238a73fdc1e 100644 --- a/go/vt/wrangler/split.go +++ b/go/vt/wrangler/split.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/wrangler/stream_migrater.go b/go/vt/wrangler/stream_migrater.go new file mode 100644 index 00000000000..c2f1b2c768d --- /dev/null +++ b/go/vt/wrangler/stream_migrater.go @@ -0,0 +1,626 @@ +/* +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 wrangler + +import ( + "fmt" + "sort" + "strings" + "sync" + "text/template" + "time" + + "github.com/golang/protobuf/proto" + "golang.org/x/net/context" + "vitess.io/vitess/go/mysql" + "vitess.io/vitess/go/sqltypes" + "vitess.io/vitess/go/vt/binlog/binlogplayer" + "vitess.io/vitess/go/vt/concurrency" + "vitess.io/vitess/go/vt/key" + binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" + "vitess.io/vitess/go/vt/sqlparser" + "vitess.io/vitess/go/vt/throttler" + "vitess.io/vitess/go/vt/topo" + "vitess.io/vitess/go/vt/vterrors" + "vitess.io/vitess/go/vt/vtgate/vindexes" + "vitess.io/vitess/go/vt/vttablet/tabletmanager/vreplication" +) + +type streamMigrater struct { + streams map[string][]*vrStream + workflows []string + templates []*vrStream + mi *migrater +} + +type vrStream struct { + id uint32 + workflow string + bls *binlogdatapb.BinlogSource + pos mysql.Position +} + +func buildStreamMigrater(ctx context.Context, mi *migrater, cancelMigrate bool) (*streamMigrater, error) { + sm := &streamMigrater{mi: mi} + if sm.mi.migrationType == binlogdatapb.MigrationType_TABLES { + // Source streams should be stopped only for shard migrations. + return sm, nil + } + streams, err := sm.readSourceStreams(ctx, cancelMigrate) + if err != nil { + return nil, err + } + sm.streams = streams + + // Loop executes only once. + for _, tabletStreams := range sm.streams { + tmpl, err := sm.templatize(ctx, tabletStreams) + if err != nil { + return nil, err + } + sm.workflows = tabletStreamWorkflows(tmpl) + return sm, nil + } + return sm, nil +} + +func (sm *streamMigrater) readSourceStreams(ctx context.Context, cancelMigrate bool) (map[string][]*vrStream, error) { + streams := make(map[string][]*vrStream) + var mu sync.Mutex + err := sm.mi.forAllSources(func(source *miSource) error { + if !cancelMigrate { + // This flow protects us from the following scenario: When we create streams, + // we always do it in two phases. We start them off as Stopped, and then + // update them to Running. If such an operation fails, we may be left with + // lingering Stopped streams. They should actually be cleaned up by the user. + // In the current workflow, we stop streams and restart them. + // Once existing streams are stopped, there will be confusion about which of + // them can be restarted because they will be no different from the lingering streams. + // To prevent this confusion, we first check if there are any stopped streams. + // If so, we request the operator to clean them up, or restart them before going ahead. + // This allows us to assume that all stopped streams can be safely restarted + // if we cancel the operation. + stoppedStreams, err := sm.readTabletStreams(ctx, source.master, "state = 'Stopped'") + if err != nil { + return err + } + if len(stoppedStreams) != 0 { + return fmt.Errorf("cannot migrate until all streams are running: %s", source.si.ShardName()) + } + } + tabletStreams, err := sm.readTabletStreams(ctx, source.master, "") + if err != nil { + return err + } + if len(tabletStreams) == 0 { + // No VReplication is running. So, we have no work to do. + return nil + } + p3qr, err := sm.mi.wr.tmc.VReplicationExec(ctx, source.master.Tablet, fmt.Sprintf("select vrepl_id from _vt.copy_state where vrepl_id in %s", tabletStreamValues(tabletStreams))) + if err != nil { + return err + } + if len(p3qr.Rows) != 0 { + return fmt.Errorf("cannot migrate while vreplication streams in source shards are still copying: %s", source.si.ShardName()) + } + + mu.Lock() + defer mu.Unlock() + streams[source.si.ShardName()] = tabletStreams + return nil + }) + if err != nil { + return nil, err + } + // Validate that streams match across source shards. + streams2 := make(map[string][]*vrStream) + var reference []*vrStream + var refshard string + for k, v := range streams { + if reference == nil { + refshard = k + reference = v + continue + } + streams2[k] = append([]*vrStream(nil), v...) + } + for shard, tabletStreams := range streams2 { + nextStream: + for _, refStream := range reference { + for i := 0; i < len(tabletStreams); i++ { + vrs := tabletStreams[i] + if refStream.workflow == vrs.workflow && + refStream.bls.Keyspace == vrs.bls.Keyspace && + refStream.bls.Shard == vrs.bls.Shard { + // Delete the matched item and scan for the next stream. + tabletStreams = append(tabletStreams[:i], tabletStreams[i+1:]...) + continue nextStream + } + } + return nil, fmt.Errorf("streams are mismatched across source shards: %s vs %s", refshard, shard) + } + if len(tabletStreams) != 0 { + return nil, fmt.Errorf("streams are mismatched across source shards: %s vs %s", refshard, shard) + } + } + return streams, nil +} + +func (sm *streamMigrater) stopStreams(ctx context.Context) ([]string, error) { + if sm.streams == nil { + return nil, nil + } + if err := sm.stopSourceStreams(ctx); err != nil { + return nil, err + } + positions, err := sm.syncSourceStreams(ctx) + if err != nil { + return nil, err + } + return sm.verifyStreamPositions(ctx, positions) +} + +func (sm *streamMigrater) readTabletStreams(ctx context.Context, ti *topo.TabletInfo, constraint string) ([]*vrStream, error) { + var query string + if constraint == "" { + query = fmt.Sprintf("select id, workflow, source, pos from _vt.vreplication where db_name=%s and workflow != %s", encodeString(ti.DbName()), encodeString(sm.mi.reverseWorkflow)) + } else { + query = fmt.Sprintf("select id, workflow, source, pos from _vt.vreplication where db_name=%s and workflow != %s and %s", encodeString(ti.DbName()), encodeString(sm.mi.reverseWorkflow), constraint) + } + p3qr, err := sm.mi.wr.tmc.VReplicationExec(ctx, ti.Tablet, query) + if err != nil { + return nil, err + } + qr := sqltypes.Proto3ToResult(p3qr) + + tabletStreams := make([]*vrStream, 0, len(qr.Rows)) + for _, row := range qr.Rows { + id, err := sqltypes.ToInt64(row[0]) + if err != nil { + return nil, err + } + workflow := row[1].ToString() + if workflow == "" { + return nil, fmt.Errorf("VReplication streams must have named workflows for migration: shard: %s:%s, stream: %d", ti.Keyspace, ti.Shard, id) + } + if workflow == sm.mi.workflow { + return nil, fmt.Errorf("VReplication stream has the same workflow name as the resharding workflow: shard: %s:%s, stream: %d", ti.Keyspace, ti.Shard, id) + } + var bls binlogdatapb.BinlogSource + if err := proto.UnmarshalText(row[2].ToString(), &bls); err != nil { + return nil, err + } + pos, err := mysql.DecodePosition(row[3].ToString()) + if err != nil { + return nil, err + } + tabletStreams = append(tabletStreams, &vrStream{ + id: uint32(id), + workflow: workflow, + bls: &bls, + pos: pos, + }) + } + return tabletStreams, nil +} + +func (sm *streamMigrater) stopSourceStreams(ctx context.Context) error { + stoppedStreams := make(map[string][]*vrStream) + var mu sync.Mutex + err := sm.mi.forAllSources(func(source *miSource) error { + tabletStreams := sm.streams[source.si.ShardName()] + if len(tabletStreams) == 0 { + return nil + } + query := fmt.Sprintf("update _vt.vreplication set state='Stopped', message='for cutover' where id in %s", tabletStreamValues(tabletStreams)) + _, err := sm.mi.wr.tmc.VReplicationExec(ctx, source.master.Tablet, query) + if err != nil { + return err + } + tabletStreams, err = sm.readTabletStreams(ctx, source.master, fmt.Sprintf("id in %s", tabletStreamValues(tabletStreams))) + if err != nil { + return err + } + mu.Lock() + defer mu.Unlock() + stoppedStreams[source.si.ShardName()] = tabletStreams + return nil + }) + if err != nil { + return err + } + sm.streams = stoppedStreams + return nil +} + +func (sm *streamMigrater) syncSourceStreams(ctx context.Context) (map[string]mysql.Position, error) { + stopPositions := make(map[string]mysql.Position) + for _, tabletStreams := range sm.streams { + for _, vrs := range tabletStreams { + key := fmt.Sprintf("%s:%s", vrs.bls.Keyspace, vrs.bls.Shard) + pos, ok := stopPositions[key] + if !ok || vrs.pos.AtLeast(pos) { + stopPositions[key] = vrs.pos + } + } + } + var wg sync.WaitGroup + allErrors := &concurrency.AllErrorRecorder{} + for shard, tabletStreams := range sm.streams { + for _, vrs := range tabletStreams { + key := fmt.Sprintf("%s:%s", vrs.bls.Keyspace, vrs.bls.Shard) + pos := stopPositions[key] + if vrs.pos.Equal(pos) { + continue + } + wg.Add(1) + go func(vrs *vrStream, shard string) { + defer wg.Done() + si, err := sm.mi.wr.ts.GetShard(ctx, sm.mi.sourceKeyspace, vrs.bls.Shard) + if err != nil { + allErrors.RecordError(err) + return + } + master, err := sm.mi.wr.ts.GetTablet(ctx, si.MasterAlias) + if err != nil { + allErrors.RecordError(err) + return + } + query := fmt.Sprintf("update _vt.vreplication set state='Running', stop_pos='%s', message='synchronizing for cutover' where id=%d", mysql.EncodePosition(pos), vrs.id) + if _, err := sm.mi.wr.tmc.VReplicationExec(ctx, master.Tablet, query); err != nil { + allErrors.RecordError(err) + return + } + sm.mi.wr.Logger().Infof("waiting for keyspace:shard: %v:%v, position %v", sm.mi.sourceKeyspace, shard, pos) + if err := sm.mi.wr.tmc.VReplicationWaitForPos(ctx, master.Tablet, int(vrs.id), mysql.EncodePosition(pos)); err != nil { + allErrors.RecordError(err) + return + } + sm.mi.wr.Logger().Infof("position for keyspace:shard: %v:%v reached", sm.mi.sourceKeyspace, shard) + }(vrs, shard) + } + } + wg.Wait() + return stopPositions, allErrors.AggrError(vterrors.Aggregate) +} + +func (sm *streamMigrater) verifyStreamPositions(ctx context.Context, stopPositions map[string]mysql.Position) ([]string, error) { + stoppedStreams := make(map[string][]*vrStream) + var mu sync.Mutex + err := sm.mi.forAllSources(func(source *miSource) error { + tabletStreams := sm.streams[source.si.ShardName()] + if len(tabletStreams) == 0 { + return nil + } + tabletStreams, err := sm.readTabletStreams(ctx, source.master, fmt.Sprintf("id in %s", tabletStreamValues(tabletStreams))) + if err != nil { + return err + } + mu.Lock() + defer mu.Unlock() + stoppedStreams[source.si.ShardName()] = tabletStreams + return nil + }) + if err != nil { + return nil, err + } + + // This is not really required because it's not used later. + // But we keep it up-to-date for good measure. + sm.streams = stoppedStreams + + var oneSet []*vrStream + allErrors := &concurrency.AllErrorRecorder{} + for _, tabletStreams := range stoppedStreams { + if oneSet == nil { + oneSet = tabletStreams + } + for _, vrs := range tabletStreams { + key := fmt.Sprintf("%s:%s", vrs.bls.Keyspace, vrs.bls.Shard) + pos := stopPositions[key] + if !vrs.pos.Equal(pos) { + allErrors.RecordError(fmt.Errorf("%s: stream %d position: %s does not match %s", key, vrs.id, mysql.EncodePosition(vrs.pos), mysql.EncodePosition(pos))) + } + } + } + if allErrors.HasErrors() { + return nil, allErrors.AggrError(vterrors.Aggregate) + } + sm.templates, err = sm.templatize(ctx, oneSet) + if err != nil { + // Unreachable: we've already templatized this before. + return nil, err + } + return tabletStreamWorkflows(sm.templates), allErrors.AggrError(vterrors.Aggregate) +} + +func (sm *streamMigrater) migrateStreams(ctx context.Context) error { + if sm.streams == nil { + return nil + } + + // Delete any previous stray workflows that might have been left-over + // due to a failed migration. + if err := sm.deleteTargetStreams(ctx); err != nil { + return err + } + + return sm.createTargetStreams(ctx, sm.templates) +} + +const ( + unknown = iota + sharded + reference +) + +// templatizeRule replaces keyrange values with {{.}}. +// This can then be used by go's template package to substitute other keyrange values. +func (sm *streamMigrater) templatize(ctx context.Context, tabletStreams []*vrStream) ([]*vrStream, error) { + tabletStreams = copyTabletStreams(tabletStreams) + var shardedStreams []*vrStream + for _, vrs := range tabletStreams { + streamType := unknown + for _, rule := range vrs.bls.Filter.Rules { + typ, err := sm.templatizeRule(ctx, rule) + if err != nil { + return nil, err + } + switch typ { + case sharded: + if streamType == reference { + return nil, fmt.Errorf("cannot migrate streams with a mix of reference and sharded tables: %v", vrs.bls) + } + streamType = sharded + case reference: + if streamType == sharded { + return nil, fmt.Errorf("cannot migrate streams with a mix of reference and sharded tables: %v", vrs.bls) + } + streamType = reference + } + } + if streamType == sharded { + shardedStreams = append(shardedStreams, vrs) + } + } + return shardedStreams, nil +} + +func (sm *streamMigrater) templatizeRule(ctx context.Context, rule *binlogdatapb.Rule) (int, error) { + vtable, ok := sm.mi.sourceKSSchema.Tables[rule.Match] + if !ok { + return 0, fmt.Errorf("table %v not found in vschema", rule.Match) + } + if vtable.Type == vindexes.TypeReference { + return reference, nil + } + switch { + case rule.Filter == "": + return unknown, fmt.Errorf("rule %v does not have a select expression in vreplication", rule) + case key.IsKeyRange(rule.Filter): + rule.Filter = "{{.}}" + return sharded, nil + case rule.Filter == vreplication.ExcludeStr: + return unknown, fmt.Errorf("unexpected rule in vreplication: %v", rule) + default: + err := sm.templatizeKeyRange(ctx, rule) + if err != nil { + return unknown, err + } + return sharded, nil + } +} + +func (sm *streamMigrater) templatizeKeyRange(ctx context.Context, rule *binlogdatapb.Rule) error { + statement, err := sqlparser.Parse(rule.Filter) + if err != nil { + return err + } + sel, ok := statement.(*sqlparser.Select) + if !ok { + return fmt.Errorf("unexpected query: %v", rule.Filter) + } + var expr sqlparser.Expr + if sel.Where != nil { + expr = sel.Where.Expr + } + exprs := sqlparser.SplitAndExpression(nil, expr) + for _, subexpr := range exprs { + funcExpr, ok := subexpr.(*sqlparser.FuncExpr) + if !ok || !funcExpr.Name.EqualString("in_keyrange") { + continue + } + var krExpr sqlparser.SelectExpr + switch len(funcExpr.Exprs) { + case 1: + krExpr = funcExpr.Exprs[0] + case 3: + krExpr = funcExpr.Exprs[2] + default: + return fmt.Errorf("unexpected in_keyrange parameters: %v", sqlparser.String(funcExpr)) + } + aliased, ok := krExpr.(*sqlparser.AliasedExpr) + if !ok { + return fmt.Errorf("unexpected in_keyrange parameters: %v", sqlparser.String(funcExpr)) + } + val, ok := aliased.Expr.(*sqlparser.SQLVal) + if !ok { + return fmt.Errorf("unexpected in_keyrange parameters: %v", sqlparser.String(funcExpr)) + } + if strings.Contains(rule.Filter, "{{") { + return fmt.Errorf("cannot migrate queries that contain '{{' in their string: %s", rule.Filter) + } + val.Val = []byte("{{.}}") + rule.Filter = sqlparser.String(statement) + return nil + } + // There was no in_keyrange expression. Create a new one. + vtable := sm.mi.sourceKSSchema.Tables[rule.Match] + inkr := &sqlparser.FuncExpr{ + Name: sqlparser.NewColIdent("in_keyrange"), + Exprs: sqlparser.SelectExprs{ + &sqlparser.AliasedExpr{Expr: &sqlparser.ColName{Name: vtable.ColumnVindexes[0].Columns[0]}}, + &sqlparser.AliasedExpr{Expr: sqlparser.NewStrVal([]byte(vtable.ColumnVindexes[0].Type))}, + &sqlparser.AliasedExpr{Expr: sqlparser.NewStrVal([]byte("{{.}}"))}, + }, + } + sel.AddWhere(inkr) + rule.Filter = sqlparser.String(statement) + return nil +} + +func (sm *streamMigrater) createTargetStreams(ctx context.Context, tmpl []*vrStream) error { + if len(tmpl) == 0 { + return nil + } + return sm.mi.forAllTargets(func(target *miTarget) error { + tabletStreams := copyTabletStreams(tmpl) + for _, vrs := range tabletStreams { + for _, rule := range vrs.bls.Filter.Rules { + buf := &strings.Builder{} + t := template.Must(template.New("").Parse(rule.Filter)) + if err := t.Execute(buf, key.KeyRangeString(target.si.KeyRange)); err != nil { + return err + } + rule.Filter = buf.String() + } + } + + buf := &strings.Builder{} + buf.WriteString("insert into _vt.vreplication(workflow, source, pos, max_tps, max_replication_lag, time_updated, transaction_timestamp, state, db_name) values ") + prefix := "" + for _, vrs := range tabletStreams { + fmt.Fprintf(buf, "%s(%v, %v, %v, %v, %v, %v, 0, '%v', %v)", + prefix, + encodeString(vrs.workflow), + encodeString(vrs.bls.String()), + encodeString(mysql.EncodePosition(vrs.pos)), + throttler.MaxRateModuleDisabled, + throttler.ReplicationLagModuleDisabled, + time.Now().Unix(), + binlogplayer.BlpStopped, + encodeString(target.master.DbName())) + prefix = ", " + } + _, err := sm.mi.wr.VReplicationExec(ctx, target.master.Alias, buf.String()) + return err + }) +} + +func (sm *streamMigrater) cancelMigration(ctx context.Context) { + if sm.streams == nil { + return + } + + // Ignore error. We still want to restart the source streams if deleteTargetStreams fails. + _ = sm.deleteTargetStreams(ctx) + + err := sm.mi.forAllSources(func(source *miSource) error { + query := fmt.Sprintf("update _vt.vreplication set state='Running', stop_pos=null, message='' where db_name=%s and workflow != %s", encodeString(source.master.DbName()), encodeString(sm.mi.reverseWorkflow)) + _, err := sm.mi.wr.VReplicationExec(ctx, source.master.Alias, query) + return err + }) + if err != nil { + sm.mi.wr.Logger().Errorf("Cancel migration failed: could not restart source streams: %v", err) + } +} + +func (sm *streamMigrater) deleteTargetStreams(ctx context.Context) error { + if len(sm.workflows) == 0 { + return nil + } + workflowList := stringListify(sm.workflows) + err := sm.mi.forAllTargets(func(target *miTarget) error { + query := fmt.Sprintf("delete from _vt.vreplication where db_name=%s and workflow in (%s)", encodeString(target.master.DbName()), workflowList) + _, err := sm.mi.wr.VReplicationExec(ctx, target.master.Alias, query) + return err + }) + if err != nil { + sm.mi.wr.Logger().Warningf("Could not delete migrated streams: %v", err) + } + return err +} + +// streamMigraterFinalize finalizes the stream migration. +// It's a standalone function because it does not use the streamMigrater state. +func streamMigraterfinalize(ctx context.Context, mi *migrater, workflows []string) error { + if len(workflows) == 0 { + return nil + } + workflowList := stringListify(workflows) + err := mi.forAllSources(func(source *miSource) error { + query := fmt.Sprintf("delete from _vt.vreplication where db_name=%s and workflow in (%s)", encodeString(source.master.DbName()), workflowList) + _, err := mi.wr.VReplicationExec(ctx, source.master.Alias, query) + return err + }) + if err != nil { + return err + } + err = mi.forAllTargets(func(target *miTarget) error { + query := fmt.Sprintf("update _vt.vreplication set state='Running' where db_name=%s and workflow in (%s)", encodeString(target.master.DbName()), workflowList) + _, err := mi.wr.VReplicationExec(ctx, target.master.Alias, query) + return err + }) + return err +} + +func tabletStreamValues(tabletStreams []*vrStream) string { + buf := &strings.Builder{} + prefix := "(" + for _, vrs := range tabletStreams { + fmt.Fprintf(buf, "%s%d", prefix, vrs.id) + prefix = ", " + } + buf.WriteString(")") + return buf.String() +} + +func tabletStreamWorkflows(tabletStreams []*vrStream) []string { + workflows := make(map[string]bool) + for _, vrs := range tabletStreams { + workflows[vrs.workflow] = true + } + list := make([]string, 0, len(workflows)) + for k := range workflows { + list = append(list, k) + } + sort.Strings(list) + return list +} + +func stringListify(in []string) string { + buf := &strings.Builder{} + prefix := "" + for _, str := range in { + fmt.Fprintf(buf, "%s%s", prefix, encodeString(str)) + prefix = ", " + } + return buf.String() +} + +func copyTabletStreams(in []*vrStream) []*vrStream { + out := make([]*vrStream, 0, len(in)) + for _, vrs := range in { + out = append(out, &vrStream{ + id: vrs.id, + workflow: vrs.workflow, + bls: proto.Clone(vrs.bls).(*binlogdatapb.BinlogSource), + pos: vrs.pos, + }) + } + return out +} diff --git a/go/vt/wrangler/stream_migrater_test.go b/go/vt/wrangler/stream_migrater_test.go new file mode 100644 index 00000000000..3c6ef0b1d8c --- /dev/null +++ b/go/vt/wrangler/stream_migrater_test.go @@ -0,0 +1,1718 @@ +/* +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 wrangler + +import ( + "encoding/json" + "fmt" + "reflect" + "strings" + "testing" + "time" + + "golang.org/x/net/context" + "vitess.io/vitess/go/sqltypes" + binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" + topodatapb "vitess.io/vitess/go/vt/proto/topodata" + "vitess.io/vitess/go/vt/proto/vschema" + vschemapb "vitess.io/vitess/go/vt/proto/vschema" + "vitess.io/vitess/go/vt/vtgate/vindexes" + "vitess.io/vitess/go/vt/vttablet/tabletmanager/vreplication" +) + +func TestStreamMigrateMainflow(t *testing.T) { + ctx := context.Background() + tme := newTestShardMigrater(ctx, t, []string{"-40", "40-"}, []string{"-80", "80-"}) + defer tme.stopTablets(t) + + // Migrate reads + err := tme.wr.MigrateReads(ctx, tme.targetKeyspace, "test", topodatapb.TabletType_RDONLY, nil, DirectionForward) + if err != nil { + t.Fatal(err) + } + err = tme.wr.MigrateReads(ctx, tme.targetKeyspace, "test", topodatapb.TabletType_REPLICA, nil, DirectionForward) + if err != nil { + t.Fatal(err) + } + + tme.expectCheckJournals() + + stopStreams := func() { + // sm.stopStreams->sm.readSourceStreams->readTabletStreams('Stopped') + tme.dbSourceClients[0].addQuery("select id, workflow, source, pos from _vt.vreplication where db_name='vt_ks' and workflow != 'test_reverse' and state = 'Stopped'", &sqltypes.Result{}, nil) + tme.dbSourceClients[1].addQuery("select id, workflow, source, pos from _vt.vreplication where db_name='vt_ks' and workflow != 'test_reverse' and state = 'Stopped'", &sqltypes.Result{}, nil) + + // pre-compute sourceRows because they're re-read multiple times. + var sourceRows [][]string + for _, sourceTargetShard := range tme.sourceShards { + var rows []string + for j, sourceShard := range tme.sourceShards { + bls := &binlogdatapb.BinlogSource{ + Keyspace: "ks1", + Shard: sourceShard, + Filter: &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{{ + Match: "t1", + Filter: fmt.Sprintf("select * from t1 where in_keyrange('%s')", sourceTargetShard), + }, { + Match: "t2", + Filter: fmt.Sprintf("select * from t2 where in_keyrange('%s')", sourceTargetShard), + }}, + }, + } + rows = append(rows, fmt.Sprintf("%d|t1t2|%v|MariaDB/5-456-888", j+1, bls)) + } + sourceRows = append(sourceRows, rows) + } + + for i, dbclient := range tme.dbSourceClients { + // sm.stopStreams->sm.readSourceStreams->readTabletStreams('') and VReplicationExec(_vt.copy_state) + dbclient.addQuery("select id, workflow, source, pos from _vt.vreplication where db_name='vt_ks' and workflow != 'test_reverse'", sqltypes.MakeTestResult(sqltypes.MakeTestFields( + "id|workflow|source|pos", + "int64|varbinary|varchar|varbinary"), + sourceRows[i]...), + nil) + dbclient.addQuery("select vrepl_id from _vt.copy_state where vrepl_id in (1, 2)", &sqltypes.Result{}, nil) + + // sm.stopStreams->sm.stopSourceStreams->VReplicationExec('Stopped') + dbclient.addQuery("select id from _vt.vreplication where id in (1, 2)", resultid12, nil) + dbclient.addQuery("update _vt.vreplication set state = 'Stopped', message = 'for cutover' where id in (1, 2)", &sqltypes.Result{}, nil) + dbclient.addQuery("select * from _vt.vreplication where id = 1", stoppedResult(1), nil) + dbclient.addQuery("select * from _vt.vreplication where id = 2", stoppedResult(2), nil) + + // sm.stopStreams->sm.stopSourceStreams->sm.readTabletStreams('id in...') + dbclient.addQuery("select id, workflow, source, pos from _vt.vreplication where db_name='vt_ks' and workflow != 'test_reverse' and id in (1, 2)", sqltypes.MakeTestResult(sqltypes.MakeTestFields( + "id|workflow|source|pos", + "int64|varbinary|varchar|varbinary"), + sourceRows[i]...), + nil) + + // sm.stopStreams->sm.verifyStreamPositions->sm.readTabletStreams('id in...') + dbclient.addQuery("select id, workflow, source, pos from _vt.vreplication where db_name='vt_ks' and workflow != 'test_reverse' and id in (1, 2)", sqltypes.MakeTestResult(sqltypes.MakeTestFields( + "id|workflow|source|pos", + "int64|varbinary|varchar|varbinary"), + sourceRows[i]...), + nil) + } + } + stopStreams() + + tme.expectWaitForCatchup() + + migrateStreams := func() { + // sm.migrateStreams->->sm.deleteTargetStreams (no previously migrated streams) + tme.dbTargetClients[0].addQuery("select id from _vt.vreplication where db_name = 'vt_ks' and workflow in ('t1t2')", &sqltypes.Result{}, nil) + tme.dbTargetClients[1].addQuery("select id from _vt.vreplication where db_name = 'vt_ks' and workflow in ('t1t2')", &sqltypes.Result{}, nil) + + // sm.migrateStreams->sm.createTargetStreams + for i, targetShard := range tme.targetShards { + buf := &strings.Builder{} + buf.WriteString("insert into.*vreplication") + for _, sourceShard := range tme.sourceShards { + fmt.Fprintf(buf, ".*t1t2.*ks.*%s.*t1.*in_keyrange.*%s.*t2.*in_keyrange.*%s.*MariaDB/5-456-888.*Stopped", sourceShard, targetShard, targetShard) + } + // Insert id is 3 so it doesn't overlap with the existing streams. + tme.dbTargetClients[i].addQueryRE(buf.String(), &sqltypes.Result{InsertID: 3}, nil) + tme.dbTargetClients[i].addQuery("select * from _vt.vreplication where id = 3", stoppedResult(3), nil) + tme.dbTargetClients[i].addQuery("select * from _vt.vreplication where id = 4", stoppedResult(4), nil) + } + } + migrateStreams() + + // mi.createJouranls (verify workflows are in the insert) + journal := "insert into _vt.resharding_journal.*source_workflows.*t1t2" + tme.dbSourceClients[0].addQueryRE(journal, &sqltypes.Result{}, nil) + tme.dbSourceClients[1].addQueryRE(journal, &sqltypes.Result{}, nil) + + finalize := func() { + // sm.finalize->Source + tme.dbSourceClients[0].addQuery("select id from _vt.vreplication where db_name = 'vt_ks' and workflow in ('t1t2')", resultid12, nil) + tme.dbSourceClients[0].addQuery("delete from _vt.vreplication where id in (1, 2)", &sqltypes.Result{}, nil) + tme.dbSourceClients[0].addQuery("delete from _vt.copy_state where vrepl_id in (1, 2)", &sqltypes.Result{}, nil) + tme.dbSourceClients[1].addQuery("select id from _vt.vreplication where db_name = 'vt_ks' and workflow in ('t1t2')", resultid12, nil) + tme.dbSourceClients[1].addQuery("delete from _vt.vreplication where id in (1, 2)", &sqltypes.Result{}, nil) + tme.dbSourceClients[1].addQuery("delete from _vt.copy_state where vrepl_id in (1, 2)", &sqltypes.Result{}, nil) + + // sm.finalize->Target + tme.dbTargetClients[0].addQuery("select id from _vt.vreplication where db_name = 'vt_ks' and workflow in ('t1t2')", resultid34, nil) + tme.dbTargetClients[1].addQuery("select id from _vt.vreplication where db_name = 'vt_ks' and workflow in ('t1t2')", resultid34, nil) + tme.dbTargetClients[0].addQuery("update _vt.vreplication set state = 'Running' where id in (3, 4)", &sqltypes.Result{}, nil) + tme.dbTargetClients[1].addQuery("update _vt.vreplication set state = 'Running' where id in (3, 4)", &sqltypes.Result{}, nil) + tme.dbTargetClients[0].addQuery("select * from _vt.vreplication where id = 3", stoppedResult(3), nil) + tme.dbTargetClients[1].addQuery("select * from _vt.vreplication where id = 3", stoppedResult(3), nil) + tme.dbTargetClients[0].addQuery("select * from _vt.vreplication where id = 4", stoppedResult(4), nil) + tme.dbTargetClients[1].addQuery("select * from _vt.vreplication where id = 4", stoppedResult(4), nil) + } + finalize() + + tme.expectCreateReverseVReplication() + tme.expectStartReverseVReplication() + tme.expectDeleteTargetVReplication() + + if _, err := tme.wr.MigrateWrites(ctx, tme.targetKeyspace, "test", 1*time.Second, false, true); err != nil { + t.Fatal(err) + } + + checkServedTypes(t, tme.ts, "ks:-40", 0) + checkServedTypes(t, tme.ts, "ks:40-", 0) + checkServedTypes(t, tme.ts, "ks:-80", 3) + checkServedTypes(t, tme.ts, "ks:80-", 3) + + checkIsMasterServing(t, tme.ts, "ks:-40", false) + checkIsMasterServing(t, tme.ts, "ks:40-", false) + checkIsMasterServing(t, tme.ts, "ks:-80", true) + checkIsMasterServing(t, tme.ts, "ks:80-", true) + + verifyQueries(t, tme.allDBClients) +} + +func TestStreamMigrateTwoStreams(t *testing.T) { + ctx := context.Background() + tme := newTestShardMigrater(ctx, t, []string{"-40", "40-"}, []string{"-80", "80-"}) + defer tme.stopTablets(t) + + // Migrate reads + err := tme.wr.MigrateReads(ctx, tme.targetKeyspace, "test", topodatapb.TabletType_RDONLY, nil, DirectionForward) + if err != nil { + t.Fatal(err) + } + err = tme.wr.MigrateReads(ctx, tme.targetKeyspace, "test", topodatapb.TabletType_REPLICA, nil, DirectionForward) + if err != nil { + t.Fatal(err) + } + + tme.expectCheckJournals() + + stopStreams := func() { + // sm.stopStreams->sm.readSourceStreams->readTabletStreams('Stopped') + tme.dbSourceClients[0].addQuery("select id, workflow, source, pos from _vt.vreplication where db_name='vt_ks' and workflow != 'test_reverse' and state = 'Stopped'", &sqltypes.Result{}, nil) + tme.dbSourceClients[1].addQuery("select id, workflow, source, pos from _vt.vreplication where db_name='vt_ks' and workflow != 'test_reverse' and state = 'Stopped'", &sqltypes.Result{}, nil) + + // pre-compute sourceRows because they're re-read multiple times. + var sourceRows [][]string + for _, sourceTargetShard := range tme.sourceShards { + var rows []string + for j, sourceShard := range tme.sourceShards { + bls := &binlogdatapb.BinlogSource{ + Keyspace: "ks1", + Shard: sourceShard, + Filter: &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{{ + Match: "t1", + Filter: fmt.Sprintf("select * from t1 where in_keyrange('%s')", sourceTargetShard), + }, { + Match: "t2", + Filter: fmt.Sprintf("select * from t2 where in_keyrange('%s')", sourceTargetShard), + }}, + }, + } + rows = append(rows, fmt.Sprintf("%d|t1t2|%v|MariaDB/5-456-888", j+1, bls)) + } + for j, sourceShard := range tme.sourceShards { + bls := &binlogdatapb.BinlogSource{ + Keyspace: "ks1", + Shard: sourceShard, + Filter: &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{{ + Match: "t3", + Filter: fmt.Sprintf("select * from t1 where in_keyrange('%s')", sourceTargetShard), + }}, + }, + } + rows = append(rows, fmt.Sprintf("%d|t3|%v|MariaDB/5-456-888", j+3, bls)) + } + sourceRows = append(sourceRows, rows) + } + + for i, dbclient := range tme.dbSourceClients { + // sm.stopStreams->sm.readSourceStreams->readTabletStreams('') and VReplicationExec(_vt.copy_state) + dbclient.addQuery("select id, workflow, source, pos from _vt.vreplication where db_name='vt_ks' and workflow != 'test_reverse'", sqltypes.MakeTestResult(sqltypes.MakeTestFields( + "id|workflow|source|pos", + "int64|varbinary|varchar|varbinary"), + sourceRows[i]...), + nil) + dbclient.addQuery("select vrepl_id from _vt.copy_state where vrepl_id in (1, 2, 3, 4)", &sqltypes.Result{}, nil) + + // sm.stopStreams->sm.stopSourceStreams->VReplicationExec('Stopped') + dbclient.addQuery("select id from _vt.vreplication where id in (1, 2, 3, 4)", resultid1234, nil) + dbclient.addQuery("update _vt.vreplication set state = 'Stopped', message = 'for cutover' where id in (1, 2, 3, 4)", &sqltypes.Result{}, nil) + dbclient.addQuery("select * from _vt.vreplication where id = 1", stoppedResult(1), nil) + dbclient.addQuery("select * from _vt.vreplication where id = 2", stoppedResult(2), nil) + dbclient.addQuery("select * from _vt.vreplication where id = 3", stoppedResult(3), nil) + dbclient.addQuery("select * from _vt.vreplication where id = 4", stoppedResult(3), nil) + + // sm.stopStreams->sm.stopSourceStreams->sm.readTabletStreams('id in...') + dbclient.addQuery("select id, workflow, source, pos from _vt.vreplication where db_name='vt_ks' and workflow != 'test_reverse' and id in (1, 2, 3, 4)", sqltypes.MakeTestResult(sqltypes.MakeTestFields( + "id|workflow|source|pos", + "int64|varbinary|varchar|varbinary"), + sourceRows[i]...), + nil) + + // sm.stopStreams->sm.verifyStreamPositions->sm.readTabletStreams('id in...') + dbclient.addQuery("select id, workflow, source, pos from _vt.vreplication where db_name='vt_ks' and workflow != 'test_reverse' and id in (1, 2, 3, 4)", sqltypes.MakeTestResult(sqltypes.MakeTestFields( + "id|workflow|source|pos", + "int64|varbinary|varchar|varbinary"), + sourceRows[i]...), + nil) + } + } + stopStreams() + + tme.expectWaitForCatchup() + + migrateStreams := func() { + // sm.migrateStreams->->sm.deleteTargetStreams (no previously migrated streams) + tme.dbTargetClients[0].addQuery("select id from _vt.vreplication where db_name = 'vt_ks' and workflow in ('t1t2', 't3')", &sqltypes.Result{}, nil) + tme.dbTargetClients[1].addQuery("select id from _vt.vreplication where db_name = 'vt_ks' and workflow in ('t1t2', 't3')", &sqltypes.Result{}, nil) + + // sm.migrateStreams->sm.createTargetStreams + for i, targetShard := range tme.targetShards { + buf := &strings.Builder{} + buf.WriteString("insert into.*vreplication") + for _, sourceShard := range tme.sourceShards { + fmt.Fprintf(buf, ".*t1t2.*ks.*%s.*t1.*in_keyrange.*%s.*t2.*in_keyrange.*%s.*MariaDB/5-456-888.*Stopped", sourceShard, targetShard, targetShard) + } + for _, sourceShard := range tme.sourceShards { + fmt.Fprintf(buf, ".*t3.*ks.*%s.*t3.*in_keyrange.*%s.*MariaDB/5-456-888.*Stopped", sourceShard, targetShard) + } + // Insert id is 3 so it doesn't overlap with the existing streams. + tme.dbTargetClients[i].addQueryRE(buf.String(), &sqltypes.Result{InsertID: 3}, nil) + tme.dbTargetClients[i].addQuery("select * from _vt.vreplication where id = 3", stoppedResult(3), nil) + tme.dbTargetClients[i].addQuery("select * from _vt.vreplication where id = 4", stoppedResult(4), nil) + tme.dbTargetClients[i].addQuery("select * from _vt.vreplication where id = 5", stoppedResult(5), nil) + tme.dbTargetClients[i].addQuery("select * from _vt.vreplication where id = 6", stoppedResult(6), nil) + } + } + migrateStreams() + + tme.expectCreateJournals() + + finalize := func() { + // sm.finalize->Source + tme.dbSourceClients[0].addQuery("select id from _vt.vreplication where db_name = 'vt_ks' and workflow in ('t1t2', 't3')", resultid1234, nil) + tme.dbSourceClients[0].addQuery("delete from _vt.vreplication where id in (1, 2, 3, 4)", &sqltypes.Result{}, nil) + tme.dbSourceClients[0].addQuery("delete from _vt.copy_state where vrepl_id in (1, 2, 3, 4)", &sqltypes.Result{}, nil) + tme.dbSourceClients[1].addQuery("select id from _vt.vreplication where db_name = 'vt_ks' and workflow in ('t1t2', 't3')", resultid1234, nil) + tme.dbSourceClients[1].addQuery("delete from _vt.vreplication where id in (1, 2, 3, 4)", &sqltypes.Result{}, nil) + tme.dbSourceClients[1].addQuery("delete from _vt.copy_state where vrepl_id in (1, 2, 3, 4)", &sqltypes.Result{}, nil) + + // sm.finalize->Target + tme.dbTargetClients[0].addQuery("select id from _vt.vreplication where db_name = 'vt_ks' and workflow in ('t1t2', 't3')", resultid3456, nil) + tme.dbTargetClients[1].addQuery("select id from _vt.vreplication where db_name = 'vt_ks' and workflow in ('t1t2', 't3')", resultid3456, nil) + tme.dbTargetClients[0].addQuery("update _vt.vreplication set state = 'Running' where id in (3, 4, 5, 6)", &sqltypes.Result{}, nil) + tme.dbTargetClients[1].addQuery("update _vt.vreplication set state = 'Running' where id in (3, 4, 5, 6)", &sqltypes.Result{}, nil) + tme.dbTargetClients[0].addQuery("select * from _vt.vreplication where id = 3", stoppedResult(3), nil) + tme.dbTargetClients[1].addQuery("select * from _vt.vreplication where id = 3", stoppedResult(3), nil) + tme.dbTargetClients[0].addQuery("select * from _vt.vreplication where id = 4", stoppedResult(4), nil) + tme.dbTargetClients[1].addQuery("select * from _vt.vreplication where id = 4", stoppedResult(4), nil) + tme.dbTargetClients[0].addQuery("select * from _vt.vreplication where id = 5", stoppedResult(5), nil) + tme.dbTargetClients[1].addQuery("select * from _vt.vreplication where id = 5", stoppedResult(5), nil) + tme.dbTargetClients[0].addQuery("select * from _vt.vreplication where id = 6", stoppedResult(6), nil) + tme.dbTargetClients[1].addQuery("select * from _vt.vreplication where id = 6", stoppedResult(6), nil) + } + finalize() + + tme.expectCreateReverseVReplication() + tme.expectStartReverseVReplication() + tme.expectDeleteTargetVReplication() + + if _, err := tme.wr.MigrateWrites(ctx, tme.targetKeyspace, "test", 1*time.Second, false, true); err != nil { + t.Fatal(err) + } + + checkServedTypes(t, tme.ts, "ks:-40", 0) + checkServedTypes(t, tme.ts, "ks:40-", 0) + checkServedTypes(t, tme.ts, "ks:-80", 3) + checkServedTypes(t, tme.ts, "ks:80-", 3) + + checkIsMasterServing(t, tme.ts, "ks:-40", false) + checkIsMasterServing(t, tme.ts, "ks:40-", false) + checkIsMasterServing(t, tme.ts, "ks:-80", true) + checkIsMasterServing(t, tme.ts, "ks:80-", true) + + verifyQueries(t, tme.allDBClients) +} + +func TestStreamMigrateOneToMany(t *testing.T) { + ctx := context.Background() + tme := newTestShardMigrater(ctx, t, []string{"0"}, []string{"-80", "80-"}) + defer tme.stopTablets(t) + + // Migrate reads + err := tme.wr.MigrateReads(ctx, tme.targetKeyspace, "test", topodatapb.TabletType_RDONLY, nil, DirectionForward) + if err != nil { + t.Fatal(err) + } + err = tme.wr.MigrateReads(ctx, tme.targetKeyspace, "test", topodatapb.TabletType_REPLICA, nil, DirectionForward) + if err != nil { + t.Fatal(err) + } + + tme.expectCheckJournals() + + stopStreams := func() { + // sm.stopStreams->sm.readSourceStreams->readTabletStreams('Stopped') + tme.dbSourceClients[0].addQuery("select id, workflow, source, pos from _vt.vreplication where db_name='vt_ks' and workflow != 'test_reverse' and state = 'Stopped'", &sqltypes.Result{}, nil) + + // pre-compute sourceRows because they're re-read multiple times. + var sourceRows [][]string + for _, sourceTargetShard := range tme.sourceShards { + var rows []string + for j, sourceShard := range tme.sourceShards { + bls := &binlogdatapb.BinlogSource{ + Keyspace: "ks1", + Shard: sourceShard, + Filter: &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{{ + Match: "t1", + Filter: fmt.Sprintf("select * from t1 where in_keyrange('%s')", sourceTargetShard), + }}, + }, + } + rows = append(rows, fmt.Sprintf("%d|t1|%v|MariaDB/5-456-888", j+1, bls)) + } + sourceRows = append(sourceRows, rows) + } + + for i, dbclient := range tme.dbSourceClients { + // sm.stopStreams->sm.readSourceStreams->readTabletStreams('') and VReplicationExec(_vt.copy_state) + dbclient.addQuery("select id, workflow, source, pos from _vt.vreplication where db_name='vt_ks' and workflow != 'test_reverse'", sqltypes.MakeTestResult(sqltypes.MakeTestFields( + "id|workflow|source|pos", + "int64|varbinary|varchar|varbinary"), + sourceRows[i]...), + nil) + dbclient.addQuery("select vrepl_id from _vt.copy_state where vrepl_id in (1)", &sqltypes.Result{}, nil) + + // sm.stopStreams->sm.stopSourceStreams->VReplicationExec('Stopped') + dbclient.addQuery("select id from _vt.vreplication where id in (1)", resultid1, nil) + dbclient.addQuery("update _vt.vreplication set state = 'Stopped', message = 'for cutover' where id in (1)", &sqltypes.Result{}, nil) + dbclient.addQuery("select * from _vt.vreplication where id = 1", stoppedResult(1), nil) + + // sm.stopStreams->sm.stopSourceStreams->sm.readTabletStreams('id in...') + dbclient.addQuery("select id, workflow, source, pos from _vt.vreplication where db_name='vt_ks' and workflow != 'test_reverse' and id in (1)", sqltypes.MakeTestResult(sqltypes.MakeTestFields( + "id|workflow|source|pos", + "int64|varbinary|varchar|varbinary"), + sourceRows[i]...), + nil) + + // sm.stopStreams->sm.verifyStreamPositions->sm.readTabletStreams('id in...') + dbclient.addQuery("select id, workflow, source, pos from _vt.vreplication where db_name='vt_ks' and workflow != 'test_reverse' and id in (1)", sqltypes.MakeTestResult(sqltypes.MakeTestFields( + "id|workflow|source|pos", + "int64|varbinary|varchar|varbinary"), + sourceRows[i]...), + nil) + } + } + stopStreams() + + tme.expectWaitForCatchup() + + migrateStreams := func() { + // sm.migrateStreams->->sm.deleteTargetStreams (no previously migrated streams) + tme.dbTargetClients[0].addQuery("select id from _vt.vreplication where db_name = 'vt_ks' and workflow in ('t1')", &sqltypes.Result{}, nil) + tme.dbTargetClients[1].addQuery("select id from _vt.vreplication where db_name = 'vt_ks' and workflow in ('t1')", &sqltypes.Result{}, nil) + + // sm.migrateStreams->sm.createTargetStreams + for i, targetShard := range tme.targetShards { + buf := &strings.Builder{} + buf.WriteString("insert into.*vreplication") + for _, sourceShard := range tme.sourceShards { + fmt.Fprintf(buf, ".*t1.*ks.*%s.*t1.*in_keyrange.*%s.*MariaDB/5-456-888.*Stopped", sourceShard, targetShard) + } + // Insert id is 3 so it doesn't overlap with the existing streams. + tme.dbTargetClients[i].addQueryRE(buf.String(), &sqltypes.Result{InsertID: 3}, nil) + tme.dbTargetClients[i].addQuery("select * from _vt.vreplication where id = 3", stoppedResult(3), nil) + } + } + migrateStreams() + + tme.expectCreateJournals() + + finalize := func() { + // sm.finalize->Source + tme.dbSourceClients[0].addQuery("select id from _vt.vreplication where db_name = 'vt_ks' and workflow in ('t1')", resultid1, nil) + tme.dbSourceClients[0].addQuery("delete from _vt.vreplication where id in (1)", &sqltypes.Result{}, nil) + tme.dbSourceClients[0].addQuery("delete from _vt.copy_state where vrepl_id in (1)", &sqltypes.Result{}, nil) + + // sm.finalize->Target + tme.dbTargetClients[0].addQuery("select id from _vt.vreplication where db_name = 'vt_ks' and workflow in ('t1')", resultid3, nil) + tme.dbTargetClients[1].addQuery("select id from _vt.vreplication where db_name = 'vt_ks' and workflow in ('t1')", resultid3, nil) + tme.dbTargetClients[0].addQuery("update _vt.vreplication set state = 'Running' where id in (3)", &sqltypes.Result{}, nil) + tme.dbTargetClients[1].addQuery("update _vt.vreplication set state = 'Running' where id in (3)", &sqltypes.Result{}, nil) + tme.dbTargetClients[0].addQuery("select * from _vt.vreplication where id = 3", stoppedResult(3), nil) + tme.dbTargetClients[1].addQuery("select * from _vt.vreplication where id = 3", stoppedResult(3), nil) + } + finalize() + + tme.expectCreateReverseVReplication() + tme.expectStartReverseVReplication() + tme.expectDeleteTargetVReplication() + + if _, err := tme.wr.MigrateWrites(ctx, tme.targetKeyspace, "test", 1*time.Second, false, true); err != nil { + t.Fatal(err) + } + + checkServedTypes(t, tme.ts, "ks:0", 0) + checkServedTypes(t, tme.ts, "ks:-80", 3) + checkServedTypes(t, tme.ts, "ks:80-", 3) + + checkIsMasterServing(t, tme.ts, "ks:0", false) + checkIsMasterServing(t, tme.ts, "ks:-80", true) + checkIsMasterServing(t, tme.ts, "ks:80-", true) + + verifyQueries(t, tme.allDBClients) +} + +func TestStreamMigrateManyToOne(t *testing.T) { + ctx := context.Background() + // Interesting tidbit: you cannot create a shard "0" for an already sharded keyspace. + tme := newTestShardMigrater(ctx, t, []string{"-80", "80-"}, []string{"-"}) + defer tme.stopTablets(t) + + // Migrate reads + err := tme.wr.MigrateReads(ctx, tme.targetKeyspace, "test", topodatapb.TabletType_RDONLY, nil, DirectionForward) + if err != nil { + t.Fatal(err) + } + err = tme.wr.MigrateReads(ctx, tme.targetKeyspace, "test", topodatapb.TabletType_REPLICA, nil, DirectionForward) + if err != nil { + t.Fatal(err) + } + + tme.expectCheckJournals() + + stopStreams := func() { + // sm.stopStreams->sm.readSourceStreams->readTabletStreams('Stopped') + tme.dbSourceClients[0].addQuery("select id, workflow, source, pos from _vt.vreplication where db_name='vt_ks' and workflow != 'test_reverse' and state = 'Stopped'", &sqltypes.Result{}, nil) + tme.dbSourceClients[1].addQuery("select id, workflow, source, pos from _vt.vreplication where db_name='vt_ks' and workflow != 'test_reverse' and state = 'Stopped'", &sqltypes.Result{}, nil) + + // pre-compute sourceRows because they're re-read multiple times. + var sourceRows [][]string + for _, sourceTargetShard := range tme.sourceShards { + var rows []string + for j, sourceShard := range tme.sourceShards { + bls := &binlogdatapb.BinlogSource{ + Keyspace: "ks1", + Shard: sourceShard, + Filter: &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{{ + Match: "t1", + Filter: fmt.Sprintf("select * from t1 where in_keyrange('%s')", sourceTargetShard), + }}, + }, + } + rows = append(rows, fmt.Sprintf("%d|t1|%v|MariaDB/5-456-888", j+1, bls)) + } + sourceRows = append(sourceRows, rows) + } + + for i, dbclient := range tme.dbSourceClients { + // sm.stopStreams->sm.readSourceStreams->readTabletStreams('') and VReplicationExec(_vt.copy_state) + dbclient.addQuery("select id, workflow, source, pos from _vt.vreplication where db_name='vt_ks' and workflow != 'test_reverse'", sqltypes.MakeTestResult(sqltypes.MakeTestFields( + "id|workflow|source|pos", + "int64|varbinary|varchar|varbinary"), + sourceRows[i]...), + nil) + dbclient.addQuery("select vrepl_id from _vt.copy_state where vrepl_id in (1, 2)", &sqltypes.Result{}, nil) + + // sm.stopStreams->sm.stopSourceStreams->VReplicationExec('Stopped') + dbclient.addQuery("select id from _vt.vreplication where id in (1, 2)", resultid12, nil) + dbclient.addQuery("update _vt.vreplication set state = 'Stopped', message = 'for cutover' where id in (1, 2)", &sqltypes.Result{}, nil) + dbclient.addQuery("select * from _vt.vreplication where id = 1", stoppedResult(1), nil) + dbclient.addQuery("select * from _vt.vreplication where id = 2", stoppedResult(2), nil) + + // sm.stopStreams->sm.stopSourceStreams->sm.readTabletStreams('id in...') + dbclient.addQuery("select id, workflow, source, pos from _vt.vreplication where db_name='vt_ks' and workflow != 'test_reverse' and id in (1, 2)", sqltypes.MakeTestResult(sqltypes.MakeTestFields( + "id|workflow|source|pos", + "int64|varbinary|varchar|varbinary"), + sourceRows[i]...), + nil) + + // sm.stopStreams->sm.verifyStreamPositions->sm.readTabletStreams('id in...') + dbclient.addQuery("select id, workflow, source, pos from _vt.vreplication where db_name='vt_ks' and workflow != 'test_reverse' and id in (1, 2)", sqltypes.MakeTestResult(sqltypes.MakeTestFields( + "id|workflow|source|pos", + "int64|varbinary|varchar|varbinary"), + sourceRows[i]...), + nil) + } + } + stopStreams() + + tme.expectWaitForCatchup() + + migrateStreams := func() { + // sm.migrateStreams->->sm.deleteTargetStreams (no previously migrated streams) + tme.dbTargetClients[0].addQuery("select id from _vt.vreplication where db_name = 'vt_ks' and workflow in ('t1')", &sqltypes.Result{}, nil) + + // sm.migrateStreams->sm.createTargetStreams + for i, targetShard := range tme.targetShards { + buf := &strings.Builder{} + buf.WriteString("insert into.*vreplication") + for _, sourceShard := range tme.sourceShards { + fmt.Fprintf(buf, ".*t1.*ks.*%s.*t1.*in_keyrange.*%s.*MariaDB/5-456-888.*Stopped", sourceShard, targetShard) + } + // Insert id is 3 so it doesn't overlap with the existing streams. + tme.dbTargetClients[i].addQueryRE(buf.String(), &sqltypes.Result{InsertID: 3}, nil) + tme.dbTargetClients[i].addQuery("select * from _vt.vreplication where id = 3", stoppedResult(3), nil) + tme.dbTargetClients[i].addQuery("select * from _vt.vreplication where id = 4", stoppedResult(4), nil) + } + } + migrateStreams() + tme.expectCreateReverseVReplication() + + tme.expectCreateJournals() + + finalize := func() { + // sm.finalize->Source + tme.dbSourceClients[0].addQuery("select id from _vt.vreplication where db_name = 'vt_ks' and workflow in ('t1')", resultid12, nil) + tme.dbSourceClients[0].addQuery("delete from _vt.vreplication where id in (1, 2)", &sqltypes.Result{}, nil) + tme.dbSourceClients[0].addQuery("delete from _vt.copy_state where vrepl_id in (1, 2)", &sqltypes.Result{}, nil) + tme.dbSourceClients[1].addQuery("select id from _vt.vreplication where db_name = 'vt_ks' and workflow in ('t1')", resultid12, nil) + tme.dbSourceClients[1].addQuery("delete from _vt.vreplication where id in (1, 2)", &sqltypes.Result{}, nil) + tme.dbSourceClients[1].addQuery("delete from _vt.copy_state where vrepl_id in (1, 2)", &sqltypes.Result{}, nil) + + // sm.finalize->Target + tme.dbTargetClients[0].addQuery("select id from _vt.vreplication where db_name = 'vt_ks' and workflow in ('t1')", resultid34, nil) + tme.dbTargetClients[0].addQuery("update _vt.vreplication set state = 'Running' where id in (3, 4)", &sqltypes.Result{}, nil) + tme.dbTargetClients[0].addQuery("select * from _vt.vreplication where id = 3", stoppedResult(3), nil) + tme.dbTargetClients[0].addQuery("select * from _vt.vreplication where id = 4", stoppedResult(4), nil) + } + finalize() + + tme.expectStartReverseVReplication() + tme.expectDeleteTargetVReplication() + + if _, err := tme.wr.MigrateWrites(ctx, tme.targetKeyspace, "test", 1*time.Second, false, true); err != nil { + t.Fatal(err) + } + + checkServedTypes(t, tme.ts, "ks:-80", 0) + checkServedTypes(t, tme.ts, "ks:80-", 0) + checkServedTypes(t, tme.ts, "ks:-", 3) + + checkIsMasterServing(t, tme.ts, "ks:-80", false) + checkIsMasterServing(t, tme.ts, "ks:80-", false) + checkIsMasterServing(t, tme.ts, "ks:-", true) + + verifyQueries(t, tme.allDBClients) +} + +func TestStreamMigrateSyncSuccess(t *testing.T) { + ctx := context.Background() + tme := newTestShardMigrater(ctx, t, []string{"-40", "40-"}, []string{"-80", "80-"}) + defer tme.stopTablets(t) + + // Migrate reads + err := tme.wr.MigrateReads(ctx, tme.targetKeyspace, "test", topodatapb.TabletType_RDONLY, nil, DirectionForward) + if err != nil { + t.Fatal(err) + } + err = tme.wr.MigrateReads(ctx, tme.targetKeyspace, "test", topodatapb.TabletType_REPLICA, nil, DirectionForward) + if err != nil { + t.Fatal(err) + } + + tme.expectCheckJournals() + + stopStreams := func() { + // sm.stopStreams->sm.readSourceStreams->readTabletStreams('Stopped') + tme.dbSourceClients[0].addQuery("select id, workflow, source, pos from _vt.vreplication where db_name='vt_ks' and workflow != 'test_reverse' and state = 'Stopped'", &sqltypes.Result{}, nil) + tme.dbSourceClients[1].addQuery("select id, workflow, source, pos from _vt.vreplication where db_name='vt_ks' and workflow != 'test_reverse' and state = 'Stopped'", &sqltypes.Result{}, nil) + + var sourceRows [][]string + for i, sourceTargetShard := range tme.sourceShards { + var rows []string + for j, sourceShard := range tme.sourceShards { + bls := &binlogdatapb.BinlogSource{ + Keyspace: "ks1", + Shard: sourceShard, + Filter: &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{{ + Match: "t1", + Filter: fmt.Sprintf("select * from t1 where in_keyrange('%s')", sourceTargetShard), + }}, + }, + } + switch i { + case 0: + switch j { + case 0: + rows = append(rows, fmt.Sprintf("%d|t1|%v|MariaDB/5-456-887", j+1, bls)) + case 1: + rows = append(rows, fmt.Sprintf("%d|t1|%v|MariaDB/5-456-888", j+1, bls)) + } + case 1: + switch j { + case 0: + rows = append(rows, fmt.Sprintf("%d|t1|%v|MariaDB/5-456-888", j+1, bls)) + case 1: + rows = append(rows, fmt.Sprintf("%d|t1|%v|MariaDB/5-456-887", j+1, bls)) + } + } + } + sourceRows = append(sourceRows, rows) + } + var finalSources [][]string + for _, sourceTargetShard := range tme.sourceShards { + var rows []string + for j, sourceShard := range tme.sourceShards { + bls := &binlogdatapb.BinlogSource{ + Keyspace: "ks1", + Shard: sourceShard, + Filter: &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{{ + Match: "t1", + Filter: fmt.Sprintf("select * from t1 where in_keyrange('%s')", sourceTargetShard), + }}, + }, + } + rows = append(rows, fmt.Sprintf("%d|t1|%v|MariaDB/5-456-888", j+1, bls)) + } + finalSources = append(finalSources, rows) + } + + for i, dbclient := range tme.dbSourceClients { + // sm.stopStreams->sm.readSourceStreams->readTabletStreams('') and VReplicationExec(_vt.copy_state) + dbclient.addQuery("select id, workflow, source, pos from _vt.vreplication where db_name='vt_ks' and workflow != 'test_reverse'", sqltypes.MakeTestResult(sqltypes.MakeTestFields( + "id|workflow|source|pos", + "int64|varbinary|varchar|varbinary"), + sourceRows[i]...), + nil) + dbclient.addQuery("select vrepl_id from _vt.copy_state where vrepl_id in (1, 2)", &sqltypes.Result{}, nil) + + // sm.stopStreams->sm.stopSourceStreams->VReplicationExec('Stopped') + dbclient.addQuery("select id from _vt.vreplication where id in (1, 2)", resultid12, nil) + dbclient.addQuery("update _vt.vreplication set state = 'Stopped', message = 'for cutover' where id in (1, 2)", &sqltypes.Result{}, nil) + dbclient.addQuery("select * from _vt.vreplication where id = 1", stoppedResult(1), nil) + dbclient.addQuery("select * from _vt.vreplication where id = 2", stoppedResult(2), nil) + + // sm.stopStreams->sm.stopSourceStreams->sm.readTabletStreams('id in...') + dbclient.addQuery("select id, workflow, source, pos from _vt.vreplication where db_name='vt_ks' and workflow != 'test_reverse' and id in (1, 2)", sqltypes.MakeTestResult(sqltypes.MakeTestFields( + "id|workflow|source|pos", + "int64|varbinary|varchar|varbinary"), + sourceRows[i]...), + nil) + + // sm.stopStreams->sm.verifyStreamPositions->sm.readTabletStreams('id in...') + dbclient.addQuery("select id, workflow, source, pos from _vt.vreplication where db_name='vt_ks' and workflow != 'test_reverse' and id in (1, 2)", sqltypes.MakeTestResult(sqltypes.MakeTestFields( + "id|workflow|source|pos", + "int64|varbinary|varchar|varbinary"), + finalSources[i]...), + nil) + } + } + stopStreams() + + // sm.stopStreams->sm.syncSourceStreams: Note that this happens inside stopStreams before verifyStreamPositions. + syncSourceStreams := func() { + reached := sqltypes.MakeTestResult(sqltypes.MakeTestFields( + "pos|state|message", + "varbinary|varbinary|varbinary"), + "MariaDB/5-456-888|Running|", + ) + tme.dbSourceClients[0].addQuery("select id from _vt.vreplication where id = 1", resultid1, nil) + tme.dbSourceClients[0].addQuery("update _vt.vreplication set state = 'Running', stop_pos = 'MariaDB/5-456-888', message = 'synchronizing for cutover' where id in (1)", &sqltypes.Result{}, nil) + tme.dbSourceClients[0].addQuery("select pos, state, message from _vt.vreplication where id=1", reached, nil) + tme.dbSourceClients[0].addQuery("select * from _vt.vreplication where id = 1", stoppedResult(1), nil) + tme.dbSourceClients[1].addQuery("select id from _vt.vreplication where id = 2", resultid2, nil) + tme.dbSourceClients[1].addQuery("update _vt.vreplication set state = 'Running', stop_pos = 'MariaDB/5-456-888', message = 'synchronizing for cutover' where id in (2)", &sqltypes.Result{}, nil) + tme.dbSourceClients[1].addQuery("select pos, state, message from _vt.vreplication where id=2", reached, nil) + tme.dbSourceClients[1].addQuery("select * from _vt.vreplication where id = 2", stoppedResult(2), nil) + } + syncSourceStreams() + + tme.expectWaitForCatchup() + + migrateStreams := func() { + // sm.migrateStreams->->sm.deleteTargetStreams (no previously migrated streams) + tme.dbTargetClients[0].addQuery("select id from _vt.vreplication where db_name = 'vt_ks' and workflow in ('t1')", &sqltypes.Result{}, nil) + tme.dbTargetClients[1].addQuery("select id from _vt.vreplication where db_name = 'vt_ks' and workflow in ('t1')", &sqltypes.Result{}, nil) + + // sm.migrateStreams->sm.createTargetStreams + for i, targetShard := range tme.targetShards { + buf := &strings.Builder{} + buf.WriteString("insert into.*vreplication") + for _, sourceShard := range tme.sourceShards { + fmt.Fprintf(buf, ".*t1.*ks.*%s.*t1.*in_keyrange.*%s.*MariaDB/5-456-888.*Stopped", sourceShard, targetShard) + } + // Insert id is 3 so it doesn't overlap with the existing streams. + tme.dbTargetClients[i].addQueryRE(buf.String(), &sqltypes.Result{InsertID: 3}, nil) + tme.dbTargetClients[i].addQuery("select * from _vt.vreplication where id = 3", stoppedResult(3), nil) + tme.dbTargetClients[i].addQuery("select * from _vt.vreplication where id = 4", stoppedResult(4), nil) + } + } + migrateStreams() + + tme.expectCreateJournals() + + finalize := func() { + // sm.finalize->Source + tme.dbSourceClients[0].addQuery("select id from _vt.vreplication where db_name = 'vt_ks' and workflow in ('t1')", resultid12, nil) + tme.dbSourceClients[0].addQuery("delete from _vt.vreplication where id in (1, 2)", &sqltypes.Result{}, nil) + tme.dbSourceClients[0].addQuery("delete from _vt.copy_state where vrepl_id in (1, 2)", &sqltypes.Result{}, nil) + tme.dbSourceClients[1].addQuery("select id from _vt.vreplication where db_name = 'vt_ks' and workflow in ('t1')", resultid12, nil) + tme.dbSourceClients[1].addQuery("delete from _vt.vreplication where id in (1, 2)", &sqltypes.Result{}, nil) + tme.dbSourceClients[1].addQuery("delete from _vt.copy_state where vrepl_id in (1, 2)", &sqltypes.Result{}, nil) + + // sm.finalize->Target + tme.dbTargetClients[0].addQuery("select id from _vt.vreplication where db_name = 'vt_ks' and workflow in ('t1')", resultid34, nil) + tme.dbTargetClients[1].addQuery("select id from _vt.vreplication where db_name = 'vt_ks' and workflow in ('t1')", resultid34, nil) + tme.dbTargetClients[0].addQuery("update _vt.vreplication set state = 'Running' where id in (3, 4)", &sqltypes.Result{}, nil) + tme.dbTargetClients[1].addQuery("update _vt.vreplication set state = 'Running' where id in (3, 4)", &sqltypes.Result{}, nil) + tme.dbTargetClients[0].addQuery("select * from _vt.vreplication where id = 3", stoppedResult(3), nil) + tme.dbTargetClients[1].addQuery("select * from _vt.vreplication where id = 3", stoppedResult(3), nil) + tme.dbTargetClients[0].addQuery("select * from _vt.vreplication where id = 4", stoppedResult(4), nil) + tme.dbTargetClients[1].addQuery("select * from _vt.vreplication where id = 4", stoppedResult(4), nil) + } + finalize() + + tme.expectCreateReverseVReplication() + tme.expectStartReverseVReplication() + tme.expectDeleteTargetVReplication() + + if _, err := tme.wr.MigrateWrites(ctx, tme.targetKeyspace, "test", 1*time.Second, false, true); err != nil { + t.Fatal(err) + } + + checkServedTypes(t, tme.ts, "ks:-40", 0) + checkServedTypes(t, tme.ts, "ks:40-", 0) + checkServedTypes(t, tme.ts, "ks:-80", 3) + checkServedTypes(t, tme.ts, "ks:80-", 3) + + checkIsMasterServing(t, tme.ts, "ks:-40", false) + checkIsMasterServing(t, tme.ts, "ks:40-", false) + checkIsMasterServing(t, tme.ts, "ks:-80", true) + checkIsMasterServing(t, tme.ts, "ks:80-", true) + + verifyQueries(t, tme.allDBClients) +} + +func TestStreamMigrateSyncFail(t *testing.T) { + ctx := context.Background() + tme := newTestShardMigrater(ctx, t, []string{"-40", "40-"}, []string{"-80", "80-"}) + defer tme.stopTablets(t) + + // Migrate reads + err := tme.wr.MigrateReads(ctx, tme.targetKeyspace, "test", topodatapb.TabletType_RDONLY, nil, DirectionForward) + if err != nil { + t.Fatal(err) + } + err = tme.wr.MigrateReads(ctx, tme.targetKeyspace, "test", topodatapb.TabletType_REPLICA, nil, DirectionForward) + if err != nil { + t.Fatal(err) + } + + tme.expectCheckJournals() + + stopStreams := func() { + // sm.stopStreams->sm.readSourceStreams->readTabletStreams('Stopped') + tme.dbSourceClients[0].addQuery("select id, workflow, source, pos from _vt.vreplication where db_name='vt_ks' and workflow != 'test_reverse' and state = 'Stopped'", &sqltypes.Result{}, nil) + tme.dbSourceClients[1].addQuery("select id, workflow, source, pos from _vt.vreplication where db_name='vt_ks' and workflow != 'test_reverse' and state = 'Stopped'", &sqltypes.Result{}, nil) + + var sourceRows [][]string + for i, sourceTargetShard := range tme.sourceShards { + var rows []string + for j, sourceShard := range tme.sourceShards { + bls := &binlogdatapb.BinlogSource{ + Keyspace: "ks1", + Shard: sourceShard, + Filter: &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{{ + Match: "t1", + Filter: fmt.Sprintf("select * from t1 where in_keyrange('%s')", sourceTargetShard), + }}, + }, + } + switch i { + case 0: + switch j { + case 0: + rows = append(rows, fmt.Sprintf("%d|t1|%v|MariaDB/5-456-887", j+1, bls)) + case 1: + rows = append(rows, fmt.Sprintf("%d|t1|%v|MariaDB/5-456-888", j+1, bls)) + } + case 1: + switch j { + case 0: + rows = append(rows, fmt.Sprintf("%d|t1|%v|MariaDB/5-456-888", j+1, bls)) + case 1: + rows = append(rows, fmt.Sprintf("%d|t1|%v|MariaDB/5-456-887", j+1, bls)) + } + } + } + sourceRows = append(sourceRows, rows) + } + + for i, dbclient := range tme.dbSourceClients { + // sm.stopStreams->sm.readSourceStreams->readTabletStreams('') and VReplicationExec(_vt.copy_state) + dbclient.addQuery("select id, workflow, source, pos from _vt.vreplication where db_name='vt_ks' and workflow != 'test_reverse'", sqltypes.MakeTestResult(sqltypes.MakeTestFields( + "id|workflow|source|pos", + "int64|varbinary|varchar|varbinary"), + sourceRows[i]...), + nil) + dbclient.addQuery("select vrepl_id from _vt.copy_state where vrepl_id in (1, 2)", &sqltypes.Result{}, nil) + + // sm.stopStreams->sm.stopSourceStreams->VReplicationExec('Stopped') + dbclient.addQuery("select id from _vt.vreplication where id in (1, 2)", resultid12, nil) + dbclient.addQuery("update _vt.vreplication set state = 'Stopped', message = 'for cutover' where id in (1, 2)", &sqltypes.Result{}, nil) + dbclient.addQuery("select * from _vt.vreplication where id = 1", stoppedResult(1), nil) + dbclient.addQuery("select * from _vt.vreplication where id = 2", stoppedResult(2), nil) + + // sm.stopStreams->sm.stopSourceStreams->sm.readTabletStreams('id in...') + dbclient.addQuery("select id, workflow, source, pos from _vt.vreplication where db_name='vt_ks' and workflow != 'test_reverse' and id in (1, 2)", sqltypes.MakeTestResult(sqltypes.MakeTestFields( + "id|workflow|source|pos", + "int64|varbinary|varchar|varbinary"), + sourceRows[i]...), + nil) + + // sm.stopStreams->sm.verifyStreamPositions->sm.readTabletStreams('id in...') + dbclient.addQuery("select id, workflow, source, pos from _vt.vreplication where db_name='vt_ks' and workflow != 'test_reverse' and id in (1, 2)", sqltypes.MakeTestResult(sqltypes.MakeTestFields( + "id|workflow|source|pos", + "int64|varbinary|varchar|varbinary"), + sourceRows[i]...), + nil) + } + } + stopStreams() + + // sm.stopStreams->sm.syncSourceStreams: Note that this happens inside stopStreams before verifyStreamPositions. + syncSourceStreams := func() { + reached := sqltypes.MakeTestResult(sqltypes.MakeTestFields( + "pos|state|message", + "varbinary|varbinary|varbinary"), + "MariaDB/5-456-888|Running|", + ) + tme.dbSourceClients[0].addQuery("select id from _vt.vreplication where id = 1", resultid1, nil) + tme.dbSourceClients[0].addQuery("update _vt.vreplication set state = 'Running', stop_pos = 'MariaDB/5-456-888', message = 'synchronizing for cutover' where id in (1)", &sqltypes.Result{}, nil) + tme.dbSourceClients[0].addQuery("select pos, state, message from _vt.vreplication where id=1", reached, nil) + tme.dbSourceClients[0].addQuery("select * from _vt.vreplication where id = 1", stoppedResult(1), nil) + tme.dbSourceClients[1].addQuery("select id from _vt.vreplication where id = 2", resultid2, nil) + tme.dbSourceClients[1].addQuery("update _vt.vreplication set state = 'Running', stop_pos = 'MariaDB/5-456-888', message = 'synchronizing for cutover' where id in (2)", &sqltypes.Result{}, nil) + tme.dbSourceClients[1].addQuery("select pos, state, message from _vt.vreplication where id=2", reached, nil) + tme.dbSourceClients[1].addQuery("select * from _vt.vreplication where id = 2", stoppedResult(2), nil) + } + syncSourceStreams() + + // sm.deleteTargetStreams (simplified to delete nothing) + tme.dbTargetClients[0].addQuery("select id from _vt.vreplication where db_name = 'vt_ks' and workflow in ('t1')", &sqltypes.Result{}, nil) + tme.dbTargetClients[1].addQuery("select id from _vt.vreplication where db_name = 'vt_ks' and workflow in ('t1')", &sqltypes.Result{}, nil) + + tme.expectCancelMigration() + + _, err = tme.wr.MigrateWrites(ctx, tme.targetKeyspace, "test", 1*time.Second, false, true) + want := "does not match" + if err == nil || !strings.Contains(err.Error(), want) { + t.Errorf("MigrateWrites err: %v, want %s", err, want) + } + verifyQueries(t, tme.allDBClients) +} + +func TestStreamMigrateCancel(t *testing.T) { + ctx := context.Background() + tme := newTestShardMigrater(ctx, t, []string{"-40", "40-"}, []string{"-80", "80-"}) + defer tme.stopTablets(t) + + // Migrate reads + err := tme.wr.MigrateReads(ctx, tme.targetKeyspace, "test", topodatapb.TabletType_RDONLY, nil, DirectionForward) + if err != nil { + t.Fatal(err) + } + err = tme.wr.MigrateReads(ctx, tme.targetKeyspace, "test", topodatapb.TabletType_REPLICA, nil, DirectionForward) + if err != nil { + t.Fatal(err) + } + + tme.expectCheckJournals() + + stopStreamsFail := func() { + // sm.stopStreams->sm.readSourceStreams->readTabletStreams('Stopped') + tme.dbSourceClients[0].addQuery("select id, workflow, source, pos from _vt.vreplication where db_name='vt_ks' and workflow != 'test_reverse' and state = 'Stopped'", &sqltypes.Result{}, nil) + tme.dbSourceClients[1].addQuery("select id, workflow, source, pos from _vt.vreplication where db_name='vt_ks' and workflow != 'test_reverse' and state = 'Stopped'", &sqltypes.Result{}, nil) + + // pre-compute sourceRows because they're re-read multiple times. + var sourceRows [][]string + for _, sourceTargetShard := range tme.sourceShards { + var rows []string + for j, sourceShard := range tme.sourceShards { + bls := &binlogdatapb.BinlogSource{ + Keyspace: "ks1", + Shard: sourceShard, + Filter: &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{{ + Match: "t1", + Filter: fmt.Sprintf("select * from t1 where in_keyrange('%s')", sourceTargetShard), + }}, + }, + } + rows = append(rows, fmt.Sprintf("%d|t1|%v|MariaDB/5-456-888", j+1, bls)) + } + sourceRows = append(sourceRows, rows) + } + + for i, dbclient := range tme.dbSourceClients { + // sm.stopStreams->sm.readSourceStreams->readTabletStreams('') and VReplicationExec(_vt.copy_state) + dbclient.addQuery("select id, workflow, source, pos from _vt.vreplication where db_name='vt_ks' and workflow != 'test_reverse'", sqltypes.MakeTestResult(sqltypes.MakeTestFields( + "id|workflow|source|pos", + "int64|varbinary|varchar|varbinary"), + sourceRows[i]...), + nil) + dbclient.addQuery("select vrepl_id from _vt.copy_state where vrepl_id in (1, 2)", &sqltypes.Result{}, nil) + + // sm.stopStreams->sm.stopSourceStreams->VReplicationExec('Stopped'): fail this + dbclient.addQuery("select id from _vt.vreplication where id in (1, 2)", nil, fmt.Errorf("intentionally failed")) + } + } + stopStreamsFail() + + cancelMigration := func() { + // sm.migrateStreams->sm.deleteTargetStreams + tme.dbTargetClients[0].addQuery("select id from _vt.vreplication where db_name = 'vt_ks' and workflow in ('t1')", resultid34, nil) + tme.dbTargetClients[1].addQuery("select id from _vt.vreplication where db_name = 'vt_ks' and workflow in ('t1')", resultid34, nil) + tme.dbTargetClients[0].addQuery("delete from _vt.vreplication where id in (3, 4)", &sqltypes.Result{}, nil) + tme.dbTargetClients[1].addQuery("delete from _vt.vreplication where id in (3, 4)", &sqltypes.Result{}, nil) + tme.dbTargetClients[0].addQuery("delete from _vt.copy_state where vrepl_id in (3, 4)", &sqltypes.Result{}, nil) + tme.dbTargetClients[1].addQuery("delete from _vt.copy_state where vrepl_id in (3, 4)", &sqltypes.Result{}, nil) + + // sm.migrateStreams->->restart source streams + tme.dbSourceClients[0].addQuery("select id from _vt.vreplication where db_name = 'vt_ks' and workflow != 'test_reverse'", resultid12, nil) + tme.dbSourceClients[1].addQuery("select id from _vt.vreplication where db_name = 'vt_ks' and workflow != 'test_reverse'", resultid12, nil) + tme.dbSourceClients[0].addQuery("update _vt.vreplication set state = 'Running', stop_pos = null, message = '' where id in (1, 2)", &sqltypes.Result{}, nil) + tme.dbSourceClients[1].addQuery("update _vt.vreplication set state = 'Running', stop_pos = null, message = '' where id in (1, 2)", &sqltypes.Result{}, nil) + tme.dbSourceClients[0].addQuery("select * from _vt.vreplication where id = 1", runningResult(1), nil) + tme.dbSourceClients[1].addQuery("select * from _vt.vreplication where id = 1", runningResult(1), nil) + tme.dbSourceClients[0].addQuery("select * from _vt.vreplication where id = 2", runningResult(2), nil) + tme.dbSourceClients[1].addQuery("select * from _vt.vreplication where id = 2", runningResult(2), nil) + + // mi.cancelMigration->restart target streams + tme.dbTargetClients[0].addQuery("select id from _vt.vreplication where db_name = 'vt_ks' and workflow = 'test'", &sqltypes.Result{}, nil) + tme.dbTargetClients[1].addQuery("select id from _vt.vreplication where db_name = 'vt_ks' and workflow = 'test'", &sqltypes.Result{}, nil) + + tme.expectDeleteReverseVReplication() + } + cancelMigration() + + _, err = tme.wr.MigrateWrites(ctx, tme.targetKeyspace, "test", 1*time.Second, false, true) + want := "intentionally failed" + if err == nil || !strings.Contains(err.Error(), want) { + t.Errorf("MigrateWrites err: %v, want %s", err, want) + } + + checkServedTypes(t, tme.ts, "ks:-40", 1) + checkServedTypes(t, tme.ts, "ks:40-", 1) + checkServedTypes(t, tme.ts, "ks:-80", 2) + checkServedTypes(t, tme.ts, "ks:80-", 2) + + checkIsMasterServing(t, tme.ts, "ks:-40", true) + checkIsMasterServing(t, tme.ts, "ks:40-", true) + checkIsMasterServing(t, tme.ts, "ks:-80", false) + checkIsMasterServing(t, tme.ts, "ks:80-", false) + + verifyQueries(t, tme.allDBClients) +} + +func TestStreamMigrateStoppedStreams(t *testing.T) { + ctx := context.Background() + tme := newTestShardMigrater(ctx, t, []string{"0"}, []string{"-80", "80-"}) + defer tme.stopTablets(t) + + // Migrate reads + err := tme.wr.MigrateReads(ctx, tme.targetKeyspace, "test", topodatapb.TabletType_RDONLY, nil, DirectionForward) + if err != nil { + t.Fatal(err) + } + err = tme.wr.MigrateReads(ctx, tme.targetKeyspace, "test", topodatapb.TabletType_REPLICA, nil, DirectionForward) + if err != nil { + t.Fatal(err) + } + + tme.expectCheckJournals() + + stopStreams := func() { + // sm.stopStreams->sm.readSourceStreams->readTabletStreams('Stopped'): returns non-empty + var sourceRows [][]string + for _, sourceTargetShard := range tme.sourceShards { + var rows []string + for j, sourceShard := range tme.sourceShards { + bls := &binlogdatapb.BinlogSource{ + Keyspace: "ks1", + Shard: sourceShard, + Filter: &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{{ + Match: "t1", + Filter: fmt.Sprintf("select * from t1 where in_keyrange('%s')", sourceTargetShard), + }}, + }, + } + rows = append(rows, fmt.Sprintf("%d|t1|%v|MariaDB/5-456-888", j+1, bls)) + } + sourceRows = append(sourceRows, rows) + } + + for i, dbclient := range tme.dbSourceClients { + // sm.stopStreams->sm.readSourceStreams->readTabletStreams('') and VReplicationExec(_vt.copy_state) + dbclient.addQuery("select id, workflow, source, pos from _vt.vreplication where db_name='vt_ks' and workflow != 'test_reverse' and state = 'Stopped'", sqltypes.MakeTestResult(sqltypes.MakeTestFields( + "id|workflow|source|pos", + "int64|varbinary|varchar|varbinary"), + sourceRows[i]...), + nil) + } + } + stopStreams() + + _, err = tme.wr.MigrateWrites(ctx, tme.targetKeyspace, "test", 1*time.Second, false, true) + want := "cannot migrate until all streams are running: 0" + if err == nil || err.Error() != want { + t.Errorf("MigrateWrites err: %v, want %v", err, want) + } + verifyQueries(t, tme.allDBClients) +} + +func TestStreamMigrateCancelWithStoppedStreams(t *testing.T) { + ctx := context.Background() + tme := newTestShardMigrater(ctx, t, []string{"-40", "40-"}, []string{"-80", "80-"}) + defer tme.stopTablets(t) + + // Migrate reads + err := tme.wr.MigrateReads(ctx, tme.targetKeyspace, "test", topodatapb.TabletType_RDONLY, nil, DirectionForward) + if err != nil { + t.Fatal(err) + } + err = tme.wr.MigrateReads(ctx, tme.targetKeyspace, "test", topodatapb.TabletType_REPLICA, nil, DirectionForward) + if err != nil { + t.Fatal(err) + } + + tme.expectCheckJournals() + + stopStreams := func() { + var sourceRows [][]string + for _, sourceTargetShard := range tme.sourceShards { + var rows []string + for j, sourceShard := range tme.sourceShards { + bls := &binlogdatapb.BinlogSource{ + Keyspace: "ks1", + Shard: sourceShard, + Filter: &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{{ + Match: "t1", + Filter: fmt.Sprintf("select * from t1 where in_keyrange('%s')", sourceTargetShard), + }, { + Match: "t2", + Filter: fmt.Sprintf("select * from t2 where in_keyrange('%s')", sourceTargetShard), + }}, + }, + } + rows = append(rows, fmt.Sprintf("%d|t1t2|%v|MariaDB/5-456-888", j+1, bls)) + } + sourceRows = append(sourceRows, rows) + } + + for i, dbclient := range tme.dbSourceClients { + // sm.stopStreams->sm.readSourceStreams->readTabletStreams('') and VReplicationExec(_vt.copy_state) + dbclient.addQuery("select id, workflow, source, pos from _vt.vreplication where db_name='vt_ks' and workflow != 'test_reverse'", sqltypes.MakeTestResult(sqltypes.MakeTestFields( + "id|workflow|source|pos", + "int64|varbinary|varchar|varbinary"), + sourceRows[i]...), + nil) + dbclient.addQuery("select vrepl_id from _vt.copy_state where vrepl_id in (1, 2)", &sqltypes.Result{}, nil) + } + } + stopStreams() + + // sm.migrateStreams->->sm.deleteTargetStreams (no previously migrated streams) + tme.dbTargetClients[0].addQuery("select id from _vt.vreplication where db_name = 'vt_ks' and workflow in ('t1t2')", &sqltypes.Result{}, nil) + tme.dbTargetClients[1].addQuery("select id from _vt.vreplication where db_name = 'vt_ks' and workflow in ('t1t2')", &sqltypes.Result{}, nil) + + tme.expectCancelMigration() + + _, err = tme.wr.MigrateWrites(ctx, tme.targetKeyspace, "test", 1*time.Second, true, false) + if err != nil { + t.Fatal(err) + } + verifyQueries(t, tme.allDBClients) +} + +func TestStreamMigrateStillCopying(t *testing.T) { + ctx := context.Background() + tme := newTestShardMigrater(ctx, t, []string{"0"}, []string{"-80", "80-"}) + defer tme.stopTablets(t) + + // Migrate reads + err := tme.wr.MigrateReads(ctx, tme.targetKeyspace, "test", topodatapb.TabletType_RDONLY, nil, DirectionForward) + if err != nil { + t.Fatal(err) + } + err = tme.wr.MigrateReads(ctx, tme.targetKeyspace, "test", topodatapb.TabletType_REPLICA, nil, DirectionForward) + if err != nil { + t.Fatal(err) + } + + tme.expectCheckJournals() + + stopStreams := func() { + // sm.stopStreams->sm.readSourceStreams->readTabletStreams('Stopped') + tme.dbSourceClients[0].addQuery("select id, workflow, source, pos from _vt.vreplication where db_name='vt_ks' and workflow != 'test_reverse' and state = 'Stopped'", &sqltypes.Result{}, nil) + + // pre-compute sourceRows because they're re-read multiple times. + var sourceRows [][]string + for _, sourceTargetShard := range tme.sourceShards { + var rows []string + for j, sourceShard := range tme.sourceShards { + bls := &binlogdatapb.BinlogSource{ + Keyspace: "ks1", + Shard: sourceShard, + Filter: &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{{ + Match: "t1", + Filter: fmt.Sprintf("select * from t1 where in_keyrange('%s')", sourceTargetShard), + }}, + }, + } + rows = append(rows, fmt.Sprintf("%d|t1|%v|MariaDB/5-456-888", j+1, bls)) + } + sourceRows = append(sourceRows, rows) + } + + for i, dbclient := range tme.dbSourceClients { + // sm.stopStreams->sm.readSourceStreams->readTabletStreams('') and VReplicationExec(_vt.copy_state) + dbclient.addQuery("select id, workflow, source, pos from _vt.vreplication where db_name='vt_ks' and workflow != 'test_reverse'", sqltypes.MakeTestResult(sqltypes.MakeTestFields( + "id|workflow|source|pos", + "int64|varbinary|varchar|varbinary"), + sourceRows[i]...), + nil) + dbclient.addQuery("select vrepl_id from _vt.copy_state where vrepl_id in (1)", resultid1, nil) + } + } + stopStreams() + + _, err = tme.wr.MigrateWrites(ctx, tme.targetKeyspace, "test", 1*time.Second, false, true) + want := "cannot migrate while vreplication streams in source shards are still copying: 0" + if err == nil || err.Error() != want { + t.Errorf("MigrateWrites err: %v, want %v", err, want) + } + verifyQueries(t, tme.allDBClients) +} + +func TestStreamMigrateEmptyWorflow(t *testing.T) { + ctx := context.Background() + tme := newTestShardMigrater(ctx, t, []string{"0"}, []string{"-80", "80-"}) + defer tme.stopTablets(t) + + // Migrate reads + err := tme.wr.MigrateReads(ctx, tme.targetKeyspace, "test", topodatapb.TabletType_RDONLY, nil, DirectionForward) + if err != nil { + t.Fatal(err) + } + err = tme.wr.MigrateReads(ctx, tme.targetKeyspace, "test", topodatapb.TabletType_REPLICA, nil, DirectionForward) + if err != nil { + t.Fatal(err) + } + + tme.expectCheckJournals() + + stopStreams := func() { + // sm.stopStreams->sm.readSourceStreams->readTabletStreams('Stopped') + tme.dbSourceClients[0].addQuery("select id, workflow, source, pos from _vt.vreplication where db_name='vt_ks' and workflow != 'test_reverse' and state = 'Stopped'", &sqltypes.Result{}, nil) + + // pre-compute sourceRows because they're re-read multiple times. + var sourceRows [][]string + for _, sourceTargetShard := range tme.sourceShards { + var rows []string + for j, sourceShard := range tme.sourceShards { + bls := &binlogdatapb.BinlogSource{ + Keyspace: "ks1", + Shard: sourceShard, + Filter: &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{{ + Match: "t1", + Filter: fmt.Sprintf("select * from t1 where in_keyrange('%s')", sourceTargetShard), + }}, + }, + } + rows = append(rows, fmt.Sprintf("%d||%v|MariaDB/5-456-888", j+1, bls)) + } + sourceRows = append(sourceRows, rows) + } + + for i, dbclient := range tme.dbSourceClients { + // sm.stopStreams->sm.readSourceStreams->readTabletStreams('') and VReplicationExec(_vt.copy_state) + dbclient.addQuery("select id, workflow, source, pos from _vt.vreplication where db_name='vt_ks' and workflow != 'test_reverse'", sqltypes.MakeTestResult(sqltypes.MakeTestFields( + "id|workflow|source|pos", + "int64|varbinary|varchar|varbinary"), + sourceRows[i]...), + nil) + } + } + stopStreams() + + _, err = tme.wr.MigrateWrites(ctx, tme.targetKeyspace, "test", 1*time.Second, false, true) + want := "VReplication streams must have named workflows for migration: shard: ks:0, stream: 1" + if err == nil || err.Error() != want { + t.Errorf("MigrateWrites err: %v, want %v", err, want) + } + verifyQueries(t, tme.allDBClients) +} + +func TestStreamMigrateDupWorflow(t *testing.T) { + ctx := context.Background() + tme := newTestShardMigrater(ctx, t, []string{"0"}, []string{"-80", "80-"}) + defer tme.stopTablets(t) + + // Migrate reads + err := tme.wr.MigrateReads(ctx, tme.targetKeyspace, "test", topodatapb.TabletType_RDONLY, nil, DirectionForward) + if err != nil { + t.Fatal(err) + } + err = tme.wr.MigrateReads(ctx, tme.targetKeyspace, "test", topodatapb.TabletType_REPLICA, nil, DirectionForward) + if err != nil { + t.Fatal(err) + } + + tme.expectCheckJournals() + + stopStreams := func() { + // sm.stopStreams->sm.readSourceStreams->readTabletStreams('Stopped') + tme.dbSourceClients[0].addQuery("select id, workflow, source, pos from _vt.vreplication where db_name='vt_ks' and workflow != 'test_reverse' and state = 'Stopped'", &sqltypes.Result{}, nil) + + // pre-compute sourceRows because they're re-read multiple times. + var sourceRows [][]string + for _, sourceTargetShard := range tme.sourceShards { + var rows []string + for j, sourceShard := range tme.sourceShards { + bls := &binlogdatapb.BinlogSource{ + Keyspace: "ks1", + Shard: sourceShard, + Filter: &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{{ + Match: "t1", + Filter: fmt.Sprintf("select * from t1 where in_keyrange('%s')", sourceTargetShard), + }}, + }, + } + rows = append(rows, fmt.Sprintf("%d|test|%v|MariaDB/5-456-888", j+1, bls)) + } + sourceRows = append(sourceRows, rows) + } + + for i, dbclient := range tme.dbSourceClients { + // sm.stopStreams->sm.readSourceStreams->readTabletStreams('') and VReplicationExec(_vt.copy_state) + dbclient.addQuery("select id, workflow, source, pos from _vt.vreplication where db_name='vt_ks' and workflow != 'test_reverse'", sqltypes.MakeTestResult(sqltypes.MakeTestFields( + "id|workflow|source|pos", + "int64|varbinary|varchar|varbinary"), + sourceRows[i]...), + nil) + } + } + stopStreams() + + _, err = tme.wr.MigrateWrites(ctx, tme.targetKeyspace, "test", 1*time.Second, false, true) + want := "VReplication stream has the same workflow name as the resharding workflow: shard: ks:0, stream: 1" + if err == nil || err.Error() != want { + t.Errorf("MigrateWrites err: %v, want %v", err, want) + } + verifyQueries(t, tme.allDBClients) +} + +func TestStreamMigrateStreamsMismatch(t *testing.T) { + ctx := context.Background() + // Interesting tidbit: you cannot create a shard "0" for an already sharded keyspace. + tme := newTestShardMigrater(ctx, t, []string{"-80", "80-"}, []string{"-"}) + defer tme.stopTablets(t) + + // Migrate reads + err := tme.wr.MigrateReads(ctx, tme.targetKeyspace, "test", topodatapb.TabletType_RDONLY, nil, DirectionForward) + if err != nil { + t.Fatal(err) + } + err = tme.wr.MigrateReads(ctx, tme.targetKeyspace, "test", topodatapb.TabletType_REPLICA, nil, DirectionForward) + if err != nil { + t.Fatal(err) + } + + tme.expectCheckJournals() + + stopStreams := func() { + // sm.stopStreams->sm.readSourceStreams->readTabletStreams('Stopped') + tme.dbSourceClients[0].addQuery("select id, workflow, source, pos from _vt.vreplication where db_name='vt_ks' and workflow != 'test_reverse' and state = 'Stopped'", &sqltypes.Result{}, nil) + tme.dbSourceClients[1].addQuery("select id, workflow, source, pos from _vt.vreplication where db_name='vt_ks' and workflow != 'test_reverse' and state = 'Stopped'", &sqltypes.Result{}, nil) + + // pre-compute sourceRows because they're re-read multiple times. + var sourceRows [][]string + for i, sourceTargetShard := range tme.sourceShards { + var rows []string + for j, sourceShard := range tme.sourceShards { + // Skip one stream in one shard. + if i == 0 && j == 0 { + continue + } + bls := &binlogdatapb.BinlogSource{ + Keyspace: "ks1", + Shard: sourceShard, + Filter: &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{{ + Match: "t1", + Filter: fmt.Sprintf("select * from t1 where in_keyrange('%s')", sourceTargetShard), + }}, + }, + } + rows = append(rows, fmt.Sprintf("%d|t1|%v|MariaDB/5-456-888", j+1, bls)) + } + sourceRows = append(sourceRows, rows) + } + + for i, dbclient := range tme.dbSourceClients { + // sm.stopStreams->sm.readSourceStreams->readTabletStreams('') and VReplicationExec(_vt.copy_state) + dbclient.addQuery("select id, workflow, source, pos from _vt.vreplication where db_name='vt_ks' and workflow != 'test_reverse'", sqltypes.MakeTestResult(sqltypes.MakeTestFields( + "id|workflow|source|pos", + "int64|varbinary|varchar|varbinary"), + sourceRows[i]...), + nil) + if i == 0 { + dbclient.addQuery("select vrepl_id from _vt.copy_state where vrepl_id in (2)", &sqltypes.Result{}, nil) + } else { + dbclient.addQuery("select vrepl_id from _vt.copy_state where vrepl_id in (1, 2)", &sqltypes.Result{}, nil) + } + } + } + stopStreams() + + _, err = tme.wr.MigrateWrites(ctx, tme.targetKeyspace, "test", 1*time.Second, false, true) + want := "streams are mismatched across source shards" + if err == nil || !strings.Contains(err.Error(), want) { + t.Errorf("MigrateWrites err: %v, must contain %v", err, want) + } + verifyQueries(t, tme.allDBClients) +} + +func TestTemplatize(t *testing.T) { + tests := []struct { + in []*vrStream + out string + err string + }{{ + // First test contains all fields. + in: []*vrStream{{ + id: 1, + workflow: "test", + bls: &binlogdatapb.BinlogSource{ + Keyspace: "ks", + Shard: "80-", + Filter: &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{{ + Match: "t1", + Filter: "select * from t1 where in_keyrange('-80')", + }}, + }, + }, + }}, + out: `[{"ID":1,"Workflow":"test","Bls":{"keyspace":"ks","shard":"80-","filter":{"rules":[{"match":"t1","filter":"select * from t1 where in_keyrange('{{.}}')"}]}}}]`, + }, { + // Reference table. + in: []*vrStream{{ + bls: &binlogdatapb.BinlogSource{ + Filter: &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{{ + Match: "ref", + Filter: "", + }}, + }, + }, + }}, + out: "", + }, { + // Sharded table. + in: []*vrStream{{ + bls: &binlogdatapb.BinlogSource{ + Filter: &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{{ + Match: "t1", + Filter: "-80", + }}, + }, + }, + }}, + out: `[{"ID":0,"Workflow":"","Bls":{"filter":{"rules":[{"match":"t1","filter":"{{.}}"}]}}}]`, + }, { + // table not found + in: []*vrStream{{ + bls: &binlogdatapb.BinlogSource{ + Filter: &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{{ + Match: "t3", + }}, + }, + }, + }}, + err: `table t3 not found in vschema`, + }, { + // sharded table with no filter + in: []*vrStream{{ + bls: &binlogdatapb.BinlogSource{ + Filter: &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{{ + Match: "t1", + }}, + }, + }, + }}, + err: `rule match:"t1" does not have a select expression in vreplication`, + }, { + // Excluded table. + in: []*vrStream{{ + bls: &binlogdatapb.BinlogSource{ + Filter: &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{{ + Match: "t1", + Filter: vreplication.ExcludeStr, + }}, + }, + }, + }}, + err: `unexpected rule in vreplication: match:"t1" filter:"exclude" `, + }, { + // Sharded table and ref table + in: []*vrStream{{ + bls: &binlogdatapb.BinlogSource{ + Filter: &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{{ + Match: "t1", + Filter: "-80", + }, { + Match: "ref", + Filter: "", + }}, + }, + }, + }}, + err: `cannot migrate streams with a mix of reference and sharded tables: filter: rules: > `, + }, { + // Ref table and sharded table (different code path) + in: []*vrStream{{ + bls: &binlogdatapb.BinlogSource{ + Filter: &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{{ + Match: "ref", + Filter: "", + }, { + Match: "t2", + Filter: "-80", + }}, + }, + }, + }}, + err: `cannot migrate streams with a mix of reference and sharded tables: filter: rules: > `, + }, { + // Ref table with select expression + in: []*vrStream{{ + bls: &binlogdatapb.BinlogSource{ + Filter: &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{{ + Match: "ref", + Filter: "select * from t1", + }}, + }, + }, + }}, + out: "", + }, { + // Select expresstion with no keyrange value + in: []*vrStream{{ + bls: &binlogdatapb.BinlogSource{ + Filter: &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{{ + Match: "t1", + Filter: "select * from t1", + }}, + }, + }, + }}, + out: `[{"ID":0,"Workflow":"","Bls":{"filter":{"rules":[{"match":"t1","filter":"select * from t1 where in_keyrange(c1, 'hash', '{{.}}')"}]}}}]`, + }, { + // Select expresstion with one keyrange value + in: []*vrStream{{ + bls: &binlogdatapb.BinlogSource{ + Filter: &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{{ + Match: "t1", + Filter: "select * from t1 where in_keyrange('-80')", + }}, + }, + }, + }}, + out: `[{"ID":0,"Workflow":"","Bls":{"filter":{"rules":[{"match":"t1","filter":"select * from t1 where in_keyrange('{{.}}')"}]}}}]`, + }, { + // Select expresstion with three keyrange values + in: []*vrStream{{ + bls: &binlogdatapb.BinlogSource{ + Filter: &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{{ + Match: "t1", + Filter: "select * from t1 where in_keyrange(col, vdx, '-80')", + }}, + }, + }, + }}, + out: `[{"ID":0,"Workflow":"","Bls":{"filter":{"rules":[{"match":"t1","filter":"select * from t1 where in_keyrange(col, vdx, '{{.}}')"}]}}}]`, + }, { + // syntax error + in: []*vrStream{{ + bls: &binlogdatapb.BinlogSource{ + Filter: &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{{ + Match: "t1", + Filter: "bad syntax", + }}, + }, + }, + }}, + err: "syntax error at position 4 near 'bad'", + }, { + // invalid statement + in: []*vrStream{{ + bls: &binlogdatapb.BinlogSource{ + Filter: &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{{ + Match: "t1", + Filter: "update t set a=1", + }}, + }, + }, + }}, + err: "unexpected query: update t set a=1", + }, { + // invalid in_keyrange + in: []*vrStream{{ + bls: &binlogdatapb.BinlogSource{ + Filter: &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{{ + Match: "t1", + Filter: "select * from t1 where in_keyrange(col, vdx, '-80', extra)", + }}, + }, + }, + }}, + err: "unexpected in_keyrange parameters: in_keyrange(col, vdx, '-80', extra)", + }, { + // * in_keyrange + in: []*vrStream{{ + bls: &binlogdatapb.BinlogSource{ + Filter: &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{{ + Match: "t1", + Filter: "select * from t1 where in_keyrange(*)", + }}, + }, + }, + }}, + err: "unexpected in_keyrange parameters: in_keyrange(*)", + }, { + // non-string in_keyrange + in: []*vrStream{{ + bls: &binlogdatapb.BinlogSource{ + Filter: &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{{ + Match: "t1", + Filter: "select * from t1 where in_keyrange(aa)", + }}, + }, + }, + }}, + err: "unexpected in_keyrange parameters: in_keyrange(aa)", + }, { + // '{{' in query + in: []*vrStream{{ + bls: &binlogdatapb.BinlogSource{ + Filter: &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{{ + Match: "t1", + Filter: "select '{{' from t1 where in_keyrange('-80')", + }}, + }, + }, + }}, + err: "cannot migrate queries that contain '{{' in their string: select '{{' from t1 where in_keyrange('-80')", + }} + vs := &vschemapb.Keyspace{ + Sharded: true, + Vindexes: map[string]*vschema.Vindex{ + "thash": { + Type: "hash", + }, + }, + Tables: map[string]*vschema.Table{ + "t1": { + ColumnVindexes: []*vschema.ColumnVindex{{ + Columns: []string{"c1"}, + Name: "thash", + }}, + }, + "t2": { + ColumnVindexes: []*vschema.ColumnVindex{{ + Columns: []string{"c1"}, + Name: "thash", + }}, + }, + "ref": { + Type: vindexes.TypeReference, + }, + }, + } + ksschema, err := vindexes.BuildKeyspaceSchema(vs, "ks") + if err != nil { + t.Fatal(err) + } + mi := &migrater{ + sourceKSSchema: ksschema, + } + for _, tt := range tests { + sm := &streamMigrater{mi: mi} + out, err := sm.templatize(context.Background(), tt.in) + var gotErr string + if err != nil { + gotErr = err.Error() + } + if gotErr != tt.err { + t.Errorf("templatize(%v) err: %v, want %v", stringifyVRS(tt.in), err, tt.err) + } + got := stringifyVRS(out) + if !reflect.DeepEqual(tt.out, got) { + t.Errorf("templatize(%v):\n%v, want\n%v", stringifyVRS(tt.in), got, tt.out) + } + } +} + +type testVRS struct { + ID uint32 + Workflow string + Bls *binlogdatapb.BinlogSource +} + +func stringifyVRS(in []*vrStream) string { + if len(in) == 0 { + return "" + } + var converted []*testVRS + for _, vrs := range in { + converted = append(converted, &testVRS{ + ID: vrs.id, + Workflow: vrs.workflow, + Bls: vrs.bls, + }) + } + b, _ := json.Marshal(converted) + return string(b) +} diff --git a/go/vt/wrangler/tablet.go b/go/vt/wrangler/tablet.go index 3f22a67081b..a8b4cab9bc3 100644 --- a/go/vt/wrangler/tablet.go +++ b/go/vt/wrangler/tablet.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -18,9 +18,11 @@ package wrangler import ( "fmt" + "time" "golang.org/x/net/context" "vitess.io/vitess/go/vt/key" + "vitess.io/vitess/go/vt/logutil" "vitess.io/vitess/go/vt/topo" "vitess.io/vitess/go/vt/topo/topoproto" "vitess.io/vitess/go/vt/topotools" @@ -70,9 +72,10 @@ func (wr *Wrangler) InitTablet(ctx context.Context, tablet *topodatapb.Tablet, a return fmt.Errorf("creating this tablet would override old master %v in shard %v/%v, use allow_master_override flag", topoproto.TabletAliasString(si.MasterAlias), tablet.Keyspace, tablet.Shard) } - // update the shard record if needed - if err := wr.updateShardMaster(ctx, si, tablet.Alias, tablet.Type, allowMasterOverride); err != nil { - return err + if tablet.Type == topodatapb.TabletType_MASTER { + // we update master_term_start_time even if the master hasn't changed + // because that means a new master term with the same master + tablet.MasterTermStartTime = logutil.TimeToProto(time.Now()) } err = wr.ts.CreateTablet(ctx, tablet) @@ -88,7 +91,6 @@ func (wr *Wrangler) InitTablet(ctx context.Context, tablet *topodatapb.Tablet, a if oldTablet.Keyspace != tablet.Keyspace || oldTablet.Shard != tablet.Shard { return fmt.Errorf("old tablet has shard %v/%v. Cannot override with shard %v/%v. Delete and re-add tablet if you want to change the tablet's keyspace/shard", oldTablet.Keyspace, oldTablet.Shard, tablet.Keyspace, tablet.Shard) } - *(oldTablet.Tablet) = *tablet if err := wr.ts.UpdateTablet(ctx, oldTablet); err != nil { return fmt.Errorf("failed updating tablet %v: %v", topoproto.TabletAliasString(tablet.Alias), err) diff --git a/go/vt/wrangler/tablet_test.go b/go/vt/wrangler/tablet_test.go index c5a445c32a5..68542de8a82 100644 --- a/go/vt/wrangler/tablet_test.go +++ b/go/vt/wrangler/tablet_test.go @@ -1,3 +1,19 @@ +/* +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 wrangler import ( diff --git a/go/vt/wrangler/testlib/apply_schema_test.go b/go/vt/wrangler/testlib/apply_schema_test.go index 1f8a3ed7f48..534d2fff8e2 100644 --- a/go/vt/wrangler/testlib/apply_schema_test.go +++ b/go/vt/wrangler/testlib/apply_schema_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/wrangler/testlib/backup_test.go b/go/vt/wrangler/testlib/backup_test.go index d4d68690ee2..861fcb5de6a 100644 --- a/go/vt/wrangler/testlib/backup_test.go +++ b/go/vt/wrangler/testlib/backup_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -21,6 +21,7 @@ import ( "os" "path" "testing" + "time" "golang.org/x/net/context" @@ -31,6 +32,7 @@ import ( "vitess.io/vitess/go/vt/mysqlctl" "vitess.io/vitess/go/vt/mysqlctl/backupstorage" "vitess.io/vitess/go/vt/mysqlctl/filebackupstorage" + "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/vttablet/tmclient" @@ -94,10 +96,26 @@ func TestBackupRestore(t *testing.T) { t.Fatalf("failed to write file db.opt: %v", err) } - // create a master tablet, not started, just for shard health + // create a master tablet, set its master position master := NewFakeTablet(t, wr, "cell1", 0, topodatapb.TabletType_MASTER, db) + master.FakeMysqlDaemon.ReadOnly = false + master.FakeMysqlDaemon.Replicating = false + master.FakeMysqlDaemon.CurrentMasterPosition = mysql.Position{ + GTIDSet: mysql.MariadbGTIDSet{ + mysql.MariadbGTID{ + Domain: 2, + Server: 123, + Sequence: 457, + }, + }, + } + + // start master so that replica can fetch master position from it + master.StartActionLoop(t, wr) + defer master.StopActionLoop(t) // create a single tablet, set it up so we can do backups + // set its position same as that of master so that backup doesn't wait for catchup sourceTablet := NewFakeTablet(t, wr, "cell1", 1, topodatapb.TabletType_REPLICA, db) sourceTablet.FakeMysqlDaemon.ReadOnly = true sourceTablet.FakeMysqlDaemon.Replicating = true @@ -194,3 +212,169 @@ func TestBackupRestore(t *testing.T) { } } + +func TestRestoreUnreachableMaster(t *testing.T) { + // Initialize our environment + ctx := context.Background() + db := fakesqldb.New(t) + defer db.Close() + ts := memorytopo.NewServer("cell1") + wr := wrangler.New(logutil.NewConsoleLogger(), ts, tmclient.NewTabletManagerClient()) + vp := NewVtctlPipe(t, ts) + defer vp.Close() + + // Set up mock query results. + db.AddQuery("CREATE DATABASE IF NOT EXISTS _vt", &sqltypes.Result{}) + db.AddQuery("BEGIN", &sqltypes.Result{}) + db.AddQuery("COMMIT", &sqltypes.Result{}) + db.AddQueryPattern(`SET @@session\.sql_log_bin = .*`, &sqltypes.Result{}) + db.AddQueryPattern(`CREATE TABLE IF NOT EXISTS _vt\.shard_metadata .*`, &sqltypes.Result{}) + db.AddQueryPattern(`CREATE TABLE IF NOT EXISTS _vt\.local_metadata .*`, &sqltypes.Result{}) + db.AddQueryPattern(`ALTER TABLE _vt\.local_metadata .*`, &sqltypes.Result{}) + db.AddQueryPattern(`ALTER TABLE _vt\.shard_metadata .*`, &sqltypes.Result{}) + db.AddQueryPattern(`UPDATE _vt\.local_metadata SET db_name=.*`, &sqltypes.Result{}) + db.AddQueryPattern(`UPDATE _vt\.shard_metadata SET db_name=.*`, &sqltypes.Result{}) + db.AddQueryPattern(`INSERT INTO _vt\.local_metadata .*`, &sqltypes.Result{}) + + // Initialize our temp dirs + root, err := ioutil.TempDir("", "backuptest") + if err != nil { + t.Fatalf("os.TempDir failed: %v", err) + } + defer os.RemoveAll(root) + + // Initialize BackupStorage + fbsRoot := path.Join(root, "fbs") + *filebackupstorage.FileBackupStorageRoot = fbsRoot + *backupstorage.BackupStorageImplementation = "file" + + // Initialize the fake mysql root directories + sourceInnodbDataDir := path.Join(root, "source_innodb_data") + sourceInnodbLogDir := path.Join(root, "source_innodb_log") + sourceDataDir := path.Join(root, "source_data") + sourceDataDbDir := path.Join(sourceDataDir, "vt_db") + for _, s := range []string{sourceInnodbDataDir, sourceInnodbLogDir, sourceDataDbDir} { + if err := os.MkdirAll(s, os.ModePerm); err != nil { + t.Fatalf("failed to create directory %v: %v", s, err) + } + } + if err := ioutil.WriteFile(path.Join(sourceInnodbDataDir, "innodb_data_1"), []byte("innodb data 1 contents"), os.ModePerm); err != nil { + t.Fatalf("failed to write file innodb_data_1: %v", err) + } + if err := ioutil.WriteFile(path.Join(sourceInnodbLogDir, "innodb_log_1"), []byte("innodb log 1 contents"), os.ModePerm); err != nil { + t.Fatalf("failed to write file innodb_log_1: %v", err) + } + if err := ioutil.WriteFile(path.Join(sourceDataDbDir, "db.opt"), []byte("db opt file"), os.ModePerm); err != nil { + t.Fatalf("failed to write file db.opt: %v", err) + } + + // create a master tablet, set its master position + master := NewFakeTablet(t, wr, "cell1", 0, topodatapb.TabletType_MASTER, db) + master.FakeMysqlDaemon.ReadOnly = false + master.FakeMysqlDaemon.Replicating = false + master.FakeMysqlDaemon.CurrentMasterPosition = mysql.Position{ + GTIDSet: mysql.MariadbGTIDSet{ + mysql.MariadbGTID{ + Domain: 2, + Server: 123, + Sequence: 457, + }, + }, + } + + // start master so that replica can fetch master position from it + master.StartActionLoop(t, wr) + + // create a single tablet, set it up so we can do backups + // set its position same as that of master so that backup doesn't wait for catchup + sourceTablet := NewFakeTablet(t, wr, "cell1", 1, topodatapb.TabletType_REPLICA, db) + sourceTablet.FakeMysqlDaemon.ReadOnly = true + sourceTablet.FakeMysqlDaemon.Replicating = true + sourceTablet.FakeMysqlDaemon.CurrentMasterPosition = mysql.Position{ + GTIDSet: mysql.MariadbGTIDSet{ + mysql.MariadbGTID{ + Domain: 2, + Server: 123, + Sequence: 457, + }, + }, + } + sourceTablet.FakeMysqlDaemon.ExpectedExecuteSuperQueryList = []string{ + "STOP SLAVE", + "START SLAVE", + } + sourceTablet.StartActionLoop(t, wr) + defer sourceTablet.StopActionLoop(t) + + sourceTablet.Agent.Cnf = &mysqlctl.Mycnf{ + DataDir: sourceDataDir, + InnodbDataHomeDir: sourceInnodbDataDir, + InnodbLogGroupHomeDir: sourceInnodbLogDir, + } + + // run the backup + if err := vp.Run([]string{"Backup", topoproto.TabletAliasString(sourceTablet.Tablet.Alias)}); err != nil { + t.Fatalf("Backup failed: %v", err) + } + + // create a destination tablet, set it up so we can do restores + destTablet := NewFakeTablet(t, wr, "cell1", 2, topodatapb.TabletType_REPLICA, db) + destTablet.FakeMysqlDaemon.ReadOnly = true + destTablet.FakeMysqlDaemon.Replicating = true + destTablet.FakeMysqlDaemon.CurrentMasterPosition = mysql.Position{ + GTIDSet: mysql.MariadbGTIDSet{ + mysql.MariadbGTID{ + Domain: 2, + Server: 123, + Sequence: 457, + }, + }, + } + destTablet.FakeMysqlDaemon.ExpectedExecuteSuperQueryList = []string{ + "STOP SLAVE", + "RESET SLAVE ALL", + "FAKE SET SLAVE POSITION", + "FAKE SET MASTER", + "START SLAVE", + } + destTablet.FakeMysqlDaemon.FetchSuperQueryMap = map[string]*sqltypes.Result{ + "SHOW DATABASES": {}, + } + destTablet.FakeMysqlDaemon.SetSlavePositionPos = sourceTablet.FakeMysqlDaemon.CurrentMasterPosition + destTablet.FakeMysqlDaemon.SetMasterInput = topoproto.MysqlAddr(master.Tablet) + + destTablet.StartActionLoop(t, wr) + defer destTablet.StopActionLoop(t) + + destTablet.Agent.Cnf = &mysqlctl.Mycnf{ + DataDir: sourceDataDir, + InnodbDataHomeDir: sourceInnodbDataDir, + InnodbLogGroupHomeDir: sourceInnodbLogDir, + BinLogPath: path.Join(root, "bin-logs/filename_prefix"), + RelayLogPath: path.Join(root, "relay-logs/filename_prefix"), + RelayLogIndexPath: path.Join(root, "relay-log.index"), + RelayLogInfoPath: path.Join(root, "relay-log.info"), + } + + // stop master so that it is unreachable + master.StopActionLoop(t) + + // set a short timeout so that we don't have to wait 30 seconds + *topo.RemoteOperationTimeout = 2 * time.Second + // Restore should still succeed + if err := destTablet.Agent.RestoreData(ctx, logutil.NewConsoleLogger(), 0 /* waitForBackupInterval */, false /* deleteBeforeRestore */); err != nil { + t.Fatalf("RestoreData failed: %v", err) + } + + // verify the full status + if err := destTablet.FakeMysqlDaemon.CheckSuperQueryList(); err != nil { + t.Errorf("destTablet.FakeMysqlDaemon.CheckSuperQueryList failed: %v", err) + } + if !destTablet.FakeMysqlDaemon.Replicating { + t.Errorf("destTablet.FakeMysqlDaemon.Replicating not set") + } + if !destTablet.FakeMysqlDaemon.Running { + t.Errorf("destTablet.FakeMysqlDaemon.Running not set") + } + +} diff --git a/go/vt/wrangler/testlib/copy_schema_shard_test.go b/go/vt/wrangler/testlib/copy_schema_shard_test.go index ad33097440b..35523a7dd26 100644 --- a/go/vt/wrangler/testlib/copy_schema_shard_test.go +++ b/go/vt/wrangler/testlib/copy_schema_shard_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/wrangler/testlib/emergency_reparent_shard_test.go b/go/vt/wrangler/testlib/emergency_reparent_shard_test.go index 0df00ad3d58..6749d8e8c03 100644 --- a/go/vt/wrangler/testlib/emergency_reparent_shard_test.go +++ b/go/vt/wrangler/testlib/emergency_reparent_shard_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/wrangler/testlib/external_reparent_test.go b/go/vt/wrangler/testlib/external_reparent_test.go new file mode 100644 index 00000000000..5fbfd239f5e --- /dev/null +++ b/go/vt/wrangler/testlib/external_reparent_test.go @@ -0,0 +1,438 @@ +/* +Copyright 2017 Google Inc. + +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 testlib + +import ( + "testing" + "time" + + "golang.org/x/net/context" + + "vitess.io/vitess/go/vt/logutil" + "vitess.io/vitess/go/vt/topo/memorytopo" + "vitess.io/vitess/go/vt/topo/topoproto" + "vitess.io/vitess/go/vt/topotools" + "vitess.io/vitess/go/vt/vttablet/tmclient" + "vitess.io/vitess/go/vt/wrangler" + + topodatapb "vitess.io/vitess/go/vt/proto/topodata" +) + +// The tests in this package test the wrangler version of TabletExternallyReparented +// This is the one that is now called by the vtctl command + +// TestTabletExternallyReparentedBasic tests the base cases for TER +func TestTabletExternallyReparentedBasic(t *testing.T) { + ctx := context.Background() + ts := memorytopo.NewServer("cell1") + wr := wrangler.New(logutil.NewConsoleLogger(), ts, tmclient.NewTabletManagerClient()) + vp := NewVtctlPipe(t, ts) + defer vp.Close() + + // Create an old master, a new master, two good replicas, one bad replica + oldMaster := NewFakeTablet(t, wr, "cell1", 0, topodatapb.TabletType_MASTER, nil) + newMaster := NewFakeTablet(t, wr, "cell1", 1, topodatapb.TabletType_REPLICA, nil) + + // Build keyspace graph + err := topotools.RebuildKeyspace(ctx, logutil.NewConsoleLogger(), ts, oldMaster.Tablet.Keyspace, []string{"cell1"}) + if err != nil { + t.Fatalf("RebuildKeyspaceLocked failed: %v", err) + } + + // On the elected master, we will respond to + // TabletActionSlaveWasPromoted + newMaster.StartActionLoop(t, wr) + defer newMaster.StopActionLoop(t) + + // On the old master, we will only respond to + // TabletActionSlaveWasRestarted. + oldMaster.StartActionLoop(t, wr) + defer oldMaster.StopActionLoop(t) + + // First test: reparent to the same master, make sure it works + // as expected. + if err := vp.Run([]string{"TabletExternallyReparented", topoproto.TabletAliasString(oldMaster.Tablet.Alias)}); err != nil { + t.Fatalf("TabletExternallyReparented(same master) should have worked: %v", err) + } + + // check the old master is still master + tablet, err := ts.GetTablet(ctx, oldMaster.Tablet.Alias) + if err != nil { + t.Fatalf("GetTablet(%v) failed: %v", oldMaster.Tablet.Alias, err) + } + if tablet.Type != topodatapb.TabletType_MASTER { + t.Fatalf("old master should be MASTER but is: %v", tablet.Type) + } + + oldMaster.FakeMysqlDaemon.SetMasterInput = topoproto.MysqlAddr(newMaster.Tablet) + oldMaster.FakeMysqlDaemon.ExpectedExecuteSuperQueryList = []string{ + "FAKE SET MASTER", + "START SLAVE", + } + + // This tests the good case, where everything works as planned + t.Logf("TabletExternallyReparented(new master) expecting success") + if err := wr.TabletExternallyReparented(ctx, newMaster.Tablet.Alias); err != nil { + t.Fatalf("TabletExternallyReparented(replica) failed: %v", err) + } + + // check the new master is master + tablet, err = ts.GetTablet(ctx, newMaster.Tablet.Alias) + if err != nil { + t.Fatalf("GetTablet(%v) failed: %v", newMaster.Tablet.Alias, err) + } + if tablet.Type != topodatapb.TabletType_MASTER { + t.Fatalf("new master should be MASTER but is: %v", tablet.Type) + } + + // We have to wait for shard sync to do its magic in the background + startTime := time.Now() + for { + if time.Since(startTime) > 10*time.Second /* timeout */ { + tablet, err = ts.GetTablet(ctx, oldMaster.Tablet.Alias) + if err != nil { + t.Fatalf("GetTablet(%v) failed: %v", oldMaster.Tablet.Alias, err) + } + t.Fatalf("old master (%v) should be replica but is: %v", topoproto.TabletAliasString(oldMaster.Tablet.Alias), tablet.Type) + } + // check the old master was converted to replica + tablet, err = ts.GetTablet(ctx, oldMaster.Tablet.Alias) + if err != nil { + t.Fatalf("GetTablet(%v) failed: %v", oldMaster.Tablet.Alias, err) + } + if tablet.Type == topodatapb.TabletType_REPLICA { + break + } else { + time.Sleep(100 * time.Millisecond /* interval at which to check again */) + } + } +} + +func TestTabletExternallyReparentedToSlave(t *testing.T) { + ctx := context.Background() + ts := memorytopo.NewServer("cell1") + wr := wrangler.New(logutil.NewConsoleLogger(), ts, tmclient.NewTabletManagerClient()) + + // Create an old master, a new master, two good replicas, one bad replica + oldMaster := NewFakeTablet(t, wr, "cell1", 0, topodatapb.TabletType_MASTER, nil) + newMaster := NewFakeTablet(t, wr, "cell1", 1, topodatapb.TabletType_REPLICA, nil) + newMaster.FakeMysqlDaemon.ReadOnly = true + newMaster.FakeMysqlDaemon.Replicating = true + + // Build keyspace graph + err := topotools.RebuildKeyspace(ctx, logutil.NewConsoleLogger(), ts, oldMaster.Tablet.Keyspace, []string{"cell1"}) + if err != nil { + t.Fatalf("RebuildKeyspaceLocked failed: %v", err) + } + + // On the elected master, we will respond to + // TabletActionSlaveWasPromoted + newMaster.StartActionLoop(t, wr) + defer newMaster.StopActionLoop(t) + + // On the old master, we will only respond to + // TabletActionSlaveWasRestarted. + oldMaster.StartActionLoop(t, wr) + defer oldMaster.StopActionLoop(t) + + // Second test: reparent to a replica, and pretend the old + // master is still good to go. + oldMaster.FakeMysqlDaemon.SetMasterInput = topoproto.MysqlAddr(newMaster.Tablet) + oldMaster.FakeMysqlDaemon.ExpectedExecuteSuperQueryList = []string{ + "FAKE SET MASTER", + "START SLAVE", + } + + // This tests a bad case: the new designated master is a slave at mysql level, + // but we should do what we're told anyway. + if err := wr.TabletExternallyReparented(ctx, newMaster.Tablet.Alias); err != nil { + t.Fatalf("TabletExternallyReparented(replica) error: %v", err) + } + + // check that newMaster is master + tablet, err := ts.GetTablet(ctx, newMaster.Tablet.Alias) + if err != nil { + t.Fatalf("GetTablet(%v) failed: %v", newMaster.Tablet.Alias, err) + } + if tablet.Type != topodatapb.TabletType_MASTER { + t.Fatalf("new master should be MASTER but is: %v", tablet.Type) + } + + // We have to wait for shard sync to do its magic in the background + startTime := time.Now() + for { + if time.Since(startTime) > 10*time.Second /* timeout */ { + tablet, err = ts.GetTablet(ctx, oldMaster.Tablet.Alias) + if err != nil { + t.Fatalf("GetTablet(%v) failed: %v", oldMaster.Tablet.Alias, err) + } + t.Fatalf("old master (%v) should be replica but is: %v", topoproto.TabletAliasString(oldMaster.Tablet.Alias), tablet.Type) + } + // check the old master was converted to replica + tablet, err = ts.GetTablet(ctx, oldMaster.Tablet.Alias) + if err != nil { + t.Fatalf("GetTablet(%v) failed: %v", oldMaster.Tablet.Alias, err) + } + if tablet.Type == topodatapb.TabletType_REPLICA { + break + } else { + time.Sleep(100 * time.Millisecond /* interval at which to check again */) + } + } +} + +// TestTabletExternallyReparentedWithDifferentMysqlPort makes sure +// that if mysql is restarted on the master-elect tablet and has a different +// port, we pick it up correctly. +func TestTabletExternallyReparentedWithDifferentMysqlPort(t *testing.T) { + ctx := context.Background() + ts := memorytopo.NewServer("cell1") + wr := wrangler.New(logutil.NewConsoleLogger(), ts, tmclient.NewTabletManagerClient()) + + // Create an old master, a new master, two good replicas, one bad replica + oldMaster := NewFakeTablet(t, wr, "cell1", 0, topodatapb.TabletType_MASTER, nil) + newMaster := NewFakeTablet(t, wr, "cell1", 1, topodatapb.TabletType_REPLICA, nil) + goodReplica := NewFakeTablet(t, wr, "cell1", 2, topodatapb.TabletType_REPLICA, nil) + + // Build keyspace graph + err := topotools.RebuildKeyspace(context.Background(), logutil.NewConsoleLogger(), ts, oldMaster.Tablet.Keyspace, []string{"cell1"}) + if err != nil { + t.Fatalf("RebuildKeyspaceLocked failed: %v", err) + } + // Now we're restarting mysql on a different port, 3301->3303 + // but without updating the Tablet record in topology. + + // On the elected master, we will respond to + // TabletActionSlaveWasPromoted, so we need a MysqlDaemon + // that returns no master, and the new port (as returned by mysql) + newMaster.FakeMysqlDaemon.MysqlPort = 3303 + newMaster.StartActionLoop(t, wr) + defer newMaster.StopActionLoop(t) + + oldMaster.FakeMysqlDaemon.SetMasterInput = topoproto.MysqlAddr(newMaster.Tablet) + oldMaster.FakeMysqlDaemon.ExpectedExecuteSuperQueryList = []string{ + "FAKE SET MASTER", + "START SLAVE", + } + // On the old master, we will only respond to + // TabletActionSlaveWasRestarted and point to the new mysql port + oldMaster.StartActionLoop(t, wr) + defer oldMaster.StopActionLoop(t) + + // On the good replicas, we will respond to + // TabletActionSlaveWasRestarted and point to the new mysql port + goodReplica.StartActionLoop(t, wr) + defer goodReplica.StopActionLoop(t) + + // This tests the good case, where everything works as planned + t.Logf("TabletExternallyReparented(new master) expecting success") + if err := wr.TabletExternallyReparented(ctx, newMaster.Tablet.Alias); err != nil { + t.Fatalf("TabletExternallyReparented(replica) failed: %v", err) + } + // check the new master is master + tablet, err := ts.GetTablet(ctx, newMaster.Tablet.Alias) + if err != nil { + t.Fatalf("GetTablet(%v) failed: %v", newMaster.Tablet.Alias, err) + } + if tablet.Type != topodatapb.TabletType_MASTER { + t.Fatalf("new master should be MASTER but is: %v", tablet.Type) + } + + // We have to wait for shard sync to do its magic in the background + startTime := time.Now() + for { + if time.Since(startTime) > 10*time.Second /* timeout */ { + tablet, err = ts.GetTablet(ctx, oldMaster.Tablet.Alias) + if err != nil { + t.Fatalf("GetTablet(%v) failed: %v", oldMaster.Tablet.Alias, err) + } + t.Fatalf("old master (%v) should be replica but is: %v", topoproto.TabletAliasString(oldMaster.Tablet.Alias), tablet.Type) + } + // check the old master was converted to replica + tablet, err = ts.GetTablet(ctx, oldMaster.Tablet.Alias) + if err != nil { + t.Fatalf("GetTablet(%v) failed: %v", oldMaster.Tablet.Alias, err) + } + if tablet.Type == topodatapb.TabletType_REPLICA { + break + } else { + time.Sleep(100 * time.Millisecond /* interval at which to check again */) + } + } +} + +// TestTabletExternallyReparentedContinueOnUnexpectedMaster makes sure +// that we ignore mysql's master if the flag is set +func TestTabletExternallyReparentedContinueOnUnexpectedMaster(t *testing.T) { + ctx := context.Background() + ts := memorytopo.NewServer("cell1") + wr := wrangler.New(logutil.NewConsoleLogger(), ts, tmclient.NewTabletManagerClient()) + + // Create an old master, a new master, two good replicas, one bad replica + oldMaster := NewFakeTablet(t, wr, "cell1", 0, topodatapb.TabletType_MASTER, nil) + newMaster := NewFakeTablet(t, wr, "cell1", 1, topodatapb.TabletType_REPLICA, nil) + goodReplica := NewFakeTablet(t, wr, "cell1", 2, topodatapb.TabletType_REPLICA, nil) + + // Build keyspace graph + err := topotools.RebuildKeyspace(context.Background(), logutil.NewConsoleLogger(), ts, oldMaster.Tablet.Keyspace, []string{"cell1"}) + if err != nil { + t.Fatalf("RebuildKeyspaceLocked failed: %v", err) + } + // On the elected master, we will respond to + // TabletActionSlaveWasPromoted, so we need a MysqlDaemon + // that returns no master, and the new port (as returned by mysql) + newMaster.StartActionLoop(t, wr) + defer newMaster.StopActionLoop(t) + + oldMaster.FakeMysqlDaemon.SetMasterInput = topoproto.MysqlAddr(newMaster.Tablet) + oldMaster.FakeMysqlDaemon.ExpectedExecuteSuperQueryList = []string{ + "FAKE SET MASTER", + "START SLAVE", + } + // On the old master, we will only respond to + // TabletActionSlaveWasRestarted and point to a bad host + oldMaster.StartActionLoop(t, wr) + defer oldMaster.StopActionLoop(t) + + // On the good replica, we will respond to + // TabletActionSlaveWasRestarted and point to a bad host + goodReplica.StartActionLoop(t, wr) + defer goodReplica.StopActionLoop(t) + + // This tests the good case, where everything works as planned + t.Logf("TabletExternallyReparented(new master) expecting success") + if err := wr.TabletExternallyReparented(ctx, newMaster.Tablet.Alias); err != nil { + t.Fatalf("TabletExternallyReparented(replica) failed: %v", err) + } + // check the new master is master + tablet, err := ts.GetTablet(ctx, newMaster.Tablet.Alias) + if err != nil { + t.Fatalf("GetTablet(%v) failed: %v", newMaster.Tablet.Alias, err) + } + if tablet.Type != topodatapb.TabletType_MASTER { + t.Fatalf("new master should be MASTER but is: %v", tablet.Type) + } + // We have to wait for shard sync to do its magic in the background + startTime := time.Now() + for { + if time.Since(startTime) > 10*time.Second /* timeout */ { + tablet, err = ts.GetTablet(ctx, oldMaster.Tablet.Alias) + if err != nil { + t.Fatalf("GetTablet(%v) failed: %v", oldMaster.Tablet.Alias, err) + } + t.Fatalf("old master (%v) should be replica but is: %v", topoproto.TabletAliasString(oldMaster.Tablet.Alias), tablet.Type) + } + // check the old master was converted to replica + tablet, err = ts.GetTablet(ctx, oldMaster.Tablet.Alias) + if err != nil { + t.Fatalf("GetTablet(%v) failed: %v", oldMaster.Tablet.Alias, err) + } + if tablet.Type == topodatapb.TabletType_REPLICA { + break + } else { + time.Sleep(100 * time.Millisecond /* interval at which to check again */) + } + } +} + +func TestTabletExternallyReparentedRerun(t *testing.T) { + ctx := context.Background() + ts := memorytopo.NewServer("cell1") + wr := wrangler.New(logutil.NewConsoleLogger(), ts, tmclient.NewTabletManagerClient()) + + // Create an old master, a new master, and a good replica. + oldMaster := NewFakeTablet(t, wr, "cell1", 0, topodatapb.TabletType_MASTER, nil) + newMaster := NewFakeTablet(t, wr, "cell1", 1, topodatapb.TabletType_REPLICA, nil) + goodReplica := NewFakeTablet(t, wr, "cell1", 2, topodatapb.TabletType_REPLICA, nil) + + // Build keyspace graph + err := topotools.RebuildKeyspace(context.Background(), logutil.NewConsoleLogger(), ts, oldMaster.Tablet.Keyspace, []string{"cell1"}) + if err != nil { + t.Fatalf("RebuildKeyspaceLocked failed: %v", err) + } + // On the elected master, we will respond to + // TabletActionSlaveWasPromoted. + newMaster.StartActionLoop(t, wr) + defer newMaster.StopActionLoop(t) + + oldMaster.FakeMysqlDaemon.SetMasterInput = topoproto.MysqlAddr(newMaster.Tablet) + oldMaster.FakeMysqlDaemon.ExpectedExecuteSuperQueryList = []string{ + "FAKE SET MASTER", + "START SLAVE", + } + // On the old master, we will only respond to + // TabletActionSlaveWasRestarted. + oldMaster.StartActionLoop(t, wr) + defer oldMaster.StopActionLoop(t) + + goodReplica.FakeMysqlDaemon.SetMasterInput = topoproto.MysqlAddr(newMaster.Tablet) + // On the good replica, we will respond to + // TabletActionSlaveWasRestarted. + goodReplica.StartActionLoop(t, wr) + defer goodReplica.StopActionLoop(t) + + // The reparent should work as expected here + if err := wr.TabletExternallyReparented(ctx, newMaster.Tablet.Alias); err != nil { + t.Fatalf("TabletExternallyReparented(replica) failed: %v", err) + } + + // check the new master is master + tablet, err := ts.GetTablet(ctx, newMaster.Tablet.Alias) + if err != nil { + t.Fatalf("GetTablet(%v) failed: %v", newMaster.Tablet.Alias, err) + } + if tablet.Type != topodatapb.TabletType_MASTER { + t.Fatalf("new master should be MASTER but is: %v", tablet.Type) + } + + // We have to wait for shard sync to do its magic in the background + startTime := time.Now() + for { + if time.Since(startTime) > 10*time.Second /* timeout */ { + tablet, err = ts.GetTablet(ctx, oldMaster.Tablet.Alias) + if err != nil { + t.Fatalf("GetTablet(%v) failed: %v", oldMaster.Tablet.Alias, err) + } + t.Fatalf("old master (%v) should be replica but is: %v", topoproto.TabletAliasString(oldMaster.Tablet.Alias), tablet.Type) + } + // check the old master was converted to replica + tablet, err = ts.GetTablet(ctx, oldMaster.Tablet.Alias) + if err != nil { + t.Fatalf("GetTablet(%v) failed: %v", oldMaster.Tablet.Alias, err) + } + if tablet.Type == topodatapb.TabletType_REPLICA { + break + } else { + time.Sleep(100 * time.Millisecond /* interval at which to check again */) + } + } + + // run TER again and make sure the master is still correct + if err := wr.TabletExternallyReparented(ctx, newMaster.Tablet.Alias); err != nil { + t.Fatalf("TabletExternallyReparented(replica) failed: %v", err) + } + + // check the new master is still master + tablet, err = ts.GetTablet(ctx, newMaster.Tablet.Alias) + if err != nil { + t.Fatalf("GetTablet(%v) failed: %v", newMaster.Tablet.Alias, err) + } + if tablet.Type != topodatapb.TabletType_MASTER { + t.Fatalf("new master should be MASTER but is: %v", tablet.Type) + } + +} diff --git a/go/vt/wrangler/testlib/fake_tablet.go b/go/vt/wrangler/testlib/fake_tablet.go index 75766e27d61..0e5be5c793c 100644 --- a/go/vt/wrangler/testlib/fake_tablet.go +++ b/go/vt/wrangler/testlib/fake_tablet.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/wrangler/testlib/find_tablet_test.go b/go/vt/wrangler/testlib/find_tablet_test.go new file mode 100644 index 00000000000..d6835ce053c --- /dev/null +++ b/go/vt/wrangler/testlib/find_tablet_test.go @@ -0,0 +1,92 @@ +/* +Copyright 2017 Google Inc. + +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 testlib + +import ( + "testing" + "time" + + "golang.org/x/net/context" + + "vitess.io/vitess/go/vt/logutil" + "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/topotools" + "vitess.io/vitess/go/vt/vttablet/tabletmanager" + "vitess.io/vitess/go/vt/vttablet/tmclient" + "vitess.io/vitess/go/vt/wrangler" + + topodatapb "vitess.io/vitess/go/vt/proto/topodata" +) + +func TestFindTablet(t *testing.T) { + tabletmanager.SetReparentFlags(time.Minute /* finalizeTimeout */) + + ctx := context.Background() + ts := memorytopo.NewServer("cell1", "cell2") + wr := wrangler.New(logutil.NewConsoleLogger(), ts, tmclient.NewTabletManagerClient()) + + // Create an old master, two good slaves + oldMaster := NewFakeTablet(t, wr, "cell1", 0, topodatapb.TabletType_MASTER, nil) + goodSlave1 := NewFakeTablet(t, wr, "cell1", 2, topodatapb.TabletType_REPLICA, nil) + goodSlave2 := NewFakeTablet(t, wr, "cell2", 3, topodatapb.TabletType_REPLICA, nil) + + // Build keyspace graph + err := topotools.RebuildKeyspace(context.Background(), logutil.NewConsoleLogger(), ts, oldMaster.Tablet.Keyspace, []string{"cell1", "cell2"}) + if err != nil { + t.Fatalf("RebuildKeyspaceLocked failed: %v", err) + } + + // make sure we can find the tablets + // even with a datacenter being down. + tabletMap, err := ts.GetTabletMapForShardByCell(ctx, "test_keyspace", "0", []string{"cell1"}) + if err != nil { + t.Fatalf("GetTabletMapForShardByCell should have worked but got: %v", err) + } + master, err := topotools.FindTabletByHostAndPort(tabletMap, oldMaster.Tablet.Hostname, "vt", oldMaster.Tablet.PortMap["vt"]) + if err != nil || !topoproto.TabletAliasEqual(master, oldMaster.Tablet.Alias) { + t.Fatalf("FindTabletByHostAndPort(master) failed: %v %v", err, master) + } + slave1, err := topotools.FindTabletByHostAndPort(tabletMap, goodSlave1.Tablet.Hostname, "vt", goodSlave1.Tablet.PortMap["vt"]) + if err != nil || !topoproto.TabletAliasEqual(slave1, goodSlave1.Tablet.Alias) { + t.Fatalf("FindTabletByHostAndPort(slave1) failed: %v %v", err, master) + } + slave2, err := topotools.FindTabletByHostAndPort(tabletMap, goodSlave2.Tablet.Hostname, "vt", goodSlave2.Tablet.PortMap["vt"]) + if !topo.IsErrType(err, topo.NoNode) { + t.Fatalf("FindTabletByHostAndPort(slave2) worked: %v %v", err, slave2) + } + + // Make sure the master is not exported in other cells + tabletMap, _ = ts.GetTabletMapForShardByCell(ctx, "test_keyspace", "0", []string{"cell2"}) + master, err = topotools.FindTabletByHostAndPort(tabletMap, oldMaster.Tablet.Hostname, "vt", oldMaster.Tablet.PortMap["vt"]) + if !topo.IsErrType(err, topo.NoNode) { + t.Fatalf("FindTabletByHostAndPort(master) worked in cell2: %v %v", err, master) + } + + // Get tablet map for all cells. If there were to be failures talking to local cells, this will return the tablet map + // and forward a partial result error + tabletMap, err = ts.GetTabletMapForShard(ctx, "test_keyspace", "0") + if err != nil { + t.Fatalf("GetTabletMapForShard should nil but got: %v", err) + } + master, err = topotools.FindTabletByHostAndPort(tabletMap, oldMaster.Tablet.Hostname, "vt", oldMaster.Tablet.PortMap["vt"]) + if err != nil || !topoproto.TabletAliasEqual(master, oldMaster.Tablet.Alias) { + t.Fatalf("FindTabletByHostAndPort(master) failed: %v %v", err, master) + } + +} diff --git a/go/vt/wrangler/testlib/init_shard_master_test.go b/go/vt/wrangler/testlib/init_shard_master_test.go index faf6d9069c0..870cc8094ef 100644 --- a/go/vt/wrangler/testlib/init_shard_master_test.go +++ b/go/vt/wrangler/testlib/init_shard_master_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -78,6 +78,29 @@ func TestInitMasterShard(t *testing.T) { master.StartActionLoop(t, wr) defer master.StopActionLoop(t) + // wait for shard record to be updated with master + startTime := time.Now() + for { + if time.Since(startTime) > 10*time.Second /* timeout */ { + si, err := ts.GetShard(ctx, master.Tablet.Keyspace, master.Tablet.Shard) + if err != nil { + t.Fatalf("GetShard(%v, %v) failed: %v", master.Tablet.Keyspace, master.Tablet.Shard, err) + } + if !topoproto.TabletAliasEqual(si.MasterAlias, master.Tablet.Alias) { + t.Fatalf("ShardInfo should have MasterAlias %v but has %v", topoproto.TabletAliasString(master.Tablet.Alias), topoproto.TabletAliasString(si.MasterAlias)) + } + } + si, err := ts.GetShard(ctx, master.Tablet.Keyspace, master.Tablet.Shard) + if err != nil { + t.Fatalf("GetShard(%v, %v) failed: %v", master.Tablet.Keyspace, master.Tablet.Shard, err) + } + if topoproto.TabletAliasEqual(si.MasterAlias, master.Tablet.Alias) { + break + } else { + time.Sleep(100 * time.Millisecond /* interval at which to re-check the shard record */) + } + } + // Slave1: expect to be reset and re-parented goodSlave1.FakeMysqlDaemon.ReadOnly = true goodSlave1.FakeMysqlDaemon.SetSlavePositionPos = master.FakeMysqlDaemon.CurrentMasterPosition @@ -155,7 +178,8 @@ func TestInitMasterShardChecks(t *testing.T) { // (master2 needs to run InitTablet with -force, as it is the second // master in the same shard) master2 := NewFakeTablet(t, wr, "cell1", 1, topodatapb.TabletType_MASTER, db, ForceInitTablet()) - if err := wr.InitShardMaster(ctx, master2.Tablet.Keyspace, master2.Tablet.Shard, master2.Tablet.Alias, false /*force*/, 10*time.Second); err == nil || !strings.Contains(err.Error(), "is not the only master in the shard") { + + if err := wr.InitShardMaster(ctx, master2.Tablet.Keyspace, master2.Tablet.Shard, master2.Tablet.Alias, false /*force*/, 10*time.Second); err == nil || !strings.Contains(err.Error(), "is not the shard master") { t.Errorf("InitShardMaster with two masters returned wrong error: %v", err) } @@ -208,6 +232,29 @@ func TestInitMasterShardOneSlaveFails(t *testing.T) { master.StartActionLoop(t, wr) defer master.StopActionLoop(t) + // wait for shard record to be updated with master + startTime := time.Now() + for { + if time.Since(startTime) > 10*time.Second /* timeout */ { + si, err := ts.GetShard(ctx, master.Tablet.Keyspace, master.Tablet.Shard) + if err != nil { + t.Fatalf("GetShard(%v, %v) failed: %v", master.Tablet.Keyspace, master.Tablet.Shard, err) + } + if !topoproto.TabletAliasEqual(si.MasterAlias, master.Tablet.Alias) { + t.Fatalf("ShardInfo should have MasterAlias %v but has %v", topoproto.TabletAliasString(master.Tablet.Alias), topoproto.TabletAliasString(si.MasterAlias)) + } + } + si, err := ts.GetShard(ctx, master.Tablet.Keyspace, master.Tablet.Shard) + if err != nil { + t.Fatalf("GetShard(%v, %v) failed: %v", master.Tablet.Keyspace, master.Tablet.Shard, err) + } + if topoproto.TabletAliasEqual(si.MasterAlias, master.Tablet.Alias) { + break + } else { + time.Sleep(100 * time.Millisecond /* interval at which to re-check the shard record */) + } + } + // goodSlave: expect to be re-parented goodSlave.FakeMysqlDaemon.ReadOnly = true goodSlave.FakeMysqlDaemon.SetSlavePositionPos = master.FakeMysqlDaemon.CurrentMasterPosition @@ -236,7 +283,7 @@ func TestInitMasterShardOneSlaveFails(t *testing.T) { // also change the master alias in the Shard object, to make sure it // is set back. _, err := ts.UpdateShardFields(ctx, master.Tablet.Keyspace, master.Tablet.Shard, func(si *topo.ShardInfo) error { - // note it's OK to retry this and increment mutiple times, + // note it's OK to retry this and increment multiple times, // we just want it to be different si.MasterAlias.Uid++ return nil diff --git a/go/vt/wrangler/testlib/migrate_served_from_test.go b/go/vt/wrangler/testlib/migrate_served_from_test.go index 9b804ed7c16..22912050631 100644 --- a/go/vt/wrangler/testlib/migrate_served_from_test.go +++ b/go/vt/wrangler/testlib/migrate_served_from_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/wrangler/testlib/migrate_served_types_test.go b/go/vt/wrangler/testlib/migrate_served_types_test.go index 3db2caa496e..c7debf1cc6d 100644 --- a/go/vt/wrangler/testlib/migrate_served_types_test.go +++ b/go/vt/wrangler/testlib/migrate_served_types_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -585,8 +585,9 @@ func TestMultiShardMigrateServedTypes(t *testing.T) { func expectDeleteVRepl(dbClient *binlogplayer.MockDBClient) { dbClient.ExpectRequest("use _vt", &sqltypes.Result{}, nil) + dbClient.ExpectRequest("select id from _vt.vreplication where id = 1", &sqltypes.Result{Rows: [][]sqltypes.Value{{sqltypes.NewInt64(1)}}}, nil) dbClient.ExpectRequest("begin", nil, nil) - dbClient.ExpectRequest("delete from _vt.vreplication where id = 1", &sqltypes.Result{RowsAffected: 1}, nil) - dbClient.ExpectRequest("delete from _vt.copy_state where vrepl_id = 1", nil, nil) + dbClient.ExpectRequest("delete from _vt.vreplication where id in (1)", &sqltypes.Result{RowsAffected: 1}, nil) + dbClient.ExpectRequest("delete from _vt.copy_state where vrepl_id in (1)", nil, nil) dbClient.ExpectRequest("commit", nil, nil) } diff --git a/go/vt/wrangler/testlib/permissions_test.go b/go/vt/wrangler/testlib/permissions_test.go index 70a8a94b7e5..903fbf8ff57 100644 --- a/go/vt/wrangler/testlib/permissions_test.go +++ b/go/vt/wrangler/testlib/permissions_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/wrangler/testlib/planned_reparent_shard_test.go b/go/vt/wrangler/testlib/planned_reparent_shard_test.go index eae9ef390b3..2378baa1587 100644 --- a/go/vt/wrangler/testlib/planned_reparent_shard_test.go +++ b/go/vt/wrangler/testlib/planned_reparent_shard_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -65,6 +65,9 @@ func TestPlannedReparentShardNoMasterProvided(t *testing.T) { }, } newMaster.FakeMysqlDaemon.ExpectedExecuteSuperQueryList = []string{ + "STOP SLAVE", + "FAKE SET MASTER", + "START SLAVE", "CREATE DATABASE IF NOT EXISTS _vt", "SUBCREATE TABLE IF NOT EXISTS _vt.reparent_journal", "SUBINSERT INTO _vt.reparent_journal (time_created_ns, action_name, master_alias, replication_position) VALUES", @@ -75,16 +78,23 @@ func TestPlannedReparentShardNoMasterProvided(t *testing.T) { // old master oldMaster.FakeMysqlDaemon.ReadOnly = false oldMaster.FakeMysqlDaemon.Replicating = false + oldMaster.FakeMysqlDaemon.SlaveStatusError = mysql.ErrNotSlave oldMaster.FakeMysqlDaemon.CurrentMasterPosition = newMaster.FakeMysqlDaemon.WaitMasterPosition oldMaster.FakeMysqlDaemon.SetMasterInput = topoproto.MysqlAddr(newMaster.Tablet) oldMaster.FakeMysqlDaemon.ExpectedExecuteSuperQueryList = []string{ "FAKE SET MASTER", "START SLAVE", + // we end up calling SetMaster twice on the old master + "FAKE SET MASTER", + "START SLAVE", } oldMaster.StartActionLoop(t, wr) defer oldMaster.StopActionLoop(t) oldMaster.Agent.QueryServiceControl.(*tabletservermock.Controller).SetQueryServiceEnabledForTests(true) + // SetMaster is called on new master to make sure it's replicating before reparenting. + newMaster.FakeMysqlDaemon.SetMasterInput = topoproto.MysqlAddr(oldMaster.Tablet) + // good slave 1 is replicating goodSlave1.FakeMysqlDaemon.ReadOnly = true goodSlave1.FakeMysqlDaemon.Replicating = true @@ -102,7 +112,7 @@ func TestPlannedReparentShardNoMasterProvided(t *testing.T) { t.Fatalf("PlannedReparentShard failed: %v", err) } - // // check what was run + // check what was run if err := newMaster.FakeMysqlDaemon.CheckSuperQueryList(); err != nil { t.Errorf("newMaster.FakeMysqlDaemon.CheckSuperQueryList failed: %v", err) } @@ -125,8 +135,8 @@ func TestPlannedReparentShardNoMasterProvided(t *testing.T) { t.Errorf("oldMaster...QueryServiceControl not serving") } - // // verify the old master was told to start replicating (and not - // // the slave that wasn't replicating in the first place) + // verify the old master was told to start replicating (and not + // the slave that wasn't replicating in the first place) if !oldMaster.FakeMysqlDaemon.Replicating { t.Errorf("oldMaster.FakeMysqlDaemon.Replicating not set") } @@ -171,6 +181,9 @@ func TestPlannedReparentShard(t *testing.T) { }, } newMaster.FakeMysqlDaemon.ExpectedExecuteSuperQueryList = []string{ + "STOP SLAVE", + "FAKE SET MASTER", + "START SLAVE", "CREATE DATABASE IF NOT EXISTS _vt", "SUBCREATE TABLE IF NOT EXISTS _vt.reparent_journal", "SUBINSERT INTO _vt.reparent_journal (time_created_ns, action_name, master_alias, replication_position) VALUES", @@ -181,16 +194,23 @@ func TestPlannedReparentShard(t *testing.T) { // old master oldMaster.FakeMysqlDaemon.ReadOnly = false oldMaster.FakeMysqlDaemon.Replicating = false + oldMaster.FakeMysqlDaemon.SlaveStatusError = mysql.ErrNotSlave oldMaster.FakeMysqlDaemon.CurrentMasterPosition = newMaster.FakeMysqlDaemon.WaitMasterPosition oldMaster.FakeMysqlDaemon.SetMasterInput = topoproto.MysqlAddr(newMaster.Tablet) oldMaster.FakeMysqlDaemon.ExpectedExecuteSuperQueryList = []string{ "FAKE SET MASTER", "START SLAVE", + // we end up calling SetMaster twice on the old master + "FAKE SET MASTER", + "START SLAVE", } oldMaster.StartActionLoop(t, wr) defer oldMaster.StopActionLoop(t) oldMaster.Agent.QueryServiceControl.(*tabletservermock.Controller).SetQueryServiceEnabledForTests(true) + // SetMaster is called on new master to make sure it's replicating before reparenting. + newMaster.FakeMysqlDaemon.SetMasterInput = topoproto.MysqlAddr(oldMaster.Tablet) + // good slave 1 is replicating goodSlave1.FakeMysqlDaemon.ReadOnly = true goodSlave1.FakeMysqlDaemon.Replicating = true @@ -366,7 +386,7 @@ func TestPlannedReparentShardPromoteSlaveFail(t *testing.T) { if err == nil { t.Fatalf("PlannedReparentShard succeeded: %v", err) } - if !strings.Contains(err.Error(), "master-elect tablet cell1-0000000001 failed to catch up with replication or be upgraded to master") { + if !strings.Contains(err.Error(), "replication on master-elect cell1-0000000001 did not catch up in time") { t.Fatalf("PlannedReparentShard failed with the wrong error: %v", err) } @@ -462,7 +482,7 @@ func TestPlannedReparentShardPromoteSlaveTimeout(t *testing.T) { if err == nil { t.Fatalf("PlannedReparentShard succeeded: %v", err) } - if !strings.Contains(err.Error(), "master-elect tablet cell1-0000000001 failed to catch up with replication or be upgraded to master") { + if !strings.Contains(err.Error(), "replication on master-elect cell1-0000000001 did not catch up in time") { t.Fatalf("PlannedReparentShard failed with the wrong error: %v", err) } diff --git a/go/vt/wrangler/testlib/reparent_external_test.go b/go/vt/wrangler/testlib/reparent_external_test.go deleted file mode 100644 index 153bb8d0a72..00000000000 --- a/go/vt/wrangler/testlib/reparent_external_test.go +++ /dev/null @@ -1,356 +0,0 @@ -/* -Copyright 2017 Google Inc. - -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 testlib - -import ( - "fmt" - "sync" - "testing" - "time" - - "golang.org/x/net/context" - - "vitess.io/vitess/go/event" - "vitess.io/vitess/go/vt/logutil" - "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/topotools" - "vitess.io/vitess/go/vt/topotools/events" - "vitess.io/vitess/go/vt/vttablet/tabletmanager" - "vitess.io/vitess/go/vt/vttablet/tmclient" - "vitess.io/vitess/go/vt/wrangler" - - topodatapb "vitess.io/vitess/go/vt/proto/topodata" -) - -func TestTabletExternallyReparented(t *testing.T) { - tabletmanager.SetReparentFlags(time.Minute /* finalizeTimeout */) - - ctx := context.Background() - ts := memorytopo.NewServer("cell1", "cell2") - wr := wrangler.New(logutil.NewConsoleLogger(), ts, tmclient.NewTabletManagerClient()) - vp := NewVtctlPipe(t, ts) - defer vp.Close() - - // Create an old master, a new master, two good slaves, one bad slave - oldMaster := NewFakeTablet(t, wr, "cell1", 0, topodatapb.TabletType_MASTER, nil) - newMaster := NewFakeTablet(t, wr, "cell1", 1, topodatapb.TabletType_REPLICA, nil) - goodSlave1 := NewFakeTablet(t, wr, "cell1", 2, topodatapb.TabletType_REPLICA, nil) - goodSlave2 := NewFakeTablet(t, wr, "cell2", 3, topodatapb.TabletType_REPLICA, nil) - badSlave := NewFakeTablet(t, wr, "cell1", 4, topodatapb.TabletType_REPLICA, nil) - - // Build keyspace graph - err := topotools.RebuildKeyspace(context.Background(), logutil.NewConsoleLogger(), ts, oldMaster.Tablet.Keyspace, []string{"cell1", "cell2"}) - if err != nil { - t.Fatalf("RebuildKeyspaceLocked failed: %v", err) - } - - // Slightly unrelated test: make sure we can find the tablets - // even with a datacenter being down. - tabletMap, err := ts.GetTabletMapForShardByCell(ctx, "test_keyspace", "0", []string{"cell1"}) - if err != nil { - t.Fatalf("GetTabletMapForShardByCell should have worked but got: %v", err) - } - master, err := topotools.FindTabletByHostAndPort(tabletMap, oldMaster.Tablet.Hostname, "vt", oldMaster.Tablet.PortMap["vt"]) - if err != nil || !topoproto.TabletAliasEqual(master, oldMaster.Tablet.Alias) { - t.Fatalf("FindTabletByHostAndPort(master) failed: %v %v", err, master) - } - slave1, err := topotools.FindTabletByHostAndPort(tabletMap, goodSlave1.Tablet.Hostname, "vt", goodSlave1.Tablet.PortMap["vt"]) - if err != nil || !topoproto.TabletAliasEqual(slave1, goodSlave1.Tablet.Alias) { - t.Fatalf("FindTabletByHostAndPort(slave1) failed: %v %v", err, master) - } - slave2, err := topotools.FindTabletByHostAndPort(tabletMap, goodSlave2.Tablet.Hostname, "vt", goodSlave2.Tablet.PortMap["vt"]) - if !topo.IsErrType(err, topo.NoNode) { - t.Fatalf("FindTabletByHostAndPort(slave2) worked: %v %v", err, slave2) - } - - // Make sure the master is not exported in other cells - tabletMap, _ = ts.GetTabletMapForShardByCell(ctx, "test_keyspace", "0", []string{"cell2"}) - master, err = topotools.FindTabletByHostAndPort(tabletMap, oldMaster.Tablet.Hostname, "vt", oldMaster.Tablet.PortMap["vt"]) - if !topo.IsErrType(err, topo.NoNode) { - t.Fatalf("FindTabletByHostAndPort(master) worked in cell2: %v %v", err, master) - } - - // Get tablet map for all cells. If there were to be failures talking to local cells, this will return the tablet map - // and forward a partial result error - tabletMap, err = ts.GetTabletMapForShard(ctx, "test_keyspace", "0") - if err != nil { - t.Fatalf("GetTabletMapForShard should nil but got: %v", err) - } - master, err = topotools.FindTabletByHostAndPort(tabletMap, oldMaster.Tablet.Hostname, "vt", oldMaster.Tablet.PortMap["vt"]) - if err != nil || !topoproto.TabletAliasEqual(master, oldMaster.Tablet.Alias) { - t.Fatalf("FindTabletByHostAndPort(master) failed: %v %v", err, master) - } - - // On the elected master, we will respond to - // TabletActionSlaveWasPromoted - newMaster.StartActionLoop(t, wr) - defer newMaster.StopActionLoop(t) - - // On the old master, we will only respond to - // TabletActionSlaveWasRestarted. - oldMaster.StartActionLoop(t, wr) - defer oldMaster.StopActionLoop(t) - - // On the good slaves, we will respond to - // TabletActionSlaveWasRestarted. - goodSlave1.StartActionLoop(t, wr) - defer goodSlave1.StopActionLoop(t) - - goodSlave2.StartActionLoop(t, wr) - defer goodSlave2.StopActionLoop(t) - - // On the bad slave, we will respond to - // TabletActionSlaveWasRestarted with bad data. - badSlave.StartActionLoop(t, wr) - defer badSlave.StopActionLoop(t) - - // First test: reparent to the same master, make sure it works - // as expected. - tmc := tmclient.NewTabletManagerClient() - _, err = ts.GetTablet(ctx, oldMaster.Tablet.Alias) - if err != nil { - t.Fatalf("GetTablet failed: %v", err) - } - if err := vp.Run([]string{"TabletExternallyReparented", topoproto.TabletAliasString(oldMaster.Tablet.Alias)}); err != nil { - t.Fatalf("TabletExternallyReparented(same master) should have worked: %v", err) - } - - // Second test: reparent to a replica, and pretend the old - // master is still good to go. - - // This tests a bad case: the new designated master is a slave, - // but we should do what we're told anyway. - ti, err := ts.GetTablet(ctx, goodSlave1.Tablet.Alias) - if err != nil { - t.Fatalf("GetTablet failed: %v", err) - } - waitID := makeWaitID() - if err := tmc.TabletExternallyReparented(context.Background(), ti.Tablet, waitID); err != nil { - t.Fatalf("TabletExternallyReparented(slave) error: %v", err) - } - waitForExternalReparent(t, "TestTabletExternallyReparented: slave designated as master", waitID) - - // This tests the good case, where everything works as planned - t.Logf("TabletExternallyReparented(new master) expecting success") - ti, err = ts.GetTablet(ctx, newMaster.Tablet.Alias) - if err != nil { - t.Fatalf("GetTablet failed: %v", err) - } - waitID = makeWaitID() - if err := tmc.TabletExternallyReparented(context.Background(), ti.Tablet, waitID); err != nil { - t.Fatalf("TabletExternallyReparented(replica) failed: %v", err) - } - waitForExternalReparent(t, "TestTabletExternallyReparented: good case", waitID) -} - -// TestTabletExternallyReparentedWithDifferentMysqlPort makes sure -// that if mysql is restarted on the master-elect tablet and has a different -// port, we pick it up correctly. -func TestTabletExternallyReparentedWithDifferentMysqlPort(t *testing.T) { - tabletmanager.SetReparentFlags(time.Minute /* finalizeTimeout */) - - ctx := context.Background() - ts := memorytopo.NewServer("cell1") - wr := wrangler.New(logutil.NewConsoleLogger(), ts, tmclient.NewTabletManagerClient()) - - // Create an old master, a new master, two good slaves, one bad slave - oldMaster := NewFakeTablet(t, wr, "cell1", 0, topodatapb.TabletType_MASTER, nil) - newMaster := NewFakeTablet(t, wr, "cell1", 1, topodatapb.TabletType_REPLICA, nil) - goodSlave := NewFakeTablet(t, wr, "cell1", 2, topodatapb.TabletType_REPLICA, nil) - - // Now we're restarting mysql on a different port, 3301->3303 - // but without updating the Tablet record in topology. - - // On the elected master, we will respond to - // TabletActionSlaveWasPromoted, so we need a MysqlDaemon - // that returns no master, and the new port (as returned by mysql) - newMaster.FakeMysqlDaemon.MysqlPort = 3303 - newMaster.StartActionLoop(t, wr) - defer newMaster.StopActionLoop(t) - - // On the old master, we will only respond to - // TabletActionSlaveWasRestarted and point to the new mysql port - oldMaster.StartActionLoop(t, wr) - defer oldMaster.StopActionLoop(t) - - // On the good slaves, we will respond to - // TabletActionSlaveWasRestarted and point to the new mysql port - goodSlave.StartActionLoop(t, wr) - defer goodSlave.StopActionLoop(t) - - // This tests the good case, where everything works as planned - t.Logf("TabletExternallyReparented(new master) expecting success") - tmc := tmclient.NewTabletManagerClient() - ti, err := ts.GetTablet(ctx, newMaster.Tablet.Alias) - if err != nil { - t.Fatalf("GetTablet failed: %v", err) - } - waitID := makeWaitID() - if err := tmc.TabletExternallyReparented(context.Background(), ti.Tablet, waitID); err != nil { - t.Fatalf("TabletExternallyReparented(replica) failed: %v", err) - } - waitForExternalReparent(t, "TestTabletExternallyReparentedWithDifferentMysqlPort: good case", waitID) -} - -// TestTabletExternallyReparentedContinueOnUnexpectedMaster makes sure -// that we ignore mysql's master if the flag is set -func TestTabletExternallyReparentedContinueOnUnexpectedMaster(t *testing.T) { - tabletmanager.SetReparentFlags(time.Minute /* finalizeTimeout */) - - ctx := context.Background() - ts := memorytopo.NewServer("cell1") - wr := wrangler.New(logutil.NewConsoleLogger(), ts, tmclient.NewTabletManagerClient()) - - // Create an old master, a new master, two good slaves, one bad slave - oldMaster := NewFakeTablet(t, wr, "cell1", 0, topodatapb.TabletType_MASTER, nil) - newMaster := NewFakeTablet(t, wr, "cell1", 1, topodatapb.TabletType_REPLICA, nil) - goodSlave := NewFakeTablet(t, wr, "cell1", 2, topodatapb.TabletType_REPLICA, nil) - - // On the elected master, we will respond to - // TabletActionSlaveWasPromoted, so we need a MysqlDaemon - // that returns no master, and the new port (as returned by mysql) - newMaster.StartActionLoop(t, wr) - defer newMaster.StopActionLoop(t) - - // On the old master, we will only respond to - // TabletActionSlaveWasRestarted and point to a bad host - oldMaster.StartActionLoop(t, wr) - defer oldMaster.StopActionLoop(t) - - // On the good slave, we will respond to - // TabletActionSlaveWasRestarted and point to a bad host - goodSlave.StartActionLoop(t, wr) - defer goodSlave.StopActionLoop(t) - - // This tests the good case, where everything works as planned - t.Logf("TabletExternallyReparented(new master) expecting success") - tmc := tmclient.NewTabletManagerClient() - ti, err := ts.GetTablet(ctx, newMaster.Tablet.Alias) - if err != nil { - t.Fatalf("GetTablet failed: %v", err) - } - waitID := makeWaitID() - if err := tmc.TabletExternallyReparented(context.Background(), ti.Tablet, waitID); err != nil { - t.Fatalf("TabletExternallyReparented(replica) failed: %v", err) - } - waitForExternalReparent(t, "TestTabletExternallyReparentedContinueOnUnexpectedMaster: good case", waitID) -} - -func TestTabletExternallyReparentedFailedOldMaster(t *testing.T) { - // The 'RefreshState' clal on the old master will timeout on - // this value, so it has to be smaller than the 10s of the - // wait for the 'finished' state of waitForExternalReparent. - tabletmanager.SetReparentFlags(2 * time.Second /* finalizeTimeout */) - - ctx := context.Background() - ts := memorytopo.NewServer("cell1", "cell2") - wr := wrangler.New(logutil.NewConsoleLogger(), ts, tmclient.NewTabletManagerClient()) - - // Create an old master, a new master, and a good slave. - oldMaster := NewFakeTablet(t, wr, "cell1", 0, topodatapb.TabletType_MASTER, nil) - newMaster := NewFakeTablet(t, wr, "cell1", 1, topodatapb.TabletType_REPLICA, nil) - goodSlave := NewFakeTablet(t, wr, "cell1", 2, topodatapb.TabletType_REPLICA, nil) - - // Reparent to a replica, and pretend the old master is not responding. - - // On the elected master, we will respond to - // TabletActionSlaveWasPromoted. - newMaster.StartActionLoop(t, wr) - defer newMaster.StopActionLoop(t) - - // On the old master, we will only get a RefreshState call, - // let's just not respond to it at all, and let it timeout. - - // On the good slave, we will respond to - // TabletActionSlaveWasRestarted. - goodSlave.StartActionLoop(t, wr) - defer goodSlave.StopActionLoop(t) - - // The reparent should work as expected here - tmc := tmclient.NewTabletManagerClient() - ti, err := ts.GetTablet(ctx, newMaster.Tablet.Alias) - if err != nil { - t.Fatalf("GetTablet failed: %v", err) - } - waitID := makeWaitID() - if err := tmc.TabletExternallyReparented(context.Background(), ti.Tablet, waitID); err != nil { - t.Fatalf("TabletExternallyReparented(replica) failed: %v", err) - } - waitForExternalReparent(t, "TestTabletExternallyReparentedFailedOldMaster: good case", waitID) - - // check the old master was converted to replica - tablet, err := ts.GetTablet(ctx, oldMaster.Tablet.Alias) - if err != nil { - t.Fatalf("GetTablet(%v) failed: %v", oldMaster.Tablet.Alias, err) - } - if tablet.Type != topodatapb.TabletType_REPLICA { - t.Fatalf("old master should be spare but is: %v", tablet.Type) - } -} - -var ( - externalReparents = make(map[string]chan struct{}) - externalReparentsMutex sync.Mutex -) - -// makeWaitID generates a unique externalID that can be passed to -// TabletExternallyReparented, and then to waitForExternalReparent. -func makeWaitID() string { - externalReparentsMutex.Lock() - id := fmt.Sprintf("wait id %v", len(externalReparents)) - externalReparents[id] = make(chan struct{}) - externalReparentsMutex.Unlock() - return id -} - -func init() { - event.AddListener(func(ev *events.Reparent) { - if ev.Status == "finished" { - externalReparentsMutex.Lock() - if c, ok := externalReparents[ev.ExternalID]; ok { - close(c) - } - externalReparentsMutex.Unlock() - } - }) -} - -// waitForExternalReparent waits up to a fixed duration for the external -// reparent with the given ID to finish. The ID must have been previously -// generated by makeWaitID(). -// -// The TabletExternallyReparented RPC returns as soon as the -// new master is visible in the serving graph. Before checking things like -// replica endpoints and old master status, we should wait for the finalize -// stage, which happens in the background. -func waitForExternalReparent(t *testing.T, name, externalID string) { - timer := time.NewTimer(10 * time.Second) - defer timer.Stop() - - externalReparentsMutex.Lock() - c := externalReparents[externalID] - externalReparentsMutex.Unlock() - - select { - case <-c: - return - case <-timer.C: - t.Fatalf("deadline exceeded waiting for finalized external reparent %q for test %v", externalID, name) - } -} diff --git a/go/vt/wrangler/testlib/reparent_utils_test.go b/go/vt/wrangler/testlib/reparent_utils_test.go index f78b8b3734f..109707c6a48 100644 --- a/go/vt/wrangler/testlib/reparent_utils_test.go +++ b/go/vt/wrangler/testlib/reparent_utils_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/wrangler/testlib/rpc_reparent_external_test.go b/go/vt/wrangler/testlib/rpc_reparent_external_test.go new file mode 100644 index 00000000000..3ee7651958d --- /dev/null +++ b/go/vt/wrangler/testlib/rpc_reparent_external_test.go @@ -0,0 +1,641 @@ +/* +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 testlib + +import ( + "fmt" + "sync" + "testing" + "time" + + "golang.org/x/net/context" + + "vitess.io/vitess/go/event" + "vitess.io/vitess/go/vt/logutil" + "vitess.io/vitess/go/vt/topo/memorytopo" + "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/vttablet/tabletmanager" + "vitess.io/vitess/go/vt/vttablet/tmclient" + "vitess.io/vitess/go/vt/wrangler" + + topodatapb "vitess.io/vitess/go/vt/proto/topodata" +) + +func TestRPCTabletExternallyReparented(t *testing.T) { + tabletmanager.SetReparentFlags(time.Minute /* finalizeTimeout */) + + ctx := context.Background() + ts := memorytopo.NewServer("cell1", "cell2") + wr := wrangler.New(logutil.NewConsoleLogger(), ts, tmclient.NewTabletManagerClient()) + + // Create an old master and a new master + oldMaster := NewFakeTablet(t, wr, "cell1", 0, topodatapb.TabletType_MASTER, nil) + newMaster := NewFakeTablet(t, wr, "cell2", 1, topodatapb.TabletType_REPLICA, nil) + + // Build keyspace graph + err := topotools.RebuildKeyspace(context.Background(), logutil.NewConsoleLogger(), ts, oldMaster.Tablet.Keyspace, []string{"cell1", "cell2"}) + if err != nil { + t.Fatalf("RebuildKeyspaceLocked failed: %v", err) + } + + // On the elected master, we will respond to + // TabletActionSlaveWasPromoted + newMaster.StartActionLoop(t, wr) + defer newMaster.StopActionLoop(t) + + oldMaster.FakeMysqlDaemon.SetMasterInput = topoproto.MysqlAddr(newMaster.Tablet) + oldMaster.FakeMysqlDaemon.ExpectedExecuteSuperQueryList = []string{ + "FAKE SET MASTER", + "START SLAVE", + } + // On the old master, we will only respond to + // TabletActionSlaveWasRestarted. + oldMaster.StartActionLoop(t, wr) + defer oldMaster.StopActionLoop(t) + + // First test: reparent to the same master, make sure it works + // as expected. + tmc := tmclient.NewTabletManagerClient() + _, err = ts.GetTablet(ctx, oldMaster.Tablet.Alias) + if err != nil { + t.Fatalf("GetTablet failed: %v", err) + } + waitID := makeWaitID() + if err := tmc.TabletExternallyReparented(context.Background(), oldMaster.Tablet, waitID); err != nil { + t.Fatalf("TabletExternallyReparented(same master) should have worked: %v", err) + } + waitForExternalReparent(t, "TestRPCTabletExternallyReparented: same master", waitID) + + // This tests the good case, where everything works as planned + t.Logf("TabletExternallyReparented(new master) expecting success") + ti, err := ts.GetTablet(ctx, newMaster.Tablet.Alias) + if err != nil { + t.Fatalf("GetTablet failed: %v", err) + } + waitID = makeWaitID() + if err := tmc.TabletExternallyReparented(context.Background(), ti.Tablet, waitID); err != nil { + t.Fatalf("TabletExternallyReparented(replica) failed: %v", err) + } + waitForExternalReparent(t, "TestRPCTabletExternallyReparented: good case", waitID) +} + +func TestRPCTabletExternallyReparentedSlaveMysql(t *testing.T) { + tabletmanager.SetReparentFlags(time.Minute /* finalizeTimeout */) + + ctx := context.Background() + ts := memorytopo.NewServer("cell1", "cell2") + wr := wrangler.New(logutil.NewConsoleLogger(), ts, tmclient.NewTabletManagerClient()) + + // Create an old master, a new master, two good slaves, one bad slave + oldMaster := NewFakeTablet(t, wr, "cell1", 0, topodatapb.TabletType_MASTER, nil) + newMaster := NewFakeTablet(t, wr, "cell2", 1, topodatapb.TabletType_REPLICA, nil) + newMaster.FakeMysqlDaemon.ReadOnly = true + newMaster.FakeMysqlDaemon.Replicating = true + + // Build keyspace graph + err := topotools.RebuildKeyspace(context.Background(), logutil.NewConsoleLogger(), ts, oldMaster.Tablet.Keyspace, []string{"cell1", "cell2"}) + if err != nil { + t.Fatalf("RebuildKeyspaceLocked failed: %v", err) + } + + // On the elected master, we will respond to + // TabletActionSlaveWasPromoted + newMaster.StartActionLoop(t, wr) + defer newMaster.StopActionLoop(t) + + oldMaster.FakeMysqlDaemon.SetMasterInput = topoproto.MysqlAddr(newMaster.Tablet) + oldMaster.FakeMysqlDaemon.ExpectedExecuteSuperQueryList = []string{ + "FAKE SET MASTER", + "START SLAVE", + } + // On the old master, we will only respond to + // TabletActionSlaveWasRestarted. + oldMaster.StartActionLoop(t, wr) + defer oldMaster.StopActionLoop(t) + + // This tests a bad case: the new designated master is a slave, + // but we should do what we're told anyway. + tmc := tmclient.NewTabletManagerClient() + ti, err := ts.GetTablet(ctx, newMaster.Tablet.Alias) + if err != nil { + t.Fatalf("GetTablet failed: %v", err) + } + waitID := makeWaitID() + if err := tmc.TabletExternallyReparented(context.Background(), ti.Tablet, waitID); err != nil { + t.Fatalf("TabletExternallyReparented(slave) error: %v", err) + } + waitForExternalReparent(t, "TestRPCTabletExternallyReparented: slave designated as master", waitID) + +} + +// TestRPCTabletExternallyReparentedWithDifferentMysqlPort makes sure +// that if mysql is restarted on the master-elect tablet and has a different +// port, we pick it up correctly. +func TestRPCTabletExternallyReparentedWithDifferentMysqlPort(t *testing.T) { + tabletmanager.SetReparentFlags(time.Minute /* finalizeTimeout */) + + ctx := context.Background() + ts := memorytopo.NewServer("cell1") + wr := wrangler.New(logutil.NewConsoleLogger(), ts, tmclient.NewTabletManagerClient()) + + // Create an old master, a new master, two good slaves, one bad slave + oldMaster := NewFakeTablet(t, wr, "cell1", 0, topodatapb.TabletType_MASTER, nil) + newMaster := NewFakeTablet(t, wr, "cell1", 1, topodatapb.TabletType_REPLICA, nil) + goodSlave := NewFakeTablet(t, wr, "cell1", 2, topodatapb.TabletType_REPLICA, nil) + + // Build keyspace graph + err := topotools.RebuildKeyspace(context.Background(), logutil.NewConsoleLogger(), ts, oldMaster.Tablet.Keyspace, []string{"cell1"}) + if err != nil { + t.Fatalf("RebuildKeyspaceLocked failed: %v", err) + } + // Now we're restarting mysql on a different port, 3301->3303 + // but without updating the Tablet record in topology. + + // On the elected master, we will respond to + // TabletActionSlaveWasPromoted, so we need a MysqlDaemon + // that returns no master, and the new port (as returned by mysql) + newMaster.FakeMysqlDaemon.MysqlPort = 3303 + newMaster.StartActionLoop(t, wr) + defer newMaster.StopActionLoop(t) + + oldMaster.FakeMysqlDaemon.SetMasterInput = topoproto.MysqlAddr(newMaster.Tablet) + oldMaster.FakeMysqlDaemon.ExpectedExecuteSuperQueryList = []string{ + "FAKE SET MASTER", + "START SLAVE", + } + // On the old master, we will only respond to + // TabletActionSlaveWasRestarted and point to the new mysql port + oldMaster.StartActionLoop(t, wr) + defer oldMaster.StopActionLoop(t) + + // On the good slaves, we will respond to + // TabletActionSlaveWasRestarted and point to the new mysql port + goodSlave.StartActionLoop(t, wr) + defer goodSlave.StopActionLoop(t) + + // This tests the good case, where everything works as planned + t.Logf("TabletExternallyReparented(new master) expecting success") + tmc := tmclient.NewTabletManagerClient() + ti, err := ts.GetTablet(ctx, newMaster.Tablet.Alias) + if err != nil { + t.Fatalf("GetTablet failed: %v", err) + } + waitID := makeWaitID() + if err := tmc.TabletExternallyReparented(context.Background(), ti.Tablet, waitID); err != nil { + t.Fatalf("TabletExternallyReparented(replica) failed: %v", err) + } + waitForExternalReparent(t, "TestRPCTabletExternallyReparentedWithDifferentMysqlPort: good case", waitID) +} + +// TestRPCTabletExternallyReparentedContinueOnUnexpectedMaster makes sure +// that we ignore mysql's master if the flag is set +func TestRPCTabletExternallyReparentedContinueOnUnexpectedMaster(t *testing.T) { + tabletmanager.SetReparentFlags(time.Minute /* finalizeTimeout */) + + ctx := context.Background() + ts := memorytopo.NewServer("cell1") + wr := wrangler.New(logutil.NewConsoleLogger(), ts, tmclient.NewTabletManagerClient()) + + // Create an old master, a new master, two good slaves, one bad slave + oldMaster := NewFakeTablet(t, wr, "cell1", 0, topodatapb.TabletType_MASTER, nil) + newMaster := NewFakeTablet(t, wr, "cell1", 1, topodatapb.TabletType_REPLICA, nil) + goodSlave := NewFakeTablet(t, wr, "cell1", 2, topodatapb.TabletType_REPLICA, nil) + + // Build keyspace graph + err := topotools.RebuildKeyspace(context.Background(), logutil.NewConsoleLogger(), ts, oldMaster.Tablet.Keyspace, []string{"cell1"}) + if err != nil { + t.Fatalf("RebuildKeyspaceLocked failed: %v", err) + } + // On the elected master, we will respond to + // TabletActionSlaveWasPromoted, so we need a MysqlDaemon + // that returns no master, and the new port (as returned by mysql) + newMaster.StartActionLoop(t, wr) + defer newMaster.StopActionLoop(t) + + oldMaster.FakeMysqlDaemon.SetMasterInput = topoproto.MysqlAddr(newMaster.Tablet) + oldMaster.FakeMysqlDaemon.ExpectedExecuteSuperQueryList = []string{ + "FAKE SET MASTER", + "START SLAVE", + } + // On the old master, we will only respond to + // TabletActionSlaveWasRestarted and point to a bad host + oldMaster.StartActionLoop(t, wr) + defer oldMaster.StopActionLoop(t) + + // On the good slave, we will respond to + // TabletActionSlaveWasRestarted and point to a bad host + goodSlave.StartActionLoop(t, wr) + defer goodSlave.StopActionLoop(t) + + // This tests the good case, where everything works as planned + t.Logf("TabletExternallyReparented(new master) expecting success") + tmc := tmclient.NewTabletManagerClient() + ti, err := ts.GetTablet(ctx, newMaster.Tablet.Alias) + if err != nil { + t.Fatalf("GetTablet failed: %v", err) + } + waitID := makeWaitID() + if err := tmc.TabletExternallyReparented(context.Background(), ti.Tablet, waitID); err != nil { + t.Fatalf("TabletExternallyReparented(replica) failed: %v", err) + } + waitForExternalReparent(t, "TestRPCTabletExternallyReparentedContinueOnUnexpectedMaster: good case", waitID) +} + +func TestRPCTabletExternallyReparentedFailedOldMaster(t *testing.T) { + // The 'RefreshState' call on the old master will timeout on + // this value, so it has to be smaller than the 10s of the + // wait for the 'finished' state of waitForExternalReparent. + tabletmanager.SetReparentFlags(2 * time.Second /* finalizeTimeout */) + + ctx := context.Background() + ts := memorytopo.NewServer("cell1", "cell2") + wr := wrangler.New(logutil.NewConsoleLogger(), ts, tmclient.NewTabletManagerClient()) + + // Create an old master, a new master, and a good slave. + oldMaster := NewFakeTablet(t, wr, "cell1", 0, topodatapb.TabletType_MASTER, nil) + newMaster := NewFakeTablet(t, wr, "cell1", 1, topodatapb.TabletType_REPLICA, nil) + goodSlave := NewFakeTablet(t, wr, "cell1", 2, topodatapb.TabletType_REPLICA, nil) + + // Build keyspace graph + err := topotools.RebuildKeyspace(context.Background(), logutil.NewConsoleLogger(), ts, oldMaster.Tablet.Keyspace, []string{"cell1"}) + if err != nil { + t.Fatalf("RebuildKeyspaceLocked failed: %v", err) + } + // Reparent to a replica, and pretend the old master is not responding. + + // On the elected master, we will respond to + // TabletActionSlaveWasPromoted. + newMaster.StartActionLoop(t, wr) + defer newMaster.StopActionLoop(t) + + // On the old master, we will only get a RefreshState call, + // let's just not respond to it at all, and let it timeout. + oldMaster.FakeMysqlDaemon.SetMasterInput = topoproto.MysqlAddr(newMaster.Tablet) + oldMaster.FakeMysqlDaemon.ExpectedExecuteSuperQueryList = []string{ + "FAKE SET MASTER", + "START SLAVE", + } + + // On the good slave, we will respond to + // TabletActionSlaveWasRestarted. + goodSlave.StartActionLoop(t, wr) + defer goodSlave.StopActionLoop(t) + + // The reparent should work as expected here + tmc := tmclient.NewTabletManagerClient() + ti, err := ts.GetTablet(ctx, newMaster.Tablet.Alias) + if err != nil { + t.Fatalf("GetTablet failed: %v", err) + } + waitID := makeWaitID() + if err := tmc.TabletExternallyReparented(context.Background(), ti.Tablet, waitID); err != nil { + t.Fatalf("TabletExternallyReparented(replica) failed: %v", err) + } + waitForExternalReparent(t, "TestRPCTabletExternallyReparentedFailedOldMaster: good case", waitID) + + // check the old master was converted to replica + tablet, err := ts.GetTablet(ctx, oldMaster.Tablet.Alias) + if err != nil { + t.Fatalf("GetTablet(%v) failed: %v", oldMaster.Tablet.Alias, err) + } + if tablet.Type != topodatapb.TabletType_REPLICA { + t.Fatalf("old master should be replica but is: %v", tablet.Type) + } +} + +func TestRPCTabletExternallyReparentedImpostorMaster(t *testing.T) { + tabletmanager.SetReparentFlags(time.Minute /* finalizeTimeout */) + + ctx := context.Background() + ts := memorytopo.NewServer("cell1", "cell2") + wr := wrangler.New(logutil.NewConsoleLogger(), ts, tmclient.NewTabletManagerClient()) + + // Create an old master, a new master, and a bad slave. + badSlave := NewFakeTablet(t, wr, "cell1", 2, topodatapb.TabletType_MASTER, nil) + // do this after badSlave so that the shard record has the expected master + oldMaster := NewFakeTablet(t, wr, "cell1", 0, topodatapb.TabletType_MASTER, nil, ForceInitTablet()) + newMaster := NewFakeTablet(t, wr, "cell1", 1, topodatapb.TabletType_REPLICA, nil) + + // Build keyspace graph + err := topotools.RebuildKeyspace(context.Background(), logutil.NewConsoleLogger(), ts, oldMaster.Tablet.Keyspace, []string{"cell1"}) + if err != nil { + t.Fatalf("RebuildKeyspaceLocked failed: %v", err) + } + // check the old master is really master + tablet, err := ts.GetTablet(ctx, oldMaster.Tablet.Alias) + if err != nil { + t.Fatalf("GetTablet(%v) failed: %v", oldMaster.Tablet.Alias, err) + } + if tablet.Type != topodatapb.TabletType_MASTER { + t.Fatalf("old master should be MASTER but is: %v", tablet.Type) + } + + // check the impostor also claims to be master + tablet, err = ts.GetTablet(ctx, badSlave.Tablet.Alias) + if err != nil { + t.Fatalf("GetTablet(%v) failed: %v", badSlave.Tablet.Alias, err) + } + if tablet.Type != topodatapb.TabletType_MASTER { + t.Fatalf("impostor should be MASTER but is: %v", tablet.Type) + } + + // On the elected master, we will respond to + // TabletActionSlaveWasPromoted. + newMaster.StartActionLoop(t, wr) + defer newMaster.StopActionLoop(t) + + oldMaster.FakeMysqlDaemon.SetMasterInput = topoproto.MysqlAddr(newMaster.Tablet) + oldMaster.FakeMysqlDaemon.ExpectedExecuteSuperQueryList = []string{ + "FAKE SET MASTER", + "START SLAVE", + } + // On the old master, we will only respond to + // TabletActionSlaveWasRestarted. + oldMaster.StartActionLoop(t, wr) + defer oldMaster.StopActionLoop(t) + + // set this to old master because as soon as badSlave starts, it detects that + // there is a master with a later timestamp and demotes itself + badSlave.FakeMysqlDaemon.SetMasterInput = topoproto.MysqlAddr(oldMaster.Tablet) + badSlave.FakeMysqlDaemon.ExpectedExecuteSuperQueryList = []string{ + "FAKE SET MASTER", + "START SLAVE", + } + // On the bad slave, we will respond to + // TabletActionSlaveWasRestarted. + badSlave.StartActionLoop(t, wr) + defer badSlave.StopActionLoop(t) + + // The reparent should work as expected here + tmc := tmclient.NewTabletManagerClient() + ti, err := ts.GetTablet(ctx, newMaster.Tablet.Alias) + if err != nil { + t.Fatalf("GetTablet failed: %v", err) + } + waitID := makeWaitID() + if err := tmc.TabletExternallyReparented(context.Background(), ti.Tablet, waitID); err != nil { + t.Fatalf("TabletExternallyReparented(replica) failed: %v", err) + } + waitForExternalReparent(t, "TestRPCTabletExternallyReparentedImpostorMaster: good case", waitID) + + // check the new master is really master + tablet, err = ts.GetTablet(ctx, newMaster.Tablet.Alias) + if err != nil { + t.Fatalf("GetTablet(%v) failed: %v", newMaster.Tablet.Alias, err) + } + if tablet.Type != topodatapb.TabletType_MASTER { + t.Fatalf("new master should be MASTER but is: %v", tablet.Type) + } + + // check the old master was converted to replica + tablet, err = ts.GetTablet(ctx, oldMaster.Tablet.Alias) + if err != nil { + t.Fatalf("GetTablet(%v) failed: %v", oldMaster.Tablet.Alias, err) + } + if tablet.Type != topodatapb.TabletType_REPLICA { + t.Fatalf("old master should be replica but is: %v", tablet.Type) + } + + // check the impostor master was converted to replica + tablet, err = ts.GetTablet(ctx, badSlave.Tablet.Alias) + if err != nil { + t.Fatalf("GetTablet(%v) failed: %v", badSlave.Tablet.Alias, err) + } + if tablet.Type != topodatapb.TabletType_REPLICA { + t.Fatalf("bad slave should be replica but is: %v", tablet.Type) + } +} + +func TestRPCTabletExternallyReparentedFailedImpostorMaster(t *testing.T) { + tabletmanager.SetReparentFlags(2 * time.Second /* finalizeTimeout */) + + ctx := context.Background() + ts := memorytopo.NewServer("cell1", "cell2") + wr := wrangler.New(logutil.NewConsoleLogger(), ts, tmclient.NewTabletManagerClient()) + + // Create an old master, a new master, and a bad slave. + badSlave := NewFakeTablet(t, wr, "cell1", 2, topodatapb.TabletType_MASTER, nil) + // do this after badSlave so that the shard record has the expected master + oldMaster := NewFakeTablet(t, wr, "cell1", 0, topodatapb.TabletType_MASTER, nil, ForceInitTablet()) + newMaster := NewFakeTablet(t, wr, "cell1", 1, topodatapb.TabletType_REPLICA, nil) + + // Build keyspace graph + err := topotools.RebuildKeyspace(context.Background(), logutil.NewConsoleLogger(), ts, oldMaster.Tablet.Keyspace, []string{"cell1"}) + if err != nil { + t.Fatalf("RebuildKeyspaceLocked failed: %v", err) + } + // check the old master is really master + tablet, err := ts.GetTablet(ctx, oldMaster.Tablet.Alias) + if err != nil { + t.Fatalf("GetTablet(%v) failed: %v", oldMaster.Tablet.Alias, err) + } + if tablet.Type != topodatapb.TabletType_MASTER { + t.Fatalf("old master should be MASTER but is: %v", tablet.Type) + } + + // check the impostor also claims to be master + tablet, err = ts.GetTablet(ctx, badSlave.Tablet.Alias) + if err != nil { + t.Fatalf("GetTablet(%v) failed: %v", badSlave.Tablet.Alias, err) + } + if tablet.Type != topodatapb.TabletType_MASTER { + t.Fatalf("old master should be MASTER but is: %v", tablet.Type) + } + + // On the elected master, we will respond to + // TabletActionSlaveWasPromoted. + newMaster.StartActionLoop(t, wr) + defer newMaster.StopActionLoop(t) + + oldMaster.FakeMysqlDaemon.SetMasterInput = topoproto.MysqlAddr(newMaster.Tablet) + oldMaster.FakeMysqlDaemon.ExpectedExecuteSuperQueryList = []string{ + "FAKE SET MASTER", + "START SLAVE", + } + // On the old master, we will only respond to + // TabletActionSlaveWasRestarted. + oldMaster.StartActionLoop(t, wr) + defer oldMaster.StopActionLoop(t) + + // The reparent should work as expected here + tmc := tmclient.NewTabletManagerClient() + ti, err := ts.GetTablet(ctx, newMaster.Tablet.Alias) + if err != nil { + t.Fatalf("GetTablet failed: %v", err) + } + waitID := makeWaitID() + if err := tmc.TabletExternallyReparented(context.Background(), ti.Tablet, waitID); err != nil { + t.Fatalf("TabletExternallyReparented(replica) failed: %v", err) + } + waitForExternalReparent(t, "TestRPCTabletExternallyReparentedImpostorMaster: good case", waitID) + + // check the new master is really master + tablet, err = ts.GetTablet(ctx, newMaster.Tablet.Alias) + if err != nil { + t.Fatalf("GetTablet(%v) failed: %v", newMaster.Tablet.Alias, err) + } + if tablet.Type != topodatapb.TabletType_MASTER { + t.Fatalf("new master should be MASTER but is: %v", tablet.Type) + } + + // check the old master was converted to replica + tablet, err = ts.GetTablet(ctx, oldMaster.Tablet.Alias) + if err != nil { + t.Fatalf("GetTablet(%v) failed: %v", oldMaster.Tablet.Alias, err) + } + if tablet.Type != topodatapb.TabletType_REPLICA { + t.Fatalf("old master should be replica but is: %v", tablet.Type) + } + + // check the impostor master was converted to replica + tablet, err = ts.GetTablet(ctx, badSlave.Tablet.Alias) + if err != nil { + t.Fatalf("GetTablet(%v) failed: %v", badSlave.Tablet.Alias, err) + } + if tablet.Type != topodatapb.TabletType_REPLICA { + t.Fatalf("bad slave should be replica but is: %v", tablet.Type) + } +} + +func TestRPCTabletExternallyReparentedRerun(t *testing.T) { + tabletmanager.SetReparentFlags(time.Minute /* finalizeTimeout */) + + ctx := context.Background() + ts := memorytopo.NewServer("cell1", "cell2") + wr := wrangler.New(logutil.NewConsoleLogger(), ts, tmclient.NewTabletManagerClient()) + + // Create an old master, a new master, and a good slave. + oldMaster := NewFakeTablet(t, wr, "cell1", 0, topodatapb.TabletType_MASTER, nil) + newMaster := NewFakeTablet(t, wr, "cell1", 1, topodatapb.TabletType_REPLICA, nil) + goodSlave := NewFakeTablet(t, wr, "cell1", 2, topodatapb.TabletType_REPLICA, nil) + + // Build keyspace graph + err := topotools.RebuildKeyspace(context.Background(), logutil.NewConsoleLogger(), ts, oldMaster.Tablet.Keyspace, []string{"cell1"}) + if err != nil { + t.Fatalf("RebuildKeyspaceLocked failed: %v", err) + } + // On the elected master, we will respond to + // TabletActionSlaveWasPromoted. + newMaster.StartActionLoop(t, wr) + defer newMaster.StopActionLoop(t) + + oldMaster.FakeMysqlDaemon.SetMasterInput = topoproto.MysqlAddr(newMaster.Tablet) + oldMaster.FakeMysqlDaemon.ExpectedExecuteSuperQueryList = []string{ + "FAKE SET MASTER", + "START SLAVE", + } + // On the old master, we will only respond to + // TabletActionSlaveWasRestarted. + oldMaster.StartActionLoop(t, wr) + defer oldMaster.StopActionLoop(t) + + // On the good slave, we will respond to + // TabletActionSlaveWasRestarted. + goodSlave.StartActionLoop(t, wr) + defer goodSlave.StopActionLoop(t) + + // The reparent should work as expected here + tmc := tmclient.NewTabletManagerClient() + ti, err := ts.GetTablet(ctx, newMaster.Tablet.Alias) + if err != nil { + t.Fatalf("GetTablet failed: %v", err) + } + waitID := makeWaitID() + if err := tmc.TabletExternallyReparented(context.Background(), ti.Tablet, waitID); err != nil { + t.Fatalf("TabletExternallyReparented(replica) failed: %v", err) + } + waitForExternalReparent(t, "TestRPCTabletExternallyReparentedFailedOldMaster: good case", waitID) + + // check the old master was converted to replica + tablet, err := ts.GetTablet(ctx, oldMaster.Tablet.Alias) + if err != nil { + t.Fatalf("GetTablet(%v) failed: %v", oldMaster.Tablet.Alias, err) + } + if tablet.Type != topodatapb.TabletType_REPLICA { + t.Fatalf("old master should be replica but is: %v", tablet.Type) + } + + // run TER again and make sure the master is still correct + waitID = makeWaitID() + if err := tmc.TabletExternallyReparented(context.Background(), ti.Tablet, waitID); err != nil { + t.Fatalf("TabletExternallyReparented(replica) failed: %v", err) + } + waitForExternalReparent(t, "TestRPCTabletExternallyReparentedFailedOldMaster: good case", waitID) + + // check the new master is still master + tablet, err = ts.GetTablet(ctx, newMaster.Tablet.Alias) + if err != nil { + t.Fatalf("GetTablet(%v) failed: %v", newMaster.Tablet.Alias, err) + } + if tablet.Type != topodatapb.TabletType_MASTER { + t.Fatalf("new master should be MASTER but is: %v", tablet.Type) + } + +} + +var ( + externalReparents = make(map[string]chan struct{}) + externalReparentsMutex sync.Mutex +) + +// makeWaitID generates a unique externalID that can be passed to +// TabletExternallyReparented, and then to waitForExternalReparent. +func makeWaitID() string { + externalReparentsMutex.Lock() + id := fmt.Sprintf("wait id %v", len(externalReparents)) + externalReparents[id] = make(chan struct{}) + externalReparentsMutex.Unlock() + return id +} + +func init() { + event.AddListener(func(ev *events.Reparent) { + if ev.Status == "finished" { + externalReparentsMutex.Lock() + if c, ok := externalReparents[ev.ExternalID]; ok { + close(c) + } + externalReparentsMutex.Unlock() + } + }) +} + +// waitForExternalReparent waits up to a fixed duration for the external +// reparent with the given ID to finish. The ID must have been previously +// generated by makeWaitID(). +// +// The TabletExternallyReparented RPC returns as soon as the +// new master is visible in the serving graph. Before checking things like +// replica endpoints and old master status, we should wait for the finalize +// stage, which happens in the background. +func waitForExternalReparent(t *testing.T, name, externalID string) { + timer := time.NewTimer(10 * time.Second) + defer timer.Stop() + + externalReparentsMutex.Lock() + c := externalReparents[externalID] + externalReparentsMutex.Unlock() + + select { + case <-c: + return + case <-timer.C: + t.Fatalf("deadline exceeded waiting for finalized external reparent %q for test %v", externalID, name) + } +} diff --git a/go/vt/wrangler/testlib/semi_sync_test.go b/go/vt/wrangler/testlib/semi_sync_test.go index 789797acf78..d668bac160c 100644 --- a/go/vt/wrangler/testlib/semi_sync_test.go +++ b/go/vt/wrangler/testlib/semi_sync_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/wrangler/testlib/shard_test.go b/go/vt/wrangler/testlib/shard_test.go index 449382e85a1..778c61bd4b6 100644 --- a/go/vt/wrangler/testlib/shard_test.go +++ b/go/vt/wrangler/testlib/shard_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/wrangler/testlib/throttler_test.go b/go/vt/wrangler/testlib/throttler_test.go index 0c94403ca4a..0bcc2c11ed2 100644 --- a/go/vt/wrangler/testlib/throttler_test.go +++ b/go/vt/wrangler/testlib/throttler_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/wrangler/testlib/version_test.go b/go/vt/wrangler/testlib/version_test.go index c8a2efe07b3..184bd04f621 100644 --- a/go/vt/wrangler/testlib/version_test.go +++ b/go/vt/wrangler/testlib/version_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/wrangler/testlib/vtctl_pipe.go b/go/vt/wrangler/testlib/vtctl_pipe.go index 2e0ef8c1585..88c6236def9 100644 --- a/go/vt/wrangler/testlib/vtctl_pipe.go +++ b/go/vt/wrangler/testlib/vtctl_pipe.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/wrangler/testlib/vtctl_topo_test.go b/go/vt/wrangler/testlib/vtctl_topo_test.go index 42697668714..96252ff3411 100644 --- a/go/vt/wrangler/testlib/vtctl_topo_test.go +++ b/go/vt/wrangler/testlib/vtctl_topo_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/wrangler/testlib/wait_for_drain_test.go b/go/vt/wrangler/testlib/wait_for_drain_test.go index f5e75b8ae00..f5da3b2b4b3 100644 --- a/go/vt/wrangler/testlib/wait_for_drain_test.go +++ b/go/vt/wrangler/testlib/wait_for_drain_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/wrangler/validator.go b/go/vt/wrangler/validator.go index 9d0a21bee1b..375d63bafc5 100644 --- a/go/vt/wrangler/validator.go +++ b/go/vt/wrangler/validator.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/wrangler/validator_test.go b/go/vt/wrangler/validator_test.go index 81bb39066cc..de0bdcd5f04 100644 --- a/go/vt/wrangler/validator_test.go +++ b/go/vt/wrangler/validator_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/wrangler/vdiff.go b/go/vt/wrangler/vdiff.go new file mode 100644 index 00000000000..7b85ed2c653 --- /dev/null +++ b/go/vt/wrangler/vdiff.go @@ -0,0 +1,858 @@ +/* +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 wrangler + +import ( + "fmt" + "strings" + "sync" + "time" + + "github.com/golang/protobuf/proto" + "golang.org/x/net/context" + "vitess.io/vitess/go/mysql" + "vitess.io/vitess/go/sqltypes" + "vitess.io/vitess/go/vt/concurrency" + "vitess.io/vitess/go/vt/discovery" + "vitess.io/vitess/go/vt/grpcclient" + "vitess.io/vitess/go/vt/key" + binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" + querypb "vitess.io/vitess/go/vt/proto/query" + tabletmanagerdatapb "vitess.io/vitess/go/vt/proto/tabletmanagerdata" + topodatapb "vitess.io/vitess/go/vt/proto/topodata" + "vitess.io/vitess/go/vt/sqlparser" + "vitess.io/vitess/go/vt/srvtopo" + "vitess.io/vitess/go/vt/topo" + "vitess.io/vitess/go/vt/topo/topoproto" + "vitess.io/vitess/go/vt/vterrors" + "vitess.io/vitess/go/vt/vtgate/engine" + "vitess.io/vitess/go/vt/vttablet/tabletconn" + "vitess.io/vitess/go/vt/vttablet/tabletmanager/vreplication" +) + +// DiffReport is the summary of differences for one table. +type DiffReport struct { + ProcessedRows int + MatchingRows int + MismatchedRows int + ExtraRowsSource int + ExtraRowsTarget int +} + +type vdiff struct { + mi *migrater + sourceCell string + targetCell string + tabletTypesStr string + differs map[string]*tableDiffer + sources map[string]*dfParams + targets map[string]*dfParams +} + +type tableDiffer struct { + targetTable string + sourceExpression string + targetExpression string + compareCols []int + comparePKs []int + sourcePrimitive engine.Primitive + targetPrimitive engine.Primitive +} + +type dfParams struct { + master *topo.TabletInfo + tablet *topodatapb.Tablet + position mysql.Position + snapshotPosition string + result chan *sqltypes.Result + err error +} + +// VDiff reports differences between the sources and targets of a vreplication workflow. +func (wr *Wrangler) VDiff(ctx context.Context, targetKeyspace, workflow, sourceCell, targetCell, tabletTypesStr string, + filteredReplicationWaitTime, healthcheckTopologyRefresh, healthcheckRetryDelay, healthcheckTimeout time.Duration) (map[string]*DiffReport, error) { + if sourceCell == "" && targetCell == "" { + cells, err := wr.ts.GetCellInfoNames(ctx) + if err != nil { + return nil, err + } + if len(cells) == 0 { + // Unreachable + return nil, fmt.Errorf("there are no cells in the topo") + } + sourceCell = cells[0] + targetCell = sourceCell + } + if sourceCell == "" { + sourceCell = targetCell + } + if targetCell == "" { + targetCell = sourceCell + } + mi, err := wr.buildMigrater(ctx, targetKeyspace, workflow) + if err != nil { + wr.Logger().Errorf("buildMigrater: %v", err) + return nil, err + } + if err := mi.validate(ctx, false /* isWrite */); err != nil { + mi.wr.Logger().Errorf("validate: %v", err) + return nil, err + } + df := &vdiff{ + mi: mi, + sourceCell: sourceCell, + targetCell: targetCell, + tabletTypesStr: tabletTypesStr, + sources: make(map[string]*dfParams), + targets: make(map[string]*dfParams), + } + for shard, source := range mi.sources { + df.sources[shard] = &dfParams{ + master: source.master, + } + } + var oneTarget *miTarget + for shard, target := range mi.targets { + df.targets[shard] = &dfParams{ + master: target.master, + } + oneTarget = target + } + var oneFilter *binlogdatapb.Filter + for _, bls := range oneTarget.sources { + oneFilter = bls.Filter + break + } + schm, err := wr.GetSchema(ctx, oneTarget.master.Alias, nil, nil, false) + if err != nil { + return nil, vterrors.Wrap(err, "GetSchema") + } + df.differs, err = buildVDiffPlan(ctx, oneFilter, schm) + if err != nil { + return nil, vterrors.Wrap(err, "buildVDiffPlan") + } + if err := df.selectTablets(ctx, healthcheckTopologyRefresh, healthcheckRetryDelay, healthcheckTimeout); err != nil { + return nil, vterrors.Wrap(err, "selectTablets") + } + defer func(ctx context.Context) { + if err := df.restartTargets(ctx); err != nil { + wr.Logger().Errorf("Could not restart workflow %s: %v, please restart it manually", workflow, err) + } + }(ctx) + ctx, cancel := context.WithCancel(ctx) + defer cancel() + // TODO(sougou): parallelize + diffReports := make(map[string]*DiffReport) + for table, td := range df.differs { + if err := df.stopTargets(ctx); err != nil { + return nil, vterrors.Wrap(err, "stopTargets") + } + sourceReader, err := df.startQueryStreams(ctx, df.mi.sourceKeyspace, df.sources, td.sourceExpression, filteredReplicationWaitTime) + if err != nil { + return nil, vterrors.Wrap(err, "startQueryStreams(sources)") + } + if err := df.syncTargets(ctx, filteredReplicationWaitTime); err != nil { + return nil, vterrors.Wrap(err, "syncTargets") + } + targetReader, err := df.startQueryStreams(ctx, df.mi.targetKeyspace, df.targets, td.targetExpression, filteredReplicationWaitTime) + if err != nil { + return nil, vterrors.Wrap(err, "startQueryStreams(targets)") + } + if err := df.restartTargets(ctx); err != nil { + return nil, vterrors.Wrap(err, "restartTargets") + } + dr, err := td.diff(ctx, df.mi.wr, sourceReader, targetReader) + if err != nil { + return nil, vterrors.Wrap(err, "diff") + } + wr.Logger().Printf("Summary for %v: %+v\n", td.targetTable, *dr) + diffReports[table] = dr + } + return diffReports, nil +} + +func buildVDiffPlan(ctx context.Context, filter *binlogdatapb.Filter, schm *tabletmanagerdatapb.SchemaDefinition) (map[string]*tableDiffer, error) { + differs := make(map[string]*tableDiffer) + for _, table := range schm.TableDefinitions { + rule, err := vreplication.MatchTable(table.Name, filter) + if err != nil { + return nil, err + } + if rule == nil { + continue + } + query := rule.Filter + if rule.Filter == "" || key.IsKeyRange(rule.Filter) { + buf := sqlparser.NewTrackedBuffer(nil) + buf.Myprintf("select * from %v", sqlparser.NewTableIdent(table.Name)) + query = buf.String() + } + differs[table.Name], err = buildDifferPlan(table, query) + if err != nil { + return nil, err + } + } + return differs, nil +} + +func buildDifferPlan(table *tabletmanagerdatapb.TableDefinition, query string) (*tableDiffer, error) { + statement, err := sqlparser.Parse(query) + if err != nil { + return nil, err + } + sel, ok := statement.(*sqlparser.Select) + if !ok { + return nil, fmt.Errorf("unexpected: %v", sqlparser.String(statement)) + } + td := &tableDiffer{ + targetTable: table.Name, + } + sourceSelect := &sqlparser.Select{} + targetSelect := &sqlparser.Select{} + var aggregates []engine.AggregateParams + for _, selExpr := range sel.SelectExprs { + switch selExpr := selExpr.(type) { + case *sqlparser.StarExpr: + for _, fld := range table.Fields { + aliased := &sqlparser.AliasedExpr{Expr: &sqlparser.ColName{Name: sqlparser.NewColIdent(fld.Name)}} + sourceSelect.SelectExprs = append(sourceSelect.SelectExprs, aliased) + targetSelect.SelectExprs = append(targetSelect.SelectExprs, aliased) + } + case *sqlparser.AliasedExpr: + var targetCol *sqlparser.ColName + if !selExpr.As.IsEmpty() { + targetCol = &sqlparser.ColName{Name: selExpr.As} + } else { + if colAs, ok := selExpr.Expr.(*sqlparser.ColName); ok { + targetCol = colAs + } else { + return nil, fmt.Errorf("expression needs an alias: %v", sqlparser.String(selExpr)) + } + } + sourceSelect.SelectExprs = append(sourceSelect.SelectExprs, selExpr) + targetSelect.SelectExprs = append(targetSelect.SelectExprs, &sqlparser.AliasedExpr{Expr: targetCol}) + + // Check if it's an aggregate expression + if expr, ok := selExpr.Expr.(*sqlparser.FuncExpr); ok { + switch fname := expr.Name.Lowered(); fname { + case "count", "sum": + aggregates = append(aggregates, engine.AggregateParams{ + Opcode: engine.SupportedAggregates[fname], + Col: len(sourceSelect.SelectExprs) - 1, + }) + } + } + default: + return nil, fmt.Errorf("unexpected: %v", sqlparser.String(statement)) + } + } + fields := make(map[string]querypb.Type) + for _, field := range table.Fields { + fields[strings.ToLower(field.Name)] = field.Type + } + + td.compareCols = make([]int, len(sourceSelect.SelectExprs)) + for i := range td.compareCols { + colname := targetSelect.SelectExprs[i].(*sqlparser.AliasedExpr).Expr.(*sqlparser.ColName).Name.Lowered() + typ, ok := fields[colname] + if !ok { + return nil, fmt.Errorf("column %v not found in table %v", colname, table.Name) + } + td.compareCols[i] = i + if sqltypes.IsText(typ) { + sourceSelect.SelectExprs = append(sourceSelect.SelectExprs, wrapWeightString(sourceSelect.SelectExprs[i])) + targetSelect.SelectExprs = append(targetSelect.SelectExprs, wrapWeightString(targetSelect.SelectExprs[i])) + td.compareCols[i] = len(sourceSelect.SelectExprs) - 1 + } + } + + sourceSelect.From = sel.From + targetSelect.From = sqlparser.TableExprs{ + &sqlparser.AliasedTableExpr{ + Expr: &sqlparser.TableName{ + Name: sqlparser.NewTableIdent(table.Name), + }, + }, + } + + var orderby sqlparser.OrderBy + for _, pk := range table.PrimaryKeyColumns { + found := false + for i, selExpr := range targetSelect.SelectExprs { + colname := selExpr.(*sqlparser.AliasedExpr).Expr.(*sqlparser.ColName).Name.Lowered() + if pk == colname { + td.comparePKs = append(td.comparePKs, td.compareCols[i]) + // We'll be comparing pks seperately. So, remove them from compareCols. + td.compareCols[i] = -1 + found = true + break + } + } + if !found { + // Unreachable. + return nil, fmt.Errorf("column %v not found in table %v", pk, table.Name) + } + orderby = append(orderby, &sqlparser.Order{ + Expr: &sqlparser.ColName{Name: sqlparser.NewColIdent(pk)}, + Direction: sqlparser.AscScr, + }) + } + sourceSelect.Where = removeKeyrange(sel.Where) + sourceSelect.GroupBy = sel.GroupBy + sourceSelect.OrderBy = orderby + + targetSelect.OrderBy = orderby + + td.sourceExpression = sqlparser.String(sourceSelect) + td.targetExpression = sqlparser.String(targetSelect) + + td.sourcePrimitive = newMergeSorter(td.comparePKs) + td.targetPrimitive = newMergeSorter(td.comparePKs) + if len(aggregates) != 0 { + td.sourcePrimitive = &engine.OrderedAggregate{ + Aggregates: aggregates, + Keys: td.comparePKs, + Input: td.sourcePrimitive, + } + } + + return td, nil +} + +func (df *vdiff) selectTablets(ctx context.Context, healthcheckTopologyRefresh, healthcheckRetryDelay, healthcheckTimeout time.Duration) error { + var wg sync.WaitGroup + var err1, err2 error + + // Parallelize all discovery. + wg.Add(1) + go func() { + defer wg.Done() + err1 = df.forAll(df.sources, func(shard string, source *dfParams) error { + tp, err := discovery.NewTabletPicker(ctx, df.mi.wr.ts, df.sourceCell, df.mi.sourceKeyspace, shard, df.tabletTypesStr, healthcheckTopologyRefresh, healthcheckRetryDelay, healthcheckTimeout) + if err != nil { + return err + } + defer tp.Close() + + tablet, err := tp.PickForStreaming(ctx) + if err != nil { + return err + } + source.tablet = tablet + return nil + }) + }() + + wg.Add(1) + go func() { + defer wg.Done() + err2 = df.forAll(df.targets, func(shard string, target *dfParams) error { + tp, err := discovery.NewTabletPicker(ctx, df.mi.wr.ts, df.targetCell, df.mi.targetKeyspace, shard, df.tabletTypesStr, healthcheckTopologyRefresh, healthcheckRetryDelay, healthcheckTimeout) + if err != nil { + return err + } + defer tp.Close() + + tablet, err := tp.PickForStreaming(ctx) + if err != nil { + return err + } + target.tablet = tablet + return nil + }) + }() + + wg.Wait() + if err1 != nil { + return err1 + } + return err2 +} + +func (df *vdiff) stopTargets(ctx context.Context) error { + var mu sync.Mutex + + err := df.forAll(df.targets, func(shard string, target *dfParams) error { + query := fmt.Sprintf("update _vt.vreplication set state='Stopped', message='for vdiff' where db_name=%s and workflow=%s", encodeString(target.master.DbName()), encodeString(df.mi.workflow)) + _, err := df.mi.wr.tmc.VReplicationExec(ctx, target.master.Tablet, query) + if err != nil { + return err + } + query = fmt.Sprintf("select source, pos from _vt.vreplication where db_name=%s and workflow=%s", encodeString(target.master.DbName()), encodeString(df.mi.workflow)) + p3qr, err := df.mi.wr.tmc.VReplicationExec(ctx, target.master.Tablet, query) + if err != nil { + return err + } + qr := sqltypes.Proto3ToResult(p3qr) + + for _, row := range qr.Rows { + var bls binlogdatapb.BinlogSource + if err := proto.UnmarshalText(row[0].ToString(), &bls); err != nil { + return err + } + pos, err := mysql.DecodePosition(row[1].ToString()) + if err != nil { + return err + } + func() { + mu.Lock() + defer mu.Unlock() + + source, ok := df.sources[bls.Shard] + if !ok { + // Unreachable. + return + } + if !source.position.IsZero() && source.position.AtLeast(pos) { + return + } + source.position = pos + }() + } + return nil + }) + if err != nil { + return err + } + return nil +} + +func (df *vdiff) startQueryStreams(ctx context.Context, keyspace string, participants map[string]*dfParams, query string, filteredReplicationWaitTime time.Duration) (*resultReader, error) { + waitCtx, cancel := context.WithTimeout(ctx, filteredReplicationWaitTime) + defer cancel() + err := df.forAll(participants, func(shard string, participant *dfParams) error { + // Iteration for each participant. + if err := df.mi.wr.tmc.WaitForPosition(waitCtx, participant.tablet, mysql.EncodePosition(participant.position)); err != nil { + return vterrors.Wrapf(err, "WaitForPosition for tablet %v", topoproto.TabletAliasString(participant.tablet.Alias)) + } + participant.result = make(chan *sqltypes.Result, 1) + gtidch := make(chan string, 1) + + // Start the stream in a separate goroutine. + go df.streamOne(ctx, keyspace, shard, participant, query, gtidch) + + // Wait for the gtid to be sent. If it's not received, there was an error + // which would be stored in participant.err. + gtid, ok := <-gtidch + if !ok { + return participant.err + } + // Save the new position, as of when the query executed. + participant.snapshotPosition = gtid + return nil + }) + if err != nil { + return nil, err + } + return newResultReader(ctx, participants), nil +} + +// streamOne is called as a goroutine, and communicates its results through channels. +// It first sends the snapshot gtid to gtidch. +// Then it streams results to participant.result. +// Before returning, it sets participant.err, and closes all channels. +// If any channel is closed, then participant.err can be checked if there was an error. +func (df *vdiff) streamOne(ctx context.Context, keyspace, shard string, participant *dfParams, query string, gtidch chan string) { + defer close(participant.result) + defer close(gtidch) + + // Wrap the streaming in a separate function so we can capture the error. + // This shows that the error will be set before the channels are closed. + participant.err = func() error { + conn, err := tabletconn.GetDialer()(participant.tablet, grpcclient.FailFast(false)) + if err != nil { + return err + } + defer conn.Close(ctx) + + target := &querypb.Target{ + Keyspace: keyspace, + Shard: shard, + TabletType: participant.tablet.Type, + } + var fields []*querypb.Field + err = conn.VStreamResults(ctx, target, query, func(vrs *binlogdatapb.VStreamResultsResponse) error { + if vrs.Fields != nil { + fields = vrs.Fields + gtidch <- vrs.Gtid + } + p3qr := &querypb.QueryResult{ + Fields: fields, + Rows: vrs.Rows, + } + result := sqltypes.Proto3ToResult(p3qr) + // Fields should be received only once, and sent only once. + if vrs.Fields == nil { + result.Fields = nil + } + select { + case participant.result <- result: + case <-ctx.Done(): + return vterrors.Wrap(ctx.Err(), "VStreamResults") + } + return nil + }) + return err + }() +} + +func (df *vdiff) syncTargets(ctx context.Context, filteredReplicationWaitTime time.Duration) error { + waitCtx, cancel := context.WithTimeout(ctx, filteredReplicationWaitTime) + defer cancel() + err := df.mi.forAllUids(func(target *miTarget, uid uint32) error { + bls := target.sources[uid] + pos := df.sources[bls.Shard].snapshotPosition + query := fmt.Sprintf("update _vt.vreplication set state='Running', stop_pos='%s', message='synchronizing for vdiff' where id=%d", pos, uid) + if _, err := df.mi.wr.tmc.VReplicationExec(ctx, target.master.Tablet, query); err != nil { + return err + } + if err := df.mi.wr.tmc.VReplicationWaitForPos(waitCtx, target.master.Tablet, int(uid), pos); err != nil { + return vterrors.Wrapf(err, "VReplicationWaitForPos for tablet %v", topoproto.TabletAliasString(target.master.Tablet.Alias)) + } + return nil + }) + if err != nil { + return err + } + + err = df.forAll(df.targets, func(shard string, target *dfParams) error { + pos, err := df.mi.wr.tmc.MasterPosition(ctx, target.master.Tablet) + if err != nil { + return err + } + mpos, err := mysql.DecodePosition(pos) + if err != nil { + return err + } + target.position = mpos + return nil + }) + return err +} + +func (df *vdiff) restartTargets(ctx context.Context) error { + return df.forAll(df.targets, func(shard string, target *dfParams) error { + query := fmt.Sprintf("update _vt.vreplication set state='Running', message='', stop_pos='' where db_name=%s and workflow=%s", encodeString(target.master.DbName()), encodeString(df.mi.workflow)) + _, err := df.mi.wr.tmc.VReplicationExec(ctx, target.master.Tablet, query) + return err + }) +} + +func (df *vdiff) forAll(participants map[string]*dfParams, f func(string, *dfParams) error) error { + var wg sync.WaitGroup + allErrors := &concurrency.AllErrorRecorder{} + for shard, participant := range participants { + wg.Add(1) + go func(shard string, participant *dfParams) { + defer wg.Done() + + if err := f(shard, participant); err != nil { + allErrors.RecordError(err) + } + }(shard, participant) + } + wg.Wait() + return allErrors.AggrError(vterrors.Aggregate) +} + +//----------------------------------------------------------------- +// primitiveExecutor + +type primitiveExecutor struct { + prim engine.Primitive + rows [][]sqltypes.Value + resultch chan *sqltypes.Result + err error +} + +func newPrimitiveExecutor(ctx context.Context, vcursor engine.VCursor, prim engine.Primitive) *primitiveExecutor { + pe := &primitiveExecutor{ + prim: prim, + resultch: make(chan *sqltypes.Result, 1), + } + go func() { + defer close(pe.resultch) + pe.err = pe.prim.StreamExecute(vcursor, make(map[string]*querypb.BindVariable), false, func(qr *sqltypes.Result) error { + select { + case pe.resultch <- qr: + case <-ctx.Done(): + return vterrors.Wrap(ctx.Err(), "Outer Stream") + } + return nil + }) + }() + return pe +} + +func (pe *primitiveExecutor) next() ([]sqltypes.Value, error) { + for len(pe.rows) == 0 { + qr, ok := <-pe.resultch + if !ok { + return nil, pe.err + } + pe.rows = qr.Rows + } + + row := pe.rows[0] + pe.rows = pe.rows[1:] + return row, nil +} + +func (pe *primitiveExecutor) drain(ctx context.Context) (int, error) { + count := 0 + for { + row, err := pe.next() + if err != nil { + return 0, err + } + if row == nil { + return count, nil + } + count++ + } +} + +//----------------------------------------------------------------- +// mergeSorter + +var _ engine.Primitive = (*mergeSorter)(nil) + +// mergeSorter performs a merge-sorted read from the participants. +type mergeSorter struct { + engine.Primitive + orderBy []engine.OrderbyParams +} + +func newMergeSorter(comparePKs []int) *mergeSorter { + ob := make([]engine.OrderbyParams, 0, len(comparePKs)) + for _, col := range comparePKs { + ob = append(ob, engine.OrderbyParams{Col: col}) + } + return &mergeSorter{ + orderBy: ob, + } +} + +func (ms *mergeSorter) StreamExecute(vcursor engine.VCursor, bindVars map[string]*querypb.BindVariable, wantields bool, callback func(*sqltypes.Result) error) error { + rr, ok := vcursor.(*resultReader) + if !ok { + return fmt.Errorf("internal error: vcursor is not a resultReader: %T", vcursor) + } + rss := make([]*srvtopo.ResolvedShard, 0, len(rr.participants)) + bvs := make([]map[string]*querypb.BindVariable, 0, len(rr.participants)) + for shard := range rr.participants { + rss = append(rss, &srvtopo.ResolvedShard{ + Target: &querypb.Target{ + Shard: shard, + }, + }) + bvs = append(bvs, bindVars) + } + return engine.MergeSort(vcursor, "", ms.orderBy, rss, bvs, callback) +} + +//----------------------------------------------------------------- +// resultReader + +// resultReader acts as a VCursor for the wrapping primitives. +type resultReader struct { + engine.VCursor + ctx context.Context + participants map[string]*dfParams +} + +func newResultReader(ctx context.Context, participants map[string]*dfParams) *resultReader { + return &resultReader{ + ctx: ctx, + participants: participants, + } +} + +func (rr *resultReader) Context() context.Context { + return rr.ctx +} + +func (rr *resultReader) StreamExecuteMulti(query string, rss []*srvtopo.ResolvedShard, bindVars []map[string]*querypb.BindVariable, callback func(reply *sqltypes.Result) error) error { + for result := range rr.participants[rss[0].Target.Shard].result { + if err := callback(result); err != nil { + return err + } + } + return rr.participants[rss[0].Target.Shard].err +} + +//----------------------------------------------------------------- +// tableDiffer + +func (td *tableDiffer) diff(ctx context.Context, wr *Wrangler, sourceReader, targetReader *resultReader) (*DiffReport, error) { + sourceExecutor := newPrimitiveExecutor(ctx, sourceReader, td.sourcePrimitive) + targetExecutor := newPrimitiveExecutor(ctx, targetReader, td.targetPrimitive) + dr := &DiffReport{} + var sourceRow, targetRow []sqltypes.Value + var err error + advanceSource := true + advanceTarget := true + for { + if advanceSource { + sourceRow, err = sourceExecutor.next() + if err != nil { + return nil, err + } + } + if advanceTarget { + targetRow, err = targetExecutor.next() + if err != nil { + return nil, err + } + } + + if sourceRow == nil && targetRow == nil { + return dr, nil + } + + advanceSource = true + advanceTarget = true + + if sourceRow == nil { + // drain target, update count + wr.Logger().Errorf("Draining extra row(s) found on the target starting with: %v", targetRow) + count, err := targetExecutor.drain(ctx) + if err != nil { + return nil, err + } + dr.ExtraRowsTarget += 1 + count + dr.ProcessedRows += 1 + count + return dr, nil + } + if targetRow == nil { + // no more rows from the target + // we know we have rows from source, drain, update count + wr.Logger().Errorf("Draining extra row(s) found on the source starting with: %v", sourceRow) + count, err := sourceExecutor.drain(ctx) + if err != nil { + return nil, err + } + dr.ExtraRowsSource += 1 + count + dr.ProcessedRows += 1 + count + return dr, nil + } + + dr.ProcessedRows++ + + // Compare pk values. + c, err := td.compare(sourceRow, targetRow, td.comparePKs) + switch { + case err != nil: + return nil, err + case c < 0: + if dr.ExtraRowsSource < 10 { + wr.Logger().Errorf("[table=%v] Extra row %v on source: %v", td.targetTable, dr.ExtraRowsSource, sourceRow) + } + dr.ExtraRowsSource++ + advanceTarget = false + continue + case c > 0: + if dr.ExtraRowsTarget < 10 { + wr.Logger().Errorf("[table=%v] Extra row %v on target: %v", td.targetTable, dr.ExtraRowsTarget, targetRow) + } + dr.ExtraRowsTarget++ + advanceSource = false + continue + } + + // c == 0 + // Compare non-pk values. + c, err = td.compare(sourceRow, targetRow, td.compareCols) + switch { + case err != nil: + return nil, err + case c != 0: + if dr.MismatchedRows < 10 { + wr.Logger().Errorf("[table=%v] Different content %v in same PK: %v != %v", td.targetTable, dr.MismatchedRows, sourceRow, targetRow) + } + dr.MismatchedRows++ + default: + dr.MatchingRows++ + } + } +} + +func (td *tableDiffer) compare(sourceRow, targetRow []sqltypes.Value, cols []int) (int, error) { + for _, col := range cols { + if col == -1 { + continue + } + c, err := sqltypes.NullsafeCompare(sourceRow[col], targetRow[col]) + if err != nil { + return 0, err + } + if c != 0 { + return c, nil + } + } + return 0, nil +} + +func removeKeyrange(where *sqlparser.Where) *sqlparser.Where { + if where == nil { + return nil + } + if isFuncKeyrange(where.Expr) { + return nil + } + where.Expr = removeExprKeyrange(where.Expr) + return where +} + +func removeExprKeyrange(node sqlparser.Expr) sqlparser.Expr { + switch node := node.(type) { + case *sqlparser.AndExpr: + if isFuncKeyrange(node.Left) { + return removeExprKeyrange(node.Right) + } + if isFuncKeyrange(node.Right) { + return removeExprKeyrange(node.Left) + } + return &sqlparser.AndExpr{ + Left: removeExprKeyrange(node.Left), + Right: removeExprKeyrange(node.Right), + } + case *sqlparser.ParenExpr: + return &sqlparser.ParenExpr{ + Expr: removeExprKeyrange(node.Expr), + } + } + return node +} + +func isFuncKeyrange(expr sqlparser.Expr) bool { + funcExpr, ok := expr.(*sqlparser.FuncExpr) + return ok && funcExpr.Name.EqualString("in_keyrange") +} + +func wrapWeightString(expr sqlparser.SelectExpr) *sqlparser.AliasedExpr { + return &sqlparser.AliasedExpr{ + Expr: &sqlparser.FuncExpr{ + Name: sqlparser.NewColIdent("weight_string"), + Exprs: []sqlparser.SelectExpr{ + &sqlparser.AliasedExpr{ + Expr: expr.(*sqlparser.AliasedExpr).Expr, + }, + }, + }, + } +} diff --git a/go/vt/wrangler/vdiff_env_test.go b/go/vt/wrangler/vdiff_env_test.go new file mode 100644 index 00000000000..f41db6315e8 --- /dev/null +++ b/go/vt/wrangler/vdiff_env_test.go @@ -0,0 +1,335 @@ +/* +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 wrangler + +import ( + "flag" + "fmt" + + "golang.org/x/net/context" + "vitess.io/vitess/go/sqltypes" + "vitess.io/vitess/go/vt/grpcclient" + "vitess.io/vitess/go/vt/logutil" + binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" + querypb "vitess.io/vitess/go/vt/proto/query" + tabletmanagerdatapb "vitess.io/vitess/go/vt/proto/tabletmanagerdata" + topodatapb "vitess.io/vitess/go/vt/proto/topodata" + "vitess.io/vitess/go/vt/topo" + "vitess.io/vitess/go/vt/topo/memorytopo" + "vitess.io/vitess/go/vt/vttablet/queryservice" + "vitess.io/vitess/go/vt/vttablet/queryservice/fakes" + "vitess.io/vitess/go/vt/vttablet/tabletconn" + "vitess.io/vitess/go/vt/vttablet/tmclient" +) + +const ( + // vdiffStopPosition is the default stop position for the target vreplication. + // It can be overridden with the positons argument to newTestVDiffEnv. + vdiffStopPosition = "MariaDB/5-456-892" + // vdiffSourceGtid should be the position reported by the source side VStreamResults. + // It's expected to be higher the vdiffStopPosition. + vdiffSourceGtid = "MariaDB/5-456-893" + // vdiffTargetMasterPosition is the master position of the target after + // vreplication has been synchronized. + vdiffTargetMasterPosition = "MariaDB/6-456-892" +) + +type testVDiffEnv struct { + wr *Wrangler + workflow string + tablets map[int]*testVDiffTablet + topoServ *topo.Server + cell string + tabletType topodatapb.TabletType + tmc *testVDiffTMClient +} + +// vdiffEnv has to be a global for RegisterDialer to work. +var vdiffEnv *testVDiffEnv + +func init() { + tabletconn.RegisterDialer("VDiffTest", func(tablet *topodatapb.Tablet, failFast grpcclient.FailFast) (queryservice.QueryService, error) { + return vdiffEnv.tablets[int(tablet.Alias.Uid)], nil + }) +} + +//---------------------------------------------- +// testVDiffEnv + +func newTestVDiffEnv(sourceShards, targetShards []string, query string, positions map[string]string) *testVDiffEnv { + flag.Set("tablet_protocol", "VDiffTest") + env := &testVDiffEnv{ + workflow: "vdiffTest", + tablets: make(map[int]*testVDiffTablet), + topoServ: memorytopo.NewServer("cell"), + cell: "cell", + tabletType: topodatapb.TabletType_REPLICA, + tmc: newTestVDiffTMClient(), + } + env.wr = New(logutil.NewConsoleLogger(), env.topoServ, env.tmc) + + tabletID := 100 + for _, shard := range sourceShards { + _ = env.addTablet(tabletID, "source", shard, topodatapb.TabletType_MASTER) + _ = env.addTablet(tabletID+1, "source", shard, topodatapb.TabletType_REPLICA) + env.tmc.waitpos[tabletID+1] = vdiffStopPosition + + tabletID += 10 + } + tabletID = 200 + for _, shard := range targetShards { + master := env.addTablet(tabletID, "target", shard, topodatapb.TabletType_MASTER) + _ = env.addTablet(tabletID+1, "target", shard, topodatapb.TabletType_REPLICA) + + var rows []string + var posRows []string + for j, sourceShard := range sourceShards { + bls := &binlogdatapb.BinlogSource{ + Keyspace: "source", + Shard: sourceShard, + Filter: &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{{ + Match: "t1", + Filter: query, + }}, + }, + } + rows = append(rows, fmt.Sprintf("%d|%v|", j+1, bls)) + position := vdiffStopPosition + if pos := positions[sourceShard+shard]; pos != "" { + position = pos + } + posRows = append(posRows, fmt.Sprintf("%v|%s", bls, position)) + + // vdiff.syncTargets. This actually happens after stopTargets. + // But this is one statement per stream. + env.tmc.setVRResults( + master.tablet, + fmt.Sprintf("update _vt.vreplication set state='Running', stop_pos='%s', message='synchronizing for vdiff' where id=%d", vdiffSourceGtid, j+1), + &sqltypes.Result{}, + ) + } + // migrater buildMigrationTargets + env.tmc.setVRResults( + master.tablet, + "select id, source, message from _vt.vreplication where workflow='vdiffTest' and db_name='vt_target'", + sqltypes.MakeTestResult(sqltypes.MakeTestFields( + "id|source|message", + "int64|varchar|varchar"), + rows..., + ), + ) + + // vdiff.stopTargets + env.tmc.setVRResults(master.tablet, "update _vt.vreplication set state='Stopped', message='for vdiff' where db_name='vt_target' and workflow='vdiffTest'", &sqltypes.Result{}) + env.tmc.setVRResults( + master.tablet, + "select source, pos from _vt.vreplication where db_name='vt_target' and workflow='vdiffTest'", + sqltypes.MakeTestResult(sqltypes.MakeTestFields( + "source|pos", + "varchar|varchar"), + posRows..., + ), + ) + + // vdiff.syncTargets (continued) + env.tmc.vrpos[tabletID] = vdiffSourceGtid + env.tmc.pos[tabletID] = vdiffTargetMasterPosition + + // vdiff.startQueryStreams + env.tmc.waitpos[tabletID+1] = vdiffTargetMasterPosition + + // vdiff.restartTargets + env.tmc.setVRResults(master.tablet, "update _vt.vreplication set state='Running', message='', stop_pos='' where db_name='vt_target' and workflow='vdiffTest'", &sqltypes.Result{}) + + tabletID += 10 + } + vdiffEnv = env + return env +} + +func (env *testVDiffEnv) close() { + for _, t := range env.tablets { + env.deleteTablet(t.tablet) + } +} + +func (env *testVDiffEnv) addTablet(id int, keyspace, shard string, tabletType topodatapb.TabletType) *testVDiffTablet { + tablet := &topodatapb.Tablet{ + Alias: &topodatapb.TabletAlias{ + Cell: env.cell, + Uid: uint32(id), + }, + Keyspace: keyspace, + Shard: shard, + KeyRange: &topodatapb.KeyRange{}, + Type: tabletType, + PortMap: map[string]int32{ + "test": int32(id), + }, + } + env.tablets[id] = newTestVDiffTablet(tablet) + if err := env.wr.InitTablet(context.Background(), tablet, false /* allowMasterOverride */, true /* createShardAndKeyspace */, false /* allowUpdate */); err != nil { + panic(err) + } + if tabletType == topodatapb.TabletType_MASTER { + _, err := env.wr.ts.UpdateShardFields(context.Background(), keyspace, shard, func(si *topo.ShardInfo) error { + si.MasterAlias = tablet.Alias + return nil + }) + if err != nil { + panic(err) + } + } + return env.tablets[id] +} + +func (env *testVDiffEnv) deleteTablet(tablet *topodatapb.Tablet) { + env.topoServ.DeleteTablet(context.Background(), tablet.Alias) + delete(env.tablets, int(tablet.Alias.Uid)) +} + +//---------------------------------------------- +// testVDiffTablet + +type testVDiffTablet struct { + queryservice.QueryService + tablet *topodatapb.Tablet + queries map[string][]*binlogdatapb.VStreamResultsResponse +} + +func newTestVDiffTablet(tablet *topodatapb.Tablet) *testVDiffTablet { + return &testVDiffTablet{ + QueryService: fakes.ErrorQueryService, + tablet: tablet, + queries: make(map[string][]*binlogdatapb.VStreamResultsResponse), + } +} + +func (tvt *testVDiffTablet) StreamHealth(ctx context.Context, callback func(*querypb.StreamHealthResponse) error) error { + return callback(&querypb.StreamHealthResponse{ + Serving: true, + Target: &querypb.Target{ + Keyspace: tvt.tablet.Keyspace, + Shard: tvt.tablet.Shard, + TabletType: tvt.tablet.Type, + }, + RealtimeStats: &querypb.RealtimeStats{}, + }) +} + +func (tvt *testVDiffTablet) VStreamResults(ctx context.Context, target *querypb.Target, query string, send func(*binlogdatapb.VStreamResultsResponse) error) error { + results, ok := tvt.queries[query] + if !ok { + return fmt.Errorf("query %q not in list", query) + } + for _, result := range results { + if err := send(result); err != nil { + return err + } + } + return nil +} + +func (tvt *testVDiffTablet) setResults(query string, gtid string, results []*sqltypes.Result) { + vrs := []*binlogdatapb.VStreamResultsResponse{{ + Fields: results[0].Fields, + Gtid: gtid, + }} + + for _, result := range results[1:] { + vr := &binlogdatapb.VStreamResultsResponse{ + Rows: sqltypes.RowsToProto3(result.Rows), + } + vrs = append(vrs, vr) + } + tvt.queries[query] = vrs +} + +//---------------------------------------------- +// testVDiffTMCclient + +type testVDiffTMClient struct { + tmclient.TabletManagerClient + schema *tabletmanagerdatapb.SchemaDefinition + vrQueries map[int]map[string]*querypb.QueryResult + waitpos map[int]string + vrpos map[int]string + pos map[int]string +} + +func newTestVDiffTMClient() *testVDiffTMClient { + return &testVDiffTMClient{ + vrQueries: make(map[int]map[string]*querypb.QueryResult), + waitpos: make(map[int]string), + vrpos: make(map[int]string), + pos: make(map[int]string), + } +} + +func (tmc *testVDiffTMClient) GetSchema(ctx context.Context, tablet *topodatapb.Tablet, tables, excludeTables []string, includeViews bool) (*tabletmanagerdatapb.SchemaDefinition, error) { + return tmc.schema, nil +} + +func (tmc *testVDiffTMClient) setVRResults(tablet *topodatapb.Tablet, query string, result *sqltypes.Result) { + queries, ok := tmc.vrQueries[int(tablet.Alias.Uid)] + if !ok { + queries = make(map[string]*querypb.QueryResult) + tmc.vrQueries[int(tablet.Alias.Uid)] = queries + } + queries[query] = sqltypes.ResultToProto3(result) +} + +func (tmc *testVDiffTMClient) VReplicationExec(ctx context.Context, tablet *topodatapb.Tablet, query string) (*querypb.QueryResult, error) { + result, ok := tmc.vrQueries[int(tablet.Alias.Uid)][query] + if !ok { + return nil, fmt.Errorf("query %q not found for tablet %d", query, tablet.Alias.Uid) + } + return result, nil +} + +func (tmc *testVDiffTMClient) WaitForPosition(ctx context.Context, tablet *topodatapb.Tablet, pos string) error { + select { + case <-ctx.Done(): + return ctx.Err() + default: + } + if pos != tmc.waitpos[int(tablet.Alias.Uid)] { + return fmt.Errorf("waitpos %s not reached for tablet %d", pos, tablet.Alias.Uid) + } + return nil +} + +func (tmc *testVDiffTMClient) VReplicationWaitForPos(ctx context.Context, tablet *topodatapb.Tablet, id int, pos string) error { + select { + case <-ctx.Done(): + return ctx.Err() + default: + } + if pos != tmc.vrpos[int(tablet.Alias.Uid)] { + return fmt.Errorf("vrpos %s not reached for tablet %d", pos, tablet.Alias.Uid) + } + return nil +} + +func (tmc *testVDiffTMClient) MasterPosition(ctx context.Context, tablet *topodatapb.Tablet) (string, error) { + pos, ok := tmc.pos[int(tablet.Alias.Uid)] + if !ok { + return "", fmt.Errorf("no master position for %d", tablet.Alias.Uid) + } + return pos, nil +} diff --git a/go/vt/wrangler/vdiff_test.go b/go/vt/wrangler/vdiff_test.go new file mode 100644 index 00000000000..b2f92131c31 --- /dev/null +++ b/go/vt/wrangler/vdiff_test.go @@ -0,0 +1,889 @@ +/* +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 wrangler + +import ( + "testing" + "time" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "golang.org/x/net/context" + "vitess.io/vitess/go/sqltypes" + binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" + tabletmanagerdatapb "vitess.io/vitess/go/vt/proto/tabletmanagerdata" + "vitess.io/vitess/go/vt/vtgate/engine" +) + +func TestVDiffPlanSuccess(t *testing.T) { + schm := &tabletmanagerdatapb.SchemaDefinition{ + TableDefinitions: []*tabletmanagerdatapb.TableDefinition{{ + Name: "t1", + Columns: []string{"c1", "c2"}, + PrimaryKeyColumns: []string{"c1"}, + Fields: sqltypes.MakeTestFields("c1|c2", "int64|int64"), + }, { + Name: "nonpktext", + Columns: []string{"c1", "textcol"}, + PrimaryKeyColumns: []string{"c1"}, + Fields: sqltypes.MakeTestFields("c1|textcol", "int64|varchar"), + }, { + Name: "pktext", + Columns: []string{"textcol", "c2"}, + PrimaryKeyColumns: []string{"textcol"}, + Fields: sqltypes.MakeTestFields("textcol|c2", "varchar|int64"), + }, { + Name: "multipk", + Columns: []string{"c1", "c2"}, + PrimaryKeyColumns: []string{"c1", "c2"}, + Fields: sqltypes.MakeTestFields("c1|c2", "int64|int64"), + }, { + Name: "aggr", + Columns: []string{"c1", "c2", "c3", "c4"}, + PrimaryKeyColumns: []string{"c1"}, + Fields: sqltypes.MakeTestFields("c1|c2|c3|c4", "int64|int64|int64|int64"), + }}, + } + + testcases := []struct { + input *binlogdatapb.Rule + table string + td *tableDiffer + }{{ + input: &binlogdatapb.Rule{ + Match: "t1", + }, + table: "t1", + td: &tableDiffer{ + targetTable: "t1", + sourceExpression: "select c1, c2 from t1 order by c1 asc", + targetExpression: "select c1, c2 from t1 order by c1 asc", + compareCols: []int{-1, 1}, + comparePKs: []int{0}, + sourcePrimitive: newMergeSorter([]int{0}), + targetPrimitive: newMergeSorter([]int{0}), + }, + }, { + input: &binlogdatapb.Rule{ + Match: "t1", + Filter: "-80", + }, + table: "t1", + td: &tableDiffer{ + targetTable: "t1", + sourceExpression: "select c1, c2 from t1 order by c1 asc", + targetExpression: "select c1, c2 from t1 order by c1 asc", + compareCols: []int{-1, 1}, + comparePKs: []int{0}, + sourcePrimitive: newMergeSorter([]int{0}), + targetPrimitive: newMergeSorter([]int{0}), + }, + }, { + input: &binlogdatapb.Rule{ + Match: "t1", + Filter: "select * from t1", + }, + table: "t1", + td: &tableDiffer{ + targetTable: "t1", + sourceExpression: "select c1, c2 from t1 order by c1 asc", + targetExpression: "select c1, c2 from t1 order by c1 asc", + compareCols: []int{-1, 1}, + comparePKs: []int{0}, + sourcePrimitive: newMergeSorter([]int{0}), + targetPrimitive: newMergeSorter([]int{0}), + }, + }, { + input: &binlogdatapb.Rule{ + Match: "t1", + Filter: "select c2, c1 from t1", + }, + table: "t1", + td: &tableDiffer{ + targetTable: "t1", + sourceExpression: "select c2, c1 from t1 order by c1 asc", + targetExpression: "select c2, c1 from t1 order by c1 asc", + compareCols: []int{0, -1}, + comparePKs: []int{1}, + sourcePrimitive: newMergeSorter([]int{1}), + targetPrimitive: newMergeSorter([]int{1}), + }, + }, { + input: &binlogdatapb.Rule{ + Match: "t1", + Filter: "select c0 as c1, c2 from t2", + }, + table: "t1", + td: &tableDiffer{ + targetTable: "t1", + sourceExpression: "select c0 as c1, c2 from t2 order by c1 asc", + targetExpression: "select c1, c2 from t1 order by c1 asc", + compareCols: []int{-1, 1}, + comparePKs: []int{0}, + sourcePrimitive: newMergeSorter([]int{0}), + targetPrimitive: newMergeSorter([]int{0}), + }, + }, { + // non-pk text column. + input: &binlogdatapb.Rule{ + Match: "nonpktext", + Filter: "select c1, textcol from nonpktext", + }, + table: "nonpktext", + td: &tableDiffer{ + targetTable: "nonpktext", + sourceExpression: "select c1, textcol, weight_string(textcol) from nonpktext order by c1 asc", + targetExpression: "select c1, textcol, weight_string(textcol) from nonpktext order by c1 asc", + compareCols: []int{-1, 2}, + comparePKs: []int{0}, + sourcePrimitive: newMergeSorter([]int{0}), + targetPrimitive: newMergeSorter([]int{0}), + }, + }, { + // non-pk text column, different order. + input: &binlogdatapb.Rule{ + Match: "nonpktext", + Filter: "select textcol, c1 from nonpktext", + }, + table: "nonpktext", + td: &tableDiffer{ + targetTable: "nonpktext", + sourceExpression: "select textcol, c1, weight_string(textcol) from nonpktext order by c1 asc", + targetExpression: "select textcol, c1, weight_string(textcol) from nonpktext order by c1 asc", + compareCols: []int{2, -1}, + comparePKs: []int{1}, + sourcePrimitive: newMergeSorter([]int{1}), + targetPrimitive: newMergeSorter([]int{1}), + }, + }, { + // pk text column. + input: &binlogdatapb.Rule{ + Match: "pktext", + Filter: "select textcol, c2 from pktext", + }, + table: "pktext", + td: &tableDiffer{ + targetTable: "pktext", + sourceExpression: "select textcol, c2, weight_string(textcol) from pktext order by textcol asc", + targetExpression: "select textcol, c2, weight_string(textcol) from pktext order by textcol asc", + compareCols: []int{-1, 1}, + comparePKs: []int{2}, + sourcePrimitive: newMergeSorter([]int{2}), + targetPrimitive: newMergeSorter([]int{2}), + }, + }, { + // pk text column, different order. + input: &binlogdatapb.Rule{ + Match: "pktext", + Filter: "select c2, textcol from pktext", + }, + table: "pktext", + td: &tableDiffer{ + targetTable: "pktext", + sourceExpression: "select c2, textcol, weight_string(textcol) from pktext order by textcol asc", + targetExpression: "select c2, textcol, weight_string(textcol) from pktext order by textcol asc", + compareCols: []int{0, -1}, + comparePKs: []int{2}, + sourcePrimitive: newMergeSorter([]int{2}), + targetPrimitive: newMergeSorter([]int{2}), + }, + }, { + // text column as expression. + input: &binlogdatapb.Rule{ + Match: "pktext", + Filter: "select c2, a+b as textcol from pktext", + }, + table: "pktext", + td: &tableDiffer{ + targetTable: "pktext", + sourceExpression: "select c2, a + b as textcol, weight_string(a + b) from pktext order by textcol asc", + targetExpression: "select c2, textcol, weight_string(textcol) from pktext order by textcol asc", + compareCols: []int{0, -1}, + comparePKs: []int{2}, + sourcePrimitive: newMergeSorter([]int{2}), + targetPrimitive: newMergeSorter([]int{2}), + }, + }, { + input: &binlogdatapb.Rule{ + Match: "multipk", + }, + table: "multipk", + td: &tableDiffer{ + targetTable: "multipk", + sourceExpression: "select c1, c2 from multipk order by c1 asc, c2 asc", + targetExpression: "select c1, c2 from multipk order by c1 asc, c2 asc", + compareCols: []int{-1, -1}, + comparePKs: []int{0, 1}, + sourcePrimitive: newMergeSorter([]int{0, 1}), + targetPrimitive: newMergeSorter([]int{0, 1}), + }, + }, { + // in_keyrange + input: &binlogdatapb.Rule{ + Match: "t1", + Filter: "select * from t1 where in_keyrange('-80')", + }, + table: "t1", + td: &tableDiffer{ + targetTable: "t1", + sourceExpression: "select c1, c2 from t1 order by c1 asc", + targetExpression: "select c1, c2 from t1 order by c1 asc", + compareCols: []int{-1, 1}, + comparePKs: []int{0}, + sourcePrimitive: newMergeSorter([]int{0}), + targetPrimitive: newMergeSorter([]int{0}), + }, + }, { + // in_keyrange on RHS of AND. + // This is currently not a valid construct, but will be supported in the future. + input: &binlogdatapb.Rule{ + Match: "t1", + Filter: "select * from t1 where c2 = 2 and in_keyrange('-80')", + }, + table: "t1", + td: &tableDiffer{ + targetTable: "t1", + sourceExpression: "select c1, c2 from t1 where c2 = 2 order by c1 asc", + targetExpression: "select c1, c2 from t1 order by c1 asc", + compareCols: []int{-1, 1}, + comparePKs: []int{0}, + sourcePrimitive: newMergeSorter([]int{0}), + targetPrimitive: newMergeSorter([]int{0}), + }, + }, { + // in_keyrange on LHS of AND. + // This is currently not a valid construct, but will be supported in the future. + input: &binlogdatapb.Rule{ + Match: "t1", + Filter: "select * from t1 where in_keyrange('-80') and c2 = 2", + }, + table: "t1", + td: &tableDiffer{ + targetTable: "t1", + sourceExpression: "select c1, c2 from t1 where c2 = 2 order by c1 asc", + targetExpression: "select c1, c2 from t1 order by c1 asc", + compareCols: []int{-1, 1}, + comparePKs: []int{0}, + sourcePrimitive: newMergeSorter([]int{0}), + targetPrimitive: newMergeSorter([]int{0}), + }, + }, { + // in_keyrange on cascaded AND expression + // This is currently not a valid construct, but will be supported in the future. + input: &binlogdatapb.Rule{ + Match: "t1", + Filter: "select * from t1 where c2 = 2 and c1 = 1 and in_keyrange('-80')", + }, + table: "t1", + td: &tableDiffer{ + targetTable: "t1", + sourceExpression: "select c1, c2 from t1 where c2 = 2 and c1 = 1 order by c1 asc", + targetExpression: "select c1, c2 from t1 order by c1 asc", + compareCols: []int{-1, 1}, + comparePKs: []int{0}, + sourcePrimitive: newMergeSorter([]int{0}), + targetPrimitive: newMergeSorter([]int{0}), + }, + }, { + // in_keyrange parenthesized + // This is currently not a valid construct, but will be supported in the future. + input: &binlogdatapb.Rule{ + Match: "t1", + Filter: "select * from t1 where (c2 = 2 and in_keyrange('-80'))", + }, + table: "t1", + td: &tableDiffer{ + targetTable: "t1", + sourceExpression: "select c1, c2 from t1 where (c2 = 2) order by c1 asc", + targetExpression: "select c1, c2 from t1 order by c1 asc", + compareCols: []int{-1, 1}, + comparePKs: []int{0}, + sourcePrimitive: newMergeSorter([]int{0}), + targetPrimitive: newMergeSorter([]int{0}), + }, + }, { + // group by + input: &binlogdatapb.Rule{ + Match: "t1", + Filter: "select * from t1 group by c1", + }, + table: "t1", + td: &tableDiffer{ + targetTable: "t1", + sourceExpression: "select c1, c2 from t1 group by c1 order by c1 asc", + targetExpression: "select c1, c2 from t1 order by c1 asc", + compareCols: []int{-1, 1}, + comparePKs: []int{0}, + sourcePrimitive: newMergeSorter([]int{0}), + targetPrimitive: newMergeSorter([]int{0}), + }, + }, { + // aggregations + input: &binlogdatapb.Rule{ + Match: "aggr", + Filter: "select c1, c2, count(*) as c3, sum(c4) as c4 from t1 group by c1", + }, + table: "aggr", + td: &tableDiffer{ + targetTable: "aggr", + sourceExpression: "select c1, c2, count(*) as c3, sum(c4) as c4 from t1 group by c1 order by c1 asc", + targetExpression: "select c1, c2, c3, c4 from aggr order by c1 asc", + compareCols: []int{-1, 1, 2, 3}, + comparePKs: []int{0}, + sourcePrimitive: &engine.OrderedAggregate{ + Aggregates: []engine.AggregateParams{{ + Opcode: engine.AggregateCount, + Col: 2, + }, { + Opcode: engine.AggregateSum, + Col: 3, + }}, + Keys: []int{0}, + Input: newMergeSorter([]int{0}), + }, + targetPrimitive: newMergeSorter([]int{0}), + }, + }} + for _, tcase := range testcases { + filter := &binlogdatapb.Filter{Rules: []*binlogdatapb.Rule{tcase.input}} + differs, err := buildVDiffPlan(context.Background(), filter, schm) + require.NoError(t, err, tcase.input) + require.Equal(t, 1, len(differs), tcase.input) + assert.Equal(t, tcase.td, differs[tcase.table], tcase.input) + } +} + +func TestVDiffPlanFailure(t *testing.T) { + schm := &tabletmanagerdatapb.SchemaDefinition{ + TableDefinitions: []*tabletmanagerdatapb.TableDefinition{{ + Name: "t1", + Columns: []string{"c1", "c2"}, + PrimaryKeyColumns: []string{"c1"}, + Fields: sqltypes.MakeTestFields("c1|c2", "int64|int64"), + }}, + } + + testcases := []struct { + input *binlogdatapb.Rule + err string + }{{ + input: &binlogdatapb.Rule{ + Match: "t1", + Filter: "bad query", + }, + err: "syntax error at position 4 near 'bad'", + }, { + input: &binlogdatapb.Rule{ + Match: "t1", + Filter: "update t1 set c1=2", + }, + err: "unexpected: update t1 set c1 = 2", + }, { + input: &binlogdatapb.Rule{ + Match: "t1", + Filter: "select c1+1 from t1", + }, + err: "expression needs an alias: c1 + 1", + }, { + input: &binlogdatapb.Rule{ + Match: "t1", + Filter: "select next 2 values from t1", + }, + err: "unexpected: select next 2 values from t1", + }, { + input: &binlogdatapb.Rule{ + Match: "t1", + Filter: "select c3 from t1", + }, + err: "column c3 not found in table t1", + }} + for _, tcase := range testcases { + filter := &binlogdatapb.Filter{Rules: []*binlogdatapb.Rule{tcase.input}} + _, err := buildVDiffPlan(context.Background(), filter, schm) + assert.EqualError(t, err, tcase.err, tcase.input) + } +} + +func TestVDiffUnsharded(t *testing.T) { + env := newTestVDiffEnv([]string{"0"}, []string{"0"}, "", nil) + defer env.close() + + schm := &tabletmanagerdatapb.SchemaDefinition{ + TableDefinitions: []*tabletmanagerdatapb.TableDefinition{{ + Name: "t1", + Columns: []string{"c1", "c2"}, + PrimaryKeyColumns: []string{"c1"}, + Fields: sqltypes.MakeTestFields("c1|c2", "int64|int64"), + }}, + } + env.tmc.schema = schm + + fields := sqltypes.MakeTestFields( + "c1|c2", + "int64|int64", + ) + + testcases := []struct { + id string + source []*sqltypes.Result + target []*sqltypes.Result + dr *DiffReport + }{{ + id: "1", + source: sqltypes.MakeTestStreamingResults(fields, + "1|3", + "2|4", + "---", + "3|1", + ), + target: sqltypes.MakeTestStreamingResults(fields, + "1|3", + "---", + "2|4", + "3|1", + ), + dr: &DiffReport{ + ProcessedRows: 3, + MatchingRows: 3, + }, + }, { + id: "2", + source: sqltypes.MakeTestStreamingResults(fields, + "1|3", + ), + target: sqltypes.MakeTestStreamingResults(fields, + "1|3", + "---", + "2|4", + "3|1", + ), + dr: &DiffReport{ + ProcessedRows: 3, + MatchingRows: 1, + ExtraRowsTarget: 2, + }, + }, { + id: "3", + source: sqltypes.MakeTestStreamingResults(fields, + "1|3", + "---", + "2|4", + "3|1", + ), + target: sqltypes.MakeTestStreamingResults(fields, + "1|3", + ), + dr: &DiffReport{ + ProcessedRows: 3, + MatchingRows: 1, + ExtraRowsSource: 2, + }, + }, { + id: "4", + source: sqltypes.MakeTestStreamingResults(fields, + "1|3", + "---", + "2|4", + "3|1", + ), + target: sqltypes.MakeTestStreamingResults(fields, + "1|3", + "---", + "3|1", + ), + dr: &DiffReport{ + ProcessedRows: 3, + MatchingRows: 2, + ExtraRowsSource: 1, + }, + }, { + id: "5", + source: sqltypes.MakeTestStreamingResults(fields, + "1|3", + "---", + "3|1", + ), + target: sqltypes.MakeTestStreamingResults(fields, + "1|3", + "---", + "2|4", + "3|1", + ), + dr: &DiffReport{ + ProcessedRows: 3, + MatchingRows: 2, + ExtraRowsTarget: 1, + }, + }, { + id: "6", + source: sqltypes.MakeTestStreamingResults(fields, + "1|3", + "---", + "2|3", + "3|1", + ), + target: sqltypes.MakeTestStreamingResults(fields, + "1|3", + "---", + "2|4", + "3|1", + ), + dr: &DiffReport{ + ProcessedRows: 3, + MatchingRows: 2, + MismatchedRows: 1, + }, + }} + + for _, tcase := range testcases { + env.tablets[101].setResults("select c1, c2 from t1 order by c1 asc", vdiffSourceGtid, tcase.source) + env.tablets[201].setResults("select c1, c2 from t1 order by c1 asc", vdiffTargetMasterPosition, tcase.target) + + dr, err := env.wr.VDiff(context.Background(), "target", env.workflow, env.cell, env.cell, "replica", 30*time.Second, 1*time.Second, 1*time.Second, 1*time.Minute) + require.NoError(t, err) + assert.Equal(t, tcase.dr, dr["t1"], tcase.id) + } +} + +func TestVDiffSharded(t *testing.T) { + // Also test that highest position ""MariaDB/5-456-892" will be used + // if lower positions are found. + env := newTestVDiffEnv([]string{"-40", "40-"}, []string{"-80", "80-"}, "", map[string]string{ + "-40-80": "MariaDB/5-456-890", + "40-80-": "MariaDB/5-456-891", + }) + defer env.close() + + schm := &tabletmanagerdatapb.SchemaDefinition{ + TableDefinitions: []*tabletmanagerdatapb.TableDefinition{{ + Name: "t1", + Columns: []string{"c1", "c2"}, + PrimaryKeyColumns: []string{"c1"}, + Fields: sqltypes.MakeTestFields("c1|c2", "int64|int64"), + }}, + } + env.tmc.schema = schm + + query := "select c1, c2 from t1 order by c1 asc" + fields := sqltypes.MakeTestFields( + "c1|c2", + "int64|int64", + ) + + env.tablets[101].setResults( + query, + vdiffSourceGtid, + sqltypes.MakeTestStreamingResults(fields, + "1|3", + "2|4", + ), + ) + env.tablets[111].setResults( + query, + vdiffSourceGtid, + sqltypes.MakeTestStreamingResults(fields, + "3|4", + ), + ) + env.tablets[201].setResults( + query, + vdiffTargetMasterPosition, + sqltypes.MakeTestStreamingResults(fields, + "1|3", + ), + ) + env.tablets[211].setResults( + query, + vdiffTargetMasterPosition, + sqltypes.MakeTestStreamingResults(fields, + "2|4", + "3|4", + ), + ) + + dr, err := env.wr.VDiff(context.Background(), "target", env.workflow, env.cell, env.cell, "replica", 30*time.Second, 1*time.Second, 1*time.Second, 1*time.Minute) + require.NoError(t, err) + wantdr := &DiffReport{ + ProcessedRows: 3, + MatchingRows: 3, + } + assert.Equal(t, wantdr, dr["t1"]) +} + +func TestVDiffAggregates(t *testing.T) { + env := newTestVDiffEnv([]string{"-40", "40-"}, []string{"-80", "80-"}, "select c1, count(*) c2, sum(c3) c3 from t group by c1", nil) + defer env.close() + + schm := &tabletmanagerdatapb.SchemaDefinition{ + TableDefinitions: []*tabletmanagerdatapb.TableDefinition{{ + Name: "t1", + Columns: []string{"c1", "c2", "c3"}, + PrimaryKeyColumns: []string{"c1"}, + Fields: sqltypes.MakeTestFields("c1|c2|c3", "int64|int64|int64"), + }}, + } + env.tmc.schema = schm + + sourceQuery := "select c1, count(*) as c2, sum(c3) as c3 from t group by c1 order by c1 asc" + fields := sqltypes.MakeTestFields( + "c1|c2|c3", + "int64|int64|int64", + ) + + env.tablets[101].setResults( + sourceQuery, + vdiffSourceGtid, + sqltypes.MakeTestStreamingResults(fields, + "1|3|4", + "2|4|5", + "4|5|6", + ), + ) + env.tablets[111].setResults( + sourceQuery, + vdiffSourceGtid, + sqltypes.MakeTestStreamingResults(fields, + "1|1|1", + "3|2|2", + "5|3|3", + ), + ) + targetQuery := "select c1, c2, c3 from t1 order by c1 asc" + env.tablets[201].setResults( + targetQuery, + vdiffTargetMasterPosition, + sqltypes.MakeTestStreamingResults(fields, + "1|4|5", + "5|3|3", + ), + ) + env.tablets[211].setResults( + targetQuery, + vdiffTargetMasterPosition, + sqltypes.MakeTestStreamingResults(fields, + "2|4|5", + "3|2|2", + "4|5|6", + ), + ) + + dr, err := env.wr.VDiff(context.Background(), "target", env.workflow, env.cell, env.cell, "replica", 30*time.Second, 1*time.Second, 1*time.Second, 1*time.Minute) + require.NoError(t, err) + wantdr := &DiffReport{ + ProcessedRows: 5, + MatchingRows: 5, + } + assert.Equal(t, wantdr, dr["t1"]) +} + +func TestVDiffPKWeightString(t *testing.T) { + // Also test that highest position ""MariaDB/5-456-892" will be used + // if lower positions are found. + env := newTestVDiffEnv([]string{"-40", "40-"}, []string{"-80", "80-"}, "", nil) + defer env.close() + + schm := &tabletmanagerdatapb.SchemaDefinition{ + TableDefinitions: []*tabletmanagerdatapb.TableDefinition{{ + Name: "t1", + Columns: []string{"c1", "c2"}, + PrimaryKeyColumns: []string{"c1"}, + Fields: sqltypes.MakeTestFields("c1|c2", "varchar|int64"), + }}, + } + env.tmc.schema = schm + + query := "select c1, c2, weight_string(c1) from t1 order by c1 asc" + fields := sqltypes.MakeTestFields( + "c1|c2|weight_string(c1)", + "varchar|int64|varbinary", + ) + + env.tablets[101].setResults( + query, + vdiffSourceGtid, + sqltypes.MakeTestStreamingResults(fields, + "a|3|A", + "b|4|B", + ), + ) + env.tablets[111].setResults( + query, + vdiffSourceGtid, + sqltypes.MakeTestStreamingResults(fields, + "C|5|C", + "D|6|D", + ), + ) + env.tablets[201].setResults( + query, + vdiffTargetMasterPosition, + sqltypes.MakeTestStreamingResults(fields, + "A|3|A", + ), + ) + env.tablets[211].setResults( + query, + vdiffTargetMasterPosition, + sqltypes.MakeTestStreamingResults(fields, + "b|4|B", + "c|5|C", + "D|6|D", + ), + ) + + dr, err := env.wr.VDiff(context.Background(), "target", env.workflow, env.cell, env.cell, "replica", 30*time.Second, 1*time.Second, 1*time.Second, 1*time.Minute) + require.NoError(t, err) + wantdr := &DiffReport{ + ProcessedRows: 4, + MatchingRows: 4, + } + assert.Equal(t, wantdr, dr["t1"]) +} + +func TestVDiffNoPKWeightString(t *testing.T) { + // Also test that highest position ""MariaDB/5-456-892" will be used + // if lower positions are found. + env := newTestVDiffEnv([]string{"-40", "40-"}, []string{"-80", "80-"}, "", nil) + defer env.close() + + schm := &tabletmanagerdatapb.SchemaDefinition{ + TableDefinitions: []*tabletmanagerdatapb.TableDefinition{{ + Name: "t1", + Columns: []string{"c1", "c2"}, + PrimaryKeyColumns: []string{"c1"}, + Fields: sqltypes.MakeTestFields("c1|c2", "int64|varchar"), + }}, + } + env.tmc.schema = schm + + query := "select c1, c2, weight_string(c2) from t1 order by c1 asc" + fields := sqltypes.MakeTestFields( + "c1|c2|weight_string(c2)", + "int64|varchar|varbinary", + ) + + env.tablets[101].setResults( + query, + vdiffSourceGtid, + sqltypes.MakeTestStreamingResults(fields, + "3|a|A", + "4|b|B", + ), + ) + env.tablets[111].setResults( + query, + vdiffSourceGtid, + sqltypes.MakeTestStreamingResults(fields, + "5|C|C", + "6|D|D", + ), + ) + env.tablets[201].setResults( + query, + vdiffTargetMasterPosition, + sqltypes.MakeTestStreamingResults(fields, + "3|A|A", + ), + ) + env.tablets[211].setResults( + query, + vdiffTargetMasterPosition, + sqltypes.MakeTestStreamingResults(fields, + "4|b|B", + "5|c|C", + "6|D|D", + ), + ) + + dr, err := env.wr.VDiff(context.Background(), "target", env.workflow, env.cell, env.cell, "replica", 30*time.Second, 1*time.Second, 1*time.Second, 1*time.Minute) + require.NoError(t, err) + wantdr := &DiffReport{ + ProcessedRows: 4, + MatchingRows: 4, + } + assert.Equal(t, wantdr, dr["t1"]) +} + +func TestVDiffDefaults(t *testing.T) { + env := newTestVDiffEnv([]string{"0"}, []string{"0"}, "", nil) + defer env.close() + + schm := &tabletmanagerdatapb.SchemaDefinition{ + TableDefinitions: []*tabletmanagerdatapb.TableDefinition{{ + Name: "t1", + Columns: []string{"c1", "c2"}, + PrimaryKeyColumns: []string{"c1"}, + Fields: sqltypes.MakeTestFields("c1|c2", "int64|int64"), + }}, + } + env.tmc.schema = schm + + fields := sqltypes.MakeTestFields( + "c1|c2", + "int64|int64", + ) + + source := sqltypes.MakeTestStreamingResults(fields, + "1|3", + "2|4", + "---", + "3|1", + ) + target := source + env.tablets[101].setResults("select c1, c2 from t1 order by c1 asc", vdiffSourceGtid, source) + env.tablets[201].setResults("select c1, c2 from t1 order by c1 asc", vdiffTargetMasterPosition, target) + + _, err := env.wr.VDiff(context.Background(), "target", env.workflow, "", "", "replica", 30*time.Second, 1*time.Second, 1*time.Second, 1*time.Minute) + require.NoError(t, err) + _, err = env.wr.VDiff(context.Background(), "target", env.workflow, "", env.cell, "replica", 30*time.Second, 1*time.Second, 1*time.Second, 1*time.Minute) + require.NoError(t, err) + _, err = env.wr.VDiff(context.Background(), "target", env.workflow, env.cell, "", "replica", 30*time.Second, 1*time.Second, 1*time.Second, 1*time.Minute) + require.NoError(t, err) +} + +func TestVDiffReplicationWait(t *testing.T) { + env := newTestVDiffEnv([]string{"0"}, []string{"0"}, "", nil) + defer env.close() + + schm := &tabletmanagerdatapb.SchemaDefinition{ + TableDefinitions: []*tabletmanagerdatapb.TableDefinition{{ + Name: "t1", + Columns: []string{"c1", "c2"}, + PrimaryKeyColumns: []string{"c1"}, + Fields: sqltypes.MakeTestFields("c1|c2", "int64|int64"), + }}, + } + env.tmc.schema = schm + + fields := sqltypes.MakeTestFields( + "c1|c2", + "int64|int64", + ) + + source := sqltypes.MakeTestStreamingResults(fields, + "1|3", + "2|4", + "---", + "3|1", + ) + target := source + env.tablets[101].setResults("select c1, c2 from t1 order by c1 asc", vdiffSourceGtid, source) + env.tablets[201].setResults("select c1, c2 from t1 order by c1 asc", vdiffTargetMasterPosition, target) + + _, err := env.wr.VDiff(context.Background(), "target", env.workflow, env.cell, env.cell, "replica", 0*time.Second, 1*time.Second, 1*time.Second, 1*time.Minute) + require.EqualError(t, err, "startQueryStreams(sources): WaitForPosition for tablet cell-0000000101: context deadline exceeded") +} diff --git a/go/vt/wrangler/version.go b/go/vt/wrangler/version.go index 92256d7af0b..c33b3aa07da 100644 --- a/go/vt/wrangler/version.go +++ b/go/vt/wrangler/version.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/wrangler/wrangler.go b/go/vt/wrangler/wrangler.go index 36b25707fae..83672b0f880 100644 --- a/go/vt/wrangler/wrangler.go +++ b/go/vt/wrangler/wrangler.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/zkctl/zkconf.go b/go/vt/zkctl/zkconf.go index 360094e684d..a3e2169edc7 100644 --- a/go/vt/zkctl/zkconf.go +++ b/go/vt/zkctl/zkconf.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/zkctl/zkctl.go b/go/vt/zkctl/zkctl.go index 686eed07b43..fa79cb23370 100644 --- a/go/vt/zkctl/zkctl.go +++ b/go/vt/zkctl/zkctl.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/zkctl/zkctl_local.go b/go/vt/zkctl/zkctl_local.go index 0a5c763b7f3..dfb11e28cd6 100644 --- a/go/vt/zkctl/zkctl_local.go +++ b/go/vt/zkctl/zkctl_local.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/go/vt/zkctl/zkctl_test.go b/go/vt/zkctl/zkctl_test.go index 59b8ad01d1f..bcf1c531301 100644 --- a/go/vt/zkctl/zkctl_test.go +++ b/go/vt/zkctl/zkctl_test.go @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. diff --git a/go/vt/zkctl/zksrv.sh b/go/vt/zkctl/zksrv.sh index aada9b9b8aa..26479b373cb 100755 --- a/go/vt/zkctl/zksrv.sh +++ b/go/vt/zkctl/zksrv.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2017 Google Inc. +# 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. diff --git a/go/vtbench/client.go b/go/vtbench/client.go index e7672f1fff4..dc29d3dc423 100644 --- a/go/vtbench/client.go +++ b/go/vtbench/client.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Vitess Authors +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. diff --git a/go/vtbench/vtbench.go b/go/vtbench/vtbench.go index 5dad800899b..34e030297c4 100644 --- a/go/vtbench/vtbench.go +++ b/go/vtbench/vtbench.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Vitess Authors +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. @@ -119,7 +119,9 @@ func (b *Bench) Run(ctx context.Context) error { } b.createThreads(ctx) - b.runTest(ctx) + if err := b.runTest(ctx); err != nil { + return err + } return nil } diff --git a/helm/vitess/templates/_orchestrator-conf.tpl b/helm/vitess/templates/_orchestrator-conf.tpl index 93d8183e00f..950c0768ea0 100644 --- a/helm/vitess/templates/_orchestrator-conf.tpl +++ b/helm/vitess/templates/_orchestrator-conf.tpl @@ -14,7 +14,7 @@ metadata: name: orchestrator-cm data: orchestrator.conf.json: |- - { + { "ActiveNodeExpireSeconds": 5, "ApplyMySQLPromotionAfterMasterFailover": true, "AuditLogFile": "/tmp/orchestrator-audit.log", diff --git a/java/client/src/main/java/io/vitess/client/Context.java b/java/client/src/main/java/io/vitess/client/Context.java index c2a2bffcd98..28600cbf959 100644 --- a/java/client/src/main/java/io/vitess/client/Context.java +++ b/java/client/src/main/java/io/vitess/client/Context.java @@ -1,12 +1,12 @@ /* - * Copyright 2017 Google Inc. - * + * 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. diff --git a/java/client/src/main/java/io/vitess/client/Proto.java b/java/client/src/main/java/io/vitess/client/Proto.java index 2706a06fda4..64042d2926d 100644 --- a/java/client/src/main/java/io/vitess/client/Proto.java +++ b/java/client/src/main/java/io/vitess/client/Proto.java @@ -1,12 +1,12 @@ /* - * Copyright 2017 Google Inc. - * + * 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. diff --git a/java/client/src/main/java/io/vitess/client/RefreshableVTGateConnection.java b/java/client/src/main/java/io/vitess/client/RefreshableVTGateConnection.java index d1fb6d0621b..1dbda37254d 100644 --- a/java/client/src/main/java/io/vitess/client/RefreshableVTGateConnection.java +++ b/java/client/src/main/java/io/vitess/client/RefreshableVTGateConnection.java @@ -1,3 +1,19 @@ +/* + * 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 io.vitess.client; import java.io.File; diff --git a/java/client/src/main/java/io/vitess/client/RpcClient.java b/java/client/src/main/java/io/vitess/client/RpcClient.java index 4c83df8ec4b..a08e22745d4 100644 --- a/java/client/src/main/java/io/vitess/client/RpcClient.java +++ b/java/client/src/main/java/io/vitess/client/RpcClient.java @@ -1,12 +1,12 @@ /* - * Copyright 2017 Google Inc. - * + * 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. diff --git a/java/client/src/main/java/io/vitess/client/RpcClientFactory.java b/java/client/src/main/java/io/vitess/client/RpcClientFactory.java index 762f7105395..81ebaafc76b 100644 --- a/java/client/src/main/java/io/vitess/client/RpcClientFactory.java +++ b/java/client/src/main/java/io/vitess/client/RpcClientFactory.java @@ -1,12 +1,12 @@ /* - * Copyright 2017 Google Inc. - * + * 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. diff --git a/java/client/src/main/java/io/vitess/client/SQLFuture.java b/java/client/src/main/java/io/vitess/client/SQLFuture.java index 0afef6fd0ed..0fcfb4521bc 100644 --- a/java/client/src/main/java/io/vitess/client/SQLFuture.java +++ b/java/client/src/main/java/io/vitess/client/SQLFuture.java @@ -1,12 +1,12 @@ /* - * Copyright 2017 Google Inc. - * + * 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. diff --git a/java/client/src/main/java/io/vitess/client/StreamIterator.java b/java/client/src/main/java/io/vitess/client/StreamIterator.java index 7d97da0779a..8d471d887ef 100644 --- a/java/client/src/main/java/io/vitess/client/StreamIterator.java +++ b/java/client/src/main/java/io/vitess/client/StreamIterator.java @@ -1,12 +1,12 @@ /* - * Copyright 2017 Google Inc. - * + * 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. diff --git a/java/client/src/main/java/io/vitess/client/VTGateBlockingConn.java b/java/client/src/main/java/io/vitess/client/VTGateBlockingConn.java index d2aee89e0a0..36caf96960b 100644 --- a/java/client/src/main/java/io/vitess/client/VTGateBlockingConn.java +++ b/java/client/src/main/java/io/vitess/client/VTGateBlockingConn.java @@ -1,12 +1,12 @@ /* - * Copyright 2017 Google Inc. - * + * 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. diff --git a/java/client/src/main/java/io/vitess/client/VTGateBlockingConnection.java b/java/client/src/main/java/io/vitess/client/VTGateBlockingConnection.java index 1d29492333c..22684c98179 100644 --- a/java/client/src/main/java/io/vitess/client/VTGateBlockingConnection.java +++ b/java/client/src/main/java/io/vitess/client/VTGateBlockingConnection.java @@ -1,12 +1,12 @@ /* - * Copyright 2017 Google Inc. - * + * 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. diff --git a/java/client/src/main/java/io/vitess/client/VTGateBlockingTx.java b/java/client/src/main/java/io/vitess/client/VTGateBlockingTx.java index a44597e465c..87ecf482dff 100644 --- a/java/client/src/main/java/io/vitess/client/VTGateBlockingTx.java +++ b/java/client/src/main/java/io/vitess/client/VTGateBlockingTx.java @@ -1,12 +1,12 @@ /* - * Copyright 2017 Google Inc. - * + * 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. diff --git a/java/client/src/main/java/io/vitess/client/VTGateConn.java b/java/client/src/main/java/io/vitess/client/VTGateConn.java index 6a810327701..0431043a30b 100644 --- a/java/client/src/main/java/io/vitess/client/VTGateConn.java +++ b/java/client/src/main/java/io/vitess/client/VTGateConn.java @@ -1,12 +1,12 @@ /* - * Copyright 2017 Google Inc. - * + * 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. diff --git a/java/client/src/main/java/io/vitess/client/VTGateConnection.java b/java/client/src/main/java/io/vitess/client/VTGateConnection.java index 480de673a57..70c977d6f85 100644 --- a/java/client/src/main/java/io/vitess/client/VTGateConnection.java +++ b/java/client/src/main/java/io/vitess/client/VTGateConnection.java @@ -1,12 +1,12 @@ /* - * Copyright 2017 Google Inc. - * + * 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. diff --git a/java/client/src/main/java/io/vitess/client/VTGateTx.java b/java/client/src/main/java/io/vitess/client/VTGateTx.java index 4028bde21fa..52b20ec169d 100644 --- a/java/client/src/main/java/io/vitess/client/VTGateTx.java +++ b/java/client/src/main/java/io/vitess/client/VTGateTx.java @@ -1,12 +1,12 @@ /* - * Copyright 2017 Google Inc. - * + * 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. diff --git a/java/client/src/main/java/io/vitess/client/VTSession.java b/java/client/src/main/java/io/vitess/client/VTSession.java index 69978a12db5..9974e5f034a 100644 --- a/java/client/src/main/java/io/vitess/client/VTSession.java +++ b/java/client/src/main/java/io/vitess/client/VTSession.java @@ -1,12 +1,12 @@ /* - * Copyright 2017 Google Inc. - * + * 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. diff --git a/java/client/src/main/java/io/vitess/client/cursor/Cursor.java b/java/client/src/main/java/io/vitess/client/cursor/Cursor.java index f810bf99fd6..54218487184 100644 --- a/java/client/src/main/java/io/vitess/client/cursor/Cursor.java +++ b/java/client/src/main/java/io/vitess/client/cursor/Cursor.java @@ -1,12 +1,12 @@ /* - * Copyright 2017 Google Inc. - * + * 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. diff --git a/java/client/src/main/java/io/vitess/client/cursor/CursorWithError.java b/java/client/src/main/java/io/vitess/client/cursor/CursorWithError.java index 4051a0f7a79..a24813197c0 100644 --- a/java/client/src/main/java/io/vitess/client/cursor/CursorWithError.java +++ b/java/client/src/main/java/io/vitess/client/cursor/CursorWithError.java @@ -1,12 +1,12 @@ /* - * Copyright 2017 Google Inc. - * + * 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. diff --git a/java/client/src/main/java/io/vitess/client/cursor/FieldMap.java b/java/client/src/main/java/io/vitess/client/cursor/FieldMap.java index d34c13ab623..19fa696427c 100644 --- a/java/client/src/main/java/io/vitess/client/cursor/FieldMap.java +++ b/java/client/src/main/java/io/vitess/client/cursor/FieldMap.java @@ -1,12 +1,12 @@ /* - * Copyright 2017 Google Inc. - * + * 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. diff --git a/java/client/src/main/java/io/vitess/client/cursor/Row.java b/java/client/src/main/java/io/vitess/client/cursor/Row.java index b232fb6d8aa..b62358e2f5f 100644 --- a/java/client/src/main/java/io/vitess/client/cursor/Row.java +++ b/java/client/src/main/java/io/vitess/client/cursor/Row.java @@ -1,12 +1,12 @@ /* - * Copyright 2017 Google Inc. - * + * 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. diff --git a/java/client/src/main/java/io/vitess/client/cursor/SimpleCursor.java b/java/client/src/main/java/io/vitess/client/cursor/SimpleCursor.java index 69fe26d14e9..8ab0844aa93 100644 --- a/java/client/src/main/java/io/vitess/client/cursor/SimpleCursor.java +++ b/java/client/src/main/java/io/vitess/client/cursor/SimpleCursor.java @@ -1,12 +1,12 @@ /* - * Copyright 2017 Google Inc. - * + * 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. diff --git a/java/client/src/main/java/io/vitess/client/cursor/StreamCursor.java b/java/client/src/main/java/io/vitess/client/cursor/StreamCursor.java index 1ef5971ad73..c5e7e9bca24 100644 --- a/java/client/src/main/java/io/vitess/client/cursor/StreamCursor.java +++ b/java/client/src/main/java/io/vitess/client/cursor/StreamCursor.java @@ -1,12 +1,12 @@ /* - * Copyright 2017 Google Inc. - * + * 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. diff --git a/java/client/src/main/java/io/vitess/client/grpc/tls/TlsOptions.java b/java/client/src/main/java/io/vitess/client/grpc/tls/TlsOptions.java index a97fa3151ec..ffd570d413b 100644 --- a/java/client/src/main/java/io/vitess/client/grpc/tls/TlsOptions.java +++ b/java/client/src/main/java/io/vitess/client/grpc/tls/TlsOptions.java @@ -1,12 +1,12 @@ /* - * Copyright 2017 Google Inc. - * + * 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. diff --git a/java/client/src/main/java/io/vitess/mysql/DateTime.java b/java/client/src/main/java/io/vitess/mysql/DateTime.java index e5f9ef13e4d..0975d9aeb45 100644 --- a/java/client/src/main/java/io/vitess/mysql/DateTime.java +++ b/java/client/src/main/java/io/vitess/mysql/DateTime.java @@ -1,12 +1,12 @@ /* - * Copyright 2017 Google Inc. - * + * 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. diff --git a/java/client/src/test/java/io/vitess/client/BindVarTest.java b/java/client/src/test/java/io/vitess/client/BindVarTest.java index dee81b8ea66..6d60eab7363 100644 --- a/java/client/src/test/java/io/vitess/client/BindVarTest.java +++ b/java/client/src/test/java/io/vitess/client/BindVarTest.java @@ -1,12 +1,12 @@ /* - * Copyright 2017 Google Inc. - * + * 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. diff --git a/java/client/src/test/java/io/vitess/client/EntityIdTest.java b/java/client/src/test/java/io/vitess/client/EntityIdTest.java index 1359d487904..b614fcff2c0 100644 --- a/java/client/src/test/java/io/vitess/client/EntityIdTest.java +++ b/java/client/src/test/java/io/vitess/client/EntityIdTest.java @@ -1,12 +1,12 @@ /* - * Copyright 2017 Google Inc. - * + * 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. diff --git a/java/client/src/test/java/io/vitess/client/ProtoTest.java b/java/client/src/test/java/io/vitess/client/ProtoTest.java index d52d6551971..e92f2238114 100644 --- a/java/client/src/test/java/io/vitess/client/ProtoTest.java +++ b/java/client/src/test/java/io/vitess/client/ProtoTest.java @@ -1,12 +1,12 @@ /* - * Copyright 2017 Google Inc. - * + * 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. diff --git a/java/client/src/test/java/io/vitess/client/RpcClientTest.java b/java/client/src/test/java/io/vitess/client/RpcClientTest.java index 750cebff67f..048fffb4569 100644 --- a/java/client/src/test/java/io/vitess/client/RpcClientTest.java +++ b/java/client/src/test/java/io/vitess/client/RpcClientTest.java @@ -1,12 +1,12 @@ /* - * Copyright 2017 Google Inc. - * + * 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. diff --git a/java/client/src/test/java/io/vitess/client/TestEnv.java b/java/client/src/test/java/io/vitess/client/TestEnv.java index f9b9d0dabd3..1e631e8bfb4 100644 --- a/java/client/src/test/java/io/vitess/client/TestEnv.java +++ b/java/client/src/test/java/io/vitess/client/TestEnv.java @@ -1,12 +1,12 @@ /* - * Copyright 2017 Google Inc. - * + * 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. diff --git a/java/client/src/test/java/io/vitess/client/TestUtil.java b/java/client/src/test/java/io/vitess/client/TestUtil.java index 563874f47b4..e90e57941d7 100644 --- a/java/client/src/test/java/io/vitess/client/TestUtil.java +++ b/java/client/src/test/java/io/vitess/client/TestUtil.java @@ -1,12 +1,12 @@ /* - * Copyright 2017 Google Inc. - * + * 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. diff --git a/java/client/src/test/java/io/vitess/client/cursor/CursorTest.java b/java/client/src/test/java/io/vitess/client/cursor/CursorTest.java index 809607e00a9..b84ed4bc3fb 100644 --- a/java/client/src/test/java/io/vitess/client/cursor/CursorTest.java +++ b/java/client/src/test/java/io/vitess/client/cursor/CursorTest.java @@ -1,12 +1,12 @@ /* - * Copyright 2017 Google Inc. - * + * 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. diff --git a/java/client/src/test/java/io/vitess/mysql/DateTimeTest.java b/java/client/src/test/java/io/vitess/mysql/DateTimeTest.java index 59bd0c7ea19..9c45c088d00 100644 --- a/java/client/src/test/java/io/vitess/mysql/DateTimeTest.java +++ b/java/client/src/test/java/io/vitess/mysql/DateTimeTest.java @@ -1,12 +1,12 @@ /* - * Copyright 2017 Google Inc. - * + * 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. diff --git a/java/example/src/main/java/io/vitess/example/VitessClientExample.java b/java/example/src/main/java/io/vitess/example/VitessClientExample.java index de5e95a3e43..e407f91bf43 100644 --- a/java/example/src/main/java/io/vitess/example/VitessClientExample.java +++ b/java/example/src/main/java/io/vitess/example/VitessClientExample.java @@ -1,12 +1,12 @@ /* - * Copyright 2017 Google Inc. - * + * 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. diff --git a/java/example/src/main/java/io/vitess/example/VitessJDBCExample.java b/java/example/src/main/java/io/vitess/example/VitessJDBCExample.java index 1c6b18a17a9..f63bbeca946 100644 --- a/java/example/src/main/java/io/vitess/example/VitessJDBCExample.java +++ b/java/example/src/main/java/io/vitess/example/VitessJDBCExample.java @@ -1,12 +1,12 @@ /* - * Copyright 2017 Google Inc. - * + * 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. diff --git a/java/grpc-client/src/main/java/io/vitess/client/grpc/Constants.java b/java/grpc-client/src/main/java/io/vitess/client/grpc/Constants.java index 950c9d351ad..075d6317ec4 100644 --- a/java/grpc-client/src/main/java/io/vitess/client/grpc/Constants.java +++ b/java/grpc-client/src/main/java/io/vitess/client/grpc/Constants.java @@ -1,12 +1,12 @@ /* - * Copyright 2017 Google Inc. - * + * 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. diff --git a/java/grpc-client/src/main/java/io/vitess/client/grpc/GrpcClient.java b/java/grpc-client/src/main/java/io/vitess/client/grpc/GrpcClient.java index 2f2587fbd3f..a8285f26806 100644 --- a/java/grpc-client/src/main/java/io/vitess/client/grpc/GrpcClient.java +++ b/java/grpc-client/src/main/java/io/vitess/client/grpc/GrpcClient.java @@ -1,12 +1,12 @@ /* - * Copyright 2017 Google Inc. - * + * 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. diff --git a/java/grpc-client/src/main/java/io/vitess/client/grpc/GrpcClientFactory.java b/java/grpc-client/src/main/java/io/vitess/client/grpc/GrpcClientFactory.java index 18f629c9836..0cd5fdedf4f 100644 --- a/java/grpc-client/src/main/java/io/vitess/client/grpc/GrpcClientFactory.java +++ b/java/grpc-client/src/main/java/io/vitess/client/grpc/GrpcClientFactory.java @@ -1,12 +1,12 @@ /* - * Copyright 2017 Google Inc. - * + * 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. diff --git a/java/grpc-client/src/main/java/io/vitess/client/grpc/GrpcStreamAdapter.java b/java/grpc-client/src/main/java/io/vitess/client/grpc/GrpcStreamAdapter.java index d8b6b12aff7..4617f6642ce 100644 --- a/java/grpc-client/src/main/java/io/vitess/client/grpc/GrpcStreamAdapter.java +++ b/java/grpc-client/src/main/java/io/vitess/client/grpc/GrpcStreamAdapter.java @@ -1,12 +1,12 @@ /* - * Copyright 2017 Google Inc. - * + * 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. diff --git a/java/grpc-client/src/main/java/io/vitess/client/grpc/RetryingInterceptor.java b/java/grpc-client/src/main/java/io/vitess/client/grpc/RetryingInterceptor.java index 1991772df35..9323a1b00d4 100644 --- a/java/grpc-client/src/main/java/io/vitess/client/grpc/RetryingInterceptor.java +++ b/java/grpc-client/src/main/java/io/vitess/client/grpc/RetryingInterceptor.java @@ -1,3 +1,19 @@ +/* + * 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 io.vitess.client.grpc; import static com.google.common.base.Preconditions.checkState; diff --git a/java/grpc-client/src/main/java/io/vitess/client/grpc/RetryingInterceptorConfig.java b/java/grpc-client/src/main/java/io/vitess/client/grpc/RetryingInterceptorConfig.java index f3d3f0eeb76..d27cf126e9a 100644 --- a/java/grpc-client/src/main/java/io/vitess/client/grpc/RetryingInterceptorConfig.java +++ b/java/grpc-client/src/main/java/io/vitess/client/grpc/RetryingInterceptorConfig.java @@ -1,3 +1,19 @@ +/* + * 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 io.vitess.client.grpc; /** diff --git a/java/grpc-client/src/main/java/io/vitess/client/grpc/StaticAuthCredentials.java b/java/grpc-client/src/main/java/io/vitess/client/grpc/StaticAuthCredentials.java index d04754ee5d8..4fa119b0e7d 100644 --- a/java/grpc-client/src/main/java/io/vitess/client/grpc/StaticAuthCredentials.java +++ b/java/grpc-client/src/main/java/io/vitess/client/grpc/StaticAuthCredentials.java @@ -1,3 +1,19 @@ +/* + * 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 io.vitess.client.grpc; import io.grpc.Attributes; diff --git a/java/grpc-client/src/test/java/io/client/grpc/GrpcClientStaticAuthTest.java b/java/grpc-client/src/test/java/io/client/grpc/GrpcClientStaticAuthTest.java index 1148406412e..3666b489d2f 100644 --- a/java/grpc-client/src/test/java/io/client/grpc/GrpcClientStaticAuthTest.java +++ b/java/grpc-client/src/test/java/io/client/grpc/GrpcClientStaticAuthTest.java @@ -1,3 +1,19 @@ +/* + * 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 io.client.grpc; import com.google.common.base.Throwables; diff --git a/java/grpc-client/src/test/java/io/client/grpc/GrpcClientTest.java b/java/grpc-client/src/test/java/io/client/grpc/GrpcClientTest.java index 18e69eaba21..7bf485af3a2 100644 --- a/java/grpc-client/src/test/java/io/client/grpc/GrpcClientTest.java +++ b/java/grpc-client/src/test/java/io/client/grpc/GrpcClientTest.java @@ -1,12 +1,12 @@ /* - * Copyright 2017 Google Inc. - * + * 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. diff --git a/java/grpc-client/src/test/java/io/client/grpc/GrpcClientTlsClientAuthTest.java b/java/grpc-client/src/test/java/io/client/grpc/GrpcClientTlsClientAuthTest.java index 19f2d4de91a..92c80e7d15b 100644 --- a/java/grpc-client/src/test/java/io/client/grpc/GrpcClientTlsClientAuthTest.java +++ b/java/grpc-client/src/test/java/io/client/grpc/GrpcClientTlsClientAuthTest.java @@ -1,12 +1,12 @@ /* - * Copyright 2017 Google Inc. - * + * 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. diff --git a/java/grpc-client/src/test/java/io/client/grpc/GrpcClientTlsTest.java b/java/grpc-client/src/test/java/io/client/grpc/GrpcClientTlsTest.java index f0c44616de4..d3a6eac9ac1 100644 --- a/java/grpc-client/src/test/java/io/client/grpc/GrpcClientTlsTest.java +++ b/java/grpc-client/src/test/java/io/client/grpc/GrpcClientTlsTest.java @@ -1,12 +1,12 @@ /* - * Copyright 2017 Google Inc. - * + * 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. diff --git a/java/grpc-client/src/test/java/io/client/grpc/GrpcClientWithRetriesTest.java b/java/grpc-client/src/test/java/io/client/grpc/GrpcClientWithRetriesTest.java index f876e48fd53..29496934aca 100644 --- a/java/grpc-client/src/test/java/io/client/grpc/GrpcClientWithRetriesTest.java +++ b/java/grpc-client/src/test/java/io/client/grpc/GrpcClientWithRetriesTest.java @@ -1,3 +1,19 @@ +/* + * 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 io.client.grpc; import io.vitess.client.Context; diff --git a/java/grpc-client/src/test/java/io/vitess/client/grpc/RetryingInterceptorTest.java b/java/grpc-client/src/test/java/io/vitess/client/grpc/RetryingInterceptorTest.java index 9e325c7de68..376a920ad31 100644 --- a/java/grpc-client/src/test/java/io/vitess/client/grpc/RetryingInterceptorTest.java +++ b/java/grpc-client/src/test/java/io/vitess/client/grpc/RetryingInterceptorTest.java @@ -1,3 +1,19 @@ +/* + * 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 io.vitess.client.grpc; import com.google.common.util.concurrent.ListenableFuture; diff --git a/java/hadoop/src/main/java/io/vitess/hadoop/RowWritable.java b/java/hadoop/src/main/java/io/vitess/hadoop/RowWritable.java index d349d8ae550..ca91d512ed9 100644 --- a/java/hadoop/src/main/java/io/vitess/hadoop/RowWritable.java +++ b/java/hadoop/src/main/java/io/vitess/hadoop/RowWritable.java @@ -1,12 +1,12 @@ /* - * Copyright 2017 Google Inc. - * + * 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. diff --git a/java/hadoop/src/main/java/io/vitess/hadoop/VitessConf.java b/java/hadoop/src/main/java/io/vitess/hadoop/VitessConf.java index c70c4b22f01..e2e27d5682f 100644 --- a/java/hadoop/src/main/java/io/vitess/hadoop/VitessConf.java +++ b/java/hadoop/src/main/java/io/vitess/hadoop/VitessConf.java @@ -1,12 +1,12 @@ /* - * Copyright 2017 Google Inc. - * + * 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. diff --git a/java/hadoop/src/main/java/io/vitess/hadoop/VitessInputFormat.java b/java/hadoop/src/main/java/io/vitess/hadoop/VitessInputFormat.java index 97d06b845a1..5a9326980d8 100644 --- a/java/hadoop/src/main/java/io/vitess/hadoop/VitessInputFormat.java +++ b/java/hadoop/src/main/java/io/vitess/hadoop/VitessInputFormat.java @@ -1,12 +1,12 @@ /* - * Copyright 2017 Google Inc. - * + * 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. diff --git a/java/hadoop/src/main/java/io/vitess/hadoop/VitessInputSplit.java b/java/hadoop/src/main/java/io/vitess/hadoop/VitessInputSplit.java index e32edf4c9fc..251bdf1f763 100644 --- a/java/hadoop/src/main/java/io/vitess/hadoop/VitessInputSplit.java +++ b/java/hadoop/src/main/java/io/vitess/hadoop/VitessInputSplit.java @@ -1,12 +1,12 @@ /* - * Copyright 2017 Google Inc. - * + * 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. diff --git a/java/hadoop/src/main/java/io/vitess/hadoop/VitessRecordReader.java b/java/hadoop/src/main/java/io/vitess/hadoop/VitessRecordReader.java index e8b83d9d6ce..0f649f281e6 100644 --- a/java/hadoop/src/main/java/io/vitess/hadoop/VitessRecordReader.java +++ b/java/hadoop/src/main/java/io/vitess/hadoop/VitessRecordReader.java @@ -1,12 +1,12 @@ /* - * Copyright 2017 Google Inc. - * + * 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. @@ -51,7 +51,7 @@ public class VitessRecordReader extends RecordReader private Query.ExecuteOptions.IncludedFields includedFields; /** - * Fetch connection parameters from Configuraiton and open VtGate connection. + * Fetch connection parameters from Configuration and open VtGate connection. */ @Override public void initialize(InputSplit split, TaskAttemptContext context) diff --git a/java/hadoop/src/test/java/io/vitess/hadoop/MapReduceIT.java b/java/hadoop/src/test/java/io/vitess/hadoop/MapReduceIT.java index 5ee19911543..01e20b6eaf4 100644 --- a/java/hadoop/src/test/java/io/vitess/hadoop/MapReduceIT.java +++ b/java/hadoop/src/test/java/io/vitess/hadoop/MapReduceIT.java @@ -1,12 +1,12 @@ /* - * Copyright 2017 Google Inc. - * + * 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. diff --git a/java/jdbc/src/main/java/io/vitess/jdbc/ConnectionProperties.java b/java/jdbc/src/main/java/io/vitess/jdbc/ConnectionProperties.java index 18a9384ea30..40b0a996e74 100644 --- a/java/jdbc/src/main/java/io/vitess/jdbc/ConnectionProperties.java +++ b/java/jdbc/src/main/java/io/vitess/jdbc/ConnectionProperties.java @@ -1,12 +1,12 @@ /* - * Copyright 2017 Google Inc. - * + * 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. @@ -231,7 +231,7 @@ public int compare(Field o1, Field o2) { "The password protecting the truststore file (if a password is set)", null, null); private StringConnectionProperty trustAlias = new StringConnectionProperty( Constants.Property.TRUST_ALIAS, - "Alias under which the certficate chain is stored in the truststore file (if not specified," + "Alias under which the certificate chain is stored in the truststore file (if not specified," + " then " + "the first valid `X509Certificate` will be used)", null, null); diff --git a/java/jdbc/src/main/java/io/vitess/jdbc/DBProperties.java b/java/jdbc/src/main/java/io/vitess/jdbc/DBProperties.java index e510df6bd65..a49d50f19cb 100644 --- a/java/jdbc/src/main/java/io/vitess/jdbc/DBProperties.java +++ b/java/jdbc/src/main/java/io/vitess/jdbc/DBProperties.java @@ -1,12 +1,12 @@ /* - * Copyright 2017 Google Inc. - * + * 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. diff --git a/java/jdbc/src/main/java/io/vitess/jdbc/FieldWithMetadata.java b/java/jdbc/src/main/java/io/vitess/jdbc/FieldWithMetadata.java index 1f1eca52c6f..4616bc08921 100644 --- a/java/jdbc/src/main/java/io/vitess/jdbc/FieldWithMetadata.java +++ b/java/jdbc/src/main/java/io/vitess/jdbc/FieldWithMetadata.java @@ -1,12 +1,12 @@ /* - * Copyright 2017 Google Inc. - * + * 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. diff --git a/java/jdbc/src/main/java/io/vitess/jdbc/VitessConnection.java b/java/jdbc/src/main/java/io/vitess/jdbc/VitessConnection.java index 1dac94c92a6..5e51ff908dc 100644 --- a/java/jdbc/src/main/java/io/vitess/jdbc/VitessConnection.java +++ b/java/jdbc/src/main/java/io/vitess/jdbc/VitessConnection.java @@ -1,12 +1,12 @@ /* - * Copyright 2017 Google Inc. - * + * 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. @@ -339,7 +339,7 @@ public void setTransactionIsolation(int level) throws SQLException { /** * Return Warnings *

- * TODO: Not implementing as Error is Thrown when occured + * TODO: Not implementing as Error is Thrown when occurred * * @return SQLWarning or null */ diff --git a/java/jdbc/src/main/java/io/vitess/jdbc/VitessDatabaseMetaData.java b/java/jdbc/src/main/java/io/vitess/jdbc/VitessDatabaseMetaData.java index a037ab5ce35..3dafd8bca45 100644 --- a/java/jdbc/src/main/java/io/vitess/jdbc/VitessDatabaseMetaData.java +++ b/java/jdbc/src/main/java/io/vitess/jdbc/VitessDatabaseMetaData.java @@ -1,12 +1,12 @@ /* - * Copyright 2017 Google Inc. - * + * 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. diff --git a/java/jdbc/src/main/java/io/vitess/jdbc/VitessDriver.java b/java/jdbc/src/main/java/io/vitess/jdbc/VitessDriver.java index ce6c96c9dd3..5179e5c4831 100644 --- a/java/jdbc/src/main/java/io/vitess/jdbc/VitessDriver.java +++ b/java/jdbc/src/main/java/io/vitess/jdbc/VitessDriver.java @@ -1,12 +1,12 @@ /* - * Copyright 2017 Google Inc. - * + * 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. 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 c91c7a3342d..6234d037807 100644 --- a/java/jdbc/src/main/java/io/vitess/jdbc/VitessJDBCUrl.java +++ b/java/jdbc/src/main/java/io/vitess/jdbc/VitessJDBCUrl.java @@ -1,12 +1,12 @@ /* - * Copyright 2017 Google Inc. - * + * 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. diff --git a/java/jdbc/src/main/java/io/vitess/jdbc/VitessMariaDBDatabaseMetadata.java b/java/jdbc/src/main/java/io/vitess/jdbc/VitessMariaDBDatabaseMetadata.java index e372f150996..ed493cf9b82 100644 --- a/java/jdbc/src/main/java/io/vitess/jdbc/VitessMariaDBDatabaseMetadata.java +++ b/java/jdbc/src/main/java/io/vitess/jdbc/VitessMariaDBDatabaseMetadata.java @@ -1,12 +1,12 @@ /* - * Copyright 2017 Google Inc. - * + * 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. 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 2a04e89aee1..bced97dce76 100644 --- a/java/jdbc/src/main/java/io/vitess/jdbc/VitessMySQLDatabaseMetadata.java +++ b/java/jdbc/src/main/java/io/vitess/jdbc/VitessMySQLDatabaseMetadata.java @@ -1,12 +1,12 @@ /* - * Copyright 2017 Google Inc. - * + * 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. 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 d6c2b2a1340..8bb880e3749 100644 --- a/java/jdbc/src/main/java/io/vitess/jdbc/VitessParameterMetaData.java +++ b/java/jdbc/src/main/java/io/vitess/jdbc/VitessParameterMetaData.java @@ -1,12 +1,12 @@ /* - * Copyright 2017 Google Inc. - * + * 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. 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 19142fd4884..550b5180e11 100644 --- a/java/jdbc/src/main/java/io/vitess/jdbc/VitessPreparedStatement.java +++ b/java/jdbc/src/main/java/io/vitess/jdbc/VitessPreparedStatement.java @@ -1,12 +1,12 @@ /* - * Copyright 2017 Google Inc. - * + * 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. diff --git a/java/jdbc/src/main/java/io/vitess/jdbc/VitessResultSet.java b/java/jdbc/src/main/java/io/vitess/jdbc/VitessResultSet.java index 4b026a5fa0c..51995621548 100644 --- a/java/jdbc/src/main/java/io/vitess/jdbc/VitessResultSet.java +++ b/java/jdbc/src/main/java/io/vitess/jdbc/VitessResultSet.java @@ -1,12 +1,12 @@ /* - * Copyright 2017 Google Inc. - * + * 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. diff --git a/java/jdbc/src/main/java/io/vitess/jdbc/VitessResultSetMetaData.java b/java/jdbc/src/main/java/io/vitess/jdbc/VitessResultSetMetaData.java index eaa54e9d570..33cdca00f3a 100644 --- a/java/jdbc/src/main/java/io/vitess/jdbc/VitessResultSetMetaData.java +++ b/java/jdbc/src/main/java/io/vitess/jdbc/VitessResultSetMetaData.java @@ -1,12 +1,12 @@ /* - * Copyright 2017 Google Inc. - * + * 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. diff --git a/java/jdbc/src/main/java/io/vitess/jdbc/VitessStatement.java b/java/jdbc/src/main/java/io/vitess/jdbc/VitessStatement.java index 0ebc0cb0635..ddaf813af2d 100644 --- a/java/jdbc/src/main/java/io/vitess/jdbc/VitessStatement.java +++ b/java/jdbc/src/main/java/io/vitess/jdbc/VitessStatement.java @@ -1,12 +1,12 @@ /* - * Copyright 2017 Google Inc. - * + * 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. diff --git a/java/jdbc/src/main/java/io/vitess/jdbc/VitessVTGateManager.java b/java/jdbc/src/main/java/io/vitess/jdbc/VitessVTGateManager.java index 884f34e364e..3854251e3a8 100644 --- a/java/jdbc/src/main/java/io/vitess/jdbc/VitessVTGateManager.java +++ b/java/jdbc/src/main/java/io/vitess/jdbc/VitessVTGateManager.java @@ -1,12 +1,12 @@ /* - * Copyright 2017 Google Inc. - * + * 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. diff --git a/java/jdbc/src/main/java/io/vitess/util/CommonUtils.java b/java/jdbc/src/main/java/io/vitess/util/CommonUtils.java index 4612542d3bc..08516507824 100644 --- a/java/jdbc/src/main/java/io/vitess/util/CommonUtils.java +++ b/java/jdbc/src/main/java/io/vitess/util/CommonUtils.java @@ -1,12 +1,12 @@ /* - * Copyright 2017 Google Inc. - * + * 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. diff --git a/java/jdbc/src/main/java/io/vitess/util/Constants.java b/java/jdbc/src/main/java/io/vitess/util/Constants.java index 78666e7ed88..3c94fd65da4 100644 --- a/java/jdbc/src/main/java/io/vitess/util/Constants.java +++ b/java/jdbc/src/main/java/io/vitess/util/Constants.java @@ -1,12 +1,12 @@ /* - * Copyright 2017 Google Inc. - * + * 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. @@ -42,7 +42,7 @@ public class Constants { public static final int DRIVER_MAJOR_VERSION = 2; public static final int DRIVER_MINOR_VERSION = 2; public static final int MAX_BUFFER_SIZE = 65535; - //Default Timeout in miliseconds + //Default Timeout in milliseconds public static final int DEFAULT_TIMEOUT = 30000; public static final String VITESS_KEYSPACE = "Keyspace name in Vitess Server"; public static final Constants.QueryExecuteType DEFAULT_EXECUTE_TYPE = QueryExecuteType.SIMPLE; diff --git a/java/jdbc/src/main/java/io/vitess/util/MysqlDefs.java b/java/jdbc/src/main/java/io/vitess/util/MysqlDefs.java index c52ee81f41a..6edd18353e3 100644 --- a/java/jdbc/src/main/java/io/vitess/util/MysqlDefs.java +++ b/java/jdbc/src/main/java/io/vitess/util/MysqlDefs.java @@ -1,12 +1,12 @@ /* - * Copyright 2017 Google Inc. - * + * 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. diff --git a/java/jdbc/src/main/java/io/vitess/util/StringUtils.java b/java/jdbc/src/main/java/io/vitess/util/StringUtils.java index 4173f025e7f..a6bb406bad7 100644 --- a/java/jdbc/src/main/java/io/vitess/util/StringUtils.java +++ b/java/jdbc/src/main/java/io/vitess/util/StringUtils.java @@ -1,12 +1,12 @@ /* - * Copyright 2017 Google Inc. - * + * 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. @@ -550,7 +550,7 @@ public static String quoteIdentifier(String identifier, String quoteChar) { * * @param startingPosition the position to start the search from * @param searchIn the string to search in - * @param searchFor the array of strings to search for + * @param searchForSequence the array of strings to search for * @param openingMarkers characters which delimit the beginning of a text block to skip * @param closingMarkers characters which delimit the end of a text block to skip * @param searchMode a Set, ideally an EnumSet, containing the flags 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 1d502a180e9..c1388bfb7bb 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 @@ -1,12 +1,12 @@ /* - * Copyright 2017 Google Inc. - * + * 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. 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 53c095f623e..31548686655 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 @@ -1,12 +1,12 @@ /* - * Copyright 2017 Google Inc. - * + * 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. 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 78447d31e73..fad94cb8dcb 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 @@ -1,12 +1,12 @@ /* - * Copyright 2017 Google Inc. - * + * 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. diff --git a/java/jdbc/src/test/java/io/vitess/jdbc/BaseTest.java b/java/jdbc/src/test/java/io/vitess/jdbc/BaseTest.java index c677a376674..380527a7bf9 100644 --- a/java/jdbc/src/test/java/io/vitess/jdbc/BaseTest.java +++ b/java/jdbc/src/test/java/io/vitess/jdbc/BaseTest.java @@ -1,12 +1,12 @@ /* - * Copyright 2017 Google Inc. - * + * 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. diff --git a/java/jdbc/src/test/java/io/vitess/jdbc/ConnectionPropertiesTest.java b/java/jdbc/src/test/java/io/vitess/jdbc/ConnectionPropertiesTest.java index f7c2dccb63e..c30b404ebf1 100644 --- a/java/jdbc/src/test/java/io/vitess/jdbc/ConnectionPropertiesTest.java +++ b/java/jdbc/src/test/java/io/vitess/jdbc/ConnectionPropertiesTest.java @@ -1,12 +1,12 @@ /* - * Copyright 2017 Google Inc. - * + * 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. 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 a112d3c154f..d9d5294e89e 100644 --- a/java/jdbc/src/test/java/io/vitess/jdbc/FieldWithMetadataTest.java +++ b/java/jdbc/src/test/java/io/vitess/jdbc/FieldWithMetadataTest.java @@ -1,12 +1,12 @@ /* - * Copyright 2017 Google Inc. - * + * 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. @@ -65,7 +65,7 @@ public void testBlobRemapping() throws SQLException { conn.setBlobsAreStrings(true); Query.Field raw = Query.Field.newBuilder().setTable("#sql_my_temptable") - .setCharset(/* latin1, doesn't matter just dont want utf8 for now */ 5) + .setCharset(/* latin1, doesn't matter just don't want utf8 for now */ 5) .setFlags(Query.MySqlFlag.BINARY_FLAG_VALUE).setType(Query.Type.BLOB).setName("foo") .setOrgName("foo").build(); 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 73d312521ff..415790ed3f4 100644 --- a/java/jdbc/src/test/java/io/vitess/jdbc/VitessConnectionTest.java +++ b/java/jdbc/src/test/java/io/vitess/jdbc/VitessConnectionTest.java @@ -1,12 +1,12 @@ /* - * Copyright 2017 Google Inc. - * + * 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. 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 9da77d6f039..92d5cfede9b 100644 --- a/java/jdbc/src/test/java/io/vitess/jdbc/VitessDatabaseMetadataTest.java +++ b/java/jdbc/src/test/java/io/vitess/jdbc/VitessDatabaseMetadataTest.java @@ -1,12 +1,12 @@ /* - * Copyright 2017 Google Inc. - * + * 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. @@ -1436,7 +1436,7 @@ public void getUserNameTest() { Assert.assertEquals("username", vitessDatabaseMetaData.getUserName()); } catch (SQLException e) { - Assert.fail("Exception Occured: " + e.getMessage()); + Assert.fail("Exception occurred: " + e.getMessage()); } } diff --git a/java/jdbc/src/test/java/io/vitess/jdbc/VitessDriverTest.java b/java/jdbc/src/test/java/io/vitess/jdbc/VitessDriverTest.java index 37e5d176215..5043bb521ad 100644 --- a/java/jdbc/src/test/java/io/vitess/jdbc/VitessDriverTest.java +++ b/java/jdbc/src/test/java/io/vitess/jdbc/VitessDriverTest.java @@ -1,12 +1,12 @@ /* - * Copyright 2017 Google Inc. - * + * 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. diff --git a/java/jdbc/src/test/java/io/vitess/jdbc/VitessJDBCUrlTest.java b/java/jdbc/src/test/java/io/vitess/jdbc/VitessJDBCUrlTest.java index 60cb1829107..016216ce01c 100644 --- a/java/jdbc/src/test/java/io/vitess/jdbc/VitessJDBCUrlTest.java +++ b/java/jdbc/src/test/java/io/vitess/jdbc/VitessJDBCUrlTest.java @@ -1,12 +1,12 @@ /* - * Copyright 2017 Google Inc. - * + * 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. 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 a7374dfe47c..8916063ffaf 100644 --- a/java/jdbc/src/test/java/io/vitess/jdbc/VitessParameterMetaDataTest.java +++ b/java/jdbc/src/test/java/io/vitess/jdbc/VitessParameterMetaDataTest.java @@ -1,12 +1,12 @@ /* - * Copyright 2017 Google Inc. - * + * 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. 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 8d89e4daeea..ce2b8c8156c 100644 --- a/java/jdbc/src/test/java/io/vitess/jdbc/VitessPreparedStatementTest.java +++ b/java/jdbc/src/test/java/io/vitess/jdbc/VitessPreparedStatementTest.java @@ -1,12 +1,12 @@ /* - * Copyright 2017 Google Inc. - * + * 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. diff --git a/java/jdbc/src/test/java/io/vitess/jdbc/VitessResultSetMetadataTest.java b/java/jdbc/src/test/java/io/vitess/jdbc/VitessResultSetMetadataTest.java index 4ce4146d97e..8a406cb7783 100644 --- a/java/jdbc/src/test/java/io/vitess/jdbc/VitessResultSetMetadataTest.java +++ b/java/jdbc/src/test/java/io/vitess/jdbc/VitessResultSetMetadataTest.java @@ -1,12 +1,12 @@ /* - * Copyright 2017 Google Inc. - * + * 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. 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 7c41baf9636..6033e29a247 100644 --- a/java/jdbc/src/test/java/io/vitess/jdbc/VitessResultSetTest.java +++ b/java/jdbc/src/test/java/io/vitess/jdbc/VitessResultSetTest.java @@ -1,12 +1,12 @@ /* - * Copyright 2017 Google Inc. - * + * 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. 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 4ea49adfcb2..096aa3a6edb 100644 --- a/java/jdbc/src/test/java/io/vitess/jdbc/VitessStatementTest.java +++ b/java/jdbc/src/test/java/io/vitess/jdbc/VitessStatementTest.java @@ -1,12 +1,12 @@ /* - * Copyright 2017 Google Inc. - * + * 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. diff --git a/java/jdbc/src/test/java/io/vitess/jdbc/VitessVTGateManagerTest.java b/java/jdbc/src/test/java/io/vitess/jdbc/VitessVTGateManagerTest.java index 5509e50aa9a..4fbb51184df 100644 --- a/java/jdbc/src/test/java/io/vitess/jdbc/VitessVTGateManagerTest.java +++ b/java/jdbc/src/test/java/io/vitess/jdbc/VitessVTGateManagerTest.java @@ -1,12 +1,12 @@ /* - * Copyright 2017 Google Inc. - * + * 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. diff --git a/java/jdbc/src/test/java/io/vitess/util/StringUtilsTest.java b/java/jdbc/src/test/java/io/vitess/util/StringUtilsTest.java index 9b87e0fce20..bfea96e32ee 100644 --- a/java/jdbc/src/test/java/io/vitess/util/StringUtilsTest.java +++ b/java/jdbc/src/test/java/io/vitess/util/StringUtilsTest.java @@ -1,12 +1,12 @@ /* - * Copyright 2017 Google Inc. - * + * 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. diff --git a/misc/git/hooks/gofmt b/misc/git/hooks/gofmt index ca4327ba87e..c1c56cd189d 100755 --- a/misc/git/hooks/gofmt +++ b/misc/git/hooks/gofmt @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2017 Google Inc. +# 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. diff --git a/misc/git/hooks/goimports b/misc/git/hooks/goimports index de8408830e2..786e7ab517e 100755 --- a/misc/git/hooks/goimports +++ b/misc/git/hooks/goimports @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2017 Google Inc. +# 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. diff --git a/misc/git/hooks/golint b/misc/git/hooks/golint index 641d7d17f00..a2a3382af07 100755 --- a/misc/git/hooks/golint +++ b/misc/git/hooks/golint @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2017 Google Inc. +# 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. @@ -23,11 +23,6 @@ if [ -z "$GOPATH" ]; then exit 1 fi -if [ -z "$(which golint)" ]; then - echo "golint not found, please run: go get github.com/golang/lint/golint" - exit 1 -fi - # This script does not handle file names that contain spaces. gofiles=$(git diff --cached --name-only --diff-filter=ACM | grep '^go/.*\.go$' | grep -v '^go/vt/proto/' | grep -v 'go/vt/sqlparser/sql.go') @@ -38,11 +33,11 @@ errors= gofiles_with_warnings=() for gofile in $gofiles do - errcount=$(golint $gofile | wc -l) + errcount=$(go run golang.org/x/lint/golint $gofile | wc -l) if [ "$errcount" -gt "0" ]; then errors=YES echo "$errcount suggestions for:" - echo "golint $gofile" + echo "go run golang.org/x/lint/golint $gofile" gofiles_with_warnings+=($gofile) fi done @@ -70,7 +65,7 @@ if [[ $? -eq 0 ]]; then echo "Press enter to show the warnings for the next file." read fi - golint $gofile + go run golang.org/x/lint/golint $gofile first_file="false" done fi @@ -78,7 +73,7 @@ else # non-interactive shell (e.g. called from Eclipse). Just display the errors. for gofile in "${gofiles_with_warnings[@]}" do - golint $gofile + go run golang.org/x/lint/golint $gofile done fi exit 1 diff --git a/misc/git/hooks/govet b/misc/git/hooks/govet index 6ba5cdbcbb5..72951834cbd 100755 --- a/misc/git/hooks/govet +++ b/misc/git/hooks/govet @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2017 Google Inc. +# 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. diff --git a/misc/git/hooks/pylint b/misc/git/hooks/pylint index e92f356e38c..4452647f6f9 100755 --- a/misc/git/hooks/pylint +++ b/misc/git/hooks/pylint @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2017 Google Inc. +# 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. diff --git a/misc/git/hooks/staticcheck b/misc/git/hooks/staticcheck index 61ca139f8a9..f0ea8d5d543 100755 --- a/misc/git/hooks/staticcheck +++ b/misc/git/hooks/staticcheck @@ -7,11 +7,6 @@ if [ -z "$GOPATH" ]; then exit 1 fi -if [ -z "$(which staticcheck)" ]; then - echo "staticcheck not found, please run: go get honnef.co/go/tools/cmd/staticcheck" - exit 1 -fi - # This script does not handle file names that contain spaces. # Exclude auto-generated files (from proto or yacc compile). gofiles=$(git diff --cached --name-only --diff-filter=ACM | grep '^go/.*\.go$' | grep -v '^go/vt/proto/' | grep -v 'go/vt/sqlparser/sql.go') @@ -28,11 +23,11 @@ warnings= gopackages_with_warnings=() for gopackage in $gopackages do - warningcount="$(staticcheck "vitess.io/vitess/$gopackage" | wc -l)" + warningcount="$(go run honnef.co/go/tools/cmd/staticcheck "vitess.io/vitess/$gopackage" | wc -l)" if [ "$warningcount" -gt "0" ]; then warnings=YES echo "$warningcount reports for:" - echo "staticcheck vitess.io/vitess/$gopackage" + echo "go run honnef.co/go/tools/cmd/staticcheck vitess.io/vitess/$gopackage" gopackages_with_warnings+=($gopackage) fi done @@ -61,7 +56,7 @@ if [[ $? -eq 0 ]]; then echo "Press enter to show the warnings for the next file." read fi - staticcheck "vitess.io/vitess/$gopackage" + go run honnef.co/go/tools/cmd/staticcheck "vitess.io/vitess/$gopackage" first_file="false" done fi @@ -69,7 +64,7 @@ else # non-interactive shell (e.g. called from Eclipse). Just display the warnings. for gopackage in "${gopackages_with_warnings[@]}" do - staticcheck "vitess.io/vitess/$gopackage" + go run honnef.co/go/tools/cmd/staticcheck "vitess.io/vitess/$gopackage" done fi exit 1 diff --git a/misc/git/prepare-commit-msg.bugnumber b/misc/git/prepare-commit-msg.bugnumber index 0e14091f239..dc73f2b763d 100755 --- a/misc/git/prepare-commit-msg.bugnumber +++ b/misc/git/prepare-commit-msg.bugnumber @@ -3,8 +3,8 @@ # This script is run during "git commit" before the commit message editor # is shown. # -# It automatically adds a BUG= line to the default commit -# message if the branch name starts with "b". +# It automatically adds a BUG= line to the default commit +# message if the branch name starts with "b". # Note that refers to a Google internal bug number. branch="$(git rev-parse --abbrev-ref HEAD)" diff --git a/misc/parse_cover.py b/misc/parse_cover.py index c44e1f219a3..f028c0e39d4 100755 --- a/misc/parse_cover.py +++ b/misc/parse_cover.py @@ -1,6 +1,6 @@ #!/usr/bin/python -# Copyright 2017 Google Inc. +# 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. diff --git a/proto/automation.proto b/proto/automation.proto index 0dc91b3a1eb..17e2aac245e 100644 --- a/proto/automation.proto +++ b/proto/automation.proto @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/proto/automationservice.proto b/proto/automationservice.proto index b9604dd0718..bdf7ab029cb 100644 --- a/proto/automationservice.proto +++ b/proto/automationservice.proto @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/proto/binlogdata.proto b/proto/binlogdata.proto index b28dbc5356f..9b7e817ed6e 100644 --- a/proto/binlogdata.proto +++ b/proto/binlogdata.proto @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 @@ -130,6 +130,11 @@ message Rule { // wins. message Filter { repeated Rule rules = 1; + enum FieldEventMode { + ERR_ON_MISMATCH = 0; + BEST_EFFORT = 1; + } + FieldEventMode fieldEventMode = 2; } // OnDDLAction lists the possible actions for DDLs. @@ -235,7 +240,7 @@ message Journal { string local_position = 4; repeated ShardGtid shard_gtids = 5; repeated KeyspaceShard participants = 6; - repeated int64 reversed_ids = 7; + repeated string source_workflows = 7; } // VEvent represents a vstream event @@ -285,3 +290,21 @@ message VStreamRowsResponse { repeated query.Row rows = 4; query.Row lastpk = 5; } + +// VStreamResultsRequest is the payload for VStreamResults +// The ids match VStreamRows, in case we decide to merge the two. +message VStreamResultsRequest { + vtrpc.CallerID effective_caller_id = 1; + query.VTGateCallerID immediate_caller_id = 2; + query.Target target = 3; + + string query = 4; +} + +// VStreamResultsResponse is the response from VStreamResults +// The ids match VStreamRows, in case we decide to merge the two. +message VStreamResultsResponse { + repeated query.Field fields = 1; + string gtid = 3; + repeated query.Row rows = 4; +} diff --git a/proto/binlogservice.proto b/proto/binlogservice.proto index 24e50a9fc6c..6d919f52027 100644 --- a/proto/binlogservice.proto +++ b/proto/binlogservice.proto @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/proto/logutil.proto b/proto/logutil.proto index d720752314e..4704497a77b 100644 --- a/proto/logutil.proto +++ b/proto/logutil.proto @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 @@ -21,12 +21,7 @@ option go_package = "vitess.io/vitess/go/vt/proto/logutil"; package logutil; -// Time represents a time stamp in nanoseconds. In go, use logutil library -// to convert times. -message Time { - int64 seconds = 1; - int32 nanoseconds = 2; -} +import "time.proto"; // Level is the level of the log messages. enum Level { @@ -43,7 +38,7 @@ enum Level { // Event is a single logging event message Event { - Time time = 1; + vttime.Time time = 1; Level level = 2; string file = 3; int64 line = 4; diff --git a/proto/mysqlctl.proto b/proto/mysqlctl.proto index df1fbd6ebd0..274f82e74c6 100644 --- a/proto/mysqlctl.proto +++ b/proto/mysqlctl.proto @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/proto/query.proto b/proto/query.proto index 7c902f68631..7da7b94bd08 100644 --- a/proto/query.proto +++ b/proto/query.proto @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 @@ -327,7 +327,7 @@ message Field { // charset is actually a uint16. Only the lower 16 bits are used. uint32 charset = 8; - // decimals is actualy a uint8. Only the lower 8 bits are used. + // decimals is actually a uint8. Only the lower 8 bits are used. uint32 decimals = 9; // flags is actually a uint16. Only the lower 16 bits are used. @@ -826,7 +826,7 @@ message StreamHealthResponse { // It is only filled in if the information is about a tablet. RealtimeStats realtime_stats = 4; - // AggregateStats constains information about the group of tablet status. + // AggregateStats constrains information about the group of tablet status. // It is only filled in if the information is about a group of tablets. AggregateStats aggregate_stats = 6; diff --git a/proto/queryservice.proto b/proto/queryservice.proto index 8b6494f5e9b..fe2bd018150 100644 --- a/proto/queryservice.proto +++ b/proto/queryservice.proto @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 @@ -101,4 +101,7 @@ service Query { // VStreamRows streams rows from the specified starting point. rpc VStreamRows(binlogdata.VStreamRowsRequest) returns (stream binlogdata.VStreamRowsResponse) {}; + + // VStreamResults streams results along with the gtid of the snapshot. + rpc VStreamResults(binlogdata.VStreamResultsRequest) returns (stream binlogdata.VStreamResultsResponse) {}; } diff --git a/proto/replicationdata.proto b/proto/replicationdata.proto index 5a1a1e5ee14..4b0b65e8c9a 100644 --- a/proto/replicationdata.proto +++ b/proto/replicationdata.proto @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/proto/tableacl.proto b/proto/tableacl.proto index 1fb1af3d915..d041c78f3fa 100644 --- a/proto/tableacl.proto +++ b/proto/tableacl.proto @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/proto/tabletmanagerdata.proto b/proto/tabletmanagerdata.proto index 0d518a74309..9f05f103553 100644 --- a/proto/tabletmanagerdata.proto +++ b/proto/tabletmanagerdata.proto @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 @@ -52,6 +52,10 @@ message TableDefinition { // approximate number of rows uint64 row_count = 7; + + // column names along with their types. + // NOTE: this is a superset of columns. + repeated query.Field fields = 8; } message SchemaDefinition { @@ -271,6 +275,13 @@ message MasterPositionResponse { string position = 1; } +message WaitForPositionRequest { + string position = 1; +} + +message WaitForPositionResponse { +} + message StopSlaveRequest { } @@ -401,6 +412,7 @@ message SlaveWasPromotedResponse { message SetMasterRequest { topodata.TabletAlias parent = 1; int64 time_created_ns = 2; + string wait_position = 4; bool force_start_slave = 3; } diff --git a/proto/tabletmanagerservice.proto b/proto/tabletmanagerservice.proto index 467f249851d..f1351f63e35 100644 --- a/proto/tabletmanagerservice.proto +++ b/proto/tabletmanagerservice.proto @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 @@ -88,6 +88,9 @@ service TabletManager { // MasterPosition returns the current master position rpc MasterPosition(tabletmanagerdata.MasterPositionRequest) returns (tabletmanagerdata.MasterPositionResponse) {}; + // WaitForPosition waits for the position to be reached + rpc WaitForPosition(tabletmanagerdata.WaitForPositionRequest) returns (tabletmanagerdata.WaitForPositionResponse) {}; + // StopSlave makes mysql stop its replication rpc StopSlave(tabletmanagerdata.StopSlaveRequest) returns (tabletmanagerdata.StopSlaveResponse) {}; @@ -151,7 +154,7 @@ service TabletManager { // reparent journal rpc PopulateReparentJournal(tabletmanagerdata.PopulateReparentJournalRequest) returns (tabletmanagerdata.PopulateReparentJournalResponse) {}; - // InitSlave tells the tablet to reparent to the master unconditionnally + // InitSlave tells the tablet to reparent to the master unconditionally rpc InitSlave(tabletmanagerdata.InitSlaveRequest) returns (tabletmanagerdata.InitSlaveResponse) {}; // DemoteMaster tells the soon-to-be-former master it's gonna change diff --git a/proto/throttlerdata.proto b/proto/throttlerdata.proto index 06ecc106495..e7739e34643 100644 --- a/proto/throttlerdata.proto +++ b/proto/throttlerdata.proto @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/proto/throttlerservice.proto b/proto/throttlerservice.proto index 0ab9fdac4a0..7c717990c7f 100644 --- a/proto/throttlerservice.proto +++ b/proto/throttlerservice.proto @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/proto/time.proto b/proto/time.proto new file mode 100644 index 00000000000..5224fcb9d12 --- /dev/null +++ b/proto/time.proto @@ -0,0 +1,30 @@ +/* +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. +*/ + +// This package contains a shared time data structure + +syntax = "proto3"; +option go_package = "vitess.io/vitess/go/vt/proto/vttime"; + +package vttime; + +// Time represents a time stamp in nanoseconds. In go, use logutil library +// to convert times. +message Time { + int64 seconds = 1; + int32 nanoseconds = 2; +} + diff --git a/proto/topodata.proto b/proto/topodata.proto index 2677f721911..d5331053d8a 100644 --- a/proto/topodata.proto +++ b/proto/topodata.proto @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 @@ -26,6 +26,8 @@ option java_package="io.vitess.proto"; package topodata; +import "time.proto"; + // KeyRange describes a range of sharding keys, when range-based // sharding is used. message KeyRange { @@ -33,6 +35,15 @@ message KeyRange { bytes end = 2; } +// KeyspaceType describes the type of the keyspace +enum KeyspaceType { + // NORMAL is the default value + NORMAL = 0; + + // SNAPSHOT is when we are creating a snapshot keyspace + SNAPSHOT = 1; +} + // KeyspaceIdType describes the type of the sharding key for a // range-based sharded keyspace. enum KeyspaceIdType { @@ -147,6 +158,17 @@ message Tablet { // for legacy behavior. int32 mysql_port = 13; + // master_term_start_time is the time (in UTC) at which the current term of + // the current tablet began as master. If this tablet is not currently the + // master, this value is ignored. + // + // A new master term begins any time an authoritative decision is communicated + // about which tablet should be the master, such as via Vitess + // replication-management commands like PlannedReparentShard, + // EmergencyReparentShard, and TabletExternallyReparented. + // + vttime.Time master_term_start_time = 14; + // OBSOLETE: ip and tablet health information // string ip = 3; // map health_map = 11; @@ -157,7 +179,6 @@ message Tablet { message Shard { // master_alias is the tablet alias of the master for the shard. // If it is unset, then there is no master in this shard yet. - // No lock is necessary to update this field, when for instance // TabletExternallyReparented updates this. However, we lock the // shard for reparenting operations (InitShardMaster, @@ -165,6 +186,20 @@ message Shard { // exclusive operation. TabletAlias master_alias = 1; + // master_term_start_time is the time (in UTC) at which the current term of + // the master specified in master_alias began. + // + // A new master term begins any time an authoritative decision is communicated + // about which tablet should be the master, such as via Vitess + // replication-management commands like PlannedReparentShard, + // EmergencyReparentShard, and TabletExternallyReparented. + // + // The master_alias should only ever be changed if the new master's term began + // at a later time than this. Note that a new term can start for the tablet + // that is already the master. In that case, the master_term_start_time would + // be increased without changing the master_alias. + vttime.Time master_term_start_time = 8; + // key_range is the KeyRange for this shard. It can be unset if: // - we are not using range-based sharding in this shard. // - the shard covers the entire keyrange. @@ -185,7 +220,7 @@ message Shard { repeated ServedType served_types = 3; // SourceShard represents a data source for filtered replication - // accross shards. When this is used in a destination shard, the master + // across shards. When this is used in a destination shard, the master // of that shard will run filtered replication. message SourceShard { // Uid is the unique ID for this SourceShard object. @@ -266,6 +301,21 @@ message Keyspace { // ServedFrom will redirect the appropriate traffic to // another keyspace. repeated ServedFrom served_froms = 4; + + // keyspace_type will determine how this keyspace is treated by + // vtgate / vschema. Normal keyspaces are routable by + // any query. Snapshot keyspaces are only accessible + // by explicit addresssing or by calling "use keyspace" first + KeyspaceType keyspace_type = 5; + + // base_keyspace is the base keyspace from which a snapshot + // keyspace is created. empty for normal keyspaces + string base_keyspace = 6; + + // snapshot_time (in UTC) is a property of snapshot + // keyspaces which tells us what point in time + // the snapshot is of + vttime.Time snapshot_time = 7; } // ShardReplication describes the MySQL replication relationships diff --git a/proto/vschema.proto b/proto/vschema.proto index 12e6154f047..3fc3c2fe563 100644 --- a/proto/vschema.proto +++ b/proto/vschema.proto @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 @@ -43,6 +43,8 @@ message Keyspace { bool sharded = 1; map vindexes = 2; map tables = 3; + // If require_explicit_routing is true, vindexes and tables are not added to global routing + bool require_explicit_routing = 4; } // Vindex is the vindex info for a Keyspace. @@ -87,7 +89,7 @@ message Table { // ColumnVindex is used to associate a column to a vindex. message ColumnVindex { - // Legacy implemenation, moving forward all vindexes should define a list of columns. + // Legacy implementation, moving forward all vindexes should define a list of columns. string column = 1; // The name must match a vindex defined in Keyspace. string name = 2; diff --git a/proto/vtctldata.proto b/proto/vtctldata.proto index fee87b89793..ef964d6d07f 100644 --- a/proto/vtctldata.proto +++ b/proto/vtctldata.proto @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/proto/vtctlservice.proto b/proto/vtctlservice.proto index f29e07d6f25..07cd70b3c3a 100644 --- a/proto/vtctlservice.proto +++ b/proto/vtctlservice.proto @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/proto/vtgate.proto b/proto/vtgate.proto index d1df1b34b93..d02f9d00e9b 100644 --- a/proto/vtgate.proto +++ b/proto/vtgate.proto @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/proto/vtgateservice.proto b/proto/vtgateservice.proto index 2b7f6c901ae..8a184990af3 100644 --- a/proto/vtgateservice.proto +++ b/proto/vtgateservice.proto @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/proto/vtrpc.proto b/proto/vtrpc.proto index 9d659ff4347..9cd882f5d37 100644 --- a/proto/vtrpc.proto +++ b/proto/vtrpc.proto @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 @@ -174,7 +174,7 @@ enum Code { // LegacyErrorCode is the enum values for Errors. This type is deprecated. // Use Code instead. Background: In the initial design, we thought // that we may end up with a different list of canonical error codes -// than the ones defined by grpc. In hindisght, we realize that +// than the ones defined by grpc. In hindsight, we realize that // the grpc error codes are fairly generic and mostly sufficient. // In order to avoid confusion, this type will be deprecated in // favor of the new Code that matches exactly what grpc defines. diff --git a/proto/vttest.proto b/proto/vttest.proto index 08c6f69907c..2e76c7f7641 100644 --- a/proto/vttest.proto +++ b/proto/vttest.proto @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/proto/vtworkerdata.proto b/proto/vtworkerdata.proto index 9fa9640519b..d94721d2b17 100644 --- a/proto/vtworkerdata.proto +++ b/proto/vtworkerdata.proto @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/proto/vtworkerservice.proto b/proto/vtworkerservice.proto index 0e4f5aed3f0..7b0e87841e6 100644 --- a/proto/vtworkerservice.proto +++ b/proto/vtworkerservice.proto @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/proto/workflow.proto b/proto/workflow.proto index df3cecfbf80..772b64da7dc 100644 --- a/proto/workflow.proto +++ b/proto/workflow.proto @@ -1,5 +1,5 @@ /* -Copyright 2017 Google Inc. +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. @@ -7,7 +7,7 @@ You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto in writing, software +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 diff --git a/py/setup.py b/py/setup.py index 698d084347b..9ea1921ff9f 100755 --- a/py/setup.py +++ b/py/setup.py @@ -1,11 +1,11 @@ -# Copyright 2017 Google Inc. +# 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. diff --git a/py/util/__init__.py b/py/util/__init__.py index 15a6a3f58b8..fbc9e3ecdd1 100644 --- a/py/util/__init__.py +++ b/py/util/__init__.py @@ -1,11 +1,11 @@ -# Copyright 2017 Google Inc. +# 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. diff --git a/py/util/grpc_with_metadata.py b/py/util/grpc_with_metadata.py index b6129cac551..a2a2d219cca 100644 --- a/py/util/grpc_with_metadata.py +++ b/py/util/grpc_with_metadata.py @@ -1,11 +1,11 @@ -# Copyright 2017 Google Inc. +# 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. diff --git a/py/util/static_auth_client.py b/py/util/static_auth_client.py index 68b055f3249..f2e0235da29 100644 --- a/py/util/static_auth_client.py +++ b/py/util/static_auth_client.py @@ -1,4 +1,4 @@ -# Copyright 2017 Google Inc. +# 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. diff --git a/py/vtctl/__init__.py b/py/vtctl/__init__.py index 15a6a3f58b8..fbc9e3ecdd1 100644 --- a/py/vtctl/__init__.py +++ b/py/vtctl/__init__.py @@ -1,11 +1,11 @@ -# Copyright 2017 Google Inc. +# 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. diff --git a/py/vtctl/grpc_vtctl_client.py b/py/vtctl/grpc_vtctl_client.py index 6c85bdebca0..d9a958e8650 100644 --- a/py/vtctl/grpc_vtctl_client.py +++ b/py/vtctl/grpc_vtctl_client.py @@ -1,4 +1,4 @@ -# Copyright 2017 Google Inc. +# 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. diff --git a/py/vtctl/vtctl_client.py b/py/vtctl/vtctl_client.py index 57baa572073..663da1e4470 100644 --- a/py/vtctl/vtctl_client.py +++ b/py/vtctl/vtctl_client.py @@ -1,11 +1,11 @@ -# Copyright 2017 Google Inc. +# 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. diff --git a/py/vtdb/__init__.py b/py/vtdb/__init__.py index 302cdcb6eb6..278ebfd69c6 100644 --- a/py/vtdb/__init__.py +++ b/py/vtdb/__init__.py @@ -3,14 +3,14 @@ See https://www.python.org/dev/peps/pep-0249 for more information on these. """ -# Copyright 2017 Google Inc. +# 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. @@ -21,7 +21,7 @@ apilevel = '2.0' # Threads may share the module, but not connections. -# (we store session information in the conection now, that should be in the +# (we store session information in the connection now, that should be in the # cursor but are not for historical reasons). threadsafety = 2 diff --git a/py/vtdb/base_cursor.py b/py/vtdb/base_cursor.py index 9077a57bb0b..be753062414 100644 --- a/py/vtdb/base_cursor.py +++ b/py/vtdb/base_cursor.py @@ -1,11 +1,11 @@ -# Copyright 2017 Google Inc. -# +# 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. diff --git a/py/vtdb/cursorv3.py b/py/vtdb/cursorv3.py index 459bf6bf5d5..c5d502a5ef6 100644 --- a/py/vtdb/cursorv3.py +++ b/py/vtdb/cursorv3.py @@ -1,4 +1,4 @@ -# Copyright 2017 Google Inc. +# 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. diff --git a/py/vtdb/dbapi.py b/py/vtdb/dbapi.py index 7e62e6a595f..56c9febbd73 100644 --- a/py/vtdb/dbapi.py +++ b/py/vtdb/dbapi.py @@ -1,4 +1,4 @@ -# Copyright 2017 Google Inc. +# 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. diff --git a/py/vtdb/dbexceptions.py b/py/vtdb/dbexceptions.py index d9e8648520a..430c710f7f8 100755 --- a/py/vtdb/dbexceptions.py +++ b/py/vtdb/dbexceptions.py @@ -1,4 +1,4 @@ -# Copyright 2017 Google Inc. +# 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. diff --git a/py/vtdb/event_token.py b/py/vtdb/event_token.py index 5fa7a4067b7..f393b8b9e77 100644 --- a/py/vtdb/event_token.py +++ b/py/vtdb/event_token.py @@ -1,4 +1,4 @@ -# Copyright 2017 Google Inc. +# 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. diff --git a/py/vtdb/field_types.py b/py/vtdb/field_types.py index 08778e3f738..e1e234aede5 100755 --- a/py/vtdb/field_types.py +++ b/py/vtdb/field_types.py @@ -1,4 +1,4 @@ -# Copyright 2017 Google Inc. +# 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. diff --git a/py/vtdb/grpc_vtgate_client.py b/py/vtdb/grpc_vtgate_client.py index 2886229cf84..41348d66753 100644 --- a/py/vtdb/grpc_vtgate_client.py +++ b/py/vtdb/grpc_vtgate_client.py @@ -1,4 +1,4 @@ -# Copyright 2017 Google Inc. +# 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. diff --git a/py/vtdb/keyrange.py b/py/vtdb/keyrange.py index a44cd71b0f9..cc63f22573d 100644 --- a/py/vtdb/keyrange.py +++ b/py/vtdb/keyrange.py @@ -1,4 +1,4 @@ -# Copyright 2017 Google Inc. +# 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. diff --git a/py/vtdb/keyrange_constants.py b/py/vtdb/keyrange_constants.py index 4a9acb40d06..59913d91916 100644 --- a/py/vtdb/keyrange_constants.py +++ b/py/vtdb/keyrange_constants.py @@ -1,4 +1,4 @@ -# Copyright 2017 Google Inc. +# 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. diff --git a/py/vtdb/keyspace.py b/py/vtdb/keyspace.py index 90ea2c14aed..69754129aaa 100644 --- a/py/vtdb/keyspace.py +++ b/py/vtdb/keyspace.py @@ -1,4 +1,4 @@ -# Copyright 2017 Google Inc. +# 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. diff --git a/py/vtdb/prefer_vtroot_imports.py b/py/vtdb/prefer_vtroot_imports.py index ed16a7e8938..6456a7e8233 100644 --- a/py/vtdb/prefer_vtroot_imports.py +++ b/py/vtdb/prefer_vtroot_imports.py @@ -1,4 +1,4 @@ -# Copyright 2017 Google Inc. +# 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. diff --git a/py/vtdb/proto3_encoding.py b/py/vtdb/proto3_encoding.py index 5ed551242fc..7bf53ccc6ca 100644 --- a/py/vtdb/proto3_encoding.py +++ b/py/vtdb/proto3_encoding.py @@ -1,4 +1,4 @@ -# Copyright 2017 Google Inc. +# 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. @@ -68,7 +68,7 @@ } # legacy_code_to_code_map maps legacy error codes -# to the new code that matches grpc's cannonical error codes. +# to the new code that matches grpc's canonical error codes. legacy_code_to_code_map = { vtrpc_pb2.SUCCESS_LEGACY: vtrpc_pb2.OK, vtrpc_pb2.CANCELLED_LEGACY: vtrpc_pb2.CANCELED, diff --git a/py/vtdb/times.py b/py/vtdb/times.py index adf6c53fef5..a45abe6c018 100755 --- a/py/vtdb/times.py +++ b/py/vtdb/times.py @@ -1,4 +1,4 @@ -# Copyright 2017 Google Inc. +# 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. diff --git a/py/vtdb/topology.py b/py/vtdb/topology.py index b4e85e5b908..d0acbb8db08 100644 --- a/py/vtdb/topology.py +++ b/py/vtdb/topology.py @@ -1,6 +1,6 @@ """Deprecated module that holds keyspace / sharding methods.""" -# Copyright 2017 Google Inc. +# 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. diff --git a/py/vtdb/vtdb_logger.py b/py/vtdb/vtdb_logger.py index e444497dfe8..b203af52381 100644 --- a/py/vtdb/vtdb_logger.py +++ b/py/vtdb/vtdb_logger.py @@ -1,4 +1,4 @@ -# Copyright 2017 Google Inc. +# 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. diff --git a/py/vtdb/vtgate_client.py b/py/vtdb/vtgate_client.py index 38437598946..6c946d24ed4 100644 --- a/py/vtdb/vtgate_client.py +++ b/py/vtdb/vtgate_client.py @@ -1,4 +1,4 @@ -# Copyright 2017 Google Inc. +# 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. diff --git a/py/vtdb/vtgate_client_testsuite.py b/py/vtdb/vtgate_client_testsuite.py index f3d9a7f6d7b..eada034fc94 100755 --- a/py/vtdb/vtgate_client_testsuite.py +++ b/py/vtdb/vtgate_client_testsuite.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright 2017 Google Inc. +# 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. diff --git a/py/vtdb/vtgate_cursor.py b/py/vtdb/vtgate_cursor.py index fab3c220a8e..e19ff97407f 100644 --- a/py/vtdb/vtgate_cursor.py +++ b/py/vtdb/vtgate_cursor.py @@ -1,4 +1,4 @@ -# Copyright 2017 Google Inc. +# 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. diff --git a/py/vtdb/vtgate_utils.py b/py/vtdb/vtgate_utils.py index 623b3ae1e5a..be92599578f 100644 --- a/py/vtdb/vtgate_utils.py +++ b/py/vtdb/vtgate_utils.py @@ -1,4 +1,4 @@ -# Copyright 2017 Google Inc. +# 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. diff --git a/py/vtdb/vtrouting.py b/py/vtdb/vtrouting.py index 3265f2e0be1..3efb74fd51a 100644 --- a/py/vtdb/vtrouting.py +++ b/py/vtdb/vtrouting.py @@ -1,4 +1,4 @@ -# Copyright 2017 Google Inc. +# 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. @@ -24,7 +24,7 @@ information. The routing information object is supposed to be opaque to the client but VTGate uses it to route queries. It is also used to compute the associated where clause to be added -to the query, wich is needed to prevent returning duplicate result +to the query, which is needed to prevent returning duplicate result from two parallelized queries running over the same shard. API usage - diff --git a/py/vtproto/binlogdata_pb2.py b/py/vtproto/binlogdata_pb2.py index 53eda7da5b1..ae761e90e68 100644 --- a/py/vtproto/binlogdata_pb2.py +++ b/py/vtproto/binlogdata_pb2.py @@ -23,7 +23,7 @@ package='binlogdata', syntax='proto3', serialized_options=_b('Z\'vitess.io/vitess/go/vt/proto/binlogdata'), - serialized_pb=_b('\n\x10\x62inlogdata.proto\x12\nbinlogdata\x1a\x0bvtrpc.proto\x1a\x0bquery.proto\x1a\x0etopodata.proto\"7\n\x07\x43harset\x12\x0e\n\x06\x63lient\x18\x01 \x01(\x05\x12\x0c\n\x04\x63onn\x18\x02 \x01(\x05\x12\x0e\n\x06server\x18\x03 \x01(\x05\"\xb5\x03\n\x11\x42inlogTransaction\x12;\n\nstatements\x18\x01 \x03(\x0b\x32\'.binlogdata.BinlogTransaction.Statement\x12&\n\x0b\x65vent_token\x18\x04 \x01(\x0b\x32\x11.query.EventToken\x1a\xae\x02\n\tStatement\x12\x42\n\x08\x63\x61tegory\x18\x01 \x01(\x0e\x32\x30.binlogdata.BinlogTransaction.Statement.Category\x12$\n\x07\x63harset\x18\x02 \x01(\x0b\x32\x13.binlogdata.Charset\x12\x0b\n\x03sql\x18\x03 \x01(\x0c\"\xa9\x01\n\x08\x43\x61tegory\x12\x13\n\x0f\x42L_UNRECOGNIZED\x10\x00\x12\x0c\n\x08\x42L_BEGIN\x10\x01\x12\r\n\tBL_COMMIT\x10\x02\x12\x0f\n\x0b\x42L_ROLLBACK\x10\x03\x12\x15\n\x11\x42L_DML_DEPRECATED\x10\x04\x12\n\n\x06\x42L_DDL\x10\x05\x12\n\n\x06\x42L_SET\x10\x06\x12\r\n\tBL_INSERT\x10\x07\x12\r\n\tBL_UPDATE\x10\x08\x12\r\n\tBL_DELETE\x10\tJ\x04\x08\x02\x10\x03J\x04\x08\x03\x10\x04\"v\n\x15StreamKeyRangeRequest\x12\x10\n\x08position\x18\x01 \x01(\t\x12%\n\tkey_range\x18\x02 \x01(\x0b\x32\x12.topodata.KeyRange\x12$\n\x07\x63harset\x18\x03 \x01(\x0b\x32\x13.binlogdata.Charset\"S\n\x16StreamKeyRangeResponse\x12\x39\n\x12\x62inlog_transaction\x18\x01 \x01(\x0b\x32\x1d.binlogdata.BinlogTransaction\"]\n\x13StreamTablesRequest\x12\x10\n\x08position\x18\x01 \x01(\t\x12\x0e\n\x06tables\x18\x02 \x03(\t\x12$\n\x07\x63harset\x18\x03 \x01(\x0b\x32\x13.binlogdata.Charset\"Q\n\x14StreamTablesResponse\x12\x39\n\x12\x62inlog_transaction\x18\x01 \x01(\x0b\x32\x1d.binlogdata.BinlogTransaction\"%\n\x04Rule\x12\r\n\x05match\x18\x01 \x01(\t\x12\x0e\n\x06\x66ilter\x18\x02 \x01(\t\")\n\x06\x46ilter\x12\x1f\n\x05rules\x18\x01 \x03(\x0b\x32\x10.binlogdata.Rule\"\xde\x01\n\x0c\x42inlogSource\x12\x10\n\x08keyspace\x18\x01 \x01(\t\x12\r\n\x05shard\x18\x02 \x01(\t\x12)\n\x0btablet_type\x18\x03 \x01(\x0e\x32\x14.topodata.TabletType\x12%\n\tkey_range\x18\x04 \x01(\x0b\x32\x12.topodata.KeyRange\x12\x0e\n\x06tables\x18\x05 \x03(\t\x12\"\n\x06\x66ilter\x18\x06 \x01(\x0b\x32\x12.binlogdata.Filter\x12\'\n\x06on_ddl\x18\x07 \x01(\x0e\x32\x17.binlogdata.OnDDLAction\"B\n\tRowChange\x12\x1a\n\x06\x62\x65\x66ore\x18\x01 \x01(\x0b\x32\n.query.Row\x12\x19\n\x05\x61\x66ter\x18\x02 \x01(\x0b\x32\n.query.Row\"J\n\x08RowEvent\x12\x12\n\ntable_name\x18\x01 \x01(\t\x12*\n\x0brow_changes\x18\x02 \x03(\x0b\x32\x15.binlogdata.RowChange\">\n\nFieldEvent\x12\x12\n\ntable_name\x18\x01 \x01(\t\x12\x1c\n\x06\x66ields\x18\x02 \x03(\x0b\x32\x0c.query.Field\":\n\tShardGtid\x12\x10\n\x08keyspace\x18\x01 \x01(\t\x12\r\n\x05shard\x18\x02 \x01(\t\x12\x0c\n\x04gtid\x18\x03 \x01(\t\"3\n\x05VGtid\x12*\n\x0bshard_gtids\x18\x01 \x03(\x0b\x32\x15.binlogdata.ShardGtid\"0\n\rKeyspaceShard\x12\x10\n\x08keyspace\x18\x01 \x01(\t\x12\r\n\x05shard\x18\x02 \x01(\t\"\xe3\x01\n\x07Journal\x12\n\n\x02id\x18\x01 \x01(\x03\x12\x31\n\x0emigration_type\x18\x02 \x01(\x0e\x32\x19.binlogdata.MigrationType\x12\x0e\n\x06tables\x18\x03 \x03(\t\x12\x16\n\x0elocal_position\x18\x04 \x01(\t\x12*\n\x0bshard_gtids\x18\x05 \x03(\x0b\x32\x15.binlogdata.ShardGtid\x12/\n\x0cparticipants\x18\x06 \x03(\x0b\x32\x19.binlogdata.KeyspaceShard\x12\x14\n\x0creversed_ids\x18\x07 \x03(\x03\"\x90\x02\n\x06VEvent\x12$\n\x04type\x18\x01 \x01(\x0e\x32\x16.binlogdata.VEventType\x12\x11\n\ttimestamp\x18\x02 \x01(\x03\x12\x0c\n\x04gtid\x18\x03 \x01(\t\x12\x0b\n\x03\x64\x64l\x18\x04 \x01(\t\x12\'\n\trow_event\x18\x05 \x01(\x0b\x32\x14.binlogdata.RowEvent\x12+\n\x0b\x66ield_event\x18\x06 \x01(\x0b\x32\x16.binlogdata.FieldEvent\x12 \n\x05vgtid\x18\x07 \x01(\x0b\x32\x11.binlogdata.VGtid\x12$\n\x07journal\x18\x08 \x01(\x0b\x32\x13.binlogdata.Journal\x12\x14\n\x0c\x63urrent_time\x18\x14 \x01(\x03\"\xc7\x01\n\x0eVStreamRequest\x12,\n\x13\x65\x66\x66\x65\x63tive_caller_id\x18\x01 \x01(\x0b\x32\x0f.vtrpc.CallerID\x12\x32\n\x13immediate_caller_id\x18\x02 \x01(\x0b\x32\x15.query.VTGateCallerID\x12\x1d\n\x06target\x18\x03 \x01(\x0b\x32\r.query.Target\x12\x10\n\x08position\x18\x04 \x01(\t\x12\"\n\x06\x66ilter\x18\x05 \x01(\x0b\x32\x12.binlogdata.Filter\"5\n\x0fVStreamResponse\x12\"\n\x06\x65vents\x18\x01 \x03(\x0b\x32\x12.binlogdata.VEvent\"\xc8\x01\n\x12VStreamRowsRequest\x12,\n\x13\x65\x66\x66\x65\x63tive_caller_id\x18\x01 \x01(\x0b\x32\x0f.vtrpc.CallerID\x12\x32\n\x13immediate_caller_id\x18\x02 \x01(\x0b\x32\x15.query.VTGateCallerID\x12\x1d\n\x06target\x18\x03 \x01(\x0b\x32\r.query.Target\x12\r\n\x05query\x18\x04 \x01(\t\x12\"\n\x06lastpk\x18\x05 \x01(\x0b\x32\x12.query.QueryResult\"\x97\x01\n\x13VStreamRowsResponse\x12\x1c\n\x06\x66ields\x18\x01 \x03(\x0b\x32\x0c.query.Field\x12\x1e\n\x08pkfields\x18\x02 \x03(\x0b\x32\x0c.query.Field\x12\x0c\n\x04gtid\x18\x03 \x01(\t\x12\x18\n\x04rows\x18\x04 \x03(\x0b\x32\n.query.Row\x12\x1a\n\x06lastpk\x18\x05 \x01(\x0b\x32\n.query.Row*>\n\x0bOnDDLAction\x12\n\n\x06IGNORE\x10\x00\x12\x08\n\x04STOP\x10\x01\x12\x08\n\x04\x45XEC\x10\x02\x12\x0f\n\x0b\x45XEC_IGNORE\x10\x03*\xd1\x01\n\nVEventType\x12\x0b\n\x07UNKNOWN\x10\x00\x12\x08\n\x04GTID\x10\x01\x12\t\n\x05\x42\x45GIN\x10\x02\x12\n\n\x06\x43OMMIT\x10\x03\x12\x0c\n\x08ROLLBACK\x10\x04\x12\x07\n\x03\x44\x44L\x10\x05\x12\n\n\x06INSERT\x10\x06\x12\x0b\n\x07REPLACE\x10\x07\x12\n\n\x06UPDATE\x10\x08\x12\n\n\x06\x44\x45LETE\x10\t\x12\x07\n\x03SET\x10\n\x12\t\n\x05OTHER\x10\x0b\x12\x07\n\x03ROW\x10\x0c\x12\t\n\x05\x46IELD\x10\r\x12\r\n\tHEARTBEAT\x10\x0e\x12\t\n\x05VGTID\x10\x0f\x12\x0b\n\x07JOURNAL\x10\x10*\'\n\rMigrationType\x12\n\n\x06TABLES\x10\x00\x12\n\n\x06SHARDS\x10\x01\x42)Z\'vitess.io/vitess/go/vt/proto/binlogdatab\x06proto3') + serialized_pb=_b('\n\x10\x62inlogdata.proto\x12\nbinlogdata\x1a\x0bvtrpc.proto\x1a\x0bquery.proto\x1a\x0etopodata.proto\"7\n\x07\x43harset\x12\x0e\n\x06\x63lient\x18\x01 \x01(\x05\x12\x0c\n\x04\x63onn\x18\x02 \x01(\x05\x12\x0e\n\x06server\x18\x03 \x01(\x05\"\xb5\x03\n\x11\x42inlogTransaction\x12;\n\nstatements\x18\x01 \x03(\x0b\x32\'.binlogdata.BinlogTransaction.Statement\x12&\n\x0b\x65vent_token\x18\x04 \x01(\x0b\x32\x11.query.EventToken\x1a\xae\x02\n\tStatement\x12\x42\n\x08\x63\x61tegory\x18\x01 \x01(\x0e\x32\x30.binlogdata.BinlogTransaction.Statement.Category\x12$\n\x07\x63harset\x18\x02 \x01(\x0b\x32\x13.binlogdata.Charset\x12\x0b\n\x03sql\x18\x03 \x01(\x0c\"\xa9\x01\n\x08\x43\x61tegory\x12\x13\n\x0f\x42L_UNRECOGNIZED\x10\x00\x12\x0c\n\x08\x42L_BEGIN\x10\x01\x12\r\n\tBL_COMMIT\x10\x02\x12\x0f\n\x0b\x42L_ROLLBACK\x10\x03\x12\x15\n\x11\x42L_DML_DEPRECATED\x10\x04\x12\n\n\x06\x42L_DDL\x10\x05\x12\n\n\x06\x42L_SET\x10\x06\x12\r\n\tBL_INSERT\x10\x07\x12\r\n\tBL_UPDATE\x10\x08\x12\r\n\tBL_DELETE\x10\tJ\x04\x08\x02\x10\x03J\x04\x08\x03\x10\x04\"v\n\x15StreamKeyRangeRequest\x12\x10\n\x08position\x18\x01 \x01(\t\x12%\n\tkey_range\x18\x02 \x01(\x0b\x32\x12.topodata.KeyRange\x12$\n\x07\x63harset\x18\x03 \x01(\x0b\x32\x13.binlogdata.Charset\"S\n\x16StreamKeyRangeResponse\x12\x39\n\x12\x62inlog_transaction\x18\x01 \x01(\x0b\x32\x1d.binlogdata.BinlogTransaction\"]\n\x13StreamTablesRequest\x12\x10\n\x08position\x18\x01 \x01(\t\x12\x0e\n\x06tables\x18\x02 \x03(\t\x12$\n\x07\x63harset\x18\x03 \x01(\x0b\x32\x13.binlogdata.Charset\"Q\n\x14StreamTablesResponse\x12\x39\n\x12\x62inlog_transaction\x18\x01 \x01(\x0b\x32\x1d.binlogdata.BinlogTransaction\"%\n\x04Rule\x12\r\n\x05match\x18\x01 \x01(\t\x12\x0e\n\x06\x66ilter\x18\x02 \x01(\t\"\x9c\x01\n\x06\x46ilter\x12\x1f\n\x05rules\x18\x01 \x03(\x0b\x32\x10.binlogdata.Rule\x12\x39\n\x0e\x66ieldEventMode\x18\x02 \x01(\x0e\x32!.binlogdata.Filter.FieldEventMode\"6\n\x0e\x46ieldEventMode\x12\x13\n\x0f\x45RR_ON_MISMATCH\x10\x00\x12\x0f\n\x0b\x42\x45ST_EFFORT\x10\x01\"\xde\x01\n\x0c\x42inlogSource\x12\x10\n\x08keyspace\x18\x01 \x01(\t\x12\r\n\x05shard\x18\x02 \x01(\t\x12)\n\x0btablet_type\x18\x03 \x01(\x0e\x32\x14.topodata.TabletType\x12%\n\tkey_range\x18\x04 \x01(\x0b\x32\x12.topodata.KeyRange\x12\x0e\n\x06tables\x18\x05 \x03(\t\x12\"\n\x06\x66ilter\x18\x06 \x01(\x0b\x32\x12.binlogdata.Filter\x12\'\n\x06on_ddl\x18\x07 \x01(\x0e\x32\x17.binlogdata.OnDDLAction\"B\n\tRowChange\x12\x1a\n\x06\x62\x65\x66ore\x18\x01 \x01(\x0b\x32\n.query.Row\x12\x19\n\x05\x61\x66ter\x18\x02 \x01(\x0b\x32\n.query.Row\"J\n\x08RowEvent\x12\x12\n\ntable_name\x18\x01 \x01(\t\x12*\n\x0brow_changes\x18\x02 \x03(\x0b\x32\x15.binlogdata.RowChange\">\n\nFieldEvent\x12\x12\n\ntable_name\x18\x01 \x01(\t\x12\x1c\n\x06\x66ields\x18\x02 \x03(\x0b\x32\x0c.query.Field\":\n\tShardGtid\x12\x10\n\x08keyspace\x18\x01 \x01(\t\x12\r\n\x05shard\x18\x02 \x01(\t\x12\x0c\n\x04gtid\x18\x03 \x01(\t\"3\n\x05VGtid\x12*\n\x0bshard_gtids\x18\x01 \x03(\x0b\x32\x15.binlogdata.ShardGtid\"0\n\rKeyspaceShard\x12\x10\n\x08keyspace\x18\x01 \x01(\t\x12\r\n\x05shard\x18\x02 \x01(\t\"\xe7\x01\n\x07Journal\x12\n\n\x02id\x18\x01 \x01(\x03\x12\x31\n\x0emigration_type\x18\x02 \x01(\x0e\x32\x19.binlogdata.MigrationType\x12\x0e\n\x06tables\x18\x03 \x03(\t\x12\x16\n\x0elocal_position\x18\x04 \x01(\t\x12*\n\x0bshard_gtids\x18\x05 \x03(\x0b\x32\x15.binlogdata.ShardGtid\x12/\n\x0cparticipants\x18\x06 \x03(\x0b\x32\x19.binlogdata.KeyspaceShard\x12\x18\n\x10source_workflows\x18\x07 \x03(\t\"\x90\x02\n\x06VEvent\x12$\n\x04type\x18\x01 \x01(\x0e\x32\x16.binlogdata.VEventType\x12\x11\n\ttimestamp\x18\x02 \x01(\x03\x12\x0c\n\x04gtid\x18\x03 \x01(\t\x12\x0b\n\x03\x64\x64l\x18\x04 \x01(\t\x12\'\n\trow_event\x18\x05 \x01(\x0b\x32\x14.binlogdata.RowEvent\x12+\n\x0b\x66ield_event\x18\x06 \x01(\x0b\x32\x16.binlogdata.FieldEvent\x12 \n\x05vgtid\x18\x07 \x01(\x0b\x32\x11.binlogdata.VGtid\x12$\n\x07journal\x18\x08 \x01(\x0b\x32\x13.binlogdata.Journal\x12\x14\n\x0c\x63urrent_time\x18\x14 \x01(\x03\"\xc7\x01\n\x0eVStreamRequest\x12,\n\x13\x65\x66\x66\x65\x63tive_caller_id\x18\x01 \x01(\x0b\x32\x0f.vtrpc.CallerID\x12\x32\n\x13immediate_caller_id\x18\x02 \x01(\x0b\x32\x15.query.VTGateCallerID\x12\x1d\n\x06target\x18\x03 \x01(\x0b\x32\r.query.Target\x12\x10\n\x08position\x18\x04 \x01(\t\x12\"\n\x06\x66ilter\x18\x05 \x01(\x0b\x32\x12.binlogdata.Filter\"5\n\x0fVStreamResponse\x12\"\n\x06\x65vents\x18\x01 \x03(\x0b\x32\x12.binlogdata.VEvent\"\xc8\x01\n\x12VStreamRowsRequest\x12,\n\x13\x65\x66\x66\x65\x63tive_caller_id\x18\x01 \x01(\x0b\x32\x0f.vtrpc.CallerID\x12\x32\n\x13immediate_caller_id\x18\x02 \x01(\x0b\x32\x15.query.VTGateCallerID\x12\x1d\n\x06target\x18\x03 \x01(\x0b\x32\r.query.Target\x12\r\n\x05query\x18\x04 \x01(\t\x12\"\n\x06lastpk\x18\x05 \x01(\x0b\x32\x12.query.QueryResult\"\x97\x01\n\x13VStreamRowsResponse\x12\x1c\n\x06\x66ields\x18\x01 \x03(\x0b\x32\x0c.query.Field\x12\x1e\n\x08pkfields\x18\x02 \x03(\x0b\x32\x0c.query.Field\x12\x0c\n\x04gtid\x18\x03 \x01(\t\x12\x18\n\x04rows\x18\x04 \x03(\x0b\x32\n.query.Row\x12\x1a\n\x06lastpk\x18\x05 \x01(\x0b\x32\n.query.Row\"\xa7\x01\n\x15VStreamResultsRequest\x12,\n\x13\x65\x66\x66\x65\x63tive_caller_id\x18\x01 \x01(\x0b\x32\x0f.vtrpc.CallerID\x12\x32\n\x13immediate_caller_id\x18\x02 \x01(\x0b\x32\x15.query.VTGateCallerID\x12\x1d\n\x06target\x18\x03 \x01(\x0b\x32\r.query.Target\x12\r\n\x05query\x18\x04 \x01(\t\"^\n\x16VStreamResultsResponse\x12\x1c\n\x06\x66ields\x18\x01 \x03(\x0b\x32\x0c.query.Field\x12\x0c\n\x04gtid\x18\x03 \x01(\t\x12\x18\n\x04rows\x18\x04 \x03(\x0b\x32\n.query.Row*>\n\x0bOnDDLAction\x12\n\n\x06IGNORE\x10\x00\x12\x08\n\x04STOP\x10\x01\x12\x08\n\x04\x45XEC\x10\x02\x12\x0f\n\x0b\x45XEC_IGNORE\x10\x03*\xd1\x01\n\nVEventType\x12\x0b\n\x07UNKNOWN\x10\x00\x12\x08\n\x04GTID\x10\x01\x12\t\n\x05\x42\x45GIN\x10\x02\x12\n\n\x06\x43OMMIT\x10\x03\x12\x0c\n\x08ROLLBACK\x10\x04\x12\x07\n\x03\x44\x44L\x10\x05\x12\n\n\x06INSERT\x10\x06\x12\x0b\n\x07REPLACE\x10\x07\x12\n\n\x06UPDATE\x10\x08\x12\n\n\x06\x44\x45LETE\x10\t\x12\x07\n\x03SET\x10\n\x12\t\n\x05OTHER\x10\x0b\x12\x07\n\x03ROW\x10\x0c\x12\t\n\x05\x46IELD\x10\r\x12\r\n\tHEARTBEAT\x10\x0e\x12\t\n\x05VGTID\x10\x0f\x12\x0b\n\x07JOURNAL\x10\x10*\'\n\rMigrationType\x12\n\n\x06TABLES\x10\x00\x12\n\n\x06SHARDS\x10\x01\x42)Z\'vitess.io/vitess/go/vt/proto/binlogdatab\x06proto3') , dependencies=[vtrpc__pb2.DESCRIPTOR,query__pb2.DESCRIPTOR,topodata__pb2.DESCRIPTOR,]) @@ -52,8 +52,8 @@ ], containing_type=None, serialized_options=None, - serialized_start=2751, - serialized_end=2813, + serialized_start=3137, + serialized_end=3199, ) _sym_db.RegisterEnumDescriptor(_ONDDLACTION) @@ -135,8 +135,8 @@ ], containing_type=None, serialized_options=None, - serialized_start=2816, - serialized_end=3025, + serialized_start=3202, + serialized_end=3411, ) _sym_db.RegisterEnumDescriptor(_VEVENTTYPE) @@ -158,8 +158,8 @@ ], containing_type=None, serialized_options=None, - serialized_start=3027, - serialized_end=3066, + serialized_start=3413, + serialized_end=3452, ) _sym_db.RegisterEnumDescriptor(_MIGRATIONTYPE) @@ -243,6 +243,28 @@ ) _sym_db.RegisterEnumDescriptor(_BINLOGTRANSACTION_STATEMENT_CATEGORY) +_FILTER_FIELDEVENTMODE = _descriptor.EnumDescriptor( + name='FieldEventMode', + full_name='binlogdata.Filter.FieldEventMode', + filename=None, + file=DESCRIPTOR, + values=[ + _descriptor.EnumValueDescriptor( + name='ERR_ON_MISMATCH', index=0, number=0, + serialized_options=None, + type=None), + _descriptor.EnumValueDescriptor( + name='BEST_EFFORT', index=1, number=1, + serialized_options=None, + type=None), + ], + containing_type=None, + serialized_options=None, + serialized_start=1096, + serialized_end=1150, +) +_sym_db.RegisterEnumDescriptor(_FILTER_FIELDEVENTMODE) + _CHARSET = _descriptor.Descriptor( name='Charset', @@ -576,11 +598,19 @@ message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='fieldEventMode', full_name='binlogdata.Filter.fieldEventMode', index=1, + number=2, type=14, cpp_type=8, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), ], extensions=[ ], nested_types=[], enum_types=[ + _FILTER_FIELDEVENTMODE, ], serialized_options=None, is_extendable=False, @@ -588,8 +618,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=993, - serialized_end=1034, + serialized_start=994, + serialized_end=1150, ) @@ -661,8 +691,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=1037, - serialized_end=1259, + serialized_start=1153, + serialized_end=1375, ) @@ -699,8 +729,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=1261, - serialized_end=1327, + serialized_start=1377, + serialized_end=1443, ) @@ -737,8 +767,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=1329, - serialized_end=1403, + serialized_start=1445, + serialized_end=1519, ) @@ -775,8 +805,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=1405, - serialized_end=1467, + serialized_start=1521, + serialized_end=1583, ) @@ -820,8 +850,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=1469, - serialized_end=1527, + serialized_start=1585, + serialized_end=1643, ) @@ -851,8 +881,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=1529, - serialized_end=1580, + serialized_start=1645, + serialized_end=1696, ) @@ -889,8 +919,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=1582, - serialized_end=1630, + serialized_start=1698, + serialized_end=1746, ) @@ -944,8 +974,8 @@ is_extension=False, extension_scope=None, serialized_options=None, file=DESCRIPTOR), _descriptor.FieldDescriptor( - name='reversed_ids', full_name='binlogdata.Journal.reversed_ids', index=6, - number=7, type=3, cpp_type=2, label=3, + name='source_workflows', full_name='binlogdata.Journal.source_workflows', index=6, + number=7, type=9, cpp_type=9, label=3, has_default_value=False, default_value=[], message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, @@ -962,8 +992,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=1633, - serialized_end=1860, + serialized_start=1749, + serialized_end=1980, ) @@ -1049,8 +1079,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=1863, - serialized_end=2135, + serialized_start=1983, + serialized_end=2255, ) @@ -1108,8 +1138,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=2138, - serialized_end=2337, + serialized_start=2258, + serialized_end=2457, ) @@ -1139,8 +1169,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=2339, - serialized_end=2392, + serialized_start=2459, + serialized_end=2512, ) @@ -1198,8 +1228,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=2395, - serialized_end=2595, + serialized_start=2515, + serialized_end=2715, ) @@ -1257,8 +1287,105 @@ extension_ranges=[], oneofs=[ ], - serialized_start=2598, - serialized_end=2749, + serialized_start=2718, + serialized_end=2869, +) + + +_VSTREAMRESULTSREQUEST = _descriptor.Descriptor( + name='VStreamResultsRequest', + full_name='binlogdata.VStreamResultsRequest', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='effective_caller_id', full_name='binlogdata.VStreamResultsRequest.effective_caller_id', index=0, + number=1, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='immediate_caller_id', full_name='binlogdata.VStreamResultsRequest.immediate_caller_id', index=1, + number=2, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='target', full_name='binlogdata.VStreamResultsRequest.target', index=2, + number=3, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='query', full_name='binlogdata.VStreamResultsRequest.query', index=3, + number=4, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=2872, + serialized_end=3039, +) + + +_VSTREAMRESULTSRESPONSE = _descriptor.Descriptor( + name='VStreamResultsResponse', + full_name='binlogdata.VStreamResultsResponse', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='fields', full_name='binlogdata.VStreamResultsResponse.fields', index=0, + number=1, type=11, cpp_type=10, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='gtid', full_name='binlogdata.VStreamResultsResponse.gtid', index=1, + number=3, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='rows', full_name='binlogdata.VStreamResultsResponse.rows', index=2, + number=4, type=11, cpp_type=10, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=3041, + serialized_end=3135, ) _BINLOGTRANSACTION_STATEMENT.fields_by_name['category'].enum_type = _BINLOGTRANSACTION_STATEMENT_CATEGORY @@ -1273,6 +1400,8 @@ _STREAMTABLESREQUEST.fields_by_name['charset'].message_type = _CHARSET _STREAMTABLESRESPONSE.fields_by_name['binlog_transaction'].message_type = _BINLOGTRANSACTION _FILTER.fields_by_name['rules'].message_type = _RULE +_FILTER.fields_by_name['fieldEventMode'].enum_type = _FILTER_FIELDEVENTMODE +_FILTER_FIELDEVENTMODE.containing_type = _FILTER _BINLOGSOURCE.fields_by_name['tablet_type'].enum_type = topodata__pb2._TABLETTYPE _BINLOGSOURCE.fields_by_name['key_range'].message_type = topodata__pb2._KEYRANGE _BINLOGSOURCE.fields_by_name['filter'].message_type = _FILTER @@ -1303,6 +1432,11 @@ _VSTREAMROWSRESPONSE.fields_by_name['pkfields'].message_type = query__pb2._FIELD _VSTREAMROWSRESPONSE.fields_by_name['rows'].message_type = query__pb2._ROW _VSTREAMROWSRESPONSE.fields_by_name['lastpk'].message_type = query__pb2._ROW +_VSTREAMRESULTSREQUEST.fields_by_name['effective_caller_id'].message_type = vtrpc__pb2._CALLERID +_VSTREAMRESULTSREQUEST.fields_by_name['immediate_caller_id'].message_type = query__pb2._VTGATECALLERID +_VSTREAMRESULTSREQUEST.fields_by_name['target'].message_type = query__pb2._TARGET +_VSTREAMRESULTSRESPONSE.fields_by_name['fields'].message_type = query__pb2._FIELD +_VSTREAMRESULTSRESPONSE.fields_by_name['rows'].message_type = query__pb2._ROW DESCRIPTOR.message_types_by_name['Charset'] = _CHARSET DESCRIPTOR.message_types_by_name['BinlogTransaction'] = _BINLOGTRANSACTION DESCRIPTOR.message_types_by_name['StreamKeyRangeRequest'] = _STREAMKEYRANGEREQUEST @@ -1324,6 +1458,8 @@ DESCRIPTOR.message_types_by_name['VStreamResponse'] = _VSTREAMRESPONSE DESCRIPTOR.message_types_by_name['VStreamRowsRequest'] = _VSTREAMROWSREQUEST DESCRIPTOR.message_types_by_name['VStreamRowsResponse'] = _VSTREAMROWSRESPONSE +DESCRIPTOR.message_types_by_name['VStreamResultsRequest'] = _VSTREAMRESULTSREQUEST +DESCRIPTOR.message_types_by_name['VStreamResultsResponse'] = _VSTREAMRESULTSRESPONSE DESCRIPTOR.enum_types_by_name['OnDDLAction'] = _ONDDLACTION DESCRIPTOR.enum_types_by_name['VEventType'] = _VEVENTTYPE DESCRIPTOR.enum_types_by_name['MigrationType'] = _MIGRATIONTYPE @@ -1484,6 +1620,20 @@ )) _sym_db.RegisterMessage(VStreamRowsResponse) +VStreamResultsRequest = _reflection.GeneratedProtocolMessageType('VStreamResultsRequest', (_message.Message,), dict( + DESCRIPTOR = _VSTREAMRESULTSREQUEST, + __module__ = 'binlogdata_pb2' + # @@protoc_insertion_point(class_scope:binlogdata.VStreamResultsRequest) + )) +_sym_db.RegisterMessage(VStreamResultsRequest) + +VStreamResultsResponse = _reflection.GeneratedProtocolMessageType('VStreamResultsResponse', (_message.Message,), dict( + DESCRIPTOR = _VSTREAMRESULTSRESPONSE, + __module__ = 'binlogdata_pb2' + # @@protoc_insertion_point(class_scope:binlogdata.VStreamResultsResponse) + )) +_sym_db.RegisterMessage(VStreamResultsResponse) + DESCRIPTOR._options = None # @@protoc_insertion_point(module_scope) diff --git a/py/vtproto/logutil_pb2.py b/py/vtproto/logutil_pb2.py index 7f8d6d237e5..afa2bac4050 100644 --- a/py/vtproto/logutil_pb2.py +++ b/py/vtproto/logutil_pb2.py @@ -8,20 +8,22 @@ from google.protobuf import message as _message from google.protobuf import reflection as _reflection from google.protobuf import symbol_database as _symbol_database -from google.protobuf import descriptor_pb2 # @@protoc_insertion_point(imports) _sym_db = _symbol_database.Default() +import time_pb2 as time__pb2 DESCRIPTOR = _descriptor.FileDescriptor( name='logutil.proto', package='logutil', syntax='proto3', - serialized_pb=_b('\n\rlogutil.proto\x12\x07logutil\",\n\x04Time\x12\x0f\n\x07seconds\x18\x01 \x01(\x03\x12\x13\n\x0bnanoseconds\x18\x02 \x01(\x05\"n\n\x05\x45vent\x12\x1b\n\x04time\x18\x01 \x01(\x0b\x32\r.logutil.Time\x12\x1d\n\x05level\x18\x02 \x01(\x0e\x32\x0e.logutil.Level\x12\x0c\n\x04\x66ile\x18\x03 \x01(\t\x12\x0c\n\x04line\x18\x04 \x01(\x03\x12\r\n\x05value\x18\x05 \x01(\t*6\n\x05Level\x12\x08\n\x04INFO\x10\x00\x12\x0b\n\x07WARNING\x10\x01\x12\t\n\x05\x45RROR\x10\x02\x12\x0b\n\x07\x43ONSOLE\x10\x03\x42&Z$vitess.io/vitess/go/vt/proto/logutilb\x06proto3') -) + serialized_options=_b('Z$vitess.io/vitess/go/vt/proto/logutil'), + serialized_pb=_b('\n\rlogutil.proto\x12\x07logutil\x1a\ntime.proto\"m\n\x05\x45vent\x12\x1a\n\x04time\x18\x01 \x01(\x0b\x32\x0c.vttime.Time\x12\x1d\n\x05level\x18\x02 \x01(\x0e\x32\x0e.logutil.Level\x12\x0c\n\x04\x66ile\x18\x03 \x01(\t\x12\x0c\n\x04line\x18\x04 \x01(\x03\x12\r\n\x05value\x18\x05 \x01(\t*6\n\x05Level\x12\x08\n\x04INFO\x10\x00\x12\x0b\n\x07WARNING\x10\x01\x12\t\n\x05\x45RROR\x10\x02\x12\x0b\n\x07\x43ONSOLE\x10\x03\x42&Z$vitess.io/vitess/go/vt/proto/logutilb\x06proto3') + , + dependencies=[time__pb2.DESCRIPTOR,]) _LEVEL = _descriptor.EnumDescriptor( name='Level', @@ -31,25 +33,25 @@ values=[ _descriptor.EnumValueDescriptor( name='INFO', index=0, number=0, - options=None, + serialized_options=None, type=None), _descriptor.EnumValueDescriptor( name='WARNING', index=1, number=1, - options=None, + serialized_options=None, type=None), _descriptor.EnumValueDescriptor( name='ERROR', index=2, number=2, - options=None, + serialized_options=None, type=None), _descriptor.EnumValueDescriptor( name='CONSOLE', index=3, number=3, - options=None, + serialized_options=None, type=None), ], containing_type=None, - options=None, - serialized_start=184, - serialized_end=238, + serialized_options=None, + serialized_start=149, + serialized_end=203, ) _sym_db.RegisterEnumDescriptor(_LEVEL) @@ -61,44 +63,6 @@ -_TIME = _descriptor.Descriptor( - name='Time', - full_name='logutil.Time', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='seconds', full_name='logutil.Time.seconds', index=0, - number=1, type=3, cpp_type=2, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='nanoseconds', full_name='logutil.Time.nanoseconds', index=1, - number=2, type=5, cpp_type=1, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=26, - serialized_end=70, -) - - _EVENT = _descriptor.Descriptor( name='Event', full_name='logutil.Event', @@ -112,65 +76,57 @@ has_default_value=False, default_value=None, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), + serialized_options=None, file=DESCRIPTOR), _descriptor.FieldDescriptor( name='level', full_name='logutil.Event.level', index=1, number=2, type=14, cpp_type=8, label=1, has_default_value=False, default_value=0, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), + serialized_options=None, file=DESCRIPTOR), _descriptor.FieldDescriptor( name='file', full_name='logutil.Event.file', index=2, number=3, type=9, cpp_type=9, label=1, has_default_value=False, default_value=_b("").decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), + serialized_options=None, file=DESCRIPTOR), _descriptor.FieldDescriptor( name='line', full_name='logutil.Event.line', index=3, number=4, type=3, cpp_type=2, label=1, has_default_value=False, default_value=0, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), + serialized_options=None, file=DESCRIPTOR), _descriptor.FieldDescriptor( name='value', full_name='logutil.Event.value', index=4, number=5, type=9, cpp_type=9, label=1, has_default_value=False, default_value=_b("").decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), + serialized_options=None, file=DESCRIPTOR), ], extensions=[ ], nested_types=[], enum_types=[ ], - options=None, + serialized_options=None, is_extendable=False, syntax='proto3', extension_ranges=[], oneofs=[ ], - serialized_start=72, - serialized_end=182, + serialized_start=38, + serialized_end=147, ) -_EVENT.fields_by_name['time'].message_type = _TIME +_EVENT.fields_by_name['time'].message_type = time__pb2._TIME _EVENT.fields_by_name['level'].enum_type = _LEVEL -DESCRIPTOR.message_types_by_name['Time'] = _TIME DESCRIPTOR.message_types_by_name['Event'] = _EVENT DESCRIPTOR.enum_types_by_name['Level'] = _LEVEL _sym_db.RegisterFileDescriptor(DESCRIPTOR) -Time = _reflection.GeneratedProtocolMessageType('Time', (_message.Message,), dict( - DESCRIPTOR = _TIME, - __module__ = 'logutil_pb2' - # @@protoc_insertion_point(class_scope:logutil.Time) - )) -_sym_db.RegisterMessage(Time) - Event = _reflection.GeneratedProtocolMessageType('Event', (_message.Message,), dict( DESCRIPTOR = _EVENT, __module__ = 'logutil_pb2' @@ -179,6 +135,5 @@ _sym_db.RegisterMessage(Event) -DESCRIPTOR.has_options = True -DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), _b('Z$vitess.io/vitess/go/vt/proto/logutil')) +DESCRIPTOR._options = None # @@protoc_insertion_point(module_scope) diff --git a/py/vtproto/queryservice_pb2.py b/py/vtproto/queryservice_pb2.py index 986c7701187..b7082eaf642 100644 --- a/py/vtproto/queryservice_pb2.py +++ b/py/vtproto/queryservice_pb2.py @@ -21,7 +21,7 @@ package='queryservice', syntax='proto3', serialized_options=_b('Z)vitess.io/vitess/go/vt/proto/queryservice'), - serialized_pb=_b('\n\x12queryservice.proto\x12\x0cqueryservice\x1a\x0bquery.proto\x1a\x10\x62inlogdata.proto2\xc3\r\n\x05Query\x12:\n\x07\x45xecute\x12\x15.query.ExecuteRequest\x1a\x16.query.ExecuteResponse\"\x00\x12I\n\x0c\x45xecuteBatch\x12\x1a.query.ExecuteBatchRequest\x1a\x1b.query.ExecuteBatchResponse\"\x00\x12N\n\rStreamExecute\x12\x1b.query.StreamExecuteRequest\x1a\x1c.query.StreamExecuteResponse\"\x00\x30\x01\x12\x34\n\x05\x42\x65gin\x12\x13.query.BeginRequest\x1a\x14.query.BeginResponse\"\x00\x12\x37\n\x06\x43ommit\x12\x14.query.CommitRequest\x1a\x15.query.CommitResponse\"\x00\x12=\n\x08Rollback\x12\x16.query.RollbackRequest\x1a\x17.query.RollbackResponse\"\x00\x12:\n\x07Prepare\x12\x15.query.PrepareRequest\x1a\x16.query.PrepareResponse\"\x00\x12O\n\x0e\x43ommitPrepared\x12\x1c.query.CommitPreparedRequest\x1a\x1d.query.CommitPreparedResponse\"\x00\x12U\n\x10RollbackPrepared\x12\x1e.query.RollbackPreparedRequest\x1a\x1f.query.RollbackPreparedResponse\"\x00\x12X\n\x11\x43reateTransaction\x12\x1f.query.CreateTransactionRequest\x1a .query.CreateTransactionResponse\"\x00\x12\x46\n\x0bStartCommit\x12\x19.query.StartCommitRequest\x1a\x1a.query.StartCommitResponse\"\x00\x12\x46\n\x0bSetRollback\x12\x19.query.SetRollbackRequest\x1a\x1a.query.SetRollbackResponse\"\x00\x12^\n\x13\x43oncludeTransaction\x12!.query.ConcludeTransactionRequest\x1a\".query.ConcludeTransactionResponse\"\x00\x12R\n\x0fReadTransaction\x12\x1d.query.ReadTransactionRequest\x1a\x1e.query.ReadTransactionResponse\"\x00\x12I\n\x0c\x42\x65ginExecute\x12\x1a.query.BeginExecuteRequest\x1a\x1b.query.BeginExecuteResponse\"\x00\x12X\n\x11\x42\x65ginExecuteBatch\x12\x1f.query.BeginExecuteBatchRequest\x1a .query.BeginExecuteBatchResponse\"\x00\x12N\n\rMessageStream\x12\x1b.query.MessageStreamRequest\x1a\x1c.query.MessageStreamResponse\"\x00\x30\x01\x12\x43\n\nMessageAck\x12\x18.query.MessageAckRequest\x1a\x19.query.MessageAckResponse\"\x00\x12\x43\n\nSplitQuery\x12\x18.query.SplitQueryRequest\x1a\x19.query.SplitQueryResponse\"\x00\x12K\n\x0cStreamHealth\x12\x1a.query.StreamHealthRequest\x1a\x1b.query.StreamHealthResponse\"\x00\x30\x01\x12K\n\x0cUpdateStream\x12\x1a.query.UpdateStreamRequest\x1a\x1b.query.UpdateStreamResponse\"\x00\x30\x01\x12\x46\n\x07VStream\x12\x1a.binlogdata.VStreamRequest\x1a\x1b.binlogdata.VStreamResponse\"\x00\x30\x01\x12R\n\x0bVStreamRows\x12\x1e.binlogdata.VStreamRowsRequest\x1a\x1f.binlogdata.VStreamRowsResponse\"\x00\x30\x01\x42+Z)vitess.io/vitess/go/vt/proto/queryserviceb\x06proto3') + serialized_pb=_b('\n\x12queryservice.proto\x12\x0cqueryservice\x1a\x0bquery.proto\x1a\x10\x62inlogdata.proto2\xa0\x0e\n\x05Query\x12:\n\x07\x45xecute\x12\x15.query.ExecuteRequest\x1a\x16.query.ExecuteResponse\"\x00\x12I\n\x0c\x45xecuteBatch\x12\x1a.query.ExecuteBatchRequest\x1a\x1b.query.ExecuteBatchResponse\"\x00\x12N\n\rStreamExecute\x12\x1b.query.StreamExecuteRequest\x1a\x1c.query.StreamExecuteResponse\"\x00\x30\x01\x12\x34\n\x05\x42\x65gin\x12\x13.query.BeginRequest\x1a\x14.query.BeginResponse\"\x00\x12\x37\n\x06\x43ommit\x12\x14.query.CommitRequest\x1a\x15.query.CommitResponse\"\x00\x12=\n\x08Rollback\x12\x16.query.RollbackRequest\x1a\x17.query.RollbackResponse\"\x00\x12:\n\x07Prepare\x12\x15.query.PrepareRequest\x1a\x16.query.PrepareResponse\"\x00\x12O\n\x0e\x43ommitPrepared\x12\x1c.query.CommitPreparedRequest\x1a\x1d.query.CommitPreparedResponse\"\x00\x12U\n\x10RollbackPrepared\x12\x1e.query.RollbackPreparedRequest\x1a\x1f.query.RollbackPreparedResponse\"\x00\x12X\n\x11\x43reateTransaction\x12\x1f.query.CreateTransactionRequest\x1a .query.CreateTransactionResponse\"\x00\x12\x46\n\x0bStartCommit\x12\x19.query.StartCommitRequest\x1a\x1a.query.StartCommitResponse\"\x00\x12\x46\n\x0bSetRollback\x12\x19.query.SetRollbackRequest\x1a\x1a.query.SetRollbackResponse\"\x00\x12^\n\x13\x43oncludeTransaction\x12!.query.ConcludeTransactionRequest\x1a\".query.ConcludeTransactionResponse\"\x00\x12R\n\x0fReadTransaction\x12\x1d.query.ReadTransactionRequest\x1a\x1e.query.ReadTransactionResponse\"\x00\x12I\n\x0c\x42\x65ginExecute\x12\x1a.query.BeginExecuteRequest\x1a\x1b.query.BeginExecuteResponse\"\x00\x12X\n\x11\x42\x65ginExecuteBatch\x12\x1f.query.BeginExecuteBatchRequest\x1a .query.BeginExecuteBatchResponse\"\x00\x12N\n\rMessageStream\x12\x1b.query.MessageStreamRequest\x1a\x1c.query.MessageStreamResponse\"\x00\x30\x01\x12\x43\n\nMessageAck\x12\x18.query.MessageAckRequest\x1a\x19.query.MessageAckResponse\"\x00\x12\x43\n\nSplitQuery\x12\x18.query.SplitQueryRequest\x1a\x19.query.SplitQueryResponse\"\x00\x12K\n\x0cStreamHealth\x12\x1a.query.StreamHealthRequest\x1a\x1b.query.StreamHealthResponse\"\x00\x30\x01\x12K\n\x0cUpdateStream\x12\x1a.query.UpdateStreamRequest\x1a\x1b.query.UpdateStreamResponse\"\x00\x30\x01\x12\x46\n\x07VStream\x12\x1a.binlogdata.VStreamRequest\x1a\x1b.binlogdata.VStreamResponse\"\x00\x30\x01\x12R\n\x0bVStreamRows\x12\x1e.binlogdata.VStreamRowsRequest\x1a\x1f.binlogdata.VStreamRowsResponse\"\x00\x30\x01\x12[\n\x0eVStreamResults\x12!.binlogdata.VStreamResultsRequest\x1a\".binlogdata.VStreamResultsResponse\"\x00\x30\x01\x42+Z)vitess.io/vitess/go/vt/proto/queryserviceb\x06proto3') , dependencies=[query__pb2.DESCRIPTOR,binlogdata__pb2.DESCRIPTOR,]) @@ -39,7 +39,7 @@ index=0, serialized_options=None, serialized_start=68, - serialized_end=1799, + serialized_end=1892, methods=[ _descriptor.MethodDescriptor( name='Execute', @@ -248,6 +248,15 @@ output_type=binlogdata__pb2._VSTREAMROWSRESPONSE, serialized_options=None, ), + _descriptor.MethodDescriptor( + name='VStreamResults', + full_name='queryservice.Query.VStreamResults', + index=23, + containing_service=None, + input_type=binlogdata__pb2._VSTREAMRESULTSREQUEST, + output_type=binlogdata__pb2._VSTREAMRESULTSRESPONSE, + serialized_options=None, + ), ]) _sym_db.RegisterServiceDescriptor(_QUERY) diff --git a/py/vtproto/queryservice_pb2_grpc.py b/py/vtproto/queryservice_pb2_grpc.py index f6d80e62adc..f8d31b3ce3e 100644 --- a/py/vtproto/queryservice_pb2_grpc.py +++ b/py/vtproto/queryservice_pb2_grpc.py @@ -130,6 +130,11 @@ def __init__(self, channel): request_serializer=binlogdata__pb2.VStreamRowsRequest.SerializeToString, response_deserializer=binlogdata__pb2.VStreamRowsResponse.FromString, ) + self.VStreamResults = channel.unary_stream( + '/queryservice.Query/VStreamResults', + request_serializer=binlogdata__pb2.VStreamResultsRequest.SerializeToString, + response_deserializer=binlogdata__pb2.VStreamResultsResponse.FromString, + ) class QueryServicer(object): @@ -304,6 +309,13 @@ def VStreamRows(self, request, context): context.set_details('Method not implemented!') raise NotImplementedError('Method not implemented!') + def VStreamResults(self, request, context): + """VStreamResults streams results along with the gtid of the snapshot. + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + def add_QueryServicer_to_server(servicer, server): rpc_method_handlers = { @@ -422,6 +434,11 @@ def add_QueryServicer_to_server(servicer, server): request_deserializer=binlogdata__pb2.VStreamRowsRequest.FromString, response_serializer=binlogdata__pb2.VStreamRowsResponse.SerializeToString, ), + 'VStreamResults': grpc.unary_stream_rpc_method_handler( + servicer.VStreamResults, + request_deserializer=binlogdata__pb2.VStreamResultsRequest.FromString, + response_serializer=binlogdata__pb2.VStreamResultsResponse.SerializeToString, + ), } generic_handler = grpc.method_handlers_generic_handler( 'queryservice.Query', rpc_method_handlers) diff --git a/py/vtproto/tabletmanagerdata_pb2.py b/py/vtproto/tabletmanagerdata_pb2.py index 1a623c83833..0b246f994d9 100644 --- a/py/vtproto/tabletmanagerdata_pb2.py +++ b/py/vtproto/tabletmanagerdata_pb2.py @@ -23,7 +23,7 @@ package='tabletmanagerdata', syntax='proto3', serialized_options=_b('Z.vitess.io/vitess/go/vt/proto/tabletmanagerdata'), - serialized_pb=_b('\n\x17tabletmanagerdata.proto\x12\x11tabletmanagerdata\x1a\x0bquery.proto\x1a\x0etopodata.proto\x1a\x15replicationdata.proto\x1a\rlogutil.proto\"\x93\x01\n\x0fTableDefinition\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0e\n\x06schema\x18\x02 \x01(\t\x12\x0f\n\x07\x63olumns\x18\x03 \x03(\t\x12\x1b\n\x13primary_key_columns\x18\x04 \x03(\t\x12\x0c\n\x04type\x18\x05 \x01(\t\x12\x13\n\x0b\x64\x61ta_length\x18\x06 \x01(\x04\x12\x11\n\trow_count\x18\x07 \x01(\x04\"{\n\x10SchemaDefinition\x12\x17\n\x0f\x64\x61tabase_schema\x18\x01 \x01(\t\x12=\n\x11table_definitions\x18\x02 \x03(\x0b\x32\".tabletmanagerdata.TableDefinition\x12\x0f\n\x07version\x18\x03 \x01(\t\"\x8b\x01\n\x12SchemaChangeResult\x12:\n\rbefore_schema\x18\x01 \x01(\x0b\x32#.tabletmanagerdata.SchemaDefinition\x12\x39\n\x0c\x61\x66ter_schema\x18\x02 \x01(\x0b\x32#.tabletmanagerdata.SchemaDefinition\"\xc1\x01\n\x0eUserPermission\x12\x0c\n\x04host\x18\x01 \x01(\t\x12\x0c\n\x04user\x18\x02 \x01(\t\x12\x19\n\x11password_checksum\x18\x03 \x01(\x04\x12\x45\n\nprivileges\x18\x04 \x03(\x0b\x32\x31.tabletmanagerdata.UserPermission.PrivilegesEntry\x1a\x31\n\x0fPrivilegesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"\xae\x01\n\x0c\x44\x62Permission\x12\x0c\n\x04host\x18\x01 \x01(\t\x12\n\n\x02\x64\x62\x18\x02 \x01(\t\x12\x0c\n\x04user\x18\x03 \x01(\t\x12\x43\n\nprivileges\x18\x04 \x03(\x0b\x32/.tabletmanagerdata.DbPermission.PrivilegesEntry\x1a\x31\n\x0fPrivilegesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"\x83\x01\n\x0bPermissions\x12;\n\x10user_permissions\x18\x01 \x03(\x0b\x32!.tabletmanagerdata.UserPermission\x12\x37\n\x0e\x64\x62_permissions\x18\x02 \x03(\x0b\x32\x1f.tabletmanagerdata.DbPermission\"\x1e\n\x0bPingRequest\x12\x0f\n\x07payload\x18\x01 \x01(\t\"\x1f\n\x0cPingResponse\x12\x0f\n\x07payload\x18\x01 \x01(\t\" \n\x0cSleepRequest\x12\x10\n\x08\x64uration\x18\x01 \x01(\x03\"\x0f\n\rSleepResponse\"\xaf\x01\n\x12\x45xecuteHookRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x12\n\nparameters\x18\x02 \x03(\t\x12\x46\n\textra_env\x18\x03 \x03(\x0b\x32\x33.tabletmanagerdata.ExecuteHookRequest.ExtraEnvEntry\x1a/\n\rExtraEnvEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"J\n\x13\x45xecuteHookResponse\x12\x13\n\x0b\x65xit_status\x18\x01 \x01(\x03\x12\x0e\n\x06stdout\x18\x02 \x01(\t\x12\x0e\n\x06stderr\x18\x03 \x01(\t\"Q\n\x10GetSchemaRequest\x12\x0e\n\x06tables\x18\x01 \x03(\t\x12\x15\n\rinclude_views\x18\x02 \x01(\x08\x12\x16\n\x0e\x65xclude_tables\x18\x03 \x03(\t\"S\n\x11GetSchemaResponse\x12>\n\x11schema_definition\x18\x01 \x01(\x0b\x32#.tabletmanagerdata.SchemaDefinition\"\x17\n\x15GetPermissionsRequest\"M\n\x16GetPermissionsResponse\x12\x33\n\x0bpermissions\x18\x01 \x01(\x0b\x32\x1e.tabletmanagerdata.Permissions\"\x14\n\x12SetReadOnlyRequest\"\x15\n\x13SetReadOnlyResponse\"\x15\n\x13SetReadWriteRequest\"\x16\n\x14SetReadWriteResponse\">\n\x11\x43hangeTypeRequest\x12)\n\x0btablet_type\x18\x01 \x01(\x0e\x32\x14.topodata.TabletType\"\x14\n\x12\x43hangeTypeResponse\"\x15\n\x13RefreshStateRequest\"\x16\n\x14RefreshStateResponse\"\x17\n\x15RunHealthCheckRequest\"\x18\n\x16RunHealthCheckResponse\"+\n\x18IgnoreHealthErrorRequest\x12\x0f\n\x07pattern\x18\x01 \x01(\t\"\x1b\n\x19IgnoreHealthErrorResponse\",\n\x13ReloadSchemaRequest\x12\x15\n\rwait_position\x18\x01 \x01(\t\"\x16\n\x14ReloadSchemaResponse\")\n\x16PreflightSchemaRequest\x12\x0f\n\x07\x63hanges\x18\x01 \x03(\t\"X\n\x17PreflightSchemaResponse\x12=\n\x0e\x63hange_results\x18\x01 \x03(\x0b\x32%.tabletmanagerdata.SchemaChangeResult\"\xc2\x01\n\x12\x41pplySchemaRequest\x12\x0b\n\x03sql\x18\x01 \x01(\t\x12\r\n\x05\x66orce\x18\x02 \x01(\x08\x12\x19\n\x11\x61llow_replication\x18\x03 \x01(\x08\x12:\n\rbefore_schema\x18\x04 \x01(\x0b\x32#.tabletmanagerdata.SchemaDefinition\x12\x39\n\x0c\x61\x66ter_schema\x18\x05 \x01(\x0b\x32#.tabletmanagerdata.SchemaDefinition\"\x8c\x01\n\x13\x41pplySchemaResponse\x12:\n\rbefore_schema\x18\x01 \x01(\x0b\x32#.tabletmanagerdata.SchemaDefinition\x12\x39\n\x0c\x61\x66ter_schema\x18\x02 \x01(\x0b\x32#.tabletmanagerdata.SchemaDefinition\"\x13\n\x11LockTablesRequest\"\x14\n\x12LockTablesResponse\"\x15\n\x13UnlockTablesRequest\"\x16\n\x14UnlockTablesResponse\"|\n\x18\x45xecuteFetchAsDbaRequest\x12\r\n\x05query\x18\x01 \x01(\x0c\x12\x0f\n\x07\x64\x62_name\x18\x02 \x01(\t\x12\x10\n\x08max_rows\x18\x03 \x01(\x04\x12\x17\n\x0f\x64isable_binlogs\x18\x04 \x01(\x08\x12\x15\n\rreload_schema\x18\x05 \x01(\x08\"?\n\x19\x45xecuteFetchAsDbaResponse\x12\"\n\x06result\x18\x01 \x01(\x0b\x32\x12.query.QueryResult\"h\n\x1d\x45xecuteFetchAsAllPrivsRequest\x12\r\n\x05query\x18\x01 \x01(\x0c\x12\x0f\n\x07\x64\x62_name\x18\x02 \x01(\t\x12\x10\n\x08max_rows\x18\x03 \x01(\x04\x12\x15\n\rreload_schema\x18\x04 \x01(\x08\"D\n\x1e\x45xecuteFetchAsAllPrivsResponse\x12\"\n\x06result\x18\x01 \x01(\x0b\x32\x12.query.QueryResult\";\n\x18\x45xecuteFetchAsAppRequest\x12\r\n\x05query\x18\x01 \x01(\x0c\x12\x10\n\x08max_rows\x18\x02 \x01(\x04\"?\n\x19\x45xecuteFetchAsAppResponse\x12\"\n\x06result\x18\x01 \x01(\x0b\x32\x12.query.QueryResult\"\x14\n\x12SlaveStatusRequest\">\n\x13SlaveStatusResponse\x12\'\n\x06status\x18\x01 \x01(\x0b\x32\x17.replicationdata.Status\"\x17\n\x15MasterPositionRequest\"*\n\x16MasterPositionResponse\x12\x10\n\x08position\x18\x01 \x01(\t\"\x12\n\x10StopSlaveRequest\"\x13\n\x11StopSlaveResponse\"A\n\x17StopSlaveMinimumRequest\x12\x10\n\x08position\x18\x01 \x01(\t\x12\x14\n\x0cwait_timeout\x18\x02 \x01(\x03\",\n\x18StopSlaveMinimumResponse\x12\x10\n\x08position\x18\x01 \x01(\t\"\x13\n\x11StartSlaveRequest\"\x14\n\x12StartSlaveResponse\"E\n\x1bStartSlaveUntilAfterRequest\x12\x10\n\x08position\x18\x01 \x01(\t\x12\x14\n\x0cwait_timeout\x18\x02 \x01(\x03\"\x1e\n\x1cStartSlaveUntilAfterResponse\"8\n!TabletExternallyReparentedRequest\x12\x13\n\x0b\x65xternal_id\x18\x01 \x01(\t\"$\n\"TabletExternallyReparentedResponse\" \n\x1eTabletExternallyElectedRequest\"!\n\x1fTabletExternallyElectedResponse\"\x12\n\x10GetSlavesRequest\"\"\n\x11GetSlavesResponse\x12\r\n\x05\x61\x64\x64rs\x18\x01 \x03(\t\"\x19\n\x17ResetReplicationRequest\"\x1a\n\x18ResetReplicationResponse\"(\n\x17VReplicationExecRequest\x12\r\n\x05query\x18\x01 \x01(\t\">\n\x18VReplicationExecResponse\x12\"\n\x06result\x18\x01 \x01(\x0b\x32\x12.query.QueryResult\"=\n\x1dVReplicationWaitForPosRequest\x12\n\n\x02id\x18\x01 \x01(\x03\x12\x10\n\x08position\x18\x02 \x01(\t\" \n\x1eVReplicationWaitForPosResponse\"\x13\n\x11InitMasterRequest\"&\n\x12InitMasterResponse\x12\x10\n\x08position\x18\x01 \x01(\t\"\x99\x01\n\x1ePopulateReparentJournalRequest\x12\x17\n\x0ftime_created_ns\x18\x01 \x01(\x03\x12\x13\n\x0b\x61\x63tion_name\x18\x02 \x01(\t\x12+\n\x0cmaster_alias\x18\x03 \x01(\x0b\x32\x15.topodata.TabletAlias\x12\x1c\n\x14replication_position\x18\x04 \x01(\t\"!\n\x1fPopulateReparentJournalResponse\"p\n\x10InitSlaveRequest\x12%\n\x06parent\x18\x01 \x01(\x0b\x32\x15.topodata.TabletAlias\x12\x1c\n\x14replication_position\x18\x02 \x01(\t\x12\x17\n\x0ftime_created_ns\x18\x03 \x01(\x03\"\x13\n\x11InitSlaveResponse\"\x15\n\x13\x44\x65moteMasterRequest\"(\n\x14\x44\x65moteMasterResponse\x12\x10\n\x08position\x18\x01 \x01(\t\"\x19\n\x17UndoDemoteMasterRequest\"\x1a\n\x18UndoDemoteMasterResponse\"3\n\x1fPromoteSlaveWhenCaughtUpRequest\x12\x10\n\x08position\x18\x01 \x01(\t\"4\n PromoteSlaveWhenCaughtUpResponse\x12\x10\n\x08position\x18\x01 \x01(\t\"\x19\n\x17SlaveWasPromotedRequest\"\x1a\n\x18SlaveWasPromotedResponse\"m\n\x10SetMasterRequest\x12%\n\x06parent\x18\x01 \x01(\x0b\x32\x15.topodata.TabletAlias\x12\x17\n\x0ftime_created_ns\x18\x02 \x01(\x03\x12\x19\n\x11\x66orce_start_slave\x18\x03 \x01(\x08\"\x13\n\x11SetMasterResponse\"A\n\x18SlaveWasRestartedRequest\x12%\n\x06parent\x18\x01 \x01(\x0b\x32\x15.topodata.TabletAlias\"\x1b\n\x19SlaveWasRestartedResponse\"$\n\"StopReplicationAndGetStatusRequest\"N\n#StopReplicationAndGetStatusResponse\x12\'\n\x06status\x18\x01 \x01(\x0b\x32\x17.replicationdata.Status\"\x15\n\x13PromoteSlaveRequest\"(\n\x14PromoteSlaveResponse\x12\x10\n\x08position\x18\x01 \x01(\t\"9\n\rBackupRequest\x12\x13\n\x0b\x63oncurrency\x18\x01 \x01(\x03\x12\x13\n\x0b\x61llowMaster\x18\x02 \x01(\x08\"/\n\x0e\x42\x61\x63kupResponse\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.logutil.Event\"\x1a\n\x18RestoreFromBackupRequest\":\n\x19RestoreFromBackupResponse\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.logutil.EventB0Z.vitess.io/vitess/go/vt/proto/tabletmanagerdatab\x06proto3') + serialized_pb=_b('\n\x17tabletmanagerdata.proto\x12\x11tabletmanagerdata\x1a\x0bquery.proto\x1a\x0etopodata.proto\x1a\x15replicationdata.proto\x1a\rlogutil.proto\"\xb1\x01\n\x0fTableDefinition\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0e\n\x06schema\x18\x02 \x01(\t\x12\x0f\n\x07\x63olumns\x18\x03 \x03(\t\x12\x1b\n\x13primary_key_columns\x18\x04 \x03(\t\x12\x0c\n\x04type\x18\x05 \x01(\t\x12\x13\n\x0b\x64\x61ta_length\x18\x06 \x01(\x04\x12\x11\n\trow_count\x18\x07 \x01(\x04\x12\x1c\n\x06\x66ields\x18\x08 \x03(\x0b\x32\x0c.query.Field\"{\n\x10SchemaDefinition\x12\x17\n\x0f\x64\x61tabase_schema\x18\x01 \x01(\t\x12=\n\x11table_definitions\x18\x02 \x03(\x0b\x32\".tabletmanagerdata.TableDefinition\x12\x0f\n\x07version\x18\x03 \x01(\t\"\x8b\x01\n\x12SchemaChangeResult\x12:\n\rbefore_schema\x18\x01 \x01(\x0b\x32#.tabletmanagerdata.SchemaDefinition\x12\x39\n\x0c\x61\x66ter_schema\x18\x02 \x01(\x0b\x32#.tabletmanagerdata.SchemaDefinition\"\xc1\x01\n\x0eUserPermission\x12\x0c\n\x04host\x18\x01 \x01(\t\x12\x0c\n\x04user\x18\x02 \x01(\t\x12\x19\n\x11password_checksum\x18\x03 \x01(\x04\x12\x45\n\nprivileges\x18\x04 \x03(\x0b\x32\x31.tabletmanagerdata.UserPermission.PrivilegesEntry\x1a\x31\n\x0fPrivilegesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"\xae\x01\n\x0c\x44\x62Permission\x12\x0c\n\x04host\x18\x01 \x01(\t\x12\n\n\x02\x64\x62\x18\x02 \x01(\t\x12\x0c\n\x04user\x18\x03 \x01(\t\x12\x43\n\nprivileges\x18\x04 \x03(\x0b\x32/.tabletmanagerdata.DbPermission.PrivilegesEntry\x1a\x31\n\x0fPrivilegesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"\x83\x01\n\x0bPermissions\x12;\n\x10user_permissions\x18\x01 \x03(\x0b\x32!.tabletmanagerdata.UserPermission\x12\x37\n\x0e\x64\x62_permissions\x18\x02 \x03(\x0b\x32\x1f.tabletmanagerdata.DbPermission\"\x1e\n\x0bPingRequest\x12\x0f\n\x07payload\x18\x01 \x01(\t\"\x1f\n\x0cPingResponse\x12\x0f\n\x07payload\x18\x01 \x01(\t\" \n\x0cSleepRequest\x12\x10\n\x08\x64uration\x18\x01 \x01(\x03\"\x0f\n\rSleepResponse\"\xaf\x01\n\x12\x45xecuteHookRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x12\n\nparameters\x18\x02 \x03(\t\x12\x46\n\textra_env\x18\x03 \x03(\x0b\x32\x33.tabletmanagerdata.ExecuteHookRequest.ExtraEnvEntry\x1a/\n\rExtraEnvEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"J\n\x13\x45xecuteHookResponse\x12\x13\n\x0b\x65xit_status\x18\x01 \x01(\x03\x12\x0e\n\x06stdout\x18\x02 \x01(\t\x12\x0e\n\x06stderr\x18\x03 \x01(\t\"Q\n\x10GetSchemaRequest\x12\x0e\n\x06tables\x18\x01 \x03(\t\x12\x15\n\rinclude_views\x18\x02 \x01(\x08\x12\x16\n\x0e\x65xclude_tables\x18\x03 \x03(\t\"S\n\x11GetSchemaResponse\x12>\n\x11schema_definition\x18\x01 \x01(\x0b\x32#.tabletmanagerdata.SchemaDefinition\"\x17\n\x15GetPermissionsRequest\"M\n\x16GetPermissionsResponse\x12\x33\n\x0bpermissions\x18\x01 \x01(\x0b\x32\x1e.tabletmanagerdata.Permissions\"\x14\n\x12SetReadOnlyRequest\"\x15\n\x13SetReadOnlyResponse\"\x15\n\x13SetReadWriteRequest\"\x16\n\x14SetReadWriteResponse\">\n\x11\x43hangeTypeRequest\x12)\n\x0btablet_type\x18\x01 \x01(\x0e\x32\x14.topodata.TabletType\"\x14\n\x12\x43hangeTypeResponse\"\x15\n\x13RefreshStateRequest\"\x16\n\x14RefreshStateResponse\"\x17\n\x15RunHealthCheckRequest\"\x18\n\x16RunHealthCheckResponse\"+\n\x18IgnoreHealthErrorRequest\x12\x0f\n\x07pattern\x18\x01 \x01(\t\"\x1b\n\x19IgnoreHealthErrorResponse\",\n\x13ReloadSchemaRequest\x12\x15\n\rwait_position\x18\x01 \x01(\t\"\x16\n\x14ReloadSchemaResponse\")\n\x16PreflightSchemaRequest\x12\x0f\n\x07\x63hanges\x18\x01 \x03(\t\"X\n\x17PreflightSchemaResponse\x12=\n\x0e\x63hange_results\x18\x01 \x03(\x0b\x32%.tabletmanagerdata.SchemaChangeResult\"\xc2\x01\n\x12\x41pplySchemaRequest\x12\x0b\n\x03sql\x18\x01 \x01(\t\x12\r\n\x05\x66orce\x18\x02 \x01(\x08\x12\x19\n\x11\x61llow_replication\x18\x03 \x01(\x08\x12:\n\rbefore_schema\x18\x04 \x01(\x0b\x32#.tabletmanagerdata.SchemaDefinition\x12\x39\n\x0c\x61\x66ter_schema\x18\x05 \x01(\x0b\x32#.tabletmanagerdata.SchemaDefinition\"\x8c\x01\n\x13\x41pplySchemaResponse\x12:\n\rbefore_schema\x18\x01 \x01(\x0b\x32#.tabletmanagerdata.SchemaDefinition\x12\x39\n\x0c\x61\x66ter_schema\x18\x02 \x01(\x0b\x32#.tabletmanagerdata.SchemaDefinition\"\x13\n\x11LockTablesRequest\"\x14\n\x12LockTablesResponse\"\x15\n\x13UnlockTablesRequest\"\x16\n\x14UnlockTablesResponse\"|\n\x18\x45xecuteFetchAsDbaRequest\x12\r\n\x05query\x18\x01 \x01(\x0c\x12\x0f\n\x07\x64\x62_name\x18\x02 \x01(\t\x12\x10\n\x08max_rows\x18\x03 \x01(\x04\x12\x17\n\x0f\x64isable_binlogs\x18\x04 \x01(\x08\x12\x15\n\rreload_schema\x18\x05 \x01(\x08\"?\n\x19\x45xecuteFetchAsDbaResponse\x12\"\n\x06result\x18\x01 \x01(\x0b\x32\x12.query.QueryResult\"h\n\x1d\x45xecuteFetchAsAllPrivsRequest\x12\r\n\x05query\x18\x01 \x01(\x0c\x12\x0f\n\x07\x64\x62_name\x18\x02 \x01(\t\x12\x10\n\x08max_rows\x18\x03 \x01(\x04\x12\x15\n\rreload_schema\x18\x04 \x01(\x08\"D\n\x1e\x45xecuteFetchAsAllPrivsResponse\x12\"\n\x06result\x18\x01 \x01(\x0b\x32\x12.query.QueryResult\";\n\x18\x45xecuteFetchAsAppRequest\x12\r\n\x05query\x18\x01 \x01(\x0c\x12\x10\n\x08max_rows\x18\x02 \x01(\x04\"?\n\x19\x45xecuteFetchAsAppResponse\x12\"\n\x06result\x18\x01 \x01(\x0b\x32\x12.query.QueryResult\"\x14\n\x12SlaveStatusRequest\">\n\x13SlaveStatusResponse\x12\'\n\x06status\x18\x01 \x01(\x0b\x32\x17.replicationdata.Status\"\x17\n\x15MasterPositionRequest\"*\n\x16MasterPositionResponse\x12\x10\n\x08position\x18\x01 \x01(\t\"*\n\x16WaitForPositionRequest\x12\x10\n\x08position\x18\x01 \x01(\t\"\x19\n\x17WaitForPositionResponse\"\x12\n\x10StopSlaveRequest\"\x13\n\x11StopSlaveResponse\"A\n\x17StopSlaveMinimumRequest\x12\x10\n\x08position\x18\x01 \x01(\t\x12\x14\n\x0cwait_timeout\x18\x02 \x01(\x03\",\n\x18StopSlaveMinimumResponse\x12\x10\n\x08position\x18\x01 \x01(\t\"\x13\n\x11StartSlaveRequest\"\x14\n\x12StartSlaveResponse\"E\n\x1bStartSlaveUntilAfterRequest\x12\x10\n\x08position\x18\x01 \x01(\t\x12\x14\n\x0cwait_timeout\x18\x02 \x01(\x03\"\x1e\n\x1cStartSlaveUntilAfterResponse\"8\n!TabletExternallyReparentedRequest\x12\x13\n\x0b\x65xternal_id\x18\x01 \x01(\t\"$\n\"TabletExternallyReparentedResponse\" \n\x1eTabletExternallyElectedRequest\"!\n\x1fTabletExternallyElectedResponse\"\x12\n\x10GetSlavesRequest\"\"\n\x11GetSlavesResponse\x12\r\n\x05\x61\x64\x64rs\x18\x01 \x03(\t\"\x19\n\x17ResetReplicationRequest\"\x1a\n\x18ResetReplicationResponse\"(\n\x17VReplicationExecRequest\x12\r\n\x05query\x18\x01 \x01(\t\">\n\x18VReplicationExecResponse\x12\"\n\x06result\x18\x01 \x01(\x0b\x32\x12.query.QueryResult\"=\n\x1dVReplicationWaitForPosRequest\x12\n\n\x02id\x18\x01 \x01(\x03\x12\x10\n\x08position\x18\x02 \x01(\t\" \n\x1eVReplicationWaitForPosResponse\"\x13\n\x11InitMasterRequest\"&\n\x12InitMasterResponse\x12\x10\n\x08position\x18\x01 \x01(\t\"\x99\x01\n\x1ePopulateReparentJournalRequest\x12\x17\n\x0ftime_created_ns\x18\x01 \x01(\x03\x12\x13\n\x0b\x61\x63tion_name\x18\x02 \x01(\t\x12+\n\x0cmaster_alias\x18\x03 \x01(\x0b\x32\x15.topodata.TabletAlias\x12\x1c\n\x14replication_position\x18\x04 \x01(\t\"!\n\x1fPopulateReparentJournalResponse\"p\n\x10InitSlaveRequest\x12%\n\x06parent\x18\x01 \x01(\x0b\x32\x15.topodata.TabletAlias\x12\x1c\n\x14replication_position\x18\x02 \x01(\t\x12\x17\n\x0ftime_created_ns\x18\x03 \x01(\x03\"\x13\n\x11InitSlaveResponse\"\x15\n\x13\x44\x65moteMasterRequest\"(\n\x14\x44\x65moteMasterResponse\x12\x10\n\x08position\x18\x01 \x01(\t\"\x19\n\x17UndoDemoteMasterRequest\"\x1a\n\x18UndoDemoteMasterResponse\"3\n\x1fPromoteSlaveWhenCaughtUpRequest\x12\x10\n\x08position\x18\x01 \x01(\t\"4\n PromoteSlaveWhenCaughtUpResponse\x12\x10\n\x08position\x18\x01 \x01(\t\"\x19\n\x17SlaveWasPromotedRequest\"\x1a\n\x18SlaveWasPromotedResponse\"\x84\x01\n\x10SetMasterRequest\x12%\n\x06parent\x18\x01 \x01(\x0b\x32\x15.topodata.TabletAlias\x12\x17\n\x0ftime_created_ns\x18\x02 \x01(\x03\x12\x15\n\rwait_position\x18\x04 \x01(\t\x12\x19\n\x11\x66orce_start_slave\x18\x03 \x01(\x08\"\x13\n\x11SetMasterResponse\"A\n\x18SlaveWasRestartedRequest\x12%\n\x06parent\x18\x01 \x01(\x0b\x32\x15.topodata.TabletAlias\"\x1b\n\x19SlaveWasRestartedResponse\"$\n\"StopReplicationAndGetStatusRequest\"N\n#StopReplicationAndGetStatusResponse\x12\'\n\x06status\x18\x01 \x01(\x0b\x32\x17.replicationdata.Status\"\x15\n\x13PromoteSlaveRequest\"(\n\x14PromoteSlaveResponse\x12\x10\n\x08position\x18\x01 \x01(\t\"9\n\rBackupRequest\x12\x13\n\x0b\x63oncurrency\x18\x01 \x01(\x03\x12\x13\n\x0b\x61llowMaster\x18\x02 \x01(\x08\"/\n\x0e\x42\x61\x63kupResponse\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.logutil.Event\"\x1a\n\x18RestoreFromBackupRequest\":\n\x19RestoreFromBackupResponse\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.logutil.EventB0Z.vitess.io/vitess/go/vt/proto/tabletmanagerdatab\x06proto3') , dependencies=[query__pb2.DESCRIPTOR,topodata__pb2.DESCRIPTOR,replicationdata__pb2.DESCRIPTOR,logutil__pb2.DESCRIPTOR,]) @@ -86,6 +86,13 @@ message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='fields', full_name='tabletmanagerdata.TableDefinition.fields', index=7, + number=8, type=11, cpp_type=10, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), ], extensions=[ ], @@ -99,7 +106,7 @@ oneofs=[ ], serialized_start=114, - serialized_end=261, + serialized_end=291, ) @@ -143,8 +150,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=263, - serialized_end=386, + serialized_start=293, + serialized_end=416, ) @@ -181,8 +188,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=389, - serialized_end=528, + serialized_start=419, + serialized_end=558, ) @@ -219,8 +226,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=675, - serialized_end=724, + serialized_start=705, + serialized_end=754, ) _USERPERMISSION = _descriptor.Descriptor( @@ -270,8 +277,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=531, - serialized_end=724, + serialized_start=561, + serialized_end=754, ) @@ -308,8 +315,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=675, - serialized_end=724, + serialized_start=705, + serialized_end=754, ) _DBPERMISSION = _descriptor.Descriptor( @@ -359,8 +366,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=727, - serialized_end=901, + serialized_start=757, + serialized_end=931, ) @@ -397,8 +404,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=904, - serialized_end=1035, + serialized_start=934, + serialized_end=1065, ) @@ -428,8 +435,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=1037, - serialized_end=1067, + serialized_start=1067, + serialized_end=1097, ) @@ -459,8 +466,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=1069, - serialized_end=1100, + serialized_start=1099, + serialized_end=1130, ) @@ -490,8 +497,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=1102, - serialized_end=1134, + serialized_start=1132, + serialized_end=1164, ) @@ -514,8 +521,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=1136, - serialized_end=1151, + serialized_start=1166, + serialized_end=1181, ) @@ -552,8 +559,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=1282, - serialized_end=1329, + serialized_start=1312, + serialized_end=1359, ) _EXECUTEHOOKREQUEST = _descriptor.Descriptor( @@ -596,8 +603,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=1154, - serialized_end=1329, + serialized_start=1184, + serialized_end=1359, ) @@ -641,8 +648,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=1331, - serialized_end=1405, + serialized_start=1361, + serialized_end=1435, ) @@ -686,8 +693,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=1407, - serialized_end=1488, + serialized_start=1437, + serialized_end=1518, ) @@ -717,8 +724,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=1490, - serialized_end=1573, + serialized_start=1520, + serialized_end=1603, ) @@ -741,8 +748,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=1575, - serialized_end=1598, + serialized_start=1605, + serialized_end=1628, ) @@ -772,8 +779,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=1600, - serialized_end=1677, + serialized_start=1630, + serialized_end=1707, ) @@ -796,8 +803,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=1679, - serialized_end=1699, + serialized_start=1709, + serialized_end=1729, ) @@ -820,8 +827,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=1701, - serialized_end=1722, + serialized_start=1731, + serialized_end=1752, ) @@ -844,8 +851,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=1724, - serialized_end=1745, + serialized_start=1754, + serialized_end=1775, ) @@ -868,8 +875,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=1747, - serialized_end=1769, + serialized_start=1777, + serialized_end=1799, ) @@ -899,8 +906,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=1771, - serialized_end=1833, + serialized_start=1801, + serialized_end=1863, ) @@ -923,8 +930,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=1835, - serialized_end=1855, + serialized_start=1865, + serialized_end=1885, ) @@ -947,8 +954,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=1857, - serialized_end=1878, + serialized_start=1887, + serialized_end=1908, ) @@ -971,8 +978,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=1880, - serialized_end=1902, + serialized_start=1910, + serialized_end=1932, ) @@ -995,8 +1002,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=1904, - serialized_end=1927, + serialized_start=1934, + serialized_end=1957, ) @@ -1019,8 +1026,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=1929, - serialized_end=1953, + serialized_start=1959, + serialized_end=1983, ) @@ -1050,8 +1057,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=1955, - serialized_end=1998, + serialized_start=1985, + serialized_end=2028, ) @@ -1074,8 +1081,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=2000, - serialized_end=2027, + serialized_start=2030, + serialized_end=2057, ) @@ -1105,8 +1112,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=2029, - serialized_end=2073, + serialized_start=2059, + serialized_end=2103, ) @@ -1129,8 +1136,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=2075, - serialized_end=2097, + serialized_start=2105, + serialized_end=2127, ) @@ -1160,8 +1167,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=2099, - serialized_end=2140, + serialized_start=2129, + serialized_end=2170, ) @@ -1191,8 +1198,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=2142, - serialized_end=2230, + serialized_start=2172, + serialized_end=2260, ) @@ -1250,8 +1257,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=2233, - serialized_end=2427, + serialized_start=2263, + serialized_end=2457, ) @@ -1288,8 +1295,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=2430, - serialized_end=2570, + serialized_start=2460, + serialized_end=2600, ) @@ -1312,8 +1319,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=2572, - serialized_end=2591, + serialized_start=2602, + serialized_end=2621, ) @@ -1336,8 +1343,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=2593, - serialized_end=2613, + serialized_start=2623, + serialized_end=2643, ) @@ -1360,8 +1367,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=2615, - serialized_end=2636, + serialized_start=2645, + serialized_end=2666, ) @@ -1384,8 +1391,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=2638, - serialized_end=2660, + serialized_start=2668, + serialized_end=2690, ) @@ -1443,8 +1450,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=2662, - serialized_end=2786, + serialized_start=2692, + serialized_end=2816, ) @@ -1474,8 +1481,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=2788, - serialized_end=2851, + serialized_start=2818, + serialized_end=2881, ) @@ -1526,8 +1533,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=2853, - serialized_end=2957, + serialized_start=2883, + serialized_end=2987, ) @@ -1557,8 +1564,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=2959, - serialized_end=3027, + serialized_start=2989, + serialized_end=3057, ) @@ -1595,8 +1602,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=3029, - serialized_end=3088, + serialized_start=3059, + serialized_end=3118, ) @@ -1626,8 +1633,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=3090, - serialized_end=3153, + serialized_start=3120, + serialized_end=3183, ) @@ -1650,8 +1657,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=3155, - serialized_end=3175, + serialized_start=3185, + serialized_end=3205, ) @@ -1681,8 +1688,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=3177, - serialized_end=3239, + serialized_start=3207, + serialized_end=3269, ) @@ -1705,8 +1712,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=3241, - serialized_end=3264, + serialized_start=3271, + serialized_end=3294, ) @@ -1736,8 +1743,63 @@ extension_ranges=[], oneofs=[ ], - serialized_start=3266, - serialized_end=3308, + serialized_start=3296, + serialized_end=3338, +) + + +_WAITFORPOSITIONREQUEST = _descriptor.Descriptor( + name='WaitForPositionRequest', + full_name='tabletmanagerdata.WaitForPositionRequest', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='position', full_name='tabletmanagerdata.WaitForPositionRequest.position', index=0, + number=1, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=3340, + serialized_end=3382, +) + + +_WAITFORPOSITIONRESPONSE = _descriptor.Descriptor( + name='WaitForPositionResponse', + full_name='tabletmanagerdata.WaitForPositionResponse', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=3384, + serialized_end=3409, ) @@ -1760,8 +1822,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=3310, - serialized_end=3328, + serialized_start=3411, + serialized_end=3429, ) @@ -1784,8 +1846,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=3330, - serialized_end=3349, + serialized_start=3431, + serialized_end=3450, ) @@ -1822,8 +1884,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=3351, - serialized_end=3416, + serialized_start=3452, + serialized_end=3517, ) @@ -1853,8 +1915,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=3418, - serialized_end=3462, + serialized_start=3519, + serialized_end=3563, ) @@ -1877,8 +1939,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=3464, - serialized_end=3483, + serialized_start=3565, + serialized_end=3584, ) @@ -1901,8 +1963,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=3485, - serialized_end=3505, + serialized_start=3586, + serialized_end=3606, ) @@ -1939,8 +2001,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=3507, - serialized_end=3576, + serialized_start=3608, + serialized_end=3677, ) @@ -1963,8 +2025,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=3578, - serialized_end=3608, + serialized_start=3679, + serialized_end=3709, ) @@ -1994,8 +2056,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=3610, - serialized_end=3666, + serialized_start=3711, + serialized_end=3767, ) @@ -2018,8 +2080,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=3668, - serialized_end=3704, + serialized_start=3769, + serialized_end=3805, ) @@ -2042,8 +2104,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=3706, - serialized_end=3738, + serialized_start=3807, + serialized_end=3839, ) @@ -2066,8 +2128,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=3740, - serialized_end=3773, + serialized_start=3841, + serialized_end=3874, ) @@ -2090,8 +2152,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=3775, - serialized_end=3793, + serialized_start=3876, + serialized_end=3894, ) @@ -2121,8 +2183,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=3795, - serialized_end=3829, + serialized_start=3896, + serialized_end=3930, ) @@ -2145,8 +2207,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=3831, - serialized_end=3856, + serialized_start=3932, + serialized_end=3957, ) @@ -2169,8 +2231,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=3858, - serialized_end=3884, + serialized_start=3959, + serialized_end=3985, ) @@ -2200,8 +2262,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=3886, - serialized_end=3926, + serialized_start=3987, + serialized_end=4027, ) @@ -2231,8 +2293,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=3928, - serialized_end=3990, + serialized_start=4029, + serialized_end=4091, ) @@ -2269,8 +2331,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=3992, - serialized_end=4053, + serialized_start=4093, + serialized_end=4154, ) @@ -2293,8 +2355,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=4055, - serialized_end=4087, + serialized_start=4156, + serialized_end=4188, ) @@ -2317,8 +2379,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=4089, - serialized_end=4108, + serialized_start=4190, + serialized_end=4209, ) @@ -2348,8 +2410,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=4110, - serialized_end=4148, + serialized_start=4211, + serialized_end=4249, ) @@ -2400,8 +2462,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=4151, - serialized_end=4304, + serialized_start=4252, + serialized_end=4405, ) @@ -2424,8 +2486,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=4306, - serialized_end=4339, + serialized_start=4407, + serialized_end=4440, ) @@ -2469,8 +2531,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=4341, - serialized_end=4453, + serialized_start=4442, + serialized_end=4554, ) @@ -2493,8 +2555,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=4455, - serialized_end=4474, + serialized_start=4556, + serialized_end=4575, ) @@ -2517,8 +2579,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=4476, - serialized_end=4497, + serialized_start=4577, + serialized_end=4598, ) @@ -2548,8 +2610,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=4499, - serialized_end=4539, + serialized_start=4600, + serialized_end=4640, ) @@ -2572,8 +2634,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=4541, - serialized_end=4566, + serialized_start=4642, + serialized_end=4667, ) @@ -2596,8 +2658,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=4568, - serialized_end=4594, + serialized_start=4669, + serialized_end=4695, ) @@ -2627,8 +2689,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=4596, - serialized_end=4647, + serialized_start=4697, + serialized_end=4748, ) @@ -2658,8 +2720,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=4649, - serialized_end=4701, + serialized_start=4750, + serialized_end=4802, ) @@ -2682,8 +2744,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=4703, - serialized_end=4728, + serialized_start=4804, + serialized_end=4829, ) @@ -2706,8 +2768,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=4730, - serialized_end=4756, + serialized_start=4831, + serialized_end=4857, ) @@ -2733,7 +2795,14 @@ is_extension=False, extension_scope=None, serialized_options=None, file=DESCRIPTOR), _descriptor.FieldDescriptor( - name='force_start_slave', full_name='tabletmanagerdata.SetMasterRequest.force_start_slave', index=2, + name='wait_position', full_name='tabletmanagerdata.SetMasterRequest.wait_position', index=2, + number=4, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='force_start_slave', full_name='tabletmanagerdata.SetMasterRequest.force_start_slave', index=3, number=3, type=8, cpp_type=7, label=1, has_default_value=False, default_value=False, message_type=None, enum_type=None, containing_type=None, @@ -2751,8 +2820,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=4758, - serialized_end=4867, + serialized_start=4860, + serialized_end=4992, ) @@ -2775,8 +2844,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=4869, - serialized_end=4888, + serialized_start=4994, + serialized_end=5013, ) @@ -2806,8 +2875,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=4890, - serialized_end=4955, + serialized_start=5015, + serialized_end=5080, ) @@ -2830,8 +2899,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=4957, - serialized_end=4984, + serialized_start=5082, + serialized_end=5109, ) @@ -2854,8 +2923,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=4986, - serialized_end=5022, + serialized_start=5111, + serialized_end=5147, ) @@ -2885,8 +2954,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=5024, - serialized_end=5102, + serialized_start=5149, + serialized_end=5227, ) @@ -2909,8 +2978,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=5104, - serialized_end=5125, + serialized_start=5229, + serialized_end=5250, ) @@ -2940,8 +3009,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=5127, - serialized_end=5167, + serialized_start=5252, + serialized_end=5292, ) @@ -2978,8 +3047,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=5169, - serialized_end=5226, + serialized_start=5294, + serialized_end=5351, ) @@ -3009,8 +3078,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=5228, - serialized_end=5275, + serialized_start=5353, + serialized_end=5400, ) @@ -3033,8 +3102,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=5277, - serialized_end=5303, + serialized_start=5402, + serialized_end=5428, ) @@ -3064,10 +3133,11 @@ extension_ranges=[], oneofs=[ ], - serialized_start=5305, - serialized_end=5363, + serialized_start=5430, + serialized_end=5488, ) +_TABLEDEFINITION.fields_by_name['fields'].message_type = query__pb2._FIELD _SCHEMADEFINITION.fields_by_name['table_definitions'].message_type = _TABLEDEFINITION _SCHEMACHANGERESULT.fields_by_name['before_schema'].message_type = _SCHEMADEFINITION _SCHEMACHANGERESULT.fields_by_name['after_schema'].message_type = _SCHEMADEFINITION @@ -3147,6 +3217,8 @@ DESCRIPTOR.message_types_by_name['SlaveStatusResponse'] = _SLAVESTATUSRESPONSE DESCRIPTOR.message_types_by_name['MasterPositionRequest'] = _MASTERPOSITIONREQUEST DESCRIPTOR.message_types_by_name['MasterPositionResponse'] = _MASTERPOSITIONRESPONSE +DESCRIPTOR.message_types_by_name['WaitForPositionRequest'] = _WAITFORPOSITIONREQUEST +DESCRIPTOR.message_types_by_name['WaitForPositionResponse'] = _WAITFORPOSITIONRESPONSE DESCRIPTOR.message_types_by_name['StopSlaveRequest'] = _STOPSLAVEREQUEST DESCRIPTOR.message_types_by_name['StopSlaveResponse'] = _STOPSLAVERESPONSE DESCRIPTOR.message_types_by_name['StopSlaveMinimumRequest'] = _STOPSLAVEMINIMUMREQUEST @@ -3555,6 +3627,20 @@ )) _sym_db.RegisterMessage(MasterPositionResponse) +WaitForPositionRequest = _reflection.GeneratedProtocolMessageType('WaitForPositionRequest', (_message.Message,), dict( + DESCRIPTOR = _WAITFORPOSITIONREQUEST, + __module__ = 'tabletmanagerdata_pb2' + # @@protoc_insertion_point(class_scope:tabletmanagerdata.WaitForPositionRequest) + )) +_sym_db.RegisterMessage(WaitForPositionRequest) + +WaitForPositionResponse = _reflection.GeneratedProtocolMessageType('WaitForPositionResponse', (_message.Message,), dict( + DESCRIPTOR = _WAITFORPOSITIONRESPONSE, + __module__ = 'tabletmanagerdata_pb2' + # @@protoc_insertion_point(class_scope:tabletmanagerdata.WaitForPositionResponse) + )) +_sym_db.RegisterMessage(WaitForPositionResponse) + StopSlaveRequest = _reflection.GeneratedProtocolMessageType('StopSlaveRequest', (_message.Message,), dict( DESCRIPTOR = _STOPSLAVEREQUEST, __module__ = 'tabletmanagerdata_pb2' diff --git a/py/vtproto/tabletmanagerservice_pb2.py b/py/vtproto/tabletmanagerservice_pb2.py index d9f607b5ada..56729dea692 100644 --- a/py/vtproto/tabletmanagerservice_pb2.py +++ b/py/vtproto/tabletmanagerservice_pb2.py @@ -20,7 +20,7 @@ package='tabletmanagerservice', syntax='proto3', serialized_options=_b('Z1vitess.io/vitess/go/vt/proto/tabletmanagerservice'), - serialized_pb=_b('\n\x1atabletmanagerservice.proto\x12\x14tabletmanagerservice\x1a\x17tabletmanagerdata.proto2\xbf$\n\rTabletManager\x12I\n\x04Ping\x12\x1e.tabletmanagerdata.PingRequest\x1a\x1f.tabletmanagerdata.PingResponse\"\x00\x12L\n\x05Sleep\x12\x1f.tabletmanagerdata.SleepRequest\x1a .tabletmanagerdata.SleepResponse\"\x00\x12^\n\x0b\x45xecuteHook\x12%.tabletmanagerdata.ExecuteHookRequest\x1a&.tabletmanagerdata.ExecuteHookResponse\"\x00\x12X\n\tGetSchema\x12#.tabletmanagerdata.GetSchemaRequest\x1a$.tabletmanagerdata.GetSchemaResponse\"\x00\x12g\n\x0eGetPermissions\x12(.tabletmanagerdata.GetPermissionsRequest\x1a).tabletmanagerdata.GetPermissionsResponse\"\x00\x12^\n\x0bSetReadOnly\x12%.tabletmanagerdata.SetReadOnlyRequest\x1a&.tabletmanagerdata.SetReadOnlyResponse\"\x00\x12\x61\n\x0cSetReadWrite\x12&.tabletmanagerdata.SetReadWriteRequest\x1a\'.tabletmanagerdata.SetReadWriteResponse\"\x00\x12[\n\nChangeType\x12$.tabletmanagerdata.ChangeTypeRequest\x1a%.tabletmanagerdata.ChangeTypeResponse\"\x00\x12\x61\n\x0cRefreshState\x12&.tabletmanagerdata.RefreshStateRequest\x1a\'.tabletmanagerdata.RefreshStateResponse\"\x00\x12g\n\x0eRunHealthCheck\x12(.tabletmanagerdata.RunHealthCheckRequest\x1a).tabletmanagerdata.RunHealthCheckResponse\"\x00\x12p\n\x11IgnoreHealthError\x12+.tabletmanagerdata.IgnoreHealthErrorRequest\x1a,.tabletmanagerdata.IgnoreHealthErrorResponse\"\x00\x12\x61\n\x0cReloadSchema\x12&.tabletmanagerdata.ReloadSchemaRequest\x1a\'.tabletmanagerdata.ReloadSchemaResponse\"\x00\x12j\n\x0fPreflightSchema\x12).tabletmanagerdata.PreflightSchemaRequest\x1a*.tabletmanagerdata.PreflightSchemaResponse\"\x00\x12^\n\x0b\x41pplySchema\x12%.tabletmanagerdata.ApplySchemaRequest\x1a&.tabletmanagerdata.ApplySchemaResponse\"\x00\x12[\n\nLockTables\x12$.tabletmanagerdata.LockTablesRequest\x1a%.tabletmanagerdata.LockTablesResponse\"\x00\x12\x61\n\x0cUnlockTables\x12&.tabletmanagerdata.UnlockTablesRequest\x1a\'.tabletmanagerdata.UnlockTablesResponse\"\x00\x12p\n\x11\x45xecuteFetchAsDba\x12+.tabletmanagerdata.ExecuteFetchAsDbaRequest\x1a,.tabletmanagerdata.ExecuteFetchAsDbaResponse\"\x00\x12\x7f\n\x16\x45xecuteFetchAsAllPrivs\x12\x30.tabletmanagerdata.ExecuteFetchAsAllPrivsRequest\x1a\x31.tabletmanagerdata.ExecuteFetchAsAllPrivsResponse\"\x00\x12p\n\x11\x45xecuteFetchAsApp\x12+.tabletmanagerdata.ExecuteFetchAsAppRequest\x1a,.tabletmanagerdata.ExecuteFetchAsAppResponse\"\x00\x12^\n\x0bSlaveStatus\x12%.tabletmanagerdata.SlaveStatusRequest\x1a&.tabletmanagerdata.SlaveStatusResponse\"\x00\x12g\n\x0eMasterPosition\x12(.tabletmanagerdata.MasterPositionRequest\x1a).tabletmanagerdata.MasterPositionResponse\"\x00\x12X\n\tStopSlave\x12#.tabletmanagerdata.StopSlaveRequest\x1a$.tabletmanagerdata.StopSlaveResponse\"\x00\x12m\n\x10StopSlaveMinimum\x12*.tabletmanagerdata.StopSlaveMinimumRequest\x1a+.tabletmanagerdata.StopSlaveMinimumResponse\"\x00\x12[\n\nStartSlave\x12$.tabletmanagerdata.StartSlaveRequest\x1a%.tabletmanagerdata.StartSlaveResponse\"\x00\x12y\n\x14StartSlaveUntilAfter\x12..tabletmanagerdata.StartSlaveUntilAfterRequest\x1a/.tabletmanagerdata.StartSlaveUntilAfterResponse\"\x00\x12\x8b\x01\n\x1aTabletExternallyReparented\x12\x34.tabletmanagerdata.TabletExternallyReparentedRequest\x1a\x35.tabletmanagerdata.TabletExternallyReparentedResponse\"\x00\x12\x82\x01\n\x17TabletExternallyElected\x12\x31.tabletmanagerdata.TabletExternallyElectedRequest\x1a\x32.tabletmanagerdata.TabletExternallyElectedResponse\"\x00\x12X\n\tGetSlaves\x12#.tabletmanagerdata.GetSlavesRequest\x1a$.tabletmanagerdata.GetSlavesResponse\"\x00\x12m\n\x10VReplicationExec\x12*.tabletmanagerdata.VReplicationExecRequest\x1a+.tabletmanagerdata.VReplicationExecResponse\"\x00\x12\x7f\n\x16VReplicationWaitForPos\x12\x30.tabletmanagerdata.VReplicationWaitForPosRequest\x1a\x31.tabletmanagerdata.VReplicationWaitForPosResponse\"\x00\x12m\n\x10ResetReplication\x12*.tabletmanagerdata.ResetReplicationRequest\x1a+.tabletmanagerdata.ResetReplicationResponse\"\x00\x12[\n\nInitMaster\x12$.tabletmanagerdata.InitMasterRequest\x1a%.tabletmanagerdata.InitMasterResponse\"\x00\x12\x82\x01\n\x17PopulateReparentJournal\x12\x31.tabletmanagerdata.PopulateReparentJournalRequest\x1a\x32.tabletmanagerdata.PopulateReparentJournalResponse\"\x00\x12X\n\tInitSlave\x12#.tabletmanagerdata.InitSlaveRequest\x1a$.tabletmanagerdata.InitSlaveResponse\"\x00\x12\x61\n\x0c\x44\x65moteMaster\x12&.tabletmanagerdata.DemoteMasterRequest\x1a\'.tabletmanagerdata.DemoteMasterResponse\"\x00\x12m\n\x10UndoDemoteMaster\x12*.tabletmanagerdata.UndoDemoteMasterRequest\x1a+.tabletmanagerdata.UndoDemoteMasterResponse\"\x00\x12\x85\x01\n\x18PromoteSlaveWhenCaughtUp\x12\x32.tabletmanagerdata.PromoteSlaveWhenCaughtUpRequest\x1a\x33.tabletmanagerdata.PromoteSlaveWhenCaughtUpResponse\"\x00\x12m\n\x10SlaveWasPromoted\x12*.tabletmanagerdata.SlaveWasPromotedRequest\x1a+.tabletmanagerdata.SlaveWasPromotedResponse\"\x00\x12X\n\tSetMaster\x12#.tabletmanagerdata.SetMasterRequest\x1a$.tabletmanagerdata.SetMasterResponse\"\x00\x12p\n\x11SlaveWasRestarted\x12+.tabletmanagerdata.SlaveWasRestartedRequest\x1a,.tabletmanagerdata.SlaveWasRestartedResponse\"\x00\x12\x8e\x01\n\x1bStopReplicationAndGetStatus\x12\x35.tabletmanagerdata.StopReplicationAndGetStatusRequest\x1a\x36.tabletmanagerdata.StopReplicationAndGetStatusResponse\"\x00\x12\x61\n\x0cPromoteSlave\x12&.tabletmanagerdata.PromoteSlaveRequest\x1a\'.tabletmanagerdata.PromoteSlaveResponse\"\x00\x12Q\n\x06\x42\x61\x63kup\x12 .tabletmanagerdata.BackupRequest\x1a!.tabletmanagerdata.BackupResponse\"\x00\x30\x01\x12r\n\x11RestoreFromBackup\x12+.tabletmanagerdata.RestoreFromBackupRequest\x1a,.tabletmanagerdata.RestoreFromBackupResponse\"\x00\x30\x01\x42\x33Z1vitess.io/vitess/go/vt/proto/tabletmanagerserviceb\x06proto3') + serialized_pb=_b('\n\x1atabletmanagerservice.proto\x12\x14tabletmanagerservice\x1a\x17tabletmanagerdata.proto2\xab%\n\rTabletManager\x12I\n\x04Ping\x12\x1e.tabletmanagerdata.PingRequest\x1a\x1f.tabletmanagerdata.PingResponse\"\x00\x12L\n\x05Sleep\x12\x1f.tabletmanagerdata.SleepRequest\x1a .tabletmanagerdata.SleepResponse\"\x00\x12^\n\x0b\x45xecuteHook\x12%.tabletmanagerdata.ExecuteHookRequest\x1a&.tabletmanagerdata.ExecuteHookResponse\"\x00\x12X\n\tGetSchema\x12#.tabletmanagerdata.GetSchemaRequest\x1a$.tabletmanagerdata.GetSchemaResponse\"\x00\x12g\n\x0eGetPermissions\x12(.tabletmanagerdata.GetPermissionsRequest\x1a).tabletmanagerdata.GetPermissionsResponse\"\x00\x12^\n\x0bSetReadOnly\x12%.tabletmanagerdata.SetReadOnlyRequest\x1a&.tabletmanagerdata.SetReadOnlyResponse\"\x00\x12\x61\n\x0cSetReadWrite\x12&.tabletmanagerdata.SetReadWriteRequest\x1a\'.tabletmanagerdata.SetReadWriteResponse\"\x00\x12[\n\nChangeType\x12$.tabletmanagerdata.ChangeTypeRequest\x1a%.tabletmanagerdata.ChangeTypeResponse\"\x00\x12\x61\n\x0cRefreshState\x12&.tabletmanagerdata.RefreshStateRequest\x1a\'.tabletmanagerdata.RefreshStateResponse\"\x00\x12g\n\x0eRunHealthCheck\x12(.tabletmanagerdata.RunHealthCheckRequest\x1a).tabletmanagerdata.RunHealthCheckResponse\"\x00\x12p\n\x11IgnoreHealthError\x12+.tabletmanagerdata.IgnoreHealthErrorRequest\x1a,.tabletmanagerdata.IgnoreHealthErrorResponse\"\x00\x12\x61\n\x0cReloadSchema\x12&.tabletmanagerdata.ReloadSchemaRequest\x1a\'.tabletmanagerdata.ReloadSchemaResponse\"\x00\x12j\n\x0fPreflightSchema\x12).tabletmanagerdata.PreflightSchemaRequest\x1a*.tabletmanagerdata.PreflightSchemaResponse\"\x00\x12^\n\x0b\x41pplySchema\x12%.tabletmanagerdata.ApplySchemaRequest\x1a&.tabletmanagerdata.ApplySchemaResponse\"\x00\x12[\n\nLockTables\x12$.tabletmanagerdata.LockTablesRequest\x1a%.tabletmanagerdata.LockTablesResponse\"\x00\x12\x61\n\x0cUnlockTables\x12&.tabletmanagerdata.UnlockTablesRequest\x1a\'.tabletmanagerdata.UnlockTablesResponse\"\x00\x12p\n\x11\x45xecuteFetchAsDba\x12+.tabletmanagerdata.ExecuteFetchAsDbaRequest\x1a,.tabletmanagerdata.ExecuteFetchAsDbaResponse\"\x00\x12\x7f\n\x16\x45xecuteFetchAsAllPrivs\x12\x30.tabletmanagerdata.ExecuteFetchAsAllPrivsRequest\x1a\x31.tabletmanagerdata.ExecuteFetchAsAllPrivsResponse\"\x00\x12p\n\x11\x45xecuteFetchAsApp\x12+.tabletmanagerdata.ExecuteFetchAsAppRequest\x1a,.tabletmanagerdata.ExecuteFetchAsAppResponse\"\x00\x12^\n\x0bSlaveStatus\x12%.tabletmanagerdata.SlaveStatusRequest\x1a&.tabletmanagerdata.SlaveStatusResponse\"\x00\x12g\n\x0eMasterPosition\x12(.tabletmanagerdata.MasterPositionRequest\x1a).tabletmanagerdata.MasterPositionResponse\"\x00\x12j\n\x0fWaitForPosition\x12).tabletmanagerdata.WaitForPositionRequest\x1a*.tabletmanagerdata.WaitForPositionResponse\"\x00\x12X\n\tStopSlave\x12#.tabletmanagerdata.StopSlaveRequest\x1a$.tabletmanagerdata.StopSlaveResponse\"\x00\x12m\n\x10StopSlaveMinimum\x12*.tabletmanagerdata.StopSlaveMinimumRequest\x1a+.tabletmanagerdata.StopSlaveMinimumResponse\"\x00\x12[\n\nStartSlave\x12$.tabletmanagerdata.StartSlaveRequest\x1a%.tabletmanagerdata.StartSlaveResponse\"\x00\x12y\n\x14StartSlaveUntilAfter\x12..tabletmanagerdata.StartSlaveUntilAfterRequest\x1a/.tabletmanagerdata.StartSlaveUntilAfterResponse\"\x00\x12\x8b\x01\n\x1aTabletExternallyReparented\x12\x34.tabletmanagerdata.TabletExternallyReparentedRequest\x1a\x35.tabletmanagerdata.TabletExternallyReparentedResponse\"\x00\x12\x82\x01\n\x17TabletExternallyElected\x12\x31.tabletmanagerdata.TabletExternallyElectedRequest\x1a\x32.tabletmanagerdata.TabletExternallyElectedResponse\"\x00\x12X\n\tGetSlaves\x12#.tabletmanagerdata.GetSlavesRequest\x1a$.tabletmanagerdata.GetSlavesResponse\"\x00\x12m\n\x10VReplicationExec\x12*.tabletmanagerdata.VReplicationExecRequest\x1a+.tabletmanagerdata.VReplicationExecResponse\"\x00\x12\x7f\n\x16VReplicationWaitForPos\x12\x30.tabletmanagerdata.VReplicationWaitForPosRequest\x1a\x31.tabletmanagerdata.VReplicationWaitForPosResponse\"\x00\x12m\n\x10ResetReplication\x12*.tabletmanagerdata.ResetReplicationRequest\x1a+.tabletmanagerdata.ResetReplicationResponse\"\x00\x12[\n\nInitMaster\x12$.tabletmanagerdata.InitMasterRequest\x1a%.tabletmanagerdata.InitMasterResponse\"\x00\x12\x82\x01\n\x17PopulateReparentJournal\x12\x31.tabletmanagerdata.PopulateReparentJournalRequest\x1a\x32.tabletmanagerdata.PopulateReparentJournalResponse\"\x00\x12X\n\tInitSlave\x12#.tabletmanagerdata.InitSlaveRequest\x1a$.tabletmanagerdata.InitSlaveResponse\"\x00\x12\x61\n\x0c\x44\x65moteMaster\x12&.tabletmanagerdata.DemoteMasterRequest\x1a\'.tabletmanagerdata.DemoteMasterResponse\"\x00\x12m\n\x10UndoDemoteMaster\x12*.tabletmanagerdata.UndoDemoteMasterRequest\x1a+.tabletmanagerdata.UndoDemoteMasterResponse\"\x00\x12\x85\x01\n\x18PromoteSlaveWhenCaughtUp\x12\x32.tabletmanagerdata.PromoteSlaveWhenCaughtUpRequest\x1a\x33.tabletmanagerdata.PromoteSlaveWhenCaughtUpResponse\"\x00\x12m\n\x10SlaveWasPromoted\x12*.tabletmanagerdata.SlaveWasPromotedRequest\x1a+.tabletmanagerdata.SlaveWasPromotedResponse\"\x00\x12X\n\tSetMaster\x12#.tabletmanagerdata.SetMasterRequest\x1a$.tabletmanagerdata.SetMasterResponse\"\x00\x12p\n\x11SlaveWasRestarted\x12+.tabletmanagerdata.SlaveWasRestartedRequest\x1a,.tabletmanagerdata.SlaveWasRestartedResponse\"\x00\x12\x8e\x01\n\x1bStopReplicationAndGetStatus\x12\x35.tabletmanagerdata.StopReplicationAndGetStatusRequest\x1a\x36.tabletmanagerdata.StopReplicationAndGetStatusResponse\"\x00\x12\x61\n\x0cPromoteSlave\x12&.tabletmanagerdata.PromoteSlaveRequest\x1a\'.tabletmanagerdata.PromoteSlaveResponse\"\x00\x12Q\n\x06\x42\x61\x63kup\x12 .tabletmanagerdata.BackupRequest\x1a!.tabletmanagerdata.BackupResponse\"\x00\x30\x01\x12r\n\x11RestoreFromBackup\x12+.tabletmanagerdata.RestoreFromBackupRequest\x1a,.tabletmanagerdata.RestoreFromBackupResponse\"\x00\x30\x01\x42\x33Z1vitess.io/vitess/go/vt/proto/tabletmanagerserviceb\x06proto3') , dependencies=[tabletmanagerdata__pb2.DESCRIPTOR,]) @@ -38,7 +38,7 @@ index=0, serialized_options=None, serialized_start=78, - serialized_end=4749, + serialized_end=4857, methods=[ _descriptor.MethodDescriptor( name='Ping', @@ -229,10 +229,19 @@ output_type=tabletmanagerdata__pb2._MASTERPOSITIONRESPONSE, serialized_options=None, ), + _descriptor.MethodDescriptor( + name='WaitForPosition', + full_name='tabletmanagerservice.TabletManager.WaitForPosition', + index=21, + containing_service=None, + input_type=tabletmanagerdata__pb2._WAITFORPOSITIONREQUEST, + output_type=tabletmanagerdata__pb2._WAITFORPOSITIONRESPONSE, + serialized_options=None, + ), _descriptor.MethodDescriptor( name='StopSlave', full_name='tabletmanagerservice.TabletManager.StopSlave', - index=21, + index=22, containing_service=None, input_type=tabletmanagerdata__pb2._STOPSLAVEREQUEST, output_type=tabletmanagerdata__pb2._STOPSLAVERESPONSE, @@ -241,7 +250,7 @@ _descriptor.MethodDescriptor( name='StopSlaveMinimum', full_name='tabletmanagerservice.TabletManager.StopSlaveMinimum', - index=22, + index=23, containing_service=None, input_type=tabletmanagerdata__pb2._STOPSLAVEMINIMUMREQUEST, output_type=tabletmanagerdata__pb2._STOPSLAVEMINIMUMRESPONSE, @@ -250,7 +259,7 @@ _descriptor.MethodDescriptor( name='StartSlave', full_name='tabletmanagerservice.TabletManager.StartSlave', - index=23, + index=24, containing_service=None, input_type=tabletmanagerdata__pb2._STARTSLAVEREQUEST, output_type=tabletmanagerdata__pb2._STARTSLAVERESPONSE, @@ -259,7 +268,7 @@ _descriptor.MethodDescriptor( name='StartSlaveUntilAfter', full_name='tabletmanagerservice.TabletManager.StartSlaveUntilAfter', - index=24, + index=25, containing_service=None, input_type=tabletmanagerdata__pb2._STARTSLAVEUNTILAFTERREQUEST, output_type=tabletmanagerdata__pb2._STARTSLAVEUNTILAFTERRESPONSE, @@ -268,7 +277,7 @@ _descriptor.MethodDescriptor( name='TabletExternallyReparented', full_name='tabletmanagerservice.TabletManager.TabletExternallyReparented', - index=25, + index=26, containing_service=None, input_type=tabletmanagerdata__pb2._TABLETEXTERNALLYREPARENTEDREQUEST, output_type=tabletmanagerdata__pb2._TABLETEXTERNALLYREPARENTEDRESPONSE, @@ -277,7 +286,7 @@ _descriptor.MethodDescriptor( name='TabletExternallyElected', full_name='tabletmanagerservice.TabletManager.TabletExternallyElected', - index=26, + index=27, containing_service=None, input_type=tabletmanagerdata__pb2._TABLETEXTERNALLYELECTEDREQUEST, output_type=tabletmanagerdata__pb2._TABLETEXTERNALLYELECTEDRESPONSE, @@ -286,7 +295,7 @@ _descriptor.MethodDescriptor( name='GetSlaves', full_name='tabletmanagerservice.TabletManager.GetSlaves', - index=27, + index=28, containing_service=None, input_type=tabletmanagerdata__pb2._GETSLAVESREQUEST, output_type=tabletmanagerdata__pb2._GETSLAVESRESPONSE, @@ -295,7 +304,7 @@ _descriptor.MethodDescriptor( name='VReplicationExec', full_name='tabletmanagerservice.TabletManager.VReplicationExec', - index=28, + index=29, containing_service=None, input_type=tabletmanagerdata__pb2._VREPLICATIONEXECREQUEST, output_type=tabletmanagerdata__pb2._VREPLICATIONEXECRESPONSE, @@ -304,7 +313,7 @@ _descriptor.MethodDescriptor( name='VReplicationWaitForPos', full_name='tabletmanagerservice.TabletManager.VReplicationWaitForPos', - index=29, + index=30, containing_service=None, input_type=tabletmanagerdata__pb2._VREPLICATIONWAITFORPOSREQUEST, output_type=tabletmanagerdata__pb2._VREPLICATIONWAITFORPOSRESPONSE, @@ -313,7 +322,7 @@ _descriptor.MethodDescriptor( name='ResetReplication', full_name='tabletmanagerservice.TabletManager.ResetReplication', - index=30, + index=31, containing_service=None, input_type=tabletmanagerdata__pb2._RESETREPLICATIONREQUEST, output_type=tabletmanagerdata__pb2._RESETREPLICATIONRESPONSE, @@ -322,7 +331,7 @@ _descriptor.MethodDescriptor( name='InitMaster', full_name='tabletmanagerservice.TabletManager.InitMaster', - index=31, + index=32, containing_service=None, input_type=tabletmanagerdata__pb2._INITMASTERREQUEST, output_type=tabletmanagerdata__pb2._INITMASTERRESPONSE, @@ -331,7 +340,7 @@ _descriptor.MethodDescriptor( name='PopulateReparentJournal', full_name='tabletmanagerservice.TabletManager.PopulateReparentJournal', - index=32, + index=33, containing_service=None, input_type=tabletmanagerdata__pb2._POPULATEREPARENTJOURNALREQUEST, output_type=tabletmanagerdata__pb2._POPULATEREPARENTJOURNALRESPONSE, @@ -340,7 +349,7 @@ _descriptor.MethodDescriptor( name='InitSlave', full_name='tabletmanagerservice.TabletManager.InitSlave', - index=33, + index=34, containing_service=None, input_type=tabletmanagerdata__pb2._INITSLAVEREQUEST, output_type=tabletmanagerdata__pb2._INITSLAVERESPONSE, @@ -349,7 +358,7 @@ _descriptor.MethodDescriptor( name='DemoteMaster', full_name='tabletmanagerservice.TabletManager.DemoteMaster', - index=34, + index=35, containing_service=None, input_type=tabletmanagerdata__pb2._DEMOTEMASTERREQUEST, output_type=tabletmanagerdata__pb2._DEMOTEMASTERRESPONSE, @@ -358,7 +367,7 @@ _descriptor.MethodDescriptor( name='UndoDemoteMaster', full_name='tabletmanagerservice.TabletManager.UndoDemoteMaster', - index=35, + index=36, containing_service=None, input_type=tabletmanagerdata__pb2._UNDODEMOTEMASTERREQUEST, output_type=tabletmanagerdata__pb2._UNDODEMOTEMASTERRESPONSE, @@ -367,7 +376,7 @@ _descriptor.MethodDescriptor( name='PromoteSlaveWhenCaughtUp', full_name='tabletmanagerservice.TabletManager.PromoteSlaveWhenCaughtUp', - index=36, + index=37, containing_service=None, input_type=tabletmanagerdata__pb2._PROMOTESLAVEWHENCAUGHTUPREQUEST, output_type=tabletmanagerdata__pb2._PROMOTESLAVEWHENCAUGHTUPRESPONSE, @@ -376,7 +385,7 @@ _descriptor.MethodDescriptor( name='SlaveWasPromoted', full_name='tabletmanagerservice.TabletManager.SlaveWasPromoted', - index=37, + index=38, containing_service=None, input_type=tabletmanagerdata__pb2._SLAVEWASPROMOTEDREQUEST, output_type=tabletmanagerdata__pb2._SLAVEWASPROMOTEDRESPONSE, @@ -385,7 +394,7 @@ _descriptor.MethodDescriptor( name='SetMaster', full_name='tabletmanagerservice.TabletManager.SetMaster', - index=38, + index=39, containing_service=None, input_type=tabletmanagerdata__pb2._SETMASTERREQUEST, output_type=tabletmanagerdata__pb2._SETMASTERRESPONSE, @@ -394,7 +403,7 @@ _descriptor.MethodDescriptor( name='SlaveWasRestarted', full_name='tabletmanagerservice.TabletManager.SlaveWasRestarted', - index=39, + index=40, containing_service=None, input_type=tabletmanagerdata__pb2._SLAVEWASRESTARTEDREQUEST, output_type=tabletmanagerdata__pb2._SLAVEWASRESTARTEDRESPONSE, @@ -403,7 +412,7 @@ _descriptor.MethodDescriptor( name='StopReplicationAndGetStatus', full_name='tabletmanagerservice.TabletManager.StopReplicationAndGetStatus', - index=40, + index=41, containing_service=None, input_type=tabletmanagerdata__pb2._STOPREPLICATIONANDGETSTATUSREQUEST, output_type=tabletmanagerdata__pb2._STOPREPLICATIONANDGETSTATUSRESPONSE, @@ -412,7 +421,7 @@ _descriptor.MethodDescriptor( name='PromoteSlave', full_name='tabletmanagerservice.TabletManager.PromoteSlave', - index=41, + index=42, containing_service=None, input_type=tabletmanagerdata__pb2._PROMOTESLAVEREQUEST, output_type=tabletmanagerdata__pb2._PROMOTESLAVERESPONSE, @@ -421,7 +430,7 @@ _descriptor.MethodDescriptor( name='Backup', full_name='tabletmanagerservice.TabletManager.Backup', - index=42, + index=43, containing_service=None, input_type=tabletmanagerdata__pb2._BACKUPREQUEST, output_type=tabletmanagerdata__pb2._BACKUPRESPONSE, @@ -430,7 +439,7 @@ _descriptor.MethodDescriptor( name='RestoreFromBackup', full_name='tabletmanagerservice.TabletManager.RestoreFromBackup', - index=43, + index=44, containing_service=None, input_type=tabletmanagerdata__pb2._RESTOREFROMBACKUPREQUEST, output_type=tabletmanagerdata__pb2._RESTOREFROMBACKUPRESPONSE, diff --git a/py/vtproto/tabletmanagerservice_pb2_grpc.py b/py/vtproto/tabletmanagerservice_pb2_grpc.py index d7133c24429..95019dd89ed 100644 --- a/py/vtproto/tabletmanagerservice_pb2_grpc.py +++ b/py/vtproto/tabletmanagerservice_pb2_grpc.py @@ -122,6 +122,11 @@ def __init__(self, channel): request_serializer=tabletmanagerdata__pb2.MasterPositionRequest.SerializeToString, response_deserializer=tabletmanagerdata__pb2.MasterPositionResponse.FromString, ) + self.WaitForPosition = channel.unary_unary( + '/tabletmanagerservice.TabletManager/WaitForPosition', + request_serializer=tabletmanagerdata__pb2.WaitForPositionRequest.SerializeToString, + response_deserializer=tabletmanagerdata__pb2.WaitForPositionResponse.FromString, + ) self.StopSlave = channel.unary_unary( '/tabletmanagerservice.TabletManager/StopSlave', request_serializer=tabletmanagerdata__pb2.StopSlaveRequest.SerializeToString, @@ -400,6 +405,13 @@ def MasterPosition(self, request, context): context.set_details('Method not implemented!') raise NotImplementedError('Method not implemented!') + def WaitForPosition(self, request, context): + """WaitForPosition waits for the position to be reached + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + def StopSlave(self, request, context): """StopSlave makes mysql stop its replication """ @@ -514,7 +526,7 @@ def PopulateReparentJournal(self, request, context): raise NotImplementedError('Method not implemented!') def InitSlave(self, request, context): - """InitSlave tells the tablet to reparent to the master unconditionnally + """InitSlave tells the tablet to reparent to the master unconditionally """ context.set_code(grpc.StatusCode.UNIMPLEMENTED) context.set_details('Method not implemented!') @@ -703,6 +715,11 @@ def add_TabletManagerServicer_to_server(servicer, server): request_deserializer=tabletmanagerdata__pb2.MasterPositionRequest.FromString, response_serializer=tabletmanagerdata__pb2.MasterPositionResponse.SerializeToString, ), + 'WaitForPosition': grpc.unary_unary_rpc_method_handler( + servicer.WaitForPosition, + request_deserializer=tabletmanagerdata__pb2.WaitForPositionRequest.FromString, + response_serializer=tabletmanagerdata__pb2.WaitForPositionResponse.SerializeToString, + ), 'StopSlave': grpc.unary_unary_rpc_method_handler( servicer.StopSlave, request_deserializer=tabletmanagerdata__pb2.StopSlaveRequest.FromString, diff --git a/py/vtproto/time_pb2.py b/py/vtproto/time_pb2.py new file mode 100644 index 00000000000..af172b3c5d8 --- /dev/null +++ b/py/vtproto/time_pb2.py @@ -0,0 +1,77 @@ +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: time.proto + +import sys +_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1')) +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message +from google.protobuf import reflection as _reflection +from google.protobuf import symbol_database as _symbol_database +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + + + +DESCRIPTOR = _descriptor.FileDescriptor( + name='time.proto', + package='vttime', + syntax='proto3', + serialized_options=_b('Z#vitess.io/vitess/go/vt/proto/vttime'), + serialized_pb=_b('\n\ntime.proto\x12\x06vttime\",\n\x04Time\x12\x0f\n\x07seconds\x18\x01 \x01(\x03\x12\x13\n\x0bnanoseconds\x18\x02 \x01(\x05\x42%Z#vitess.io/vitess/go/vt/proto/vttimeb\x06proto3') +) + + + + +_TIME = _descriptor.Descriptor( + name='Time', + full_name='vttime.Time', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='seconds', full_name='vttime.Time.seconds', index=0, + number=1, type=3, cpp_type=2, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='nanoseconds', full_name='vttime.Time.nanoseconds', index=1, + number=2, type=5, cpp_type=1, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=22, + serialized_end=66, +) + +DESCRIPTOR.message_types_by_name['Time'] = _TIME +_sym_db.RegisterFileDescriptor(DESCRIPTOR) + +Time = _reflection.GeneratedProtocolMessageType('Time', (_message.Message,), dict( + DESCRIPTOR = _TIME, + __module__ = 'time_pb2' + # @@protoc_insertion_point(class_scope:vttime.Time) + )) +_sym_db.RegisterMessage(Time) + + +DESCRIPTOR._options = None +# @@protoc_insertion_point(module_scope) diff --git a/py/vtproto/time_pb2_grpc.py b/py/vtproto/time_pb2_grpc.py new file mode 100644 index 00000000000..a89435267cb --- /dev/null +++ b/py/vtproto/time_pb2_grpc.py @@ -0,0 +1,3 @@ +# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! +import grpc + diff --git a/py/vtproto/topodata_pb2.py b/py/vtproto/topodata_pb2.py index 66ac9fea9b0..4947f3dff6a 100644 --- a/py/vtproto/topodata_pb2.py +++ b/py/vtproto/topodata_pb2.py @@ -13,6 +13,7 @@ _sym_db = _symbol_database.Default() +import time_pb2 as time__pb2 DESCRIPTOR = _descriptor.FileDescriptor( @@ -20,9 +21,33 @@ package='topodata', syntax='proto3', serialized_options=_b('\n\017io.vitess.protoZ%vitess.io/vitess/go/vt/proto/topodata'), - serialized_pb=_b('\n\x0etopodata.proto\x12\x08topodata\"&\n\x08KeyRange\x12\r\n\x05start\x18\x01 \x01(\x0c\x12\x0b\n\x03\x65nd\x18\x02 \x01(\x0c\"(\n\x0bTabletAlias\x12\x0c\n\x04\x63\x65ll\x18\x01 \x01(\t\x12\x0b\n\x03uid\x18\x02 \x01(\r\"\xb6\x03\n\x06Tablet\x12$\n\x05\x61lias\x18\x01 \x01(\x0b\x32\x15.topodata.TabletAlias\x12\x10\n\x08hostname\x18\x02 \x01(\t\x12/\n\x08port_map\x18\x04 \x03(\x0b\x32\x1d.topodata.Tablet.PortMapEntry\x12\x10\n\x08keyspace\x18\x05 \x01(\t\x12\r\n\x05shard\x18\x06 \x01(\t\x12%\n\tkey_range\x18\x07 \x01(\x0b\x32\x12.topodata.KeyRange\x12\"\n\x04type\x18\x08 \x01(\x0e\x32\x14.topodata.TabletType\x12\x18\n\x10\x64\x62_name_override\x18\t \x01(\t\x12(\n\x04tags\x18\n \x03(\x0b\x32\x1a.topodata.Tablet.TagsEntry\x12\x16\n\x0emysql_hostname\x18\x0c \x01(\t\x12\x12\n\nmysql_port\x18\r \x01(\x05\x1a.\n\x0cPortMapEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\x05:\x02\x38\x01\x1a+\n\tTagsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01J\x04\x08\x03\x10\x04J\x04\x08\x0b\x10\x0c\"\xd3\x04\n\x05Shard\x12+\n\x0cmaster_alias\x18\x01 \x01(\x0b\x32\x15.topodata.TabletAlias\x12%\n\tkey_range\x18\x02 \x01(\x0b\x32\x12.topodata.KeyRange\x12\x30\n\x0cserved_types\x18\x03 \x03(\x0b\x32\x1a.topodata.Shard.ServedType\x12\x32\n\rsource_shards\x18\x04 \x03(\x0b\x32\x1b.topodata.Shard.SourceShard\x12\x36\n\x0ftablet_controls\x18\x06 \x03(\x0b\x32\x1d.topodata.Shard.TabletControl\x12\x19\n\x11is_master_serving\x18\x07 \x01(\x08\x1a\x46\n\nServedType\x12)\n\x0btablet_type\x18\x01 \x01(\x0e\x32\x14.topodata.TabletType\x12\r\n\x05\x63\x65lls\x18\x02 \x03(\t\x1ar\n\x0bSourceShard\x12\x0b\n\x03uid\x18\x01 \x01(\r\x12\x10\n\x08keyspace\x18\x02 \x01(\t\x12\r\n\x05shard\x18\x03 \x01(\t\x12%\n\tkey_range\x18\x04 \x01(\x0b\x32\x12.topodata.KeyRange\x12\x0e\n\x06tables\x18\x05 \x03(\t\x1a{\n\rTabletControl\x12)\n\x0btablet_type\x18\x01 \x01(\x0e\x32\x14.topodata.TabletType\x12\r\n\x05\x63\x65lls\x18\x02 \x03(\t\x12\x1a\n\x12\x62lacklisted_tables\x18\x04 \x03(\t\x12\x0e\n\x06\x66rozen\x18\x05 \x01(\x08J\x04\x08\x03\x10\x04J\x04\x08\x05\x10\x06\"\xf5\x01\n\x08Keyspace\x12\x1c\n\x14sharding_column_name\x18\x01 \x01(\t\x12\x36\n\x14sharding_column_type\x18\x02 \x01(\x0e\x32\x18.topodata.KeyspaceIdType\x12\x33\n\x0cserved_froms\x18\x04 \x03(\x0b\x32\x1d.topodata.Keyspace.ServedFrom\x1aX\n\nServedFrom\x12)\n\x0btablet_type\x18\x01 \x01(\x0e\x32\x14.topodata.TabletType\x12\r\n\x05\x63\x65lls\x18\x02 \x03(\t\x12\x10\n\x08keyspace\x18\x03 \x01(\tJ\x04\x08\x03\x10\x04\"w\n\x10ShardReplication\x12.\n\x05nodes\x18\x01 \x03(\x0b\x32\x1f.topodata.ShardReplication.Node\x1a\x33\n\x04Node\x12+\n\x0ctablet_alias\x18\x01 \x01(\x0b\x32\x15.topodata.TabletAlias\"E\n\x0eShardReference\x12\x0c\n\x04name\x18\x01 \x01(\t\x12%\n\tkey_range\x18\x02 \x01(\x0b\x32\x12.topodata.KeyRange\"i\n\x12ShardTabletControl\x12\x0c\n\x04name\x18\x01 \x01(\t\x12%\n\tkey_range\x18\x02 \x01(\x0b\x32\x12.topodata.KeyRange\x12\x1e\n\x16query_service_disabled\x18\x03 \x01(\x08\"\xda\x03\n\x0bSrvKeyspace\x12;\n\npartitions\x18\x01 \x03(\x0b\x32\'.topodata.SrvKeyspace.KeyspacePartition\x12\x1c\n\x14sharding_column_name\x18\x02 \x01(\t\x12\x36\n\x14sharding_column_type\x18\x03 \x01(\x0e\x32\x18.topodata.KeyspaceIdType\x12\x35\n\x0bserved_from\x18\x04 \x03(\x0b\x32 .topodata.SrvKeyspace.ServedFrom\x1a\xaf\x01\n\x11KeyspacePartition\x12)\n\x0bserved_type\x18\x01 \x01(\x0e\x32\x14.topodata.TabletType\x12\x32\n\x10shard_references\x18\x02 \x03(\x0b\x32\x18.topodata.ShardReference\x12;\n\x15shard_tablet_controls\x18\x03 \x03(\x0b\x32\x1c.topodata.ShardTabletControl\x1aI\n\nServedFrom\x12)\n\x0btablet_type\x18\x01 \x01(\x0e\x32\x14.topodata.TabletType\x12\x10\n\x08keyspace\x18\x02 \x01(\tJ\x04\x08\x05\x10\x06\"6\n\x08\x43\x65llInfo\x12\x16\n\x0eserver_address\x18\x01 \x01(\t\x12\x0c\n\x04root\x18\x02 \x01(\tJ\x04\x08\x03\x10\x04\"\x1b\n\nCellsAlias\x12\r\n\x05\x63\x65lls\x18\x02 \x03(\t*2\n\x0eKeyspaceIdType\x12\t\n\x05UNSET\x10\x00\x12\n\n\x06UINT64\x10\x01\x12\t\n\x05\x42YTES\x10\x02*\x90\x01\n\nTabletType\x12\x0b\n\x07UNKNOWN\x10\x00\x12\n\n\x06MASTER\x10\x01\x12\x0b\n\x07REPLICA\x10\x02\x12\n\n\x06RDONLY\x10\x03\x12\t\n\x05\x42\x41TCH\x10\x03\x12\t\n\x05SPARE\x10\x04\x12\x10\n\x0c\x45XPERIMENTAL\x10\x05\x12\n\n\x06\x42\x41\x43KUP\x10\x06\x12\x0b\n\x07RESTORE\x10\x07\x12\x0b\n\x07\x44RAINED\x10\x08\x1a\x02\x10\x01\x42\x38\n\x0fio.vitess.protoZ%vitess.io/vitess/go/vt/proto/topodatab\x06proto3') + serialized_pb=_b('\n\x0etopodata.proto\x12\x08topodata\x1a\ntime.proto\"&\n\x08KeyRange\x12\r\n\x05start\x18\x01 \x01(\x0c\x12\x0b\n\x03\x65nd\x18\x02 \x01(\x0c\"(\n\x0bTabletAlias\x12\x0c\n\x04\x63\x65ll\x18\x01 \x01(\t\x12\x0b\n\x03uid\x18\x02 \x01(\r\"\xe4\x03\n\x06Tablet\x12$\n\x05\x61lias\x18\x01 \x01(\x0b\x32\x15.topodata.TabletAlias\x12\x10\n\x08hostname\x18\x02 \x01(\t\x12/\n\x08port_map\x18\x04 \x03(\x0b\x32\x1d.topodata.Tablet.PortMapEntry\x12\x10\n\x08keyspace\x18\x05 \x01(\t\x12\r\n\x05shard\x18\x06 \x01(\t\x12%\n\tkey_range\x18\x07 \x01(\x0b\x32\x12.topodata.KeyRange\x12\"\n\x04type\x18\x08 \x01(\x0e\x32\x14.topodata.TabletType\x12\x18\n\x10\x64\x62_name_override\x18\t \x01(\t\x12(\n\x04tags\x18\n \x03(\x0b\x32\x1a.topodata.Tablet.TagsEntry\x12\x16\n\x0emysql_hostname\x18\x0c \x01(\t\x12\x12\n\nmysql_port\x18\r \x01(\x05\x12,\n\x16master_term_start_time\x18\x0e \x01(\x0b\x32\x0c.vttime.Time\x1a.\n\x0cPortMapEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\x05:\x02\x38\x01\x1a+\n\tTagsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01J\x04\x08\x03\x10\x04J\x04\x08\x0b\x10\x0c\"\x81\x05\n\x05Shard\x12+\n\x0cmaster_alias\x18\x01 \x01(\x0b\x32\x15.topodata.TabletAlias\x12,\n\x16master_term_start_time\x18\x08 \x01(\x0b\x32\x0c.vttime.Time\x12%\n\tkey_range\x18\x02 \x01(\x0b\x32\x12.topodata.KeyRange\x12\x30\n\x0cserved_types\x18\x03 \x03(\x0b\x32\x1a.topodata.Shard.ServedType\x12\x32\n\rsource_shards\x18\x04 \x03(\x0b\x32\x1b.topodata.Shard.SourceShard\x12\x36\n\x0ftablet_controls\x18\x06 \x03(\x0b\x32\x1d.topodata.Shard.TabletControl\x12\x19\n\x11is_master_serving\x18\x07 \x01(\x08\x1a\x46\n\nServedType\x12)\n\x0btablet_type\x18\x01 \x01(\x0e\x32\x14.topodata.TabletType\x12\r\n\x05\x63\x65lls\x18\x02 \x03(\t\x1ar\n\x0bSourceShard\x12\x0b\n\x03uid\x18\x01 \x01(\r\x12\x10\n\x08keyspace\x18\x02 \x01(\t\x12\r\n\x05shard\x18\x03 \x01(\t\x12%\n\tkey_range\x18\x04 \x01(\x0b\x32\x12.topodata.KeyRange\x12\x0e\n\x06tables\x18\x05 \x03(\t\x1a{\n\rTabletControl\x12)\n\x0btablet_type\x18\x01 \x01(\x0e\x32\x14.topodata.TabletType\x12\r\n\x05\x63\x65lls\x18\x02 \x03(\t\x12\x1a\n\x12\x62lacklisted_tables\x18\x04 \x03(\t\x12\x0e\n\x06\x66rozen\x18\x05 \x01(\x08J\x04\x08\x03\x10\x04J\x04\x08\x05\x10\x06\"\xe0\x02\n\x08Keyspace\x12\x1c\n\x14sharding_column_name\x18\x01 \x01(\t\x12\x36\n\x14sharding_column_type\x18\x02 \x01(\x0e\x32\x18.topodata.KeyspaceIdType\x12\x33\n\x0cserved_froms\x18\x04 \x03(\x0b\x32\x1d.topodata.Keyspace.ServedFrom\x12-\n\rkeyspace_type\x18\x05 \x01(\x0e\x32\x16.topodata.KeyspaceType\x12\x15\n\rbase_keyspace\x18\x06 \x01(\t\x12#\n\rsnapshot_time\x18\x07 \x01(\x0b\x32\x0c.vttime.Time\x1aX\n\nServedFrom\x12)\n\x0btablet_type\x18\x01 \x01(\x0e\x32\x14.topodata.TabletType\x12\r\n\x05\x63\x65lls\x18\x02 \x03(\t\x12\x10\n\x08keyspace\x18\x03 \x01(\tJ\x04\x08\x03\x10\x04\"w\n\x10ShardReplication\x12.\n\x05nodes\x18\x01 \x03(\x0b\x32\x1f.topodata.ShardReplication.Node\x1a\x33\n\x04Node\x12+\n\x0ctablet_alias\x18\x01 \x01(\x0b\x32\x15.topodata.TabletAlias\"E\n\x0eShardReference\x12\x0c\n\x04name\x18\x01 \x01(\t\x12%\n\tkey_range\x18\x02 \x01(\x0b\x32\x12.topodata.KeyRange\"i\n\x12ShardTabletControl\x12\x0c\n\x04name\x18\x01 \x01(\t\x12%\n\tkey_range\x18\x02 \x01(\x0b\x32\x12.topodata.KeyRange\x12\x1e\n\x16query_service_disabled\x18\x03 \x01(\x08\"\xda\x03\n\x0bSrvKeyspace\x12;\n\npartitions\x18\x01 \x03(\x0b\x32\'.topodata.SrvKeyspace.KeyspacePartition\x12\x1c\n\x14sharding_column_name\x18\x02 \x01(\t\x12\x36\n\x14sharding_column_type\x18\x03 \x01(\x0e\x32\x18.topodata.KeyspaceIdType\x12\x35\n\x0bserved_from\x18\x04 \x03(\x0b\x32 .topodata.SrvKeyspace.ServedFrom\x1a\xaf\x01\n\x11KeyspacePartition\x12)\n\x0bserved_type\x18\x01 \x01(\x0e\x32\x14.topodata.TabletType\x12\x32\n\x10shard_references\x18\x02 \x03(\x0b\x32\x18.topodata.ShardReference\x12;\n\x15shard_tablet_controls\x18\x03 \x03(\x0b\x32\x1c.topodata.ShardTabletControl\x1aI\n\nServedFrom\x12)\n\x0btablet_type\x18\x01 \x01(\x0e\x32\x14.topodata.TabletType\x12\x10\n\x08keyspace\x18\x02 \x01(\tJ\x04\x08\x05\x10\x06\"6\n\x08\x43\x65llInfo\x12\x16\n\x0eserver_address\x18\x01 \x01(\t\x12\x0c\n\x04root\x18\x02 \x01(\tJ\x04\x08\x03\x10\x04\"\x1b\n\nCellsAlias\x12\r\n\x05\x63\x65lls\x18\x02 \x03(\t*(\n\x0cKeyspaceType\x12\n\n\x06NORMAL\x10\x00\x12\x0c\n\x08SNAPSHOT\x10\x01*2\n\x0eKeyspaceIdType\x12\t\n\x05UNSET\x10\x00\x12\n\n\x06UINT64\x10\x01\x12\t\n\x05\x42YTES\x10\x02*\x90\x01\n\nTabletType\x12\x0b\n\x07UNKNOWN\x10\x00\x12\n\n\x06MASTER\x10\x01\x12\x0b\n\x07REPLICA\x10\x02\x12\n\n\x06RDONLY\x10\x03\x12\t\n\x05\x42\x41TCH\x10\x03\x12\t\n\x05SPARE\x10\x04\x12\x10\n\x0c\x45XPERIMENTAL\x10\x05\x12\n\n\x06\x42\x41\x43KUP\x10\x06\x12\x0b\n\x07RESTORE\x10\x07\x12\x0b\n\x07\x44RAINED\x10\x08\x1a\x02\x10\x01\x42\x38\n\x0fio.vitess.protoZ%vitess.io/vitess/go/vt/proto/topodatab\x06proto3') + , + dependencies=[time__pb2.DESCRIPTOR,]) + +_KEYSPACETYPE = _descriptor.EnumDescriptor( + name='KeyspaceType', + full_name='topodata.KeyspaceType', + filename=None, + file=DESCRIPTOR, + values=[ + _descriptor.EnumValueDescriptor( + name='NORMAL', index=0, number=0, + serialized_options=None, + type=None), + _descriptor.EnumValueDescriptor( + name='SNAPSHOT', index=1, number=1, + serialized_options=None, + type=None), + ], + containing_type=None, + serialized_options=None, + serialized_start=2469, + serialized_end=2509, ) +_sym_db.RegisterEnumDescriptor(_KEYSPACETYPE) +KeyspaceType = enum_type_wrapper.EnumTypeWrapper(_KEYSPACETYPE) _KEYSPACEIDTYPE = _descriptor.EnumDescriptor( name='KeyspaceIdType', full_name='topodata.KeyspaceIdType', @@ -44,8 +69,8 @@ ], containing_type=None, serialized_options=None, - serialized_start=2258, - serialized_end=2308, + serialized_start=2511, + serialized_end=2561, ) _sym_db.RegisterEnumDescriptor(_KEYSPACEIDTYPE) @@ -99,12 +124,14 @@ ], containing_type=None, serialized_options=_b('\020\001'), - serialized_start=2311, - serialized_end=2455, + serialized_start=2564, + serialized_end=2708, ) _sym_db.RegisterEnumDescriptor(_TABLETTYPE) TabletType = enum_type_wrapper.EnumTypeWrapper(_TABLETTYPE) +NORMAL = 0 +SNAPSHOT = 1 UNSET = 0 UINT64 = 1 BYTES = 2 @@ -154,8 +181,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=28, - serialized_end=66, + serialized_start=40, + serialized_end=78, ) @@ -192,8 +219,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=68, - serialized_end=108, + serialized_start=80, + serialized_end=120, ) @@ -230,8 +257,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=446, - serialized_end=492, + serialized_start=504, + serialized_end=550, ) _TABLET_TAGSENTRY = _descriptor.Descriptor( @@ -267,8 +294,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=494, - serialized_end=537, + serialized_start=552, + serialized_end=595, ) _TABLET = _descriptor.Descriptor( @@ -355,6 +382,13 @@ message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='master_term_start_time', full_name='topodata.Tablet.master_term_start_time', index=11, + number=14, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), ], extensions=[ ], @@ -367,8 +401,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=111, - serialized_end=549, + serialized_start=123, + serialized_end=607, ) @@ -405,8 +439,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=830, - serialized_end=900, + serialized_start=934, + serialized_end=1004, ) _SHARD_SOURCESHARD = _descriptor.Descriptor( @@ -463,8 +497,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=902, - serialized_end=1016, + serialized_start=1006, + serialized_end=1120, ) _SHARD_TABLETCONTROL = _descriptor.Descriptor( @@ -514,8 +548,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=1018, - serialized_end=1141, + serialized_start=1122, + serialized_end=1245, ) _SHARD = _descriptor.Descriptor( @@ -533,35 +567,42 @@ is_extension=False, extension_scope=None, serialized_options=None, file=DESCRIPTOR), _descriptor.FieldDescriptor( - name='key_range', full_name='topodata.Shard.key_range', index=1, + name='master_term_start_time', full_name='topodata.Shard.master_term_start_time', index=1, + number=8, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='key_range', full_name='topodata.Shard.key_range', index=2, number=2, type=11, cpp_type=10, label=1, has_default_value=False, default_value=None, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, serialized_options=None, file=DESCRIPTOR), _descriptor.FieldDescriptor( - name='served_types', full_name='topodata.Shard.served_types', index=2, + name='served_types', full_name='topodata.Shard.served_types', index=3, number=3, type=11, cpp_type=10, label=3, has_default_value=False, default_value=[], message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, serialized_options=None, file=DESCRIPTOR), _descriptor.FieldDescriptor( - name='source_shards', full_name='topodata.Shard.source_shards', index=3, + name='source_shards', full_name='topodata.Shard.source_shards', index=4, number=4, type=11, cpp_type=10, label=3, has_default_value=False, default_value=[], message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, serialized_options=None, file=DESCRIPTOR), _descriptor.FieldDescriptor( - name='tablet_controls', full_name='topodata.Shard.tablet_controls', index=4, + name='tablet_controls', full_name='topodata.Shard.tablet_controls', index=5, number=6, type=11, cpp_type=10, label=3, has_default_value=False, default_value=[], message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, serialized_options=None, file=DESCRIPTOR), _descriptor.FieldDescriptor( - name='is_master_serving', full_name='topodata.Shard.is_master_serving', index=5, + name='is_master_serving', full_name='topodata.Shard.is_master_serving', index=6, number=7, type=8, cpp_type=7, label=1, has_default_value=False, default_value=False, message_type=None, enum_type=None, containing_type=None, @@ -579,8 +620,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=552, - serialized_end=1147, + serialized_start=610, + serialized_end=1251, ) @@ -624,8 +665,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=1301, - serialized_end=1389, + serialized_start=1512, + serialized_end=1600, ) _KEYSPACE = _descriptor.Descriptor( @@ -656,6 +697,27 @@ message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='keyspace_type', full_name='topodata.Keyspace.keyspace_type', index=3, + number=5, type=14, cpp_type=8, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='base_keyspace', full_name='topodata.Keyspace.base_keyspace', index=4, + number=6, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='snapshot_time', full_name='topodata.Keyspace.snapshot_time', index=5, + number=7, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), ], extensions=[ ], @@ -668,8 +730,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=1150, - serialized_end=1395, + serialized_start=1254, + serialized_end=1606, ) @@ -699,8 +761,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=1465, - serialized_end=1516, + serialized_start=1676, + serialized_end=1727, ) _SHARDREPLICATION = _descriptor.Descriptor( @@ -729,8 +791,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=1397, - serialized_end=1516, + serialized_start=1608, + serialized_end=1727, ) @@ -767,8 +829,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=1518, - serialized_end=1587, + serialized_start=1729, + serialized_end=1798, ) @@ -812,8 +874,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=1589, - serialized_end=1694, + serialized_start=1800, + serialized_end=1905, ) @@ -857,8 +919,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=1915, - serialized_end=2090, + serialized_start=2126, + serialized_end=2301, ) _SRVKEYSPACE_SERVEDFROM = _descriptor.Descriptor( @@ -894,8 +956,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=2092, - serialized_end=2165, + serialized_start=2303, + serialized_end=2376, ) _SRVKEYSPACE = _descriptor.Descriptor( @@ -945,8 +1007,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=1697, - serialized_end=2171, + serialized_start=1908, + serialized_end=2382, ) @@ -983,8 +1045,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=2173, - serialized_end=2227, + serialized_start=2384, + serialized_end=2438, ) @@ -1014,8 +1076,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=2229, - serialized_end=2256, + serialized_start=2440, + serialized_end=2467, ) _TABLET_PORTMAPENTRY.containing_type = _TABLET @@ -1025,6 +1087,7 @@ _TABLET.fields_by_name['key_range'].message_type = _KEYRANGE _TABLET.fields_by_name['type'].enum_type = _TABLETTYPE _TABLET.fields_by_name['tags'].message_type = _TABLET_TAGSENTRY +_TABLET.fields_by_name['master_term_start_time'].message_type = time__pb2._TIME _SHARD_SERVEDTYPE.fields_by_name['tablet_type'].enum_type = _TABLETTYPE _SHARD_SERVEDTYPE.containing_type = _SHARD _SHARD_SOURCESHARD.fields_by_name['key_range'].message_type = _KEYRANGE @@ -1032,6 +1095,7 @@ _SHARD_TABLETCONTROL.fields_by_name['tablet_type'].enum_type = _TABLETTYPE _SHARD_TABLETCONTROL.containing_type = _SHARD _SHARD.fields_by_name['master_alias'].message_type = _TABLETALIAS +_SHARD.fields_by_name['master_term_start_time'].message_type = time__pb2._TIME _SHARD.fields_by_name['key_range'].message_type = _KEYRANGE _SHARD.fields_by_name['served_types'].message_type = _SHARD_SERVEDTYPE _SHARD.fields_by_name['source_shards'].message_type = _SHARD_SOURCESHARD @@ -1040,6 +1104,8 @@ _KEYSPACE_SERVEDFROM.containing_type = _KEYSPACE _KEYSPACE.fields_by_name['sharding_column_type'].enum_type = _KEYSPACEIDTYPE _KEYSPACE.fields_by_name['served_froms'].message_type = _KEYSPACE_SERVEDFROM +_KEYSPACE.fields_by_name['keyspace_type'].enum_type = _KEYSPACETYPE +_KEYSPACE.fields_by_name['snapshot_time'].message_type = time__pb2._TIME _SHARDREPLICATION_NODE.fields_by_name['tablet_alias'].message_type = _TABLETALIAS _SHARDREPLICATION_NODE.containing_type = _SHARDREPLICATION _SHARDREPLICATION.fields_by_name['nodes'].message_type = _SHARDREPLICATION_NODE @@ -1065,6 +1131,7 @@ DESCRIPTOR.message_types_by_name['SrvKeyspace'] = _SRVKEYSPACE DESCRIPTOR.message_types_by_name['CellInfo'] = _CELLINFO DESCRIPTOR.message_types_by_name['CellsAlias'] = _CELLSALIAS +DESCRIPTOR.enum_types_by_name['KeyspaceType'] = _KEYSPACETYPE DESCRIPTOR.enum_types_by_name['KeyspaceIdType'] = _KEYSPACEIDTYPE DESCRIPTOR.enum_types_by_name['TabletType'] = _TABLETTYPE _sym_db.RegisterFileDescriptor(DESCRIPTOR) diff --git a/py/vtproto/vschema_pb2.py b/py/vtproto/vschema_pb2.py index 94f613b8df1..90897a8f264 100644 --- a/py/vtproto/vschema_pb2.py +++ b/py/vtproto/vschema_pb2.py @@ -20,7 +20,7 @@ package='vschema', syntax='proto3', serialized_options=_b('Z$vitess.io/vitess/go/vt/proto/vschema'), - serialized_pb=_b('\n\rvschema.proto\x12\x07vschema\x1a\x0bquery.proto\"3\n\x0cRoutingRules\x12#\n\x05rules\x18\x01 \x03(\x0b\x32\x14.vschema.RoutingRule\"4\n\x0bRoutingRule\x12\x12\n\nfrom_table\x18\x01 \x01(\t\x12\x11\n\tto_tables\x18\x02 \x03(\t\"\xfe\x01\n\x08Keyspace\x12\x0f\n\x07sharded\x18\x01 \x01(\x08\x12\x31\n\x08vindexes\x18\x02 \x03(\x0b\x32\x1f.vschema.Keyspace.VindexesEntry\x12-\n\x06tables\x18\x03 \x03(\x0b\x32\x1d.vschema.Keyspace.TablesEntry\x1a@\n\rVindexesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\x1e\n\x05value\x18\x02 \x01(\x0b\x32\x0f.vschema.Vindex:\x02\x38\x01\x1a=\n\x0bTablesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\x1d\n\x05value\x18\x02 \x01(\x0b\x32\x0e.vschema.Table:\x02\x38\x01\"\x81\x01\n\x06Vindex\x12\x0c\n\x04type\x18\x01 \x01(\t\x12+\n\x06params\x18\x02 \x03(\x0b\x32\x1b.vschema.Vindex.ParamsEntry\x12\r\n\x05owner\x18\x03 \x01(\t\x1a-\n\x0bParamsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"\xca\x01\n\x05Table\x12\x0c\n\x04type\x18\x01 \x01(\t\x12.\n\x0f\x63olumn_vindexes\x18\x02 \x03(\x0b\x32\x15.vschema.ColumnVindex\x12.\n\x0e\x61uto_increment\x18\x03 \x01(\x0b\x32\x16.vschema.AutoIncrement\x12 \n\x07\x63olumns\x18\x04 \x03(\x0b\x32\x0f.vschema.Column\x12\x0e\n\x06pinned\x18\x05 \x01(\t\x12!\n\x19\x63olumn_list_authoritative\x18\x06 \x01(\x08\"=\n\x0c\x43olumnVindex\x12\x0e\n\x06\x63olumn\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x0f\n\x07\x63olumns\x18\x03 \x03(\t\"1\n\rAutoIncrement\x12\x0e\n\x06\x63olumn\x18\x01 \x01(\t\x12\x10\n\x08sequence\x18\x02 \x01(\t\"1\n\x06\x43olumn\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x19\n\x04type\x18\x02 \x01(\x0e\x32\x0b.query.Type\"\xb6\x01\n\nSrvVSchema\x12\x35\n\tkeyspaces\x18\x01 \x03(\x0b\x32\".vschema.SrvVSchema.KeyspacesEntry\x12,\n\rrouting_rules\x18\x02 \x01(\x0b\x32\x15.vschema.RoutingRules\x1a\x43\n\x0eKeyspacesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12 \n\x05value\x18\x02 \x01(\x0b\x32\x11.vschema.Keyspace:\x02\x38\x01\x42&Z$vitess.io/vitess/go/vt/proto/vschemab\x06proto3') + serialized_pb=_b('\n\rvschema.proto\x12\x07vschema\x1a\x0bquery.proto\"3\n\x0cRoutingRules\x12#\n\x05rules\x18\x01 \x03(\x0b\x32\x14.vschema.RoutingRule\"4\n\x0bRoutingRule\x12\x12\n\nfrom_table\x18\x01 \x01(\t\x12\x11\n\tto_tables\x18\x02 \x03(\t\"\xa0\x02\n\x08Keyspace\x12\x0f\n\x07sharded\x18\x01 \x01(\x08\x12\x31\n\x08vindexes\x18\x02 \x03(\x0b\x32\x1f.vschema.Keyspace.VindexesEntry\x12-\n\x06tables\x18\x03 \x03(\x0b\x32\x1d.vschema.Keyspace.TablesEntry\x12 \n\x18require_explicit_routing\x18\x04 \x01(\x08\x1a@\n\rVindexesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\x1e\n\x05value\x18\x02 \x01(\x0b\x32\x0f.vschema.Vindex:\x02\x38\x01\x1a=\n\x0bTablesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\x1d\n\x05value\x18\x02 \x01(\x0b\x32\x0e.vschema.Table:\x02\x38\x01\"\x81\x01\n\x06Vindex\x12\x0c\n\x04type\x18\x01 \x01(\t\x12+\n\x06params\x18\x02 \x03(\x0b\x32\x1b.vschema.Vindex.ParamsEntry\x12\r\n\x05owner\x18\x03 \x01(\t\x1a-\n\x0bParamsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"\xca\x01\n\x05Table\x12\x0c\n\x04type\x18\x01 \x01(\t\x12.\n\x0f\x63olumn_vindexes\x18\x02 \x03(\x0b\x32\x15.vschema.ColumnVindex\x12.\n\x0e\x61uto_increment\x18\x03 \x01(\x0b\x32\x16.vschema.AutoIncrement\x12 \n\x07\x63olumns\x18\x04 \x03(\x0b\x32\x0f.vschema.Column\x12\x0e\n\x06pinned\x18\x05 \x01(\t\x12!\n\x19\x63olumn_list_authoritative\x18\x06 \x01(\x08\"=\n\x0c\x43olumnVindex\x12\x0e\n\x06\x63olumn\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x0f\n\x07\x63olumns\x18\x03 \x03(\t\"1\n\rAutoIncrement\x12\x0e\n\x06\x63olumn\x18\x01 \x01(\t\x12\x10\n\x08sequence\x18\x02 \x01(\t\"1\n\x06\x43olumn\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x19\n\x04type\x18\x02 \x01(\x0e\x32\x0b.query.Type\"\xb6\x01\n\nSrvVSchema\x12\x35\n\tkeyspaces\x18\x01 \x03(\x0b\x32\".vschema.SrvVSchema.KeyspacesEntry\x12,\n\rrouting_rules\x18\x02 \x01(\x0b\x32\x15.vschema.RoutingRules\x1a\x43\n\x0eKeyspacesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12 \n\x05value\x18\x02 \x01(\x0b\x32\x11.vschema.Keyspace:\x02\x38\x01\x42&Z$vitess.io/vitess/go/vt/proto/vschemab\x06proto3') , dependencies=[query__pb2.DESCRIPTOR,]) @@ -129,8 +129,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=274, - serialized_end=338, + serialized_start=308, + serialized_end=372, ) _KEYSPACE_TABLESENTRY = _descriptor.Descriptor( @@ -166,8 +166,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=340, - serialized_end=401, + serialized_start=374, + serialized_end=435, ) _KEYSPACE = _descriptor.Descriptor( @@ -198,6 +198,13 @@ message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='require_explicit_routing', full_name='vschema.Keyspace.require_explicit_routing', index=3, + number=4, type=8, cpp_type=7, label=1, + has_default_value=False, default_value=False, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), ], extensions=[ ], @@ -211,7 +218,7 @@ oneofs=[ ], serialized_start=147, - serialized_end=401, + serialized_end=435, ) @@ -248,8 +255,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=488, - serialized_end=533, + serialized_start=522, + serialized_end=567, ) _VINDEX = _descriptor.Descriptor( @@ -292,8 +299,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=404, - serialized_end=533, + serialized_start=438, + serialized_end=567, ) @@ -358,8 +365,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=536, - serialized_end=738, + serialized_start=570, + serialized_end=772, ) @@ -403,8 +410,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=740, - serialized_end=801, + serialized_start=774, + serialized_end=835, ) @@ -441,8 +448,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=803, - serialized_end=852, + serialized_start=837, + serialized_end=886, ) @@ -479,8 +486,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=854, - serialized_end=903, + serialized_start=888, + serialized_end=937, ) @@ -517,8 +524,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=1021, - serialized_end=1088, + serialized_start=1055, + serialized_end=1122, ) _SRVVSCHEMA = _descriptor.Descriptor( @@ -554,8 +561,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=906, - serialized_end=1088, + serialized_start=940, + serialized_end=1122, ) _ROUTINGRULES.fields_by_name['rules'].message_type = _ROUTINGRULE diff --git a/py/vtproto/vtrpc_pb2.py b/py/vtproto/vtrpc_pb2.py index 5c9cfc4cc6a..39c07d0a732 100644 --- a/py/vtproto/vtrpc_pb2.py +++ b/py/vtproto/vtrpc_pb2.py @@ -8,7 +8,6 @@ from google.protobuf import message as _message from google.protobuf import reflection as _reflection from google.protobuf import symbol_database as _symbol_database -from google.protobuf import descriptor_pb2 # @@protoc_insertion_point(imports) _sym_db = _symbol_database.Default() @@ -20,6 +19,7 @@ name='vtrpc.proto', package='vtrpc', syntax='proto3', + serialized_options=_b('\n\017io.vitess.protoZ\"vitess.io/vitess/go/vt/proto/vtrpc'), serialized_pb=_b('\n\x0bvtrpc.proto\x12\x05vtrpc\"F\n\x08\x43\x61llerID\x12\x11\n\tprincipal\x18\x01 \x01(\t\x12\x11\n\tcomponent\x18\x02 \x01(\t\x12\x14\n\x0csubcomponent\x18\x03 \x01(\t\"c\n\x08RPCError\x12+\n\x0blegacy_code\x18\x01 \x01(\x0e\x32\x16.vtrpc.LegacyErrorCode\x12\x0f\n\x07message\x18\x02 \x01(\t\x12\x19\n\x04\x63ode\x18\x03 \x01(\x0e\x32\x0b.vtrpc.Code*\xb6\x02\n\x04\x43ode\x12\x06\n\x02OK\x10\x00\x12\x0c\n\x08\x43\x41NCELED\x10\x01\x12\x0b\n\x07UNKNOWN\x10\x02\x12\x14\n\x10INVALID_ARGUMENT\x10\x03\x12\x15\n\x11\x44\x45\x41\x44LINE_EXCEEDED\x10\x04\x12\r\n\tNOT_FOUND\x10\x05\x12\x12\n\x0e\x41LREADY_EXISTS\x10\x06\x12\x15\n\x11PERMISSION_DENIED\x10\x07\x12\x13\n\x0fUNAUTHENTICATED\x10\x10\x12\x16\n\x12RESOURCE_EXHAUSTED\x10\x08\x12\x17\n\x13\x46\x41ILED_PRECONDITION\x10\t\x12\x0b\n\x07\x41\x42ORTED\x10\n\x12\x10\n\x0cOUT_OF_RANGE\x10\x0b\x12\x11\n\rUNIMPLEMENTED\x10\x0c\x12\x0c\n\x08INTERNAL\x10\r\x12\x0f\n\x0bUNAVAILABLE\x10\x0e\x12\r\n\tDATA_LOSS\x10\x0f*\xe8\x02\n\x0fLegacyErrorCode\x12\x12\n\x0eSUCCESS_LEGACY\x10\x00\x12\x14\n\x10\x43\x41NCELLED_LEGACY\x10\x01\x12\x18\n\x14UNKNOWN_ERROR_LEGACY\x10\x02\x12\x14\n\x10\x42\x41\x44_INPUT_LEGACY\x10\x03\x12\x1c\n\x18\x44\x45\x41\x44LINE_EXCEEDED_LEGACY\x10\x04\x12\x1a\n\x16INTEGRITY_ERROR_LEGACY\x10\x05\x12\x1c\n\x18PERMISSION_DENIED_LEGACY\x10\x06\x12\x1d\n\x19RESOURCE_EXHAUSTED_LEGACY\x10\x07\x12\x1b\n\x17QUERY_NOT_SERVED_LEGACY\x10\x08\x12\x14\n\x10NOT_IN_TX_LEGACY\x10\t\x12\x19\n\x15INTERNAL_ERROR_LEGACY\x10\n\x12\x1a\n\x16TRANSIENT_ERROR_LEGACY\x10\x0b\x12\x1a\n\x16UNAUTHENTICATED_LEGACY\x10\x0c\x42\x35\n\x0fio.vitess.protoZ\"vitess.io/vitess/go/vt/proto/vtrpcb\x06proto3') ) @@ -31,75 +31,75 @@ values=[ _descriptor.EnumValueDescriptor( name='OK', index=0, number=0, - options=None, + serialized_options=None, type=None), _descriptor.EnumValueDescriptor( name='CANCELED', index=1, number=1, - options=None, + serialized_options=None, type=None), _descriptor.EnumValueDescriptor( name='UNKNOWN', index=2, number=2, - options=None, + serialized_options=None, type=None), _descriptor.EnumValueDescriptor( name='INVALID_ARGUMENT', index=3, number=3, - options=None, + serialized_options=None, type=None), _descriptor.EnumValueDescriptor( name='DEADLINE_EXCEEDED', index=4, number=4, - options=None, + serialized_options=None, type=None), _descriptor.EnumValueDescriptor( name='NOT_FOUND', index=5, number=5, - options=None, + serialized_options=None, type=None), _descriptor.EnumValueDescriptor( name='ALREADY_EXISTS', index=6, number=6, - options=None, + serialized_options=None, type=None), _descriptor.EnumValueDescriptor( name='PERMISSION_DENIED', index=7, number=7, - options=None, + serialized_options=None, type=None), _descriptor.EnumValueDescriptor( name='UNAUTHENTICATED', index=8, number=16, - options=None, + serialized_options=None, type=None), _descriptor.EnumValueDescriptor( name='RESOURCE_EXHAUSTED', index=9, number=8, - options=None, + serialized_options=None, type=None), _descriptor.EnumValueDescriptor( name='FAILED_PRECONDITION', index=10, number=9, - options=None, + serialized_options=None, type=None), _descriptor.EnumValueDescriptor( name='ABORTED', index=11, number=10, - options=None, + serialized_options=None, type=None), _descriptor.EnumValueDescriptor( name='OUT_OF_RANGE', index=12, number=11, - options=None, + serialized_options=None, type=None), _descriptor.EnumValueDescriptor( name='UNIMPLEMENTED', index=13, number=12, - options=None, + serialized_options=None, type=None), _descriptor.EnumValueDescriptor( name='INTERNAL', index=14, number=13, - options=None, + serialized_options=None, type=None), _descriptor.EnumValueDescriptor( name='UNAVAILABLE', index=15, number=14, - options=None, + serialized_options=None, type=None), _descriptor.EnumValueDescriptor( name='DATA_LOSS', index=16, number=15, - options=None, + serialized_options=None, type=None), ], containing_type=None, - options=None, + serialized_options=None, serialized_start=196, serialized_end=506, ) @@ -114,59 +114,59 @@ values=[ _descriptor.EnumValueDescriptor( name='SUCCESS_LEGACY', index=0, number=0, - options=None, + serialized_options=None, type=None), _descriptor.EnumValueDescriptor( name='CANCELLED_LEGACY', index=1, number=1, - options=None, + serialized_options=None, type=None), _descriptor.EnumValueDescriptor( name='UNKNOWN_ERROR_LEGACY', index=2, number=2, - options=None, + serialized_options=None, type=None), _descriptor.EnumValueDescriptor( name='BAD_INPUT_LEGACY', index=3, number=3, - options=None, + serialized_options=None, type=None), _descriptor.EnumValueDescriptor( name='DEADLINE_EXCEEDED_LEGACY', index=4, number=4, - options=None, + serialized_options=None, type=None), _descriptor.EnumValueDescriptor( name='INTEGRITY_ERROR_LEGACY', index=5, number=5, - options=None, + serialized_options=None, type=None), _descriptor.EnumValueDescriptor( name='PERMISSION_DENIED_LEGACY', index=6, number=6, - options=None, + serialized_options=None, type=None), _descriptor.EnumValueDescriptor( name='RESOURCE_EXHAUSTED_LEGACY', index=7, number=7, - options=None, + serialized_options=None, type=None), _descriptor.EnumValueDescriptor( name='QUERY_NOT_SERVED_LEGACY', index=8, number=8, - options=None, + serialized_options=None, type=None), _descriptor.EnumValueDescriptor( name='NOT_IN_TX_LEGACY', index=9, number=9, - options=None, + serialized_options=None, type=None), _descriptor.EnumValueDescriptor( name='INTERNAL_ERROR_LEGACY', index=10, number=10, - options=None, + serialized_options=None, type=None), _descriptor.EnumValueDescriptor( name='TRANSIENT_ERROR_LEGACY', index=11, number=11, - options=None, + serialized_options=None, type=None), _descriptor.EnumValueDescriptor( name='UNAUTHENTICATED_LEGACY', index=12, number=12, - options=None, + serialized_options=None, type=None), ], containing_type=None, - options=None, + serialized_options=None, serialized_start=509, serialized_end=869, ) @@ -219,28 +219,28 @@ has_default_value=False, default_value=_b("").decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), + serialized_options=None, file=DESCRIPTOR), _descriptor.FieldDescriptor( name='component', full_name='vtrpc.CallerID.component', index=1, number=2, type=9, cpp_type=9, label=1, has_default_value=False, default_value=_b("").decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), + serialized_options=None, file=DESCRIPTOR), _descriptor.FieldDescriptor( name='subcomponent', full_name='vtrpc.CallerID.subcomponent', index=2, number=3, type=9, cpp_type=9, label=1, has_default_value=False, default_value=_b("").decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), + serialized_options=None, file=DESCRIPTOR), ], extensions=[ ], nested_types=[], enum_types=[ ], - options=None, + serialized_options=None, is_extendable=False, syntax='proto3', extension_ranges=[], @@ -264,28 +264,28 @@ has_default_value=False, default_value=0, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), + serialized_options=None, file=DESCRIPTOR), _descriptor.FieldDescriptor( name='message', full_name='vtrpc.RPCError.message', index=1, number=2, type=9, cpp_type=9, label=1, has_default_value=False, default_value=_b("").decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), + serialized_options=None, file=DESCRIPTOR), _descriptor.FieldDescriptor( name='code', full_name='vtrpc.RPCError.code', index=2, number=3, type=14, cpp_type=8, label=1, has_default_value=False, default_value=0, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), + serialized_options=None, file=DESCRIPTOR), ], extensions=[ ], nested_types=[], enum_types=[ ], - options=None, + serialized_options=None, is_extendable=False, syntax='proto3', extension_ranges=[], @@ -318,6 +318,5 @@ _sym_db.RegisterMessage(RPCError) -DESCRIPTOR.has_options = True -DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), _b('\n\017io.vitess.protoZ\"vitess.io/vitess/go/vt/proto/vtrpc')) +DESCRIPTOR._options = None # @@protoc_insertion_point(module_scope) diff --git a/py/vttest/__init__.py b/py/vttest/__init__.py index 14394e97a10..4d32e37cccb 100644 --- a/py/vttest/__init__.py +++ b/py/vttest/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2017 Google Inc. +# 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. diff --git a/py/vttest/environment.py b/py/vttest/environment.py index 4c55910646e..b84d14814de 100644 --- a/py/vttest/environment.py +++ b/py/vttest/environment.py @@ -1,4 +1,4 @@ -# Copyright 2017 Google Inc. +# 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. diff --git a/py/vttest/init_data_options.py b/py/vttest/init_data_options.py index 0cd4efd7382..04219f036b2 100644 --- a/py/vttest/init_data_options.py +++ b/py/vttest/init_data_options.py @@ -1,4 +1,4 @@ -# Copyright 2017 Google Inc. +# 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. diff --git a/py/vttest/local_database.py b/py/vttest/local_database.py index e5e5117bf25..fb3adeba309 100644 --- a/py/vttest/local_database.py +++ b/py/vttest/local_database.py @@ -1,4 +1,4 @@ -# Copyright 2017 Google Inc. +# 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. diff --git a/py/vttest/mysql_db.py b/py/vttest/mysql_db.py index 1ddb97a0ef3..fe0c4e2037b 100644 --- a/py/vttest/mysql_db.py +++ b/py/vttest/mysql_db.py @@ -1,4 +1,4 @@ -# Copyright 2017 Google Inc. +# 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. diff --git a/py/vttest/mysql_db_mysqlctl.py b/py/vttest/mysql_db_mysqlctl.py index 50e7cc58d27..f79f5c6504f 100644 --- a/py/vttest/mysql_db_mysqlctl.py +++ b/py/vttest/mysql_db_mysqlctl.py @@ -1,4 +1,4 @@ -# Copyright 2017 Google Inc. +# 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. diff --git a/py/vttest/mysql_flavor.py b/py/vttest/mysql_flavor.py index 02183d3da8f..26e8aaf3d49 100644 --- a/py/vttest/mysql_flavor.py +++ b/py/vttest/mysql_flavor.py @@ -1,4 +1,4 @@ -# Copyright 2017 Google Inc. +# 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. @@ -49,7 +49,7 @@ class MariaDB(MysqlFlavor): def my_cnf(self): files = [ os.path.join(vttop, "config/mycnf/default-fast.cnf"), - os.path.join(vttop, "config/mycnf/master_mariadb.cnf"), + os.path.join(vttop, "config/mycnf/master_mariadb100.cnf"), ] return ":".join(files) @@ -99,7 +99,7 @@ def set_mysql_flavor(flavor): global __mysql_flavor # Last default is there because the environment variable might be set to "". - flavor = flavor or os.environ.get("MYSQL_FLAVOR", "MariaDB") or "MariaDB" + flavor = flavor or os.environ.get("MYSQL_FLAVOR", "MySQL56") or "MySQL56" # Set the environment variable explicitly in case we're overriding it via # command-line flag. diff --git a/py/vttest/run_local_database.py b/py/vttest/run_local_database.py index 41abb0537cb..8301a4e2b42 100755 --- a/py/vttest/run_local_database.py +++ b/py/vttest/run_local_database.py @@ -1,6 +1,6 @@ #!/usr/bin/env python -# Copyright 2017 Google Inc. +# 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. diff --git a/py/vttest/sharding_utils.py b/py/vttest/sharding_utils.py index 432fbf9f6a9..db9b15ff6b9 100644 --- a/py/vttest/sharding_utils.py +++ b/py/vttest/sharding_utils.py @@ -1,6 +1,6 @@ #!/usr/bin/env python -# Copyright 2017 Google Inc. +# 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. diff --git a/py/vttest/vt_processes.py b/py/vttest/vt_processes.py index 7dccde5ec06..14de9fb347e 100644 --- a/py/vttest/vt_processes.py +++ b/py/vttest/vt_processes.py @@ -1,4 +1,4 @@ -# Copyright 2017 Google Inc. +# 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. diff --git a/test.go b/test.go index 84faf767082..73b75e9df30 100755 --- a/test.go +++ b/test.go @@ -1,20 +1,20 @@ ///bin/true; exec /usr/bin/env go run "$0" "$@" /* -Copyright 2017 Google Inc. + * 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 + * 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 + * 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. -*/ + * 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. + */ /* test.go is a "Go script" for running Vitess tests. It runs each test in its own diff --git a/test/backup.py b/test/backup.py index c6d3d743452..823e2a2ba2a 100755 --- a/test/backup.py +++ b/test/backup.py @@ -1,6 +1,6 @@ #!/usr/bin/env python -# Copyright 2017 Google Inc. +# 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. diff --git a/test/backup_mysqlctld.py b/test/backup_mysqlctld.py index 58041806a99..a3ed88ee8be 100755 --- a/test/backup_mysqlctld.py +++ b/test/backup_mysqlctld.py @@ -1,6 +1,6 @@ #!/usr/bin/env python -# Copyright 2017 Google Inc. +# 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. diff --git a/test/backup_only.py b/test/backup_only.py index 2148409d8bd..dd9b547dacf 100755 --- a/test/backup_only.py +++ b/test/backup_only.py @@ -1,6 +1,6 @@ #!/usr/bin/env python -# Copyright 2017 The Vitess Authors. +# 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. @@ -101,7 +101,7 @@ def setUpModule(): fd.write(init_db) fd.write(mysql_flavor().change_passwords(password_col)) - logging.debug("initilizing mysql %s",str(datetime.datetime.now())) + logging.debug("initializing mysql %s",str(datetime.datetime.now())) # start mysql instance external to the test setup_procs = [ tablet_master.init_mysql(init_db=new_init_db, @@ -120,7 +120,7 @@ def setUpModule(): tablet_replica2.wait_for_mysqlctl_socket() else: utils.wait_procs(setup_procs) - logging.debug("done initilizing mysql %s",str(datetime.datetime.now())) + logging.debug("done initializing mysql %s",str(datetime.datetime.now())) except: tearDownModule() raise @@ -286,7 +286,7 @@ def _backup_only(self, t, initial_backup=False): def test_tablet_initial_backup(self): self._test_initial_backup() - # Restore the Shard from the inital backup + # Restore the Shard from the initial backup self._init_tablets(init=False,start=False) # Restore the Tablets diff --git a/test/backup_transform.py b/test/backup_transform.py index 050ad215499..b0e665b6fa8 100755 --- a/test/backup_transform.py +++ b/test/backup_transform.py @@ -1,6 +1,6 @@ #!/usr/bin/env python -# Copyright 2017 Google Inc. +# 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. diff --git a/test/backup_transform_mysqlctld.py b/test/backup_transform_mysqlctld.py index c5383f733d1..537b3d95a22 100755 --- a/test/backup_transform_mysqlctld.py +++ b/test/backup_transform_mysqlctld.py @@ -1,6 +1,6 @@ #!/usr/bin/env python -# Copyright 2017 Google Inc. +# 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. diff --git a/test/base_sharding.py b/test/base_sharding.py index 5cdb5398271..0978993e039 100644 --- a/test/base_sharding.py +++ b/test/base_sharding.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright 2017 Google Inc. +# 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. diff --git a/test/binlog.py b/test/binlog.py index cb677f051ab..9b4f09cb2a8 100755 --- a/test/binlog.py +++ b/test/binlog.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- # -# Copyright 2017 Google Inc. +# 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. diff --git a/test/cache_invalidation.py b/test/cache_invalidation.py index 576a7860f37..595ff7f8e6b 100755 --- a/test/cache_invalidation.py +++ b/test/cache_invalidation.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright 2017 Google Inc. +# 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. diff --git a/test/cell_no_aliases.py b/test/cell_no_aliases.py index 5344cfa0a7d..5d0668b0b4c 100755 --- a/test/cell_no_aliases.py +++ b/test/cell_no_aliases.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright 2017 Google Inc. +# 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. diff --git a/test/client_test.sh b/test/client_test.sh new file mode 100755 index 00000000000..82be7996c8d --- /dev/null +++ b/test/client_test.sh @@ -0,0 +1,53 @@ +#!/bin/bash + +# 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. + +# This runs client tests. It used to be part of local_example, +# but has been moved to its own test. It hijacks the public examples scripts + +set -xe +cd "$VTTOP/examples/local" + +CELL=test ./etcd-up.sh +CELL=test ./vtctld-up.sh + +CELL=test KEYSPACE=test_keyspace UID_BASE=100 ./vttablet-up.sh + +./lvtctl.sh InitShardMaster -force test_keyspace/0 test-100 + +./lvtctl.sh ApplySchema -sql-file create_test_table.sql test_keyspace +./lvtctl.sh RebuildVSchemaGraph + +CELL=test ./vtgate-up.sh + +echo "Run Python client script.." +./client.sh + +echo "Run Go client script..." +go run client.go -server=localhost:15991 + +echo "Run Java client script..." +./client_java.sh + +echo "Run JDBC client script..." +./client_jdbc.sh + +# Clean up + +./vtgate-down.sh +CELL=test UID_BASE=100 ./vttablet-down.sh +./vtctld-down.sh +CELL=test ./etcd-down.sh + diff --git a/test/cluster/aws_environment.py b/test/cluster/aws_environment.py index b4a9443c852..069b678a0d9 100644 --- a/test/cluster/aws_environment.py +++ b/test/cluster/aws_environment.py @@ -1,4 +1,4 @@ -# Copyright 2017 Google Inc. +# 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. diff --git a/test/cluster/backup_test.py b/test/cluster/backup_test.py index 9f9a62d2546..3bfa01b32ff 100755 --- a/test/cluster/backup_test.py +++ b/test/cluster/backup_test.py @@ -1,6 +1,6 @@ #!/usr/bin/env python -# Copyright 2017 Google Inc. +# 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. diff --git a/test/cluster/base_cluster_test.py b/test/cluster/base_cluster_test.py index 44b96780277..cb8cd5a4e63 100644 --- a/test/cluster/base_cluster_test.py +++ b/test/cluster/base_cluster_test.py @@ -1,4 +1,4 @@ -# Copyright 2017 Google Inc. +# 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. diff --git a/test/cluster/base_environment.py b/test/cluster/base_environment.py index 830d4a4f9f2..436353c4989 100644 --- a/test/cluster/base_environment.py +++ b/test/cluster/base_environment.py @@ -1,4 +1,4 @@ -# Copyright 2017 Google Inc. +# 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. diff --git a/test/cluster/drain_test.py b/test/cluster/drain_test.py index 0d17d095426..ae573d5c90f 100755 --- a/test/cluster/drain_test.py +++ b/test/cluster/drain_test.py @@ -1,6 +1,6 @@ #!/usr/bin/env python -# Copyright 2017 Google Inc. +# 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. diff --git a/test/cluster/k8s_environment.py b/test/cluster/k8s_environment.py index deddabbd20f..0951ae58a09 100644 --- a/test/cluster/k8s_environment.py +++ b/test/cluster/k8s_environment.py @@ -1,4 +1,4 @@ -# Copyright 2017 Google Inc. +# 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. diff --git a/test/cluster/keytar/dummy_test.py b/test/cluster/keytar/dummy_test.py index 66d33203181..e0ae6cf6fd9 100755 --- a/test/cluster/keytar/dummy_test.py +++ b/test/cluster/keytar/dummy_test.py @@ -1,6 +1,6 @@ #!/usr/bin/env python -# Copyright 2017 Google Inc. +# 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. diff --git a/test/cluster/keytar/keytar-down.sh b/test/cluster/keytar/keytar-down.sh index 44f9e48c26a..d82a4b08f3d 100755 --- a/test/cluster/keytar/keytar-down.sh +++ b/test/cluster/keytar/keytar-down.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2017 Google Inc. +# 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. diff --git a/test/cluster/keytar/keytar-up.sh b/test/cluster/keytar/keytar-up.sh index 5902766c0d4..a2f51b05557 100755 --- a/test/cluster/keytar/keytar-up.sh +++ b/test/cluster/keytar/keytar-up.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2017 Google Inc. +# 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. diff --git a/test/cluster/keytar/keytar.py b/test/cluster/keytar/keytar.py index e5b8e22d994..9b1af17623e 100755 --- a/test/cluster/keytar/keytar.py +++ b/test/cluster/keytar/keytar.py @@ -1,6 +1,6 @@ #!/usr/bin/env python -# Copyright 2017 Google Inc. +# 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. diff --git a/test/cluster/keytar/keytar_test.py b/test/cluster/keytar/keytar_test.py index 01855cc7bf1..04769a013b3 100644 --- a/test/cluster/keytar/keytar_test.py +++ b/test/cluster/keytar/keytar_test.py @@ -1,4 +1,4 @@ -# Copyright 2017 Google Inc. +# 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. diff --git a/test/cluster/keytar/keytar_web_test.py b/test/cluster/keytar/keytar_web_test.py index 6d948b40539..5784d3335f5 100755 --- a/test/cluster/keytar/keytar_web_test.py +++ b/test/cluster/keytar/keytar_web_test.py @@ -1,6 +1,6 @@ #!/usr/bin/env python -# Copyright 2017 Google Inc. +# 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. diff --git a/test/cluster/keytar/requirements.txt b/test/cluster/keytar/requirements.txt index 694958b30d5..310546af9c3 100644 --- a/test/cluster/keytar/requirements.txt +++ b/test/cluster/keytar/requirements.txt @@ -1,2 +1,2 @@ -Flask==0.12.3 +Flask==1.0 pyyaml==4.2b1 diff --git a/test/cluster/keytar/test_runner.py b/test/cluster/keytar/test_runner.py index 5527bd2f04c..79d8d496e04 100755 --- a/test/cluster/keytar/test_runner.py +++ b/test/cluster/keytar/test_runner.py @@ -1,4 +1,4 @@ -# Copyright 2017 Google Inc. +# 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. diff --git a/test/cluster/local_environment.py b/test/cluster/local_environment.py index 5a237c0c378..d868a2d7502 100644 --- a/test/cluster/local_environment.py +++ b/test/cluster/local_environment.py @@ -1,4 +1,4 @@ -# Copyright 2017 Google Inc. +# 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. diff --git a/test/cluster/reparent_test.py b/test/cluster/reparent_test.py index 85166f628fb..756cdea388c 100755 --- a/test/cluster/reparent_test.py +++ b/test/cluster/reparent_test.py @@ -1,6 +1,6 @@ #!/usr/bin/env python -# Copyright 2017 Google Inc. +# 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. diff --git a/test/cluster/sandbox/create_schema.py b/test/cluster/sandbox/create_schema.py index 6b28f147e23..198858eeffe 100755 --- a/test/cluster/sandbox/create_schema.py +++ b/test/cluster/sandbox/create_schema.py @@ -1,6 +1,6 @@ #!/usr/bin/env python -# Copyright 2017 Google Inc. +# 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. diff --git a/test/cluster/sandbox/fix_served_types.py b/test/cluster/sandbox/fix_served_types.py index 88441352337..10c40bf117a 100755 --- a/test/cluster/sandbox/fix_served_types.py +++ b/test/cluster/sandbox/fix_served_types.py @@ -1,6 +1,6 @@ #!/usr/bin/env python -# Copyright 2017 Google Inc. +# 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. diff --git a/test/cluster/sandbox/fix_served_types_test.py b/test/cluster/sandbox/fix_served_types_test.py index 8e67c117dd8..ed9c39c1929 100644 --- a/test/cluster/sandbox/fix_served_types_test.py +++ b/test/cluster/sandbox/fix_served_types_test.py @@ -1,4 +1,4 @@ -# Copyright 2017 Google Inc. +# 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. diff --git a/test/cluster/sandbox/gke.py b/test/cluster/sandbox/gke.py index b2448c0c433..e9bcf4c16b3 100755 --- a/test/cluster/sandbox/gke.py +++ b/test/cluster/sandbox/gke.py @@ -1,6 +1,6 @@ #!/usr/bin/env python -# Copyright 2017 Google Inc. +# 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. diff --git a/test/cluster/sandbox/initial_reparent.py b/test/cluster/sandbox/initial_reparent.py index 561eb0053c7..8ed555ff742 100755 --- a/test/cluster/sandbox/initial_reparent.py +++ b/test/cluster/sandbox/initial_reparent.py @@ -1,6 +1,6 @@ #!/usr/bin/env python -# Copyright 2017 Google Inc. +# 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. diff --git a/test/cluster/sandbox/kubernetes_components.py b/test/cluster/sandbox/kubernetes_components.py index 993891aa665..e67c4bf379c 100755 --- a/test/cluster/sandbox/kubernetes_components.py +++ b/test/cluster/sandbox/kubernetes_components.py @@ -1,6 +1,6 @@ #!/usr/bin/env python -# Copyright 2017 Google Inc. +# 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. diff --git a/test/cluster/sandbox/sandbox.py b/test/cluster/sandbox/sandbox.py index 26747a8a443..366a0eb5726 100755 --- a/test/cluster/sandbox/sandbox.py +++ b/test/cluster/sandbox/sandbox.py @@ -1,6 +1,6 @@ #!/usr/bin/env python -# Copyright 2017 Google Inc. +# 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. diff --git a/test/cluster/sandbox/sandbox_utils.py b/test/cluster/sandbox/sandbox_utils.py index 9002c768f7e..02f39f1fb52 100644 --- a/test/cluster/sandbox/sandbox_utils.py +++ b/test/cluster/sandbox/sandbox_utils.py @@ -1,4 +1,4 @@ -# Copyright 2017 Google Inc. +# 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. diff --git a/test/cluster/sandbox/sandlet.py b/test/cluster/sandbox/sandlet.py index d8e3b48da1d..107a090ec20 100644 --- a/test/cluster/sandbox/sandlet.py +++ b/test/cluster/sandbox/sandlet.py @@ -1,4 +1,4 @@ -# Copyright 2017 Google Inc. +# 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. diff --git a/test/cluster/sandbox/sandlet_test.py b/test/cluster/sandbox/sandlet_test.py index 1561314fd71..f8cf2d8ec87 100644 --- a/test/cluster/sandbox/sandlet_test.py +++ b/test/cluster/sandbox/sandlet_test.py @@ -1,4 +1,4 @@ -# Copyright 2017 Google Inc. +# 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. diff --git a/test/cluster/sandbox/subprocess_component.py b/test/cluster/sandbox/subprocess_component.py index 8a55c2a2232..744ce4b203c 100644 --- a/test/cluster/sandbox/subprocess_component.py +++ b/test/cluster/sandbox/subprocess_component.py @@ -1,4 +1,4 @@ -# Copyright 2017 Google Inc. +# 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. diff --git a/test/cluster/sandbox/vitess_kubernetes_sandbox.py b/test/cluster/sandbox/vitess_kubernetes_sandbox.py index 75fe1c8b21e..734f8d1ac46 100755 --- a/test/cluster/sandbox/vitess_kubernetes_sandbox.py +++ b/test/cluster/sandbox/vitess_kubernetes_sandbox.py @@ -1,6 +1,6 @@ #!/usr/bin/env python -# Copyright 2017 Google Inc. +# 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. diff --git a/test/cluster/sandbox/vtctl_sandbox.py b/test/cluster/sandbox/vtctl_sandbox.py index c813ac494b8..ef0f1d978ed 100755 --- a/test/cluster/sandbox/vtctl_sandbox.py +++ b/test/cluster/sandbox/vtctl_sandbox.py @@ -1,4 +1,4 @@ -# Copyright 2017 Google Inc. +# 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. diff --git a/test/cluster/sandbox/wait_for_mysql.py b/test/cluster/sandbox/wait_for_mysql.py index 9be3e8435c0..ed880afa36a 100755 --- a/test/cluster/sandbox/wait_for_mysql.py +++ b/test/cluster/sandbox/wait_for_mysql.py @@ -1,6 +1,6 @@ #!/usr/bin/env python -# Copyright 2017 Google Inc. +# 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. diff --git a/test/cluster/vtctl_helper.py b/test/cluster/vtctl_helper.py index 00a960a2d1e..4f72ee771cd 100644 --- a/test/cluster/vtctl_helper.py +++ b/test/cluster/vtctl_helper.py @@ -1,4 +1,4 @@ -# Copyright 2017 Google Inc. +# 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. diff --git a/test/config.json b/test/config.json index 93802fc4b0a..0974ba92c3f 100644 --- a/test/config.json +++ b/test/config.json @@ -216,6 +216,17 @@ "RetryMax": 0, "Tags": [] }, + "client_test": { + "File": "", + "Args": [], + "Command": [ + "test/client_test.sh" + ], + "Manual": false, + "Shard": 3, + "RetryMax": 0, + "Tags": [] + }, "merge_sharding": { "File": "merge_sharding.py", "Args": [], @@ -307,6 +318,15 @@ "RetryMax": 0, "Tags": [] }, + "recovery": { + "File": "recovery.py", + "Args": [], + "Command": [], + "Manual": false, + "Shard": 4, + "RetryMax": 0, + "Tags": [] + }, "reparent": { "File": "reparent.py", "Args": [], @@ -367,6 +387,15 @@ "RetryMax": 0, "Tags": [] }, + "sharded_recovery": { + "File": "sharded_recovery.py", + "Args": [], + "Command": [], + "Manual": false, + "Shard": 4, + "RetryMax": 0, + "Tags": [] + }, "tabletmanager": { "File": "tabletmanager.py", "Args": [], @@ -404,6 +433,29 @@ "site_test" ] }, + "endtoend": { + "File": "", + "Args": [], + "Command": [ + "tools/e2e_test_runner.sh" + ], + "Manual": false, + "Shard": 3, + "RetryMax": 0, + "Tags": [] + }, + "e2e_race": { + "File": "", + "Args": [], + "Command": [ + "make", + "e2e_test_race" + ], + "Manual": false, + "Shard": 1, + "RetryMax": 0, + "Tags": [] + }, "unit": { "File": "", "Args": [], @@ -411,7 +463,7 @@ "tools/unit_test_runner.sh" ], "Manual": false, - "Shard": 4, + "Shard": 0, "RetryMax": 0, "Tags": [] }, @@ -563,6 +615,15 @@ "RetryMax": 0, "Tags": [] }, + "xb_recovery": { + "File": "xb_recovery.py", + "Args": [], + "Command": [], + "Manual": false, + "Shard": 4, + "RetryMax": 0, + "Tags": [] + }, "xtrabackup_xbstream": { "File": "xtrabackup_xbstream.py", "Args": [], diff --git a/test/custom_sharding.py b/test/custom_sharding.py index b571e2f278c..a3197cbb2e5 100755 --- a/test/custom_sharding.py +++ b/test/custom_sharding.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright 2017 Google Inc. +# 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. diff --git a/test/encrypted_replication.py b/test/encrypted_replication.py index ff5d935c5bc..d7c61b2cca2 100755 --- a/test/encrypted_replication.py +++ b/test/encrypted_replication.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright 2017 Google Inc. +# 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. diff --git a/test/encrypted_transport.py b/test/encrypted_transport.py index e01f27213c4..28e6dbe3177 100755 --- a/test/encrypted_transport.py +++ b/test/encrypted_transport.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright 2017 Google Inc. +# 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. diff --git a/test/environment.py b/test/environment.py index 2319597bc07..ce3b58db683 100644 --- a/test/environment.py +++ b/test/environment.py @@ -1,6 +1,6 @@ #!/usr/bin/env python -# Copyright 2017 Google Inc. +# 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. diff --git a/test/grpc_protocols_flavor.py b/test/grpc_protocols_flavor.py index d9685f4453c..4ccd7dcabed 100644 --- a/test/grpc_protocols_flavor.py +++ b/test/grpc_protocols_flavor.py @@ -1,6 +1,6 @@ #!/usr/bin/env python -# Copyright 2017 Google Inc. +# 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. diff --git a/test/horizontal_resharding_workflow.py b/test/horizontal_resharding_workflow.py index 96c25e0fd0d..44a8741f8bf 100644 --- a/test/horizontal_resharding_workflow.py +++ b/test/horizontal_resharding_workflow.py @@ -1,4 +1,4 @@ -# Copyright 2017 Google Inc. +# 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. diff --git a/test/initial_sharding.py b/test/initial_sharding.py index 1213544b171..cd561f3bc73 100755 --- a/test/initial_sharding.py +++ b/test/initial_sharding.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright 2017 Google Inc. +# 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. diff --git a/test/initial_sharding_bytes.py b/test/initial_sharding_bytes.py index 48463f61443..6103372e7be 100755 --- a/test/initial_sharding_bytes.py +++ b/test/initial_sharding_bytes.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright 2017 Google Inc. +# 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. diff --git a/test/initial_sharding_multi.py b/test/initial_sharding_multi.py index 11c06c30aea..af0b167ed2d 100755 --- a/test/initial_sharding_multi.py +++ b/test/initial_sharding_multi.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright 2017 Google Inc. +# 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. diff --git a/test/initial_sharding_multi_split_diff.py b/test/initial_sharding_multi_split_diff.py index d21c41cf162..c214d98755c 100755 --- a/test/initial_sharding_multi_split_diff.py +++ b/test/initial_sharding_multi_split_diff.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright 2017 Google Inc. +# 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. diff --git a/test/keyrange_test.py b/test/keyrange_test.py index 2e8af76bb35..675607fb791 100755 --- a/test/keyrange_test.py +++ b/test/keyrange_test.py @@ -1,6 +1,6 @@ #!/usr/bin/env python -# Copyright 2017 Google Inc. +# 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. @@ -114,7 +114,6 @@ def test_bind_values_for_int_keyspace(self): else: self.assertNotEqual(where_clause.find('<'), -1) else: - self.assertNotEqual(where_clause.find('>='), -1) self.assertNotEqual(where_clause.find('>='), -1) self.assertNotEqual(where_clause.find('AND'), -1) kid_list = int_shard_kid_map[kr] @@ -145,7 +144,6 @@ def test_bind_values_for_str_keyspace(self): else: self.assertNotEqual(where_clause.find('<'), -1) else: - self.assertNotEqual(where_clause.find('>='), -1) self.assertNotEqual(where_clause.find('>='), -1) self.assertNotEqual(where_clause.find('AND'), -1) kid_list = str_shard_kid_map[kr] diff --git a/test/keyspace_test.py b/test/keyspace_test.py index 11535480141..bc35027adc2 100755 --- a/test/keyspace_test.py +++ b/test/keyspace_test.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright 2017 Google Inc. +# 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. diff --git a/test/keyspace_util.py b/test/keyspace_util.py index 52996fec6d0..d152937ca70 100644 --- a/test/keyspace_util.py +++ b/test/keyspace_util.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- # -# Copyright 2017 Google Inc. +# 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. diff --git a/test/legacy_resharding.py b/test/legacy_resharding.py index a145c5e2bb4..0bc84d27378 100755 --- a/test/legacy_resharding.py +++ b/test/legacy_resharding.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright 2017 Google Inc. +# 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. diff --git a/test/local_example.sh b/test/local_example.sh index 88d3ca5253e..f0ba0f4278b 100755 --- a/test/local_example.sh +++ b/test/local_example.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2017 Google Inc. +# 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. @@ -15,111 +15,51 @@ # limitations under the License. # This test runs through the scripts in examples/local to make sure they work. +# It should be kept in sync with the steps in https://vitess.io/docs/get-started/local/ +# So we can detect if a regression affecting a tutorial is introduced. -# timeout in seconds (for each step, not overall) -timeout=30 -export TOPO=zk2 +set -xe -cd $VTTOP/examples/local +cd "$VTTOP/examples/local" -exitcode=1 +./101_initial_cluster.sh -# Use a minimal number of tablets for the test. -# This helps with staying under CI resource limits. -num_tablets=2 -uid_base=100 -cell=test -TABLETS_UIDS="$(seq 0 $((num_tablets - 1)))" -export TABLETS_UIDS +mysql -h 127.0.0.1 -P 15306 < ../common/insert_commerce_data.sql +mysql -h 127.0.0.1 -P 15306 --table < ../common/select_commerce_data.sql +./201_customer_keyspace.sh +./202_customer_tablets.sh +./203_vertical_split.sh +mysql -h 127.0.0.1 -P 15306 --table < ../common/select_customer0_data.sql -teardown() { - ./vtgate-down.sh & - ./vttablet-down.sh "$TABLETS_UIDS" & - ./vtctld-down.sh & - ./zk-down.sh & - wait - exit $exitcode -} -trap teardown SIGTERM SIGINT EXIT +./204_vertical_migrate_replicas.sh +./205_vertical_migrate_master.sh +# Expected to fail! +mysql -h 127.0.0.1 -P 15306 --table < ../common/select_commerce_data.sql || echo "Blacklist working as expected" +./206_clean_commerce.sh +# Expected to fail! +mysql -h 127.0.0.1 -P 15306 --table < ../common/select_commerce_data.sql || echo "Tables missing as expected" -# Set up servers. -timeout $timeout ./zk-up.sh || teardown -timeout $timeout ./vtctld-up.sh || teardown -timeout $timeout ./vttablet-up.sh || teardown +./301_customer_sharded.sh +./302_new_shards.sh -# Retry loop function -retry_with_timeout() { - if [ `date +%s` -gt $[$start + $timeout] ]; then - echo "Timeout ($timeout) exceeded" - teardown - fi +# Wait for the schema to be targetable before proceeding +# TODO: Eliminate this race in the examples' scripts +for shard in "customer/-80" "customer/80-"; do + while true; do + mysql -h 127.0.0.1 -P 15306 "$shard" -e 'show tables' && break || echo "waiting for shard: $shard!" + sleep 1 + done; +done; - echo "Waiting 2 seconds to try again..." - sleep 2 -} +mysql -h 127.0.0.1 -P 15306 --table < ../common/select_customer-80_data.sql +mysql -h 127.0.0.1 -P 15306 --table < ../common/select_customer80-_data.sql -# Wait for vttablets to show up in topology. -# If we don't do this, then vtgate might take up to a minute -# to notice the new tablets, which is normally fine, but not -# when we're trying to get through the test ASAP. -echo "Waiting for $num_tablets tablets to appear in topology..." -start=`date +%s` -until [[ $(./lvtctl.sh ListAllTablets test | wc -l) -eq $num_tablets ]]; do - retry_with_timeout -done +./303_horizontal_split.sh -timeout $timeout ./vtgate-up.sh || teardown +./304_migrate_replicas.sh +./305_migrate_master.sh -echo "Initialize shard..." -start=`date +%s` -until ./lvtctl.sh InitShardMaster -force test_keyspace/0 test-100; do - retry_with_timeout -done +mysql -h 127.0.0.1 -P 15306 --table < ../common/select_customer-80_data.sql -# Run manual health check on each tablet. -# This is not necessary, but it helps make this test more representative of -# what a human would do. It simulates the case where a periodic health check -# occurs before the user gets around to running the next command. For example, -# in that case the health check will make the tablet begin serving prior to the -# ApplySchema command below. Otherwise, ApplySchema races with the periodic -# health check. -echo "Running health check on tablets..." -start=`date +%s` -for uid_index in $TABLETS_UIDS; do - uid=$[$uid_base + $uid_index] - printf -v alias '%s-%010d' $cell $uid - ./lvtctl.sh RunHealthCheck $alias -done +./401_teardown.sh -echo "Create table..." -start=`date +%s` -until ./lvtctl.sh ApplySchema -sql "$(cat create_test_table.sql)" test_keyspace; do - retry_with_timeout -done - -echo "Rebuild vschema..." -start=`date +%s` -until ./lvtctl.sh RebuildVSchemaGraph; do - retry_with_timeout -done - -echo "Run Python client script..." -# Retry until vtgate is ready. -start=`date +%s` -# Test that the client.sh script works with no --server arg, -# because that's how the tutorial says to run it. -until ./client.sh ; do - retry_with_timeout -done - -echo "Run Go client script..." -go run client.go -server=localhost:15991 || teardown - -echo "Run Java client script..." -./client_java.sh || teardown - -echo "Run JDBC client script..." -./client_jdbc.sh || teardown - -exitcode=0 -teardown diff --git a/test/merge_sharding.py b/test/merge_sharding.py index 8a424b4bd0c..f733ce30454 100755 --- a/test/merge_sharding.py +++ b/test/merge_sharding.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright 2017 Google Inc. +# 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. diff --git a/test/merge_sharding_bytes.py b/test/merge_sharding_bytes.py index 1a786f7d16f..6fc6dc9e99e 100755 --- a/test/merge_sharding_bytes.py +++ b/test/merge_sharding_bytes.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright 2017 Google Inc. +# 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. diff --git a/test/messaging.py b/test/messaging.py index 37dfb0bd6f9..31d46faed5c 100755 --- a/test/messaging.py +++ b/test/messaging.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # coding: utf-8 -# Copyright 2017 Google Inc. +# 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. diff --git a/test/mysql_flavor.py b/test/mysql_flavor.py index a0be7b1289a..9cf057982ea 100644 --- a/test/mysql_flavor.py +++ b/test/mysql_flavor.py @@ -1,4 +1,4 @@ -# Copyright 2017 Google Inc. +# 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. @@ -126,7 +126,7 @@ def reset_replication_commands(self): ] def extra_my_cnf(self): - return environment.vttop + "/config/mycnf/master_mariadb.cnf" + return environment.vttop + "/config/mycnf/master_mariadb100.cnf" def master_position(self, tablet): gtid = tablet.mquery("", "SELECT @@GLOBAL.gtid_binlog_pos")[0][0] @@ -228,10 +228,10 @@ def set_mysql_flavor(flavor): global MYSQL_FLAVOR if not flavor: - flavor = os.environ.get("MYSQL_FLAVOR", "MariaDB") + flavor = os.environ.get("MYSQL_FLAVOR", "MySQL56") # The environment variable might be set, but equal to "". if not flavor: - flavor = "MariaDB" + flavor = "MySQL56" v = flavor_map.get(flavor, None) if not v: diff --git a/test/mysql_server_test.py b/test/mysql_server_test.py index d65380133ba..729a519bde2 100755 --- a/test/mysql_server_test.py +++ b/test/mysql_server_test.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright 2017 Google Inc. +# 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. diff --git a/test/mysqlctl.py b/test/mysqlctl.py index 887f4cc6a74..43ec926176a 100755 --- a/test/mysqlctl.py +++ b/test/mysqlctl.py @@ -1,6 +1,6 @@ #!/usr/bin/env python -# Copyright 2017 Google Inc. +# 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. diff --git a/test/prepared_statement_test.py b/test/prepared_statement_test.py index 963f2550c6f..475b8dfa84d 100755 --- a/test/prepared_statement_test.py +++ b/test/prepared_statement_test.py @@ -14,7 +14,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -"""Ensures the vtgate MySQL server protocol plugin works as expected with prepared statments. +"""Ensures the vtgate MySQL server protocol plugin works as expected with prepared statements. We use table ACLs to verify the user name authenticated by the connector is set properly. @@ -51,7 +51,7 @@ "options": [ "New York Bulls", "Los Angeles Kings", - "Golden State Warriros", + "Golden State Warriors", "Huston Rocket" ], "answer": "Huston Rocket" @@ -213,7 +213,8 @@ def test_prepared_statements(self): utils.VtGate(mysql_server=True).start( extra_args=['-mysql_auth_server_impl', 'static', '-mysql_server_query_timeout', '1s', - '-mysql_auth_server_static_file', mysql_auth_server_static]) + '-mysql_auth_server_static_file', mysql_auth_server_static, + "-mysql_server_version", '8.0.16-7']) # We use gethostbyname('localhost') so we don't presume # of the IP format (travis is only IP v4, really). params = dict(host=socket.gethostbyname('localhost'), @@ -255,6 +256,16 @@ def test_prepared_statements(self): cursor.fetchone() cursor.close() + # Send an invalid table name to ensure that python's mysql client will not fail before entering vtgate + cursor = conn.cursor(cursor_class=MySQLCursorPrepared) + try: + cursor.execute('select * from prepare_stmt_test where id = %s', (1,)) + except mysql.connector.Error as err: + if err.errno == 1105: + print "Could not find the table" + else: + raise + cursor = conn.cursor(cursor_class=MySQLCursorPrepared) cursor.execute('select * from vt_prepare_stmt_test where id = %s', (1,)) result = cursor.fetchall() @@ -296,6 +307,15 @@ def test_prepared_statements(self): if res[0] != 1: self.fail("Delete failed") cursor.close() - + + # resetting the connection + conn.cmd_reset_connection() + cursor = conn.cursor(cursor_class=MySQLCursorPrepared) + cursor.execute('select * from vt_prepare_stmt_test where id = %s', (1,)) + result = cursor.fetchone() + # Should fail since we cleared PreparedData inside the connection + with self.assertRaises(TypeError): + empty_val = result[-2] + if __name__ == '__main__': utils.main() diff --git a/test/protocols_flavor.py b/test/protocols_flavor.py index 4af6457c8f6..b4a32eef560 100644 --- a/test/protocols_flavor.py +++ b/test/protocols_flavor.py @@ -1,6 +1,6 @@ #!/usr/bin/env python -# Copyright 2017 Google Inc. +# 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. diff --git a/test/python_client_test.py b/test/python_client_test.py index 02299521dbf..820902694b3 100755 --- a/test/python_client_test.py +++ b/test/python_client_test.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright 2017 Google Inc. +# 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. diff --git a/test/recovery.py b/test/recovery.py new file mode 100755 index 00000000000..a319e5c7de8 --- /dev/null +++ b/test/recovery.py @@ -0,0 +1,534 @@ +#!/usr/bin/env python + +# 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. + +from datetime import datetime +import json +import logging +import os +import unittest + +import MySQLdb + +import environment +import tablet +import utils + +from mysql_flavor import mysql_flavor +from vtdb import vtgate_client + +use_xtrabackup = False +xtrabackup_args = [] +stream_mode = 'xbstream' + +# tablets +tablet_master = tablet.Tablet() +tablet_replica1 = tablet.Tablet() +tablet_replica2 = tablet.Tablet() +tablet_replica3 = tablet.Tablet() + +all_tablets = [tablet_master, tablet_replica1, tablet_replica2, tablet_replica3] + +def setUpModule(): + global xtrabackup_args + xtrabackup_args = ['-backup_engine_implementation', + 'xtrabackup', + '-xtrabackup_stream_mode', + stream_mode, + '-xtrabackup_user=vt_dba'] + try: + environment.topo_server().setup() + setup_procs = [t.init_mysql() for t in all_tablets] + utils.wait_procs(setup_procs) + except: + tearDownModule() + raise + +def tearDownModule(): + utils.required_teardown() + if utils.options.skip_teardown: + return + teardown_procs = [t.teardown_mysql() for t in all_tablets] + utils.wait_procs(teardown_procs, raise_on_error=False) + environment.topo_server().teardown() + utils.kill_sub_processes() + utils.remove_tmp_files() + for t in all_tablets: + t.remove_tree() + +def get_connection(timeout=15.0): + protocol, endpoint = utils.vtgate.rpc_endpoint(python=True) + try: + return vtgate_client.connect(protocol, endpoint, timeout) + except Exception: + logging.exception('Connection to vtgate (timeout=%s) failed.', timeout) + raise + +class TestRecovery(unittest.TestCase): + + def setUp(self): + xtra_args = ['-enable_replication_reporter'] + if use_xtrabackup: + xtra_args.extend(xtrabackup_args) + tablet_master.init_tablet('replica', 'test_keyspace', '0', start=True, + supports_backups=True, + extra_args=xtra_args) + tablet_replica1.init_tablet('replica', 'test_keyspace', '0', start=True, + supports_backups=True, + extra_args=xtra_args) + utils.run_vtctl(['InitShardMaster', '-force', 'test_keyspace/0', + tablet_master.tablet_alias]) + + def tearDown(self): + for t in all_tablets: + t.kill_vttablet() + + tablet.Tablet.check_vttablet_count() + environment.topo_server().wipe() + for t in all_tablets: + t.reset_replication() + t.set_semi_sync_enabled(master=False, slave=False) + t.clean_dbs() + + for backup in self._list_backups(): + self._remove_backup(backup) + + _create_vt_insert_test = '''create table vt_insert_test ( + id bigint auto_increment, + msg varchar(64), + primary key (id) + ) Engine=InnoDB''' + + _vschema_json = '''{ + "tables": { + "vt_insert_test": {} + } +}''' + + + def _insert_data(self, t, index): + """Add a single row with value 'index' to the given tablet.""" + t.mquery( + 'vt_test_keyspace', + "insert into vt_insert_test (msg) values ('test %s')" % + index, write=True) + + def _check_data(self, t, count, msg): + """Check that the specified tablet has the expected number of rows.""" + timeout = 10 + while True: + try: + result = t.mquery( + 'vt_test_keyspace', 'select count(*) from vt_insert_test') + if result[0][0] == count: + break + except MySQLdb.DatabaseError: + # ignore exceptions, we'll just timeout (the tablet creation + # can take some time to replicate, and we get a 'table vt_insert_test + # does not exist exception in some rare cases) + logging.exception('exception waiting for data to replicate') + timeout = utils.wait_step(msg, timeout) + + def _restore(self, t, keyspace): + """Erase mysql/tablet dir, then start tablet with restore enabled.""" + self._reset_tablet_dir(t) + + # create a recovery keyspace + utils.run_vtctl(['CreateKeyspace', + '-keyspace_type=SNAPSHOT', + '-base_keyspace=test_keyspace', + '-snapshot_time', + datetime.utcnow().isoformat("T")+"Z", + keyspace]) + # set disable_active_reparents to true and enable_replication_reporter to false + # otherwise replication_reporter will try to restart replication + xtra_args = ['-disable_active_reparents', + '-enable_replication_reporter=false'] + xtra_args.extend(tablet.get_backup_storage_flags()) + if use_xtrabackup: + xtra_args.extend(xtrabackup_args) + + t.start_vttablet(wait_for_state='SERVING', + init_tablet_type='replica', + init_keyspace=keyspace, + init_shard='0', + supports_backups=True, + extra_args=xtra_args) + + def _reset_tablet_dir(self, t): + """Stop mysql, delete everything including tablet dir, restart mysql.""" + utils.wait_procs([t.teardown_mysql()]) + # Specify ignore_options because we want to delete the tree even + # if the test's -k / --keep-logs was specified on the command line. + t.remove_tree(ignore_options=True) + proc = t.init_mysql() + utils.wait_procs([proc]) + + def _list_backups(self): + """Get a list of backup names for the test shard.""" + backups, _ = utils.run_vtctl(tablet.get_backup_storage_flags() + + ['ListBackups', 'test_keyspace/0'], + mode=utils.VTCTL_VTCTL, trap_output=True) + return backups.splitlines() + + def _remove_backup(self, backup): + """Remove a named backup from the test shard.""" + utils.run_vtctl( + tablet.get_backup_storage_flags() + + ['RemoveBackup', 'test_keyspace/0', backup], + auto_log=True, mode=utils.VTCTL_VTCTL) + + def test_basic_recovery(self): + """Test recovery from backup flow. + + test_recovery will: + - create a shard with master and replica1 only + - run InitShardMaster + - insert some data + - take a backup + - insert more data on the master + - create a recovery keyspace + - bring up tablet_replica2 in the new keyspace + - check that new tablet does not have data created after backup + - check that vtgate queries work correctly + + """ + + # insert data on master, wait for replica to get it + utils.run_vtctl(['ApplySchema', + '-sql', self._create_vt_insert_test, + 'test_keyspace'], + auto_log=True) + self._insert_data(tablet_master, 1) + self._check_data(tablet_replica1, 1, 'replica1 tablet getting data') + + master_pos = mysql_flavor().master_position(tablet_master) + # backup the replica + utils.run_vtctl(['Backup', tablet_replica1.tablet_alias], auto_log=True) + + # check that the backup shows up in the listing + backups = self._list_backups() + logging.debug('list of backups: %s', backups) + self.assertEqual(len(backups), 1) + self.assertTrue(backups[0].endswith(tablet_replica1.tablet_alias)) + # backup name is of format date.time.tablet_alias + strs = backups[0].split('.') + expectedTime = datetime.strptime(strs[0] + '.' + strs[1], '%Y-%m-%d.%H%M%S') + + # insert more data on the master + self._insert_data(tablet_master, 2) + + utils.run_vtctl(['ApplyVSchema', + '-vschema', self._vschema_json, + 'test_keyspace'], + auto_log=True) + + vs = utils.run_vtctl_json(['GetVSchema', 'test_keyspace']) + logging.debug('test_keyspace vschema: %s', str(vs)) + ks = utils.run_vtctl_json(['GetSrvKeyspace', 'test_nj', 'test_keyspace']) + logging.debug('Serving keyspace before: %s', str(ks)) + vs = utils.run_vtctl_json(['GetSrvVSchema', 'test_nj']) + logging.debug('Serving vschema before recovery: %s', str(vs)) + + # now bring up the recovery keyspace with 1 tablet, letting it restore from backup. + self._restore(tablet_replica2, 'recovery_keyspace') + + vs = utils.run_vtctl_json(['GetSrvVSchema', 'test_nj']) + logging.debug('Serving vschema after recovery: %s', str(vs)) + ks = utils.run_vtctl_json(['GetSrvKeyspace', 'test_nj', 'test_keyspace']) + logging.debug('Serving keyspace after: %s', str(ks)) + vs = utils.run_vtctl_json(['GetVSchema', 'recovery_keyspace']) + logging.debug('recovery_keyspace vschema: %s', str(vs)) + + # check the new replica has only 1 row + self._check_data(tablet_replica2, 1, 'replica2 tablet should not have new data') + + # check that the restored replica has the right local_metadata + result = tablet_replica2.mquery('_vt', 'select * from local_metadata') + metadata = {} + for row in result: + metadata[row[0]] = row[1] + self.assertEqual(metadata['Alias'], 'test_nj-0000062346') + self.assertEqual(metadata['ClusterAlias'], 'recovery_keyspace.0') + self.assertEqual(metadata['DataCenter'], 'test_nj') + self.assertEqual(metadata['RestorePosition'], master_pos) + logging.debug('RestoredBackupTime: %s', str(metadata['RestoredBackupTime'])) + gotTime = datetime.strptime(metadata['RestoredBackupTime'], '%Y-%m-%dT%H:%M:%SZ') + self.assertEqual(gotTime, expectedTime) + + # update original 1st row in master + tablet_master.mquery( + 'vt_test_keyspace', + "update vt_insert_test set msg='new msg' where id=1", write=True) + + # verify that master has new value + result = tablet_master.mquery('vt_test_keyspace', 'select msg from vt_insert_test where id=1') + self.assertEqual(result[0][0], 'new msg') + + # verify that restored replica has old value + result = tablet_replica2.mquery('vt_test_keyspace', 'select msg from vt_insert_test where id=1') + self.assertEqual(result[0][0], 'test 1') + + # start vtgate + vtgate = utils.VtGate() + vtgate.start(tablets=[ + tablet_master, tablet_replica1, tablet_replica2 + ], tablet_types_to_wait='REPLICA') + utils.vtgate.wait_for_endpoints('test_keyspace.0.master', 1) + utils.vtgate.wait_for_endpoints('test_keyspace.0.replica', 1) + utils.vtgate.wait_for_endpoints('recovery_keyspace.0.replica', 1) + + # check that vtgate doesn't route queries to new tablet + vtgate_conn = get_connection() + cursor = vtgate_conn.cursor( + tablet_type='replica', keyspace=None, writable=True) + + cursor.execute('select count(*) from vt_insert_test', {}) + result = cursor.fetchall() + if not result: + self.fail('Result cannot be null') + else: + self.assertEqual(result[0][0], 2) + + cursor.execute('select msg from vt_insert_test where id=1', {}) + result = cursor.fetchall() + if not result: + self.fail('Result cannot be null') + else: + self.assertEqual(result[0][0], 'new msg') + + # check that new keyspace is accessible by using ks.table + cursor.execute('select count(*) from recovery_keyspace.vt_insert_test', {}) + result = cursor.fetchall() + if not result: + self.fail('Result cannot be null') + else: + self.assertEqual(result[0][0], 1) + + cursor.execute('select msg from recovery_keyspace.vt_insert_test where id=1', {}) + result = cursor.fetchall() + if not result: + self.fail('Result cannot be null') + else: + self.assertEqual(result[0][0], 'test 1') + + # check that new keyspace is accessible with 'use ks' + cursor.execute('use recovery_keyspace@replica', {}) + cursor.execute('select count(*) from vt_insert_test', {}) + result = cursor.fetchall() + if not result: + self.fail('Result cannot be null') + else: + self.assertEqual(result[0][0], 1) + + cursor.execute('select msg from recovery_keyspace.vt_insert_test where id=1', {}) + result = cursor.fetchall() + if not result: + self.fail('Result cannot be null') + else: + self.assertEqual(result[0][0], 'test 1') + + # TODO check that new tablet is accessible with 'use ks:shard' + # this currently does not work through the python client, though it works from mysql client + #cursor.execute('use recovery_keyspace:0@replica', {}) + #cursor.execute('select count(*) from vt_insert_test', {}) + #result = cursor.fetchall() + #if not result: + #self.fail('Result cannot be null') + #else: + #self.assertEqual(result[0][0], 1) + + vtgate_conn.close() + tablet_replica2.kill_vttablet() + vtgate.kill() + + def test_multi_recovery(self): + """Test recovery from backup flow. + + test_multi_recovery will: + - create a shard with master and replica1 only + - run InitShardMaster + - insert some data + - take a backup + - insert more data on the master + - take another backup + - create a recovery keyspace after first backup + - bring up tablet_replica2 in the new keyspace + - check that new tablet does not have data created after backup1 + - create second recovery keyspace after second backup + - bring up tablet_replica3 in second keyspace + - check that new tablet has data created after backup1 but not data created after backup2 + - check that vtgate queries work correctly + + """ + + # insert data on master, wait for replica to get it + utils.run_vtctl(['ApplySchema', + '-sql', self._create_vt_insert_test, + 'test_keyspace'], + auto_log=True) + self._insert_data(tablet_master, 1) + self._check_data(tablet_replica1, 1, 'replica1 tablet getting data') + + # backup the replica + utils.run_vtctl(['Backup', tablet_replica1.tablet_alias], auto_log=True) + + # check that the backup shows up in the listing + backups = self._list_backups() + logging.debug('list of backups: %s', backups) + self.assertEqual(len(backups), 1) + self.assertTrue(backups[0].endswith(tablet_replica1.tablet_alias)) + + # insert more data on the master + self._insert_data(tablet_master, 2) + # wait for it to replicate + self._check_data(tablet_replica1, 2, 'replica1 tablet getting data') + + utils.run_vtctl(['ApplyVSchema', + '-vschema', self._vschema_json, + 'test_keyspace'], + auto_log=True) + + vs = utils.run_vtctl_json(['GetVSchema', 'test_keyspace']) + logging.debug('test_keyspace vschema: %s', str(vs)) + + # now bring up the other replica, letting it restore from backup. + self._restore(tablet_replica2, 'recovery_ks1') + + # we are not asserting on the contents of vschema here + # because the later part of the test (vtgate) will fail + # if the vschema is not copied correctly from the base_keyspace + vs = utils.run_vtctl_json(['GetVSchema', 'recovery_ks1']) + logging.debug('recovery_ks1 vschema: %s', str(vs)) + + # check the new replica does not have the data + self._check_data(tablet_replica2, 1, 'replica2 tablet should not have new data') + + # update original 1st row in master + tablet_master.mquery( + 'vt_test_keyspace', + "update vt_insert_test set msg='new msg 1' where id=1", write=True) + + # verify that master has new value + result = tablet_master.mquery('vt_test_keyspace', 'select msg from vt_insert_test where id=1') + self.assertEqual(result[0][0], 'new msg 1') + + # verify that restored replica has old value + result = tablet_replica2.mquery('vt_test_keyspace', 'select msg from vt_insert_test where id=1') + self.assertEqual(result[0][0], 'test 1') + + # take another backup on the replica + utils.run_vtctl(['Backup', tablet_replica1.tablet_alias], auto_log=True) + + # insert more data on the master + self._insert_data(tablet_master, 3) + # wait for it to replicate + self._check_data(tablet_replica1, 3, 'replica1 tablet getting data') + + # now bring up the other replica, letting it restore from backup2. + # this also validates that if there are multiple backups, the most recent one is used + self._restore(tablet_replica3, 'recovery_ks2') + + vs = utils.run_vtctl(['GetVSchema', 'recovery_ks2']) + logging.debug('recovery_ks2 vschema: %s', str(vs)) + + # check the new replica does not have the latest data + self._check_data(tablet_replica3, 2, 'replica3 tablet should not have new data') + + # update original 1st row in master again + tablet_master.mquery( + 'vt_test_keyspace', + "update vt_insert_test set msg='new msg 2' where id=1", write=True) + + # verify that master has new value + result = tablet_master.mquery('vt_test_keyspace', 'select msg from vt_insert_test where id=1') + self.assertEqual(result[0][0], 'new msg 2') + + # verify that restored replica has correct value + result = tablet_replica3.mquery('vt_test_keyspace', 'select msg from vt_insert_test where id=1') + self.assertEqual(result[0][0], 'new msg 1') + + # start vtgate + vtgate = utils.VtGate() + vtgate.start(tablets=all_tablets, tablet_types_to_wait='REPLICA') + utils.vtgate.wait_for_endpoints('test_keyspace.0.master', 1) + utils.vtgate.wait_for_endpoints('test_keyspace.0.replica', 1) + utils.vtgate.wait_for_endpoints('recovery_ks1.0.replica', 1) + utils.vtgate.wait_for_endpoints('recovery_ks2.0.replica', 1) + + # check that vtgate doesn't route queries to new tablet + vtgate_conn = get_connection() + cursor = vtgate_conn.cursor( + tablet_type='replica', keyspace=None, writable=True) + + cursor.execute('select count(*) from vt_insert_test', {}) + result = cursor.fetchall() + if not result: + self.fail('Result cannot be null') + else: + self.assertEqual(result[0][0], 3) + + cursor.execute('select msg from vt_insert_test where id=1', {}) + result = cursor.fetchall() + if not result: + self.fail('Result cannot be null') + else: + self.assertEqual(result[0][0], 'new msg 2') + + # check that new keyspace is accessible by using ks.table + cursor.execute('select count(*) from recovery_ks1.vt_insert_test', {}) + result = cursor.fetchall() + if not result: + self.fail('Result cannot be null') + else: + self.assertEqual(result[0][0], 1) + + cursor.execute('select msg from recovery_ks1.vt_insert_test where id=1', {}) + result = cursor.fetchall() + if not result: + self.fail('Result cannot be null') + else: + self.assertEqual(result[0][0], 'test 1') + + # check that new keyspace is accessible by using ks.table + cursor.execute('select count(*) from recovery_ks2.vt_insert_test', {}) + result = cursor.fetchall() + if not result: + self.fail('Result cannot be null') + else: + self.assertEqual(result[0][0], 2) + + cursor.execute('select msg from recovery_ks2.vt_insert_test where id=1', {}) + result = cursor.fetchall() + if not result: + self.fail('Result cannot be null') + else: + self.assertEqual(result[0][0], 'new msg 1') + + # TODO check that new tablet is accessible with 'use ks:shard' + # this currently does not work through the python client, though it works from mysql client + #cursor.execute('use recovery_ks1:0@replica', {}) + #cursor.execute('select count(*) from vt_insert_test', {}) + #result = cursor.fetchall() + #if not result: + #self.fail('Result cannot be null') + #else: + #self.assertEqual(result[0][0], 1) + + vtgate_conn.close() + vtgate.kill() + +if __name__ == '__main__': + utils.main() diff --git a/test/reparent.py b/test/reparent.py index f8729b7069a..9f883ffdfac 100755 --- a/test/reparent.py +++ b/test/reparent.py @@ -1,6 +1,6 @@ #!/usr/bin/env python -# Copyright 2017 Google Inc. +# 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. @@ -177,7 +177,7 @@ def test_reparent_down_master(self): '-keyspace_shard', 'test_keyspace/0', '-new_master', tablet_62044.tablet_alias], expect_fail=True) - self.assertIn('DemoteMaster failed', stderr) + self.assertIn('current master must be healthy to perform planned reparent', stderr) # Run forced reparent operation, this should now proceed unimpeded. utils.run_vtctl(['EmergencyReparentShard', @@ -255,7 +255,13 @@ def test_reparent_graceful(self): utils.run_vtctl(['CreateKeyspace', 'test_keyspace']) self._test_reparent_graceful('0') - def _test_reparent_graceful(self, shard_id): + def test_reparent_graceful_recovery(self): + # Test that PRS can perform a graceful recovery + # as long as all tablets are responding. + utils.run_vtctl(['CreateKeyspace', 'test_keyspace']) + self._test_reparent_graceful('0', confused_master=True) + + def _test_reparent_graceful(self, shard_id, confused_master=False): # create the database so vttablets start, as they are serving tablet_62344.create_db('vt_test_keyspace') tablet_62044.create_db('vt_test_keyspace') @@ -300,6 +306,20 @@ def _test_reparent_graceful(self, shard_id): '-new_master', tablet_62044.tablet_alias], auto_log=True) utils.validate_topology() + if confused_master: + # Simulate a master that forgets it's master and becomes replica. + # PRS should be able to recover by reparenting to the same master again, + # as long as all tablets are available to check that it's safe. + tablet_62044.init_tablet('replica', 'test_keyspace', shard_id, start=False) + utils.run_vtctl(['RefreshState', tablet_62044.tablet_alias]) + + # Perform a graceful reparent to the same master. + # It should be idempotent, and should fix any inconsistencies if necessary. + utils.run_vtctl(['PlannedReparentShard', + '-keyspace_shard', 'test_keyspace/' + shard_id, + '-new_master', tablet_62044.tablet_alias], auto_log=True) + utils.validate_topology() + self._check_master_tablet(tablet_62044) # insert data into the new master, check the connected slaves work @@ -621,10 +641,10 @@ def test_reparent_with_down_slave(self, shard_id='0'): utils.pause('check orphan') - # reparent the tablet (will not start replication, so we have to - # do it ourselves), then it should catch up on replication really quickly - utils.run_vtctl(['ReparentTablet', tablet_41983.tablet_alias]) - utils.run_vtctl(['StartSlave', tablet_41983.tablet_alias]) + # Use the same PlannedReparentShard command to fix up the tablet. + utils.run_vtctl(['PlannedReparentShard', + '-keyspace_shard', 'test_keyspace/' + shard_id, + '-new_master', tablet_62044.tablet_alias]) # wait until it gets the data self._check_vt_insert_test(tablet_41983, 3) @@ -754,7 +774,7 @@ def test_reparent_doesnt_hang_if_master_fails(self): '-keyspace_shard', 'test_keyspace/0', '-new_master', tablet_62044.tablet_alias], expect_fail=True) - self.assertIn('master failed to PopulateReparentJournal, canceling slaves', + self.assertIn('master failed to PopulateReparentJournal', stderr) # Clean up the tablets. diff --git a/test/resharding.py b/test/resharding.py index 4bc50021cff..1ecfcba5ee1 100755 --- a/test/resharding.py +++ b/test/resharding.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright 2017 Google Inc. +# 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. diff --git a/test/resharding_bytes.py b/test/resharding_bytes.py index 74189faecd2..4fccf92d177 100755 --- a/test/resharding_bytes.py +++ b/test/resharding_bytes.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright 2017 Google Inc. +# 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. diff --git a/test/resharding_multi_split_diff.py b/test/resharding_multi_split_diff.py index 64413128816..e4ce4169b12 100755 --- a/test/resharding_multi_split_diff.py +++ b/test/resharding_multi_split_diff.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright 2017 Google Inc. +# 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. diff --git a/test/resharding_rbr.py b/test/resharding_rbr.py index f0f4d76f117..a2037168ab1 100755 --- a/test/resharding_rbr.py +++ b/test/resharding_rbr.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright 2017 Google Inc. +# 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. diff --git a/test/schema.py b/test/schema.py index d7fc2f4994d..fc1781b646a 100755 --- a/test/schema.py +++ b/test/schema.py @@ -1,6 +1,6 @@ #!/usr/bin/env python -# Copyright 2017 Google Inc. +# 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. diff --git a/test/schema_swap_test.py b/test/schema_swap_test.py index c94b81a2c97..edf381ef6f9 100755 --- a/test/schema_swap_test.py +++ b/test/schema_swap_test.py @@ -1,6 +1,6 @@ #!/usr/bin/env python -# Copyright 2017 Google Inc. +# 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. diff --git a/test/sharded.py b/test/sharded.py index 83af888c82a..280b0ed688a 100755 --- a/test/sharded.py +++ b/test/sharded.py @@ -1,6 +1,6 @@ #!/usr/bin/env python -# Copyright 2017 Google Inc. +# 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. diff --git a/test/sharded_recovery.py b/test/sharded_recovery.py new file mode 100755 index 00000000000..26c93cb3693 --- /dev/null +++ b/test/sharded_recovery.py @@ -0,0 +1,648 @@ +#!/usr/bin/env python + +# 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. + +import datetime +import json +import logging +import os +import unittest + +import MySQLdb + +import environment +import tablet +import utils + +from vtdb import vtgate_client + +# initial shard, covers everything +tablet_master = tablet.Tablet() +tablet_replica1 = tablet.Tablet() +tablet_rdonly = tablet.Tablet() +# to use for recovery keyspace +tablet_replica2 = tablet.Tablet() +tablet_replica3 = tablet.Tablet() + +# split shards +# range '' - 80 +shard_0_master = tablet.Tablet() +shard_0_replica = tablet.Tablet() +shard_0_rdonly = tablet.Tablet() +# range 80 - '' +shard_1_master = tablet.Tablet() +shard_1_replica = tablet.Tablet() +shard_1_rdonly = tablet.Tablet() + +all_tablets = [tablet_master, tablet_replica1, tablet_replica2, tablet_replica3, tablet_rdonly, + shard_0_master, shard_0_replica, shard_0_rdonly, shard_1_master, shard_1_replica, shard_1_rdonly] + +def setUpModule(): + try: + environment.topo_server().setup() + setup_procs = [t.init_mysql() for t in all_tablets] + utils.wait_procs(setup_procs) + except: + tearDownModule() + raise + +def tearDownModule(): + utils.required_teardown() + if utils.options.skip_teardown: + return + teardown_procs = [t.teardown_mysql() for t in all_tablets] + utils.wait_procs(teardown_procs, raise_on_error=False) + environment.topo_server().teardown() + utils.kill_sub_processes() + utils.remove_tmp_files() + for t in all_tablets: + t.remove_tree() + +def get_connection(timeout=15.0): + protocol, endpoint = utils.vtgate.rpc_endpoint(python=True) + try: + return vtgate_client.connect(protocol, endpoint, timeout) + except Exception: + logging.exception('Connection to vtgate (timeout=%s) failed.', timeout) + raise + +class TestShardedRecovery(unittest.TestCase): + + def setUp(self): + xtra_args = ['-enable_replication_reporter'] + tablet_master.init_tablet('replica', 'test_keyspace', '0', start=True, + supports_backups=True, + extra_args=xtra_args) + tablet_replica1.init_tablet('replica', 'test_keyspace', '0', start=True, + supports_backups=True, + extra_args=xtra_args) + tablet_rdonly.init_tablet('rdonly', 'test_keyspace', '0', start=True, + supports_backups=True, + extra_args=xtra_args) + utils.run_vtctl(['InitShardMaster', '-force', 'test_keyspace/0', + tablet_master.tablet_alias]) + + def tearDown(self): + for t in all_tablets: + t.kill_vttablet() + + tablet.Tablet.check_vttablet_count() + environment.topo_server().wipe() + for t in all_tablets: + t.reset_replication() + t.set_semi_sync_enabled(master=False, slave=False) + t.clean_dbs() + + for shard in ['0', '-80', '80-']: + for backup in self._list_backups(shard): + self._remove_backup(backup, shard) + + _create_vt_insert_test = '''create table vt_insert_test ( + id bigint, + msg varchar(64), + primary key (id) + ) Engine=InnoDB''' + + _vschema_json = '''{ + "sharded": true, + "vindexes": { + "hash": { + "type": "hash" + } + }, + "tables": { + "vt_insert_test": { + "column_vindexes": [ + { + "column": "id", + "name": "hash" + } + ] + } + } +}''' + + def _insert_data(self, t, index): + """Add a single row with value 'index' to the given tablet.""" + t.mquery( + 'vt_test_keyspace', + "insert into vt_insert_test (id, msg) values (%d, 'test %s')" % + (index, index), write=True) + + def _check_data(self, t, count, msg): + """Check that the specified tablet has the expected number of rows.""" + timeout = 10 + while True: + try: + result = t.mquery( + 'vt_test_keyspace', 'select count(*) from vt_insert_test') + if result[0][0] == count: + break + except MySQLdb.DatabaseError: + # ignore exceptions, we'll just timeout (the tablet creation + # can take some time to replicate, and we get a 'table vt_insert_test + # does not exist exception in some rare cases) + logging.exception('exception waiting for data to replicate') + timeout = utils.wait_step(msg, timeout) + + def _restore(self, t, keyspace, shard): + """Erase mysql/tablet dir, then start tablet with restore enabled.""" + self._reset_tablet_dir(t) + + # create a recovery keyspace + utils.run_vtctl(['CreateKeyspace', + '-keyspace_type=SNAPSHOT', + '-base_keyspace=test_keyspace', + '-snapshot_time', + datetime.datetime.utcnow().isoformat("T")+"Z", + keyspace]) + + # set disable_active_reparents to true and enable_replication_reporter to false + # otherwise replication_reporter will try to restart replication + xtra_args = ['-disable_active_reparents', + '-enable_replication_reporter=false'] + xtra_args.extend(tablet.get_backup_storage_flags()) + t.start_vttablet(wait_for_state='SERVING', + init_tablet_type='replica', + init_keyspace=keyspace, + init_shard=shard, + supports_backups=True, + extra_args=xtra_args) + + def _reset_tablet_dir(self, t): + """Stop mysql, delete everything including tablet dir, restart mysql.""" + utils.wait_procs([t.teardown_mysql()]) + # Specify ignore_options because we want to delete the tree even + # if the test's -k / --keep-logs was specified on the command line. + t.remove_tree(ignore_options=True) + proc = t.init_mysql() + utils.wait_procs([proc]) + + def _list_backups(self, shard): + """Get a list of backup names for the test shard.""" + backups, _ = utils.run_vtctl(tablet.get_backup_storage_flags() + + ['ListBackups', 'test_keyspace/%s' % shard], + mode=utils.VTCTL_VTCTL, trap_output=True) + return backups.splitlines() + + def _remove_backup(self, backup, shard): + """Remove a named backup from the test shard.""" + utils.run_vtctl( + tablet.get_backup_storage_flags() + + ['RemoveBackup', 'test_keyspace/%s' % shard, backup], + auto_log=True, mode=utils.VTCTL_VTCTL) + + def test_unsharded_recovery_after_sharding(self): + """Test recovery from backup flow. + + test_recovery will: + - create a shard with master and replica1 only + - run InitShardMaster + - insert some data + - take a backup + - insert more data on the master + - perform a resharding + - create a recovery keyspace + - bring up tablet_replica2 in the new keyspace + - check that new tablet does not have data created after backup + - check that vtgate queries work correctly + + """ + + # insert data on master, wait for replica to get it + utils.run_vtctl(['ApplySchema', + '-sql', self._create_vt_insert_test, + 'test_keyspace'], + auto_log=True) + self._insert_data(tablet_master, 1) + self._check_data(tablet_replica1, 1, 'replica1 tablet getting data') + # insert more data on the master + self._insert_data(tablet_master, 2) + + # backup the replica + utils.run_vtctl(['Backup', tablet_replica1.tablet_alias], auto_log=True) + + # check that the backup shows up in the listing + backups = self._list_backups('0') + logging.debug('list of backups: %s', backups) + self.assertEqual(len(backups), 1) + self.assertTrue(backups[0].endswith(tablet_replica1.tablet_alias)) + + # insert more data on the master + self._insert_data(tablet_master, 3) + + utils.run_vtctl(['ApplyVSchema', + '-vschema', self._vschema_json, + 'test_keyspace'], + auto_log=True) + + # create the split shards + shard_0_master.init_tablet( + 'replica', + keyspace='test_keyspace', + shard='-80', + tablet_index=0) + shard_0_replica.init_tablet( + 'replica', + keyspace='test_keyspace', + shard='-80', + tablet_index=1) + shard_0_rdonly.init_tablet( + 'rdonly', + keyspace='test_keyspace', + shard='-80', + tablet_index=2) + shard_1_master.init_tablet( + 'replica', + keyspace='test_keyspace', + shard='80-', + tablet_index=0) + shard_1_replica.init_tablet( + 'replica', + keyspace='test_keyspace', + shard='80-', + tablet_index=1) + shard_1_rdonly.init_tablet( + 'rdonly', + keyspace='test_keyspace', + shard='80-', + tablet_index=2) + + for t in [shard_0_master, shard_0_replica, shard_0_rdonly, + shard_1_master, shard_1_replica, shard_1_rdonly]: + t.start_vttablet(wait_for_state=None, + binlog_use_v3_resharding_mode=True) + + for t in [shard_0_master, shard_0_replica, shard_0_rdonly, + shard_1_master, shard_1_replica, shard_1_rdonly]: + t.wait_for_vttablet_state('NOT_SERVING') + + utils.run_vtctl(['InitShardMaster', '-force', 'test_keyspace/-80', + shard_0_master.tablet_alias], auto_log=True) + utils.run_vtctl(['InitShardMaster', '-force', 'test_keyspace/80-', + shard_1_master.tablet_alias], auto_log=True) + + for t in [shard_0_replica, shard_1_replica]: + utils.wait_for_tablet_type(t.tablet_alias, 'replica') + + sharded_tablets = [shard_0_master, shard_0_replica, shard_0_rdonly, + shard_1_master, shard_1_replica, shard_1_rdonly] + for t in sharded_tablets: + t.wait_for_vttablet_state('SERVING') + + # we need to create the schema, and the worker will do data copying + for keyspace_shard in ('test_keyspace/-80', 'test_keyspace/80-'): + utils.run_vtctl(['CopySchemaShard', + 'test_keyspace/0', + keyspace_shard], + auto_log=True) + + utils.run_vtctl( + ['SplitClone', 'test_keyspace', '0', '-80,80-'], auto_log=True) + + utils.run_vtctl( + ['MigrateServedTypes', 'test_keyspace/0', 'rdonly'], auto_log=True) + utils.run_vtctl( + ['MigrateServedTypes', 'test_keyspace/0', 'replica'], auto_log=True) + # then serve master from the split shards + utils.run_vtctl(['MigrateServedTypes', 'test_keyspace/0', 'master'], + auto_log=True) + + # remove the original tablets in the original shard + tablet.kill_tablets([tablet_master, tablet_replica1, tablet_rdonly]) + for t in [tablet_replica1, tablet_rdonly]: + utils.run_vtctl(['DeleteTablet', t.tablet_alias], auto_log=True) + utils.run_vtctl(['DeleteTablet', '-allow_master', + tablet_master.tablet_alias], auto_log=True) + + # rebuild the serving graph, all mentions of the old shards should be gone + utils.run_vtctl(['RebuildKeyspaceGraph', 'test_keyspace'], auto_log=True) + + # delete the original shard + utils.run_vtctl(['DeleteShard', 'test_keyspace/0'], auto_log=True) + + # now bring up the recovery keyspace and a tablet, letting it restore from backup. + self._restore(tablet_replica2, 'recovery_keyspace', '0') + + # check the new replica does not have the data + self._check_data(tablet_replica2, 2, 'replica2 tablet should not have new data') + + # start vtgate + vtgate = utils.VtGate() + vtgate.start(tablets=[ + shard_0_master, shard_0_replica, shard_1_master, shard_1_replica, tablet_replica2 + ], tablet_types_to_wait='REPLICA') + utils.vtgate.wait_for_endpoints('test_keyspace.-80.master', 1) + utils.vtgate.wait_for_endpoints('test_keyspace.80-.replica', 1) + utils.vtgate.wait_for_endpoints('test_keyspace.-80.master', 1) + utils.vtgate.wait_for_endpoints('test_keyspace.80-.replica', 1) + utils.vtgate.wait_for_endpoints('recovery_keyspace.0.replica', 1) + + # check that vtgate doesn't route queries to new tablet + vtgate_conn = get_connection() + cursor = vtgate_conn.cursor( + tablet_type='replica', keyspace=None, writable=True) + + cursor.execute('select count(*) from vt_insert_test', {}) + result = cursor.fetchall() + if not result: + self.fail('Result cannot be null') + else: + self.assertEqual(result[0][0], 3) + + # check that new tablet is accessible by using ks.table + cursor.execute('select count(*) from recovery_keyspace.vt_insert_test', {}) + result = cursor.fetchall() + if not result: + self.fail('Result cannot be null') + else: + self.assertEqual(result[0][0], 2) + + # check that new tablet is accessible with 'use ks' + cursor.execute('use recovery_keyspace@replica', {}) + cursor.execute('select count(*) from vt_insert_test', {}) + result = cursor.fetchall() + if not result: + self.fail('Result cannot be null') + else: + self.assertEqual(result[0][0], 2) + + # TODO check that new tablet is accessible with 'use ks:shard' + # this currently does not work through the python client, though it works from mysql client + #cursor.execute('use recovery_keyspace:0@replica', {}) + #cursor.execute('select count(*) from vt_insert_test', {}) + #result = cursor.fetchall() + #if not result: + #self.fail('Result cannot be null') + #else: + #self.assertEqual(result[0][0], 1) + + vtgate_conn.close() + tablet_replica2.kill_vttablet() + vtgate.kill() + + def test_sharded_recovery(self): + """Test recovery from backup flow. + + test_recovery will: + - create a shard with master and replica1 only + - run InitShardMaster + - insert some data + - perform a resharding + - take a backup of both new shards + - insert more data on the masters of both shards + - create a recovery keyspace + - bring up tablet_replica2 and tablet_replica3 in the new keyspace + - check that new tablets do not have data created after backup + - check that vtgate queries work correctly + + """ + + # insert data on master, wait for replica to get it + utils.run_vtctl(['ApplySchema', + '-sql', self._create_vt_insert_test, + 'test_keyspace'], + auto_log=True) + self._insert_data(tablet_master, 1) + self._check_data(tablet_replica1, 1, 'replica1 tablet getting data') + # insert more data on the master + self._insert_data(tablet_master, 4) + + utils.run_vtctl(['ApplyVSchema', + '-vschema', self._vschema_json, + 'test_keyspace'], + auto_log=True) + + # create the split shards + shard_0_master.init_tablet( + 'replica', + keyspace='test_keyspace', + shard='-80', + tablet_index=0) + shard_0_replica.init_tablet( + 'replica', + keyspace='test_keyspace', + shard='-80', + tablet_index=1) + shard_0_rdonly.init_tablet( + 'rdonly', + keyspace='test_keyspace', + shard='-80', + tablet_index=2) + shard_1_master.init_tablet( + 'replica', + keyspace='test_keyspace', + shard='80-', + tablet_index=0) + shard_1_replica.init_tablet( + 'replica', + keyspace='test_keyspace', + shard='80-', + tablet_index=1) + shard_1_rdonly.init_tablet( + 'rdonly', + keyspace='test_keyspace', + shard='80-', + tablet_index=2) + + for t in [shard_0_master, shard_0_replica, shard_0_rdonly, + shard_1_master, shard_1_replica, shard_1_rdonly]: + t.start_vttablet(wait_for_state=None, + binlog_use_v3_resharding_mode=True) + + for t in [shard_0_master, shard_0_replica, shard_0_rdonly, + shard_1_master, shard_1_replica, shard_1_rdonly]: + t.wait_for_vttablet_state('NOT_SERVING') + + utils.run_vtctl(['InitShardMaster', '-force', 'test_keyspace/-80', + shard_0_master.tablet_alias], auto_log=True) + utils.run_vtctl(['InitShardMaster', '-force', 'test_keyspace/80-', + shard_1_master.tablet_alias], auto_log=True) + + for t in [shard_0_replica, shard_1_replica]: + utils.wait_for_tablet_type(t.tablet_alias, 'replica') + + sharded_tablets = [shard_0_master, shard_0_replica, shard_0_rdonly, + shard_1_master, shard_1_replica, shard_1_rdonly] + for t in sharded_tablets: + t.wait_for_vttablet_state('SERVING') + + # we need to create the schema, and the worker will do data copying + for keyspace_shard in ('test_keyspace/-80', 'test_keyspace/80-'): + utils.run_vtctl(['CopySchemaShard', + 'test_keyspace/0', + keyspace_shard], + auto_log=True) + + utils.run_vtctl( + ['SplitClone', 'test_keyspace', '0', '-80,80-'], auto_log=True) + + utils.run_vtctl( + ['MigrateServedTypes', 'test_keyspace/0', 'rdonly'], auto_log=True) + utils.run_vtctl( + ['MigrateServedTypes', 'test_keyspace/0', 'replica'], auto_log=True) + # then serve master from the split shards + utils.run_vtctl(['MigrateServedTypes', 'test_keyspace/0', 'master'], + auto_log=True) + + # remove the original tablets in the original shard + tablet.kill_tablets([tablet_master, tablet_replica1, tablet_rdonly]) + for t in [tablet_replica1, tablet_rdonly]: + utils.run_vtctl(['DeleteTablet', t.tablet_alias], auto_log=True) + utils.run_vtctl(['DeleteTablet', '-allow_master', + tablet_master.tablet_alias], auto_log=True) + + # rebuild the serving graph, all mentions of the old shards should be gone + utils.run_vtctl(['RebuildKeyspaceGraph', 'test_keyspace'], auto_log=True) + + # delete the original shard + utils.run_vtctl(['DeleteShard', 'test_keyspace/0'], auto_log=True) + + result = shard_0_master.mquery('vt_test_keyspace', "select count(*) from vt_insert_test") + shard_0_count = result[0][0] + logging.debug("Shard -80 has %d rows", shard_0_count) + shard_0_test_id = 0 + if shard_0_count > 0: + result = shard_0_master.mquery('vt_test_keyspace', "select id from vt_insert_test") + shard_0_test_id = result[0][0] + + result = shard_1_master.mquery('vt_test_keyspace', "select count(*) from vt_insert_test") + shard_1_count = result[0][0] + logging.debug("Shard 80- has %d rows", shard_1_count) + shard_1_test_id = 0 + if shard_1_count > 0: + result = shard_1_master.mquery('vt_test_keyspace', "select id from vt_insert_test") + shard_1_test_id = result[0][0] + + # backup the new shards + utils.run_vtctl(['Backup', shard_0_replica.tablet_alias], auto_log=True) + utils.run_vtctl(['Backup', shard_1_replica.tablet_alias], auto_log=True) + + # check that the backup shows up in the listing + backups = self._list_backups('-80') + logging.debug('list of backups: %s', backups) + self.assertEqual(len(backups), 1) + self.assertTrue(backups[0].endswith(shard_0_replica.tablet_alias)) + + backups = self._list_backups('80-') + logging.debug('list of backups: %s', backups) + self.assertEqual(len(backups), 1) + self.assertTrue(backups[0].endswith(shard_1_replica.tablet_alias)) + + # start vtgate + vtgate = utils.VtGate() + vtgate.start(tablets=[ + shard_0_master, shard_1_master + ], tablet_types_to_wait='MASTER') + utils.vtgate.wait_for_endpoints('test_keyspace.-80.master', 1) + utils.vtgate.wait_for_endpoints('test_keyspace.80-.master', 1) + + vtgate_conn = get_connection() + cursor = vtgate_conn.cursor( + tablet_type='master', keyspace=None, writable=True) + # insert more data on the masters + for i in [2, 3]: + cursor.execute('insert into vt_insert_test (id, msg) values (:id, :msg)', {'id': i, 'msg': 'test %s' % i}) + + vtgate_conn.close() + vtgate.kill() + + # now bring up the recovery keyspace and 2 tablets, letting it restore from backup. + self._restore(tablet_replica2, 'recovery_keyspace', '-80') + self._restore(tablet_replica3, 'recovery_keyspace', '80-') + + # check the new replicas have the correct number of rows + self._check_data(tablet_replica2, shard_0_count, 'replica2 tablet should not have new data') + self._check_data(tablet_replica3, shard_1_count, 'replica3 tablet should not have new data') + + # start vtgate + vtgate = utils.VtGate() + vtgate.start(tablets=[ + shard_0_master, shard_0_replica, shard_1_master, shard_1_replica, tablet_replica2, tablet_replica3 + ], tablet_types_to_wait='REPLICA') + utils.vtgate.wait_for_endpoints('test_keyspace.-80.master', 1) + utils.vtgate.wait_for_endpoints('test_keyspace.80-.replica', 1) + utils.vtgate.wait_for_endpoints('test_keyspace.-80.master', 1) + utils.vtgate.wait_for_endpoints('test_keyspace.80-.replica', 1) + utils.vtgate.wait_for_endpoints('recovery_keyspace.-80.replica', 1) + utils.vtgate.wait_for_endpoints('recovery_keyspace.80-.replica', 1) + + # check that vtgate doesn't route queries to new tablet + vtgate_conn = get_connection() + cursor = vtgate_conn.cursor( + tablet_type='replica', keyspace=None, writable=True) + + cursor.execute('select count(*) from vt_insert_test', {}) + result = cursor.fetchall() + if not result: + self.fail('Result cannot be null') + else: + self.assertEqual(result[0][0], 4) + + # check that new keyspace is accessible by using ks.table + cursor.execute('select count(*) from recovery_keyspace.vt_insert_test', {}) + result = cursor.fetchall() + if not result: + self.fail('Result cannot be null') + else: + self.assertEqual(result[0][0], 2) + + # check that new keyspace is accessible with 'use ks' + cursor.execute('use recovery_keyspace@replica', {}) + cursor.execute('select count(*) from vt_insert_test', {}) + result = cursor.fetchall() + if not result: + self.fail('Result cannot be null') + else: + self.assertEqual(result[0][0], 2) + + # TODO check that new tablet is accessible with 'use ks:shard' + # this currently does not work through the python client, though it works from mysql client + #cursor.execute('use recovery_keyspace:-80@replica', {}) + #cursor.execute('select count(*) from vt_insert_test', {}) + #result = cursor.fetchall() + #if not result: + # self.fail('Result cannot be null') + #else: + # self.assertEqual(result[0][0], shard_0_count) + #cursor.execute('select id from vt_insert_test', {}) + #result = cursor.fetchall() + #if not result: + # self.fail('Result cannot be null') + #else: + # self.assertEqual(result[0][0], shard_0_test_id) + + #cursor.execute('use recovery_keyspace:80-@replica', {}) + #cursor.execute('select count(*) from vt_insert_test', {}) + #result = cursor.fetchall() + #if not result: + # self.fail('Result cannot be null') + #else: + # self.assertEqual(result[0][0], shard_1_count) + #cursor.execute('use recovery_keyspace:80-@replica', {}) + #cursor.execute('select id from vt_insert_test', {}) + #result = cursor.fetchall() + #if not result: + # self.fail('Result cannot be null') + #else: + # self.assertEqual(result[0][0], shard_1_test_id) + + vtgate_conn.close() + tablet_replica2.kill_vttablet() + tablet_replica3.kill_vttablet() + vtgate.kill() + +if __name__ == '__main__': + utils.main() diff --git a/test/tablet.py b/test/tablet.py index 06e80492469..552c7d5031d 100644 --- a/test/tablet.py +++ b/test/tablet.py @@ -1,4 +1,4 @@ -# Copyright 2017 Google Inc. +# 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. @@ -401,6 +401,7 @@ def init_tablet(self, tablet_type, keyspace, shard, args = ['InitTablet', '-hostname', 'localhost', '-port', str(self.port), + '-grpc_port', str(self.grpc_port), '-allow_update'] if include_mysql_port: args.extend(['-mysql_port', str(self.mysql_port)]) diff --git a/test/tabletmanager.py b/test/tabletmanager.py index 706034663c8..4cc5f059ac8 100755 --- a/test/tabletmanager.py +++ b/test/tabletmanager.py @@ -1,6 +1,6 @@ #!/usr/bin/env python -# Copyright 2017 Google Inc. +# 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. @@ -100,8 +100,6 @@ def _test_sanity(self): utils.run_vtctl(['createshard', '-force', 'test_keyspace/0']) tablet_62344.init_tablet('master', 'test_keyspace', '0', parent=False) utils.run_vtctl(['RebuildKeyspaceGraph', 'test_keyspace']) - utils.validate_topology() - # if these statements don't run before the tablet it will wedge # waiting for the db to become accessible. this is more a bug than # a feature. @@ -109,6 +107,8 @@ def _test_sanity(self): self._populate_vt_select_test) tablet_62344.start_vttablet() + utils.validate_topology() + # make sure the query service is started right away. qr = tablet_62344.execute('select id, msg from vt_select_test') @@ -202,9 +202,18 @@ def test_actions_and_timeouts(self): utils.run_vtctl(['CreateKeyspace', 'test_keyspace']) tablet_62344.init_tablet('master', 'test_keyspace', '0') - utils.validate_topology() tablet_62344.create_db('vt_test_keyspace') tablet_62344.start_vttablet() + # validate topology after starting tablet so that tablet has a chance + # to update shard master_alias + timeout = 10 + while True: + shard = utils.run_vtctl_json(['GetShard', 'test_keyspace/0']) + if shard['master_alias']['uid'] == 62344: + break + wait_step('master_alias has been set', timeout) + + utils.validate_topology() utils.run_vtctl(['Ping', tablet_62344.tablet_alias]) @@ -685,14 +694,81 @@ def test_repeated_init_shard_master(self): # And done. tablet.kill_tablets([tablet_62344, tablet_62044]) - def test_fallback_policy(self): + def test_fallback_security_policy(self): tablet_62344.create_db('vt_test_keyspace') tablet_62344.init_tablet('master', 'test_keyspace', '0') + + # Requesting an unregistered security_policy should fall back to deny-all. tablet_62344.start_vttablet(security_policy='bogus') + + # It should deny ADMIN role. + f = urllib.urlopen('http://localhost:%d/streamqueryz/terminate' % int(tablet_62344.port)) + response = f.read() + f.close() + self.assertIn('not allowed', response) + + # It should deny MONITORING role. + f = urllib.urlopen('http://localhost:%d/debug/health' % int(tablet_62344.port)) + response = f.read() + f.close() + self.assertIn('not allowed', response) + + # It should deny DEBUGGING role. + f = urllib.urlopen('http://localhost:%d/queryz' % int(tablet_62344.port)) + response = f.read() + f.close() + self.assertIn('not allowed', response) + + tablet_62344.kill_vttablet() + + def test_deny_all_security_policy(self): + tablet_62344.create_db('vt_test_keyspace') + tablet_62344.init_tablet('master', 'test_keyspace', '0') + tablet_62344.start_vttablet(security_policy='deny-all') + + # It should deny ADMIN role. + f = urllib.urlopen('http://localhost:%d/streamqueryz/terminate' % int(tablet_62344.port)) + response = f.read() + f.close() + self.assertIn('not allowed', response) + + # It should deny MONITORING role. + f = urllib.urlopen('http://localhost:%d/debug/health' % int(tablet_62344.port)) + response = f.read() + f.close() + self.assertIn('not allowed', response) + + # It should deny DEBUGGING role. f = urllib.urlopen('http://localhost:%d/queryz' % int(tablet_62344.port)) response = f.read() f.close() self.assertIn('not allowed', response) + + tablet_62344.kill_vttablet() + + def test_read_only_security_policy(self): + tablet_62344.create_db('vt_test_keyspace') + tablet_62344.init_tablet('master', 'test_keyspace', '0') + tablet_62344.start_vttablet(security_policy='read-only') + + # It should deny ADMIN role. + f = urllib.urlopen('http://localhost:%d/streamqueryz/terminate' % int(tablet_62344.port)) + response = f.read() + f.close() + self.assertIn('not allowed', response) + + # It should allow MONITORING role. + f = urllib.urlopen('http://localhost:%d/debug/health' % int(tablet_62344.port)) + response = f.read() + f.close() + self.assertNotIn('not allowed', response) + + # It should allow DEBUGGING role. + f = urllib.urlopen('http://localhost:%d/queryz' % int(tablet_62344.port)) + response = f.read() + f.close() + self.assertNotIn('not allowed', response) + tablet_62344.kill_vttablet() def test_ignore_health_error(self): @@ -759,7 +835,7 @@ def test_master_restart_sets_ter_timestamp(self): init_keyspace='test_keyspace', init_shard='0') - # Make sure that the TER increased i.e. it was set to the current time. + # Make sure that the TER did not change health_after_restart = utils.run_vtctl_json(['VtTabletStreamHealth', '-count', '1', master.tablet_alias]) @@ -767,11 +843,11 @@ def test_master_restart_sets_ter_timestamp(self): health_after_restart['target']['tablet_type']) self.assertIn('tablet_externally_reparented_timestamp', health_after_restart) - self.assertGreater( + self.assertEqual( health_after_restart['tablet_externally_reparented_timestamp'], health['tablet_externally_reparented_timestamp'], 'When the MASTER vttablet was restarted, the TER timestamp must be set' - ' to the current time.') + ' by reading the old value from the tablet record. Old: %s, New: %s' % (str(health['tablet_externally_reparented_timestamp']), str(health_after_restart['tablet_externally_reparented_timestamp']))) # Shutdown. for t in tablets: @@ -788,8 +864,6 @@ def test_topocustomrule(self): utils.run_vtctl(['createshard', '-force', 'test_keyspace/0']) tablet_62344.init_tablet('master', 'test_keyspace', '0', parent=False) utils.run_vtctl(['RebuildKeyspaceGraph', 'test_keyspace']) - utils.validate_topology() - # Copy config file into topo. topocustomrule_path = '/keyspaces/test_keyspace/configs/CustomRules' utils.run_vtctl(['TopoCp', '-to_topo', topocustomrule_file, @@ -800,6 +874,8 @@ def test_topocustomrule(self): self._populate_vt_select_test) tablet_62344.start_vttablet(topocustomrule_path=topocustomrule_path) + utils.validate_topology() + # make sure the query service is working qr = tablet_62344.execute('select id, msg from vt_select_test') self.assertEqual(len(qr['rows']), 4, diff --git a/test/tabletmanager2.py b/test/tabletmanager2.py index b2d4ba87899..20bf74599ca 100755 --- a/test/tabletmanager2.py +++ b/test/tabletmanager2.py @@ -1,6 +1,6 @@ #!/usr/bin/env python -# Copyright 2017 Google Inc. +# 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. diff --git a/test/topo_flavor/__init__.py b/test/topo_flavor/__init__.py index 1b2b3632207..35bf136ccc5 100644 --- a/test/topo_flavor/__init__.py +++ b/test/topo_flavor/__init__.py @@ -1,6 +1,6 @@ #!/usr/bin/env python -# Copyright 2017 Google Inc. +# 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. diff --git a/test/topo_flavor/consul.py b/test/topo_flavor/consul.py index 9b0ec04bfa3..364b37b1f60 100644 --- a/test/topo_flavor/consul.py +++ b/test/topo_flavor/consul.py @@ -1,6 +1,6 @@ #!/usr/bin/env python -# Copyright 2017 Google Inc. +# 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. diff --git a/test/topo_flavor/etcd2.py b/test/topo_flavor/etcd2.py index 5c7d3bdcd11..8396bcc2b77 100644 --- a/test/topo_flavor/etcd2.py +++ b/test/topo_flavor/etcd2.py @@ -1,6 +1,6 @@ #!/usr/bin/env python -# Copyright 2017 Google Inc. +# 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. diff --git a/test/topo_flavor/server.py b/test/topo_flavor/server.py index 40fee6ad30d..24bd8dc7984 100644 --- a/test/topo_flavor/server.py +++ b/test/topo_flavor/server.py @@ -1,6 +1,6 @@ #!/usr/bin/env python -# Copyright 2017 Google Inc. +# 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. diff --git a/test/topo_flavor/zk2.py b/test/topo_flavor/zk2.py index e3695b14612..a605f8aea9d 100644 --- a/test/topo_flavor/zk2.py +++ b/test/topo_flavor/zk2.py @@ -1,6 +1,6 @@ #!/usr/bin/env python -# Copyright 2017 Google Inc. +# 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. diff --git a/test/update_stream.py b/test/update_stream.py index 035a3dcd9d6..39c8f88c7c4 100755 --- a/test/update_stream.py +++ b/test/update_stream.py @@ -1,6 +1,6 @@ #!/usr/bin/env python -# Copyright 2017 Google Inc. +# 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. diff --git a/test/update_stream_rbr.py b/test/update_stream_rbr.py index 706f0ff070a..313d2093783 100755 --- a/test/update_stream_rbr.py +++ b/test/update_stream_rbr.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright 2017 Google Inc. +# 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. diff --git a/test/utils.py b/test/utils.py index e73dccfdfd2..0a162375fff 100644 --- a/test/utils.py +++ b/test/utils.py @@ -1,6 +1,6 @@ #!/usr/bin/env python -# Copyright 2017 Google Inc. +# 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. @@ -815,7 +815,7 @@ def condition(v): def run_vtctl(clargs, auto_log=False, expect_fail=False, - mode=VTCTL_AUTO, **kwargs): + mode=VTCTL_AUTO, action_timeout=10, **kwargs): if mode == VTCTL_AUTO: if not expect_fail and vtctld: mode = VTCTL_RPC @@ -833,7 +833,7 @@ def run_vtctl(clargs, auto_log=False, expect_fail=False, logging.debug('vtctl: %s', ' '.join(clargs)) result = vtctl_client.execute_vtctl_command(vtctld_connection, clargs, info_to_debug=True, - action_timeout=10) + action_timeout=action_timeout) return result, '' raise Exception('Unknown mode: %s', mode) diff --git a/test/vertical_split.py b/test/vertical_split.py index 7f659d655e5..fbb61c30c74 100755 --- a/test/vertical_split.py +++ b/test/vertical_split.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright 2017 Google Inc. +# 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. diff --git a/test/vertical_split_rbr.py b/test/vertical_split_rbr.py index 0243085c34c..dc332dc5189 100755 --- a/test/vertical_split_rbr.py +++ b/test/vertical_split_rbr.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright 2017 Google Inc. +# 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. diff --git a/test/vtbackup.py b/test/vtbackup.py index 5eeef3cf8d5..f42831ea4e0 100644 --- a/test/vtbackup.py +++ b/test/vtbackup.py @@ -134,7 +134,7 @@ def start_vtbackup(self, "-init_db_sql_file",init_db ]) - # Pass through inital_backup flag to vtbackup + # Pass through initial_backup flag to vtbackup if initial_backup: args.extend(["-initial_backup"]) diff --git a/test/vtctld_test.py b/test/vtctld_test.py index 9bdfbe03a12..e481ce16f55 100755 --- a/test/vtctld_test.py +++ b/test/vtctld_test.py @@ -1,6 +1,6 @@ #!/usr/bin/env python -# Copyright 2017 Google Inc. +# 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. diff --git a/test/vtctld_web_test.py b/test/vtctld_web_test.py index 4fbe8131319..19738abf77f 100755 --- a/test/vtctld_web_test.py +++ b/test/vtctld_web_test.py @@ -1,6 +1,6 @@ #!/usr/bin/env python -# Copyright 2017 Google Inc. +# 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. diff --git a/test/vtgate_buffer.py b/test/vtgate_buffer.py index ecc24d61551..8fda7edbca1 100755 --- a/test/vtgate_buffer.py +++ b/test/vtgate_buffer.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright 2017 Google Inc. +# 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. @@ -37,6 +37,7 @@ import tablet import utils from mysql_flavor import mysql_flavor +from vtproto import topodata_pb2 KEYSPACE = 'ks1' SHARD = '0' @@ -380,6 +381,23 @@ def external_reparent(self): utils.run_vtctl(['TabletExternallyReparented', new_master.tablet_alias], auto_log=True) + # Wait until the old master becomes a replica before returning. + # Otherwise, that time counts against the timeout of the next test. + # Set the timeout well above 30, because it takes 30 seconds just to cancel + # stuck transactions when demoting the master. + timeout = 60.0 + while True: + try: + health = utils.run_vtctl_json(['VtTabletStreamHealth', + '-count', '1', + old_master.tablet_alias]) + if health['target']['tablet_type'] == topodata_pb2.REPLICA: + break + except: + pass + timeout = utils.wait_step('old master becomes replica', timeout, + sleep_time=1.0) + class TestBuffer(TestBufferBase): @@ -394,7 +412,7 @@ def test_buffer_planned_reparent(self): def planned_reparent(): utils.run_vtctl(['PlannedReparentShard', '-keyspace_shard', '%s/%s' % (KEYSPACE, SHARD), - '-new_master', replica.tablet_alias]) + '-new_master', replica.tablet_alias], auto_log=True) self._test_buffer(planned_reparent) def test_buffer_external_reparent(self): diff --git a/test/vtgate_gateway_flavor/__init__.py b/test/vtgate_gateway_flavor/__init__.py index 1b2b3632207..35bf136ccc5 100644 --- a/test/vtgate_gateway_flavor/__init__.py +++ b/test/vtgate_gateway_flavor/__init__.py @@ -1,6 +1,6 @@ #!/usr/bin/env python -# Copyright 2017 Google Inc. +# 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. diff --git a/test/vtgate_gateway_flavor/discoverygateway.py b/test/vtgate_gateway_flavor/discoverygateway.py index dcf48de082b..79c20ea2158 100644 --- a/test/vtgate_gateway_flavor/discoverygateway.py +++ b/test/vtgate_gateway_flavor/discoverygateway.py @@ -1,6 +1,6 @@ #!/usr/bin/env python -# Copyright 2017 Google Inc. +# 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. diff --git a/test/vtgate_gateway_flavor/gateway.py b/test/vtgate_gateway_flavor/gateway.py index fd96c3baf7c..5ab8f4759eb 100644 --- a/test/vtgate_gateway_flavor/gateway.py +++ b/test/vtgate_gateway_flavor/gateway.py @@ -1,6 +1,6 @@ #!/usr/bin/env python -# Copyright 2017 Google Inc. +# 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. diff --git a/test/vtgate_utils_test.py b/test/vtgate_utils_test.py index f6265419f6d..2c38b71cfb5 100755 --- a/test/vtgate_utils_test.py +++ b/test/vtgate_utils_test.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # coding: utf-8 -# Copyright 2017 Google Inc. +# 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. diff --git a/test/vtgatev2_test.py b/test/vtgatev2_test.py index 4d45f44d307..7f634a965be 100755 --- a/test/vtgatev2_test.py +++ b/test/vtgatev2_test.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # coding: utf-8 -# Copyright 2017 Google Inc. +# 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. diff --git a/test/vtgatev3_test.py b/test/vtgatev3_test.py index 557832dfd5b..83039e40ef3 100755 --- a/test/vtgatev3_test.py +++ b/test/vtgatev3_test.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # coding: utf-8 -# Copyright 2017 Google Inc. +# 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. @@ -1822,7 +1822,7 @@ def test_insert_value_required(self): try: vtgate_conn.begin() with self.assertRaisesRegexp(dbexceptions.DatabaseError, - '.*could not map NULL to a keyspace id.*'): + '.*could not map.*NULL.*to a keyspace id.*'): self.execute_on_master( vtgate_conn, 'insert into vt_user_extra (email) values (:email)', diff --git a/test/vthook-make_mycnf b/test/vthook-make_mycnf index 9755abc56ae..ed9b946d716 100755 --- a/test/vthook-make_mycnf +++ b/test/vthook-make_mycnf @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2018 The Vitess Authors. +# 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. diff --git a/test/vthook-test.sh b/test/vthook-test.sh index 73f0ed36cd8..8642ef8d2fa 100755 --- a/test/vthook-test.sh +++ b/test/vthook-test.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2017 Google Inc. +# 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. diff --git a/test/vthook-test_backup_error b/test/vthook-test_backup_error index 584e48929c9..233de9b7b28 100755 --- a/test/vthook-test_backup_error +++ b/test/vthook-test_backup_error @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2017 Google Inc. +# 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. diff --git a/test/vthook-test_backup_transform b/test/vthook-test_backup_transform index ac29e6b2744..f90b3094f9b 100755 --- a/test/vthook-test_backup_transform +++ b/test/vthook-test_backup_transform @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2017 Google Inc. +# 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. diff --git a/test/vttest_sample_test.py b/test/vttest_sample_test.py index ac815b843b8..98888a97777 100755 --- a/test/vttest_sample_test.py +++ b/test/vttest_sample_test.py @@ -1,6 +1,6 @@ #!/usr/bin/env python -# Copyright 2017 Google Inc. +# 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. diff --git a/test/worker.py b/test/worker.py index 5c51f811289..0d955bf94f8 100755 --- a/test/worker.py +++ b/test/worker.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright 2017 Google Inc. +# 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. @@ -217,6 +217,12 @@ def run_shard_tablets( utils.run_vtctl( ['InitShardMaster', '-force', 'test_keyspace/%s' % shard_name, shard_tablets.master.tablet_alias], auto_log=True) + timeout = 10 + while True: + shard = utils.run_vtctl_json(['GetShard', 'test_keyspace/%s' % shard_name]) + if shard['master_alias']['uid'] == shard_tablets.master.tablet_uid: + break + wait_step('master_alias has been set', timeout) utils.run_vtctl(['RebuildKeyspaceGraph', 'test_keyspace'], auto_log=True) # Enforce a health check instead of waiting for the next periodic one. @@ -507,8 +513,9 @@ def verify_successful_worker_copy_with_reparent(self, mysql_down=False): # Bring back masters. Since we test with semi-sync now, we need at least # one replica for the new master. This test is already quite expensive, - # so we bring back the old master as a replica rather than having a third - # replica up the whole time. + # so we bring back the old master and then let it be converted to a + # replica by PRS, rather than leaving the old master down and having a + # third replica up the whole time. logging.debug('Restarting mysqld on destination masters') utils.wait_procs( [shard_0_master.start_mysql(), diff --git a/test/xb_recovery.py b/test/xb_recovery.py new file mode 100755 index 00000000000..d73483d707c --- /dev/null +++ b/test/xb_recovery.py @@ -0,0 +1,25 @@ +#!/usr/bin/env python + +# 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. + + +"""Re-runs recovery.py with use_xtrabackup=True.""" + +import recovery +import utils + +if __name__ == '__main__': + recovery.use_xtrabackup = True + utils.main(recovery) diff --git a/tools/bootstrap_web.sh b/tools/bootstrap_web.sh index 258c6fe7312..aecc89b8f80 100755 --- a/tools/bootstrap_web.sh +++ b/tools/bootstrap_web.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2017 Google Inc. +# 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. diff --git a/tools/build_version_flags.sh b/tools/build_version_flags.sh index dc0ad5d630b..b2effa7fa42 100755 --- a/tools/build_version_flags.sh +++ b/tools/build_version_flags.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2017 Google Inc. +# 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. diff --git a/tools/check_make_parser.sh b/tools/check_make_parser.sh index 139e18199a8..d28d4f18f09 100755 --- a/tools/check_make_parser.sh +++ b/tools/check_make_parser.sh @@ -9,6 +9,7 @@ CUR="sql.go" TMP="/tmp/sql.$$.go" +set -e if ! cd go/vt/sqlparser/ ; then echo "ERROR: $0 must be run in the root project directory" @@ -16,7 +17,7 @@ if ! cd go/vt/sqlparser/ ; then fi mv $CUR $TMP -output=`goyacc -o $CUR sql.y` +output=$(go run golang.org/x/tools/cmd/goyacc -o $CUR sql.y) if [ -n "$output" ]; then echo "Expected empty output from goyacc, got:" diff --git a/tools/e2e_test_race.sh b/tools/e2e_test_race.sh new file mode 100755 index 00000000000..d66a427a5ff --- /dev/null +++ b/tools/e2e_test_race.sh @@ -0,0 +1,55 @@ +#!/bin/bash + +# 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. + +temp_log_file="$(mktemp --suffix .unit_test_race.log)" +trap '[ -f "$temp_log_file" ] && rm $temp_log_file' EXIT + +# This can be removed once the docker images are rebuilt +export GO111MODULE=on + +# Wrapper around go test -race. + +# This script exists because the -race test doesn't allow to distinguish +# between a failed (e.g. flaky) unit test and a found data race. +# Although Go 1.5 says 'exit status 66' in case of a race, it exits with 1. +# Therefore, we manually check the output of 'go test' for data races and +# exit with an error if one was found. +# TODO(mberlin): Test all packages (go/... instead of go/vt/...) once +# go/cgzip is moved into a separate repository. We currently +# skip the cgzip package because -race takes >30 sec for it. + +# All endtoend Go packages with test files. +# Output per line: * +packages_with_tests=$(go list -f '{{if len .TestGoFiles}}{{.ImportPath}} {{join .TestGoFiles " "}}{{end}}' ./go/.../endtoend/... | sort) + +# endtoend tests should be in a directory called endtoend +all_e2e_tests=$(echo "$packages_with_tests" | cut -d" " -f1) + +# Run all endtoend tests. +echo "$all_e2e_tests" | xargs go test $VT_GO_PARALLEL -race 2>&1 | tee $temp_log_file +if [ ${PIPESTATUS[0]} -ne 0 ]; then + if grep "WARNING: DATA RACE" -q $temp_log_file; then + echo + echo "ERROR: go test -race found a data race. See log above." + exit 2 + fi + + echo "ERROR: go test -race found NO data race, but failed. See log above." + exit 1 +fi + +echo +echo "SUCCESS: No data race was found." diff --git a/tools/e2e_test_runner.sh b/tools/e2e_test_runner.sh new file mode 100755 index 00000000000..4f7822d18ef --- /dev/null +++ b/tools/e2e_test_runner.sh @@ -0,0 +1,66 @@ +#!/bin/bash + +# 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. + +# Custom Go endtoend test runner which runs all endtoend tests in parallel +# except for known flaky tests. +# Flaky unit tests are run sequentially in the second phase and retried up to +# three times. + +# Why are there flaky unit tests? +# +# Some of the Go unit tests are inherently flaky e.g. because they use the +# real timer implementation and might fail when things take longer as usual. +# In particular, this happens when the system is under load and threads do not +# get scheduled as fast as usual. Then, the expected timings do not match. + +# Set VT_GO_PARALLEL variable in the same way as the Makefile does. +# We repeat this here because this script is called directly by test.go +# and not via the Makefile. +if [[ -z $VT_GO_PARALLEL && -n $VT_GO_PARALLEL_VALUE ]]; then + VT_GO_PARALLEL="-p $VT_GO_PARALLEL_VALUE" +fi + +# All Go packages with test files. +# Output per line: * +packages_with_tests=$(go list -f '{{if len .TestGoFiles}}{{.ImportPath}} {{join .TestGoFiles " "}}{{end}}' ./go/.../endtoend/... | sort) + +# Flaky tests have the suffix "_flaky_test.go". +all_except_flaky_tests=$(echo "$packages_with_tests" | grep -vE ".+ .+_flaky_test\.go" | cut -d" " -f1) +flaky_tests=$(echo "$packages_with_tests" | grep -E ".+ .+_flaky_test\.go" | cut -d" " -f1) + +# Run non-flaky tests. +echo "$all_except_flaky_tests" | xargs go test $VT_GO_PARALLEL +if [ $? -ne 0 ]; then + echo "ERROR: Go unit tests failed. See above for errors." + echo + echo "This should NOT happen. Did you introduce a flaky unit test?" + echo "If so, please rename it to the suffix _flaky_test.go." + exit 1 +fi + +# Run flaky tests sequentially. Retry when necessary. +for pkg in $flaky_tests; do + max_attempts=3 + attempt=1 + # Set a timeout because some tests may deadlock when they flake. + until go test -timeout 30s $VT_GO_PARALLEL $pkg; do + echo "FAILED (try $attempt/$max_attempts) in $pkg (return code $?). See above for errors." + if [ $((++attempt)) -gt $max_attempts ]; then + echo "ERROR: Flaky Go unit tests in package $pkg failed too often (after $max_attempts retries). Please reduce the flakiness." + exit 1 + fi + done +done diff --git a/tools/generate_web_artifacts.sh b/tools/generate_web_artifacts.sh index 4e13fdee82e..d21da7e84e6 100755 --- a/tools/generate_web_artifacts.sh +++ b/tools/generate_web_artifacts.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2017 Google Inc. +# 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. diff --git a/tools/pylint.sh b/tools/pylint.sh index ec86c36d535..92f97f4e885 100755 --- a/tools/pylint.sh +++ b/tools/pylint.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2017 Google Inc. +# 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. diff --git a/tools/sauce_connect_setup.sh b/tools/sauce_connect_setup.sh index d7778ffa98e..652e85788d2 100755 --- a/tools/sauce_connect_setup.sh +++ b/tools/sauce_connect_setup.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2017 Google Inc. +# 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. diff --git a/tools/sauce_connect_teardown.sh b/tools/sauce_connect_teardown.sh index e200b234f98..ff3e8936060 100755 --- a/tools/sauce_connect_teardown.sh +++ b/tools/sauce_connect_teardown.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2017 Google Inc. +# 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. diff --git a/tools/shell_functions.inc b/tools/shell_functions.inc index 8f6fcceae47..00696dee5fb 100644 --- a/tools/shell_functions.inc +++ b/tools/shell_functions.inc @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2017 Google Inc. +# 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. diff --git a/tools/statsd.go b/tools/statsd.go index 80518b0c657..f2ccd91e69b 100644 --- a/tools/statsd.go +++ b/tools/statsd.go @@ -1,18 +1,18 @@ /* -Copyright 2017 Google Inc. + * 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 + * 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 + * http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto 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. -*/ + * 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. + */ // statsd is a simple server for hosting test.go remote stats. package main diff --git a/tools/tools.go b/tools/tools.go new file mode 100644 index 00000000000..b9fb5d923fd --- /dev/null +++ b/tools/tools.go @@ -0,0 +1,30 @@ +// +build tools + +/* + * 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 tools + +// These imports ensure that "go mod tidy" won't remove deps +// for build-time dependencies like linters and code generators +import ( + _ "github.com/golang/mock/mockgen" + _ "golang.org/x/lint" + _ "golang.org/x/tools/cmd/cover" + _ "golang.org/x/tools/cmd/goimports" + _ "golang.org/x/tools/cmd/goyacc" + _ "honnef.co/go/tools/cmd/staticcheck" +) diff --git a/tools/unit_test_race.sh b/tools/unit_test_race.sh index c7861c9db8a..fef312ff340 100755 --- a/tools/unit_test_race.sh +++ b/tools/unit_test_race.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2017 Google Inc. +# 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. @@ -27,7 +27,16 @@ trap '[ -f "$temp_log_file" ] && rm $temp_log_file' EXIT # TODO(mberlin): Test all packages (go/... instead of go/vt/...) once # go/cgzip is moved into a separate repository. We currently # skip the cgzip package because -race takes >30 sec for it. -go test $VT_GO_PARALLEL -race ./go/vt/... 2>&1 | tee $temp_log_file + +# All Go packages with test files. +# Output per line: * +packages_with_tests=$(go list -f '{{if len .TestGoFiles}}{{.ImportPath}} {{join .TestGoFiles " "}}{{end}}' ./go/vt/... | sort) + +# endtoend tests should be in a directory called endtoend +all_except_e2e_tests=$(echo "$packages_with_tests" | cut -d" " -f1 | grep -v "endtoend") + +# Run non endtoend tests. +echo "$all_except_e2e_tests" | xargs go test $VT_GO_PARALLEL -race 2>&1 | tee $temp_log_file if [ ${PIPESTATUS[0]} -ne 0 ]; then if grep "WARNING: DATA RACE" -q $temp_log_file; then echo diff --git a/tools/unit_test_runner.sh b/tools/unit_test_runner.sh index 7e0c8150f05..382dd2f0b76 100755 --- a/tools/unit_test_runner.sh +++ b/tools/unit_test_runner.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2017 Google Inc. +# 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. @@ -38,7 +38,8 @@ fi packages_with_tests=$(go list -f '{{if len .TestGoFiles}}{{.ImportPath}} {{join .TestGoFiles " "}}{{end}}' ./go/... | sort) # Flaky tests have the suffix "_flaky_test.go". -all_except_flaky_tests=$(echo "$packages_with_tests" | grep -vE ".+ .+_flaky_test\.go" | cut -d" " -f1) +# Exclude endtoend tests +all_except_flaky_tests=$(echo "$packages_with_tests" | grep -vE ".+ .+_flaky_test\.go" | cut -d" " -f1 | grep -v "endtoend") flaky_tests=$(echo "$packages_with_tests" | grep -E ".+ .+_flaky_test\.go" | cut -d" " -f1) # Run non-flaky tests. diff --git a/travis/check_make_proto.sh b/travis/check_make_proto.sh index 3749fea5ba9..30af1bdcf83 100755 --- a/travis/check_make_proto.sh +++ b/travis/check_make_proto.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2017 Google Inc. +# 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. diff --git a/travis/log_gomaxprocs.go b/travis/log_gomaxprocs.go index d90758ef7b5..d6c18b9ce15 100644 --- a/travis/log_gomaxprocs.go +++ b/travis/log_gomaxprocs.go @@ -1,18 +1,18 @@ /* -Copyright 2017 Google Inc. + * 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 + * 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 + * http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreedto 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. -*/ + * 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. + */ // The sole purpose of this file is to print the configured value of GOMAXPROCS. // This way we can verify that the Travis CI worker is configured correctly by default. diff --git a/vendor/README.md b/vendor/README.md deleted file mode 100644 index 50fefa8917d..00000000000 --- a/vendor/README.md +++ /dev/null @@ -1,19 +0,0 @@ -# govendor - -We manage the file `vendor.json` through the [govendor](https://github.com/kardianos/govendor) command. - -## Add a new dependency - -```sh -govendor fetch @ -``` - -If available, please always use a release version. If not, you can omit `@`. - -## Update a dependency - -Example gRPC: - -```sh -govendor fetch google.golang.org/grpc/...@v1.11.2 -``` diff --git a/vendor/vendor.json b/vendor/vendor.json deleted file mode 100644 index 212a4c22416..00000000000 --- a/vendor/vendor.json +++ /dev/null @@ -1,2035 +0,0 @@ -{ - "comment": "", - "ignore": "appengine test", - "package": [ - { - "checksumSHA1": "b1KgRkWqz0RmrEBK6IJ8kOJva6w=", - "path": "cloud.google.com/go/compute/metadata", - "revision": "cdaaf98f9226c39dc162b8e55083b2fbc67b4674", - "revisionTime": "2019-07-12T19:01:42Z", - "version": "v0.43.0", - "versionExact": "v0.43.0" - }, - { - "checksumSHA1": "+S/9jBntS1iHZwxkR64vsy97Gh8=", - "path": "cloud.google.com/go/iam", - "revision": "cdaaf98f9226c39dc162b8e55083b2fbc67b4674", - "revisionTime": "2019-07-12T19:01:42Z", - "version": "v0.43.0", - "versionExact": "v0.43.0" - }, - { - "checksumSHA1": "JfGXEtr79UaxukcL05IERkjYm/g=", - "path": "cloud.google.com/go/internal", - "revision": "cdaaf98f9226c39dc162b8e55083b2fbc67b4674", - "revisionTime": "2019-07-12T19:01:42Z", - "version": "v0.43.0", - "versionExact": "v0.43.0" - }, - { - "checksumSHA1": "wQ4uGuRwMb24vG16pPQDOOCPkFo=", - "path": "cloud.google.com/go/internal/optional", - "revision": "cdaaf98f9226c39dc162b8e55083b2fbc67b4674", - "revisionTime": "2019-07-12T19:01:42Z", - "version": "v0.43.0", - "versionExact": "v0.43.0" - }, - { - "checksumSHA1": "5Jz6j0verpzBzMwIEZai+EbV6Ls=", - "path": "cloud.google.com/go/internal/testutil", - "revision": "cdaaf98f9226c39dc162b8e55083b2fbc67b4674", - "revisionTime": "2019-07-12T19:01:42Z", - "version": "v0.43.0", - "versionExact": "v0.43.0" - }, - { - "checksumSHA1": "jHOn3QLqvr1luNqyOg24/BXLrsM=", - "path": "cloud.google.com/go/internal/trace", - "revision": "cdaaf98f9226c39dc162b8e55083b2fbc67b4674", - "revisionTime": "2019-07-12T19:01:42Z", - "version": "v0.43.0", - "versionExact": "v0.43.0" - }, - { - "checksumSHA1": "FSifvUBJjm4OsSU5rp5s5+bqvN0=", - "path": "cloud.google.com/go/internal/version", - "revision": "cdaaf98f9226c39dc162b8e55083b2fbc67b4674", - "revisionTime": "2019-07-12T19:01:42Z", - "version": "v0.43.0", - "versionExact": "v0.43.0" - }, - { - "checksumSHA1": "tof7cbQFVwy2rN/iJfKXDKUf4rs=", - "path": "cloud.google.com/go/storage", - "revision": "cdaaf98f9226c39dc162b8e55083b2fbc67b4674", - "revisionTime": "2019-07-12T19:01:42Z", - "version": "v0.43.0", - "versionExact": "v0.43.0" - }, - { - "checksumSHA1": "t5pzf8AGtuCmECrPlJM9oAky+dk=", - "path": "github.com/aws/aws-sdk-go/aws", - "revision": "f07b33eb84960583bbb72889ae0f98d300e107fe", - "revisionTime": "2018-02-23T17:39:05Z" - }, - { - "checksumSHA1": "Y9W+4GimK4Fuxq+vyIskVYFRnX4=", - "path": "github.com/aws/aws-sdk-go/aws/awserr", - "revision": "f07b33eb84960583bbb72889ae0f98d300e107fe", - "revisionTime": "2018-02-23T17:39:05Z" - }, - { - "checksumSHA1": "yyYr41HZ1Aq0hWc3J5ijXwYEcac=", - "path": "github.com/aws/aws-sdk-go/aws/awsutil", - "revision": "f07b33eb84960583bbb72889ae0f98d300e107fe", - "revisionTime": "2018-02-23T17:39:05Z" - }, - { - "checksumSHA1": "wGf8GkrbZe2VFXOo28K0jq68A+g=", - "path": "github.com/aws/aws-sdk-go/aws/client", - "revision": "f07b33eb84960583bbb72889ae0f98d300e107fe", - "revisionTime": "2018-02-23T17:39:05Z" - }, - { - "checksumSHA1": "ieAJ+Cvp/PKv1LpUEnUXpc3OI6E=", - "path": "github.com/aws/aws-sdk-go/aws/client/metadata", - "revision": "f07b33eb84960583bbb72889ae0f98d300e107fe", - "revisionTime": "2018-02-23T17:39:05Z" - }, - { - "checksumSHA1": "U2W3pMTHfONS6R/QP/Zg18+89TQ=", - "path": "github.com/aws/aws-sdk-go/aws/corehandlers", - "revision": "f07b33eb84960583bbb72889ae0f98d300e107fe", - "revisionTime": "2018-02-23T17:39:05Z" - }, - { - "checksumSHA1": "Y+cPwQL0dZMyqp3wI+KJWmA9KQ8=", - "path": "github.com/aws/aws-sdk-go/aws/credentials", - "revision": "f07b33eb84960583bbb72889ae0f98d300e107fe", - "revisionTime": "2018-02-23T17:39:05Z" - }, - { - "checksumSHA1": "u3GOAJLmdvbuNUeUEcZSEAOeL/0=", - "path": "github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds", - "revision": "f07b33eb84960583bbb72889ae0f98d300e107fe", - "revisionTime": "2018-02-23T17:39:05Z" - }, - { - "checksumSHA1": "NUJUTWlc1sV8b7WjfiYc4JZbXl0=", - "path": "github.com/aws/aws-sdk-go/aws/credentials/endpointcreds", - "revision": "ebef4262e06a772a06a80aaee8e952c2514e1606", - "revisionTime": "2018-02-23T18:40:12Z" - }, - { - "checksumSHA1": "JEYqmF83O5n5bHkupAzA6STm0no=", - "path": "github.com/aws/aws-sdk-go/aws/credentials/stscreds", - "revision": "ebef4262e06a772a06a80aaee8e952c2514e1606", - "revisionTime": "2018-02-23T18:40:12Z" - }, - { - "checksumSHA1": "OnU/n7R33oYXiB4SAGd5pK7I0Bs=", - "path": "github.com/aws/aws-sdk-go/aws/defaults", - "revision": "f07b33eb84960583bbb72889ae0f98d300e107fe", - "revisionTime": "2018-02-23T17:39:05Z" - }, - { - "checksumSHA1": "pDnK93CqjQ4ROSW8Y/RuHXjv52M=", - "path": "github.com/aws/aws-sdk-go/aws/ec2metadata", - "revision": "f07b33eb84960583bbb72889ae0f98d300e107fe", - "revisionTime": "2018-02-23T17:39:05Z" - }, - { - "checksumSHA1": "dUurC4Vz9SYV3ZSSP+aM+DH4F14=", - "path": "github.com/aws/aws-sdk-go/aws/endpoints", - "revision": "ebef4262e06a772a06a80aaee8e952c2514e1606", - "revisionTime": "2018-02-23T18:40:12Z" - }, - { - "checksumSHA1": "FpjCPoRNsVKM1hOg9EpC7jn5pRI=", - "path": "github.com/aws/aws-sdk-go/aws/request", - "revision": "f07b33eb84960583bbb72889ae0f98d300e107fe", - "revisionTime": "2018-02-23T17:39:05Z" - }, - { - "checksumSHA1": "DIn7B+oP++/nw603OB95fmupzu8=", - "path": "github.com/aws/aws-sdk-go/aws/session", - "revision": "f07b33eb84960583bbb72889ae0f98d300e107fe", - "revisionTime": "2018-02-23T17:39:05Z" - }, - { - "checksumSHA1": "4gwCpxPnVQISJGF/skyWpzzxFAc=", - "path": "github.com/aws/aws-sdk-go/aws/signer/v4", - "revision": "ebef4262e06a772a06a80aaee8e952c2514e1606", - "revisionTime": "2018-02-23T18:40:12Z" - }, - { - "checksumSHA1": "MxSiiCoPpY1mCRjyEFClUu3e14w=", - "path": "github.com/aws/aws-sdk-go/awstesting", - "revision": "f07b33eb84960583bbb72889ae0f98d300e107fe", - "revisionTime": "2018-02-23T17:39:05Z" - }, - { - "checksumSHA1": "iOAj9X968hli6R2oCTjFVQPH5Ug=", - "path": "github.com/aws/aws-sdk-go/awstesting/mock", - "revision": "f07b33eb84960583bbb72889ae0f98d300e107fe", - "revisionTime": "2018-02-23T17:39:05Z" - }, - { - "checksumSHA1": "MIp5H1niMhCZFAwYsjJx9NxmHIc=", - "path": "github.com/aws/aws-sdk-go/awstesting/unit", - "revision": "f07b33eb84960583bbb72889ae0f98d300e107fe", - "revisionTime": "2018-02-23T17:39:05Z" - }, - { - "checksumSHA1": "MYLldFRnsZh21TfCkgkXCT3maPU=", - "path": "github.com/aws/aws-sdk-go/internal/sdkrand", - "revision": "ebef4262e06a772a06a80aaee8e952c2514e1606", - "revisionTime": "2018-02-23T18:40:12Z" - }, - { - "checksumSHA1": "04ypv4x12l4q0TksA1zEVsmgpvw=", - "path": "github.com/aws/aws-sdk-go/internal/shareddefaults", - "revision": "ebef4262e06a772a06a80aaee8e952c2514e1606", - "revisionTime": "2018-02-23T18:40:12Z" - }, - { - "checksumSHA1": "sgft7A0lRCVD7QBogydg46lr3NM=", - "path": "github.com/aws/aws-sdk-go/private/endpoints", - "revision": "2e1a49c71fb7d8f6b7e8cca2259ed9b68d9b97ce", - "revisionTime": "2016-06-13T21:28:44Z" - }, - { - "checksumSHA1": "NStHCXEvYqG72GknZyv1jaKaeH0=", - "path": "github.com/aws/aws-sdk-go/private/protocol", - "revision": "f07b33eb84960583bbb72889ae0f98d300e107fe", - "revisionTime": "2018-02-23T17:39:05Z" - }, - { - "checksumSHA1": "1QmQ3FqV37w0Zi44qv8pA1GeR0A=", - "path": "github.com/aws/aws-sdk-go/private/protocol/ec2query", - "revision": "f07b33eb84960583bbb72889ae0f98d300e107fe", - "revisionTime": "2018-02-23T17:39:05Z" - }, - { - "checksumSHA1": "yHfT5DTbeCLs4NE2Rgnqrhe15ls=", - "path": "github.com/aws/aws-sdk-go/private/protocol/json/jsonutil", - "revision": "f07b33eb84960583bbb72889ae0f98d300e107fe", - "revisionTime": "2018-02-23T17:39:05Z" - }, - { - "checksumSHA1": "R00RL5jJXRYq1iiK1+PGvMfvXyM=", - "path": "github.com/aws/aws-sdk-go/private/protocol/jsonrpc", - "revision": "f07b33eb84960583bbb72889ae0f98d300e107fe", - "revisionTime": "2018-02-23T17:39:05Z" - }, - { - "checksumSHA1": "ZqY5RWavBLWTo6j9xqdyBEaNFRk=", - "path": "github.com/aws/aws-sdk-go/private/protocol/query", - "revision": "f07b33eb84960583bbb72889ae0f98d300e107fe", - "revisionTime": "2018-02-23T17:39:05Z" - }, - { - "checksumSHA1": "9V1PvtFQ9MObZTc3sa86WcuOtOU=", - "path": "github.com/aws/aws-sdk-go/private/protocol/query/queryutil", - "revision": "f07b33eb84960583bbb72889ae0f98d300e107fe", - "revisionTime": "2018-02-23T17:39:05Z" - }, - { - "checksumSHA1": "pkeoOfZpHRvFG/AOZeTf0lwtsFg=", - "path": "github.com/aws/aws-sdk-go/private/protocol/rest", - "revision": "f07b33eb84960583bbb72889ae0f98d300e107fe", - "revisionTime": "2018-02-23T17:39:05Z" - }, - { - "checksumSHA1": "Rpu8KBtHZgvhkwHxUfaky+qW+G4=", - "path": "github.com/aws/aws-sdk-go/private/protocol/restjson", - "revision": "f07b33eb84960583bbb72889ae0f98d300e107fe", - "revisionTime": "2018-02-23T17:39:05Z" - }, - { - "checksumSHA1": "ODo+ko8D6unAxZuN1jGzMcN4QCc=", - "path": "github.com/aws/aws-sdk-go/private/protocol/restxml", - "revision": "f07b33eb84960583bbb72889ae0f98d300e107fe", - "revisionTime": "2018-02-23T17:39:05Z" - }, - { - "checksumSHA1": "0qYPUga28aQVkxZgBR3Z86AbGUQ=", - "path": "github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil", - "revision": "f07b33eb84960583bbb72889ae0f98d300e107fe", - "revisionTime": "2018-02-23T17:39:05Z" - }, - { - "checksumSHA1": "wZbHPxkyYsr5h6GW5OVh9qIMZR8=", - "path": "github.com/aws/aws-sdk-go/private/signer/v4", - "revision": "2e1a49c71fb7d8f6b7e8cca2259ed9b68d9b97ce", - "revisionTime": "2016-06-13T21:28:44Z" - }, - { - "checksumSHA1": "01b4hmyUzoReoOyEDylDinWBSdA=", - "path": "github.com/aws/aws-sdk-go/private/util", - "revision": "f07b33eb84960583bbb72889ae0f98d300e107fe", - "revisionTime": "2018-02-23T17:39:05Z" - }, - { - "checksumSHA1": "Eo9yODN5U99BK0pMzoqnBm7PCrY=", - "path": "github.com/aws/aws-sdk-go/private/waiter", - "revision": "2e1a49c71fb7d8f6b7e8cca2259ed9b68d9b97ce", - "revisionTime": "2016-06-13T21:28:44Z" - }, - { - "checksumSHA1": "0nPnGWlegQG7bn/iIIfjJFoljyU=", - "path": "github.com/aws/aws-sdk-go/service/cloudfront", - "revision": "f07b33eb84960583bbb72889ae0f98d300e107fe", - "revisionTime": "2018-02-23T17:39:05Z" - }, - { - "checksumSHA1": "8JiVrxMjFSdBOfVWCy1QU+JzB08=", - "path": "github.com/aws/aws-sdk-go/service/dynamodb", - "revision": "f07b33eb84960583bbb72889ae0f98d300e107fe", - "revisionTime": "2018-02-23T17:39:05Z" - }, - { - "checksumSHA1": "/I6I2nR59isqKtSpEnTfLRWZ8Mc=", - "path": "github.com/aws/aws-sdk-go/service/dynamodb/dynamodbattribute", - "revision": "f07b33eb84960583bbb72889ae0f98d300e107fe", - "revisionTime": "2018-02-23T17:39:05Z" - }, - { - "checksumSHA1": "roq8pXva49Jq13gh5n6iiZ+LXBc=", - "path": "github.com/aws/aws-sdk-go/service/ec2", - "revision": "f07b33eb84960583bbb72889ae0f98d300e107fe", - "revisionTime": "2018-02-23T17:39:05Z" - }, - { - "checksumSHA1": "SZ7yLDZ6RvMhpWe0Goyem64kgyA=", - "path": "github.com/aws/aws-sdk-go/service/elastictranscoder", - "revision": "f07b33eb84960583bbb72889ae0f98d300e107fe", - "revisionTime": "2018-02-23T17:39:05Z" - }, - { - "checksumSHA1": "DfzNze8B3ME2tV3TtXP7eQXUjD0=", - "path": "github.com/aws/aws-sdk-go/service/kinesis", - "revision": "f07b33eb84960583bbb72889ae0f98d300e107fe", - "revisionTime": "2018-02-23T17:39:05Z" - }, - { - "checksumSHA1": "KPRDrVt4hrFBmJ2le8HebKphfjE=", - "path": "github.com/aws/aws-sdk-go/service/route53", - "revision": "f07b33eb84960583bbb72889ae0f98d300e107fe", - "revisionTime": "2018-02-23T17:39:05Z" - }, - { - "checksumSHA1": "fXQn3V0ZRBZpTXUEHl4/yOjR4mQ=", - "path": "github.com/aws/aws-sdk-go/service/s3", - "revision": "f07b33eb84960583bbb72889ae0f98d300e107fe", - "revisionTime": "2018-02-23T17:39:05Z" - }, - { - "checksumSHA1": "ZP6QI0X9BNKk8o1p3AyLfjabS20=", - "path": "github.com/aws/aws-sdk-go/service/s3/s3iface", - "revision": "f07b33eb84960583bbb72889ae0f98d300e107fe", - "revisionTime": "2018-02-23T17:39:05Z" - }, - { - "checksumSHA1": "N+U01iPy566cfzEY+dliw/fYEdE=", - "path": "github.com/aws/aws-sdk-go/service/s3/s3manager", - "revision": "f07b33eb84960583bbb72889ae0f98d300e107fe", - "revisionTime": "2018-02-23T17:39:05Z" - }, - { - "checksumSHA1": "x7HCNPJnQi+4P6FKpBTY1hm3m6o=", - "path": "github.com/aws/aws-sdk-go/service/sts", - "revision": "ebef4262e06a772a06a80aaee8e952c2514e1606", - "revisionTime": "2018-02-23T18:40:12Z" - }, - { - "checksumSHA1": "4QnLdmB1kG3N+KlDd1N+G9TWAGQ=", - "path": "github.com/beorn7/perks/quantile", - "revision": "3ac7bf7a47d159a033b107610db8a1b6575507a4", - "revisionTime": "2016-02-29T21:34:45Z" - }, - { - "checksumSHA1": "7BC2/27NId9xaPDB5w3nWN2mn9A=", - "path": "github.com/coreos/etcd/auth/authpb", - "revision": "703663d1f6ed070ab83b01386f0b023091c5e016", - "revisionTime": "2017-06-26T01:50:32Z" - }, - { - "checksumSHA1": "MljqP0GJ8+FxtIDFxmCtkmt+Auo=", - "path": "github.com/coreos/etcd/clientv3", - "revision": "703663d1f6ed070ab83b01386f0b023091c5e016", - "revisionTime": "2017-06-26T01:50:32Z" - }, - { - "checksumSHA1": "PnBbh5xS4/RtluD+Vatock/WZts=", - "path": "github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes", - "revision": "703663d1f6ed070ab83b01386f0b023091c5e016", - "revisionTime": "2017-06-26T01:50:32Z" - }, - { - "checksumSHA1": "7xBiCrhCPYjgh2TAsZP9hBLzDgA=", - "path": "github.com/coreos/etcd/etcdserver/etcdserverpb", - "revision": "703663d1f6ed070ab83b01386f0b023091c5e016", - "revisionTime": "2017-06-26T01:50:32Z" - }, - { - "checksumSHA1": "JAkX9DfIBrSe0vUa07xl5cikxVQ=", - "path": "github.com/coreos/etcd/mvcc/mvccpb", - "revision": "703663d1f6ed070ab83b01386f0b023091c5e016", - "revisionTime": "2017-06-26T01:50:32Z" - }, - { - "checksumSHA1": "Ggn+h7g45yWJ9QWZtZ3Vu2qevcQ=", - "path": "github.com/coreos/go-etcd/etcd", - "revision": "f02171fbd43c7b9b53ce8679b03235a1ef3c7b12", - "revisionTime": "2015-04-16T20:55:17Z", - "version": "=v2.0.0", - "versionExact": "v2.0.0" - }, - { - "checksumSHA1": "CSPbwbyzqA6sfORicn4HFtIhF/c=", - "path": "github.com/davecgh/go-spew/spew", - "revision": "d8f796af33cc11cb798c1aaeb27a4ebc5099927d", - "revisionTime": "2018-08-30T19:11:22Z" - }, - { - "checksumSHA1": "a2yC46a1qsJomgY6rb+FkTFiqmE=", - "path": "github.com/davecgh/go-spew/spew/testdata", - "revision": "5215b55f46b2b919f50a1df0eaa5886afe4e3b3d", - "revisionTime": "2015-11-05T21:09:06Z" - }, - { - "checksumSHA1": "muGVyM8mY3/gcap6kr4Ib3F5Xn4=", - "path": "github.com/ghodss/yaml", - "revision": "04f313413ffd65ce25f2541bfd2b2ceec5c0908c", - "revisionTime": "2016-12-07T00:33:20Z" - }, - { - "checksumSHA1": "FfdxnQ4CZVJJvG4BC1fWavgperI=", - "path": "github.com/go-ini/ini", - "revision": "72ba3e6b9e6b87e0c74c9a7a4dc86e8dd8ba4355", - "revisionTime": "2016-06-01T19:11:21Z" - }, - { - "checksumSHA1": "HmbftipkadrLlCfzzVQ+iFHbl6g=", - "path": "github.com/golang/glog", - "revision": "23def4e6c14b4da8ac2ed8007337bc5eb5007998", - "revisionTime": "2016-01-25T20:49:56Z" - }, - { - "checksumSHA1": "M3BUApw7nNipzKvYbHSpxqE04FY=", - "path": "github.com/golang/mock/gomock", - "revision": "13f360950a79f5864a972c786a10a50e44b69541", - "revisionTime": "2017-07-22T14:45:13Z", - "version": "v1.0.0", - "versionExact": "v1.0.0" - }, - { - "checksumSHA1": "ks9nCA68MefWDMUIjIF/zJwpTuw=", - "path": "github.com/golang/mock/gomock/mock_matcher", - "revision": "bd3c8e81be01eef76d4b503f5e687d2d1354d2d9", - "revisionTime": "2016-01-21T18:51:14Z" - }, - { - "checksumSHA1": "MgBmXopyMTVxPYgWfLrSsMIFE84=", - "path": "github.com/golang/protobuf/jsonpb", - "revision": "6c65a5562fc06764971b7c5d05c76c75e84bdbf7", - "revisionTime": "2019-07-01T18:22:01Z", - "version": "v1.3.2", - "versionExact": "v1.3.2" - }, - { - "checksumSHA1": "78dam9bgu36kpCiQPsy5ni3s1cs=", - "path": "github.com/golang/protobuf/jsonpb/jsonpb_test_proto", - "revision": "6c65a5562fc06764971b7c5d05c76c75e84bdbf7", - "revisionTime": "2019-07-01T18:22:01Z", - "version": "v1.3.2", - "versionExact": "v1.3.2" - }, - { - "checksumSHA1": "CGj8VcI/CpzxaNqlqpEVM7qElD4=", - "path": "github.com/golang/protobuf/proto", - "revision": "6c65a5562fc06764971b7c5d05c76c75e84bdbf7", - "revisionTime": "2019-07-01T18:22:01Z", - "version": "v1.3.2", - "versionExact": "v1.3.2" - }, - { - "checksumSHA1": "cQvjaQ6YsQ2s/QOmJeSGMjbyLhU=", - "path": "github.com/golang/protobuf/proto/proto3_proto", - "revision": "6c65a5562fc06764971b7c5d05c76c75e84bdbf7", - "revisionTime": "2019-07-01T18:22:01Z", - "version": "v1.3.2", - "versionExact": "v1.3.2" - }, - { - "checksumSHA1": "Ap3fxoENMwxwOM77e56TlCVt+7o=", - "path": "github.com/golang/protobuf/proto/test_proto", - "revision": "6c65a5562fc06764971b7c5d05c76c75e84bdbf7", - "revisionTime": "2019-07-01T18:22:01Z", - "version": "v1.3.2", - "versionExact": "v1.3.2" - }, - { - "checksumSHA1": "A0DxiyxXV4u8PmwUwlVkQ2CKyiQ=", - "path": "github.com/golang/protobuf/proto/testdata", - "revision": "1909bc2f63dc92bb931deace8b8312c4db72d12f", - "revisionTime": "2017-08-08T02:16:21Z", - "version": "v1.3.2", - "versionExact": "v1.3.2" - }, - { - "checksumSHA1": "iqWBA0GWNr+cwAdF2KVy1eq9mlU=", - "path": "github.com/golang/protobuf/protoc-gen-go", - "revision": "6c65a5562fc06764971b7c5d05c76c75e84bdbf7", - "revisionTime": "2019-07-01T18:22:01Z", - "version": "v1.3.2", - "versionExact": "v1.3.2" - }, - { - "checksumSHA1": "WOkXetG3AqJnfVVuqTJvdukcHps=", - "path": "github.com/golang/protobuf/protoc-gen-go/descriptor", - "revision": "6c65a5562fc06764971b7c5d05c76c75e84bdbf7", - "revisionTime": "2019-07-01T18:22:01Z", - "version": "v1.3.2", - "versionExact": "v1.3.2" - }, - { - "checksumSHA1": "dqkZJ8o1Hj3gbN30RyZ7G3CxhfU=", - "path": "github.com/golang/protobuf/protoc-gen-go/generator", - "revision": "6c65a5562fc06764971b7c5d05c76c75e84bdbf7", - "revisionTime": "2019-07-01T18:22:01Z", - "version": "v1.3.2", - "versionExact": "v1.3.2" - }, - { - "checksumSHA1": "uY4dEtqaAe5gsU8gbpCI1JgEIII=", - "path": "github.com/golang/protobuf/protoc-gen-go/generator/internal/remap", - "revision": "6c65a5562fc06764971b7c5d05c76c75e84bdbf7", - "revisionTime": "2019-07-01T18:22:01Z", - "version": "v1.3.2", - "versionExact": "v1.3.2" - }, - { - "checksumSHA1": "fejUXovU2abLTPX7kU8fzwT8Kmo=", - "path": "github.com/golang/protobuf/protoc-gen-go/grpc", - "revision": "6c65a5562fc06764971b7c5d05c76c75e84bdbf7", - "revisionTime": "2019-07-01T18:22:01Z", - "version": "v1.3.2", - "versionExact": "v1.3.2" - }, - { - "checksumSHA1": "h4PLbJDYnRmcUuf56USJ5K3xJOg=", - "path": "github.com/golang/protobuf/protoc-gen-go/plugin", - "revision": "6c65a5562fc06764971b7c5d05c76c75e84bdbf7", - "revisionTime": "2019-07-01T18:22:01Z", - "version": "v1.3.2", - "versionExact": "v1.3.2" - }, - { - "checksumSHA1": "/vLtyN6HK5twSZIFerD199YTmjk=", - "path": "github.com/golang/protobuf/protoc-gen-go/testdata/multi", - "revision": "2bc9827a78f95c6665b5fe0abd1fd66b496ae2d8", - "revisionTime": "2016-11-03T22:44:32Z" - }, - { - "checksumSHA1": "aEiR2m3NGaMGTbUW5P+w5gKFyc8=", - "path": "github.com/golang/protobuf/ptypes", - "revision": "6c65a5562fc06764971b7c5d05c76c75e84bdbf7", - "revisionTime": "2019-07-01T18:22:01Z", - "version": "v1.3.2", - "versionExact": "v1.3.2" - }, - { - "checksumSHA1": "2/Xg4L9IVGQRJB8zCELZx7/Z4HU=", - "path": "github.com/golang/protobuf/ptypes/any", - "revision": "6c65a5562fc06764971b7c5d05c76c75e84bdbf7", - "revisionTime": "2019-07-01T18:22:01Z", - "version": "v1.3.2", - "versionExact": "v1.3.2" - }, - { - "checksumSHA1": "RE9rLveNHapyMKQC8p10tbkUE9w=", - "path": "github.com/golang/protobuf/ptypes/duration", - "revision": "6c65a5562fc06764971b7c5d05c76c75e84bdbf7", - "revisionTime": "2019-07-01T18:22:01Z", - "version": "v1.3.2", - "versionExact": "v1.3.2" - }, - { - "checksumSHA1": "RT/PGRMtH/yBCbIJfZftaz5yc3M=", - "path": "github.com/golang/protobuf/ptypes/struct", - "revision": "6c65a5562fc06764971b7c5d05c76c75e84bdbf7", - "revisionTime": "2019-07-01T18:22:01Z", - "version": "v1.3.2", - "versionExact": "v1.3.2" - }, - { - "checksumSHA1": "seEwY2xETpK9yHJ9+bHqkLZ0VMU=", - "path": "github.com/golang/protobuf/ptypes/timestamp", - "revision": "6c65a5562fc06764971b7c5d05c76c75e84bdbf7", - "revisionTime": "2019-07-01T18:22:01Z", - "version": "v1.3.2", - "versionExact": "v1.3.2" - }, - { - "checksumSHA1": "KlQCb83HC090bojw4ofNDxn2nho=", - "path": "github.com/golang/protobuf/ptypes/wrappers", - "revision": "6c65a5562fc06764971b7c5d05c76c75e84bdbf7", - "revisionTime": "2019-07-01T18:22:01Z", - "version": "v1.3.2", - "versionExact": "v1.3.2" - }, - { - "checksumSHA1": "p/8vSviYF91gFflhrt5vkyksroo=", - "path": "github.com/golang/snappy", - "revision": "553a641470496b2327abcac10b36396bd98e45c9", - "revisionTime": "2017-02-15T23:32:05Z" - }, - { - "checksumSHA1": "HYqCnwjrsx9RYvx7uA0EkzLGnxA=", - "path": "github.com/google/go-cmp/cmp", - "revision": "6d8cafd2f64fe3cd66b7530d95df066b00bdd777", - "revisionTime": "2019-08-01T21:37:55Z" - }, - { - "checksumSHA1": "FUnTgtE5i3f8asIvicGkJSFlrts=", - "path": "github.com/google/go-cmp/cmp/internal/diff", - "revision": "6d8cafd2f64fe3cd66b7530d95df066b00bdd777", - "revisionTime": "2019-08-01T21:37:55Z" - }, - { - "checksumSHA1": "nR8EJ8i8lqxxmtLPnXI7WlYANiE=", - "path": "github.com/google/go-cmp/cmp/internal/flags", - "revision": "6d8cafd2f64fe3cd66b7530d95df066b00bdd777", - "revisionTime": "2019-08-01T21:37:55Z" - }, - { - "checksumSHA1": "0pcLJsUQUaBdPXM5LuL9uFeuETs=", - "path": "github.com/google/go-cmp/cmp/internal/function", - "revision": "6d8cafd2f64fe3cd66b7530d95df066b00bdd777", - "revisionTime": "2019-08-01T21:37:55Z" - }, - { - "checksumSHA1": "ZNN1jJuHnBCpo21lSv25VvkotIM=", - "path": "github.com/google/go-cmp/cmp/internal/value", - "revision": "6d8cafd2f64fe3cd66b7530d95df066b00bdd777", - "revisionTime": "2019-08-01T21:37:55Z" - }, - { - "checksumSHA1": "V/53BpqgOkSDZCX6snQCAkdO2fM=", - "path": "github.com/googleapis/gax-go", - "revision": "da06d194a00e19ce00d9011a13931c3f6f6887c7", - "revisionTime": "2016-11-07T00:24:06Z" - }, - { - "checksumSHA1": "WZoHSeTnVjnPIX2+U1Otst5MUKw=", - "path": "github.com/googleapis/gax-go/v2", - "revision": "bd5b16380fd03dc758d11cef74ba2e3bc8b0e8c2", - "revisionTime": "2019-05-13T18:38:25Z" - }, - { - "checksumSHA1": "P3zGmsNjW8m15a+nks4FdVpFKwE=", - "path": "github.com/gopherjs/gopherjs/js", - "revision": "a727a4a1dd2f292e948cebe6ec9aef1a7863f145", - "revisionTime": "2016-06-12T21:17:59Z" - }, - { - "checksumSHA1": "klfNfdEPsrWYLps2qBkLgfJsNYI=", - "path": "github.com/gorilla/websocket", - "revision": "2d1e4548da234d9cb742cc3628556fef86aafbac", - "revisionTime": "2016-09-12T15:30:41Z" - }, - { - "checksumSHA1": "Naa1qU7ykpIyDUZktjbqAU3V6bY=", - "path": "github.com/grpc-ecosystem/go-grpc-middleware", - "revision": "f849b5445de4819127e123ca96ba0eeb62b5e479", - "revisionTime": "2019-01-18T09:38:23Z" - }, - { - "checksumSHA1": "9dP53doJ/haDqTJyD0iuv8g0XFs=", - "path": "github.com/grpc-ecosystem/go-grpc-prometheus", - "revision": "39de4380c2e0353a115b80b1c730719c79bfb771", - "revisionTime": "2018-04-18T17:09:36Z" - }, - { - "checksumSHA1": "LoEQ+t5UoMm4InaYVPVn0XqHPwA=", - "path": "github.com/grpc-ecosystem/grpc-gateway/runtime", - "revision": "199c40a060d1e55508b3b85182ce6f3895ae6302", - "revisionTime": "2016-11-28T00:20:07Z" - }, - { - "checksumSHA1": "x396LPNfci/5x8aVJbliQHH11HQ=", - "path": "github.com/grpc-ecosystem/grpc-gateway/runtime/internal", - "revision": "199c40a060d1e55508b3b85182ce6f3895ae6302", - "revisionTime": "2016-11-28T00:20:07Z" - }, - { - "checksumSHA1": "vqiK5r5dntV7JNZ+ZsGlD0Samos=", - "path": "github.com/grpc-ecosystem/grpc-gateway/utilities", - "revision": "199c40a060d1e55508b3b85182ce6f3895ae6302", - "revisionTime": "2016-11-28T00:20:07Z" - }, - { - "checksumSHA1": "LQOVduohnld12Px2o0MfYDPI7oQ=", - "path": "github.com/hashicorp/consul/api", - "revision": "0bddfa23a2ebe3c0773d917fc104f53d74f7a5ec", - "revisionTime": "2018-11-14T22:37:47Z", - "version": "v1.4.0", - "versionExact": "v1.4.0" - }, - { - "checksumSHA1": "Uzyon2091lmwacNsl1hCytjhHtg=", - "path": "github.com/hashicorp/go-cleanhttp", - "revision": "ad28ea4487f05916463e2423a55166280e8254b5", - "revisionTime": "2016-04-07T17:41:26Z" - }, - { - "checksumSHA1": "A1PcINvF3UiwHRKn8UcgARgvGRs=", - "path": "github.com/hashicorp/go-rootcerts", - "revision": "6bb64b370b90e7ef1fa532be9e591a81c3493e00", - "revisionTime": "2016-05-03T14:34:40Z" - }, - { - "checksumSHA1": "UThRII2e7MEeIJ2sTHbCXC+4tKU=", - "path": "github.com/hashicorp/golang-lru/simplelru", - "revision": "7f827b33c0f158ec5dfbba01bb0b14a4541fd81d", - "revisionTime": "2019-07-26T16:11:22Z" - }, - { - "checksumSHA1": "E3Xcanc9ouQwL+CZGOUyA/+giLg=", - "path": "github.com/hashicorp/serf/coordinate", - "revision": "d3a67ab21bc8a4643fa53a3633f2d951dd50c6ca", - "revisionTime": "2016-12-07T01:17:43Z" - }, - { - "checksumSHA1": "0ZrwvB6KoGPj2PoDNSEJwxQ6Mog=", - "path": "github.com/jmespath/go-jmespath", - "revision": "0b12d6b521d83fc7f755e7cfc1b1fbdd35a01a74", - "revisionTime": "2016-02-02T18:50:14Z" - }, - { - "checksumSHA1": "tewA7jXVGCw1zb5mA0BDecWi4iQ=", - "path": "github.com/jtolds/gls", - "revision": "8ddce2a84170772b95dd5d576c48d517b22cac63", - "revisionTime": "2016-01-05T22:08:40Z" - }, - { - "checksumSHA1": "rmCbOBewXcbEdHRerzoanS+kI2U=", - "path": "github.com/klauspost/compress/flate", - "revision": "b50017755d442260d792c34c7c43216d9ba7ffc7", - "revisionTime": "2018-08-01T09:52:37Z" - }, - { - "checksumSHA1": "vGHBCcWkLCbAc3PJcRs7vFbvaYM=", - "path": "github.com/klauspost/cpuid", - "revision": "e7e905edc00ea8827e58662220139109efea09db", - "revisionTime": "2018-04-05T13:32:22Z" - }, - { - "checksumSHA1": "6/zXof97s7P9tlNp3mUioXgeEVI=", - "path": "github.com/klauspost/crc32", - "revision": "bab58d77464aa9cf4e84200c3276da0831fe0c03", - "revisionTime": "2017-06-28T07:24:49Z" - }, - { - "checksumSHA1": "N4EMcnfxHl1f4TQsKQWX/yLF/BE=", - "path": "github.com/klauspost/pgzip", - "revision": "c4ad2ed77aece7b3270909769a30a3fcea262a66", - "revisionTime": "2018-07-17T08:42:24Z" - }, - { - "checksumSHA1": "DdH3xAkzAWJ4B/LGYJyCeRsly2I=", - "path": "github.com/mattn/go-runewidth", - "revision": "d6bea18f789704b5f83375793155289da36a3c7f", - "revisionTime": "2016-03-15T04:07:12Z" - }, - { - "checksumSHA1": "bKMZjd2wPw13VwoE7mBeSv5djFA=", - "path": "github.com/matttproud/golang_protobuf_extensions/pbutil", - "revision": "c12348ce28de40eed0136aa2b644d0ee0650e56c", - "revisionTime": "2016-04-24T11:30:07Z" - }, - { - "checksumSHA1": "fROk3NEFAz88JXptqo4kpwD15Ic=", - "path": "github.com/matttproud/golang_protobuf_extensions/testdata", - "revision": "c12348ce28de40eed0136aa2b644d0ee0650e56c", - "revisionTime": "2016-04-24T11:30:07Z" - }, - { - "checksumSHA1": "Yi/mSgnMkG30eC61vcQWVwmxQQ8=", - "path": "github.com/minio/minio-go", - "revision": "c8a261de75c1a9a9ece4dcc0c81ff6db525bcf27", - "revisionTime": "2019-01-31T01:53:50Z", - "version": "v6.0.16", - "versionExact": "v6.0.16" - }, - { - "checksumSHA1": "pw8e6bgWfeEZUIMnD0Zge4d/KPo=", - "path": "github.com/minio/minio-go/pkg/credentials", - "revision": "c8a261de75c1a9a9ece4dcc0c81ff6db525bcf27", - "revisionTime": "2019-01-31T01:53:50Z", - "version": "v6.0.16", - "versionExact": "v6.0.16" - }, - { - "checksumSHA1": "Md5pOKYfoKtrG7xNvs2FtiDPfDc=", - "path": "github.com/minio/minio-go/pkg/encrypt", - "revision": "c8a261de75c1a9a9ece4dcc0c81ff6db525bcf27", - "revisionTime": "2019-01-31T01:53:50Z", - "version": "v6.0.16", - "versionExact": "v6.0.16" - }, - { - "checksumSHA1": "1KcTZxPRRQ0BWLt1zDVG1bSjm/4=", - "path": "github.com/minio/minio-go/pkg/s3signer", - "revision": "c8a261de75c1a9a9ece4dcc0c81ff6db525bcf27", - "revisionTime": "2019-01-31T01:53:50Z", - "version": "v6.0.16", - "versionExact": "v6.0.16" - }, - { - "checksumSHA1": "7iUaZkEJdhkyAu3F07vrX8pyavI=", - "path": "github.com/minio/minio-go/pkg/s3utils", - "revision": "c8a261de75c1a9a9ece4dcc0c81ff6db525bcf27", - "revisionTime": "2019-01-31T01:53:50Z", - "version": "v6.0.16", - "versionExact": "v6.0.16" - }, - { - "checksumSHA1": "Wt8ej+rZXTdNBR9Xyw1eGo3Iq5o=", - "path": "github.com/minio/minio-go/pkg/set", - "revision": "c8a261de75c1a9a9ece4dcc0c81ff6db525bcf27", - "revisionTime": "2019-01-31T01:53:50Z", - "version": "v6.0.16", - "versionExact": "v6.0.16" - }, - { - "checksumSHA1": "V/quM7+em2ByJbWBLOsEwnY3j/Q=", - "path": "github.com/mitchellh/go-homedir", - "revision": "b8bc1bf767474819792c23f32d8286a45736f1c6", - "revisionTime": "2016-12-03T19:45:07Z" - }, - { - "checksumSHA1": "J+g0oZePWp2zSIISD2dZZKTxmgg=", - "path": "github.com/mitchellh/mapstructure", - "revision": "3536a929edddb9a5b34bd6861dc4a9647cb459fe", - "revisionTime": "2018-10-05T04:51:35Z" - }, - { - "checksumSHA1": "txj5yUDiaSATtBLDlT0f6uaiIP8=", - "path": "github.com/olekukonko/tablewriter", - "revision": "cca8bbc0798408af109aaaa239cbd2634846b340", - "revisionTime": "2016-01-15T11:10:02Z" - }, - { - "checksumSHA1": "n38KWy7vkTd5/n7QqyRveENyZ98=", - "path": "github.com/opentracing-contrib/go-grpc", - "revision": "4b5a12d3ff02ba61ae861b7797e17a0c4f0ecea9", - "revisionTime": "2018-09-28T15:53:21Z" - }, - { - "checksumSHA1": "N+a8z9+g8MnuPN0aItiVP2CVFQs=", - "path": "github.com/opentracing/opentracing-go", - "revision": "1949ddbfd147afd4d964a9f00b24eb291e0e7c38", - "revisionTime": "2017-04-26T17:58:16Z", - "version": "v1.0.2", - "versionExact": "v1.0.2" - }, - { - "checksumSHA1": "XPOyfxsryU1pByZESwduVu9OEQU=", - "path": "github.com/opentracing/opentracing-go/ext", - "revision": "1949ddbfd147afd4d964a9f00b24eb291e0e7c38", - "revisionTime": "2017-04-26T17:58:16Z", - "version": "v1.0.2", - "versionExact": "v1.0.2" - }, - { - "checksumSHA1": "+rbKrafLHDnrQFgeWawo9tfZhV4=", - "path": "github.com/opentracing/opentracing-go/log", - "revision": "1949ddbfd147afd4d964a9f00b24eb291e0e7c38", - "revisionTime": "2017-04-26T17:58:16Z", - "version": "v1.0.2", - "versionExact": "v1.0.2" - }, - { - "checksumSHA1": "mhvIMH8oAtOiEyg37zWKmgb+6v4=", - "path": "github.com/pborman/uuid", - "revision": "b984ec7fa9ff9e428bd0cf0abf429384dfbe3e37", - "revisionTime": "2016-08-24T21:06:00Z" - }, - { - "checksumSHA1": "0H/VjT8w1CB702qWpbYMqr65Mf0=", - "path": "github.com/pkg/errors", - "revision": "ffb6e22f01932bf7ac35e0bad9be11f01d1c8685", - "revisionTime": "2019-01-09T06:16:28Z" - }, - { - "checksumSHA1": "LuFv4/jlrmFNnDb/5SCSEPAM9vU=", - "path": "github.com/pmezard/go-difflib/difflib", - "revision": "792786c7400a136282c1664665ae0a8db921c6c2", - "revisionTime": "2016-01-10T10:55:54Z" - }, - { - "checksumSHA1": "I87tkF1e/hrl4d/XIKFfkPRq1ww=", - "path": "github.com/prometheus/client_golang/prometheus", - "revision": "d49167c4b9f3c4451707560c5c71471ff5291aaa", - "revisionTime": "2018-03-19T13:17:21Z" - }, - { - "checksumSHA1": "mIWVz1E1QJ6yZnf7ELNwLboyK4w=", - "path": "github.com/prometheus/client_golang/prometheus/promhttp", - "revision": "d49167c4b9f3c4451707560c5c71471ff5291aaa", - "revisionTime": "2018-03-19T13:17:21Z" - }, - { - "checksumSHA1": "DvwvOlPNAgRntBzt3b3OSRMS2N4=", - "path": "github.com/prometheus/client_model/go", - "revision": "fa8ad6fec33561be4280a8f0514318c79d7f6cb6", - "revisionTime": "2015-02-12T10:17:44Z" - }, - { - "checksumSHA1": "m+nrHcRrjgi0wEa5PODKnY5yNX8=", - "path": "github.com/prometheus/common/expfmt", - "revision": "3a184ff7dfd46b9091030bf2e56c71112b0ddb0e", - "revisionTime": "2016-06-07T09:43:39Z" - }, - { - "checksumSHA1": "GWlM3d2vPYyNATtTFgftS10/A9w=", - "path": "github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg", - "revision": "3a184ff7dfd46b9091030bf2e56c71112b0ddb0e", - "revisionTime": "2016-06-07T09:43:39Z" - }, - { - "checksumSHA1": "Jx0GXl5hGnO25s3ryyvtdWHdCpw=", - "path": "github.com/prometheus/common/model", - "revision": "3a184ff7dfd46b9091030bf2e56c71112b0ddb0e", - "revisionTime": "2016-06-07T09:43:39Z" - }, - { - "checksumSHA1": "W218eJZPXJG783fUr/z6IaAZyes=", - "path": "github.com/prometheus/procfs", - "revision": "abf152e5f3e97f2fafac028d2cc06c1feb87ffa5", - "revisionTime": "2016-04-11T19:08:41Z" - }, - { - "checksumSHA1": "zmC8/3V4ls53DJlNTKDZwPSC/dA=", - "path": "github.com/satori/go.uuid", - "revision": "0aa62d5ddceb50dbcb909d790b5345affd3669b6", - "revisionTime": "2016-07-13T18:03:06Z" - }, - { - "checksumSHA1": "v7C+aJ1D/z3MEeCte6bxvpoGjM4=", - "path": "github.com/sergi/go-diff/diffmatchpatch", - "revision": "feef008d51ad2b3778f85d387ccf91735543008d", - "revisionTime": "2017-04-09T07:17:39Z" - }, - { - "checksumSHA1": "6AYg4fjEvFuAVN3wHakGApjhZAM=", - "path": "github.com/smartystreets/assertions", - "revision": "40711f7748186bbf9c99977cd89f21ce1a229447", - "revisionTime": "2016-04-22T19:53:51Z" - }, - { - "checksumSHA1": "Vzb+dEH/LTYbvr8RXHmt6xJHz04=", - "path": "github.com/smartystreets/assertions/internal/go-render/render", - "revision": "40711f7748186bbf9c99977cd89f21ce1a229447", - "revisionTime": "2016-04-22T19:53:51Z" - }, - { - "checksumSHA1": "SLC6TfV4icQA9l8YJQu8acJYbuo=", - "path": "github.com/smartystreets/assertions/internal/oglematchers", - "revision": "40711f7748186bbf9c99977cd89f21ce1a229447", - "revisionTime": "2016-04-22T19:53:51Z" - }, - { - "checksumSHA1": "SrDo9JDu6DyZ7I+4uQABY6EkW90=", - "path": "github.com/smartystreets/assertions/internal/oglemock", - "revision": "40711f7748186bbf9c99977cd89f21ce1a229447", - "revisionTime": "2016-04-22T19:53:51Z" - }, - { - "checksumSHA1": "fqmDhb1Vu5Ian6bKOIK/qKHbfDY=", - "path": "github.com/smartystreets/assertions/internal/oglemock/sample/mock_io", - "revision": "40711f7748186bbf9c99977cd89f21ce1a229447", - "revisionTime": "2016-04-22T19:53:51Z" - }, - { - "checksumSHA1": "iZ6XlO018Wjbq08EmI/gF98wWuI=", - "path": "github.com/smartystreets/assertions/internal/ogletest", - "revision": "40711f7748186bbf9c99977cd89f21ce1a229447", - "revisionTime": "2016-04-22T19:53:51Z" - }, - { - "checksumSHA1": "Ji1ubfT/e0/n/ABIjm+SkAnB2nI=", - "path": "github.com/smartystreets/assertions/internal/ogletest/srcutil", - "revision": "40711f7748186bbf9c99977cd89f21ce1a229447", - "revisionTime": "2016-04-22T19:53:51Z" - }, - { - "checksumSHA1": "Lq4IjivEPadH4fnuG/3uXyMZHEQ=", - "path": "github.com/smartystreets/assertions/internal/reqtrace", - "revision": "40711f7748186bbf9c99977cd89f21ce1a229447", - "revisionTime": "2016-04-22T19:53:51Z" - }, - { - "checksumSHA1": "/mwAihy9AmznMzmbPQ5nWJXBiRU=", - "path": "github.com/smartystreets/goconvey/convey", - "revision": "c53abc99456fa3402dd33c15ee51c3e545e04a3f", - "revisionTime": "2016-05-23T15:31:47Z" - }, - { - "checksumSHA1": "9LakndErFi5uCXtY1KWl0iRnT4c=", - "path": "github.com/smartystreets/goconvey/convey/gotest", - "revision": "c53abc99456fa3402dd33c15ee51c3e545e04a3f", - "revisionTime": "2016-05-23T15:31:47Z" - }, - { - "checksumSHA1": "FWDhk37bhAwZ2363D/L2xePwR64=", - "path": "github.com/smartystreets/goconvey/convey/reporting", - "revision": "c53abc99456fa3402dd33c15ee51c3e545e04a3f", - "revisionTime": "2016-05-23T15:31:47Z" - }, - { - "checksumSHA1": "/7bZ0f2fM9AAsLf3nMca6Gtlm6E=", - "path": "github.com/stretchr/testify/assert", - "revision": "221dbe5ed46703ee255b1da0dec05086f5035f62", - "revisionTime": "2019-05-17T17:51:56Z" - }, - { - "checksumSHA1": "P9FJpir2c4G5PA46qEkaWy3l60U=", - "path": "github.com/stretchr/testify/require", - "revision": "8d64eb7173c7753d6419fd4a9caf057398611364", - "revisionTime": "2016-05-24T23:42:29Z" - }, - { - "checksumSHA1": "fi13nRs6FDnhY5kL/9eMcNF8rQ8=", - "path": "github.com/tchap/go-patricia/patricia", - "revision": "dd168db6051b704a01881df7e003cb7ec9a7a440", - "revisionTime": "2016-07-29T07:16:56Z" - }, - { - "checksumSHA1": "DPkZT4nujrbAaKzqiWe+nmsNw2M=", - "path": "github.com/uber/jaeger-client-go", - "revision": "2f47546e3facd43297739439600bcf43f44cce5d", - "revisionTime": "2019-03-24T18:29:16Z", - "version": "v2.16.0", - "versionExact": "v2.16.0" - }, - { - "checksumSHA1": "/PA9bYu1glNCL5ucsKj8s+NkkHc=", - "path": "github.com/uber/jaeger-client-go/config", - "revision": "2f47546e3facd43297739439600bcf43f44cce5d", - "revisionTime": "2019-03-24T18:29:16Z", - "version": "v2.16.0", - "versionExact": "v2.16.0" - }, - { - "checksumSHA1": "KM5UXTWkHULmw0dDRNuk8ogWyGs=", - "path": "github.com/uber/jaeger-client-go/internal/baggage", - "revision": "2f47546e3facd43297739439600bcf43f44cce5d", - "revisionTime": "2019-03-24T18:29:16Z", - "version": "v2.16.0", - "versionExact": "v2.16.0" - }, - { - "checksumSHA1": "tZqlcHV1XoLdZp9jfnydzsZAvYo=", - "path": "github.com/uber/jaeger-client-go/internal/baggage/remote", - "revision": "2f47546e3facd43297739439600bcf43f44cce5d", - "revisionTime": "2019-03-24T18:29:16Z", - "version": "v2.16.0", - "versionExact": "v2.16.0" - }, - { - "checksumSHA1": "QB0L0GrzyMGQp6ivkkxp7a1DPsE=", - "path": "github.com/uber/jaeger-client-go/internal/spanlog", - "revision": "2f47546e3facd43297739439600bcf43f44cce5d", - "revisionTime": "2019-03-24T18:29:16Z", - "version": "v2.16.0", - "versionExact": "v2.16.0" - }, - { - "checksumSHA1": "79HRO/+ekkpwqDB/OMiW+AHJtlE=", - "path": "github.com/uber/jaeger-client-go/internal/throttler", - "revision": "2f47546e3facd43297739439600bcf43f44cce5d", - "revisionTime": "2019-03-24T18:29:16Z", - "version": "v2.16.0", - "versionExact": "v2.16.0" - }, - { - "checksumSHA1": "OVQDWFtFMs+NODe0F/S5kYViQco=", - "path": "github.com/uber/jaeger-client-go/internal/throttler/remote", - "revision": "2f47546e3facd43297739439600bcf43f44cce5d", - "revisionTime": "2019-03-24T18:29:16Z", - "version": "v2.16.0", - "versionExact": "v2.16.0" - }, - { - "checksumSHA1": "tMP/vxbHwNAbOEaUhic5/meKfac=", - "path": "github.com/uber/jaeger-client-go/log", - "revision": "2f47546e3facd43297739439600bcf43f44cce5d", - "revisionTime": "2019-03-24T18:29:16Z", - "version": "v2.16.0", - "versionExact": "v2.16.0" - }, - { - "checksumSHA1": "empqDwPkKUkGNeGHCu/EWoGI21o=", - "path": "github.com/uber/jaeger-client-go/rpcmetrics", - "revision": "2f47546e3facd43297739439600bcf43f44cce5d", - "revisionTime": "2019-03-24T18:29:16Z", - "version": "v2.16.0", - "versionExact": "v2.16.0" - }, - { - "checksumSHA1": "+ffspyTBQLql2UiU6muvfWR/m1o=", - "path": "github.com/uber/jaeger-client-go/thrift", - "revision": "2f47546e3facd43297739439600bcf43f44cce5d", - "revisionTime": "2019-03-24T18:29:16Z", - "version": "v2.16.0", - "versionExact": "v2.16.0" - }, - { - "checksumSHA1": "fMIQ4sJFCkqFYhXvvLKIlofqxvY=", - "path": "github.com/uber/jaeger-client-go/thrift-gen/agent", - "revision": "2f47546e3facd43297739439600bcf43f44cce5d", - "revisionTime": "2019-03-24T18:29:16Z", - "version": "v2.16.0", - "versionExact": "v2.16.0" - }, - { - "checksumSHA1": "fRR2p+JAp7paApf32YuQuWU7yzY=", - "path": "github.com/uber/jaeger-client-go/thrift-gen/baggage", - "revision": "2f47546e3facd43297739439600bcf43f44cce5d", - "revisionTime": "2019-03-24T18:29:16Z", - "version": "v2.16.0", - "versionExact": "v2.16.0" - }, - { - "checksumSHA1": "JZkMEOmiOFFEuGCsDOVLK5RzvMM=", - "path": "github.com/uber/jaeger-client-go/thrift-gen/jaeger", - "revision": "2f47546e3facd43297739439600bcf43f44cce5d", - "revisionTime": "2019-03-24T18:29:16Z", - "version": "v2.16.0", - "versionExact": "v2.16.0" - }, - { - "checksumSHA1": "0teQUhTqTE1fLs+vbnTTzWOqdEQ=", - "path": "github.com/uber/jaeger-client-go/thrift-gen/sampling", - "revision": "2f47546e3facd43297739439600bcf43f44cce5d", - "revisionTime": "2019-03-24T18:29:16Z", - "version": "v2.16.0", - "versionExact": "v2.16.0" - }, - { - "checksumSHA1": "jB+fvt3/iJYRDDp6+twGm5gGIXQ=", - "path": "github.com/uber/jaeger-client-go/thrift-gen/zipkincore", - "revision": "2f47546e3facd43297739439600bcf43f44cce5d", - "revisionTime": "2019-03-24T18:29:16Z", - "version": "v2.16.0", - "versionExact": "v2.16.0" - }, - { - "checksumSHA1": "UlW+AcyeItWM0x1W4vT9hbUiOJs=", - "path": "github.com/uber/jaeger-client-go/transport", - "revision": "2f47546e3facd43297739439600bcf43f44cce5d", - "revisionTime": "2019-03-24T18:29:16Z", - "version": "v2.16.0", - "versionExact": "v2.16.0" - }, - { - "checksumSHA1": "DKwwIk9vq53IKO7RKccat9cnqeo=", - "path": "github.com/uber/jaeger-client-go/utils", - "revision": "2f47546e3facd43297739439600bcf43f44cce5d", - "revisionTime": "2019-03-24T18:29:16Z", - "version": "v2.16.0", - "versionExact": "v2.16.0" - }, - { - "checksumSHA1": "gF1WPb3/R8RoZw/wqEQmkwntrQc=", - "path": "github.com/uber/jaeger-lib/metrics", - "revision": "0e30338a695636fe5bcf7301e8030ce8dd2a8530", - "revisionTime": "2018-12-17T19:14:06Z", - "version": "v2.0.0", - "versionExact": "v2.0.0" - }, - { - "checksumSHA1": "8Kj0VH496b0exuyv4wAF4CXa7Y4=", - "path": "github.com/yudai/gojsondiff", - "revision": "081cda2ee95045a2c26da52c2ba80860838549de", - "revisionTime": "2017-06-26T13:12:58Z" - }, - { - "checksumSHA1": "50gdo5Kq0/gEKG1A4agCPOZ26JA=", - "path": "github.com/yudai/gojsondiff/formatter", - "revision": "081cda2ee95045a2c26da52c2ba80860838549de", - "revisionTime": "2017-06-26T13:12:58Z" - }, - { - "checksumSHA1": "5xoBoioS8LWHn9FC0pL+vo7wDjs=", - "path": "github.com/yudai/golcs", - "revision": "ecda9a501e8220fae3b4b600c3db4b0ba22cfc68", - "revisionTime": "2017-03-16T03:48:04Z" - }, - { - "checksumSHA1": "az5f5DY8K9vZizIo4mjHNPAALUA=", - "path": "github.com/z-division/go-zookeeper/zk", - "revision": "6d7457066b9b62f64b9a884659d89ad5c5ad5173", - "revisionTime": "2019-01-28T07:28:38Z" - }, - { - "checksumSHA1": "w+WRj7WpdItd5iR7PcaQQKMrVB0=", - "path": "go.opencensus.io", - "revision": "b4a14686f0a98096416fe1b4cb848e384fb2b22b", - "revisionTime": "2019-07-13T07:22:01Z" - }, - { - "checksumSHA1": "KLZy3Nh+8JlI04JmBa/Jc8fxrVQ=", - "path": "go.opencensus.io/internal", - "revision": "b4a14686f0a98096416fe1b4cb848e384fb2b22b", - "revisionTime": "2019-07-13T07:22:01Z" - }, - { - "checksumSHA1": "Dw3rpna1DwTa7TCzijInKcU49g4=", - "path": "go.opencensus.io/internal/tagencoding", - "revision": "b4a14686f0a98096416fe1b4cb848e384fb2b22b", - "revisionTime": "2019-07-13T07:22:01Z" - }, - { - "checksumSHA1": "r6fbtPwxK4/TYUOWc7y0hXdAG4Q=", - "path": "go.opencensus.io/metric/metricdata", - "revision": "b4a14686f0a98096416fe1b4cb848e384fb2b22b", - "revisionTime": "2019-07-13T07:22:01Z" - }, - { - "checksumSHA1": "kWj13srwY1SH5KgFecPhEfHnzVc=", - "path": "go.opencensus.io/metric/metricproducer", - "revision": "b4a14686f0a98096416fe1b4cb848e384fb2b22b", - "revisionTime": "2019-07-13T07:22:01Z" - }, - { - "checksumSHA1": "kZAPvdijG2qWdS00Vt2NS4kH02k=", - "path": "go.opencensus.io/plugin/ocgrpc", - "revision": "b4a14686f0a98096416fe1b4cb848e384fb2b22b", - "revisionTime": "2019-07-13T07:22:01Z" - }, - { - "checksumSHA1": "Ur+xijNXCbNHR8Q5VjW1czSAabo=", - "path": "go.opencensus.io/plugin/ochttp", - "revision": "b4a14686f0a98096416fe1b4cb848e384fb2b22b", - "revisionTime": "2019-07-13T07:22:01Z" - }, - { - "checksumSHA1": "UZhIoErIy1tKLmVT/5huwlp6KFQ=", - "path": "go.opencensus.io/plugin/ochttp/propagation/b3", - "revision": "b4a14686f0a98096416fe1b4cb848e384fb2b22b", - "revisionTime": "2019-07-13T07:22:01Z" - }, - { - "checksumSHA1": "q+y8X+5nDONIlJlxfkv+OtA18ds=", - "path": "go.opencensus.io/resource", - "revision": "b4a14686f0a98096416fe1b4cb848e384fb2b22b", - "revisionTime": "2019-07-13T07:22:01Z" - }, - { - "checksumSHA1": "Cc4tRuW0IjlfAFY8BcdfMDqG0R8=", - "path": "go.opencensus.io/stats", - "revision": "b4a14686f0a98096416fe1b4cb848e384fb2b22b", - "revisionTime": "2019-07-13T07:22:01Z" - }, - { - "checksumSHA1": "oIo4NRi6AVCfcwVfHzCXAsoZsdI=", - "path": "go.opencensus.io/stats/internal", - "revision": "b4a14686f0a98096416fe1b4cb848e384fb2b22b", - "revisionTime": "2019-07-13T07:22:01Z" - }, - { - "checksumSHA1": "vN9GN1vwD4RU/3ld2tKK00K0i94=", - "path": "go.opencensus.io/stats/view", - "revision": "b4a14686f0a98096416fe1b4cb848e384fb2b22b", - "revisionTime": "2019-07-13T07:22:01Z" - }, - { - "checksumSHA1": "AoqL/neZwl05Fv08vcXXlhbY12g=", - "path": "go.opencensus.io/tag", - "revision": "b4a14686f0a98096416fe1b4cb848e384fb2b22b", - "revisionTime": "2019-07-13T07:22:01Z" - }, - { - "checksumSHA1": "0O3djqX4bcg5O9LZdcinEoYeQKs=", - "path": "go.opencensus.io/trace", - "revision": "b4a14686f0a98096416fe1b4cb848e384fb2b22b", - "revisionTime": "2019-07-13T07:22:01Z" - }, - { - "checksumSHA1": "JkvEb8oMEFjic5K/03Tyr5Lok+w=", - "path": "go.opencensus.io/trace/internal", - "revision": "b4a14686f0a98096416fe1b4cb848e384fb2b22b", - "revisionTime": "2019-07-13T07:22:01Z" - }, - { - "checksumSHA1": "FHJParRi8f1GHO7Cx+lk3bMWBq0=", - "path": "go.opencensus.io/trace/propagation", - "revision": "b4a14686f0a98096416fe1b4cb848e384fb2b22b", - "revisionTime": "2019-07-13T07:22:01Z" - }, - { - "checksumSHA1": "UHbxxaMqpEPsubh8kPwzSlyEwqI=", - "path": "go.opencensus.io/trace/tracestate", - "revision": "b4a14686f0a98096416fe1b4cb848e384fb2b22b", - "revisionTime": "2019-07-13T07:22:01Z" - }, - { - "checksumSHA1": "FwW3Vv4jW0Nv7V2SZC7x/Huj5M4=", - "path": "golang.org/x/crypto/argon2", - "revision": "b8fe1690c61389d7d2a8074a507d1d40c5d30448", - "revisionTime": "2019-01-30T22:18:58Z" - }, - { - "checksumSHA1": "eaK7NuGdfEVypOnqYniZSuF2S6s=", - "path": "golang.org/x/crypto/blake2b", - "revision": "b8fe1690c61389d7d2a8074a507d1d40c5d30448", - "revisionTime": "2019-01-30T22:18:58Z" - }, - { - "checksumSHA1": "N5fb5y92DFIP+wUhi1rSwPp9vyk=", - "path": "golang.org/x/crypto/ssh/terminal", - "revision": "1777f3ba8c1fed80fcaec3317e3aaa4f627764d2", - "revisionTime": "2016-03-18T12:12:46Z" - }, - { - "checksumSHA1": "GtamqiJoL7PGHsN454AoffBFMa8=", - "path": "golang.org/x/net/context", - "revision": "adae6a3d119ae4890b46832a2e88a95adc62b8e7", - "revisionTime": "2018-11-14T21:44:15Z" - }, - { - "checksumSHA1": "EJMLw8rk55bsqmIpSMtVORJpSGo=", - "path": "golang.org/x/net/context/ctxhttp", - "revision": "fb93926129b8ec0056f2f458b1f519654814edf0", - "revisionTime": "2016-04-12T22:48:50Z" - }, - { - "checksumSHA1": "pCY4YtdNKVBYRbNvODjx8hj0hIs=", - "path": "golang.org/x/net/http/httpguts", - "revision": "adae6a3d119ae4890b46832a2e88a95adc62b8e7", - "revisionTime": "2018-11-14T21:44:15Z" - }, - { - "checksumSHA1": "QmfYRV9T2HIj1cvl2ZQCd6bXXKo=", - "path": "golang.org/x/net/http2", - "revision": "adae6a3d119ae4890b46832a2e88a95adc62b8e7", - "revisionTime": "2018-11-14T21:44:15Z" - }, - { - "checksumSHA1": "KZniwnfpWkaTPhUQDUTvgex/7y0=", - "path": "golang.org/x/net/http2/hpack", - "revision": "adae6a3d119ae4890b46832a2e88a95adc62b8e7", - "revisionTime": "2018-11-14T21:44:15Z" - }, - { - "checksumSHA1": "RcrB7tgYS/GMW4QrwVdMOTNqIU8=", - "path": "golang.org/x/net/idna", - "revision": "adae6a3d119ae4890b46832a2e88a95adc62b8e7", - "revisionTime": "2018-11-14T21:44:15Z" - }, - { - "checksumSHA1": "UxahDzW2v4mf/+aFxruuupaoIwo=", - "path": "golang.org/x/net/internal/timeseries", - "revision": "adae6a3d119ae4890b46832a2e88a95adc62b8e7", - "revisionTime": "2018-11-14T21:44:15Z" - }, - { - "checksumSHA1": "3xyuaSNmClqG4YWC7g0isQIbUTc=", - "path": "golang.org/x/net/lex/httplex", - "revision": "5f8847ae0d0e90b6a9dc8148e7ad616874625171", - "revisionTime": "2017-06-23T17:10:45Z" - }, - { - "checksumSHA1": "j6leSoJatxWHJGLjRxIjZ8GbaDQ=", - "path": "golang.org/x/net/publicsuffix", - "revision": "65e2d4e15006aab9813ff8769e768bbf4bb667a0", - "revisionTime": "2019-02-01T23:59:58Z" - }, - { - "checksumSHA1": "4vGl3N46SAJwQl/uSlQvZQvc734=", - "path": "golang.org/x/net/trace", - "revision": "adae6a3d119ae4890b46832a2e88a95adc62b8e7", - "revisionTime": "2018-11-14T21:44:15Z" - }, - { - "checksumSHA1": "uRlaEkyMCxyjj57KBa81GEfvCwg=", - "path": "golang.org/x/oauth2", - "revision": "0f29369cfe4552d0e4bcddc57cc75f4d7e672a33", - "revisionTime": "2019-05-07T23:52:07Z" - }, - { - "checksumSHA1": "UmEcak5EiFA6UpbMnlfkQzHyw3M=", - "path": "golang.org/x/oauth2/google", - "revision": "0f29369cfe4552d0e4bcddc57cc75f4d7e672a33", - "revisionTime": "2019-05-07T23:52:07Z" - }, - { - "checksumSHA1": "+9KSfsjsC3F2CldDDb+Dt+d/H3Q=", - "path": "golang.org/x/oauth2/internal", - "revision": "0f29369cfe4552d0e4bcddc57cc75f4d7e672a33", - "revisionTime": "2019-05-07T23:52:07Z" - }, - { - "checksumSHA1": "huVltYnXdRFDJLgp/ZP9IALzG7g=", - "path": "golang.org/x/oauth2/jws", - "revision": "0f29369cfe4552d0e4bcddc57cc75f4d7e672a33", - "revisionTime": "2019-05-07T23:52:07Z" - }, - { - "checksumSHA1": "HGS6ig1GfcE2CBHBsi965ZVn9Xw=", - "path": "golang.org/x/oauth2/jwt", - "revision": "0f29369cfe4552d0e4bcddc57cc75f4d7e672a33", - "revisionTime": "2019-05-07T23:52:07Z" - }, - { - "checksumSHA1": "1CmUDjhZlyKZcbLYlWI7cRzK3fI=", - "path": "golang.org/x/sys/cpu", - "revision": "41f3e6584952bb034a481797859f6ab34b6803bd", - "revisionTime": "2019-02-04T12:38:20Z" - }, - { - "checksumSHA1": "QmmEQv1jLvjlVGPsWewqeNYNoyk=", - "path": "golang.org/x/sys/unix", - "revision": "62eef0e2fa9b2c385f7b2778e763486da6880d37", - "revisionTime": "2018-11-22T14:36:24Z" - }, - { - "checksumSHA1": "Gwx30TD3lMSgskBCmXTDXbICPRQ=", - "path": "golang.org/x/text/collate", - "revision": "fc7fa097411d30e6708badff276c4c164425590c", - "revisionTime": "2017-03-23T10:04:54Z" - }, - { - "checksumSHA1": "gRurdsue4RAi2xYzy89YDzO2c2I=", - "path": "golang.org/x/text/collate/build", - "revision": "fc7fa097411d30e6708badff276c4c164425590c", - "revisionTime": "2017-03-23T10:04:54Z" - }, - { - "checksumSHA1": "fM/n4f1c26uIh3wB9g+1flJkSAo=", - "path": "golang.org/x/text/internal/colltab", - "revision": "fc7fa097411d30e6708badff276c4c164425590c", - "revisionTime": "2017-03-23T10:04:54Z" - }, - { - "checksumSHA1": "ZQdHbB9VYCXwQ+9/CmZPhJv0+SM=", - "path": "golang.org/x/text/internal/gen", - "revision": "fc7fa097411d30e6708badff276c4c164425590c", - "revisionTime": "2017-03-23T10:04:54Z" - }, - { - "checksumSHA1": "hyNCcTwMQnV6/MK8uUW9E5H0J0M=", - "path": "golang.org/x/text/internal/tag", - "revision": "fc7fa097411d30e6708badff276c4c164425590c", - "revisionTime": "2017-03-23T10:04:54Z" - }, - { - "checksumSHA1": "47nwiUyVBY2RKoEGXmCSvusY4Js=", - "path": "golang.org/x/text/internal/triegen", - "revision": "fc7fa097411d30e6708badff276c4c164425590c", - "revisionTime": "2017-03-23T10:04:54Z" - }, - { - "checksumSHA1": "Yd5wMObzagIfCiKLpZbtBIrOUA4=", - "path": "golang.org/x/text/internal/ucd", - "revision": "fc7fa097411d30e6708badff276c4c164425590c", - "revisionTime": "2017-03-23T10:04:54Z" - }, - { - "checksumSHA1": "ckawpDnd22U/0HjSPKF4yY5pIeg=", - "path": "golang.org/x/text/language", - "revision": "fc7fa097411d30e6708badff276c4c164425590c", - "revisionTime": "2017-03-23T10:04:54Z" - }, - { - "checksumSHA1": "CbpjEkkOeh0fdM/V8xKDdI0AA88=", - "path": "golang.org/x/text/secure/bidirule", - "revision": "6f44c5a2ea40ee3593d98cdcc905cc1fdaa660e2", - "revisionTime": "2018-10-29T18:00:05Z" - }, - { - "checksumSHA1": "o3YChxWLvyCmkAn/ZNBj9HC9zKw=", - "path": "golang.org/x/text/transform", - "revision": "6f44c5a2ea40ee3593d98cdcc905cc1fdaa660e2", - "revisionTime": "2018-10-29T18:00:05Z" - }, - { - "checksumSHA1": "qjFbU4RWY+Caxaa5/TlMJW82E+A=", - "path": "golang.org/x/text/unicode/bidi", - "revision": "6f44c5a2ea40ee3593d98cdcc905cc1fdaa660e2", - "revisionTime": "2018-10-29T18:00:05Z" - }, - { - "checksumSHA1": "+U+vu5UQXoIB4egXy7uX3GYBxVo=", - "path": "golang.org/x/text/unicode/cldr", - "revision": "fc7fa097411d30e6708badff276c4c164425590c", - "revisionTime": "2017-03-23T10:04:54Z" - }, - { - "checksumSHA1": "vAScJLvb0ucuuclyN9vmJUyWTBA=", - "path": "golang.org/x/text/unicode/norm", - "revision": "6f44c5a2ea40ee3593d98cdcc905cc1fdaa660e2", - "revisionTime": "2018-10-29T18:00:05Z" - }, - { - "checksumSHA1": "bLoGyjxHeYpHKEzU1g9f3m5qsnQ=", - "path": "golang.org/x/text/unicode/rangetable", - "revision": "4e9ab9ee170f2a39bd66c92b3e0a47ff47a4bc77", - "revisionTime": "2017-06-09T11:26:06Z" - }, - { - "checksumSHA1": "eFQDEix/mGnhwnFu/Hq63zMfrX8=", - "path": "golang.org/x/time/rate", - "revision": "f51c12702a4d776e4c1fa9b0fabab841babae631", - "revisionTime": "2016-10-28T04:02:39Z" - }, - { - "checksumSHA1": "FhzGDPlkW5SaQGtSgKnjQAiYVk0=", - "path": "google.golang.org/api/gensupport", - "revision": "02490b97dff7cfde1995bd77de808fd27053bc87", - "revisionTime": "2019-06-24T17:16:18Z", - "version": "v0.7.0", - "versionExact": "v0.7.0" - }, - { - "checksumSHA1": "YIDE68w/xMptf6Nu9hHiOwXOvho=", - "path": "google.golang.org/api/googleapi", - "revision": "02490b97dff7cfde1995bd77de808fd27053bc87", - "revisionTime": "2019-06-24T17:16:18Z", - "version": "v0.7.0", - "versionExact": "v0.7.0" - }, - { - "checksumSHA1": "1K0JxrUfDqAB3MyRiU1LKjfHyf4=", - "path": "google.golang.org/api/googleapi/internal/uritemplates", - "revision": "02490b97dff7cfde1995bd77de808fd27053bc87", - "revisionTime": "2019-06-24T17:16:18Z", - "version": "v0.7.0", - "versionExact": "v0.7.0" - }, - { - "checksumSHA1": "Mr2fXhMRzlQCgANFm91s536pG7E=", - "path": "google.golang.org/api/googleapi/transport", - "revision": "02490b97dff7cfde1995bd77de808fd27053bc87", - "revisionTime": "2019-06-24T17:16:18Z", - "version": "v0.7.0", - "versionExact": "v0.7.0" - }, - { - "checksumSHA1": "6Tg4dDJKzoSrAA5beVknvnjluOU=", - "path": "google.golang.org/api/internal", - "revision": "02490b97dff7cfde1995bd77de808fd27053bc87", - "revisionTime": "2019-06-24T17:16:18Z", - "version": "v0.7.0", - "versionExact": "v0.7.0" - }, - { - "checksumSHA1": "zh9AcT6oNvhnOqb7w7njY48TkvI=", - "path": "google.golang.org/api/iterator", - "revision": "02490b97dff7cfde1995bd77de808fd27053bc87", - "revisionTime": "2019-06-24T17:16:18Z", - "version": "v0.7.0", - "versionExact": "v0.7.0" - }, - { - "checksumSHA1": "XdTB13Pxzd95rhckAEBpCeMp69M=", - "path": "google.golang.org/api/iterator/testing", - "revision": "02490b97dff7cfde1995bd77de808fd27053bc87", - "revisionTime": "2019-06-24T17:16:18Z", - "version": "v0.7.0", - "versionExact": "v0.7.0" - }, - { - "checksumSHA1": "2AyxThTPscWdy49fGsU2tg0Uyw8=", - "path": "google.golang.org/api/option", - "revision": "02490b97dff7cfde1995bd77de808fd27053bc87", - "revisionTime": "2019-06-24T17:16:18Z", - "version": "v0.7.0", - "versionExact": "v0.7.0" - }, - { - "checksumSHA1": "Aka6Sle3vs6xGP70PADl9lAlZIE=", - "path": "google.golang.org/api/storage/v1", - "revision": "02490b97dff7cfde1995bd77de808fd27053bc87", - "revisionTime": "2019-06-24T17:16:18Z", - "version": "v0.7.0", - "versionExact": "v0.7.0" - }, - { - "checksumSHA1": "hOQM3ns9t81o566ge8UNFEtoXX8=", - "path": "google.golang.org/api/transport", - "revision": "02490b97dff7cfde1995bd77de808fd27053bc87", - "revisionTime": "2019-06-24T17:16:18Z", - "version": "v0.7.0", - "versionExact": "v0.7.0" - }, - { - "checksumSHA1": "XeonlHuXpmHUQDqIK2qJ/DSKg0o=", - "path": "google.golang.org/api/transport/grpc", - "revision": "02490b97dff7cfde1995bd77de808fd27053bc87", - "revisionTime": "2019-06-24T17:16:18Z", - "version": "v0.7.0", - "versionExact": "v0.7.0" - }, - { - "checksumSHA1": "WzZfHJ4G6jO/qf3n6DI9a9awJQk=", - "path": "google.golang.org/api/transport/http", - "revision": "02490b97dff7cfde1995bd77de808fd27053bc87", - "revisionTime": "2019-06-24T17:16:18Z", - "version": "v0.7.0", - "versionExact": "v0.7.0" - }, - { - "checksumSHA1": "sJcKCvjPtoysqyelsB2CQzC5oQI=", - "path": "google.golang.org/api/transport/http/internal/propagation", - "revision": "02490b97dff7cfde1995bd77de808fd27053bc87", - "revisionTime": "2019-06-24T17:16:18Z", - "version": "v0.7.0", - "versionExact": "v0.7.0" - }, - { - "checksumSHA1": "buWXkeU6VNtym88sZ7lKJvsCVXk=", - "path": "google.golang.org/appengine", - "revision": "54a98f90d1c46b7731eb8fb305d2a321c30ef610", - "revisionTime": "2019-02-15T20:43:44Z", - "version": "v1.5.0", - "versionExact": "v1.5.0" - }, - { - "checksumSHA1": "61EFkyXUswt3Su1R/C8JHJWF+jw=", - "path": "google.golang.org/appengine/internal", - "revision": "54a98f90d1c46b7731eb8fb305d2a321c30ef610", - "revisionTime": "2019-02-15T20:43:44Z", - "version": "v1.5.0", - "versionExact": "v1.5.0" - }, - { - "checksumSHA1": "GyzSDzUj78G9nyNhmlFGg5IufHc=", - "path": "google.golang.org/appengine/internal/app_identity", - "revision": "54a98f90d1c46b7731eb8fb305d2a321c30ef610", - "revisionTime": "2019-02-15T20:43:44Z", - "version": "v1.5.0", - "versionExact": "v1.5.0" - }, - { - "checksumSHA1": "5PakGXEgSbyFptkhGO8MnGf7uH0=", - "path": "google.golang.org/appengine/internal/base", - "revision": "54a98f90d1c46b7731eb8fb305d2a321c30ef610", - "revisionTime": "2019-02-15T20:43:44Z", - "version": "v1.5.0", - "versionExact": "v1.5.0" - }, - { - "checksumSHA1": "3DZ+Ah5hFQb1/nh1+li2VE+kkfk=", - "path": "google.golang.org/appengine/internal/datastore", - "revision": "54a98f90d1c46b7731eb8fb305d2a321c30ef610", - "revisionTime": "2019-02-15T20:43:44Z", - "version": "v1.5.0", - "versionExact": "v1.5.0" - }, - { - "checksumSHA1": "HJQ4JM9YWfwIe4vmAgXC7J/1T3E=", - "path": "google.golang.org/appengine/internal/log", - "revision": "54a98f90d1c46b7731eb8fb305d2a321c30ef610", - "revisionTime": "2019-02-15T20:43:44Z", - "version": "v1.5.0", - "versionExact": "v1.5.0" - }, - { - "checksumSHA1": "rPcVt7Td1StpB6Z9DiShhu753PM=", - "path": "google.golang.org/appengine/internal/modules", - "revision": "54a98f90d1c46b7731eb8fb305d2a321c30ef610", - "revisionTime": "2019-02-15T20:43:44Z", - "version": "v1.5.0", - "versionExact": "v1.5.0" - }, - { - "checksumSHA1": "hApgRLSl7w9XG2waJxdH/o0A398=", - "path": "google.golang.org/appengine/internal/remote_api", - "revision": "54a98f90d1c46b7731eb8fb305d2a321c30ef610", - "revisionTime": "2019-02-15T20:43:44Z", - "version": "v1.5.0", - "versionExact": "v1.5.0" - }, - { - "checksumSHA1": "GlPZsxfa/OYvumlfU8+2j4cVai8=", - "path": "google.golang.org/genproto/googleapis/api/annotations", - "revision": "fa694d86fc64c7654a660f8908de4e879866748d", - "revisionTime": "2019-08-01T16:59:51Z" - }, - { - "checksumSHA1": "nTQH9H1cWFc4Ft8sJylUT9ANl/Y=", - "path": "google.golang.org/genproto/googleapis/iam/v1", - "revision": "fa694d86fc64c7654a660f8908de4e879866748d", - "revisionTime": "2019-08-01T16:59:51Z" - }, - { - "checksumSHA1": "EOkBjXBkCQcsEf9fk2KOQZcJO08=", - "path": "google.golang.org/genproto/googleapis/rpc/code", - "revision": "fa694d86fc64c7654a660f8908de4e879866748d", - "revisionTime": "2019-08-01T16:59:51Z" - }, - { - "checksumSHA1": "dU5fToNngC22+3DsebkdYv+T3jE=", - "path": "google.golang.org/genproto/googleapis/rpc/status", - "revision": "fa694d86fc64c7654a660f8908de4e879866748d", - "revisionTime": "2019-08-01T16:59:51Z" - }, - { - "checksumSHA1": "F1znYp6CXz3gZ0WGdy89d7jZgP4=", - "path": "google.golang.org/genproto/googleapis/type/expr", - "revision": "fa694d86fc64c7654a660f8908de4e879866748d", - "revisionTime": "2019-08-01T16:59:51Z" - }, - { - "checksumSHA1": "O6SQTcVdhL+4betKp/7ketCc/AU=", - "path": "google.golang.org/grpc", - "revision": "2e463a05d100327ca47ac218281906921038fd95", - "revisionTime": "2018-10-23T17:37:47Z", - "version": "v1.16.0", - "versionExact": "v1.16.0" - }, - { - "checksumSHA1": "9KEKKMRAdFnz2sMBXbb33ZLS8Oo=", - "path": "google.golang.org/grpc/balancer", - "revision": "2e463a05d100327ca47ac218281906921038fd95", - "revisionTime": "2018-10-23T17:37:47Z", - "version": "v1.16.0", - "versionExact": "v1.16.0" - }, - { - "checksumSHA1": "lw+L836hLeH8+//le+C+ycddCCU=", - "path": "google.golang.org/grpc/balancer/base", - "revision": "2e463a05d100327ca47ac218281906921038fd95", - "revisionTime": "2018-10-23T17:37:47Z", - "version": "v1.16.0", - "versionExact": "v1.16.0" - }, - { - "checksumSHA1": "ZD8cJs3NtFy3pzofoTThBvVVdKU=", - "path": "google.golang.org/grpc/balancer/grpclb", - "revision": "2e463a05d100327ca47ac218281906921038fd95", - "revisionTime": "2018-10-23T17:37:47Z", - "version": "v1.16.0", - "versionExact": "v1.16.0" - }, - { - "checksumSHA1": "CWf3yHL+DCM8pZETYCGA70C4JGM=", - "path": "google.golang.org/grpc/balancer/grpclb/grpc_lb_v1", - "revision": "2e463a05d100327ca47ac218281906921038fd95", - "revisionTime": "2018-10-23T17:37:47Z", - "version": "v1.16.0", - "versionExact": "v1.16.0" - }, - { - "checksumSHA1": "DJ1AtOk4Pu7bqtUMob95Hw8HPNw=", - "path": "google.golang.org/grpc/balancer/roundrobin", - "revision": "2e463a05d100327ca47ac218281906921038fd95", - "revisionTime": "2018-10-23T17:37:47Z", - "version": "v1.16.0", - "versionExact": "v1.16.0" - }, - { - "checksumSHA1": "R3tuACGAPyK4lr+oSNt1saUzC0M=", - "path": "google.golang.org/grpc/codes", - "revision": "2e463a05d100327ca47ac218281906921038fd95", - "revisionTime": "2018-10-23T17:37:47Z", - "version": "v1.16.0", - "versionExact": "v1.16.0" - }, - { - "checksumSHA1": "XH2WYcDNwVO47zYShREJjcYXm0Y=", - "path": "google.golang.org/grpc/connectivity", - "revision": "2e463a05d100327ca47ac218281906921038fd95", - "revisionTime": "2018-10-23T17:37:47Z", - "version": "v1.16.0", - "versionExact": "v1.16.0" - }, - { - "checksumSHA1": "5r6NIQY1c3NjwLtxUOo/BcUOqFo=", - "path": "google.golang.org/grpc/credentials", - "revision": "2e463a05d100327ca47ac218281906921038fd95", - "revisionTime": "2018-10-23T17:37:47Z", - "version": "v1.16.0", - "versionExact": "v1.16.0" - }, - { - "checksumSHA1": "RqDVFWVRXNIzSEge/L8JSMskEME=", - "path": "google.golang.org/grpc/credentials/alts", - "revision": "2e463a05d100327ca47ac218281906921038fd95", - "revisionTime": "2018-10-23T17:37:47Z", - "version": "v1.16.0", - "versionExact": "v1.16.0" - }, - { - "checksumSHA1": "qAUIOU0aukDblUKBw9Pbjzc+nW8=", - "path": "google.golang.org/grpc/credentials/alts/internal", - "revision": "2e463a05d100327ca47ac218281906921038fd95", - "revisionTime": "2018-10-23T17:37:47Z", - "version": "v1.16.0", - "versionExact": "v1.16.0" - }, - { - "checksumSHA1": "PTVv5w1hd88sHf2TJbctBasS4ck=", - "path": "google.golang.org/grpc/credentials/alts/internal/authinfo", - "revision": "2e463a05d100327ca47ac218281906921038fd95", - "revisionTime": "2018-10-23T17:37:47Z", - "version": "v1.16.0", - "versionExact": "v1.16.0" - }, - { - "checksumSHA1": "/s6U8ulRJiogFjFygs450dOeIoI=", - "path": "google.golang.org/grpc/credentials/alts/internal/conn", - "revision": "2e463a05d100327ca47ac218281906921038fd95", - "revisionTime": "2018-10-23T17:37:47Z", - "version": "v1.16.0", - "versionExact": "v1.16.0" - }, - { - "checksumSHA1": "znhrvWfbdiviJiZpekYHOi4TRmw=", - "path": "google.golang.org/grpc/credentials/alts/internal/handshaker", - "revision": "2e463a05d100327ca47ac218281906921038fd95", - "revisionTime": "2018-10-23T17:37:47Z", - "version": "v1.16.0", - "versionExact": "v1.16.0" - }, - { - "checksumSHA1": "CliKuySSTAK7m5iZuEA3fRiLHjg=", - "path": "google.golang.org/grpc/credentials/alts/internal/handshaker/service", - "revision": "2e463a05d100327ca47ac218281906921038fd95", - "revisionTime": "2018-10-23T17:37:47Z", - "version": "v1.16.0", - "versionExact": "v1.16.0" - }, - { - "checksumSHA1": "3/WS7uTk/B23ijy0PoHmIS/A76M=", - "path": "google.golang.org/grpc/credentials/alts/internal/proto/grpc_gcp", - "revision": "2e463a05d100327ca47ac218281906921038fd95", - "revisionTime": "2018-10-23T17:37:47Z", - "version": "v1.16.0", - "versionExact": "v1.16.0" - }, - { - "checksumSHA1": "KreBPF6lZnpT8psfiyRson0C9lI=", - "path": "google.golang.org/grpc/credentials/google", - "revision": "2e463a05d100327ca47ac218281906921038fd95", - "revisionTime": "2018-10-23T17:37:47Z", - "version": "v1.16.0", - "versionExact": "v1.16.0" - }, - { - "checksumSHA1": "QbufP1o0bXrtd5XecqdRCK/Vl0M=", - "path": "google.golang.org/grpc/credentials/oauth", - "revision": "8dea3dc473e90c8179e519d91302d0597c0ca1d1", - "revisionTime": "2018-09-11T17:48:51Z", - "version": "v1.15.0", - "versionExact": "v1.15.0" - }, - { - "checksumSHA1": "cfLb+pzWB+Glwp82rgfcEST1mv8=", - "path": "google.golang.org/grpc/encoding", - "revision": "2e463a05d100327ca47ac218281906921038fd95", - "revisionTime": "2018-10-23T17:37:47Z", - "version": "v1.16.0", - "versionExact": "v1.16.0" - }, - { - "checksumSHA1": "LKKkn7EYA+Do9Qwb2/SUKLFNxoo=", - "path": "google.golang.org/grpc/encoding/proto", - "revision": "2e463a05d100327ca47ac218281906921038fd95", - "revisionTime": "2018-10-23T17:37:47Z", - "version": "v1.16.0", - "versionExact": "v1.16.0" - }, - { - "checksumSHA1": "H7SuPUqbPcdbNqgl+k3ohuwMAwE=", - "path": "google.golang.org/grpc/grpclb/grpc_lb_v1/messages", - "revision": "d89cded64628466c4ab532d1f0ba5c220459ebe8", - "revisionTime": "2018-04-04T21:41:50Z", - "version": "v1.16.0", - "versionExact": "v1.16.0" - }, - { - "checksumSHA1": "ZPPSFisPDz2ANO4FBZIft+fRxyk=", - "path": "google.golang.org/grpc/grpclog", - "revision": "2e463a05d100327ca47ac218281906921038fd95", - "revisionTime": "2018-10-23T17:37:47Z", - "version": "v1.16.0", - "versionExact": "v1.16.0" - }, - { - "checksumSHA1": "QyasSHZlgle+PHSIQ2/p+fr+ihY=", - "path": "google.golang.org/grpc/grpclog/glogger", - "revision": "d89cded64628466c4ab532d1f0ba5c220459ebe8", - "revisionTime": "2018-04-04T21:41:50Z", - "version": "v1.11.2", - "versionExact": "v1.11.2" - }, - { - "checksumSHA1": "LVvnj/+AVrdZMDw0DZ8D/vI24+M=", - "path": "google.golang.org/grpc/internal", - "revision": "2e463a05d100327ca47ac218281906921038fd95", - "revisionTime": "2018-10-23T17:37:47Z", - "version": "v1.16.0", - "versionExact": "v1.16.0" - }, - { - "checksumSHA1": "uDJA7QK2iGnEwbd9TPqkLaM+xuU=", - "path": "google.golang.org/grpc/internal/backoff", - "revision": "2e463a05d100327ca47ac218281906921038fd95", - "revisionTime": "2018-10-23T17:37:47Z", - "version": "v1.16.0", - "versionExact": "v1.16.0" - }, - { - "checksumSHA1": "V6eyqZJfYh+cX+I/AxPVjkQLjTM=", - "path": "google.golang.org/grpc/internal/channelz", - "revision": "2e463a05d100327ca47ac218281906921038fd95", - "revisionTime": "2018-10-23T17:37:47Z", - "version": "v1.16.0", - "versionExact": "v1.16.0" - }, - { - "checksumSHA1": "5dFUCEaPjKwza9kwKqgljp8ckU4=", - "path": "google.golang.org/grpc/internal/envconfig", - "revision": "2e463a05d100327ca47ac218281906921038fd95", - "revisionTime": "2018-10-23T17:37:47Z", - "version": "v1.16.0", - "versionExact": "v1.16.0" - }, - { - "checksumSHA1": "70gndc/uHwyAl3D45zqp7vyHWlo=", - "path": "google.golang.org/grpc/internal/grpcrand", - "revision": "2e463a05d100327ca47ac218281906921038fd95", - "revisionTime": "2018-10-23T17:37:47Z", - "version": "v1.16.0", - "versionExact": "v1.16.0" - }, - { - "checksumSHA1": "0r7S4jTgUIatKqL/8ra0J7Q5iO0=", - "path": "google.golang.org/grpc/internal/transport", - "revision": "2e463a05d100327ca47ac218281906921038fd95", - "revisionTime": "2018-10-23T17:37:47Z", - "version": "v1.16.0", - "versionExact": "v1.16.0" - }, - { - "checksumSHA1": "350+v+N+AuknxomqjND19nR969g=", - "path": "google.golang.org/grpc/keepalive", - "revision": "2e463a05d100327ca47ac218281906921038fd95", - "revisionTime": "2018-10-23T17:37:47Z", - "version": "v1.16.0", - "versionExact": "v1.16.0" - }, - { - "checksumSHA1": "OjIAi5AzqlQ7kLtdAyjvdgMf6hc=", - "path": "google.golang.org/grpc/metadata", - "revision": "2e463a05d100327ca47ac218281906921038fd95", - "revisionTime": "2018-10-23T17:37:47Z", - "version": "v1.16.0", - "versionExact": "v1.16.0" - }, - { - "checksumSHA1": "VvGBoawND0urmYDy11FT+U1IHtU=", - "path": "google.golang.org/grpc/naming", - "revision": "2e463a05d100327ca47ac218281906921038fd95", - "revisionTime": "2018-10-23T17:37:47Z", - "version": "v1.16.0", - "versionExact": "v1.16.0" - }, - { - "checksumSHA1": "n5EgDdBqFMa2KQFhtl+FF/4gIFo=", - "path": "google.golang.org/grpc/peer", - "revision": "2e463a05d100327ca47ac218281906921038fd95", - "revisionTime": "2018-10-23T17:37:47Z", - "version": "v1.16.0", - "versionExact": "v1.16.0" - }, - { - "checksumSHA1": "GEq6wwE1qWLmkaM02SjxBmmnHDo=", - "path": "google.golang.org/grpc/resolver", - "revision": "2e463a05d100327ca47ac218281906921038fd95", - "revisionTime": "2018-10-23T17:37:47Z", - "version": "v1.16.0", - "versionExact": "v1.16.0" - }, - { - "checksumSHA1": "grHAHa6Fi3WBsXJpmlEOlRbWWVg=", - "path": "google.golang.org/grpc/resolver/dns", - "revision": "2e463a05d100327ca47ac218281906921038fd95", - "revisionTime": "2018-10-23T17:37:47Z", - "version": "v1.16.0", - "versionExact": "v1.16.0" - }, - { - "checksumSHA1": "zs9M4xE8Lyg4wvuYvR00XoBxmuw=", - "path": "google.golang.org/grpc/resolver/passthrough", - "revision": "2e463a05d100327ca47ac218281906921038fd95", - "revisionTime": "2018-10-23T17:37:47Z", - "version": "v1.16.0", - "versionExact": "v1.16.0" - }, - { - "checksumSHA1": "YclPgme2gT3S0hTkHVdE1zAxJdo=", - "path": "google.golang.org/grpc/stats", - "revision": "2e463a05d100327ca47ac218281906921038fd95", - "revisionTime": "2018-10-23T17:37:47Z", - "version": "v1.16.0", - "versionExact": "v1.16.0" - }, - { - "checksumSHA1": "hFyBO5vgsMamKhUOSyPCqROk1vo=", - "path": "google.golang.org/grpc/status", - "revision": "2e463a05d100327ca47ac218281906921038fd95", - "revisionTime": "2018-10-23T17:37:47Z", - "version": "v1.16.0", - "versionExact": "v1.16.0" - }, - { - "checksumSHA1": "qvArRhlrww5WvRmbyMF2mUfbJew=", - "path": "google.golang.org/grpc/tap", - "revision": "2e463a05d100327ca47ac218281906921038fd95", - "revisionTime": "2018-10-23T17:37:47Z", - "version": "v1.16.0", - "versionExact": "v1.16.0" - }, - { - "checksumSHA1": "sg7RY87LaWXaZMj0cuLQQaJJQYo=", - "path": "google.golang.org/grpc/transport", - "revision": "d89cded64628466c4ab532d1f0ba5c220459ebe8", - "revisionTime": "2018-04-04T21:41:50Z", - "version": "v1.16.0", - "versionExact": "v1.16.0" - }, - { - "checksumSHA1": "wSu8owMAP7GixsYoSZ4CmKUVhnU=", - "path": "gopkg.in/asn1-ber.v1", - "revision": "4e86f4367175e39f69d9358a5f17b4dda270378d", - "revisionTime": "2015-09-24T05:17:56Z" - }, - { - "checksumSHA1": "8yg3QdSXVEmuHm2CgWXEMFN3K6Q=", - "path": "gopkg.in/ini.v1", - "revision": "6ed8d5f64cd79a498d1f3fab5880cc376ce41bbe", - "revisionTime": "2019-01-03T01:53:35Z" - }, - { - "checksumSHA1": "itYnRitfdzJjy2mZlvJ+hCJZvtY=", - "path": "gopkg.in/ldap.v2", - "revision": "8168ee085ee43257585e50c6441aadf54ecb2c9f", - "revisionTime": "2016-12-01T20:47:33Z" - }, - { - "checksumSHA1": "12GqsW8PiRPnezDDy0v4brZrndM=", - "path": "gopkg.in/yaml.v2", - "revision": "a5b47d31c556af34a302ce5d659e6fea44d90de0", - "revisionTime": "2016-09-28T15:37:09Z" - } - ], - "rootPath": "vitess.io/vitess" -} diff --git a/web/vtctld2/app/index.html b/web/vtctld2/app/index.html index 70ef85f14ed..2b336f6061f 100644 --- a/web/vtctld2/app/index.html +++ b/web/vtctld2/app/index.html @@ -27,5 +27,5 @@ Loading... - + diff --git a/web/vtctld2/app/inline.js b/web/vtctld2/app/inline.js index 2ac73298ee9..0284dd00f11 100644 --- a/web/vtctld2/app/inline.js +++ b/web/vtctld2/app/inline.js @@ -1 +1 @@ -!function(e){function __webpack_require__(r){if(t[r])return t[r].exports;var n=t[r]={i:r,l:!1,exports:{}};return e[r].call(n.exports,n,n.exports,__webpack_require__),n.l=!0,n.exports}var r=window.webpackJsonp;window.webpackJsonp=function(t,o,c){for(var _,a,i,u=0,p=[];u1;){var o=r.shift();i=i.hasOwnProperty(o)&&isPresent(i[o])?i[o]:i[o]={}}void 0!==i&&null!==i||(i={}),i[r.shift()]=n}function getSymbolIterator(){if(isBlank(h))if(isPresent(n.Symbol)&&isPresent(Symbol.iterator))h=Symbol.iterator;else for(var e=Object.getOwnPropertyNames(Map.prototype),t=0;t=0&&e[r]==t;r--)n--;e=e.substring(0,n)}return e},StringWrapper.replace=function(e,t,n){return e.replace(t,n)},StringWrapper.replaceAll=function(e,t,n){return e.replace(t,n)},StringWrapper.slice=function(e,t,n){return void 0===t&&(t=0),void 0===n&&(n=null),e.slice(t,null===n?void 0:n)},StringWrapper.replaceAllMapped=function(e,t,n){return e.replace(t,function(){for(var e=[],t=0;tt?1:0},StringWrapper}();t.StringWrapper=s;var a=function(){function StringJoiner(e){void 0===e&&(e=[]),this.parts=e}return StringJoiner.prototype.add=function(e){this.parts.push(e)},StringJoiner.prototype.toString=function(){return this.parts.join("")},StringJoiner}();t.StringJoiner=a;var l=function(e){function NumberParseError(t){e.call(this),this.message=t}return r(NumberParseError,e),NumberParseError.prototype.toString=function(){return this.message},NumberParseError}(Error);t.NumberParseError=l;var c=function(){function NumberWrapper(){}return NumberWrapper.toFixed=function(e,t){return e.toFixed(t)},NumberWrapper.equal=function(e,t){return e===t},NumberWrapper.parseIntAutoRadix=function(e){var t=parseInt(e);if(isNaN(t))throw new l("Invalid integer literal when parsing "+e);return t},NumberWrapper.parseInt=function(e,t){if(10==t){if(/^(\-|\+)?[0-9]+$/.test(e))return parseInt(e,t)}else if(16==t){if(/^(\-|\+)?[0-9ABCDEFabcdef]+$/.test(e))return parseInt(e,t)}else{var n=parseInt(e,t);if(!isNaN(n))return n}throw new l("Invalid integer literal when parsing "+e+" in base "+t)},NumberWrapper.parseFloat=function(e){return parseFloat(e)},Object.defineProperty(NumberWrapper,"NaN",{get:function(){return NaN},enumerable:!0,configurable:!0}),NumberWrapper.isNumeric=function(e){return!isNaN(e-parseFloat(e))},NumberWrapper.isNaN=function(e){return isNaN(e)},NumberWrapper.isInteger=function(e){return Number.isInteger(e)},NumberWrapper}();t.NumberWrapper=c,t.RegExp=i.RegExp;var u=function(){function FunctionWrapper(){}return FunctionWrapper.apply=function(e,t){return e.apply(null,t)},FunctionWrapper.bind=function(e,t){return e.bind(t)},FunctionWrapper}();t.FunctionWrapper=u,t.looseIdentical=looseIdentical,t.getMapKey=getMapKey,t.normalizeBlank=normalizeBlank,t.normalizeBool=normalizeBool,t.isJsObject=isJsObject,t.print=print,t.warn=warn;var p=function(){function Json(){}return Json.parse=function(e){return i.JSON.parse(e)},Json.stringify=function(e){return i.JSON.stringify(e,null,2)},Json}();t.Json=p;var d=function(){function DateWrapper(){}return DateWrapper.create=function(e,n,r,i,o,s,a){return void 0===n&&(n=1),void 0===r&&(r=1),void 0===i&&(i=0),void 0===o&&(o=0),void 0===s&&(s=0),void 0===a&&(a=0),new t.Date(e,n-1,r,i,o,s,a)},DateWrapper.fromISOString=function(e){return new t.Date(e)},DateWrapper.fromMillis=function(e){return new t.Date(e)},DateWrapper.toMillis=function(e){return e.getTime()},DateWrapper.now=function(){return new t.Date},DateWrapper.toJson=function(e){return e.toJSON()},DateWrapper}();t.DateWrapper=d,t.setValueOnPath=setValueOnPath;var h=null;t.getSymbolIterator=getSymbolIterator,t.evalExpression=evalExpression,t.isPrimitive=isPrimitive,t.hasConstructor=hasConstructor,t.escape=escape,t.escapeRegExp=escapeRegExp}).call(t,n(82))},4,function(e,t,n){"use strict";var r=this&&this.__extends||function(e,t){function __(){this.constructor=e}for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n]);e.prototype=null===t?Object.create(t):(__.prototype=t.prototype,new __)},i=n(217),o=n(41),s=n(215),a=n(897),l=function(e){function Subscriber(t,n,r){switch(e.call(this),this.syncErrorValue=null,this.syncErrorThrown=!1,this.syncErrorThrowable=!1,this.isStopped=!1,arguments.length){case 0:this.destination=a.empty;break;case 1:if(!t){this.destination=a.empty;break}if("object"==typeof t){t instanceof Subscriber?(this.destination=t,this.destination.add(this)):(this.syncErrorThrowable=!0,this.destination=new c(this,t));break}default:this.syncErrorThrowable=!0,this.destination=new c(this,t,n,r)}}return r(Subscriber,e),Subscriber.create=function(e,t,n){var r=new Subscriber(e,t,n);return r.syncErrorThrowable=!1,r},Subscriber.prototype.next=function(e){this.isStopped||this._next(e)},Subscriber.prototype.error=function(e){this.isStopped||(this.isStopped=!0,this._error(e))},Subscriber.prototype.complete=function(){this.isStopped||(this.isStopped=!0,this._complete())},Subscriber.prototype.unsubscribe=function(){this.isUnsubscribed||(this.isStopped=!0,e.prototype.unsubscribe.call(this))},Subscriber.prototype._next=function(e){this.destination.next(e)},Subscriber.prototype._error=function(e){this.destination.error(e),this.unsubscribe()},Subscriber.prototype._complete=function(){this.destination.complete(),this.unsubscribe()},Subscriber.prototype[s.$$rxSubscriber]=function(){return this},Subscriber}(o.Subscription);t.Subscriber=l;var c=function(e){function SafeSubscriber(t,n,r,o){e.call(this),this._parent=t;var s,a=this;i.isFunction(n)?s=n:n&&(a=n,s=n.next,r=n.error,o=n.complete,i.isFunction(a.unsubscribe)&&this.add(a.unsubscribe.bind(a)),a.unsubscribe=this.unsubscribe.bind(this)),this._context=a,this._next=s,this._error=r,this._complete=o}return r(SafeSubscriber,e),SafeSubscriber.prototype.next=function(e){if(!this.isStopped&&this._next){var t=this._parent;t.syncErrorThrowable?this.__tryOrSetError(t,this._next,e)&&this.unsubscribe():this.__tryOrUnsub(this._next,e)}},SafeSubscriber.prototype.error=function(e){if(!this.isStopped){var t=this._parent;if(this._error)t.syncErrorThrowable?(this.__tryOrSetError(t,this._error,e),this.unsubscribe()):(this.__tryOrUnsub(this._error,e),this.unsubscribe());else{if(!t.syncErrorThrowable)throw this.unsubscribe(),e;t.syncErrorValue=e,t.syncErrorThrown=!0,this.unsubscribe()}}},SafeSubscriber.prototype.complete=function(){if(!this.isStopped){var e=this._parent;this._complete?e.syncErrorThrowable?(this.__tryOrSetError(e,this._complete),this.unsubscribe()):(this.__tryOrUnsub(this._complete),this.unsubscribe()):this.unsubscribe()}},SafeSubscriber.prototype.__tryOrUnsub=function(e,t){try{e.call(this._context,t)}catch(n){throw this.unsubscribe(),n}},SafeSubscriber.prototype.__tryOrSetError=function(e,t,n){try{t.call(this._context,n)}catch(r){return e.syncErrorValue=r,e.syncErrorThrown=!0,!0}return!1},SafeSubscriber.prototype._unsubscribe=function(){var e=this._parent;this._context=null,this._parent=null,e.unsubscribe()},SafeSubscriber}(l)},4,function(e,t,n){var r=n(15);e.exports=function(e){if(!r(e))throw TypeError(e+" is not an object!");return e}},function(e,t,n){"use strict";var r=this&&this.__decorate||function(e,t,n,r){var i,o=arguments.length,s=o<3?t:null===r?r=Object.getOwnPropertyDescriptor(t,n):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(e,t,n,r);else for(var a=e.length-1;a>=0;a--)(i=e[a])&&(s=(o<3?i(s):o>3?i(t,n,s):i(t,n))||s);return o>3&&s&&Object.defineProperty(t,n,s),s},i=this&&this.__metadata||function(e,t){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(e,t)},o=n(0),s=function(){function DomHandler(){}return DomHandler.prototype.addClass=function(e,t){e.classList?e.classList.add(t):e.className+=" "+t},DomHandler.prototype.addMultipleClasses=function(e,t){if(e.classList)for(var n=t.split(" "),r=0;rwindow.innerHeight?-1*i.height:o,r=a.left+i.width>window.innerWidth?s-i.width:0,e.style.top=n+"px",e.style.left=r+"px"},DomHandler.prototype.absolutePosition=function(e,t){var n,r,i=e.offsetParent?{width:e.offsetWidth,height:e.offsetHeight}:this.getHiddenElementDimensions(e),o=i.height,s=i.width,a=t.offsetHeight,l=t.offsetWidth,c=t.getBoundingClientRect(),u=this.getWindowScrollTop(),p=this.getWindowScrollLeft();n=c.top+a+o>window.innerHeight?c.top+u-o:a+c.top+u,r=c.left+l+s>window.innerWidth?c.left+p+l-s:c.left+p,e.style.top=n+"px",e.style.left=r+"px"},DomHandler.prototype.getHiddenElementOuterHeight=function(e){e.style.visibility="hidden",e.style.display="block";var t=e.offsetHeight;return e.style.display="none",e.style.visibility="visible",t},DomHandler.prototype.getHiddenElementOuterWidth=function(e){e.style.visibility="hidden",e.style.display="block";var t=e.offsetWidth;return e.style.display="none",e.style.visibility="visible",t},DomHandler.prototype.getHiddenElementDimensions=function(e){var t={};return e.style.visibility="hidden",e.style.display="block",t.width=e.offsetWidth,t.height=e.offsetHeight,e.style.display="none",e.style.visibility="visible",t},DomHandler.prototype.scrollInView=function(e,t){var n=getComputedStyle(e).getPropertyValue("borderTopWidth"),r=n?parseFloat(n):0,i=getComputedStyle(e).getPropertyValue("paddingTop"),o=i?parseFloat(i):0,s=e.getBoundingClientRect(),a=t.getBoundingClientRect(),l=a.top+document.body.scrollTop-(s.top+document.body.scrollTop)-r-o,c=e.scrollTop,u=e.clientHeight,p=this.getOuterHeight(t);l<0?e.scrollTop=c+l:l+p>u&&(e.scrollTop=c+l-u+p)},DomHandler.prototype.fadeIn=function(e,t){e.style.opacity=0;var n=+new Date,r=function(){e.style.opacity=+e.style.opacity+((new Date).getTime()-n)/t,n=+new Date,+e.style.opacity<1&&(window.requestAnimationFrame&&requestAnimationFrame(r)||setTimeout(r,16))};r()},DomHandler.prototype.fadeOut=function(e,t){var n=1,r=50,i=t,o=r/i,s=setInterval(function(){n-=o,e.style.opacity=n,n<=0&&clearInterval(s)},r)},DomHandler.prototype.getWindowScrollTop=function(){var e=document.documentElement;return(window.pageYOffset||e.scrollTop)-(e.clientTop||0)},DomHandler.prototype.getWindowScrollLeft=function(){var e=document.documentElement;return(window.pageXOffset||e.scrollLeft)-(e.clientLeft||0)},DomHandler.prototype.matches=function(e,t){var n=Element.prototype,r=n.matches||n.webkitMatchesSelector||n.mozMatchesSelector||n.msMatchesSelector||function(e){return[].indexOf.call(document.querySelectorAll(e),this)!==-1};return r.call(e,t)},DomHandler.prototype.getOuterWidth=function(e,t){var n=e.offsetWidth;if(t){var r=getComputedStyle(e);n+=parseInt(r.paddingLeft)+parseInt(r.paddingRight)}return n},DomHandler.prototype.getHorizontalMargin=function(e){var t=getComputedStyle(e);return parseInt(t.marginLeft)+parseInt(t.marginRight)},DomHandler.prototype.innerWidth=function(e){var t=e.offsetWidth,n=getComputedStyle(e);return t+=parseInt(n.paddingLeft)+parseInt(n.paddingRight)},DomHandler.prototype.width=function(e){var t=e.offsetWidth,n=getComputedStyle(e);return t-=parseInt(n.paddingLeft)+parseInt(n.paddingRight)},DomHandler.prototype.getOuterHeight=function(e,t){var n=e.offsetHeight;if(t){var r=getComputedStyle(e);n+=parseInt(r.marginTop)+parseInt(r.marginBottom)}return n},DomHandler.prototype.getHeight=function(e){var t=e.offsetHeight,n=getComputedStyle(e);return t-=parseInt(n.paddingTop)+parseInt(n.paddingBottom)+parseInt(n.borderTopWidth)+parseInt(n.borderBottomWidth)},DomHandler.prototype.getViewport=function(){var e=window,t=document,n=t.documentElement,r=t.getElementsByTagName("body")[0],i=e.innerWidth||n.clientWidth||r.clientWidth,o=e.innerHeight||n.clientHeight||r.clientHeight;return{width:i,height:o}},DomHandler.prototype.equals=function(e,t){if(null==e||null==t)return!1;if(e==t)return!0;if("object"==typeof e&&"object"==typeof t){for(var n in e){if(e.hasOwnProperty(n)!==t.hasOwnProperty(n))return!1;switch(typeof e[n]){case"object":if(!this.equals(e[n],t[n]))return!1;break;case"function":if("undefined"==typeof t[n]||"compare"!=n&&e[n].toString()!=t[n].toString())return!1;break;default:if(e[n]!=t[n])return!1}}for(var n in t)if("undefined"==typeof e[n])return!1;return!0}return!1},DomHandler.zindex=1e3,DomHandler=r([o.Injectable(),i("design:paramtypes",[])],DomHandler)}();t.DomHandler=s},[1104,5],function(e,t,n){"use strict";var r=this&&this.__extends||function(e,t){function __(){this.constructor=e}for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n]);e.prototype=null===t?Object.create(t):(__.prototype=t.prototype,new __)},i=n(6),o=function(e){function OuterSubscriber(){e.apply(this,arguments)}return r(OuterSubscriber,e),OuterSubscriber.prototype.notifyNext=function(e,t,n,r,i){this.destination.next(t)},OuterSubscriber.prototype.notifyError=function(e,t){this.destination.error(e)},OuterSubscriber.prototype.notifyComplete=function(e){this.destination.complete()},OuterSubscriber}(i.Subscriber);t.OuterSubscriber=o},function(e,t,n){"use strict";function subscribeToResult(e,t,n,u){var p=new c.InnerSubscriber(e,n,u);if(!p.isUnsubscribed){if(t instanceof s.Observable)return t._isScalar?(p.next(t.value),void p.complete()):t.subscribe(p);if(i.isArray(t)){for(var d=0,h=t.length;d=0;a--)(i=e[a])&&(s=(o<3?i(s):o>3?i(t,n,s):i(t,n))||s);return o>3&&s&&Object.defineProperty(t,n,s),s},i=this&&this.__metadata||function(e,t){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(e,t)},o=n(0),s=n(3),a=n(0),l=function(){function Header(){}return Header=r([a.Component({selector:"header",template:""}),i("design:paramtypes",[])],Header)}();t.Header=l;var c=function(){function Footer(){}return Footer=r([a.Component({selector:"footer",template:""}),i("design:paramtypes",[])],Footer)}();t.Footer=c;var u=function(){function TemplateWrapper(e){this.viewContainer=e}return TemplateWrapper.prototype.ngOnInit=function(){this.viewContainer.createEmbeddedView(this.templateRef,{$implicit:this.item})},r([o.Input(),i("design:type",Object)],TemplateWrapper.prototype,"item",void 0),r([o.Input("pTemplateWrapper"),i("design:type",o.TemplateRef)],TemplateWrapper.prototype,"templateRef",void 0),TemplateWrapper=r([o.Directive({selector:"[pTemplateWrapper]"}),i("design:paramtypes",[o.ViewContainerRef])],TemplateWrapper)}();t.TemplateWrapper=u;var p=function(){function Column(){this.sortFunction=new o.EventEmitter}return r([o.Input(),i("design:type",String)],Column.prototype,"field",void 0),r([o.Input(),i("design:type",String)],Column.prototype,"header",void 0),r([o.Input(),i("design:type",String)],Column.prototype,"footer",void 0),r([o.Input(),i("design:type",Object)],Column.prototype,"sortable",void 0),r([o.Input(),i("design:type",Boolean)],Column.prototype,"editable",void 0),r([o.Input(),i("design:type",Boolean)],Column.prototype,"filter",void 0),r([o.Input(),i("design:type",String)],Column.prototype,"filterMatchMode",void 0),r([o.Input(),i("design:type",Number)],Column.prototype,"rowspan",void 0),r([o.Input(),i("design:type",Number)],Column.prototype,"colspan",void 0),r([o.Input(),i("design:type",Object)],Column.prototype,"style",void 0),r([o.Input(),i("design:type",String)],Column.prototype,"styleClass",void 0),r([o.Input(),i("design:type",Boolean)],Column.prototype,"hidden",void 0),r([o.Input(),i("design:type",Boolean)],Column.prototype,"expander",void 0),r([o.Input(),i("design:type",String)],Column.prototype,"selectionMode",void 0),r([o.Output(),i("design:type",o.EventEmitter)],Column.prototype,"sortFunction",void 0),r([o.ContentChild(o.TemplateRef),i("design:type",o.TemplateRef)],Column.prototype,"template",void 0),Column=r([a.Component({selector:"p-column",template:""}),i("design:paramtypes",[])],Column)}();t.Column=p;var d=function(){function ColumnTemplateLoader(e){this.viewContainer=e}return ColumnTemplateLoader.prototype.ngOnInit=function(){this.viewContainer.createEmbeddedView(this.column.template,{$implicit:this.column,rowData:this.rowData,rowIndex:this.rowIndex})},r([o.Input(),i("design:type",Object)],ColumnTemplateLoader.prototype,"column",void 0),r([o.Input(),i("design:type",Object)],ColumnTemplateLoader.prototype,"rowData",void 0),r([o.Input(),i("design:type",Number)],ColumnTemplateLoader.prototype,"rowIndex",void 0),ColumnTemplateLoader=r([a.Component({selector:"p-columnTemplateLoader",template:""}),i("design:paramtypes",[o.ViewContainerRef])],ColumnTemplateLoader)}();t.ColumnTemplateLoader=d;var h=function(){function SharedModule(){}return SharedModule=r([o.NgModule({imports:[s.CommonModule],exports:[l,c,p,u,d],declarations:[l,c,p,u,d]}),i("design:paramtypes",[])],SharedModule)}();t.SharedModule=h},function(e,t,n){"use strict";var r=this&&this.__extends||function(e,t){function __(){this.constructor=e}for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n]);e.prototype=null===t?Object.create(t):(__.prototype=t.prototype,new __)},i=n(1),o=n(6),s=n(41),a=n(899),l=n(215),c=n(517),u=n(317),p=function(e){function Subject(t,n){e.call(this),this.destination=t,this.source=n,this.observers=[],this.isUnsubscribed=!1,this.isStopped=!1,this.hasErrored=!1,this.dispatching=!1,this.hasCompleted=!1,this.source=n}return r(Subject,e),Subject.prototype.lift=function(e){var t=new Subject(this.destination||this,this);return t.operator=e,t},Subject.prototype.add=function(e){return s.Subscription.prototype.add.call(this,e)},Subject.prototype.remove=function(e){s.Subscription.prototype.remove.call(this,e)},Subject.prototype.unsubscribe=function(){s.Subscription.prototype.unsubscribe.call(this)},Subject.prototype._subscribe=function(e){if(this.source)return this.source.subscribe(e);if(!e.isUnsubscribed){if(this.hasErrored)return e.error(this.errorValue);if(this.hasCompleted)return e.complete();this.throwIfUnsubscribed();var t=new a.SubjectSubscription(this,e);return this.observers.push(e),t}},Subject.prototype._unsubscribe=function(){this.source=null,this.isStopped=!0,this.observers=null,this.destination=null},Subject.prototype.next=function(e){this.throwIfUnsubscribed(),this.isStopped||(this.dispatching=!0,this._next(e),this.dispatching=!1,this.hasErrored?this._error(this.errorValue):this.hasCompleted&&this._complete())},Subject.prototype.error=function(e){this.throwIfUnsubscribed(),this.isStopped||(this.isStopped=!0,this.hasErrored=!0,this.errorValue=e,this.dispatching||this._error(e))},Subject.prototype.complete=function(){this.throwIfUnsubscribed(),this.isStopped||(this.isStopped=!0,this.hasCompleted=!0,this.dispatching||this._complete())},Subject.prototype.asObservable=function(){var e=new d(this);return e},Subject.prototype._next=function(e){this.destination?this.destination.next(e):this._finalNext(e)},Subject.prototype._finalNext=function(e){for(var t=-1,n=this.observers.slice(0),r=n.length;++t"+i+""};e.exports=function(e,t){var n={};n[e]=t(a),r(r.P+r.F*i(function(){var t=""[e]('"');return t!==t.toLowerCase()||t.split('"').length>3}),"String",n)}},function(e,t,n){"use strict";var r=n(81),i=n(514),o=n(217),s=n(42),a=n(38),l=n(513),c=function(){function Subscription(e){this.isUnsubscribed=!1,e&&(this._unsubscribe=e)}return Subscription.prototype.unsubscribe=function(){var e,t=!1;if(!this.isUnsubscribed){this.isUnsubscribed=!0;var n=this,c=n._unsubscribe,u=n._subscriptions;if(this._subscriptions=null,o.isFunction(c)){var p=s.tryCatch(c).call(this);p===a.errorObject&&(t=!0,(e=e||[]).push(a.errorObject.e))}if(r.isArray(u))for(var d=-1,h=u.length;++d0?i(r(e),9007199254740991):0}},function(e,t,n){"use strict";var r=n(1082);t.async=new r.AsyncScheduler},function(e,t,n){"use strict";function __export(e){for(var n in e)t.hasOwnProperty(n)||(t[n]=e[n])}var r=n(86);t.HostMetadata=r.HostMetadata,t.InjectMetadata=r.InjectMetadata,t.InjectableMetadata=r.InjectableMetadata,t.OptionalMetadata=r.OptionalMetadata,t.SelfMetadata=r.SelfMetadata,t.SkipSelfMetadata=r.SkipSelfMetadata,__export(n(115));var i=n(162);t.forwardRef=i.forwardRef,t.resolveForwardRef=i.resolveForwardRef;var o=n(163);t.Injector=o.Injector;var s=n(571);t.ReflectiveInjector=s.ReflectiveInjector;var a=n(250);t.Binding=a.Binding,t.ProviderBuilder=a.ProviderBuilder,t.bind=a.bind,t.Provider=a.Provider,t.provide=a.provide;var l=n(253);t.ResolvedReflectiveFactory=l.ResolvedReflectiveFactory;var c=n(252);t.ReflectiveKey=c.ReflectiveKey;var u=n(251);t.NoProviderError=u.NoProviderError,t.AbstractProviderError=u.AbstractProviderError,t.CyclicDependencyError=u.CyclicDependencyError,t.InstantiationError=u.InstantiationError,t.InvalidProviderError=u.InvalidProviderError,t.NoAnnotationError=u.NoAnnotationError,t.OutOfBoundsError=u.OutOfBoundsError;var p=n(374);t.OpaqueToken=p.OpaqueToken},[1104,32],function(e,t){var n={}.hasOwnProperty;e.exports=function(e,t){return n.call(e,t)}},function(e,t,n){"use strict";var r=n(13);e.exports=function(e,t){return!!e&&r(function(){t?e.call(null,function(){},1):e.call(null)})}},function(e,t,n){var r=n(75);e.exports=function(e){return Object(r(e))}},function(e,t,n){"use strict";(function(e,n){var r={"boolean":!1,"function":!0,object:!0,number:!1,string:!1,undefined:!1};t.root=r[typeof self]&&self||r[typeof window]&&window;var i=(r[typeof t]&&t&&!t.nodeType&&t,r[typeof e]&&e&&!e.nodeType&&e,r[typeof n]&&n);!i||i.global!==i&&i.window!==i||(t.root=i)}).call(t,n(1100)(e),n(82))},function(e,t,n){"use strict";var r=n(0);t.NG_VALUE_ACCESSOR=new r.OpaqueToken("NgValueAccessor")},52,function(e,t,n){"use strict";function _convertToPromise(e){return s.isPromise(e)?e:i.toPromise.call(e)}function _executeValidators(e,t){return t.map(function(t){return t(e)})}function _executeAsyncValidators(e,t){return t.map(function(t){return t(e)})}function _mergeErrors(e){var t=e.reduce(function(e,t){return s.isPresent(t)?o.StringMapWrapper.merge(e,t):e},{});return o.StringMapWrapper.isEmpty(t)?null:t}var r=n(0),i=n(313),o=n(47),s=n(32);t.NG_VALIDATORS=new r.OpaqueToken("NgValidators"),t.NG_ASYNC_VALIDATORS=new r.OpaqueToken("NgAsyncValidators");var a=function(){function Validators(){}return Validators.required=function(e){return s.isBlank(e.value)||s.isString(e.value)&&""==e.value?{required:!0}:null},Validators.minLength=function(e){return function(t){if(s.isPresent(Validators.required(t)))return null;var n=t.value;return n.lengthe?{maxlength:{requiredLength:e,actualLength:n.length}}:null}},Validators.pattern=function(e){return function(t){if(s.isPresent(Validators.required(t)))return null;var n=new RegExp("^"+e+"$"),r=t.value;return n.test(r)?null:{pattern:{requiredPattern:"^"+e+"$",actualValue:r}}}},Validators.nullValidator=function(e){return null},Validators.compose=function(e){if(s.isBlank(e))return null;var t=e.filter(s.isPresent);return 0==t.length?null:function(e){return _mergeErrors(_executeValidators(e,t))}},Validators.composeAsync=function(e){if(s.isBlank(e))return null;var t=e.filter(s.isPresent);return 0==t.length?null:function(e){var n=_executeAsyncValidators(e,t).map(_convertToPromise);return Promise.all(n).then(_mergeErrors)}},Validators}();t.Validators=a},function(e,t,n){"use strict";var r=n(0),i=n(123),o=n(72),s=n(16),a=n(126),l=n(278);t.PRIMITIVE=String;var c=function(){function Serializer(e){this._renderStore=e}return Serializer.prototype.serialize=function(e,n){var i=this;if(!s.isPresent(e))return null;if(s.isArray(e))return e.map(function(e){return i.serialize(e,n)});if(n==t.PRIMITIVE)return e;if(n==u)return this._renderStore.serialize(e);if(n===r.RenderComponentType)return this._serializeRenderComponentType(e);if(n===r.ViewEncapsulation)return s.serializeEnum(e);if(n===l.LocationType)return this._serializeLocation(e);throw new o.BaseException("No serializer for "+n.toString())},Serializer.prototype.deserialize=function(e,n,a){var c=this;if(!s.isPresent(e))return null;if(s.isArray(e)){var p=[];return e.forEach(function(e){return p.push(c.deserialize(e,n,a))}),p}if(n==t.PRIMITIVE)return e;if(n==u)return this._renderStore.deserialize(e);if(n===r.RenderComponentType)return this._deserializeRenderComponentType(e);if(n===r.ViewEncapsulation)return i.VIEW_ENCAPSULATION_VALUES[e];if(n===l.LocationType)return this._deserializeLocation(e);throw new o.BaseException("No deserializer for "+n.toString())},Serializer.prototype._serializeLocation=function(e){return{href:e.href,protocol:e.protocol,host:e.host,hostname:e.hostname,port:e.port,pathname:e.pathname,search:e.search,hash:e.hash,origin:e.origin}},Serializer.prototype._deserializeLocation=function(e){return new l.LocationType(e.href,e.protocol,e.host,e.hostname,e.port,e.pathname,e.search,e.hash,e.origin)},Serializer.prototype._serializeRenderComponentType=function(e){return{id:e.id,templateUrl:e.templateUrl,slotCount:e.slotCount,encapsulation:this.serialize(e.encapsulation,r.ViewEncapsulation),styles:this.serialize(e.styles,t.PRIMITIVE)}},Serializer.prototype._deserializeRenderComponentType=function(e){return new r.RenderComponentType(e.id,e.templateUrl,e.slotCount,this.deserialize(e.encapsulation,r.ViewEncapsulation),this.deserialize(e.styles,t.PRIMITIVE),{})},Serializer.decorators=[{type:r.Injectable}],Serializer.ctorParameters=[{type:a.RenderStore}],Serializer}();t.Serializer=c;var u=function(){function RenderStoreObject(){}return RenderStoreObject}();t.RenderStoreObject=u},function(e,t,n){var r=n(2),i=n(24),o=n(13);e.exports=function(e,t){var n=(i.Object||{})[e]||Object[e],s={};s[e]=t(n),r(r.S+r.F*o(function(){n(1)}),"Object",s)}},function(e,t,n){var r=n(133),i=n(75);e.exports=function(e){return r(i(e))}},function(e,t,n){"use strict";function _convertToPromise(e){return s.isPromise(e)?e:i.toPromise.call(e)}function _executeValidators(e,t){return t.map(function(t){return t(e)})}function _executeAsyncValidators(e,t){return t.map(function(t){return t(e)})}function _mergeErrors(e){var t=e.reduce(function(e,t){return s.isPresent(t)?o.StringMapWrapper.merge(e,t):e},{});return o.StringMapWrapper.isEmpty(t)?null:t}var r=n(0),i=n(313),o=n(34),s=n(7);t.NG_VALIDATORS=new r.OpaqueToken("NgValidators"),t.NG_ASYNC_VALIDATORS=new r.OpaqueToken("NgAsyncValidators");var a=function(){function Validators(){}return Validators.required=function(e){return s.isBlank(e.value)||s.isString(e.value)&&""==e.value?{required:!0}:null},Validators.minLength=function(e){return function(t){if(s.isPresent(Validators.required(t)))return null;var n=t.value;return n.lengthe?{maxlength:{requiredLength:e,actualLength:n.length}}:null}},Validators.pattern=function(e){return function(t){if(s.isPresent(Validators.required(t)))return null;var n=new RegExp("^"+e+"$"),r=t.value;return n.test(r)?null:{pattern:{requiredPattern:"^"+e+"$",actualValue:r}}}},Validators.nullValidator=function(e){return null},Validators.compose=function(e){if(s.isBlank(e))return null;var t=e.filter(s.isPresent);return 0==t.length?null:function(e){return _mergeErrors(_executeValidators(e,t))}},Validators.composeAsync=function(e){if(s.isBlank(e))return null;var t=e.filter(s.isPresent);return 0==t.length?null:function(e){var n=_executeAsyncValidators(e,t).map(_convertToPromise);return Promise.all(n).then(_mergeErrors)}},Validators}();t.Validators=a},function(e,t,n){"use strict";var r=this&&this.__extends||function(e,t){function __(){this.constructor=e}for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n]);e.prototype=null===t?Object.create(t):(__.prototype=t.prototype,new __)},i=n(83),o=n(7),s=function(e){function InvalidPipeArgumentException(t,n){e.call(this,"Invalid argument '"+n+"' for pipe '"+o.stringify(t)+"'")}return r(InvalidPipeArgumentException,e),InvalidPipeArgumentException}(i.BaseException);t.InvalidPipeArgumentException=s},function(e,t,n){"use strict";/** +webpackJsonp([0,2],[function(e,t,n){"use strict";function __export(e){for(var n in e)t.hasOwnProperty(n)||(t[n]=e[n])}__export(n(386)),__export(n(585)),__export(n(46));var r=n(248);t.createPlatform=r.createPlatform,t.assertPlatform=r.assertPlatform,t.disposePlatform=r.disposePlatform,t.getPlatform=r.getPlatform,t.coreBootstrap=r.coreBootstrap,t.coreLoadAndBootstrap=r.coreLoadAndBootstrap,t.PlatformRef=r.PlatformRef,t.ApplicationRef=r.ApplicationRef,t.enableProdMode=r.enableProdMode,t.lockRunMode=r.lockRunMode,t.isDevMode=r.isDevMode,t.createPlatformFactory=r.createPlatformFactory;var i=n(157);t.APP_ID=i.APP_ID,t.PACKAGE_ROOT_URL=i.PACKAGE_ROOT_URL,t.PLATFORM_INITIALIZER=i.PLATFORM_INITIALIZER,t.APP_BOOTSTRAP_LISTENER=i.APP_BOOTSTRAP_LISTENER;var o=n(247);t.APP_INITIALIZER=o.APP_INITIALIZER,t.ApplicationInitStatus=o.ApplicationInitStatus,__export(n(586)),__export(n(584)),__export(n(573));var s=n(373);t.DebugElement=s.DebugElement,t.DebugNode=s.DebugNode,t.asNativeElements=s.asNativeElements,t.getDebugNode=s.getDebugNode,__export(n(261)),__export(n(568)),__export(n(581)),__export(n(580));var a=n(567);t.APPLICATION_COMMON_PROVIDERS=a.APPLICATION_COMMON_PROVIDERS,t.ApplicationModule=a.ApplicationModule;var l=n(167);t.wtfCreateScope=l.wtfCreateScope,t.wtfLeave=l.wtfLeave,t.wtfStartTimeRange=l.wtfStartTimeRange,t.wtfEndTimeRange=l.wtfEndTimeRange;var c=n(4);t.Type=c.Type;var u=n(254);t.EventEmitter=u.EventEmitter;var p=n(14);t.ExceptionHandler=p.ExceptionHandler,t.WrappedException=p.WrappedException,t.BaseException=p.BaseException,__export(n(561)),__export(n(369));var d=n(246);t.AnimationPlayer=d.AnimationPlayer;var h=n(394);t.SanitizationService=h.SanitizationService,t.SecurityContext=h.SecurityContext},function(e,t,n){"use strict";var r=n(51),i=n(214),o=n(1089),s=function(){function Observable(e){this._isScalar=!1,e&&(this._subscribe=e)}return Observable.prototype.lift=function(e){var t=new Observable;return t.source=this,t.operator=e,t},Observable.prototype.subscribe=function(e,t,n){var r=this.operator,i=o.toSubscriber(e,t,n);if(i.add(r?r.call(i,this):this._subscribe(i)),i.syncErrorThrowable&&(i.syncErrorThrowable=!1,i.syncErrorThrown))throw i.syncErrorValue;return i},Observable.prototype.forEach=function(e,t){var n=this;if(t||(r.root.Rx&&r.root.Rx.config&&r.root.Rx.config.Promise?t=r.root.Rx.config.Promise:r.root.Promise&&(t=r.root.Promise)),!t)throw new Error("no Promise impl found");return new t(function(t,r){var i=n.subscribe(function(t){if(i)try{e(t)}catch(n){r(n),i.unsubscribe()}else e(t)},r,t)})},Observable.prototype._subscribe=function(e){return this.source.subscribe(e)},Observable.prototype[i.$$observable]=function(){return this},Observable.create=function(e){return new Observable(e)},Observable}();t.Observable=s},function(e,t,n){var r=n(26),i=n(24),o=n(65),s=n(39),a=n(106),l="prototype",c=function(e,t,n){var u,p,d,h,f=e&c.F,m=e&c.G,g=e&c.S,y=e&c.P,v=e&c.B,b=m?r:g?r[t]||(r[t]={}):(r[t]||{})[l],_=m?i:i[t]||(i[t]={}),w=_[l]||(_[l]={});m&&(n=t);for(u in n)p=!f&&b&&void 0!==b[u],d=(p?b:n)[u],h=v&&p?a(d,r):y&&"function"==typeof d?a(Function.call,d):d,b&&s(b,u,d,e&c.U),_[u]!=d&&o(_,u,h),y&&w[u]!=d&&(w[u]=d)};r.core=i,c.F=1,c.G=2,c.S=4,c.P=8,c.B=16,c.W=32,c.U=64,c.R=128,e.exports=c},function(e,t,n){"use strict";function __export(e){for(var n in e)t.hasOwnProperty(n)||(t[n]=e[n])}var r=n(0),i=n(321),o=n(334);__export(n(334)),__export(n(322)),__export(n(525)),__export(n(321)),__export(n(527));var s=n(230);t.NgLocalization=s.NgLocalization;var a=function(){function CommonModule(){}return CommonModule.decorators=[{type:r.NgModule,args:[{declarations:[i.COMMON_DIRECTIVES,o.COMMON_PIPES],exports:[i.COMMON_DIRECTIVES,o.COMMON_PIPES]}]}],CommonModule}();t.CommonModule=a},function(e,t,n){"use strict";(function(e){function scheduleMicroTask(e){Zone.current.scheduleMicroTask("scheduleMicrotask",e)}function getTypeNameForDebugging(e){return e.name?e.name:typeof e}function isPresent(e){return void 0!==e&&null!==e}function isBlank(e){return void 0===e||null===e}function isBoolean(e){return"boolean"==typeof e}function isNumber(e){return"number"==typeof e}function isString(e){return"string"==typeof e}function isFunction(e){return"function"==typeof e}function isType(e){return isFunction(e)}function isStringMap(e){return"object"==typeof e&&null!==e}function isStrictStringMap(e){return isStringMap(e)&&Object.getPrototypeOf(e)===o}function isPromise(e){return isPresent(e)&&isFunction(e.then)}function isArray(e){return Array.isArray(e)}function isDate(e){return e instanceof t.Date&&!isNaN(e.valueOf())}function noop(){}function stringify(e){if("string"==typeof e)return e;if(void 0===e||null===e)return""+e;if(e.overriddenName)return e.overriddenName;if(e.name)return e.name;var t=e.toString(),n=t.indexOf("\n");return n===-1?t:t.substring(0,n)}function serializeEnum(e){return e}function deserializeEnum(e,t){return e}function resolveEnumToken(e,t){return e[t]}function looseIdentical(e,t){return e===t||"number"==typeof e&&"number"==typeof t&&isNaN(e)&&isNaN(t)}function getMapKey(e){return e}function normalizeBlank(e){return isBlank(e)?null:e}function normalizeBool(e){return!isBlank(e)&&e}function isJsObject(e){return null!==e&&("function"==typeof e||"object"==typeof e)}function print(e){console.log(e)}function warn(e){console.warn(e)}function setValueOnPath(e,t,n){for(var r=t.split("."),i=e;r.length>1;){var o=r.shift();i=i.hasOwnProperty(o)&&isPresent(i[o])?i[o]:i[o]={}}void 0!==i&&null!==i||(i={}),i[r.shift()]=n}function getSymbolIterator(){if(isBlank(h))if(isPresent(n.Symbol)&&isPresent(Symbol.iterator))h=Symbol.iterator;else for(var e=Object.getOwnPropertyNames(Map.prototype),t=0;t=0&&e[r]==t;r--)n--;e=e.substring(0,n)}return e},StringWrapper.replace=function(e,t,n){return e.replace(t,n)},StringWrapper.replaceAll=function(e,t,n){return e.replace(t,n)},StringWrapper.slice=function(e,t,n){return void 0===t&&(t=0),void 0===n&&(n=null),e.slice(t,null===n?void 0:n)},StringWrapper.replaceAllMapped=function(e,t,n){return e.replace(t,function(){for(var e=[],t=0;tt?1:0},StringWrapper}();t.StringWrapper=s;var a=function(){function StringJoiner(e){void 0===e&&(e=[]),this.parts=e}return StringJoiner.prototype.add=function(e){this.parts.push(e)},StringJoiner.prototype.toString=function(){return this.parts.join("")},StringJoiner}();t.StringJoiner=a;var l=function(e){function NumberParseError(t){e.call(this),this.message=t}return r(NumberParseError,e),NumberParseError.prototype.toString=function(){return this.message},NumberParseError}(Error);t.NumberParseError=l;var c=function(){function NumberWrapper(){}return NumberWrapper.toFixed=function(e,t){return e.toFixed(t)},NumberWrapper.equal=function(e,t){return e===t},NumberWrapper.parseIntAutoRadix=function(e){var t=parseInt(e);if(isNaN(t))throw new l("Invalid integer literal when parsing "+e);return t},NumberWrapper.parseInt=function(e,t){if(10==t){if(/^(\-|\+)?[0-9]+$/.test(e))return parseInt(e,t)}else if(16==t){if(/^(\-|\+)?[0-9ABCDEFabcdef]+$/.test(e))return parseInt(e,t)}else{var n=parseInt(e,t);if(!isNaN(n))return n}throw new l("Invalid integer literal when parsing "+e+" in base "+t)},NumberWrapper.parseFloat=function(e){return parseFloat(e)},Object.defineProperty(NumberWrapper,"NaN",{get:function(){return NaN},enumerable:!0,configurable:!0}),NumberWrapper.isNumeric=function(e){return!isNaN(e-parseFloat(e))},NumberWrapper.isNaN=function(e){return isNaN(e)},NumberWrapper.isInteger=function(e){return Number.isInteger(e)},NumberWrapper}();t.NumberWrapper=c,t.RegExp=i.RegExp;var u=function(){function FunctionWrapper(){}return FunctionWrapper.apply=function(e,t){return e.apply(null,t)},FunctionWrapper.bind=function(e,t){return e.bind(t)},FunctionWrapper}();t.FunctionWrapper=u,t.looseIdentical=looseIdentical,t.getMapKey=getMapKey,t.normalizeBlank=normalizeBlank,t.normalizeBool=normalizeBool,t.isJsObject=isJsObject,t.print=print,t.warn=warn;var p=function(){function Json(){}return Json.parse=function(e){return i.JSON.parse(e)},Json.stringify=function(e){return i.JSON.stringify(e,null,2)},Json}();t.Json=p;var d=function(){function DateWrapper(){}return DateWrapper.create=function(e,n,r,i,o,s,a){return void 0===n&&(n=1),void 0===r&&(r=1),void 0===i&&(i=0),void 0===o&&(o=0),void 0===s&&(s=0),void 0===a&&(a=0),new t.Date(e,n-1,r,i,o,s,a)},DateWrapper.fromISOString=function(e){return new t.Date(e)},DateWrapper.fromMillis=function(e){return new t.Date(e)},DateWrapper.toMillis=function(e){return e.getTime()},DateWrapper.now=function(){return new t.Date},DateWrapper.toJson=function(e){return e.toJSON()},DateWrapper}();t.DateWrapper=d,t.setValueOnPath=setValueOnPath;var h=null;t.getSymbolIterator=getSymbolIterator,t.evalExpression=evalExpression,t.isPrimitive=isPrimitive,t.hasConstructor=hasConstructor,t.escape=escape,t.escapeRegExp=escapeRegExp}).call(t,n(82))},4,function(e,t,n){"use strict";var r=this&&this.__extends||function(e,t){function __(){this.constructor=e}for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n]);e.prototype=null===t?Object.create(t):(__.prototype=t.prototype,new __)},i=n(217),o=n(41),s=n(215),a=n(897),l=function(e){function Subscriber(t,n,r){switch(e.call(this),this.syncErrorValue=null,this.syncErrorThrown=!1,this.syncErrorThrowable=!1,this.isStopped=!1,arguments.length){case 0:this.destination=a.empty;break;case 1:if(!t){this.destination=a.empty;break}if("object"==typeof t){t instanceof Subscriber?(this.destination=t,this.destination.add(this)):(this.syncErrorThrowable=!0,this.destination=new c(this,t));break}default:this.syncErrorThrowable=!0,this.destination=new c(this,t,n,r)}}return r(Subscriber,e),Subscriber.create=function(e,t,n){var r=new Subscriber(e,t,n);return r.syncErrorThrowable=!1,r},Subscriber.prototype.next=function(e){this.isStopped||this._next(e)},Subscriber.prototype.error=function(e){this.isStopped||(this.isStopped=!0,this._error(e))},Subscriber.prototype.complete=function(){this.isStopped||(this.isStopped=!0,this._complete())},Subscriber.prototype.unsubscribe=function(){this.isUnsubscribed||(this.isStopped=!0,e.prototype.unsubscribe.call(this))},Subscriber.prototype._next=function(e){this.destination.next(e)},Subscriber.prototype._error=function(e){this.destination.error(e),this.unsubscribe()},Subscriber.prototype._complete=function(){this.destination.complete(),this.unsubscribe()},Subscriber.prototype[s.$$rxSubscriber]=function(){return this},Subscriber}(o.Subscription);t.Subscriber=l;var c=function(e){function SafeSubscriber(t,n,r,o){e.call(this),this._parent=t;var s,a=this;i.isFunction(n)?s=n:n&&(a=n,s=n.next,r=n.error,o=n.complete,i.isFunction(a.unsubscribe)&&this.add(a.unsubscribe.bind(a)),a.unsubscribe=this.unsubscribe.bind(this)),this._context=a,this._next=s,this._error=r,this._complete=o}return r(SafeSubscriber,e),SafeSubscriber.prototype.next=function(e){if(!this.isStopped&&this._next){var t=this._parent;t.syncErrorThrowable?this.__tryOrSetError(t,this._next,e)&&this.unsubscribe():this.__tryOrUnsub(this._next,e)}},SafeSubscriber.prototype.error=function(e){if(!this.isStopped){var t=this._parent;if(this._error)t.syncErrorThrowable?(this.__tryOrSetError(t,this._error,e),this.unsubscribe()):(this.__tryOrUnsub(this._error,e),this.unsubscribe());else{if(!t.syncErrorThrowable)throw this.unsubscribe(),e;t.syncErrorValue=e,t.syncErrorThrown=!0,this.unsubscribe()}}},SafeSubscriber.prototype.complete=function(){if(!this.isStopped){var e=this._parent;this._complete?e.syncErrorThrowable?(this.__tryOrSetError(e,this._complete),this.unsubscribe()):(this.__tryOrUnsub(this._complete),this.unsubscribe()):this.unsubscribe()}},SafeSubscriber.prototype.__tryOrUnsub=function(e,t){try{e.call(this._context,t)}catch(n){throw this.unsubscribe(),n}},SafeSubscriber.prototype.__tryOrSetError=function(e,t,n){try{t.call(this._context,n)}catch(r){return e.syncErrorValue=r,e.syncErrorThrown=!0,!0}return!1},SafeSubscriber.prototype._unsubscribe=function(){var e=this._parent;this._context=null,this._parent=null,e.unsubscribe()},SafeSubscriber}(l)},4,function(e,t,n){var r=n(15);e.exports=function(e){if(!r(e))throw TypeError(e+" is not an object!");return e}},function(e,t,n){"use strict";var r=this&&this.__decorate||function(e,t,n,r){var i,o=arguments.length,s=o<3?t:null===r?r=Object.getOwnPropertyDescriptor(t,n):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(e,t,n,r);else for(var a=e.length-1;a>=0;a--)(i=e[a])&&(s=(o<3?i(s):o>3?i(t,n,s):i(t,n))||s);return o>3&&s&&Object.defineProperty(t,n,s),s},i=this&&this.__metadata||function(e,t){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(e,t)},o=n(0),s=function(){function DomHandler(){}return DomHandler.prototype.addClass=function(e,t){e.classList?e.classList.add(t):e.className+=" "+t},DomHandler.prototype.addMultipleClasses=function(e,t){if(e.classList)for(var n=t.split(" "),r=0;rwindow.innerHeight?-1*i.height:o,r=a.left+i.width>window.innerWidth?s-i.width:0,e.style.top=n+"px",e.style.left=r+"px"},DomHandler.prototype.absolutePosition=function(e,t){var n,r,i=e.offsetParent?{width:e.offsetWidth,height:e.offsetHeight}:this.getHiddenElementDimensions(e),o=i.height,s=i.width,a=t.offsetHeight,l=t.offsetWidth,c=t.getBoundingClientRect(),u=this.getWindowScrollTop(),p=this.getWindowScrollLeft();n=c.top+a+o>window.innerHeight?c.top+u-o:a+c.top+u,r=c.left+l+s>window.innerWidth?c.left+p+l-s:c.left+p,e.style.top=n+"px",e.style.left=r+"px"},DomHandler.prototype.getHiddenElementOuterHeight=function(e){e.style.visibility="hidden",e.style.display="block";var t=e.offsetHeight;return e.style.display="none",e.style.visibility="visible",t},DomHandler.prototype.getHiddenElementOuterWidth=function(e){e.style.visibility="hidden",e.style.display="block";var t=e.offsetWidth;return e.style.display="none",e.style.visibility="visible",t},DomHandler.prototype.getHiddenElementDimensions=function(e){var t={};return e.style.visibility="hidden",e.style.display="block",t.width=e.offsetWidth,t.height=e.offsetHeight,e.style.display="none",e.style.visibility="visible",t},DomHandler.prototype.scrollInView=function(e,t){var n=getComputedStyle(e).getPropertyValue("borderTopWidth"),r=n?parseFloat(n):0,i=getComputedStyle(e).getPropertyValue("paddingTop"),o=i?parseFloat(i):0,s=e.getBoundingClientRect(),a=t.getBoundingClientRect(),l=a.top+document.body.scrollTop-(s.top+document.body.scrollTop)-r-o,c=e.scrollTop,u=e.clientHeight,p=this.getOuterHeight(t);l<0?e.scrollTop=c+l:l+p>u&&(e.scrollTop=c+l-u+p)},DomHandler.prototype.fadeIn=function(e,t){e.style.opacity=0;var n=+new Date,r=function(){e.style.opacity=+e.style.opacity+((new Date).getTime()-n)/t,n=+new Date,+e.style.opacity<1&&(window.requestAnimationFrame&&requestAnimationFrame(r)||setTimeout(r,16))};r()},DomHandler.prototype.fadeOut=function(e,t){var n=1,r=50,i=t,o=r/i,s=setInterval(function(){n-=o,e.style.opacity=n,n<=0&&clearInterval(s)},r)},DomHandler.prototype.getWindowScrollTop=function(){var e=document.documentElement;return(window.pageYOffset||e.scrollTop)-(e.clientTop||0)},DomHandler.prototype.getWindowScrollLeft=function(){var e=document.documentElement;return(window.pageXOffset||e.scrollLeft)-(e.clientLeft||0)},DomHandler.prototype.matches=function(e,t){var n=Element.prototype,r=n.matches||n.webkitMatchesSelector||n.mozMatchesSelector||n.msMatchesSelector||function(e){return[].indexOf.call(document.querySelectorAll(e),this)!==-1};return r.call(e,t)},DomHandler.prototype.getOuterWidth=function(e,t){var n=e.offsetWidth;if(t){var r=getComputedStyle(e);n+=parseInt(r.paddingLeft)+parseInt(r.paddingRight)}return n},DomHandler.prototype.getHorizontalMargin=function(e){var t=getComputedStyle(e);return parseInt(t.marginLeft)+parseInt(t.marginRight)},DomHandler.prototype.innerWidth=function(e){var t=e.offsetWidth,n=getComputedStyle(e);return t+=parseInt(n.paddingLeft)+parseInt(n.paddingRight)},DomHandler.prototype.width=function(e){var t=e.offsetWidth,n=getComputedStyle(e);return t-=parseInt(n.paddingLeft)+parseInt(n.paddingRight)},DomHandler.prototype.getOuterHeight=function(e,t){var n=e.offsetHeight;if(t){var r=getComputedStyle(e);n+=parseInt(r.marginTop)+parseInt(r.marginBottom)}return n},DomHandler.prototype.getHeight=function(e){var t=e.offsetHeight,n=getComputedStyle(e);return t-=parseInt(n.paddingTop)+parseInt(n.paddingBottom)+parseInt(n.borderTopWidth)+parseInt(n.borderBottomWidth)},DomHandler.prototype.getViewport=function(){var e=window,t=document,n=t.documentElement,r=t.getElementsByTagName("body")[0],i=e.innerWidth||n.clientWidth||r.clientWidth,o=e.innerHeight||n.clientHeight||r.clientHeight;return{width:i,height:o}},DomHandler.prototype.equals=function(e,t){if(null==e||null==t)return!1;if(e==t)return!0;if("object"==typeof e&&"object"==typeof t){for(var n in e){if(e.hasOwnProperty(n)!==t.hasOwnProperty(n))return!1;switch(typeof e[n]){case"object":if(!this.equals(e[n],t[n]))return!1;break;case"function":if("undefined"==typeof t[n]||"compare"!=n&&e[n].toString()!=t[n].toString())return!1;break;default:if(e[n]!=t[n])return!1}}for(var n in t)if("undefined"==typeof e[n])return!1;return!0}return!1},DomHandler.zindex=1e3,DomHandler=r([o.Injectable(),i("design:paramtypes",[])],DomHandler)}();t.DomHandler=s},[1104,5],function(e,t,n){"use strict";var r=this&&this.__extends||function(e,t){function __(){this.constructor=e}for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n]);e.prototype=null===t?Object.create(t):(__.prototype=t.prototype,new __)},i=n(6),o=function(e){function OuterSubscriber(){e.apply(this,arguments)}return r(OuterSubscriber,e),OuterSubscriber.prototype.notifyNext=function(e,t,n,r,i){this.destination.next(t)},OuterSubscriber.prototype.notifyError=function(e,t){this.destination.error(e)},OuterSubscriber.prototype.notifyComplete=function(e){this.destination.complete()},OuterSubscriber}(i.Subscriber);t.OuterSubscriber=o},function(e,t,n){"use strict";function subscribeToResult(e,t,n,u){var p=new c.InnerSubscriber(e,n,u);if(!p.isUnsubscribed){if(t instanceof s.Observable)return t._isScalar?(p.next(t.value),void p.complete()):t.subscribe(p);if(i.isArray(t)){for(var d=0,h=t.length;d=0;a--)(i=e[a])&&(s=(o<3?i(s):o>3?i(t,n,s):i(t,n))||s);return o>3&&s&&Object.defineProperty(t,n,s),s},i=this&&this.__metadata||function(e,t){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(e,t)},o=n(0),s=n(3),a=n(0),l=function(){function Header(){}return Header=r([a.Component({selector:"header",template:""}),i("design:paramtypes",[])],Header)}();t.Header=l;var c=function(){function Footer(){}return Footer=r([a.Component({selector:"footer",template:""}),i("design:paramtypes",[])],Footer)}();t.Footer=c;var u=function(){function TemplateWrapper(e){this.viewContainer=e}return TemplateWrapper.prototype.ngOnInit=function(){this.viewContainer.createEmbeddedView(this.templateRef,{$implicit:this.item})},r([o.Input(),i("design:type",Object)],TemplateWrapper.prototype,"item",void 0),r([o.Input("pTemplateWrapper"),i("design:type",o.TemplateRef)],TemplateWrapper.prototype,"templateRef",void 0),TemplateWrapper=r([o.Directive({selector:"[pTemplateWrapper]"}),i("design:paramtypes",[o.ViewContainerRef])],TemplateWrapper)}();t.TemplateWrapper=u;var p=function(){function Column(){this.sortFunction=new o.EventEmitter}return r([o.Input(),i("design:type",String)],Column.prototype,"field",void 0),r([o.Input(),i("design:type",String)],Column.prototype,"header",void 0),r([o.Input(),i("design:type",String)],Column.prototype,"footer",void 0),r([o.Input(),i("design:type",Object)],Column.prototype,"sortable",void 0),r([o.Input(),i("design:type",Boolean)],Column.prototype,"editable",void 0),r([o.Input(),i("design:type",Boolean)],Column.prototype,"filter",void 0),r([o.Input(),i("design:type",String)],Column.prototype,"filterMatchMode",void 0),r([o.Input(),i("design:type",Number)],Column.prototype,"rowspan",void 0),r([o.Input(),i("design:type",Number)],Column.prototype,"colspan",void 0),r([o.Input(),i("design:type",Object)],Column.prototype,"style",void 0),r([o.Input(),i("design:type",String)],Column.prototype,"styleClass",void 0),r([o.Input(),i("design:type",Boolean)],Column.prototype,"hidden",void 0),r([o.Input(),i("design:type",Boolean)],Column.prototype,"expander",void 0),r([o.Input(),i("design:type",String)],Column.prototype,"selectionMode",void 0),r([o.Output(),i("design:type",o.EventEmitter)],Column.prototype,"sortFunction",void 0),r([o.ContentChild(o.TemplateRef),i("design:type",o.TemplateRef)],Column.prototype,"template",void 0),Column=r([a.Component({selector:"p-column",template:""}),i("design:paramtypes",[])],Column)}();t.Column=p;var d=function(){function ColumnTemplateLoader(e){this.viewContainer=e}return ColumnTemplateLoader.prototype.ngOnInit=function(){this.viewContainer.createEmbeddedView(this.column.template,{$implicit:this.column,rowData:this.rowData,rowIndex:this.rowIndex})},r([o.Input(),i("design:type",Object)],ColumnTemplateLoader.prototype,"column",void 0),r([o.Input(),i("design:type",Object)],ColumnTemplateLoader.prototype,"rowData",void 0),r([o.Input(),i("design:type",Number)],ColumnTemplateLoader.prototype,"rowIndex",void 0),ColumnTemplateLoader=r([a.Component({selector:"p-columnTemplateLoader",template:""}),i("design:paramtypes",[o.ViewContainerRef])],ColumnTemplateLoader)}();t.ColumnTemplateLoader=d;var h=function(){function SharedModule(){}return SharedModule=r([o.NgModule({imports:[s.CommonModule],exports:[l,c,p,u,d],declarations:[l,c,p,u,d]}),i("design:paramtypes",[])],SharedModule)}();t.SharedModule=h},function(e,t,n){"use strict";var r=this&&this.__extends||function(e,t){function __(){this.constructor=e}for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n]);e.prototype=null===t?Object.create(t):(__.prototype=t.prototype,new __)},i=n(1),o=n(6),s=n(41),a=n(899),l=n(215),c=n(517),u=n(317),p=function(e){function Subject(t,n){e.call(this),this.destination=t,this.source=n,this.observers=[],this.isUnsubscribed=!1,this.isStopped=!1,this.hasErrored=!1,this.dispatching=!1,this.hasCompleted=!1,this.source=n}return r(Subject,e),Subject.prototype.lift=function(e){var t=new Subject(this.destination||this,this);return t.operator=e,t},Subject.prototype.add=function(e){return s.Subscription.prototype.add.call(this,e)},Subject.prototype.remove=function(e){s.Subscription.prototype.remove.call(this,e)},Subject.prototype.unsubscribe=function(){s.Subscription.prototype.unsubscribe.call(this)},Subject.prototype._subscribe=function(e){if(this.source)return this.source.subscribe(e);if(!e.isUnsubscribed){if(this.hasErrored)return e.error(this.errorValue);if(this.hasCompleted)return e.complete();this.throwIfUnsubscribed();var t=new a.SubjectSubscription(this,e);return this.observers.push(e),t}},Subject.prototype._unsubscribe=function(){this.source=null,this.isStopped=!0,this.observers=null,this.destination=null},Subject.prototype.next=function(e){this.throwIfUnsubscribed(),this.isStopped||(this.dispatching=!0,this._next(e),this.dispatching=!1,this.hasErrored?this._error(this.errorValue):this.hasCompleted&&this._complete())},Subject.prototype.error=function(e){this.throwIfUnsubscribed(),this.isStopped||(this.isStopped=!0,this.hasErrored=!0,this.errorValue=e,this.dispatching||this._error(e))},Subject.prototype.complete=function(){this.throwIfUnsubscribed(),this.isStopped||(this.isStopped=!0,this.hasCompleted=!0,this.dispatching||this._complete())},Subject.prototype.asObservable=function(){var e=new d(this);return e},Subject.prototype._next=function(e){this.destination?this.destination.next(e):this._finalNext(e)},Subject.prototype._finalNext=function(e){for(var t=-1,n=this.observers.slice(0),r=n.length;++t"+i+""};e.exports=function(e,t){var n={};n[e]=t(a),r(r.P+r.F*i(function(){var t=""[e]('"');return t!==t.toLowerCase()||t.split('"').length>3}),"String",n)}},function(e,t,n){"use strict";var r=n(81),i=n(514),o=n(217),s=n(42),a=n(38),l=n(513),c=function(){function Subscription(e){this.isUnsubscribed=!1,e&&(this._unsubscribe=e)}return Subscription.prototype.unsubscribe=function(){var e,t=!1;if(!this.isUnsubscribed){this.isUnsubscribed=!0;var n=this,c=n._unsubscribe,u=n._subscriptions;if(this._subscriptions=null,o.isFunction(c)){var p=s.tryCatch(c).call(this);p===a.errorObject&&(t=!0,(e=e||[]).push(a.errorObject.e))}if(r.isArray(u))for(var d=-1,h=u.length;++d0?i(r(e),9007199254740991):0}},function(e,t,n){"use strict";var r=n(1082);t.async=new r.AsyncScheduler},function(e,t,n){"use strict";function __export(e){for(var n in e)t.hasOwnProperty(n)||(t[n]=e[n])}var r=n(86);t.HostMetadata=r.HostMetadata,t.InjectMetadata=r.InjectMetadata,t.InjectableMetadata=r.InjectableMetadata,t.OptionalMetadata=r.OptionalMetadata,t.SelfMetadata=r.SelfMetadata,t.SkipSelfMetadata=r.SkipSelfMetadata,__export(n(115));var i=n(162);t.forwardRef=i.forwardRef,t.resolveForwardRef=i.resolveForwardRef;var o=n(163);t.Injector=o.Injector;var s=n(571);t.ReflectiveInjector=s.ReflectiveInjector;var a=n(250);t.Binding=a.Binding,t.ProviderBuilder=a.ProviderBuilder,t.bind=a.bind,t.Provider=a.Provider,t.provide=a.provide;var l=n(253);t.ResolvedReflectiveFactory=l.ResolvedReflectiveFactory;var c=n(252);t.ReflectiveKey=c.ReflectiveKey;var u=n(251);t.NoProviderError=u.NoProviderError,t.AbstractProviderError=u.AbstractProviderError,t.CyclicDependencyError=u.CyclicDependencyError,t.InstantiationError=u.InstantiationError,t.InvalidProviderError=u.InvalidProviderError,t.NoAnnotationError=u.NoAnnotationError,t.OutOfBoundsError=u.OutOfBoundsError;var p=n(374);t.OpaqueToken=p.OpaqueToken},[1104,32],function(e,t){var n={}.hasOwnProperty;e.exports=function(e,t){return n.call(e,t)}},function(e,t,n){"use strict";var r=n(13);e.exports=function(e,t){return!!e&&r(function(){t?e.call(null,function(){},1):e.call(null)})}},function(e,t,n){var r=n(75);e.exports=function(e){return Object(r(e))}},function(e,t,n){"use strict";(function(e,n){var r={"boolean":!1,"function":!0,object:!0,number:!1,string:!1,undefined:!1};t.root=r[typeof self]&&self||r[typeof window]&&window;var i=(r[typeof t]&&t&&!t.nodeType&&t,r[typeof e]&&e&&!e.nodeType&&e,r[typeof n]&&n);!i||i.global!==i&&i.window!==i||(t.root=i)}).call(t,n(1100)(e),n(82))},function(e,t,n){"use strict";var r=n(0);t.NG_VALUE_ACCESSOR=new r.OpaqueToken("NgValueAccessor")},52,function(e,t,n){"use strict";function _convertToPromise(e){return s.isPromise(e)?e:i.toPromise.call(e)}function _executeValidators(e,t){return t.map(function(t){return t(e)})}function _executeAsyncValidators(e,t){return t.map(function(t){return t(e)})}function _mergeErrors(e){var t=e.reduce(function(e,t){return s.isPresent(t)?o.StringMapWrapper.merge(e,t):e},{});return o.StringMapWrapper.isEmpty(t)?null:t}var r=n(0),i=n(313),o=n(47),s=n(32);t.NG_VALIDATORS=new r.OpaqueToken("NgValidators"),t.NG_ASYNC_VALIDATORS=new r.OpaqueToken("NgAsyncValidators");var a=function(){function Validators(){}return Validators.required=function(e){return s.isBlank(e.value)||s.isString(e.value)&&""==e.value?{required:!0}:null},Validators.minLength=function(e){return function(t){if(s.isPresent(Validators.required(t)))return null;var n=t.value;return n.lengthe?{maxlength:{requiredLength:e,actualLength:n.length}}:null}},Validators.pattern=function(e){return function(t){if(s.isPresent(Validators.required(t)))return null;var n=new RegExp("^"+e+"$"),r=t.value;return n.test(r)?null:{pattern:{requiredPattern:"^"+e+"$",actualValue:r}}}},Validators.nullValidator=function(e){return null},Validators.compose=function(e){if(s.isBlank(e))return null;var t=e.filter(s.isPresent);return 0==t.length?null:function(e){return _mergeErrors(_executeValidators(e,t))}},Validators.composeAsync=function(e){if(s.isBlank(e))return null;var t=e.filter(s.isPresent);return 0==t.length?null:function(e){var n=_executeAsyncValidators(e,t).map(_convertToPromise);return Promise.all(n).then(_mergeErrors)}},Validators}();t.Validators=a},function(e,t,n){"use strict";var r=n(0),i=n(123),o=n(72),s=n(16),a=n(126),l=n(278);t.PRIMITIVE=String;var c=function(){function Serializer(e){this._renderStore=e}return Serializer.prototype.serialize=function(e,n){var i=this;if(!s.isPresent(e))return null;if(s.isArray(e))return e.map(function(e){return i.serialize(e,n)});if(n==t.PRIMITIVE)return e;if(n==u)return this._renderStore.serialize(e);if(n===r.RenderComponentType)return this._serializeRenderComponentType(e);if(n===r.ViewEncapsulation)return s.serializeEnum(e);if(n===l.LocationType)return this._serializeLocation(e);throw new o.BaseException("No serializer for "+n.toString())},Serializer.prototype.deserialize=function(e,n,a){var c=this;if(!s.isPresent(e))return null;if(s.isArray(e)){var p=[];return e.forEach(function(e){return p.push(c.deserialize(e,n,a))}),p}if(n==t.PRIMITIVE)return e;if(n==u)return this._renderStore.deserialize(e);if(n===r.RenderComponentType)return this._deserializeRenderComponentType(e);if(n===r.ViewEncapsulation)return i.VIEW_ENCAPSULATION_VALUES[e];if(n===l.LocationType)return this._deserializeLocation(e);throw new o.BaseException("No deserializer for "+n.toString())},Serializer.prototype._serializeLocation=function(e){return{href:e.href,protocol:e.protocol,host:e.host,hostname:e.hostname,port:e.port,pathname:e.pathname,search:e.search,hash:e.hash,origin:e.origin}},Serializer.prototype._deserializeLocation=function(e){return new l.LocationType(e.href,e.protocol,e.host,e.hostname,e.port,e.pathname,e.search,e.hash,e.origin)},Serializer.prototype._serializeRenderComponentType=function(e){return{id:e.id,templateUrl:e.templateUrl,slotCount:e.slotCount,encapsulation:this.serialize(e.encapsulation,r.ViewEncapsulation),styles:this.serialize(e.styles,t.PRIMITIVE)}},Serializer.prototype._deserializeRenderComponentType=function(e){return new r.RenderComponentType(e.id,e.templateUrl,e.slotCount,this.deserialize(e.encapsulation,r.ViewEncapsulation),this.deserialize(e.styles,t.PRIMITIVE),{})},Serializer.decorators=[{type:r.Injectable}],Serializer.ctorParameters=[{type:a.RenderStore}],Serializer}();t.Serializer=c;var u=function(){function RenderStoreObject(){}return RenderStoreObject}();t.RenderStoreObject=u},function(e,t,n){var r=n(2),i=n(24),o=n(13);e.exports=function(e,t){var n=(i.Object||{})[e]||Object[e],s={};s[e]=t(n),r(r.S+r.F*o(function(){n(1)}),"Object",s)}},function(e,t,n){var r=n(133),i=n(75);e.exports=function(e){return r(i(e))}},function(e,t,n){"use strict";function _convertToPromise(e){return s.isPromise(e)?e:i.toPromise.call(e)}function _executeValidators(e,t){return t.map(function(t){return t(e)})}function _executeAsyncValidators(e,t){return t.map(function(t){return t(e)})}function _mergeErrors(e){var t=e.reduce(function(e,t){return s.isPresent(t)?o.StringMapWrapper.merge(e,t):e},{});return o.StringMapWrapper.isEmpty(t)?null:t}var r=n(0),i=n(313),o=n(34),s=n(7);t.NG_VALIDATORS=new r.OpaqueToken("NgValidators"),t.NG_ASYNC_VALIDATORS=new r.OpaqueToken("NgAsyncValidators");var a=function(){function Validators(){}return Validators.required=function(e){return s.isBlank(e.value)||s.isString(e.value)&&""==e.value?{required:!0}:null},Validators.minLength=function(e){return function(t){if(s.isPresent(Validators.required(t)))return null;var n=t.value;return n.lengthe?{maxlength:{requiredLength:e,actualLength:n.length}}:null}},Validators.pattern=function(e){return function(t){if(s.isPresent(Validators.required(t)))return null;var n=new RegExp("^"+e+"$"),r=t.value;return n.test(r)?null:{pattern:{requiredPattern:"^"+e+"$",actualValue:r}}}},Validators.nullValidator=function(e){return null},Validators.compose=function(e){if(s.isBlank(e))return null;var t=e.filter(s.isPresent);return 0==t.length?null:function(e){return _mergeErrors(_executeValidators(e,t))}},Validators.composeAsync=function(e){if(s.isBlank(e))return null;var t=e.filter(s.isPresent);return 0==t.length?null:function(e){var n=_executeAsyncValidators(e,t).map(_convertToPromise);return Promise.all(n).then(_mergeErrors)}},Validators}();t.Validators=a},function(e,t,n){"use strict";var r=this&&this.__extends||function(e,t){function __(){this.constructor=e}for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n]);e.prototype=null===t?Object.create(t):(__.prototype=t.prototype,new __)},i=n(83),o=n(7),s=function(e){function InvalidPipeArgumentException(t,n){e.call(this,"Invalid argument '"+n+"' for pipe '"+o.stringify(t)+"'")}return r(InvalidPipeArgumentException,e),InvalidPipeArgumentException}(i.BaseException);t.InvalidPipeArgumentException=s},function(e,t,n){"use strict";/** * @license * Copyright Google Inc. All Rights Reserved. * * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://angular.io/license */ -var r=n(5),i=function(){function ParseLocation(e,t,n,r){this.file=e,this.offset=t,this.line=n,this.col=r}return ParseLocation.prototype.toString=function(){return r.isPresent(this.offset)?this.file.url+"@"+this.line+":"+this.col:this.file.url},ParseLocation}();t.ParseLocation=i;var o=function(){function ParseSourceFile(e,t){this.content=e,this.url=t}return ParseSourceFile}();t.ParseSourceFile=o;var s=function(){function ParseSourceSpan(e,t,n){void 0===n&&(n=null),this.start=e,this.end=t,this.details=n}return ParseSourceSpan.prototype.toString=function(){return this.start.file.content.substring(this.start.offset,this.end.offset)},ParseSourceSpan}();t.ParseSourceSpan=s,function(e){e[e.WARNING=0]="WARNING",e[e.FATAL=1]="FATAL"}(t.ParseErrorLevel||(t.ParseErrorLevel={}));var a=t.ParseErrorLevel,l=function(){function ParseError(e,t,n){void 0===n&&(n=a.FATAL),this.span=e,this.msg=t,this.level=n}return ParseError.prototype.toString=function(){var e=this.span.start.file.content,t=this.span.start.offset,n="",i="";if(r.isPresent(t)){t>e.length-1&&(t=e.length-1);for(var o=t,s=0,a=0;s<100&&t>0&&(t--,s++,"\n"!=e[t]||3!=++a););for(s=0,a=0;s<100&&o]"+e.substring(this.span.start.offset,o+1);n=' ("'+l+'")'}return this.span.details&&(i=", "+this.span.details),""+this.msg+n+": "+this.span.start+i},ParseError}();t.ParseError=l},function(e,t,n){"use strict";function templateVisitAll(e,t,n){void 0===n&&(n=null);var i=[];return t.forEach(function(t){var o=t.visit(e,n);r.isPresent(o)&&i.push(o)}),i}var r=n(5),i=function(){function TextAst(e,t,n){this.value=e,this.ngContentIndex=t,this.sourceSpan=n}return TextAst.prototype.visit=function(e,t){return e.visitText(this,t)},TextAst}();t.TextAst=i;var o=function(){function BoundTextAst(e,t,n){this.value=e,this.ngContentIndex=t,this.sourceSpan=n}return BoundTextAst.prototype.visit=function(e,t){return e.visitBoundText(this,t)},BoundTextAst}();t.BoundTextAst=o;var s=function(){function AttrAst(e,t,n){this.name=e,this.value=t,this.sourceSpan=n}return AttrAst.prototype.visit=function(e,t){return e.visitAttr(this,t)},AttrAst}();t.AttrAst=s;var a=function(){function BoundElementPropertyAst(e,t,n,r,i,o){this.name=e,this.type=t,this.securityContext=n,this.value=r,this.unit=i,this.sourceSpan=o}return BoundElementPropertyAst.prototype.visit=function(e,t){return e.visitElementProperty(this,t)},BoundElementPropertyAst}();t.BoundElementPropertyAst=a;var l=function(){function BoundEventAst(e,t,n,r){this.name=e,this.target=t,this.handler=n,this.sourceSpan=r}return BoundEventAst.prototype.visit=function(e,t){return e.visitEvent(this,t)},Object.defineProperty(BoundEventAst.prototype,"fullName",{get:function(){return r.isPresent(this.target)?this.target+":"+this.name:this.name},enumerable:!0,configurable:!0}),BoundEventAst}();t.BoundEventAst=l;var c=function(){function ReferenceAst(e,t,n){this.name=e,this.value=t,this.sourceSpan=n}return ReferenceAst.prototype.visit=function(e,t){return e.visitReference(this,t)},ReferenceAst}();t.ReferenceAst=c;var u=function(){function VariableAst(e,t,n){this.name=e,this.value=t,this.sourceSpan=n}return VariableAst.prototype.visit=function(e,t){return e.visitVariable(this,t)},VariableAst}();t.VariableAst=u;var p=function(){function ElementAst(e,t,n,r,i,o,s,a,l,c,u){this.name=e,this.attrs=t,this.inputs=n,this.outputs=r,this.references=i,this.directives=o,this.providers=s,this.hasViewContainer=a,this.children=l,this.ngContentIndex=c,this.sourceSpan=u}return ElementAst.prototype.visit=function(e,t){return e.visitElement(this,t)},ElementAst}();t.ElementAst=p;var d=function(){function EmbeddedTemplateAst(e,t,n,r,i,o,s,a,l,c){this.attrs=e,this.outputs=t,this.references=n,this.variables=r,this.directives=i,this.providers=o,this.hasViewContainer=s,this.children=a,this.ngContentIndex=l,this.sourceSpan=c}return EmbeddedTemplateAst.prototype.visit=function(e,t){return e.visitEmbeddedTemplate(this,t)},EmbeddedTemplateAst}();t.EmbeddedTemplateAst=d;var h=function(){function BoundDirectivePropertyAst(e,t,n,r){this.directiveName=e,this.templateName=t,this.value=n,this.sourceSpan=r}return BoundDirectivePropertyAst.prototype.visit=function(e,t){return e.visitDirectiveProperty(this,t)},BoundDirectivePropertyAst}();t.BoundDirectivePropertyAst=h;var f=function(){function DirectiveAst(e,t,n,r,i){this.directive=e,this.inputs=t,this.hostProperties=n,this.hostEvents=r,this.sourceSpan=i}return DirectiveAst.prototype.visit=function(e,t){return e.visitDirective(this,t)},DirectiveAst}();t.DirectiveAst=f;var m=function(){function ProviderAst(e,t,n,r,i,o,s){this.token=e,this.multiProvider=t,this.eager=n,this.providers=r,this.providerType=i,this.lifecycleHooks=o,this.sourceSpan=s}return ProviderAst.prototype.visit=function(e,t){return null},ProviderAst}();t.ProviderAst=m,function(e){e[e.PublicService=0]="PublicService",e[e.PrivateService=1]="PrivateService",e[e.Component=2]="Component",e[e.Directive=3]="Directive",e[e.Builtin=4]="Builtin"}(t.ProviderAstType||(t.ProviderAstType={}));var y=(t.ProviderAstType,function(){function NgContentAst(e,t,n){this.index=e,this.ngContentIndex=t,this.sourceSpan=n}return NgContentAst.prototype.visit=function(e,t){return e.visitNgContent(this,t)},NgContentAst}());t.NgContentAst=y,function(e){e[e.Property=0]="Property",e[e.Attribute=1]="Attribute",e[e.Class=2]="Class",e[e.Style=3]="Style",e[e.Animation=4]="Animation"}(t.PropertyBindingType||(t.PropertyBindingType={}));t.PropertyBindingType;t.templateVisitAll=templateVisitAll},function(e,t){"use strict";var n=function(){function MessageBus(){}return MessageBus}();t.MessageBus=n},function(e,t){"use strict";t.PRIMARY_OUTLET="primary"},function(e,t,n){var r=n(106),i=n(133),o=n(50),s=n(44),a=n(676);e.exports=function(e,t){var n=1==e,l=2==e,c=3==e,u=4==e,p=6==e,d=5==e||p,h=t||a;return function(t,a,f){for(var m,y,g=o(t),v=i(g),b=r(a,f,3),_=s(v.length),w=0,S=n?h(t,_):l?h(t,0):void 0;_>w;w++)if((d||w in v)&&(m=v[w],y=b(m,w,g),e))if(n)S[w]=y;else if(y)switch(e){case 3:return!0;case 5:return m;case 6:return w;case 2:S.push(m)}else if(u)return!1;return p?-1:c||u?u:S}}},function(e,t,n){var r=n(30),i=n(109);e.exports=n(35)?function(e,t,n){return r.f(e,t,i(1,n))}:function(e,t,n){return e[t]=n,e}},function(e,t,n){var r=n(472),i=n(2),o=n(199)("metadata"),s=o.store||(o.store=new(n(798))),a=function(e,t,n){var i=s.get(e);if(!i){if(!n)return;s.set(e,i=new r)}var o=i.get(t);if(!o){if(!n)return;i.set(t,o=new r)}return o},l=function(e,t,n){var r=a(t,n,!1);return void 0!==r&&r.has(e)},c=function(e,t,n){var r=a(t,n,!1);return void 0===r?void 0:r.get(e)},u=function(e,t,n,r){a(n,r,!0).set(e,t)},p=function(e,t){var n=a(e,t,!1),r=[];return n&&n.forEach(function(e,t){r.push(t)}),r},d=function(e){return void 0===e||"symbol"==typeof e?e:String(e)},h=function(e){i(i.S,"Reflect",e)};e.exports={store:s,map:a,has:l,get:c,set:u,keys:p,key:d,exp:h}},function(e,t,n){var r=n(48),i=n(50),o=n(300)("IE_PROTO"),s=Object.prototype;e.exports=Object.getPrototypeOf||function(e){return e=i(e),r(e,o)?e[o]:"function"==typeof e.constructor&&e instanceof e.constructor?e.constructor.prototype:e instanceof Object?s:null}},function(e,t,n){"use strict";var r=n(347),i=function(){function InterpolationConfig(e,t){this.start=e,this.end=t}return InterpolationConfig.fromArray=function(e){return e?(r.assertInterpolationSymbols("interpolation",e),new InterpolationConfig(e[0],e[1])):t.DEFAULT_INTERPOLATION_CONFIG},InterpolationConfig}();t.InterpolationConfig=i,t.DEFAULT_INTERPOLATION_CONFIG=new i("{{","}}")},[1107,263],function(e,t,n){"use strict";function controlPath(e,t){var n=r.ListWrapper.clone(t.path);return n.push(e),n}function setUpControl(e,t){o.isBlank(e)&&_throwError(t,"Cannot find control with"),o.isBlank(t.valueAccessor)&&_throwError(t,"No value accessor for form control with"),e.validator=s.Validators.compose([e.validator,t.validator]),e.asyncValidator=s.Validators.composeAsync([e.asyncValidator,t.asyncValidator]),t.valueAccessor.writeValue(e.value),t.valueAccessor.registerOnChange(function(n){t.viewToModelUpdate(n),e.markAsDirty(),e.setValue(n,{emitModelToViewChange:!1})}),e.registerOnChange(function(e,n){t.valueAccessor.writeValue(e),n&&t.viewToModelUpdate(e)}),t.valueAccessor.registerOnTouched(function(){return e.markAsTouched()})}function setUpFormContainer(e,t){o.isBlank(e)&&_throwError(t,"Cannot find control with"),e.validator=s.Validators.compose([e.validator,t.validator]),e.asyncValidator=s.Validators.composeAsync([e.asyncValidator,t.asyncValidator])}function _throwError(e,t){var n;throw n=e.path.length>1?"path: '"+e.path.join(" -> ")+"'":e.path[0]?"name: '"+e.path+"'":"unspecified name attribute",new i.BaseException(t+" "+n)}function composeValidators(e){return o.isPresent(e)?s.Validators.compose(e.map(c.normalizeValidator)):null}function composeAsyncValidators(e){return o.isPresent(e)?s.Validators.composeAsync(e.map(c.normalizeAsyncValidator)):null}function isPropertyUpdated(e,t){if(!r.StringMapWrapper.contains(e,"model"))return!1;var n=e.model;return!!n.isFirstChange()||!o.looseIdentical(t,n.currentValue)}function selectValueAccessor(e,t){if(o.isBlank(t))return null;var n,r,i;return t.forEach(function(t){o.hasConstructor(t,l.DefaultValueAccessor)?n=t:o.hasConstructor(t,a.CheckboxControlValueAccessor)||o.hasConstructor(t,u.NumberValueAccessor)||o.hasConstructor(t,d.SelectControlValueAccessor)||o.hasConstructor(t,h.SelectMultipleControlValueAccessor)||o.hasConstructor(t,p.RadioControlValueAccessor)?(o.isPresent(r)&&_throwError(e,"More than one built-in value accessor matches form control with"),r=t):(o.isPresent(i)&&_throwError(e,"More than one custom value accessor matches form control with"),i=t)}),o.isPresent(i)?i:o.isPresent(r)?r:o.isPresent(n)?n:(_throwError(e,"No valid value accessor for form control with"),null)}var r=n(47),i=n(88),o=n(32),s=n(54),a=n(169),l=n(170),c=n(587),u=n(266),p=n(172),d=n(173),h=n(174);t.controlPath=controlPath,t.setUpControl=setUpControl,t.setUpFormContainer=setUpFormContainer,t.composeValidators=composeValidators,t.composeAsyncValidators=composeAsyncValidators,t.isPropertyUpdated=isPropertyUpdated,t.selectValueAccessor=selectValueAccessor},function(e,t){"use strict";!function(e){e[e.Get=0]="Get",e[e.Post=1]="Post",e[e.Put=2]="Put",e[e.Delete=3]="Delete",e[e.Options=4]="Options",e[e.Head=5]="Head",e[e.Patch=6]="Patch"}(t.RequestMethod||(t.RequestMethod={}));t.RequestMethod;!function(e){e[e.Unsent=0]="Unsent",e[e.Open=1]="Open",e[e.HeadersReceived=2]="HeadersReceived",e[e.Loading=3]="Loading",e[e.Done=4]="Done",e[e.Cancelled=5]="Cancelled"}(t.ReadyState||(t.ReadyState={}));t.ReadyState;!function(e){e[e.Basic=0]="Basic",e[e.Cors=1]="Cors",e[e.Default=2]="Default",e[e.Error=3]="Error",e[e.Opaque=4]="Opaque"}(t.ResponseType||(t.ResponseType={}));t.ResponseType;!function(e){e[e.NONE=0]="NONE",e[e.JSON=1]="JSON",e[e.FORM=2]="FORM",e[e.FORM_DATA=3]="FORM_DATA",e[e.TEXT=4]="TEXT",e[e.BLOB=5]="BLOB",e[e.ARRAY_BUFFER=6]="ARRAY_BUFFER"}(t.ContentType||(t.ContentType={}));t.ContentType;!function(e){e[e.Text=0]="Text",e[e.Json=1]="Json",e[e.ArrayBuffer=2]="ArrayBuffer",e[e.Blob=3]="Blob"}(t.ResponseContentType||(t.ResponseContentType={}));t.ResponseContentType},[1106,418,419,419],function(e,t,n){"use strict";function createEmptyUrlTree(){return new o(new s([],{}),{},null)}function containsTree(e,t,n){return n?equalSegmentGroups(e.root,t.root):containsSegmentGroup(e.root,t.root)}function equalSegmentGroups(e,t){if(!equalPath(e.segments,t.segments))return!1;if(e.numberOfChildren!==t.numberOfChildren)return!1;for(var n in t.children){if(!e.children[n])return!1;if(!equalSegmentGroups(e.children[n],t.children[n]))return!1}return!0}function containsSegmentGroup(e,t){return containsSegmentGroupHelper(e,t,t.segments)}function containsSegmentGroupHelper(e,t,n){if(e.segments.length>n.length){var i=e.segments.slice(0,n.length);return!!equalPath(i,n)&&!t.hasChildren()}if(e.segments.length===n.length){if(!equalPath(e.segments,n))return!1;for(var o in t.children){if(!e.children[o])return!1;if(!containsSegmentGroup(e.children[o],t.children[o]))return!1}return!0}var i=n.slice(0,e.segments.length),s=n.slice(e.segments.length);return!!equalPath(e.segments,i)&&(!!e.children[r.PRIMARY_OUTLET]&&containsSegmentGroupHelper(e.children[r.PRIMARY_OUTLET],t,s))}function equalSegments(e,t){if(e.length!==t.length)return!1;for(var n=0;n0?n+"("+o.join("//")+")":""+n}if(e.hasChildren()&&!t){var s=mapChildrenIntoArray(e,function(t,n){return n===r.PRIMARY_OUTLET?[serializeSegment(e.children[r.PRIMARY_OUTLET],!1)]:[n+":"+serializeSegment(t,!1)]});return serializePaths(e)+"/("+s.join("//")+")"}return serializePaths(e)}function encode(e){return encodeURIComponent(e)}function decode(e){return decodeURIComponent(e)}function serializePath(e){return""+encode(e.path)+serializeParams(e.parameters)}function serializeParams(e){return pairs(e).map(function(e){return";"+encode(e.first)+"="+encode(e.second)}).join("")}function serializeQueryParams(e){var t=pairs(e).map(function(e){return encode(e.first)+"="+encode(e.second)});return t.length>0?"?"+t.join("&"):""}function pairs(e){var t=[];for(var n in e)e.hasOwnProperty(n)&&t.push(new u(n,e[n]));return t}function matchSegments(e){p.lastIndex=0;var t=e.match(p);return t?t[0]:""}function matchQueryParams(e){d.lastIndex=0;var t=e.match(p);return t?t[0]:""}function matchUrlQueryParamValue(e){h.lastIndex=0;var t=e.match(h);return t?t[0]:""}var r=n(63),i=n(74);t.createEmptyUrlTree=createEmptyUrlTree,t.containsTree=containsTree;var o=function(){function UrlTree(e,t,n){this.root=e,this.queryParams=t,this.fragment=n}return UrlTree.prototype.toString=function(){return(new c).serialize(this)},UrlTree}();t.UrlTree=o;var s=function(){function UrlSegmentGroup(e,t){var n=this;this.segments=e,this.children=t,this.parent=null,i.forEach(t,function(e,t){return e.parent=n})}return UrlSegmentGroup.prototype.hasChildren=function(){return this.numberOfChildren>0},Object.defineProperty(UrlSegmentGroup.prototype,"numberOfChildren",{get:function(){return Object.keys(this.children).length},enumerable:!0,configurable:!0}),UrlSegmentGroup.prototype.toString=function(){return serializePaths(this)},UrlSegmentGroup}();t.UrlSegmentGroup=s;var a=function(){function UrlSegment(e,t){this.path=e,this.parameters=t}return UrlSegment.prototype.toString=function(){return serializePath(this)},UrlSegment}();t.UrlSegment=a,t.equalSegments=equalSegments,t.equalPath=equalPath,t.mapChildrenIntoArray=mapChildrenIntoArray;var l=function(){function UrlSerializer(){}return UrlSerializer}();t.UrlSerializer=l;var c=function(){function DefaultUrlSerializer(){}return DefaultUrlSerializer.prototype.parse=function(e){var t=new f(e);return new o(t.parseRootSegment(),t.parseQueryParams(),t.parseFragment())},DefaultUrlSerializer.prototype.serialize=function(e){var t="/"+serializeSegment(e.root,!0),n=serializeQueryParams(e.queryParams),r=null!==e.fragment&&void 0!==e.fragment?"#"+encodeURIComponent(e.fragment):"";return""+t+n+r},DefaultUrlSerializer}();t.DefaultUrlSerializer=c,t.serializePaths=serializePaths,t.encode=encode,t.decode=decode,t.serializePath=serializePath;var u=function(){function Pair(e,t){this.first=e,this.second=t}return Pair}(),p=/^[^\/\(\)\?;=&#]+/,d=/^[^=\?&#]+/,h=/^[^\?&#]+/,f=function(){function UrlParser(e){this.url=e,this.remaining=e}return UrlParser.prototype.peekStartsWith=function(e){return this.remaining.startsWith(e)},UrlParser.prototype.capture=function(e){if(!this.remaining.startsWith(e))throw new Error('Expected "'+e+'".');this.remaining=this.remaining.substring(e.length)},UrlParser.prototype.parseRootSegment=function(){return this.remaining.startsWith("/")&&this.capture("/"),""===this.remaining||this.remaining.startsWith("?")||this.remaining.startsWith("#")?new s([],{}):new s([],this.parseChildren())},UrlParser.prototype.parseChildren=function(){if(0==this.remaining.length)return{};this.peekStartsWith("/")&&this.capture("/");var e=[];for(this.peekStartsWith("(")||e.push(this.parseSegments());this.peekStartsWith("/")&&!this.peekStartsWith("//")&&!this.peekStartsWith("/(");)this.capture("/"),e.push(this.parseSegments());var t={};this.peekStartsWith("/(")&&(this.capture("/"),t=this.parseParens(!0));var n={};return this.peekStartsWith("(")&&(n=this.parseParens(!1)),(e.length>0||Object.keys(t).length>0)&&(n[r.PRIMARY_OUTLET]=new s(e,t)),n},UrlParser.prototype.parseSegments=function(){var e=matchSegments(this.remaining);if(""===e&&this.peekStartsWith(";"))throw new Error("Empty path url segment cannot have parameters: '"+this.remaining+"'.");this.capture(e);var t={};return this.peekStartsWith(";")&&(t=this.parseMatrixParams()),new a(decode(e),t)},UrlParser.prototype.parseQueryParams=function(){var e={};if(this.peekStartsWith("?"))for(this.capture("?"),this.parseQueryParam(e);this.remaining.length>0&&this.peekStartsWith("&");)this.capture("&"),this.parseQueryParam(e);return e},UrlParser.prototype.parseFragment=function(){return this.peekStartsWith("#")?decode(this.remaining.substring(1)):null},UrlParser.prototype.parseMatrixParams=function(){for(var e={};this.remaining.length>0&&this.peekStartsWith(";");)this.capture(";"),this.parseParam(e);return e},UrlParser.prototype.parseParam=function(e){var t=matchSegments(this.remaining);if(t){this.capture(t);var n="true";if(this.peekStartsWith("=")){this.capture("=");var r=matchSegments(this.remaining);r&&(n=r,this.capture(n))}e[decode(t)]=decode(n)}},UrlParser.prototype.parseQueryParam=function(e){var t=matchQueryParams(this.remaining);if(t){this.capture(t);var n="";if(this.peekStartsWith("=")){this.capture("=");var r=matchUrlQueryParamValue(this.remaining);r&&(n=r,this.capture(n))}e[decode(t)]=decode(n)}},UrlParser.prototype.parseParens=function(e){var t={};for(this.capture("(");!this.peekStartsWith(")")&&this.remaining.length>0;){var n=matchSegments(this.remaining),i=this.remaining[n.length];if("/"!==i&&")"!==i&&";"!==i)throw new Error("Cannot parse url '"+this.url+"'");var o=void 0;n.indexOf(":")>-1?(o=n.substr(0,n.indexOf(":")),this.capture(o),this.capture(":")):e&&(o=r.PRIMARY_OUTLET);var a=this.parseChildren();t[o]=1===Object.keys(a).length?a[r.PRIMARY_OUTLET]:new s([],a),this.peekStartsWith("//")&&this.capture("//")}return this.capture(")"),t},UrlParser}()},function(e,t,n){"use strict";function shallowEqualArrays(e,t){if(e.length!==t.length)return!1;for(var n=0;n0?e[0]:null}function last(e){return e.length>0?e[e.length-1]:null}function and(e){return e.reduce(function(e,t){return e&&t},!0)}function merge(e,t){var n={};for(var r in e)e.hasOwnProperty(r)&&(n[r]=e[r]);for(var r in t)t.hasOwnProperty(r)&&(n[r]=t[r]);return n}function forEach(e,t){for(var n in e)e.hasOwnProperty(n)&&t(e[n],n)}function waitForMap(e,t){var n=[],r={};return forEach(e,function(e,i){i===s.PRIMARY_OUTLET&&n.push(t(i,e).map(function(e){return r[i]=e,e}))}),forEach(e,function(e,i){i!==s.PRIMARY_OUTLET&&n.push(t(i,e).map(function(e){return r[i]=e,e}))}),n.length>0?o.of.apply(void 0,n).concatAll().last().map(function(e){return r}):o.of(r)}function andObservables(e){return e.mergeAll().every(function(e){return e===!0})}function wrapIntoObservable(e){return e instanceof r.Observable?e:e instanceof Promise?i.fromPromise(e):o.of(e)}n(304),n(497);var r=n(1),i=n(211),o=n(141),s=n(63);t.shallowEqualArrays=shallowEqualArrays,t.shallowEqual=shallowEqual,t.flatten=flatten,t.first=first,t.last=last,t.and=and,t.merge=merge,t.forEach=forEach,t.waitForMap=waitForMap,t.andObservables=andObservables,t.wrapIntoObservable=wrapIntoObservable},function(e,t){e.exports=function(e){if(void 0==e)throw TypeError("Can't call method on "+e);return e}},function(e,t,n){var r=n(137)("meta"),i=n(15),o=n(48),s=n(30).f,a=0,l=Object.isExtensible||function(){return!0},c=!n(13)(function(){return l(Object.preventExtensions({}))}),u=function(e){s(e,r,{value:{i:"O"+ ++a,w:{}}})},p=function(e,t){if(!i(e))return"symbol"==typeof e?e:("string"==typeof e?"S":"P")+e;if(!o(e,r)){if(!l(e))return"F";if(!t)return"E";u(e)}return e[r].i},d=function(e,t){if(!o(e,r)){if(!l(e))return!0;if(!t)return!1;u(e)}return e[r].w},h=function(e){return c&&f.NEED&&l(e)&&!o(e,r)&&u(e),e},f=e.exports={KEY:r,NEED:!1,fastKey:p,getWeak:d,onFreeze:h}},function(e,t,n){var r=n(197),i=n(109),o=n(57),s=n(97),a=n(48),l=n(453),c=Object.getOwnPropertyDescriptor;t.f=n(35)?c:function(e,t){if(e=o(e),t=s(t,!0),l)try{return c(e,t)}catch(n){}if(a(e,t))return i(!r.f.call(e,t),e[t])}},function(e,t){e.exports=".vt-row {\n display: flex;\n flex-wrap: wrap;\n height: 100%;\n width: 100%;\n}\n\n.vt-card {\n display: inline-table;\n margin-left: 25px;\n margin-bottom: 10px;\n margin-top: 10px;\n}\n\n.stats-container {\n width: 100%;\n}\n\n.vt-padding{\n padding-left: 25px;\n padding-right: 25px;\n}\n\n>>> p-dialog .ui-dialog{\n position: fixed !important;\n top: 50% !important;\n left: 50% !important;\n transform: translate(-50%, -50%);\n margin: 0;\n width: auto !important;\n}\n\n.vt-popUpContainer{\n position: fixed;\n padding: 0;\n margin: 0;\n z-index: 0;\n bottom: 0;\n right: 0;\n top: 0;\n left: 0;\n min-height: 1000vh;\n min-width: 1000vw;\n height: 100%;\n width: 100%;\n background: rgba(0,0,0,0.6);\n}\n\n.vt-dark-link:link {\n text-decoration: none;\n color: black;\n}\n\n.vt-dark-link:visited {\n text-decoration: none;\n color: black;\n}\n\n.vt-dark-link:hover {\n text-decoration: none;\n color: black;\n}\n\n.vt-dark-link:active {\n text-decoration: none;\n color: black;\n}\n\n/* Toolbar */\n.vt-toolbar {\n width: 100%;\n text-align: center;\n}\n\n>>> p-accordiontab a {\n padding-left: 25px! important;\n}\n\n>>> .ui-accordion-content button {\n margin-top: 2px;\n}\n\n>>> p-menu .ui-menu {\n margin-top: 19px;\n display: inline-block;\n top: auto !important;\n left: auto !important;\n float: right;\n \n}\n\np-menu {\n display: inline-block;\n float: left;\n}\n\n.vt-toolbar .vt-menu {\n padding-top: 19px;\n float: left;\n}\n\n.vt-toolbar .vt-right-menu {\n padding-top: 19px;\n position: fixed;\n right: 25px;\n top: 19px;\n}\n\n.vt-card-toolbar {\n display: inline-block;\n width: 100%;\n}\n\n.vt-card-toolbar .vt-menu {\n float: left;\n}\n.vt-card-toolbar .vt-title {\n float: right;\n margin: 0;\n padding-left: 25px;\n}\n\nmd-list:hover {\n background: #E8E8E8\n}\n"},function(e,t,n){"use strict";var r=this&&this.__extends||function(e,t){function __(){this.constructor=e}for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n]);e.prototype=null===t?Object.create(t):(__.prototype=t.prototype,new __)},i=n(1),o=n(308),s=n(80),a=n(98),l=function(e){function ArrayObservable(t,n){e.call(this),this.array=t,this.scheduler=n,n||1!==t.length||(this._isScalar=!0,this.value=t[0])}return r(ArrayObservable,e),ArrayObservable.create=function(e,t){return new ArrayObservable(e,t)},ArrayObservable.of=function(){for(var e=[],t=0;t1?new ArrayObservable(e,n):1===r?new o.ScalarObservable(e[0],n):new s.EmptyObservable(n)},ArrayObservable.dispatch=function(e){var t=e.array,n=e.index,r=e.count,i=e.subscriber;return n>=r?void i.complete():(i.next(t[n]),void(i.isUnsubscribed||(e.index=n+1,this.schedule(e))))},ArrayObservable.prototype._subscribe=function(e){var t=0,n=this.array,r=n.length,i=this.scheduler;if(i)return i.schedule(ArrayObservable.dispatch,0,{array:n,index:t,count:r,subscriber:e});for(var o=0;o0?" { "+e.children.map(serializeNode).join(", ")+" } ":"";return""+e.value+t}function advanceActivatedRoute(e){e.snapshot?(a.shallowEqual(e.snapshot.queryParams,e._futureSnapshot.queryParams)||e.queryParams.next(e._futureSnapshot.queryParams),e.snapshot.fragment!==e._futureSnapshot.fragment&&e.fragment.next(e._futureSnapshot.fragment),a.shallowEqual(e.snapshot.params,e._futureSnapshot.params)||(e.params.next(e._futureSnapshot.params),e.data.next(e._futureSnapshot.data)),a.shallowEqualArrays(e.snapshot.url,e._futureSnapshot.url)||e.url.next(e._futureSnapshot.url),e.snapshot=e._futureSnapshot):(e.snapshot=e._futureSnapshot,e.data.next(e._futureSnapshot.data))}var r=this&&this.__extends||function(e,t){function __(){this.constructor=e}for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n]);e.prototype=null===t?Object.create(t):(__.prototype=t.prototype,new __)},i=n(207),o=n(63),s=n(73),a=n(74),l=n(281),c=function(e){function RouterState(t,n){e.call(this,t),this.snapshot=n,setRouterStateSnapshot(this,t)}return r(RouterState,e),Object.defineProperty(RouterState.prototype,"queryParams",{get:function(){return this.root.queryParams},enumerable:!0,configurable:!0}),Object.defineProperty(RouterState.prototype,"fragment",{get:function(){return this.root.fragment},enumerable:!0,configurable:!0}),RouterState.prototype.toString=function(){return this.snapshot.toString()},RouterState}(l.Tree);t.RouterState=c,t.createEmptyState=createEmptyState;var u=function(){function ActivatedRoute(e,t,n,r,i,o,s,a){this.url=e,this.params=t,this.queryParams=n,this.fragment=r,this.data=i,this.outlet=o,this.component=s,this._futureSnapshot=a}return Object.defineProperty(ActivatedRoute.prototype,"routeConfig",{get:function(){return this._futureSnapshot.routeConfig},enumerable:!0,configurable:!0}),Object.defineProperty(ActivatedRoute.prototype,"root",{get:function(){return this._routerState.root},enumerable:!0,configurable:!0}),Object.defineProperty(ActivatedRoute.prototype,"parent",{get:function(){return this._routerState.parent(this)},enumerable:!0,configurable:!0}),Object.defineProperty(ActivatedRoute.prototype,"firstChild",{get:function(){return this._routerState.firstChild(this)},enumerable:!0,configurable:!0}),Object.defineProperty(ActivatedRoute.prototype,"children",{get:function(){return this._routerState.children(this)},enumerable:!0,configurable:!0}),Object.defineProperty(ActivatedRoute.prototype,"pathFromRoot",{get:function(){return this._routerState.pathFromRoot(this)},enumerable:!0,configurable:!0}),ActivatedRoute.prototype.toString=function(){return this.snapshot?this.snapshot.toString():"Future("+this._futureSnapshot+")"},ActivatedRoute}();t.ActivatedRoute=u;var p=function(){function InheritedResolve(e,t){this.parent=e,this.current=t,this.resolvedData={}}return Object.defineProperty(InheritedResolve.prototype,"flattenedResolvedData",{get:function(){return this.parent?a.merge(this.parent.flattenedResolvedData,this.resolvedData):this.resolvedData},enumerable:!0,configurable:!0}),Object.defineProperty(InheritedResolve,"empty",{get:function(){return new InheritedResolve(null,{})},enumerable:!0,configurable:!0}),InheritedResolve}();t.InheritedResolve=p;var d=function(){function ActivatedRouteSnapshot(e,t,n,r,i,o,s,a,l,c,u){this.url=e,this.params=t,this.queryParams=n,this.fragment=r,this.data=i,this.outlet=o,this.component=s,this._routeConfig=a,this._urlSegment=l,this._lastPathIndex=c,this._resolve=u}return Object.defineProperty(ActivatedRouteSnapshot.prototype,"routeConfig",{get:function(){return this._routeConfig},enumerable:!0,configurable:!0}),Object.defineProperty(ActivatedRouteSnapshot.prototype,"root",{get:function(){return this._routerState.root},enumerable:!0,configurable:!0}),Object.defineProperty(ActivatedRouteSnapshot.prototype,"parent",{get:function(){return this._routerState.parent(this)},enumerable:!0,configurable:!0}),Object.defineProperty(ActivatedRouteSnapshot.prototype,"firstChild",{get:function(){return this._routerState.firstChild(this)},enumerable:!0,configurable:!0}),Object.defineProperty(ActivatedRouteSnapshot.prototype,"children",{get:function(){return this._routerState.children(this)},enumerable:!0,configurable:!0}),Object.defineProperty(ActivatedRouteSnapshot.prototype,"pathFromRoot",{get:function(){return this._routerState.pathFromRoot(this)},enumerable:!0,configurable:!0}),ActivatedRouteSnapshot.prototype.toString=function(){var e=this.url.map(function(e){return e.toString()}).join("/"),t=this._routeConfig?this._routeConfig.path:"";return"Route(url:'"+e+"', path:'"+t+"')"},ActivatedRouteSnapshot}();t.ActivatedRouteSnapshot=d;var h=function(e){function RouterStateSnapshot(t,n){e.call(this,n),this.url=t,setRouterStateSnapshot(this,n)}return r(RouterStateSnapshot,e),Object.defineProperty(RouterStateSnapshot.prototype,"queryParams",{get:function(){return this.root.queryParams},enumerable:!0,configurable:!0}),Object.defineProperty(RouterStateSnapshot.prototype,"fragment",{get:function(){return this.root.fragment},enumerable:!0,configurable:!0}),RouterStateSnapshot.prototype.toString=function(){return serializeNode(this._root)},RouterStateSnapshot}(l.Tree);t.RouterStateSnapshot=h,t.advanceActivatedRoute=advanceActivatedRoute},function(e,t,n){"use strict";var r=n(43),i=(n.n(r),n(0));n.n(i);n.d(t,"a",function(){return a});var o=this&&this.__decorate||function(e,t,n,r){var i,o=arguments.length,s=o<3?t:null===r?r=Object.getOwnPropertyDescriptor(t,n):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(e,t,n,r);else for(var a=e.length-1;a>=0;a--)(i=e[a])&&(s=(o<3?i(s):o>3?i(t,n,s):i(t,n))||s);return o>3&&s&&Object.defineProperty(t,n,s),s},s=this&&this.__metadata||function(e,t){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(e,t)},a=function(){function VtctlService(e){this.http=e,this.vtctlUrl="../api/vtctl/"}return VtctlService.prototype.sendPostRequest=function(e,t){var n=new r.Headers({"Content-Type":"application/json"}),i=new r.RequestOptions({headers:n});return this.http.post(e,JSON.stringify(t),i).map(function(e){return e.json()})},VtctlService.prototype.runCommand=function(e){return this.sendPostRequest(this.vtctlUrl,e)},VtctlService=o([n.i(i.Injectable)(),s("design:paramtypes",["function"==typeof(e="undefined"!=typeof r.Http&&r.Http)&&e||Object])],VtctlService);var e}()},function(e,t,n){"use strict";var r=n(192);n.d(t,"a",function(){return i});var i=function(){function DialogContent(e,t,n,r,i){void 0===e&&(e=""),void 0===t&&(t={}),void 0===n&&(n={}),void 0===r&&(r=void 0),void 0===i&&(i=""),this.nameId=e,this.flags=t,this.requiredFlags=n,this.prepareFunction=r,this.action=i}return DialogContent.prototype.getName=function(){return this.flags[this.nameId]?this.flags[this.nameId].getStrValue():""},DialogContent.prototype.setName=function(e){this.flags[this.nameId]&&this.flags[this.nameId].setValue(e)},DialogContent.prototype.getPostBody=function(e){void 0===e&&(e=void 0),e||(e=this.getFlags());var t=[],n=[];t.push(this.action);for(var r=0,i=e;r1?"path: '"+e.path.join(" -> ")+"'":e.path[0]?"name: '"+e.path+"'":"unspecified name",new i.BaseException(t+" "+n)}function composeValidators(e){return o.isPresent(e)?s.Validators.compose(e.map(c.normalizeValidator)):null}function composeAsyncValidators(e){return o.isPresent(e)?s.Validators.composeAsync(e.map(c.normalizeAsyncValidator)):null}function isPropertyUpdated(e,t){if(!r.StringMapWrapper.contains(e,"model"))return!1;var n=e.model;return!!n.isFirstChange()||!o.looseIdentical(t,n.currentValue)}function selectValueAccessor(e,t){if(o.isBlank(t))return null;var n,r,i;return t.forEach(function(t){o.hasConstructor(t,l.DefaultValueAccessor)?n=t:o.hasConstructor(t,a.CheckboxControlValueAccessor)||o.hasConstructor(t,u.NumberValueAccessor)||o.hasConstructor(t,d.SelectControlValueAccessor)||o.hasConstructor(t,h.SelectMultipleControlValueAccessor)||o.hasConstructor(t,p.RadioControlValueAccessor)?(o.isPresent(r)&&_throwError(e,"More than one built-in value accessor matches form control with"),r=t):(o.isPresent(i)&&_throwError(e,"More than one custom value accessor matches form control with"),i=t)}),o.isPresent(i)?i:o.isPresent(r)?r:o.isPresent(n)?n:(_throwError(e,"No valid value accessor for form control with"),null)}var r=n(34),i=n(83),o=n(7),s=n(58),a=n(144),l=n(145),c=n(526),u=n(227),p=n(146),d=n(147),h=n(228);t.controlPath=controlPath,t.setUpControl=setUpControl,t.setUpControlGroup=setUpControlGroup,t.composeValidators=composeValidators,t.composeAsyncValidators=composeAsyncValidators,t.isPropertyUpdated=isPropertyUpdated,t.selectValueAccessor=selectValueAccessor},function(e,t,n){"use strict";var r=n(0),i=n(18),o=n(28),s=function(){function CompilerConfig(e){var t=void 0===e?{}:e,n=t.renderTypes,i=void 0===n?new l:n,o=t.defaultEncapsulation,s=void 0===o?r.ViewEncapsulation.Emulated:o,a=t.genDebugInfo,c=t.logBindingUpdate,u=t.useJit,p=void 0===u||u,d=t.deprecatedPlatformDirectives,h=void 0===d?[]:d,f=t.deprecatedPlatformPipes,m=void 0===f?[]:f;this.renderTypes=i,this.defaultEncapsulation=s,this._genDebugInfo=a,this._logBindingUpdate=c,this.useJit=p,this.platformDirectives=h,this.platformPipes=m}return Object.defineProperty(CompilerConfig.prototype,"genDebugInfo",{get:function(){return void 0===this._genDebugInfo?r.isDevMode():this._genDebugInfo},enumerable:!0,configurable:!0}),Object.defineProperty(CompilerConfig.prototype,"logBindingUpdate",{get:function(){return void 0===this._logBindingUpdate?r.isDevMode():this._logBindingUpdate},enumerable:!0,configurable:!0}),CompilerConfig}();t.CompilerConfig=s;var a=function(){function RenderTypes(){}return Object.defineProperty(RenderTypes.prototype,"renderer",{get:function(){return i.unimplemented()},enumerable:!0,configurable:!0}),Object.defineProperty(RenderTypes.prototype,"renderText",{get:function(){return i.unimplemented()},enumerable:!0,configurable:!0}),Object.defineProperty(RenderTypes.prototype,"renderElement",{get:function(){return i.unimplemented()},enumerable:!0,configurable:!0}),Object.defineProperty(RenderTypes.prototype,"renderComment",{get:function(){return i.unimplemented()},enumerable:!0,configurable:!0}),Object.defineProperty(RenderTypes.prototype,"renderNode",{get:function(){return i.unimplemented()},enumerable:!0,configurable:!0}),Object.defineProperty(RenderTypes.prototype,"renderEvent",{get:function(){return i.unimplemented()},enumerable:!0,configurable:!0}),RenderTypes}();t.RenderTypes=a;var l=function(){function DefaultRenderTypes(){this.renderer=o.Identifiers.Renderer,this.renderText=null,this.renderElement=null,this.renderComment=null,this.renderNode=null,this.renderEvent=null}return DefaultRenderTypes}();t.DefaultRenderTypes=l},function(e,t){"use strict";function splitNsName(e){if(":"!=e[0])return[null,e];var t=e.indexOf(":",1);if(t==-1)throw new Error('Unsupported format "'+e+'" expecting ":namespace:name"');return[e.slice(1,t),e.slice(t+1)]}function getNsPrefix(e){return null===e?null:splitNsName(e)[0]}function mergeNsAndName(e,t){return e?":"+e+":"+t:t}!function(e){e[e.RAW_TEXT=0]="RAW_TEXT",e[e.ESCAPABLE_RAW_TEXT=1]="ESCAPABLE_RAW_TEXT",e[e.PARSABLE_DATA=2]="PARSABLE_DATA"}(t.TagContentType||(t.TagContentType={}));t.TagContentType;t.splitNsName=splitNsName,t.getNsPrefix=getNsPrefix,t.mergeNsAndName=mergeNsAndName,t.NAMED_ENTITIES={Aacute:"Á",aacute:"á",Acirc:"Â",acirc:"â",acute:"´",AElig:"Æ",aelig:"æ",Agrave:"À",agrave:"à",alefsym:"ℵ",Alpha:"Α",alpha:"α",amp:"&",and:"∧",ang:"∠",apos:"'",Aring:"Å",aring:"å",asymp:"≈",Atilde:"Ã",atilde:"ã",Auml:"Ä",auml:"ä",bdquo:"„",Beta:"Β",beta:"β",brvbar:"¦",bull:"•",cap:"∩",Ccedil:"Ç",ccedil:"ç",cedil:"¸",cent:"¢",Chi:"Χ",chi:"χ",circ:"ˆ",clubs:"♣",cong:"≅",copy:"©",crarr:"↵",cup:"∪",curren:"¤",dagger:"†",Dagger:"‡",darr:"↓",dArr:"⇓",deg:"°",Delta:"Δ",delta:"δ",diams:"♦",divide:"÷",Eacute:"É",eacute:"é",Ecirc:"Ê",ecirc:"ê",Egrave:"È",egrave:"è",empty:"∅",emsp:" ",ensp:" ",Epsilon:"Ε",epsilon:"ε",equiv:"≡",Eta:"Η",eta:"η",ETH:"Ð",eth:"ð",Euml:"Ë",euml:"ë",euro:"€",exist:"∃",fnof:"ƒ",forall:"∀",frac12:"½",frac14:"¼",frac34:"¾",frasl:"⁄",Gamma:"Γ",gamma:"γ",ge:"≥",gt:">",harr:"↔",hArr:"⇔",hearts:"♥",hellip:"…",Iacute:"Í",iacute:"í",Icirc:"Î",icirc:"î",iexcl:"¡",Igrave:"Ì",igrave:"ì",image:"ℑ",infin:"∞","int":"∫",Iota:"Ι",iota:"ι",iquest:"¿",isin:"∈",Iuml:"Ï",iuml:"ï",Kappa:"Κ",kappa:"κ",Lambda:"Λ",lambda:"λ",lang:"⟨",laquo:"«",larr:"←",lArr:"⇐",lceil:"⌈",ldquo:"“",le:"≤",lfloor:"⌊",lowast:"∗",loz:"◊",lrm:"‎",lsaquo:"‹",lsquo:"‘",lt:"<",macr:"¯",mdash:"—",micro:"µ",middot:"·",minus:"−",Mu:"Μ",mu:"μ",nabla:"∇",nbsp:" ",ndash:"–",ne:"≠",ni:"∋",not:"¬",notin:"∉",nsub:"⊄",Ntilde:"Ñ",ntilde:"ñ",Nu:"Ν",nu:"ν",Oacute:"Ó",oacute:"ó",Ocirc:"Ô",ocirc:"ô",OElig:"Œ",oelig:"œ",Ograve:"Ò",ograve:"ò",oline:"‾",Omega:"Ω",omega:"ω",Omicron:"Ο",omicron:"ο",oplus:"⊕",or:"∨",ordf:"ª",ordm:"º",Oslash:"Ø",oslash:"ø",Otilde:"Õ",otilde:"õ",otimes:"⊗",Ouml:"Ö",ouml:"ö",para:"¶",permil:"‰",perp:"⊥",Phi:"Φ",phi:"φ",Pi:"Π",pi:"π",piv:"ϖ",plusmn:"±",pound:"£",prime:"′",Prime:"″",prod:"∏",prop:"∝",Psi:"Ψ",psi:"ψ",quot:'"',radic:"√",rang:"⟩",raquo:"»",rarr:"→",rArr:"⇒",rceil:"⌉",rdquo:"”",real:"ℜ",reg:"®",rfloor:"⌋",Rho:"Ρ",rho:"ρ",rlm:"‏",rsaquo:"›",rsquo:"’",sbquo:"‚",Scaron:"Š",scaron:"š",sdot:"⋅",sect:"§",shy:"­",Sigma:"Σ",sigma:"σ",sigmaf:"ς",sim:"∼",spades:"♠",sub:"⊂",sube:"⊆",sum:"∑",sup:"⊃",sup1:"¹",sup2:"²",sup3:"³",supe:"⊇",szlig:"ß",Tau:"Τ",tau:"τ",there4:"∴",Theta:"Θ",theta:"θ",thetasym:"ϑ",thinsp:" ",THORN:"Þ",thorn:"þ",tilde:"˜",times:"×",trade:"™",Uacute:"Ú",uacute:"ú",uarr:"↑",uArr:"⇑",Ucirc:"Û",ucirc:"û",Ugrave:"Ù",ugrave:"ù",uml:"¨",upsih:"ϒ",Upsilon:"Υ",upsilon:"υ",Uuml:"Ü",uuml:"ü",weierp:"℘",Xi:"Ξ",xi:"ξ",Yacute:"Ý",yacute:"ý",yen:"¥",yuml:"ÿ",Yuml:"Ÿ",Zeta:"Ζ",zeta:"ζ",zwj:"‍",zwnj:"‌"}},function(e,t,n){"use strict";function createUrlResolverWithoutPackagePrefix(){return new s}function createOfflineCompileUrlResolver(){return new s(o)}function getUrlScheme(e){var t=_split(e);return t&&t[a.Scheme]||""}function _buildFromEncodedParts(e,t,n,r,o,s,a){var l=[];return i.isPresent(e)&&l.push(e+":"),i.isPresent(n)&&(l.push("//"),i.isPresent(t)&&l.push(t+"@"),l.push(n),i.isPresent(r)&&l.push(":"+r)),i.isPresent(o)&&l.push(o),i.isPresent(s)&&l.push("?"+s),i.isPresent(a)&&l.push("#"+a),l.join("")}function _split(e){return e.match(l)}function _removeDotSegments(e){if("/"==e)return"/";for(var t="/"==e[0]?"/":"",n="/"===e[e.length-1]?"/":"",r=e.split("/"),i=[],o=0,s=0;s0?i.pop():o++;break;default:i.push(a)}}if(""==t){for(;o-- >0;)i.unshift("..");0===i.length&&i.push(".")}return t+i.join("/")+n}function _joinAndCanonicalizePath(e){var t=e[a.Path];return t=i.isBlank(t)?"":_removeDotSegments(t),e[a.Path]=t,_buildFromEncodedParts(e[a.Scheme],e[a.UserInfo],e[a.Domain],e[a.Port],t,e[a.QueryData],e[a.Fragment])}function _resolveUrl(e,t){var n=_split(encodeURI(t)),r=_split(e);if(i.isPresent(n[a.Scheme]))return _joinAndCanonicalizePath(n);n[a.Scheme]=r[a.Scheme];for(var o=a.Scheme;o<=a.Port;o++)i.isBlank(n[o])&&(n[o]=r[o]);if("/"==n[a.Path][0])return _joinAndCanonicalizePath(n);var s=r[a.Path];i.isBlank(s)&&(s="/");var l=s.lastIndexOf("/");return s=s.substring(0,l+1)+n[a.Path],n[a.Path]=s,_joinAndCanonicalizePath(n)}var r=n(0),i=n(5),o="asset:";t.createUrlResolverWithoutPackagePrefix=createUrlResolverWithoutPackagePrefix,t.createOfflineCompileUrlResolver=createOfflineCompileUrlResolver,t.DEFAULT_PACKAGE_URL_PROVIDER={provide:r.PACKAGE_ROOT_URL,useValue:"/"};var s=function(){function UrlResolver(e){void 0===e&&(e=null),this._packagePrefix=e}return UrlResolver.prototype.resolve=function(e,t){var n=t;i.isPresent(e)&&e.length>0&&(n=_resolveUrl(e,n));var r=_split(n),s=this._packagePrefix;if(i.isPresent(s)&&i.isPresent(r)&&"package"==r[a.Scheme]){var l=r[a.Path];if(this._packagePrefix!==o)return s=i.StringWrapper.stripRight(s,"/"),l=i.StringWrapper.stripLeft(l,"/"),s+"/"+l;var c=l.split(/\//);n="asset:"+c[0]+"/lib/"+c.slice(1).join("/")}return n},UrlResolver.decorators=[{type:r.Injectable}],UrlResolver.ctorParameters=[{type:void 0,decorators:[{type:r.Inject,args:[r.PACKAGE_ROOT_URL]}]}],UrlResolver}();t.UrlResolver=s,t.getUrlScheme=getUrlScheme;var a,l=new RegExp("^(?:([^:/?#.]+):)?(?://(?:([^/?#]*)@)?([\\w\\d\\-\\u0100-\\uffff.%]*)(?::([0-9]+))?)?([^?#]+)?(?:\\?([^#]*))?(?:#(.*))?$");!function(e){e[e.Scheme=1]="Scheme",e[e.UserInfo=2]="UserInfo",e[e.Domain=3]="Domain",e[e.Port=4]="Port",e[e.Path=5]="Path",e[e.QueryData=6]="QueryData",e[e.Fragment=7]="Fragment"}(a||(a={}))},function(e,t,n){"use strict";function _enumExpression(e,t){if(s.isBlank(t))return l.NULL_EXPR;var n=s.resolveEnumToken(e.runtime,t);return l.importExpr(new o.CompileIdentifierMetadata({name:e.name+"."+n,moduleUrl:e.moduleUrl,runtime:t}))}var r=n(0),i=n(27),o=n(31),s=n(5),a=n(28),l=n(17),c=function(){function ViewTypeEnum(){}return ViewTypeEnum.fromValue=function(e){return _enumExpression(a.Identifiers.ViewType,e)},ViewTypeEnum.HOST=ViewTypeEnum.fromValue(i.ViewType.HOST),ViewTypeEnum.COMPONENT=ViewTypeEnum.fromValue(i.ViewType.COMPONENT),ViewTypeEnum.EMBEDDED=ViewTypeEnum.fromValue(i.ViewType.EMBEDDED),ViewTypeEnum}();t.ViewTypeEnum=c;var u=function(){function ViewEncapsulationEnum(){}return ViewEncapsulationEnum.fromValue=function(e){return _enumExpression(a.Identifiers.ViewEncapsulation,e)},ViewEncapsulationEnum.Emulated=ViewEncapsulationEnum.fromValue(r.ViewEncapsulation.Emulated),ViewEncapsulationEnum.Native=ViewEncapsulationEnum.fromValue(r.ViewEncapsulation.Native),ViewEncapsulationEnum.None=ViewEncapsulationEnum.fromValue(r.ViewEncapsulation.None),ViewEncapsulationEnum}();t.ViewEncapsulationEnum=u;var p=function(){function ChangeDetectionStrategyEnum(){}return ChangeDetectionStrategyEnum.fromValue=function(e){return _enumExpression(a.Identifiers.ChangeDetectionStrategy,e)},ChangeDetectionStrategyEnum.OnPush=ChangeDetectionStrategyEnum.fromValue(r.ChangeDetectionStrategy.OnPush),ChangeDetectionStrategyEnum.Default=ChangeDetectionStrategyEnum.fromValue(r.ChangeDetectionStrategy.Default),ChangeDetectionStrategyEnum}();t.ChangeDetectionStrategyEnum=p;var d=function(){function ChangeDetectorStatusEnum(){}return ChangeDetectorStatusEnum.fromValue=function(e){return _enumExpression(a.Identifiers.ChangeDetectorStatus,e)},ChangeDetectorStatusEnum.CheckOnce=ChangeDetectorStatusEnum.fromValue(i.ChangeDetectorStatus.CheckOnce),ChangeDetectorStatusEnum.Checked=ChangeDetectorStatusEnum.fromValue(i.ChangeDetectorStatus.Checked),ChangeDetectorStatusEnum.CheckAlways=ChangeDetectorStatusEnum.fromValue(i.ChangeDetectorStatus.CheckAlways),ChangeDetectorStatusEnum.Detached=ChangeDetectorStatusEnum.fromValue(i.ChangeDetectorStatus.Detached),ChangeDetectorStatusEnum.Errored=ChangeDetectorStatusEnum.fromValue(i.ChangeDetectorStatus.Errored),ChangeDetectorStatusEnum.Destroyed=ChangeDetectorStatusEnum.fromValue(i.ChangeDetectorStatus.Destroyed),ChangeDetectorStatusEnum}();t.ChangeDetectorStatusEnum=d;var h=function(){function ViewConstructorVars(){}return ViewConstructorVars.viewUtils=l.variable("viewUtils"),ViewConstructorVars.parentInjector=l.variable("parentInjector"),ViewConstructorVars.declarationEl=l.variable("declarationEl"),ViewConstructorVars}();t.ViewConstructorVars=h;var f=function(){function ViewProperties(){}return ViewProperties.renderer=l.THIS_EXPR.prop("renderer"),ViewProperties.projectableNodes=l.THIS_EXPR.prop("projectableNodes"),ViewProperties.viewUtils=l.THIS_EXPR.prop("viewUtils"),ViewProperties}();t.ViewProperties=f;var m=function(){function EventHandlerVars(){}return EventHandlerVars.event=l.variable("$event"),EventHandlerVars}();t.EventHandlerVars=m;var y=function(){function InjectMethodVars(){}return InjectMethodVars.token=l.variable("token"),InjectMethodVars.requestNodeIndex=l.variable("requestNodeIndex"),InjectMethodVars.notFoundResult=l.variable("notFoundResult"),InjectMethodVars}();t.InjectMethodVars=y;var g=function(){function DetectChangesVars(){}return DetectChangesVars.throwOnChange=l.variable("throwOnChange"),DetectChangesVars.changes=l.variable("changes"),DetectChangesVars.changed=l.variable("changed"),DetectChangesVars.valUnwrapper=l.variable("valUnwrapper"),DetectChangesVars}();t.DetectChangesVars=g},99,function(e,t,n){var r=n(95);e.exports=function(e,t,n){if(r(e),void 0===t)return e;switch(n){case 1:return function(n){return e.call(t,n)};case 2:return function(n,r){return e.call(t,n,r)};case 3:return function(n,r,i){return e.call(t,n,r,i)}}return function(){return e.apply(t,arguments)}}},function(e,t,n){var r=n(8),i=n(462),o=n(288),s=n(300)("IE_PROTO"),a=function(){},l="prototype",c=function(){var e,t=n(451)("iframe"),r=o.length,i="<",s=">";for(t.style.display="none",n(452).appendChild(t),t.src="javascript:",e=t.contentWindow.document,e.open(),e.write(i+"script"+s+"document.F=Object"+i+"/script"+s),e.close(),c=e.F;r--;)delete c[l][o[r]];return c()};e.exports=Object.create||function(e,t){var n;return null!==e?(a[l]=r(e),n=new a,a[l]=null,n[s]=e):n=c(),void 0===t?n:i(n,t)}},function(e,t,n){var r=n(464),i=n(288);e.exports=Object.keys||function(e){return r(e,i)}},function(e,t){e.exports=function(e,t){return{enumerable:!(1&e),configurable:!(2&e),writable:!(4&e),value:t}}},function(e,t){var n=Math.ceil,r=Math.floor;e.exports=function(e){return isNaN(e=+e)?0:(e>0?r:n)(e)}},function(e,t,n){"use strict";function multicast(e){var t;return t="function"==typeof e?e:function(){return e},new r.ConnectableObservable(this,t)}var r=n(502);t.multicast=multicast},[1107,219],function(e,t){"use strict";var n=function(){function ElementSchemaRegistry(){}return ElementSchemaRegistry}();t.ElementSchemaRegistry=n},function(e,t,n){"use strict";function getPropertyInView(e,t,n){if(t===n)return e;for(var o=s.THIS_EXPR,a=t;a!==n&&i.isPresent(a.declarationElement.view);)a=a.declarationElement.view,o=o.prop("parent");if(a!==n)throw new r.BaseException("Internal error: Could not calculate a property in a parent view: "+e);if(e instanceof s.ReadPropExpr){var l=e;(n.fields.some(function(e){return e.name==l.name})||n.getters.some(function(e){return e.name==l.name}))&&(o=o.cast(n.classType))}return s.replaceVarInExpression(s.THIS_EXPR.name,o,e)}function injectFromViewParentInjector(e,t){var n=[a.createDiTokenExpression(e)];return t&&n.push(s.NULL_EXPR),s.THIS_EXPR.prop("parentInjector").callMethod("get",n)}function getViewFactoryName(e,t){return"viewFactory_"+e.type.name+t}function createFlatArray(e){for(var t=[],n=s.literalArr([]),r=0;r0&&(n=n.callMethod(s.BuiltinMethod.ConcatArray,[s.literalArr(t)]),t=[]),n=n.callMethod(s.BuiltinMethod.ConcatArray,[i])):t.push(i)}return t.length>0&&(n=n.callMethod(s.BuiltinMethod.ConcatArray,[s.literalArr(t)])),n}function createPureProxy(e,t,n,a){a.fields.push(new s.ClassField(n.name,null));var l=t0){var r=e.substring(0,n),i=e.substring(n+1).trim();t.set(r,i)}}),t},Headers.prototype.append=function(e,t){e=normalize(e);var n=this._headersMap.get(e),i=r.isListLikeIterable(n)?n:[];i.push(t),this._headersMap.set(e,i)},Headers.prototype.delete=function(e){this._headersMap.delete(normalize(e))},Headers.prototype.forEach=function(e){this._headersMap.forEach(e)},Headers.prototype.get=function(e){return r.ListWrapper.first(this._headersMap.get(normalize(e)))},Headers.prototype.has=function(e){return this._headersMap.has(normalize(e))},Headers.prototype.keys=function(){return r.MapWrapper.keys(this._headersMap)},Headers.prototype.set=function(e,t){var n=[];if(r.isListLikeIterable(t)){var i=t.join(",");n.push(i)}else n.push(t);this._headersMap.set(normalize(e),n)},Headers.prototype.values=function(){return r.MapWrapper.values(this._headersMap)},Headers.prototype.toJSON=function(){var e={};return this._headersMap.forEach(function(t,n){var i=[];r.iterateListLike(t,function(e){return i=r.ListWrapper.concat(i,e.split(","))}),e[normalize(n)]=i}),e},Headers.prototype.getAll=function(e){var t=this._headersMap.get(normalize(e));return r.isListLikeIterable(t)?t:[]},Headers.prototype.entries=function(){throw new i.BaseException('"entries" method is not implemented on Headers class')},Headers}();t.Headers=s},function(e,t){"use strict";var n=function(){function ConnectionBackend(){}return ConnectionBackend}();t.ConnectionBackend=n;var r=function(){function Connection(){}return Connection}();t.Connection=r;var i=function(){function XSRFStrategy(){}return XSRFStrategy}();t.XSRFStrategy=i},function(e,t,n){"use strict";var r=n(0);t.RenderDebugInfo=r.__core_private__.RenderDebugInfo,t.wtfInit=r.__core_private__.wtfInit,t.ReflectionCapabilities=r.__core_private__.ReflectionCapabilities,t.VIEW_ENCAPSULATION_VALUES=r.__core_private__.VIEW_ENCAPSULATION_VALUES,t.DebugDomRootRenderer=r.__core_private__.DebugDomRootRenderer,t.reflector=r.__core_private__.reflector,t.NoOpAnimationPlayer=r.__core_private__.NoOpAnimationPlayer,t.AnimationPlayer=r.__core_private__.AnimationPlayer,t.AnimationSequencePlayer=r.__core_private__.AnimationSequencePlayer,t.AnimationGroupPlayer=r.__core_private__.AnimationGroupPlayer,t.AnimationKeyframe=r.__core_private__.AnimationKeyframe,t.AnimationStyles=r.__core_private__.AnimationStyles,t.prepareFinalAnimationStyles=r.__core_private__.prepareFinalAnimationStyles,t.balanceAnimationKeyframes=r.__core_private__.balanceAnimationKeyframes,t.flattenStyles=r.__core_private__.flattenStyles,t.clearStyles=r.__core_private__.clearStyles,t.collectAndResolveStyles=r.__core_private__.collectAndResolveStyles},function(e,t,n){"use strict";var r=n(0);t.DOCUMENT=new r.OpaqueToken("DocumentToken")},function(e,t,n){"use strict";var r=this&&this.__extends||function(e,t){function __(){this.constructor=e}for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n]);e.prototype=null===t?Object.create(t):(__.prototype=t.prototype,new __)},i=n(0),o=n(33),s=n(16),a=n(62),l=n(55),c=function(){function ClientMessageBrokerFactory(){}return ClientMessageBrokerFactory}();t.ClientMessageBrokerFactory=c;var u=function(e){function ClientMessageBrokerFactory_(t,n){e.call(this),this._messageBus=t,this._serializer=n}return r(ClientMessageBrokerFactory_,e),ClientMessageBrokerFactory_.prototype.createMessageBroker=function(e,t){return void 0===t&&(t=!0),this._messageBus.initChannel(e,t),new d(this._messageBus,this._serializer,e)},ClientMessageBrokerFactory_.decorators=[{type:i.Injectable}],ClientMessageBrokerFactory_.ctorParameters=[{type:a.MessageBus},{type:l.Serializer}],ClientMessageBrokerFactory_}(c);t.ClientMessageBrokerFactory_=u;var p=function(){function ClientMessageBroker(){}return ClientMessageBroker}();t.ClientMessageBroker=p;var d=function(e){function ClientMessageBroker_(t,n,r){var i=this;e.call(this),this.channel=r,this._pending=new Map,this._sink=t.to(r),this._serializer=n;var o=t.from(r);o.subscribe({next:function(e){return i._handleMessage(e)}})}return r(ClientMessageBroker_,e),ClientMessageBroker_.prototype._generateMessageId=function(e){for(var t=s.stringify(s.DateWrapper.toMillis(s.DateWrapper.now())),n=0,r=e+t+s.stringify(n);s.isPresent(this._pending[r]);)r=""+e+t+n,n++;return r},ClientMessageBroker_.prototype.runOnService=function(e,t){var n=this,r=[];s.isPresent(e.args)&&e.args.forEach(function(e){null!=e.type?r.push(n._serializer.serialize(e.value,e.type)):r.push(e.value)});var i,o=null;if(null!=t){var a;i=new Promise(function(e,t){a={resolve:e,reject:t}}),o=this._generateMessageId(e.method),this._pending.set(o,a),i.catch(function(e){s.print(e),a.reject(e)}),i=i.then(function(e){return null==n._serializer?e:n._serializer.deserialize(e,t)})}else i=null;var l={method:e.method,args:r};return null!=o&&(l.id=o),this._sink.emit(l),i},ClientMessageBroker_.prototype._handleMessage=function(e){var t=new h(e);if(s.StringWrapper.equals(t.type,"result")||s.StringWrapper.equals(t.type,"error")){var n=t.id;this._pending.has(n)&&(s.StringWrapper.equals(t.type,"result")?this._pending.get(n).resolve(t.value):this._pending.get(n).reject(t.value),this._pending.delete(n))}},ClientMessageBroker_}(p);t.ClientMessageBroker_=d;var h=function(){function MessageData(e){this.type=o.StringMapWrapper.get(e,"type"),this.id=this._getValueIfPresent(e,"id"),this.value=this._getValueIfPresent(e,"value")}return MessageData.prototype._getValueIfPresent=function(e,t){return o.StringMapWrapper.contains(e,t)?o.StringMapWrapper.get(e,t):null},MessageData}(),f=function(){function FnArg(e,t){this.value=e,this.type=t}return FnArg}();t.FnArg=f;var m=function(){function UiArguments(e,t){this.method=e,this.args=t}return UiArguments}();t.UiArguments=m},function(e,t,n){"use strict";var r=n(0),i=function(){function RenderStore(){this._nextIndex=0,this._lookupById=new Map,this._lookupByObject=new Map}return RenderStore.prototype.allocateId=function(){return this._nextIndex++},RenderStore.prototype.store=function(e,t){this._lookupById.set(t,e),this._lookupByObject.set(e,t)},RenderStore.prototype.remove=function(e){var t=this._lookupByObject.get(e);this._lookupByObject.delete(e),this._lookupById.delete(t)},RenderStore.prototype.deserialize=function(e){return null==e?null:this._lookupById.has(e)?this._lookupById.get(e):null},RenderStore.prototype.serialize=function(e){return null==e?null:this._lookupByObject.get(e)},RenderStore.decorators=[{type:r.Injectable}],RenderStore.ctorParameters=[],RenderStore}();t.RenderStore=i},function(e,t,n){"use strict";var r=this&&this.__extends||function(e,t){function __(){this.constructor=e}for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n]);e.prototype=null===t?Object.create(t):(__.prototype=t.prototype,new __)},i=n(0),o=n(33),s=n(16),a=n(62),l=n(55),c=function(){function ServiceMessageBrokerFactory(){}return ServiceMessageBrokerFactory}();t.ServiceMessageBrokerFactory=c;var u=function(e){function ServiceMessageBrokerFactory_(t,n){e.call(this),this._messageBus=t,this._serializer=n}return r(ServiceMessageBrokerFactory_,e),ServiceMessageBrokerFactory_.prototype.createMessageBroker=function(e,t){return void 0===t&&(t=!0),this._messageBus.initChannel(e,t),new d(this._messageBus,this._serializer,e)},ServiceMessageBrokerFactory_.decorators=[{type:i.Injectable}],ServiceMessageBrokerFactory_.ctorParameters=[{type:a.MessageBus},{type:l.Serializer}],ServiceMessageBrokerFactory_}(c);t.ServiceMessageBrokerFactory_=u;var p=function(){function ServiceMessageBroker(){}return ServiceMessageBroker}();t.ServiceMessageBroker=p;var d=function(e){function ServiceMessageBroker_(t,n,r){var i=this;e.call(this),this._serializer=n,this.channel=r,this._methods=new o.Map,this._sink=t.to(r);var s=t.from(r);s.subscribe({next:function(e){return i._handleMessage(e)}})}return r(ServiceMessageBroker_,e),ServiceMessageBroker_.prototype.registerMethod=function(e,t,n,r){var i=this;this._methods.set(e,function(e){for(var a=e.args,l=null===t?0:t.length,c=o.ListWrapper.createFixedSize(l),u=0;u0?n[n.length-1]._routeConfig._loadedConfig:null}function nodeChildrenAsMap(e){return e?e.children.reduce(function(e,t){return e[t.value.outlet]=t,e},{}):{}}function getOutlet(e,t){var n=e._outlets[t.outlet];if(!n){var r=t.component.name;throw t.outlet===y.PRIMARY_OUTLET?new Error("Cannot find primary outlet to load '"+r+"'"):new Error("Cannot find the outlet "+t.outlet+" to load '"+r+"'")}return n}n(140),n(499),n(305),n(500),n(493);var r=n(0),i=n(20),o=n(309),s=n(141),a=n(623),l=n(624),c=n(625),u=n(626),p=n(627),d=n(628),h=n(187),f=n(129),m=n(91),y=n(63),g=n(73),v=n(74),b=function(){function NavigationStart(e,t){this.id=e,this.url=t}return NavigationStart.prototype.toString=function(){return"NavigationStart(id: "+this.id+", url: '"+this.url+"')"},NavigationStart}();t.NavigationStart=b;var _=function(){function NavigationEnd(e,t,n){this.id=e,this.url=t,this.urlAfterRedirects=n}return NavigationEnd.prototype.toString=function(){return"NavigationEnd(id: "+this.id+", url: '"+this.url+"', urlAfterRedirects: '"+this.urlAfterRedirects+"')"},NavigationEnd}();t.NavigationEnd=_;var w=function(){function NavigationCancel(e,t){this.id=e,this.url=t}return NavigationCancel.prototype.toString=function(){return"NavigationCancel(id: "+this.id+", url: '"+this.url+"')"},NavigationCancel}();t.NavigationCancel=w;var S=function(){function NavigationError(e,t,n){this.id=e,this.url=t,this.error=n}return NavigationError.prototype.toString=function(){return"NavigationError(id: "+this.id+", url: '"+this.url+"', error: "+this.error+")"},NavigationError}();t.NavigationError=S;var C=function(){function RoutesRecognized(e,t,n,r){this.id=e,this.url=t,this.urlAfterRedirects=n,this.state=r}return RoutesRecognized.prototype.toString=function(){return"RoutesRecognized(id: "+this.id+", url: '"+this.url+"', urlAfterRedirects: '"+this.urlAfterRedirects+"', state: "+this.state+")"},RoutesRecognized}();t.RoutesRecognized=C;var E=function(){function Router(e,t,n,r,o,s,a,l){this.rootComponentType=e,this.resolver=t,this.urlSerializer=n,this.outletMap=r,this.location=o,this.injector=s,this.navigationId=0,this.navigated=!1,this.resetConfig(l),this.routerEvents=new i.Subject,this.currentUrlTree=g.createEmptyUrlTree(),this.configLoader=new h.RouterConfigLoader(a),this.currentRouterState=m.createEmptyState(this.currentUrlTree,this.rootComponentType)}return Router.prototype.initialNavigation=function(){this.setUpLocationChangeListener(),this.navigateByUrl(this.location.path(!0))},Object.defineProperty(Router.prototype,"routerState",{get:function(){return this.currentRouterState},enumerable:!0,configurable:!0}),Object.defineProperty(Router.prototype,"url",{get:function(){return this.serializeUrl(this.currentUrlTree)},enumerable:!0,configurable:!0}),Object.defineProperty(Router.prototype,"events",{get:function(){return this.routerEvents},enumerable:!0,configurable:!0}),Router.prototype.resetConfig=function(e){l.validateConfig(e),this.config=e},Router.prototype.ngOnDestroy=function(){this.dispose()},Router.prototype.dispose=function(){this.locationSubscription.unsubscribe()},Router.prototype.createUrlTree=function(e,t){var n=void 0===t?{}:t,r=n.relativeTo,i=n.queryParams,o=n.fragment,s=n.preserveQueryParams,a=n.preserveFragment,l=r?r:this.routerState.root,c=s?this.currentUrlTree.queryParams:i,p=a?this.currentUrlTree.fragment:o;return u.createUrlTree(l,this.currentUrlTree,e,c,p)},Router.prototype.navigateByUrl=function(e,t){if(void 0===t&&(t={skipLocationChange:!1}),e instanceof g.UrlTree)return this.scheduleNavigation(e,t);var n=this.urlSerializer.parse(e);return this.scheduleNavigation(n,t)},Router.prototype.navigate=function(e,t){return void 0===t&&(t={skipLocationChange:!1}),this.scheduleNavigation(this.createUrlTree(e,t),t)},Router.prototype.serializeUrl=function(e){return this.urlSerializer.serialize(e)},Router.prototype.parseUrl=function(e){return this.urlSerializer.parse(e)},Router.prototype.isActive=function(e,t){if(e instanceof g.UrlTree)return g.containsTree(this.currentUrlTree,e,t);var n=this.urlSerializer.parse(e);return g.containsTree(this.currentUrlTree,n,t)},Router.prototype.scheduleNavigation=function(e,t){var n=this,r=++this.navigationId;return this.routerEvents.next(new b(r,this.serializeUrl(e))),Promise.resolve().then(function(i){return n.runNavigate(e,t.skipLocationChange,r)})},Router.prototype.setUpLocationChangeListener=function(){var e=this;this.locationSubscription=this.location.subscribe(Zone.current.wrap(function(t){var n=e.urlSerializer.parse(t.url);return e.currentUrlTree.toString()!==n.toString()?e.scheduleNavigation(n,t.pop):null}))},Router.prototype.runNavigate=function(e,t,n){var r=this;return n!==this.navigationId?(this.location.go(this.urlSerializer.serialize(this.currentUrlTree)),this.routerEvents.next(new w(n,this.serializeUrl(e))),Promise.resolve(!1)):new Promise(function(i,o){var l,u,h,f,m=r.currentRouterState,y=r.currentUrlTree;a.applyRedirects(r.injector,r.configLoader,e,r.config).mergeMap(function(e){return f=e,p.recognize(r.rootComponentType,r.config,f,r.serializeUrl(f))}).mergeMap(function(t){return r.routerEvents.next(new C(n,r.serializeUrl(e),r.serializeUrl(f),t)),d.resolve(r.resolver,t)}).map(function(e){return c.createRouterState(e,r.currentRouterState)}).map(function(e){l=e,h=new P(l.snapshot,r.currentRouterState.snapshot,r.injector),h.traverse(r.outletMap)}).mergeMap(function(e){return h.checkGuards()}).mergeMap(function(e){return e?h.resolveData().map(function(){return e}):s.of(e)}).forEach(function(i){if(!i||n!==r.navigationId)return r.routerEvents.next(new w(n,r.serializeUrl(e))),void(u=!1);if(r.currentUrlTree=f,r.currentRouterState=l,new x(l,m).activate(r.outletMap),!t){var o=r.urlSerializer.serialize(f);r.location.isCurrentPathEqualTo(o)?r.location.replaceState(o):r.location.go(o)}u=!0}).then(function(){r.navigated=!0,r.routerEvents.next(new _(n,r.serializeUrl(e),r.serializeUrl(f))),i(u)},function(t){r.currentRouterState=m,r.currentUrlTree=y,r.routerEvents.next(new S(n,r.serializeUrl(e),t)),o(t)})})},Router}();t.Router=E;var T=function(){function CanActivate(e){this.path=e}return Object.defineProperty(CanActivate.prototype,"route",{get:function(){return this.path[this.path.length-1]},enumerable:!0,configurable:!0}),CanActivate}(),R=function(){function CanDeactivate(e,t){this.component=e,this.route=t}return CanDeactivate}(),P=function(){function PreActivation(e,t,n){this.future=e,this.curr=t,this.injector=n,this.checks=[]}return PreActivation.prototype.traverse=function(e){var t=this.future._root,n=this.curr?this.curr._root:null;this.traverseChildRoutes(t,n,e,[t.value])},PreActivation.prototype.checkGuards=function(){var e=this;return 0===this.checks.length?s.of(!0):o.from(this.checks).map(function(t){if(t instanceof T)return v.andObservables(o.from([e.runCanActivate(t.route),e.runCanActivateChild(t.path)]));if(t instanceof R){var n=t;return e.runCanDeactivate(n.component,n.route)}throw new Error("Cannot be reached")}).mergeAll().every(function(e){return e===!0})},PreActivation.prototype.resolveData=function(){var e=this;return 0===this.checks.length?s.of(null):o.from(this.checks).mergeMap(function(t){return t instanceof T?e.runResolve(t.route):s.of(null)}).reduce(function(e,t){return e})},PreActivation.prototype.traverseChildRoutes=function(e,t,n,r){var i=this,o=nodeChildrenAsMap(t);e.children.forEach(function(e){i.traverseRoutes(e,o[e.value.outlet],n,r.concat([e.value])),delete o[e.value.outlet]}),v.forEach(o,function(e,t){return i.deactivateOutletAndItChildren(e,n._outlets[t])})},PreActivation.prototype.traverseRoutes=function(e,t,n,r){var i=e.value,o=t?t.value:null,s=n?n._outlets[e.value.outlet]:null;o&&i._routeConfig===o._routeConfig?(v.shallowEqual(i.params,o.params)||this.checks.push(new R(s.component,o),new T(r)),i.component?this.traverseChildRoutes(e,t,s?s.outletMap:null,r):this.traverseChildRoutes(e,t,n,r)):(o&&(o.component?this.deactivateOutletAndItChildren(o,s):this.deactivateOutletMap(n)),this.checks.push(new T(r)),i.component?this.traverseChildRoutes(e,null,s?s.outletMap:null,r):this.traverseChildRoutes(e,null,n,r))},PreActivation.prototype.deactivateOutletAndItChildren=function(e,t){t&&t.isActivated&&(this.deactivateOutletMap(t.outletMap),this.checks.push(new R(t.component,e)))},PreActivation.prototype.deactivateOutletMap=function(e){var t=this;v.forEach(e._outlets,function(e){e.isActivated&&t.deactivateOutletAndItChildren(e.activatedRoute.snapshot,e)})},PreActivation.prototype.runCanActivate=function(e){var t=this,n=e._routeConfig?e._routeConfig.canActivate:null;if(!n||0===n.length)return s.of(!0);var r=o.from(n).map(function(n){var r=t.getToken(n,e,t.future);return r.canActivate?v.wrapIntoObservable(r.canActivate(e,t.future)):v.wrapIntoObservable(r(e,t.future))});return v.andObservables(r)},PreActivation.prototype.runCanActivateChild=function(e){var t=this,n=e[e.length-1],r=e.slice(0,e.length-1).reverse().map(function(e){return t.extractCanActivateChild(e)}).filter(function(e){return null!==e});return v.andObservables(o.from(r).map(function(e){var r=o.from(e.guards).map(function(e){var r=t.getToken(e,e.node,t.future);return r.canActivateChild?v.wrapIntoObservable(r.canActivateChild(n,t.future)):v.wrapIntoObservable(r(n,t.future))});return v.andObservables(r)}))},PreActivation.prototype.extractCanActivateChild=function(e){var t=e._routeConfig?e._routeConfig.canActivateChild:null;return t&&0!==t.length?{node:e,guards:t}:null},PreActivation.prototype.runCanDeactivate=function(e,t){var n=this,r=t&&t._routeConfig?t._routeConfig.canDeactivate:null;return r&&0!==r.length?o.from(r).map(function(r){var i=n.getToken(r,t,n.curr);return i.canDeactivate?v.wrapIntoObservable(i.canDeactivate(e,t,n.curr)):v.wrapIntoObservable(i(e,t,n.curr))}).mergeAll().every(function(e){return e===!0}):s.of(!0)},PreActivation.prototype.runResolve=function(e){var t=e._resolve;return this.resolveNode(t.current,e).map(function(n){return t.resolvedData=n,e.data=v.merge(e.data,t.flattenedResolvedData),null})},PreActivation.prototype.resolveNode=function(e,t){var n=this;return v.waitForMap(e,function(e,r){var i=n.getToken(r,t,n.future);return i.resolve?v.wrapIntoObservable(i.resolve(t,n.future)):v.wrapIntoObservable(i(t,n.future))})},PreActivation.prototype.getToken=function(e,t,n){var r=closestLoadedConfig(n,t),i=r?r.injector:this.injector;return i.get(e)},PreActivation}(),x=function(){function ActivateRoutes(e,t){this.futureState=e,this.currState=t}return ActivateRoutes.prototype.activate=function(e){var t=this.futureState._root,n=this.currState?this.currState._root:null;m.advanceActivatedRoute(this.futureState.root),this.activateChildRoutes(t,n,e)},ActivateRoutes.prototype.activateChildRoutes=function(e,t,n){var r=this,i=nodeChildrenAsMap(t);e.children.forEach(function(e){r.activateRoutes(e,i[e.value.outlet],n),delete i[e.value.outlet]}),v.forEach(i,function(e,t){return r.deactivateOutletAndItChildren(n._outlets[t])})},ActivateRoutes.prototype.activateRoutes=function(e,t,n){ +var r=n(5),i=function(){function ParseLocation(e,t,n,r){this.file=e,this.offset=t,this.line=n,this.col=r}return ParseLocation.prototype.toString=function(){return r.isPresent(this.offset)?this.file.url+"@"+this.line+":"+this.col:this.file.url},ParseLocation}();t.ParseLocation=i;var o=function(){function ParseSourceFile(e,t){this.content=e,this.url=t}return ParseSourceFile}();t.ParseSourceFile=o;var s=function(){function ParseSourceSpan(e,t,n){void 0===n&&(n=null),this.start=e,this.end=t,this.details=n}return ParseSourceSpan.prototype.toString=function(){return this.start.file.content.substring(this.start.offset,this.end.offset)},ParseSourceSpan}();t.ParseSourceSpan=s,function(e){e[e.WARNING=0]="WARNING",e[e.FATAL=1]="FATAL"}(t.ParseErrorLevel||(t.ParseErrorLevel={}));var a=t.ParseErrorLevel,l=function(){function ParseError(e,t,n){void 0===n&&(n=a.FATAL),this.span=e,this.msg=t,this.level=n}return ParseError.prototype.toString=function(){var e=this.span.start.file.content,t=this.span.start.offset,n="",i="";if(r.isPresent(t)){t>e.length-1&&(t=e.length-1);for(var o=t,s=0,a=0;s<100&&t>0&&(t--,s++,"\n"!=e[t]||3!=++a););for(s=0,a=0;s<100&&o]"+e.substring(this.span.start.offset,o+1);n=' ("'+l+'")'}return this.span.details&&(i=", "+this.span.details),""+this.msg+n+": "+this.span.start+i},ParseError}();t.ParseError=l},function(e,t,n){"use strict";function templateVisitAll(e,t,n){void 0===n&&(n=null);var i=[];return t.forEach(function(t){var o=t.visit(e,n);r.isPresent(o)&&i.push(o)}),i}var r=n(5),i=function(){function TextAst(e,t,n){this.value=e,this.ngContentIndex=t,this.sourceSpan=n}return TextAst.prototype.visit=function(e,t){return e.visitText(this,t)},TextAst}();t.TextAst=i;var o=function(){function BoundTextAst(e,t,n){this.value=e,this.ngContentIndex=t,this.sourceSpan=n}return BoundTextAst.prototype.visit=function(e,t){return e.visitBoundText(this,t)},BoundTextAst}();t.BoundTextAst=o;var s=function(){function AttrAst(e,t,n){this.name=e,this.value=t,this.sourceSpan=n}return AttrAst.prototype.visit=function(e,t){return e.visitAttr(this,t)},AttrAst}();t.AttrAst=s;var a=function(){function BoundElementPropertyAst(e,t,n,r,i,o){this.name=e,this.type=t,this.securityContext=n,this.value=r,this.unit=i,this.sourceSpan=o}return BoundElementPropertyAst.prototype.visit=function(e,t){return e.visitElementProperty(this,t)},BoundElementPropertyAst}();t.BoundElementPropertyAst=a;var l=function(){function BoundEventAst(e,t,n,r){this.name=e,this.target=t,this.handler=n,this.sourceSpan=r}return BoundEventAst.prototype.visit=function(e,t){return e.visitEvent(this,t)},Object.defineProperty(BoundEventAst.prototype,"fullName",{get:function(){return r.isPresent(this.target)?this.target+":"+this.name:this.name},enumerable:!0,configurable:!0}),BoundEventAst}();t.BoundEventAst=l;var c=function(){function ReferenceAst(e,t,n){this.name=e,this.value=t,this.sourceSpan=n}return ReferenceAst.prototype.visit=function(e,t){return e.visitReference(this,t)},ReferenceAst}();t.ReferenceAst=c;var u=function(){function VariableAst(e,t,n){this.name=e,this.value=t,this.sourceSpan=n}return VariableAst.prototype.visit=function(e,t){return e.visitVariable(this,t)},VariableAst}();t.VariableAst=u;var p=function(){function ElementAst(e,t,n,r,i,o,s,a,l,c,u){this.name=e,this.attrs=t,this.inputs=n,this.outputs=r,this.references=i,this.directives=o,this.providers=s,this.hasViewContainer=a,this.children=l,this.ngContentIndex=c,this.sourceSpan=u}return ElementAst.prototype.visit=function(e,t){return e.visitElement(this,t)},ElementAst}();t.ElementAst=p;var d=function(){function EmbeddedTemplateAst(e,t,n,r,i,o,s,a,l,c){this.attrs=e,this.outputs=t,this.references=n,this.variables=r,this.directives=i,this.providers=o,this.hasViewContainer=s,this.children=a,this.ngContentIndex=l,this.sourceSpan=c}return EmbeddedTemplateAst.prototype.visit=function(e,t){return e.visitEmbeddedTemplate(this,t)},EmbeddedTemplateAst}();t.EmbeddedTemplateAst=d;var h=function(){function BoundDirectivePropertyAst(e,t,n,r){this.directiveName=e,this.templateName=t,this.value=n,this.sourceSpan=r}return BoundDirectivePropertyAst.prototype.visit=function(e,t){return e.visitDirectiveProperty(this,t)},BoundDirectivePropertyAst}();t.BoundDirectivePropertyAst=h;var f=function(){function DirectiveAst(e,t,n,r,i){this.directive=e,this.inputs=t,this.hostProperties=n,this.hostEvents=r,this.sourceSpan=i}return DirectiveAst.prototype.visit=function(e,t){return e.visitDirective(this,t)},DirectiveAst}();t.DirectiveAst=f;var m=function(){function ProviderAst(e,t,n,r,i,o,s){this.token=e,this.multiProvider=t,this.eager=n,this.providers=r,this.providerType=i,this.lifecycleHooks=o,this.sourceSpan=s}return ProviderAst.prototype.visit=function(e,t){return null},ProviderAst}();t.ProviderAst=m,function(e){e[e.PublicService=0]="PublicService",e[e.PrivateService=1]="PrivateService",e[e.Component=2]="Component",e[e.Directive=3]="Directive",e[e.Builtin=4]="Builtin"}(t.ProviderAstType||(t.ProviderAstType={}));var g=(t.ProviderAstType,function(){function NgContentAst(e,t,n){this.index=e,this.ngContentIndex=t,this.sourceSpan=n}return NgContentAst.prototype.visit=function(e,t){return e.visitNgContent(this,t)},NgContentAst}());t.NgContentAst=g,function(e){e[e.Property=0]="Property",e[e.Attribute=1]="Attribute",e[e.Class=2]="Class",e[e.Style=3]="Style",e[e.Animation=4]="Animation"}(t.PropertyBindingType||(t.PropertyBindingType={}));t.PropertyBindingType;t.templateVisitAll=templateVisitAll},function(e,t){"use strict";var n=function(){function MessageBus(){}return MessageBus}();t.MessageBus=n},function(e,t){"use strict";t.PRIMARY_OUTLET="primary"},function(e,t,n){var r=n(106),i=n(133),o=n(50),s=n(44),a=n(676);e.exports=function(e,t){var n=1==e,l=2==e,c=3==e,u=4==e,p=6==e,d=5==e||p,h=t||a;return function(t,a,f){for(var m,g,y=o(t),v=i(y),b=r(a,f,3),_=s(v.length),w=0,S=n?h(t,_):l?h(t,0):void 0;_>w;w++)if((d||w in v)&&(m=v[w],g=b(m,w,y),e))if(n)S[w]=g;else if(g)switch(e){case 3:return!0;case 5:return m;case 6:return w;case 2:S.push(m)}else if(u)return!1;return p?-1:c||u?u:S}}},function(e,t,n){var r=n(30),i=n(109);e.exports=n(35)?function(e,t,n){return r.f(e,t,i(1,n))}:function(e,t,n){return e[t]=n,e}},function(e,t,n){var r=n(472),i=n(2),o=n(199)("metadata"),s=o.store||(o.store=new(n(798))),a=function(e,t,n){var i=s.get(e);if(!i){if(!n)return;s.set(e,i=new r)}var o=i.get(t);if(!o){if(!n)return;i.set(t,o=new r)}return o},l=function(e,t,n){var r=a(t,n,!1);return void 0!==r&&r.has(e)},c=function(e,t,n){var r=a(t,n,!1);return void 0===r?void 0:r.get(e)},u=function(e,t,n,r){a(n,r,!0).set(e,t)},p=function(e,t){var n=a(e,t,!1),r=[];return n&&n.forEach(function(e,t){r.push(t)}),r},d=function(e){return void 0===e||"symbol"==typeof e?e:String(e)},h=function(e){i(i.S,"Reflect",e)};e.exports={store:s,map:a,has:l,get:c,set:u,keys:p,key:d,exp:h}},function(e,t,n){var r=n(48),i=n(50),o=n(300)("IE_PROTO"),s=Object.prototype;e.exports=Object.getPrototypeOf||function(e){return e=i(e),r(e,o)?e[o]:"function"==typeof e.constructor&&e instanceof e.constructor?e.constructor.prototype:e instanceof Object?s:null}},function(e,t,n){"use strict";var r=n(347),i=function(){function InterpolationConfig(e,t){this.start=e,this.end=t}return InterpolationConfig.fromArray=function(e){return e?(r.assertInterpolationSymbols("interpolation",e),new InterpolationConfig(e[0],e[1])):t.DEFAULT_INTERPOLATION_CONFIG},InterpolationConfig}();t.InterpolationConfig=i,t.DEFAULT_INTERPOLATION_CONFIG=new i("{{","}}")},[1107,263],function(e,t,n){"use strict";function controlPath(e,t){var n=r.ListWrapper.clone(t.path);return n.push(e),n}function setUpControl(e,t){o.isBlank(e)&&_throwError(t,"Cannot find control with"),o.isBlank(t.valueAccessor)&&_throwError(t,"No value accessor for form control with"),e.validator=s.Validators.compose([e.validator,t.validator]),e.asyncValidator=s.Validators.composeAsync([e.asyncValidator,t.asyncValidator]),t.valueAccessor.writeValue(e.value),t.valueAccessor.registerOnChange(function(n){t.viewToModelUpdate(n),e.markAsDirty(),e.setValue(n,{emitModelToViewChange:!1})}),e.registerOnChange(function(e,n){t.valueAccessor.writeValue(e),n&&t.viewToModelUpdate(e)}),t.valueAccessor.registerOnTouched(function(){return e.markAsTouched()})}function setUpFormContainer(e,t){o.isBlank(e)&&_throwError(t,"Cannot find control with"),e.validator=s.Validators.compose([e.validator,t.validator]),e.asyncValidator=s.Validators.composeAsync([e.asyncValidator,t.asyncValidator])}function _throwError(e,t){var n;throw n=e.path.length>1?"path: '"+e.path.join(" -> ")+"'":e.path[0]?"name: '"+e.path+"'":"unspecified name attribute",new i.BaseException(t+" "+n)}function composeValidators(e){return o.isPresent(e)?s.Validators.compose(e.map(c.normalizeValidator)):null}function composeAsyncValidators(e){return o.isPresent(e)?s.Validators.composeAsync(e.map(c.normalizeAsyncValidator)):null}function isPropertyUpdated(e,t){if(!r.StringMapWrapper.contains(e,"model"))return!1;var n=e.model;return!!n.isFirstChange()||!o.looseIdentical(t,n.currentValue)}function selectValueAccessor(e,t){if(o.isBlank(t))return null;var n,r,i;return t.forEach(function(t){o.hasConstructor(t,l.DefaultValueAccessor)?n=t:o.hasConstructor(t,a.CheckboxControlValueAccessor)||o.hasConstructor(t,u.NumberValueAccessor)||o.hasConstructor(t,d.SelectControlValueAccessor)||o.hasConstructor(t,h.SelectMultipleControlValueAccessor)||o.hasConstructor(t,p.RadioControlValueAccessor)?(o.isPresent(r)&&_throwError(e,"More than one built-in value accessor matches form control with"),r=t):(o.isPresent(i)&&_throwError(e,"More than one custom value accessor matches form control with"),i=t)}),o.isPresent(i)?i:o.isPresent(r)?r:o.isPresent(n)?n:(_throwError(e,"No valid value accessor for form control with"),null)}var r=n(47),i=n(88),o=n(32),s=n(54),a=n(169),l=n(170),c=n(587),u=n(266),p=n(172),d=n(173),h=n(174);t.controlPath=controlPath,t.setUpControl=setUpControl,t.setUpFormContainer=setUpFormContainer,t.composeValidators=composeValidators,t.composeAsyncValidators=composeAsyncValidators,t.isPropertyUpdated=isPropertyUpdated,t.selectValueAccessor=selectValueAccessor},function(e,t){"use strict";!function(e){e[e.Get=0]="Get",e[e.Post=1]="Post",e[e.Put=2]="Put",e[e.Delete=3]="Delete",e[e.Options=4]="Options",e[e.Head=5]="Head",e[e.Patch=6]="Patch"}(t.RequestMethod||(t.RequestMethod={}));t.RequestMethod;!function(e){e[e.Unsent=0]="Unsent",e[e.Open=1]="Open",e[e.HeadersReceived=2]="HeadersReceived",e[e.Loading=3]="Loading",e[e.Done=4]="Done",e[e.Cancelled=5]="Cancelled"}(t.ReadyState||(t.ReadyState={}));t.ReadyState;!function(e){e[e.Basic=0]="Basic",e[e.Cors=1]="Cors",e[e.Default=2]="Default",e[e.Error=3]="Error",e[e.Opaque=4]="Opaque"}(t.ResponseType||(t.ResponseType={}));t.ResponseType;!function(e){e[e.NONE=0]="NONE",e[e.JSON=1]="JSON",e[e.FORM=2]="FORM",e[e.FORM_DATA=3]="FORM_DATA",e[e.TEXT=4]="TEXT",e[e.BLOB=5]="BLOB",e[e.ARRAY_BUFFER=6]="ARRAY_BUFFER"}(t.ContentType||(t.ContentType={}));t.ContentType;!function(e){e[e.Text=0]="Text",e[e.Json=1]="Json",e[e.ArrayBuffer=2]="ArrayBuffer",e[e.Blob=3]="Blob"}(t.ResponseContentType||(t.ResponseContentType={}));t.ResponseContentType},[1106,418,419,419],function(e,t,n){"use strict";function createEmptyUrlTree(){return new o(new s([],{}),{},null)}function containsTree(e,t,n){return n?equalSegmentGroups(e.root,t.root):containsSegmentGroup(e.root,t.root)}function equalSegmentGroups(e,t){if(!equalPath(e.segments,t.segments))return!1;if(e.numberOfChildren!==t.numberOfChildren)return!1;for(var n in t.children){if(!e.children[n])return!1;if(!equalSegmentGroups(e.children[n],t.children[n]))return!1}return!0}function containsSegmentGroup(e,t){return containsSegmentGroupHelper(e,t,t.segments)}function containsSegmentGroupHelper(e,t,n){if(e.segments.length>n.length){var i=e.segments.slice(0,n.length);return!!equalPath(i,n)&&!t.hasChildren()}if(e.segments.length===n.length){if(!equalPath(e.segments,n))return!1;for(var o in t.children){if(!e.children[o])return!1;if(!containsSegmentGroup(e.children[o],t.children[o]))return!1}return!0}var i=n.slice(0,e.segments.length),s=n.slice(e.segments.length);return!!equalPath(e.segments,i)&&(!!e.children[r.PRIMARY_OUTLET]&&containsSegmentGroupHelper(e.children[r.PRIMARY_OUTLET],t,s))}function equalSegments(e,t){if(e.length!==t.length)return!1;for(var n=0;n0?n+"("+o.join("//")+")":""+n}if(e.hasChildren()&&!t){var s=mapChildrenIntoArray(e,function(t,n){return n===r.PRIMARY_OUTLET?[serializeSegment(e.children[r.PRIMARY_OUTLET],!1)]:[n+":"+serializeSegment(t,!1)]});return serializePaths(e)+"/("+s.join("//")+")"}return serializePaths(e)}function encode(e){return encodeURIComponent(e)}function decode(e){return decodeURIComponent(e)}function serializePath(e){return""+encode(e.path)+serializeParams(e.parameters)}function serializeParams(e){return pairs(e).map(function(e){return";"+encode(e.first)+"="+encode(e.second)}).join("")}function serializeQueryParams(e){var t=pairs(e).map(function(e){return encode(e.first)+"="+encode(e.second)});return t.length>0?"?"+t.join("&"):""}function pairs(e){var t=[];for(var n in e)e.hasOwnProperty(n)&&t.push(new u(n,e[n]));return t}function matchSegments(e){p.lastIndex=0;var t=e.match(p);return t?t[0]:""}function matchQueryParams(e){d.lastIndex=0;var t=e.match(p);return t?t[0]:""}function matchUrlQueryParamValue(e){h.lastIndex=0;var t=e.match(h);return t?t[0]:""}var r=n(63),i=n(74);t.createEmptyUrlTree=createEmptyUrlTree,t.containsTree=containsTree;var o=function(){function UrlTree(e,t,n){this.root=e,this.queryParams=t,this.fragment=n}return UrlTree.prototype.toString=function(){return(new c).serialize(this)},UrlTree}();t.UrlTree=o;var s=function(){function UrlSegmentGroup(e,t){var n=this;this.segments=e,this.children=t,this.parent=null,i.forEach(t,function(e,t){return e.parent=n})}return UrlSegmentGroup.prototype.hasChildren=function(){return this.numberOfChildren>0},Object.defineProperty(UrlSegmentGroup.prototype,"numberOfChildren",{get:function(){return Object.keys(this.children).length},enumerable:!0,configurable:!0}),UrlSegmentGroup.prototype.toString=function(){return serializePaths(this)},UrlSegmentGroup}();t.UrlSegmentGroup=s;var a=function(){function UrlSegment(e,t){this.path=e,this.parameters=t}return UrlSegment.prototype.toString=function(){return serializePath(this)},UrlSegment}();t.UrlSegment=a,t.equalSegments=equalSegments,t.equalPath=equalPath,t.mapChildrenIntoArray=mapChildrenIntoArray;var l=function(){function UrlSerializer(){}return UrlSerializer}();t.UrlSerializer=l;var c=function(){function DefaultUrlSerializer(){}return DefaultUrlSerializer.prototype.parse=function(e){var t=new f(e);return new o(t.parseRootSegment(),t.parseQueryParams(),t.parseFragment())},DefaultUrlSerializer.prototype.serialize=function(e){var t="/"+serializeSegment(e.root,!0),n=serializeQueryParams(e.queryParams),r=null!==e.fragment&&void 0!==e.fragment?"#"+encodeURIComponent(e.fragment):"";return""+t+n+r},DefaultUrlSerializer}();t.DefaultUrlSerializer=c,t.serializePaths=serializePaths,t.encode=encode,t.decode=decode,t.serializePath=serializePath;var u=function(){function Pair(e,t){this.first=e,this.second=t}return Pair}(),p=/^[^\/\(\)\?;=&#]+/,d=/^[^=\?&#]+/,h=/^[^\?&#]+/,f=function(){function UrlParser(e){this.url=e,this.remaining=e}return UrlParser.prototype.peekStartsWith=function(e){return this.remaining.startsWith(e)},UrlParser.prototype.capture=function(e){if(!this.remaining.startsWith(e))throw new Error('Expected "'+e+'".');this.remaining=this.remaining.substring(e.length)},UrlParser.prototype.parseRootSegment=function(){return this.remaining.startsWith("/")&&this.capture("/"),""===this.remaining||this.remaining.startsWith("?")||this.remaining.startsWith("#")?new s([],{}):new s([],this.parseChildren())},UrlParser.prototype.parseChildren=function(){if(0==this.remaining.length)return{};this.peekStartsWith("/")&&this.capture("/");var e=[];for(this.peekStartsWith("(")||e.push(this.parseSegments());this.peekStartsWith("/")&&!this.peekStartsWith("//")&&!this.peekStartsWith("/(");)this.capture("/"),e.push(this.parseSegments());var t={};this.peekStartsWith("/(")&&(this.capture("/"),t=this.parseParens(!0));var n={};return this.peekStartsWith("(")&&(n=this.parseParens(!1)),(e.length>0||Object.keys(t).length>0)&&(n[r.PRIMARY_OUTLET]=new s(e,t)),n},UrlParser.prototype.parseSegments=function(){var e=matchSegments(this.remaining);if(""===e&&this.peekStartsWith(";"))throw new Error("Empty path url segment cannot have parameters: '"+this.remaining+"'.");this.capture(e);var t={};return this.peekStartsWith(";")&&(t=this.parseMatrixParams()),new a(decode(e),t)},UrlParser.prototype.parseQueryParams=function(){var e={};if(this.peekStartsWith("?"))for(this.capture("?"),this.parseQueryParam(e);this.remaining.length>0&&this.peekStartsWith("&");)this.capture("&"),this.parseQueryParam(e);return e},UrlParser.prototype.parseFragment=function(){return this.peekStartsWith("#")?decode(this.remaining.substring(1)):null},UrlParser.prototype.parseMatrixParams=function(){for(var e={};this.remaining.length>0&&this.peekStartsWith(";");)this.capture(";"),this.parseParam(e);return e},UrlParser.prototype.parseParam=function(e){var t=matchSegments(this.remaining);if(t){this.capture(t);var n="true";if(this.peekStartsWith("=")){this.capture("=");var r=matchSegments(this.remaining);r&&(n=r,this.capture(n))}e[decode(t)]=decode(n)}},UrlParser.prototype.parseQueryParam=function(e){var t=matchQueryParams(this.remaining);if(t){this.capture(t);var n="";if(this.peekStartsWith("=")){this.capture("=");var r=matchUrlQueryParamValue(this.remaining);r&&(n=r,this.capture(n))}e[decode(t)]=decode(n)}},UrlParser.prototype.parseParens=function(e){var t={};for(this.capture("(");!this.peekStartsWith(")")&&this.remaining.length>0;){var n=matchSegments(this.remaining),i=this.remaining[n.length];if("/"!==i&&")"!==i&&";"!==i)throw new Error("Cannot parse url '"+this.url+"'");var o=void 0;n.indexOf(":")>-1?(o=n.substr(0,n.indexOf(":")),this.capture(o),this.capture(":")):e&&(o=r.PRIMARY_OUTLET);var a=this.parseChildren();t[o]=1===Object.keys(a).length?a[r.PRIMARY_OUTLET]:new s([],a),this.peekStartsWith("//")&&this.capture("//")}return this.capture(")"),t},UrlParser}()},function(e,t,n){"use strict";function shallowEqualArrays(e,t){if(e.length!==t.length)return!1;for(var n=0;n0?e[0]:null}function last(e){return e.length>0?e[e.length-1]:null}function and(e){return e.reduce(function(e,t){return e&&t},!0)}function merge(e,t){var n={};for(var r in e)e.hasOwnProperty(r)&&(n[r]=e[r]);for(var r in t)t.hasOwnProperty(r)&&(n[r]=t[r]);return n}function forEach(e,t){for(var n in e)e.hasOwnProperty(n)&&t(e[n],n)}function waitForMap(e,t){var n=[],r={};return forEach(e,function(e,i){i===s.PRIMARY_OUTLET&&n.push(t(i,e).map(function(e){return r[i]=e,e}))}),forEach(e,function(e,i){i!==s.PRIMARY_OUTLET&&n.push(t(i,e).map(function(e){return r[i]=e,e}))}),n.length>0?o.of.apply(void 0,n).concatAll().last().map(function(e){return r}):o.of(r)}function andObservables(e){return e.mergeAll().every(function(e){return e===!0})}function wrapIntoObservable(e){return e instanceof r.Observable?e:e instanceof Promise?i.fromPromise(e):o.of(e)}n(304),n(497);var r=n(1),i=n(211),o=n(141),s=n(63);t.shallowEqualArrays=shallowEqualArrays,t.shallowEqual=shallowEqual,t.flatten=flatten,t.first=first,t.last=last,t.and=and,t.merge=merge,t.forEach=forEach,t.waitForMap=waitForMap,t.andObservables=andObservables,t.wrapIntoObservable=wrapIntoObservable},function(e,t){e.exports=function(e){if(void 0==e)throw TypeError("Can't call method on "+e);return e}},function(e,t,n){var r=n(137)("meta"),i=n(15),o=n(48),s=n(30).f,a=0,l=Object.isExtensible||function(){return!0},c=!n(13)(function(){return l(Object.preventExtensions({}))}),u=function(e){s(e,r,{value:{i:"O"+ ++a,w:{}}})},p=function(e,t){if(!i(e))return"symbol"==typeof e?e:("string"==typeof e?"S":"P")+e;if(!o(e,r)){if(!l(e))return"F";if(!t)return"E";u(e)}return e[r].i},d=function(e,t){if(!o(e,r)){if(!l(e))return!0;if(!t)return!1;u(e)}return e[r].w},h=function(e){return c&&f.NEED&&l(e)&&!o(e,r)&&u(e),e},f=e.exports={KEY:r,NEED:!1,fastKey:p,getWeak:d,onFreeze:h}},function(e,t,n){var r=n(197),i=n(109),o=n(57),s=n(97),a=n(48),l=n(453),c=Object.getOwnPropertyDescriptor;t.f=n(35)?c:function(e,t){if(e=o(e),t=s(t,!0),l)try{return c(e,t)}catch(n){}if(a(e,t))return i(!r.f.call(e,t),e[t])}},function(e,t){e.exports=".vt-row {\n display: flex;\n flex-wrap: wrap;\n height: 100%;\n width: 100%;\n}\n\n.vt-card {\n display: inline-table;\n margin-left: 25px;\n margin-bottom: 10px;\n margin-top: 10px;\n}\n\n.stats-container {\n width: 100%;\n}\n\n.vt-padding{\n padding-left: 25px;\n padding-right: 25px;\n}\n\n>>> p-dialog .ui-dialog{\n position: fixed !important;\n top: 50% !important;\n left: 50% !important;\n transform: translate(-50%, -50%);\n margin: 0;\n width: auto !important;\n}\n\n.vt-popUpContainer{\n position: fixed;\n padding: 0;\n margin: 0;\n z-index: 0;\n bottom: 0;\n right: 0;\n top: 0;\n left: 0;\n min-height: 1000vh;\n min-width: 1000vw;\n height: 100%;\n width: 100%;\n background: rgba(0,0,0,0.6);\n}\n\n.vt-dark-link:link {\n text-decoration: none;\n color: black;\n}\n\n.vt-dark-link:visited {\n text-decoration: none;\n color: black;\n}\n\n.vt-dark-link:hover {\n text-decoration: none;\n color: black;\n}\n\n.vt-dark-link:active {\n text-decoration: none;\n color: black;\n}\n\n/* Toolbar */\n.vt-toolbar {\n width: 100%;\n text-align: center;\n}\n\n>>> p-accordiontab a {\n padding-left: 25px! important;\n}\n\n>>> .ui-accordion-content button {\n margin-top: 2px;\n}\n\n>>> p-menu .ui-menu {\n margin-top: 19px;\n display: inline-block;\n top: auto !important;\n left: auto !important;\n float: right;\n \n}\n\np-menu {\n display: inline-block;\n float: left;\n}\n\n.vt-toolbar .vt-menu {\n padding-top: 19px;\n float: left;\n}\n\n.vt-toolbar .vt-right-menu {\n padding-top: 19px;\n position: fixed;\n right: 25px;\n top: 19px;\n}\n\n.vt-card-toolbar {\n display: inline-block;\n width: 100%;\n}\n\n.vt-card-toolbar .vt-menu {\n float: left;\n}\n.vt-card-toolbar .vt-title {\n float: right;\n margin: 0;\n padding-left: 25px;\n}\n\nmd-list:hover {\n background: #E8E8E8\n}\n"},function(e,t,n){"use strict";var r=this&&this.__extends||function(e,t){function __(){this.constructor=e}for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n]);e.prototype=null===t?Object.create(t):(__.prototype=t.prototype,new __)},i=n(1),o=n(308),s=n(80),a=n(98),l=function(e){function ArrayObservable(t,n){e.call(this),this.array=t,this.scheduler=n,n||1!==t.length||(this._isScalar=!0,this.value=t[0])}return r(ArrayObservable,e),ArrayObservable.create=function(e,t){return new ArrayObservable(e,t)},ArrayObservable.of=function(){for(var e=[],t=0;t1?new ArrayObservable(e,n):1===r?new o.ScalarObservable(e[0],n):new s.EmptyObservable(n)},ArrayObservable.dispatch=function(e){var t=e.array,n=e.index,r=e.count,i=e.subscriber;return n>=r?void i.complete():(i.next(t[n]),void(i.isUnsubscribed||(e.index=n+1,this.schedule(e))))},ArrayObservable.prototype._subscribe=function(e){var t=0,n=this.array,r=n.length,i=this.scheduler;if(i)return i.schedule(ArrayObservable.dispatch,0,{array:n,index:t,count:r,subscriber:e});for(var o=0;o0?" { "+e.children.map(serializeNode).join(", ")+" } ":"";return""+e.value+t}function advanceActivatedRoute(e){e.snapshot?(a.shallowEqual(e.snapshot.queryParams,e._futureSnapshot.queryParams)||e.queryParams.next(e._futureSnapshot.queryParams),e.snapshot.fragment!==e._futureSnapshot.fragment&&e.fragment.next(e._futureSnapshot.fragment),a.shallowEqual(e.snapshot.params,e._futureSnapshot.params)||(e.params.next(e._futureSnapshot.params),e.data.next(e._futureSnapshot.data)),a.shallowEqualArrays(e.snapshot.url,e._futureSnapshot.url)||e.url.next(e._futureSnapshot.url),e.snapshot=e._futureSnapshot):(e.snapshot=e._futureSnapshot,e.data.next(e._futureSnapshot.data))}var r=this&&this.__extends||function(e,t){function __(){this.constructor=e}for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n]);e.prototype=null===t?Object.create(t):(__.prototype=t.prototype,new __)},i=n(207),o=n(63),s=n(73),a=n(74),l=n(281),c=function(e){function RouterState(t,n){e.call(this,t),this.snapshot=n,setRouterStateSnapshot(this,t)}return r(RouterState,e),Object.defineProperty(RouterState.prototype,"queryParams",{get:function(){return this.root.queryParams},enumerable:!0,configurable:!0}),Object.defineProperty(RouterState.prototype,"fragment",{get:function(){return this.root.fragment},enumerable:!0,configurable:!0}),RouterState.prototype.toString=function(){return this.snapshot.toString()},RouterState}(l.Tree);t.RouterState=c,t.createEmptyState=createEmptyState;var u=function(){function ActivatedRoute(e,t,n,r,i,o,s,a){this.url=e,this.params=t,this.queryParams=n,this.fragment=r,this.data=i,this.outlet=o,this.component=s,this._futureSnapshot=a}return Object.defineProperty(ActivatedRoute.prototype,"routeConfig",{get:function(){return this._futureSnapshot.routeConfig},enumerable:!0,configurable:!0}),Object.defineProperty(ActivatedRoute.prototype,"root",{get:function(){return this._routerState.root},enumerable:!0,configurable:!0}),Object.defineProperty(ActivatedRoute.prototype,"parent",{get:function(){return this._routerState.parent(this)},enumerable:!0,configurable:!0}),Object.defineProperty(ActivatedRoute.prototype,"firstChild",{get:function(){return this._routerState.firstChild(this)},enumerable:!0,configurable:!0}),Object.defineProperty(ActivatedRoute.prototype,"children",{get:function(){return this._routerState.children(this)},enumerable:!0,configurable:!0}),Object.defineProperty(ActivatedRoute.prototype,"pathFromRoot",{get:function(){return this._routerState.pathFromRoot(this)},enumerable:!0,configurable:!0}),ActivatedRoute.prototype.toString=function(){return this.snapshot?this.snapshot.toString():"Future("+this._futureSnapshot+")"},ActivatedRoute}();t.ActivatedRoute=u;var p=function(){function InheritedResolve(e,t){this.parent=e,this.current=t,this.resolvedData={}}return Object.defineProperty(InheritedResolve.prototype,"flattenedResolvedData",{get:function(){return this.parent?a.merge(this.parent.flattenedResolvedData,this.resolvedData):this.resolvedData},enumerable:!0,configurable:!0}),Object.defineProperty(InheritedResolve,"empty",{get:function(){return new InheritedResolve(null,{})},enumerable:!0,configurable:!0}),InheritedResolve}();t.InheritedResolve=p;var d=function(){function ActivatedRouteSnapshot(e,t,n,r,i,o,s,a,l,c,u){this.url=e,this.params=t,this.queryParams=n,this.fragment=r,this.data=i,this.outlet=o,this.component=s,this._routeConfig=a,this._urlSegment=l,this._lastPathIndex=c,this._resolve=u}return Object.defineProperty(ActivatedRouteSnapshot.prototype,"routeConfig",{get:function(){return this._routeConfig},enumerable:!0,configurable:!0}),Object.defineProperty(ActivatedRouteSnapshot.prototype,"root",{get:function(){return this._routerState.root},enumerable:!0,configurable:!0}),Object.defineProperty(ActivatedRouteSnapshot.prototype,"parent",{get:function(){return this._routerState.parent(this)},enumerable:!0,configurable:!0}),Object.defineProperty(ActivatedRouteSnapshot.prototype,"firstChild",{get:function(){return this._routerState.firstChild(this)},enumerable:!0,configurable:!0}),Object.defineProperty(ActivatedRouteSnapshot.prototype,"children",{get:function(){return this._routerState.children(this)},enumerable:!0,configurable:!0}),Object.defineProperty(ActivatedRouteSnapshot.prototype,"pathFromRoot",{get:function(){return this._routerState.pathFromRoot(this)},enumerable:!0,configurable:!0}),ActivatedRouteSnapshot.prototype.toString=function(){var e=this.url.map(function(e){return e.toString()}).join("/"),t=this._routeConfig?this._routeConfig.path:"";return"Route(url:'"+e+"', path:'"+t+"')"},ActivatedRouteSnapshot}();t.ActivatedRouteSnapshot=d;var h=function(e){function RouterStateSnapshot(t,n){e.call(this,n),this.url=t,setRouterStateSnapshot(this,n)}return r(RouterStateSnapshot,e),Object.defineProperty(RouterStateSnapshot.prototype,"queryParams",{get:function(){return this.root.queryParams},enumerable:!0,configurable:!0}),Object.defineProperty(RouterStateSnapshot.prototype,"fragment",{get:function(){return this.root.fragment},enumerable:!0,configurable:!0}),RouterStateSnapshot.prototype.toString=function(){return serializeNode(this._root)},RouterStateSnapshot}(l.Tree);t.RouterStateSnapshot=h,t.advanceActivatedRoute=advanceActivatedRoute},function(e,t,n){"use strict";var r=n(43),i=(n.n(r),n(0));n.n(i);n.d(t,"a",function(){return a});var o=this&&this.__decorate||function(e,t,n,r){var i,o=arguments.length,s=o<3?t:null===r?r=Object.getOwnPropertyDescriptor(t,n):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(e,t,n,r);else for(var a=e.length-1;a>=0;a--)(i=e[a])&&(s=(o<3?i(s):o>3?i(t,n,s):i(t,n))||s);return o>3&&s&&Object.defineProperty(t,n,s),s},s=this&&this.__metadata||function(e,t){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(e,t)},a=function(){function VtctlService(e){this.http=e,this.vtctlUrl="../api/vtctl/"}return VtctlService.prototype.sendPostRequest=function(e,t){var n=new r.Headers({"Content-Type":"application/json"}),i=new r.RequestOptions({headers:n});return this.http.post(e,JSON.stringify(t),i).map(function(e){return e.json()})},VtctlService.prototype.runCommand=function(e){return this.sendPostRequest(this.vtctlUrl,e)},VtctlService=o([n.i(i.Injectable)(),s("design:paramtypes",["function"==typeof(e="undefined"!=typeof r.Http&&r.Http)&&e||Object])],VtctlService);var e}()},function(e,t,n){"use strict";var r=n(192);n.d(t,"a",function(){return i});var i=function(){function DialogContent(e,t,n,r,i){void 0===e&&(e=""),void 0===t&&(t={}),void 0===n&&(n={}),void 0===r&&(r=void 0),void 0===i&&(i=""),this.nameId=e,this.flags=t,this.requiredFlags=n,this.prepareFunction=r,this.action=i}return DialogContent.prototype.getName=function(){return this.flags[this.nameId]?this.flags[this.nameId].getStrValue():""},DialogContent.prototype.setName=function(e){this.flags[this.nameId]&&this.flags[this.nameId].setValue(e)},DialogContent.prototype.getPostBody=function(e){void 0===e&&(e=void 0),e||(e=this.getFlags());var t=[],n=[];t.push(this.action);for(var r=0,i=e;r1?"path: '"+e.path.join(" -> ")+"'":e.path[0]?"name: '"+e.path+"'":"unspecified name",new i.BaseException(t+" "+n)}function composeValidators(e){return o.isPresent(e)?s.Validators.compose(e.map(c.normalizeValidator)):null}function composeAsyncValidators(e){return o.isPresent(e)?s.Validators.composeAsync(e.map(c.normalizeAsyncValidator)):null}function isPropertyUpdated(e,t){if(!r.StringMapWrapper.contains(e,"model"))return!1;var n=e.model;return!!n.isFirstChange()||!o.looseIdentical(t,n.currentValue)}function selectValueAccessor(e,t){if(o.isBlank(t))return null;var n,r,i;return t.forEach(function(t){o.hasConstructor(t,l.DefaultValueAccessor)?n=t:o.hasConstructor(t,a.CheckboxControlValueAccessor)||o.hasConstructor(t,u.NumberValueAccessor)||o.hasConstructor(t,d.SelectControlValueAccessor)||o.hasConstructor(t,h.SelectMultipleControlValueAccessor)||o.hasConstructor(t,p.RadioControlValueAccessor)?(o.isPresent(r)&&_throwError(e,"More than one built-in value accessor matches form control with"),r=t):(o.isPresent(i)&&_throwError(e,"More than one custom value accessor matches form control with"),i=t)}),o.isPresent(i)?i:o.isPresent(r)?r:o.isPresent(n)?n:(_throwError(e,"No valid value accessor for form control with"),null)}var r=n(34),i=n(83),o=n(7),s=n(58),a=n(144),l=n(145),c=n(526),u=n(227),p=n(146),d=n(147),h=n(228);t.controlPath=controlPath,t.setUpControl=setUpControl,t.setUpControlGroup=setUpControlGroup,t.composeValidators=composeValidators,t.composeAsyncValidators=composeAsyncValidators,t.isPropertyUpdated=isPropertyUpdated,t.selectValueAccessor=selectValueAccessor},function(e,t,n){"use strict";var r=n(0),i=n(18),o=n(28),s=function(){function CompilerConfig(e){var t=void 0===e?{}:e,n=t.renderTypes,i=void 0===n?new l:n,o=t.defaultEncapsulation,s=void 0===o?r.ViewEncapsulation.Emulated:o,a=t.genDebugInfo,c=t.logBindingUpdate,u=t.useJit,p=void 0===u||u,d=t.deprecatedPlatformDirectives,h=void 0===d?[]:d,f=t.deprecatedPlatformPipes,m=void 0===f?[]:f;this.renderTypes=i,this.defaultEncapsulation=s,this._genDebugInfo=a,this._logBindingUpdate=c,this.useJit=p,this.platformDirectives=h,this.platformPipes=m}return Object.defineProperty(CompilerConfig.prototype,"genDebugInfo",{get:function(){return void 0===this._genDebugInfo?r.isDevMode():this._genDebugInfo},enumerable:!0,configurable:!0}),Object.defineProperty(CompilerConfig.prototype,"logBindingUpdate",{get:function(){return void 0===this._logBindingUpdate?r.isDevMode():this._logBindingUpdate},enumerable:!0,configurable:!0}),CompilerConfig}();t.CompilerConfig=s;var a=function(){function RenderTypes(){}return Object.defineProperty(RenderTypes.prototype,"renderer",{get:function(){return i.unimplemented()},enumerable:!0,configurable:!0}),Object.defineProperty(RenderTypes.prototype,"renderText",{get:function(){return i.unimplemented()},enumerable:!0,configurable:!0}),Object.defineProperty(RenderTypes.prototype,"renderElement",{get:function(){return i.unimplemented()},enumerable:!0,configurable:!0}),Object.defineProperty(RenderTypes.prototype,"renderComment",{get:function(){return i.unimplemented()},enumerable:!0,configurable:!0}),Object.defineProperty(RenderTypes.prototype,"renderNode",{get:function(){return i.unimplemented()},enumerable:!0,configurable:!0}),Object.defineProperty(RenderTypes.prototype,"renderEvent",{get:function(){return i.unimplemented()},enumerable:!0,configurable:!0}),RenderTypes}();t.RenderTypes=a;var l=function(){function DefaultRenderTypes(){this.renderer=o.Identifiers.Renderer,this.renderText=null,this.renderElement=null,this.renderComment=null,this.renderNode=null,this.renderEvent=null}return DefaultRenderTypes}();t.DefaultRenderTypes=l},function(e,t){"use strict";function splitNsName(e){if(":"!=e[0])return[null,e];var t=e.indexOf(":",1);if(t==-1)throw new Error('Unsupported format "'+e+'" expecting ":namespace:name"');return[e.slice(1,t),e.slice(t+1)]}function getNsPrefix(e){return null===e?null:splitNsName(e)[0]}function mergeNsAndName(e,t){return e?":"+e+":"+t:t}!function(e){e[e.RAW_TEXT=0]="RAW_TEXT",e[e.ESCAPABLE_RAW_TEXT=1]="ESCAPABLE_RAW_TEXT",e[e.PARSABLE_DATA=2]="PARSABLE_DATA"}(t.TagContentType||(t.TagContentType={}));t.TagContentType;t.splitNsName=splitNsName,t.getNsPrefix=getNsPrefix,t.mergeNsAndName=mergeNsAndName,t.NAMED_ENTITIES={Aacute:"Á",aacute:"á",Acirc:"Â",acirc:"â",acute:"´",AElig:"Æ",aelig:"æ",Agrave:"À",agrave:"à",alefsym:"ℵ",Alpha:"Α",alpha:"α",amp:"&",and:"∧",ang:"∠",apos:"'",Aring:"Å",aring:"å",asymp:"≈",Atilde:"Ã",atilde:"ã",Auml:"Ä",auml:"ä",bdquo:"„",Beta:"Β",beta:"β",brvbar:"¦",bull:"•",cap:"∩",Ccedil:"Ç",ccedil:"ç",cedil:"¸",cent:"¢",Chi:"Χ",chi:"χ",circ:"ˆ",clubs:"♣",cong:"≅",copy:"©",crarr:"↵",cup:"∪",curren:"¤",dagger:"†",Dagger:"‡",darr:"↓",dArr:"⇓",deg:"°",Delta:"Δ",delta:"δ",diams:"♦",divide:"÷",Eacute:"É",eacute:"é",Ecirc:"Ê",ecirc:"ê",Egrave:"È",egrave:"è",empty:"∅",emsp:" ",ensp:" ",Epsilon:"Ε",epsilon:"ε",equiv:"≡",Eta:"Η",eta:"η",ETH:"Ð",eth:"ð",Euml:"Ë",euml:"ë",euro:"€",exist:"∃",fnof:"ƒ",forall:"∀",frac12:"½",frac14:"¼",frac34:"¾",frasl:"⁄",Gamma:"Γ",gamma:"γ",ge:"≥",gt:">",harr:"↔",hArr:"⇔",hearts:"♥",hellip:"…",Iacute:"Í",iacute:"í",Icirc:"Î",icirc:"î",iexcl:"¡",Igrave:"Ì",igrave:"ì",image:"ℑ",infin:"∞","int":"∫",Iota:"Ι",iota:"ι",iquest:"¿",isin:"∈",Iuml:"Ï",iuml:"ï",Kappa:"Κ",kappa:"κ",Lambda:"Λ",lambda:"λ",lang:"⟨",laquo:"«",larr:"←",lArr:"⇐",lceil:"⌈",ldquo:"“",le:"≤",lfloor:"⌊",lowast:"∗",loz:"◊",lrm:"‎",lsaquo:"‹",lsquo:"‘",lt:"<",macr:"¯",mdash:"—",micro:"µ",middot:"·",minus:"−",Mu:"Μ",mu:"μ",nabla:"∇",nbsp:" ",ndash:"–",ne:"≠",ni:"∋",not:"¬",notin:"∉",nsub:"⊄",Ntilde:"Ñ",ntilde:"ñ",Nu:"Ν",nu:"ν",Oacute:"Ó",oacute:"ó",Ocirc:"Ô",ocirc:"ô",OElig:"Œ",oelig:"œ",Ograve:"Ò",ograve:"ò",oline:"‾",Omega:"Ω",omega:"ω",Omicron:"Ο",omicron:"ο",oplus:"⊕",or:"∨",ordf:"ª",ordm:"º",Oslash:"Ø",oslash:"ø",Otilde:"Õ",otilde:"õ",otimes:"⊗",Ouml:"Ö",ouml:"ö",para:"¶",permil:"‰",perp:"⊥",Phi:"Φ",phi:"φ",Pi:"Π",pi:"π",piv:"ϖ",plusmn:"±",pound:"£",prime:"′",Prime:"″",prod:"∏",prop:"∝",Psi:"Ψ",psi:"ψ",quot:'"',radic:"√",rang:"⟩",raquo:"»",rarr:"→",rArr:"⇒",rceil:"⌉",rdquo:"”",real:"ℜ",reg:"®",rfloor:"⌋",Rho:"Ρ",rho:"ρ",rlm:"‏",rsaquo:"›",rsquo:"’",sbquo:"‚",Scaron:"Š",scaron:"š",sdot:"⋅",sect:"§",shy:"­",Sigma:"Σ",sigma:"σ",sigmaf:"ς",sim:"∼",spades:"♠",sub:"⊂",sube:"⊆",sum:"∑",sup:"⊃",sup1:"¹",sup2:"²",sup3:"³",supe:"⊇",szlig:"ß",Tau:"Τ",tau:"τ",there4:"∴",Theta:"Θ",theta:"θ",thetasym:"ϑ",thinsp:" ",THORN:"Þ",thorn:"þ",tilde:"˜",times:"×",trade:"™",Uacute:"Ú",uacute:"ú",uarr:"↑",uArr:"⇑",Ucirc:"Û",ucirc:"û",Ugrave:"Ù",ugrave:"ù",uml:"¨",upsih:"ϒ",Upsilon:"Υ",upsilon:"υ",Uuml:"Ü",uuml:"ü",weierp:"℘",Xi:"Ξ",xi:"ξ",Yacute:"Ý",yacute:"ý",yen:"¥",yuml:"ÿ",Yuml:"Ÿ",Zeta:"Ζ",zeta:"ζ",zwj:"‍",zwnj:"‌"}},function(e,t,n){"use strict";function createUrlResolverWithoutPackagePrefix(){return new s}function createOfflineCompileUrlResolver(){return new s(o)}function getUrlScheme(e){var t=_split(e);return t&&t[a.Scheme]||""}function _buildFromEncodedParts(e,t,n,r,o,s,a){var l=[];return i.isPresent(e)&&l.push(e+":"),i.isPresent(n)&&(l.push("//"),i.isPresent(t)&&l.push(t+"@"),l.push(n),i.isPresent(r)&&l.push(":"+r)),i.isPresent(o)&&l.push(o),i.isPresent(s)&&l.push("?"+s),i.isPresent(a)&&l.push("#"+a),l.join("")}function _split(e){return e.match(l)}function _removeDotSegments(e){if("/"==e)return"/";for(var t="/"==e[0]?"/":"",n="/"===e[e.length-1]?"/":"",r=e.split("/"),i=[],o=0,s=0;s0?i.pop():o++;break;default:i.push(a)}}if(""==t){for(;o-- >0;)i.unshift("..");0===i.length&&i.push(".")}return t+i.join("/")+n}function _joinAndCanonicalizePath(e){var t=e[a.Path];return t=i.isBlank(t)?"":_removeDotSegments(t),e[a.Path]=t,_buildFromEncodedParts(e[a.Scheme],e[a.UserInfo],e[a.Domain],e[a.Port],t,e[a.QueryData],e[a.Fragment])}function _resolveUrl(e,t){var n=_split(encodeURI(t)),r=_split(e);if(i.isPresent(n[a.Scheme]))return _joinAndCanonicalizePath(n);n[a.Scheme]=r[a.Scheme];for(var o=a.Scheme;o<=a.Port;o++)i.isBlank(n[o])&&(n[o]=r[o]);if("/"==n[a.Path][0])return _joinAndCanonicalizePath(n);var s=r[a.Path];i.isBlank(s)&&(s="/");var l=s.lastIndexOf("/");return s=s.substring(0,l+1)+n[a.Path],n[a.Path]=s,_joinAndCanonicalizePath(n)}var r=n(0),i=n(5),o="asset:";t.createUrlResolverWithoutPackagePrefix=createUrlResolverWithoutPackagePrefix,t.createOfflineCompileUrlResolver=createOfflineCompileUrlResolver,t.DEFAULT_PACKAGE_URL_PROVIDER={provide:r.PACKAGE_ROOT_URL,useValue:"/"};var s=function(){function UrlResolver(e){void 0===e&&(e=null),this._packagePrefix=e}return UrlResolver.prototype.resolve=function(e,t){var n=t;i.isPresent(e)&&e.length>0&&(n=_resolveUrl(e,n));var r=_split(n),s=this._packagePrefix;if(i.isPresent(s)&&i.isPresent(r)&&"package"==r[a.Scheme]){var l=r[a.Path];if(this._packagePrefix!==o)return s=i.StringWrapper.stripRight(s,"/"),l=i.StringWrapper.stripLeft(l,"/"),s+"/"+l;var c=l.split(/\//);n="asset:"+c[0]+"/lib/"+c.slice(1).join("/")}return n},UrlResolver.decorators=[{type:r.Injectable}],UrlResolver.ctorParameters=[{type:void 0,decorators:[{type:r.Inject,args:[r.PACKAGE_ROOT_URL]}]}],UrlResolver}();t.UrlResolver=s,t.getUrlScheme=getUrlScheme;var a,l=new RegExp("^(?:([^:/?#.]+):)?(?://(?:([^/?#]*)@)?([\\w\\d\\-\\u0100-\\uffff.%]*)(?::([0-9]+))?)?([^?#]+)?(?:\\?([^#]*))?(?:#(.*))?$");!function(e){e[e.Scheme=1]="Scheme",e[e.UserInfo=2]="UserInfo",e[e.Domain=3]="Domain",e[e.Port=4]="Port",e[e.Path=5]="Path",e[e.QueryData=6]="QueryData",e[e.Fragment=7]="Fragment"}(a||(a={}))},function(e,t,n){"use strict";function _enumExpression(e,t){if(s.isBlank(t))return l.NULL_EXPR;var n=s.resolveEnumToken(e.runtime,t);return l.importExpr(new o.CompileIdentifierMetadata({name:e.name+"."+n,moduleUrl:e.moduleUrl,runtime:t}))}var r=n(0),i=n(27),o=n(31),s=n(5),a=n(28),l=n(17),c=function(){function ViewTypeEnum(){}return ViewTypeEnum.fromValue=function(e){return _enumExpression(a.Identifiers.ViewType,e)},ViewTypeEnum.HOST=ViewTypeEnum.fromValue(i.ViewType.HOST),ViewTypeEnum.COMPONENT=ViewTypeEnum.fromValue(i.ViewType.COMPONENT),ViewTypeEnum.EMBEDDED=ViewTypeEnum.fromValue(i.ViewType.EMBEDDED),ViewTypeEnum}();t.ViewTypeEnum=c;var u=function(){function ViewEncapsulationEnum(){}return ViewEncapsulationEnum.fromValue=function(e){return _enumExpression(a.Identifiers.ViewEncapsulation,e)},ViewEncapsulationEnum.Emulated=ViewEncapsulationEnum.fromValue(r.ViewEncapsulation.Emulated),ViewEncapsulationEnum.Native=ViewEncapsulationEnum.fromValue(r.ViewEncapsulation.Native),ViewEncapsulationEnum.None=ViewEncapsulationEnum.fromValue(r.ViewEncapsulation.None),ViewEncapsulationEnum}();t.ViewEncapsulationEnum=u;var p=function(){function ChangeDetectionStrategyEnum(){}return ChangeDetectionStrategyEnum.fromValue=function(e){return _enumExpression(a.Identifiers.ChangeDetectionStrategy,e)},ChangeDetectionStrategyEnum.OnPush=ChangeDetectionStrategyEnum.fromValue(r.ChangeDetectionStrategy.OnPush),ChangeDetectionStrategyEnum.Default=ChangeDetectionStrategyEnum.fromValue(r.ChangeDetectionStrategy.Default),ChangeDetectionStrategyEnum}();t.ChangeDetectionStrategyEnum=p;var d=function(){function ChangeDetectorStatusEnum(){}return ChangeDetectorStatusEnum.fromValue=function(e){return _enumExpression(a.Identifiers.ChangeDetectorStatus,e)},ChangeDetectorStatusEnum.CheckOnce=ChangeDetectorStatusEnum.fromValue(i.ChangeDetectorStatus.CheckOnce),ChangeDetectorStatusEnum.Checked=ChangeDetectorStatusEnum.fromValue(i.ChangeDetectorStatus.Checked),ChangeDetectorStatusEnum.CheckAlways=ChangeDetectorStatusEnum.fromValue(i.ChangeDetectorStatus.CheckAlways),ChangeDetectorStatusEnum.Detached=ChangeDetectorStatusEnum.fromValue(i.ChangeDetectorStatus.Detached),ChangeDetectorStatusEnum.Errored=ChangeDetectorStatusEnum.fromValue(i.ChangeDetectorStatus.Errored),ChangeDetectorStatusEnum.Destroyed=ChangeDetectorStatusEnum.fromValue(i.ChangeDetectorStatus.Destroyed),ChangeDetectorStatusEnum}();t.ChangeDetectorStatusEnum=d;var h=function(){function ViewConstructorVars(){}return ViewConstructorVars.viewUtils=l.variable("viewUtils"),ViewConstructorVars.parentInjector=l.variable("parentInjector"),ViewConstructorVars.declarationEl=l.variable("declarationEl"),ViewConstructorVars}();t.ViewConstructorVars=h;var f=function(){function ViewProperties(){}return ViewProperties.renderer=l.THIS_EXPR.prop("renderer"),ViewProperties.projectableNodes=l.THIS_EXPR.prop("projectableNodes"),ViewProperties.viewUtils=l.THIS_EXPR.prop("viewUtils"),ViewProperties}();t.ViewProperties=f;var m=function(){function EventHandlerVars(){}return EventHandlerVars.event=l.variable("$event"),EventHandlerVars}();t.EventHandlerVars=m;var g=function(){function InjectMethodVars(){}return InjectMethodVars.token=l.variable("token"),InjectMethodVars.requestNodeIndex=l.variable("requestNodeIndex"),InjectMethodVars.notFoundResult=l.variable("notFoundResult"),InjectMethodVars}();t.InjectMethodVars=g;var y=function(){function DetectChangesVars(){}return DetectChangesVars.throwOnChange=l.variable("throwOnChange"),DetectChangesVars.changes=l.variable("changes"),DetectChangesVars.changed=l.variable("changed"),DetectChangesVars.valUnwrapper=l.variable("valUnwrapper"),DetectChangesVars}();t.DetectChangesVars=y},99,function(e,t,n){var r=n(95);e.exports=function(e,t,n){if(r(e),void 0===t)return e;switch(n){case 1:return function(n){return e.call(t,n)};case 2:return function(n,r){return e.call(t,n,r)};case 3:return function(n,r,i){return e.call(t,n,r,i)}}return function(){return e.apply(t,arguments)}}},function(e,t,n){var r=n(8),i=n(462),o=n(288),s=n(300)("IE_PROTO"),a=function(){},l="prototype",c=function(){var e,t=n(451)("iframe"),r=o.length,i="<",s=">";for(t.style.display="none",n(452).appendChild(t),t.src="javascript:",e=t.contentWindow.document,e.open(),e.write(i+"script"+s+"document.F=Object"+i+"/script"+s),e.close(),c=e.F;r--;)delete c[l][o[r]];return c()};e.exports=Object.create||function(e,t){var n;return null!==e?(a[l]=r(e),n=new a,a[l]=null,n[s]=e):n=c(),void 0===t?n:i(n,t)}},function(e,t,n){var r=n(464),i=n(288);e.exports=Object.keys||function(e){return r(e,i)}},function(e,t){e.exports=function(e,t){return{enumerable:!(1&e),configurable:!(2&e),writable:!(4&e),value:t}}},function(e,t){var n=Math.ceil,r=Math.floor;e.exports=function(e){return isNaN(e=+e)?0:(e>0?r:n)(e)}},function(e,t,n){"use strict";function multicast(e){var t;return t="function"==typeof e?e:function(){return e},new r.ConnectableObservable(this,t)}var r=n(502);t.multicast=multicast},[1107,219],function(e,t){"use strict";var n=function(){function ElementSchemaRegistry(){}return ElementSchemaRegistry}();t.ElementSchemaRegistry=n},function(e,t,n){"use strict";function getPropertyInView(e,t,n){if(t===n)return e;for(var o=s.THIS_EXPR,a=t;a!==n&&i.isPresent(a.declarationElement.view);)a=a.declarationElement.view,o=o.prop("parent");if(a!==n)throw new r.BaseException("Internal error: Could not calculate a property in a parent view: "+e);if(e instanceof s.ReadPropExpr){var l=e;(n.fields.some(function(e){return e.name==l.name})||n.getters.some(function(e){return e.name==l.name}))&&(o=o.cast(n.classType))}return s.replaceVarInExpression(s.THIS_EXPR.name,o,e)}function injectFromViewParentInjector(e,t){var n=[a.createDiTokenExpression(e)];return t&&n.push(s.NULL_EXPR),s.THIS_EXPR.prop("parentInjector").callMethod("get",n)}function getViewFactoryName(e,t){return"viewFactory_"+e.type.name+t}function createFlatArray(e){for(var t=[],n=s.literalArr([]),r=0;r0&&(n=n.callMethod(s.BuiltinMethod.ConcatArray,[s.literalArr(t)]),t=[]),n=n.callMethod(s.BuiltinMethod.ConcatArray,[i])):t.push(i)}return t.length>0&&(n=n.callMethod(s.BuiltinMethod.ConcatArray,[s.literalArr(t)])),n}function createPureProxy(e,t,n,a){a.fields.push(new s.ClassField(n.name,null));var l=t0){var r=e.substring(0,n),i=e.substring(n+1).trim();t.set(r,i)}}),t},Headers.prototype.append=function(e,t){e=normalize(e);var n=this._headersMap.get(e),i=r.isListLikeIterable(n)?n:[];i.push(t),this._headersMap.set(e,i)},Headers.prototype.delete=function(e){this._headersMap.delete(normalize(e))},Headers.prototype.forEach=function(e){this._headersMap.forEach(e)},Headers.prototype.get=function(e){return r.ListWrapper.first(this._headersMap.get(normalize(e)))},Headers.prototype.has=function(e){return this._headersMap.has(normalize(e))},Headers.prototype.keys=function(){return r.MapWrapper.keys(this._headersMap)},Headers.prototype.set=function(e,t){var n=[];if(r.isListLikeIterable(t)){var i=t.join(",");n.push(i)}else n.push(t);this._headersMap.set(normalize(e),n)},Headers.prototype.values=function(){return r.MapWrapper.values(this._headersMap)},Headers.prototype.toJSON=function(){var e={};return this._headersMap.forEach(function(t,n){var i=[];r.iterateListLike(t,function(e){return i=r.ListWrapper.concat(i,e.split(","))}),e[normalize(n)]=i}),e},Headers.prototype.getAll=function(e){var t=this._headersMap.get(normalize(e));return r.isListLikeIterable(t)?t:[]},Headers.prototype.entries=function(){throw new i.BaseException('"entries" method is not implemented on Headers class')},Headers}();t.Headers=s},function(e,t){"use strict";var n=function(){function ConnectionBackend(){}return ConnectionBackend}();t.ConnectionBackend=n;var r=function(){function Connection(){}return Connection}();t.Connection=r;var i=function(){function XSRFStrategy(){}return XSRFStrategy}();t.XSRFStrategy=i},function(e,t,n){"use strict";var r=n(0);t.RenderDebugInfo=r.__core_private__.RenderDebugInfo,t.wtfInit=r.__core_private__.wtfInit,t.ReflectionCapabilities=r.__core_private__.ReflectionCapabilities,t.VIEW_ENCAPSULATION_VALUES=r.__core_private__.VIEW_ENCAPSULATION_VALUES,t.DebugDomRootRenderer=r.__core_private__.DebugDomRootRenderer,t.reflector=r.__core_private__.reflector,t.NoOpAnimationPlayer=r.__core_private__.NoOpAnimationPlayer,t.AnimationPlayer=r.__core_private__.AnimationPlayer,t.AnimationSequencePlayer=r.__core_private__.AnimationSequencePlayer,t.AnimationGroupPlayer=r.__core_private__.AnimationGroupPlayer,t.AnimationKeyframe=r.__core_private__.AnimationKeyframe,t.AnimationStyles=r.__core_private__.AnimationStyles,t.prepareFinalAnimationStyles=r.__core_private__.prepareFinalAnimationStyles,t.balanceAnimationKeyframes=r.__core_private__.balanceAnimationKeyframes,t.flattenStyles=r.__core_private__.flattenStyles,t.clearStyles=r.__core_private__.clearStyles,t.collectAndResolveStyles=r.__core_private__.collectAndResolveStyles},function(e,t,n){"use strict";var r=n(0);t.DOCUMENT=new r.OpaqueToken("DocumentToken")},function(e,t,n){"use strict";var r=this&&this.__extends||function(e,t){function __(){this.constructor=e}for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n]);e.prototype=null===t?Object.create(t):(__.prototype=t.prototype,new __)},i=n(0),o=n(33),s=n(16),a=n(62),l=n(55),c=function(){function ClientMessageBrokerFactory(){}return ClientMessageBrokerFactory}();t.ClientMessageBrokerFactory=c;var u=function(e){function ClientMessageBrokerFactory_(t,n){e.call(this),this._messageBus=t,this._serializer=n}return r(ClientMessageBrokerFactory_,e),ClientMessageBrokerFactory_.prototype.createMessageBroker=function(e,t){return void 0===t&&(t=!0),this._messageBus.initChannel(e,t),new d(this._messageBus,this._serializer,e)},ClientMessageBrokerFactory_.decorators=[{type:i.Injectable}],ClientMessageBrokerFactory_.ctorParameters=[{type:a.MessageBus},{type:l.Serializer}],ClientMessageBrokerFactory_}(c);t.ClientMessageBrokerFactory_=u;var p=function(){function ClientMessageBroker(){}return ClientMessageBroker}();t.ClientMessageBroker=p;var d=function(e){function ClientMessageBroker_(t,n,r){var i=this;e.call(this),this.channel=r,this._pending=new Map,this._sink=t.to(r),this._serializer=n;var o=t.from(r);o.subscribe({next:function(e){return i._handleMessage(e)}})}return r(ClientMessageBroker_,e),ClientMessageBroker_.prototype._generateMessageId=function(e){for(var t=s.stringify(s.DateWrapper.toMillis(s.DateWrapper.now())),n=0,r=e+t+s.stringify(n);s.isPresent(this._pending[r]);)r=""+e+t+n,n++;return r},ClientMessageBroker_.prototype.runOnService=function(e,t){var n=this,r=[];s.isPresent(e.args)&&e.args.forEach(function(e){null!=e.type?r.push(n._serializer.serialize(e.value,e.type)):r.push(e.value)});var i,o=null;if(null!=t){var a;i=new Promise(function(e,t){a={resolve:e,reject:t}}),o=this._generateMessageId(e.method),this._pending.set(o,a),i.catch(function(e){s.print(e),a.reject(e)}),i=i.then(function(e){return null==n._serializer?e:n._serializer.deserialize(e,t)})}else i=null;var l={method:e.method,args:r};return null!=o&&(l.id=o),this._sink.emit(l),i},ClientMessageBroker_.prototype._handleMessage=function(e){var t=new h(e);if(s.StringWrapper.equals(t.type,"result")||s.StringWrapper.equals(t.type,"error")){var n=t.id;this._pending.has(n)&&(s.StringWrapper.equals(t.type,"result")?this._pending.get(n).resolve(t.value):this._pending.get(n).reject(t.value),this._pending.delete(n))}},ClientMessageBroker_}(p);t.ClientMessageBroker_=d;var h=function(){function MessageData(e){this.type=o.StringMapWrapper.get(e,"type"),this.id=this._getValueIfPresent(e,"id"),this.value=this._getValueIfPresent(e,"value")}return MessageData.prototype._getValueIfPresent=function(e,t){return o.StringMapWrapper.contains(e,t)?o.StringMapWrapper.get(e,t):null},MessageData}(),f=function(){function FnArg(e,t){this.value=e,this.type=t}return FnArg}();t.FnArg=f;var m=function(){function UiArguments(e,t){this.method=e,this.args=t}return UiArguments}();t.UiArguments=m},function(e,t,n){"use strict";var r=n(0),i=function(){function RenderStore(){this._nextIndex=0,this._lookupById=new Map,this._lookupByObject=new Map}return RenderStore.prototype.allocateId=function(){return this._nextIndex++},RenderStore.prototype.store=function(e,t){this._lookupById.set(t,e),this._lookupByObject.set(e,t)},RenderStore.prototype.remove=function(e){var t=this._lookupByObject.get(e);this._lookupByObject.delete(e),this._lookupById.delete(t)},RenderStore.prototype.deserialize=function(e){return null==e?null:this._lookupById.has(e)?this._lookupById.get(e):null},RenderStore.prototype.serialize=function(e){return null==e?null:this._lookupByObject.get(e)},RenderStore.decorators=[{type:r.Injectable}],RenderStore.ctorParameters=[],RenderStore}();t.RenderStore=i},function(e,t,n){"use strict";var r=this&&this.__extends||function(e,t){function __(){this.constructor=e}for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n]);e.prototype=null===t?Object.create(t):(__.prototype=t.prototype,new __)},i=n(0),o=n(33),s=n(16),a=n(62),l=n(55),c=function(){function ServiceMessageBrokerFactory(){}return ServiceMessageBrokerFactory}();t.ServiceMessageBrokerFactory=c;var u=function(e){function ServiceMessageBrokerFactory_(t,n){e.call(this),this._messageBus=t,this._serializer=n}return r(ServiceMessageBrokerFactory_,e),ServiceMessageBrokerFactory_.prototype.createMessageBroker=function(e,t){return void 0===t&&(t=!0),this._messageBus.initChannel(e,t),new d(this._messageBus,this._serializer,e)},ServiceMessageBrokerFactory_.decorators=[{type:i.Injectable}],ServiceMessageBrokerFactory_.ctorParameters=[{type:a.MessageBus},{type:l.Serializer}],ServiceMessageBrokerFactory_}(c);t.ServiceMessageBrokerFactory_=u;var p=function(){function ServiceMessageBroker(){}return ServiceMessageBroker}();t.ServiceMessageBroker=p;var d=function(e){function ServiceMessageBroker_(t,n,r){var i=this;e.call(this),this._serializer=n,this.channel=r,this._methods=new o.Map,this._sink=t.to(r);var s=t.from(r);s.subscribe({next:function(e){return i._handleMessage(e)}})}return r(ServiceMessageBroker_,e),ServiceMessageBroker_.prototype.registerMethod=function(e,t,n,r){var i=this;this._methods.set(e,function(e){for(var a=e.args,l=null===t?0:t.length,c=o.ListWrapper.createFixedSize(l),u=0;u0?n[n.length-1]._routeConfig._loadedConfig:null}function nodeChildrenAsMap(e){return e?e.children.reduce(function(e,t){return e[t.value.outlet]=t,e},{}):{}}function getOutlet(e,t){var n=e._outlets[t.outlet];if(!n){var r=t.component.name;throw t.outlet===g.PRIMARY_OUTLET?new Error("Cannot find primary outlet to load '"+r+"'"):new Error("Cannot find the outlet "+t.outlet+" to load '"+r+"'")}return n}n(140),n(499),n(305),n(500),n(493);var r=n(0),i=n(20),o=n(309),s=n(141),a=n(623),l=n(624),c=n(625),u=n(626),p=n(627),d=n(628),h=n(187),f=n(129),m=n(91),g=n(63),y=n(73),v=n(74),b=function(){function NavigationStart(e,t){this.id=e,this.url=t}return NavigationStart.prototype.toString=function(){return"NavigationStart(id: "+this.id+", url: '"+this.url+"')"},NavigationStart}();t.NavigationStart=b;var _=function(){function NavigationEnd(e,t,n){this.id=e,this.url=t,this.urlAfterRedirects=n}return NavigationEnd.prototype.toString=function(){return"NavigationEnd(id: "+this.id+", url: '"+this.url+"', urlAfterRedirects: '"+this.urlAfterRedirects+"')"},NavigationEnd}();t.NavigationEnd=_;var w=function(){function NavigationCancel(e,t){this.id=e,this.url=t}return NavigationCancel.prototype.toString=function(){return"NavigationCancel(id: "+this.id+", url: '"+this.url+"')"},NavigationCancel}();t.NavigationCancel=w;var S=function(){function NavigationError(e,t,n){this.id=e,this.url=t,this.error=n}return NavigationError.prototype.toString=function(){return"NavigationError(id: "+this.id+", url: '"+this.url+"', error: "+this.error+")"},NavigationError}();t.NavigationError=S;var C=function(){function RoutesRecognized(e,t,n,r){this.id=e,this.url=t,this.urlAfterRedirects=n,this.state=r}return RoutesRecognized.prototype.toString=function(){return"RoutesRecognized(id: "+this.id+", url: '"+this.url+"', urlAfterRedirects: '"+this.urlAfterRedirects+"', state: "+this.state+")"},RoutesRecognized}();t.RoutesRecognized=C;var E=function(){function Router(e,t,n,r,o,s,a,l){this.rootComponentType=e,this.resolver=t,this.urlSerializer=n,this.outletMap=r,this.location=o,this.injector=s,this.navigationId=0,this.navigated=!1,this.resetConfig(l),this.routerEvents=new i.Subject,this.currentUrlTree=y.createEmptyUrlTree(),this.configLoader=new h.RouterConfigLoader(a),this.currentRouterState=m.createEmptyState(this.currentUrlTree,this.rootComponentType)}return Router.prototype.initialNavigation=function(){this.setUpLocationChangeListener(),this.navigateByUrl(this.location.path(!0))},Object.defineProperty(Router.prototype,"routerState",{get:function(){return this.currentRouterState},enumerable:!0,configurable:!0}),Object.defineProperty(Router.prototype,"url",{get:function(){return this.serializeUrl(this.currentUrlTree)},enumerable:!0,configurable:!0}),Object.defineProperty(Router.prototype,"events",{get:function(){return this.routerEvents},enumerable:!0,configurable:!0}),Router.prototype.resetConfig=function(e){l.validateConfig(e),this.config=e},Router.prototype.ngOnDestroy=function(){this.dispose()},Router.prototype.dispose=function(){this.locationSubscription.unsubscribe()},Router.prototype.createUrlTree=function(e,t){var n=void 0===t?{}:t,r=n.relativeTo,i=n.queryParams,o=n.fragment,s=n.preserveQueryParams,a=n.preserveFragment,l=r?r:this.routerState.root,c=s?this.currentUrlTree.queryParams:i,p=a?this.currentUrlTree.fragment:o;return u.createUrlTree(l,this.currentUrlTree,e,c,p)},Router.prototype.navigateByUrl=function(e,t){if(void 0===t&&(t={skipLocationChange:!1}),e instanceof y.UrlTree)return this.scheduleNavigation(e,t);var n=this.urlSerializer.parse(e);return this.scheduleNavigation(n,t)},Router.prototype.navigate=function(e,t){return void 0===t&&(t={skipLocationChange:!1}),this.scheduleNavigation(this.createUrlTree(e,t),t)},Router.prototype.serializeUrl=function(e){return this.urlSerializer.serialize(e)},Router.prototype.parseUrl=function(e){return this.urlSerializer.parse(e)},Router.prototype.isActive=function(e,t){if(e instanceof y.UrlTree)return y.containsTree(this.currentUrlTree,e,t);var n=this.urlSerializer.parse(e);return y.containsTree(this.currentUrlTree,n,t)},Router.prototype.scheduleNavigation=function(e,t){var n=this,r=++this.navigationId;return this.routerEvents.next(new b(r,this.serializeUrl(e))),Promise.resolve().then(function(i){return n.runNavigate(e,t.skipLocationChange,r)})},Router.prototype.setUpLocationChangeListener=function(){var e=this;this.locationSubscription=this.location.subscribe(Zone.current.wrap(function(t){var n=e.urlSerializer.parse(t.url);return e.currentUrlTree.toString()!==n.toString()?e.scheduleNavigation(n,t.pop):null}))},Router.prototype.runNavigate=function(e,t,n){var r=this;return n!==this.navigationId?(this.location.go(this.urlSerializer.serialize(this.currentUrlTree)),this.routerEvents.next(new w(n,this.serializeUrl(e))),Promise.resolve(!1)):new Promise(function(i,o){var l,u,h,f,m=r.currentRouterState,g=r.currentUrlTree;a.applyRedirects(r.injector,r.configLoader,e,r.config).mergeMap(function(e){return f=e,p.recognize(r.rootComponentType,r.config,f,r.serializeUrl(f))}).mergeMap(function(t){return r.routerEvents.next(new C(n,r.serializeUrl(e),r.serializeUrl(f),t)),d.resolve(r.resolver,t)}).map(function(e){return c.createRouterState(e,r.currentRouterState)}).map(function(e){l=e,h=new P(l.snapshot,r.currentRouterState.snapshot,r.injector),h.traverse(r.outletMap)}).mergeMap(function(e){return h.checkGuards()}).mergeMap(function(e){return e?h.resolveData().map(function(){return e}):s.of(e)}).forEach(function(i){if(!i||n!==r.navigationId)return r.routerEvents.next(new w(n,r.serializeUrl(e))),void(u=!1);if(r.currentUrlTree=f,r.currentRouterState=l,new x(l,m).activate(r.outletMap),!t){var o=r.urlSerializer.serialize(f);r.location.isCurrentPathEqualTo(o)?r.location.replaceState(o):r.location.go(o)}u=!0}).then(function(){r.navigated=!0,r.routerEvents.next(new _(n,r.serializeUrl(e),r.serializeUrl(f))),i(u)},function(t){r.currentRouterState=m,r.currentUrlTree=g,r.routerEvents.next(new S(n,r.serializeUrl(e),t)),o(t)})})},Router}();t.Router=E;var R=function(){function CanActivate(e){this.path=e}return Object.defineProperty(CanActivate.prototype,"route",{get:function(){return this.path[this.path.length-1]},enumerable:!0,configurable:!0}),CanActivate}(),T=function(){function CanDeactivate(e,t){this.component=e,this.route=t}return CanDeactivate}(),P=function(){function PreActivation(e,t,n){this.future=e,this.curr=t,this.injector=n,this.checks=[]}return PreActivation.prototype.traverse=function(e){var t=this.future._root,n=this.curr?this.curr._root:null;this.traverseChildRoutes(t,n,e,[t.value])},PreActivation.prototype.checkGuards=function(){var e=this;return 0===this.checks.length?s.of(!0):o.from(this.checks).map(function(t){if(t instanceof R)return v.andObservables(o.from([e.runCanActivate(t.route),e.runCanActivateChild(t.path)]));if(t instanceof T){var n=t;return e.runCanDeactivate(n.component,n.route)}throw new Error("Cannot be reached")}).mergeAll().every(function(e){return e===!0})},PreActivation.prototype.resolveData=function(){var e=this;return 0===this.checks.length?s.of(null):o.from(this.checks).mergeMap(function(t){return t instanceof R?e.runResolve(t.route):s.of(null)}).reduce(function(e,t){return e})},PreActivation.prototype.traverseChildRoutes=function(e,t,n,r){var i=this,o=nodeChildrenAsMap(t);e.children.forEach(function(e){i.traverseRoutes(e,o[e.value.outlet],n,r.concat([e.value])),delete o[e.value.outlet]}),v.forEach(o,function(e,t){return i.deactivateOutletAndItChildren(e,n._outlets[t])})},PreActivation.prototype.traverseRoutes=function(e,t,n,r){var i=e.value,o=t?t.value:null,s=n?n._outlets[e.value.outlet]:null;o&&i._routeConfig===o._routeConfig?(v.shallowEqual(i.params,o.params)||this.checks.push(new T(s.component,o),new R(r)),i.component?this.traverseChildRoutes(e,t,s?s.outletMap:null,r):this.traverseChildRoutes(e,t,n,r)):(o&&(o.component?this.deactivateOutletAndItChildren(o,s):this.deactivateOutletMap(n)),this.checks.push(new R(r)),i.component?this.traverseChildRoutes(e,null,s?s.outletMap:null,r):this.traverseChildRoutes(e,null,n,r))},PreActivation.prototype.deactivateOutletAndItChildren=function(e,t){t&&t.isActivated&&(this.deactivateOutletMap(t.outletMap),this.checks.push(new T(t.component,e)))},PreActivation.prototype.deactivateOutletMap=function(e){var t=this;v.forEach(e._outlets,function(e){e.isActivated&&t.deactivateOutletAndItChildren(e.activatedRoute.snapshot,e)})},PreActivation.prototype.runCanActivate=function(e){var t=this,n=e._routeConfig?e._routeConfig.canActivate:null;if(!n||0===n.length)return s.of(!0);var r=o.from(n).map(function(n){var r=t.getToken(n,e,t.future);return r.canActivate?v.wrapIntoObservable(r.canActivate(e,t.future)):v.wrapIntoObservable(r(e,t.future))});return v.andObservables(r)},PreActivation.prototype.runCanActivateChild=function(e){var t=this,n=e[e.length-1],r=e.slice(0,e.length-1).reverse().map(function(e){return t.extractCanActivateChild(e)}).filter(function(e){return null!==e});return v.andObservables(o.from(r).map(function(e){var r=o.from(e.guards).map(function(e){var r=t.getToken(e,e.node,t.future);return r.canActivateChild?v.wrapIntoObservable(r.canActivateChild(n,t.future)):v.wrapIntoObservable(r(n,t.future))});return v.andObservables(r)}))},PreActivation.prototype.extractCanActivateChild=function(e){var t=e._routeConfig?e._routeConfig.canActivateChild:null;return t&&0!==t.length?{node:e,guards:t}:null},PreActivation.prototype.runCanDeactivate=function(e,t){var n=this,r=t&&t._routeConfig?t._routeConfig.canDeactivate:null;return r&&0!==r.length?o.from(r).map(function(r){var i=n.getToken(r,t,n.curr);return i.canDeactivate?v.wrapIntoObservable(i.canDeactivate(e,t,n.curr)):v.wrapIntoObservable(i(e,t,n.curr))}).mergeAll().every(function(e){return e===!0}):s.of(!0)},PreActivation.prototype.runResolve=function(e){var t=e._resolve;return this.resolveNode(t.current,e).map(function(n){return t.resolvedData=n,e.data=v.merge(e.data,t.flattenedResolvedData),null})},PreActivation.prototype.resolveNode=function(e,t){var n=this;return v.waitForMap(e,function(e,r){var i=n.getToken(r,t,n.future);return i.resolve?v.wrapIntoObservable(i.resolve(t,n.future)):v.wrapIntoObservable(i(t,n.future))})},PreActivation.prototype.getToken=function(e,t,n){var r=closestLoadedConfig(n,t),i=r?r.injector:this.injector;return i.get(e)},PreActivation}(),x=function(){function ActivateRoutes(e,t){this.futureState=e,this.currState=t}return ActivateRoutes.prototype.activate=function(e){var t=this.futureState._root,n=this.currState?this.currState._root:null;m.advanceActivatedRoute(this.futureState.root),this.activateChildRoutes(t,n,e)},ActivateRoutes.prototype.activateChildRoutes=function(e,t,n){var r=this,i=nodeChildrenAsMap(t);e.children.forEach(function(e){r.activateRoutes(e,i[e.value.outlet],n),delete i[e.value.outlet]}),v.forEach(i,function(e,t){return r.deactivateOutletAndItChildren(n._outlets[t])})},ActivateRoutes.prototype.activateRoutes=function(e,t,n){ var r=e.value,i=t?t.value:null;if(r===i)if(m.advanceActivatedRoute(r),r.component){var o=getOutlet(n,e.value);this.activateChildRoutes(e,t,o.outletMap)}else this.activateChildRoutes(e,t,n);else{if(i)if(i.component){var o=getOutlet(n,e.value);this.deactivateOutletAndItChildren(o)}else this.deactivateOutletMap(n);if(r.component){m.advanceActivatedRoute(r);var o=getOutlet(n,e.value),s=new f.RouterOutletMap;this.placeComponentIntoOutlet(s,r,o),this.activateChildRoutes(e,null,s)}else m.advanceActivatedRoute(r),this.activateChildRoutes(e,null,n)}},ActivateRoutes.prototype.placeComponentIntoOutlet=function(e,t,n){var i=[{provide:m.ActivatedRoute,useValue:t},{provide:f.RouterOutletMap,useValue:e}],o=closestLoadedConfig(this.futureState.snapshot,t.snapshot),s=null,a=null;o&&(s=o.factoryResolver,a=o.injector,i.push({provide:r.ComponentFactoryResolver,useValue:s})),n.activate(t,s,a,r.ReflectiveInjector.resolve(i),e)},ActivateRoutes.prototype.deactivateOutletAndItChildren=function(e){e&&e.isActivated&&(this.deactivateOutletMap(e.outletMap),e.deactivate())},ActivateRoutes.prototype.deactivateOutletMap=function(e){var t=this;v.forEach(e._outlets,function(e){return t.deactivateOutletAndItChildren(e)})},ActivateRoutes}()},function(e,t){"use strict";var n=function(){function RouterOutletMap(){this._outlets={}}return RouterOutletMap.prototype.registerOutlet=function(e,t){this._outlets[e]=t},RouterOutletMap.prototype.removeOutlet=function(e){this._outlets[e]=void 0},RouterOutletMap}();t.RouterOutletMap=n},function(e,t,n){"use strict";var r=n(43),i=(n.n(r),n(0));n.n(i);n.d(t,"a",function(){return a});var o=this&&this.__decorate||function(e,t,n,r){var i,o=arguments.length,s=o<3?t:null===r?r=Object.getOwnPropertyDescriptor(t,n):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(e,t,n,r);else for(var a=e.length-1;a>=0;a--)(i=e[a])&&(s=(o<3?i(s):o>3?i(t,n,s):i(t,n))||s);return o>3&&s&&Object.defineProperty(t,n,s),s},s=this&&this.__metadata||function(e,t){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(e,t)},a=function(){function FeaturesService(e){var t=this;this.http=e,this.activeReparents=!1,this.showStatus=!1,this.showTopologyCRUD=!1,this.showWorkflows=!1,this.workflows=[],this.featuresUrl="../api/features",this.getFeatures().subscribe(function(e){t.activeReparents=e.activeReparents,t.showStatus=e.showStatus,t.showTopologyCRUD=e.showTopologyCRUD,t.showWorkflows=e.showWorkflows,t.workflows=e.workflows})}return FeaturesService.prototype.getFeatures=function(){return this.http.get(this.featuresUrl).map(function(e){return e.json()})},FeaturesService=o([n.i(i.Injectable)(),s("design:paramtypes",["function"==typeof(e="undefined"!=typeof r.Http&&r.Http)&&e||Object])],FeaturesService);var e}()},function(e,t,n){"use strict";var r=n(43),i=(n.n(r),n(0)),o=(n.n(i),n(484)),s=(n.n(o),n(283)),a=n(644),l=n(284);n.d(t,"a",function(){return p});var c=this&&this.__decorate||function(e,t,n,r){var i,o=arguments.length,s=o<3?t:null===r?r=Object.getOwnPropertyDescriptor(t,n):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(e,t,n,r);else for(var a=e.length-1;a>=0;a--)(i=e[a])&&(s=(o<3?i(s):o>3?i(t,n,s):i(t,n))||s);return o>3&&s&&Object.defineProperty(t,n,s),s},u=this&&this.__metadata||function(e,t){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(e,t)},p=function(){function KeyspaceService(e,t){this.http=e,this.shardService=t,this.keyspacesUrl="../api/keyspaces/",this.srvKeyspaceUrl="../api/srv_keyspace/local/"}return KeyspaceService.prototype.getShards=function(e){return this.shardService.getShards(e)},KeyspaceService.prototype.getKeyspaceNames=function(){return this.http.get(this.keyspacesUrl).map(function(e){return e.json()})},KeyspaceService.prototype.getSrvKeyspaces=function(){return this.http.get(this.srvKeyspaceUrl).map(function(e){return e.json()})},KeyspaceService.prototype.SrvKeyspaceAndNamesObservable=function(){var e=this.getKeyspaceNames(),t=this.getSrvKeyspaces();return e.combineLatest(t)},KeyspaceService.prototype.getKeyspaceShardingData=function(e){return this.http.get(this.keyspacesUrl+e).map(function(e){return e.json()})},KeyspaceService.prototype.getShardsAndShardingData=function(e){var t=this.getShards(e),n=this.getKeyspaceShardingData(e);return t.combineLatest(n)},KeyspaceService.prototype.buildKeyspace=function(e,t){return this.getShardsAndShardingData(e).map(function(n){var r=n[0],i=n[1],o=new a.a(e);return t.forEach(function(e){return o.addServingShard(e)}),r.forEach(function(e){o.contains(e)||o.addNonservingShard(e)}),o.shardingColumnName=i.sharding_column_name||"",o.shardingColumnType=i.sharding_column_type||"",o})},KeyspaceService.prototype.getServingShards=function(e,t){if(t&&t[e]){var n=t[e].partitions;if(void 0===n)return[];for(var r=0;r=0;a--)(i=e[a])&&(s=(o<3?i(s):o>3?i(t,n,s):i(t,n))||s);return o>3&&s&&Object.defineProperty(t,n,s),s},i=this&&this.__metadata||function(e,t){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(e,t)},o=n(0),s=n(9),a=n(3),l=function(){function Button(e,t){this.el=e,this.domHandler=t,this.iconPos="left"}return Button.prototype.ngAfterViewInit=function(){if(this.domHandler.addMultipleClasses(this.el.nativeElement,this.getStyleClass()),this.icon){var e=document.createElement("span"),t="right"==this.iconPos?"ui-button-icon-right":"ui-button-icon-left";e.className=t+" ui-c fa fa-fw "+this.icon,this.el.nativeElement.appendChild(e)}var n=document.createElement("span");n.className="ui-button-text ui-c",n.appendChild(document.createTextNode(this.label||"ui-button")),this.el.nativeElement.appendChild(n),this.initialized=!0},Button.prototype.onMouseenter=function(e){this.hover=!0},Button.prototype.onMouseleave=function(e){this.hover=!1,this.active=!1},Button.prototype.onMouseDown=function(e){this.active=!0},Button.prototype.onMouseUp=function(e){this.active=!1},Button.prototype.onFocus=function(e){this.focus=!0},Button.prototype.onBlur=function(e){this.focus=!1},Button.prototype.isDisabled=function(){return this.el.nativeElement.disabled},Button.prototype.getStyleClass=function(){var e="ui-button ui-widget ui-state-default ui-corner-all";return e+=this.icon?null!=this.label&&void 0!=this.label?"left"==this.iconPos?" ui-button-text-icon-left":" ui-button-text-icon-right":" ui-button-icon-only":" ui-button-text-only"},Object.defineProperty(Button.prototype,"label",{get:function(){return this._label},set:function(e){this._label=e,this.initialized&&(this.domHandler.findSingle(this.el.nativeElement,".ui-button-text").textContent=this._label)},enumerable:!0,configurable:!0}),Button.prototype.ngOnDestroy=function(){for(;this.el.nativeElement.hasChildNodes();)this.el.nativeElement.removeChild(this.el.nativeElement.lastChild);this.initialized=!1},r([o.Input(),i("design:type",String)],Button.prototype,"icon",void 0),r([o.Input(),i("design:type",String)],Button.prototype,"iconPos",void 0),r([o.HostListener("mouseenter",["$event"]),i("design:type",Function),i("design:paramtypes",[Object]),i("design:returntype",void 0)],Button.prototype,"onMouseenter",null),r([o.HostListener("mouseleave",["$event"]),i("design:type",Function),i("design:paramtypes",[Object]),i("design:returntype",void 0)],Button.prototype,"onMouseleave",null),r([o.HostListener("mousedown",["$event"]),i("design:type",Function),i("design:paramtypes",[Object]),i("design:returntype",void 0)],Button.prototype,"onMouseDown",null),r([o.HostListener("mouseup",["$event"]),i("design:type",Function),i("design:paramtypes",[Object]),i("design:returntype",void 0)],Button.prototype,"onMouseUp",null),r([o.HostListener("focus",["$event"]),i("design:type",Function),i("design:paramtypes",[Object]),i("design:returntype",void 0)],Button.prototype,"onFocus",null),r([o.HostListener("blur",["$event"]),i("design:type",Function),i("design:paramtypes",[Object]),i("design:returntype",void 0)],Button.prototype,"onBlur",null),r([o.Input(),i("design:type",String)],Button.prototype,"label",null),Button=r([o.Directive({selector:"[pButton]",host:{"[class.ui-state-hover]":"hover&&!isDisabled()","[class.ui-state-focus]":"focus","[class.ui-state-active]":"active","[class.ui-state-disabled]":"isDisabled()"},providers:[s.DomHandler]}),i("design:paramtypes",[o.ElementRef,s.DomHandler])],Button)}();t.Button=l;var c=function(){function ButtonModule(){}return ButtonModule=r([o.NgModule({imports:[a.CommonModule],exports:[l],declarations:[l]}),i("design:paramtypes",[])],ButtonModule)}();t.ButtonModule=c},function(e,t,n){"use strict";var r=n(1),i=n(505);r.Observable.prototype.map=i.map},function(e,t,n){"use strict";var r=n(79);t.of=r.ArrayObservable.of},function(e,t,n){"use strict";var r=n(51),i=r.root.Symbol;if("function"==typeof i)i.iterator?t.$$iterator=i.iterator:"function"==typeof i.for&&(t.$$iterator=i.for("iterator"));else if(r.root.Set&&"function"==typeof(new r.root.Set)["@@iterator"])t.$$iterator="@@iterator";else if(r.root.Map)for(var o=Object.getOwnPropertyNames(r.root.Map.prototype),s=0;s=this.length?i.$EOF:o.StringWrapper.charCodeAt(this.input,this.index)},_Scanner.prototype.scanToken=function(){for(var e=this.input,t=this.length,n=this.peek,r=this.index;n<=i.$SPACE;){if(++r>=t){n=i.$EOF;break}n=o.StringWrapper.charCodeAt(e,r)}if(this.peek=n,this.index=r,r>=t)return null;if(isIdentifierStart(n))return this.scanIdentifier();if(i.isDigit(n))return this.scanNumber(r);var s=r;switch(n){case i.$PERIOD:return this.advance(),i.isDigit(this.peek)?this.scanNumber(s):newCharacterToken(s,i.$PERIOD);case i.$LPAREN:case i.$RPAREN:case i.$LBRACE:case i.$RBRACE:case i.$LBRACKET:case i.$RBRACKET:case i.$COMMA:case i.$COLON:case i.$SEMICOLON:return this.scanCharacter(s,n);case i.$SQ:case i.$DQ:return this.scanString();case i.$HASH:case i.$PLUS:case i.$MINUS:case i.$STAR:case i.$SLASH:case i.$PERCENT:case i.$CARET:return this.scanOperator(s,o.StringWrapper.fromCharCode(n));case i.$QUESTION:return this.scanComplexOperator(s,"?",i.$PERIOD,".");case i.$LT:case i.$GT:return this.scanComplexOperator(s,o.StringWrapper.fromCharCode(n),i.$EQ,"=");case i.$BANG:case i.$EQ:return this.scanComplexOperator(s,o.StringWrapper.fromCharCode(n),i.$EQ,"=",i.$EQ,"=");case i.$AMPERSAND:return this.scanComplexOperator(s,"&",i.$AMPERSAND,"&");case i.$BAR:return this.scanComplexOperator(s,"|",i.$BAR,"|");case i.$NBSP:for(;i.isWhitespace(this.peek);)this.advance();return this.scanToken()}return this.advance(),this.error("Unexpected character ["+o.StringWrapper.fromCharCode(n)+"]",0)},_Scanner.prototype.scanCharacter=function(e,t){return this.advance(),newCharacterToken(e,t)},_Scanner.prototype.scanOperator=function(e,t){return this.advance(),newOperatorToken(e,t)},_Scanner.prototype.scanComplexOperator=function(e,t,n,r,i,s){this.advance();var a=t;return this.peek==n&&(this.advance(),a+=r),o.isPresent(i)&&this.peek==i&&(this.advance(),a+=s),newOperatorToken(e,a)},_Scanner.prototype.scanIdentifier=function(){var e=this.index;for(this.advance();isIdentifierPart(this.peek);)this.advance();var t=this.input.substring(e,this.index);return a.indexOf(t)>-1?newKeywordToken(e,t):newIdentifierToken(e,t)},_Scanner.prototype.scanNumber=function(e){var t=this.index===e;for(this.advance();;){if(i.isDigit(this.peek));else if(this.peek==i.$PERIOD)t=!1;else{if(!isExponentStart(this.peek))break;if(this.advance(),isExponentSign(this.peek)&&this.advance(),!i.isDigit(this.peek))return this.error("Invalid exponent",-1);t=!1}this.advance()}var n=this.input.substring(e,this.index),r=t?o.NumberWrapper.parseIntAutoRadix(n):o.NumberWrapper.parseFloat(n);return newNumberToken(e,r)},_Scanner.prototype.scanString=function(){var e=this.index,t=this.peek;this.advance();for(var n,r=this.index,s=this.input;this.peek!=t;)if(this.peek==i.$BACKSLASH){null==n&&(n=new o.StringJoiner),n.add(s.substring(r,this.index)),this.advance();var a;if(this.peek==i.$u){var l=s.substring(this.index+1,this.index+5);try{a=o.NumberWrapper.parseInt(l,16)}catch(c){return this.error("Invalid unicode escape [\\u"+l+"]",0)}for(var u=0;u<5;u++)this.advance()}else a=unescape(this.peek),this.advance();n.add(o.StringWrapper.fromCharCode(a)),r=this.index}else{if(this.peek==i.$EOF)return this.error("Unterminated quote",0);this.advance()}var p=s.substring(r,this.index);this.advance();var d=p;return null!=n&&(n.add(p),d=n.toString()),newStringToken(e,d)},_Scanner.prototype.error=function(e,t){var n=this.index+t;return newErrorToken(n,"Lexer Error: "+e+" at column "+n+" in expression ["+this.input+"]")},_Scanner}();t.isIdentifier=isIdentifier,t.isQuote=isQuote},function(e,t,n){"use strict";function _createInterpolateRegExp(e){var t=o.escapeRegExp(e.start)+"([\\s\\S]*?)"+o.escapeRegExp(e.end);return new RegExp(t,"g")}var r=n(0),i=n(233),o=n(5),s=n(68),a=n(236),l=n(151),c=function(){function SplitInterpolation(e,t){this.strings=e,this.expressions=t}return SplitInterpolation}();t.SplitInterpolation=c;var u=function(){function TemplateBindingParseResult(e,t,n){this.templateBindings=e,this.warnings=t,this.errors=n}return TemplateBindingParseResult}();t.TemplateBindingParseResult=u;var p=function(){function Parser(e){this._lexer=e,this.errors=[]}return Parser.prototype.parseAction=function(e,t,n){void 0===n&&(n=s.DEFAULT_INTERPOLATION_CONFIG),this._checkNoInterpolation(e,t,n);var r=this._lexer.tokenize(this._stripComments(e)),i=new d(e,t,r,(!0),this.errors).parseChain();return new a.ASTWithSource(i,e,t,this.errors)},Parser.prototype.parseBinding=function(e,t,n){void 0===n&&(n=s.DEFAULT_INTERPOLATION_CONFIG);var r=this._parseBindingAst(e,t,n);return new a.ASTWithSource(r,e,t,this.errors)},Parser.prototype.parseSimpleBinding=function(e,t,n){void 0===n&&(n=s.DEFAULT_INTERPOLATION_CONFIG);var r=this._parseBindingAst(e,t,n);return h.check(r)||this._reportError("Host binding expression can only contain field access and constants",e,t),new a.ASTWithSource(r,e,t,this.errors)},Parser.prototype._reportError=function(e,t,n,r){this.errors.push(new a.ParserError(e,t,n,r))},Parser.prototype._parseBindingAst=function(e,t,n){var r=this._parseQuote(e,t);if(o.isPresent(r))return r;this._checkNoInterpolation(e,t,n);var i=this._lexer.tokenize(this._stripComments(e));return new d(e,t,i,(!1),this.errors).parseChain()},Parser.prototype._parseQuote=function(e,t){if(o.isBlank(e))return null;var n=e.indexOf(":");if(n==-1)return null;var r=e.substring(0,n).trim();if(!l.isIdentifier(r))return null;var i=e.substring(n+1);return new a.Quote(new a.ParseSpan(0,e.length),r,i,t)},Parser.prototype.parseTemplateBindings=function(e,t){var n=this._lexer.tokenize(e);return new d(e,t,n,(!1),this.errors).parseTemplateBindings()},Parser.prototype.parseInterpolation=function(e,t,n){void 0===n&&(n=s.DEFAULT_INTERPOLATION_CONFIG);var r=this.splitInterpolation(e,t,n);if(null==r)return null;for(var i=[],l=0;l0?l.push(p):this._reportError("Blank expressions are not allowed in interpolated strings",e,"at column "+this._findInterpolationErrorColumn(i,u,n)+" in",t)}return new c(a,l)},Parser.prototype.wrapLiteralPrimitive=function(e,t){return new a.ASTWithSource(new a.LiteralPrimitive(new a.ParseSpan(0,o.isBlank(e)?0:e.length),e),e,t,this.errors)},Parser.prototype._stripComments=function(e){var t=this._commentStart(e);return o.isPresent(t)?e.substring(0,t).trim():e},Parser.prototype._commentStart=function(e){for(var t=null,n=0;n1&&this._reportError("Got interpolation ("+n.start+n.end+") where expression was expected",e,"at column "+this._findInterpolationErrorColumn(i,1,n)+" in",t)},Parser.prototype._findInterpolationErrorColumn=function(e,t,n){for(var r="",i=0;i":case"<=":case">=":this.advance();var n=this.parseAdditive();e=new a.Binary(this.span(e.span.start),t,e,n);continue}break}return e},_ParseAST.prototype.parseAdditive=function(){for(var e=this.parseMultiplicative();this.next.type==l.TokenType.Operator;){var t=this.next.strValue;switch(t){case"+":case"-":this.advance();var n=this.parseMultiplicative();e=new a.Binary(this.span(e.span.start),t,e,n);continue}break}return e},_ParseAST.prototype.parseMultiplicative=function(){for(var e=this.parsePrefix();this.next.type==l.TokenType.Operator;){var t=this.next.strValue;switch(t){case"*":case"%":case"/":this.advance();var n=this.parsePrefix();e=new a.Binary(this.span(e.span.start),t,e,n);continue}break}return e},_ParseAST.prototype.parsePrefix=function(){if(this.next.type==l.TokenType.Operator){var e=this.inputIndex,t=this.next.strValue,n=void 0;switch(t){case"+":return this.advance(),this.parsePrefix();case"-":return this.advance(),n=this.parsePrefix(),new a.Binary(this.span(e),t,new a.LiteralPrimitive(new a.ParseSpan(e,e),0),n);case"!":return this.advance(),n=this.parsePrefix(),new a.PrefixNot(this.span(e),n)}}return this.parseCallChain()},_ParseAST.prototype.parseCallChain=function(){for(var e=this.parsePrimary();;)if(this.optionalCharacter(i.$PERIOD))e=this.parseAccessMemberOrMethodCall(e,!1);else if(this.optionalOperator("?."))e=this.parseAccessMemberOrMethodCall(e,!0);else if(this.optionalCharacter(i.$LBRACKET)){this.rbracketsExpected++;var t=this.parsePipe();if(this.rbracketsExpected--,this.expectCharacter(i.$RBRACKET),this.optionalOperator("=")){var n=this.parseConditional();e=new a.KeyedWrite(this.span(e.span.start),e,t,n)}else e=new a.KeyedRead(this.span(e.span.start),e,t)}else{if(!this.optionalCharacter(i.$LPAREN))return e;this.rparensExpected++;var r=this.parseCallArguments();this.rparensExpected--,this.expectCharacter(i.$RPAREN),e=new a.FunctionCall(this.span(e.span.start),e,r)}},_ParseAST.prototype.parsePrimary=function(){var e=this.inputIndex;if(this.optionalCharacter(i.$LPAREN)){this.rparensExpected++;var t=this.parsePipe();return this.rparensExpected--,this.expectCharacter(i.$RPAREN),t}if(this.next.isKeywordNull())return this.advance(),new a.LiteralPrimitive(this.span(e),null);if(this.next.isKeywordUndefined())return this.advance(),new a.LiteralPrimitive(this.span(e),(void 0));if(this.next.isKeywordTrue())return this.advance(),new a.LiteralPrimitive(this.span(e),(!0));if(this.next.isKeywordFalse())return this.advance(),new a.LiteralPrimitive(this.span(e),(!1));if(this.next.isKeywordThis())return this.advance(),new a.ImplicitReceiver(this.span(e));if(this.optionalCharacter(i.$LBRACKET)){this.rbracketsExpected++;var n=this.parseExpressionList(i.$RBRACKET);return this.rbracketsExpected--,this.expectCharacter(i.$RBRACKET),new a.LiteralArray(this.span(e),n)}if(this.next.isCharacter(i.$LBRACE))return this.parseLiteralMap();if(this.next.isIdentifier())return this.parseAccessMemberOrMethodCall(new a.ImplicitReceiver(this.span(e)),!1);if(this.next.isNumber()){var r=this.next.toNumber();return this.advance(),new a.LiteralPrimitive(this.span(e),r)}if(this.next.isString()){var o=this.next.toString();return this.advance(),new a.LiteralPrimitive(this.span(e),o)}return this.index>=this.tokens.length?(this.error("Unexpected end of expression: "+this.input),new a.EmptyExpr(this.span(e))):(this.error("Unexpected token "+this.next),new a.EmptyExpr(this.span(e)))},_ParseAST.prototype.parseExpressionList=function(e){var t=[];if(!this.next.isCharacter(e))do t.push(this.parsePipe());while(this.optionalCharacter(i.$COMMA));return t},_ParseAST.prototype.parseLiteralMap=function(){var e=[],t=[],n=this.inputIndex;if(this.expectCharacter(i.$LBRACE),!this.optionalCharacter(i.$RBRACE)){this.rbracesExpected++;do{var r=this.expectIdentifierOrKeywordOrString();e.push(r),this.expectCharacter(i.$COLON),t.push(this.parsePipe())}while(this.optionalCharacter(i.$COMMA));this.rbracesExpected--,this.expectCharacter(i.$RBRACE)}return new a.LiteralMap(this.span(n),e,t)},_ParseAST.prototype.parseAccessMemberOrMethodCall=function(e,t){void 0===t&&(t=!1);var n=e.span.start,r=this.expectIdentifierOrKeyword();if(this.optionalCharacter(i.$LPAREN)){this.rparensExpected++;var o=this.parseCallArguments();this.expectCharacter(i.$RPAREN),this.rparensExpected--;var s=this.span(n);return t?new a.SafeMethodCall(s,e,r,o):new a.MethodCall(s,e,r,o)}if(t)return this.optionalOperator("=")?(this.error("The '?.' operator cannot be used in the assignment"),new a.EmptyExpr(this.span(n))):new a.SafePropertyRead(this.span(n),e,r);if(this.optionalOperator("=")){if(!this.parseAction)return this.error("Bindings cannot contain assignments"),new a.EmptyExpr(this.span(n));var l=this.parseConditional();return new a.PropertyWrite(this.span(n),e,r,l)}return new a.PropertyRead(this.span(n),e,r)},_ParseAST.prototype.parseCallArguments=function(){if(this.next.isCharacter(i.$RPAREN))return[];var e=[];do e.push(this.parsePipe());while(this.optionalCharacter(i.$COMMA));return e},_ParseAST.prototype.expectTemplateBindingKey=function(){var e="",t=!1;do e+=this.expectIdentifierOrKeywordOrString(),t=this.optionalOperator("-"),t&&(e+="-");while(t);return e.toString()},_ParseAST.prototype.parseTemplateBindings=function(){for(var e=[],t=null,n=[];this.index0&&e[e.length-1]===t}var r=this&&this.__extends||function(e,t){function __(){this.constructor=e}for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n]);e.prototype=null===t?Object.create(t):(__.prototype=t.prototype,new __)},i=n(10),o=n(5),s=n(60),a=n(85),l=n(68),c=n(546),u=n(102),p=function(e){function TreeError(t,n,r){e.call(this,n,r),this.elementName=t}return r(TreeError,e),TreeError.create=function(e,t,n){return new TreeError(e,t,n)},TreeError}(s.ParseError);t.TreeError=p;var d=function(){function ParseTreeResult(e,t){this.rootNodes=e,this.errors=t}return ParseTreeResult}();t.ParseTreeResult=d;var h=function(){function Parser(e){this._getTagDefinition=e}return Parser.prototype.parse=function(e,t,n,r){void 0===n&&(n=!1),void 0===r&&(r=l.DEFAULT_INTERPOLATION_CONFIG);var i=c.tokenize(e,t,this._getTagDefinition,n,r),o=new f(i.tokens,this._getTagDefinition).build();return new d(o.rootNodes,i.errors.concat(o.errors))},Parser}();t.Parser=h;var f=function(){function _TreeBuilder(e,t){this.tokens=e,this.getTagDefinition=t,this._index=-1,this._rootNodes=[],this._errors=[],this._elementStack=[],this._advance()}return _TreeBuilder.prototype.build=function(){for(;this._peek.type!==c.TokenType.EOF;)this._peek.type===c.TokenType.TAG_OPEN_START?this._consumeStartTag(this._advance()):this._peek.type===c.TokenType.TAG_CLOSE?this._consumeEndTag(this._advance()):this._peek.type===c.TokenType.CDATA_START?(this._closeVoidElement(),this._consumeCdata(this._advance())):this._peek.type===c.TokenType.COMMENT_START?(this._closeVoidElement(),this._consumeComment(this._advance())):this._peek.type===c.TokenType.TEXT||this._peek.type===c.TokenType.RAW_TEXT||this._peek.type===c.TokenType.ESCAPABLE_RAW_TEXT?(this._closeVoidElement(),this._consumeText(this._advance())):this._peek.type===c.TokenType.EXPANSION_FORM_START?this._consumeExpansion(this._advance()):this._advance();return new d(this._rootNodes,this._errors)},_TreeBuilder.prototype._advance=function(){var e=this._peek;return this._index0)return this._errors=this._errors.concat(i.errors),null;var l=new s.ParseSourceSpan(e.sourceSpan.start,r.sourceSpan.end),u=new s.ParseSourceSpan(t.sourceSpan.start,r.sourceSpan.end);return new a.ExpansionCase(e.parts[0],i.rootNodes,l,e.sourceSpan,u)},_TreeBuilder.prototype._collectExpansionExpTokens=function(e){for(var t=[],n=[c.TokenType.EXPANSION_CASE_EXP_START];;){if(this._peek.type!==c.TokenType.EXPANSION_FORM_START&&this._peek.type!==c.TokenType.EXPANSION_CASE_EXP_START||n.push(this._peek.type),this._peek.type===c.TokenType.EXPANSION_CASE_EXP_END){if(!lastOnStack(n,c.TokenType.EXPANSION_CASE_EXP_START))return this._errors.push(p.create(null,e.sourceSpan,"Invalid ICU message. Missing '}'.")),null;if(n.pop(),0==n.length)return t}if(this._peek.type===c.TokenType.EXPANSION_FORM_END){if(!lastOnStack(n,c.TokenType.EXPANSION_FORM_START))return this._errors.push(p.create(null,e.sourceSpan,"Invalid ICU message. Missing '}'.")),null;n.pop()}if(this._peek.type===c.TokenType.EOF)return this._errors.push(p.create(null,e.sourceSpan,"Invalid ICU message. Missing '}'.")),null;t.push(this._advance())}},_TreeBuilder.prototype._consumeText=function(e){var t=e.parts[0];if(t.length>0&&"\n"==t[0]){var n=this._getParentElement();o.isPresent(n)&&0==n.children.length&&this.getTagDefinition(n.name).ignoreFirstLf&&(t=t.substring(1))}t.length>0&&this._addToParent(new a.Text(t,e.sourceSpan))},_TreeBuilder.prototype._closeVoidElement=function(){if(this._elementStack.length>0){var e=i.ListWrapper.last(this._elementStack);this.getTagDefinition(e.name).isVoid&&this._elementStack.pop()}},_TreeBuilder.prototype._consumeStartTag=function(e){for(var t=e.parts[0],n=e.parts[1],r=[];this._peek.type===c.TokenType.ATTR_NAME;)r.push(this._consumeAttr(this._advance()));var i=this._getElementFullName(t,n,this._getParentElement()),o=!1;if(this._peek.type===c.TokenType.TAG_OPEN_END_VOID){this._advance(),o=!0;var l=this.getTagDefinition(i);l.canSelfClose||null!==u.getNsPrefix(i)||l.isVoid||this._errors.push(p.create(i,e.sourceSpan,'Only void and foreign elements can be self closed "'+e.parts[1]+'"'))}else this._peek.type===c.TokenType.TAG_OPEN_END&&(this._advance(),o=!1);var d=this._peek.sourceSpan.start,h=new s.ParseSourceSpan(e.sourceSpan.start,d),f=new a.Element(i,r,[],h,h,null);this._pushElement(f),o&&(this._popElement(i),f.endSourceSpan=h)},_TreeBuilder.prototype._pushElement=function(e){if(this._elementStack.length>0){var t=i.ListWrapper.last(this._elementStack);this.getTagDefinition(t.name).isClosedByChild(e.name)&&this._elementStack.pop()}var n=this.getTagDefinition(e.name),r=this._getParentElementSkippingContainers(),s=r.parent,l=r.container;if(o.isPresent(s)&&n.requireExtraParent(s.name)){var c=new a.Element(n.parentToAdd,[],[],e.sourceSpan,e.startSourceSpan,e.endSourceSpan);this._insertBeforeContainer(s,l,c)}this._addToParent(e),this._elementStack.push(e)},_TreeBuilder.prototype._consumeEndTag=function(e){var t=this._getElementFullName(e.parts[0],e.parts[1],this._getParentElement());this._getParentElement()&&(this._getParentElement().endSourceSpan=e.sourceSpan),this.getTagDefinition(t).isVoid?this._errors.push(p.create(t,e.sourceSpan,'Void elements do not have end tags "'+e.parts[1]+'"')):this._popElement(t)||this._errors.push(p.create(t,e.sourceSpan,'Unexpected closing tag "'+e.parts[1]+'"'))},_TreeBuilder.prototype._popElement=function(e){for(var t=this._elementStack.length-1;t>=0;t--){var n=this._elementStack[t];if(n.name==e)return i.ListWrapper.splice(this._elementStack,t,this._elementStack.length-t),!0;if(!this.getTagDefinition(n.name).closedByParent)return!1}return!1},_TreeBuilder.prototype._consumeAttr=function(e){var t=u.mergeNsAndName(e.parts[0],e.parts[1]),n=e.sourceSpan.end,r="";if(this._peek.type===c.TokenType.ATTR_VALUE){var i=this._advance();r=i.parts[0],n=i.sourceSpan.end}return new a.Attribute(t,r,new s.ParseSourceSpan(e.sourceSpan.start,n))},_TreeBuilder.prototype._getParentElement=function(){return this._elementStack.length>0?i.ListWrapper.last(this._elementStack):null},_TreeBuilder.prototype._getParentElementSkippingContainers=function(){for(var e=null,t=this._elementStack.length-1;t>=0;t--){if("ng-container"!==this._elementStack[t].name)return{parent:this._elementStack[t],container:e};e=this._elementStack[t]}return{parent:i.ListWrapper.last(this._elementStack),container:e}},_TreeBuilder.prototype._addToParent=function(e){var t=this._getParentElement();o.isPresent(t)?t.children.push(e):this._rootNodes.push(e)},_TreeBuilder.prototype._insertBeforeContainer=function(e,t,n){if(t){if(e){var r=e.children.indexOf(t);e.children[r]=n}else this._rootNodes.push(n);n.children.push(t),this._elementStack.splice(this._elementStack.indexOf(t),0,n)}else this._addToParent(n),this._elementStack.push(n)},_TreeBuilder.prototype._getElementFullName=function(e,t,n){return o.isBlank(e)&&(e=this.getTagDefinition(t).implicitNamespacePrefix,o.isBlank(e)&&o.isPresent(n)&&(e=u.getNsPrefix(n.name))),u.mergeNsAndName(e,t)},_TreeBuilder}()},function(e,t,n){"use strict";function splitClasses(e){return e.trim().split(/\s+/g)}function createElementCssSelector(e,t){var n=new w.CssSelector,r=g.splitNsName(e)[1];n.setElement(r);for(var i=0;i0&&this._console.warn("Template parse warnings:\n"+a.join("\n")),l.length>0){var c=l.join("\n");throw new u.BaseException("Template parse errors:\n"+c)}return s.templateAst},TemplateParser.prototype.tryParse=function(e,t,n,r,i,o){var a;e.template&&(a=y.InterpolationConfig.fromArray(e.template.interpolation));var l,c=this._htmlParser.parse(t,o,!0,a),u=c.errors;if(0==u.length){var d=m.expandNodes(c.rootNodes);u.push.apply(u,d.errors),c=new f.ParseTreeResult(d.nodes,u)}if(c.rootNodes.length>0){var g=s.removeIdentifierDuplicates(n),v=s.removeIdentifierDuplicates(r),_=new b.ProviderViewContext(e,c.rootNodes[0].sourceSpan),w=new j(_,g,v,i,this._exprParser,this._schemaRegistry);l=h.visitAll(w,c.rootNodes,z),u.push.apply(u,w.errors.concat(_.errors))}else l=[];return this._assertNoReferenceDuplicationOnTemplate(l,u),u.length>0?new L(l,u):(p.isPresent(this.transforms)&&this.transforms.forEach(function(e){l=E.templateVisitAll(e,l)}),new L(l,u))},TemplateParser.prototype._assertNoReferenceDuplicationOnTemplate=function(e,t){var n=[];e.filter(function(e){return!!e.references}).forEach(function(e){return e.references.forEach(function(e){var r=e.name;if(n.indexOf(r)<0)n.push(r);else{var i=new V('Reference "#'+r+'" is defined several times',e.sourceSpan,v.ParseErrorLevel.FATAL);t.push(i)}})})},TemplateParser.decorators=[{type:i.Injectable}],TemplateParser.ctorParameters=[{type:l.Parser},{type:_.ElementSchemaRegistry},{type:f.HtmlParser},{type:o.Console},{type:Array,decorators:[{type:i.Optional},{type:i.Inject,args:[t.TEMPLATE_TRANSFORMS]}]}],TemplateParser}();t.TemplateParser=F;var j=function(){function TemplateParseVisitor(e,t,n,r,i,o){var s=this;this.providerViewContext=e,this._schemas=r,this._exprParser=i,this._schemaRegistry=o,this.errors=[],this.directivesIndex=new Map,this.ngContentCount=0,this.selectorMatcher=new w.SelectorMatcher;var a=e.component.template;p.isPresent(a)&&p.isPresent(a.interpolation)&&(this._interpolationConfig={start:a.interpolation[0],end:a.interpolation[1]}),c.ListWrapper.forEachWithIndex(t,function(e,t){var n=w.CssSelector.parse(e.selector);s.selectorMatcher.addSelectables(n,e),s.directivesIndex.set(e,t)}),this.pipesByName=new Map,n.forEach(function(e){return s.pipesByName.set(e.name,e)})}return TemplateParseVisitor.prototype._reportError=function(e,t,n){void 0===n&&(n=v.ParseErrorLevel.FATAL),this.errors.push(new V(e,t,n))},TemplateParseVisitor.prototype._reportParserErors=function(e,t){for(var n=0,r=e;no.MAX_INTERPOLATION_VALUES)throw new u.BaseException("Only support at most "+o.MAX_INTERPOLATION_VALUES+" interpolation values!");return r}catch(i){return this._reportError(""+i,t),this._exprParser.wrapLiteralPrimitive("ERROR",n)}},TemplateParseVisitor.prototype._parseAction=function(e,t){var n=t.start.toString();try{var r=this._exprParser.parseAction(e,n,this._interpolationConfig);return r&&this._reportParserErors(r.errors,t),!r||r.ast instanceof a.EmptyExpr?(this._reportError("Empty expressions are not allowed",t),this._exprParser.wrapLiteralPrimitive("ERROR",n)):(this._checkPipes(r,t),r)}catch(i){return this._reportError(""+i,t),this._exprParser.wrapLiteralPrimitive("ERROR",n)}},TemplateParseVisitor.prototype._parseBinding=function(e,t){var n=t.start.toString();try{var r=this._exprParser.parseBinding(e,n,this._interpolationConfig);return r&&this._reportParserErors(r.errors,t),this._checkPipes(r,t),r}catch(i){return this._reportError(""+i,t),this._exprParser.wrapLiteralPrimitive("ERROR",n)}},TemplateParseVisitor.prototype._parseTemplateBindings=function(e,t){var n=this,r=t.start.toString();try{var i=this._exprParser.parseTemplateBindings(e,r);return this._reportParserErors(i.errors,t),i.templateBindings.forEach(function(e){p.isPresent(e.expression)&&n._checkPipes(e.expression,t)}),i.warnings.forEach(function(e){n._reportError(e,t,v.ParseErrorLevel.WARNING)}),i.templateBindings}catch(o){return this._reportError(""+o,t),[]}},TemplateParseVisitor.prototype._checkPipes=function(e,t){var n=this;if(p.isPresent(e)){var r=new q;e.visit(r),r.pipes.forEach(function(e){n.pipesByName.has(e)||n._reportError("The pipe '"+e+"' could not be found",t)})}},TemplateParseVisitor.prototype.visitExpansion=function(e,t){return null},TemplateParseVisitor.prototype.visitExpansionCase=function(e,t){return null},TemplateParseVisitor.prototype.visitText=function(e,t){var n=t.findNgContentIndex(N),r=this._parseInterpolation(e.value,e.sourceSpan);return p.isPresent(r)?new E.BoundTextAst(r,n,e.sourceSpan):new E.TextAst(e.value,n,e.sourceSpan)},TemplateParseVisitor.prototype.visitAttribute=function(e,t){return new E.AttrAst(e.name,e.value,e.sourceSpan)},TemplateParseVisitor.prototype.visitComment=function(e,t){return null},TemplateParseVisitor.prototype.visitElement=function(e,t){var n=this,r=e.name,i=T.preparseElement(e);if(i.type===T.PreparsedElementType.SCRIPT||i.type===T.PreparsedElementType.STYLE)return null;if(i.type===T.PreparsedElementType.STYLESHEET&&S.isStyleUrlResolvable(i.hrefAttr))return null;var o=[],s=[],a=[],l=[],c=[],u=[],d=[],f=[],m=[],y=!1,v=[],_=g.splitNsName(r.toLowerCase())[1],C=_==P;e.attrs.forEach(function(e){var t=n._parseAttr(C,e,o,s,c,u,a,l),r=n._parseInlineTemplateBinding(e,f,d,m);r&&y&&n._reportError("Can't have multiple template bindings on one element. Use only one attribute named 'template' or prefixed with *",e.sourceSpan),t||r||(v.push(n.visitAttribute(e,null)),o.push([e.name,e.value])),r&&(y=!0)});var R=createElementCssSelector(r,o),x=this._parseDirectives(this.selectorMatcher,R),M=[],I=this._createDirectiveAsts(C,e.name,x,s,a,e.sourceSpan,M),k=this._createElementPropertyAsts(e.name,s,I).concat(c),A=t.isTemplateElement||y,O=new b.ProviderElementContext(this.providerViewContext,t.providerContext,A,I,v,M,e.sourceSpan),D=h.visitAll(i.nonBindable?G:this,e.children,U.create(C,I,C?t.providerContext:O));O.afterElement();var N,V=p.isPresent(i.projectAs)?w.CssSelector.parse(i.projectAs)[0]:R,L=t.findNgContentIndex(V);if(i.type===T.PreparsedElementType.NG_CONTENT)p.isPresent(e.children)&&e.children.length>0&&this._reportError(" element cannot have content. must be immediately followed by ",e.sourceSpan),N=new E.NgContentAst((this.ngContentCount++),y?null:L,e.sourceSpan);else if(C)this._assertAllEventsPublishedByDirectives(I,u),this._assertNoComponentsNorElementBindingsOnTemplate(I,k,e.sourceSpan),N=new E.EmbeddedTemplateAst(v,u,M,l,O.transformedDirectiveAsts,O.transformProviders,O.transformedHasViewContainer,D,y?null:L,e.sourceSpan);else{this._assertOnlyOneComponent(I,e.sourceSpan);var F=y?null:t.findNgContentIndex(V);N=new E.ElementAst(r,v,k,u,M,O.transformedDirectiveAsts,O.transformProviders,O.transformedHasViewContainer,D,y?null:F,e.sourceSpan)}if(y){var j=createElementCssSelector(P,f),B=this._parseDirectives(this.selectorMatcher,j),W=this._createDirectiveAsts(!0,e.name,B,d,[],e.sourceSpan,[]),H=this._createElementPropertyAsts(e.name,d,W);this._assertNoComponentsNorElementBindingsOnTemplate(W,H,e.sourceSpan);var z=new b.ProviderElementContext(this.providerViewContext,t.providerContext,t.isTemplateElement,W,[],[],e.sourceSpan);z.afterElement(),N=new E.EmbeddedTemplateAst([],[],[],m,z.transformedDirectiveAsts,z.transformProviders,z.transformedHasViewContainer,[N],L,e.sourceSpan)}return N},TemplateParseVisitor.prototype._parseInlineTemplateBinding=function(e,t,n,r){var i=null;if(this._normalizeAttributeName(e.name)==x)i=e.value;else if(e.name.startsWith(M)){var o=e.name.substring(M.length);i=0==e.value.length?o:o+" "+e.value}if(p.isPresent(i)){for(var s=this._parseTemplateBindings(i,e.sourceSpan),a=0;a elements is deprecated. Use "let-" instead!',t.sourceSpan,v.ParseErrorLevel.WARNING),this._parseVariable(h,c,t.sourceSpan,a)):(this._reportError('"var-" on non