From 8ea39c31a45ff97385247b32535ca181b0e2e5e2 Mon Sep 17 00:00:00 2001 From: deepthi Date: Tue, 4 Dec 2018 15:08:19 -0800 Subject: [PATCH 001/115] change ClusterAlias in _vt.local_metadata to be keyspace/shard instead of keyspace.shard Signed-off-by: deepthi --- go/vt/vttablet/tabletmanager/restore.go | 2 +- test/backup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/go/vt/vttablet/tabletmanager/restore.go b/go/vt/vttablet/tabletmanager/restore.go index 55a3a57285d..d61bfff2d85 100644 --- a/go/vt/vttablet/tabletmanager/restore.go +++ b/go/vt/vttablet/tabletmanager/restore.go @@ -189,7 +189,7 @@ func (agent *ActionAgent) getLocalMetadataValues(tabletType topodatapb.TabletTyp tablet := agent.Tablet() values := map[string]string{ "Alias": topoproto.TabletAliasString(tablet.Alias), - "ClusterAlias": fmt.Sprintf("%s.%s", tablet.Keyspace, tablet.Shard), + "ClusterAlias": fmt.Sprintf("%s/%s", tablet.Keyspace, tablet.Shard), "DataCenter": tablet.Alias.Cell, "PromotionRule": "must_not", } diff --git a/test/backup.py b/test/backup.py index 78e8735fb9b..7de8b683851 100755 --- a/test/backup.py +++ b/test/backup.py @@ -297,7 +297,7 @@ def _test_backup(self, tablet_type): for row in result: metadata[row[0]] = row[1] self.assertEqual(metadata['Alias'], 'test_nj-0000062346') - self.assertEqual(metadata['ClusterAlias'], 'test_keyspace.0') + self.assertEqual(metadata['ClusterAlias'], 'test_keyspace/0') self.assertEqual(metadata['DataCenter'], 'test_nj') if tablet_type == 'replica': self.assertEqual(metadata['PromotionRule'], 'neutral') From 6d20c51fe0f30d2fce26ef44016d1663a12ff72e Mon Sep 17 00:00:00 2001 From: Leo Xuzhang Lin Date: Fri, 21 Dec 2018 11:33:10 -0500 Subject: [PATCH 002/115] Remove trailing whitespace Signed-off-by: Leo Xuzhang Lin --- java/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/pom.xml b/java/pom.xml index e5b2fbd7b45..5c710cc14d1 100644 --- a/java/pom.xml +++ b/java/pom.xml @@ -23,7 +23,7 @@ client example - grpc-client + grpc-client hadoop jdbc From 421e45abdcccbfde40266ba41074e84169160463 Mon Sep 17 00:00:00 2001 From: Leo Xuzhang Lin Date: Fri, 21 Dec 2018 11:37:59 -0500 Subject: [PATCH 003/115] Use recommended version combination Signed-off-by: Leo Xuzhang Lin --- java/pom.xml | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/java/pom.xml b/java/pom.xml index 5c710cc14d1..2805c2e5693 100644 --- a/java/pom.xml +++ b/java/pom.xml @@ -68,6 +68,11 @@ UTF-8 1.16.0 + + 4.1.30.Final + 2.0.17.Final + 3.6.1 3.6.1 @@ -130,14 +135,14 @@ io.netty netty-handler - 4.1.27.Final + ${netty.handler.version} io.netty netty-tcnative-boringssl-static - 2.0.17.Final + ${tcnative.boring.ssl.version} From a33b3d6d98ef64afe33422dd08e7854b6c148afb Mon Sep 17 00:00:00 2001 From: David Weitzman Date: Sat, 22 Dec 2018 09:53:19 -0800 Subject: [PATCH 004/115] Extract the connection com_query implementation into its own method Signed-off-by: David Weitzman --- go/mysql/conn.go | 128 +++++++++++++++++++++++++---------------------- 1 file changed, 69 insertions(+), 59 deletions(-) diff --git a/go/mysql/conn.go b/go/mysql/conn.go index 8f24ae53555..ef6bfed2261 100644 --- a/go/mysql/conn.go +++ b/go/mysql/conn.go @@ -723,66 +723,10 @@ func (c *Conn) handleNextCommand(handler Handler) error { queryStart := time.Now() query := c.parseComQuery(data) c.recycleReadPacket() - fieldSent := false - // sendFinished is set if the response should just be an OK packet. - sendFinished := false - - err := handler.ComQuery(c, query, func(qr *sqltypes.Result) error { - if sendFinished { - // Failsafe: Unreachable if server is well-behaved. - return io.EOF - } - - if !fieldSent { - fieldSent = true - - if len(qr.Fields) == 0 { - sendFinished = true - - // A successful callback with no fields means that this was a - // DML or other write-only operation. - // - // We should not send any more packets after this, but make sure - // to extract the affected rows and last insert id from the result - // struct here since clients expect it. - return c.writeOKPacket(qr.RowsAffected, qr.InsertID, c.StatusFlags, handler.WarningCount(c)) - } - if err := c.writeFields(qr); err != nil { - return err - } - } - - return c.writeRows(qr) - }) - // If no field was sent, we expect an error. - if !fieldSent { - // This is just a failsafe. Should never happen. - if err == nil || err == io.EOF { - err = NewSQLErrorFromError(errors.New("unexpected: query ended without no results and no error")) - } - if werr := c.writeErrorPacketFromError(err); werr != nil { - // If we can't even write the error, we're done. - log.Errorf("Error writing query error to %s: %v", c, werr) - return werr - } - } else { - if err != nil { - // We can't send an error in the middle of a stream. - // All we can do is abort the send, which will cause a 2013. - log.Errorf("Error in the middle of a stream to %s: %v", c, err) - return err - } - - // Send the end packet only sendFinished is false (results were streamed). - // In this case the affectedRows and lastInsertID are always 0 since it - // was a read operation. - if !sendFinished { - if err := c.writeEndResult(false, 0, 0, handler.WarningCount(c)); err != nil { - log.Errorf("Error writing result to %s: %v", c, err) - return err - } - } + err := c.execQuery(query, handler) + if err != nil { + return err } timings.Record(queryTimingKey, queryStart) @@ -843,6 +787,72 @@ func (c *Conn) handleNextCommand(handler Handler) error { return nil } +func (c *Conn) execQuery(query string, handler Handler) error { + fieldSent := false + // sendFinished is set if the response should just be an OK packet. + sendFinished := false + + err := handler.ComQuery(c, query, func(qr *sqltypes.Result) error { + if sendFinished { + // Failsafe: Unreachable if server is well-behaved. + return io.EOF + } + + if !fieldSent { + fieldSent = true + + if len(qr.Fields) == 0 { + sendFinished = true + + // A successful callback with no fields means that this was a + // DML or other write-only operation. + // + // We should not send any more packets after this, but make sure + // to extract the affected rows and last insert id from the result + // struct here since clients expect it. + return c.writeOKPacket(qr.RowsAffected, qr.InsertID, c.StatusFlags, handler.WarningCount(c)) + } + if err := c.writeFields(qr); err != nil { + return err + } + } + + return c.writeRows(qr) + }) + + // If no field was sent, we expect an error. + if !fieldSent { + // This is just a failsafe. Should never happen. + if err == nil || err == io.EOF { + err = NewSQLErrorFromError(errors.New("unexpected: query ended without no results and no error")) + } + if werr := c.writeErrorPacketFromError(err); werr != nil { + // If we can't even write the error, we're done. + log.Errorf("Error writing query error to %s: %v", c, werr) + return werr + } + } else { + if err != nil { + // We can't send an error in the middle of a stream. + // All we can do is abort the send, which will cause a 2013. + log.Errorf("Error in the middle of a stream to %s: %v", c, err) + return err + } + + // Send the end packet only sendFinished is false (results were streamed). + // In this case the affectedRows and lastInsertID are always 0 since it + // was a read operation. + if !sendFinished { + if err := c.writeEndResult(false, 0, 0, handler.WarningCount(c)); err != nil { + log.Errorf("Error writing result to %s: %v", c, err) + return err + } + } + } + + return nil +} + // // Packet parsing methods, for generic packets. // From f1397ed998f60c02883d5eee651e171ae3f4e3fd Mon Sep 17 00:00:00 2001 From: David Weitzman Date: Sat, 22 Dec 2018 09:42:23 -0800 Subject: [PATCH 005/115] Multi-statement support for the vtgate mysql protocol This completes yuananf's work from https://github.com/vitessio/vitess/pull/3683 which was split into several diffs and never fully landed. One large benefit of multi-statement support is that the "rewriteBatchedStatements" option in Java's connector-j driver doesn't work without it. There's a bug where connector-j fails to check the server capabilities and assumes multi-statement support. Signed-off-by: David Weitzman --- go/mysql/conn.go | 40 ++++++++++++++++++++++++++++++++------- test/mysql_server_test.py | 26 +++++++++++++++++++++++++ 2 files changed, 59 insertions(+), 7 deletions(-) diff --git a/go/mysql/conn.go b/go/mysql/conn.go index ef6bfed2261..2cf2ab99786 100644 --- a/go/mysql/conn.go +++ b/go/mysql/conn.go @@ -31,6 +31,7 @@ import ( "vitess.io/vitess/go/sync2" "vitess.io/vitess/go/vt/log" querypb "vitess.io/vitess/go/vt/proto/query" + "vitess.io/vitess/go/vt/sqlparser" ) const ( @@ -724,9 +725,28 @@ func (c *Conn) handleNextCommand(handler Handler) error { query := c.parseComQuery(data) c.recycleReadPacket() - err := c.execQuery(query, handler) - if err != nil { - return err + var queries []string + if c.Capabilities&CapabilityClientMultiStatements != 0 { + queries, err = sqlparser.SplitStatementToPieces(query) + if err != nil { + log.Errorf("Conn %v: Error splitting query: %v", c, err) + if werr := c.writeErrorPacketFromError(err); werr != nil { + // If we can't even write the error, we're done. + log.Errorf("Conn %v: Error writing query error: %v", c, werr) + return werr + } + } + } else { + queries = []string{query} + } + for index, sql := range queries { + more := false + if index != len(queries)-1 { + more = true + } + if err := c.execQuery(sql, handler, more); err != nil { + return err + } } timings.Record(queryTimingKey, queryStart) @@ -751,7 +771,9 @@ func (c *Conn) handleNextCommand(handler Handler) error { } } case ComSetOption: - if operation, ok := c.parseComSetOption(data); ok { + operation, ok := c.parseComSetOption(data) + c.recycleReadPacket() + if ok { switch operation { case 0: c.Capabilities |= CapabilityClientMultiStatements @@ -787,12 +809,16 @@ func (c *Conn) handleNextCommand(handler Handler) error { return nil } -func (c *Conn) execQuery(query string, handler Handler) error { +func (c *Conn) execQuery(query string, handler Handler, more bool) error { fieldSent := false // sendFinished is set if the response should just be an OK packet. sendFinished := false err := handler.ComQuery(c, query, func(qr *sqltypes.Result) error { + flag := c.StatusFlags + if more { + flag |= ServerMoreResultsExists + } if sendFinished { // Failsafe: Unreachable if server is well-behaved. return io.EOF @@ -810,7 +836,7 @@ func (c *Conn) execQuery(query string, handler Handler) error { // We should not send any more packets after this, but make sure // to extract the affected rows and last insert id from the result // struct here since clients expect it. - return c.writeOKPacket(qr.RowsAffected, qr.InsertID, c.StatusFlags, handler.WarningCount(c)) + return c.writeOKPacket(qr.RowsAffected, qr.InsertID, flag, handler.WarningCount(c)) } if err := c.writeFields(qr); err != nil { return err @@ -843,7 +869,7 @@ func (c *Conn) execQuery(query string, handler Handler) error { // In this case the affectedRows and lastInsertID are always 0 since it // was a read operation. if !sendFinished { - if err := c.writeEndResult(false, 0, 0, handler.WarningCount(c)); err != nil { + if err := c.writeEndResult(more, 0, 0, handler.WarningCount(c)); err != nil { log.Errorf("Error writing result to %s: %v", c, err) return err } diff --git a/test/mysql_server_test.py b/test/mysql_server_test.py index b723eb33ec7..d65380133ba 100755 --- a/test/mysql_server_test.py +++ b/test/mysql_server_test.py @@ -100,6 +100,9 @@ class TestMySQL(unittest.TestCase): """This test makes sure the MySQL server connector is correct. """ + MYSQL_OPTION_MULTI_STATEMENTS_ON = 0 + MYSQL_OPTION_MULTI_STATEMENTS_OFF = 1 + def test_mysql_connector(self): with open(table_acl_config, 'w') as fd: fd.write("""{ @@ -160,6 +163,29 @@ def test_mysql_connector(self): cursor.execute('select * from vt_insert_test', {}) cursor.close() + # Test multi-statement support. It should only work when + # COM_SET_OPTION has set the options to 0 + conn.set_server_option(self.MYSQL_OPTION_MULTI_STATEMENTS_ON) + cursor = conn.cursor() + cursor.execute("select 1; select 2") + self.assertEquals(((1L,),), cursor.fetchall()) + self.assertEquals(1, cursor.nextset()) + self.assertEquals(((2L,),), cursor.fetchall()) + self.assertEquals(None, cursor.nextset()) + cursor.close() + conn.set_server_option(self.MYSQL_OPTION_MULTI_STATEMENTS_OFF) + + # Multi-statement support should not work without the + # option enabled + cursor = conn.cursor() + try: + cursor.execute("select 1; select 2") + self.fail('Execute went through') + except MySQLdb.OperationalError, e: + s = str(e) + self.assertIn('syntax error', s) + cursor.close() + # verify that queries work end-to-end with large grpc messages largeComment = 'L' * ((4 * 1024 * 1024) + 1) cursor = conn.cursor() From 157ebf5830e6c6eae970af42959d367d7d1b57e9 Mon Sep 17 00:00:00 2001 From: Jitendra Vaidya Date: Sun, 23 Dec 2018 06:13:33 +0000 Subject: [PATCH 006/115] Added the ability to build without tests Signed-off-by: Jitendra Vaidya --- bootstrap.sh | 123 ++++++++++++++++++++++++++++++--------------------- build.env | 39 ++++++++++++++++ dev.env | 16 +------ 3 files changed, 113 insertions(+), 65 deletions(-) create mode 100644 build.env diff --git a/bootstrap.sh b/bootstrap.sh index 70108e7d37c..4e7548a599b 100755 --- a/bootstrap.sh +++ b/bootstrap.sh @@ -23,6 +23,7 @@ # 3. Detection of installed MySQL and setting MYSQL_FLAVOR. # 4. Installation of development related steps e.g. creating Git hooks. +BUILD_TESTS=${BUILD_TESTS:-1} # # 0. Initialization and helper methods. @@ -47,7 +48,11 @@ function fail() { go version &>/dev/null || fail "Go is not installed or is not on \$PATH" # Set up the proper GOPATH for go get below. -source ./dev.env +if [ "$BUILD_TESTS" == 1 ] ; then + source ./dev.env +else + source ./build.env +fi # Create main directories. mkdir -p "$VTROOT/dist" @@ -55,15 +60,21 @@ mkdir -p "$VTROOT/bin" mkdir -p "$VTROOT/lib" mkdir -p "$VTROOT/vthook" -# Set up required soft links. -# TODO(mberlin): Which of these can be deleted? -ln -snf "$VTTOP/config" "$VTROOT/config" -ln -snf "$VTTOP/data" "$VTROOT/data" -ln -snf "$VTTOP/py" "$VTROOT/py-vtdb" -ln -snf "$VTTOP/go/vt/zkctl/zksrv.sh" "$VTROOT/bin/zksrv.sh" -ln -snf "$VTTOP/test/vthook-test.sh" "$VTROOT/vthook/test.sh" -ln -snf "$VTTOP/test/vthook-test_backup_error" "$VTROOT/vthook/test_backup_error" -ln -snf "$VTTOP/test/vthook-test_backup_transform" "$VTROOT/vthook/test_backup_transform" +if [ "$BUILD_TESTS" == 1 ] ; then + # Set up required soft links. + # TODO(mberlin): Which of these can be deleted? + ln -snf "$VTTOP/config" "$VTROOT/config" + ln -snf "$VTTOP/data" "$VTROOT/data" + ln -snf "$VTTOP/py" "$VTROOT/py-vtdb" + ln -snf "$VTTOP/go/vt/zkctl/zksrv.sh" "$VTROOT/bin/zksrv.sh" + ln -snf "$VTTOP/test/vthook-test.sh" "$VTROOT/vthook/test.sh" + ln -snf "$VTTOP/test/vthook-test_backup_error" "$VTROOT/vthook/test_backup_error" + ln -snf "$VTTOP/test/vthook-test_backup_transform" "$VTROOT/vthook/test_backup_transform" +else + ln -snf "$VTTOP/config" "$VTROOT/config" + ln -snf "$VTTOP/data" "$VTROOT/data" + ln -snf "$VTTOP/go/vt/zkctl/zksrv.sh" "$VTROOT/bin/zksrv.sh" +fi # install_dep is a helper function to generalize the download and installation of dependencies. # @@ -136,8 +147,10 @@ function install_grpc() { grpcio_ver=$version $PIP install --upgrade grpcio=="$grpcio_ver" grpcio-tools=="$grpcio_ver" } -install_dep "gRPC" "1.16.0" "$VTROOT/dist/grpc" install_grpc +if [ "$BUILD_TESTS" == 1 ] ; then + install_dep "gRPC" "1.16.0" "$VTROOT/dist/grpc" install_grpc +fi # Install protoc. function install_protoc() { @@ -225,8 +238,9 @@ function install_pymock() { popd >/dev/null } pymock_version=1.0.1 -install_dep "py-mock" "$pymock_version" "$VTROOT/dist/py-mock-$pymock_version" install_pymock - +if [ "$BUILD_TESTS" == 1 ] ; then + install_dep "py-mock" "$pymock_version" "$VTROOT/dist/py-mock-$pymock_version" install_pymock +fi # Download Selenium (necessary to run test/vtctld_web_test.py). function install_selenium() { @@ -239,7 +253,9 @@ function install_selenium() { # instead of go/dist/selenium/lib/python3.5/site-packages and then can't find module 'pip._vendor.requests' PYTHONPATH='' $PIP install selenium } -install_dep "Selenium" "latest" "$VTROOT/dist/selenium" install_selenium +if [ "$BUILD_TESTS" == 1 ] ; then + install_dep "Selenium" "latest" "$VTROOT/dist/selenium" install_selenium +fi # Download chromedriver (necessary to run test/vtctld_web_test.py). @@ -251,7 +267,9 @@ function install_chromedriver() { unzip -o -q chromedriver_linux64.zip -d "$dist" rm chromedriver_linux64.zip } -install_dep "chromedriver" "2.44" "$VTROOT/dist/chromedriver" install_chromedriver +if [ "$BUILD_TESTS" == 1 ] ; then + install_dep "chromedriver" "2.44" "$VTROOT/dist/chromedriver" install_chromedriver +fi # @@ -300,47 +318,52 @@ govendor sync || fail "Failed to download/update dependencies with govendor. Ple # find mysql and prepare to use libmysqlclient -if [ -z "$MYSQL_FLAVOR" ]; then - export MYSQL_FLAVOR=MySQL56 - echo "MYSQL_FLAVOR environment variable not set. Using default: $MYSQL_FLAVOR" -fi -case "$MYSQL_FLAVOR" in - "MySQL56") - myversion="$("$VT_MYSQL_ROOT/bin/mysql" --version)" - [[ "$myversion" =~ Distrib\ 5\.[67] || "$myversion" =~ Ver\ 8\. ]] || fail "Couldn't find MySQL 5.6+ in $VT_MYSQL_ROOT. Set VT_MYSQL_ROOT to override search location." - echo "Found MySQL 5.6+ installation in $VT_MYSQL_ROOT." - ;; - - "MariaDB") - myversion="$("$VT_MYSQL_ROOT/bin/mysql" --version)" - [[ "$myversion" =~ MariaDB ]] || fail "Couldn't find MariaDB in $VT_MYSQL_ROOT. Set VT_MYSQL_ROOT to override search location." - echo "Found MariaDB installation in $VT_MYSQL_ROOT." - ;; - - *) - fail "Unsupported MYSQL_FLAVOR $MYSQL_FLAVOR" - ;; -esac - -# save the flavor that was used in bootstrap, so it can be restored -# every time dev.env is sourced. -echo "$MYSQL_FLAVOR" > "$VTROOT/dist/MYSQL_FLAVOR" +if [ "$BUILD_TESTS" == 1 ] ; then + if [ -z "$MYSQL_FLAVOR" ]; then + export MYSQL_FLAVOR=MySQL56 + echo "MYSQL_FLAVOR environment variable not set. Using default: $MYSQL_FLAVOR" + fi + case "$MYSQL_FLAVOR" in + "MySQL56") + myversion="$("$VT_MYSQL_ROOT/bin/mysql" --version)" + [[ "$myversion" =~ Distrib\ 5\.[67] || "$myversion" =~ Ver\ 8\. ]] || fail "Couldn't find MySQL 5.6+ in $VT_MYSQL_ROOT. Set VT_MYSQL_ROOT to override search location." + echo "Found MySQL 5.6+ installation in $VT_MYSQL_ROOT." + ;; + + "MariaDB") + myversion="$("$VT_MYSQL_ROOT/bin/mysql" --version)" + [[ "$myversion" =~ MariaDB ]] || fail "Couldn't find MariaDB in $VT_MYSQL_ROOT. Set VT_MYSQL_ROOT to override search location." + echo "Found MariaDB installation in $VT_MYSQL_ROOT." + ;; + + *) + fail "Unsupported MYSQL_FLAVOR $MYSQL_FLAVOR" + ;; + esac + # save the flavor that was used in bootstrap, so it can be restored + # every time dev.env is sourced. + echo "$MYSQL_FLAVOR" > "$VTROOT/dist/MYSQL_FLAVOR" +fi # # 4. Installation of development related steps e.g. creating Git hooks. # - -# Create the 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/prepare-commit-msg.bugnumber" "$VTTOP/.git/hooks/prepare-commit-msg" -ln -sf "$VTTOP/misc/git/commit-msg" "$VTTOP/.git/hooks/commit-msg" -(cd "$VTTOP" && git config core.hooksPath "$VTTOP/.git/hooks") +if [ "$BUILD_TESTS" == 1 ] ; then + # Create the 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/prepare-commit-msg.bugnumber" "$VTTOP/.git/hooks/prepare-commit-msg" + ln -sf "$VTTOP/misc/git/commit-msg" "$VTTOP/.git/hooks/commit-msg" + (cd "$VTTOP" && git config core.hooksPath "$VTTOP/.git/hooks") + echo + echo "bootstrap finished - run 'source dev.env' in your shell before building." +else + echo + echo "bootstrap finished - run 'source build.env' in your shell before building." +fi -echo -echo "bootstrap finished - run 'source dev.env' in your shell before building." diff --git a/build.env b/build.env new file mode 100644 index 00000000000..a9d46a99b92 --- /dev/null +++ b/build.env @@ -0,0 +1,39 @@ +# No shebang line as this script is sourced from an external shell. + +# 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. + +# Plese ensure dev.env is written in a way which is POSIX (bourne) +# shell compatible. +# - Some build systems like rpm require the different scriptlets used +# to build a package to be run under a POSIX shell so non-POSIX +# syntax will break that as dev.env will not be sourced by bash.. + +# Import prepend_path function. +dir="$(dirname "${BASH_SOURCE[0]}")" +# shellcheck source=tools/shell_functions.inc +if ! source "${dir}/tools/shell_functions.inc"; then + echo "failed to load tools/shell_functions.inc" + return 1 +fi + +VTTOP=$(pwd) +export VTTOP +VTROOT="${VTROOT:-${VTTOP/\/src\/vitess.io\/vitess/}}" +export VTROOT +# VTTOP sanity check +if [[ "$VTTOP" == "${VTTOP/\/src\/vitess.io\/vitess/}" ]]; then + echo "WARNING: VTTOP($VTTOP) does not contain src/vitess.io/vitess" +fi + diff --git a/dev.env b/dev.env index dbb3fe86409..5e0b69b78c2 100644 --- a/dev.env +++ b/dev.env @@ -20,22 +20,8 @@ # to build a package to be run under a POSIX shell so non-POSIX # syntax will break that as dev.env will not be sourced by bash.. -# Import prepend_path function. -dir="$(dirname "${BASH_SOURCE[0]}")" -# shellcheck source=tools/shell_functions.inc -if ! source "${dir}/tools/shell_functions.inc"; then - echo "failed to load tools/shell_functions.inc" - return 1 -fi +source build.env -VTTOP=$(pwd) -export VTTOP -VTROOT="${VTROOT:-${VTTOP/\/src\/vitess.io\/vitess/}}" -export VTROOT -# VTTOP sanity check -if [[ "$VTTOP" == "${VTTOP/\/src\/vitess.io\/vitess/}" ]]; then - echo "WARNING: VTTOP($VTTOP) does not contain src/vitess.io/vitess" -fi export GOTOP=$VTTOP/go export PYTOP=$VTTOP/py From 1de05582f74c28c2b0de3e4b23a1881de06572fd Mon Sep 17 00:00:00 2001 From: Scott Lanning Date: Mon, 24 Dec 2018 12:07:15 +0100 Subject: [PATCH 007/115] require golang version 1.11+ See also PR 4470 and commit dba155b8f5e5 which introduced a dependency on golang 1.10+. Some docs refer to 1.11+ so I made bootstrap.sh require that. Signed-off-by: Scott Lanning --- bootstrap.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/bootstrap.sh b/bootstrap.sh index 70108e7d37c..7e67b287065 100755 --- a/bootstrap.sh +++ b/bootstrap.sh @@ -45,6 +45,7 @@ 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+" # Set up the proper GOPATH for go get below. source ./dev.env From 6232bc350f8e4100aa4246f1391ab18118b6a673 Mon Sep 17 00:00:00 2001 From: Jitendra Vaidya Date: Mon, 24 Dec 2018 21:08:26 +0000 Subject: [PATCH 008/115] Fix docs. Make sure that env.sh does not set VTTOP if already set. Signed-off-by: Jitendra Vaidya --- examples/local/README.md | 4 ++-- examples/local/env.sh | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/local/README.md b/examples/local/README.md index 5ea31be0f6d..245dbd4bb9e 100644 --- a/examples/local/README.md +++ b/examples/local/README.md @@ -5,6 +5,6 @@ local machine, which may be useful for experimentation. These scripts can also serve as a starting point for configuring Vitess into your preferred deployment strategy or toolset. -See the [Run Vitess Locally](http://vitess.io/getting-started/local-instance/) -guide for instructions on using these scripts. +See the [Run Vitess Locally](https://vitess.io/docs/tutorials/local/) +tutorial ("Start a Vitess cluster" section) for instructions on using these scripts. diff --git a/examples/local/env.sh b/examples/local/env.sh index dab3ae00be6..72398b2e1f2 100644 --- a/examples/local/env.sh +++ b/examples/local/env.sh @@ -16,7 +16,7 @@ hostname=`hostname -f` vtctld_web_port=15000 # Set up environment. -export VTTOP=$VTROOT/src/vitess.io/vitess +export VTTOP=${VTTOP-$VTROOT/src/vitess.io/vitess} # Try to find mysqld_safe on PATH. if [ -z "$VT_MYSQL_ROOT" ]; then From a60a42d4c5c7fcd0b48a92457e38e7baa0331ba4 Mon Sep 17 00:00:00 2001 From: Sugu Sougoumarane Date: Mon, 31 Dec 2018 13:21:17 -0800 Subject: [PATCH 009/115] build: fix broken build for other flavors There were a few regressions that got introduced due to recent changes: * MYSQL_FLAVOR got dropped from Dockerfile.mariadb. * New build.env did not get included in the docker builds. * CapabilityClientDeprecateEOF behaves differently for MySQL 5.7 vs older versions: MySQL 5.6 and MariaDB. For 5.7, the capability always comes back true, but it comes back as true or false for other versions. So, I just removed the check. Also removed column length check in one of the tests because they are not consistent across flavors. Signed-off-by: Sugu Sougoumarane --- docker/bootstrap/Dockerfile.common | 2 +- docker/bootstrap/Dockerfile.mariadb | 1 + go/mysql/endtoend/client_test.go | 5 ----- go/mysql/endtoend/query_test.go | 5 ----- go/mysql/endtoend/schema_test.go | 7 +++---- go/mysql/schema.go | 14 ++++++++------ 6 files changed, 13 insertions(+), 21 deletions(-) diff --git a/docker/bootstrap/Dockerfile.common b/docker/bootstrap/Dockerfile.common index 8db6dd15d5c..86f5ad7e34c 100644 --- a/docker/bootstrap/Dockerfile.common +++ b/docker/bootstrap/Dockerfile.common @@ -52,7 +52,7 @@ ENV PKG_CONFIG_PATH $VTROOT/lib ENV USER vitess # Copy files needed for bootstrap -COPY bootstrap.sh dev.env /vt/src/vitess.io/vitess/ +COPY bootstrap.sh dev.env build.env /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 diff --git a/docker/bootstrap/Dockerfile.mariadb b/docker/bootstrap/Dockerfile.mariadb index 437ea492771..bc76702faa9 100644 --- a/docker/bootstrap/Dockerfile.mariadb +++ b/docker/bootstrap/Dockerfile.mariadb @@ -9,5 +9,6 @@ RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-ins # Bootstrap Vitess WORKDIR /vt/src/vitess.io/vitess +ENV MYSQL_FLAVOR MariaDB USER vitess RUN ./bootstrap.sh diff --git a/go/mysql/endtoend/client_test.go b/go/mysql/endtoend/client_test.go index 0a190944952..569f4c9ae50 100644 --- a/go/mysql/endtoend/client_test.go +++ b/go/mysql/endtoend/client_test.go @@ -150,11 +150,6 @@ func doTestMultiResult(t *testing.T, disableClientDeprecateEOF bool) { expectNoError(t, err) defer conn.Close() - connParams.DisableClientDeprecateEOF = false - - expectFlag(t, "Negotiated ClientDeprecateEOF flag", (conn.Capabilities&mysql.CapabilityClientDeprecateEOF) != 0, !disableClientDeprecateEOF) - defer conn.Close() - qr, more, err := conn.ExecuteFetchMulti("select 1 from dual; set autocommit=1; select 1 from dual", 10, true) expectNoError(t, err) expectFlag(t, "ExecuteMultiFetch(multi result)", more, true) diff --git a/go/mysql/endtoend/query_test.go b/go/mysql/endtoend/query_test.go index 185a6de5627..8621c1bb877 100644 --- a/go/mysql/endtoend/query_test.go +++ b/go/mysql/endtoend/query_test.go @@ -247,11 +247,6 @@ func doTestWarnings(t *testing.T, disableClientDeprecateEOF bool) { expectNoError(t, err) defer conn.Close() - connParams.DisableClientDeprecateEOF = false - - expectFlag(t, "Negotiated ClientDeprecateEOF flag", (conn.Capabilities&mysql.CapabilityClientDeprecateEOF) != 0, !disableClientDeprecateEOF) - defer conn.Close() - result, err := conn.ExecuteFetch("create table a(id int, val int not null, primary key(id))", 0, false) if err != nil { t.Fatalf("create table failed: %v", err) diff --git a/go/mysql/endtoend/schema_test.go b/go/mysql/endtoend/schema_test.go index 3467a4ffbae..49ed2675472 100644 --- a/go/mysql/endtoend/schema_test.go +++ b/go/mysql/endtoend/schema_test.go @@ -52,10 +52,9 @@ func testDescribeTable(t *testing.T) { t.Fatal(err) } - // MariaDB has '81' instead of '90' of Extra ColumnLength. - // Just try it and see if it's the only difference. - if conn.IsMariaDB() && result.Fields[5].ColumnLength == 81 { - result.Fields[5].ColumnLength = 90 + // Zero-out the column lengths, because they can't be compared. + for i := range result.Fields { + result.Fields[i].ColumnLength = 0 } if !sqltypes.FieldsEqual(result.Fields, mysql.DescribeTableFields) { diff --git a/go/mysql/schema.go b/go/mysql/schema.go index 3fc122c29b3..6de7d42b6f7 100644 --- a/go/mysql/schema.go +++ b/go/mysql/schema.go @@ -34,6 +34,8 @@ import ( // DescribeTableFields contains the fields returned by a // 'describe ' command. They are validated by the testDescribeTable // test. +// Column lengths returned seem to differ between versions. So, we +// don't compare them. var DescribeTableFields = []*querypb.Field{ { Name: "Field", @@ -42,7 +44,7 @@ var DescribeTableFields = []*querypb.Field{ OrgTable: "COLUMNS", Database: "information_schema", OrgName: "COLUMN_NAME", - ColumnLength: 192, + ColumnLength: 0, Charset: 33, Flags: uint32(querypb.MySqlFlag_NOT_NULL_FLAG), }, @@ -53,7 +55,7 @@ var DescribeTableFields = []*querypb.Field{ OrgTable: "COLUMNS", Database: "information_schema", OrgName: "COLUMN_TYPE", - ColumnLength: 589815, + ColumnLength: 0, Charset: 33, Flags: uint32(querypb.MySqlFlag_NOT_NULL_FLAG | querypb.MySqlFlag_BLOB_FLAG), }, @@ -64,7 +66,7 @@ var DescribeTableFields = []*querypb.Field{ OrgTable: "COLUMNS", Database: "information_schema", OrgName: "IS_NULLABLE", - ColumnLength: 9, + ColumnLength: 0, Charset: 33, Flags: uint32(querypb.MySqlFlag_NOT_NULL_FLAG), }, @@ -75,7 +77,7 @@ var DescribeTableFields = []*querypb.Field{ OrgTable: "COLUMNS", Database: "information_schema", OrgName: "COLUMN_KEY", - ColumnLength: 9, + ColumnLength: 0, Charset: 33, Flags: uint32(querypb.MySqlFlag_NOT_NULL_FLAG), }, @@ -86,7 +88,7 @@ var DescribeTableFields = []*querypb.Field{ OrgTable: "COLUMNS", Database: "information_schema", OrgName: "COLUMN_DEFAULT", - ColumnLength: 589815, + ColumnLength: 0, Charset: 33, Flags: uint32(querypb.MySqlFlag_BLOB_FLAG), }, @@ -97,7 +99,7 @@ var DescribeTableFields = []*querypb.Field{ OrgTable: "COLUMNS", Database: "information_schema", OrgName: "EXTRA", - ColumnLength: 90, + ColumnLength: 0, Charset: 33, Flags: uint32(querypb.MySqlFlag_NOT_NULL_FLAG), }, From 6ecb6d3bb074a67cbc0b05d63a8155a792698081 Mon Sep 17 00:00:00 2001 From: Derek Perkins Date: Mon, 31 Dec 2018 16:00:45 -0700 Subject: [PATCH 010/115] docker: install wget into vttablet container Signed-off-by: Derek Perkins --- docker/k8s/vttablet/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker/k8s/vttablet/Dockerfile b/docker/k8s/vttablet/Dockerfile index 887a9f45894..9af272a84aa 100644 --- a/docker/k8s/vttablet/Dockerfile +++ b/docker/k8s/vttablet/Dockerfile @@ -5,7 +5,7 @@ FROM debian:stretch-slim # TODO: remove when https://github.com/vitessio/vitess/issues/3553 is fixed RUN apt-get update && \ apt-get upgrade -qq && \ - apt-get install mysql-client jq -qq --no-install-recommends && \ + apt-get install wget mysql-client jq -qq --no-install-recommends && \ apt-get autoremove && \ apt-get clean && \ rm -rf /var/lib/apt/lists/* From 92617b023612d8f3ca8098a1c64207abe7f09e09 Mon Sep 17 00:00:00 2001 From: Derek Perkins Date: Mon, 31 Dec 2018 16:02:12 -0700 Subject: [PATCH 011/115] helm: orchestrator refresh/forget in preStop hook Signed-off-by: Derek Perkins --- helm/vitess/templates/_vttablet.tpl | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/helm/vitess/templates/_vttablet.tpl b/helm/vitess/templates/_vttablet.tpl index 0c3e4643fc3..0d8753a78c3 100644 --- a/helm/vitess/templates/_vttablet.tpl +++ b/helm/vitess/templates/_vttablet.tpl @@ -345,6 +345,7 @@ spec: RETRY_COUNT=0 MAX_RETRY_COUNT=100000 + hostname=$(hostname -s) # retry reparenting until [ $DONE_REPARENTING ]; do @@ -368,10 +369,21 @@ spec: done +{{ if $orc.enabled }} + # tell orchestrator to refresh its view of this tablet + wget -q -S -O - "http://orchestrator.{{ $namespace }}/api/refresh/$hostname.vttablet/3306" +{{ end }} + # delete the current tablet from topology. Not strictly necessary, but helps to prevent # edge cases where there are two masters /vt/bin/vtctlclient ${VTCTL_EXTRA_FLAGS[@]} -server $VTCTLD_SVC DeleteTablet $current_alias + +{{ if $orc.enabled }} + # tell orchestrator to forget the tablet, to prevent confusion / race conditions while the tablet restarts + wget -q -S -O - "http://orchestrator.{{ $namespace }}/api/forget/$hostname.vttablet/3306" +{{ end }} + command: ["bash"] args: - "-c" From 87c0f0c6d4ab0f355a36f270c2207f842500a62c Mon Sep 17 00:00:00 2001 From: Derek Perkins Date: Mon, 31 Dec 2018 23:12:26 -0700 Subject: [PATCH 012/115] helm: downtime orchestrator in preStop reparent Signed-off-by: Derek Perkins --- helm/vitess/templates/_vttablet.tpl | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/helm/vitess/templates/_vttablet.tpl b/helm/vitess/templates/_vttablet.tpl index 0d8753a78c3..d526642ddf9 100644 --- a/helm/vitess/templates/_vttablet.tpl +++ b/helm/vitess/templates/_vttablet.tpl @@ -350,9 +350,19 @@ spec: # retry reparenting until [ $DONE_REPARENTING ]; do +{{ if $orc.enabled }} + # tell orchestrator to not attempt a recovery for 10 seconds while we are in the middle of reparenting + wget -q -S -O - "http://orchestrator.{{ $namespace }}/api/begin-downtime/$hostname.vttablet/3306/preStopHook/VitessPlannedReparent/10s" +{{ end }} + # reparent before shutting down /vt/bin/vtctlclient ${VTCTL_EXTRA_FLAGS[@]} -server $VTCTLD_SVC PlannedReparentShard -keyspace_shard={{ $keyspace.name }}/{{ $shard.name }} -avoid_master=$current_alias +{{ if $orc.enabled }} + # let orchestrator attempt recoveries now + wget -q -S -O - "http://orchestrator.{{ $namespace }}/api/end-downtime/$hostname.vttablet/3306" +{{ end }} + # if PlannedReparentShard succeeded, then don't retry if [ $? -eq 0 ]; then DONE_REPARENTING=true From 155095523d3e468ebc7c00dd3a9cf711aecfd0df Mon Sep 17 00:00:00 2001 From: Derek Perkins Date: Tue, 1 Jan 2019 16:16:24 -0700 Subject: [PATCH 013/115] helm: run orchestrator refresh before downtime end Signed-off-by: Derek Perkins --- helm/vitess/templates/_vttablet.tpl | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/helm/vitess/templates/_vttablet.tpl b/helm/vitess/templates/_vttablet.tpl index d526642ddf9..4f00a785677 100644 --- a/helm/vitess/templates/_vttablet.tpl +++ b/helm/vitess/templates/_vttablet.tpl @@ -359,6 +359,9 @@ spec: /vt/bin/vtctlclient ${VTCTL_EXTRA_FLAGS[@]} -server $VTCTLD_SVC PlannedReparentShard -keyspace_shard={{ $keyspace.name }}/{{ $shard.name }} -avoid_master=$current_alias {{ if $orc.enabled }} + # tell orchestrator to refresh its view of this tablet + wget -q -S -O - "http://orchestrator.{{ $namespace }}/api/refresh/$hostname.vttablet/3306" + # let orchestrator attempt recoveries now wget -q -S -O - "http://orchestrator.{{ $namespace }}/api/end-downtime/$hostname.vttablet/3306" {{ end }} @@ -379,11 +382,6 @@ spec: done -{{ if $orc.enabled }} - # tell orchestrator to refresh its view of this tablet - wget -q -S -O - "http://orchestrator.{{ $namespace }}/api/refresh/$hostname.vttablet/3306" -{{ end }} - # delete the current tablet from topology. Not strictly necessary, but helps to prevent # edge cases where there are two masters /vt/bin/vtctlclient ${VTCTL_EXTRA_FLAGS[@]} -server $VTCTLD_SVC DeleteTablet $current_alias From 71a2b0c644485649d43e5a5142e760aa1922b3c2 Mon Sep 17 00:00:00 2001 From: Derek Perkins Date: Tue, 1 Jan 2019 16:30:57 -0700 Subject: [PATCH 014/115] helm: bump chart version to 1.0.4 Signed-off-by: Derek Perkins --- helm/release.sh | 2 +- helm/vitess/CHANGELOG.md | 9 +++++++++ helm/vitess/Chart.yaml | 2 +- helm/vitess/templates/_orchestrator.tpl | 4 ++-- helm/vitess/templates/_pmm.tpl | 2 +- helm/vitess/templates/_vttablet.tpl | 8 ++++---- helm/vitess/values.yaml | 10 +++++----- 7 files changed, 23 insertions(+), 14 deletions(-) diff --git a/helm/release.sh b/helm/release.sh index 7e0f3a1642a..a9f1a17d646 100755 --- a/helm/release.sh +++ b/helm/release.sh @@ -1,6 +1,6 @@ #!/bin/bash -version_tag=1.0.3 +version_tag=1.0.4 docker pull vitess/k8s:latest docker tag vitess/k8s:latest vitess/k8s:helm-$version_tag diff --git a/helm/vitess/CHANGELOG.md b/helm/vitess/CHANGELOG.md index 992437e922f..aca78299575 100644 --- a/helm/vitess/CHANGELOG.md +++ b/helm/vitess/CHANGELOG.md @@ -1,3 +1,12 @@ +## 1.0.4 - 2019-01-01 + +### Changes +* Use the [Orchestrator API](https://github.com/github/orchestrator/blob/master/docs/using-the-web-api.md) +to call `begin-downtime` before running `PlannedReparentShard` in the `preStopHook`, to make sure that Orchestrator +doesn't try to run an external failover while Vitess is reparenting. When it is complete, it calls `end-downtime`. +Also call `forget` on the instance after calling `vtctlclient DeleteTablet`. It will be rediscovered if/when +the tablet comes back up. This eliminates most possible race conditions that could cause split brain. + ## 1.0.3 - 2018-12-20 ### Changes diff --git a/helm/vitess/Chart.yaml b/helm/vitess/Chart.yaml index b65208e7bf0..021aa8a39bd 100644 --- a/helm/vitess/Chart.yaml +++ b/helm/vitess/Chart.yaml @@ -1,6 +1,6 @@ apiVersion: v1 name: vitess -version: 1.0.3 +version: 1.0.4 description: Single-Chart Vitess Cluster keywords: - vitess diff --git a/helm/vitess/templates/_orchestrator.tpl b/helm/vitess/templates/_orchestrator.tpl index d0babc41a59..99f88de1e21 100644 --- a/helm/vitess/templates/_orchestrator.tpl +++ b/helm/vitess/templates/_orchestrator.tpl @@ -123,7 +123,7 @@ spec: value: "15999" - name: recovery-log - image: vitess/logtail:helm-1.0.3 + image: vitess/logtail:helm-1.0.4 imagePullPolicy: IfNotPresent env: - name: TAIL_FILEPATH @@ -133,7 +133,7 @@ spec: mountPath: /tmp - name: audit-log - image: vitess/logtail:helm-1.0.3 + image: vitess/logtail:helm-1.0.4 imagePullPolicy: IfNotPresent env: - name: TAIL_FILEPATH diff --git a/helm/vitess/templates/_pmm.tpl b/helm/vitess/templates/_pmm.tpl index 9ff20aa94a5..32e8d70fce8 100644 --- a/helm/vitess/templates/_pmm.tpl +++ b/helm/vitess/templates/_pmm.tpl @@ -218,7 +218,7 @@ spec: trap : TERM INT; sleep infinity & wait - name: pmm-client-metrics-log - image: vitess/logtail:helm-1.0.3 + image: vitess/logtail:helm-1.0.4 imagePullPolicy: IfNotPresent env: - name: TAIL_FILEPATH diff --git a/helm/vitess/templates/_vttablet.tpl b/helm/vitess/templates/_vttablet.tpl index 4f00a785677..636393efa34 100644 --- a/helm/vitess/templates/_vttablet.tpl +++ b/helm/vitess/templates/_vttablet.tpl @@ -533,7 +533,7 @@ spec: {{ define "cont-logrotate" }} - name: logrotate - image: vitess/logrotate:helm-1.0.3 + image: vitess/logrotate:helm-1.0.4 imagePullPolicy: IfNotPresent volumeMounts: - name: vtdataroot @@ -547,7 +547,7 @@ spec: {{ define "cont-mysql-errorlog" }} - name: error-log - image: vitess/logtail:helm-1.0.3 + image: vitess/logtail:helm-1.0.4 imagePullPolicy: IfNotPresent env: @@ -565,7 +565,7 @@ spec: {{ define "cont-mysql-slowlog" }} - name: slow-log - image: vitess/logtail:helm-1.0.3 + image: vitess/logtail:helm-1.0.4 imagePullPolicy: IfNotPresent env: @@ -583,7 +583,7 @@ spec: {{ define "cont-mysql-generallog" }} - name: general-log - image: vitess/logtail:helm-1.0.3 + image: vitess/logtail:helm-1.0.4 imagePullPolicy: IfNotPresent env: diff --git a/helm/vitess/values.yaml b/helm/vitess/values.yaml index 03d200e2a71..9d9c9a371c9 100644 --- a/helm/vitess/values.yaml +++ b/helm/vitess/values.yaml @@ -177,7 +177,7 @@ etcd: # Default values for vtctld resources defined in 'topology' vtctld: serviceType: ClusterIP - vitessTag: helm-1.0.3 + vitessTag: helm-1.0.4 resources: # requests: # cpu: 100m @@ -188,7 +188,7 @@ vtctld: # Default values for vtgate resources defined in 'topology' vtgate: serviceType: ClusterIP - vitessTag: helm-1.0.3 + vitessTag: helm-1.0.4 resources: # requests: # cpu: 500m @@ -207,13 +207,13 @@ vtgate: # Default values for vtctlclient resources defined in 'topology' vtctlclient: - vitessTag: helm-1.0.3 + vitessTag: helm-1.0.4 extraFlags: {} secrets: [] # secrets are mounted under /vt/usersecrets/{secretname} # Default values for vtworker resources defined in 'jobs' vtworker: - vitessTag: helm-1.0.3 + vitessTag: helm-1.0.4 extraFlags: {} resources: # requests: @@ -224,7 +224,7 @@ vtworker: # Default values for vttablet resources defined in 'topology' vttablet: - vitessTag: helm-1.0.3 + vitessTag: helm-1.0.4 # valid values are # - mysql56 (for MySQL 8.0) From fea4e1db6a74d363686beb4af909ec798fecdd19 Mon Sep 17 00:00:00 2001 From: Scott Lanning Date: Wed, 2 Jan 2019 17:31:38 +0100 Subject: [PATCH 015/115] fix a bootstrap.sh error The error from bootstrap.sh was: "./dev.env: line 23: source: build.env: file not found". I think it broke in commit 157ebf5830e6c . Not sure if this is the right fix, but it worked for me (bootstrap.sh does `source ./build.env`, so it's probably ok). Signed-off-by: Scott Lanning --- dev.env | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev.env b/dev.env index 5e0b69b78c2..e31c16167e2 100644 --- a/dev.env +++ b/dev.env @@ -20,7 +20,7 @@ # to build a package to be run under a POSIX shell so non-POSIX # syntax will break that as dev.env will not be sourced by bash.. -source build.env +source ./build.env export GOTOP=$VTTOP/go export PYTOP=$VTTOP/py From e0133e43b88325f7a970b1a49a13986550c6a391 Mon Sep 17 00:00:00 2001 From: Rafael Chacon Date: Wed, 2 Jan 2019 15:22:57 -0800 Subject: [PATCH 016/115] Regenerates protobuf files using protoc 3.6.1 Signed-off-by: Rafael Chacon --- go/vt/proto/automation/automation.pb.go | 26 +-- .../automationservice/automationservice.pb.go | 4 +- go/vt/proto/binlogdata/binlogdata.pb.go | 22 +- go/vt/proto/binlogservice/binlogservice.pb.go | 4 +- go/vt/proto/logutil/logutil.pb.go | 10 +- go/vt/proto/mysqlctl/mysqlctl.pb.go | 24 +-- go/vt/proto/query/query.pb.go | 144 ++++++------- go/vt/proto/queryservice/queryservice.pb.go | 4 +- .../replicationdata/replicationdata.pb.go | 6 +- go/vt/proto/tableacl/tableacl.pb.go | 8 +- .../tabletmanagerdata/tabletmanagerdata.pb.go | 176 ++++++++-------- .../tabletmanagerservice.pb.go | 4 +- go/vt/proto/throttlerdata/throttlerdata.pb.go | 26 +-- .../throttlerservice/throttlerservice.pb.go | 4 +- go/vt/proto/topodata/topodata.pb.go | 40 ++-- go/vt/proto/vschema/vschema.pb.go | 18 +- go/vt/proto/vtctldata/vtctldata.pb.go | 8 +- go/vt/proto/vtctlservice/vtctlservice.pb.go | 4 +- go/vt/proto/vtgate/vtgate.pb.go | 106 +++++----- go/vt/proto/vtgateservice/vtgateservice.pb.go | 4 +- go/vt/proto/vtrpc/vtrpc.pb.go | 12 +- go/vt/proto/vttest/vttest.pb.go | 10 +- go/vt/proto/vtworkerdata/vtworkerdata.pb.go | 8 +- .../vtworkerservice/vtworkerservice.pb.go | 4 +- go/vt/proto/workflow/workflow.pb.go | 14 +- py/vtproto/topodata_pb2.py | 196 +++++++++--------- 26 files changed, 441 insertions(+), 445 deletions(-) diff --git a/go/vt/proto/automation/automation.pb.go b/go/vt/proto/automation/automation.pb.go index 9cfe471fe11..e810986daee 100644 --- a/go/vt/proto/automation/automation.pb.go +++ b/go/vt/proto/automation/automation.pb.go @@ -44,7 +44,7 @@ func (x ClusterOperationState) String() string { return proto.EnumName(ClusterOperationState_name, int32(x)) } func (ClusterOperationState) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_automation_7092712054bc689e, []int{0} + return fileDescriptor_automation_4d7d55680fa173cc, []int{0} } type TaskState int32 @@ -73,7 +73,7 @@ func (x TaskState) String() string { return proto.EnumName(TaskState_name, int32(x)) } func (TaskState) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_automation_7092712054bc689e, []int{1} + return fileDescriptor_automation_4d7d55680fa173cc, []int{1} } type ClusterOperation struct { @@ -93,7 +93,7 @@ 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_7092712054bc689e, []int{0} + return fileDescriptor_automation_4d7d55680fa173cc, []int{0} } func (m *ClusterOperation) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ClusterOperation.Unmarshal(m, b) @@ -155,7 +155,7 @@ 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_7092712054bc689e, []int{1} + return fileDescriptor_automation_4d7d55680fa173cc, []int{1} } func (m *TaskContainer) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_TaskContainer.Unmarshal(m, b) @@ -210,7 +210,7 @@ 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_7092712054bc689e, []int{2} + return fileDescriptor_automation_4d7d55680fa173cc, []int{2} } func (m *Task) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Task.Unmarshal(m, b) @@ -284,7 +284,7 @@ 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_7092712054bc689e, []int{3} + return fileDescriptor_automation_4d7d55680fa173cc, []int{3} } func (m *EnqueueClusterOperationRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_EnqueueClusterOperationRequest.Unmarshal(m, b) @@ -329,7 +329,7 @@ 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_7092712054bc689e, []int{4} + return fileDescriptor_automation_4d7d55680fa173cc, []int{4} } func (m *EnqueueClusterOperationResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_EnqueueClusterOperationResponse.Unmarshal(m, b) @@ -367,7 +367,7 @@ 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_7092712054bc689e, []int{5} + return fileDescriptor_automation_4d7d55680fa173cc, []int{5} } func (m *GetClusterOperationStateRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_GetClusterOperationStateRequest.Unmarshal(m, b) @@ -405,7 +405,7 @@ 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_7092712054bc689e, []int{6} + return fileDescriptor_automation_4d7d55680fa173cc, []int{6} } func (m *GetClusterOperationStateResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_GetClusterOperationStateResponse.Unmarshal(m, b) @@ -443,7 +443,7 @@ 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_7092712054bc689e, []int{7} + return fileDescriptor_automation_4d7d55680fa173cc, []int{7} } func (m *GetClusterOperationDetailsRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_GetClusterOperationDetailsRequest.Unmarshal(m, b) @@ -482,7 +482,7 @@ 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_7092712054bc689e, []int{8} + return fileDescriptor_automation_4d7d55680fa173cc, []int{8} } func (m *GetClusterOperationDetailsResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_GetClusterOperationDetailsResponse.Unmarshal(m, b) @@ -525,9 +525,9 @@ func init() { proto.RegisterEnum("automation.TaskState", TaskState_name, TaskState_value) } -func init() { proto.RegisterFile("automation.proto", fileDescriptor_automation_7092712054bc689e) } +func init() { proto.RegisterFile("automation.proto", fileDescriptor_automation_4d7d55680fa173cc) } -var fileDescriptor_automation_7092712054bc689e = []byte{ +var fileDescriptor_automation_4d7d55680fa173cc = []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 e3c00ceddd0..61ac349af85 100644 --- a/go/vt/proto/automationservice/automationservice.pb.go +++ b/go/vt/proto/automationservice/automationservice.pb.go @@ -136,10 +136,10 @@ var _Automation_serviceDesc = grpc.ServiceDesc{ } func init() { - proto.RegisterFile("automationservice.proto", fileDescriptor_automationservice_42ff8d484b987c6f) + proto.RegisterFile("automationservice.proto", fileDescriptor_automationservice_5369cb995212ce22) } -var fileDescriptor_automationservice_42ff8d484b987c6f = []byte{ +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, diff --git a/go/vt/proto/binlogdata/binlogdata.pb.go b/go/vt/proto/binlogdata/binlogdata.pb.go index c520a6a4f7a..5214ce5f4d4 100644 --- a/go/vt/proto/binlogdata/binlogdata.pb.go +++ b/go/vt/proto/binlogdata/binlogdata.pb.go @@ -65,7 +65,7 @@ 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_ac14f15f6b19a931, []int{1, 0, 0} + return fileDescriptor_binlogdata_599cd600856cd9fe, []int{1, 0, 0} } // Charset is the per-statement charset info from a QUERY_EVENT binlog entry. @@ -85,7 +85,7 @@ 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_ac14f15f6b19a931, []int{0} + return fileDescriptor_binlogdata_599cd600856cd9fe, []int{0} } func (m *Charset) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Charset.Unmarshal(m, b) @@ -142,7 +142,7 @@ 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_ac14f15f6b19a931, []int{1} + return fileDescriptor_binlogdata_599cd600856cd9fe, []int{1} } func (m *BinlogTransaction) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_BinlogTransaction.Unmarshal(m, b) @@ -192,7 +192,7 @@ 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_ac14f15f6b19a931, []int{1, 0} + return fileDescriptor_binlogdata_599cd600856cd9fe, []int{1, 0} } func (m *BinlogTransaction_Statement) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_BinlogTransaction_Statement.Unmarshal(m, b) @@ -250,7 +250,7 @@ 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_ac14f15f6b19a931, []int{2} + return fileDescriptor_binlogdata_599cd600856cd9fe, []int{2} } func (m *StreamKeyRangeRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_StreamKeyRangeRequest.Unmarshal(m, b) @@ -303,7 +303,7 @@ 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_ac14f15f6b19a931, []int{3} + return fileDescriptor_binlogdata_599cd600856cd9fe, []int{3} } func (m *StreamKeyRangeResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_StreamKeyRangeResponse.Unmarshal(m, b) @@ -347,7 +347,7 @@ 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_ac14f15f6b19a931, []int{4} + return fileDescriptor_binlogdata_599cd600856cd9fe, []int{4} } func (m *StreamTablesRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_StreamTablesRequest.Unmarshal(m, b) @@ -400,7 +400,7 @@ 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_ac14f15f6b19a931, []int{5} + return fileDescriptor_binlogdata_599cd600856cd9fe, []int{5} } func (m *StreamTablesResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_StreamTablesResponse.Unmarshal(m, b) @@ -450,7 +450,7 @@ 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_ac14f15f6b19a931, []int{6} + return fileDescriptor_binlogdata_599cd600856cd9fe, []int{6} } func (m *BinlogSource) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_BinlogSource.Unmarshal(m, b) @@ -517,9 +517,9 @@ func init() { proto.RegisterEnum("binlogdata.BinlogTransaction_Statement_Category", BinlogTransaction_Statement_Category_name, BinlogTransaction_Statement_Category_value) } -func init() { proto.RegisterFile("binlogdata.proto", fileDescriptor_binlogdata_ac14f15f6b19a931) } +func init() { proto.RegisterFile("binlogdata.proto", fileDescriptor_binlogdata_599cd600856cd9fe) } -var fileDescriptor_binlogdata_ac14f15f6b19a931 = []byte{ +var fileDescriptor_binlogdata_599cd600856cd9fe = []byte{ // 640 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x54, 0xcd, 0x6e, 0xda, 0x4a, 0x14, 0xbe, 0xc6, 0x40, 0xec, 0xe3, 0xdc, 0x64, 0x98, 0xfc, 0x08, 0x21, 0x5d, 0x09, 0xb1, 0x09, diff --git a/go/vt/proto/binlogservice/binlogservice.pb.go b/go/vt/proto/binlogservice/binlogservice.pb.go index 164dddef669..790a92f4a2b 100644 --- a/go/vt/proto/binlogservice/binlogservice.pb.go +++ b/go/vt/proto/binlogservice/binlogservice.pb.go @@ -191,9 +191,9 @@ var _UpdateStream_serviceDesc = grpc.ServiceDesc{ Metadata: "binlogservice.proto", } -func init() { proto.RegisterFile("binlogservice.proto", fileDescriptor_binlogservice_0e1eb8b2f97a2dc1) } +func init() { proto.RegisterFile("binlogservice.proto", fileDescriptor_binlogservice_bfebf84e565603b8) } -var fileDescriptor_binlogservice_0e1eb8b2f97a2dc1 = []byte{ +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, diff --git a/go/vt/proto/logutil/logutil.pb.go b/go/vt/proto/logutil/logutil.pb.go index 7b1c092c26b..f1202173262 100644 --- a/go/vt/proto/logutil/logutil.pb.go +++ b/go/vt/proto/logutil/logutil.pb.go @@ -49,7 +49,7 @@ func (x Level) String() string { return proto.EnumName(Level_name, int32(x)) } func (Level) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_logutil_39c26af5691dd7cd, []int{0} + return fileDescriptor_logutil_1922c06158165cc5, []int{0} } // Time represents a time stamp in nanoseconds. In go, use logutil library @@ -66,7 +66,7 @@ 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_39c26af5691dd7cd, []int{0} + return fileDescriptor_logutil_1922c06158165cc5, []int{0} } func (m *Time) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Time.Unmarshal(m, b) @@ -116,7 +116,7 @@ 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_39c26af5691dd7cd, []int{1} + return fileDescriptor_logutil_1922c06158165cc5, []int{1} } func (m *Event) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Event.Unmarshal(m, b) @@ -177,9 +177,9 @@ func init() { proto.RegisterEnum("logutil.Level", Level_name, Level_value) } -func init() { proto.RegisterFile("logutil.proto", fileDescriptor_logutil_39c26af5691dd7cd) } +func init() { proto.RegisterFile("logutil.proto", fileDescriptor_logutil_1922c06158165cc5) } -var fileDescriptor_logutil_39c26af5691dd7cd = []byte{ +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, diff --git a/go/vt/proto/mysqlctl/mysqlctl.pb.go b/go/vt/proto/mysqlctl/mysqlctl.pb.go index f499dce3cd4..b75568fd4b2 100644 --- a/go/vt/proto/mysqlctl/mysqlctl.pb.go +++ b/go/vt/proto/mysqlctl/mysqlctl.pb.go @@ -34,7 +34,7 @@ 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_dc3430948664e7fa, []int{0} + return fileDescriptor_mysqlctl_6cf72a3618d6fe7c, []int{0} } func (m *StartRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_StartRequest.Unmarshal(m, b) @@ -71,7 +71,7 @@ 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_dc3430948664e7fa, []int{1} + return fileDescriptor_mysqlctl_6cf72a3618d6fe7c, []int{1} } func (m *StartResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_StartResponse.Unmarshal(m, b) @@ -102,7 +102,7 @@ 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_dc3430948664e7fa, []int{2} + return fileDescriptor_mysqlctl_6cf72a3618d6fe7c, []int{2} } func (m *ShutdownRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ShutdownRequest.Unmarshal(m, b) @@ -139,7 +139,7 @@ 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_dc3430948664e7fa, []int{3} + return fileDescriptor_mysqlctl_6cf72a3618d6fe7c, []int{3} } func (m *ShutdownResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ShutdownResponse.Unmarshal(m, b) @@ -169,7 +169,7 @@ 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_dc3430948664e7fa, []int{4} + return fileDescriptor_mysqlctl_6cf72a3618d6fe7c, []int{4} } func (m *RunMysqlUpgradeRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_RunMysqlUpgradeRequest.Unmarshal(m, b) @@ -199,7 +199,7 @@ 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_dc3430948664e7fa, []int{5} + return fileDescriptor_mysqlctl_6cf72a3618d6fe7c, []int{5} } func (m *RunMysqlUpgradeResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_RunMysqlUpgradeResponse.Unmarshal(m, b) @@ -229,7 +229,7 @@ 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_dc3430948664e7fa, []int{6} + return fileDescriptor_mysqlctl_6cf72a3618d6fe7c, []int{6} } func (m *ReinitConfigRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ReinitConfigRequest.Unmarshal(m, b) @@ -259,7 +259,7 @@ 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_dc3430948664e7fa, []int{7} + return fileDescriptor_mysqlctl_6cf72a3618d6fe7c, []int{7} } func (m *ReinitConfigResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ReinitConfigResponse.Unmarshal(m, b) @@ -289,7 +289,7 @@ 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_dc3430948664e7fa, []int{8} + return fileDescriptor_mysqlctl_6cf72a3618d6fe7c, []int{8} } func (m *RefreshConfigRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_RefreshConfigRequest.Unmarshal(m, b) @@ -319,7 +319,7 @@ 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_dc3430948664e7fa, []int{9} + return fileDescriptor_mysqlctl_6cf72a3618d6fe7c, []int{9} } func (m *RefreshConfigResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_RefreshConfigResponse.Unmarshal(m, b) @@ -556,9 +556,9 @@ var _MysqlCtl_serviceDesc = grpc.ServiceDesc{ Metadata: "mysqlctl.proto", } -func init() { proto.RegisterFile("mysqlctl.proto", fileDescriptor_mysqlctl_dc3430948664e7fa) } +func init() { proto.RegisterFile("mysqlctl.proto", fileDescriptor_mysqlctl_6cf72a3618d6fe7c) } -var fileDescriptor_mysqlctl_dc3430948664e7fa = []byte{ +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, diff --git a/go/vt/proto/query/query.pb.go b/go/vt/proto/query/query.pb.go index 483b516fef4..1176ca07bd4 100644 --- a/go/vt/proto/query/query.pb.go +++ b/go/vt/proto/query/query.pb.go @@ -95,7 +95,7 @@ func (x MySqlFlag) String() string { return proto.EnumName(MySqlFlag_name, int32(x)) } func (MySqlFlag) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_query_9111254583ad7475, []int{0} + return fileDescriptor_query_1e32bb78b6357529, []int{0} } // Flag allows us to qualify types by their common properties. @@ -134,7 +134,7 @@ func (x Flag) String() string { return proto.EnumName(Flag_name, int32(x)) } func (Flag) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_query_9111254583ad7475, []int{1} + return fileDescriptor_query_1e32bb78b6357529, []int{1} } // Type defines the various supported data types in bind vars @@ -315,7 +315,7 @@ func (x Type) String() string { return proto.EnumName(Type_name, int32(x)) } func (Type) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_query_9111254583ad7475, []int{2} + return fileDescriptor_query_1e32bb78b6357529, []int{2} } // TransactionState represents the state of a distributed transaction. @@ -345,7 +345,7 @@ func (x TransactionState) String() string { return proto.EnumName(TransactionState_name, int32(x)) } func (TransactionState) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_query_9111254583ad7475, []int{3} + return fileDescriptor_query_1e32bb78b6357529, []int{3} } type ExecuteOptions_IncludedFields int32 @@ -371,7 +371,7 @@ func (x ExecuteOptions_IncludedFields) String() string { return proto.EnumName(ExecuteOptions_IncludedFields_name, int32(x)) } func (ExecuteOptions_IncludedFields) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_query_9111254583ad7475, []int{6, 0} + return fileDescriptor_query_1e32bb78b6357529, []int{6, 0} } type ExecuteOptions_Workload int32 @@ -400,7 +400,7 @@ func (x ExecuteOptions_Workload) String() string { return proto.EnumName(ExecuteOptions_Workload_name, int32(x)) } func (ExecuteOptions_Workload) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_query_9111254583ad7475, []int{6, 1} + return fileDescriptor_query_1e32bb78b6357529, []int{6, 1} } type ExecuteOptions_TransactionIsolation int32 @@ -432,7 +432,7 @@ func (x ExecuteOptions_TransactionIsolation) String() string { return proto.EnumName(ExecuteOptions_TransactionIsolation_name, int32(x)) } func (ExecuteOptions_TransactionIsolation) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_query_9111254583ad7475, []int{6, 2} + return fileDescriptor_query_1e32bb78b6357529, []int{6, 2} } // The category of one statement. @@ -459,7 +459,7 @@ 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_9111254583ad7475, []int{12, 0, 0} + return fileDescriptor_query_1e32bb78b6357529, []int{12, 0, 0} } type SplitQueryRequest_Algorithm int32 @@ -482,7 +482,7 @@ func (x SplitQueryRequest_Algorithm) String() string { return proto.EnumName(SplitQueryRequest_Algorithm_name, int32(x)) } func (SplitQueryRequest_Algorithm) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_query_9111254583ad7475, []int{50, 0} + return fileDescriptor_query_1e32bb78b6357529, []int{50, 0} } // Target describes what the client expects the tablet is. @@ -503,7 +503,7 @@ 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_9111254583ad7475, []int{0} + return fileDescriptor_query_1e32bb78b6357529, []int{0} } func (m *Target) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Target.Unmarshal(m, b) @@ -571,7 +571,7 @@ 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_9111254583ad7475, []int{1} + return fileDescriptor_query_1e32bb78b6357529, []int{1} } func (m *VTGateCallerID) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_VTGateCallerID.Unmarshal(m, b) @@ -627,7 +627,7 @@ 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_9111254583ad7475, []int{2} + return fileDescriptor_query_1e32bb78b6357529, []int{2} } func (m *EventToken) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_EventToken.Unmarshal(m, b) @@ -681,7 +681,7 @@ 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_9111254583ad7475, []int{3} + return fileDescriptor_query_1e32bb78b6357529, []int{3} } func (m *Value) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Value.Unmarshal(m, b) @@ -730,7 +730,7 @@ 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_9111254583ad7475, []int{4} + return fileDescriptor_query_1e32bb78b6357529, []int{4} } func (m *BindVariable) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_BindVariable.Unmarshal(m, b) @@ -787,7 +787,7 @@ 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_9111254583ad7475, []int{5} + return fileDescriptor_query_1e32bb78b6357529, []int{5} } func (m *BoundQuery) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_BoundQuery.Unmarshal(m, b) @@ -861,7 +861,7 @@ 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_9111254583ad7475, []int{6} + return fileDescriptor_query_1e32bb78b6357529, []int{6} } func (m *ExecuteOptions) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ExecuteOptions.Unmarshal(m, b) @@ -967,7 +967,7 @@ 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_9111254583ad7475, []int{7} + return fileDescriptor_query_1e32bb78b6357529, []int{7} } func (m *Field) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Field.Unmarshal(m, b) @@ -1075,7 +1075,7 @@ 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_9111254583ad7475, []int{8} + return fileDescriptor_query_1e32bb78b6357529, []int{8} } func (m *Row) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Row.Unmarshal(m, b) @@ -1127,7 +1127,7 @@ 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_9111254583ad7475, []int{9} + return fileDescriptor_query_1e32bb78b6357529, []int{9} } func (m *ResultExtras) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ResultExtras.Unmarshal(m, b) @@ -1185,7 +1185,7 @@ 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_9111254583ad7475, []int{10} + return fileDescriptor_query_1e32bb78b6357529, []int{10} } func (m *QueryResult) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_QueryResult.Unmarshal(m, b) @@ -1254,7 +1254,7 @@ 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_9111254583ad7475, []int{11} + return fileDescriptor_query_1e32bb78b6357529, []int{11} } func (m *QueryWarning) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_QueryWarning.Unmarshal(m, b) @@ -1305,7 +1305,7 @@ 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_9111254583ad7475, []int{12} + return fileDescriptor_query_1e32bb78b6357529, []int{12} } func (m *StreamEvent) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_StreamEvent.Unmarshal(m, b) @@ -1358,7 +1358,7 @@ 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_9111254583ad7475, []int{12, 0} + return fileDescriptor_query_1e32bb78b6357529, []int{12, 0} } func (m *StreamEvent_Statement) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_StreamEvent_Statement.Unmarshal(m, b) @@ -1430,7 +1430,7 @@ 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_9111254583ad7475, []int{13} + return fileDescriptor_query_1e32bb78b6357529, []int{13} } func (m *ExecuteRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ExecuteRequest.Unmarshal(m, b) @@ -1504,7 +1504,7 @@ 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_9111254583ad7475, []int{14} + return fileDescriptor_query_1e32bb78b6357529, []int{14} } func (m *ExecuteResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ExecuteResponse.Unmarshal(m, b) @@ -1548,7 +1548,7 @@ 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_9111254583ad7475, []int{15} + return fileDescriptor_query_1e32bb78b6357529, []int{15} } func (m *ResultWithError) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ResultWithError.Unmarshal(m, b) @@ -1600,7 +1600,7 @@ 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_9111254583ad7475, []int{16} + return fileDescriptor_query_1e32bb78b6357529, []int{16} } func (m *ExecuteBatchRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ExecuteBatchRequest.Unmarshal(m, b) @@ -1681,7 +1681,7 @@ 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_9111254583ad7475, []int{17} + return fileDescriptor_query_1e32bb78b6357529, []int{17} } func (m *ExecuteBatchResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ExecuteBatchResponse.Unmarshal(m, b) @@ -1724,7 +1724,7 @@ 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_9111254583ad7475, []int{18} + return fileDescriptor_query_1e32bb78b6357529, []int{18} } func (m *StreamExecuteRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_StreamExecuteRequest.Unmarshal(m, b) @@ -1791,7 +1791,7 @@ 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_9111254583ad7475, []int{19} + return fileDescriptor_query_1e32bb78b6357529, []int{19} } func (m *StreamExecuteResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_StreamExecuteResponse.Unmarshal(m, b) @@ -1833,7 +1833,7 @@ 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_9111254583ad7475, []int{20} + return fileDescriptor_query_1e32bb78b6357529, []int{20} } func (m *BeginRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_BeginRequest.Unmarshal(m, b) @@ -1893,7 +1893,7 @@ 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_9111254583ad7475, []int{21} + return fileDescriptor_query_1e32bb78b6357529, []int{21} } func (m *BeginResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_BeginResponse.Unmarshal(m, b) @@ -1935,7 +1935,7 @@ 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_9111254583ad7475, []int{22} + return fileDescriptor_query_1e32bb78b6357529, []int{22} } func (m *CommitRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_CommitRequest.Unmarshal(m, b) @@ -1994,7 +1994,7 @@ 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_9111254583ad7475, []int{23} + return fileDescriptor_query_1e32bb78b6357529, []int{23} } func (m *CommitResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_CommitResponse.Unmarshal(m, b) @@ -2029,7 +2029,7 @@ 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_9111254583ad7475, []int{24} + return fileDescriptor_query_1e32bb78b6357529, []int{24} } func (m *RollbackRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_RollbackRequest.Unmarshal(m, b) @@ -2088,7 +2088,7 @@ 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_9111254583ad7475, []int{25} + return fileDescriptor_query_1e32bb78b6357529, []int{25} } func (m *RollbackResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_RollbackResponse.Unmarshal(m, b) @@ -2124,7 +2124,7 @@ 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_9111254583ad7475, []int{26} + return fileDescriptor_query_1e32bb78b6357529, []int{26} } func (m *PrepareRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_PrepareRequest.Unmarshal(m, b) @@ -2190,7 +2190,7 @@ 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_9111254583ad7475, []int{27} + return fileDescriptor_query_1e32bb78b6357529, []int{27} } func (m *PrepareResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_PrepareResponse.Unmarshal(m, b) @@ -2225,7 +2225,7 @@ 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_9111254583ad7475, []int{28} + return fileDescriptor_query_1e32bb78b6357529, []int{28} } func (m *CommitPreparedRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_CommitPreparedRequest.Unmarshal(m, b) @@ -2284,7 +2284,7 @@ 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_9111254583ad7475, []int{29} + return fileDescriptor_query_1e32bb78b6357529, []int{29} } func (m *CommitPreparedResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_CommitPreparedResponse.Unmarshal(m, b) @@ -2320,7 +2320,7 @@ 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_9111254583ad7475, []int{30} + return fileDescriptor_query_1e32bb78b6357529, []int{30} } func (m *RollbackPreparedRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_RollbackPreparedRequest.Unmarshal(m, b) @@ -2386,7 +2386,7 @@ 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_9111254583ad7475, []int{31} + return fileDescriptor_query_1e32bb78b6357529, []int{31} } func (m *RollbackPreparedResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_RollbackPreparedResponse.Unmarshal(m, b) @@ -2422,7 +2422,7 @@ 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_9111254583ad7475, []int{32} + return fileDescriptor_query_1e32bb78b6357529, []int{32} } func (m *CreateTransactionRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_CreateTransactionRequest.Unmarshal(m, b) @@ -2488,7 +2488,7 @@ 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_9111254583ad7475, []int{33} + return fileDescriptor_query_1e32bb78b6357529, []int{33} } func (m *CreateTransactionResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_CreateTransactionResponse.Unmarshal(m, b) @@ -2524,7 +2524,7 @@ 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_9111254583ad7475, []int{34} + return fileDescriptor_query_1e32bb78b6357529, []int{34} } func (m *StartCommitRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_StartCommitRequest.Unmarshal(m, b) @@ -2590,7 +2590,7 @@ 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_9111254583ad7475, []int{35} + return fileDescriptor_query_1e32bb78b6357529, []int{35} } func (m *StartCommitResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_StartCommitResponse.Unmarshal(m, b) @@ -2626,7 +2626,7 @@ 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_9111254583ad7475, []int{36} + return fileDescriptor_query_1e32bb78b6357529, []int{36} } func (m *SetRollbackRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_SetRollbackRequest.Unmarshal(m, b) @@ -2692,7 +2692,7 @@ 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_9111254583ad7475, []int{37} + return fileDescriptor_query_1e32bb78b6357529, []int{37} } func (m *SetRollbackResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_SetRollbackResponse.Unmarshal(m, b) @@ -2727,7 +2727,7 @@ 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_9111254583ad7475, []int{38} + return fileDescriptor_query_1e32bb78b6357529, []int{38} } func (m *ConcludeTransactionRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ConcludeTransactionRequest.Unmarshal(m, b) @@ -2786,7 +2786,7 @@ 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_9111254583ad7475, []int{39} + return fileDescriptor_query_1e32bb78b6357529, []int{39} } func (m *ConcludeTransactionResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ConcludeTransactionResponse.Unmarshal(m, b) @@ -2821,7 +2821,7 @@ 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_9111254583ad7475, []int{40} + return fileDescriptor_query_1e32bb78b6357529, []int{40} } func (m *ReadTransactionRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ReadTransactionRequest.Unmarshal(m, b) @@ -2881,7 +2881,7 @@ 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_9111254583ad7475, []int{41} + return fileDescriptor_query_1e32bb78b6357529, []int{41} } func (m *ReadTransactionResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ReadTransactionResponse.Unmarshal(m, b) @@ -2924,7 +2924,7 @@ 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_9111254583ad7475, []int{42} + return fileDescriptor_query_1e32bb78b6357529, []int{42} } func (m *BeginExecuteRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_BeginExecuteRequest.Unmarshal(m, b) @@ -2997,7 +2997,7 @@ 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_9111254583ad7475, []int{43} + return fileDescriptor_query_1e32bb78b6357529, []int{43} } func (m *BeginExecuteResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_BeginExecuteResponse.Unmarshal(m, b) @@ -3055,7 +3055,7 @@ 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_9111254583ad7475, []int{44} + return fileDescriptor_query_1e32bb78b6357529, []int{44} } func (m *BeginExecuteBatchRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_BeginExecuteBatchRequest.Unmarshal(m, b) @@ -3135,7 +3135,7 @@ 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_9111254583ad7475, []int{45} + return fileDescriptor_query_1e32bb78b6357529, []int{45} } func (m *BeginExecuteBatchResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_BeginExecuteBatchResponse.Unmarshal(m, b) @@ -3192,7 +3192,7 @@ 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_9111254583ad7475, []int{46} + return fileDescriptor_query_1e32bb78b6357529, []int{46} } func (m *MessageStreamRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_MessageStreamRequest.Unmarshal(m, b) @@ -3252,7 +3252,7 @@ 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_9111254583ad7475, []int{47} + return fileDescriptor_query_1e32bb78b6357529, []int{47} } func (m *MessageStreamResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_MessageStreamResponse.Unmarshal(m, b) @@ -3296,7 +3296,7 @@ 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_9111254583ad7475, []int{48} + return fileDescriptor_query_1e32bb78b6357529, []int{48} } func (m *MessageAckRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_MessageAckRequest.Unmarshal(m, b) @@ -3366,7 +3366,7 @@ 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_9111254583ad7475, []int{49} + return fileDescriptor_query_1e32bb78b6357529, []int{49} } func (m *MessageAckResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_MessageAckResponse.Unmarshal(m, b) @@ -3414,7 +3414,7 @@ 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_9111254583ad7475, []int{50} + return fileDescriptor_query_1e32bb78b6357529, []int{50} } func (m *SplitQueryRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_SplitQueryRequest.Unmarshal(m, b) @@ -3505,7 +3505,7 @@ 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_9111254583ad7475, []int{51} + return fileDescriptor_query_1e32bb78b6357529, []int{51} } func (m *QuerySplit) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_QuerySplit.Unmarshal(m, b) @@ -3552,7 +3552,7 @@ 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_9111254583ad7475, []int{52} + return fileDescriptor_query_1e32bb78b6357529, []int{52} } func (m *SplitQueryResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_SplitQueryResponse.Unmarshal(m, b) @@ -3590,7 +3590,7 @@ 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_9111254583ad7475, []int{53} + return fileDescriptor_query_1e32bb78b6357529, []int{53} } func (m *StreamHealthRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_StreamHealthRequest.Unmarshal(m, b) @@ -3649,7 +3649,7 @@ 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_9111254583ad7475, []int{54} + return fileDescriptor_query_1e32bb78b6357529, []int{54} } func (m *RealtimeStats) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_RealtimeStats.Unmarshal(m, b) @@ -3737,7 +3737,7 @@ 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_9111254583ad7475, []int{55} + return fileDescriptor_query_1e32bb78b6357529, []int{55} } func (m *AggregateStats) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_AggregateStats.Unmarshal(m, b) @@ -3849,7 +3849,7 @@ 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_9111254583ad7475, []int{56} + return fileDescriptor_query_1e32bb78b6357529, []int{56} } func (m *StreamHealthResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_StreamHealthResponse.Unmarshal(m, b) @@ -3933,7 +3933,7 @@ 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_9111254583ad7475, []int{57} + return fileDescriptor_query_1e32bb78b6357529, []int{57} } func (m *UpdateStreamRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_UpdateStreamRequest.Unmarshal(m, b) @@ -4000,7 +4000,7 @@ 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_9111254583ad7475, []int{58} + return fileDescriptor_query_1e32bb78b6357529, []int{58} } func (m *UpdateStreamResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_UpdateStreamResponse.Unmarshal(m, b) @@ -4042,7 +4042,7 @@ 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_9111254583ad7475, []int{59} + return fileDescriptor_query_1e32bb78b6357529, []int{59} } func (m *TransactionMetadata) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_TransactionMetadata.Unmarshal(m, b) @@ -4164,9 +4164,9 @@ func init() { proto.RegisterEnum("query.SplitQueryRequest_Algorithm", SplitQueryRequest_Algorithm_name, SplitQueryRequest_Algorithm_value) } -func init() { proto.RegisterFile("query.proto", fileDescriptor_query_9111254583ad7475) } +func init() { proto.RegisterFile("query.proto", fileDescriptor_query_1e32bb78b6357529) } -var fileDescriptor_query_9111254583ad7475 = []byte{ +var fileDescriptor_query_1e32bb78b6357529 = []byte{ // 3231 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x5a, 0x4b, 0x73, 0x1b, 0xc7, 0x76, 0xd6, 0xe0, 0x41, 0x02, 0x07, 0x04, 0xd8, 0x6c, 0x90, 0x12, 0x44, 0xf9, 0xda, 0xcc, 0xdc, diff --git a/go/vt/proto/queryservice/queryservice.pb.go b/go/vt/proto/queryservice/queryservice.pb.go index c6c7ad3be1e..dc4bf2f2ba8 100644 --- a/go/vt/proto/queryservice/queryservice.pb.go +++ b/go/vt/proto/queryservice/queryservice.pb.go @@ -921,9 +921,9 @@ var _Query_serviceDesc = grpc.ServiceDesc{ Metadata: "queryservice.proto", } -func init() { proto.RegisterFile("queryservice.proto", fileDescriptor_queryservice_81e549fbfb878a8d) } +func init() { proto.RegisterFile("queryservice.proto", fileDescriptor_queryservice_bb9da33c43234b51) } -var fileDescriptor_queryservice_81e549fbfb878a8d = []byte{ +var fileDescriptor_queryservice_bb9da33c43234b51 = []byte{ // 519 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x95, 0xdf, 0x6b, 0xd4, 0x40, 0x10, 0xc7, 0xf5, 0xa1, 0xad, 0x4c, 0xe3, 0xaf, 0xad, 0x55, 0x9b, 0xd6, 0xb6, 0xf6, 0x4d, 0x84, diff --git a/go/vt/proto/replicationdata/replicationdata.pb.go b/go/vt/proto/replicationdata/replicationdata.pb.go index e308aa9230c..5104477b7c0 100644 --- a/go/vt/proto/replicationdata/replicationdata.pb.go +++ b/go/vt/proto/replicationdata/replicationdata.pb.go @@ -37,7 +37,7 @@ 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_535db925ee5677f7, []int{0} + return fileDescriptor_replicationdata_1dfa1a45cfa5e522, []int{0} } func (m *Status) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Status.Unmarshal(m, b) @@ -111,10 +111,10 @@ func init() { } func init() { - proto.RegisterFile("replicationdata.proto", fileDescriptor_replicationdata_535db925ee5677f7) + proto.RegisterFile("replicationdata.proto", fileDescriptor_replicationdata_1dfa1a45cfa5e522) } -var fileDescriptor_replicationdata_535db925ee5677f7 = []byte{ +var fileDescriptor_replicationdata_1dfa1a45cfa5e522 = []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 0b807555005..917663e342b 100644 --- a/go/vt/proto/tableacl/tableacl.pb.go +++ b/go/vt/proto/tableacl/tableacl.pb.go @@ -35,7 +35,7 @@ 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_38276fd243b9c307, []int{0} + return fileDescriptor_tableacl_82b5f1376534b35e, []int{0} } func (m *TableGroupSpec) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_TableGroupSpec.Unmarshal(m, b) @@ -101,7 +101,7 @@ 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_38276fd243b9c307, []int{1} + return fileDescriptor_tableacl_82b5f1376534b35e, []int{1} } func (m *Config) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Config.Unmarshal(m, b) @@ -133,9 +133,9 @@ func init() { proto.RegisterType((*Config)(nil), "tableacl.Config") } -func init() { proto.RegisterFile("tableacl.proto", fileDescriptor_tableacl_38276fd243b9c307) } +func init() { proto.RegisterFile("tableacl.proto", fileDescriptor_tableacl_82b5f1376534b35e) } -var fileDescriptor_tableacl_38276fd243b9c307 = []byte{ +var fileDescriptor_tableacl_82b5f1376534b35e = []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 d780c3bd0e3..851721cdec1 100644 --- a/go/vt/proto/tabletmanagerdata/tabletmanagerdata.pb.go +++ b/go/vt/proto/tabletmanagerdata/tabletmanagerdata.pb.go @@ -46,7 +46,7 @@ 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_7a10c2dfddcc994f, []int{0} + return fileDescriptor_tabletmanagerdata_bfd6af383c5f908a, []int{0} } func (m *TableDefinition) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_TableDefinition.Unmarshal(m, b) @@ -128,7 +128,7 @@ 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_7a10c2dfddcc994f, []int{1} + return fileDescriptor_tabletmanagerdata_bfd6af383c5f908a, []int{1} } func (m *SchemaDefinition) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_SchemaDefinition.Unmarshal(m, b) @@ -183,7 +183,7 @@ 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_7a10c2dfddcc994f, []int{2} + return fileDescriptor_tabletmanagerdata_bfd6af383c5f908a, []int{2} } func (m *SchemaChangeResult) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_SchemaChangeResult.Unmarshal(m, b) @@ -234,7 +234,7 @@ 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_7a10c2dfddcc994f, []int{3} + return fileDescriptor_tabletmanagerdata_bfd6af383c5f908a, []int{3} } func (m *UserPermission) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_UserPermission.Unmarshal(m, b) @@ -298,7 +298,7 @@ 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_7a10c2dfddcc994f, []int{4} + return fileDescriptor_tabletmanagerdata_bfd6af383c5f908a, []int{4} } func (m *DbPermission) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_DbPermission.Unmarshal(m, b) @@ -360,7 +360,7 @@ 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_7a10c2dfddcc994f, []int{5} + return fileDescriptor_tabletmanagerdata_bfd6af383c5f908a, []int{5} } func (m *Permissions) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Permissions.Unmarshal(m, b) @@ -405,7 +405,7 @@ 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_7a10c2dfddcc994f, []int{6} + return fileDescriptor_tabletmanagerdata_bfd6af383c5f908a, []int{6} } func (m *PingRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_PingRequest.Unmarshal(m, b) @@ -443,7 +443,7 @@ 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_7a10c2dfddcc994f, []int{7} + return fileDescriptor_tabletmanagerdata_bfd6af383c5f908a, []int{7} } func (m *PingResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_PingResponse.Unmarshal(m, b) @@ -482,7 +482,7 @@ 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_7a10c2dfddcc994f, []int{8} + return fileDescriptor_tabletmanagerdata_bfd6af383c5f908a, []int{8} } func (m *SleepRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_SleepRequest.Unmarshal(m, b) @@ -519,7 +519,7 @@ 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_7a10c2dfddcc994f, []int{9} + return fileDescriptor_tabletmanagerdata_bfd6af383c5f908a, []int{9} } func (m *SleepResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_SleepResponse.Unmarshal(m, b) @@ -552,7 +552,7 @@ 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_7a10c2dfddcc994f, []int{10} + return fileDescriptor_tabletmanagerdata_bfd6af383c5f908a, []int{10} } func (m *ExecuteHookRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ExecuteHookRequest.Unmarshal(m, b) @@ -606,7 +606,7 @@ 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_7a10c2dfddcc994f, []int{11} + return fileDescriptor_tabletmanagerdata_bfd6af383c5f908a, []int{11} } func (m *ExecuteHookResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ExecuteHookResponse.Unmarshal(m, b) @@ -660,7 +660,7 @@ 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_7a10c2dfddcc994f, []int{12} + return fileDescriptor_tabletmanagerdata_bfd6af383c5f908a, []int{12} } func (m *GetSchemaRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_GetSchemaRequest.Unmarshal(m, b) @@ -712,7 +712,7 @@ 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_7a10c2dfddcc994f, []int{13} + return fileDescriptor_tabletmanagerdata_bfd6af383c5f908a, []int{13} } func (m *GetSchemaResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_GetSchemaResponse.Unmarshal(m, b) @@ -749,7 +749,7 @@ 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_7a10c2dfddcc994f, []int{14} + return fileDescriptor_tabletmanagerdata_bfd6af383c5f908a, []int{14} } func (m *GetPermissionsRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_GetPermissionsRequest.Unmarshal(m, b) @@ -780,7 +780,7 @@ 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_7a10c2dfddcc994f, []int{15} + return fileDescriptor_tabletmanagerdata_bfd6af383c5f908a, []int{15} } func (m *GetPermissionsResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_GetPermissionsResponse.Unmarshal(m, b) @@ -817,7 +817,7 @@ 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_7a10c2dfddcc994f, []int{16} + return fileDescriptor_tabletmanagerdata_bfd6af383c5f908a, []int{16} } func (m *SetReadOnlyRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_SetReadOnlyRequest.Unmarshal(m, b) @@ -847,7 +847,7 @@ 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_7a10c2dfddcc994f, []int{17} + return fileDescriptor_tabletmanagerdata_bfd6af383c5f908a, []int{17} } func (m *SetReadOnlyResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_SetReadOnlyResponse.Unmarshal(m, b) @@ -877,7 +877,7 @@ 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_7a10c2dfddcc994f, []int{18} + return fileDescriptor_tabletmanagerdata_bfd6af383c5f908a, []int{18} } func (m *SetReadWriteRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_SetReadWriteRequest.Unmarshal(m, b) @@ -907,7 +907,7 @@ 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_7a10c2dfddcc994f, []int{19} + return fileDescriptor_tabletmanagerdata_bfd6af383c5f908a, []int{19} } func (m *SetReadWriteResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_SetReadWriteResponse.Unmarshal(m, b) @@ -938,7 +938,7 @@ 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_7a10c2dfddcc994f, []int{20} + return fileDescriptor_tabletmanagerdata_bfd6af383c5f908a, []int{20} } func (m *ChangeTypeRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ChangeTypeRequest.Unmarshal(m, b) @@ -975,7 +975,7 @@ 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_7a10c2dfddcc994f, []int{21} + return fileDescriptor_tabletmanagerdata_bfd6af383c5f908a, []int{21} } func (m *ChangeTypeResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ChangeTypeResponse.Unmarshal(m, b) @@ -1005,7 +1005,7 @@ 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_7a10c2dfddcc994f, []int{22} + return fileDescriptor_tabletmanagerdata_bfd6af383c5f908a, []int{22} } func (m *RefreshStateRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_RefreshStateRequest.Unmarshal(m, b) @@ -1035,7 +1035,7 @@ 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_7a10c2dfddcc994f, []int{23} + return fileDescriptor_tabletmanagerdata_bfd6af383c5f908a, []int{23} } func (m *RefreshStateResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_RefreshStateResponse.Unmarshal(m, b) @@ -1065,7 +1065,7 @@ 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_7a10c2dfddcc994f, []int{24} + return fileDescriptor_tabletmanagerdata_bfd6af383c5f908a, []int{24} } func (m *RunHealthCheckRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_RunHealthCheckRequest.Unmarshal(m, b) @@ -1095,7 +1095,7 @@ 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_7a10c2dfddcc994f, []int{25} + return fileDescriptor_tabletmanagerdata_bfd6af383c5f908a, []int{25} } func (m *RunHealthCheckResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_RunHealthCheckResponse.Unmarshal(m, b) @@ -1126,7 +1126,7 @@ 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_7a10c2dfddcc994f, []int{26} + return fileDescriptor_tabletmanagerdata_bfd6af383c5f908a, []int{26} } func (m *IgnoreHealthErrorRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_IgnoreHealthErrorRequest.Unmarshal(m, b) @@ -1163,7 +1163,7 @@ 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_7a10c2dfddcc994f, []int{27} + return fileDescriptor_tabletmanagerdata_bfd6af383c5f908a, []int{27} } func (m *IgnoreHealthErrorResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_IgnoreHealthErrorResponse.Unmarshal(m, b) @@ -1197,7 +1197,7 @@ 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_7a10c2dfddcc994f, []int{28} + return fileDescriptor_tabletmanagerdata_bfd6af383c5f908a, []int{28} } func (m *ReloadSchemaRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ReloadSchemaRequest.Unmarshal(m, b) @@ -1234,7 +1234,7 @@ 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_7a10c2dfddcc994f, []int{29} + return fileDescriptor_tabletmanagerdata_bfd6af383c5f908a, []int{29} } func (m *ReloadSchemaResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ReloadSchemaResponse.Unmarshal(m, b) @@ -1265,7 +1265,7 @@ 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_7a10c2dfddcc994f, []int{30} + return fileDescriptor_tabletmanagerdata_bfd6af383c5f908a, []int{30} } func (m *PreflightSchemaRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_PreflightSchemaRequest.Unmarshal(m, b) @@ -1305,7 +1305,7 @@ 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_7a10c2dfddcc994f, []int{31} + return fileDescriptor_tabletmanagerdata_bfd6af383c5f908a, []int{31} } func (m *PreflightSchemaResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_PreflightSchemaResponse.Unmarshal(m, b) @@ -1347,7 +1347,7 @@ 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_7a10c2dfddcc994f, []int{32} + return fileDescriptor_tabletmanagerdata_bfd6af383c5f908a, []int{32} } func (m *ApplySchemaRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ApplySchemaRequest.Unmarshal(m, b) @@ -1414,7 +1414,7 @@ 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_7a10c2dfddcc994f, []int{33} + return fileDescriptor_tabletmanagerdata_bfd6af383c5f908a, []int{33} } func (m *ApplySchemaResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ApplySchemaResponse.Unmarshal(m, b) @@ -1463,7 +1463,7 @@ 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_7a10c2dfddcc994f, []int{34} + return fileDescriptor_tabletmanagerdata_bfd6af383c5f908a, []int{34} } func (m *ExecuteFetchAsDbaRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ExecuteFetchAsDbaRequest.Unmarshal(m, b) @@ -1529,7 +1529,7 @@ 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_7a10c2dfddcc994f, []int{35} + return fileDescriptor_tabletmanagerdata_bfd6af383c5f908a, []int{35} } func (m *ExecuteFetchAsDbaResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ExecuteFetchAsDbaResponse.Unmarshal(m, b) @@ -1570,7 +1570,7 @@ 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_7a10c2dfddcc994f, []int{36} + return fileDescriptor_tabletmanagerdata_bfd6af383c5f908a, []int{36} } func (m *ExecuteFetchAsAllPrivsRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ExecuteFetchAsAllPrivsRequest.Unmarshal(m, b) @@ -1629,7 +1629,7 @@ 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_7a10c2dfddcc994f, []int{37} + return fileDescriptor_tabletmanagerdata_bfd6af383c5f908a, []int{37} } func (m *ExecuteFetchAsAllPrivsResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ExecuteFetchAsAllPrivsResponse.Unmarshal(m, b) @@ -1668,7 +1668,7 @@ 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_7a10c2dfddcc994f, []int{38} + return fileDescriptor_tabletmanagerdata_bfd6af383c5f908a, []int{38} } func (m *ExecuteFetchAsAppRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ExecuteFetchAsAppRequest.Unmarshal(m, b) @@ -1713,7 +1713,7 @@ 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_7a10c2dfddcc994f, []int{39} + return fileDescriptor_tabletmanagerdata_bfd6af383c5f908a, []int{39} } func (m *ExecuteFetchAsAppResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ExecuteFetchAsAppResponse.Unmarshal(m, b) @@ -1750,7 +1750,7 @@ 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_7a10c2dfddcc994f, []int{40} + return fileDescriptor_tabletmanagerdata_bfd6af383c5f908a, []int{40} } func (m *SlaveStatusRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_SlaveStatusRequest.Unmarshal(m, b) @@ -1781,7 +1781,7 @@ 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_7a10c2dfddcc994f, []int{41} + return fileDescriptor_tabletmanagerdata_bfd6af383c5f908a, []int{41} } func (m *SlaveStatusResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_SlaveStatusResponse.Unmarshal(m, b) @@ -1818,7 +1818,7 @@ 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_7a10c2dfddcc994f, []int{42} + return fileDescriptor_tabletmanagerdata_bfd6af383c5f908a, []int{42} } func (m *MasterPositionRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_MasterPositionRequest.Unmarshal(m, b) @@ -1849,7 +1849,7 @@ 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_7a10c2dfddcc994f, []int{43} + return fileDescriptor_tabletmanagerdata_bfd6af383c5f908a, []int{43} } func (m *MasterPositionResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_MasterPositionResponse.Unmarshal(m, b) @@ -1886,7 +1886,7 @@ 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_7a10c2dfddcc994f, []int{44} + return fileDescriptor_tabletmanagerdata_bfd6af383c5f908a, []int{44} } func (m *StopSlaveRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_StopSlaveRequest.Unmarshal(m, b) @@ -1916,7 +1916,7 @@ 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_7a10c2dfddcc994f, []int{45} + return fileDescriptor_tabletmanagerdata_bfd6af383c5f908a, []int{45} } func (m *StopSlaveResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_StopSlaveResponse.Unmarshal(m, b) @@ -1948,7 +1948,7 @@ 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_7a10c2dfddcc994f, []int{46} + return fileDescriptor_tabletmanagerdata_bfd6af383c5f908a, []int{46} } func (m *StopSlaveMinimumRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_StopSlaveMinimumRequest.Unmarshal(m, b) @@ -1993,7 +1993,7 @@ 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_7a10c2dfddcc994f, []int{47} + return fileDescriptor_tabletmanagerdata_bfd6af383c5f908a, []int{47} } func (m *StopSlaveMinimumResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_StopSlaveMinimumResponse.Unmarshal(m, b) @@ -2030,7 +2030,7 @@ 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_7a10c2dfddcc994f, []int{48} + return fileDescriptor_tabletmanagerdata_bfd6af383c5f908a, []int{48} } func (m *StartSlaveRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_StartSlaveRequest.Unmarshal(m, b) @@ -2060,7 +2060,7 @@ 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_7a10c2dfddcc994f, []int{49} + return fileDescriptor_tabletmanagerdata_bfd6af383c5f908a, []int{49} } func (m *StartSlaveResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_StartSlaveResponse.Unmarshal(m, b) @@ -2094,7 +2094,7 @@ 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_7a10c2dfddcc994f, []int{50} + return fileDescriptor_tabletmanagerdata_bfd6af383c5f908a, []int{50} } func (m *TabletExternallyReparentedRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_TabletExternallyReparentedRequest.Unmarshal(m, b) @@ -2131,7 +2131,7 @@ 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_7a10c2dfddcc994f, []int{51} + return fileDescriptor_tabletmanagerdata_bfd6af383c5f908a, []int{51} } func (m *TabletExternallyReparentedResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_TabletExternallyReparentedResponse.Unmarshal(m, b) @@ -2161,7 +2161,7 @@ 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_7a10c2dfddcc994f, []int{52} + return fileDescriptor_tabletmanagerdata_bfd6af383c5f908a, []int{52} } func (m *TabletExternallyElectedRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_TabletExternallyElectedRequest.Unmarshal(m, b) @@ -2191,7 +2191,7 @@ 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_7a10c2dfddcc994f, []int{53} + return fileDescriptor_tabletmanagerdata_bfd6af383c5f908a, []int{53} } func (m *TabletExternallyElectedResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_TabletExternallyElectedResponse.Unmarshal(m, b) @@ -2221,7 +2221,7 @@ 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_7a10c2dfddcc994f, []int{54} + return fileDescriptor_tabletmanagerdata_bfd6af383c5f908a, []int{54} } func (m *GetSlavesRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_GetSlavesRequest.Unmarshal(m, b) @@ -2252,7 +2252,7 @@ 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_7a10c2dfddcc994f, []int{55} + return fileDescriptor_tabletmanagerdata_bfd6af383c5f908a, []int{55} } func (m *GetSlavesResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_GetSlavesResponse.Unmarshal(m, b) @@ -2289,7 +2289,7 @@ 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_7a10c2dfddcc994f, []int{56} + return fileDescriptor_tabletmanagerdata_bfd6af383c5f908a, []int{56} } func (m *ResetReplicationRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ResetReplicationRequest.Unmarshal(m, b) @@ -2319,7 +2319,7 @@ 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_7a10c2dfddcc994f, []int{57} + return fileDescriptor_tabletmanagerdata_bfd6af383c5f908a, []int{57} } func (m *ResetReplicationResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ResetReplicationResponse.Unmarshal(m, b) @@ -2350,7 +2350,7 @@ 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_7a10c2dfddcc994f, []int{58} + return fileDescriptor_tabletmanagerdata_bfd6af383c5f908a, []int{58} } func (m *VReplicationExecRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_VReplicationExecRequest.Unmarshal(m, b) @@ -2388,7 +2388,7 @@ 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_7a10c2dfddcc994f, []int{59} + return fileDescriptor_tabletmanagerdata_bfd6af383c5f908a, []int{59} } func (m *VReplicationExecResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_VReplicationExecResponse.Unmarshal(m, b) @@ -2427,7 +2427,7 @@ 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_7a10c2dfddcc994f, []int{60} + return fileDescriptor_tabletmanagerdata_bfd6af383c5f908a, []int{60} } func (m *VReplicationWaitForPosRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_VReplicationWaitForPosRequest.Unmarshal(m, b) @@ -2471,7 +2471,7 @@ 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_7a10c2dfddcc994f, []int{61} + return fileDescriptor_tabletmanagerdata_bfd6af383c5f908a, []int{61} } func (m *VReplicationWaitForPosResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_VReplicationWaitForPosResponse.Unmarshal(m, b) @@ -2501,7 +2501,7 @@ 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_7a10c2dfddcc994f, []int{62} + return fileDescriptor_tabletmanagerdata_bfd6af383c5f908a, []int{62} } func (m *InitMasterRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_InitMasterRequest.Unmarshal(m, b) @@ -2532,7 +2532,7 @@ 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_7a10c2dfddcc994f, []int{63} + return fileDescriptor_tabletmanagerdata_bfd6af383c5f908a, []int{63} } func (m *InitMasterResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_InitMasterResponse.Unmarshal(m, b) @@ -2573,7 +2573,7 @@ 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_7a10c2dfddcc994f, []int{64} + return fileDescriptor_tabletmanagerdata_bfd6af383c5f908a, []int{64} } func (m *PopulateReparentJournalRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_PopulateReparentJournalRequest.Unmarshal(m, b) @@ -2631,7 +2631,7 @@ 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_7a10c2dfddcc994f, []int{65} + return fileDescriptor_tabletmanagerdata_bfd6af383c5f908a, []int{65} } func (m *PopulateReparentJournalResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_PopulateReparentJournalResponse.Unmarshal(m, b) @@ -2664,7 +2664,7 @@ 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_7a10c2dfddcc994f, []int{66} + return fileDescriptor_tabletmanagerdata_bfd6af383c5f908a, []int{66} } func (m *InitSlaveRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_InitSlaveRequest.Unmarshal(m, b) @@ -2715,7 +2715,7 @@ 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_7a10c2dfddcc994f, []int{67} + return fileDescriptor_tabletmanagerdata_bfd6af383c5f908a, []int{67} } func (m *InitSlaveResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_InitSlaveResponse.Unmarshal(m, b) @@ -2745,7 +2745,7 @@ 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_7a10c2dfddcc994f, []int{68} + return fileDescriptor_tabletmanagerdata_bfd6af383c5f908a, []int{68} } func (m *DemoteMasterRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_DemoteMasterRequest.Unmarshal(m, b) @@ -2776,7 +2776,7 @@ 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_7a10c2dfddcc994f, []int{69} + return fileDescriptor_tabletmanagerdata_bfd6af383c5f908a, []int{69} } func (m *DemoteMasterResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_DemoteMasterResponse.Unmarshal(m, b) @@ -2814,7 +2814,7 @@ 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_7a10c2dfddcc994f, []int{70} + return fileDescriptor_tabletmanagerdata_bfd6af383c5f908a, []int{70} } func (m *PromoteSlaveWhenCaughtUpRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_PromoteSlaveWhenCaughtUpRequest.Unmarshal(m, b) @@ -2852,7 +2852,7 @@ 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_7a10c2dfddcc994f, []int{71} + return fileDescriptor_tabletmanagerdata_bfd6af383c5f908a, []int{71} } func (m *PromoteSlaveWhenCaughtUpResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_PromoteSlaveWhenCaughtUpResponse.Unmarshal(m, b) @@ -2889,7 +2889,7 @@ 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_7a10c2dfddcc994f, []int{72} + return fileDescriptor_tabletmanagerdata_bfd6af383c5f908a, []int{72} } func (m *SlaveWasPromotedRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_SlaveWasPromotedRequest.Unmarshal(m, b) @@ -2919,7 +2919,7 @@ 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_7a10c2dfddcc994f, []int{73} + return fileDescriptor_tabletmanagerdata_bfd6af383c5f908a, []int{73} } func (m *SlaveWasPromotedResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_SlaveWasPromotedResponse.Unmarshal(m, b) @@ -2952,7 +2952,7 @@ 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_7a10c2dfddcc994f, []int{74} + return fileDescriptor_tabletmanagerdata_bfd6af383c5f908a, []int{74} } func (m *SetMasterRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_SetMasterRequest.Unmarshal(m, b) @@ -3003,7 +3003,7 @@ 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_7a10c2dfddcc994f, []int{75} + return fileDescriptor_tabletmanagerdata_bfd6af383c5f908a, []int{75} } func (m *SetMasterResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_SetMasterResponse.Unmarshal(m, b) @@ -3035,7 +3035,7 @@ 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_7a10c2dfddcc994f, []int{76} + return fileDescriptor_tabletmanagerdata_bfd6af383c5f908a, []int{76} } func (m *SlaveWasRestartedRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_SlaveWasRestartedRequest.Unmarshal(m, b) @@ -3072,7 +3072,7 @@ 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_7a10c2dfddcc994f, []int{77} + return fileDescriptor_tabletmanagerdata_bfd6af383c5f908a, []int{77} } func (m *SlaveWasRestartedResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_SlaveWasRestartedResponse.Unmarshal(m, b) @@ -3102,7 +3102,7 @@ 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_7a10c2dfddcc994f, []int{78} + return fileDescriptor_tabletmanagerdata_bfd6af383c5f908a, []int{78} } func (m *StopReplicationAndGetStatusRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_StopReplicationAndGetStatusRequest.Unmarshal(m, b) @@ -3133,7 +3133,7 @@ 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_7a10c2dfddcc994f, []int{79} + return fileDescriptor_tabletmanagerdata_bfd6af383c5f908a, []int{79} } func (m *StopReplicationAndGetStatusResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_StopReplicationAndGetStatusResponse.Unmarshal(m, b) @@ -3170,7 +3170,7 @@ 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_7a10c2dfddcc994f, []int{80} + return fileDescriptor_tabletmanagerdata_bfd6af383c5f908a, []int{80} } func (m *PromoteSlaveRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_PromoteSlaveRequest.Unmarshal(m, b) @@ -3201,7 +3201,7 @@ 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_7a10c2dfddcc994f, []int{81} + return fileDescriptor_tabletmanagerdata_bfd6af383c5f908a, []int{81} } func (m *PromoteSlaveResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_PromoteSlaveResponse.Unmarshal(m, b) @@ -3239,7 +3239,7 @@ 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_7a10c2dfddcc994f, []int{82} + return fileDescriptor_tabletmanagerdata_bfd6af383c5f908a, []int{82} } func (m *BackupRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_BackupRequest.Unmarshal(m, b) @@ -3277,7 +3277,7 @@ 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_7a10c2dfddcc994f, []int{83} + return fileDescriptor_tabletmanagerdata_bfd6af383c5f908a, []int{83} } func (m *BackupResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_BackupResponse.Unmarshal(m, b) @@ -3314,7 +3314,7 @@ 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_7a10c2dfddcc994f, []int{84} + return fileDescriptor_tabletmanagerdata_bfd6af383c5f908a, []int{84} } func (m *RestoreFromBackupRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_RestoreFromBackupRequest.Unmarshal(m, b) @@ -3345,7 +3345,7 @@ 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_7a10c2dfddcc994f, []int{85} + return fileDescriptor_tabletmanagerdata_bfd6af383c5f908a, []int{85} } func (m *RestoreFromBackupResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_RestoreFromBackupResponse.Unmarshal(m, b) @@ -3465,10 +3465,10 @@ func init() { } func init() { - proto.RegisterFile("tabletmanagerdata.proto", fileDescriptor_tabletmanagerdata_7a10c2dfddcc994f) + proto.RegisterFile("tabletmanagerdata.proto", fileDescriptor_tabletmanagerdata_bfd6af383c5f908a) } -var fileDescriptor_tabletmanagerdata_7a10c2dfddcc994f = []byte{ +var fileDescriptor_tabletmanagerdata_bfd6af383c5f908a = []byte{ // 1999 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x58, 0x5b, 0x6f, 0x1b, 0xc7, 0x15, 0x06, 0x49, 0x49, 0x96, 0x0e, 0x2f, 0xa2, 0x96, 0x92, 0x48, 0x29, 0x88, 0x24, 0xaf, 0x9d, diff --git a/go/vt/proto/tabletmanagerservice/tabletmanagerservice.pb.go b/go/vt/proto/tabletmanagerservice/tabletmanagerservice.pb.go index 11555ab3a4f..6153dc90aab 100644 --- a/go/vt/proto/tabletmanagerservice/tabletmanagerservice.pb.go +++ b/go/vt/proto/tabletmanagerservice/tabletmanagerservice.pb.go @@ -1545,10 +1545,10 @@ var _TabletManager_serviceDesc = grpc.ServiceDesc{ } func init() { - proto.RegisterFile("tabletmanagerservice.proto", fileDescriptor_tabletmanagerservice_a64e2f6154f58360) + proto.RegisterFile("tabletmanagerservice.proto", fileDescriptor_tabletmanagerservice_f4d7827db0506c7d) } -var fileDescriptor_tabletmanagerservice_a64e2f6154f58360 = []byte{ +var fileDescriptor_tabletmanagerservice_f4d7827db0506c7d = []byte{ // 956 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x98, 0xdf, 0x8f, 0x1b, 0x35, 0x10, 0xc7, 0x89, 0x04, 0x95, 0x30, 0x3f, 0x6b, 0x21, 0x8a, 0x0e, 0x09, 0x28, 0x6d, 0xf9, 0xd1, diff --git a/go/vt/proto/throttlerdata/throttlerdata.pb.go b/go/vt/proto/throttlerdata/throttlerdata.pb.go index d1bd1620f46..74788363a48 100644 --- a/go/vt/proto/throttlerdata/throttlerdata.pb.go +++ b/go/vt/proto/throttlerdata/throttlerdata.pb.go @@ -29,7 +29,7 @@ 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_7d084fd3a7704c85, []int{0} + return fileDescriptor_throttlerdata_d10a8d735853021e, []int{0} } func (m *MaxRatesRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_MaxRatesRequest.Unmarshal(m, b) @@ -63,7 +63,7 @@ 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_7d084fd3a7704c85, []int{1} + return fileDescriptor_throttlerdata_d10a8d735853021e, []int{1} } func (m *MaxRatesResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_MaxRatesResponse.Unmarshal(m, b) @@ -102,7 +102,7 @@ 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_7d084fd3a7704c85, []int{2} + return fileDescriptor_throttlerdata_d10a8d735853021e, []int{2} } func (m *SetMaxRateRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_SetMaxRateRequest.Unmarshal(m, b) @@ -142,7 +142,7 @@ 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_7d084fd3a7704c85, []int{3} + return fileDescriptor_throttlerdata_d10a8d735853021e, []int{3} } func (m *SetMaxRateResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_SetMaxRateResponse.Unmarshal(m, b) @@ -259,7 +259,7 @@ 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_7d084fd3a7704c85, []int{4} + return fileDescriptor_throttlerdata_d10a8d735853021e, []int{4} } func (m *Configuration) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Configuration.Unmarshal(m, b) @@ -391,7 +391,7 @@ 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_7d084fd3a7704c85, []int{5} + return fileDescriptor_throttlerdata_d10a8d735853021e, []int{5} } func (m *GetConfigurationRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_GetConfigurationRequest.Unmarshal(m, b) @@ -432,7 +432,7 @@ 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_7d084fd3a7704c85, []int{6} + return fileDescriptor_throttlerdata_d10a8d735853021e, []int{6} } func (m *GetConfigurationResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_GetConfigurationResponse.Unmarshal(m, b) @@ -478,7 +478,7 @@ 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_7d084fd3a7704c85, []int{7} + return fileDescriptor_throttlerdata_d10a8d735853021e, []int{7} } func (m *UpdateConfigurationRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_UpdateConfigurationRequest.Unmarshal(m, b) @@ -532,7 +532,7 @@ 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_7d084fd3a7704c85, []int{8} + return fileDescriptor_throttlerdata_d10a8d735853021e, []int{8} } func (m *UpdateConfigurationResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_UpdateConfigurationResponse.Unmarshal(m, b) @@ -573,7 +573,7 @@ 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_7d084fd3a7704c85, []int{9} + return fileDescriptor_throttlerdata_d10a8d735853021e, []int{9} } func (m *ResetConfigurationRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ResetConfigurationRequest.Unmarshal(m, b) @@ -613,7 +613,7 @@ 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_7d084fd3a7704c85, []int{10} + return fileDescriptor_throttlerdata_d10a8d735853021e, []int{10} } func (m *ResetConfigurationResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ResetConfigurationResponse.Unmarshal(m, b) @@ -656,9 +656,9 @@ func init() { proto.RegisterType((*ResetConfigurationResponse)(nil), "throttlerdata.ResetConfigurationResponse") } -func init() { proto.RegisterFile("throttlerdata.proto", fileDescriptor_throttlerdata_7d084fd3a7704c85) } +func init() { proto.RegisterFile("throttlerdata.proto", fileDescriptor_throttlerdata_d10a8d735853021e) } -var fileDescriptor_throttlerdata_7d084fd3a7704c85 = []byte{ +var fileDescriptor_throttlerdata_d10a8d735853021e = []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 ecbe7cdac25..988d592e406 100644 --- a/go/vt/proto/throttlerservice/throttlerservice.pb.go +++ b/go/vt/proto/throttlerservice/throttlerservice.pb.go @@ -255,10 +255,10 @@ var _Throttler_serviceDesc = grpc.ServiceDesc{ } func init() { - proto.RegisterFile("throttlerservice.proto", fileDescriptor_throttlerservice_151ce3faa7ac0b15) + proto.RegisterFile("throttlerservice.proto", fileDescriptor_throttlerservice_8b1d9f2a5de89835) } -var fileDescriptor_throttlerservice_151ce3faa7ac0b15 = []byte{ +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, diff --git a/go/vt/proto/topodata/topodata.pb.go b/go/vt/proto/topodata/topodata.pb.go index d3903dbfd8f..504f39b0eaf 100644 --- a/go/vt/proto/topodata/topodata.pb.go +++ b/go/vt/proto/topodata/topodata.pb.go @@ -48,7 +48,7 @@ func (x KeyspaceIdType) String() string { return proto.EnumName(KeyspaceIdType_name, int32(x)) } func (KeyspaceIdType) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_topodata_23985cc74c86747c, []int{0} + return fileDescriptor_topodata_693bf5422a92a7f4, []int{0} } // TabletType represents the type of a given tablet. @@ -117,7 +117,7 @@ func (x TabletType) String() string { return proto.EnumName(TabletType_name, int32(x)) } func (TabletType) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_topodata_23985cc74c86747c, []int{1} + return fileDescriptor_topodata_693bf5422a92a7f4, []int{1} } // KeyRange describes a range of sharding keys, when range-based @@ -134,7 +134,7 @@ 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_23985cc74c86747c, []int{0} + return fileDescriptor_topodata_693bf5422a92a7f4, []int{0} } func (m *KeyRange) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_KeyRange.Unmarshal(m, b) @@ -184,7 +184,7 @@ 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_23985cc74c86747c, []int{1} + return fileDescriptor_topodata_693bf5422a92a7f4, []int{1} } func (m *TabletAlias) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_TabletAlias.Unmarshal(m, b) @@ -260,7 +260,7 @@ 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_23985cc74c86747c, []int{2} + return fileDescriptor_topodata_693bf5422a92a7f4, []int{2} } func (m *Tablet) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Tablet.Unmarshal(m, b) @@ -394,7 +394,7 @@ 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_23985cc74c86747c, []int{3} + return fileDescriptor_topodata_693bf5422a92a7f4, []int{3} } func (m *Shard) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Shard.Unmarshal(m, b) @@ -469,7 +469,7 @@ 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_23985cc74c86747c, []int{3, 0} + return fileDescriptor_topodata_693bf5422a92a7f4, []int{3, 0} } func (m *Shard_ServedType) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Shard_ServedType.Unmarshal(m, b) @@ -526,7 +526,7 @@ 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_23985cc74c86747c, []int{3, 1} + return fileDescriptor_topodata_693bf5422a92a7f4, []int{3, 1} } func (m *Shard_SourceShard) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Shard_SourceShard.Unmarshal(m, b) @@ -601,7 +601,7 @@ 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_23985cc74c86747c, []int{3, 2} + return fileDescriptor_topodata_693bf5422a92a7f4, []int{3, 2} } func (m *Shard_TabletControl) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Shard_TabletControl.Unmarshal(m, b) @@ -676,7 +676,7 @@ 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_23985cc74c86747c, []int{4} + return fileDescriptor_topodata_693bf5422a92a7f4, []int{4} } func (m *Keyspace) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Keyspace.Unmarshal(m, b) @@ -735,7 +735,7 @@ 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_23985cc74c86747c, []int{4, 0} + return fileDescriptor_topodata_693bf5422a92a7f4, []int{4, 0} } func (m *Keyspace_ServedFrom) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Keyspace_ServedFrom.Unmarshal(m, b) @@ -791,7 +791,7 @@ 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_23985cc74c86747c, []int{5} + return fileDescriptor_topodata_693bf5422a92a7f4, []int{5} } func (m *ShardReplication) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ShardReplication.Unmarshal(m, b) @@ -830,7 +830,7 @@ 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_23985cc74c86747c, []int{5, 0} + return fileDescriptor_topodata_693bf5422a92a7f4, []int{5, 0} } func (m *ShardReplication_Node) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ShardReplication_Node.Unmarshal(m, b) @@ -871,7 +871,7 @@ 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_23985cc74c86747c, []int{6} + return fileDescriptor_topodata_693bf5422a92a7f4, []int{6} } func (m *ShardReference) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ShardReference.Unmarshal(m, b) @@ -922,7 +922,7 @@ 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_23985cc74c86747c, []int{7} + return fileDescriptor_topodata_693bf5422a92a7f4, []int{7} } func (m *SrvKeyspace) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_SrvKeyspace.Unmarshal(m, b) @@ -984,7 +984,7 @@ 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_23985cc74c86747c, []int{7, 0} + return fileDescriptor_topodata_693bf5422a92a7f4, []int{7, 0} } func (m *SrvKeyspace_KeyspacePartition) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_SrvKeyspace_KeyspacePartition.Unmarshal(m, b) @@ -1034,7 +1034,7 @@ 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_23985cc74c86747c, []int{7, 1} + return fileDescriptor_topodata_693bf5422a92a7f4, []int{7, 1} } func (m *SrvKeyspace_ServedFrom) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_SrvKeyspace_ServedFrom.Unmarshal(m, b) @@ -1092,7 +1092,7 @@ 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_23985cc74c86747c, []int{8} + return fileDescriptor_topodata_693bf5422a92a7f4, []int{8} } func (m *CellInfo) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_CellInfo.Unmarshal(m, b) @@ -1156,9 +1156,9 @@ func init() { proto.RegisterEnum("topodata.TabletType", TabletType_name, TabletType_value) } -func init() { proto.RegisterFile("topodata.proto", fileDescriptor_topodata_23985cc74c86747c) } +func init() { proto.RegisterFile("topodata.proto", fileDescriptor_topodata_693bf5422a92a7f4) } -var fileDescriptor_topodata_23985cc74c86747c = []byte{ +var fileDescriptor_topodata_693bf5422a92a7f4 = []byte{ // 1162 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x56, 0x6f, 0x8f, 0xda, 0x46, 0x13, 0x7f, 0x0c, 0x86, 0x33, 0x63, 0x8e, 0x38, 0xfb, 0x24, 0x95, 0xe5, 0x2a, 0x2a, 0x42, 0x8a, diff --git a/go/vt/proto/vschema/vschema.pb.go b/go/vt/proto/vschema/vschema.pb.go index e6436628cda..4a3aa16b0d1 100644 --- a/go/vt/proto/vschema/vschema.pb.go +++ b/go/vt/proto/vschema/vschema.pb.go @@ -34,7 +34,7 @@ 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_5ecfaf46981fe072, []int{0} + return fileDescriptor_vschema_58a865bec489dd60, []int{0} } func (m *Keyspace) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Keyspace.Unmarshal(m, b) @@ -99,7 +99,7 @@ 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_5ecfaf46981fe072, []int{1} + return fileDescriptor_vschema_58a865bec489dd60, []int{1} } func (m *Vindex) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Vindex.Unmarshal(m, b) @@ -170,7 +170,7 @@ 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_5ecfaf46981fe072, []int{2} + return fileDescriptor_vschema_58a865bec489dd60, []int{2} } func (m *Table) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Table.Unmarshal(m, b) @@ -249,7 +249,7 @@ 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_5ecfaf46981fe072, []int{3} + return fileDescriptor_vschema_58a865bec489dd60, []int{3} } func (m *ColumnVindex) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ColumnVindex.Unmarshal(m, b) @@ -304,7 +304,7 @@ 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_5ecfaf46981fe072, []int{4} + return fileDescriptor_vschema_58a865bec489dd60, []int{4} } func (m *AutoIncrement) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_AutoIncrement.Unmarshal(m, b) @@ -351,7 +351,7 @@ 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_5ecfaf46981fe072, []int{5} + return fileDescriptor_vschema_58a865bec489dd60, []int{5} } func (m *Column) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Column.Unmarshal(m, b) @@ -398,7 +398,7 @@ 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_5ecfaf46981fe072, []int{6} + return fileDescriptor_vschema_58a865bec489dd60, []int{6} } func (m *SrvVSchema) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_SrvVSchema.Unmarshal(m, b) @@ -439,9 +439,9 @@ func init() { proto.RegisterMapType((map[string]*Keyspace)(nil), "vschema.SrvVSchema.KeyspacesEntry") } -func init() { proto.RegisterFile("vschema.proto", fileDescriptor_vschema_5ecfaf46981fe072) } +func init() { proto.RegisterFile("vschema.proto", fileDescriptor_vschema_58a865bec489dd60) } -var fileDescriptor_vschema_5ecfaf46981fe072 = []byte{ +var fileDescriptor_vschema_58a865bec489dd60 = []byte{ // 562 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x54, 0x41, 0x6f, 0xd3, 0x4c, 0x10, 0x95, 0x93, 0xc6, 0x4d, 0xc6, 0x5f, 0xd2, 0x8f, 0x55, 0x29, 0xc6, 0x08, 0x35, 0xb2, 0x0a, diff --git a/go/vt/proto/vtctldata/vtctldata.pb.go b/go/vt/proto/vtctldata/vtctldata.pb.go index 849b81f15ec..6f3860b8efc 100644 --- a/go/vt/proto/vtctldata/vtctldata.pb.go +++ b/go/vt/proto/vtctldata/vtctldata.pb.go @@ -33,7 +33,7 @@ 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_1ba3ba7c409e0e97, []int{0} + return fileDescriptor_vtctldata_116d6c451a061272, []int{0} } func (m *ExecuteVtctlCommandRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ExecuteVtctlCommandRequest.Unmarshal(m, b) @@ -79,7 +79,7 @@ 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_1ba3ba7c409e0e97, []int{1} + return fileDescriptor_vtctldata_116d6c451a061272, []int{1} } func (m *ExecuteVtctlCommandResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ExecuteVtctlCommandResponse.Unmarshal(m, b) @@ -111,9 +111,9 @@ func init() { proto.RegisterType((*ExecuteVtctlCommandResponse)(nil), "vtctldata.ExecuteVtctlCommandResponse") } -func init() { proto.RegisterFile("vtctldata.proto", fileDescriptor_vtctldata_1ba3ba7c409e0e97) } +func init() { proto.RegisterFile("vtctldata.proto", fileDescriptor_vtctldata_116d6c451a061272) } -var fileDescriptor_vtctldata_1ba3ba7c409e0e97 = []byte{ +var fileDescriptor_vtctldata_116d6c451a061272 = []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 4214d5d15af..9dd938fd48b 100644 --- a/go/vt/proto/vtctlservice/vtctlservice.pb.go +++ b/go/vt/proto/vtctlservice/vtctlservice.pb.go @@ -123,9 +123,9 @@ var _Vtctl_serviceDesc = grpc.ServiceDesc{ Metadata: "vtctlservice.proto", } -func init() { proto.RegisterFile("vtctlservice.proto", fileDescriptor_vtctlservice_a3582c3eb674ce30) } +func init() { proto.RegisterFile("vtctlservice.proto", fileDescriptor_vtctlservice_af4114a311e29c50) } -var fileDescriptor_vtctlservice_a3582c3eb674ce30 = []byte{ +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, diff --git a/go/vt/proto/vtgate/vtgate.pb.go b/go/vt/proto/vtgate/vtgate.pb.go index 51e445dc618..d5bebcf6c71 100644 --- a/go/vt/proto/vtgate/vtgate.pb.go +++ b/go/vt/proto/vtgate/vtgate.pb.go @@ -53,7 +53,7 @@ func (x TransactionMode) String() string { return proto.EnumName(TransactionMode_name, int32(x)) } func (TransactionMode) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_vtgate_071b9c990aff35bf, []int{0} + return fileDescriptor_vtgate_8f5c6038eac4796e, []int{0} } // Session objects are exchanged like cookies through various @@ -98,7 +98,7 @@ 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_071b9c990aff35bf, []int{0} + return fileDescriptor_vtgate_8f5c6038eac4796e, []int{0} } func (m *Session) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Session.Unmarshal(m, b) @@ -186,7 +186,7 @@ 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_071b9c990aff35bf, []int{0, 0} + return fileDescriptor_vtgate_8f5c6038eac4796e, []int{0, 0} } func (m *Session_ShardSession) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Session_ShardSession.Unmarshal(m, b) @@ -244,7 +244,7 @@ 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_071b9c990aff35bf, []int{1} + return fileDescriptor_vtgate_8f5c6038eac4796e, []int{1} } func (m *ExecuteRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ExecuteRequest.Unmarshal(m, b) @@ -332,7 +332,7 @@ 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_071b9c990aff35bf, []int{2} + return fileDescriptor_vtgate_8f5c6038eac4796e, []int{2} } func (m *ExecuteResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ExecuteResponse.Unmarshal(m, b) @@ -402,7 +402,7 @@ 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_071b9c990aff35bf, []int{3} + return fileDescriptor_vtgate_8f5c6038eac4796e, []int{3} } func (m *ExecuteShardsRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ExecuteShardsRequest.Unmarshal(m, b) @@ -497,7 +497,7 @@ 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_071b9c990aff35bf, []int{4} + return fileDescriptor_vtgate_8f5c6038eac4796e, []int{4} } func (m *ExecuteShardsResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ExecuteShardsResponse.Unmarshal(m, b) @@ -568,7 +568,7 @@ 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_071b9c990aff35bf, []int{5} + return fileDescriptor_vtgate_8f5c6038eac4796e, []int{5} } func (m *ExecuteKeyspaceIdsRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ExecuteKeyspaceIdsRequest.Unmarshal(m, b) @@ -663,7 +663,7 @@ 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_071b9c990aff35bf, []int{6} + return fileDescriptor_vtgate_8f5c6038eac4796e, []int{6} } func (m *ExecuteKeyspaceIdsResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ExecuteKeyspaceIdsResponse.Unmarshal(m, b) @@ -734,7 +734,7 @@ 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_071b9c990aff35bf, []int{7} + return fileDescriptor_vtgate_8f5c6038eac4796e, []int{7} } func (m *ExecuteKeyRangesRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ExecuteKeyRangesRequest.Unmarshal(m, b) @@ -829,7 +829,7 @@ 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_071b9c990aff35bf, []int{8} + return fileDescriptor_vtgate_8f5c6038eac4796e, []int{8} } func (m *ExecuteKeyRangesResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ExecuteKeyRangesResponse.Unmarshal(m, b) @@ -902,7 +902,7 @@ 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_071b9c990aff35bf, []int{9} + return fileDescriptor_vtgate_8f5c6038eac4796e, []int{9} } func (m *ExecuteEntityIdsRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ExecuteEntityIdsRequest.Unmarshal(m, b) @@ -1001,7 +1001,7 @@ 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_071b9c990aff35bf, []int{9, 0} + return fileDescriptor_vtgate_8f5c6038eac4796e, []int{9, 0} } func (m *ExecuteEntityIdsRequest_EntityId) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ExecuteEntityIdsRequest_EntityId.Unmarshal(m, b) @@ -1061,7 +1061,7 @@ 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_071b9c990aff35bf, []int{10} + return fileDescriptor_vtgate_8f5c6038eac4796e, []int{10} } func (m *ExecuteEntityIdsResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ExecuteEntityIdsResponse.Unmarshal(m, b) @@ -1126,7 +1126,7 @@ 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_071b9c990aff35bf, []int{11} + return fileDescriptor_vtgate_8f5c6038eac4796e, []int{11} } func (m *ExecuteBatchRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ExecuteBatchRequest.Unmarshal(m, b) @@ -1214,7 +1214,7 @@ 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_071b9c990aff35bf, []int{12} + return fileDescriptor_vtgate_8f5c6038eac4796e, []int{12} } func (m *ExecuteBatchResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ExecuteBatchResponse.Unmarshal(m, b) @@ -1274,7 +1274,7 @@ 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_071b9c990aff35bf, []int{13} + return fileDescriptor_vtgate_8f5c6038eac4796e, []int{13} } func (m *BoundShardQuery) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_BoundShardQuery.Unmarshal(m, b) @@ -1342,7 +1342,7 @@ 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_071b9c990aff35bf, []int{14} + return fileDescriptor_vtgate_8f5c6038eac4796e, []int{14} } func (m *ExecuteBatchShardsRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ExecuteBatchShardsRequest.Unmarshal(m, b) @@ -1423,7 +1423,7 @@ 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_071b9c990aff35bf, []int{15} + return fileDescriptor_vtgate_8f5c6038eac4796e, []int{15} } func (m *ExecuteBatchShardsResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ExecuteBatchShardsResponse.Unmarshal(m, b) @@ -1484,7 +1484,7 @@ 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_071b9c990aff35bf, []int{16} + return fileDescriptor_vtgate_8f5c6038eac4796e, []int{16} } func (m *BoundKeyspaceIdQuery) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_BoundKeyspaceIdQuery.Unmarshal(m, b) @@ -1551,7 +1551,7 @@ 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_071b9c990aff35bf, []int{17} + return fileDescriptor_vtgate_8f5c6038eac4796e, []int{17} } func (m *ExecuteBatchKeyspaceIdsRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ExecuteBatchKeyspaceIdsRequest.Unmarshal(m, b) @@ -1632,7 +1632,7 @@ 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_071b9c990aff35bf, []int{18} + return fileDescriptor_vtgate_8f5c6038eac4796e, []int{18} } func (m *ExecuteBatchKeyspaceIdsResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ExecuteBatchKeyspaceIdsResponse.Unmarshal(m, b) @@ -1696,7 +1696,7 @@ 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_071b9c990aff35bf, []int{19} + return fileDescriptor_vtgate_8f5c6038eac4796e, []int{19} } func (m *StreamExecuteRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_StreamExecuteRequest.Unmarshal(m, b) @@ -1775,7 +1775,7 @@ 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_071b9c990aff35bf, []int{20} + return fileDescriptor_vtgate_8f5c6038eac4796e, []int{20} } func (m *StreamExecuteResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_StreamExecuteResponse.Unmarshal(m, b) @@ -1826,7 +1826,7 @@ 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_071b9c990aff35bf, []int{21} + return fileDescriptor_vtgate_8f5c6038eac4796e, []int{21} } func (m *StreamExecuteShardsRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_StreamExecuteShardsRequest.Unmarshal(m, b) @@ -1903,7 +1903,7 @@ 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_071b9c990aff35bf, []int{22} + return fileDescriptor_vtgate_8f5c6038eac4796e, []int{22} } func (m *StreamExecuteShardsResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_StreamExecuteShardsResponse.Unmarshal(m, b) @@ -1955,7 +1955,7 @@ 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_071b9c990aff35bf, []int{23} + return fileDescriptor_vtgate_8f5c6038eac4796e, []int{23} } func (m *StreamExecuteKeyspaceIdsRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_StreamExecuteKeyspaceIdsRequest.Unmarshal(m, b) @@ -2032,7 +2032,7 @@ 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_071b9c990aff35bf, []int{24} + return fileDescriptor_vtgate_8f5c6038eac4796e, []int{24} } func (m *StreamExecuteKeyspaceIdsResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_StreamExecuteKeyspaceIdsResponse.Unmarshal(m, b) @@ -2084,7 +2084,7 @@ 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_071b9c990aff35bf, []int{25} + return fileDescriptor_vtgate_8f5c6038eac4796e, []int{25} } func (m *StreamExecuteKeyRangesRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_StreamExecuteKeyRangesRequest.Unmarshal(m, b) @@ -2161,7 +2161,7 @@ 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_071b9c990aff35bf, []int{26} + return fileDescriptor_vtgate_8f5c6038eac4796e, []int{26} } func (m *StreamExecuteKeyRangesResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_StreamExecuteKeyRangesResponse.Unmarshal(m, b) @@ -2207,7 +2207,7 @@ 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_071b9c990aff35bf, []int{27} + return fileDescriptor_vtgate_8f5c6038eac4796e, []int{27} } func (m *BeginRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_BeginRequest.Unmarshal(m, b) @@ -2254,7 +2254,7 @@ 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_071b9c990aff35bf, []int{28} + return fileDescriptor_vtgate_8f5c6038eac4796e, []int{28} } func (m *BeginResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_BeginResponse.Unmarshal(m, b) @@ -2302,7 +2302,7 @@ 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_071b9c990aff35bf, []int{29} + return fileDescriptor_vtgate_8f5c6038eac4796e, []int{29} } func (m *CommitRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_CommitRequest.Unmarshal(m, b) @@ -2354,7 +2354,7 @@ 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_071b9c990aff35bf, []int{30} + return fileDescriptor_vtgate_8f5c6038eac4796e, []int{30} } func (m *CommitResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_CommitResponse.Unmarshal(m, b) @@ -2390,7 +2390,7 @@ 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_071b9c990aff35bf, []int{31} + return fileDescriptor_vtgate_8f5c6038eac4796e, []int{31} } func (m *RollbackRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_RollbackRequest.Unmarshal(m, b) @@ -2435,7 +2435,7 @@ 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_071b9c990aff35bf, []int{32} + return fileDescriptor_vtgate_8f5c6038eac4796e, []int{32} } func (m *RollbackResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_RollbackResponse.Unmarshal(m, b) @@ -2471,7 +2471,7 @@ 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_071b9c990aff35bf, []int{33} + return fileDescriptor_vtgate_8f5c6038eac4796e, []int{33} } func (m *ResolveTransactionRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ResolveTransactionRequest.Unmarshal(m, b) @@ -2527,7 +2527,7 @@ 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_071b9c990aff35bf, []int{34} + return fileDescriptor_vtgate_8f5c6038eac4796e, []int{34} } func (m *MessageStreamRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_MessageStreamRequest.Unmarshal(m, b) @@ -2602,7 +2602,7 @@ 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_071b9c990aff35bf, []int{35} + return fileDescriptor_vtgate_8f5c6038eac4796e, []int{35} } func (m *MessageAckRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_MessageAckRequest.Unmarshal(m, b) @@ -2666,7 +2666,7 @@ 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_071b9c990aff35bf, []int{36} + return fileDescriptor_vtgate_8f5c6038eac4796e, []int{36} } func (m *IdKeyspaceId) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_IdKeyspaceId.Unmarshal(m, b) @@ -2719,7 +2719,7 @@ 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_071b9c990aff35bf, []int{37} + return fileDescriptor_vtgate_8f5c6038eac4796e, []int{37} } func (m *MessageAckKeyspaceIdsRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_MessageAckKeyspaceIdsRequest.Unmarshal(m, b) @@ -2778,7 +2778,7 @@ 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_071b9c990aff35bf, []int{38} + return fileDescriptor_vtgate_8f5c6038eac4796e, []int{38} } func (m *ResolveTransactionResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ResolveTransactionResponse.Unmarshal(m, b) @@ -2896,7 +2896,7 @@ 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_071b9c990aff35bf, []int{39} + return fileDescriptor_vtgate_8f5c6038eac4796e, []int{39} } func (m *SplitQueryRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_SplitQueryRequest.Unmarshal(m, b) @@ -2985,7 +2985,7 @@ 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_071b9c990aff35bf, []int{40} + return fileDescriptor_vtgate_8f5c6038eac4796e, []int{40} } func (m *SplitQueryResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_SplitQueryResponse.Unmarshal(m, b) @@ -3026,7 +3026,7 @@ 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_071b9c990aff35bf, []int{40, 0} + return fileDescriptor_vtgate_8f5c6038eac4796e, []int{40, 0} } func (m *SplitQueryResponse_KeyRangePart) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_SplitQueryResponse_KeyRangePart.Unmarshal(m, b) @@ -3074,7 +3074,7 @@ 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_071b9c990aff35bf, []int{40, 1} + return fileDescriptor_vtgate_8f5c6038eac4796e, []int{40, 1} } func (m *SplitQueryResponse_ShardPart) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_SplitQueryResponse_ShardPart.Unmarshal(m, b) @@ -3127,7 +3127,7 @@ 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_071b9c990aff35bf, []int{40, 2} + return fileDescriptor_vtgate_8f5c6038eac4796e, []int{40, 2} } func (m *SplitQueryResponse_Part) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_SplitQueryResponse_Part.Unmarshal(m, b) @@ -3188,7 +3188,7 @@ 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_071b9c990aff35bf, []int{41} + return fileDescriptor_vtgate_8f5c6038eac4796e, []int{41} } func (m *GetSrvKeyspaceRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_GetSrvKeyspaceRequest.Unmarshal(m, b) @@ -3228,7 +3228,7 @@ 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_071b9c990aff35bf, []int{42} + return fileDescriptor_vtgate_8f5c6038eac4796e, []int{42} } func (m *GetSrvKeyspaceResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_GetSrvKeyspaceResponse.Unmarshal(m, b) @@ -3286,7 +3286,7 @@ 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_071b9c990aff35bf, []int{43} + return fileDescriptor_vtgate_8f5c6038eac4796e, []int{43} } func (m *UpdateStreamRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_UpdateStreamRequest.Unmarshal(m, b) @@ -3374,7 +3374,7 @@ 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_071b9c990aff35bf, []int{44} + return fileDescriptor_vtgate_8f5c6038eac4796e, []int{44} } func (m *UpdateStreamResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_UpdateStreamResponse.Unmarshal(m, b) @@ -3462,9 +3462,9 @@ func init() { proto.RegisterEnum("vtgate.TransactionMode", TransactionMode_name, TransactionMode_value) } -func init() { proto.RegisterFile("vtgate.proto", fileDescriptor_vtgate_071b9c990aff35bf) } +func init() { proto.RegisterFile("vtgate.proto", fileDescriptor_vtgate_8f5c6038eac4796e) } -var fileDescriptor_vtgate_071b9c990aff35bf = []byte{ +var fileDescriptor_vtgate_8f5c6038eac4796e = []byte{ // 1883 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x5a, 0x4f, 0x8f, 0x23, 0x47, 0x15, 0xa7, 0xbb, 0xfd, 0xf7, 0xf9, 0xef, 0xd6, 0x78, 0x77, 0x1d, 0x67, 0xd8, 0x99, 0x74, 0x18, diff --git a/go/vt/proto/vtgateservice/vtgateservice.pb.go b/go/vt/proto/vtgateservice/vtgateservice.pb.go index 7d9302b07fe..3a0bc073da8 100644 --- a/go/vt/proto/vtgateservice/vtgateservice.pb.go +++ b/go/vt/proto/vtgateservice/vtgateservice.pb.go @@ -1069,9 +1069,9 @@ var _Vitess_serviceDesc = grpc.ServiceDesc{ Metadata: "vtgateservice.proto", } -func init() { proto.RegisterFile("vtgateservice.proto", fileDescriptor_vtgateservice_7815d679f21c0eb2) } +func init() { proto.RegisterFile("vtgateservice.proto", fileDescriptor_vtgateservice_6694e3d05903167c) } -var fileDescriptor_vtgateservice_7815d679f21c0eb2 = []byte{ +var fileDescriptor_vtgateservice_6694e3d05903167c = []byte{ // 579 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x95, 0xdb, 0x6f, 0xd3, 0x30, 0x14, 0xc6, 0xe1, 0x81, 0x82, 0x0e, 0xed, 0x84, 0xbc, 0xad, 0xdb, 0xca, 0x75, 0x05, 0x36, 0xc4, diff --git a/go/vt/proto/vtrpc/vtrpc.pb.go b/go/vt/proto/vtrpc/vtrpc.pb.go index a65e8735874..a9b53a78efa 100644 --- a/go/vt/proto/vtrpc/vtrpc.pb.go +++ b/go/vt/proto/vtrpc/vtrpc.pb.go @@ -168,7 +168,7 @@ func (x Code) String() string { return proto.EnumName(Code_name, int32(x)) } func (Code) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_vtrpc_63266364cf161411, []int{0} + return fileDescriptor_vtrpc_88a14d8f1bc03cf5, []int{0} } // LegacyErrorCode is the enum values for Errors. This type is deprecated. @@ -276,7 +276,7 @@ func (x LegacyErrorCode) String() string { return proto.EnumName(LegacyErrorCode_name, int32(x)) } func (LegacyErrorCode) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_vtrpc_63266364cf161411, []int{1} + return fileDescriptor_vtrpc_88a14d8f1bc03cf5, []int{1} } // CallerID is passed along RPCs to identify the originating client @@ -311,7 +311,7 @@ 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_63266364cf161411, []int{0} + return fileDescriptor_vtrpc_88a14d8f1bc03cf5, []int{0} } func (m *CallerID) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_CallerID.Unmarshal(m, b) @@ -369,7 +369,7 @@ 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_63266364cf161411, []int{1} + return fileDescriptor_vtrpc_88a14d8f1bc03cf5, []int{1} } func (m *RPCError) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_RPCError.Unmarshal(m, b) @@ -417,9 +417,9 @@ func init() { proto.RegisterEnum("vtrpc.LegacyErrorCode", LegacyErrorCode_name, LegacyErrorCode_value) } -func init() { proto.RegisterFile("vtrpc.proto", fileDescriptor_vtrpc_63266364cf161411) } +func init() { proto.RegisterFile("vtrpc.proto", fileDescriptor_vtrpc_88a14d8f1bc03cf5) } -var fileDescriptor_vtrpc_63266364cf161411 = []byte{ +var fileDescriptor_vtrpc_88a14d8f1bc03cf5 = []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 ffb667b13fa..b53058b7dc2 100644 --- a/go/vt/proto/vttest/vttest.pb.go +++ b/go/vt/proto/vttest/vttest.pb.go @@ -37,7 +37,7 @@ 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_beaece7261b82562, []int{0} + return fileDescriptor_vttest_6aca346ef34e15cf, []int{0} } func (m *Shard) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Shard.Unmarshal(m, b) @@ -96,7 +96,7 @@ 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_beaece7261b82562, []int{1} + return fileDescriptor_vttest_6aca346ef34e15cf, []int{1} } func (m *Keyspace) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Keyspace.Unmarshal(m, b) @@ -180,7 +180,7 @@ 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_beaece7261b82562, []int{2} + return fileDescriptor_vttest_6aca346ef34e15cf, []int{2} } func (m *VTTestTopology) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_VTTestTopology.Unmarshal(m, b) @@ -220,9 +220,9 @@ func init() { proto.RegisterType((*VTTestTopology)(nil), "vttest.VTTestTopology") } -func init() { proto.RegisterFile("vttest.proto", fileDescriptor_vttest_beaece7261b82562) } +func init() { proto.RegisterFile("vttest.proto", fileDescriptor_vttest_6aca346ef34e15cf) } -var fileDescriptor_vttest_beaece7261b82562 = []byte{ +var fileDescriptor_vttest_6aca346ef34e15cf = []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/vtworkerdata/vtworkerdata.pb.go b/go/vt/proto/vtworkerdata/vtworkerdata.pb.go index 4944c62ba3c..42135571576 100644 --- a/go/vt/proto/vtworkerdata/vtworkerdata.pb.go +++ b/go/vt/proto/vtworkerdata/vtworkerdata.pb.go @@ -31,7 +31,7 @@ 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_9c94bc714251542b, []int{0} + return fileDescriptor_vtworkerdata_cae0940479e6aeb1, []int{0} } func (m *ExecuteVtworkerCommandRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ExecuteVtworkerCommandRequest.Unmarshal(m, b) @@ -70,7 +70,7 @@ 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_9c94bc714251542b, []int{1} + return fileDescriptor_vtworkerdata_cae0940479e6aeb1, []int{1} } func (m *ExecuteVtworkerCommandResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ExecuteVtworkerCommandResponse.Unmarshal(m, b) @@ -102,9 +102,9 @@ func init() { proto.RegisterType((*ExecuteVtworkerCommandResponse)(nil), "vtworkerdata.ExecuteVtworkerCommandResponse") } -func init() { proto.RegisterFile("vtworkerdata.proto", fileDescriptor_vtworkerdata_9c94bc714251542b) } +func init() { proto.RegisterFile("vtworkerdata.proto", fileDescriptor_vtworkerdata_cae0940479e6aeb1) } -var fileDescriptor_vtworkerdata_9c94bc714251542b = []byte{ +var fileDescriptor_vtworkerdata_cae0940479e6aeb1 = []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 015b0945e9d..bc38e2eca4c 100644 --- a/go/vt/proto/vtworkerservice/vtworkerservice.pb.go +++ b/go/vt/proto/vtworkerservice/vtworkerservice.pb.go @@ -128,10 +128,10 @@ var _Vtworker_serviceDesc = grpc.ServiceDesc{ } func init() { - proto.RegisterFile("vtworkerservice.proto", fileDescriptor_vtworkerservice_0d36cb3c7cfddd2b) + proto.RegisterFile("vtworkerservice.proto", fileDescriptor_vtworkerservice_4efa3310356e3c00) } -var fileDescriptor_vtworkerservice_0d36cb3c7cfddd2b = []byte{ +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, diff --git a/go/vt/proto/workflow/workflow.pb.go b/go/vt/proto/workflow/workflow.pb.go index 5b0fb41e1cd..8c173f294b2 100644 --- a/go/vt/proto/workflow/workflow.pb.go +++ b/go/vt/proto/workflow/workflow.pb.go @@ -45,7 +45,7 @@ func (x WorkflowState) String() string { return proto.EnumName(WorkflowState_name, int32(x)) } func (WorkflowState) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_workflow_cc5eebeb403313d8, []int{0} + return fileDescriptor_workflow_daba593a7423a6c7, []int{0} } type TaskState int32 @@ -71,7 +71,7 @@ func (x TaskState) String() string { return proto.EnumName(TaskState_name, int32(x)) } func (TaskState) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_workflow_cc5eebeb403313d8, []int{1} + return fileDescriptor_workflow_daba593a7423a6c7, []int{1} } // Workflow is the persisted state of a long-running workflow. @@ -119,7 +119,7 @@ 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_cc5eebeb403313d8, []int{0} + return fileDescriptor_workflow_daba593a7423a6c7, []int{0} } func (m *Workflow) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Workflow.Unmarshal(m, b) @@ -223,7 +223,7 @@ 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_cc5eebeb403313d8, []int{1} + return fileDescriptor_workflow_daba593a7423a6c7, []int{1} } func (m *WorkflowCheckpoint) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_WorkflowCheckpoint.Unmarshal(m, b) @@ -279,7 +279,7 @@ 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_cc5eebeb403313d8, []int{2} + return fileDescriptor_workflow_daba593a7423a6c7, []int{2} } func (m *Task) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Task.Unmarshal(m, b) @@ -338,9 +338,9 @@ func init() { proto.RegisterEnum("workflow.TaskState", TaskState_name, TaskState_value) } -func init() { proto.RegisterFile("workflow.proto", fileDescriptor_workflow_cc5eebeb403313d8) } +func init() { proto.RegisterFile("workflow.proto", fileDescriptor_workflow_daba593a7423a6c7) } -var fileDescriptor_workflow_cc5eebeb403313d8 = []byte{ +var fileDescriptor_workflow_daba593a7423a6c7 = []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/py/vtproto/topodata_pb2.py b/py/vtproto/topodata_pb2.py index e74204fad56..b048124834d 100644 --- a/py/vtproto/topodata_pb2.py +++ b/py/vtproto/topodata_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='topodata.proto', 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\"\xdb\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\r\n\x05\x63\x65lls\x18\x05 \x03(\t\x12\x36\n\x0ftablet_controls\x18\x06 \x03(\x0b\x32\x1d.topodata.Shard.TabletControl\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\x94\x01\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\x1d\n\x15\x64isable_query_service\x18\x03 \x01(\x08\x12\x1a\n\x12\x62lacklisted_tables\x18\x04 \x03(\t\x12\x0e\n\x06\x66rozen\x18\x05 \x01(\x08\"\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\"\x9c\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\x1ar\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\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\"@\n\x08\x43\x65llInfo\x12\x16\n\x0eserver_address\x18\x01 \x01(\t\x12\x0c\n\x04root\x18\x02 \x01(\t\x12\x0e\n\x06region\x18\x03 \x01(\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') ) @@ -31,19 +31,19 @@ values=[ _descriptor.EnumValueDescriptor( name='UNSET', index=0, number=0, - options=None, + serialized_options=None, type=None), _descriptor.EnumValueDescriptor( name='UINT64', index=1, number=1, - options=None, + serialized_options=None, type=None), _descriptor.EnumValueDescriptor( name='BYTES', index=2, number=2, - options=None, + serialized_options=None, type=None), ], containing_type=None, - options=None, + serialized_options=None, serialized_start=2078, serialized_end=2128, ) @@ -58,47 +58,47 @@ values=[ _descriptor.EnumValueDescriptor( name='UNKNOWN', index=0, number=0, - options=None, + serialized_options=None, type=None), _descriptor.EnumValueDescriptor( name='MASTER', index=1, number=1, - options=None, + serialized_options=None, type=None), _descriptor.EnumValueDescriptor( name='REPLICA', index=2, number=2, - options=None, + serialized_options=None, type=None), _descriptor.EnumValueDescriptor( name='RDONLY', index=3, number=3, - options=None, + serialized_options=None, type=None), _descriptor.EnumValueDescriptor( name='BATCH', index=4, number=3, - options=None, + serialized_options=None, type=None), _descriptor.EnumValueDescriptor( name='SPARE', index=5, number=4, - options=None, + serialized_options=None, type=None), _descriptor.EnumValueDescriptor( name='EXPERIMENTAL', index=6, number=5, - options=None, + serialized_options=None, type=None), _descriptor.EnumValueDescriptor( name='BACKUP', index=7, number=6, - options=None, + serialized_options=None, type=None), _descriptor.EnumValueDescriptor( name='RESTORE', index=8, number=7, - options=None, + serialized_options=None, type=None), _descriptor.EnumValueDescriptor( name='DRAINED', index=9, number=8, - options=None, + serialized_options=None, type=None), ], containing_type=None, - options=_descriptor._ParseOptions(descriptor_pb2.EnumOptions(), _b('\020\001')), + serialized_options=_b('\020\001'), serialized_start=2131, serialized_end=2275, ) @@ -134,21 +134,21 @@ has_default_value=False, default_value=_b(""), 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='end', full_name='topodata.KeyRange.end', index=1, number=2, type=12, cpp_type=9, label=1, has_default_value=False, default_value=_b(""), 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=[], @@ -172,21 +172,21 @@ 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='uid', full_name='topodata.TabletAlias.uid', index=1, number=2, type=13, cpp_type=3, 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=[], @@ -210,21 +210,21 @@ 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='value', full_name='topodata.Tablet.PortMapEntry.value', 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), + serialized_options=None, file=DESCRIPTOR), ], extensions=[ ], nested_types=[], enum_types=[ ], - options=_descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001')), + serialized_options=_b('8\001'), is_extendable=False, syntax='proto3', extension_ranges=[], @@ -247,21 +247,21 @@ 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='value', full_name='topodata.Tablet.TagsEntry.value', 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), ], extensions=[ ], nested_types=[], enum_types=[ ], - options=_descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001')), + serialized_options=_b('8\001'), is_extendable=False, syntax='proto3', extension_ranges=[], @@ -284,84 +284,84 @@ 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='hostname', full_name='topodata.Tablet.hostname', 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='port_map', full_name='topodata.Tablet.port_map', 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, - options=None, file=DESCRIPTOR), + serialized_options=None, file=DESCRIPTOR), _descriptor.FieldDescriptor( name='keyspace', full_name='topodata.Tablet.keyspace', index=3, 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), _descriptor.FieldDescriptor( name='shard', full_name='topodata.Tablet.shard', 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, - options=None, file=DESCRIPTOR), + serialized_options=None, file=DESCRIPTOR), _descriptor.FieldDescriptor( name='key_range', full_name='topodata.Tablet.key_range', 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, - options=None, file=DESCRIPTOR), + serialized_options=None, file=DESCRIPTOR), _descriptor.FieldDescriptor( name='type', full_name='topodata.Tablet.type', index=6, number=8, 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='db_name_override', full_name='topodata.Tablet.db_name_override', index=7, number=9, 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='tags', full_name='topodata.Tablet.tags', index=8, number=10, 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, - options=None, file=DESCRIPTOR), + serialized_options=None, file=DESCRIPTOR), _descriptor.FieldDescriptor( name='mysql_hostname', full_name='topodata.Tablet.mysql_hostname', index=9, number=12, 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='mysql_port', full_name='topodata.Tablet.mysql_port', index=10, number=13, 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), + serialized_options=None, file=DESCRIPTOR), ], extensions=[ ], nested_types=[_TABLET_PORTMAPENTRY, _TABLET_TAGSENTRY, ], enum_types=[ ], - options=None, + serialized_options=None, is_extendable=False, syntax='proto3', extension_ranges=[], @@ -385,21 +385,21 @@ 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='cells', full_name='topodata.Shard.ServedType.cells', index=1, number=2, 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, - 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=[], @@ -422,42 +422,42 @@ 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='keyspace', full_name='topodata.Shard.SourceShard.keyspace', 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='shard', full_name='topodata.Shard.SourceShard.shard', 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='key_range', full_name='topodata.Shard.SourceShard.key_range', index=3, number=4, 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, - options=None, file=DESCRIPTOR), + serialized_options=None, file=DESCRIPTOR), _descriptor.FieldDescriptor( name='tables', full_name='topodata.Shard.SourceShard.tables', index=4, number=5, 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, - 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=[], @@ -480,42 +480,42 @@ 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='cells', full_name='topodata.Shard.TabletControl.cells', index=1, number=2, 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, - options=None, file=DESCRIPTOR), + serialized_options=None, file=DESCRIPTOR), _descriptor.FieldDescriptor( name='disable_query_service', full_name='topodata.Shard.TabletControl.disable_query_service', index=2, 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, is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), + serialized_options=None, file=DESCRIPTOR), _descriptor.FieldDescriptor( name='blacklisted_tables', full_name='topodata.Shard.TabletControl.blacklisted_tables', index=3, number=4, 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, - options=None, file=DESCRIPTOR), + serialized_options=None, file=DESCRIPTOR), _descriptor.FieldDescriptor( name='frozen', full_name='topodata.Shard.TabletControl.frozen', index=4, number=5, 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, - 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=[], @@ -538,49 +538,49 @@ 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='key_range', full_name='topodata.Shard.key_range', 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, - options=None, file=DESCRIPTOR), + serialized_options=None, file=DESCRIPTOR), _descriptor.FieldDescriptor( name='served_types', full_name='topodata.Shard.served_types', index=2, 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, - options=None, file=DESCRIPTOR), + serialized_options=None, file=DESCRIPTOR), _descriptor.FieldDescriptor( name='source_shards', full_name='topodata.Shard.source_shards', index=3, 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, - options=None, file=DESCRIPTOR), + serialized_options=None, file=DESCRIPTOR), _descriptor.FieldDescriptor( name='cells', full_name='topodata.Shard.cells', index=4, number=5, 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, - options=None, file=DESCRIPTOR), + serialized_options=None, file=DESCRIPTOR), _descriptor.FieldDescriptor( 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, - options=None, file=DESCRIPTOR), + serialized_options=None, file=DESCRIPTOR), ], extensions=[ ], nested_types=[_SHARD_SERVEDTYPE, _SHARD_SOURCESHARD, _SHARD_TABLETCONTROL, ], enum_types=[ ], - options=None, + serialized_options=None, is_extendable=False, syntax='proto3', extension_ranges=[], @@ -604,28 +604,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='cells', full_name='topodata.Keyspace.ServedFrom.cells', index=1, number=2, 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, - options=None, file=DESCRIPTOR), + serialized_options=None, file=DESCRIPTOR), _descriptor.FieldDescriptor( name='keyspace', full_name='topodata.Keyspace.ServedFrom.keyspace', 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=[], @@ -648,28 +648,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='sharding_column_type', full_name='topodata.Keyspace.sharding_column_type', 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='served_froms', full_name='topodata.Keyspace.served_froms', 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, - options=None, file=DESCRIPTOR), + serialized_options=None, file=DESCRIPTOR), ], extensions=[ ], nested_types=[_KEYSPACE_SERVEDFROM, ], enum_types=[ ], - options=None, + serialized_options=None, is_extendable=False, syntax='proto3', extension_ranges=[], @@ -693,14 +693,14 @@ 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), ], extensions=[ ], nested_types=[], enum_types=[ ], - options=None, + serialized_options=None, is_extendable=False, syntax='proto3', extension_ranges=[], @@ -723,14 +723,14 @@ has_default_value=False, default_value=[], 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=[_SHARDREPLICATION_NODE, ], enum_types=[ ], - options=None, + serialized_options=None, is_extendable=False, syntax='proto3', extension_ranges=[], @@ -754,21 +754,21 @@ 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='key_range', full_name='topodata.ShardReference.key_range', 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, - 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=[], @@ -792,21 +792,21 @@ 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='shard_references', full_name='topodata.SrvKeyspace.KeyspacePartition.shard_references', index=1, number=2, 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, - 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=[], @@ -829,21 +829,21 @@ 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='keyspace', full_name='topodata.SrvKeyspace.ServedFrom.keyspace', 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), ], extensions=[ ], nested_types=[], enum_types=[ ], - options=None, + serialized_options=None, is_extendable=False, syntax='proto3', extension_ranges=[], @@ -866,35 +866,35 @@ has_default_value=False, default_value=[], 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='sharding_column_name', full_name='topodata.SrvKeyspace.sharding_column_name', 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='sharding_column_type', full_name='topodata.SrvKeyspace.sharding_column_type', 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), _descriptor.FieldDescriptor( name='served_from', full_name='topodata.SrvKeyspace.served_from', index=3, 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, - options=None, file=DESCRIPTOR), + serialized_options=None, file=DESCRIPTOR), ], extensions=[ ], nested_types=[_SRVKEYSPACE_KEYSPACEPARTITION, _SRVKEYSPACE_SERVEDFROM, ], enum_types=[ ], - options=None, + serialized_options=None, is_extendable=False, syntax='proto3', extension_ranges=[], @@ -918,28 +918,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='root', full_name='topodata.CellInfo.root', 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='region', full_name='topodata.CellInfo.region', 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=[], @@ -1132,12 +1132,8 @@ _sym_db.RegisterMessage(CellInfo) -DESCRIPTOR.has_options = True -DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), _b('\n\017io.vitess.protoZ%vitess.io/vitess/go/vt/proto/topodata')) -_TABLETTYPE.has_options = True -_TABLETTYPE._options = _descriptor._ParseOptions(descriptor_pb2.EnumOptions(), _b('\020\001')) -_TABLET_PORTMAPENTRY.has_options = True -_TABLET_PORTMAPENTRY._options = _descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001')) -_TABLET_TAGSENTRY.has_options = True -_TABLET_TAGSENTRY._options = _descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001')) +DESCRIPTOR._options = None +_TABLETTYPE._options = None +_TABLET_PORTMAPENTRY._options = None +_TABLET_TAGSENTRY._options = None # @@protoc_insertion_point(module_scope) From f5868c6f7299ac19ea7ddc99fa62e6cf7ee5ba94 Mon Sep 17 00:00:00 2001 From: Sugu Sougoumarane Date: Wed, 26 Dec 2018 14:01:51 -0800 Subject: [PATCH 017/115] vreplication: vstreamer Engine Signed-off-by: Sugu Sougoumarane --- go/vt/proto/binlogdata/binlogdata.pb.go | 216 +++++++++++++----- .../vttablet/tabletserver/vstreamer/engine.go | 171 ++++++++++++++ .../tabletserver/vstreamer/streamer.go | 54 +++++ proto/binlogdata.proto | 21 ++ py/vtproto/binlogdata_pb2.py | 185 +++++++++++---- 5 files changed, 547 insertions(+), 100 deletions(-) create mode 100644 go/vt/vttablet/tabletserver/vstreamer/engine.go create mode 100644 go/vt/vttablet/tabletserver/vstreamer/streamer.go diff --git a/go/vt/proto/binlogdata/binlogdata.pb.go b/go/vt/proto/binlogdata/binlogdata.pb.go index 5214ce5f4d4..62fe086a107 100644 --- a/go/vt/proto/binlogdata/binlogdata.pb.go +++ b/go/vt/proto/binlogdata/binlogdata.pb.go @@ -65,7 +65,7 @@ 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_599cd600856cd9fe, []int{1, 0, 0} + return fileDescriptor_binlogdata_e83d7972bcc6f0aa, []int{1, 0, 0} } // Charset is the per-statement charset info from a QUERY_EVENT binlog entry. @@ -85,7 +85,7 @@ 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_599cd600856cd9fe, []int{0} + return fileDescriptor_binlogdata_e83d7972bcc6f0aa, []int{0} } func (m *Charset) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Charset.Unmarshal(m, b) @@ -142,7 +142,7 @@ 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_599cd600856cd9fe, []int{1} + return fileDescriptor_binlogdata_e83d7972bcc6f0aa, []int{1} } func (m *BinlogTransaction) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_BinlogTransaction.Unmarshal(m, b) @@ -192,7 +192,7 @@ 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_599cd600856cd9fe, []int{1, 0} + return fileDescriptor_binlogdata_e83d7972bcc6f0aa, []int{1, 0} } func (m *BinlogTransaction_Statement) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_BinlogTransaction_Statement.Unmarshal(m, b) @@ -250,7 +250,7 @@ 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_599cd600856cd9fe, []int{2} + return fileDescriptor_binlogdata_e83d7972bcc6f0aa, []int{2} } func (m *StreamKeyRangeRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_StreamKeyRangeRequest.Unmarshal(m, b) @@ -303,7 +303,7 @@ 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_599cd600856cd9fe, []int{3} + return fileDescriptor_binlogdata_e83d7972bcc6f0aa, []int{3} } func (m *StreamKeyRangeResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_StreamKeyRangeResponse.Unmarshal(m, b) @@ -347,7 +347,7 @@ 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_599cd600856cd9fe, []int{4} + return fileDescriptor_binlogdata_e83d7972bcc6f0aa, []int{4} } func (m *StreamTablesRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_StreamTablesRequest.Unmarshal(m, b) @@ -400,7 +400,7 @@ 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_599cd600856cd9fe, []int{5} + return fileDescriptor_binlogdata_e83d7972bcc6f0aa, []int{5} } func (m *StreamTablesResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_StreamTablesResponse.Unmarshal(m, b) @@ -427,6 +427,98 @@ func (m *StreamTablesResponse) GetBinlogTransaction() *BinlogTransaction { return nil } +// Rule represents one rule. +type Rule struct { + // match can be a table name or a regular expression + // delineated by '/' and '/'. + Match string `protobuf:"bytes,1,opt,name=match,proto3" json:"match,omitempty"` + // filter can be an empty string or keyrange if the match + // is a regular expression. Otherwise, it must be a select + // query. + Filter string `protobuf:"bytes,2,opt,name=filter,proto3" json:"filter,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +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_e83d7972bcc6f0aa, []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_Size() int { + return xxx_messageInfo_Rule.Size(m) +} +func (m *Rule) XXX_DiscardUnknown() { + xxx_messageInfo_Rule.DiscardUnknown(m) +} + +var xxx_messageInfo_Rule proto.InternalMessageInfo + +func (m *Rule) GetMatch() string { + if m != nil { + return m.Match + } + return "" +} + +func (m *Rule) GetFilter() string { + if m != nil { + return m.Filter + } + return "" +} + +// 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:"-"` +} + +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_e83d7972bcc6f0aa, []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_Size() int { + return xxx_messageInfo_Filter.Size(m) +} +func (m *Filter) XXX_DiscardUnknown() { + xxx_messageInfo_Filter.DiscardUnknown(m) +} + +var xxx_messageInfo_Filter proto.InternalMessageInfo + +func (m *Filter) GetRules() []*Rule { + if m != nil { + return m.Rules + } + return nil +} + // BinlogSource specifies the source and filter parameters for // Filtered Replication. It currently supports a keyrange // or a list of tables. @@ -440,7 +532,10 @@ type BinlogSource struct { // key_range is set if the request is for a keyrange KeyRange *topodata.KeyRange `protobuf:"bytes,4,opt,name=key_range,json=keyRange,proto3" json:"key_range,omitempty"` // tables is set if the request is for a list of tables - Tables []string `protobuf:"bytes,5,rep,name=tables,proto3" json:"tables,omitempty"` + Tables []string `protobuf:"bytes,5,rep,name=tables,proto3" json:"tables,omitempty"` + // filter is set if we're using the generalized representation + // for the filter. + Filter *Filter `protobuf:"bytes,6,opt,name=filter,proto3" json:"filter,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -450,7 +545,7 @@ 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_599cd600856cd9fe, []int{6} + return fileDescriptor_binlogdata_e83d7972bcc6f0aa, []int{8} } func (m *BinlogSource) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_BinlogSource.Unmarshal(m, b) @@ -505,6 +600,13 @@ func (m *BinlogSource) GetTables() []string { return nil } +func (m *BinlogSource) GetFilter() *Filter { + if m != nil { + return m.Filter + } + return nil +} + func init() { proto.RegisterType((*Charset)(nil), "binlogdata.Charset") proto.RegisterType((*BinlogTransaction)(nil), "binlogdata.BinlogTransaction") @@ -513,52 +615,58 @@ func init() { proto.RegisterType((*StreamKeyRangeResponse)(nil), "binlogdata.StreamKeyRangeResponse") proto.RegisterType((*StreamTablesRequest)(nil), "binlogdata.StreamTablesRequest") proto.RegisterType((*StreamTablesResponse)(nil), "binlogdata.StreamTablesResponse") + proto.RegisterType((*Rule)(nil), "binlogdata.Rule") + proto.RegisterType((*Filter)(nil), "binlogdata.Filter") proto.RegisterType((*BinlogSource)(nil), "binlogdata.BinlogSource") proto.RegisterEnum("binlogdata.BinlogTransaction_Statement_Category", BinlogTransaction_Statement_Category_name, BinlogTransaction_Statement_Category_value) } -func init() { proto.RegisterFile("binlogdata.proto", fileDescriptor_binlogdata_599cd600856cd9fe) } - -var fileDescriptor_binlogdata_599cd600856cd9fe = []byte{ - // 640 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x54, 0xcd, 0x6e, 0xda, 0x4a, - 0x14, 0xbe, 0xc6, 0x40, 0xec, 0xe3, 0xdc, 0x64, 0x98, 0xfc, 0x08, 0x21, 0x5d, 0x09, 0xb1, 0x09, - 0x77, 0x71, 0xcd, 0x95, 0xab, 0x3e, 0x40, 0x8c, 0xad, 0x88, 0xc4, 0x90, 0x68, 0x70, 0x36, 0xd9, - 0x58, 0xc6, 0x99, 0x12, 0x04, 0xf1, 0x38, 0x9e, 0x09, 0xaa, 0x9f, 0xa3, 0x4f, 0xd1, 0xb7, 0xe8, - 0xaa, 0x6f, 0xd2, 0xf7, 0xa8, 0x3c, 0x36, 0x86, 0xa4, 0x52, 0x9b, 0x2e, 0xba, 0x3b, 0xdf, 0x99, - 0xef, 0x9c, 0x39, 0xdf, 0x37, 0x47, 0x03, 0x68, 0xb6, 0x88, 0x57, 0x6c, 0x7e, 0x1f, 0x8a, 0xd0, - 0x4c, 0x52, 0x26, 0x18, 0x86, 0x6d, 0xa6, 0x63, 0x3c, 0x3d, 0xd3, 0x34, 0x2b, 0x0e, 0x3a, 0x07, - 0x82, 0x25, 0x6c, 0x4b, 0xec, 0x8d, 0x61, 0x6f, 0xf8, 0x10, 0xa6, 0x9c, 0x0a, 0x7c, 0x0a, 0xcd, - 0x68, 0xb5, 0xa0, 0xb1, 0x68, 0x2b, 0x5d, 0xa5, 0xdf, 0x20, 0x25, 0xc2, 0x18, 0xea, 0x11, 0x8b, - 0xe3, 0x76, 0x4d, 0x66, 0x65, 0x9c, 0x73, 0x39, 0x4d, 0xd7, 0x34, 0x6d, 0xab, 0x05, 0xb7, 0x40, - 0xbd, 0x6f, 0x2a, 0xb4, 0x6c, 0x79, 0xb5, 0x9f, 0x86, 0x31, 0x0f, 0x23, 0xb1, 0x60, 0x31, 0xbe, - 0x00, 0xe0, 0x22, 0x14, 0xf4, 0x91, 0xc6, 0x82, 0xb7, 0x95, 0xae, 0xda, 0x37, 0xac, 0x33, 0x73, - 0x67, 0xe8, 0x1f, 0x4a, 0xcc, 0xe9, 0x86, 0x4f, 0x76, 0x4a, 0xb1, 0x05, 0x06, 0x5d, 0xd3, 0x58, - 0x04, 0x82, 0x2d, 0x69, 0xdc, 0xae, 0x77, 0x95, 0xbe, 0x61, 0xb5, 0xcc, 0x42, 0xa0, 0x9b, 0x9f, - 0xf8, 0xf9, 0x01, 0x01, 0x5a, 0xc5, 0x9d, 0xaf, 0x35, 0xd0, 0xab, 0x6e, 0xd8, 0x03, 0x2d, 0x0a, - 0x05, 0x9d, 0xb3, 0x34, 0x93, 0x32, 0x0f, 0xac, 0xff, 0xdf, 0x38, 0x88, 0x39, 0x2c, 0xeb, 0x48, - 0xd5, 0x01, 0xff, 0x07, 0x7b, 0x51, 0xe1, 0x9e, 0x74, 0xc7, 0xb0, 0x8e, 0x76, 0x9b, 0x95, 0xc6, - 0x92, 0x0d, 0x07, 0x23, 0x50, 0xf9, 0xd3, 0x4a, 0x5a, 0xb6, 0x4f, 0xf2, 0xb0, 0xf7, 0x59, 0x01, - 0x6d, 0xd3, 0x17, 0x1f, 0xc1, 0xa1, 0xed, 0x05, 0xb7, 0x13, 0xe2, 0x0e, 0xaf, 0x2f, 0x26, 0xa3, - 0x3b, 0xd7, 0x41, 0x7f, 0xe1, 0x7d, 0xd0, 0x6c, 0x2f, 0xb0, 0xdd, 0x8b, 0xd1, 0x04, 0x29, 0xf8, - 0x6f, 0xd0, 0x6d, 0x2f, 0x18, 0x5e, 0x8f, 0xc7, 0x23, 0x1f, 0xd5, 0xf0, 0x21, 0x18, 0xb6, 0x17, - 0x90, 0x6b, 0xcf, 0xb3, 0xcf, 0x87, 0x57, 0x48, 0xc5, 0x27, 0xd0, 0xb2, 0xbd, 0xc0, 0x19, 0x7b, - 0x81, 0xe3, 0xde, 0x10, 0x77, 0x78, 0xee, 0xbb, 0x0e, 0xaa, 0x63, 0x80, 0x66, 0x9e, 0x76, 0x3c, - 0xd4, 0x28, 0xe3, 0xa9, 0xeb, 0xa3, 0x66, 0xd9, 0x6e, 0x34, 0x99, 0xba, 0xc4, 0x47, 0x7b, 0x25, - 0xbc, 0xbd, 0x71, 0xce, 0x7d, 0x17, 0x69, 0x25, 0x74, 0x5c, 0xcf, 0xf5, 0x5d, 0xa4, 0x5f, 0xd6, - 0xb5, 0x1a, 0x52, 0x2f, 0xeb, 0x9a, 0x8a, 0xea, 0xbd, 0x4f, 0x0a, 0x9c, 0x4c, 0x45, 0x4a, 0xc3, - 0xc7, 0x2b, 0x9a, 0x91, 0x30, 0x9e, 0x53, 0x42, 0x9f, 0x9e, 0x29, 0x17, 0xb8, 0x03, 0x5a, 0xc2, - 0xf8, 0x22, 0xf7, 0x4e, 0x1a, 0xac, 0x93, 0x0a, 0xe3, 0x01, 0xe8, 0x4b, 0x9a, 0x05, 0x69, 0xce, - 0x2f, 0x0d, 0xc3, 0x66, 0xb5, 0x90, 0x55, 0x27, 0x6d, 0x59, 0x46, 0xbb, 0xfe, 0xaa, 0xbf, 0xf6, - 0xb7, 0xf7, 0x01, 0x4e, 0x5f, 0x0f, 0xc5, 0x13, 0x16, 0x73, 0x8a, 0x3d, 0xc0, 0x45, 0x61, 0x20, - 0xb6, 0x6f, 0x2b, 0xe7, 0x33, 0xac, 0x7f, 0x7e, 0xba, 0x00, 0xa4, 0x35, 0x7b, 0x9d, 0xea, 0x7d, - 0x84, 0xa3, 0xe2, 0x1e, 0x3f, 0x9c, 0xad, 0x28, 0x7f, 0x8b, 0xf4, 0x53, 0x68, 0x0a, 0x49, 0x6e, - 0xd7, 0xba, 0x6a, 0x5f, 0x27, 0x25, 0xfa, 0x5d, 0x85, 0xf7, 0x70, 0xfc, 0xf2, 0xe6, 0x3f, 0xa2, - 0xef, 0x8b, 0x02, 0xfb, 0x05, 0x71, 0xca, 0x9e, 0xd3, 0x88, 0xe6, 0xca, 0x96, 0x34, 0xe3, 0x49, - 0x18, 0xd1, 0x8d, 0xb2, 0x0d, 0xc6, 0xc7, 0xd0, 0xe0, 0x0f, 0x61, 0x7a, 0x2f, 0x1f, 0x54, 0x27, - 0x05, 0xc0, 0xef, 0xc1, 0x90, 0x0a, 0x45, 0x20, 0xb2, 0x84, 0x4a, 0x6d, 0x07, 0xd6, 0xf1, 0xf6, - 0xb1, 0xe5, 0xfc, 0xc2, 0xcf, 0x12, 0x4a, 0x40, 0x54, 0xf1, 0xcb, 0x0d, 0xa9, 0xbf, 0x61, 0x43, - 0xb6, 0xbe, 0x36, 0x76, 0x7d, 0xb5, 0xff, 0xbd, 0x3b, 0x5b, 0x2f, 0x04, 0xe5, 0xdc, 0x5c, 0xb0, - 0x41, 0x11, 0x0d, 0xe6, 0x6c, 0xb0, 0x16, 0x03, 0xf9, 0xef, 0x0d, 0xb6, 0x96, 0xcc, 0x9a, 0x32, - 0xf3, 0xee, 0x7b, 0x00, 0x00, 0x00, 0xff, 0xff, 0xd6, 0x08, 0xae, 0x13, 0x46, 0x05, 0x00, 0x00, +func init() { proto.RegisterFile("binlogdata.proto", fileDescriptor_binlogdata_e83d7972bcc6f0aa) } + +var fileDescriptor_binlogdata_e83d7972bcc6f0aa = []byte{ + // 702 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x94, 0xdd, 0x6e, 0xda, 0x4a, + 0x10, 0xc7, 0x8f, 0xb1, 0x21, 0x66, 0x9c, 0x93, 0x2c, 0x9b, 0x0f, 0x21, 0xa4, 0x23, 0x21, 0x5f, + 0x9c, 0x70, 0x8e, 0x54, 0x88, 0x68, 0xfb, 0x00, 0x31, 0xb8, 0x11, 0x89, 0x21, 0xd1, 0xe2, 0xdc, + 0xe4, 0xc6, 0x32, 0xce, 0x84, 0x20, 0x88, 0x4d, 0xbc, 0x0b, 0x2a, 0xcf, 0xd1, 0xa7, 0xe8, 0x8b, + 0xf4, 0x4d, 0x7a, 0xd7, 0x87, 0xa8, 0xbc, 0x36, 0x86, 0xa4, 0x52, 0x9b, 0x5e, 0xf4, 0x6e, 0xfe, + 0xb3, 0x33, 0xb3, 0x33, 0xbf, 0x1d, 0x1b, 0xc8, 0x68, 0x12, 0xce, 0xa2, 0xf1, 0x9d, 0x2f, 0xfc, + 0xe6, 0x3c, 0x8e, 0x44, 0x44, 0x61, 0xe3, 0xa9, 0x19, 0x4f, 0x0b, 0x8c, 0x57, 0xe9, 0x41, 0x6d, + 0x4f, 0x44, 0xf3, 0x68, 0x13, 0x68, 0xf6, 0x61, 0xa7, 0xf3, 0xe0, 0xc7, 0x1c, 0x05, 0x3d, 0x86, + 0x52, 0x30, 0x9b, 0x60, 0x28, 0xaa, 0x4a, 0x5d, 0x69, 0x14, 0x59, 0xa6, 0x28, 0x05, 0x2d, 0x88, + 0xc2, 0xb0, 0x5a, 0x90, 0x5e, 0x69, 0x27, 0xb1, 0x1c, 0xe3, 0x25, 0xc6, 0x55, 0x35, 0x8d, 0x4d, + 0x95, 0xf9, 0x55, 0x85, 0x8a, 0x25, 0xaf, 0x76, 0x63, 0x3f, 0xe4, 0x7e, 0x20, 0x26, 0x51, 0x48, + 0xcf, 0x01, 0xb8, 0xf0, 0x05, 0x3e, 0x62, 0x28, 0x78, 0x55, 0xa9, 0xab, 0x0d, 0xa3, 0x7d, 0xd2, + 0xdc, 0x6a, 0xfa, 0x87, 0x94, 0xe6, 0x70, 0x1d, 0xcf, 0xb6, 0x52, 0x69, 0x1b, 0x0c, 0x5c, 0x62, + 0x28, 0x3c, 0x11, 0x4d, 0x31, 0xac, 0x6a, 0x75, 0xa5, 0x61, 0xb4, 0x2b, 0xcd, 0x74, 0x40, 0x3b, + 0x39, 0x71, 0x93, 0x03, 0x06, 0x98, 0xdb, 0xb5, 0x2f, 0x05, 0x28, 0xe7, 0xd5, 0xa8, 0x03, 0x7a, + 0xe0, 0x0b, 0x1c, 0x47, 0xf1, 0x4a, 0x8e, 0xb9, 0xd7, 0x3e, 0x7d, 0x65, 0x23, 0xcd, 0x4e, 0x96, + 0xc7, 0xf2, 0x0a, 0xf4, 0x0d, 0xec, 0x04, 0x29, 0x3d, 0x49, 0xc7, 0x68, 0x1f, 0x6c, 0x17, 0xcb, + 0xc0, 0xb2, 0x75, 0x0c, 0x25, 0xa0, 0xf2, 0xa7, 0x99, 0x44, 0xb6, 0xcb, 0x12, 0xd3, 0xfc, 0xac, + 0x80, 0xbe, 0xae, 0x4b, 0x0f, 0x60, 0xdf, 0x72, 0xbc, 0x9b, 0x01, 0xb3, 0x3b, 0x57, 0xe7, 0x83, + 0xde, 0xad, 0xdd, 0x25, 0x7f, 0xd1, 0x5d, 0xd0, 0x2d, 0xc7, 0xb3, 0xec, 0xf3, 0xde, 0x80, 0x28, + 0xf4, 0x6f, 0x28, 0x5b, 0x8e, 0xd7, 0xb9, 0xea, 0xf7, 0x7b, 0x2e, 0x29, 0xd0, 0x7d, 0x30, 0x2c, + 0xc7, 0x63, 0x57, 0x8e, 0x63, 0x9d, 0x75, 0x2e, 0x89, 0x4a, 0x8f, 0xa0, 0x62, 0x39, 0x5e, 0xb7, + 0xef, 0x78, 0x5d, 0xfb, 0x9a, 0xd9, 0x9d, 0x33, 0xd7, 0xee, 0x12, 0x8d, 0x02, 0x94, 0x12, 0x77, + 0xd7, 0x21, 0xc5, 0xcc, 0x1e, 0xda, 0x2e, 0x29, 0x65, 0xe5, 0x7a, 0x83, 0xa1, 0xcd, 0x5c, 0xb2, + 0x93, 0xc9, 0x9b, 0xeb, 0xee, 0x99, 0x6b, 0x13, 0x3d, 0x93, 0x5d, 0xdb, 0xb1, 0x5d, 0x9b, 0x94, + 0x2f, 0x34, 0xbd, 0x40, 0xd4, 0x0b, 0x4d, 0x57, 0x89, 0x66, 0x7e, 0x52, 0xe0, 0x68, 0x28, 0x62, + 0xf4, 0x1f, 0x2f, 0x71, 0xc5, 0xfc, 0x70, 0x8c, 0x0c, 0x9f, 0x16, 0xc8, 0x05, 0xad, 0x81, 0x3e, + 0x8f, 0xf8, 0x24, 0x61, 0x27, 0x01, 0x97, 0x59, 0xae, 0x69, 0x0b, 0xca, 0x53, 0x5c, 0x79, 0x71, + 0x12, 0x9f, 0x01, 0xa3, 0xcd, 0x7c, 0x21, 0xf3, 0x4a, 0xfa, 0x34, 0xb3, 0xb6, 0xf9, 0xaa, 0xbf, + 0xe6, 0x6b, 0xde, 0xc3, 0xf1, 0xcb, 0xa6, 0xf8, 0x3c, 0x0a, 0x39, 0x52, 0x07, 0x68, 0x9a, 0xe8, + 0x89, 0xcd, 0xdb, 0xca, 0xfe, 0x8c, 0xf6, 0x3f, 0x3f, 0x5d, 0x00, 0x56, 0x19, 0xbd, 0x74, 0x99, + 0x1f, 0xe1, 0x20, 0xbd, 0xc7, 0xf5, 0x47, 0x33, 0xe4, 0xaf, 0x19, 0xfd, 0x18, 0x4a, 0x42, 0x06, + 0x57, 0x0b, 0x75, 0xb5, 0x51, 0x66, 0x99, 0xfa, 0xdd, 0x09, 0xef, 0xe0, 0xf0, 0xf9, 0xcd, 0x7f, + 0x64, 0xbe, 0x77, 0xa0, 0xb1, 0xc5, 0x0c, 0xe9, 0x21, 0x14, 0x1f, 0x7d, 0x11, 0x3c, 0x64, 0xd3, + 0xa4, 0x22, 0x19, 0xe5, 0x7e, 0x32, 0x13, 0x18, 0xcb, 0x27, 0x2c, 0xb3, 0x4c, 0x99, 0xa7, 0x50, + 0xfa, 0x20, 0x2d, 0xfa, 0x2f, 0x14, 0xe3, 0x45, 0x32, 0x6b, 0xfa, 0xa9, 0x93, 0xed, 0x06, 0x92, + 0xc2, 0x2c, 0x3d, 0x36, 0xbf, 0x29, 0xb0, 0x9b, 0x36, 0x34, 0x8c, 0x16, 0x71, 0x80, 0x09, 0xc1, + 0x29, 0xae, 0xf8, 0xdc, 0x0f, 0x70, 0x4d, 0x70, 0xad, 0x93, 0x66, 0xf8, 0x83, 0x1f, 0xdf, 0x65, + 0xb7, 0xa6, 0x82, 0xbe, 0x07, 0x43, 0x92, 0x14, 0x9e, 0x58, 0xcd, 0x51, 0x32, 0xdc, 0x6b, 0x1f, + 0x6e, 0x96, 0x4a, 0x72, 0x12, 0xee, 0x6a, 0x8e, 0x0c, 0x44, 0x6e, 0x3f, 0xdf, 0x44, 0xed, 0x15, + 0x9b, 0xb8, 0x79, 0xbf, 0xe2, 0xb3, 0xf7, 0xfb, 0x3f, 0x87, 0x51, 0xca, 0xaa, 0x6c, 0xcd, 0x9a, + 0xe2, 0x58, 0x03, 0xb2, 0xfe, 0xbb, 0x3d, 0x59, 0x4e, 0x04, 0x72, 0xde, 0x9c, 0x44, 0xad, 0xd4, + 0x6a, 0x8d, 0xa3, 0xd6, 0x52, 0xb4, 0xe4, 0xbf, 0xb8, 0xb5, 0xc9, 0x1c, 0x95, 0xa4, 0xe7, 0xed, + 0xf7, 0x00, 0x00, 0x00, 0xff, 0xff, 0xd7, 0x3c, 0x64, 0xd3, 0xda, 0x05, 0x00, 0x00, } diff --git a/go/vt/vttablet/tabletserver/vstreamer/engine.go b/go/vt/vttablet/tabletserver/vstreamer/engine.go new file mode 100644 index 00000000000..03708684236 --- /dev/null +++ b/go/vt/vttablet/tabletserver/vstreamer/engine.go @@ -0,0 +1,171 @@ +/* +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 vstreamer + +import ( + "context" + "errors" + "sync" + + "vitess.io/vitess/go/mysql" + "vitess.io/vitess/go/stats" + "vitess.io/vitess/go/vt/log" + "vitess.io/vitess/go/vt/srvtopo" + "vitess.io/vitess/go/vt/topo" + "vitess.io/vitess/go/vt/vtgate/vindexes" + + binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" + vschemapb "vitess.io/vitess/go/vt/proto/vschema" +) + +var vschemaErrors *stats.Counter + +// Engine is the engine for handling vseplication streaming requests. +type Engine struct { + // mu protects isOpen, streamers, streamIdx and kschema. + mu sync.Mutex + + isOpen bool + // wg is incremented for every Stream, and decremented on end. + wg sync.WaitGroup + streamers map[int]*vstreamer + streamIdx int + + // watcherOnce is used for initializing kschema + // and setting up the vschema watch. It's guaranteed that + // no stream will start until kschema is initialized by + // the first call through watcherOnce. + watcherOnce sync.Once + kschema *vindexes.KeyspaceSchema + + ts srvtopo.Server + keyspace string + cell string +} + +// NewEngine creates a new Engine. +func NewEngine(ts srvtopo.Server) *Engine { + vschemaErrors = stats.NewCounter("VSchemaErrors", "Count of VSchema errors") + return &Engine{ + streamers: make(map[int]*vstreamer), + kschema: &vindexes.KeyspaceSchema{}, + ts: ts, + } +} + +// Open starts the Engine service. +func (vse *Engine) Open(keyspace, cell string) error { + vse.mu.Lock() + defer vse.mu.Unlock() + if vse.isOpen { + return nil + } + vse.isOpen = true + vse.keyspace = keyspace + vse.cell = cell + return nil +} + +// Close closes the Engine service. +func (vse *Engine) Close() { + func() { + vse.mu.Lock() + defer vse.mu.Unlock() + if !vse.isOpen { + return + } + for _, s := range vse.streamers { + // cancel is non-blocking. + s.Cancel() + } + vse.isOpen = false + }() + + // Wait only after releasing the lock because the end of every + // stream will use the lock to remove the entry from streamers. + vse.wg.Wait() +} + +// Stream starts a new stream. +func (vse *Engine) Stream(ctx context.Context, cp *mysql.ConnParams, startPos mysql.Position, filter *binlogdatapb.Filter, f func()) error { + // Ensure kschema is initialized and the watcher is started. + vse.watcherOnce.Do(vse.setWatch) + + // Create stream and add it to the map. + streamer, idx, err := func() (*vstreamer, int, error) { + vse.mu.Lock() + defer vse.mu.Unlock() + if !vse.isOpen { + return nil, 0, errors.New("VStreamer is not open") + } + streamer, err := newVStreamer(cp, startPos, filter, f) + if err != nil { + return nil, 0, err + } + idx := vse.streamIdx + vse.streamIdx++ + vse.streamers[idx] = streamer + // Now that we've added the stream, increment wg. + // This must be done before releasing the lock. + vse.wg.Add(1) + return streamer, 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.streamers, idx) + vse.wg.Done() + }() + + // No lock is held while streaming, but wg is incremented. + return streamer.Stream(ctx) +} + +func (vse *Engine) setWatch() { + // WatchSrvVSchema does not return until the inner func has been called at least once. + vse.ts.WatchSrvVSchema(context.TODO(), vse.cell, func(v *vschemapb.SrvVSchema, err error) { + var kschema *vindexes.KeyspaceSchema + switch { + case err == nil: + kschema, err = vindexes.BuildKeyspaceSchema(v.Keyspaces[vse.keyspace], vse.keyspace) + if err != nil { + log.Errorf("Error building vschema %s: %v", vse.keyspace, err) + vschemaErrors.Add(1) + return + } + case topo.IsErrType(err, topo.NoNode): + kschema = &vindexes.KeyspaceSchema{} + default: + log.Errorf("Error fetching vschema %s: %v", vse.keyspace, err) + vschemaErrors.Add(1) + return + } + + // Broadcast the change to all streamers. + vse.mu.Lock() + defer vse.mu.Unlock() + vse.kschema = kschema + for _, s := range vse.streamers { + s.SetKSchema(kschema) + } + }) +} diff --git a/go/vt/vttablet/tabletserver/vstreamer/streamer.go b/go/vt/vttablet/tabletserver/vstreamer/streamer.go new file mode 100644 index 00000000000..04103b90c11 --- /dev/null +++ b/go/vt/vttablet/tabletserver/vstreamer/streamer.go @@ -0,0 +1,54 @@ +/* +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 vstreamer + +import ( + "context" + + "vitess.io/vitess/go/mysql" + "vitess.io/vitess/go/vt/binlog" + "vitess.io/vitess/go/vt/vtgate/vindexes" + + binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" +) + +type vstreamer struct { + cp *mysql.ConnParams + startPos mysql.Position + filter *binlogdatapb.Filter + f func() + conn *binlog.SlaveConnection +} + +func newVStreamer(cp *mysql.ConnParams, startPos mysql.Position, filter *binlogdatapb.Filter, f func()) (*vstreamer, error) { + return &vstreamer{ + cp: cp, + startPos: startPos, + filter: filter, + f: f, + }, nil +} + +func (vs *vstreamer) SetKSchema(kschema *vindexes.KeyspaceSchema) { +} + +func (vs *vstreamer) Stream(ctx context.Context) error { + return nil +} + +func (vs *vstreamer) Cancel() { +} diff --git a/proto/binlogdata.proto b/proto/binlogdata.proto index 252cdb05abc..b5ac7bebd33 100644 --- a/proto/binlogdata.proto +++ b/proto/binlogdata.proto @@ -114,6 +114,23 @@ message StreamTablesResponse { BinlogTransaction binlog_transaction = 1; } +// Rule represents one rule. +message Rule { + // match can be a table name or a regular expression + // delineated by '/' and '/'. + string match = 1; + // filter can be an empty string or keyrange if the match + // is a regular expression. Otherwise, it must be a select + // query. + string filter = 2; +} + +// Filter represents a list of ordered rules. First match +// wins. +message Filter { + repeated Rule rules = 1; +} + // BinlogSource specifies the source and filter parameters for // Filtered Replication. It currently supports a keyrange // or a list of tables. @@ -132,4 +149,8 @@ message BinlogSource { // tables is set if the request is for a list of tables repeated string tables = 5; + + // filter is set if we're using the generalized representation + // for the filter. + Filter filter = 6; } diff --git a/py/vtproto/binlogdata_pb2.py b/py/vtproto/binlogdata_pb2.py index 97cae7e7c3f..a6578c15bdf 100644 --- a/py/vtproto/binlogdata_pb2.py +++ b/py/vtproto/binlogdata_pb2.py @@ -7,7 +7,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() @@ -21,7 +20,8 @@ name='binlogdata.proto', package='binlogdata', syntax='proto3', - serialized_pb=_b('\n\x10\x62inlogdata.proto\x12\nbinlogdata\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\"\x91\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(\tB)Z\'vitess.io/vitess/go/vt/proto/binlogdatab\x06proto3') + serialized_options=_b('Z\'vitess.io/vitess/go/vt/proto/binlogdata'), + serialized_pb=_b('\n\x10\x62inlogdata.proto\x12\nbinlogdata\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\"\xb5\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.FilterB)Z\'vitess.io/vitess/go/vt/proto/binlogdatab\x06proto3') , dependencies=[query__pb2.DESCRIPTOR,topodata__pb2.DESCRIPTOR,]) @@ -35,47 +35,47 @@ values=[ _descriptor.EnumValueDescriptor( name='BL_UNRECOGNIZED', index=0, number=0, - options=None, + serialized_options=None, type=None), _descriptor.EnumValueDescriptor( name='BL_BEGIN', index=1, number=1, - options=None, + serialized_options=None, type=None), _descriptor.EnumValueDescriptor( name='BL_COMMIT', index=2, number=2, - options=None, + serialized_options=None, type=None), _descriptor.EnumValueDescriptor( name='BL_ROLLBACK', index=3, number=3, - options=None, + serialized_options=None, type=None), _descriptor.EnumValueDescriptor( name='BL_DML_DEPRECATED', index=4, number=4, - options=None, + serialized_options=None, type=None), _descriptor.EnumValueDescriptor( name='BL_DDL', index=5, number=5, - options=None, + serialized_options=None, type=None), _descriptor.EnumValueDescriptor( name='BL_SET', index=6, number=6, - options=None, + serialized_options=None, type=None), _descriptor.EnumValueDescriptor( name='BL_INSERT', index=7, number=7, - options=None, + serialized_options=None, type=None), _descriptor.EnumValueDescriptor( name='BL_UPDATE', index=8, number=8, - options=None, + serialized_options=None, type=None), _descriptor.EnumValueDescriptor( name='BL_DELETE', index=9, number=9, - options=None, + serialized_options=None, type=None), ], containing_type=None, - options=None, + serialized_options=None, serialized_start=375, serialized_end=544, ) @@ -95,28 +95,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='conn', full_name='binlogdata.Charset.conn', 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), + serialized_options=None, file=DESCRIPTOR), _descriptor.FieldDescriptor( name='server', full_name='binlogdata.Charset.server', index=2, number=3, 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), + serialized_options=None, file=DESCRIPTOR), ], extensions=[ ], nested_types=[], enum_types=[ ], - options=None, + serialized_options=None, is_extendable=False, syntax='proto3', extension_ranges=[], @@ -140,21 +140,21 @@ 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='charset', full_name='binlogdata.BinlogTransaction.Statement.charset', 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, - options=None, file=DESCRIPTOR), + serialized_options=None, file=DESCRIPTOR), _descriptor.FieldDescriptor( name='sql', full_name='binlogdata.BinlogTransaction.Statement.sql', index=2, number=3, type=12, cpp_type=9, label=1, has_default_value=False, default_value=_b(""), 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=[ ], @@ -162,7 +162,7 @@ enum_types=[ _BINLOGTRANSACTION_STATEMENT_CATEGORY, ], - options=None, + serialized_options=None, is_extendable=False, syntax='proto3', extension_ranges=[], @@ -185,21 +185,21 @@ has_default_value=False, default_value=[], 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='event_token', full_name='binlogdata.BinlogTransaction.event_token', index=1, number=4, 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, - options=None, file=DESCRIPTOR), + serialized_options=None, file=DESCRIPTOR), ], extensions=[ ], nested_types=[_BINLOGTRANSACTION_STATEMENT, ], enum_types=[ ], - options=None, + serialized_options=None, is_extendable=False, syntax='proto3', extension_ranges=[], @@ -223,28 +223,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='key_range', full_name='binlogdata.StreamKeyRangeRequest.key_range', 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, - options=None, file=DESCRIPTOR), + serialized_options=None, file=DESCRIPTOR), _descriptor.FieldDescriptor( name='charset', full_name='binlogdata.StreamKeyRangeRequest.charset', 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, - 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=[], @@ -268,14 +268,14 @@ 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), ], extensions=[ ], nested_types=[], enum_types=[ ], - options=None, + serialized_options=None, is_extendable=False, syntax='proto3', extension_ranges=[], @@ -299,28 +299,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='tables', full_name='binlogdata.StreamTablesRequest.tables', index=1, number=2, 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, - options=None, file=DESCRIPTOR), + serialized_options=None, file=DESCRIPTOR), _descriptor.FieldDescriptor( name='charset', full_name='binlogdata.StreamTablesRequest.charset', 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, - 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=[], @@ -344,14 +344,14 @@ 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), ], extensions=[ ], nested_types=[], enum_types=[ ], - options=None, + serialized_options=None, is_extendable=False, syntax='proto3', extension_ranges=[], @@ -362,6 +362,75 @@ ) +_RULE = _descriptor.Descriptor( + name='Rule', + full_name='binlogdata.Rule', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='match', full_name='binlogdata.Rule.match', 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), + _descriptor.FieldDescriptor( + name='filter', full_name='binlogdata.Rule.filter', 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, + serialized_options=None, file=DESCRIPTOR), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=941, + serialized_end=978, +) + + +_FILTER = _descriptor.Descriptor( + name='Filter', + full_name='binlogdata.Filter', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='rules', full_name='binlogdata.Filter.rules', 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), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=980, + serialized_end=1021, +) + + _BINLOGSOURCE = _descriptor.Descriptor( name='BinlogSource', full_name='binlogdata.BinlogSource', @@ -375,49 +444,56 @@ 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='shard', full_name='binlogdata.BinlogSource.shard', 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='tablet_type', full_name='binlogdata.BinlogSource.tablet_type', 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), _descriptor.FieldDescriptor( name='key_range', full_name='binlogdata.BinlogSource.key_range', index=3, number=4, 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, - options=None, file=DESCRIPTOR), + serialized_options=None, file=DESCRIPTOR), _descriptor.FieldDescriptor( name='tables', full_name='binlogdata.BinlogSource.tables', index=4, number=5, 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, - options=None, file=DESCRIPTOR), + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='filter', full_name='binlogdata.BinlogSource.filter', index=5, + number=6, 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=[ ], nested_types=[], enum_types=[ ], - options=None, + serialized_options=None, is_extendable=False, syntax='proto3', extension_ranges=[], oneofs=[ ], - serialized_start=942, - serialized_end=1087, + serialized_start=1024, + serialized_end=1205, ) _BINLOGTRANSACTION_STATEMENT.fields_by_name['category'].enum_type = _BINLOGTRANSACTION_STATEMENT_CATEGORY @@ -431,14 +507,18 @@ _STREAMKEYRANGERESPONSE.fields_by_name['binlog_transaction'].message_type = _BINLOGTRANSACTION _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 _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 DESCRIPTOR.message_types_by_name['Charset'] = _CHARSET DESCRIPTOR.message_types_by_name['BinlogTransaction'] = _BINLOGTRANSACTION DESCRIPTOR.message_types_by_name['StreamKeyRangeRequest'] = _STREAMKEYRANGEREQUEST DESCRIPTOR.message_types_by_name['StreamKeyRangeResponse'] = _STREAMKEYRANGERESPONSE DESCRIPTOR.message_types_by_name['StreamTablesRequest'] = _STREAMTABLESREQUEST DESCRIPTOR.message_types_by_name['StreamTablesResponse'] = _STREAMTABLESRESPONSE +DESCRIPTOR.message_types_by_name['Rule'] = _RULE +DESCRIPTOR.message_types_by_name['Filter'] = _FILTER DESCRIPTOR.message_types_by_name['BinlogSource'] = _BINLOGSOURCE _sym_db.RegisterFileDescriptor(DESCRIPTOR) @@ -492,6 +572,20 @@ )) _sym_db.RegisterMessage(StreamTablesResponse) +Rule = _reflection.GeneratedProtocolMessageType('Rule', (_message.Message,), dict( + DESCRIPTOR = _RULE, + __module__ = 'binlogdata_pb2' + # @@protoc_insertion_point(class_scope:binlogdata.Rule) + )) +_sym_db.RegisterMessage(Rule) + +Filter = _reflection.GeneratedProtocolMessageType('Filter', (_message.Message,), dict( + DESCRIPTOR = _FILTER, + __module__ = 'binlogdata_pb2' + # @@protoc_insertion_point(class_scope:binlogdata.Filter) + )) +_sym_db.RegisterMessage(Filter) + BinlogSource = _reflection.GeneratedProtocolMessageType('BinlogSource', (_message.Message,), dict( DESCRIPTOR = _BINLOGSOURCE, __module__ = 'binlogdata_pb2' @@ -500,6 +594,5 @@ _sym_db.RegisterMessage(BinlogSource) -DESCRIPTOR.has_options = True -DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), _b('Z\'vitess.io/vitess/go/vt/proto/binlogdata')) +DESCRIPTOR._options = None # @@protoc_insertion_point(module_scope) From a6097408e4321fe1a1228596d3e59cca8636949a Mon Sep 17 00:00:00 2001 From: Sugu Sougoumarane Date: Thu, 27 Dec 2018 16:47:10 -0800 Subject: [PATCH 018/115] vreplication: streamer planbuilder Signed-off-by: Sugu Sougoumarane --- .../tabletserver/vstreamer/planbuilder.go | 273 ++++++++++++++++++ 1 file changed, 273 insertions(+) create mode 100644 go/vt/vttablet/tabletserver/vstreamer/planbuilder.go diff --git a/go/vt/vttablet/tabletserver/vstreamer/planbuilder.go b/go/vt/vttablet/tabletserver/vstreamer/planbuilder.go new file mode 100644 index 00000000000..4140124f5ea --- /dev/null +++ b/go/vt/vttablet/tabletserver/vstreamer/planbuilder.go @@ -0,0 +1,273 @@ +/* +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 vstreamer + +import ( + "fmt" + "regexp" + "strings" + + "vitess.io/vitess/go/mysql" + "vitess.io/vitess/go/vt/key" + "vitess.io/vitess/go/vt/sqlparser" + "vitess.io/vitess/go/vt/vtgate/vindexes" + + binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" + topodatapb "vitess.io/vitess/go/vt/proto/topodata" +) + +// Plan represents the streaming plan for a table. +type Plan struct { + Table string + ColExprs []ColExpr + VindexColumn int + Vindex vindexes.Vindex + KeyRange *topodatapb.KeyRange +} + +// ColExpr represents a column expression. +type ColExpr struct { + ColNum int + Operation Operation +} + +// Operation represents the operation to be performed on a column. +type Operation int + +// The following are the supported operations on a column. +const ( + OpNone = Operation(iota) + OpYearMonth + OpDay + OpHour +) + +// TableMap contains the metadata for a table. The +// name is dervied from mysql's Table_map_log_event. +type TableMap struct { + *mysql.TableMap + ColumnNames []sqlparser.ColIdent +} + +func buildPlan(tm *TableMap, kschema *vindexes.KeyspaceSchema, filter *binlogdatapb.Filter) (*Plan, error) { + for _, rule := range filter.Rules { + switch { + case strings.HasPrefix(rule.Match, "/"): + expr := strings.Trim(rule.Match, "/") + result, err := regexp.MatchString(expr, tm.Name) + if err != nil { + return nil, err + } + if !result { + continue + } + return buildREPlan(tm, kschema, rule.Filter) + case rule.Match == tm.Name: + } + } + return nil, nil +} + +func buildREPlan(tm *TableMap, kschema *vindexes.KeyspaceSchema, filter string) (*Plan, error) { + plan := &Plan{ + Table: tm.Name, + } + plan.ColExprs = make([]ColExpr, len(tm.ColumnNames)) + for i := range tm.ColumnNames { + plan.ColExprs[i].ColNum = i + } + if filter != "" { + // We need to additionally set VindexColumn, Vindex and KeyRange + // based on the Primary Vindex of the table. + // Find table in kschema. + table := kschema.Tables[tm.Name] + if table == nil { + return nil, fmt.Errorf("no vschema definition for table %s", tm.Name) + } + // Get Primary Vindex. + if len(table.ColumnVindexes) == 0 { + return nil, fmt.Errorf("table %s has no primary vindex", tm.Name) + } + colnum, err := findColumn(tm, table.ColumnVindexes[0].Columns[0]) + if err != nil { + return nil, err + } + plan.VindexColumn = colnum + plan.Vindex = table.ColumnVindexes[0].Vindex + + // Parse keyrange. + keyranges, err := key.ParseShardingSpec(filter) + if err != nil { + return nil, err + } + if len(keyranges) != 1 { + return nil, fmt.Errorf("error parsing keyrange: %v", filter) + } + plan.KeyRange = keyranges[0] + } + return plan, nil +} + +func buildTablePlan(tm *TableMap, kschema *vindexes.KeyspaceSchema, query string) (*Plan, error) { + statement, err := sqlparser.Parse(query) + if err != nil { + return nil, err + } + plan := &Plan{ + Table: tm.Name, + } + sel, ok := statement.(*sqlparser.Select) + if !ok { + return nil, fmt.Errorf("unexpected: %v", sqlparser.String(sel)) + } + if len(sel.From) > 1 { + return nil, fmt.Errorf("unexpected: %v", sqlparser.String(sel)) + } + node, ok := sel.From[0].(*sqlparser.AliasedTableExpr) + if !ok { + return nil, fmt.Errorf("unexpected: %v", sqlparser.String(sel)) + } + fromTable := sqlparser.GetTableName(node.Expr) + if fromTable.IsEmpty() { + return nil, fmt.Errorf("unexpected: %v", sqlparser.String(sel)) + } + if fromTable.String() == tm.Name { + return nil, fmt.Errorf("unexpected: select expression table %v does not match the table entry name %s", sqlparser.String(fromTable), tm.Name) + } + + if _, ok := sel.SelectExprs[0].(*sqlparser.StarExpr); !ok { + for _, expr := range sel.SelectExprs { + cExpr, err := analyzeExpr(tm, expr) + if err != nil { + return nil, err + } + plan.ColExprs = append(plan.ColExprs, cExpr) + } + } + + if sel.Where == nil { + return plan, nil + } + funcExpr, ok := sel.Where.Expr.(*sqlparser.FuncExpr) + if !ok { + return nil, fmt.Errorf("unexpected where clause: %v", sqlparser.String(sel.Where)) + } + if !funcExpr.Name.EqualString("in_keyrange") { + return nil, fmt.Errorf("unexpected where clause: %v", sqlparser.String(sel.Where)) + } + if len(funcExpr.Exprs) != 3 { + return nil, fmt.Errorf("unexpected where clause: %v", sqlparser.String(sel.Where)) + } + cExpr, err := analyzeExpr(tm, funcExpr.Exprs[0]) + if err != nil { + return nil, err + } + if cExpr.Operation != OpNone { + return nil, fmt.Errorf("unexpected operaion on vindex column: %v", funcExpr.Exprs[0]) + } + plan.VindexColumn = cExpr.ColNum + vtype, err := selString(funcExpr.Exprs[1]) + if err != nil { + return nil, err + } + plan.Vindex, err = vindexes.CreateVindex(vtype, vtype, map[string]string{}) + if err != nil { + return nil, err + } + kr, err := selString(funcExpr.Exprs[2]) + if err != nil { + return nil, err + } + keyranges, err := key.ParseShardingSpec(kr) + if err != nil { + return nil, err + } + if len(keyranges) != 1 { + return nil, fmt.Errorf("unexpected where clause: %v", sqlparser.String(sel.Where)) + } + plan.KeyRange = keyranges[0] + return plan, nil +} + +func analyzeExpr(tm *TableMap, expr sqlparser.SelectExpr) (cExpr ColExpr, err error) { + aexpr, ok := expr.(*sqlparser.AliasedExpr) + if !ok { + return ColExpr{}, fmt.Errorf("unexpected: %v", sqlparser.String(expr)) + } + switch expr := aexpr.Expr.(type) { + case *sqlparser.ColName: + colnum, err := findColumn(tm, expr.Name) + if err != nil { + return ColExpr{}, err + } + return ColExpr{ColNum: colnum}, nil + case *sqlparser.FuncExpr: + if expr.Distinct || len(expr.Exprs) != 1 { + return ColExpr{}, fmt.Errorf("unsupported: %v", sqlparser.String(expr)) + } + switch fname := expr.Name.Lowered(); fname { + case "yearmonth", "day", "hour": + aInner, ok := expr.Exprs[0].(*sqlparser.AliasedExpr) + if !ok { + return ColExpr{}, fmt.Errorf("unsupported: %v", sqlparser.String(expr)) + } + innerCol, ok := aInner.Expr.(*sqlparser.ColName) + if !ok { + return ColExpr{}, fmt.Errorf("unsupported: %v", sqlparser.String(expr)) + } + colnum, err := findColumn(tm, innerCol.Name) + if err != nil { + return ColExpr{}, err + } + switch fname { + case "yearmonth": + return ColExpr{ColNum: colnum, Operation: OpYearMonth}, nil + case "day": + return ColExpr{ColNum: colnum, Operation: OpDay}, nil + case "hour": + return ColExpr{ColNum: colnum, Operation: OpHour}, nil + default: + panic("unreachable") + } + default: + return ColExpr{}, fmt.Errorf("unsupported: %v", sqlparser.String(expr)) + } + default: + return ColExpr{}, fmt.Errorf("unexpected: %v", sqlparser.String(expr)) + } +} + +func selString(expr sqlparser.SelectExpr) (string, error) { + aexpr, ok := expr.(*sqlparser.AliasedExpr) + if !ok { + return "", fmt.Errorf("unexpected: %v", sqlparser.String(expr)) + } + val, ok := aexpr.Expr.(*sqlparser.SQLVal) + if !ok { + return "", fmt.Errorf("unexpected: %v", sqlparser.String(expr)) + } + return string(val.Val), nil +} + +func findColumn(tm *TableMap, name sqlparser.ColIdent) (int, error) { + for i, cname := range tm.ColumnNames { + if name.Equal(cname) { + return i, nil + } + } + return 0, fmt.Errorf("column %s not found in table %s", sqlparser.String(name), tm.Name) +} From ec4e808b471c37bbbd5776900fa805880a6ae792 Mon Sep 17 00:00:00 2001 From: Sugu Sougoumarane Date: Fri, 28 Dec 2018 22:51:25 -0800 Subject: [PATCH 019/115] vreplication: vstreamer, plan and filtering Signed-off-by: Sugu Sougoumarane --- go/vt/proto/binlogdata/binlogdata.pb.go | 379 +++++++++++++++--- .../vttablet/tabletserver/vstreamer/engine.go | 15 +- .../tabletserver/vstreamer/planbuilder.go | 187 ++++++--- .../tabletserver/vstreamer/streamer.go | 366 ++++++++++++++++- proto/binlogdata.proto | 38 ++ py/vtproto/binlogdata_pb2.py | 266 +++++++++++- 6 files changed, 1115 insertions(+), 136 deletions(-) diff --git a/go/vt/proto/binlogdata/binlogdata.pb.go b/go/vt/proto/binlogdata/binlogdata.pb.go index 62fe086a107..d2dd885698a 100644 --- a/go/vt/proto/binlogdata/binlogdata.pb.go +++ b/go/vt/proto/binlogdata/binlogdata.pb.go @@ -20,6 +20,54 @@ var _ = math.Inf // proto package needs to be updated. const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package +// VEventType enumerates the event types. +type VEventType int32 + +const ( + VEventType_UNKNOWN VEventType = 0 + VEventType_GTID VEventType = 1 + VEventType_BEGIN VEventType = 2 + VEventType_COMMIT VEventType = 3 + VEventType_ROLLBACK VEventType = 4 + VEventType_DDL VEventType = 5 + VEventType_INSERT VEventType = 6 + VEventType_UPDATE VEventType = 7 + VEventType_DELETE VEventType = 8 + VEventType_SET VEventType = 9 +) + +var VEventType_name = map[int32]string{ + 0: "UNKNOWN", + 1: "GTID", + 2: "BEGIN", + 3: "COMMIT", + 4: "ROLLBACK", + 5: "DDL", + 6: "INSERT", + 7: "UPDATE", + 8: "DELETE", + 9: "SET", +} +var VEventType_value = map[string]int32{ + "UNKNOWN": 0, + "GTID": 1, + "BEGIN": 2, + "COMMIT": 3, + "ROLLBACK": 4, + "DDL": 5, + "INSERT": 6, + "UPDATE": 7, + "DELETE": 8, + "SET": 9, +} + +func (x VEventType) String() string { + return proto.EnumName(VEventType_name, int32(x)) +} +func (VEventType) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_binlogdata_9f7a55f16227bf1c, []int{0} +} + type BinlogTransaction_Statement_Category int32 const ( @@ -65,7 +113,7 @@ 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_e83d7972bcc6f0aa, []int{1, 0, 0} + return fileDescriptor_binlogdata_9f7a55f16227bf1c, []int{1, 0, 0} } // Charset is the per-statement charset info from a QUERY_EVENT binlog entry. @@ -85,7 +133,7 @@ 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_e83d7972bcc6f0aa, []int{0} + return fileDescriptor_binlogdata_9f7a55f16227bf1c, []int{0} } func (m *Charset) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Charset.Unmarshal(m, b) @@ -142,7 +190,7 @@ 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_e83d7972bcc6f0aa, []int{1} + return fileDescriptor_binlogdata_9f7a55f16227bf1c, []int{1} } func (m *BinlogTransaction) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_BinlogTransaction.Unmarshal(m, b) @@ -192,7 +240,7 @@ 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_e83d7972bcc6f0aa, []int{1, 0} + return fileDescriptor_binlogdata_9f7a55f16227bf1c, []int{1, 0} } func (m *BinlogTransaction_Statement) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_BinlogTransaction_Statement.Unmarshal(m, b) @@ -250,7 +298,7 @@ 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_e83d7972bcc6f0aa, []int{2} + return fileDescriptor_binlogdata_9f7a55f16227bf1c, []int{2} } func (m *StreamKeyRangeRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_StreamKeyRangeRequest.Unmarshal(m, b) @@ -303,7 +351,7 @@ 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_e83d7972bcc6f0aa, []int{3} + return fileDescriptor_binlogdata_9f7a55f16227bf1c, []int{3} } func (m *StreamKeyRangeResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_StreamKeyRangeResponse.Unmarshal(m, b) @@ -347,7 +395,7 @@ 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_e83d7972bcc6f0aa, []int{4} + return fileDescriptor_binlogdata_9f7a55f16227bf1c, []int{4} } func (m *StreamTablesRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_StreamTablesRequest.Unmarshal(m, b) @@ -400,7 +448,7 @@ 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_e83d7972bcc6f0aa, []int{5} + return fileDescriptor_binlogdata_9f7a55f16227bf1c, []int{5} } func (m *StreamTablesResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_StreamTablesResponse.Unmarshal(m, b) @@ -445,7 +493,7 @@ 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_e83d7972bcc6f0aa, []int{6} + return fileDescriptor_binlogdata_9f7a55f16227bf1c, []int{6} } func (m *Rule) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Rule.Unmarshal(m, b) @@ -492,7 +540,7 @@ 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_e83d7972bcc6f0aa, []int{7} + return fileDescriptor_binlogdata_9f7a55f16227bf1c, []int{7} } func (m *Filter) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Filter.Unmarshal(m, b) @@ -545,7 +593,7 @@ 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_e83d7972bcc6f0aa, []int{8} + return fileDescriptor_binlogdata_9f7a55f16227bf1c, []int{8} } func (m *BinlogSource) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_BinlogSource.Unmarshal(m, b) @@ -607,6 +655,201 @@ func (m *BinlogSource) GetFilter() *Filter { return nil } +type RowEvent struct { + Before *query.Row `protobuf:"bytes,1,opt,name=before,proto3" json:"before,omitempty"` + After *query.Row `protobuf:"bytes,2,opt,name=after,proto3" json:"after,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +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_9f7a55f16227bf1c, []int{9} +} +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_Size() int { + return xxx_messageInfo_RowEvent.Size(m) +} +func (m *RowEvent) XXX_DiscardUnknown() { + xxx_messageInfo_RowEvent.DiscardUnknown(m) +} + +var xxx_messageInfo_RowEvent proto.InternalMessageInfo + +func (m *RowEvent) GetBefore() *query.Row { + if m != nil { + return m.Before + } + return nil +} + +func (m *RowEvent) GetAfter() *query.Row { + if m != nil { + return m.After + } + return nil +} + +// VEvent represents a vstream event +type VEvent struct { + Type VEventType `protobuf:"varint,1,opt,name=type,proto3,enum=binlogdata.VEventType" json:"type,omitempty"` + Gtid string `protobuf:"bytes,2,opt,name=gtid,proto3" json:"gtid,omitempty"` + Ddl string `protobuf:"bytes,3,opt,name=ddl,proto3" json:"ddl,omitempty"` + RowEvents []*RowEvent `protobuf:"bytes,4,rep,name=row_events,json=rowEvents,proto3" json:"row_events,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +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_9f7a55f16227bf1c, []int{10} +} +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_Size() int { + return xxx_messageInfo_VEvent.Size(m) +} +func (m *VEvent) XXX_DiscardUnknown() { + xxx_messageInfo_VEvent.DiscardUnknown(m) +} + +var xxx_messageInfo_VEvent proto.InternalMessageInfo + +func (m *VEvent) GetType() VEventType { + if m != nil { + return m.Type + } + return VEventType_UNKNOWN +} + +func (m *VEvent) GetGtid() string { + if m != nil { + return m.Gtid + } + return "" +} + +func (m *VEvent) GetDdl() string { + if m != nil { + return m.Ddl + } + return "" +} + +func (m *VEvent) GetRowEvents() []*RowEvent { + if m != nil { + return m.RowEvents + } + return nil +} + +// VStreamRequest is the payload for VStream +type VStreamRequest struct { + Position string `protobuf:"bytes,1,opt,name=position,proto3" json:"position,omitempty"` + Filter *Filter `protobuf:"bytes,2,opt,name=filter,proto3" json:"filter,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +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_9f7a55f16227bf1c, []int{11} +} +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_Size() int { + return xxx_messageInfo_VStreamRequest.Size(m) +} +func (m *VStreamRequest) XXX_DiscardUnknown() { + xxx_messageInfo_VStreamRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_VStreamRequest proto.InternalMessageInfo + +func (m *VStreamRequest) GetPosition() string { + if m != nil { + return m.Position + } + return "" +} + +func (m *VStreamRequest) GetFilter() *Filter { + if m != nil { + return m.Filter + } + return nil +} + +// VStreamResponse is the response from VStream +type VStreamResponse struct { + Event []*VEvent `protobuf:"bytes,1,rep,name=event,proto3" json:"event,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +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_9f7a55f16227bf1c, []int{12} +} +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_Size() int { + return xxx_messageInfo_VStreamResponse.Size(m) +} +func (m *VStreamResponse) XXX_DiscardUnknown() { + xxx_messageInfo_VStreamResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_VStreamResponse proto.InternalMessageInfo + +func (m *VStreamResponse) GetEvent() []*VEvent { + if m != nil { + return m.Event + } + return nil +} + func init() { proto.RegisterType((*Charset)(nil), "binlogdata.Charset") proto.RegisterType((*BinlogTransaction)(nil), "binlogdata.BinlogTransaction") @@ -618,55 +861,73 @@ func init() { proto.RegisterType((*Rule)(nil), "binlogdata.Rule") proto.RegisterType((*Filter)(nil), "binlogdata.Filter") proto.RegisterType((*BinlogSource)(nil), "binlogdata.BinlogSource") + proto.RegisterType((*RowEvent)(nil), "binlogdata.RowEvent") + proto.RegisterType((*VEvent)(nil), "binlogdata.VEvent") + proto.RegisterType((*VStreamRequest)(nil), "binlogdata.VStreamRequest") + proto.RegisterType((*VStreamResponse)(nil), "binlogdata.VStreamResponse") + proto.RegisterEnum("binlogdata.VEventType", VEventType_name, VEventType_value) proto.RegisterEnum("binlogdata.BinlogTransaction_Statement_Category", BinlogTransaction_Statement_Category_name, BinlogTransaction_Statement_Category_value) } -func init() { proto.RegisterFile("binlogdata.proto", fileDescriptor_binlogdata_e83d7972bcc6f0aa) } - -var fileDescriptor_binlogdata_e83d7972bcc6f0aa = []byte{ - // 702 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x94, 0xdd, 0x6e, 0xda, 0x4a, - 0x10, 0xc7, 0x8f, 0xb1, 0x21, 0x66, 0x9c, 0x93, 0x2c, 0x9b, 0x0f, 0x21, 0xa4, 0x23, 0x21, 0x5f, - 0x9c, 0x70, 0x8e, 0x54, 0x88, 0x68, 0xfb, 0x00, 0x31, 0xb8, 0x11, 0x89, 0x21, 0xd1, 0xe2, 0xdc, - 0xe4, 0xc6, 0x32, 0xce, 0x84, 0x20, 0x88, 0x4d, 0xbc, 0x0b, 0x2a, 0xcf, 0xd1, 0xa7, 0xe8, 0x8b, - 0xf4, 0x4d, 0x7a, 0xd7, 0x87, 0xa8, 0xbc, 0x36, 0x86, 0xa4, 0x52, 0x9b, 0x5e, 0xf4, 0x6e, 0xfe, - 0xb3, 0x33, 0xb3, 0x33, 0xbf, 0x1d, 0x1b, 0xc8, 0x68, 0x12, 0xce, 0xa2, 0xf1, 0x9d, 0x2f, 0xfc, - 0xe6, 0x3c, 0x8e, 0x44, 0x44, 0x61, 0xe3, 0xa9, 0x19, 0x4f, 0x0b, 0x8c, 0x57, 0xe9, 0x41, 0x6d, - 0x4f, 0x44, 0xf3, 0x68, 0x13, 0x68, 0xf6, 0x61, 0xa7, 0xf3, 0xe0, 0xc7, 0x1c, 0x05, 0x3d, 0x86, - 0x52, 0x30, 0x9b, 0x60, 0x28, 0xaa, 0x4a, 0x5d, 0x69, 0x14, 0x59, 0xa6, 0x28, 0x05, 0x2d, 0x88, - 0xc2, 0xb0, 0x5a, 0x90, 0x5e, 0x69, 0x27, 0xb1, 0x1c, 0xe3, 0x25, 0xc6, 0x55, 0x35, 0x8d, 0x4d, - 0x95, 0xf9, 0x55, 0x85, 0x8a, 0x25, 0xaf, 0x76, 0x63, 0x3f, 0xe4, 0x7e, 0x20, 0x26, 0x51, 0x48, - 0xcf, 0x01, 0xb8, 0xf0, 0x05, 0x3e, 0x62, 0x28, 0x78, 0x55, 0xa9, 0xab, 0x0d, 0xa3, 0x7d, 0xd2, - 0xdc, 0x6a, 0xfa, 0x87, 0x94, 0xe6, 0x70, 0x1d, 0xcf, 0xb6, 0x52, 0x69, 0x1b, 0x0c, 0x5c, 0x62, - 0x28, 0x3c, 0x11, 0x4d, 0x31, 0xac, 0x6a, 0x75, 0xa5, 0x61, 0xb4, 0x2b, 0xcd, 0x74, 0x40, 0x3b, - 0x39, 0x71, 0x93, 0x03, 0x06, 0x98, 0xdb, 0xb5, 0x2f, 0x05, 0x28, 0xe7, 0xd5, 0xa8, 0x03, 0x7a, - 0xe0, 0x0b, 0x1c, 0x47, 0xf1, 0x4a, 0x8e, 0xb9, 0xd7, 0x3e, 0x7d, 0x65, 0x23, 0xcd, 0x4e, 0x96, - 0xc7, 0xf2, 0x0a, 0xf4, 0x0d, 0xec, 0x04, 0x29, 0x3d, 0x49, 0xc7, 0x68, 0x1f, 0x6c, 0x17, 0xcb, - 0xc0, 0xb2, 0x75, 0x0c, 0x25, 0xa0, 0xf2, 0xa7, 0x99, 0x44, 0xb6, 0xcb, 0x12, 0xd3, 0xfc, 0xac, - 0x80, 0xbe, 0xae, 0x4b, 0x0f, 0x60, 0xdf, 0x72, 0xbc, 0x9b, 0x01, 0xb3, 0x3b, 0x57, 0xe7, 0x83, - 0xde, 0xad, 0xdd, 0x25, 0x7f, 0xd1, 0x5d, 0xd0, 0x2d, 0xc7, 0xb3, 0xec, 0xf3, 0xde, 0x80, 0x28, - 0xf4, 0x6f, 0x28, 0x5b, 0x8e, 0xd7, 0xb9, 0xea, 0xf7, 0x7b, 0x2e, 0x29, 0xd0, 0x7d, 0x30, 0x2c, - 0xc7, 0x63, 0x57, 0x8e, 0x63, 0x9d, 0x75, 0x2e, 0x89, 0x4a, 0x8f, 0xa0, 0x62, 0x39, 0x5e, 0xb7, - 0xef, 0x78, 0x5d, 0xfb, 0x9a, 0xd9, 0x9d, 0x33, 0xd7, 0xee, 0x12, 0x8d, 0x02, 0x94, 0x12, 0x77, - 0xd7, 0x21, 0xc5, 0xcc, 0x1e, 0xda, 0x2e, 0x29, 0x65, 0xe5, 0x7a, 0x83, 0xa1, 0xcd, 0x5c, 0xb2, - 0x93, 0xc9, 0x9b, 0xeb, 0xee, 0x99, 0x6b, 0x13, 0x3d, 0x93, 0x5d, 0xdb, 0xb1, 0x5d, 0x9b, 0x94, - 0x2f, 0x34, 0xbd, 0x40, 0xd4, 0x0b, 0x4d, 0x57, 0x89, 0x66, 0x7e, 0x52, 0xe0, 0x68, 0x28, 0x62, - 0xf4, 0x1f, 0x2f, 0x71, 0xc5, 0xfc, 0x70, 0x8c, 0x0c, 0x9f, 0x16, 0xc8, 0x05, 0xad, 0x81, 0x3e, - 0x8f, 0xf8, 0x24, 0x61, 0x27, 0x01, 0x97, 0x59, 0xae, 0x69, 0x0b, 0xca, 0x53, 0x5c, 0x79, 0x71, - 0x12, 0x9f, 0x01, 0xa3, 0xcd, 0x7c, 0x21, 0xf3, 0x4a, 0xfa, 0x34, 0xb3, 0xb6, 0xf9, 0xaa, 0xbf, - 0xe6, 0x6b, 0xde, 0xc3, 0xf1, 0xcb, 0xa6, 0xf8, 0x3c, 0x0a, 0x39, 0x52, 0x07, 0x68, 0x9a, 0xe8, - 0x89, 0xcd, 0xdb, 0xca, 0xfe, 0x8c, 0xf6, 0x3f, 0x3f, 0x5d, 0x00, 0x56, 0x19, 0xbd, 0x74, 0x99, - 0x1f, 0xe1, 0x20, 0xbd, 0xc7, 0xf5, 0x47, 0x33, 0xe4, 0xaf, 0x19, 0xfd, 0x18, 0x4a, 0x42, 0x06, - 0x57, 0x0b, 0x75, 0xb5, 0x51, 0x66, 0x99, 0xfa, 0xdd, 0x09, 0xef, 0xe0, 0xf0, 0xf9, 0xcd, 0x7f, - 0x64, 0xbe, 0x77, 0xa0, 0xb1, 0xc5, 0x0c, 0xe9, 0x21, 0x14, 0x1f, 0x7d, 0x11, 0x3c, 0x64, 0xd3, - 0xa4, 0x22, 0x19, 0xe5, 0x7e, 0x32, 0x13, 0x18, 0xcb, 0x27, 0x2c, 0xb3, 0x4c, 0x99, 0xa7, 0x50, - 0xfa, 0x20, 0x2d, 0xfa, 0x2f, 0x14, 0xe3, 0x45, 0x32, 0x6b, 0xfa, 0xa9, 0x93, 0xed, 0x06, 0x92, - 0xc2, 0x2c, 0x3d, 0x36, 0xbf, 0x29, 0xb0, 0x9b, 0x36, 0x34, 0x8c, 0x16, 0x71, 0x80, 0x09, 0xc1, - 0x29, 0xae, 0xf8, 0xdc, 0x0f, 0x70, 0x4d, 0x70, 0xad, 0x93, 0x66, 0xf8, 0x83, 0x1f, 0xdf, 0x65, - 0xb7, 0xa6, 0x82, 0xbe, 0x07, 0x43, 0x92, 0x14, 0x9e, 0x58, 0xcd, 0x51, 0x32, 0xdc, 0x6b, 0x1f, - 0x6e, 0x96, 0x4a, 0x72, 0x12, 0xee, 0x6a, 0x8e, 0x0c, 0x44, 0x6e, 0x3f, 0xdf, 0x44, 0xed, 0x15, - 0x9b, 0xb8, 0x79, 0xbf, 0xe2, 0xb3, 0xf7, 0xfb, 0x3f, 0x87, 0x51, 0xca, 0xaa, 0x6c, 0xcd, 0x9a, - 0xe2, 0x58, 0x03, 0xb2, 0xfe, 0xbb, 0x3d, 0x59, 0x4e, 0x04, 0x72, 0xde, 0x9c, 0x44, 0xad, 0xd4, - 0x6a, 0x8d, 0xa3, 0xd6, 0x52, 0xb4, 0xe4, 0xbf, 0xb8, 0xb5, 0xc9, 0x1c, 0x95, 0xa4, 0xe7, 0xed, - 0xf7, 0x00, 0x00, 0x00, 0xff, 0xff, 0xd7, 0x3c, 0x64, 0xd3, 0xda, 0x05, 0x00, 0x00, +func init() { proto.RegisterFile("binlogdata.proto", fileDescriptor_binlogdata_9f7a55f16227bf1c) } + +var fileDescriptor_binlogdata_9f7a55f16227bf1c = []byte{ + // 900 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x55, 0xcd, 0x6e, 0xdb, 0x46, + 0x10, 0x0e, 0x45, 0x8a, 0x22, 0x47, 0xae, 0x4d, 0xaf, 0x1d, 0x43, 0x30, 0x50, 0x40, 0xe0, 0xa1, + 0x51, 0x0d, 0x54, 0x0a, 0x94, 0xf6, 0xd4, 0x93, 0x29, 0xb1, 0x86, 0x62, 0x5a, 0x36, 0x56, 0x74, + 0x5a, 0xe4, 0x42, 0x50, 0xd2, 0x5a, 0x16, 0x2c, 0x73, 0x65, 0xee, 0xca, 0xae, 0x2e, 0x7d, 0x85, + 0x1e, 0xfa, 0x14, 0x7d, 0x91, 0xbe, 0x49, 0x6f, 0x7d, 0x88, 0x62, 0x7f, 0x44, 0x49, 0x09, 0xe0, + 0xba, 0x87, 0xdc, 0xbe, 0xd9, 0x99, 0x9d, 0x9d, 0xf9, 0x66, 0xf8, 0x11, 0xbc, 0xe1, 0x34, 0x9b, + 0xd1, 0xc9, 0x38, 0xe5, 0x69, 0x73, 0x9e, 0x53, 0x4e, 0x11, 0xac, 0x4f, 0x8e, 0xab, 0x0f, 0x0b, + 0x92, 0x2f, 0x95, 0xe3, 0x78, 0x97, 0xd3, 0x39, 0x5d, 0x07, 0xfa, 0x17, 0x50, 0xe9, 0xdc, 0xa6, + 0x39, 0x23, 0x1c, 0x1d, 0x81, 0x3d, 0x9a, 0x4d, 0x49, 0xc6, 0x6b, 0x46, 0xdd, 0x68, 0x94, 0xb1, + 0xb6, 0x10, 0x02, 0x6b, 0x44, 0xb3, 0xac, 0x56, 0x92, 0xa7, 0x12, 0x8b, 0x58, 0x46, 0xf2, 0x47, + 0x92, 0xd7, 0x4c, 0x15, 0xab, 0x2c, 0xff, 0x6f, 0x13, 0xf6, 0x03, 0xf9, 0x74, 0x9c, 0xa7, 0x19, + 0x4b, 0x47, 0x7c, 0x4a, 0x33, 0x74, 0x06, 0xc0, 0x78, 0xca, 0xc9, 0x3d, 0xc9, 0x38, 0xab, 0x19, + 0x75, 0xb3, 0x51, 0x6d, 0xbf, 0x69, 0x6e, 0x14, 0xfd, 0xd9, 0x95, 0xe6, 0x60, 0x15, 0x8f, 0x37, + 0xae, 0xa2, 0x36, 0x54, 0xc9, 0x23, 0xc9, 0x78, 0xc2, 0xe9, 0x1d, 0xc9, 0x6a, 0x56, 0xdd, 0x68, + 0x54, 0xdb, 0xfb, 0x4d, 0xd5, 0x60, 0x28, 0x3c, 0xb1, 0x70, 0x60, 0x20, 0x05, 0x3e, 0xfe, 0xab, + 0x04, 0x6e, 0x91, 0x0d, 0x45, 0xe0, 0x8c, 0x52, 0x4e, 0x26, 0x34, 0x5f, 0xca, 0x36, 0x77, 0xdb, + 0x6f, 0x5f, 0x58, 0x48, 0xb3, 0xa3, 0xef, 0xe1, 0x22, 0x03, 0xfa, 0x0e, 0x2a, 0x23, 0xc5, 0x9e, + 0x64, 0xa7, 0xda, 0x3e, 0xd8, 0x4c, 0xa6, 0x89, 0xc5, 0xab, 0x18, 0xe4, 0x81, 0xc9, 0x1e, 0x66, + 0x92, 0xb2, 0x1d, 0x2c, 0xa0, 0xff, 0xa7, 0x01, 0xce, 0x2a, 0x2f, 0x3a, 0x80, 0xbd, 0x20, 0x4a, + 0xae, 0xfb, 0x38, 0xec, 0x5c, 0x9e, 0xf5, 0x7b, 0x1f, 0xc3, 0xae, 0xf7, 0x0a, 0xed, 0x80, 0x13, + 0x44, 0x49, 0x10, 0x9e, 0xf5, 0xfa, 0x9e, 0x81, 0xbe, 0x02, 0x37, 0x88, 0x92, 0xce, 0xe5, 0xc5, + 0x45, 0x2f, 0xf6, 0x4a, 0x68, 0x0f, 0xaa, 0x41, 0x94, 0xe0, 0xcb, 0x28, 0x0a, 0x4e, 0x3b, 0xe7, + 0x9e, 0x89, 0x5e, 0xc3, 0x7e, 0x10, 0x25, 0xdd, 0x8b, 0x28, 0xe9, 0x86, 0x57, 0x38, 0xec, 0x9c, + 0xc6, 0x61, 0xd7, 0xb3, 0x10, 0x80, 0x2d, 0x8e, 0xbb, 0x91, 0x57, 0xd6, 0x78, 0x10, 0xc6, 0x9e, + 0xad, 0xd3, 0xf5, 0xfa, 0x83, 0x10, 0xc7, 0x5e, 0x45, 0x9b, 0xd7, 0x57, 0xdd, 0xd3, 0x38, 0xf4, + 0x1c, 0x6d, 0x76, 0xc3, 0x28, 0x8c, 0x43, 0xcf, 0x7d, 0x6f, 0x39, 0x25, 0xcf, 0x7c, 0x6f, 0x39, + 0xa6, 0x67, 0xf9, 0x7f, 0x18, 0xf0, 0x7a, 0xc0, 0x73, 0x92, 0xde, 0x9f, 0x93, 0x25, 0x4e, 0xb3, + 0x09, 0xc1, 0xe4, 0x61, 0x41, 0x18, 0x47, 0xc7, 0xe0, 0xcc, 0x29, 0x9b, 0x0a, 0xee, 0x24, 0xc1, + 0x2e, 0x2e, 0x6c, 0xd4, 0x02, 0xf7, 0x8e, 0x2c, 0x93, 0x5c, 0xc4, 0x6b, 0xc2, 0x50, 0xb3, 0x58, + 0xc8, 0x22, 0x93, 0x73, 0xa7, 0xd1, 0x26, 0xbf, 0xe6, 0x7f, 0xf3, 0xeb, 0xdf, 0xc0, 0xd1, 0xa7, + 0x45, 0xb1, 0x39, 0xcd, 0x18, 0x41, 0x11, 0x20, 0x75, 0x31, 0xe1, 0xeb, 0xd9, 0xca, 0xfa, 0xaa, + 0xed, 0xaf, 0x9f, 0x5d, 0x00, 0xbc, 0x3f, 0xfc, 0xf4, 0xc8, 0xff, 0x15, 0x0e, 0xd4, 0x3b, 0x71, + 0x3a, 0x9c, 0x11, 0xf6, 0x92, 0xd6, 0x8f, 0xc0, 0xe6, 0x32, 0xb8, 0x56, 0xaa, 0x9b, 0x0d, 0x17, + 0x6b, 0xeb, 0xff, 0x76, 0x38, 0x86, 0xc3, 0xed, 0x97, 0xbf, 0x48, 0x7f, 0xdf, 0x83, 0x85, 0x17, + 0x33, 0x82, 0x0e, 0xa1, 0x7c, 0x9f, 0xf2, 0xd1, 0xad, 0xee, 0x46, 0x19, 0xa2, 0x95, 0x9b, 0xe9, + 0x8c, 0x93, 0x5c, 0x8e, 0xd0, 0xc5, 0xda, 0xf2, 0xdf, 0x82, 0xfd, 0x93, 0x44, 0xe8, 0x1b, 0x28, + 0xe7, 0x0b, 0xd1, 0xab, 0xfa, 0xd4, 0xbd, 0xcd, 0x02, 0x44, 0x62, 0xac, 0xdc, 0xfe, 0x3f, 0x06, + 0xec, 0xa8, 0x82, 0x06, 0x74, 0x91, 0x8f, 0x88, 0x60, 0xf0, 0x8e, 0x2c, 0xd9, 0x3c, 0x1d, 0x91, + 0x15, 0x83, 0x2b, 0x5b, 0x14, 0xc3, 0x6e, 0xd3, 0x7c, 0xac, 0x5f, 0x55, 0x06, 0xfa, 0x01, 0xaa, + 0x92, 0x49, 0x9e, 0xf0, 0xe5, 0x9c, 0x48, 0x0e, 0x77, 0xdb, 0x87, 0xeb, 0xa5, 0x92, 0x3c, 0xf1, + 0x78, 0x39, 0x27, 0x18, 0x78, 0x81, 0xb7, 0x37, 0xd1, 0x7a, 0xc1, 0x26, 0xae, 0xe7, 0x57, 0xde, + 0x9a, 0xdf, 0x49, 0x41, 0x86, 0xad, 0xb3, 0x6c, 0xf4, 0xaa, 0xe8, 0x28, 0x08, 0xba, 0x02, 0x07, + 0xd3, 0x27, 0x29, 0x53, 0xc8, 0x07, 0x7b, 0x48, 0x6e, 0x68, 0x4e, 0xf4, 0x90, 0x40, 0x8b, 0x18, + 0xa6, 0x4f, 0x58, 0x7b, 0x50, 0x1d, 0xca, 0xe9, 0xcd, 0x8a, 0xe7, 0xed, 0x10, 0xe5, 0xf0, 0x7f, + 0x37, 0xc0, 0xfe, 0xa0, 0x12, 0x9e, 0x80, 0x25, 0x19, 0x50, 0xa2, 0x76, 0xb4, 0x59, 0x86, 0x8a, + 0x90, 0x1c, 0xc8, 0x18, 0xa1, 0xe8, 0x13, 0x3e, 0x5d, 0x31, 0x29, 0xb1, 0xd0, 0xa6, 0xf1, 0x58, + 0x69, 0x93, 0x8b, 0x05, 0x44, 0xef, 0x00, 0x72, 0xfa, 0x94, 0x48, 0x29, 0x65, 0x35, 0x4b, 0x8e, + 0xf2, 0x70, 0x6b, 0x94, 0xba, 0x19, 0xec, 0xe6, 0x1a, 0x31, 0xff, 0x17, 0xd8, 0xfd, 0xa0, 0x36, + 0xf4, 0x25, 0x5f, 0xc5, 0xc9, 0xd6, 0x2a, 0x3d, 0xcf, 0xde, 0x8f, 0xb0, 0x57, 0x64, 0xd6, 0x5b, + 0xdf, 0x80, 0xb2, 0xac, 0x4e, 0xef, 0x19, 0xfa, 0xbc, 0x69, 0xac, 0x02, 0x4e, 0x7e, 0x03, 0x58, + 0xb3, 0x80, 0xaa, 0x50, 0xb9, 0xee, 0x9f, 0xf7, 0x2f, 0x7f, 0xee, 0x7b, 0xaf, 0x90, 0x03, 0xd6, + 0x59, 0xdc, 0xeb, 0x7a, 0x06, 0x72, 0xa1, 0xac, 0x74, 0xb6, 0x24, 0x44, 0x52, 0x8b, 0xac, 0x29, + 0x14, 0xb8, 0x50, 0x58, 0x0b, 0x55, 0xc0, 0x2c, 0x74, 0x54, 0x0b, 0xa7, 0x2d, 0xb0, 0x56, 0xcd, + 0x8a, 0xc0, 0x5a, 0x32, 0x1d, 0x11, 0x2c, 0x84, 0xd6, 0x0d, 0xbe, 0xfd, 0xf8, 0xe6, 0x71, 0xca, + 0x09, 0x63, 0xcd, 0x29, 0x6d, 0x29, 0xd4, 0x9a, 0xd0, 0xd6, 0x23, 0x6f, 0xc9, 0xdf, 0x70, 0x6b, + 0x5d, 0xf8, 0xd0, 0x96, 0x27, 0xef, 0xfe, 0x0d, 0x00, 0x00, 0xff, 0xff, 0x94, 0x9d, 0xa9, 0x2b, + 0xd5, 0x07, 0x00, 0x00, } diff --git a/go/vt/vttablet/tabletserver/vstreamer/engine.go b/go/vt/vttablet/tabletserver/vstreamer/engine.go index 03708684236..50dc5e4a4df 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/engine.go +++ b/go/vt/vttablet/tabletserver/vstreamer/engine.go @@ -27,6 +27,7 @@ import ( "vitess.io/vitess/go/vt/srvtopo" "vitess.io/vitess/go/vt/topo" "vitess.io/vitess/go/vt/vtgate/vindexes" + "vitess.io/vitess/go/vt/vttablet/tabletserver/schema" binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" vschemapb "vitess.io/vitess/go/vt/proto/vschema" @@ -53,12 +54,13 @@ type Engine struct { kschema *vindexes.KeyspaceSchema ts srvtopo.Server + se *schema.Engine keyspace string cell string } // NewEngine creates a new Engine. -func NewEngine(ts srvtopo.Server) *Engine { +func NewEngine(ts srvtopo.Server, se *schema.Engine) *Engine { vschemaErrors = stats.NewCounter("VSchemaErrors", "Count of VSchema errors") return &Engine{ streamers: make(map[int]*vstreamer), @@ -101,7 +103,7 @@ func (vse *Engine) Close() { } // Stream starts a new stream. -func (vse *Engine) Stream(ctx context.Context, cp *mysql.ConnParams, startPos mysql.Position, filter *binlogdatapb.Filter, f func()) error { +func (vse *Engine) Stream(ctx context.Context, cp *mysql.ConnParams, startPos mysql.Position, filter *binlogdatapb.Filter, send func(*binlogdatapb.VEvent) error) error { // Ensure kschema is initialized and the watcher is started. vse.watcherOnce.Do(vse.setWatch) @@ -112,13 +114,10 @@ func (vse *Engine) Stream(ctx context.Context, cp *mysql.ConnParams, startPos my if !vse.isOpen { return nil, 0, errors.New("VStreamer is not open") } - streamer, err := newVStreamer(cp, startPos, filter, f) - if err != nil { - return nil, 0, err - } + streamer := newVStreamer(ctx, cp, vse.se, startPos, filter, vse.kschema, send) idx := vse.streamIdx - vse.streamIdx++ vse.streamers[idx] = streamer + vse.streamIdx++ // Now that we've added the stream, increment wg. // This must be done before releasing the lock. vse.wg.Add(1) @@ -137,7 +136,7 @@ func (vse *Engine) Stream(ctx context.Context, cp *mysql.ConnParams, startPos my }() // No lock is held while streaming, but wg is incremented. - return streamer.Stream(ctx) + return streamer.Stream() } func (vse *Engine) setWatch() { diff --git a/go/vt/vttablet/tabletserver/vstreamer/planbuilder.go b/go/vt/vttablet/tabletserver/vstreamer/planbuilder.go index 4140124f5ea..24ccbd40f08 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/planbuilder.go +++ b/go/vt/vttablet/tabletserver/vstreamer/planbuilder.go @@ -20,11 +20,14 @@ import ( "fmt" "regexp" "strings" + "time" "vitess.io/vitess/go/mysql" + "vitess.io/vitess/go/sqltypes" "vitess.io/vitess/go/vt/key" "vitess.io/vitess/go/vt/sqlparser" "vitess.io/vitess/go/vt/vtgate/vindexes" + "vitess.io/vitess/go/vt/vttablet/tabletserver/schema" binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" topodatapb "vitess.io/vitess/go/vt/proto/topodata" @@ -32,7 +35,7 @@ import ( // Plan represents the streaming plan for a table. type Plan struct { - Table string + Table *Table ColExprs []ColExpr VindexColumn int Vindex vindexes.Vindex @@ -42,6 +45,7 @@ type Plan struct { // ColExpr represents a column expression. type ColExpr struct { ColNum int + Alias sqlparser.ColIdent Operation Operation } @@ -56,79 +60,126 @@ const ( OpHour ) -// TableMap contains the metadata for a table. The +// Table contains the metadata for a table. The // name is dervied from mysql's Table_map_log_event. -type TableMap struct { +type Table struct { *mysql.TableMap - ColumnNames []sqlparser.ColIdent + Columns []schema.TableColumn } -func buildPlan(tm *TableMap, kschema *vindexes.KeyspaceSchema, filter *binlogdatapb.Filter) (*Plan, error) { +func (plan *Plan) filter(values []sqltypes.Value) (bool, []sqltypes.Value, error) { + result := make([]sqltypes.Value, len(plan.ColExprs)) + for i, colExpr := range plan.ColExprs { + switch colExpr.Operation { + case OpYearMonth: + v, _ := sqltypes.ToInt64(values[colExpr.ColNum]) + t := time.Unix(v, 0) + s := fmt.Sprintf("%d%02d", t.Year(), t.Month()) + result[i] = sqltypes.NewVarBinary(s) + case OpDay: + v, _ := sqltypes.ToInt64(values[colExpr.ColNum]) + t := time.Unix(v, 0) + s := fmt.Sprintf("%d%02d%02d", t.Year(), t.Month(), t.Day()) + result[i] = sqltypes.NewVarBinary(s) + case OpHour: + v, _ := sqltypes.ToInt64(values[colExpr.ColNum]) + t := time.Unix(v, 0) + s := fmt.Sprintf("%d%02d%02d%02d", t.Year(), t.Month(), t.Day(), t.Hour()) + result[i] = sqltypes.NewVarBinary(s) + default: + result[i] = values[colExpr.ColNum] + } + } + if plan.Vindex == nil { + return true, result, nil + } + destinations, err := plan.Vindex.Map(nil, []sqltypes.Value{result[plan.VindexColumn]}) + if err != nil { + return false, nil, err + } + if len(destinations) != 1 { + return false, nil, fmt.Errorf("mapping row to keyspace id returned an invalid array of destinations: %v", key.DestinationsString(destinations)) + } + ksid, ok := destinations[0].(key.DestinationKeyspaceID) + if !ok || len(ksid) == 0 { + return false, nil, fmt.Errorf("could not map %v to a keyspace id, got destination %v", result[plan.VindexColumn], destinations[0]) + } + if !key.KeyRangeContains(plan.KeyRange, ksid) { + return false, nil, nil + } + return true, result, nil +} + +func buildPlan(ti *Table, kschema *vindexes.KeyspaceSchema, filter *binlogdatapb.Filter) (*Plan, error) { for _, rule := range filter.Rules { switch { case strings.HasPrefix(rule.Match, "/"): expr := strings.Trim(rule.Match, "/") - result, err := regexp.MatchString(expr, tm.Name) + result, err := regexp.MatchString(expr, ti.Name) if err != nil { return nil, err } if !result { continue } - return buildREPlan(tm, kschema, rule.Filter) - case rule.Match == tm.Name: + return buildREPlan(ti, kschema, rule.Filter) + case rule.Match == ti.Name: + return buildTablePlan(ti, kschema, rule.Filter) } } return nil, nil } -func buildREPlan(tm *TableMap, kschema *vindexes.KeyspaceSchema, filter string) (*Plan, error) { +func buildREPlan(ti *Table, kschema *vindexes.KeyspaceSchema, filter string) (*Plan, error) { plan := &Plan{ - Table: tm.Name, + Table: ti, } - plan.ColExprs = make([]ColExpr, len(tm.ColumnNames)) - for i := range tm.ColumnNames { + plan.ColExprs = make([]ColExpr, len(ti.Columns)) + for i, col := range ti.Columns { plan.ColExprs[i].ColNum = i + plan.ColExprs[i].Alias = col.Name + } + if filter == "" { + return plan, nil } - if filter != "" { - // We need to additionally set VindexColumn, Vindex and KeyRange - // based on the Primary Vindex of the table. - // Find table in kschema. - table := kschema.Tables[tm.Name] - if table == nil { - return nil, fmt.Errorf("no vschema definition for table %s", tm.Name) - } - // Get Primary Vindex. - if len(table.ColumnVindexes) == 0 { - return nil, fmt.Errorf("table %s has no primary vindex", tm.Name) - } - colnum, err := findColumn(tm, table.ColumnVindexes[0].Columns[0]) - if err != nil { - return nil, err - } - plan.VindexColumn = colnum - plan.Vindex = table.ColumnVindexes[0].Vindex - // Parse keyrange. - keyranges, err := key.ParseShardingSpec(filter) - if err != nil { - return nil, err - } - if len(keyranges) != 1 { - return nil, fmt.Errorf("error parsing keyrange: %v", filter) - } - plan.KeyRange = keyranges[0] + // We need to additionally set VindexColumn, Vindex and KeyRange + // based on the Primary Vindex of the table. + // Find table in kschema. + table := kschema.Tables[ti.Name] + if table == nil { + return nil, fmt.Errorf("no vschema definition for table %s", ti.Name) } + // Get Primary Vindex. + if len(table.ColumnVindexes) == 0 { + return nil, fmt.Errorf("table %s has no primary vindex", ti.Name) + } + colnum, err := findColumn(ti, table.ColumnVindexes[0].Columns[0]) + if err != nil { + return nil, err + } + plan.VindexColumn = colnum + plan.Vindex = table.ColumnVindexes[0].Vindex + + // Parse keyrange. + keyranges, err := key.ParseShardingSpec(filter) + if err != nil { + return nil, err + } + if len(keyranges) != 1 { + return nil, fmt.Errorf("error parsing keyrange: %v", filter) + } + plan.KeyRange = keyranges[0] return plan, nil } -func buildTablePlan(tm *TableMap, kschema *vindexes.KeyspaceSchema, query string) (*Plan, error) { +func buildTablePlan(ti *Table, kschema *vindexes.KeyspaceSchema, query string) (*Plan, error) { statement, err := sqlparser.Parse(query) if err != nil { return nil, err } plan := &Plan{ - Table: tm.Name, + Table: ti, } sel, ok := statement.(*sqlparser.Select) if !ok { @@ -145,13 +196,13 @@ func buildTablePlan(tm *TableMap, kschema *vindexes.KeyspaceSchema, query string if fromTable.IsEmpty() { return nil, fmt.Errorf("unexpected: %v", sqlparser.String(sel)) } - if fromTable.String() == tm.Name { - return nil, fmt.Errorf("unexpected: select expression table %v does not match the table entry name %s", sqlparser.String(fromTable), tm.Name) + if fromTable.String() == ti.Name { + return nil, fmt.Errorf("unexpected: select expression table %v does not match the table entry name %s", sqlparser.String(fromTable), ti.Name) } if _, ok := sel.SelectExprs[0].(*sqlparser.StarExpr); !ok { for _, expr := range sel.SelectExprs { - cExpr, err := analyzeExpr(tm, expr) + cExpr, err := analyzeExpr(ti, expr) if err != nil { return nil, err } @@ -172,14 +223,25 @@ func buildTablePlan(tm *TableMap, kschema *vindexes.KeyspaceSchema, query string if len(funcExpr.Exprs) != 3 { return nil, fmt.Errorf("unexpected where clause: %v", sqlparser.String(sel.Where)) } - cExpr, err := analyzeExpr(tm, funcExpr.Exprs[0]) - if err != nil { - return nil, err + aexpr, ok := funcExpr.Exprs[0].(*sqlparser.AliasedExpr) + if !ok { + return nil, fmt.Errorf("unexpected: %v", sqlparser.String(funcExpr)) } - if cExpr.Operation != OpNone { - return nil, fmt.Errorf("unexpected operaion on vindex column: %v", funcExpr.Exprs[0]) + colname, ok := aexpr.Expr.(*sqlparser.ColName) + if !ok { + return nil, fmt.Errorf("unsupported: %v", sqlparser.String(funcExpr)) + } + found := false + for i, cExpr := range plan.ColExprs { + if cExpr.Alias.Equal(colname.Name) { + found = true + plan.VindexColumn = i + break + } + } + if !found { + return nil, fmt.Errorf("keyrange expression does not reference a column in the select list: %v", sqlparser.String(colname)) } - plan.VindexColumn = cExpr.ColNum vtype, err := selString(funcExpr.Exprs[1]) if err != nil { return nil, err @@ -203,18 +265,18 @@ func buildTablePlan(tm *TableMap, kschema *vindexes.KeyspaceSchema, query string return plan, nil } -func analyzeExpr(tm *TableMap, expr sqlparser.SelectExpr) (cExpr ColExpr, err error) { +func analyzeExpr(ti *Table, expr sqlparser.SelectExpr) (cExpr ColExpr, err error) { aexpr, ok := expr.(*sqlparser.AliasedExpr) if !ok { return ColExpr{}, fmt.Errorf("unexpected: %v", sqlparser.String(expr)) } switch expr := aexpr.Expr.(type) { case *sqlparser.ColName: - colnum, err := findColumn(tm, expr.Name) + colnum, err := findColumn(ti, expr.Name) if err != nil { return ColExpr{}, err } - return ColExpr{ColNum: colnum}, nil + return ColExpr{ColNum: colnum, Alias: expr.Name}, nil case *sqlparser.FuncExpr: if expr.Distinct || len(expr.Exprs) != 1 { return ColExpr{}, fmt.Errorf("unsupported: %v", sqlparser.String(expr)) @@ -229,17 +291,20 @@ func analyzeExpr(tm *TableMap, expr sqlparser.SelectExpr) (cExpr ColExpr, err er if !ok { return ColExpr{}, fmt.Errorf("unsupported: %v", sqlparser.String(expr)) } - colnum, err := findColumn(tm, innerCol.Name) + if aInner.As.IsEmpty() { + return ColExpr{}, fmt.Errorf("need alias for expression: %v", sqlparser.String(expr)) + } + colnum, err := findColumn(ti, innerCol.Name) if err != nil { return ColExpr{}, err } switch fname { case "yearmonth": - return ColExpr{ColNum: colnum, Operation: OpYearMonth}, nil + return ColExpr{ColNum: colnum, Alias: aInner.As, Operation: OpYearMonth}, nil case "day": - return ColExpr{ColNum: colnum, Operation: OpDay}, nil + return ColExpr{ColNum: colnum, Alias: aInner.As, Operation: OpDay}, nil case "hour": - return ColExpr{ColNum: colnum, Operation: OpHour}, nil + return ColExpr{ColNum: colnum, Alias: aInner.As, Operation: OpHour}, nil default: panic("unreachable") } @@ -263,11 +328,11 @@ func selString(expr sqlparser.SelectExpr) (string, error) { return string(val.Val), nil } -func findColumn(tm *TableMap, name sqlparser.ColIdent) (int, error) { - for i, cname := range tm.ColumnNames { - if name.Equal(cname) { +func findColumn(ti *Table, name sqlparser.ColIdent) (int, error) { + for i, col := range ti.Columns { + if name.Equal(col.Name) { return i, nil } } - return 0, fmt.Errorf("column %s not found in table %s", sqlparser.String(name), tm.Name) + return 0, fmt.Errorf("column %s not found in table %s", sqlparser.String(name), ti.Name) } diff --git a/go/vt/vttablet/tabletserver/vstreamer/streamer.go b/go/vt/vttablet/tabletserver/vstreamer/streamer.go index 04103b90c11..f31ebe4b72a 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/streamer.go +++ b/go/vt/vttablet/tabletserver/vstreamer/streamer.go @@ -18,37 +18,389 @@ package vstreamer import ( "context" + "fmt" + "strings" "vitess.io/vitess/go/mysql" + "vitess.io/vitess/go/sqltypes" "vitess.io/vitess/go/vt/binlog" + "vitess.io/vitess/go/vt/log" + "vitess.io/vitess/go/vt/sqlparser" "vitess.io/vitess/go/vt/vtgate/vindexes" + "vitess.io/vitess/go/vt/vttablet/tabletserver/schema" binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" ) +// statementPrefixes are normal sql statement prefixes. +var statementPrefixes = map[string]binlogdatapb.VEventType{ + "begin": binlogdatapb.VEventType_BEGIN, + "commit": binlogdatapb.VEventType_COMMIT, + "rollback": binlogdatapb.VEventType_ROLLBACK, + "insert": binlogdatapb.VEventType_INSERT, + "update": binlogdatapb.VEventType_UPDATE, + "delete": binlogdatapb.VEventType_DELETE, + "create": binlogdatapb.VEventType_DDL, + "alter": binlogdatapb.VEventType_DDL, + "drop": binlogdatapb.VEventType_DDL, + "truncate": binlogdatapb.VEventType_DDL, + "rename": binlogdatapb.VEventType_DDL, + "set": binlogdatapb.VEventType_SET, +} + +// getStatementCategory returns the binlogdatapb.BL_* category for a SQL statement. +func getStatementCategory(sql string) binlogdatapb.VEventType { + if i := strings.IndexByte(sql, byte(' ')); i >= 0 { + sql = sql[:i] + } + return statementPrefixes[strings.ToLower(sql)] +} + type vstreamer struct { + ctx context.Context + cancel func() + cp *mysql.ConnParams + se *schema.Engine startPos mysql.Position filter *binlogdatapb.Filter - f func() - conn *binlog.SlaveConnection + send func(*binlogdatapb.VEvent) error + + kevents chan *vindexes.KeyspaceSchema + kschema *vindexes.KeyspaceSchema + plans map[uint64]*Plan + + // format and pos are updated by parseEvent. + format mysql.BinlogFormat + pos mysql.Position } -func newVStreamer(cp *mysql.ConnParams, startPos mysql.Position, filter *binlogdatapb.Filter, f func()) (*vstreamer, error) { +func newVStreamer(ctx context.Context, cp *mysql.ConnParams, se *schema.Engine, startPos mysql.Position, filter *binlogdatapb.Filter, kschema *vindexes.KeyspaceSchema, send func(*binlogdatapb.VEvent) error) *vstreamer { + ctx, cancel := context.WithCancel(ctx) return &vstreamer{ + ctx: ctx, + cancel: cancel, cp: cp, + se: se, startPos: startPos, filter: filter, - f: f, - }, nil + send: send, + kevents: make(chan *vindexes.KeyspaceSchema, 1), + kschema: kschema, + plans: make(map[uint64]*Plan), + } } func (vs *vstreamer) SetKSchema(kschema *vindexes.KeyspaceSchema) { + // Since vs.Stream is a single-threaded loop. We just send an event to + // that thread, which helps us avoid mutexes to update the plans. + select { + case vs.kevents <- kschema: + case <-vs.ctx.Done(): + } +} + +func (vs *vstreamer) Cancel() { + vs.cancel() +} + +// Stream runs a single-threaded loop. +func (vs *vstreamer) Stream() error { + defer vs.cancel() + vs.pos = vs.startPos + + // Ensure se is Open. If vttablet came up in a non_serving role, + // the schema engine may not have been initialized. + if err := vs.se.Open(); err != nil { + return wrapError(err, vs.pos) + } + + conn, err := binlog.NewSlaveConnection(vs.cp) + if err != nil { + return wrapError(err, vs.pos) + } + defer conn.Close() + + events, err := conn.StartBinlogDumpFromPosition(vs.ctx, vs.pos) + if err != nil { + return wrapError(err, vs.pos) + } + err = vs.parseEvents(vs.ctx, events) + return wrapError(err, vs.pos) +} + +func (vs *vstreamer) parseEvents(ctx context.Context, events <-chan mysql.BinlogEvent) error { + for { + select { + case ev, ok := <-events: + if !ok { + return fmt.Errorf("server EOF") + } + if err := vs.parseEvent(ev); err != nil { + return err + } + case vs.kschema = <-vs.kevents: + if err := vs.updatePlans(); err != nil { + return err + } + case <-ctx.Done(): + return ctx.Err() + } + } } -func (vs *vstreamer) Stream(ctx context.Context) error { +func (vs *vstreamer) parseEvent(ev mysql.BinlogEvent) error { + // Validate the buffer before reading fields from it. + if !ev.IsValid() { + return fmt.Errorf("can't parse binlog event: invalid data: %#v", ev) + } + + // We need to keep checking for FORMAT_DESCRIPTION_EVENT even after we've + // seen one, because another one might come along (e.g. on log rotate due to + // binlog settings change) that changes the format. + if ev.IsFormatDescription() { + var err error + vs.format, err = ev.Format() + if err != nil { + return fmt.Errorf("can't parse FORMAT_DESCRIPTION_EVENT: %v, event data: %#v", err, ev) + } + return nil + } + + // We can't parse anything until we get a FORMAT_DESCRIPTION_EVENT that + // tells us the size of the event header. + if vs.format.IsZero() { + // The only thing that should come before the FORMAT_DESCRIPTION_EVENT + // is a fake ROTATE_EVENT, which the master sends to tell us the name + // of the current log file. + if ev.IsRotate() { + return nil + } + return fmt.Errorf("got a real event before FORMAT_DESCRIPTION_EVENT: %#v", ev) + } + + // Strip the checksum, if any. We don't actually verify the checksum, so discard it. + ev, _, err := ev.StripChecksum(vs.format) + if err != nil { + return fmt.Errorf("can't strip checksum from binlog event: %v, event data: %#v", err, ev) + } + switch { + case ev.IsPseudo() || ev.IsGTID(): + gtid, hasBegin, err := ev.GTID(vs.format) + if err != nil { + return fmt.Errorf("can't get GTID from binlog event: %v, event data: %#v", err, ev) + } + vs.pos = mysql.AppendGTID(vs.pos, gtid) + vevent := &binlogdatapb.VEvent{ + Type: binlogdatapb.VEventType_GTID, + Gtid: mysql.EncodePosition(vs.pos), + } + if err := vs.send(vevent); err != nil { + return fmt.Errorf("error sending GTID: %v", err) + } + if hasBegin { + vevent := &binlogdatapb.VEvent{ + Type: binlogdatapb.VEventType_BEGIN, + } + if err := vs.send(vevent); err != nil { + return fmt.Errorf("error sending BEGIN: %v", err) + } + } + case ev.IsXID(): + vevent := &binlogdatapb.VEvent{ + Type: binlogdatapb.VEventType_COMMIT, + } + if err := vs.send(vevent); err != nil { + return fmt.Errorf("error sending COMMIT: %v", err) + } + case ev.IsQuery(): + q, err := ev.Query(vs.format) + if err != nil { + return fmt.Errorf("can't get query from binlog event: %v, event data: %#v", err, ev) + } + var vevent *binlogdatapb.VEvent + switch cat := getStatementCategory(q.SQL); cat { + case binlogdatapb.VEventType_BEGIN, binlogdatapb.VEventType_COMMIT, binlogdatapb.VEventType_ROLLBACK: + vevent = &binlogdatapb.VEvent{ + Type: cat, + } + case binlogdatapb.VEventType_DDL: + vevent = &binlogdatapb.VEvent{ + Type: cat, + Ddl: q.SQL, + } + default: + return fmt.Errorf("unexpected event type %v in row-based replication: %#v", cat, ev) + } + if err := vs.send(vevent); err != nil { + return fmt.Errorf("error sending COMMIT: %v", err) + } + case ev.IsTableMap(): + id := ev.TableID(vs.format) + tm, err := ev.TableMap(vs.format) + if err != nil { + return err + } + if tm.Database != "" && tm.Database != vs.cp.DbName { + return nil + } + ti := vs.se.GetTable(sqlparser.NewTableIdent(tm.Name)) + if ti == nil { + return fmt.Errorf("unknown table %v in schema", tm.Name) + } + if len(ti.Columns) < len(tm.Types) { + return fmt.Errorf("cannot determine table columns for %s: event has %d columns, current schema has %d: %#v", tm.Name, len(tm.Types), len(ti.Columns), ev) + } + table := &Table{ + TableMap: tm, + Columns: ti.Columns, + } + plan, err := buildPlan(table, vs.kschema, vs.filter) + if err != nil { + return err + } + if plan != nil { + vs.plans[id] = plan + } + case ev.IsWriteRows(): + id := ev.TableID(vs.format) + plan, ok := vs.plans[id] + if !ok { + return nil + } + rows, err := ev.Rows(vs.format, plan.Table.TableMap) + if err != nil { + return err + } + rowEvents := make([]*binlogdatapb.RowEvent, 0, len(rows.Rows)) + for _, row := range rows.Rows { + ok, values, err := vs.extractRowAndFilter(plan, row.Data, rows.DataColumns, row.NullColumns) + if err != nil { + return err + } + if !ok { + continue + } + encoded := sqltypes.RowToProto3(values) + rowEvents = append(rowEvents, &binlogdatapb.RowEvent{After: encoded}) + } + vevent := &binlogdatapb.VEvent{ + Type: binlogdatapb.VEventType_INSERT, + RowEvents: rowEvents, + } + if err := vs.send(vevent); err != nil { + return fmt.Errorf("error sending INSERT: %v", err) + } + case ev.IsDeleteRows(): + id := ev.TableID(vs.format) + plan, ok := vs.plans[id] + if !ok { + return nil + } + rows, err := ev.Rows(vs.format, plan.Table.TableMap) + if err != nil { + return err + } + rowEvents := make([]*binlogdatapb.RowEvent, 0, len(rows.Rows)) + for _, row := range rows.Rows { + ok, values, err := vs.extractRowAndFilter(plan, row.Identify, rows.IdentifyColumns, row.NullIdentifyColumns) + if err != nil { + return err + } + if !ok { + continue + } + encoded := sqltypes.RowToProto3(values) + rowEvents = append(rowEvents, &binlogdatapb.RowEvent{Before: encoded}) + } + vevent := &binlogdatapb.VEvent{ + Type: binlogdatapb.VEventType_DELETE, + RowEvents: rowEvents, + } + if err := vs.send(vevent); err != nil { + return fmt.Errorf("error sending DELETE: %v", err) + } + case ev.IsUpdateRows(): + id := ev.TableID(vs.format) + plan, ok := vs.plans[id] + if !ok { + return nil + } + rows, err := ev.Rows(vs.format, plan.Table.TableMap) + if err != nil { + return err + } + rowEvents := make([]*binlogdatapb.RowEvent, 0, len(rows.Rows)) + for _, row := range rows.Rows { + beforeOK, beforeValues, err := vs.extractRowAndFilter(plan, row.Identify, rows.IdentifyColumns, row.NullIdentifyColumns) + if err != nil { + return err + } + afterOK, afterValues, err := vs.extractRowAndFilter(plan, row.Data, rows.DataColumns, row.NullColumns) + if err != nil { + return err + } + if !beforeOK && !afterOK { + continue + } + rowEvent := &binlogdatapb.RowEvent{} + if beforeOK { + rowEvent.Before = sqltypes.RowToProto3(beforeValues) + } + if afterOK { + rowEvent.After = sqltypes.RowToProto3(afterValues) + } + rowEvents = append(rowEvents, rowEvent) + } + vevent := &binlogdatapb.VEvent{ + Type: binlogdatapb.VEventType_UPDATE, + RowEvents: rowEvents, + } + if err := vs.send(vevent); err != nil { + return fmt.Errorf("error sending UPDATE: %v", err) + } + } return nil } -func (vs *vstreamer) Cancel() { +func (vs *vstreamer) updatePlans() error { + for id, plan := range vs.plans { + newPlan, err := buildPlan(plan.Table, vs.kschema, vs.filter) + if err != nil { + return err + } + vs.plans[id] = newPlan + } + return nil +} + +func (vs *vstreamer) extractRowAndFilter(plan *Plan, data []byte, dataColumns, nullColumns mysql.Bitmap) (bool, []sqltypes.Value, error) { + values := make([]sqltypes.Value, dataColumns.Count()) + valueIndex := 0 + pos := 0 + for colNum := 0; colNum < dataColumns.Count(); colNum++ { + if !dataColumns.Bit(colNum) { + continue + } + if nullColumns.Bit(valueIndex) { + valueIndex++ + continue + } + value, l, err := mysql.CellValue(data, pos, plan.Table.Types[colNum], plan.Table.Metadata[colNum], plan.Table.Columns[colNum].Type) + if err != nil { + return false, nil, err + } + pos += l + values[colNum] = value + valueIndex++ + } + return plan.filter(values) +} + +func wrapError(err error, stopPos mysql.Position) error { + if err != nil { + err = fmt.Errorf("stream error @ %v: %v", stopPos, err) + } + log.Infof("stream ended @ %v, err: %v", stopPos, err) + return err } diff --git a/proto/binlogdata.proto b/proto/binlogdata.proto index b5ac7bebd33..1a2ab445094 100644 --- a/proto/binlogdata.proto +++ b/proto/binlogdata.proto @@ -154,3 +154,41 @@ message BinlogSource { // for the filter. Filter filter = 6; } + +// VEventType enumerates the event types. +enum VEventType { + UNKNOWN = 0; + GTID = 1; + BEGIN = 2; + COMMIT = 3; + ROLLBACK = 4; + DDL = 5; + INSERT = 6; + UPDATE = 7; + DELETE = 8; + SET = 9; +} + +message RowEvent { + query.Row before = 1; + query.Row after = 2; +} + +// VEvent represents a vstream event +message VEvent { + VEventType type = 1; + string gtid = 2; + string ddl = 3; + repeated RowEvent row_events = 4; +} + +// VStreamRequest is the payload for VStream +message VStreamRequest { + string position = 1; + Filter filter = 2; +} + +// VStreamResponse is the response from VStream +message VStreamResponse { + repeated VEvent event = 1; +} diff --git a/py/vtproto/binlogdata_pb2.py b/py/vtproto/binlogdata_pb2.py index a6578c15bdf..b9c3737957c 100644 --- a/py/vtproto/binlogdata_pb2.py +++ b/py/vtproto/binlogdata_pb2.py @@ -3,6 +3,7 @@ import sys _b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1')) +from google.protobuf.internal import enum_type_wrapper from google.protobuf import descriptor as _descriptor from google.protobuf import message as _message from google.protobuf import reflection as _reflection @@ -21,10 +22,75 @@ 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\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\"\xb5\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.FilterB)Z\'vitess.io/vitess/go/vt/proto/binlogdatab\x06proto3') + serialized_pb=_b('\n\x10\x62inlogdata.proto\x12\nbinlogdata\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\"\xb5\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\"A\n\x08RowEvent\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\"s\n\x06VEvent\x12$\n\x04type\x18\x01 \x01(\x0e\x32\x16.binlogdata.VEventType\x12\x0c\n\x04gtid\x18\x02 \x01(\t\x12\x0b\n\x03\x64\x64l\x18\x03 \x01(\t\x12(\n\nrow_events\x18\x04 \x03(\x0b\x32\x14.binlogdata.RowEvent\"F\n\x0eVStreamRequest\x12\x10\n\x08position\x18\x01 \x01(\t\x12\"\n\x06\x66ilter\x18\x02 \x01(\x0b\x32\x12.binlogdata.Filter\"4\n\x0fVStreamResponse\x12!\n\x05\x65vent\x18\x01 \x03(\x0b\x32\x12.binlogdata.VEvent*~\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\n\n\x06UPDATE\x10\x07\x12\n\n\x06\x44\x45LETE\x10\x08\x12\x07\n\x03SET\x10\tB)Z\'vitess.io/vitess/go/vt/proto/binlogdatab\x06proto3') , dependencies=[query__pb2.DESCRIPTOR,topodata__pb2.DESCRIPTOR,]) +_VEVENTTYPE = _descriptor.EnumDescriptor( + name='VEventType', + full_name='binlogdata.VEventType', + filename=None, + file=DESCRIPTOR, + values=[ + _descriptor.EnumValueDescriptor( + name='UNKNOWN', index=0, number=0, + serialized_options=None, + type=None), + _descriptor.EnumValueDescriptor( + name='GTID', index=1, number=1, + serialized_options=None, + type=None), + _descriptor.EnumValueDescriptor( + name='BEGIN', index=2, number=2, + serialized_options=None, + type=None), + _descriptor.EnumValueDescriptor( + name='COMMIT', index=3, number=3, + serialized_options=None, + type=None), + _descriptor.EnumValueDescriptor( + name='ROLLBACK', index=4, number=4, + serialized_options=None, + type=None), + _descriptor.EnumValueDescriptor( + name='DDL', index=5, number=5, + serialized_options=None, + type=None), + _descriptor.EnumValueDescriptor( + name='INSERT', index=6, number=6, + serialized_options=None, + type=None), + _descriptor.EnumValueDescriptor( + name='UPDATE', index=7, number=7, + serialized_options=None, + type=None), + _descriptor.EnumValueDescriptor( + name='DELETE', index=8, number=8, + serialized_options=None, + type=None), + _descriptor.EnumValueDescriptor( + name='SET', index=9, number=9, + serialized_options=None, + type=None), + ], + containing_type=None, + serialized_options=None, + serialized_start=1517, + serialized_end=1643, +) +_sym_db.RegisterEnumDescriptor(_VEVENTTYPE) + +VEventType = enum_type_wrapper.EnumTypeWrapper(_VEVENTTYPE) +UNKNOWN = 0 +GTID = 1 +BEGIN = 2 +COMMIT = 3 +ROLLBACK = 4 +DDL = 5 +INSERT = 6 +UPDATE = 7 +DELETE = 8 +SET = 9 _BINLOGTRANSACTION_STATEMENT_CATEGORY = _descriptor.EnumDescriptor( @@ -496,6 +562,165 @@ serialized_end=1205, ) + +_ROWEVENT = _descriptor.Descriptor( + name='RowEvent', + full_name='binlogdata.RowEvent', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='before', full_name='binlogdata.RowEvent.before', 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='after', full_name='binlogdata.RowEvent.after', 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), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=1207, + serialized_end=1272, +) + + +_VEVENT = _descriptor.Descriptor( + name='VEvent', + full_name='binlogdata.VEvent', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='type', full_name='binlogdata.VEvent.type', index=0, + number=1, 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='gtid', full_name='binlogdata.VEvent.gtid', 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, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='ddl', full_name='binlogdata.VEvent.ddl', 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, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='row_events', full_name='binlogdata.VEvent.row_events', index=3, + 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=1274, + serialized_end=1389, +) + + +_VSTREAMREQUEST = _descriptor.Descriptor( + name='VStreamRequest', + full_name='binlogdata.VStreamRequest', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='position', full_name='binlogdata.VStreamRequest.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), + _descriptor.FieldDescriptor( + name='filter', full_name='binlogdata.VStreamRequest.filter', 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), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=1391, + serialized_end=1461, +) + + +_VSTREAMRESPONSE = _descriptor.Descriptor( + name='VStreamResponse', + full_name='binlogdata.VStreamResponse', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='event', full_name='binlogdata.VStreamResponse.event', 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), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=1463, + serialized_end=1515, +) + _BINLOGTRANSACTION_STATEMENT.fields_by_name['category'].enum_type = _BINLOGTRANSACTION_STATEMENT_CATEGORY _BINLOGTRANSACTION_STATEMENT.fields_by_name['charset'].message_type = _CHARSET _BINLOGTRANSACTION_STATEMENT.containing_type = _BINLOGTRANSACTION @@ -511,6 +736,12 @@ _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 +_ROWEVENT.fields_by_name['before'].message_type = query__pb2._ROW +_ROWEVENT.fields_by_name['after'].message_type = query__pb2._ROW +_VEVENT.fields_by_name['type'].enum_type = _VEVENTTYPE +_VEVENT.fields_by_name['row_events'].message_type = _ROWEVENT +_VSTREAMREQUEST.fields_by_name['filter'].message_type = _FILTER +_VSTREAMRESPONSE.fields_by_name['event'].message_type = _VEVENT DESCRIPTOR.message_types_by_name['Charset'] = _CHARSET DESCRIPTOR.message_types_by_name['BinlogTransaction'] = _BINLOGTRANSACTION DESCRIPTOR.message_types_by_name['StreamKeyRangeRequest'] = _STREAMKEYRANGEREQUEST @@ -520,6 +751,11 @@ DESCRIPTOR.message_types_by_name['Rule'] = _RULE DESCRIPTOR.message_types_by_name['Filter'] = _FILTER DESCRIPTOR.message_types_by_name['BinlogSource'] = _BINLOGSOURCE +DESCRIPTOR.message_types_by_name['RowEvent'] = _ROWEVENT +DESCRIPTOR.message_types_by_name['VEvent'] = _VEVENT +DESCRIPTOR.message_types_by_name['VStreamRequest'] = _VSTREAMREQUEST +DESCRIPTOR.message_types_by_name['VStreamResponse'] = _VSTREAMRESPONSE +DESCRIPTOR.enum_types_by_name['VEventType'] = _VEVENTTYPE _sym_db.RegisterFileDescriptor(DESCRIPTOR) Charset = _reflection.GeneratedProtocolMessageType('Charset', (_message.Message,), dict( @@ -593,6 +829,34 @@ )) _sym_db.RegisterMessage(BinlogSource) +RowEvent = _reflection.GeneratedProtocolMessageType('RowEvent', (_message.Message,), dict( + DESCRIPTOR = _ROWEVENT, + __module__ = 'binlogdata_pb2' + # @@protoc_insertion_point(class_scope:binlogdata.RowEvent) + )) +_sym_db.RegisterMessage(RowEvent) + +VEvent = _reflection.GeneratedProtocolMessageType('VEvent', (_message.Message,), dict( + DESCRIPTOR = _VEVENT, + __module__ = 'binlogdata_pb2' + # @@protoc_insertion_point(class_scope:binlogdata.VEvent) + )) +_sym_db.RegisterMessage(VEvent) + +VStreamRequest = _reflection.GeneratedProtocolMessageType('VStreamRequest', (_message.Message,), dict( + DESCRIPTOR = _VSTREAMREQUEST, + __module__ = 'binlogdata_pb2' + # @@protoc_insertion_point(class_scope:binlogdata.VStreamRequest) + )) +_sym_db.RegisterMessage(VStreamRequest) + +VStreamResponse = _reflection.GeneratedProtocolMessageType('VStreamResponse', (_message.Message,), dict( + DESCRIPTOR = _VSTREAMRESPONSE, + __module__ = 'binlogdata_pb2' + # @@protoc_insertion_point(class_scope:binlogdata.VStreamResponse) + )) +_sym_db.RegisterMessage(VStreamResponse) + DESCRIPTOR._options = None # @@protoc_insertion_point(module_scope) From 8cd1c5b33f0cf1af9702f2c2eaaa448ded1e82ea Mon Sep 17 00:00:00 2001 From: Sugu Sougoumarane Date: Sat, 29 Dec 2018 14:37:24 -0800 Subject: [PATCH 020/115] vreplication: tabletserver inits and other tweaks Signed-off-by: Sugu Sougoumarane --- go/vt/proto/binlogdata/binlogdata.pb.go | 175 +++++++++--------- go/vt/vttablet/tabletserver/tabletserver.go | 7 + .../vttablet/tabletserver/vstreamer/engine.go | 13 +- .../tabletserver/vstreamer/planbuilder.go | 15 ++ .../tabletserver/vstreamer/streamer.go | 171 ++++++----------- proto/binlogdata.proto | 3 + py/vtproto/binlogdata_pb2.py | 11 +- 7 files changed, 190 insertions(+), 205 deletions(-) diff --git a/go/vt/proto/binlogdata/binlogdata.pb.go b/go/vt/proto/binlogdata/binlogdata.pb.go index d2dd885698a..ecfbf2ee435 100644 --- a/go/vt/proto/binlogdata/binlogdata.pb.go +++ b/go/vt/proto/binlogdata/binlogdata.pb.go @@ -21,6 +21,8 @@ var _ = math.Inf const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package // VEventType enumerates the event types. +// This list is comprehensive. Many of these types +// will not be encountered in RBR mode. type VEventType int32 const ( @@ -34,19 +36,21 @@ const ( VEventType_UPDATE VEventType = 7 VEventType_DELETE VEventType = 8 VEventType_SET VEventType = 9 + VEventType_ROW VEventType = 10 ) var VEventType_name = map[int32]string{ - 0: "UNKNOWN", - 1: "GTID", - 2: "BEGIN", - 3: "COMMIT", - 4: "ROLLBACK", - 5: "DDL", - 6: "INSERT", - 7: "UPDATE", - 8: "DELETE", - 9: "SET", + 0: "UNKNOWN", + 1: "GTID", + 2: "BEGIN", + 3: "COMMIT", + 4: "ROLLBACK", + 5: "DDL", + 6: "INSERT", + 7: "UPDATE", + 8: "DELETE", + 9: "SET", + 10: "ROW", } var VEventType_value = map[string]int32{ "UNKNOWN": 0, @@ -59,13 +63,14 @@ var VEventType_value = map[string]int32{ "UPDATE": 7, "DELETE": 8, "SET": 9, + "ROW": 10, } func (x VEventType) String() string { return proto.EnumName(VEventType_name, int32(x)) } func (VEventType) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_binlogdata_9f7a55f16227bf1c, []int{0} + return fileDescriptor_binlogdata_41dfc977aeca6f81, []int{0} } type BinlogTransaction_Statement_Category int32 @@ -113,7 +118,7 @@ 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_9f7a55f16227bf1c, []int{1, 0, 0} + return fileDescriptor_binlogdata_41dfc977aeca6f81, []int{1, 0, 0} } // Charset is the per-statement charset info from a QUERY_EVENT binlog entry. @@ -133,7 +138,7 @@ 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_9f7a55f16227bf1c, []int{0} + return fileDescriptor_binlogdata_41dfc977aeca6f81, []int{0} } func (m *Charset) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Charset.Unmarshal(m, b) @@ -190,7 +195,7 @@ 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_9f7a55f16227bf1c, []int{1} + return fileDescriptor_binlogdata_41dfc977aeca6f81, []int{1} } func (m *BinlogTransaction) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_BinlogTransaction.Unmarshal(m, b) @@ -240,7 +245,7 @@ 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_9f7a55f16227bf1c, []int{1, 0} + return fileDescriptor_binlogdata_41dfc977aeca6f81, []int{1, 0} } func (m *BinlogTransaction_Statement) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_BinlogTransaction_Statement.Unmarshal(m, b) @@ -298,7 +303,7 @@ 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_9f7a55f16227bf1c, []int{2} + return fileDescriptor_binlogdata_41dfc977aeca6f81, []int{2} } func (m *StreamKeyRangeRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_StreamKeyRangeRequest.Unmarshal(m, b) @@ -351,7 +356,7 @@ 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_9f7a55f16227bf1c, []int{3} + return fileDescriptor_binlogdata_41dfc977aeca6f81, []int{3} } func (m *StreamKeyRangeResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_StreamKeyRangeResponse.Unmarshal(m, b) @@ -395,7 +400,7 @@ 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_9f7a55f16227bf1c, []int{4} + return fileDescriptor_binlogdata_41dfc977aeca6f81, []int{4} } func (m *StreamTablesRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_StreamTablesRequest.Unmarshal(m, b) @@ -448,7 +453,7 @@ 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_9f7a55f16227bf1c, []int{5} + return fileDescriptor_binlogdata_41dfc977aeca6f81, []int{5} } func (m *StreamTablesResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_StreamTablesResponse.Unmarshal(m, b) @@ -493,7 +498,7 @@ 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_9f7a55f16227bf1c, []int{6} + return fileDescriptor_binlogdata_41dfc977aeca6f81, []int{6} } func (m *Rule) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Rule.Unmarshal(m, b) @@ -540,7 +545,7 @@ 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_9f7a55f16227bf1c, []int{7} + return fileDescriptor_binlogdata_41dfc977aeca6f81, []int{7} } func (m *Filter) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Filter.Unmarshal(m, b) @@ -593,7 +598,7 @@ 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_9f7a55f16227bf1c, []int{8} + return fileDescriptor_binlogdata_41dfc977aeca6f81, []int{8} } func (m *BinlogSource) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_BinlogSource.Unmarshal(m, b) @@ -667,7 +672,7 @@ 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_9f7a55f16227bf1c, []int{9} + return fileDescriptor_binlogdata_41dfc977aeca6f81, []int{9} } func (m *RowEvent) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_RowEvent.Unmarshal(m, b) @@ -716,7 +721,7 @@ 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_9f7a55f16227bf1c, []int{10} + return fileDescriptor_binlogdata_41dfc977aeca6f81, []int{10} } func (m *VEvent) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_VEvent.Unmarshal(m, b) @@ -777,7 +782,7 @@ 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_9f7a55f16227bf1c, []int{11} + return fileDescriptor_binlogdata_41dfc977aeca6f81, []int{11} } func (m *VStreamRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_VStreamRequest.Unmarshal(m, b) @@ -823,7 +828,7 @@ 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_9f7a55f16227bf1c, []int{12} + return fileDescriptor_binlogdata_41dfc977aeca6f81, []int{12} } func (m *VStreamResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_VStreamResponse.Unmarshal(m, b) @@ -869,65 +874,65 @@ func init() { proto.RegisterEnum("binlogdata.BinlogTransaction_Statement_Category", BinlogTransaction_Statement_Category_name, BinlogTransaction_Statement_Category_value) } -func init() { proto.RegisterFile("binlogdata.proto", fileDescriptor_binlogdata_9f7a55f16227bf1c) } +func init() { proto.RegisterFile("binlogdata.proto", fileDescriptor_binlogdata_41dfc977aeca6f81) } -var fileDescriptor_binlogdata_9f7a55f16227bf1c = []byte{ - // 900 bytes of a gzipped FileDescriptorProto +var fileDescriptor_binlogdata_41dfc977aeca6f81 = []byte{ + // 906 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x55, 0xcd, 0x6e, 0xdb, 0x46, - 0x10, 0x0e, 0x45, 0x8a, 0x22, 0x47, 0xae, 0x4d, 0xaf, 0x1d, 0x43, 0x30, 0x50, 0x40, 0xe0, 0xa1, - 0x51, 0x0d, 0x54, 0x0a, 0x94, 0xf6, 0xd4, 0x93, 0x29, 0xb1, 0x86, 0x62, 0x5a, 0x36, 0x56, 0x74, - 0x5a, 0xe4, 0x42, 0x50, 0xd2, 0x5a, 0x16, 0x2c, 0x73, 0x65, 0xee, 0xca, 0xae, 0x2e, 0x7d, 0x85, - 0x1e, 0xfa, 0x14, 0x7d, 0x91, 0xbe, 0x49, 0x6f, 0x7d, 0x88, 0x62, 0x7f, 0x44, 0x49, 0x09, 0xe0, - 0xba, 0x87, 0xdc, 0xbe, 0xd9, 0x99, 0x9d, 0x9d, 0xf9, 0x66, 0xf8, 0x11, 0xbc, 0xe1, 0x34, 0x9b, - 0xd1, 0xc9, 0x38, 0xe5, 0x69, 0x73, 0x9e, 0x53, 0x4e, 0x11, 0xac, 0x4f, 0x8e, 0xab, 0x0f, 0x0b, - 0x92, 0x2f, 0x95, 0xe3, 0x78, 0x97, 0xd3, 0x39, 0x5d, 0x07, 0xfa, 0x17, 0x50, 0xe9, 0xdc, 0xa6, - 0x39, 0x23, 0x1c, 0x1d, 0x81, 0x3d, 0x9a, 0x4d, 0x49, 0xc6, 0x6b, 0x46, 0xdd, 0x68, 0x94, 0xb1, - 0xb6, 0x10, 0x02, 0x6b, 0x44, 0xb3, 0xac, 0x56, 0x92, 0xa7, 0x12, 0x8b, 0x58, 0x46, 0xf2, 0x47, - 0x92, 0xd7, 0x4c, 0x15, 0xab, 0x2c, 0xff, 0x6f, 0x13, 0xf6, 0x03, 0xf9, 0x74, 0x9c, 0xa7, 0x19, - 0x4b, 0x47, 0x7c, 0x4a, 0x33, 0x74, 0x06, 0xc0, 0x78, 0xca, 0xc9, 0x3d, 0xc9, 0x38, 0xab, 0x19, - 0x75, 0xb3, 0x51, 0x6d, 0xbf, 0x69, 0x6e, 0x14, 0xfd, 0xd9, 0x95, 0xe6, 0x60, 0x15, 0x8f, 0x37, - 0xae, 0xa2, 0x36, 0x54, 0xc9, 0x23, 0xc9, 0x78, 0xc2, 0xe9, 0x1d, 0xc9, 0x6a, 0x56, 0xdd, 0x68, - 0x54, 0xdb, 0xfb, 0x4d, 0xd5, 0x60, 0x28, 0x3c, 0xb1, 0x70, 0x60, 0x20, 0x05, 0x3e, 0xfe, 0xab, - 0x04, 0x6e, 0x91, 0x0d, 0x45, 0xe0, 0x8c, 0x52, 0x4e, 0x26, 0x34, 0x5f, 0xca, 0x36, 0x77, 0xdb, - 0x6f, 0x5f, 0x58, 0x48, 0xb3, 0xa3, 0xef, 0xe1, 0x22, 0x03, 0xfa, 0x0e, 0x2a, 0x23, 0xc5, 0x9e, - 0x64, 0xa7, 0xda, 0x3e, 0xd8, 0x4c, 0xa6, 0x89, 0xc5, 0xab, 0x18, 0xe4, 0x81, 0xc9, 0x1e, 0x66, - 0x92, 0xb2, 0x1d, 0x2c, 0xa0, 0xff, 0xa7, 0x01, 0xce, 0x2a, 0x2f, 0x3a, 0x80, 0xbd, 0x20, 0x4a, - 0xae, 0xfb, 0x38, 0xec, 0x5c, 0x9e, 0xf5, 0x7b, 0x1f, 0xc3, 0xae, 0xf7, 0x0a, 0xed, 0x80, 0x13, - 0x44, 0x49, 0x10, 0x9e, 0xf5, 0xfa, 0x9e, 0x81, 0xbe, 0x02, 0x37, 0x88, 0x92, 0xce, 0xe5, 0xc5, - 0x45, 0x2f, 0xf6, 0x4a, 0x68, 0x0f, 0xaa, 0x41, 0x94, 0xe0, 0xcb, 0x28, 0x0a, 0x4e, 0x3b, 0xe7, - 0x9e, 0x89, 0x5e, 0xc3, 0x7e, 0x10, 0x25, 0xdd, 0x8b, 0x28, 0xe9, 0x86, 0x57, 0x38, 0xec, 0x9c, - 0xc6, 0x61, 0xd7, 0xb3, 0x10, 0x80, 0x2d, 0x8e, 0xbb, 0x91, 0x57, 0xd6, 0x78, 0x10, 0xc6, 0x9e, - 0xad, 0xd3, 0xf5, 0xfa, 0x83, 0x10, 0xc7, 0x5e, 0x45, 0x9b, 0xd7, 0x57, 0xdd, 0xd3, 0x38, 0xf4, - 0x1c, 0x6d, 0x76, 0xc3, 0x28, 0x8c, 0x43, 0xcf, 0x7d, 0x6f, 0x39, 0x25, 0xcf, 0x7c, 0x6f, 0x39, - 0xa6, 0x67, 0xf9, 0x7f, 0x18, 0xf0, 0x7a, 0xc0, 0x73, 0x92, 0xde, 0x9f, 0x93, 0x25, 0x4e, 0xb3, - 0x09, 0xc1, 0xe4, 0x61, 0x41, 0x18, 0x47, 0xc7, 0xe0, 0xcc, 0x29, 0x9b, 0x0a, 0xee, 0x24, 0xc1, - 0x2e, 0x2e, 0x6c, 0xd4, 0x02, 0xf7, 0x8e, 0x2c, 0x93, 0x5c, 0xc4, 0x6b, 0xc2, 0x50, 0xb3, 0x58, - 0xc8, 0x22, 0x93, 0x73, 0xa7, 0xd1, 0x26, 0xbf, 0xe6, 0x7f, 0xf3, 0xeb, 0xdf, 0xc0, 0xd1, 0xa7, - 0x45, 0xb1, 0x39, 0xcd, 0x18, 0x41, 0x11, 0x20, 0x75, 0x31, 0xe1, 0xeb, 0xd9, 0xca, 0xfa, 0xaa, - 0xed, 0xaf, 0x9f, 0x5d, 0x00, 0xbc, 0x3f, 0xfc, 0xf4, 0xc8, 0xff, 0x15, 0x0e, 0xd4, 0x3b, 0x71, - 0x3a, 0x9c, 0x11, 0xf6, 0x92, 0xd6, 0x8f, 0xc0, 0xe6, 0x32, 0xb8, 0x56, 0xaa, 0x9b, 0x0d, 0x17, - 0x6b, 0xeb, 0xff, 0x76, 0x38, 0x86, 0xc3, 0xed, 0x97, 0xbf, 0x48, 0x7f, 0xdf, 0x83, 0x85, 0x17, - 0x33, 0x82, 0x0e, 0xa1, 0x7c, 0x9f, 0xf2, 0xd1, 0xad, 0xee, 0x46, 0x19, 0xa2, 0x95, 0x9b, 0xe9, - 0x8c, 0x93, 0x5c, 0x8e, 0xd0, 0xc5, 0xda, 0xf2, 0xdf, 0x82, 0xfd, 0x93, 0x44, 0xe8, 0x1b, 0x28, - 0xe7, 0x0b, 0xd1, 0xab, 0xfa, 0xd4, 0xbd, 0xcd, 0x02, 0x44, 0x62, 0xac, 0xdc, 0xfe, 0x3f, 0x06, - 0xec, 0xa8, 0x82, 0x06, 0x74, 0x91, 0x8f, 0x88, 0x60, 0xf0, 0x8e, 0x2c, 0xd9, 0x3c, 0x1d, 0x91, - 0x15, 0x83, 0x2b, 0x5b, 0x14, 0xc3, 0x6e, 0xd3, 0x7c, 0xac, 0x5f, 0x55, 0x06, 0xfa, 0x01, 0xaa, - 0x92, 0x49, 0x9e, 0xf0, 0xe5, 0x9c, 0x48, 0x0e, 0x77, 0xdb, 0x87, 0xeb, 0xa5, 0x92, 0x3c, 0xf1, - 0x78, 0x39, 0x27, 0x18, 0x78, 0x81, 0xb7, 0x37, 0xd1, 0x7a, 0xc1, 0x26, 0xae, 0xe7, 0x57, 0xde, - 0x9a, 0xdf, 0x49, 0x41, 0x86, 0xad, 0xb3, 0x6c, 0xf4, 0xaa, 0xe8, 0x28, 0x08, 0xba, 0x02, 0x07, - 0xd3, 0x27, 0x29, 0x53, 0xc8, 0x07, 0x7b, 0x48, 0x6e, 0x68, 0x4e, 0xf4, 0x90, 0x40, 0x8b, 0x18, - 0xa6, 0x4f, 0x58, 0x7b, 0x50, 0x1d, 0xca, 0xe9, 0xcd, 0x8a, 0xe7, 0xed, 0x10, 0xe5, 0xf0, 0x7f, - 0x37, 0xc0, 0xfe, 0xa0, 0x12, 0x9e, 0x80, 0x25, 0x19, 0x50, 0xa2, 0x76, 0xb4, 0x59, 0x86, 0x8a, - 0x90, 0x1c, 0xc8, 0x18, 0xa1, 0xe8, 0x13, 0x3e, 0x5d, 0x31, 0x29, 0xb1, 0xd0, 0xa6, 0xf1, 0x58, - 0x69, 0x93, 0x8b, 0x05, 0x44, 0xef, 0x00, 0x72, 0xfa, 0x94, 0x48, 0x29, 0x65, 0x35, 0x4b, 0x8e, - 0xf2, 0x70, 0x6b, 0x94, 0xba, 0x19, 0xec, 0xe6, 0x1a, 0x31, 0xff, 0x17, 0xd8, 0xfd, 0xa0, 0x36, - 0xf4, 0x25, 0x5f, 0xc5, 0xc9, 0xd6, 0x2a, 0x3d, 0xcf, 0xde, 0x8f, 0xb0, 0x57, 0x64, 0xd6, 0x5b, - 0xdf, 0x80, 0xb2, 0xac, 0x4e, 0xef, 0x19, 0xfa, 0xbc, 0x69, 0xac, 0x02, 0x4e, 0x7e, 0x03, 0x58, - 0xb3, 0x80, 0xaa, 0x50, 0xb9, 0xee, 0x9f, 0xf7, 0x2f, 0x7f, 0xee, 0x7b, 0xaf, 0x90, 0x03, 0xd6, - 0x59, 0xdc, 0xeb, 0x7a, 0x06, 0x72, 0xa1, 0xac, 0x74, 0xb6, 0x24, 0x44, 0x52, 0x8b, 0xac, 0x29, - 0x14, 0xb8, 0x50, 0x58, 0x0b, 0x55, 0xc0, 0x2c, 0x74, 0x54, 0x0b, 0xa7, 0x2d, 0xb0, 0x56, 0xcd, - 0x8a, 0xc0, 0x5a, 0x32, 0x1d, 0x11, 0x2c, 0x84, 0xd6, 0x0d, 0xbe, 0xfd, 0xf8, 0xe6, 0x71, 0xca, - 0x09, 0x63, 0xcd, 0x29, 0x6d, 0x29, 0xd4, 0x9a, 0xd0, 0xd6, 0x23, 0x6f, 0xc9, 0xdf, 0x70, 0x6b, - 0x5d, 0xf8, 0xd0, 0x96, 0x27, 0xef, 0xfe, 0x0d, 0x00, 0x00, 0xff, 0xff, 0x94, 0x9d, 0xa9, 0x2b, - 0xd5, 0x07, 0x00, 0x00, + 0x10, 0x0e, 0x45, 0x8a, 0x22, 0x47, 0xa9, 0xbd, 0x5e, 0x3b, 0x86, 0x60, 0xa0, 0x80, 0xc0, 0x43, + 0xa3, 0x1a, 0xa8, 0x14, 0x28, 0xed, 0xa9, 0x27, 0x53, 0x62, 0x0d, 0xc5, 0xb4, 0x64, 0xac, 0xe8, + 0xa4, 0xc8, 0x85, 0xa0, 0xa4, 0xb5, 0x2c, 0x58, 0xe6, 0xca, 0xe4, 0xca, 0xae, 0x9e, 0xa0, 0xc7, + 0x1e, 0xfa, 0x14, 0x7d, 0x91, 0xbe, 0x49, 0x6f, 0x7d, 0x88, 0x62, 0x7f, 0x44, 0x49, 0x09, 0x90, + 0xba, 0x87, 0xde, 0xbe, 0xd9, 0x99, 0x9d, 0x9d, 0xf9, 0x66, 0xf8, 0x11, 0xd0, 0x68, 0x96, 0xce, + 0xd9, 0x74, 0x92, 0xf0, 0xa4, 0xb9, 0xc8, 0x18, 0x67, 0x18, 0x36, 0x27, 0x27, 0xd5, 0x87, 0x25, + 0xcd, 0x56, 0xca, 0x71, 0xb2, 0xc7, 0xd9, 0x82, 0x6d, 0x02, 0xbd, 0x4b, 0xa8, 0x74, 0x6e, 0x93, + 0x2c, 0xa7, 0x1c, 0x1f, 0x83, 0x3d, 0x9e, 0xcf, 0x68, 0xca, 0x6b, 0x46, 0xdd, 0x68, 0x94, 0x89, + 0xb6, 0x30, 0x06, 0x6b, 0xcc, 0xd2, 0xb4, 0x56, 0x92, 0xa7, 0x12, 0x8b, 0xd8, 0x9c, 0x66, 0x8f, + 0x34, 0xab, 0x99, 0x2a, 0x56, 0x59, 0xde, 0x5f, 0x26, 0x1c, 0xf8, 0xf2, 0xe9, 0x28, 0x4b, 0xd2, + 0x3c, 0x19, 0xf3, 0x19, 0x4b, 0xf1, 0x39, 0x40, 0xce, 0x13, 0x4e, 0xef, 0x69, 0xca, 0xf3, 0x9a, + 0x51, 0x37, 0x1b, 0xd5, 0xf6, 0xeb, 0xe6, 0x56, 0xd1, 0x9f, 0x5d, 0x69, 0x0e, 0xd7, 0xf1, 0x64, + 0xeb, 0x2a, 0x6e, 0x43, 0x95, 0x3e, 0xd2, 0x94, 0xc7, 0x9c, 0xdd, 0xd1, 0xb4, 0x66, 0xd5, 0x8d, + 0x46, 0xb5, 0x7d, 0xd0, 0x54, 0x0d, 0x06, 0xc2, 0x13, 0x09, 0x07, 0x01, 0x5a, 0xe0, 0x93, 0x3f, + 0x4b, 0xe0, 0x16, 0xd9, 0x70, 0x08, 0xce, 0x38, 0xe1, 0x74, 0xca, 0xb2, 0x95, 0x6c, 0x73, 0xaf, + 0xfd, 0xe6, 0x99, 0x85, 0x34, 0x3b, 0xfa, 0x1e, 0x29, 0x32, 0xe0, 0xef, 0xa0, 0x32, 0x56, 0xec, + 0x49, 0x76, 0xaa, 0xed, 0xc3, 0xed, 0x64, 0x9a, 0x58, 0xb2, 0x8e, 0xc1, 0x08, 0xcc, 0xfc, 0x61, + 0x2e, 0x29, 0x7b, 0x49, 0x04, 0xf4, 0xfe, 0x30, 0xc0, 0x59, 0xe7, 0xc5, 0x87, 0xb0, 0xef, 0x87, + 0xf1, 0x75, 0x9f, 0x04, 0x9d, 0xc1, 0x79, 0xbf, 0xf7, 0x31, 0xe8, 0xa2, 0x17, 0xf8, 0x25, 0x38, + 0x7e, 0x18, 0xfb, 0xc1, 0x79, 0xaf, 0x8f, 0x0c, 0xfc, 0x15, 0xb8, 0x7e, 0x18, 0x77, 0x06, 0x97, + 0x97, 0xbd, 0x08, 0x95, 0xf0, 0x3e, 0x54, 0xfd, 0x30, 0x26, 0x83, 0x30, 0xf4, 0xcf, 0x3a, 0x17, + 0xc8, 0xc4, 0xaf, 0xe0, 0xc0, 0x0f, 0xe3, 0xee, 0x65, 0x18, 0x77, 0x83, 0x2b, 0x12, 0x74, 0xce, + 0xa2, 0xa0, 0x8b, 0x2c, 0x0c, 0x60, 0x8b, 0xe3, 0x6e, 0x88, 0xca, 0x1a, 0x0f, 0x83, 0x08, 0xd9, + 0x3a, 0x5d, 0xaf, 0x3f, 0x0c, 0x48, 0x84, 0x2a, 0xda, 0xbc, 0xbe, 0xea, 0x9e, 0x45, 0x01, 0x72, + 0xb4, 0xd9, 0x0d, 0xc2, 0x20, 0x0a, 0x90, 0xfb, 0xce, 0x72, 0x4a, 0xc8, 0x7c, 0x67, 0x39, 0x26, + 0xb2, 0xbc, 0xdf, 0x0d, 0x78, 0x35, 0xe4, 0x19, 0x4d, 0xee, 0x2f, 0xe8, 0x8a, 0x24, 0xe9, 0x94, + 0x12, 0xfa, 0xb0, 0xa4, 0x39, 0xc7, 0x27, 0xe0, 0x2c, 0x58, 0x3e, 0x13, 0xdc, 0x49, 0x82, 0x5d, + 0x52, 0xd8, 0xb8, 0x05, 0xee, 0x1d, 0x5d, 0xc5, 0x99, 0x88, 0xd7, 0x84, 0xe1, 0x66, 0xb1, 0x90, + 0x45, 0x26, 0xe7, 0x4e, 0xa3, 0x6d, 0x7e, 0xcd, 0x7f, 0xe7, 0xd7, 0xbb, 0x81, 0xe3, 0x4f, 0x8b, + 0xca, 0x17, 0x2c, 0xcd, 0x29, 0x0e, 0x01, 0xab, 0x8b, 0x31, 0xdf, 0xcc, 0x56, 0xd6, 0x57, 0x6d, + 0x7f, 0xfd, 0xc5, 0x05, 0x20, 0x07, 0xa3, 0x4f, 0x8f, 0xbc, 0x5f, 0xe0, 0x50, 0xbd, 0x13, 0x25, + 0xa3, 0x39, 0xcd, 0x9f, 0xd3, 0xfa, 0x31, 0xd8, 0x5c, 0x06, 0xd7, 0x4a, 0x75, 0xb3, 0xe1, 0x12, + 0x6d, 0xfd, 0xd7, 0x0e, 0x27, 0x70, 0xb4, 0xfb, 0xf2, 0xff, 0xd2, 0xdf, 0xf7, 0x60, 0x91, 0xe5, + 0x9c, 0xe2, 0x23, 0x28, 0xdf, 0x27, 0x7c, 0x7c, 0xab, 0xbb, 0x51, 0x86, 0x68, 0xe5, 0x66, 0x36, + 0xe7, 0x34, 0x93, 0x23, 0x74, 0x89, 0xb6, 0xbc, 0x37, 0x60, 0xff, 0x24, 0x11, 0xfe, 0x06, 0xca, + 0xd9, 0x52, 0xf4, 0xaa, 0x3e, 0x75, 0xb4, 0x5d, 0x80, 0x48, 0x4c, 0x94, 0xdb, 0xfb, 0xdb, 0x80, + 0x97, 0xaa, 0xa0, 0x21, 0x5b, 0x66, 0x63, 0x2a, 0x18, 0xbc, 0xa3, 0xab, 0x7c, 0x91, 0x8c, 0xe9, + 0x9a, 0xc1, 0xb5, 0x2d, 0x8a, 0xc9, 0x6f, 0x93, 0x6c, 0xa2, 0x5f, 0x55, 0x06, 0xfe, 0x01, 0xaa, + 0x92, 0x49, 0x1e, 0xf3, 0xd5, 0x82, 0x4a, 0x0e, 0xf7, 0xda, 0x47, 0x9b, 0xa5, 0x92, 0x3c, 0xf1, + 0x68, 0xb5, 0xa0, 0x04, 0x78, 0x81, 0x77, 0x37, 0xd1, 0x7a, 0xc6, 0x26, 0x6e, 0xe6, 0x57, 0xde, + 0x99, 0xdf, 0x69, 0x41, 0x86, 0xad, 0xb3, 0x6c, 0xf5, 0xaa, 0xe8, 0x28, 0x08, 0xba, 0x02, 0x87, + 0xb0, 0x27, 0x29, 0x53, 0xd8, 0x03, 0x7b, 0x44, 0x6f, 0x58, 0x46, 0xf5, 0x90, 0x40, 0x8b, 0x18, + 0x61, 0x4f, 0x44, 0x7b, 0x70, 0x1d, 0xca, 0xc9, 0xcd, 0x9a, 0xe7, 0xdd, 0x10, 0xe5, 0xf0, 0x7e, + 0x33, 0xc0, 0x7e, 0xaf, 0x12, 0x9e, 0x82, 0x25, 0x19, 0x50, 0xa2, 0x76, 0xbc, 0x5d, 0x86, 0x8a, + 0x90, 0x1c, 0xc8, 0x18, 0xa1, 0xe8, 0x53, 0x3e, 0x5b, 0x33, 0x29, 0xb1, 0xd0, 0xa6, 0xc9, 0x44, + 0x69, 0x93, 0x4b, 0x04, 0xc4, 0x6f, 0x01, 0x32, 0xf6, 0x14, 0x4b, 0x29, 0xcd, 0x6b, 0x96, 0x1c, + 0xe5, 0xd1, 0xce, 0x28, 0x75, 0x33, 0xc4, 0xcd, 0x34, 0xca, 0xbd, 0x9f, 0x61, 0xef, 0xbd, 0xda, + 0xd0, 0xe7, 0x7c, 0x15, 0xa7, 0x3b, 0xab, 0xf4, 0x65, 0xf6, 0x7e, 0x84, 0xfd, 0x22, 0xb3, 0xde, + 0xfa, 0x06, 0x94, 0x65, 0x75, 0x7a, 0xcf, 0xf0, 0xe7, 0x4d, 0x13, 0x15, 0x70, 0xfa, 0xab, 0x01, + 0xb0, 0xa1, 0x01, 0x57, 0xa1, 0x72, 0xdd, 0xbf, 0xe8, 0x0f, 0x3e, 0xf4, 0xd1, 0x0b, 0xec, 0x80, + 0x75, 0x1e, 0xf5, 0xba, 0xc8, 0xc0, 0x2e, 0x94, 0x95, 0xd0, 0x96, 0x84, 0x4a, 0x6a, 0x95, 0x35, + 0x85, 0x04, 0x17, 0x12, 0x6b, 0xe1, 0x0a, 0x98, 0x85, 0x90, 0x6a, 0xe5, 0xb4, 0x05, 0xd6, 0xb2, + 0x59, 0x11, 0x58, 0x6b, 0xa6, 0x23, 0x82, 0x85, 0xd2, 0xba, 0x02, 0x90, 0xc1, 0x07, 0x04, 0xfe, + 0xb7, 0x1f, 0x5f, 0x3f, 0xce, 0x38, 0xcd, 0xf3, 0xe6, 0x8c, 0xb5, 0x14, 0x6a, 0x4d, 0x59, 0xeb, + 0x91, 0xb7, 0xe4, 0x0f, 0xb9, 0xb5, 0x69, 0x61, 0x64, 0xcb, 0x93, 0xb7, 0xff, 0x04, 0x00, 0x00, + 0xff, 0xff, 0x70, 0xe7, 0x5c, 0xa7, 0xdf, 0x07, 0x00, 0x00, } diff --git a/go/vt/vttablet/tabletserver/tabletserver.go b/go/vt/vttablet/tabletserver/tabletserver.go index e698969816e..3de0ad5aa79 100644 --- a/go/vt/vttablet/tabletserver/tabletserver.go +++ b/go/vt/vttablet/tabletserver/tabletserver.go @@ -46,6 +46,7 @@ import ( "vitess.io/vitess/go/vt/log" "vitess.io/vitess/go/vt/logutil" "vitess.io/vitess/go/vt/sqlparser" + "vitess.io/vitess/go/vt/srvtopo" "vitess.io/vitess/go/vt/tableacl" "vitess.io/vitess/go/vt/topo" "vitess.io/vitess/go/vt/vterrors" @@ -60,6 +61,7 @@ import ( "vitess.io/vitess/go/vt/vttablet/tabletserver/tabletenv" "vitess.io/vitess/go/vt/vttablet/tabletserver/txserializer" "vitess.io/vitess/go/vt/vttablet/tabletserver/txthrottler" + "vitess.io/vitess/go/vt/vttablet/tabletserver/vstreamer" querypb "vitess.io/vitess/go/vt/proto/query" topodatapb "vitess.io/vitess/go/vt/proto/topodata" @@ -170,6 +172,7 @@ type TabletServer struct { hr *heartbeat.Reader messager *messager.Engine watcher *ReplicationWatcher + vstreamer *vstreamer.Engine updateStreamList *binlog.StreamList // checkMySQLThrottler is used to throttle the number of @@ -238,6 +241,7 @@ func NewTabletServer(config tabletenv.TabletConfig, topoServer *topo.Server, ali tsv.txThrottler = txthrottler.CreateTxThrottlerFromTabletConfig(topoServer) tsv.messager = messager.NewEngine(tsv, tsv.se, config) tsv.watcher = NewReplicationWatcher(tsv.se, config) + tsv.vstreamer = vstreamer.NewEngine(srvtopo.NewResilientServer(topoServer, "TabletSrvTopo"), tsv.se) tsv.updateStreamList = &binlog.StreamList{} // FIXME(alainjobart) could we move this to the Register method below? // So that vtcombo doesn't even call it once, on the first tablet. @@ -348,6 +352,7 @@ func (tsv *TabletServer) InitDBConfig(target querypb.Target, dbcfgs *dbconfigs.D tsv.hr.InitDBConfig(tsv.dbconfigs) tsv.messager.InitDBConfig(tsv.dbconfigs) tsv.watcher.InitDBConfig(tsv.dbconfigs) + tsv.vstreamer.InitDBConfig(tsv.dbconfigs) return nil } @@ -513,6 +518,7 @@ func (tsv *TabletServer) fullStart() (err error) { } tsv.hr.Init(tsv.target) tsv.updateStreamList.Init() + tsv.vstreamer.Open(tsv.target.Keyspace, tsv.alias.Cell) return tsv.serveNewType() } @@ -577,6 +583,7 @@ func (tsv *TabletServer) StopService() { tsv.se.Close() tsv.hw.Close() tsv.hr.Close() + tsv.vstreamer.Close() log.Infof("Shutdown complete.") tsv.transition(StateNotConnected) } diff --git a/go/vt/vttablet/tabletserver/vstreamer/engine.go b/go/vt/vttablet/tabletserver/vstreamer/engine.go index 50dc5e4a4df..8e2b057ed41 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/engine.go +++ b/go/vt/vttablet/tabletserver/vstreamer/engine.go @@ -23,6 +23,7 @@ import ( "vitess.io/vitess/go/mysql" "vitess.io/vitess/go/stats" + "vitess.io/vitess/go/vt/dbconfigs" "vitess.io/vitess/go/vt/log" "vitess.io/vitess/go/vt/srvtopo" "vitess.io/vitess/go/vt/topo" @@ -37,6 +38,9 @@ var vschemaErrors *stats.Counter // Engine is the engine for handling vseplication streaming requests. type Engine struct { + // cp is initialized by InitDBConfig + cp *mysql.ConnParams + // mu protects isOpen, streamers, streamIdx and kschema. mu sync.Mutex @@ -69,6 +73,11 @@ func NewEngine(ts srvtopo.Server, se *schema.Engine) *Engine { } } +// InitDBConfig performs saves the required info from dbconfigs for future use. +func (vse *Engine) InitDBConfig(dbcfgs *dbconfigs.DBConfigs) { + vse.cp = dbcfgs.DbaWithDB() +} + // Open starts the Engine service. func (vse *Engine) Open(keyspace, cell string) error { vse.mu.Lock() @@ -103,7 +112,7 @@ func (vse *Engine) Close() { } // Stream starts a new stream. -func (vse *Engine) Stream(ctx context.Context, cp *mysql.ConnParams, startPos mysql.Position, filter *binlogdatapb.Filter, send func(*binlogdatapb.VEvent) error) error { +func (vse *Engine) Stream(ctx context.Context, startPos mysql.Position, filter *binlogdatapb.Filter, send func(*binlogdatapb.VEvent) error) error { // Ensure kschema is initialized and the watcher is started. vse.watcherOnce.Do(vse.setWatch) @@ -114,7 +123,7 @@ func (vse *Engine) Stream(ctx context.Context, cp *mysql.ConnParams, startPos my if !vse.isOpen { return nil, 0, errors.New("VStreamer is not open") } - streamer := newVStreamer(ctx, cp, vse.se, startPos, filter, vse.kschema, send) + streamer := newVStreamer(ctx, vse.cp, vse.se, startPos, filter, vse.kschema, send) idx := vse.streamIdx vse.streamers[idx] = streamer vse.streamIdx++ diff --git a/go/vt/vttablet/tabletserver/vstreamer/planbuilder.go b/go/vt/vttablet/tabletserver/vstreamer/planbuilder.go index 24ccbd40f08..f4c9f6c6c24 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/planbuilder.go +++ b/go/vt/vttablet/tabletserver/vstreamer/planbuilder.go @@ -93,6 +93,8 @@ func (plan *Plan) filter(values []sqltypes.Value) (bool, []sqltypes.Value, error if plan.Vindex == nil { return true, result, nil } + + // Filter by Vindex. destinations, err := plan.Vindex.Map(nil, []sqltypes.Value{result[plan.VindexColumn]}) if err != nil { return false, nil, err @@ -154,6 +156,8 @@ func buildREPlan(ti *Table, kschema *vindexes.KeyspaceSchema, filter string) (*P if len(table.ColumnVindexes) == 0 { return nil, fmt.Errorf("table %s has no primary vindex", ti.Name) } + // findColumn can be used here because result column list is same + // as source. colnum, err := findColumn(ti, table.ColumnVindexes[0].Columns[0]) if err != nil { return nil, err @@ -208,11 +212,22 @@ func buildTablePlan(ti *Table, kschema *vindexes.KeyspaceSchema, query string) ( } plan.ColExprs = append(plan.ColExprs, cExpr) } + } else { + if len(sel.SelectExprs) != 1 { + return nil, fmt.Errorf("unexpected: %v", sqlparser.String(sel)) + } + plan.ColExprs = make([]ColExpr, len(ti.Columns)) + for i, col := range ti.Columns { + plan.ColExprs[i].ColNum = i + plan.ColExprs[i].Alias = col.Name + } } if sel.Where == nil { return plan, nil } + + // Filter by Vindex. funcExpr, ok := sel.Where.Expr.(*sqlparser.FuncExpr) if !ok { return nil, fmt.Errorf("unexpected where clause: %v", sqlparser.String(sel.Where)) diff --git a/go/vt/vttablet/tabletserver/vstreamer/streamer.go b/go/vt/vttablet/tabletserver/vstreamer/streamer.go index f31ebe4b72a..d2291a5a5ef 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/streamer.go +++ b/go/vt/vttablet/tabletserver/vstreamer/streamer.go @@ -136,11 +136,17 @@ func (vs *vstreamer) parseEvents(ctx context.Context, events <-chan mysql.Binlog if !ok { return fmt.Errorf("server EOF") } - if err := vs.parseEvent(ev); err != nil { + vevents, err := vs.parseEvent(ev) + if err != nil { return err } + for _, vevent := range vevents { + if err := vs.send(vevent); err != nil { + return fmt.Errorf("error sending event: %v", err) + } + } case vs.kschema = <-vs.kevents: - if err := vs.updatePlans(); err != nil { + if err := vs.rebuildPlans(); err != nil { return err } case <-ctx.Done(): @@ -149,10 +155,10 @@ func (vs *vstreamer) parseEvents(ctx context.Context, events <-chan mysql.Binlog } } -func (vs *vstreamer) parseEvent(ev mysql.BinlogEvent) error { +func (vs *vstreamer) parseEvent(ev mysql.BinlogEvent) ([]*binlogdatapb.VEvent, error) { // Validate the buffer before reading fields from it. if !ev.IsValid() { - return fmt.Errorf("can't parse binlog event: invalid data: %#v", ev) + return nil, fmt.Errorf("can't parse binlog event: invalid data: %#v", ev) } // We need to keep checking for FORMAT_DESCRIPTION_EVENT even after we've @@ -162,9 +168,9 @@ func (vs *vstreamer) parseEvent(ev mysql.BinlogEvent) error { var err error vs.format, err = ev.Format() if err != nil { - return fmt.Errorf("can't parse FORMAT_DESCRIPTION_EVENT: %v, event data: %#v", err, ev) + return nil, fmt.Errorf("can't parse FORMAT_DESCRIPTION_EVENT: %v, event data: %#v", err, ev) } - return nil + return nil, nil } // We can't parse anything until we get a FORMAT_DESCRIPTION_EVENT that @@ -174,82 +180,70 @@ func (vs *vstreamer) parseEvent(ev mysql.BinlogEvent) error { // is a fake ROTATE_EVENT, which the master sends to tell us the name // of the current log file. if ev.IsRotate() { - return nil + return nil, nil } - return fmt.Errorf("got a real event before FORMAT_DESCRIPTION_EVENT: %#v", ev) + return nil, fmt.Errorf("got a real event before FORMAT_DESCRIPTION_EVENT: %#v", ev) } // Strip the checksum, if any. We don't actually verify the checksum, so discard it. ev, _, err := ev.StripChecksum(vs.format) if err != nil { - return fmt.Errorf("can't strip checksum from binlog event: %v, event data: %#v", err, ev) + return nil, fmt.Errorf("can't strip checksum from binlog event: %v, event data: %#v", err, ev) } + var vevents []*binlogdatapb.VEvent switch { case ev.IsPseudo() || ev.IsGTID(): gtid, hasBegin, err := ev.GTID(vs.format) if err != nil { - return fmt.Errorf("can't get GTID from binlog event: %v, event data: %#v", err, ev) - } - vs.pos = mysql.AppendGTID(vs.pos, gtid) - vevent := &binlogdatapb.VEvent{ - Type: binlogdatapb.VEventType_GTID, - Gtid: mysql.EncodePosition(vs.pos), - } - if err := vs.send(vevent); err != nil { - return fmt.Errorf("error sending GTID: %v", err) + return nil, fmt.Errorf("can't get GTID from binlog event: %v, event data: %#v", err, ev) } if hasBegin { - vevent := &binlogdatapb.VEvent{ + vevents = append(vevents, &binlogdatapb.VEvent{ Type: binlogdatapb.VEventType_BEGIN, - } - if err := vs.send(vevent); err != nil { - return fmt.Errorf("error sending BEGIN: %v", err) - } + }) } + vs.pos = mysql.AppendGTID(vs.pos, gtid) + vevents = append(vevents, &binlogdatapb.VEvent{ + Type: binlogdatapb.VEventType_GTID, + Gtid: mysql.EncodePosition(vs.pos), + }) case ev.IsXID(): - vevent := &binlogdatapb.VEvent{ + vevents = append(vevents, &binlogdatapb.VEvent{ Type: binlogdatapb.VEventType_COMMIT, - } - if err := vs.send(vevent); err != nil { - return fmt.Errorf("error sending COMMIT: %v", err) - } + }) case ev.IsQuery(): q, err := ev.Query(vs.format) if err != nil { - return fmt.Errorf("can't get query from binlog event: %v, event data: %#v", err, ev) + return nil, fmt.Errorf("can't get query from binlog event: %v, event data: %#v", err, ev) } - var vevent *binlogdatapb.VEvent switch cat := getStatementCategory(q.SQL); cat { case binlogdatapb.VEventType_BEGIN, binlogdatapb.VEventType_COMMIT, binlogdatapb.VEventType_ROLLBACK: - vevent = &binlogdatapb.VEvent{ + vevents = append(vevents, &binlogdatapb.VEvent{ Type: cat, - } + }) case binlogdatapb.VEventType_DDL: - vevent = &binlogdatapb.VEvent{ + vevents = append(vevents, &binlogdatapb.VEvent{ Type: cat, Ddl: q.SQL, - } + }) default: - return fmt.Errorf("unexpected event type %v in row-based replication: %#v", cat, ev) - } - if err := vs.send(vevent); err != nil { - return fmt.Errorf("error sending COMMIT: %v", err) + return nil, fmt.Errorf("unexpected event type %v in row-based replication: %#v", cat, ev) } case ev.IsTableMap(): id := ev.TableID(vs.format) tm, err := ev.TableMap(vs.format) if err != nil { - return err + return nil, err } if tm.Database != "" && tm.Database != vs.cp.DbName { - return nil + return nil, nil } ti := vs.se.GetTable(sqlparser.NewTableIdent(tm.Name)) if ti == nil { - return fmt.Errorf("unknown table %v in schema", tm.Name) + return nil, fmt.Errorf("unknown table %v in schema", tm.Name) } if len(ti.Columns) < len(tm.Types) { - return fmt.Errorf("cannot determine table columns for %s: event has %d columns, current schema has %d: %#v", tm.Name, len(tm.Types), len(ti.Columns), ev) + 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(ti.Columns), ev) } table := &Table{ TableMap: tm, @@ -257,88 +251,35 @@ func (vs *vstreamer) parseEvent(ev mysql.BinlogEvent) error { } plan, err := buildPlan(table, vs.kschema, vs.filter) if err != nil { - return err + return nil, err } if plan != nil { vs.plans[id] = plan } - case ev.IsWriteRows(): + case ev.IsWriteRows() || ev.IsDeleteRows() || ev.IsUpdateRows(): + // The existence of before and after images can be used to + // identify statememt types. It's also possible that the + // before and after images end up going to different shards. + // If so, an update will be treated as delete on one shard + // and insert on the other. id := ev.TableID(vs.format) plan, ok := vs.plans[id] if !ok { - return nil + return nil, nil } rows, err := ev.Rows(vs.format, plan.Table.TableMap) if err != nil { - return err - } - rowEvents := make([]*binlogdatapb.RowEvent, 0, len(rows.Rows)) - for _, row := range rows.Rows { - ok, values, err := vs.extractRowAndFilter(plan, row.Data, rows.DataColumns, row.NullColumns) - if err != nil { - return err - } - if !ok { - continue - } - encoded := sqltypes.RowToProto3(values) - rowEvents = append(rowEvents, &binlogdatapb.RowEvent{After: encoded}) - } - vevent := &binlogdatapb.VEvent{ - Type: binlogdatapb.VEventType_INSERT, - RowEvents: rowEvents, - } - if err := vs.send(vevent); err != nil { - return fmt.Errorf("error sending INSERT: %v", err) - } - case ev.IsDeleteRows(): - id := ev.TableID(vs.format) - plan, ok := vs.plans[id] - if !ok { - return nil - } - rows, err := ev.Rows(vs.format, plan.Table.TableMap) - if err != nil { - return err - } - rowEvents := make([]*binlogdatapb.RowEvent, 0, len(rows.Rows)) - for _, row := range rows.Rows { - ok, values, err := vs.extractRowAndFilter(plan, row.Identify, rows.IdentifyColumns, row.NullIdentifyColumns) - if err != nil { - return err - } - if !ok { - continue - } - encoded := sqltypes.RowToProto3(values) - rowEvents = append(rowEvents, &binlogdatapb.RowEvent{Before: encoded}) - } - vevent := &binlogdatapb.VEvent{ - Type: binlogdatapb.VEventType_DELETE, - RowEvents: rowEvents, - } - if err := vs.send(vevent); err != nil { - return fmt.Errorf("error sending DELETE: %v", err) - } - case ev.IsUpdateRows(): - id := ev.TableID(vs.format) - plan, ok := vs.plans[id] - if !ok { - return nil - } - rows, err := ev.Rows(vs.format, plan.Table.TableMap) - if err != nil { - return err + return nil, err } rowEvents := make([]*binlogdatapb.RowEvent, 0, len(rows.Rows)) for _, row := range rows.Rows { beforeOK, beforeValues, err := vs.extractRowAndFilter(plan, row.Identify, rows.IdentifyColumns, row.NullIdentifyColumns) if err != nil { - return err + return nil, err } afterOK, afterValues, err := vs.extractRowAndFilter(plan, row.Data, rows.DataColumns, row.NullColumns) if err != nil { - return err + return nil, err } if !beforeOK && !afterOK { continue @@ -352,18 +293,15 @@ func (vs *vstreamer) parseEvent(ev mysql.BinlogEvent) error { } rowEvents = append(rowEvents, rowEvent) } - vevent := &binlogdatapb.VEvent{ - Type: binlogdatapb.VEventType_UPDATE, + vevents = append(vevents, &binlogdatapb.VEvent{ + Type: binlogdatapb.VEventType_ROW, RowEvents: rowEvents, - } - if err := vs.send(vevent); err != nil { - return fmt.Errorf("error sending UPDATE: %v", err) - } + }) } - return nil + return vevents, nil } -func (vs *vstreamer) updatePlans() error { +func (vs *vstreamer) rebuildPlans() error { for id, plan := range vs.plans { newPlan, err := buildPlan(plan.Table, vs.kschema, vs.filter) if err != nil { @@ -375,12 +313,15 @@ func (vs *vstreamer) updatePlans() error { } func (vs *vstreamer) extractRowAndFilter(plan *Plan, data []byte, dataColumns, nullColumns mysql.Bitmap) (bool, []sqltypes.Value, error) { + if len(data) == 0 { + return false, nil, nil + } values := make([]sqltypes.Value, dataColumns.Count()) valueIndex := 0 pos := 0 for colNum := 0; colNum < dataColumns.Count(); colNum++ { if !dataColumns.Bit(colNum) { - continue + return false, nil, fmt.Errorf("partial row image encountered: ensure binlog_row_image is set to 'full'") } if nullColumns.Bit(valueIndex) { valueIndex++ diff --git a/proto/binlogdata.proto b/proto/binlogdata.proto index 1a2ab445094..b75d94fa031 100644 --- a/proto/binlogdata.proto +++ b/proto/binlogdata.proto @@ -156,6 +156,8 @@ message BinlogSource { } // VEventType enumerates the event types. +// This list is comprehensive. Many of these types +// will not be encountered in RBR mode. enum VEventType { UNKNOWN = 0; GTID = 1; @@ -167,6 +169,7 @@ enum VEventType { UPDATE = 7; DELETE = 8; SET = 9; + ROW = 10; } message RowEvent { diff --git a/py/vtproto/binlogdata_pb2.py b/py/vtproto/binlogdata_pb2.py index b9c3737957c..e3d91c969f6 100644 --- a/py/vtproto/binlogdata_pb2.py +++ b/py/vtproto/binlogdata_pb2.py @@ -22,7 +22,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\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\"\xb5\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\"A\n\x08RowEvent\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\"s\n\x06VEvent\x12$\n\x04type\x18\x01 \x01(\x0e\x32\x16.binlogdata.VEventType\x12\x0c\n\x04gtid\x18\x02 \x01(\t\x12\x0b\n\x03\x64\x64l\x18\x03 \x01(\t\x12(\n\nrow_events\x18\x04 \x03(\x0b\x32\x14.binlogdata.RowEvent\"F\n\x0eVStreamRequest\x12\x10\n\x08position\x18\x01 \x01(\t\x12\"\n\x06\x66ilter\x18\x02 \x01(\x0b\x32\x12.binlogdata.Filter\"4\n\x0fVStreamResponse\x12!\n\x05\x65vent\x18\x01 \x03(\x0b\x32\x12.binlogdata.VEvent*~\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\n\n\x06UPDATE\x10\x07\x12\n\n\x06\x44\x45LETE\x10\x08\x12\x07\n\x03SET\x10\tB)Z\'vitess.io/vitess/go/vt/proto/binlogdatab\x06proto3') + serialized_pb=_b('\n\x10\x62inlogdata.proto\x12\nbinlogdata\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\"\xb5\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\"A\n\x08RowEvent\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\"s\n\x06VEvent\x12$\n\x04type\x18\x01 \x01(\x0e\x32\x16.binlogdata.VEventType\x12\x0c\n\x04gtid\x18\x02 \x01(\t\x12\x0b\n\x03\x64\x64l\x18\x03 \x01(\t\x12(\n\nrow_events\x18\x04 \x03(\x0b\x32\x14.binlogdata.RowEvent\"F\n\x0eVStreamRequest\x12\x10\n\x08position\x18\x01 \x01(\t\x12\"\n\x06\x66ilter\x18\x02 \x01(\x0b\x32\x12.binlogdata.Filter\"4\n\x0fVStreamResponse\x12!\n\x05\x65vent\x18\x01 \x03(\x0b\x32\x12.binlogdata.VEvent*\x87\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\n\n\x06UPDATE\x10\x07\x12\n\n\x06\x44\x45LETE\x10\x08\x12\x07\n\x03SET\x10\t\x12\x07\n\x03ROW\x10\nB)Z\'vitess.io/vitess/go/vt/proto/binlogdatab\x06proto3') , dependencies=[query__pb2.DESCRIPTOR,topodata__pb2.DESCRIPTOR,]) @@ -72,11 +72,15 @@ name='SET', index=9, number=9, serialized_options=None, type=None), + _descriptor.EnumValueDescriptor( + name='ROW', index=10, number=10, + serialized_options=None, + type=None), ], containing_type=None, serialized_options=None, - serialized_start=1517, - serialized_end=1643, + serialized_start=1518, + serialized_end=1653, ) _sym_db.RegisterEnumDescriptor(_VEVENTTYPE) @@ -91,6 +95,7 @@ UPDATE = 7 DELETE = 8 SET = 9 +ROW = 10 _BINLOGTRANSACTION_STATEMENT_CATEGORY = _descriptor.EnumDescriptor( From a0b948974f7974d2bce03e549c52a81165d22f42 Mon Sep 17 00:00:00 2001 From: Sugu Sougoumarane Date: Sun, 30 Dec 2018 18:27:09 -0800 Subject: [PATCH 021/115] vreplication: got some basic tests working Signed-off-by: Sugu Sougoumarane --- go/vt/proto/binlogdata/binlogdata.pb.go | 267 +++++++++++------- go/vt/sqlparser/analyzer.go | 1 + go/vt/vttablet/endtoend/framework/server.go | 52 +++- go/vt/vttablet/tabletserver/tabletserver.go | 35 +++ .../vstreamer/endtoend/main_test.go | 131 +++++++++ .../vstreamer/endtoend/vstreamer_test.go | 171 +++++++++++ .../vttablet/tabletserver/vstreamer/engine.go | 3 +- .../vstreamer/{streamer.go => vstreamer.go} | 142 +++++++--- proto/binlogdata.proto | 21 +- py/vtproto/binlogdata_pb2.py | 115 ++++++-- 10 files changed, 736 insertions(+), 202 deletions(-) create mode 100644 go/vt/vttablet/tabletserver/vstreamer/endtoend/main_test.go create mode 100644 go/vt/vttablet/tabletserver/vstreamer/endtoend/vstreamer_test.go rename go/vt/vttablet/tabletserver/vstreamer/{streamer.go => vstreamer.go} (70%) diff --git a/go/vt/proto/binlogdata/binlogdata.pb.go b/go/vt/proto/binlogdata/binlogdata.pb.go index ecfbf2ee435..de20633f792 100644 --- a/go/vt/proto/binlogdata/binlogdata.pb.go +++ b/go/vt/proto/binlogdata/binlogdata.pb.go @@ -33,10 +33,12 @@ const ( VEventType_ROLLBACK VEventType = 4 VEventType_DDL VEventType = 5 VEventType_INSERT VEventType = 6 - VEventType_UPDATE VEventType = 7 - VEventType_DELETE VEventType = 8 - VEventType_SET VEventType = 9 - VEventType_ROW VEventType = 10 + VEventType_REPLACE VEventType = 7 + VEventType_UPDATE VEventType = 8 + VEventType_DELETE VEventType = 9 + VEventType_SET VEventType = 10 + VEventType_OTHER VEventType = 11 + VEventType_ROW VEventType = 12 ) var VEventType_name = map[int32]string{ @@ -47,10 +49,12 @@ var VEventType_name = map[int32]string{ 4: "ROLLBACK", 5: "DDL", 6: "INSERT", - 7: "UPDATE", - 8: "DELETE", - 9: "SET", - 10: "ROW", + 7: "REPLACE", + 8: "UPDATE", + 9: "DELETE", + 10: "SET", + 11: "OTHER", + 12: "ROW", } var VEventType_value = map[string]int32{ "UNKNOWN": 0, @@ -60,17 +64,19 @@ var VEventType_value = map[string]int32{ "ROLLBACK": 4, "DDL": 5, "INSERT": 6, - "UPDATE": 7, - "DELETE": 8, - "SET": 9, - "ROW": 10, + "REPLACE": 7, + "UPDATE": 8, + "DELETE": 9, + "SET": 10, + "OTHER": 11, + "ROW": 12, } func (x VEventType) String() string { return proto.EnumName(VEventType_name, int32(x)) } func (VEventType) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_binlogdata_41dfc977aeca6f81, []int{0} + return fileDescriptor_binlogdata_8c20ffb2cc31e3c4, []int{0} } type BinlogTransaction_Statement_Category int32 @@ -118,7 +124,7 @@ 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_41dfc977aeca6f81, []int{1, 0, 0} + return fileDescriptor_binlogdata_8c20ffb2cc31e3c4, []int{1, 0, 0} } // Charset is the per-statement charset info from a QUERY_EVENT binlog entry. @@ -138,7 +144,7 @@ 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_41dfc977aeca6f81, []int{0} + return fileDescriptor_binlogdata_8c20ffb2cc31e3c4, []int{0} } func (m *Charset) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Charset.Unmarshal(m, b) @@ -195,7 +201,7 @@ 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_41dfc977aeca6f81, []int{1} + return fileDescriptor_binlogdata_8c20ffb2cc31e3c4, []int{1} } func (m *BinlogTransaction) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_BinlogTransaction.Unmarshal(m, b) @@ -245,7 +251,7 @@ 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_41dfc977aeca6f81, []int{1, 0} + return fileDescriptor_binlogdata_8c20ffb2cc31e3c4, []int{1, 0} } func (m *BinlogTransaction_Statement) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_BinlogTransaction_Statement.Unmarshal(m, b) @@ -303,7 +309,7 @@ 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_41dfc977aeca6f81, []int{2} + return fileDescriptor_binlogdata_8c20ffb2cc31e3c4, []int{2} } func (m *StreamKeyRangeRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_StreamKeyRangeRequest.Unmarshal(m, b) @@ -356,7 +362,7 @@ 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_41dfc977aeca6f81, []int{3} + return fileDescriptor_binlogdata_8c20ffb2cc31e3c4, []int{3} } func (m *StreamKeyRangeResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_StreamKeyRangeResponse.Unmarshal(m, b) @@ -400,7 +406,7 @@ 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_41dfc977aeca6f81, []int{4} + return fileDescriptor_binlogdata_8c20ffb2cc31e3c4, []int{4} } func (m *StreamTablesRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_StreamTablesRequest.Unmarshal(m, b) @@ -453,7 +459,7 @@ 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_41dfc977aeca6f81, []int{5} + return fileDescriptor_binlogdata_8c20ffb2cc31e3c4, []int{5} } func (m *StreamTablesResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_StreamTablesResponse.Unmarshal(m, b) @@ -498,7 +504,7 @@ 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_41dfc977aeca6f81, []int{6} + return fileDescriptor_binlogdata_8c20ffb2cc31e3c4, []int{6} } func (m *Rule) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Rule.Unmarshal(m, b) @@ -545,7 +551,7 @@ 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_41dfc977aeca6f81, []int{7} + return fileDescriptor_binlogdata_8c20ffb2cc31e3c4, []int{7} } func (m *Filter) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Filter.Unmarshal(m, b) @@ -598,7 +604,7 @@ 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_41dfc977aeca6f81, []int{8} + return fileDescriptor_binlogdata_8c20ffb2cc31e3c4, []int{8} } func (m *BinlogSource) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_BinlogSource.Unmarshal(m, b) @@ -660,7 +666,8 @@ func (m *BinlogSource) GetFilter() *Filter { return nil } -type RowEvent struct { +// RowChange represents one row change +type RowChange struct { Before *query.Row `protobuf:"bytes,1,opt,name=before,proto3" json:"before,omitempty"` After *query.Row `protobuf:"bytes,2,opt,name=after,proto3" json:"after,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` @@ -668,11 +675,58 @@ type RowEvent struct { XXX_sizecache int32 `json:"-"` } +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_8c20ffb2cc31e3c4, []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_Size() int { + return xxx_messageInfo_RowChange.Size(m) +} +func (m *RowChange) XXX_DiscardUnknown() { + xxx_messageInfo_RowChange.DiscardUnknown(m) +} + +var xxx_messageInfo_RowChange proto.InternalMessageInfo + +func (m *RowChange) GetBefore() *query.Row { + if m != nil { + return m.Before + } + return nil +} + +func (m *RowChange) GetAfter() *query.Row { + if m != nil { + return m.After + } + return nil +} + +// RowEvent represent row events for one table +type RowEvent struct { + TableName string `protobuf:"bytes,1,opt,name=table_name,json=tableName,proto3" json:"table_name,omitempty"` + RowChanges []*RowChange `protobuf:"bytes,2,rep,name=row_changes,json=rowChanges,proto3" json:"row_changes,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + 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_41dfc977aeca6f81, []int{9} + return fileDescriptor_binlogdata_8c20ffb2cc31e3c4, []int{10} } func (m *RowEvent) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_RowEvent.Unmarshal(m, b) @@ -692,36 +746,36 @@ func (m *RowEvent) XXX_DiscardUnknown() { var xxx_messageInfo_RowEvent proto.InternalMessageInfo -func (m *RowEvent) GetBefore() *query.Row { +func (m *RowEvent) GetTableName() string { if m != nil { - return m.Before + return m.TableName } - return nil + return "" } -func (m *RowEvent) GetAfter() *query.Row { +func (m *RowEvent) GetRowChanges() []*RowChange { if m != nil { - return m.After + return m.RowChanges } return nil } // VEvent represents a vstream event type VEvent struct { - Type VEventType `protobuf:"varint,1,opt,name=type,proto3,enum=binlogdata.VEventType" json:"type,omitempty"` - Gtid string `protobuf:"bytes,2,opt,name=gtid,proto3" json:"gtid,omitempty"` - Ddl string `protobuf:"bytes,3,opt,name=ddl,proto3" json:"ddl,omitempty"` - RowEvents []*RowEvent `protobuf:"bytes,4,rep,name=row_events,json=rowEvents,proto3" json:"row_events,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + Type VEventType `protobuf:"varint,1,opt,name=type,proto3,enum=binlogdata.VEventType" json:"type,omitempty"` + Gtid string `protobuf:"bytes,2,opt,name=gtid,proto3" json:"gtid,omitempty"` + Ddl string `protobuf:"bytes,3,opt,name=ddl,proto3" json:"ddl,omitempty"` + RowEvent *RowEvent `protobuf:"bytes,4,opt,name=row_event,json=rowEvent,proto3" json:"row_event,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } 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_41dfc977aeca6f81, []int{10} + return fileDescriptor_binlogdata_8c20ffb2cc31e3c4, []int{11} } func (m *VEvent) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_VEvent.Unmarshal(m, b) @@ -762,9 +816,9 @@ func (m *VEvent) GetDdl() string { return "" } -func (m *VEvent) GetRowEvents() []*RowEvent { +func (m *VEvent) GetRowEvent() *RowEvent { if m != nil { - return m.RowEvents + return m.RowEvent } return nil } @@ -782,7 +836,7 @@ 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_41dfc977aeca6f81, []int{11} + return fileDescriptor_binlogdata_8c20ffb2cc31e3c4, []int{12} } func (m *VStreamRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_VStreamRequest.Unmarshal(m, b) @@ -828,7 +882,7 @@ 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_41dfc977aeca6f81, []int{12} + return fileDescriptor_binlogdata_8c20ffb2cc31e3c4, []int{13} } func (m *VStreamResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_VStreamResponse.Unmarshal(m, b) @@ -866,6 +920,7 @@ func init() { proto.RegisterType((*Rule)(nil), "binlogdata.Rule") proto.RegisterType((*Filter)(nil), "binlogdata.Filter") proto.RegisterType((*BinlogSource)(nil), "binlogdata.BinlogSource") + proto.RegisterType((*RowChange)(nil), "binlogdata.RowChange") proto.RegisterType((*RowEvent)(nil), "binlogdata.RowEvent") proto.RegisterType((*VEvent)(nil), "binlogdata.VEvent") proto.RegisterType((*VStreamRequest)(nil), "binlogdata.VStreamRequest") @@ -874,65 +929,69 @@ func init() { proto.RegisterEnum("binlogdata.BinlogTransaction_Statement_Category", BinlogTransaction_Statement_Category_name, BinlogTransaction_Statement_Category_value) } -func init() { proto.RegisterFile("binlogdata.proto", fileDescriptor_binlogdata_41dfc977aeca6f81) } - -var fileDescriptor_binlogdata_41dfc977aeca6f81 = []byte{ - // 906 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x55, 0xcd, 0x6e, 0xdb, 0x46, - 0x10, 0x0e, 0x45, 0x8a, 0x22, 0x47, 0xa9, 0xbd, 0x5e, 0x3b, 0x86, 0x60, 0xa0, 0x80, 0xc0, 0x43, - 0xa3, 0x1a, 0xa8, 0x14, 0x28, 0xed, 0xa9, 0x27, 0x53, 0x62, 0x0d, 0xc5, 0xb4, 0x64, 0xac, 0xe8, - 0xa4, 0xc8, 0x85, 0xa0, 0xa4, 0xb5, 0x2c, 0x58, 0xe6, 0xca, 0xe4, 0xca, 0xae, 0x9e, 0xa0, 0xc7, - 0x1e, 0xfa, 0x14, 0x7d, 0x91, 0xbe, 0x49, 0x6f, 0x7d, 0x88, 0x62, 0x7f, 0x44, 0x49, 0x09, 0x90, - 0xba, 0x87, 0xde, 0xbe, 0xd9, 0x99, 0x9d, 0x9d, 0xf9, 0x66, 0xf8, 0x11, 0xd0, 0x68, 0x96, 0xce, - 0xd9, 0x74, 0x92, 0xf0, 0xa4, 0xb9, 0xc8, 0x18, 0x67, 0x18, 0x36, 0x27, 0x27, 0xd5, 0x87, 0x25, - 0xcd, 0x56, 0xca, 0x71, 0xb2, 0xc7, 0xd9, 0x82, 0x6d, 0x02, 0xbd, 0x4b, 0xa8, 0x74, 0x6e, 0x93, - 0x2c, 0xa7, 0x1c, 0x1f, 0x83, 0x3d, 0x9e, 0xcf, 0x68, 0xca, 0x6b, 0x46, 0xdd, 0x68, 0x94, 0x89, - 0xb6, 0x30, 0x06, 0x6b, 0xcc, 0xd2, 0xb4, 0x56, 0x92, 0xa7, 0x12, 0x8b, 0xd8, 0x9c, 0x66, 0x8f, - 0x34, 0xab, 0x99, 0x2a, 0x56, 0x59, 0xde, 0x5f, 0x26, 0x1c, 0xf8, 0xf2, 0xe9, 0x28, 0x4b, 0xd2, - 0x3c, 0x19, 0xf3, 0x19, 0x4b, 0xf1, 0x39, 0x40, 0xce, 0x13, 0x4e, 0xef, 0x69, 0xca, 0xf3, 0x9a, - 0x51, 0x37, 0x1b, 0xd5, 0xf6, 0xeb, 0xe6, 0x56, 0xd1, 0x9f, 0x5d, 0x69, 0x0e, 0xd7, 0xf1, 0x64, - 0xeb, 0x2a, 0x6e, 0x43, 0x95, 0x3e, 0xd2, 0x94, 0xc7, 0x9c, 0xdd, 0xd1, 0xb4, 0x66, 0xd5, 0x8d, - 0x46, 0xb5, 0x7d, 0xd0, 0x54, 0x0d, 0x06, 0xc2, 0x13, 0x09, 0x07, 0x01, 0x5a, 0xe0, 0x93, 0x3f, - 0x4b, 0xe0, 0x16, 0xd9, 0x70, 0x08, 0xce, 0x38, 0xe1, 0x74, 0xca, 0xb2, 0x95, 0x6c, 0x73, 0xaf, - 0xfd, 0xe6, 0x99, 0x85, 0x34, 0x3b, 0xfa, 0x1e, 0x29, 0x32, 0xe0, 0xef, 0xa0, 0x32, 0x56, 0xec, - 0x49, 0x76, 0xaa, 0xed, 0xc3, 0xed, 0x64, 0x9a, 0x58, 0xb2, 0x8e, 0xc1, 0x08, 0xcc, 0xfc, 0x61, - 0x2e, 0x29, 0x7b, 0x49, 0x04, 0xf4, 0xfe, 0x30, 0xc0, 0x59, 0xe7, 0xc5, 0x87, 0xb0, 0xef, 0x87, - 0xf1, 0x75, 0x9f, 0x04, 0x9d, 0xc1, 0x79, 0xbf, 0xf7, 0x31, 0xe8, 0xa2, 0x17, 0xf8, 0x25, 0x38, - 0x7e, 0x18, 0xfb, 0xc1, 0x79, 0xaf, 0x8f, 0x0c, 0xfc, 0x15, 0xb8, 0x7e, 0x18, 0x77, 0x06, 0x97, - 0x97, 0xbd, 0x08, 0x95, 0xf0, 0x3e, 0x54, 0xfd, 0x30, 0x26, 0x83, 0x30, 0xf4, 0xcf, 0x3a, 0x17, - 0xc8, 0xc4, 0xaf, 0xe0, 0xc0, 0x0f, 0xe3, 0xee, 0x65, 0x18, 0x77, 0x83, 0x2b, 0x12, 0x74, 0xce, - 0xa2, 0xa0, 0x8b, 0x2c, 0x0c, 0x60, 0x8b, 0xe3, 0x6e, 0x88, 0xca, 0x1a, 0x0f, 0x83, 0x08, 0xd9, - 0x3a, 0x5d, 0xaf, 0x3f, 0x0c, 0x48, 0x84, 0x2a, 0xda, 0xbc, 0xbe, 0xea, 0x9e, 0x45, 0x01, 0x72, - 0xb4, 0xd9, 0x0d, 0xc2, 0x20, 0x0a, 0x90, 0xfb, 0xce, 0x72, 0x4a, 0xc8, 0x7c, 0x67, 0x39, 0x26, - 0xb2, 0xbc, 0xdf, 0x0d, 0x78, 0x35, 0xe4, 0x19, 0x4d, 0xee, 0x2f, 0xe8, 0x8a, 0x24, 0xe9, 0x94, - 0x12, 0xfa, 0xb0, 0xa4, 0x39, 0xc7, 0x27, 0xe0, 0x2c, 0x58, 0x3e, 0x13, 0xdc, 0x49, 0x82, 0x5d, - 0x52, 0xd8, 0xb8, 0x05, 0xee, 0x1d, 0x5d, 0xc5, 0x99, 0x88, 0xd7, 0x84, 0xe1, 0x66, 0xb1, 0x90, - 0x45, 0x26, 0xe7, 0x4e, 0xa3, 0x6d, 0x7e, 0xcd, 0x7f, 0xe7, 0xd7, 0xbb, 0x81, 0xe3, 0x4f, 0x8b, - 0xca, 0x17, 0x2c, 0xcd, 0x29, 0x0e, 0x01, 0xab, 0x8b, 0x31, 0xdf, 0xcc, 0x56, 0xd6, 0x57, 0x6d, - 0x7f, 0xfd, 0xc5, 0x05, 0x20, 0x07, 0xa3, 0x4f, 0x8f, 0xbc, 0x5f, 0xe0, 0x50, 0xbd, 0x13, 0x25, - 0xa3, 0x39, 0xcd, 0x9f, 0xd3, 0xfa, 0x31, 0xd8, 0x5c, 0x06, 0xd7, 0x4a, 0x75, 0xb3, 0xe1, 0x12, - 0x6d, 0xfd, 0xd7, 0x0e, 0x27, 0x70, 0xb4, 0xfb, 0xf2, 0xff, 0xd2, 0xdf, 0xf7, 0x60, 0x91, 0xe5, - 0x9c, 0xe2, 0x23, 0x28, 0xdf, 0x27, 0x7c, 0x7c, 0xab, 0xbb, 0x51, 0x86, 0x68, 0xe5, 0x66, 0x36, - 0xe7, 0x34, 0x93, 0x23, 0x74, 0x89, 0xb6, 0xbc, 0x37, 0x60, 0xff, 0x24, 0x11, 0xfe, 0x06, 0xca, - 0xd9, 0x52, 0xf4, 0xaa, 0x3e, 0x75, 0xb4, 0x5d, 0x80, 0x48, 0x4c, 0x94, 0xdb, 0xfb, 0xdb, 0x80, - 0x97, 0xaa, 0xa0, 0x21, 0x5b, 0x66, 0x63, 0x2a, 0x18, 0xbc, 0xa3, 0xab, 0x7c, 0x91, 0x8c, 0xe9, - 0x9a, 0xc1, 0xb5, 0x2d, 0x8a, 0xc9, 0x6f, 0x93, 0x6c, 0xa2, 0x5f, 0x55, 0x06, 0xfe, 0x01, 0xaa, - 0x92, 0x49, 0x1e, 0xf3, 0xd5, 0x82, 0x4a, 0x0e, 0xf7, 0xda, 0x47, 0x9b, 0xa5, 0x92, 0x3c, 0xf1, - 0x68, 0xb5, 0xa0, 0x04, 0x78, 0x81, 0x77, 0x37, 0xd1, 0x7a, 0xc6, 0x26, 0x6e, 0xe6, 0x57, 0xde, - 0x99, 0xdf, 0x69, 0x41, 0x86, 0xad, 0xb3, 0x6c, 0xf5, 0xaa, 0xe8, 0x28, 0x08, 0xba, 0x02, 0x87, - 0xb0, 0x27, 0x29, 0x53, 0xd8, 0x03, 0x7b, 0x44, 0x6f, 0x58, 0x46, 0xf5, 0x90, 0x40, 0x8b, 0x18, - 0x61, 0x4f, 0x44, 0x7b, 0x70, 0x1d, 0xca, 0xc9, 0xcd, 0x9a, 0xe7, 0xdd, 0x10, 0xe5, 0xf0, 0x7e, - 0x33, 0xc0, 0x7e, 0xaf, 0x12, 0x9e, 0x82, 0x25, 0x19, 0x50, 0xa2, 0x76, 0xbc, 0x5d, 0x86, 0x8a, - 0x90, 0x1c, 0xc8, 0x18, 0xa1, 0xe8, 0x53, 0x3e, 0x5b, 0x33, 0x29, 0xb1, 0xd0, 0xa6, 0xc9, 0x44, - 0x69, 0x93, 0x4b, 0x04, 0xc4, 0x6f, 0x01, 0x32, 0xf6, 0x14, 0x4b, 0x29, 0xcd, 0x6b, 0x96, 0x1c, - 0xe5, 0xd1, 0xce, 0x28, 0x75, 0x33, 0xc4, 0xcd, 0x34, 0xca, 0xbd, 0x9f, 0x61, 0xef, 0xbd, 0xda, - 0xd0, 0xe7, 0x7c, 0x15, 0xa7, 0x3b, 0xab, 0xf4, 0x65, 0xf6, 0x7e, 0x84, 0xfd, 0x22, 0xb3, 0xde, - 0xfa, 0x06, 0x94, 0x65, 0x75, 0x7a, 0xcf, 0xf0, 0xe7, 0x4d, 0x13, 0x15, 0x70, 0xfa, 0xab, 0x01, - 0xb0, 0xa1, 0x01, 0x57, 0xa1, 0x72, 0xdd, 0xbf, 0xe8, 0x0f, 0x3e, 0xf4, 0xd1, 0x0b, 0xec, 0x80, - 0x75, 0x1e, 0xf5, 0xba, 0xc8, 0xc0, 0x2e, 0x94, 0x95, 0xd0, 0x96, 0x84, 0x4a, 0x6a, 0x95, 0x35, - 0x85, 0x04, 0x17, 0x12, 0x6b, 0xe1, 0x0a, 0x98, 0x85, 0x90, 0x6a, 0xe5, 0xb4, 0x05, 0xd6, 0xb2, - 0x59, 0x11, 0x58, 0x6b, 0xa6, 0x23, 0x82, 0x85, 0xd2, 0xba, 0x02, 0x90, 0xc1, 0x07, 0x04, 0xfe, - 0xb7, 0x1f, 0x5f, 0x3f, 0xce, 0x38, 0xcd, 0xf3, 0xe6, 0x8c, 0xb5, 0x14, 0x6a, 0x4d, 0x59, 0xeb, - 0x91, 0xb7, 0xe4, 0x0f, 0xb9, 0xb5, 0x69, 0x61, 0x64, 0xcb, 0x93, 0xb7, 0xff, 0x04, 0x00, 0x00, - 0xff, 0xff, 0x70, 0xe7, 0x5c, 0xa7, 0xdf, 0x07, 0x00, 0x00, +func init() { proto.RegisterFile("binlogdata.proto", fileDescriptor_binlogdata_8c20ffb2cc31e3c4) } + +var fileDescriptor_binlogdata_8c20ffb2cc31e3c4 = []byte{ + // 964 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x56, 0xcb, 0x6e, 0xe2, 0x56, + 0x18, 0x1e, 0x63, 0x63, 0xec, 0xdf, 0x69, 0xe6, 0xe4, 0xe4, 0x22, 0x14, 0x69, 0xa4, 0xc8, 0x8b, + 0x0e, 0x8d, 0x54, 0x98, 0xd2, 0xcb, 0xa6, 0xab, 0x00, 0x6e, 0xca, 0xc4, 0x81, 0xf4, 0xe0, 0xcc, + 0x54, 0xb3, 0xb1, 0x0c, 0x9c, 0x10, 0x14, 0xb0, 0x89, 0x7d, 0x48, 0xca, 0x43, 0x74, 0xd5, 0x07, + 0xe8, 0xba, 0x2f, 0xd2, 0x37, 0xe9, 0xae, 0x0f, 0x51, 0x9d, 0x8b, 0x0d, 0x64, 0xa4, 0x69, 0xba, + 0xe8, 0xee, 0xbf, 0x9d, 0xff, 0xf2, 0xfd, 0xbf, 0x3f, 0x00, 0x34, 0x9c, 0xc6, 0xb3, 0x64, 0x32, + 0x8e, 0x58, 0x54, 0x5f, 0xa4, 0x09, 0x4b, 0x30, 0xac, 0x2d, 0xc7, 0xce, 0xfd, 0x92, 0xa6, 0x2b, + 0xe9, 0x38, 0xde, 0x65, 0xc9, 0x22, 0x59, 0x07, 0xba, 0x97, 0x50, 0x69, 0xdf, 0x46, 0x69, 0x46, + 0x19, 0x3e, 0x02, 0x73, 0x34, 0x9b, 0xd2, 0x98, 0x55, 0xb5, 0x13, 0xad, 0x56, 0x26, 0x4a, 0xc3, + 0x18, 0x8c, 0x51, 0x12, 0xc7, 0xd5, 0x92, 0xb0, 0x0a, 0x99, 0xc7, 0x66, 0x34, 0x7d, 0xa0, 0x69, + 0x55, 0x97, 0xb1, 0x52, 0x73, 0xff, 0xd2, 0x61, 0xaf, 0x25, 0x4a, 0x07, 0x69, 0x14, 0x67, 0xd1, + 0x88, 0x4d, 0x93, 0x18, 0x9f, 0x03, 0x64, 0x2c, 0x62, 0x74, 0x4e, 0x63, 0x96, 0x55, 0xb5, 0x13, + 0xbd, 0xe6, 0x34, 0x5f, 0xd7, 0x37, 0x9a, 0xfe, 0xe8, 0x49, 0x7d, 0x90, 0xc7, 0x93, 0x8d, 0xa7, + 0xb8, 0x09, 0x0e, 0x7d, 0xa0, 0x31, 0x0b, 0x59, 0x72, 0x47, 0xe3, 0xaa, 0x71, 0xa2, 0xd5, 0x9c, + 0xe6, 0x5e, 0x5d, 0x0e, 0xe8, 0x71, 0x4f, 0xc0, 0x1d, 0x04, 0x68, 0x21, 0x1f, 0xff, 0x59, 0x02, + 0xbb, 0xc8, 0x86, 0x7d, 0xb0, 0x46, 0x11, 0xa3, 0x93, 0x24, 0x5d, 0x89, 0x31, 0x77, 0x9b, 0x6f, + 0x9e, 0xd9, 0x48, 0xbd, 0xad, 0xde, 0x91, 0x22, 0x03, 0xfe, 0x12, 0x2a, 0x23, 0x89, 0x9e, 0x40, + 0xc7, 0x69, 0xee, 0x6f, 0x26, 0x53, 0xc0, 0x92, 0x3c, 0x06, 0x23, 0xd0, 0xb3, 0xfb, 0x99, 0x80, + 0x6c, 0x87, 0x70, 0xd1, 0xfd, 0x43, 0x03, 0x2b, 0xcf, 0x8b, 0xf7, 0xe1, 0x65, 0xcb, 0x0f, 0xaf, + 0x7b, 0xc4, 0x6b, 0xf7, 0xcf, 0x7b, 0xdd, 0x0f, 0x5e, 0x07, 0xbd, 0xc0, 0x3b, 0x60, 0xb5, 0xfc, + 0xb0, 0xe5, 0x9d, 0x77, 0x7b, 0x48, 0xc3, 0x9f, 0x81, 0xdd, 0xf2, 0xc3, 0x76, 0xff, 0xf2, 0xb2, + 0x1b, 0xa0, 0x12, 0x7e, 0x09, 0x4e, 0xcb, 0x0f, 0x49, 0xdf, 0xf7, 0x5b, 0x67, 0xed, 0x0b, 0xa4, + 0xe3, 0x43, 0xd8, 0x6b, 0xf9, 0x61, 0xe7, 0xd2, 0x0f, 0x3b, 0xde, 0x15, 0xf1, 0xda, 0x67, 0x81, + 0xd7, 0x41, 0x06, 0x06, 0x30, 0xb9, 0xb9, 0xe3, 0xa3, 0xb2, 0x92, 0x07, 0x5e, 0x80, 0x4c, 0x95, + 0xae, 0xdb, 0x1b, 0x78, 0x24, 0x40, 0x15, 0xa5, 0x5e, 0x5f, 0x75, 0xce, 0x02, 0x0f, 0x59, 0x4a, + 0xed, 0x78, 0xbe, 0x17, 0x78, 0xc8, 0x7e, 0x6b, 0x58, 0x25, 0xa4, 0xbf, 0x35, 0x2c, 0x1d, 0x19, + 0xee, 0x6f, 0x1a, 0x1c, 0x0e, 0x58, 0x4a, 0xa3, 0xf9, 0x05, 0x5d, 0x91, 0x28, 0x9e, 0x50, 0x42, + 0xef, 0x97, 0x34, 0x63, 0xf8, 0x18, 0xac, 0x45, 0x92, 0x4d, 0x39, 0x76, 0x02, 0x60, 0x9b, 0x14, + 0x3a, 0x6e, 0x80, 0x7d, 0x47, 0x57, 0x61, 0xca, 0xe3, 0x15, 0x60, 0xb8, 0x5e, 0x1c, 0x64, 0x91, + 0xc9, 0xba, 0x53, 0xd2, 0x26, 0xbe, 0xfa, 0xbf, 0xe3, 0xeb, 0xde, 0xc0, 0xd1, 0xd3, 0xa6, 0xb2, + 0x45, 0x12, 0x67, 0x14, 0xfb, 0x80, 0xe5, 0xc3, 0x90, 0xad, 0x77, 0x2b, 0xfa, 0x73, 0x9a, 0xaf, + 0x3e, 0x79, 0x00, 0x64, 0x6f, 0xf8, 0xd4, 0xe4, 0xfe, 0x02, 0xfb, 0xb2, 0x4e, 0x10, 0x0d, 0x67, + 0x34, 0x7b, 0xce, 0xe8, 0x47, 0x60, 0x32, 0x11, 0x5c, 0x2d, 0x9d, 0xe8, 0x35, 0x9b, 0x28, 0xed, + 0xbf, 0x4e, 0x38, 0x86, 0x83, 0xed, 0xca, 0xff, 0xcb, 0x7c, 0xdf, 0x80, 0x41, 0x96, 0x33, 0x8a, + 0x0f, 0xa0, 0x3c, 0x8f, 0xd8, 0xe8, 0x56, 0x4d, 0x23, 0x15, 0x3e, 0xca, 0xcd, 0x74, 0xc6, 0x68, + 0x2a, 0x56, 0x68, 0x13, 0xa5, 0xb9, 0x6f, 0xc0, 0xfc, 0x41, 0x48, 0xf8, 0x73, 0x28, 0xa7, 0x4b, + 0x3e, 0xab, 0xfc, 0xd4, 0xd1, 0x66, 0x03, 0x3c, 0x31, 0x91, 0x6e, 0xf7, 0x6f, 0x0d, 0x76, 0x64, + 0x43, 0x83, 0x64, 0x99, 0x8e, 0x28, 0x47, 0xf0, 0x8e, 0xae, 0xb2, 0x45, 0x34, 0xa2, 0x39, 0x82, + 0xb9, 0xce, 0x9b, 0xc9, 0x6e, 0xa3, 0x74, 0xac, 0xaa, 0x4a, 0x05, 0x7f, 0x0b, 0x8e, 0x40, 0x92, + 0x85, 0x6c, 0xb5, 0xa0, 0x02, 0xc3, 0xdd, 0xe6, 0xc1, 0xfa, 0xa8, 0x04, 0x4e, 0x2c, 0x58, 0x2d, + 0x28, 0x01, 0x56, 0xc8, 0xdb, 0x97, 0x68, 0x3c, 0xe3, 0x12, 0xd7, 0xfb, 0x2b, 0x6f, 0xed, 0xef, + 0xb4, 0x00, 0xc3, 0x54, 0x59, 0x36, 0x66, 0x95, 0x70, 0x14, 0x00, 0xfd, 0x04, 0x36, 0x49, 0x1e, + 0xdb, 0xb7, 0x22, 0xa1, 0x0b, 0xe6, 0x90, 0xde, 0x24, 0x29, 0x55, 0x5b, 0x02, 0xc5, 0x62, 0x24, + 0x79, 0x24, 0xca, 0x83, 0x4f, 0xa0, 0x1c, 0xdd, 0xe4, 0x40, 0x6f, 0x87, 0x48, 0x87, 0x1b, 0x81, + 0x45, 0x92, 0x47, 0xc1, 0x7c, 0xf8, 0x15, 0xc8, 0x09, 0xc3, 0x38, 0x9a, 0xe7, 0xf0, 0xd9, 0xc2, + 0xd2, 0x8b, 0xe6, 0x14, 0x7f, 0x07, 0x4e, 0x9a, 0x3c, 0x86, 0x23, 0x51, 0x5e, 0x9e, 0xa1, 0xd3, + 0x3c, 0xdc, 0x5a, 0x4d, 0xde, 0x1c, 0x81, 0x34, 0x17, 0x33, 0xf7, 0x57, 0x0d, 0xcc, 0x77, 0xb2, + 0xc2, 0x29, 0x18, 0x02, 0x65, 0x49, 0x9c, 0x47, 0x9b, 0x6f, 0x65, 0x84, 0xc0, 0x59, 0xc4, 0xf0, + 0x5f, 0x8d, 0x09, 0x9b, 0xe6, 0xdb, 0x12, 0x32, 0xe7, 0xbf, 0xf1, 0x58, 0xf2, 0x9f, 0x4d, 0xb8, + 0x88, 0xbf, 0x02, 0x9b, 0x37, 0x25, 0xe8, 0x5a, 0xed, 0xe1, 0xe0, 0x49, 0x4b, 0x22, 0x31, 0xb1, + 0x52, 0x25, 0xb9, 0x3f, 0xc3, 0xee, 0x3b, 0xf9, 0x0d, 0x3c, 0xe7, 0xbb, 0x3b, 0xdd, 0x3a, 0xd6, + 0x4f, 0xef, 0xe7, 0x7b, 0x78, 0x59, 0x64, 0x56, 0xdf, 0x55, 0x0d, 0xca, 0xb2, 0x37, 0x79, 0xc9, + 0xf8, 0xe3, 0x91, 0x89, 0x0c, 0x38, 0xfd, 0x5d, 0x03, 0x58, 0x83, 0x80, 0x1d, 0xa8, 0x5c, 0xf7, + 0x2e, 0x7a, 0xfd, 0xf7, 0x3d, 0xf4, 0x02, 0x5b, 0x60, 0x9c, 0x07, 0xdd, 0x0e, 0xd2, 0xb0, 0x0d, + 0x65, 0x49, 0xe5, 0x25, 0xce, 0xc3, 0x8a, 0xc7, 0x75, 0x4e, 0xf2, 0x05, 0x89, 0x1b, 0xb8, 0x02, + 0x7a, 0x41, 0xd5, 0x8a, 0x9b, 0x4d, 0x9e, 0x90, 0x78, 0x57, 0xfe, 0x59, 0xdb, 0x43, 0x15, 0xee, + 0x28, 0x58, 0x1a, 0xc0, 0xcc, 0x29, 0x9a, 0xbf, 0xe4, 0xc4, 0x0e, 0xbc, 0x4e, 0x3f, 0xf8, 0xd1, + 0x23, 0xc8, 0xe1, 0x36, 0xd2, 0x7f, 0x8f, 0x76, 0x5a, 0x5f, 0x7c, 0x78, 0xfd, 0x30, 0x65, 0x34, + 0xcb, 0xea, 0xd3, 0xa4, 0x21, 0xa5, 0xc6, 0x24, 0x69, 0x3c, 0xb0, 0x86, 0xf8, 0x2b, 0xd0, 0x58, + 0x8f, 0x36, 0x34, 0x85, 0xe5, 0xeb, 0x7f, 0x02, 0x00, 0x00, 0xff, 0xff, 0xbd, 0x1a, 0xf9, 0xf4, + 0x59, 0x08, 0x00, 0x00, } diff --git a/go/vt/sqlparser/analyzer.go b/go/vt/sqlparser/analyzer.go index 1c459cee5b9..9c0f4a13e81 100644 --- a/go/vt/sqlparser/analyzer.go +++ b/go/vt/sqlparser/analyzer.go @@ -31,6 +31,7 @@ import ( ) // These constants are used to identify the SQL statement type. +// Chaging this list will require reviewing all calls to Preview. const ( StmtSelect = iota StmtStream diff --git a/go/vt/vttablet/endtoend/framework/server.go b/go/vt/vttablet/endtoend/framework/server.go index d267c231f41..5f39a12e65c 100644 --- a/go/vt/vttablet/endtoend/framework/server.go +++ b/go/vt/vttablet/endtoend/framework/server.go @@ -22,6 +22,9 @@ import ( "net/http" "time" + "vitess.io/vitess/go/vt/mysqlctl" + "vitess.io/vitess/go/vt/topo" + "vitess.io/vitess/go/vt/topo/topoproto" "vitess.io/vitess/go/vt/vterrors" "golang.org/x/net/context" @@ -46,12 +49,29 @@ var ( ServerAddress string // ResolveChan is the channel that sends dtids that are to be resolved. ResolveChan = make(chan string, 1) + // Mysqld is for sending direct commands to mysql + Mysqld *mysqlctl.Mysqld ) -// StartServer starts the server and initializes -// all the global variables. This function should only be called -// once at the beginning of the test. +// StartServer starts the server with configs set for endtoend testing. func StartServer(connParams, connAppDebugParams mysql.ConnParams, dbName string) error { + config := tabletenv.DefaultQsConfig + config.EnableAutoCommit = true + config.StrictTableACL = true + config.TwoPCEnable = true + config.TwoPCAbandonAge = 1 + config.TwoPCCoordinatorAddress = "fake" + config.EnableHotRowProtection = true + + return startServer(nil, config, connParams, connAppDebugParams, dbName, "", "") +} + +// StartFullServer is like StartServer, but with more configurable options. +func StartFullServer(ts *topo.Server, config tabletenv.TabletConfig, connParams, connAppDebugParams mysql.ConnParams, dbName, keyspaceName, alias string) error { + return startServer(ts, config, connParams, connAppDebugParams, dbName, keyspaceName, alias) +} + +func startServer(ts *topo.Server, config tabletenv.TabletConfig, connParams, connAppDebugParams mysql.ConnParams, dbName, keyspaceName, alias string) error { // Setup a fake vtgate server. protocol := "resolveTest" *vtgateconn.VtgateProtocol = protocol @@ -62,25 +82,26 @@ func StartServer(connParams, connAppDebugParams mysql.ConnParams, dbName string) }) dbcfgs := dbconfigs.NewTestDBConfigs(connParams, connAppDebugParams, dbName) - - config := tabletenv.DefaultQsConfig - config.EnableAutoCommit = true - config.StrictTableACL = true - config.TwoPCEnable = true - config.TwoPCAbandonAge = 1 - config.TwoPCCoordinatorAddress = "fake" - config.EnableHotRowProtection = true + Mysqld = mysqlctl.NewMysqld(dbcfgs) Target = querypb.Target{ - Keyspace: "vttest", + Keyspace: keyspaceName, Shard: "0", TabletType: topodatapb.TabletType_MASTER, } - Server = tabletserver.NewTabletServerWithNilTopoServer(config) + if ts == nil { + Server = tabletserver.NewTabletServerWithNilTopoServer(config) + } else { + talias, err := topoproto.ParseTabletAlias(alias) + if err != nil { + return err + } + Server = tabletserver.NewTabletServer(config, ts, *talias) + } + Server.Register() - err := Server.StartService(Target, dbcfgs) - if err != nil { + if err := Server.StartService(Target, dbcfgs); err != nil { return vterrors.Wrap(err, "could not start service") } @@ -104,6 +125,7 @@ func StartServer(connParams, connAppDebugParams mysql.ConnParams, dbName string) // StopServer must be called once all the tests are done. func StopServer() { + Mysqld.Close() Server.StopService() } diff --git a/go/vt/vttablet/tabletserver/tabletserver.go b/go/vt/vttablet/tabletserver/tabletserver.go index 3de0ad5aa79..3d0693310c7 100644 --- a/go/vt/vttablet/tabletserver/tabletserver.go +++ b/go/vt/vttablet/tabletserver/tabletserver.go @@ -63,6 +63,7 @@ import ( "vitess.io/vitess/go/vt/vttablet/tabletserver/txthrottler" "vitess.io/vitess/go/vt/vttablet/tabletserver/vstreamer" + binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" querypb "vitess.io/vitess/go/vt/proto/query" topodatapb "vitess.io/vitess/go/vt/proto/topodata" vtrpcpb "vitess.io/vitess/go/vt/proto/vtrpc" @@ -1270,6 +1271,40 @@ func (tsv *TabletServer) execDML(ctx context.Context, target *querypb.Target, qu return int64(qr.RowsAffected), nil } +// VStream streams VReplication events. +func (tsv *TabletServer) VStream(ctx context.Context, target *querypb.Target, startPos mysql.Position, filter *binlogdatapb.Filter, send func([]*binlogdatapb.VEvent) error) error { + // This code is partially duplicated from execRequest. This is because + // is allowed even if the tablet is in non-serving state. + err := func() error { + tsv.mu.Lock() + defer tsv.mu.Unlock() + + if target != nil { + // a valid target needs to be used + switch { + case target.Keyspace != tsv.target.Keyspace: + return vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "invalid keyspace %v", target.Keyspace) + case target.Shard != tsv.target.Shard: + return vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "invalid shard %v", target.Shard) + case target.TabletType != tsv.target.TabletType: + for _, otherType := range tsv.alsoAllow { + if target.TabletType == otherType { + return nil + } + } + return vterrors.Errorf(vtrpcpb.Code_FAILED_PRECONDITION, "invalid tablet type: %v, want: %v or %v", target.TabletType, tsv.target.TabletType, tsv.alsoAllow) + } + } else if !tabletenv.IsLocalContext(ctx) { + return vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "No target") + } + return nil + }() + if err != nil { + return err + } + return tsv.vstreamer.Stream(ctx, startPos, filter, 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 algortihms. diff --git a/go/vt/vttablet/tabletserver/vstreamer/endtoend/main_test.go b/go/vt/vttablet/tabletserver/vstreamer/endtoend/main_test.go new file mode 100644 index 00000000000..eca848929fb --- /dev/null +++ b/go/vt/vttablet/tabletserver/vstreamer/endtoend/main_test.go @@ -0,0 +1,131 @@ +/* +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 vstreamer + +import ( + "flag" + "fmt" + "os" + "path" + "testing" + + "golang.org/x/net/context" + "vitess.io/vitess/go/mysql" + "vitess.io/vitess/go/vt/logutil" + "vitess.io/vitess/go/vt/topo" + "vitess.io/vitess/go/vt/topo/memorytopo" + "vitess.io/vitess/go/vt/topotools" + "vitess.io/vitess/go/vt/vttablet/endtoend/framework" + "vitess.io/vitess/go/vt/vttablet/tabletserver/tabletenv" + "vitess.io/vitess/go/vt/vttest" + + topodatapb "vitess.io/vitess/go/vt/proto/topodata" + vschemapb "vitess.io/vitess/go/vt/proto/vschema" + vttestpb "vitess.io/vitess/go/vt/proto/vttest" +) + +var ( + connParams mysql.ConnParams + connAppDebugParams mysql.ConnParams +) + +func TestMain(m *testing.M) { + flag.Parse() // Do not remove this comment, import into google3 depends on it + tabletenv.Init() + + exitCode := func() int { + // Launch MySQL. + // We need a Keyspace in the topology, so the DbName is set. + // We need a Shard too, so the database 'vttest' is created. + cfg := vttest.Config{ + Topology: &vttestpb.VTTestTopology{ + Keyspaces: []*vttestpb.Keyspace{ + { + Name: "vttest", + Shards: []*vttestpb.Shard{ + { + Name: "0", + DbNameOverride: "vttest", + }, + }, + }, + }, + }, + ExtraMyCnf: []string{path.Join(os.Getenv("VTTOP"), "config/mycnf/rbr.cnf")}, + OnlyMySQL: true, + } + if err := cfg.InitSchemas("vttest", testSchema, nil); err != nil { + fmt.Fprintf(os.Stderr, "InitSchemas failed: %v\n", err) + return 1 + } + defer os.RemoveAll(cfg.SchemaDir) + cluster := vttest.LocalCluster{ + Config: cfg, + } + if err := cluster.Setup(); err != nil { + fmt.Fprintf(os.Stderr, "could not launch mysql: %v\n", err) + return 1 + } + defer cluster.TearDown() + + keyspaceName := "vttest" + ts, err := initTopo(keyspaceName) + if err != nil { + fmt.Fprintf(os.Stderr, "topo init failed: %v\n", err) + return 1 + } + config := tabletenv.DefaultQsConfig + config.EnableAutoCommit = true + + connParams = cluster.MySQLConnParams() + connAppDebugParams = cluster.MySQLAppDebugConnParams() + if err := framework.StartFullServer(ts, config, connParams, connAppDebugParams, cluster.DbName(), keyspaceName, "cell1-100"); err != nil { + fmt.Fprintf(os.Stderr, "%v", err) + return 1 + } + defer framework.StopServer() + + return m.Run() + }() + os.Exit(exitCode) +} + +func initTopo(keyspaceName string) (*topo.Server, error) { + ctx := context.Background() + logger := logutil.NewConsoleLogger() + + cells := []string{"cell1"} + ts := memorytopo.NewServer(cells...) + + if err := ts.CreateKeyspace(ctx, keyspaceName, &topodatapb.Keyspace{}); err != nil { + return nil, fmt.Errorf("CreateKeyspace failed: %v", err) + } + + ks := &vschemapb.Keyspace{ + Sharded: true, + } + if err := ts.SaveVSchema(ctx, keyspaceName, ks); err != nil { + return nil, fmt.Errorf("SaveVSchema failed: %v", err) + } + if err := topotools.RebuildVSchema(ctx, logger, ts, cells); err != nil { + return nil, fmt.Errorf("RebuildVSchema failed: %v", err) + } + return ts, nil +} + +var testSchema = `create table stream1(id int, val varbinary(128), primary key(id)); +create table stream2(id int, val varbinary(128), primary key(id));` diff --git a/go/vt/vttablet/tabletserver/vstreamer/endtoend/vstreamer_test.go b/go/vt/vttablet/tabletserver/vstreamer/endtoend/vstreamer_test.go new file mode 100644 index 00000000000..635dfc64d24 --- /dev/null +++ b/go/vt/vttablet/tabletserver/vstreamer/endtoend/vstreamer_test.go @@ -0,0 +1,171 @@ +/* +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 vstreamer + +import ( + "fmt" + "testing" + + "golang.org/x/net/context" + + "vitess.io/vitess/go/vt/vttablet/endtoend/framework" + + binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" +) + +func TestVStream(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + ch := startStream(ctx, t, &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{{ + Match: "/.*/", + }}, + }) + + testcases := []struct { + input interface{} + output [][]string + }{{ + input: []string{ + "insert into stream1 values (1, 'aaa')", + "update stream1 set val='bbb' where id = 1", + }, + output: [][]string{{ + `gtid`, + `begin`, + `type:ROW row_event: > > `, + `type:ROW row_event: after: > > `, + `commit`, + }}, + }} + + client := framework.NewClient() + + for _, tcase := range testcases { + switch input := tcase.input.(type) { + case []string: + execTransaction(t, client, input) + default: + t.Fatalf("unexpected input: %#v", input) + } + for _, wantset := range tcase.output { + evs := <-ch + if len(wantset) != len(evs) { + t.Fatalf("evs\n%v, want\n%v", evs, wantset) + } + for i, want := range wantset { + switch want { + case "gtid": + if evs[i].Type != binlogdatapb.VEventType_GTID { + t.Fatalf("event: %v, want gtid", evs[i]) + } + case "begin": + if evs[i].Type != binlogdatapb.VEventType_BEGIN { + t.Fatalf("event: %v, want begin", evs[i]) + } + case "commit": + if evs[i].Type != binlogdatapb.VEventType_COMMIT { + t.Fatalf("event: %v, want commit", evs[i]) + } + default: + if got := fmt.Sprintf("%v", evs[i]); got != want { + t.Fatalf("event:\n%q, want\n%q", got, want) + } + } + } + } + } + + //execTransaction(t, client, []string{ + // "insert into stream1 values (1, 'aaa')", + // "update stream1 set val='bbb' where id = 1", + //}) + //execStatement(t, client, "/* c1 */ alter table stream1 change column val val varbinary(128)") + //execTransaction(t, client, []string{ + // "set timestamp=1", + // "insert into stream1 values (2, 'bbb')", + // "insert into stream2 values (1, 'aaa')", + // "update stream1 set val='ccc'", + //}) + //if err := framework.Mysqld.ExecuteSuperQueryList(ctx, []string{ + // "/* c1 */ begin /* c2 */", + // "insert into stream1 values(3, 'ccc')", + // "/* c3 */ commit /* c4 */", + //}); err != nil { + // t.Fatal(err) + //} + //execStatement(t, client, "set timestamp=1") + //execStatement(t, client, "delete from stream1") + //execStatement(t, client, "describe stream2") + //execStatement(t, client, "repair table stream2") + //execStatement(t, client, "optimize table stream2") + //execStatement(t, client, "analyze table stream2") +} + +func startStream(ctx context.Context, t *testing.T, filter *binlogdatapb.Filter) <-chan []*binlogdatapb.VEvent { + pos, err := framework.Mysqld.MasterPosition() + if err != nil { + t.Fatal(err) + } + + ch := make(chan []*binlogdatapb.VEvent) + + go func() { + err := framework.Server.VStream( + ctx, + &framework.Target, + pos, + &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{{ + Match: "/.*/", + }}, + }, + func(evs []*binlogdatapb.VEvent) error { + t.Logf("evs: %v\n", evs) + ch <- evs + return nil + }) + if err != nil { + t.Fatal(err) + } + close(ch) + }() + return ch +} + +func execTransaction(t *testing.T, client *framework.QueryClient, queries []string) { + t.Helper() + if err := client.Begin(false); err != nil { + t.Fatal(err) + } + for _, query := range queries { + if _, err := client.Execute(query, nil); err != nil { + t.Fatal(err) + } + } + if err := client.Commit(); err != nil { + t.Fatal(err) + } +} + +func execStatement(t *testing.T, client *framework.QueryClient, query string) { + t.Helper() + if err := framework.Mysqld.ExecuteSuperQuery(context.Background(), query); err != nil { + t.Fatal(err) + } +} diff --git a/go/vt/vttablet/tabletserver/vstreamer/engine.go b/go/vt/vttablet/tabletserver/vstreamer/engine.go index 8e2b057ed41..ea7cd8a35d3 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/engine.go +++ b/go/vt/vttablet/tabletserver/vstreamer/engine.go @@ -70,6 +70,7 @@ func NewEngine(ts srvtopo.Server, se *schema.Engine) *Engine { streamers: make(map[int]*vstreamer), kschema: &vindexes.KeyspaceSchema{}, ts: ts, + se: se, } } @@ -112,7 +113,7 @@ func (vse *Engine) Close() { } // Stream starts a new stream. -func (vse *Engine) Stream(ctx context.Context, startPos mysql.Position, filter *binlogdatapb.Filter, send func(*binlogdatapb.VEvent) error) error { +func (vse *Engine) Stream(ctx context.Context, startPos mysql.Position, filter *binlogdatapb.Filter, send func([]*binlogdatapb.VEvent) error) error { // Ensure kschema is initialized and the watcher is started. vse.watcherOnce.Do(vse.setWatch) diff --git a/go/vt/vttablet/tabletserver/vstreamer/streamer.go b/go/vt/vttablet/tabletserver/vstreamer/vstreamer.go similarity index 70% rename from go/vt/vttablet/tabletserver/vstreamer/streamer.go rename to go/vt/vttablet/tabletserver/vstreamer/vstreamer.go index d2291a5a5ef..f0272126fbe 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/streamer.go +++ b/go/vt/vttablet/tabletserver/vstreamer/vstreamer.go @@ -18,8 +18,8 @@ package vstreamer import ( "context" + "flag" "fmt" - "strings" "vitess.io/vitess/go/mysql" "vitess.io/vitess/go/sqltypes" @@ -32,29 +32,8 @@ import ( binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" ) -// statementPrefixes are normal sql statement prefixes. -var statementPrefixes = map[string]binlogdatapb.VEventType{ - "begin": binlogdatapb.VEventType_BEGIN, - "commit": binlogdatapb.VEventType_COMMIT, - "rollback": binlogdatapb.VEventType_ROLLBACK, - "insert": binlogdatapb.VEventType_INSERT, - "update": binlogdatapb.VEventType_UPDATE, - "delete": binlogdatapb.VEventType_DELETE, - "create": binlogdatapb.VEventType_DDL, - "alter": binlogdatapb.VEventType_DDL, - "drop": binlogdatapb.VEventType_DDL, - "truncate": binlogdatapb.VEventType_DDL, - "rename": binlogdatapb.VEventType_DDL, - "set": binlogdatapb.VEventType_SET, -} - -// getStatementCategory returns the binlogdatapb.BL_* category for a SQL statement. -func getStatementCategory(sql string) binlogdatapb.VEventType { - if i := strings.IndexByte(sql, byte(' ')); i >= 0 { - sql = sql[:i] - } - return statementPrefixes[strings.ToLower(sql)] -} +// PacketSize is exported for allowing tests to change this value. +var PacketSize = flag.Int("vstream_packet_size", 10000, "Suggested packet size for VReplication streamer. This is used only as a recommendation. The actual packet size may be more or less than this amount.") type vstreamer struct { ctx context.Context @@ -64,7 +43,7 @@ type vstreamer struct { se *schema.Engine startPos mysql.Position filter *binlogdatapb.Filter - send func(*binlogdatapb.VEvent) error + send func([]*binlogdatapb.VEvent) error kevents chan *vindexes.KeyspaceSchema kschema *vindexes.KeyspaceSchema @@ -75,7 +54,7 @@ type vstreamer struct { pos mysql.Position } -func newVStreamer(ctx context.Context, cp *mysql.ConnParams, se *schema.Engine, startPos mysql.Position, filter *binlogdatapb.Filter, kschema *vindexes.KeyspaceSchema, send func(*binlogdatapb.VEvent) error) *vstreamer { +func newVStreamer(ctx context.Context, cp *mysql.ConnParams, se *schema.Engine, startPos mysql.Position, filter *binlogdatapb.Filter, kschema *vindexes.KeyspaceSchema, send func([]*binlogdatapb.VEvent) error) *vstreamer { ctx, cancel := context.WithCancel(ctx) return &vstreamer{ ctx: ctx, @@ -130,18 +109,63 @@ func (vs *vstreamer) Stream() error { } func (vs *vstreamer) parseEvents(ctx context.Context, events <-chan mysql.BinlogEvent) error { + // bufferAndTransmit uses bufferedEvents and curSize to buffer events. + var bufferedEvents []*binlogdatapb.VEvent + var curSize int + bufferAndTransmit := func(vevent *binlogdatapb.VEvent) error { + switch vevent.Type { + case binlogdatapb.VEventType_GTID, binlogdatapb.VEventType_BEGIN: + // We never have to send GTID or BEGIN events on their own. + bufferedEvents = append(bufferedEvents, vevent) + case binlogdatapb.VEventType_COMMIT, binlogdatapb.VEventType_ROLLBACK, binlogdatapb.VEventType_DDL: + // COMMIT, ROLLBACK and DDL are terminal. There may be no more events after + // these for a long time. So, we have to send whatever we have. + bufferedEvents = append(bufferedEvents, vevent) + vevents := bufferedEvents + bufferedEvents = nil + curSize = 0 + return vs.send(vevents) + case binlogdatapb.VEventType_ROW: + // ROW events happen inside transactions. So, we can chunk them. + // Buffer everything until packet size is reached, and then send. + newSize := 0 + for _, rowChange := range vevent.RowEvent.RowChanges { + if rowChange.Before != nil { + newSize += len(rowChange.Before.Values) + } + if rowChange.After != nil { + newSize += len(rowChange.After.Values) + } + } + if curSize+newSize > *PacketSize { + vevents := bufferedEvents + bufferedEvents = []*binlogdatapb.VEvent{vevent} + curSize = newSize + return vs.send(vevents) + } + bufferedEvents = append(bufferedEvents, vevent) + } + return nil + } + + // Main loop: calls bufferAndTransmit as events arrive. for { select { case ev, ok := <-events: if !ok { - return fmt.Errorf("server EOF") + select { + case <-ctx.Done(): + return nil + default: + } + return fmt.Errorf("unexpected server EOF") } vevents, err := vs.parseEvent(ev) if err != nil { return err } for _, vevent := range vevents { - if err := vs.send(vevent); err != nil { + if err := bufferAndTransmit(vevent); err != nil { return fmt.Errorf("error sending event: %v", err) } } @@ -150,7 +174,7 @@ func (vs *vstreamer) parseEvents(ctx context.Context, events <-chan mysql.Binlog return err } case <-ctx.Done(): - return ctx.Err() + return nil } } } @@ -216,26 +240,42 @@ func (vs *vstreamer) parseEvent(ev mysql.BinlogEvent) ([]*binlogdatapb.VEvent, e if err != nil { return nil, fmt.Errorf("can't get query from binlog event: %v, event data: %#v", err, ev) } - switch cat := getStatementCategory(q.SQL); cat { - case binlogdatapb.VEventType_BEGIN, binlogdatapb.VEventType_COMMIT, binlogdatapb.VEventType_ROLLBACK: + switch cat := sqlparser.Preview(q.SQL); cat { + case sqlparser.StmtBegin: vevents = append(vevents, &binlogdatapb.VEvent{ - Type: cat, + Type: binlogdatapb.VEventType_BEGIN, + }) + case sqlparser.StmtCommit: + vevents = append(vevents, &binlogdatapb.VEvent{ + Type: binlogdatapb.VEventType_COMMIT, }) - case binlogdatapb.VEventType_DDL: + case sqlparser.StmtRollback: vevents = append(vevents, &binlogdatapb.VEvent{ - Type: cat, + Type: binlogdatapb.VEventType_ROLLBACK, + }) + case sqlparser.StmtDDL: + vevents = append(vevents, &binlogdatapb.VEvent{ + Type: binlogdatapb.VEventType_DDL, Ddl: q.SQL, }) + case sqlparser.StmtOther: + // These are DBA statements like REPAIR that can be ignored. default: - return nil, fmt.Errorf("unexpected event type %v in row-based replication: %#v", cat, ev) + return nil, fmt.Errorf("unexpected statement type %s in row-based replication: %q", sqlparser.StmtType(cat), q.SQL) } case ev.IsTableMap(): + // This is very frequent. It precedes every row event. id := ev.TableID(vs.format) tm, err := ev.TableMap(vs.format) if err != nil { return nil, err } + // We have to build a plan only for new ids. + if _, ok := vs.plans[id]; ok { + return nil, nil + } if tm.Database != "" && tm.Database != vs.cp.DbName { + vs.plans[id] = nil return nil, nil } ti := vs.se.GetTable(sqlparser.NewTableIdent(tm.Name)) @@ -253,9 +293,7 @@ func (vs *vstreamer) parseEvent(ev mysql.BinlogEvent) ([]*binlogdatapb.VEvent, e if err != nil { return nil, err } - if plan != nil { - vs.plans[id] = plan - } + vs.plans[id] = plan case ev.IsWriteRows() || ev.IsDeleteRows() || ev.IsUpdateRows(): // The existence of before and after images can be used to // identify statememt types. It's also possible that the @@ -271,7 +309,7 @@ func (vs *vstreamer) parseEvent(ev mysql.BinlogEvent) ([]*binlogdatapb.VEvent, e if err != nil { return nil, err } - rowEvents := make([]*binlogdatapb.RowEvent, 0, len(rows.Rows)) + rowChanges := make([]*binlogdatapb.RowChange, 0, len(rows.Rows)) for _, row := range rows.Rows { beforeOK, beforeValues, err := vs.extractRowAndFilter(plan, row.Identify, rows.IdentifyColumns, row.NullIdentifyColumns) if err != nil { @@ -284,18 +322,21 @@ func (vs *vstreamer) parseEvent(ev mysql.BinlogEvent) ([]*binlogdatapb.VEvent, e if !beforeOK && !afterOK { continue } - rowEvent := &binlogdatapb.RowEvent{} + rowChange := &binlogdatapb.RowChange{} if beforeOK { - rowEvent.Before = sqltypes.RowToProto3(beforeValues) + rowChange.Before = sqltypes.RowToProto3(beforeValues) } if afterOK { - rowEvent.After = sqltypes.RowToProto3(afterValues) + rowChange.After = sqltypes.RowToProto3(afterValues) } - rowEvents = append(rowEvents, rowEvent) + rowChanges = append(rowChanges, rowChange) } vevents = append(vevents, &binlogdatapb.VEvent{ - Type: binlogdatapb.VEventType_ROW, - RowEvents: rowEvents, + Type: binlogdatapb.VEventType_ROW, + RowEvent: &binlogdatapb.RowEvent{ + TableName: plan.Table.Name, + RowChanges: rowChanges, + }, }) } return vevents, nil @@ -303,6 +344,11 @@ func (vs *vstreamer) parseEvent(ev mysql.BinlogEvent) ([]*binlogdatapb.VEvent, e func (vs *vstreamer) rebuildPlans() error { for id, plan := range vs.plans { + if plan == nil { + // If a table has no plan, a kschema change will not + // cause that to change. + continue + } newPlan, err := buildPlan(plan.Table, vs.kschema, vs.filter) if err != nil { return err @@ -341,7 +387,9 @@ func (vs *vstreamer) extractRowAndFilter(plan *Plan, data []byte, dataColumns, n func wrapError(err error, stopPos mysql.Position) error { if err != nil { err = fmt.Errorf("stream error @ %v: %v", stopPos, err) + log.Error(err) + return err } - log.Infof("stream ended @ %v, err: %v", stopPos, err) - return err + log.Infof("stream ended @ %v", stopPos) + return nil } diff --git a/proto/binlogdata.proto b/proto/binlogdata.proto index b75d94fa031..e7a90bee538 100644 --- a/proto/binlogdata.proto +++ b/proto/binlogdata.proto @@ -166,23 +166,32 @@ enum VEventType { ROLLBACK = 4; DDL = 5; INSERT = 6; - UPDATE = 7; - DELETE = 8; - SET = 9; - ROW = 10; + REPLACE = 7; + UPDATE = 8; + DELETE = 9; + SET = 10; + OTHER = 11; + ROW = 12; } -message RowEvent { +// RowChange represents one row change +message RowChange { query.Row before = 1; query.Row after = 2; } +// RowEvent represent row events for one table +message RowEvent { + string table_name = 1; + repeated RowChange row_changes = 2; +} + // VEvent represents a vstream event message VEvent { VEventType type = 1; string gtid = 2; string ddl = 3; - repeated RowEvent row_events = 4; + RowEvent row_event = 4; } // VStreamRequest is the payload for VStream diff --git a/py/vtproto/binlogdata_pb2.py b/py/vtproto/binlogdata_pb2.py index e3d91c969f6..494106e8187 100644 --- a/py/vtproto/binlogdata_pb2.py +++ b/py/vtproto/binlogdata_pb2.py @@ -22,7 +22,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\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\"\xb5\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\"A\n\x08RowEvent\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\"s\n\x06VEvent\x12$\n\x04type\x18\x01 \x01(\x0e\x32\x16.binlogdata.VEventType\x12\x0c\n\x04gtid\x18\x02 \x01(\t\x12\x0b\n\x03\x64\x64l\x18\x03 \x01(\t\x12(\n\nrow_events\x18\x04 \x03(\x0b\x32\x14.binlogdata.RowEvent\"F\n\x0eVStreamRequest\x12\x10\n\x08position\x18\x01 \x01(\t\x12\"\n\x06\x66ilter\x18\x02 \x01(\x0b\x32\x12.binlogdata.Filter\"4\n\x0fVStreamResponse\x12!\n\x05\x65vent\x18\x01 \x03(\x0b\x32\x12.binlogdata.VEvent*\x87\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\n\n\x06UPDATE\x10\x07\x12\n\n\x06\x44\x45LETE\x10\x08\x12\x07\n\x03SET\x10\t\x12\x07\n\x03ROW\x10\nB)Z\'vitess.io/vitess/go/vt/proto/binlogdatab\x06proto3') + serialized_pb=_b('\n\x10\x62inlogdata.proto\x12\nbinlogdata\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\"\xb5\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\"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\"r\n\x06VEvent\x12$\n\x04type\x18\x01 \x01(\x0e\x32\x16.binlogdata.VEventType\x12\x0c\n\x04gtid\x18\x02 \x01(\t\x12\x0b\n\x03\x64\x64l\x18\x03 \x01(\t\x12\'\n\trow_event\x18\x04 \x01(\x0b\x32\x14.binlogdata.RowEvent\"F\n\x0eVStreamRequest\x12\x10\n\x08position\x18\x01 \x01(\t\x12\"\n\x06\x66ilter\x18\x02 \x01(\x0b\x32\x12.binlogdata.Filter\"4\n\x0fVStreamResponse\x12!\n\x05\x65vent\x18\x01 \x03(\x0b\x32\x12.binlogdata.VEvent*\x9f\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\x42)Z\'vitess.io/vitess/go/vt/proto/binlogdatab\x06proto3') , dependencies=[query__pb2.DESCRIPTOR,topodata__pb2.DESCRIPTOR,]) @@ -61,26 +61,34 @@ serialized_options=None, type=None), _descriptor.EnumValueDescriptor( - name='UPDATE', index=7, number=7, + name='REPLACE', index=7, number=7, serialized_options=None, type=None), _descriptor.EnumValueDescriptor( - name='DELETE', index=8, number=8, + name='UPDATE', index=8, number=8, serialized_options=None, type=None), _descriptor.EnumValueDescriptor( - name='SET', index=9, number=9, + name='DELETE', index=9, number=9, serialized_options=None, type=None), _descriptor.EnumValueDescriptor( - name='ROW', index=10, number=10, + name='SET', index=10, number=10, + serialized_options=None, + type=None), + _descriptor.EnumValueDescriptor( + name='OTHER', index=11, number=11, + serialized_options=None, + type=None), + _descriptor.EnumValueDescriptor( + name='ROW', index=12, number=12, serialized_options=None, type=None), ], containing_type=None, serialized_options=None, - serialized_start=1518, - serialized_end=1653, + serialized_start=1594, + serialized_end=1753, ) _sym_db.RegisterEnumDescriptor(_VEVENTTYPE) @@ -92,10 +100,12 @@ ROLLBACK = 4 DDL = 5 INSERT = 6 -UPDATE = 7 -DELETE = 8 -SET = 9 -ROW = 10 +REPLACE = 7 +UPDATE = 8 +DELETE = 9 +SET = 10 +OTHER = 11 +ROW = 12 _BINLOGTRANSACTION_STATEMENT_CATEGORY = _descriptor.EnumDescriptor( @@ -568,22 +578,22 @@ ) -_ROWEVENT = _descriptor.Descriptor( - name='RowEvent', - full_name='binlogdata.RowEvent', +_ROWCHANGE = _descriptor.Descriptor( + name='RowChange', + full_name='binlogdata.RowChange', filename=None, file=DESCRIPTOR, containing_type=None, fields=[ _descriptor.FieldDescriptor( - name='before', full_name='binlogdata.RowEvent.before', index=0, + name='before', full_name='binlogdata.RowChange.before', 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='after', full_name='binlogdata.RowEvent.after', index=1, + name='after', full_name='binlogdata.RowChange.after', 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, @@ -602,7 +612,45 @@ oneofs=[ ], serialized_start=1207, - serialized_end=1272, + serialized_end=1273, +) + + +_ROWEVENT = _descriptor.Descriptor( + name='RowEvent', + full_name='binlogdata.RowEvent', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='table_name', full_name='binlogdata.RowEvent.table_name', 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), + _descriptor.FieldDescriptor( + name='row_changes', full_name='binlogdata.RowEvent.row_changes', index=1, + number=2, 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=1275, + serialized_end=1349, ) @@ -635,9 +683,9 @@ is_extension=False, extension_scope=None, serialized_options=None, file=DESCRIPTOR), _descriptor.FieldDescriptor( - name='row_events', full_name='binlogdata.VEvent.row_events', index=3, - number=4, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], + name='row_event', full_name='binlogdata.VEvent.row_event', index=3, + number=4, 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), @@ -653,8 +701,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=1274, - serialized_end=1389, + serialized_start=1351, + serialized_end=1465, ) @@ -691,8 +739,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=1391, - serialized_end=1461, + serialized_start=1467, + serialized_end=1537, ) @@ -722,8 +770,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=1463, - serialized_end=1515, + serialized_start=1539, + serialized_end=1591, ) _BINLOGTRANSACTION_STATEMENT.fields_by_name['category'].enum_type = _BINLOGTRANSACTION_STATEMENT_CATEGORY @@ -741,10 +789,11 @@ _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 -_ROWEVENT.fields_by_name['before'].message_type = query__pb2._ROW -_ROWEVENT.fields_by_name['after'].message_type = query__pb2._ROW +_ROWCHANGE.fields_by_name['before'].message_type = query__pb2._ROW +_ROWCHANGE.fields_by_name['after'].message_type = query__pb2._ROW +_ROWEVENT.fields_by_name['row_changes'].message_type = _ROWCHANGE _VEVENT.fields_by_name['type'].enum_type = _VEVENTTYPE -_VEVENT.fields_by_name['row_events'].message_type = _ROWEVENT +_VEVENT.fields_by_name['row_event'].message_type = _ROWEVENT _VSTREAMREQUEST.fields_by_name['filter'].message_type = _FILTER _VSTREAMRESPONSE.fields_by_name['event'].message_type = _VEVENT DESCRIPTOR.message_types_by_name['Charset'] = _CHARSET @@ -756,6 +805,7 @@ DESCRIPTOR.message_types_by_name['Rule'] = _RULE DESCRIPTOR.message_types_by_name['Filter'] = _FILTER DESCRIPTOR.message_types_by_name['BinlogSource'] = _BINLOGSOURCE +DESCRIPTOR.message_types_by_name['RowChange'] = _ROWCHANGE DESCRIPTOR.message_types_by_name['RowEvent'] = _ROWEVENT DESCRIPTOR.message_types_by_name['VEvent'] = _VEVENT DESCRIPTOR.message_types_by_name['VStreamRequest'] = _VSTREAMREQUEST @@ -834,6 +884,13 @@ )) _sym_db.RegisterMessage(BinlogSource) +RowChange = _reflection.GeneratedProtocolMessageType('RowChange', (_message.Message,), dict( + DESCRIPTOR = _ROWCHANGE, + __module__ = 'binlogdata_pb2' + # @@protoc_insertion_point(class_scope:binlogdata.RowChange) + )) +_sym_db.RegisterMessage(RowChange) + RowEvent = _reflection.GeneratedProtocolMessageType('RowEvent', (_message.Message,), dict( DESCRIPTOR = _ROWEVENT, __module__ = 'binlogdata_pb2' From bd7fe99b180a243a93c21af290a5f70bb4b5c634 Mon Sep 17 00:00:00 2001 From: Sugu Sougoumarane Date: Sun, 30 Dec 2018 20:05:01 -0800 Subject: [PATCH 022/115] vreplication: make a singleton srvtopo.Server Also need to make VSchemaErrors into a singleton Signed-off-by: Sugu Sougoumarane --- go/vt/vttablet/tabletserver/tabletserver.go | 5 ++++- go/vt/vttablet/tabletserver/vstreamer/engine.go | 3 +-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/go/vt/vttablet/tabletserver/tabletserver.go b/go/vt/vttablet/tabletserver/tabletserver.go index 3d0693310c7..261df14c53e 100644 --- a/go/vt/vttablet/tabletserver/tabletserver.go +++ b/go/vt/vttablet/tabletserver/tabletserver.go @@ -213,6 +213,7 @@ func NewServer(topoServer *topo.Server, alias topodatapb.TabletAlias) *TabletSer } var tsOnce sync.Once +var srvTopoServer srvtopo.Server // NewTabletServerWithNilTopoServer is typically used in tests that // don't need a topoServer member. @@ -242,12 +243,12 @@ func NewTabletServer(config tabletenv.TabletConfig, topoServer *topo.Server, ali tsv.txThrottler = txthrottler.CreateTxThrottlerFromTabletConfig(topoServer) tsv.messager = messager.NewEngine(tsv, tsv.se, config) tsv.watcher = NewReplicationWatcher(tsv.se, config) - tsv.vstreamer = vstreamer.NewEngine(srvtopo.NewResilientServer(topoServer, "TabletSrvTopo"), tsv.se) tsv.updateStreamList = &binlog.StreamList{} // FIXME(alainjobart) could we move this to the Register method below? // So that vtcombo doesn't even call it once, on the first tablet. // And we can remove the tsOnce variable. tsOnce.Do(func() { + srvTopoServer = srvtopo.NewResilientServer(topoServer, "TabletSrvTopo") stats.NewGaugeFunc("TabletState", "Tablet server state", func() int64 { tsv.mu.Lock() state := tsv.state @@ -265,6 +266,8 @@ func NewTabletServer(config tabletenv.TabletConfig, topoServer *topo.Server, ali 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) return tsv } diff --git a/go/vt/vttablet/tabletserver/vstreamer/engine.go b/go/vt/vttablet/tabletserver/vstreamer/engine.go index ea7cd8a35d3..b9020fb69b1 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/engine.go +++ b/go/vt/vttablet/tabletserver/vstreamer/engine.go @@ -34,7 +34,7 @@ import ( vschemapb "vitess.io/vitess/go/vt/proto/vschema" ) -var vschemaErrors *stats.Counter +var vschemaErrors = stats.NewCounter("VSchemaErrors", "Count of VSchema errors") // Engine is the engine for handling vseplication streaming requests. type Engine struct { @@ -65,7 +65,6 @@ type Engine struct { // NewEngine creates a new Engine. func NewEngine(ts srvtopo.Server, se *schema.Engine) *Engine { - vschemaErrors = stats.NewCounter("VSchemaErrors", "Count of VSchema errors") return &Engine{ streamers: make(map[int]*vstreamer), kschema: &vindexes.KeyspaceSchema{}, From 7f1c7b5657ef061ad250b9d834d1d49994fa7681 Mon Sep 17 00:00:00 2001 From: Sugu Sougoumarane Date: Sun, 30 Dec 2018 22:54:02 -0800 Subject: [PATCH 023/115] vreplication: tests: statements and DDL add column Signed-off-by: Sugu Sougoumarane --- go/vt/vttablet/tabletserver/tabletserver.go | 2 +- .../vstreamer/endtoend/main_test.go | 7 - .../vstreamer/endtoend/vstreamer_test.go | 265 +++++++++++++----- .../tabletserver/vstreamer/vstreamer.go | 7 +- 4 files changed, 196 insertions(+), 85 deletions(-) diff --git a/go/vt/vttablet/tabletserver/tabletserver.go b/go/vt/vttablet/tabletserver/tabletserver.go index 261df14c53e..e6eb5dd1eda 100644 --- a/go/vt/vttablet/tabletserver/tabletserver.go +++ b/go/vt/vttablet/tabletserver/tabletserver.go @@ -583,11 +583,11 @@ func (tsv *TabletServer) StopService() { log.Infof("Executing complete shutdown.") tsv.waitForShutdown() + tsv.vstreamer.Close() tsv.qe.Close() tsv.se.Close() tsv.hw.Close() tsv.hr.Close() - tsv.vstreamer.Close() log.Infof("Shutdown complete.") tsv.transition(StateNotConnected) } diff --git a/go/vt/vttablet/tabletserver/vstreamer/endtoend/main_test.go b/go/vt/vttablet/tabletserver/vstreamer/endtoend/main_test.go index eca848929fb..d4f2feb0070 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/endtoend/main_test.go +++ b/go/vt/vttablet/tabletserver/vstreamer/endtoend/main_test.go @@ -68,10 +68,6 @@ func TestMain(m *testing.M) { ExtraMyCnf: []string{path.Join(os.Getenv("VTTOP"), "config/mycnf/rbr.cnf")}, OnlyMySQL: true, } - if err := cfg.InitSchemas("vttest", testSchema, nil); err != nil { - fmt.Fprintf(os.Stderr, "InitSchemas failed: %v\n", err) - return 1 - } defer os.RemoveAll(cfg.SchemaDir) cluster := vttest.LocalCluster{ Config: cfg, @@ -126,6 +122,3 @@ func initTopo(keyspaceName string) (*topo.Server, error) { } return ts, nil } - -var testSchema = `create table stream1(id int, val varbinary(128), primary key(id)); -create table stream2(id int, val varbinary(128), primary key(id));` diff --git a/go/vt/vttablet/tabletserver/vstreamer/endtoend/vstreamer_test.go b/go/vt/vttablet/tabletserver/vstreamer/endtoend/vstreamer_test.go index 635dfc64d24..b4d25375902 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/endtoend/vstreamer_test.go +++ b/go/vt/vttablet/tabletserver/vstreamer/endtoend/vstreamer_test.go @@ -27,20 +27,25 @@ import ( binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" ) -func TestVStream(t *testing.T) { - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() +type testcase struct { + input interface{} + output [][]string +} + +func TestStatements(t *testing.T) { + execStatements(t, []string{ + "create table stream1(id int, val varbinary(128), primary key(id))", + "create table stream2(id int, val varbinary(128), primary key(id))", + }) + framework.Server.ReloadSchema(context.Background()) - ch := startStream(ctx, t, &binlogdatapb.Filter{ + filter := &binlogdatapb.Filter{ Rules: []*binlogdatapb.Rule{{ Match: "/.*/", }}, - }) + } - testcases := []struct { - input interface{} - output [][]string - }{{ + testcases := []testcase{{ input: []string{ "insert into stream1 values (1, 'aaa')", "update stream1 set val='bbb' where id = 1", @@ -52,69 +57,178 @@ func TestVStream(t *testing.T) { `type:ROW row_event: after: > > `, `commit`, }}, + }, { + // Normal DDL. + input: "alter table stream1 change column val val varbinary(128)", + output: [][]string{{ + `gtid`, + `type:DDL ddl:"alter table stream1 change column val val varbinary(128)" `, + }}, + }, { + // DDL padded with comments. + input: " /* prefix */ alter table stream1 change column val val varbinary(256) /* suffix */ ", + output: [][]string{{ + `gtid`, + `type:DDL ddl:"/* prefix */ alter table stream1 change column val val varbinary(256) /* suffix */" `, + }}, + }, { + // Multiple tables, and multiple rows changed per statement. + input: []string{ + "insert into stream1 values (2, 'bbb')", + "insert into stream2 values (1, 'aaa')", + "update stream1 set val='ccc'", + "delete from stream1", + }, + output: [][]string{{ + `gtid`, + `begin`, + `type:ROW row_event: > > `, + `type:ROW row_event: > > `, + `type:ROW row_event: after: > ` + + `row_changes: after: > > `, + `type:ROW row_event: > ` + + `row_changes: > > `, + `commit`, + }}, + }, { + // truncate is a DDL + input: "truncate table stream2", + output: [][]string{{ + `gtid`, + `type:DDL ddl:"truncate table stream2" `, + }}, + }, { + // repair, optimize and analyze show up in binlog stream, but ignored by vitess. + input: "repair table stream2", + }, { + input: "optimize table stream2", + }, { + input: "analyze table stream2", + }, { + // select, set, show, analyze and describe don't get logged. + input: "select * from stream1", + }, { + input: "set @val=1", + }, { + input: "show tables", + }, { + input: "analyze table stream1", + }, { + input: "describe stream1", }} + runCases(t, filter, testcases) +} - client := framework.NewClient() +func TestDDLAddColumn(t *testing.T) { + execStatement(t, "create table ddl_test(id int, val varbinary(128), primary key(id))") + + // Record position before the next few statements. + pos, err := framework.Mysqld.MasterPosition() + if err != nil { + t.Fatal(err) + } + execStatements(t, []string{ + "insert into ddl_test values(1, 'aaa')", + // Adding columns is allowed. + "alter table ddl_test add column val2 varbinary(128)", + "insert into ddl_test values(2, 'bbb', 'ccc')", + }) + framework.Server.ReloadSchema(context.Background()) + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + filter := &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{{ + Match: "/.*/", + }}, + } + + ch := make(chan []*binlogdatapb.VEvent) + go func() { + err := framework.Server.VStream(ctx, &framework.Target, pos, filter, func(evs []*binlogdatapb.VEvent) error { + t.Logf("evs: %v\n", evs) + ch <- evs + return nil + }) + if err != nil { + t.Fatal(err) + } + close(ch) + }() + expectLog(t, "ddls", ch, [][]string{{ + // Current schema has 3 columns, but they'll be truncated to match the two columns in the event. + `gtid`, + `begin`, + `type:ROW row_event: > > `, + `commit`, + }, { + `gtid`, + `type:DDL ddl:"alter table ddl_test add column val2 varbinary(128)" `, + }, { + // The plan will be updated to now include the third column + // because the new table map will have three columns. + `gtid`, + `begin`, + `type:ROW row_event: > > `, + `commit`, + }}) +} + +func runCases(t *testing.T, filter *binlogdatapb.Filter, testcases []testcase) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + ch := startStream(ctx, t, filter) for _, tcase := range testcases { switch input := tcase.input.(type) { case []string: - execTransaction(t, client, input) + execTransaction(t, input) + case string: + execStatement(t, input) default: t.Fatalf("unexpected input: %#v", input) } - for _, wantset := range tcase.output { - evs := <-ch - if len(wantset) != len(evs) { - t.Fatalf("evs\n%v, want\n%v", evs, wantset) - } - for i, want := range wantset { - switch want { - case "gtid": - if evs[i].Type != binlogdatapb.VEventType_GTID { - t.Fatalf("event: %v, want gtid", evs[i]) - } - case "begin": - if evs[i].Type != binlogdatapb.VEventType_BEGIN { - t.Fatalf("event: %v, want begin", evs[i]) - } - case "commit": - if evs[i].Type != binlogdatapb.VEventType_COMMIT { - t.Fatalf("event: %v, want commit", evs[i]) - } - default: - if got := fmt.Sprintf("%v", evs[i]); got != want { - t.Fatalf("event:\n%q, want\n%q", got, want) - } + expectLog(t, tcase.input, ch, tcase.output) + } + cancel() + if evs, ok := <-ch; ok { + t.Fatalf("unexpected evs: %v", evs) + } +} + +func expectLog(t *testing.T, input interface{}, ch <-chan []*binlogdatapb.VEvent, output [][]string) { + t.Helper() + + for _, wantset := range output { + evs := <-ch + if len(wantset) != len(evs) { + t.Fatalf("%v: evs\n%v, want\n%v", input, evs, wantset) + } + for i, want := range wantset { + switch want { + case "gtid": + if evs[i].Type != binlogdatapb.VEventType_GTID { + t.Fatalf("%v (%d): event: %v, want gtid", input, i, evs[i]) + } + case "begin": + if evs[i].Type != binlogdatapb.VEventType_BEGIN { + t.Fatalf("%v (%d): event: %v, want begin", input, i, evs[i]) + } + case "commit": + if evs[i].Type != binlogdatapb.VEventType_COMMIT { + t.Fatalf("%v (%d): event: %v, want commit", input, i, evs[i]) + } + default: + if got := fmt.Sprintf("%v", evs[i]); got != want { + t.Fatalf("%v (%d): event:\n%q, want\n%q", input, i, got, want) } } } } - - //execTransaction(t, client, []string{ - // "insert into stream1 values (1, 'aaa')", - // "update stream1 set val='bbb' where id = 1", - //}) - //execStatement(t, client, "/* c1 */ alter table stream1 change column val val varbinary(128)") - //execTransaction(t, client, []string{ - // "set timestamp=1", - // "insert into stream1 values (2, 'bbb')", - // "insert into stream2 values (1, 'aaa')", - // "update stream1 set val='ccc'", - //}) - //if err := framework.Mysqld.ExecuteSuperQueryList(ctx, []string{ - // "/* c1 */ begin /* c2 */", - // "insert into stream1 values(3, 'ccc')", - // "/* c3 */ commit /* c4 */", - //}); err != nil { - // t.Fatal(err) - //} - //execStatement(t, client, "set timestamp=1") - //execStatement(t, client, "delete from stream1") - //execStatement(t, client, "describe stream2") - //execStatement(t, client, "repair table stream2") - //execStatement(t, client, "optimize table stream2") - //execStatement(t, client, "analyze table stream2") } func startStream(ctx context.Context, t *testing.T, filter *binlogdatapb.Filter) <-chan []*binlogdatapb.VEvent { @@ -124,22 +238,12 @@ func startStream(ctx context.Context, t *testing.T, filter *binlogdatapb.Filter) } ch := make(chan []*binlogdatapb.VEvent) - go func() { - err := framework.Server.VStream( - ctx, - &framework.Target, - pos, - &binlogdatapb.Filter{ - Rules: []*binlogdatapb.Rule{{ - Match: "/.*/", - }}, - }, - func(evs []*binlogdatapb.VEvent) error { - t.Logf("evs: %v\n", evs) - ch <- evs - return nil - }) + err := framework.Server.VStream(ctx, &framework.Target, pos, filter, func(evs []*binlogdatapb.VEvent) error { + t.Logf("evs: %v\n", evs) + ch <- evs + return nil + }) if err != nil { t.Fatal(err) } @@ -148,8 +252,10 @@ func startStream(ctx context.Context, t *testing.T, filter *binlogdatapb.Filter) return ch } -func execTransaction(t *testing.T, client *framework.QueryClient, queries []string) { +func execTransaction(t *testing.T, queries []string) { t.Helper() + + client := framework.NewClient() if err := client.Begin(false); err != nil { t.Fatal(err) } @@ -163,9 +269,16 @@ func execTransaction(t *testing.T, client *framework.QueryClient, queries []stri } } -func execStatement(t *testing.T, client *framework.QueryClient, query string) { +func execStatement(t *testing.T, query string) { t.Helper() if err := framework.Mysqld.ExecuteSuperQuery(context.Background(), query); err != nil { t.Fatal(err) } } + +func execStatements(t *testing.T, queries []string) { + t.Helper() + if err := framework.Mysqld.ExecuteSuperQueryList(context.Background(), queries); err != nil { + t.Fatal(err) + } +} diff --git a/go/vt/vttablet/tabletserver/vstreamer/vstreamer.go b/go/vt/vttablet/tabletserver/vstreamer/vstreamer.go index f0272126fbe..b0bbf8572be 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/vstreamer.go +++ b/go/vt/vttablet/tabletserver/vstreamer/vstreamer.go @@ -258,6 +258,10 @@ func (vs *vstreamer) parseEvent(ev mysql.BinlogEvent) ([]*binlogdatapb.VEvent, e Type: binlogdatapb.VEventType_DDL, Ddl: q.SQL, }) + // Proactively reload schema. + // If the DDL adds a column, comparing with an older snapshot of the + // schema will make us think that a column was dropped and error out. + vs.se.Reload(vs.ctx) case sqlparser.StmtOther: // These are DBA statements like REPAIR that can be ignored. default: @@ -287,7 +291,8 @@ func (vs *vstreamer) parseEvent(ev mysql.BinlogEvent) ([]*binlogdatapb.VEvent, e } table := &Table{ TableMap: tm, - Columns: ti.Columns, + // Columns should be truncated to match those in tm. + Columns: ti.Columns[:len(tm.Types)], } plan, err := buildPlan(table, vs.kschema, vs.filter) if err != nil { From 7fd0c825db756a2029f94543f110024682d49f18 Mon Sep 17 00:00:00 2001 From: Sugu Sougoumarane Date: Mon, 31 Dec 2018 14:19:21 -0800 Subject: [PATCH 024/115] vreplication: MariaDB test tweaks and more tests Signed-off-by: Sugu Sougoumarane --- .../vstreamer/endtoend/vstreamer_test.go | 132 +++++++++++++----- 1 file changed, 95 insertions(+), 37 deletions(-) diff --git a/go/vt/vttablet/tabletserver/vstreamer/endtoend/vstreamer_test.go b/go/vt/vttablet/tabletserver/vstreamer/endtoend/vstreamer_test.go index b4d25375902..82b33c0d08a 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/endtoend/vstreamer_test.go +++ b/go/vt/vttablet/tabletserver/vstreamer/endtoend/vstreamer_test.go @@ -18,10 +18,12 @@ package vstreamer import ( "fmt" + "strings" "testing" "golang.org/x/net/context" + "vitess.io/vitess/go/mysql" "vitess.io/vitess/go/vt/vttablet/endtoend/framework" binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" @@ -37,6 +39,10 @@ func TestStatements(t *testing.T) { "create table stream1(id int, val varbinary(128), primary key(id))", "create table stream2(id int, val varbinary(128), primary key(id))", }) + defer execStatements(t, []string{ + "drop table stream1", + "drop table stream2", + }) framework.Server.ReloadSchema(context.Background()) filter := &binlogdatapb.Filter{ @@ -50,9 +56,11 @@ func TestStatements(t *testing.T) { "insert into stream1 values (1, 'aaa')", "update stream1 set val='bbb' where id = 1", }, + // MySQL issues GTID->BEGIN. + // MariaDB issues BEGIN->GTID. output: [][]string{{ - `gtid`, - `begin`, + `gtid|begin`, + `gtid|begin`, `type:ROW row_event: > > `, `type:ROW row_event: after: > > `, `commit`, @@ -80,8 +88,8 @@ func TestStatements(t *testing.T) { "delete from stream1", }, output: [][]string{{ - `gtid`, - `begin`, + `gtid|begin`, + `gtid|begin`, `type:ROW row_event: > > `, `type:ROW row_event: > > `, `type:ROW row_event: > > `, + `gtid|begin`, + `gtid|begin`, + `type:ROW row_event: > > `, `commit`, }, { `gtid`, - `type:DDL ddl:"alter table ddl_test add column val2 varbinary(128)" `, + `type:DDL ddl:"alter table ddl_test1 add column val2 varbinary(128)" `, }, { // The plan will be updated to now include the third column // because the new table map will have three columns. - `gtid`, - `begin`, - `type:ROW row_event: > > `, + `gtid|begin`, + `gtid|begin`, + `type:ROW row_event: > > `, `commit`, }}) } +func TestDDLDropColumn(t *testing.T) { + execStatement(t, "create table ddl_test2(id int, val1 varbinary(128), val2 varbinary(128), primary key(id))") + defer execStatement(t, "drop table ddl_test2") + + // Record position before the next few statements. + pos, err := framework.Mysqld.MasterPosition() + if err != nil { + t.Fatal(err) + } + execStatements(t, []string{ + "insert into ddl_test2 values(1, 'aaa', 'ccc')", + // Adding columns is allowed. + "alter table ddl_test2 drop column val2", + "insert into ddl_test2 values(2, 'bbb')", + }) + framework.Server.ReloadSchema(context.Background()) + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + filter := &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{{ + Match: "/.*/", + }}, + } + + ch := make(chan []*binlogdatapb.VEvent) + go func() { + for range ch { + } + }() + defer close(ch) + err = vstream(ctx, pos, filter, ch) + want := "Column count doesn't match value" + if err == nil || strings.Contains(err.Error(), want) { + t.Errorf("err: %v, must contain %s", err, want) + } +} + func runCases(t *testing.T, filter *binlogdatapb.Filter, testcases []testcase) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() @@ -192,7 +235,7 @@ func runCases(t *testing.T, filter *binlogdatapb.Filter, testcases []testcase) { default: t.Fatalf("unexpected input: %#v", input) } - expectLog(t, tcase.input, ch, tcase.output) + expectLog(ctx, t, tcase.input, ch, tcase.output) } cancel() if evs, ok := <-ch; ok { @@ -200,24 +243,33 @@ func runCases(t *testing.T, filter *binlogdatapb.Filter, testcases []testcase) { } } -func expectLog(t *testing.T, input interface{}, ch <-chan []*binlogdatapb.VEvent, output [][]string) { +func expectLog(ctx context.Context, t *testing.T, input interface{}, ch <-chan []*binlogdatapb.VEvent, output [][]string) { t.Helper() for _, wantset := range output { - evs := <-ch + var evs []*binlogdatapb.VEvent + var ok bool + select { + case evs, ok = <-ch: + if !ok { + t.Fatal("stream ended early") + } + case <-ctx.Done(): + t.Fatal("stream ended early") + } if len(wantset) != len(evs) { t.Fatalf("%v: evs\n%v, want\n%v", input, evs, wantset) } for i, want := range wantset { switch want { + case "gtid|begin": + if evs[i].Type != binlogdatapb.VEventType_GTID && evs[i].Type != binlogdatapb.VEventType_BEGIN { + t.Fatalf("%v (%d): event: %v, want gtid or begin", input, i, evs[i]) + } case "gtid": if evs[i].Type != binlogdatapb.VEventType_GTID { t.Fatalf("%v (%d): event: %v, want gtid", input, i, evs[i]) } - case "begin": - if evs[i].Type != binlogdatapb.VEventType_BEGIN { - t.Fatalf("%v (%d): event: %v, want begin", input, i, evs[i]) - } case "commit": if evs[i].Type != binlogdatapb.VEventType_COMMIT { t.Fatalf("%v (%d): event: %v, want commit", input, i, evs[i]) @@ -239,19 +291,25 @@ func startStream(ctx context.Context, t *testing.T, filter *binlogdatapb.Filter) ch := make(chan []*binlogdatapb.VEvent) go func() { - err := framework.Server.VStream(ctx, &framework.Target, pos, filter, func(evs []*binlogdatapb.VEvent) error { - t.Logf("evs: %v\n", evs) - ch <- evs - return nil - }) - if err != nil { + defer close(ch) + if err := vstream(ctx, pos, filter, ch); err != nil { t.Fatal(err) } - close(ch) }() return ch } +func vstream(ctx context.Context, pos mysql.Position, filter *binlogdatapb.Filter, ch chan []*binlogdatapb.VEvent) error { + return framework.Server.VStream(ctx, &framework.Target, pos, filter, func(evs []*binlogdatapb.VEvent) error { + select { + case ch <- evs: + case <-ctx.Done(): + return fmt.Errorf("stream ended early") + } + return nil + }) +} + func execTransaction(t *testing.T, queries []string) { t.Helper() From b17b55139c02f28addcf7625cd383b72c6b37485 Mon Sep 17 00:00:00 2001 From: Sugu Sougoumarane Date: Tue, 1 Jan 2019 08:48:01 -0800 Subject: [PATCH 025/115] vreplication: more vstreamer tests Signed-off-by: Sugu Sougoumarane --- .../vstreamer/endtoend/engine_test.go | 114 +++++++++++ .../vstreamer/endtoend/main_test.go | 44 +++-- .../vstreamer/endtoend/vstreamer_test.go | 187 +++++++++++++++--- .../vttablet/tabletserver/vstreamer/engine.go | 58 +++++- .../tabletserver/vstreamer/planbuilder.go | 2 +- .../tabletserver/vstreamer/vstreamer.go | 26 +-- 6 files changed, 376 insertions(+), 55 deletions(-) create mode 100644 go/vt/vttablet/tabletserver/vstreamer/endtoend/engine_test.go diff --git a/go/vt/vttablet/tabletserver/vstreamer/endtoend/engine_test.go b/go/vt/vttablet/tabletserver/vstreamer/endtoend/engine_test.go new file mode 100644 index 00000000000..4a3276c2503 --- /dev/null +++ b/go/vt/vttablet/tabletserver/vstreamer/endtoend/engine_test.go @@ -0,0 +1,114 @@ +/* +Copyright 2019 The Vitess Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this 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 ( + "testing" + + "golang.org/x/net/context" + + "vitess.io/vitess/go/vt/vttablet/endtoend/framework" + + binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" +) + +var shardedVSchema = `{ + "sharded": true, + "vindexes": { + "hash": { + "type": "hash" + } + }, + "tables": { + "t1": { + "column_vindexes": [ + { + "column": "id1", + "name": "hash" + } + ] + } + } +}` + +func TestUpdateVSchema(t *testing.T) { + defer setVSchema("{}") + + // We have to start at least one stream to start the vschema watcher. + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + filter := &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{{ + Match: "/.*/", + }}, + } + + _ = startStream(ctx, t, filter) + cancel() + + startCount := framework.FetchInt(framework.DebugVars(), "VSchemaUpdates") + if startCount == 0 { + t.Errorf("startCount: %d, want non-zero", startCount) + } + + if err := setVSchema(shardedVSchema); err != nil { + t.Fatal(err) + } + + // Looks like memorytopo instantly transmits the watch. + // No need to wait for vschema to propagate. + endCount := framework.FetchInt(framework.DebugVars(), "VSchemaUpdates") + if endCount != startCount+1 { + t.Errorf("endCount: %d, want %d", endCount, startCount+1) + } + + want := `{ + "sharded": true, + "tables": { + "t1": { + "name": "t1", + "column_vindexes": [ + { + "columns": [ + "id1" + ], + "type": "hash", + "name": "hash", + "vindex": {} + } + ], + "ordered": [ + { + "columns": [ + "id1" + ], + "type": "hash", + "name": "hash", + "vindex": {} + } + ] + } + }, + "vindexes": { + "hash": {} + } +}` + if got := framework.FetchURL("/debug/vschema"); got != want { + t.Errorf("vschema:\n%s, want:\n%s", got, want) + } +} diff --git a/go/vt/vttablet/tabletserver/vstreamer/endtoend/main_test.go b/go/vt/vttablet/tabletserver/vstreamer/endtoend/main_test.go index d4f2feb0070..9fc8bce94f9 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/endtoend/main_test.go +++ b/go/vt/vttablet/tabletserver/vstreamer/endtoend/main_test.go @@ -24,6 +24,7 @@ import ( "testing" "golang.org/x/net/context" + "vitess.io/vitess/go/json2" "vitess.io/vitess/go/mysql" "vitess.io/vitess/go/vt/logutil" "vitess.io/vitess/go/vt/topo" @@ -41,6 +42,9 @@ import ( var ( connParams mysql.ConnParams connAppDebugParams mysql.ConnParams + topoServ *topo.Server + keyspaceName = "vttest" + cells = []string{"cell1"} ) func TestMain(m *testing.M) { @@ -78,9 +82,8 @@ func TestMain(m *testing.M) { } defer cluster.TearDown() - keyspaceName := "vttest" - ts, err := initTopo(keyspaceName) - if err != nil { + // initTopo initializes topoServ. + if err := initTopo(); err != nil { fmt.Fprintf(os.Stderr, "topo init failed: %v\n", err) return 1 } @@ -89,7 +92,7 @@ func TestMain(m *testing.M) { connParams = cluster.MySQLConnParams() connAppDebugParams = cluster.MySQLAppDebugConnParams() - if err := framework.StartFullServer(ts, config, connParams, connAppDebugParams, cluster.DbName(), keyspaceName, "cell1-100"); err != nil { + if err := framework.StartFullServer(topoServ, config, connParams, connAppDebugParams, cluster.DbName(), keyspaceName, "cell1-100"); err != nil { fmt.Fprintf(os.Stderr, "%v", err) return 1 } @@ -100,25 +103,30 @@ func TestMain(m *testing.M) { os.Exit(exitCode) } -func initTopo(keyspaceName string) (*topo.Server, error) { +func initTopo() error { ctx := context.Background() - logger := logutil.NewConsoleLogger() - - cells := []string{"cell1"} - ts := memorytopo.NewServer(cells...) - if err := ts.CreateKeyspace(ctx, keyspaceName, &topodatapb.Keyspace{}); err != nil { - return nil, fmt.Errorf("CreateKeyspace failed: %v", err) + topoServ = memorytopo.NewServer(cells...) + if err := topoServ.CreateKeyspace(ctx, keyspaceName, &topodatapb.Keyspace{}); err != nil { + return err } + // The first vschema should not be empty. Leads to Node not found error. + // TODO(sougou): need to fix the bug. + return setVSchema(`{"sharded": true}`) +} - ks := &vschemapb.Keyspace{ - Sharded: true, +func setVSchema(vs string) error { + ctx := context.Background() + logger := logutil.NewConsoleLogger() + var kspb vschemapb.Keyspace + if err := json2.Unmarshal([]byte(vs), &kspb); err != nil { + return fmt.Errorf("Unmarshal failed: %v", err) } - if err := ts.SaveVSchema(ctx, keyspaceName, ks); err != nil { - return nil, fmt.Errorf("SaveVSchema failed: %v", err) + if err := topoServ.SaveVSchema(ctx, keyspaceName, &kspb); err != nil { + return fmt.Errorf("SaveVSchema failed: %v", err) } - if err := topotools.RebuildVSchema(ctx, logger, ts, cells); err != nil { - return nil, fmt.Errorf("RebuildVSchema failed: %v", err) + if err := topotools.RebuildVSchema(ctx, logger, topoServ, cells); err != nil { + return fmt.Errorf("RebuildVSchema failed: %v", err) } - return ts, nil + return nil } diff --git a/go/vt/vttablet/tabletserver/vstreamer/endtoend/vstreamer_test.go b/go/vt/vttablet/tabletserver/vstreamer/endtoend/vstreamer_test.go index 82b33c0d08a..9bd578437e2 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/endtoend/vstreamer_test.go +++ b/go/vt/vttablet/tabletserver/vstreamer/endtoend/vstreamer_test.go @@ -45,12 +45,6 @@ func TestStatements(t *testing.T) { }) framework.Server.ReloadSchema(context.Background()) - filter := &binlogdatapb.Filter{ - Rules: []*binlogdatapb.Rule{{ - Match: "/.*/", - }}, - } - testcases := []testcase{{ input: []string{ "insert into stream1 values (1, 'aaa')", @@ -126,6 +120,159 @@ func TestStatements(t *testing.T) { }, { input: "describe stream1", }} + runCases(t, nil, testcases) +} + +func TestRegexp(t *testing.T) { + execStatements(t, []string{ + "create table yes_stream(id int, val varbinary(128), primary key(id))", + "create table no_stream(id int, val varbinary(128), primary key(id))", + }) + defer execStatements(t, []string{ + "drop table yes_stream", + "drop table no_stream", + }) + framework.Server.ReloadSchema(context.Background()) + + filter := &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{{ + Match: "/yes.*/", + }}, + } + + testcases := []testcase{{ + input: []string{ + "insert into yes_stream values (1, 'aaa')", + "insert into no_stream values (2, 'bbb')", + "update yes_stream set val='bbb' where id = 1", + "update no_stream set val='bbb' where id = 2", + }, + output: [][]string{{ + `gtid|begin`, + `gtid|begin`, + `type:ROW row_event: > > `, + `type:ROW row_event: after: > > `, + `commit`, + }}, + }} + runCases(t, filter, testcases) +} + +func TestREKeyrange(t *testing.T) { + execStatements(t, []string{ + "create table t1(id1 int, id2 int, val varbinary(128), primary key(id1))", + }) + defer execStatements(t, []string{ + "drop table t1", + }) + framework.Server.ReloadSchema(context.Background()) + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + filter := &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{{ + Match: "/.*/", + Filter: "-80", + }}, + } + ch := startStream(ctx, t, filter) + + if err := setVSchema(shardedVSchema); err != nil { + t.Fatal(err) + } + defer setVSchema("{}") + + // 1, 2, 3 and 5 are in shard -80. + // 4 and 6 are in shard 80-. + input := []string{ + "insert into t1 values (1, 4, 'aaa')", + "insert into t1 values (4, 1, 'bbb')", + // Stay in shard. + "update t1 set id1 = 2 where id1 = 1", + // Move from -80 to 80-. + "update t1 set id1 = 6 where id1 = 2", + // Move from 80- to -80. + "update t1 set id1 = 3 where id1 = 4", + } + execTransaction(t, input) + expectLog(ctx, t, input, ch, [][]string{{ + `gtid|begin`, + `gtid|begin`, + `type:ROW row_event: > > `, + `type:ROW row_event: after: > > `, + `type:ROW row_event: > > `, + `type:ROW row_event: > > `, + `commit`, + }}) + + // Switch the vschema to make id2 the primary vindex. + altVSchema := `{ + "sharded": true, + "vindexes": { + "hash": { + "type": "hash" + } + }, + "tables": { + "t1": { + "column_vindexes": [ + { + "column": "id2", + "name": "hash" + } + ] + } + } +}` + if err := setVSchema(altVSchema); err != nil { + t.Fatal(err) + } + + // Only the first insert should be sent. + input = []string{ + "insert into t1 values (4, 1, 'aaa')", + "insert into t1 values (1, 4, 'aaa')", + } + execTransaction(t, input) + expectLog(ctx, t, input, ch, [][]string{{ + `gtid|begin`, + `gtid|begin`, + `type:ROW row_event: > > `, + `commit`, + }}) +} + +func TestSelectFilter(t *testing.T) { + execStatements(t, []string{ + "create table t1(id1 int, id2 int, val varbinary(128), primary key(id1))", + }) + defer execStatements(t, []string{ + "drop table t1", + }) + framework.Server.ReloadSchema(context.Background()) + + filter := &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{{ + Match: "t1", + Filter: "select id2, val from t1 where in_keyrange(id2, 'hash', '-80')", + }}, + } + + testcases := []testcase{{ + input: []string{ + "insert into t1 values (4, 1, 'aaa')", + "insert into t1 values (2, 4, 'aaa')", + }, + // MySQL issues GTID->BEGIN. + // MariaDB issues BEGIN->GTID. + output: [][]string{{ + `gtid|begin`, + `gtid|begin`, + `type:ROW row_event: > > `, + `commit`, + }}, + }} runCases(t, filter, testcases) } @@ -149,16 +296,10 @@ func TestDDLAddColumn(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - filter := &binlogdatapb.Filter{ - Rules: []*binlogdatapb.Rule{{ - Match: "/.*/", - }}, - } - ch := make(chan []*binlogdatapb.VEvent) go func() { defer close(ch) - if err := vstream(ctx, pos, filter, ch); err != nil { + if err := vstream(ctx, t, pos, nil, ch); err != nil { t.Fatal(err) } }() @@ -201,19 +342,13 @@ func TestDDLDropColumn(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - filter := &binlogdatapb.Filter{ - Rules: []*binlogdatapb.Rule{{ - Match: "/.*/", - }}, - } - ch := make(chan []*binlogdatapb.VEvent) go func() { for range ch { } }() defer close(ch) - err = vstream(ctx, pos, filter, ch) + err = vstream(ctx, t, pos, nil, ch) want := "Column count doesn't match value" if err == nil || strings.Contains(err.Error(), want) { t.Errorf("err: %v, must contain %s", err, want) @@ -292,15 +427,23 @@ func startStream(ctx context.Context, t *testing.T, filter *binlogdatapb.Filter) ch := make(chan []*binlogdatapb.VEvent) go func() { defer close(ch) - if err := vstream(ctx, pos, filter, ch); err != nil { + if err := vstream(ctx, t, pos, filter, ch); err != nil { t.Fatal(err) } }() return ch } -func vstream(ctx context.Context, pos mysql.Position, filter *binlogdatapb.Filter, ch chan []*binlogdatapb.VEvent) error { +func vstream(ctx context.Context, t *testing.T, pos mysql.Position, filter *binlogdatapb.Filter, ch chan []*binlogdatapb.VEvent) error { + if filter == nil { + filter = &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{{ + Match: "/.*/", + }}, + } + } return framework.Server.VStream(ctx, &framework.Target, pos, filter, func(evs []*binlogdatapb.VEvent) error { + t.Logf("Received events: %v", evs) select { case ch <- evs: case <-ctx.Done(): diff --git a/go/vt/vttablet/tabletserver/vstreamer/engine.go b/go/vt/vttablet/tabletserver/vstreamer/engine.go index b9020fb69b1..b24bb6c9c02 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/engine.go +++ b/go/vt/vttablet/tabletserver/vstreamer/engine.go @@ -17,10 +17,14 @@ limitations under the License. package vstreamer import ( + "bytes" "context" + "encoding/json" "errors" + "net/http" "sync" + "vitess.io/vitess/go/acl" "vitess.io/vitess/go/mysql" "vitess.io/vitess/go/stats" "vitess.io/vitess/go/vt/dbconfigs" @@ -34,7 +38,11 @@ import ( vschemapb "vitess.io/vitess/go/vt/proto/vschema" ) -var vschemaErrors = stats.NewCounter("VSchemaErrors", "Count of VSchema errors") +var ( + once sync.Once + vschemaErrors *stats.Counter + vschemaUpdates *stats.Counter +) // Engine is the engine for handling vseplication streaming requests. type Engine struct { @@ -65,12 +73,24 @@ type Engine struct { // NewEngine creates a new Engine. func NewEngine(ts srvtopo.Server, se *schema.Engine) *Engine { - return &Engine{ + vse := &Engine{ streamers: make(map[int]*vstreamer), kschema: &vindexes.KeyspaceSchema{}, ts: ts, se: se, } + once.Do(func() { + vschemaErrors = stats.NewCounter("VSchemaErrors", "Count of VSchema errors") + vschemaUpdates = stats.NewCounter("VSchemaUpdates", "Count of VSchema updates. Does not include errors") + http.Handle("/debug/vschema", vse) + }) + return vse +} + +func (vse *Engine) vschema() *vindexes.KeyspaceSchema { + vse.mu.Lock() + defer vse.mu.Unlock() + return vse.kschema } // InitDBConfig performs saves the required info from dbconfigs for future use. @@ -148,6 +168,27 @@ func (vse *Engine) Stream(ctx context.Context, startPos mysql.Position, filter * return streamer.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 { + acl.SendError(response, err) + return + } + response.Header().Set("Content-Type", "application/json; charset=utf-8") + vs := vse.vschema() + if vs == nil || vs.Keyspace == nil { + response.Write([]byte("{}")) + } + b, err := json.MarshalIndent(vs, "", " ") + if err != nil { + response.Write([]byte(err.Error())) + return + } + buf := bytes.NewBuffer(nil) + json.HTMLEscape(buf, b) + response.Write(buf.Bytes()) +} + func (vse *Engine) setWatch() { // WatchSrvVSchema does not return until the inner func has been called at least once. vse.ts.WatchSrvVSchema(context.TODO(), vse.cell, func(v *vschemapb.SrvVSchema, err error) { @@ -161,19 +202,30 @@ func (vse *Engine) setWatch() { return } case topo.IsErrType(err, topo.NoNode): - kschema = &vindexes.KeyspaceSchema{} + // No-op. default: log.Errorf("Error fetching vschema %s: %v", vse.keyspace, err) vschemaErrors.Add(1) return } + if kschema == nil { + kschema = &vindexes.KeyspaceSchema{ + Keyspace: &vindexes.Keyspace{ + Name: vse.keyspace, + }, + } + } + // Broadcast the change to all streamers. vse.mu.Lock() defer vse.mu.Unlock() vse.kschema = kschema + b, _ := json.MarshalIndent(kschema, "", " ") + log.Infof("Updated KSchema: %s", b) for _, s := range vse.streamers { s.SetKSchema(kschema) } + vschemaUpdates.Add(1) }) } diff --git a/go/vt/vttablet/tabletserver/vstreamer/planbuilder.go b/go/vt/vttablet/tabletserver/vstreamer/planbuilder.go index f4c9f6c6c24..06c85b42ab6 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/planbuilder.go +++ b/go/vt/vttablet/tabletserver/vstreamer/planbuilder.go @@ -200,7 +200,7 @@ func buildTablePlan(ti *Table, kschema *vindexes.KeyspaceSchema, query string) ( if fromTable.IsEmpty() { return nil, fmt.Errorf("unexpected: %v", sqlparser.String(sel)) } - if fromTable.String() == ti.Name { + if fromTable.String() != ti.Name { return nil, fmt.Errorf("unexpected: select expression table %v does not match the table entry name %s", sqlparser.String(fromTable), ti.Name) } diff --git a/go/vt/vttablet/tabletserver/vstreamer/vstreamer.go b/go/vt/vttablet/tabletserver/vstreamer/vstreamer.go index b0bbf8572be..128a63ad30f 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/vstreamer.go +++ b/go/vt/vttablet/tabletserver/vstreamer/vstreamer.go @@ -110,8 +110,10 @@ func (vs *vstreamer) Stream() error { func (vs *vstreamer) parseEvents(ctx context.Context, events <-chan mysql.BinlogEvent) error { // bufferAndTransmit uses bufferedEvents and curSize to buffer events. - var bufferedEvents []*binlogdatapb.VEvent - var curSize int + var ( + bufferedEvents []*binlogdatapb.VEvent + curSize int + ) bufferAndTransmit := func(vevent *binlogdatapb.VEvent) error { switch vevent.Type { case binlogdatapb.VEventType_GTID, binlogdatapb.VEventType_BEGIN: @@ -306,8 +308,8 @@ func (vs *vstreamer) parseEvent(ev mysql.BinlogEvent) ([]*binlogdatapb.VEvent, e // If so, an update will be treated as delete on one shard // and insert on the other. id := ev.TableID(vs.format) - plan, ok := vs.plans[id] - if !ok { + plan := vs.plans[id] + if plan == nil { return nil, nil } rows, err := ev.Rows(vs.format, plan.Table.TableMap) @@ -336,13 +338,15 @@ func (vs *vstreamer) parseEvent(ev mysql.BinlogEvent) ([]*binlogdatapb.VEvent, e } rowChanges = append(rowChanges, rowChange) } - vevents = append(vevents, &binlogdatapb.VEvent{ - Type: binlogdatapb.VEventType_ROW, - RowEvent: &binlogdatapb.RowEvent{ - TableName: plan.Table.Name, - RowChanges: rowChanges, - }, - }) + if len(rowChanges) != 0 { + vevents = append(vevents, &binlogdatapb.VEvent{ + Type: binlogdatapb.VEventType_ROW, + RowEvent: &binlogdatapb.RowEvent{ + TableName: plan.Table.Name, + RowChanges: rowChanges, + }, + }) + } } return vevents, nil } From 155211762f55e3f272bd4d58a4b23159dbbcac90 Mon Sep 17 00:00:00 2001 From: Sugu Sougoumarane Date: Tue, 1 Jan 2019 14:13:23 -0800 Subject: [PATCH 026/115] vreplication: moved tests into vstreamer dir Also added more tests Signed-off-by: Sugu Sougoumarane --- .../vttablet/tabletserver/vstreamer/engine.go | 12 +- .../vstreamer/{endtoend => }/engine_test.go | 37 ++- .../vstreamer/{endtoend => }/main_test.go | 45 ++- .../tabletserver/vstreamer/vstreamer.go | 11 +- .../{endtoend => }/vstreamer_test.go | 256 +++++++++++++++--- 5 files changed, 293 insertions(+), 68 deletions(-) rename go/vt/vttablet/tabletserver/vstreamer/{endtoend => }/engine_test.go (77%) rename go/vt/vttablet/tabletserver/vstreamer/{endtoend => }/main_test.go (76%) rename go/vt/vttablet/tabletserver/vstreamer/{endtoend => }/vstreamer_test.go (62%) diff --git a/go/vt/vttablet/tabletserver/vstreamer/engine.go b/go/vt/vttablet/tabletserver/vstreamer/engine.go index b24bb6c9c02..88a513b02ee 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/engine.go +++ b/go/vt/vttablet/tabletserver/vstreamer/engine.go @@ -87,12 +87,6 @@ func NewEngine(ts srvtopo.Server, se *schema.Engine) *Engine { return vse } -func (vse *Engine) vschema() *vindexes.KeyspaceSchema { - vse.mu.Lock() - defer vse.mu.Unlock() - return vse.kschema -} - // InitDBConfig performs saves the required info from dbconfigs for future use. func (vse *Engine) InitDBConfig(dbcfgs *dbconfigs.DBConfigs) { vse.cp = dbcfgs.DbaWithDB() @@ -131,6 +125,12 @@ func (vse *Engine) Close() { vse.wg.Wait() } +func (vse *Engine) vschema() *vindexes.KeyspaceSchema { + vse.mu.Lock() + defer vse.mu.Unlock() + return vse.kschema +} + // Stream starts a new stream. func (vse *Engine) Stream(ctx context.Context, startPos mysql.Position, filter *binlogdatapb.Filter, send func([]*binlogdatapb.VEvent) error) error { // Ensure kschema is initialized and the watcher is started. diff --git a/go/vt/vttablet/tabletserver/vstreamer/endtoend/engine_test.go b/go/vt/vttablet/tabletserver/vstreamer/engine_test.go similarity index 77% rename from go/vt/vttablet/tabletserver/vstreamer/endtoend/engine_test.go rename to go/vt/vttablet/tabletserver/vstreamer/engine_test.go index 4a3276c2503..d23ce11fe13 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/endtoend/engine_test.go +++ b/go/vt/vttablet/tabletserver/vstreamer/engine_test.go @@ -17,12 +17,12 @@ limitations under the License. package vstreamer import ( + "encoding/json" "testing" + "time" "golang.org/x/net/context" - "vitess.io/vitess/go/vt/vttablet/endtoend/framework" - binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" ) @@ -61,21 +61,12 @@ func TestUpdateVSchema(t *testing.T) { _ = startStream(ctx, t, filter) cancel() - startCount := framework.FetchInt(framework.DebugVars(), "VSchemaUpdates") - if startCount == 0 { - t.Errorf("startCount: %d, want non-zero", startCount) - } + startCount := expectUpdateCount(t, 1) if err := setVSchema(shardedVSchema); err != nil { t.Fatal(err) } - - // Looks like memorytopo instantly transmits the watch. - // No need to wait for vschema to propagate. - endCount := framework.FetchInt(framework.DebugVars(), "VSchemaUpdates") - if endCount != startCount+1 { - t.Errorf("endCount: %d, want %d", endCount, startCount+1) - } + expectUpdateCount(t, startCount+1) want := `{ "sharded": true, @@ -108,7 +99,25 @@ func TestUpdateVSchema(t *testing.T) { "hash": {} } }` - if got := framework.FetchURL("/debug/vschema"); got != want { + b, err := json.MarshalIndent(engine.vschema(), "", " ") + if err != nil { + t.Fatal(err) + } + if got := string(b); got != want { t.Errorf("vschema:\n%s, want:\n%s", got, want) } } + +func expectUpdateCount(t *testing.T, wantCount int64) int64 { + for i := 0; i < 10; i++ { + gotCount := vschemaUpdates.Get() + if gotCount >= wantCount { + return gotCount + } + if i == 9 { + t.Fatalf("update count: %d, want %d", gotCount, wantCount) + } + time.Sleep(10 * time.Millisecond) + } + panic("unreachable") +} diff --git a/go/vt/vttablet/tabletserver/vstreamer/endtoend/main_test.go b/go/vt/vttablet/tabletserver/vstreamer/main_test.go similarity index 76% rename from go/vt/vttablet/tabletserver/vstreamer/endtoend/main_test.go rename to go/vt/vttablet/tabletserver/vstreamer/main_test.go index 9fc8bce94f9..45f39071877 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/endtoend/main_test.go +++ b/go/vt/vttablet/tabletserver/vstreamer/main_test.go @@ -26,11 +26,15 @@ import ( "golang.org/x/net/context" "vitess.io/vitess/go/json2" "vitess.io/vitess/go/mysql" + "vitess.io/vitess/go/vt/dbconfigs" "vitess.io/vitess/go/vt/logutil" + "vitess.io/vitess/go/vt/mysqlctl" + "vitess.io/vitess/go/vt/srvtopo" "vitess.io/vitess/go/vt/topo" "vitess.io/vitess/go/vt/topo/memorytopo" "vitess.io/vitess/go/vt/topotools" - "vitess.io/vitess/go/vt/vttablet/endtoend/framework" + "vitess.io/vitess/go/vt/vttablet/tabletserver/connpool" + "vitess.io/vitess/go/vt/vttablet/tabletserver/schema" "vitess.io/vitess/go/vt/vttablet/tabletserver/tabletenv" "vitess.io/vitess/go/vt/vttest" @@ -40,6 +44,8 @@ import ( ) var ( + engine *Engine + mysqld *mysqlctl.Mysqld connParams mysql.ConnParams connAppDebugParams mysql.ConnParams topoServ *topo.Server @@ -47,6 +53,12 @@ var ( cells = []string{"cell1"} ) +type checker struct{} + +var _ = connpool.MySQLChecker(checker{}) + +func (checker) CheckMySQL() {} + func TestMain(m *testing.M) { flag.Parse() // Do not remove this comment, import into google3 depends on it tabletenv.Init() @@ -83,26 +95,35 @@ func TestMain(m *testing.M) { defer cluster.TearDown() // initTopo initializes topoServ. - if err := initTopo(); err != nil { - fmt.Fprintf(os.Stderr, "topo init failed: %v\n", err) - return 1 - } - config := tabletenv.DefaultQsConfig - config.EnableAutoCommit = true - - connParams = cluster.MySQLConnParams() - connAppDebugParams = cluster.MySQLAppDebugConnParams() - if err := framework.StartFullServer(topoServ, config, connParams, connAppDebugParams, cluster.DbName(), keyspaceName, "cell1-100"); err != nil { + if err := initEngine(&cluster); err != nil { fmt.Fprintf(os.Stderr, "%v", err) return 1 } - defer framework.StopServer() + defer engine.Close() return m.Run() }() os.Exit(exitCode) } +func initEngine(cluster *vttest.LocalCluster) error { + if err := initTopo(); err != nil { + return err + } + + se := schema.NewEngine(checker{}, tabletenv.DefaultQsConfig) + srvTopoServer := srvtopo.NewResilientServer(topoServ, "TestTopo") + engine = NewEngine(srvTopoServer, se) + + dbcfgs := dbconfigs.NewTestDBConfigs(cluster.MySQLConnParams(), cluster.MySQLAppDebugConnParams(), cluster.DbName()) + mysqld = mysqlctl.NewMysqld(dbcfgs) + se.InitDBConfig(dbcfgs) + engine.InitDBConfig(dbcfgs) + + engine.Open(keyspaceName, cells[0]) + return nil +} + func initTopo() error { ctx := context.Background() diff --git a/go/vt/vttablet/tabletserver/vstreamer/vstreamer.go b/go/vt/vttablet/tabletserver/vstreamer/vstreamer.go index 128a63ad30f..c167990d557 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/vstreamer.go +++ b/go/vt/vttablet/tabletserver/vstreamer/vstreamer.go @@ -32,8 +32,7 @@ import ( binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" ) -// PacketSize is exported for allowing tests to change this value. -var PacketSize = flag.Int("vstream_packet_size", 10000, "Suggested packet size for VReplication streamer. This is used only as a recommendation. The actual packet size may be more or less than this amount.") +var packetSize = flag.Int("vstream_packet_size", 10000, "Suggested packet size for VReplication streamer. This is used only as a recommendation. The actual packet size may be more or less than this amount.") type vstreamer struct { ctx context.Context @@ -114,6 +113,11 @@ func (vs *vstreamer) parseEvents(ctx context.Context, events <-chan mysql.Binlog bufferedEvents []*binlogdatapb.VEvent curSize int ) + // Buffering only takes row lenghts into consideration. + // Length of other events is considered negligible. + // If a new row event causes the packet size to be exceeded, + // all existing rows are sent without the new row. + // If a single row exceeds the packet size, it will be in its own packet. bufferAndTransmit := func(vevent *binlogdatapb.VEvent) error { switch vevent.Type { case binlogdatapb.VEventType_GTID, binlogdatapb.VEventType_BEGIN: @@ -139,12 +143,13 @@ func (vs *vstreamer) parseEvents(ctx context.Context, events <-chan mysql.Binlog newSize += len(rowChange.After.Values) } } - if curSize+newSize > *PacketSize { + if curSize+newSize > *packetSize { vevents := bufferedEvents bufferedEvents = []*binlogdatapb.VEvent{vevent} curSize = newSize return vs.send(vevents) } + curSize += newSize bufferedEvents = append(bufferedEvents, vevent) } return nil diff --git a/go/vt/vttablet/tabletserver/vstreamer/endtoend/vstreamer_test.go b/go/vt/vttablet/tabletserver/vstreamer/vstreamer_test.go similarity index 62% rename from go/vt/vttablet/tabletserver/vstreamer/endtoend/vstreamer_test.go rename to go/vt/vttablet/tabletserver/vstreamer/vstreamer_test.go index 9bd578437e2..46bce5d5b23 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/endtoend/vstreamer_test.go +++ b/go/vt/vttablet/tabletserver/vstreamer/vstreamer_test.go @@ -24,7 +24,6 @@ import ( "golang.org/x/net/context" "vitess.io/vitess/go/mysql" - "vitess.io/vitess/go/vt/vttablet/endtoend/framework" binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" ) @@ -43,12 +42,14 @@ func TestStatements(t *testing.T) { "drop table stream1", "drop table stream2", }) - framework.Server.ReloadSchema(context.Background()) + engine.se.Reload(context.Background()) testcases := []testcase{{ input: []string{ + "begin", "insert into stream1 values (1, 'aaa')", "update stream1 set val='bbb' where id = 1", + "commit", }, // MySQL issues GTID->BEGIN. // MariaDB issues BEGIN->GTID. @@ -76,10 +77,12 @@ func TestStatements(t *testing.T) { }, { // Multiple tables, and multiple rows changed per statement. input: []string{ + "begin", "insert into stream1 values (2, 'bbb')", "insert into stream2 values (1, 'aaa')", "update stream1 set val='ccc'", "delete from stream1", + "commit", }, output: [][]string{{ `gtid|begin`, @@ -132,7 +135,7 @@ func TestRegexp(t *testing.T) { "drop table yes_stream", "drop table no_stream", }) - framework.Server.ReloadSchema(context.Background()) + engine.se.Reload(context.Background()) filter := &binlogdatapb.Filter{ Rules: []*binlogdatapb.Rule{{ @@ -142,10 +145,12 @@ func TestRegexp(t *testing.T) { testcases := []testcase{{ input: []string{ + "begin", "insert into yes_stream values (1, 'aaa')", "insert into no_stream values (2, 'bbb')", "update yes_stream set val='bbb' where id = 1", "update no_stream set val='bbb' where id = 2", + "commit", }, output: [][]string{{ `gtid|begin`, @@ -165,7 +170,7 @@ func TestREKeyrange(t *testing.T) { defer execStatements(t, []string{ "drop table t1", }) - framework.Server.ReloadSchema(context.Background()) + engine.se.Reload(context.Background()) ctx, cancel := context.WithCancel(context.Background()) defer cancel() @@ -186,6 +191,7 @@ func TestREKeyrange(t *testing.T) { // 1, 2, 3 and 5 are in shard -80. // 4 and 6 are in shard 80-. input := []string{ + "begin", "insert into t1 values (1, 4, 'aaa')", "insert into t1 values (4, 1, 'bbb')", // Stay in shard. @@ -194,8 +200,9 @@ func TestREKeyrange(t *testing.T) { "update t1 set id1 = 6 where id1 = 2", // Move from 80- to -80. "update t1 set id1 = 3 where id1 = 4", + "commit", } - execTransaction(t, input) + execStatements(t, input) expectLog(ctx, t, input, ch, [][]string{{ `gtid|begin`, `gtid|begin`, @@ -231,10 +238,12 @@ func TestREKeyrange(t *testing.T) { // Only the first insert should be sent. input = []string{ + "begin", "insert into t1 values (4, 1, 'aaa')", "insert into t1 values (1, 4, 'aaa')", + "commit", } - execTransaction(t, input) + execStatements(t, input) expectLog(ctx, t, input, ch, [][]string{{ `gtid|begin`, `gtid|begin`, @@ -250,7 +259,7 @@ func TestSelectFilter(t *testing.T) { defer execStatements(t, []string{ "drop table t1", }) - framework.Server.ReloadSchema(context.Background()) + engine.se.Reload(context.Background()) filter := &binlogdatapb.Filter{ Rules: []*binlogdatapb.Rule{{ @@ -261,8 +270,10 @@ func TestSelectFilter(t *testing.T) { testcases := []testcase{{ input: []string{ + "begin", "insert into t1 values (4, 1, 'aaa')", "insert into t1 values (2, 4, 'aaa')", + "commit", }, // MySQL issues GTID->BEGIN. // MariaDB issues BEGIN->GTID. @@ -281,7 +292,7 @@ func TestDDLAddColumn(t *testing.T) { defer execStatement(t, "drop table ddl_test1") // Record position before the next few statements. - pos, err := framework.Mysqld.MasterPosition() + pos, err := mysqld.MasterPosition() if err != nil { t.Fatal(err) } @@ -291,7 +302,7 @@ func TestDDLAddColumn(t *testing.T) { "alter table ddl_test1 add column val2 varbinary(128)", "insert into ddl_test1 values(2, 'bbb', 'ccc')", }) - framework.Server.ReloadSchema(context.Background()) + engine.se.Reload(context.Background()) ctx, cancel := context.WithCancel(context.Background()) defer cancel() @@ -327,7 +338,7 @@ func TestDDLDropColumn(t *testing.T) { defer execStatement(t, "drop table ddl_test2") // Record position before the next few statements. - pos, err := framework.Mysqld.MasterPosition() + pos, err := mysqld.MasterPosition() if err != nil { t.Fatal(err) } @@ -337,7 +348,7 @@ func TestDDLDropColumn(t *testing.T) { "alter table ddl_test2 drop column val2", "insert into ddl_test2 values(2, 'bbb')", }) - framework.Server.ReloadSchema(context.Background()) + engine.se.Reload(context.Background()) ctx, cancel := context.WithCancel(context.Background()) defer cancel() @@ -355,7 +366,203 @@ func TestDDLDropColumn(t *testing.T) { } } +func TestBuffering(t *testing.T) { + savedSize := *packetSize + *packetSize = 10 + defer func() { *packetSize = savedSize }() + + execStatement(t, "create table packet_test(id int, val varbinary(128), primary key(id))") + defer execStatement(t, "drop table packet_test") + engine.se.Reload(context.Background()) + + testcases := []testcase{{ + // All rows in one packet. + input: []string{ + "begin", + "insert into packet_test values (1, '123')", + "insert into packet_test values (2, '456')", + "commit", + }, + output: [][]string{{ + `gtid|begin`, + `gtid|begin`, + `type:ROW row_event: > > `, + `type:ROW row_event: > > `, + `commit`, + }}, + }, { + // A new row causes packet size to be exceeded. + // Also test deletes + input: []string{ + "begin", + "insert into packet_test values (3, '123456')", + "insert into packet_test values (4, '789012')", + "delete from packet_test where id=3", + "delete from packet_test where id=4", + "commit", + }, + output: [][]string{{ + `gtid|begin`, + `gtid|begin`, + `type:ROW row_event: > > `, + }, { + `type:ROW row_event: > > `, + }, { + `type:ROW row_event: > > `, + }, { + `type:ROW row_event: > > `, + `commit`, + }}, + }, { + // A single row is itself bigger than the packet size. + input: []string{ + "begin", + "insert into packet_test values (5, '123456')", + "insert into packet_test values (6, '12345678901')", + "insert into packet_test values (7, '23456')", + "commit", + }, + output: [][]string{{ + `gtid|begin`, + `gtid|begin`, + `type:ROW row_event: > > `, + }, { + `type:ROW row_event: > > `, + }, { + `type:ROW row_event: > > `, + `commit`, + }}, + }, { + // An update packet is bigger because it has a before and after image. + input: []string{ + "begin", + "insert into packet_test values (8, '123')", + "update packet_test set val='456' where id=8", + "commit", + }, + output: [][]string{{ + `gtid|begin`, + `gtid|begin`, + `type:ROW row_event: > > `, + }, { + `type:ROW row_event: after: > > `, + `commit`, + }}, + }, { + // DDL is in its own packet + input: []string{ + "alter table packet_test change val val varchar(128)", + }, + output: [][]string{{ + `gtid`, + `type:DDL ddl:"alter table packet_test change val val varchar(128)" `, + }}, + }} + runCases(t, nil, testcases) +} + +func TestTypes(t *testing.T) { + // Modeled after vttablet endtoend compatibility tests. + 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))", + "create table vitess_fracts(id int, deci decimal(5,2), num numeric(5,2), f float, d double, primary key(id))", + "create table vitess_strings(vb varbinary(16), c char(16), vc varchar(16), b binary(4), tb tinyblob, bl blob, ttx tinytext, tx text, en enum('a','b'), s set('a','b'), primary key(vb))", + "create table vitess_misc(id int, b bit(8), d date, dt datetime, t time, g geometry, primary key(id))", + "create table vitess_json(id int default 1, val json, primary key(id))", + }) + defer execStatements(t, []string{ + "drop table vitess_ints", + "drop table vitess_fracts", + "drop table vitess_strings", + "drop table vitess_misc", + "drop table vitess_json", + }) + engine.se.Reload(context.Background()) + + testcases := []testcase{{ + input: []string{ + "insert into vitess_ints values(-128, 255, -32768, 65535, -8388608, 16777215, -2147483648, 4294967295, -9223372036854775808, 18446744073709551615, 2012)", + }, + output: [][]string{{ + `gtid|begin`, + `gtid|begin`, + `type:ROW row_event: > > `, + `commit`, + }}, + }, { + input: []string{ + "insert into vitess_fracts values(1, 1.99, 2.99, 3.99, 4.99)", + }, + output: [][]string{{ + `gtid|begin`, + `gtid|begin`, + `type:ROW row_event: > > `, + `commit`, + }}, + }, { + // TODO(sougou): validate that binary and char data generate correct DMLs on the other end. + input: []string{ + "insert into vitess_strings values('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'a', 'a,b')", + }, + output: [][]string{{ + `gtid|begin`, + `gtid|begin`, + `type:ROW row_event: > > `, + `commit`, + }}, + }, { + // TODO(sougou): validate that the geometry value generates the correct DMLs on the other end. + input: []string{ + "insert into vitess_misc values(1, '\x01', '2012-01-01', '2012-01-01 15:45:45', '15:45:45', point(1, 2))", + }, + output: [][]string{{ + `gtid|begin`, + `gtid|begin`, + `type:ROW row_event: > > `, + `commit`, + }}, + }, { + input: []string{ + `insert into vitess_json values(1, '{"foo": "bar"}')`, + }, + output: [][]string{{ + `gtid|begin`, + `gtid|begin`, + `type:ROW row_event: > > `, + `commit`, + }}, + }} + runCases(t, nil, testcases) +} + func runCases(t *testing.T, filter *binlogdatapb.Filter, testcases []testcase) { + t.Helper() ctx, cancel := context.WithCancel(context.Background()) defer cancel() @@ -364,7 +571,7 @@ func runCases(t *testing.T, filter *binlogdatapb.Filter, testcases []testcase) { for _, tcase := range testcases { switch input := tcase.input.(type) { case []string: - execTransaction(t, input) + execStatements(t, input) case string: execStatement(t, input) default: @@ -419,7 +626,7 @@ 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, err := framework.Mysqld.MasterPosition() + pos, err := mysqld.MasterPosition() if err != nil { t.Fatal(err) } @@ -442,7 +649,7 @@ func vstream(ctx context.Context, t *testing.T, pos mysql.Position, filter *binl }}, } } - return framework.Server.VStream(ctx, &framework.Target, pos, filter, func(evs []*binlogdatapb.VEvent) error { + return engine.Stream(ctx, pos, filter, func(evs []*binlogdatapb.VEvent) error { t.Logf("Received events: %v", evs) select { case ch <- evs: @@ -453,33 +660,16 @@ func vstream(ctx context.Context, t *testing.T, pos mysql.Position, filter *binl }) } -func execTransaction(t *testing.T, queries []string) { - t.Helper() - - client := framework.NewClient() - if err := client.Begin(false); err != nil { - t.Fatal(err) - } - for _, query := range queries { - if _, err := client.Execute(query, nil); err != nil { - t.Fatal(err) - } - } - if err := client.Commit(); err != nil { - t.Fatal(err) - } -} - func execStatement(t *testing.T, query string) { t.Helper() - if err := framework.Mysqld.ExecuteSuperQuery(context.Background(), query); err != nil { + if err := mysqld.ExecuteSuperQuery(context.Background(), query); err != nil { t.Fatal(err) } } func execStatements(t *testing.T, queries []string) { t.Helper() - if err := framework.Mysqld.ExecuteSuperQueryList(context.Background(), queries); err != nil { + if err := mysqld.ExecuteSuperQueryList(context.Background(), queries); err != nil { t.Fatal(err) } } From 6b1190370943f9a934a11d058d32a4e84a8fa68b Mon Sep 17 00:00:00 2001 From: Sugu Sougoumarane Date: Tue, 1 Jan 2019 14:35:04 -0800 Subject: [PATCH 027/115] vreplication: handle singleton and mariadb issues Signed-off-by: Sugu Sougoumarane --- .../vttablet/tabletserver/vstreamer/engine.go | 2 +- .../tabletserver/vstreamer/vstreamer_test.go | 20 ++++++++++++++++--- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/go/vt/vttablet/tabletserver/vstreamer/engine.go b/go/vt/vttablet/tabletserver/vstreamer/engine.go index 88a513b02ee..c46c14d5b5a 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/engine.go +++ b/go/vt/vttablet/tabletserver/vstreamer/engine.go @@ -82,7 +82,7 @@ func NewEngine(ts srvtopo.Server, se *schema.Engine) *Engine { once.Do(func() { vschemaErrors = stats.NewCounter("VSchemaErrors", "Count of VSchema errors") vschemaUpdates = stats.NewCounter("VSchemaUpdates", "Count of VSchema updates. Does not include errors") - http.Handle("/debug/vschema", vse) + http.Handle("/debug/tablet_vschema", vse) }) return vse } diff --git a/go/vt/vttablet/tabletserver/vstreamer/vstreamer_test.go b/go/vt/vttablet/tabletserver/vstreamer/vstreamer_test.go index 46bce5d5b23..37f5af140cb 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/vstreamer_test.go +++ b/go/vt/vttablet/tabletserver/vstreamer/vstreamer_test.go @@ -468,14 +468,12 @@ func TestTypes(t *testing.T) { "create table vitess_fracts(id int, deci decimal(5,2), num numeric(5,2), f float, d double, primary key(id))", "create table vitess_strings(vb varbinary(16), c char(16), vc varchar(16), b binary(4), tb tinyblob, bl blob, ttx tinytext, tx text, en enum('a','b'), s set('a','b'), primary key(vb))", "create table vitess_misc(id int, b bit(8), d date, dt datetime, t time, g geometry, primary key(id))", - "create table vitess_json(id int default 1, val json, primary key(id))", }) defer execStatements(t, []string{ "drop table vitess_ints", "drop table vitess_fracts", "drop table vitess_strings", "drop table vitess_misc", - "drop table vitess_json", }) engine.se.Reload(context.Background()) @@ -547,7 +545,23 @@ func TestTypes(t *testing.T) { `" > > > `, `commit`, }}, - }, { + }} + runCases(t, nil, testcases) +} + +func TestJSON(t *testing.T) { + // JSON is supported only after mysql57. + if err := mysqld.ExecuteSuperQuery(context.Background(), "create table vitess_json(id int default 1, val json, primary key(id))"); err != nil { + // If it's a syntax error, MySQL is an older version. Skip this test. + if strings.Contains(err.Error(), "syntax") { + return + } + t.Fatal(err) + } + defer execStatement(t, "drop table vitess_json") + engine.se.Reload(context.Background()) + + testcases := []testcase{{ input: []string{ `insert into vitess_json values(1, '{"foo": "bar"}')`, }, From 6ff51d39cf7092239dcd70c38beff89ea97bc63d Mon Sep 17 00:00:00 2001 From: Sugu Sougoumarane Date: Tue, 1 Jan 2019 23:24:40 -0800 Subject: [PATCH 028/115] vreplication: tests are done Also had to added transmission of field info, which may come in handy for encoding the values on the player end. Signed-off-by: Sugu Sougoumarane --- go/vt/proto/binlogdata/binlogdata.pb.go | 239 +++++++---- .../tabletserver/vstreamer/engine_test.go | 4 + .../tabletserver/vstreamer/main_test.go | 7 +- .../tabletserver/vstreamer/planbuilder.go | 36 +- .../vstreamer/planbuilder_test.go | 383 ++++++++++++++++++ .../tabletserver/vstreamer/vstreamer.go | 24 +- .../tabletserver/vstreamer/vstreamer_test.go | 299 +++++++++++++- proto/binlogdata.proto | 7 + py/vtproto/binlogdata_pb2.py | 78 +++- 9 files changed, 956 insertions(+), 121 deletions(-) create mode 100644 go/vt/vttablet/tabletserver/vstreamer/planbuilder_test.go diff --git a/go/vt/proto/binlogdata/binlogdata.pb.go b/go/vt/proto/binlogdata/binlogdata.pb.go index de20633f792..1a3510d1bc5 100644 --- a/go/vt/proto/binlogdata/binlogdata.pb.go +++ b/go/vt/proto/binlogdata/binlogdata.pb.go @@ -39,6 +39,7 @@ const ( VEventType_SET VEventType = 10 VEventType_OTHER VEventType = 11 VEventType_ROW VEventType = 12 + VEventType_FIELD VEventType = 13 ) var VEventType_name = map[int32]string{ @@ -55,6 +56,7 @@ var VEventType_name = map[int32]string{ 10: "SET", 11: "OTHER", 12: "ROW", + 13: "FIELD", } var VEventType_value = map[string]int32{ "UNKNOWN": 0, @@ -70,13 +72,14 @@ var VEventType_value = map[string]int32{ "SET": 10, "OTHER": 11, "ROW": 12, + "FIELD": 13, } func (x VEventType) String() string { return proto.EnumName(VEventType_name, int32(x)) } func (VEventType) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_binlogdata_8c20ffb2cc31e3c4, []int{0} + return fileDescriptor_binlogdata_e1edbb575eea20d0, []int{0} } type BinlogTransaction_Statement_Category int32 @@ -124,7 +127,7 @@ 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_8c20ffb2cc31e3c4, []int{1, 0, 0} + return fileDescriptor_binlogdata_e1edbb575eea20d0, []int{1, 0, 0} } // Charset is the per-statement charset info from a QUERY_EVENT binlog entry. @@ -144,7 +147,7 @@ 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_8c20ffb2cc31e3c4, []int{0} + return fileDescriptor_binlogdata_e1edbb575eea20d0, []int{0} } func (m *Charset) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Charset.Unmarshal(m, b) @@ -201,7 +204,7 @@ 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_8c20ffb2cc31e3c4, []int{1} + return fileDescriptor_binlogdata_e1edbb575eea20d0, []int{1} } func (m *BinlogTransaction) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_BinlogTransaction.Unmarshal(m, b) @@ -251,7 +254,7 @@ 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_8c20ffb2cc31e3c4, []int{1, 0} + return fileDescriptor_binlogdata_e1edbb575eea20d0, []int{1, 0} } func (m *BinlogTransaction_Statement) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_BinlogTransaction_Statement.Unmarshal(m, b) @@ -309,7 +312,7 @@ 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_8c20ffb2cc31e3c4, []int{2} + return fileDescriptor_binlogdata_e1edbb575eea20d0, []int{2} } func (m *StreamKeyRangeRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_StreamKeyRangeRequest.Unmarshal(m, b) @@ -362,7 +365,7 @@ 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_8c20ffb2cc31e3c4, []int{3} + return fileDescriptor_binlogdata_e1edbb575eea20d0, []int{3} } func (m *StreamKeyRangeResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_StreamKeyRangeResponse.Unmarshal(m, b) @@ -406,7 +409,7 @@ 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_8c20ffb2cc31e3c4, []int{4} + return fileDescriptor_binlogdata_e1edbb575eea20d0, []int{4} } func (m *StreamTablesRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_StreamTablesRequest.Unmarshal(m, b) @@ -459,7 +462,7 @@ 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_8c20ffb2cc31e3c4, []int{5} + return fileDescriptor_binlogdata_e1edbb575eea20d0, []int{5} } func (m *StreamTablesResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_StreamTablesResponse.Unmarshal(m, b) @@ -504,7 +507,7 @@ 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_8c20ffb2cc31e3c4, []int{6} + return fileDescriptor_binlogdata_e1edbb575eea20d0, []int{6} } func (m *Rule) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Rule.Unmarshal(m, b) @@ -551,7 +554,7 @@ 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_8c20ffb2cc31e3c4, []int{7} + return fileDescriptor_binlogdata_e1edbb575eea20d0, []int{7} } func (m *Filter) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Filter.Unmarshal(m, b) @@ -604,7 +607,7 @@ 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_8c20ffb2cc31e3c4, []int{8} + return fileDescriptor_binlogdata_e1edbb575eea20d0, []int{8} } func (m *BinlogSource) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_BinlogSource.Unmarshal(m, b) @@ -679,7 +682,7 @@ 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_8c20ffb2cc31e3c4, []int{9} + return fileDescriptor_binlogdata_e1edbb575eea20d0, []int{9} } func (m *RowChange) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_RowChange.Unmarshal(m, b) @@ -726,7 +729,7 @@ 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_8c20ffb2cc31e3c4, []int{10} + return fileDescriptor_binlogdata_e1edbb575eea20d0, []int{10} } func (m *RowEvent) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_RowEvent.Unmarshal(m, b) @@ -760,22 +763,69 @@ func (m *RowEvent) GetRowChanges() []*RowChange { return nil } +type FieldEvent struct { + TableName string `protobuf:"bytes,1,opt,name=table_name,json=tableName,proto3" json:"table_name,omitempty"` + Fields []*query.Field `protobuf:"bytes,2,rep,name=fields,proto3" json:"fields,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +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_e1edbb575eea20d0, []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_Size() int { + return xxx_messageInfo_FieldEvent.Size(m) +} +func (m *FieldEvent) XXX_DiscardUnknown() { + xxx_messageInfo_FieldEvent.DiscardUnknown(m) +} + +var xxx_messageInfo_FieldEvent proto.InternalMessageInfo + +func (m *FieldEvent) GetTableName() string { + if m != nil { + return m.TableName + } + return "" +} + +func (m *FieldEvent) GetFields() []*query.Field { + if m != nil { + return m.Fields + } + return nil +} + // VEvent represents a vstream event type VEvent struct { - Type VEventType `protobuf:"varint,1,opt,name=type,proto3,enum=binlogdata.VEventType" json:"type,omitempty"` - Gtid string `protobuf:"bytes,2,opt,name=gtid,proto3" json:"gtid,omitempty"` - Ddl string `protobuf:"bytes,3,opt,name=ddl,proto3" json:"ddl,omitempty"` - RowEvent *RowEvent `protobuf:"bytes,4,opt,name=row_event,json=rowEvent,proto3" json:"row_event,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + Type VEventType `protobuf:"varint,1,opt,name=type,proto3,enum=binlogdata.VEventType" json:"type,omitempty"` + Gtid string `protobuf:"bytes,2,opt,name=gtid,proto3" json:"gtid,omitempty"` + Ddl string `protobuf:"bytes,3,opt,name=ddl,proto3" json:"ddl,omitempty"` + RowEvent *RowEvent `protobuf:"bytes,4,opt,name=row_event,json=rowEvent,proto3" json:"row_event,omitempty"` + FieldEvent *FieldEvent `protobuf:"bytes,5,opt,name=field_event,json=fieldEvent,proto3" json:"field_event,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } 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_8c20ffb2cc31e3c4, []int{11} + return fileDescriptor_binlogdata_e1edbb575eea20d0, []int{12} } func (m *VEvent) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_VEvent.Unmarshal(m, b) @@ -823,6 +873,13 @@ func (m *VEvent) GetRowEvent() *RowEvent { return nil } +func (m *VEvent) GetFieldEvent() *FieldEvent { + if m != nil { + return m.FieldEvent + } + return nil +} + // VStreamRequest is the payload for VStream type VStreamRequest struct { Position string `protobuf:"bytes,1,opt,name=position,proto3" json:"position,omitempty"` @@ -836,7 +893,7 @@ 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_8c20ffb2cc31e3c4, []int{12} + return fileDescriptor_binlogdata_e1edbb575eea20d0, []int{13} } func (m *VStreamRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_VStreamRequest.Unmarshal(m, b) @@ -882,7 +939,7 @@ 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_8c20ffb2cc31e3c4, []int{13} + return fileDescriptor_binlogdata_e1edbb575eea20d0, []int{14} } func (m *VStreamResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_VStreamResponse.Unmarshal(m, b) @@ -922,6 +979,7 @@ func init() { proto.RegisterType((*BinlogSource)(nil), "binlogdata.BinlogSource") proto.RegisterType((*RowChange)(nil), "binlogdata.RowChange") proto.RegisterType((*RowEvent)(nil), "binlogdata.RowEvent") + proto.RegisterType((*FieldEvent)(nil), "binlogdata.FieldEvent") proto.RegisterType((*VEvent)(nil), "binlogdata.VEvent") proto.RegisterType((*VStreamRequest)(nil), "binlogdata.VStreamRequest") proto.RegisterType((*VStreamResponse)(nil), "binlogdata.VStreamResponse") @@ -929,69 +987,72 @@ func init() { proto.RegisterEnum("binlogdata.BinlogTransaction_Statement_Category", BinlogTransaction_Statement_Category_name, BinlogTransaction_Statement_Category_value) } -func init() { proto.RegisterFile("binlogdata.proto", fileDescriptor_binlogdata_8c20ffb2cc31e3c4) } - -var fileDescriptor_binlogdata_8c20ffb2cc31e3c4 = []byte{ - // 964 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x56, 0xcb, 0x6e, 0xe2, 0x56, - 0x18, 0x1e, 0x63, 0x63, 0xec, 0xdf, 0x69, 0xe6, 0xe4, 0xe4, 0x22, 0x14, 0x69, 0xa4, 0xc8, 0x8b, - 0x0e, 0x8d, 0x54, 0x98, 0xd2, 0xcb, 0xa6, 0xab, 0x00, 0x6e, 0xca, 0xc4, 0x81, 0xf4, 0xe0, 0xcc, - 0x54, 0xb3, 0xb1, 0x0c, 0x9c, 0x10, 0x14, 0xb0, 0x89, 0x7d, 0x48, 0xca, 0x43, 0x74, 0xd5, 0x07, - 0xe8, 0xba, 0x2f, 0xd2, 0x37, 0xe9, 0xae, 0x0f, 0x51, 0x9d, 0x8b, 0x0d, 0x64, 0xa4, 0x69, 0xba, - 0xe8, 0xee, 0xbf, 0x9d, 0xff, 0xf2, 0xfd, 0xbf, 0x3f, 0x00, 0x34, 0x9c, 0xc6, 0xb3, 0x64, 0x32, - 0x8e, 0x58, 0x54, 0x5f, 0xa4, 0x09, 0x4b, 0x30, 0xac, 0x2d, 0xc7, 0xce, 0xfd, 0x92, 0xa6, 0x2b, - 0xe9, 0x38, 0xde, 0x65, 0xc9, 0x22, 0x59, 0x07, 0xba, 0x97, 0x50, 0x69, 0xdf, 0x46, 0x69, 0x46, - 0x19, 0x3e, 0x02, 0x73, 0x34, 0x9b, 0xd2, 0x98, 0x55, 0xb5, 0x13, 0xad, 0x56, 0x26, 0x4a, 0xc3, - 0x18, 0x8c, 0x51, 0x12, 0xc7, 0xd5, 0x92, 0xb0, 0x0a, 0x99, 0xc7, 0x66, 0x34, 0x7d, 0xa0, 0x69, - 0x55, 0x97, 0xb1, 0x52, 0x73, 0xff, 0xd2, 0x61, 0xaf, 0x25, 0x4a, 0x07, 0x69, 0x14, 0x67, 0xd1, - 0x88, 0x4d, 0x93, 0x18, 0x9f, 0x03, 0x64, 0x2c, 0x62, 0x74, 0x4e, 0x63, 0x96, 0x55, 0xb5, 0x13, - 0xbd, 0xe6, 0x34, 0x5f, 0xd7, 0x37, 0x9a, 0xfe, 0xe8, 0x49, 0x7d, 0x90, 0xc7, 0x93, 0x8d, 0xa7, - 0xb8, 0x09, 0x0e, 0x7d, 0xa0, 0x31, 0x0b, 0x59, 0x72, 0x47, 0xe3, 0xaa, 0x71, 0xa2, 0xd5, 0x9c, - 0xe6, 0x5e, 0x5d, 0x0e, 0xe8, 0x71, 0x4f, 0xc0, 0x1d, 0x04, 0x68, 0x21, 0x1f, 0xff, 0x59, 0x02, - 0xbb, 0xc8, 0x86, 0x7d, 0xb0, 0x46, 0x11, 0xa3, 0x93, 0x24, 0x5d, 0x89, 0x31, 0x77, 0x9b, 0x6f, - 0x9e, 0xd9, 0x48, 0xbd, 0xad, 0xde, 0x91, 0x22, 0x03, 0xfe, 0x12, 0x2a, 0x23, 0x89, 0x9e, 0x40, - 0xc7, 0x69, 0xee, 0x6f, 0x26, 0x53, 0xc0, 0x92, 0x3c, 0x06, 0x23, 0xd0, 0xb3, 0xfb, 0x99, 0x80, - 0x6c, 0x87, 0x70, 0xd1, 0xfd, 0x43, 0x03, 0x2b, 0xcf, 0x8b, 0xf7, 0xe1, 0x65, 0xcb, 0x0f, 0xaf, - 0x7b, 0xc4, 0x6b, 0xf7, 0xcf, 0x7b, 0xdd, 0x0f, 0x5e, 0x07, 0xbd, 0xc0, 0x3b, 0x60, 0xb5, 0xfc, - 0xb0, 0xe5, 0x9d, 0x77, 0x7b, 0x48, 0xc3, 0x9f, 0x81, 0xdd, 0xf2, 0xc3, 0x76, 0xff, 0xf2, 0xb2, - 0x1b, 0xa0, 0x12, 0x7e, 0x09, 0x4e, 0xcb, 0x0f, 0x49, 0xdf, 0xf7, 0x5b, 0x67, 0xed, 0x0b, 0xa4, - 0xe3, 0x43, 0xd8, 0x6b, 0xf9, 0x61, 0xe7, 0xd2, 0x0f, 0x3b, 0xde, 0x15, 0xf1, 0xda, 0x67, 0x81, - 0xd7, 0x41, 0x06, 0x06, 0x30, 0xb9, 0xb9, 0xe3, 0xa3, 0xb2, 0x92, 0x07, 0x5e, 0x80, 0x4c, 0x95, - 0xae, 0xdb, 0x1b, 0x78, 0x24, 0x40, 0x15, 0xa5, 0x5e, 0x5f, 0x75, 0xce, 0x02, 0x0f, 0x59, 0x4a, - 0xed, 0x78, 0xbe, 0x17, 0x78, 0xc8, 0x7e, 0x6b, 0x58, 0x25, 0xa4, 0xbf, 0x35, 0x2c, 0x1d, 0x19, - 0xee, 0x6f, 0x1a, 0x1c, 0x0e, 0x58, 0x4a, 0xa3, 0xf9, 0x05, 0x5d, 0x91, 0x28, 0x9e, 0x50, 0x42, - 0xef, 0x97, 0x34, 0x63, 0xf8, 0x18, 0xac, 0x45, 0x92, 0x4d, 0x39, 0x76, 0x02, 0x60, 0x9b, 0x14, - 0x3a, 0x6e, 0x80, 0x7d, 0x47, 0x57, 0x61, 0xca, 0xe3, 0x15, 0x60, 0xb8, 0x5e, 0x1c, 0x64, 0x91, - 0xc9, 0xba, 0x53, 0xd2, 0x26, 0xbe, 0xfa, 0xbf, 0xe3, 0xeb, 0xde, 0xc0, 0xd1, 0xd3, 0xa6, 0xb2, - 0x45, 0x12, 0x67, 0x14, 0xfb, 0x80, 0xe5, 0xc3, 0x90, 0xad, 0x77, 0x2b, 0xfa, 0x73, 0x9a, 0xaf, - 0x3e, 0x79, 0x00, 0x64, 0x6f, 0xf8, 0xd4, 0xe4, 0xfe, 0x02, 0xfb, 0xb2, 0x4e, 0x10, 0x0d, 0x67, - 0x34, 0x7b, 0xce, 0xe8, 0x47, 0x60, 0x32, 0x11, 0x5c, 0x2d, 0x9d, 0xe8, 0x35, 0x9b, 0x28, 0xed, - 0xbf, 0x4e, 0x38, 0x86, 0x83, 0xed, 0xca, 0xff, 0xcb, 0x7c, 0xdf, 0x80, 0x41, 0x96, 0x33, 0x8a, - 0x0f, 0xa0, 0x3c, 0x8f, 0xd8, 0xe8, 0x56, 0x4d, 0x23, 0x15, 0x3e, 0xca, 0xcd, 0x74, 0xc6, 0x68, - 0x2a, 0x56, 0x68, 0x13, 0xa5, 0xb9, 0x6f, 0xc0, 0xfc, 0x41, 0x48, 0xf8, 0x73, 0x28, 0xa7, 0x4b, - 0x3e, 0xab, 0xfc, 0xd4, 0xd1, 0x66, 0x03, 0x3c, 0x31, 0x91, 0x6e, 0xf7, 0x6f, 0x0d, 0x76, 0x64, - 0x43, 0x83, 0x64, 0x99, 0x8e, 0x28, 0x47, 0xf0, 0x8e, 0xae, 0xb2, 0x45, 0x34, 0xa2, 0x39, 0x82, - 0xb9, 0xce, 0x9b, 0xc9, 0x6e, 0xa3, 0x74, 0xac, 0xaa, 0x4a, 0x05, 0x7f, 0x0b, 0x8e, 0x40, 0x92, - 0x85, 0x6c, 0xb5, 0xa0, 0x02, 0xc3, 0xdd, 0xe6, 0xc1, 0xfa, 0xa8, 0x04, 0x4e, 0x2c, 0x58, 0x2d, - 0x28, 0x01, 0x56, 0xc8, 0xdb, 0x97, 0x68, 0x3c, 0xe3, 0x12, 0xd7, 0xfb, 0x2b, 0x6f, 0xed, 0xef, - 0xb4, 0x00, 0xc3, 0x54, 0x59, 0x36, 0x66, 0x95, 0x70, 0x14, 0x00, 0xfd, 0x04, 0x36, 0x49, 0x1e, - 0xdb, 0xb7, 0x22, 0xa1, 0x0b, 0xe6, 0x90, 0xde, 0x24, 0x29, 0x55, 0x5b, 0x02, 0xc5, 0x62, 0x24, - 0x79, 0x24, 0xca, 0x83, 0x4f, 0xa0, 0x1c, 0xdd, 0xe4, 0x40, 0x6f, 0x87, 0x48, 0x87, 0x1b, 0x81, - 0x45, 0x92, 0x47, 0xc1, 0x7c, 0xf8, 0x15, 0xc8, 0x09, 0xc3, 0x38, 0x9a, 0xe7, 0xf0, 0xd9, 0xc2, - 0xd2, 0x8b, 0xe6, 0x14, 0x7f, 0x07, 0x4e, 0x9a, 0x3c, 0x86, 0x23, 0x51, 0x5e, 0x9e, 0xa1, 0xd3, - 0x3c, 0xdc, 0x5a, 0x4d, 0xde, 0x1c, 0x81, 0x34, 0x17, 0x33, 0xf7, 0x57, 0x0d, 0xcc, 0x77, 0xb2, - 0xc2, 0x29, 0x18, 0x02, 0x65, 0x49, 0x9c, 0x47, 0x9b, 0x6f, 0x65, 0x84, 0xc0, 0x59, 0xc4, 0xf0, - 0x5f, 0x8d, 0x09, 0x9b, 0xe6, 0xdb, 0x12, 0x32, 0xe7, 0xbf, 0xf1, 0x58, 0xf2, 0x9f, 0x4d, 0xb8, - 0x88, 0xbf, 0x02, 0x9b, 0x37, 0x25, 0xe8, 0x5a, 0xed, 0xe1, 0xe0, 0x49, 0x4b, 0x22, 0x31, 0xb1, - 0x52, 0x25, 0xb9, 0x3f, 0xc3, 0xee, 0x3b, 0xf9, 0x0d, 0x3c, 0xe7, 0xbb, 0x3b, 0xdd, 0x3a, 0xd6, - 0x4f, 0xef, 0xe7, 0x7b, 0x78, 0x59, 0x64, 0x56, 0xdf, 0x55, 0x0d, 0xca, 0xb2, 0x37, 0x79, 0xc9, - 0xf8, 0xe3, 0x91, 0x89, 0x0c, 0x38, 0xfd, 0x5d, 0x03, 0x58, 0x83, 0x80, 0x1d, 0xa8, 0x5c, 0xf7, - 0x2e, 0x7a, 0xfd, 0xf7, 0x3d, 0xf4, 0x02, 0x5b, 0x60, 0x9c, 0x07, 0xdd, 0x0e, 0xd2, 0xb0, 0x0d, - 0x65, 0x49, 0xe5, 0x25, 0xce, 0xc3, 0x8a, 0xc7, 0x75, 0x4e, 0xf2, 0x05, 0x89, 0x1b, 0xb8, 0x02, - 0x7a, 0x41, 0xd5, 0x8a, 0x9b, 0x4d, 0x9e, 0x90, 0x78, 0x57, 0xfe, 0x59, 0xdb, 0x43, 0x15, 0xee, - 0x28, 0x58, 0x1a, 0xc0, 0xcc, 0x29, 0x9a, 0xbf, 0xe4, 0xc4, 0x0e, 0xbc, 0x4e, 0x3f, 0xf8, 0xd1, - 0x23, 0xc8, 0xe1, 0x36, 0xd2, 0x7f, 0x8f, 0x76, 0x5a, 0x5f, 0x7c, 0x78, 0xfd, 0x30, 0x65, 0x34, - 0xcb, 0xea, 0xd3, 0xa4, 0x21, 0xa5, 0xc6, 0x24, 0x69, 0x3c, 0xb0, 0x86, 0xf8, 0x2b, 0xd0, 0x58, - 0x8f, 0x36, 0x34, 0x85, 0xe5, 0xeb, 0x7f, 0x02, 0x00, 0x00, 0xff, 0xff, 0xbd, 0x1a, 0xf9, 0xf4, - 0x59, 0x08, 0x00, 0x00, +func init() { proto.RegisterFile("binlogdata.proto", fileDescriptor_binlogdata_e1edbb575eea20d0) } + +var fileDescriptor_binlogdata_e1edbb575eea20d0 = []byte{ + // 1017 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x56, 0xdb, 0x6e, 0xdb, 0x46, + 0x13, 0x0e, 0x45, 0x8a, 0x22, 0x87, 0x8e, 0xbd, 0x5e, 0x1f, 0x20, 0x18, 0x08, 0x60, 0x10, 0x3f, + 0xfe, 0xb8, 0x06, 0x2a, 0xa5, 0xea, 0xe9, 0xa2, 0x57, 0x96, 0x44, 0xbb, 0x8a, 0x69, 0xc9, 0x59, + 0xd3, 0x49, 0x91, 0x1b, 0x82, 0x96, 0xd6, 0xb2, 0x60, 0x89, 0x94, 0xc9, 0x95, 0x5d, 0x3d, 0x47, + 0x9f, 0xa2, 0x7d, 0x90, 0xbc, 0x49, 0xef, 0xfa, 0x10, 0xc5, 0x1e, 0x48, 0x49, 0x0e, 0x90, 0xaa, + 0x17, 0xbd, 0x9b, 0xd3, 0x7e, 0x3b, 0xf3, 0xcd, 0x70, 0x87, 0x80, 0x6e, 0x46, 0xf1, 0x38, 0x19, + 0x0e, 0x22, 0x16, 0xd5, 0xa6, 0x69, 0xc2, 0x12, 0x0c, 0x0b, 0xcb, 0x81, 0xf3, 0x30, 0xa3, 0xe9, + 0x5c, 0x3a, 0x0e, 0x36, 0x59, 0x32, 0x4d, 0x16, 0x81, 0xee, 0x05, 0x54, 0x5a, 0x77, 0x51, 0x9a, + 0x51, 0x86, 0xf7, 0xc1, 0xec, 0x8f, 0x47, 0x34, 0x66, 0x55, 0xed, 0x50, 0x3b, 0x2a, 0x13, 0xa5, + 0x61, 0x0c, 0x46, 0x3f, 0x89, 0xe3, 0x6a, 0x49, 0x58, 0x85, 0xcc, 0x63, 0x33, 0x9a, 0x3e, 0xd2, + 0xb4, 0xaa, 0xcb, 0x58, 0xa9, 0xb9, 0x7f, 0xea, 0xb0, 0xdd, 0x14, 0x57, 0x07, 0x69, 0x14, 0x67, + 0x51, 0x9f, 0x8d, 0x92, 0x18, 0x9f, 0x01, 0x64, 0x2c, 0x62, 0x74, 0x42, 0x63, 0x96, 0x55, 0xb5, + 0x43, 0xfd, 0xc8, 0x69, 0xbc, 0xae, 0x2d, 0x25, 0xfd, 0xd9, 0x91, 0xda, 0x55, 0x1e, 0x4f, 0x96, + 0x8e, 0xe2, 0x06, 0x38, 0xf4, 0x91, 0xc6, 0x2c, 0x64, 0xc9, 0x3d, 0x8d, 0xab, 0xc6, 0xa1, 0x76, + 0xe4, 0x34, 0xb6, 0x6b, 0xb2, 0x40, 0x8f, 0x7b, 0x02, 0xee, 0x20, 0x40, 0x0b, 0xf9, 0xe0, 0x53, + 0x09, 0xec, 0x02, 0x0d, 0xfb, 0x60, 0xf5, 0x23, 0x46, 0x87, 0x49, 0x3a, 0x17, 0x65, 0x6e, 0x36, + 0xde, 0xac, 0x99, 0x48, 0xad, 0xa5, 0xce, 0x91, 0x02, 0x01, 0x7f, 0x0d, 0x95, 0xbe, 0x64, 0x4f, + 0xb0, 0xe3, 0x34, 0x76, 0x96, 0xc1, 0x14, 0xb1, 0x24, 0x8f, 0xc1, 0x08, 0xf4, 0xec, 0x61, 0x2c, + 0x28, 0xdb, 0x20, 0x5c, 0x74, 0x7f, 0xd7, 0xc0, 0xca, 0x71, 0xf1, 0x0e, 0x6c, 0x35, 0xfd, 0xf0, + 0xba, 0x4b, 0xbc, 0x56, 0xef, 0xac, 0xdb, 0xf9, 0xe8, 0xb5, 0xd1, 0x0b, 0xbc, 0x01, 0x56, 0xd3, + 0x0f, 0x9b, 0xde, 0x59, 0xa7, 0x8b, 0x34, 0xfc, 0x12, 0xec, 0xa6, 0x1f, 0xb6, 0x7a, 0x17, 0x17, + 0x9d, 0x00, 0x95, 0xf0, 0x16, 0x38, 0x4d, 0x3f, 0x24, 0x3d, 0xdf, 0x6f, 0x9e, 0xb4, 0xce, 0x91, + 0x8e, 0xf7, 0x60, 0xbb, 0xe9, 0x87, 0xed, 0x0b, 0x3f, 0x6c, 0x7b, 0x97, 0xc4, 0x6b, 0x9d, 0x04, + 0x5e, 0x1b, 0x19, 0x18, 0xc0, 0xe4, 0xe6, 0xb6, 0x8f, 0xca, 0x4a, 0xbe, 0xf2, 0x02, 0x64, 0x2a, + 0xb8, 0x4e, 0xf7, 0xca, 0x23, 0x01, 0xaa, 0x28, 0xf5, 0xfa, 0xb2, 0x7d, 0x12, 0x78, 0xc8, 0x52, + 0x6a, 0xdb, 0xf3, 0xbd, 0xc0, 0x43, 0xf6, 0x5b, 0xc3, 0x2a, 0x21, 0xfd, 0xad, 0x61, 0xe9, 0xc8, + 0x70, 0x7f, 0xd3, 0x60, 0xef, 0x8a, 0xa5, 0x34, 0x9a, 0x9c, 0xd3, 0x39, 0x89, 0xe2, 0x21, 0x25, + 0xf4, 0x61, 0x46, 0x33, 0x86, 0x0f, 0xc0, 0x9a, 0x26, 0xd9, 0x88, 0x73, 0x27, 0x08, 0xb6, 0x49, + 0xa1, 0xe3, 0x3a, 0xd8, 0xf7, 0x74, 0x1e, 0xa6, 0x3c, 0x5e, 0x11, 0x86, 0x6b, 0xc5, 0x40, 0x16, + 0x48, 0xd6, 0xbd, 0x92, 0x96, 0xf9, 0xd5, 0xff, 0x99, 0x5f, 0xf7, 0x16, 0xf6, 0x9f, 0x27, 0x95, + 0x4d, 0x93, 0x38, 0xa3, 0xd8, 0x07, 0x2c, 0x0f, 0x86, 0x6c, 0xd1, 0x5b, 0x91, 0x9f, 0xd3, 0x78, + 0xf5, 0xc5, 0x01, 0x20, 0xdb, 0x37, 0xcf, 0x4d, 0xee, 0xaf, 0xb0, 0x23, 0xef, 0x09, 0xa2, 0x9b, + 0x31, 0xcd, 0xd6, 0x29, 0x7d, 0x1f, 0x4c, 0x26, 0x82, 0xab, 0xa5, 0x43, 0xfd, 0xc8, 0x26, 0x4a, + 0xfb, 0xb7, 0x15, 0x0e, 0x60, 0x77, 0xf5, 0xe6, 0xff, 0xa4, 0xbe, 0xef, 0xc0, 0x20, 0xb3, 0x31, + 0xc5, 0xbb, 0x50, 0x9e, 0x44, 0xac, 0x7f, 0xa7, 0xaa, 0x91, 0x0a, 0x2f, 0xe5, 0x76, 0x34, 0x66, + 0x34, 0x15, 0x2d, 0xb4, 0x89, 0xd2, 0xdc, 0x37, 0x60, 0x9e, 0x0a, 0x09, 0xff, 0x1f, 0xca, 0xe9, + 0x8c, 0xd7, 0x2a, 0x3f, 0x75, 0xb4, 0x9c, 0x00, 0x07, 0x26, 0xd2, 0xed, 0xfe, 0xa5, 0xc1, 0x86, + 0x4c, 0xe8, 0x2a, 0x99, 0xa5, 0x7d, 0xca, 0x19, 0xbc, 0xa7, 0xf3, 0x6c, 0x1a, 0xf5, 0x69, 0xce, + 0x60, 0xae, 0xf3, 0x64, 0xb2, 0xbb, 0x28, 0x1d, 0xa8, 0x5b, 0xa5, 0x82, 0xbf, 0x07, 0x47, 0x30, + 0xc9, 0x42, 0x36, 0x9f, 0x52, 0xc1, 0xe1, 0x66, 0x63, 0x77, 0x31, 0x54, 0x82, 0x27, 0x16, 0xcc, + 0xa7, 0x94, 0x00, 0x2b, 0xe4, 0xd5, 0x49, 0x34, 0xd6, 0x98, 0xc4, 0x45, 0xff, 0xca, 0x2b, 0xfd, + 0x3b, 0x2e, 0xc8, 0x30, 0x15, 0xca, 0x52, 0xad, 0x92, 0x8e, 0x82, 0xa0, 0x77, 0x60, 0x93, 0xe4, + 0xa9, 0x75, 0x27, 0x00, 0x5d, 0x30, 0x6f, 0xe8, 0x6d, 0x92, 0x52, 0xd5, 0x25, 0x50, 0xaf, 0x18, + 0x49, 0x9e, 0x88, 0xf2, 0xe0, 0x43, 0x28, 0x47, 0xb7, 0x39, 0xd1, 0xab, 0x21, 0xd2, 0xe1, 0x46, + 0x60, 0x91, 0xe4, 0x49, 0xbc, 0x7c, 0xf8, 0x15, 0xc8, 0x0a, 0xc3, 0x38, 0x9a, 0xe4, 0xf4, 0xd9, + 0xc2, 0xd2, 0x8d, 0x26, 0x14, 0xff, 0x00, 0x4e, 0x9a, 0x3c, 0x85, 0x7d, 0x71, 0xbd, 0x1c, 0x43, + 0xa7, 0xb1, 0xb7, 0xd2, 0x9a, 0x3c, 0x39, 0x02, 0x69, 0x2e, 0x66, 0xee, 0x3b, 0x80, 0xd3, 0x11, + 0x1d, 0x0f, 0xd6, 0xba, 0xe4, 0x7f, 0x9c, 0x0e, 0x3a, 0x1e, 0xe4, 0xf8, 0x1b, 0x2a, 0x65, 0x81, + 0x40, 0x94, 0xcf, 0xfd, 0xa4, 0x81, 0xf9, 0x5e, 0xe2, 0x1d, 0x83, 0x21, 0x1a, 0x27, 0xdf, 0xe2, + 0xfd, 0xe5, 0x74, 0x64, 0x84, 0x68, 0x9d, 0x88, 0xe1, 0x8b, 0x68, 0xc8, 0x46, 0xf9, 0x00, 0x08, + 0x99, 0x3f, 0xa9, 0x83, 0x81, 0x7c, 0x52, 0x6d, 0xc2, 0x45, 0xfc, 0x0d, 0xd8, 0xbc, 0x4e, 0xb1, + 0x01, 0x54, 0x6b, 0x77, 0x9f, 0x55, 0x29, 0x80, 0x89, 0x95, 0xe6, 0xcc, 0xfd, 0x08, 0x8e, 0xc8, + 0x4c, 0x1d, 0x2a, 0x8b, 0x43, 0xfb, 0xab, 0x9d, 0xcc, 0x19, 0x20, 0x70, 0x5b, 0xc8, 0xee, 0x2f, + 0xb0, 0xf9, 0x5e, 0x7e, 0x8f, 0xeb, 0xbc, 0x01, 0xc7, 0x2b, 0x1f, 0xce, 0x97, 0x67, 0xe5, 0x27, + 0xd8, 0x2a, 0x90, 0xd5, 0x37, 0x7e, 0x04, 0x65, 0x99, 0x9f, 0xfc, 0xaa, 0xf0, 0xe7, 0x5c, 0x11, + 0x19, 0x70, 0xfc, 0x87, 0x06, 0xb0, 0x60, 0x0f, 0x3b, 0x50, 0xb9, 0xee, 0x9e, 0x77, 0x7b, 0x1f, + 0xba, 0xe8, 0x05, 0xb6, 0xc0, 0x38, 0x0b, 0x3a, 0x6d, 0xa4, 0x61, 0x1b, 0xca, 0x72, 0xad, 0x94, + 0xf8, 0x4e, 0x50, 0x3b, 0x45, 0xe7, 0x0b, 0xa7, 0x58, 0x28, 0x06, 0xae, 0x80, 0x5e, 0xac, 0x0d, + 0xb5, 0x27, 0x4c, 0x0e, 0x48, 0xbc, 0x4b, 0xff, 0xa4, 0xe5, 0xa1, 0x0a, 0x77, 0x14, 0x1b, 0x03, + 0xc0, 0xcc, 0xd7, 0x05, 0x3f, 0xc9, 0x97, 0x0c, 0xf0, 0x7b, 0x7a, 0xc1, 0xcf, 0x1e, 0x41, 0x0e, + 0xb7, 0x91, 0xde, 0x07, 0xb4, 0xc1, 0x6d, 0xa7, 0x1d, 0xcf, 0x6f, 0xa3, 0x97, 0xcd, 0xaf, 0x3e, + 0xbe, 0x7e, 0x1c, 0x31, 0x9a, 0x65, 0xb5, 0x51, 0x52, 0x97, 0x52, 0x7d, 0x98, 0xd4, 0x1f, 0x59, + 0x5d, 0xfc, 0xa1, 0xd4, 0x17, 0x55, 0xde, 0x98, 0xc2, 0xf2, 0xed, 0xdf, 0x01, 0x00, 0x00, 0xff, + 0xff, 0xda, 0xbf, 0xad, 0x34, 0xf0, 0x08, 0x00, 0x00, } diff --git a/go/vt/vttablet/tabletserver/vstreamer/engine_test.go b/go/vt/vttablet/tabletserver/vstreamer/engine_test.go index d23ce11fe13..1e209663b77 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/engine_test.go +++ b/go/vt/vttablet/tabletserver/vstreamer/engine_test.go @@ -46,6 +46,10 @@ var shardedVSchema = `{ }` func TestUpdateVSchema(t *testing.T) { + if testing.Short() { + t.Skip() + } + defer setVSchema("{}") // We have to start at least one stream to start the vschema watcher. diff --git a/go/vt/vttablet/tabletserver/vstreamer/main_test.go b/go/vt/vttablet/tabletserver/vstreamer/main_test.go index 45f39071877..d308e431690 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/main_test.go +++ b/go/vt/vttablet/tabletserver/vstreamer/main_test.go @@ -61,7 +61,10 @@ func (checker) CheckMySQL() {} func TestMain(m *testing.M) { flag.Parse() // Do not remove this comment, import into google3 depends on it - tabletenv.Init() + + if testing.Short() { + os.Exit(m.Run()) + } exitCode := func() int { // Launch MySQL. @@ -71,7 +74,7 @@ func TestMain(m *testing.M) { Topology: &vttestpb.VTTestTopology{ Keyspaces: []*vttestpb.Keyspace{ { - Name: "vttest", + Name: keyspaceName, Shards: []*vttestpb.Shard{ { Name: "0", diff --git a/go/vt/vttablet/tabletserver/vstreamer/planbuilder.go b/go/vt/vttablet/tabletserver/vstreamer/planbuilder.go index 06c85b42ab6..be6ea986a43 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/planbuilder.go +++ b/go/vt/vttablet/tabletserver/vstreamer/planbuilder.go @@ -30,6 +30,7 @@ import ( "vitess.io/vitess/go/vt/vttablet/tabletserver/schema" binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" + querypb "vitess.io/vitess/go/vt/proto/query" topodatapb "vitess.io/vitess/go/vt/proto/topodata" ) @@ -46,6 +47,7 @@ type Plan struct { type ColExpr struct { ColNum int Alias sqlparser.ColIdent + Type querypb.Type Operation Operation } @@ -55,7 +57,7 @@ type Operation int // The following are the supported operations on a column. const ( OpNone = Operation(iota) - OpYearMonth + OpMonth OpDay OpHour ) @@ -71,19 +73,19 @@ func (plan *Plan) filter(values []sqltypes.Value) (bool, []sqltypes.Value, error result := make([]sqltypes.Value, len(plan.ColExprs)) for i, colExpr := range plan.ColExprs { switch colExpr.Operation { - case OpYearMonth: + case OpMonth: v, _ := sqltypes.ToInt64(values[colExpr.ColNum]) - t := time.Unix(v, 0) + t := time.Unix(v, 0).UTC() s := fmt.Sprintf("%d%02d", t.Year(), t.Month()) result[i] = sqltypes.NewVarBinary(s) case OpDay: v, _ := sqltypes.ToInt64(values[colExpr.ColNum]) - t := time.Unix(v, 0) + t := time.Unix(v, 0).UTC() s := fmt.Sprintf("%d%02d%02d", t.Year(), t.Month(), t.Day()) result[i] = sqltypes.NewVarBinary(s) case OpHour: v, _ := sqltypes.ToInt64(values[colExpr.ColNum]) - t := time.Unix(v, 0) + t := time.Unix(v, 0).UTC() s := fmt.Sprintf("%d%02d%02d%02d", t.Year(), t.Month(), t.Day(), t.Hour()) result[i] = sqltypes.NewVarBinary(s) default: @@ -140,6 +142,7 @@ func buildREPlan(ti *Table, kschema *vindexes.KeyspaceSchema, filter string) (*P for i, col := range ti.Columns { plan.ColExprs[i].ColNum = i plan.ColExprs[i].Alias = col.Name + plan.ColExprs[i].Type = col.Type } if filter == "" { return plan, nil @@ -187,7 +190,7 @@ func buildTablePlan(ti *Table, kschema *vindexes.KeyspaceSchema, query string) ( } sel, ok := statement.(*sqlparser.Select) if !ok { - return nil, fmt.Errorf("unexpected: %v", sqlparser.String(sel)) + return nil, fmt.Errorf("unexpected: %v", sqlparser.String(statement)) } if len(sel.From) > 1 { return nil, fmt.Errorf("unexpected: %v", sqlparser.String(sel)) @@ -220,6 +223,7 @@ func buildTablePlan(ti *Table, kschema *vindexes.KeyspaceSchema, query string) ( for i, col := range ti.Columns { plan.ColExprs[i].ColNum = i plan.ColExprs[i].Alias = col.Name + plan.ColExprs[i].Type = col.Type } } @@ -265,6 +269,9 @@ func buildTablePlan(ti *Table, kschema *vindexes.KeyspaceSchema, query string) ( if err != nil { return nil, err } + if !plan.Vindex.IsUnique() || !plan.Vindex.IsFunctional() { + return nil, fmt.Errorf("vindex must be Unique and Functional to be used for VReplication: %s", vtype) + } kr, err := selString(funcExpr.Exprs[2]) if err != nil { return nil, err @@ -291,13 +298,13 @@ func analyzeExpr(ti *Table, expr sqlparser.SelectExpr) (cExpr ColExpr, err error if err != nil { return ColExpr{}, err } - return ColExpr{ColNum: colnum, Alias: expr.Name}, nil + return ColExpr{ColNum: colnum, Alias: expr.Name, Type: ti.Columns[colnum].Type}, nil case *sqlparser.FuncExpr: if expr.Distinct || len(expr.Exprs) != 1 { return ColExpr{}, fmt.Errorf("unsupported: %v", sqlparser.String(expr)) } switch fname := expr.Name.Lowered(); fname { - case "yearmonth", "day", "hour": + case "month", "day", "hour": aInner, ok := expr.Exprs[0].(*sqlparser.AliasedExpr) if !ok { return ColExpr{}, fmt.Errorf("unsupported: %v", sqlparser.String(expr)) @@ -306,20 +313,21 @@ func analyzeExpr(ti *Table, expr sqlparser.SelectExpr) (cExpr ColExpr, err error if !ok { return ColExpr{}, fmt.Errorf("unsupported: %v", sqlparser.String(expr)) } - if aInner.As.IsEmpty() { - return ColExpr{}, fmt.Errorf("need alias for expression: %v", sqlparser.String(expr)) + as := aexpr.As + if as.IsEmpty() { + as = sqlparser.NewColIdent(sqlparser.String(expr)) } colnum, err := findColumn(ti, innerCol.Name) if err != nil { return ColExpr{}, err } switch fname { - case "yearmonth": - return ColExpr{ColNum: colnum, Alias: aInner.As, Operation: OpYearMonth}, nil + case "month": + return ColExpr{ColNum: colnum, Alias: as, Type: sqltypes.VarBinary, Operation: OpMonth}, nil case "day": - return ColExpr{ColNum: colnum, Alias: aInner.As, Operation: OpDay}, nil + return ColExpr{ColNum: colnum, Alias: as, Type: sqltypes.VarBinary, Operation: OpDay}, nil case "hour": - return ColExpr{ColNum: colnum, Alias: aInner.As, Operation: OpHour}, nil + return ColExpr{ColNum: colnum, Alias: as, Type: sqltypes.VarBinary, Operation: OpHour}, nil default: panic("unreachable") } diff --git a/go/vt/vttablet/tabletserver/vstreamer/planbuilder_test.go b/go/vt/vttablet/tabletserver/vstreamer/planbuilder_test.go new file mode 100644 index 00000000000..1dda4116101 --- /dev/null +++ b/go/vt/vttablet/tabletserver/vstreamer/planbuilder_test.go @@ -0,0 +1,383 @@ +/* +Copyright 2019 The Vitess Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this 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 ( + "fmt" + "reflect" + "testing" + + "vitess.io/vitess/go/json2" + "vitess.io/vitess/go/mysql" + "vitess.io/vitess/go/sqltypes" + "vitess.io/vitess/go/vt/sqlparser" + "vitess.io/vitess/go/vt/vtgate/vindexes" + "vitess.io/vitess/go/vt/vttablet/tabletserver/schema" + + binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" + vschemapb "vitess.io/vitess/go/vt/proto/vschema" +) + +var testKSChema *vindexes.KeyspaceSchema + +func init() { + input := `{ + "sharded": true, + "vindexes": { + "hash": { + "type": "hash" + }, + "lookup": { + "type": "lookup" + } + }, + "tables": { + "t1": { + "column_vindexes": [ + { + "column": "id", + "name": "hash" + } + ] + } + } +}` + var kspb vschemapb.Keyspace + if err := json2.Unmarshal([]byte(input), &kspb); err != nil { + panic(fmt.Errorf("Unmarshal failed: %v", err)) + } + kschema, err := vindexes.BuildKeyspaceSchema(&kspb, keyspaceName) + if err != nil { + panic(err) + } + testKSChema = kschema +} + +func TestPlanbuilder(t *testing.T) { + t1 := &Table{ + TableMap: &mysql.TableMap{ + Name: "t1", + }, + Columns: []schema.TableColumn{{ + Name: sqlparser.NewColIdent("id"), + Type: sqltypes.Int64, + }, { + Name: sqlparser.NewColIdent("val"), + Type: sqltypes.VarBinary, + }}, + } + // t1alt has no id column + t1alt := &Table{ + TableMap: &mysql.TableMap{ + Name: "t1", + }, + Columns: []schema.TableColumn{{ + Name: sqlparser.NewColIdent("val"), + Type: sqltypes.VarBinary, + }}, + } + t2 := &Table{ + TableMap: &mysql.TableMap{ + Name: "t2", + }, + Columns: []schema.TableColumn{{ + Name: sqlparser.NewColIdent("id"), + Type: sqltypes.Int64, + }, { + Name: sqlparser.NewColIdent("val"), + Type: sqltypes.VarBinary, + }}, + } + + testcases := []struct { + inTable *Table + inRule *binlogdatapb.Rule + outPlan *Plan + outErr string + }{{ + inTable: t1, + inRule: &binlogdatapb.Rule{Match: "/.*/"}, + outPlan: &Plan{ + ColExprs: []ColExpr{{ + ColNum: 0, + Alias: sqlparser.NewColIdent("id"), + Type: sqltypes.Int64, + }, { + ColNum: 1, + Alias: sqlparser.NewColIdent("val"), + Type: sqltypes.VarBinary, + }}, + }, + }, { + inTable: t1, + inRule: &binlogdatapb.Rule{Match: "/.*/", Filter: "-80"}, + outPlan: &Plan{ + ColExprs: []ColExpr{{ + ColNum: 0, + Alias: sqlparser.NewColIdent("id"), + Type: sqltypes.Int64, + }, { + ColNum: 1, + Alias: sqlparser.NewColIdent("val"), + Type: sqltypes.VarBinary, + }}, + VindexColumn: 0, + }, + }, { + inTable: t1, + inRule: &binlogdatapb.Rule{Match: "t1", Filter: "select * from t1"}, + outPlan: &Plan{ + ColExprs: []ColExpr{{ + ColNum: 0, + Alias: sqlparser.NewColIdent("id"), + Type: sqltypes.Int64, + }, { + ColNum: 1, + Alias: sqlparser.NewColIdent("val"), + Type: sqltypes.VarBinary, + }}, + }, + }, { + inTable: t1, + inRule: &binlogdatapb.Rule{Match: "t1", Filter: "select id, val from t1"}, + outPlan: &Plan{ + ColExprs: []ColExpr{{ + ColNum: 0, + Alias: sqlparser.NewColIdent("id"), + Type: sqltypes.Int64, + }, { + ColNum: 1, + Alias: sqlparser.NewColIdent("val"), + Type: sqltypes.VarBinary, + }}, + }, + }, { + inTable: t1, + inRule: &binlogdatapb.Rule{Match: "t1", Filter: "select val, id from t1"}, + outPlan: &Plan{ + ColExprs: []ColExpr{{ + ColNum: 1, + Alias: sqlparser.NewColIdent("val"), + Type: sqltypes.VarBinary, + }, { + ColNum: 0, + Alias: sqlparser.NewColIdent("id"), + Type: sqltypes.Int64, + }}, + }, + }, { + inTable: t1, + inRule: &binlogdatapb.Rule{Match: "t1", Filter: "select val, id from t1 where in_keyrange(id, 'hash', '-80')"}, + outPlan: &Plan{ + ColExprs: []ColExpr{{ + ColNum: 1, + Alias: sqlparser.NewColIdent("val"), + Type: sqltypes.VarBinary, + }, { + ColNum: 0, + Alias: sqlparser.NewColIdent("id"), + Type: sqltypes.Int64, + }}, + VindexColumn: 1, + }, + }, { + inTable: t1, + inRule: &binlogdatapb.Rule{Match: "t1", Filter: "select id, val, month(val) m, day(id), hour(val) from t1 where in_keyrange(m, 'hash', '-80')"}, + outPlan: &Plan{ + ColExprs: []ColExpr{{ + ColNum: 0, + Alias: sqlparser.NewColIdent("id"), + Type: sqltypes.Int64, + }, { + ColNum: 1, + Alias: sqlparser.NewColIdent("val"), + Type: sqltypes.VarBinary, + }, { + ColNum: 1, + Alias: sqlparser.NewColIdent("m"), + Type: sqltypes.VarBinary, + Operation: OpMonth, + }, { + ColNum: 0, + Alias: sqlparser.NewColIdent("day(id)"), + Type: sqltypes.VarBinary, + Operation: OpDay, + }, { + ColNum: 1, + Alias: sqlparser.NewColIdent("hour(val)"), + Type: sqltypes.VarBinary, + Operation: OpHour, + }}, + VindexColumn: 2, + }, + }, { + inTable: t2, + inRule: &binlogdatapb.Rule{Match: "/t1/"}, + }, { + inTable: t1, + inRule: &binlogdatapb.Rule{Match: "/*/"}, + outErr: "error parsing regexp: missing argument to repetition operator: `*`", + }, { + inTable: t2, + inRule: &binlogdatapb.Rule{Match: "/.*/", Filter: "-80"}, + outErr: `no vschema definition for table t2`, + }, { + inTable: t1alt, + inRule: &binlogdatapb.Rule{Match: "/.*/", Filter: "-80"}, + outErr: `column id not found in table t1`, + }, { + inTable: t1, + inRule: &binlogdatapb.Rule{Match: "/.*/", Filter: "80"}, + outErr: `malformed spec: doesn't define a range: "80"`, + }, { + inTable: t1, + inRule: &binlogdatapb.Rule{Match: "/.*/", Filter: "-80-"}, + outErr: `error parsing keyrange: -80-`, + }, { + inTable: t1, + inRule: &binlogdatapb.Rule{Match: "t1", Filter: "bad query"}, + outErr: `syntax error at position 4 near 'bad'`, + }, { + inTable: t1, + inRule: &binlogdatapb.Rule{Match: "t1", Filter: "delete from t1"}, + outErr: `unexpected: delete from t1`, + }, { + inTable: t1, + inRule: &binlogdatapb.Rule{Match: "t1", Filter: "select * from t1, t2"}, + outErr: `unexpected: select * from t1, t2`, + }, { + inTable: t1, + inRule: &binlogdatapb.Rule{Match: "t1", Filter: "select * from t1 join t2"}, + outErr: `unexpected: select * from t1 join t2`, + }, { + inTable: t1, + inRule: &binlogdatapb.Rule{Match: "t1", Filter: "select * from a.t1"}, + outErr: `unexpected: select * from a.t1`, + }, { + inTable: t1, + inRule: &binlogdatapb.Rule{Match: "t1", Filter: "select * from t2"}, + outErr: `unexpected: select expression table t2 does not match the table entry name t1`, + }, { + inTable: t1, + inRule: &binlogdatapb.Rule{Match: "t1", Filter: "select *, id from t1"}, + outErr: `unexpected: select *, id from t1`, + }, { + inTable: t1, + inRule: &binlogdatapb.Rule{Match: "t1", Filter: "select id, val from t1 where id=1"}, + outErr: `unexpected where clause: where id = 1`, + }, { + inTable: t1, + inRule: &binlogdatapb.Rule{Match: "t1", Filter: "select id, val from t1 where max(id)"}, + outErr: `unexpected where clause: where max(id)`, + }, { + inTable: t1, + inRule: &binlogdatapb.Rule{Match: "t1", Filter: "select id, val from t1 where in_keyrange(id)"}, + outErr: `unexpected where clause: where in_keyrange(id)`, + }, { + inTable: t1, + inRule: &binlogdatapb.Rule{Match: "t1", Filter: "select id, val from t1 where in_keyrange(*, 'hash', '-80')"}, + outErr: `unexpected: in_keyrange(*, 'hash', '-80')`, + }, { + inTable: t1, + inRule: &binlogdatapb.Rule{Match: "t1", Filter: "select id, val from t1 where in_keyrange(1, 'hash', '-80')"}, + outErr: `unsupported: in_keyrange(1, 'hash', '-80')`, + }, { + inTable: t1, + inRule: &binlogdatapb.Rule{Match: "t1", Filter: "select id, val from t1 where in_keyrange(none, 'hash', '-80')"}, + outErr: `keyrange expression does not reference a column in the select list: none`, + }, { + 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`, + }, { + inTable: t1, + inRule: &binlogdatapb.Rule{Match: "t1", Filter: "select id, val from t1 where in_keyrange(id, 'hash', '80')"}, + outErr: `malformed spec: doesn't define a range: "80"`, + }, { + inTable: t1, + inRule: &binlogdatapb.Rule{Match: "t1", Filter: "select id, val from t1 where in_keyrange(id, 'hash', '-80-')"}, + outErr: `unexpected where clause: where in_keyrange(id, 'hash', '-80-')`, + }, { + // analyzeExpr tests. + inTable: t1, + inRule: &binlogdatapb.Rule{Match: "t1", Filter: "select id, * from t1"}, + outErr: `unexpected: *`, + }, { + inTable: t1, + inRule: &binlogdatapb.Rule{Match: "t1", Filter: "select none from t1"}, + outErr: `column none not found in table t1`, + }, { + inTable: t1, + inRule: &binlogdatapb.Rule{Match: "t1", Filter: "select id, val, hour(distinct a) from t1"}, + outErr: `unsupported: hour(distinct a)`, + }, { + inTable: t1, + inRule: &binlogdatapb.Rule{Match: "t1", Filter: "select id, val, hour(a, b) from t1"}, + outErr: `unsupported: hour(a, b)`, + }, { + inTable: t1, + inRule: &binlogdatapb.Rule{Match: "t1", Filter: "select id, val, hour(*) from t1"}, + outErr: `unsupported: hour(*)`, + }, { + inTable: t1, + inRule: &binlogdatapb.Rule{Match: "t1", Filter: "select id, val, hour(val+1) from t1"}, + outErr: `unsupported: hour(val + 1)`, + }, { + inTable: t1, + inRule: &binlogdatapb.Rule{Match: "t1", Filter: "select id, val, hour(none) from t1"}, + outErr: `column none not found in table t1`, + }, { + inTable: t1, + inRule: &binlogdatapb.Rule{Match: "t1", Filter: "select id, val, max(val) from t1"}, + outErr: `unsupported: max(val)`, + }, { + inTable: t1, + inRule: &binlogdatapb.Rule{Match: "t1", Filter: "select id+1, val from t1"}, + outErr: `unexpected: id + 1`, + }, { + // selString + inTable: t1, + inRule: &binlogdatapb.Rule{Match: "t1", Filter: "select id, val from t1 where in_keyrange(id, *, '-80')"}, + outErr: `unexpected: *`, + }, { + inTable: t1, + inRule: &binlogdatapb.Rule{Match: "t1", Filter: "select id, val from t1 where in_keyrange(id, 1+1, '-80')"}, + outErr: `unexpected: 1 + 1`, + }} + + for _, tcase := range testcases { + plan, err := buildPlan(tcase.inTable, testKSChema, &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{tcase.inRule}, + }) + if plan != nil { + plan.Table = nil + plan.Vindex = nil + plan.KeyRange = nil + if !reflect.DeepEqual(tcase.outPlan, plan) { + t.Errorf("Plan(%v, %v):\n%v, want\n%v", tcase.inTable, tcase.inRule, plan, tcase.outPlan) + } + } + gotErr := "" + if err != nil { + gotErr = err.Error() + } + if gotErr != tcase.outErr { + t.Errorf("Plan(%v, %v) err: %v, want %v", tcase.inTable, tcase.inRule, err, tcase.outErr) + } + + } +} diff --git a/go/vt/vttablet/tabletserver/vstreamer/vstreamer.go b/go/vt/vttablet/tabletserver/vstreamer/vstreamer.go index c167990d557..83a5b8d1c6e 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/vstreamer.go +++ b/go/vt/vttablet/tabletserver/vstreamer/vstreamer.go @@ -30,6 +30,7 @@ import ( "vitess.io/vitess/go/vt/vttablet/tabletserver/schema" binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" + querypb "vitess.io/vitess/go/vt/proto/query" ) var packetSize = flag.Int("vstream_packet_size", 10000, "Suggested packet size for VReplication streamer. This is used only as a recommendation. The actual packet size may be more or less than this amount.") @@ -120,8 +121,8 @@ func (vs *vstreamer) parseEvents(ctx context.Context, events <-chan mysql.Binlog // If a single row exceeds the packet size, it will be in its own packet. bufferAndTransmit := func(vevent *binlogdatapb.VEvent) error { switch vevent.Type { - case binlogdatapb.VEventType_GTID, binlogdatapb.VEventType_BEGIN: - // We never have to send GTID or BEGIN events on their own. + case binlogdatapb.VEventType_GTID, binlogdatapb.VEventType_BEGIN, binlogdatapb.VEventType_FIELD: + // We never have to send GTID, BEGIN or FIELD events on their own. bufferedEvents = append(bufferedEvents, vevent) case binlogdatapb.VEventType_COMMIT, binlogdatapb.VEventType_ROLLBACK, binlogdatapb.VEventType_DDL: // COMMIT, ROLLBACK and DDL are terminal. There may be no more events after @@ -151,6 +152,8 @@ func (vs *vstreamer) parseEvents(ctx context.Context, events <-chan mysql.Binlog } curSize += newSize bufferedEvents = append(bufferedEvents, vevent) + default: + return fmt.Errorf("unexpected event: %v", vevent) } return nil } @@ -306,6 +309,23 @@ func (vs *vstreamer) parseEvent(ev mysql.BinlogEvent) ([]*binlogdatapb.VEvent, e return nil, err } vs.plans[id] = plan + if plan == nil { + return nil, nil + } + fields := make([]*querypb.Field, len(plan.ColExprs)) + for i, ce := range plan.ColExprs { + fields[i] = &querypb.Field{ + Name: ce.Alias.String(), + Type: ce.Type, + } + } + vevents = append(vevents, &binlogdatapb.VEvent{ + Type: binlogdatapb.VEventType_FIELD, + FieldEvent: &binlogdatapb.FieldEvent{ + TableName: plan.Table.Name, + Fields: fields, + }, + }) case ev.IsWriteRows() || ev.IsDeleteRows() || ev.IsUpdateRows(): // The existence of before and after images can be used to // identify statememt types. It's also possible that the diff --git a/go/vt/vttablet/tabletserver/vstreamer/vstreamer_test.go b/go/vt/vttablet/tabletserver/vstreamer/vstreamer_test.go index 37f5af140cb..9a9ff697b07 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/vstreamer_test.go +++ b/go/vt/vttablet/tabletserver/vstreamer/vstreamer_test.go @@ -34,6 +34,10 @@ type testcase struct { } func TestStatements(t *testing.T) { + if testing.Short() { + t.Skip() + } + execStatements(t, []string{ "create table stream1(id int, val varbinary(128), primary key(id))", "create table stream2(id int, val varbinary(128), primary key(id))", @@ -56,6 +60,7 @@ func TestStatements(t *testing.T) { output: [][]string{{ `gtid|begin`, `gtid|begin`, + `type:FIELD field_event: fields: > `, `type:ROW row_event: > > `, `type:ROW row_event: after: > > `, `commit`, @@ -87,7 +92,9 @@ func TestStatements(t *testing.T) { output: [][]string{{ `gtid|begin`, `gtid|begin`, + `type:FIELD field_event: fields: > `, `type:ROW row_event: > > `, + `type:FIELD field_event: fields: > `, `type:ROW row_event: > > `, `type:ROW row_event: after: > ` + @@ -127,6 +134,10 @@ func TestStatements(t *testing.T) { } func TestRegexp(t *testing.T) { + if testing.Short() { + t.Skip() + } + execStatements(t, []string{ "create table yes_stream(id int, val varbinary(128), primary key(id))", "create table no_stream(id int, val varbinary(128), primary key(id))", @@ -155,6 +166,7 @@ func TestRegexp(t *testing.T) { output: [][]string{{ `gtid|begin`, `gtid|begin`, + `type:FIELD field_event: fields: > `, `type:ROW row_event: > > `, `type:ROW row_event: after: > > `, `commit`, @@ -164,6 +176,10 @@ func TestRegexp(t *testing.T) { } func TestREKeyrange(t *testing.T) { + if testing.Short() { + t.Skip() + } + execStatements(t, []string{ "create table t1(id1 int, id2 int, val varbinary(128), primary key(id1))", }) @@ -206,6 +222,7 @@ func TestREKeyrange(t *testing.T) { expectLog(ctx, t, input, ch, [][]string{{ `gtid|begin`, `gtid|begin`, + `type:FIELD field_event: fields: fields: > `, `type:ROW row_event: > > `, `type:ROW row_event: after: > > `, `type:ROW row_event: > > `, @@ -253,6 +270,10 @@ func TestREKeyrange(t *testing.T) { } func TestSelectFilter(t *testing.T) { + if testing.Short() { + t.Skip() + } + execStatements(t, []string{ "create table t1(id1 int, id2 int, val varbinary(128), primary key(id1))", }) @@ -280,6 +301,7 @@ func TestSelectFilter(t *testing.T) { output: [][]string{{ `gtid|begin`, `gtid|begin`, + `type:FIELD field_event: fields: > `, `type:ROW row_event: > > `, `commit`, }}, @@ -287,9 +309,69 @@ func TestSelectFilter(t *testing.T) { runCases(t, filter, testcases) } +func TestSelectExpressions(t *testing.T) { + if testing.Short() { + t.Skip() + } + + execStatements(t, []string{ + "create table expr_test(id int, val bigint, primary key(id))", + }) + defer execStatements(t, []string{ + "drop table expr_test", + }) + engine.se.Reload(context.Background()) + + filter := &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{{ + Match: "expr_test", + Filter: "select id, val, month(val), day(val), hour(val) from expr_test", + }}, + } + + testcases := []testcase{{ + input: []string{ + "begin", + "insert into expr_test values (1, 1546392881)", + "commit", + }, + // MySQL issues GTID->BEGIN. + // MariaDB issues BEGIN->GTID. + output: [][]string{{ + `gtid|begin`, + `gtid|begin`, + `type:FIELD field_event: ` + + `fields: ` + + `fields: ` + + `fields: ` + + `fields: > `, + `type:ROW row_event: > > `, + `commit`, + }}, + }} + runCases(t, filter, testcases) +} + func TestDDLAddColumn(t *testing.T) { - execStatement(t, "create table ddl_test1(id int, val1 varbinary(128), primary key(id))") - defer execStatement(t, "drop table ddl_test1") + if testing.Short() { + t.Skip() + } + + execStatements(t, []string{ + "create table ddl_test1(id int, val1 varbinary(128), primary key(id))", + "create table ddl_test2(id int, val1 varbinary(128), primary key(id))", + }) + defer execStatements(t, []string{ + "drop table ddl_test1", + "drop table ddl_test2", + }) // Record position before the next few statements. pos, err := mysqld.MasterPosition() @@ -297,20 +379,37 @@ func TestDDLAddColumn(t *testing.T) { t.Fatal(err) } execStatements(t, []string{ + "begin", "insert into ddl_test1 values(1, 'aaa')", + "insert into ddl_test2 values(1, 'aaa')", + "commit", // Adding columns is allowed. "alter table ddl_test1 add column val2 varbinary(128)", + "alter table ddl_test2 add column val2 varbinary(128)", + "begin", "insert into ddl_test1 values(2, 'bbb', 'ccc')", + "insert into ddl_test2 values(2, 'bbb', 'ccc')", + "commit", }) engine.se.Reload(context.Background()) ctx, cancel := context.WithCancel(context.Background()) defer cancel() + // Test RE as well as select-based filters. + filter := &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{{ + Match: "ddl_test2", + Filter: "select * from ddl_test2", + }, { + Match: "/.*/", + }}, + } + ch := make(chan []*binlogdatapb.VEvent) go func() { defer close(ch) - if err := vstream(ctx, t, pos, nil, ch); err != nil { + if err := vstream(ctx, t, pos, filter, ch); err != nil { t.Fatal(err) } }() @@ -318,22 +417,35 @@ func TestDDLAddColumn(t *testing.T) { // Current schema has 3 columns, but they'll be truncated to match the two columns in the event. `gtid|begin`, `gtid|begin`, + `type:FIELD field_event: fields: > `, `type:ROW row_event: > > `, + `type:FIELD field_event: fields: > `, + `type:ROW row_event: > > `, `commit`, }, { `gtid`, `type:DDL ddl:"alter table ddl_test1 add column val2 varbinary(128)" `, + }, { + `gtid`, + `type:DDL ddl:"alter table ddl_test2 add column val2 varbinary(128)" `, }, { // The plan will be updated to now include the third column // because the new table map will have three columns. `gtid|begin`, `gtid|begin`, + `type:FIELD field_event: fields: fields: > `, `type:ROW row_event: > > `, + `type:FIELD field_event: fields: fields: > `, + `type:ROW row_event: > > `, `commit`, }}) } func TestDDLDropColumn(t *testing.T) { + if testing.Short() { + t.Skip() + } + execStatement(t, "create table ddl_test2(id int, val1 varbinary(128), val2 varbinary(128), primary key(id))") defer execStatement(t, "drop table ddl_test2") @@ -360,13 +472,17 @@ func TestDDLDropColumn(t *testing.T) { }() defer close(ch) err = vstream(ctx, t, pos, nil, ch) - want := "Column count doesn't match value" - if err == nil || strings.Contains(err.Error(), want) { + want := "cannot determine table columns" + if err == nil || !strings.Contains(err.Error(), want) { t.Errorf("err: %v, must contain %s", err, want) } } func TestBuffering(t *testing.T) { + if testing.Short() { + t.Skip() + } + savedSize := *packetSize *packetSize = 10 defer func() { *packetSize = savedSize }() @@ -386,6 +502,7 @@ func TestBuffering(t *testing.T) { output: [][]string{{ `gtid|begin`, `gtid|begin`, + `type:FIELD field_event: fields: > `, `type:ROW row_event: > > `, `type:ROW row_event: > > `, `commit`, @@ -462,18 +579,24 @@ func TestBuffering(t *testing.T) { } func TestTypes(t *testing.T) { + if testing.Short() { + t.Skip() + } + // Modeled after vttablet endtoend compatibility tests. 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))", "create table vitess_fracts(id int, deci decimal(5,2), num numeric(5,2), f float, d double, primary key(id))", "create table vitess_strings(vb varbinary(16), c char(16), vc varchar(16), b binary(4), tb tinyblob, bl blob, ttx tinytext, tx text, en enum('a','b'), s set('a','b'), primary key(vb))", "create table vitess_misc(id int, b bit(8), d date, dt datetime, t time, g geometry, primary key(id))", + "create table vitess_null(id int, val varbinary(128), primary key(id))", }) defer execStatements(t, []string{ "drop table vitess_ints", "drop table vitess_fracts", "drop table vitess_strings", "drop table vitess_misc", + "drop table vitess_null", }) engine.se.Reload(context.Background()) @@ -484,6 +607,18 @@ func TestTypes(t *testing.T) { output: [][]string{{ `gtid|begin`, `gtid|begin`, + `type:FIELD field_event: ` + + `fields: ` + + `fields: ` + + `fields: ` + + `fields: ` + + `fields: ` + + `fields: ` + + `fields: ` + + `fields: ` + + `fields: ` + + `fields: > `, `type:ROW row_event: ` + + `fields: ` + + `fields: ` + + `fields: ` + + `fields: > `, `type:ROW row_event: ` + + `fields: ` + + `fields: ` + + `fields: ` + + `fields: ` + + `fields: ` + + `fields: ` + + `fields: ` + + `fields: ` + + `fields: > `, `type:ROW row_event: > > `, `commit`, @@ -535,6 +687,13 @@ func TestTypes(t *testing.T) { output: [][]string{{ `gtid|begin`, `gtid|begin`, + `type:FIELD field_event: ` + + `fields: ` + + `fields: ` + + `fields: ` + + `fields: ` + + `fields: > `, `type:ROW row_event: > > `, `commit`, }}, + }, { + input: []string{ + "insert into vitess_null values(1, null)", + }, + output: [][]string{{ + `gtid|begin`, + `gtid|begin`, + `type:FIELD field_event: fields: > `, + `type:ROW row_event: > > `, + `commit`, + }}, }} runCases(t, nil, testcases) } func TestJSON(t *testing.T) { + if testing.Short() { + t.Skip() + } + // JSON is supported only after mysql57. if err := mysqld.ExecuteSuperQuery(context.Background(), "create table vitess_json(id int default 1, val json, primary key(id))"); err != nil { // If it's a syntax error, MySQL is an older version. Skip this test. @@ -568,6 +742,7 @@ func TestJSON(t *testing.T) { output: [][]string{{ `gtid|begin`, `gtid|begin`, + `type:FIELD field_event: fields: > `, `type:ROW row_event: > > `, `commit`, }}, @@ -575,6 +750,120 @@ func TestJSON(t *testing.T) { runCases(t, nil, testcases) } +func TestExternalTable(t *testing.T) { + if testing.Short() { + t.Skip() + } + + execStatements(t, []string{ + "create database external", + "create table external.ext(id int, val varbinary(128), primary key(id))", + }) + defer execStatements(t, []string{ + "drop database external", + }) + engine.se.Reload(context.Background()) + + testcases := []testcase{{ + input: []string{ + "begin", + "insert into external.ext values (1, 'aaa')", + "commit", + }, + // External table events don't get sent. + output: [][]string{{ + `gtid|begin`, + `gtid|begin`, + `commit`, + }}, + }} + runCases(t, nil, testcases) +} + +func TestMinimalMode(t *testing.T) { + if testing.Short() { + t.Skip() + } + + execStatements(t, []string{ + "create table t1(id int, val1 varbinary(128), val2 varbinary(128), primary key(id))", + "insert into t1 values(1, 'aaa', 'bbb')", + }) + defer execStatements(t, []string{ + "drop table t1", + }) + engine.se.Reload(context.Background()) + + // Record position before the next few statements. + pos, err := mysqld.MasterPosition() + if err != nil { + t.Fatal(err) + } + execStatements(t, []string{ + "set @@session.binlog_row_image='minimal'", + "update t1 set val1='bbb' where id=1", + "set @@session.binlog_row_image='full'", + }) + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + ch := make(chan []*binlogdatapb.VEvent) + go func() { + for evs := range ch { + t.Errorf("received: %v", evs) + } + }() + defer close(ch) + err = vstream(ctx, t, pos, nil, ch) + want := "partial row image encountered" + if err == nil || !strings.Contains(err.Error(), want) { + t.Errorf("err: %v, must contain '%s'", err, want) + } +} + +func TestStatementMode(t *testing.T) { + if testing.Short() { + t.Skip() + } + + execStatements(t, []string{ + "create table t1(id int, val1 varbinary(128), val2 varbinary(128), primary key(id))", + "insert into t1 values(1, 'aaa', 'bbb')", + }) + defer execStatements(t, []string{ + "drop table t1", + }) + engine.se.Reload(context.Background()) + + // Record position before the next few statements. + pos, err := mysqld.MasterPosition() + if err != nil { + t.Fatal(err) + } + execStatements(t, []string{ + "set @@session.binlog_format='statement'", + "update t1 set val1='bbb' where id=1", + "set @@session.binlog_format='row'", + }) + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + ch := make(chan []*binlogdatapb.VEvent) + go func() { + for evs := range ch { + t.Errorf("received: %v", evs) + } + }() + defer close(ch) + err = vstream(ctx, t, pos, nil, ch) + want := "unexpected statement type" + if err == nil || !strings.Contains(err.Error(), want) { + t.Errorf("err: %v, must contain '%s'", err, want) + } +} + func runCases(t *testing.T, filter *binlogdatapb.Filter, testcases []testcase) { t.Helper() ctx, cancel := context.WithCancel(context.Background()) diff --git a/proto/binlogdata.proto b/proto/binlogdata.proto index e7a90bee538..8c758d9895f 100644 --- a/proto/binlogdata.proto +++ b/proto/binlogdata.proto @@ -172,6 +172,7 @@ enum VEventType { SET = 10; OTHER = 11; ROW = 12; + FIELD = 13; } // RowChange represents one row change @@ -186,12 +187,18 @@ message RowEvent { repeated RowChange row_changes = 2; } +message FieldEvent { + string table_name = 1; + repeated query.Field fields = 2; +} + // VEvent represents a vstream event message VEvent { VEventType type = 1; string gtid = 2; string ddl = 3; RowEvent row_event = 4; + FieldEvent field_event = 5; } // VStreamRequest is the payload for VStream diff --git a/py/vtproto/binlogdata_pb2.py b/py/vtproto/binlogdata_pb2.py index 494106e8187..d9d8e896d92 100644 --- a/py/vtproto/binlogdata_pb2.py +++ b/py/vtproto/binlogdata_pb2.py @@ -22,7 +22,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\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\"\xb5\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\"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\"r\n\x06VEvent\x12$\n\x04type\x18\x01 \x01(\x0e\x32\x16.binlogdata.VEventType\x12\x0c\n\x04gtid\x18\x02 \x01(\t\x12\x0b\n\x03\x64\x64l\x18\x03 \x01(\t\x12\'\n\trow_event\x18\x04 \x01(\x0b\x32\x14.binlogdata.RowEvent\"F\n\x0eVStreamRequest\x12\x10\n\x08position\x18\x01 \x01(\t\x12\"\n\x06\x66ilter\x18\x02 \x01(\x0b\x32\x12.binlogdata.Filter\"4\n\x0fVStreamResponse\x12!\n\x05\x65vent\x18\x01 \x03(\x0b\x32\x12.binlogdata.VEvent*\x9f\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\x42)Z\'vitess.io/vitess/go/vt/proto/binlogdatab\x06proto3') + serialized_pb=_b('\n\x10\x62inlogdata.proto\x12\nbinlogdata\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\"\xb5\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\"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\"\x9f\x01\n\x06VEvent\x12$\n\x04type\x18\x01 \x01(\x0e\x32\x16.binlogdata.VEventType\x12\x0c\n\x04gtid\x18\x02 \x01(\t\x12\x0b\n\x03\x64\x64l\x18\x03 \x01(\t\x12\'\n\trow_event\x18\x04 \x01(\x0b\x32\x14.binlogdata.RowEvent\x12+\n\x0b\x66ield_event\x18\x05 \x01(\x0b\x32\x16.binlogdata.FieldEvent\"F\n\x0eVStreamRequest\x12\x10\n\x08position\x18\x01 \x01(\t\x12\"\n\x06\x66ilter\x18\x02 \x01(\x0b\x32\x12.binlogdata.Filter\"4\n\x0fVStreamResponse\x12!\n\x05\x65vent\x18\x01 \x03(\x0b\x32\x12.binlogdata.VEvent*\xaa\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\rB)Z\'vitess.io/vitess/go/vt/proto/binlogdatab\x06proto3') , dependencies=[query__pb2.DESCRIPTOR,topodata__pb2.DESCRIPTOR,]) @@ -84,11 +84,15 @@ name='ROW', index=12, number=12, serialized_options=None, type=None), + _descriptor.EnumValueDescriptor( + name='FIELD', index=13, number=13, + serialized_options=None, + type=None), ], containing_type=None, serialized_options=None, - serialized_start=1594, - serialized_end=1753, + serialized_start=1704, + serialized_end=1874, ) _sym_db.RegisterEnumDescriptor(_VEVENTTYPE) @@ -106,6 +110,7 @@ SET = 10 OTHER = 11 ROW = 12 +FIELD = 13 _BINLOGTRANSACTION_STATEMENT_CATEGORY = _descriptor.EnumDescriptor( @@ -654,6 +659,44 @@ ) +_FIELDEVENT = _descriptor.Descriptor( + name='FieldEvent', + full_name='binlogdata.FieldEvent', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='table_name', full_name='binlogdata.FieldEvent.table_name', 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), + _descriptor.FieldDescriptor( + name='fields', full_name='binlogdata.FieldEvent.fields', index=1, + number=2, 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=1351, + serialized_end=1413, +) + + _VEVENT = _descriptor.Descriptor( name='VEvent', full_name='binlogdata.VEvent', @@ -689,6 +732,13 @@ message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='field_event', full_name='binlogdata.VEvent.field_event', index=4, + number=5, 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=[ ], @@ -701,8 +751,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=1351, - serialized_end=1465, + serialized_start=1416, + serialized_end=1575, ) @@ -739,8 +789,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=1467, - serialized_end=1537, + serialized_start=1577, + serialized_end=1647, ) @@ -770,8 +820,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=1539, - serialized_end=1591, + serialized_start=1649, + serialized_end=1701, ) _BINLOGTRANSACTION_STATEMENT.fields_by_name['category'].enum_type = _BINLOGTRANSACTION_STATEMENT_CATEGORY @@ -792,8 +842,10 @@ _ROWCHANGE.fields_by_name['before'].message_type = query__pb2._ROW _ROWCHANGE.fields_by_name['after'].message_type = query__pb2._ROW _ROWEVENT.fields_by_name['row_changes'].message_type = _ROWCHANGE +_FIELDEVENT.fields_by_name['fields'].message_type = query__pb2._FIELD _VEVENT.fields_by_name['type'].enum_type = _VEVENTTYPE _VEVENT.fields_by_name['row_event'].message_type = _ROWEVENT +_VEVENT.fields_by_name['field_event'].message_type = _FIELDEVENT _VSTREAMREQUEST.fields_by_name['filter'].message_type = _FILTER _VSTREAMRESPONSE.fields_by_name['event'].message_type = _VEVENT DESCRIPTOR.message_types_by_name['Charset'] = _CHARSET @@ -807,6 +859,7 @@ DESCRIPTOR.message_types_by_name['BinlogSource'] = _BINLOGSOURCE DESCRIPTOR.message_types_by_name['RowChange'] = _ROWCHANGE DESCRIPTOR.message_types_by_name['RowEvent'] = _ROWEVENT +DESCRIPTOR.message_types_by_name['FieldEvent'] = _FIELDEVENT DESCRIPTOR.message_types_by_name['VEvent'] = _VEVENT DESCRIPTOR.message_types_by_name['VStreamRequest'] = _VSTREAMREQUEST DESCRIPTOR.message_types_by_name['VStreamResponse'] = _VSTREAMRESPONSE @@ -898,6 +951,13 @@ )) _sym_db.RegisterMessage(RowEvent) +FieldEvent = _reflection.GeneratedProtocolMessageType('FieldEvent', (_message.Message,), dict( + DESCRIPTOR = _FIELDEVENT, + __module__ = 'binlogdata_pb2' + # @@protoc_insertion_point(class_scope:binlogdata.FieldEvent) + )) +_sym_db.RegisterMessage(FieldEvent) + VEvent = _reflection.GeneratedProtocolMessageType('VEvent', (_message.Message,), dict( DESCRIPTOR = _VEVENT, __module__ = 'binlogdata_pb2' From 01aa2331cf65c7694833bd1fb6a451bd50fb8cbc Mon Sep 17 00:00:00 2001 From: Sugu Sougoumarane Date: Wed, 2 Jan 2019 11:43:08 -0800 Subject: [PATCH 029/115] vreplication: vstream final tweaks Signed-off-by: Sugu Sougoumarane --- go/vt/vttablet/endtoend/framework/server.go | 52 ++++++------------- .../vttablet/tabletserver/vstreamer/engine.go | 6 ++- .../tabletserver/vstreamer/vstreamer.go | 2 + 3 files changed, 22 insertions(+), 38 deletions(-) diff --git a/go/vt/vttablet/endtoend/framework/server.go b/go/vt/vttablet/endtoend/framework/server.go index 5f39a12e65c..d267c231f41 100644 --- a/go/vt/vttablet/endtoend/framework/server.go +++ b/go/vt/vttablet/endtoend/framework/server.go @@ -22,9 +22,6 @@ import ( "net/http" "time" - "vitess.io/vitess/go/vt/mysqlctl" - "vitess.io/vitess/go/vt/topo" - "vitess.io/vitess/go/vt/topo/topoproto" "vitess.io/vitess/go/vt/vterrors" "golang.org/x/net/context" @@ -49,29 +46,12 @@ var ( ServerAddress string // ResolveChan is the channel that sends dtids that are to be resolved. ResolveChan = make(chan string, 1) - // Mysqld is for sending direct commands to mysql - Mysqld *mysqlctl.Mysqld ) -// StartServer starts the server with configs set for endtoend testing. +// StartServer starts the server and initializes +// all the global variables. This function should only be called +// once at the beginning of the test. func StartServer(connParams, connAppDebugParams mysql.ConnParams, dbName string) error { - config := tabletenv.DefaultQsConfig - config.EnableAutoCommit = true - config.StrictTableACL = true - config.TwoPCEnable = true - config.TwoPCAbandonAge = 1 - config.TwoPCCoordinatorAddress = "fake" - config.EnableHotRowProtection = true - - return startServer(nil, config, connParams, connAppDebugParams, dbName, "", "") -} - -// StartFullServer is like StartServer, but with more configurable options. -func StartFullServer(ts *topo.Server, config tabletenv.TabletConfig, connParams, connAppDebugParams mysql.ConnParams, dbName, keyspaceName, alias string) error { - return startServer(ts, config, connParams, connAppDebugParams, dbName, keyspaceName, alias) -} - -func startServer(ts *topo.Server, config tabletenv.TabletConfig, connParams, connAppDebugParams mysql.ConnParams, dbName, keyspaceName, alias string) error { // Setup a fake vtgate server. protocol := "resolveTest" *vtgateconn.VtgateProtocol = protocol @@ -82,26 +62,25 @@ func startServer(ts *topo.Server, config tabletenv.TabletConfig, connParams, con }) dbcfgs := dbconfigs.NewTestDBConfigs(connParams, connAppDebugParams, dbName) - Mysqld = mysqlctl.NewMysqld(dbcfgs) + + config := tabletenv.DefaultQsConfig + config.EnableAutoCommit = true + config.StrictTableACL = true + config.TwoPCEnable = true + config.TwoPCAbandonAge = 1 + config.TwoPCCoordinatorAddress = "fake" + config.EnableHotRowProtection = true Target = querypb.Target{ - Keyspace: keyspaceName, + Keyspace: "vttest", Shard: "0", TabletType: topodatapb.TabletType_MASTER, } - if ts == nil { - Server = tabletserver.NewTabletServerWithNilTopoServer(config) - } else { - talias, err := topoproto.ParseTabletAlias(alias) - if err != nil { - return err - } - Server = tabletserver.NewTabletServer(config, ts, *talias) - } - + Server = tabletserver.NewTabletServerWithNilTopoServer(config) Server.Register() - if err := Server.StartService(Target, dbcfgs); err != nil { + err := Server.StartService(Target, dbcfgs) + if err != nil { return vterrors.Wrap(err, "could not start service") } @@ -125,7 +104,6 @@ func startServer(ts *topo.Server, config tabletenv.TabletConfig, connParams, con // StopServer must be called once all the tests are done. func StopServer() { - Mysqld.Close() Server.StopService() } diff --git a/go/vt/vttablet/tabletserver/vstreamer/engine.go b/go/vt/vttablet/tabletserver/vstreamer/engine.go index c46c14d5b5a..7370314a2fa 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/engine.go +++ b/go/vt/vttablet/tabletserver/vstreamer/engine.go @@ -44,7 +44,7 @@ var ( vschemaUpdates *stats.Counter ) -// Engine is the engine for handling vseplication streaming requests. +// Engine is the engine for handling vreplication streaming requests. type Engine struct { // cp is initialized by InitDBConfig cp *mysql.ConnParams @@ -54,6 +54,7 @@ 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 streamIdx int @@ -65,6 +66,7 @@ type Engine struct { watcherOnce sync.Once kschema *vindexes.KeyspaceSchema + // The following members are initialized once at the beginning. ts srvtopo.Server se *schema.Engine keyspace string @@ -72,6 +74,8 @@ type Engine struct { } // NewEngine creates a new Engine. +// Initialization sequence is: NewEngine->InitDBConfig->Open. +// 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), diff --git a/go/vt/vttablet/tabletserver/vstreamer/vstreamer.go b/go/vt/vttablet/tabletserver/vstreamer/vstreamer.go index 83a5b8d1c6e..e2b4f74c213 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/vstreamer.go +++ b/go/vt/vttablet/tabletserver/vstreamer/vstreamer.go @@ -45,6 +45,7 @@ type vstreamer struct { filter *binlogdatapb.Filter send func([]*binlogdatapb.VEvent) error + // A kschema is a VSchema for just one keyspace. kevents chan *vindexes.KeyspaceSchema kschema *vindexes.KeyspaceSchema plans map[uint64]*Plan @@ -70,6 +71,7 @@ func newVStreamer(ctx context.Context, cp *mysql.ConnParams, se *schema.Engine, } } +// SetKSchema updates all existing against the new kschema. func (vs *vstreamer) SetKSchema(kschema *vindexes.KeyspaceSchema) { // Since vs.Stream is a single-threaded loop. We just send an event to // that thread, which helps us avoid mutexes to update the plans. From de9dd9c168edff1887720704baf9e75178d397f6 Mon Sep 17 00:00:00 2001 From: Michael Hebelka Date: Thu, 3 Jan 2019 13:27:17 -0500 Subject: [PATCH 030/115] Add group specification to mysql static auth for ACL usage Signed-off-by: Michael Hebelka --- go/mysql/auth_server_static.go | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/go/mysql/auth_server_static.go b/go/mysql/auth_server_static.go index 34fcd7c884b..c6e3004544c 100644 --- a/go/mysql/auth_server_static.go +++ b/go/mysql/auth_server_static.go @@ -72,6 +72,7 @@ type AuthServerStaticEntry struct { Password string UserData string SourceHost string + Groups []string } // InitAuthServerStatic Handles initializing the AuthServerStatic if necessary. @@ -204,24 +205,24 @@ func (a *AuthServerStatic) ValidateHash(salt []byte, user string, authResponse [ a.mu.Unlock() if !ok { - return &StaticUserData{""}, NewSQLError(ERAccessDeniedError, SSAccessDeniedError, "Access denied for user '%v'", user) + return &StaticUserData{}, NewSQLError(ERAccessDeniedError, SSAccessDeniedError, "Access denied for user '%v'", user) } for _, entry := range entries { if entry.MysqlNativePassword != "" { isPass := isPassScrambleMysqlNativePassword(authResponse, salt, entry.MysqlNativePassword) if matchSourceHost(remoteAddr, entry.SourceHost) && isPass { - return &StaticUserData{entry.UserData}, nil + return &StaticUserData{entry.UserData, entry.Groups}, nil } } else { computedAuthResponse := ScramblePassword(salt, []byte(entry.Password)) // Validate the password. if matchSourceHost(remoteAddr, entry.SourceHost) && bytes.Compare(authResponse, computedAuthResponse) == 0 { - return &StaticUserData{entry.UserData}, nil + return &StaticUserData{entry.UserData, entry.Groups}, nil } } } - return &StaticUserData{""}, NewSQLError(ERAccessDeniedError, SSAccessDeniedError, "Access denied for user '%v'", user) + return &StaticUserData{}, NewSQLError(ERAccessDeniedError, SSAccessDeniedError, "Access denied for user '%v'", user) } // Negotiate is part of the AuthServer interface. @@ -239,15 +240,15 @@ func (a *AuthServerStatic) Negotiate(c *Conn, user string, remoteAddr net.Addr) a.mu.Unlock() if !ok { - return &StaticUserData{""}, NewSQLError(ERAccessDeniedError, SSAccessDeniedError, "Access denied for user '%v'", user) + return &StaticUserData{}, NewSQLError(ERAccessDeniedError, SSAccessDeniedError, "Access denied for user '%v'", user) } for _, entry := range entries { // Validate the password. if matchSourceHost(remoteAddr, entry.SourceHost) && entry.Password == password { - return &StaticUserData{entry.UserData}, nil + return &StaticUserData{entry.UserData, entry.Groups}, nil } } - return &StaticUserData{""}, NewSQLError(ERAccessDeniedError, SSAccessDeniedError, "Access denied for user '%v'", user) + return &StaticUserData{}, NewSQLError(ERAccessDeniedError, SSAccessDeniedError, "Access denied for user '%v'", user) } func matchSourceHost(remoteAddr net.Addr, targetSourceHost string) bool { @@ -264,12 +265,13 @@ func matchSourceHost(remoteAddr net.Addr, targetSourceHost string) bool { return false } -// StaticUserData holds the username +// StaticUserData holds the username and groups type StaticUserData struct { - value string + username string + groups []string } -// Get returns the wrapped username +// Get returns the wrapped username and groups func (sud *StaticUserData) Get() *querypb.VTGateCallerID { - return &querypb.VTGateCallerID{Username: sud.value} + return &querypb.VTGateCallerID{Username: sud.username, Groups: sud.groups} } From 5be6e2a20d26a87edabcc6c23928c52170ae443d Mon Sep 17 00:00:00 2001 From: Michael Hebelka Date: Thu, 3 Jan 2019 17:02:13 -0500 Subject: [PATCH 031/115] Add a StaticUserData test and update json parsing test Signed-off-by: Michael Hebelka --- go/mysql/auth_server_static_test.go | 44 ++++++++++++++++++++++++++--- 1 file changed, 40 insertions(+), 4 deletions(-) diff --git a/go/mysql/auth_server_static_test.go b/go/mysql/auth_server_static_test.go index a1fd2809d11..ef4e9bd47b9 100644 --- a/go/mysql/auth_server_static_test.go +++ b/go/mysql/auth_server_static_test.go @@ -42,17 +42,53 @@ func TestJsonConfigParser(t *testing.T) { t.Fatalf("mysql_user config size should be equal to 1") } // works with new format - jsonConfig = "{\"mysql_user\":[{\"Password\":\"123\", \"UserData\":\"dummy\", \"SourceHost\": \"localhost\"}, {\"Password\": \"123\", \"UserData\": \"mysql_user_all\"}]}" + jsonConfig = `{"mysql_user":[ + {"Password":"123", "UserData":"dummy", "SourceHost": "localhost"}, + {"Password": "123", "UserData": "mysql_user_all"}, + {"Password": "456", "UserData": "mysql_user_with_groups", "Groups": ["user_group"]} + ]}` err = parseConfig([]byte(jsonConfig), &config) if err != nil { t.Fatalf("should not get an error, but got: %v", err) } - if len(config["mysql_user"]) != 2 { - t.Fatalf("mysql_user config size should be equal to 2") + if len(config["mysql_user"]) != 3 { + t.Fatalf("mysql_user config size should be equal to 3") } if config["mysql_user"][0].SourceHost != "localhost" { - t.Fatalf("SourceHost should be equal localhost") + t.Fatalf("SourceHost should be equal to localhost") + } + + if len(config["mysql_user"][2].Groups) != 1 || config["mysql_user"][2].Groups[0] != "user_group" { + t.Fatalf("Groups should be equal to [\"user_group\"]") + } +} + +func TestValidateHashGetter(t *testing.T) { + jsonConfig := `{"mysql_user": [{"Password": "password", "UserData": "user.name", "Groups": ["user_group"]}]}` + + auth := NewAuthServerStatic() + auth.loadConfigFromParams("", jsonConfig) + ip := net.ParseIP("127.0.0.1") + addr := &net.IPAddr{IP: ip, Zone: ""} + + salt, err := NewSalt() + if err != nil { + t.Fatalf("error generating salt: %v", err) + } + + scrambled := ScramblePassword(salt, []byte("password")) + getter, err := auth.ValidateHash(salt, "mysql_user", scrambled, addr) + if err != nil { + t.Fatalf("error validating password: %v", err) + } + + callerId := getter.Get() + if callerId.Username != "user.name" { + t.Fatalf("getter username incorrect, expected \"user.name\", got %v", callerId.Username) + } + if len(callerId.Groups) != 1 || callerId.Groups[0] != "user_group" { + t.Fatalf("getter groups incorrect, expected [\"user_group\"], got %v", callerId.Groups) } } From 3a04099fe5ee41730384d5ef7c74a946672617f7 Mon Sep 17 00:00:00 2001 From: David Weitzman Date: Fri, 4 Jan 2019 08:51:53 -0800 Subject: [PATCH 032/115] Fix MultiSplitDiff incorrectly logging "have already found differences" Signed-off-by: David Weitzman --- go/vt/worker/multi_split_diff.go | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/go/vt/worker/multi_split_diff.go b/go/vt/worker/multi_split_diff.go index dbf899883fa..71ee4c22c28 100644 --- a/go/vt/worker/multi_split_diff.go +++ b/go/vt/worker/multi_split_diff.go @@ -19,26 +19,21 @@ package worker import ( "fmt" "html/template" - "sync" - - "vitess.io/vitess/go/vt/vterrors" - - "golang.org/x/net/context" - - "vitess.io/vitess/go/vt/concurrency" - "vitess.io/vitess/go/vt/mysqlctl/tmutils" - "vitess.io/vitess/go/vt/topo" - "vitess.io/vitess/go/vt/wrangler" - "sort" - + "sync" "time" + "golang.org/x/net/context" "vitess.io/vitess/go/sqltypes" "vitess.io/vitess/go/vt/binlog/binlogplayer" + "vitess.io/vitess/go/vt/concurrency" + "vitess.io/vitess/go/vt/mysqlctl/tmutils" 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/vterrors" "vitess.io/vitess/go/vt/vtgate/vindexes" + "vitess.io/vitess/go/vt/wrangler" ) // MultiSplitDiffWorker executes a diff between a destination shard and its @@ -631,7 +626,9 @@ func (msdw *MultiSplitDiffWorker) gatherSchemaInfo(ctx context.Context) ([]*tabl destinationSchemaDefinition, err := msdw.wr.GetSchema( shortCtx, destinationAlias, nil /* tables */, msdw.excludeTables, false /* includeViews */) cancel() - msdw.markAsWillFail(rec, err) + if err != nil { + msdw.markAsWillFail(rec, err) + } destinationSchemaDefinitions[i] = destinationSchemaDefinition msdw.wr.Logger().Infof("Got schema from destination %v", destinationAlias) wg.Done() @@ -644,7 +641,9 @@ func (msdw *MultiSplitDiffWorker) gatherSchemaInfo(ctx context.Context) ([]*tabl sourceSchemaDefinition, err = msdw.wr.GetSchema( shortCtx, msdw.sourceAlias, nil /* tables */, msdw.excludeTables, false /* includeViews */) cancel() - msdw.markAsWillFail(rec, err) + if err != nil { + msdw.markAsWillFail(rec, err) + } msdw.wr.Logger().Infof("Got schema from source %v", msdw.sourceAlias) wg.Done() }() From 5147e9f7e660c8dbba8acf8df320a7ea2e6b3102 Mon Sep 17 00:00:00 2001 From: David Weitzman Date: Wed, 12 Dec 2018 16:13:15 -0800 Subject: [PATCH 033/115] Don't freeze with no serving shards if reversing vreplication fails during MigrateServedTypes Signed-off-by: David Weitzman --- go/vt/wrangler/keyspace.go | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/go/vt/wrangler/keyspace.go b/go/vt/wrangler/keyspace.go index 1e5cd10200a..29a64533b55 100644 --- a/go/vt/wrangler/keyspace.go +++ b/go/vt/wrangler/keyspace.go @@ -29,14 +29,13 @@ import ( "vitess.io/vitess/go/vt/binlog/binlogplayer" "vitess.io/vitess/go/vt/concurrency" "vitess.io/vitess/go/vt/discovery" + binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" + topodatapb "vitess.io/vitess/go/vt/proto/topodata" + vschemapb "vitess.io/vitess/go/vt/proto/vschema" "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" - - binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" - topodatapb "vitess.io/vitess/go/vt/proto/topodata" - vschemapb "vitess.io/vitess/go/vt/proto/vschema" ) const ( @@ -553,6 +552,13 @@ func (wr *Wrangler) masterMigrateServedType(ctx context.Context, keyspace string // Always setup reverse replication. We'll start it later if reverseReplication was specified. // This will allow someone to reverse the replication later if they change their mind. if err := wr.setupReverseReplication(ctx, sourceShards, destinationShards); err != nil { + // It's safe to unfreeze if reverse replication setup fails. + wr.cancelMasterMigrateServedTypes(ctx, sourceShards) + unfreezeErr := wr.updateFrozenFlag(ctx, sourceShards, false) + if unfreezeErr != nil { + wr.Logger().Errorf("Problem recovering for failed reverse replication: %v", unfreezeErr) + } + return err } From 96e7c5ddbac7fb29cbd0c6e978dd9c2fdd07f0ed Mon Sep 17 00:00:00 2001 From: David Weitzman Date: Fri, 4 Jan 2019 10:47:37 -0800 Subject: [PATCH 034/115] Delete orphan SourceShard records for a failed master migration with reverse replication enabled Signed-off-by: David Weitzman --- go/vt/wrangler/keyspace.go | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/go/vt/wrangler/keyspace.go b/go/vt/wrangler/keyspace.go index 29a64533b55..a98a467feef 100644 --- a/go/vt/wrangler/keyspace.go +++ b/go/vt/wrangler/keyspace.go @@ -474,13 +474,13 @@ func (wr *Wrangler) replicaMigrateServedType(ctx context.Context, keyspace strin // Check and update all source shard records. // Enable query service if needed event.DispatchUpdate(ev, "updating shards to migrate from") - if err = wr.updateShardRecords(ctx, fromShards, cells, servedType, true); err != nil { + if err = wr.updateShardRecords(ctx, fromShards, cells, servedType, true, false); err != nil { return err } // Do the same for destination shards event.DispatchUpdate(ev, "updating shards to migrate to") - if err = wr.updateShardRecords(ctx, toShards, cells, servedType, false); err != nil { + if err = wr.updateShardRecords(ctx, toShards, cells, servedType, false, false); err != nil { return err } @@ -520,7 +520,7 @@ func (wr *Wrangler) masterMigrateServedType(ctx context.Context, keyspace string // - wait for filtered replication to catch up // - mark source shards as frozen event.DispatchUpdate(ev, "disabling query service on all source masters") - if err := wr.updateShardRecords(ctx, sourceShards, nil, topodatapb.TabletType_MASTER, true); err != nil { + if err := wr.updateShardRecords(ctx, sourceShards, nil, topodatapb.TabletType_MASTER, true, false); err != nil { wr.cancelMasterMigrateServedTypes(ctx, sourceShards) return err } @@ -612,7 +612,7 @@ func (wr *Wrangler) masterMigrateServedType(ctx context.Context, keyspace string } func (wr *Wrangler) cancelMasterMigrateServedTypes(ctx context.Context, sourceShards []*topo.ShardInfo) { - if err := wr.updateShardRecords(ctx, sourceShards, nil, topodatapb.TabletType_MASTER, false); err != nil { + if err := wr.updateShardRecords(ctx, sourceShards, nil, topodatapb.TabletType_MASTER, false, true); err != nil { wr.Logger().Errorf2(err, "failed to re-enable source masters") return } @@ -698,9 +698,12 @@ func (wr *Wrangler) startReverseReplication(ctx context.Context, sourceShards [] } // updateShardRecords updates the shard records based on 'from' or 'to' direction. -func (wr *Wrangler) updateShardRecords(ctx context.Context, shards []*topo.ShardInfo, cells []string, servedType topodatapb.TabletType, isFrom bool) (err error) { +func (wr *Wrangler) updateShardRecords(ctx context.Context, shards []*topo.ShardInfo, cells []string, servedType topodatapb.TabletType, isFrom bool, clearSourceShards bool) (err error) { for i, si := range shards { shards[i], err = wr.ts.UpdateShardFields(ctx, si.Keyspace(), si.ShardName(), func(si *topo.ShardInfo) error { + if clearSourceShards { + si.SourceShards = nil + } if err := si.UpdateServedTypesMap(servedType, cells, isFrom /* remove */); err != nil { return err } From 230bf56e00a20335cfa00ea9a852a4a567e6b70b Mon Sep 17 00:00:00 2001 From: David Weitzman Date: Fri, 4 Jan 2019 11:33:39 -0800 Subject: [PATCH 035/115] Gracefully re-create the vreplication table if it disappears It might disappear due to someone manually mucking with the db without restarting the tablet. We hit this due to having a test environment where the db can be restored to a pre-sharding snapshot withou the tablet restarting. Prior to this change the tablet would have mustCreate false and would fail to adapt to disappearence of the vreplication table. Signed-off-by: David Weitzman --- .../tabletmanager/vreplication/engine.go | 54 ++++++++++++------- .../tabletmanager/vreplication/engine_test.go | 31 +++++++++-- 2 files changed, 63 insertions(+), 22 deletions(-) diff --git a/go/vt/vttablet/tabletmanager/vreplication/engine.go b/go/vt/vttablet/tabletmanager/vreplication/engine.go index 1b272473694..c499225cf4c 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/engine.go +++ b/go/vt/vttablet/tabletmanager/vreplication/engine.go @@ -24,7 +24,6 @@ import ( "time" "golang.org/x/net/context" - "vitess.io/vitess/go/mysql" "vitess.io/vitess/go/sqltypes" "vitess.io/vitess/go/vt/binlog/binlogplayer" @@ -51,8 +50,7 @@ type Engine struct { isOpen bool controllers map[int]*controller // wg is used by in-flight functions that can run for long periods. - wg sync.WaitGroup - mustCreate bool + wg sync.WaitGroup // ctx is the root context for all controllers. ctx context.Context @@ -100,6 +98,34 @@ func (vre *Engine) Open(ctx context.Context) error { return nil } +// executeFetchMaybeCreateTable calls DBClient.ExecuteFetch and does one retry if +// there's a failure due to mysql.ERNoSuchTable or mysql.ERBadDb which can be fixed +// by re-creating the _vt.vreplication table. +func (vre *Engine) executeFetchMaybeCreateTable(dbClient binlogplayer.DBClient, query string, maxrows int) (qr *sqltypes.Result, err error) { + qr, err = dbClient.ExecuteFetch(query, maxrows) + + if err == nil { + return + } + + // If it's a bad table or db, it could be because _vt.vreplication wasn't created. + // In that case we can try creating it again. + merr, isSQLErr := err.(*mysql.SQLError) + if !isSQLErr || !(merr.Num == mysql.ERNoSuchTable || merr.Num == mysql.ERBadDb) { + return qr, err + } + + log.Info("Looks like _vt.vreplication table may not exist. Trying to recreate... ") + for _, query := range binlogplayer.CreateVReplicationTable() { + if _, merr := dbClient.ExecuteFetch(query, 0); merr != nil { + log.Warningf("Failed to ensure _vt.vreplication table exists: %v", merr) + return nil, err + } + } + + return dbClient.ExecuteFetch(query, maxrows) +} + func (vre *Engine) initAll() error { dbClient := vre.dbClientFactory() if err := dbClient.Connect(); err != nil { @@ -110,8 +136,7 @@ func (vre *Engine) initAll() error { rows, err := readAllRows(dbClient) if err != nil { // Handle Table not found. - if merr, ok := err.(*mysql.SQLError); ok && merr.Num == 1146 { - vre.mustCreate = true + if merr, ok := err.(*mysql.SQLError); ok && merr.Num == mysql.ERNoSuchTable { log.Info("_vt.vreplication table not found. Will create it later if needed") return nil } @@ -185,25 +210,16 @@ func (vre *Engine) Exec(query string) (*sqltypes.Result, error) { } defer dbClient.Close() - if vre.mustCreate { - for _, query := range binlogplayer.CreateVReplicationTable() { - if _, err := dbClient.ExecuteFetch(query, 0); err != nil { - return nil, err - } - } - vre.mustCreate = false - } - // Change the database to ensure that these events don't get // replicated by another vreplication. This can happen when // we reverse replication. - if _, err := dbClient.ExecuteFetch("use _vt", 1); err != nil { + if _, err := vre.executeFetchMaybeCreateTable(dbClient, "use _vt", 1); err != nil { return nil, err } switch plan.opcode { case insertQuery: - qr, err := dbClient.ExecuteFetch(plan.query, 1) + qr, err := vre.executeFetchMaybeCreateTable(dbClient, plan.query, 1) if err != nil { return nil, err } @@ -228,7 +244,7 @@ func (vre *Engine) Exec(query string) (*sqltypes.Result, error) { ct.Stop() blpStats = ct.blpStats } - qr, err := dbClient.ExecuteFetch(plan.query, 1) + qr, err := vre.executeFetchMaybeCreateTable(dbClient, plan.query, 1) if err != nil { return nil, err } @@ -250,10 +266,10 @@ func (vre *Engine) Exec(query string) (*sqltypes.Result, error) { ct.Stop() delete(vre.controllers, plan.id) } - return dbClient.ExecuteFetch(plan.query, 1) + return vre.executeFetchMaybeCreateTable(dbClient, plan.query, 1) case selectQuery: // select queries are passed through. - return dbClient.ExecuteFetch(plan.query, 10000) + return vre.executeFetchMaybeCreateTable(dbClient, plan.query, 10000) } panic("unreachable") } diff --git a/go/vt/vttablet/tabletmanager/vreplication/engine_test.go b/go/vt/vttablet/tabletmanager/vreplication/engine_test.go index 24c2140e5dd..f93ec5559e5 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/engine_test.go +++ b/go/vt/vttablet/tabletmanager/vreplication/engine_test.go @@ -26,7 +26,6 @@ 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" ) @@ -395,18 +394,39 @@ func TestCreateDBAndTable(t *testing.T) { vre := NewEngine(ts, testCell, mysqld, dbClientFactory) - notFound := mysql.SQLError{Num: 1146, Message: "not found"} - dbClient.ExpectRequest("select * from _vt.vreplication", nil, ¬Found) + tableNotFound := mysql.SQLError{Num: 1146, Message: "table not found"} + dbClient.ExpectRequest("select * from _vt.vreplication", nil, &tableNotFound) if err := vre.Open(context.Background()); err != nil { t.Fatal(err) } defer vre.Close() + // Missing db. Statement should get retried after creating everything. + dbNotFound := mysql.SQLError{Num: 1049, Message: "db not found"} + dbClient.ExpectRequest("use _vt", &sqltypes.Result{}, &dbNotFound) + 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.ExpectRequest("use _vt", &sqltypes.Result{}, nil) + + // Non-recoverable error. + unrecoverableError := &mysql.SQLError{Num: 1234, Message: "random error"} + dbClient.ExpectRequest("select fail_query from _vt.vreplication", &sqltypes.Result{}, unrecoverableError) + + // 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("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.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. + dbClient.ExpectRequest("select * from _vt.vreplication where id = 1", sqltypes.MakeTestResult( sqltypes.MakeTestFields( "id|state|source", @@ -421,6 +441,11 @@ func TestCreateDBAndTable(t *testing.T) { dbClient.ExpectRequestRE("update _vt.vreplication set pos='MariaDB/0-1-1235', time_updated=.*", testDMLResponse, nil) dbClient.ExpectRequest("commit", nil, nil) + _, err := vre.Exec("select fail_query from _vt.vreplication") + if err != unrecoverableError { + t.Errorf("Want: %v, Got: %v", unrecoverableError, err) + } + qr, err := vre.Exec("insert into _vt.vreplication values(null)") if err != nil { t.Fatal(err) From 876b842d139086a98f01827f492214c54245e294 Mon Sep 17 00:00:00 2001 From: Rafael Chacon Date: Mon, 7 Jan 2019 17:08:56 -0800 Subject: [PATCH 036/115] Check perceived tablet type before taking a backup Signed-off-by: Rafael Chacon --- go/vt/vttablet/tabletmanager/rpc_backup.go | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/go/vt/vttablet/tabletmanager/rpc_backup.go b/go/vt/vttablet/tabletmanager/rpc_backup.go index 2ad3cc2d988..8eeeb322ce1 100644 --- a/go/vt/vttablet/tabletmanager/rpc_backup.go +++ b/go/vt/vttablet/tabletmanager/rpc_backup.go @@ -40,7 +40,15 @@ func (agent *ActionAgent) Backup(ctx context.Context, concurrency int, logger lo return fmt.Errorf("cannot perform backup without my.cnf, please restart vttablet with a my.cnf file specified") } - // update our type to BACKUP + // Check tablet type current process has. + // During a network partition it is possible that from the topology perspective this is no longer the master, + // but the process didn't find out about this. + // It is not safe to take backups from tablet in this state + currentTablet := agent.Tablet() + if currentTablet.Type == topodatapb.TabletType_MASTER { + return fmt.Errorf("type MASTER cannot take backup, if you really need to do this, restart vttablet in replica mode") + } + tablet, err := agent.TopoServer.GetTablet(ctx, agent.TabletAlias) if err != nil { return err @@ -49,6 +57,8 @@ func (agent *ActionAgent) Backup(ctx context.Context, concurrency int, logger lo return fmt.Errorf("type MASTER cannot take backup, if you really need to do this, restart vttablet in replica mode") } originalType := tablet.Type + + // update our type to BACKUP if _, err := topotools.ChangeType(ctx, agent.TopoServer, tablet.Alias, topodatapb.TabletType_BACKUP); err != nil { return err } From 6ccbb93414ee02e152cfef68c97a2b5afbfdfe43 Mon Sep 17 00:00:00 2001 From: David Weitzman Date: Mon, 7 Jan 2019 18:05:07 -0800 Subject: [PATCH 037/115] Remove influxdb as a push backend The code seems to be out of date, unmaintained, and incompatible with current versions of influx and recent versions of the influx golang client. Signed-off-by: David Weitzman --- doc/Monitoring.md | 6 +- doc/ScalingMySQL.md | 2 +- go/cmd/mysqlctl/plugin_influxdbbackend.go | 23 ---- go/cmd/mysqlctld/plugin_influxdbbackend.go | 23 ---- go/cmd/vtctl/plugin_influxdbbackend.go | 23 ---- go/cmd/vtctld/plugin_influxdbbackend.go | 23 ---- go/cmd/vtgate/plugin_influxdbbackend.go | 23 ---- go/cmd/vttablet/plugin_influxdbbackend.go | 23 ---- go/cmd/vtworker/plugin_influxdbbackend.go | 23 ---- go/cmd/zkctld/plugin_influxdbbackend.go | 23 ---- go/stats/export.go | 2 +- go/stats/influxdbbackend/influxdb_backend.go | 104 ------------------- vendor/vendor.json | 8 -- 13 files changed, 5 insertions(+), 301 deletions(-) delete mode 100644 go/cmd/mysqlctl/plugin_influxdbbackend.go delete mode 100644 go/cmd/mysqlctld/plugin_influxdbbackend.go delete mode 100644 go/cmd/vtctl/plugin_influxdbbackend.go delete mode 100644 go/cmd/vtctld/plugin_influxdbbackend.go delete mode 100644 go/cmd/vtgate/plugin_influxdbbackend.go delete mode 100644 go/cmd/vttablet/plugin_influxdbbackend.go delete mode 100644 go/cmd/vtworker/plugin_influxdbbackend.go delete mode 100644 go/cmd/zkctld/plugin_influxdbbackend.go delete mode 100644 go/stats/influxdbbackend/influxdb_backend.go diff --git a/doc/Monitoring.md b/doc/Monitoring.md index 8206089a583..9722ea0ba0b 100644 --- a/doc/Monitoring.md +++ b/doc/Monitoring.md @@ -24,9 +24,9 @@ Vitess also includes support for push-based metrics systems via plug-ins. Each V By default, the stats_emit_period is 60s, so each component will push stats to the the selected backend every minute. This is configurable via the `--stats_emit_period` flag. -Vitess has preliminary plug-ins to support InfluxDB and OpenTSDB as push-based metrics backends. However, there is very limited support at this time, as InfluxDB itself is going through various API breaking changes. +Vitess has preliminary plug-ins to support OpenTSDB as a push-based metrics backend. -It should be fairly straightforward to write your own plug-in, if you want to support a different backend. The plug-in package simply needs to implement the `PushBackend` interface of the `stats` package. For an example, you can see the [InfluxDB plugin](https://github.com/vitessio/vitess/blob/master/go/stats/influxdbbackend/influxdb_backend.go). +It should be fairly straightforward to write your own plug-in, if you want to support a different backend. The plug-in package simply needs to implement the `PushBackend` interface of the `stats` package. For an example, you can see the [OpenTSDB plugin](https://github.com/vitessio/vitess/blob/master/go/stats/opentsdb/opentsdb.go). Once you’ve written the backend plug-in, you also need to register the plug-in from within all the relevant Vitess binaries. An example of how to do this can be seen in [this pull request](https://github.com/vitessio/vitess/pull/469). @@ -36,7 +36,7 @@ Connecting Vitess to a push-based metrics system can be useful if you’re alrea ## Monitoring with Kubernetes -The existing methods for integrating metrics are not supported in a Kubernetes environment by the Vitess team yet, but are on the roadmap for the future. However, it should be possible to get the InfluxDB backend working with Kubernetes, similar to how [Heapster for Kubernetes works](https://github.com/GoogleCloudPlatform/kubernetes/tree/master/cluster/addons/cluster-monitoring). +The existing methods for integrating metrics are not supported in a Kubernetes environment by the Vitess team yet, but are on the roadmap for the future. However, it should be possible to get the Prometheus backend working with Kubernetes, similar to how [Heapster for Kubernetes works](https://github.com/kubernetes/kubernetes/tree/master/cluster/addons/prometheus). In the meantime, if you run into issues or have questions, please post on our [forum](https://groups.google.com/forum/#!forum/vitess). diff --git a/doc/ScalingMySQL.md b/doc/ScalingMySQL.md index 16139991c2a..45b2544388b 100644 --- a/doc/ScalingMySQL.md +++ b/doc/ScalingMySQL.md @@ -54,7 +54,7 @@ Setting up these components directly -- for example, writing your own topology s * *Recommended*. Vitess has basic support for identifying or changing a master, but it doesn't aim to fully address this feature. As such, we recommend using another program, like [Orchestrator](https://github.com/github/orchestrator), to monitor the health of your servers and to change your master database when necessary. (In a sharded database, each shard has a master.) -* *Recommended*. You should have a way to monitor your database topology and set up alerts as needed. Vitess components facilitate this monitoring by exporting a lot of runtime variables, like QPS over the last few minutes, error rates, and query latency. The variables are exported in JSON format, and Vitess also supports an InfluxDB plug-in. +* *Recommended*. You should have a way to monitor your database topology and set up alerts as needed. Vitess components facilitate this monitoring by exporting a lot of runtime variables, like QPS over the last few minutes, error rates, and query latency. The variables are exported in JSON format, and Vitess also supports a Prometheus plug-in. * *Optional*. Using the Kubernetes scripts as a base, you could run Vitess components with other configuration management systems (like Puppet) or frameworks (like Mesos or AWS images). diff --git a/go/cmd/mysqlctl/plugin_influxdbbackend.go b/go/cmd/mysqlctl/plugin_influxdbbackend.go deleted file mode 100644 index fae7ccbb9a2..00000000000 --- a/go/cmd/mysqlctl/plugin_influxdbbackend.go +++ /dev/null @@ -1,23 +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 main - -// This plugin imports influxdbbackend to register the influxdbbackend stats backend. - -import ( - _ "vitess.io/vitess/go/stats/influxdbbackend" -) diff --git a/go/cmd/mysqlctld/plugin_influxdbbackend.go b/go/cmd/mysqlctld/plugin_influxdbbackend.go deleted file mode 100644 index fae7ccbb9a2..00000000000 --- a/go/cmd/mysqlctld/plugin_influxdbbackend.go +++ /dev/null @@ -1,23 +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 main - -// This plugin imports influxdbbackend to register the influxdbbackend stats backend. - -import ( - _ "vitess.io/vitess/go/stats/influxdbbackend" -) diff --git a/go/cmd/vtctl/plugin_influxdbbackend.go b/go/cmd/vtctl/plugin_influxdbbackend.go deleted file mode 100644 index fae7ccbb9a2..00000000000 --- a/go/cmd/vtctl/plugin_influxdbbackend.go +++ /dev/null @@ -1,23 +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 main - -// This plugin imports influxdbbackend to register the influxdbbackend stats backend. - -import ( - _ "vitess.io/vitess/go/stats/influxdbbackend" -) diff --git a/go/cmd/vtctld/plugin_influxdbbackend.go b/go/cmd/vtctld/plugin_influxdbbackend.go deleted file mode 100644 index fae7ccbb9a2..00000000000 --- a/go/cmd/vtctld/plugin_influxdbbackend.go +++ /dev/null @@ -1,23 +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 main - -// This plugin imports influxdbbackend to register the influxdbbackend stats backend. - -import ( - _ "vitess.io/vitess/go/stats/influxdbbackend" -) diff --git a/go/cmd/vtgate/plugin_influxdbbackend.go b/go/cmd/vtgate/plugin_influxdbbackend.go deleted file mode 100644 index fae7ccbb9a2..00000000000 --- a/go/cmd/vtgate/plugin_influxdbbackend.go +++ /dev/null @@ -1,23 +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 main - -// This plugin imports influxdbbackend to register the influxdbbackend stats backend. - -import ( - _ "vitess.io/vitess/go/stats/influxdbbackend" -) diff --git a/go/cmd/vttablet/plugin_influxdbbackend.go b/go/cmd/vttablet/plugin_influxdbbackend.go deleted file mode 100644 index fae7ccbb9a2..00000000000 --- a/go/cmd/vttablet/plugin_influxdbbackend.go +++ /dev/null @@ -1,23 +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 main - -// This plugin imports influxdbbackend to register the influxdbbackend stats backend. - -import ( - _ "vitess.io/vitess/go/stats/influxdbbackend" -) diff --git a/go/cmd/vtworker/plugin_influxdbbackend.go b/go/cmd/vtworker/plugin_influxdbbackend.go deleted file mode 100644 index fae7ccbb9a2..00000000000 --- a/go/cmd/vtworker/plugin_influxdbbackend.go +++ /dev/null @@ -1,23 +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 main - -// This plugin imports influxdbbackend to register the influxdbbackend stats backend. - -import ( - _ "vitess.io/vitess/go/stats/influxdbbackend" -) diff --git a/go/cmd/zkctld/plugin_influxdbbackend.go b/go/cmd/zkctld/plugin_influxdbbackend.go deleted file mode 100644 index fae7ccbb9a2..00000000000 --- a/go/cmd/zkctld/plugin_influxdbbackend.go +++ /dev/null @@ -1,23 +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 main - -// This plugin imports influxdbbackend to register the influxdbbackend stats backend. - -import ( - _ "vitess.io/vitess/go/stats/influxdbbackend" -) diff --git a/go/stats/export.go b/go/stats/export.go index b5e516cf975..8bac7618c03 100644 --- a/go/stats/export.go +++ b/go/stats/export.go @@ -41,7 +41,7 @@ import ( var emitStats = flag.Bool("emit_stats", false, "true iff we should emit stats to push-based monitoring/stats backends") var statsEmitPeriod = flag.Duration("stats_emit_period", time.Duration(60*time.Second), "Interval between emitting stats to all registered backends") -var statsBackend = flag.String("stats_backend", "influxdb", "The name of the registered push-based monitoring/stats backend to use") +var statsBackend = flag.String("stats_backend", "", "The name of the registered push-based monitoring/stats backend to use") // NewVarHook is the type of a hook to export variables in a different way type NewVarHook func(name string, v expvar.Var) diff --git a/go/stats/influxdbbackend/influxdb_backend.go b/go/stats/influxdbbackend/influxdb_backend.go deleted file mode 100644 index 54a4e41a820..00000000000 --- a/go/stats/influxdbbackend/influxdb_backend.go +++ /dev/null @@ -1,104 +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 influxdbbackend is useful for publishing metrics to an InfluxDB backend (tested on v0.88). -// It requires a database to already have been created in InfluxDB, and then specified via the -// "--influxdb_database" flag. -// -// It's still a work in progress, as it publishes almost all stats as key-value string pairs, -// instead of better JSON representations. This limitation will hopefully be fixed after the -// release of InfluxDB v0.9, as it has better support for arbitrary metadata dicts in the -// form of tags. -package influxdbbackend - -import ( - "expvar" - "flag" - - influxClient "github.com/influxdb/influxdb/client" - "vitess.io/vitess/go/stats" - "vitess.io/vitess/go/vt/log" - "vitess.io/vitess/go/vt/servenv" -) - -var influxDBHost = flag.String("influxdb_host", "localhost:8086", "the influxdb host (with port)") -var influxDBDatabase = flag.String("influxdb_database", "vitess", "the name of the influxdb database") -var influxDBUsername = flag.String("influxdb_username", "root", "influxdb username") -var influxDBPassword = flag.String("influxdb_password", "root", "influxdb password") - -// InfluxDBBackend implements stats.PushBackend -type InfluxDBBackend struct { - client *influxClient.Client -} - -// init attempts to create a singleton InfluxDBBackend and register it as a PushBackend. -// If it fails to create one, this is a noop. -func init() { - // Needs to happen in servenv.OnRun() instead of init because it requires flag parsing and logging - servenv.OnRun(func() { - config := &influxClient.ClientConfig{ - Host: *influxDBHost, - Username: *influxDBUsername, - Password: *influxDBPassword, - Database: *influxDBDatabase, - } - client, err := influxClient.NewClient(config) - if err != nil { - log.Errorf("Unable to create an InfluxDB client: %v", err) - return - } - - stats.RegisterPushBackend("influxdb", &InfluxDBBackend{ - client: client, - }) - }) -} - -// PushAll pushes all expvar stats to InfluxDB -func (backend *InfluxDBBackend) PushAll() error { - series := []*influxClient.Series{} - expvar.Do(func(kv expvar.KeyValue) { - series = append(series, &influxClient.Series{ - Name: "stats", - // TODO(aaijazi): This would be much better suited to InfluxDB v0.90's tags. - // Ideally, we'd use some of the expvars as tags, and some as values. - // However, as of 03/11/2015, InfluxDB v0.90 hasn't proven quite stable enough to use. - Columns: []string{"key", "value"}, - Points: [][]interface{}{ - {kv.Key, statToValue(kv.Value)}, - }, - }) - }) - err := backend.client.WriteSeries(series) - return err -} - -// statToValue converts from a stats.Stat type to a JSON representable value. -// This is preferred to just calling the String() for things like numbers, so that -// InfluxDB can also represent the metrics as numbers. -// TODO(aaijazi): this needs to be extended to support better serialization of other types.. -// It's probably good to do this after InfluxDB 0.9 is released, as it has has better support -// for arbitrary dict values (as tags). -func statToValue(v expvar.Var) interface{} { - switch v := v.(type) { - case *stats.Counter: - return v.Get() - case stats.FloatFunc: - return v() - default: - return v.String() - } -} diff --git a/vendor/vendor.json b/vendor/vendor.json index cd518cfd8a4..cd595fc3943 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -618,14 +618,6 @@ "revision": "d3a67ab21bc8a4643fa53a3633f2d951dd50c6ca", "revisionTime": "2016-12-07T01:17:43Z" }, - { - "checksumSHA1": "fe0NspvyJjx6DhmTjIpO0zmR+kg=", - "path": "github.com/influxdb/influxdb/client", - "revision": "afde71eb1740fd763ab9450e1f700ba0e53c36d0", - "revisionTime": "2014-12-28T19:15:54Z", - "version": "=v0.8.8", - "versionExact": "v0.8.8" - }, { "checksumSHA1": "0ZrwvB6KoGPj2PoDNSEJwxQ6Mog=", "path": "github.com/jmespath/go-jmespath", From 85253b8b82cc252433e28d16d52cf724d6930b8d Mon Sep 17 00:00:00 2001 From: Derek Perkins Date: Tue, 8 Jan 2019 14:13:13 -0700 Subject: [PATCH 038/115] helm: FailMasterPromotionIfSQLThreadNotUpToDate=tr Signed-off-by: Derek Perkins --- helm/vitess/templates/_orchestrator-conf.tpl | 1 + 1 file changed, 1 insertion(+) diff --git a/helm/vitess/templates/_orchestrator-conf.tpl b/helm/vitess/templates/_orchestrator-conf.tpl index 6ae31c21ffe..bdcc7d3cd63 100644 --- a/helm/vitess/templates/_orchestrator-conf.tpl +++ b/helm/vitess/templates/_orchestrator-conf.tpl @@ -40,6 +40,7 @@ data: "DiscoverByShowSlaveHosts": true, "EnableSyslog": false, "ExpiryHostnameResolvesMinutes": 60, + "FailMasterPromotionIfSQLThreadNotUpToDate": true, "FailureDetectionPeriodBlockMinutes": 60, "GraphiteAddr": "", "GraphiteConvertHostnameDotsToUnderscores": true, From 6fec4da70e9e7ddbbebbb424075e5f4ef7eacb08 Mon Sep 17 00:00:00 2001 From: David Weitzman Date: Tue, 8 Jan 2019 14:37:39 -0800 Subject: [PATCH 039/115] Route "show tables from " to the named keyspace This only applies when the query has not already selected a target keyspace. Some queries that previously error'd should succeed now, but queries that previously succeeded should not be affected. Signed-off-by: David Weitzman --- go/vt/vtgate/executor.go | 4 +++ go/vt/vtgate/executor_test.go | 50 ++++++++++++++++++++++++++++++++--- 2 files changed, 51 insertions(+), 3 deletions(-) diff --git a/go/vt/vtgate/executor.go b/go/vt/vtgate/executor.go index 38440dc3af8..ef319ac7d0b 100644 --- a/go/vt/vtgate/executor.go +++ b/go/vt/vtgate/executor.go @@ -749,6 +749,10 @@ func (e *Executor) handleShow(ctx context.Context, safeSession *SafeSession, sql }, nil case sqlparser.KeywordString(sqlparser.TABLES): if show.ShowTablesOpt != nil && show.ShowTablesOpt.DbName != "" { + if destKeyspace == "" { + // Change "show tables from " to "show tables" directed to that keyspace. + destKeyspace = show.ShowTablesOpt.DbName + } show.ShowTablesOpt.DbName = "" } sql = sqlparser.String(show) diff --git a/go/vt/vtgate/executor_test.go b/go/vt/vtgate/executor_test.go index 008e0976fe2..df2e6d1e335 100644 --- a/go/vt/vtgate/executor_test.go +++ b/go/vt/vtgate/executor_test.go @@ -18,6 +18,7 @@ package vtgate import ( "bytes" + "fmt" "html/template" "reflect" "sort" @@ -589,7 +590,7 @@ func TestExecutorLegacyAutocommit(t *testing.T) { } func TestExecutorShow(t *testing.T) { - executor, _, _, _ := createExecutorEnv() + executor, _, _, sbclookup := createExecutorEnv() session := NewSafeSession(&vtgatepb.Session{TargetString: "@master"}) for _, query := range []string{"show databases", "show vitess_keyspaces"} { @@ -624,6 +625,49 @@ func TestExecutorShow(t *testing.T) { if err != nil { t.Error(err) } + + _, err = executor.Execute(context.Background(), "TestExecute", session, "show tables", nil) + if err != errNoKeyspace { + t.Errorf("'show tables' should fail without a keyspace") + } + + if len(sbclookup.Queries) != 0 { + t.Errorf("sbclookup unexpectedly has queries already") + } + + showResults := &sqltypes.Result{ + Fields: []*querypb.Field{ + {Name: "Tables_in_keyspace", Type: sqltypes.VarChar}, + }, + RowsAffected: 1, + InsertID: 0, + Rows: [][]sqltypes.Value{{ + sqltypes.NewVarChar("some_table"), + }}, + } + sbclookup.SetResults([]*sqltypes.Result{showResults}) + + query := fmt.Sprintf("show tables from %v", KsTestUnsharded) + qr, err := executor.Execute(context.Background(), "TestExecute", session, query, nil) + if err != nil { + t.Error(err) + } + + if len(sbclookup.Queries) != 1 { + t.Errorf("Tablet should have recieved one 'show' query. Instead received: %v", sbclookup.Queries) + } else { + lastQuery := sbclookup.Queries[len(sbclookup.Queries)-1].Sql + want := "show tables" + if lastQuery != want { + t.Errorf("Got: %v, want %v", lastQuery, want) + } + } + + wantqr := showResults + if !reflect.DeepEqual(qr, wantqr) { + t.Errorf("%v:\n%+v, want\n%+v", query, qr, wantqr) + } + for _, query := range []string{"show charset", "show charset like '%foo'", "show character set", "show character set like '%foo'"} { qr, err := executor.Execute(context.Background(), "TestExecute", session, query, nil) if err != nil { @@ -648,11 +692,11 @@ func TestExecutorShow(t *testing.T) { t.Errorf("%v:\n%+v, want\n%+v", query, qr, wantqr) } } - qr, err := executor.Execute(context.Background(), "TestExecute", session, "show engines", nil) + qr, err = executor.Execute(context.Background(), "TestExecute", session, "show engines", nil) if err != nil { t.Error(err) } - wantqr := &sqltypes.Result{ + wantqr = &sqltypes.Result{ Fields: buildVarCharFields("Engine", "Support", "Comment", "Transactions", "XA", "Savepoints"), Rows: [][]sqltypes.Value{ buildVarCharRow( From e92c392fa96abfd7b88d589f7193137788876a83 Mon Sep 17 00:00:00 2001 From: Derek Perkins Date: Wed, 9 Jan 2019 12:45:12 -0700 Subject: [PATCH 040/115] =?UTF-8?q?planbuilder:=20support=20=E2=80=98on=20?= =?UTF-8?q?duplicate=20key=E2=80=99=20for=20msgs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Derek Perkins --- go/vt/vttablet/tabletserver/planbuilder/dml.go | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/go/vt/vttablet/tabletserver/planbuilder/dml.go b/go/vt/vttablet/tabletserver/planbuilder/dml.go index 13544efe651..bdaed0ac5f8 100644 --- a/go/vt/vttablet/tabletserver/planbuilder/dml.go +++ b/go/vt/vttablet/tabletserver/planbuilder/dml.go @@ -466,7 +466,14 @@ func analyzeInsertMessage(ins *sqlparser.Insert, plan *Plan, table *schema.Table return nil, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "subquery not allowed for message table: %s", table.Name.String()) } if ins.OnDup != nil { - return nil, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "'on duplicate key' construct not allowed for message table: %s", table.Name.String()) + // only allow 'on duplicate key' where time_scheduled and id are not referenced + ts := sqlparser.NewColIdent("time_scheduled") + id := sqlparser.NewColIdent("id") + for _, updateExpr := range ins.OnDup { + if updateExpr.Name.Name.Equal(ts) || updateExpr.Name.Name.Equal(id) { + return nil, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "'on duplicate key' cannot reference time_scheduled or id for message table: %s", table.Name.String()) + } + } } if len(ins.Columns) == 0 { return nil, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "column list must be specified for message table insert: %s", table.Name.String()) From 28def542b6d48b3074676f69108d256c9e2cbb36 Mon Sep 17 00:00:00 2001 From: Derek Perkins Date: Wed, 9 Jan 2019 12:58:28 -0700 Subject: [PATCH 041/115] exec_cases: add failing tests for msgs on dupe Signed-off-by: Derek Perkins --- data/test/tabletserver/exec_cases.txt | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/data/test/tabletserver/exec_cases.txt b/data/test/tabletserver/exec_cases.txt index d4d1a296b51..19ac9ad05b8 100644 --- a/data/test/tabletserver/exec_cases.txt +++ b/data/test/tabletserver/exec_cases.txt @@ -1019,9 +1019,13 @@ options:PassthroughDMLs "insert into msg(time_scheduled, id, message) select * from a" "subquery not allowed for message table: msg" -# message insert upsert key -"insert into msg(time_scheduled, id, message) Values(1, 2, 'aa') on duplicate key update message='bb'" -"'on duplicate key' construct not allowed for message table: msg" +# message insert upsert time_scheduled +"insert into msg(time_scheduled, id, message) Values(1, 2, 'aa') on duplicate key update time_scheduled=123" +"'on duplicate key' cannot reference time_scheduled or id for message table: msg" + +# message insert upsert id +"insert into msg(time_scheduled, id, message) Values(1, 2, 'aa') on duplicate key update id=123" +"'on duplicate key' cannot reference time_scheduled or id for message table: msg" # message insert without column list "insert into msg values(1)" From 9ab9ecc1490fd8b42a59d4daa8ad8db89c13c207 Mon Sep 17 00:00:00 2001 From: Derek Perkins Date: Wed, 9 Jan 2019 13:47:26 -0700 Subject: [PATCH 042/115] exec_cases: add passing messages OnDup test Signed-off-by: Derek Perkins --- data/test/tabletserver/exec_cases.txt | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/data/test/tabletserver/exec_cases.txt b/data/test/tabletserver/exec_cases.txt index 19ac9ad05b8..9a60c082c79 100644 --- a/data/test/tabletserver/exec_cases.txt +++ b/data/test/tabletserver/exec_cases.txt @@ -1015,6 +1015,31 @@ options:PassthroughDMLs ] } +# message multi-value upsert +"insert into msg(time_scheduled, id, message) values(1, 2, 'aa'), (3, 4, 'bb') on duplicate key update message = values(message)" +{ + "PlanID": "INSERT_MESSAGE", + "TableName": "msg", + "Permissions": [ + { + "TableName": "msg", + "Role": 1 + } + ], + "FullQuery": "insert into msg(time_scheduled, id, message) values (1, 2, 'aa'), (3, 4, 'bb') on duplicate key update message = values(message)", + "OuterQuery": "insert into msg(time_scheduled, id, message, time_next, time_created, epoch) values (1, 2, 'aa', 1, :#time_now, 0), (3, 4, 'bb', 3, :#time_now, 0) on duplicate key update message = values(message)", + "PKValues": [ + [ + 1, + 3 + ], + [ + 2, + 4 + ] + ] +} + # message insert subquery "insert into msg(time_scheduled, id, message) select * from a" "subquery not allowed for message table: msg" From 698aa3721d6d23c824f6835969f811384ba6d04f Mon Sep 17 00:00:00 2001 From: Rafael Chacon Date: Wed, 9 Jan 2019 17:36:12 -0800 Subject: [PATCH 043/115] Support tables that have columns named desc Signed-off-by: Rafael Chacon --- go/vt/sqlparser/parse_test.go | 3 + go/vt/sqlparser/sql.go | 3117 ++++++++++++++++----------------- go/vt/sqlparser/sql.y | 1 + 3 files changed, 1560 insertions(+), 1561 deletions(-) diff --git a/go/vt/sqlparser/parse_test.go b/go/vt/sqlparser/parse_test.go index bdafd2061ae..8141ac89905 100644 --- a/go/vt/sqlparser/parse_test.go +++ b/go/vt/sqlparser/parse_test.go @@ -610,6 +610,9 @@ var ( }, { input: "insert /* it accepts columns with keyword action */ into a(action, b) values (1, 2)", output: "insert /* it accepts columns with keyword action */ into a(`action`, b) values (1, 2)", + }, { + input: "insert /* it accepts columns with keyword desc */ into a(desc, b) values (1, 2)", + output: "insert /* it accepts columns with keyword desc */ into a(`desc`, b) values (1, 2)", }, { input: "insert /* no cols & paren select */ into a(select * from t)", output: "insert /* no cols & paren select */ into a select * from t", diff --git a/go/vt/sqlparser/sql.go b/go/vt/sqlparser/sql.go index 7575306054c..6bde27a44cd 100644 --- a/go/vt/sqlparser/sql.go +++ b/go/vt/sqlparser/sql.go @@ -638,25 +638,25 @@ var yyExca = [...]int{ 159, 300, 160, 300, -2, 290, - -1, 267, + -1, 268, 112, 636, -2, 632, - -1, 268, + -1, 269, 112, 637, -2, 633, - -1, 331, - 82, 807, - -2, 60, -1, 332, - 82, 764, + 82, 808, + -2, 60, + -1, 333, + 82, 765, -2, 61, - -1, 337, + -1, 338, 82, 743, -2, 598, - -1, 339, - 82, 785, + -1, 340, + 82, 786, -2, 600, - -1, 597, + -1, 598, 1, 352, 5, 352, 12, 352, @@ -680,1262 +680,1256 @@ var yyExca = [...]int{ 56, 352, 266, 352, -2, 370, - -1, 600, + -1, 601, 53, 43, 55, 43, -2, 45, - -1, 740, + -1, 741, 112, 639, -2, 635, - -1, 958, + -1, 959, 5, 30, -2, 436, - -1, 987, + -1, 988, 5, 29, -2, 572, - -1, 1240, + -1, 1241, 5, 30, -2, 573, - -1, 1295, + -1, 1296, 5, 29, -2, 575, - -1, 1376, + -1, 1377, 5, 30, -2, 576, } const yyPrivate = 57344 -const yyLast = 12140 +const yyLast = 12083 var yyAct = [...]int{ - 268, 1411, 1401, 1197, 1364, 1079, 272, 990, 562, 844, - 1008, 1274, 1132, 1166, 991, 1260, 57, 821, 246, 1133, - 1129, 1307, 840, 887, 873, 853, 923, 843, 1139, 1033, - 1014, 1102, 81, 561, 3, 819, 208, 336, 1145, 208, - 765, 775, 705, 1059, 1050, 857, 950, 298, 808, 823, - 772, 742, 793, 593, 610, 237, 494, 500, 609, 594, - 255, 330, 883, 514, 325, 801, 435, 208, 81, 327, - 932, 506, 208, 56, 208, 1404, 774, 1388, 1399, 1374, - 1396, 1198, 1387, 1373, 867, 245, 1124, 1234, 440, 1318, - 468, 203, 199, 200, 201, 1161, 1162, 1160, 270, 61, - 238, 239, 240, 241, 834, 259, 244, 576, 488, 1340, - 527, 526, 536, 537, 529, 530, 531, 532, 533, 534, - 535, 528, 243, 906, 538, 63, 64, 65, 66, 67, - 1174, 1175, 1176, 835, 836, 242, 1041, 905, 1179, 1177, - 1021, 484, 611, 1020, 612, 195, 1022, 197, 866, 485, - 482, 483, 218, 1263, 453, 874, 470, 1280, 472, 1217, - 1215, 236, 477, 478, 680, 910, 487, 1082, 1081, 678, - 1398, 1395, 1365, 1078, 904, 802, 231, 1356, 858, 1419, - 1103, 454, 1415, 442, 1308, 197, 1009, 1011, 469, 471, - 1083, 684, 671, 860, 860, 1345, 208, 1310, 679, 208, - 860, 599, 1155, 1154, 1153, 208, 438, 681, 445, 210, - 198, 208, 202, 1316, 81, 1243, 81, 1105, 81, 81, - 1183, 81, 1034, 81, 901, 898, 899, 211, 897, 436, - 917, 841, 81, 916, 214, 550, 551, 205, 1089, 968, - 196, 1075, 222, 217, 944, 714, 518, 1077, 528, 460, - 1107, 538, 1111, 450, 1106, 538, 1104, 513, 1354, 908, - 911, 1109, 81, 1010, 436, 1309, 502, 706, 326, 711, - 1108, 1184, 70, 437, 220, 439, 467, 963, 1066, 1341, - 230, 1326, 1143, 1110, 1112, 503, 613, 874, 1413, 859, - 859, 1414, 1126, 1412, 1372, 903, 859, 434, 490, 491, - 925, 856, 854, 511, 855, 794, 212, 1064, 71, 852, - 858, 299, 51, 1178, 1317, 1315, 447, 902, 448, 513, - 794, 449, 977, 208, 208, 208, 441, 512, 511, 81, - 1039, 673, 1359, 224, 215, 81, 225, 226, 227, 229, - 508, 228, 234, 1076, 513, 1074, 216, 219, 707, 213, - 233, 232, 504, 512, 511, 1420, 456, 457, 458, 592, - 907, 749, 1378, 51, 531, 532, 533, 534, 535, 528, - 513, 251, 538, 909, 1065, 747, 748, 746, 924, 1070, - 1067, 1060, 1068, 1063, 863, 512, 511, 1061, 1062, 601, - 864, 261, 1128, 1270, 1421, 717, 718, 446, 607, 1380, - 452, 1069, 513, 443, 444, 54, 459, 732, 734, 735, - 1269, 194, 461, 733, 1054, 745, 274, 1053, 466, 578, - 579, 580, 581, 582, 583, 584, 529, 530, 531, 532, - 533, 534, 535, 528, 1042, 208, 538, 1355, 1291, 962, - 81, 961, 1267, 512, 511, 208, 208, 81, 713, 22, - 1086, 208, 1352, 766, 208, 767, 1200, 208, 512, 511, - 513, 208, 1051, 81, 81, 941, 942, 943, 81, 81, - 81, 81, 81, 81, 1034, 513, 322, 323, 81, 81, - 1023, 1029, 1024, 1313, 1397, 712, 333, 526, 536, 537, - 529, 530, 531, 532, 533, 534, 535, 528, 693, 768, - 538, 690, 512, 511, 297, 689, 81, 1383, 493, 250, - 208, 1313, 1368, 1313, 493, 604, 81, 674, 685, 513, - 672, 719, 1313, 1346, 591, 465, 600, 465, 669, 465, - 465, 691, 465, 462, 465, 455, 79, 1313, 1312, 1258, - 1257, 1245, 493, 465, 527, 526, 536, 537, 529, 530, - 531, 532, 533, 534, 535, 528, 740, 605, 538, 603, - 81, 1242, 493, 51, 493, 721, 1190, 1189, 1381, 743, - 1186, 1187, 335, 1186, 1185, 1323, 784, 788, 547, 736, - 1322, 549, 795, 288, 287, 290, 291, 292, 293, 738, - 1319, 208, 289, 294, 956, 493, 1180, 951, 779, 208, - 208, 805, 493, 208, 208, 777, 493, 81, 1015, 560, - 861, 564, 565, 566, 567, 568, 569, 570, 571, 572, - 81, 575, 577, 577, 577, 577, 577, 577, 577, 577, - 585, 586, 587, 588, 1092, 598, 621, 798, 829, 497, - 501, 1142, 780, 781, 791, 804, 675, 676, 790, 769, - 770, 805, 682, 620, 619, 326, 519, 58, 688, 875, - 876, 877, 797, 1015, 799, 800, 827, 832, 831, 972, - 805, 24, 208, 81, 1130, 81, 24, 1142, 956, 81, - 81, 208, 208, 777, 208, 208, 548, 848, 208, 81, - 970, 563, 889, 967, 965, 985, 828, 956, 603, 986, - 574, 492, 1238, 1325, 1294, 208, 1142, 208, 208, 805, - 208, 728, 1188, 971, 869, 870, 871, 872, 335, 54, - 335, 24, 335, 335, 54, 335, 1025, 335, 885, 886, - 880, 881, 882, 833, 969, 956, 335, 966, 964, 603, - 597, 606, 810, 813, 814, 815, 811, 333, 812, 816, - 715, 465, 740, 810, 813, 814, 815, 811, 465, 812, - 816, 683, 54, 1146, 1147, 252, 516, 1389, 1362, 54, - 1276, 1265, 868, 933, 465, 465, 934, 1250, 888, 465, - 465, 465, 465, 465, 465, 1171, 1146, 1147, 1080, 465, - 465, 1028, 803, 884, 743, 879, 878, 891, 946, 1406, - 1402, 1173, 1149, 940, 1130, 830, 208, 208, 208, 208, - 208, 992, 1055, 54, 709, 687, 727, 1002, 208, 1000, - 1152, 208, 1003, 1151, 1001, 208, 999, 998, 1004, 208, - 814, 815, 1393, 335, 1386, 987, 256, 257, 1088, 615, - 929, 507, 1391, 939, 81, 976, 938, 1046, 618, 463, - 955, 495, 1038, 1026, 779, 1361, 505, 1360, 1292, 993, - 1017, 51, 996, 496, 1016, 1005, 994, 995, 974, 997, - 1036, 1030, 1236, 892, 1013, 1272, 564, 894, 708, 686, - 818, 507, 914, 915, 247, 918, 919, 1035, 1018, 920, - 253, 254, 81, 81, 1043, 1044, 1045, 937, 1047, 1048, - 1049, 1031, 1032, 729, 730, 936, 922, 1330, 248, 58, - 820, 928, 1329, 1278, 598, 1015, 486, 1408, 1407, 1408, - 704, 81, 509, 1342, 1052, 1264, 710, 60, 62, 602, - 55, 1, 1400, 1199, 1273, 900, 208, 739, 744, 1363, - 1306, 1165, 1071, 851, 335, 81, 842, 69, 433, 68, - 1353, 335, 1058, 850, 849, 1314, 563, 1262, 862, 782, - 783, 1040, 865, 1172, 1358, 1085, 1037, 335, 335, 626, - 624, 625, 335, 335, 335, 335, 335, 335, 623, 628, - 627, 622, 335, 335, 465, 221, 465, 328, 817, 81, - 81, 1125, 992, 1131, 1096, 1114, 1095, 614, 1101, 890, - 465, 510, 72, 1113, 1073, 839, 740, 1072, 896, 480, - 723, 481, 223, 81, 546, 597, 935, 1019, 334, 597, - 516, 1141, 1136, 335, 1137, 333, 81, 716, 81, 81, - 499, 1157, 1328, 1277, 1134, 1150, 975, 1164, 845, 573, - 792, 1156, 265, 273, 731, 286, 283, 1159, 285, 284, - 722, 945, 984, 1163, 520, 1168, 208, 271, 263, 596, - 589, 1169, 1170, 809, 771, 807, 1181, 1182, 806, 1148, - 1144, 595, 1091, 208, 786, 786, 1233, 1339, 726, 81, - 786, 26, 81, 81, 208, 59, 258, 19, 18, 17, - 81, 20, 16, 208, 536, 537, 529, 530, 531, 532, - 533, 534, 535, 528, 930, 931, 538, 501, 15, 14, - 451, 335, 1204, 988, 989, 1192, 30, 598, 598, 598, - 598, 598, 1205, 21, 335, 13, 12, 1193, 1206, 1195, - 11, 1213, 820, 739, 1012, 10, 9, 1090, 8, 7, - 598, 6, 5, 4, 249, 23, 2, 0, 0, 992, - 0, 0, 1237, 0, 0, 0, 0, 1247, 1246, 0, - 0, 0, 0, 744, 81, 0, 0, 0, 0, 957, - 0, 0, 81, 1026, 0, 0, 1256, 335, 0, 335, - 0, 0, 0, 912, 913, 0, 978, 0, 1210, 1211, - 0, 1212, 81, 335, 1214, 0, 1216, 0, 0, 81, - 0, 0, 0, 0, 465, 720, 0, 0, 0, 0, - 1266, 0, 1268, 0, 0, 0, 464, 0, 0, 335, - 0, 0, 597, 597, 597, 597, 597, 0, 0, 0, - 0, 0, 465, 0, 0, 0, 1279, 597, 0, 0, - 0, 0, 0, 81, 81, 597, 81, 0, 0, 0, - 0, 81, 1259, 81, 81, 81, 208, 1191, 1293, 81, - 0, 0, 845, 776, 778, 1300, 1301, 0, 1302, 1303, - 1304, 0, 1311, 1305, 1194, 1295, 0, 81, 0, 796, - 0, 0, 0, 0, 0, 1203, 1134, 0, 0, 1320, - 0, 1321, 1327, 0, 0, 0, 0, 0, 1135, 0, - 51, 0, 0, 0, 0, 0, 0, 1343, 0, 786, - 0, 0, 0, 0, 81, 0, 1350, 1087, 552, 553, - 554, 555, 556, 557, 558, 559, 81, 81, 1351, 0, - 1344, 0, 0, 0, 0, 0, 1367, 1366, 0, 1370, - 0, 0, 1134, 0, 0, 0, 81, 0, 335, 992, - 1375, 0, 0, 0, 0, 0, 0, 208, 0, 0, - 0, 0, 0, 1094, 0, 0, 81, 0, 0, 1127, - 0, 0, 0, 0, 1385, 1230, 493, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1119, 1390, 1392, - 81, 0, 0, 0, 0, 0, 1056, 335, 0, 0, - 0, 0, 0, 1405, 598, 1394, 0, 1158, 0, 0, - 1416, 0, 0, 527, 526, 536, 537, 529, 530, 531, - 532, 533, 534, 535, 528, 335, 0, 538, 0, 0, - 1097, 0, 473, 0, 474, 475, 1232, 476, 0, 479, - 0, 0, 0, 0, 845, 0, 845, 0, 489, 335, - 527, 526, 536, 537, 529, 530, 531, 532, 533, 534, - 535, 528, 0, 0, 538, 1252, 1253, 1254, 0, 0, - 953, 0, 0, 335, 954, 0, 0, 0, 0, 0, - 0, 958, 959, 960, 0, 0, 0, 0, 0, 0, - 786, 0, 973, 1138, 1140, 0, 0, 979, 0, 980, - 981, 982, 983, 465, 0, 0, 0, 0, 1094, 597, - 0, 0, 0, 0, 0, 0, 0, 1140, 0, 0, - 1235, 1007, 0, 0, 0, 0, 0, 563, 0, 0, - 335, 0, 335, 1167, 0, 1248, 0, 0, 1249, 0, - 0, 1251, 0, 0, 0, 0, 0, 0, 0, 0, - 1135, 0, 0, 1296, 0, 0, 0, 0, 1379, 0, - 0, 0, 0, 741, 0, 0, 750, 751, 752, 753, + 269, 1412, 1402, 1198, 1365, 1080, 273, 991, 563, 845, + 1308, 1275, 1133, 1134, 1167, 1261, 57, 992, 247, 1130, + 822, 841, 1009, 888, 924, 854, 1034, 844, 1146, 337, + 874, 1140, 81, 562, 3, 820, 209, 1103, 776, 209, + 766, 706, 1060, 1051, 1015, 824, 951, 299, 809, 794, + 275, 858, 743, 773, 611, 501, 495, 436, 802, 595, + 610, 331, 884, 515, 507, 256, 594, 209, 81, 328, + 933, 577, 209, 238, 209, 56, 1405, 1389, 1400, 326, + 1375, 1397, 1199, 1388, 1125, 246, 1374, 61, 1235, 441, + 271, 1319, 469, 204, 200, 201, 202, 1161, 1175, 1176, + 1177, 835, 260, 1162, 1163, 489, 1180, 1178, 907, 836, + 837, 244, 243, 63, 64, 65, 66, 67, 239, 240, + 241, 242, 906, 867, 245, 1341, 528, 527, 537, 538, + 530, 531, 532, 533, 534, 535, 536, 529, 1022, 485, + 539, 1021, 1042, 612, 1023, 613, 1264, 486, 483, 484, + 911, 196, 454, 198, 1281, 875, 1218, 1216, 471, 905, + 473, 237, 1104, 488, 478, 479, 1083, 1082, 528, 527, + 537, 538, 530, 531, 532, 533, 534, 535, 536, 529, + 679, 1399, 539, 1396, 681, 1366, 1357, 1079, 859, 803, + 470, 472, 1416, 1420, 455, 1309, 443, 209, 1317, 1106, + 209, 600, 1010, 1012, 198, 1084, 209, 685, 1311, 902, + 899, 900, 209, 898, 203, 81, 672, 81, 680, 81, + 81, 952, 81, 861, 81, 1156, 861, 1155, 1154, 1076, + 439, 682, 1108, 81, 1112, 1078, 1107, 206, 1105, 446, + 211, 451, 199, 1110, 909, 912, 197, 918, 551, 552, + 917, 1346, 1109, 1244, 1184, 1035, 532, 533, 534, 535, + 536, 529, 1090, 81, 539, 1111, 1113, 503, 327, 707, + 969, 945, 868, 438, 842, 440, 1310, 465, 468, 1011, + 904, 1179, 712, 715, 875, 519, 504, 461, 529, 539, + 514, 539, 926, 513, 512, 1342, 1355, 1373, 1414, 1318, + 1316, 1415, 903, 1413, 448, 1185, 449, 714, 1327, 450, + 514, 300, 51, 437, 1067, 964, 1144, 491, 492, 860, + 614, 549, 860, 750, 209, 209, 209, 467, 718, 719, + 81, 1077, 963, 1075, 962, 1127, 81, 748, 749, 747, + 795, 505, 978, 1065, 713, 908, 435, 513, 512, 795, + 708, 513, 512, 864, 1129, 457, 458, 459, 910, 865, + 593, 513, 512, 51, 514, 513, 512, 70, 514, 674, + 925, 252, 442, 1421, 1040, 598, 513, 512, 514, 509, + 861, 512, 514, 1360, 579, 580, 581, 582, 583, 584, + 585, 195, 54, 514, 1379, 334, 1271, 514, 447, 608, + 1270, 453, 746, 71, 767, 602, 768, 460, 1055, 437, + 1066, 1054, 1422, 462, 1043, 1071, 1068, 1061, 1069, 1064, + 1024, 1381, 1025, 1062, 1063, 527, 537, 538, 530, 531, + 532, 533, 534, 535, 536, 529, 209, 1070, 539, 1356, + 22, 81, 942, 943, 944, 1292, 209, 209, 81, 444, + 445, 1268, 209, 1087, 1052, 209, 323, 324, 209, 1314, + 1398, 494, 209, 1353, 81, 81, 1384, 494, 1382, 81, + 81, 81, 81, 81, 81, 1324, 860, 1314, 1369, 81, + 81, 857, 855, 1201, 856, 1035, 733, 735, 736, 853, + 859, 694, 734, 1030, 474, 769, 475, 476, 691, 477, + 251, 480, 1314, 494, 298, 1314, 1347, 81, 1314, 1313, + 490, 209, 1259, 1258, 1246, 494, 1323, 81, 1243, 494, + 775, 690, 720, 1191, 1190, 592, 466, 601, 466, 675, + 466, 466, 692, 466, 686, 466, 79, 289, 288, 291, + 292, 293, 294, 673, 466, 670, 290, 295, 463, 741, + 537, 538, 530, 531, 532, 533, 534, 535, 536, 529, + 456, 81, 539, 24, 51, 1187, 1188, 1187, 1186, 1320, + 744, 722, 336, 745, 957, 494, 1181, 785, 789, 548, + 737, 862, 550, 796, 806, 494, 1143, 986, 778, 494, + 739, 987, 209, 621, 620, 1131, 778, 1016, 1143, 780, + 209, 209, 605, 1239, 209, 209, 1016, 24, 81, 1326, + 561, 54, 565, 566, 567, 568, 569, 570, 571, 572, + 573, 81, 576, 578, 578, 578, 578, 578, 578, 578, + 578, 586, 587, 588, 589, 1295, 599, 622, 792, 830, + 806, 799, 770, 771, 606, 806, 604, 676, 677, 1143, + 598, 58, 1093, 683, 598, 54, 327, 334, 973, 689, + 828, 971, 829, 968, 604, 24, 876, 877, 878, 832, + 833, 966, 805, 209, 81, 1189, 81, 1026, 834, 849, + 81, 81, 209, 209, 957, 209, 209, 604, 607, 209, + 81, 957, 716, 890, 684, 253, 957, 806, 54, 1390, + 1363, 493, 972, 1277, 1081, 970, 209, 967, 209, 209, + 1266, 209, 729, 54, 892, 965, 869, 1251, 671, 336, + 889, 336, 1172, 336, 336, 678, 336, 1029, 336, 886, + 887, 885, 811, 814, 815, 816, 812, 336, 813, 817, + 880, 695, 696, 54, 1407, 741, 697, 698, 699, 700, + 701, 702, 466, 1147, 1148, 1403, 703, 704, 879, 466, + 1174, 1150, 1131, 1056, 710, 688, 1003, 517, 1001, 1394, + 728, 1004, 934, 1002, 1153, 466, 466, 935, 1152, 1000, + 466, 466, 466, 466, 466, 466, 1005, 999, 815, 816, + 466, 466, 1387, 804, 1089, 744, 257, 258, 745, 930, + 947, 1392, 940, 939, 1047, 619, 831, 209, 209, 209, + 209, 209, 993, 508, 811, 814, 815, 816, 812, 209, + 813, 817, 209, 496, 1147, 1148, 209, 464, 506, 1039, + 209, 1362, 1273, 1361, 336, 497, 988, 1293, 1037, 1031, + 616, 1237, 895, 977, 687, 81, 819, 740, 254, 255, + 248, 508, 1331, 249, 1027, 780, 938, 598, 598, 598, + 598, 598, 51, 58, 937, 1017, 1006, 995, 996, 1330, + 998, 1014, 598, 994, 893, 1018, 997, 565, 1279, 1016, + 598, 487, 705, 915, 916, 1036, 919, 920, 510, 1019, + 921, 1409, 1408, 81, 81, 1409, 1046, 1343, 1048, 1049, + 1050, 1044, 1045, 870, 871, 872, 873, 923, 1032, 1033, + 1265, 821, 929, 711, 60, 599, 62, 603, 55, 881, + 882, 883, 81, 1, 1053, 1401, 530, 531, 532, 533, + 534, 535, 536, 529, 1200, 334, 539, 209, 1274, 901, + 1364, 1307, 1072, 1166, 852, 336, 81, 843, 846, 69, + 434, 894, 336, 896, 68, 1354, 851, 850, 1315, 1263, + 863, 1041, 866, 1173, 1359, 1086, 1038, 922, 336, 336, + 627, 1059, 625, 336, 336, 336, 336, 336, 336, 626, + 624, 629, 628, 336, 336, 466, 623, 466, 222, 329, + 81, 81, 1126, 993, 1132, 1097, 1102, 818, 615, 741, + 1096, 466, 1115, 891, 1114, 511, 72, 1074, 1073, 897, + 481, 724, 482, 224, 81, 547, 936, 1020, 335, 1138, + 717, 517, 500, 1137, 336, 1329, 1151, 81, 1278, 81, + 81, 976, 1158, 574, 793, 1135, 1142, 274, 1165, 732, + 287, 284, 266, 740, 286, 1157, 285, 723, 985, 521, + 272, 264, 946, 597, 1164, 590, 1169, 209, 810, 1170, + 1171, 808, 1160, 807, 1149, 772, 1182, 1183, 1145, 596, + 1092, 1234, 1340, 727, 209, 787, 787, 26, 59, 259, + 81, 787, 19, 81, 81, 209, 18, 781, 782, 17, + 20, 81, 16, 791, 209, 15, 14, 452, 30, 21, + 13, 12, 11, 10, 9, 8, 7, 798, 6, 800, + 801, 1205, 336, 5, 989, 990, 4, 250, 599, 599, + 599, 599, 599, 23, 2, 336, 0, 0, 0, 1207, + 0, 0, 1214, 821, 1193, 1013, 0, 1206, 1091, 0, + 0, 599, 0, 0, 598, 0, 1194, 1232, 1196, 0, + 993, 262, 1238, 0, 0, 0, 0, 0, 0, 1247, + 0, 1248, 0, 0, 0, 81, 0, 0, 0, 0, + 0, 1058, 846, 81, 1027, 0, 0, 1257, 336, 0, + 336, 0, 0, 0, 913, 914, 0, 0, 0, 0, + 0, 0, 0, 81, 336, 0, 0, 0, 0, 1085, + 81, 0, 0, 0, 0, 466, 721, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1267, 0, 1269, + 336, 528, 527, 537, 538, 530, 531, 532, 533, 534, + 535, 536, 529, 466, 0, 539, 0, 0, 0, 0, + 0, 0, 0, 1280, 81, 81, 0, 81, 941, 0, + 0, 0, 81, 1294, 81, 81, 81, 209, 1192, 0, + 81, 0, 0, 0, 777, 779, 1301, 1302, 0, 1303, + 1304, 1305, 0, 1095, 1312, 1195, 1296, 1306, 81, 0, + 797, 0, 0, 0, 0, 0, 1204, 1135, 0, 1321, + 0, 1322, 0, 1328, 0, 956, 0, 1120, 0, 1136, + 0, 51, 0, 0, 0, 0, 0, 0, 1344, 0, + 787, 0, 0, 975, 0, 81, 0, 0, 1352, 553, + 554, 555, 556, 557, 558, 559, 560, 81, 81, 1351, + 0, 1345, 0, 0, 0, 0, 0, 1368, 1367, 0, + 1371, 0, 0, 1135, 0, 0, 0, 81, 0, 336, + 993, 1376, 0, 0, 846, 0, 846, 0, 209, 0, + 0, 0, 0, 0, 0, 0, 0, 81, 0, 0, + 0, 0, 0, 0, 0, 1386, 0, 1211, 1212, 0, + 1213, 0, 0, 1215, 0, 1217, 0, 0, 0, 1391, + 1393, 81, 0, 0, 0, 0, 0, 1057, 336, 0, + 498, 502, 0, 0, 1406, 599, 1395, 0, 0, 0, + 0, 1417, 0, 0, 0, 0, 0, 520, 1095, 0, + 0, 0, 0, 0, 0, 0, 336, 0, 0, 0, + 0, 0, 0, 0, 0, 219, 0, 1233, 0, 0, + 0, 1260, 0, 0, 0, 0, 0, 0, 0, 0, + 336, 0, 564, 0, 0, 0, 0, 0, 0, 232, + 0, 575, 0, 0, 0, 0, 1253, 1254, 1255, 0, + 1272, 954, 0, 0, 336, 955, 0, 0, 0, 0, + 0, 0, 959, 960, 961, 0, 0, 0, 0, 0, + 0, 787, 846, 974, 1139, 1141, 0, 0, 980, 494, + 981, 982, 983, 984, 466, 0, 0, 0, 0, 0, + 212, 0, 0, 0, 0, 0, 0, 215, 1141, 499, + 0, 0, 1008, 0, 0, 223, 218, 1276, 0, 0, + 0, 336, 0, 336, 1168, 0, 528, 527, 537, 538, + 530, 531, 532, 533, 534, 535, 536, 529, 0, 0, + 539, 1136, 0, 0, 1297, 207, 0, 221, 236, 1380, + 0, 0, 0, 231, 742, 0, 0, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, - 764, 0, 845, 1196, 1324, 0, 1201, 1202, 0, 0, - 0, 0, 0, 0, 335, 0, 0, 498, 0, 0, - 0, 0, 522, 0, 525, 0, 1135, 0, 51, 0, - 539, 540, 541, 542, 543, 544, 545, 1275, 523, 524, - 521, 527, 526, 536, 537, 529, 530, 531, 532, 533, - 534, 535, 528, 206, 0, 538, 235, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 786, 0, 0, - 0, 0, 0, 0, 0, 0, 670, 1100, 0, 0, - 0, 262, 0, 677, 206, 0, 0, 0, 335, 206, - 0, 206, 0, 0, 0, 0, 1261, 0, 0, 694, - 695, 0, 0, 0, 696, 697, 698, 699, 700, 701, - 1227, 493, 0, 0, 702, 703, 335, 0, 0, 0, - 0, 0, 0, 335, 0, 0, 0, 0, 0, 0, - 1403, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1369, 563, 0, 0, 0, 1224, 493, 527, 526, - 536, 537, 529, 530, 531, 532, 533, 534, 535, 528, - 0, 0, 538, 0, 1275, 845, 0, 1297, 1298, 0, - 1299, 0, 0, 0, 0, 1261, 0, 1261, 1261, 1261, - 0, 0, 0, 1167, 527, 526, 536, 537, 529, 530, - 531, 532, 533, 534, 535, 528, 0, 0, 538, 0, - 0, 1261, 0, 0, 0, 0, 0, 0, 0, 0, - 947, 948, 949, 206, 0, 0, 206, 1207, 0, 0, - 0, 0, 206, 0, 1209, 0, 0, 0, 206, 0, - 0, 0, 0, 0, 0, 1218, 1219, 1220, 1357, 1223, - 0, 0, 1226, 0, 1229, 0, 0, 0, 0, 0, - 335, 335, 0, 0, 0, 0, 0, 1239, 1240, 1241, - 0, 1244, 0, 0, 0, 0, 0, 786, 0, 0, - 1377, 0, 0, 0, 0, 0, 0, 0, 1255, 0, - 24, 25, 52, 27, 28, 0, 0, 0, 0, 0, - 1384, 0, 0, 0, 0, 0, 0, 0, 0, 43, - 0, 0, 0, 0, 29, 48, 49, 0, 0, 893, - 0, 895, 0, 0, 1261, 0, 0, 0, 1221, 493, - 0, 0, 0, 0, 38, 921, 0, 0, 54, 0, - 0, 0, 0, 0, 493, 0, 0, 0, 0, 0, - 206, 206, 206, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1290, 527, 526, 536, 537, - 529, 530, 531, 532, 533, 534, 535, 528, 0, 0, - 538, 527, 526, 536, 537, 529, 530, 531, 532, 533, - 534, 535, 528, 0, 0, 538, 0, 0, 0, 31, - 32, 34, 33, 36, 0, 50, 0, 0, 0, 0, - 0, 0, 0, 1331, 1332, 1333, 1334, 1335, 1336, 1337, - 1338, 0, 0, 1231, 1098, 1099, 37, 44, 45, 0, - 0, 46, 47, 35, 1347, 1348, 1349, 1115, 1116, 1117, - 1118, 1228, 1120, 1121, 1122, 1123, 39, 40, 0, 41, - 42, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 206, 0, 0, 0, 0, 0, 0, 0, - 0, 1371, 206, 206, 1225, 0, 1376, 0, 206, 0, - 0, 206, 0, 0, 206, 0, 0, 0, 692, 0, - 0, 0, 0, 0, 0, 1382, 643, 527, 526, 536, - 537, 529, 530, 531, 532, 533, 534, 535, 528, 0, - 0, 538, 0, 0, 0, 527, 526, 536, 537, 529, - 530, 531, 532, 533, 534, 535, 528, 0, 0, 538, - 0, 0, 0, 0, 0, 53, 0, 206, 0, 1057, - 0, 1417, 1418, 0, 0, 0, 692, 0, 527, 526, - 536, 537, 529, 530, 531, 532, 533, 534, 535, 528, - 0, 0, 538, 0, 0, 0, 0, 1084, 0, 0, - 1208, 0, 0, 0, 631, 527, 526, 536, 537, 529, - 530, 531, 532, 533, 534, 535, 528, 0, 262, 538, - 0, 0, 0, 262, 262, 0, 0, 787, 787, 262, - 1222, 0, 0, 787, 0, 0, 0, 0, 0, 0, - 0, 644, 0, 262, 262, 262, 262, 0, 206, 0, - 0, 0, 0, 0, 0, 0, 206, 825, 0, 0, - 206, 206, 0, 657, 658, 659, 660, 661, 662, 663, - 0, 664, 665, 666, 667, 668, 645, 646, 647, 648, - 629, 630, 0, 0, 632, 0, 633, 634, 635, 636, - 637, 638, 639, 640, 641, 642, 649, 650, 651, 652, - 653, 654, 655, 656, 527, 526, 536, 537, 529, 530, - 531, 532, 533, 534, 535, 528, 0, 0, 538, 0, - 0, 0, 0, 0, 1281, 1282, 952, 1283, 1284, 206, - 1285, 1286, 0, 1287, 1288, 1289, 0, 0, 206, 206, - 0, 206, 206, 0, 0, 206, 527, 526, 536, 537, - 529, 530, 531, 532, 533, 534, 535, 528, 0, 0, - 538, 0, 206, 0, 926, 927, 0, 206, 0, 0, - 0, 0, 692, 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, 0, 0, 0, 0, 0, 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, 0, 787, 206, 206, 206, 206, 206, 1271, 0, - 0, 0, 0, 0, 0, 1006, 0, 0, 206, 0, - 0, 0, 825, 0, 0, 0, 206, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1409, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 206, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 262, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 262, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 692, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 787, 138, 0, 0, 0, 0, 269, - 0, 0, 0, 102, 0, 266, 0, 0, 0, 119, - 309, 121, 0, 0, 158, 130, 0, 0, 0, 0, - 300, 301, 0, 0, 0, 0, 0, 0, 837, 0, - 54, 0, 0, 267, 288, 287, 290, 291, 292, 293, - 0, 0, 95, 289, 294, 295, 296, 838, 0, 0, - 264, 281, 0, 308, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 206, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 278, 279, 0, 0, 0, 0, 320, - 206, 280, 0, 0, 275, 276, 277, 282, 0, 0, - 0, 206, 0, 0, 0, 0, 0, 108, 0, 0, - 206, 209, 0, 0, 318, 0, 145, 0, 161, 110, - 118, 83, 89, 0, 109, 136, 150, 154, 0, 0, - 0, 98, 0, 152, 140, 174, 0, 141, 151, 122, - 166, 146, 173, 181, 182, 163, 180, 189, 84, 162, - 172, 96, 155, 86, 170, 160, 128, 114, 115, 85, - 787, 149, 101, 106, 100, 137, 167, 168, 99, 192, - 90, 179, 88, 91, 178, 135, 165, 171, 129, 126, - 87, 169, 127, 125, 117, 104, 111, 143, 124, 144, - 112, 132, 131, 133, 0, 0, 0, 159, 176, 193, - 93, 0, 164, 183, 184, 185, 186, 187, 188, 0, - 0, 94, 107, 103, 142, 134, 92, 113, 156, 116, - 123, 148, 191, 139, 153, 97, 175, 157, 310, 319, - 316, 317, 314, 315, 313, 312, 311, 321, 302, 303, - 304, 305, 307, 0, 306, 82, 0, 120, 190, 147, - 105, 177, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 825, 0, 0, 0, 421, 412, 0, - 383, 424, 361, 375, 432, 376, 377, 405, 347, 391, - 138, 373, 0, 364, 342, 370, 343, 362, 385, 102, - 388, 360, 414, 394, 423, 119, 430, 121, 399, 0, - 158, 130, 0, 0, 387, 416, 389, 410, 382, 406, - 352, 398, 425, 374, 403, 426, 0, 0, 0, 80, - 0, 846, 847, 0, 0, 0, 0, 0, 95, 0, - 401, 420, 372, 402, 404, 341, 400, 0, 345, 348, - 431, 418, 367, 368, 1027, 0, 0, 0, 0, 0, - 787, 386, 390, 407, 380, 0, 0, 0, 0, 0, - 0, 0, 0, 365, 206, 397, 0, 0, 0, 349, - 346, 0, 0, 384, 0, 0, 0, 351, 0, 366, - 408, 0, 340, 108, 411, 417, 381, 209, 419, 379, - 378, 422, 145, 0, 161, 110, 118, 83, 89, 0, - 109, 136, 150, 154, 415, 363, 371, 98, 369, 152, - 140, 174, 396, 141, 151, 122, 166, 146, 173, 181, - 182, 163, 180, 189, 84, 162, 172, 96, 155, 86, - 170, 160, 128, 114, 115, 85, 0, 149, 101, 106, - 100, 137, 167, 168, 99, 192, 90, 179, 88, 91, - 178, 135, 165, 171, 129, 126, 87, 169, 127, 125, - 117, 104, 111, 143, 124, 144, 112, 132, 131, 133, - 0, 344, 0, 159, 176, 193, 93, 359, 164, 183, - 184, 185, 186, 187, 188, 0, 0, 94, 107, 103, - 142, 134, 92, 113, 156, 116, 123, 148, 191, 139, - 153, 97, 175, 157, 355, 358, 353, 354, 392, 393, - 427, 428, 429, 409, 350, 0, 356, 357, 0, 413, - 395, 82, 0, 120, 190, 147, 105, 177, 421, 412, - 0, 383, 424, 361, 375, 432, 376, 377, 405, 347, - 391, 138, 373, 0, 364, 342, 370, 343, 362, 385, - 102, 388, 360, 414, 394, 423, 119, 430, 121, 399, - 0, 158, 130, 0, 0, 387, 416, 389, 410, 382, - 406, 352, 398, 425, 374, 403, 426, 0, 0, 0, - 80, 0, 846, 847, 0, 0, 0, 0, 0, 95, - 0, 401, 420, 372, 402, 404, 341, 400, 0, 345, - 348, 431, 418, 367, 368, 0, 0, 0, 0, 0, - 0, 0, 386, 390, 407, 380, 0, 0, 0, 0, - 0, 0, 0, 0, 365, 0, 397, 0, 0, 0, - 349, 346, 0, 0, 384, 0, 0, 0, 351, 0, - 366, 408, 0, 340, 108, 411, 417, 381, 209, 419, - 379, 378, 422, 145, 0, 161, 110, 118, 83, 89, - 0, 109, 136, 150, 154, 415, 363, 371, 98, 369, - 152, 140, 174, 396, 141, 151, 122, 166, 146, 173, - 181, 182, 163, 180, 189, 84, 162, 172, 96, 155, - 86, 170, 160, 128, 114, 115, 85, 0, 149, 101, - 106, 100, 137, 167, 168, 99, 192, 90, 179, 88, - 91, 178, 135, 165, 171, 129, 126, 87, 169, 127, - 125, 117, 104, 111, 143, 124, 144, 112, 132, 131, - 133, 0, 344, 0, 159, 176, 193, 93, 359, 164, - 183, 184, 185, 186, 187, 188, 0, 0, 94, 107, - 103, 142, 134, 92, 113, 156, 116, 123, 148, 191, - 139, 153, 97, 175, 157, 355, 358, 353, 354, 392, - 393, 427, 428, 429, 409, 350, 0, 356, 357, 0, - 413, 395, 82, 0, 120, 190, 147, 105, 177, 421, - 412, 0, 383, 424, 361, 375, 432, 376, 377, 405, - 347, 391, 138, 373, 0, 364, 342, 370, 343, 362, - 385, 102, 388, 360, 414, 394, 423, 119, 430, 121, - 399, 0, 158, 130, 0, 0, 387, 416, 389, 410, - 382, 406, 352, 398, 425, 374, 403, 426, 54, 0, + 764, 765, 0, 263, 1197, 1325, 207, 1202, 1203, 213, + 0, 207, 0, 207, 0, 336, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1136, 0, 51, + 0, 0, 0, 0, 0, 0, 225, 216, 0, 226, + 227, 228, 230, 0, 229, 235, 0, 0, 0, 217, + 220, 0, 214, 234, 233, 0, 0, 0, 0, 709, + 1231, 494, 0, 0, 0, 0, 0, 0, 787, 0, + 0, 0, 0, 0, 1276, 846, 0, 0, 1101, 0, + 0, 0, 0, 0, 730, 731, 0, 0, 0, 336, + 0, 0, 0, 0, 0, 0, 0, 1262, 528, 527, + 537, 538, 530, 531, 532, 533, 534, 535, 536, 529, + 0, 0, 539, 0, 1228, 494, 0, 336, 0, 0, + 0, 0, 0, 0, 336, 0, 0, 0, 0, 0, + 0, 1404, 0, 0, 0, 0, 207, 564, 0, 207, + 783, 784, 0, 0, 0, 207, 0, 0, 0, 1225, + 494, 207, 528, 527, 537, 538, 530, 531, 532, 533, + 534, 535, 536, 529, 0, 0, 539, 0, 1298, 1299, + 0, 1300, 0, 0, 0, 0, 1262, 0, 1262, 1262, + 1262, 0, 0, 0, 1168, 0, 840, 528, 527, 537, + 538, 530, 531, 532, 533, 534, 535, 536, 529, 0, + 0, 539, 1262, 0, 0, 0, 0, 0, 0, 0, + 0, 948, 949, 950, 0, 0, 0, 0, 1208, 0, + 0, 0, 0, 0, 0, 1210, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1219, 1220, 1221, 1358, + 1224, 0, 0, 1227, 0, 1230, 0, 0, 0, 0, + 0, 336, 336, 0, 1222, 494, 0, 0, 1240, 1241, + 1242, 1229, 1245, 207, 207, 207, 0, 0, 787, 0, + 0, 1378, 0, 0, 0, 0, 0, 0, 0, 1256, + 0, 0, 0, 0, 0, 931, 932, 0, 502, 0, + 0, 1385, 528, 527, 537, 538, 530, 531, 532, 533, + 534, 535, 536, 529, 0, 0, 539, 0, 0, 0, + 0, 0, 0, 0, 0, 1262, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 24, 25, + 52, 27, 28, 0, 0, 528, 527, 537, 538, 530, + 531, 532, 533, 534, 535, 536, 529, 43, 0, 539, + 958, 0, 29, 48, 49, 0, 1291, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 979, 0, 0, + 0, 0, 38, 0, 0, 207, 54, 0, 0, 0, + 0, 0, 0, 0, 0, 207, 207, 0, 0, 0, + 0, 207, 0, 0, 207, 0, 0, 207, 0, 0, + 0, 693, 0, 0, 1332, 1333, 1334, 1335, 1336, 1337, + 1338, 1339, 0, 0, 0, 1099, 1100, 0, 0, 0, + 0, 0, 0, 0, 0, 1348, 1349, 1350, 1116, 1117, + 1118, 1119, 0, 1121, 1122, 1123, 1124, 31, 32, 34, + 33, 36, 0, 50, 0, 0, 0, 0, 0, 0, + 207, 0, 0, 0, 0, 0, 0, 0, 0, 693, + 0, 0, 1372, 0, 37, 44, 45, 1377, 0, 46, + 47, 35, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 39, 40, 1383, 41, 42, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1088, 0, + 0, 263, 0, 0, 0, 0, 263, 263, 0, 0, + 788, 788, 263, 0, 0, 0, 788, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 263, 263, 263, 263, + 0, 207, 1418, 1419, 0, 0, 0, 0, 0, 207, + 826, 0, 0, 207, 207, 0, 0, 0, 0, 0, + 1128, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1209, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 53, 0, 0, 0, 0, 0, 0, + 0, 523, 0, 526, 0, 0, 0, 0, 1159, 540, + 541, 542, 543, 544, 545, 546, 1226, 524, 525, 522, + 528, 527, 537, 538, 530, 531, 532, 533, 534, 535, + 536, 529, 207, 0, 539, 0, 0, 0, 0, 0, + 0, 207, 207, 0, 207, 207, 0, 0, 207, 0, + 0, 0, 0, 0, 0, 0, 0, 644, 0, 0, + 0, 0, 0, 0, 0, 207, 0, 927, 928, 0, + 207, 0, 0, 0, 0, 693, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 263, 0, 0, + 528, 527, 537, 538, 530, 531, 532, 533, 534, 535, + 536, 529, 0, 0, 539, 1282, 1283, 0, 1284, 1285, + 0, 1286, 1287, 0, 1288, 1289, 1290, 0, 0, 0, + 0, 1236, 0, 0, 0, 0, 0, 0, 564, 0, + 0, 0, 0, 0, 263, 632, 1249, 0, 0, 1250, + 0, 0, 1252, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 263, 0, 0, 0, 0, 0, 0, 0, + 0, 1223, 0, 0, 0, 788, 207, 207, 207, 207, + 207, 0, 645, 0, 0, 0, 0, 0, 1007, 0, + 0, 207, 0, 0, 0, 826, 0, 0, 0, 207, + 0, 0, 0, 0, 658, 659, 660, 661, 662, 663, + 664, 0, 665, 666, 667, 668, 669, 646, 647, 648, + 649, 630, 631, 0, 0, 633, 0, 634, 635, 636, + 637, 638, 639, 640, 641, 642, 643, 650, 651, 652, + 653, 654, 655, 656, 657, 528, 527, 537, 538, 530, + 531, 532, 533, 534, 535, 536, 529, 1098, 0, 539, + 528, 527, 537, 538, 530, 531, 532, 533, 534, 535, + 536, 529, 0, 0, 539, 0, 0, 528, 527, 537, + 538, 530, 531, 532, 533, 534, 535, 536, 529, 0, + 0, 539, 0, 0, 0, 0, 0, 1410, 0, 0, + 0, 0, 0, 0, 0, 0, 207, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 263, 0, 0, 0, + 953, 0, 0, 0, 0, 0, 0, 263, 0, 0, + 0, 0, 1370, 564, 0, 0, 0, 0, 0, 693, + 528, 527, 537, 538, 530, 531, 532, 533, 534, 535, + 536, 529, 0, 0, 539, 0, 788, 139, 0, 0, + 0, 0, 270, 0, 98, 0, 103, 0, 267, 0, + 0, 0, 120, 310, 122, 0, 0, 159, 131, 0, + 0, 0, 0, 301, 302, 0, 0, 0, 0, 0, + 0, 838, 0, 54, 0, 0, 268, 289, 288, 291, + 292, 293, 294, 0, 0, 95, 290, 295, 296, 297, + 839, 0, 0, 265, 282, 0, 309, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 207, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 279, 280, 0, 0, + 0, 0, 321, 207, 281, 0, 0, 276, 277, 278, + 283, 0, 0, 0, 207, 0, 0, 0, 0, 0, + 109, 0, 0, 207, 210, 0, 0, 319, 0, 146, + 0, 162, 111, 119, 83, 89, 0, 110, 137, 151, + 155, 0, 0, 0, 99, 0, 153, 141, 175, 0, + 142, 152, 123, 167, 147, 174, 182, 183, 164, 181, + 190, 84, 163, 173, 96, 156, 86, 171, 161, 129, + 115, 116, 85, 788, 150, 102, 107, 101, 138, 168, + 169, 100, 193, 90, 180, 88, 91, 179, 136, 166, + 172, 130, 127, 87, 170, 128, 126, 118, 105, 112, + 144, 125, 145, 113, 133, 132, 134, 0, 0, 0, + 160, 177, 194, 93, 0, 165, 184, 185, 186, 187, + 188, 189, 0, 0, 94, 108, 104, 143, 135, 92, + 114, 157, 117, 124, 149, 192, 140, 154, 97, 176, + 158, 311, 320, 317, 318, 315, 316, 314, 313, 312, + 322, 303, 304, 305, 306, 308, 0, 307, 82, 0, + 121, 191, 148, 106, 178, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 826, 0, 0, 0, + 422, 413, 0, 384, 425, 362, 376, 433, 377, 378, + 406, 348, 392, 139, 374, 0, 365, 343, 371, 344, + 363, 386, 103, 389, 361, 415, 395, 424, 120, 431, + 122, 400, 0, 159, 131, 0, 0, 388, 417, 390, + 411, 383, 407, 353, 399, 426, 375, 404, 427, 0, + 0, 0, 80, 0, 847, 848, 0, 0, 0, 0, + 0, 95, 0, 402, 421, 373, 403, 405, 342, 401, + 0, 346, 349, 432, 419, 368, 369, 1028, 0, 0, + 0, 0, 0, 788, 387, 391, 408, 381, 0, 0, + 0, 0, 0, 0, 0, 0, 366, 207, 398, 0, + 0, 0, 350, 347, 0, 0, 385, 0, 0, 0, + 352, 0, 367, 409, 0, 341, 109, 412, 418, 382, + 210, 420, 380, 379, 423, 146, 0, 162, 111, 119, + 83, 89, 0, 110, 137, 151, 155, 416, 364, 372, + 99, 370, 153, 141, 175, 397, 142, 152, 123, 167, + 147, 174, 182, 183, 164, 181, 190, 84, 163, 173, + 96, 156, 86, 171, 161, 129, 115, 116, 85, 0, + 150, 102, 107, 101, 138, 168, 169, 100, 193, 90, + 180, 88, 91, 179, 136, 166, 172, 130, 127, 87, + 170, 128, 126, 118, 105, 112, 144, 125, 145, 113, + 133, 132, 134, 0, 345, 0, 160, 177, 194, 93, + 360, 165, 184, 185, 186, 187, 188, 189, 0, 0, + 94, 108, 104, 143, 135, 92, 114, 157, 117, 124, + 149, 192, 140, 154, 97, 176, 158, 356, 359, 354, + 355, 393, 394, 428, 429, 430, 410, 351, 0, 357, + 358, 0, 414, 396, 82, 0, 121, 191, 148, 106, + 178, 422, 413, 0, 384, 425, 362, 376, 433, 377, + 378, 406, 348, 392, 139, 374, 0, 365, 343, 371, + 344, 363, 386, 103, 389, 361, 415, 395, 424, 120, + 431, 122, 400, 0, 159, 131, 0, 0, 388, 417, + 390, 411, 383, 407, 353, 399, 426, 375, 404, 427, + 0, 0, 0, 80, 0, 847, 848, 0, 0, 0, + 0, 0, 95, 0, 402, 421, 373, 403, 405, 342, + 401, 0, 346, 349, 432, 419, 368, 369, 0, 0, + 0, 0, 0, 0, 0, 387, 391, 408, 381, 0, + 0, 0, 0, 0, 0, 0, 0, 366, 0, 398, + 0, 0, 0, 350, 347, 0, 0, 385, 0, 0, + 0, 352, 0, 367, 409, 0, 341, 109, 412, 418, + 382, 210, 420, 380, 379, 423, 146, 0, 162, 111, + 119, 83, 89, 0, 110, 137, 151, 155, 416, 364, + 372, 99, 370, 153, 141, 175, 397, 142, 152, 123, + 167, 147, 174, 182, 183, 164, 181, 190, 84, 163, + 173, 96, 156, 86, 171, 161, 129, 115, 116, 85, + 0, 150, 102, 107, 101, 138, 168, 169, 100, 193, + 90, 180, 88, 91, 179, 136, 166, 172, 130, 127, + 87, 170, 128, 126, 118, 105, 112, 144, 125, 145, + 113, 133, 132, 134, 0, 345, 0, 160, 177, 194, + 93, 360, 165, 184, 185, 186, 187, 188, 189, 0, + 0, 94, 108, 104, 143, 135, 92, 114, 157, 117, + 124, 149, 192, 140, 154, 97, 176, 158, 356, 359, + 354, 355, 393, 394, 428, 429, 430, 410, 351, 0, + 357, 358, 0, 414, 396, 82, 0, 121, 191, 148, + 106, 178, 422, 413, 0, 384, 425, 362, 376, 433, + 377, 378, 406, 348, 392, 139, 374, 0, 365, 343, + 371, 344, 363, 386, 103, 389, 361, 415, 395, 424, + 120, 431, 122, 400, 0, 159, 131, 0, 0, 388, + 417, 390, 411, 383, 407, 353, 399, 426, 375, 404, + 427, 54, 0, 0, 80, 0, 0, 0, 0, 0, + 0, 0, 0, 95, 0, 402, 421, 373, 403, 405, + 342, 401, 0, 346, 349, 432, 419, 368, 369, 0, + 0, 0, 0, 0, 0, 0, 387, 391, 408, 381, + 0, 0, 0, 0, 0, 0, 0, 0, 366, 0, + 398, 0, 0, 0, 350, 347, 0, 0, 385, 0, + 0, 0, 352, 0, 367, 409, 0, 341, 109, 412, + 418, 382, 210, 420, 380, 379, 423, 146, 0, 162, + 111, 119, 83, 89, 0, 110, 137, 151, 155, 416, + 364, 372, 99, 370, 153, 141, 175, 397, 142, 152, + 123, 167, 147, 174, 182, 183, 164, 181, 190, 84, + 163, 173, 96, 156, 86, 171, 161, 129, 115, 116, + 85, 0, 150, 102, 107, 101, 138, 168, 169, 100, + 193, 90, 180, 88, 91, 179, 136, 166, 172, 130, + 127, 87, 170, 128, 126, 118, 105, 112, 144, 125, + 145, 113, 133, 132, 134, 0, 345, 0, 160, 177, + 194, 93, 360, 165, 184, 185, 186, 187, 188, 189, + 0, 0, 94, 108, 104, 143, 135, 92, 114, 157, + 117, 124, 149, 192, 140, 154, 97, 176, 158, 356, + 359, 354, 355, 393, 394, 428, 429, 430, 410, 351, + 0, 357, 358, 0, 414, 396, 82, 0, 121, 191, + 148, 106, 178, 422, 413, 0, 384, 425, 362, 376, + 433, 377, 378, 406, 348, 392, 139, 374, 0, 365, + 343, 371, 344, 363, 386, 103, 389, 361, 415, 395, + 424, 120, 431, 122, 400, 0, 159, 131, 0, 0, + 388, 417, 390, 411, 383, 407, 353, 399, 426, 375, + 404, 427, 0, 0, 0, 80, 0, 0, 0, 0, + 0, 0, 0, 0, 95, 0, 402, 421, 373, 403, + 405, 342, 401, 0, 346, 349, 432, 419, 368, 369, + 0, 0, 0, 0, 0, 0, 0, 387, 391, 408, + 381, 0, 0, 0, 0, 0, 0, 1094, 0, 366, + 0, 398, 0, 0, 0, 350, 347, 0, 0, 385, + 0, 0, 0, 352, 0, 367, 409, 0, 341, 109, + 412, 418, 382, 210, 420, 380, 379, 423, 146, 0, + 162, 111, 119, 83, 89, 0, 110, 137, 151, 155, + 416, 364, 372, 99, 370, 153, 141, 175, 397, 142, + 152, 123, 167, 147, 174, 182, 183, 164, 181, 190, + 84, 163, 173, 96, 156, 86, 171, 161, 129, 115, + 116, 85, 0, 150, 102, 107, 101, 138, 168, 169, + 100, 193, 90, 180, 88, 91, 179, 136, 166, 172, + 130, 127, 87, 170, 128, 126, 118, 105, 112, 144, + 125, 145, 113, 133, 132, 134, 0, 345, 0, 160, + 177, 194, 93, 360, 165, 184, 185, 186, 187, 188, + 189, 0, 0, 94, 108, 104, 143, 135, 92, 114, + 157, 117, 124, 149, 192, 140, 154, 97, 176, 158, + 356, 359, 354, 355, 393, 394, 428, 429, 430, 410, + 351, 0, 357, 358, 0, 414, 396, 82, 0, 121, + 191, 148, 106, 178, 422, 413, 0, 384, 425, 362, + 376, 433, 377, 378, 406, 348, 392, 139, 374, 0, + 365, 343, 371, 344, 363, 386, 103, 389, 361, 415, + 395, 424, 120, 431, 122, 400, 0, 159, 131, 0, + 0, 388, 417, 390, 411, 383, 407, 353, 399, 426, + 375, 404, 427, 0, 0, 0, 268, 0, 0, 0, + 0, 0, 0, 0, 0, 95, 0, 402, 421, 373, + 403, 405, 342, 401, 0, 346, 349, 432, 419, 368, + 369, 0, 0, 0, 0, 0, 0, 0, 387, 391, + 408, 381, 0, 0, 0, 0, 0, 0, 738, 0, + 366, 0, 398, 0, 0, 0, 350, 347, 0, 0, + 385, 0, 0, 0, 352, 0, 367, 409, 0, 341, + 109, 412, 418, 382, 210, 420, 380, 379, 423, 146, + 0, 162, 111, 119, 83, 89, 0, 110, 137, 151, + 155, 416, 364, 372, 99, 370, 153, 141, 175, 397, + 142, 152, 123, 167, 147, 174, 182, 183, 164, 181, + 190, 84, 163, 173, 96, 156, 86, 171, 161, 129, + 115, 116, 85, 0, 150, 102, 107, 101, 138, 168, + 169, 100, 193, 90, 180, 88, 91, 179, 136, 166, + 172, 130, 127, 87, 170, 128, 126, 118, 105, 112, + 144, 125, 145, 113, 133, 132, 134, 0, 345, 0, + 160, 177, 194, 93, 360, 165, 184, 185, 186, 187, + 188, 189, 0, 0, 94, 108, 104, 143, 135, 92, + 114, 157, 117, 124, 149, 192, 140, 154, 97, 176, + 158, 356, 359, 354, 355, 393, 394, 428, 429, 430, + 410, 351, 0, 357, 358, 0, 414, 396, 82, 0, + 121, 191, 148, 106, 178, 422, 413, 0, 384, 425, + 362, 376, 433, 377, 378, 406, 348, 392, 139, 374, + 0, 365, 343, 371, 344, 363, 386, 103, 389, 361, + 415, 395, 424, 120, 431, 122, 400, 0, 159, 131, + 0, 0, 388, 417, 390, 411, 383, 407, 353, 399, + 426, 375, 404, 427, 0, 0, 0, 80, 0, 0, + 0, 0, 0, 0, 0, 0, 95, 0, 402, 421, + 373, 403, 405, 342, 401, 0, 346, 349, 432, 419, + 368, 369, 0, 0, 0, 0, 0, 0, 0, 387, + 391, 408, 381, 0, 0, 0, 0, 0, 0, 0, + 0, 366, 0, 398, 0, 0, 0, 350, 347, 0, + 0, 385, 0, 0, 0, 352, 0, 367, 409, 0, + 341, 109, 412, 418, 382, 210, 420, 380, 379, 423, + 146, 0, 162, 111, 119, 83, 89, 0, 110, 137, + 151, 155, 416, 364, 372, 99, 370, 153, 141, 175, + 397, 142, 152, 123, 167, 147, 174, 182, 183, 164, + 181, 190, 84, 163, 173, 96, 156, 86, 171, 161, + 129, 115, 116, 85, 0, 150, 102, 107, 101, 138, + 168, 169, 100, 193, 90, 180, 88, 91, 179, 136, + 166, 172, 130, 127, 87, 170, 128, 126, 118, 105, + 112, 144, 125, 145, 113, 133, 132, 134, 0, 345, + 0, 160, 177, 194, 93, 360, 165, 184, 185, 186, + 187, 188, 189, 0, 0, 94, 108, 104, 143, 135, + 92, 114, 157, 117, 124, 149, 192, 140, 154, 97, + 176, 158, 356, 359, 354, 355, 393, 394, 428, 429, + 430, 410, 351, 0, 357, 358, 0, 414, 396, 82, + 0, 121, 191, 148, 106, 178, 422, 413, 0, 384, + 425, 362, 376, 433, 377, 378, 406, 348, 392, 139, + 374, 0, 365, 343, 371, 344, 363, 386, 103, 389, + 361, 415, 395, 424, 120, 431, 122, 400, 0, 159, + 131, 0, 0, 388, 417, 390, 411, 383, 407, 353, + 399, 426, 375, 404, 427, 0, 0, 0, 268, 0, + 0, 0, 0, 0, 0, 0, 0, 95, 0, 402, + 421, 373, 403, 405, 342, 401, 0, 346, 349, 432, + 419, 368, 369, 0, 0, 0, 0, 0, 0, 0, + 387, 391, 408, 381, 0, 0, 0, 0, 0, 0, + 0, 0, 366, 0, 398, 0, 0, 0, 350, 347, + 0, 0, 385, 0, 0, 0, 352, 0, 367, 409, + 0, 341, 109, 412, 418, 382, 210, 420, 380, 379, + 423, 146, 0, 162, 111, 119, 83, 89, 0, 110, + 137, 151, 155, 416, 364, 372, 99, 370, 153, 141, + 175, 397, 142, 152, 123, 167, 147, 174, 182, 183, + 164, 181, 190, 84, 163, 173, 96, 156, 86, 171, + 161, 129, 115, 116, 85, 0, 150, 102, 107, 101, + 138, 168, 169, 100, 193, 90, 180, 88, 91, 179, + 136, 166, 172, 130, 127, 87, 170, 128, 126, 118, + 105, 112, 144, 125, 145, 113, 133, 132, 134, 0, + 345, 0, 160, 177, 194, 93, 360, 165, 184, 185, + 186, 187, 188, 189, 0, 0, 94, 108, 104, 143, + 135, 92, 114, 157, 117, 124, 149, 192, 140, 154, + 97, 176, 158, 356, 359, 354, 355, 393, 394, 428, + 429, 430, 410, 351, 0, 357, 358, 0, 414, 396, + 82, 0, 121, 191, 148, 106, 178, 422, 413, 0, + 384, 425, 362, 376, 433, 377, 378, 406, 348, 392, + 139, 374, 0, 365, 343, 371, 344, 363, 386, 103, + 389, 361, 415, 395, 424, 120, 431, 122, 400, 0, + 159, 131, 0, 0, 388, 417, 390, 411, 383, 407, + 353, 399, 426, 375, 404, 427, 0, 0, 0, 80, + 0, 0, 0, 0, 0, 0, 0, 0, 95, 0, + 402, 421, 373, 403, 405, 342, 401, 0, 346, 349, + 432, 419, 368, 369, 0, 0, 0, 0, 0, 0, + 0, 387, 391, 408, 381, 0, 0, 0, 0, 0, + 0, 0, 0, 366, 0, 398, 0, 0, 0, 350, + 347, 0, 0, 385, 0, 0, 0, 352, 0, 367, + 409, 0, 341, 109, 412, 418, 382, 210, 420, 380, + 379, 423, 146, 0, 162, 111, 119, 83, 89, 0, + 110, 137, 151, 155, 416, 364, 372, 99, 370, 153, + 141, 175, 397, 142, 152, 123, 167, 147, 174, 182, + 183, 164, 181, 190, 84, 163, 173, 96, 156, 86, + 171, 161, 129, 115, 116, 85, 0, 150, 102, 107, + 101, 138, 168, 169, 100, 193, 90, 180, 88, 339, + 179, 136, 166, 172, 130, 127, 87, 170, 128, 126, + 118, 105, 112, 144, 125, 145, 113, 133, 132, 134, + 0, 345, 0, 160, 177, 194, 93, 360, 165, 184, + 185, 186, 187, 188, 189, 0, 0, 94, 108, 104, + 143, 340, 338, 114, 157, 117, 124, 149, 192, 140, + 154, 97, 176, 158, 356, 359, 354, 355, 393, 394, + 428, 429, 430, 410, 351, 0, 357, 358, 0, 414, + 396, 82, 0, 121, 191, 148, 106, 178, 422, 413, + 0, 384, 425, 362, 376, 433, 377, 378, 406, 348, + 392, 139, 374, 0, 365, 343, 371, 344, 363, 386, + 103, 389, 361, 415, 395, 424, 120, 431, 122, 400, + 0, 159, 131, 0, 0, 388, 417, 390, 411, 383, + 407, 353, 399, 426, 375, 404, 427, 0, 0, 0, + 208, 0, 0, 0, 0, 0, 0, 0, 0, 95, + 0, 402, 421, 373, 403, 405, 342, 401, 0, 346, + 349, 432, 419, 368, 369, 0, 0, 0, 0, 0, + 0, 0, 387, 391, 408, 381, 0, 0, 0, 0, + 0, 0, 0, 0, 366, 0, 398, 0, 0, 0, + 350, 347, 0, 0, 385, 0, 0, 0, 352, 0, + 367, 409, 0, 341, 109, 412, 418, 382, 210, 420, + 380, 379, 423, 146, 0, 162, 111, 119, 83, 89, + 0, 110, 137, 151, 155, 416, 364, 372, 99, 370, + 153, 141, 175, 397, 142, 152, 123, 167, 147, 174, + 182, 183, 164, 181, 190, 84, 163, 173, 96, 156, + 86, 171, 161, 129, 115, 116, 85, 0, 150, 102, + 107, 101, 138, 168, 169, 100, 193, 90, 180, 88, + 91, 179, 136, 166, 172, 130, 127, 87, 170, 128, + 126, 118, 105, 112, 144, 125, 145, 113, 133, 132, + 134, 0, 345, 0, 160, 177, 194, 93, 360, 165, + 184, 185, 186, 187, 188, 189, 0, 0, 94, 108, + 104, 143, 135, 92, 114, 157, 117, 124, 149, 192, + 140, 154, 97, 176, 158, 356, 359, 354, 355, 393, + 394, 428, 429, 430, 410, 351, 0, 357, 358, 0, + 414, 396, 82, 0, 121, 191, 148, 106, 178, 422, + 413, 0, 384, 425, 362, 376, 433, 377, 378, 406, + 348, 392, 139, 374, 0, 365, 343, 371, 344, 363, + 386, 103, 389, 361, 415, 395, 424, 120, 431, 122, + 400, 0, 159, 131, 0, 0, 388, 417, 390, 411, + 383, 407, 353, 399, 426, 375, 404, 427, 0, 0, 0, 80, 0, 0, 0, 0, 0, 0, 0, 0, - 95, 0, 401, 420, 372, 402, 404, 341, 400, 0, - 345, 348, 431, 418, 367, 368, 0, 0, 0, 0, - 0, 0, 0, 386, 390, 407, 380, 0, 0, 0, - 0, 0, 0, 0, 0, 365, 0, 397, 0, 0, - 0, 349, 346, 0, 0, 384, 0, 0, 0, 351, - 0, 366, 408, 0, 340, 108, 411, 417, 381, 209, - 419, 379, 378, 422, 145, 0, 161, 110, 118, 83, - 89, 0, 109, 136, 150, 154, 415, 363, 371, 98, - 369, 152, 140, 174, 396, 141, 151, 122, 166, 146, - 173, 181, 182, 163, 180, 189, 84, 162, 172, 96, - 155, 86, 170, 160, 128, 114, 115, 85, 0, 149, - 101, 106, 100, 137, 167, 168, 99, 192, 90, 179, - 88, 91, 178, 135, 165, 171, 129, 126, 87, 169, - 127, 125, 117, 104, 111, 143, 124, 144, 112, 132, - 131, 133, 0, 344, 0, 159, 176, 193, 93, 359, - 164, 183, 184, 185, 186, 187, 188, 0, 0, 94, - 107, 103, 142, 134, 92, 113, 156, 116, 123, 148, - 191, 139, 153, 97, 175, 157, 355, 358, 353, 354, - 392, 393, 427, 428, 429, 409, 350, 0, 356, 357, - 0, 413, 395, 82, 0, 120, 190, 147, 105, 177, - 421, 412, 0, 383, 424, 361, 375, 432, 376, 377, - 405, 347, 391, 138, 373, 0, 364, 342, 370, 343, - 362, 385, 102, 388, 360, 414, 394, 423, 119, 430, - 121, 399, 0, 158, 130, 0, 0, 387, 416, 389, - 410, 382, 406, 352, 398, 425, 374, 403, 426, 0, + 95, 0, 402, 421, 373, 403, 405, 342, 401, 0, + 346, 349, 432, 419, 368, 369, 0, 0, 0, 0, + 0, 0, 0, 387, 391, 408, 381, 0, 0, 0, + 0, 0, 0, 0, 0, 366, 0, 398, 0, 0, + 0, 350, 347, 0, 0, 385, 0, 0, 0, 352, + 0, 367, 409, 0, 341, 109, 412, 418, 382, 210, + 420, 380, 379, 423, 146, 0, 162, 111, 119, 83, + 89, 0, 110, 137, 151, 155, 416, 364, 372, 99, + 370, 153, 141, 175, 397, 142, 152, 123, 167, 147, + 174, 182, 183, 164, 181, 190, 84, 163, 609, 96, + 156, 86, 171, 161, 129, 115, 116, 85, 0, 150, + 102, 107, 101, 138, 168, 169, 100, 193, 90, 180, + 88, 339, 179, 136, 166, 172, 130, 127, 87, 170, + 128, 126, 118, 105, 112, 144, 125, 145, 113, 133, + 132, 134, 0, 345, 0, 160, 177, 194, 93, 360, + 165, 184, 185, 186, 187, 188, 189, 0, 0, 94, + 108, 104, 143, 340, 338, 114, 157, 117, 124, 149, + 192, 140, 154, 97, 176, 158, 356, 359, 354, 355, + 393, 394, 428, 429, 430, 410, 351, 0, 357, 358, + 0, 414, 396, 82, 0, 121, 191, 148, 106, 178, + 422, 413, 0, 384, 425, 362, 376, 433, 377, 378, + 406, 348, 392, 139, 374, 0, 365, 343, 371, 344, + 363, 386, 103, 389, 361, 415, 395, 424, 120, 431, + 122, 400, 0, 159, 131, 0, 0, 388, 417, 390, + 411, 383, 407, 353, 399, 426, 375, 404, 427, 0, 0, 0, 80, 0, 0, 0, 0, 0, 0, 0, - 0, 95, 0, 401, 420, 372, 402, 404, 341, 400, - 0, 345, 348, 431, 418, 367, 368, 0, 0, 0, - 0, 0, 0, 0, 386, 390, 407, 380, 0, 0, - 0, 0, 0, 0, 1093, 0, 365, 0, 397, 0, - 0, 0, 349, 346, 0, 0, 384, 0, 0, 0, - 351, 0, 366, 408, 0, 340, 108, 411, 417, 381, - 209, 419, 379, 378, 422, 145, 0, 161, 110, 118, - 83, 89, 0, 109, 136, 150, 154, 415, 363, 371, - 98, 369, 152, 140, 174, 396, 141, 151, 122, 166, - 146, 173, 181, 182, 163, 180, 189, 84, 162, 172, - 96, 155, 86, 170, 160, 128, 114, 115, 85, 0, - 149, 101, 106, 100, 137, 167, 168, 99, 192, 90, - 179, 88, 91, 178, 135, 165, 171, 129, 126, 87, - 169, 127, 125, 117, 104, 111, 143, 124, 144, 112, - 132, 131, 133, 0, 344, 0, 159, 176, 193, 93, - 359, 164, 183, 184, 185, 186, 187, 188, 0, 0, - 94, 107, 103, 142, 134, 92, 113, 156, 116, 123, - 148, 191, 139, 153, 97, 175, 157, 355, 358, 353, - 354, 392, 393, 427, 428, 429, 409, 350, 0, 356, - 357, 0, 413, 395, 82, 0, 120, 190, 147, 105, - 177, 421, 412, 0, 383, 424, 361, 375, 432, 376, - 377, 405, 347, 391, 138, 373, 0, 364, 342, 370, - 343, 362, 385, 102, 388, 360, 414, 394, 423, 119, - 430, 121, 399, 0, 158, 130, 0, 0, 387, 416, - 389, 410, 382, 406, 352, 398, 425, 374, 403, 426, - 0, 0, 0, 267, 0, 0, 0, 0, 0, 0, - 0, 0, 95, 0, 401, 420, 372, 402, 404, 341, - 400, 0, 345, 348, 431, 418, 367, 368, 0, 0, - 0, 0, 0, 0, 0, 386, 390, 407, 380, 0, - 0, 0, 0, 0, 0, 737, 0, 365, 0, 397, - 0, 0, 0, 349, 346, 0, 0, 384, 0, 0, - 0, 351, 0, 366, 408, 0, 340, 108, 411, 417, - 381, 209, 419, 379, 378, 422, 145, 0, 161, 110, - 118, 83, 89, 0, 109, 136, 150, 154, 415, 363, - 371, 98, 369, 152, 140, 174, 396, 141, 151, 122, - 166, 146, 173, 181, 182, 163, 180, 189, 84, 162, - 172, 96, 155, 86, 170, 160, 128, 114, 115, 85, - 0, 149, 101, 106, 100, 137, 167, 168, 99, 192, - 90, 179, 88, 91, 178, 135, 165, 171, 129, 126, - 87, 169, 127, 125, 117, 104, 111, 143, 124, 144, - 112, 132, 131, 133, 0, 344, 0, 159, 176, 193, - 93, 359, 164, 183, 184, 185, 186, 187, 188, 0, - 0, 94, 107, 103, 142, 134, 92, 113, 156, 116, - 123, 148, 191, 139, 153, 97, 175, 157, 355, 358, - 353, 354, 392, 393, 427, 428, 429, 409, 350, 0, - 356, 357, 0, 413, 395, 82, 0, 120, 190, 147, - 105, 177, 421, 412, 0, 383, 424, 361, 375, 432, - 376, 377, 405, 347, 391, 138, 373, 0, 364, 342, - 370, 343, 362, 385, 102, 388, 360, 414, 394, 423, - 119, 430, 121, 399, 0, 158, 130, 0, 0, 387, - 416, 389, 410, 382, 406, 352, 398, 425, 374, 403, - 426, 0, 0, 0, 80, 0, 0, 0, 0, 0, - 0, 0, 0, 95, 0, 401, 420, 372, 402, 404, - 341, 400, 0, 345, 348, 431, 418, 367, 368, 0, - 0, 0, 0, 0, 0, 0, 386, 390, 407, 380, - 0, 0, 0, 0, 0, 0, 0, 0, 365, 0, - 397, 0, 0, 0, 349, 346, 0, 0, 384, 0, - 0, 0, 351, 0, 366, 408, 0, 340, 108, 411, - 417, 381, 209, 419, 379, 378, 422, 145, 0, 161, - 110, 118, 83, 89, 0, 109, 136, 150, 154, 415, - 363, 371, 98, 369, 152, 140, 174, 396, 141, 151, - 122, 166, 146, 173, 181, 182, 163, 180, 189, 84, - 162, 172, 96, 155, 86, 170, 160, 128, 114, 115, - 85, 0, 149, 101, 106, 100, 137, 167, 168, 99, - 192, 90, 179, 88, 91, 178, 135, 165, 171, 129, - 126, 87, 169, 127, 125, 117, 104, 111, 143, 124, - 144, 112, 132, 131, 133, 0, 344, 0, 159, 176, - 193, 93, 359, 164, 183, 184, 185, 186, 187, 188, - 0, 0, 94, 107, 103, 142, 134, 92, 113, 156, - 116, 123, 148, 191, 139, 153, 97, 175, 157, 355, - 358, 353, 354, 392, 393, 427, 428, 429, 409, 350, - 0, 356, 357, 0, 413, 395, 82, 0, 120, 190, - 147, 105, 177, 421, 412, 0, 383, 424, 361, 375, - 432, 376, 377, 405, 347, 391, 138, 373, 0, 364, - 342, 370, 343, 362, 385, 102, 388, 360, 414, 394, - 423, 119, 430, 121, 399, 0, 158, 130, 0, 0, - 387, 416, 389, 410, 382, 406, 352, 398, 425, 374, - 403, 426, 0, 0, 0, 267, 0, 0, 0, 0, - 0, 0, 0, 0, 95, 0, 401, 420, 372, 402, - 404, 341, 400, 0, 345, 348, 431, 418, 367, 368, - 0, 0, 0, 0, 0, 0, 0, 386, 390, 407, - 380, 0, 0, 0, 0, 0, 0, 0, 0, 365, - 0, 397, 0, 0, 0, 349, 346, 0, 0, 384, - 0, 0, 0, 351, 0, 366, 408, 0, 340, 108, - 411, 417, 381, 209, 419, 379, 378, 422, 145, 0, - 161, 110, 118, 83, 89, 0, 109, 136, 150, 154, - 415, 363, 371, 98, 369, 152, 140, 174, 396, 141, - 151, 122, 166, 146, 173, 181, 182, 163, 180, 189, - 84, 162, 172, 96, 155, 86, 170, 160, 128, 114, - 115, 85, 0, 149, 101, 106, 100, 137, 167, 168, - 99, 192, 90, 179, 88, 91, 178, 135, 165, 171, - 129, 126, 87, 169, 127, 125, 117, 104, 111, 143, - 124, 144, 112, 132, 131, 133, 0, 344, 0, 159, - 176, 193, 93, 359, 164, 183, 184, 185, 186, 187, - 188, 0, 0, 94, 107, 103, 142, 134, 92, 113, - 156, 116, 123, 148, 191, 139, 153, 97, 175, 157, - 355, 358, 353, 354, 392, 393, 427, 428, 429, 409, - 350, 0, 356, 357, 0, 413, 395, 82, 0, 120, - 190, 147, 105, 177, 421, 412, 0, 383, 424, 361, - 375, 432, 376, 377, 405, 347, 391, 138, 373, 0, - 364, 342, 370, 343, 362, 385, 102, 388, 360, 414, - 394, 423, 119, 430, 121, 399, 0, 158, 130, 0, - 0, 387, 416, 389, 410, 382, 406, 352, 398, 425, - 374, 403, 426, 0, 0, 0, 80, 0, 0, 0, - 0, 0, 0, 0, 0, 95, 0, 401, 420, 372, - 402, 404, 341, 400, 0, 345, 348, 431, 418, 367, - 368, 0, 0, 0, 0, 0, 0, 0, 386, 390, - 407, 380, 0, 0, 0, 0, 0, 0, 0, 0, - 365, 0, 397, 0, 0, 0, 349, 346, 0, 0, - 384, 0, 0, 0, 351, 0, 366, 408, 0, 340, - 108, 411, 417, 381, 209, 419, 379, 378, 422, 145, - 0, 161, 110, 118, 83, 89, 0, 109, 136, 150, - 154, 415, 363, 371, 98, 369, 152, 140, 174, 396, - 141, 151, 122, 166, 146, 173, 181, 182, 163, 180, - 189, 84, 162, 172, 96, 155, 86, 170, 160, 128, - 114, 115, 85, 0, 149, 101, 106, 100, 137, 167, - 168, 99, 192, 90, 179, 88, 338, 178, 135, 165, - 171, 129, 126, 87, 169, 127, 125, 117, 104, 111, - 143, 124, 144, 112, 132, 131, 133, 0, 344, 0, - 159, 176, 193, 93, 359, 164, 183, 184, 185, 186, - 187, 188, 0, 0, 94, 107, 103, 142, 339, 337, - 113, 156, 116, 123, 148, 191, 139, 153, 97, 175, - 157, 355, 358, 353, 354, 392, 393, 427, 428, 429, - 409, 350, 0, 356, 357, 0, 413, 395, 82, 0, - 120, 190, 147, 105, 177, 421, 412, 0, 383, 424, - 361, 375, 432, 376, 377, 405, 347, 391, 138, 373, - 0, 364, 342, 370, 343, 362, 385, 102, 388, 360, - 414, 394, 423, 119, 430, 121, 399, 0, 158, 130, - 0, 0, 387, 416, 389, 410, 382, 406, 352, 398, - 425, 374, 403, 426, 0, 0, 0, 207, 0, 0, - 0, 0, 0, 0, 0, 0, 95, 0, 401, 420, - 372, 402, 404, 341, 400, 0, 345, 348, 431, 418, - 367, 368, 0, 0, 0, 0, 0, 0, 0, 386, - 390, 407, 380, 0, 0, 0, 0, 0, 0, 0, - 0, 365, 0, 397, 0, 0, 0, 349, 346, 0, - 0, 384, 0, 0, 0, 351, 0, 366, 408, 0, - 340, 108, 411, 417, 381, 209, 419, 379, 378, 422, - 145, 0, 161, 110, 118, 83, 89, 0, 109, 136, - 150, 154, 415, 363, 371, 98, 369, 152, 140, 174, - 396, 141, 151, 122, 166, 146, 173, 181, 182, 163, - 180, 189, 84, 162, 172, 96, 155, 86, 170, 160, - 128, 114, 115, 85, 0, 149, 101, 106, 100, 137, - 167, 168, 99, 192, 90, 179, 88, 91, 178, 135, - 165, 171, 129, 126, 87, 169, 127, 125, 117, 104, - 111, 143, 124, 144, 112, 132, 131, 133, 0, 344, - 0, 159, 176, 193, 93, 359, 164, 183, 184, 185, - 186, 187, 188, 0, 0, 94, 107, 103, 142, 134, - 92, 113, 156, 116, 123, 148, 191, 139, 153, 97, - 175, 157, 355, 358, 353, 354, 392, 393, 427, 428, - 429, 409, 350, 0, 356, 357, 0, 413, 395, 82, - 0, 120, 190, 147, 105, 177, 421, 412, 0, 383, - 424, 361, 375, 432, 376, 377, 405, 347, 391, 138, - 373, 0, 364, 342, 370, 343, 362, 385, 102, 388, - 360, 414, 394, 423, 119, 430, 121, 399, 0, 158, - 130, 0, 0, 387, 416, 389, 410, 382, 406, 352, - 398, 425, 374, 403, 426, 0, 0, 0, 80, 0, - 0, 0, 0, 0, 0, 0, 0, 95, 0, 401, - 420, 372, 402, 404, 341, 400, 0, 345, 348, 431, - 418, 367, 368, 0, 0, 0, 0, 0, 0, 0, - 386, 390, 407, 380, 0, 0, 0, 0, 0, 0, - 0, 0, 365, 0, 397, 0, 0, 0, 349, 346, - 0, 0, 384, 0, 0, 0, 351, 0, 366, 408, - 0, 340, 108, 411, 417, 381, 209, 419, 379, 378, - 422, 145, 0, 161, 110, 118, 83, 89, 0, 109, - 136, 150, 154, 415, 363, 371, 98, 369, 152, 140, - 174, 396, 141, 151, 122, 166, 146, 173, 181, 182, - 163, 180, 189, 84, 162, 608, 96, 155, 86, 170, - 160, 128, 114, 115, 85, 0, 149, 101, 106, 100, - 137, 167, 168, 99, 192, 90, 179, 88, 338, 178, - 135, 165, 171, 129, 126, 87, 169, 127, 125, 117, - 104, 111, 143, 124, 144, 112, 132, 131, 133, 0, - 344, 0, 159, 176, 193, 93, 359, 164, 183, 184, - 185, 186, 187, 188, 0, 0, 94, 107, 103, 142, - 339, 337, 113, 156, 116, 123, 148, 191, 139, 153, - 97, 175, 157, 355, 358, 353, 354, 392, 393, 427, - 428, 429, 409, 350, 0, 356, 357, 0, 413, 395, - 82, 0, 120, 190, 147, 105, 177, 421, 412, 0, - 383, 424, 361, 375, 432, 376, 377, 405, 347, 391, - 138, 373, 0, 364, 342, 370, 343, 362, 385, 102, - 388, 360, 414, 394, 423, 119, 430, 121, 399, 0, - 158, 130, 0, 0, 387, 416, 389, 410, 382, 406, - 352, 398, 425, 374, 403, 426, 0, 0, 0, 80, - 0, 0, 0, 0, 0, 0, 0, 0, 95, 0, - 401, 420, 372, 402, 404, 341, 400, 0, 345, 348, - 431, 418, 367, 368, 0, 0, 0, 0, 0, 0, - 0, 386, 390, 407, 380, 0, 0, 0, 0, 0, - 0, 0, 0, 365, 0, 397, 0, 0, 0, 349, - 346, 0, 0, 384, 0, 0, 0, 351, 0, 366, - 408, 0, 340, 108, 411, 417, 381, 209, 419, 379, - 378, 422, 145, 0, 161, 110, 118, 83, 89, 0, - 109, 136, 150, 154, 415, 363, 371, 98, 369, 152, - 140, 174, 396, 141, 151, 122, 166, 146, 173, 181, - 182, 163, 180, 189, 84, 162, 329, 96, 155, 86, - 170, 160, 128, 114, 115, 85, 0, 149, 101, 106, - 100, 137, 167, 168, 99, 192, 90, 179, 88, 338, - 178, 135, 165, 171, 129, 126, 87, 169, 127, 125, - 117, 104, 111, 143, 124, 144, 112, 132, 131, 133, - 0, 344, 0, 159, 176, 193, 93, 359, 164, 183, - 184, 185, 186, 187, 188, 0, 0, 94, 107, 103, - 142, 339, 337, 332, 331, 116, 123, 148, 191, 139, - 153, 97, 175, 157, 355, 358, 353, 354, 392, 393, - 427, 428, 429, 409, 350, 0, 356, 357, 0, 413, - 395, 82, 0, 120, 190, 147, 105, 177, 138, 0, - 0, 773, 0, 269, 0, 0, 0, 102, 0, 266, - 0, 0, 0, 119, 309, 121, 0, 0, 158, 130, - 0, 0, 0, 0, 300, 301, 0, 0, 0, 0, - 0, 0, 0, 0, 54, 0, 0, 267, 288, 287, - 290, 291, 292, 293, 0, 0, 95, 289, 294, 295, - 296, 0, 0, 0, 264, 281, 0, 308, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 278, 279, 260, - 0, 0, 0, 320, 0, 280, 0, 0, 275, 276, - 277, 282, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 108, 0, 0, 0, 209, 0, 0, 318, 0, - 145, 0, 161, 110, 118, 83, 89, 0, 109, 136, - 150, 154, 0, 0, 0, 98, 0, 152, 140, 174, - 0, 141, 151, 122, 166, 146, 173, 181, 182, 163, - 180, 189, 84, 162, 172, 96, 155, 86, 170, 160, - 128, 114, 115, 85, 0, 149, 101, 106, 100, 137, - 167, 168, 99, 192, 90, 179, 88, 91, 178, 135, - 165, 171, 129, 126, 87, 169, 127, 125, 117, 104, - 111, 143, 124, 144, 112, 132, 131, 133, 0, 0, - 0, 159, 176, 193, 93, 0, 164, 183, 184, 185, - 186, 187, 188, 0, 0, 94, 107, 103, 142, 134, - 92, 113, 156, 116, 123, 148, 191, 139, 153, 97, - 175, 157, 310, 319, 316, 317, 314, 315, 313, 312, - 311, 321, 302, 303, 304, 305, 307, 0, 306, 82, - 0, 120, 190, 147, 105, 177, 138, 0, 0, 0, - 0, 269, 0, 0, 0, 102, 0, 266, 0, 0, - 0, 119, 309, 121, 0, 0, 158, 130, 0, 0, - 0, 0, 300, 301, 0, 0, 0, 0, 0, 0, - 0, 0, 54, 0, 493, 267, 288, 287, 290, 291, - 292, 293, 0, 0, 95, 289, 294, 295, 296, 0, - 0, 0, 264, 281, 0, 308, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 278, 279, 0, 0, 0, - 0, 320, 0, 280, 0, 0, 275, 276, 277, 282, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 108, - 0, 0, 0, 209, 0, 0, 318, 0, 145, 0, - 161, 110, 118, 83, 89, 0, 109, 136, 150, 154, - 0, 0, 0, 98, 0, 152, 140, 174, 0, 141, - 151, 122, 166, 146, 173, 181, 182, 163, 180, 189, - 84, 162, 172, 96, 155, 86, 170, 160, 128, 114, - 115, 85, 0, 149, 101, 106, 100, 137, 167, 168, - 99, 192, 90, 179, 88, 91, 178, 135, 165, 171, - 129, 126, 87, 169, 127, 125, 117, 104, 111, 143, - 124, 144, 112, 132, 131, 133, 0, 0, 0, 159, - 176, 193, 93, 0, 164, 183, 184, 185, 186, 187, - 188, 0, 0, 94, 107, 103, 142, 134, 92, 113, - 156, 116, 123, 148, 191, 139, 153, 97, 175, 157, - 310, 319, 316, 317, 314, 315, 313, 312, 311, 321, - 302, 303, 304, 305, 307, 0, 306, 82, 0, 120, - 190, 147, 105, 177, 138, 0, 0, 0, 0, 269, - 0, 0, 0, 102, 0, 266, 0, 0, 0, 119, - 309, 121, 0, 0, 158, 130, 0, 0, 0, 0, - 300, 301, 0, 0, 0, 0, 0, 0, 0, 0, - 54, 0, 0, 267, 288, 287, 290, 291, 292, 293, - 0, 0, 95, 289, 294, 295, 296, 0, 0, 0, - 264, 281, 0, 308, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 278, 279, 260, 0, 0, 0, 320, - 0, 280, 0, 0, 275, 276, 277, 282, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 108, 0, 0, - 0, 209, 0, 0, 318, 0, 145, 0, 161, 110, - 118, 83, 89, 0, 109, 136, 150, 154, 0, 0, - 0, 98, 0, 152, 140, 174, 0, 141, 151, 122, - 166, 146, 173, 181, 182, 163, 180, 189, 84, 162, - 172, 96, 155, 86, 170, 160, 128, 114, 115, 85, - 0, 149, 101, 106, 100, 137, 167, 168, 99, 192, - 90, 179, 88, 91, 178, 135, 165, 171, 129, 126, - 87, 169, 127, 125, 117, 104, 111, 143, 124, 144, - 112, 132, 131, 133, 0, 0, 0, 159, 176, 193, - 93, 0, 164, 183, 184, 185, 186, 187, 188, 0, - 0, 94, 107, 103, 142, 134, 92, 113, 156, 116, - 123, 148, 191, 139, 153, 97, 175, 157, 310, 319, - 316, 317, 314, 315, 313, 312, 311, 321, 302, 303, - 304, 305, 307, 24, 306, 82, 0, 120, 190, 147, - 105, 177, 0, 0, 0, 138, 0, 0, 0, 0, - 269, 0, 0, 0, 102, 0, 266, 0, 0, 0, - 119, 309, 121, 0, 0, 158, 130, 0, 0, 0, - 0, 300, 301, 0, 0, 0, 0, 0, 0, 0, - 0, 54, 0, 0, 267, 288, 287, 290, 291, 292, - 293, 0, 0, 95, 289, 294, 295, 296, 0, 0, - 0, 264, 281, 0, 308, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 278, 279, 0, 0, 0, 0, - 320, 0, 280, 0, 0, 275, 276, 277, 282, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 108, 0, - 0, 0, 209, 0, 0, 318, 0, 145, 0, 161, - 110, 118, 83, 89, 0, 109, 136, 150, 154, 0, - 0, 0, 98, 0, 152, 140, 174, 0, 141, 151, - 122, 166, 146, 173, 181, 182, 163, 180, 189, 84, - 162, 172, 96, 155, 86, 170, 160, 128, 114, 115, - 85, 0, 149, 101, 106, 100, 137, 167, 168, 99, - 192, 90, 179, 88, 91, 178, 135, 165, 171, 129, - 126, 87, 169, 127, 125, 117, 104, 111, 143, 124, - 144, 112, 132, 131, 133, 0, 0, 0, 159, 176, - 193, 93, 0, 164, 183, 184, 185, 186, 187, 188, - 0, 0, 94, 107, 103, 142, 134, 92, 113, 156, - 116, 123, 148, 191, 139, 153, 97, 175, 157, 310, - 319, 316, 317, 314, 315, 313, 312, 311, 321, 302, - 303, 304, 305, 307, 0, 306, 82, 0, 120, 190, - 147, 105, 177, 138, 0, 0, 0, 0, 269, 0, - 0, 0, 102, 0, 266, 0, 0, 0, 119, 309, - 121, 0, 0, 158, 130, 0, 0, 0, 0, 300, - 301, 0, 0, 0, 0, 0, 0, 0, 0, 54, - 0, 0, 267, 288, 287, 290, 291, 292, 293, 0, - 0, 95, 289, 294, 295, 296, 0, 0, 0, 264, - 281, 0, 308, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 278, 279, 0, 0, 0, 0, 320, 0, - 280, 0, 0, 275, 276, 277, 282, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 108, 0, 0, 0, - 209, 0, 0, 318, 0, 145, 0, 161, 110, 118, - 83, 89, 0, 109, 136, 150, 154, 0, 0, 0, - 98, 0, 152, 140, 174, 0, 141, 151, 122, 166, - 146, 173, 181, 182, 163, 180, 189, 84, 162, 172, - 96, 155, 86, 170, 160, 128, 114, 115, 85, 0, - 149, 101, 106, 100, 137, 167, 168, 99, 192, 90, - 179, 88, 91, 178, 135, 165, 171, 129, 126, 87, - 169, 127, 125, 117, 104, 111, 143, 124, 144, 112, - 132, 131, 133, 0, 0, 0, 159, 176, 193, 93, - 0, 164, 183, 184, 185, 186, 187, 188, 0, 0, - 94, 107, 103, 142, 134, 92, 113, 156, 116, 123, - 148, 191, 139, 153, 97, 175, 157, 310, 319, 316, - 317, 314, 315, 313, 312, 311, 321, 302, 303, 304, - 305, 307, 138, 306, 82, 0, 120, 190, 147, 105, - 177, 102, 0, 0, 0, 0, 0, 119, 309, 121, - 0, 0, 158, 130, 0, 0, 0, 0, 300, 301, - 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, - 0, 267, 288, 287, 290, 291, 292, 293, 0, 0, - 95, 289, 294, 295, 296, 0, 0, 0, 0, 281, - 0, 308, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 278, 279, 0, 0, 0, 0, 320, 0, 280, - 0, 0, 275, 276, 277, 282, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 108, 0, 0, 0, 209, - 0, 0, 318, 0, 145, 0, 161, 110, 118, 83, - 89, 0, 109, 136, 150, 154, 0, 0, 0, 98, - 0, 152, 140, 174, 1410, 141, 151, 122, 166, 146, - 173, 181, 182, 163, 180, 189, 84, 162, 172, 96, - 155, 86, 170, 160, 128, 114, 115, 85, 0, 149, - 101, 106, 100, 137, 167, 168, 99, 192, 90, 179, - 88, 91, 178, 135, 165, 171, 129, 126, 87, 169, - 127, 125, 117, 104, 111, 143, 124, 144, 112, 132, - 131, 133, 0, 0, 0, 159, 176, 193, 93, 0, - 164, 183, 184, 185, 186, 187, 188, 0, 0, 94, - 107, 103, 142, 134, 92, 113, 156, 116, 123, 148, - 191, 139, 153, 97, 175, 157, 310, 319, 316, 317, - 314, 315, 313, 312, 311, 321, 302, 303, 304, 305, - 307, 138, 306, 82, 0, 120, 190, 147, 105, 177, - 102, 0, 0, 0, 0, 0, 119, 309, 121, 0, - 0, 158, 130, 0, 0, 0, 0, 300, 301, 0, + 0, 95, 0, 402, 421, 373, 403, 405, 342, 401, + 0, 346, 349, 432, 419, 368, 369, 0, 0, 0, + 0, 0, 0, 0, 387, 391, 408, 381, 0, 0, + 0, 0, 0, 0, 0, 0, 366, 0, 398, 0, + 0, 0, 350, 347, 0, 0, 385, 0, 0, 0, + 352, 0, 367, 409, 0, 341, 109, 412, 418, 382, + 210, 420, 380, 379, 423, 146, 0, 162, 111, 119, + 83, 89, 0, 110, 137, 151, 155, 416, 364, 372, + 99, 370, 153, 141, 175, 397, 142, 152, 123, 167, + 147, 174, 182, 183, 164, 181, 190, 84, 163, 330, + 96, 156, 86, 171, 161, 129, 115, 116, 85, 0, + 150, 102, 107, 101, 138, 168, 169, 100, 193, 90, + 180, 88, 339, 179, 136, 166, 172, 130, 127, 87, + 170, 128, 126, 118, 105, 112, 144, 125, 145, 113, + 133, 132, 134, 0, 345, 0, 160, 177, 194, 93, + 360, 165, 184, 185, 186, 187, 188, 189, 0, 0, + 94, 108, 104, 143, 340, 338, 333, 332, 117, 124, + 149, 192, 140, 154, 97, 176, 158, 356, 359, 354, + 355, 393, 394, 428, 429, 430, 410, 351, 0, 357, + 358, 0, 414, 396, 82, 0, 121, 191, 148, 106, + 178, 139, 0, 0, 774, 0, 270, 0, 98, 0, + 103, 0, 267, 0, 0, 0, 120, 310, 122, 0, + 0, 159, 131, 0, 0, 0, 0, 301, 302, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, - 267, 288, 287, 290, 291, 292, 293, 0, 0, 95, - 289, 294, 295, 296, 0, 0, 0, 0, 281, 0, - 308, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 278, 279, 0, 0, 0, 0, 320, 0, 280, 0, - 0, 275, 276, 277, 282, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 108, 0, 0, 0, 209, 0, - 0, 318, 0, 145, 0, 161, 110, 118, 83, 89, - 0, 109, 136, 150, 154, 0, 0, 0, 98, 0, - 152, 140, 174, 0, 141, 151, 122, 166, 146, 173, - 181, 182, 163, 180, 189, 84, 162, 172, 96, 155, - 86, 170, 160, 128, 114, 115, 85, 0, 149, 101, - 106, 100, 137, 167, 168, 99, 192, 90, 179, 88, - 91, 178, 135, 165, 171, 129, 126, 87, 169, 127, - 125, 117, 104, 111, 143, 124, 144, 112, 132, 131, - 133, 0, 0, 0, 159, 176, 193, 93, 0, 164, - 183, 184, 185, 186, 187, 188, 0, 0, 94, 107, - 103, 142, 134, 92, 113, 156, 116, 123, 148, 191, - 139, 153, 97, 175, 157, 310, 319, 316, 317, 314, - 315, 313, 312, 311, 321, 302, 303, 304, 305, 307, - 138, 306, 82, 0, 120, 190, 147, 105, 177, 102, - 0, 0, 0, 0, 0, 119, 0, 121, 0, 0, - 158, 130, 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, 95, 0, - 0, 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, 108, 0, 0, 0, 209, 0, 0, - 0, 0, 145, 0, 161, 110, 118, 83, 89, 0, - 109, 136, 150, 154, 0, 0, 0, 98, 0, 152, - 140, 174, 0, 141, 151, 122, 166, 146, 173, 181, - 182, 163, 180, 189, 84, 162, 172, 96, 155, 86, - 170, 160, 128, 114, 115, 85, 0, 149, 101, 106, - 100, 137, 167, 168, 99, 192, 90, 179, 88, 91, - 178, 135, 165, 171, 129, 126, 87, 169, 127, 125, - 117, 104, 111, 143, 124, 144, 112, 132, 131, 133, - 0, 0, 0, 159, 176, 193, 93, 0, 164, 183, - 184, 185, 186, 187, 188, 0, 0, 94, 107, 103, - 142, 134, 92, 113, 156, 116, 123, 148, 191, 139, - 153, 97, 175, 157, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 138, 0, 0, 0, 515, 0, 0, - 0, 82, 102, 120, 190, 147, 105, 177, 119, 0, - 121, 0, 0, 158, 130, 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, 95, 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, + 268, 289, 288, 291, 292, 293, 294, 0, 0, 95, + 290, 295, 296, 297, 0, 0, 0, 265, 282, 0, + 309, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 279, 280, 261, 0, 0, 0, 321, 0, 281, 0, + 0, 276, 277, 278, 283, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 109, 0, 0, 0, 210, 0, + 0, 319, 0, 146, 0, 162, 111, 119, 83, 89, + 0, 110, 137, 151, 155, 0, 0, 0, 99, 0, + 153, 141, 175, 0, 142, 152, 123, 167, 147, 174, + 182, 183, 164, 181, 190, 84, 163, 173, 96, 156, + 86, 171, 161, 129, 115, 116, 85, 0, 150, 102, + 107, 101, 138, 168, 169, 100, 193, 90, 180, 88, + 91, 179, 136, 166, 172, 130, 127, 87, 170, 128, + 126, 118, 105, 112, 144, 125, 145, 113, 133, 132, + 134, 0, 0, 0, 160, 177, 194, 93, 0, 165, + 184, 185, 186, 187, 188, 189, 0, 0, 94, 108, + 104, 143, 135, 92, 114, 157, 117, 124, 149, 192, + 140, 154, 97, 176, 158, 311, 320, 317, 318, 315, + 316, 314, 313, 312, 322, 303, 304, 305, 306, 308, + 0, 307, 82, 0, 121, 191, 148, 106, 178, 139, + 0, 0, 0, 0, 270, 0, 98, 0, 103, 0, + 267, 0, 0, 0, 120, 310, 122, 0, 0, 159, + 131, 0, 0, 0, 0, 301, 302, 0, 0, 0, + 0, 0, 0, 0, 0, 54, 0, 494, 268, 289, + 288, 291, 292, 293, 294, 0, 0, 95, 290, 295, + 296, 297, 0, 0, 0, 265, 282, 0, 309, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 279, 280, + 0, 0, 0, 0, 321, 0, 281, 0, 0, 276, + 277, 278, 283, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 109, 0, 0, 0, 210, 0, 0, 319, + 0, 146, 0, 162, 111, 119, 83, 89, 0, 110, + 137, 151, 155, 0, 0, 0, 99, 0, 153, 141, + 175, 0, 142, 152, 123, 167, 147, 174, 182, 183, + 164, 181, 190, 84, 163, 173, 96, 156, 86, 171, + 161, 129, 115, 116, 85, 0, 150, 102, 107, 101, + 138, 168, 169, 100, 193, 90, 180, 88, 91, 179, + 136, 166, 172, 130, 127, 87, 170, 128, 126, 118, + 105, 112, 144, 125, 145, 113, 133, 132, 134, 0, + 0, 0, 160, 177, 194, 93, 0, 165, 184, 185, + 186, 187, 188, 189, 0, 0, 94, 108, 104, 143, + 135, 92, 114, 157, 117, 124, 149, 192, 140, 154, + 97, 176, 158, 311, 320, 317, 318, 315, 316, 314, + 313, 312, 322, 303, 304, 305, 306, 308, 0, 307, + 82, 0, 121, 191, 148, 106, 178, 139, 0, 0, + 0, 0, 270, 0, 98, 0, 103, 0, 267, 0, + 0, 0, 120, 310, 122, 0, 0, 159, 131, 0, + 0, 0, 0, 301, 302, 0, 0, 0, 0, 0, + 0, 0, 0, 54, 0, 0, 268, 289, 288, 291, + 292, 293, 294, 0, 0, 95, 290, 295, 296, 297, + 0, 0, 0, 265, 282, 0, 309, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 279, 280, 261, 0, + 0, 0, 321, 0, 281, 0, 0, 276, 277, 278, + 283, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 109, 0, 0, 0, 210, 0, 0, 319, 0, 146, + 0, 162, 111, 119, 83, 89, 0, 110, 137, 151, + 155, 0, 0, 0, 99, 0, 153, 141, 175, 0, + 142, 152, 123, 167, 147, 174, 182, 183, 164, 181, + 190, 84, 163, 173, 96, 156, 86, 171, 161, 129, + 115, 116, 85, 0, 150, 102, 107, 101, 138, 168, + 169, 100, 193, 90, 180, 88, 91, 179, 136, 166, + 172, 130, 127, 87, 170, 128, 126, 118, 105, 112, + 144, 125, 145, 113, 133, 132, 134, 0, 0, 0, + 160, 177, 194, 93, 0, 165, 184, 185, 186, 187, + 188, 189, 0, 0, 94, 108, 104, 143, 135, 92, + 114, 157, 117, 124, 149, 192, 140, 154, 97, 176, + 158, 311, 320, 317, 318, 315, 316, 314, 313, 312, + 322, 303, 304, 305, 306, 308, 24, 307, 82, 0, + 121, 191, 148, 106, 178, 0, 0, 0, 139, 0, + 0, 0, 0, 270, 0, 98, 0, 103, 0, 267, + 0, 0, 0, 120, 310, 122, 0, 0, 159, 131, + 0, 0, 0, 0, 301, 302, 0, 0, 0, 0, + 0, 0, 0, 0, 54, 0, 0, 268, 289, 288, + 291, 292, 293, 294, 0, 0, 95, 290, 295, 296, + 297, 0, 0, 0, 265, 282, 0, 309, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 279, 280, 0, + 0, 0, 0, 321, 0, 281, 0, 0, 276, 277, + 278, 283, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 109, 0, 0, 0, 210, 0, 0, 319, 0, + 146, 0, 162, 111, 119, 83, 89, 0, 110, 137, + 151, 155, 0, 0, 0, 99, 0, 153, 141, 175, + 0, 142, 152, 123, 167, 147, 174, 182, 183, 164, + 181, 190, 84, 163, 173, 96, 156, 86, 171, 161, + 129, 115, 116, 85, 0, 150, 102, 107, 101, 138, + 168, 169, 100, 193, 90, 180, 88, 91, 179, 136, + 166, 172, 130, 127, 87, 170, 128, 126, 118, 105, + 112, 144, 125, 145, 113, 133, 132, 134, 0, 0, + 0, 160, 177, 194, 93, 0, 165, 184, 185, 186, + 187, 188, 189, 0, 0, 94, 108, 104, 143, 135, + 92, 114, 157, 117, 124, 149, 192, 140, 154, 97, + 176, 158, 311, 320, 317, 318, 315, 316, 314, 313, + 312, 322, 303, 304, 305, 306, 308, 0, 307, 82, + 0, 121, 191, 148, 106, 178, 139, 0, 0, 0, + 0, 270, 0, 98, 0, 103, 0, 267, 0, 0, + 0, 120, 310, 122, 0, 0, 159, 131, 0, 0, + 0, 0, 301, 302, 0, 0, 0, 0, 0, 0, + 0, 0, 54, 0, 0, 268, 289, 288, 291, 292, + 293, 294, 0, 0, 95, 290, 295, 296, 297, 0, + 0, 0, 265, 282, 0, 309, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 279, 280, 0, 0, 0, + 0, 321, 0, 281, 0, 0, 276, 277, 278, 283, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, + 0, 0, 0, 210, 0, 0, 319, 0, 146, 0, + 162, 111, 119, 83, 89, 0, 110, 137, 151, 155, + 0, 0, 0, 99, 0, 153, 141, 175, 0, 142, + 152, 123, 167, 147, 174, 182, 183, 164, 181, 190, + 84, 163, 173, 96, 156, 86, 171, 161, 129, 115, + 116, 85, 0, 150, 102, 107, 101, 138, 168, 169, + 100, 193, 90, 180, 88, 91, 179, 136, 166, 172, + 130, 127, 87, 170, 128, 126, 118, 105, 112, 144, + 125, 145, 113, 133, 132, 134, 0, 0, 0, 160, + 177, 194, 93, 0, 165, 184, 185, 186, 187, 188, + 189, 0, 0, 94, 108, 104, 143, 135, 92, 114, + 157, 117, 124, 149, 192, 140, 154, 97, 176, 158, + 311, 320, 317, 318, 315, 316, 314, 313, 312, 322, + 303, 304, 305, 306, 308, 0, 307, 82, 139, 121, + 191, 148, 106, 178, 0, 98, 0, 103, 0, 0, + 0, 0, 0, 120, 310, 122, 0, 0, 159, 131, + 0, 0, 0, 0, 301, 302, 0, 0, 0, 0, + 0, 0, 0, 0, 54, 0, 0, 268, 289, 288, + 291, 292, 293, 294, 0, 0, 95, 290, 295, 296, + 297, 0, 0, 0, 0, 282, 0, 309, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 279, 280, 0, + 0, 0, 0, 321, 0, 281, 0, 0, 276, 277, + 278, 283, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 109, 0, 0, 0, 210, 0, 0, 319, 0, + 146, 0, 162, 111, 119, 83, 89, 0, 110, 137, + 151, 155, 0, 0, 0, 99, 0, 153, 141, 175, + 1411, 142, 152, 123, 167, 147, 174, 182, 183, 164, + 181, 190, 84, 163, 173, 96, 156, 86, 171, 161, + 129, 115, 116, 85, 0, 150, 102, 107, 101, 138, + 168, 169, 100, 193, 90, 180, 88, 91, 179, 136, + 166, 172, 130, 127, 87, 170, 128, 126, 118, 105, + 112, 144, 125, 145, 113, 133, 132, 134, 0, 0, + 0, 160, 177, 194, 93, 0, 165, 184, 185, 186, + 187, 188, 189, 0, 0, 94, 108, 104, 143, 135, + 92, 114, 157, 117, 124, 149, 192, 140, 154, 97, + 176, 158, 311, 320, 317, 318, 315, 316, 314, 313, + 312, 322, 303, 304, 305, 306, 308, 0, 307, 82, + 139, 121, 191, 148, 106, 178, 0, 98, 0, 103, + 0, 0, 0, 0, 0, 120, 310, 122, 0, 0, + 159, 131, 0, 0, 0, 0, 301, 302, 0, 0, + 0, 0, 0, 0, 0, 0, 54, 0, 0, 268, + 289, 288, 291, 292, 293, 294, 0, 0, 95, 290, + 295, 296, 297, 0, 0, 0, 0, 282, 0, 309, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 279, + 280, 0, 0, 0, 0, 321, 0, 281, 0, 0, + 276, 277, 278, 283, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 109, 0, 0, 0, 210, 0, 0, + 319, 0, 146, 0, 162, 111, 119, 83, 89, 0, + 110, 137, 151, 155, 0, 0, 0, 99, 0, 153, + 141, 175, 0, 142, 152, 123, 167, 147, 174, 182, + 183, 164, 181, 190, 84, 163, 173, 96, 156, 86, + 171, 161, 129, 115, 116, 85, 0, 150, 102, 107, + 101, 138, 168, 169, 100, 193, 90, 180, 88, 91, + 179, 136, 166, 172, 130, 127, 87, 170, 128, 126, + 118, 105, 112, 144, 125, 145, 113, 133, 132, 134, + 0, 0, 0, 160, 177, 194, 93, 0, 165, 184, + 185, 186, 187, 188, 189, 0, 0, 94, 108, 104, + 143, 135, 92, 114, 157, 117, 124, 149, 192, 140, + 154, 97, 176, 158, 311, 320, 317, 318, 315, 316, + 314, 313, 312, 322, 303, 304, 305, 306, 308, 0, + 307, 82, 139, 121, 191, 148, 106, 178, 0, 98, + 0, 103, 0, 0, 0, 0, 0, 120, 0, 122, + 0, 0, 159, 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, + 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 108, 0, 0, 0, - 209, 0, 0, 0, 0, 145, 0, 161, 110, 118, - 83, 89, 0, 109, 136, 150, 154, 0, 0, 0, - 98, 0, 152, 140, 174, 0, 141, 151, 122, 166, - 146, 173, 181, 182, 163, 180, 189, 84, 162, 172, - 96, 155, 86, 170, 160, 128, 114, 115, 85, 0, - 149, 101, 106, 100, 137, 167, 168, 99, 192, 90, - 179, 88, 91, 178, 135, 165, 171, 129, 126, 87, - 169, 127, 125, 117, 104, 111, 143, 124, 144, 112, - 132, 131, 133, 0, 0, 0, 159, 176, 193, 93, - 0, 164, 183, 184, 185, 186, 187, 188, 0, 0, - 94, 107, 103, 142, 134, 92, 113, 156, 116, 123, - 148, 191, 139, 153, 97, 175, 157, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 138, 0, 0, 0, - 0, 0, 0, 0, 82, 102, 120, 190, 147, 105, - 177, 119, 0, 121, 0, 0, 158, 130, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 528, 527, 537, + 538, 530, 531, 532, 533, 534, 535, 536, 529, 0, + 0, 539, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 109, 0, 0, 0, 210, + 0, 0, 0, 0, 146, 0, 162, 111, 119, 83, + 89, 0, 110, 137, 151, 155, 0, 0, 0, 99, + 0, 153, 141, 175, 0, 142, 152, 123, 167, 147, + 174, 182, 183, 164, 181, 190, 84, 163, 173, 96, + 156, 86, 171, 161, 129, 115, 116, 85, 0, 150, + 102, 107, 101, 138, 168, 169, 100, 193, 90, 180, + 88, 91, 179, 136, 166, 172, 130, 127, 87, 170, + 128, 126, 118, 105, 112, 144, 125, 145, 113, 133, + 132, 134, 0, 0, 0, 160, 177, 194, 93, 0, + 165, 184, 185, 186, 187, 188, 189, 0, 0, 94, + 108, 104, 143, 135, 92, 114, 157, 117, 124, 149, + 192, 140, 154, 97, 176, 158, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 139, 0, 0, 0, 516, + 0, 0, 98, 82, 103, 121, 191, 148, 106, 178, + 120, 0, 122, 0, 0, 159, 131, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 80, 0, 518, 0, 0, 0, + 0, 0, 0, 95, 0, 0, 0, 0, 0, 513, + 512, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 514, 0, 0, 0, + 0, 0, 0, 0, 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, 210, 0, 0, 0, 0, 146, 0, 162, + 111, 119, 83, 89, 0, 110, 137, 151, 155, 0, + 0, 0, 99, 0, 153, 141, 175, 0, 142, 152, + 123, 167, 147, 174, 182, 183, 164, 181, 190, 84, + 163, 173, 96, 156, 86, 171, 161, 129, 115, 116, + 85, 0, 150, 102, 107, 101, 138, 168, 169, 100, + 193, 90, 180, 88, 91, 179, 136, 166, 172, 130, + 127, 87, 170, 128, 126, 118, 105, 112, 144, 125, + 145, 113, 133, 132, 134, 0, 0, 0, 160, 177, + 194, 93, 0, 165, 184, 185, 186, 187, 188, 189, + 0, 0, 94, 108, 104, 143, 135, 92, 114, 157, + 117, 124, 149, 192, 140, 154, 97, 176, 158, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 139, 0, + 0, 0, 0, 0, 0, 98, 82, 103, 121, 191, + 148, 106, 178, 120, 0, 122, 0, 0, 159, 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, 95, 0, 0, 0, + 0, 0, 74, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 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, 76, 77, 0, 73, 0, 0, 0, 78, + 146, 0, 162, 111, 119, 83, 89, 0, 110, 137, + 151, 155, 0, 0, 0, 99, 0, 153, 141, 175, + 0, 142, 152, 123, 167, 147, 174, 182, 183, 164, + 181, 190, 84, 163, 173, 96, 156, 86, 171, 161, + 129, 115, 116, 85, 0, 150, 102, 107, 101, 138, + 168, 169, 100, 193, 90, 180, 88, 91, 179, 136, + 166, 172, 130, 127, 87, 170, 128, 126, 118, 105, + 112, 144, 125, 145, 113, 133, 132, 134, 0, 0, + 0, 160, 177, 194, 93, 0, 165, 184, 185, 186, + 187, 188, 189, 0, 0, 94, 108, 104, 143, 135, + 92, 114, 157, 117, 124, 149, 192, 140, 154, 97, + 176, 158, 0, 75, 0, 0, 0, 0, 0, 0, + 0, 139, 0, 0, 0, 825, 0, 0, 98, 82, + 103, 121, 191, 148, 106, 178, 120, 0, 122, 0, + 0, 159, 131, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 208, 0, 827, 0, 0, 0, 0, 0, 0, 95, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 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, 210, 0, + 0, 0, 0, 146, 0, 162, 111, 119, 83, 89, + 0, 110, 137, 151, 155, 0, 0, 0, 99, 0, + 153, 141, 175, 0, 142, 152, 123, 167, 147, 174, + 182, 183, 164, 181, 190, 84, 163, 173, 96, 156, + 86, 171, 161, 129, 115, 116, 85, 0, 150, 102, + 107, 101, 138, 168, 169, 100, 193, 90, 180, 88, + 91, 179, 136, 166, 172, 130, 127, 87, 170, 128, + 126, 118, 105, 112, 144, 125, 145, 113, 133, 132, + 134, 0, 0, 0, 160, 177, 194, 93, 0, 165, + 184, 185, 186, 187, 188, 189, 0, 0, 94, 108, + 104, 143, 135, 92, 114, 157, 117, 124, 149, 192, + 140, 154, 97, 176, 158, 0, 0, 0, 0, 0, + 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 82, 139, 121, 191, 148, 106, 178, 0, + 98, 0, 103, 0, 0, 0, 0, 0, 120, 0, + 122, 0, 0, 159, 131, 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, 95, 0, 0, 0, 0, 0, 0, 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, 95, 0, 0, 0, 0, 0, - 74, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 108, - 76, 77, 0, 73, 0, 0, 0, 78, 145, 0, - 161, 110, 118, 83, 89, 0, 109, 136, 150, 154, - 0, 0, 0, 98, 0, 152, 140, 174, 0, 141, - 151, 122, 166, 146, 173, 181, 182, 163, 180, 189, - 84, 162, 172, 96, 155, 86, 170, 160, 128, 114, - 115, 85, 0, 149, 101, 106, 100, 137, 167, 168, - 99, 192, 90, 179, 88, 91, 178, 135, 165, 171, - 129, 126, 87, 169, 127, 125, 117, 104, 111, 143, - 124, 144, 112, 132, 131, 133, 0, 0, 0, 159, - 176, 193, 93, 0, 164, 183, 184, 185, 186, 187, - 188, 0, 0, 94, 107, 103, 142, 134, 92, 113, - 156, 116, 123, 148, 191, 139, 153, 97, 175, 157, - 0, 75, 0, 0, 0, 0, 0, 0, 0, 138, - 0, 0, 0, 824, 0, 0, 0, 82, 102, 120, - 190, 147, 105, 177, 119, 0, 121, 0, 0, 158, - 130, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 207, 0, - 826, 0, 0, 0, 0, 0, 0, 95, 0, 0, + 0, 0, 0, 0, 0, 0, 109, 0, 0, 0, + 210, 0, 0, 0, 0, 146, 0, 162, 111, 119, + 83, 89, 0, 110, 137, 151, 155, 0, 0, 0, + 99, 0, 153, 141, 175, 0, 142, 152, 123, 167, + 147, 174, 182, 183, 164, 181, 190, 84, 163, 173, + 96, 156, 86, 171, 161, 129, 115, 116, 85, 0, + 150, 102, 107, 101, 138, 168, 169, 100, 193, 90, + 180, 88, 91, 179, 136, 166, 172, 130, 127, 87, + 170, 128, 126, 118, 105, 112, 144, 125, 145, 113, + 133, 132, 134, 0, 0, 0, 160, 177, 194, 93, + 0, 165, 184, 185, 186, 187, 188, 189, 0, 0, + 94, 108, 104, 143, 135, 92, 114, 157, 117, 124, + 149, 192, 140, 154, 97, 176, 158, 0, 0, 0, + 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 82, 139, 121, 191, 148, 106, + 178, 0, 98, 0, 103, 0, 0, 0, 0, 0, + 120, 0, 122, 0, 0, 159, 131, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 54, 0, 0, 208, 0, 0, 0, 0, 0, + 0, 0, 0, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 108, 0, 0, 0, 209, 0, 0, 0, - 0, 145, 0, 161, 110, 118, 83, 89, 0, 109, - 136, 150, 154, 0, 0, 0, 98, 0, 152, 140, - 174, 0, 141, 151, 122, 166, 146, 173, 181, 182, - 163, 180, 189, 84, 162, 172, 96, 155, 86, 170, - 160, 128, 114, 115, 85, 0, 149, 101, 106, 100, - 137, 167, 168, 99, 192, 90, 179, 88, 91, 178, - 135, 165, 171, 129, 126, 87, 169, 127, 125, 117, - 104, 111, 143, 124, 144, 112, 132, 131, 133, 0, - 0, 0, 159, 176, 193, 93, 0, 164, 183, 184, - 185, 186, 187, 188, 0, 0, 94, 107, 103, 142, - 134, 92, 113, 156, 116, 123, 148, 191, 139, 153, - 97, 175, 157, 0, 0, 0, 24, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 138, 0, - 82, 0, 120, 190, 147, 105, 177, 102, 0, 0, - 0, 0, 0, 119, 0, 121, 0, 0, 158, 130, + 0, 0, 0, 0, 0, 0, 0, 0, 109, 0, + 0, 0, 210, 0, 0, 0, 0, 146, 0, 162, + 111, 119, 83, 89, 0, 110, 137, 151, 155, 0, + 0, 0, 99, 0, 153, 141, 175, 0, 142, 152, + 123, 167, 147, 174, 182, 183, 164, 181, 190, 84, + 163, 173, 96, 156, 86, 171, 161, 129, 115, 116, + 85, 0, 150, 102, 107, 101, 138, 168, 169, 100, + 193, 90, 180, 88, 91, 179, 136, 166, 172, 130, + 127, 87, 170, 128, 126, 118, 105, 112, 144, 125, + 145, 113, 133, 132, 134, 0, 0, 0, 160, 177, + 194, 93, 0, 165, 184, 185, 186, 187, 188, 189, + 0, 0, 94, 108, 104, 143, 135, 92, 114, 157, + 117, 124, 149, 192, 140, 154, 97, 176, 158, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 139, 0, + 0, 0, 825, 0, 0, 98, 82, 103, 121, 191, + 148, 106, 178, 120, 0, 122, 0, 0, 159, 131, 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, 0, 208, 0, 827, 0, 0, 0, 0, 0, 0, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 108, 0, 0, 0, 209, 0, 0, 0, 0, - 145, 0, 161, 110, 118, 83, 89, 0, 109, 136, - 150, 154, 0, 0, 0, 98, 0, 152, 140, 174, - 0, 141, 151, 122, 166, 146, 173, 181, 182, 163, - 180, 189, 84, 162, 172, 96, 155, 86, 170, 160, - 128, 114, 115, 85, 0, 149, 101, 106, 100, 137, - 167, 168, 99, 192, 90, 179, 88, 91, 178, 135, - 165, 171, 129, 126, 87, 169, 127, 125, 117, 104, - 111, 143, 124, 144, 112, 132, 131, 133, 0, 0, - 0, 159, 176, 193, 93, 0, 164, 183, 184, 185, - 186, 187, 188, 0, 0, 94, 107, 103, 142, 134, - 92, 113, 156, 116, 123, 148, 191, 139, 153, 97, - 175, 157, 0, 0, 0, 24, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 138, 0, 82, - 0, 120, 190, 147, 105, 177, 102, 0, 0, 0, - 0, 0, 119, 0, 121, 0, 0, 158, 130, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 54, 0, 0, 207, 0, 0, 0, - 0, 0, 0, 0, 0, 95, 0, 0, 0, 0, + 0, 109, 0, 0, 0, 210, 0, 0, 0, 0, + 146, 0, 162, 111, 119, 83, 89, 0, 110, 137, + 151, 155, 0, 0, 0, 99, 0, 153, 141, 175, + 0, 823, 152, 123, 167, 147, 174, 182, 183, 164, + 181, 190, 84, 163, 173, 96, 156, 86, 171, 161, + 129, 115, 116, 85, 0, 150, 102, 107, 101, 138, + 168, 169, 100, 193, 90, 180, 88, 91, 179, 136, + 166, 172, 130, 127, 87, 170, 128, 126, 118, 105, + 112, 144, 125, 145, 113, 133, 132, 134, 0, 0, + 0, 160, 177, 194, 93, 0, 165, 184, 185, 186, + 187, 188, 189, 0, 0, 94, 108, 104, 143, 135, + 92, 114, 157, 117, 124, 149, 192, 140, 154, 97, + 176, 158, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 139, 0, 0, 0, 0, 0, 0, 98, 82, + 103, 121, 191, 148, 106, 178, 120, 0, 122, 0, + 0, 159, 131, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 80, 0, 0, 725, 0, 0, 726, 0, 0, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 108, 0, 0, 0, 209, 0, 0, 0, 0, 145, - 0, 161, 110, 118, 83, 89, 0, 109, 136, 150, - 154, 0, 0, 0, 98, 0, 152, 140, 174, 0, - 141, 151, 122, 166, 146, 173, 181, 182, 163, 180, - 189, 84, 162, 172, 96, 155, 86, 170, 160, 128, - 114, 115, 85, 0, 149, 101, 106, 100, 137, 167, - 168, 99, 192, 90, 179, 88, 91, 178, 135, 165, - 171, 129, 126, 87, 169, 127, 125, 117, 104, 111, - 143, 124, 144, 112, 132, 131, 133, 0, 0, 0, - 159, 176, 193, 93, 0, 164, 183, 184, 185, 186, - 187, 188, 0, 0, 94, 107, 103, 142, 134, 92, - 113, 156, 116, 123, 148, 191, 139, 153, 97, 175, - 157, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 138, 0, 0, 0, 824, 0, 0, 0, 82, 102, - 120, 190, 147, 105, 177, 119, 0, 121, 0, 0, - 158, 130, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 207, - 0, 826, 0, 0, 0, 0, 0, 0, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 109, 0, 0, 0, 210, 0, + 0, 0, 0, 146, 0, 162, 111, 119, 83, 89, + 0, 110, 137, 151, 155, 0, 0, 0, 99, 0, + 153, 141, 175, 0, 142, 152, 123, 167, 147, 174, + 182, 183, 164, 181, 190, 84, 163, 173, 96, 156, + 86, 171, 161, 129, 115, 116, 85, 0, 150, 102, + 107, 101, 138, 168, 169, 100, 193, 90, 180, 88, + 91, 179, 136, 166, 172, 130, 127, 87, 170, 128, + 126, 118, 105, 112, 144, 125, 145, 113, 133, 132, + 134, 0, 0, 0, 160, 177, 194, 93, 0, 165, + 184, 185, 186, 187, 188, 189, 0, 0, 94, 108, + 104, 143, 135, 92, 114, 157, 117, 124, 149, 192, + 140, 154, 97, 176, 158, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 82, 139, 121, 191, 148, 106, 178, 0, + 98, 0, 103, 0, 618, 0, 0, 0, 120, 0, + 122, 0, 0, 159, 131, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 80, 0, 617, 0, 0, 0, 0, 0, + 0, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 108, 0, 0, 0, 209, 0, 0, - 0, 0, 145, 0, 161, 110, 118, 83, 89, 0, - 109, 136, 150, 154, 0, 0, 0, 98, 0, 152, - 140, 174, 0, 822, 151, 122, 166, 146, 173, 181, - 182, 163, 180, 189, 84, 162, 172, 96, 155, 86, - 170, 160, 128, 114, 115, 85, 0, 149, 101, 106, - 100, 137, 167, 168, 99, 192, 90, 179, 88, 91, - 178, 135, 165, 171, 129, 126, 87, 169, 127, 125, - 117, 104, 111, 143, 124, 144, 112, 132, 131, 133, - 0, 0, 0, 159, 176, 193, 93, 0, 164, 183, - 184, 185, 186, 187, 188, 0, 0, 94, 107, 103, - 142, 134, 92, 113, 156, 116, 123, 148, 191, 139, - 153, 97, 175, 157, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 138, 0, 0, 0, 0, 0, 0, - 0, 82, 102, 120, 190, 147, 105, 177, 119, 0, - 121, 0, 0, 158, 130, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 80, 0, 0, 724, 0, 0, 725, 0, - 0, 95, 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, + 210, 0, 0, 0, 0, 146, 0, 162, 111, 119, + 83, 89, 0, 110, 137, 151, 155, 0, 0, 0, + 99, 0, 153, 141, 175, 0, 142, 152, 123, 167, + 147, 174, 182, 183, 164, 181, 190, 84, 163, 173, + 96, 156, 86, 171, 161, 129, 115, 116, 85, 0, + 150, 102, 107, 101, 138, 168, 169, 100, 193, 90, + 180, 88, 91, 179, 136, 166, 172, 130, 127, 87, + 170, 128, 126, 118, 105, 112, 144, 125, 145, 113, + 133, 132, 134, 0, 0, 0, 160, 177, 194, 93, + 0, 165, 184, 185, 186, 187, 188, 189, 0, 0, + 94, 108, 104, 143, 135, 92, 114, 157, 117, 124, + 149, 192, 140, 154, 97, 176, 158, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 139, 0, 0, 0, + 0, 0, 0, 98, 82, 103, 121, 191, 148, 106, + 178, 120, 0, 122, 0, 0, 159, 131, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 54, 0, 0, 208, 0, 0, 0, 0, + 0, 0, 0, 0, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 108, 0, 0, 0, - 209, 0, 0, 0, 0, 145, 0, 161, 110, 118, - 83, 89, 0, 109, 136, 150, 154, 0, 0, 0, - 98, 0, 152, 140, 174, 0, 141, 151, 122, 166, - 146, 173, 181, 182, 163, 180, 189, 84, 162, 172, - 96, 155, 86, 170, 160, 128, 114, 115, 85, 0, - 149, 101, 106, 100, 137, 167, 168, 99, 192, 90, - 179, 88, 91, 178, 135, 165, 171, 129, 126, 87, - 169, 127, 125, 117, 104, 111, 143, 124, 144, 112, - 132, 131, 133, 0, 0, 0, 159, 176, 193, 93, - 0, 164, 183, 184, 185, 186, 187, 188, 0, 0, - 94, 107, 103, 142, 134, 92, 113, 156, 116, 123, - 148, 191, 139, 153, 97, 175, 157, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 138, 0, 82, 0, 120, 190, 147, 105, - 177, 102, 0, 617, 0, 0, 0, 119, 0, 121, - 0, 0, 158, 130, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 80, 0, 616, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, + 0, 0, 0, 210, 0, 0, 0, 0, 146, 0, + 162, 111, 119, 83, 89, 0, 110, 137, 151, 155, + 0, 0, 0, 99, 0, 153, 141, 175, 0, 142, + 152, 123, 167, 147, 174, 182, 183, 164, 181, 190, + 84, 163, 173, 96, 156, 86, 171, 161, 129, 115, + 116, 85, 0, 150, 102, 107, 101, 138, 168, 169, + 100, 193, 90, 180, 88, 91, 179, 136, 166, 172, + 130, 127, 87, 170, 128, 126, 118, 105, 112, 144, + 125, 145, 113, 133, 132, 134, 0, 0, 0, 160, + 177, 194, 93, 0, 165, 184, 185, 186, 187, 188, + 189, 0, 0, 94, 108, 104, 143, 135, 92, 114, + 157, 117, 124, 149, 192, 140, 154, 97, 176, 158, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 139, + 0, 0, 0, 0, 0, 0, 98, 82, 103, 121, + 191, 148, 106, 178, 120, 0, 122, 0, 0, 159, + 131, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 208, 0, + 827, 0, 0, 0, 0, 0, 0, 95, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 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, 210, 0, 0, 0, + 0, 146, 0, 162, 111, 119, 83, 89, 0, 110, + 137, 151, 155, 0, 0, 0, 99, 0, 153, 141, + 175, 0, 142, 152, 123, 167, 147, 174, 182, 183, + 164, 181, 190, 84, 163, 173, 96, 156, 86, 171, + 161, 129, 115, 116, 85, 0, 150, 102, 107, 101, + 138, 168, 169, 100, 193, 90, 180, 88, 91, 179, + 136, 166, 172, 130, 127, 87, 170, 128, 126, 118, + 105, 112, 144, 125, 145, 113, 133, 132, 134, 0, + 0, 0, 160, 177, 194, 93, 0, 165, 184, 185, + 186, 187, 188, 189, 0, 0, 94, 108, 104, 143, + 135, 92, 114, 157, 117, 124, 149, 192, 140, 154, + 97, 176, 158, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 139, 0, 0, 0, 0, 0, 0, 98, + 82, 103, 121, 191, 148, 106, 178, 120, 0, 122, + 0, 0, 159, 131, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 268, 0, 790, 0, 0, 0, 0, 0, 0, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 108, 0, 0, 0, 209, - 0, 0, 0, 0, 145, 0, 161, 110, 118, 83, - 89, 0, 109, 136, 150, 154, 0, 0, 0, 98, - 0, 152, 140, 174, 0, 141, 151, 122, 166, 146, - 173, 181, 182, 163, 180, 189, 84, 162, 172, 96, - 155, 86, 170, 160, 128, 114, 115, 85, 0, 149, - 101, 106, 100, 137, 167, 168, 99, 192, 90, 179, - 88, 91, 178, 135, 165, 171, 129, 126, 87, 169, - 127, 125, 117, 104, 111, 143, 124, 144, 112, 132, - 131, 133, 0, 0, 0, 159, 176, 193, 93, 0, - 164, 183, 184, 185, 186, 187, 188, 0, 0, 94, - 107, 103, 142, 134, 92, 113, 156, 116, 123, 148, - 191, 139, 153, 97, 175, 157, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 138, 0, 0, 0, 0, - 0, 0, 0, 82, 102, 120, 190, 147, 105, 177, - 119, 0, 121, 0, 0, 158, 130, 0, 0, 0, + 0, 0, 0, 0, 0, 109, 0, 0, 0, 210, + 0, 0, 0, 0, 146, 0, 162, 111, 119, 83, + 89, 0, 110, 137, 151, 155, 0, 0, 0, 99, + 0, 153, 141, 175, 0, 142, 152, 123, 167, 147, + 174, 182, 183, 164, 181, 190, 84, 163, 173, 96, + 156, 86, 171, 161, 129, 115, 116, 85, 0, 150, + 102, 107, 101, 138, 168, 169, 100, 193, 90, 180, + 88, 91, 179, 136, 166, 172, 130, 127, 87, 170, + 128, 126, 118, 105, 112, 144, 125, 145, 113, 133, + 132, 134, 0, 0, 0, 160, 177, 194, 93, 0, + 165, 184, 185, 186, 187, 188, 189, 0, 0, 94, + 108, 104, 143, 135, 92, 114, 157, 117, 124, 149, + 192, 140, 154, 97, 176, 158, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 139, 0, 0, 0, 0, + 0, 0, 98, 82, 103, 121, 191, 148, 106, 178, + 120, 0, 122, 0, 0, 159, 131, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 54, 0, 0, 207, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 268, 0, 786, 0, 0, 0, 0, 0, 0, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 108, 0, - 0, 0, 209, 0, 0, 0, 0, 145, 0, 161, - 110, 118, 83, 89, 0, 109, 136, 150, 154, 0, - 0, 0, 98, 0, 152, 140, 174, 0, 141, 151, - 122, 166, 146, 173, 181, 182, 163, 180, 189, 84, - 162, 172, 96, 155, 86, 170, 160, 128, 114, 115, - 85, 0, 149, 101, 106, 100, 137, 167, 168, 99, - 192, 90, 179, 88, 91, 178, 135, 165, 171, 129, - 126, 87, 169, 127, 125, 117, 104, 111, 143, 124, - 144, 112, 132, 131, 133, 0, 0, 0, 159, 176, - 193, 93, 0, 164, 183, 184, 185, 186, 187, 188, - 0, 0, 94, 107, 103, 142, 134, 92, 113, 156, - 116, 123, 148, 191, 139, 153, 97, 175, 157, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 138, 0, - 0, 0, 0, 0, 0, 0, 82, 102, 120, 190, - 147, 105, 177, 119, 0, 121, 0, 0, 158, 130, + 0, 0, 0, 0, 0, 0, 0, 0, 109, 0, + 0, 0, 210, 0, 0, 0, 0, 146, 0, 162, + 111, 119, 83, 89, 0, 110, 137, 151, 155, 0, + 0, 0, 99, 0, 153, 141, 175, 0, 142, 152, + 123, 167, 147, 174, 182, 183, 164, 181, 190, 84, + 163, 173, 96, 156, 86, 171, 161, 129, 115, 116, + 85, 0, 150, 102, 107, 101, 138, 168, 169, 100, + 193, 90, 180, 88, 91, 179, 136, 166, 172, 130, + 127, 87, 170, 128, 126, 118, 105, 112, 144, 125, + 145, 113, 133, 132, 134, 0, 0, 0, 160, 177, + 194, 93, 0, 165, 184, 185, 186, 187, 188, 189, + 0, 0, 94, 108, 104, 143, 135, 92, 114, 157, + 117, 124, 149, 192, 140, 154, 97, 176, 158, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 139, 0, + 0, 0, 0, 0, 0, 98, 82, 103, 121, 191, + 148, 106, 178, 120, 0, 122, 0, 0, 159, 131, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 207, 0, 826, + 0, 0, 0, 0, 0, 0, 0, 80, 0, 518, 0, 0, 0, 0, 0, 0, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 108, 0, 0, 0, 209, 0, 0, 0, 0, - 145, 0, 161, 110, 118, 83, 89, 0, 109, 136, - 150, 154, 0, 0, 0, 98, 0, 152, 140, 174, - 0, 141, 151, 122, 166, 146, 173, 181, 182, 163, - 180, 189, 84, 162, 172, 96, 155, 86, 170, 160, - 128, 114, 115, 85, 0, 149, 101, 106, 100, 137, - 167, 168, 99, 192, 90, 179, 88, 91, 178, 135, - 165, 171, 129, 126, 87, 169, 127, 125, 117, 104, - 111, 143, 124, 144, 112, 132, 131, 133, 0, 0, - 0, 159, 176, 193, 93, 0, 164, 183, 184, 185, - 186, 187, 188, 0, 0, 94, 107, 103, 142, 134, - 92, 113, 156, 116, 123, 148, 191, 139, 153, 97, - 175, 157, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 138, 0, 0, 0, 0, 0, 0, 0, 82, - 102, 120, 190, 147, 105, 177, 119, 0, 121, 0, - 0, 158, 130, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 267, 0, 789, 0, 0, 0, 0, 0, 0, 95, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 108, 0, 0, 0, 209, 0, - 0, 0, 0, 145, 0, 161, 110, 118, 83, 89, - 0, 109, 136, 150, 154, 0, 0, 0, 98, 0, - 152, 140, 174, 0, 141, 151, 122, 166, 146, 173, - 181, 182, 163, 180, 189, 84, 162, 172, 96, 155, - 86, 170, 160, 128, 114, 115, 85, 0, 149, 101, - 106, 100, 137, 167, 168, 99, 192, 90, 179, 88, - 91, 178, 135, 165, 171, 129, 126, 87, 169, 127, - 125, 117, 104, 111, 143, 124, 144, 112, 132, 131, - 133, 0, 0, 0, 159, 176, 193, 93, 0, 164, - 183, 184, 185, 186, 187, 188, 0, 0, 94, 107, - 103, 142, 134, 92, 113, 156, 116, 123, 148, 191, - 139, 153, 97, 175, 157, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 138, 0, 0, 0, 0, 0, - 0, 0, 82, 102, 120, 190, 147, 105, 177, 119, - 0, 121, 0, 0, 158, 130, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 267, 0, 785, 0, 0, 0, 0, - 0, 0, 95, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 108, 0, 0, - 0, 209, 0, 0, 0, 0, 145, 0, 161, 110, - 118, 83, 89, 0, 109, 136, 150, 154, 0, 0, - 0, 98, 0, 152, 140, 174, 0, 141, 151, 122, - 166, 146, 173, 181, 182, 163, 180, 189, 84, 162, - 172, 96, 155, 86, 170, 160, 128, 114, 115, 85, - 0, 149, 101, 106, 100, 137, 167, 168, 99, 192, - 90, 179, 88, 91, 178, 135, 165, 171, 129, 126, - 87, 169, 127, 125, 117, 104, 111, 143, 124, 144, - 112, 132, 131, 133, 0, 0, 0, 159, 176, 193, - 93, 0, 164, 183, 184, 185, 186, 187, 188, 0, - 0, 94, 107, 103, 142, 134, 92, 113, 156, 116, - 123, 148, 191, 139, 153, 97, 175, 157, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 138, 0, 0, - 0, 0, 0, 0, 0, 82, 102, 120, 190, 147, - 105, 177, 119, 0, 121, 0, 0, 158, 130, 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, 95, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 108, 0, 0, 0, 209, 0, 0, 0, 0, 145, - 0, 161, 110, 118, 83, 89, 0, 109, 136, 150, - 154, 0, 0, 0, 98, 0, 152, 140, 174, 0, - 141, 151, 122, 166, 146, 173, 181, 182, 163, 180, - 189, 84, 162, 172, 96, 155, 86, 170, 160, 128, - 114, 115, 85, 0, 149, 101, 106, 100, 137, 167, - 168, 99, 192, 90, 179, 88, 91, 178, 135, 165, - 171, 129, 126, 87, 169, 127, 125, 117, 104, 111, - 143, 124, 144, 112, 132, 131, 133, 0, 0, 0, - 159, 176, 193, 93, 0, 164, 183, 184, 185, 186, - 187, 188, 0, 0, 94, 107, 103, 142, 134, 92, - 113, 156, 116, 123, 148, 191, 139, 153, 97, 175, - 157, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 138, 82, 0, - 120, 190, 147, 105, 177, 590, 102, 0, 0, 0, - 0, 0, 119, 0, 121, 0, 0, 158, 130, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 207, 0, 0, 0, - 0, 0, 0, 0, 0, 95, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 108, 0, 0, 0, 209, 0, 0, 0, 0, 145, - 0, 161, 110, 118, 83, 89, 0, 109, 136, 150, - 154, 0, 0, 0, 98, 0, 152, 140, 174, 0, - 141, 151, 122, 166, 146, 173, 181, 182, 163, 180, - 189, 84, 162, 172, 96, 155, 86, 170, 160, 128, - 114, 115, 85, 0, 149, 101, 106, 100, 137, 167, - 168, 99, 192, 90, 179, 88, 91, 178, 135, 165, - 171, 129, 126, 87, 169, 127, 125, 117, 104, 111, - 143, 124, 144, 112, 132, 131, 133, 0, 0, 0, - 159, 176, 193, 93, 0, 164, 183, 184, 185, 186, - 187, 188, 0, 0, 94, 107, 103, 142, 134, 92, - 113, 156, 116, 123, 148, 191, 139, 153, 97, 175, - 157, 0, 0, 324, 0, 0, 0, 0, 0, 0, - 138, 0, 0, 0, 0, 0, 0, 0, 82, 102, - 120, 190, 147, 105, 177, 119, 0, 121, 0, 0, - 158, 130, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 207, + 0, 109, 0, 0, 0, 210, 0, 0, 0, 0, + 146, 0, 162, 111, 119, 83, 89, 0, 110, 137, + 151, 155, 0, 0, 0, 99, 0, 153, 141, 175, + 0, 142, 152, 123, 167, 147, 174, 182, 183, 164, + 181, 190, 84, 163, 173, 96, 156, 86, 171, 161, + 129, 115, 116, 85, 0, 150, 102, 107, 101, 138, + 168, 169, 100, 193, 90, 180, 88, 91, 179, 136, + 166, 172, 130, 127, 87, 170, 128, 126, 118, 105, + 112, 144, 125, 145, 113, 133, 132, 134, 0, 0, + 0, 160, 177, 194, 93, 0, 165, 184, 185, 186, + 187, 188, 189, 0, 0, 94, 108, 104, 143, 135, + 92, 114, 157, 117, 124, 149, 192, 140, 154, 97, + 176, 158, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, + 139, 121, 191, 148, 106, 178, 0, 98, 591, 103, + 0, 0, 0, 0, 0, 120, 0, 122, 0, 0, + 159, 131, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 208, 0, 0, 0, 0, 0, 0, 0, 0, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 108, 0, 0, 0, 209, 0, 0, - 0, 0, 145, 0, 161, 110, 118, 83, 89, 0, - 109, 136, 150, 154, 0, 0, 0, 98, 0, 152, - 140, 174, 0, 141, 151, 122, 166, 146, 173, 181, - 182, 163, 180, 189, 84, 162, 172, 96, 155, 86, - 170, 160, 128, 114, 115, 85, 0, 149, 101, 106, - 100, 137, 167, 168, 99, 192, 90, 179, 88, 91, - 178, 135, 165, 171, 129, 126, 87, 169, 127, 125, - 117, 104, 111, 143, 124, 144, 112, 132, 131, 133, - 0, 0, 0, 159, 176, 193, 93, 0, 164, 183, - 184, 185, 186, 187, 188, 0, 0, 94, 107, 103, - 142, 134, 92, 113, 156, 116, 123, 148, 191, 139, - 153, 97, 175, 157, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 138, 0, 0, 0, 0, 0, 0, - 0, 82, 102, 120, 190, 147, 105, 177, 119, 0, - 121, 0, 0, 158, 130, 0, 0, 0, 0, 0, + 0, 0, 0, 109, 0, 0, 0, 210, 0, 0, + 0, 0, 146, 0, 162, 111, 119, 83, 89, 0, + 110, 137, 151, 155, 0, 0, 0, 99, 0, 153, + 141, 175, 0, 142, 152, 123, 167, 147, 174, 182, + 183, 164, 181, 190, 84, 163, 173, 96, 156, 86, + 171, 161, 129, 115, 116, 85, 0, 150, 102, 107, + 101, 138, 168, 169, 100, 193, 90, 180, 88, 91, + 179, 136, 166, 172, 130, 127, 87, 170, 128, 126, + 118, 105, 112, 144, 125, 145, 113, 133, 132, 134, + 0, 0, 0, 160, 177, 194, 93, 0, 165, 184, + 185, 186, 187, 188, 189, 0, 0, 94, 108, 104, + 143, 135, 92, 114, 157, 117, 124, 149, 192, 140, + 154, 97, 176, 158, 0, 0, 325, 0, 0, 0, + 0, 0, 0, 139, 0, 0, 0, 0, 0, 0, + 98, 82, 103, 121, 191, 148, 106, 178, 120, 0, + 122, 0, 0, 159, 131, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 207, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 208, 0, 0, 0, 0, 0, 0, 0, 0, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 108, 0, 204, 0, - 209, 0, 0, 0, 0, 145, 0, 161, 110, 118, - 83, 89, 0, 109, 136, 150, 154, 0, 0, 0, - 98, 0, 152, 140, 174, 0, 141, 151, 122, 166, - 146, 173, 181, 182, 163, 180, 189, 84, 162, 172, - 96, 155, 86, 170, 160, 128, 114, 115, 85, 0, - 149, 101, 106, 100, 137, 167, 168, 99, 192, 90, - 179, 88, 91, 178, 135, 165, 171, 129, 126, 87, - 169, 127, 125, 117, 104, 111, 143, 124, 144, 112, - 132, 131, 133, 0, 0, 0, 159, 176, 193, 93, - 0, 164, 183, 184, 185, 186, 187, 188, 0, 0, - 94, 107, 103, 142, 134, 92, 113, 156, 116, 123, - 148, 191, 139, 153, 97, 175, 157, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 138, 0, 0, 0, - 0, 0, 0, 0, 82, 102, 120, 190, 147, 105, - 177, 119, 0, 121, 0, 0, 158, 130, 0, 0, + 0, 0, 0, 0, 0, 0, 109, 0, 0, 0, + 210, 0, 0, 0, 0, 146, 0, 162, 111, 119, + 83, 89, 0, 110, 137, 151, 155, 0, 0, 0, + 99, 0, 153, 141, 175, 0, 142, 152, 123, 167, + 147, 174, 182, 183, 164, 181, 190, 84, 163, 173, + 96, 156, 86, 171, 161, 129, 115, 116, 85, 0, + 150, 102, 107, 101, 138, 168, 169, 100, 193, 90, + 180, 88, 91, 179, 136, 166, 172, 130, 127, 87, + 170, 128, 126, 118, 105, 112, 144, 125, 145, 113, + 133, 132, 134, 0, 0, 0, 160, 177, 194, 93, + 0, 165, 184, 185, 186, 187, 188, 189, 0, 0, + 94, 108, 104, 143, 135, 92, 114, 157, 117, 124, + 149, 192, 140, 154, 97, 176, 158, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 139, 0, 0, 0, + 0, 0, 0, 98, 82, 103, 121, 191, 148, 106, + 178, 120, 0, 122, 0, 0, 159, 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, 0, 208, 0, 0, 0, 0, 0, 0, 0, 0, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 108, - 0, 0, 0, 209, 0, 0, 0, 0, 145, 0, - 161, 110, 118, 83, 89, 0, 109, 136, 150, 154, - 0, 0, 0, 98, 0, 152, 140, 174, 0, 141, - 151, 122, 166, 146, 173, 181, 182, 163, 180, 189, - 84, 162, 172, 96, 155, 86, 170, 160, 128, 114, - 115, 85, 0, 149, 101, 106, 100, 137, 167, 168, - 99, 192, 90, 179, 88, 91, 178, 135, 165, 171, - 129, 126, 87, 169, 127, 125, 117, 104, 111, 143, - 124, 144, 112, 132, 131, 133, 0, 0, 0, 159, - 176, 193, 93, 0, 164, 183, 184, 185, 186, 187, - 188, 0, 0, 94, 107, 103, 142, 134, 92, 113, - 156, 116, 123, 148, 191, 139, 153, 97, 175, 157, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 138, - 0, 0, 0, 0, 0, 0, 0, 82, 102, 120, - 190, 147, 105, 177, 119, 0, 121, 0, 0, 158, - 130, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 207, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, + 0, 205, 0, 210, 0, 0, 0, 0, 146, 0, + 162, 111, 119, 83, 89, 0, 110, 137, 151, 155, + 0, 0, 0, 99, 0, 153, 141, 175, 0, 142, + 152, 123, 167, 147, 174, 182, 183, 164, 181, 190, + 84, 163, 173, 96, 156, 86, 171, 161, 129, 115, + 116, 85, 0, 150, 102, 107, 101, 138, 168, 169, + 100, 193, 90, 180, 88, 91, 179, 136, 166, 172, + 130, 127, 87, 170, 128, 126, 118, 105, 112, 144, + 125, 145, 113, 133, 132, 134, 0, 0, 0, 160, + 177, 194, 93, 0, 165, 184, 185, 186, 187, 188, + 189, 0, 0, 94, 108, 104, 143, 135, 92, 114, + 157, 117, 124, 149, 192, 140, 154, 97, 176, 158, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 139, + 0, 0, 0, 0, 0, 0, 98, 82, 103, 121, + 191, 148, 106, 178, 120, 0, 122, 0, 0, 159, + 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, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 108, 0, 0, 0, 209, 0, 0, 0, - 0, 145, 0, 161, 110, 118, 83, 89, 0, 109, - 136, 150, 154, 0, 0, 0, 98, 0, 152, 140, - 174, 0, 141, 151, 122, 166, 146, 173, 181, 182, - 163, 180, 189, 84, 162, 172, 96, 155, 86, 170, - 160, 128, 114, 115, 85, 0, 149, 101, 106, 100, - 137, 167, 168, 99, 192, 90, 179, 88, 91, 178, - 135, 165, 171, 129, 126, 87, 169, 127, 125, 117, - 104, 111, 143, 124, 144, 112, 132, 131, 133, 0, - 0, 0, 159, 176, 193, 93, 0, 164, 183, 184, - 185, 186, 187, 188, 0, 0, 94, 107, 103, 142, - 134, 92, 113, 156, 116, 123, 148, 191, 139, 153, - 97, 175, 157, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 138, 0, 0, 0, 0, 0, 0, 0, - 82, 102, 120, 190, 147, 105, 177, 119, 0, 121, - 0, 0, 158, 130, 0, 0, 0, 0, 0, 0, + 0, 0, 109, 0, 0, 0, 210, 0, 0, 0, + 0, 146, 0, 162, 111, 119, 83, 89, 0, 110, + 137, 151, 155, 0, 0, 0, 99, 0, 153, 141, + 175, 0, 142, 152, 123, 167, 147, 174, 182, 183, + 164, 181, 190, 84, 163, 173, 96, 156, 86, 171, + 161, 129, 115, 116, 85, 0, 150, 102, 107, 101, + 138, 168, 169, 100, 193, 90, 180, 88, 91, 179, + 136, 166, 172, 130, 127, 87, 170, 128, 126, 118, + 105, 112, 144, 125, 145, 113, 133, 132, 134, 0, + 0, 0, 160, 177, 194, 93, 0, 165, 184, 185, + 186, 187, 188, 189, 0, 0, 94, 108, 104, 143, + 135, 92, 114, 157, 117, 124, 149, 192, 140, 154, + 97, 176, 158, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 139, 0, 0, 0, 0, 0, 0, 98, + 82, 103, 121, 191, 148, 106, 178, 120, 0, 122, + 0, 0, 159, 131, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 267, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 208, 0, 0, 0, 0, 0, 0, 0, 0, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 108, 0, 0, 0, 209, - 0, 0, 0, 0, 145, 0, 161, 110, 118, 83, - 89, 0, 109, 136, 150, 154, 0, 0, 0, 98, - 0, 152, 140, 174, 0, 141, 151, 122, 166, 146, - 173, 181, 182, 163, 180, 189, 84, 162, 172, 96, - 155, 86, 170, 160, 128, 114, 115, 85, 0, 149, - 101, 106, 100, 137, 167, 168, 99, 192, 90, 179, - 88, 91, 178, 135, 165, 171, 129, 126, 87, 169, - 127, 125, 117, 104, 111, 143, 124, 144, 112, 132, - 131, 133, 0, 0, 0, 159, 176, 193, 93, 0, - 164, 183, 184, 185, 186, 187, 188, 0, 0, 94, - 107, 103, 142, 134, 92, 113, 156, 116, 123, 148, - 191, 139, 153, 97, 175, 157, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 109, 0, 0, 0, 210, + 0, 0, 0, 0, 146, 0, 162, 111, 119, 83, + 89, 0, 110, 137, 151, 155, 0, 0, 0, 99, + 0, 153, 141, 175, 0, 142, 152, 123, 167, 147, + 174, 182, 183, 164, 181, 190, 84, 163, 173, 96, + 156, 86, 171, 161, 129, 115, 116, 85, 0, 150, + 102, 107, 101, 138, 168, 169, 100, 193, 90, 180, + 88, 91, 179, 136, 166, 172, 130, 127, 87, 170, + 128, 126, 118, 105, 112, 144, 125, 145, 113, 133, + 132, 134, 0, 0, 0, 160, 177, 194, 93, 0, + 165, 184, 185, 186, 187, 188, 189, 0, 0, 94, + 108, 104, 143, 135, 92, 114, 157, 117, 124, 149, + 192, 140, 154, 97, 176, 158, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 139, 0, 0, 0, 0, + 0, 0, 98, 82, 103, 121, 191, 148, 106, 178, + 120, 0, 122, 0, 0, 159, 131, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 268, 0, 0, 0, 0, 0, + 0, 0, 0, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 82, 0, 120, 190, 147, 105, 177, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 109, 0, + 0, 0, 210, 0, 0, 0, 0, 146, 0, 162, + 111, 119, 83, 89, 0, 110, 137, 151, 155, 0, + 0, 0, 99, 0, 153, 141, 175, 0, 142, 152, + 123, 167, 147, 174, 182, 183, 164, 181, 190, 84, + 163, 173, 96, 156, 86, 171, 161, 129, 115, 116, + 85, 0, 150, 102, 107, 101, 138, 168, 169, 100, + 193, 90, 180, 88, 91, 179, 136, 166, 172, 130, + 127, 87, 170, 128, 126, 118, 105, 112, 144, 125, + 145, 113, 133, 132, 134, 0, 0, 0, 160, 177, + 194, 93, 0, 165, 184, 185, 186, 187, 188, 189, + 0, 0, 94, 108, 104, 143, 135, 92, 114, 157, + 117, 124, 149, 192, 140, 154, 97, 176, 158, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 82, 0, 121, 191, + 148, 106, 178, } var yyPact = [...]int{ - 1854, -1000, -193, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, 894, 922, -1000, -1000, -1000, -1000, -1000, -1000, - 218, 7888, 20, 87, -31, 11175, 86, 119, 11641, -1000, - -3, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -81, -94, - -1000, 715, -1000, -1000, -1000, -1000, -1000, 867, 892, 759, - 870, 796, -1000, 6206, 58, 58, 10942, 5462, -1000, -1000, - 207, 11641, 82, 11641, -163, 55, 55, 55, -1000, -1000, + 1902, -1000, -191, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, 848, 909, -1000, -1000, -1000, -1000, -1000, -1000, + 313, 7820, 26, 119, -29, 11118, 117, 1402, 11584, -1000, + -3, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -104, -105, + -1000, 659, -1000, -1000, -1000, -1000, -1000, 833, 837, 689, + 828, 756, -1000, 6129, 77, 77, 10885, 5385, -1000, -1000, + 256, 11584, 106, 11584, -162, 68, 68, 68, -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, @@ -1946,22 +1940,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, -1000, -1000, -1000, 85, 11641, 201, -1000, 11641, 53, - 478, 53, 53, 53, 11641, -1000, 137, -1000, -1000, -1000, - 11641, 476, 819, 3374, 33, 3374, -1000, 3374, 3374, -1000, - 3374, 3, 3374, -75, 904, -1000, -1000, -1000, -1000, -50, - -1000, 3374, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, 508, 832, 6705, 6705, 894, - -1000, 715, -1000, -1000, -1000, 820, -1000, -1000, 275, 911, - -1000, 7655, 134, -1000, 6705, 1528, 708, -1000, -1000, 708, - -1000, -1000, 122, -1000, -1000, 7183, 7183, 7183, 7183, 7183, - 7183, 7183, 7183, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, -1000, 708, -1000, 6457, - 708, 708, 708, 708, 708, 708, 708, 708, 6705, 708, - 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, - 708, 708, 10709, 9537, 11641, 504, -1000, 686, 5201, -91, - -1000, -1000, -1000, 204, 9304, -1000, -1000, -1000, 818, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, 116, 11584, 189, -1000, 11584, + 66, 503, 66, 66, 66, 11584, -1000, 175, -1000, -1000, + -1000, 11584, 491, 797, 3297, 35, 3297, -1000, 3297, 3297, + -1000, 3297, 5, 3297, -77, 869, -1000, -1000, -1000, -1000, + -53, -1000, 3297, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, 405, 804, 6628, 6628, + 848, -1000, 659, -1000, -1000, -1000, 792, -1000, -1000, 314, + 877, -1000, 7587, 173, -1000, 6628, 2087, 644, -1000, -1000, + 644, -1000, -1000, 135, -1000, -1000, 7112, 7112, 7112, 7112, + 7112, 7112, 7112, 7112, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 644, -1000, + 6380, 644, 644, 644, 644, 644, 644, 644, 644, 6628, + 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, + 644, 644, 644, 10652, 9478, 11584, 591, -1000, 633, 5124, + -90, -1000, -1000, -1000, 238, 9245, -1000, -1000, -1000, 775, -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, @@ -1970,129 +1964,130 @@ 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, 598, 11641, -1000, 2036, -1000, 471, 3374, - 67, 463, 257, 460, 11641, 11641, 3374, 12, 41, 84, - 11641, 706, 65, 11641, 856, 763, 11641, 448, 444, -1000, - 4940, -1000, 3374, 3374, -1000, -1000, -1000, 3374, 3374, 3374, - 3374, 3374, 3374, -1000, -1000, -1000, -1000, 3374, 3374, -1000, - 909, 256, -1000, -1000, -1000, -1000, 6705, -1000, 762, -1000, - -1000, -1000, -1000, -1000, -1000, 917, 177, 430, 133, 695, - -1000, 371, 867, 508, 796, 9065, 773, -1000, -1000, 11641, - -1000, 6705, 6705, 339, -1000, 10469, -1000, -1000, 3896, 168, - 7183, 351, 285, 7183, 7183, 7183, 7183, 7183, 7183, 7183, - 7183, 7183, 7183, 7183, 7183, 7183, 7183, 7183, 396, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, -1000, 442, -1000, 715, - 525, 525, 148, 148, 148, 148, 148, 148, 148, 7422, - 5710, 508, 550, 281, 6457, 6206, 6206, 6705, 6705, 10236, - 10003, 6206, 860, 227, 281, 11874, -1000, 508, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, 6206, 6206, 6206, 6206, 24, - 11641, -1000, 615, 700, -1000, -1000, -1000, 858, 8599, 8832, - 24, 643, 9537, 11641, -1000, -1000, 4679, 686, -91, 678, - -1000, -130, -103, 2566, 124, -1000, -1000, -1000, -1000, 3113, - 172, 554, 316, -64, -1000, -1000, -1000, 718, -1000, 718, - 718, 718, 718, -32, -32, -32, -32, -1000, -1000, -1000, - -1000, -1000, 742, 741, -1000, 718, 718, 718, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, 739, 739, 739, 724, 724, 744, - -1000, 11641, 3374, 854, 3374, -1000, 108, -1000, 11408, 11408, - 11641, 11641, 113, 11641, 11641, 684, -1000, 11641, 3374, -1000, + -1000, -1000, -1000, -1000, 538, 11584, -1000, 2187, -1000, 488, + 3297, 91, 486, 295, 472, 11584, 11584, 3297, 23, 61, + 108, 11584, 639, 81, 11584, 821, 713, 11584, 464, 441, + -1000, 4863, -1000, 3297, 3297, -1000, -1000, -1000, 3297, 3297, + 3297, 3297, 3297, 3297, -1000, -1000, -1000, -1000, 3297, 3297, + -1000, 871, 258, -1000, -1000, -1000, -1000, 6628, -1000, 712, + -1000, -1000, -1000, -1000, -1000, -1000, 904, 190, 289, 171, + 637, -1000, 304, 833, 405, 756, 9003, 727, -1000, -1000, + 11584, -1000, 6628, 6628, 418, -1000, 10410, -1000, -1000, 3819, + 201, 7112, 338, 247, 7112, 7112, 7112, 7112, 7112, 7112, + 7112, 7112, 7112, 7112, 7112, 7112, 7112, 7112, 7112, 347, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 438, -1000, + 659, 479, 479, 182, 182, 182, 182, 182, 182, 182, + 7354, 5633, 405, 533, 221, 6380, 6129, 6129, 6628, 6628, + 10177, 9944, 6129, 830, 271, 221, 11817, -1000, 405, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, 6129, 6129, 6129, 6129, + 38, 11584, -1000, 642, 690, -1000, -1000, -1000, 824, 8537, + 8770, 38, 609, 9478, 11584, -1000, -1000, 4602, 633, -90, + 623, -1000, -133, -127, 2489, 167, -1000, -1000, -1000, -1000, + 3036, 352, 525, 285, -89, -1000, -1000, -1000, 662, -1000, + 662, 662, 662, 662, -32, -32, -32, -32, -1000, -1000, + -1000, -1000, -1000, 704, 686, -1000, 662, 662, 662, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, 11641, 288, 11641, 11641, 281, 11641, - -1000, 802, 6705, 6705, 4418, 6705, -1000, -1000, -1000, 832, - -1000, 860, 886, -1000, 812, 809, 6206, -1000, -1000, 168, - 230, -1000, -1000, 397, -1000, -1000, -1000, -1000, 132, 708, - -1000, 2052, -1000, -1000, -1000, -1000, 351, 7183, 7183, 7183, - 451, 2052, 2193, 999, 393, 148, 265, 265, 144, 144, - 144, 144, 144, 329, 329, -1000, -1000, -1000, 508, -1000, - -1000, -1000, 508, 6206, 680, -1000, -1000, 6705, -1000, 508, - 539, 539, 386, 255, 683, 682, -1000, 127, 679, 658, - 539, 6206, 242, -1000, 6705, 508, -1000, 539, 508, 539, - 539, 665, 708, -1000, 11874, 9537, 9537, 9537, 9537, 9537, - -1000, 785, 784, -1000, 777, 775, 786, 11641, -1000, 546, - 8599, 136, 708, -1000, 9770, -1000, -1000, 903, 9537, 596, - -1000, -1000, 678, -91, -95, -1000, -1000, -1000, -1000, 281, - -1000, 423, 671, 2852, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, 737, 424, -1000, 843, 166, 165, 417, 842, -1000, - -1000, -1000, 823, -1000, 262, -77, -1000, -1000, 374, -32, - -32, -1000, -1000, 124, 817, 124, 124, 124, 403, 403, - -1000, -1000, -1000, -1000, 357, -1000, -1000, -1000, 354, -1000, - 760, 11408, 3374, -1000, -1000, -1000, -1000, 250, 250, 219, + -1000, -1000, -1000, -1000, -1000, 677, 677, 677, 666, 666, + 661, -1000, 11584, 3297, 819, 3297, -1000, 93, -1000, 11351, + 11351, 11584, 11584, 130, 11584, 11584, 632, -1000, 11584, 3297, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, 22, 735, -1000, -1000, -1000, 11, 10, 64, -1000, - 3374, -1000, 256, -1000, 391, 6705, -1000, -1000, -1000, 799, - 281, 281, 126, -1000, -1000, 11641, -1000, -1000, -1000, -1000, - 623, -1000, -1000, -1000, 3635, 6206, -1000, 451, 2052, 1357, - -1000, 7183, 7183, -1000, -1000, 539, 6206, 281, -1000, -1000, - -1000, 72, 396, 72, 7183, 7183, 7183, 7183, 4418, 7183, - 7183, 7183, 7183, -173, 642, 211, -1000, 6705, 313, -1000, - -1000, -1000, -1000, -1000, 752, 11874, 708, -1000, 8360, 11408, - 651, -1000, 200, 700, 734, 750, 711, -1000, -1000, -1000, - -1000, 781, -1000, 778, -1000, -1000, -1000, -1000, -1000, 80, - 79, 78, 11408, -1000, 894, 6705, 596, -1000, -1000, -1000, - -138, -144, -1000, -1000, -1000, 3113, -1000, 3113, 11408, 40, - -1000, 417, 417, -1000, -1000, -1000, 731, 749, 71, -1000, - -1000, -1000, 540, 124, 124, -1000, 163, -1000, -1000, -1000, - 518, -1000, 515, 657, 511, 11641, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, 11584, 280, 11584, 11584, 221, + 11584, -1000, 761, 6628, 6628, 4341, 6628, -1000, -1000, -1000, + 804, -1000, 830, 845, -1000, 769, 768, 6129, -1000, -1000, + 201, 308, -1000, -1000, 374, -1000, -1000, -1000, -1000, 159, + 644, -1000, 2317, -1000, -1000, -1000, -1000, 338, 7112, 7112, + 7112, 75, 2317, 2397, 455, 331, 182, 157, 157, 184, + 184, 184, 184, 184, 829, 829, -1000, -1000, -1000, 405, + -1000, -1000, -1000, 405, 6129, 629, -1000, -1000, 6628, -1000, + 405, 519, 519, 279, 293, 660, 652, -1000, 158, 650, + 647, 519, 6129, 262, -1000, 6628, 405, -1000, 519, 405, + 519, 519, 557, 644, -1000, 11817, 9478, 9478, 9478, 9478, + 9478, -1000, 745, 737, -1000, 726, 724, 744, 11584, -1000, + 529, 8537, 152, 644, -1000, 9711, -1000, -1000, 867, 9478, + 585, -1000, -1000, 623, -90, -97, -1000, -1000, -1000, -1000, + 221, -1000, 363, 622, 2775, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, 673, 436, -1000, 811, 195, 198, 428, 810, + -1000, -1000, -1000, 800, -1000, 306, -71, -1000, -1000, 354, + -32, -32, -1000, -1000, 167, 774, 167, 167, 167, 395, + 395, -1000, -1000, -1000, -1000, 351, -1000, -1000, -1000, 348, + -1000, 711, 11351, 3297, -1000, -1000, -1000, -1000, 286, 286, + 207, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, 36, 651, -1000, -1000, -1000, 10, 9, 79, + -1000, 3297, -1000, 258, -1000, 394, 6628, -1000, -1000, -1000, + 755, 221, 221, 150, -1000, -1000, 11584, -1000, -1000, -1000, + -1000, 641, -1000, -1000, -1000, 3558, 6129, -1000, 75, 2317, + 2334, -1000, 7112, 7112, -1000, -1000, 519, 6129, 221, -1000, + -1000, -1000, 54, 347, 54, 7112, 7112, 7112, 7112, 4341, + 7112, 7112, 7112, 7112, -175, 636, 254, -1000, 6628, 275, + -1000, -1000, -1000, -1000, -1000, 710, 11817, 644, -1000, 8295, + 11351, 594, -1000, 234, 690, 701, 709, 772, -1000, -1000, + -1000, -1000, 736, -1000, 732, -1000, -1000, -1000, -1000, -1000, + 104, 103, 101, 11351, -1000, 848, 6628, 585, -1000, -1000, + -1000, -138, -136, -1000, -1000, -1000, 3036, -1000, 3036, 11351, + 50, -1000, 428, 428, -1000, -1000, -1000, 668, 708, 39, + -1000, -1000, -1000, 520, 167, 167, -1000, 197, -1000, -1000, + -1000, 512, -1000, 510, 620, 468, 11584, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, 11641, -1000, -1000, -1000, -1000, -1000, 11408, -181, - 399, 11408, 11408, 11641, -1000, 288, -1000, 281, -1000, 4157, - -1000, 903, 9537, -1000, -1000, 508, -1000, 7183, 2052, 2052, - -1000, -1000, 508, 718, 718, -1000, 718, 724, -1000, 718, - -12, 718, -13, 508, 508, 1843, 2151, 1671, 2025, -1000, - 1635, 1992, 1320, 1974, 708, -170, -1000, 281, 6705, -1000, - 845, 622, 647, -1000, -1000, 5958, 508, 506, 103, 486, - -1000, 894, 11874, 6705, -1000, -1000, 6705, 723, -1000, 6705, - -1000, -1000, -1000, 708, 708, 708, 486, 867, 281, -1000, - -1000, -1000, -1000, 2852, -1000, 484, -1000, 718, -1000, -1000, - -1000, 11408, -56, 916, -1000, -1000, -1000, -1000, 717, -1000, - -1000, -1000, -1000, -1000, -1000, -32, 383, -32, 350, -1000, - 333, 3374, -1000, -1000, -1000, -1000, 849, -1000, 4157, -1000, - -1000, 716, -1000, -1000, -1000, 900, 654, -1000, 2052, -1000, - -1000, 100, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, 7183, 7183, -1000, 7183, 7183, -1000, 7183, 7183, -1000, - 7183, 7183, 7183, 508, 379, 281, 830, -1000, 708, -1000, - -1000, 670, 11408, 11408, -1000, 11408, 867, -1000, 281, 281, - 11408, 281, 11408, 11408, 11408, 8121, -1000, 131, 11408, -1000, - 482, -1000, 185, -1000, -153, 534, 124, -1000, 124, 524, - 519, -1000, 708, 648, -1000, 199, 11408, 898, 891, -1000, - -1000, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 17, - -1000, -1000, 914, -1000, 708, -1000, 715, 83, -1000, -1000, - -1000, 467, 458, 458, 458, 136, 131, -1000, 395, 176, - 378, -1000, 37, 11408, 266, 829, -1000, 827, 714, -1000, - -1000, -1000, -1000, -1000, 21, 4157, 3113, 456, -1000, 6705, - 6705, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 508, - 34, -184, 11874, 647, 508, 11408, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, 302, -1000, -1000, 11641, -1000, -1000, 340, - -1000, -1000, 512, 452, -1000, 11408, -1000, -1000, 735, 281, - 628, -1000, 795, -179, -187, 586, -1000, -1000, -1000, 713, - -1000, -1000, -1000, 21, 808, -181, -1000, 793, -1000, 11408, - -1000, 18, -1000, -182, 428, 16, -185, 748, 708, -189, - 747, -1000, 908, 6944, -1000, -1000, 910, 152, 152, 1858, - 508, -1000, -1000, -1000, 44, 326, -1000, -1000, -1000, -1000, - -1000, -1000, + -1000, -1000, -1000, 11584, -1000, -1000, -1000, -1000, -1000, 11351, + -180, 426, 11351, 11351, 11584, -1000, 280, -1000, 221, -1000, + 4080, -1000, 867, 9478, -1000, -1000, 405, -1000, 7112, 2317, + 2317, -1000, -1000, 405, 662, 662, -1000, 662, 666, -1000, + 662, -15, 662, -16, 405, 405, 1779, 2302, 1674, 2157, + -1000, 1639, 1822, 1585, 1128, 644, -169, -1000, 221, 6628, + -1000, 814, 543, 548, -1000, -1000, 5881, 405, 463, 141, + 459, -1000, 848, 11817, 6628, -1000, -1000, 6628, 663, -1000, + 6628, -1000, -1000, -1000, 644, 644, 644, 459, 833, 221, + -1000, -1000, -1000, -1000, 2775, -1000, 457, -1000, 662, -1000, + -1000, -1000, 11351, -63, 901, -1000, -1000, -1000, -1000, 656, + -1000, -1000, -1000, -1000, -1000, -1000, -32, 392, -32, 340, + -1000, 336, 3297, -1000, -1000, -1000, -1000, 806, -1000, 4080, + -1000, -1000, 649, -1000, -1000, -1000, 865, 590, -1000, 2317, + -1000, -1000, 97, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, 7112, 7112, -1000, 7112, 7112, -1000, 7112, 7112, + -1000, 7112, 7112, 7112, 405, 386, 221, 809, -1000, 644, + -1000, -1000, 601, 11351, 11351, -1000, 11351, 833, -1000, 221, + 221, 11351, 221, 11351, 11351, 11351, 8053, -1000, 142, 11351, + -1000, 453, -1000, 170, -1000, -151, 513, 167, -1000, 167, + 460, 419, -1000, 644, 554, -1000, 226, 11351, 855, 836, + -1000, -1000, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, + 33, -1000, -1000, 888, -1000, 644, -1000, 659, 139, -1000, + -1000, -1000, 450, 447, 447, 447, 152, 142, -1000, 406, + 214, 380, -1000, 46, 11351, 317, 805, -1000, 803, 646, + -1000, -1000, -1000, -1000, -1000, 34, 4080, 3036, 422, -1000, + 6628, 6628, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + 405, 37, -183, 11817, 548, 405, 11351, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, 334, -1000, -1000, 11584, -1000, -1000, + 362, -1000, -1000, 412, 411, -1000, 11351, -1000, -1000, 651, + 221, 541, -1000, 753, -178, -187, 531, -1000, -1000, -1000, + 645, -1000, -1000, -1000, 34, 767, -180, -1000, 730, -1000, + 11351, -1000, 30, -1000, -181, 404, 27, -185, 703, 644, + -188, 692, -1000, 882, 6870, -1000, -1000, 886, 162, 162, + 1443, 405, -1000, -1000, -1000, 58, 344, -1000, -1000, -1000, + -1000, -1000, -1000, } var yyPgo = [...]int{ - 0, 1146, 33, 449, 1145, 1144, 1143, 1142, 1141, 1139, - 1138, 1136, 1135, 1130, 1126, 1125, 1123, 1116, 1110, 1109, - 1108, 1092, 1091, 1089, 1088, 1087, 99, 1086, 1085, 1081, - 71, 1078, 60, 1077, 1076, 46, 76, 50, 41, 391, - 1072, 35, 53, 59, 1071, 38, 1070, 1069, 64, 1068, - 48, 1065, 1063, 201, 1060, 1059, 10, 30, 1058, 1057, - 1054, 1052, 98, 1042, 1050, 1049, 1048, 1046, 1045, 1044, - 51, 8, 12, 47, 19, 1043, 416, 6, 1040, 52, - 1039, 1036, 1033, 1032, 16, 1030, 57, 1027, 18, 56, - 1024, 15, 65, 28, 20, 7, 69, 58, 1018, 14, - 61, 54, 1017, 1016, 411, 1014, 1012, 42, 1011, 1009, - 26, 154, 326, 1008, 1007, 1004, 1002, 37, 0, 504, - 418, 63, 1001, 999, 997, 1597, 70, 49, 17, 988, - 55, 1216, 40, 987, 985, 31, 981, 980, 979, 978, - 971, 970, 969, 84, 966, 964, 963, 24, 22, 962, - 961, 62, 23, 958, 957, 955, 44, 66, 954, 953, - 45, 29, 950, 949, 948, 947, 946, 27, 9, 943, - 13, 941, 21, 940, 25, 939, 4, 935, 11, 934, - 3, 933, 5, 43, 1, 932, 2, 931, 930, 311, - 701, 929, 928, 107, + 0, 1124, 33, 440, 1123, 1117, 1116, 1113, 1108, 1106, + 1105, 1104, 1103, 1102, 1101, 1100, 1099, 1098, 1097, 1096, + 1095, 1092, 1090, 1089, 1086, 1082, 87, 1079, 1078, 1077, + 64, 1073, 65, 1072, 1071, 46, 520, 53, 38, 1151, + 1070, 35, 66, 59, 1069, 28, 1068, 1064, 79, 1063, + 48, 1061, 1058, 201, 1055, 1053, 22, 44, 1051, 1050, + 1049, 1048, 90, 1042, 1047, 1046, 1044, 1041, 1040, 1039, + 52, 8, 12, 47, 13, 1037, 50, 6, 1034, 49, + 1033, 1031, 1028, 1025, 16, 1022, 55, 1020, 18, 56, + 1019, 15, 58, 31, 19, 7, 69, 60, 1018, 17, + 61, 54, 1017, 1016, 391, 1015, 1013, 41, 1012, 1010, + 24, 152, 372, 1009, 1008, 1007, 1006, 29, 0, 504, + 327, 63, 1005, 1003, 998, 1519, 70, 45, 20, 997, + 73, 277, 40, 989, 988, 37, 986, 982, 981, 980, + 979, 972, 970, 272, 966, 964, 963, 30, 21, 962, + 961, 62, 23, 960, 959, 958, 43, 57, 957, 956, + 51, 26, 955, 954, 950, 949, 947, 27, 9, 944, + 14, 943, 10, 941, 25, 940, 4, 939, 11, 938, + 3, 934, 5, 42, 1, 925, 2, 923, 918, 311, + 701, 917, 916, 71, } var yyR1 = [...]int{ @@ -2180,8 +2175,8 @@ var yyR1 = [...]int{ 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, - 118, 118, 118, 118, 118, 118, 189, 190, 130, 131, - 131, 131, + 118, 118, 118, 118, 118, 118, 118, 189, 190, 130, + 131, 131, 131, } var yyR2 = [...]int{ @@ -2269,8 +2264,8 @@ 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, 1, 0, 0, - 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, + 0, 1, 1, } var yyChk = [...]int{ @@ -2283,140 +2278,140 @@ var yyChk = [...]int{ 5, -26, -192, -26, -26, -26, -26, -26, -163, -165, 54, 90, -116, 125, 72, 243, 122, 123, 129, -119, 57, -118, 259, 135, 162, 173, 167, 194, 186, 136, - 184, 187, 230, 214, 225, 66, 165, 239, 145, 182, - 178, 176, 27, 227, 199, 264, 177, 226, 121, 138, - 133, 200, 204, 231, 171, 172, 233, 198, 134, 33, - 261, 35, 153, 234, 202, 197, 193, 196, 170, 192, - 39, 206, 205, 207, 229, 189, 139, 179, 18, 237, - 148, 151, 228, 201, 203, 130, 155, 263, 235, 175, - 140, 152, 147, 238, 141, 166, 232, 241, 38, 211, - 169, 132, 163, 159, 216, 190, 154, 180, 181, 195, - 168, 191, 164, 156, 149, 240, 212, 265, 188, 185, - 160, 157, 158, 217, 218, 219, 220, 221, 222, 161, - 262, 236, 183, 213, -104, 125, 220, 127, 123, 123, - 124, 125, 243, 122, 123, -53, -125, 57, -118, 125, - 123, 108, 187, 230, 115, 215, 227, 124, 33, 228, - 155, -134, 123, -106, 214, 217, 218, 219, 222, 220, - 161, 57, 232, 231, 223, -125, 164, -130, -130, -130, - -130, -130, 216, 216, -130, -2, -88, 17, 16, -5, - -3, -189, 6, 20, 21, -32, 40, 41, -27, -38, - 99, -39, -125, -58, 74, -63, 29, 57, -118, 23, - -62, -59, -77, -75, -76, 108, 109, 110, 97, 98, - 105, 75, 111, -67, -65, -66, -68, 59, 58, 67, - 60, 61, 62, 63, 68, 69, 70, -119, -73, -189, - 44, 45, 252, 253, 254, 255, 258, 256, 77, 34, - 242, 250, 249, 248, 246, 247, 244, 245, 128, 243, - 103, 251, -104, -104, 11, -48, -53, -96, -133, 164, - -100, 232, 231, -120, -98, -119, -117, 230, 187, 229, - 120, 73, 22, 24, 209, 76, 108, 16, 77, 107, - 252, 115, 48, 244, 245, 242, 254, 255, 243, 215, - 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, 246, 247, 31, 258, 150, 103, 49, 36, - 74, 68, 71, 52, 72, 15, 47, 91, 118, 251, - 45, 122, 6, 257, 30, 142, 43, 123, 79, 126, - 69, 5, 129, 32, 9, 50, 53, 248, 249, 250, - 34, 78, 12, -164, 90, -157, 57, -53, 124, -53, - 251, -112, 128, -112, -112, 123, -53, 115, 117, 120, - 52, -18, -53, -111, 128, 57, -111, -111, -111, -53, - 112, -53, 57, 30, -131, -189, -120, 243, 57, 155, - 123, 156, 125, -131, -131, -131, -131, 159, 160, -131, - -109, -108, 225, 226, 216, 224, 12, 216, 158, -131, - -130, -130, -190, 56, -89, 19, 31, -39, -125, -85, - -86, -39, -84, -2, -26, 36, -30, 21, 65, 11, - -122, 73, 72, 89, -121, 22, -119, 59, 112, -39, - -60, 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, -105, -189, -76, -189, - 113, 114, -63, -63, -63, -63, -63, -63, -63, -63, - -189, -2, -71, -39, -189, -189, -189, -189, -189, -189, - -189, -189, -189, -80, -39, -189, -193, -189, -193, -193, - -193, -193, -193, -193, -193, -189, -189, -189, -189, -54, - 26, -53, -41, -42, -43, -44, -55, -76, -189, -53, - -53, -48, -191, 55, 11, 53, 55, -96, 164, -97, - -101, 233, 235, 82, -124, -119, 59, 29, 30, 56, - 55, -53, -136, -139, -141, -140, -142, -137, -138, 184, - 185, 108, 188, 190, 191, 192, 193, 194, 195, 196, - 197, 198, 199, 30, 145, 180, 181, 182, 183, 200, - 201, 202, 203, 204, 205, 206, 207, 167, 168, 169, - 170, 171, 172, 173, 175, 176, 177, 178, 179, 57, - -131, 125, 57, 74, 57, -53, -53, -131, 157, 157, - 123, 123, -53, 55, 126, -48, 23, 52, -53, 57, - 57, -126, -125, -117, -131, -131, -131, -131, -131, -131, - -131, -131, -131, -131, 11, -107, 11, 92, -39, 52, - 9, 92, 55, 18, 112, 55, -87, 24, 25, -88, - -190, -32, -64, -119, 60, 63, -31, 43, -53, -39, - -39, -69, 68, 74, 69, 70, -121, 99, -126, -120, - -117, -63, -70, -73, -76, 64, 92, 90, 91, 76, - -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, - -63, -63, -63, -63, -63, -132, 57, 59, 57, -62, - -62, -119, -37, 21, -36, -38, -190, 55, -190, -2, - -36, -36, -39, -39, -77, 59, -119, -125, -77, 59, - -36, -30, -78, -79, 78, -77, -190, -36, -37, -36, - -36, -92, 151, -53, 30, 55, -49, -51, -50, -52, - 42, 46, 48, 43, 44, 45, 49, -129, 22, -41, - -189, -128, 151, -127, 22, -125, 59, -92, 53, -41, - -53, -100, -97, 55, 234, 236, 237, 52, 71, -39, - -148, 107, -166, -167, -168, -120, 59, 60, -157, -158, - -159, -169, 137, -174, 130, 132, 129, -160, 138, 124, - 28, 56, -153, 68, 74, -149, 212, -143, 54, -143, - -143, -143, -143, -147, 187, -147, -147, -147, 54, 54, - -143, -143, -143, -151, 54, -151, -151, -152, 54, -152, - -123, 53, -53, -131, 23, -131, -113, 120, 117, 118, - -177, 116, 209, 187, 66, 29, 15, 252, 151, 265, - 57, 152, -119, -119, -53, -53, 120, 117, -53, -53, - -53, -131, -53, -110, 90, 12, -125, -125, -53, 38, - -39, -39, -126, -86, -89, -103, 19, 11, 34, 34, - -36, 68, 69, 70, 112, -189, -70, -63, -63, -63, - -35, 146, 73, -190, -190, -36, 55, -39, -190, -190, - -190, 55, 53, 22, 55, 11, 55, 11, 112, 55, - 11, 55, 11, -190, -36, -81, -79, 80, -39, -190, - -190, -190, -190, -190, -61, 30, 34, -2, -189, -189, - -95, -99, -77, -42, -43, -43, -42, -43, 42, 42, - 42, 47, 42, 47, 42, -50, -125, -190, -56, 50, - 127, 51, -189, -127, -57, 12, -41, -57, -101, -102, - 238, 235, 241, 57, 59, 55, -168, 82, 54, 57, - 28, -160, -160, -161, 57, -161, 28, -144, 29, 68, - -150, 213, 60, -147, -147, -148, 30, -148, -148, -148, - -156, 59, -156, 60, 60, 52, -119, -131, -130, -183, - 131, 137, 138, 133, 57, 124, 28, 130, 132, 151, - 129, -183, -114, -115, 126, 22, 124, 28, 151, -182, - 53, 157, 157, 126, -131, -107, 59, -39, 39, 112, - -53, -40, 11, 99, -120, -37, -35, 73, -63, -63, - -190, -38, -135, 108, 184, 145, 182, 178, 198, 189, - 211, 180, 212, -132, -135, -63, -63, -63, -63, -120, - -63, -63, -63, -63, 259, -84, 81, -39, 79, -94, - 52, -95, -72, -74, -73, -189, -2, -90, -119, -93, - -119, -57, 55, 82, -46, -45, 52, 53, -47, 52, - -45, 42, 42, 124, 124, 124, -93, -84, -39, -57, - 235, 239, 240, -167, -168, -171, -170, -119, -174, -161, - -161, 54, -146, 52, 59, 60, 61, 68, 242, 67, - 56, -148, -148, 57, 108, 56, 55, 56, 55, 56, - 55, -53, -130, -130, -53, -130, -119, -180, 262, -181, - 57, -119, -119, -53, -110, -57, -41, -190, -63, -190, - -143, -143, -143, -152, -143, 172, -143, 172, -190, -190, - -190, 55, 19, -190, 55, 19, -190, 55, 19, -190, - 55, 19, -189, -34, 257, -39, 27, -94, 55, -190, - -190, -190, 55, 112, -190, 55, -84, -99, -39, -39, - 54, -39, -189, -189, -189, -190, -88, 56, 55, -143, - -91, -119, -154, 209, 9, 54, -147, 59, -147, 60, - 60, -131, 26, -179, -178, -120, 54, -82, 13, -147, - 57, -63, -63, -63, -63, -63, -63, -63, -63, -63, - -190, 59, 28, -74, 34, -2, -189, -119, -119, -119, - -88, -91, -91, -91, -91, -128, -173, -172, 53, 134, - 66, -170, 56, 55, -155, 130, 28, 129, 242, 56, - -148, -148, 56, 56, -189, 55, 82, -91, -83, 14, - 16, -190, -190, -190, -190, -190, -190, -190, -190, -33, - 92, 262, 9, -72, -2, 112, 56, -190, -190, -190, - -56, -172, 57, -162, 82, 59, 140, -119, -145, 66, - 28, 28, 54, -175, -176, 151, -178, -168, 56, -39, - -71, -190, 260, 49, 263, -95, -190, -119, 60, -53, - 59, 56, -190, 55, -119, -182, 39, 261, 264, 54, - -176, 34, -180, 39, -91, 153, 262, 56, 154, 263, - -185, -186, 52, -189, 264, -186, 52, 10, 9, -63, - 150, -184, 141, 136, 139, 30, -184, -190, -190, 135, - 29, 68, + 184, 187, 230, 214, 225, 66, 165, 239, 25, 145, + 182, 178, 176, 27, 227, 199, 264, 177, 226, 121, + 138, 133, 200, 204, 231, 171, 172, 233, 198, 134, + 33, 261, 35, 153, 234, 202, 197, 193, 196, 170, + 192, 39, 206, 205, 207, 229, 189, 139, 179, 18, + 237, 148, 151, 228, 201, 203, 130, 155, 263, 235, + 175, 140, 152, 147, 238, 141, 166, 232, 241, 38, + 211, 169, 132, 163, 159, 216, 190, 154, 180, 181, + 195, 168, 191, 164, 156, 149, 240, 212, 265, 188, + 185, 160, 157, 158, 217, 218, 219, 220, 221, 222, + 161, 262, 236, 183, 213, -104, 125, 220, 127, 123, + 123, 124, 125, 243, 122, 123, -53, -125, 57, -118, + 125, 123, 108, 187, 230, 115, 215, 227, 124, 33, + 228, 155, -134, 123, -106, 214, 217, 218, 219, 222, + 220, 161, 57, 232, 231, 223, -125, 164, -130, -130, + -130, -130, -130, 216, 216, -130, -2, -88, 17, 16, + -5, -3, -189, 6, 20, 21, -32, 40, 41, -27, + -38, 99, -39, -125, -58, 74, -63, 29, 57, -118, + 23, -62, -59, -77, -75, -76, 108, 109, 110, 97, + 98, 105, 75, 111, -67, -65, -66, -68, 59, 58, + 67, 60, 61, 62, 63, 68, 69, 70, -119, -73, + -189, 44, 45, 252, 253, 254, 255, 258, 256, 77, + 34, 242, 250, 249, 248, 246, 247, 244, 245, 128, + 243, 103, 251, -104, -104, 11, -48, -53, -96, -133, + 164, -100, 232, 231, -120, -98, -119, -117, 230, 187, + 229, 120, 73, 22, 24, 209, 76, 108, 16, 77, + 107, 252, 115, 48, 244, 245, 242, 254, 255, 243, + 215, 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, 246, 247, 31, 258, 150, 103, 49, + 36, 74, 68, 71, 52, 72, 15, 47, 91, 118, + 251, 45, 122, 6, 257, 30, 142, 43, 123, 79, + 126, 69, 5, 129, 32, 9, 50, 53, 248, 249, + 250, 34, 78, 12, -164, 90, -157, 57, -53, 124, + -53, 251, -112, 128, -112, -112, 123, -53, 115, 117, + 120, 52, -18, -53, -111, 128, 57, -111, -111, -111, + -53, 112, -53, 57, 30, -131, -189, -120, 243, 57, + 155, 123, 156, 125, -131, -131, -131, -131, 159, 160, + -131, -109, -108, 225, 226, 216, 224, 12, 216, 158, + -131, -130, -130, -190, 56, -89, 19, 31, -39, -125, + -85, -86, -39, -84, -2, -26, 36, -30, 21, 65, + 11, -122, 73, 72, 89, -121, 22, -119, 59, 112, + -39, -60, 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, -105, -189, -76, + -189, 113, 114, -63, -63, -63, -63, -63, -63, -63, + -63, -189, -2, -71, -39, -189, -189, -189, -189, -189, + -189, -189, -189, -189, -80, -39, -189, -193, -189, -193, + -193, -193, -193, -193, -193, -193, -189, -189, -189, -189, + -54, 26, -53, -41, -42, -43, -44, -55, -76, -189, + -53, -53, -48, -191, 55, 11, 53, 55, -96, 164, + -97, -101, 233, 235, 82, -124, -119, 59, 29, 30, + 56, 55, -53, -136, -139, -141, -140, -142, -137, -138, + 184, 185, 108, 188, 190, 191, 192, 193, 194, 195, + 196, 197, 198, 199, 30, 145, 180, 181, 182, 183, + 200, 201, 202, 203, 204, 205, 206, 207, 167, 168, + 169, 170, 171, 172, 173, 175, 176, 177, 178, 179, + 57, -131, 125, 57, 74, 57, -53, -53, -131, 157, + 157, 123, 123, -53, 55, 126, -48, 23, 52, -53, + 57, 57, -126, -125, -117, -131, -131, -131, -131, -131, + -131, -131, -131, -131, -131, 11, -107, 11, 92, -39, + 52, 9, 92, 55, 18, 112, 55, -87, 24, 25, + -88, -190, -32, -64, -119, 60, 63, -31, 43, -53, + -39, -39, -69, 68, 74, 69, 70, -121, 99, -126, + -120, -117, -63, -70, -73, -76, 64, 92, 90, 91, + 76, -63, -63, -63, -63, -63, -63, -63, -63, -63, + -63, -63, -63, -63, -63, -63, -132, 57, 59, 57, + -62, -62, -119, -37, 21, -36, -38, -190, 55, -190, + -2, -36, -36, -39, -39, -77, 59, -119, -125, -77, + 59, -36, -30, -78, -79, 78, -77, -190, -36, -37, + -36, -36, -92, 151, -53, 30, 55, -49, -51, -50, + -52, 42, 46, 48, 43, 44, 45, 49, -129, 22, + -41, -189, -128, 151, -127, 22, -125, 59, -92, 53, + -41, -53, -100, -97, 55, 234, 236, 237, 52, 71, + -39, -148, 107, -166, -167, -168, -120, 59, 60, -157, + -158, -159, -169, 137, -174, 130, 132, 129, -160, 138, + 124, 28, 56, -153, 68, 74, -149, 212, -143, 54, + -143, -143, -143, -143, -147, 187, -147, -147, -147, 54, + 54, -143, -143, -143, -151, 54, -151, -151, -152, 54, + -152, -123, 53, -53, -131, 23, -131, -113, 120, 117, + 118, -177, 116, 209, 187, 66, 29, 15, 252, 151, + 265, 57, 152, -119, -119, -53, -53, 120, 117, -53, + -53, -53, -131, -53, -110, 90, 12, -125, -125, -53, + 38, -39, -39, -126, -86, -89, -103, 19, 11, 34, + 34, -36, 68, 69, 70, 112, -189, -70, -63, -63, + -63, -35, 146, 73, -190, -190, -36, 55, -39, -190, + -190, -190, 55, 53, 22, 55, 11, 55, 11, 112, + 55, 11, 55, 11, -190, -36, -81, -79, 80, -39, + -190, -190, -190, -190, -190, -61, 30, 34, -2, -189, + -189, -95, -99, -77, -42, -43, -43, -42, -43, 42, + 42, 42, 47, 42, 47, 42, -50, -125, -190, -56, + 50, 127, 51, -189, -127, -57, 12, -41, -57, -101, + -102, 238, 235, 241, 57, 59, 55, -168, 82, 54, + 57, 28, -160, -160, -161, 57, -161, 28, -144, 29, + 68, -150, 213, 60, -147, -147, -148, 30, -148, -148, + -148, -156, 59, -156, 60, 60, 52, -119, -131, -130, + -183, 131, 137, 138, 133, 57, 124, 28, 130, 132, + 151, 129, -183, -114, -115, 126, 22, 124, 28, 151, + -182, 53, 157, 157, 126, -131, -107, 59, -39, 39, + 112, -53, -40, 11, 99, -120, -37, -35, 73, -63, + -63, -190, -38, -135, 108, 184, 145, 182, 178, 198, + 189, 211, 180, 212, -132, -135, -63, -63, -63, -63, + -120, -63, -63, -63, -63, 259, -84, 81, -39, 79, + -94, 52, -95, -72, -74, -73, -189, -2, -90, -119, + -93, -119, -57, 55, 82, -46, -45, 52, 53, -47, + 52, -45, 42, 42, 124, 124, 124, -93, -84, -39, + -57, 235, 239, 240, -167, -168, -171, -170, -119, -174, + -161, -161, 54, -146, 52, 59, 60, 61, 68, 242, + 67, 56, -148, -148, 57, 108, 56, 55, 56, 55, + 56, 55, -53, -130, -130, -53, -130, -119, -180, 262, + -181, 57, -119, -119, -53, -110, -57, -41, -190, -63, + -190, -143, -143, -143, -152, -143, 172, -143, 172, -190, + -190, -190, 55, 19, -190, 55, 19, -190, 55, 19, + -190, 55, 19, -189, -34, 257, -39, 27, -94, 55, + -190, -190, -190, 55, 112, -190, 55, -84, -99, -39, + -39, 54, -39, -189, -189, -189, -190, -88, 56, 55, + -143, -91, -119, -154, 209, 9, 54, -147, 59, -147, + 60, 60, -131, 26, -179, -178, -120, 54, -82, 13, + -147, 57, -63, -63, -63, -63, -63, -63, -63, -63, + -63, -190, 59, 28, -74, 34, -2, -189, -119, -119, + -119, -88, -91, -91, -91, -91, -128, -173, -172, 53, + 134, 66, -170, 56, 55, -155, 130, 28, 129, 242, + 56, -148, -148, 56, 56, -189, 55, 82, -91, -83, + 14, 16, -190, -190, -190, -190, -190, -190, -190, -190, + -33, 92, 262, 9, -72, -2, 112, 56, -190, -190, + -190, -56, -172, 57, -162, 82, 59, 140, -119, -145, + 66, 28, 28, 54, -175, -176, 151, -178, -168, 56, + -39, -71, -190, 260, 49, 263, -95, -190, -119, 60, + -53, 59, 56, -190, 55, -119, -182, 39, 261, 264, + 54, -176, 34, -180, 39, -91, 153, 262, 56, 154, + 263, -185, -186, 52, -189, 264, -186, 52, 10, 9, + -63, 150, -184, 141, 136, 139, 30, -184, -190, -190, + 135, 29, 68, } var yyDef = [...]int{ @@ -2424,10 +2419,10 @@ var yyDef = [...]int{ 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 556, 0, 317, 317, 317, 317, 317, 317, 0, 627, 610, 0, 0, 0, 0, -2, 304, 305, - 0, 307, 308, 848, 848, 848, 848, 848, 0, 0, - 848, 0, 35, 36, 846, 1, 3, 564, 0, 0, + 0, 307, 308, 849, 849, 849, 849, 849, 0, 0, + 849, 0, 35, 36, 847, 1, 3, 564, 0, 0, 321, 324, 319, 0, 610, 610, 0, 0, 62, 63, - 0, 0, 0, 832, 0, 608, 608, 608, 628, 629, + 0, 0, 0, 833, 0, 608, 608, 608, 628, 629, 632, 633, 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, @@ -2438,131 +2433,131 @@ var yyDef = [...]int{ 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, 833, 834, 835, 836, 837, 838, 839, 840, 841, - 842, 843, 844, 845, 0, 0, 0, 611, 0, 606, - 0, 606, 606, 606, 0, 255, 389, 636, 637, 832, - 0, 0, 0, 849, 0, 849, 267, 849, 849, 270, - 849, 0, 849, 0, 277, 279, 280, 281, 282, 0, - 286, 849, 301, 302, 291, 303, 306, 309, 310, 311, - 312, 313, 848, 848, 316, 29, 568, 0, 0, 556, - 31, 0, 317, 322, 323, 327, 325, 326, 318, 0, - 335, 339, 0, 397, 0, 402, 404, -2, -2, 0, - 439, 440, 441, 442, 443, 0, 0, 0, 0, 0, - 0, 0, 0, 467, 468, 469, 470, 541, 542, 543, - 544, 545, 546, 547, 548, 406, 407, 538, 588, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 529, 0, - 503, 503, 503, 503, 503, 503, 503, 503, 0, 0, - 0, 0, 0, 0, 0, 0, 43, 47, 0, 823, - 592, -2, -2, 0, 0, 634, 635, -2, 742, -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, 0, 0, 81, 0, 79, 0, 849, - 0, 0, 0, 0, 0, 0, 849, 0, 0, 0, - 0, 246, 0, 0, 0, 0, 0, 0, 0, 254, - 0, 256, 849, 849, 259, 850, 851, 849, 849, 849, - 849, 849, 849, 266, 268, 269, 271, 849, 849, 273, - 0, 294, 292, 293, 288, 289, 0, 283, 284, 287, - 314, 315, 30, 847, 24, 0, 0, 565, 0, 557, - 558, 561, 564, 29, 324, 0, 329, 328, 320, 0, - 336, 0, 0, 0, 340, 0, 342, 343, 0, 400, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 424, - 425, 426, 427, 428, 429, 430, 403, 0, 417, 0, - 0, 0, 459, 460, 461, 462, 463, 464, 465, 0, - 331, 29, 0, 437, 0, 0, 0, 0, 0, 0, - 0, 0, 327, 0, 530, 0, 495, 0, 496, 497, - 498, 499, 500, 501, 502, 0, 331, 0, 0, 45, - 0, 388, 0, 346, 348, 349, 350, -2, 0, 372, - -2, 0, 0, 0, 41, 42, 0, 48, 823, 50, - 51, 0, 0, 0, 164, 601, 602, 603, 599, 208, - 0, 0, 145, 141, 87, 88, 89, 134, 91, 134, - 134, 134, 134, 161, 161, 161, 161, 117, 118, 119, - 120, 121, 0, 0, 104, 134, 134, 134, 108, 124, - 125, 126, 127, 128, 129, 130, 131, 92, 93, 94, - 95, 96, 97, 98, 136, 136, 136, 138, 138, 630, - 65, 0, 849, 0, 849, 77, 0, 222, 0, 0, - 0, 0, 0, 0, 0, 249, 607, 0, 849, 252, - 253, 390, 638, 639, 257, 258, 260, 261, 262, 263, - 264, 265, 272, 276, 0, 297, 0, 0, 278, 0, - 569, 0, 0, 0, 0, 0, 560, 562, 563, 568, - 32, 327, 0, 549, 0, 0, 0, 330, 27, 398, - 399, 401, 418, 0, 420, 422, 341, 337, 0, 539, - -2, 408, 409, 433, 434, 435, 0, 0, 0, 0, - 431, 413, 0, 444, 445, 446, 447, 448, 449, 450, - 451, 452, 453, 454, 455, 458, 514, 515, 0, 456, - 457, 466, 0, 0, 332, 333, 436, 0, 587, 29, - 0, 0, 0, 0, 0, 0, 538, 0, 0, 0, - 0, 0, 536, 533, 0, 0, 504, 0, 0, 0, - 0, 0, 0, 387, 0, 0, 0, 0, 0, 0, - 377, 0, 0, 380, 0, 0, 0, 0, 371, 0, - 0, 391, 792, 373, 0, 375, 376, 395, 0, 395, - 44, 593, 49, 0, 0, 54, 55, 594, 595, 596, - 597, 0, 78, 209, 211, 214, 215, 216, 82, 83, - 84, 0, 0, 196, 0, 0, 190, 190, 0, 188, - 189, 80, 148, 146, 0, 143, 142, 90, 0, 161, - 161, 111, 112, 164, 0, 164, 164, 164, 0, 0, - 105, 106, 107, 99, 0, 100, 101, 102, 0, 103, - 0, 0, 849, 67, 609, 68, 848, 0, 0, 622, - 223, 612, 613, 614, 615, 616, 617, 618, 619, 620, - 621, 0, 69, 225, 227, 226, 0, 0, 0, 247, - 849, 251, 294, 275, 0, 0, 295, 296, 285, 0, - 566, 567, 0, 559, 25, 0, 604, 605, 550, 551, - 344, 419, 421, 423, 0, 331, 410, 431, 414, 0, - 411, 0, 0, 405, 471, 0, 0, 438, -2, 474, - 475, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 556, 0, 534, 0, 0, 494, - 505, 506, 507, 508, 581, 0, 0, -2, 0, 0, - 395, 589, 0, 347, 366, 368, 0, 363, 378, 379, - 381, 0, 383, 0, 385, 386, 351, 353, 354, 0, - 0, 0, 0, 374, 556, 0, 395, 40, 52, 53, - 0, 0, 59, 165, 166, 0, 212, 0, 0, 0, - 183, 190, 190, 186, 191, 187, 0, 156, 0, 147, - 86, 144, 0, 164, 164, 113, 0, 114, 115, 116, - 0, 132, 0, 0, 0, 0, 631, 66, 217, 848, - 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, - 240, 848, 0, 848, 623, 624, 625, 626, 0, 72, - 0, 0, 0, 0, 250, 297, 298, 299, 570, 0, - 26, 395, 0, 338, 540, 0, 412, 0, 432, 415, - 472, 334, 0, 134, 134, 519, 134, 138, 522, 134, - 524, 134, 527, 0, 0, 0, 0, 0, 0, 539, - 0, 0, 0, 0, 0, 531, 493, 537, 0, 33, - 0, 581, 571, 583, 585, 0, 29, 0, 577, 0, - 358, 556, 0, 0, 360, 367, 0, 0, 361, 0, - 362, 382, 384, 0, 0, 0, 0, 564, 396, 39, - 56, 57, 58, 210, 213, 0, 192, 134, 195, 184, - 185, 0, 159, 0, 149, 150, 151, 152, 153, 155, - 135, 109, 110, 162, 163, 161, 0, 161, 0, 139, - 0, 849, 218, 219, 220, 221, 0, 224, 0, 70, - 71, 0, 229, 248, 274, 552, 345, 473, 416, 476, - 516, 161, 520, 521, 523, 525, 526, 528, 478, 477, - 479, 0, 0, 485, 0, 0, 482, 0, 0, 488, - 0, 0, 0, 0, 0, 535, 0, 34, 0, 586, - -2, 0, 0, 0, 46, 0, 564, 590, 591, 364, - 0, 369, 0, 0, 0, 372, 38, 175, 0, 194, - 0, 356, 167, 160, 0, 0, 164, 133, 164, 0, - 0, 64, 0, 73, 74, 0, 0, 554, 0, 517, - 518, 0, 0, 0, 0, 0, 0, 0, 0, 509, - 492, 532, 0, 584, 0, -2, 0, 579, 578, 359, - 37, 0, 0, 0, 0, 391, 174, 176, 0, 181, - 0, 193, 0, 0, 172, 0, 169, 171, 157, 154, - 122, 123, 137, 140, 0, 0, 0, 0, 28, 0, - 0, 480, 481, 486, 487, 483, 484, 489, 490, 0, - 0, 0, 0, 574, 29, 0, 365, 392, 393, 394, - 355, 177, 178, 0, 182, 180, 0, 357, 85, 0, - 168, 170, 0, 0, 242, 0, 75, 76, 69, 555, - 553, 491, 0, 0, 0, 582, -2, 580, 179, 0, - 173, 158, 241, 0, 0, 72, 510, 0, 513, 0, - 243, 0, 228, 511, 0, 0, 0, 197, 0, 0, - 198, 199, 0, 0, 512, 200, 0, 0, 0, 0, - 0, 201, 203, 204, 0, 0, 202, 244, 245, 205, - 206, 207, + 831, 832, 834, 835, 836, 837, 838, 839, 840, 841, + 842, 843, 844, 845, 846, 0, 0, 0, 611, 0, + 606, 0, 606, 606, 606, 0, 255, 389, 636, 637, + 833, 0, 0, 0, 850, 0, 850, 267, 850, 850, + 270, 850, 0, 850, 0, 277, 279, 280, 281, 282, + 0, 286, 850, 301, 302, 291, 303, 306, 309, 310, + 311, 312, 313, 849, 849, 316, 29, 568, 0, 0, + 556, 31, 0, 317, 322, 323, 327, 325, 326, 318, + 0, 335, 339, 0, 397, 0, 402, 404, -2, -2, + 0, 439, 440, 441, 442, 443, 0, 0, 0, 0, + 0, 0, 0, 0, 467, 468, 469, 470, 541, 542, + 543, 544, 545, 546, 547, 548, 406, 407, 538, 588, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 529, + 0, 503, 503, 503, 503, 503, 503, 503, 503, 0, + 0, 0, 0, 0, 0, 0, 0, 43, 47, 0, + 824, 592, -2, -2, 0, 0, 634, 635, -2, 742, + -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, 0, 0, 81, 0, 79, 0, + 850, 0, 0, 0, 0, 0, 0, 850, 0, 0, + 0, 0, 246, 0, 0, 0, 0, 0, 0, 0, + 254, 0, 256, 850, 850, 259, 851, 852, 850, 850, + 850, 850, 850, 850, 266, 268, 269, 271, 850, 850, + 273, 0, 294, 292, 293, 288, 289, 0, 283, 284, + 287, 314, 315, 30, 848, 24, 0, 0, 565, 0, + 557, 558, 561, 564, 29, 324, 0, 329, 328, 320, + 0, 336, 0, 0, 0, 340, 0, 342, 343, 0, + 400, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 424, 425, 426, 427, 428, 429, 430, 403, 0, 417, + 0, 0, 0, 459, 460, 461, 462, 463, 464, 465, + 0, 331, 29, 0, 437, 0, 0, 0, 0, 0, + 0, 0, 0, 327, 0, 530, 0, 495, 0, 496, + 497, 498, 499, 500, 501, 502, 0, 331, 0, 0, + 45, 0, 388, 0, 346, 348, 349, 350, -2, 0, + 372, -2, 0, 0, 0, 41, 42, 0, 48, 824, + 50, 51, 0, 0, 0, 164, 601, 602, 603, 599, + 208, 0, 0, 145, 141, 87, 88, 89, 134, 91, + 134, 134, 134, 134, 161, 161, 161, 161, 117, 118, + 119, 120, 121, 0, 0, 104, 134, 134, 134, 108, + 124, 125, 126, 127, 128, 129, 130, 131, 92, 93, + 94, 95, 96, 97, 98, 136, 136, 136, 138, 138, + 630, 65, 0, 850, 0, 850, 77, 0, 222, 0, + 0, 0, 0, 0, 0, 0, 249, 607, 0, 850, + 252, 253, 390, 638, 639, 257, 258, 260, 261, 262, + 263, 264, 265, 272, 276, 0, 297, 0, 0, 278, + 0, 569, 0, 0, 0, 0, 0, 560, 562, 563, + 568, 32, 327, 0, 549, 0, 0, 0, 330, 27, + 398, 399, 401, 418, 0, 420, 422, 341, 337, 0, + 539, -2, 408, 409, 433, 434, 435, 0, 0, 0, + 0, 431, 413, 0, 444, 445, 446, 447, 448, 449, + 450, 451, 452, 453, 454, 455, 458, 514, 515, 0, + 456, 457, 466, 0, 0, 332, 333, 436, 0, 587, + 29, 0, 0, 0, 0, 0, 0, 538, 0, 0, + 0, 0, 0, 536, 533, 0, 0, 504, 0, 0, + 0, 0, 0, 0, 387, 0, 0, 0, 0, 0, + 0, 377, 0, 0, 380, 0, 0, 0, 0, 371, + 0, 0, 391, 793, 373, 0, 375, 376, 395, 0, + 395, 44, 593, 49, 0, 0, 54, 55, 594, 595, + 596, 597, 0, 78, 209, 211, 214, 215, 216, 82, + 83, 84, 0, 0, 196, 0, 0, 190, 190, 0, + 188, 189, 80, 148, 146, 0, 143, 142, 90, 0, + 161, 161, 111, 112, 164, 0, 164, 164, 164, 0, + 0, 105, 106, 107, 99, 0, 100, 101, 102, 0, + 103, 0, 0, 850, 67, 609, 68, 849, 0, 0, + 622, 223, 612, 613, 614, 615, 616, 617, 618, 619, + 620, 621, 0, 69, 225, 227, 226, 0, 0, 0, + 247, 850, 251, 294, 275, 0, 0, 295, 296, 285, + 0, 566, 567, 0, 559, 25, 0, 604, 605, 550, + 551, 344, 419, 421, 423, 0, 331, 410, 431, 414, + 0, 411, 0, 0, 405, 471, 0, 0, 438, -2, + 474, 475, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 556, 0, 534, 0, 0, + 494, 505, 506, 507, 508, 581, 0, 0, -2, 0, + 0, 395, 589, 0, 347, 366, 368, 0, 363, 378, + 379, 381, 0, 383, 0, 385, 386, 351, 353, 354, + 0, 0, 0, 0, 374, 556, 0, 395, 40, 52, + 53, 0, 0, 59, 165, 166, 0, 212, 0, 0, + 0, 183, 190, 190, 186, 191, 187, 0, 156, 0, + 147, 86, 144, 0, 164, 164, 113, 0, 114, 115, + 116, 0, 132, 0, 0, 0, 0, 631, 66, 217, + 849, 230, 231, 232, 233, 234, 235, 236, 237, 238, + 239, 240, 849, 0, 849, 623, 624, 625, 626, 0, + 72, 0, 0, 0, 0, 250, 297, 298, 299, 570, + 0, 26, 395, 0, 338, 540, 0, 412, 0, 432, + 415, 472, 334, 0, 134, 134, 519, 134, 138, 522, + 134, 524, 134, 527, 0, 0, 0, 0, 0, 0, + 539, 0, 0, 0, 0, 0, 531, 493, 537, 0, + 33, 0, 581, 571, 583, 585, 0, 29, 0, 577, + 0, 358, 556, 0, 0, 360, 367, 0, 0, 361, + 0, 362, 382, 384, 0, 0, 0, 0, 564, 396, + 39, 56, 57, 58, 210, 213, 0, 192, 134, 195, + 184, 185, 0, 159, 0, 149, 150, 151, 152, 153, + 155, 135, 109, 110, 162, 163, 161, 0, 161, 0, + 139, 0, 850, 218, 219, 220, 221, 0, 224, 0, + 70, 71, 0, 229, 248, 274, 552, 345, 473, 416, + 476, 516, 161, 520, 521, 523, 525, 526, 528, 478, + 477, 479, 0, 0, 485, 0, 0, 482, 0, 0, + 488, 0, 0, 0, 0, 0, 535, 0, 34, 0, + 586, -2, 0, 0, 0, 46, 0, 564, 590, 591, + 364, 0, 369, 0, 0, 0, 372, 38, 175, 0, + 194, 0, 356, 167, 160, 0, 0, 164, 133, 164, + 0, 0, 64, 0, 73, 74, 0, 0, 554, 0, + 517, 518, 0, 0, 0, 0, 0, 0, 0, 0, + 509, 492, 532, 0, 584, 0, -2, 0, 579, 578, + 359, 37, 0, 0, 0, 0, 391, 174, 176, 0, + 181, 0, 193, 0, 0, 172, 0, 169, 171, 157, + 154, 122, 123, 137, 140, 0, 0, 0, 0, 28, + 0, 0, 480, 481, 486, 487, 483, 484, 489, 490, + 0, 0, 0, 0, 574, 29, 0, 365, 392, 393, + 394, 355, 177, 178, 0, 182, 180, 0, 357, 85, + 0, 168, 170, 0, 0, 242, 0, 75, 76, 69, + 555, 553, 491, 0, 0, 0, 582, -2, 580, 179, + 0, 173, 158, 241, 0, 0, 72, 510, 0, 513, + 0, 243, 0, 228, 511, 0, 0, 0, 197, 0, + 0, 198, 199, 0, 0, 512, 200, 0, 0, 0, + 0, 0, 201, 203, 204, 0, 0, 202, 244, 245, + 205, 206, 207, } var yyTok1 = [...]int{ @@ -6628,42 +6623,42 @@ yydefault: { yyVAL.tableIdent = NewTableIdent(string(yyDollar[1].bytes)) } - case 846: + case 847: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3379 +//line sql.y:3380 { if incNesting(yylex) { yylex.Error("max nesting level reached") return 1 } } - case 847: + case 848: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3388 +//line sql.y:3389 { decNesting(yylex) } - case 848: + case 849: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:3393 +//line sql.y:3394 { skipToEnd(yylex) } - case 849: + case 850: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:3398 +//line sql.y:3399 { skipToEnd(yylex) } - case 850: + case 851: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3402 +//line sql.y:3403 { skipToEnd(yylex) } - case 851: + case 852: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3406 +//line sql.y:3407 { skipToEnd(yylex) } diff --git a/go/vt/sqlparser/sql.y b/go/vt/sqlparser/sql.y index 07dc55ca4c7..c534e84617e 100644 --- a/go/vt/sqlparser/sql.y +++ b/go/vt/sqlparser/sql.y @@ -3276,6 +3276,7 @@ non_reserved_keyword: | COMMENT_KEYWORD | COMMIT | COMMITTED +| DESC | DATE | DATETIME | DECIMAL From eae8f86290a85ffc332dc813b9e912b91c1258c9 Mon Sep 17 00:00:00 2001 From: Alex Charis Date: Thu, 10 Jan 2019 14:18:46 -0500 Subject: [PATCH 044/115] reload db-credentials-file upon SIGHUP Signed-off-by: Alex Charis --- go/vt/dbconfigs/credentials.go | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/go/vt/dbconfigs/credentials.go b/go/vt/dbconfigs/credentials.go index ab73e9d5695..0ee4f911864 100644 --- a/go/vt/dbconfigs/credentials.go +++ b/go/vt/dbconfigs/credentials.go @@ -26,7 +26,10 @@ import ( "errors" "flag" "io/ioutil" + "os" + "os/signal" "sync" + "syscall" "vitess.io/vitess/go/mysql" "vitess.io/vitess/go/vt/log" @@ -126,4 +129,16 @@ func WithCredentials(cp *mysql.ConnParams) (*mysql.ConnParams, error) { func init() { AllCredentialsServers["file"] = &FileCredentialsServer{} + + sigChan := make(chan os.Signal, 1) + signal.Notify(sigChan, syscall.SIGHUP) + go func() { + for { + <-sigChan + fcs, ok := AllCredentialsServers["file"].(*FileCredentialsServer) + if ok { + fcs.dbCredentials = nil + } + } + }() } From 8bb118247790bb0b9052e336d5d6ab7913314001 Mon Sep 17 00:00:00 2001 From: Michael Pawliszyn Date: Thu, 10 Jan 2019 15:27:27 -0500 Subject: [PATCH 045/115] Makes sure the schema engine has started up before getting debug information. Signed-off-by: Michael Pawliszyn --- go/vt/vttablet/tabletserver/schema/engine.go | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/go/vt/vttablet/tabletserver/schema/engine.go b/go/vt/vttablet/tabletserver/schema/engine.go index e0f59421bde..630d117d940 100644 --- a/go/vt/vttablet/tabletserver/schema/engine.go +++ b/go/vt/vttablet/tabletserver/schema/engine.go @@ -85,6 +85,14 @@ func NewEngine(checker connpool.MySQLChecker, config tabletenv.TabletConfig) *En http.Handle("/debug/schema", se) http.HandleFunc("/schemaz", func(w http.ResponseWriter, r *http.Request) { + // Ensure schema engine is Open. If vttablet came up in a non_serving role, + // the schema engine may not have been initialized. + err := se.Open() + if err != nil { + w.Write([]byte(err.Error())) + return + } + schemazHandler(se.GetSchema(), w, r) }) }) @@ -483,6 +491,14 @@ func (se *Engine) ServeHTTP(response http.ResponseWriter, request *http.Request) } func (se *Engine) handleHTTPSchema(response http.ResponseWriter, request *http.Request) { + // Ensure schema engine is Open. If vttablet came up in a non_serving role, + // the schema engine may not have been initialized. + err := se.Open() + if err != nil { + response.Write([]byte(err.Error())) + return + } + response.Header().Set("Content-Type", "application/json; charset=utf-8") b, err := json.MarshalIndent(se.GetSchema(), "", " ") if err != nil { From c171538d12f5c70872418ffde03d0f8fa474dc07 Mon Sep 17 00:00:00 2001 From: Michael Hebelka Date: Thu, 10 Jan 2019 18:58:58 -0500 Subject: [PATCH 046/115] Skip ACL checks for dual pseudotable Signed-off-by: Michael Hebelka --- go/vt/vttablet/tabletserver/query_executor.go | 5 ++ .../tabletserver/query_executor_test.go | 61 +++++++++++++++++++ 2 files changed, 66 insertions(+) diff --git a/go/vt/vttablet/tabletserver/query_executor.go b/go/vt/vttablet/tabletserver/query_executor.go index 847b8923e28..bf4e103aec5 100644 --- a/go/vt/vttablet/tabletserver/query_executor.go +++ b/go/vt/vttablet/tabletserver/query_executor.go @@ -326,6 +326,11 @@ func (qre *QueryExecutor) checkPermissions() error { return vterrors.Errorf(vtrpcpb.Code_FAILED_PRECONDITION, "disallowed due to rule: %s", desc) } + // Skip ACL check for queries against the dummy dual table + if qre.plan.TableName().String() == "dual" { + return nil + } + // Skip the ACL check if the connecting user is an exempted superuser. // Necessary to whitelist e.g. direct vtworker access. if qre.tsv.qe.exemptACL != nil && qre.tsv.qe.exemptACL.IsMember(&querypb.VTGateCallerID{Username: username}) { diff --git a/go/vt/vttablet/tabletserver/query_executor_test.go b/go/vt/vttablet/tabletserver/query_executor_test.go index 84d0d02f455..84ff6fd6016 100644 --- a/go/vt/vttablet/tabletserver/query_executor_test.go +++ b/go/vt/vttablet/tabletserver/query_executor_test.go @@ -1706,6 +1706,53 @@ func TestQueryExecutorTableAclNoPermission(t *testing.T) { } } +func TestQueryExecutorTableAclDualTableExempt(t *testing.T) { + aclName := fmt.Sprintf("simpleacl-test-%d", rand.Int63()) + tableacl.Register(aclName, &simpleacl.Factory{}) + tableacl.SetDefaultACL(aclName) + db := setUpQueryExecutorTest(t) + defer db.Close() + + username := "Sleve McDichael" + callerID := &querypb.VTGateCallerID{ + Username: username, + } + ctx := callerid.NewContext(context.Background(), nil, callerID) + + config := &tableaclpb.Config{ + TableGroups: []*tableaclpb.TableGroupSpec{}, + } + + if err := tableacl.InitFromProto(config); err != nil { + t.Fatalf("unable to load tableacl config, error: %v", err) + } + + // enable Config.StrictTableAcl + tsv := newTestTabletServer(ctx, enableStrictTableACL, db) + query := "select * from test_table where 1 != 1" + qre := newTestQueryExecutor(ctx, tsv, query, 0) + defer tsv.StopService() + checkPlanID(t, planbuilder.PlanPassSelect, qre.plan.PlanID) + // query should fail because nobody has read access to test_table + _, err := qre.Execute() + if code := vterrors.Code(err); code != vtrpcpb.Code_PERMISSION_DENIED { + t.Fatalf("qre.Execute: %v, want %v", code, vtrpcpb.Code_PERMISSION_DENIED) + } + wanterr := "table acl error" + if !strings.Contains(err.Error(), wanterr) { + t.Fatalf("qre.Execute: %v, want %s", err, wanterr) + } + + // table acl should be ignored when querying against dual table + query = "select @@version_comment from dual limit 1" + ctx = callerid.NewContext(context.Background(), nil, callerID) + qre = newTestQueryExecutor(ctx, tsv, query, 0) + _, err = qre.Execute() + if err != nil { + t.Fatalf("qre.Execute: %v, want: nil", err) + } +} + func TestQueryExecutorTableAclExemptACL(t *testing.T) { aclName := fmt.Sprintf("simpleacl-test-%d", rand.Int63()) tableacl.Register(aclName, &simpleacl.Factory{}) @@ -2112,6 +2159,20 @@ func getQueryExecutorSupportedQueries(testTableHasMultipleUniqueKeys bool) map[s {sqltypes.NewVarBinary("0")}, }, }, + "select @@version_comment from dual where 1 != 1": { + Fields: []*querypb.Field{{ + Type: sqltypes.VarChar, + }}, + }, + "select @@version_comment from dual limit 1": { + Fields: []*querypb.Field{{ + Type: sqltypes.VarChar, + }}, + RowsAffected: 1, + Rows: [][]sqltypes.Value{ + {sqltypes.NewVarBinary("fakedb server")}, + }, + }, "show variables like 'binlog_format'": { Fields: []*querypb.Field{{ Type: sqltypes.VarChar, From 599854e23f830c14dcc40767d502c099ab009478 Mon Sep 17 00:00:00 2001 From: Alex Charis Date: Fri, 11 Jan 2019 09:18:51 -0500 Subject: [PATCH 047/115] test the signal handler Signed-off-by: Alex Charis --- go/vt/dbconfigs/credentials.go | 4 ++- go/vt/dbconfigs/dbconfigs_test.go | 49 +++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+), 1 deletion(-) diff --git a/go/vt/dbconfigs/credentials.go b/go/vt/dbconfigs/credentials.go index 0ee4f911864..71213f40908 100644 --- a/go/vt/dbconfigs/credentials.go +++ b/go/vt/dbconfigs/credentials.go @@ -40,7 +40,7 @@ var ( dbCredentialsServer = flag.String("db-credentials-server", "file", "db credentials server type (use 'file' for the file implementation)") // 'file' implementation flags - dbCredentialsFile = flag.String("db-credentials-file", "", "db credentials file") + dbCredentialsFile = flag.String("db-credentials-file", "", "db credentials file; send SIGHUP to reload this file") // ErrUnknownUser is returned by credential server when the // user doesn't exist @@ -137,7 +137,9 @@ func init() { <-sigChan fcs, ok := AllCredentialsServers["file"].(*FileCredentialsServer) if ok { + fcs.mu.Lock() fcs.dbCredentials = nil + fcs.mu.Unlock() } } }() diff --git a/go/vt/dbconfigs/dbconfigs_test.go b/go/vt/dbconfigs/dbconfigs_test.go index 0f6e87fd4c5..86fbd757581 100644 --- a/go/vt/dbconfigs/dbconfigs_test.go +++ b/go/vt/dbconfigs/dbconfigs_test.go @@ -17,8 +17,13 @@ limitations under the License. package dbconfigs import ( + "fmt" + "io/ioutil" + "os" "reflect" + "syscall" "testing" + "time" "vitess.io/vitess/go/mysql" ) @@ -217,3 +222,47 @@ func TestCopy(t *testing.T) { t.Errorf("DBConfig: %v, want %v", got, want) } } + +func TestCredentialsFileHUP(t *testing.T) { + tmpFile, err := ioutil.TempFile("", "credentials.json") + if err != nil { + t.Fatalf("couldn't create temp file: %v", err) + } + defer os.Remove(tmpFile.Name()) + *dbCredentialsFile = tmpFile.Name() + *dbCredentialsServer = "file" + oldStr := "str1" + jsonConfig := fmt.Sprintf("{\"%s\": [\"%s\"]}", oldStr, oldStr) + if err := ioutil.WriteFile(tmpFile.Name(), []byte(jsonConfig), 0600); err != nil { + t.Fatalf("couldn't write temp file: %v", err) + } + cs := GetCredentialsServer() + _, pass, err := cs.GetUserAndPassword(oldStr) + if pass != oldStr { + t.Fatalf("%s's Password should still be '%s'", oldStr, oldStr) + } + hupTest(t, tmpFile, oldStr, "str2") + hupTest(t, tmpFile, "str2", "str3") // still handling the signal +} + +func hupTest(t *testing.T, tmpFile *os.File, oldStr, newStr string) { + cs := GetCredentialsServer() + jsonConfig := fmt.Sprintf("{\"%s\": [\"%s\"]}", newStr, newStr) + if err := ioutil.WriteFile(tmpFile.Name(), []byte(jsonConfig), 0600); err != nil { + t.Fatalf("couldn't overwrite temp file: %v", err) + } + _, pass, err := cs.GetUserAndPassword(oldStr) + if pass != oldStr { + t.Fatalf("%s's Password should still be '%s'", oldStr, oldStr) + } + syscall.Kill(syscall.Getpid(), syscall.SIGHUP) + time.Sleep(100 * time.Millisecond) // wait for signal handler + _, pass, err = cs.GetUserAndPassword(oldStr) + if err != ErrUnknownUser { + t.Fatalf("Should not have old %s after config reload", oldStr) + } + _, pass, err = cs.GetUserAndPassword(newStr) + if pass != newStr { + t.Fatalf("%s's Password should be '%s'", newStr, newStr) + } +} From bf5e4b17ef972e10101f292343509360be17e57b Mon Sep 17 00:00:00 2001 From: Alain Jobart Date: Fri, 11 Jan 2019 16:07:44 -0800 Subject: [PATCH 048/115] tlstest_test: Go 1.12 / TLS 1.3 fix TLS 1.3 pushes detection of some client-side handshake errors to the time of the first read. For more details, see: https://github.com/golang/go/issues/28779#issuecomment-442694636 Signed-off-by: Alain Jobart --- go/vt/tlstest/tlstest_test.go | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/go/vt/tlstest/tlstest_test.go b/go/vt/tlstest/tlstest_test.go index 686a2dcbd7d..a88ab1c5857 100644 --- a/go/vt/tlstest/tlstest_test.go +++ b/go/vt/tlstest/tlstest_test.go @@ -140,11 +140,21 @@ func TestClientServer(t *testing.T) { serverConn.Close() }() - if _, err = tls.Dial("tcp", addr, badClientConfig); err == nil { - t.Fatalf("Dial was expected to fail") + // When using TLS 1.2, the Dial will fail. + // With TLS 1.3, the Dial will succeed and the first Read will fail. + clientConn, err := tls.Dial("tcp", addr, badClientConfig) + if err != nil { + if !strings.Contains(err.Error(), "bad certificate") { + t.Errorf("Wrong error returned: %v", err) + } + return + } + data := make([]byte, 1) + _, err = clientConn.Read(data) + if err == nil { + t.Fatalf("Dial or first Read was expected to fail") } if !strings.Contains(err.Error(), "bad certificate") { t.Errorf("Wrong error returned: %v", err) } - t.Logf("Dial returned: %v", err) } From 0e37f1f019e1a7238218f907ed6097e4d7bd50d9 Mon Sep 17 00:00:00 2001 From: Sugu Sougoumarane Date: Sat, 12 Jan 2019 11:40:37 -0800 Subject: [PATCH 049/115] vreplication: address review comments Signed-off-by: Sugu Sougoumarane --- go/vt/sqlparser/analyzer.go | 2 +- go/vt/vttablet/tabletserver/tabletserver.go | 2 +- go/vt/vttablet/tabletserver/vstreamer/engine.go | 2 ++ go/vt/vttablet/tabletserver/vstreamer/planbuilder.go | 6 ++++++ 4 files changed, 10 insertions(+), 2 deletions(-) diff --git a/go/vt/sqlparser/analyzer.go b/go/vt/sqlparser/analyzer.go index 9c0f4a13e81..418a63ab01b 100644 --- a/go/vt/sqlparser/analyzer.go +++ b/go/vt/sqlparser/analyzer.go @@ -31,7 +31,7 @@ import ( ) // These constants are used to identify the SQL statement type. -// Chaging this list will require reviewing all calls to Preview. +// Changing this list will require reviewing all calls to Preview. const ( StmtSelect = iota StmtStream diff --git a/go/vt/vttablet/tabletserver/tabletserver.go b/go/vt/vttablet/tabletserver/tabletserver.go index e6eb5dd1eda..cbb3358d7b5 100644 --- a/go/vt/vttablet/tabletserver/tabletserver.go +++ b/go/vt/vttablet/tabletserver/tabletserver.go @@ -1276,7 +1276,7 @@ func (tsv *TabletServer) execDML(ctx context.Context, target *querypb.Target, qu // VStream streams VReplication events. func (tsv *TabletServer) VStream(ctx context.Context, target *querypb.Target, startPos mysql.Position, filter *binlogdatapb.Filter, send func([]*binlogdatapb.VEvent) error) error { - // This code is partially duplicated from execRequest. This is because + // This code is partially duplicated from startRequest. This is because // is allowed even if the tablet is in non-serving state. err := func() error { tsv.mu.Lock() diff --git a/go/vt/vttablet/tabletserver/vstreamer/engine.go b/go/vt/vttablet/tabletserver/vstreamer/engine.go index 7370314a2fa..61cb603976c 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/engine.go +++ b/go/vt/vttablet/tabletserver/vstreamer/engine.go @@ -138,6 +138,8 @@ func (vse *Engine) vschema() *vindexes.KeyspaceSchema { // Stream starts a new stream. func (vse *Engine) Stream(ctx context.Context, startPos mysql.Position, filter *binlogdatapb.Filter, send func([]*binlogdatapb.VEvent) error) error { // Ensure kschema is initialized and the watcher is started. + // Starting of the watcher has to be delayed till the first call to Stream + // because this overhead should be incurred only if someone uses this feature. vse.watcherOnce.Do(vse.setWatch) // Create stream and add it to the map. diff --git a/go/vt/vttablet/tabletserver/vstreamer/planbuilder.go b/go/vt/vttablet/tabletserver/vstreamer/planbuilder.go index be6ea986a43..d3709ca7361 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/planbuilder.go +++ b/go/vt/vttablet/tabletserver/vstreamer/planbuilder.go @@ -69,6 +69,12 @@ type Table struct { Columns []schema.TableColumn } +// The filter function needs the ability to perform expression evaluations. This is +// because the consumer of vstream is not just VPlayer. It can also be a dumb client +// like a mysql client that's subscribing to changes. This ability to allow users +// to directly pull events by sending a complex select query. The same reasoning +// applies to where clauses. For now, only simple functions like hour are supported, +// but this can be expanded in the future. func (plan *Plan) filter(values []sqltypes.Value) (bool, []sqltypes.Value, error) { result := make([]sqltypes.Value, len(plan.ColExprs)) for i, colExpr := range plan.ColExprs { From f9f74b3ff2e3ed194a31f3c195efe4f80bc49c68 Mon Sep 17 00:00:00 2001 From: Derek Perkins Date: Sat, 12 Jan 2019 12:53:01 -0700 Subject: [PATCH 050/115] helm: release 1.0.5 Signed-off-by: Derek Perkins --- helm/release.sh | 2 +- helm/vitess/CHANGELOG.md | 8 ++++++++ helm/vitess/Chart.yaml | 2 +- helm/vitess/templates/_orchestrator.tpl | 4 ++-- helm/vitess/templates/_pmm.tpl | 2 +- helm/vitess/templates/_vttablet.tpl | 8 ++++---- helm/vitess/values.yaml | 10 +++++----- 7 files changed, 22 insertions(+), 14 deletions(-) diff --git a/helm/release.sh b/helm/release.sh index a9f1a17d646..890a1d76182 100755 --- a/helm/release.sh +++ b/helm/release.sh @@ -1,6 +1,6 @@ #!/bin/bash -version_tag=1.0.4 +version_tag=1.0.5 docker pull vitess/k8s:latest docker tag vitess/k8s:latest vitess/k8s:helm-$version_tag diff --git a/helm/vitess/CHANGELOG.md b/helm/vitess/CHANGELOG.md index aca78299575..2e30bf4fea2 100644 --- a/helm/vitess/CHANGELOG.md +++ b/helm/vitess/CHANGELOG.md @@ -1,3 +1,11 @@ +## 1.0.5 - 2019-01-12 + +### Changes +* Set FailMasterPromotionIfSQLThreadNotUpToDate = true in Orchestrator config, to prevent +lagging replicas from being promoted to master and causing errant GTID problems. + +**NOTE:** You need to manually restart your Orchestrator pods for this change to take effect + ## 1.0.4 - 2019-01-01 ### Changes diff --git a/helm/vitess/Chart.yaml b/helm/vitess/Chart.yaml index 021aa8a39bd..b10a00bb2b4 100644 --- a/helm/vitess/Chart.yaml +++ b/helm/vitess/Chart.yaml @@ -1,6 +1,6 @@ apiVersion: v1 name: vitess -version: 1.0.4 +version: 1.0.5 description: Single-Chart Vitess Cluster keywords: - vitess diff --git a/helm/vitess/templates/_orchestrator.tpl b/helm/vitess/templates/_orchestrator.tpl index 99f88de1e21..9f061154454 100644 --- a/helm/vitess/templates/_orchestrator.tpl +++ b/helm/vitess/templates/_orchestrator.tpl @@ -123,7 +123,7 @@ spec: value: "15999" - name: recovery-log - image: vitess/logtail:helm-1.0.4 + image: vitess/logtail:helm-1.0.5 imagePullPolicy: IfNotPresent env: - name: TAIL_FILEPATH @@ -133,7 +133,7 @@ spec: mountPath: /tmp - name: audit-log - image: vitess/logtail:helm-1.0.4 + image: vitess/logtail:helm-1.0.5 imagePullPolicy: IfNotPresent env: - name: TAIL_FILEPATH diff --git a/helm/vitess/templates/_pmm.tpl b/helm/vitess/templates/_pmm.tpl index 32e8d70fce8..afc9a57e31d 100644 --- a/helm/vitess/templates/_pmm.tpl +++ b/helm/vitess/templates/_pmm.tpl @@ -218,7 +218,7 @@ spec: trap : TERM INT; sleep infinity & wait - name: pmm-client-metrics-log - image: vitess/logtail:helm-1.0.4 + image: vitess/logtail:helm-1.0.5 imagePullPolicy: IfNotPresent env: - name: TAIL_FILEPATH diff --git a/helm/vitess/templates/_vttablet.tpl b/helm/vitess/templates/_vttablet.tpl index 636393efa34..7523b796b49 100644 --- a/helm/vitess/templates/_vttablet.tpl +++ b/helm/vitess/templates/_vttablet.tpl @@ -533,7 +533,7 @@ spec: {{ define "cont-logrotate" }} - name: logrotate - image: vitess/logrotate:helm-1.0.4 + image: vitess/logrotate:helm-1.0.5 imagePullPolicy: IfNotPresent volumeMounts: - name: vtdataroot @@ -547,7 +547,7 @@ spec: {{ define "cont-mysql-errorlog" }} - name: error-log - image: vitess/logtail:helm-1.0.4 + image: vitess/logtail:helm-1.0.5 imagePullPolicy: IfNotPresent env: @@ -565,7 +565,7 @@ spec: {{ define "cont-mysql-slowlog" }} - name: slow-log - image: vitess/logtail:helm-1.0.4 + image: vitess/logtail:helm-1.0.5 imagePullPolicy: IfNotPresent env: @@ -583,7 +583,7 @@ spec: {{ define "cont-mysql-generallog" }} - name: general-log - image: vitess/logtail:helm-1.0.4 + image: vitess/logtail:helm-1.0.5 imagePullPolicy: IfNotPresent env: diff --git a/helm/vitess/values.yaml b/helm/vitess/values.yaml index 9d9c9a371c9..3b85d6c2d54 100644 --- a/helm/vitess/values.yaml +++ b/helm/vitess/values.yaml @@ -177,7 +177,7 @@ etcd: # Default values for vtctld resources defined in 'topology' vtctld: serviceType: ClusterIP - vitessTag: helm-1.0.4 + vitessTag: helm-1.0.5 resources: # requests: # cpu: 100m @@ -188,7 +188,7 @@ vtctld: # Default values for vtgate resources defined in 'topology' vtgate: serviceType: ClusterIP - vitessTag: helm-1.0.4 + vitessTag: helm-1.0.5 resources: # requests: # cpu: 500m @@ -207,13 +207,13 @@ vtgate: # Default values for vtctlclient resources defined in 'topology' vtctlclient: - vitessTag: helm-1.0.4 + vitessTag: helm-1.0.5 extraFlags: {} secrets: [] # secrets are mounted under /vt/usersecrets/{secretname} # Default values for vtworker resources defined in 'jobs' vtworker: - vitessTag: helm-1.0.4 + vitessTag: helm-1.0.5 extraFlags: {} resources: # requests: @@ -224,7 +224,7 @@ vtworker: # Default values for vttablet resources defined in 'topology' vttablet: - vitessTag: helm-1.0.4 + vitessTag: helm-1.0.5 # valid values are # - mysql56 (for MySQL 8.0) From 0b0b841b53d81e19cb9efe20c4b18dfb9946a8ae Mon Sep 17 00:00:00 2001 From: Alex Charis Date: Mon, 14 Jan 2019 17:15:10 -0500 Subject: [PATCH 051/115] inline ok check; while-range instead of bare while Signed-off-by: Alex Charis --- go/mysql/auth_server_static.go | 3 +-- go/vt/dbconfigs/credentials.go | 6 ++---- go/vt/vttablet/tabletserver/tabletserver.go | 3 +-- 3 files changed, 4 insertions(+), 8 deletions(-) diff --git a/go/mysql/auth_server_static.go b/go/mysql/auth_server_static.go index c6e3004544c..290de7a2b87 100644 --- a/go/mysql/auth_server_static.go +++ b/go/mysql/auth_server_static.go @@ -148,8 +148,7 @@ func (a *AuthServerStatic) installSignalHandlers() { sigChan := make(chan os.Signal, 1) signal.Notify(sigChan, syscall.SIGHUP) go func() { - for { - <-sigChan + for range sigChan { a.loadConfigFromParams(*mysqlAuthServerStaticFile, "") } }() diff --git a/go/vt/dbconfigs/credentials.go b/go/vt/dbconfigs/credentials.go index 71213f40908..3062e7a2151 100644 --- a/go/vt/dbconfigs/credentials.go +++ b/go/vt/dbconfigs/credentials.go @@ -133,10 +133,8 @@ func init() { sigChan := make(chan os.Signal, 1) signal.Notify(sigChan, syscall.SIGHUP) go func() { - for { - <-sigChan - fcs, ok := AllCredentialsServers["file"].(*FileCredentialsServer) - if ok { + for range sigChan { + if fcs, ok := AllCredentialsServers["file"].(*FileCredentialsServer); ok { fcs.mu.Lock() fcs.dbCredentials = nil fcs.mu.Unlock() diff --git a/go/vt/vttablet/tabletserver/tabletserver.go b/go/vt/vttablet/tabletserver/tabletserver.go index e698969816e..3f25c1bdeea 100644 --- a/go/vt/vttablet/tabletserver/tabletserver.go +++ b/go/vt/vttablet/tabletserver/tabletserver.go @@ -374,8 +374,7 @@ func (tsv *TabletServer) InitACL(tableACLConfigFile string, enforceTableACLConfi sigChan := make(chan os.Signal, 1) signal.Notify(sigChan, syscall.SIGHUP) go func() { - for { - <-sigChan + for range sigChan { tsv.initACL(tableACLConfigFile, enforceTableACLConfig) } }() From ddae5bbfaad810be16004eea995d9b71be1850f6 Mon Sep 17 00:00:00 2001 From: Adam Saponara Date: Mon, 14 Jan 2019 18:10:22 -0500 Subject: [PATCH 052/115] Expose `glog.MaxSize` as `-log_rotate_max_size` flag Signed-off-by: Adam Saponara --- go/vt/log/log.go | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/go/vt/log/log.go b/go/vt/log/log.go index 4f06ec38cc6..d2d0adf1dfe 100644 --- a/go/vt/log/log.go +++ b/go/vt/log/log.go @@ -5,7 +5,10 @@ package log -import "github.com/golang/glog" +import ( + "flag" + "github.com/golang/glog" +) // Level is used with V() to test log verbosity. type Level = glog.Level @@ -52,3 +55,7 @@ var ( // FatalDepth formats arguments like fmt.Print and uses depth to choose which call frame to log. FatalDepth = glog.FatalDepth ) + +func init() { + flag.Uint64Var(&glog.MaxSize, "log_rotate_max_size", glog.MaxSize, "size in bytes at which logs are rotated (glog.MaxSize)") +} From 47fcfa6a5bce5d589e5b51f37a76765eb7918fdb Mon Sep 17 00:00:00 2001 From: Derek Perkins Date: Mon, 14 Jan 2019 21:30:02 -0700 Subject: [PATCH 053/115] vtctl: run BackupShard on replica, rdonly or spare Signed-off-by: Derek Perkins --- go/vt/vtctl/backup.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/go/vt/vtctl/backup.go b/go/vt/vtctl/backup.go index 0309f41b8e8..487bc909183 100644 --- a/go/vt/vtctl/backup.go +++ b/go/vt/vtctl/backup.go @@ -103,8 +103,10 @@ func commandBackupShard(ctx context.Context, wr *wrangler.Wrangler, subFlags *fl var secondsBehind uint32 for i := range tablets { - // don't run a backup on a non-slave type - if !tablets[i].IsSlaveType() { + // only run a backup on a replica, rdonly or spare tablet type + switch tablets[i].Type { + case topodatapb.TabletType_REPLICA, topodatapb.TabletType_RDONLY, topodatapb.TabletType_SPARE: + default: continue } From 87a9adf8ef0ab50fabdfb0e690c7286b62febd64 Mon Sep 17 00:00:00 2001 From: Aaron Young Date: Mon, 14 Jan 2019 17:24:18 -0500 Subject: [PATCH 054/115] Use a truly random Destination for DestinationAnyShard Signed-off-by: Aaron Young --- go/vt/key/destination.go | 23 +- go/vt/vtgate/engine/insert.go | 31 +++ go/vt/vtgate/engine/insert_test.go | 324 ++++++++++++------------ go/vt/vtgate/engine/route.go | 18 ++ go/vt/vtgate/engine/route_test.go | 320 +++++++++++------------ go/vt/vtgate/executor_framework_test.go | 7 + go/vt/vtgate/planbuilder/from.go | 25 +- go/vt/vtgate/planbuilder/insert.go | 20 +- 8 files changed, 416 insertions(+), 352 deletions(-) diff --git a/go/vt/key/destination.go b/go/vt/key/destination.go index 2f3e32c88c5..ca7867fa501 100644 --- a/go/vt/key/destination.go +++ b/go/vt/key/destination.go @@ -19,6 +19,7 @@ package key import ( "bytes" "encoding/hex" + "math/rand" "strings" "vitess.io/vitess/go/vt/vterrors" @@ -27,6 +28,9 @@ import ( vtrpcpb "vitess.io/vitess/go/vt/proto/vtrpc" ) +// AnyShardPicker makes a choice on what shard to use when any shard will do. Used for testing. +var AnyShardPicker DestinationAnyShardPicker = DestinationAnyShardPickerRandomShard{} + // Destination is an interface definition for a query destination, // within a given Keyspace / Tablet Type. It is meant to be an internal // data structure, with multiple possible implementations. @@ -369,12 +373,25 @@ func (d DestinationKeyspaceIDs) String() string { return buffer.String() } +// DestinationAnyShardPicker exposes an interface that will pick an index given a number of available shards. +type DestinationAnyShardPicker interface { + // PickShard picks a shard given a number of shards + PickShard(shardCount int) int +} + +// DestinationAnyShardPickerRandomShard picks a random shard. +type DestinationAnyShardPickerRandomShard struct{} + +// PickShard is DestinationAnyShardPickerRandomShard's implmentation. +func (dp DestinationAnyShardPickerRandomShard) PickShard(shardCount int) int { + return rand.Intn(shardCount) +} + // // DestinationAnyShard // -// DestinationAnyShard is the destination for any one shard in the -// keyspace. This usually maps to the first one in the list. +// DestinationAnyShard is the destination for any one shard in the keyspace. // It implements the Destination interface. type DestinationAnyShard struct{} @@ -388,7 +405,7 @@ func (d DestinationAnyShard) Resolve(allShards []*topodatapb.ShardReference, add if len(allShards) == 0 { return vterrors.Errorf(vtrpcpb.Code_UNAVAILABLE, "no shard in keyspace") } - return addShard(allShards[0].Name) + return addShard(allShards[AnyShardPicker.PickShard(len(allShards))].Name) } // String is part of the Destination interface. diff --git a/go/vt/vtgate/engine/insert.go b/go/vt/vtgate/engine/insert.go index 72d5e20da56..a1ead406736 100644 --- a/go/vt/vtgate/engine/insert.go +++ b/go/vt/vtgate/engine/insert.go @@ -78,6 +78,37 @@ type Insert struct { MultiShardAutocommit bool } +// NewQueryInsert creates an Insert with a query string. +func NewQueryInsert(opcode InsertOpcode, keyspace *vindexes.Keyspace, query string) *Insert { + return &Insert{ + Opcode: opcode, + Keyspace: keyspace, + Query: query, + } +} + +// NewSimpleInsert creates an Insert for a Table. +func NewSimpleInsert(opcode InsertOpcode, table *vindexes.Table, keyspace *vindexes.Keyspace) *Insert { + return &Insert{ + Opcode: opcode, + Table: table, + Keyspace: keyspace, + } +} + +// NewInsert creates a new Insert. +func NewInsert(opcode InsertOpcode, keyspace *vindexes.Keyspace, vindexValues []sqltypes.PlanValue, table *vindexes.Table, prefix string, mid []string, suffix string) *Insert { + return &Insert{ + Opcode: opcode, + Keyspace: keyspace, + VindexValues: vindexValues, + Table: table, + Prefix: prefix, + Mid: mid, + Suffix: suffix, + } +} + // MarshalJSON serializes the Insert into a JSON representation. // It's used for testing and diagnostics. func (ins *Insert) MarshalJSON() ([]byte, error) { diff --git a/go/vt/vtgate/engine/insert_test.go b/go/vt/vtgate/engine/insert_test.go index 5353588c73d..70722ad2c18 100644 --- a/go/vt/vtgate/engine/insert_test.go +++ b/go/vt/vtgate/engine/insert_test.go @@ -28,14 +28,14 @@ import ( ) func TestInsertUnsharded(t *testing.T) { - ins := &Insert{ - Opcode: InsertUnsharded, - Keyspace: &vindexes.Keyspace{ + ins := NewQueryInsert( + InsertUnsharded, + &vindexes.Keyspace{ Name: "ks", Sharded: false, }, - Query: "dummy_insert", - } + "dummy_insert", + ) vc := &loggingVCursor{ shards: []string{"0"}, @@ -64,27 +64,27 @@ func TestInsertUnsharded(t *testing.T) { } func TestInsertUnshardedGenerate(t *testing.T) { - ins := &Insert{ - Opcode: InsertUnsharded, - Keyspace: &vindexes.Keyspace{ + ins := NewQueryInsert( + InsertUnsharded, + &vindexes.Keyspace{ Name: "ks", Sharded: false, }, - Query: "dummy_insert", - Generate: &Generate{ - Keyspace: &vindexes.Keyspace{ - Name: "ks2", - Sharded: false, - }, - Query: "dummy_generate", - Values: sqltypes.PlanValue{ - Values: []sqltypes.PlanValue{ - {Value: sqltypes.NewInt64(1)}, - {Value: sqltypes.NULL}, - {Value: sqltypes.NewInt64(2)}, - {Value: sqltypes.NULL}, - {Value: sqltypes.NewInt64(3)}, - }, + "dummy_insert", + ) + ins.Generate = &Generate{ + Keyspace: &vindexes.Keyspace{ + Name: "ks2", + Sharded: false, + }, + Query: "dummy_generate", + Values: sqltypes.PlanValue{ + Values: []sqltypes.PlanValue{ + {Value: sqltypes.NewInt64(1)}, + {Value: sqltypes.NULL}, + {Value: sqltypes.NewInt64(2)}, + {Value: sqltypes.NULL}, + {Value: sqltypes.NewInt64(3)}, }, }, } @@ -147,10 +147,10 @@ func TestInsertShardedSimple(t *testing.T) { ks := vs.Keyspaces["sharded"] // A single row insert should be autocommitted - ins := &Insert{ - Opcode: InsertSharded, - Keyspace: ks.Keyspace, - VindexValues: []sqltypes.PlanValue{{ + ins := NewInsert( + InsertSharded, + ks.Keyspace, + []sqltypes.PlanValue{{ // colVindex columns: id Values: []sqltypes.PlanValue{{ // 3 rows. @@ -159,11 +159,11 @@ func TestInsertShardedSimple(t *testing.T) { }}, }}, }}, - Table: ks.Tables["t1"], - Prefix: "prefix", - Mid: []string{" mid1"}, - Suffix: " suffix", - } + ks.Tables["t1"], + "prefix", + []string{" mid1"}, + " suffix", + ) vc := &loggingVCursor{ shards: []string{"-20", "20-"}, shardForKsid: []string{"20-", "-20", "20-"}, @@ -182,10 +182,10 @@ func TestInsertShardedSimple(t *testing.T) { }) // Multiple rows are not autocommitted by default - ins = &Insert{ - Opcode: InsertSharded, - Keyspace: ks.Keyspace, - VindexValues: []sqltypes.PlanValue{{ + ins = NewInsert( + InsertSharded, + ks.Keyspace, + []sqltypes.PlanValue{{ // colVindex columns: id Values: []sqltypes.PlanValue{{ // 3 rows. @@ -198,11 +198,11 @@ func TestInsertShardedSimple(t *testing.T) { }}, }}, }}, - Table: ks.Tables["t1"], - Prefix: "prefix", - Mid: []string{" mid1", " mid2", " mid3"}, - Suffix: " suffix", - } + ks.Tables["t1"], + "prefix", + []string{" mid1", " mid2", " mid3"}, + " suffix", + ) vc = &loggingVCursor{ shards: []string{"-20", "20-"}, shardForKsid: []string{"20-", "-20", "20-"}, @@ -222,10 +222,10 @@ func TestInsertShardedSimple(t *testing.T) { }) // Optional flag overrides autocommit - ins = &Insert{ - Opcode: InsertSharded, - Keyspace: ks.Keyspace, - VindexValues: []sqltypes.PlanValue{{ + ins = NewInsert( + InsertSharded, + ks.Keyspace, + []sqltypes.PlanValue{{ // colVindex columns: id Values: []sqltypes.PlanValue{{ // 3 rows. @@ -238,12 +238,13 @@ func TestInsertShardedSimple(t *testing.T) { }}, }}, }}, - Table: ks.Tables["t1"], - Prefix: "prefix", - Mid: []string{" mid1", " mid2", " mid3"}, - Suffix: " suffix", - MultiShardAutocommit: true, - } + ks.Tables["t1"], + "prefix", + []string{" mid1", " mid2", " mid3"}, + " suffix", + ) + ins.MultiShardAutocommit = true + vc = &loggingVCursor{ shards: []string{"-20", "20-"}, shardForKsid: []string{"20-", "-20", "20-"}, @@ -295,10 +296,10 @@ func TestInsertShardedFail(t *testing.T) { } ks := vs.Keyspaces["sharded"] - ins := &Insert{ - Opcode: InsertSharded, - Keyspace: ks.Keyspace, - VindexValues: []sqltypes.PlanValue{{ + ins := NewInsert( + InsertSharded, + ks.Keyspace, + []sqltypes.PlanValue{{ // colVindex columns: id Values: []sqltypes.PlanValue{{ // 1 row @@ -307,11 +308,11 @@ func TestInsertShardedFail(t *testing.T) { }}, }}, }}, - Table: ks.Tables["t1"], - Prefix: "prefix", - Mid: []string{" mid1", " mid2", " mid3"}, - Suffix: " suffix", - } + ks.Tables["t1"], + "prefix", + []string{" mid1", " mid2", " mid3"}, + " suffix", + ) vc := &loggingVCursor{} @@ -347,10 +348,10 @@ func TestInsertShardedGenerate(t *testing.T) { } ks := vs.Keyspaces["sharded"] - ins := &Insert{ - Opcode: InsertSharded, - Keyspace: ks.Keyspace, - VindexValues: []sqltypes.PlanValue{{ + ins := NewInsert( + InsertSharded, + ks.Keyspace, + []sqltypes.PlanValue{{ // colVindex columns: id Values: []sqltypes.PlanValue{{ // 3 rows. @@ -363,24 +364,25 @@ func TestInsertShardedGenerate(t *testing.T) { }}, }}, }}, - Table: ks.Tables["t1"], - Generate: &Generate{ - Keyspace: &vindexes.Keyspace{ - Name: "ks2", - Sharded: false, - }, - Query: "dummy_generate", - Values: sqltypes.PlanValue{ - Values: []sqltypes.PlanValue{ - {Value: sqltypes.NewInt64(1)}, - {Value: sqltypes.NULL}, - {Value: sqltypes.NewInt64(2)}, - }, + ks.Tables["t1"], + "prefix", + []string{" mid1", " mid2", " mid3"}, + " suffix", + ) + + ins.Generate = &Generate{ + Keyspace: &vindexes.Keyspace{ + Name: "ks2", + Sharded: false, + }, + Query: "dummy_generate", + Values: sqltypes.PlanValue{ + Values: []sqltypes.PlanValue{ + {Value: sqltypes.NewInt64(1)}, + {Value: sqltypes.NULL}, + {Value: sqltypes.NewInt64(2)}, }, }, - Prefix: "prefix", - Mid: []string{" mid1", " mid2", " mid3"}, - Suffix: " suffix", } vc := &loggingVCursor{ @@ -472,10 +474,10 @@ func TestInsertShardedOwned(t *testing.T) { } ks := vs.Keyspaces["sharded"] - ins := &Insert{ - Opcode: InsertSharded, - Keyspace: ks.Keyspace, - VindexValues: []sqltypes.PlanValue{{ + ins := NewInsert( + InsertSharded, + ks.Keyspace, + []sqltypes.PlanValue{{ // colVindex columns: id Values: []sqltypes.PlanValue{{ // rows for id @@ -521,11 +523,11 @@ func TestInsertShardedOwned(t *testing.T) { }}, }}, }}, - Table: ks.Tables["t1"], - Prefix: "prefix", - Mid: []string{" mid1", " mid2", " mid3"}, - Suffix: " suffix", - } + ks.Tables["t1"], + "prefix", + []string{" mid1", " mid2", " mid3"}, + " suffix", + ) vc := &loggingVCursor{ shards: []string{"-20", "20-"}, @@ -599,10 +601,10 @@ func TestInsertShardedOwnedWithNull(t *testing.T) { } ks := vs.Keyspaces["sharded"] - ins := &Insert{ - Opcode: InsertSharded, - Keyspace: ks.Keyspace, - VindexValues: []sqltypes.PlanValue{{ + ins := NewInsert( + InsertSharded, + ks.Keyspace, + []sqltypes.PlanValue{{ // colVindex columns: id Values: []sqltypes.PlanValue{{ // rows for id @@ -619,11 +621,11 @@ func TestInsertShardedOwnedWithNull(t *testing.T) { }}, }}, }}, - Table: ks.Tables["t1"], - Prefix: "prefix", - Mid: []string{" mid1", " mid2", " mid3"}, - Suffix: " suffix", - } + ks.Tables["t1"], + "prefix", + []string{" mid1", " mid2", " mid3"}, + " suffix", + ) vc := &loggingVCursor{ shards: []string{"-20", "20-"}, @@ -698,10 +700,10 @@ func TestInsertShardedIgnoreOwned(t *testing.T) { } ks := vs.Keyspaces["sharded"] - ins := &Insert{ - Opcode: InsertShardedIgnore, - Keyspace: ks.Keyspace, - VindexValues: []sqltypes.PlanValue{{ + ins := NewInsert( + InsertShardedIgnore, + ks.Keyspace, + []sqltypes.PlanValue{{ // colVindex columns: id Values: []sqltypes.PlanValue{{ // rows for id @@ -755,11 +757,11 @@ func TestInsertShardedIgnoreOwned(t *testing.T) { }}, }}, }}, - Table: ks.Tables["t1"], - Prefix: "prefix", - Mid: []string{" mid1", " mid2", " mid3", " mid4"}, - Suffix: " suffix", - } + ks.Tables["t1"], + "prefix", + []string{" mid1", " mid2", " mid3", " mid4"}, + " suffix", + ) ksid0 := sqltypes.MakeTestResult( sqltypes.MakeTestFields( @@ -872,10 +874,10 @@ func TestInsertShardedIgnoreOwnedWithNull(t *testing.T) { } ks := vs.Keyspaces["sharded"] - ins := &Insert{ - Opcode: InsertShardedIgnore, - Keyspace: ks.Keyspace, - VindexValues: []sqltypes.PlanValue{{ + ins := NewInsert( + InsertShardedIgnore, + ks.Keyspace, + []sqltypes.PlanValue{{ // colVindex columns: id Values: []sqltypes.PlanValue{{ // rows for id @@ -892,11 +894,11 @@ func TestInsertShardedIgnoreOwnedWithNull(t *testing.T) { }}, }}, }}, - Table: ks.Tables["t1"], - Prefix: "prefix", - Mid: []string{" mid1", " mid2", " mid3", " mid4"}, - Suffix: " suffix", - } + ks.Tables["t1"], + "prefix", + []string{" mid1", " mid2", " mid3", " mid4"}, + " suffix", + ) ksid0 := sqltypes.MakeTestResult( sqltypes.MakeTestFields( @@ -978,10 +980,10 @@ func TestInsertShardedUnownedVerify(t *testing.T) { } ks := vs.Keyspaces["sharded"] - ins := &Insert{ - Opcode: InsertSharded, - Keyspace: ks.Keyspace, - VindexValues: []sqltypes.PlanValue{{ + ins := NewInsert( + InsertSharded, + ks.Keyspace, + []sqltypes.PlanValue{{ // colVindex columns: id Values: []sqltypes.PlanValue{{ // rows for id @@ -1027,11 +1029,11 @@ func TestInsertShardedUnownedVerify(t *testing.T) { }}, }}, }}, - Table: ks.Tables["t1"], - Prefix: "prefix", - Mid: []string{" mid1", " mid2", " mid3"}, - Suffix: " suffix", - } + ks.Tables["t1"], + "prefix", + []string{" mid1", " mid2", " mid3"}, + " suffix", + ) // nonemptyResult will cause the lookup verify queries to succeed. nonemptyResult := sqltypes.MakeTestResult( @@ -1122,10 +1124,10 @@ func TestInsertShardedIgnoreUnownedVerify(t *testing.T) { } ks := vs.Keyspaces["sharded"] - ins := &Insert{ - Opcode: InsertShardedIgnore, - Keyspace: ks.Keyspace, - VindexValues: []sqltypes.PlanValue{{ + ins := NewInsert( + InsertShardedIgnore, + ks.Keyspace, + []sqltypes.PlanValue{{ // colVindex columns: id Values: []sqltypes.PlanValue{{ // rows for id @@ -1150,11 +1152,11 @@ func TestInsertShardedIgnoreUnownedVerify(t *testing.T) { }}, }}, }}, - Table: ks.Tables["t1"], - Prefix: "prefix", - Mid: []string{" mid1", " mid2", " mid3"}, - Suffix: " suffix", - } + ks.Tables["t1"], + "prefix", + []string{" mid1", " mid2", " mid3"}, + " suffix", + ) // nonemptyResult will cause the lookup verify queries to succeed. nonemptyResult := sqltypes.MakeTestResult( @@ -1236,10 +1238,10 @@ func TestInsertShardedIgnoreUnownedVerifyFail(t *testing.T) { } ks := vs.Keyspaces["sharded"] - ins := &Insert{ - Opcode: InsertSharded, - Keyspace: ks.Keyspace, - VindexValues: []sqltypes.PlanValue{{ + ins := NewInsert( + InsertSharded, + ks.Keyspace, + []sqltypes.PlanValue{{ // colVindex columns: id Values: []sqltypes.PlanValue{{ // rows for id @@ -1256,11 +1258,11 @@ func TestInsertShardedIgnoreUnownedVerifyFail(t *testing.T) { }}, }}, }}, - Table: ks.Tables["t1"], - Prefix: "prefix", - Mid: []string{" mid1", " mid2", " mid3"}, - Suffix: " suffix", - } + ks.Tables["t1"], + "prefix", + []string{" mid1", " mid2", " mid3"}, + " suffix", + ) vc := &loggingVCursor{ shards: []string{"-20", "20-"}, @@ -1318,10 +1320,10 @@ func TestInsertShardedUnownedReverseMap(t *testing.T) { } ks := vs.Keyspaces["sharded"] - ins := &Insert{ - Opcode: InsertSharded, - Keyspace: ks.Keyspace, - VindexValues: []sqltypes.PlanValue{{ + ins := NewInsert( + InsertSharded, + ks.Keyspace, + []sqltypes.PlanValue{{ // colVindex columns: id Values: []sqltypes.PlanValue{{ // rows for id @@ -1367,11 +1369,11 @@ func TestInsertShardedUnownedReverseMap(t *testing.T) { }}, }}, }}, - Table: ks.Tables["t1"], - Prefix: "prefix", - Mid: []string{" mid1", " mid2", " mid3"}, - Suffix: " suffix", - } + ks.Tables["t1"], + "prefix", + []string{" mid1", " mid2", " mid3"}, + " suffix", + ) // nonemptyResult will cause the lookup verify queries to succeed. nonemptyResult := sqltypes.MakeTestResult( @@ -1448,10 +1450,10 @@ func TestInsertShardedUnownedReverseMapFail(t *testing.T) { } ks := vs.Keyspaces["sharded"] - ins := &Insert{ - Opcode: InsertSharded, - Keyspace: ks.Keyspace, - VindexValues: []sqltypes.PlanValue{{ + ins := NewInsert( + InsertSharded, + ks.Keyspace, + []sqltypes.PlanValue{{ // colVindex columns: id Values: []sqltypes.PlanValue{{ // rows for id @@ -1468,11 +1470,11 @@ func TestInsertShardedUnownedReverseMapFail(t *testing.T) { }}, }}, }}, - Table: ks.Tables["t1"], - Prefix: "prefix", - Mid: []string{" mid1", " mid2", " mid3"}, - Suffix: " suffix", - } + ks.Tables["t1"], + "prefix", + []string{" mid1", " mid2", " mid3"}, + " suffix", + ) vc := &loggingVCursor{ shards: []string{"-20", "20-"}, diff --git a/go/vt/vtgate/engine/route.go b/go/vt/vtgate/engine/route.go index 470cc8f93c1..fb6678bd23c 100644 --- a/go/vt/vtgate/engine/route.go +++ b/go/vt/vtgate/engine/route.go @@ -83,6 +83,24 @@ type Route struct { ScatterErrorsAsWarnings bool } +// NewSimpleRoute creates a Route with the bare minimum of parameters. +func NewSimpleRoute(opcode RouteOpcode, keyspace *vindexes.Keyspace) *Route { + return &Route{ + Opcode: opcode, + Keyspace: keyspace, + } +} + +// NewRoute creates a Route. +func NewRoute(opcode RouteOpcode, keyspace *vindexes.Keyspace, query, fieldQuery string) *Route { + return &Route{ + Opcode: opcode, + Keyspace: keyspace, + Query: query, + FieldQuery: fieldQuery, + } +} + // OrderbyParams specifies the parameters for ordering. // This is used for merge-sorting scatter queries. type OrderbyParams struct { diff --git a/go/vt/vtgate/engine/route_test.go b/go/vt/vtgate/engine/route_test.go index 7aaf3fb3ce7..682e6f0d788 100644 --- a/go/vt/vtgate/engine/route_test.go +++ b/go/vt/vtgate/engine/route_test.go @@ -35,15 +35,15 @@ var defaultSelectResult = sqltypes.MakeTestResult( ) func TestSelectUnsharded(t *testing.T) { - sel := &Route{ - Opcode: SelectUnsharded, - Keyspace: &vindexes.Keyspace{ + sel := NewRoute( + SelectUnsharded, + &vindexes.Keyspace{ Name: "ks", Sharded: false, }, - Query: "dummy_select", - FieldQuery: "dummy_select_field", - } + "dummy_select", + "dummy_select_field", + ) vc := &loggingVCursor{ shards: []string{"0"}, @@ -72,15 +72,15 @@ func TestSelectUnsharded(t *testing.T) { } func TestSelectScatter(t *testing.T) { - sel := &Route{ - Opcode: SelectScatter, - Keyspace: &vindexes.Keyspace{ + sel := NewRoute( + SelectScatter, + &vindexes.Keyspace{ Name: "ks", Sharded: true, }, - Query: "dummy_select", - FieldQuery: "dummy_select_field", - } + "dummy_select", + "dummy_select_field", + ) vc := &loggingVCursor{ shards: []string{"-20", "20-"}, @@ -110,17 +110,17 @@ func TestSelectScatter(t *testing.T) { func TestSelectEqualUnique(t *testing.T) { vindex, _ := vindexes.NewHash("", nil) - sel := &Route{ - Opcode: SelectEqualUnique, - Keyspace: &vindexes.Keyspace{ + sel := NewRoute( + SelectEqualUnique, + &vindexes.Keyspace{ Name: "ks", Sharded: true, }, - Query: "dummy_select", - FieldQuery: "dummy_select_field", - Vindex: vindex, - Values: []sqltypes.PlanValue{{Value: sqltypes.NewInt64(1)}}, - } + "dummy_select", + "dummy_select_field", + ) + sel.Vindex = vindex + sel.Values = []sqltypes.PlanValue{{Value: sqltypes.NewInt64(1)}} vc := &loggingVCursor{ shards: []string{"-20", "20-"}, @@ -155,17 +155,17 @@ func TestSelectEqualUniqueScatter(t *testing.T) { "to": "toc", "write_only": "true", }) - sel := &Route{ - Opcode: SelectEqualUnique, - Keyspace: &vindexes.Keyspace{ + sel := NewRoute( + SelectEqualUnique, + &vindexes.Keyspace{ Name: "ks", Sharded: true, }, - Query: "dummy_select", - FieldQuery: "dummy_select_field", - Vindex: vindex, - Values: []sqltypes.PlanValue{{Value: sqltypes.NewInt64(1)}}, - } + "dummy_select", + "dummy_select_field", + ) + sel.Vindex = vindex + sel.Values = []sqltypes.PlanValue{{Value: sqltypes.NewInt64(1)}} vc := &loggingVCursor{ shards: []string{"-20", "20-"}, @@ -199,17 +199,17 @@ func TestSelectEqual(t *testing.T) { "from": "from", "to": "toc", }) - sel := &Route{ - Opcode: SelectEqual, - Keyspace: &vindexes.Keyspace{ + sel := NewRoute( + SelectEqual, + &vindexes.Keyspace{ Name: "ks", Sharded: true, }, - Query: "dummy_select", - FieldQuery: "dummy_select_field", - Vindex: vindex, - Values: []sqltypes.PlanValue{{Value: sqltypes.NewInt64(1)}}, - } + "dummy_select", + "dummy_select_field", + ) + sel.Vindex = vindex + sel.Values = []sqltypes.PlanValue{{Value: sqltypes.NewInt64(1)}} vc := &loggingVCursor{ shards: []string{"-20", "20-"}, @@ -255,17 +255,17 @@ func TestSelectEqualNoRoute(t *testing.T) { "from": "from", "to": "toc", }) - sel := &Route{ - Opcode: SelectEqual, - Keyspace: &vindexes.Keyspace{ + sel := NewRoute( + SelectEqual, + &vindexes.Keyspace{ Name: "ks", Sharded: true, }, - Query: "dummy_select", - FieldQuery: "dummy_select_field", - Vindex: vindex, - Values: []sqltypes.PlanValue{{Value: sqltypes.NewInt64(1)}}, - } + "dummy_select", + "dummy_select_field", + ) + sel.Vindex = vindex + sel.Values = []sqltypes.PlanValue{{Value: sqltypes.NewInt64(1)}} vc := &loggingVCursor{shards: []string{"-20", "20-"}} result, err := sel.Execute(vc, map[string]*querypb.BindVariable{}, false) @@ -292,25 +292,25 @@ func TestSelectEqualNoRoute(t *testing.T) { func TestSelectINUnique(t *testing.T) { vindex, _ := vindexes.NewHash("", nil) - sel := &Route{ - Opcode: SelectIN, - Keyspace: &vindexes.Keyspace{ + sel := NewRoute( + SelectIN, + &vindexes.Keyspace{ Name: "ks", Sharded: true, }, - Query: "dummy_select", - FieldQuery: "dummy_select_field", - Vindex: vindex, + "dummy_select", + "dummy_select_field", + ) + sel.Vindex = vindex + sel.Values = []sqltypes.PlanValue{{ Values: []sqltypes.PlanValue{{ - Values: []sqltypes.PlanValue{{ - Value: sqltypes.NewInt64(1), - }, { - Value: sqltypes.NewInt64(2), - }, { - Value: sqltypes.NewInt64(4), - }}, + Value: sqltypes.NewInt64(1), + }, { + Value: sqltypes.NewInt64(2), + }, { + Value: sqltypes.NewInt64(4), }}, - } + }} vc := &loggingVCursor{ shards: []string{"-20", "20-"}, @@ -348,25 +348,25 @@ func TestSelectINNonUnique(t *testing.T) { "from": "from", "to": "toc", }) - sel := &Route{ - Opcode: SelectIN, - Keyspace: &vindexes.Keyspace{ + sel := NewRoute( + SelectIN, + &vindexes.Keyspace{ Name: "ks", Sharded: true, }, - Query: "dummy_select", - FieldQuery: "dummy_select_field", - Vindex: vindex, + "dummy_select", + "dummy_select_field", + ) + sel.Vindex = vindex + sel.Values = []sqltypes.PlanValue{{ Values: []sqltypes.PlanValue{{ - Values: []sqltypes.PlanValue{{ - Value: sqltypes.NewInt64(1), - }, { - Value: sqltypes.NewInt64(2), - }, { - Value: sqltypes.NewInt64(4), - }}, + Value: sqltypes.NewInt64(1), + }, { + Value: sqltypes.NewInt64(2), + }, { + Value: sqltypes.NewInt64(4), }}, - } + }} fields := sqltypes.MakeTestFields( "toc", @@ -426,15 +426,15 @@ func TestSelectINNonUnique(t *testing.T) { } func TestSelectNext(t *testing.T) { - sel := &Route{ - Opcode: SelectNext, - Keyspace: &vindexes.Keyspace{ + sel := NewRoute( + SelectNext, + &vindexes.Keyspace{ Name: "ks", Sharded: true, }, - Query: "dummy_select", - FieldQuery: "dummy_select_field", - } + "dummy_select", + "dummy_select_field", + ) vc := &loggingVCursor{ shards: []string{"-20", "20-"}, @@ -456,15 +456,15 @@ func TestSelectNext(t *testing.T) { } func TestSelectDBA(t *testing.T) { - sel := &Route{ - Opcode: SelectDBA, - Keyspace: &vindexes.Keyspace{ + sel := NewRoute( + SelectDBA, + &vindexes.Keyspace{ Name: "ks", Sharded: true, }, - Query: "dummy_select", - FieldQuery: "dummy_select_field", - } + "dummy_select", + "dummy_select_field", + ) vc := &loggingVCursor{ shards: []string{"-20", "20-"}, @@ -491,17 +491,17 @@ func TestRouteGetFields(t *testing.T) { "from": "from", "to": "toc", }) - sel := &Route{ - Opcode: SelectEqual, - Keyspace: &vindexes.Keyspace{ + sel := NewRoute( + SelectEqual, + &vindexes.Keyspace{ Name: "ks", Sharded: true, }, - Query: "dummy_select", - FieldQuery: "dummy_select_field", - Vindex: vindex, - Values: []sqltypes.PlanValue{{Value: sqltypes.NewInt64(1)}}, - } + "dummy_select", + "dummy_select_field", + ) + sel.Vindex = vindex + sel.Values = []sqltypes.PlanValue{{Value: sqltypes.NewInt64(1)}} vc := &loggingVCursor{shards: []string{"-20", "20-"}} result, err := sel.Execute(vc, map[string]*querypb.BindVariable{}, true) @@ -531,18 +531,18 @@ func TestRouteGetFields(t *testing.T) { } func TestRouteSort(t *testing.T) { - sel := &Route{ - Opcode: SelectUnsharded, - Keyspace: &vindexes.Keyspace{ + sel := NewRoute( + SelectUnsharded, + &vindexes.Keyspace{ Name: "ks", Sharded: false, }, - Query: "dummy_select", - FieldQuery: "dummy_select_field", - OrderBy: []OrderbyParams{{ - Col: 0, - }}, - } + "dummy_select", + "dummy_select_field", + ) + sel.OrderBy = []OrderbyParams{{ + Col: 0, + }} vc := &loggingVCursor{ shards: []string{"0"}, @@ -616,19 +616,19 @@ func TestRouteSort(t *testing.T) { } func TestRouteSortTruncate(t *testing.T) { - sel := &Route{ - Opcode: SelectUnsharded, - Keyspace: &vindexes.Keyspace{ + sel := NewRoute( + SelectUnsharded, + &vindexes.Keyspace{ Name: "ks", Sharded: false, }, - Query: "dummy_select", - FieldQuery: "dummy_select_field", - OrderBy: []OrderbyParams{{ - Col: 0, - }}, - TruncateColumnCount: 1, - } + "dummy_select", + "dummy_select_field", + ) + sel.OrderBy = []OrderbyParams{{ + Col: 0, + }} + sel.TruncateColumnCount = 1 vc := &loggingVCursor{ shards: []string{"0"}, @@ -667,16 +667,16 @@ func TestRouteSortTruncate(t *testing.T) { } func TestRouteStreamTruncate(t *testing.T) { - sel := &Route{ - Opcode: SelectUnsharded, - Keyspace: &vindexes.Keyspace{ + sel := NewRoute( + SelectUnsharded, + &vindexes.Keyspace{ Name: "ks", Sharded: false, }, - Query: "dummy_select", - FieldQuery: "dummy_select_field", - TruncateColumnCount: 1, - } + "dummy_select", + "dummy_select_field", + ) + sel.TruncateColumnCount = 1 vc := &loggingVCursor{ shards: []string{"0"}, @@ -711,19 +711,19 @@ func TestRouteStreamTruncate(t *testing.T) { } func TestRouteStreamSortTruncate(t *testing.T) { - sel := &Route{ - Opcode: SelectUnsharded, - Keyspace: &vindexes.Keyspace{ + sel := NewRoute( + SelectUnsharded, + &vindexes.Keyspace{ Name: "ks", Sharded: false, }, - Query: "dummy_select", - FieldQuery: "dummy_select_field", - OrderBy: []OrderbyParams{{ - Col: 0, - }}, - TruncateColumnCount: 1, - } + "dummy_select", + "dummy_select_field", + ) + sel.OrderBy = []OrderbyParams{{ + Col: 0, + }} + sel.TruncateColumnCount = 1 vc := &loggingVCursor{ shards: []string{"0"}, @@ -762,15 +762,15 @@ func TestRouteStreamSortTruncate(t *testing.T) { } func TestParamsFail(t *testing.T) { - sel := &Route{ - Opcode: SelectUnsharded, - Keyspace: &vindexes.Keyspace{ + sel := NewRoute( + SelectUnsharded, + &vindexes.Keyspace{ Name: "ks", Sharded: false, }, - Query: "dummy_select", - FieldQuery: "dummy_select_field", - } + "dummy_select", + "dummy_select_field", + ) vc := &loggingVCursor{shardErr: errors.New("shard error")} _, err := sel.Execute(vc, map[string]*querypb.BindVariable{}, false) @@ -783,15 +783,15 @@ func TestParamsFail(t *testing.T) { func TestExecFail(t *testing.T) { // Unsharded error - sel := &Route{ - Opcode: SelectUnsharded, - Keyspace: &vindexes.Keyspace{ + sel := NewRoute( + SelectUnsharded, + &vindexes.Keyspace{ Name: "ks", Sharded: false, }, - Query: "dummy_select", - FieldQuery: "dummy_select_field", - } + "dummy_select", + "dummy_select_field", + ) vc := &loggingVCursor{shards: []string{"0"}, resultErr: mysql.NewSQLError(mysql.ERQueryInterrupted, "", "query timeout")} _, err := sel.Execute(vc, map[string]*querypb.BindVariable{}, false) @@ -803,15 +803,15 @@ func TestExecFail(t *testing.T) { expectError(t, "sel.StreamExecute err", err, "query timeout (errno 1317) (sqlstate HY000)") // Scatter fails if one of N fails without ScatterErrorsAsWarnings - sel = &Route{ - Opcode: SelectScatter, - Keyspace: &vindexes.Keyspace{ + sel = NewRoute( + SelectScatter, + &vindexes.Keyspace{ Name: "ks", Sharded: true, }, - Query: "dummy_select", - FieldQuery: "dummy_select_field", - } + "dummy_select", + "dummy_select_field", + ) vc = &loggingVCursor{ shards: []string{"-20", "20-"}, @@ -831,16 +831,16 @@ func TestExecFail(t *testing.T) { vc.Rewind() // Scatter succeeds if all shards fail with ScatterErrorsAsWarnings - sel = &Route{ - Opcode: SelectScatter, - Keyspace: &vindexes.Keyspace{ + sel = NewRoute( + SelectScatter, + &vindexes.Keyspace{ Name: "ks", Sharded: true, }, - Query: "dummy_select", - FieldQuery: "dummy_select_field", - ScatterErrorsAsWarnings: true, - } + "dummy_select", + "dummy_select_field", + ) + sel.ScatterErrorsAsWarnings = true vc = &loggingVCursor{ shards: []string{"-20", "20-"}, @@ -869,16 +869,16 @@ func TestExecFail(t *testing.T) { vc.Rewind() // Scatter succeeds if one of N fails with ScatterErrorsAsWarnings - sel = &Route{ - Opcode: SelectScatter, - Keyspace: &vindexes.Keyspace{ + sel = NewRoute( + SelectScatter, + &vindexes.Keyspace{ Name: "ks", Sharded: true, }, - Query: "dummy_select", - FieldQuery: "dummy_select_field", - ScatterErrorsAsWarnings: true, - } + "dummy_select", + "dummy_select_field", + ) + sel.ScatterErrorsAsWarnings = true vc = &loggingVCursor{ shards: []string{"-20", "20-"}, diff --git a/go/vt/vtgate/executor_framework_test.go b/go/vt/vtgate/executor_framework_test.go index 36f4909ee00..26f86cbae6f 100644 --- a/go/vt/vtgate/executor_framework_test.go +++ b/go/vt/vtgate/executor_framework_test.go @@ -267,6 +267,12 @@ var unshardedVSchema = ` } ` +type DestinationAnyShardPickerFirstShard struct{} + +func (dp DestinationAnyShardPickerFirstShard) PickShard(shardCount int) int { + return 0 +} + // keyRangeLookuper is for testing a lookup that returns a keyrange. type keyRangeLookuper struct { } @@ -353,6 +359,7 @@ func createExecutorEnv() (executor *Executor, sbc1, sbc2, sbclookup *sandboxconn getSandbox(KsTestUnsharded).VSchema = unshardedVSchema executor = NewExecutor(context.Background(), serv, cell, "", resolver, false, testBufferSize, testCacheSize, false) + key.AnyShardPicker = DestinationAnyShardPickerFirstShard{} return executor, sbc1, sbc2, sbclookup } diff --git a/go/vt/vtgate/planbuilder/from.go b/go/vt/vtgate/planbuilder/from.go index af0319a3dfe..dd598cc9510 100644 --- a/go/vt/vtgate/planbuilder/from.go +++ b/go/vt/vtgate/planbuilder/from.go @@ -149,10 +149,7 @@ func (pb *primitiveBuilder) buildTablePrimitive(tableExpr *sqlparser.AliasedTabl return err } rb, st := newRoute(sel, nil, nil) - rb.ERoute = &engine.Route{ - Opcode: engine.SelectDBA, - Keyspace: ks, - } + rb.ERoute = engine.NewSimpleRoute(engine.SelectDBA, ks) pb.bldr, pb.st = rb, st return nil } @@ -172,28 +169,20 @@ func (pb *primitiveBuilder) buildTablePrimitive(tableExpr *sqlparser.AliasedTabl _ = st.AddVindexTable(alias, table, rb) if !table.Keyspace.Sharded { - rb.ERoute = &engine.Route{ - Opcode: engine.SelectUnsharded, - Keyspace: table.Keyspace, - } + rb.ERoute = engine.NewSimpleRoute(engine.SelectUnsharded, table.Keyspace) return nil } if table.Pinned == nil { - rb.ERoute = &engine.Route{ - Opcode: engine.SelectScatter, - Keyspace: table.Keyspace, - TargetDestination: destTarget, - TargetTabletType: destTableType, - } + rb.ERoute = engine.NewSimpleRoute(engine.SelectScatter, table.Keyspace) + rb.ERoute.TargetDestination = destTarget + rb.ERoute.TargetTabletType = destTableType + return nil } // 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. - eRoute := &engine.Route{ - Opcode: engine.SelectEqualUnique, - Keyspace: table.Keyspace, - } + eRoute := engine.NewSimpleRoute(engine.SelectEqualUnique, table.Keyspace) eRoute.Vindex, _ = vindexes.NewBinary("binary", nil) eRoute.Values = []sqltypes.PlanValue{{Value: sqltypes.MakeTrusted(sqltypes.VarBinary, table.Pinned)}} rb.ERoute = eRoute diff --git a/go/vt/vtgate/planbuilder/insert.go b/go/vt/vtgate/planbuilder/insert.go index 4ba900513b0..7046dfcdee6 100644 --- a/go/vt/vtgate/planbuilder/insert.go +++ b/go/vt/vtgate/planbuilder/insert.go @@ -59,11 +59,11 @@ func buildInsertPlan(ins *sqlparser.Insert, vschema ContextVSchema) (*engine.Ins } func buildInsertUnshardedPlan(ins *sqlparser.Insert, table *vindexes.Table, vschema ContextVSchema) (*engine.Insert, error) { - eins := &engine.Insert{ - Opcode: engine.InsertUnsharded, - Table: table, - Keyspace: table.Keyspace, - } + eins := engine.NewSimpleInsert( + engine.InsertUnsharded, + table, + table.Keyspace, + ) var rows sqlparser.Values switch insertValues := ins.Rows.(type) { case *sqlparser.Select, *sqlparser.Union: @@ -99,11 +99,11 @@ func buildInsertUnshardedPlan(ins *sqlparser.Insert, table *vindexes.Table, vsch } func buildInsertShardedPlan(ins *sqlparser.Insert, table *vindexes.Table) (*engine.Insert, error) { - eins := &engine.Insert{ - Opcode: engine.InsertSharded, - Table: table, - Keyspace: table.Keyspace, - } + eins := engine.NewSimpleInsert( + engine.InsertSharded, + table, + table.Keyspace, + ) if ins.Ignore != "" { eins.Opcode = engine.InsertShardedIgnore } From 7bd3486fde7213d9b01c1d4c135b2733fae82c50 Mon Sep 17 00:00:00 2001 From: Rafael Chacon Date: Tue, 15 Jan 2019 08:06:01 -0800 Subject: [PATCH 055/115] Revert "Support tables that have columns named desc" This reverts commit 698aa3721d6d23c824f6835969f811384ba6d04f. Signed-off-by: Rafael Chacon --- go/vt/sqlparser/parse_test.go | 3 - go/vt/sqlparser/sql.go | 3117 +++++++++++++++++---------------- go/vt/sqlparser/sql.y | 1 - 3 files changed, 1561 insertions(+), 1560 deletions(-) diff --git a/go/vt/sqlparser/parse_test.go b/go/vt/sqlparser/parse_test.go index 8141ac89905..bdafd2061ae 100644 --- a/go/vt/sqlparser/parse_test.go +++ b/go/vt/sqlparser/parse_test.go @@ -610,9 +610,6 @@ var ( }, { input: "insert /* it accepts columns with keyword action */ into a(action, b) values (1, 2)", output: "insert /* it accepts columns with keyword action */ into a(`action`, b) values (1, 2)", - }, { - input: "insert /* it accepts columns with keyword desc */ into a(desc, b) values (1, 2)", - output: "insert /* it accepts columns with keyword desc */ into a(`desc`, b) values (1, 2)", }, { input: "insert /* no cols & paren select */ into a(select * from t)", output: "insert /* no cols & paren select */ into a select * from t", diff --git a/go/vt/sqlparser/sql.go b/go/vt/sqlparser/sql.go index 6bde27a44cd..7575306054c 100644 --- a/go/vt/sqlparser/sql.go +++ b/go/vt/sqlparser/sql.go @@ -638,25 +638,25 @@ var yyExca = [...]int{ 159, 300, 160, 300, -2, 290, - -1, 268, + -1, 267, 112, 636, -2, 632, - -1, 269, + -1, 268, 112, 637, -2, 633, - -1, 332, - 82, 808, + -1, 331, + 82, 807, -2, 60, - -1, 333, - 82, 765, + -1, 332, + 82, 764, -2, 61, - -1, 338, + -1, 337, 82, 743, -2, 598, - -1, 340, - 82, 786, + -1, 339, + 82, 785, -2, 600, - -1, 598, + -1, 597, 1, 352, 5, 352, 12, 352, @@ -680,1256 +680,1262 @@ var yyExca = [...]int{ 56, 352, 266, 352, -2, 370, - -1, 601, + -1, 600, 53, 43, 55, 43, -2, 45, - -1, 741, + -1, 740, 112, 639, -2, 635, - -1, 959, + -1, 958, 5, 30, -2, 436, - -1, 988, + -1, 987, 5, 29, -2, 572, - -1, 1241, + -1, 1240, 5, 30, -2, 573, - -1, 1296, + -1, 1295, 5, 29, -2, 575, - -1, 1377, + -1, 1376, 5, 30, -2, 576, } const yyPrivate = 57344 -const yyLast = 12083 +const yyLast = 12140 var yyAct = [...]int{ - 269, 1412, 1402, 1198, 1365, 1080, 273, 991, 563, 845, - 1308, 1275, 1133, 1134, 1167, 1261, 57, 992, 247, 1130, - 822, 841, 1009, 888, 924, 854, 1034, 844, 1146, 337, - 874, 1140, 81, 562, 3, 820, 209, 1103, 776, 209, - 766, 706, 1060, 1051, 1015, 824, 951, 299, 809, 794, - 275, 858, 743, 773, 611, 501, 495, 436, 802, 595, - 610, 331, 884, 515, 507, 256, 594, 209, 81, 328, - 933, 577, 209, 238, 209, 56, 1405, 1389, 1400, 326, - 1375, 1397, 1199, 1388, 1125, 246, 1374, 61, 1235, 441, - 271, 1319, 469, 204, 200, 201, 202, 1161, 1175, 1176, - 1177, 835, 260, 1162, 1163, 489, 1180, 1178, 907, 836, - 837, 244, 243, 63, 64, 65, 66, 67, 239, 240, - 241, 242, 906, 867, 245, 1341, 528, 527, 537, 538, - 530, 531, 532, 533, 534, 535, 536, 529, 1022, 485, - 539, 1021, 1042, 612, 1023, 613, 1264, 486, 483, 484, - 911, 196, 454, 198, 1281, 875, 1218, 1216, 471, 905, - 473, 237, 1104, 488, 478, 479, 1083, 1082, 528, 527, - 537, 538, 530, 531, 532, 533, 534, 535, 536, 529, - 679, 1399, 539, 1396, 681, 1366, 1357, 1079, 859, 803, - 470, 472, 1416, 1420, 455, 1309, 443, 209, 1317, 1106, - 209, 600, 1010, 1012, 198, 1084, 209, 685, 1311, 902, - 899, 900, 209, 898, 203, 81, 672, 81, 680, 81, - 81, 952, 81, 861, 81, 1156, 861, 1155, 1154, 1076, - 439, 682, 1108, 81, 1112, 1078, 1107, 206, 1105, 446, - 211, 451, 199, 1110, 909, 912, 197, 918, 551, 552, - 917, 1346, 1109, 1244, 1184, 1035, 532, 533, 534, 535, - 536, 529, 1090, 81, 539, 1111, 1113, 503, 327, 707, - 969, 945, 868, 438, 842, 440, 1310, 465, 468, 1011, - 904, 1179, 712, 715, 875, 519, 504, 461, 529, 539, - 514, 539, 926, 513, 512, 1342, 1355, 1373, 1414, 1318, - 1316, 1415, 903, 1413, 448, 1185, 449, 714, 1327, 450, - 514, 300, 51, 437, 1067, 964, 1144, 491, 492, 860, - 614, 549, 860, 750, 209, 209, 209, 467, 718, 719, - 81, 1077, 963, 1075, 962, 1127, 81, 748, 749, 747, - 795, 505, 978, 1065, 713, 908, 435, 513, 512, 795, - 708, 513, 512, 864, 1129, 457, 458, 459, 910, 865, - 593, 513, 512, 51, 514, 513, 512, 70, 514, 674, - 925, 252, 442, 1421, 1040, 598, 513, 512, 514, 509, - 861, 512, 514, 1360, 579, 580, 581, 582, 583, 584, - 585, 195, 54, 514, 1379, 334, 1271, 514, 447, 608, - 1270, 453, 746, 71, 767, 602, 768, 460, 1055, 437, - 1066, 1054, 1422, 462, 1043, 1071, 1068, 1061, 1069, 1064, - 1024, 1381, 1025, 1062, 1063, 527, 537, 538, 530, 531, - 532, 533, 534, 535, 536, 529, 209, 1070, 539, 1356, - 22, 81, 942, 943, 944, 1292, 209, 209, 81, 444, - 445, 1268, 209, 1087, 1052, 209, 323, 324, 209, 1314, - 1398, 494, 209, 1353, 81, 81, 1384, 494, 1382, 81, - 81, 81, 81, 81, 81, 1324, 860, 1314, 1369, 81, - 81, 857, 855, 1201, 856, 1035, 733, 735, 736, 853, - 859, 694, 734, 1030, 474, 769, 475, 476, 691, 477, - 251, 480, 1314, 494, 298, 1314, 1347, 81, 1314, 1313, - 490, 209, 1259, 1258, 1246, 494, 1323, 81, 1243, 494, - 775, 690, 720, 1191, 1190, 592, 466, 601, 466, 675, - 466, 466, 692, 466, 686, 466, 79, 289, 288, 291, - 292, 293, 294, 673, 466, 670, 290, 295, 463, 741, - 537, 538, 530, 531, 532, 533, 534, 535, 536, 529, - 456, 81, 539, 24, 51, 1187, 1188, 1187, 1186, 1320, - 744, 722, 336, 745, 957, 494, 1181, 785, 789, 548, - 737, 862, 550, 796, 806, 494, 1143, 986, 778, 494, - 739, 987, 209, 621, 620, 1131, 778, 1016, 1143, 780, - 209, 209, 605, 1239, 209, 209, 1016, 24, 81, 1326, - 561, 54, 565, 566, 567, 568, 569, 570, 571, 572, - 573, 81, 576, 578, 578, 578, 578, 578, 578, 578, - 578, 586, 587, 588, 589, 1295, 599, 622, 792, 830, - 806, 799, 770, 771, 606, 806, 604, 676, 677, 1143, - 598, 58, 1093, 683, 598, 54, 327, 334, 973, 689, - 828, 971, 829, 968, 604, 24, 876, 877, 878, 832, - 833, 966, 805, 209, 81, 1189, 81, 1026, 834, 849, - 81, 81, 209, 209, 957, 209, 209, 604, 607, 209, - 81, 957, 716, 890, 684, 253, 957, 806, 54, 1390, - 1363, 493, 972, 1277, 1081, 970, 209, 967, 209, 209, - 1266, 209, 729, 54, 892, 965, 869, 1251, 671, 336, - 889, 336, 1172, 336, 336, 678, 336, 1029, 336, 886, - 887, 885, 811, 814, 815, 816, 812, 336, 813, 817, - 880, 695, 696, 54, 1407, 741, 697, 698, 699, 700, - 701, 702, 466, 1147, 1148, 1403, 703, 704, 879, 466, - 1174, 1150, 1131, 1056, 710, 688, 1003, 517, 1001, 1394, - 728, 1004, 934, 1002, 1153, 466, 466, 935, 1152, 1000, - 466, 466, 466, 466, 466, 466, 1005, 999, 815, 816, - 466, 466, 1387, 804, 1089, 744, 257, 258, 745, 930, - 947, 1392, 940, 939, 1047, 619, 831, 209, 209, 209, - 209, 209, 993, 508, 811, 814, 815, 816, 812, 209, - 813, 817, 209, 496, 1147, 1148, 209, 464, 506, 1039, - 209, 1362, 1273, 1361, 336, 497, 988, 1293, 1037, 1031, - 616, 1237, 895, 977, 687, 81, 819, 740, 254, 255, - 248, 508, 1331, 249, 1027, 780, 938, 598, 598, 598, - 598, 598, 51, 58, 937, 1017, 1006, 995, 996, 1330, - 998, 1014, 598, 994, 893, 1018, 997, 565, 1279, 1016, - 598, 487, 705, 915, 916, 1036, 919, 920, 510, 1019, - 921, 1409, 1408, 81, 81, 1409, 1046, 1343, 1048, 1049, - 1050, 1044, 1045, 870, 871, 872, 873, 923, 1032, 1033, - 1265, 821, 929, 711, 60, 599, 62, 603, 55, 881, - 882, 883, 81, 1, 1053, 1401, 530, 531, 532, 533, - 534, 535, 536, 529, 1200, 334, 539, 209, 1274, 901, - 1364, 1307, 1072, 1166, 852, 336, 81, 843, 846, 69, - 434, 894, 336, 896, 68, 1354, 851, 850, 1315, 1263, - 863, 1041, 866, 1173, 1359, 1086, 1038, 922, 336, 336, - 627, 1059, 625, 336, 336, 336, 336, 336, 336, 626, - 624, 629, 628, 336, 336, 466, 623, 466, 222, 329, - 81, 81, 1126, 993, 1132, 1097, 1102, 818, 615, 741, - 1096, 466, 1115, 891, 1114, 511, 72, 1074, 1073, 897, - 481, 724, 482, 224, 81, 547, 936, 1020, 335, 1138, - 717, 517, 500, 1137, 336, 1329, 1151, 81, 1278, 81, - 81, 976, 1158, 574, 793, 1135, 1142, 274, 1165, 732, - 287, 284, 266, 740, 286, 1157, 285, 723, 985, 521, - 272, 264, 946, 597, 1164, 590, 1169, 209, 810, 1170, - 1171, 808, 1160, 807, 1149, 772, 1182, 1183, 1145, 596, - 1092, 1234, 1340, 727, 209, 787, 787, 26, 59, 259, - 81, 787, 19, 81, 81, 209, 18, 781, 782, 17, - 20, 81, 16, 791, 209, 15, 14, 452, 30, 21, - 13, 12, 11, 10, 9, 8, 7, 798, 6, 800, - 801, 1205, 336, 5, 989, 990, 4, 250, 599, 599, - 599, 599, 599, 23, 2, 336, 0, 0, 0, 1207, - 0, 0, 1214, 821, 1193, 1013, 0, 1206, 1091, 0, - 0, 599, 0, 0, 598, 0, 1194, 1232, 1196, 0, - 993, 262, 1238, 0, 0, 0, 0, 0, 0, 1247, - 0, 1248, 0, 0, 0, 81, 0, 0, 0, 0, - 0, 1058, 846, 81, 1027, 0, 0, 1257, 336, 0, - 336, 0, 0, 0, 913, 914, 0, 0, 0, 0, - 0, 0, 0, 81, 336, 0, 0, 0, 0, 1085, - 81, 0, 0, 0, 0, 466, 721, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1267, 0, 1269, - 336, 528, 527, 537, 538, 530, 531, 532, 533, 534, - 535, 536, 529, 466, 0, 539, 0, 0, 0, 0, - 0, 0, 0, 1280, 81, 81, 0, 81, 941, 0, - 0, 0, 81, 1294, 81, 81, 81, 209, 1192, 0, - 81, 0, 0, 0, 777, 779, 1301, 1302, 0, 1303, - 1304, 1305, 0, 1095, 1312, 1195, 1296, 1306, 81, 0, - 797, 0, 0, 0, 0, 0, 1204, 1135, 0, 1321, - 0, 1322, 0, 1328, 0, 956, 0, 1120, 0, 1136, - 0, 51, 0, 0, 0, 0, 0, 0, 1344, 0, - 787, 0, 0, 975, 0, 81, 0, 0, 1352, 553, - 554, 555, 556, 557, 558, 559, 560, 81, 81, 1351, - 0, 1345, 0, 0, 0, 0, 0, 1368, 1367, 0, - 1371, 0, 0, 1135, 0, 0, 0, 81, 0, 336, - 993, 1376, 0, 0, 846, 0, 846, 0, 209, 0, - 0, 0, 0, 0, 0, 0, 0, 81, 0, 0, - 0, 0, 0, 0, 0, 1386, 0, 1211, 1212, 0, - 1213, 0, 0, 1215, 0, 1217, 0, 0, 0, 1391, - 1393, 81, 0, 0, 0, 0, 0, 1057, 336, 0, - 498, 502, 0, 0, 1406, 599, 1395, 0, 0, 0, - 0, 1417, 0, 0, 0, 0, 0, 520, 1095, 0, - 0, 0, 0, 0, 0, 0, 336, 0, 0, 0, - 0, 0, 0, 0, 0, 219, 0, 1233, 0, 0, - 0, 1260, 0, 0, 0, 0, 0, 0, 0, 0, - 336, 0, 564, 0, 0, 0, 0, 0, 0, 232, - 0, 575, 0, 0, 0, 0, 1253, 1254, 1255, 0, - 1272, 954, 0, 0, 336, 955, 0, 0, 0, 0, - 0, 0, 959, 960, 961, 0, 0, 0, 0, 0, - 0, 787, 846, 974, 1139, 1141, 0, 0, 980, 494, - 981, 982, 983, 984, 466, 0, 0, 0, 0, 0, - 212, 0, 0, 0, 0, 0, 0, 215, 1141, 499, - 0, 0, 1008, 0, 0, 223, 218, 1276, 0, 0, - 0, 336, 0, 336, 1168, 0, 528, 527, 537, 538, - 530, 531, 532, 533, 534, 535, 536, 529, 0, 0, - 539, 1136, 0, 0, 1297, 207, 0, 221, 236, 1380, - 0, 0, 0, 231, 742, 0, 0, 751, 752, 753, + 268, 1411, 1401, 1197, 1364, 1079, 272, 990, 562, 844, + 1008, 1274, 1132, 1166, 991, 1260, 57, 821, 246, 1133, + 1129, 1307, 840, 887, 873, 853, 923, 843, 1139, 1033, + 1014, 1102, 81, 561, 3, 819, 208, 336, 1145, 208, + 765, 775, 705, 1059, 1050, 857, 950, 298, 808, 823, + 772, 742, 793, 593, 610, 237, 494, 500, 609, 594, + 255, 330, 883, 514, 325, 801, 435, 208, 81, 327, + 932, 506, 208, 56, 208, 1404, 774, 1388, 1399, 1374, + 1396, 1198, 1387, 1373, 867, 245, 1124, 1234, 440, 1318, + 468, 203, 199, 200, 201, 1161, 1162, 1160, 270, 61, + 238, 239, 240, 241, 834, 259, 244, 576, 488, 1340, + 527, 526, 536, 537, 529, 530, 531, 532, 533, 534, + 535, 528, 243, 906, 538, 63, 64, 65, 66, 67, + 1174, 1175, 1176, 835, 836, 242, 1041, 905, 1179, 1177, + 1021, 484, 611, 1020, 612, 195, 1022, 197, 866, 485, + 482, 483, 218, 1263, 453, 874, 470, 1280, 472, 1217, + 1215, 236, 477, 478, 680, 910, 487, 1082, 1081, 678, + 1398, 1395, 1365, 1078, 904, 802, 231, 1356, 858, 1419, + 1103, 454, 1415, 442, 1308, 197, 1009, 1011, 469, 471, + 1083, 684, 671, 860, 860, 1345, 208, 1310, 679, 208, + 860, 599, 1155, 1154, 1153, 208, 438, 681, 445, 210, + 198, 208, 202, 1316, 81, 1243, 81, 1105, 81, 81, + 1183, 81, 1034, 81, 901, 898, 899, 211, 897, 436, + 917, 841, 81, 916, 214, 550, 551, 205, 1089, 968, + 196, 1075, 222, 217, 944, 714, 518, 1077, 528, 460, + 1107, 538, 1111, 450, 1106, 538, 1104, 513, 1354, 908, + 911, 1109, 81, 1010, 436, 1309, 502, 706, 326, 711, + 1108, 1184, 70, 437, 220, 439, 467, 963, 1066, 1341, + 230, 1326, 1143, 1110, 1112, 503, 613, 874, 1413, 859, + 859, 1414, 1126, 1412, 1372, 903, 859, 434, 490, 491, + 925, 856, 854, 511, 855, 794, 212, 1064, 71, 852, + 858, 299, 51, 1178, 1317, 1315, 447, 902, 448, 513, + 794, 449, 977, 208, 208, 208, 441, 512, 511, 81, + 1039, 673, 1359, 224, 215, 81, 225, 226, 227, 229, + 508, 228, 234, 1076, 513, 1074, 216, 219, 707, 213, + 233, 232, 504, 512, 511, 1420, 456, 457, 458, 592, + 907, 749, 1378, 51, 531, 532, 533, 534, 535, 528, + 513, 251, 538, 909, 1065, 747, 748, 746, 924, 1070, + 1067, 1060, 1068, 1063, 863, 512, 511, 1061, 1062, 601, + 864, 261, 1128, 1270, 1421, 717, 718, 446, 607, 1380, + 452, 1069, 513, 443, 444, 54, 459, 732, 734, 735, + 1269, 194, 461, 733, 1054, 745, 274, 1053, 466, 578, + 579, 580, 581, 582, 583, 584, 529, 530, 531, 532, + 533, 534, 535, 528, 1042, 208, 538, 1355, 1291, 962, + 81, 961, 1267, 512, 511, 208, 208, 81, 713, 22, + 1086, 208, 1352, 766, 208, 767, 1200, 208, 512, 511, + 513, 208, 1051, 81, 81, 941, 942, 943, 81, 81, + 81, 81, 81, 81, 1034, 513, 322, 323, 81, 81, + 1023, 1029, 1024, 1313, 1397, 712, 333, 526, 536, 537, + 529, 530, 531, 532, 533, 534, 535, 528, 693, 768, + 538, 690, 512, 511, 297, 689, 81, 1383, 493, 250, + 208, 1313, 1368, 1313, 493, 604, 81, 674, 685, 513, + 672, 719, 1313, 1346, 591, 465, 600, 465, 669, 465, + 465, 691, 465, 462, 465, 455, 79, 1313, 1312, 1258, + 1257, 1245, 493, 465, 527, 526, 536, 537, 529, 530, + 531, 532, 533, 534, 535, 528, 740, 605, 538, 603, + 81, 1242, 493, 51, 493, 721, 1190, 1189, 1381, 743, + 1186, 1187, 335, 1186, 1185, 1323, 784, 788, 547, 736, + 1322, 549, 795, 288, 287, 290, 291, 292, 293, 738, + 1319, 208, 289, 294, 956, 493, 1180, 951, 779, 208, + 208, 805, 493, 208, 208, 777, 493, 81, 1015, 560, + 861, 564, 565, 566, 567, 568, 569, 570, 571, 572, + 81, 575, 577, 577, 577, 577, 577, 577, 577, 577, + 585, 586, 587, 588, 1092, 598, 621, 798, 829, 497, + 501, 1142, 780, 781, 791, 804, 675, 676, 790, 769, + 770, 805, 682, 620, 619, 326, 519, 58, 688, 875, + 876, 877, 797, 1015, 799, 800, 827, 832, 831, 972, + 805, 24, 208, 81, 1130, 81, 24, 1142, 956, 81, + 81, 208, 208, 777, 208, 208, 548, 848, 208, 81, + 970, 563, 889, 967, 965, 985, 828, 956, 603, 986, + 574, 492, 1238, 1325, 1294, 208, 1142, 208, 208, 805, + 208, 728, 1188, 971, 869, 870, 871, 872, 335, 54, + 335, 24, 335, 335, 54, 335, 1025, 335, 885, 886, + 880, 881, 882, 833, 969, 956, 335, 966, 964, 603, + 597, 606, 810, 813, 814, 815, 811, 333, 812, 816, + 715, 465, 740, 810, 813, 814, 815, 811, 465, 812, + 816, 683, 54, 1146, 1147, 252, 516, 1389, 1362, 54, + 1276, 1265, 868, 933, 465, 465, 934, 1250, 888, 465, + 465, 465, 465, 465, 465, 1171, 1146, 1147, 1080, 465, + 465, 1028, 803, 884, 743, 879, 878, 891, 946, 1406, + 1402, 1173, 1149, 940, 1130, 830, 208, 208, 208, 208, + 208, 992, 1055, 54, 709, 687, 727, 1002, 208, 1000, + 1152, 208, 1003, 1151, 1001, 208, 999, 998, 1004, 208, + 814, 815, 1393, 335, 1386, 987, 256, 257, 1088, 615, + 929, 507, 1391, 939, 81, 976, 938, 1046, 618, 463, + 955, 495, 1038, 1026, 779, 1361, 505, 1360, 1292, 993, + 1017, 51, 996, 496, 1016, 1005, 994, 995, 974, 997, + 1036, 1030, 1236, 892, 1013, 1272, 564, 894, 708, 686, + 818, 507, 914, 915, 247, 918, 919, 1035, 1018, 920, + 253, 254, 81, 81, 1043, 1044, 1045, 937, 1047, 1048, + 1049, 1031, 1032, 729, 730, 936, 922, 1330, 248, 58, + 820, 928, 1329, 1278, 598, 1015, 486, 1408, 1407, 1408, + 704, 81, 509, 1342, 1052, 1264, 710, 60, 62, 602, + 55, 1, 1400, 1199, 1273, 900, 208, 739, 744, 1363, + 1306, 1165, 1071, 851, 335, 81, 842, 69, 433, 68, + 1353, 335, 1058, 850, 849, 1314, 563, 1262, 862, 782, + 783, 1040, 865, 1172, 1358, 1085, 1037, 335, 335, 626, + 624, 625, 335, 335, 335, 335, 335, 335, 623, 628, + 627, 622, 335, 335, 465, 221, 465, 328, 817, 81, + 81, 1125, 992, 1131, 1096, 1114, 1095, 614, 1101, 890, + 465, 510, 72, 1113, 1073, 839, 740, 1072, 896, 480, + 723, 481, 223, 81, 546, 597, 935, 1019, 334, 597, + 516, 1141, 1136, 335, 1137, 333, 81, 716, 81, 81, + 499, 1157, 1328, 1277, 1134, 1150, 975, 1164, 845, 573, + 792, 1156, 265, 273, 731, 286, 283, 1159, 285, 284, + 722, 945, 984, 1163, 520, 1168, 208, 271, 263, 596, + 589, 1169, 1170, 809, 771, 807, 1181, 1182, 806, 1148, + 1144, 595, 1091, 208, 786, 786, 1233, 1339, 726, 81, + 786, 26, 81, 81, 208, 59, 258, 19, 18, 17, + 81, 20, 16, 208, 536, 537, 529, 530, 531, 532, + 533, 534, 535, 528, 930, 931, 538, 501, 15, 14, + 451, 335, 1204, 988, 989, 1192, 30, 598, 598, 598, + 598, 598, 1205, 21, 335, 13, 12, 1193, 1206, 1195, + 11, 1213, 820, 739, 1012, 10, 9, 1090, 8, 7, + 598, 6, 5, 4, 249, 23, 2, 0, 0, 992, + 0, 0, 1237, 0, 0, 0, 0, 1247, 1246, 0, + 0, 0, 0, 744, 81, 0, 0, 0, 0, 957, + 0, 0, 81, 1026, 0, 0, 1256, 335, 0, 335, + 0, 0, 0, 912, 913, 0, 978, 0, 1210, 1211, + 0, 1212, 81, 335, 1214, 0, 1216, 0, 0, 81, + 0, 0, 0, 0, 465, 720, 0, 0, 0, 0, + 1266, 0, 1268, 0, 0, 0, 464, 0, 0, 335, + 0, 0, 597, 597, 597, 597, 597, 0, 0, 0, + 0, 0, 465, 0, 0, 0, 1279, 597, 0, 0, + 0, 0, 0, 81, 81, 597, 81, 0, 0, 0, + 0, 81, 1259, 81, 81, 81, 208, 1191, 1293, 81, + 0, 0, 845, 776, 778, 1300, 1301, 0, 1302, 1303, + 1304, 0, 1311, 1305, 1194, 1295, 0, 81, 0, 796, + 0, 0, 0, 0, 0, 1203, 1134, 0, 0, 1320, + 0, 1321, 1327, 0, 0, 0, 0, 0, 1135, 0, + 51, 0, 0, 0, 0, 0, 0, 1343, 0, 786, + 0, 0, 0, 0, 81, 0, 1350, 1087, 552, 553, + 554, 555, 556, 557, 558, 559, 81, 81, 1351, 0, + 1344, 0, 0, 0, 0, 0, 1367, 1366, 0, 1370, + 0, 0, 1134, 0, 0, 0, 81, 0, 335, 992, + 1375, 0, 0, 0, 0, 0, 0, 208, 0, 0, + 0, 0, 0, 1094, 0, 0, 81, 0, 0, 1127, + 0, 0, 0, 0, 1385, 1230, 493, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1119, 1390, 1392, + 81, 0, 0, 0, 0, 0, 1056, 335, 0, 0, + 0, 0, 0, 1405, 598, 1394, 0, 1158, 0, 0, + 1416, 0, 0, 527, 526, 536, 537, 529, 530, 531, + 532, 533, 534, 535, 528, 335, 0, 538, 0, 0, + 1097, 0, 473, 0, 474, 475, 1232, 476, 0, 479, + 0, 0, 0, 0, 845, 0, 845, 0, 489, 335, + 527, 526, 536, 537, 529, 530, 531, 532, 533, 534, + 535, 528, 0, 0, 538, 1252, 1253, 1254, 0, 0, + 953, 0, 0, 335, 954, 0, 0, 0, 0, 0, + 0, 958, 959, 960, 0, 0, 0, 0, 0, 0, + 786, 0, 973, 1138, 1140, 0, 0, 979, 0, 980, + 981, 982, 983, 465, 0, 0, 0, 0, 1094, 597, + 0, 0, 0, 0, 0, 0, 0, 1140, 0, 0, + 1235, 1007, 0, 0, 0, 0, 0, 563, 0, 0, + 335, 0, 335, 1167, 0, 1248, 0, 0, 1249, 0, + 0, 1251, 0, 0, 0, 0, 0, 0, 0, 0, + 1135, 0, 0, 1296, 0, 0, 0, 0, 1379, 0, + 0, 0, 0, 741, 0, 0, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, - 764, 765, 0, 263, 1197, 1325, 207, 1202, 1203, 213, - 0, 207, 0, 207, 0, 336, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1136, 0, 51, - 0, 0, 0, 0, 0, 0, 225, 216, 0, 226, - 227, 228, 230, 0, 229, 235, 0, 0, 0, 217, - 220, 0, 214, 234, 233, 0, 0, 0, 0, 709, - 1231, 494, 0, 0, 0, 0, 0, 0, 787, 0, - 0, 0, 0, 0, 1276, 846, 0, 0, 1101, 0, - 0, 0, 0, 0, 730, 731, 0, 0, 0, 336, - 0, 0, 0, 0, 0, 0, 0, 1262, 528, 527, - 537, 538, 530, 531, 532, 533, 534, 535, 536, 529, - 0, 0, 539, 0, 1228, 494, 0, 336, 0, 0, - 0, 0, 0, 0, 336, 0, 0, 0, 0, 0, - 0, 1404, 0, 0, 0, 0, 207, 564, 0, 207, - 783, 784, 0, 0, 0, 207, 0, 0, 0, 1225, - 494, 207, 528, 527, 537, 538, 530, 531, 532, 533, - 534, 535, 536, 529, 0, 0, 539, 0, 1298, 1299, - 0, 1300, 0, 0, 0, 0, 1262, 0, 1262, 1262, - 1262, 0, 0, 0, 1168, 0, 840, 528, 527, 537, - 538, 530, 531, 532, 533, 534, 535, 536, 529, 0, - 0, 539, 1262, 0, 0, 0, 0, 0, 0, 0, - 0, 948, 949, 950, 0, 0, 0, 0, 1208, 0, - 0, 0, 0, 0, 0, 1210, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1219, 1220, 1221, 1358, - 1224, 0, 0, 1227, 0, 1230, 0, 0, 0, 0, - 0, 336, 336, 0, 1222, 494, 0, 0, 1240, 1241, - 1242, 1229, 1245, 207, 207, 207, 0, 0, 787, 0, - 0, 1378, 0, 0, 0, 0, 0, 0, 0, 1256, - 0, 0, 0, 0, 0, 931, 932, 0, 502, 0, - 0, 1385, 528, 527, 537, 538, 530, 531, 532, 533, - 534, 535, 536, 529, 0, 0, 539, 0, 0, 0, - 0, 0, 0, 0, 0, 1262, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 24, 25, - 52, 27, 28, 0, 0, 528, 527, 537, 538, 530, - 531, 532, 533, 534, 535, 536, 529, 43, 0, 539, - 958, 0, 29, 48, 49, 0, 1291, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 979, 0, 0, - 0, 0, 38, 0, 0, 207, 54, 0, 0, 0, - 0, 0, 0, 0, 0, 207, 207, 0, 0, 0, - 0, 207, 0, 0, 207, 0, 0, 207, 0, 0, - 0, 693, 0, 0, 1332, 1333, 1334, 1335, 1336, 1337, - 1338, 1339, 0, 0, 0, 1099, 1100, 0, 0, 0, - 0, 0, 0, 0, 0, 1348, 1349, 1350, 1116, 1117, - 1118, 1119, 0, 1121, 1122, 1123, 1124, 31, 32, 34, - 33, 36, 0, 50, 0, 0, 0, 0, 0, 0, - 207, 0, 0, 0, 0, 0, 0, 0, 0, 693, - 0, 0, 1372, 0, 37, 44, 45, 1377, 0, 46, - 47, 35, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 39, 40, 1383, 41, 42, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1088, 0, - 0, 263, 0, 0, 0, 0, 263, 263, 0, 0, - 788, 788, 263, 0, 0, 0, 788, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 263, 263, 263, 263, - 0, 207, 1418, 1419, 0, 0, 0, 0, 0, 207, - 826, 0, 0, 207, 207, 0, 0, 0, 0, 0, - 1128, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1209, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 53, 0, 0, 0, 0, 0, 0, - 0, 523, 0, 526, 0, 0, 0, 0, 1159, 540, - 541, 542, 543, 544, 545, 546, 1226, 524, 525, 522, - 528, 527, 537, 538, 530, 531, 532, 533, 534, 535, - 536, 529, 207, 0, 539, 0, 0, 0, 0, 0, - 0, 207, 207, 0, 207, 207, 0, 0, 207, 0, - 0, 0, 0, 0, 0, 0, 0, 644, 0, 0, - 0, 0, 0, 0, 0, 207, 0, 927, 928, 0, - 207, 0, 0, 0, 0, 693, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 263, 0, 0, - 528, 527, 537, 538, 530, 531, 532, 533, 534, 535, - 536, 529, 0, 0, 539, 1282, 1283, 0, 1284, 1285, - 0, 1286, 1287, 0, 1288, 1289, 1290, 0, 0, 0, - 0, 1236, 0, 0, 0, 0, 0, 0, 564, 0, - 0, 0, 0, 0, 263, 632, 1249, 0, 0, 1250, - 0, 0, 1252, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 263, 0, 0, 0, 0, 0, 0, 0, - 0, 1223, 0, 0, 0, 788, 207, 207, 207, 207, - 207, 0, 645, 0, 0, 0, 0, 0, 1007, 0, - 0, 207, 0, 0, 0, 826, 0, 0, 0, 207, - 0, 0, 0, 0, 658, 659, 660, 661, 662, 663, - 664, 0, 665, 666, 667, 668, 669, 646, 647, 648, - 649, 630, 631, 0, 0, 633, 0, 634, 635, 636, - 637, 638, 639, 640, 641, 642, 643, 650, 651, 652, - 653, 654, 655, 656, 657, 528, 527, 537, 538, 530, - 531, 532, 533, 534, 535, 536, 529, 1098, 0, 539, - 528, 527, 537, 538, 530, 531, 532, 533, 534, 535, - 536, 529, 0, 0, 539, 0, 0, 528, 527, 537, - 538, 530, 531, 532, 533, 534, 535, 536, 529, 0, - 0, 539, 0, 0, 0, 0, 0, 1410, 0, 0, - 0, 0, 0, 0, 0, 0, 207, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 263, 0, 0, 0, - 953, 0, 0, 0, 0, 0, 0, 263, 0, 0, - 0, 0, 1370, 564, 0, 0, 0, 0, 0, 693, - 528, 527, 537, 538, 530, 531, 532, 533, 534, 535, - 536, 529, 0, 0, 539, 0, 788, 139, 0, 0, - 0, 0, 270, 0, 98, 0, 103, 0, 267, 0, - 0, 0, 120, 310, 122, 0, 0, 159, 131, 0, - 0, 0, 0, 301, 302, 0, 0, 0, 0, 0, - 0, 838, 0, 54, 0, 0, 268, 289, 288, 291, - 292, 293, 294, 0, 0, 95, 290, 295, 296, 297, - 839, 0, 0, 265, 282, 0, 309, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 207, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 279, 280, 0, 0, - 0, 0, 321, 207, 281, 0, 0, 276, 277, 278, - 283, 0, 0, 0, 207, 0, 0, 0, 0, 0, - 109, 0, 0, 207, 210, 0, 0, 319, 0, 146, - 0, 162, 111, 119, 83, 89, 0, 110, 137, 151, - 155, 0, 0, 0, 99, 0, 153, 141, 175, 0, - 142, 152, 123, 167, 147, 174, 182, 183, 164, 181, - 190, 84, 163, 173, 96, 156, 86, 171, 161, 129, - 115, 116, 85, 788, 150, 102, 107, 101, 138, 168, - 169, 100, 193, 90, 180, 88, 91, 179, 136, 166, - 172, 130, 127, 87, 170, 128, 126, 118, 105, 112, - 144, 125, 145, 113, 133, 132, 134, 0, 0, 0, - 160, 177, 194, 93, 0, 165, 184, 185, 186, 187, - 188, 189, 0, 0, 94, 108, 104, 143, 135, 92, - 114, 157, 117, 124, 149, 192, 140, 154, 97, 176, - 158, 311, 320, 317, 318, 315, 316, 314, 313, 312, - 322, 303, 304, 305, 306, 308, 0, 307, 82, 0, - 121, 191, 148, 106, 178, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 826, 0, 0, 0, - 422, 413, 0, 384, 425, 362, 376, 433, 377, 378, - 406, 348, 392, 139, 374, 0, 365, 343, 371, 344, - 363, 386, 103, 389, 361, 415, 395, 424, 120, 431, - 122, 400, 0, 159, 131, 0, 0, 388, 417, 390, - 411, 383, 407, 353, 399, 426, 375, 404, 427, 0, - 0, 0, 80, 0, 847, 848, 0, 0, 0, 0, - 0, 95, 0, 402, 421, 373, 403, 405, 342, 401, - 0, 346, 349, 432, 419, 368, 369, 1028, 0, 0, - 0, 0, 0, 788, 387, 391, 408, 381, 0, 0, - 0, 0, 0, 0, 0, 0, 366, 207, 398, 0, - 0, 0, 350, 347, 0, 0, 385, 0, 0, 0, - 352, 0, 367, 409, 0, 341, 109, 412, 418, 382, - 210, 420, 380, 379, 423, 146, 0, 162, 111, 119, - 83, 89, 0, 110, 137, 151, 155, 416, 364, 372, - 99, 370, 153, 141, 175, 397, 142, 152, 123, 167, - 147, 174, 182, 183, 164, 181, 190, 84, 163, 173, - 96, 156, 86, 171, 161, 129, 115, 116, 85, 0, - 150, 102, 107, 101, 138, 168, 169, 100, 193, 90, - 180, 88, 91, 179, 136, 166, 172, 130, 127, 87, - 170, 128, 126, 118, 105, 112, 144, 125, 145, 113, - 133, 132, 134, 0, 345, 0, 160, 177, 194, 93, - 360, 165, 184, 185, 186, 187, 188, 189, 0, 0, - 94, 108, 104, 143, 135, 92, 114, 157, 117, 124, - 149, 192, 140, 154, 97, 176, 158, 356, 359, 354, - 355, 393, 394, 428, 429, 430, 410, 351, 0, 357, - 358, 0, 414, 396, 82, 0, 121, 191, 148, 106, - 178, 422, 413, 0, 384, 425, 362, 376, 433, 377, - 378, 406, 348, 392, 139, 374, 0, 365, 343, 371, - 344, 363, 386, 103, 389, 361, 415, 395, 424, 120, - 431, 122, 400, 0, 159, 131, 0, 0, 388, 417, - 390, 411, 383, 407, 353, 399, 426, 375, 404, 427, - 0, 0, 0, 80, 0, 847, 848, 0, 0, 0, - 0, 0, 95, 0, 402, 421, 373, 403, 405, 342, - 401, 0, 346, 349, 432, 419, 368, 369, 0, 0, - 0, 0, 0, 0, 0, 387, 391, 408, 381, 0, - 0, 0, 0, 0, 0, 0, 0, 366, 0, 398, - 0, 0, 0, 350, 347, 0, 0, 385, 0, 0, - 0, 352, 0, 367, 409, 0, 341, 109, 412, 418, - 382, 210, 420, 380, 379, 423, 146, 0, 162, 111, - 119, 83, 89, 0, 110, 137, 151, 155, 416, 364, - 372, 99, 370, 153, 141, 175, 397, 142, 152, 123, - 167, 147, 174, 182, 183, 164, 181, 190, 84, 163, - 173, 96, 156, 86, 171, 161, 129, 115, 116, 85, - 0, 150, 102, 107, 101, 138, 168, 169, 100, 193, - 90, 180, 88, 91, 179, 136, 166, 172, 130, 127, - 87, 170, 128, 126, 118, 105, 112, 144, 125, 145, - 113, 133, 132, 134, 0, 345, 0, 160, 177, 194, - 93, 360, 165, 184, 185, 186, 187, 188, 189, 0, - 0, 94, 108, 104, 143, 135, 92, 114, 157, 117, - 124, 149, 192, 140, 154, 97, 176, 158, 356, 359, - 354, 355, 393, 394, 428, 429, 430, 410, 351, 0, - 357, 358, 0, 414, 396, 82, 0, 121, 191, 148, - 106, 178, 422, 413, 0, 384, 425, 362, 376, 433, - 377, 378, 406, 348, 392, 139, 374, 0, 365, 343, - 371, 344, 363, 386, 103, 389, 361, 415, 395, 424, - 120, 431, 122, 400, 0, 159, 131, 0, 0, 388, - 417, 390, 411, 383, 407, 353, 399, 426, 375, 404, - 427, 54, 0, 0, 80, 0, 0, 0, 0, 0, - 0, 0, 0, 95, 0, 402, 421, 373, 403, 405, - 342, 401, 0, 346, 349, 432, 419, 368, 369, 0, - 0, 0, 0, 0, 0, 0, 387, 391, 408, 381, - 0, 0, 0, 0, 0, 0, 0, 0, 366, 0, - 398, 0, 0, 0, 350, 347, 0, 0, 385, 0, - 0, 0, 352, 0, 367, 409, 0, 341, 109, 412, - 418, 382, 210, 420, 380, 379, 423, 146, 0, 162, - 111, 119, 83, 89, 0, 110, 137, 151, 155, 416, - 364, 372, 99, 370, 153, 141, 175, 397, 142, 152, - 123, 167, 147, 174, 182, 183, 164, 181, 190, 84, - 163, 173, 96, 156, 86, 171, 161, 129, 115, 116, - 85, 0, 150, 102, 107, 101, 138, 168, 169, 100, - 193, 90, 180, 88, 91, 179, 136, 166, 172, 130, - 127, 87, 170, 128, 126, 118, 105, 112, 144, 125, - 145, 113, 133, 132, 134, 0, 345, 0, 160, 177, - 194, 93, 360, 165, 184, 185, 186, 187, 188, 189, - 0, 0, 94, 108, 104, 143, 135, 92, 114, 157, - 117, 124, 149, 192, 140, 154, 97, 176, 158, 356, - 359, 354, 355, 393, 394, 428, 429, 430, 410, 351, - 0, 357, 358, 0, 414, 396, 82, 0, 121, 191, - 148, 106, 178, 422, 413, 0, 384, 425, 362, 376, - 433, 377, 378, 406, 348, 392, 139, 374, 0, 365, - 343, 371, 344, 363, 386, 103, 389, 361, 415, 395, - 424, 120, 431, 122, 400, 0, 159, 131, 0, 0, - 388, 417, 390, 411, 383, 407, 353, 399, 426, 375, - 404, 427, 0, 0, 0, 80, 0, 0, 0, 0, - 0, 0, 0, 0, 95, 0, 402, 421, 373, 403, - 405, 342, 401, 0, 346, 349, 432, 419, 368, 369, - 0, 0, 0, 0, 0, 0, 0, 387, 391, 408, - 381, 0, 0, 0, 0, 0, 0, 1094, 0, 366, - 0, 398, 0, 0, 0, 350, 347, 0, 0, 385, - 0, 0, 0, 352, 0, 367, 409, 0, 341, 109, - 412, 418, 382, 210, 420, 380, 379, 423, 146, 0, - 162, 111, 119, 83, 89, 0, 110, 137, 151, 155, - 416, 364, 372, 99, 370, 153, 141, 175, 397, 142, - 152, 123, 167, 147, 174, 182, 183, 164, 181, 190, - 84, 163, 173, 96, 156, 86, 171, 161, 129, 115, - 116, 85, 0, 150, 102, 107, 101, 138, 168, 169, - 100, 193, 90, 180, 88, 91, 179, 136, 166, 172, - 130, 127, 87, 170, 128, 126, 118, 105, 112, 144, - 125, 145, 113, 133, 132, 134, 0, 345, 0, 160, - 177, 194, 93, 360, 165, 184, 185, 186, 187, 188, - 189, 0, 0, 94, 108, 104, 143, 135, 92, 114, - 157, 117, 124, 149, 192, 140, 154, 97, 176, 158, - 356, 359, 354, 355, 393, 394, 428, 429, 430, 410, - 351, 0, 357, 358, 0, 414, 396, 82, 0, 121, - 191, 148, 106, 178, 422, 413, 0, 384, 425, 362, - 376, 433, 377, 378, 406, 348, 392, 139, 374, 0, - 365, 343, 371, 344, 363, 386, 103, 389, 361, 415, - 395, 424, 120, 431, 122, 400, 0, 159, 131, 0, - 0, 388, 417, 390, 411, 383, 407, 353, 399, 426, - 375, 404, 427, 0, 0, 0, 268, 0, 0, 0, - 0, 0, 0, 0, 0, 95, 0, 402, 421, 373, - 403, 405, 342, 401, 0, 346, 349, 432, 419, 368, - 369, 0, 0, 0, 0, 0, 0, 0, 387, 391, - 408, 381, 0, 0, 0, 0, 0, 0, 738, 0, - 366, 0, 398, 0, 0, 0, 350, 347, 0, 0, - 385, 0, 0, 0, 352, 0, 367, 409, 0, 341, - 109, 412, 418, 382, 210, 420, 380, 379, 423, 146, - 0, 162, 111, 119, 83, 89, 0, 110, 137, 151, - 155, 416, 364, 372, 99, 370, 153, 141, 175, 397, - 142, 152, 123, 167, 147, 174, 182, 183, 164, 181, - 190, 84, 163, 173, 96, 156, 86, 171, 161, 129, - 115, 116, 85, 0, 150, 102, 107, 101, 138, 168, - 169, 100, 193, 90, 180, 88, 91, 179, 136, 166, - 172, 130, 127, 87, 170, 128, 126, 118, 105, 112, - 144, 125, 145, 113, 133, 132, 134, 0, 345, 0, - 160, 177, 194, 93, 360, 165, 184, 185, 186, 187, - 188, 189, 0, 0, 94, 108, 104, 143, 135, 92, - 114, 157, 117, 124, 149, 192, 140, 154, 97, 176, - 158, 356, 359, 354, 355, 393, 394, 428, 429, 430, - 410, 351, 0, 357, 358, 0, 414, 396, 82, 0, - 121, 191, 148, 106, 178, 422, 413, 0, 384, 425, - 362, 376, 433, 377, 378, 406, 348, 392, 139, 374, - 0, 365, 343, 371, 344, 363, 386, 103, 389, 361, - 415, 395, 424, 120, 431, 122, 400, 0, 159, 131, - 0, 0, 388, 417, 390, 411, 383, 407, 353, 399, - 426, 375, 404, 427, 0, 0, 0, 80, 0, 0, - 0, 0, 0, 0, 0, 0, 95, 0, 402, 421, - 373, 403, 405, 342, 401, 0, 346, 349, 432, 419, - 368, 369, 0, 0, 0, 0, 0, 0, 0, 387, - 391, 408, 381, 0, 0, 0, 0, 0, 0, 0, - 0, 366, 0, 398, 0, 0, 0, 350, 347, 0, - 0, 385, 0, 0, 0, 352, 0, 367, 409, 0, - 341, 109, 412, 418, 382, 210, 420, 380, 379, 423, - 146, 0, 162, 111, 119, 83, 89, 0, 110, 137, - 151, 155, 416, 364, 372, 99, 370, 153, 141, 175, - 397, 142, 152, 123, 167, 147, 174, 182, 183, 164, - 181, 190, 84, 163, 173, 96, 156, 86, 171, 161, - 129, 115, 116, 85, 0, 150, 102, 107, 101, 138, - 168, 169, 100, 193, 90, 180, 88, 91, 179, 136, - 166, 172, 130, 127, 87, 170, 128, 126, 118, 105, - 112, 144, 125, 145, 113, 133, 132, 134, 0, 345, - 0, 160, 177, 194, 93, 360, 165, 184, 185, 186, - 187, 188, 189, 0, 0, 94, 108, 104, 143, 135, - 92, 114, 157, 117, 124, 149, 192, 140, 154, 97, - 176, 158, 356, 359, 354, 355, 393, 394, 428, 429, - 430, 410, 351, 0, 357, 358, 0, 414, 396, 82, - 0, 121, 191, 148, 106, 178, 422, 413, 0, 384, - 425, 362, 376, 433, 377, 378, 406, 348, 392, 139, - 374, 0, 365, 343, 371, 344, 363, 386, 103, 389, - 361, 415, 395, 424, 120, 431, 122, 400, 0, 159, - 131, 0, 0, 388, 417, 390, 411, 383, 407, 353, - 399, 426, 375, 404, 427, 0, 0, 0, 268, 0, - 0, 0, 0, 0, 0, 0, 0, 95, 0, 402, - 421, 373, 403, 405, 342, 401, 0, 346, 349, 432, - 419, 368, 369, 0, 0, 0, 0, 0, 0, 0, - 387, 391, 408, 381, 0, 0, 0, 0, 0, 0, - 0, 0, 366, 0, 398, 0, 0, 0, 350, 347, - 0, 0, 385, 0, 0, 0, 352, 0, 367, 409, - 0, 341, 109, 412, 418, 382, 210, 420, 380, 379, - 423, 146, 0, 162, 111, 119, 83, 89, 0, 110, - 137, 151, 155, 416, 364, 372, 99, 370, 153, 141, - 175, 397, 142, 152, 123, 167, 147, 174, 182, 183, - 164, 181, 190, 84, 163, 173, 96, 156, 86, 171, - 161, 129, 115, 116, 85, 0, 150, 102, 107, 101, - 138, 168, 169, 100, 193, 90, 180, 88, 91, 179, - 136, 166, 172, 130, 127, 87, 170, 128, 126, 118, - 105, 112, 144, 125, 145, 113, 133, 132, 134, 0, - 345, 0, 160, 177, 194, 93, 360, 165, 184, 185, - 186, 187, 188, 189, 0, 0, 94, 108, 104, 143, - 135, 92, 114, 157, 117, 124, 149, 192, 140, 154, - 97, 176, 158, 356, 359, 354, 355, 393, 394, 428, - 429, 430, 410, 351, 0, 357, 358, 0, 414, 396, - 82, 0, 121, 191, 148, 106, 178, 422, 413, 0, - 384, 425, 362, 376, 433, 377, 378, 406, 348, 392, - 139, 374, 0, 365, 343, 371, 344, 363, 386, 103, - 389, 361, 415, 395, 424, 120, 431, 122, 400, 0, - 159, 131, 0, 0, 388, 417, 390, 411, 383, 407, - 353, 399, 426, 375, 404, 427, 0, 0, 0, 80, - 0, 0, 0, 0, 0, 0, 0, 0, 95, 0, - 402, 421, 373, 403, 405, 342, 401, 0, 346, 349, - 432, 419, 368, 369, 0, 0, 0, 0, 0, 0, - 0, 387, 391, 408, 381, 0, 0, 0, 0, 0, - 0, 0, 0, 366, 0, 398, 0, 0, 0, 350, - 347, 0, 0, 385, 0, 0, 0, 352, 0, 367, - 409, 0, 341, 109, 412, 418, 382, 210, 420, 380, - 379, 423, 146, 0, 162, 111, 119, 83, 89, 0, - 110, 137, 151, 155, 416, 364, 372, 99, 370, 153, - 141, 175, 397, 142, 152, 123, 167, 147, 174, 182, - 183, 164, 181, 190, 84, 163, 173, 96, 156, 86, - 171, 161, 129, 115, 116, 85, 0, 150, 102, 107, - 101, 138, 168, 169, 100, 193, 90, 180, 88, 339, - 179, 136, 166, 172, 130, 127, 87, 170, 128, 126, - 118, 105, 112, 144, 125, 145, 113, 133, 132, 134, - 0, 345, 0, 160, 177, 194, 93, 360, 165, 184, - 185, 186, 187, 188, 189, 0, 0, 94, 108, 104, - 143, 340, 338, 114, 157, 117, 124, 149, 192, 140, - 154, 97, 176, 158, 356, 359, 354, 355, 393, 394, - 428, 429, 430, 410, 351, 0, 357, 358, 0, 414, - 396, 82, 0, 121, 191, 148, 106, 178, 422, 413, - 0, 384, 425, 362, 376, 433, 377, 378, 406, 348, - 392, 139, 374, 0, 365, 343, 371, 344, 363, 386, - 103, 389, 361, 415, 395, 424, 120, 431, 122, 400, - 0, 159, 131, 0, 0, 388, 417, 390, 411, 383, - 407, 353, 399, 426, 375, 404, 427, 0, 0, 0, - 208, 0, 0, 0, 0, 0, 0, 0, 0, 95, - 0, 402, 421, 373, 403, 405, 342, 401, 0, 346, - 349, 432, 419, 368, 369, 0, 0, 0, 0, 0, - 0, 0, 387, 391, 408, 381, 0, 0, 0, 0, - 0, 0, 0, 0, 366, 0, 398, 0, 0, 0, - 350, 347, 0, 0, 385, 0, 0, 0, 352, 0, - 367, 409, 0, 341, 109, 412, 418, 382, 210, 420, - 380, 379, 423, 146, 0, 162, 111, 119, 83, 89, - 0, 110, 137, 151, 155, 416, 364, 372, 99, 370, - 153, 141, 175, 397, 142, 152, 123, 167, 147, 174, - 182, 183, 164, 181, 190, 84, 163, 173, 96, 156, - 86, 171, 161, 129, 115, 116, 85, 0, 150, 102, - 107, 101, 138, 168, 169, 100, 193, 90, 180, 88, - 91, 179, 136, 166, 172, 130, 127, 87, 170, 128, - 126, 118, 105, 112, 144, 125, 145, 113, 133, 132, - 134, 0, 345, 0, 160, 177, 194, 93, 360, 165, - 184, 185, 186, 187, 188, 189, 0, 0, 94, 108, - 104, 143, 135, 92, 114, 157, 117, 124, 149, 192, - 140, 154, 97, 176, 158, 356, 359, 354, 355, 393, - 394, 428, 429, 430, 410, 351, 0, 357, 358, 0, - 414, 396, 82, 0, 121, 191, 148, 106, 178, 422, - 413, 0, 384, 425, 362, 376, 433, 377, 378, 406, - 348, 392, 139, 374, 0, 365, 343, 371, 344, 363, - 386, 103, 389, 361, 415, 395, 424, 120, 431, 122, - 400, 0, 159, 131, 0, 0, 388, 417, 390, 411, - 383, 407, 353, 399, 426, 375, 404, 427, 0, 0, + 764, 0, 845, 1196, 1324, 0, 1201, 1202, 0, 0, + 0, 0, 0, 0, 335, 0, 0, 498, 0, 0, + 0, 0, 522, 0, 525, 0, 1135, 0, 51, 0, + 539, 540, 541, 542, 543, 544, 545, 1275, 523, 524, + 521, 527, 526, 536, 537, 529, 530, 531, 532, 533, + 534, 535, 528, 206, 0, 538, 235, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 786, 0, 0, + 0, 0, 0, 0, 0, 0, 670, 1100, 0, 0, + 0, 262, 0, 677, 206, 0, 0, 0, 335, 206, + 0, 206, 0, 0, 0, 0, 1261, 0, 0, 694, + 695, 0, 0, 0, 696, 697, 698, 699, 700, 701, + 1227, 493, 0, 0, 702, 703, 335, 0, 0, 0, + 0, 0, 0, 335, 0, 0, 0, 0, 0, 0, + 1403, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1369, 563, 0, 0, 0, 1224, 493, 527, 526, + 536, 537, 529, 530, 531, 532, 533, 534, 535, 528, + 0, 0, 538, 0, 1275, 845, 0, 1297, 1298, 0, + 1299, 0, 0, 0, 0, 1261, 0, 1261, 1261, 1261, + 0, 0, 0, 1167, 527, 526, 536, 537, 529, 530, + 531, 532, 533, 534, 535, 528, 0, 0, 538, 0, + 0, 1261, 0, 0, 0, 0, 0, 0, 0, 0, + 947, 948, 949, 206, 0, 0, 206, 1207, 0, 0, + 0, 0, 206, 0, 1209, 0, 0, 0, 206, 0, + 0, 0, 0, 0, 0, 1218, 1219, 1220, 1357, 1223, + 0, 0, 1226, 0, 1229, 0, 0, 0, 0, 0, + 335, 335, 0, 0, 0, 0, 0, 1239, 1240, 1241, + 0, 1244, 0, 0, 0, 0, 0, 786, 0, 0, + 1377, 0, 0, 0, 0, 0, 0, 0, 1255, 0, + 24, 25, 52, 27, 28, 0, 0, 0, 0, 0, + 1384, 0, 0, 0, 0, 0, 0, 0, 0, 43, + 0, 0, 0, 0, 29, 48, 49, 0, 0, 893, + 0, 895, 0, 0, 1261, 0, 0, 0, 1221, 493, + 0, 0, 0, 0, 38, 921, 0, 0, 54, 0, + 0, 0, 0, 0, 493, 0, 0, 0, 0, 0, + 206, 206, 206, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1290, 527, 526, 536, 537, + 529, 530, 531, 532, 533, 534, 535, 528, 0, 0, + 538, 527, 526, 536, 537, 529, 530, 531, 532, 533, + 534, 535, 528, 0, 0, 538, 0, 0, 0, 31, + 32, 34, 33, 36, 0, 50, 0, 0, 0, 0, + 0, 0, 0, 1331, 1332, 1333, 1334, 1335, 1336, 1337, + 1338, 0, 0, 1231, 1098, 1099, 37, 44, 45, 0, + 0, 46, 47, 35, 1347, 1348, 1349, 1115, 1116, 1117, + 1118, 1228, 1120, 1121, 1122, 1123, 39, 40, 0, 41, + 42, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 206, 0, 0, 0, 0, 0, 0, 0, + 0, 1371, 206, 206, 1225, 0, 1376, 0, 206, 0, + 0, 206, 0, 0, 206, 0, 0, 0, 692, 0, + 0, 0, 0, 0, 0, 1382, 643, 527, 526, 536, + 537, 529, 530, 531, 532, 533, 534, 535, 528, 0, + 0, 538, 0, 0, 0, 527, 526, 536, 537, 529, + 530, 531, 532, 533, 534, 535, 528, 0, 0, 538, + 0, 0, 0, 0, 0, 53, 0, 206, 0, 1057, + 0, 1417, 1418, 0, 0, 0, 692, 0, 527, 526, + 536, 537, 529, 530, 531, 532, 533, 534, 535, 528, + 0, 0, 538, 0, 0, 0, 0, 1084, 0, 0, + 1208, 0, 0, 0, 631, 527, 526, 536, 537, 529, + 530, 531, 532, 533, 534, 535, 528, 0, 262, 538, + 0, 0, 0, 262, 262, 0, 0, 787, 787, 262, + 1222, 0, 0, 787, 0, 0, 0, 0, 0, 0, + 0, 644, 0, 262, 262, 262, 262, 0, 206, 0, + 0, 0, 0, 0, 0, 0, 206, 825, 0, 0, + 206, 206, 0, 657, 658, 659, 660, 661, 662, 663, + 0, 664, 665, 666, 667, 668, 645, 646, 647, 648, + 629, 630, 0, 0, 632, 0, 633, 634, 635, 636, + 637, 638, 639, 640, 641, 642, 649, 650, 651, 652, + 653, 654, 655, 656, 527, 526, 536, 537, 529, 530, + 531, 532, 533, 534, 535, 528, 0, 0, 538, 0, + 0, 0, 0, 0, 1281, 1282, 952, 1283, 1284, 206, + 1285, 1286, 0, 1287, 1288, 1289, 0, 0, 206, 206, + 0, 206, 206, 0, 0, 206, 527, 526, 536, 537, + 529, 530, 531, 532, 533, 534, 535, 528, 0, 0, + 538, 0, 206, 0, 926, 927, 0, 206, 0, 0, + 0, 0, 692, 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, 0, 0, 0, 0, 0, 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, 0, 787, 206, 206, 206, 206, 206, 1271, 0, + 0, 0, 0, 0, 0, 1006, 0, 0, 206, 0, + 0, 0, 825, 0, 0, 0, 206, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1409, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 206, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 262, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 262, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 692, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 787, 138, 0, 0, 0, 0, 269, + 0, 0, 0, 102, 0, 266, 0, 0, 0, 119, + 309, 121, 0, 0, 158, 130, 0, 0, 0, 0, + 300, 301, 0, 0, 0, 0, 0, 0, 837, 0, + 54, 0, 0, 267, 288, 287, 290, 291, 292, 293, + 0, 0, 95, 289, 294, 295, 296, 838, 0, 0, + 264, 281, 0, 308, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 206, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 278, 279, 0, 0, 0, 0, 320, + 206, 280, 0, 0, 275, 276, 277, 282, 0, 0, + 0, 206, 0, 0, 0, 0, 0, 108, 0, 0, + 206, 209, 0, 0, 318, 0, 145, 0, 161, 110, + 118, 83, 89, 0, 109, 136, 150, 154, 0, 0, + 0, 98, 0, 152, 140, 174, 0, 141, 151, 122, + 166, 146, 173, 181, 182, 163, 180, 189, 84, 162, + 172, 96, 155, 86, 170, 160, 128, 114, 115, 85, + 787, 149, 101, 106, 100, 137, 167, 168, 99, 192, + 90, 179, 88, 91, 178, 135, 165, 171, 129, 126, + 87, 169, 127, 125, 117, 104, 111, 143, 124, 144, + 112, 132, 131, 133, 0, 0, 0, 159, 176, 193, + 93, 0, 164, 183, 184, 185, 186, 187, 188, 0, + 0, 94, 107, 103, 142, 134, 92, 113, 156, 116, + 123, 148, 191, 139, 153, 97, 175, 157, 310, 319, + 316, 317, 314, 315, 313, 312, 311, 321, 302, 303, + 304, 305, 307, 0, 306, 82, 0, 120, 190, 147, + 105, 177, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 825, 0, 0, 0, 421, 412, 0, + 383, 424, 361, 375, 432, 376, 377, 405, 347, 391, + 138, 373, 0, 364, 342, 370, 343, 362, 385, 102, + 388, 360, 414, 394, 423, 119, 430, 121, 399, 0, + 158, 130, 0, 0, 387, 416, 389, 410, 382, 406, + 352, 398, 425, 374, 403, 426, 0, 0, 0, 80, + 0, 846, 847, 0, 0, 0, 0, 0, 95, 0, + 401, 420, 372, 402, 404, 341, 400, 0, 345, 348, + 431, 418, 367, 368, 1027, 0, 0, 0, 0, 0, + 787, 386, 390, 407, 380, 0, 0, 0, 0, 0, + 0, 0, 0, 365, 206, 397, 0, 0, 0, 349, + 346, 0, 0, 384, 0, 0, 0, 351, 0, 366, + 408, 0, 340, 108, 411, 417, 381, 209, 419, 379, + 378, 422, 145, 0, 161, 110, 118, 83, 89, 0, + 109, 136, 150, 154, 415, 363, 371, 98, 369, 152, + 140, 174, 396, 141, 151, 122, 166, 146, 173, 181, + 182, 163, 180, 189, 84, 162, 172, 96, 155, 86, + 170, 160, 128, 114, 115, 85, 0, 149, 101, 106, + 100, 137, 167, 168, 99, 192, 90, 179, 88, 91, + 178, 135, 165, 171, 129, 126, 87, 169, 127, 125, + 117, 104, 111, 143, 124, 144, 112, 132, 131, 133, + 0, 344, 0, 159, 176, 193, 93, 359, 164, 183, + 184, 185, 186, 187, 188, 0, 0, 94, 107, 103, + 142, 134, 92, 113, 156, 116, 123, 148, 191, 139, + 153, 97, 175, 157, 355, 358, 353, 354, 392, 393, + 427, 428, 429, 409, 350, 0, 356, 357, 0, 413, + 395, 82, 0, 120, 190, 147, 105, 177, 421, 412, + 0, 383, 424, 361, 375, 432, 376, 377, 405, 347, + 391, 138, 373, 0, 364, 342, 370, 343, 362, 385, + 102, 388, 360, 414, 394, 423, 119, 430, 121, 399, + 0, 158, 130, 0, 0, 387, 416, 389, 410, 382, + 406, 352, 398, 425, 374, 403, 426, 0, 0, 0, + 80, 0, 846, 847, 0, 0, 0, 0, 0, 95, + 0, 401, 420, 372, 402, 404, 341, 400, 0, 345, + 348, 431, 418, 367, 368, 0, 0, 0, 0, 0, + 0, 0, 386, 390, 407, 380, 0, 0, 0, 0, + 0, 0, 0, 0, 365, 0, 397, 0, 0, 0, + 349, 346, 0, 0, 384, 0, 0, 0, 351, 0, + 366, 408, 0, 340, 108, 411, 417, 381, 209, 419, + 379, 378, 422, 145, 0, 161, 110, 118, 83, 89, + 0, 109, 136, 150, 154, 415, 363, 371, 98, 369, + 152, 140, 174, 396, 141, 151, 122, 166, 146, 173, + 181, 182, 163, 180, 189, 84, 162, 172, 96, 155, + 86, 170, 160, 128, 114, 115, 85, 0, 149, 101, + 106, 100, 137, 167, 168, 99, 192, 90, 179, 88, + 91, 178, 135, 165, 171, 129, 126, 87, 169, 127, + 125, 117, 104, 111, 143, 124, 144, 112, 132, 131, + 133, 0, 344, 0, 159, 176, 193, 93, 359, 164, + 183, 184, 185, 186, 187, 188, 0, 0, 94, 107, + 103, 142, 134, 92, 113, 156, 116, 123, 148, 191, + 139, 153, 97, 175, 157, 355, 358, 353, 354, 392, + 393, 427, 428, 429, 409, 350, 0, 356, 357, 0, + 413, 395, 82, 0, 120, 190, 147, 105, 177, 421, + 412, 0, 383, 424, 361, 375, 432, 376, 377, 405, + 347, 391, 138, 373, 0, 364, 342, 370, 343, 362, + 385, 102, 388, 360, 414, 394, 423, 119, 430, 121, + 399, 0, 158, 130, 0, 0, 387, 416, 389, 410, + 382, 406, 352, 398, 425, 374, 403, 426, 54, 0, 0, 80, 0, 0, 0, 0, 0, 0, 0, 0, - 95, 0, 402, 421, 373, 403, 405, 342, 401, 0, - 346, 349, 432, 419, 368, 369, 0, 0, 0, 0, - 0, 0, 0, 387, 391, 408, 381, 0, 0, 0, - 0, 0, 0, 0, 0, 366, 0, 398, 0, 0, - 0, 350, 347, 0, 0, 385, 0, 0, 0, 352, - 0, 367, 409, 0, 341, 109, 412, 418, 382, 210, - 420, 380, 379, 423, 146, 0, 162, 111, 119, 83, - 89, 0, 110, 137, 151, 155, 416, 364, 372, 99, - 370, 153, 141, 175, 397, 142, 152, 123, 167, 147, - 174, 182, 183, 164, 181, 190, 84, 163, 609, 96, - 156, 86, 171, 161, 129, 115, 116, 85, 0, 150, - 102, 107, 101, 138, 168, 169, 100, 193, 90, 180, - 88, 339, 179, 136, 166, 172, 130, 127, 87, 170, - 128, 126, 118, 105, 112, 144, 125, 145, 113, 133, - 132, 134, 0, 345, 0, 160, 177, 194, 93, 360, - 165, 184, 185, 186, 187, 188, 189, 0, 0, 94, - 108, 104, 143, 340, 338, 114, 157, 117, 124, 149, - 192, 140, 154, 97, 176, 158, 356, 359, 354, 355, - 393, 394, 428, 429, 430, 410, 351, 0, 357, 358, - 0, 414, 396, 82, 0, 121, 191, 148, 106, 178, - 422, 413, 0, 384, 425, 362, 376, 433, 377, 378, - 406, 348, 392, 139, 374, 0, 365, 343, 371, 344, - 363, 386, 103, 389, 361, 415, 395, 424, 120, 431, - 122, 400, 0, 159, 131, 0, 0, 388, 417, 390, - 411, 383, 407, 353, 399, 426, 375, 404, 427, 0, + 95, 0, 401, 420, 372, 402, 404, 341, 400, 0, + 345, 348, 431, 418, 367, 368, 0, 0, 0, 0, + 0, 0, 0, 386, 390, 407, 380, 0, 0, 0, + 0, 0, 0, 0, 0, 365, 0, 397, 0, 0, + 0, 349, 346, 0, 0, 384, 0, 0, 0, 351, + 0, 366, 408, 0, 340, 108, 411, 417, 381, 209, + 419, 379, 378, 422, 145, 0, 161, 110, 118, 83, + 89, 0, 109, 136, 150, 154, 415, 363, 371, 98, + 369, 152, 140, 174, 396, 141, 151, 122, 166, 146, + 173, 181, 182, 163, 180, 189, 84, 162, 172, 96, + 155, 86, 170, 160, 128, 114, 115, 85, 0, 149, + 101, 106, 100, 137, 167, 168, 99, 192, 90, 179, + 88, 91, 178, 135, 165, 171, 129, 126, 87, 169, + 127, 125, 117, 104, 111, 143, 124, 144, 112, 132, + 131, 133, 0, 344, 0, 159, 176, 193, 93, 359, + 164, 183, 184, 185, 186, 187, 188, 0, 0, 94, + 107, 103, 142, 134, 92, 113, 156, 116, 123, 148, + 191, 139, 153, 97, 175, 157, 355, 358, 353, 354, + 392, 393, 427, 428, 429, 409, 350, 0, 356, 357, + 0, 413, 395, 82, 0, 120, 190, 147, 105, 177, + 421, 412, 0, 383, 424, 361, 375, 432, 376, 377, + 405, 347, 391, 138, 373, 0, 364, 342, 370, 343, + 362, 385, 102, 388, 360, 414, 394, 423, 119, 430, + 121, 399, 0, 158, 130, 0, 0, 387, 416, 389, + 410, 382, 406, 352, 398, 425, 374, 403, 426, 0, 0, 0, 80, 0, 0, 0, 0, 0, 0, 0, - 0, 95, 0, 402, 421, 373, 403, 405, 342, 401, - 0, 346, 349, 432, 419, 368, 369, 0, 0, 0, - 0, 0, 0, 0, 387, 391, 408, 381, 0, 0, - 0, 0, 0, 0, 0, 0, 366, 0, 398, 0, - 0, 0, 350, 347, 0, 0, 385, 0, 0, 0, - 352, 0, 367, 409, 0, 341, 109, 412, 418, 382, - 210, 420, 380, 379, 423, 146, 0, 162, 111, 119, - 83, 89, 0, 110, 137, 151, 155, 416, 364, 372, - 99, 370, 153, 141, 175, 397, 142, 152, 123, 167, - 147, 174, 182, 183, 164, 181, 190, 84, 163, 330, - 96, 156, 86, 171, 161, 129, 115, 116, 85, 0, - 150, 102, 107, 101, 138, 168, 169, 100, 193, 90, - 180, 88, 339, 179, 136, 166, 172, 130, 127, 87, - 170, 128, 126, 118, 105, 112, 144, 125, 145, 113, - 133, 132, 134, 0, 345, 0, 160, 177, 194, 93, - 360, 165, 184, 185, 186, 187, 188, 189, 0, 0, - 94, 108, 104, 143, 340, 338, 333, 332, 117, 124, - 149, 192, 140, 154, 97, 176, 158, 356, 359, 354, - 355, 393, 394, 428, 429, 430, 410, 351, 0, 357, - 358, 0, 414, 396, 82, 0, 121, 191, 148, 106, - 178, 139, 0, 0, 774, 0, 270, 0, 98, 0, - 103, 0, 267, 0, 0, 0, 120, 310, 122, 0, - 0, 159, 131, 0, 0, 0, 0, 301, 302, 0, + 0, 95, 0, 401, 420, 372, 402, 404, 341, 400, + 0, 345, 348, 431, 418, 367, 368, 0, 0, 0, + 0, 0, 0, 0, 386, 390, 407, 380, 0, 0, + 0, 0, 0, 0, 1093, 0, 365, 0, 397, 0, + 0, 0, 349, 346, 0, 0, 384, 0, 0, 0, + 351, 0, 366, 408, 0, 340, 108, 411, 417, 381, + 209, 419, 379, 378, 422, 145, 0, 161, 110, 118, + 83, 89, 0, 109, 136, 150, 154, 415, 363, 371, + 98, 369, 152, 140, 174, 396, 141, 151, 122, 166, + 146, 173, 181, 182, 163, 180, 189, 84, 162, 172, + 96, 155, 86, 170, 160, 128, 114, 115, 85, 0, + 149, 101, 106, 100, 137, 167, 168, 99, 192, 90, + 179, 88, 91, 178, 135, 165, 171, 129, 126, 87, + 169, 127, 125, 117, 104, 111, 143, 124, 144, 112, + 132, 131, 133, 0, 344, 0, 159, 176, 193, 93, + 359, 164, 183, 184, 185, 186, 187, 188, 0, 0, + 94, 107, 103, 142, 134, 92, 113, 156, 116, 123, + 148, 191, 139, 153, 97, 175, 157, 355, 358, 353, + 354, 392, 393, 427, 428, 429, 409, 350, 0, 356, + 357, 0, 413, 395, 82, 0, 120, 190, 147, 105, + 177, 421, 412, 0, 383, 424, 361, 375, 432, 376, + 377, 405, 347, 391, 138, 373, 0, 364, 342, 370, + 343, 362, 385, 102, 388, 360, 414, 394, 423, 119, + 430, 121, 399, 0, 158, 130, 0, 0, 387, 416, + 389, 410, 382, 406, 352, 398, 425, 374, 403, 426, + 0, 0, 0, 267, 0, 0, 0, 0, 0, 0, + 0, 0, 95, 0, 401, 420, 372, 402, 404, 341, + 400, 0, 345, 348, 431, 418, 367, 368, 0, 0, + 0, 0, 0, 0, 0, 386, 390, 407, 380, 0, + 0, 0, 0, 0, 0, 737, 0, 365, 0, 397, + 0, 0, 0, 349, 346, 0, 0, 384, 0, 0, + 0, 351, 0, 366, 408, 0, 340, 108, 411, 417, + 381, 209, 419, 379, 378, 422, 145, 0, 161, 110, + 118, 83, 89, 0, 109, 136, 150, 154, 415, 363, + 371, 98, 369, 152, 140, 174, 396, 141, 151, 122, + 166, 146, 173, 181, 182, 163, 180, 189, 84, 162, + 172, 96, 155, 86, 170, 160, 128, 114, 115, 85, + 0, 149, 101, 106, 100, 137, 167, 168, 99, 192, + 90, 179, 88, 91, 178, 135, 165, 171, 129, 126, + 87, 169, 127, 125, 117, 104, 111, 143, 124, 144, + 112, 132, 131, 133, 0, 344, 0, 159, 176, 193, + 93, 359, 164, 183, 184, 185, 186, 187, 188, 0, + 0, 94, 107, 103, 142, 134, 92, 113, 156, 116, + 123, 148, 191, 139, 153, 97, 175, 157, 355, 358, + 353, 354, 392, 393, 427, 428, 429, 409, 350, 0, + 356, 357, 0, 413, 395, 82, 0, 120, 190, 147, + 105, 177, 421, 412, 0, 383, 424, 361, 375, 432, + 376, 377, 405, 347, 391, 138, 373, 0, 364, 342, + 370, 343, 362, 385, 102, 388, 360, 414, 394, 423, + 119, 430, 121, 399, 0, 158, 130, 0, 0, 387, + 416, 389, 410, 382, 406, 352, 398, 425, 374, 403, + 426, 0, 0, 0, 80, 0, 0, 0, 0, 0, + 0, 0, 0, 95, 0, 401, 420, 372, 402, 404, + 341, 400, 0, 345, 348, 431, 418, 367, 368, 0, + 0, 0, 0, 0, 0, 0, 386, 390, 407, 380, + 0, 0, 0, 0, 0, 0, 0, 0, 365, 0, + 397, 0, 0, 0, 349, 346, 0, 0, 384, 0, + 0, 0, 351, 0, 366, 408, 0, 340, 108, 411, + 417, 381, 209, 419, 379, 378, 422, 145, 0, 161, + 110, 118, 83, 89, 0, 109, 136, 150, 154, 415, + 363, 371, 98, 369, 152, 140, 174, 396, 141, 151, + 122, 166, 146, 173, 181, 182, 163, 180, 189, 84, + 162, 172, 96, 155, 86, 170, 160, 128, 114, 115, + 85, 0, 149, 101, 106, 100, 137, 167, 168, 99, + 192, 90, 179, 88, 91, 178, 135, 165, 171, 129, + 126, 87, 169, 127, 125, 117, 104, 111, 143, 124, + 144, 112, 132, 131, 133, 0, 344, 0, 159, 176, + 193, 93, 359, 164, 183, 184, 185, 186, 187, 188, + 0, 0, 94, 107, 103, 142, 134, 92, 113, 156, + 116, 123, 148, 191, 139, 153, 97, 175, 157, 355, + 358, 353, 354, 392, 393, 427, 428, 429, 409, 350, + 0, 356, 357, 0, 413, 395, 82, 0, 120, 190, + 147, 105, 177, 421, 412, 0, 383, 424, 361, 375, + 432, 376, 377, 405, 347, 391, 138, 373, 0, 364, + 342, 370, 343, 362, 385, 102, 388, 360, 414, 394, + 423, 119, 430, 121, 399, 0, 158, 130, 0, 0, + 387, 416, 389, 410, 382, 406, 352, 398, 425, 374, + 403, 426, 0, 0, 0, 267, 0, 0, 0, 0, + 0, 0, 0, 0, 95, 0, 401, 420, 372, 402, + 404, 341, 400, 0, 345, 348, 431, 418, 367, 368, + 0, 0, 0, 0, 0, 0, 0, 386, 390, 407, + 380, 0, 0, 0, 0, 0, 0, 0, 0, 365, + 0, 397, 0, 0, 0, 349, 346, 0, 0, 384, + 0, 0, 0, 351, 0, 366, 408, 0, 340, 108, + 411, 417, 381, 209, 419, 379, 378, 422, 145, 0, + 161, 110, 118, 83, 89, 0, 109, 136, 150, 154, + 415, 363, 371, 98, 369, 152, 140, 174, 396, 141, + 151, 122, 166, 146, 173, 181, 182, 163, 180, 189, + 84, 162, 172, 96, 155, 86, 170, 160, 128, 114, + 115, 85, 0, 149, 101, 106, 100, 137, 167, 168, + 99, 192, 90, 179, 88, 91, 178, 135, 165, 171, + 129, 126, 87, 169, 127, 125, 117, 104, 111, 143, + 124, 144, 112, 132, 131, 133, 0, 344, 0, 159, + 176, 193, 93, 359, 164, 183, 184, 185, 186, 187, + 188, 0, 0, 94, 107, 103, 142, 134, 92, 113, + 156, 116, 123, 148, 191, 139, 153, 97, 175, 157, + 355, 358, 353, 354, 392, 393, 427, 428, 429, 409, + 350, 0, 356, 357, 0, 413, 395, 82, 0, 120, + 190, 147, 105, 177, 421, 412, 0, 383, 424, 361, + 375, 432, 376, 377, 405, 347, 391, 138, 373, 0, + 364, 342, 370, 343, 362, 385, 102, 388, 360, 414, + 394, 423, 119, 430, 121, 399, 0, 158, 130, 0, + 0, 387, 416, 389, 410, 382, 406, 352, 398, 425, + 374, 403, 426, 0, 0, 0, 80, 0, 0, 0, + 0, 0, 0, 0, 0, 95, 0, 401, 420, 372, + 402, 404, 341, 400, 0, 345, 348, 431, 418, 367, + 368, 0, 0, 0, 0, 0, 0, 0, 386, 390, + 407, 380, 0, 0, 0, 0, 0, 0, 0, 0, + 365, 0, 397, 0, 0, 0, 349, 346, 0, 0, + 384, 0, 0, 0, 351, 0, 366, 408, 0, 340, + 108, 411, 417, 381, 209, 419, 379, 378, 422, 145, + 0, 161, 110, 118, 83, 89, 0, 109, 136, 150, + 154, 415, 363, 371, 98, 369, 152, 140, 174, 396, + 141, 151, 122, 166, 146, 173, 181, 182, 163, 180, + 189, 84, 162, 172, 96, 155, 86, 170, 160, 128, + 114, 115, 85, 0, 149, 101, 106, 100, 137, 167, + 168, 99, 192, 90, 179, 88, 338, 178, 135, 165, + 171, 129, 126, 87, 169, 127, 125, 117, 104, 111, + 143, 124, 144, 112, 132, 131, 133, 0, 344, 0, + 159, 176, 193, 93, 359, 164, 183, 184, 185, 186, + 187, 188, 0, 0, 94, 107, 103, 142, 339, 337, + 113, 156, 116, 123, 148, 191, 139, 153, 97, 175, + 157, 355, 358, 353, 354, 392, 393, 427, 428, 429, + 409, 350, 0, 356, 357, 0, 413, 395, 82, 0, + 120, 190, 147, 105, 177, 421, 412, 0, 383, 424, + 361, 375, 432, 376, 377, 405, 347, 391, 138, 373, + 0, 364, 342, 370, 343, 362, 385, 102, 388, 360, + 414, 394, 423, 119, 430, 121, 399, 0, 158, 130, + 0, 0, 387, 416, 389, 410, 382, 406, 352, 398, + 425, 374, 403, 426, 0, 0, 0, 207, 0, 0, + 0, 0, 0, 0, 0, 0, 95, 0, 401, 420, + 372, 402, 404, 341, 400, 0, 345, 348, 431, 418, + 367, 368, 0, 0, 0, 0, 0, 0, 0, 386, + 390, 407, 380, 0, 0, 0, 0, 0, 0, 0, + 0, 365, 0, 397, 0, 0, 0, 349, 346, 0, + 0, 384, 0, 0, 0, 351, 0, 366, 408, 0, + 340, 108, 411, 417, 381, 209, 419, 379, 378, 422, + 145, 0, 161, 110, 118, 83, 89, 0, 109, 136, + 150, 154, 415, 363, 371, 98, 369, 152, 140, 174, + 396, 141, 151, 122, 166, 146, 173, 181, 182, 163, + 180, 189, 84, 162, 172, 96, 155, 86, 170, 160, + 128, 114, 115, 85, 0, 149, 101, 106, 100, 137, + 167, 168, 99, 192, 90, 179, 88, 91, 178, 135, + 165, 171, 129, 126, 87, 169, 127, 125, 117, 104, + 111, 143, 124, 144, 112, 132, 131, 133, 0, 344, + 0, 159, 176, 193, 93, 359, 164, 183, 184, 185, + 186, 187, 188, 0, 0, 94, 107, 103, 142, 134, + 92, 113, 156, 116, 123, 148, 191, 139, 153, 97, + 175, 157, 355, 358, 353, 354, 392, 393, 427, 428, + 429, 409, 350, 0, 356, 357, 0, 413, 395, 82, + 0, 120, 190, 147, 105, 177, 421, 412, 0, 383, + 424, 361, 375, 432, 376, 377, 405, 347, 391, 138, + 373, 0, 364, 342, 370, 343, 362, 385, 102, 388, + 360, 414, 394, 423, 119, 430, 121, 399, 0, 158, + 130, 0, 0, 387, 416, 389, 410, 382, 406, 352, + 398, 425, 374, 403, 426, 0, 0, 0, 80, 0, + 0, 0, 0, 0, 0, 0, 0, 95, 0, 401, + 420, 372, 402, 404, 341, 400, 0, 345, 348, 431, + 418, 367, 368, 0, 0, 0, 0, 0, 0, 0, + 386, 390, 407, 380, 0, 0, 0, 0, 0, 0, + 0, 0, 365, 0, 397, 0, 0, 0, 349, 346, + 0, 0, 384, 0, 0, 0, 351, 0, 366, 408, + 0, 340, 108, 411, 417, 381, 209, 419, 379, 378, + 422, 145, 0, 161, 110, 118, 83, 89, 0, 109, + 136, 150, 154, 415, 363, 371, 98, 369, 152, 140, + 174, 396, 141, 151, 122, 166, 146, 173, 181, 182, + 163, 180, 189, 84, 162, 608, 96, 155, 86, 170, + 160, 128, 114, 115, 85, 0, 149, 101, 106, 100, + 137, 167, 168, 99, 192, 90, 179, 88, 338, 178, + 135, 165, 171, 129, 126, 87, 169, 127, 125, 117, + 104, 111, 143, 124, 144, 112, 132, 131, 133, 0, + 344, 0, 159, 176, 193, 93, 359, 164, 183, 184, + 185, 186, 187, 188, 0, 0, 94, 107, 103, 142, + 339, 337, 113, 156, 116, 123, 148, 191, 139, 153, + 97, 175, 157, 355, 358, 353, 354, 392, 393, 427, + 428, 429, 409, 350, 0, 356, 357, 0, 413, 395, + 82, 0, 120, 190, 147, 105, 177, 421, 412, 0, + 383, 424, 361, 375, 432, 376, 377, 405, 347, 391, + 138, 373, 0, 364, 342, 370, 343, 362, 385, 102, + 388, 360, 414, 394, 423, 119, 430, 121, 399, 0, + 158, 130, 0, 0, 387, 416, 389, 410, 382, 406, + 352, 398, 425, 374, 403, 426, 0, 0, 0, 80, + 0, 0, 0, 0, 0, 0, 0, 0, 95, 0, + 401, 420, 372, 402, 404, 341, 400, 0, 345, 348, + 431, 418, 367, 368, 0, 0, 0, 0, 0, 0, + 0, 386, 390, 407, 380, 0, 0, 0, 0, 0, + 0, 0, 0, 365, 0, 397, 0, 0, 0, 349, + 346, 0, 0, 384, 0, 0, 0, 351, 0, 366, + 408, 0, 340, 108, 411, 417, 381, 209, 419, 379, + 378, 422, 145, 0, 161, 110, 118, 83, 89, 0, + 109, 136, 150, 154, 415, 363, 371, 98, 369, 152, + 140, 174, 396, 141, 151, 122, 166, 146, 173, 181, + 182, 163, 180, 189, 84, 162, 329, 96, 155, 86, + 170, 160, 128, 114, 115, 85, 0, 149, 101, 106, + 100, 137, 167, 168, 99, 192, 90, 179, 88, 338, + 178, 135, 165, 171, 129, 126, 87, 169, 127, 125, + 117, 104, 111, 143, 124, 144, 112, 132, 131, 133, + 0, 344, 0, 159, 176, 193, 93, 359, 164, 183, + 184, 185, 186, 187, 188, 0, 0, 94, 107, 103, + 142, 339, 337, 332, 331, 116, 123, 148, 191, 139, + 153, 97, 175, 157, 355, 358, 353, 354, 392, 393, + 427, 428, 429, 409, 350, 0, 356, 357, 0, 413, + 395, 82, 0, 120, 190, 147, 105, 177, 138, 0, + 0, 773, 0, 269, 0, 0, 0, 102, 0, 266, + 0, 0, 0, 119, 309, 121, 0, 0, 158, 130, + 0, 0, 0, 0, 300, 301, 0, 0, 0, 0, + 0, 0, 0, 0, 54, 0, 0, 267, 288, 287, + 290, 291, 292, 293, 0, 0, 95, 289, 294, 295, + 296, 0, 0, 0, 264, 281, 0, 308, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 278, 279, 260, + 0, 0, 0, 320, 0, 280, 0, 0, 275, 276, + 277, 282, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 108, 0, 0, 0, 209, 0, 0, 318, 0, + 145, 0, 161, 110, 118, 83, 89, 0, 109, 136, + 150, 154, 0, 0, 0, 98, 0, 152, 140, 174, + 0, 141, 151, 122, 166, 146, 173, 181, 182, 163, + 180, 189, 84, 162, 172, 96, 155, 86, 170, 160, + 128, 114, 115, 85, 0, 149, 101, 106, 100, 137, + 167, 168, 99, 192, 90, 179, 88, 91, 178, 135, + 165, 171, 129, 126, 87, 169, 127, 125, 117, 104, + 111, 143, 124, 144, 112, 132, 131, 133, 0, 0, + 0, 159, 176, 193, 93, 0, 164, 183, 184, 185, + 186, 187, 188, 0, 0, 94, 107, 103, 142, 134, + 92, 113, 156, 116, 123, 148, 191, 139, 153, 97, + 175, 157, 310, 319, 316, 317, 314, 315, 313, 312, + 311, 321, 302, 303, 304, 305, 307, 0, 306, 82, + 0, 120, 190, 147, 105, 177, 138, 0, 0, 0, + 0, 269, 0, 0, 0, 102, 0, 266, 0, 0, + 0, 119, 309, 121, 0, 0, 158, 130, 0, 0, + 0, 0, 300, 301, 0, 0, 0, 0, 0, 0, + 0, 0, 54, 0, 493, 267, 288, 287, 290, 291, + 292, 293, 0, 0, 95, 289, 294, 295, 296, 0, + 0, 0, 264, 281, 0, 308, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 278, 279, 0, 0, 0, + 0, 320, 0, 280, 0, 0, 275, 276, 277, 282, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 108, + 0, 0, 0, 209, 0, 0, 318, 0, 145, 0, + 161, 110, 118, 83, 89, 0, 109, 136, 150, 154, + 0, 0, 0, 98, 0, 152, 140, 174, 0, 141, + 151, 122, 166, 146, 173, 181, 182, 163, 180, 189, + 84, 162, 172, 96, 155, 86, 170, 160, 128, 114, + 115, 85, 0, 149, 101, 106, 100, 137, 167, 168, + 99, 192, 90, 179, 88, 91, 178, 135, 165, 171, + 129, 126, 87, 169, 127, 125, 117, 104, 111, 143, + 124, 144, 112, 132, 131, 133, 0, 0, 0, 159, + 176, 193, 93, 0, 164, 183, 184, 185, 186, 187, + 188, 0, 0, 94, 107, 103, 142, 134, 92, 113, + 156, 116, 123, 148, 191, 139, 153, 97, 175, 157, + 310, 319, 316, 317, 314, 315, 313, 312, 311, 321, + 302, 303, 304, 305, 307, 0, 306, 82, 0, 120, + 190, 147, 105, 177, 138, 0, 0, 0, 0, 269, + 0, 0, 0, 102, 0, 266, 0, 0, 0, 119, + 309, 121, 0, 0, 158, 130, 0, 0, 0, 0, + 300, 301, 0, 0, 0, 0, 0, 0, 0, 0, + 54, 0, 0, 267, 288, 287, 290, 291, 292, 293, + 0, 0, 95, 289, 294, 295, 296, 0, 0, 0, + 264, 281, 0, 308, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 278, 279, 260, 0, 0, 0, 320, + 0, 280, 0, 0, 275, 276, 277, 282, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 108, 0, 0, + 0, 209, 0, 0, 318, 0, 145, 0, 161, 110, + 118, 83, 89, 0, 109, 136, 150, 154, 0, 0, + 0, 98, 0, 152, 140, 174, 0, 141, 151, 122, + 166, 146, 173, 181, 182, 163, 180, 189, 84, 162, + 172, 96, 155, 86, 170, 160, 128, 114, 115, 85, + 0, 149, 101, 106, 100, 137, 167, 168, 99, 192, + 90, 179, 88, 91, 178, 135, 165, 171, 129, 126, + 87, 169, 127, 125, 117, 104, 111, 143, 124, 144, + 112, 132, 131, 133, 0, 0, 0, 159, 176, 193, + 93, 0, 164, 183, 184, 185, 186, 187, 188, 0, + 0, 94, 107, 103, 142, 134, 92, 113, 156, 116, + 123, 148, 191, 139, 153, 97, 175, 157, 310, 319, + 316, 317, 314, 315, 313, 312, 311, 321, 302, 303, + 304, 305, 307, 24, 306, 82, 0, 120, 190, 147, + 105, 177, 0, 0, 0, 138, 0, 0, 0, 0, + 269, 0, 0, 0, 102, 0, 266, 0, 0, 0, + 119, 309, 121, 0, 0, 158, 130, 0, 0, 0, + 0, 300, 301, 0, 0, 0, 0, 0, 0, 0, + 0, 54, 0, 0, 267, 288, 287, 290, 291, 292, + 293, 0, 0, 95, 289, 294, 295, 296, 0, 0, + 0, 264, 281, 0, 308, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 278, 279, 0, 0, 0, 0, + 320, 0, 280, 0, 0, 275, 276, 277, 282, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 108, 0, + 0, 0, 209, 0, 0, 318, 0, 145, 0, 161, + 110, 118, 83, 89, 0, 109, 136, 150, 154, 0, + 0, 0, 98, 0, 152, 140, 174, 0, 141, 151, + 122, 166, 146, 173, 181, 182, 163, 180, 189, 84, + 162, 172, 96, 155, 86, 170, 160, 128, 114, 115, + 85, 0, 149, 101, 106, 100, 137, 167, 168, 99, + 192, 90, 179, 88, 91, 178, 135, 165, 171, 129, + 126, 87, 169, 127, 125, 117, 104, 111, 143, 124, + 144, 112, 132, 131, 133, 0, 0, 0, 159, 176, + 193, 93, 0, 164, 183, 184, 185, 186, 187, 188, + 0, 0, 94, 107, 103, 142, 134, 92, 113, 156, + 116, 123, 148, 191, 139, 153, 97, 175, 157, 310, + 319, 316, 317, 314, 315, 313, 312, 311, 321, 302, + 303, 304, 305, 307, 0, 306, 82, 0, 120, 190, + 147, 105, 177, 138, 0, 0, 0, 0, 269, 0, + 0, 0, 102, 0, 266, 0, 0, 0, 119, 309, + 121, 0, 0, 158, 130, 0, 0, 0, 0, 300, + 301, 0, 0, 0, 0, 0, 0, 0, 0, 54, + 0, 0, 267, 288, 287, 290, 291, 292, 293, 0, + 0, 95, 289, 294, 295, 296, 0, 0, 0, 264, + 281, 0, 308, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 278, 279, 0, 0, 0, 0, 320, 0, + 280, 0, 0, 275, 276, 277, 282, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 108, 0, 0, 0, + 209, 0, 0, 318, 0, 145, 0, 161, 110, 118, + 83, 89, 0, 109, 136, 150, 154, 0, 0, 0, + 98, 0, 152, 140, 174, 0, 141, 151, 122, 166, + 146, 173, 181, 182, 163, 180, 189, 84, 162, 172, + 96, 155, 86, 170, 160, 128, 114, 115, 85, 0, + 149, 101, 106, 100, 137, 167, 168, 99, 192, 90, + 179, 88, 91, 178, 135, 165, 171, 129, 126, 87, + 169, 127, 125, 117, 104, 111, 143, 124, 144, 112, + 132, 131, 133, 0, 0, 0, 159, 176, 193, 93, + 0, 164, 183, 184, 185, 186, 187, 188, 0, 0, + 94, 107, 103, 142, 134, 92, 113, 156, 116, 123, + 148, 191, 139, 153, 97, 175, 157, 310, 319, 316, + 317, 314, 315, 313, 312, 311, 321, 302, 303, 304, + 305, 307, 138, 306, 82, 0, 120, 190, 147, 105, + 177, 102, 0, 0, 0, 0, 0, 119, 309, 121, + 0, 0, 158, 130, 0, 0, 0, 0, 300, 301, + 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, + 0, 267, 288, 287, 290, 291, 292, 293, 0, 0, + 95, 289, 294, 295, 296, 0, 0, 0, 0, 281, + 0, 308, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 278, 279, 0, 0, 0, 0, 320, 0, 280, + 0, 0, 275, 276, 277, 282, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 108, 0, 0, 0, 209, + 0, 0, 318, 0, 145, 0, 161, 110, 118, 83, + 89, 0, 109, 136, 150, 154, 0, 0, 0, 98, + 0, 152, 140, 174, 1410, 141, 151, 122, 166, 146, + 173, 181, 182, 163, 180, 189, 84, 162, 172, 96, + 155, 86, 170, 160, 128, 114, 115, 85, 0, 149, + 101, 106, 100, 137, 167, 168, 99, 192, 90, 179, + 88, 91, 178, 135, 165, 171, 129, 126, 87, 169, + 127, 125, 117, 104, 111, 143, 124, 144, 112, 132, + 131, 133, 0, 0, 0, 159, 176, 193, 93, 0, + 164, 183, 184, 185, 186, 187, 188, 0, 0, 94, + 107, 103, 142, 134, 92, 113, 156, 116, 123, 148, + 191, 139, 153, 97, 175, 157, 310, 319, 316, 317, + 314, 315, 313, 312, 311, 321, 302, 303, 304, 305, + 307, 138, 306, 82, 0, 120, 190, 147, 105, 177, + 102, 0, 0, 0, 0, 0, 119, 309, 121, 0, + 0, 158, 130, 0, 0, 0, 0, 300, 301, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, - 268, 289, 288, 291, 292, 293, 294, 0, 0, 95, - 290, 295, 296, 297, 0, 0, 0, 265, 282, 0, - 309, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 279, 280, 261, 0, 0, 0, 321, 0, 281, 0, - 0, 276, 277, 278, 283, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 109, 0, 0, 0, 210, 0, - 0, 319, 0, 146, 0, 162, 111, 119, 83, 89, - 0, 110, 137, 151, 155, 0, 0, 0, 99, 0, - 153, 141, 175, 0, 142, 152, 123, 167, 147, 174, - 182, 183, 164, 181, 190, 84, 163, 173, 96, 156, - 86, 171, 161, 129, 115, 116, 85, 0, 150, 102, - 107, 101, 138, 168, 169, 100, 193, 90, 180, 88, - 91, 179, 136, 166, 172, 130, 127, 87, 170, 128, - 126, 118, 105, 112, 144, 125, 145, 113, 133, 132, - 134, 0, 0, 0, 160, 177, 194, 93, 0, 165, - 184, 185, 186, 187, 188, 189, 0, 0, 94, 108, - 104, 143, 135, 92, 114, 157, 117, 124, 149, 192, - 140, 154, 97, 176, 158, 311, 320, 317, 318, 315, - 316, 314, 313, 312, 322, 303, 304, 305, 306, 308, - 0, 307, 82, 0, 121, 191, 148, 106, 178, 139, - 0, 0, 0, 0, 270, 0, 98, 0, 103, 0, - 267, 0, 0, 0, 120, 310, 122, 0, 0, 159, - 131, 0, 0, 0, 0, 301, 302, 0, 0, 0, - 0, 0, 0, 0, 0, 54, 0, 494, 268, 289, - 288, 291, 292, 293, 294, 0, 0, 95, 290, 295, - 296, 297, 0, 0, 0, 265, 282, 0, 309, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 279, 280, - 0, 0, 0, 0, 321, 0, 281, 0, 0, 276, - 277, 278, 283, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 109, 0, 0, 0, 210, 0, 0, 319, - 0, 146, 0, 162, 111, 119, 83, 89, 0, 110, - 137, 151, 155, 0, 0, 0, 99, 0, 153, 141, - 175, 0, 142, 152, 123, 167, 147, 174, 182, 183, - 164, 181, 190, 84, 163, 173, 96, 156, 86, 171, - 161, 129, 115, 116, 85, 0, 150, 102, 107, 101, - 138, 168, 169, 100, 193, 90, 180, 88, 91, 179, - 136, 166, 172, 130, 127, 87, 170, 128, 126, 118, - 105, 112, 144, 125, 145, 113, 133, 132, 134, 0, - 0, 0, 160, 177, 194, 93, 0, 165, 184, 185, - 186, 187, 188, 189, 0, 0, 94, 108, 104, 143, - 135, 92, 114, 157, 117, 124, 149, 192, 140, 154, - 97, 176, 158, 311, 320, 317, 318, 315, 316, 314, - 313, 312, 322, 303, 304, 305, 306, 308, 0, 307, - 82, 0, 121, 191, 148, 106, 178, 139, 0, 0, - 0, 0, 270, 0, 98, 0, 103, 0, 267, 0, - 0, 0, 120, 310, 122, 0, 0, 159, 131, 0, - 0, 0, 0, 301, 302, 0, 0, 0, 0, 0, - 0, 0, 0, 54, 0, 0, 268, 289, 288, 291, - 292, 293, 294, 0, 0, 95, 290, 295, 296, 297, - 0, 0, 0, 265, 282, 0, 309, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 279, 280, 261, 0, - 0, 0, 321, 0, 281, 0, 0, 276, 277, 278, - 283, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 109, 0, 0, 0, 210, 0, 0, 319, 0, 146, - 0, 162, 111, 119, 83, 89, 0, 110, 137, 151, - 155, 0, 0, 0, 99, 0, 153, 141, 175, 0, - 142, 152, 123, 167, 147, 174, 182, 183, 164, 181, - 190, 84, 163, 173, 96, 156, 86, 171, 161, 129, - 115, 116, 85, 0, 150, 102, 107, 101, 138, 168, - 169, 100, 193, 90, 180, 88, 91, 179, 136, 166, - 172, 130, 127, 87, 170, 128, 126, 118, 105, 112, - 144, 125, 145, 113, 133, 132, 134, 0, 0, 0, - 160, 177, 194, 93, 0, 165, 184, 185, 186, 187, - 188, 189, 0, 0, 94, 108, 104, 143, 135, 92, - 114, 157, 117, 124, 149, 192, 140, 154, 97, 176, - 158, 311, 320, 317, 318, 315, 316, 314, 313, 312, - 322, 303, 304, 305, 306, 308, 24, 307, 82, 0, - 121, 191, 148, 106, 178, 0, 0, 0, 139, 0, - 0, 0, 0, 270, 0, 98, 0, 103, 0, 267, - 0, 0, 0, 120, 310, 122, 0, 0, 159, 131, - 0, 0, 0, 0, 301, 302, 0, 0, 0, 0, - 0, 0, 0, 0, 54, 0, 0, 268, 289, 288, - 291, 292, 293, 294, 0, 0, 95, 290, 295, 296, - 297, 0, 0, 0, 265, 282, 0, 309, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 279, 280, 0, - 0, 0, 0, 321, 0, 281, 0, 0, 276, 277, - 278, 283, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 109, 0, 0, 0, 210, 0, 0, 319, 0, - 146, 0, 162, 111, 119, 83, 89, 0, 110, 137, - 151, 155, 0, 0, 0, 99, 0, 153, 141, 175, - 0, 142, 152, 123, 167, 147, 174, 182, 183, 164, - 181, 190, 84, 163, 173, 96, 156, 86, 171, 161, - 129, 115, 116, 85, 0, 150, 102, 107, 101, 138, - 168, 169, 100, 193, 90, 180, 88, 91, 179, 136, - 166, 172, 130, 127, 87, 170, 128, 126, 118, 105, - 112, 144, 125, 145, 113, 133, 132, 134, 0, 0, - 0, 160, 177, 194, 93, 0, 165, 184, 185, 186, - 187, 188, 189, 0, 0, 94, 108, 104, 143, 135, - 92, 114, 157, 117, 124, 149, 192, 140, 154, 97, - 176, 158, 311, 320, 317, 318, 315, 316, 314, 313, - 312, 322, 303, 304, 305, 306, 308, 0, 307, 82, - 0, 121, 191, 148, 106, 178, 139, 0, 0, 0, - 0, 270, 0, 98, 0, 103, 0, 267, 0, 0, - 0, 120, 310, 122, 0, 0, 159, 131, 0, 0, - 0, 0, 301, 302, 0, 0, 0, 0, 0, 0, - 0, 0, 54, 0, 0, 268, 289, 288, 291, 292, - 293, 294, 0, 0, 95, 290, 295, 296, 297, 0, - 0, 0, 265, 282, 0, 309, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 279, 280, 0, 0, 0, - 0, 321, 0, 281, 0, 0, 276, 277, 278, 283, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, - 0, 0, 0, 210, 0, 0, 319, 0, 146, 0, - 162, 111, 119, 83, 89, 0, 110, 137, 151, 155, - 0, 0, 0, 99, 0, 153, 141, 175, 0, 142, - 152, 123, 167, 147, 174, 182, 183, 164, 181, 190, - 84, 163, 173, 96, 156, 86, 171, 161, 129, 115, - 116, 85, 0, 150, 102, 107, 101, 138, 168, 169, - 100, 193, 90, 180, 88, 91, 179, 136, 166, 172, - 130, 127, 87, 170, 128, 126, 118, 105, 112, 144, - 125, 145, 113, 133, 132, 134, 0, 0, 0, 160, - 177, 194, 93, 0, 165, 184, 185, 186, 187, 188, - 189, 0, 0, 94, 108, 104, 143, 135, 92, 114, - 157, 117, 124, 149, 192, 140, 154, 97, 176, 158, - 311, 320, 317, 318, 315, 316, 314, 313, 312, 322, - 303, 304, 305, 306, 308, 0, 307, 82, 139, 121, - 191, 148, 106, 178, 0, 98, 0, 103, 0, 0, - 0, 0, 0, 120, 310, 122, 0, 0, 159, 131, - 0, 0, 0, 0, 301, 302, 0, 0, 0, 0, - 0, 0, 0, 0, 54, 0, 0, 268, 289, 288, - 291, 292, 293, 294, 0, 0, 95, 290, 295, 296, - 297, 0, 0, 0, 0, 282, 0, 309, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 279, 280, 0, - 0, 0, 0, 321, 0, 281, 0, 0, 276, 277, - 278, 283, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 109, 0, 0, 0, 210, 0, 0, 319, 0, - 146, 0, 162, 111, 119, 83, 89, 0, 110, 137, - 151, 155, 0, 0, 0, 99, 0, 153, 141, 175, - 1411, 142, 152, 123, 167, 147, 174, 182, 183, 164, - 181, 190, 84, 163, 173, 96, 156, 86, 171, 161, - 129, 115, 116, 85, 0, 150, 102, 107, 101, 138, - 168, 169, 100, 193, 90, 180, 88, 91, 179, 136, - 166, 172, 130, 127, 87, 170, 128, 126, 118, 105, - 112, 144, 125, 145, 113, 133, 132, 134, 0, 0, - 0, 160, 177, 194, 93, 0, 165, 184, 185, 186, - 187, 188, 189, 0, 0, 94, 108, 104, 143, 135, - 92, 114, 157, 117, 124, 149, 192, 140, 154, 97, - 176, 158, 311, 320, 317, 318, 315, 316, 314, 313, - 312, 322, 303, 304, 305, 306, 308, 0, 307, 82, - 139, 121, 191, 148, 106, 178, 0, 98, 0, 103, - 0, 0, 0, 0, 0, 120, 310, 122, 0, 0, - 159, 131, 0, 0, 0, 0, 301, 302, 0, 0, - 0, 0, 0, 0, 0, 0, 54, 0, 0, 268, - 289, 288, 291, 292, 293, 294, 0, 0, 95, 290, - 295, 296, 297, 0, 0, 0, 0, 282, 0, 309, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 279, - 280, 0, 0, 0, 0, 321, 0, 281, 0, 0, - 276, 277, 278, 283, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 109, 0, 0, 0, 210, 0, 0, - 319, 0, 146, 0, 162, 111, 119, 83, 89, 0, - 110, 137, 151, 155, 0, 0, 0, 99, 0, 153, - 141, 175, 0, 142, 152, 123, 167, 147, 174, 182, - 183, 164, 181, 190, 84, 163, 173, 96, 156, 86, - 171, 161, 129, 115, 116, 85, 0, 150, 102, 107, - 101, 138, 168, 169, 100, 193, 90, 180, 88, 91, - 179, 136, 166, 172, 130, 127, 87, 170, 128, 126, - 118, 105, 112, 144, 125, 145, 113, 133, 132, 134, - 0, 0, 0, 160, 177, 194, 93, 0, 165, 184, - 185, 186, 187, 188, 189, 0, 0, 94, 108, 104, - 143, 135, 92, 114, 157, 117, 124, 149, 192, 140, - 154, 97, 176, 158, 311, 320, 317, 318, 315, 316, - 314, 313, 312, 322, 303, 304, 305, 306, 308, 0, - 307, 82, 139, 121, 191, 148, 106, 178, 0, 98, - 0, 103, 0, 0, 0, 0, 0, 120, 0, 122, - 0, 0, 159, 131, 0, 0, 0, 0, 0, 0, + 267, 288, 287, 290, 291, 292, 293, 0, 0, 95, + 289, 294, 295, 296, 0, 0, 0, 0, 281, 0, + 308, 0, 0, 0, 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, - 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 278, 279, 0, 0, 0, 0, 320, 0, 280, 0, + 0, 275, 276, 277, 282, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 108, 0, 0, 0, 209, 0, + 0, 318, 0, 145, 0, 161, 110, 118, 83, 89, + 0, 109, 136, 150, 154, 0, 0, 0, 98, 0, + 152, 140, 174, 0, 141, 151, 122, 166, 146, 173, + 181, 182, 163, 180, 189, 84, 162, 172, 96, 155, + 86, 170, 160, 128, 114, 115, 85, 0, 149, 101, + 106, 100, 137, 167, 168, 99, 192, 90, 179, 88, + 91, 178, 135, 165, 171, 129, 126, 87, 169, 127, + 125, 117, 104, 111, 143, 124, 144, 112, 132, 131, + 133, 0, 0, 0, 159, 176, 193, 93, 0, 164, + 183, 184, 185, 186, 187, 188, 0, 0, 94, 107, + 103, 142, 134, 92, 113, 156, 116, 123, 148, 191, + 139, 153, 97, 175, 157, 310, 319, 316, 317, 314, + 315, 313, 312, 311, 321, 302, 303, 304, 305, 307, + 138, 306, 82, 0, 120, 190, 147, 105, 177, 102, + 0, 0, 0, 0, 0, 119, 0, 121, 0, 0, + 158, 130, 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, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 528, 527, 537, - 538, 530, 531, 532, 533, 534, 535, 536, 529, 0, - 0, 539, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 109, 0, 0, 0, 210, - 0, 0, 0, 0, 146, 0, 162, 111, 119, 83, - 89, 0, 110, 137, 151, 155, 0, 0, 0, 99, - 0, 153, 141, 175, 0, 142, 152, 123, 167, 147, - 174, 182, 183, 164, 181, 190, 84, 163, 173, 96, - 156, 86, 171, 161, 129, 115, 116, 85, 0, 150, - 102, 107, 101, 138, 168, 169, 100, 193, 90, 180, - 88, 91, 179, 136, 166, 172, 130, 127, 87, 170, - 128, 126, 118, 105, 112, 144, 125, 145, 113, 133, - 132, 134, 0, 0, 0, 160, 177, 194, 93, 0, - 165, 184, 185, 186, 187, 188, 189, 0, 0, 94, - 108, 104, 143, 135, 92, 114, 157, 117, 124, 149, - 192, 140, 154, 97, 176, 158, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 139, 0, 0, 0, 516, - 0, 0, 98, 82, 103, 121, 191, 148, 106, 178, - 120, 0, 122, 0, 0, 159, 131, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 80, 0, 518, 0, 0, 0, - 0, 0, 0, 95, 0, 0, 0, 0, 0, 513, - 512, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 514, 0, 0, 0, - 0, 0, 0, 0, 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, 210, 0, 0, 0, 0, 146, 0, 162, - 111, 119, 83, 89, 0, 110, 137, 151, 155, 0, - 0, 0, 99, 0, 153, 141, 175, 0, 142, 152, - 123, 167, 147, 174, 182, 183, 164, 181, 190, 84, - 163, 173, 96, 156, 86, 171, 161, 129, 115, 116, - 85, 0, 150, 102, 107, 101, 138, 168, 169, 100, - 193, 90, 180, 88, 91, 179, 136, 166, 172, 130, - 127, 87, 170, 128, 126, 118, 105, 112, 144, 125, - 145, 113, 133, 132, 134, 0, 0, 0, 160, 177, - 194, 93, 0, 165, 184, 185, 186, 187, 188, 189, - 0, 0, 94, 108, 104, 143, 135, 92, 114, 157, - 117, 124, 149, 192, 140, 154, 97, 176, 158, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 139, 0, - 0, 0, 0, 0, 0, 98, 82, 103, 121, 191, - 148, 106, 178, 120, 0, 122, 0, 0, 159, 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, 95, 0, 0, 0, - 0, 0, 74, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 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, 76, 77, 0, 73, 0, 0, 0, 78, - 146, 0, 162, 111, 119, 83, 89, 0, 110, 137, - 151, 155, 0, 0, 0, 99, 0, 153, 141, 175, - 0, 142, 152, 123, 167, 147, 174, 182, 183, 164, - 181, 190, 84, 163, 173, 96, 156, 86, 171, 161, - 129, 115, 116, 85, 0, 150, 102, 107, 101, 138, - 168, 169, 100, 193, 90, 180, 88, 91, 179, 136, - 166, 172, 130, 127, 87, 170, 128, 126, 118, 105, - 112, 144, 125, 145, 113, 133, 132, 134, 0, 0, - 0, 160, 177, 194, 93, 0, 165, 184, 185, 186, - 187, 188, 189, 0, 0, 94, 108, 104, 143, 135, - 92, 114, 157, 117, 124, 149, 192, 140, 154, 97, - 176, 158, 0, 75, 0, 0, 0, 0, 0, 0, - 0, 139, 0, 0, 0, 825, 0, 0, 98, 82, - 103, 121, 191, 148, 106, 178, 120, 0, 122, 0, - 0, 159, 131, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 208, 0, 827, 0, 0, 0, 0, 0, 0, 95, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 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, 210, 0, - 0, 0, 0, 146, 0, 162, 111, 119, 83, 89, - 0, 110, 137, 151, 155, 0, 0, 0, 99, 0, - 153, 141, 175, 0, 142, 152, 123, 167, 147, 174, - 182, 183, 164, 181, 190, 84, 163, 173, 96, 156, - 86, 171, 161, 129, 115, 116, 85, 0, 150, 102, - 107, 101, 138, 168, 169, 100, 193, 90, 180, 88, - 91, 179, 136, 166, 172, 130, 127, 87, 170, 128, - 126, 118, 105, 112, 144, 125, 145, 113, 133, 132, - 134, 0, 0, 0, 160, 177, 194, 93, 0, 165, - 184, 185, 186, 187, 188, 189, 0, 0, 94, 108, - 104, 143, 135, 92, 114, 157, 117, 124, 149, 192, - 140, 154, 97, 176, 158, 0, 0, 0, 0, 0, - 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 82, 139, 121, 191, 148, 106, 178, 0, - 98, 0, 103, 0, 0, 0, 0, 0, 120, 0, - 122, 0, 0, 159, 131, 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, 95, 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, 108, 0, 0, 0, 209, 0, 0, + 0, 0, 145, 0, 161, 110, 118, 83, 89, 0, + 109, 136, 150, 154, 0, 0, 0, 98, 0, 152, + 140, 174, 0, 141, 151, 122, 166, 146, 173, 181, + 182, 163, 180, 189, 84, 162, 172, 96, 155, 86, + 170, 160, 128, 114, 115, 85, 0, 149, 101, 106, + 100, 137, 167, 168, 99, 192, 90, 179, 88, 91, + 178, 135, 165, 171, 129, 126, 87, 169, 127, 125, + 117, 104, 111, 143, 124, 144, 112, 132, 131, 133, + 0, 0, 0, 159, 176, 193, 93, 0, 164, 183, + 184, 185, 186, 187, 188, 0, 0, 94, 107, 103, + 142, 134, 92, 113, 156, 116, 123, 148, 191, 139, + 153, 97, 175, 157, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 138, 0, 0, 0, 515, 0, 0, + 0, 82, 102, 120, 190, 147, 105, 177, 119, 0, + 121, 0, 0, 158, 130, 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, 95, 0, 0, 0, 0, 0, 512, 511, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 109, 0, 0, 0, - 210, 0, 0, 0, 0, 146, 0, 162, 111, 119, - 83, 89, 0, 110, 137, 151, 155, 0, 0, 0, - 99, 0, 153, 141, 175, 0, 142, 152, 123, 167, - 147, 174, 182, 183, 164, 181, 190, 84, 163, 173, - 96, 156, 86, 171, 161, 129, 115, 116, 85, 0, - 150, 102, 107, 101, 138, 168, 169, 100, 193, 90, - 180, 88, 91, 179, 136, 166, 172, 130, 127, 87, - 170, 128, 126, 118, 105, 112, 144, 125, 145, 113, - 133, 132, 134, 0, 0, 0, 160, 177, 194, 93, - 0, 165, 184, 185, 186, 187, 188, 189, 0, 0, - 94, 108, 104, 143, 135, 92, 114, 157, 117, 124, - 149, 192, 140, 154, 97, 176, 158, 0, 0, 0, - 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 82, 139, 121, 191, 148, 106, - 178, 0, 98, 0, 103, 0, 0, 0, 0, 0, - 120, 0, 122, 0, 0, 159, 131, 0, 0, 0, + 0, 0, 0, 0, 513, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 54, 0, 0, 208, 0, 0, 0, 0, 0, - 0, 0, 0, 95, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 108, 0, 0, 0, + 209, 0, 0, 0, 0, 145, 0, 161, 110, 118, + 83, 89, 0, 109, 136, 150, 154, 0, 0, 0, + 98, 0, 152, 140, 174, 0, 141, 151, 122, 166, + 146, 173, 181, 182, 163, 180, 189, 84, 162, 172, + 96, 155, 86, 170, 160, 128, 114, 115, 85, 0, + 149, 101, 106, 100, 137, 167, 168, 99, 192, 90, + 179, 88, 91, 178, 135, 165, 171, 129, 126, 87, + 169, 127, 125, 117, 104, 111, 143, 124, 144, 112, + 132, 131, 133, 0, 0, 0, 159, 176, 193, 93, + 0, 164, 183, 184, 185, 186, 187, 188, 0, 0, + 94, 107, 103, 142, 134, 92, 113, 156, 116, 123, + 148, 191, 139, 153, 97, 175, 157, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 138, 0, 0, 0, + 0, 0, 0, 0, 82, 102, 120, 190, 147, 105, + 177, 119, 0, 121, 0, 0, 158, 130, 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, 95, 0, 0, 0, 0, 0, + 74, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 108, + 76, 77, 0, 73, 0, 0, 0, 78, 145, 0, + 161, 110, 118, 83, 89, 0, 109, 136, 150, 154, + 0, 0, 0, 98, 0, 152, 140, 174, 0, 141, + 151, 122, 166, 146, 173, 181, 182, 163, 180, 189, + 84, 162, 172, 96, 155, 86, 170, 160, 128, 114, + 115, 85, 0, 149, 101, 106, 100, 137, 167, 168, + 99, 192, 90, 179, 88, 91, 178, 135, 165, 171, + 129, 126, 87, 169, 127, 125, 117, 104, 111, 143, + 124, 144, 112, 132, 131, 133, 0, 0, 0, 159, + 176, 193, 93, 0, 164, 183, 184, 185, 186, 187, + 188, 0, 0, 94, 107, 103, 142, 134, 92, 113, + 156, 116, 123, 148, 191, 139, 153, 97, 175, 157, + 0, 75, 0, 0, 0, 0, 0, 0, 0, 138, + 0, 0, 0, 824, 0, 0, 0, 82, 102, 120, + 190, 147, 105, 177, 119, 0, 121, 0, 0, 158, + 130, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 207, 0, + 826, 0, 0, 0, 0, 0, 0, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 109, 0, - 0, 0, 210, 0, 0, 0, 0, 146, 0, 162, - 111, 119, 83, 89, 0, 110, 137, 151, 155, 0, - 0, 0, 99, 0, 153, 141, 175, 0, 142, 152, - 123, 167, 147, 174, 182, 183, 164, 181, 190, 84, - 163, 173, 96, 156, 86, 171, 161, 129, 115, 116, - 85, 0, 150, 102, 107, 101, 138, 168, 169, 100, - 193, 90, 180, 88, 91, 179, 136, 166, 172, 130, - 127, 87, 170, 128, 126, 118, 105, 112, 144, 125, - 145, 113, 133, 132, 134, 0, 0, 0, 160, 177, - 194, 93, 0, 165, 184, 185, 186, 187, 188, 189, - 0, 0, 94, 108, 104, 143, 135, 92, 114, 157, - 117, 124, 149, 192, 140, 154, 97, 176, 158, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 139, 0, - 0, 0, 825, 0, 0, 98, 82, 103, 121, 191, - 148, 106, 178, 120, 0, 122, 0, 0, 159, 131, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 208, 0, 827, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 108, 0, 0, 0, 209, 0, 0, 0, + 0, 145, 0, 161, 110, 118, 83, 89, 0, 109, + 136, 150, 154, 0, 0, 0, 98, 0, 152, 140, + 174, 0, 141, 151, 122, 166, 146, 173, 181, 182, + 163, 180, 189, 84, 162, 172, 96, 155, 86, 170, + 160, 128, 114, 115, 85, 0, 149, 101, 106, 100, + 137, 167, 168, 99, 192, 90, 179, 88, 91, 178, + 135, 165, 171, 129, 126, 87, 169, 127, 125, 117, + 104, 111, 143, 124, 144, 112, 132, 131, 133, 0, + 0, 0, 159, 176, 193, 93, 0, 164, 183, 184, + 185, 186, 187, 188, 0, 0, 94, 107, 103, 142, + 134, 92, 113, 156, 116, 123, 148, 191, 139, 153, + 97, 175, 157, 0, 0, 0, 24, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 138, 0, + 82, 0, 120, 190, 147, 105, 177, 102, 0, 0, + 0, 0, 0, 119, 0, 121, 0, 0, 158, 130, + 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, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 210, 0, 0, 0, 0, - 146, 0, 162, 111, 119, 83, 89, 0, 110, 137, - 151, 155, 0, 0, 0, 99, 0, 153, 141, 175, - 0, 823, 152, 123, 167, 147, 174, 182, 183, 164, - 181, 190, 84, 163, 173, 96, 156, 86, 171, 161, - 129, 115, 116, 85, 0, 150, 102, 107, 101, 138, - 168, 169, 100, 193, 90, 180, 88, 91, 179, 136, - 166, 172, 130, 127, 87, 170, 128, 126, 118, 105, - 112, 144, 125, 145, 113, 133, 132, 134, 0, 0, - 0, 160, 177, 194, 93, 0, 165, 184, 185, 186, - 187, 188, 189, 0, 0, 94, 108, 104, 143, 135, - 92, 114, 157, 117, 124, 149, 192, 140, 154, 97, - 176, 158, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 139, 0, 0, 0, 0, 0, 0, 98, 82, - 103, 121, 191, 148, 106, 178, 120, 0, 122, 0, - 0, 159, 131, 0, 0, 0, 0, 0, 0, 0, + 0, 108, 0, 0, 0, 209, 0, 0, 0, 0, + 145, 0, 161, 110, 118, 83, 89, 0, 109, 136, + 150, 154, 0, 0, 0, 98, 0, 152, 140, 174, + 0, 141, 151, 122, 166, 146, 173, 181, 182, 163, + 180, 189, 84, 162, 172, 96, 155, 86, 170, 160, + 128, 114, 115, 85, 0, 149, 101, 106, 100, 137, + 167, 168, 99, 192, 90, 179, 88, 91, 178, 135, + 165, 171, 129, 126, 87, 169, 127, 125, 117, 104, + 111, 143, 124, 144, 112, 132, 131, 133, 0, 0, + 0, 159, 176, 193, 93, 0, 164, 183, 184, 185, + 186, 187, 188, 0, 0, 94, 107, 103, 142, 134, + 92, 113, 156, 116, 123, 148, 191, 139, 153, 97, + 175, 157, 0, 0, 0, 24, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 138, 0, 82, + 0, 120, 190, 147, 105, 177, 102, 0, 0, 0, + 0, 0, 119, 0, 121, 0, 0, 158, 130, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 80, 0, 0, 725, 0, 0, 726, 0, 0, 95, + 0, 0, 0, 54, 0, 0, 207, 0, 0, 0, + 0, 0, 0, 0, 0, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 210, 0, - 0, 0, 0, 146, 0, 162, 111, 119, 83, 89, - 0, 110, 137, 151, 155, 0, 0, 0, 99, 0, - 153, 141, 175, 0, 142, 152, 123, 167, 147, 174, - 182, 183, 164, 181, 190, 84, 163, 173, 96, 156, - 86, 171, 161, 129, 115, 116, 85, 0, 150, 102, - 107, 101, 138, 168, 169, 100, 193, 90, 180, 88, - 91, 179, 136, 166, 172, 130, 127, 87, 170, 128, - 126, 118, 105, 112, 144, 125, 145, 113, 133, 132, - 134, 0, 0, 0, 160, 177, 194, 93, 0, 165, - 184, 185, 186, 187, 188, 189, 0, 0, 94, 108, - 104, 143, 135, 92, 114, 157, 117, 124, 149, 192, - 140, 154, 97, 176, 158, 0, 0, 0, 0, 0, + 108, 0, 0, 0, 209, 0, 0, 0, 0, 145, + 0, 161, 110, 118, 83, 89, 0, 109, 136, 150, + 154, 0, 0, 0, 98, 0, 152, 140, 174, 0, + 141, 151, 122, 166, 146, 173, 181, 182, 163, 180, + 189, 84, 162, 172, 96, 155, 86, 170, 160, 128, + 114, 115, 85, 0, 149, 101, 106, 100, 137, 167, + 168, 99, 192, 90, 179, 88, 91, 178, 135, 165, + 171, 129, 126, 87, 169, 127, 125, 117, 104, 111, + 143, 124, 144, 112, 132, 131, 133, 0, 0, 0, + 159, 176, 193, 93, 0, 164, 183, 184, 185, 186, + 187, 188, 0, 0, 94, 107, 103, 142, 134, 92, + 113, 156, 116, 123, 148, 191, 139, 153, 97, 175, + 157, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 138, 0, 0, 0, 824, 0, 0, 0, 82, 102, + 120, 190, 147, 105, 177, 119, 0, 121, 0, 0, + 158, 130, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 207, + 0, 826, 0, 0, 0, 0, 0, 0, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 82, 139, 121, 191, 148, 106, 178, 0, - 98, 0, 103, 0, 618, 0, 0, 0, 120, 0, - 122, 0, 0, 159, 131, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 80, 0, 617, 0, 0, 0, 0, 0, - 0, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 108, 0, 0, 0, 209, 0, 0, + 0, 0, 145, 0, 161, 110, 118, 83, 89, 0, + 109, 136, 150, 154, 0, 0, 0, 98, 0, 152, + 140, 174, 0, 822, 151, 122, 166, 146, 173, 181, + 182, 163, 180, 189, 84, 162, 172, 96, 155, 86, + 170, 160, 128, 114, 115, 85, 0, 149, 101, 106, + 100, 137, 167, 168, 99, 192, 90, 179, 88, 91, + 178, 135, 165, 171, 129, 126, 87, 169, 127, 125, + 117, 104, 111, 143, 124, 144, 112, 132, 131, 133, + 0, 0, 0, 159, 176, 193, 93, 0, 164, 183, + 184, 185, 186, 187, 188, 0, 0, 94, 107, 103, + 142, 134, 92, 113, 156, 116, 123, 148, 191, 139, + 153, 97, 175, 157, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 138, 0, 0, 0, 0, 0, 0, + 0, 82, 102, 120, 190, 147, 105, 177, 119, 0, + 121, 0, 0, 158, 130, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 80, 0, 0, 724, 0, 0, 725, 0, + 0, 95, 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, - 210, 0, 0, 0, 0, 146, 0, 162, 111, 119, - 83, 89, 0, 110, 137, 151, 155, 0, 0, 0, - 99, 0, 153, 141, 175, 0, 142, 152, 123, 167, - 147, 174, 182, 183, 164, 181, 190, 84, 163, 173, - 96, 156, 86, 171, 161, 129, 115, 116, 85, 0, - 150, 102, 107, 101, 138, 168, 169, 100, 193, 90, - 180, 88, 91, 179, 136, 166, 172, 130, 127, 87, - 170, 128, 126, 118, 105, 112, 144, 125, 145, 113, - 133, 132, 134, 0, 0, 0, 160, 177, 194, 93, - 0, 165, 184, 185, 186, 187, 188, 189, 0, 0, - 94, 108, 104, 143, 135, 92, 114, 157, 117, 124, - 149, 192, 140, 154, 97, 176, 158, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 139, 0, 0, 0, - 0, 0, 0, 98, 82, 103, 121, 191, 148, 106, - 178, 120, 0, 122, 0, 0, 159, 131, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 54, 0, 0, 208, 0, 0, 0, 0, - 0, 0, 0, 0, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 108, 0, 0, 0, + 209, 0, 0, 0, 0, 145, 0, 161, 110, 118, + 83, 89, 0, 109, 136, 150, 154, 0, 0, 0, + 98, 0, 152, 140, 174, 0, 141, 151, 122, 166, + 146, 173, 181, 182, 163, 180, 189, 84, 162, 172, + 96, 155, 86, 170, 160, 128, 114, 115, 85, 0, + 149, 101, 106, 100, 137, 167, 168, 99, 192, 90, + 179, 88, 91, 178, 135, 165, 171, 129, 126, 87, + 169, 127, 125, 117, 104, 111, 143, 124, 144, 112, + 132, 131, 133, 0, 0, 0, 159, 176, 193, 93, + 0, 164, 183, 184, 185, 186, 187, 188, 0, 0, + 94, 107, 103, 142, 134, 92, 113, 156, 116, 123, + 148, 191, 139, 153, 97, 175, 157, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 138, 0, 82, 0, 120, 190, 147, 105, + 177, 102, 0, 617, 0, 0, 0, 119, 0, 121, + 0, 0, 158, 130, 0, 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, 210, 0, 0, 0, 0, 146, 0, - 162, 111, 119, 83, 89, 0, 110, 137, 151, 155, - 0, 0, 0, 99, 0, 153, 141, 175, 0, 142, - 152, 123, 167, 147, 174, 182, 183, 164, 181, 190, - 84, 163, 173, 96, 156, 86, 171, 161, 129, 115, - 116, 85, 0, 150, 102, 107, 101, 138, 168, 169, - 100, 193, 90, 180, 88, 91, 179, 136, 166, 172, - 130, 127, 87, 170, 128, 126, 118, 105, 112, 144, - 125, 145, 113, 133, 132, 134, 0, 0, 0, 160, - 177, 194, 93, 0, 165, 184, 185, 186, 187, 188, - 189, 0, 0, 94, 108, 104, 143, 135, 92, 114, - 157, 117, 124, 149, 192, 140, 154, 97, 176, 158, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 139, - 0, 0, 0, 0, 0, 0, 98, 82, 103, 121, - 191, 148, 106, 178, 120, 0, 122, 0, 0, 159, - 131, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 208, 0, - 827, 0, 0, 0, 0, 0, 0, 95, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 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, 210, 0, 0, 0, - 0, 146, 0, 162, 111, 119, 83, 89, 0, 110, - 137, 151, 155, 0, 0, 0, 99, 0, 153, 141, - 175, 0, 142, 152, 123, 167, 147, 174, 182, 183, - 164, 181, 190, 84, 163, 173, 96, 156, 86, 171, - 161, 129, 115, 116, 85, 0, 150, 102, 107, 101, - 138, 168, 169, 100, 193, 90, 180, 88, 91, 179, - 136, 166, 172, 130, 127, 87, 170, 128, 126, 118, - 105, 112, 144, 125, 145, 113, 133, 132, 134, 0, - 0, 0, 160, 177, 194, 93, 0, 165, 184, 185, - 186, 187, 188, 189, 0, 0, 94, 108, 104, 143, - 135, 92, 114, 157, 117, 124, 149, 192, 140, 154, - 97, 176, 158, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 139, 0, 0, 0, 0, 0, 0, 98, - 82, 103, 121, 191, 148, 106, 178, 120, 0, 122, - 0, 0, 159, 131, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 268, 0, 790, 0, 0, 0, 0, 0, 0, + 0, 80, 0, 616, 0, 0, 0, 0, 0, 0, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 210, - 0, 0, 0, 0, 146, 0, 162, 111, 119, 83, - 89, 0, 110, 137, 151, 155, 0, 0, 0, 99, - 0, 153, 141, 175, 0, 142, 152, 123, 167, 147, - 174, 182, 183, 164, 181, 190, 84, 163, 173, 96, - 156, 86, 171, 161, 129, 115, 116, 85, 0, 150, - 102, 107, 101, 138, 168, 169, 100, 193, 90, 180, - 88, 91, 179, 136, 166, 172, 130, 127, 87, 170, - 128, 126, 118, 105, 112, 144, 125, 145, 113, 133, - 132, 134, 0, 0, 0, 160, 177, 194, 93, 0, - 165, 184, 185, 186, 187, 188, 189, 0, 0, 94, - 108, 104, 143, 135, 92, 114, 157, 117, 124, 149, - 192, 140, 154, 97, 176, 158, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 139, 0, 0, 0, 0, - 0, 0, 98, 82, 103, 121, 191, 148, 106, 178, - 120, 0, 122, 0, 0, 159, 131, 0, 0, 0, + 0, 0, 0, 0, 0, 108, 0, 0, 0, 209, + 0, 0, 0, 0, 145, 0, 161, 110, 118, 83, + 89, 0, 109, 136, 150, 154, 0, 0, 0, 98, + 0, 152, 140, 174, 0, 141, 151, 122, 166, 146, + 173, 181, 182, 163, 180, 189, 84, 162, 172, 96, + 155, 86, 170, 160, 128, 114, 115, 85, 0, 149, + 101, 106, 100, 137, 167, 168, 99, 192, 90, 179, + 88, 91, 178, 135, 165, 171, 129, 126, 87, 169, + 127, 125, 117, 104, 111, 143, 124, 144, 112, 132, + 131, 133, 0, 0, 0, 159, 176, 193, 93, 0, + 164, 183, 184, 185, 186, 187, 188, 0, 0, 94, + 107, 103, 142, 134, 92, 113, 156, 116, 123, 148, + 191, 139, 153, 97, 175, 157, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 138, 0, 0, 0, 0, + 0, 0, 0, 82, 102, 120, 190, 147, 105, 177, + 119, 0, 121, 0, 0, 158, 130, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 268, 0, 786, 0, 0, 0, + 0, 54, 0, 0, 207, 0, 0, 0, 0, 0, 0, 0, 0, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 210, 0, 0, 0, 0, 146, 0, 162, - 111, 119, 83, 89, 0, 110, 137, 151, 155, 0, - 0, 0, 99, 0, 153, 141, 175, 0, 142, 152, - 123, 167, 147, 174, 182, 183, 164, 181, 190, 84, - 163, 173, 96, 156, 86, 171, 161, 129, 115, 116, - 85, 0, 150, 102, 107, 101, 138, 168, 169, 100, - 193, 90, 180, 88, 91, 179, 136, 166, 172, 130, - 127, 87, 170, 128, 126, 118, 105, 112, 144, 125, - 145, 113, 133, 132, 134, 0, 0, 0, 160, 177, - 194, 93, 0, 165, 184, 185, 186, 187, 188, 189, - 0, 0, 94, 108, 104, 143, 135, 92, 114, 157, - 117, 124, 149, 192, 140, 154, 97, 176, 158, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 139, 0, - 0, 0, 0, 0, 0, 98, 82, 103, 121, 191, - 148, 106, 178, 120, 0, 122, 0, 0, 159, 131, + 0, 0, 0, 0, 0, 0, 0, 0, 108, 0, + 0, 0, 209, 0, 0, 0, 0, 145, 0, 161, + 110, 118, 83, 89, 0, 109, 136, 150, 154, 0, + 0, 0, 98, 0, 152, 140, 174, 0, 141, 151, + 122, 166, 146, 173, 181, 182, 163, 180, 189, 84, + 162, 172, 96, 155, 86, 170, 160, 128, 114, 115, + 85, 0, 149, 101, 106, 100, 137, 167, 168, 99, + 192, 90, 179, 88, 91, 178, 135, 165, 171, 129, + 126, 87, 169, 127, 125, 117, 104, 111, 143, 124, + 144, 112, 132, 131, 133, 0, 0, 0, 159, 176, + 193, 93, 0, 164, 183, 184, 185, 186, 187, 188, + 0, 0, 94, 107, 103, 142, 134, 92, 113, 156, + 116, 123, 148, 191, 139, 153, 97, 175, 157, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 138, 0, + 0, 0, 0, 0, 0, 0, 82, 102, 120, 190, + 147, 105, 177, 119, 0, 121, 0, 0, 158, 130, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 80, 0, 518, + 0, 0, 0, 0, 0, 0, 0, 207, 0, 826, 0, 0, 0, 0, 0, 0, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 210, 0, 0, 0, 0, - 146, 0, 162, 111, 119, 83, 89, 0, 110, 137, - 151, 155, 0, 0, 0, 99, 0, 153, 141, 175, - 0, 142, 152, 123, 167, 147, 174, 182, 183, 164, - 181, 190, 84, 163, 173, 96, 156, 86, 171, 161, - 129, 115, 116, 85, 0, 150, 102, 107, 101, 138, - 168, 169, 100, 193, 90, 180, 88, 91, 179, 136, - 166, 172, 130, 127, 87, 170, 128, 126, 118, 105, - 112, 144, 125, 145, 113, 133, 132, 134, 0, 0, - 0, 160, 177, 194, 93, 0, 165, 184, 185, 186, - 187, 188, 189, 0, 0, 94, 108, 104, 143, 135, - 92, 114, 157, 117, 124, 149, 192, 140, 154, 97, - 176, 158, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, - 139, 121, 191, 148, 106, 178, 0, 98, 591, 103, - 0, 0, 0, 0, 0, 120, 0, 122, 0, 0, - 159, 131, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 208, - 0, 0, 0, 0, 0, 0, 0, 0, 95, 0, + 0, 108, 0, 0, 0, 209, 0, 0, 0, 0, + 145, 0, 161, 110, 118, 83, 89, 0, 109, 136, + 150, 154, 0, 0, 0, 98, 0, 152, 140, 174, + 0, 141, 151, 122, 166, 146, 173, 181, 182, 163, + 180, 189, 84, 162, 172, 96, 155, 86, 170, 160, + 128, 114, 115, 85, 0, 149, 101, 106, 100, 137, + 167, 168, 99, 192, 90, 179, 88, 91, 178, 135, + 165, 171, 129, 126, 87, 169, 127, 125, 117, 104, + 111, 143, 124, 144, 112, 132, 131, 133, 0, 0, + 0, 159, 176, 193, 93, 0, 164, 183, 184, 185, + 186, 187, 188, 0, 0, 94, 107, 103, 142, 134, + 92, 113, 156, 116, 123, 148, 191, 139, 153, 97, + 175, 157, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 138, 0, 0, 0, 0, 0, 0, 0, 82, + 102, 120, 190, 147, 105, 177, 119, 0, 121, 0, + 0, 158, 130, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 267, 0, 789, 0, 0, 0, 0, 0, 0, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 210, 0, 0, - 0, 0, 146, 0, 162, 111, 119, 83, 89, 0, - 110, 137, 151, 155, 0, 0, 0, 99, 0, 153, - 141, 175, 0, 142, 152, 123, 167, 147, 174, 182, - 183, 164, 181, 190, 84, 163, 173, 96, 156, 86, - 171, 161, 129, 115, 116, 85, 0, 150, 102, 107, - 101, 138, 168, 169, 100, 193, 90, 180, 88, 91, - 179, 136, 166, 172, 130, 127, 87, 170, 128, 126, - 118, 105, 112, 144, 125, 145, 113, 133, 132, 134, - 0, 0, 0, 160, 177, 194, 93, 0, 165, 184, - 185, 186, 187, 188, 189, 0, 0, 94, 108, 104, - 143, 135, 92, 114, 157, 117, 124, 149, 192, 140, - 154, 97, 176, 158, 0, 0, 325, 0, 0, 0, - 0, 0, 0, 139, 0, 0, 0, 0, 0, 0, - 98, 82, 103, 121, 191, 148, 106, 178, 120, 0, - 122, 0, 0, 159, 131, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 208, 0, 0, 0, 0, 0, 0, 0, - 0, 95, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 108, 0, 0, 0, 209, 0, + 0, 0, 0, 145, 0, 161, 110, 118, 83, 89, + 0, 109, 136, 150, 154, 0, 0, 0, 98, 0, + 152, 140, 174, 0, 141, 151, 122, 166, 146, 173, + 181, 182, 163, 180, 189, 84, 162, 172, 96, 155, + 86, 170, 160, 128, 114, 115, 85, 0, 149, 101, + 106, 100, 137, 167, 168, 99, 192, 90, 179, 88, + 91, 178, 135, 165, 171, 129, 126, 87, 169, 127, + 125, 117, 104, 111, 143, 124, 144, 112, 132, 131, + 133, 0, 0, 0, 159, 176, 193, 93, 0, 164, + 183, 184, 185, 186, 187, 188, 0, 0, 94, 107, + 103, 142, 134, 92, 113, 156, 116, 123, 148, 191, + 139, 153, 97, 175, 157, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 138, 0, 0, 0, 0, 0, + 0, 0, 82, 102, 120, 190, 147, 105, 177, 119, + 0, 121, 0, 0, 158, 130, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 267, 0, 785, 0, 0, 0, 0, + 0, 0, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, - 210, 0, 0, 0, 0, 146, 0, 162, 111, 119, - 83, 89, 0, 110, 137, 151, 155, 0, 0, 0, - 99, 0, 153, 141, 175, 0, 142, 152, 123, 167, - 147, 174, 182, 183, 164, 181, 190, 84, 163, 173, - 96, 156, 86, 171, 161, 129, 115, 116, 85, 0, - 150, 102, 107, 101, 138, 168, 169, 100, 193, 90, - 180, 88, 91, 179, 136, 166, 172, 130, 127, 87, - 170, 128, 126, 118, 105, 112, 144, 125, 145, 113, - 133, 132, 134, 0, 0, 0, 160, 177, 194, 93, - 0, 165, 184, 185, 186, 187, 188, 189, 0, 0, - 94, 108, 104, 143, 135, 92, 114, 157, 117, 124, - 149, 192, 140, 154, 97, 176, 158, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 139, 0, 0, 0, - 0, 0, 0, 98, 82, 103, 121, 191, 148, 106, - 178, 120, 0, 122, 0, 0, 159, 131, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 208, 0, 0, 0, 0, - 0, 0, 0, 0, 95, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 108, 0, 0, + 0, 209, 0, 0, 0, 0, 145, 0, 161, 110, + 118, 83, 89, 0, 109, 136, 150, 154, 0, 0, + 0, 98, 0, 152, 140, 174, 0, 141, 151, 122, + 166, 146, 173, 181, 182, 163, 180, 189, 84, 162, + 172, 96, 155, 86, 170, 160, 128, 114, 115, 85, + 0, 149, 101, 106, 100, 137, 167, 168, 99, 192, + 90, 179, 88, 91, 178, 135, 165, 171, 129, 126, + 87, 169, 127, 125, 117, 104, 111, 143, 124, 144, + 112, 132, 131, 133, 0, 0, 0, 159, 176, 193, + 93, 0, 164, 183, 184, 185, 186, 187, 188, 0, + 0, 94, 107, 103, 142, 134, 92, 113, 156, 116, + 123, 148, 191, 139, 153, 97, 175, 157, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 138, 0, 0, + 0, 0, 0, 0, 0, 82, 102, 120, 190, 147, + 105, 177, 119, 0, 121, 0, 0, 158, 130, 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, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 205, 0, 210, 0, 0, 0, 0, 146, 0, - 162, 111, 119, 83, 89, 0, 110, 137, 151, 155, - 0, 0, 0, 99, 0, 153, 141, 175, 0, 142, - 152, 123, 167, 147, 174, 182, 183, 164, 181, 190, - 84, 163, 173, 96, 156, 86, 171, 161, 129, 115, - 116, 85, 0, 150, 102, 107, 101, 138, 168, 169, - 100, 193, 90, 180, 88, 91, 179, 136, 166, 172, - 130, 127, 87, 170, 128, 126, 118, 105, 112, 144, - 125, 145, 113, 133, 132, 134, 0, 0, 0, 160, - 177, 194, 93, 0, 165, 184, 185, 186, 187, 188, - 189, 0, 0, 94, 108, 104, 143, 135, 92, 114, - 157, 117, 124, 149, 192, 140, 154, 97, 176, 158, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 139, - 0, 0, 0, 0, 0, 0, 98, 82, 103, 121, - 191, 148, 106, 178, 120, 0, 122, 0, 0, 159, - 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, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 108, 0, 0, 0, 209, 0, 0, 0, 0, 145, + 0, 161, 110, 118, 83, 89, 0, 109, 136, 150, + 154, 0, 0, 0, 98, 0, 152, 140, 174, 0, + 141, 151, 122, 166, 146, 173, 181, 182, 163, 180, + 189, 84, 162, 172, 96, 155, 86, 170, 160, 128, + 114, 115, 85, 0, 149, 101, 106, 100, 137, 167, + 168, 99, 192, 90, 179, 88, 91, 178, 135, 165, + 171, 129, 126, 87, 169, 127, 125, 117, 104, 111, + 143, 124, 144, 112, 132, 131, 133, 0, 0, 0, + 159, 176, 193, 93, 0, 164, 183, 184, 185, 186, + 187, 188, 0, 0, 94, 107, 103, 142, 134, 92, + 113, 156, 116, 123, 148, 191, 139, 153, 97, 175, + 157, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 138, 82, 0, + 120, 190, 147, 105, 177, 590, 102, 0, 0, 0, + 0, 0, 119, 0, 121, 0, 0, 158, 130, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 207, 0, 0, 0, + 0, 0, 0, 0, 0, 95, 0, 0, 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, 210, 0, 0, 0, - 0, 146, 0, 162, 111, 119, 83, 89, 0, 110, - 137, 151, 155, 0, 0, 0, 99, 0, 153, 141, - 175, 0, 142, 152, 123, 167, 147, 174, 182, 183, - 164, 181, 190, 84, 163, 173, 96, 156, 86, 171, - 161, 129, 115, 116, 85, 0, 150, 102, 107, 101, - 138, 168, 169, 100, 193, 90, 180, 88, 91, 179, - 136, 166, 172, 130, 127, 87, 170, 128, 126, 118, - 105, 112, 144, 125, 145, 113, 133, 132, 134, 0, - 0, 0, 160, 177, 194, 93, 0, 165, 184, 185, - 186, 187, 188, 189, 0, 0, 94, 108, 104, 143, - 135, 92, 114, 157, 117, 124, 149, 192, 140, 154, - 97, 176, 158, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 139, 0, 0, 0, 0, 0, 0, 98, - 82, 103, 121, 191, 148, 106, 178, 120, 0, 122, - 0, 0, 159, 131, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 208, 0, 0, 0, 0, 0, 0, 0, 0, - 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 108, 0, 0, 0, 209, 0, 0, 0, 0, 145, + 0, 161, 110, 118, 83, 89, 0, 109, 136, 150, + 154, 0, 0, 0, 98, 0, 152, 140, 174, 0, + 141, 151, 122, 166, 146, 173, 181, 182, 163, 180, + 189, 84, 162, 172, 96, 155, 86, 170, 160, 128, + 114, 115, 85, 0, 149, 101, 106, 100, 137, 167, + 168, 99, 192, 90, 179, 88, 91, 178, 135, 165, + 171, 129, 126, 87, 169, 127, 125, 117, 104, 111, + 143, 124, 144, 112, 132, 131, 133, 0, 0, 0, + 159, 176, 193, 93, 0, 164, 183, 184, 185, 186, + 187, 188, 0, 0, 94, 107, 103, 142, 134, 92, + 113, 156, 116, 123, 148, 191, 139, 153, 97, 175, + 157, 0, 0, 324, 0, 0, 0, 0, 0, 0, + 138, 0, 0, 0, 0, 0, 0, 0, 82, 102, + 120, 190, 147, 105, 177, 119, 0, 121, 0, 0, + 158, 130, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 207, + 0, 0, 0, 0, 0, 0, 0, 0, 95, 0, 0, 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, 210, - 0, 0, 0, 0, 146, 0, 162, 111, 119, 83, - 89, 0, 110, 137, 151, 155, 0, 0, 0, 99, - 0, 153, 141, 175, 0, 142, 152, 123, 167, 147, - 174, 182, 183, 164, 181, 190, 84, 163, 173, 96, - 156, 86, 171, 161, 129, 115, 116, 85, 0, 150, - 102, 107, 101, 138, 168, 169, 100, 193, 90, 180, - 88, 91, 179, 136, 166, 172, 130, 127, 87, 170, - 128, 126, 118, 105, 112, 144, 125, 145, 113, 133, - 132, 134, 0, 0, 0, 160, 177, 194, 93, 0, - 165, 184, 185, 186, 187, 188, 189, 0, 0, 94, - 108, 104, 143, 135, 92, 114, 157, 117, 124, 149, - 192, 140, 154, 97, 176, 158, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 139, 0, 0, 0, 0, - 0, 0, 98, 82, 103, 121, 191, 148, 106, 178, - 120, 0, 122, 0, 0, 159, 131, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 268, 0, 0, 0, 0, 0, - 0, 0, 0, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 108, 0, 0, 0, 209, 0, 0, + 0, 0, 145, 0, 161, 110, 118, 83, 89, 0, + 109, 136, 150, 154, 0, 0, 0, 98, 0, 152, + 140, 174, 0, 141, 151, 122, 166, 146, 173, 181, + 182, 163, 180, 189, 84, 162, 172, 96, 155, 86, + 170, 160, 128, 114, 115, 85, 0, 149, 101, 106, + 100, 137, 167, 168, 99, 192, 90, 179, 88, 91, + 178, 135, 165, 171, 129, 126, 87, 169, 127, 125, + 117, 104, 111, 143, 124, 144, 112, 132, 131, 133, + 0, 0, 0, 159, 176, 193, 93, 0, 164, 183, + 184, 185, 186, 187, 188, 0, 0, 94, 107, 103, + 142, 134, 92, 113, 156, 116, 123, 148, 191, 139, + 153, 97, 175, 157, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 138, 0, 0, 0, 0, 0, 0, + 0, 82, 102, 120, 190, 147, 105, 177, 119, 0, + 121, 0, 0, 158, 130, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 207, 0, 0, 0, 0, 0, 0, 0, + 0, 95, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 108, 0, 204, 0, + 209, 0, 0, 0, 0, 145, 0, 161, 110, 118, + 83, 89, 0, 109, 136, 150, 154, 0, 0, 0, + 98, 0, 152, 140, 174, 0, 141, 151, 122, 166, + 146, 173, 181, 182, 163, 180, 189, 84, 162, 172, + 96, 155, 86, 170, 160, 128, 114, 115, 85, 0, + 149, 101, 106, 100, 137, 167, 168, 99, 192, 90, + 179, 88, 91, 178, 135, 165, 171, 129, 126, 87, + 169, 127, 125, 117, 104, 111, 143, 124, 144, 112, + 132, 131, 133, 0, 0, 0, 159, 176, 193, 93, + 0, 164, 183, 184, 185, 186, 187, 188, 0, 0, + 94, 107, 103, 142, 134, 92, 113, 156, 116, 123, + 148, 191, 139, 153, 97, 175, 157, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 138, 0, 0, 0, + 0, 0, 0, 0, 82, 102, 120, 190, 147, 105, + 177, 119, 0, 121, 0, 0, 158, 130, 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, 95, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 108, + 0, 0, 0, 209, 0, 0, 0, 0, 145, 0, + 161, 110, 118, 83, 89, 0, 109, 136, 150, 154, + 0, 0, 0, 98, 0, 152, 140, 174, 0, 141, + 151, 122, 166, 146, 173, 181, 182, 163, 180, 189, + 84, 162, 172, 96, 155, 86, 170, 160, 128, 114, + 115, 85, 0, 149, 101, 106, 100, 137, 167, 168, + 99, 192, 90, 179, 88, 91, 178, 135, 165, 171, + 129, 126, 87, 169, 127, 125, 117, 104, 111, 143, + 124, 144, 112, 132, 131, 133, 0, 0, 0, 159, + 176, 193, 93, 0, 164, 183, 184, 185, 186, 187, + 188, 0, 0, 94, 107, 103, 142, 134, 92, 113, + 156, 116, 123, 148, 191, 139, 153, 97, 175, 157, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 138, + 0, 0, 0, 0, 0, 0, 0, 82, 102, 120, + 190, 147, 105, 177, 119, 0, 121, 0, 0, 158, + 130, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 207, 0, + 0, 0, 0, 0, 0, 0, 0, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 109, 0, - 0, 0, 210, 0, 0, 0, 0, 146, 0, 162, - 111, 119, 83, 89, 0, 110, 137, 151, 155, 0, - 0, 0, 99, 0, 153, 141, 175, 0, 142, 152, - 123, 167, 147, 174, 182, 183, 164, 181, 190, 84, - 163, 173, 96, 156, 86, 171, 161, 129, 115, 116, - 85, 0, 150, 102, 107, 101, 138, 168, 169, 100, - 193, 90, 180, 88, 91, 179, 136, 166, 172, 130, - 127, 87, 170, 128, 126, 118, 105, 112, 144, 125, - 145, 113, 133, 132, 134, 0, 0, 0, 160, 177, - 194, 93, 0, 165, 184, 185, 186, 187, 188, 189, - 0, 0, 94, 108, 104, 143, 135, 92, 114, 157, - 117, 124, 149, 192, 140, 154, 97, 176, 158, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 82, 0, 121, 191, - 148, 106, 178, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 108, 0, 0, 0, 209, 0, 0, 0, + 0, 145, 0, 161, 110, 118, 83, 89, 0, 109, + 136, 150, 154, 0, 0, 0, 98, 0, 152, 140, + 174, 0, 141, 151, 122, 166, 146, 173, 181, 182, + 163, 180, 189, 84, 162, 172, 96, 155, 86, 170, + 160, 128, 114, 115, 85, 0, 149, 101, 106, 100, + 137, 167, 168, 99, 192, 90, 179, 88, 91, 178, + 135, 165, 171, 129, 126, 87, 169, 127, 125, 117, + 104, 111, 143, 124, 144, 112, 132, 131, 133, 0, + 0, 0, 159, 176, 193, 93, 0, 164, 183, 184, + 185, 186, 187, 188, 0, 0, 94, 107, 103, 142, + 134, 92, 113, 156, 116, 123, 148, 191, 139, 153, + 97, 175, 157, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 138, 0, 0, 0, 0, 0, 0, 0, + 82, 102, 120, 190, 147, 105, 177, 119, 0, 121, + 0, 0, 158, 130, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 267, 0, 0, 0, 0, 0, 0, 0, 0, + 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 108, 0, 0, 0, 209, + 0, 0, 0, 0, 145, 0, 161, 110, 118, 83, + 89, 0, 109, 136, 150, 154, 0, 0, 0, 98, + 0, 152, 140, 174, 0, 141, 151, 122, 166, 146, + 173, 181, 182, 163, 180, 189, 84, 162, 172, 96, + 155, 86, 170, 160, 128, 114, 115, 85, 0, 149, + 101, 106, 100, 137, 167, 168, 99, 192, 90, 179, + 88, 91, 178, 135, 165, 171, 129, 126, 87, 169, + 127, 125, 117, 104, 111, 143, 124, 144, 112, 132, + 131, 133, 0, 0, 0, 159, 176, 193, 93, 0, + 164, 183, 184, 185, 186, 187, 188, 0, 0, 94, + 107, 103, 142, 134, 92, 113, 156, 116, 123, 148, + 191, 139, 153, 97, 175, 157, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 82, 0, 120, 190, 147, 105, 177, } var yyPact = [...]int{ - 1902, -1000, -191, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + 1854, -1000, -193, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, 894, 922, -1000, -1000, -1000, -1000, -1000, -1000, + 218, 7888, 20, 87, -31, 11175, 86, 119, 11641, -1000, + -3, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -81, -94, + -1000, 715, -1000, -1000, -1000, -1000, -1000, 867, 892, 759, + 870, 796, -1000, 6206, 58, 58, 10942, 5462, -1000, -1000, + 207, 11641, 82, 11641, -163, 55, 55, 55, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, 848, 909, -1000, -1000, -1000, -1000, -1000, -1000, - 313, 7820, 26, 119, -29, 11118, 117, 1402, 11584, -1000, - -3, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -104, -105, - -1000, 659, -1000, -1000, -1000, -1000, -1000, 833, 837, 689, - 828, 756, -1000, 6129, 77, 77, 10885, 5385, -1000, -1000, - 256, 11584, 106, 11584, -162, 68, 68, 68, -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, @@ -1940,22 +1946,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, -1000, -1000, -1000, 85, 11641, 201, -1000, 11641, 53, + 478, 53, 53, 53, 11641, -1000, 137, -1000, -1000, -1000, + 11641, 476, 819, 3374, 33, 3374, -1000, 3374, 3374, -1000, + 3374, 3, 3374, -75, 904, -1000, -1000, -1000, -1000, -50, + -1000, 3374, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, 508, 832, 6705, 6705, 894, + -1000, 715, -1000, -1000, -1000, 820, -1000, -1000, 275, 911, + -1000, 7655, 134, -1000, 6705, 1528, 708, -1000, -1000, 708, + -1000, -1000, 122, -1000, -1000, 7183, 7183, 7183, 7183, 7183, + 7183, 7183, 7183, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, 708, -1000, 6457, + 708, 708, 708, 708, 708, 708, 708, 708, 6705, 708, + 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, + 708, 708, 10709, 9537, 11641, 504, -1000, 686, 5201, -91, + -1000, -1000, -1000, 204, 9304, -1000, -1000, -1000, 818, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, 116, 11584, 189, -1000, 11584, - 66, 503, 66, 66, 66, 11584, -1000, 175, -1000, -1000, - -1000, 11584, 491, 797, 3297, 35, 3297, -1000, 3297, 3297, - -1000, 3297, 5, 3297, -77, 869, -1000, -1000, -1000, -1000, - -53, -1000, 3297, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, 405, 804, 6628, 6628, - 848, -1000, 659, -1000, -1000, -1000, 792, -1000, -1000, 314, - 877, -1000, 7587, 173, -1000, 6628, 2087, 644, -1000, -1000, - 644, -1000, -1000, 135, -1000, -1000, 7112, 7112, 7112, 7112, - 7112, 7112, 7112, 7112, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 644, -1000, - 6380, 644, 644, 644, 644, 644, 644, 644, 644, 6628, - 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, - 644, 644, 644, 10652, 9478, 11584, 591, -1000, 633, 5124, - -90, -1000, -1000, -1000, 238, 9245, -1000, -1000, -1000, 775, -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, @@ -1964,130 +1970,129 @@ 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, 598, 11641, -1000, 2036, -1000, 471, 3374, + 67, 463, 257, 460, 11641, 11641, 3374, 12, 41, 84, + 11641, 706, 65, 11641, 856, 763, 11641, 448, 444, -1000, + 4940, -1000, 3374, 3374, -1000, -1000, -1000, 3374, 3374, 3374, + 3374, 3374, 3374, -1000, -1000, -1000, -1000, 3374, 3374, -1000, + 909, 256, -1000, -1000, -1000, -1000, 6705, -1000, 762, -1000, + -1000, -1000, -1000, -1000, -1000, 917, 177, 430, 133, 695, + -1000, 371, 867, 508, 796, 9065, 773, -1000, -1000, 11641, + -1000, 6705, 6705, 339, -1000, 10469, -1000, -1000, 3896, 168, + 7183, 351, 285, 7183, 7183, 7183, 7183, 7183, 7183, 7183, + 7183, 7183, 7183, 7183, 7183, 7183, 7183, 7183, 396, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, 442, -1000, 715, + 525, 525, 148, 148, 148, 148, 148, 148, 148, 7422, + 5710, 508, 550, 281, 6457, 6206, 6206, 6705, 6705, 10236, + 10003, 6206, 860, 227, 281, 11874, -1000, 508, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, 6206, 6206, 6206, 6206, 24, + 11641, -1000, 615, 700, -1000, -1000, -1000, 858, 8599, 8832, + 24, 643, 9537, 11641, -1000, -1000, 4679, 686, -91, 678, + -1000, -130, -103, 2566, 124, -1000, -1000, -1000, -1000, 3113, + 172, 554, 316, -64, -1000, -1000, -1000, 718, -1000, 718, + 718, 718, 718, -32, -32, -32, -32, -1000, -1000, -1000, + -1000, -1000, 742, 741, -1000, 718, 718, 718, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, 538, 11584, -1000, 2187, -1000, 488, - 3297, 91, 486, 295, 472, 11584, 11584, 3297, 23, 61, - 108, 11584, 639, 81, 11584, 821, 713, 11584, 464, 441, - -1000, 4863, -1000, 3297, 3297, -1000, -1000, -1000, 3297, 3297, - 3297, 3297, 3297, 3297, -1000, -1000, -1000, -1000, 3297, 3297, - -1000, 871, 258, -1000, -1000, -1000, -1000, 6628, -1000, 712, - -1000, -1000, -1000, -1000, -1000, -1000, 904, 190, 289, 171, - 637, -1000, 304, 833, 405, 756, 9003, 727, -1000, -1000, - 11584, -1000, 6628, 6628, 418, -1000, 10410, -1000, -1000, 3819, - 201, 7112, 338, 247, 7112, 7112, 7112, 7112, 7112, 7112, - 7112, 7112, 7112, 7112, 7112, 7112, 7112, 7112, 7112, 347, - -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 438, -1000, - 659, 479, 479, 182, 182, 182, 182, 182, 182, 182, - 7354, 5633, 405, 533, 221, 6380, 6129, 6129, 6628, 6628, - 10177, 9944, 6129, 830, 271, 221, 11817, -1000, 405, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, 6129, 6129, 6129, 6129, - 38, 11584, -1000, 642, 690, -1000, -1000, -1000, 824, 8537, - 8770, 38, 609, 9478, 11584, -1000, -1000, 4602, 633, -90, - 623, -1000, -133, -127, 2489, 167, -1000, -1000, -1000, -1000, - 3036, 352, 525, 285, -89, -1000, -1000, -1000, 662, -1000, - 662, 662, 662, 662, -32, -32, -32, -32, -1000, -1000, - -1000, -1000, -1000, 704, 686, -1000, 662, 662, 662, -1000, + -1000, -1000, -1000, -1000, 739, 739, 739, 724, 724, 744, + -1000, 11641, 3374, 854, 3374, -1000, 108, -1000, 11408, 11408, + 11641, 11641, 113, 11641, 11641, 684, -1000, 11641, 3374, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, 677, 677, 677, 666, 666, - 661, -1000, 11584, 3297, 819, 3297, -1000, 93, -1000, 11351, - 11351, 11584, 11584, 130, 11584, 11584, 632, -1000, 11584, 3297, + -1000, -1000, -1000, -1000, 11641, 288, 11641, 11641, 281, 11641, + -1000, 802, 6705, 6705, 4418, 6705, -1000, -1000, -1000, 832, + -1000, 860, 886, -1000, 812, 809, 6206, -1000, -1000, 168, + 230, -1000, -1000, 397, -1000, -1000, -1000, -1000, 132, 708, + -1000, 2052, -1000, -1000, -1000, -1000, 351, 7183, 7183, 7183, + 451, 2052, 2193, 999, 393, 148, 265, 265, 144, 144, + 144, 144, 144, 329, 329, -1000, -1000, -1000, 508, -1000, + -1000, -1000, 508, 6206, 680, -1000, -1000, 6705, -1000, 508, + 539, 539, 386, 255, 683, 682, -1000, 127, 679, 658, + 539, 6206, 242, -1000, 6705, 508, -1000, 539, 508, 539, + 539, 665, 708, -1000, 11874, 9537, 9537, 9537, 9537, 9537, + -1000, 785, 784, -1000, 777, 775, 786, 11641, -1000, 546, + 8599, 136, 708, -1000, 9770, -1000, -1000, 903, 9537, 596, + -1000, -1000, 678, -91, -95, -1000, -1000, -1000, -1000, 281, + -1000, 423, 671, 2852, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, 737, 424, -1000, 843, 166, 165, 417, 842, -1000, + -1000, -1000, 823, -1000, 262, -77, -1000, -1000, 374, -32, + -32, -1000, -1000, 124, 817, 124, 124, 124, 403, 403, + -1000, -1000, -1000, -1000, 357, -1000, -1000, -1000, 354, -1000, + 760, 11408, 3374, -1000, -1000, -1000, -1000, 250, 250, 219, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, 11584, 280, 11584, 11584, 221, - 11584, -1000, 761, 6628, 6628, 4341, 6628, -1000, -1000, -1000, - 804, -1000, 830, 845, -1000, 769, 768, 6129, -1000, -1000, - 201, 308, -1000, -1000, 374, -1000, -1000, -1000, -1000, 159, - 644, -1000, 2317, -1000, -1000, -1000, -1000, 338, 7112, 7112, - 7112, 75, 2317, 2397, 455, 331, 182, 157, 157, 184, - 184, 184, 184, 184, 829, 829, -1000, -1000, -1000, 405, - -1000, -1000, -1000, 405, 6129, 629, -1000, -1000, 6628, -1000, - 405, 519, 519, 279, 293, 660, 652, -1000, 158, 650, - 647, 519, 6129, 262, -1000, 6628, 405, -1000, 519, 405, - 519, 519, 557, 644, -1000, 11817, 9478, 9478, 9478, 9478, - 9478, -1000, 745, 737, -1000, 726, 724, 744, 11584, -1000, - 529, 8537, 152, 644, -1000, 9711, -1000, -1000, 867, 9478, - 585, -1000, -1000, 623, -90, -97, -1000, -1000, -1000, -1000, - 221, -1000, 363, 622, 2775, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, 673, 436, -1000, 811, 195, 198, 428, 810, - -1000, -1000, -1000, 800, -1000, 306, -71, -1000, -1000, 354, - -32, -32, -1000, -1000, 167, 774, 167, 167, 167, 395, - 395, -1000, -1000, -1000, -1000, 351, -1000, -1000, -1000, 348, - -1000, 711, 11351, 3297, -1000, -1000, -1000, -1000, 286, 286, - 207, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, 36, 651, -1000, -1000, -1000, 10, 9, 79, - -1000, 3297, -1000, 258, -1000, 394, 6628, -1000, -1000, -1000, - 755, 221, 221, 150, -1000, -1000, 11584, -1000, -1000, -1000, - -1000, 641, -1000, -1000, -1000, 3558, 6129, -1000, 75, 2317, - 2334, -1000, 7112, 7112, -1000, -1000, 519, 6129, 221, -1000, - -1000, -1000, 54, 347, 54, 7112, 7112, 7112, 7112, 4341, - 7112, 7112, 7112, 7112, -175, 636, 254, -1000, 6628, 275, - -1000, -1000, -1000, -1000, -1000, 710, 11817, 644, -1000, 8295, - 11351, 594, -1000, 234, 690, 701, 709, 772, -1000, -1000, - -1000, -1000, 736, -1000, 732, -1000, -1000, -1000, -1000, -1000, - 104, 103, 101, 11351, -1000, 848, 6628, 585, -1000, -1000, - -1000, -138, -136, -1000, -1000, -1000, 3036, -1000, 3036, 11351, - 50, -1000, 428, 428, -1000, -1000, -1000, 668, 708, 39, - -1000, -1000, -1000, 520, 167, 167, -1000, 197, -1000, -1000, - -1000, 512, -1000, 510, 620, 468, 11584, -1000, -1000, -1000, + -1000, 22, 735, -1000, -1000, -1000, 11, 10, 64, -1000, + 3374, -1000, 256, -1000, 391, 6705, -1000, -1000, -1000, 799, + 281, 281, 126, -1000, -1000, 11641, -1000, -1000, -1000, -1000, + 623, -1000, -1000, -1000, 3635, 6206, -1000, 451, 2052, 1357, + -1000, 7183, 7183, -1000, -1000, 539, 6206, 281, -1000, -1000, + -1000, 72, 396, 72, 7183, 7183, 7183, 7183, 4418, 7183, + 7183, 7183, 7183, -173, 642, 211, -1000, 6705, 313, -1000, + -1000, -1000, -1000, -1000, 752, 11874, 708, -1000, 8360, 11408, + 651, -1000, 200, 700, 734, 750, 711, -1000, -1000, -1000, + -1000, 781, -1000, 778, -1000, -1000, -1000, -1000, -1000, 80, + 79, 78, 11408, -1000, 894, 6705, 596, -1000, -1000, -1000, + -138, -144, -1000, -1000, -1000, 3113, -1000, 3113, 11408, 40, + -1000, 417, 417, -1000, -1000, -1000, 731, 749, 71, -1000, + -1000, -1000, 540, 124, 124, -1000, 163, -1000, -1000, -1000, + 518, -1000, 515, 657, 511, 11641, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, 11584, -1000, -1000, -1000, -1000, -1000, 11351, - -180, 426, 11351, 11351, 11584, -1000, 280, -1000, 221, -1000, - 4080, -1000, 867, 9478, -1000, -1000, 405, -1000, 7112, 2317, - 2317, -1000, -1000, 405, 662, 662, -1000, 662, 666, -1000, - 662, -15, 662, -16, 405, 405, 1779, 2302, 1674, 2157, - -1000, 1639, 1822, 1585, 1128, 644, -169, -1000, 221, 6628, - -1000, 814, 543, 548, -1000, -1000, 5881, 405, 463, 141, - 459, -1000, 848, 11817, 6628, -1000, -1000, 6628, 663, -1000, - 6628, -1000, -1000, -1000, 644, 644, 644, 459, 833, 221, - -1000, -1000, -1000, -1000, 2775, -1000, 457, -1000, 662, -1000, - -1000, -1000, 11351, -63, 901, -1000, -1000, -1000, -1000, 656, - -1000, -1000, -1000, -1000, -1000, -1000, -32, 392, -32, 340, - -1000, 336, 3297, -1000, -1000, -1000, -1000, 806, -1000, 4080, - -1000, -1000, 649, -1000, -1000, -1000, 865, 590, -1000, 2317, - -1000, -1000, 97, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, 7112, 7112, -1000, 7112, 7112, -1000, 7112, 7112, - -1000, 7112, 7112, 7112, 405, 386, 221, 809, -1000, 644, - -1000, -1000, 601, 11351, 11351, -1000, 11351, 833, -1000, 221, - 221, 11351, 221, 11351, 11351, 11351, 8053, -1000, 142, 11351, - -1000, 453, -1000, 170, -1000, -151, 513, 167, -1000, 167, - 460, 419, -1000, 644, 554, -1000, 226, 11351, 855, 836, - -1000, -1000, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, - 33, -1000, -1000, 888, -1000, 644, -1000, 659, 139, -1000, - -1000, -1000, 450, 447, 447, 447, 152, 142, -1000, 406, - 214, 380, -1000, 46, 11351, 317, 805, -1000, 803, 646, - -1000, -1000, -1000, -1000, -1000, 34, 4080, 3036, 422, -1000, - 6628, 6628, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - 405, 37, -183, 11817, 548, 405, 11351, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, 334, -1000, -1000, 11584, -1000, -1000, - 362, -1000, -1000, 412, 411, -1000, 11351, -1000, -1000, 651, - 221, 541, -1000, 753, -178, -187, 531, -1000, -1000, -1000, - 645, -1000, -1000, -1000, 34, 767, -180, -1000, 730, -1000, - 11351, -1000, 30, -1000, -181, 404, 27, -185, 703, 644, - -188, 692, -1000, 882, 6870, -1000, -1000, 886, 162, 162, - 1443, 405, -1000, -1000, -1000, 58, 344, -1000, -1000, -1000, - -1000, -1000, -1000, + -1000, -1000, 11641, -1000, -1000, -1000, -1000, -1000, 11408, -181, + 399, 11408, 11408, 11641, -1000, 288, -1000, 281, -1000, 4157, + -1000, 903, 9537, -1000, -1000, 508, -1000, 7183, 2052, 2052, + -1000, -1000, 508, 718, 718, -1000, 718, 724, -1000, 718, + -12, 718, -13, 508, 508, 1843, 2151, 1671, 2025, -1000, + 1635, 1992, 1320, 1974, 708, -170, -1000, 281, 6705, -1000, + 845, 622, 647, -1000, -1000, 5958, 508, 506, 103, 486, + -1000, 894, 11874, 6705, -1000, -1000, 6705, 723, -1000, 6705, + -1000, -1000, -1000, 708, 708, 708, 486, 867, 281, -1000, + -1000, -1000, -1000, 2852, -1000, 484, -1000, 718, -1000, -1000, + -1000, 11408, -56, 916, -1000, -1000, -1000, -1000, 717, -1000, + -1000, -1000, -1000, -1000, -1000, -32, 383, -32, 350, -1000, + 333, 3374, -1000, -1000, -1000, -1000, 849, -1000, 4157, -1000, + -1000, 716, -1000, -1000, -1000, 900, 654, -1000, 2052, -1000, + -1000, 100, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, 7183, 7183, -1000, 7183, 7183, -1000, 7183, 7183, -1000, + 7183, 7183, 7183, 508, 379, 281, 830, -1000, 708, -1000, + -1000, 670, 11408, 11408, -1000, 11408, 867, -1000, 281, 281, + 11408, 281, 11408, 11408, 11408, 8121, -1000, 131, 11408, -1000, + 482, -1000, 185, -1000, -153, 534, 124, -1000, 124, 524, + 519, -1000, 708, 648, -1000, 199, 11408, 898, 891, -1000, + -1000, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 17, + -1000, -1000, 914, -1000, 708, -1000, 715, 83, -1000, -1000, + -1000, 467, 458, 458, 458, 136, 131, -1000, 395, 176, + 378, -1000, 37, 11408, 266, 829, -1000, 827, 714, -1000, + -1000, -1000, -1000, -1000, 21, 4157, 3113, 456, -1000, 6705, + 6705, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 508, + 34, -184, 11874, 647, 508, 11408, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, 302, -1000, -1000, 11641, -1000, -1000, 340, + -1000, -1000, 512, 452, -1000, 11408, -1000, -1000, 735, 281, + 628, -1000, 795, -179, -187, 586, -1000, -1000, -1000, 713, + -1000, -1000, -1000, 21, 808, -181, -1000, 793, -1000, 11408, + -1000, 18, -1000, -182, 428, 16, -185, 748, 708, -189, + 747, -1000, 908, 6944, -1000, -1000, 910, 152, 152, 1858, + 508, -1000, -1000, -1000, 44, 326, -1000, -1000, -1000, -1000, + -1000, -1000, } var yyPgo = [...]int{ - 0, 1124, 33, 440, 1123, 1117, 1116, 1113, 1108, 1106, - 1105, 1104, 1103, 1102, 1101, 1100, 1099, 1098, 1097, 1096, - 1095, 1092, 1090, 1089, 1086, 1082, 87, 1079, 1078, 1077, - 64, 1073, 65, 1072, 1071, 46, 520, 53, 38, 1151, - 1070, 35, 66, 59, 1069, 28, 1068, 1064, 79, 1063, - 48, 1061, 1058, 201, 1055, 1053, 22, 44, 1051, 1050, - 1049, 1048, 90, 1042, 1047, 1046, 1044, 1041, 1040, 1039, - 52, 8, 12, 47, 13, 1037, 50, 6, 1034, 49, - 1033, 1031, 1028, 1025, 16, 1022, 55, 1020, 18, 56, - 1019, 15, 58, 31, 19, 7, 69, 60, 1018, 17, - 61, 54, 1017, 1016, 391, 1015, 1013, 41, 1012, 1010, - 24, 152, 372, 1009, 1008, 1007, 1006, 29, 0, 504, - 327, 63, 1005, 1003, 998, 1519, 70, 45, 20, 997, - 73, 277, 40, 989, 988, 37, 986, 982, 981, 980, - 979, 972, 970, 272, 966, 964, 963, 30, 21, 962, - 961, 62, 23, 960, 959, 958, 43, 57, 957, 956, - 51, 26, 955, 954, 950, 949, 947, 27, 9, 944, - 14, 943, 10, 941, 25, 940, 4, 939, 11, 938, - 3, 934, 5, 42, 1, 925, 2, 923, 918, 311, - 701, 917, 916, 71, + 0, 1146, 33, 449, 1145, 1144, 1143, 1142, 1141, 1139, + 1138, 1136, 1135, 1130, 1126, 1125, 1123, 1116, 1110, 1109, + 1108, 1092, 1091, 1089, 1088, 1087, 99, 1086, 1085, 1081, + 71, 1078, 60, 1077, 1076, 46, 76, 50, 41, 391, + 1072, 35, 53, 59, 1071, 38, 1070, 1069, 64, 1068, + 48, 1065, 1063, 201, 1060, 1059, 10, 30, 1058, 1057, + 1054, 1052, 98, 1042, 1050, 1049, 1048, 1046, 1045, 1044, + 51, 8, 12, 47, 19, 1043, 416, 6, 1040, 52, + 1039, 1036, 1033, 1032, 16, 1030, 57, 1027, 18, 56, + 1024, 15, 65, 28, 20, 7, 69, 58, 1018, 14, + 61, 54, 1017, 1016, 411, 1014, 1012, 42, 1011, 1009, + 26, 154, 326, 1008, 1007, 1004, 1002, 37, 0, 504, + 418, 63, 1001, 999, 997, 1597, 70, 49, 17, 988, + 55, 1216, 40, 987, 985, 31, 981, 980, 979, 978, + 971, 970, 969, 84, 966, 964, 963, 24, 22, 962, + 961, 62, 23, 958, 957, 955, 44, 66, 954, 953, + 45, 29, 950, 949, 948, 947, 946, 27, 9, 943, + 13, 941, 21, 940, 25, 939, 4, 935, 11, 934, + 3, 933, 5, 43, 1, 932, 2, 931, 930, 311, + 701, 929, 928, 107, } var yyR1 = [...]int{ @@ -2175,8 +2180,8 @@ var yyR1 = [...]int{ 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, - 118, 118, 118, 118, 118, 118, 118, 189, 190, 130, - 131, 131, 131, + 118, 118, 118, 118, 118, 118, 189, 190, 130, 131, + 131, 131, } var yyR2 = [...]int{ @@ -2264,8 +2269,8 @@ 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, 1, 1, 0, - 0, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, + 1, 1, } var yyChk = [...]int{ @@ -2278,140 +2283,140 @@ var yyChk = [...]int{ 5, -26, -192, -26, -26, -26, -26, -26, -163, -165, 54, 90, -116, 125, 72, 243, 122, 123, 129, -119, 57, -118, 259, 135, 162, 173, 167, 194, 186, 136, - 184, 187, 230, 214, 225, 66, 165, 239, 25, 145, - 182, 178, 176, 27, 227, 199, 264, 177, 226, 121, - 138, 133, 200, 204, 231, 171, 172, 233, 198, 134, - 33, 261, 35, 153, 234, 202, 197, 193, 196, 170, - 192, 39, 206, 205, 207, 229, 189, 139, 179, 18, - 237, 148, 151, 228, 201, 203, 130, 155, 263, 235, - 175, 140, 152, 147, 238, 141, 166, 232, 241, 38, - 211, 169, 132, 163, 159, 216, 190, 154, 180, 181, - 195, 168, 191, 164, 156, 149, 240, 212, 265, 188, - 185, 160, 157, 158, 217, 218, 219, 220, 221, 222, - 161, 262, 236, 183, 213, -104, 125, 220, 127, 123, - 123, 124, 125, 243, 122, 123, -53, -125, 57, -118, - 125, 123, 108, 187, 230, 115, 215, 227, 124, 33, - 228, 155, -134, 123, -106, 214, 217, 218, 219, 222, - 220, 161, 57, 232, 231, 223, -125, 164, -130, -130, - -130, -130, -130, 216, 216, -130, -2, -88, 17, 16, - -5, -3, -189, 6, 20, 21, -32, 40, 41, -27, - -38, 99, -39, -125, -58, 74, -63, 29, 57, -118, - 23, -62, -59, -77, -75, -76, 108, 109, 110, 97, - 98, 105, 75, 111, -67, -65, -66, -68, 59, 58, - 67, 60, 61, 62, 63, 68, 69, 70, -119, -73, - -189, 44, 45, 252, 253, 254, 255, 258, 256, 77, - 34, 242, 250, 249, 248, 246, 247, 244, 245, 128, - 243, 103, 251, -104, -104, 11, -48, -53, -96, -133, - 164, -100, 232, 231, -120, -98, -119, -117, 230, 187, - 229, 120, 73, 22, 24, 209, 76, 108, 16, 77, - 107, 252, 115, 48, 244, 245, 242, 254, 255, 243, - 215, 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, 246, 247, 31, 258, 150, 103, 49, - 36, 74, 68, 71, 52, 72, 15, 47, 91, 118, - 251, 45, 122, 6, 257, 30, 142, 43, 123, 79, - 126, 69, 5, 129, 32, 9, 50, 53, 248, 249, - 250, 34, 78, 12, -164, 90, -157, 57, -53, 124, - -53, 251, -112, 128, -112, -112, 123, -53, 115, 117, - 120, 52, -18, -53, -111, 128, 57, -111, -111, -111, - -53, 112, -53, 57, 30, -131, -189, -120, 243, 57, - 155, 123, 156, 125, -131, -131, -131, -131, 159, 160, - -131, -109, -108, 225, 226, 216, 224, 12, 216, 158, - -131, -130, -130, -190, 56, -89, 19, 31, -39, -125, - -85, -86, -39, -84, -2, -26, 36, -30, 21, 65, - 11, -122, 73, 72, 89, -121, 22, -119, 59, 112, - -39, -60, 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, -105, -189, -76, - -189, 113, 114, -63, -63, -63, -63, -63, -63, -63, - -63, -189, -2, -71, -39, -189, -189, -189, -189, -189, - -189, -189, -189, -189, -80, -39, -189, -193, -189, -193, - -193, -193, -193, -193, -193, -193, -189, -189, -189, -189, - -54, 26, -53, -41, -42, -43, -44, -55, -76, -189, - -53, -53, -48, -191, 55, 11, 53, 55, -96, 164, - -97, -101, 233, 235, 82, -124, -119, 59, 29, 30, - 56, 55, -53, -136, -139, -141, -140, -142, -137, -138, - 184, 185, 108, 188, 190, 191, 192, 193, 194, 195, - 196, 197, 198, 199, 30, 145, 180, 181, 182, 183, - 200, 201, 202, 203, 204, 205, 206, 207, 167, 168, - 169, 170, 171, 172, 173, 175, 176, 177, 178, 179, - 57, -131, 125, 57, 74, 57, -53, -53, -131, 157, - 157, 123, 123, -53, 55, 126, -48, 23, 52, -53, - 57, 57, -126, -125, -117, -131, -131, -131, -131, -131, - -131, -131, -131, -131, -131, 11, -107, 11, 92, -39, - 52, 9, 92, 55, 18, 112, 55, -87, 24, 25, - -88, -190, -32, -64, -119, 60, 63, -31, 43, -53, - -39, -39, -69, 68, 74, 69, 70, -121, 99, -126, - -120, -117, -63, -70, -73, -76, 64, 92, 90, 91, - 76, -63, -63, -63, -63, -63, -63, -63, -63, -63, - -63, -63, -63, -63, -63, -63, -132, 57, 59, 57, - -62, -62, -119, -37, 21, -36, -38, -190, 55, -190, - -2, -36, -36, -39, -39, -77, 59, -119, -125, -77, - 59, -36, -30, -78, -79, 78, -77, -190, -36, -37, - -36, -36, -92, 151, -53, 30, 55, -49, -51, -50, - -52, 42, 46, 48, 43, 44, 45, 49, -129, 22, - -41, -189, -128, 151, -127, 22, -125, 59, -92, 53, - -41, -53, -100, -97, 55, 234, 236, 237, 52, 71, - -39, -148, 107, -166, -167, -168, -120, 59, 60, -157, - -158, -159, -169, 137, -174, 130, 132, 129, -160, 138, - 124, 28, 56, -153, 68, 74, -149, 212, -143, 54, - -143, -143, -143, -143, -147, 187, -147, -147, -147, 54, - 54, -143, -143, -143, -151, 54, -151, -151, -152, 54, - -152, -123, 53, -53, -131, 23, -131, -113, 120, 117, - 118, -177, 116, 209, 187, 66, 29, 15, 252, 151, - 265, 57, 152, -119, -119, -53, -53, 120, 117, -53, - -53, -53, -131, -53, -110, 90, 12, -125, -125, -53, - 38, -39, -39, -126, -86, -89, -103, 19, 11, 34, - 34, -36, 68, 69, 70, 112, -189, -70, -63, -63, - -63, -35, 146, 73, -190, -190, -36, 55, -39, -190, - -190, -190, 55, 53, 22, 55, 11, 55, 11, 112, - 55, 11, 55, 11, -190, -36, -81, -79, 80, -39, - -190, -190, -190, -190, -190, -61, 30, 34, -2, -189, - -189, -95, -99, -77, -42, -43, -43, -42, -43, 42, - 42, 42, 47, 42, 47, 42, -50, -125, -190, -56, - 50, 127, 51, -189, -127, -57, 12, -41, -57, -101, - -102, 238, 235, 241, 57, 59, 55, -168, 82, 54, - 57, 28, -160, -160, -161, 57, -161, 28, -144, 29, - 68, -150, 213, 60, -147, -147, -148, 30, -148, -148, - -148, -156, 59, -156, 60, 60, 52, -119, -131, -130, - -183, 131, 137, 138, 133, 57, 124, 28, 130, 132, - 151, 129, -183, -114, -115, 126, 22, 124, 28, 151, - -182, 53, 157, 157, 126, -131, -107, 59, -39, 39, - 112, -53, -40, 11, 99, -120, -37, -35, 73, -63, - -63, -190, -38, -135, 108, 184, 145, 182, 178, 198, - 189, 211, 180, 212, -132, -135, -63, -63, -63, -63, - -120, -63, -63, -63, -63, 259, -84, 81, -39, 79, - -94, 52, -95, -72, -74, -73, -189, -2, -90, -119, - -93, -119, -57, 55, 82, -46, -45, 52, 53, -47, - 52, -45, 42, 42, 124, 124, 124, -93, -84, -39, - -57, 235, 239, 240, -167, -168, -171, -170, -119, -174, - -161, -161, 54, -146, 52, 59, 60, 61, 68, 242, - 67, 56, -148, -148, 57, 108, 56, 55, 56, 55, - 56, 55, -53, -130, -130, -53, -130, -119, -180, 262, - -181, 57, -119, -119, -53, -110, -57, -41, -190, -63, - -190, -143, -143, -143, -152, -143, 172, -143, 172, -190, - -190, -190, 55, 19, -190, 55, 19, -190, 55, 19, - -190, 55, 19, -189, -34, 257, -39, 27, -94, 55, - -190, -190, -190, 55, 112, -190, 55, -84, -99, -39, - -39, 54, -39, -189, -189, -189, -190, -88, 56, 55, - -143, -91, -119, -154, 209, 9, 54, -147, 59, -147, - 60, 60, -131, 26, -179, -178, -120, 54, -82, 13, - -147, 57, -63, -63, -63, -63, -63, -63, -63, -63, - -63, -190, 59, 28, -74, 34, -2, -189, -119, -119, - -119, -88, -91, -91, -91, -91, -128, -173, -172, 53, - 134, 66, -170, 56, 55, -155, 130, 28, 129, 242, - 56, -148, -148, 56, 56, -189, 55, 82, -91, -83, - 14, 16, -190, -190, -190, -190, -190, -190, -190, -190, - -33, 92, 262, 9, -72, -2, 112, 56, -190, -190, - -190, -56, -172, 57, -162, 82, 59, 140, -119, -145, - 66, 28, 28, 54, -175, -176, 151, -178, -168, 56, - -39, -71, -190, 260, 49, 263, -95, -190, -119, 60, - -53, 59, 56, -190, 55, -119, -182, 39, 261, 264, - 54, -176, 34, -180, 39, -91, 153, 262, 56, 154, - 263, -185, -186, 52, -189, 264, -186, 52, 10, 9, - -63, 150, -184, 141, 136, 139, 30, -184, -190, -190, - 135, 29, 68, + 184, 187, 230, 214, 225, 66, 165, 239, 145, 182, + 178, 176, 27, 227, 199, 264, 177, 226, 121, 138, + 133, 200, 204, 231, 171, 172, 233, 198, 134, 33, + 261, 35, 153, 234, 202, 197, 193, 196, 170, 192, + 39, 206, 205, 207, 229, 189, 139, 179, 18, 237, + 148, 151, 228, 201, 203, 130, 155, 263, 235, 175, + 140, 152, 147, 238, 141, 166, 232, 241, 38, 211, + 169, 132, 163, 159, 216, 190, 154, 180, 181, 195, + 168, 191, 164, 156, 149, 240, 212, 265, 188, 185, + 160, 157, 158, 217, 218, 219, 220, 221, 222, 161, + 262, 236, 183, 213, -104, 125, 220, 127, 123, 123, + 124, 125, 243, 122, 123, -53, -125, 57, -118, 125, + 123, 108, 187, 230, 115, 215, 227, 124, 33, 228, + 155, -134, 123, -106, 214, 217, 218, 219, 222, 220, + 161, 57, 232, 231, 223, -125, 164, -130, -130, -130, + -130, -130, 216, 216, -130, -2, -88, 17, 16, -5, + -3, -189, 6, 20, 21, -32, 40, 41, -27, -38, + 99, -39, -125, -58, 74, -63, 29, 57, -118, 23, + -62, -59, -77, -75, -76, 108, 109, 110, 97, 98, + 105, 75, 111, -67, -65, -66, -68, 59, 58, 67, + 60, 61, 62, 63, 68, 69, 70, -119, -73, -189, + 44, 45, 252, 253, 254, 255, 258, 256, 77, 34, + 242, 250, 249, 248, 246, 247, 244, 245, 128, 243, + 103, 251, -104, -104, 11, -48, -53, -96, -133, 164, + -100, 232, 231, -120, -98, -119, -117, 230, 187, 229, + 120, 73, 22, 24, 209, 76, 108, 16, 77, 107, + 252, 115, 48, 244, 245, 242, 254, 255, 243, 215, + 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, 246, 247, 31, 258, 150, 103, 49, 36, + 74, 68, 71, 52, 72, 15, 47, 91, 118, 251, + 45, 122, 6, 257, 30, 142, 43, 123, 79, 126, + 69, 5, 129, 32, 9, 50, 53, 248, 249, 250, + 34, 78, 12, -164, 90, -157, 57, -53, 124, -53, + 251, -112, 128, -112, -112, 123, -53, 115, 117, 120, + 52, -18, -53, -111, 128, 57, -111, -111, -111, -53, + 112, -53, 57, 30, -131, -189, -120, 243, 57, 155, + 123, 156, 125, -131, -131, -131, -131, 159, 160, -131, + -109, -108, 225, 226, 216, 224, 12, 216, 158, -131, + -130, -130, -190, 56, -89, 19, 31, -39, -125, -85, + -86, -39, -84, -2, -26, 36, -30, 21, 65, 11, + -122, 73, 72, 89, -121, 22, -119, 59, 112, -39, + -60, 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, -105, -189, -76, -189, + 113, 114, -63, -63, -63, -63, -63, -63, -63, -63, + -189, -2, -71, -39, -189, -189, -189, -189, -189, -189, + -189, -189, -189, -80, -39, -189, -193, -189, -193, -193, + -193, -193, -193, -193, -193, -189, -189, -189, -189, -54, + 26, -53, -41, -42, -43, -44, -55, -76, -189, -53, + -53, -48, -191, 55, 11, 53, 55, -96, 164, -97, + -101, 233, 235, 82, -124, -119, 59, 29, 30, 56, + 55, -53, -136, -139, -141, -140, -142, -137, -138, 184, + 185, 108, 188, 190, 191, 192, 193, 194, 195, 196, + 197, 198, 199, 30, 145, 180, 181, 182, 183, 200, + 201, 202, 203, 204, 205, 206, 207, 167, 168, 169, + 170, 171, 172, 173, 175, 176, 177, 178, 179, 57, + -131, 125, 57, 74, 57, -53, -53, -131, 157, 157, + 123, 123, -53, 55, 126, -48, 23, 52, -53, 57, + 57, -126, -125, -117, -131, -131, -131, -131, -131, -131, + -131, -131, -131, -131, 11, -107, 11, 92, -39, 52, + 9, 92, 55, 18, 112, 55, -87, 24, 25, -88, + -190, -32, -64, -119, 60, 63, -31, 43, -53, -39, + -39, -69, 68, 74, 69, 70, -121, 99, -126, -120, + -117, -63, -70, -73, -76, 64, 92, 90, 91, 76, + -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, + -63, -63, -63, -63, -63, -132, 57, 59, 57, -62, + -62, -119, -37, 21, -36, -38, -190, 55, -190, -2, + -36, -36, -39, -39, -77, 59, -119, -125, -77, 59, + -36, -30, -78, -79, 78, -77, -190, -36, -37, -36, + -36, -92, 151, -53, 30, 55, -49, -51, -50, -52, + 42, 46, 48, 43, 44, 45, 49, -129, 22, -41, + -189, -128, 151, -127, 22, -125, 59, -92, 53, -41, + -53, -100, -97, 55, 234, 236, 237, 52, 71, -39, + -148, 107, -166, -167, -168, -120, 59, 60, -157, -158, + -159, -169, 137, -174, 130, 132, 129, -160, 138, 124, + 28, 56, -153, 68, 74, -149, 212, -143, 54, -143, + -143, -143, -143, -147, 187, -147, -147, -147, 54, 54, + -143, -143, -143, -151, 54, -151, -151, -152, 54, -152, + -123, 53, -53, -131, 23, -131, -113, 120, 117, 118, + -177, 116, 209, 187, 66, 29, 15, 252, 151, 265, + 57, 152, -119, -119, -53, -53, 120, 117, -53, -53, + -53, -131, -53, -110, 90, 12, -125, -125, -53, 38, + -39, -39, -126, -86, -89, -103, 19, 11, 34, 34, + -36, 68, 69, 70, 112, -189, -70, -63, -63, -63, + -35, 146, 73, -190, -190, -36, 55, -39, -190, -190, + -190, 55, 53, 22, 55, 11, 55, 11, 112, 55, + 11, 55, 11, -190, -36, -81, -79, 80, -39, -190, + -190, -190, -190, -190, -61, 30, 34, -2, -189, -189, + -95, -99, -77, -42, -43, -43, -42, -43, 42, 42, + 42, 47, 42, 47, 42, -50, -125, -190, -56, 50, + 127, 51, -189, -127, -57, 12, -41, -57, -101, -102, + 238, 235, 241, 57, 59, 55, -168, 82, 54, 57, + 28, -160, -160, -161, 57, -161, 28, -144, 29, 68, + -150, 213, 60, -147, -147, -148, 30, -148, -148, -148, + -156, 59, -156, 60, 60, 52, -119, -131, -130, -183, + 131, 137, 138, 133, 57, 124, 28, 130, 132, 151, + 129, -183, -114, -115, 126, 22, 124, 28, 151, -182, + 53, 157, 157, 126, -131, -107, 59, -39, 39, 112, + -53, -40, 11, 99, -120, -37, -35, 73, -63, -63, + -190, -38, -135, 108, 184, 145, 182, 178, 198, 189, + 211, 180, 212, -132, -135, -63, -63, -63, -63, -120, + -63, -63, -63, -63, 259, -84, 81, -39, 79, -94, + 52, -95, -72, -74, -73, -189, -2, -90, -119, -93, + -119, -57, 55, 82, -46, -45, 52, 53, -47, 52, + -45, 42, 42, 124, 124, 124, -93, -84, -39, -57, + 235, 239, 240, -167, -168, -171, -170, -119, -174, -161, + -161, 54, -146, 52, 59, 60, 61, 68, 242, 67, + 56, -148, -148, 57, 108, 56, 55, 56, 55, 56, + 55, -53, -130, -130, -53, -130, -119, -180, 262, -181, + 57, -119, -119, -53, -110, -57, -41, -190, -63, -190, + -143, -143, -143, -152, -143, 172, -143, 172, -190, -190, + -190, 55, 19, -190, 55, 19, -190, 55, 19, -190, + 55, 19, -189, -34, 257, -39, 27, -94, 55, -190, + -190, -190, 55, 112, -190, 55, -84, -99, -39, -39, + 54, -39, -189, -189, -189, -190, -88, 56, 55, -143, + -91, -119, -154, 209, 9, 54, -147, 59, -147, 60, + 60, -131, 26, -179, -178, -120, 54, -82, 13, -147, + 57, -63, -63, -63, -63, -63, -63, -63, -63, -63, + -190, 59, 28, -74, 34, -2, -189, -119, -119, -119, + -88, -91, -91, -91, -91, -128, -173, -172, 53, 134, + 66, -170, 56, 55, -155, 130, 28, 129, 242, 56, + -148, -148, 56, 56, -189, 55, 82, -91, -83, 14, + 16, -190, -190, -190, -190, -190, -190, -190, -190, -33, + 92, 262, 9, -72, -2, 112, 56, -190, -190, -190, + -56, -172, 57, -162, 82, 59, 140, -119, -145, 66, + 28, 28, 54, -175, -176, 151, -178, -168, 56, -39, + -71, -190, 260, 49, 263, -95, -190, -119, 60, -53, + 59, 56, -190, 55, -119, -182, 39, 261, 264, 54, + -176, 34, -180, 39, -91, 153, 262, 56, 154, 263, + -185, -186, 52, -189, 264, -186, 52, 10, 9, -63, + 150, -184, 141, 136, 139, 30, -184, -190, -190, 135, + 29, 68, } var yyDef = [...]int{ @@ -2419,10 +2424,10 @@ var yyDef = [...]int{ 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 556, 0, 317, 317, 317, 317, 317, 317, 0, 627, 610, 0, 0, 0, 0, -2, 304, 305, - 0, 307, 308, 849, 849, 849, 849, 849, 0, 0, - 849, 0, 35, 36, 847, 1, 3, 564, 0, 0, + 0, 307, 308, 848, 848, 848, 848, 848, 0, 0, + 848, 0, 35, 36, 846, 1, 3, 564, 0, 0, 321, 324, 319, 0, 610, 610, 0, 0, 62, 63, - 0, 0, 0, 833, 0, 608, 608, 608, 628, 629, + 0, 0, 0, 832, 0, 608, 608, 608, 628, 629, 632, 633, 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, @@ -2433,131 +2438,131 @@ var yyDef = [...]int{ 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, 834, 835, 836, 837, 838, 839, 840, 841, - 842, 843, 844, 845, 846, 0, 0, 0, 611, 0, - 606, 0, 606, 606, 606, 0, 255, 389, 636, 637, - 833, 0, 0, 0, 850, 0, 850, 267, 850, 850, - 270, 850, 0, 850, 0, 277, 279, 280, 281, 282, - 0, 286, 850, 301, 302, 291, 303, 306, 309, 310, - 311, 312, 313, 849, 849, 316, 29, 568, 0, 0, - 556, 31, 0, 317, 322, 323, 327, 325, 326, 318, - 0, 335, 339, 0, 397, 0, 402, 404, -2, -2, - 0, 439, 440, 441, 442, 443, 0, 0, 0, 0, - 0, 0, 0, 0, 467, 468, 469, 470, 541, 542, - 543, 544, 545, 546, 547, 548, 406, 407, 538, 588, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 529, - 0, 503, 503, 503, 503, 503, 503, 503, 503, 0, - 0, 0, 0, 0, 0, 0, 0, 43, 47, 0, - 824, 592, -2, -2, 0, 0, 634, 635, -2, 742, - -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, 0, 0, 81, 0, 79, 0, - 850, 0, 0, 0, 0, 0, 0, 850, 0, 0, - 0, 0, 246, 0, 0, 0, 0, 0, 0, 0, - 254, 0, 256, 850, 850, 259, 851, 852, 850, 850, - 850, 850, 850, 850, 266, 268, 269, 271, 850, 850, - 273, 0, 294, 292, 293, 288, 289, 0, 283, 284, - 287, 314, 315, 30, 848, 24, 0, 0, 565, 0, - 557, 558, 561, 564, 29, 324, 0, 329, 328, 320, - 0, 336, 0, 0, 0, 340, 0, 342, 343, 0, - 400, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 424, 425, 426, 427, 428, 429, 430, 403, 0, 417, - 0, 0, 0, 459, 460, 461, 462, 463, 464, 465, - 0, 331, 29, 0, 437, 0, 0, 0, 0, 0, - 0, 0, 0, 327, 0, 530, 0, 495, 0, 496, - 497, 498, 499, 500, 501, 502, 0, 331, 0, 0, - 45, 0, 388, 0, 346, 348, 349, 350, -2, 0, - 372, -2, 0, 0, 0, 41, 42, 0, 48, 824, - 50, 51, 0, 0, 0, 164, 601, 602, 603, 599, - 208, 0, 0, 145, 141, 87, 88, 89, 134, 91, - 134, 134, 134, 134, 161, 161, 161, 161, 117, 118, - 119, 120, 121, 0, 0, 104, 134, 134, 134, 108, - 124, 125, 126, 127, 128, 129, 130, 131, 92, 93, - 94, 95, 96, 97, 98, 136, 136, 136, 138, 138, - 630, 65, 0, 850, 0, 850, 77, 0, 222, 0, - 0, 0, 0, 0, 0, 0, 249, 607, 0, 850, - 252, 253, 390, 638, 639, 257, 258, 260, 261, 262, - 263, 264, 265, 272, 276, 0, 297, 0, 0, 278, - 0, 569, 0, 0, 0, 0, 0, 560, 562, 563, - 568, 32, 327, 0, 549, 0, 0, 0, 330, 27, - 398, 399, 401, 418, 0, 420, 422, 341, 337, 0, - 539, -2, 408, 409, 433, 434, 435, 0, 0, 0, - 0, 431, 413, 0, 444, 445, 446, 447, 448, 449, - 450, 451, 452, 453, 454, 455, 458, 514, 515, 0, - 456, 457, 466, 0, 0, 332, 333, 436, 0, 587, - 29, 0, 0, 0, 0, 0, 0, 538, 0, 0, - 0, 0, 0, 536, 533, 0, 0, 504, 0, 0, - 0, 0, 0, 0, 387, 0, 0, 0, 0, 0, - 0, 377, 0, 0, 380, 0, 0, 0, 0, 371, - 0, 0, 391, 793, 373, 0, 375, 376, 395, 0, - 395, 44, 593, 49, 0, 0, 54, 55, 594, 595, - 596, 597, 0, 78, 209, 211, 214, 215, 216, 82, - 83, 84, 0, 0, 196, 0, 0, 190, 190, 0, - 188, 189, 80, 148, 146, 0, 143, 142, 90, 0, - 161, 161, 111, 112, 164, 0, 164, 164, 164, 0, - 0, 105, 106, 107, 99, 0, 100, 101, 102, 0, - 103, 0, 0, 850, 67, 609, 68, 849, 0, 0, - 622, 223, 612, 613, 614, 615, 616, 617, 618, 619, - 620, 621, 0, 69, 225, 227, 226, 0, 0, 0, - 247, 850, 251, 294, 275, 0, 0, 295, 296, 285, - 0, 566, 567, 0, 559, 25, 0, 604, 605, 550, - 551, 344, 419, 421, 423, 0, 331, 410, 431, 414, - 0, 411, 0, 0, 405, 471, 0, 0, 438, -2, - 474, 475, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 556, 0, 534, 0, 0, - 494, 505, 506, 507, 508, 581, 0, 0, -2, 0, - 0, 395, 589, 0, 347, 366, 368, 0, 363, 378, - 379, 381, 0, 383, 0, 385, 386, 351, 353, 354, - 0, 0, 0, 0, 374, 556, 0, 395, 40, 52, - 53, 0, 0, 59, 165, 166, 0, 212, 0, 0, - 0, 183, 190, 190, 186, 191, 187, 0, 156, 0, - 147, 86, 144, 0, 164, 164, 113, 0, 114, 115, - 116, 0, 132, 0, 0, 0, 0, 631, 66, 217, - 849, 230, 231, 232, 233, 234, 235, 236, 237, 238, - 239, 240, 849, 0, 849, 623, 624, 625, 626, 0, - 72, 0, 0, 0, 0, 250, 297, 298, 299, 570, - 0, 26, 395, 0, 338, 540, 0, 412, 0, 432, - 415, 472, 334, 0, 134, 134, 519, 134, 138, 522, - 134, 524, 134, 527, 0, 0, 0, 0, 0, 0, - 539, 0, 0, 0, 0, 0, 531, 493, 537, 0, - 33, 0, 581, 571, 583, 585, 0, 29, 0, 577, - 0, 358, 556, 0, 0, 360, 367, 0, 0, 361, - 0, 362, 382, 384, 0, 0, 0, 0, 564, 396, - 39, 56, 57, 58, 210, 213, 0, 192, 134, 195, - 184, 185, 0, 159, 0, 149, 150, 151, 152, 153, - 155, 135, 109, 110, 162, 163, 161, 0, 161, 0, - 139, 0, 850, 218, 219, 220, 221, 0, 224, 0, - 70, 71, 0, 229, 248, 274, 552, 345, 473, 416, - 476, 516, 161, 520, 521, 523, 525, 526, 528, 478, - 477, 479, 0, 0, 485, 0, 0, 482, 0, 0, - 488, 0, 0, 0, 0, 0, 535, 0, 34, 0, - 586, -2, 0, 0, 0, 46, 0, 564, 590, 591, - 364, 0, 369, 0, 0, 0, 372, 38, 175, 0, - 194, 0, 356, 167, 160, 0, 0, 164, 133, 164, - 0, 0, 64, 0, 73, 74, 0, 0, 554, 0, - 517, 518, 0, 0, 0, 0, 0, 0, 0, 0, - 509, 492, 532, 0, 584, 0, -2, 0, 579, 578, - 359, 37, 0, 0, 0, 0, 391, 174, 176, 0, - 181, 0, 193, 0, 0, 172, 0, 169, 171, 157, - 154, 122, 123, 137, 140, 0, 0, 0, 0, 28, - 0, 0, 480, 481, 486, 487, 483, 484, 489, 490, - 0, 0, 0, 0, 574, 29, 0, 365, 392, 393, - 394, 355, 177, 178, 0, 182, 180, 0, 357, 85, - 0, 168, 170, 0, 0, 242, 0, 75, 76, 69, - 555, 553, 491, 0, 0, 0, 582, -2, 580, 179, - 0, 173, 158, 241, 0, 0, 72, 510, 0, 513, - 0, 243, 0, 228, 511, 0, 0, 0, 197, 0, - 0, 198, 199, 0, 0, 512, 200, 0, 0, 0, - 0, 0, 201, 203, 204, 0, 0, 202, 244, 245, - 205, 206, 207, + 831, 833, 834, 835, 836, 837, 838, 839, 840, 841, + 842, 843, 844, 845, 0, 0, 0, 611, 0, 606, + 0, 606, 606, 606, 0, 255, 389, 636, 637, 832, + 0, 0, 0, 849, 0, 849, 267, 849, 849, 270, + 849, 0, 849, 0, 277, 279, 280, 281, 282, 0, + 286, 849, 301, 302, 291, 303, 306, 309, 310, 311, + 312, 313, 848, 848, 316, 29, 568, 0, 0, 556, + 31, 0, 317, 322, 323, 327, 325, 326, 318, 0, + 335, 339, 0, 397, 0, 402, 404, -2, -2, 0, + 439, 440, 441, 442, 443, 0, 0, 0, 0, 0, + 0, 0, 0, 467, 468, 469, 470, 541, 542, 543, + 544, 545, 546, 547, 548, 406, 407, 538, 588, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 529, 0, + 503, 503, 503, 503, 503, 503, 503, 503, 0, 0, + 0, 0, 0, 0, 0, 0, 43, 47, 0, 823, + 592, -2, -2, 0, 0, 634, 635, -2, 742, -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, 0, 0, 81, 0, 79, 0, 849, + 0, 0, 0, 0, 0, 0, 849, 0, 0, 0, + 0, 246, 0, 0, 0, 0, 0, 0, 0, 254, + 0, 256, 849, 849, 259, 850, 851, 849, 849, 849, + 849, 849, 849, 266, 268, 269, 271, 849, 849, 273, + 0, 294, 292, 293, 288, 289, 0, 283, 284, 287, + 314, 315, 30, 847, 24, 0, 0, 565, 0, 557, + 558, 561, 564, 29, 324, 0, 329, 328, 320, 0, + 336, 0, 0, 0, 340, 0, 342, 343, 0, 400, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 424, + 425, 426, 427, 428, 429, 430, 403, 0, 417, 0, + 0, 0, 459, 460, 461, 462, 463, 464, 465, 0, + 331, 29, 0, 437, 0, 0, 0, 0, 0, 0, + 0, 0, 327, 0, 530, 0, 495, 0, 496, 497, + 498, 499, 500, 501, 502, 0, 331, 0, 0, 45, + 0, 388, 0, 346, 348, 349, 350, -2, 0, 372, + -2, 0, 0, 0, 41, 42, 0, 48, 823, 50, + 51, 0, 0, 0, 164, 601, 602, 603, 599, 208, + 0, 0, 145, 141, 87, 88, 89, 134, 91, 134, + 134, 134, 134, 161, 161, 161, 161, 117, 118, 119, + 120, 121, 0, 0, 104, 134, 134, 134, 108, 124, + 125, 126, 127, 128, 129, 130, 131, 92, 93, 94, + 95, 96, 97, 98, 136, 136, 136, 138, 138, 630, + 65, 0, 849, 0, 849, 77, 0, 222, 0, 0, + 0, 0, 0, 0, 0, 249, 607, 0, 849, 252, + 253, 390, 638, 639, 257, 258, 260, 261, 262, 263, + 264, 265, 272, 276, 0, 297, 0, 0, 278, 0, + 569, 0, 0, 0, 0, 0, 560, 562, 563, 568, + 32, 327, 0, 549, 0, 0, 0, 330, 27, 398, + 399, 401, 418, 0, 420, 422, 341, 337, 0, 539, + -2, 408, 409, 433, 434, 435, 0, 0, 0, 0, + 431, 413, 0, 444, 445, 446, 447, 448, 449, 450, + 451, 452, 453, 454, 455, 458, 514, 515, 0, 456, + 457, 466, 0, 0, 332, 333, 436, 0, 587, 29, + 0, 0, 0, 0, 0, 0, 538, 0, 0, 0, + 0, 0, 536, 533, 0, 0, 504, 0, 0, 0, + 0, 0, 0, 387, 0, 0, 0, 0, 0, 0, + 377, 0, 0, 380, 0, 0, 0, 0, 371, 0, + 0, 391, 792, 373, 0, 375, 376, 395, 0, 395, + 44, 593, 49, 0, 0, 54, 55, 594, 595, 596, + 597, 0, 78, 209, 211, 214, 215, 216, 82, 83, + 84, 0, 0, 196, 0, 0, 190, 190, 0, 188, + 189, 80, 148, 146, 0, 143, 142, 90, 0, 161, + 161, 111, 112, 164, 0, 164, 164, 164, 0, 0, + 105, 106, 107, 99, 0, 100, 101, 102, 0, 103, + 0, 0, 849, 67, 609, 68, 848, 0, 0, 622, + 223, 612, 613, 614, 615, 616, 617, 618, 619, 620, + 621, 0, 69, 225, 227, 226, 0, 0, 0, 247, + 849, 251, 294, 275, 0, 0, 295, 296, 285, 0, + 566, 567, 0, 559, 25, 0, 604, 605, 550, 551, + 344, 419, 421, 423, 0, 331, 410, 431, 414, 0, + 411, 0, 0, 405, 471, 0, 0, 438, -2, 474, + 475, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 556, 0, 534, 0, 0, 494, + 505, 506, 507, 508, 581, 0, 0, -2, 0, 0, + 395, 589, 0, 347, 366, 368, 0, 363, 378, 379, + 381, 0, 383, 0, 385, 386, 351, 353, 354, 0, + 0, 0, 0, 374, 556, 0, 395, 40, 52, 53, + 0, 0, 59, 165, 166, 0, 212, 0, 0, 0, + 183, 190, 190, 186, 191, 187, 0, 156, 0, 147, + 86, 144, 0, 164, 164, 113, 0, 114, 115, 116, + 0, 132, 0, 0, 0, 0, 631, 66, 217, 848, + 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, + 240, 848, 0, 848, 623, 624, 625, 626, 0, 72, + 0, 0, 0, 0, 250, 297, 298, 299, 570, 0, + 26, 395, 0, 338, 540, 0, 412, 0, 432, 415, + 472, 334, 0, 134, 134, 519, 134, 138, 522, 134, + 524, 134, 527, 0, 0, 0, 0, 0, 0, 539, + 0, 0, 0, 0, 0, 531, 493, 537, 0, 33, + 0, 581, 571, 583, 585, 0, 29, 0, 577, 0, + 358, 556, 0, 0, 360, 367, 0, 0, 361, 0, + 362, 382, 384, 0, 0, 0, 0, 564, 396, 39, + 56, 57, 58, 210, 213, 0, 192, 134, 195, 184, + 185, 0, 159, 0, 149, 150, 151, 152, 153, 155, + 135, 109, 110, 162, 163, 161, 0, 161, 0, 139, + 0, 849, 218, 219, 220, 221, 0, 224, 0, 70, + 71, 0, 229, 248, 274, 552, 345, 473, 416, 476, + 516, 161, 520, 521, 523, 525, 526, 528, 478, 477, + 479, 0, 0, 485, 0, 0, 482, 0, 0, 488, + 0, 0, 0, 0, 0, 535, 0, 34, 0, 586, + -2, 0, 0, 0, 46, 0, 564, 590, 591, 364, + 0, 369, 0, 0, 0, 372, 38, 175, 0, 194, + 0, 356, 167, 160, 0, 0, 164, 133, 164, 0, + 0, 64, 0, 73, 74, 0, 0, 554, 0, 517, + 518, 0, 0, 0, 0, 0, 0, 0, 0, 509, + 492, 532, 0, 584, 0, -2, 0, 579, 578, 359, + 37, 0, 0, 0, 0, 391, 174, 176, 0, 181, + 0, 193, 0, 0, 172, 0, 169, 171, 157, 154, + 122, 123, 137, 140, 0, 0, 0, 0, 28, 0, + 0, 480, 481, 486, 487, 483, 484, 489, 490, 0, + 0, 0, 0, 574, 29, 0, 365, 392, 393, 394, + 355, 177, 178, 0, 182, 180, 0, 357, 85, 0, + 168, 170, 0, 0, 242, 0, 75, 76, 69, 555, + 553, 491, 0, 0, 0, 582, -2, 580, 179, 0, + 173, 158, 241, 0, 0, 72, 510, 0, 513, 0, + 243, 0, 228, 511, 0, 0, 0, 197, 0, 0, + 198, 199, 0, 0, 512, 200, 0, 0, 0, 0, + 0, 201, 203, 204, 0, 0, 202, 244, 245, 205, + 206, 207, } var yyTok1 = [...]int{ @@ -6623,42 +6628,42 @@ yydefault: { yyVAL.tableIdent = NewTableIdent(string(yyDollar[1].bytes)) } - case 847: + case 846: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3380 +//line sql.y:3379 { if incNesting(yylex) { yylex.Error("max nesting level reached") return 1 } } - case 848: + case 847: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3389 +//line sql.y:3388 { decNesting(yylex) } - case 849: + case 848: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:3394 +//line sql.y:3393 { skipToEnd(yylex) } - case 850: + case 849: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:3399 +//line sql.y:3398 { skipToEnd(yylex) } - case 851: + case 850: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3403 +//line sql.y:3402 { skipToEnd(yylex) } - case 852: + case 851: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3407 +//line sql.y:3406 { skipToEnd(yylex) } diff --git a/go/vt/sqlparser/sql.y b/go/vt/sqlparser/sql.y index c534e84617e..07dc55ca4c7 100644 --- a/go/vt/sqlparser/sql.y +++ b/go/vt/sqlparser/sql.y @@ -3276,7 +3276,6 @@ non_reserved_keyword: | COMMENT_KEYWORD | COMMIT | COMMITTED -| DESC | DATE | DATETIME | DECIMAL From a9cf065995cf264a24223c4ad8443d6df78abc3e Mon Sep 17 00:00:00 2001 From: Dan Kozlowski Date: Tue, 15 Jan 2019 14:27:39 -0800 Subject: [PATCH 056/115] Adding in SQL commands to prepare an instance to join an existing shard Signed-off-by: Dan Kozlowski --- config/init_db.sql | 2 ++ 1 file changed, 2 insertions(+) diff --git a/config/init_db.sql b/config/init_db.sql index 4a278549dd6..6bf2ac52023 100644 --- a/config/init_db.sql +++ b/config/init_db.sql @@ -84,3 +84,5 @@ GRANT SELECT FLUSH PRIVILEGES; +RESET SLAVE ALL; +RESET MASTER; From 7c36faa8854b59d6fe20c73f670e6fa8e1bc7835 Mon Sep 17 00:00:00 2001 From: Rafael Chacon Date: Tue, 15 Jan 2019 09:57:12 -0800 Subject: [PATCH 057/115] Adds a test to check regressions in parser Signed-off-by: Rafael Chacon --- tools/check_make_parser.sh | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/tools/check_make_parser.sh b/tools/check_make_parser.sh index 577b881dce6..139e18199a8 100755 --- a/tools/check_make_parser.sh +++ b/tools/check_make_parser.sh @@ -16,7 +16,15 @@ if ! cd go/vt/sqlparser/ ; then fi mv $CUR $TMP -goyacc -o $CUR sql.y +output=`goyacc -o $CUR sql.y` + +if [ -n "$output" ]; then + echo "Expected empty output from goyacc, got:" + echo $output + mv $TMP $CUR + exit 1 +fi + gofmt -w $CUR if ! diff -q $CUR $TMP > /dev/null ; then From ac24f9108173aaee8ea21545b1147d343164e08c Mon Sep 17 00:00:00 2001 From: Sugu Sougoumarane Date: Sat, 5 Jan 2019 19:48:14 -0800 Subject: [PATCH 058/115] vreplication: playerPlan initial cut Signed-off-by: Sugu Sougoumarane --- .../{planbuilder.go => controller_plan.go} | 24 +- ...uilder_test.go => controller_plan_test.go} | 16 +- .../tabletmanager/vreplication/engine.go | 2 +- .../tabletmanager/vreplication/player_plan.go | 213 ++++++++++++++++++ .../tabletserver/vstreamer/planbuilder.go | 10 +- 5 files changed, 239 insertions(+), 26 deletions(-) rename go/vt/vttablet/tabletmanager/vreplication/{planbuilder.go => controller_plan.go} (88%) rename go/vt/vttablet/tabletmanager/vreplication/{planbuilder_test.go => controller_plan_test.go} (96%) create mode 100644 go/vt/vttablet/tabletmanager/vreplication/player_plan.go diff --git a/go/vt/vttablet/tabletmanager/vreplication/planbuilder.go b/go/vt/vttablet/tabletmanager/vreplication/controller_plan.go similarity index 88% rename from go/vt/vttablet/tabletmanager/vreplication/planbuilder.go rename to go/vt/vttablet/tabletmanager/vreplication/controller_plan.go index 22713df9478..1a964e7b02a 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/planbuilder.go +++ b/go/vt/vttablet/tabletmanager/vreplication/controller_plan.go @@ -23,8 +23,8 @@ import ( "vitess.io/vitess/go/vt/sqlparser" ) -// plan is the plan for vreplication control statements. -type plan struct { +// controllerPlan is the plan for vreplication control statements. +type controllerPlan struct { opcode int query string id int @@ -37,8 +37,8 @@ const ( selectQuery ) -// getPlan parses the input query and returns an appropriate plan. -func getPlan(query string) (*plan, error) { +// buildControllerPlan parses the input query and returns an appropriate plan. +func buildControllerPlan(query string) (*controllerPlan, error) { stmt, err := sqlparser.Parse(query) if err != nil { return nil, err @@ -57,7 +57,7 @@ func getPlan(query string) (*plan, error) { } } -func buildInsertPlan(ins *sqlparser.Insert) (*plan, error) { +func buildInsertPlan(ins *sqlparser.Insert) (*controllerPlan, error) { if ins.Action != sqlparser.InsertStr { return nil, fmt.Errorf("unsupported construct: %v", sqlparser.String(ins)) } @@ -99,13 +99,13 @@ func buildInsertPlan(ins *sqlparser.Insert) (*plan, error) { return nil, fmt.Errorf("id should not have a value: %v", sqlparser.String(ins)) } } - return &plan{ + return &controllerPlan{ opcode: insertQuery, query: sqlparser.String(ins), }, nil } -func buildUpdatePlan(upd *sqlparser.Update) (*plan, error) { +func buildUpdatePlan(upd *sqlparser.Update) (*controllerPlan, error) { if sqlparser.String(upd.TableExprs) != "_vt.vreplication" { return nil, fmt.Errorf("invalid table name: %v", sqlparser.String(upd.TableExprs)) } @@ -123,14 +123,14 @@ func buildUpdatePlan(upd *sqlparser.Update) (*plan, error) { return nil, err } - return &plan{ + return &controllerPlan{ opcode: updateQuery, query: sqlparser.String(upd), id: id, }, nil } -func buildDeletePlan(del *sqlparser.Delete) (*plan, error) { +func buildDeletePlan(del *sqlparser.Delete) (*controllerPlan, error) { if del.Targets != nil { return nil, fmt.Errorf("unsupported construct: %v", sqlparser.String(del)) } @@ -149,18 +149,18 @@ func buildDeletePlan(del *sqlparser.Delete) (*plan, error) { return nil, err } - return &plan{ + return &controllerPlan{ opcode: deleteQuery, query: sqlparser.String(del), id: id, }, nil } -func buildSelectPlan(sel *sqlparser.Select) (*plan, error) { +func buildSelectPlan(sel *sqlparser.Select) (*controllerPlan, error) { if sqlparser.String(sel.From) != "_vt.vreplication" { return nil, fmt.Errorf("invalid table name: %v", sqlparser.String(sel.From)) } - return &plan{ + return &controllerPlan{ opcode: selectQuery, query: sqlparser.String(sel), }, nil diff --git a/go/vt/vttablet/tabletmanager/vreplication/planbuilder_test.go b/go/vt/vttablet/tabletmanager/vreplication/controller_plan_test.go similarity index 96% rename from go/vt/vttablet/tabletmanager/vreplication/planbuilder_test.go rename to go/vt/vttablet/tabletmanager/vreplication/controller_plan_test.go index af89c949c65..6d9a7c54caf 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/planbuilder_test.go +++ b/go/vt/vttablet/tabletmanager/vreplication/controller_plan_test.go @@ -24,24 +24,24 @@ import ( func TestPlanBuilder(t *testing.T) { tcases := []struct { in string - plan *plan + plan *controllerPlan err string }{{ // Insert in: "insert into _vt.vreplication values(null)", - plan: &plan{ + plan: &controllerPlan{ opcode: insertQuery, query: "insert into _vt.vreplication values (null)", }, }, { in: "insert into _vt.vreplication(id) values(null)", - plan: &plan{ + plan: &controllerPlan{ opcode: insertQuery, query: "insert into _vt.vreplication(id) values (null)", }, }, { in: "insert into _vt.vreplication(workflow, id) values('', null)", - plan: &plan{ + plan: &controllerPlan{ opcode: insertQuery, query: "insert into _vt.vreplication(workflow, id) values ('', null)", }, @@ -79,7 +79,7 @@ func TestPlanBuilder(t *testing.T) { // Update }, { in: "update _vt.vreplication set state='Running' where id = 1", - plan: &plan{ + plan: &controllerPlan{ opcode: updateQuery, query: "update _vt.vreplication set state = 'Running' where id = 1", id: 1, @@ -115,7 +115,7 @@ func TestPlanBuilder(t *testing.T) { // Delete }, { in: "delete from _vt.vreplication where id = 1", - plan: &plan{ + plan: &controllerPlan{ opcode: deleteQuery, query: "delete from _vt.vreplication where id = 1", id: 1, @@ -154,7 +154,7 @@ func TestPlanBuilder(t *testing.T) { // Select }, { in: "select * from _vt.vreplication where id = 1", - plan: &plan{ + plan: &controllerPlan{ opcode: selectQuery, query: "select * from _vt.vreplication where id = 1", }, @@ -171,7 +171,7 @@ func TestPlanBuilder(t *testing.T) { err: "unsupported construct: set a = 1", }} for _, tcase := range tcases { - pl, err := getPlan(tcase.in) + pl, err := buildControllerPlan(tcase.in) if err != nil { if err.Error() != tcase.err { t.Errorf("getPlan(%v) error:\n%v, want\n%v", tcase.in, err, tcase.err) diff --git a/go/vt/vttablet/tabletmanager/vreplication/engine.go b/go/vt/vttablet/tabletmanager/vreplication/engine.go index c499225cf4c..f214876de88 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/engine.go +++ b/go/vt/vttablet/tabletmanager/vreplication/engine.go @@ -200,7 +200,7 @@ func (vre *Engine) Exec(query string) (*sqltypes.Result, error) { } defer vre.updateStats() - plan, err := getPlan(query) + plan, err := buildControllerPlan(query) if err != nil { return nil, err } diff --git a/go/vt/vttablet/tabletmanager/vreplication/player_plan.go b/go/vt/vttablet/tabletmanager/vreplication/player_plan.go new file mode 100644 index 00000000000..f08c59f7e8e --- /dev/null +++ b/go/vt/vttablet/tabletmanager/vreplication/player_plan.go @@ -0,0 +1,213 @@ +/* +Copyright 2019 The Vitess Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package vreplication + +import ( + "fmt" + "strings" + + "vitess.io/vitess/go/vt/sqlparser" + + binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" +) + +type playerPlan struct { + vstreamFilter *binlogdatapb.Filter + tablePlans map[string]*tablePlan +} + +type tablePlan struct { + colExprs []*colExpr + onInsert insertType + updateCols []int +} + +func (tp *tablePlan) findCol(name sqlparser.ColIdent) *colExpr { + for _, cExpr := range tp.colExprs { + if cExpr.colname.Equal(name) { + return cExpr + } + } + return nil +} + +type colExpr struct { + colname sqlparser.ColIdent + colnum int + op operation +} + +type operation int + +const ( + opNone = operation(iota) + opCount + opSum + opExclude +) + +type insertType int + +const ( + insertNormal = insertType(iota) + insertOndup + insertIgnore +) + +func buildPlayerPlan(filter *binlogdatapb.Filter) (*playerPlan, error) { + plan := &playerPlan{ + vstreamFilter: &binlogdatapb.Filter{ + Rules: make([]*binlogdatapb.Rule, len(filter.Rules)), + }, + tablePlans: make(map[string]*tablePlan), + } + for i, rule := range filter.Rules { + if strings.HasPrefix(rule.Match, "/") { + plan.vstreamFilter.Rules[i] = rule + continue + } + sendRule, tplan, err := buildTablePlan(rule) + if err != nil { + return nil, err + } + if tplan == nil { + continue + } + plan.vstreamFilter.Rules[i] = sendRule + plan.tablePlans[rule.Match] = tplan + } + return plan, nil +} + +func buildTablePlan(rule *binlogdatapb.Rule) (*binlogdatapb.Rule, *tablePlan, error) { + statement, err := sqlparser.Parse(rule.Filter) + if err != nil { + return nil, nil, err + } + sel, ok := statement.(*sqlparser.Select) + if !ok { + return nil, nil, fmt.Errorf("unexpected: %v", sqlparser.String(statement)) + } + if len(sel.From) > 1 { + return nil, nil, fmt.Errorf("unexpected: %v", sqlparser.String(sel)) + } + node, ok := sel.From[0].(*sqlparser.AliasedTableExpr) + if !ok { + return nil, nil, fmt.Errorf("unexpected: %v", sqlparser.String(sel)) + } + fromTable := sqlparser.GetTableName(node.Expr) + if fromTable.IsEmpty() { + return nil, nil, fmt.Errorf("unexpected: %v", sqlparser.String(sel)) + } + if fromTable.String() != rule.Match { + return nil, nil, fmt.Errorf("unexpected: select expression table %v does not match the table entry name %s", sqlparser.String(fromTable), rule.Match) + } + + if _, ok := sel.SelectExprs[0].(*sqlparser.StarExpr); ok { + if len(sel.SelectExprs) != 1 { + return nil, nil, fmt.Errorf("unexpected: %v", sqlparser.String(sel)) + } + return rule, nil, nil + } + + tplan := &tablePlan{} + sendSelect := &sqlparser.Select{ + From: sel.From, + Where: sel.Where, + } + for _, expr := range sel.SelectExprs { + selExpr, cExpr, err := analyzeExpr(expr) + if err != nil { + return nil, nil, err + } + if selExpr != nil { + sendSelect.SelectExprs = append(sendSelect.SelectExprs, selExpr) + cExpr.colnum = len(sendSelect.SelectExprs) - 1 + } + tplan.colExprs = append(tplan.colExprs, cExpr) + } + + if sel.GroupBy != nil { + if err := analyzeGroupBy(sel.GroupBy, tplan); err != nil { + return nil, nil, err + } + } + sendRule := &binlogdatapb.Rule{ + Match: rule.Match, + Filter: sqlparser.String(sendSelect), + } + return sendRule, tplan, nil +} + +func analyzeExpr(selExpr sqlparser.SelectExpr) (sqlparser.SelectExpr, *colExpr, error) { + aliased, ok := selExpr.(*sqlparser.AliasedExpr) + if !ok { + return nil, nil, fmt.Errorf("unexpected: %v", sqlparser.String(selExpr)) + } + switch expr := aliased.Expr.(type) { + case *sqlparser.ColName: + return selExpr, &colExpr{colname: expr.Name}, nil + case *sqlparser.FuncExpr: + if expr.Distinct || len(expr.Exprs) != 1 { + return nil, nil, fmt.Errorf("unsupported: %v", sqlparser.String(expr)) + } + if aliased.As.IsEmpty() { + return nil, nil, fmt.Errorf("expression needs an alias: %v", sqlparser.String(expr)) + } + switch fname := expr.Name.Lowered(); fname { + case "month", "day", "hour": + return selExpr, &colExpr{colname: aliased.As}, nil + case "count": + if _, ok := expr.Exprs[0].(*sqlparser.StarExpr); !ok { + return nil, nil, fmt.Errorf("only count(*) is supported: %v", sqlparser.String(expr)) + } + return nil, &colExpr{colname: aliased.As, op: opCount}, nil + case "sum": + aInner, ok := expr.Exprs[0].(*sqlparser.AliasedExpr) + if !ok { + return nil, nil, fmt.Errorf("unsupported: %v", sqlparser.String(expr)) + } + innerCol, ok := aInner.Expr.(*sqlparser.ColName) + if !ok { + return nil, nil, fmt.Errorf("unsupported: %v", sqlparser.String(expr)) + } + return &sqlparser.AliasedExpr{Expr: innerCol}, &colExpr{colname: aliased.As, op: opSum}, nil + default: + return nil, nil, fmt.Errorf("unsupported: %v", sqlparser.String(expr)) + } + default: + return nil, nil, fmt.Errorf("unexpected: %v", sqlparser.String(expr)) + } +} + +func analyzeGroupBy(groupBy sqlparser.GroupBy, tplan *tablePlan) error { + for _, expr := range groupBy { + colname, ok := expr.(*sqlparser.ColName) + if !ok { + return fmt.Errorf("unsupported: %v", sqlparser.String(expr)) + } + cExpr := tplan.findCol(colname.Name) + if cExpr == nil { + return fmt.Errorf("group by expression does not reference an alias in the select list: %v", sqlparser.String(expr)) + } + if cExpr.op != opNone { + return fmt.Errorf("group by expression is not allowed to reference an aggregate expression: %v", sqlparser.String(expr)) + } + cExpr.op = opExclude + } + return nil +} diff --git a/go/vt/vttablet/tabletserver/vstreamer/planbuilder.go b/go/vt/vttablet/tabletserver/vstreamer/planbuilder.go index d3709ca7361..432251f8cba 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/planbuilder.go +++ b/go/vt/vttablet/tabletserver/vstreamer/planbuilder.go @@ -293,12 +293,12 @@ func buildTablePlan(ti *Table, kschema *vindexes.KeyspaceSchema, query string) ( return plan, nil } -func analyzeExpr(ti *Table, expr sqlparser.SelectExpr) (cExpr ColExpr, err error) { - aexpr, ok := expr.(*sqlparser.AliasedExpr) +func analyzeExpr(ti *Table, selExpr sqlparser.SelectExpr) (cExpr ColExpr, err error) { + aliased, ok := selExpr.(*sqlparser.AliasedExpr) if !ok { - return ColExpr{}, fmt.Errorf("unexpected: %v", sqlparser.String(expr)) + return ColExpr{}, fmt.Errorf("unexpected: %v", sqlparser.String(selExpr)) } - switch expr := aexpr.Expr.(type) { + switch expr := aliased.Expr.(type) { case *sqlparser.ColName: colnum, err := findColumn(ti, expr.Name) if err != nil { @@ -319,7 +319,7 @@ func analyzeExpr(ti *Table, expr sqlparser.SelectExpr) (cExpr ColExpr, err error if !ok { return ColExpr{}, fmt.Errorf("unsupported: %v", sqlparser.String(expr)) } - as := aexpr.As + as := aliased.As if as.IsEmpty() { as = sqlparser.NewColIdent(sqlparser.String(expr)) } From 1f0f55e783a21f3befd4459db91d3c337557481e Mon Sep 17 00:00:00 2001 From: Sugu Sougoumarane Date: Sun, 6 Jan 2019 19:53:04 -0800 Subject: [PATCH 059/115] vreplication: vplayer WIP Signed-off-by: Sugu Sougoumarane --- go/vt/binlog/binlogplayer/binlog_player.go | 26 +- .../binlog/binlogplayer/binlog_player_test.go | 4 +- go/vt/proto/binlogdata/binlogdata.pb.go | 236 ++++++++++-------- go/vt/proto/queryservice/queryservice.pb.go | 134 +++++++--- go/vt/vtcombo/tablet_map.go | 7 + go/vt/vttablet/grpcqueryservice/server.go | 18 ++ go/vt/vttablet/grpctabletconn/conn.go | 45 ++++ go/vt/vttablet/queryservice/queryservice.go | 4 + go/vt/vttablet/queryservice/wrapped.go | 8 + go/vt/vttablet/sandboxconn/sandboxconn.go | 7 +- .../tabletconntest/fakequeryservice.go | 6 + .../tabletmanager/vreplication/controller.go | 2 +- .../tabletmanager/vreplication/player_plan.go | 26 +- .../tabletmanager/vreplication/vplayer.go | 236 ++++++++++++++++++ go/vt/vttablet/tabletserver/tabletserver.go | 2 +- .../vttablet/tabletserver/vstreamer/engine.go | 2 +- .../tabletserver/vstreamer/planbuilder.go | 10 +- .../tabletserver/vstreamer/vstreamer.go | 14 +- .../tabletserver/vstreamer/vstreamer_test.go | 46 ++-- proto/binlogdata.proto | 20 +- proto/queryservice.proto | 4 + py/vtproto/binlogdata_pb2.py | 136 ++++++---- py/vtproto/queryservice_pb2.py | 67 ++--- py/vtproto/queryservice_pb2_grpc.py | 18 ++ 24 files changed, 798 insertions(+), 280 deletions(-) create mode 100644 go/vt/vttablet/tabletmanager/vreplication/vplayer.go diff --git a/go/vt/binlog/binlogplayer/binlog_player.go b/go/vt/binlog/binlogplayer/binlog_player.go index b76fa52f42c..da81c6f1053 100644 --- a/go/vt/binlog/binlogplayer/binlog_player.go +++ b/go/vt/binlog/binlogplayer/binlog_player.go @@ -170,7 +170,7 @@ func NewBinlogPlayerTables(dbClient DBClient, tablet *topodatapb.Tablet, tables // If an error is encountered, it updates the vreplication state to "Error". // If a stop position was specifed, and reached, the state is updated to "Stopped". func (blp *BinlogPlayer) ApplyBinlogEvents(ctx context.Context) error { - if err := setVReplicationState(blp.dbClient, blp.uid, BlpRunning, ""); err != nil { + if err := SetVReplicationState(blp.dbClient, blp.uid, BlpRunning, ""); err != nil { log.Errorf("Error writing Running state: %v", err) } @@ -180,7 +180,7 @@ func (blp *BinlogPlayer) ApplyBinlogEvents(ctx context.Context) error { Time: time.Now(), Message: msg, }) - if err := setVReplicationState(blp.dbClient, blp.uid, BlpError, msg); err != nil { + if err := SetVReplicationState(blp.dbClient, blp.uid, BlpError, msg); err != nil { log.Errorf("Error writing stop state: %v", err) } return err @@ -191,7 +191,7 @@ func (blp *BinlogPlayer) ApplyBinlogEvents(ctx context.Context) error { // applyEvents returns a recordable status message on termination or an error otherwise. func (blp *BinlogPlayer) applyEvents(ctx context.Context) error { // Read starting values for vreplication. - pos, stopPos, maxTPS, maxReplicationLag, err := readVRSettings(blp.dbClient, blp.uid) + pos, stopPos, maxTPS, maxReplicationLag, err := ReadVRSettings(blp.dbClient, blp.uid) if err != nil { log.Error(err) return err @@ -244,14 +244,14 @@ func (blp *BinlogPlayer) applyEvents(ctx context.Context) error { case blp.position.Equal(blp.stopPosition): msg := fmt.Sprintf("not starting BinlogPlayer, we're already at the desired position %v", blp.stopPosition) log.Info(msg) - if err := setVReplicationState(blp.dbClient, blp.uid, BlpStopped, msg); err != nil { + if err := SetVReplicationState(blp.dbClient, blp.uid, BlpStopped, msg); err != nil { log.Errorf("Error writing stop state: %v", err) } return nil case blp.position.AtLeast(blp.stopPosition): msg := fmt.Sprintf("starting point %v greater than stopping point %v", blp.position, blp.stopPosition) log.Error(msg) - if err := setVReplicationState(blp.dbClient, blp.uid, BlpStopped, msg); err != nil { + if err := SetVReplicationState(blp.dbClient, blp.uid, BlpStopped, msg); err != nil { log.Errorf("Error writing stop state: %v", err) } // Don't return an error. Otherwise, it will keep retrying. @@ -351,7 +351,7 @@ func (blp *BinlogPlayer) applyEvents(ctx context.Context) error { if blp.position.AtLeast(blp.stopPosition) { msg := "Reached stopping position, done playing logs" log.Info(msg) - if err := setVReplicationState(blp.dbClient, blp.uid, BlpStopped, msg); err != nil { + if err := SetVReplicationState(blp.dbClient, blp.uid, BlpStopped, msg); err != nil { log.Errorf("Error writing stop state: %v", err) } return nil @@ -447,7 +447,7 @@ func (blp *BinlogPlayer) writeRecoveryPosition(tx *binlogdatapb.BinlogTransactio } now := time.Now().Unix() - updateRecovery := updateVReplicationPos(blp.uid, position, now, tx.EventToken.Timestamp) + updateRecovery := GenerateUpdatePos(blp.uid, position, now, tx.EventToken.Timestamp) qr, err := blp.exec(updateRecovery) if err != nil { @@ -503,8 +503,8 @@ func CreateVReplicationTable() []string { ) ENGINE=InnoDB`} } -// setVReplicationState updates the state in the _vt.vreplication table. -func setVReplicationState(dbClient DBClient, uid uint32, state, message string) error { +// SetVReplicationState updates the state in the _vt.vreplication table. +func SetVReplicationState(dbClient DBClient, uid uint32, state, message string) error { query := fmt.Sprintf("update _vt.vreplication set state='%v', message=%v where id=%v", state, encodeString(message), uid) if _, err := dbClient.ExecuteFetch(query, 1); err != nil { return fmt.Errorf("could not set state: %v: %v", query, err) @@ -512,9 +512,9 @@ func setVReplicationState(dbClient DBClient, uid uint32, state, message string) return nil } -// readVRSettings retrieves the throttler settings for +// ReadVRSettings retrieves the throttler settings for // vreplication from the checkpoint table. -func readVRSettings(dbClient DBClient, uid uint32) (pos, stopPos string, maxTPS, maxReplicationLag int64, err error) { +func ReadVRSettings(dbClient DBClient, uid uint32) (pos, stopPos string, maxTPS, maxReplicationLag int64, err error) { query := fmt.Sprintf("select pos, stop_pos, max_tps, max_replication_lag from _vt.vreplication where id=%v", uid) qr, err := dbClient.ExecuteFetch(query, 1) if err != nil { @@ -554,9 +554,9 @@ func CreateVReplicationStopped(workflow string, source *binlogdatapb.BinlogSourc encodeString(workflow), encodeString(source.String()), encodeString(position), throttler.MaxRateModuleDisabled, throttler.ReplicationLagModuleDisabled, time.Now().Unix(), BlpStopped) } -// updateVReplicationPos returns a statement to update a value in the +// GenerateUpdatePos returns a statement to update a value in the // _vt.vreplication table. -func updateVReplicationPos(uid uint32, pos mysql.Position, timeUpdated int64, txTimestamp int64) string { +func GenerateUpdatePos(uid uint32, pos mysql.Position, timeUpdated int64, txTimestamp int64) string { if txTimestamp != 0 { return fmt.Sprintf( "update _vt.vreplication set pos=%v, time_updated=%v, transaction_timestamp=%v where id=%v", diff --git a/go/vt/binlog/binlogplayer/binlog_player_test.go b/go/vt/binlog/binlogplayer/binlog_player_test.go index 8f4376f8212..8db24607dab 100644 --- a/go/vt/binlog/binlogplayer/binlog_player_test.go +++ b/go/vt/binlog/binlogplayer/binlog_player_test.go @@ -355,7 +355,7 @@ func TestUpdateVReplicationPos(t *testing.T) { "set pos='MariaDB/0-1-8283', time_updated=88822 " + "where id=78522" - got := updateVReplicationPos(78522, mysql.Position{GTIDSet: gtid.GTIDSet()}, 88822, 0) + got := GenerateUpdatePos(78522, mysql.Position{GTIDSet: gtid.GTIDSet()}, 88822, 0) if got != want { t.Errorf("updateVReplicationPos() = %#v, want %#v", got, want) } @@ -367,7 +367,7 @@ func TestUpdateVReplicationTimestamp(t *testing.T) { "set pos='MariaDB/0-2-582', time_updated=88822, transaction_timestamp=481828 " + "where id=78522" - got := updateVReplicationPos(78522, mysql.Position{GTIDSet: gtid.GTIDSet()}, 88822, 481828) + got := GenerateUpdatePos(78522, mysql.Position{GTIDSet: gtid.GTIDSet()}, 88822, 481828) if got != want { t.Errorf("updateVReplicationPos() = %#v, want %#v", got, want) } diff --git a/go/vt/proto/binlogdata/binlogdata.pb.go b/go/vt/proto/binlogdata/binlogdata.pb.go index 1a3510d1bc5..0cddb2d2342 100644 --- a/go/vt/proto/binlogdata/binlogdata.pb.go +++ b/go/vt/proto/binlogdata/binlogdata.pb.go @@ -8,6 +8,7 @@ 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" // Reference imports to suppress errors if they are not otherwise used. var _ = proto.Marshal @@ -79,7 +80,7 @@ func (x VEventType) String() string { return proto.EnumName(VEventType_name, int32(x)) } func (VEventType) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_binlogdata_e1edbb575eea20d0, []int{0} + return fileDescriptor_binlogdata_602eda7964a9642b, []int{0} } type BinlogTransaction_Statement_Category int32 @@ -127,7 +128,7 @@ 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_e1edbb575eea20d0, []int{1, 0, 0} + return fileDescriptor_binlogdata_602eda7964a9642b, []int{1, 0, 0} } // Charset is the per-statement charset info from a QUERY_EVENT binlog entry. @@ -147,7 +148,7 @@ 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_e1edbb575eea20d0, []int{0} + return fileDescriptor_binlogdata_602eda7964a9642b, []int{0} } func (m *Charset) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Charset.Unmarshal(m, b) @@ -204,7 +205,7 @@ 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_e1edbb575eea20d0, []int{1} + return fileDescriptor_binlogdata_602eda7964a9642b, []int{1} } func (m *BinlogTransaction) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_BinlogTransaction.Unmarshal(m, b) @@ -254,7 +255,7 @@ 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_e1edbb575eea20d0, []int{1, 0} + return fileDescriptor_binlogdata_602eda7964a9642b, []int{1, 0} } func (m *BinlogTransaction_Statement) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_BinlogTransaction_Statement.Unmarshal(m, b) @@ -312,7 +313,7 @@ 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_e1edbb575eea20d0, []int{2} + return fileDescriptor_binlogdata_602eda7964a9642b, []int{2} } func (m *StreamKeyRangeRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_StreamKeyRangeRequest.Unmarshal(m, b) @@ -365,7 +366,7 @@ 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_e1edbb575eea20d0, []int{3} + return fileDescriptor_binlogdata_602eda7964a9642b, []int{3} } func (m *StreamKeyRangeResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_StreamKeyRangeResponse.Unmarshal(m, b) @@ -409,7 +410,7 @@ 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_e1edbb575eea20d0, []int{4} + return fileDescriptor_binlogdata_602eda7964a9642b, []int{4} } func (m *StreamTablesRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_StreamTablesRequest.Unmarshal(m, b) @@ -462,7 +463,7 @@ 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_e1edbb575eea20d0, []int{5} + return fileDescriptor_binlogdata_602eda7964a9642b, []int{5} } func (m *StreamTablesResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_StreamTablesResponse.Unmarshal(m, b) @@ -507,7 +508,7 @@ 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_e1edbb575eea20d0, []int{6} + return fileDescriptor_binlogdata_602eda7964a9642b, []int{6} } func (m *Rule) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Rule.Unmarshal(m, b) @@ -554,7 +555,7 @@ 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_e1edbb575eea20d0, []int{7} + return fileDescriptor_binlogdata_602eda7964a9642b, []int{7} } func (m *Filter) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Filter.Unmarshal(m, b) @@ -607,7 +608,7 @@ 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_e1edbb575eea20d0, []int{8} + return fileDescriptor_binlogdata_602eda7964a9642b, []int{8} } func (m *BinlogSource) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_BinlogSource.Unmarshal(m, b) @@ -682,7 +683,7 @@ 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_e1edbb575eea20d0, []int{9} + return fileDescriptor_binlogdata_602eda7964a9642b, []int{9} } func (m *RowChange) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_RowChange.Unmarshal(m, b) @@ -729,7 +730,7 @@ 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_e1edbb575eea20d0, []int{10} + return fileDescriptor_binlogdata_602eda7964a9642b, []int{10} } func (m *RowEvent) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_RowEvent.Unmarshal(m, b) @@ -775,7 +776,7 @@ 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_e1edbb575eea20d0, []int{11} + return fileDescriptor_binlogdata_602eda7964a9642b, []int{11} } func (m *FieldEvent) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_FieldEvent.Unmarshal(m, b) @@ -812,10 +813,11 @@ func (m *FieldEvent) GetFields() []*query.Field { // VEvent represents a vstream event type VEvent struct { Type VEventType `protobuf:"varint,1,opt,name=type,proto3,enum=binlogdata.VEventType" json:"type,omitempty"` - Gtid string `protobuf:"bytes,2,opt,name=gtid,proto3" json:"gtid,omitempty"` - Ddl string `protobuf:"bytes,3,opt,name=ddl,proto3" json:"ddl,omitempty"` - RowEvent *RowEvent `protobuf:"bytes,4,opt,name=row_event,json=rowEvent,proto3" json:"row_event,omitempty"` - FieldEvent *FieldEvent `protobuf:"bytes,5,opt,name=field_event,json=fieldEvent,proto3" json:"field_event,omitempty"` + Timestamp int64 `protobuf:"varint,2,opt,name=timestamp,proto3" json:"timestamp,omitempty"` + Gtid string `protobuf:"bytes,3,opt,name=gtid,proto3" json:"gtid,omitempty"` + Ddl string `protobuf:"bytes,4,opt,name=ddl,proto3" json:"ddl,omitempty"` + RowEvent *RowEvent `protobuf:"bytes,5,opt,name=row_event,json=rowEvent,proto3" json:"row_event,omitempty"` + FieldEvent *FieldEvent `protobuf:"bytes,6,opt,name=field_event,json=fieldEvent,proto3" json:"field_event,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -825,7 +827,7 @@ 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_e1edbb575eea20d0, []int{12} + return fileDescriptor_binlogdata_602eda7964a9642b, []int{12} } func (m *VEvent) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_VEvent.Unmarshal(m, b) @@ -852,6 +854,13 @@ func (m *VEvent) GetType() VEventType { return VEventType_UNKNOWN } +func (m *VEvent) GetTimestamp() int64 { + if m != nil { + return m.Timestamp + } + return 0 +} + func (m *VEvent) GetGtid() string { if m != nil { return m.Gtid @@ -882,18 +891,21 @@ func (m *VEvent) GetFieldEvent() *FieldEvent { // VStreamRequest is the payload for VStream type VStreamRequest struct { - Position string `protobuf:"bytes,1,opt,name=position,proto3" json:"position,omitempty"` - Filter *Filter `protobuf:"bytes,2,opt,name=filter,proto3" json:"filter,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + 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"` + Position string `protobuf:"bytes,4,opt,name=position,proto3" json:"position,omitempty"` + Filter *Filter `protobuf:"bytes,5,opt,name=filter,proto3" json:"filter,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } 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_e1edbb575eea20d0, []int{13} + return fileDescriptor_binlogdata_602eda7964a9642b, []int{13} } func (m *VStreamRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_VStreamRequest.Unmarshal(m, b) @@ -913,6 +925,27 @@ func (m *VStreamRequest) XXX_DiscardUnknown() { var xxx_messageInfo_VStreamRequest proto.InternalMessageInfo +func (m *VStreamRequest) GetEffectiveCallerId() *vtrpc.CallerID { + if m != nil { + return m.EffectiveCallerId + } + return nil +} + +func (m *VStreamRequest) GetImmediateCallerId() *query.VTGateCallerID { + if m != nil { + return m.ImmediateCallerId + } + return nil +} + +func (m *VStreamRequest) GetTarget() *query.Target { + if m != nil { + return m.Target + } + return nil +} + func (m *VStreamRequest) GetPosition() string { if m != nil { return m.Position @@ -929,7 +962,7 @@ func (m *VStreamRequest) GetFilter() *Filter { // VStreamResponse is the response from VStream type VStreamResponse struct { - Event []*VEvent `protobuf:"bytes,1,rep,name=event,proto3" json:"event,omitempty"` + Events []*VEvent `protobuf:"bytes,1,rep,name=events,proto3" json:"events,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -939,7 +972,7 @@ 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_e1edbb575eea20d0, []int{14} + return fileDescriptor_binlogdata_602eda7964a9642b, []int{14} } func (m *VStreamResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_VStreamResponse.Unmarshal(m, b) @@ -959,9 +992,9 @@ func (m *VStreamResponse) XXX_DiscardUnknown() { var xxx_messageInfo_VStreamResponse proto.InternalMessageInfo -func (m *VStreamResponse) GetEvent() []*VEvent { +func (m *VStreamResponse) GetEvents() []*VEvent { if m != nil { - return m.Event + return m.Events } return nil } @@ -987,72 +1020,79 @@ func init() { proto.RegisterEnum("binlogdata.BinlogTransaction_Statement_Category", BinlogTransaction_Statement_Category_name, BinlogTransaction_Statement_Category_value) } -func init() { proto.RegisterFile("binlogdata.proto", fileDescriptor_binlogdata_e1edbb575eea20d0) } - -var fileDescriptor_binlogdata_e1edbb575eea20d0 = []byte{ - // 1017 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x56, 0xdb, 0x6e, 0xdb, 0x46, - 0x13, 0x0e, 0x45, 0x8a, 0x22, 0x87, 0x8e, 0xbd, 0x5e, 0x1f, 0x20, 0x18, 0x08, 0x60, 0x10, 0x3f, - 0xfe, 0xb8, 0x06, 0x2a, 0xa5, 0xea, 0xe9, 0xa2, 0x57, 0x96, 0x44, 0xbb, 0x8a, 0x69, 0xc9, 0x59, - 0xd3, 0x49, 0x91, 0x1b, 0x82, 0x96, 0xd6, 0xb2, 0x60, 0x89, 0x94, 0xc9, 0x95, 0x5d, 0x3d, 0x47, - 0x9f, 0xa2, 0x7d, 0x90, 0xbc, 0x49, 0xef, 0xfa, 0x10, 0xc5, 0x1e, 0x48, 0x49, 0x0e, 0x90, 0xaa, - 0x17, 0xbd, 0x9b, 0xd3, 0x7e, 0x3b, 0xf3, 0xcd, 0x70, 0x87, 0x80, 0x6e, 0x46, 0xf1, 0x38, 0x19, - 0x0e, 0x22, 0x16, 0xd5, 0xa6, 0x69, 0xc2, 0x12, 0x0c, 0x0b, 0xcb, 0x81, 0xf3, 0x30, 0xa3, 0xe9, - 0x5c, 0x3a, 0x0e, 0x36, 0x59, 0x32, 0x4d, 0x16, 0x81, 0xee, 0x05, 0x54, 0x5a, 0x77, 0x51, 0x9a, - 0x51, 0x86, 0xf7, 0xc1, 0xec, 0x8f, 0x47, 0x34, 0x66, 0x55, 0xed, 0x50, 0x3b, 0x2a, 0x13, 0xa5, - 0x61, 0x0c, 0x46, 0x3f, 0x89, 0xe3, 0x6a, 0x49, 0x58, 0x85, 0xcc, 0x63, 0x33, 0x9a, 0x3e, 0xd2, - 0xb4, 0xaa, 0xcb, 0x58, 0xa9, 0xb9, 0x7f, 0xea, 0xb0, 0xdd, 0x14, 0x57, 0x07, 0x69, 0x14, 0x67, - 0x51, 0x9f, 0x8d, 0x92, 0x18, 0x9f, 0x01, 0x64, 0x2c, 0x62, 0x74, 0x42, 0x63, 0x96, 0x55, 0xb5, - 0x43, 0xfd, 0xc8, 0x69, 0xbc, 0xae, 0x2d, 0x25, 0xfd, 0xd9, 0x91, 0xda, 0x55, 0x1e, 0x4f, 0x96, - 0x8e, 0xe2, 0x06, 0x38, 0xf4, 0x91, 0xc6, 0x2c, 0x64, 0xc9, 0x3d, 0x8d, 0xab, 0xc6, 0xa1, 0x76, - 0xe4, 0x34, 0xb6, 0x6b, 0xb2, 0x40, 0x8f, 0x7b, 0x02, 0xee, 0x20, 0x40, 0x0b, 0xf9, 0xe0, 0x53, - 0x09, 0xec, 0x02, 0x0d, 0xfb, 0x60, 0xf5, 0x23, 0x46, 0x87, 0x49, 0x3a, 0x17, 0x65, 0x6e, 0x36, - 0xde, 0xac, 0x99, 0x48, 0xad, 0xa5, 0xce, 0x91, 0x02, 0x01, 0x7f, 0x0d, 0x95, 0xbe, 0x64, 0x4f, - 0xb0, 0xe3, 0x34, 0x76, 0x96, 0xc1, 0x14, 0xb1, 0x24, 0x8f, 0xc1, 0x08, 0xf4, 0xec, 0x61, 0x2c, - 0x28, 0xdb, 0x20, 0x5c, 0x74, 0x7f, 0xd7, 0xc0, 0xca, 0x71, 0xf1, 0x0e, 0x6c, 0x35, 0xfd, 0xf0, - 0xba, 0x4b, 0xbc, 0x56, 0xef, 0xac, 0xdb, 0xf9, 0xe8, 0xb5, 0xd1, 0x0b, 0xbc, 0x01, 0x56, 0xd3, - 0x0f, 0x9b, 0xde, 0x59, 0xa7, 0x8b, 0x34, 0xfc, 0x12, 0xec, 0xa6, 0x1f, 0xb6, 0x7a, 0x17, 0x17, - 0x9d, 0x00, 0x95, 0xf0, 0x16, 0x38, 0x4d, 0x3f, 0x24, 0x3d, 0xdf, 0x6f, 0x9e, 0xb4, 0xce, 0x91, - 0x8e, 0xf7, 0x60, 0xbb, 0xe9, 0x87, 0xed, 0x0b, 0x3f, 0x6c, 0x7b, 0x97, 0xc4, 0x6b, 0x9d, 0x04, - 0x5e, 0x1b, 0x19, 0x18, 0xc0, 0xe4, 0xe6, 0xb6, 0x8f, 0xca, 0x4a, 0xbe, 0xf2, 0x02, 0x64, 0x2a, - 0xb8, 0x4e, 0xf7, 0xca, 0x23, 0x01, 0xaa, 0x28, 0xf5, 0xfa, 0xb2, 0x7d, 0x12, 0x78, 0xc8, 0x52, - 0x6a, 0xdb, 0xf3, 0xbd, 0xc0, 0x43, 0xf6, 0x5b, 0xc3, 0x2a, 0x21, 0xfd, 0xad, 0x61, 0xe9, 0xc8, - 0x70, 0x7f, 0xd3, 0x60, 0xef, 0x8a, 0xa5, 0x34, 0x9a, 0x9c, 0xd3, 0x39, 0x89, 0xe2, 0x21, 0x25, - 0xf4, 0x61, 0x46, 0x33, 0x86, 0x0f, 0xc0, 0x9a, 0x26, 0xd9, 0x88, 0x73, 0x27, 0x08, 0xb6, 0x49, - 0xa1, 0xe3, 0x3a, 0xd8, 0xf7, 0x74, 0x1e, 0xa6, 0x3c, 0x5e, 0x11, 0x86, 0x6b, 0xc5, 0x40, 0x16, - 0x48, 0xd6, 0xbd, 0x92, 0x96, 0xf9, 0xd5, 0xff, 0x99, 0x5f, 0xf7, 0x16, 0xf6, 0x9f, 0x27, 0x95, - 0x4d, 0x93, 0x38, 0xa3, 0xd8, 0x07, 0x2c, 0x0f, 0x86, 0x6c, 0xd1, 0x5b, 0x91, 0x9f, 0xd3, 0x78, - 0xf5, 0xc5, 0x01, 0x20, 0xdb, 0x37, 0xcf, 0x4d, 0xee, 0xaf, 0xb0, 0x23, 0xef, 0x09, 0xa2, 0x9b, - 0x31, 0xcd, 0xd6, 0x29, 0x7d, 0x1f, 0x4c, 0x26, 0x82, 0xab, 0xa5, 0x43, 0xfd, 0xc8, 0x26, 0x4a, - 0xfb, 0xb7, 0x15, 0x0e, 0x60, 0x77, 0xf5, 0xe6, 0xff, 0xa4, 0xbe, 0xef, 0xc0, 0x20, 0xb3, 0x31, - 0xc5, 0xbb, 0x50, 0x9e, 0x44, 0xac, 0x7f, 0xa7, 0xaa, 0x91, 0x0a, 0x2f, 0xe5, 0x76, 0x34, 0x66, - 0x34, 0x15, 0x2d, 0xb4, 0x89, 0xd2, 0xdc, 0x37, 0x60, 0x9e, 0x0a, 0x09, 0xff, 0x1f, 0xca, 0xe9, - 0x8c, 0xd7, 0x2a, 0x3f, 0x75, 0xb4, 0x9c, 0x00, 0x07, 0x26, 0xd2, 0xed, 0xfe, 0xa5, 0xc1, 0x86, - 0x4c, 0xe8, 0x2a, 0x99, 0xa5, 0x7d, 0xca, 0x19, 0xbc, 0xa7, 0xf3, 0x6c, 0x1a, 0xf5, 0x69, 0xce, - 0x60, 0xae, 0xf3, 0x64, 0xb2, 0xbb, 0x28, 0x1d, 0xa8, 0x5b, 0xa5, 0x82, 0xbf, 0x07, 0x47, 0x30, - 0xc9, 0x42, 0x36, 0x9f, 0x52, 0xc1, 0xe1, 0x66, 0x63, 0x77, 0x31, 0x54, 0x82, 0x27, 0x16, 0xcc, - 0xa7, 0x94, 0x00, 0x2b, 0xe4, 0xd5, 0x49, 0x34, 0xd6, 0x98, 0xc4, 0x45, 0xff, 0xca, 0x2b, 0xfd, - 0x3b, 0x2e, 0xc8, 0x30, 0x15, 0xca, 0x52, 0xad, 0x92, 0x8e, 0x82, 0xa0, 0x77, 0x60, 0x93, 0xe4, - 0xa9, 0x75, 0x27, 0x00, 0x5d, 0x30, 0x6f, 0xe8, 0x6d, 0x92, 0x52, 0xd5, 0x25, 0x50, 0xaf, 0x18, - 0x49, 0x9e, 0x88, 0xf2, 0xe0, 0x43, 0x28, 0x47, 0xb7, 0x39, 0xd1, 0xab, 0x21, 0xd2, 0xe1, 0x46, - 0x60, 0x91, 0xe4, 0x49, 0xbc, 0x7c, 0xf8, 0x15, 0xc8, 0x0a, 0xc3, 0x38, 0x9a, 0xe4, 0xf4, 0xd9, - 0xc2, 0xd2, 0x8d, 0x26, 0x14, 0xff, 0x00, 0x4e, 0x9a, 0x3c, 0x85, 0x7d, 0x71, 0xbd, 0x1c, 0x43, - 0xa7, 0xb1, 0xb7, 0xd2, 0x9a, 0x3c, 0x39, 0x02, 0x69, 0x2e, 0x66, 0xee, 0x3b, 0x80, 0xd3, 0x11, - 0x1d, 0x0f, 0xd6, 0xba, 0xe4, 0x7f, 0x9c, 0x0e, 0x3a, 0x1e, 0xe4, 0xf8, 0x1b, 0x2a, 0x65, 0x81, - 0x40, 0x94, 0xcf, 0xfd, 0xa4, 0x81, 0xf9, 0x5e, 0xe2, 0x1d, 0x83, 0x21, 0x1a, 0x27, 0xdf, 0xe2, - 0xfd, 0xe5, 0x74, 0x64, 0x84, 0x68, 0x9d, 0x88, 0xe1, 0x8b, 0x68, 0xc8, 0x46, 0xf9, 0x00, 0x08, - 0x99, 0x3f, 0xa9, 0x83, 0x81, 0x7c, 0x52, 0x6d, 0xc2, 0x45, 0xfc, 0x0d, 0xd8, 0xbc, 0x4e, 0xb1, - 0x01, 0x54, 0x6b, 0x77, 0x9f, 0x55, 0x29, 0x80, 0x89, 0x95, 0xe6, 0xcc, 0xfd, 0x08, 0x8e, 0xc8, - 0x4c, 0x1d, 0x2a, 0x8b, 0x43, 0xfb, 0xab, 0x9d, 0xcc, 0x19, 0x20, 0x70, 0x5b, 0xc8, 0xee, 0x2f, - 0xb0, 0xf9, 0x5e, 0x7e, 0x8f, 0xeb, 0xbc, 0x01, 0xc7, 0x2b, 0x1f, 0xce, 0x97, 0x67, 0xe5, 0x27, - 0xd8, 0x2a, 0x90, 0xd5, 0x37, 0x7e, 0x04, 0x65, 0x99, 0x9f, 0xfc, 0xaa, 0xf0, 0xe7, 0x5c, 0x11, - 0x19, 0x70, 0xfc, 0x87, 0x06, 0xb0, 0x60, 0x0f, 0x3b, 0x50, 0xb9, 0xee, 0x9e, 0x77, 0x7b, 0x1f, - 0xba, 0xe8, 0x05, 0xb6, 0xc0, 0x38, 0x0b, 0x3a, 0x6d, 0xa4, 0x61, 0x1b, 0xca, 0x72, 0xad, 0x94, - 0xf8, 0x4e, 0x50, 0x3b, 0x45, 0xe7, 0x0b, 0xa7, 0x58, 0x28, 0x06, 0xae, 0x80, 0x5e, 0xac, 0x0d, - 0xb5, 0x27, 0x4c, 0x0e, 0x48, 0xbc, 0x4b, 0xff, 0xa4, 0xe5, 0xa1, 0x0a, 0x77, 0x14, 0x1b, 0x03, - 0xc0, 0xcc, 0xd7, 0x05, 0x3f, 0xc9, 0x97, 0x0c, 0xf0, 0x7b, 0x7a, 0xc1, 0xcf, 0x1e, 0x41, 0x0e, - 0xb7, 0x91, 0xde, 0x07, 0xb4, 0xc1, 0x6d, 0xa7, 0x1d, 0xcf, 0x6f, 0xa3, 0x97, 0xcd, 0xaf, 0x3e, - 0xbe, 0x7e, 0x1c, 0x31, 0x9a, 0x65, 0xb5, 0x51, 0x52, 0x97, 0x52, 0x7d, 0x98, 0xd4, 0x1f, 0x59, - 0x5d, 0xfc, 0xa1, 0xd4, 0x17, 0x55, 0xde, 0x98, 0xc2, 0xf2, 0xed, 0xdf, 0x01, 0x00, 0x00, 0xff, - 0xff, 0xda, 0xbf, 0xad, 0x34, 0xf0, 0x08, 0x00, 0x00, +func init() { proto.RegisterFile("binlogdata.proto", fileDescriptor_binlogdata_602eda7964a9642b) } + +var fileDescriptor_binlogdata_602eda7964a9642b = []byte{ + // 1123 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x56, 0xdd, 0x6e, 0xe2, 0x56, + 0x10, 0x5e, 0xb0, 0x31, 0x78, 0x9c, 0x1f, 0xe7, 0xe4, 0x47, 0x28, 0xea, 0x4a, 0x91, 0xd5, 0x76, + 0xd3, 0x48, 0x85, 0x2d, 0xfd, 0xbb, 0xaa, 0xaa, 0x00, 0x4e, 0xca, 0xc6, 0x81, 0xec, 0x89, 0x93, + 0x95, 0xf6, 0xc6, 0x72, 0xcc, 0x81, 0x58, 0x31, 0x36, 0xb1, 0x4f, 0x48, 0x79, 0x82, 0x3e, 0x40, + 0x9f, 0xa2, 0x7d, 0x90, 0x3e, 0x49, 0x7b, 0xd7, 0x87, 0xa8, 0xce, 0x8f, 0x0d, 0x64, 0xa5, 0x6e, + 0x7a, 0xd1, 0xbb, 0xf9, 0x3f, 0x33, 0xdf, 0x8c, 0x67, 0x0c, 0xe6, 0x4d, 0x18, 0x47, 0xc9, 0x78, + 0xe8, 0x53, 0xbf, 0x31, 0x4d, 0x13, 0x9a, 0x20, 0x58, 0x48, 0xf6, 0x8d, 0x19, 0x4d, 0xa7, 0x81, + 0x50, 0xec, 0x1b, 0xf7, 0x0f, 0x24, 0x9d, 0x4b, 0x66, 0x83, 0x26, 0xd3, 0x64, 0xe1, 0x65, 0x9d, + 0x43, 0xb5, 0x73, 0xeb, 0xa7, 0x19, 0xa1, 0x68, 0x0f, 0xb4, 0x20, 0x0a, 0x49, 0x4c, 0xeb, 0xa5, + 0x83, 0xd2, 0x61, 0x05, 0x4b, 0x0e, 0x21, 0x50, 0x83, 0x24, 0x8e, 0xeb, 0x65, 0x2e, 0xe5, 0x34, + 0xb3, 0xcd, 0x48, 0x3a, 0x23, 0x69, 0x5d, 0x11, 0xb6, 0x82, 0xb3, 0xfe, 0x52, 0x60, 0xab, 0xcd, + 0xf3, 0x70, 0x53, 0x3f, 0xce, 0xfc, 0x80, 0x86, 0x49, 0x8c, 0x4e, 0x01, 0x32, 0xea, 0x53, 0x32, + 0x21, 0x31, 0xcd, 0xea, 0xa5, 0x03, 0xe5, 0xd0, 0x68, 0xbd, 0x6a, 0x2c, 0x55, 0xf0, 0x81, 0x4b, + 0xe3, 0x32, 0xb7, 0xc7, 0x4b, 0xae, 0xa8, 0x05, 0x06, 0x99, 0x91, 0x98, 0x7a, 0x34, 0xb9, 0x23, + 0x71, 0x5d, 0x3d, 0x28, 0x1d, 0x1a, 0xad, 0xad, 0x86, 0x28, 0xd0, 0x66, 0x1a, 0x97, 0x29, 0x30, + 0x90, 0x82, 0xde, 0xff, 0xa3, 0x0c, 0x7a, 0x11, 0x0d, 0x39, 0x50, 0x0b, 0x7c, 0x4a, 0xc6, 0x49, + 0x3a, 0xe7, 0x65, 0x6e, 0xb4, 0x5e, 0x3f, 0x33, 0x91, 0x46, 0x47, 0xfa, 0xe1, 0x22, 0x02, 0xfa, + 0x12, 0xaa, 0x81, 0x40, 0x8f, 0xa3, 0x63, 0xb4, 0xb6, 0x97, 0x83, 0x49, 0x60, 0x71, 0x6e, 0x83, + 0x4c, 0x50, 0xb2, 0xfb, 0x88, 0x43, 0xb6, 0x86, 0x19, 0x69, 0xfd, 0x56, 0x82, 0x5a, 0x1e, 0x17, + 0x6d, 0xc3, 0x66, 0xdb, 0xf1, 0xae, 0xfa, 0xd8, 0xee, 0x0c, 0x4e, 0xfb, 0xbd, 0xf7, 0x76, 0xd7, + 0x7c, 0x81, 0xd6, 0xa0, 0xd6, 0x76, 0xbc, 0xb6, 0x7d, 0xda, 0xeb, 0x9b, 0x25, 0xb4, 0x0e, 0x7a, + 0xdb, 0xf1, 0x3a, 0x83, 0xf3, 0xf3, 0x9e, 0x6b, 0x96, 0xd1, 0x26, 0x18, 0x6d, 0xc7, 0xc3, 0x03, + 0xc7, 0x69, 0x1f, 0x77, 0xce, 0x4c, 0x05, 0xed, 0xc2, 0x56, 0xdb, 0xf1, 0xba, 0xe7, 0x8e, 0xd7, + 0xb5, 0x2f, 0xb0, 0xdd, 0x39, 0x76, 0xed, 0xae, 0xa9, 0x22, 0x00, 0x8d, 0x89, 0xbb, 0x8e, 0x59, + 0x91, 0xf4, 0xa5, 0xed, 0x9a, 0x9a, 0x0c, 0xd7, 0xeb, 0x5f, 0xda, 0xd8, 0x35, 0xab, 0x92, 0xbd, + 0xba, 0xe8, 0x1e, 0xbb, 0xb6, 0x59, 0x93, 0x6c, 0xd7, 0x76, 0x6c, 0xd7, 0x36, 0xf5, 0x37, 0x6a, + 0xad, 0x6c, 0x2a, 0x6f, 0xd4, 0x9a, 0x62, 0xaa, 0xd6, 0xaf, 0x25, 0xd8, 0xbd, 0xa4, 0x29, 0xf1, + 0x27, 0x67, 0x64, 0x8e, 0xfd, 0x78, 0x4c, 0x30, 0xb9, 0x7f, 0x20, 0x19, 0x45, 0xfb, 0x50, 0x9b, + 0x26, 0x59, 0xc8, 0xb0, 0xe3, 0x00, 0xeb, 0xb8, 0xe0, 0x51, 0x13, 0xf4, 0x3b, 0x32, 0xf7, 0x52, + 0x66, 0x2f, 0x01, 0x43, 0x8d, 0x62, 0x20, 0x8b, 0x48, 0xb5, 0x3b, 0x49, 0x2d, 0xe3, 0xab, 0x7c, + 0x1c, 0x5f, 0x6b, 0x04, 0x7b, 0x4f, 0x93, 0xca, 0xa6, 0x49, 0x9c, 0x11, 0xe4, 0x00, 0x12, 0x8e, + 0x1e, 0x5d, 0xf4, 0x96, 0xe7, 0x67, 0xb4, 0x5e, 0xfe, 0xeb, 0x00, 0xe0, 0xad, 0x9b, 0xa7, 0x22, + 0xeb, 0x67, 0xd8, 0x16, 0xef, 0xb8, 0xfe, 0x4d, 0x44, 0xb2, 0xe7, 0x94, 0xbe, 0x07, 0x1a, 0xe5, + 0xc6, 0xf5, 0xf2, 0x81, 0x72, 0xa8, 0x63, 0xc9, 0xfd, 0xd7, 0x0a, 0x87, 0xb0, 0xb3, 0xfa, 0xf2, + 0xff, 0x52, 0xdf, 0x37, 0xa0, 0xe2, 0x87, 0x88, 0xa0, 0x1d, 0xa8, 0x4c, 0x7c, 0x1a, 0xdc, 0xca, + 0x6a, 0x04, 0xc3, 0x4a, 0x19, 0x85, 0x11, 0x25, 0x29, 0x6f, 0xa1, 0x8e, 0x25, 0x67, 0xbd, 0x06, + 0xed, 0x84, 0x53, 0xe8, 0x73, 0xa8, 0xa4, 0x0f, 0xac, 0x56, 0xf1, 0xa9, 0x9b, 0xcb, 0x09, 0xb0, + 0xc0, 0x58, 0xa8, 0xad, 0xbf, 0x4b, 0xb0, 0x26, 0x12, 0xba, 0x4c, 0x1e, 0xd2, 0x80, 0x30, 0x04, + 0xef, 0xc8, 0x3c, 0x9b, 0xfa, 0x01, 0xc9, 0x11, 0xcc, 0x79, 0x96, 0x4c, 0x76, 0xeb, 0xa7, 0x43, + 0xf9, 0xaa, 0x60, 0xd0, 0xb7, 0x60, 0x70, 0x24, 0xa9, 0x47, 0xe7, 0x53, 0xc2, 0x31, 0xdc, 0x68, + 0xed, 0x2c, 0x86, 0x8a, 0xe3, 0x44, 0xdd, 0xf9, 0x94, 0x60, 0xa0, 0x05, 0xbd, 0x3a, 0x89, 0xea, + 0x33, 0x26, 0x71, 0xd1, 0xbf, 0xca, 0x4a, 0xff, 0x8e, 0x0a, 0x30, 0x34, 0x19, 0x65, 0xa9, 0x56, + 0x01, 0x47, 0x01, 0xd0, 0x5b, 0xd0, 0x71, 0xf2, 0xd8, 0xb9, 0xe5, 0x01, 0x2d, 0xd0, 0x6e, 0xc8, + 0x28, 0x49, 0x89, 0xec, 0x12, 0xc8, 0x2d, 0x86, 0x93, 0x47, 0x2c, 0x35, 0xe8, 0x00, 0x2a, 0xfe, + 0x28, 0x07, 0x7a, 0xd5, 0x44, 0x28, 0x2c, 0x1f, 0x6a, 0x38, 0x79, 0xe4, 0x9b, 0x0f, 0xbd, 0x04, + 0x51, 0xa1, 0x17, 0xfb, 0x93, 0x1c, 0x3e, 0x9d, 0x4b, 0xfa, 0xfe, 0x84, 0xa0, 0xef, 0xc0, 0x48, + 0x93, 0x47, 0x2f, 0xe0, 0xcf, 0x8b, 0x31, 0x34, 0x5a, 0xbb, 0x2b, 0xad, 0xc9, 0x93, 0xc3, 0x90, + 0xe6, 0x64, 0x66, 0xbd, 0x05, 0x38, 0x09, 0x49, 0x34, 0x7c, 0xd6, 0x23, 0x9f, 0x32, 0x38, 0x48, + 0x34, 0xcc, 0xe3, 0xaf, 0xc9, 0x94, 0x79, 0x04, 0x2c, 0x75, 0xd6, 0x9f, 0x25, 0xd0, 0xae, 0x45, + 0xbc, 0x23, 0x50, 0x79, 0xe3, 0xc4, 0x2e, 0xde, 0x5b, 0x4e, 0x47, 0x58, 0xf0, 0xd6, 0x71, 0x1b, + 0xf4, 0x09, 0xe8, 0x34, 0x9c, 0x90, 0x8c, 0xfa, 0x93, 0x29, 0x87, 0x44, 0xc1, 0x0b, 0x01, 0x3b, + 0x53, 0x63, 0x1a, 0x0e, 0xf9, 0x08, 0xe8, 0x98, 0xd3, 0x6c, 0xe1, 0x0e, 0x87, 0x11, 0x6f, 0xb0, + 0x8e, 0x19, 0x89, 0xbe, 0x02, 0x9d, 0xa1, 0xc0, 0xef, 0x43, 0xbd, 0xc2, 0x61, 0xdd, 0x79, 0x82, + 0x01, 0x7f, 0x16, 0xd7, 0xd2, 0x1c, 0xd7, 0xef, 0xc1, 0xe0, 0x79, 0x4b, 0x27, 0xd1, 0xe7, 0xbd, + 0xd5, 0x3e, 0xe7, 0xf8, 0x60, 0x18, 0x15, 0xb4, 0xf5, 0x4b, 0x19, 0x36, 0xae, 0xc5, 0xe7, 0x9a, + 0xaf, 0x88, 0x1f, 0x61, 0x9b, 0x8c, 0x46, 0x24, 0xa0, 0xe1, 0x8c, 0x78, 0x81, 0x1f, 0x45, 0x24, + 0xf5, 0xc2, 0xa1, 0x1c, 0x81, 0xcd, 0x86, 0x38, 0xdb, 0x1d, 0x2e, 0xef, 0x75, 0xf1, 0x56, 0x61, + 0x2b, 0x45, 0x43, 0x64, 0xc3, 0x76, 0x38, 0x99, 0x90, 0x61, 0xe8, 0xd3, 0xe5, 0x00, 0x62, 0x40, + 0x76, 0x25, 0xda, 0xd7, 0xee, 0xa9, 0x4f, 0xc9, 0x22, 0x4c, 0xe1, 0x51, 0x84, 0xf9, 0x8c, 0x8d, + 0x73, 0x3a, 0x2e, 0xb6, 0xce, 0xba, 0xf4, 0x74, 0xb9, 0x10, 0x4b, 0xe5, 0xca, 0x46, 0x53, 0x9f, + 0x6c, 0xb4, 0xc5, 0xe4, 0x57, 0x3e, 0x3a, 0xf9, 0x3f, 0xc0, 0x66, 0x01, 0x84, 0xdc, 0x58, 0x47, + 0xa0, 0x71, 0x3c, 0xf3, 0x25, 0x81, 0x3e, 0x6c, 0x3d, 0x96, 0x16, 0x47, 0xbf, 0x97, 0x00, 0x16, + 0xd3, 0x80, 0x0c, 0xa8, 0x5e, 0xf5, 0xcf, 0xfa, 0x83, 0x77, 0x7d, 0xf3, 0x05, 0xaa, 0x81, 0x7a, + 0xea, 0xf6, 0xba, 0x66, 0x09, 0xe9, 0x50, 0x11, 0x67, 0xb2, 0xcc, 0x6e, 0x9c, 0xbc, 0x91, 0x0a, + 0x3b, 0xa0, 0xc5, 0x81, 0x54, 0x51, 0x15, 0x94, 0xe2, 0x0c, 0xca, 0xbb, 0xa7, 0xb1, 0x80, 0xd8, + 0xbe, 0x70, 0x8e, 0x3b, 0xb6, 0x59, 0x65, 0x8a, 0xe2, 0x02, 0x02, 0x68, 0xf9, 0xf9, 0x63, 0x9e, + 0xec, 0x68, 0x02, 0x7b, 0x67, 0xe0, 0xfe, 0x64, 0x63, 0xd3, 0x60, 0x32, 0x3c, 0x78, 0x67, 0xae, + 0x31, 0xd9, 0x49, 0xcf, 0x76, 0xba, 0xe6, 0x7a, 0xfb, 0x8b, 0xf7, 0xaf, 0x66, 0x21, 0x25, 0x59, + 0xd6, 0x08, 0x93, 0xa6, 0xa0, 0x9a, 0xe3, 0xa4, 0x39, 0xa3, 0x4d, 0xfe, 0xc7, 0xd5, 0x5c, 0x94, + 0x79, 0xa3, 0x71, 0xc9, 0xd7, 0xff, 0x04, 0x00, 0x00, 0xff, 0xff, 0xcb, 0x74, 0x80, 0x55, 0xcd, + 0x09, 0x00, 0x00, } diff --git a/go/vt/proto/queryservice/queryservice.pb.go b/go/vt/proto/queryservice/queryservice.pb.go index dc4bf2f2ba8..7a0bce4f401 100644 --- a/go/vt/proto/queryservice/queryservice.pb.go +++ b/go/vt/proto/queryservice/queryservice.pb.go @@ -6,6 +6,7 @@ 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" import ( @@ -85,6 +86,8 @@ type QueryClient interface { StreamHealth(ctx context.Context, in *query.StreamHealthRequest, opts ...grpc.CallOption) (Query_StreamHealthClient, error) // UpdateStream asks the server to return a stream of the updates that have been applied to its database. UpdateStream(ctx context.Context, in *query.UpdateStreamRequest, opts ...grpc.CallOption) (Query_UpdateStreamClient, error) + // VStream streams vreplication events. + VStream(ctx context.Context, in *binlogdata.VStreamRequest, opts ...grpc.CallOption) (Query_VStreamClient, error) } type queryClient struct { @@ -376,6 +379,38 @@ func (x *queryUpdateStreamClient) Recv() (*query.UpdateStreamResponse, error) { return m, nil } +func (c *queryClient) VStream(ctx context.Context, in *binlogdata.VStreamRequest, opts ...grpc.CallOption) (Query_VStreamClient, error) { + stream, err := c.cc.NewStream(ctx, &_Query_serviceDesc.Streams[4], "/queryservice.Query/VStream", opts...) + if err != nil { + return nil, err + } + x := &queryVStreamClient{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_VStreamClient interface { + Recv() (*binlogdata.VStreamResponse, error) + grpc.ClientStream +} + +type queryVStreamClient struct { + grpc.ClientStream +} + +func (x *queryVStreamClient) Recv() (*binlogdata.VStreamResponse, error) { + m := new(binlogdata.VStreamResponse) + 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 @@ -427,6 +462,8 @@ type QueryServer interface { StreamHealth(*query.StreamHealthRequest, Query_StreamHealthServer) error // UpdateStream asks the server to return a stream of the updates that have been applied to its database. UpdateStream(*query.UpdateStreamRequest, Query_UpdateStreamServer) error + // VStream streams vreplication events. + VStream(*binlogdata.VStreamRequest, Query_VStreamServer) error } func RegisterQueryServer(s *grpc.Server, srv QueryServer) { @@ -823,6 +860,27 @@ func (x *queryUpdateStreamServer) Send(m *query.UpdateStreamResponse) error { return x.ServerStream.SendMsg(m) } +func _Query_VStream_Handler(srv interface{}, stream grpc.ServerStream) error { + m := new(binlogdata.VStreamRequest) + if err := stream.RecvMsg(m); err != nil { + return err + } + return srv.(QueryServer).VStream(m, &queryVStreamServer{stream}) +} + +type Query_VStreamServer interface { + Send(*binlogdata.VStreamResponse) error + grpc.ServerStream +} + +type queryVStreamServer struct { + grpc.ServerStream +} + +func (x *queryVStreamServer) Send(m *binlogdata.VStreamResponse) error { + return x.ServerStream.SendMsg(m) +} + var _Query_serviceDesc = grpc.ServiceDesc{ ServiceName: "queryservice.Query", HandlerType: (*QueryServer)(nil), @@ -917,45 +975,51 @@ var _Query_serviceDesc = grpc.ServiceDesc{ Handler: _Query_UpdateStream_Handler, ServerStreams: true, }, + { + StreamName: "VStream", + Handler: _Query_VStream_Handler, + ServerStreams: true, + }, }, Metadata: "queryservice.proto", } -func init() { proto.RegisterFile("queryservice.proto", fileDescriptor_queryservice_bb9da33c43234b51) } +func init() { proto.RegisterFile("queryservice.proto", fileDescriptor_queryservice_17509881eb07629d) } -var fileDescriptor_queryservice_bb9da33c43234b51 = []byte{ - // 519 bytes of a gzipped FileDescriptorProto +var fileDescriptor_queryservice_17509881eb07629d = []byte{ + // 544 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x95, 0xdf, 0x6b, 0xd4, 0x40, - 0x10, 0xc7, 0xf5, 0xa1, 0xad, 0x4c, 0xe3, 0xaf, 0xad, 0x55, 0x9b, 0xd6, 0xb6, 0xf6, 0x4d, 0x84, - 0x46, 0x54, 0x10, 0x0a, 0x3e, 0xf4, 0x82, 0xa2, 0x14, 0x7f, 0xdd, 0x59, 0x10, 0x1f, 0x84, 0x6d, - 0x6e, 0x38, 0x43, 0x73, 0x49, 0xba, 0xbb, 0x77, 0xe8, 0x5f, 0xe4, 0xbf, 0x29, 0x66, 0x33, 0x93, - 0xdd, 0xbd, 0xc4, 0xb7, 0xce, 0xf7, 0x3b, 0xf3, 0x61, 0x6e, 0xa7, 0x33, 0x01, 0x71, 0xb5, 0x40, - 0xf5, 0x5b, 0xa3, 0x5a, 0xe6, 0x19, 0x1e, 0xd7, 0xaa, 0x32, 0x95, 0x88, 0x5c, 0x2d, 0xde, 0x6c, - 0x22, 0x6b, 0x3d, 0xff, 0x13, 0xc1, 0xda, 0x97, 0x7f, 0xb1, 0x38, 0x81, 0x8d, 0x37, 0xbf, 0x30, - 0x5b, 0x18, 0x14, 0xdb, 0xc7, 0x36, 0xa5, 0x8d, 0xc7, 0x78, 0xb5, 0x40, 0x6d, 0xe2, 0xfb, 0xa1, - 0xac, 0xeb, 0xaa, 0xd4, 0x78, 0x74, 0x4d, 0xbc, 0x87, 0xa8, 0x15, 0x47, 0xd2, 0x64, 0x3f, 0x45, - 0xec, 0x67, 0x36, 0x22, 0x51, 0x76, 0x7b, 0x3d, 0x46, 0x7d, 0x84, 0x9b, 0x13, 0xa3, 0x50, 0xce, - 0xa9, 0x19, 0xca, 0xf7, 0x54, 0x82, 0xed, 0xf5, 0x9b, 0x44, 0x7b, 0x76, 0x5d, 0xbc, 0x84, 0xb5, - 0x11, 0xce, 0xf2, 0x52, 0x6c, 0xb5, 0xa9, 0x4d, 0x44, 0xf5, 0xf7, 0x7c, 0x91, 0xbb, 0x78, 0x05, - 0xeb, 0x69, 0x35, 0x9f, 0xe7, 0x46, 0x50, 0x86, 0x0d, 0xa9, 0x6e, 0x3b, 0x50, 0xb9, 0xf0, 0x35, - 0xdc, 0x18, 0x57, 0x45, 0x71, 0x21, 0xb3, 0x4b, 0x41, 0xef, 0x45, 0x02, 0x15, 0x3f, 0x58, 0xd1, - 0xb9, 0xfc, 0x04, 0x36, 0x3e, 0x2b, 0xac, 0xa5, 0xea, 0x86, 0xd0, 0xc6, 0xe1, 0x10, 0x58, 0xe6, - 0xda, 0x4f, 0x70, 0xcb, 0xb6, 0xd3, 0x5a, 0x53, 0xb1, 0xe7, 0x75, 0x49, 0x32, 0x91, 0x1e, 0x0d, - 0xb8, 0x0c, 0x3c, 0x87, 0x3b, 0xd4, 0x22, 0x23, 0xf7, 0x83, 0xde, 0x43, 0xe8, 0xc1, 0xa0, 0xcf, - 0xd8, 0x6f, 0x70, 0x37, 0x55, 0x28, 0x0d, 0x7e, 0x55, 0xb2, 0xd4, 0x32, 0x33, 0x79, 0x55, 0x0a, - 0xaa, 0x5b, 0x71, 0x08, 0x7c, 0x38, 0x9c, 0xc0, 0xe4, 0xb7, 0xb0, 0x39, 0x31, 0x52, 0x99, 0x76, - 0x74, 0x3b, 0xfc, 0xcf, 0xc1, 0x1a, 0xd1, 0xe2, 0x3e, 0xcb, 0xe3, 0xa0, 0xe1, 0x39, 0x32, 0xa7, - 0xd3, 0x56, 0x38, 0xae, 0xc5, 0x9c, 0x1f, 0xb0, 0x95, 0x56, 0x65, 0x56, 0x2c, 0xa6, 0xde, 0x6f, - 0x7d, 0xcc, 0x0f, 0xbf, 0xe2, 0x11, 0xf7, 0xe8, 0x7f, 0x29, 0xcc, 0x1f, 0xc3, 0xed, 0x31, 0xca, - 0xa9, 0xcb, 0xa6, 0xa1, 0x06, 0x3a, 0x71, 0xf7, 0x87, 0x6c, 0x77, 0x95, 0x9b, 0x65, 0xa0, 0xf5, - 0x8b, 0xdd, 0x0d, 0x09, 0xb6, 0x6f, 0xb7, 0xd7, 0x73, 0x07, 0xed, 0x3a, 0xf6, 0x34, 0x1c, 0xf4, - 0xd4, 0x78, 0xf7, 0xe1, 0x70, 0x38, 0xc1, 0x3d, 0x12, 0x1f, 0x50, 0x6b, 0x39, 0x43, 0xbb, 0xf8, - 0x7c, 0x24, 0x3c, 0x35, 0x3c, 0x12, 0x81, 0xe9, 0x1c, 0x89, 0x14, 0xa0, 0x35, 0x4f, 0xb3, 0x4b, - 0xf1, 0xd0, 0xcf, 0x3f, 0xed, 0xc6, 0xbd, 0xd3, 0xe3, 0x70, 0x53, 0x29, 0xc0, 0xa4, 0x2e, 0x72, - 0x63, 0xcf, 0x29, 0x41, 0x3a, 0x29, 0x84, 0xb8, 0x0e, 0x43, 0xce, 0x20, 0xb2, 0xfd, 0xbd, 0x43, - 0x59, 0x98, 0xee, 0x92, 0xba, 0x62, 0xf8, 0xfc, 0xbe, 0xe7, 0xfc, 0xac, 0x33, 0x88, 0xce, 0xeb, - 0xa9, 0x34, 0xf4, 0x4a, 0x04, 0x73, 0xc5, 0x10, 0xe6, 0x7b, 0x1d, 0x6c, 0xf4, 0xf4, 0xfb, 0x93, - 0x65, 0x6e, 0x50, 0xeb, 0xe3, 0xbc, 0x4a, 0xec, 0x5f, 0xc9, 0xac, 0x4a, 0x96, 0x26, 0x69, 0xbe, - 0x24, 0x89, 0xfb, 0x8d, 0xb9, 0x58, 0x6f, 0xb4, 0x17, 0x7f, 0x03, 0x00, 0x00, 0xff, 0xff, 0x51, - 0x5a, 0xbc, 0xc0, 0x8e, 0x06, 0x00, 0x00, + 0x10, 0xc7, 0xf5, 0xa1, 0xad, 0x4c, 0x4f, 0xad, 0x5b, 0xab, 0x36, 0xad, 0x6d, 0xed, 0x9b, 0x08, + 0x17, 0x51, 0x41, 0x28, 0xf8, 0xd0, 0x0b, 0x16, 0xa5, 0xf8, 0xeb, 0xce, 0x16, 0xf1, 0x41, 0xd8, + 0x4b, 0x86, 0x33, 0x34, 0x97, 0x4d, 0x93, 0xbd, 0x43, 0xff, 0x6a, 0xff, 0x05, 0x31, 0x9b, 0x99, + 0xec, 0xee, 0x25, 0xbe, 0xdd, 0x7e, 0xbf, 0x33, 0x1f, 0x26, 0x3b, 0x37, 0xb3, 0x20, 0xae, 0x17, + 0x58, 0xfe, 0xae, 0xb0, 0x5c, 0xa6, 0x31, 0x0e, 0x8b, 0x52, 0x69, 0x25, 0x06, 0xb6, 0x16, 0x6c, + 0xd6, 0x27, 0x63, 0x05, 0x5b, 0xd3, 0x34, 0xcf, 0xd4, 0x2c, 0x91, 0x5a, 0x1a, 0xe5, 0xc5, 0x9f, + 0x01, 0xac, 0x7d, 0xf9, 0x17, 0x21, 0x4e, 0x60, 0xe3, 0xed, 0x2f, 0x8c, 0x17, 0x1a, 0xc5, 0xce, + 0xd0, 0x24, 0x35, 0xe7, 0x31, 0x5e, 0x2f, 0xb0, 0xd2, 0xc1, 0x03, 0x5f, 0xae, 0x0a, 0x95, 0x57, + 0x78, 0x7c, 0x43, 0xbc, 0x87, 0x41, 0x23, 0x8e, 0xa4, 0x8e, 0x7f, 0x8a, 0xc0, 0x8d, 0xac, 0x45, + 0xa2, 0xec, 0x75, 0x7a, 0x8c, 0xfa, 0x08, 0xb7, 0x27, 0xba, 0x44, 0x39, 0xa7, 0x62, 0x28, 0xde, + 0x51, 0x09, 0xb6, 0xdf, 0x6d, 0x12, 0xed, 0xf9, 0x4d, 0xf1, 0x0a, 0xd6, 0x46, 0x38, 0x4b, 0x73, + 0xb1, 0xdd, 0x84, 0xd6, 0x27, 0xca, 0xbf, 0xef, 0x8a, 0x5c, 0xc5, 0x6b, 0x58, 0x8f, 0xd4, 0x7c, + 0x9e, 0x6a, 0x41, 0x11, 0xe6, 0x48, 0x79, 0x3b, 0x9e, 0xca, 0x89, 0x6f, 0xe0, 0xd6, 0x58, 0x65, + 0xd9, 0x54, 0xc6, 0x57, 0x82, 0xee, 0x8b, 0x04, 0x4a, 0x7e, 0xb8, 0xa2, 0x73, 0xfa, 0x09, 0x6c, + 0x7c, 0x2e, 0xb1, 0x90, 0x65, 0xdb, 0x84, 0xe6, 0xec, 0x37, 0x81, 0x65, 0xce, 0xfd, 0x04, 0x77, + 0x4c, 0x39, 0x8d, 0x95, 0x88, 0x7d, 0xa7, 0x4a, 0x92, 0x89, 0xf4, 0xb8, 0xc7, 0x65, 0xe0, 0x05, + 0x6c, 0x51, 0x89, 0x8c, 0x3c, 0xf0, 0x6a, 0xf7, 0xa1, 0x87, 0xbd, 0x3e, 0x63, 0xbf, 0xc1, 0xbd, + 0xa8, 0x44, 0xa9, 0xf1, 0x6b, 0x29, 0xf3, 0x4a, 0xc6, 0x3a, 0x55, 0xb9, 0xa0, 0xbc, 0x15, 0x87, + 0xc0, 0x47, 0xfd, 0x01, 0x4c, 0x3e, 0x83, 0xcd, 0x89, 0x96, 0xa5, 0x6e, 0x5a, 0xb7, 0xcb, 0x7f, + 0x0e, 0xd6, 0x88, 0x16, 0x74, 0x59, 0x0e, 0x07, 0x35, 0xf7, 0x91, 0x39, 0xad, 0xb6, 0xc2, 0xb1, + 0x2d, 0xe6, 0xfc, 0x80, 0xed, 0x48, 0xe5, 0x71, 0xb6, 0x48, 0x9c, 0x6f, 0x7d, 0xc2, 0x17, 0xbf, + 0xe2, 0x11, 0xf7, 0xf8, 0x7f, 0x21, 0xcc, 0x1f, 0xc3, 0xdd, 0x31, 0xca, 0xc4, 0x66, 0x53, 0x53, + 0x3d, 0x9d, 0xb8, 0x07, 0x7d, 0xb6, 0x3d, 0xca, 0xf5, 0x30, 0xd0, 0xf8, 0x05, 0xf6, 0x84, 0x78, + 0xd3, 0xb7, 0xd7, 0xe9, 0xd9, 0x8d, 0xb6, 0x1d, 0xb3, 0x1a, 0x0e, 0x3b, 0x72, 0x9c, 0xfd, 0x70, + 0xd4, 0x1f, 0x60, 0x2f, 0x89, 0x0f, 0x58, 0x55, 0x72, 0x86, 0x66, 0xf0, 0x79, 0x49, 0x38, 0xaa, + 0xbf, 0x24, 0x3c, 0xd3, 0x5a, 0x12, 0x11, 0x40, 0x63, 0x9e, 0xc6, 0x57, 0xe2, 0x91, 0x1b, 0x7f, + 0xda, 0xb6, 0x7b, 0xb7, 0xc3, 0xe1, 0xa2, 0x22, 0x80, 0x49, 0x91, 0xa5, 0xda, 0xac, 0x53, 0x82, + 0xb4, 0x92, 0x0f, 0xb1, 0x1d, 0x86, 0x9c, 0xc3, 0xc0, 0xd4, 0xf7, 0x0e, 0x65, 0xa6, 0xdb, 0x4d, + 0x6a, 0x8b, 0xfe, 0xf5, 0xbb, 0x9e, 0xf5, 0x59, 0xe7, 0x30, 0xb8, 0x28, 0x12, 0xa9, 0xe9, 0x96, + 0x08, 0x66, 0x8b, 0x3e, 0xcc, 0xf5, 0x2c, 0xd8, 0x19, 0x6c, 0x5c, 0x32, 0xc7, 0x7a, 0x47, 0x2e, + 0x7d, 0x4e, 0x97, 0xd7, 0x72, 0x46, 0xcf, 0xbe, 0x3f, 0x5d, 0xa6, 0x1a, 0xab, 0x6a, 0x98, 0xaa, + 0xd0, 0xfc, 0x0a, 0x67, 0x2a, 0x5c, 0xea, 0xb0, 0x7e, 0x91, 0x42, 0xfb, 0xf5, 0x9a, 0xae, 0xd7, + 0xda, 0xcb, 0xbf, 0x01, 0x00, 0x00, 0xff, 0xff, 0xbd, 0x47, 0x8e, 0x80, 0xe8, 0x06, 0x00, 0x00, } diff --git a/go/vt/vtcombo/tablet_map.go b/go/vt/vtcombo/tablet_map.go index 0e6c79d254a..849fbb979af 100644 --- a/go/vt/vtcombo/tablet_map.go +++ b/go/vt/vtcombo/tablet_map.go @@ -47,6 +47,7 @@ import ( "vitess.io/vitess/go/vt/vttablet/tmclient" "vitess.io/vitess/go/vt/wrangler" + binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" querypb "vitess.io/vitess/go/vt/proto/query" replicationdatapb "vitess.io/vitess/go/vt/proto/replicationdata" tabletmanagerdatapb "vitess.io/vitess/go/vt/proto/tabletmanagerdata" @@ -472,6 +473,12 @@ func (itc *internalTabletConn) UpdateStream(ctx context.Context, target *querypb return tabletconn.ErrorFromGRPC(vterrors.ToGRPC(err)) } +// VStream is part of queryservice.QueryService. +func (itc *internalTabletConn) VStream(ctx context.Context, target *querypb.Target, startPos string, filter *binlogdatapb.Filter, send func([]*binlogdatapb.VEvent) error) error { + err := itc.tablet.qsc.QueryService().VStream(ctx, target, startPos, filter, send) + return tabletconn.ErrorFromGRPC(vterrors.ToGRPC(err)) +} + // // TabletManagerClient implementation // diff --git a/go/vt/vttablet/grpcqueryservice/server.go b/go/vt/vttablet/grpcqueryservice/server.go index c3ada0faecf..76f90995f74 100644 --- a/go/vt/vttablet/grpcqueryservice/server.go +++ b/go/vt/vttablet/grpcqueryservice/server.go @@ -26,6 +26,7 @@ import ( "vitess.io/vitess/go/vt/vterrors" "vitess.io/vitess/go/vt/vttablet/queryservice" + binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" querypb "vitess.io/vitess/go/vt/proto/query" queryservicepb "vitess.io/vitess/go/vt/proto/queryservice" ) @@ -375,6 +376,23 @@ func (q *query) UpdateStream(request *querypb.UpdateStreamRequest, stream querys return nil } +// VStream is part of the queryservice.QueryServer interface +func (q *query) VStream(request *binlogdatapb.VStreamRequest, stream queryservicepb.Query_VStreamServer) (err error) { + defer q.server.HandlePanic(&err) + ctx := callerid.NewContext(callinfo.GRPCCallInfo(stream.Context()), + request.EffectiveCallerId, + request.ImmediateCallerId, + ) + if err := q.server.VStream(ctx, request.Target, request.Position, request.Filter, func(events []*binlogdatapb.VEvent) error { + return stream.Send(&binlogdatapb.VStreamResponse{ + Events: events, + }) + }); err != nil { + return vterrors.ToGRPC(err) + } + return nil +} + // 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 f4871b5a860..7410c56e5ac 100644 --- a/go/vt/vttablet/grpctabletconn/conn.go +++ b/go/vt/vttablet/grpctabletconn/conn.go @@ -30,6 +30,7 @@ import ( "vitess.io/vitess/go/vt/vttablet/queryservice" "vitess.io/vitess/go/vt/vttablet/tabletconn" + binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" querypb "vitess.io/vitess/go/vt/proto/query" queryservicepb "vitess.io/vitess/go/vt/proto/queryservice" topodatapb "vitess.io/vitess/go/vt/proto/topodata" @@ -668,6 +669,50 @@ func (conn *gRPCQueryClient) UpdateStream(ctx context.Context, target *querypb.T } } +// VStream starts a VReplication stream. +func (conn *gRPCQueryClient) VStream(ctx context.Context, target *querypb.Target, position string, filter *binlogdatapb.Filter, send func([]*binlogdatapb.VEvent) error) error { + stream, err := func() (queryservicepb.Query_VStreamClient, error) { + conn.mu.RLock() + defer conn.mu.RUnlock() + if conn.cc == nil { + return nil, tabletconn.ConnClosed + } + + req := &binlogdatapb.VStreamRequest{ + Target: target, + EffectiveCallerId: callerid.EffectiveCallerIDFromContext(ctx), + ImmediateCallerId: callerid.ImmediateCallerIDFromContext(ctx), + Position: position, + Filter: filter, + } + stream, err := conn.c.VStream(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 nil + default: + } + if err := send(r.Events); err != nil { + if err == io.EOF { + return nil + } + return err + } + } +} + // HandlePanic is a no-op. func (conn *gRPCQueryClient) HandlePanic(err *error) { } diff --git a/go/vt/vttablet/queryservice/queryservice.go b/go/vt/vttablet/queryservice/queryservice.go index 225912ab26f..4f3204fc800 100644 --- a/go/vt/vttablet/queryservice/queryservice.go +++ b/go/vt/vttablet/queryservice/queryservice.go @@ -25,6 +25,7 @@ import ( "vitess.io/vitess/go/sqltypes" + binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" querypb "vitess.io/vitess/go/vt/proto/query" ) @@ -99,6 +100,9 @@ type QueryService interface { // UpdateStream streams updates from the provided position or timestamp. UpdateStream(ctx context.Context, target *querypb.Target, position string, timestamp int64, callback func(*querypb.StreamEvent) error) error + // VStream streams VReplication events based on the specified filter. + VStream(ctx context.Context, target *querypb.Target, startPos string, filter *binlogdatapb.Filter, send func([]*binlogdatapb.VEvent) 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 0ba474dff63..611c0630711 100644 --- a/go/vt/vttablet/queryservice/wrapped.go +++ b/go/vt/vttablet/queryservice/wrapped.go @@ -22,6 +22,7 @@ import ( "vitess.io/vitess/go/sqltypes" "vitess.io/vitess/go/vt/vterrors" + binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" querypb "vitess.io/vitess/go/vt/proto/query" vtrpcpb "vitess.io/vitess/go/vt/proto/vtrpc" ) @@ -250,6 +251,13 @@ func (ws *wrappedService) UpdateStream(ctx context.Context, target *querypb.Targ }) } +func (ws *wrappedService) VStream(ctx context.Context, target *querypb.Target, startPos string, filter *binlogdatapb.Filter, send func([]*binlogdatapb.VEvent) error) error { + return ws.wrapper(ctx, target, ws.impl, "UpdateStream", false, func(ctx context.Context, target *querypb.Target, conn QueryService) (error, bool) { + innerErr := conn.VStream(ctx, target, startPos, filter, send) + return innerErr, canRetry(ctx, 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) (error, bool) { innerErr := conn.StreamHealth(ctx, callback) diff --git a/go/vt/vttablet/sandboxconn/sandboxconn.go b/go/vt/vttablet/sandboxconn/sandboxconn.go index dc614c7d2be..a856555098f 100644 --- a/go/vt/vttablet/sandboxconn/sandboxconn.go +++ b/go/vt/vttablet/sandboxconn/sandboxconn.go @@ -27,6 +27,7 @@ import ( "vitess.io/vitess/go/vt/vterrors" "vitess.io/vitess/go/vt/vttablet/queryservice" + binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" querypb "vitess.io/vitess/go/vt/proto/query" topodatapb "vitess.io/vitess/go/vt/proto/topodata" vtrpcpb "vitess.io/vitess/go/vt/proto/vtrpc" @@ -354,7 +355,11 @@ func (sbc *SandboxConn) StreamHealth(ctx context.Context, callback func(*querypb // UpdateStream is part of the QueryService interface. func (sbc *SandboxConn) UpdateStream(ctx context.Context, target *querypb.Target, position string, timestamp int64, callback func(*querypb.StreamEvent) error) error { - // FIXME(alainjobart) implement, use in vtgate tests. + return fmt.Errorf("Not implemented in test") +} + +// VStream is part of the QueryService interface. +func (sbc *SandboxConn) VStream(ctx context.Context, target *querypb.Target, startPos string, filter *binlogdatapb.Filter, send func([]*binlogdatapb.VEvent) error) error { return fmt.Errorf("Not implemented in test") } diff --git a/go/vt/vttablet/tabletconntest/fakequeryservice.go b/go/vt/vttablet/tabletconntest/fakequeryservice.go index 813a48efd3a..f6ebc1e5bdd 100644 --- a/go/vt/vttablet/tabletconntest/fakequeryservice.go +++ b/go/vt/vttablet/tabletconntest/fakequeryservice.go @@ -28,6 +28,7 @@ import ( "vitess.io/vitess/go/sqltypes" "vitess.io/vitess/go/vt/callerid" + binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" querypb "vitess.io/vitess/go/vt/proto/query" topodatapb "vitess.io/vitess/go/vt/proto/topodata" vtrpcpb "vitess.io/vitess/go/vt/proto/vtrpc" @@ -850,6 +851,11 @@ func (f *FakeQueryService) UpdateStream(ctx context.Context, target *querypb.Tar return nil } +// VStream is part of the queryservice.QueryService interface +func (f *FakeQueryService) VStream(ctx context.Context, target *querypb.Target, position string, filter *binlogdatapb.Filter, send func([]*binlogdatapb.VEvent) 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/tabletmanager/vreplication/controller.go b/go/vt/vttablet/tabletmanager/vreplication/controller.go index 784d104c1f8..3379ba39743 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/controller.go +++ b/go/vt/vttablet/tabletmanager/vreplication/controller.go @@ -131,7 +131,7 @@ func (ct *controller) run(ctx context.Context) { return default: } - log.Warningf("stream %v: %v, retrying after %v", ct.id, err, *retryDelay) + log.Errorf("stream %v: %v, retrying after %v", ct.id, err, *retryDelay) time.Sleep(*retryDelay) } } diff --git a/go/vt/vttablet/tabletmanager/vreplication/player_plan.go b/go/vt/vttablet/tabletmanager/vreplication/player_plan.go index f08c59f7e8e..d848b02dcb8 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/player_plan.go +++ b/go/vt/vttablet/tabletmanager/vreplication/player_plan.go @@ -23,6 +23,7 @@ import ( "vitess.io/vitess/go/vt/sqlparser" binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" + querypb "vitess.io/vitess/go/vt/proto/query" ) type playerPlan struct { @@ -31,9 +32,13 @@ type playerPlan struct { } type tablePlan struct { + name string colExprs []*colExpr onInsert insertType updateCols []int + + fields []*querypb.Field + pkCols []*colExpr } func (tp *tablePlan) findCol(name sqlparser.ColIdent) *colExpr { @@ -113,15 +118,16 @@ func buildTablePlan(rule *binlogdatapb.Rule) (*binlogdatapb.Rule, *tablePlan, er if fromTable.IsEmpty() { return nil, nil, fmt.Errorf("unexpected: %v", sqlparser.String(sel)) } - if fromTable.String() != rule.Match { - return nil, nil, fmt.Errorf("unexpected: select expression table %v does not match the table entry name %s", sqlparser.String(fromTable), rule.Match) - } if _, ok := sel.SelectExprs[0].(*sqlparser.StarExpr); ok { if len(sel.SelectExprs) != 1 { return nil, nil, fmt.Errorf("unexpected: %v", sqlparser.String(sel)) } - return rule, nil, nil + sendRule := &binlogdatapb.Rule{ + Match: fromTable.String(), + Filter: rule.Filter, + } + return sendRule, &tablePlan{name: rule.Match}, nil } tplan := &tablePlan{} @@ -158,9 +164,13 @@ func analyzeExpr(selExpr sqlparser.SelectExpr) (sqlparser.SelectExpr, *colExpr, if !ok { return nil, nil, fmt.Errorf("unexpected: %v", sqlparser.String(selExpr)) } + as := aliased.As + if as.IsEmpty() { + as = sqlparser.NewColIdent(sqlparser.String(aliased.Expr)) + } switch expr := aliased.Expr.(type) { case *sqlparser.ColName: - return selExpr, &colExpr{colname: expr.Name}, nil + return selExpr, &colExpr{colname: as}, nil case *sqlparser.FuncExpr: if expr.Distinct || len(expr.Exprs) != 1 { return nil, nil, fmt.Errorf("unsupported: %v", sqlparser.String(expr)) @@ -170,12 +180,12 @@ func analyzeExpr(selExpr sqlparser.SelectExpr) (sqlparser.SelectExpr, *colExpr, } switch fname := expr.Name.Lowered(); fname { case "month", "day", "hour": - return selExpr, &colExpr{colname: aliased.As}, nil + return selExpr, &colExpr{colname: as}, nil case "count": if _, ok := expr.Exprs[0].(*sqlparser.StarExpr); !ok { return nil, nil, fmt.Errorf("only count(*) is supported: %v", sqlparser.String(expr)) } - return nil, &colExpr{colname: aliased.As, op: opCount}, nil + return nil, &colExpr{colname: as, op: opCount}, nil case "sum": aInner, ok := expr.Exprs[0].(*sqlparser.AliasedExpr) if !ok { @@ -185,7 +195,7 @@ func analyzeExpr(selExpr sqlparser.SelectExpr) (sqlparser.SelectExpr, *colExpr, if !ok { return nil, nil, fmt.Errorf("unsupported: %v", sqlparser.String(expr)) } - return &sqlparser.AliasedExpr{Expr: innerCol}, &colExpr{colname: aliased.As, op: opSum}, nil + return &sqlparser.AliasedExpr{Expr: innerCol}, &colExpr{colname: as, op: opSum}, nil default: return nil, nil, fmt.Errorf("unsupported: %v", sqlparser.String(expr)) } diff --git a/go/vt/vttablet/tabletmanager/vreplication/vplayer.go b/go/vt/vttablet/tabletmanager/vreplication/vplayer.go new file mode 100644 index 00000000000..dff3cfa7b77 --- /dev/null +++ b/go/vt/vttablet/tabletmanager/vreplication/vplayer.go @@ -0,0 +1,236 @@ +/* +Copyright 2019 The Vitess Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this 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" + "io" + "time" + + "golang.org/x/net/context" + + "vitess.io/vitess/go/mysql" + "vitess.io/vitess/go/vt/binlog/binlogplayer" + "vitess.io/vitess/go/vt/grpcclient" + "vitess.io/vitess/go/vt/log" + "vitess.io/vitess/go/vt/mysqlctl" + "vitess.io/vitess/go/vt/sqlparser" + "vitess.io/vitess/go/vt/vttablet/tabletconn" + + binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" + querypb "vitess.io/vitess/go/vt/proto/query" + topodatapb "vitess.io/vitess/go/vt/proto/topodata" +) + +type vplayer struct { + id uint32 + filter *binlogdatapb.Filter + sourceTablet *topodatapb.Tablet + stats *binlogplayer.Stats + dbClient binlogplayer.DBClient + mysqld *mysqlctl.Mysqld + + pos mysql.Position + stopPos mysql.Position + pplan *playerPlan + tplans map[string]*tablePlan + + retryDelay time.Duration +} + +func newVStreamer(id uint32, filter *binlogdatapb.Filter, sourceTablet *topodatapb.Tablet, stats *binlogplayer.Stats, dbClient binlogplayer.DBClient, mysqld *mysqlctl.Mysqld) *vplayer { + return &vplayer{ + id: id, + filter: filter, + sourceTablet: sourceTablet, + stats: stats, + dbClient: dbClient, + mysqld: mysqld, + retryDelay: 1 * time.Second, + } +} + +func (vp *vplayer) Play(ctx context.Context) error { + vp.setState(binlogplayer.BlpRunning, "") + if err := vp.play(ctx); err != nil { + msg := err.Error() + vp.stats.History.Add(&binlogplayer.StatsHistoryRecord{ + Time: time.Now(), + Message: msg, + }) + vp.setState(binlogplayer.BlpError, msg) + return err + } + return nil +} + +func (vp *vplayer) play(ctx context.Context) error { + startPos, stopPos, _, _, err := binlogplayer.ReadVRSettings(vp.dbClient, vp.id) + if err != nil { + return fmt.Errorf("error reading VReplication settings: %v", err) + } + vp.pos, err = mysql.DecodePosition(startPos) + if err != nil { + return fmt.Errorf("error decoding start position %v: %v", startPos, err) + } + if stopPos != "" { + vp.stopPos, err = mysql.DecodePosition(stopPos) + if err != nil { + return fmt.Errorf("error decoding stop position %v: %v", stopPos, err) + } + } + if !vp.stopPos.IsZero() { + if vp.pos.AtLeast(vp.stopPos) { + vp.setState(binlogplayer.BlpStopped, fmt.Sprintf("Stop position %v already reached: %v", vp.pos, vp.stopPos)) + return nil + } + } + log.Infof("Starting VReplication player id: %v, startPos: %v, stop: %v, source: %v", vp.id, startPos, vp.stopPos, vp.sourceTablet) + + plan, err := buildPlayerPlan(vp.filter) + if err != nil { + return err + } + + vsClient, err := tabletconn.GetDialer()(vp.sourceTablet, grpcclient.FailFast(false)) + if err != nil { + return fmt.Errorf("error dialing tablet: %v", err) + } + target := &querypb.Target{ + Keyspace: vp.sourceTablet.Keyspace, + Shard: vp.sourceTablet.Shard, + TabletType: vp.sourceTablet.Type, + } + return vsClient.VStream(ctx, target, startPos, plan.vstreamFilter, func(events []*binlogdatapb.VEvent) error { + for _, event := range events { + select { + case <-ctx.Done(): + return io.EOF + default: + } + if err := vp.applyEvent(event); err != nil { + return err + } + } + return nil + }) +} + +func (vp *vplayer) applyEvent(event *binlogdatapb.VEvent) error { + switch event.Type { + case binlogdatapb.VEventType_GTID: + pos, err := mysql.DecodePosition(event.Gtid) + if err != nil { + return err + } + vp.pos = pos + if vp.stopPos.IsZero() { + return nil + } + if !vp.pos.Equal(vp.stopPos) && vp.pos.AtLeast(vp.stopPos) { + return fmt.Errorf("next event position %v exceeds stop pos %v, exiting without applying", vp.pos, vp.stopPos) + } + case binlogdatapb.VEventType_BEGIN: + if err := vp.dbClient.Begin(); err != nil { + return err + } + case binlogdatapb.VEventType_COMMIT: + updatePos := binlogplayer.GenerateUpdatePos(vp.id, vp.pos, time.Now().Unix(), event.Timestamp) + if _, err := vp.dbClient.ExecuteFetch(updatePos, 0); err != nil { + _ = vp.dbClient.Rollback() + return fmt.Errorf("error %v updating position", err) + } + if err := vp.dbClient.Commit(); err != nil { + return err + } + case binlogdatapb.VEventType_ROLLBACK: + // This code is unreachable. It's just here as failsafe. + _ = vp.dbClient.Rollback() + case binlogdatapb.VEventType_FIELD: + if err := vp.updatePlans(event.FieldEvent); err != nil { + return err + } + } + return nil +} + +func (vp *vplayer) setState(state, message string) { + if err := binlogplayer.SetVReplicationState(vp.dbClient, vp.id, state, message); err != nil { + log.Errorf("Error writing state: %s, msg: %s, err: %v", state, message, err) + } +} + +func (vp *vplayer) updatePlans(fieldEvent *binlogdatapb.FieldEvent) error { + prelim := vp.pplan.tablePlans[fieldEvent.TableName] + tplan := &tablePlan{ + name: fieldEvent.TableName, + } + if prelim != nil { + *tplan = *prelim + } + tplan.fields = fieldEvent.Fields + + if tplan.colExprs == nil { + tplan.colExprs = make([]*colExpr, len(tplan.fields)) + for i, field := range tplan.fields { + tplan.colExprs[i] = &colExpr{ + colname: sqlparser.NewColIdent(field.Name), + colnum: i, + } + } + } else { + if len(tplan.fields) != len(tplan.colExprs) { + return fmt.Errorf("columns received from vreplication: %v, do not match expected: %v", tplan.fields, tplan.colExprs) + } + for i, field := range tplan.fields { + if tplan.colExprs[i].colname.EqualString(field.Name) { + return fmt.Errorf("column name from vreplication field %d: %s, does not match expected: %s", i, field.Name, tplan.colExprs[i].colname) + } + } + } + + qr, err := vp.dbClient.ExecuteFetch("select database()", 1) + if err != nil { + return err + } + if len(qr.Rows) == 0 || len(qr.Rows[0]) == 0 { + return fmt.Errorf("unexpected result from 'select database()': %v", qr) + } + dbname := qr.Rows[0][0].ToString() + pkcols, err := vp.mysqld.GetPrimaryKeyColumns(dbname, tplan.name) + if err != nil { + return fmt.Errorf("error fetching pk columns for %s: %v", tplan.name, err) + } + for _, pkcol := range pkcols { + found := false + for i, cExpr := range tplan.colExprs { + if cExpr.colname.EqualString(pkcol) { + found = true + tplan.pkCols = append(tplan.pkCols, &colExpr{ + colname: cExpr.colname, + colnum: i, + }) + break + } + } + if !found { + return fmt.Errorf("primary key column %s missing from select list for table %s", pkcol, tplan.name) + } + } + vp.tplans[fieldEvent.TableName] = tplan + return nil +} diff --git a/go/vt/vttablet/tabletserver/tabletserver.go b/go/vt/vttablet/tabletserver/tabletserver.go index 51b7c0bf907..eb707aa1031 100644 --- a/go/vt/vttablet/tabletserver/tabletserver.go +++ b/go/vt/vttablet/tabletserver/tabletserver.go @@ -1274,7 +1274,7 @@ func (tsv *TabletServer) execDML(ctx context.Context, target *querypb.Target, qu } // VStream streams VReplication events. -func (tsv *TabletServer) VStream(ctx context.Context, target *querypb.Target, startPos mysql.Position, filter *binlogdatapb.Filter, send func([]*binlogdatapb.VEvent) error) error { +func (tsv *TabletServer) VStream(ctx context.Context, target *querypb.Target, startPos string, filter *binlogdatapb.Filter, send func([]*binlogdatapb.VEvent) error) error { // This code is partially duplicated from startRequest. This is because // is allowed even if the tablet is in non-serving state. err := func() error { diff --git a/go/vt/vttablet/tabletserver/vstreamer/engine.go b/go/vt/vttablet/tabletserver/vstreamer/engine.go index 61cb603976c..9e0e014bd95 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/engine.go +++ b/go/vt/vttablet/tabletserver/vstreamer/engine.go @@ -136,7 +136,7 @@ func (vse *Engine) vschema() *vindexes.KeyspaceSchema { } // Stream starts a new stream. -func (vse *Engine) Stream(ctx context.Context, startPos mysql.Position, filter *binlogdatapb.Filter, send func([]*binlogdatapb.VEvent) error) error { +func (vse *Engine) Stream(ctx context.Context, startPos string, filter *binlogdatapb.Filter, send func([]*binlogdatapb.VEvent) error) error { // Ensure kschema is initialized and the watcher is started. // Starting of the watcher has to be delayed till the first call to Stream // because this overhead should be incurred only if someone uses this feature. diff --git a/go/vt/vttablet/tabletserver/vstreamer/planbuilder.go b/go/vt/vttablet/tabletserver/vstreamer/planbuilder.go index 432251f8cba..04e430bcb2b 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/planbuilder.go +++ b/go/vt/vttablet/tabletserver/vstreamer/planbuilder.go @@ -298,13 +298,17 @@ func analyzeExpr(ti *Table, selExpr sqlparser.SelectExpr) (cExpr ColExpr, err er if !ok { return ColExpr{}, fmt.Errorf("unexpected: %v", sqlparser.String(selExpr)) } + as := aliased.As + if as.IsEmpty() { + as = sqlparser.NewColIdent(sqlparser.String(aliased.Expr)) + } switch expr := aliased.Expr.(type) { case *sqlparser.ColName: colnum, err := findColumn(ti, expr.Name) if err != nil { return ColExpr{}, err } - return ColExpr{ColNum: colnum, Alias: expr.Name, Type: ti.Columns[colnum].Type}, nil + return ColExpr{ColNum: colnum, Alias: as, Type: ti.Columns[colnum].Type}, nil case *sqlparser.FuncExpr: if expr.Distinct || len(expr.Exprs) != 1 { return ColExpr{}, fmt.Errorf("unsupported: %v", sqlparser.String(expr)) @@ -319,10 +323,6 @@ func analyzeExpr(ti *Table, selExpr sqlparser.SelectExpr) (cExpr ColExpr, err er if !ok { return ColExpr{}, fmt.Errorf("unsupported: %v", sqlparser.String(expr)) } - as := aliased.As - if as.IsEmpty() { - as = sqlparser.NewColIdent(sqlparser.String(expr)) - } colnum, err := findColumn(ti, innerCol.Name) if err != nil { return ColExpr{}, err diff --git a/go/vt/vttablet/tabletserver/vstreamer/vstreamer.go b/go/vt/vttablet/tabletserver/vstreamer/vstreamer.go index e2b4f74c213..ade2ced8c32 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/vstreamer.go +++ b/go/vt/vttablet/tabletserver/vstreamer/vstreamer.go @@ -41,7 +41,7 @@ type vstreamer struct { cp *mysql.ConnParams se *schema.Engine - startPos mysql.Position + startPos string filter *binlogdatapb.Filter send func([]*binlogdatapb.VEvent) error @@ -55,7 +55,7 @@ type vstreamer struct { pos mysql.Position } -func newVStreamer(ctx context.Context, cp *mysql.ConnParams, se *schema.Engine, startPos mysql.Position, filter *binlogdatapb.Filter, kschema *vindexes.KeyspaceSchema, send func([]*binlogdatapb.VEvent) error) *vstreamer { +func newVStreamer(ctx context.Context, cp *mysql.ConnParams, se *schema.Engine, startPos string, filter *binlogdatapb.Filter, kschema *vindexes.KeyspaceSchema, send func([]*binlogdatapb.VEvent) error) *vstreamer { ctx, cancel := context.WithCancel(ctx) return &vstreamer{ ctx: ctx, @@ -88,7 +88,12 @@ func (vs *vstreamer) Cancel() { // Stream runs a single-threaded loop. func (vs *vstreamer) Stream() error { defer vs.cancel() - vs.pos = vs.startPos + + pos, err := mysql.DecodePosition(vs.startPos) + if err != nil { + return err + } + vs.pos = pos // Ensure se is Open. If vttablet came up in a non_serving role, // the schema engine may not have been initialized. @@ -375,6 +380,9 @@ func (vs *vstreamer) parseEvent(ev mysql.BinlogEvent) ([]*binlogdatapb.VEvent, e }) } } + for _, vevent := range vevents { + vevent.Timestamp = int64(ev.Timestamp()) + } return vevents, nil } diff --git a/go/vt/vttablet/tabletserver/vstreamer/vstreamer_test.go b/go/vt/vttablet/tabletserver/vstreamer/vstreamer_test.go index 9a9ff697b07..55e68399286 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/vstreamer_test.go +++ b/go/vt/vttablet/tabletserver/vstreamer/vstreamer_test.go @@ -374,10 +374,7 @@ func TestDDLAddColumn(t *testing.T) { }) // Record position before the next few statements. - pos, err := mysqld.MasterPosition() - if err != nil { - t.Fatal(err) - } + pos := masterPosition(t) execStatements(t, []string{ "begin", "insert into ddl_test1 values(1, 'aaa')", @@ -450,10 +447,7 @@ func TestDDLDropColumn(t *testing.T) { defer execStatement(t, "drop table ddl_test2") // Record position before the next few statements. - pos, err := mysqld.MasterPosition() - if err != nil { - t.Fatal(err) - } + pos := masterPosition(t) execStatements(t, []string{ "insert into ddl_test2 values(1, 'aaa', 'ccc')", // Adding columns is allowed. @@ -471,7 +465,7 @@ func TestDDLDropColumn(t *testing.T) { } }() defer close(ch) - err = vstream(ctx, t, pos, nil, ch) + err := vstream(ctx, t, pos, nil, ch) want := "cannot determine table columns" if err == nil || !strings.Contains(err.Error(), want) { t.Errorf("err: %v, must contain %s", err, want) @@ -795,10 +789,7 @@ func TestMinimalMode(t *testing.T) { engine.se.Reload(context.Background()) // Record position before the next few statements. - pos, err := mysqld.MasterPosition() - if err != nil { - t.Fatal(err) - } + pos := masterPosition(t) execStatements(t, []string{ "set @@session.binlog_row_image='minimal'", "update t1 set val1='bbb' where id=1", @@ -815,7 +806,7 @@ func TestMinimalMode(t *testing.T) { } }() defer close(ch) - err = vstream(ctx, t, pos, nil, ch) + err := vstream(ctx, t, pos, nil, ch) want := "partial row image encountered" if err == nil || !strings.Contains(err.Error(), want) { t.Errorf("err: %v, must contain '%s'", err, want) @@ -837,10 +828,7 @@ func TestStatementMode(t *testing.T) { engine.se.Reload(context.Background()) // Record position before the next few statements. - pos, err := mysqld.MasterPosition() - if err != nil { - t.Fatal(err) - } + pos := masterPosition(t) execStatements(t, []string{ "set @@session.binlog_format='statement'", "update t1 set val1='bbb' where id=1", @@ -857,7 +845,7 @@ func TestStatementMode(t *testing.T) { } }() defer close(ch) - err = vstream(ctx, t, pos, nil, ch) + err := vstream(ctx, t, pos, nil, ch) want := "unexpected statement type" if err == nil || !strings.Contains(err.Error(), want) { t.Errorf("err: %v, must contain '%s'", err, want) @@ -920,6 +908,10 @@ func expectLog(ctx context.Context, t *testing.T, input interface{}, ch <-chan [ t.Fatalf("%v (%d): event: %v, want commit", input, i, evs[i]) } default: + if evs[i].Timestamp == 0 { + t.Fatalf("evs[%d].Timestamp: 0, want non-zero", i) + } + evs[i].Timestamp = 0 if got := fmt.Sprintf("%v", evs[i]); got != want { t.Fatalf("%v (%d): event:\n%q, want\n%q", input, i, got, want) } @@ -929,10 +921,7 @@ 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, err := mysqld.MasterPosition() - if err != nil { - t.Fatal(err) - } + pos := masterPosition(t) ch := make(chan []*binlogdatapb.VEvent) go func() { @@ -944,7 +933,7 @@ func startStream(ctx context.Context, t *testing.T, filter *binlogdatapb.Filter) return ch } -func vstream(ctx context.Context, t *testing.T, pos mysql.Position, filter *binlogdatapb.Filter, ch chan []*binlogdatapb.VEvent) error { +func vstream(ctx context.Context, t *testing.T, pos string, filter *binlogdatapb.Filter, ch chan []*binlogdatapb.VEvent) error { if filter == nil { filter = &binlogdatapb.Filter{ Rules: []*binlogdatapb.Rule{{ @@ -976,3 +965,12 @@ func execStatements(t *testing.T, queries []string) { t.Fatal(err) } } + +func masterPosition(t *testing.T) string { + t.Helper() + pos, err := mysqld.MasterPosition() + if err != nil { + t.Fatal(err) + } + return mysql.EncodePosition(pos) +} diff --git a/proto/binlogdata.proto b/proto/binlogdata.proto index 8c758d9895f..83f5abfca49 100644 --- a/proto/binlogdata.proto +++ b/proto/binlogdata.proto @@ -23,6 +23,7 @@ option go_package = "vitess.io/vitess/go/vt/proto/binlogdata"; package binlogdata; +import "vtrpc.proto"; import "query.proto"; import "topodata.proto"; @@ -195,19 +196,24 @@ message FieldEvent { // VEvent represents a vstream event message VEvent { VEventType type = 1; - string gtid = 2; - string ddl = 3; - RowEvent row_event = 4; - FieldEvent field_event = 5; + int64 timestamp = 2; + string gtid = 3; + string ddl = 4; + RowEvent row_event = 5; + FieldEvent field_event = 6; } // VStreamRequest is the payload for VStream message VStreamRequest { - string position = 1; - Filter filter = 2; + vtrpc.CallerID effective_caller_id = 1; + query.VTGateCallerID immediate_caller_id = 2; + query.Target target = 3; + + string position = 4; + Filter filter = 5; } // VStreamResponse is the response from VStream message VStreamResponse { - repeated VEvent event = 1; + repeated VEvent events = 1; } diff --git a/proto/queryservice.proto b/proto/queryservice.proto index a6a7074c9dc..897cbf3f034 100644 --- a/proto/queryservice.proto +++ b/proto/queryservice.proto @@ -22,6 +22,7 @@ package queryservice; option go_package = "vitess.io/vitess/go/vt/proto/queryservice"; import "query.proto"; +import "binlogdata.proto"; // Query defines the tablet query service, implemented by vttablet. service Query { @@ -94,4 +95,7 @@ service Query { // UpdateStream asks the server to return a stream of the updates that have been applied to its database. rpc UpdateStream(query.UpdateStreamRequest) returns (stream query.UpdateStreamResponse) {}; + + // VStream streams vreplication events. + rpc VStream(binlogdata.VStreamRequest) returns (stream binlogdata.VStreamResponse) {}; } diff --git a/py/vtproto/binlogdata_pb2.py b/py/vtproto/binlogdata_pb2.py index d9d8e896d92..0278b0f83f0 100644 --- a/py/vtproto/binlogdata_pb2.py +++ b/py/vtproto/binlogdata_pb2.py @@ -13,6 +13,7 @@ _sym_db = _symbol_database.Default() +import vtrpc_pb2 as vtrpc__pb2 import query_pb2 as query__pb2 import topodata_pb2 as topodata__pb2 @@ -22,9 +23,9 @@ 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\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\"\xb5\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\"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\"\x9f\x01\n\x06VEvent\x12$\n\x04type\x18\x01 \x01(\x0e\x32\x16.binlogdata.VEventType\x12\x0c\n\x04gtid\x18\x02 \x01(\t\x12\x0b\n\x03\x64\x64l\x18\x03 \x01(\t\x12\'\n\trow_event\x18\x04 \x01(\x0b\x32\x14.binlogdata.RowEvent\x12+\n\x0b\x66ield_event\x18\x05 \x01(\x0b\x32\x16.binlogdata.FieldEvent\"F\n\x0eVStreamRequest\x12\x10\n\x08position\x18\x01 \x01(\t\x12\"\n\x06\x66ilter\x18\x02 \x01(\x0b\x32\x12.binlogdata.Filter\"4\n\x0fVStreamResponse\x12!\n\x05\x65vent\x18\x01 \x03(\x0b\x32\x12.binlogdata.VEvent*\xaa\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\rB)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\")\n\x06\x46ilter\x12\x1f\n\x05rules\x18\x01 \x03(\x0b\x32\x10.binlogdata.Rule\"\xb5\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\"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\"\xb2\x01\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\"\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*\xaa\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\rB)Z\'vitess.io/vitess/go/vt/proto/binlogdatab\x06proto3') , - dependencies=[query__pb2.DESCRIPTOR,topodata__pb2.DESCRIPTOR,]) + dependencies=[vtrpc__pb2.DESCRIPTOR,query__pb2.DESCRIPTOR,topodata__pb2.DESCRIPTOR,]) _VEVENTTYPE = _descriptor.EnumDescriptor( name='VEventType', @@ -91,8 +92,8 @@ ], containing_type=None, serialized_options=None, - serialized_start=1704, - serialized_end=1874, + serialized_start=1867, + serialized_end=2037, ) _sym_db.RegisterEnumDescriptor(_VEVENTTYPE) @@ -162,8 +163,8 @@ ], containing_type=None, serialized_options=None, - serialized_start=375, - serialized_end=544, + serialized_start=388, + serialized_end=557, ) _sym_db.RegisterEnumDescriptor(_BINLOGTRANSACTION_STATEMENT_CATEGORY) @@ -208,8 +209,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=61, - serialized_end=116, + serialized_start=74, + serialized_end=129, ) @@ -254,8 +255,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=242, - serialized_end=544, + serialized_start=255, + serialized_end=557, ) _BINLOGTRANSACTION = _descriptor.Descriptor( @@ -291,8 +292,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=119, - serialized_end=556, + serialized_start=132, + serialized_end=569, ) @@ -336,8 +337,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=558, - serialized_end=676, + serialized_start=571, + serialized_end=689, ) @@ -367,8 +368,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=678, - serialized_end=761, + serialized_start=691, + serialized_end=774, ) @@ -412,8 +413,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=763, - serialized_end=856, + serialized_start=776, + serialized_end=869, ) @@ -443,8 +444,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=858, - serialized_end=939, + serialized_start=871, + serialized_end=952, ) @@ -481,8 +482,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=941, - serialized_end=978, + serialized_start=954, + serialized_end=991, ) @@ -512,8 +513,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=980, - serialized_end=1021, + serialized_start=993, + serialized_end=1034, ) @@ -578,8 +579,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=1024, - serialized_end=1205, + serialized_start=1037, + serialized_end=1218, ) @@ -616,8 +617,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=1207, - serialized_end=1273, + serialized_start=1220, + serialized_end=1286, ) @@ -654,8 +655,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=1275, - serialized_end=1349, + serialized_start=1288, + serialized_end=1362, ) @@ -692,8 +693,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=1351, - serialized_end=1413, + serialized_start=1364, + serialized_end=1426, ) @@ -712,33 +713,40 @@ is_extension=False, extension_scope=None, serialized_options=None, file=DESCRIPTOR), _descriptor.FieldDescriptor( - name='gtid', full_name='binlogdata.VEvent.gtid', index=1, - number=2, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), + name='timestamp', full_name='binlogdata.VEvent.timestamp', index=1, + number=2, 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='ddl', full_name='binlogdata.VEvent.ddl', index=2, + name='gtid', full_name='binlogdata.VEvent.gtid', 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, serialized_options=None, file=DESCRIPTOR), _descriptor.FieldDescriptor( - name='row_event', full_name='binlogdata.VEvent.row_event', index=3, - number=4, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, + name='ddl', full_name='binlogdata.VEvent.ddl', 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), _descriptor.FieldDescriptor( - name='field_event', full_name='binlogdata.VEvent.field_event', index=4, + name='row_event', full_name='binlogdata.VEvent.row_event', index=4, number=5, 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='field_event', full_name='binlogdata.VEvent.field_event', index=5, + number=6, 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=[ ], @@ -751,8 +759,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=1416, - serialized_end=1575, + serialized_start=1429, + serialized_end=1607, ) @@ -764,19 +772,40 @@ containing_type=None, fields=[ _descriptor.FieldDescriptor( - name='position', full_name='binlogdata.VStreamRequest.position', index=0, - number=1, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), + name='effective_caller_id', full_name='binlogdata.VStreamRequest.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='filter', full_name='binlogdata.VStreamRequest.filter', index=1, + name='immediate_caller_id', full_name='binlogdata.VStreamRequest.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.VStreamRequest.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='position', full_name='binlogdata.VStreamRequest.position', 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), + _descriptor.FieldDescriptor( + name='filter', full_name='binlogdata.VStreamRequest.filter', index=4, + number=5, 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=[ ], @@ -789,8 +818,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=1577, - serialized_end=1647, + serialized_start=1610, + serialized_end=1809, ) @@ -802,7 +831,7 @@ containing_type=None, fields=[ _descriptor.FieldDescriptor( - name='event', full_name='binlogdata.VStreamResponse.event', index=0, + name='events', full_name='binlogdata.VStreamResponse.events', 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, @@ -820,8 +849,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=1649, - serialized_end=1701, + serialized_start=1811, + serialized_end=1864, ) _BINLOGTRANSACTION_STATEMENT.fields_by_name['category'].enum_type = _BINLOGTRANSACTION_STATEMENT_CATEGORY @@ -846,8 +875,11 @@ _VEVENT.fields_by_name['type'].enum_type = _VEVENTTYPE _VEVENT.fields_by_name['row_event'].message_type = _ROWEVENT _VEVENT.fields_by_name['field_event'].message_type = _FIELDEVENT +_VSTREAMREQUEST.fields_by_name['effective_caller_id'].message_type = vtrpc__pb2._CALLERID +_VSTREAMREQUEST.fields_by_name['immediate_caller_id'].message_type = query__pb2._VTGATECALLERID +_VSTREAMREQUEST.fields_by_name['target'].message_type = query__pb2._TARGET _VSTREAMREQUEST.fields_by_name['filter'].message_type = _FILTER -_VSTREAMRESPONSE.fields_by_name['event'].message_type = _VEVENT +_VSTREAMRESPONSE.fields_by_name['events'].message_type = _VEVENT DESCRIPTOR.message_types_by_name['Charset'] = _CHARSET DESCRIPTOR.message_types_by_name['BinlogTransaction'] = _BINLOGTRANSACTION DESCRIPTOR.message_types_by_name['StreamKeyRangeRequest'] = _STREAMKEYRANGEREQUEST diff --git a/py/vtproto/queryservice_pb2.py b/py/vtproto/queryservice_pb2.py index 467e8b4dd44..3c443df129b 100644 --- a/py/vtproto/queryservice_pb2.py +++ b/py/vtproto/queryservice_pb2.py @@ -7,39 +7,39 @@ 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 query_pb2 as query__pb2 +import binlogdata_pb2 as binlogdata__pb2 DESCRIPTOR = _descriptor.FileDescriptor( name='queryservice.proto', package='queryservice', syntax='proto3', - serialized_pb=_b('\n\x12queryservice.proto\x12\x0cqueryservice\x1a\x0bquery.proto2\xa7\x0c\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\x42+Z)vitess.io/vitess/go/vt/proto/queryserviceb\x06proto3') + 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\xef\x0c\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\x42+Z)vitess.io/vitess/go/vt/proto/queryserviceb\x06proto3') , - dependencies=[query__pb2.DESCRIPTOR,]) + dependencies=[query__pb2.DESCRIPTOR,binlogdata__pb2.DESCRIPTOR,]) _sym_db.RegisterFileDescriptor(DESCRIPTOR) -DESCRIPTOR.has_options = True -DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), _b('Z)vitess.io/vitess/go/vt/proto/queryservice')) +DESCRIPTOR._options = None _QUERY = _descriptor.ServiceDescriptor( name='Query', full_name='queryservice.Query', file=DESCRIPTOR, index=0, - options=None, - serialized_start=50, - serialized_end=1625, + serialized_options=None, + serialized_start=68, + serialized_end=1715, methods=[ _descriptor.MethodDescriptor( name='Execute', @@ -48,7 +48,7 @@ containing_service=None, input_type=query__pb2._EXECUTEREQUEST, output_type=query__pb2._EXECUTERESPONSE, - options=None, + serialized_options=None, ), _descriptor.MethodDescriptor( name='ExecuteBatch', @@ -57,7 +57,7 @@ containing_service=None, input_type=query__pb2._EXECUTEBATCHREQUEST, output_type=query__pb2._EXECUTEBATCHRESPONSE, - options=None, + serialized_options=None, ), _descriptor.MethodDescriptor( name='StreamExecute', @@ -66,7 +66,7 @@ containing_service=None, input_type=query__pb2._STREAMEXECUTEREQUEST, output_type=query__pb2._STREAMEXECUTERESPONSE, - options=None, + serialized_options=None, ), _descriptor.MethodDescriptor( name='Begin', @@ -75,7 +75,7 @@ containing_service=None, input_type=query__pb2._BEGINREQUEST, output_type=query__pb2._BEGINRESPONSE, - options=None, + serialized_options=None, ), _descriptor.MethodDescriptor( name='Commit', @@ -84,7 +84,7 @@ containing_service=None, input_type=query__pb2._COMMITREQUEST, output_type=query__pb2._COMMITRESPONSE, - options=None, + serialized_options=None, ), _descriptor.MethodDescriptor( name='Rollback', @@ -93,7 +93,7 @@ containing_service=None, input_type=query__pb2._ROLLBACKREQUEST, output_type=query__pb2._ROLLBACKRESPONSE, - options=None, + serialized_options=None, ), _descriptor.MethodDescriptor( name='Prepare', @@ -102,7 +102,7 @@ containing_service=None, input_type=query__pb2._PREPAREREQUEST, output_type=query__pb2._PREPARERESPONSE, - options=None, + serialized_options=None, ), _descriptor.MethodDescriptor( name='CommitPrepared', @@ -111,7 +111,7 @@ containing_service=None, input_type=query__pb2._COMMITPREPAREDREQUEST, output_type=query__pb2._COMMITPREPAREDRESPONSE, - options=None, + serialized_options=None, ), _descriptor.MethodDescriptor( name='RollbackPrepared', @@ -120,7 +120,7 @@ containing_service=None, input_type=query__pb2._ROLLBACKPREPAREDREQUEST, output_type=query__pb2._ROLLBACKPREPAREDRESPONSE, - options=None, + serialized_options=None, ), _descriptor.MethodDescriptor( name='CreateTransaction', @@ -129,7 +129,7 @@ containing_service=None, input_type=query__pb2._CREATETRANSACTIONREQUEST, output_type=query__pb2._CREATETRANSACTIONRESPONSE, - options=None, + serialized_options=None, ), _descriptor.MethodDescriptor( name='StartCommit', @@ -138,7 +138,7 @@ containing_service=None, input_type=query__pb2._STARTCOMMITREQUEST, output_type=query__pb2._STARTCOMMITRESPONSE, - options=None, + serialized_options=None, ), _descriptor.MethodDescriptor( name='SetRollback', @@ -147,7 +147,7 @@ containing_service=None, input_type=query__pb2._SETROLLBACKREQUEST, output_type=query__pb2._SETROLLBACKRESPONSE, - options=None, + serialized_options=None, ), _descriptor.MethodDescriptor( name='ConcludeTransaction', @@ -156,7 +156,7 @@ containing_service=None, input_type=query__pb2._CONCLUDETRANSACTIONREQUEST, output_type=query__pb2._CONCLUDETRANSACTIONRESPONSE, - options=None, + serialized_options=None, ), _descriptor.MethodDescriptor( name='ReadTransaction', @@ -165,7 +165,7 @@ containing_service=None, input_type=query__pb2._READTRANSACTIONREQUEST, output_type=query__pb2._READTRANSACTIONRESPONSE, - options=None, + serialized_options=None, ), _descriptor.MethodDescriptor( name='BeginExecute', @@ -174,7 +174,7 @@ containing_service=None, input_type=query__pb2._BEGINEXECUTEREQUEST, output_type=query__pb2._BEGINEXECUTERESPONSE, - options=None, + serialized_options=None, ), _descriptor.MethodDescriptor( name='BeginExecuteBatch', @@ -183,7 +183,7 @@ containing_service=None, input_type=query__pb2._BEGINEXECUTEBATCHREQUEST, output_type=query__pb2._BEGINEXECUTEBATCHRESPONSE, - options=None, + serialized_options=None, ), _descriptor.MethodDescriptor( name='MessageStream', @@ -192,7 +192,7 @@ containing_service=None, input_type=query__pb2._MESSAGESTREAMREQUEST, output_type=query__pb2._MESSAGESTREAMRESPONSE, - options=None, + serialized_options=None, ), _descriptor.MethodDescriptor( name='MessageAck', @@ -201,7 +201,7 @@ containing_service=None, input_type=query__pb2._MESSAGEACKREQUEST, output_type=query__pb2._MESSAGEACKRESPONSE, - options=None, + serialized_options=None, ), _descriptor.MethodDescriptor( name='SplitQuery', @@ -210,7 +210,7 @@ containing_service=None, input_type=query__pb2._SPLITQUERYREQUEST, output_type=query__pb2._SPLITQUERYRESPONSE, - options=None, + serialized_options=None, ), _descriptor.MethodDescriptor( name='StreamHealth', @@ -219,7 +219,7 @@ containing_service=None, input_type=query__pb2._STREAMHEALTHREQUEST, output_type=query__pb2._STREAMHEALTHRESPONSE, - options=None, + serialized_options=None, ), _descriptor.MethodDescriptor( name='UpdateStream', @@ -228,7 +228,16 @@ containing_service=None, input_type=query__pb2._UPDATESTREAMREQUEST, output_type=query__pb2._UPDATESTREAMRESPONSE, - options=None, + serialized_options=None, + ), + _descriptor.MethodDescriptor( + name='VStream', + full_name='queryservice.Query.VStream', + index=21, + containing_service=None, + input_type=binlogdata__pb2._VSTREAMREQUEST, + output_type=binlogdata__pb2._VSTREAMRESPONSE, + serialized_options=None, ), ]) _sym_db.RegisterServiceDescriptor(_QUERY) diff --git a/py/vtproto/queryservice_pb2_grpc.py b/py/vtproto/queryservice_pb2_grpc.py index 3fc203d463e..61adf9b42bd 100644 --- a/py/vtproto/queryservice_pb2_grpc.py +++ b/py/vtproto/queryservice_pb2_grpc.py @@ -1,6 +1,7 @@ # Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! import grpc +import binlogdata_pb2 as binlogdata__pb2 import query_pb2 as query__pb2 @@ -119,6 +120,11 @@ def __init__(self, channel): request_serializer=query__pb2.UpdateStreamRequest.SerializeToString, response_deserializer=query__pb2.UpdateStreamResponse.FromString, ) + self.VStream = channel.unary_stream( + '/queryservice.Query/VStream', + request_serializer=binlogdata__pb2.VStreamRequest.SerializeToString, + response_deserializer=binlogdata__pb2.VStreamResponse.FromString, + ) class QueryServicer(object): @@ -279,6 +285,13 @@ def UpdateStream(self, request, context): context.set_details('Method not implemented!') raise NotImplementedError('Method not implemented!') + def VStream(self, request, context): + """VStream streams vreplication events. + """ + 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 = { @@ -387,6 +400,11 @@ def add_QueryServicer_to_server(servicer, server): request_deserializer=query__pb2.UpdateStreamRequest.FromString, response_serializer=query__pb2.UpdateStreamResponse.SerializeToString, ), + 'VStream': grpc.unary_stream_rpc_method_handler( + servicer.VStream, + request_deserializer=binlogdata__pb2.VStreamRequest.FromString, + response_serializer=binlogdata__pb2.VStreamResponse.SerializeToString, + ), } generic_handler = grpc.method_handlers_generic_handler( 'queryservice.Query', rpc_method_handlers) From 39e974899d614c2c398e5d73c1b4347d5a4ed4cc Mon Sep 17 00:00:00 2001 From: Sugu Sougoumarane Date: Tue, 8 Jan 2019 21:58:57 -0800 Subject: [PATCH 060/115] vreplication: vplayer basic functionality done Signed-off-by: Sugu Sougoumarane --- go/vt/proto/binlogdata/binlogdata.pb.go | 237 +++++++++++------- .../tabletmanager/vreplication/player_plan.go | 24 +- .../tabletmanager/vreplication/vplayer.go | 232 ++++++++++++++++- proto/binlogdata.proto | 11 + py/vtproto/binlogdata_pb2.py | 76 ++++-- 5 files changed, 448 insertions(+), 132 deletions(-) diff --git a/go/vt/proto/binlogdata/binlogdata.pb.go b/go/vt/proto/binlogdata/binlogdata.pb.go index 0cddb2d2342..2683321fd16 100644 --- a/go/vt/proto/binlogdata/binlogdata.pb.go +++ b/go/vt/proto/binlogdata/binlogdata.pb.go @@ -21,6 +21,36 @@ var _ = math.Inf // proto package needs to be updated. const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package +// OnDDLAction lists the possible actions for DDLs. +type OnDDLAction int32 + +const ( + OnDDLAction_IGNORE OnDDLAction = 0 + OnDDLAction_STOP OnDDLAction = 1 + OnDDLAction_EXEC OnDDLAction = 2 + OnDDLAction_EXEC_IGNORE OnDDLAction = 3 +) + +var OnDDLAction_name = map[int32]string{ + 0: "IGNORE", + 1: "STOP", + 2: "EXEC", + 3: "EXEC_IGNORE", +} +var OnDDLAction_value = map[string]int32{ + "IGNORE": 0, + "STOP": 1, + "EXEC": 2, + "EXEC_IGNORE": 3, +} + +func (x OnDDLAction) String() string { + return proto.EnumName(OnDDLAction_name, int32(x)) +} +func (OnDDLAction) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_binlogdata_6d214635eb8c538c, []int{0} +} + // VEventType enumerates the event types. // This list is comprehensive. Many of these types // will not be encountered in RBR mode. @@ -80,7 +110,7 @@ func (x VEventType) String() string { return proto.EnumName(VEventType_name, int32(x)) } func (VEventType) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_binlogdata_602eda7964a9642b, []int{0} + return fileDescriptor_binlogdata_6d214635eb8c538c, []int{1} } type BinlogTransaction_Statement_Category int32 @@ -128,7 +158,7 @@ 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_602eda7964a9642b, []int{1, 0, 0} + return fileDescriptor_binlogdata_6d214635eb8c538c, []int{1, 0, 0} } // Charset is the per-statement charset info from a QUERY_EVENT binlog entry. @@ -148,7 +178,7 @@ 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_602eda7964a9642b, []int{0} + return fileDescriptor_binlogdata_6d214635eb8c538c, []int{0} } func (m *Charset) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Charset.Unmarshal(m, b) @@ -205,7 +235,7 @@ 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_602eda7964a9642b, []int{1} + return fileDescriptor_binlogdata_6d214635eb8c538c, []int{1} } func (m *BinlogTransaction) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_BinlogTransaction.Unmarshal(m, b) @@ -255,7 +285,7 @@ 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_602eda7964a9642b, []int{1, 0} + return fileDescriptor_binlogdata_6d214635eb8c538c, []int{1, 0} } func (m *BinlogTransaction_Statement) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_BinlogTransaction_Statement.Unmarshal(m, b) @@ -313,7 +343,7 @@ 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_602eda7964a9642b, []int{2} + return fileDescriptor_binlogdata_6d214635eb8c538c, []int{2} } func (m *StreamKeyRangeRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_StreamKeyRangeRequest.Unmarshal(m, b) @@ -366,7 +396,7 @@ 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_602eda7964a9642b, []int{3} + return fileDescriptor_binlogdata_6d214635eb8c538c, []int{3} } func (m *StreamKeyRangeResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_StreamKeyRangeResponse.Unmarshal(m, b) @@ -410,7 +440,7 @@ 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_602eda7964a9642b, []int{4} + return fileDescriptor_binlogdata_6d214635eb8c538c, []int{4} } func (m *StreamTablesRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_StreamTablesRequest.Unmarshal(m, b) @@ -463,7 +493,7 @@ 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_602eda7964a9642b, []int{5} + return fileDescriptor_binlogdata_6d214635eb8c538c, []int{5} } func (m *StreamTablesResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_StreamTablesResponse.Unmarshal(m, b) @@ -508,7 +538,7 @@ 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_602eda7964a9642b, []int{6} + return fileDescriptor_binlogdata_6d214635eb8c538c, []int{6} } func (m *Rule) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Rule.Unmarshal(m, b) @@ -555,7 +585,7 @@ 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_602eda7964a9642b, []int{7} + return fileDescriptor_binlogdata_6d214635eb8c538c, []int{7} } func (m *Filter) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Filter.Unmarshal(m, b) @@ -598,17 +628,19 @@ type BinlogSource struct { Tables []string `protobuf:"bytes,5,rep,name=tables,proto3" json:"tables,omitempty"` // filter is set if we're using the generalized representation // for the filter. - Filter *Filter `protobuf:"bytes,6,opt,name=filter,proto3" json:"filter,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + Filter *Filter `protobuf:"bytes,6,opt,name=filter,proto3" json:"filter,omitempty"` + // on_ddl specifies the action to be taken when a DDL is encountered. + OnDdl OnDDLAction `protobuf:"varint,7,opt,name=on_ddl,json=onDdl,proto3,enum=binlogdata.OnDDLAction" json:"on_ddl,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } 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_602eda7964a9642b, []int{8} + return fileDescriptor_binlogdata_6d214635eb8c538c, []int{8} } func (m *BinlogSource) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_BinlogSource.Unmarshal(m, b) @@ -670,6 +702,13 @@ func (m *BinlogSource) GetFilter() *Filter { return nil } +func (m *BinlogSource) GetOnDdl() OnDDLAction { + if m != nil { + return m.OnDdl + } + return OnDDLAction_IGNORE +} + // RowChange represents one row change type RowChange struct { Before *query.Row `protobuf:"bytes,1,opt,name=before,proto3" json:"before,omitempty"` @@ -683,7 +722,7 @@ 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_602eda7964a9642b, []int{9} + return fileDescriptor_binlogdata_6d214635eb8c538c, []int{9} } func (m *RowChange) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_RowChange.Unmarshal(m, b) @@ -730,7 +769,7 @@ 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_602eda7964a9642b, []int{10} + return fileDescriptor_binlogdata_6d214635eb8c538c, []int{10} } func (m *RowEvent) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_RowEvent.Unmarshal(m, b) @@ -776,7 +815,7 @@ 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_602eda7964a9642b, []int{11} + return fileDescriptor_binlogdata_6d214635eb8c538c, []int{11} } func (m *FieldEvent) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_FieldEvent.Unmarshal(m, b) @@ -827,7 +866,7 @@ 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_602eda7964a9642b, []int{12} + return fileDescriptor_binlogdata_6d214635eb8c538c, []int{12} } func (m *VEvent) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_VEvent.Unmarshal(m, b) @@ -905,7 +944,7 @@ 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_602eda7964a9642b, []int{13} + return fileDescriptor_binlogdata_6d214635eb8c538c, []int{13} } func (m *VStreamRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_VStreamRequest.Unmarshal(m, b) @@ -972,7 +1011,7 @@ 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_602eda7964a9642b, []int{14} + return fileDescriptor_binlogdata_6d214635eb8c538c, []int{14} } func (m *VStreamResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_VStreamResponse.Unmarshal(m, b) @@ -1016,83 +1055,87 @@ func init() { proto.RegisterType((*VEvent)(nil), "binlogdata.VEvent") proto.RegisterType((*VStreamRequest)(nil), "binlogdata.VStreamRequest") proto.RegisterType((*VStreamResponse)(nil), "binlogdata.VStreamResponse") + proto.RegisterEnum("binlogdata.OnDDLAction", OnDDLAction_name, OnDDLAction_value) proto.RegisterEnum("binlogdata.VEventType", VEventType_name, VEventType_value) proto.RegisterEnum("binlogdata.BinlogTransaction_Statement_Category", BinlogTransaction_Statement_Category_name, BinlogTransaction_Statement_Category_value) } -func init() { proto.RegisterFile("binlogdata.proto", fileDescriptor_binlogdata_602eda7964a9642b) } - -var fileDescriptor_binlogdata_602eda7964a9642b = []byte{ - // 1123 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x56, 0xdd, 0x6e, 0xe2, 0x56, - 0x10, 0x5e, 0xb0, 0x31, 0x78, 0x9c, 0x1f, 0xe7, 0xe4, 0x47, 0x28, 0xea, 0x4a, 0x91, 0xd5, 0x76, - 0xd3, 0x48, 0x85, 0x2d, 0xfd, 0xbb, 0xaa, 0xaa, 0x00, 0x4e, 0xca, 0xc6, 0x81, 0xec, 0x89, 0x93, - 0x95, 0xf6, 0xc6, 0x72, 0xcc, 0x81, 0x58, 0x31, 0x36, 0xb1, 0x4f, 0x48, 0x79, 0x82, 0x3e, 0x40, - 0x9f, 0xa2, 0x7d, 0x90, 0x3e, 0x49, 0x7b, 0xd7, 0x87, 0xa8, 0xce, 0x8f, 0x0d, 0x64, 0xa5, 0x6e, - 0x7a, 0xd1, 0xbb, 0xf9, 0x3f, 0x33, 0xdf, 0x8c, 0x67, 0x0c, 0xe6, 0x4d, 0x18, 0x47, 0xc9, 0x78, - 0xe8, 0x53, 0xbf, 0x31, 0x4d, 0x13, 0x9a, 0x20, 0x58, 0x48, 0xf6, 0x8d, 0x19, 0x4d, 0xa7, 0x81, - 0x50, 0xec, 0x1b, 0xf7, 0x0f, 0x24, 0x9d, 0x4b, 0x66, 0x83, 0x26, 0xd3, 0x64, 0xe1, 0x65, 0x9d, - 0x43, 0xb5, 0x73, 0xeb, 0xa7, 0x19, 0xa1, 0x68, 0x0f, 0xb4, 0x20, 0x0a, 0x49, 0x4c, 0xeb, 0xa5, - 0x83, 0xd2, 0x61, 0x05, 0x4b, 0x0e, 0x21, 0x50, 0x83, 0x24, 0x8e, 0xeb, 0x65, 0x2e, 0xe5, 0x34, - 0xb3, 0xcd, 0x48, 0x3a, 0x23, 0x69, 0x5d, 0x11, 0xb6, 0x82, 0xb3, 0xfe, 0x52, 0x60, 0xab, 0xcd, - 0xf3, 0x70, 0x53, 0x3f, 0xce, 0xfc, 0x80, 0x86, 0x49, 0x8c, 0x4e, 0x01, 0x32, 0xea, 0x53, 0x32, - 0x21, 0x31, 0xcd, 0xea, 0xa5, 0x03, 0xe5, 0xd0, 0x68, 0xbd, 0x6a, 0x2c, 0x55, 0xf0, 0x81, 0x4b, - 0xe3, 0x32, 0xb7, 0xc7, 0x4b, 0xae, 0xa8, 0x05, 0x06, 0x99, 0x91, 0x98, 0x7a, 0x34, 0xb9, 0x23, - 0x71, 0x5d, 0x3d, 0x28, 0x1d, 0x1a, 0xad, 0xad, 0x86, 0x28, 0xd0, 0x66, 0x1a, 0x97, 0x29, 0x30, - 0x90, 0x82, 0xde, 0xff, 0xa3, 0x0c, 0x7a, 0x11, 0x0d, 0x39, 0x50, 0x0b, 0x7c, 0x4a, 0xc6, 0x49, - 0x3a, 0xe7, 0x65, 0x6e, 0xb4, 0x5e, 0x3f, 0x33, 0x91, 0x46, 0x47, 0xfa, 0xe1, 0x22, 0x02, 0xfa, - 0x12, 0xaa, 0x81, 0x40, 0x8f, 0xa3, 0x63, 0xb4, 0xb6, 0x97, 0x83, 0x49, 0x60, 0x71, 0x6e, 0x83, - 0x4c, 0x50, 0xb2, 0xfb, 0x88, 0x43, 0xb6, 0x86, 0x19, 0x69, 0xfd, 0x56, 0x82, 0x5a, 0x1e, 0x17, - 0x6d, 0xc3, 0x66, 0xdb, 0xf1, 0xae, 0xfa, 0xd8, 0xee, 0x0c, 0x4e, 0xfb, 0xbd, 0xf7, 0x76, 0xd7, - 0x7c, 0x81, 0xd6, 0xa0, 0xd6, 0x76, 0xbc, 0xb6, 0x7d, 0xda, 0xeb, 0x9b, 0x25, 0xb4, 0x0e, 0x7a, - 0xdb, 0xf1, 0x3a, 0x83, 0xf3, 0xf3, 0x9e, 0x6b, 0x96, 0xd1, 0x26, 0x18, 0x6d, 0xc7, 0xc3, 0x03, - 0xc7, 0x69, 0x1f, 0x77, 0xce, 0x4c, 0x05, 0xed, 0xc2, 0x56, 0xdb, 0xf1, 0xba, 0xe7, 0x8e, 0xd7, - 0xb5, 0x2f, 0xb0, 0xdd, 0x39, 0x76, 0xed, 0xae, 0xa9, 0x22, 0x00, 0x8d, 0x89, 0xbb, 0x8e, 0x59, - 0x91, 0xf4, 0xa5, 0xed, 0x9a, 0x9a, 0x0c, 0xd7, 0xeb, 0x5f, 0xda, 0xd8, 0x35, 0xab, 0x92, 0xbd, - 0xba, 0xe8, 0x1e, 0xbb, 0xb6, 0x59, 0x93, 0x6c, 0xd7, 0x76, 0x6c, 0xd7, 0x36, 0xf5, 0x37, 0x6a, - 0xad, 0x6c, 0x2a, 0x6f, 0xd4, 0x9a, 0x62, 0xaa, 0xd6, 0xaf, 0x25, 0xd8, 0xbd, 0xa4, 0x29, 0xf1, - 0x27, 0x67, 0x64, 0x8e, 0xfd, 0x78, 0x4c, 0x30, 0xb9, 0x7f, 0x20, 0x19, 0x45, 0xfb, 0x50, 0x9b, - 0x26, 0x59, 0xc8, 0xb0, 0xe3, 0x00, 0xeb, 0xb8, 0xe0, 0x51, 0x13, 0xf4, 0x3b, 0x32, 0xf7, 0x52, - 0x66, 0x2f, 0x01, 0x43, 0x8d, 0x62, 0x20, 0x8b, 0x48, 0xb5, 0x3b, 0x49, 0x2d, 0xe3, 0xab, 0x7c, - 0x1c, 0x5f, 0x6b, 0x04, 0x7b, 0x4f, 0x93, 0xca, 0xa6, 0x49, 0x9c, 0x11, 0xe4, 0x00, 0x12, 0x8e, - 0x1e, 0x5d, 0xf4, 0x96, 0xe7, 0x67, 0xb4, 0x5e, 0xfe, 0xeb, 0x00, 0xe0, 0xad, 0x9b, 0xa7, 0x22, - 0xeb, 0x67, 0xd8, 0x16, 0xef, 0xb8, 0xfe, 0x4d, 0x44, 0xb2, 0xe7, 0x94, 0xbe, 0x07, 0x1a, 0xe5, - 0xc6, 0xf5, 0xf2, 0x81, 0x72, 0xa8, 0x63, 0xc9, 0xfd, 0xd7, 0x0a, 0x87, 0xb0, 0xb3, 0xfa, 0xf2, - 0xff, 0x52, 0xdf, 0x37, 0xa0, 0xe2, 0x87, 0x88, 0xa0, 0x1d, 0xa8, 0x4c, 0x7c, 0x1a, 0xdc, 0xca, - 0x6a, 0x04, 0xc3, 0x4a, 0x19, 0x85, 0x11, 0x25, 0x29, 0x6f, 0xa1, 0x8e, 0x25, 0x67, 0xbd, 0x06, - 0xed, 0x84, 0x53, 0xe8, 0x73, 0xa8, 0xa4, 0x0f, 0xac, 0x56, 0xf1, 0xa9, 0x9b, 0xcb, 0x09, 0xb0, - 0xc0, 0x58, 0xa8, 0xad, 0xbf, 0x4b, 0xb0, 0x26, 0x12, 0xba, 0x4c, 0x1e, 0xd2, 0x80, 0x30, 0x04, - 0xef, 0xc8, 0x3c, 0x9b, 0xfa, 0x01, 0xc9, 0x11, 0xcc, 0x79, 0x96, 0x4c, 0x76, 0xeb, 0xa7, 0x43, - 0xf9, 0xaa, 0x60, 0xd0, 0xb7, 0x60, 0x70, 0x24, 0xa9, 0x47, 0xe7, 0x53, 0xc2, 0x31, 0xdc, 0x68, - 0xed, 0x2c, 0x86, 0x8a, 0xe3, 0x44, 0xdd, 0xf9, 0x94, 0x60, 0xa0, 0x05, 0xbd, 0x3a, 0x89, 0xea, - 0x33, 0x26, 0x71, 0xd1, 0xbf, 0xca, 0x4a, 0xff, 0x8e, 0x0a, 0x30, 0x34, 0x19, 0x65, 0xa9, 0x56, - 0x01, 0x47, 0x01, 0xd0, 0x5b, 0xd0, 0x71, 0xf2, 0xd8, 0xb9, 0xe5, 0x01, 0x2d, 0xd0, 0x6e, 0xc8, - 0x28, 0x49, 0x89, 0xec, 0x12, 0xc8, 0x2d, 0x86, 0x93, 0x47, 0x2c, 0x35, 0xe8, 0x00, 0x2a, 0xfe, - 0x28, 0x07, 0x7a, 0xd5, 0x44, 0x28, 0x2c, 0x1f, 0x6a, 0x38, 0x79, 0xe4, 0x9b, 0x0f, 0xbd, 0x04, - 0x51, 0xa1, 0x17, 0xfb, 0x93, 0x1c, 0x3e, 0x9d, 0x4b, 0xfa, 0xfe, 0x84, 0xa0, 0xef, 0xc0, 0x48, - 0x93, 0x47, 0x2f, 0xe0, 0xcf, 0x8b, 0x31, 0x34, 0x5a, 0xbb, 0x2b, 0xad, 0xc9, 0x93, 0xc3, 0x90, - 0xe6, 0x64, 0x66, 0xbd, 0x05, 0x38, 0x09, 0x49, 0x34, 0x7c, 0xd6, 0x23, 0x9f, 0x32, 0x38, 0x48, - 0x34, 0xcc, 0xe3, 0xaf, 0xc9, 0x94, 0x79, 0x04, 0x2c, 0x75, 0xd6, 0x9f, 0x25, 0xd0, 0xae, 0x45, - 0xbc, 0x23, 0x50, 0x79, 0xe3, 0xc4, 0x2e, 0xde, 0x5b, 0x4e, 0x47, 0x58, 0xf0, 0xd6, 0x71, 0x1b, - 0xf4, 0x09, 0xe8, 0x34, 0x9c, 0x90, 0x8c, 0xfa, 0x93, 0x29, 0x87, 0x44, 0xc1, 0x0b, 0x01, 0x3b, - 0x53, 0x63, 0x1a, 0x0e, 0xf9, 0x08, 0xe8, 0x98, 0xd3, 0x6c, 0xe1, 0x0e, 0x87, 0x11, 0x6f, 0xb0, - 0x8e, 0x19, 0x89, 0xbe, 0x02, 0x9d, 0xa1, 0xc0, 0xef, 0x43, 0xbd, 0xc2, 0x61, 0xdd, 0x79, 0x82, - 0x01, 0x7f, 0x16, 0xd7, 0xd2, 0x1c, 0xd7, 0xef, 0xc1, 0xe0, 0x79, 0x4b, 0x27, 0xd1, 0xe7, 0xbd, - 0xd5, 0x3e, 0xe7, 0xf8, 0x60, 0x18, 0x15, 0xb4, 0xf5, 0x4b, 0x19, 0x36, 0xae, 0xc5, 0xe7, 0x9a, - 0xaf, 0x88, 0x1f, 0x61, 0x9b, 0x8c, 0x46, 0x24, 0xa0, 0xe1, 0x8c, 0x78, 0x81, 0x1f, 0x45, 0x24, - 0xf5, 0xc2, 0xa1, 0x1c, 0x81, 0xcd, 0x86, 0x38, 0xdb, 0x1d, 0x2e, 0xef, 0x75, 0xf1, 0x56, 0x61, - 0x2b, 0x45, 0x43, 0x64, 0xc3, 0x76, 0x38, 0x99, 0x90, 0x61, 0xe8, 0xd3, 0xe5, 0x00, 0x62, 0x40, - 0x76, 0x25, 0xda, 0xd7, 0xee, 0xa9, 0x4f, 0xc9, 0x22, 0x4c, 0xe1, 0x51, 0x84, 0xf9, 0x8c, 0x8d, - 0x73, 0x3a, 0x2e, 0xb6, 0xce, 0xba, 0xf4, 0x74, 0xb9, 0x10, 0x4b, 0xe5, 0xca, 0x46, 0x53, 0x9f, - 0x6c, 0xb4, 0xc5, 0xe4, 0x57, 0x3e, 0x3a, 0xf9, 0x3f, 0xc0, 0x66, 0x01, 0x84, 0xdc, 0x58, 0x47, - 0xa0, 0x71, 0x3c, 0xf3, 0x25, 0x81, 0x3e, 0x6c, 0x3d, 0x96, 0x16, 0x47, 0xbf, 0x97, 0x00, 0x16, - 0xd3, 0x80, 0x0c, 0xa8, 0x5e, 0xf5, 0xcf, 0xfa, 0x83, 0x77, 0x7d, 0xf3, 0x05, 0xaa, 0x81, 0x7a, - 0xea, 0xf6, 0xba, 0x66, 0x09, 0xe9, 0x50, 0x11, 0x67, 0xb2, 0xcc, 0x6e, 0x9c, 0xbc, 0x91, 0x0a, - 0x3b, 0xa0, 0xc5, 0x81, 0x54, 0x51, 0x15, 0x94, 0xe2, 0x0c, 0xca, 0xbb, 0xa7, 0xb1, 0x80, 0xd8, - 0xbe, 0x70, 0x8e, 0x3b, 0xb6, 0x59, 0x65, 0x8a, 0xe2, 0x02, 0x02, 0x68, 0xf9, 0xf9, 0x63, 0x9e, - 0xec, 0x68, 0x02, 0x7b, 0x67, 0xe0, 0xfe, 0x64, 0x63, 0xd3, 0x60, 0x32, 0x3c, 0x78, 0x67, 0xae, - 0x31, 0xd9, 0x49, 0xcf, 0x76, 0xba, 0xe6, 0x7a, 0xfb, 0x8b, 0xf7, 0xaf, 0x66, 0x21, 0x25, 0x59, - 0xd6, 0x08, 0x93, 0xa6, 0xa0, 0x9a, 0xe3, 0xa4, 0x39, 0xa3, 0x4d, 0xfe, 0xc7, 0xd5, 0x5c, 0x94, - 0x79, 0xa3, 0x71, 0xc9, 0xd7, 0xff, 0x04, 0x00, 0x00, 0xff, 0xff, 0xcb, 0x74, 0x80, 0x55, 0xcd, - 0x09, 0x00, 0x00, +func init() { proto.RegisterFile("binlogdata.proto", fileDescriptor_binlogdata_6d214635eb8c538c) } + +var fileDescriptor_binlogdata_6d214635eb8c538c = []byte{ + // 1184 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x56, 0x5b, 0x6e, 0xdb, 0x56, + 0x13, 0x8e, 0x44, 0x8a, 0x12, 0x87, 0x8e, 0x4d, 0x1f, 0x5f, 0x7e, 0xc1, 0xf8, 0x03, 0x18, 0x44, + 0xdb, 0xb8, 0x06, 0x2a, 0xa7, 0xea, 0xed, 0xa9, 0x2d, 0x2c, 0x91, 0x71, 0x95, 0xd0, 0x92, 0x73, + 0xcc, 0x24, 0x45, 0x5e, 0x08, 0x9a, 0x3c, 0xb2, 0x09, 0x53, 0xa4, 0x4c, 0x1e, 0xcb, 0xd5, 0x0a, + 0xba, 0x80, 0xbe, 0x76, 0x03, 0xed, 0x42, 0xba, 0x92, 0x76, 0x1f, 0xc5, 0xb9, 0x90, 0x92, 0x1c, + 0xa0, 0x71, 0x1f, 0xfa, 0x36, 0xf7, 0x33, 0xf3, 0xcd, 0x70, 0x86, 0x60, 0x5e, 0xc4, 0x69, 0x92, + 0x5d, 0x46, 0x01, 0x0d, 0x3a, 0xd3, 0x3c, 0xa3, 0x19, 0x82, 0x85, 0x64, 0xcf, 0x98, 0xd1, 0x7c, + 0x1a, 0x0a, 0xc5, 0x9e, 0x71, 0x73, 0x4b, 0xf2, 0xb9, 0x64, 0xd6, 0x69, 0x36, 0xcd, 0x16, 0x5e, + 0xd6, 0x29, 0x34, 0xfb, 0x57, 0x41, 0x5e, 0x10, 0x8a, 0x76, 0x41, 0x0b, 0x93, 0x98, 0xa4, 0xb4, + 0x5d, 0xdb, 0xaf, 0x1d, 0x34, 0xb0, 0xe4, 0x10, 0x02, 0x35, 0xcc, 0xd2, 0xb4, 0x5d, 0xe7, 0x52, + 0x4e, 0x33, 0xdb, 0x82, 0xe4, 0x33, 0x92, 0xb7, 0x15, 0x61, 0x2b, 0x38, 0xeb, 0x2f, 0x05, 0x36, + 0x7b, 0x3c, 0x0f, 0x2f, 0x0f, 0xd2, 0x22, 0x08, 0x69, 0x9c, 0xa5, 0xe8, 0x04, 0xa0, 0xa0, 0x01, + 0x25, 0x13, 0x92, 0xd2, 0xa2, 0x5d, 0xdb, 0x57, 0x0e, 0x8c, 0xee, 0xd3, 0xce, 0x52, 0x05, 0xef, + 0xb9, 0x74, 0xce, 0x4b, 0x7b, 0xbc, 0xe4, 0x8a, 0xba, 0x60, 0x90, 0x19, 0x49, 0xa9, 0x4f, 0xb3, + 0x6b, 0x92, 0xb6, 0xd5, 0xfd, 0xda, 0x81, 0xd1, 0xdd, 0xec, 0x88, 0x02, 0x1d, 0xa6, 0xf1, 0x98, + 0x02, 0x03, 0xa9, 0xe8, 0xbd, 0x3f, 0xea, 0xa0, 0x57, 0xd1, 0x90, 0x0b, 0xad, 0x30, 0xa0, 0xe4, + 0x32, 0xcb, 0xe7, 0xbc, 0xcc, 0xf5, 0xee, 0xb3, 0x07, 0x26, 0xd2, 0xe9, 0x4b, 0x3f, 0x5c, 0x45, + 0x40, 0x9f, 0x41, 0x33, 0x14, 0xe8, 0x71, 0x74, 0x8c, 0xee, 0xd6, 0x72, 0x30, 0x09, 0x2c, 0x2e, + 0x6d, 0x90, 0x09, 0x4a, 0x71, 0x93, 0x70, 0xc8, 0xd6, 0x30, 0x23, 0xad, 0xdf, 0x6a, 0xd0, 0x2a, + 0xe3, 0xa2, 0x2d, 0xd8, 0xe8, 0xb9, 0xfe, 0xeb, 0x21, 0x76, 0xfa, 0xa3, 0x93, 0xe1, 0xe0, 0x9d, + 0x63, 0x9b, 0x8f, 0xd0, 0x1a, 0xb4, 0x7a, 0xae, 0xdf, 0x73, 0x4e, 0x06, 0x43, 0xb3, 0x86, 0x1e, + 0x83, 0xde, 0x73, 0xfd, 0xfe, 0xe8, 0xf4, 0x74, 0xe0, 0x99, 0x75, 0xb4, 0x01, 0x46, 0xcf, 0xf5, + 0xf1, 0xc8, 0x75, 0x7b, 0xc7, 0xfd, 0x97, 0xa6, 0x82, 0x76, 0x60, 0xb3, 0xe7, 0xfa, 0xf6, 0xa9, + 0xeb, 0xdb, 0xce, 0x19, 0x76, 0xfa, 0xc7, 0x9e, 0x63, 0x9b, 0x2a, 0x02, 0xd0, 0x98, 0xd8, 0x76, + 0xcd, 0x86, 0xa4, 0xcf, 0x1d, 0xcf, 0xd4, 0x64, 0xb8, 0xc1, 0xf0, 0xdc, 0xc1, 0x9e, 0xd9, 0x94, + 0xec, 0xeb, 0x33, 0xfb, 0xd8, 0x73, 0xcc, 0x96, 0x64, 0x6d, 0xc7, 0x75, 0x3c, 0xc7, 0xd4, 0x5f, + 0xa8, 0xad, 0xba, 0xa9, 0xbc, 0x50, 0x5b, 0x8a, 0xa9, 0x5a, 0xbf, 0xd4, 0x60, 0xe7, 0x9c, 0xe6, + 0x24, 0x98, 0xbc, 0x24, 0x73, 0x1c, 0xa4, 0x97, 0x04, 0x93, 0x9b, 0x5b, 0x52, 0x50, 0xb4, 0x07, + 0xad, 0x69, 0x56, 0xc4, 0x0c, 0x3b, 0x0e, 0xb0, 0x8e, 0x2b, 0x1e, 0x1d, 0x81, 0x7e, 0x4d, 0xe6, + 0x7e, 0xce, 0xec, 0x25, 0x60, 0xa8, 0x53, 0x0d, 0x64, 0x15, 0xa9, 0x75, 0x2d, 0xa9, 0x65, 0x7c, + 0x95, 0x0f, 0xe3, 0x6b, 0x8d, 0x61, 0xf7, 0x7e, 0x52, 0xc5, 0x34, 0x4b, 0x0b, 0x82, 0x5c, 0x40, + 0xc2, 0xd1, 0xa7, 0x8b, 0xde, 0xf2, 0xfc, 0x8c, 0xee, 0x93, 0x7f, 0x1c, 0x00, 0xbc, 0x79, 0x71, + 0x5f, 0x64, 0xfd, 0x04, 0x5b, 0xe2, 0x1d, 0x2f, 0xb8, 0x48, 0x48, 0xf1, 0x90, 0xd2, 0x77, 0x41, + 0xa3, 0xdc, 0xb8, 0x5d, 0xdf, 0x57, 0x0e, 0x74, 0x2c, 0xb9, 0x7f, 0x5b, 0x61, 0x04, 0xdb, 0xab, + 0x2f, 0xff, 0x27, 0xf5, 0x7d, 0x09, 0x2a, 0xbe, 0x4d, 0x08, 0xda, 0x86, 0xc6, 0x24, 0xa0, 0xe1, + 0x95, 0xac, 0x46, 0x30, 0xac, 0x94, 0x71, 0x9c, 0x50, 0x92, 0xf3, 0x16, 0xea, 0x58, 0x72, 0xd6, + 0x33, 0xd0, 0x9e, 0x73, 0x0a, 0x7d, 0x02, 0x8d, 0xfc, 0x96, 0xd5, 0x2a, 0x3e, 0x75, 0x73, 0x39, + 0x01, 0x16, 0x18, 0x0b, 0xb5, 0xf5, 0x6b, 0x1d, 0xd6, 0x44, 0x42, 0xe7, 0xd9, 0x6d, 0x1e, 0x12, + 0x86, 0xe0, 0x35, 0x99, 0x17, 0xd3, 0x20, 0x24, 0x25, 0x82, 0x25, 0xcf, 0x92, 0x29, 0xae, 0x82, + 0x3c, 0x92, 0xaf, 0x0a, 0x06, 0x7d, 0x05, 0x06, 0x47, 0x92, 0xfa, 0x74, 0x3e, 0x25, 0x1c, 0xc3, + 0xf5, 0xee, 0xf6, 0x62, 0xa8, 0x38, 0x4e, 0xd4, 0x9b, 0x4f, 0x09, 0x06, 0x5a, 0xd1, 0xab, 0x93, + 0xa8, 0x3e, 0x60, 0x12, 0x17, 0xfd, 0x6b, 0xac, 0xf4, 0xef, 0xb0, 0x02, 0x43, 0x93, 0x51, 0x96, + 0x6a, 0x15, 0x70, 0x94, 0x00, 0xa1, 0x0e, 0x68, 0x59, 0xea, 0x47, 0x51, 0xd2, 0x6e, 0xf2, 0x34, + 0xff, 0xb7, 0x6c, 0x3b, 0x4a, 0x6d, 0xdb, 0x3d, 0x16, 0x2d, 0x69, 0x64, 0xa9, 0x1d, 0x25, 0xd6, + 0x2b, 0xd0, 0x71, 0x76, 0xd7, 0xbf, 0xe2, 0x09, 0x58, 0xa0, 0x5d, 0x90, 0x71, 0x96, 0x13, 0xd9, + 0x55, 0x90, 0x5b, 0x0f, 0x67, 0x77, 0x58, 0x6a, 0xd0, 0x3e, 0x34, 0x82, 0x71, 0xd9, 0x98, 0x55, + 0x13, 0xa1, 0xb0, 0x02, 0x68, 0xe1, 0xec, 0x8e, 0x6f, 0x4a, 0xf4, 0x04, 0x04, 0x22, 0x7e, 0x1a, + 0x4c, 0x4a, 0xb8, 0x75, 0x2e, 0x19, 0x06, 0x13, 0x82, 0xbe, 0x06, 0x23, 0xcf, 0xee, 0xfc, 0x90, + 0x3f, 0x2f, 0xc6, 0xd6, 0xe8, 0xee, 0xac, 0xb4, 0xb2, 0x4c, 0x0e, 0x43, 0x5e, 0x92, 0x85, 0xf5, + 0x0a, 0xe0, 0x79, 0x4c, 0x92, 0xe8, 0x41, 0x8f, 0x7c, 0xc4, 0xe0, 0x23, 0x49, 0x54, 0xc6, 0x5f, + 0x93, 0x29, 0xf3, 0x08, 0x58, 0xea, 0xac, 0x3f, 0x6b, 0xa0, 0xbd, 0x11, 0xf1, 0x0e, 0x41, 0xe5, + 0x8d, 0x16, 0xbb, 0x7b, 0x77, 0x39, 0x1d, 0x61, 0xc1, 0x5b, 0xcd, 0x6d, 0xd0, 0xff, 0x41, 0xa7, + 0xf1, 0x84, 0x14, 0x34, 0x98, 0x4c, 0x39, 0x24, 0x0a, 0x5e, 0x08, 0xd8, 0x59, 0xbb, 0xa4, 0x71, + 0xc4, 0x47, 0x46, 0xc7, 0x9c, 0x66, 0x0b, 0x9a, 0xb5, 0x47, 0xe5, 0x22, 0x46, 0xa2, 0xcf, 0x41, + 0x67, 0x28, 0xf0, 0x7b, 0xd2, 0x6e, 0x70, 0x58, 0xb7, 0xef, 0x61, 0xc0, 0x9f, 0xc5, 0xad, 0xbc, + 0xc4, 0xf5, 0x1b, 0x30, 0x78, 0xde, 0xd2, 0x49, 0xcc, 0xc5, 0xee, 0xea, 0x5c, 0x94, 0xf8, 0x60, + 0x18, 0x57, 0xb4, 0xf5, 0x73, 0x1d, 0xd6, 0xdf, 0x88, 0xcf, 0xbb, 0x5c, 0x29, 0xdf, 0xc3, 0x16, + 0x19, 0x8f, 0x49, 0x48, 0xe3, 0x19, 0xf1, 0xc3, 0x20, 0x49, 0x48, 0xee, 0xc7, 0x91, 0x1c, 0x81, + 0x8d, 0x8e, 0x38, 0xf3, 0x7d, 0x2e, 0x1f, 0xd8, 0x78, 0xb3, 0xb2, 0x95, 0xa2, 0x08, 0x39, 0xb0, + 0x15, 0x4f, 0x26, 0x24, 0x8a, 0x03, 0xba, 0x1c, 0x40, 0x0c, 0xc8, 0x8e, 0x44, 0xfb, 0x8d, 0x77, + 0x12, 0x50, 0xb2, 0x08, 0x53, 0x79, 0x54, 0x61, 0x3e, 0x66, 0xe3, 0x9f, 0x5f, 0x56, 0x5b, 0xea, + 0xb1, 0xf4, 0xf4, 0xb8, 0x10, 0x4b, 0xe5, 0xca, 0x06, 0x54, 0xef, 0x6d, 0xc0, 0xc5, 0x97, 0xd2, + 0xf8, 0xd0, 0x97, 0x62, 0x7d, 0x0b, 0x1b, 0x15, 0x10, 0x72, 0xc3, 0x1d, 0x82, 0xc6, 0xf1, 0x2c, + 0x97, 0x0a, 0x7a, 0xbf, 0xf5, 0x58, 0x5a, 0x1c, 0x7e, 0x07, 0xc6, 0xd2, 0xe7, 0xc4, 0x2e, 0xde, + 0xe0, 0x64, 0x38, 0xc2, 0x8e, 0xf9, 0x08, 0xb5, 0x40, 0x3d, 0xf7, 0x46, 0x67, 0x66, 0x8d, 0x51, + 0xce, 0x8f, 0x4e, 0x5f, 0x5c, 0x51, 0x46, 0xf9, 0xd2, 0x48, 0x39, 0xfc, 0xbd, 0x06, 0xb0, 0x98, + 0x26, 0x64, 0x40, 0xf3, 0xf5, 0xf0, 0xe5, 0x70, 0xf4, 0x76, 0x28, 0x02, 0x9c, 0x78, 0x03, 0xdb, + 0xac, 0x21, 0x1d, 0x1a, 0xe2, 0x2c, 0xd7, 0xd9, 0x0b, 0xf2, 0x26, 0x2b, 0xec, 0x60, 0x57, 0x07, + 0x59, 0x45, 0x4d, 0x50, 0xaa, 0xb3, 0x2b, 0xef, 0xac, 0xc6, 0x02, 0x62, 0xe7, 0xcc, 0x3d, 0xee, + 0x3b, 0x66, 0x93, 0x29, 0xaa, 0x8b, 0x0b, 0xa0, 0x95, 0xe7, 0x96, 0x79, 0xb2, 0x23, 0x0d, 0xec, + 0x9d, 0x91, 0xf7, 0x83, 0x83, 0x4d, 0x83, 0xc9, 0xf0, 0xe8, 0xad, 0xb9, 0xc6, 0x64, 0xcf, 0x07, + 0x8e, 0x6b, 0x9b, 0x8f, 0x7b, 0x9f, 0xbe, 0x7b, 0x3a, 0x8b, 0x29, 0x29, 0x8a, 0x4e, 0x9c, 0x1d, + 0x09, 0xea, 0xe8, 0x32, 0x3b, 0x9a, 0xd1, 0x23, 0xfe, 0x87, 0x77, 0xb4, 0x80, 0xe9, 0x42, 0xe3, + 0x92, 0x2f, 0xfe, 0x0e, 0x00, 0x00, 0xff, 0xff, 0x68, 0xbd, 0x20, 0x05, 0x3d, 0x0a, 0x00, 0x00, } diff --git a/go/vt/vttablet/tabletmanager/vreplication/player_plan.go b/go/vt/vttablet/tabletmanager/vreplication/player_plan.go index d848b02dcb8..67b7c566972 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/player_plan.go +++ b/go/vt/vttablet/tabletmanager/vreplication/player_plan.go @@ -32,10 +32,9 @@ type playerPlan struct { } type tablePlan struct { - name string - colExprs []*colExpr - onInsert insertType - updateCols []int + name string + colExprs []*colExpr + onInsert insertType fields []*querypb.Field pkCols []*colExpr @@ -51,9 +50,10 @@ func (tp *tablePlan) findCol(name sqlparser.ColIdent) *colExpr { } type colExpr struct { - colname sqlparser.ColIdent - colnum int - op operation + colname sqlparser.ColIdent + colnum int + op operation + isGrouped bool } type operation int @@ -62,7 +62,6 @@ const ( opNone = operation(iota) opCount opSum - opExclude ) type insertType int @@ -151,6 +150,13 @@ func buildTablePlan(rule *binlogdatapb.Rule) (*binlogdatapb.Rule, *tablePlan, er if err := analyzeGroupBy(sel.GroupBy, tplan); err != nil { return nil, nil, err } + tplan.onInsert = insertIgnore + for _, cExpr := range tplan.colExprs { + if !cExpr.isGrouped { + tplan.onInsert = insertOndup + break + } + } } sendRule := &binlogdatapb.Rule{ Match: rule.Match, @@ -217,7 +223,7 @@ func analyzeGroupBy(groupBy sqlparser.GroupBy, tplan *tablePlan) error { if cExpr.op != opNone { return fmt.Errorf("group by expression is not allowed to reference an aggregate expression: %v", sqlparser.String(expr)) } - cExpr.op = opExclude + cExpr.isGrouped = true } return nil } diff --git a/go/vt/vttablet/tabletmanager/vreplication/vplayer.go b/go/vt/vttablet/tabletmanager/vreplication/vplayer.go index dff3cfa7b77..26bc1479acd 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/vplayer.go +++ b/go/vt/vttablet/tabletmanager/vreplication/vplayer.go @@ -17,6 +17,7 @@ limitations under the License. package vreplication import ( + "bytes" "fmt" "io" "time" @@ -24,6 +25,7 @@ import ( "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/grpcclient" "vitess.io/vitess/go/vt/log" @@ -38,7 +40,7 @@ import ( type vplayer struct { id uint32 - filter *binlogdatapb.Filter + source *binlogdatapb.BinlogSource sourceTablet *topodatapb.Tablet stats *binlogplayer.Stats dbClient binlogplayer.DBClient @@ -52,10 +54,10 @@ type vplayer struct { retryDelay time.Duration } -func newVStreamer(id uint32, filter *binlogdatapb.Filter, sourceTablet *topodatapb.Tablet, stats *binlogplayer.Stats, dbClient binlogplayer.DBClient, mysqld *mysqlctl.Mysqld) *vplayer { +func newVPlayer(id uint32, source *binlogdatapb.BinlogSource, sourceTablet *topodatapb.Tablet, stats *binlogplayer.Stats, dbClient binlogplayer.DBClient, mysqld *mysqlctl.Mysqld) *vplayer { return &vplayer{ id: id, - filter: filter, + source: source, sourceTablet: sourceTablet, stats: stats, dbClient: dbClient, @@ -101,7 +103,7 @@ func (vp *vplayer) play(ctx context.Context) error { } log.Infof("Starting VReplication player id: %v, startPos: %v, stop: %v, source: %v", vp.id, startPos, vp.stopPos, vp.sourceTablet) - plan, err := buildPlayerPlan(vp.filter) + plan, err := buildPlayerPlan(vp.source.Filter) if err != nil { return err } @@ -149,10 +151,8 @@ func (vp *vplayer) applyEvent(event *binlogdatapb.VEvent) error { return err } case binlogdatapb.VEventType_COMMIT: - updatePos := binlogplayer.GenerateUpdatePos(vp.id, vp.pos, time.Now().Unix(), event.Timestamp) - if _, err := vp.dbClient.ExecuteFetch(updatePos, 0); err != nil { - _ = vp.dbClient.Rollback() - return fmt.Errorf("error %v updating position", err) + if err := vp.updatePos(event.Timestamp); err != nil { + return err } if err := vp.dbClient.Commit(); err != nil { return err @@ -161,9 +161,51 @@ func (vp *vplayer) applyEvent(event *binlogdatapb.VEvent) error { // This code is unreachable. It's just here as failsafe. _ = vp.dbClient.Rollback() case binlogdatapb.VEventType_FIELD: - if err := vp.updatePlans(event.FieldEvent); err != nil { + if err := vp.updatePlan(event.FieldEvent); err != nil { + return err + } + case binlogdatapb.VEventType_ROW: + if err := vp.applyRowEvent(event.RowEvent); err != nil { return err } + case binlogdatapb.VEventType_DDL: + switch vp.source.OnDdl { + case binlogdatapb.OnDDLAction_IGNORE: + if err := vp.updatePos(event.Timestamp); err != nil { + return err + } + if err := vp.dbClient.Commit(); err != nil { + return err + } + case binlogdatapb.OnDDLAction_STOP: + if err := vp.updatePos(event.Timestamp); err != nil { + return err + } + vp.setState(binlogplayer.BlpStopped, fmt.Sprintf("stopped at DDL %s", event.Ddl)) + if err := vp.dbClient.Commit(); err != nil { + return err + } + case binlogdatapb.OnDDLAction_EXEC: + if err := vp.updatePos(event.Timestamp); err != nil { + return err + } + if err := vp.exec(event.Ddl); err != nil { + return err + } + if err := vp.dbClient.Commit(); err != nil { + return err + } + case binlogdatapb.OnDDLAction_EXEC_IGNORE: + if err := vp.updatePos(event.Timestamp); err != nil { + return err + } + if err := vp.exec(event.Ddl); err != nil { + log.Infof("Ignoring error: %v for DDL: %s", err, event.Ddl) + } + if err := vp.dbClient.Commit(); err != nil { + return err + } + } } return nil } @@ -174,7 +216,7 @@ func (vp *vplayer) setState(state, message string) { } } -func (vp *vplayer) updatePlans(fieldEvent *binlogdatapb.FieldEvent) error { +func (vp *vplayer) updatePlan(fieldEvent *binlogdatapb.FieldEvent) error { prelim := vp.pplan.tablePlans[fieldEvent.TableName] tplan := &tablePlan{ name: fieldEvent.TableName, @@ -234,3 +276,173 @@ func (vp *vplayer) updatePlans(fieldEvent *binlogdatapb.FieldEvent) error { vp.tplans[fieldEvent.TableName] = tplan return nil } + +func (vp *vplayer) applyRowEvent(rowEvent *binlogdatapb.RowEvent) error { + tplan := vp.tplans[rowEvent.TableName] + if tplan != nil { + return fmt.Errorf("unexpected event on table %s", rowEvent.TableName) + } + for _, change := range rowEvent.RowChanges { + if err := vp.applyRowChange(tplan, change); err != nil { + return err + } + } + return nil +} + +func (vp *vplayer) applyRowChange(tplan *tablePlan, rowChange *binlogdatapb.RowChange) error { + // MakeRowTrusted is needed here because because Proto3ToResult is not convenient. + var before, after []sqltypes.Value + if rowChange.Before != nil { + before = sqltypes.MakeRowTrusted(tplan.fields, rowChange.Before) + } + if rowChange.After != nil { + after = sqltypes.MakeRowTrusted(tplan.fields, rowChange.After) + } + var query string + switch { + case before == nil && after != nil: + query = vp.generateInsert(tplan, after) + case before != nil && after != nil: + query = vp.generateUpdate(tplan, before, after) + case before != nil && after == nil: + query = vp.generateDelete(tplan, before) + case before == nil && after == nil: + // unreachable + } + return vp.exec(query) +} + +func (vp *vplayer) generateInsert(tplan *tablePlan, after []sqltypes.Value) string { + sql := sqlparser.NewTrackedBuffer(nil) + if tplan.onInsert == insertIgnore { + sql.Myprintf("insert ignore into %s set ", sqlparser.NewTableIdent(tplan.name)) + } else { + sql.Myprintf("insert into %s set ", sqlparser.NewTableIdent(tplan.name)) + } + vp.writeInsertValues(sql, tplan, after) + if tplan.onInsert == insertOndup { + sql.Myprintf(" on duplicate key update ") + vp.writeUpdateValues(sql, tplan, nil, after) + } + return sql.String() +} + +func (vp *vplayer) generateUpdate(tplan *tablePlan, before, after []sqltypes.Value) string { + if tplan.onInsert == insertIgnore { + return "" + } + sql := sqlparser.NewTrackedBuffer(nil) + sql.Myprintf("update %v set ", sqlparser.NewTableIdent(tplan.name)) + vp.writeUpdateValues(sql, tplan, before, after) + sql.Myprintf(" where ") + vp.writeWhereValues(sql, tplan, before) + return sql.String() +} + +func (vp *vplayer) generateDelete(tplan *tablePlan, before []sqltypes.Value) string { + sql := sqlparser.NewTrackedBuffer(nil) + if tplan.onInsert == insertNormal { + sql.Myprintf("delete from %v where ", sqlparser.NewTableIdent(tplan.name)) + vp.writeWhereValues(sql, tplan, before) + return sql.String() + } + sql.Myprintf("update %v set ", sqlparser.NewTableIdent(tplan.name)) + vp.writeUpdateValues(sql, tplan, before, nil) + sql.Myprintf(" where ") + vp.writeWhereValues(sql, tplan, before) + return sql.String() +} + +func (vp *vplayer) writeInsertValues(sql *sqlparser.TrackedBuffer, tplan *tablePlan, after []sqltypes.Value) { + separator := "" + for _, cExpr := range tplan.colExprs { + sql.Myprintf("%s%s=", separator, cExpr.colname) + if separator == "" { + separator = ", " + } + if cExpr.op == opCount { + sql.WriteString("1") + } else { + encodeValue(sql, after[cExpr.colnum]) + } + } +} + +func (vp *vplayer) writeUpdateValues(sql *sqlparser.TrackedBuffer, tplan *tablePlan, before, after []sqltypes.Value) { + separator := "" + for _, cExpr := range tplan.colExprs { + if cExpr.isGrouped { + continue + } + sql.Myprintf("%s%s=", separator, cExpr.colname) + if separator == "" { + separator = ", " + } + if cExpr.op == opCount || cExpr.op == opSum { + sql.Myprintf("%s", cExpr.colname) + } + if len(before) != 0 { + switch cExpr.op { + case opNone: + if len(after) == 0 { + sql.WriteString("NULL") + } + case opCount: + sql.WriteString("-1") + case opSum: + sql.WriteString("-") + encodeValue(sql, before[cExpr.colnum]) + } + } + if len(after) != 0 { + switch cExpr.op { + case opNone: + encodeValue(sql, after[cExpr.colnum]) + case opCount: + sql.WriteString("+1") + case opSum: + sql.WriteString("+") + encodeValue(sql, after[cExpr.colnum]) + } + } + } +} + +func (vp *vplayer) writeWhereValues(sql *sqlparser.TrackedBuffer, tplan *tablePlan, before []sqltypes.Value) { + separator := "" + for _, cExpr := range tplan.pkCols { + sql.Myprintf("%s%s=", separator, cExpr.colname) + if separator == "" { + separator = " AND " + } + encodeValue(sql, before[cExpr.colnum]) + } +} +func (vp *vplayer) updatePos(ts int64) error { + updatePos := binlogplayer.GenerateUpdatePos(vp.id, vp.pos, time.Now().Unix(), ts) + if _, err := vp.dbClient.ExecuteFetch(updatePos, 0); err != nil { + _ = vp.dbClient.Rollback() + return fmt.Errorf("error %v updating position", err) + } + return nil +} + +func (vp *vplayer) exec(sql string) error { + vp.stats.Timings.Record("query", time.Now()) + _, err := vp.dbClient.ExecuteFetch(sql, 0) + return err +} + +func encodeValue(sql *sqlparser.TrackedBuffer, value sqltypes.Value) { + if value.Type() == querypb.Type_TIMESTAMP && !bytes.HasPrefix(value.ToBytes(), mysql.ZeroTimestamp) { + // Values in the binary log are UTC. Let's convert them + // to whatever timezone the connection is using, + // so MySQL properly converts them back to UTC. + sql.WriteString("convert_tz(") + value.EncodeSQL(sql) + sql.WriteString(", '+00:00', @@session.time_zone)") + } else { + value.EncodeSQL(sql) + } +} diff --git a/proto/binlogdata.proto b/proto/binlogdata.proto index 83f5abfca49..a1471e44f5c 100644 --- a/proto/binlogdata.proto +++ b/proto/binlogdata.proto @@ -132,6 +132,14 @@ message Filter { repeated Rule rules = 1; } +// OnDDLAction lists the possible actions for DDLs. +enum OnDDLAction { + IGNORE = 0; + STOP = 1; + EXEC = 2; + EXEC_IGNORE = 3; +} + // BinlogSource specifies the source and filter parameters for // Filtered Replication. It currently supports a keyrange // or a list of tables. @@ -154,6 +162,9 @@ message BinlogSource { // filter is set if we're using the generalized representation // for the filter. Filter filter = 6; + + // on_ddl specifies the action to be taken when a DDL is encountered. + OnDDLAction on_ddl = 7; } // VEventType enumerates the event types. diff --git a/py/vtproto/binlogdata_pb2.py b/py/vtproto/binlogdata_pb2.py index 0278b0f83f0..e586658b98d 100644 --- a/py/vtproto/binlogdata_pb2.py +++ b/py/vtproto/binlogdata_pb2.py @@ -23,10 +23,41 @@ 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\"\xb5\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\"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\"\xb2\x01\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\"\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*\xaa\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\rB)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\")\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\"\xb2\x01\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\"\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*>\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*\xaa\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\rB)Z\'vitess.io/vitess/go/vt/proto/binlogdatab\x06proto3') , dependencies=[vtrpc__pb2.DESCRIPTOR,query__pb2.DESCRIPTOR,topodata__pb2.DESCRIPTOR,]) +_ONDDLACTION = _descriptor.EnumDescriptor( + name='OnDDLAction', + full_name='binlogdata.OnDDLAction', + filename=None, + file=DESCRIPTOR, + values=[ + _descriptor.EnumValueDescriptor( + name='IGNORE', index=0, number=0, + serialized_options=None, + type=None), + _descriptor.EnumValueDescriptor( + name='STOP', index=1, number=1, + serialized_options=None, + type=None), + _descriptor.EnumValueDescriptor( + name='EXEC', index=2, number=2, + serialized_options=None, + type=None), + _descriptor.EnumValueDescriptor( + name='EXEC_IGNORE', index=3, number=3, + serialized_options=None, + type=None), + ], + containing_type=None, + serialized_options=None, + serialized_start=1907, + serialized_end=1969, +) +_sym_db.RegisterEnumDescriptor(_ONDDLACTION) + +OnDDLAction = enum_type_wrapper.EnumTypeWrapper(_ONDDLACTION) _VEVENTTYPE = _descriptor.EnumDescriptor( name='VEventType', full_name='binlogdata.VEventType', @@ -92,12 +123,16 @@ ], containing_type=None, serialized_options=None, - serialized_start=1867, - serialized_end=2037, + serialized_start=1972, + serialized_end=2142, ) _sym_db.RegisterEnumDescriptor(_VEVENTTYPE) VEventType = enum_type_wrapper.EnumTypeWrapper(_VEVENTTYPE) +IGNORE = 0 +STOP = 1 +EXEC = 2 +EXEC_IGNORE = 3 UNKNOWN = 0 GTID = 1 BEGIN = 2 @@ -567,6 +602,13 @@ message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='on_ddl', full_name='binlogdata.BinlogSource.on_ddl', index=6, + number=7, 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=[ ], @@ -580,7 +622,7 @@ oneofs=[ ], serialized_start=1037, - serialized_end=1218, + serialized_end=1259, ) @@ -617,8 +659,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=1220, - serialized_end=1286, + serialized_start=1261, + serialized_end=1327, ) @@ -655,8 +697,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=1288, - serialized_end=1362, + serialized_start=1329, + serialized_end=1403, ) @@ -693,8 +735,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=1364, - serialized_end=1426, + serialized_start=1405, + serialized_end=1467, ) @@ -759,8 +801,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=1429, - serialized_end=1607, + serialized_start=1470, + serialized_end=1648, ) @@ -818,8 +860,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=1610, - serialized_end=1809, + serialized_start=1651, + serialized_end=1850, ) @@ -849,8 +891,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=1811, - serialized_end=1864, + serialized_start=1852, + serialized_end=1905, ) _BINLOGTRANSACTION_STATEMENT.fields_by_name['category'].enum_type = _BINLOGTRANSACTION_STATEMENT_CATEGORY @@ -868,6 +910,7 @@ _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 +_BINLOGSOURCE.fields_by_name['on_ddl'].enum_type = _ONDDLACTION _ROWCHANGE.fields_by_name['before'].message_type = query__pb2._ROW _ROWCHANGE.fields_by_name['after'].message_type = query__pb2._ROW _ROWEVENT.fields_by_name['row_changes'].message_type = _ROWCHANGE @@ -895,6 +938,7 @@ DESCRIPTOR.message_types_by_name['VEvent'] = _VEVENT DESCRIPTOR.message_types_by_name['VStreamRequest'] = _VSTREAMREQUEST DESCRIPTOR.message_types_by_name['VStreamResponse'] = _VSTREAMRESPONSE +DESCRIPTOR.enum_types_by_name['OnDDLAction'] = _ONDDLACTION DESCRIPTOR.enum_types_by_name['VEventType'] = _VEVENTTYPE _sym_db.RegisterFileDescriptor(DESCRIPTOR) From 0fe23126ac2f1028a660a8970ddb0800e8601b85 Mon Sep 17 00:00:00 2001 From: Sugu Sougoumarane Date: Wed, 9 Jan 2019 00:03:01 -0800 Subject: [PATCH 061/115] vreplication: refactored vstreamer test for reuse Signed-off-by: Sugu Sougoumarane --- .../tabletserver/vstreamer/engine_test.go | 4 +- .../tabletserver/vstreamer/main_test.go | 123 ++-------------- .../vstreamer/planbuilder_test.go | 2 +- .../tabletserver/vstreamer/testenv/testenv.go | 138 ++++++++++++++++++ .../tabletserver/vstreamer/vstreamer_test.go | 14 +- 5 files changed, 161 insertions(+), 120 deletions(-) create mode 100644 go/vt/vttablet/tabletserver/vstreamer/testenv/testenv.go diff --git a/go/vt/vttablet/tabletserver/vstreamer/engine_test.go b/go/vt/vttablet/tabletserver/vstreamer/engine_test.go index 1e209663b77..c88a9aeef40 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/engine_test.go +++ b/go/vt/vttablet/tabletserver/vstreamer/engine_test.go @@ -50,7 +50,7 @@ func TestUpdateVSchema(t *testing.T) { t.Skip() } - defer setVSchema("{}") + defer env.SetVSchema("{}") // We have to start at least one stream to start the vschema watcher. ctx, cancel := context.WithCancel(context.Background()) @@ -67,7 +67,7 @@ func TestUpdateVSchema(t *testing.T) { startCount := expectUpdateCount(t, 1) - if err := setVSchema(shardedVSchema); err != nil { + if err := env.SetVSchema(shardedVSchema); err != nil { t.Fatal(err) } expectUpdateCount(t, startCount+1) diff --git a/go/vt/vttablet/tabletserver/vstreamer/main_test.go b/go/vt/vttablet/tabletserver/vstreamer/main_test.go index d308e431690..224091078f0 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/main_test.go +++ b/go/vt/vttablet/tabletserver/vstreamer/main_test.go @@ -20,45 +20,16 @@ import ( "flag" "fmt" "os" - "path" "testing" - "golang.org/x/net/context" - "vitess.io/vitess/go/json2" - "vitess.io/vitess/go/mysql" - "vitess.io/vitess/go/vt/dbconfigs" - "vitess.io/vitess/go/vt/logutil" - "vitess.io/vitess/go/vt/mysqlctl" - "vitess.io/vitess/go/vt/srvtopo" - "vitess.io/vitess/go/vt/topo" - "vitess.io/vitess/go/vt/topo/memorytopo" - "vitess.io/vitess/go/vt/topotools" - "vitess.io/vitess/go/vt/vttablet/tabletserver/connpool" - "vitess.io/vitess/go/vt/vttablet/tabletserver/schema" - "vitess.io/vitess/go/vt/vttablet/tabletserver/tabletenv" - "vitess.io/vitess/go/vt/vttest" - - topodatapb "vitess.io/vitess/go/vt/proto/topodata" - vschemapb "vitess.io/vitess/go/vt/proto/vschema" - vttestpb "vitess.io/vitess/go/vt/proto/vttest" + "vitess.io/vitess/go/vt/vttablet/tabletserver/vstreamer/testenv" ) var ( - engine *Engine - mysqld *mysqlctl.Mysqld - connParams mysql.ConnParams - connAppDebugParams mysql.ConnParams - topoServ *topo.Server - keyspaceName = "vttest" - cells = []string{"cell1"} + engine *Engine + env *testenv.Env ) -type checker struct{} - -var _ = connpool.MySQLChecker(checker{}) - -func (checker) CheckMySQL() {} - func TestMain(m *testing.M) { flag.Parse() // Do not remove this comment, import into google3 depends on it @@ -67,90 +38,22 @@ func TestMain(m *testing.M) { } exitCode := func() int { - // Launch MySQL. - // We need a Keyspace in the topology, so the DbName is set. - // We need a Shard too, so the database 'vttest' is created. - cfg := vttest.Config{ - Topology: &vttestpb.VTTestTopology{ - Keyspaces: []*vttestpb.Keyspace{ - { - Name: keyspaceName, - Shards: []*vttestpb.Shard{ - { - Name: "0", - DbNameOverride: "vttest", - }, - }, - }, - }, - }, - ExtraMyCnf: []string{path.Join(os.Getenv("VTTOP"), "config/mycnf/rbr.cnf")}, - OnlyMySQL: true, - } - defer os.RemoveAll(cfg.SchemaDir) - cluster := vttest.LocalCluster{ - Config: cfg, - } - if err := cluster.Setup(); err != nil { - fmt.Fprintf(os.Stderr, "could not launch mysql: %v\n", err) - return 1 - } - defer cluster.TearDown() - - // initTopo initializes topoServ. - if err := initEngine(&cluster); err != nil { + var err error + env, err = testenv.Init() + if err != nil { fmt.Fprintf(os.Stderr, "%v", err) return 1 } + defer env.Close() + + // engine cannot be initialized in testenv because it introduces + // circular dependencies. + engine = NewEngine(env.SrvTopo, env.SchemaEngine) + engine.InitDBConfig(env.Dbcfgs) + engine.Open(env.KeyspaceName, env.Cells[0]) defer engine.Close() return m.Run() }() os.Exit(exitCode) } - -func initEngine(cluster *vttest.LocalCluster) error { - if err := initTopo(); err != nil { - return err - } - - se := schema.NewEngine(checker{}, tabletenv.DefaultQsConfig) - srvTopoServer := srvtopo.NewResilientServer(topoServ, "TestTopo") - engine = NewEngine(srvTopoServer, se) - - dbcfgs := dbconfigs.NewTestDBConfigs(cluster.MySQLConnParams(), cluster.MySQLAppDebugConnParams(), cluster.DbName()) - mysqld = mysqlctl.NewMysqld(dbcfgs) - se.InitDBConfig(dbcfgs) - engine.InitDBConfig(dbcfgs) - - engine.Open(keyspaceName, cells[0]) - return nil -} - -func initTopo() error { - ctx := context.Background() - - topoServ = memorytopo.NewServer(cells...) - if err := topoServ.CreateKeyspace(ctx, keyspaceName, &topodatapb.Keyspace{}); err != nil { - return err - } - // The first vschema should not be empty. Leads to Node not found error. - // TODO(sougou): need to fix the bug. - return setVSchema(`{"sharded": true}`) -} - -func setVSchema(vs string) error { - ctx := context.Background() - logger := logutil.NewConsoleLogger() - var kspb vschemapb.Keyspace - if err := json2.Unmarshal([]byte(vs), &kspb); err != nil { - return fmt.Errorf("Unmarshal failed: %v", err) - } - if err := topoServ.SaveVSchema(ctx, keyspaceName, &kspb); err != nil { - return fmt.Errorf("SaveVSchema failed: %v", err) - } - if err := topotools.RebuildVSchema(ctx, logger, topoServ, cells); err != nil { - return fmt.Errorf("RebuildVSchema failed: %v", err) - } - return nil -} diff --git a/go/vt/vttablet/tabletserver/vstreamer/planbuilder_test.go b/go/vt/vttablet/tabletserver/vstreamer/planbuilder_test.go index 1dda4116101..f3bf8d4aaa4 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/planbuilder_test.go +++ b/go/vt/vttablet/tabletserver/vstreamer/planbuilder_test.go @@ -60,7 +60,7 @@ func init() { if err := json2.Unmarshal([]byte(input), &kspb); err != nil { panic(fmt.Errorf("Unmarshal failed: %v", err)) } - kschema, err := vindexes.BuildKeyspaceSchema(&kspb, keyspaceName) + kschema, err := vindexes.BuildKeyspaceSchema(&kspb, "ks") if err != nil { panic(err) } diff --git a/go/vt/vttablet/tabletserver/vstreamer/testenv/testenv.go b/go/vt/vttablet/tabletserver/vstreamer/testenv/testenv.go new file mode 100644 index 00000000000..036bcd2e77f --- /dev/null +++ b/go/vt/vttablet/tabletserver/vstreamer/testenv/testenv.go @@ -0,0 +1,138 @@ +/* +Copyright 2019 The Vitess Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this 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 testenv supplies test functions for testing vstreamer. +package testenv + +import ( + "context" + "fmt" + "os" + "path" + + "vitess.io/vitess/go/json2" + "vitess.io/vitess/go/vt/dbconfigs" + "vitess.io/vitess/go/vt/logutil" + "vitess.io/vitess/go/vt/mysqlctl" + "vitess.io/vitess/go/vt/srvtopo" + "vitess.io/vitess/go/vt/topo" + "vitess.io/vitess/go/vt/topo/memorytopo" + "vitess.io/vitess/go/vt/topotools" + "vitess.io/vitess/go/vt/vttablet/tabletserver/connpool" + "vitess.io/vitess/go/vt/vttablet/tabletserver/schema" + "vitess.io/vitess/go/vt/vttablet/tabletserver/tabletenv" + "vitess.io/vitess/go/vt/vttest" + + topodatapb "vitess.io/vitess/go/vt/proto/topodata" + vschemapb "vitess.io/vitess/go/vt/proto/vschema" + vttestpb "vitess.io/vitess/go/vt/proto/vttest" +) + +// Env contains all the env vars for a test against a mysql instance. +type Env struct { + cluster *vttest.LocalCluster + + KeyspaceName string + Cells []string + + TopoServ *topo.Server + SrvTopo srvtopo.Server + Dbcfgs *dbconfigs.DBConfigs + Mysqld *mysqlctl.Mysqld + SchemaEngine *schema.Engine +} + +type checker struct{} + +var _ = connpool.MySQLChecker(checker{}) + +func (checker) CheckMySQL() {} + +// Init initializes an Env. +func Init() (*Env, error) { + te := &Env{ + KeyspaceName: "vttest", + Cells: []string{"cell1"}, + } + + ctx := context.Background() + te.TopoServ = memorytopo.NewServer(te.Cells...) + if err := te.TopoServ.CreateKeyspace(ctx, te.KeyspaceName, &topodatapb.Keyspace{}); err != nil { + return nil, err + } + te.SrvTopo = srvtopo.NewResilientServer(te.TopoServ, "TestTopo") + + cfg := vttest.Config{ + Topology: &vttestpb.VTTestTopology{ + Keyspaces: []*vttestpb.Keyspace{ + { + Name: te.KeyspaceName, + Shards: []*vttestpb.Shard{ + { + Name: "0", + DbNameOverride: "vttest", + }, + }, + }, + }, + }, + ExtraMyCnf: []string{path.Join(os.Getenv("VTTOP"), "config/mycnf/rbr.cnf")}, + OnlyMySQL: true, + } + te.cluster = &vttest.LocalCluster{ + Config: cfg, + } + if err := te.cluster.Setup(); err != nil { + os.RemoveAll(te.cluster.Config.SchemaDir) + return nil, fmt.Errorf("could not launch mysql: %v", err) + } + + te.Dbcfgs = dbconfigs.NewTestDBConfigs(te.cluster.MySQLConnParams(), te.cluster.MySQLAppDebugConnParams(), te.cluster.DbName()) + te.Mysqld = mysqlctl.NewMysqld(te.Dbcfgs) + te.SchemaEngine = schema.NewEngine(checker{}, tabletenv.DefaultQsConfig) + te.SchemaEngine.InitDBConfig(te.Dbcfgs) + + // The first vschema should not be empty. Leads to Node not found error. + // TODO(sougou): need to fix the bug. + if err := te.SetVSchema(`{"sharded": true}`); err != nil { + te.Close() + return nil, err + } + + return te, nil +} + +// Close tears down TestEnv. +func (te *Env) Close() { + te.SchemaEngine.Close() + te.Mysqld.Close() + te.cluster.TearDown() + os.RemoveAll(te.cluster.Config.SchemaDir) +} + +// SetVSchema sets the vschema for the test keyspace. +func (te *Env) SetVSchema(vs string) error { + ctx := context.Background() + logger := logutil.NewConsoleLogger() + var kspb vschemapb.Keyspace + if err := json2.Unmarshal([]byte(vs), &kspb); err != nil { + return err + } + if err := te.TopoServ.SaveVSchema(ctx, te.KeyspaceName, &kspb); err != nil { + return err + } + return topotools.RebuildVSchema(ctx, logger, te.TopoServ, te.Cells) +} diff --git a/go/vt/vttablet/tabletserver/vstreamer/vstreamer_test.go b/go/vt/vttablet/tabletserver/vstreamer/vstreamer_test.go index 55e68399286..03dfe5470ba 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/vstreamer_test.go +++ b/go/vt/vttablet/tabletserver/vstreamer/vstreamer_test.go @@ -199,10 +199,10 @@ func TestREKeyrange(t *testing.T) { } ch := startStream(ctx, t, filter) - if err := setVSchema(shardedVSchema); err != nil { + if err := env.SetVSchema(shardedVSchema); err != nil { t.Fatal(err) } - defer setVSchema("{}") + defer env.SetVSchema("{}") // 1, 2, 3 and 5 are in shard -80. // 4 and 6 are in shard 80-. @@ -249,7 +249,7 @@ func TestREKeyrange(t *testing.T) { } } }` - if err := setVSchema(altVSchema); err != nil { + if err := env.SetVSchema(altVSchema); err != nil { t.Fatal(err) } @@ -719,7 +719,7 @@ func TestJSON(t *testing.T) { } // JSON is supported only after mysql57. - if err := mysqld.ExecuteSuperQuery(context.Background(), "create table vitess_json(id int default 1, val json, primary key(id))"); err != nil { + if err := env.Mysqld.ExecuteSuperQuery(context.Background(), "create table vitess_json(id int default 1, val json, primary key(id))"); err != nil { // If it's a syntax error, MySQL is an older version. Skip this test. if strings.Contains(err.Error(), "syntax") { return @@ -954,21 +954,21 @@ func vstream(ctx context.Context, t *testing.T, pos string, filter *binlogdatapb func execStatement(t *testing.T, query string) { t.Helper() - if err := mysqld.ExecuteSuperQuery(context.Background(), query); err != nil { + if err := env.Mysqld.ExecuteSuperQuery(context.Background(), query); err != nil { t.Fatal(err) } } func execStatements(t *testing.T, queries []string) { t.Helper() - if err := mysqld.ExecuteSuperQueryList(context.Background(), queries); err != nil { + if err := env.Mysqld.ExecuteSuperQueryList(context.Background(), queries); err != nil { t.Fatal(err) } } func masterPosition(t *testing.T) string { t.Helper() - pos, err := mysqld.MasterPosition() + pos, err := env.Mysqld.MasterPosition() if err != nil { t.Fatal(err) } From 226aff463b514e48269bd3937986c997b12d61c4 Mon Sep 17 00:00:00 2001 From: Sugu Sougoumarane Date: Thu, 10 Jan 2019 10:53:13 -0800 Subject: [PATCH 062/115] vreplication: preliminary vplayer tests Signed-off-by: Sugu Sougoumarane --- .../fakemysqldaemon/fakemysqldaemon.go | 5 + go/vt/mysqlctl/mysql_daemon.go | 1 + .../tabletmanager/vreplication/controller.go | 12 +- .../vreplication/controller_test.go | 69 +++++---- .../tabletmanager/vreplication/engine_test.go | 52 ++++--- .../vreplication/framework_test.go | 131 ++++++++++-------- .../tabletmanager/vreplication/player_plan.go | 8 +- .../vreplication/tablet_picker_test.go | 39 +++--- .../tabletmanager/vreplication/vplayer.go | 19 +-- .../vreplication/vplayer_test.go | 125 +++++++++++++++++ .../tabletserver/vstreamer/testenv/testenv.go | 5 + .../tabletserver/vstreamer/vstreamer.go | 3 + 12 files changed, 314 insertions(+), 155 deletions(-) create mode 100644 go/vt/vttablet/tabletmanager/vreplication/vplayer_test.go diff --git a/go/vt/mysqlctl/fakemysqldaemon/fakemysqldaemon.go b/go/vt/mysqlctl/fakemysqldaemon/fakemysqldaemon.go index a7d945f06b6..e2dda296fb0 100644 --- a/go/vt/mysqlctl/fakemysqldaemon/fakemysqldaemon.go +++ b/go/vt/mysqlctl/fakemysqldaemon/fakemysqldaemon.go @@ -383,6 +383,11 @@ func (fmd *FakeMysqlDaemon) GetSchema(dbName string, tables, excludeTables []str return tmutils.FilterTables(fmd.Schema, tables, excludeTables, includeViews) } +// GetPrimaryKeyColumns is part of the MysqlDaemon interface +func (fmd *FakeMysqlDaemon) GetPrimaryKeyColumns(dbName, table string) ([]string, error) { + return []string{}, nil +} + // PreflightSchemaChange is part of the MysqlDaemon interface func (fmd *FakeMysqlDaemon) PreflightSchemaChange(dbName string, changes []string) ([]*tabletmanagerdatapb.SchemaChangeResult, error) { if fmd.PreflightSchemaChangeResult == nil { diff --git a/go/vt/mysqlctl/mysql_daemon.go b/go/vt/mysqlctl/mysql_daemon.go index c8426e8915b..49b30dbf65e 100644 --- a/go/vt/mysqlctl/mysql_daemon.go +++ b/go/vt/mysqlctl/mysql_daemon.go @@ -69,6 +69,7 @@ type MysqlDaemon interface { // Schema related methods GetSchema(dbName string, tables, excludeTables []string, includeViews bool) (*tabletmanagerdatapb.SchemaDefinition, 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/vttablet/tabletmanager/vreplication/controller.go b/go/vt/vttablet/tabletmanager/vreplication/controller.go index 3379ba39743..200492e0cdf 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/controller.go +++ b/go/vt/vttablet/tabletmanager/vreplication/controller.go @@ -169,7 +169,8 @@ func (ct *controller) runBlp(ctx context.Context) (err error) { } ct.sourceTablet.Set(tablet.Alias.String()) - if len(ct.source.Tables) > 0 { + switch { + case len(ct.source.Tables) > 0: // Table names can have search patterns. Resolve them against the schema. tables, err := mysqlctl.ResolveTables(ct.mysqld, dbClient.DBName(), ct.source.Tables) if err != nil { @@ -178,9 +179,14 @@ func (ct *controller) runBlp(ctx context.Context) (err error) { player := binlogplayer.NewBinlogPlayerTables(dbClient, tablet, tables, ct.id, ct.blpStats) return player.ApplyBinlogEvents(ctx) + case ct.source.KeyRange != nil: + player := binlogplayer.NewBinlogPlayerKeyRange(dbClient, tablet, ct.source.KeyRange, ct.id, ct.blpStats) + return player.ApplyBinlogEvents(ctx) + case ct.source.Filter != nil: + player := newVPlayer(ct.id, &ct.source, tablet, ct.blpStats, dbClient, ct.mysqld) + return player.Play(ctx) } - player := binlogplayer.NewBinlogPlayerKeyRange(dbClient, tablet, ct.source.KeyRange, ct.id, ct.blpStats) - return player.ApplyBinlogEvents(ctx) + return fmt.Errorf("missing source") } func (ct *controller) Stop() { diff --git a/go/vt/vttablet/tabletmanager/vreplication/controller_test.go b/go/vt/vttablet/tabletmanager/vreplication/controller_test.go index 52c2a0f0b69..e261444ee6c 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/controller_test.go +++ b/go/vt/vttablet/tabletmanager/vreplication/controller_test.go @@ -18,6 +18,7 @@ package vreplication import ( "errors" + "fmt" "testing" "time" @@ -51,14 +52,14 @@ var ( ) func TestControllerKeyRange(t *testing.T) { - ts := createTopo() - fbc := newFakeBinlogClient() - wantTablet := addTablet(ts, 100, "0", topodatapb.TabletType_REPLICA, true, true) + resetBinlogClient() + wantTablet := addTablet(100, "0", topodatapb.TabletType_REPLICA, true, true) + defer deleteTablet(wantTablet) params := map[string]string{ "id": "1", "state": binlogplayer.BlpRunning, - "source": `keyspace:"ks" shard:"0" key_range: `, + "source": fmt.Sprintf(`keyspace:"%s" shard:"0" key_range: `, env.KeyspaceName), } dbClient := binlogplayer.NewMockDBClient(t) @@ -72,7 +73,7 @@ func TestControllerKeyRange(t *testing.T) { dbClientFactory := func() binlogplayer.DBClient { return dbClient } mysqld := &fakemysqldaemon.FakeMysqlDaemon{MysqlPort: 3306} - ct, err := newController(context.Background(), params, dbClientFactory, mysqld, ts, testCell, "replica", nil) + ct, err := newController(context.Background(), params, dbClientFactory, mysqld, env.TopoServ, env.Cells[0], "replica", nil) if err != nil { t.Fatal(err) } @@ -82,18 +83,18 @@ func TestControllerKeyRange(t *testing.T) { }() dbClient.Wait() - expectFBCRequest(t, fbc, wantTablet, testPos, nil, &topodatapb.KeyRange{End: []byte{0x80}}) + expectFBCRequest(t, wantTablet, testPos, nil, &topodatapb.KeyRange{End: []byte{0x80}}) } func TestControllerTables(t *testing.T) { - ts := createTopo() - wantTablet := addTablet(ts, 100, "0", topodatapb.TabletType_REPLICA, true, true) - fbc := newFakeBinlogClient() + wantTablet := addTablet(100, "0", topodatapb.TabletType_REPLICA, true, true) + defer deleteTablet(wantTablet) + resetBinlogClient() params := map[string]string{ "id": "1", "state": binlogplayer.BlpRunning, - "source": `keyspace:"ks" shard:"0" tables:"table1" tables:"/funtables_/" `, + "source": fmt.Sprintf(`keyspace:"%s" shard:"0" tables:"table1" tables:"/funtables_/" `, env.KeyspaceName), } dbClient := binlogplayer.NewMockDBClient(t) @@ -132,7 +133,7 @@ func TestControllerTables(t *testing.T) { }, } - ct, err := newController(context.Background(), params, dbClientFactory, mysqld, ts, testCell, "replica", nil) + ct, err := newController(context.Background(), params, dbClientFactory, mysqld, env.TopoServ, env.Cells[0], "replica", nil) if err != nil { t.Fatal(err) } @@ -142,7 +143,7 @@ func TestControllerTables(t *testing.T) { }() dbClient.Wait() - expectFBCRequest(t, fbc, wantTablet, testPos, []string{"table1", "funtables_one"}, nil) + expectFBCRequest(t, wantTablet, testPos, []string{"table1", "funtables_one"}, nil) } func TestControllerBadID(t *testing.T) { @@ -176,15 +177,15 @@ func TestControllerStopped(t *testing.T) { } func TestControllerOverrides(t *testing.T) { - ts := createTopo() - fbc := newFakeBinlogClient() - wantTablet := addTablet(ts, 100, "0", topodatapb.TabletType_REPLICA, true, true) + resetBinlogClient() + wantTablet := addTablet(100, "0", topodatapb.TabletType_REPLICA, true, true) + defer deleteTablet(wantTablet) params := map[string]string{ "id": "1", "state": binlogplayer.BlpRunning, - "source": `keyspace:"ks" shard:"0" key_range: `, - "cell": testCell, + "source": fmt.Sprintf(`keyspace:"%s" shard:"0" key_range: `, env.KeyspaceName), + "cell": env.Cells[0], "tablet_types": "replica", } @@ -199,7 +200,7 @@ func TestControllerOverrides(t *testing.T) { dbClientFactory := func() binlogplayer.DBClient { return dbClient } mysqld := &fakemysqldaemon.FakeMysqlDaemon{MysqlPort: 3306} - ct, err := newController(context.Background(), params, dbClientFactory, mysqld, ts, testCell, "rdonly", nil) + ct, err := newController(context.Background(), params, dbClientFactory, mysqld, env.TopoServ, env.Cells[0], "rdonly", nil) if err != nil { t.Fatal(err) } @@ -209,22 +210,21 @@ func TestControllerOverrides(t *testing.T) { }() dbClient.Wait() - expectFBCRequest(t, fbc, wantTablet, testPos, nil, &topodatapb.KeyRange{End: []byte{0x80}}) + expectFBCRequest(t, wantTablet, testPos, nil, &topodatapb.KeyRange{End: []byte{0x80}}) } func TestControllerCanceledContext(t *testing.T) { - ts := createTopo() - _ = addTablet(ts, 100, "0", topodatapb.TabletType_REPLICA, true, true) + defer deleteTablet(addTablet(100, "0", topodatapb.TabletType_REPLICA, true, true)) params := map[string]string{ "id": "1", "state": binlogplayer.BlpRunning, - "source": `keyspace:"ks" shard:"0" key_range: `, + "source": fmt.Sprintf(`keyspace:"%s" shard:"0" key_range: `, env.KeyspaceName), } ctx, cancel := context.WithCancel(context.Background()) cancel() - ct, err := newController(ctx, params, nil, nil, ts, testCell, "rdonly", nil) + ct, err := newController(ctx, params, nil, nil, env.TopoServ, env.Cells[0], "rdonly", nil) if err != nil { t.Fatal(err) } @@ -242,15 +242,14 @@ func TestControllerRetry(t *testing.T) { defer func() { *retryDelay = savedDelay }() *retryDelay = 10 * time.Millisecond - ts := createTopo() - _ = newFakeBinlogClient() - _ = addTablet(ts, 100, "0", topodatapb.TabletType_REPLICA, true, true) + resetBinlogClient() + defer deleteTablet(addTablet(100, "0", topodatapb.TabletType_REPLICA, true, true)) params := map[string]string{ "id": "1", "state": binlogplayer.BlpRunning, - "source": `keyspace:"ks" shard:"0" key_range: `, - "cell": testCell, + "source": fmt.Sprintf(`keyspace:"%s" shard:"0" key_range: `, env.KeyspaceName), + "cell": env.Cells[0], "tablet_types": "replica", } @@ -267,7 +266,7 @@ func TestControllerRetry(t *testing.T) { dbClientFactory := func() binlogplayer.DBClient { return dbClient } mysqld := &fakemysqldaemon.FakeMysqlDaemon{MysqlPort: 3306} - ct, err := newController(context.Background(), params, dbClientFactory, mysqld, ts, testCell, "rdonly", nil) + ct, err := newController(context.Background(), params, dbClientFactory, mysqld, env.TopoServ, env.Cells[0], "rdonly", nil) if err != nil { t.Fatal(err) } @@ -277,14 +276,14 @@ func TestControllerRetry(t *testing.T) { } func TestControllerStopPosition(t *testing.T) { - ts := createTopo() - fbc := newFakeBinlogClient() - wantTablet := addTablet(ts, 100, "0", topodatapb.TabletType_REPLICA, true, true) + resetBinlogClient() + wantTablet := addTablet(100, "0", topodatapb.TabletType_REPLICA, true, true) + defer deleteTablet(wantTablet) params := map[string]string{ "id": "1", "state": binlogplayer.BlpRunning, - "source": `keyspace:"ks" shard:"0" key_range: `, + "source": fmt.Sprintf(`keyspace:"%s" shard:"0" key_range: `, env.KeyspaceName), } dbClient := binlogplayer.NewMockDBClient(t) @@ -312,7 +311,7 @@ func TestControllerStopPosition(t *testing.T) { dbClientFactory := func() binlogplayer.DBClient { return dbClient } mysqld := &fakemysqldaemon.FakeMysqlDaemon{MysqlPort: 3306} - ct, err := newController(context.Background(), params, dbClientFactory, mysqld, ts, testCell, "replica", nil) + ct, err := newController(context.Background(), params, dbClientFactory, mysqld, env.TopoServ, env.Cells[0], "replica", nil) if err != nil { t.Fatal(err) } @@ -329,5 +328,5 @@ func TestControllerStopPosition(t *testing.T) { } dbClient.Wait() - expectFBCRequest(t, fbc, wantTablet, testPos, nil, &topodatapb.KeyRange{End: []byte{0x80}}) + expectFBCRequest(t, wantTablet, testPos, nil, &topodatapb.KeyRange{End: []byte{0x80}}) } diff --git a/go/vt/vttablet/tabletmanager/vreplication/engine_test.go b/go/vt/vttablet/tabletmanager/vreplication/engine_test.go index f93ec5559e5..5b335a05a9a 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/engine_test.go +++ b/go/vt/vttablet/tabletmanager/vreplication/engine_test.go @@ -17,6 +17,7 @@ limitations under the License. package vreplication import ( + "fmt" "reflect" "testing" "time" @@ -32,16 +33,15 @@ import ( func TestEngineOpen(t *testing.T) { defer func() { globalStats = &vrStats{} }() - ts := createTopo() - _ = addTablet(ts, 100, "0", topodatapb.TabletType_REPLICA, true, true) - _ = newFakeBinlogClient() + defer deleteTablet(addTablet(100, "0", topodatapb.TabletType_REPLICA, true, true)) + resetBinlogClient() dbClient := binlogplayer.NewMockDBClient(t) dbClientFactory := func() binlogplayer.DBClient { return dbClient } mysqld := &fakemysqldaemon.FakeMysqlDaemon{MysqlPort: 3306} // Test Insert - vre := NewEngine(ts, testCell, mysqld, dbClientFactory) + vre := NewEngine(env.TopoServ, env.Cells[0], mysqld, dbClientFactory) if vre.IsOpen() { t.Errorf("IsOpen: %v, want false", vre.IsOpen()) } @@ -51,7 +51,7 @@ func TestEngineOpen(t *testing.T) { "id|state|source", "int64|varchar|varchar", ), - `1|Running|keyspace:"ks" shard:"0" key_range: `, + fmt.Sprintf(`1|Running|keyspace:"%s" shard:"0" key_range: `, env.KeyspaceName), ), nil) dbClient.ExpectRequest("update _vt.vreplication set state='Running', message='' where id=1", testDMLResponse, nil) dbClient.ExpectRequest("select pos, stop_pos, max_tps, max_replication_lag from _vt.vreplication where id=1", testSettingsResponse, nil) @@ -81,16 +81,15 @@ func TestEngineOpen(t *testing.T) { func TestEngineExec(t *testing.T) { defer func() { globalStats = &vrStats{} }() - ts := createTopo() - _ = addTablet(ts, 100, "0", topodatapb.TabletType_REPLICA, true, true) - _ = newFakeBinlogClient() + defer deleteTablet(addTablet(100, "0", topodatapb.TabletType_REPLICA, true, true)) + resetBinlogClient() dbClient := binlogplayer.NewMockDBClient(t) dbClientFactory := func() binlogplayer.DBClient { return dbClient } mysqld := &fakemysqldaemon.FakeMysqlDaemon{MysqlPort: 3306} // Test Insert - vre := NewEngine(ts, testCell, mysqld, dbClientFactory) + vre := NewEngine(env.TopoServ, env.Cells[0], mysqld, dbClientFactory) dbClient.ExpectRequest("select * from _vt.vreplication", &sqltypes.Result{}, nil) if err := vre.Open(context.Background()); err != nil { @@ -105,7 +104,7 @@ func TestEngineExec(t *testing.T) { "id|state|source", "int64|varchar|varchar", ), - `1|Running|keyspace:"ks" shard:"0" key_range: `, + fmt.Sprintf(`1|Running|keyspace:"%s" shard:"0" key_range: `, env.KeyspaceName), ), nil) dbClient.ExpectRequest("update _vt.vreplication set state='Running', message='' where id=1", testDMLResponse, nil) dbClient.ExpectRequest("select pos, stop_pos, max_tps, max_replication_lag from _vt.vreplication where id=1", testSettingsResponse, nil) @@ -145,7 +144,7 @@ func TestEngineExec(t *testing.T) { "id|state|source", "int64|varchar|varchar", ), - `1|Running|keyspace:"ks" shard:"0" key_range: `, + fmt.Sprintf(`1|Running|keyspace:"%s" shard:"0" key_range: `, env.KeyspaceName), ), nil) dbClient.ExpectRequest("update _vt.vreplication set state='Running', message='' where id=1", testDMLResponse, nil) dbClient.ExpectRequest("select pos, stop_pos, max_tps, max_replication_lag from _vt.vreplication where id=1", testSettingsResponse, nil) @@ -206,15 +205,14 @@ func TestEngineExec(t *testing.T) { func TestEngineBadInsert(t *testing.T) { defer func() { globalStats = &vrStats{} }() - ts := createTopo() - _ = addTablet(ts, 100, "0", topodatapb.TabletType_REPLICA, true, true) - _ = newFakeBinlogClient() + defer deleteTablet(addTablet(100, "0", topodatapb.TabletType_REPLICA, true, true)) + resetBinlogClient() dbClient := binlogplayer.NewMockDBClient(t) dbClientFactory := func() binlogplayer.DBClient { return dbClient } mysqld := &fakemysqldaemon.FakeMysqlDaemon{MysqlPort: 3306} - vre := NewEngine(ts, testCell, mysqld, dbClientFactory) + vre := NewEngine(env.TopoServ, env.Cells[0], mysqld, dbClientFactory) dbClient.ExpectRequest("select * from _vt.vreplication", &sqltypes.Result{}, nil) if err := vre.Open(context.Background()); err != nil { @@ -237,15 +235,14 @@ func TestEngineBadInsert(t *testing.T) { } func TestEngineSelect(t *testing.T) { - ts := createTopo() - _ = addTablet(ts, 100, "0", topodatapb.TabletType_REPLICA, true, true) - _ = newFakeBinlogClient() + defer deleteTablet(addTablet(100, "0", topodatapb.TabletType_REPLICA, true, true)) + resetBinlogClient() dbClient := binlogplayer.NewMockDBClient(t) dbClientFactory := func() binlogplayer.DBClient { return dbClient } mysqld := &fakemysqldaemon.FakeMysqlDaemon{MysqlPort: 3306} - vre := NewEngine(ts, testCell, mysqld, dbClientFactory) + vre := NewEngine(env.TopoServ, env.Cells[0], mysqld, dbClientFactory) dbClient.ExpectRequest("select * from _vt.vreplication", &sqltypes.Result{}, nil) if err := vre.Open(context.Background()); err != nil { @@ -260,7 +257,7 @@ func TestEngineSelect(t *testing.T) { "id|state|source|pos", "int64|varchar|varchar|varchar", ), - `1|Running|keyspace:"ks" shard:"0" key_range: |MariaDB/0-1-1083`, + fmt.Sprintf(`1|Running|keyspace:"%s" shard:"0" key_range: |MariaDB/0-1-1083`, env.KeyspaceName), ) dbClient.ExpectRequest(wantQuery, wantResult, nil) qr, err := vre.Exec(wantQuery) @@ -280,7 +277,7 @@ func TestWaitForPos(t *testing.T) { dbClient := binlogplayer.NewMockDBClient(t) mysqld := &fakemysqldaemon.FakeMysqlDaemon{MysqlPort: 3306} dbClientFactory := func() binlogplayer.DBClient { return dbClient } - vre := NewEngine(createTopo(), testCell, mysqld, dbClientFactory) + vre := NewEngine(env.TopoServ, env.Cells[0], mysqld, dbClientFactory) dbClient.ExpectRequest("select * from _vt.vreplication", &sqltypes.Result{}, nil) if err := vre.Open(context.Background()); err != nil { @@ -306,7 +303,7 @@ func TestWaitForPosError(t *testing.T) { dbClient := binlogplayer.NewMockDBClient(t) mysqld := &fakemysqldaemon.FakeMysqlDaemon{MysqlPort: 3306} dbClientFactory := func() binlogplayer.DBClient { return dbClient } - vre := NewEngine(createTopo(), testCell, mysqld, dbClientFactory) + vre := NewEngine(env.TopoServ, env.Cells[0], mysqld, dbClientFactory) err := vre.WaitForPos(context.Background(), 1, "MariaDB/0-1-1084") want := `vreplication engine is closed` @@ -348,7 +345,7 @@ func TestWaitForPosCancel(t *testing.T) { dbClient := binlogplayer.NewMockDBClient(t) mysqld := &fakemysqldaemon.FakeMysqlDaemon{MysqlPort: 3306} dbClientFactory := func() binlogplayer.DBClient { return dbClient } - vre := NewEngine(createTopo(), testCell, mysqld, dbClientFactory) + vre := NewEngine(env.TopoServ, env.Cells[0], mysqld, dbClientFactory) dbClient.ExpectRequest("select * from _vt.vreplication", &sqltypes.Result{}, nil) if err := vre.Open(context.Background()); err != nil { @@ -383,16 +380,15 @@ func TestWaitForPosCancel(t *testing.T) { func TestCreateDBAndTable(t *testing.T) { defer func() { globalStats = &vrStats{} }() - ts := createTopo() - _ = addTablet(ts, 100, "0", topodatapb.TabletType_REPLICA, true, true) - _ = newFakeBinlogClient() + defer deleteTablet(addTablet(100, "0", topodatapb.TabletType_REPLICA, true, true)) + resetBinlogClient() dbClient := binlogplayer.NewMockDBClient(t) dbClientFactory := func() binlogplayer.DBClient { return dbClient } mysqld := &fakemysqldaemon.FakeMysqlDaemon{MysqlPort: 3306} // Test Insert - vre := NewEngine(ts, testCell, mysqld, dbClientFactory) + vre := NewEngine(env.TopoServ, env.Cells[0], mysqld, dbClientFactory) tableNotFound := mysql.SQLError{Num: 1146, Message: "table not found"} dbClient.ExpectRequest("select * from _vt.vreplication", nil, &tableNotFound) @@ -432,7 +428,7 @@ func TestCreateDBAndTable(t *testing.T) { "id|state|source", "int64|varchar|varchar", ), - `1|Running|keyspace:"ks" shard:"0" key_range: `, + fmt.Sprintf(`1|Running|keyspace:"%s" shard:"0" key_range: `, env.KeyspaceName), ), nil) dbClient.ExpectRequest("update _vt.vreplication set state='Running', message='' where id=1", testDMLResponse, nil) dbClient.ExpectRequest("select pos, stop_pos, max_tps, max_replication_lag from _vt.vreplication where id=1", testSettingsResponse, nil) diff --git a/go/vt/vttablet/tabletmanager/vreplication/framework_test.go b/go/vt/vttablet/tabletmanager/vreplication/framework_test.go index 559f285e1ff..c8ef077e56f 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/framework_test.go +++ b/go/vt/vttablet/tabletmanager/vreplication/framework_test.go @@ -18,6 +18,8 @@ package vreplication import ( "flag" + "fmt" + "os" "reflect" "testing" @@ -27,49 +29,83 @@ import ( "vitess.io/vitess/go/vt/binlog/binlogplayer" "vitess.io/vitess/go/vt/grpcclient" "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/tabletserver/vstreamer" + "vitess.io/vitess/go/vt/vttablet/tabletserver/vstreamer/testenv" binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" querypb "vitess.io/vitess/go/vt/proto/query" topodatapb "vitess.io/vitess/go/vt/proto/topodata" ) -const ( - testCell = "cell" - testKeyspace = "ks" - testShard = "0" +var ( + engine *vstreamer.Engine + env *testenv.Env + globalFBC = &fakeBinlogClient{} ) -// This file provides support functions for tests. -// It's capable of creating a single unsharded keyspace -// and allows you to add various tablet types. +func init() { + tabletconn.RegisterDialer("test", func(tablet *topodatapb.Tablet, failFast grpcclient.FailFast) (queryservice.QueryService, error) { + return &fakeTabletConn{ + QueryService: fakes.ErrorQueryService, + tablet: tablet, + }, nil + }) + flag.Set("tablet_protocol", "test") -//-------------------------------------- -// Topos and tablets + binlogplayer.RegisterClientFactory("test", func() binlogplayer.Client { return globalFBC }) + flag.Set("binlog_player_protocol", "test") +} -func createTopo() *topo.Server { - ts := memorytopo.NewServer(testCell) - ctx := context.Background() - if err := ts.CreateKeyspace(ctx, testKeyspace, &topodatapb.Keyspace{}); err != nil { - panic(err) - } - if err := ts.CreateShard(ctx, testKeyspace, testShard); err != nil { - panic(err) +func TestMain(m *testing.M) { + flag.Parse() // Do not remove this comment, import into google3 depends on it + + if testing.Short() { + os.Exit(m.Run()) } - return ts + + exitCode := func() int { + var err error + env, err = testenv.Init() + if err != nil { + fmt.Fprintf(os.Stderr, "%v", err) + return 1 + } + defer env.Close() + + // engine cannot be initialized in testenv because it introduces + // circular dependencies. + engine = vstreamer.NewEngine(env.SrvTopo, env.SchemaEngine) + engine.InitDBConfig(env.Dbcfgs) + engine.Open(env.KeyspaceName, env.Cells[0]) + defer engine.Close() + + return m.Run() + }() + os.Exit(exitCode) +} + +func resetBinlogClient() { + globalFBC = &fakeBinlogClient{} } -func addTablet(ts *topo.Server, id int, shard string, tabletType topodatapb.TabletType, serving, healthy bool) *topodatapb.Tablet { +//-------------------------------------- +// 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 := ts.CreateTablet(context.Background(), t); err != nil { + 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) +} + func newTablet(id int, shard string, tabletType topodatapb.TabletType, serving, healthy bool) *topodatapb.Tablet { stag := "not_serving" if serving { @@ -85,11 +121,11 @@ func newTablet(id int, shard string, tabletType topodatapb.TabletType, serving, } return &topodatapb.Tablet{ Alias: &topodatapb.TabletAlias{ - Cell: testCell, + Cell: env.Cells[0], Uid: uint32(id), }, - Keyspace: testKeyspace, - Shard: testShard, + Keyspace: env.KeyspaceName, + Shard: env.ShardName, KeyRange: kr, Type: tabletType, Tags: map[string]string{ @@ -132,6 +168,11 @@ func (ftc *fakeTabletConn) StreamHealth(ctx context.Context, callback func(*quer return nil } +// VStream directly calls into the pre-initialized engine. +func (ftc *fakeTabletConn) VStream(ctx context.Context, target *querypb.Target, startPos string, filter *binlogdatapb.Filter, send func([]*binlogdatapb.VEvent) error) error { + return engine.Stream(ctx, startPos, filter, send) +} + //-------------------------------------- // Binlog Client to TabletManager @@ -145,11 +186,6 @@ type fakeBinlogClient struct { lastCharset *binlogdatapb.Charset } -func newFakeBinlogClient() *fakeBinlogClient { - globalFBC = &fakeBinlogClient{} - return globalFBC -} - func (fbc *fakeBinlogClient) Dial(tablet *topodatapb.Tablet) error { fbc.lastTablet = tablet return nil @@ -198,37 +234,18 @@ func (t *btStream) Recv() (*binlogdatapb.BinlogTransaction, error) { return nil, t.ctx.Err() } -func expectFBCRequest(t *testing.T, fbc *fakeBinlogClient, tablet *topodatapb.Tablet, pos string, tables []string, kr *topodatapb.KeyRange) { +func expectFBCRequest(t *testing.T, tablet *topodatapb.Tablet, pos string, tables []string, kr *topodatapb.KeyRange) { t.Helper() - if !proto.Equal(tablet, fbc.lastTablet) { - t.Errorf("Request tablet: %v, want %v", fbc.lastTablet, tablet) + if !proto.Equal(tablet, globalFBC.lastTablet) { + t.Errorf("Request tablet: %v, want %v", globalFBC.lastTablet, tablet) } - if pos != fbc.lastPos { - t.Errorf("Request pos: %v, want %v", fbc.lastPos, pos) + if pos != globalFBC.lastPos { + t.Errorf("Request pos: %v, want %v", globalFBC.lastPos, pos) } - if !reflect.DeepEqual(tables, fbc.lastTables) { - t.Errorf("Request tables: %v, want %v", fbc.lastTables, tables) + if !reflect.DeepEqual(tables, globalFBC.lastTables) { + t.Errorf("Request tables: %v, want %v", globalFBC.lastTables, tables) } - if !proto.Equal(kr, fbc.lastKeyRange) { - t.Errorf("Request KeyRange: %v, want %v", fbc.lastKeyRange, kr) + if !proto.Equal(kr, globalFBC.lastKeyRange) { + t.Errorf("Request KeyRange: %v, want %v", globalFBC.lastKeyRange, kr) } } - -//-------------------------------------- -// init - -// globalFBC is set by newFakeBinlogClient, which is then returned by the client factory below. -var globalFBC *fakeBinlogClient - -func init() { - tabletconn.RegisterDialer("test", func(tablet *topodatapb.Tablet, failFast grpcclient.FailFast) (queryservice.QueryService, error) { - return &fakeTabletConn{ - QueryService: fakes.ErrorQueryService, - tablet: tablet, - }, nil - }) - flag.Set("tablet_protocol", "test") - - binlogplayer.RegisterClientFactory("test", func() binlogplayer.Client { return globalFBC }) - flag.Set("binlog_player_protocol", "test") -} diff --git a/go/vt/vttablet/tabletmanager/vreplication/player_plan.go b/go/vt/vttablet/tabletmanager/vreplication/player_plan.go index 67b7c566972..25100ae3773 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/player_plan.go +++ b/go/vt/vttablet/tabletmanager/vreplication/player_plan.go @@ -92,7 +92,7 @@ func buildPlayerPlan(filter *binlogdatapb.Filter) (*playerPlan, error) { continue } plan.vstreamFilter.Rules[i] = sendRule - plan.tablePlans[rule.Match] = tplan + plan.tablePlans[sendRule.Match] = tplan } return plan, nil } @@ -129,7 +129,9 @@ func buildTablePlan(rule *binlogdatapb.Rule) (*binlogdatapb.Rule, *tablePlan, er return sendRule, &tablePlan{name: rule.Match}, nil } - tplan := &tablePlan{} + tplan := &tablePlan{ + name: rule.Match, + } sendSelect := &sqlparser.Select{ From: sel.From, Where: sel.Where, @@ -159,7 +161,7 @@ func buildTablePlan(rule *binlogdatapb.Rule) (*binlogdatapb.Rule, *tablePlan, er } } sendRule := &binlogdatapb.Rule{ - Match: rule.Match, + Match: fromTable.String(), Filter: sqlparser.String(sendSelect), } return sendRule, tplan, nil diff --git a/go/vt/vttablet/tabletmanager/vreplication/tablet_picker_test.go b/go/vt/vttablet/tabletmanager/vreplication/tablet_picker_test.go index 3bbec75cb5e..e3e4daf5e7b 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/tablet_picker_test.go +++ b/go/vt/vttablet/tabletmanager/vreplication/tablet_picker_test.go @@ -17,6 +17,7 @@ limitations under the License. package vreplication import ( + "fmt" "testing" "github.com/golang/protobuf/proto" @@ -26,11 +27,10 @@ import ( ) func TestPickSimple(t *testing.T) { - ts := createTopo() - defer ts.Close() - want := addTablet(ts, 100, "0", topodatapb.TabletType_REPLICA, true, true) + want := addTablet(100, "0", topodatapb.TabletType_REPLICA, true, true) + defer deleteTablet(want) - tp, err := newTabletPicker(ts, testCell, testKeyspace, testShard, "replica") + tp, err := newTabletPicker(env.TopoServ, env.Cells[0], env.KeyspaceName, env.ShardName, "replica") if err != nil { t.Fatal(err) } @@ -46,12 +46,12 @@ func TestPickSimple(t *testing.T) { } func TestPickFromTwoHealthy(t *testing.T) { - ts := createTopo() - defer ts.Close() - want1 := addTablet(ts, 100, "0", topodatapb.TabletType_REPLICA, true, true) - want2 := addTablet(ts, 101, "0", topodatapb.TabletType_RDONLY, true, true) + 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(ts, testCell, testKeyspace, testShard, "replica,rdonly") + tp, err := newTabletPicker(env.TopoServ, env.Cells[0], env.KeyspaceName, env.ShardName, "replica,rdonly") if err != nil { t.Fatal(err) } @@ -65,7 +65,7 @@ func TestPickFromTwoHealthy(t *testing.T) { t.Errorf("Pick:\n%v, want\n%v", tablet, want1) } - tp, err = newTabletPicker(ts, testCell, testKeyspace, testShard, "rdonly,replica") + tp, err = newTabletPicker(env.TopoServ, env.Cells[0], env.KeyspaceName, env.ShardName, "rdonly,replica") if err != nil { t.Fatal(err) } @@ -81,12 +81,11 @@ func TestPickFromTwoHealthy(t *testing.T) { } func TestPickFromSomeUnhealthy(t *testing.T) { - ts := createTopo() - defer ts.Close() - _ = addTablet(ts, 100, "0", topodatapb.TabletType_REPLICA, false, false) - want := addTablet(ts, 101, "0", topodatapb.TabletType_RDONLY, false, true) + 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(ts, testCell, testKeyspace, testShard, "replica,rdonly") + tp, err := newTabletPicker(env.TopoServ, env.Cells[0], env.KeyspaceName, env.ShardName, "replica,rdonly") if err != nil { t.Fatal(err) } @@ -102,24 +101,22 @@ func TestPickFromSomeUnhealthy(t *testing.T) { } func TestPickError(t *testing.T) { - ts := createTopo() - defer ts.Close() - _ = addTablet(ts, 100, "0", topodatapb.TabletType_REPLICA, false, false) + defer deleteTablet(addTablet(100, "0", topodatapb.TabletType_REPLICA, false, false)) - _, err := newTabletPicker(ts, testCell, testKeyspace, testShard, "badtype") + _, err := newTabletPicker(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(ts, testCell, testKeyspace, testShard, "replica,rdonly") + tp, err := newTabletPicker(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 = "can't find any healthy source tablet for ks 0 [REPLICA RDONLY]" + 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/vplayer.go b/go/vt/vttablet/tabletmanager/vreplication/vplayer.go index 26bc1479acd..19fd8e08967 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/vplayer.go +++ b/go/vt/vttablet/tabletmanager/vreplication/vplayer.go @@ -44,7 +44,7 @@ type vplayer struct { sourceTablet *topodatapb.Tablet stats *binlogplayer.Stats dbClient binlogplayer.DBClient - mysqld *mysqlctl.Mysqld + mysqld mysqlctl.MysqlDaemon pos mysql.Position stopPos mysql.Position @@ -54,7 +54,7 @@ type vplayer struct { retryDelay time.Duration } -func newVPlayer(id uint32, source *binlogdatapb.BinlogSource, sourceTablet *topodatapb.Tablet, stats *binlogplayer.Stats, dbClient binlogplayer.DBClient, mysqld *mysqlctl.Mysqld) *vplayer { +func newVPlayer(id uint32, source *binlogdatapb.BinlogSource, sourceTablet *topodatapb.Tablet, stats *binlogplayer.Stats, dbClient binlogplayer.DBClient, mysqld mysqlctl.MysqlDaemon) *vplayer { return &vplayer{ id: id, source: source, @@ -63,6 +63,7 @@ func newVPlayer(id uint32, source *binlogdatapb.BinlogSource, sourceTablet *topo dbClient: dbClient, mysqld: mysqld, retryDelay: 1 * time.Second, + tplans: make(map[string]*tablePlan), } } @@ -107,6 +108,7 @@ func (vp *vplayer) play(ctx context.Context) error { if err != nil { return err } + vp.pplan = plan vsClient, err := tabletconn.GetDialer()(vp.sourceTablet, grpcclient.FailFast(false)) if err != nil { @@ -133,6 +135,7 @@ func (vp *vplayer) play(ctx context.Context) error { } func (vp *vplayer) applyEvent(event *binlogdatapb.VEvent) error { + fmt.Printf("applying: %v\n", event) switch event.Type { case binlogdatapb.VEventType_GTID: pos, err := mysql.DecodePosition(event.Gtid) @@ -279,7 +282,7 @@ func (vp *vplayer) updatePlan(fieldEvent *binlogdatapb.FieldEvent) error { func (vp *vplayer) applyRowEvent(rowEvent *binlogdatapb.RowEvent) error { tplan := vp.tplans[rowEvent.TableName] - if tplan != nil { + if tplan == nil { return fmt.Errorf("unexpected event on table %s", rowEvent.TableName) } for _, change := range rowEvent.RowChanges { @@ -316,9 +319,9 @@ func (vp *vplayer) applyRowChange(tplan *tablePlan, rowChange *binlogdatapb.RowC func (vp *vplayer) generateInsert(tplan *tablePlan, after []sqltypes.Value) string { sql := sqlparser.NewTrackedBuffer(nil) if tplan.onInsert == insertIgnore { - sql.Myprintf("insert ignore into %s set ", sqlparser.NewTableIdent(tplan.name)) + sql.Myprintf("insert ignore into %v set ", sqlparser.NewTableIdent(tplan.name)) } else { - sql.Myprintf("insert into %s set ", sqlparser.NewTableIdent(tplan.name)) + sql.Myprintf("insert into %v set ", sqlparser.NewTableIdent(tplan.name)) } vp.writeInsertValues(sql, tplan, after) if tplan.onInsert == insertOndup { @@ -357,7 +360,7 @@ func (vp *vplayer) generateDelete(tplan *tablePlan, before []sqltypes.Value) str func (vp *vplayer) writeInsertValues(sql *sqlparser.TrackedBuffer, tplan *tablePlan, after []sqltypes.Value) { separator := "" for _, cExpr := range tplan.colExprs { - sql.Myprintf("%s%s=", separator, cExpr.colname) + sql.Myprintf("%s%v=", separator, cExpr.colname) if separator == "" { separator = ", " } @@ -375,7 +378,7 @@ func (vp *vplayer) writeUpdateValues(sql *sqlparser.TrackedBuffer, tplan *tableP if cExpr.isGrouped { continue } - sql.Myprintf("%s%s=", separator, cExpr.colname) + sql.Myprintf("%s%v=", separator, cExpr.colname) if separator == "" { separator = ", " } @@ -412,7 +415,7 @@ func (vp *vplayer) writeUpdateValues(sql *sqlparser.TrackedBuffer, tplan *tableP func (vp *vplayer) writeWhereValues(sql *sqlparser.TrackedBuffer, tplan *tablePlan, before []sqltypes.Value) { separator := "" for _, cExpr := range tplan.pkCols { - sql.Myprintf("%s%s=", separator, cExpr.colname) + sql.Myprintf("%s%v=", separator, cExpr.colname) if separator == "" { separator = " AND " } diff --git a/go/vt/vttablet/tabletmanager/vreplication/vplayer_test.go b/go/vt/vttablet/tabletmanager/vreplication/vplayer_test.go new file mode 100644 index 00000000000..04527d179b6 --- /dev/null +++ b/go/vt/vttablet/tabletmanager/vreplication/vplayer_test.go @@ -0,0 +1,125 @@ +/* +Copyright 2019 The Vitess Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package vreplication + +import ( + "fmt" + "strings" + "testing" + "time" + + "golang.org/x/net/context" + "vitess.io/vitess/go/mysql" + "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" +) + +func TestSimple(t *testing.T) { + defer deleteTablet(addTablet(100, "0", topodatapb.TabletType_REPLICA, true, true)) + + execStatements(t, []string{ + "create table t1(id int, val varbinary(128), primary key(id))", + "create table t2(id int, val varbinary(128), primary key(id))", + }) + defer execStatements(t, []string{ + "drop table t1", + "drop table t2", + }) + env.SchemaEngine.Reload(context.Background()) + vre := NewEngine(env.TopoServ, env.Cells[0], env.Mysqld, realDBClientFactory) + vre.Open(context.Background()) + defer vre.Close() + + bls := &binlogdatapb.BinlogSource{ + Keyspace: env.KeyspaceName, + Shard: env.ShardName, + Filter: &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{{ + Match: "t2", + Filter: "select * from t1", + }}, + }, + } + pos := masterPosition(t) + query := fmt.Sprintf(`insert into _vt.vreplication`+ + `(workflow, source, pos, max_tps, max_replication_lag, time_updated, transaction_timestamp, state)`+ + `values('test', '%v', '%s', 9223372036854775807, 9223372036854775807, 481823, 0, 'Running')`, + bls, pos, + ) + if _, err := vre.Exec(query); err != nil { + t.Fatal(err) + } + execStatements(t, []string{"insert into t1 values(1, 'aaa')"}) + time.Sleep(1 * time.Second) +} + +func execStatements(t *testing.T, queries []string) { + t.Helper() + if err := env.Mysqld.ExecuteSuperQueryList(context.Background(), queries); err != nil { + t.Fatal(err) + } +} + +func masterPosition(t *testing.T) string { + t.Helper() + pos, err := env.Mysqld.MasterPosition() + if err != nil { + t.Fatal(err) + } + return mysql.EncodePosition(pos) +} + +func realDBClientFactory() binlogplayer.DBClient { + return realDBClient{} +} + +type realDBClient struct{} + +func (dbc realDBClient) DBName() string { + return env.KeyspaceName +} + +func (dbc realDBClient) Connect() error { + return nil +} + +func (dbc realDBClient) Begin() error { + return env.Mysqld.ExecuteSuperQueryList(context.Background(), []string{"begin"}) +} + +func (dbc realDBClient) Commit() error { + return env.Mysqld.ExecuteSuperQueryList(context.Background(), []string{"commit"}) +} + +func (dbc realDBClient) Rollback() error { + return env.Mysqld.ExecuteSuperQueryList(context.Background(), []string{"rollback"}) +} + +func (dbc realDBClient) Close() { +} + +func (dbc realDBClient) ExecuteFetch(query string, maxrows int) (qr *sqltypes.Result, err error) { + fmt.Printf("executing: %v\n", query) + if strings.HasPrefix(query, "use") { + return nil, nil + } + return env.Mysqld.FetchSuperQuery(context.Background(), query) +} diff --git a/go/vt/vttablet/tabletserver/vstreamer/testenv/testenv.go b/go/vt/vttablet/tabletserver/vstreamer/testenv/testenv.go index 036bcd2e77f..557fa40a60a 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/testenv/testenv.go +++ b/go/vt/vttablet/tabletserver/vstreamer/testenv/testenv.go @@ -46,6 +46,7 @@ type Env struct { cluster *vttest.LocalCluster KeyspaceName string + ShardName string Cells []string TopoServ *topo.Server @@ -65,6 +66,7 @@ func (checker) CheckMySQL() {} func Init() (*Env, error) { te := &Env{ KeyspaceName: "vttest", + ShardName: "0", Cells: []string{"cell1"}, } @@ -73,6 +75,9 @@ func Init() (*Env, error) { if err := te.TopoServ.CreateKeyspace(ctx, te.KeyspaceName, &topodatapb.Keyspace{}); err != nil { return nil, err } + if err := te.TopoServ.CreateShard(ctx, te.KeyspaceName, te.ShardName); err != nil { + panic(err) + } te.SrvTopo = srvtopo.NewResilientServer(te.TopoServ, "TestTopo") cfg := vttest.Config{ diff --git a/go/vt/vttablet/tabletserver/vstreamer/vstreamer.go b/go/vt/vttablet/tabletserver/vstreamer/vstreamer.go index ade2ced8c32..df3947f4b45 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/vstreamer.go +++ b/go/vt/vttablet/tabletserver/vstreamer/vstreamer.go @@ -138,6 +138,9 @@ func (vs *vstreamer) parseEvents(ctx context.Context, events <-chan mysql.Binlog vevents := bufferedEvents bufferedEvents = nil curSize = 0 + if len(vevents) == 3 && vevents[0].Type == binlogdatapb.VEventType_GTID && vevents[1].Type == binlogdatapb.VEventType_BEGIN && vevents[2].Type == binlogdatapb.VEventType_COMMIT { + vevents = vevents[:1] + } return vs.send(vevents) case binlogdatapb.VEventType_ROW: // ROW events happen inside transactions. So, we can chunk them. From afa7baf9b1e88fb7b598518b5e05929e71bf8284 Mon Sep 17 00:00:00 2001 From: Sugu Sougoumarane Date: Sun, 13 Jan 2019 17:06:00 -0800 Subject: [PATCH 063/115] vreplication: more tweaks Signed-off-by: Sugu Sougoumarane --- .../vreplication/framework_test.go | 103 +++++++++++++++-- .../tabletmanager/vreplication/vplayer.go | 33 +++--- .../vreplication/vplayer_test.go | 105 ++++++++---------- .../tabletserver/vstreamer/planbuilder.go | 55 +++++++++ .../vstreamer/planbuilder_test.go | 81 ++++++++++++++ .../tabletserver/vstreamer/vstreamer.go | 23 ++-- .../tabletserver/vstreamer/vstreamer_test.go | 27 +++++ 7 files changed, 335 insertions(+), 92 deletions(-) diff --git a/go/vt/vttablet/tabletmanager/vreplication/framework_test.go b/go/vt/vttablet/tabletmanager/vreplication/framework_test.go index c8ef077e56f..275f1763306 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/framework_test.go +++ b/go/vt/vttablet/tabletmanager/vreplication/framework_test.go @@ -21,11 +21,15 @@ import ( "fmt" "os" "reflect" + "regexp" + "strings" "testing" + "time" "github.com/golang/protobuf/proto" "golang.org/x/net/context" + "vitess.io/vitess/go/sqltypes" "vitess.io/vitess/go/vt/binlog/binlogplayer" "vitess.io/vitess/go/vt/grpcclient" "vitess.io/vitess/go/vt/topo" @@ -41,9 +45,11 @@ import ( ) var ( - engine *vstreamer.Engine - env *testenv.Env - globalFBC = &fakeBinlogClient{} + playerEngine *Engine + streamerEngine *vstreamer.Engine + env *testenv.Env + globalFBC = &fakeBinlogClient{} + globalDBClient = &realDBClient{} ) func init() { @@ -75,12 +81,16 @@ func TestMain(m *testing.M) { } defer env.Close() - // engine cannot be initialized in testenv because it introduces + // engines cannot be initialized in testenv because it introduces // circular dependencies. - engine = vstreamer.NewEngine(env.SrvTopo, env.SchemaEngine) - engine.InitDBConfig(env.Dbcfgs) - engine.Open(env.KeyspaceName, env.Cells[0]) - defer engine.Close() + streamerEngine = vstreamer.NewEngine(env.SrvTopo, env.SchemaEngine) + streamerEngine.InitDBConfig(env.Dbcfgs) + streamerEngine.Open(env.KeyspaceName, env.Cells[0]) + defer streamerEngine.Close() + + playerEngine = NewEngine(env.TopoServ, env.Cells[0], env.Mysqld, realDBClientFactory) + playerEngine.Open(context.Background()) + defer playerEngine.Close() return m.Run() }() @@ -170,7 +180,7 @@ func (ftc *fakeTabletConn) StreamHealth(ctx context.Context, callback func(*quer // VStream directly calls into the pre-initialized engine. func (ftc *fakeTabletConn) VStream(ctx context.Context, target *querypb.Target, startPos string, filter *binlogdatapb.Filter, send func([]*binlogdatapb.VEvent) error) error { - return engine.Stream(ctx, startPos, filter, send) + return streamerEngine.Stream(ctx, startPos, filter, send) } //-------------------------------------- @@ -249,3 +259,78 @@ func expectFBCRequest(t *testing.T, tablet *topodatapb.Tablet, pos string, table t.Errorf("Request KeyRange: %v, want %v", globalFBC.lastKeyRange, kr) } } + +//-------------------------------------- +// DBCLient wrapper + +func resetDBClient() { + globalDBClient.queries = make(chan string, 1000) +} + +func realDBClientFactory() binlogplayer.DBClient { + resetDBClient() + return globalDBClient +} + +type realDBClient struct { + queries chan string +} + +func (dbc *realDBClient) DBName() string { + return env.KeyspaceName +} + +func (dbc *realDBClient) Connect() error { + return nil +} + +func (dbc *realDBClient) Begin() error { + dbc.queries <- "begin" + return env.Mysqld.ExecuteSuperQueryList(context.Background(), []string{"begin"}) +} + +func (dbc *realDBClient) Commit() error { + dbc.queries <- "commit" + return env.Mysqld.ExecuteSuperQueryList(context.Background(), []string{"commit"}) +} + +func (dbc *realDBClient) Rollback() error { + panic("rollback should never be called") +} + +func (dbc *realDBClient) Close() { +} + +func (dbc *realDBClient) ExecuteFetch(query string, maxrows int) (qr *sqltypes.Result, err error) { + if !strings.HasPrefix(query, "select") { + dbc.queries <- query + } + if strings.HasPrefix(query, "use") { + return nil, nil + } + return env.Mysqld.FetchSuperQuery(context.Background(), query) +} + +func expectDBClientQueries(t *testing.T, queries []string) { + t.Helper() + for i, query := range queries { + var got string + select { + case got = <-globalDBClient.queries: + match, err := regexp.MatchString(query, got) + if err != nil { + panic(err) + } + if !match { + t.Fatalf("query:\n%s, does not match query %d:\n%s", got, i, query) + } + case <-time.After(5 * time.Second): + t.Fatalf("no query received, expecting %s", query) + } + } + select { + case got := <-globalDBClient.queries: + t.Fatalf("unexpected query: %s", got) + default: + } +} diff --git a/go/vt/vttablet/tabletmanager/vreplication/vplayer.go b/go/vt/vttablet/tabletmanager/vreplication/vplayer.go index 19fd8e08967..02938c7479e 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/vplayer.go +++ b/go/vt/vttablet/tabletmanager/vreplication/vplayer.go @@ -135,7 +135,6 @@ func (vp *vplayer) play(ctx context.Context) error { } func (vp *vplayer) applyEvent(event *binlogdatapb.VEvent) error { - fmt.Printf("applying: %v\n", event) switch event.Type { case binlogdatapb.VEventType_GTID: pos, err := mysql.DecodePosition(event.Gtid) @@ -174,13 +173,11 @@ func (vp *vplayer) applyEvent(event *binlogdatapb.VEvent) error { case binlogdatapb.VEventType_DDL: switch vp.source.OnDdl { case binlogdatapb.OnDDLAction_IGNORE: - if err := vp.updatePos(event.Timestamp); err != nil { - return err - } - if err := vp.dbClient.Commit(); err != nil { + // no-op + case binlogdatapb.OnDDLAction_STOP: + if err := vp.dbClient.Begin(); err != nil { return err } - case binlogdatapb.OnDDLAction_STOP: if err := vp.updatePos(event.Timestamp); err != nil { return err } @@ -189,23 +186,17 @@ func (vp *vplayer) applyEvent(event *binlogdatapb.VEvent) error { return err } case binlogdatapb.OnDDLAction_EXEC: - if err := vp.updatePos(event.Timestamp); err != nil { - return err - } if err := vp.exec(event.Ddl); err != nil { return err } - if err := vp.dbClient.Commit(); err != nil { + if err := vp.savePos(event.Timestamp); err != nil { return err } case binlogdatapb.OnDDLAction_EXEC_IGNORE: - if err := vp.updatePos(event.Timestamp); err != nil { - return err - } if err := vp.exec(event.Ddl); err != nil { log.Infof("Ignoring error: %v for DDL: %s", err, event.Ddl) } - if err := vp.dbClient.Commit(); err != nil { + if err := vp.savePos(event.Timestamp); err != nil { return err } } @@ -214,6 +205,8 @@ func (vp *vplayer) applyEvent(event *binlogdatapb.VEvent) error { } func (vp *vplayer) setState(state, message string) { + if state == binlogplayer.BlpStopped { + } if err := binlogplayer.SetVReplicationState(vp.dbClient, vp.id, state, message); err != nil { log.Errorf("Error writing state: %s, msg: %s, err: %v", state, message, err) } @@ -422,6 +415,18 @@ func (vp *vplayer) writeWhereValues(sql *sqlparser.TrackedBuffer, tplan *tablePl encodeValue(sql, before[cExpr.colnum]) } } + +// savePos performs an updatePos in its own transaction. +func (vp *vplayer) savePos(ts int64) error { + if err := vp.dbClient.Begin(); err != nil { + return err + } + if err := vp.updatePos(ts); err != nil { + return err + } + return vp.dbClient.Commit() +} + func (vp *vplayer) updatePos(ts int64) error { updatePos := binlogplayer.GenerateUpdatePos(vp.id, vp.pos, time.Now().Unix(), ts) if _, err := vp.dbClient.ExecuteFetch(updatePos, 0); err != nil { diff --git a/go/vt/vttablet/tabletmanager/vreplication/vplayer_test.go b/go/vt/vttablet/tabletmanager/vreplication/vplayer_test.go index 04527d179b6..11e2d8bc5da 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/vplayer_test.go +++ b/go/vt/vttablet/tabletmanager/vreplication/vplayer_test.go @@ -18,15 +18,10 @@ package vreplication import ( "fmt" - "strings" "testing" - "time" "golang.org/x/net/context" "vitess.io/vitess/go/mysql" - "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" @@ -44,37 +39,62 @@ func TestSimple(t *testing.T) { "drop table t2", }) env.SchemaEngine.Reload(context.Background()) - vre := NewEngine(env.TopoServ, env.Cells[0], env.Mysqld, realDBClientFactory) - vre.Open(context.Background()) - defer vre.Close() + + filter := &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{{ + Match: "t2", + Filter: "select * from t1", + }}, + } + cancel := startVReplication(t, playerEngine, filter, "") + defer cancel() + + execStatements(t, []string{"insert into t1 values(1, 'aaa')"}) + expectDBClientQueries(t, []string{ + "update _vt.vreplication set state='Running'.*", + "begin", + "update _vt.vreplication set pos=.*", + "commit", + "begin", + "insert into t2 set id=1, val='aaa'", + "update _vt.vreplication set pos=.*", + "commit", + }) +} + +func execStatements(t *testing.T, queries []string) { + t.Helper() + if err := env.Mysqld.ExecuteSuperQueryList(context.Background(), queries); err != nil { + t.Fatal(err) + } +} + +func startVReplication(t *testing.T, pe *Engine, filter *binlogdatapb.Filter, pos string) (cancelFunc func()) { + t.Helper() bls := &binlogdatapb.BinlogSource{ Keyspace: env.KeyspaceName, Shard: env.ShardName, - Filter: &binlogdatapb.Filter{ - Rules: []*binlogdatapb.Rule{{ - Match: "t2", - Filter: "select * from t1", - }}, - }, + Filter: filter, + } + if pos == "" { + pos = masterPosition(t) } - pos := masterPosition(t) query := fmt.Sprintf(`insert into _vt.vreplication`+ `(workflow, source, pos, max_tps, max_replication_lag, time_updated, transaction_timestamp, state)`+ `values('test', '%v', '%s', 9223372036854775807, 9223372036854775807, 481823, 0, 'Running')`, bls, pos, ) - if _, err := vre.Exec(query); err != nil { + qr, err := pe.Exec(query) + if err != nil { t.Fatal(err) } - execStatements(t, []string{"insert into t1 values(1, 'aaa')"}) - time.Sleep(1 * time.Second) -} - -func execStatements(t *testing.T, queries []string) { - t.Helper() - if err := env.Mysqld.ExecuteSuperQueryList(context.Background(), queries); err != nil { - t.Fatal(err) + resetDBClient() + return func() { + query := fmt.Sprintf("delete from _vt.vreplication where id = %d", qr.InsertID) + if _, err := pe.Exec(query); err != nil { + t.Fatal(err) + } } } @@ -86,40 +106,3 @@ func masterPosition(t *testing.T) string { } return mysql.EncodePosition(pos) } - -func realDBClientFactory() binlogplayer.DBClient { - return realDBClient{} -} - -type realDBClient struct{} - -func (dbc realDBClient) DBName() string { - return env.KeyspaceName -} - -func (dbc realDBClient) Connect() error { - return nil -} - -func (dbc realDBClient) Begin() error { - return env.Mysqld.ExecuteSuperQueryList(context.Background(), []string{"begin"}) -} - -func (dbc realDBClient) Commit() error { - return env.Mysqld.ExecuteSuperQueryList(context.Background(), []string{"commit"}) -} - -func (dbc realDBClient) Rollback() error { - return env.Mysqld.ExecuteSuperQueryList(context.Background(), []string{"rollback"}) -} - -func (dbc realDBClient) Close() { -} - -func (dbc realDBClient) ExecuteFetch(query string, maxrows int) (qr *sqltypes.Result, err error) { - fmt.Printf("executing: %v\n", query) - if strings.HasPrefix(query, "use") { - return nil, nil - } - return env.Mysqld.FetchSuperQuery(context.Background(), query) -} diff --git a/go/vt/vttablet/tabletserver/vstreamer/planbuilder.go b/go/vt/vttablet/tabletserver/vstreamer/planbuilder.go index 04e430bcb2b..f9920e791fb 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/planbuilder.go +++ b/go/vt/vttablet/tabletserver/vstreamer/planbuilder.go @@ -120,6 +120,61 @@ func (plan *Plan) filter(values []sqltypes.Value) (bool, []sqltypes.Value, error return true, result, nil } +func mustSendDDL(query mysql.Query, dbname string, filter *binlogdatapb.Filter) bool { + if query.Database != "" && query.Database != dbname { + return false + } + ast, err := sqlparser.Parse(query.SQL) + // If there was a parsing error, we send it through. Hopefully, + // recipient can handle it. + if err != nil { + return true + } + switch stmt := ast.(type) { + case *sqlparser.DBDDL: + return false + case *sqlparser.DDL: + if !stmt.Table.IsEmpty() { + return tableMatches(stmt.Table, dbname, filter) + } + for _, table := range stmt.FromTables { + if tableMatches(table, dbname, filter) { + return true + } + } + for _, table := range stmt.ToTables { + if tableMatches(table, dbname, filter) { + return true + } + } + return false + } + return true +} + +func tableMatches(table sqlparser.TableName, dbname string, filter *binlogdatapb.Filter) bool { + if !table.Qualifier.IsEmpty() && table.Qualifier.String() != dbname { + return false + } + for _, rule := range filter.Rules { + switch { + case strings.HasPrefix(rule.Match, "/"): + expr := strings.Trim(rule.Match, "/") + result, err := regexp.MatchString(expr, table.Name.String()) + if err != nil { + return true + } + if !result { + continue + } + return true + case table.Name.String() == rule.Match: + return true + } + } + return false +} + func buildPlan(ti *Table, kschema *vindexes.KeyspaceSchema, filter *binlogdatapb.Filter) (*Plan, error) { for _, rule := range filter.Rules { switch { diff --git a/go/vt/vttablet/tabletserver/vstreamer/planbuilder_test.go b/go/vt/vttablet/tabletserver/vstreamer/planbuilder_test.go index f3bf8d4aaa4..f9f357e24e2 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/planbuilder_test.go +++ b/go/vt/vttablet/tabletserver/vstreamer/planbuilder_test.go @@ -67,6 +67,87 @@ func init() { testKSChema = kschema } +func TestMustSendDDL(t *testing.T) { + filter := &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{{ + Match: "/t1.*/", + }, { + Match: "t2", + }}, + } + testcases := []struct { + sql string + db string + output bool + }{{ + sql: "create database db", + output: false, + }, { + sql: "create table foo(id int)", + output: false, + }, { + sql: "create table db.foo(id int)", + output: false, + }, { + sql: "create table mydb.foo(id int)", + output: false, + }, { + sql: "create table t1a(id int)", + output: true, + }, { + sql: "create table db.t1a(id int)", + output: false, + }, { + sql: "create table mydb.t1a(id int)", + output: true, + }, { + sql: "rename table t1a to foo, foo to bar", + output: true, + }, { + sql: "rename table foo to t1a, foo to bar", + output: true, + }, { + sql: "rename table foo to bar, t1a to bar", + output: true, + }, { + sql: "rename table foo to bar, bar to foo", + output: false, + }, { + sql: "drop table t1a, foo", + output: true, + }, { + sql: "drop table foo, t1a", + output: true, + }, { + sql: "drop table foo, bar", + output: false, + }, { + sql: "bad query", + output: true, + }, { + sql: "select * from t", + output: true, + }, { + sql: "drop table t2", + output: true, + }, { + sql: "create table t1a(id int)", + db: "db", + output: false, + }, { + sql: "create table t1a(id int)", + db: "mydb", + output: true, + }} + for _, tcase := range testcases { + q := mysql.Query{SQL: tcase.sql, Database: tcase.db} + got := mustSendDDL(q, "mydb", filter) + if got != tcase.output { + t.Errorf("%v: %v, want %v", q, got, tcase.output) + } + } +} + func TestPlanbuilder(t *testing.T) { t1 := &Table{ TableMap: &mysql.TableMap{ diff --git a/go/vt/vttablet/tabletserver/vstreamer/vstreamer.go b/go/vt/vttablet/tabletserver/vstreamer/vstreamer.go index df3947f4b45..0ae019c8326 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/vstreamer.go +++ b/go/vt/vttablet/tabletserver/vstreamer/vstreamer.go @@ -138,9 +138,6 @@ func (vs *vstreamer) parseEvents(ctx context.Context, events <-chan mysql.Binlog vevents := bufferedEvents bufferedEvents = nil curSize = 0 - if len(vevents) == 3 && vevents[0].Type == binlogdatapb.VEventType_GTID && vevents[1].Type == binlogdatapb.VEventType_BEGIN && vevents[2].Type == binlogdatapb.VEventType_COMMIT { - vevents = vevents[:1] - } return vs.send(vevents) case binlogdatapb.VEventType_ROW: // ROW events happen inside transactions. So, we can chunk them. @@ -236,7 +233,7 @@ func (vs *vstreamer) parseEvent(ev mysql.BinlogEvent) ([]*binlogdatapb.VEvent, e } var vevents []*binlogdatapb.VEvent switch { - case ev.IsPseudo() || ev.IsGTID(): + case ev.IsGTID(): gtid, hasBegin, err := ev.GTID(vs.format) if err != nil { return nil, fmt.Errorf("can't get GTID from binlog event: %v, event data: %#v", err, ev) @@ -274,10 +271,20 @@ func (vs *vstreamer) parseEvent(ev mysql.BinlogEvent) ([]*binlogdatapb.VEvent, e Type: binlogdatapb.VEventType_ROLLBACK, }) case sqlparser.StmtDDL: - vevents = append(vevents, &binlogdatapb.VEvent{ - Type: binlogdatapb.VEventType_DDL, - Ddl: q.SQL, - }) + if mustSendDDL(q, vs.cp.DbName, vs.filter) { + vevents = append(vevents, &binlogdatapb.VEvent{ + Type: binlogdatapb.VEventType_DDL, + Ddl: q.SQL, + }) + } else { + vevents = append(vevents, + &binlogdatapb.VEvent{ + Type: binlogdatapb.VEventType_BEGIN, + }, + &binlogdatapb.VEvent{ + Type: binlogdatapb.VEventType_COMMIT, + }) + } // Proactively reload schema. // If the DDL adds a column, comparing with an older snapshot of the // schema will make us think that a column was dropped and error out. diff --git a/go/vt/vttablet/tabletserver/vstreamer/vstreamer_test.go b/go/vt/vttablet/tabletserver/vstreamer/vstreamer_test.go index 03dfe5470ba..7c345cd3cdd 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/vstreamer_test.go +++ b/go/vt/vttablet/tabletserver/vstreamer/vstreamer_test.go @@ -472,6 +472,33 @@ func TestDDLDropColumn(t *testing.T) { } } +func TestUnsentDDL(t *testing.T) { + if testing.Short() { + t.Skip() + } + + execStatement(t, "create table unsent(id int, val varbinary(128), primary key(id))") + + testcases := []testcase{{ + input: []string{ + "drop table unsent", + }, + // An unsent DDL is sent as an empty transaction. + output: [][]string{{ + `gtid|begin`, + `gtid|begin`, + `commit`, + }}, + }} + + filter := &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{{ + Match: "/none/", + }}, + } + runCases(t, filter, testcases) +} + func TestBuffering(t *testing.T) { if testing.Short() { t.Skip() From cf26d48bc0b65f8c1aec041aa334ec86783d5c7c Mon Sep 17 00:00:00 2001 From: Sugu Sougoumarane Date: Mon, 14 Jan 2019 22:25:32 -0800 Subject: [PATCH 064/115] vreplication: relayLog functionality Signed-off-by: Sugu Sougoumarane --- .../vreplication/framework_test.go | 25 ++- .../tabletmanager/vreplication/relaylog.go | 145 ++++++++++++++++++ .../tabletmanager/vreplication/vplayer.go | 112 ++++++++++---- .../vreplication/vplayer_test.go | 30 ++-- 4 files changed, 268 insertions(+), 44 deletions(-) create mode 100644 go/vt/vttablet/tabletmanager/vreplication/relaylog.go diff --git a/go/vt/vttablet/tabletmanager/vreplication/framework_test.go b/go/vt/vttablet/tabletmanager/vreplication/framework_test.go index 275f1763306..51537b96af3 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/framework_test.go +++ b/go/vt/vttablet/tabletmanager/vreplication/framework_test.go @@ -311,6 +311,18 @@ func (dbc *realDBClient) ExecuteFetch(query string, maxrows int) (qr *sqltypes.R return env.Mysqld.FetchSuperQuery(context.Background(), query) } +func printQueries(t *testing.T) { + t.Helper() + for { + select { + case got := <-globalDBClient.queries: + t.Errorf("%s", got) + default: + return + } + } +} + func expectDBClientQueries(t *testing.T, queries []string) { t.Helper() for i, query := range queries { @@ -322,15 +334,18 @@ func expectDBClientQueries(t *testing.T, queries []string) { panic(err) } if !match { - t.Fatalf("query:\n%s, does not match query %d:\n%s", got, i, query) + t.Errorf("query:\n%s, does not match query %d:\n%s", got, i, query) } case <-time.After(5 * time.Second): t.Fatalf("no query received, expecting %s", query) } } - select { - case got := <-globalDBClient.queries: - t.Fatalf("unexpected query: %s", got) - default: + for { + select { + case got := <-globalDBClient.queries: + t.Errorf("unexpected query: %s", got) + default: + return + } } } diff --git a/go/vt/vttablet/tabletmanager/vreplication/relaylog.go b/go/vt/vttablet/tabletmanager/vreplication/relaylog.go new file mode 100644 index 00000000000..635bf1a76c3 --- /dev/null +++ b/go/vt/vttablet/tabletmanager/vreplication/relaylog.go @@ -0,0 +1,145 @@ +/* +Copyright 2019 The Vitess Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this 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 ( + "io" + "sync" + + "golang.org/x/net/context" + + binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" +) + +type relayLog struct { + ctx context.Context + maxItems int + maxSize int + + // mu controls all variables below and is shared by canAccept and hasItems. + // Broadcasting must be done while holding mu. This is mainly necessary because both + // conditions depend on ctx.Done(), which can change state asynchronously. + mu sync.Mutex + curSize int + items [][]*binlogdatapb.VEvent + err error + // canAccept is true if: curSize<=maxSize, len(items)0, err==nil and ctx is not Done. + hasItems sync.Cond +} + +func newRelayLog(ctx context.Context, maxItems, maxSize int) *relayLog { + rl := &relayLog{ + ctx: ctx, + maxItems: maxItems, + maxSize: maxSize, + } + rl.canAccept.L = &rl.mu + rl.hasItems.L = &rl.mu + + // Any time context is done, wake up all waiters to make them exit. + go func() { + select { + case <-ctx.Done(): + rl.mu.Lock() + defer rl.mu.Unlock() + rl.canAccept.Broadcast() + rl.hasItems.Broadcast() + default: + } + }() + return rl +} + +func (rl *relayLog) Send(events []*binlogdatapb.VEvent) error { + rl.mu.Lock() + defer rl.mu.Unlock() + + if err := rl.checkDone(); err != nil { + return err + } + for rl.curSize > rl.maxSize || len(rl.items) >= rl.maxItems { + rl.canAccept.Wait() + if err := rl.checkDone(); err != nil { + return err + } + } + rl.items = append(rl.items, events) + rl.curSize += eventsSize(events) + rl.hasItems.Broadcast() + return nil +} + +func (rl *relayLog) Fetch() ([][]*binlogdatapb.VEvent, error) { + rl.mu.Lock() + defer rl.mu.Unlock() + + if err := rl.checkDone(); err != nil { + return nil, err + } + for len(rl.items) == 0 { + rl.hasItems.Wait() + if err := rl.checkDone(); err != nil { + return nil, err + } + } + items := rl.items + rl.items = nil + rl.curSize = 0 + rl.canAccept.Broadcast() + return items, nil +} + +func (rl *relayLog) checkDone() error { + if rl.err != nil { + return rl.err + } + select { + case <-rl.ctx.Done(): + return io.EOF + default: + } + return nil +} + +func (rl *relayLog) SetError(err error) { + rl.mu.Lock() + defer rl.mu.Unlock() + + rl.err = err + rl.canAccept.Broadcast() + rl.hasItems.Broadcast() +} + +func eventsSize(events []*binlogdatapb.VEvent) int { + size := 0 + for _, event := range events { + if event.Type != binlogdatapb.VEventType_ROW { + continue + } + for _, rowChange := range event.RowEvent.RowChanges { + if rowChange.Before != nil { + size += len(rowChange.Before.Values) + } + if rowChange.After != nil { + size += len(rowChange.After.Values) + } + } + } + return size +} diff --git a/go/vt/vttablet/tabletmanager/vreplication/vplayer.go b/go/vt/vttablet/tabletmanager/vreplication/vplayer.go index 02938c7479e..27aca2e525a 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/vplayer.go +++ b/go/vt/vttablet/tabletmanager/vreplication/vplayer.go @@ -19,7 +19,6 @@ package vreplication import ( "bytes" "fmt" - "io" "time" "golang.org/x/net/context" @@ -46,10 +45,13 @@ type vplayer struct { dbClient binlogplayer.DBClient mysqld mysqlctl.MysqlDaemon - pos mysql.Position - stopPos mysql.Position - pplan *playerPlan - tplans map[string]*tablePlan + pos mysql.Position + stopPos mysql.Position + externalizePos []mysql.Position + mustCommit bool + + pplan *playerPlan + tplans map[string]*tablePlan retryDelay time.Duration } @@ -114,24 +116,69 @@ func (vp *vplayer) play(ctx context.Context) error { if err != nil { return fmt.Errorf("error dialing tablet: %v", err) } + ctx, cancel := context.WithCancel(ctx) + defer cancel() + + relay := newRelayLog(ctx, 10, 10) + go vp.applyEvents(relay) + target := &querypb.Target{ Keyspace: vp.sourceTablet.Keyspace, Shard: vp.sourceTablet.Shard, TabletType: vp.sourceTablet.Type, } return vsClient.VStream(ctx, target, startPos, plan.vstreamFilter, func(events []*binlogdatapb.VEvent) error { - for _, event := range events { - select { - case <-ctx.Done(): - return io.EOF - default: + return relay.Send(events) + }) +} + +func (vp *vplayer) applyEvents(relay *relayLog) { + for { + items, err := relay.Fetch() + if err != nil { + return + } + events := linearizeEvents(items) + for i, event := range events { + switch event.Type { + case binlogdatapb.VEventType_COMMIT: + if vp.pos.Equal(vp.stopPos) { + break + } + // Check for externalizePos + foundAnotherCommit := false + searchCommit: + for j := i + 1; j < len(events); j++ { + switch event.Type { + case binlogdatapb.VEventType_COMMIT: + foundAnotherCommit = true + break searchCommit + case binlogdatapb.VEventType_ROLLBACK, binlogdatapb.VEventType_DDL: + break searchCommit + } + } + if foundAnotherCommit { + continue + } } if err := vp.applyEvent(event); err != nil { - return err + relay.SetError(err) + return } } - return nil - }) + } +} + +func linearizeEvents(items [][]*binlogdatapb.VEvent) []*binlogdatapb.VEvent { + length := 0 + for _, events := range items { + length += len(events) + } + linear := make([]*binlogdatapb.VEvent, 0, length) + for _, events := range items { + linear = append(linear, events...) + } + return linear } func (vp *vplayer) applyEvent(event *binlogdatapb.VEvent) error { @@ -149,28 +196,46 @@ func (vp *vplayer) applyEvent(event *binlogdatapb.VEvent) error { return fmt.Errorf("next event position %v exceeds stop pos %v, exiting without applying", vp.pos, vp.stopPos) } case binlogdatapb.VEventType_BEGIN: - if err := vp.dbClient.Begin(); err != nil { - return err - } + // No-op: begin is called as needed. case binlogdatapb.VEventType_COMMIT: + if !vp.mustCommit { + return nil + } if err := vp.updatePos(event.Timestamp); err != nil { return err } if err := vp.dbClient.Commit(); err != nil { return err } + vp.mustCommit = false case binlogdatapb.VEventType_ROLLBACK: // This code is unreachable. It's just here as failsafe. + vp.mustCommit = false _ = vp.dbClient.Rollback() case binlogdatapb.VEventType_FIELD: + if !vp.mustCommit { + if err := vp.dbClient.Begin(); err != nil { + return err + } + vp.mustCommit = true + } if err := vp.updatePlan(event.FieldEvent); err != nil { return err } case binlogdatapb.VEventType_ROW: + if !vp.mustCommit { + if err := vp.dbClient.Begin(); err != nil { + return err + } + vp.mustCommit = true + } if err := vp.applyRowEvent(event.RowEvent); err != nil { return err } case binlogdatapb.VEventType_DDL: + if vp.mustCommit { + return fmt.Errorf("unexpected state: DDL encountered in the middle of a transaction: %v", event.Ddl) + } switch vp.source.OnDdl { case binlogdatapb.OnDDLAction_IGNORE: // no-op @@ -189,14 +254,14 @@ func (vp *vplayer) applyEvent(event *binlogdatapb.VEvent) error { if err := vp.exec(event.Ddl); err != nil { return err } - if err := vp.savePos(event.Timestamp); err != nil { + if err := vp.updatePos(event.Timestamp); err != nil { return err } case binlogdatapb.OnDDLAction_EXEC_IGNORE: if err := vp.exec(event.Ddl); err != nil { log.Infof("Ignoring error: %v for DDL: %s", err, event.Ddl) } - if err := vp.savePos(event.Timestamp); err != nil { + if err := vp.updatePos(event.Timestamp); err != nil { return err } } @@ -416,17 +481,6 @@ func (vp *vplayer) writeWhereValues(sql *sqlparser.TrackedBuffer, tplan *tablePl } } -// savePos performs an updatePos in its own transaction. -func (vp *vplayer) savePos(ts int64) error { - if err := vp.dbClient.Begin(); err != nil { - return err - } - if err := vp.updatePos(ts); err != nil { - return err - } - return vp.dbClient.Commit() -} - func (vp *vplayer) updatePos(ts int64) error { updatePos := binlogplayer.GenerateUpdatePos(vp.id, vp.pos, time.Now().Unix(), ts) if _, err := vp.dbClient.ExecuteFetch(updatePos, 0); err != nil { diff --git a/go/vt/vttablet/tabletmanager/vreplication/vplayer_test.go b/go/vt/vttablet/tabletmanager/vreplication/vplayer_test.go index 11e2d8bc5da..a349b026204 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/vplayer_test.go +++ b/go/vt/vttablet/tabletmanager/vreplication/vplayer_test.go @@ -19,6 +19,7 @@ package vreplication import ( "fmt" "testing" + "time" "golang.org/x/net/context" "vitess.io/vitess/go/mysql" @@ -49,17 +50,26 @@ func TestSimple(t *testing.T) { cancel := startVReplication(t, playerEngine, filter, "") defer cancel() - execStatements(t, []string{"insert into t1 values(1, 'aaa')"}) - expectDBClientQueries(t, []string{ - "update _vt.vreplication set state='Running'.*", - "begin", - "update _vt.vreplication set pos=.*", - "commit", - "begin", - "insert into t2 set id=1, val='aaa'", - "update _vt.vreplication set pos=.*", - "commit", + execStatements(t, []string{ + "insert into t1 values(1, 'aaa')", + "insert into t1 values(2, 'aaa')", + "insert into t1 values(3, 'aaa')", + "insert into t1 values(4, 'aaa')", }) + time.Sleep(1 * time.Second) + printQueries(t) + /* + expectDBClientQueries(t, []string{ + "update _vt.vreplication set state='Running'.*", + "begin", + "update _vt.vreplication set pos=.*", + "commit", + "begin", + "insert into t2 set id=1, val='aaa'", + "update _vt.vreplication set pos=.*", + "commit", + }) + */ } func execStatements(t *testing.T, queries []string) { From 8b56b338986afc93a4e722cd226c2ab22cfd12a6 Mon Sep 17 00:00:00 2001 From: Sugu Sougoumarane Date: Thu, 17 Jan 2019 11:52:00 -0800 Subject: [PATCH 065/115] vplayer: more features Signed-off-by: Sugu Sougoumarane --- .../tabletmanager/vreplication/controller.go | 14 +- .../tabletmanager/vreplication/engine.go | 31 ++- .../tabletmanager/vreplication/engine_test.go | 11 + .../tabletmanager/vreplication/relaylog.go | 20 +- .../vreplication/retryableClient.go | 82 +++++++ .../tabletmanager/vreplication/vplayer.go | 200 ++++++++++++------ .../tabletserver/vstreamer/vstreamer.go | 8 +- 7 files changed, 288 insertions(+), 78 deletions(-) create mode 100644 go/vt/vttablet/tabletmanager/vreplication/retryableClient.go diff --git a/go/vt/vttablet/tabletmanager/vreplication/controller.go b/go/vt/vttablet/tabletmanager/vreplication/controller.go index 200492e0cdf..574b1484d21 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/controller.go +++ b/go/vt/vttablet/tabletmanager/vreplication/controller.go @@ -22,6 +22,7 @@ import ( "strconv" "time" + "vitess.io/vitess/go/mysql" "vitess.io/vitess/go/vt/vterrors" "github.com/golang/protobuf/proto" @@ -47,6 +48,9 @@ type controller struct { mysqld mysqlctl.MysqlDaemon blpStats *binlogplayer.Stats + // vplayer is set only if we launch vplayer. + vplayer *vplayer + id uint32 source binlogdatapb.BinlogSource stopPos string @@ -183,12 +187,18 @@ func (ct *controller) runBlp(ctx context.Context) (err error) { player := binlogplayer.NewBinlogPlayerKeyRange(dbClient, tablet, ct.source.KeyRange, ct.id, ct.blpStats) return player.ApplyBinlogEvents(ctx) case ct.source.Filter != nil: - player := newVPlayer(ct.id, &ct.source, tablet, ct.blpStats, dbClient, ct.mysqld) - return player.Play(ctx) + ct.vplayer = newVPlayer(ct.id, &ct.source, tablet, ct.blpStats, dbClient, ct.mysqld) + return ct.vplayer.Play(ctx) } return fmt.Errorf("missing source") } +func (ct *controller) exportPosition(pos mysql.Position) { + if ct.vplayer != nil { + ct.vplayer.exportPosition(pos) + } +} + func (ct *controller) Stop() { ct.cancel() <-ct.done diff --git a/go/vt/vttablet/tabletmanager/vreplication/engine.go b/go/vt/vttablet/tabletmanager/vreplication/engine.go index f214876de88..3a664b131f5 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/engine.go +++ b/go/vt/vttablet/tabletmanager/vreplication/engine.go @@ -281,14 +281,31 @@ func (vre *Engine) WaitForPos(ctx context.Context, id int, pos string) error { return err } - vre.mu.Lock() - if !vre.isOpen { - vre.mu.Unlock() - return errors.New("vreplication engine is closed") + if err := func() error { + vre.mu.Lock() + defer vre.mu.Unlock() + + if !vre.isOpen { + return errors.New("vreplication engine is closed") + } + ct, ok := vre.controllers[id] + if !ok { + return fmt.Errorf("vreplication stream %d not found", id) + } + mpos, err := mysql.DecodePosition(pos) + if err != nil { + return err + } + // vplayer doesn't export all the positions it receives unless + // we specifically request it for one. + ct.exportPosition(mpos) + + // Ensure that the engine won't be closed while this is running. + vre.wg.Add(1) + return nil + }(); err != nil { + return err } - // Ensure that the engine won't be closed while this is running. - vre.wg.Add(1) - vre.mu.Unlock() defer vre.wg.Done() dbClient := vre.dbClientFactory() diff --git a/go/vt/vttablet/tabletmanager/vreplication/engine_test.go b/go/vt/vttablet/tabletmanager/vreplication/engine_test.go index 5b335a05a9a..8394a8328f0 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/engine_test.go +++ b/go/vt/vttablet/tabletmanager/vreplication/engine_test.go @@ -283,6 +283,8 @@ func TestWaitForPos(t *testing.T) { if err := vre.Open(context.Background()); err != nil { t.Fatal(err) } + // hack a controller into vre. + vre.controllers[1] = &controller{} dbClient.ExpectRequest("select pos from _vt.vreplication where id=1", &sqltypes.Result{Rows: [][]sqltypes.Value{{ sqltypes.NewVarBinary("MariaDB/0-1-1083"), @@ -315,6 +317,8 @@ func TestWaitForPosError(t *testing.T) { if err := vre.Open(context.Background()); err != nil { t.Fatal(err) } + // hack a controller into vre. + vre.controllers[1] = &controller{} err = vre.WaitForPos(context.Background(), 1, "BadFlavor/0-1-1084") want = `parse error: unknown GTIDSet flavor "BadFlavor"` @@ -357,6 +361,13 @@ func TestWaitForPosCancel(t *testing.T) { }}}, nil) ctx, cancel := context.WithCancel(context.Background()) cancel() + // hack a controller that can handle Close + done := make(chan struct{}) + close(done) + vre.controllers[1] = &controller{ + cancel: func() {}, + done: done, + } err := vre.WaitForPos(ctx, 1, "MariaDB/0-1-1084") if err == nil || err != context.Canceled { t.Errorf("WaitForPos: %v, want %v", err, context.Canceled) diff --git a/go/vt/vttablet/tabletmanager/vreplication/relaylog.go b/go/vt/vttablet/tabletmanager/vreplication/relaylog.go index 635bf1a76c3..b8544e81164 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/relaylog.go +++ b/go/vt/vttablet/tabletmanager/vreplication/relaylog.go @@ -19,9 +19,11 @@ package vreplication import ( "io" "sync" + "time" "golang.org/x/net/context" + "vitess.io/vitess/go/sync2" binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" ) @@ -39,7 +41,7 @@ type relayLog struct { err error // canAccept is true if: curSize<=maxSize, len(items)0, err==nil and ctx is not Done. + // hasItems is true if len(items)>0, err==nil, ctx is not Done, and call has not timedout. hasItems sync.Cond } @@ -92,11 +94,27 @@ func (rl *relayLog) Fetch() ([][]*binlogdatapb.VEvent, error) { if err := rl.checkDone(); err != nil { return nil, err } + timer := time.NewTimer(idleTimeout) + defer timer.Stop() + var timedout sync2.AtomicBool + go func() { + select { + case <-timer.C: + rl.mu.Lock() + defer rl.mu.Unlock() + timedout.Set(true) + rl.hasItems.Broadcast() + default: + } + }() for len(rl.items) == 0 { rl.hasItems.Wait() if err := rl.checkDone(); err != nil { return nil, err } + if timedout.Get() { + return nil, nil + } } items := rl.items rl.items = nil diff --git a/go/vt/vttablet/tabletmanager/vreplication/retryableClient.go b/go/vt/vttablet/tabletmanager/vreplication/retryableClient.go new file mode 100644 index 00000000000..30deacf155b --- /dev/null +++ b/go/vt/vttablet/tabletmanager/vreplication/retryableClient.go @@ -0,0 +1,82 @@ +/* +Copyright 2019 The Vitess Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this 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 ( + "vitess.io/vitess/go/sqltypes" + "vitess.io/vitess/go/vt/binlog/binlogplayer" +) + +type retryableClient struct { + binlogplayer.DBClient + inTransaction bool + queries []string +} + +func (rt *retryableClient) Begin() error { + if err := rt.DBClient.Begin(); err != nil { + return err + } + rt.inTransaction = true + return nil +} + +func (rt *retryableClient) Commit() error { + if err := rt.DBClient.Commit(); err != nil { + return err + } + rt.inTransaction = false + rt.queries = nil + return nil +} + +func (rt *retryableClient) Rollback() error { + if err := rt.DBClient.Rollback(); err != nil { + return err + } + rt.inTransaction = false + rt.queries = nil + return nil +} + +func (rt *retryableClient) ExecuteFetch(query string, maxrows int) (*sqltypes.Result, error) { + if !rt.inTransaction { + rt.queries = []string{query} + } else { + rt.queries = append(rt.queries, query) + } + return rt.DBClient.ExecuteFetch(query, maxrows) +} + +func (rt *retryableClient) Retry() error { + if !rt.inTransaction { + _, err := rt.DBClient.ExecuteFetch(rt.queries[0], 10000) + return err + } + if err := rt.DBClient.Rollback(); err != nil { + return err + } + if err := rt.DBClient.Begin(); err != nil { + return err + } + for _, q := range rt.queries { + if _, err := rt.DBClient.ExecuteFetch(q, 10000); err != nil { + return err + } + } + return nil +} diff --git a/go/vt/vttablet/tabletmanager/vreplication/vplayer.go b/go/vt/vttablet/tabletmanager/vreplication/vplayer.go index 27aca2e525a..d79640bbcd0 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/vplayer.go +++ b/go/vt/vttablet/tabletmanager/vreplication/vplayer.go @@ -19,6 +19,8 @@ package vreplication import ( "bytes" "fmt" + "io" + "sync" "time" "golang.org/x/net/context" @@ -37,47 +39,67 @@ import ( topodatapb "vitess.io/vitess/go/vt/proto/topodata" ) +var ( + idleTimeout = 1 * time.Hour + dblockRetryDelay = 1 * time.Second +) + type vplayer struct { id uint32 source *binlogdatapb.BinlogSource sourceTablet *topodatapb.Tablet stats *binlogplayer.Stats - dbClient binlogplayer.DBClient + dbClient *retryableClient mysqld mysqlctl.MysqlDaemon - pos mysql.Position - stopPos mysql.Position - externalizePos []mysql.Position - mustCommit bool + pos mysql.Position + unsavedGTID *binlogdatapb.VEvent + timeLastSaved time.Time + stopPos mysql.Position + mustCommit bool + + // mu protects exportPositions. + // exportPositions specifies a list of positions. + // Anytime the vplayer reaches or exceeds one of these + // positions, it will update the position even if it's + // an empty transaction. This is used for cases where + // a target is stopped, and a request is initiated to + // wait for vreplication to reach the source's position. + // Since vreplication only updates state on non-empty + // transactions, this list is used to force such updates. + mu sync.Mutex + exportPositions []mysql.Position pplan *playerPlan tplans map[string]*tablePlan - - retryDelay time.Duration } func newVPlayer(id uint32, source *binlogdatapb.BinlogSource, sourceTablet *topodatapb.Tablet, stats *binlogplayer.Stats, dbClient binlogplayer.DBClient, mysqld mysqlctl.MysqlDaemon) *vplayer { return &vplayer{ - id: id, - source: source, - sourceTablet: sourceTablet, - stats: stats, - dbClient: dbClient, - mysqld: mysqld, - retryDelay: 1 * time.Second, - tplans: make(map[string]*tablePlan), + id: id, + source: source, + sourceTablet: sourceTablet, + stats: stats, + dbClient: &retryableClient{DBClient: dbClient}, + mysqld: mysqld, + timeLastSaved: time.Now(), + tplans: make(map[string]*tablePlan), } } func (vp *vplayer) Play(ctx context.Context) error { - vp.setState(binlogplayer.BlpRunning, "") + if err := vp.setState(binlogplayer.BlpRunning, ""); err != nil { + return err + } if err := vp.play(ctx); err != nil { msg := err.Error() vp.stats.History.Add(&binlogplayer.StatsHistoryRecord{ Time: time.Now(), Message: msg, }) - vp.setState(binlogplayer.BlpError, msg) + if err := vp.setState(binlogplayer.BlpError, msg); err != nil { + return err + } return err } return nil @@ -100,8 +122,7 @@ func (vp *vplayer) play(ctx context.Context) error { } if !vp.stopPos.IsZero() { if vp.pos.AtLeast(vp.stopPos) { - vp.setState(binlogplayer.BlpStopped, fmt.Sprintf("Stop position %v already reached: %v", vp.pos, vp.stopPos)) - return nil + return vp.setState(binlogplayer.BlpStopped, fmt.Sprintf("Stop position %v already reached: %v", vp.pos, vp.stopPos)) } } log.Infof("Starting VReplication player id: %v, startPos: %v, stop: %v, source: %v", vp.id, startPos, vp.stopPos, vp.sourceTablet) @@ -136,49 +157,81 @@ func (vp *vplayer) applyEvents(relay *relayLog) { for { items, err := relay.Fetch() if err != nil { + relay.SetError(err) return } - events := linearizeEvents(items) - for i, event := range events { - switch event.Type { - case binlogdatapb.VEventType_COMMIT: - if vp.pos.Equal(vp.stopPos) { - break - } - // Check for externalizePos - foundAnotherCommit := false - searchCommit: - for j := i + 1; j < len(events); j++ { - switch event.Type { - case binlogdatapb.VEventType_COMMIT: - foundAnotherCommit = true - break searchCommit - case binlogdatapb.VEventType_ROLLBACK, binlogdatapb.VEventType_DDL: - break searchCommit + // This covers two situations: + // 1. Fetch was idle for idleTimeout. + // 2. We've been receiving empty events for longer than idleTimeout. + // In both cases, now > timeLastSaved. If so, any unsaved GTID should be saved + // to prevent us from falling behind on tracking the source binlog position. + if time.Now().Sub(vp.timeLastSaved) >= idleTimeout && vp.unsavedGTID != nil { + if err := vp.updatePos(vp.unsavedGTID.Timestamp); err != nil { + relay.SetError(err) + return + } + } + for i, events := range items { + for j, event := range events { + switch event.Type { + case binlogdatapb.VEventType_COMMIT: + if vp.pos.Equal(vp.stopPos) { + // If stop pos is reached, we have to commit. + break + } + if vp.mustExport() { + break + } + if hasAnotherCommit(items, i, j+1) { + continue } } - if foundAnotherCommit { - continue + if err := vp.applyEvent(event); err != nil { + relay.SetError(err) + return } } - if err := vp.applyEvent(event); err != nil { - relay.SetError(err) - return - } } } } -func linearizeEvents(items [][]*binlogdatapb.VEvent) []*binlogdatapb.VEvent { - length := 0 - for _, events := range items { - length += len(events) +func (vp *vplayer) mustExport() bool { + vp.mu.Lock() + defer vp.mu.Unlock() + + mustExport := false + for { + found := false + for i, export := range vp.exportPositions { + if vp.pos.AtLeast(export) { + mustExport = true + found = true + vp.exportPositions = append(vp.exportPositions[:i], vp.exportPositions[i+1:]...) + break + } + } + if !found { + return mustExport + } } - linear := make([]*binlogdatapb.VEvent, 0, length) - for _, events := range items { - linear = append(linear, events...) +} + +func hasAnotherCommit(items [][]*binlogdatapb.VEvent, i, j int) bool { + for i < len(items) { + for j < len(items[i]) { + // We ignore GTID, BEGIN, FIELD and ROW. + switch items[i][j].Type { + case binlogdatapb.VEventType_COMMIT: + return true + case binlogdatapb.VEventType_DDL: + return false + } + j++ + } + j = 0 + i++ } - return linear + return false } func (vp *vplayer) applyEvent(event *binlogdatapb.VEvent) error { @@ -189,6 +242,7 @@ func (vp *vplayer) applyEvent(event *binlogdatapb.VEvent) error { return err } vp.pos = pos + vp.unsavedGTID = event if vp.stopPos.IsZero() { return nil } @@ -204,14 +258,19 @@ func (vp *vplayer) applyEvent(event *binlogdatapb.VEvent) error { if err := vp.updatePos(event.Timestamp); err != nil { return err } + posReached := !vp.stopPos.IsZero() && vp.pos.Equal(vp.stopPos) + if posReached { + if err := vp.setState(binlogplayer.BlpStopped, fmt.Sprintf("Stopped at position %v", vp.stopPos)); err != nil { + return err + } + } if err := vp.dbClient.Commit(); err != nil { return err } vp.mustCommit = false - case binlogdatapb.VEventType_ROLLBACK: - // This code is unreachable. It's just here as failsafe. - vp.mustCommit = false - _ = vp.dbClient.Rollback() + if posReached { + return io.EOF + } case binlogdatapb.VEventType_FIELD: if !vp.mustCommit { if err := vp.dbClient.Begin(); err != nil { @@ -246,10 +305,13 @@ func (vp *vplayer) applyEvent(event *binlogdatapb.VEvent) error { if err := vp.updatePos(event.Timestamp); err != nil { return err } - vp.setState(binlogplayer.BlpStopped, fmt.Sprintf("stopped at DDL %s", event.Ddl)) + if err := vp.setState(binlogplayer.BlpStopped, fmt.Sprintf("Stopped at DDL %s", event.Ddl)); err != nil { + return err + } if err := vp.dbClient.Commit(); err != nil { return err } + return io.EOF case binlogdatapb.OnDDLAction_EXEC: if err := vp.exec(event.Ddl); err != nil { return err @@ -269,12 +331,8 @@ func (vp *vplayer) applyEvent(event *binlogdatapb.VEvent) error { return nil } -func (vp *vplayer) setState(state, message string) { - if state == binlogplayer.BlpStopped { - } - if err := binlogplayer.SetVReplicationState(vp.dbClient, vp.id, state, message); err != nil { - log.Errorf("Error writing state: %s, msg: %s, err: %v", state, message, err) - } +func (vp *vplayer) setState(state, message string) error { + return binlogplayer.SetVReplicationState(vp.dbClient, vp.id, state, message) } func (vp *vplayer) updatePlan(fieldEvent *binlogdatapb.FieldEvent) error { @@ -487,13 +545,31 @@ func (vp *vplayer) updatePos(ts int64) error { _ = vp.dbClient.Rollback() return fmt.Errorf("error %v updating position", err) } + vp.unsavedGTID = nil + vp.timeLastSaved = time.Now() return nil } func (vp *vplayer) exec(sql string) error { vp.stats.Timings.Record("query", time.Now()) _, err := vp.dbClient.ExecuteFetch(sql, 0) - return err + for err != nil { + // 1213: deadlock, 1205: lock wait timeout + if sqlErr, ok := err.(*mysql.SQLError); ok && sqlErr.Number() == 1213 || sqlErr.Number() == 1205 { + log.Infof("retryable error: %v, waiting for %v and retrying", sqlErr, dblockRetryDelay) + time.Sleep(dblockRetryDelay) + err = vp.dbClient.Retry() + continue + } + return err + } + return nil +} + +func (vp *vplayer) exportPosition(pos mysql.Position) { + vp.mu.Lock() + defer vp.mu.Unlock() + vp.exportPositions = append(vp.exportPositions, pos) } func encodeValue(sql *sqlparser.TrackedBuffer, value sqltypes.Value) { diff --git a/go/vt/vttablet/tabletserver/vstreamer/vstreamer.go b/go/vt/vttablet/tabletserver/vstreamer/vstreamer.go index 0ae019c8326..6c8631a49ba 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/vstreamer.go +++ b/go/vt/vttablet/tabletserver/vstreamer/vstreamer.go @@ -131,8 +131,8 @@ func (vs *vstreamer) parseEvents(ctx context.Context, events <-chan mysql.Binlog case binlogdatapb.VEventType_GTID, binlogdatapb.VEventType_BEGIN, binlogdatapb.VEventType_FIELD: // We never have to send GTID, BEGIN or FIELD events on their own. bufferedEvents = append(bufferedEvents, vevent) - case binlogdatapb.VEventType_COMMIT, binlogdatapb.VEventType_ROLLBACK, binlogdatapb.VEventType_DDL: - // COMMIT, ROLLBACK and DDL are terminal. There may be no more events after + case binlogdatapb.VEventType_COMMIT, binlogdatapb.VEventType_DDL: + // COMMIT and DDL are terminal. There may be no more events after // these for a long time. So, we have to send whatever we have. bufferedEvents = append(bufferedEvents, vevent) vevents := bufferedEvents @@ -266,10 +266,6 @@ func (vs *vstreamer) parseEvent(ev mysql.BinlogEvent) ([]*binlogdatapb.VEvent, e vevents = append(vevents, &binlogdatapb.VEvent{ Type: binlogdatapb.VEventType_COMMIT, }) - case sqlparser.StmtRollback: - vevents = append(vevents, &binlogdatapb.VEvent{ - Type: binlogdatapb.VEventType_ROLLBACK, - }) case sqlparser.StmtDDL: if mustSendDDL(q, vs.cp.DbName, vs.filter) { vevents = append(vevents, &binlogdatapb.VEvent{ From cff8cda6ac4d46d1f81d745321d09655576e2b39 Mon Sep 17 00:00:00 2001 From: Sugu Sougoumarane Date: Thu, 17 Jan 2019 23:26:15 -0800 Subject: [PATCH 066/115] vplayer: more tests and a few bug fixes Signed-off-by: Sugu Sougoumarane --- .../vreplication/framework_test.go | 81 ++++++++++--------- .../tabletmanager/vreplication/relaylog.go | 16 +--- .../tabletmanager/vreplication/vplayer.go | 60 +++++++------- .../vreplication/vplayer_test.go | 74 +++++++++++------ 4 files changed, 127 insertions(+), 104 deletions(-) diff --git a/go/vt/vttablet/tabletmanager/vreplication/framework_test.go b/go/vt/vttablet/tabletmanager/vreplication/framework_test.go index 51537b96af3..139313e3393 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/framework_test.go +++ b/go/vt/vttablet/tabletmanager/vreplication/framework_test.go @@ -29,6 +29,7 @@ import ( "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/grpcclient" @@ -45,11 +46,11 @@ import ( ) var ( - playerEngine *Engine - streamerEngine *vstreamer.Engine - env *testenv.Env - globalFBC = &fakeBinlogClient{} - globalDBClient = &realDBClient{} + playerEngine *Engine + streamerEngine *vstreamer.Engine + env *testenv.Env + globalFBC = &fakeBinlogClient{} + globalDBQueries = make(chan string, 1000) ) func init() { @@ -263,17 +264,12 @@ func expectFBCRequest(t *testing.T, tablet *topodatapb.Tablet, pos string, table //-------------------------------------- // DBCLient wrapper -func resetDBClient() { - globalDBClient.queries = make(chan string, 1000) -} - func realDBClientFactory() binlogplayer.DBClient { - resetDBClient() - return globalDBClient + return &realDBClient{} } type realDBClient struct { - queries chan string + conn *mysql.Conn } func (dbc *realDBClient) DBName() string { @@ -281,17 +277,24 @@ func (dbc *realDBClient) DBName() string { } func (dbc *realDBClient) Connect() error { + conn, err := mysql.Connect(context.Background(), env.Dbcfgs.AppWithDB()) + if err != nil { + return err + } + dbc.conn = conn return nil } func (dbc *realDBClient) Begin() error { - dbc.queries <- "begin" - return env.Mysqld.ExecuteSuperQueryList(context.Background(), []string{"begin"}) + globalDBQueries <- "begin" + _, err := dbc.conn.ExecuteFetch("begin", 10000, true) + return err } func (dbc *realDBClient) Commit() error { - dbc.queries <- "commit" - return env.Mysqld.ExecuteSuperQueryList(context.Background(), []string{"commit"}) + globalDBQueries <- "commit" + _, err := dbc.conn.ExecuteFetch("commit", 10000, true) + return err } func (dbc *realDBClient) Rollback() error { @@ -299,50 +302,52 @@ func (dbc *realDBClient) Rollback() error { } func (dbc *realDBClient) Close() { + dbc.conn.Close() + dbc.conn = nil } -func (dbc *realDBClient) ExecuteFetch(query string, maxrows int) (qr *sqltypes.Result, err error) { +func (dbc *realDBClient) ExecuteFetch(query string, maxrows int) (*sqltypes.Result, error) { if !strings.HasPrefix(query, "select") { - dbc.queries <- query + globalDBQueries <- query } if strings.HasPrefix(query, "use") { return nil, nil } - return env.Mysqld.FetchSuperQuery(context.Background(), query) -} - -func printQueries(t *testing.T) { - t.Helper() - for { - select { - case got := <-globalDBClient.queries: - t.Errorf("%s", got) - default: - return - } - } + return dbc.conn.ExecuteFetch(query, 10000, true) } func expectDBClientQueries(t *testing.T, queries []string) { t.Helper() + failed := false for i, query := range queries { + if failed { + t.Errorf("no query received, expecting %s", query) + continue + } var got string select { - case got = <-globalDBClient.queries: - match, err := regexp.MatchString(query, got) - if err != nil { - panic(err) + case got = <-globalDBQueries: + var match bool + if query[0] == '/' { + result, err := regexp.MatchString(query[1:], got) + if err != nil { + panic(err) + } + match = result + } else { + match = (got == query) } if !match { - t.Errorf("query:\n%s, does not match query %d:\n%s", got, i, query) + t.Errorf("query:\n%q, does not match query %d:\n%q", got, i, query) } case <-time.After(5 * time.Second): - t.Fatalf("no query received, expecting %s", query) + t.Errorf("no query received, expecting %s", query) + failed = true } } for { select { - case got := <-globalDBClient.queries: + case got := <-globalDBQueries: t.Errorf("unexpected query: %s", got) default: return diff --git a/go/vt/vttablet/tabletmanager/vreplication/relaylog.go b/go/vt/vttablet/tabletmanager/vreplication/relaylog.go index b8544e81164..9be66dd75c4 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/relaylog.go +++ b/go/vt/vttablet/tabletmanager/vreplication/relaylog.go @@ -39,9 +39,9 @@ type relayLog struct { curSize int items [][]*binlogdatapb.VEvent err error - // canAccept is true if: curSize<=maxSize, len(items)0, err==nil, ctx is not Done, and call has not timedout. + // hasItems is true if len(items)>0, ctx is not Done, and call has not timedout. hasItems sync.Cond } @@ -124,9 +124,6 @@ func (rl *relayLog) Fetch() ([][]*binlogdatapb.VEvent, error) { } func (rl *relayLog) checkDone() error { - if rl.err != nil { - return rl.err - } select { case <-rl.ctx.Done(): return io.EOF @@ -135,15 +132,6 @@ func (rl *relayLog) checkDone() error { return nil } -func (rl *relayLog) SetError(err error) { - rl.mu.Lock() - defer rl.mu.Unlock() - - rl.err = err - rl.canAccept.Broadcast() - rl.hasItems.Broadcast() -} - func eventsSize(events []*binlogdatapb.VEvent) int { size := 0 for _, event := range events { diff --git a/go/vt/vttablet/tabletmanager/vreplication/vplayer.go b/go/vt/vttablet/tabletmanager/vreplication/vplayer.go index d79640bbcd0..9f21b3f2f50 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/vplayer.go +++ b/go/vt/vttablet/tabletmanager/vreplication/vplayer.go @@ -125,7 +125,7 @@ func (vp *vplayer) play(ctx context.Context) error { return vp.setState(binlogplayer.BlpStopped, fmt.Sprintf("Stop position %v already reached: %v", vp.pos, vp.stopPos)) } } - log.Infof("Starting VReplication player id: %v, startPos: %v, stop: %v, source: %v", vp.id, startPos, vp.stopPos, vp.sourceTablet) + log.Infof("Starting VReplication player id: %v, startPos: %v, stop: %v, source: %v, filter: %v", vp.id, startPos, vp.stopPos, vp.sourceTablet, vp.source) plan, err := buildPlayerPlan(vp.source.Filter) if err != nil { @@ -141,24 +141,40 @@ func (vp *vplayer) play(ctx context.Context) error { defer cancel() relay := newRelayLog(ctx, 10, 10) - go vp.applyEvents(relay) target := &querypb.Target{ Keyspace: vp.sourceTablet.Keyspace, Shard: vp.sourceTablet.Shard, TabletType: vp.sourceTablet.Type, } - return vsClient.VStream(ctx, target, startPos, plan.vstreamFilter, func(events []*binlogdatapb.VEvent) error { - return relay.Send(events) - }) + log.Infof("Sending vstream command: %v", plan.vstreamFilter) + streamErr := make(chan error, 1) + go func() { + streamErr <- vsClient.VStream(ctx, target, startPos, plan.vstreamFilter, func(events []*binlogdatapb.VEvent) error { + return relay.Send(events) + }) + }() + + applyErr := make(chan error, 1) + go func() { + applyErr <- vp.applyEvents(relay) + }() + + select { + case err = <-applyErr: + case err = <-streamErr: + } + if err == io.EOF { + return nil + } + return err } -func (vp *vplayer) applyEvents(relay *relayLog) { +func (vp *vplayer) applyEvents(relay *relayLog) error { for { items, err := relay.Fetch() if err != nil { - relay.SetError(err) - return + return err } // This covers two situations: // 1. Fetch was idle for idleTimeout. @@ -167,8 +183,7 @@ func (vp *vplayer) applyEvents(relay *relayLog) { // to prevent us from falling behind on tracking the source binlog position. if time.Now().Sub(vp.timeLastSaved) >= idleTimeout && vp.unsavedGTID != nil { if err := vp.updatePos(vp.unsavedGTID.Timestamp); err != nil { - relay.SetError(err) - return + return err } } for i, events := range items { @@ -187,8 +202,7 @@ func (vp *vplayer) applyEvents(relay *relayLog) { } } if err := vp.applyEvent(event); err != nil { - relay.SetError(err) - return + return err } } } @@ -354,25 +368,15 @@ func (vp *vplayer) updatePlan(fieldEvent *binlogdatapb.FieldEvent) error { } } } else { - if len(tplan.fields) != len(tplan.colExprs) { - return fmt.Errorf("columns received from vreplication: %v, do not match expected: %v", tplan.fields, tplan.colExprs) - } - for i, field := range tplan.fields { - if tplan.colExprs[i].colname.EqualString(field.Name) { - return fmt.Errorf("column name from vreplication field %d: %s, does not match expected: %s", i, field.Name, tplan.colExprs[i].colname) + for _, cExpr := range tplan.colExprs { + if cExpr.colnum >= len(tplan.fields) { + // Unreachable code. + return fmt.Errorf("columns received from vreplication: %v, do not match expected: %v", tplan.fields, tplan.colExprs) } } } - qr, err := vp.dbClient.ExecuteFetch("select database()", 1) - if err != nil { - return err - } - if len(qr.Rows) == 0 || len(qr.Rows[0]) == 0 { - return fmt.Errorf("unexpected result from 'select database()': %v", qr) - } - dbname := qr.Rows[0][0].ToString() - pkcols, err := vp.mysqld.GetPrimaryKeyColumns(dbname, tplan.name) + pkcols, err := vp.mysqld.GetPrimaryKeyColumns(vp.dbClient.DBName(), tplan.name) if err != nil { return fmt.Errorf("error fetching pk columns for %s: %v", tplan.name, err) } @@ -499,7 +503,7 @@ func (vp *vplayer) writeUpdateValues(sql *sqlparser.TrackedBuffer, tplan *tableP separator = ", " } if cExpr.op == opCount || cExpr.op == opSum { - sql.Myprintf("%s", cExpr.colname) + sql.Myprintf("%v", cExpr.colname) } if len(before) != 0 { switch cExpr.op { diff --git a/go/vt/vttablet/tabletmanager/vreplication/vplayer_test.go b/go/vt/vttablet/tabletmanager/vreplication/vplayer_test.go index a349b026204..a59168f435c 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/vplayer_test.go +++ b/go/vt/vttablet/tabletmanager/vreplication/vplayer_test.go @@ -18,8 +18,8 @@ package vreplication import ( "fmt" + "strings" "testing" - "time" "golang.org/x/net/context" "vitess.io/vitess/go/mysql" @@ -32,44 +32,65 @@ func TestSimple(t *testing.T) { defer deleteTablet(addTablet(100, "0", topodatapb.TabletType_REPLICA, true, true)) execStatements(t, []string{ - "create table t1(id int, val varbinary(128), primary key(id))", - "create table t2(id int, val varbinary(128), primary key(id))", + "create table src1(id int, val varbinary(128), primary key(id))", + "create table dst1(id int, val varbinary(128), primary key(id))", + "create table src2(id int, val1 int, val2 int, primary key(id))", + "create table dst2(id int, val1 int, sval2 int, rcount int, primary key(id))", }) defer execStatements(t, []string{ - "drop table t1", - "drop table t2", + "drop table src1", + "drop table dst1", + "drop table src2", + //"drop table dst2", }) env.SchemaEngine.Reload(context.Background()) filter := &binlogdatapb.Filter{ Rules: []*binlogdatapb.Rule{{ - Match: "t2", - Filter: "select * from t1", + Match: "dst1", + Filter: "select * from src1", + }, { + Match: "dst2", + Filter: "select id, val1, sum(val2) as sval2, count(*) as rcount from src2 group by id", }}, } cancel := startVReplication(t, playerEngine, filter, "") defer cancel() - execStatements(t, []string{ - "insert into t1 values(1, 'aaa')", - "insert into t1 values(2, 'aaa')", - "insert into t1 values(3, 'aaa')", - "insert into t1 values(4, 'aaa')", - }) - time.Sleep(1 * time.Second) - printQueries(t) - /* + testcases := []struct { + input string + output string + }{{ + input: "insert into src1 values(1, 'aaa')", + output: "insert into dst1 set id=1, val='aaa'", + }, { + input: "update src1 set val='bbb'", + output: "update dst1 set id=1, val='bbb' where id=1", + }, { + input: "delete from src1 where id=1", + output: "delete from dst1 where id=1", + }, { + input: "insert into src2 values(1, 2, 3)", + output: "insert into dst2 set id=1, val1=2, sval2=3, rcount=1 on duplicate key update val1=2, sval2=sval2+3, rcount=rcount+1", + }, { + input: "update src2 set val1=5, val2=1 where id=1", + output: "update dst2 set val1=5, sval2=sval2-3+1, rcount=rcount-1+1 where id=1", + }, { + input: "delete from src2 where id=1", + output: "update dst2 set val1=NULL, sval2=sval2-1, rcount=rcount-1 where id=1", + }} + + for _, tcases := range testcases { + execStatements(t, []string{ + tcases.input, + }) expectDBClientQueries(t, []string{ - "update _vt.vreplication set state='Running'.*", "begin", - "update _vt.vreplication set pos=.*", - "commit", - "begin", - "insert into t2 set id=1, val='aaa'", - "update _vt.vreplication set pos=.*", + tcases.output, + "/update _vt.vreplication set pos=.*", "commit", }) - */ + } } func execStatements(t *testing.T, queries []string) { @@ -99,7 +120,12 @@ func startVReplication(t *testing.T, pe *Engine, filter *binlogdatapb.Filter, po if err != nil { t.Fatal(err) } - resetDBClient() + // Eat all the initialization queries + for q := range globalDBQueries { + if strings.HasPrefix(q, "update") { + break + } + } return func() { query := fmt.Sprintf("delete from _vt.vreplication where id = %d", qr.InsertID) if _, err := pe.Exec(query); err != nil { From be97d690ebb45b65d847330e0f883c998bf9ace5 Mon Sep 17 00:00:00 2001 From: Andres Taylor Date: Fri, 18 Jan 2019 16:26:25 +0100 Subject: [PATCH 067/115] Add capability create consistent transactions To make this possible, some things are added: - The capability to lock all tables on a tablet, to momenterily stop updates - Once the database is locked, we can create multiple consistent snapshot transactions that all share the same view of the data - Adds the capability to have replication move forward to a specific point in the transaction log This commit also refactors tabletserver and tx_engine, moving logic of state transitions into the tx engine. Signed-off-by: Andres Taylor --- go/mysql/flavor.go | 9 + go/mysql/flavor_mariadb.go | 4 + go/mysql/flavor_mysql.go | 4 + .../fakemysqldaemon/fakemysqldaemon.go | 14 + go/vt/mysqlctl/mysql_daemon.go | 1 + go/vt/mysqlctl/replication.go | 13 + go/vt/proto/query/query.pb.go | 577 ++++++++-------- .../tabletmanagerdata/tabletmanagerdata.pb.go | 638 ++++++++++++------ .../tabletmanagerservice.pb.go | 237 +++++-- go/vt/vtcombo/tablet_map.go | 16 +- go/vt/vtgate/gateway/discoverygateway_test.go | 2 +- go/vt/vtgate/scatter_conn.go | 4 +- go/vt/vttablet/agentrpctest/test_agent_rpc.go | 23 + go/vt/vttablet/endtoend/framework/client.go | 2 + go/vt/vttablet/faketmclient/fake_client.go | 15 + go/vt/vttablet/grpcqueryservice/server.go | 2 +- go/vt/vttablet/grpctabletconn/conn.go | 5 +- go/vt/vttablet/grpctmclient/client.go | 38 ++ go/vt/vttablet/grpctmserver/server.go | 23 + go/vt/vttablet/queryservice/queryservice.go | 27 +- go/vt/vttablet/queryservice/wrapped.go | 4 +- go/vt/vttablet/sandboxconn/sandboxconn.go | 2 +- .../tabletconntest/fakequeryservice.go | 2 +- .../vttablet/tabletconntest/tabletconntest.go | 8 +- go/vt/vttablet/tabletmanager/action_agent.go | 6 + go/vt/vttablet/tabletmanager/rpc_agent.go | 6 + .../vttablet/tabletmanager/rpc_lock_tables.go | 144 ++++ .../vttablet/tabletmanager/rpc_replication.go | 19 + go/vt/vttablet/tabletserver/connpool/pool.go | 4 +- go/vt/vttablet/tabletserver/query_executor.go | 20 +- go/vt/vttablet/tabletserver/tabletserver.go | 99 +-- .../tabletserver/tabletserver_test.go | 137 ++-- go/vt/vttablet/tabletserver/tx_engine.go | 314 ++++++++- go/vt/vttablet/tabletserver/tx_engine_test.go | 385 ++++++++++- go/vt/vttablet/tabletserver/tx_pool.go | 33 +- go/vt/vttablet/tmclient/rpc_client_api.go | 7 + go/vt/worker/diff_utils.go | 65 ++ go/vt/worker/legacy_split_clone_test.go | 2 +- go/vt/worker/multi_split_diff_test.go | 10 +- go/vt/worker/split_clone_test.go | 2 +- go/vt/worker/split_diff_test.go | 4 +- go/vt/worker/vertical_split_diff_test.go | 2 +- proto/query.proto | 5 + proto/tabletmanagerdata.proto | 20 + proto/tabletmanagerservice.proto | 8 + py/vtproto/query_pb2.py | 259 +++---- py/vtproto/tabletmanagerdata_pb2.py | 416 +++++++++--- py/vtproto/tabletmanagerservice_pb2.py | 83 ++- py/vtproto/tabletmanagerservice_pb2_grpc.py | 52 ++ test/tablet.py | 17 +- test/tabletmanager.py | 2 +- test/tabletmanager2.py | 228 +++++++ test/utils.py | 3 +- 53 files changed, 2992 insertions(+), 1030 deletions(-) create mode 100644 go/vt/vttablet/tabletmanager/rpc_lock_tables.go create mode 100755 test/tabletmanager2.py diff --git a/go/mysql/flavor.go b/go/mysql/flavor.go index 69cf7434b9f..f0a9a53a20d 100644 --- a/go/mysql/flavor.go +++ b/go/mysql/flavor.go @@ -45,6 +45,10 @@ type flavor interface { // startSlave returns the command to start the slave. startSlaveCommand() string + // startSlaveUntilAfter will restart replication, but only allow it + // to run until `pos` is reached. After reaching pos, replication will be stopped again + startSlaveUntilAfter(pos Position) string + // stopSlave returns the command to stop the slave. stopSlaveCommand() string @@ -146,6 +150,11 @@ func (c *Conn) StartSlaveCommand() string { return c.flavor.startSlaveCommand() } +// StartSlaveUntilAfterCommand returns the command to start the slave. +func (c *Conn) StartSlaveUntilAfterCommand(pos Position) string { + return c.flavor.startSlaveUntilAfter(pos) +} + // StopSlaveCommand returns the command to stop the slave. func (c *Conn) StopSlaveCommand() string { return c.flavor.stopSlaveCommand() diff --git a/go/mysql/flavor_mariadb.go b/go/mysql/flavor_mariadb.go index 7374f52d47b..329b6a04b52 100644 --- a/go/mysql/flavor_mariadb.go +++ b/go/mysql/flavor_mariadb.go @@ -41,6 +41,10 @@ func (mariadbFlavor) masterGTIDSet(c *Conn) (GTIDSet, error) { return parseMariadbGTIDSet(qr.Rows[0][0].ToString()) } +func (mariadbFlavor) startSlaveUntilAfter(pos Position) string { + return fmt.Sprintf("START SLAVE UNTIL master_gtid_pos = \"%s\"", pos) +} + func (mariadbFlavor) startSlaveCommand() string { return "START SLAVE" } diff --git a/go/mysql/flavor_mysql.go b/go/mysql/flavor_mysql.go index d8b8eab6c91..3a3fd99400b 100644 --- a/go/mysql/flavor_mysql.go +++ b/go/mysql/flavor_mysql.go @@ -43,6 +43,10 @@ func (mysqlFlavor) startSlaveCommand() string { return "START SLAVE" } +func (mysqlFlavor) startSlaveUntilAfter(pos Position) string { + return fmt.Sprintf("START SLAVE UNTIL SQL_AFTER_GTIDS = '%s'", pos) +} + func (mysqlFlavor) stopSlaveCommand() string { return "STOP SLAVE" } diff --git a/go/vt/mysqlctl/fakemysqldaemon/fakemysqldaemon.go b/go/vt/mysqlctl/fakemysqldaemon/fakemysqldaemon.go index a7d945f06b6..f240b04c0c9 100644 --- a/go/vt/mysqlctl/fakemysqldaemon/fakemysqldaemon.go +++ b/go/vt/mysqlctl/fakemysqldaemon/fakemysqldaemon.go @@ -80,6 +80,9 @@ type FakeMysqlDaemon struct { // If it doesn't match, SetSlavePosition will return an error. SetSlavePositionPos mysql.Position + // StartSlaveUntilAfterPos is matched against the input + StartSlaveUntilAfterPos mysql.Position + // SetMasterInput is matched against the input of SetMaster // (as "%v:%v"). If it doesn't match, SetMaster will return an error. SetMasterInput string @@ -240,6 +243,17 @@ func (fmd *FakeMysqlDaemon) StartSlave(hookExtraEnv map[string]string) error { }) } +// StartSlaveUntilAfter is part of the MysqlDaemon interface. +func (fmd *FakeMysqlDaemon) StartSlaveUntilAfter(ctx context.Context, pos mysql.Position) error { + if !reflect.DeepEqual(fmd.StartSlaveUntilAfterPos, pos) { + return fmt.Errorf("wrong pos for StartSlaveUntilAfter: expected %v got %v", fmd.SetSlavePositionPos, pos) + } + + return fmd.ExecuteSuperQueryList(context.Background(), []string{ + "START SLAVE UNTIL AFTER", + }) +} + // StopSlave is part of the MysqlDaemon interface. func (fmd *FakeMysqlDaemon) StopSlave(hookExtraEnv map[string]string) error { return fmd.ExecuteSuperQueryList(context.Background(), []string{ diff --git a/go/vt/mysqlctl/mysql_daemon.go b/go/vt/mysqlctl/mysql_daemon.go index c8426e8915b..581936b0f74 100644 --- a/go/vt/mysqlctl/mysql_daemon.go +++ b/go/vt/mysqlctl/mysql_daemon.go @@ -41,6 +41,7 @@ type MysqlDaemon interface { // replication related methods StartSlave(hookExtraEnv map[string]string) error + StartSlaveUntilAfter(ctx context.Context, pos mysql.Position) error StopSlave(hookExtraEnv map[string]string) error SlaveStatus() (mysql.SlaveStatus, error) SetSemiSyncEnabled(master, slave bool) error diff --git a/go/vt/mysqlctl/replication.go b/go/vt/mysqlctl/replication.go index 70e08f625e3..12aef08d9ab 100644 --- a/go/vt/mysqlctl/replication.go +++ b/go/vt/mysqlctl/replication.go @@ -83,6 +83,19 @@ func (mysqld *Mysqld) StartSlave(hookExtraEnv map[string]string) error { return h.ExecuteOptional() } +// StartSlaveUntilAfter starts a slave until replication has come to `targetPos`, then it stops replication +func (mysqld *Mysqld) StartSlaveUntilAfter(ctx context.Context, targetPos mysql.Position) error { + conn, err := getPoolReconnect(ctx, mysqld.dbaPool) + if err != nil { + return err + } + defer conn.Recycle() + + queries := []string{conn.StartSlaveUntilAfterCommand(targetPos)} + + return mysqld.executeSuperQueryListConn(ctx, conn, queries) +} + // StopSlave stops a slave. func (mysqld *Mysqld) StopSlave(hookExtraEnv map[string]string) error { h := hook.NewSimpleHook("preflight_stop_slave") diff --git a/go/vt/proto/query/query.pb.go b/go/vt/proto/query/query.pb.go index 1176ca07bd4..34f04da29f9 100644 --- a/go/vt/proto/query/query.pb.go +++ b/go/vt/proto/query/query.pb.go @@ -95,7 +95,7 @@ func (x MySqlFlag) String() string { return proto.EnumName(MySqlFlag_name, int32(x)) } func (MySqlFlag) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_query_1e32bb78b6357529, []int{0} + return fileDescriptor_query_b0bca749772b6512, []int{0} } // Flag allows us to qualify types by their common properties. @@ -134,7 +134,7 @@ func (x Flag) String() string { return proto.EnumName(Flag_name, int32(x)) } func (Flag) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_query_1e32bb78b6357529, []int{1} + return fileDescriptor_query_b0bca749772b6512, []int{1} } // Type defines the various supported data types in bind vars @@ -315,7 +315,7 @@ func (x Type) String() string { return proto.EnumName(Type_name, int32(x)) } func (Type) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_query_1e32bb78b6357529, []int{2} + return fileDescriptor_query_b0bca749772b6512, []int{2} } // TransactionState represents the state of a distributed transaction. @@ -345,7 +345,7 @@ func (x TransactionState) String() string { return proto.EnumName(TransactionState_name, int32(x)) } func (TransactionState) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_query_1e32bb78b6357529, []int{3} + return fileDescriptor_query_b0bca749772b6512, []int{3} } type ExecuteOptions_IncludedFields int32 @@ -371,7 +371,7 @@ func (x ExecuteOptions_IncludedFields) String() string { return proto.EnumName(ExecuteOptions_IncludedFields_name, int32(x)) } func (ExecuteOptions_IncludedFields) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_query_1e32bb78b6357529, []int{6, 0} + return fileDescriptor_query_b0bca749772b6512, []int{6, 0} } type ExecuteOptions_Workload int32 @@ -400,7 +400,7 @@ func (x ExecuteOptions_Workload) String() string { return proto.EnumName(ExecuteOptions_Workload_name, int32(x)) } func (ExecuteOptions_Workload) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_query_1e32bb78b6357529, []int{6, 1} + return fileDescriptor_query_b0bca749772b6512, []int{6, 1} } type ExecuteOptions_TransactionIsolation int32 @@ -411,6 +411,9 @@ const ( ExecuteOptions_READ_COMMITTED ExecuteOptions_TransactionIsolation = 2 ExecuteOptions_READ_UNCOMMITTED ExecuteOptions_TransactionIsolation = 3 ExecuteOptions_SERIALIZABLE ExecuteOptions_TransactionIsolation = 4 + // This is not an "official" transaction level but it will do a + // START TRANSACTION WITH CONSISTENT SNAPSHOT, READ ONLY + ExecuteOptions_CONSISTENT_SNAPSHOT_READ_ONLY ExecuteOptions_TransactionIsolation = 5 ) var ExecuteOptions_TransactionIsolation_name = map[int32]string{ @@ -419,20 +422,22 @@ var ExecuteOptions_TransactionIsolation_name = map[int32]string{ 2: "READ_COMMITTED", 3: "READ_UNCOMMITTED", 4: "SERIALIZABLE", + 5: "CONSISTENT_SNAPSHOT_READ_ONLY", } var ExecuteOptions_TransactionIsolation_value = map[string]int32{ - "DEFAULT": 0, - "REPEATABLE_READ": 1, - "READ_COMMITTED": 2, - "READ_UNCOMMITTED": 3, - "SERIALIZABLE": 4, + "DEFAULT": 0, + "REPEATABLE_READ": 1, + "READ_COMMITTED": 2, + "READ_UNCOMMITTED": 3, + "SERIALIZABLE": 4, + "CONSISTENT_SNAPSHOT_READ_ONLY": 5, } func (x ExecuteOptions_TransactionIsolation) String() string { return proto.EnumName(ExecuteOptions_TransactionIsolation_name, int32(x)) } func (ExecuteOptions_TransactionIsolation) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_query_1e32bb78b6357529, []int{6, 2} + return fileDescriptor_query_b0bca749772b6512, []int{6, 2} } // The category of one statement. @@ -459,7 +464,7 @@ 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_1e32bb78b6357529, []int{12, 0, 0} + return fileDescriptor_query_b0bca749772b6512, []int{12, 0, 0} } type SplitQueryRequest_Algorithm int32 @@ -482,7 +487,7 @@ func (x SplitQueryRequest_Algorithm) String() string { return proto.EnumName(SplitQueryRequest_Algorithm_name, int32(x)) } func (SplitQueryRequest_Algorithm) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_query_1e32bb78b6357529, []int{50, 0} + return fileDescriptor_query_b0bca749772b6512, []int{50, 0} } // Target describes what the client expects the tablet is. @@ -503,7 +508,7 @@ 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_1e32bb78b6357529, []int{0} + return fileDescriptor_query_b0bca749772b6512, []int{0} } func (m *Target) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Target.Unmarshal(m, b) @@ -571,7 +576,7 @@ 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_1e32bb78b6357529, []int{1} + return fileDescriptor_query_b0bca749772b6512, []int{1} } func (m *VTGateCallerID) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_VTGateCallerID.Unmarshal(m, b) @@ -627,7 +632,7 @@ 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_1e32bb78b6357529, []int{2} + return fileDescriptor_query_b0bca749772b6512, []int{2} } func (m *EventToken) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_EventToken.Unmarshal(m, b) @@ -681,7 +686,7 @@ 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_1e32bb78b6357529, []int{3} + return fileDescriptor_query_b0bca749772b6512, []int{3} } func (m *Value) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Value.Unmarshal(m, b) @@ -730,7 +735,7 @@ 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_1e32bb78b6357529, []int{4} + return fileDescriptor_query_b0bca749772b6512, []int{4} } func (m *BindVariable) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_BindVariable.Unmarshal(m, b) @@ -787,7 +792,7 @@ 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_1e32bb78b6357529, []int{5} + return fileDescriptor_query_b0bca749772b6512, []int{5} } func (m *BoundQuery) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_BoundQuery.Unmarshal(m, b) @@ -861,7 +866,7 @@ 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_1e32bb78b6357529, []int{6} + return fileDescriptor_query_b0bca749772b6512, []int{6} } func (m *ExecuteOptions) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ExecuteOptions.Unmarshal(m, b) @@ -967,7 +972,7 @@ 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_1e32bb78b6357529, []int{7} + return fileDescriptor_query_b0bca749772b6512, []int{7} } func (m *Field) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Field.Unmarshal(m, b) @@ -1075,7 +1080,7 @@ 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_1e32bb78b6357529, []int{8} + return fileDescriptor_query_b0bca749772b6512, []int{8} } func (m *Row) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Row.Unmarshal(m, b) @@ -1127,7 +1132,7 @@ 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_1e32bb78b6357529, []int{9} + return fileDescriptor_query_b0bca749772b6512, []int{9} } func (m *ResultExtras) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ResultExtras.Unmarshal(m, b) @@ -1185,7 +1190,7 @@ 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_1e32bb78b6357529, []int{10} + return fileDescriptor_query_b0bca749772b6512, []int{10} } func (m *QueryResult) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_QueryResult.Unmarshal(m, b) @@ -1254,7 +1259,7 @@ 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_1e32bb78b6357529, []int{11} + return fileDescriptor_query_b0bca749772b6512, []int{11} } func (m *QueryWarning) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_QueryWarning.Unmarshal(m, b) @@ -1305,7 +1310,7 @@ 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_1e32bb78b6357529, []int{12} + return fileDescriptor_query_b0bca749772b6512, []int{12} } func (m *StreamEvent) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_StreamEvent.Unmarshal(m, b) @@ -1358,7 +1363,7 @@ 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_1e32bb78b6357529, []int{12, 0} + return fileDescriptor_query_b0bca749772b6512, []int{12, 0} } func (m *StreamEvent_Statement) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_StreamEvent_Statement.Unmarshal(m, b) @@ -1430,7 +1435,7 @@ 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_1e32bb78b6357529, []int{13} + return fileDescriptor_query_b0bca749772b6512, []int{13} } func (m *ExecuteRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ExecuteRequest.Unmarshal(m, b) @@ -1504,7 +1509,7 @@ 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_1e32bb78b6357529, []int{14} + return fileDescriptor_query_b0bca749772b6512, []int{14} } func (m *ExecuteResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ExecuteResponse.Unmarshal(m, b) @@ -1548,7 +1553,7 @@ 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_1e32bb78b6357529, []int{15} + return fileDescriptor_query_b0bca749772b6512, []int{15} } func (m *ResultWithError) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ResultWithError.Unmarshal(m, b) @@ -1600,7 +1605,7 @@ 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_1e32bb78b6357529, []int{16} + return fileDescriptor_query_b0bca749772b6512, []int{16} } func (m *ExecuteBatchRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ExecuteBatchRequest.Unmarshal(m, b) @@ -1681,7 +1686,7 @@ 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_1e32bb78b6357529, []int{17} + return fileDescriptor_query_b0bca749772b6512, []int{17} } func (m *ExecuteBatchResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ExecuteBatchResponse.Unmarshal(m, b) @@ -1715,6 +1720,7 @@ type StreamExecuteRequest struct { Target *Target `protobuf:"bytes,3,opt,name=target,proto3" json:"target,omitempty"` Query *BoundQuery `protobuf:"bytes,4,opt,name=query,proto3" json:"query,omitempty"` Options *ExecuteOptions `protobuf:"bytes,5,opt,name=options,proto3" json:"options,omitempty"` + TransactionId int64 `protobuf:"varint,6,opt,name=transaction_id,json=transactionId,proto3" json:"transaction_id,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -1724,7 +1730,7 @@ 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_1e32bb78b6357529, []int{18} + return fileDescriptor_query_b0bca749772b6512, []int{18} } func (m *StreamExecuteRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_StreamExecuteRequest.Unmarshal(m, b) @@ -1779,6 +1785,13 @@ func (m *StreamExecuteRequest) GetOptions() *ExecuteOptions { return nil } +func (m *StreamExecuteRequest) GetTransactionId() int64 { + if m != nil { + return m.TransactionId + } + return 0 +} + // StreamExecuteResponse is the returned value from StreamExecute type StreamExecuteResponse struct { Result *QueryResult `protobuf:"bytes,1,opt,name=result,proto3" json:"result,omitempty"` @@ -1791,7 +1804,7 @@ 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_1e32bb78b6357529, []int{19} + return fileDescriptor_query_b0bca749772b6512, []int{19} } func (m *StreamExecuteResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_StreamExecuteResponse.Unmarshal(m, b) @@ -1833,7 +1846,7 @@ 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_1e32bb78b6357529, []int{20} + return fileDescriptor_query_b0bca749772b6512, []int{20} } func (m *BeginRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_BeginRequest.Unmarshal(m, b) @@ -1893,7 +1906,7 @@ 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_1e32bb78b6357529, []int{21} + return fileDescriptor_query_b0bca749772b6512, []int{21} } func (m *BeginResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_BeginResponse.Unmarshal(m, b) @@ -1935,7 +1948,7 @@ 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_1e32bb78b6357529, []int{22} + return fileDescriptor_query_b0bca749772b6512, []int{22} } func (m *CommitRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_CommitRequest.Unmarshal(m, b) @@ -1994,7 +2007,7 @@ 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_1e32bb78b6357529, []int{23} + return fileDescriptor_query_b0bca749772b6512, []int{23} } func (m *CommitResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_CommitResponse.Unmarshal(m, b) @@ -2029,7 +2042,7 @@ 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_1e32bb78b6357529, []int{24} + return fileDescriptor_query_b0bca749772b6512, []int{24} } func (m *RollbackRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_RollbackRequest.Unmarshal(m, b) @@ -2088,7 +2101,7 @@ 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_1e32bb78b6357529, []int{25} + return fileDescriptor_query_b0bca749772b6512, []int{25} } func (m *RollbackResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_RollbackResponse.Unmarshal(m, b) @@ -2124,7 +2137,7 @@ 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_1e32bb78b6357529, []int{26} + return fileDescriptor_query_b0bca749772b6512, []int{26} } func (m *PrepareRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_PrepareRequest.Unmarshal(m, b) @@ -2190,7 +2203,7 @@ 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_1e32bb78b6357529, []int{27} + return fileDescriptor_query_b0bca749772b6512, []int{27} } func (m *PrepareResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_PrepareResponse.Unmarshal(m, b) @@ -2225,7 +2238,7 @@ 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_1e32bb78b6357529, []int{28} + return fileDescriptor_query_b0bca749772b6512, []int{28} } func (m *CommitPreparedRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_CommitPreparedRequest.Unmarshal(m, b) @@ -2284,7 +2297,7 @@ 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_1e32bb78b6357529, []int{29} + return fileDescriptor_query_b0bca749772b6512, []int{29} } func (m *CommitPreparedResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_CommitPreparedResponse.Unmarshal(m, b) @@ -2320,7 +2333,7 @@ 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_1e32bb78b6357529, []int{30} + return fileDescriptor_query_b0bca749772b6512, []int{30} } func (m *RollbackPreparedRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_RollbackPreparedRequest.Unmarshal(m, b) @@ -2386,7 +2399,7 @@ 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_1e32bb78b6357529, []int{31} + return fileDescriptor_query_b0bca749772b6512, []int{31} } func (m *RollbackPreparedResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_RollbackPreparedResponse.Unmarshal(m, b) @@ -2422,7 +2435,7 @@ 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_1e32bb78b6357529, []int{32} + return fileDescriptor_query_b0bca749772b6512, []int{32} } func (m *CreateTransactionRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_CreateTransactionRequest.Unmarshal(m, b) @@ -2488,7 +2501,7 @@ 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_1e32bb78b6357529, []int{33} + return fileDescriptor_query_b0bca749772b6512, []int{33} } func (m *CreateTransactionResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_CreateTransactionResponse.Unmarshal(m, b) @@ -2524,7 +2537,7 @@ 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_1e32bb78b6357529, []int{34} + return fileDescriptor_query_b0bca749772b6512, []int{34} } func (m *StartCommitRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_StartCommitRequest.Unmarshal(m, b) @@ -2590,7 +2603,7 @@ 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_1e32bb78b6357529, []int{35} + return fileDescriptor_query_b0bca749772b6512, []int{35} } func (m *StartCommitResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_StartCommitResponse.Unmarshal(m, b) @@ -2626,7 +2639,7 @@ 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_1e32bb78b6357529, []int{36} + return fileDescriptor_query_b0bca749772b6512, []int{36} } func (m *SetRollbackRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_SetRollbackRequest.Unmarshal(m, b) @@ -2692,7 +2705,7 @@ 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_1e32bb78b6357529, []int{37} + return fileDescriptor_query_b0bca749772b6512, []int{37} } func (m *SetRollbackResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_SetRollbackResponse.Unmarshal(m, b) @@ -2727,7 +2740,7 @@ 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_1e32bb78b6357529, []int{38} + return fileDescriptor_query_b0bca749772b6512, []int{38} } func (m *ConcludeTransactionRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ConcludeTransactionRequest.Unmarshal(m, b) @@ -2786,7 +2799,7 @@ 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_1e32bb78b6357529, []int{39} + return fileDescriptor_query_b0bca749772b6512, []int{39} } func (m *ConcludeTransactionResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ConcludeTransactionResponse.Unmarshal(m, b) @@ -2821,7 +2834,7 @@ 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_1e32bb78b6357529, []int{40} + return fileDescriptor_query_b0bca749772b6512, []int{40} } func (m *ReadTransactionRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ReadTransactionRequest.Unmarshal(m, b) @@ -2881,7 +2894,7 @@ 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_1e32bb78b6357529, []int{41} + return fileDescriptor_query_b0bca749772b6512, []int{41} } func (m *ReadTransactionResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ReadTransactionResponse.Unmarshal(m, b) @@ -2924,7 +2937,7 @@ 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_1e32bb78b6357529, []int{42} + return fileDescriptor_query_b0bca749772b6512, []int{42} } func (m *BeginExecuteRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_BeginExecuteRequest.Unmarshal(m, b) @@ -2997,7 +3010,7 @@ 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_1e32bb78b6357529, []int{43} + return fileDescriptor_query_b0bca749772b6512, []int{43} } func (m *BeginExecuteResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_BeginExecuteResponse.Unmarshal(m, b) @@ -3055,7 +3068,7 @@ 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_1e32bb78b6357529, []int{44} + return fileDescriptor_query_b0bca749772b6512, []int{44} } func (m *BeginExecuteBatchRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_BeginExecuteBatchRequest.Unmarshal(m, b) @@ -3135,7 +3148,7 @@ 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_1e32bb78b6357529, []int{45} + return fileDescriptor_query_b0bca749772b6512, []int{45} } func (m *BeginExecuteBatchResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_BeginExecuteBatchResponse.Unmarshal(m, b) @@ -3192,7 +3205,7 @@ 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_1e32bb78b6357529, []int{46} + return fileDescriptor_query_b0bca749772b6512, []int{46} } func (m *MessageStreamRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_MessageStreamRequest.Unmarshal(m, b) @@ -3252,7 +3265,7 @@ 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_1e32bb78b6357529, []int{47} + return fileDescriptor_query_b0bca749772b6512, []int{47} } func (m *MessageStreamResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_MessageStreamResponse.Unmarshal(m, b) @@ -3296,7 +3309,7 @@ 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_1e32bb78b6357529, []int{48} + return fileDescriptor_query_b0bca749772b6512, []int{48} } func (m *MessageAckRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_MessageAckRequest.Unmarshal(m, b) @@ -3366,7 +3379,7 @@ 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_1e32bb78b6357529, []int{49} + return fileDescriptor_query_b0bca749772b6512, []int{49} } func (m *MessageAckResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_MessageAckResponse.Unmarshal(m, b) @@ -3414,7 +3427,7 @@ 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_1e32bb78b6357529, []int{50} + return fileDescriptor_query_b0bca749772b6512, []int{50} } func (m *SplitQueryRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_SplitQueryRequest.Unmarshal(m, b) @@ -3505,7 +3518,7 @@ 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_1e32bb78b6357529, []int{51} + return fileDescriptor_query_b0bca749772b6512, []int{51} } func (m *QuerySplit) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_QuerySplit.Unmarshal(m, b) @@ -3552,7 +3565,7 @@ 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_1e32bb78b6357529, []int{52} + return fileDescriptor_query_b0bca749772b6512, []int{52} } func (m *SplitQueryResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_SplitQueryResponse.Unmarshal(m, b) @@ -3590,7 +3603,7 @@ 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_1e32bb78b6357529, []int{53} + return fileDescriptor_query_b0bca749772b6512, []int{53} } func (m *StreamHealthRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_StreamHealthRequest.Unmarshal(m, b) @@ -3649,7 +3662,7 @@ 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_1e32bb78b6357529, []int{54} + return fileDescriptor_query_b0bca749772b6512, []int{54} } func (m *RealtimeStats) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_RealtimeStats.Unmarshal(m, b) @@ -3737,7 +3750,7 @@ 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_1e32bb78b6357529, []int{55} + return fileDescriptor_query_b0bca749772b6512, []int{55} } func (m *AggregateStats) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_AggregateStats.Unmarshal(m, b) @@ -3849,7 +3862,7 @@ 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_1e32bb78b6357529, []int{56} + return fileDescriptor_query_b0bca749772b6512, []int{56} } func (m *StreamHealthResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_StreamHealthResponse.Unmarshal(m, b) @@ -3933,7 +3946,7 @@ 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_1e32bb78b6357529, []int{57} + return fileDescriptor_query_b0bca749772b6512, []int{57} } func (m *UpdateStreamRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_UpdateStreamRequest.Unmarshal(m, b) @@ -4000,7 +4013,7 @@ 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_1e32bb78b6357529, []int{58} + return fileDescriptor_query_b0bca749772b6512, []int{58} } func (m *UpdateStreamResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_UpdateStreamResponse.Unmarshal(m, b) @@ -4042,7 +4055,7 @@ 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_1e32bb78b6357529, []int{59} + return fileDescriptor_query_b0bca749772b6512, []int{59} } func (m *TransactionMetadata) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_TransactionMetadata.Unmarshal(m, b) @@ -4164,210 +4177,212 @@ func init() { proto.RegisterEnum("query.SplitQueryRequest_Algorithm", SplitQueryRequest_Algorithm_name, SplitQueryRequest_Algorithm_value) } -func init() { proto.RegisterFile("query.proto", fileDescriptor_query_1e32bb78b6357529) } - -var fileDescriptor_query_1e32bb78b6357529 = []byte{ - // 3231 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x5a, 0x4b, 0x73, 0x1b, 0xc7, - 0x76, 0xd6, 0xe0, 0x41, 0x02, 0x07, 0x04, 0xd8, 0x6c, 0x90, 0x12, 0x44, 0xf9, 0xda, 0xcc, 0xdc, - 0xab, 0x7b, 0x19, 0xde, 0x1b, 0x4a, 0xa6, 0x64, 0x45, 0xb1, 0x1d, 0x47, 0x43, 0x70, 0x28, 0xc3, - 0xc2, 0x4b, 0x8d, 0x81, 0x64, 0xa9, 0x5c, 0x35, 0x35, 0x04, 0x5a, 0xe0, 0x14, 0x07, 0x33, 0xd0, - 0xcc, 0x80, 0x14, 0x77, 0x4a, 0x1c, 0xe7, 0xfd, 0x70, 0x9e, 0x8e, 0x93, 0x8a, 0x93, 0xaa, 0xec, - 0xf3, 0x1b, 0x52, 0xf9, 0x01, 0xd9, 0x65, 0x91, 0x64, 0x91, 0x45, 0x2a, 0x95, 0x45, 0xaa, 0x5c, - 0x59, 0x65, 0x91, 0x45, 0x2a, 0xd5, 0x8f, 0x19, 0x0c, 0x48, 0xe8, 0x61, 0xe5, 0x6e, 0x28, 0x7b, - 0xd7, 0x7d, 0xce, 0xe9, 0xc7, 0xf7, 0x9d, 0x33, 0xa7, 0x7b, 0xba, 0x1b, 0x0a, 0x8f, 0xc7, 0xd4, - 0x3f, 0xde, 0x1c, 0xf9, 0x5e, 0xe8, 0xe1, 0x2c, 0xaf, 0xac, 0x96, 0x42, 0x6f, 0xe4, 0xf5, 0xad, - 0xd0, 0x12, 0xe2, 0xd5, 0xc2, 0x61, 0xe8, 0x8f, 0x7a, 0xa2, 0xa2, 0x7e, 0xa6, 0xc0, 0x9c, 0x61, - 0xf9, 0x03, 0x1a, 0xe2, 0x55, 0xc8, 0x1d, 0xd0, 0xe3, 0x60, 0x64, 0xf5, 0x68, 0x45, 0x59, 0x53, - 0xd6, 0xf3, 0x24, 0xae, 0xe3, 0x65, 0xc8, 0x06, 0xfb, 0x96, 0xdf, 0xaf, 0xa4, 0xb8, 0x42, 0x54, - 0xf0, 0x3b, 0x50, 0x08, 0xad, 0x3d, 0x87, 0x86, 0x66, 0x78, 0x3c, 0xa2, 0x95, 0xf4, 0x9a, 0xb2, - 0x5e, 0xda, 0x5a, 0xde, 0x8c, 0xc7, 0x33, 0xb8, 0xd2, 0x38, 0x1e, 0x51, 0x02, 0x61, 0x5c, 0xc6, - 0x18, 0x32, 0x3d, 0xea, 0x38, 0x95, 0x0c, 0xef, 0x8b, 0x97, 0xd5, 0x1d, 0x28, 0xdd, 0x33, 0x6e, - 0x5b, 0x21, 0xad, 0x5a, 0x8e, 0x43, 0xfd, 0xda, 0x0e, 0x9b, 0xce, 0x38, 0xa0, 0xbe, 0x6b, 0x0d, - 0xe3, 0xe9, 0x44, 0x75, 0x7c, 0x1e, 0xe6, 0x06, 0xbe, 0x37, 0x1e, 0x05, 0x95, 0xd4, 0x5a, 0x7a, - 0x3d, 0x4f, 0x64, 0x4d, 0xfd, 0x04, 0x40, 0x3f, 0xa4, 0x6e, 0x68, 0x78, 0x07, 0xd4, 0xc5, 0x6f, - 0x40, 0x3e, 0xb4, 0x87, 0x34, 0x08, 0xad, 0xe1, 0x88, 0x77, 0x91, 0x26, 0x13, 0xc1, 0x33, 0x20, - 0xad, 0x42, 0x6e, 0xe4, 0x05, 0x76, 0x68, 0x7b, 0x2e, 0xc7, 0x93, 0x27, 0x71, 0x5d, 0xfd, 0x00, - 0xb2, 0xf7, 0x2c, 0x67, 0x4c, 0xf1, 0x5b, 0x90, 0xe1, 0x80, 0x15, 0x0e, 0xb8, 0xb0, 0x29, 0x48, - 0xe7, 0x38, 0xb9, 0x82, 0xf5, 0x7d, 0xc8, 0x2c, 0x79, 0xdf, 0x0b, 0x44, 0x54, 0xd4, 0x03, 0x58, - 0xd8, 0xb6, 0xdd, 0xfe, 0x3d, 0xcb, 0xb7, 0x19, 0x19, 0xaf, 0xd8, 0x0d, 0xfe, 0x01, 0xcc, 0xf1, - 0x42, 0x50, 0x49, 0xaf, 0xa5, 0xd7, 0x0b, 0x5b, 0x0b, 0xb2, 0x21, 0x9f, 0x1b, 0x91, 0x3a, 0xf5, - 0xef, 0x15, 0x80, 0x6d, 0x6f, 0xec, 0xf6, 0xef, 0x32, 0x25, 0x46, 0x90, 0x0e, 0x1e, 0x3b, 0x92, - 0x48, 0x56, 0xc4, 0x77, 0xa0, 0xb4, 0x67, 0xbb, 0x7d, 0xf3, 0x50, 0x4e, 0x47, 0x70, 0x59, 0xd8, - 0xfa, 0x81, 0xec, 0x6e, 0xd2, 0x78, 0x33, 0x39, 0xeb, 0x40, 0x77, 0x43, 0xff, 0x98, 0x14, 0xf7, - 0x92, 0xb2, 0xd5, 0x2e, 0xe0, 0xd3, 0x46, 0x6c, 0xd0, 0x03, 0x7a, 0x1c, 0x0d, 0x7a, 0x40, 0x8f, - 0xf1, 0xcf, 0x26, 0x11, 0x15, 0xb6, 0xca, 0xd1, 0x58, 0x89, 0xb6, 0x12, 0xe6, 0xbb, 0xa9, 0x9b, - 0x8a, 0xfa, 0x9f, 0x59, 0x28, 0xe9, 0x4f, 0x68, 0x6f, 0x1c, 0xd2, 0xd6, 0x88, 0xf9, 0x20, 0xc0, - 0x9b, 0x50, 0xb6, 0xdd, 0x9e, 0x33, 0xee, 0x53, 0x93, 0x32, 0x57, 0x9b, 0x21, 0xf3, 0x35, 0xef, - 0x2f, 0x47, 0x96, 0xa4, 0x2a, 0x11, 0x04, 0x1a, 0x94, 0x7b, 0xde, 0x70, 0x64, 0xf9, 0xd3, 0xf6, - 0x69, 0x3e, 0xfe, 0x92, 0x1c, 0x7f, 0x62, 0x4f, 0x96, 0xa4, 0x75, 0xa2, 0x8b, 0x06, 0x2c, 0xca, - 0x7e, 0xfb, 0xe6, 0x23, 0x9b, 0x3a, 0xfd, 0x80, 0x87, 0x6e, 0x29, 0xa6, 0x6a, 0x7a, 0x8a, 0x9b, - 0x35, 0x69, 0xbc, 0xcb, 0x6d, 0x49, 0xc9, 0x9e, 0xaa, 0xe3, 0x0d, 0x58, 0xea, 0x39, 0x36, 0x9b, - 0xca, 0x23, 0x46, 0xb1, 0xe9, 0x7b, 0x47, 0x41, 0x25, 0xcb, 0xe7, 0xbf, 0x28, 0x14, 0xbb, 0x4c, - 0x4e, 0xbc, 0xa3, 0x00, 0xbf, 0x0b, 0xb9, 0x23, 0xcf, 0x3f, 0x70, 0x3c, 0xab, 0x5f, 0x99, 0xe3, - 0x63, 0xbe, 0x39, 0x7b, 0xcc, 0xfb, 0xd2, 0x8a, 0xc4, 0xf6, 0x78, 0x1d, 0x50, 0xf0, 0xd8, 0x31, - 0x03, 0xea, 0xd0, 0x5e, 0x68, 0x3a, 0xf6, 0xd0, 0x0e, 0x2b, 0x39, 0xfe, 0x15, 0x94, 0x82, 0xc7, - 0x4e, 0x87, 0x8b, 0xeb, 0x4c, 0x8a, 0x4d, 0x58, 0x09, 0x7d, 0xcb, 0x0d, 0xac, 0x1e, 0xeb, 0xcc, - 0xb4, 0x03, 0xcf, 0xb1, 0xf8, 0x17, 0x90, 0xe7, 0x43, 0x6e, 0xcc, 0x1e, 0xd2, 0x98, 0x34, 0xa9, - 0x45, 0x2d, 0xc8, 0x72, 0x38, 0x43, 0x8a, 0xdf, 0x86, 0x95, 0xe0, 0xc0, 0x1e, 0x99, 0xbc, 0x1f, - 0x73, 0xe4, 0x58, 0xae, 0xd9, 0xb3, 0x7a, 0xfb, 0xb4, 0x02, 0x1c, 0x36, 0x66, 0x4a, 0x1e, 0x6a, - 0x6d, 0xc7, 0x72, 0xab, 0x4c, 0xa3, 0xbe, 0x07, 0xa5, 0x69, 0x1e, 0xf1, 0x12, 0x14, 0x8d, 0x07, - 0x6d, 0xdd, 0xd4, 0x9a, 0x3b, 0x66, 0x53, 0x6b, 0xe8, 0xe8, 0x1c, 0x2e, 0x42, 0x9e, 0x8b, 0x5a, - 0xcd, 0xfa, 0x03, 0xa4, 0xe0, 0x79, 0x48, 0x6b, 0xf5, 0x3a, 0x4a, 0xa9, 0x37, 0x21, 0x17, 0x11, - 0x82, 0x17, 0xa1, 0xd0, 0x6d, 0x76, 0xda, 0x7a, 0xb5, 0xb6, 0x5b, 0xd3, 0x77, 0xd0, 0x39, 0x9c, - 0x83, 0x4c, 0xab, 0x6e, 0xb4, 0x91, 0x22, 0x4a, 0x5a, 0x1b, 0xa5, 0x58, 0xcb, 0x9d, 0x6d, 0x0d, - 0xa5, 0xd5, 0x10, 0x96, 0x67, 0xe1, 0xc2, 0x05, 0x98, 0xdf, 0xd1, 0x77, 0xb5, 0x6e, 0xdd, 0x40, - 0xe7, 0x70, 0x19, 0x16, 0x89, 0xde, 0xd6, 0x35, 0x43, 0xdb, 0xae, 0xeb, 0x26, 0xd1, 0xb5, 0x1d, - 0xa4, 0x60, 0x0c, 0x25, 0x56, 0x32, 0xab, 0xad, 0x46, 0xa3, 0x66, 0x18, 0xfa, 0x0e, 0x4a, 0xe1, - 0x65, 0x40, 0x5c, 0xd6, 0x6d, 0x4e, 0xa4, 0x69, 0x8c, 0x60, 0xa1, 0xa3, 0x93, 0x9a, 0x56, 0xaf, - 0x3d, 0x64, 0x1d, 0xa0, 0xcc, 0x47, 0x99, 0x9c, 0x82, 0x52, 0xea, 0x17, 0x29, 0xc8, 0x72, 0xac, - 0x2c, 0x43, 0x26, 0xf2, 0x1e, 0x2f, 0xc7, 0xd9, 0x22, 0xf5, 0x9c, 0x6c, 0xc1, 0x93, 0xac, 0xcc, - 0x5b, 0xa2, 0x82, 0x2f, 0x41, 0xde, 0xf3, 0x07, 0xa6, 0xd0, 0x88, 0x8c, 0x9b, 0xf3, 0xfc, 0x01, - 0x4f, 0xcd, 0x2c, 0xdb, 0xb1, 0x44, 0xbd, 0x67, 0x05, 0x94, 0x47, 0x60, 0x9e, 0xc4, 0x75, 0x7c, - 0x11, 0x98, 0x9d, 0xc9, 0xe7, 0x31, 0xc7, 0x75, 0xf3, 0x9e, 0x3f, 0x68, 0xb2, 0xa9, 0x7c, 0x1f, - 0x8a, 0x3d, 0xcf, 0x19, 0x0f, 0x5d, 0xd3, 0xa1, 0xee, 0x20, 0xdc, 0xaf, 0xcc, 0xaf, 0x29, 0xeb, - 0x45, 0xb2, 0x20, 0x84, 0x75, 0x2e, 0xc3, 0x15, 0x98, 0xef, 0xed, 0x5b, 0x7e, 0x40, 0x45, 0xd4, - 0x15, 0x49, 0x54, 0xe5, 0xa3, 0xd2, 0x9e, 0x3d, 0xb4, 0x9c, 0x80, 0x47, 0x58, 0x91, 0xc4, 0x75, - 0x06, 0xe2, 0x91, 0x63, 0x0d, 0x02, 0x1e, 0x19, 0x45, 0x22, 0x2a, 0xea, 0xcf, 0x43, 0x9a, 0x78, - 0x47, 0xac, 0x4b, 0x31, 0x60, 0x50, 0x51, 0xd6, 0xd2, 0xeb, 0x98, 0x44, 0x55, 0xb6, 0x20, 0xc8, - 0x9c, 0x28, 0x52, 0x65, 0x94, 0x05, 0x3f, 0x81, 0x05, 0x42, 0x83, 0xb1, 0x13, 0xea, 0x4f, 0x42, - 0xdf, 0x0a, 0xf0, 0x16, 0x14, 0x92, 0x59, 0x40, 0x79, 0x56, 0x16, 0x00, 0x3a, 0xf9, 0xfc, 0x2b, - 0x30, 0xff, 0xc8, 0xa7, 0xc1, 0x3e, 0xf5, 0x65, 0x96, 0x89, 0xaa, 0x2c, 0xc7, 0x16, 0x78, 0xd8, - 0x8a, 0x31, 0x58, 0x66, 0x96, 0xf9, 0x41, 0x99, 0xca, 0xcc, 0xdc, 0xa9, 0x44, 0xea, 0x18, 0x7b, - 0xec, 0x93, 0x37, 0xad, 0x47, 0x8f, 0x68, 0x2f, 0xa4, 0x62, 0x01, 0xca, 0x90, 0x05, 0x26, 0xd4, - 0xa4, 0x8c, 0xb9, 0xcd, 0x76, 0x03, 0xea, 0x87, 0xa6, 0xdd, 0xe7, 0x0e, 0xcd, 0x90, 0x9c, 0x10, - 0xd4, 0xfa, 0xf8, 0x4d, 0xc8, 0xf0, 0xa4, 0x91, 0xe1, 0xa3, 0x80, 0x1c, 0x85, 0x78, 0x47, 0x84, - 0xcb, 0xf1, 0x8f, 0x61, 0x8e, 0x72, 0xbc, 0xdc, 0xa9, 0x93, 0x34, 0x9b, 0xa4, 0x82, 0x48, 0x13, - 0xf5, 0x7d, 0x58, 0xe0, 0x18, 0xee, 0x5b, 0xbe, 0x6b, 0xbb, 0x03, 0xbe, 0x3a, 0x7b, 0x7d, 0x11, - 0x7b, 0x45, 0xc2, 0xcb, 0x8c, 0x82, 0x21, 0x0d, 0x02, 0x6b, 0x40, 0xe5, 0x6a, 0x19, 0x55, 0xd5, - 0xbf, 0x4e, 0x43, 0xa1, 0x13, 0xfa, 0xd4, 0x1a, 0x72, 0xf6, 0xf0, 0xfb, 0x00, 0x41, 0x68, 0x85, - 0x74, 0x48, 0xdd, 0x30, 0xa2, 0xe1, 0x0d, 0x39, 0x7c, 0xc2, 0x6e, 0xb3, 0x13, 0x19, 0x91, 0x84, - 0xfd, 0x49, 0xf7, 0xa4, 0x5e, 0xc2, 0x3d, 0xab, 0x5f, 0xa5, 0x20, 0x1f, 0xf7, 0x86, 0x35, 0xc8, - 0xf5, 0xac, 0x90, 0x0e, 0x3c, 0xff, 0x58, 0xae, 0xab, 0x97, 0x9f, 0x37, 0xfa, 0x66, 0x55, 0x1a, - 0x93, 0xb8, 0x19, 0xfe, 0x1e, 0x88, 0xcd, 0x8a, 0x08, 0x7d, 0x81, 0x37, 0xcf, 0x25, 0x3c, 0xf8, - 0xdf, 0x05, 0x3c, 0xf2, 0xed, 0xa1, 0xe5, 0x1f, 0x9b, 0x07, 0xf4, 0x38, 0x5a, 0x10, 0xd2, 0x33, - 0x1c, 0x8e, 0xa4, 0xdd, 0x1d, 0x7a, 0x2c, 0x53, 0xd8, 0xcd, 0xe9, 0xb6, 0x32, 0x64, 0x4f, 0xbb, - 0x31, 0xd1, 0x92, 0xaf, 0xea, 0x41, 0xb4, 0x7e, 0x67, 0x79, 0x74, 0xb3, 0xa2, 0xfa, 0x23, 0xc8, - 0x45, 0x93, 0xc7, 0x79, 0xc8, 0xea, 0xbe, 0xef, 0xf9, 0xe8, 0x1c, 0xcf, 0x64, 0x8d, 0xba, 0x48, - 0x86, 0x3b, 0x3b, 0x2c, 0x19, 0xfe, 0x5d, 0x2a, 0x5e, 0x44, 0x09, 0x7d, 0x3c, 0xa6, 0x41, 0x88, - 0x7f, 0x09, 0xca, 0x94, 0x47, 0x9a, 0x7d, 0x48, 0xcd, 0x1e, 0xdf, 0x71, 0xb1, 0x38, 0x13, 0x9f, - 0xc3, 0xe2, 0xa6, 0xd8, 0x20, 0x46, 0x3b, 0x31, 0xb2, 0x14, 0xdb, 0x4a, 0x51, 0x1f, 0xeb, 0x50, - 0xb6, 0x87, 0x43, 0xda, 0xb7, 0xad, 0x30, 0xd9, 0x81, 0x70, 0xd8, 0x4a, 0xb4, 0x21, 0x99, 0xda, - 0xd0, 0x91, 0xa5, 0xb8, 0x45, 0xdc, 0xcd, 0x65, 0x98, 0x0b, 0xf9, 0xe6, 0x53, 0xae, 0xc7, 0xc5, - 0x28, 0xab, 0x71, 0x21, 0x91, 0x4a, 0xfc, 0x23, 0x10, 0x5b, 0x59, 0x9e, 0xbf, 0x26, 0x01, 0x31, - 0xd9, 0xa1, 0x10, 0xa1, 0xc7, 0x97, 0xa1, 0x34, 0xb5, 0x90, 0xf5, 0x39, 0x61, 0x69, 0x52, 0x4c, - 0xae, 0x4a, 0x7d, 0x7c, 0x05, 0xe6, 0x3d, 0xb1, 0x88, 0xf1, 0xcc, 0x36, 0x99, 0xf1, 0xf4, 0x0a, - 0x47, 0x22, 0x2b, 0xf5, 0x17, 0x61, 0x31, 0x66, 0x30, 0x18, 0x79, 0x6e, 0x40, 0xf1, 0x06, 0xcc, - 0xf9, 0xfc, 0x73, 0x92, 0xac, 0x61, 0xd9, 0x45, 0x22, 0x1f, 0x10, 0x69, 0xa1, 0xf6, 0x61, 0x51, - 0x48, 0xee, 0xdb, 0xe1, 0x3e, 0x77, 0x14, 0xbe, 0x0c, 0x59, 0xca, 0x0a, 0x27, 0x38, 0x27, 0xed, - 0x2a, 0xd7, 0x13, 0xa1, 0x4d, 0x8c, 0x92, 0x7a, 0xe1, 0x28, 0xff, 0x95, 0x82, 0xb2, 0x9c, 0xe5, - 0xb6, 0x15, 0xf6, 0xf6, 0xcf, 0xa8, 0xb3, 0x7f, 0x0c, 0xf3, 0x4c, 0x6e, 0xc7, 0x1f, 0xc6, 0x0c, - 0x77, 0x47, 0x16, 0xcc, 0xe1, 0x56, 0x60, 0x26, 0xbc, 0x2b, 0x37, 0x52, 0x45, 0x2b, 0x48, 0x2c, - 0xe3, 0x33, 0xe2, 0x62, 0xee, 0x05, 0x71, 0x31, 0xff, 0x52, 0x71, 0xb1, 0x03, 0xcb, 0xd3, 0x8c, - 0xcb, 0xe0, 0xf8, 0x09, 0xcc, 0x0b, 0xa7, 0x44, 0x29, 0x70, 0x96, 0xdf, 0x22, 0x13, 0xf5, 0xaf, - 0x52, 0xb0, 0x2c, 0xb3, 0xd3, 0xb7, 0xe3, 0x33, 0x4d, 0xf0, 0x9c, 0x7d, 0x29, 0x9e, 0xab, 0xb0, - 0x72, 0x82, 0xa0, 0x57, 0xf8, 0x0a, 0xbf, 0x56, 0x60, 0x61, 0x9b, 0x0e, 0x6c, 0xf7, 0x8c, 0xd2, - 0x9b, 0x60, 0x2d, 0xf3, 0x52, 0xac, 0xdd, 0x80, 0xa2, 0xc4, 0x2b, 0xd9, 0x3a, 0xfd, 0x19, 0x28, - 0x33, 0x3e, 0x03, 0xf5, 0xdf, 0x15, 0x28, 0x56, 0xbd, 0xe1, 0xd0, 0x0e, 0xcf, 0x28, 0x53, 0xa7, - 0x71, 0x66, 0x66, 0xe1, 0x44, 0x50, 0x8a, 0x60, 0x0a, 0x82, 0xd4, 0xff, 0x50, 0x60, 0x91, 0x78, - 0x8e, 0xb3, 0x67, 0xf5, 0x0e, 0x5e, 0x6f, 0xec, 0x18, 0xd0, 0x04, 0xa8, 0x44, 0xff, 0x3f, 0x0a, - 0x94, 0xda, 0x3e, 0x65, 0x7f, 0xbf, 0xaf, 0x35, 0x78, 0xb6, 0xc5, 0xed, 0x87, 0x72, 0x73, 0x90, - 0x27, 0xbc, 0xac, 0x2e, 0xc1, 0x62, 0x8c, 0x5d, 0xf2, 0xf1, 0xcf, 0x0a, 0xac, 0x88, 0x00, 0x91, - 0x9a, 0xfe, 0x19, 0xa5, 0x25, 0xc2, 0x9b, 0x49, 0xe0, 0xad, 0xc0, 0xf9, 0x93, 0xd8, 0x24, 0xec, - 0x4f, 0x53, 0x70, 0x21, 0x8a, 0x8d, 0x33, 0x0e, 0xfc, 0xff, 0x11, 0x0f, 0xab, 0x50, 0x39, 0x4d, - 0x82, 0x64, 0xe8, 0xf3, 0x14, 0x54, 0xaa, 0x3e, 0xb5, 0x42, 0x9a, 0xd8, 0x64, 0xbc, 0x3e, 0xb1, - 0x81, 0xdf, 0x86, 0x85, 0x91, 0xe5, 0x87, 0x76, 0xcf, 0x1e, 0x59, 0xec, 0x37, 0x2e, 0xcb, 0xf7, - 0x30, 0x27, 0x3a, 0x98, 0x32, 0x51, 0x2f, 0xc1, 0xc5, 0x19, 0x8c, 0x48, 0xbe, 0xfe, 0x57, 0x01, - 0xdc, 0x09, 0x2d, 0x3f, 0xfc, 0x16, 0xac, 0x2a, 0x33, 0x83, 0x69, 0x05, 0xca, 0x53, 0xf8, 0x93, - 0xbc, 0xd0, 0xf0, 0x5b, 0xb1, 0xe2, 0x3c, 0x93, 0x97, 0x24, 0x7e, 0xc9, 0xcb, 0xbf, 0x2a, 0xb0, - 0x5a, 0xf5, 0xc4, 0xe9, 0xdf, 0x6b, 0xf9, 0x85, 0xa9, 0xdf, 0x83, 0x4b, 0x33, 0x01, 0x4a, 0x02, - 0xfe, 0x45, 0x81, 0xf3, 0x84, 0x5a, 0xfd, 0xd7, 0x13, 0xfc, 0x5d, 0xb8, 0x70, 0x0a, 0x9c, 0xdc, - 0xa1, 0xde, 0x80, 0xdc, 0x90, 0x86, 0x56, 0xdf, 0x0a, 0x2d, 0x09, 0x69, 0x35, 0xea, 0x77, 0x62, - 0xdd, 0x90, 0x16, 0x24, 0xb6, 0x55, 0xbf, 0x4a, 0x41, 0x99, 0xef, 0x75, 0xbf, 0xfb, 0x83, 0x9a, - 0xfd, 0x2f, 0xf0, 0xb9, 0x02, 0xcb, 0xd3, 0x04, 0xc5, 0xff, 0x04, 0x3f, 0xed, 0x83, 0x88, 0x19, - 0x09, 0x21, 0x3d, 0x6b, 0x0b, 0xfa, 0x0f, 0x29, 0xa8, 0x24, 0xa7, 0xf4, 0xdd, 0xa1, 0xc5, 0xf4, - 0xa1, 0xc5, 0x37, 0x3e, 0xa5, 0xfa, 0x42, 0x81, 0x8b, 0x33, 0x08, 0xfd, 0x66, 0x8e, 0x4e, 0x1c, - 0x5d, 0xa4, 0x5e, 0x78, 0x74, 0xf1, 0xb2, 0xae, 0xfe, 0x27, 0x05, 0x96, 0x1b, 0xe2, 0xc4, 0x58, - 0xfc, 0xc7, 0x9f, 0xdd, 0x6c, 0xc6, 0x0f, 0x85, 0x33, 0x93, 0x7b, 0x19, 0xb5, 0x0a, 0x2b, 0x27, - 0xa0, 0xbd, 0xc2, 0xd9, 0xc4, 0x7f, 0x2b, 0xb0, 0x24, 0x7b, 0xd1, 0xce, 0xec, 0x46, 0x60, 0x06, - 0x3b, 0xf8, 0x4d, 0x48, 0xdb, 0xfd, 0x68, 0x07, 0x39, 0x7d, 0x53, 0xcd, 0x14, 0xea, 0x2d, 0xc0, - 0x49, 0xdc, 0xaf, 0x40, 0xdd, 0x3f, 0xa6, 0x61, 0xa9, 0x33, 0x72, 0xec, 0x50, 0x2a, 0x5f, 0xef, - 0xc4, 0xff, 0x33, 0xb0, 0x10, 0x30, 0xb0, 0xa6, 0xb8, 0x6b, 0xe3, 0xc4, 0xe6, 0x49, 0x81, 0xcb, - 0xaa, 0x5c, 0x84, 0xdf, 0x82, 0x42, 0x64, 0x32, 0x76, 0x43, 0x79, 0xd2, 0x09, 0xd2, 0x62, 0xec, - 0x86, 0xf8, 0x3a, 0x5c, 0x70, 0xc7, 0x43, 0x7e, 0xef, 0x6c, 0x8e, 0xa8, 0x1f, 0xdd, 0xca, 0x5a, - 0x7e, 0x74, 0x3f, 0x5c, 0x76, 0xc7, 0x43, 0xe2, 0x1d, 0x05, 0x6d, 0xea, 0x8b, 0x5b, 0x59, 0xcb, - 0x0f, 0xf1, 0x2d, 0xc8, 0x5b, 0xce, 0xc0, 0xf3, 0xed, 0x70, 0x7f, 0x28, 0x2f, 0x86, 0xd5, 0xe8, - 0x6a, 0xe5, 0x24, 0xfd, 0x9b, 0x5a, 0x64, 0x49, 0x26, 0x8d, 0xd4, 0x9f, 0x40, 0x3e, 0x96, 0x63, - 0x04, 0x0b, 0xfa, 0xdd, 0xae, 0x56, 0x37, 0x3b, 0xed, 0x7a, 0xcd, 0xe8, 0x88, 0xcb, 0xdc, 0xdd, - 0x6e, 0xbd, 0x6e, 0x76, 0xaa, 0x5a, 0x13, 0x29, 0x2a, 0x01, 0xe0, 0x5d, 0xf2, 0xce, 0x27, 0x04, - 0x29, 0x2f, 0x20, 0xe8, 0x12, 0xe4, 0x7d, 0xef, 0x48, 0x62, 0x4f, 0x71, 0x38, 0x39, 0xdf, 0x3b, - 0xe2, 0xc8, 0x55, 0x0d, 0x70, 0x72, 0xae, 0x32, 0xda, 0x12, 0xc9, 0x5b, 0x99, 0x4a, 0xde, 0x93, - 0xf1, 0xe3, 0xe4, 0x2d, 0xb6, 0xf2, 0xec, 0x3b, 0xff, 0x90, 0x5a, 0x4e, 0x18, 0xad, 0x57, 0xea, - 0xdf, 0xa4, 0xa0, 0x48, 0x98, 0xc4, 0x1e, 0xd2, 0x4e, 0x68, 0x85, 0x01, 0xf3, 0xd4, 0x3e, 0x37, - 0x31, 0x27, 0x69, 0x37, 0x4f, 0x0a, 0x42, 0x26, 0x2e, 0x01, 0xb6, 0x60, 0x25, 0xa0, 0x3d, 0xcf, - 0xed, 0x07, 0xe6, 0x1e, 0xdd, 0xb7, 0xdd, 0xbe, 0x39, 0xb4, 0x82, 0x50, 0xde, 0x33, 0x16, 0x49, - 0x59, 0x2a, 0xb7, 0xb9, 0xae, 0xc1, 0x55, 0xf8, 0x2a, 0x2c, 0xef, 0xd9, 0xae, 0xe3, 0x0d, 0xcc, - 0x91, 0x63, 0x1d, 0x53, 0x3f, 0x90, 0x50, 0x59, 0x78, 0x65, 0x09, 0x16, 0xba, 0xb6, 0x50, 0x09, - 0x77, 0x3f, 0x84, 0x8d, 0x99, 0xa3, 0x98, 0x8f, 0x6c, 0x27, 0xa4, 0x3e, 0xed, 0x9b, 0x3e, 0x1d, - 0x39, 0x76, 0x4f, 0x5c, 0xf9, 0x8b, 0xbd, 0xfb, 0x0f, 0x67, 0x0c, 0xbd, 0x2b, 0xcd, 0xc9, 0xc4, - 0x9a, 0xb1, 0xdd, 0x1b, 0x8d, 0xcd, 0x31, 0xbf, 0x1a, 0x64, 0xab, 0x98, 0x42, 0x72, 0xbd, 0xd1, - 0xb8, 0xcb, 0xea, 0x18, 0x41, 0xfa, 0xf1, 0x48, 0x2c, 0x5e, 0x0a, 0x61, 0x45, 0xf5, 0x6b, 0x05, - 0x4a, 0xda, 0x60, 0xe0, 0xd3, 0x81, 0x15, 0x4a, 0x9a, 0xae, 0xc2, 0xb2, 0xa0, 0xe4, 0xd8, 0x94, - 0x6f, 0x89, 0x04, 0x1e, 0x45, 0xe0, 0x91, 0x3a, 0xf1, 0x92, 0x28, 0x0a, 0xdf, 0xf3, 0x63, 0x77, - 0x66, 0x9b, 0x14, 0x6f, 0xb3, 0x1c, 0x6b, 0x93, 0xad, 0x7e, 0x01, 0x2e, 0xce, 0x66, 0x61, 0x68, - 0x8b, 0xd7, 0x20, 0x45, 0x72, 0x7e, 0x06, 0xe8, 0x86, 0xed, 0x3e, 0xa7, 0xa9, 0xf5, 0x84, 0xf3, - 0xf5, 0x8c, 0xa6, 0xd6, 0x13, 0xf5, 0xdf, 0xe2, 0xa3, 0xfd, 0x28, 0x5c, 0xe2, 0xd5, 0x38, 0xca, - 0x0b, 0xca, 0xf3, 0xf2, 0x42, 0x05, 0xe6, 0x03, 0xea, 0x1f, 0xda, 0xee, 0x20, 0xba, 0x7b, 0x96, - 0x55, 0xdc, 0x81, 0x1f, 0x4a, 0xec, 0xf4, 0x49, 0x48, 0x7d, 0xd7, 0x72, 0x9c, 0x63, 0x53, 0x1c, - 0x54, 0xb8, 0x21, 0xed, 0x9b, 0x93, 0x97, 0x4f, 0x62, 0x45, 0xfe, 0xbe, 0xb0, 0xd6, 0x63, 0x63, - 0x12, 0xdb, 0x1a, 0xf1, 0x9b, 0xa8, 0xf7, 0xa0, 0xe4, 0xcb, 0x20, 0x36, 0x03, 0xe6, 0x1e, 0x99, - 0x8f, 0x96, 0xe3, 0x0b, 0xe4, 0x44, 0x84, 0x93, 0xa2, 0x3f, 0x15, 0xf0, 0x1f, 0xc0, 0xa2, 0x15, - 0xf9, 0x56, 0xb6, 0x9e, 0xde, 0xb7, 0x4c, 0x7b, 0x9e, 0x94, 0xac, 0xe9, 0x48, 0xb8, 0x09, 0x0b, - 0x12, 0x91, 0xe5, 0xd8, 0xd6, 0x64, 0x63, 0x7b, 0xe2, 0x39, 0x99, 0xc6, 0x94, 0x44, 0x3e, 0x3c, - 0xe3, 0x15, 0xf6, 0x1f, 0x5d, 0xee, 0x8e, 0xfa, 0xbc, 0xa7, 0x33, 0xbc, 0xbb, 0x48, 0xbe, 0x3d, - 0xcb, 0x4c, 0xbf, 0x3d, 0x9b, 0x7e, 0xcb, 0x96, 0x3d, 0xf1, 0x96, 0x4d, 0xbd, 0x05, 0xcb, 0xd3, - 0xf8, 0x65, 0x94, 0xad, 0x43, 0x96, 0xdf, 0x94, 0x9f, 0x58, 0x46, 0x13, 0x57, 0xe1, 0x44, 0x18, - 0xa8, 0x7f, 0xab, 0x40, 0x79, 0xc6, 0x2f, 0x56, 0xfc, 0xff, 0xa6, 0x24, 0x8e, 0x87, 0x7e, 0x0e, - 0xb2, 0xfc, 0xce, 0x5e, 0x3e, 0x45, 0xb9, 0x70, 0xfa, 0x0f, 0x8d, 0xdf, 0xaf, 0x13, 0x61, 0xc5, - 0x12, 0x21, 0x0f, 0xa8, 0x1e, 0x3f, 0x1f, 0x8a, 0x76, 0x88, 0x05, 0x26, 0x13, 0x47, 0x46, 0xa7, - 0x0f, 0x9c, 0x32, 0x2f, 0x3c, 0x70, 0xda, 0xf8, 0xc3, 0x34, 0xe4, 0x1b, 0xc7, 0x9d, 0xc7, 0xce, - 0xae, 0x63, 0x0d, 0xf8, 0x05, 0x78, 0xa3, 0x6d, 0x3c, 0x40, 0xe7, 0xf0, 0x12, 0x14, 0x9b, 0x2d, - 0xc3, 0x6c, 0xb2, 0xa5, 0x64, 0xb7, 0xae, 0xdd, 0x46, 0x0a, 0x5b, 0x6b, 0xda, 0xa4, 0x66, 0xde, - 0xd1, 0x1f, 0x08, 0x49, 0x0a, 0x97, 0x61, 0xb1, 0xdb, 0xac, 0xdd, 0xed, 0xea, 0x13, 0x61, 0x06, - 0xaf, 0xc0, 0x52, 0xa3, 0x5b, 0x37, 0x6a, 0xed, 0x7a, 0x42, 0x9c, 0x63, 0xeb, 0xd2, 0x76, 0xbd, - 0xb5, 0x2d, 0xaa, 0x88, 0xf5, 0xdf, 0x6d, 0x76, 0x6a, 0xb7, 0x9b, 0xfa, 0x8e, 0x10, 0xad, 0x31, - 0xd1, 0x43, 0x9d, 0xb4, 0x76, 0x6b, 0xd1, 0x90, 0xb7, 0x30, 0x82, 0xc2, 0x76, 0xad, 0xa9, 0x11, - 0xd9, 0xcb, 0x53, 0x05, 0x97, 0x20, 0xaf, 0x37, 0xbb, 0x0d, 0x59, 0x4f, 0xe1, 0x0a, 0x94, 0xb5, - 0xae, 0xd1, 0x32, 0x6b, 0xcd, 0x2a, 0xd1, 0x1b, 0x7a, 0xd3, 0x90, 0x9a, 0x0c, 0x2e, 0x43, 0xc9, - 0xa8, 0x35, 0xf4, 0x8e, 0xa1, 0x35, 0xda, 0x52, 0xc8, 0x66, 0x91, 0xeb, 0xe8, 0x91, 0x0d, 0xc2, - 0xab, 0xb0, 0xd2, 0x6c, 0x99, 0xf2, 0x49, 0x92, 0x79, 0x4f, 0xab, 0x77, 0x75, 0xa9, 0x5b, 0xc3, - 0x17, 0x00, 0xb7, 0x9a, 0x66, 0xb7, 0xbd, 0xa3, 0x19, 0xba, 0xd9, 0x6c, 0xdd, 0x97, 0x8a, 0x5b, - 0xb8, 0x04, 0xb9, 0xc9, 0x0c, 0x9e, 0x32, 0x16, 0x8a, 0x6d, 0x8d, 0x18, 0x13, 0xb0, 0x4f, 0x9f, - 0x32, 0xb2, 0xe0, 0x36, 0x69, 0x75, 0xdb, 0x13, 0xb3, 0x25, 0x28, 0x48, 0xb2, 0xa4, 0x28, 0xc3, - 0x44, 0xdb, 0xb5, 0x66, 0x35, 0x9e, 0xdf, 0xd3, 0xdc, 0x6a, 0x0a, 0x29, 0x1b, 0x07, 0x90, 0xe1, - 0xee, 0xc8, 0x41, 0xa6, 0xd9, 0x6a, 0xea, 0xe8, 0x1c, 0x5e, 0x04, 0xa8, 0x75, 0x6a, 0x4d, 0x43, - 0xbf, 0x4d, 0xb4, 0x3a, 0x83, 0xcd, 0x05, 0x11, 0x81, 0x0c, 0xed, 0x02, 0xcc, 0xd7, 0x3a, 0xbb, - 0xf5, 0x96, 0x66, 0x48, 0x98, 0xb5, 0xce, 0xdd, 0x6e, 0xcb, 0x60, 0x4a, 0x84, 0x0b, 0x30, 0x57, - 0xeb, 0x18, 0xfa, 0xc7, 0x06, 0xc3, 0xc5, 0x75, 0x82, 0x55, 0xf4, 0xf4, 0xd6, 0xc6, 0x97, 0x69, - 0xc8, 0xf0, 0xf7, 0xa4, 0x45, 0xc8, 0x73, 0x6f, 0x1b, 0x0f, 0xda, 0x6c, 0xc8, 0x3c, 0x64, 0x6a, - 0x4d, 0xe3, 0x26, 0xfa, 0xe5, 0x14, 0x06, 0xc8, 0x76, 0x79, 0xf9, 0x57, 0xe6, 0x58, 0xb9, 0xd6, - 0x34, 0xde, 0xbe, 0x81, 0x3e, 0x4d, 0xb1, 0x6e, 0xbb, 0xa2, 0xf2, 0xab, 0x91, 0x62, 0xeb, 0x3a, - 0xfa, 0x2c, 0x56, 0x6c, 0x5d, 0x47, 0xbf, 0x16, 0x29, 0xae, 0x6d, 0xa1, 0x5f, 0x8f, 0x15, 0xd7, - 0xb6, 0xd0, 0x6f, 0x44, 0x8a, 0x1b, 0xd7, 0xd1, 0x6f, 0xc6, 0x8a, 0x1b, 0xd7, 0xd1, 0x6f, 0xcd, - 0x31, 0x2c, 0x1c, 0xc9, 0xb5, 0x2d, 0xf4, 0xdb, 0xb9, 0xb8, 0x76, 0xe3, 0x3a, 0xfa, 0x9d, 0x1c, - 0xf3, 0x7f, 0xec, 0x55, 0xf4, 0xbb, 0x88, 0x4d, 0x93, 0x39, 0x08, 0xfd, 0x1e, 0x2f, 0x32, 0x15, - 0xfa, 0x7d, 0xc4, 0x30, 0x32, 0x29, 0xaf, 0x7e, 0xce, 0x35, 0x0f, 0x74, 0x8d, 0xa0, 0x3f, 0x98, - 0x13, 0x2f, 0xd0, 0xaa, 0xb5, 0x86, 0x56, 0x47, 0x98, 0xb7, 0x60, 0xac, 0xfc, 0xd1, 0x55, 0x56, - 0x64, 0xe1, 0x89, 0xfe, 0xb8, 0xcd, 0x06, 0xbc, 0xa7, 0x91, 0xea, 0x87, 0x1a, 0x41, 0x7f, 0x72, - 0x95, 0x0d, 0x78, 0x4f, 0x23, 0x92, 0xaf, 0x3f, 0x6d, 0x33, 0x43, 0xae, 0xfa, 0xe2, 0x2a, 0x9b, - 0xb4, 0x94, 0xff, 0x59, 0x1b, 0xe7, 0x20, 0xbd, 0x5d, 0x33, 0xd0, 0x97, 0x7c, 0x34, 0x16, 0xa2, - 0xe8, 0xcf, 0x11, 0x13, 0x76, 0x74, 0x03, 0xfd, 0x05, 0x13, 0x66, 0x8d, 0x6e, 0xbb, 0xae, 0xa3, - 0x37, 0xd8, 0xe4, 0x6e, 0xeb, 0xad, 0x86, 0x6e, 0x90, 0x07, 0xe8, 0x2f, 0xb9, 0xf9, 0x47, 0x9d, - 0x56, 0x13, 0x7d, 0x85, 0x70, 0x09, 0x40, 0xff, 0xb8, 0x4d, 0xf4, 0x4e, 0xa7, 0xd6, 0x6a, 0xa2, - 0xb7, 0x36, 0x76, 0x01, 0x9d, 0x4c, 0x07, 0x0c, 0x40, 0xb7, 0x79, 0xa7, 0xd9, 0xba, 0xdf, 0x44, - 0xe7, 0x58, 0xa5, 0x4d, 0xf4, 0xb6, 0x46, 0x74, 0xa4, 0x60, 0x80, 0x39, 0xf1, 0x3e, 0x0e, 0xa5, - 0xf0, 0x02, 0xe4, 0x48, 0xab, 0x5e, 0xdf, 0xd6, 0xaa, 0x77, 0x50, 0x7a, 0xfb, 0x1d, 0x58, 0xb4, - 0xbd, 0xcd, 0x43, 0x3b, 0xa4, 0x41, 0x20, 0x5e, 0x2c, 0x3f, 0x54, 0x65, 0xcd, 0xf6, 0xae, 0x88, - 0xd2, 0x95, 0x81, 0x77, 0xe5, 0x30, 0xbc, 0xc2, 0xb5, 0x57, 0x78, 0xc6, 0xd8, 0x9b, 0xe3, 0x95, - 0x6b, 0xff, 0x17, 0x00, 0x00, 0xff, 0xff, 0xda, 0x0b, 0x47, 0xfb, 0x0f, 0x2d, 0x00, 0x00, +func init() { proto.RegisterFile("query.proto", fileDescriptor_query_b0bca749772b6512) } + +var fileDescriptor_query_b0bca749772b6512 = []byte{ + // 3259 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x5a, 0xcd, 0x73, 0x1b, 0xc9, + 0x75, 0xd7, 0xe0, 0x8b, 0xc0, 0x03, 0x01, 0x36, 0x1b, 0xa4, 0x84, 0xe5, 0x7e, 0xd1, 0x63, 0xaf, + 0xcd, 0xd0, 0x0e, 0xa5, 0xe5, 0xca, 0x8a, 0xb2, 0x76, 0x1c, 0x0d, 0xc1, 0xa1, 0x16, 0x16, 0x30, + 0x80, 0x1a, 0x03, 0xc9, 0xda, 0x72, 0xd5, 0xd4, 0x10, 0x68, 0x81, 0x53, 0x1c, 0xcc, 0x40, 0x33, + 0x03, 0x52, 0xbc, 0x29, 0x71, 0x9c, 0xef, 0xc4, 0x9b, 0xcf, 0x8d, 0x93, 0xca, 0x56, 0xaa, 0x72, + 0xcf, 0xdf, 0x90, 0xca, 0x21, 0xc7, 0xdc, 0x72, 0x48, 0x72, 0xc8, 0x21, 0x95, 0xca, 0xcd, 0x95, + 0x53, 0x0e, 0x39, 0xa4, 0x52, 0xfd, 0x31, 0x83, 0x01, 0x89, 0x95, 0x64, 0x25, 0x17, 0x6a, 0x7d, + 0xeb, 0x7e, 0xef, 0xf5, 0xc7, 0xef, 0xf7, 0xde, 0xbc, 0xee, 0xe9, 0x6e, 0x28, 0x3f, 0x99, 0xd2, + 0xe0, 0x6c, 0x67, 0x12, 0xf8, 0x91, 0x8f, 0xf3, 0xbc, 0xb2, 0x51, 0x8d, 0xfc, 0x89, 0x3f, 0xb4, + 0x23, 0x5b, 0x88, 0x37, 0xca, 0x27, 0x51, 0x30, 0x19, 0x88, 0x8a, 0xfa, 0x43, 0x05, 0x0a, 0xa6, + 0x1d, 0x8c, 0x68, 0x84, 0x37, 0xa0, 0x78, 0x4c, 0xcf, 0xc2, 0x89, 0x3d, 0xa0, 0x75, 0x65, 0x53, + 0xd9, 0x2a, 0x91, 0xa4, 0x8e, 0xd7, 0x20, 0x1f, 0x1e, 0xd9, 0xc1, 0xb0, 0x9e, 0xe1, 0x0a, 0x51, + 0xc1, 0xdf, 0x84, 0x72, 0x64, 0x1f, 0xba, 0x34, 0xb2, 0xa2, 0xb3, 0x09, 0xad, 0x67, 0x37, 0x95, + 0xad, 0xea, 0xee, 0xda, 0x4e, 0x32, 0x9e, 0xc9, 0x95, 0xe6, 0xd9, 0x84, 0x12, 0x88, 0x92, 0x32, + 0xc6, 0x90, 0x1b, 0x50, 0xd7, 0xad, 0xe7, 0x78, 0x5f, 0xbc, 0xac, 0xee, 0x43, 0xf5, 0x81, 0x79, + 0xd7, 0x8e, 0x68, 0xc3, 0x76, 0x5d, 0x1a, 0x34, 0xf7, 0xd9, 0x74, 0xa6, 0x21, 0x0d, 0x3c, 0x7b, + 0x9c, 0x4c, 0x27, 0xae, 0xe3, 0xab, 0x50, 0x18, 0x05, 0xfe, 0x74, 0x12, 0xd6, 0x33, 0x9b, 0xd9, + 0xad, 0x12, 0x91, 0x35, 0xf5, 0xfb, 0x00, 0xfa, 0x09, 0xf5, 0x22, 0xd3, 0x3f, 0xa6, 0x1e, 0x7e, + 0x0b, 0x4a, 0x91, 0x33, 0xa6, 0x61, 0x64, 0x8f, 0x27, 0xbc, 0x8b, 0x2c, 0x99, 0x09, 0x3e, 0x07, + 0xd2, 0x06, 0x14, 0x27, 0x7e, 0xe8, 0x44, 0x8e, 0xef, 0x71, 0x3c, 0x25, 0x92, 0xd4, 0xd5, 0xef, + 0x40, 0xfe, 0x81, 0xed, 0x4e, 0x29, 0x7e, 0x17, 0x72, 0x1c, 0xb0, 0xc2, 0x01, 0x97, 0x77, 0x04, + 0xe9, 0x1c, 0x27, 0x57, 0xb0, 0xbe, 0x4f, 0x98, 0x25, 0xef, 0x7b, 0x99, 0x88, 0x8a, 0x7a, 0x0c, + 0xcb, 0x7b, 0x8e, 0x37, 0x7c, 0x60, 0x07, 0x0e, 0x23, 0xe3, 0x15, 0xbb, 0xc1, 0x5f, 0x81, 0x02, + 0x2f, 0x84, 0xf5, 0xec, 0x66, 0x76, 0xab, 0xbc, 0xbb, 0x2c, 0x1b, 0xf2, 0xb9, 0x11, 0xa9, 0x53, + 0xff, 0x4e, 0x01, 0xd8, 0xf3, 0xa7, 0xde, 0xf0, 0x3e, 0x53, 0x62, 0x04, 0xd9, 0xf0, 0x89, 0x2b, + 0x89, 0x64, 0x45, 0x7c, 0x0f, 0xaa, 0x87, 0x8e, 0x37, 0xb4, 0x4e, 0xe4, 0x74, 0x04, 0x97, 0xe5, + 0xdd, 0xaf, 0xc8, 0xee, 0x66, 0x8d, 0x77, 0xd2, 0xb3, 0x0e, 0x75, 0x2f, 0x0a, 0xce, 0x48, 0xe5, + 0x30, 0x2d, 0xdb, 0xe8, 0x03, 0xbe, 0x68, 0xc4, 0x06, 0x3d, 0xa6, 0x67, 0xf1, 0xa0, 0xc7, 0xf4, + 0x0c, 0xff, 0x5c, 0x1a, 0x51, 0x79, 0xb7, 0x16, 0x8f, 0x95, 0x6a, 0x2b, 0x61, 0x7e, 0x98, 0xb9, + 0xad, 0xa8, 0x3f, 0x2a, 0x40, 0x55, 0x7f, 0x4a, 0x07, 0xd3, 0x88, 0x76, 0x26, 0xcc, 0x07, 0x21, + 0xde, 0x81, 0x9a, 0xe3, 0x0d, 0xdc, 0xe9, 0x90, 0x5a, 0x94, 0xb9, 0xda, 0x8a, 0x98, 0xaf, 0x79, + 0x7f, 0x45, 0xb2, 0x2a, 0x55, 0xa9, 0x20, 0xd0, 0xa0, 0x36, 0xf0, 0xc7, 0x13, 0x3b, 0x98, 0xb7, + 0xcf, 0xf2, 0xf1, 0x57, 0xe5, 0xf8, 0x33, 0x7b, 0xb2, 0x2a, 0xad, 0x53, 0x5d, 0xb4, 0x61, 0x45, + 0xf6, 0x3b, 0xb4, 0x1e, 0x3b, 0xd4, 0x1d, 0x86, 0x3c, 0x74, 0xab, 0x09, 0x55, 0xf3, 0x53, 0xdc, + 0x69, 0x4a, 0xe3, 0x03, 0x6e, 0x4b, 0xaa, 0xce, 0x5c, 0x1d, 0x6f, 0xc3, 0xea, 0xc0, 0x75, 0xd8, + 0x54, 0x1e, 0x33, 0x8a, 0xad, 0xc0, 0x3f, 0x0d, 0xeb, 0x79, 0x3e, 0xff, 0x15, 0xa1, 0x38, 0x60, + 0x72, 0xe2, 0x9f, 0x86, 0xf8, 0x43, 0x28, 0x9e, 0xfa, 0xc1, 0xb1, 0xeb, 0xdb, 0xc3, 0x7a, 0x81, + 0x8f, 0xf9, 0xce, 0xe2, 0x31, 0x1f, 0x4a, 0x2b, 0x92, 0xd8, 0xe3, 0x2d, 0x40, 0xe1, 0x13, 0xd7, + 0x0a, 0xa9, 0x4b, 0x07, 0x91, 0xe5, 0x3a, 0x63, 0x27, 0xaa, 0x17, 0xf9, 0x57, 0x50, 0x0d, 0x9f, + 0xb8, 0x3d, 0x2e, 0x6e, 0x31, 0x29, 0xb6, 0x60, 0x3d, 0x0a, 0x6c, 0x2f, 0xb4, 0x07, 0xac, 0x33, + 0xcb, 0x09, 0x7d, 0xd7, 0xe6, 0x5f, 0x40, 0x89, 0x0f, 0xb9, 0xbd, 0x78, 0x48, 0x73, 0xd6, 0xa4, + 0x19, 0xb7, 0x20, 0x6b, 0xd1, 0x02, 0x29, 0x7e, 0x1f, 0xd6, 0xc3, 0x63, 0x67, 0x62, 0xf1, 0x7e, + 0xac, 0x89, 0x6b, 0x7b, 0xd6, 0xc0, 0x1e, 0x1c, 0xd1, 0x3a, 0x70, 0xd8, 0x98, 0x29, 0x79, 0xa8, + 0x75, 0x5d, 0xdb, 0x6b, 0x30, 0x8d, 0xfa, 0x2d, 0xa8, 0xce, 0xf3, 0x88, 0x57, 0xa1, 0x62, 0x3e, + 0xea, 0xea, 0x96, 0x66, 0xec, 0x5b, 0x86, 0xd6, 0xd6, 0xd1, 0x15, 0x5c, 0x81, 0x12, 0x17, 0x75, + 0x8c, 0xd6, 0x23, 0xa4, 0xe0, 0x25, 0xc8, 0x6a, 0xad, 0x16, 0xca, 0xa8, 0xb7, 0xa1, 0x18, 0x13, + 0x82, 0x57, 0xa0, 0xdc, 0x37, 0x7a, 0x5d, 0xbd, 0xd1, 0x3c, 0x68, 0xea, 0xfb, 0xe8, 0x0a, 0x2e, + 0x42, 0xae, 0xd3, 0x32, 0xbb, 0x48, 0x11, 0x25, 0xad, 0x8b, 0x32, 0xac, 0xe5, 0xfe, 0x9e, 0x86, + 0xb2, 0xea, 0xa7, 0x0a, 0xac, 0x2d, 0x02, 0x86, 0xcb, 0xb0, 0xb4, 0xaf, 0x1f, 0x68, 0xfd, 0x96, + 0x89, 0xae, 0xe0, 0x1a, 0xac, 0x10, 0xbd, 0xab, 0x6b, 0xa6, 0xb6, 0xd7, 0xd2, 0x2d, 0xa2, 0x6b, + 0xfb, 0x48, 0xc1, 0x18, 0xaa, 0xac, 0x64, 0x35, 0x3a, 0xed, 0x76, 0xd3, 0x34, 0xf5, 0x7d, 0x94, + 0xc1, 0x6b, 0x80, 0xb8, 0xac, 0x6f, 0xcc, 0xa4, 0x59, 0x8c, 0x60, 0xb9, 0xa7, 0x93, 0xa6, 0xd6, + 0x6a, 0x7e, 0xcc, 0x3a, 0x40, 0x39, 0xfc, 0x25, 0x78, 0xbb, 0xd1, 0x31, 0x7a, 0xcd, 0x9e, 0xa9, + 0x1b, 0xa6, 0xd5, 0x33, 0xb4, 0x6e, 0xef, 0xa3, 0x8e, 0xc9, 0x7b, 0x16, 0xe0, 0xf2, 0xdf, 0xcd, + 0x15, 0x15, 0x94, 0x51, 0x3f, 0xcd, 0x40, 0x9e, 0xf3, 0xc1, 0xb2, 0x68, 0x2a, 0x37, 0xf2, 0x72, + 0x92, 0x51, 0x32, 0xcf, 0xc9, 0x28, 0x3c, 0x11, 0xcb, 0xdc, 0x26, 0x2a, 0xf8, 0x4d, 0x28, 0xf9, + 0xc1, 0xc8, 0x12, 0x1a, 0x91, 0x95, 0x8b, 0x7e, 0x30, 0xe2, 0xe9, 0x9b, 0x65, 0x44, 0x96, 0xcc, + 0x0f, 0xed, 0x90, 0xf2, 0x28, 0x2d, 0x91, 0xa4, 0x8e, 0xdf, 0x00, 0x66, 0x67, 0xf1, 0x79, 0x14, + 0xb8, 0x6e, 0xc9, 0x0f, 0x46, 0x06, 0x9b, 0xca, 0x97, 0xa1, 0x32, 0xf0, 0xdd, 0xe9, 0xd8, 0xb3, + 0x5c, 0xea, 0x8d, 0xa2, 0xa3, 0xfa, 0xd2, 0xa6, 0xb2, 0x55, 0x21, 0xcb, 0x42, 0xd8, 0xe2, 0x32, + 0x5c, 0x87, 0xa5, 0xc1, 0x91, 0x1d, 0x84, 0x54, 0x44, 0x66, 0x85, 0xc4, 0x55, 0x3e, 0x2a, 0x1d, + 0x38, 0x63, 0xdb, 0x0d, 0x79, 0x14, 0x56, 0x48, 0x52, 0x67, 0x20, 0x1e, 0xbb, 0xf6, 0x28, 0xe4, + 0xd1, 0x53, 0x21, 0xa2, 0xa2, 0xfe, 0x02, 0x64, 0x89, 0x7f, 0xca, 0xba, 0x14, 0x03, 0x86, 0x75, + 0x65, 0x33, 0xbb, 0x85, 0x49, 0x5c, 0x65, 0x8b, 0x86, 0xcc, 0x9b, 0x22, 0x9d, 0xc6, 0x99, 0xf2, + 0xfb, 0xb0, 0x4c, 0x68, 0x38, 0x75, 0x23, 0xfd, 0x69, 0x14, 0xd8, 0x21, 0xde, 0x85, 0x72, 0x3a, + 0x53, 0x28, 0x9f, 0x97, 0x29, 0x80, 0xce, 0x52, 0x44, 0x1d, 0x96, 0x1e, 0x07, 0x34, 0x3c, 0xa2, + 0x81, 0xcc, 0x44, 0x71, 0x95, 0xe5, 0xe1, 0x32, 0x0f, 0x6d, 0x31, 0x06, 0xcb, 0xde, 0x32, 0x87, + 0x28, 0x73, 0xd9, 0x9b, 0x3b, 0x95, 0x48, 0x1d, 0x63, 0x8f, 0xa5, 0x05, 0xcb, 0x7e, 0xfc, 0x98, + 0x0e, 0x22, 0x2a, 0x16, 0xa9, 0x1c, 0x59, 0x66, 0x42, 0x4d, 0xca, 0x98, 0xdb, 0x1c, 0x2f, 0xa4, + 0x41, 0x64, 0x39, 0x43, 0xee, 0xd0, 0x1c, 0x29, 0x0a, 0x41, 0x73, 0x88, 0xdf, 0x81, 0x1c, 0x4f, + 0x2c, 0x39, 0x3e, 0x0a, 0xc8, 0x51, 0x88, 0x7f, 0x4a, 0xb8, 0x1c, 0x7f, 0x1d, 0x0a, 0x94, 0xe3, + 0xe5, 0x4e, 0x9d, 0xa5, 0xe2, 0x34, 0x15, 0x44, 0x9a, 0xa8, 0xdf, 0x86, 0x65, 0x8e, 0xe1, 0xa1, + 0x1d, 0x78, 0x8e, 0x37, 0xe2, 0x2b, 0xb8, 0x3f, 0x14, 0xb1, 0x57, 0x21, 0xbc, 0xcc, 0x28, 0x18, + 0xd3, 0x30, 0xb4, 0x47, 0x54, 0xae, 0xa8, 0x71, 0x55, 0xfd, 0xab, 0x2c, 0x94, 0x7b, 0x51, 0x40, + 0xed, 0x31, 0x67, 0x0f, 0x7f, 0x1b, 0x20, 0x8c, 0xec, 0x88, 0x8e, 0xa9, 0x17, 0xc5, 0x34, 0xbc, + 0x25, 0x87, 0x4f, 0xd9, 0xed, 0xf4, 0x62, 0x23, 0x92, 0xb2, 0x3f, 0xef, 0x9e, 0xcc, 0x4b, 0xb8, + 0x67, 0xe3, 0xb3, 0x0c, 0x94, 0x92, 0xde, 0xb0, 0x06, 0xc5, 0x81, 0x1d, 0xd1, 0x91, 0x1f, 0x9c, + 0xc9, 0xb5, 0xf7, 0xbd, 0xe7, 0x8d, 0xbe, 0xd3, 0x90, 0xc6, 0x24, 0x69, 0x86, 0xdf, 0x06, 0xb1, + 0xa1, 0x11, 0xa1, 0x2f, 0xf0, 0x96, 0xb8, 0x84, 0x07, 0xff, 0x87, 0x80, 0x27, 0x81, 0x33, 0xb6, + 0x83, 0x33, 0xeb, 0x98, 0x9e, 0xc5, 0x8b, 0x46, 0x76, 0x81, 0xc3, 0x91, 0xb4, 0xbb, 0x47, 0xcf, + 0x64, 0x9a, 0xbb, 0x3d, 0xdf, 0x56, 0x86, 0xec, 0x45, 0x37, 0xa6, 0x5a, 0xf2, 0x95, 0x3f, 0x8c, + 0xd7, 0xf8, 0x3c, 0x8f, 0x6e, 0x56, 0x54, 0xbf, 0x06, 0xc5, 0x78, 0xf2, 0xb8, 0x04, 0x79, 0x3d, + 0x08, 0xfc, 0x00, 0x5d, 0xe1, 0xd9, 0xae, 0xdd, 0x12, 0x09, 0x73, 0x7f, 0x9f, 0x25, 0xcc, 0xbf, + 0xcd, 0x24, 0x0b, 0x2d, 0xa1, 0x4f, 0xa6, 0x34, 0x8c, 0xf0, 0x2f, 0x43, 0x8d, 0xf2, 0x48, 0x73, + 0x4e, 0xa8, 0x35, 0xe0, 0xbb, 0x32, 0x16, 0x67, 0xe2, 0x73, 0x58, 0xd9, 0x11, 0x9b, 0xc8, 0x78, + 0xb7, 0x46, 0x56, 0x13, 0x5b, 0x29, 0x1a, 0x62, 0x1d, 0x6a, 0xce, 0x78, 0x4c, 0x87, 0x8e, 0x1d, + 0xa5, 0x3b, 0x10, 0x0e, 0x5b, 0x8f, 0x37, 0x2d, 0x73, 0x9b, 0x3e, 0xb2, 0x9a, 0xb4, 0x48, 0xba, + 0x79, 0x0f, 0x0a, 0x11, 0xdf, 0xa0, 0xca, 0x35, 0xbb, 0x12, 0x67, 0x35, 0x2e, 0x24, 0x52, 0x89, + 0xbf, 0x06, 0x62, 0xbb, 0xcb, 0xf3, 0xd7, 0x2c, 0x20, 0x66, 0xbb, 0x18, 0x22, 0xf4, 0xf8, 0x3d, + 0xa8, 0xce, 0x2d, 0x76, 0x43, 0x4e, 0x58, 0x96, 0x54, 0xd2, 0x2b, 0xd7, 0x10, 0x5f, 0x87, 0x25, + 0x5f, 0x2c, 0x74, 0x3c, 0xb3, 0xcd, 0x66, 0x3c, 0xbf, 0x0a, 0x92, 0xd8, 0x4a, 0xfd, 0x25, 0x58, + 0x49, 0x18, 0x0c, 0x27, 0xbe, 0x17, 0x52, 0xbc, 0x0d, 0x85, 0x80, 0x7f, 0x4e, 0x92, 0x35, 0x2c, + 0xbb, 0x48, 0xe5, 0x03, 0x22, 0x2d, 0xd4, 0x21, 0xac, 0x08, 0xc9, 0x43, 0x27, 0x3a, 0xe2, 0x8e, + 0xc2, 0xef, 0x41, 0x9e, 0xb2, 0xc2, 0x39, 0xce, 0x49, 0xb7, 0xc1, 0xf5, 0x44, 0x68, 0x53, 0xa3, + 0x64, 0x5e, 0x38, 0xca, 0x7f, 0x66, 0xa0, 0x26, 0x67, 0xb9, 0x67, 0x47, 0x83, 0xa3, 0x4b, 0xea, + 0xec, 0xaf, 0xc3, 0x12, 0x93, 0x3b, 0xc9, 0x87, 0xb1, 0xc0, 0xdd, 0xb1, 0x05, 0x73, 0xb8, 0x1d, + 0x5a, 0x29, 0xef, 0xca, 0xcd, 0x56, 0xc5, 0x0e, 0x53, 0x2b, 0xfd, 0x82, 0xb8, 0x28, 0xbc, 0x20, + 0x2e, 0x96, 0x5e, 0x2a, 0x2e, 0xf6, 0x61, 0x6d, 0x9e, 0x71, 0x19, 0x1c, 0xdf, 0x80, 0x25, 0xe1, + 0x94, 0x38, 0x05, 0x2e, 0xf2, 0x5b, 0x6c, 0xa2, 0xfe, 0x7d, 0x06, 0xd6, 0x64, 0x76, 0xfa, 0x62, + 0x7c, 0xa6, 0x29, 0x9e, 0xf3, 0x2f, 0xc3, 0xf3, 0x4b, 0xfa, 0x4f, 0x6d, 0xc0, 0xfa, 0x39, 0x1e, + 0x5f, 0xe1, 0x63, 0xfd, 0x89, 0x02, 0xcb, 0x7b, 0x74, 0xe4, 0x78, 0x97, 0xd4, 0x0b, 0x29, 0x72, + 0x73, 0x2f, 0x15, 0xc4, 0xb7, 0xa0, 0x22, 0xf1, 0x4a, 0xb6, 0x2e, 0xb2, 0xad, 0x2c, 0x62, 0xfb, + 0xdf, 0x15, 0xa8, 0x34, 0xfc, 0xf1, 0xd8, 0x89, 0x2e, 0x29, 0x53, 0x17, 0x71, 0xe6, 0x16, 0xe1, + 0x44, 0x50, 0x8d, 0x61, 0x0a, 0x82, 0xd4, 0xff, 0x50, 0x60, 0x85, 0xf8, 0xae, 0x7b, 0x68, 0x0f, + 0x8e, 0x5f, 0x6f, 0xec, 0x18, 0xd0, 0x0c, 0xa8, 0x44, 0xff, 0xdf, 0x0a, 0x54, 0xbb, 0x01, 0x65, + 0x3f, 0xd2, 0xaf, 0x35, 0x78, 0xb6, 0x13, 0x1e, 0x46, 0x72, 0x0f, 0x51, 0x22, 0xbc, 0xac, 0xae, + 0xc2, 0x4a, 0x82, 0x5d, 0xf2, 0xf1, 0xcf, 0x0a, 0xac, 0x8b, 0x00, 0x91, 0x9a, 0xe1, 0x25, 0xa5, + 0x25, 0xc6, 0x9b, 0x4b, 0xe1, 0xad, 0xc3, 0xd5, 0xf3, 0xd8, 0x24, 0xec, 0x1f, 0x64, 0xe0, 0x5a, + 0x1c, 0x1b, 0x97, 0x1c, 0xf8, 0xff, 0x21, 0x1e, 0x36, 0xa0, 0x7e, 0x91, 0x04, 0xc9, 0xd0, 0x27, + 0x19, 0xa8, 0x37, 0x02, 0x6a, 0x47, 0x34, 0xb5, 0x17, 0x79, 0x7d, 0x62, 0x03, 0xbf, 0x0f, 0xcb, + 0x13, 0x3b, 0x88, 0x9c, 0x81, 0x33, 0xb1, 0xd9, 0xdf, 0x5e, 0x9e, 0x6f, 0x75, 0xce, 0x75, 0x30, + 0x67, 0xa2, 0xbe, 0x09, 0x6f, 0x2c, 0x60, 0x44, 0xf2, 0xf5, 0x3f, 0x0a, 0xe0, 0x5e, 0x64, 0x07, + 0xd1, 0x17, 0x60, 0x55, 0x59, 0x18, 0x4c, 0xeb, 0x50, 0x9b, 0xc3, 0x9f, 0xe6, 0x85, 0x46, 0x5f, + 0x88, 0x15, 0xe7, 0x73, 0x79, 0x49, 0xe3, 0x97, 0xbc, 0xfc, 0xab, 0x02, 0x1b, 0x0d, 0x5f, 0x1c, + 0x24, 0xbe, 0x96, 0x5f, 0x98, 0xfa, 0x36, 0xbc, 0xb9, 0x10, 0xa0, 0x24, 0xe0, 0x5f, 0x14, 0xb8, + 0x4a, 0xa8, 0x3d, 0x7c, 0x3d, 0xc1, 0xdf, 0x87, 0x6b, 0x17, 0xc0, 0xc9, 0x1d, 0xea, 0x2d, 0x28, + 0x8e, 0x69, 0x64, 0x0f, 0xed, 0xc8, 0x96, 0x90, 0x36, 0xe2, 0x7e, 0x67, 0xd6, 0x6d, 0x69, 0x41, + 0x12, 0x5b, 0xf5, 0xb3, 0x0c, 0xd4, 0xf8, 0x5e, 0xf7, 0x67, 0x3f, 0x5a, 0x8b, 0xff, 0x05, 0x3e, + 0x51, 0x60, 0x6d, 0x9e, 0xa0, 0xe4, 0x9f, 0xe0, 0xff, 0xfb, 0xbc, 0x62, 0x41, 0x42, 0xc8, 0x2e, + 0xda, 0x82, 0xfe, 0x43, 0x06, 0xea, 0xe9, 0x29, 0xfd, 0xec, 0x6c, 0x63, 0xfe, 0x6c, 0xe3, 0xa7, + 0x3e, 0xcc, 0xfa, 0x54, 0x81, 0x37, 0x16, 0x10, 0xfa, 0xd3, 0x39, 0x3a, 0x75, 0xc2, 0x91, 0x79, + 0xe1, 0x09, 0xc7, 0xcb, 0xba, 0xfa, 0x9f, 0x14, 0x58, 0x6b, 0x8b, 0x83, 0x65, 0xf1, 0x1f, 0x7f, + 0x79, 0xb3, 0x19, 0x3f, 0x3b, 0xce, 0xcd, 0xae, 0x6f, 0xd4, 0x06, 0xac, 0x9f, 0x83, 0xf6, 0x0a, + 0x67, 0x13, 0xff, 0xa5, 0xc0, 0xaa, 0xec, 0x45, 0xbb, 0xb4, 0x1b, 0x81, 0x05, 0xec, 0xe0, 0x77, + 0x20, 0xeb, 0x0c, 0xe3, 0x1d, 0xe4, 0xfc, 0xa5, 0x37, 0x53, 0xa8, 0x77, 0x00, 0xa7, 0x71, 0xbf, + 0x02, 0x75, 0xff, 0x98, 0x85, 0xd5, 0xde, 0xc4, 0x75, 0x22, 0xa9, 0x7c, 0xbd, 0x13, 0xff, 0x97, + 0x60, 0x39, 0x64, 0x60, 0x2d, 0x71, 0x25, 0xc7, 0x89, 0x2d, 0x91, 0x32, 0x97, 0x35, 0xb8, 0x08, + 0xbf, 0x0b, 0xe5, 0xd8, 0x64, 0xea, 0x45, 0xf2, 0x40, 0x0d, 0xa4, 0xc5, 0xd4, 0x8b, 0xf0, 0x4d, + 0xb8, 0xe6, 0x4d, 0xc7, 0xfc, 0x0a, 0xdb, 0x9a, 0xd0, 0x20, 0xbe, 0xe0, 0xb5, 0x83, 0xf8, 0xaa, + 0xb9, 0xe6, 0x4d, 0xc7, 0xc4, 0x3f, 0x0d, 0xbb, 0x34, 0x10, 0x17, 0xbc, 0x76, 0x10, 0xe1, 0x3b, + 0x50, 0xb2, 0xdd, 0x91, 0x1f, 0x38, 0xd1, 0xd1, 0x58, 0xde, 0x31, 0xab, 0xf1, 0x0d, 0xcc, 0x79, + 0xfa, 0x77, 0xb4, 0xd8, 0x92, 0xcc, 0x1a, 0xa9, 0xdf, 0x80, 0x52, 0x22, 0xc7, 0x08, 0x96, 0xf5, + 0xfb, 0x7d, 0xad, 0x65, 0xf5, 0xba, 0xad, 0xa6, 0xd9, 0x13, 0xf7, 0xc2, 0x07, 0xfd, 0x56, 0xcb, + 0xea, 0x35, 0x34, 0x03, 0x29, 0x2a, 0x01, 0xe0, 0x5d, 0xf2, 0xce, 0x67, 0x04, 0x29, 0x2f, 0x20, + 0xe8, 0x4d, 0x28, 0x05, 0xfe, 0xa9, 0xc4, 0x9e, 0xe1, 0x70, 0x8a, 0x81, 0x7f, 0xca, 0x91, 0xab, + 0x1a, 0xe0, 0xf4, 0x5c, 0x65, 0xb4, 0xa5, 0x92, 0xb7, 0x32, 0x97, 0xbc, 0x67, 0xe3, 0x27, 0xc9, + 0x5b, 0x6c, 0xe5, 0xd9, 0x77, 0xfe, 0x11, 0xb5, 0xdd, 0x28, 0x5e, 0xaf, 0xd4, 0xbf, 0xce, 0x40, + 0x85, 0x30, 0x89, 0x33, 0xa6, 0xbd, 0xc8, 0x8e, 0x42, 0xe6, 0xa9, 0x23, 0x6e, 0x62, 0xcd, 0xd2, + 0x6e, 0x89, 0x94, 0x85, 0x4c, 0xdc, 0x15, 0xec, 0xc2, 0x7a, 0x48, 0x07, 0xbe, 0x37, 0x0c, 0xad, + 0x43, 0x7a, 0xe4, 0x78, 0x43, 0x6b, 0x6c, 0x87, 0x91, 0xbc, 0x8e, 0xac, 0x90, 0x9a, 0x54, 0xee, + 0x71, 0x5d, 0x9b, 0xab, 0xf0, 0x0d, 0x58, 0x3b, 0x74, 0x3c, 0xd7, 0x1f, 0x59, 0x13, 0xd7, 0x3e, + 0xa3, 0x41, 0x28, 0xa1, 0xb2, 0xf0, 0xca, 0x13, 0x2c, 0x74, 0x5d, 0xa1, 0x12, 0xee, 0xfe, 0x18, + 0xb6, 0x17, 0x8e, 0x62, 0x3d, 0x76, 0xdc, 0x88, 0x06, 0x74, 0x68, 0x05, 0x74, 0xe2, 0x3a, 0x03, + 0xf1, 0x7a, 0x40, 0xec, 0xdd, 0xbf, 0xba, 0x60, 0xe8, 0x03, 0x69, 0x4e, 0x66, 0xd6, 0x8c, 0xed, + 0xc1, 0x64, 0x6a, 0x4d, 0xf9, 0x0d, 0x22, 0x5b, 0xc5, 0x14, 0x52, 0x1c, 0x4c, 0xa6, 0x7d, 0x56, + 0xc7, 0x08, 0xb2, 0x4f, 0x26, 0x62, 0xf1, 0x52, 0x08, 0x2b, 0xaa, 0x3f, 0x51, 0xa0, 0xaa, 0x8d, + 0x46, 0x01, 0x1d, 0xd9, 0x91, 0xa4, 0xe9, 0x06, 0xac, 0x09, 0x4a, 0xce, 0x2c, 0xf9, 0x2c, 0x49, + 0xe0, 0x51, 0x04, 0x1e, 0xa9, 0x13, 0x8f, 0x92, 0xe2, 0xf0, 0xbd, 0x3a, 0xf5, 0x16, 0xb6, 0xc9, + 0xf0, 0x36, 0x6b, 0x89, 0x36, 0xdd, 0xea, 0x17, 0xe1, 0x8d, 0xc5, 0x2c, 0x8c, 0x1d, 0xf1, 0xb0, + 0xa4, 0x42, 0xae, 0x2e, 0x00, 0xdd, 0x76, 0xbc, 0xe7, 0x34, 0xb5, 0x9f, 0x72, 0xbe, 0x3e, 0xa7, + 0xa9, 0xfd, 0x54, 0xfd, 0xb7, 0xe4, 0x06, 0x20, 0x0e, 0x97, 0x64, 0x35, 0x8e, 0xf3, 0x82, 0xf2, + 0xbc, 0xbc, 0x50, 0x87, 0xa5, 0x90, 0x06, 0x27, 0x8e, 0x37, 0x8a, 0xaf, 0xa8, 0x65, 0x15, 0xf7, + 0xe0, 0xab, 0x12, 0x3b, 0x7d, 0x1a, 0xd1, 0xc0, 0xb3, 0x5d, 0xf7, 0xcc, 0x12, 0x07, 0x15, 0x5e, + 0x44, 0x87, 0xd6, 0xec, 0x11, 0x95, 0x58, 0x91, 0xbf, 0x2c, 0xac, 0xf5, 0xc4, 0x98, 0x24, 0xb6, + 0x66, 0xf2, 0xbc, 0xea, 0x5b, 0x50, 0x0d, 0x64, 0x10, 0x5b, 0x21, 0x73, 0x8f, 0xcc, 0x47, 0x6b, + 0xc9, 0x3d, 0x73, 0x2a, 0xc2, 0x49, 0x25, 0x98, 0x0b, 0xf8, 0xef, 0xc0, 0x8a, 0x1d, 0xfb, 0x56, + 0xb6, 0x9e, 0xdf, 0xb7, 0xcc, 0x7b, 0x9e, 0x54, 0xed, 0xf9, 0x48, 0xb8, 0x0d, 0xcb, 0x12, 0x91, + 0xed, 0x3a, 0xf6, 0x6c, 0x63, 0x7b, 0xee, 0x65, 0x9a, 0xc6, 0x94, 0x44, 0xbe, 0x61, 0xe3, 0x15, + 0xf6, 0x1f, 0x5d, 0xeb, 0x4f, 0x86, 0xbc, 0xa7, 0x4b, 0xbc, 0xbb, 0x48, 0x3f, 0x63, 0xcb, 0xcd, + 0x3f, 0x63, 0x9b, 0x7f, 0x16, 0x97, 0x3f, 0xf7, 0x2c, 0x4e, 0xbd, 0x03, 0x6b, 0xf3, 0xf8, 0x65, + 0x94, 0x6d, 0x41, 0x9e, 0x5f, 0xa8, 0x9f, 0x5b, 0x46, 0x53, 0x37, 0xe6, 0x44, 0x18, 0xa8, 0x7f, + 0xa3, 0x40, 0x6d, 0xc1, 0x2f, 0x56, 0xf2, 0xff, 0xa6, 0xa4, 0x8e, 0x87, 0x7e, 0x1e, 0xf2, 0xfc, + 0x6a, 0x5f, 0xbe, 0x58, 0xb9, 0x76, 0xf1, 0x0f, 0x8d, 0x5f, 0xc3, 0x13, 0x61, 0xc5, 0x12, 0x21, + 0x0f, 0xa8, 0x01, 0x3f, 0x1f, 0x8a, 0x77, 0x88, 0x65, 0x26, 0x13, 0x47, 0x46, 0x17, 0x0f, 0x9c, + 0x72, 0x2f, 0x3c, 0x70, 0xda, 0xfe, 0xc3, 0x2c, 0x94, 0xda, 0x67, 0xbd, 0x27, 0xee, 0x81, 0x6b, + 0x8f, 0xf8, 0x3d, 0x79, 0xbb, 0x6b, 0x3e, 0x42, 0x57, 0xf0, 0x2a, 0x54, 0x8c, 0x8e, 0x69, 0x19, + 0x6c, 0x29, 0x39, 0x68, 0x69, 0x77, 0x91, 0xc2, 0xd6, 0x9a, 0x2e, 0x69, 0x5a, 0xf7, 0xf4, 0x47, + 0x42, 0x92, 0xc1, 0x35, 0x58, 0xe9, 0x1b, 0xcd, 0xfb, 0x7d, 0x7d, 0x26, 0xcc, 0xe1, 0x75, 0x58, + 0x6d, 0xf7, 0x5b, 0x66, 0xb3, 0xdb, 0x4a, 0x89, 0x8b, 0x6c, 0x5d, 0xda, 0x6b, 0x75, 0xf6, 0x44, + 0x15, 0xb1, 0xfe, 0xfb, 0x46, 0xaf, 0x79, 0xd7, 0xd0, 0xf7, 0x85, 0x68, 0x93, 0x89, 0x3e, 0xd6, + 0x49, 0xe7, 0xa0, 0x19, 0x0f, 0x79, 0x07, 0x23, 0x28, 0xef, 0x35, 0x0d, 0x8d, 0xc8, 0x5e, 0x9e, + 0x29, 0xb8, 0x0a, 0x25, 0xdd, 0xe8, 0xb7, 0x65, 0x3d, 0x83, 0xeb, 0x50, 0xd3, 0xfa, 0x66, 0xc7, + 0x6a, 0x1a, 0x0d, 0xa2, 0xb7, 0x75, 0xc3, 0x94, 0x9a, 0x1c, 0xae, 0x41, 0xd5, 0x6c, 0xb6, 0xf5, + 0x9e, 0xa9, 0xb5, 0xbb, 0x52, 0xc8, 0x66, 0x51, 0xec, 0xe9, 0xb1, 0x0d, 0xc2, 0x1b, 0xb0, 0x6e, + 0x74, 0x2c, 0xf9, 0xb8, 0xc9, 0x7a, 0xa0, 0xb5, 0xfa, 0xba, 0xd4, 0x6d, 0xe2, 0x6b, 0x80, 0x3b, + 0x86, 0xd5, 0xef, 0xee, 0x6b, 0xa6, 0x6e, 0x19, 0x9d, 0x87, 0x52, 0x71, 0x07, 0x57, 0xa1, 0x38, + 0x9b, 0xc1, 0x33, 0xc6, 0x42, 0xa5, 0xab, 0x11, 0x73, 0x06, 0xf6, 0xd9, 0x33, 0x46, 0x16, 0xdc, + 0x25, 0x9d, 0x7e, 0x77, 0x66, 0xb6, 0x0a, 0x65, 0x49, 0x96, 0x14, 0xe5, 0x98, 0x68, 0xaf, 0x69, + 0x34, 0x92, 0xf9, 0x3d, 0x2b, 0x6e, 0x64, 0x90, 0xb2, 0x7d, 0x0c, 0x39, 0xee, 0x8e, 0x22, 0xe4, + 0x8c, 0x8e, 0xa1, 0xa3, 0x2b, 0x78, 0x05, 0xa0, 0xd9, 0x6b, 0x1a, 0xa6, 0x7e, 0x97, 0x68, 0x2d, + 0x06, 0x9b, 0x0b, 0x62, 0x02, 0x19, 0xda, 0x65, 0x58, 0x6a, 0xf6, 0x0e, 0x5a, 0x1d, 0xcd, 0x94, + 0x30, 0x9b, 0xbd, 0xfb, 0xfd, 0x8e, 0xc9, 0x94, 0x08, 0x97, 0xa1, 0xd0, 0xec, 0x99, 0xfa, 0xf7, + 0x4c, 0x86, 0x8b, 0xeb, 0x04, 0xab, 0xe8, 0xd9, 0x9d, 0xed, 0x1f, 0x67, 0x21, 0xc7, 0x9f, 0xa6, + 0x56, 0xa0, 0xc4, 0xbd, 0x6d, 0x3e, 0xea, 0xb2, 0x21, 0x4b, 0x90, 0x6b, 0x1a, 0xe6, 0x6d, 0xf4, + 0x2b, 0x19, 0x0c, 0x90, 0xef, 0xf3, 0xf2, 0xaf, 0x16, 0x58, 0xb9, 0x69, 0x98, 0xef, 0xdf, 0x42, + 0x3f, 0xc8, 0xb0, 0x6e, 0xfb, 0xa2, 0xf2, 0x6b, 0xb1, 0x62, 0xf7, 0x26, 0xfa, 0x61, 0xa2, 0xd8, + 0xbd, 0x89, 0x7e, 0x3d, 0x56, 0x7c, 0xb0, 0x8b, 0x7e, 0x23, 0x51, 0x7c, 0xb0, 0x8b, 0x7e, 0x33, + 0x56, 0xdc, 0xba, 0x89, 0x7e, 0x2b, 0x51, 0xdc, 0xba, 0x89, 0x7e, 0xbb, 0xc0, 0xb0, 0x70, 0x24, + 0x1f, 0xec, 0xa2, 0xdf, 0x29, 0x26, 0xb5, 0x5b, 0x37, 0xd1, 0xef, 0x16, 0x99, 0xff, 0x13, 0xaf, + 0xa2, 0xdf, 0x43, 0x6c, 0x9a, 0xcc, 0x41, 0xe8, 0xf7, 0x79, 0x91, 0xa9, 0xd0, 0x8f, 0x10, 0xc3, + 0xc8, 0xa4, 0xbc, 0xfa, 0x09, 0xd7, 0x3c, 0xd2, 0x35, 0x82, 0xfe, 0xa0, 0x20, 0xde, 0xb2, 0x35, + 0x9a, 0x6d, 0xad, 0x85, 0x30, 0x6f, 0xc1, 0x58, 0xf9, 0xa3, 0x1b, 0xac, 0xc8, 0xc2, 0x13, 0xfd, + 0x71, 0x97, 0x0d, 0xf8, 0x40, 0x23, 0x8d, 0x8f, 0x34, 0x82, 0xfe, 0xe4, 0x06, 0x1b, 0xf0, 0x81, + 0x46, 0x24, 0x5f, 0x7f, 0xda, 0x65, 0x86, 0x5c, 0xf5, 0xe9, 0x0d, 0x36, 0x69, 0x29, 0xff, 0xb3, + 0x2e, 0x2e, 0x42, 0x76, 0xaf, 0x69, 0xa2, 0x1f, 0xf3, 0xd1, 0x58, 0x88, 0xa2, 0x3f, 0x47, 0x4c, + 0xd8, 0xd3, 0x4d, 0xf4, 0x17, 0x4c, 0x98, 0x37, 0xfb, 0xdd, 0x96, 0x8e, 0xde, 0x62, 0x93, 0xbb, + 0xab, 0x77, 0xda, 0xba, 0x49, 0x1e, 0xa1, 0xbf, 0xe4, 0xe6, 0xdf, 0xed, 0x75, 0x0c, 0xf4, 0x19, + 0xc2, 0x55, 0x00, 0xfd, 0x7b, 0x5d, 0xa2, 0xf7, 0x7a, 0xcd, 0x8e, 0x81, 0xde, 0xdd, 0x3e, 0x00, + 0x74, 0x3e, 0x1d, 0x30, 0x00, 0x7d, 0xe3, 0x9e, 0xd1, 0x79, 0x68, 0xa0, 0x2b, 0xac, 0xd2, 0x25, + 0x7a, 0x57, 0x23, 0x3a, 0x52, 0x30, 0x40, 0x41, 0xbc, 0xb4, 0x43, 0x19, 0xbc, 0x0c, 0x45, 0xd2, + 0x69, 0xb5, 0xf6, 0xb4, 0xc6, 0x3d, 0x94, 0xdd, 0xfb, 0x26, 0xac, 0x38, 0xfe, 0xce, 0x89, 0x13, + 0xd1, 0x30, 0x14, 0x8f, 0x9f, 0x3f, 0x56, 0x65, 0xcd, 0xf1, 0xaf, 0x8b, 0xd2, 0xf5, 0x91, 0x7f, + 0xfd, 0x24, 0xba, 0xce, 0xb5, 0xd7, 0x79, 0xc6, 0x38, 0x2c, 0xf0, 0xca, 0x07, 0xff, 0x1b, 0x00, + 0x00, 0xff, 0xff, 0x0e, 0x62, 0xd9, 0x82, 0x5a, 0x2d, 0x00, 0x00, } diff --git a/go/vt/proto/tabletmanagerdata/tabletmanagerdata.pb.go b/go/vt/proto/tabletmanagerdata/tabletmanagerdata.pb.go index 851721cdec1..432b78cad9b 100644 --- a/go/vt/proto/tabletmanagerdata/tabletmanagerdata.pb.go +++ b/go/vt/proto/tabletmanagerdata/tabletmanagerdata.pb.go @@ -46,7 +46,7 @@ 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_bfd6af383c5f908a, []int{0} + return fileDescriptor_tabletmanagerdata_9e0123608316bc1a, []int{0} } func (m *TableDefinition) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_TableDefinition.Unmarshal(m, b) @@ -128,7 +128,7 @@ 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_bfd6af383c5f908a, []int{1} + return fileDescriptor_tabletmanagerdata_9e0123608316bc1a, []int{1} } func (m *SchemaDefinition) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_SchemaDefinition.Unmarshal(m, b) @@ -183,7 +183,7 @@ 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_bfd6af383c5f908a, []int{2} + return fileDescriptor_tabletmanagerdata_9e0123608316bc1a, []int{2} } func (m *SchemaChangeResult) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_SchemaChangeResult.Unmarshal(m, b) @@ -234,7 +234,7 @@ 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_bfd6af383c5f908a, []int{3} + return fileDescriptor_tabletmanagerdata_9e0123608316bc1a, []int{3} } func (m *UserPermission) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_UserPermission.Unmarshal(m, b) @@ -298,7 +298,7 @@ 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_bfd6af383c5f908a, []int{4} + return fileDescriptor_tabletmanagerdata_9e0123608316bc1a, []int{4} } func (m *DbPermission) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_DbPermission.Unmarshal(m, b) @@ -360,7 +360,7 @@ 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_bfd6af383c5f908a, []int{5} + return fileDescriptor_tabletmanagerdata_9e0123608316bc1a, []int{5} } func (m *Permissions) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Permissions.Unmarshal(m, b) @@ -405,7 +405,7 @@ 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_bfd6af383c5f908a, []int{6} + return fileDescriptor_tabletmanagerdata_9e0123608316bc1a, []int{6} } func (m *PingRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_PingRequest.Unmarshal(m, b) @@ -443,7 +443,7 @@ 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_bfd6af383c5f908a, []int{7} + return fileDescriptor_tabletmanagerdata_9e0123608316bc1a, []int{7} } func (m *PingResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_PingResponse.Unmarshal(m, b) @@ -482,7 +482,7 @@ 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_bfd6af383c5f908a, []int{8} + return fileDescriptor_tabletmanagerdata_9e0123608316bc1a, []int{8} } func (m *SleepRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_SleepRequest.Unmarshal(m, b) @@ -519,7 +519,7 @@ 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_bfd6af383c5f908a, []int{9} + return fileDescriptor_tabletmanagerdata_9e0123608316bc1a, []int{9} } func (m *SleepResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_SleepResponse.Unmarshal(m, b) @@ -552,7 +552,7 @@ 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_bfd6af383c5f908a, []int{10} + return fileDescriptor_tabletmanagerdata_9e0123608316bc1a, []int{10} } func (m *ExecuteHookRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ExecuteHookRequest.Unmarshal(m, b) @@ -606,7 +606,7 @@ 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_bfd6af383c5f908a, []int{11} + return fileDescriptor_tabletmanagerdata_9e0123608316bc1a, []int{11} } func (m *ExecuteHookResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ExecuteHookResponse.Unmarshal(m, b) @@ -660,7 +660,7 @@ 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_bfd6af383c5f908a, []int{12} + return fileDescriptor_tabletmanagerdata_9e0123608316bc1a, []int{12} } func (m *GetSchemaRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_GetSchemaRequest.Unmarshal(m, b) @@ -712,7 +712,7 @@ 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_bfd6af383c5f908a, []int{13} + return fileDescriptor_tabletmanagerdata_9e0123608316bc1a, []int{13} } func (m *GetSchemaResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_GetSchemaResponse.Unmarshal(m, b) @@ -749,7 +749,7 @@ 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_bfd6af383c5f908a, []int{14} + return fileDescriptor_tabletmanagerdata_9e0123608316bc1a, []int{14} } func (m *GetPermissionsRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_GetPermissionsRequest.Unmarshal(m, b) @@ -780,7 +780,7 @@ 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_bfd6af383c5f908a, []int{15} + return fileDescriptor_tabletmanagerdata_9e0123608316bc1a, []int{15} } func (m *GetPermissionsResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_GetPermissionsResponse.Unmarshal(m, b) @@ -817,7 +817,7 @@ 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_bfd6af383c5f908a, []int{16} + return fileDescriptor_tabletmanagerdata_9e0123608316bc1a, []int{16} } func (m *SetReadOnlyRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_SetReadOnlyRequest.Unmarshal(m, b) @@ -847,7 +847,7 @@ 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_bfd6af383c5f908a, []int{17} + return fileDescriptor_tabletmanagerdata_9e0123608316bc1a, []int{17} } func (m *SetReadOnlyResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_SetReadOnlyResponse.Unmarshal(m, b) @@ -877,7 +877,7 @@ 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_bfd6af383c5f908a, []int{18} + return fileDescriptor_tabletmanagerdata_9e0123608316bc1a, []int{18} } func (m *SetReadWriteRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_SetReadWriteRequest.Unmarshal(m, b) @@ -907,7 +907,7 @@ 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_bfd6af383c5f908a, []int{19} + return fileDescriptor_tabletmanagerdata_9e0123608316bc1a, []int{19} } func (m *SetReadWriteResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_SetReadWriteResponse.Unmarshal(m, b) @@ -938,7 +938,7 @@ 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_bfd6af383c5f908a, []int{20} + return fileDescriptor_tabletmanagerdata_9e0123608316bc1a, []int{20} } func (m *ChangeTypeRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ChangeTypeRequest.Unmarshal(m, b) @@ -975,7 +975,7 @@ 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_bfd6af383c5f908a, []int{21} + return fileDescriptor_tabletmanagerdata_9e0123608316bc1a, []int{21} } func (m *ChangeTypeResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ChangeTypeResponse.Unmarshal(m, b) @@ -1005,7 +1005,7 @@ 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_bfd6af383c5f908a, []int{22} + return fileDescriptor_tabletmanagerdata_9e0123608316bc1a, []int{22} } func (m *RefreshStateRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_RefreshStateRequest.Unmarshal(m, b) @@ -1035,7 +1035,7 @@ 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_bfd6af383c5f908a, []int{23} + return fileDescriptor_tabletmanagerdata_9e0123608316bc1a, []int{23} } func (m *RefreshStateResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_RefreshStateResponse.Unmarshal(m, b) @@ -1065,7 +1065,7 @@ 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_bfd6af383c5f908a, []int{24} + return fileDescriptor_tabletmanagerdata_9e0123608316bc1a, []int{24} } func (m *RunHealthCheckRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_RunHealthCheckRequest.Unmarshal(m, b) @@ -1095,7 +1095,7 @@ 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_bfd6af383c5f908a, []int{25} + return fileDescriptor_tabletmanagerdata_9e0123608316bc1a, []int{25} } func (m *RunHealthCheckResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_RunHealthCheckResponse.Unmarshal(m, b) @@ -1126,7 +1126,7 @@ 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_bfd6af383c5f908a, []int{26} + return fileDescriptor_tabletmanagerdata_9e0123608316bc1a, []int{26} } func (m *IgnoreHealthErrorRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_IgnoreHealthErrorRequest.Unmarshal(m, b) @@ -1163,7 +1163,7 @@ 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_bfd6af383c5f908a, []int{27} + return fileDescriptor_tabletmanagerdata_9e0123608316bc1a, []int{27} } func (m *IgnoreHealthErrorResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_IgnoreHealthErrorResponse.Unmarshal(m, b) @@ -1197,7 +1197,7 @@ 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_bfd6af383c5f908a, []int{28} + return fileDescriptor_tabletmanagerdata_9e0123608316bc1a, []int{28} } func (m *ReloadSchemaRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ReloadSchemaRequest.Unmarshal(m, b) @@ -1234,7 +1234,7 @@ 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_bfd6af383c5f908a, []int{29} + return fileDescriptor_tabletmanagerdata_9e0123608316bc1a, []int{29} } func (m *ReloadSchemaResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ReloadSchemaResponse.Unmarshal(m, b) @@ -1265,7 +1265,7 @@ 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_bfd6af383c5f908a, []int{30} + return fileDescriptor_tabletmanagerdata_9e0123608316bc1a, []int{30} } func (m *PreflightSchemaRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_PreflightSchemaRequest.Unmarshal(m, b) @@ -1305,7 +1305,7 @@ 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_bfd6af383c5f908a, []int{31} + return fileDescriptor_tabletmanagerdata_9e0123608316bc1a, []int{31} } func (m *PreflightSchemaResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_PreflightSchemaResponse.Unmarshal(m, b) @@ -1347,7 +1347,7 @@ 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_bfd6af383c5f908a, []int{32} + return fileDescriptor_tabletmanagerdata_9e0123608316bc1a, []int{32} } func (m *ApplySchemaRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ApplySchemaRequest.Unmarshal(m, b) @@ -1414,7 +1414,7 @@ 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_bfd6af383c5f908a, []int{33} + return fileDescriptor_tabletmanagerdata_9e0123608316bc1a, []int{33} } func (m *ApplySchemaResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ApplySchemaResponse.Unmarshal(m, b) @@ -1448,6 +1448,126 @@ func (m *ApplySchemaResponse) GetAfterSchema() *SchemaDefinition { return nil } +type LockTablesRequest struct { + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +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_9e0123608316bc1a, []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_Size() int { + return xxx_messageInfo_LockTablesRequest.Size(m) +} +func (m *LockTablesRequest) XXX_DiscardUnknown() { + xxx_messageInfo_LockTablesRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_LockTablesRequest proto.InternalMessageInfo + +type LockTablesResponse struct { + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +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_9e0123608316bc1a, []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_Size() int { + return xxx_messageInfo_LockTablesResponse.Size(m) +} +func (m *LockTablesResponse) XXX_DiscardUnknown() { + xxx_messageInfo_LockTablesResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_LockTablesResponse proto.InternalMessageInfo + +type UnlockTablesRequest struct { + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +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_9e0123608316bc1a, []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_Size() int { + return xxx_messageInfo_UnlockTablesRequest.Size(m) +} +func (m *UnlockTablesRequest) XXX_DiscardUnknown() { + xxx_messageInfo_UnlockTablesRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_UnlockTablesRequest proto.InternalMessageInfo + +type UnlockTablesResponse struct { + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +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_9e0123608316bc1a, []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_Size() int { + return xxx_messageInfo_UnlockTablesResponse.Size(m) +} +func (m *UnlockTablesResponse) XXX_DiscardUnknown() { + xxx_messageInfo_UnlockTablesResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_UnlockTablesResponse proto.InternalMessageInfo + type ExecuteFetchAsDbaRequest struct { Query []byte `protobuf:"bytes,1,opt,name=query,proto3" json:"query,omitempty"` DbName string `protobuf:"bytes,2,opt,name=db_name,json=dbName,proto3" json:"db_name,omitempty"` @@ -1463,7 +1583,7 @@ 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_bfd6af383c5f908a, []int{34} + return fileDescriptor_tabletmanagerdata_9e0123608316bc1a, []int{38} } func (m *ExecuteFetchAsDbaRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ExecuteFetchAsDbaRequest.Unmarshal(m, b) @@ -1529,7 +1649,7 @@ 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_bfd6af383c5f908a, []int{35} + return fileDescriptor_tabletmanagerdata_9e0123608316bc1a, []int{39} } func (m *ExecuteFetchAsDbaResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ExecuteFetchAsDbaResponse.Unmarshal(m, b) @@ -1570,7 +1690,7 @@ 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_bfd6af383c5f908a, []int{36} + return fileDescriptor_tabletmanagerdata_9e0123608316bc1a, []int{40} } func (m *ExecuteFetchAsAllPrivsRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ExecuteFetchAsAllPrivsRequest.Unmarshal(m, b) @@ -1629,7 +1749,7 @@ 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_bfd6af383c5f908a, []int{37} + return fileDescriptor_tabletmanagerdata_9e0123608316bc1a, []int{41} } func (m *ExecuteFetchAsAllPrivsResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ExecuteFetchAsAllPrivsResponse.Unmarshal(m, b) @@ -1668,7 +1788,7 @@ 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_bfd6af383c5f908a, []int{38} + return fileDescriptor_tabletmanagerdata_9e0123608316bc1a, []int{42} } func (m *ExecuteFetchAsAppRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ExecuteFetchAsAppRequest.Unmarshal(m, b) @@ -1713,7 +1833,7 @@ 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_bfd6af383c5f908a, []int{39} + return fileDescriptor_tabletmanagerdata_9e0123608316bc1a, []int{43} } func (m *ExecuteFetchAsAppResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ExecuteFetchAsAppResponse.Unmarshal(m, b) @@ -1750,7 +1870,7 @@ 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_bfd6af383c5f908a, []int{40} + return fileDescriptor_tabletmanagerdata_9e0123608316bc1a, []int{44} } func (m *SlaveStatusRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_SlaveStatusRequest.Unmarshal(m, b) @@ -1781,7 +1901,7 @@ 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_bfd6af383c5f908a, []int{41} + return fileDescriptor_tabletmanagerdata_9e0123608316bc1a, []int{45} } func (m *SlaveStatusResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_SlaveStatusResponse.Unmarshal(m, b) @@ -1818,7 +1938,7 @@ 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_bfd6af383c5f908a, []int{42} + return fileDescriptor_tabletmanagerdata_9e0123608316bc1a, []int{46} } func (m *MasterPositionRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_MasterPositionRequest.Unmarshal(m, b) @@ -1849,7 +1969,7 @@ 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_bfd6af383c5f908a, []int{43} + return fileDescriptor_tabletmanagerdata_9e0123608316bc1a, []int{47} } func (m *MasterPositionResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_MasterPositionResponse.Unmarshal(m, b) @@ -1886,7 +2006,7 @@ 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_bfd6af383c5f908a, []int{44} + return fileDescriptor_tabletmanagerdata_9e0123608316bc1a, []int{48} } func (m *StopSlaveRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_StopSlaveRequest.Unmarshal(m, b) @@ -1916,7 +2036,7 @@ 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_bfd6af383c5f908a, []int{45} + return fileDescriptor_tabletmanagerdata_9e0123608316bc1a, []int{49} } func (m *StopSlaveResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_StopSlaveResponse.Unmarshal(m, b) @@ -1948,7 +2068,7 @@ 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_bfd6af383c5f908a, []int{46} + return fileDescriptor_tabletmanagerdata_9e0123608316bc1a, []int{50} } func (m *StopSlaveMinimumRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_StopSlaveMinimumRequest.Unmarshal(m, b) @@ -1993,7 +2113,7 @@ 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_bfd6af383c5f908a, []int{47} + return fileDescriptor_tabletmanagerdata_9e0123608316bc1a, []int{51} } func (m *StopSlaveMinimumResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_StopSlaveMinimumResponse.Unmarshal(m, b) @@ -2030,7 +2150,7 @@ 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_bfd6af383c5f908a, []int{48} + return fileDescriptor_tabletmanagerdata_9e0123608316bc1a, []int{52} } func (m *StartSlaveRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_StartSlaveRequest.Unmarshal(m, b) @@ -2060,7 +2180,7 @@ 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_bfd6af383c5f908a, []int{49} + return fileDescriptor_tabletmanagerdata_9e0123608316bc1a, []int{53} } func (m *StartSlaveResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_StartSlaveResponse.Unmarshal(m, b) @@ -2080,6 +2200,82 @@ func (m *StartSlaveResponse) XXX_DiscardUnknown() { var xxx_messageInfo_StartSlaveResponse proto.InternalMessageInfo +type StartSlaveUntilAfterRequest struct { + Position string `protobuf:"bytes,1,opt,name=position,proto3" json:"position,omitempty"` + WaitTimeout int64 `protobuf:"varint,2,opt,name=wait_timeout,json=waitTimeout,proto3" json:"wait_timeout,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *StartSlaveUntilAfterRequest) Reset() { *m = StartSlaveUntilAfterRequest{} } +func (m *StartSlaveUntilAfterRequest) String() string { return proto.CompactTextString(m) } +func (*StartSlaveUntilAfterRequest) ProtoMessage() {} +func (*StartSlaveUntilAfterRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_tabletmanagerdata_9e0123608316bc1a, []int{54} +} +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_Size() int { + return xxx_messageInfo_StartSlaveUntilAfterRequest.Size(m) +} +func (m *StartSlaveUntilAfterRequest) XXX_DiscardUnknown() { + xxx_messageInfo_StartSlaveUntilAfterRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_StartSlaveUntilAfterRequest proto.InternalMessageInfo + +func (m *StartSlaveUntilAfterRequest) GetPosition() string { + if m != nil { + return m.Position + } + return "" +} + +func (m *StartSlaveUntilAfterRequest) GetWaitTimeout() int64 { + if m != nil { + return m.WaitTimeout + } + return 0 +} + +type StartSlaveUntilAfterResponse struct { + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *StartSlaveUntilAfterResponse) Reset() { *m = StartSlaveUntilAfterResponse{} } +func (m *StartSlaveUntilAfterResponse) String() string { return proto.CompactTextString(m) } +func (*StartSlaveUntilAfterResponse) ProtoMessage() {} +func (*StartSlaveUntilAfterResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_tabletmanagerdata_9e0123608316bc1a, []int{55} +} +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_Size() int { + return xxx_messageInfo_StartSlaveUntilAfterResponse.Size(m) +} +func (m *StartSlaveUntilAfterResponse) XXX_DiscardUnknown() { + xxx_messageInfo_StartSlaveUntilAfterResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_StartSlaveUntilAfterResponse proto.InternalMessageInfo + type TabletExternallyReparentedRequest struct { // external_id is an string value that may be provided by an external // agent for tracking purposes. The tablet will emit this string in @@ -2094,7 +2290,7 @@ 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_bfd6af383c5f908a, []int{50} + return fileDescriptor_tabletmanagerdata_9e0123608316bc1a, []int{56} } func (m *TabletExternallyReparentedRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_TabletExternallyReparentedRequest.Unmarshal(m, b) @@ -2131,7 +2327,7 @@ 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_bfd6af383c5f908a, []int{51} + return fileDescriptor_tabletmanagerdata_9e0123608316bc1a, []int{57} } func (m *TabletExternallyReparentedResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_TabletExternallyReparentedResponse.Unmarshal(m, b) @@ -2161,7 +2357,7 @@ 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_bfd6af383c5f908a, []int{52} + return fileDescriptor_tabletmanagerdata_9e0123608316bc1a, []int{58} } func (m *TabletExternallyElectedRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_TabletExternallyElectedRequest.Unmarshal(m, b) @@ -2191,7 +2387,7 @@ 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_bfd6af383c5f908a, []int{53} + return fileDescriptor_tabletmanagerdata_9e0123608316bc1a, []int{59} } func (m *TabletExternallyElectedResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_TabletExternallyElectedResponse.Unmarshal(m, b) @@ -2221,7 +2417,7 @@ 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_bfd6af383c5f908a, []int{54} + return fileDescriptor_tabletmanagerdata_9e0123608316bc1a, []int{60} } func (m *GetSlavesRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_GetSlavesRequest.Unmarshal(m, b) @@ -2252,7 +2448,7 @@ 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_bfd6af383c5f908a, []int{55} + return fileDescriptor_tabletmanagerdata_9e0123608316bc1a, []int{61} } func (m *GetSlavesResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_GetSlavesResponse.Unmarshal(m, b) @@ -2289,7 +2485,7 @@ 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_bfd6af383c5f908a, []int{56} + return fileDescriptor_tabletmanagerdata_9e0123608316bc1a, []int{62} } func (m *ResetReplicationRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ResetReplicationRequest.Unmarshal(m, b) @@ -2319,7 +2515,7 @@ 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_bfd6af383c5f908a, []int{57} + return fileDescriptor_tabletmanagerdata_9e0123608316bc1a, []int{63} } func (m *ResetReplicationResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ResetReplicationResponse.Unmarshal(m, b) @@ -2350,7 +2546,7 @@ 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_bfd6af383c5f908a, []int{58} + return fileDescriptor_tabletmanagerdata_9e0123608316bc1a, []int{64} } func (m *VReplicationExecRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_VReplicationExecRequest.Unmarshal(m, b) @@ -2388,7 +2584,7 @@ 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_bfd6af383c5f908a, []int{59} + return fileDescriptor_tabletmanagerdata_9e0123608316bc1a, []int{65} } func (m *VReplicationExecResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_VReplicationExecResponse.Unmarshal(m, b) @@ -2427,7 +2623,7 @@ 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_bfd6af383c5f908a, []int{60} + return fileDescriptor_tabletmanagerdata_9e0123608316bc1a, []int{66} } func (m *VReplicationWaitForPosRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_VReplicationWaitForPosRequest.Unmarshal(m, b) @@ -2471,7 +2667,7 @@ 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_bfd6af383c5f908a, []int{61} + return fileDescriptor_tabletmanagerdata_9e0123608316bc1a, []int{67} } func (m *VReplicationWaitForPosResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_VReplicationWaitForPosResponse.Unmarshal(m, b) @@ -2501,7 +2697,7 @@ 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_bfd6af383c5f908a, []int{62} + return fileDescriptor_tabletmanagerdata_9e0123608316bc1a, []int{68} } func (m *InitMasterRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_InitMasterRequest.Unmarshal(m, b) @@ -2532,7 +2728,7 @@ 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_bfd6af383c5f908a, []int{63} + return fileDescriptor_tabletmanagerdata_9e0123608316bc1a, []int{69} } func (m *InitMasterResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_InitMasterResponse.Unmarshal(m, b) @@ -2573,7 +2769,7 @@ 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_bfd6af383c5f908a, []int{64} + return fileDescriptor_tabletmanagerdata_9e0123608316bc1a, []int{70} } func (m *PopulateReparentJournalRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_PopulateReparentJournalRequest.Unmarshal(m, b) @@ -2631,7 +2827,7 @@ 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_bfd6af383c5f908a, []int{65} + return fileDescriptor_tabletmanagerdata_9e0123608316bc1a, []int{71} } func (m *PopulateReparentJournalResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_PopulateReparentJournalResponse.Unmarshal(m, b) @@ -2664,7 +2860,7 @@ 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_bfd6af383c5f908a, []int{66} + return fileDescriptor_tabletmanagerdata_9e0123608316bc1a, []int{72} } func (m *InitSlaveRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_InitSlaveRequest.Unmarshal(m, b) @@ -2715,7 +2911,7 @@ 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_bfd6af383c5f908a, []int{67} + return fileDescriptor_tabletmanagerdata_9e0123608316bc1a, []int{73} } func (m *InitSlaveResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_InitSlaveResponse.Unmarshal(m, b) @@ -2745,7 +2941,7 @@ 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_bfd6af383c5f908a, []int{68} + return fileDescriptor_tabletmanagerdata_9e0123608316bc1a, []int{74} } func (m *DemoteMasterRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_DemoteMasterRequest.Unmarshal(m, b) @@ -2776,7 +2972,7 @@ 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_bfd6af383c5f908a, []int{69} + return fileDescriptor_tabletmanagerdata_9e0123608316bc1a, []int{75} } func (m *DemoteMasterResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_DemoteMasterResponse.Unmarshal(m, b) @@ -2814,7 +3010,7 @@ 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_bfd6af383c5f908a, []int{70} + return fileDescriptor_tabletmanagerdata_9e0123608316bc1a, []int{76} } func (m *PromoteSlaveWhenCaughtUpRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_PromoteSlaveWhenCaughtUpRequest.Unmarshal(m, b) @@ -2852,7 +3048,7 @@ 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_bfd6af383c5f908a, []int{71} + return fileDescriptor_tabletmanagerdata_9e0123608316bc1a, []int{77} } func (m *PromoteSlaveWhenCaughtUpResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_PromoteSlaveWhenCaughtUpResponse.Unmarshal(m, b) @@ -2889,7 +3085,7 @@ 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_bfd6af383c5f908a, []int{72} + return fileDescriptor_tabletmanagerdata_9e0123608316bc1a, []int{78} } func (m *SlaveWasPromotedRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_SlaveWasPromotedRequest.Unmarshal(m, b) @@ -2919,7 +3115,7 @@ 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_bfd6af383c5f908a, []int{73} + return fileDescriptor_tabletmanagerdata_9e0123608316bc1a, []int{79} } func (m *SlaveWasPromotedResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_SlaveWasPromotedResponse.Unmarshal(m, b) @@ -2952,7 +3148,7 @@ 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_bfd6af383c5f908a, []int{74} + return fileDescriptor_tabletmanagerdata_9e0123608316bc1a, []int{80} } func (m *SetMasterRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_SetMasterRequest.Unmarshal(m, b) @@ -3003,7 +3199,7 @@ 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_bfd6af383c5f908a, []int{75} + return fileDescriptor_tabletmanagerdata_9e0123608316bc1a, []int{81} } func (m *SetMasterResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_SetMasterResponse.Unmarshal(m, b) @@ -3035,7 +3231,7 @@ 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_bfd6af383c5f908a, []int{76} + return fileDescriptor_tabletmanagerdata_9e0123608316bc1a, []int{82} } func (m *SlaveWasRestartedRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_SlaveWasRestartedRequest.Unmarshal(m, b) @@ -3072,7 +3268,7 @@ 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_bfd6af383c5f908a, []int{77} + return fileDescriptor_tabletmanagerdata_9e0123608316bc1a, []int{83} } func (m *SlaveWasRestartedResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_SlaveWasRestartedResponse.Unmarshal(m, b) @@ -3102,7 +3298,7 @@ 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_bfd6af383c5f908a, []int{78} + return fileDescriptor_tabletmanagerdata_9e0123608316bc1a, []int{84} } func (m *StopReplicationAndGetStatusRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_StopReplicationAndGetStatusRequest.Unmarshal(m, b) @@ -3133,7 +3329,7 @@ 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_bfd6af383c5f908a, []int{79} + return fileDescriptor_tabletmanagerdata_9e0123608316bc1a, []int{85} } func (m *StopReplicationAndGetStatusResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_StopReplicationAndGetStatusResponse.Unmarshal(m, b) @@ -3170,7 +3366,7 @@ 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_bfd6af383c5f908a, []int{80} + return fileDescriptor_tabletmanagerdata_9e0123608316bc1a, []int{86} } func (m *PromoteSlaveRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_PromoteSlaveRequest.Unmarshal(m, b) @@ -3201,7 +3397,7 @@ 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_bfd6af383c5f908a, []int{81} + return fileDescriptor_tabletmanagerdata_9e0123608316bc1a, []int{87} } func (m *PromoteSlaveResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_PromoteSlaveResponse.Unmarshal(m, b) @@ -3239,7 +3435,7 @@ 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_bfd6af383c5f908a, []int{82} + return fileDescriptor_tabletmanagerdata_9e0123608316bc1a, []int{88} } func (m *BackupRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_BackupRequest.Unmarshal(m, b) @@ -3277,7 +3473,7 @@ 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_bfd6af383c5f908a, []int{83} + return fileDescriptor_tabletmanagerdata_9e0123608316bc1a, []int{89} } func (m *BackupResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_BackupResponse.Unmarshal(m, b) @@ -3314,7 +3510,7 @@ 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_bfd6af383c5f908a, []int{84} + return fileDescriptor_tabletmanagerdata_9e0123608316bc1a, []int{90} } func (m *RestoreFromBackupRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_RestoreFromBackupRequest.Unmarshal(m, b) @@ -3345,7 +3541,7 @@ 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_bfd6af383c5f908a, []int{85} + return fileDescriptor_tabletmanagerdata_9e0123608316bc1a, []int{91} } func (m *RestoreFromBackupResponse) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_RestoreFromBackupResponse.Unmarshal(m, b) @@ -3410,6 +3606,10 @@ func init() { proto.RegisterType((*PreflightSchemaResponse)(nil), "tabletmanagerdata.PreflightSchemaResponse") proto.RegisterType((*ApplySchemaRequest)(nil), "tabletmanagerdata.ApplySchemaRequest") proto.RegisterType((*ApplySchemaResponse)(nil), "tabletmanagerdata.ApplySchemaResponse") + proto.RegisterType((*LockTablesRequest)(nil), "tabletmanagerdata.LockTablesRequest") + proto.RegisterType((*LockTablesResponse)(nil), "tabletmanagerdata.LockTablesResponse") + proto.RegisterType((*UnlockTablesRequest)(nil), "tabletmanagerdata.UnlockTablesRequest") + proto.RegisterType((*UnlockTablesResponse)(nil), "tabletmanagerdata.UnlockTablesResponse") proto.RegisterType((*ExecuteFetchAsDbaRequest)(nil), "tabletmanagerdata.ExecuteFetchAsDbaRequest") proto.RegisterType((*ExecuteFetchAsDbaResponse)(nil), "tabletmanagerdata.ExecuteFetchAsDbaResponse") proto.RegisterType((*ExecuteFetchAsAllPrivsRequest)(nil), "tabletmanagerdata.ExecuteFetchAsAllPrivsRequest") @@ -3426,6 +3626,8 @@ func init() { proto.RegisterType((*StopSlaveMinimumResponse)(nil), "tabletmanagerdata.StopSlaveMinimumResponse") proto.RegisterType((*StartSlaveRequest)(nil), "tabletmanagerdata.StartSlaveRequest") proto.RegisterType((*StartSlaveResponse)(nil), "tabletmanagerdata.StartSlaveResponse") + proto.RegisterType((*StartSlaveUntilAfterRequest)(nil), "tabletmanagerdata.StartSlaveUntilAfterRequest") + proto.RegisterType((*StartSlaveUntilAfterResponse)(nil), "tabletmanagerdata.StartSlaveUntilAfterResponse") proto.RegisterType((*TabletExternallyReparentedRequest)(nil), "tabletmanagerdata.TabletExternallyReparentedRequest") proto.RegisterType((*TabletExternallyReparentedResponse)(nil), "tabletmanagerdata.TabletExternallyReparentedResponse") proto.RegisterType((*TabletExternallyElectedRequest)(nil), "tabletmanagerdata.TabletExternallyElectedRequest") @@ -3465,134 +3667,138 @@ func init() { } func init() { - proto.RegisterFile("tabletmanagerdata.proto", fileDescriptor_tabletmanagerdata_bfd6af383c5f908a) -} - -var fileDescriptor_tabletmanagerdata_bfd6af383c5f908a = []byte{ - // 1999 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x58, 0x5b, 0x6f, 0x1b, 0xc7, - 0x15, 0x06, 0x49, 0x49, 0x96, 0x0e, 0x2f, 0xa2, 0x96, 0x92, 0x48, 0x29, 0x88, 0x24, 0xaf, 0x9d, - 0x46, 0x75, 0x51, 0x2a, 0x56, 0xd2, 0x20, 0x48, 0x91, 0xa2, 0xb2, 0x2e, 0xb6, 0x13, 0x27, 0x66, - 0x56, 0x8e, 0x5d, 0xe4, 0x65, 0x31, 0xe4, 0x1e, 0x91, 0x0b, 0x2d, 0x77, 0xd6, 0x33, 0xb3, 0x94, - 0xf8, 0x27, 0xfa, 0xd6, 0xb7, 0xbe, 0x15, 0x68, 0xdf, 0xfb, 0x63, 0x52, 0xf4, 0x97, 0xf4, 0xa1, - 0x2f, 0xc5, 0x5c, 0x96, 0xdc, 0xe5, 0xc5, 0x96, 0x84, 0x14, 0xc8, 0x8b, 0xc0, 0xf3, 0x9d, 0xfb, - 0x99, 0x33, 0x67, 0xce, 0x0a, 0xea, 0x82, 0xb4, 0x03, 0x14, 0x7d, 0x12, 0x92, 0x2e, 0x32, 0x8f, - 0x08, 0xd2, 0x8c, 0x18, 0x15, 0xd4, 0x5a, 0x9b, 0x62, 0x6c, 0x17, 0xdf, 0xc6, 0xc8, 0x86, 0x9a, - 0xbf, 0x5d, 0x11, 0x34, 0xa2, 0x63, 0xf9, 0xed, 0x0d, 0x86, 0x51, 0xe0, 0x77, 0x88, 0xf0, 0x69, - 0x98, 0x82, 0xcb, 0x01, 0xed, 0xc6, 0xc2, 0x0f, 0x34, 0x69, 0xff, 0x3b, 0x07, 0xab, 0xaf, 0xa4, - 0xe1, 0x13, 0xbc, 0xf0, 0x43, 0x5f, 0x0a, 0x5b, 0x16, 0x2c, 0x84, 0xa4, 0x8f, 0x8d, 0xdc, 0x5e, - 0x6e, 0x7f, 0xc5, 0x51, 0xbf, 0xad, 0x4d, 0x58, 0xe2, 0x9d, 0x1e, 0xf6, 0x49, 0x23, 0xaf, 0x50, - 0x43, 0x59, 0x0d, 0xb8, 0xd7, 0xa1, 0x41, 0xdc, 0x0f, 0x79, 0xa3, 0xb0, 0x57, 0xd8, 0x5f, 0x71, - 0x12, 0xd2, 0x6a, 0x42, 0x2d, 0x62, 0x7e, 0x9f, 0xb0, 0xa1, 0x7b, 0x89, 0x43, 0x37, 0x91, 0x5a, - 0x50, 0x52, 0x6b, 0x86, 0xf5, 0x0d, 0x0e, 0x8f, 0x8d, 0xbc, 0x05, 0x0b, 0x62, 0x18, 0x61, 0x63, - 0x51, 0x7b, 0x95, 0xbf, 0xad, 0x5d, 0x28, 0xca, 0xd0, 0xdd, 0x00, 0xc3, 0xae, 0xe8, 0x35, 0x96, - 0xf6, 0x72, 0xfb, 0x0b, 0x0e, 0x48, 0xe8, 0x85, 0x42, 0xac, 0x0f, 0x60, 0x85, 0xd1, 0x2b, 0xb7, - 0x43, 0xe3, 0x50, 0x34, 0xee, 0x29, 0xf6, 0x32, 0xa3, 0x57, 0xc7, 0x92, 0xb6, 0xff, 0x9e, 0x83, - 0xea, 0xb9, 0x0a, 0x33, 0x95, 0xdc, 0xc7, 0xb0, 0x2a, 0xf5, 0xdb, 0x84, 0xa3, 0x6b, 0x32, 0xd2, - 0x79, 0x56, 0x12, 0x58, 0xab, 0x58, 0x2f, 0x41, 0x57, 0xdc, 0xf5, 0x46, 0xca, 0xbc, 0x91, 0xdf, - 0x2b, 0xec, 0x17, 0x0f, 0xed, 0xe6, 0xf4, 0x21, 0x4d, 0x14, 0xd1, 0xa9, 0x8a, 0x2c, 0xc0, 0x65, - 0xa9, 0x06, 0xc8, 0xb8, 0x4f, 0xc3, 0x46, 0x41, 0x79, 0x4c, 0x48, 0x19, 0xa8, 0xa5, 0xbd, 0x1e, - 0xf7, 0x48, 0xd8, 0x45, 0x07, 0x79, 0x1c, 0x08, 0xeb, 0x19, 0x94, 0xdb, 0x78, 0x41, 0x59, 0x26, - 0xd0, 0xe2, 0xe1, 0x83, 0x19, 0xde, 0x27, 0xd3, 0x74, 0x4a, 0x5a, 0xd3, 0xe4, 0x72, 0x06, 0x25, - 0x72, 0x21, 0x90, 0xb9, 0xa9, 0x33, 0xbc, 0xa1, 0xa1, 0xa2, 0x52, 0xd4, 0xb0, 0xfd, 0x9f, 0x1c, - 0x54, 0x7e, 0xe0, 0xc8, 0x5a, 0xc8, 0xfa, 0x3e, 0xe7, 0xa6, 0x59, 0x7a, 0x94, 0x8b, 0xa4, 0x59, - 0xe4, 0x6f, 0x89, 0xc5, 0x1c, 0x99, 0x69, 0x15, 0xf5, 0xdb, 0xfa, 0x0d, 0xac, 0x45, 0x84, 0xf3, - 0x2b, 0xca, 0x3c, 0xb7, 0xd3, 0xc3, 0xce, 0x25, 0x8f, 0xfb, 0xaa, 0x0e, 0x0b, 0x4e, 0x35, 0x61, - 0x1c, 0x1b, 0xdc, 0xfa, 0x1e, 0x20, 0x62, 0xfe, 0xc0, 0x0f, 0xb0, 0x8b, 0xba, 0x65, 0x8a, 0x87, - 0x8f, 0x67, 0x44, 0x9b, 0x8d, 0xa5, 0xd9, 0x1a, 0xe9, 0x9c, 0x86, 0x82, 0x0d, 0x9d, 0x94, 0x91, - 0xed, 0xaf, 0x60, 0x75, 0x82, 0x6d, 0x55, 0xa1, 0x70, 0x89, 0x43, 0x13, 0xb9, 0xfc, 0x69, 0xad, - 0xc3, 0xe2, 0x80, 0x04, 0x31, 0x9a, 0xc8, 0x35, 0xf1, 0x65, 0xfe, 0x8b, 0x9c, 0xfd, 0x53, 0x0e, - 0x4a, 0x27, 0xed, 0xf7, 0xe4, 0x5d, 0x81, 0xbc, 0xd7, 0x36, 0xba, 0x79, 0xaf, 0x3d, 0xaa, 0x43, - 0x21, 0x55, 0x87, 0x97, 0x33, 0x52, 0x3b, 0x98, 0x91, 0x5a, 0xda, 0xd9, 0xff, 0x33, 0xb1, 0xbf, - 0xe5, 0xa0, 0x38, 0xf6, 0xc4, 0xad, 0x17, 0x50, 0x95, 0x71, 0xba, 0xd1, 0x18, 0x6b, 0xe4, 0x54, - 0x94, 0xf7, 0xdf, 0x7b, 0x00, 0xce, 0x6a, 0x9c, 0xa1, 0xb9, 0x75, 0x06, 0x15, 0xaf, 0x9d, 0xb1, - 0xa5, 0x6f, 0xd0, 0xee, 0x7b, 0x32, 0x76, 0xca, 0x5e, 0x8a, 0xe2, 0xf6, 0xc7, 0x50, 0x6c, 0xf9, - 0x61, 0xd7, 0xc1, 0xb7, 0x31, 0x72, 0x21, 0xaf, 0x52, 0x44, 0x86, 0x01, 0x25, 0x9e, 0x49, 0x32, - 0x21, 0xed, 0x7d, 0x28, 0x69, 0x41, 0x1e, 0xd1, 0x90, 0xe3, 0x3b, 0x24, 0x1f, 0x41, 0xe9, 0x3c, - 0x40, 0x8c, 0x12, 0x9b, 0xdb, 0xb0, 0xec, 0xc5, 0x4c, 0x8d, 0x4b, 0x25, 0x5a, 0x70, 0x46, 0xb4, - 0xbd, 0x0a, 0x65, 0x23, 0xab, 0xcd, 0xda, 0xff, 0xca, 0x81, 0x75, 0x7a, 0x8d, 0x9d, 0x58, 0xe0, - 0x33, 0x4a, 0x2f, 0x13, 0x1b, 0xb3, 0x26, 0xe7, 0x0e, 0x40, 0x44, 0x18, 0xe9, 0xa3, 0x40, 0xa6, - 0xd3, 0x5f, 0x71, 0x52, 0x88, 0xd5, 0x82, 0x15, 0xbc, 0x16, 0x8c, 0xb8, 0x18, 0x0e, 0xd4, 0x0c, - 0x2d, 0x1e, 0x7e, 0x3a, 0xa3, 0x3a, 0xd3, 0xde, 0x9a, 0xa7, 0x52, 0xed, 0x34, 0x1c, 0xe8, 0x9e, - 0x58, 0x46, 0x43, 0x6e, 0xff, 0x1e, 0xca, 0x19, 0xd6, 0xad, 0xfa, 0xe1, 0x02, 0x6a, 0x19, 0x57, - 0xa6, 0x8e, 0xbb, 0x50, 0xc4, 0x6b, 0x5f, 0xb8, 0x5c, 0x10, 0x11, 0x73, 0x53, 0x20, 0x90, 0xd0, - 0xb9, 0x42, 0xd4, 0x03, 0x21, 0x3c, 0x1a, 0x8b, 0xd1, 0x03, 0xa1, 0x28, 0x83, 0x23, 0x4b, 0x6e, - 0x81, 0xa1, 0xec, 0x01, 0x54, 0x9f, 0xa2, 0xd0, 0x73, 0x25, 0x29, 0xdf, 0x26, 0x2c, 0xa9, 0xc4, - 0x75, 0xc7, 0xad, 0x38, 0x86, 0xb2, 0x1e, 0x40, 0xd9, 0x0f, 0x3b, 0x41, 0xec, 0xa1, 0x3b, 0xf0, - 0xf1, 0x8a, 0x2b, 0x17, 0xcb, 0x4e, 0xc9, 0x80, 0xaf, 0x25, 0x66, 0x7d, 0x04, 0x15, 0xbc, 0xd6, - 0x42, 0xc6, 0x88, 0x7e, 0x90, 0xca, 0x06, 0x55, 0x03, 0x9a, 0xdb, 0x08, 0x6b, 0x29, 0xbf, 0x26, - 0xbb, 0x16, 0xac, 0xe9, 0xc9, 0x98, 0x1a, 0xf6, 0xb7, 0x99, 0xb6, 0x55, 0x3e, 0x81, 0xd8, 0x75, - 0xd8, 0x78, 0x8a, 0x22, 0xd5, 0xc2, 0x26, 0x47, 0xfb, 0x47, 0xd8, 0x9c, 0x64, 0x98, 0x20, 0xfe, - 0x08, 0xc5, 0xec, 0xa5, 0x93, 0xee, 0x77, 0x66, 0xb8, 0x4f, 0x2b, 0xa7, 0x55, 0xec, 0x75, 0xb0, - 0xce, 0x51, 0x38, 0x48, 0xbc, 0x97, 0x61, 0x30, 0x4c, 0x3c, 0x6e, 0x40, 0x2d, 0x83, 0x9a, 0x16, - 0x1e, 0xc3, 0x6f, 0x98, 0x2f, 0x30, 0x91, 0xde, 0x84, 0xf5, 0x2c, 0x6c, 0xc4, 0xbf, 0x86, 0x35, - 0xfd, 0x38, 0xbd, 0x1a, 0x46, 0x89, 0xb0, 0xf5, 0x3b, 0x28, 0xea, 0xf0, 0x5c, 0xf5, 0x74, 0xcb, - 0x90, 0x2b, 0x87, 0xeb, 0xcd, 0xd1, 0x26, 0xa2, 0x6a, 0x2e, 0x94, 0x06, 0x88, 0xd1, 0x6f, 0x19, - 0x67, 0xda, 0xd6, 0x38, 0x20, 0x07, 0x2f, 0x18, 0xf2, 0x9e, 0x6c, 0xa9, 0x74, 0x40, 0x59, 0xd8, - 0x88, 0xd7, 0x61, 0xc3, 0x89, 0xc3, 0x67, 0x48, 0x02, 0xd1, 0x53, 0x0f, 0x47, 0xa2, 0xd0, 0x80, - 0xcd, 0x49, 0x86, 0x51, 0xf9, 0x0c, 0x1a, 0xcf, 0xbb, 0x21, 0x65, 0xa8, 0x99, 0xa7, 0x8c, 0x51, - 0x96, 0x19, 0x29, 0x42, 0x20, 0x0b, 0xc7, 0x83, 0x42, 0x91, 0xf6, 0x07, 0xb0, 0x35, 0x43, 0xcb, - 0x98, 0xfc, 0x52, 0x06, 0x2d, 0xe7, 0x49, 0xb6, 0x93, 0x1f, 0x40, 0xf9, 0x8a, 0xf8, 0xc2, 0x8d, - 0x28, 0x1f, 0x37, 0xd3, 0x8a, 0x53, 0x92, 0x60, 0xcb, 0x60, 0x3a, 0xb3, 0xb4, 0xae, 0xb1, 0x79, - 0x08, 0x9b, 0x2d, 0x86, 0x17, 0x81, 0xdf, 0xed, 0x4d, 0x5c, 0x10, 0xb9, 0x6d, 0xa9, 0xc2, 0x25, - 0x37, 0x24, 0x21, 0xed, 0x2e, 0xd4, 0xa7, 0x74, 0x4c, 0x5f, 0xbd, 0x80, 0x8a, 0x96, 0x72, 0x99, - 0xda, 0x2b, 0x92, 0x79, 0xfe, 0xd1, 0xdc, 0xce, 0x4e, 0x6f, 0x21, 0x4e, 0xb9, 0x93, 0xa2, 0xb8, - 0xfd, 0xdf, 0x1c, 0x58, 0x47, 0x51, 0x14, 0x0c, 0xb3, 0x91, 0x55, 0xa1, 0xc0, 0xdf, 0x06, 0xc9, - 0x88, 0xe1, 0x6f, 0x03, 0x39, 0x62, 0x2e, 0x28, 0xeb, 0xa0, 0xb9, 0xac, 0x9a, 0x90, 0x6b, 0x00, - 0x09, 0x02, 0x7a, 0xe5, 0xa6, 0xb6, 0x53, 0x35, 0x19, 0x96, 0x9d, 0xaa, 0x62, 0x38, 0x63, 0x7c, - 0x7a, 0x01, 0x5a, 0xf8, 0xb9, 0x16, 0xa0, 0xc5, 0x3b, 0x2e, 0x40, 0xff, 0xc8, 0x41, 0x2d, 0x93, - 0xbd, 0xa9, 0xf1, 0x2f, 0x6f, 0x55, 0xfb, 0x67, 0x0e, 0x1a, 0x66, 0x90, 0x9f, 0xa1, 0xe8, 0xf4, - 0x8e, 0xf8, 0x49, 0x7b, 0x74, 0x5a, 0xeb, 0xb0, 0xa8, 0x3e, 0x1d, 0x54, 0x98, 0x25, 0x47, 0x13, - 0x56, 0x1d, 0xee, 0x79, 0x6d, 0x57, 0x3d, 0x60, 0x66, 0x86, 0x7b, 0xed, 0xef, 0xe4, 0x13, 0xb6, - 0x05, 0xcb, 0x7d, 0x72, 0xed, 0x32, 0x7a, 0xc5, 0xcd, 0xca, 0x76, 0xaf, 0x4f, 0xae, 0x1d, 0x7a, - 0xc5, 0xd5, 0x3a, 0xed, 0x73, 0xb5, 0x27, 0xb7, 0xfd, 0x30, 0xa0, 0x5d, 0xae, 0x0e, 0x69, 0xd9, - 0xa9, 0x18, 0xf8, 0x89, 0x46, 0xe5, 0x8d, 0x60, 0xaa, 0xd9, 0xd3, 0x47, 0xb0, 0xec, 0x94, 0x58, - 0xea, 0x06, 0xd8, 0x4f, 0x61, 0x6b, 0x46, 0xcc, 0xa6, 0xc6, 0x8f, 0x60, 0x49, 0x37, 0xb0, 0x29, - 0xae, 0xd5, 0xd4, 0x9f, 0x3f, 0xdf, 0xcb, 0xbf, 0xa6, 0x59, 0x8d, 0x84, 0xfd, 0xe7, 0x1c, 0x7c, - 0x98, 0xb5, 0x74, 0x14, 0x04, 0x72, 0x4d, 0xe2, 0x3f, 0x7f, 0x09, 0xa6, 0x32, 0x5b, 0x98, 0x91, - 0xd9, 0x0b, 0xd8, 0x99, 0x17, 0xcf, 0x1d, 0xd2, 0xfb, 0x66, 0xf2, 0x6c, 0x8f, 0xa2, 0xe8, 0xdd, - 0x89, 0xa5, 0xe3, 0xcf, 0x67, 0xe2, 0x9f, 0x2e, 0xba, 0x32, 0x76, 0x87, 0xa8, 0xe4, 0xf3, 0x13, - 0x90, 0x01, 0xea, 0x8d, 0x20, 0x19, 0xc7, 0x67, 0x50, 0xcb, 0xa0, 0xc6, 0xf0, 0x81, 0xdc, 0x0b, - 0x46, 0xbb, 0x44, 0xf1, 0xb0, 0xde, 0x9c, 0xfc, 0x5e, 0x35, 0x0a, 0x46, 0x4c, 0xce, 0xfb, 0x6f, - 0x09, 0x17, 0xc8, 0x92, 0xf9, 0x99, 0x38, 0xf8, 0x0c, 0x36, 0x27, 0x19, 0xc6, 0xc7, 0x36, 0x2c, - 0x4f, 0x0c, 0xe0, 0x11, 0x6d, 0x5b, 0x50, 0x3d, 0x17, 0x34, 0x52, 0xa1, 0x25, 0x96, 0x6a, 0xb0, - 0x96, 0xc2, 0xcc, 0x34, 0xfe, 0x13, 0xd4, 0x47, 0xe0, 0xb7, 0x7e, 0xe8, 0xf7, 0xe3, 0x7e, 0x6a, - 0x65, 0x9c, 0x67, 0xdf, 0xba, 0x0f, 0x6a, 0xd8, 0xbb, 0xc2, 0xef, 0x63, 0xb2, 0x15, 0x15, 0x9c, - 0xa2, 0xc4, 0x5e, 0x69, 0xc8, 0xfe, 0x1c, 0x1a, 0xd3, 0x96, 0x6f, 0x10, 0xba, 0x0a, 0x93, 0x30, - 0x91, 0x89, 0x5d, 0x16, 0x3f, 0x05, 0x9a, 0xe0, 0x4f, 0xe0, 0xbe, 0x7e, 0x83, 0x4f, 0xaf, 0xe5, - 0x5b, 0x46, 0x02, 0xb9, 0x00, 0x44, 0x84, 0x61, 0x28, 0xd0, 0x4b, 0xd2, 0x50, 0xbb, 0x9d, 0x66, - 0xbb, 0x7e, 0xb2, 0x27, 0x43, 0x02, 0x3d, 0xf7, 0xec, 0x87, 0x60, 0xbf, 0xcb, 0x8a, 0xf1, 0xb5, - 0x07, 0x3b, 0x93, 0x52, 0xa7, 0x01, 0x76, 0xc6, 0x8e, 0xec, 0xfb, 0xb0, 0x3b, 0x57, 0xc2, 0x18, - 0xb1, 0xf4, 0x5a, 0x28, 0x93, 0x18, 0x75, 0xd0, 0xaf, 0xf5, 0xca, 0x66, 0x30, 0x53, 0xa0, 0x75, - 0x58, 0x24, 0x9e, 0xc7, 0x92, 0x87, 0x50, 0x13, 0xf6, 0x16, 0xd4, 0x1d, 0xe4, 0x72, 0x7f, 0x19, - 0xf5, 0x52, 0x62, 0x65, 0x1b, 0x1a, 0xd3, 0x2c, 0xe3, 0xf5, 0x00, 0xea, 0xaf, 0x53, 0xb8, 0xbc, - 0x0e, 0x33, 0xaf, 0xd3, 0x8a, 0xb9, 0x4e, 0xf6, 0x19, 0x34, 0xa6, 0x15, 0xee, 0x74, 0x91, 0x3f, - 0x4c, 0xdb, 0x79, 0x43, 0x7c, 0x71, 0x46, 0x65, 0x23, 0x27, 0xee, 0x2b, 0x90, 0x37, 0x47, 0x52, - 0x70, 0xf2, 0xbe, 0x97, 0xe9, 0x8b, 0xfc, 0x44, 0x5f, 0xec, 0xc1, 0xce, 0x3c, 0x63, 0x26, 0xcf, - 0x1a, 0xac, 0x3d, 0x0f, 0x7d, 0xa1, 0xaf, 0x4b, 0x52, 0x98, 0x4f, 0xc0, 0x4a, 0x83, 0x37, 0x68, - 0xc0, 0x9f, 0x72, 0xb0, 0xd3, 0xa2, 0x51, 0x1c, 0xa8, 0x7d, 0x4c, 0x37, 0xc2, 0xd7, 0x34, 0x96, - 0x27, 0x9a, 0xc4, 0xfd, 0x2b, 0x58, 0x95, 0x9d, 0xef, 0x76, 0x18, 0x12, 0x81, 0x9e, 0x1b, 0x26, - 0xdf, 0x0c, 0x65, 0x09, 0x1f, 0x6b, 0xf4, 0x3b, 0x2e, 0x7b, 0x8f, 0x74, 0xa4, 0xd1, 0xf4, 0xd0, - 0x05, 0x0d, 0xa9, 0xc1, 0xfb, 0x05, 0x94, 0xfa, 0x2a, 0x32, 0x97, 0x04, 0x3e, 0xd1, 0xc3, 0xb7, - 0x78, 0xb8, 0x31, 0xb9, 0x63, 0x1e, 0x49, 0xa6, 0x53, 0xd4, 0xa2, 0x8a, 0xb0, 0x1e, 0xc3, 0x7a, - 0x6a, 0xa4, 0x8c, 0x57, 0xb1, 0x05, 0xe5, 0xa3, 0x96, 0xe2, 0x8d, 0x36, 0xb2, 0xfb, 0xb0, 0x3b, - 0x37, 0x2f, 0x53, 0xc2, 0xbf, 0xe6, 0xa0, 0x2a, 0xcb, 0x95, 0xbe, 0x7c, 0xd6, 0x6f, 0x61, 0x49, - 0x4b, 0x9b, 0x23, 0x9f, 0x13, 0x9e, 0x11, 0x9a, 0x1b, 0x59, 0x7e, 0x6e, 0x64, 0xb3, 0xea, 0x59, - 0x98, 0x51, 0xcf, 0xe4, 0x84, 0xb3, 0x53, 0x60, 0x03, 0x6a, 0x27, 0xd8, 0xa7, 0x02, 0xb3, 0x07, - 0x7f, 0x08, 0xeb, 0x59, 0xf8, 0x06, 0x47, 0xff, 0x15, 0xec, 0xb6, 0x18, 0x95, 0x4a, 0xca, 0xc5, - 0x9b, 0x1e, 0x86, 0xc7, 0x24, 0xee, 0xf6, 0xc4, 0x0f, 0xd1, 0x0d, 0xa6, 0xa2, 0xfd, 0x07, 0xd8, - 0x9b, 0xaf, 0x7e, 0x03, 0xf7, 0x5b, 0x50, 0xd7, 0x8a, 0x84, 0x1b, 0x3b, 0x5e, 0xea, 0x7e, 0x4f, - 0xb3, 0x4c, 0x01, 0xfe, 0x92, 0x83, 0xea, 0x39, 0x66, 0xfb, 0xfe, 0xb6, 0x87, 0x36, 0xe3, 0x04, - 0xf2, 0xb3, 0x3a, 0xfa, 0x11, 0xac, 0xa9, 0x55, 0x57, 0x7e, 0x2a, 0x33, 0xe1, 0x72, 0x19, 0x93, - 0xd9, 0x70, 0x57, 0x15, 0x63, 0x3c, 0xa6, 0xd5, 0x24, 0xc7, 0x89, 0x9b, 0x67, 0x3f, 0x1f, 0x27, - 0xe2, 0xa0, 0x32, 0x32, 0x1e, 0xd5, 0xb7, 0x8b, 0x59, 0x7e, 0xba, 0xcc, 0x30, 0x65, 0xfc, 0x3c, - 0x04, 0x5b, 0x3e, 0x3f, 0xa9, 0x89, 0x71, 0x14, 0x7a, 0x72, 0xd0, 0x66, 0x9e, 0xef, 0xd7, 0xf0, - 0xe0, 0x9d, 0x52, 0x77, 0x7d, 0xce, 0x37, 0xa0, 0x96, 0xee, 0x84, 0x54, 0x4f, 0x66, 0xe1, 0x1b, - 0x34, 0xc5, 0x63, 0x28, 0x3f, 0x21, 0x9d, 0xcb, 0x78, 0xd4, 0x81, 0x7b, 0x50, 0xec, 0xd0, 0xb0, - 0x13, 0x33, 0x86, 0x61, 0x67, 0x68, 0x06, 0x4f, 0x1a, 0xb2, 0x3f, 0x87, 0x4a, 0xa2, 0x62, 0x1c, - 0x3c, 0x84, 0x45, 0x1c, 0x8c, 0x0b, 0x5b, 0x69, 0x26, 0xff, 0x27, 0x3f, 0x95, 0xa8, 0xa3, 0x99, - 0xe6, 0x11, 0x11, 0x94, 0xe1, 0x19, 0xa3, 0xfd, 0x8c, 0x57, 0xfb, 0x08, 0xb6, 0x66, 0xf0, 0x6e, - 0x63, 0xfe, 0xc9, 0x27, 0x3f, 0x36, 0x07, 0xbe, 0x40, 0xce, 0x9b, 0x3e, 0x3d, 0xd0, 0xbf, 0x0e, - 0xba, 0xf4, 0x60, 0x20, 0x0e, 0xd4, 0x7f, 0xeb, 0x0f, 0xa6, 0x3e, 0x02, 0xda, 0x4b, 0x8a, 0xf1, - 0xe9, 0xff, 0x02, 0x00, 0x00, 0xff, 0xff, 0x7e, 0x8b, 0x0f, 0x3a, 0x37, 0x18, 0x00, 0x00, + proto.RegisterFile("tabletmanagerdata.proto", fileDescriptor_tabletmanagerdata_9e0123608316bc1a) +} + +var fileDescriptor_tabletmanagerdata_9e0123608316bc1a = []byte{ + // 2050 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x59, 0x5b, 0x6f, 0x1b, 0xc7, + 0x15, 0x06, 0x49, 0x49, 0x96, 0x0e, 0x2f, 0x22, 0x97, 0x94, 0x48, 0xc9, 0x8d, 0x24, 0xaf, 0x9d, + 0xc6, 0x75, 0x51, 0x2a, 0x56, 0xd2, 0x20, 0x48, 0x91, 0xa2, 0xb2, 0x2e, 0xb6, 0x13, 0x25, 0x56, + 0x56, 0xbe, 0x14, 0x41, 0x81, 0xc5, 0x70, 0x77, 0x44, 0x2e, 0xb4, 0xdc, 0x59, 0xcf, 0xcc, 0x52, + 0xe2, 0x9f, 0xe8, 0x5b, 0xdf, 0xfa, 0x56, 0xa0, 0x7d, 0xef, 0x8f, 0x49, 0xd1, 0x5f, 0xd2, 0x87, + 0xbe, 0x14, 0x73, 0x59, 0x72, 0x96, 0x17, 0x5b, 0x12, 0x5c, 0x20, 0x2f, 0xc6, 0x9e, 0x6f, 0xce, + 0x7d, 0xce, 0x39, 0x73, 0x68, 0x41, 0x93, 0xa3, 0x4e, 0x88, 0x79, 0x1f, 0x45, 0xa8, 0x8b, 0xa9, + 0x8f, 0x38, 0x6a, 0xc7, 0x94, 0x70, 0x62, 0xd5, 0xa6, 0x0e, 0x36, 0x8b, 0x6f, 0x13, 0x4c, 0x87, + 0xea, 0x7c, 0xb3, 0xc2, 0x49, 0x4c, 0xc6, 0xfc, 0x9b, 0x6b, 0x14, 0xc7, 0x61, 0xe0, 0x21, 0x1e, + 0x90, 0xc8, 0x80, 0xcb, 0x21, 0xe9, 0x26, 0x3c, 0x08, 0x15, 0x69, 0xff, 0x3b, 0x07, 0xab, 0x2f, + 0x85, 0xe2, 0x43, 0x7c, 0x1e, 0x44, 0x81, 0x60, 0xb6, 0x2c, 0x58, 0x88, 0x50, 0x1f, 0xb7, 0x72, + 0x3b, 0xb9, 0x87, 0x2b, 0x8e, 0xfc, 0xb6, 0xd6, 0x61, 0x89, 0x79, 0x3d, 0xdc, 0x47, 0xad, 0xbc, + 0x44, 0x35, 0x65, 0xb5, 0xe0, 0x8e, 0x47, 0xc2, 0xa4, 0x1f, 0xb1, 0x56, 0x61, 0xa7, 0xf0, 0x70, + 0xc5, 0x49, 0x49, 0xab, 0x0d, 0xf5, 0x98, 0x06, 0x7d, 0x44, 0x87, 0xee, 0x05, 0x1e, 0xba, 0x29, + 0xd7, 0x82, 0xe4, 0xaa, 0xe9, 0xa3, 0x6f, 0xf1, 0xf0, 0x40, 0xf3, 0x5b, 0xb0, 0xc0, 0x87, 0x31, + 0x6e, 0x2d, 0x2a, 0xab, 0xe2, 0xdb, 0xda, 0x86, 0xa2, 0x70, 0xdd, 0x0d, 0x71, 0xd4, 0xe5, 0xbd, + 0xd6, 0xd2, 0x4e, 0xee, 0xe1, 0x82, 0x03, 0x02, 0x3a, 0x91, 0x88, 0x75, 0x17, 0x56, 0x28, 0xb9, + 0x74, 0x3d, 0x92, 0x44, 0xbc, 0x75, 0x47, 0x1e, 0x2f, 0x53, 0x72, 0x79, 0x20, 0x68, 0xfb, 0xef, + 0x39, 0xa8, 0x9e, 0x49, 0x37, 0x8d, 0xe0, 0x3e, 0x81, 0x55, 0x21, 0xdf, 0x41, 0x0c, 0xbb, 0x3a, + 0x22, 0x15, 0x67, 0x25, 0x85, 0x95, 0x88, 0xf5, 0x02, 0x54, 0xc6, 0x5d, 0x7f, 0x24, 0xcc, 0x5a, + 0xf9, 0x9d, 0xc2, 0xc3, 0xe2, 0x9e, 0xdd, 0x9e, 0xbe, 0xa4, 0x89, 0x24, 0x3a, 0x55, 0x9e, 0x05, + 0x98, 0x48, 0xd5, 0x00, 0x53, 0x16, 0x90, 0xa8, 0x55, 0x90, 0x16, 0x53, 0x52, 0x38, 0x6a, 0x29, + 0xab, 0x07, 0x3d, 0x14, 0x75, 0xb1, 0x83, 0x59, 0x12, 0x72, 0xeb, 0x19, 0x94, 0x3b, 0xf8, 0x9c, + 0xd0, 0x8c, 0xa3, 0xc5, 0xbd, 0xfb, 0x33, 0xac, 0x4f, 0x86, 0xe9, 0x94, 0x94, 0xa4, 0x8e, 0xe5, + 0x18, 0x4a, 0xe8, 0x9c, 0x63, 0xea, 0x1a, 0x77, 0x78, 0x4d, 0x45, 0x45, 0x29, 0xa8, 0x60, 0xfb, + 0x3f, 0x39, 0xa8, 0xbc, 0x62, 0x98, 0x9e, 0x62, 0xda, 0x0f, 0x18, 0xd3, 0xc5, 0xd2, 0x23, 0x8c, + 0xa7, 0xc5, 0x22, 0xbe, 0x05, 0x96, 0x30, 0x4c, 0x75, 0xa9, 0xc8, 0x6f, 0xeb, 0xd7, 0x50, 0x8b, + 0x11, 0x63, 0x97, 0x84, 0xfa, 0xae, 0xd7, 0xc3, 0xde, 0x05, 0x4b, 0xfa, 0x32, 0x0f, 0x0b, 0x4e, + 0x35, 0x3d, 0x38, 0xd0, 0xb8, 0xf5, 0x03, 0x40, 0x4c, 0x83, 0x41, 0x10, 0xe2, 0x2e, 0x56, 0x25, + 0x53, 0xdc, 0x7b, 0x3c, 0xc3, 0xdb, 0xac, 0x2f, 0xed, 0xd3, 0x91, 0xcc, 0x51, 0xc4, 0xe9, 0xd0, + 0x31, 0x94, 0x6c, 0x7e, 0x0d, 0xab, 0x13, 0xc7, 0x56, 0x15, 0x0a, 0x17, 0x78, 0xa8, 0x3d, 0x17, + 0x9f, 0x56, 0x03, 0x16, 0x07, 0x28, 0x4c, 0xb0, 0xf6, 0x5c, 0x11, 0x5f, 0xe5, 0xbf, 0xcc, 0xd9, + 0x3f, 0xe5, 0xa0, 0x74, 0xd8, 0x79, 0x4f, 0xdc, 0x15, 0xc8, 0xfb, 0x1d, 0x2d, 0x9b, 0xf7, 0x3b, + 0xa3, 0x3c, 0x14, 0x8c, 0x3c, 0xbc, 0x98, 0x11, 0xda, 0xee, 0x8c, 0xd0, 0x4c, 0x63, 0xff, 0xcf, + 0xc0, 0xfe, 0x96, 0x83, 0xe2, 0xd8, 0x12, 0xb3, 0x4e, 0xa0, 0x2a, 0xfc, 0x74, 0xe3, 0x31, 0xd6, + 0xca, 0x49, 0x2f, 0xef, 0xbd, 0xf7, 0x02, 0x9c, 0xd5, 0x24, 0x43, 0x33, 0xeb, 0x18, 0x2a, 0x7e, + 0x27, 0xa3, 0x4b, 0x75, 0xd0, 0xf6, 0x7b, 0x22, 0x76, 0xca, 0xbe, 0x41, 0x31, 0xfb, 0x13, 0x28, + 0x9e, 0x06, 0x51, 0xd7, 0xc1, 0x6f, 0x13, 0xcc, 0xb8, 0x68, 0xa5, 0x18, 0x0d, 0x43, 0x82, 0x7c, + 0x1d, 0x64, 0x4a, 0xda, 0x0f, 0xa1, 0xa4, 0x18, 0x59, 0x4c, 0x22, 0x86, 0xdf, 0xc1, 0xf9, 0x08, + 0x4a, 0x67, 0x21, 0xc6, 0x71, 0xaa, 0x73, 0x13, 0x96, 0xfd, 0x84, 0xca, 0x71, 0x29, 0x59, 0x0b, + 0xce, 0x88, 0xb6, 0x57, 0xa1, 0xac, 0x79, 0x95, 0x5a, 0xfb, 0x5f, 0x39, 0xb0, 0x8e, 0xae, 0xb0, + 0x97, 0x70, 0xfc, 0x8c, 0x90, 0x8b, 0x54, 0xc7, 0xac, 0xc9, 0xb9, 0x05, 0x10, 0x23, 0x8a, 0xfa, + 0x98, 0x63, 0xaa, 0xc2, 0x5f, 0x71, 0x0c, 0xc4, 0x3a, 0x85, 0x15, 0x7c, 0xc5, 0x29, 0x72, 0x71, + 0x34, 0x90, 0x33, 0xb4, 0xb8, 0xf7, 0xd9, 0x8c, 0xec, 0x4c, 0x5b, 0x6b, 0x1f, 0x09, 0xb1, 0xa3, + 0x68, 0xa0, 0x6a, 0x62, 0x19, 0x6b, 0x72, 0xf3, 0x77, 0x50, 0xce, 0x1c, 0xdd, 0xa8, 0x1e, 0xce, + 0xa1, 0x9e, 0x31, 0xa5, 0xf3, 0xb8, 0x0d, 0x45, 0x7c, 0x15, 0x70, 0x97, 0x71, 0xc4, 0x13, 0xa6, + 0x13, 0x04, 0x02, 0x3a, 0x93, 0x88, 0x7c, 0x20, 0xb8, 0x4f, 0x12, 0x3e, 0x7a, 0x20, 0x24, 0xa5, + 0x71, 0x4c, 0xd3, 0x2e, 0xd0, 0x94, 0x3d, 0x80, 0xea, 0x53, 0xcc, 0xd5, 0x5c, 0x49, 0xd3, 0xb7, + 0x0e, 0x4b, 0x32, 0x70, 0x55, 0x71, 0x2b, 0x8e, 0xa6, 0xac, 0xfb, 0x50, 0x0e, 0x22, 0x2f, 0x4c, + 0x7c, 0xec, 0x0e, 0x02, 0x7c, 0xc9, 0xa4, 0x89, 0x65, 0xa7, 0xa4, 0xc1, 0xd7, 0x02, 0xb3, 0x3e, + 0x86, 0x0a, 0xbe, 0x52, 0x4c, 0x5a, 0x89, 0x7a, 0x90, 0xca, 0x1a, 0x95, 0x03, 0x9a, 0xd9, 0x18, + 0x6a, 0x86, 0x5d, 0x1d, 0xdd, 0x29, 0xd4, 0xd4, 0x64, 0x34, 0x86, 0xfd, 0x4d, 0xa6, 0x6d, 0x95, + 0x4d, 0x20, 0x76, 0x13, 0xd6, 0x9e, 0x62, 0x6e, 0x94, 0xb0, 0x8e, 0xd1, 0xfe, 0x11, 0xd6, 0x27, + 0x0f, 0xb4, 0x13, 0x7f, 0x80, 0x62, 0xb6, 0xe9, 0x84, 0xf9, 0xad, 0x19, 0xe6, 0x4d, 0x61, 0x53, + 0xc4, 0x6e, 0x80, 0x75, 0x86, 0xb9, 0x83, 0x91, 0xff, 0x22, 0x0a, 0x87, 0xa9, 0xc5, 0x35, 0xa8, + 0x67, 0x50, 0x5d, 0xc2, 0x63, 0xf8, 0x0d, 0x0d, 0x38, 0x4e, 0xb9, 0xd7, 0xa1, 0x91, 0x85, 0x35, + 0xfb, 0x37, 0x50, 0x53, 0x8f, 0xd3, 0xcb, 0x61, 0x9c, 0x32, 0x5b, 0xbf, 0x85, 0xa2, 0x72, 0xcf, + 0x95, 0x4f, 0xb7, 0x70, 0xb9, 0xb2, 0xd7, 0x68, 0x8f, 0x36, 0x11, 0x99, 0x73, 0x2e, 0x25, 0x80, + 0x8f, 0xbe, 0x85, 0x9f, 0xa6, 0xae, 0xb1, 0x43, 0x0e, 0x3e, 0xa7, 0x98, 0xf5, 0x44, 0x49, 0x99, + 0x0e, 0x65, 0x61, 0xcd, 0xde, 0x84, 0x35, 0x27, 0x89, 0x9e, 0x61, 0x14, 0xf2, 0x9e, 0x7c, 0x38, + 0x52, 0x81, 0x16, 0xac, 0x4f, 0x1e, 0x68, 0x91, 0xcf, 0xa1, 0xf5, 0xbc, 0x1b, 0x11, 0x8a, 0xd5, + 0xe1, 0x11, 0xa5, 0x84, 0x66, 0x46, 0x0a, 0xe7, 0x98, 0x46, 0xe3, 0x41, 0x21, 0x49, 0xfb, 0x2e, + 0x6c, 0xcc, 0x90, 0xd2, 0x2a, 0xbf, 0x12, 0x4e, 0x8b, 0x79, 0x92, 0xad, 0xe4, 0xfb, 0x50, 0xbe, + 0x44, 0x01, 0x77, 0x63, 0xc2, 0xc6, 0xc5, 0xb4, 0xe2, 0x94, 0x04, 0x78, 0xaa, 0x31, 0x15, 0x99, + 0x29, 0xab, 0x75, 0xee, 0xc1, 0xfa, 0x29, 0xc5, 0xe7, 0x61, 0xd0, 0xed, 0x4d, 0x34, 0x88, 0xd8, + 0xb6, 0x64, 0xe2, 0xd2, 0x0e, 0x49, 0x49, 0xbb, 0x0b, 0xcd, 0x29, 0x19, 0x5d, 0x57, 0x27, 0x50, + 0x51, 0x5c, 0x2e, 0x95, 0x7b, 0x45, 0x3a, 0xcf, 0x3f, 0x9e, 0x5b, 0xd9, 0xe6, 0x16, 0xe2, 0x94, + 0x3d, 0x83, 0x62, 0xf6, 0x7f, 0x73, 0x60, 0xed, 0xc7, 0x71, 0x38, 0xcc, 0x7a, 0x56, 0x85, 0x02, + 0x7b, 0x1b, 0xa6, 0x23, 0x86, 0xbd, 0x0d, 0xc5, 0x88, 0x39, 0x27, 0xd4, 0xc3, 0xba, 0x59, 0x15, + 0x21, 0xd6, 0x00, 0x14, 0x86, 0xe4, 0xd2, 0x35, 0xb6, 0x53, 0x39, 0x19, 0x96, 0x9d, 0xaa, 0x3c, + 0x70, 0xc6, 0xf8, 0xf4, 0x02, 0xb4, 0xf0, 0xa1, 0x16, 0xa0, 0xc5, 0x5b, 0x2e, 0x40, 0xff, 0xc8, + 0x41, 0x3d, 0x13, 0xbd, 0xce, 0xf1, 0xcf, 0x6f, 0x55, 0xab, 0x43, 0xed, 0x84, 0x78, 0x17, 0x6a, + 0xea, 0xa5, 0xad, 0xd1, 0x00, 0xcb, 0x04, 0xc7, 0x8d, 0xf7, 0x2a, 0x0a, 0xa7, 0x98, 0xd7, 0xa1, + 0x91, 0x85, 0x35, 0xfb, 0x3f, 0x73, 0xd0, 0xd2, 0x4f, 0xc4, 0x31, 0xe6, 0x5e, 0x6f, 0x9f, 0x1d, + 0x76, 0x46, 0x75, 0xd0, 0x80, 0x45, 0xf9, 0xa3, 0x44, 0x26, 0xa0, 0xe4, 0x28, 0xc2, 0x6a, 0xc2, + 0x1d, 0xbf, 0xe3, 0xca, 0xa7, 0x51, 0xbf, 0x0e, 0x7e, 0xe7, 0x7b, 0xf1, 0x38, 0x6e, 0xc0, 0x72, + 0x1f, 0x5d, 0xb9, 0x94, 0x5c, 0x32, 0xbd, 0x0c, 0xde, 0xe9, 0xa3, 0x2b, 0x87, 0x5c, 0x32, 0xb9, + 0xa8, 0x07, 0x4c, 0x6e, 0xe0, 0x9d, 0x20, 0x0a, 0x49, 0x97, 0xc9, 0xeb, 0x5f, 0x76, 0x2a, 0x1a, + 0x7e, 0xa2, 0x50, 0xd1, 0x6b, 0x54, 0xb6, 0x91, 0x79, 0xb9, 0xcb, 0x4e, 0x89, 0x1a, 0xbd, 0x65, + 0x3f, 0x85, 0x8d, 0x19, 0x3e, 0xeb, 0xdb, 0x7b, 0x04, 0x4b, 0xaa, 0x35, 0xf4, 0xb5, 0x59, 0x6d, + 0xf5, 0xc3, 0xea, 0x07, 0xf1, 0xaf, 0x6e, 0x03, 0xcd, 0x61, 0xff, 0x39, 0x07, 0x1f, 0x65, 0x35, + 0xed, 0x87, 0xa1, 0x58, 0xc0, 0xd8, 0x87, 0x4f, 0xc1, 0x54, 0x64, 0x0b, 0x33, 0x22, 0x3b, 0x81, + 0xad, 0x79, 0xfe, 0xdc, 0x22, 0xbc, 0x6f, 0x27, 0xef, 0x76, 0x3f, 0x8e, 0xdf, 0x1d, 0x98, 0xe9, + 0x7f, 0x3e, 0xe3, 0xff, 0x74, 0xd2, 0xa5, 0xb2, 0x5b, 0x78, 0x25, 0x1e, 0xb6, 0x10, 0x0d, 0xb0, + 0xda, 0x35, 0xd2, 0x02, 0x3d, 0x86, 0x7a, 0x06, 0xd5, 0x8a, 0x77, 0xc5, 0xc6, 0x31, 0xda, 0x52, + 0x8a, 0x7b, 0xcd, 0xf6, 0xe4, 0x2f, 0x61, 0x2d, 0xa0, 0xd9, 0xc4, 0x4b, 0xf2, 0x1d, 0x62, 0x1c, + 0xd3, 0x74, 0x32, 0xa7, 0x06, 0x3e, 0x87, 0xf5, 0xc9, 0x03, 0x6d, 0x63, 0x13, 0x96, 0x27, 0x46, + 0xfb, 0x88, 0xb6, 0x2d, 0xa8, 0x9e, 0x71, 0x12, 0x4b, 0xd7, 0x52, 0x4d, 0x75, 0xa8, 0x19, 0x98, + 0x6e, 0xa4, 0x3f, 0x42, 0x73, 0x04, 0x7e, 0x17, 0x44, 0x41, 0x3f, 0xe9, 0x1b, 0xcb, 0xe8, 0x3c, + 0xfd, 0xd6, 0x3d, 0x90, 0xcf, 0x88, 0xcb, 0x83, 0x3e, 0x4e, 0xf7, 0xad, 0x82, 0x53, 0x14, 0xd8, + 0x4b, 0x05, 0xd9, 0x5f, 0x40, 0x6b, 0x5a, 0xf3, 0x35, 0x5c, 0x97, 0x6e, 0x22, 0xca, 0x33, 0xbe, + 0x8b, 0xe4, 0x1b, 0xa0, 0x76, 0xfe, 0x4f, 0x70, 0x77, 0x8c, 0xbe, 0x8a, 0x78, 0x10, 0xee, 0x8b, + 0xe9, 0xf3, 0x81, 0x02, 0xd8, 0x82, 0x5f, 0xcc, 0xd6, 0xae, 0xad, 0x1f, 0xc2, 0x3d, 0xb5, 0x5b, + 0x1c, 0x5d, 0x89, 0x37, 0x1a, 0x85, 0x62, 0xb1, 0x89, 0x11, 0xc5, 0x11, 0xc7, 0x7e, 0xea, 0x83, + 0xdc, 0x59, 0xd5, 0xb1, 0x1b, 0xa4, 0xfb, 0x3f, 0xa4, 0xd0, 0x73, 0xdf, 0x7e, 0x00, 0xf6, 0xbb, + 0xb4, 0x68, 0x5b, 0x3b, 0xb0, 0x35, 0xc9, 0x75, 0x14, 0x62, 0x6f, 0x6c, 0xc8, 0xbe, 0x07, 0xdb, + 0x73, 0x39, 0xb4, 0x12, 0x4b, 0xad, 0xbb, 0x22, 0x9c, 0x51, 0xfd, 0xfe, 0x4a, 0xad, 0xa2, 0x1a, + 0xd3, 0xd7, 0xd3, 0x80, 0x45, 0xe4, 0xfb, 0x34, 0x7d, 0xe0, 0x15, 0x61, 0x6f, 0x40, 0xd3, 0xc1, + 0x4c, 0xec, 0x65, 0xa3, 0x4a, 0x4e, 0xb5, 0x6c, 0x42, 0x6b, 0xfa, 0x48, 0x5b, 0xdd, 0x85, 0xe6, + 0x6b, 0x03, 0x17, 0xcd, 0x38, 0xb3, 0x99, 0x57, 0x74, 0x33, 0xdb, 0xc7, 0xd0, 0x9a, 0x16, 0xb8, + 0xd5, 0x18, 0xf9, 0xc8, 0xd4, 0xf3, 0x06, 0x05, 0xfc, 0x98, 0x88, 0x36, 0x4a, 0xcd, 0x57, 0x20, + 0xaf, 0xaf, 0xa4, 0xe0, 0xe4, 0x03, 0x3f, 0x53, 0x2f, 0xf9, 0x89, 0xaa, 0xdc, 0x81, 0xad, 0x79, + 0xca, 0x74, 0x9c, 0x75, 0xa8, 0x3d, 0x8f, 0x02, 0xae, 0x9a, 0x35, 0x4d, 0xcc, 0xa7, 0x60, 0x99, + 0xe0, 0x35, 0xca, 0xff, 0xa7, 0x1c, 0x6c, 0x9d, 0x92, 0x38, 0x09, 0xe5, 0x9e, 0xa9, 0x0a, 0xe1, + 0x1b, 0x92, 0x88, 0x1b, 0x4d, 0xfd, 0xfe, 0x25, 0xac, 0x8a, 0xb2, 0x75, 0x3d, 0x8a, 0x11, 0xc7, + 0xbe, 0x1b, 0xa5, 0xbf, 0x85, 0xca, 0x02, 0x3e, 0x50, 0xe8, 0xf7, 0x4c, 0xd4, 0x1e, 0xf2, 0x84, + 0x52, 0x73, 0xe4, 0x83, 0x82, 0xe4, 0xd8, 0xff, 0x12, 0x4a, 0x7d, 0xe9, 0x99, 0x8b, 0xc2, 0x00, + 0xa9, 0xd1, 0x5f, 0xdc, 0x5b, 0x9b, 0xdc, 0x9d, 0xf7, 0xc5, 0xa1, 0x53, 0x54, 0xac, 0x92, 0xb0, + 0x1e, 0x43, 0xc3, 0x18, 0x68, 0xe3, 0x15, 0x73, 0x41, 0xda, 0xa8, 0x1b, 0x67, 0xa3, 0x4d, 0xf3, + 0x1e, 0x6c, 0xcf, 0x8d, 0x4b, 0xa7, 0xf0, 0xaf, 0x39, 0xa8, 0x8a, 0x74, 0x99, 0xad, 0x6f, 0xfd, + 0x06, 0x96, 0x14, 0xb7, 0xbe, 0xf2, 0x39, 0xee, 0x69, 0xa6, 0xb9, 0x9e, 0xe5, 0xe7, 0x7a, 0x36, + 0x2b, 0x9f, 0x85, 0x19, 0xf9, 0x4c, 0x6f, 0x38, 0x3b, 0x83, 0xd6, 0xa0, 0x7e, 0x88, 0xfb, 0x84, + 0xe3, 0xec, 0xc5, 0xef, 0x41, 0x23, 0x0b, 0x5f, 0xe3, 0xea, 0xbf, 0x86, 0xed, 0x53, 0x4a, 0x84, + 0x90, 0x34, 0xf1, 0xa6, 0x87, 0xa3, 0x03, 0x94, 0x74, 0x7b, 0xfc, 0x55, 0x7c, 0x8d, 0x91, 0x66, + 0xff, 0x1e, 0x76, 0xe6, 0x8b, 0x5f, 0xc3, 0xfc, 0x06, 0x34, 0x95, 0x20, 0x62, 0x5a, 0x8f, 0x6f, + 0xf4, 0xf7, 0xf4, 0x91, 0x4e, 0xc0, 0x5f, 0x72, 0x50, 0x3d, 0xc3, 0xd9, 0xba, 0xbf, 0xe9, 0xa5, + 0xcd, 0xb8, 0x81, 0xfc, 0xac, 0x8a, 0x7e, 0x04, 0x35, 0xb9, 0xc2, 0xbb, 0x4c, 0x0c, 0x66, 0x97, + 0x09, 0x9f, 0xf4, 0xe6, 0xbe, 0x2a, 0x0f, 0xc6, 0x03, 0x5b, 0xbe, 0x23, 0x78, 0xa2, 0xf3, 0xec, + 0xe7, 0xe3, 0x40, 0x1c, 0x2c, 0x95, 0x8c, 0x47, 0xf5, 0xcd, 0x7c, 0x16, 0x3f, 0xc9, 0x66, 0xa8, + 0xd2, 0x76, 0x1e, 0x80, 0x2d, 0x1e, 0x3f, 0x63, 0x62, 0xec, 0x47, 0xbe, 0x18, 0xb4, 0x99, 0xe5, + 0xe1, 0x35, 0xdc, 0x7f, 0x27, 0xd7, 0x6d, 0x97, 0x89, 0x35, 0xa8, 0x9b, 0x95, 0x60, 0xd4, 0x64, + 0x16, 0xbe, 0x46, 0x51, 0x3c, 0x86, 0xf2, 0x13, 0xe4, 0x5d, 0x24, 0xa3, 0x0a, 0xdc, 0x81, 0xa2, + 0x47, 0x22, 0x2f, 0xa1, 0x14, 0x47, 0xde, 0x50, 0x0f, 0x1e, 0x13, 0xb2, 0xbf, 0x80, 0x4a, 0x2a, + 0xa2, 0x0d, 0x3c, 0x80, 0x45, 0x3c, 0x18, 0x27, 0xb6, 0xd2, 0x4e, 0xff, 0xff, 0xff, 0x48, 0xa0, + 0x8e, 0x3a, 0xd4, 0x8f, 0x08, 0x27, 0x14, 0x1f, 0x53, 0xd2, 0xcf, 0x58, 0xb5, 0xf7, 0x61, 0x63, + 0xc6, 0xd9, 0x4d, 0xd4, 0x3f, 0xf9, 0xf4, 0xc7, 0xf6, 0x20, 0xe0, 0x98, 0xb1, 0x76, 0x40, 0x76, + 0xd5, 0xd7, 0x6e, 0x97, 0xec, 0x0e, 0xf8, 0xae, 0xfc, 0x2b, 0xc4, 0xee, 0xd4, 0x8f, 0x9b, 0xce, + 0x92, 0x3c, 0xf8, 0xec, 0x7f, 0x01, 0x00, 0x00, 0xff, 0xff, 0x30, 0x7f, 0x51, 0x40, 0x0f, 0x19, + 0x00, 0x00, } diff --git a/go/vt/proto/tabletmanagerservice/tabletmanagerservice.pb.go b/go/vt/proto/tabletmanagerservice/tabletmanagerservice.pb.go index 6153dc90aab..41169028ed6 100644 --- a/go/vt/proto/tabletmanagerservice/tabletmanagerservice.pb.go +++ b/go/vt/proto/tabletmanagerservice/tabletmanagerservice.pb.go @@ -56,6 +56,8 @@ type TabletManagerClient interface { ReloadSchema(ctx context.Context, in *tabletmanagerdata.ReloadSchemaRequest, opts ...grpc.CallOption) (*tabletmanagerdata.ReloadSchemaResponse, error) PreflightSchema(ctx context.Context, in *tabletmanagerdata.PreflightSchemaRequest, opts ...grpc.CallOption) (*tabletmanagerdata.PreflightSchemaResponse, error) ApplySchema(ctx context.Context, in *tabletmanagerdata.ApplySchemaRequest, opts ...grpc.CallOption) (*tabletmanagerdata.ApplySchemaResponse, error) + LockTables(ctx context.Context, in *tabletmanagerdata.LockTablesRequest, opts ...grpc.CallOption) (*tabletmanagerdata.LockTablesResponse, error) + UnlockTables(ctx context.Context, in *tabletmanagerdata.UnlockTablesRequest, opts ...grpc.CallOption) (*tabletmanagerdata.UnlockTablesResponse, error) ExecuteFetchAsDba(ctx context.Context, in *tabletmanagerdata.ExecuteFetchAsDbaRequest, opts ...grpc.CallOption) (*tabletmanagerdata.ExecuteFetchAsDbaResponse, error) ExecuteFetchAsAllPrivs(ctx context.Context, in *tabletmanagerdata.ExecuteFetchAsAllPrivsRequest, opts ...grpc.CallOption) (*tabletmanagerdata.ExecuteFetchAsAllPrivsResponse, error) ExecuteFetchAsApp(ctx context.Context, in *tabletmanagerdata.ExecuteFetchAsAppRequest, opts ...grpc.CallOption) (*tabletmanagerdata.ExecuteFetchAsAppResponse, error) @@ -70,6 +72,9 @@ type TabletManagerClient interface { StopSlaveMinimum(ctx context.Context, in *tabletmanagerdata.StopSlaveMinimumRequest, opts ...grpc.CallOption) (*tabletmanagerdata.StopSlaveMinimumResponse, error) // StartSlave starts the mysql replication StartSlave(ctx context.Context, in *tabletmanagerdata.StartSlaveRequest, opts ...grpc.CallOption) (*tabletmanagerdata.StartSlaveResponse, error) + // StartSlave starts the mysql replication until and including + // the provided position + StartSlaveUntilAfter(ctx context.Context, in *tabletmanagerdata.StartSlaveUntilAfterRequest, opts ...grpc.CallOption) (*tabletmanagerdata.StartSlaveUntilAfterResponse, error) // TabletExternallyReparented tells a tablet that its underlying MySQL is // currently the master. It is only used in environments (tabletmanagerdata.such as Vitess+MoB) // in which MySQL is reparented by some agent external to Vitess, and then @@ -265,6 +270,24 @@ func (c *tabletManagerClient) ApplySchema(ctx context.Context, in *tabletmanager return out, nil } +func (c *tabletManagerClient) LockTables(ctx context.Context, in *tabletmanagerdata.LockTablesRequest, opts ...grpc.CallOption) (*tabletmanagerdata.LockTablesResponse, error) { + out := new(tabletmanagerdata.LockTablesResponse) + err := c.cc.Invoke(ctx, "/tabletmanagerservice.TabletManager/LockTables", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *tabletManagerClient) UnlockTables(ctx context.Context, in *tabletmanagerdata.UnlockTablesRequest, opts ...grpc.CallOption) (*tabletmanagerdata.UnlockTablesResponse, error) { + out := new(tabletmanagerdata.UnlockTablesResponse) + err := c.cc.Invoke(ctx, "/tabletmanagerservice.TabletManager/UnlockTables", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *tabletManagerClient) ExecuteFetchAsDba(ctx context.Context, in *tabletmanagerdata.ExecuteFetchAsDbaRequest, opts ...grpc.CallOption) (*tabletmanagerdata.ExecuteFetchAsDbaResponse, error) { out := new(tabletmanagerdata.ExecuteFetchAsDbaResponse) err := c.cc.Invoke(ctx, "/tabletmanagerservice.TabletManager/ExecuteFetchAsDba", in, out, opts...) @@ -337,6 +360,15 @@ func (c *tabletManagerClient) StartSlave(ctx context.Context, in *tabletmanagerd return out, nil } +func (c *tabletManagerClient) StartSlaveUntilAfter(ctx context.Context, in *tabletmanagerdata.StartSlaveUntilAfterRequest, opts ...grpc.CallOption) (*tabletmanagerdata.StartSlaveUntilAfterResponse, error) { + out := new(tabletmanagerdata.StartSlaveUntilAfterResponse) + err := c.cc.Invoke(ctx, "/tabletmanagerservice.TabletManager/StartSlaveUntilAfter", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *tabletManagerClient) TabletExternallyReparented(ctx context.Context, in *tabletmanagerdata.TabletExternallyReparentedRequest, opts ...grpc.CallOption) (*tabletmanagerdata.TabletExternallyReparentedResponse, error) { out := new(tabletmanagerdata.TabletExternallyReparentedResponse) err := c.cc.Invoke(ctx, "/tabletmanagerservice.TabletManager/TabletExternallyReparented", in, out, opts...) @@ -567,6 +599,8 @@ type TabletManagerServer interface { ReloadSchema(context.Context, *tabletmanagerdata.ReloadSchemaRequest) (*tabletmanagerdata.ReloadSchemaResponse, error) PreflightSchema(context.Context, *tabletmanagerdata.PreflightSchemaRequest) (*tabletmanagerdata.PreflightSchemaResponse, error) ApplySchema(context.Context, *tabletmanagerdata.ApplySchemaRequest) (*tabletmanagerdata.ApplySchemaResponse, error) + LockTables(context.Context, *tabletmanagerdata.LockTablesRequest) (*tabletmanagerdata.LockTablesResponse, error) + UnlockTables(context.Context, *tabletmanagerdata.UnlockTablesRequest) (*tabletmanagerdata.UnlockTablesResponse, error) ExecuteFetchAsDba(context.Context, *tabletmanagerdata.ExecuteFetchAsDbaRequest) (*tabletmanagerdata.ExecuteFetchAsDbaResponse, error) ExecuteFetchAsAllPrivs(context.Context, *tabletmanagerdata.ExecuteFetchAsAllPrivsRequest) (*tabletmanagerdata.ExecuteFetchAsAllPrivsResponse, error) ExecuteFetchAsApp(context.Context, *tabletmanagerdata.ExecuteFetchAsAppRequest) (*tabletmanagerdata.ExecuteFetchAsAppResponse, error) @@ -581,6 +615,9 @@ type TabletManagerServer interface { StopSlaveMinimum(context.Context, *tabletmanagerdata.StopSlaveMinimumRequest) (*tabletmanagerdata.StopSlaveMinimumResponse, error) // StartSlave starts the mysql replication StartSlave(context.Context, *tabletmanagerdata.StartSlaveRequest) (*tabletmanagerdata.StartSlaveResponse, error) + // StartSlave starts the mysql replication until and including + // the provided position + StartSlaveUntilAfter(context.Context, *tabletmanagerdata.StartSlaveUntilAfterRequest) (*tabletmanagerdata.StartSlaveUntilAfterResponse, error) // TabletExternallyReparented tells a tablet that its underlying MySQL is // currently the master. It is only used in environments (tabletmanagerdata.such as Vitess+MoB) // in which MySQL is reparented by some agent external to Vitess, and then @@ -898,6 +935,42 @@ func _TabletManager_ApplySchema_Handler(srv interface{}, ctx context.Context, de return interceptor(ctx, in, info, handler) } +func _TabletManager_LockTables_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(tabletmanagerdata.LockTablesRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(TabletManagerServer).LockTables(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/tabletmanagerservice.TabletManager/LockTables", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(TabletManagerServer).LockTables(ctx, req.(*tabletmanagerdata.LockTablesRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _TabletManager_UnlockTables_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(tabletmanagerdata.UnlockTablesRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(TabletManagerServer).UnlockTables(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/tabletmanagerservice.TabletManager/UnlockTables", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(TabletManagerServer).UnlockTables(ctx, req.(*tabletmanagerdata.UnlockTablesRequest)) + } + return interceptor(ctx, in, info, handler) +} + func _TabletManager_ExecuteFetchAsDba_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(tabletmanagerdata.ExecuteFetchAsDbaRequest) if err := dec(in); err != nil { @@ -1042,6 +1115,24 @@ func _TabletManager_StartSlave_Handler(srv interface{}, ctx context.Context, dec return interceptor(ctx, in, info, handler) } +func _TabletManager_StartSlaveUntilAfter_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(tabletmanagerdata.StartSlaveUntilAfterRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(TabletManagerServer).StartSlaveUntilAfter(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/tabletmanagerservice.TabletManager/StartSlaveUntilAfter", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(TabletManagerServer).StartSlaveUntilAfter(ctx, req.(*tabletmanagerdata.StartSlaveUntilAfterRequest)) + } + return interceptor(ctx, in, info, handler) +} + func _TabletManager_TabletExternallyReparented_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(tabletmanagerdata.TabletExternallyReparentedRequest) if err := dec(in); err != nil { @@ -1432,6 +1523,14 @@ var _TabletManager_serviceDesc = grpc.ServiceDesc{ MethodName: "ApplySchema", Handler: _TabletManager_ApplySchema_Handler, }, + { + MethodName: "LockTables", + Handler: _TabletManager_LockTables_Handler, + }, + { + MethodName: "UnlockTables", + Handler: _TabletManager_UnlockTables_Handler, + }, { MethodName: "ExecuteFetchAsDba", Handler: _TabletManager_ExecuteFetchAsDba_Handler, @@ -1464,6 +1563,10 @@ var _TabletManager_serviceDesc = grpc.ServiceDesc{ MethodName: "StartSlave", Handler: _TabletManager_StartSlave_Handler, }, + { + MethodName: "StartSlaveUntilAfter", + Handler: _TabletManager_StartSlaveUntilAfter_Handler, + }, { MethodName: "TabletExternallyReparented", Handler: _TabletManager_TabletExternallyReparented_Handler, @@ -1545,69 +1648,73 @@ var _TabletManager_serviceDesc = grpc.ServiceDesc{ } func init() { - proto.RegisterFile("tabletmanagerservice.proto", fileDescriptor_tabletmanagerservice_f4d7827db0506c7d) -} - -var fileDescriptor_tabletmanagerservice_f4d7827db0506c7d = []byte{ - // 956 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x98, 0xdf, 0x8f, 0x1b, 0x35, - 0x10, 0xc7, 0x89, 0x04, 0x95, 0x30, 0x3f, 0x6b, 0x21, 0x8a, 0x0e, 0x09, 0x28, 0x6d, 0xf9, 0xd1, - 0xa2, 0x4b, 0xaf, 0x47, 0x79, 0x4f, 0xaf, 0x77, 0xed, 0x21, 0x4e, 0x84, 0xa4, 0x70, 0x08, 0x24, - 0x24, 0x5f, 0x32, 0xcd, 0x2e, 0xb7, 0x59, 0x1b, 0xdb, 0x1b, 0xdd, 0x3d, 0x21, 0x21, 0xf1, 0x84, - 0xc4, 0x1b, 0xff, 0x2f, 0xf2, 0xee, 0xda, 0x19, 0x27, 0xb3, 0x4e, 0xf2, 0x76, 0xca, 0xf7, 0x33, - 0x33, 0xf6, 0x78, 0x66, 0xec, 0x5b, 0xb6, 0x67, 0xc5, 0x45, 0x01, 0x76, 0x2e, 0x4a, 0x31, 0x03, - 0x6d, 0x40, 0x2f, 0xf2, 0x09, 0xec, 0x2b, 0x2d, 0xad, 0xe4, 0xef, 0x51, 0xda, 0xde, 0xad, 0xe8, - 0xd7, 0xa9, 0xb0, 0xa2, 0xc1, 0x1f, 0xfd, 0x77, 0x9b, 0xbd, 0xf5, 0xa2, 0xd6, 0xce, 0x1a, 0x8d, - 0x9f, 0xb2, 0x57, 0x87, 0x79, 0x39, 0xe3, 0x1f, 0xed, 0xaf, 0xdb, 0x38, 0x61, 0x04, 0x7f, 0x54, - 0x60, 0xec, 0xde, 0xc7, 0x9d, 0xba, 0x51, 0xb2, 0x34, 0xf0, 0xe9, 0x2b, 0xfc, 0x3b, 0xf6, 0xda, - 0xb8, 0x00, 0x50, 0x9c, 0x62, 0x6b, 0xc5, 0x3b, 0xfb, 0xa4, 0x1b, 0x08, 0xde, 0x7e, 0x63, 0x6f, - 0x1c, 0x5f, 0xc1, 0xa4, 0xb2, 0xf0, 0x5c, 0xca, 0x4b, 0x7e, 0x8f, 0x30, 0x41, 0xba, 0xf7, 0xfc, - 0xd9, 0x26, 0x2c, 0xf8, 0xff, 0x99, 0xbd, 0xfe, 0x0c, 0xec, 0x78, 0x92, 0xc1, 0x5c, 0xf0, 0x3b, - 0x84, 0x59, 0x50, 0xbd, 0xef, 0xbb, 0x69, 0x28, 0x78, 0x9e, 0xb1, 0xb7, 0x9f, 0x81, 0x1d, 0x82, - 0x9e, 0xe7, 0xc6, 0xe4, 0xb2, 0x34, 0xfc, 0x0b, 0xda, 0x12, 0x21, 0x3e, 0xc6, 0x97, 0x5b, 0x90, - 0x38, 0x45, 0x63, 0xb0, 0x23, 0x10, 0xd3, 0xef, 0xcb, 0xe2, 0x9a, 0x4c, 0x11, 0xd2, 0x53, 0x29, - 0x8a, 0xb0, 0xe0, 0x5f, 0xb0, 0x37, 0x5b, 0xe1, 0x5c, 0xe7, 0x16, 0x78, 0xc2, 0xb2, 0x06, 0x7c, - 0x84, 0xcf, 0x37, 0x72, 0x21, 0xc4, 0xaf, 0x8c, 0x1d, 0x65, 0xa2, 0x9c, 0xc1, 0x8b, 0x6b, 0x05, - 0x9c, 0xca, 0xf0, 0x52, 0xf6, 0xee, 0xef, 0x6d, 0xa0, 0xf0, 0xfa, 0x47, 0xf0, 0x52, 0x83, 0xc9, - 0xc6, 0x56, 0x74, 0xac, 0x1f, 0x03, 0xa9, 0xf5, 0xc7, 0x1c, 0x3e, 0xeb, 0x51, 0x55, 0x3e, 0x07, - 0x51, 0xd8, 0xec, 0x28, 0x83, 0xc9, 0x25, 0x79, 0xd6, 0x31, 0x92, 0x3a, 0xeb, 0x55, 0x32, 0x04, - 0x52, 0xec, 0xe6, 0xe9, 0xac, 0x94, 0x1a, 0x1a, 0xf9, 0x58, 0x6b, 0xa9, 0xf9, 0x03, 0xc2, 0xc3, - 0x1a, 0xe5, 0xc3, 0x7d, 0xb5, 0x1d, 0x1c, 0x67, 0xaf, 0x90, 0x62, 0xda, 0xf6, 0x08, 0x9d, 0xbd, - 0x25, 0x90, 0xce, 0x1e, 0xe6, 0x42, 0x88, 0xdf, 0xd9, 0x3b, 0x43, 0x0d, 0x2f, 0x8b, 0x7c, 0x96, - 0xf9, 0x4e, 0xa4, 0x92, 0xb2, 0xc2, 0xf8, 0x40, 0xf7, 0xb7, 0x41, 0x71, 0xb3, 0x0c, 0x94, 0x2a, - 0xae, 0xdb, 0x38, 0x54, 0x11, 0x21, 0x3d, 0xd5, 0x2c, 0x11, 0x86, 0x0f, 0xa8, 0x1d, 0x34, 0x27, - 0x60, 0x27, 0xd9, 0xc0, 0x3c, 0xbd, 0x10, 0xe4, 0x01, 0xad, 0x51, 0xa9, 0x03, 0x22, 0xe0, 0x10, - 0xf1, 0x4f, 0xf6, 0x7e, 0x2c, 0x0f, 0x8a, 0x62, 0xa8, 0xf3, 0x85, 0xe1, 0x0f, 0x37, 0x7a, 0xf2, - 0xa8, 0x8f, 0x7d, 0xb0, 0x83, 0x45, 0xf7, 0x96, 0x07, 0x4a, 0x6d, 0xb1, 0xe5, 0x81, 0x52, 0xdb, - 0x6f, 0xb9, 0x86, 0xa3, 0x89, 0x57, 0x88, 0x05, 0xb8, 0x36, 0xac, 0x0c, 0x3d, 0xf1, 0x96, 0x7a, - 0x72, 0xe2, 0x61, 0x0c, 0xb7, 0xf3, 0x99, 0x30, 0x16, 0xf4, 0x50, 0x9a, 0xdc, 0xe6, 0xb2, 0x24, - 0xdb, 0x39, 0x46, 0x52, 0xed, 0xbc, 0x4a, 0xe2, 0xdb, 0x67, 0x6c, 0xa5, 0xaa, 0x57, 0x41, 0xde, - 0x3e, 0x41, 0x4d, 0xdd, 0x3e, 0x08, 0x0a, 0x9e, 0xe7, 0xec, 0xdd, 0xf0, 0xf3, 0x59, 0x5e, 0xe6, - 0xf3, 0x6a, 0xce, 0xef, 0xa7, 0x6c, 0x5b, 0xc8, 0xc7, 0x79, 0xb0, 0x15, 0x8b, 0x07, 0xf8, 0xd8, - 0x0a, 0x6d, 0x9b, 0x9d, 0xd0, 0x8b, 0xf4, 0x72, 0x6a, 0x80, 0x63, 0x2a, 0x38, 0xff, 0xa7, 0xc7, - 0xf6, 0x9a, 0xe7, 0xca, 0xf1, 0x95, 0x05, 0x5d, 0x8a, 0xc2, 0xdd, 0x4f, 0x4a, 0x68, 0x28, 0x2d, - 0x4c, 0xf9, 0xd7, 0x84, 0x9f, 0x6e, 0xdc, 0x47, 0x7f, 0xbc, 0xa3, 0x55, 0x58, 0xcd, 0x5f, 0x3d, - 0x76, 0x6b, 0x15, 0x3c, 0x2e, 0x60, 0xe2, 0x96, 0x72, 0xb0, 0x85, 0xd3, 0x96, 0xf5, 0xeb, 0x78, - 0xb4, 0x8b, 0xc9, 0xea, 0xb3, 0xc5, 0x25, 0xca, 0x74, 0x3e, 0x5b, 0x6a, 0x75, 0xd3, 0xb3, 0xa5, - 0x85, 0x70, 0xe1, 0xfc, 0x34, 0x02, 0x55, 0xe4, 0x13, 0xe1, 0x8a, 0xd5, 0xb5, 0x21, 0x59, 0x38, - 0xab, 0x50, 0xaa, 0x70, 0xd6, 0x59, 0x3c, 0xbd, 0xb0, 0x7a, 0x2e, 0x72, 0x7b, 0x22, 0x5d, 0xab, - 0x90, 0xd3, 0x8b, 0x46, 0x53, 0xd3, 0xab, 0xcb, 0x02, 0xef, 0x77, 0x04, 0xc6, 0x3d, 0x4b, 0x02, - 0x47, 0xee, 0x77, 0x15, 0x4a, 0xed, 0x77, 0x9d, 0xc5, 0x8d, 0x72, 0x5a, 0xe6, 0xb6, 0x99, 0x08, - 0x64, 0xa3, 0x2c, 0xe5, 0x54, 0xa3, 0x60, 0x2a, 0x2a, 0xcd, 0xa1, 0x54, 0x55, 0x51, 0xbf, 0x4e, - 0x9a, 0xda, 0xfd, 0x56, 0x56, 0xae, 0x88, 0xc8, 0xd2, 0xec, 0x60, 0x53, 0xa5, 0xd9, 0x69, 0x82, - 0x4b, 0xd3, 0x2d, 0xae, 0x7b, 0xa6, 0x05, 0x35, 0x55, 0x9a, 0x08, 0xc2, 0x4f, 0x91, 0xa7, 0x30, - 0x97, 0x16, 0xda, 0xec, 0x51, 0x03, 0x1d, 0x03, 0xa9, 0xa7, 0x48, 0xcc, 0x85, 0x10, 0x7f, 0xf7, - 0xd8, 0x07, 0x43, 0x2d, 0x9d, 0x56, 0x47, 0x3f, 0xcf, 0xa0, 0x3c, 0x12, 0xd5, 0x2c, 0xb3, 0x3f, - 0x2a, 0x4e, 0xe6, 0xa3, 0x03, 0xf6, 0xb1, 0x0f, 0x77, 0xb2, 0x89, 0xc6, 0x77, 0x2d, 0x0b, 0xd3, - 0xd2, 0x53, 0x7a, 0x7c, 0xaf, 0x40, 0xc9, 0xf1, 0xbd, 0xc6, 0x46, 0xf7, 0x10, 0xf8, 0xa2, 0xbc, - 0x43, 0xbf, 0xdb, 0xe3, 0x9c, 0xde, 0x4d, 0x43, 0xf8, 0x71, 0xe0, 0xe3, 0x8e, 0xc0, 0xb8, 0xe9, - 0x0e, 0x53, 0x9e, 0x5a, 0x5d, 0xa0, 0x52, 0x8f, 0x03, 0x02, 0x0e, 0x11, 0xff, 0xed, 0xb1, 0x0f, - 0xdd, 0x4d, 0x85, 0xfa, 0x6f, 0x50, 0x4e, 0xdd, 0xa8, 0x6b, 0x5e, 0x0b, 0x8f, 0x3b, 0x6e, 0xb6, - 0x0e, 0xde, 0x2f, 0xe3, 0x9b, 0x5d, 0xcd, 0x70, 0xd9, 0xe2, 0x13, 0x27, 0xcb, 0x16, 0x03, 0xa9, - 0xb2, 0x8d, 0xb9, 0x10, 0xe2, 0x07, 0x76, 0xe3, 0x89, 0x98, 0x5c, 0x56, 0x8a, 0x53, 0xff, 0x53, - 0x37, 0x92, 0x77, 0x7b, 0x3b, 0x41, 0x78, 0x87, 0x0f, 0x7b, 0x5c, 0xb3, 0x9b, 0x2e, 0xbb, 0x52, - 0xc3, 0x89, 0x96, 0xf3, 0xd6, 0x7b, 0xc7, 0xb0, 0x8b, 0xa9, 0xd4, 0xc1, 0x11, 0xf0, 0x32, 0xe6, - 0x93, 0xc3, 0x5f, 0x0e, 0x16, 0xb9, 0x05, 0x63, 0xf6, 0x73, 0xd9, 0x6f, 0xfe, 0xea, 0xcf, 0x64, - 0x7f, 0x61, 0xfb, 0xf5, 0x77, 0x8b, 0x3e, 0xf5, 0x95, 0xe3, 0xe2, 0x46, 0xad, 0x1d, 0xfe, 0x1f, - 0x00, 0x00, 0xff, 0xff, 0x2e, 0xeb, 0x66, 0x65, 0x20, 0x11, 0x00, 0x00, + proto.RegisterFile("tabletmanagerservice.proto", fileDescriptor_tabletmanagerservice_d0dfb5502bc9cb1c) +} + +var fileDescriptor_tabletmanagerservice_d0dfb5502bc9cb1c = []byte{ + // 1012 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x98, 0x5b, 0x6f, 0x1b, 0x45, + 0x14, 0xc7, 0xb1, 0x04, 0x95, 0x18, 0xae, 0x1d, 0x55, 0x14, 0x05, 0x89, 0x5b, 0x5a, 0x2e, 0x2d, + 0x8a, 0x9b, 0x86, 0xf2, 0xee, 0xa6, 0x49, 0x1b, 0xd4, 0x08, 0x63, 0x37, 0x04, 0x81, 0x84, 0x34, + 0xb1, 0x4f, 0xbc, 0x4b, 0xd6, 0x3b, 0xc3, 0xcc, 0xac, 0x95, 0x3c, 0x21, 0x21, 0xf1, 0x84, 0xc4, + 0x67, 0xe3, 0x23, 0xa1, 0xbd, 0xcc, 0xec, 0x19, 0xfb, 0xec, 0xd8, 0x7e, 0x8b, 0xfc, 0xff, 0x9d, + 0xcb, 0x9c, 0x39, 0x73, 0x66, 0xb2, 0x6c, 0xc7, 0x8a, 0x8b, 0x0c, 0xec, 0x5c, 0xe4, 0x62, 0x06, + 0xda, 0x80, 0x5e, 0xa4, 0x13, 0xd8, 0x53, 0x5a, 0x5a, 0xc9, 0xef, 0x50, 0xda, 0xce, 0xdd, 0xe0, + 0xd7, 0xa9, 0xb0, 0xa2, 0xc6, 0x1f, 0xff, 0xb7, 0xcb, 0xde, 0x79, 0x55, 0x69, 0xa7, 0xb5, 0xc6, + 0x4f, 0xd8, 0xeb, 0xc3, 0x34, 0x9f, 0xf1, 0x8f, 0xf7, 0x56, 0x6d, 0x4a, 0x61, 0x04, 0x7f, 0x14, + 0x60, 0xec, 0xce, 0x27, 0x9d, 0xba, 0x51, 0x32, 0x37, 0xf0, 0xf9, 0x6b, 0xfc, 0x25, 0x7b, 0x63, + 0x9c, 0x01, 0x28, 0x4e, 0xb1, 0x95, 0xe2, 0x9c, 0x7d, 0xda, 0x0d, 0x78, 0x6f, 0xbf, 0xb1, 0xb7, + 0x8e, 0xae, 0x61, 0x52, 0x58, 0x78, 0x21, 0xe5, 0x15, 0xbf, 0x4f, 0x98, 0x20, 0xdd, 0x79, 0xfe, + 0x62, 0x1d, 0xe6, 0xfd, 0xff, 0xcc, 0xde, 0x7c, 0x0e, 0x76, 0x3c, 0x49, 0x60, 0x2e, 0xf8, 0x2e, + 0x61, 0xe6, 0x55, 0xe7, 0xfb, 0x5e, 0x1c, 0xf2, 0x9e, 0x67, 0xec, 0xdd, 0xe7, 0x60, 0x87, 0xa0, + 0xe7, 0xa9, 0x31, 0xa9, 0xcc, 0x0d, 0xff, 0x8a, 0xb6, 0x44, 0x88, 0x8b, 0xf1, 0xf5, 0x06, 0x24, + 0x2e, 0xd1, 0x18, 0xec, 0x08, 0xc4, 0xf4, 0x87, 0x3c, 0xbb, 0x21, 0x4b, 0x84, 0xf4, 0x58, 0x89, + 0x02, 0xcc, 0xfb, 0x17, 0xec, 0xed, 0x46, 0x38, 0xd7, 0xa9, 0x05, 0x1e, 0xb1, 0xac, 0x00, 0x17, + 0xe1, 0xcb, 0xb5, 0x9c, 0x0f, 0xf1, 0x2b, 0x63, 0x87, 0x89, 0xc8, 0x67, 0xf0, 0xea, 0x46, 0x01, + 0xa7, 0x2a, 0xdc, 0xca, 0xce, 0xfd, 0xfd, 0x35, 0x14, 0xce, 0x7f, 0x04, 0x97, 0x1a, 0x4c, 0x32, + 0xb6, 0xa2, 0x23, 0x7f, 0x0c, 0xc4, 0xf2, 0x0f, 0x39, 0xbc, 0xd7, 0xa3, 0x22, 0x7f, 0x01, 0x22, + 0xb3, 0xc9, 0x61, 0x02, 0x93, 0x2b, 0x72, 0xaf, 0x43, 0x24, 0xb6, 0xd7, 0xcb, 0xa4, 0x0f, 0xa4, + 0xd8, 0xed, 0x93, 0x59, 0x2e, 0x35, 0xd4, 0xf2, 0x91, 0xd6, 0x52, 0xf3, 0x87, 0x84, 0x87, 0x15, + 0xca, 0x85, 0xfb, 0x66, 0x33, 0x38, 0xac, 0x5e, 0x26, 0xc5, 0xb4, 0x39, 0x23, 0x74, 0xf5, 0x5a, + 0x20, 0x5e, 0x3d, 0xcc, 0xf9, 0x10, 0xbf, 0xb3, 0xf7, 0x86, 0x1a, 0x2e, 0xb3, 0x74, 0x96, 0xb8, + 0x93, 0x48, 0x15, 0x65, 0x89, 0x71, 0x81, 0x1e, 0x6c, 0x82, 0xe2, 0xc3, 0x32, 0x50, 0x2a, 0xbb, + 0x69, 0xe2, 0x50, 0x4d, 0x84, 0xf4, 0xd8, 0x61, 0x09, 0x30, 0xdc, 0xc9, 0x2f, 0xe5, 0xe4, 0xaa, + 0x9a, 0xae, 0x86, 0xec, 0xe4, 0x56, 0x8e, 0x75, 0x32, 0xa6, 0xf0, 0x5e, 0x9c, 0xe5, 0x59, 0xeb, + 0x9e, 0x4a, 0x0b, 0x03, 0xb1, 0xbd, 0x08, 0x39, 0xdc, 0x60, 0xcd, 0xa0, 0x3c, 0x06, 0x3b, 0x49, + 0x06, 0xe6, 0xd9, 0x85, 0x20, 0x1b, 0x6c, 0x85, 0x8a, 0x35, 0x18, 0x01, 0xfb, 0x88, 0x7f, 0xb2, + 0x0f, 0x42, 0x79, 0x90, 0x65, 0x43, 0x9d, 0x2e, 0x0c, 0x7f, 0xb4, 0xd6, 0x93, 0x43, 0x5d, 0xec, + 0xfd, 0x2d, 0x2c, 0xba, 0x97, 0x3c, 0x50, 0x6a, 0x83, 0x25, 0x0f, 0x94, 0xda, 0x7c, 0xc9, 0x15, + 0x1c, 0x4c, 0xec, 0x4c, 0x2c, 0xa0, 0x1c, 0x23, 0x85, 0xa1, 0x27, 0x76, 0xab, 0x47, 0x27, 0x36, + 0xc6, 0xf0, 0x38, 0x3a, 0x15, 0xc6, 0x82, 0x1e, 0x4a, 0x93, 0xda, 0x54, 0xe6, 0xe4, 0x38, 0x0a, + 0x91, 0xd8, 0x38, 0x5a, 0x26, 0xf1, 0xed, 0x39, 0xb6, 0x52, 0x55, 0x59, 0x90, 0xb7, 0xa7, 0x57, + 0x63, 0xb7, 0x27, 0x82, 0xbc, 0xe7, 0x39, 0x7b, 0xdf, 0xff, 0x7c, 0x9a, 0xe6, 0xe9, 0xbc, 0x98, + 0xf3, 0x07, 0x31, 0xdb, 0x06, 0x72, 0x71, 0x1e, 0x6e, 0xc4, 0xe2, 0x63, 0x3b, 0xb6, 0x42, 0xdb, + 0x7a, 0x25, 0x74, 0x92, 0x4e, 0x8e, 0x1d, 0x5b, 0x4c, 0x79, 0xe7, 0x37, 0xec, 0x4e, 0xfb, 0xfb, + 0x59, 0x6e, 0xd3, 0x6c, 0x70, 0x69, 0x41, 0xf3, 0xbd, 0xa8, 0x83, 0x16, 0x74, 0x01, 0xfb, 0x1b, + 0xf3, 0x3e, 0xf4, 0x3f, 0x3d, 0xb6, 0x53, 0xbf, 0xf4, 0x8e, 0xae, 0x2d, 0xe8, 0x5c, 0x64, 0xe5, + 0xd5, 0xae, 0x84, 0x86, 0xdc, 0xc2, 0x94, 0x7f, 0x4b, 0x78, 0xec, 0xc6, 0x5d, 0x1e, 0x4f, 0xb6, + 0xb4, 0xf2, 0xd9, 0xfc, 0xd5, 0x63, 0x77, 0x97, 0xc1, 0xa3, 0x0c, 0x26, 0x65, 0x2a, 0xfb, 0x1b, + 0x38, 0x6d, 0x58, 0x97, 0xc7, 0xe3, 0x6d, 0x4c, 0x96, 0x5f, 0x7c, 0x65, 0xc9, 0x4c, 0xe7, 0x8b, + 0xaf, 0x52, 0xd7, 0xbd, 0xf8, 0x1a, 0x08, 0xf7, 0xec, 0x4f, 0x23, 0x50, 0x59, 0x3a, 0x11, 0xe5, + 0x39, 0x29, 0x27, 0x00, 0xd9, 0xb3, 0xcb, 0x50, 0xac, 0x67, 0x57, 0x59, 0x3c, 0x38, 0xb1, 0x7a, + 0x2e, 0x52, 0x7b, 0x2c, 0xcb, 0x53, 0x4a, 0x0e, 0x4e, 0x1a, 0x8d, 0x0d, 0xce, 0x2e, 0x0b, 0xbc, + 0xde, 0x11, 0x98, 0xf2, 0x45, 0xe7, 0x39, 0x72, 0xbd, 0xcb, 0x50, 0x6c, 0xbd, 0xab, 0x2c, 0x3e, + 0xa3, 0x27, 0x79, 0x6a, 0xeb, 0x61, 0x44, 0x9e, 0xd1, 0x56, 0x8e, 0x9d, 0x51, 0x4c, 0x05, 0xad, + 0x39, 0x94, 0xaa, 0xc8, 0xaa, 0x87, 0x5d, 0xdd, 0xbb, 0xdf, 0xcb, 0xa2, 0x6c, 0x22, 0xb2, 0x35, + 0x3b, 0xd8, 0x58, 0x6b, 0x76, 0x9a, 0xe0, 0xd6, 0x2c, 0x93, 0xeb, 0x1e, 0xa7, 0x5e, 0x8d, 0xb5, + 0x26, 0x82, 0xf0, 0xcb, 0xe1, 0x19, 0xcc, 0xa5, 0x85, 0xa6, 0x7a, 0xd4, 0x5d, 0x82, 0x81, 0xd8, + 0xcb, 0x21, 0xe4, 0x7c, 0x88, 0xbf, 0x7b, 0xec, 0xc3, 0xa1, 0x96, 0xa5, 0x56, 0x45, 0x3f, 0x4f, + 0x20, 0x3f, 0x14, 0xc5, 0x2c, 0xb1, 0x67, 0x8a, 0x93, 0xf5, 0xe8, 0x80, 0x5d, 0xec, 0x83, 0xad, + 0x6c, 0x82, 0x9b, 0xa3, 0x92, 0x85, 0x69, 0xe8, 0x29, 0x7d, 0x73, 0x2c, 0x41, 0xd1, 0x9b, 0x63, + 0x85, 0x0d, 0xae, 0x40, 0x70, 0x4d, 0xb9, 0x4b, 0xff, 0xcb, 0x13, 0xd6, 0xf4, 0x5e, 0x1c, 0xc2, + 0xef, 0x12, 0x17, 0x77, 0x04, 0xa6, 0x9c, 0xf3, 0x30, 0xe5, 0xb1, 0xec, 0x3c, 0x15, 0x7b, 0x97, + 0x10, 0xb0, 0x8f, 0xf8, 0x6f, 0x8f, 0x7d, 0x54, 0x5e, 0x92, 0xe8, 0xfc, 0x0d, 0xf2, 0x69, 0x39, + 0xea, 0xea, 0x87, 0xca, 0x93, 0x8e, 0x4b, 0xb5, 0x83, 0x77, 0x69, 0x7c, 0xb7, 0xad, 0x19, 0x6e, + 0x5b, 0xbc, 0xe3, 0x64, 0xdb, 0x62, 0x20, 0xd6, 0xb6, 0x21, 0xe7, 0x43, 0xfc, 0xc8, 0x6e, 0x3d, + 0x15, 0x93, 0xab, 0x42, 0x71, 0xea, 0x73, 0x44, 0x2d, 0x39, 0xb7, 0x9f, 0x45, 0x08, 0xe7, 0xf0, + 0x51, 0x8f, 0x6b, 0x76, 0xbb, 0xac, 0xae, 0xd4, 0x70, 0xac, 0xe5, 0xbc, 0xf1, 0xde, 0x31, 0xec, + 0x42, 0x2a, 0xb6, 0x71, 0x04, 0xdc, 0xc6, 0x7c, 0x7a, 0xf0, 0xcb, 0xfe, 0x22, 0xb5, 0x60, 0xcc, + 0x5e, 0x2a, 0xfb, 0xf5, 0x5f, 0xfd, 0x99, 0xec, 0x2f, 0x6c, 0xbf, 0xfa, 0xe4, 0xd3, 0xa7, 0x3e, + 0x10, 0x5d, 0xdc, 0xaa, 0xb4, 0x83, 0xff, 0x03, 0x00, 0x00, 0xff, 0xff, 0x6a, 0x46, 0xe6, 0xae, + 0x5b, 0x12, 0x00, 0x00, } diff --git a/go/vt/vtcombo/tablet_map.go b/go/vt/vtcombo/tablet_map.go index 0e6c79d254a..afda516f43f 100644 --- a/go/vt/vtcombo/tablet_map.go +++ b/go/vt/vtcombo/tablet_map.go @@ -315,9 +315,9 @@ func (itc *internalTabletConn) ExecuteBatch(ctx context.Context, target *querypb // StreamExecute is part of queryservice.QueryService // We need to copy the bind variables as tablet server will change them. -func (itc *internalTabletConn) StreamExecute(ctx context.Context, target *querypb.Target, query string, bindVars map[string]*querypb.BindVariable, options *querypb.ExecuteOptions, callback func(*sqltypes.Result) error) error { +func (itc *internalTabletConn) StreamExecute(ctx context.Context, target *querypb.Target, query string, bindVars map[string]*querypb.BindVariable, transactionID int64, options *querypb.ExecuteOptions, callback func(*sqltypes.Result) error) error { bindVars = sqltypes.CopyBindVariables(bindVars) - err := itc.tablet.qsc.QueryService().StreamExecute(ctx, target, query, bindVars, options, callback) + err := itc.tablet.qsc.QueryService().StreamExecute(ctx, target, query, bindVars, transactionID, options, callback) return tabletconn.ErrorFromGRPC(vterrors.ToGRPC(err)) } @@ -479,6 +479,14 @@ func (itc *internalTabletConn) UpdateStream(ctx context.Context, target *querypb // internalTabletManagerClient implements tmclient.TabletManagerClient type internalTabletManagerClient struct{} +func (itmc *internalTabletManagerClient) LockTables(ctx context.Context, tablet *topodatapb.Tablet) error { + return fmt.Errorf("not implemented in vtcombo") +} + +func (itmc *internalTabletManagerClient) UnlockTables(ctx context.Context, tablet *topodatapb.Tablet) error { + return fmt.Errorf("not implemented in vtcombo") +} + func (itmc *internalTabletManagerClient) Ping(ctx context.Context, tablet *topodatapb.Tablet) error { t, ok := tabletMap[tablet.Alias.Uid] if !ok { @@ -616,6 +624,10 @@ func (itmc *internalTabletManagerClient) StartSlave(ctx context.Context, tablet return fmt.Errorf("not implemented in vtcombo") } +func (itmc *internalTabletManagerClient) StartSlaveUntilAfter(ctx context.Context, tablet *topodatapb.Tablet, position string, duration time.Duration) error { + return fmt.Errorf("not implemented in vtcombo") +} + func (itmc *internalTabletManagerClient) TabletExternallyReparented(ctx context.Context, tablet *topodatapb.Tablet, externalID string) error { return fmt.Errorf("not implemented in vtcombo") } diff --git a/go/vt/vtgate/gateway/discoverygateway_test.go b/go/vt/vtgate/gateway/discoverygateway_test.go index 510a86d459c..f3e06462a63 100644 --- a/go/vt/vtgate/gateway/discoverygateway_test.go +++ b/go/vt/vtgate/gateway/discoverygateway_test.go @@ -59,7 +59,7 @@ func TestDiscoveryGatewayExecuteBatch(t *testing.T) { func TestDiscoveryGatewayExecuteStream(t *testing.T) { testDiscoveryGatewayGeneric(t, true, func(dg Gateway, target *querypb.Target) error { - err := dg.StreamExecute(context.Background(), target, "query", nil, nil, func(qr *sqltypes.Result) error { + err := dg.StreamExecute(context.Background(), target, "query", nil, 0, nil, func(qr *sqltypes.Result) error { return nil }) return err diff --git a/go/vt/vtgate/scatter_conn.go b/go/vt/vtgate/scatter_conn.go index 32283678d33..8c42c0fa26c 100644 --- a/go/vt/vtgate/scatter_conn.go +++ b/go/vt/vtgate/scatter_conn.go @@ -458,7 +458,7 @@ func (stc *ScatterConn) StreamExecute( fieldSent := false allErrors := stc.multiGo(ctx, "StreamExecute", rss, tabletType, func(rs *srvtopo.ResolvedShard, i int) error { - return rs.QueryService.StreamExecute(ctx, rs.Target, query, bindVars, options, func(qr *sqltypes.Result) error { + return rs.QueryService.StreamExecute(ctx, rs.Target, query, bindVars, 0, options, func(qr *sqltypes.Result) error { return stc.processOneStreamingResult(&mu, &fieldSent, qr, callback) }) }) @@ -484,7 +484,7 @@ func (stc *ScatterConn) StreamExecuteMulti( fieldSent := false allErrors := stc.multiGo(ctx, "StreamExecute", rss, tabletType, func(rs *srvtopo.ResolvedShard, i int) error { - return rs.QueryService.StreamExecute(ctx, rs.Target, query, bindVars[i], options, func(qr *sqltypes.Result) error { + return rs.QueryService.StreamExecute(ctx, rs.Target, query, bindVars[i], 0, options, func(qr *sqltypes.Result) error { return stc.processOneStreamingResult(&mu, &fieldSent, qr, callback) }) }) diff --git a/go/vt/vttablet/agentrpctest/test_agent_rpc.go b/go/vt/vttablet/agentrpctest/test_agent_rpc.go index 0bfa22d1e79..7039a216a46 100644 --- a/go/vt/vttablet/agentrpctest/test_agent_rpc.go +++ b/go/vt/vttablet/agentrpctest/test_agent_rpc.go @@ -52,6 +52,14 @@ type fakeRPCAgent struct { mu sync.Mutex } +func (fra *fakeRPCAgent) LockTables(ctx context.Context) error { + panic("implement me") +} + +func (fra *fakeRPCAgent) UnlockTables(ctx context.Context) error { + panic("implement me") +} + func (fra *fakeRPCAgent) setSlow(slow bool) { fra.mu.Lock() fra.slow = slow @@ -781,11 +789,26 @@ func (fra *fakeRPCAgent) StartSlave(ctx context.Context) error { return nil } +var testStartSlaveUntilAfterCalledWith = "" + +func (fra *fakeRPCAgent) StartSlaveUntilAfter(ctx context.Context, position string, waitTime time.Duration) error { + if fra.panics { + panic(fmt.Errorf("test-triggered panic")) + } + testStartSlaveUntilAfterCalledWith = position + return nil +} + func agentRPCTestStartSlave(ctx context.Context, t *testing.T, client tmclient.TabletManagerClient, tablet *topodatapb.Tablet) { err := client.StartSlave(ctx, tablet) compareError(t, "StartSlave", err, true, testStartSlaveCalled) } +func agentRPCTestStartSlaveUntilAfter(ctx context.Context, t *testing.T, client tmclient.TabletManagerClient, tablet *topodatapb.Tablet) { + err := client.StartSlaveUntilAfter(ctx, tablet, "test-position", time.Minute) + compareError(t, "StartSlaveUntilAfter", err, "test-position", testStartSlaveUntilAfterCalledWith) +} + func agentRPCTestStartSlavePanic(ctx context.Context, t *testing.T, client tmclient.TabletManagerClient, tablet *topodatapb.Tablet) { err := client.StartSlave(ctx, tablet) expectHandleRPCPanic(t, "StartSlave", true /*verbose*/, err) diff --git a/go/vt/vttablet/endtoend/framework/client.go b/go/vt/vttablet/endtoend/framework/client.go index 782304b1cc4..a590e08bad7 100644 --- a/go/vt/vttablet/endtoend/framework/client.go +++ b/go/vt/vttablet/endtoend/framework/client.go @@ -188,6 +188,7 @@ func (client *QueryClient) StreamExecuteWithOptions(query string, bindvars map[s &client.target, query, bindvars, + 0, options, func(res *sqltypes.Result) error { if result.Fields == nil { @@ -211,6 +212,7 @@ func (client *QueryClient) Stream(query string, bindvars map[string]*querypb.Bin &client.target, query, bindvars, + 0, &querypb.ExecuteOptions{IncludedFields: querypb.ExecuteOptions_ALL}, sendFunc, ) diff --git a/go/vt/vttablet/faketmclient/fake_client.go b/go/vt/vttablet/faketmclient/fake_client.go index 77b528d9930..5ce41a95adf 100644 --- a/go/vt/vttablet/faketmclient/fake_client.go +++ b/go/vt/vttablet/faketmclient/fake_client.go @@ -93,6 +93,16 @@ func (client *FakeTabletManagerClient) GetPermissions(ctx context.Context, table return &tabletmanagerdatapb.Permissions{}, nil } +// LockTables is part of the tmclient.TabletManagerClient interface. +func (client *FakeTabletManagerClient) LockTables(ctx context.Context, tablet *topodatapb.Tablet) error { + return nil +} + +// UnlockTables is part of the tmclient.TabletManagerClient interface. +func (client *FakeTabletManagerClient) UnlockTables(ctx context.Context, tablet *topodatapb.Tablet) error { + return nil +} + // // Various read-write methods // @@ -186,6 +196,11 @@ func (client *FakeTabletManagerClient) StartSlave(ctx context.Context, tablet *t return nil } +// StartSlaveUntilAfter is part of the tmclient.TabletManagerClient interface. +func (client *FakeTabletManagerClient) StartSlaveUntilAfter(ctx context.Context, tablet *topodatapb.Tablet, position string, duration time.Duration) error { + return nil +} + // TabletExternallyReparented is part of the tmclient.TabletManagerClient interface. func (client *FakeTabletManagerClient) TabletExternallyReparented(ctx context.Context, tablet *topodatapb.Tablet, externalID string) error { return nil diff --git a/go/vt/vttablet/grpcqueryservice/server.go b/go/vt/vttablet/grpcqueryservice/server.go index c3ada0faecf..0781c3bae21 100644 --- a/go/vt/vttablet/grpcqueryservice/server.go +++ b/go/vt/vttablet/grpcqueryservice/server.go @@ -75,7 +75,7 @@ func (q *query) StreamExecute(request *querypb.StreamExecuteRequest, stream quer request.EffectiveCallerId, request.ImmediateCallerId, ) - if err := q.server.StreamExecute(ctx, request.Target, request.Query.Sql, request.Query.BindVariables, request.Options, func(reply *sqltypes.Result) error { + if err := q.server.StreamExecute(ctx, request.Target, request.Query.Sql, request.Query.BindVariables, request.TransactionId, request.Options, func(reply *sqltypes.Result) error { return stream.Send(&querypb.StreamExecuteResponse{ Result: sqltypes.ResultToProto3(reply), }) diff --git a/go/vt/vttablet/grpctabletconn/conn.go b/go/vt/vttablet/grpctabletconn/conn.go index f4871b5a860..5de510ff06d 100644 --- a/go/vt/vttablet/grpctabletconn/conn.go +++ b/go/vt/vttablet/grpctabletconn/conn.go @@ -138,7 +138,7 @@ func (conn *gRPCQueryClient) ExecuteBatch(ctx context.Context, target *querypb.T } // StreamExecute executes the query and streams results back through callback. -func (conn *gRPCQueryClient) StreamExecute(ctx context.Context, target *querypb.Target, query string, bindVars map[string]*querypb.BindVariable, options *querypb.ExecuteOptions, callback func(*sqltypes.Result) error) error { +func (conn *gRPCQueryClient) StreamExecute(ctx context.Context, target *querypb.Target, query string, bindVars map[string]*querypb.BindVariable, transactionID int64, options *querypb.ExecuteOptions, callback func(*sqltypes.Result) error) error { // All streaming clients should follow the code pattern below. // The first part of the function starts the stream while holding // a lock on conn.mu. The second part receives the data and calls @@ -165,7 +165,8 @@ func (conn *gRPCQueryClient) StreamExecute(ctx context.Context, target *querypb. Sql: query, BindVariables: bindVars, }, - Options: options, + Options: options, + TransactionId: transactionID, } stream, err := conn.c.StreamExecute(ctx, req) if err != nil { diff --git a/go/vt/vttablet/grpctmclient/client.go b/go/vt/vttablet/grpctmclient/client.go index 0a0232c51b0..7b83101e1be 100644 --- a/go/vt/vttablet/grpctmclient/client.go +++ b/go/vt/vttablet/grpctmclient/client.go @@ -344,6 +344,30 @@ func (client *Client) ApplySchema(ctx context.Context, tablet *topodatapb.Tablet }, nil } +// LockTables is part of the tmclient.TabletManagerClient interface. +func (client *Client) LockTables(ctx context.Context, tablet *topodatapb.Tablet) error { + cc, c, err := client.dial(tablet) + if err != nil { + return err + } + defer cc.Close() + + _, err = c.LockTables(ctx, &tabletmanagerdatapb.LockTablesRequest{}) + return err +} + +// UnlockTables is part of the tmclient.TabletManagerClient interface. +func (client *Client) UnlockTables(ctx context.Context, tablet *topodatapb.Tablet) error { + cc, c, err := client.dial(tablet) + if err != nil { + return err + } + defer cc.Close() + + _, err = c.UnlockTables(ctx, &tabletmanagerdatapb.UnlockTablesRequest{}) + return err +} + // ExecuteFetchAsDba is part of the tmclient.TabletManagerClient interface. func (client *Client) ExecuteFetchAsDba(ctx context.Context, tablet *topodatapb.Tablet, usePool bool, query []byte, maxRows int, disableBinlogs, reloadSchema bool) (*querypb.QueryResult, error) { var c tabletmanagerservicepb.TabletManagerClient @@ -497,6 +521,20 @@ func (client *Client) StartSlave(ctx context.Context, tablet *topodatapb.Tablet) return err } +// StartSlaveUntilAfter is part of the tmclient.TabletManagerClient interface. +func (client *Client) StartSlaveUntilAfter(ctx context.Context, tablet *topodatapb.Tablet, position string, waitTime time.Duration) error { + cc, c, err := client.dial(tablet) + if err != nil { + return err + } + defer cc.Close() + _, err = c.StartSlaveUntilAfter(ctx, &tabletmanagerdatapb.StartSlaveUntilAfterRequest{ + Position: position, + WaitTimeout: int64(waitTime), + }) + return err +} + // TabletExternallyReparented is part of the tmclient.TabletManagerClient interface. func (client *Client) TabletExternallyReparented(ctx context.Context, tablet *topodatapb.Tablet, externalID string) error { cc, c, err := client.dial(tablet) diff --git a/go/vt/vttablet/grpctmserver/server.go b/go/vt/vttablet/grpctmserver/server.go index 7054c37b721..bba4157a885 100644 --- a/go/vt/vttablet/grpctmserver/server.go +++ b/go/vt/vttablet/grpctmserver/server.go @@ -178,6 +178,22 @@ func (s *server) ApplySchema(ctx context.Context, request *tabletmanagerdatapb.A return response, err } +func (s *server) LockTables(ctx context.Context, req *tabletmanagerdatapb.LockTablesRequest) (*tabletmanagerdatapb.LockTablesResponse, error) { + err := s.agent.LockTables(ctx) + if err != nil { + return nil, err + } + return &tabletmanagerdatapb.LockTablesResponse{}, nil +} + +func (s *server) UnlockTables(ctx context.Context, req *tabletmanagerdatapb.UnlockTablesRequest) (*tabletmanagerdatapb.UnlockTablesResponse, error) { + err := s.agent.UnlockTables(ctx) + if err != nil { + return nil, err + } + return &tabletmanagerdatapb.UnlockTablesResponse{}, nil +} + func (s *server) ExecuteFetchAsDba(ctx context.Context, request *tabletmanagerdatapb.ExecuteFetchAsDbaRequest) (response *tabletmanagerdatapb.ExecuteFetchAsDbaResponse, err error) { defer s.agent.HandleRPCPanic(ctx, "ExecuteFetchAsDba", request, response, false /*verbose*/, &err) ctx = callinfo.GRPCCallInfo(ctx) @@ -265,6 +281,13 @@ func (s *server) StartSlave(ctx context.Context, request *tabletmanagerdatapb.St return response, s.agent.StartSlave(ctx) } +func (s *server) StartSlaveUntilAfter(ctx context.Context, request *tabletmanagerdatapb.StartSlaveUntilAfterRequest) (response *tabletmanagerdatapb.StartSlaveUntilAfterResponse, err error) { + defer s.agent.HandleRPCPanic(ctx, "StartSlave", request, response, true /*verbose*/, &err) + ctx = callinfo.GRPCCallInfo(ctx) + response = &tabletmanagerdatapb.StartSlaveUntilAfterResponse{} + return response, s.agent.StartSlaveUntilAfter(ctx, request.Position, time.Duration(request.WaitTimeout)) +} + func (s *server) TabletExternallyReparented(ctx context.Context, request *tabletmanagerdatapb.TabletExternallyReparentedRequest) (response *tabletmanagerdatapb.TabletExternallyReparentedResponse, err error) { defer s.agent.HandleRPCPanic(ctx, "TabletExternallyReparented", request, response, false /*verbose*/, &err) ctx = callinfo.GRPCCallInfo(ctx) diff --git a/go/vt/vttablet/queryservice/queryservice.go b/go/vt/vttablet/queryservice/queryservice.go index 225912ab26f..ecff428d518 100644 --- a/go/vt/vttablet/queryservice/queryservice.go +++ b/go/vt/vttablet/queryservice/queryservice.go @@ -77,7 +77,7 @@ type QueryService interface { // Query execution Execute(ctx context.Context, target *querypb.Target, sql string, bindVariables map[string]*querypb.BindVariable, transactionID int64, options *querypb.ExecuteOptions) (*sqltypes.Result, error) - StreamExecute(ctx context.Context, target *querypb.Target, sql string, bindVariables map[string]*querypb.BindVariable, options *querypb.ExecuteOptions, callback func(*sqltypes.Result) error) error + StreamExecute(ctx context.Context, target *querypb.Target, sql string, bindVariables map[string]*querypb.BindVariable, transactionID int64, options *querypb.ExecuteOptions, callback func(*sqltypes.Result) error) error ExecuteBatch(ctx context.Context, target *querypb.Target, queries []*querypb.BoundQuery, asTransaction bool, transactionID int64, options *querypb.ExecuteOptions) ([]sqltypes.Result, error) // Combo methods, they also return the transactionID from the @@ -133,7 +133,30 @@ func ExecuteWithStreamer(ctx context.Context, conn QueryService, target *querypb } go func() { defer close(rs.done) - rs.err = conn.StreamExecute(ctx, target, sql, bindVariables, options, func(qr *sqltypes.Result) error { + rs.err = conn.StreamExecute(ctx, target, sql, bindVariables, 0, options, func(qr *sqltypes.Result) error { + select { + case <-ctx.Done(): + return io.EOF + case rs.ch <- qr: + } + return nil + }) + if rs.err == nil { + rs.err = io.EOF + } + }() + return rs +} + +// ExecuteWithTransactionalStreamer does the same thing as ExecuteWithStreamer, but inside a transaction +func ExecuteWithTransactionalStreamer(ctx context.Context, conn QueryService, target *querypb.Target, sql string, bindVariables map[string]*querypb.BindVariable, transactionID int64, options *querypb.ExecuteOptions) sqltypes.ResultStream { + rs := &resultStreamer{ + done: make(chan struct{}), + ch: make(chan *sqltypes.Result), + } + go func() { + defer close(rs.done) + rs.err = conn.StreamExecute(ctx, target, sql, bindVariables, transactionID, options, func(qr *sqltypes.Result) error { select { case <-ctx.Done(): return io.EOF diff --git a/go/vt/vttablet/queryservice/wrapped.go b/go/vt/vttablet/queryservice/wrapped.go index 0ba474dff63..1d9dbe692bc 100644 --- a/go/vt/vttablet/queryservice/wrapped.go +++ b/go/vt/vttablet/queryservice/wrapped.go @@ -175,10 +175,10 @@ func (ws *wrappedService) Execute(ctx context.Context, target *querypb.Target, q return qr, err } -func (ws *wrappedService) StreamExecute(ctx context.Context, target *querypb.Target, query string, bindVars map[string]*querypb.BindVariable, options *querypb.ExecuteOptions, callback func(*sqltypes.Result) error) error { +func (ws *wrappedService) StreamExecute(ctx context.Context, target *querypb.Target, query string, bindVars map[string]*querypb.BindVariable, transactionID int64, options *querypb.ExecuteOptions, callback func(*sqltypes.Result) error) error { return ws.wrapper(ctx, target, ws.impl, "StreamExecute", false, func(ctx context.Context, target *querypb.Target, conn QueryService) (error, bool) { streamingStarted := false - innerErr := conn.StreamExecute(ctx, target, query, bindVars, options, func(qr *sqltypes.Result) error { + innerErr := conn.StreamExecute(ctx, target, query, bindVars, transactionID, options, func(qr *sqltypes.Result) error { streamingStarted = true return callback(qr) }) diff --git a/go/vt/vttablet/sandboxconn/sandboxconn.go b/go/vt/vttablet/sandboxconn/sandboxconn.go index dc614c7d2be..8c4ebbbca11 100644 --- a/go/vt/vttablet/sandboxconn/sandboxconn.go +++ b/go/vt/vttablet/sandboxconn/sandboxconn.go @@ -152,7 +152,7 @@ func (sbc *SandboxConn) ExecuteBatch(ctx context.Context, target *querypb.Target } // StreamExecute is part of the QueryService interface. -func (sbc *SandboxConn) StreamExecute(ctx context.Context, target *querypb.Target, query string, bindVars map[string]*querypb.BindVariable, options *querypb.ExecuteOptions, callback func(*sqltypes.Result) error) error { +func (sbc *SandboxConn) StreamExecute(ctx context.Context, target *querypb.Target, query string, bindVars map[string]*querypb.BindVariable, transactionID int64, options *querypb.ExecuteOptions, callback func(*sqltypes.Result) error) error { sbc.ExecCount.Add(1) bv := make(map[string]*querypb.BindVariable) for k, v := range bindVars { diff --git a/go/vt/vttablet/tabletconntest/fakequeryservice.go b/go/vt/vttablet/tabletconntest/fakequeryservice.go index 813a48efd3a..f6654cf21ac 100644 --- a/go/vt/vttablet/tabletconntest/fakequeryservice.go +++ b/go/vt/vttablet/tabletconntest/fakequeryservice.go @@ -457,7 +457,7 @@ var StreamExecuteQueryResult2 = sqltypes.Result{ } // StreamExecute is part of the queryservice.QueryService interface -func (f *FakeQueryService) StreamExecute(ctx context.Context, target *querypb.Target, sql string, bindVariables map[string]*querypb.BindVariable, options *querypb.ExecuteOptions, callback func(*sqltypes.Result) error) error { +func (f *FakeQueryService) StreamExecute(ctx context.Context, target *querypb.Target, sql string, bindVariables map[string]*querypb.BindVariable, transactionID int64, options *querypb.ExecuteOptions, callback func(*sqltypes.Result) error) error { if f.Panics && f.StreamExecutePanicsEarly { panic(fmt.Errorf("test-triggered panic early")) } diff --git a/go/vt/vttablet/tabletconntest/tabletconntest.go b/go/vt/vttablet/tabletconntest/tabletconntest.go index 6fb78fa7529..8b25182816e 100644 --- a/go/vt/vttablet/tabletconntest/tabletconntest.go +++ b/go/vt/vttablet/tabletconntest/tabletconntest.go @@ -479,7 +479,7 @@ func testStreamExecute(t *testing.T, conn queryservice.QueryService, f *FakeQuer ctx := context.Background() ctx = callerid.NewContext(ctx, TestCallerID, TestVTGateCallerID) i := 0 - err := conn.StreamExecute(ctx, TestTarget, StreamExecuteQuery, StreamExecuteBindVars, TestExecuteOptions, func(qr *sqltypes.Result) error { + err := conn.StreamExecute(ctx, TestTarget, StreamExecuteQuery, StreamExecuteBindVars, 0, TestExecuteOptions, func(qr *sqltypes.Result) error { switch i { case 0: if len(qr.Rows) == 0 { @@ -515,7 +515,7 @@ func testStreamExecuteError(t *testing.T, conn queryservice.QueryService, f *Fak testErrorHelper(t, f, "StreamExecute", func(ctx context.Context) error { f.ErrorWait = make(chan struct{}) ctx = callerid.NewContext(ctx, TestCallerID, TestVTGateCallerID) - return conn.StreamExecute(ctx, TestTarget, StreamExecuteQuery, StreamExecuteBindVars, TestExecuteOptions, func(qr *sqltypes.Result) error { + return conn.StreamExecute(ctx, TestTarget, StreamExecuteQuery, StreamExecuteBindVars, 0, TestExecuteOptions, func(qr *sqltypes.Result) error { // For some errors, the call can be retried. select { case <-f.ErrorWait: @@ -544,7 +544,7 @@ func testStreamExecutePanics(t *testing.T, conn queryservice.QueryService, f *Fa f.StreamExecutePanicsEarly = true testPanicHelper(t, f, "StreamExecute.Early", func(ctx context.Context) error { ctx = callerid.NewContext(ctx, TestCallerID, TestVTGateCallerID) - return conn.StreamExecute(ctx, TestTarget, StreamExecuteQuery, StreamExecuteBindVars, TestExecuteOptions, func(qr *sqltypes.Result) error { + return conn.StreamExecute(ctx, TestTarget, StreamExecuteQuery, StreamExecuteBindVars, 0, TestExecuteOptions, func(qr *sqltypes.Result) error { return nil }) }) @@ -554,7 +554,7 @@ func testStreamExecutePanics(t *testing.T, conn queryservice.QueryService, f *Fa testPanicHelper(t, f, "StreamExecute.Late", func(ctx context.Context) error { f.PanicWait = make(chan struct{}) ctx = callerid.NewContext(ctx, TestCallerID, TestVTGateCallerID) - return conn.StreamExecute(ctx, TestTarget, StreamExecuteQuery, StreamExecuteBindVars, TestExecuteOptions, func(qr *sqltypes.Result) error { + return conn.StreamExecute(ctx, TestTarget, StreamExecuteQuery, StreamExecuteBindVars, 0, TestExecuteOptions, func(qr *sqltypes.Result) error { // For some errors, the call can be retried. select { case <-f.PanicWait: diff --git a/go/vt/vttablet/tabletmanager/action_agent.go b/go/vt/vttablet/tabletmanager/action_agent.go index d2673b48a76..2663fe4ac10 100644 --- a/go/vt/vttablet/tabletmanager/action_agent.go +++ b/go/vt/vttablet/tabletmanager/action_agent.go @@ -47,6 +47,7 @@ import ( "vitess.io/vitess/go/vt/vterrors" "golang.org/x/net/context" + "vitess.io/vitess/go/vt/dbconnpool" "github.com/golang/protobuf/proto" "vitess.io/vitess/go/history" @@ -204,6 +205,11 @@ type ActionAgent struct { // _slaveStopped remembers if we've been told to stop replicating. // If it's nil, we'll try to check for the slaveStoppedFile. _slaveStopped *bool + + // _lockTablesConnection is used to get and release the table read locks to pause replication + _lockTablesConnection *dbconnpool.DBConnection + _lockTablesTimer *time.Timer + _lockTablesTimeout *time.Duration } // NewActionAgent creates a new ActionAgent and registers all the diff --git a/go/vt/vttablet/tabletmanager/rpc_agent.go b/go/vt/vttablet/tabletmanager/rpc_agent.go index 04f956afdfd..1bef381a7e8 100644 --- a/go/vt/vttablet/tabletmanager/rpc_agent.go +++ b/go/vt/vttablet/tabletmanager/rpc_agent.go @@ -66,6 +66,10 @@ type RPCAgent interface { ApplySchema(ctx context.Context, change *tmutils.SchemaChange) (*tabletmanagerdatapb.SchemaChangeResult, error) + LockTables(ctx context.Context) error + + UnlockTables(ctx context.Context) error + ExecuteFetchAsDba(ctx context.Context, query []byte, dbName string, maxrows int, disableBinlogs bool, reloadSchema bool) (*querypb.QueryResult, error) ExecuteFetchAsAllPrivs(ctx context.Context, query []byte, dbName string, maxrows int, reloadSchema bool) (*querypb.QueryResult, error) @@ -84,6 +88,8 @@ type RPCAgent interface { StartSlave(ctx context.Context) error + StartSlaveUntilAfter(ctx context.Context, position string, waitTime time.Duration) error + TabletExternallyReparented(ctx context.Context, externalID string) error GetSlaves(ctx context.Context) ([]string, error) diff --git a/go/vt/vttablet/tabletmanager/rpc_lock_tables.go b/go/vt/vttablet/tabletmanager/rpc_lock_tables.go new file mode 100644 index 00000000000..66fda083959 --- /dev/null +++ b/go/vt/vttablet/tabletmanager/rpc_lock_tables.go @@ -0,0 +1,144 @@ +/* +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 tabletmanager + +import ( + "errors" + "flag" + "fmt" + "strings" + "time" + + "vitess.io/vitess/go/vt/dbconnpool" + + "github.com/golang/glog" + "vitess.io/vitess/go/sqlescape" + + "golang.org/x/net/context" +) + +var ( + lockTablesTimeout = flag.Duration("lock_tables_timeout", 1*time.Minute, "How long to keep the table locked before timing out") +) + +// LockTables will lock all tables with read locks, effectively pausing replication while the lock is held (idempotent) +func (agent *ActionAgent) LockTables(ctx context.Context) error { + // get a connection + agent.mutex.Lock() + defer agent.mutex.Unlock() + + if agent._lockTablesConnection != nil { + // tables are already locked, bail out + return errors.New("tables already locked on this tablet") + } + + conn, err := agent.MysqlDaemon.GetDbaConnection() + if err != nil { + return err + } + + // FTWRL is preferable, so we'll try that first + _, err = conn.ExecuteFetch("FLUSH TABLES WITH READ LOCK", 0, false) + if err != nil { + // as fall back, we can lock each individual table as well. + // this requires slightly less privileges but achieves the same effect + err = agent.lockTablesUsingLockTables(conn) + if err != nil { + return err + } + } + glog.Infof("[%v] Tables locked", conn.ConnectionID) + + agent._lockTablesConnection = conn + agent._lockTablesTimer = time.AfterFunc(*lockTablesTimeout, func() { + // Here we'll sleep until the timeout time has elapsed. + // If the table locks have not been released yet, we'll release them here + agent.mutex.Lock() + defer agent.mutex.Unlock() + + // We need the mutex locked before we check this field + if agent._lockTablesConnection == conn { + glog.Errorf("table lock timed out and released the lock - something went wrong") + err = agent.unlockTablesHoldingMutex() + if err != nil { + glog.Errorf("failed to unlock tables: %v", err) + } + } + }) + + return nil +} + +func (agent *ActionAgent) lockTablesUsingLockTables(conn *dbconnpool.DBConnection) error { + glog.Warningf("failed to lock tables with FTWRL - falling back to LOCK TABLES") + + // Ensure schema engine is Open. If vttablet came up in a non_serving role, + // the schema engine may not have been initialized. Open() is idempotent, so this + // is always safe + se := agent.QueryServiceControl.SchemaEngine() + if err := se.Open(); err != nil { + return err + } + + tables := se.GetSchema() + tableNames := make([]string, 0, len(tables)) + for name := range tables { + if name == "dual" { + continue + } + tableNames = append(tableNames, fmt.Sprintf("%s READ", sqlescape.EscapeID(name))) + } + lockStatement := fmt.Sprintf("LOCK TABLES %v", strings.Join(tableNames, ", ")) + _, err := conn.ExecuteFetch(fmt.Sprintf("USE %s", agent.DBConfigs.DBName.Get()), 0, false) + if err != nil { + return err + } + + _, err = conn.ExecuteFetch(lockStatement, 0, false) + if err != nil { + return err + } + + return nil +} + +// UnlockTables will unlock all tables (idempotent) +func (agent *ActionAgent) UnlockTables(ctx context.Context) error { + agent.mutex.Lock() + defer agent.mutex.Unlock() + + if agent._lockTablesConnection == nil { + return fmt.Errorf("tables were not locked") + } + + return agent.unlockTablesHoldingMutex() +} + +func (agent *ActionAgent) unlockTablesHoldingMutex() error { + // We are cleaning up manually, let's kill the timer + agent._lockTablesTimer.Stop() + _, err := agent._lockTablesConnection.ExecuteFetch("UNLOCK TABLES", 0, false) + if err != nil { + return err + } + glog.Infof("[%v] Tables unlocked", agent._lockTablesConnection.ConnectionID) + agent._lockTablesConnection.Close() + agent._lockTablesConnection = nil + agent._lockTablesTimer = nil + + return nil +} diff --git a/go/vt/vttablet/tabletmanager/rpc_replication.go b/go/vt/vttablet/tabletmanager/rpc_replication.go index f11d2875bd1..4b255b68632 100644 --- a/go/vt/vttablet/tabletmanager/rpc_replication.go +++ b/go/vt/vttablet/tabletmanager/rpc_replication.go @@ -144,6 +144,25 @@ func (agent *ActionAgent) StartSlave(ctx context.Context) error { return agent.MysqlDaemon.StartSlave(agent.hookExtraEnv()) } +// StartSlaveUntilAfter will start the replication and let it catch up +// until and including the transactions in `position` +func (agent *ActionAgent) StartSlaveUntilAfter(ctx context.Context, position string, waitTime time.Duration) error { + if err := agent.lock(ctx); err != nil { + return err + } + defer agent.unlock() + + waitCtx, cancel := context.WithTimeout(ctx, waitTime) + defer cancel() + + pos, err := mysql.DecodePosition(position) + if err != nil { + return err + } + + return agent.MysqlDaemon.StartSlaveUntilAfter(waitCtx, pos) +} + // GetSlaves returns the address of all the slaves func (agent *ActionAgent) GetSlaves(ctx context.Context) ([]string, error) { return mysqlctl.FindSlaves(agent.MysqlDaemon) diff --git a/go/vt/vttablet/tabletserver/connpool/pool.go b/go/vt/vttablet/tabletserver/connpool/pool.go index 7c96b1dd642..02272c1aaec 100644 --- a/go/vt/vttablet/tabletserver/connpool/pool.go +++ b/go/vt/vttablet/tabletserver/connpool/pool.go @@ -277,9 +277,9 @@ func (cp *Pool) IdleClosed() int64 { } func (cp *Pool) isCallerIDAppDebug(ctx context.Context) bool { - callerID := callerid.ImmediateCallerIDFromContext(ctx) - if cp.appDebugParams.Uname == "" { + if cp.appDebugParams == nil || cp.appDebugParams.Uname == "" { return false } + callerID := callerid.ImmediateCallerIDFromContext(ctx) return callerID != nil && callerID.Username == cp.appDebugParams.Uname } diff --git a/go/vt/vttablet/tabletserver/query_executor.go b/go/vt/vttablet/tabletserver/query_executor.go index bf4e103aec5..28b9c42eeec 100644 --- a/go/vt/vttablet/tabletserver/query_executor.go +++ b/go/vt/vttablet/tabletserver/query_executor.go @@ -209,11 +209,23 @@ func (qre *QueryExecutor) Stream(callback func(*sqltypes.Result) error) error { return err } - conn, err := qre.getStreamConn() - if err != nil { - return err + // if we have a transaction id, let's use the txPool for this query + var conn *connpool.DBConn + if qre.transactionID != 0 { + txConn, err := qre.tsv.te.txPool.Get(qre.transactionID, "for streaming query") + if err != nil { + return err + } + defer txConn.Recycle() + conn = txConn.DBConn + } else { + dbConn, err := qre.getStreamConn() + if err != nil { + return err + } + defer dbConn.Recycle() + conn = dbConn } - defer conn.Recycle() qd := NewQueryDetail(qre.logStats.Ctx, conn) qre.tsv.qe.streamQList.Add(qd) diff --git a/go/vt/vttablet/tabletserver/tabletserver.go b/go/vt/vttablet/tabletserver/tabletserver.go index 51b7c0bf907..b2967837c43 100644 --- a/go/vt/vttablet/tabletserver/tabletserver.go +++ b/go/vt/vttablet/tabletserver/tabletserver.go @@ -158,7 +158,6 @@ type TabletServer struct { target querypb.Target alsoAllow []topodatapb.TabletType requests sync.WaitGroup - beginRequests sync.WaitGroup // The following variables should be initialized only once // before starting the tabletserver. @@ -169,6 +168,7 @@ type TabletServer struct { se *schema.Engine qe *QueryEngine te *TxEngine + teCtrl TxPoolController hw *heartbeat.Writer hr *heartbeat.Reader messager *messager.Engine @@ -212,6 +212,43 @@ func NewServer(topoServer *topo.Server, alias topodatapb.TabletAlias) *TabletSer return NewTabletServer(tabletenv.Config, topoServer, alias) } +// TxPoolController is how the tablet server interacts with the tx-pool. +// It is responsible for keeping it's own state - knowing when different types +// of transactions are allowed, and how to do state transitions. +type TxPoolController interface { + // Stop will stop accepting any new transactions. Transactions are immediately aborted. + Stop() error + + // Will start accepting all transactions. If transitioning from RO mode, transactions + // might need to be rolled back before new transactions can be accepts. + AcceptReadWrite() error + + // Will start accepting read-only transactions, but not full read and write transactions. + // If the engine is currently accepting full read and write transactions, they need to + // given a chance to clean up before they are forcefully rolled back. + AcceptReadOnly() error + + // InitDBConfig must be called before Init. + InitDBConfig(dbcfgs *dbconfigs.DBConfigs) + + // Init must be called once when vttablet starts for setting + // up the metadata tables. + Init() error + + // StopGently will change the state to NotServing but first wait for transactions to wrap up + StopGently() + + // Begin begins a transaction, and returns the associated transaction id. + // Subsequent statements can access the connection through the transaction id. + Begin(ctx context.Context, options *querypb.ExecuteOptions) (int64, error) + + // Commit commits the specified transaction. + Commit(ctx context.Context, transactionID int64, mc messageCommitter) error + + // Rollback rolls back the specified transaction. + Rollback(ctx context.Context, transactionID int64) error +} + var tsOnce sync.Once var srvTopoServer srvtopo.Server @@ -238,6 +275,7 @@ func NewTabletServer(config tabletenv.TabletConfig, topoServer *topo.Server, ali tsv.se = schema.NewEngine(tsv, config) tsv.qe = NewQueryEngine(tsv, tsv.se, config) tsv.te = NewTxEngine(tsv, config) + tsv.teCtrl = tsv.te tsv.hw = heartbeat.NewWriter(tsv, alias, config) tsv.hr = heartbeat.NewReader(tsv, config) tsv.txThrottler = txthrottler.CreateTxThrottlerFromTabletConfig(topoServer) @@ -351,7 +389,7 @@ func (tsv *TabletServer) InitDBConfig(target querypb.Target, dbcfgs *dbconfigs.D tsv.se.InitDBConfig(tsv.dbconfigs) tsv.qe.InitDBConfig(tsv.dbconfigs) - tsv.te.InitDBConfig(tsv.dbconfigs) + tsv.teCtrl.InitDBConfig(tsv.dbconfigs) tsv.hw.InitDBConfig(tsv.dbconfigs) tsv.hr.InitDBConfig(tsv.dbconfigs) tsv.messager.InitDBConfig(tsv.dbconfigs) @@ -513,7 +551,7 @@ func (tsv *TabletServer) fullStart() (err error) { if err := tsv.qe.Open(); err != nil { return err } - if err := tsv.te.Init(); err != nil { + if err := tsv.teCtrl.Init(); err != nil { return err } if err := tsv.hw.Init(tsv.target); err != nil { @@ -526,28 +564,25 @@ func (tsv *TabletServer) fullStart() (err error) { } func (tsv *TabletServer) serveNewType() (err error) { + // Wait for in-flight transactional requests to complete + // before rolling back everything. In this state new + // transactional requests are not allowed. So, we can + // be sure that the tx pool won't change after the wait. if tsv.target.TabletType == topodatapb.TabletType_MASTER { + tsv.teCtrl.AcceptReadWrite() if err := tsv.txThrottler.Open(tsv.target.Keyspace, tsv.target.Shard); err != nil { return err } tsv.watcher.Close() - tsv.te.Open() tsv.messager.Open() tsv.hr.Close() tsv.hw.Open() } else { + tsv.teCtrl.AcceptReadOnly() tsv.messager.Close() tsv.hr.Open() tsv.hw.Close() - - // Wait for in-flight transactional requests to complete - // before rolling back everything. In this state new - // transactional requests are not allowed. So, we can - // be sure that the tx pool won't change after the wait. - tsv.beginRequests.Wait() - tsv.te.Close(true) tsv.watcher.Open() - tsv.txThrottler.Close() // Reset the sequences. tsv.se.MakeNonMaster() @@ -597,9 +632,8 @@ func (tsv *TabletServer) waitForShutdown() { // we have the assurance that only non-begin transactional calls // will be allowed. They will enable the conclusion of outstanding // transactions. - tsv.beginRequests.Wait() tsv.messager.Close() - tsv.te.Close(false) + tsv.teCtrl.StopGently() tsv.qe.streamQList.TerminateAll() tsv.updateStreamList.Stop() tsv.watcher.Close() @@ -613,7 +647,7 @@ func (tsv *TabletServer) closeAll() { tsv.messager.Close() tsv.hr.Close() tsv.hw.Close() - tsv.te.Close(true) + tsv.teCtrl.StopGently() tsv.watcher.Close() tsv.updateStreamList.Stop() tsv.qe.Close() @@ -745,7 +779,7 @@ func (tsv *TabletServer) Begin(ctx context.Context, target *querypb.Target, opti // TODO(erez): I think this should be RESOURCE_EXHAUSTED. return vterrors.Errorf(vtrpcpb.Code_UNAVAILABLE, "Transaction throttled") } - transactionID, err = tsv.te.txPool.Begin(ctx, options) + transactionID, err = tsv.teCtrl.Begin(ctx, options) logStats.TransactionID = transactionID return err }, @@ -762,7 +796,7 @@ func (tsv *TabletServer) Commit(ctx context.Context, target *querypb.Target, tra func(ctx context.Context, logStats *tabletenv.LogStats) error { defer tabletenv.QueryStats.Record("COMMIT", time.Now()) logStats.TransactionID = transactionID - return tsv.te.txPool.Commit(ctx, transactionID, tsv.messager) + return tsv.teCtrl.Commit(ctx, transactionID, tsv.messager) }, ) } @@ -776,7 +810,7 @@ func (tsv *TabletServer) Rollback(ctx context.Context, target *querypb.Target, t func(ctx context.Context, logStats *tabletenv.LogStats) error { defer tabletenv.QueryStats.Record("ROLLBACK", time.Now()) logStats.TransactionID = transactionID - return tsv.te.txPool.Rollback(ctx, transactionID) + return tsv.teCtrl.Rollback(ctx, transactionID) }, ) } @@ -973,7 +1007,7 @@ func (tsv *TabletServer) Execute(ctx context.Context, target *querypb.Target, sq // StreamExecute executes the query and streams the result. // The first QueryResult will have Fields set (and Rows nil). // The subsequent QueryResult will have Rows set (and Fields nil). -func (tsv *TabletServer) StreamExecute(ctx context.Context, target *querypb.Target, sql string, bindVariables map[string]*querypb.BindVariable, options *querypb.ExecuteOptions, callback func(*sqltypes.Result) error) (err error) { +func (tsv *TabletServer) StreamExecute(ctx context.Context, target *querypb.Target, sql string, bindVariables map[string]*querypb.BindVariable, transactionID int64, options *querypb.ExecuteOptions, callback func(*sqltypes.Result) error) (err error) { return tsv.execRequest( ctx, 0, "StreamExecute", sql, bindVariables, @@ -991,6 +1025,7 @@ func (tsv *TabletServer) StreamExecute(ctx context.Context, target *querypb.Targ query: query, marginComments: comments, bindVars: bindVariables, + transactionID: transactionID, options: options, plan: plan, ctx: ctx, @@ -1040,7 +1075,7 @@ func (tsv *TabletServer) ExecuteBatch(ctx context.Context, target *querypb.Targe return nil, err } defer tsv.endRequest(false) - defer tsv.handlePanicAndSendLogStats("batch", nil, &err, nil) + defer tsv.handlePanicAndSendLogStats("batch", nil, nil) if asTransaction { transactionID, err = tsv.Begin(ctx, target, options) @@ -1243,7 +1278,7 @@ func (tsv *TabletServer) execDML(ctx context.Context, target *querypb.Target, qu return 0, err } defer tsv.endRequest(true) - defer tsv.handlePanicAndSendLogStats("ack", nil, &err, nil) + defer tsv.handlePanicAndSendLogStats("ack", nil, nil) query, bv, err := queryGenerator() if err != nil { @@ -1335,7 +1370,6 @@ func (tsv *TabletServer) SplitQuery( if err := validateSplitQueryParameters( target, query, - splitColumns, splitCount, numRowsPerQueryPart, algorithm, @@ -1371,7 +1405,7 @@ func (tsv *TabletServer) SplitQuery( return splits, err } -// execRequest performs verfications, sets up the necessary environments +// execRequest performs verifications, sets up the necessary environments // and calls the supplied function for executing the request. func (tsv *TabletServer) execRequest( ctx context.Context, timeout time.Duration, @@ -1383,7 +1417,7 @@ func (tsv *TabletServer) execRequest( logStats.Target = target logStats.OriginalSQL = sql logStats.BindVariables = bindVariables - defer tsv.handlePanicAndSendLogStats(sql, bindVariables, &err, logStats) + defer tsv.handlePanicAndSendLogStats(sql, bindVariables, logStats) if err = tsv.startRequest(ctx, target, isBegin, allowOnShutdown); err != nil { return err } @@ -1404,7 +1438,6 @@ func (tsv *TabletServer) execRequest( func (tsv *TabletServer) handlePanicAndSendLogStats( sql string, bindVariables map[string]*querypb.BindVariable, - err *error, logStats *tabletenv.LogStats, ) { if x := recover(); x != nil { @@ -1415,7 +1448,6 @@ func (tsv *TabletServer) handlePanicAndSendLogStats( tb.Stack(4) /* Skip the last 4 boiler-plate frames. */) log.Errorf(errorMessage) terr := vterrors.Errorf(vtrpcpb.Code_UNKNOWN, "%s", errorMessage) - *err = terr tabletenv.InternalErrors.Add("Panic", 1) if logStats != nil { logStats.Error = terr @@ -1434,7 +1466,7 @@ func (tsv *TabletServer) convertAndLogError(ctx context.Context, sql string, bin return nil } - errCode := tsv.convertErrorCode(err) + errCode := convertErrorCode(err) tabletenv.ErrorStats.Add(errCode.String(), 1) callerID := "" @@ -1534,7 +1566,7 @@ func truncateSQLAndBindVars(sql string, bindVariables map[string]*querypb.BindVa return fmt.Sprintf("Sql: %q, %s", truncatedQuery, bv) } -func (tsv *TabletServer) convertErrorCode(err error) vtrpcpb.Code { +func convertErrorCode(err error) vtrpcpb.Code { errCode := vterrors.Code(err) sqlErr, ok := err.(*mysql.SQLError) if !ok { @@ -1613,7 +1645,6 @@ func (tsv *TabletServer) convertErrorCode(err error) vtrpcpb.Code { func validateSplitQueryParameters( target *querypb.Target, query *querypb.BoundQuery, - splitColumns []string, splitCount int64, numRowsPerQueryPart int64, algorithm querypb.SplitQueryRequest_Algorithm, @@ -1924,8 +1955,6 @@ verifyTarget: return vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "invalid keyspace %v", target.Keyspace) case target.Shard != tsv.target.Shard: return vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "invalid shard %v", target.Shard) - case isBegin && tsv.target.TabletType != topodatapb.TabletType_MASTER: - return vterrors.Errorf(vtrpcpb.Code_FAILED_PRECONDITION, "transactional statement disallowed on non-master tablet: %v", tsv.target.TabletType) case target.TabletType != tsv.target.TabletType: for _, otherType := range tsv.alsoAllow { if target.TabletType == otherType { @@ -1940,20 +1969,12 @@ verifyTarget: ok: tsv.requests.Add(1) - // If it's a begin, we should make the shutdown code - // wait for the call to end before it waits for tx empty. - if isBegin { - tsv.beginRequests.Add(1) - } return nil } // endRequest unregisters the current request (a waitgroup) as done. func (tsv *TabletServer) endRequest(isBegin bool) { tsv.requests.Done() - if isBegin { - tsv.beginRequests.Done() - } } func (tsv *TabletServer) registerDebugHealthHandler() { diff --git a/go/vt/vttablet/tabletserver/tabletserver_test.go b/go/vt/vttablet/tabletserver/tabletserver_test.go index b2ba5a51e55..4151045a98b 100644 --- a/go/vt/vttablet/tabletserver/tabletserver_test.go +++ b/go/vt/vttablet/tabletserver/tabletserver_test.go @@ -17,14 +17,12 @@ limitations under the License. package tabletserver import ( - "expvar" "fmt" "io" "io/ioutil" "math/rand" "os" "reflect" - "strconv" "strings" "sync" "syscall" @@ -429,29 +427,6 @@ func TestTabletServerCheckMysqlFailInvalidConn(t *testing.T) { } } -func TestTabletServerCheckMysqlInUnintialized(t *testing.T) { - testUtils := newTestUtils() - config := testUtils.newQueryServiceConfig() - tsv := NewTabletServerWithNilTopoServer(config) - // TabletServer start request fail because we are in StateNotConnected; - // however, isMySQLReachable should return true. Here, we always assume - // MySQL is healthy unless we've verified it is not. - if !tsv.isMySQLReachable() { - t.Fatalf("isMySQLReachable should return true") - } - tabletState := expvar.Get("TabletState") - if tabletState == nil { - t.Fatal("TabletState should be exposed") - } - varzState, err := strconv.Atoi(tabletState.String()) - if err != nil { - t.Fatalf("invalid state reported by expvar, should be a valid state code, but got: %s", tabletState.String()) - } - if varzState != StateNotConnected { - t.Fatalf("queryservice should be in %d state, but exposed varz reports: %d", StateNotConnected, varzState) - } -} - func TestTabletServerReconnect(t *testing.T) { db := setUpTabletServerTest(t) defer db.Close() @@ -575,19 +550,6 @@ func TestTabletServerTarget(t *testing.T) { t.Errorf("err: %v, must contain %s", err, want) } - // Disallow tx statements if non-master. - tsv.SetServingType(topodatapb.TabletType_REPLICA, true, nil) - _, err = tsv.Begin(ctx, &target1, nil) - want = "transactional statement disallowed on non-master tablet" - if err == nil || !strings.Contains(err.Error(), want) { - t.Errorf("err: %v, must contain %s", err, want) - } - err = tsv.Commit(ctx, &target1, 1) - want = "invalid tablet type: MASTER" - if err == nil || !strings.Contains(err.Error(), want) { - t.Errorf("err: %v, must contain %s", err, want) - } - // Disallow all if service is stopped. tsv.StopService() _, err = tsv.Execute(ctx, &target1, "select * from test_table limit 1000", nil, 0, nil) @@ -597,46 +559,50 @@ func TestTabletServerTarget(t *testing.T) { } } -func TestTabletServerStopWithPrepare(t *testing.T) { - // Reuse code from tx_executor_test. - _, tsv, db := newTestTxExecutor(t) +func TestBeginOnReplica(t *testing.T) { + db := setUpTabletServerTest(t) + db.AddQuery("set transaction isolation level REPEATABLE READ", &sqltypes.Result{}) + db.AddQuery("start transaction with consistent snapshot, read only", &sqltypes.Result{}) defer db.Close() - ctx := context.Background() - target := querypb.Target{TabletType: topodatapb.TabletType_MASTER} - transactionID, err := tsv.Begin(ctx, &target, nil) - if err != nil { - t.Error(err) - } - if _, err := tsv.Execute(ctx, &target, "update test_table set name = 2 where pk = 1", nil, transactionID, nil); err != nil { - t.Error(err) + testUtils := newTestUtils() + config := testUtils.newQueryServiceConfig() + tsv := NewTabletServerWithNilTopoServer(config) + dbcfgs := testUtils.newDBConfigs(db) + target1 := querypb.Target{ + Keyspace: "test_keyspace", + Shard: "test_shard", + TabletType: topodatapb.TabletType_REPLICA, } - if err = tsv.Prepare(ctx, &target, transactionID, "aa"); err != nil { - t.Error(err) + err := tsv.StartService(target1, dbcfgs) + if err != nil { + t.Fatalf("StartService failed: %v", err) } - ch := make(chan bool) - go func() { - tsv.StopService() - ch <- true - }() + defer tsv.StopService() - // StopService must wait for the prepared transaction to resolve. - select { - case <-ch: - t.Fatal("ch should not fire") - case <-time.After(10 * time.Millisecond): + tsv.SetServingType(topodatapb.TabletType_REPLICA, true, nil) + ctx := context.Background() + options := querypb.ExecuteOptions{ + TransactionIsolation: querypb.ExecuteOptions_CONSISTENT_SNAPSHOT_READ_ONLY, } - if len(tsv.te.preparedPool.conns) != 1 { - t.Errorf("len(tsv.te.preparedPool.conns): %d, want 1", len(tsv.te.preparedPool.conns)) + txID, err := tsv.Begin(ctx, &target1, &options) + + if err != nil { + t.Errorf("err: %v, failed to create read only tx on replica", err) } - // RollbackPrepared will allow StopService to complete. - err = tsv.RollbackPrepared(ctx, &target, "aa", 0) + err = tsv.Rollback(ctx, &target1, txID) if err != nil { - t.Error(err) + t.Errorf("err: %v, failed to rollback read only tx", err) } - <-ch - if len(tsv.te.preparedPool.conns) != 0 { - t.Errorf("len(tsv.te.preparedPool.conns): %d, want 0", len(tsv.te.preparedPool.conns)) + + // test that RW transactions are refused + options = querypb.ExecuteOptions{ + TransactionIsolation: querypb.ExecuteOptions_DEFAULT, + } + _, err = tsv.Begin(ctx, &target1, &options) + + if err == nil { + t.Error("expected write tx to be refused") } } @@ -687,20 +653,28 @@ func TestTabletServerMasterToReplica(t *testing.T) { <-ch } -func TestTabletServerReplicaToMaster(t *testing.T) { +func TestTabletServerRedoLogIsKeptBetweenRestarts(t *testing.T) { // Reuse code from tx_executor_test. _, tsv, db := newTestTxExecutor(t) defer db.Close() defer tsv.StopService() tsv.SetServingType(topodatapb.TabletType_REPLICA, true, nil) + + turnOnTxEngine := func() { + tsv.SetServingType(topodatapb.TabletType_MASTER, true, nil) + } + turnOffTxEngine := func() { + tsv.SetServingType(topodatapb.TabletType_REPLICA, true, nil) + } + tpc := tsv.te.twoPC db.AddQuery(tpc.readAllRedo, &sqltypes.Result{}) - tsv.SetServingType(topodatapb.TabletType_MASTER, true, nil) + turnOnTxEngine() if len(tsv.te.preparedPool.conns) != 0 { t.Errorf("len(tsv.te.preparedPool.conns): %d, want 0", len(tsv.te.preparedPool.conns)) } - tsv.SetServingType(topodatapb.TabletType_REPLICA, true, nil) + turnOffTxEngine() db.AddQuery(tpc.readAllRedo, &sqltypes.Result{ Fields: []*querypb.Field{ @@ -716,7 +690,7 @@ func TestTabletServerReplicaToMaster(t *testing.T) { sqltypes.NewVarBinary("update test_table set name = 2 where pk in (1) /* _stream test_table (pk ) (1 ); */"), }}, }) - tsv.SetServingType(topodatapb.TabletType_MASTER, true, nil) + turnOnTxEngine() if len(tsv.te.preparedPool.conns) != 1 { t.Errorf("len(tsv.te.preparedPool.conns): %d, want 1", len(tsv.te.preparedPool.conns)) } @@ -725,7 +699,10 @@ func TestTabletServerReplicaToMaster(t *testing.T) { if !reflect.DeepEqual(got, want) { t.Errorf("Prepared queries: %v, want %v", got, want) } - tsv.SetServingType(topodatapb.TabletType_REPLICA, true, nil) + turnOffTxEngine() + if v := len(tsv.te.preparedPool.conns); v != 0 { + t.Errorf("len(tsv.te.preparedPool.conns): %d, want 0", v) + } tsv.te.txPool.lastID.Set(1) // Ensure we continue past errors. @@ -753,7 +730,7 @@ func TestTabletServerReplicaToMaster(t *testing.T) { sqltypes.NewVarBinary("unused"), }}, }) - tsv.SetServingType(topodatapb.TabletType_MASTER, true, nil) + turnOnTxEngine() if len(tsv.te.preparedPool.conns) != 1 { t.Errorf("len(tsv.te.preparedPool.conns): %d, want 1", len(tsv.te.preparedPool.conns)) } @@ -770,7 +747,10 @@ func TestTabletServerReplicaToMaster(t *testing.T) { if v := tsv.te.txPool.lastID.Get(); v != 20 { t.Errorf("tsv.te.txPool.lastID.Get(): %d, want 20", v) } - tsv.SetServingType(topodatapb.TabletType_REPLICA, true, nil) + turnOffTxEngine() + if v := len(tsv.te.preparedPool.conns); v != 0 { + t.Errorf("len(tsv.te.preparedPool.conns): %d, want 0", v) + } } func TestTabletServerCreateTransaction(t *testing.T) { @@ -1182,7 +1162,7 @@ func TestTabletServerStreamExecute(t *testing.T) { defer tsv.StopService() ctx := context.Background() callback := func(*sqltypes.Result) error { return nil } - if err := tsv.StreamExecute(ctx, &target, executeSQL, nil, nil, callback); err != nil { + if err := tsv.StreamExecute(ctx, &target, executeSQL, nil, 0, nil, callback); err != nil { t.Fatalf("TabletServer.StreamExecute should success: %s, but get error: %v", executeSQL, err) } @@ -2512,11 +2492,10 @@ func TestTabletServerSplitQueryEqualSplitsOnStringColumn(t *testing.T) { func TestHandleExecUnknownError(t *testing.T) { ctx := context.Background() logStats := tabletenv.NewLogStats(ctx, "TestHandleExecError") - var err error testUtils := newTestUtils() config := testUtils.newQueryServiceConfig() tsv := NewTabletServerWithNilTopoServer(config) - defer tsv.handlePanicAndSendLogStats("select * from test_table", nil, &err, logStats) + defer tsv.handlePanicAndSendLogStats("select * from test_table", nil, logStats) panic("unknown exec error") } diff --git a/go/vt/vttablet/tabletserver/tx_engine.go b/go/vt/vttablet/tabletserver/tx_engine.go index 17f0405fb82..8ecd19b653c 100644 --- a/go/vt/vttablet/tabletserver/tx_engine.go +++ b/go/vt/vttablet/tabletserver/tx_engine.go @@ -17,9 +17,13 @@ limitations under the License. package tabletserver import ( + "fmt" "sync" "time" + "vitess.io/vitess/go/vt/proto/vtrpc" + "vitess.io/vitess/go/vt/vterrors" + "golang.org/x/net/context" "vitess.io/vitess/go/timer" @@ -35,15 +39,58 @@ import ( querypb "vitess.io/vitess/go/vt/proto/query" ) -// TxEngine handles transactions. +type txEngineState int + +// The TxEngine can be in any of these states +const ( + NotServing txEngineState = iota + Transitioning + AcceptingReadAndWrite + AcceptingReadOnly +) + +func (state txEngineState) String() string { + names := [...]string{ + "NotServing", + "Transitioning", + "AcceptReadWrite", + "AcceptingReadOnly"} + + if state < NotServing || state > AcceptingReadOnly { + return fmt.Sprintf("Unknown - %d", int(state)) + } + + return names[state] +} + +// TxEngine is responsible for handling the tx-pool and keeping read-write, read-only or not-serving +// states. It will start and shut down the underlying tx-pool as required. +// It does this in a concurrently safe way. type TxEngine struct { + // the following four fields are interconnected. `state` and `nextState` should be protected by the + // `stateLock` + // + // `nextState` is used when state is Transitioning. This means that in order to change the state of + // the transaction engine, we had to close transactions. `nextState` is the state we'll end up in + // once the transactions are closed + // while transitioning, `transitionSignal` will contain an open channel. Once the transition is + // over, the channel is closed to signal to any waiting goroutines that the state change is done. + stateLock sync.Mutex + state txEngineState + nextState txEngineState + transitionSignal chan struct{} + + // beginRequests is used to make sure that we do not make a state + // transition while creating new transactions + beginRequests sync.WaitGroup + dbconfigs *dbconfigs.DBConfigs - isOpen, twopcEnabled bool - shutdownGracePeriod time.Duration - coordinatorAddress string - abandonAge time.Duration - ticks *timer.Timer + twopcEnabled bool + shutdownGracePeriod time.Duration + coordinatorAddress string + abandonAge time.Duration + ticks *timer.Timer txPool *TxPool preparedPool *TxPreparedPool @@ -103,9 +150,205 @@ func NewTxEngine(checker connpool.MySQLChecker, config tabletenv.TabletConfig) * checker, ) te.twoPC = NewTwoPC(readPool) + te.transitionSignal = make(chan struct{}) + // By immediately closing this channel, all state changes can simply be made blocking by issuing the + // state change desired, and then selecting on this channel. It will contain an open channel while + // transitioning. + close(te.transitionSignal) + te.nextState = -1 + te.state = NotServing return te } +// Stop will stop accepting any new transactions. Transactions are immediately aborted. +func (te *TxEngine) Stop() error { + te.beginRequests.Wait() + te.stateLock.Lock() + + switch te.state { + case NotServing: + // Nothing to do. We are already stopped or stopping + te.stateLock.Unlock() + return nil + + case AcceptingReadAndWrite: + return te.transitionTo(NotServing) + + case AcceptingReadOnly: + // We are not master, so it's safe to kill all read-only transactions + te.close(true) + te.state = NotServing + te.stateLock.Unlock() + return nil + + case Transitioning: + te.nextState = NotServing + te.stateLock.Unlock() + te.blockUntilEndOfTransition() + return nil + + default: + te.stateLock.Unlock() + return te.unknownStateError() + } +} + +// AcceptReadWrite will start accepting all transactions. +// If transitioning from RO mode, transactions might need to be +// rolled back before new transactions can be accepts. +func (te *TxEngine) AcceptReadWrite() error { + te.beginRequests.Wait() + te.stateLock.Lock() + + switch te.state { + case AcceptingReadAndWrite: + // Nothing to do + te.stateLock.Unlock() + return nil + + case NotServing: + te.state = AcceptingReadAndWrite + te.open() + te.stateLock.Unlock() + return nil + + case Transitioning: + te.nextState = AcceptingReadAndWrite + te.stateLock.Unlock() + te.blockUntilEndOfTransition() + return nil + + case AcceptingReadOnly: + // We need to restart the tx-pool to make sure we handle 2PC correctly + te.close(true) + te.state = AcceptingReadAndWrite + te.open() + te.stateLock.Unlock() + return nil + + default: + return te.unknownStateError() + } +} + +// AcceptReadOnly will start accepting read-only transactions, but not full read and write transactions. +// If the engine is currently accepting full read and write transactions, they need to +// be rolled back. +func (te *TxEngine) AcceptReadOnly() error { + te.beginRequests.Wait() + te.stateLock.Lock() + switch te.state { + case AcceptingReadOnly: + // Nothing to do + te.stateLock.Unlock() + return nil + + case NotServing: + te.state = AcceptingReadOnly + te.open() + te.stateLock.Unlock() + return nil + + case AcceptingReadAndWrite: + return te.transitionTo(AcceptingReadOnly) + + case Transitioning: + te.nextState = AcceptingReadOnly + te.stateLock.Unlock() + te.blockUntilEndOfTransition() + return nil + + default: + te.stateLock.Unlock() + return te.unknownStateError() + } +} + +// Begin begins a transaction, and returns the associated transaction id. +// Subsequent statements can access the connection through the transaction id. +func (te *TxEngine) Begin(ctx context.Context, options *querypb.ExecuteOptions) (int64, error) { + te.stateLock.Lock() + + canOpenTransactions := te.state == AcceptingReadOnly || te.state == AcceptingReadAndWrite + if !canOpenTransactions { + // We are not in a state where we can start new transactions. Abort. + te.stateLock.Unlock() + return 0, vterrors.Errorf(vtrpc.Code_UNAVAILABLE, "tx engine can't accept new transactions in state %v", te.state) + } + + isWriteTransaction := options == nil || options.TransactionIsolation != querypb.ExecuteOptions_CONSISTENT_SNAPSHOT_READ_ONLY + if te.state == AcceptingReadOnly && isWriteTransaction { + te.stateLock.Unlock() + return 0, vterrors.Errorf(vtrpc.Code_UNAVAILABLE, "tx engine can only accept read-only transactions in current state") + } + + // By Add() to beginRequests, we block others from initiating state + // changes until we have finished adding this transaction + te.beginRequests.Add(1) + te.stateLock.Unlock() + + defer te.beginRequests.Done() + return te.txPool.Begin(ctx, options) +} + +// Commit commits the specified transaction. +func (te *TxEngine) Commit(ctx context.Context, transactionID int64, mc messageCommitter) error { + return te.txPool.Commit(ctx, transactionID, mc) +} + +// Rollback rolls back the specified transaction. +func (te *TxEngine) Rollback(ctx context.Context, transactionID int64) error { + return te.txPool.Rollback(ctx, transactionID) +} + +func (te *TxEngine) unknownStateError() error { + return vterrors.Errorf(vtrpc.Code_INTERNAL, "unknown state %v", te.state) +} + +func (te *TxEngine) blockUntilEndOfTransition() error { + select { + case <-te.transitionSignal: + return nil + } +} + +func (te *TxEngine) transitionTo(nextState txEngineState) error { + te.state = Transitioning + te.nextState = nextState + te.transitionSignal = make(chan struct{}) + te.stateLock.Unlock() + + // We do this outside the lock so others can see our state while we close up waiting transactions + te.close(true) + + te.stateLock.Lock() + defer func() { + // we use a lambda to make it clear in which order things need to happen + te.stateLock.Unlock() + close(te.transitionSignal) + }() + + if te.state != Transitioning { + return vterrors.Errorf(vtrpc.Code_INTERNAL, "this should never happen. the goroutine starting the transition should also finish it") + } + + // Once we reach this point, it's as if our state is NotServing, + // and we need to decide what the next step is + switch te.nextState { + case AcceptingReadAndWrite, AcceptingReadOnly: + te.state = te.nextState + te.open() + case NotServing: + te.state = NotServing + case Transitioning: + return vterrors.Errorf(vtrpc.Code_INTERNAL, "this should never happen. nextState cannot be transitioning") + } + + te.nextState = -1 + + return nil +} + // InitDBConfig must be called before Init. func (te *TxEngine) InitDBConfig(dbcfgs *dbconfigs.DBConfigs) { te.dbconfigs = dbcfgs @@ -120,28 +363,32 @@ func (te *TxEngine) Init() error { return nil } -// Open opens the TxEngine. If 2pc is enabled, it restores +// open opens the TxEngine. If 2pc is enabled, it restores // all previously prepared transactions from the redo log. -func (te *TxEngine) Open() { - if te.isOpen { - return - } +// this should only be called when the state is already locked +func (te *TxEngine) open() { te.txPool.Open(te.dbconfigs.AppWithDB(), te.dbconfigs.DbaWithDB(), te.dbconfigs.AppDebugWithDB()) - if !te.twopcEnabled { - te.isOpen = true - return - } - te.twoPC.Open(te.dbconfigs) - if err := te.prepareFromRedo(); err != nil { - // If this operation fails, we choose to raise an alert and - // continue anyway. Serving traffic is considered more important - // than blocking everything for the sake of a few transactions. - tabletenv.InternalErrors.Add("TwopcResurrection", 1) - log.Errorf("Could not prepare transactions: %v", err) + if te.twopcEnabled && te.state == AcceptingReadAndWrite { + te.twoPC.Open(te.dbconfigs) + if err := te.prepareFromRedo(); err != nil { + // If this operation fails, we choose to raise an alert and + // continue anyway. Serving traffic is considered more important + // than blocking everything for the sake of a few transactions. + tabletenv.InternalErrors.Add("TwopcResurrection", 1) + log.Errorf("Could not prepare transactions: %v", err) + } + te.startWatchdog() } - te.startWatchdog() - te.isOpen = true +} + +// StopGently will disregard common rules for when to kill transactions +// and wait forever for transactions to wrap up +func (te *TxEngine) StopGently() { + te.stateLock.Lock() + defer te.stateLock.Unlock() + te.close(false) + te.state = NotServing } // Close closes the TxEngine. If the immediate flag is on, @@ -150,10 +397,7 @@ func (te *TxEngine) Open() { // to conclude. If a shutdown grace period was specified, // the transactions are rolled back if they're not resolved // by that time. -func (te *TxEngine) Close(immediate bool) { - if !te.isOpen { - return - } +func (te *TxEngine) close(immediate bool) { // Shut down functions are idempotent. // No need to check if 2pc is enabled. te.stopWatchdog() @@ -177,6 +421,7 @@ func (te *TxEngine) Close(immediate bool) { } if te.shutdownGracePeriod <= 0 { // No grace period was specified. Never rollback. + te.rollbackPrepared() log.Info("No grace period specified: performing normal wait.") return } @@ -184,9 +429,8 @@ func (te *TxEngine) Close(immediate bool) { defer tmr.Stop() select { case <-tmr.C: - // The grace period has passed. Rollback, but don't touch the 2pc transactions. - log.Info("Grace period exceeded: rolling back non-2pc transactions now.") - te.txPool.RollbackNonBusy(tabletenv.LocalContext()) + log.Info("Grace period exceeded: rolling back now.") + te.rollbackTransactions() case <-poolEmpty: // The pool cleared before the timer kicked in. Just return. log.Info("Transactions completed before grace period: shutting down.") @@ -200,7 +444,6 @@ func (te *TxEngine) Close(immediate bool) { te.txPool.Close() te.twoPC.Close() - te.isOpen = false } // prepareFromRedo replays and prepares the transactions @@ -268,11 +511,18 @@ outer: // serving type. func (te *TxEngine) rollbackTransactions() { ctx := tabletenv.LocalContext() + for _, c := range te.preparedPool.FetchAll() { + te.txPool.LocalConclude(ctx, c) + } // The order of rollbacks is currently not material because // we don't allow new statements or commits during // this function. In case of any such change, this will // have to be revisited. te.txPool.RollbackNonBusy(ctx) +} + +func (te *TxEngine) rollbackPrepared() { + ctx := tabletenv.LocalContext() for _, c := range te.preparedPool.FetchAll() { te.txPool.LocalConclude(ctx, c) } diff --git a/go/vt/vttablet/tabletserver/tx_engine_test.go b/go/vt/vttablet/tabletserver/tx_engine_test.go index e570abed323..8cbfef5556c 100644 --- a/go/vt/vttablet/tabletserver/tx_engine_test.go +++ b/go/vt/vttablet/tabletserver/tx_engine_test.go @@ -17,9 +17,15 @@ limitations under the License. package tabletserver import ( + "fmt" + "strings" + "sync" "testing" "time" + "vitess.io/vitess/go/mysql/fakesqldb" + "vitess.io/vitess/go/sqltypes" + "vitess.io/vitess/go/vt/vttablet/tabletserver/tabletenv" "golang.org/x/net/context" @@ -40,49 +46,49 @@ func TestTxEngineClose(t *testing.T) { te.InitDBConfig(dbcfgs) // Normal close. - te.Open() + te.open() start := time.Now() - te.Close(false) + te.close(false) if diff := time.Now().Sub(start); diff > 500*time.Millisecond { t.Errorf("Close time: %v, must be under 0.5s", diff) } // Normal close with timeout wait. - te.Open() + te.open() c, err := te.txPool.LocalBegin(ctx, &querypb.ExecuteOptions{}) if err != nil { t.Fatal(err) } c.Recycle() start = time.Now() - te.Close(false) + te.close(false) if diff := time.Now().Sub(start); diff < 500*time.Millisecond { t.Errorf("Close time: %v, must be over 0.5s", diff) } // Immediate close. - te.Open() + te.open() c, err = te.txPool.LocalBegin(ctx, &querypb.ExecuteOptions{}) if err != nil { t.Fatal(err) } c.Recycle() start = time.Now() - te.Close(true) + te.close(true) if diff := time.Now().Sub(start); diff > 500*time.Millisecond { t.Errorf("Close time: %v, must be under 0.5s", diff) } // Normal close with short grace period. te.shutdownGracePeriod = 250 * time.Millisecond - te.Open() + te.open() c, err = te.txPool.LocalBegin(ctx, &querypb.ExecuteOptions{}) if err != nil { t.Fatal(err) } c.Recycle() start = time.Now() - te.Close(false) + te.close(false) if diff := time.Now().Sub(start); diff > 500*time.Millisecond { t.Errorf("Close time: %v, must be under 0.5s", diff) } @@ -92,7 +98,7 @@ func TestTxEngineClose(t *testing.T) { // Normal close with short grace period, but pool gets empty early. te.shutdownGracePeriod = 250 * time.Millisecond - te.Open() + te.open() c, err = te.txPool.LocalBegin(ctx, &querypb.ExecuteOptions{}) if err != nil { t.Fatal(err) @@ -107,7 +113,7 @@ func TestTxEngineClose(t *testing.T) { te.txPool.LocalConclude(ctx, c) }() start = time.Now() - te.Close(false) + te.close(false) if diff := time.Now().Sub(start); diff > 250*time.Millisecond { t.Errorf("Close time: %v, must be under 0.25s", diff) } @@ -116,7 +122,7 @@ func TestTxEngineClose(t *testing.T) { } // Immediate close, but connection is in use. - te.Open() + te.open() c, err = te.txPool.LocalBegin(ctx, &querypb.ExecuteOptions{}) if err != nil { t.Fatal(err) @@ -126,7 +132,7 @@ func TestTxEngineClose(t *testing.T) { te.txPool.LocalConclude(ctx, c) }() start = time.Now() - te.Close(true) + te.close(true) if diff := time.Now().Sub(start); diff > 250*time.Millisecond { t.Errorf("Close time: %v, must be under 0.25s", diff) } @@ -134,3 +140,358 @@ func TestTxEngineClose(t *testing.T) { t.Errorf("Close time: %v, must be over 0.1", diff) } } + +type TxType int + +const ( + NoTx TxType = iota + ReadOnlyAccepted + WriteAccepted + ReadOnlyRejected + WriteRejected +) + +func (t TxType) String() string { + names := [...]string{ + "no transaction", + "read only transaction accepted", + "write transaction accepted", + "read only transaction rejected", + "write transaction rejected", + } + + if t < NoTx || t > WriteRejected { + return "unknown" + } + + return names[t] +} + +type TestCase struct { + startState txEngineState + TxEngineStates []txEngineState + tx TxType + stateAssertion func(state txEngineState) error +} + +func (test TestCase) String() string { + var sb strings.Builder + sb.WriteString("start from ") + sb.WriteString(test.startState.String()) + sb.WriteString(" with ") + sb.WriteString(test.tx.String()) + + for _, change := range test.TxEngineStates { + sb.WriteString(" change state to ") + sb.WriteString(change.String()) + } + + return sb.String() +} + +func changeState(te *TxEngine, state txEngineState) error { + switch state { + case AcceptingReadAndWrite: + return te.AcceptReadWrite() + case AcceptingReadOnly: + return te.AcceptReadOnly() + case NotServing: + return te.Stop() + default: + return fmt.Errorf("don't know how to do that: %v", state) + } +} + +func TestWithInnerTests(outerT *testing.T) { + + tests := []TestCase{ + // Start from RW and test all single hop transitions with and without tx + {AcceptingReadAndWrite, []txEngineState{ + NotServing}, + NoTx, assertEndStateIs(NotServing)}, + + {AcceptingReadAndWrite, []txEngineState{ + AcceptingReadAndWrite}, + NoTx, assertEndStateIs(AcceptingReadAndWrite)}, + + {AcceptingReadAndWrite, []txEngineState{ + AcceptingReadOnly}, + NoTx, assertEndStateIs(AcceptingReadOnly)}, + + {AcceptingReadAndWrite, []txEngineState{ + NotServing}, + WriteAccepted, assertEndStateIs(NotServing)}, + + {AcceptingReadAndWrite, []txEngineState{ + AcceptingReadAndWrite}, + WriteAccepted, assertEndStateIs(AcceptingReadAndWrite)}, + + {AcceptingReadAndWrite, []txEngineState{ + AcceptingReadOnly}, + WriteAccepted, assertEndStateIs(AcceptingReadOnly)}, + + {AcceptingReadAndWrite, []txEngineState{ + NotServing}, + ReadOnlyAccepted, assertEndStateIs(NotServing)}, + + {AcceptingReadAndWrite, []txEngineState{ + AcceptingReadAndWrite}, + ReadOnlyAccepted, assertEndStateIs(AcceptingReadAndWrite)}, + + {AcceptingReadAndWrite, []txEngineState{ + AcceptingReadOnly}, + ReadOnlyAccepted, assertEndStateIs(AcceptingReadOnly)}, + + // Start from RW and test all transitions with and without tx, plus a concurrent Stop() + {AcceptingReadAndWrite, []txEngineState{ + NotServing, + NotServing}, + NoTx, assertEndStateIs(NotServing)}, + + {AcceptingReadAndWrite, []txEngineState{ + AcceptingReadAndWrite, + NotServing}, + NoTx, assertEndStateIs(NotServing)}, + + {AcceptingReadAndWrite, []txEngineState{ + AcceptingReadOnly, + NotServing}, + NoTx, assertEndStateIs(NotServing)}, + + {AcceptingReadAndWrite, []txEngineState{ + NotServing, + NotServing}, + WriteAccepted, assertEndStateIs(NotServing)}, + + {AcceptingReadAndWrite, []txEngineState{ + AcceptingReadAndWrite, + NotServing}, + WriteAccepted, assertEndStateIs(NotServing)}, + + {AcceptingReadAndWrite, []txEngineState{ + AcceptingReadOnly, + NotServing}, + WriteAccepted, assertEndStateIs(NotServing)}, + + // Start from RW and test all transitions with and without tx, plus a concurrent ReadOnly() + {AcceptingReadAndWrite, []txEngineState{ + NotServing, + AcceptingReadOnly}, + NoTx, assertEndStateIs(AcceptingReadOnly)}, + + {AcceptingReadAndWrite, []txEngineState{ + AcceptingReadAndWrite, + AcceptingReadOnly}, + NoTx, assertEndStateIs(AcceptingReadOnly)}, + + {AcceptingReadAndWrite, []txEngineState{ + AcceptingReadOnly, + AcceptingReadOnly}, + NoTx, assertEndStateIs(AcceptingReadOnly)}, + + {AcceptingReadAndWrite, []txEngineState{ + NotServing, + AcceptingReadOnly}, + WriteAccepted, assertEndStateIs(AcceptingReadOnly)}, + + {AcceptingReadAndWrite, []txEngineState{ + AcceptingReadAndWrite, + AcceptingReadOnly}, + WriteAccepted, assertEndStateIs(AcceptingReadOnly)}, + + {AcceptingReadAndWrite, []txEngineState{ + AcceptingReadOnly, + AcceptingReadOnly}, + WriteAccepted, assertEndStateIs(AcceptingReadOnly)}, + + // Start from RO and test all single hop transitions with and without tx + {AcceptingReadOnly, []txEngineState{ + NotServing}, + NoTx, assertEndStateIs(NotServing)}, + + {AcceptingReadOnly, []txEngineState{ + AcceptingReadAndWrite}, + NoTx, assertEndStateIs(AcceptingReadAndWrite)}, + + {AcceptingReadOnly, []txEngineState{ + AcceptingReadOnly}, + NoTx, assertEndStateIs(AcceptingReadOnly)}, + + {AcceptingReadOnly, []txEngineState{ + NotServing}, + WriteRejected, assertEndStateIs(NotServing)}, + + {AcceptingReadOnly, []txEngineState{ + AcceptingReadAndWrite}, + WriteRejected, assertEndStateIs(AcceptingReadAndWrite)}, + + {AcceptingReadOnly, []txEngineState{ + AcceptingReadOnly}, + WriteRejected, assertEndStateIs(AcceptingReadOnly)}, + + // Start from RO and test all transitions with and without tx, plus a concurrent Stop() + {AcceptingReadOnly, []txEngineState{ + NotServing, + NotServing}, + NoTx, assertEndStateIs(NotServing)}, + + {AcceptingReadOnly, []txEngineState{ + AcceptingReadAndWrite, + NotServing}, + NoTx, assertEndStateIs(NotServing)}, + + {AcceptingReadOnly, []txEngineState{ + AcceptingReadOnly, + NotServing}, + NoTx, assertEndStateIs(NotServing)}, + + {AcceptingReadOnly, []txEngineState{ + NotServing, + NotServing}, + WriteRejected, assertEndStateIs(NotServing)}, + + {AcceptingReadOnly, []txEngineState{ + AcceptingReadAndWrite, + NotServing}, + WriteRejected, assertEndStateIs(NotServing)}, + + {AcceptingReadOnly, []txEngineState{ + AcceptingReadOnly, + NotServing}, + WriteRejected, assertEndStateIs(NotServing)}, + + // Start from RO and test all transitions with and without tx, plus a concurrent ReadWrite() + {AcceptingReadOnly, []txEngineState{ + NotServing, + AcceptingReadAndWrite}, + NoTx, assertEndStateIs(AcceptingReadAndWrite)}, + + {AcceptingReadOnly, []txEngineState{ + AcceptingReadAndWrite, + AcceptingReadAndWrite}, + NoTx, assertEndStateIs(AcceptingReadAndWrite)}, + + {AcceptingReadOnly, []txEngineState{ + AcceptingReadOnly, + AcceptingReadAndWrite}, + NoTx, assertEndStateIs(AcceptingReadAndWrite)}, + + {AcceptingReadOnly, []txEngineState{ + NotServing, + AcceptingReadAndWrite}, + WriteRejected, assertEndStateIs(AcceptingReadAndWrite)}, + + {AcceptingReadOnly, []txEngineState{ + AcceptingReadAndWrite, + AcceptingReadAndWrite}, + WriteRejected, assertEndStateIs(AcceptingReadAndWrite)}, + + {AcceptingReadOnly, []txEngineState{ + AcceptingReadOnly, + AcceptingReadAndWrite}, + WriteRejected, assertEndStateIs(AcceptingReadAndWrite)}, + + // Make sure that all transactions are rejected when we are not serving + {NotServing, []txEngineState{}, + WriteRejected, assertEndStateIs(NotServing)}, + + {NotServing, []txEngineState{}, + ReadOnlyRejected, assertEndStateIs(NotServing)}, + } + + for _, test := range tests { + outerT.Run(test.String(), func(t *testing.T) { + + db := setUpQueryExecutorTest(t) + db.AddQuery("set transaction isolation level REPEATABLE READ", &sqltypes.Result{}) + db.AddQuery("start transaction with consistent snapshot, read only", &sqltypes.Result{}) + defer db.Close() + te := setupTxEngine(db) + + failIfError(t, + changeState(te, test.startState)) + + switch test.tx { + case NoTx: + // nothing to do + case WriteAccepted: + failIfError(t, + startTransaction(te, true)) + case ReadOnlyAccepted: + failIfError(t, + startTransaction(te, false)) + case WriteRejected: + err := startTransaction(te, true) + if err == nil { + t.Fatalf("expected an error to be returned when opening write transaction, but got nil") + } + case ReadOnlyRejected: + err := startTransaction(te, false) + if err == nil { + t.Fatalf("expected an error to be returned when opening read transaction, but got nil") + } + default: + t.Fatalf("don't know how to [%v]", test.tx) + } + + wg := sync.WaitGroup{} + for _, newState := range test.TxEngineStates { + wg.Add(1) + go func(s txEngineState) { + defer wg.Done() + + failIfError(t, + changeState(te, s)) + }(newState) + + // We give the state changes a chance to get started + time.Sleep(10 * time.Millisecond) + } + + // Let's wait for all transitions to wrap up + wg.Wait() + + failIfError(t, + test.stateAssertion(te.state)) + }) + } +} + +func setupTxEngine(db *fakesqldb.DB) *TxEngine { + testUtils := newTestUtils() + dbcfgs := testUtils.newDBConfigs(db) + config := tabletenv.DefaultQsConfig + config.TransactionCap = 10 + config.TransactionTimeout = 0.5 + config.TxShutDownGracePeriod = 0 + te := NewTxEngine(nil, config) + te.InitDBConfig(dbcfgs) + return te +} + +func failIfError(t *testing.T, err error) { + if err != nil { + t.Logf("%+v", err) + t.FailNow() + } +} + +func assertEndStateIs(expected txEngineState) func(actual txEngineState) error { + return func(actual txEngineState) error { + if actual != expected { + return fmt.Errorf("expected the end state to be %v, but it was %v", expected, actual) + } + return nil + } +} + +func startTransaction(te *TxEngine, writeTransaction bool) error { + options := &querypb.ExecuteOptions{} + if writeTransaction { + options.TransactionIsolation = querypb.ExecuteOptions_DEFAULT + } else { + options.TransactionIsolation = querypb.ExecuteOptions_CONSISTENT_SNAPSHOT_READ_ONLY + } + _, err := te.Begin(context.Background(), options) + return err +} diff --git a/go/vt/vttablet/tabletserver/tx_pool.go b/go/vt/vttablet/tabletserver/tx_pool.go index 8d610becb6d..44b07e125ef 100644 --- a/go/vt/vttablet/tabletserver/tx_pool.go +++ b/go/vt/vttablet/tabletserver/tx_pool.go @@ -54,15 +54,22 @@ const ( const txLogInterval = time.Duration(1 * time.Minute) +type queries struct { + setIsolationLevel string + openTransaction string +} + var ( txOnce sync.Once txStats = stats.NewTimings("Transactions", "Transaction stats", "operation") - txIsolations = map[querypb.ExecuteOptions_TransactionIsolation]string{ - querypb.ExecuteOptions_REPEATABLE_READ: "set transaction isolation level REPEATABLE READ", - querypb.ExecuteOptions_READ_COMMITTED: "set transaction isolation level READ COMMITTED", - querypb.ExecuteOptions_READ_UNCOMMITTED: "set transaction isolation level READ UNCOMMITTED", - querypb.ExecuteOptions_SERIALIZABLE: "set transaction isolation level SERIALIZABLE", + txIsolations = map[querypb.ExecuteOptions_TransactionIsolation]queries{ + querypb.ExecuteOptions_DEFAULT: {setIsolationLevel: "", openTransaction: "begin"}, + querypb.ExecuteOptions_REPEATABLE_READ: {setIsolationLevel: "REPEATABLE READ", openTransaction: "begin"}, + querypb.ExecuteOptions_READ_COMMITTED: {setIsolationLevel: "READ COMMITTED", openTransaction: "begin"}, + querypb.ExecuteOptions_READ_UNCOMMITTED: {setIsolationLevel: "READ UNCOMMITTED", openTransaction: "begin"}, + querypb.ExecuteOptions_SERIALIZABLE: {setIsolationLevel: "SERIALIZABLE", openTransaction: "begin"}, + querypb.ExecuteOptions_CONSISTENT_SNAPSHOT_READ_ONLY: {setIsolationLevel: "REPEATABLE READ", openTransaction: "start transaction with consistent snapshot, read only"}, } ) @@ -232,14 +239,18 @@ func (axp *TxPool) Begin(ctx context.Context, options *querypb.ExecuteOptions) ( return 0, err } - if query, ok := txIsolations[options.GetTransactionIsolation()]; ok { - if _, err := conn.Exec(ctx, query, 1, false); err != nil { - return 0, err + if queries, ok := txIsolations[options.GetTransactionIsolation()]; ok { + if queries.setIsolationLevel != "" { + if _, err := conn.Exec(ctx, "set transaction isolation level "+queries.setIsolationLevel, 1, false); err != nil { + return 0, err + } } - } - if _, err := conn.Exec(ctx, "begin", 1, false); err != nil { - return 0, err + if _, err := conn.Exec(ctx, queries.openTransaction, 1, false); err != nil { + return 0, err + } + } else { + return 0, fmt.Errorf("don't know how to open a transaction of this type: %v", options.GetTransactionIsolation()) } beginSucceeded = true diff --git a/go/vt/vttablet/tmclient/rpc_client_api.go b/go/vt/vttablet/tmclient/rpc_client_api.go index d02115afb40..77c344d35d4 100644 --- a/go/vt/vttablet/tmclient/rpc_client_api.go +++ b/go/vt/vttablet/tmclient/rpc_client_api.go @@ -89,6 +89,10 @@ type TabletManagerClient interface { // ApplySchema will apply a schema change ApplySchema(ctx context.Context, tablet *topodatapb.Tablet, change *tmutils.SchemaChange) (*tabletmanagerdatapb.SchemaChangeResult, error) + LockTables(ctx context.Context, tablet *topodatapb.Tablet) error + + UnlockTables(ctx context.Context, tablet *topodatapb.Tablet) error + // ExecuteFetchAsDba executes a query remotely using the DBA pool. // If usePool is set, a connection pool may be used to make the // query faster. Close() should close the pool in that case. @@ -122,6 +126,9 @@ type TabletManagerClient interface { // StartSlave starts the mysql replication StartSlave(ctx context.Context, tablet *topodatapb.Tablet) error + // StartSlaveUntilAfter starts replication until after the position specified + StartSlaveUntilAfter(ctx context.Context, tablet *topodatapb.Tablet, position string, duration time.Duration) error + // TabletExternallyReparented tells a tablet it is now the master, after an // external tool has already promoted the underlying mysqld to master and // reparented the other mysqld servers to it. diff --git a/go/vt/worker/diff_utils.go b/go/vt/worker/diff_utils.go index 43b469fd21b..551e12281fa 100644 --- a/go/vt/worker/diff_utils.go +++ b/go/vt/worker/diff_utils.go @@ -91,6 +91,61 @@ func NewQueryResultReaderForTablet(ctx context.Context, ts *topo.Server, tabletA }, nil } +// NewTransactionalQueryResultReaderForTablet creates a new QueryResultReader for +// the provided tablet / sql query, and runs it in an existing transaction +func NewTransactionalQueryResultReaderForTablet(ctx context.Context, ts *topo.Server, tabletAlias *topodatapb.TabletAlias, sql string, txID int64) (*QueryResultReader, error) { + shortCtx, cancel := context.WithTimeout(ctx, *remoteActionsTimeout) + tablet, err := ts.GetTablet(shortCtx, tabletAlias) + cancel() + if err != nil { + return nil, err + } + + conn, err := tabletconn.GetDialer()(tablet.Tablet, grpcclient.FailFast(false)) + if err != nil { + return nil, err + } + + stream := queryservice.ExecuteWithTransactionalStreamer(ctx, conn, &querypb.Target{ + Keyspace: tablet.Tablet.Keyspace, + Shard: tablet.Tablet.Shard, + TabletType: tablet.Tablet.Type, + }, sql, make(map[string]*querypb.BindVariable), txID, nil) + + // read the columns, or grab the error + cols, err := stream.Recv() + if err != nil { + return nil, fmt.Errorf("Cannot read Fields for query '%v': %v", sql, err) + } + + return &QueryResultReader{ + output: stream, + fields: cols.Fields, + conn: conn, + }, nil +} + +// RollbackTransaction rolls back the transaction +func RollbackTransaction(ctx context.Context, ts *topo.Server, tabletAlias *topodatapb.TabletAlias, txID int64) error { + shortCtx, cancel := context.WithTimeout(ctx, *remoteActionsTimeout) + tablet, err := ts.GetTablet(shortCtx, tabletAlias) + cancel() + if err != nil { + return err + } + + conn, err := tabletconn.GetDialer()(tablet.Tablet, grpcclient.FailFast(false)) + if err != nil { + return err + } + + return conn.Rollback(ctx, &querypb.Target{ + Keyspace: tablet.Tablet.Keyspace, + Shard: tablet.Tablet.Shard, + TabletType: tablet.Tablet.Type, + }, txID) +} + // Next returns the next result on the stream. It implements ResultReader. func (qrr *QueryResultReader) Next() (*sqltypes.Result, error) { return qrr.output.Recv() @@ -201,6 +256,16 @@ func TableScan(ctx context.Context, log logutil.Logger, ts *topo.Server, tabletA return NewQueryResultReaderForTablet(ctx, ts, tabletAlias, sql) } +// TransactionalTableScan does the same thing as TableScan, but runs inside a transaction +func TransactionalTableScan(ctx context.Context, log logutil.Logger, ts *topo.Server, tabletAlias *topodatapb.TabletAlias, txID int64, td *tabletmanagerdatapb.TableDefinition) (*QueryResultReader, error) { + sql := fmt.Sprintf("SELECT %v FROM %v", strings.Join(escapeAll(orderedColumns(td)), ", "), sqlescape.EscapeID(td.Name)) + if len(td.PrimaryKeyColumns) > 0 { + sql += fmt.Sprintf(" ORDER BY %v", strings.Join(escapeAll(td.PrimaryKeyColumns), ", ")) + } + log.Infof("SQL query for %v/%v: %v", topoproto.TabletAliasString(tabletAlias), td.Name, sql) + return NewTransactionalQueryResultReaderForTablet(ctx, ts, tabletAlias, sql, txID) +} + // TableScanByKeyRange returns a QueryResultReader that gets all the // rows from a table that match the supplied KeyRange, ordered by // Primary Key. The returned columns are ordered with the Primary Key diff --git a/go/vt/worker/legacy_split_clone_test.go b/go/vt/worker/legacy_split_clone_test.go index 8754f0c7d6d..1bdd773fb8b 100644 --- a/go/vt/worker/legacy_split_clone_test.go +++ b/go/vt/worker/legacy_split_clone_test.go @@ -238,7 +238,7 @@ type legacyTestQueryService struct { *fakes.StreamHealthQueryService } -func (sq *legacyTestQueryService) StreamExecute(ctx context.Context, target *querypb.Target, sql string, bindVariables map[string]*querypb.BindVariable, options *querypb.ExecuteOptions, callback func(reply *sqltypes.Result) error) error { +func (sq *legacyTestQueryService) StreamExecute(ctx context.Context, target *querypb.Target, sql string, bindVariables map[string]*querypb.BindVariable, transactionID int64, options *querypb.ExecuteOptions, callback func(reply *sqltypes.Result) error) error { // Custom parsing of the query we expect. min := legacySplitCloneTestMin max := legacySplitCloneTestMax diff --git a/go/vt/worker/multi_split_diff_test.go b/go/vt/worker/multi_split_diff_test.go index 7811f5b1b54..8195fb5628c 100644 --- a/go/vt/worker/multi_split_diff_test.go +++ b/go/vt/worker/multi_split_diff_test.go @@ -49,7 +49,7 @@ type msdDestinationTabletServer struct { shardIndex int } -func (sq *msdDestinationTabletServer) StreamExecute(ctx context.Context, target *querypb.Target, sql string, bindVariables map[string]*querypb.BindVariable, options *querypb.ExecuteOptions, callback func(reply *sqltypes.Result) error) error { +func (sq *msdDestinationTabletServer) StreamExecute(ctx context.Context, target *querypb.Target, sql string, bindVariables map[string]*querypb.BindVariable, transactionID int64, options *querypb.ExecuteOptions, callback func(reply *sqltypes.Result) error) error { if strings.Contains(sql, sq.excludedTable) { sq.t.Errorf("Split Diff operation on destination should skip the excluded table: %v query: %v", sq.excludedTable, sql) } @@ -111,7 +111,7 @@ type msdSourceTabletServer struct { v3 bool } -func (sq *msdSourceTabletServer) StreamExecute(ctx context.Context, target *querypb.Target, sql string, bindVariables map[string]*querypb.BindVariable, options *querypb.ExecuteOptions, callback func(reply *sqltypes.Result) error) error { +func (sq *msdSourceTabletServer) StreamExecute(ctx context.Context, target *querypb.Target, sql string, bindVariables map[string]*querypb.BindVariable, transactionID int64, options *querypb.ExecuteOptions, callback func(reply *sqltypes.Result) error) error { if strings.Contains(sql, sq.excludedTable) { sq.t.Errorf("Split Diff operation on source should skip the excluded table: %v query: %v", sq.excludedTable, sql) } @@ -277,7 +277,7 @@ func testMultiSplitDiff(t *testing.T, v3 bool) { qs := fakes.NewStreamHealthQueryService(sourceRdonly.Target()) qs.AddDefaultHealthResponse() grpcqueryservice.Register(sourceRdonly.RPCServer, &msdSourceTabletServer{ - t: t, + t: t, StreamHealthQueryService: qs, excludedTable: excludedTable, v3: v3, @@ -288,7 +288,7 @@ func testMultiSplitDiff(t *testing.T, v3 bool) { qs := fakes.NewStreamHealthQueryService(destRdonly.Target()) qs.AddDefaultHealthResponse() grpcqueryservice.Register(destRdonly.RPCServer, &msdDestinationTabletServer{ - t: t, + t: t, StreamHealthQueryService: qs, excludedTable: excludedTable, shardIndex: 0, @@ -299,7 +299,7 @@ func testMultiSplitDiff(t *testing.T, v3 bool) { qs := fakes.NewStreamHealthQueryService(destRdonly.Target()) qs.AddDefaultHealthResponse() grpcqueryservice.Register(destRdonly.RPCServer, &msdDestinationTabletServer{ - t: t, + t: t, StreamHealthQueryService: qs, excludedTable: excludedTable, shardIndex: 1, diff --git a/go/vt/worker/split_clone_test.go b/go/vt/worker/split_clone_test.go index 911a5c8ff82..6e219171ed2 100644 --- a/go/vt/worker/split_clone_test.go +++ b/go/vt/worker/split_clone_test.go @@ -342,7 +342,7 @@ func newTestQueryService(t *testing.T, target querypb.Target, shqs *fakes.Stream } } -func (sq *testQueryService) StreamExecute(ctx context.Context, target *querypb.Target, sql string, bindVariables map[string]*querypb.BindVariable, options *querypb.ExecuteOptions, callback func(reply *sqltypes.Result) error) error { +func (sq *testQueryService) StreamExecute(ctx context.Context, target *querypb.Target, sql string, bindVariables map[string]*querypb.BindVariable, transactionID int64, options *querypb.ExecuteOptions, callback func(reply *sqltypes.Result) error) error { // Custom parsing of the query we expect. // Example: SELECT `id`, `msg`, `keyspace_id` FROM table1 WHERE id>=180 AND id<190 ORDER BY id min := math.MinInt32 diff --git a/go/vt/worker/split_diff_test.go b/go/vt/worker/split_diff_test.go index efc8f4be612..c281852f804 100644 --- a/go/vt/worker/split_diff_test.go +++ b/go/vt/worker/split_diff_test.go @@ -48,7 +48,7 @@ type destinationTabletServer struct { excludedTable string } -func (sq *destinationTabletServer) StreamExecute(ctx context.Context, target *querypb.Target, sql string, bindVariables map[string]*querypb.BindVariable, options *querypb.ExecuteOptions, callback func(reply *sqltypes.Result) error) error { +func (sq *destinationTabletServer) StreamExecute(ctx context.Context, target *querypb.Target, sql string, bindVariables map[string]*querypb.BindVariable, transactionID int64, options *querypb.ExecuteOptions, callback func(reply *sqltypes.Result) error) error { if strings.Contains(sql, sq.excludedTable) { sq.t.Errorf("Split Diff operation on destination should skip the excluded table: %v query: %v", sq.excludedTable, sql) } @@ -110,7 +110,7 @@ type sourceTabletServer struct { v3 bool } -func (sq *sourceTabletServer) StreamExecute(ctx context.Context, target *querypb.Target, sql string, bindVariables map[string]*querypb.BindVariable, options *querypb.ExecuteOptions, callback func(reply *sqltypes.Result) error) error { +func (sq *sourceTabletServer) StreamExecute(ctx context.Context, target *querypb.Target, sql string, bindVariables map[string]*querypb.BindVariable, transactionID int64, options *querypb.ExecuteOptions, callback func(reply *sqltypes.Result) error) error { if strings.Contains(sql, sq.excludedTable) { sq.t.Errorf("Split Diff operation on source should skip the excluded table: %v query: %v", sq.excludedTable, sql) } diff --git a/go/vt/worker/vertical_split_diff_test.go b/go/vt/worker/vertical_split_diff_test.go index c2c05a97f2c..826e965700e 100644 --- a/go/vt/worker/vertical_split_diff_test.go +++ b/go/vt/worker/vertical_split_diff_test.go @@ -46,7 +46,7 @@ type verticalDiffTabletServer struct { *fakes.StreamHealthQueryService } -func (sq *verticalDiffTabletServer) StreamExecute(ctx context.Context, target *querypb.Target, sql string, bindVariables map[string]*querypb.BindVariable, options *querypb.ExecuteOptions, callback func(reply *sqltypes.Result) error) error { +func (sq *verticalDiffTabletServer) StreamExecute(ctx context.Context, target *querypb.Target, sql string, bindVariables map[string]*querypb.BindVariable, transactionID int64, options *querypb.ExecuteOptions, callback func(reply *sqltypes.Result) error) error { if !strings.Contains(sql, "moving1") { sq.t.Errorf("Vertical Split Diff operation should only operate on the 'moving1' table. query: %v", sql) } diff --git a/proto/query.proto b/proto/query.proto index e55c95674b9..53525325378 100644 --- a/proto/query.proto +++ b/proto/query.proto @@ -288,6 +288,10 @@ message ExecuteOptions { READ_COMMITTED = 2; READ_UNCOMMITTED = 3; SERIALIZABLE = 4; + + // This is not an "official" transaction level but it will do a + // START TRANSACTION WITH CONSISTENT SNAPSHOT, READ ONLY + CONSISTENT_SNAPSHOT_READ_ONLY = 5; } TransactionIsolation transaction_isolation = 9; @@ -453,6 +457,7 @@ message StreamExecuteRequest { Target target = 3; BoundQuery query = 4; ExecuteOptions options = 5; + int64 transaction_id = 6; } // StreamExecuteResponse is the returned value from StreamExecute diff --git a/proto/tabletmanagerdata.proto b/proto/tabletmanagerdata.proto index 0898209b5a6..7606d568405 100644 --- a/proto/tabletmanagerdata.proto +++ b/proto/tabletmanagerdata.proto @@ -213,6 +213,18 @@ message ApplySchemaResponse { SchemaDefinition after_schema = 2; } +message LockTablesRequest { +} + +message LockTablesResponse { +} + +message UnlockTablesRequest { +} + +message UnlockTablesResponse { +} + message ExecuteFetchAsDbaRequest { bytes query = 1; string db_name = 2; @@ -280,6 +292,14 @@ message StartSlaveRequest { message StartSlaveResponse { } +message StartSlaveUntilAfterRequest { + string position = 1; + int64 wait_timeout = 2; +} + +message StartSlaveUntilAfterResponse { +} + message TabletExternallyReparentedRequest { // external_id is an string value that may be provided by an external // agent for tracking purposes. The tablet will emit this string in diff --git a/proto/tabletmanagerservice.proto b/proto/tabletmanagerservice.proto index e43de2938e1..ebc83056d86 100644 --- a/proto/tabletmanagerservice.proto +++ b/proto/tabletmanagerservice.proto @@ -68,6 +68,10 @@ service TabletManager { rpc ApplySchema(tabletmanagerdata.ApplySchemaRequest) returns (tabletmanagerdata.ApplySchemaResponse) {}; + rpc LockTables(tabletmanagerdata.LockTablesRequest) returns (tabletmanagerdata.LockTablesResponse) {}; + + rpc UnlockTables(tabletmanagerdata.UnlockTablesRequest) returns (tabletmanagerdata.UnlockTablesResponse) {}; + rpc ExecuteFetchAsDba(tabletmanagerdata.ExecuteFetchAsDbaRequest) returns (tabletmanagerdata.ExecuteFetchAsDbaResponse) {}; rpc ExecuteFetchAsAllPrivs(tabletmanagerdata.ExecuteFetchAsAllPrivsRequest) returns (tabletmanagerdata.ExecuteFetchAsAllPrivsResponse) {}; @@ -94,6 +98,10 @@ service TabletManager { // StartSlave starts the mysql replication rpc StartSlave(tabletmanagerdata.StartSlaveRequest) returns (tabletmanagerdata.StartSlaveResponse) {}; + // StartSlave starts the mysql replication until and including + // the provided position + rpc StartSlaveUntilAfter(tabletmanagerdata.StartSlaveUntilAfterRequest) returns (tabletmanagerdata.StartSlaveUntilAfterResponse) {}; + // TabletExternallyReparented tells a tablet that its underlying MySQL is // currently the master. It is only used in environments (tabletmanagerdata.such as Vitess+MoB) // in which MySQL is reparented by some agent external to Vitess, and then diff --git a/py/vtproto/query_pb2.py b/py/vtproto/query_pb2.py index fa74a6018bd..77b47ac9826 100644 --- a/py/vtproto/query_pb2.py +++ b/py/vtproto/query_pb2.py @@ -22,7 +22,7 @@ name='query.proto', package='query', syntax='proto3', - serialized_pb=_b('\n\x0bquery.proto\x12\x05query\x1a\x0etopodata.proto\x1a\x0bvtrpc.proto\"b\n\x06Target\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\x0c\n\x04\x63\x65ll\x18\x04 \x01(\t\"2\n\x0eVTGateCallerID\x12\x10\n\x08username\x18\x01 \x01(\t\x12\x0e\n\x06groups\x18\x02 \x03(\t\"@\n\nEventToken\x12\x11\n\ttimestamp\x18\x01 \x01(\x03\x12\r\n\x05shard\x18\x02 \x01(\t\x12\x10\n\x08position\x18\x03 \x01(\t\"1\n\x05Value\x12\x19\n\x04type\x18\x01 \x01(\x0e\x32\x0b.query.Type\x12\r\n\x05value\x18\x02 \x01(\x0c\"V\n\x0c\x42indVariable\x12\x19\n\x04type\x18\x01 \x01(\x0e\x32\x0b.query.Type\x12\r\n\x05value\x18\x02 \x01(\x0c\x12\x1c\n\x06values\x18\x03 \x03(\x0b\x32\x0c.query.Value\"\xa2\x01\n\nBoundQuery\x12\x0b\n\x03sql\x18\x01 \x01(\t\x12<\n\x0e\x62ind_variables\x18\x02 \x03(\x0b\x32$.query.BoundQuery.BindVariablesEntry\x1aI\n\x12\x42indVariablesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\"\n\x05value\x18\x02 \x01(\x0b\x32\x13.query.BindVariable:\x02\x38\x01\"\xe0\x04\n\x0e\x45xecuteOptions\x12\x1b\n\x13include_event_token\x18\x02 \x01(\x08\x12.\n\x13\x63ompare_event_token\x18\x03 \x01(\x0b\x32\x11.query.EventToken\x12=\n\x0fincluded_fields\x18\x04 \x01(\x0e\x32$.query.ExecuteOptions.IncludedFields\x12\x19\n\x11\x63lient_found_rows\x18\x05 \x01(\x08\x12\x30\n\x08workload\x18\x06 \x01(\x0e\x32\x1e.query.ExecuteOptions.Workload\x12\x18\n\x10sql_select_limit\x18\x08 \x01(\x03\x12I\n\x15transaction_isolation\x18\t \x01(\x0e\x32*.query.ExecuteOptions.TransactionIsolation\x12\x1d\n\x15skip_query_plan_cache\x18\n \x01(\x08\";\n\x0eIncludedFields\x12\x11\n\rTYPE_AND_NAME\x10\x00\x12\r\n\tTYPE_ONLY\x10\x01\x12\x07\n\x03\x41LL\x10\x02\"8\n\x08Workload\x12\x0f\n\x0bUNSPECIFIED\x10\x00\x12\x08\n\x04OLTP\x10\x01\x12\x08\n\x04OLAP\x10\x02\x12\x07\n\x03\x44\x42\x41\x10\x03\"t\n\x14TransactionIsolation\x12\x0b\n\x07\x44\x45\x46\x41ULT\x10\x00\x12\x13\n\x0fREPEATABLE_READ\x10\x01\x12\x12\n\x0eREAD_COMMITTED\x10\x02\x12\x14\n\x10READ_UNCOMMITTED\x10\x03\x12\x10\n\x0cSERIALIZABLE\x10\x04J\x04\x08\x01\x10\x02\"\xbf\x01\n\x05\x46ield\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x19\n\x04type\x18\x02 \x01(\x0e\x32\x0b.query.Type\x12\r\n\x05table\x18\x03 \x01(\t\x12\x11\n\torg_table\x18\x04 \x01(\t\x12\x10\n\x08\x64\x61tabase\x18\x05 \x01(\t\x12\x10\n\x08org_name\x18\x06 \x01(\t\x12\x15\n\rcolumn_length\x18\x07 \x01(\r\x12\x0f\n\x07\x63harset\x18\x08 \x01(\r\x12\x10\n\x08\x64\x65\x63imals\x18\t \x01(\r\x12\r\n\x05\x66lags\x18\n \x01(\r\"&\n\x03Row\x12\x0f\n\x07lengths\x18\x01 \x03(\x12\x12\x0e\n\x06values\x18\x02 \x01(\x0c\"G\n\x0cResultExtras\x12&\n\x0b\x65vent_token\x18\x01 \x01(\x0b\x32\x11.query.EventToken\x12\x0f\n\x07\x66resher\x18\x02 \x01(\x08\"\x94\x01\n\x0bQueryResult\x12\x1c\n\x06\x66ields\x18\x01 \x03(\x0b\x32\x0c.query.Field\x12\x15\n\rrows_affected\x18\x02 \x01(\x04\x12\x11\n\tinsert_id\x18\x03 \x01(\x04\x12\x18\n\x04rows\x18\x04 \x03(\x0b\x32\n.query.Row\x12#\n\x06\x65xtras\x18\x05 \x01(\x0b\x32\x13.query.ResultExtras\"-\n\x0cQueryWarning\x12\x0c\n\x04\x63ode\x18\x01 \x01(\r\x12\x0f\n\x07message\x18\x02 \x01(\t\"\xca\x02\n\x0bStreamEvent\x12\x30\n\nstatements\x18\x01 \x03(\x0b\x32\x1c.query.StreamEvent.Statement\x12&\n\x0b\x65vent_token\x18\x02 \x01(\x0b\x32\x11.query.EventToken\x1a\xe0\x01\n\tStatement\x12\x37\n\x08\x63\x61tegory\x18\x01 \x01(\x0e\x32%.query.StreamEvent.Statement.Category\x12\x12\n\ntable_name\x18\x02 \x01(\t\x12(\n\x12primary_key_fields\x18\x03 \x03(\x0b\x32\x0c.query.Field\x12&\n\x12primary_key_values\x18\x04 \x03(\x0b\x32\n.query.Row\x12\x0b\n\x03sql\x18\x05 \x01(\x0c\"\'\n\x08\x43\x61tegory\x12\t\n\x05\x45rror\x10\x00\x12\x07\n\x03\x44ML\x10\x01\x12\x07\n\x03\x44\x44L\x10\x02\"\xf3\x01\n\x0e\x45xecuteRequest\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 \n\x05query\x18\x04 \x01(\x0b\x32\x11.query.BoundQuery\x12\x16\n\x0etransaction_id\x18\x05 \x01(\x03\x12&\n\x07options\x18\x06 \x01(\x0b\x32\x15.query.ExecuteOptions\"5\n\x0f\x45xecuteResponse\x12\"\n\x06result\x18\x01 \x01(\x0b\x32\x12.query.QueryResult\"U\n\x0fResultWithError\x12\x1e\n\x05\x65rror\x18\x01 \x01(\x0b\x32\x0f.vtrpc.RPCError\x12\"\n\x06result\x18\x02 \x01(\x0b\x32\x12.query.QueryResult\"\x92\x02\n\x13\x45xecuteBatchRequest\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\"\n\x07queries\x18\x04 \x03(\x0b\x32\x11.query.BoundQuery\x12\x16\n\x0e\x61s_transaction\x18\x05 \x01(\x08\x12\x16\n\x0etransaction_id\x18\x06 \x01(\x03\x12&\n\x07options\x18\x07 \x01(\x0b\x32\x15.query.ExecuteOptions\";\n\x14\x45xecuteBatchResponse\x12#\n\x07results\x18\x01 \x03(\x0b\x32\x12.query.QueryResult\"\xe1\x01\n\x14StreamExecuteRequest\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 \n\x05query\x18\x04 \x01(\x0b\x32\x11.query.BoundQuery\x12&\n\x07options\x18\x05 \x01(\x0b\x32\x15.query.ExecuteOptions\";\n\x15StreamExecuteResponse\x12\"\n\x06result\x18\x01 \x01(\x0b\x32\x12.query.QueryResult\"\xb7\x01\n\x0c\x42\x65ginRequest\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&\n\x07options\x18\x04 \x01(\x0b\x32\x15.query.ExecuteOptions\"\'\n\rBeginResponse\x12\x16\n\x0etransaction_id\x18\x01 \x01(\x03\"\xa8\x01\n\rCommitRequest\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\x16\n\x0etransaction_id\x18\x04 \x01(\x03\"\x10\n\x0e\x43ommitResponse\"\xaa\x01\n\x0fRollbackRequest\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\x16\n\x0etransaction_id\x18\x04 \x01(\x03\"\x12\n\x10RollbackResponse\"\xb7\x01\n\x0ePrepareRequest\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\x16\n\x0etransaction_id\x18\x04 \x01(\x03\x12\x0c\n\x04\x64tid\x18\x05 \x01(\t\"\x11\n\x0fPrepareResponse\"\xa6\x01\n\x15\x43ommitPreparedRequest\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\x0c\n\x04\x64tid\x18\x04 \x01(\t\"\x18\n\x16\x43ommitPreparedResponse\"\xc0\x01\n\x17RollbackPreparedRequest\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\x16\n\x0etransaction_id\x18\x04 \x01(\x03\x12\x0c\n\x04\x64tid\x18\x05 \x01(\t\"\x1a\n\x18RollbackPreparedResponse\"\xce\x01\n\x18\x43reateTransactionRequest\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\x0c\n\x04\x64tid\x18\x04 \x01(\t\x12#\n\x0cparticipants\x18\x05 \x03(\x0b\x32\r.query.Target\"\x1b\n\x19\x43reateTransactionResponse\"\xbb\x01\n\x12StartCommitRequest\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\x16\n\x0etransaction_id\x18\x04 \x01(\x03\x12\x0c\n\x04\x64tid\x18\x05 \x01(\t\"\x15\n\x13StartCommitResponse\"\xbb\x01\n\x12SetRollbackRequest\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\x16\n\x0etransaction_id\x18\x04 \x01(\x03\x12\x0c\n\x04\x64tid\x18\x05 \x01(\t\"\x15\n\x13SetRollbackResponse\"\xab\x01\n\x1a\x43oncludeTransactionRequest\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\x0c\n\x04\x64tid\x18\x04 \x01(\t\"\x1d\n\x1b\x43oncludeTransactionResponse\"\xa7\x01\n\x16ReadTransactionRequest\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\x0c\n\x04\x64tid\x18\x04 \x01(\t\"G\n\x17ReadTransactionResponse\x12,\n\x08metadata\x18\x01 \x01(\x0b\x32\x1a.query.TransactionMetadata\"\xe0\x01\n\x13\x42\x65ginExecuteRequest\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 \n\x05query\x18\x04 \x01(\x0b\x32\x11.query.BoundQuery\x12&\n\x07options\x18\x05 \x01(\x0b\x32\x15.query.ExecuteOptions\"r\n\x14\x42\x65ginExecuteResponse\x12\x1e\n\x05\x65rror\x18\x01 \x01(\x0b\x32\x0f.vtrpc.RPCError\x12\"\n\x06result\x18\x02 \x01(\x0b\x32\x12.query.QueryResult\x12\x16\n\x0etransaction_id\x18\x03 \x01(\x03\"\xff\x01\n\x18\x42\x65ginExecuteBatchRequest\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\"\n\x07queries\x18\x04 \x03(\x0b\x32\x11.query.BoundQuery\x12\x16\n\x0e\x61s_transaction\x18\x05 \x01(\x08\x12&\n\x07options\x18\x06 \x01(\x0b\x32\x15.query.ExecuteOptions\"x\n\x19\x42\x65ginExecuteBatchResponse\x12\x1e\n\x05\x65rror\x18\x01 \x01(\x0b\x32\x0f.vtrpc.RPCError\x12#\n\x07results\x18\x02 \x03(\x0b\x32\x12.query.QueryResult\x12\x16\n\x0etransaction_id\x18\x03 \x01(\x03\"\xa5\x01\n\x14MessageStreamRequest\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\x0c\n\x04name\x18\x04 \x01(\t\";\n\x15MessageStreamResponse\x12\"\n\x06result\x18\x01 \x01(\x0b\x32\x12.query.QueryResult\"\xbd\x01\n\x11MessageAckRequest\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\x0c\n\x04name\x18\x04 \x01(\t\x12\x19\n\x03ids\x18\x05 \x03(\x0b\x32\x0c.query.Value\"8\n\x12MessageAckResponse\x12\"\n\x06result\x18\x01 \x01(\x0b\x32\x12.query.QueryResult\"\xe7\x02\n\x11SplitQueryRequest\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 \n\x05query\x18\x04 \x01(\x0b\x32\x11.query.BoundQuery\x12\x14\n\x0csplit_column\x18\x05 \x03(\t\x12\x13\n\x0bsplit_count\x18\x06 \x01(\x03\x12\x1f\n\x17num_rows_per_query_part\x18\x08 \x01(\x03\x12\x35\n\talgorithm\x18\t \x01(\x0e\x32\".query.SplitQueryRequest.Algorithm\",\n\tAlgorithm\x12\x10\n\x0c\x45QUAL_SPLITS\x10\x00\x12\r\n\tFULL_SCAN\x10\x01\"A\n\nQuerySplit\x12 \n\x05query\x18\x01 \x01(\x0b\x32\x11.query.BoundQuery\x12\x11\n\trow_count\x18\x02 \x01(\x03\"8\n\x12SplitQueryResponse\x12\"\n\x07queries\x18\x01 \x03(\x0b\x32\x11.query.QuerySplit\"\x15\n\x13StreamHealthRequest\"\xb6\x01\n\rRealtimeStats\x12\x14\n\x0chealth_error\x18\x01 \x01(\t\x12\x1d\n\x15seconds_behind_master\x18\x02 \x01(\r\x12\x1c\n\x14\x62inlog_players_count\x18\x03 \x01(\x05\x12\x32\n*seconds_behind_master_filtered_replication\x18\x04 \x01(\x03\x12\x11\n\tcpu_usage\x18\x05 \x01(\x01\x12\x0b\n\x03qps\x18\x06 \x01(\x01\"\x94\x01\n\x0e\x41ggregateStats\x12\x1c\n\x14healthy_tablet_count\x18\x01 \x01(\x05\x12\x1e\n\x16unhealthy_tablet_count\x18\x02 \x01(\x05\x12!\n\x19seconds_behind_master_min\x18\x03 \x01(\r\x12!\n\x19seconds_behind_master_max\x18\x04 \x01(\r\"\x81\x02\n\x14StreamHealthResponse\x12\x1d\n\x06target\x18\x01 \x01(\x0b\x32\r.query.Target\x12\x0f\n\x07serving\x18\x02 \x01(\x08\x12.\n&tablet_externally_reparented_timestamp\x18\x03 \x01(\x03\x12,\n\x0erealtime_stats\x18\x04 \x01(\x0b\x32\x14.query.RealtimeStats\x12.\n\x0f\x61ggregate_stats\x18\x06 \x01(\x0b\x32\x15.query.AggregateStats\x12+\n\x0ctablet_alias\x18\x05 \x01(\x0b\x32\x15.topodata.TabletAlias\"\xbb\x01\n\x13UpdateStreamRequest\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\x11\n\ttimestamp\x18\x05 \x01(\x03\"9\n\x14UpdateStreamResponse\x12!\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x12.query.StreamEvent\"\x86\x01\n\x13TransactionMetadata\x12\x0c\n\x04\x64tid\x18\x01 \x01(\t\x12&\n\x05state\x18\x02 \x01(\x0e\x32\x17.query.TransactionState\x12\x14\n\x0ctime_created\x18\x03 \x01(\x03\x12#\n\x0cparticipants\x18\x04 \x03(\x0b\x32\r.query.Target*\x92\x03\n\tMySqlFlag\x12\t\n\x05\x45MPTY\x10\x00\x12\x11\n\rNOT_NULL_FLAG\x10\x01\x12\x10\n\x0cPRI_KEY_FLAG\x10\x02\x12\x13\n\x0fUNIQUE_KEY_FLAG\x10\x04\x12\x15\n\x11MULTIPLE_KEY_FLAG\x10\x08\x12\r\n\tBLOB_FLAG\x10\x10\x12\x11\n\rUNSIGNED_FLAG\x10 \x12\x11\n\rZEROFILL_FLAG\x10@\x12\x10\n\x0b\x42INARY_FLAG\x10\x80\x01\x12\x0e\n\tENUM_FLAG\x10\x80\x02\x12\x18\n\x13\x41UTO_INCREMENT_FLAG\x10\x80\x04\x12\x13\n\x0eTIMESTAMP_FLAG\x10\x80\x08\x12\r\n\x08SET_FLAG\x10\x80\x10\x12\x1a\n\x15NO_DEFAULT_VALUE_FLAG\x10\x80 \x12\x17\n\x12ON_UPDATE_NOW_FLAG\x10\x80@\x12\x0e\n\x08NUM_FLAG\x10\x80\x80\x02\x12\x13\n\rPART_KEY_FLAG\x10\x80\x80\x01\x12\x10\n\nGROUP_FLAG\x10\x80\x80\x02\x12\x11\n\x0bUNIQUE_FLAG\x10\x80\x80\x04\x12\x11\n\x0b\x42INCMP_FLAG\x10\x80\x80\x08\x1a\x02\x10\x01*k\n\x04\x46lag\x12\x08\n\x04NONE\x10\x00\x12\x0f\n\nISINTEGRAL\x10\x80\x02\x12\x0f\n\nISUNSIGNED\x10\x80\x04\x12\x0c\n\x07ISFLOAT\x10\x80\x08\x12\r\n\x08ISQUOTED\x10\x80\x10\x12\x0b\n\x06ISTEXT\x10\x80 \x12\r\n\x08ISBINARY\x10\x80@*\x99\x03\n\x04Type\x12\r\n\tNULL_TYPE\x10\x00\x12\t\n\x04INT8\x10\x81\x02\x12\n\n\x05UINT8\x10\x82\x06\x12\n\n\x05INT16\x10\x83\x02\x12\x0b\n\x06UINT16\x10\x84\x06\x12\n\n\x05INT24\x10\x85\x02\x12\x0b\n\x06UINT24\x10\x86\x06\x12\n\n\x05INT32\x10\x87\x02\x12\x0b\n\x06UINT32\x10\x88\x06\x12\n\n\x05INT64\x10\x89\x02\x12\x0b\n\x06UINT64\x10\x8a\x06\x12\x0c\n\x07\x46LOAT32\x10\x8b\x08\x12\x0c\n\x07\x46LOAT64\x10\x8c\x08\x12\x0e\n\tTIMESTAMP\x10\x8d\x10\x12\t\n\x04\x44\x41TE\x10\x8e\x10\x12\t\n\x04TIME\x10\x8f\x10\x12\r\n\x08\x44\x41TETIME\x10\x90\x10\x12\t\n\x04YEAR\x10\x91\x06\x12\x0b\n\x07\x44\x45\x43IMAL\x10\x12\x12\t\n\x04TEXT\x10\x93\x30\x12\t\n\x04\x42LOB\x10\x94P\x12\x0c\n\x07VARCHAR\x10\x95\x30\x12\x0e\n\tVARBINARY\x10\x96P\x12\t\n\x04\x43HAR\x10\x97\x30\x12\x0b\n\x06\x42INARY\x10\x98P\x12\x08\n\x03\x42IT\x10\x99\x10\x12\t\n\x04\x45NUM\x10\x9a\x10\x12\x08\n\x03SET\x10\x9b\x10\x12\t\n\x05TUPLE\x10\x1c\x12\r\n\x08GEOMETRY\x10\x9d\x10\x12\t\n\x04JSON\x10\x9e\x10\x12\x0e\n\nEXPRESSION\x10\x1f*F\n\x10TransactionState\x12\x0b\n\x07UNKNOWN\x10\x00\x12\x0b\n\x07PREPARE\x10\x01\x12\n\n\x06\x43OMMIT\x10\x02\x12\x0c\n\x08ROLLBACK\x10\x03\x42\x35\n\x0fio.vitess.protoZ\"vitess.io/vitess/go/vt/proto/queryb\x06proto3') + serialized_pb=_b('\n\x0bquery.proto\x12\x05query\x1a\x0etopodata.proto\x1a\x0bvtrpc.proto\"b\n\x06Target\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\x0c\n\x04\x63\x65ll\x18\x04 \x01(\t\"2\n\x0eVTGateCallerID\x12\x10\n\x08username\x18\x01 \x01(\t\x12\x0e\n\x06groups\x18\x02 \x03(\t\"@\n\nEventToken\x12\x11\n\ttimestamp\x18\x01 \x01(\x03\x12\r\n\x05shard\x18\x02 \x01(\t\x12\x10\n\x08position\x18\x03 \x01(\t\"1\n\x05Value\x12\x19\n\x04type\x18\x01 \x01(\x0e\x32\x0b.query.Type\x12\r\n\x05value\x18\x02 \x01(\x0c\"V\n\x0c\x42indVariable\x12\x19\n\x04type\x18\x01 \x01(\x0e\x32\x0b.query.Type\x12\r\n\x05value\x18\x02 \x01(\x0c\x12\x1c\n\x06values\x18\x03 \x03(\x0b\x32\x0c.query.Value\"\xa2\x01\n\nBoundQuery\x12\x0b\n\x03sql\x18\x01 \x01(\t\x12<\n\x0e\x62ind_variables\x18\x02 \x03(\x0b\x32$.query.BoundQuery.BindVariablesEntry\x1aI\n\x12\x42indVariablesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\"\n\x05value\x18\x02 \x01(\x0b\x32\x13.query.BindVariable:\x02\x38\x01\"\x84\x05\n\x0e\x45xecuteOptions\x12\x1b\n\x13include_event_token\x18\x02 \x01(\x08\x12.\n\x13\x63ompare_event_token\x18\x03 \x01(\x0b\x32\x11.query.EventToken\x12=\n\x0fincluded_fields\x18\x04 \x01(\x0e\x32$.query.ExecuteOptions.IncludedFields\x12\x19\n\x11\x63lient_found_rows\x18\x05 \x01(\x08\x12\x30\n\x08workload\x18\x06 \x01(\x0e\x32\x1e.query.ExecuteOptions.Workload\x12\x18\n\x10sql_select_limit\x18\x08 \x01(\x03\x12I\n\x15transaction_isolation\x18\t \x01(\x0e\x32*.query.ExecuteOptions.TransactionIsolation\x12\x1d\n\x15skip_query_plan_cache\x18\n \x01(\x08\";\n\x0eIncludedFields\x12\x11\n\rTYPE_AND_NAME\x10\x00\x12\r\n\tTYPE_ONLY\x10\x01\x12\x07\n\x03\x41LL\x10\x02\"8\n\x08Workload\x12\x0f\n\x0bUNSPECIFIED\x10\x00\x12\x08\n\x04OLTP\x10\x01\x12\x08\n\x04OLAP\x10\x02\x12\x07\n\x03\x44\x42\x41\x10\x03\"\x97\x01\n\x14TransactionIsolation\x12\x0b\n\x07\x44\x45\x46\x41ULT\x10\x00\x12\x13\n\x0fREPEATABLE_READ\x10\x01\x12\x12\n\x0eREAD_COMMITTED\x10\x02\x12\x14\n\x10READ_UNCOMMITTED\x10\x03\x12\x10\n\x0cSERIALIZABLE\x10\x04\x12!\n\x1d\x43ONSISTENT_SNAPSHOT_READ_ONLY\x10\x05J\x04\x08\x01\x10\x02\"\xbf\x01\n\x05\x46ield\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x19\n\x04type\x18\x02 \x01(\x0e\x32\x0b.query.Type\x12\r\n\x05table\x18\x03 \x01(\t\x12\x11\n\torg_table\x18\x04 \x01(\t\x12\x10\n\x08\x64\x61tabase\x18\x05 \x01(\t\x12\x10\n\x08org_name\x18\x06 \x01(\t\x12\x15\n\rcolumn_length\x18\x07 \x01(\r\x12\x0f\n\x07\x63harset\x18\x08 \x01(\r\x12\x10\n\x08\x64\x65\x63imals\x18\t \x01(\r\x12\r\n\x05\x66lags\x18\n \x01(\r\"&\n\x03Row\x12\x0f\n\x07lengths\x18\x01 \x03(\x12\x12\x0e\n\x06values\x18\x02 \x01(\x0c\"G\n\x0cResultExtras\x12&\n\x0b\x65vent_token\x18\x01 \x01(\x0b\x32\x11.query.EventToken\x12\x0f\n\x07\x66resher\x18\x02 \x01(\x08\"\x94\x01\n\x0bQueryResult\x12\x1c\n\x06\x66ields\x18\x01 \x03(\x0b\x32\x0c.query.Field\x12\x15\n\rrows_affected\x18\x02 \x01(\x04\x12\x11\n\tinsert_id\x18\x03 \x01(\x04\x12\x18\n\x04rows\x18\x04 \x03(\x0b\x32\n.query.Row\x12#\n\x06\x65xtras\x18\x05 \x01(\x0b\x32\x13.query.ResultExtras\"-\n\x0cQueryWarning\x12\x0c\n\x04\x63ode\x18\x01 \x01(\r\x12\x0f\n\x07message\x18\x02 \x01(\t\"\xca\x02\n\x0bStreamEvent\x12\x30\n\nstatements\x18\x01 \x03(\x0b\x32\x1c.query.StreamEvent.Statement\x12&\n\x0b\x65vent_token\x18\x02 \x01(\x0b\x32\x11.query.EventToken\x1a\xe0\x01\n\tStatement\x12\x37\n\x08\x63\x61tegory\x18\x01 \x01(\x0e\x32%.query.StreamEvent.Statement.Category\x12\x12\n\ntable_name\x18\x02 \x01(\t\x12(\n\x12primary_key_fields\x18\x03 \x03(\x0b\x32\x0c.query.Field\x12&\n\x12primary_key_values\x18\x04 \x03(\x0b\x32\n.query.Row\x12\x0b\n\x03sql\x18\x05 \x01(\x0c\"\'\n\x08\x43\x61tegory\x12\t\n\x05\x45rror\x10\x00\x12\x07\n\x03\x44ML\x10\x01\x12\x07\n\x03\x44\x44L\x10\x02\"\xf3\x01\n\x0e\x45xecuteRequest\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 \n\x05query\x18\x04 \x01(\x0b\x32\x11.query.BoundQuery\x12\x16\n\x0etransaction_id\x18\x05 \x01(\x03\x12&\n\x07options\x18\x06 \x01(\x0b\x32\x15.query.ExecuteOptions\"5\n\x0f\x45xecuteResponse\x12\"\n\x06result\x18\x01 \x01(\x0b\x32\x12.query.QueryResult\"U\n\x0fResultWithError\x12\x1e\n\x05\x65rror\x18\x01 \x01(\x0b\x32\x0f.vtrpc.RPCError\x12\"\n\x06result\x18\x02 \x01(\x0b\x32\x12.query.QueryResult\"\x92\x02\n\x13\x45xecuteBatchRequest\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\"\n\x07queries\x18\x04 \x03(\x0b\x32\x11.query.BoundQuery\x12\x16\n\x0e\x61s_transaction\x18\x05 \x01(\x08\x12\x16\n\x0etransaction_id\x18\x06 \x01(\x03\x12&\n\x07options\x18\x07 \x01(\x0b\x32\x15.query.ExecuteOptions\";\n\x14\x45xecuteBatchResponse\x12#\n\x07results\x18\x01 \x03(\x0b\x32\x12.query.QueryResult\"\xf9\x01\n\x14StreamExecuteRequest\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 \n\x05query\x18\x04 \x01(\x0b\x32\x11.query.BoundQuery\x12&\n\x07options\x18\x05 \x01(\x0b\x32\x15.query.ExecuteOptions\x12\x16\n\x0etransaction_id\x18\x06 \x01(\x03\";\n\x15StreamExecuteResponse\x12\"\n\x06result\x18\x01 \x01(\x0b\x32\x12.query.QueryResult\"\xb7\x01\n\x0c\x42\x65ginRequest\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&\n\x07options\x18\x04 \x01(\x0b\x32\x15.query.ExecuteOptions\"\'\n\rBeginResponse\x12\x16\n\x0etransaction_id\x18\x01 \x01(\x03\"\xa8\x01\n\rCommitRequest\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\x16\n\x0etransaction_id\x18\x04 \x01(\x03\"\x10\n\x0e\x43ommitResponse\"\xaa\x01\n\x0fRollbackRequest\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\x16\n\x0etransaction_id\x18\x04 \x01(\x03\"\x12\n\x10RollbackResponse\"\xb7\x01\n\x0ePrepareRequest\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\x16\n\x0etransaction_id\x18\x04 \x01(\x03\x12\x0c\n\x04\x64tid\x18\x05 \x01(\t\"\x11\n\x0fPrepareResponse\"\xa6\x01\n\x15\x43ommitPreparedRequest\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\x0c\n\x04\x64tid\x18\x04 \x01(\t\"\x18\n\x16\x43ommitPreparedResponse\"\xc0\x01\n\x17RollbackPreparedRequest\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\x16\n\x0etransaction_id\x18\x04 \x01(\x03\x12\x0c\n\x04\x64tid\x18\x05 \x01(\t\"\x1a\n\x18RollbackPreparedResponse\"\xce\x01\n\x18\x43reateTransactionRequest\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\x0c\n\x04\x64tid\x18\x04 \x01(\t\x12#\n\x0cparticipants\x18\x05 \x03(\x0b\x32\r.query.Target\"\x1b\n\x19\x43reateTransactionResponse\"\xbb\x01\n\x12StartCommitRequest\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\x16\n\x0etransaction_id\x18\x04 \x01(\x03\x12\x0c\n\x04\x64tid\x18\x05 \x01(\t\"\x15\n\x13StartCommitResponse\"\xbb\x01\n\x12SetRollbackRequest\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\x16\n\x0etransaction_id\x18\x04 \x01(\x03\x12\x0c\n\x04\x64tid\x18\x05 \x01(\t\"\x15\n\x13SetRollbackResponse\"\xab\x01\n\x1a\x43oncludeTransactionRequest\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\x0c\n\x04\x64tid\x18\x04 \x01(\t\"\x1d\n\x1b\x43oncludeTransactionResponse\"\xa7\x01\n\x16ReadTransactionRequest\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\x0c\n\x04\x64tid\x18\x04 \x01(\t\"G\n\x17ReadTransactionResponse\x12,\n\x08metadata\x18\x01 \x01(\x0b\x32\x1a.query.TransactionMetadata\"\xe0\x01\n\x13\x42\x65ginExecuteRequest\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 \n\x05query\x18\x04 \x01(\x0b\x32\x11.query.BoundQuery\x12&\n\x07options\x18\x05 \x01(\x0b\x32\x15.query.ExecuteOptions\"r\n\x14\x42\x65ginExecuteResponse\x12\x1e\n\x05\x65rror\x18\x01 \x01(\x0b\x32\x0f.vtrpc.RPCError\x12\"\n\x06result\x18\x02 \x01(\x0b\x32\x12.query.QueryResult\x12\x16\n\x0etransaction_id\x18\x03 \x01(\x03\"\xff\x01\n\x18\x42\x65ginExecuteBatchRequest\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\"\n\x07queries\x18\x04 \x03(\x0b\x32\x11.query.BoundQuery\x12\x16\n\x0e\x61s_transaction\x18\x05 \x01(\x08\x12&\n\x07options\x18\x06 \x01(\x0b\x32\x15.query.ExecuteOptions\"x\n\x19\x42\x65ginExecuteBatchResponse\x12\x1e\n\x05\x65rror\x18\x01 \x01(\x0b\x32\x0f.vtrpc.RPCError\x12#\n\x07results\x18\x02 \x03(\x0b\x32\x12.query.QueryResult\x12\x16\n\x0etransaction_id\x18\x03 \x01(\x03\"\xa5\x01\n\x14MessageStreamRequest\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\x0c\n\x04name\x18\x04 \x01(\t\";\n\x15MessageStreamResponse\x12\"\n\x06result\x18\x01 \x01(\x0b\x32\x12.query.QueryResult\"\xbd\x01\n\x11MessageAckRequest\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\x0c\n\x04name\x18\x04 \x01(\t\x12\x19\n\x03ids\x18\x05 \x03(\x0b\x32\x0c.query.Value\"8\n\x12MessageAckResponse\x12\"\n\x06result\x18\x01 \x01(\x0b\x32\x12.query.QueryResult\"\xe7\x02\n\x11SplitQueryRequest\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 \n\x05query\x18\x04 \x01(\x0b\x32\x11.query.BoundQuery\x12\x14\n\x0csplit_column\x18\x05 \x03(\t\x12\x13\n\x0bsplit_count\x18\x06 \x01(\x03\x12\x1f\n\x17num_rows_per_query_part\x18\x08 \x01(\x03\x12\x35\n\talgorithm\x18\t \x01(\x0e\x32\".query.SplitQueryRequest.Algorithm\",\n\tAlgorithm\x12\x10\n\x0c\x45QUAL_SPLITS\x10\x00\x12\r\n\tFULL_SCAN\x10\x01\"A\n\nQuerySplit\x12 \n\x05query\x18\x01 \x01(\x0b\x32\x11.query.BoundQuery\x12\x11\n\trow_count\x18\x02 \x01(\x03\"8\n\x12SplitQueryResponse\x12\"\n\x07queries\x18\x01 \x03(\x0b\x32\x11.query.QuerySplit\"\x15\n\x13StreamHealthRequest\"\xb6\x01\n\rRealtimeStats\x12\x14\n\x0chealth_error\x18\x01 \x01(\t\x12\x1d\n\x15seconds_behind_master\x18\x02 \x01(\r\x12\x1c\n\x14\x62inlog_players_count\x18\x03 \x01(\x05\x12\x32\n*seconds_behind_master_filtered_replication\x18\x04 \x01(\x03\x12\x11\n\tcpu_usage\x18\x05 \x01(\x01\x12\x0b\n\x03qps\x18\x06 \x01(\x01\"\x94\x01\n\x0e\x41ggregateStats\x12\x1c\n\x14healthy_tablet_count\x18\x01 \x01(\x05\x12\x1e\n\x16unhealthy_tablet_count\x18\x02 \x01(\x05\x12!\n\x19seconds_behind_master_min\x18\x03 \x01(\r\x12!\n\x19seconds_behind_master_max\x18\x04 \x01(\r\"\x81\x02\n\x14StreamHealthResponse\x12\x1d\n\x06target\x18\x01 \x01(\x0b\x32\r.query.Target\x12\x0f\n\x07serving\x18\x02 \x01(\x08\x12.\n&tablet_externally_reparented_timestamp\x18\x03 \x01(\x03\x12,\n\x0erealtime_stats\x18\x04 \x01(\x0b\x32\x14.query.RealtimeStats\x12.\n\x0f\x61ggregate_stats\x18\x06 \x01(\x0b\x32\x15.query.AggregateStats\x12+\n\x0ctablet_alias\x18\x05 \x01(\x0b\x32\x15.topodata.TabletAlias\"\xbb\x01\n\x13UpdateStreamRequest\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\x11\n\ttimestamp\x18\x05 \x01(\x03\"9\n\x14UpdateStreamResponse\x12!\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x12.query.StreamEvent\"\x86\x01\n\x13TransactionMetadata\x12\x0c\n\x04\x64tid\x18\x01 \x01(\t\x12&\n\x05state\x18\x02 \x01(\x0e\x32\x17.query.TransactionState\x12\x14\n\x0ctime_created\x18\x03 \x01(\x03\x12#\n\x0cparticipants\x18\x04 \x03(\x0b\x32\r.query.Target*\x92\x03\n\tMySqlFlag\x12\t\n\x05\x45MPTY\x10\x00\x12\x11\n\rNOT_NULL_FLAG\x10\x01\x12\x10\n\x0cPRI_KEY_FLAG\x10\x02\x12\x13\n\x0fUNIQUE_KEY_FLAG\x10\x04\x12\x15\n\x11MULTIPLE_KEY_FLAG\x10\x08\x12\r\n\tBLOB_FLAG\x10\x10\x12\x11\n\rUNSIGNED_FLAG\x10 \x12\x11\n\rZEROFILL_FLAG\x10@\x12\x10\n\x0b\x42INARY_FLAG\x10\x80\x01\x12\x0e\n\tENUM_FLAG\x10\x80\x02\x12\x18\n\x13\x41UTO_INCREMENT_FLAG\x10\x80\x04\x12\x13\n\x0eTIMESTAMP_FLAG\x10\x80\x08\x12\r\n\x08SET_FLAG\x10\x80\x10\x12\x1a\n\x15NO_DEFAULT_VALUE_FLAG\x10\x80 \x12\x17\n\x12ON_UPDATE_NOW_FLAG\x10\x80@\x12\x0e\n\x08NUM_FLAG\x10\x80\x80\x02\x12\x13\n\rPART_KEY_FLAG\x10\x80\x80\x01\x12\x10\n\nGROUP_FLAG\x10\x80\x80\x02\x12\x11\n\x0bUNIQUE_FLAG\x10\x80\x80\x04\x12\x11\n\x0b\x42INCMP_FLAG\x10\x80\x80\x08\x1a\x02\x10\x01*k\n\x04\x46lag\x12\x08\n\x04NONE\x10\x00\x12\x0f\n\nISINTEGRAL\x10\x80\x02\x12\x0f\n\nISUNSIGNED\x10\x80\x04\x12\x0c\n\x07ISFLOAT\x10\x80\x08\x12\r\n\x08ISQUOTED\x10\x80\x10\x12\x0b\n\x06ISTEXT\x10\x80 \x12\r\n\x08ISBINARY\x10\x80@*\x99\x03\n\x04Type\x12\r\n\tNULL_TYPE\x10\x00\x12\t\n\x04INT8\x10\x81\x02\x12\n\n\x05UINT8\x10\x82\x06\x12\n\n\x05INT16\x10\x83\x02\x12\x0b\n\x06UINT16\x10\x84\x06\x12\n\n\x05INT24\x10\x85\x02\x12\x0b\n\x06UINT24\x10\x86\x06\x12\n\n\x05INT32\x10\x87\x02\x12\x0b\n\x06UINT32\x10\x88\x06\x12\n\n\x05INT64\x10\x89\x02\x12\x0b\n\x06UINT64\x10\x8a\x06\x12\x0c\n\x07\x46LOAT32\x10\x8b\x08\x12\x0c\n\x07\x46LOAT64\x10\x8c\x08\x12\x0e\n\tTIMESTAMP\x10\x8d\x10\x12\t\n\x04\x44\x41TE\x10\x8e\x10\x12\t\n\x04TIME\x10\x8f\x10\x12\r\n\x08\x44\x41TETIME\x10\x90\x10\x12\t\n\x04YEAR\x10\x91\x06\x12\x0b\n\x07\x44\x45\x43IMAL\x10\x12\x12\t\n\x04TEXT\x10\x93\x30\x12\t\n\x04\x42LOB\x10\x94P\x12\x0c\n\x07VARCHAR\x10\x95\x30\x12\x0e\n\tVARBINARY\x10\x96P\x12\t\n\x04\x43HAR\x10\x97\x30\x12\x0b\n\x06\x42INARY\x10\x98P\x12\x08\n\x03\x42IT\x10\x99\x10\x12\t\n\x04\x45NUM\x10\x9a\x10\x12\x08\n\x03SET\x10\x9b\x10\x12\t\n\x05TUPLE\x10\x1c\x12\r\n\x08GEOMETRY\x10\x9d\x10\x12\t\n\x04JSON\x10\x9e\x10\x12\x0e\n\nEXPRESSION\x10\x1f*F\n\x10TransactionState\x12\x0b\n\x07UNKNOWN\x10\x00\x12\x0b\n\x07PREPARE\x10\x01\x12\n\n\x06\x43OMMIT\x10\x02\x12\x0c\n\x08ROLLBACK\x10\x03\x42\x35\n\x0fio.vitess.protoZ\"vitess.io/vitess/go/vt/proto/queryb\x06proto3') , dependencies=[topodata__pb2.DESCRIPTOR,vtrpc__pb2.DESCRIPTOR,]) @@ -115,8 +115,8 @@ ], containing_type=None, options=_descriptor._ParseOptions(descriptor_pb2.EnumOptions(), _b('\020\001')), - serialized_start=8076, - serialized_end=8478, + serialized_start=8136, + serialized_end=8538, ) _sym_db.RegisterEnumDescriptor(_MYSQLFLAG) @@ -158,8 +158,8 @@ ], containing_type=None, options=None, - serialized_start=8480, - serialized_end=8587, + serialized_start=8540, + serialized_end=8647, ) _sym_db.RegisterEnumDescriptor(_FLAG) @@ -301,8 +301,8 @@ ], containing_type=None, options=None, - serialized_start=8590, - serialized_end=8999, + serialized_start=8650, + serialized_end=9059, ) _sym_db.RegisterEnumDescriptor(_TYPE) @@ -332,8 +332,8 @@ ], containing_type=None, options=None, - serialized_start=9001, - serialized_end=9071, + serialized_start=9061, + serialized_end=9131, ) _sym_db.RegisterEnumDescriptor(_TRANSACTIONSTATE) @@ -485,11 +485,15 @@ name='SERIALIZABLE', index=4, number=4, options=None, type=None), + _descriptor.EnumValueDescriptor( + name='CONSISTENT_SNAPSHOT_READ_ONLY', index=5, number=5, + options=None, + type=None), ], containing_type=None, options=None, - serialized_start=1060, - serialized_end=1176, + serialized_start=1061, + serialized_end=1212, ) _sym_db.RegisterEnumDescriptor(_EXECUTEOPTIONS_TRANSACTIONISOLATION) @@ -514,8 +518,8 @@ ], containing_type=None, options=None, - serialized_start=1981, - serialized_end=2020, + serialized_start=2017, + serialized_end=2056, ) _sym_db.RegisterEnumDescriptor(_STREAMEVENT_STATEMENT_CATEGORY) @@ -536,8 +540,8 @@ ], containing_type=None, options=None, - serialized_start=6899, - serialized_end=6943, + serialized_start=6959, + serialized_end=7003, ) _sym_db.RegisterEnumDescriptor(_SPLITQUERYREQUEST_ALGORITHM) @@ -914,7 +918,7 @@ oneofs=[ ], serialized_start=574, - serialized_end=1182, + serialized_end=1218, ) @@ -1007,8 +1011,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=1185, - serialized_end=1376, + serialized_start=1221, + serialized_end=1412, ) @@ -1045,8 +1049,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=1378, - serialized_end=1416, + serialized_start=1414, + serialized_end=1452, ) @@ -1083,8 +1087,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=1418, - serialized_end=1489, + serialized_start=1454, + serialized_end=1525, ) @@ -1142,8 +1146,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=1492, - serialized_end=1640, + serialized_start=1528, + serialized_end=1676, ) @@ -1180,8 +1184,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=1642, - serialized_end=1687, + serialized_start=1678, + serialized_end=1723, ) @@ -1240,8 +1244,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=1796, - serialized_end=2020, + serialized_start=1832, + serialized_end=2056, ) _STREAMEVENT = _descriptor.Descriptor( @@ -1277,8 +1281,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=1690, - serialized_end=2020, + serialized_start=1726, + serialized_end=2056, ) @@ -1343,8 +1347,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=2023, - serialized_end=2266, + serialized_start=2059, + serialized_end=2302, ) @@ -1374,8 +1378,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=2268, - serialized_end=2321, + serialized_start=2304, + serialized_end=2357, ) @@ -1412,8 +1416,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=2323, - serialized_end=2408, + serialized_start=2359, + serialized_end=2444, ) @@ -1485,8 +1489,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=2411, - serialized_end=2685, + serialized_start=2447, + serialized_end=2721, ) @@ -1516,8 +1520,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=2687, - serialized_end=2746, + serialized_start=2723, + serialized_end=2782, ) @@ -1563,6 +1567,13 @@ message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='transaction_id', full_name='query.StreamExecuteRequest.transaction_id', index=5, + number=6, 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), ], extensions=[ ], @@ -1575,8 +1586,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=2749, - serialized_end=2974, + serialized_start=2785, + serialized_end=3034, ) @@ -1606,8 +1617,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=2976, - serialized_end=3035, + serialized_start=3036, + serialized_end=3095, ) @@ -1658,8 +1669,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=3038, - serialized_end=3221, + serialized_start=3098, + serialized_end=3281, ) @@ -1689,8 +1700,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=3223, - serialized_end=3262, + serialized_start=3283, + serialized_end=3322, ) @@ -1741,8 +1752,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=3265, - serialized_end=3433, + serialized_start=3325, + serialized_end=3493, ) @@ -1765,8 +1776,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=3435, - serialized_end=3451, + serialized_start=3495, + serialized_end=3511, ) @@ -1817,8 +1828,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=3454, - serialized_end=3624, + serialized_start=3514, + serialized_end=3684, ) @@ -1841,8 +1852,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=3626, - serialized_end=3644, + serialized_start=3686, + serialized_end=3704, ) @@ -1900,8 +1911,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=3647, - serialized_end=3830, + serialized_start=3707, + serialized_end=3890, ) @@ -1924,8 +1935,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=3832, - serialized_end=3849, + serialized_start=3892, + serialized_end=3909, ) @@ -1976,8 +1987,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=3852, - serialized_end=4018, + serialized_start=3912, + serialized_end=4078, ) @@ -2000,8 +2011,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=4020, - serialized_end=4044, + serialized_start=4080, + serialized_end=4104, ) @@ -2059,8 +2070,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=4047, - serialized_end=4239, + serialized_start=4107, + serialized_end=4299, ) @@ -2083,8 +2094,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=4241, - serialized_end=4267, + serialized_start=4301, + serialized_end=4327, ) @@ -2142,8 +2153,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=4270, - serialized_end=4476, + serialized_start=4330, + serialized_end=4536, ) @@ -2166,8 +2177,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=4478, - serialized_end=4505, + serialized_start=4538, + serialized_end=4565, ) @@ -2225,8 +2236,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=4508, - serialized_end=4695, + serialized_start=4568, + serialized_end=4755, ) @@ -2249,8 +2260,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=4697, - serialized_end=4718, + serialized_start=4757, + serialized_end=4778, ) @@ -2308,8 +2319,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=4721, - serialized_end=4908, + serialized_start=4781, + serialized_end=4968, ) @@ -2332,8 +2343,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=4910, - serialized_end=4931, + serialized_start=4970, + serialized_end=4991, ) @@ -2384,8 +2395,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=4934, - serialized_end=5105, + serialized_start=4994, + serialized_end=5165, ) @@ -2408,8 +2419,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=5107, - serialized_end=5136, + serialized_start=5167, + serialized_end=5196, ) @@ -2460,8 +2471,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=5139, - serialized_end=5306, + serialized_start=5199, + serialized_end=5366, ) @@ -2491,8 +2502,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=5308, - serialized_end=5379, + serialized_start=5368, + serialized_end=5439, ) @@ -2550,8 +2561,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=5382, - serialized_end=5606, + serialized_start=5442, + serialized_end=5666, ) @@ -2595,8 +2606,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=5608, - serialized_end=5722, + serialized_start=5668, + serialized_end=5782, ) @@ -2661,8 +2672,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=5725, - serialized_end=5980, + serialized_start=5785, + serialized_end=6040, ) @@ -2706,8 +2717,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=5982, - serialized_end=6102, + serialized_start=6042, + serialized_end=6162, ) @@ -2758,8 +2769,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=6105, - serialized_end=6270, + serialized_start=6165, + serialized_end=6330, ) @@ -2789,8 +2800,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=6272, - serialized_end=6331, + serialized_start=6332, + serialized_end=6391, ) @@ -2848,8 +2859,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=6334, - serialized_end=6523, + serialized_start=6394, + serialized_end=6583, ) @@ -2879,8 +2890,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=6525, - serialized_end=6581, + serialized_start=6585, + serialized_end=6641, ) @@ -2960,8 +2971,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=6584, - serialized_end=6943, + serialized_start=6644, + serialized_end=7003, ) @@ -2998,8 +3009,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=6945, - serialized_end=7010, + serialized_start=7005, + serialized_end=7070, ) @@ -3029,8 +3040,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=7012, - serialized_end=7068, + serialized_start=7072, + serialized_end=7128, ) @@ -3053,8 +3064,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=7070, - serialized_end=7091, + serialized_start=7130, + serialized_end=7151, ) @@ -3119,8 +3130,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=7094, - serialized_end=7276, + serialized_start=7154, + serialized_end=7336, ) @@ -3171,8 +3182,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=7279, - serialized_end=7427, + serialized_start=7339, + serialized_end=7487, ) @@ -3237,8 +3248,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=7430, - serialized_end=7687, + serialized_start=7490, + serialized_end=7747, ) @@ -3296,8 +3307,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=7690, - serialized_end=7877, + serialized_start=7750, + serialized_end=7937, ) @@ -3327,8 +3338,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=7879, - serialized_end=7936, + serialized_start=7939, + serialized_end=7996, ) @@ -3379,8 +3390,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=7939, - serialized_end=8073, + serialized_start=7999, + serialized_end=8133, ) _TARGET.fields_by_name['tablet_type'].enum_type = topodata__pb2._TABLETTYPE diff --git a/py/vtproto/tabletmanagerdata_pb2.py b/py/vtproto/tabletmanagerdata_pb2.py index a728e5b07fb..62f4a97b3b1 100644 --- a/py/vtproto/tabletmanagerdata_pb2.py +++ b/py/vtproto/tabletmanagerdata_pb2.py @@ -23,7 +23,7 @@ name='tabletmanagerdata.proto', package='tabletmanagerdata', syntax='proto3', - 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\"|\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\"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\"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\"$\n\rBackupRequest\x12\x13\n\x0b\x63oncurrency\x18\x01 \x01(\x03\"/\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\"\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\"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\"$\n\rBackupRequest\x12\x13\n\x0b\x63oncurrency\x18\x01 \x01(\x03\"/\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,]) @@ -1293,6 +1293,102 @@ ) +_LOCKTABLESREQUEST = _descriptor.Descriptor( + name='LockTablesRequest', + full_name='tabletmanagerdata.LockTablesRequest', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=2572, + serialized_end=2591, +) + + +_LOCKTABLESRESPONSE = _descriptor.Descriptor( + name='LockTablesResponse', + full_name='tabletmanagerdata.LockTablesResponse', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=2593, + serialized_end=2613, +) + + +_UNLOCKTABLESREQUEST = _descriptor.Descriptor( + name='UnlockTablesRequest', + full_name='tabletmanagerdata.UnlockTablesRequest', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=2615, + serialized_end=2636, +) + + +_UNLOCKTABLESRESPONSE = _descriptor.Descriptor( + name='UnlockTablesResponse', + full_name='tabletmanagerdata.UnlockTablesResponse', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=2638, + serialized_end=2660, +) + + _EXECUTEFETCHASDBAREQUEST = _descriptor.Descriptor( name='ExecuteFetchAsDbaRequest', full_name='tabletmanagerdata.ExecuteFetchAsDbaRequest', @@ -1347,8 +1443,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=2572, - serialized_end=2696, + serialized_start=2662, + serialized_end=2786, ) @@ -1378,8 +1474,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=2698, - serialized_end=2761, + serialized_start=2788, + serialized_end=2851, ) @@ -1430,8 +1526,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=2763, - serialized_end=2867, + serialized_start=2853, + serialized_end=2957, ) @@ -1461,8 +1557,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=2869, - serialized_end=2937, + serialized_start=2959, + serialized_end=3027, ) @@ -1499,8 +1595,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=2939, - serialized_end=2998, + serialized_start=3029, + serialized_end=3088, ) @@ -1530,8 +1626,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=3000, - serialized_end=3063, + serialized_start=3090, + serialized_end=3153, ) @@ -1554,8 +1650,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=3065, - serialized_end=3085, + serialized_start=3155, + serialized_end=3175, ) @@ -1585,8 +1681,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=3087, - serialized_end=3149, + serialized_start=3177, + serialized_end=3239, ) @@ -1609,8 +1705,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=3151, - serialized_end=3174, + serialized_start=3241, + serialized_end=3264, ) @@ -1640,8 +1736,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=3176, - serialized_end=3218, + serialized_start=3266, + serialized_end=3308, ) @@ -1664,8 +1760,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=3220, - serialized_end=3238, + serialized_start=3310, + serialized_end=3328, ) @@ -1688,8 +1784,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=3240, - serialized_end=3259, + serialized_start=3330, + serialized_end=3349, ) @@ -1726,8 +1822,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=3261, - serialized_end=3326, + serialized_start=3351, + serialized_end=3416, ) @@ -1757,8 +1853,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=3328, - serialized_end=3372, + serialized_start=3418, + serialized_end=3462, ) @@ -1781,8 +1877,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=3374, - serialized_end=3393, + serialized_start=3464, + serialized_end=3483, ) @@ -1805,8 +1901,70 @@ extension_ranges=[], oneofs=[ ], - serialized_start=3395, - serialized_end=3415, + serialized_start=3485, + serialized_end=3505, +) + + +_STARTSLAVEUNTILAFTERREQUEST = _descriptor.Descriptor( + name='StartSlaveUntilAfterRequest', + full_name='tabletmanagerdata.StartSlaveUntilAfterRequest', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='position', full_name='tabletmanagerdata.StartSlaveUntilAfterRequest.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, + options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='wait_timeout', full_name='tabletmanagerdata.StartSlaveUntilAfterRequest.wait_timeout', index=1, + number=2, 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), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=3507, + serialized_end=3576, +) + + +_STARTSLAVEUNTILAFTERRESPONSE = _descriptor.Descriptor( + name='StartSlaveUntilAfterResponse', + full_name='tabletmanagerdata.StartSlaveUntilAfterResponse', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=3578, + serialized_end=3608, ) @@ -1836,8 +1994,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=3417, - serialized_end=3473, + serialized_start=3610, + serialized_end=3666, ) @@ -1860,8 +2018,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=3475, - serialized_end=3511, + serialized_start=3668, + serialized_end=3704, ) @@ -1884,8 +2042,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=3513, - serialized_end=3545, + serialized_start=3706, + serialized_end=3738, ) @@ -1908,8 +2066,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=3547, - serialized_end=3580, + serialized_start=3740, + serialized_end=3773, ) @@ -1932,8 +2090,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=3582, - serialized_end=3600, + serialized_start=3775, + serialized_end=3793, ) @@ -1963,8 +2121,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=3602, - serialized_end=3636, + serialized_start=3795, + serialized_end=3829, ) @@ -1987,8 +2145,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=3638, - serialized_end=3663, + serialized_start=3831, + serialized_end=3856, ) @@ -2011,8 +2169,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=3665, - serialized_end=3691, + serialized_start=3858, + serialized_end=3884, ) @@ -2042,8 +2200,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=3693, - serialized_end=3733, + serialized_start=3886, + serialized_end=3926, ) @@ -2073,8 +2231,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=3735, - serialized_end=3797, + serialized_start=3928, + serialized_end=3990, ) @@ -2111,8 +2269,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=3799, - serialized_end=3860, + serialized_start=3992, + serialized_end=4053, ) @@ -2135,8 +2293,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=3862, - serialized_end=3894, + serialized_start=4055, + serialized_end=4087, ) @@ -2159,8 +2317,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=3896, - serialized_end=3915, + serialized_start=4089, + serialized_end=4108, ) @@ -2190,8 +2348,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=3917, - serialized_end=3955, + serialized_start=4110, + serialized_end=4148, ) @@ -2242,8 +2400,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=3958, - serialized_end=4111, + serialized_start=4151, + serialized_end=4304, ) @@ -2266,8 +2424,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=4113, - serialized_end=4146, + serialized_start=4306, + serialized_end=4339, ) @@ -2311,8 +2469,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=4148, - serialized_end=4260, + serialized_start=4341, + serialized_end=4453, ) @@ -2335,8 +2493,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=4262, - serialized_end=4281, + serialized_start=4455, + serialized_end=4474, ) @@ -2359,8 +2517,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=4283, - serialized_end=4304, + serialized_start=4476, + serialized_end=4497, ) @@ -2390,8 +2548,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=4306, - serialized_end=4346, + serialized_start=4499, + serialized_end=4539, ) @@ -2421,8 +2579,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=4348, - serialized_end=4399, + serialized_start=4541, + serialized_end=4592, ) @@ -2452,8 +2610,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=4401, - serialized_end=4453, + serialized_start=4594, + serialized_end=4646, ) @@ -2476,8 +2634,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=4455, - serialized_end=4480, + serialized_start=4648, + serialized_end=4673, ) @@ -2500,8 +2658,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=4482, - serialized_end=4508, + serialized_start=4675, + serialized_end=4701, ) @@ -2545,8 +2703,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=4510, - serialized_end=4619, + serialized_start=4703, + serialized_end=4812, ) @@ -2569,8 +2727,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=4621, - serialized_end=4640, + serialized_start=4814, + serialized_end=4833, ) @@ -2600,8 +2758,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=4642, - serialized_end=4707, + serialized_start=4835, + serialized_end=4900, ) @@ -2624,8 +2782,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=4709, - serialized_end=4736, + serialized_start=4902, + serialized_end=4929, ) @@ -2648,8 +2806,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=4738, - serialized_end=4774, + serialized_start=4931, + serialized_end=4967, ) @@ -2679,8 +2837,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=4776, - serialized_end=4854, + serialized_start=4969, + serialized_end=5047, ) @@ -2703,8 +2861,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=4856, - serialized_end=4877, + serialized_start=5049, + serialized_end=5070, ) @@ -2734,8 +2892,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=4879, - serialized_end=4919, + serialized_start=5072, + serialized_end=5112, ) @@ -2765,8 +2923,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=4921, - serialized_end=4957, + serialized_start=5114, + serialized_end=5150, ) @@ -2796,8 +2954,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=4959, - serialized_end=5006, + serialized_start=5152, + serialized_end=5199, ) @@ -2820,8 +2978,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=5008, - serialized_end=5034, + serialized_start=5201, + serialized_end=5227, ) @@ -2851,8 +3009,8 @@ extension_ranges=[], oneofs=[ ], - serialized_start=5036, - serialized_end=5094, + serialized_start=5229, + serialized_end=5287, ) _SCHEMADEFINITION.fields_by_name['table_definitions'].message_type = _TABLEDEFINITION @@ -2920,6 +3078,10 @@ DESCRIPTOR.message_types_by_name['PreflightSchemaResponse'] = _PREFLIGHTSCHEMARESPONSE DESCRIPTOR.message_types_by_name['ApplySchemaRequest'] = _APPLYSCHEMAREQUEST DESCRIPTOR.message_types_by_name['ApplySchemaResponse'] = _APPLYSCHEMARESPONSE +DESCRIPTOR.message_types_by_name['LockTablesRequest'] = _LOCKTABLESREQUEST +DESCRIPTOR.message_types_by_name['LockTablesResponse'] = _LOCKTABLESRESPONSE +DESCRIPTOR.message_types_by_name['UnlockTablesRequest'] = _UNLOCKTABLESREQUEST +DESCRIPTOR.message_types_by_name['UnlockTablesResponse'] = _UNLOCKTABLESRESPONSE DESCRIPTOR.message_types_by_name['ExecuteFetchAsDbaRequest'] = _EXECUTEFETCHASDBAREQUEST DESCRIPTOR.message_types_by_name['ExecuteFetchAsDbaResponse'] = _EXECUTEFETCHASDBARESPONSE DESCRIPTOR.message_types_by_name['ExecuteFetchAsAllPrivsRequest'] = _EXECUTEFETCHASALLPRIVSREQUEST @@ -2936,6 +3098,8 @@ DESCRIPTOR.message_types_by_name['StopSlaveMinimumResponse'] = _STOPSLAVEMINIMUMRESPONSE DESCRIPTOR.message_types_by_name['StartSlaveRequest'] = _STARTSLAVEREQUEST DESCRIPTOR.message_types_by_name['StartSlaveResponse'] = _STARTSLAVERESPONSE +DESCRIPTOR.message_types_by_name['StartSlaveUntilAfterRequest'] = _STARTSLAVEUNTILAFTERREQUEST +DESCRIPTOR.message_types_by_name['StartSlaveUntilAfterResponse'] = _STARTSLAVEUNTILAFTERRESPONSE DESCRIPTOR.message_types_by_name['TabletExternallyReparentedRequest'] = _TABLETEXTERNALLYREPARENTEDREQUEST DESCRIPTOR.message_types_by_name['TabletExternallyReparentedResponse'] = _TABLETEXTERNALLYREPARENTEDRESPONSE DESCRIPTOR.message_types_by_name['TabletExternallyElectedRequest'] = _TABLETEXTERNALLYELECTEDREQUEST @@ -3236,6 +3400,34 @@ )) _sym_db.RegisterMessage(ApplySchemaResponse) +LockTablesRequest = _reflection.GeneratedProtocolMessageType('LockTablesRequest', (_message.Message,), dict( + DESCRIPTOR = _LOCKTABLESREQUEST, + __module__ = 'tabletmanagerdata_pb2' + # @@protoc_insertion_point(class_scope:tabletmanagerdata.LockTablesRequest) + )) +_sym_db.RegisterMessage(LockTablesRequest) + +LockTablesResponse = _reflection.GeneratedProtocolMessageType('LockTablesResponse', (_message.Message,), dict( + DESCRIPTOR = _LOCKTABLESRESPONSE, + __module__ = 'tabletmanagerdata_pb2' + # @@protoc_insertion_point(class_scope:tabletmanagerdata.LockTablesResponse) + )) +_sym_db.RegisterMessage(LockTablesResponse) + +UnlockTablesRequest = _reflection.GeneratedProtocolMessageType('UnlockTablesRequest', (_message.Message,), dict( + DESCRIPTOR = _UNLOCKTABLESREQUEST, + __module__ = 'tabletmanagerdata_pb2' + # @@protoc_insertion_point(class_scope:tabletmanagerdata.UnlockTablesRequest) + )) +_sym_db.RegisterMessage(UnlockTablesRequest) + +UnlockTablesResponse = _reflection.GeneratedProtocolMessageType('UnlockTablesResponse', (_message.Message,), dict( + DESCRIPTOR = _UNLOCKTABLESRESPONSE, + __module__ = 'tabletmanagerdata_pb2' + # @@protoc_insertion_point(class_scope:tabletmanagerdata.UnlockTablesResponse) + )) +_sym_db.RegisterMessage(UnlockTablesResponse) + ExecuteFetchAsDbaRequest = _reflection.GeneratedProtocolMessageType('ExecuteFetchAsDbaRequest', (_message.Message,), dict( DESCRIPTOR = _EXECUTEFETCHASDBAREQUEST, __module__ = 'tabletmanagerdata_pb2' @@ -3348,6 +3540,20 @@ )) _sym_db.RegisterMessage(StartSlaveResponse) +StartSlaveUntilAfterRequest = _reflection.GeneratedProtocolMessageType('StartSlaveUntilAfterRequest', (_message.Message,), dict( + DESCRIPTOR = _STARTSLAVEUNTILAFTERREQUEST, + __module__ = 'tabletmanagerdata_pb2' + # @@protoc_insertion_point(class_scope:tabletmanagerdata.StartSlaveUntilAfterRequest) + )) +_sym_db.RegisterMessage(StartSlaveUntilAfterRequest) + +StartSlaveUntilAfterResponse = _reflection.GeneratedProtocolMessageType('StartSlaveUntilAfterResponse', (_message.Message,), dict( + DESCRIPTOR = _STARTSLAVEUNTILAFTERRESPONSE, + __module__ = 'tabletmanagerdata_pb2' + # @@protoc_insertion_point(class_scope:tabletmanagerdata.StartSlaveUntilAfterResponse) + )) +_sym_db.RegisterMessage(StartSlaveUntilAfterResponse) + TabletExternallyReparentedRequest = _reflection.GeneratedProtocolMessageType('TabletExternallyReparentedRequest', (_message.Message,), dict( DESCRIPTOR = _TABLETEXTERNALLYREPARENTEDREQUEST, __module__ = 'tabletmanagerdata_pb2' diff --git a/py/vtproto/tabletmanagerservice_pb2.py b/py/vtproto/tabletmanagerservice_pb2.py index 515efe78587..33d62d43bdc 100644 --- a/py/vtproto/tabletmanagerservice_pb2.py +++ b/py/vtproto/tabletmanagerservice_pb2.py @@ -20,7 +20,7 @@ name='tabletmanagerservice.proto', package='tabletmanagerservice', syntax='proto3', - serialized_pb=_b('\n\x1atabletmanagerservice.proto\x12\x14tabletmanagerservice\x1a\x17tabletmanagerdata.proto2\x95!\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\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\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\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\xd0#\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\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,]) @@ -39,7 +39,7 @@ index=0, options=None, serialized_start=78, - serialized_end=4323, + serialized_end=4638, methods=[ _descriptor.MethodDescriptor( name='Ping', @@ -167,10 +167,28 @@ output_type=tabletmanagerdata__pb2._APPLYSCHEMARESPONSE, options=None, ), + _descriptor.MethodDescriptor( + name='LockTables', + full_name='tabletmanagerservice.TabletManager.LockTables', + index=14, + containing_service=None, + input_type=tabletmanagerdata__pb2._LOCKTABLESREQUEST, + output_type=tabletmanagerdata__pb2._LOCKTABLESRESPONSE, + options=None, + ), + _descriptor.MethodDescriptor( + name='UnlockTables', + full_name='tabletmanagerservice.TabletManager.UnlockTables', + index=15, + containing_service=None, + input_type=tabletmanagerdata__pb2._UNLOCKTABLESREQUEST, + output_type=tabletmanagerdata__pb2._UNLOCKTABLESRESPONSE, + options=None, + ), _descriptor.MethodDescriptor( name='ExecuteFetchAsDba', full_name='tabletmanagerservice.TabletManager.ExecuteFetchAsDba', - index=14, + index=16, containing_service=None, input_type=tabletmanagerdata__pb2._EXECUTEFETCHASDBAREQUEST, output_type=tabletmanagerdata__pb2._EXECUTEFETCHASDBARESPONSE, @@ -179,7 +197,7 @@ _descriptor.MethodDescriptor( name='ExecuteFetchAsAllPrivs', full_name='tabletmanagerservice.TabletManager.ExecuteFetchAsAllPrivs', - index=15, + index=17, containing_service=None, input_type=tabletmanagerdata__pb2._EXECUTEFETCHASALLPRIVSREQUEST, output_type=tabletmanagerdata__pb2._EXECUTEFETCHASALLPRIVSRESPONSE, @@ -188,7 +206,7 @@ _descriptor.MethodDescriptor( name='ExecuteFetchAsApp', full_name='tabletmanagerservice.TabletManager.ExecuteFetchAsApp', - index=16, + index=18, containing_service=None, input_type=tabletmanagerdata__pb2._EXECUTEFETCHASAPPREQUEST, output_type=tabletmanagerdata__pb2._EXECUTEFETCHASAPPRESPONSE, @@ -197,7 +215,7 @@ _descriptor.MethodDescriptor( name='SlaveStatus', full_name='tabletmanagerservice.TabletManager.SlaveStatus', - index=17, + index=19, containing_service=None, input_type=tabletmanagerdata__pb2._SLAVESTATUSREQUEST, output_type=tabletmanagerdata__pb2._SLAVESTATUSRESPONSE, @@ -206,7 +224,7 @@ _descriptor.MethodDescriptor( name='MasterPosition', full_name='tabletmanagerservice.TabletManager.MasterPosition', - index=18, + index=20, containing_service=None, input_type=tabletmanagerdata__pb2._MASTERPOSITIONREQUEST, output_type=tabletmanagerdata__pb2._MASTERPOSITIONRESPONSE, @@ -215,7 +233,7 @@ _descriptor.MethodDescriptor( name='StopSlave', full_name='tabletmanagerservice.TabletManager.StopSlave', - index=19, + index=21, containing_service=None, input_type=tabletmanagerdata__pb2._STOPSLAVEREQUEST, output_type=tabletmanagerdata__pb2._STOPSLAVERESPONSE, @@ -224,7 +242,7 @@ _descriptor.MethodDescriptor( name='StopSlaveMinimum', full_name='tabletmanagerservice.TabletManager.StopSlaveMinimum', - index=20, + index=22, containing_service=None, input_type=tabletmanagerdata__pb2._STOPSLAVEMINIMUMREQUEST, output_type=tabletmanagerdata__pb2._STOPSLAVEMINIMUMRESPONSE, @@ -233,16 +251,25 @@ _descriptor.MethodDescriptor( name='StartSlave', full_name='tabletmanagerservice.TabletManager.StartSlave', - index=21, + index=23, containing_service=None, input_type=tabletmanagerdata__pb2._STARTSLAVEREQUEST, output_type=tabletmanagerdata__pb2._STARTSLAVERESPONSE, options=None, ), + _descriptor.MethodDescriptor( + name='StartSlaveUntilAfter', + full_name='tabletmanagerservice.TabletManager.StartSlaveUntilAfter', + index=24, + containing_service=None, + input_type=tabletmanagerdata__pb2._STARTSLAVEUNTILAFTERREQUEST, + output_type=tabletmanagerdata__pb2._STARTSLAVEUNTILAFTERRESPONSE, + options=None, + ), _descriptor.MethodDescriptor( name='TabletExternallyReparented', full_name='tabletmanagerservice.TabletManager.TabletExternallyReparented', - index=22, + index=25, containing_service=None, input_type=tabletmanagerdata__pb2._TABLETEXTERNALLYREPARENTEDREQUEST, output_type=tabletmanagerdata__pb2._TABLETEXTERNALLYREPARENTEDRESPONSE, @@ -251,7 +278,7 @@ _descriptor.MethodDescriptor( name='TabletExternallyElected', full_name='tabletmanagerservice.TabletManager.TabletExternallyElected', - index=23, + index=26, containing_service=None, input_type=tabletmanagerdata__pb2._TABLETEXTERNALLYELECTEDREQUEST, output_type=tabletmanagerdata__pb2._TABLETEXTERNALLYELECTEDRESPONSE, @@ -260,7 +287,7 @@ _descriptor.MethodDescriptor( name='GetSlaves', full_name='tabletmanagerservice.TabletManager.GetSlaves', - index=24, + index=27, containing_service=None, input_type=tabletmanagerdata__pb2._GETSLAVESREQUEST, output_type=tabletmanagerdata__pb2._GETSLAVESRESPONSE, @@ -269,7 +296,7 @@ _descriptor.MethodDescriptor( name='VReplicationExec', full_name='tabletmanagerservice.TabletManager.VReplicationExec', - index=25, + index=28, containing_service=None, input_type=tabletmanagerdata__pb2._VREPLICATIONEXECREQUEST, output_type=tabletmanagerdata__pb2._VREPLICATIONEXECRESPONSE, @@ -278,7 +305,7 @@ _descriptor.MethodDescriptor( name='VReplicationWaitForPos', full_name='tabletmanagerservice.TabletManager.VReplicationWaitForPos', - index=26, + index=29, containing_service=None, input_type=tabletmanagerdata__pb2._VREPLICATIONWAITFORPOSREQUEST, output_type=tabletmanagerdata__pb2._VREPLICATIONWAITFORPOSRESPONSE, @@ -287,7 +314,7 @@ _descriptor.MethodDescriptor( name='ResetReplication', full_name='tabletmanagerservice.TabletManager.ResetReplication', - index=27, + index=30, containing_service=None, input_type=tabletmanagerdata__pb2._RESETREPLICATIONREQUEST, output_type=tabletmanagerdata__pb2._RESETREPLICATIONRESPONSE, @@ -296,7 +323,7 @@ _descriptor.MethodDescriptor( name='InitMaster', full_name='tabletmanagerservice.TabletManager.InitMaster', - index=28, + index=31, containing_service=None, input_type=tabletmanagerdata__pb2._INITMASTERREQUEST, output_type=tabletmanagerdata__pb2._INITMASTERRESPONSE, @@ -305,7 +332,7 @@ _descriptor.MethodDescriptor( name='PopulateReparentJournal', full_name='tabletmanagerservice.TabletManager.PopulateReparentJournal', - index=29, + index=32, containing_service=None, input_type=tabletmanagerdata__pb2._POPULATEREPARENTJOURNALREQUEST, output_type=tabletmanagerdata__pb2._POPULATEREPARENTJOURNALRESPONSE, @@ -314,7 +341,7 @@ _descriptor.MethodDescriptor( name='InitSlave', full_name='tabletmanagerservice.TabletManager.InitSlave', - index=30, + index=33, containing_service=None, input_type=tabletmanagerdata__pb2._INITSLAVEREQUEST, output_type=tabletmanagerdata__pb2._INITSLAVERESPONSE, @@ -323,7 +350,7 @@ _descriptor.MethodDescriptor( name='DemoteMaster', full_name='tabletmanagerservice.TabletManager.DemoteMaster', - index=31, + index=34, containing_service=None, input_type=tabletmanagerdata__pb2._DEMOTEMASTERREQUEST, output_type=tabletmanagerdata__pb2._DEMOTEMASTERRESPONSE, @@ -332,7 +359,7 @@ _descriptor.MethodDescriptor( name='PromoteSlaveWhenCaughtUp', full_name='tabletmanagerservice.TabletManager.PromoteSlaveWhenCaughtUp', - index=32, + index=35, containing_service=None, input_type=tabletmanagerdata__pb2._PROMOTESLAVEWHENCAUGHTUPREQUEST, output_type=tabletmanagerdata__pb2._PROMOTESLAVEWHENCAUGHTUPRESPONSE, @@ -341,7 +368,7 @@ _descriptor.MethodDescriptor( name='SlaveWasPromoted', full_name='tabletmanagerservice.TabletManager.SlaveWasPromoted', - index=33, + index=36, containing_service=None, input_type=tabletmanagerdata__pb2._SLAVEWASPROMOTEDREQUEST, output_type=tabletmanagerdata__pb2._SLAVEWASPROMOTEDRESPONSE, @@ -350,7 +377,7 @@ _descriptor.MethodDescriptor( name='SetMaster', full_name='tabletmanagerservice.TabletManager.SetMaster', - index=34, + index=37, containing_service=None, input_type=tabletmanagerdata__pb2._SETMASTERREQUEST, output_type=tabletmanagerdata__pb2._SETMASTERRESPONSE, @@ -359,7 +386,7 @@ _descriptor.MethodDescriptor( name='SlaveWasRestarted', full_name='tabletmanagerservice.TabletManager.SlaveWasRestarted', - index=35, + index=38, containing_service=None, input_type=tabletmanagerdata__pb2._SLAVEWASRESTARTEDREQUEST, output_type=tabletmanagerdata__pb2._SLAVEWASRESTARTEDRESPONSE, @@ -368,7 +395,7 @@ _descriptor.MethodDescriptor( name='StopReplicationAndGetStatus', full_name='tabletmanagerservice.TabletManager.StopReplicationAndGetStatus', - index=36, + index=39, containing_service=None, input_type=tabletmanagerdata__pb2._STOPREPLICATIONANDGETSTATUSREQUEST, output_type=tabletmanagerdata__pb2._STOPREPLICATIONANDGETSTATUSRESPONSE, @@ -377,7 +404,7 @@ _descriptor.MethodDescriptor( name='PromoteSlave', full_name='tabletmanagerservice.TabletManager.PromoteSlave', - index=37, + index=40, containing_service=None, input_type=tabletmanagerdata__pb2._PROMOTESLAVEREQUEST, output_type=tabletmanagerdata__pb2._PROMOTESLAVERESPONSE, @@ -386,7 +413,7 @@ _descriptor.MethodDescriptor( name='Backup', full_name='tabletmanagerservice.TabletManager.Backup', - index=38, + index=41, containing_service=None, input_type=tabletmanagerdata__pb2._BACKUPREQUEST, output_type=tabletmanagerdata__pb2._BACKUPRESPONSE, @@ -395,7 +422,7 @@ _descriptor.MethodDescriptor( name='RestoreFromBackup', full_name='tabletmanagerservice.TabletManager.RestoreFromBackup', - index=39, + index=42, 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 f21854be9f0..e559823327e 100644 --- a/py/vtproto/tabletmanagerservice_pb2_grpc.py +++ b/py/vtproto/tabletmanagerservice_pb2_grpc.py @@ -87,6 +87,16 @@ def __init__(self, channel): request_serializer=tabletmanagerdata__pb2.ApplySchemaRequest.SerializeToString, response_deserializer=tabletmanagerdata__pb2.ApplySchemaResponse.FromString, ) + self.LockTables = channel.unary_unary( + '/tabletmanagerservice.TabletManager/LockTables', + request_serializer=tabletmanagerdata__pb2.LockTablesRequest.SerializeToString, + response_deserializer=tabletmanagerdata__pb2.LockTablesResponse.FromString, + ) + self.UnlockTables = channel.unary_unary( + '/tabletmanagerservice.TabletManager/UnlockTables', + request_serializer=tabletmanagerdata__pb2.UnlockTablesRequest.SerializeToString, + response_deserializer=tabletmanagerdata__pb2.UnlockTablesResponse.FromString, + ) self.ExecuteFetchAsDba = channel.unary_unary( '/tabletmanagerservice.TabletManager/ExecuteFetchAsDba', request_serializer=tabletmanagerdata__pb2.ExecuteFetchAsDbaRequest.SerializeToString, @@ -127,6 +137,11 @@ def __init__(self, channel): request_serializer=tabletmanagerdata__pb2.StartSlaveRequest.SerializeToString, response_deserializer=tabletmanagerdata__pb2.StartSlaveResponse.FromString, ) + self.StartSlaveUntilAfter = channel.unary_unary( + '/tabletmanagerservice.TabletManager/StartSlaveUntilAfter', + request_serializer=tabletmanagerdata__pb2.StartSlaveUntilAfterRequest.SerializeToString, + response_deserializer=tabletmanagerdata__pb2.StartSlaveUntilAfterResponse.FromString, + ) self.TabletExternallyReparented = channel.unary_unary( '/tabletmanagerservice.TabletManager/TabletExternallyReparented', request_serializer=tabletmanagerdata__pb2.TabletExternallyReparentedRequest.SerializeToString, @@ -327,6 +342,20 @@ def ApplySchema(self, request, context): context.set_details('Method not implemented!') raise NotImplementedError('Method not implemented!') + def LockTables(self, request, context): + # missing associated documentation comment in .proto file + pass + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def UnlockTables(self, request, context): + # missing associated documentation comment in .proto file + pass + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + def ExecuteFetchAsDba(self, request, context): # missing associated documentation comment in .proto file pass @@ -388,6 +417,14 @@ def StartSlave(self, request, context): context.set_details('Method not implemented!') raise NotImplementedError('Method not implemented!') + def StartSlaveUntilAfter(self, request, context): + """StartSlave starts the mysql replication until and including + the provided position + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + def TabletExternallyReparented(self, request, context): """TabletExternallyReparented tells a tablet that its underlying MySQL is currently the master. It is only used in environments (tabletmanagerdata.such as Vitess+MoB) @@ -619,6 +656,16 @@ def add_TabletManagerServicer_to_server(servicer, server): request_deserializer=tabletmanagerdata__pb2.ApplySchemaRequest.FromString, response_serializer=tabletmanagerdata__pb2.ApplySchemaResponse.SerializeToString, ), + 'LockTables': grpc.unary_unary_rpc_method_handler( + servicer.LockTables, + request_deserializer=tabletmanagerdata__pb2.LockTablesRequest.FromString, + response_serializer=tabletmanagerdata__pb2.LockTablesResponse.SerializeToString, + ), + 'UnlockTables': grpc.unary_unary_rpc_method_handler( + servicer.UnlockTables, + request_deserializer=tabletmanagerdata__pb2.UnlockTablesRequest.FromString, + response_serializer=tabletmanagerdata__pb2.UnlockTablesResponse.SerializeToString, + ), 'ExecuteFetchAsDba': grpc.unary_unary_rpc_method_handler( servicer.ExecuteFetchAsDba, request_deserializer=tabletmanagerdata__pb2.ExecuteFetchAsDbaRequest.FromString, @@ -659,6 +706,11 @@ def add_TabletManagerServicer_to_server(servicer, server): request_deserializer=tabletmanagerdata__pb2.StartSlaveRequest.FromString, response_serializer=tabletmanagerdata__pb2.StartSlaveResponse.SerializeToString, ), + 'StartSlaveUntilAfter': grpc.unary_unary_rpc_method_handler( + servicer.StartSlaveUntilAfter, + request_deserializer=tabletmanagerdata__pb2.StartSlaveUntilAfterRequest.FromString, + response_serializer=tabletmanagerdata__pb2.StartSlaveUntilAfterResponse.SerializeToString, + ), 'TabletExternallyReparented': grpc.unary_unary_rpc_method_handler( servicer.TabletExternallyReparented, request_deserializer=tabletmanagerdata__pb2.TabletExternallyReparentedRequest.FromString, diff --git a/test/tablet.py b/test/tablet.py index 930f5941295..1d64bfbe752 100644 --- a/test/tablet.py +++ b/test/tablet.py @@ -30,8 +30,12 @@ from mysql_flavor import mysql_flavor from protocols_flavor import protocols_flavor from topo_flavor.server import topo_server +from urlparse import urlparse import utils +import grpc +from vtproto.tabletmanagerservice_pb2_grpc import TabletManagerStub + # Dropping a table inexplicably produces a warning despite # the 'IF EXISTS' clause. Squelch these warnings. warnings.simplefilter('ignore') @@ -473,6 +477,7 @@ def start_vttablet( args.extend(['-health_check_interval', '2s']) args.extend(['-enable_replication_reporter']) args.extend(['-degraded_threshold', '5s']) + args.extend(['-lock_tables_timeout', '5s']) args.extend(['-watch_replication_stream']) if enable_semi_sync: args.append('-enable_semi_sync') @@ -635,10 +640,10 @@ def wait_for_vttablet_state(self, expected, timeout=60.0, port=None): break else: logging.debug( - ' vttablet %s in state %s != %s', self.tablet_alias, s, + ' vttablet %s in state: %s, expected: %s', self.tablet_alias, s, expected) timeout = utils.wait_step( - 'waiting for %s state %s (last seen state: %s)' % + '%s state %s (last seen state: %s)' % (self.tablet_alias, expected, last_seen_state), timeout, sleep_time=0.1) @@ -842,6 +847,12 @@ def rpc_endpoint(self): return 'localhost:%d' % self.grpc_port return 'localhost:%d' % self.port + def tablet_manager(self): + """Returns a rpc client able to talk to the TabletManager rpc server in go""" + addr = self.rpc_endpoint() + p = urlparse('http://' + addr) + channel = grpc.insecure_channel('%s:%s' % (p.hostname, p.port)) + return TabletManagerStub(channel) def kill_tablets(tablets): for t in tablets: @@ -854,3 +865,5 @@ def kill_tablets(tablets): if t.proc is not None: t.proc.wait() t.proc = None + + diff --git a/test/tabletmanager.py b/test/tabletmanager.py index 68a5bf9f645..1956cf9d245 100755 --- a/test/tabletmanager.py +++ b/test/tabletmanager.py @@ -840,4 +840,4 @@ def test_topocustomrule(self): if __name__ == '__main__': - utils.main() + utils.main() \ No newline at end of file diff --git a/test/tabletmanager2.py b/test/tabletmanager2.py new file mode 100755 index 00000000000..e65af1f1f92 --- /dev/null +++ b/test/tabletmanager2.py @@ -0,0 +1,228 @@ +#!/usr/bin/env python + +# 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. + +# vim: tabstop=8 expandtab shiftwidth=2 softtabstop=2 + +import MySQLdb +import logging +import re +import unittest +import os +import environment +import tablet +import utils +import time +from utils import TestError +from vtproto.tabletmanagerdata_pb2 import LockTablesRequest, UnlockTablesRequest, StopSlaveRequest, \ + MasterPositionRequest, StartSlaveUntilAfterRequest + +# regexp to check if the tablet status page reports healthy, +# regardless of actual replication lag +healthy_expr = re.compile(r'Current status: healthy') + +_create_vt_insert_test = '''create table vt_insert_test ( + id bigint auto_increment, + msg varchar(64), + primary key (id) + ) Engine=InnoDB''' + + +class TestServiceTestOfTabletManager(unittest.TestCase): + """This tests the locking functionality by running rpc calls against the tabletmanager, + in contrast to testing the tabletmanager through the vtcl""" + + replica = tablet.Tablet(62344) + master = tablet.Tablet(62044) + + def setUp(self): + try: + os.makedirs(environment.tmproot) + except OSError: + # directory already exists + pass + + try: + topo_flavor = environment.topo_server().flavor() + if topo_flavor == 'zk2': + # This is a one-off test to make sure our 'zk2' implementation + # behave with a server that is not DNS-resolveable. + environment.topo_server().setup(add_bad_host=True) + else: + environment.topo_server().setup() + + # start mysql instance external to the test + setup_procs = [ + self.replica.init_mysql(), + self.master.init_mysql(), + ] + utils.Vtctld().start() + logging.debug(utils.vtctld_connection) + utils.wait_procs(setup_procs) + + for t in self.master, self.replica: + t.create_db('vt_test_keyspace') + + self.master.init_tablet('replica', 'test_keyspace', '0', start=True) + self.replica.init_tablet('replica', 'test_keyspace', '0', start=True) + utils.run_vtctl(['InitShardMaster', '-force', 'test_keyspace/0', + self.master.tablet_alias]) + self.master.mquery('vt_test_keyspace', _create_vt_insert_test) + for t in [self.master, self.replica]: + t.set_semi_sync_enabled(master=False, slave=False) + except Exception as e: + logging.exception(e) + self.tearDown() + + def tearDown(self): + try: + for t in self.master, self.replica: + t.kill_vttablet() + tablet.Tablet.check_vttablet_count() + environment.topo_server().wipe() + for t in [self.master, self.replica]: + t.reset_replication() + t.set_semi_sync_enabled(master=False, slave=False) + t.clean_dbs() + finally: + utils.required_teardown() + + if utils.options.skip_teardown: + return + + teardown_procs = [ + self.master.teardown_mysql(), + self.replica.teardown_mysql(), + ] + utils.wait_procs(teardown_procs, raise_on_error=False) + + environment.topo_server().teardown() + utils.kill_sub_processes() + utils.remove_tmp_files() + + self.replica.remove_tree() + self.master.remove_tree() + + def _write_data_to_master(self): + """Write a single row to the master""" + self.master.mquery('vt_test_keyspace', "insert into vt_insert_test (msg) values ('test')", write=True) + + def _check_data_on_replica(self, count, msg): + """Check that the specified tablet has the expected number of rows.""" + timeout = 3 + while True: + try: + result = self.replica.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 test_lock_and_unlock(self): + """Test the lock ability by locking a replica and asserting it does not see changes""" + # first make sure that our writes to the master make it to the replica + self._write_data_to_master() + self._check_data_on_replica(1, "replica getting the data") + + # now lock the replica + tablet_manager = self.replica.tablet_manager() + tablet_manager.LockTables(LockTablesRequest()) + + # make sure that writing to the master does not show up on the replica while locked + self._write_data_to_master() + with self.assertRaises(TestError): + self._check_data_on_replica(2, "the replica should not see these updates") + + # finally, make sure that unlocking the replica leads to the previous write showing up + tablet_manager.UnlockTables(UnlockTablesRequest()) + self._check_data_on_replica(2, "after unlocking the replica, we should see these updates") + + def test_unlock_when_we_dont_have_a_lock(self): + """Unlocking when we do not have a valid lock should lead to an exception being raised""" + # unlock the replica + tablet_manager = self.replica.tablet_manager() + with self.assertRaises(Exception): + tablet_manager.UnlockTables(UnlockTablesRequest()) + + def test_start_slave_until_after(self): + """Test by writing three rows, noting the gtid after each, and then replaying them one by one""" + self.replica.start_vttablet() + self.master.start_vttablet() + + # first we stop replication to the replica, so we can move forward step by step. + replica_tablet_manager = self.replica.tablet_manager() + replica_tablet_manager.StopSlave(StopSlaveRequest()) + + master_tablet_manager = self.master.tablet_manager() + self._write_data_to_master() + pos1 = master_tablet_manager.MasterPosition(MasterPositionRequest()) + + self._write_data_to_master() + pos2 = master_tablet_manager.MasterPosition(MasterPositionRequest()) + + self._write_data_to_master() + pos3 = master_tablet_manager.MasterPosition(MasterPositionRequest()) + + # Now, we'll resume stepwise position by position and make sure that we see the expected data + self._check_data_on_replica(0, "no data has yet reached the replica") + + # timeout is given in nanoseconds. we want to wait no more than 10 seconds + timeout = int(10 * 1e9) + + replica_tablet_manager.StartSlaveUntilAfter( + StartSlaveUntilAfterRequest(position=pos1.position, wait_timeout=timeout)) + self._check_data_on_replica(1, "first row is now visible") + + replica_tablet_manager.StartSlaveUntilAfter( + StartSlaveUntilAfterRequest(position=pos2.position, wait_timeout=timeout)) + self._check_data_on_replica(2, "second row is now visible") + + replica_tablet_manager.StartSlaveUntilAfter( + StartSlaveUntilAfterRequest(position=pos3.position, wait_timeout=timeout)) + self._check_data_on_replica(3, "third row is now visible") + + def test_lock_and_timeout(self): + """Test that the lock times out and updates can be seen even though nothing is unlocked""" + + # first make sure that our writes to the master make it to the replica + self._write_data_to_master() + self._check_data_on_replica(1, "replica getting the data") + + # now lock the replica + tablet_manager = self.replica.tablet_manager() + tablet_manager.LockTables(LockTablesRequest()) + + # make sure that writing to the master does not show up on the replica while locked + self._write_data_to_master() + with self.assertRaises(TestError): + self._check_data_on_replica(2, "the replica should not see these updates") + + # the tests sets the lock timeout to 5 seconds, so sleeping 10 should be safe + time.sleep(10) + + self._check_data_on_replica(2, "the replica should now see these updates") + + # finally, trying to unlock should clearly tell us we did not have the lock + with self.assertRaises(Exception): + tablet_manager.UnlockTables(UnlockTablesRequest()) + + +if __name__ == '__main__': + utils.main() diff --git a/test/utils.py b/test/utils.py index d7e65ff23dc..2bae9fa3ebf 100644 --- a/test/utils.py +++ b/test/utils.py @@ -224,10 +224,11 @@ def required_teardown(): """Required cleanup steps that can't be skipped with --skip-teardown.""" # We can't skip closing of gRPC connections, because the Python interpreter # won't let us die if any connections are left open. - global vtctld_connection + global vtctld_connection, vtctld if vtctld_connection: vtctld_connection.close() vtctld_connection = None + vtctld = None def kill_sub_processes(): From 4e8ff1af475af03c93358888ea271e4aa63d81ca Mon Sep 17 00:00:00 2001 From: Miriam Lauter Date: Fri, 18 Jan 2019 12:58:46 -0500 Subject: [PATCH 068/115] Since STRICT_ALL_TABLES is a superset of STRICT_TRANS_TABLES, allow dbs to be configured with STRICT_ALL_TABLES when vitess is enforcing STRICT_TRANS_TABLES (-enforce_strict_trans_tables=true) Signed-off-by: Miriam Lauter --- doc/ServerConfiguration.md | 2 +- go/vt/vttablet/tabletserver/connpool/dbconn.go | 9 +++++---- go/vt/vttablet/tabletserver/query_engine_test.go | 6 +++--- go/vt/vttablet/tabletserver/tabletenv/config.go | 2 +- 4 files changed, 10 insertions(+), 9 deletions(-) diff --git a/doc/ServerConfiguration.md b/doc/ServerConfiguration.md index 07020310175..32f19087208 100644 --- a/doc/ServerConfiguration.md +++ b/doc/ServerConfiguration.md @@ -71,7 +71,7 @@ This rule is not strictly enforced. You are allowed to add these things, but at Similar guidelines should be used when deciding to bypass Vitess to send statements directly to MySQL. -Vitess also requires you to turn on STRICT_TRANS_TABLES mode. Otherwise, it cannot accurately predict what will be written to the database. +Vitess also requires you to turn on STRICT_TRANS_TABLES or STRICT_ALL_TABLES mode. Otherwise, it cannot accurately predict what will be written to the database. It’s safe to apply backward compatible DDLs directly to MySQL. VTTablets can be configured to periodically check the schema for changes. diff --git a/go/vt/vttablet/tabletserver/connpool/dbconn.go b/go/vt/vttablet/tabletserver/connpool/dbconn.go index 8c020f143a6..2a189676a44 100644 --- a/go/vt/vttablet/tabletserver/connpool/dbconn.go +++ b/go/vt/vttablet/tabletserver/connpool/dbconn.go @@ -231,8 +231,8 @@ var ( ) // VerifyMode is a helper method to verify mysql is running with -// sql_mode = STRICT_TRANS_TABLES and autocommit=ON. It also returns -// the current binlog format. +// sql_mode = STRICT_TRANS_TABLES or STRICT_ALL_TABLES and autocommit=ON. +// It also returns the current binlog format. func (dbc *DBConn) VerifyMode(strictTransTables bool) (BinlogFormat, error) { if strictTransTables { qr, err := dbc.conn.ExecuteFetch(getModeSQL, 2, false) @@ -242,8 +242,9 @@ func (dbc *DBConn) VerifyMode(strictTransTables bool) (BinlogFormat, error) { if len(qr.Rows) != 1 { return 0, fmt.Errorf("incorrect rowcount received for %s: %d", getModeSQL, len(qr.Rows)) } - if !strings.Contains(qr.Rows[0][0].ToString(), "STRICT_TRANS_TABLES") { - return 0, fmt.Errorf("require sql_mode to be STRICT_TRANS_TABLES: got '%s'", qr.Rows[0][0].ToString()) + sqlMode := qr.Rows[0][0].ToString() + if !(strings.Contains(sqlMode, "STRICT_TRANS_TABLES") || strings.Contains(sqlMode, "STRICT_ALL_TABLES")) { + return 0, fmt.Errorf("require sql_mode to be STRICT_TRANS_TABLES or STRICT_ALL_TABLES: got '%s'", qr.Rows[0][0].ToString()) } } qr, err := dbc.conn.ExecuteFetch(getAutocommit, 2, false) diff --git a/go/vt/vttablet/tabletserver/query_engine_test.go b/go/vt/vttablet/tabletserver/query_engine_test.go index 882cbe0dd5f..739d823982c 100644 --- a/go/vt/vttablet/tabletserver/query_engine_test.go +++ b/go/vt/vttablet/tabletserver/query_engine_test.go @@ -40,7 +40,7 @@ import ( querypb "vitess.io/vitess/go/vt/proto/query" ) -func TestStrictTransTables(t *testing.T) { +func TestStrictMode(t *testing.T) { db := fakesqldb.New(t) defer db.Close() for query, result := range schematest.Queries() { @@ -61,7 +61,7 @@ func TestStrictTransTables(t *testing.T) { } qe.Close() - // Check that we fail if STRICT_TRANS_TABLES is not set. + // Check that we fail if STRICT_TRANS_TABLES or STRICT_ALL_TABLES is not set. db.AddQuery( "select @@global.sql_mode", &sqltypes.Result{ @@ -72,7 +72,7 @@ func TestStrictTransTables(t *testing.T) { qe = NewQueryEngine(DummyChecker, schema.NewEngine(DummyChecker, config), config) qe.InitDBConfig(dbcfgs) err := qe.Open() - wantErr := "require sql_mode to be STRICT_TRANS_TABLES: got ''" + wantErr := "require sql_mode to be STRICT_TRANS_TABLES or STRICT_ALL_TABLES: got ''" if err == nil || err.Error() != wantErr { t.Errorf("Open: %v, want %s", err, wantErr) } diff --git a/go/vt/vttablet/tabletserver/tabletenv/config.go b/go/vt/vttablet/tabletserver/tabletenv/config.go index cc6eac7df9d..f0fa5e9d2e9 100644 --- a/go/vt/vttablet/tabletserver/tabletenv/config.go +++ b/go/vt/vttablet/tabletserver/tabletenv/config.go @@ -99,7 +99,7 @@ func init() { flag.BoolVar(&Config.HeartbeatEnable, "heartbeat_enable", DefaultQsConfig.HeartbeatEnable, "If true, vttablet records (if master) or checks (if replica) the current time of a replication heartbeat in the table _vt.heartbeat. The result is used to inform the serving state of the vttablet via healthchecks.") flag.DurationVar(&Config.HeartbeatInterval, "heartbeat_interval", DefaultQsConfig.HeartbeatInterval, "How frequently to read and write replication heartbeat.") - flag.BoolVar(&Config.EnforceStrictTransTables, "enforce_strict_trans_tables", DefaultQsConfig.EnforceStrictTransTables, "If true, vttablet requires MySQL to run with STRICT_TRANS_TABLES on. It is recommended to not turn this flag off. Otherwise MySQL may alter your supplied values before saving them to the database.") + flag.BoolVar(&Config.EnforceStrictTransTables, "enforce_strict_trans_tables", DefaultQsConfig.EnforceStrictTransTables, "If true, vttablet requires MySQL to run with STRICT_TRANS_TABLES or STRICT_ALL_TABLES on. It is recommended to not turn this flag off. Otherwise MySQL may alter your supplied values before saving them to the database.") flag.BoolVar(&Config.EnableConsolidator, "enable-consolidator", DefaultQsConfig.EnableConsolidator, "This option enables the query consolidator.") } From ed9216df2f4633b91f6cceccb043a98fe1324658 Mon Sep 17 00:00:00 2001 From: Sugu Sougoumarane Date: Sat, 19 Jan 2019 14:46:47 -0800 Subject: [PATCH 069/115] vplayer: ddl tests and some fixes Signed-off-by: Sugu Sougoumarane --- go/vt/binlog/binlogplayer/binlog_player.go | 8 +- .../binlog/binlogplayer/binlog_player_test.go | 10 +- .../tabletmanager/vreplication/engine.go | 14 +- .../vreplication/framework_test.go | 34 ++- .../tabletmanager/vreplication/relaylog.go | 13 +- .../tabletmanager/vreplication/vplayer.go | 65 +++-- .../vreplication/vplayer_test.go | 246 +++++++++++++++--- .../tabletserver/vstreamer/vstreamer.go | 4 + .../tabletserver/vstreamer/vstreamer_test.go | 2 +- 9 files changed, 326 insertions(+), 70 deletions(-) diff --git a/go/vt/binlog/binlogplayer/binlog_player.go b/go/vt/binlog/binlogplayer/binlog_player.go index da81c6f1053..419bacf1624 100644 --- a/go/vt/binlog/binlogplayer/binlog_player.go +++ b/go/vt/binlog/binlogplayer/binlog_player.go @@ -601,11 +601,17 @@ func encodeString(in string) string { } // ReadVReplicationPos returns a statement to query the gtid for a -// given shard from the _vt.vreplication table. +// given stream from the _vt.vreplication table. func ReadVReplicationPos(index uint32) string { return fmt.Sprintf("select pos from _vt.vreplication where id=%v", index) } +// ReadVReplicationStatus returns a statement to query the status fields for a +// given stream from the _vt.vreplication table. +func ReadVReplicationStatus(index uint32) string { + return fmt.Sprintf("select pos, state, message from _vt.vreplication where id=%v", index) +} + // StatsHistoryRecord is used to store a Message with timestamp type StatsHistoryRecord struct { Time time.Time diff --git a/go/vt/binlog/binlogplayer/binlog_player_test.go b/go/vt/binlog/binlogplayer/binlog_player_test.go index 8db24607dab..4493dc33a37 100644 --- a/go/vt/binlog/binlogplayer/binlog_player_test.go +++ b/go/vt/binlog/binlogplayer/binlog_player_test.go @@ -377,6 +377,14 @@ func TestReadVReplicationPos(t *testing.T) { want := "select pos from _vt.vreplication where id=482821" got := ReadVReplicationPos(482821) if got != want { - t.Errorf("ReadVReplicationThrottlerSettings(482821) = %#v, want %#v", got, want) + t.Errorf("ReadVReplicationPos(482821) = %#v, want %#v", got, want) + } +} + +func TestReadVReplicationStatus(t *testing.T) { + want := "select pos, state, message from _vt.vreplication where id=482821" + got := ReadVReplicationStatus(482821) + if got != want { + t.Errorf("ReadVReplicationStatus(482821) = %#v, want %#v", got, want) } } diff --git a/go/vt/vttablet/tabletmanager/vreplication/engine.go b/go/vt/vttablet/tabletmanager/vreplication/engine.go index 3a664b131f5..e5f47456cd7 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/engine.go +++ b/go/vt/vttablet/tabletmanager/vreplication/engine.go @@ -315,13 +315,13 @@ func (vre *Engine) WaitForPos(ctx context.Context, id int, pos string) error { defer dbClient.Close() for { - qr, err := dbClient.ExecuteFetch(binlogplayer.ReadVReplicationPos(uint32(id)), 10) + qr, err := dbClient.ExecuteFetch(binlogplayer.ReadVReplicationStatus(uint32(id)), 10) switch { case err != nil: return err case len(qr.Rows) == 0: return fmt.Errorf("vreplication stream %d not found", id) - case len(qr.Rows) > 1 || len(qr.Rows[0]) != 1: + case len(qr.Rows) > 1 || len(qr.Rows[0]) != 3: return fmt.Errorf("unexpected result: %v", qr) } current, err := mysql.DecodePosition(qr.Rows[0][0].ToString()) @@ -329,10 +329,18 @@ func (vre *Engine) WaitForPos(ctx context.Context, id int, pos string) error { return err } - if current.AtLeast(mPos) { + if current.Equal(mPos) { return nil } + if current.AtLeast(mPos) { + return fmt.Errorf("postion %v has been overshot, current position is %v", mPos, current) + } + + if qr.Rows[0][1].ToString() == binlogplayer.BlpStopped { + return fmt.Errorf("replication has stopped at %v before reaching position %v, message: %s", current, mPos, qr.Rows[0][2].ToString()) + } + select { case <-ctx.Done(): return ctx.Err() diff --git a/go/vt/vttablet/tabletmanager/vreplication/framework_test.go b/go/vt/vttablet/tabletmanager/vreplication/framework_test.go index 139313e3393..5149b3bf00d 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/framework_test.go +++ b/go/vt/vttablet/tabletmanager/vreplication/framework_test.go @@ -50,6 +50,7 @@ var ( streamerEngine *vstreamer.Engine env *testenv.Env globalFBC = &fakeBinlogClient{} + vrepldb = "vrepl" globalDBQueries = make(chan string, 1000) ) @@ -89,8 +90,16 @@ func TestMain(m *testing.M) { streamerEngine.Open(env.KeyspaceName, env.Cells[0]) defer streamerEngine.Close() + if err := env.Mysqld.ExecuteSuperQuery(context.Background(), fmt.Sprintf("create database %s", vrepldb)); err != nil { + fmt.Fprintf(os.Stderr, "%v", err) + return 1 + } + playerEngine = NewEngine(env.TopoServ, env.Cells[0], env.Mysqld, realDBClientFactory) - playerEngine.Open(context.Background()) + if err := playerEngine.Open(context.Background()); err != nil { + fmt.Fprintf(os.Stderr, "%v", err) + return 1 + } defer playerEngine.Close() return m.Run() @@ -273,11 +282,13 @@ type realDBClient struct { } func (dbc *realDBClient) DBName() string { - return env.KeyspaceName + return vrepldb } func (dbc *realDBClient) Connect() error { - conn, err := mysql.Connect(context.Background(), env.Dbcfgs.AppWithDB()) + app := env.Dbcfgs.AppWithDB() + app.DbName = vrepldb + conn, err := mysql.Connect(context.Background(), app) if err != nil { return err } @@ -286,19 +297,21 @@ func (dbc *realDBClient) Connect() error { } func (dbc *realDBClient) Begin() error { - globalDBQueries <- "begin" _, err := dbc.conn.ExecuteFetch("begin", 10000, true) + globalDBQueries <- "begin" return err } func (dbc *realDBClient) Commit() error { - globalDBQueries <- "commit" _, err := dbc.conn.ExecuteFetch("commit", 10000, true) + globalDBQueries <- "commit" return err } func (dbc *realDBClient) Rollback() error { - panic("rollback should never be called") + _, err := dbc.conn.ExecuteFetch("rollback", 10000, true) + globalDBQueries <- "rollback" + return err } func (dbc *realDBClient) Close() { @@ -307,13 +320,14 @@ func (dbc *realDBClient) Close() { } func (dbc *realDBClient) ExecuteFetch(query string, maxrows int) (*sqltypes.Result, error) { - if !strings.HasPrefix(query, "select") { - globalDBQueries <- query - } if strings.HasPrefix(query, "use") { return nil, nil } - return dbc.conn.ExecuteFetch(query, 10000, true) + qr, err := dbc.conn.ExecuteFetch(query, 10000, true) + if !strings.HasPrefix(query, "select") { + globalDBQueries <- query + } + return qr, err } func expectDBClientQueries(t *testing.T, queries []string) { diff --git a/go/vt/vttablet/tabletmanager/vreplication/relaylog.go b/go/vt/vttablet/tabletmanager/vreplication/relaylog.go index 9be66dd75c4..3830d632a4e 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/relaylog.go +++ b/go/vt/vttablet/tabletmanager/vreplication/relaylog.go @@ -56,14 +56,11 @@ func newRelayLog(ctx context.Context, maxItems, maxSize int) *relayLog { // Any time context is done, wake up all waiters to make them exit. go func() { - select { - case <-ctx.Done(): - rl.mu.Lock() - defer rl.mu.Unlock() - rl.canAccept.Broadcast() - rl.hasItems.Broadcast() - default: - } + <-ctx.Done() + rl.mu.Lock() + defer rl.mu.Unlock() + rl.canAccept.Broadcast() + rl.hasItems.Broadcast() }() return rl } diff --git a/go/vt/vttablet/tabletmanager/vreplication/vplayer.go b/go/vt/vttablet/tabletmanager/vreplication/vplayer.go index 9f21b3f2f50..c53973a28e0 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/vplayer.go +++ b/go/vt/vttablet/tabletmanager/vreplication/vplayer.go @@ -18,6 +18,7 @@ package vreplication import ( "bytes" + "errors" "fmt" "io" "sync" @@ -108,7 +109,7 @@ func (vp *vplayer) Play(ctx context.Context) error { func (vp *vplayer) play(ctx context.Context) error { startPos, stopPos, _, _, err := binlogplayer.ReadVRSettings(vp.dbClient, vp.id) if err != nil { - return fmt.Errorf("error reading VReplication settings: %v", err) + return vp.setState(binlogplayer.BlpStopped, fmt.Sprintf("error reading VReplication settings: %v", err)) } vp.pos, err = mysql.DecodePosition(startPos) if err != nil { @@ -117,7 +118,7 @@ func (vp *vplayer) play(ctx context.Context) error { if stopPos != "" { vp.stopPos, err = mysql.DecodePosition(stopPos) if err != nil { - return fmt.Errorf("error decoding stop position %v: %v", stopPos, err) + return vp.setState(binlogplayer.BlpStopped, fmt.Sprintf("error decoding stop position %v: %v", stopPos, err)) } } if !vp.stopPos.IsZero() { @@ -161,13 +162,39 @@ func (vp *vplayer) play(ctx context.Context) error { }() select { - case err = <-applyErr: - case err = <-streamErr: - } - if err == io.EOF { - return nil + case err := <-applyErr: + defer func() { + // cancel and wait for the other thread to finish. + cancel() + <-streamErr + }() + // If the apply thread ends with io.EOF, it means the context + // was canceled, which can only happen if Engine is shutting down. + // If so, we return nil which will cause the vplayer to shut down. + if err == io.EOF { + return nil + } + return err + case err := <-streamErr: + defer func() { + // cancel and wait for the other thread to finish. + cancel() + <-applyErr + }() + // If context is done, don't return an error. + select { + case <-ctx.Done(): + return nil + default: + } + // If the stream ends normally without context being canceled, + // we have to return an error indicating that the controller + // has to retry a different vttablet. + if err == nil { + return errors.New("vstream ended") + } + return err } - return err } func (vp *vplayer) applyEvents(relay *relayLog) error { @@ -261,7 +288,7 @@ func (vp *vplayer) applyEvent(event *binlogdatapb.VEvent) error { return nil } if !vp.pos.Equal(vp.stopPos) && vp.pos.AtLeast(vp.stopPos) { - return fmt.Errorf("next event position %v exceeds stop pos %v, exiting without applying", vp.pos, vp.stopPos) + return vp.setState(binlogplayer.BlpStopped, fmt.Sprintf("next event position %v exceeds stop pos %v, exiting without applying", vp.pos, vp.stopPos)) } case binlogdatapb.VEventType_BEGIN: // No-op: begin is called as needed. @@ -433,6 +460,9 @@ func (vp *vplayer) applyRowChange(tplan *tablePlan, rowChange *binlogdatapb.RowC case before == nil && after == nil: // unreachable } + if query == "" { + return nil + } return vp.exec(query) } @@ -453,7 +483,7 @@ func (vp *vplayer) generateInsert(tplan *tablePlan, after []sqltypes.Value) stri func (vp *vplayer) generateUpdate(tplan *tablePlan, before, after []sqltypes.Value) string { if tplan.onInsert == insertIgnore { - return "" + return vp.generateInsert(tplan, after) } sql := sqlparser.NewTrackedBuffer(nil) sql.Myprintf("update %v set ", sqlparser.NewTableIdent(tplan.name)) @@ -465,15 +495,18 @@ func (vp *vplayer) generateUpdate(tplan *tablePlan, before, after []sqltypes.Val func (vp *vplayer) generateDelete(tplan *tablePlan, before []sqltypes.Value) string { sql := sqlparser.NewTrackedBuffer(nil) - if tplan.onInsert == insertNormal { + switch tplan.onInsert { + case insertOndup: + sql.Myprintf("update %v set ", sqlparser.NewTableIdent(tplan.name)) + vp.writeUpdateValues(sql, tplan, before, nil) + sql.Myprintf(" where ") + vp.writeWhereValues(sql, tplan, before) + case insertIgnore: + return "" + default: // insertNormal sql.Myprintf("delete from %v where ", sqlparser.NewTableIdent(tplan.name)) vp.writeWhereValues(sql, tplan, before) - return sql.String() } - sql.Myprintf("update %v set ", sqlparser.NewTableIdent(tplan.name)) - vp.writeUpdateValues(sql, tplan, before, nil) - sql.Myprintf(" where ") - vp.writeWhereValues(sql, tplan, before) return sql.String() } diff --git a/go/vt/vttablet/tabletmanager/vreplication/vplayer_test.go b/go/vt/vttablet/tabletmanager/vreplication/vplayer_test.go index a59168f435c..c0082879697 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/vplayer_test.go +++ b/go/vt/vttablet/tabletmanager/vreplication/vplayer_test.go @@ -28,20 +28,30 @@ import ( topodatapb "vitess.io/vitess/go/vt/proto/topodata" ) -func TestSimple(t *testing.T) { +func TestFilters(t *testing.T) { defer deleteTablet(addTablet(100, "0", topodatapb.TabletType_REPLICA, true, true)) execStatements(t, []string{ "create table src1(id int, val varbinary(128), primary key(id))", - "create table dst1(id int, val varbinary(128), primary key(id))", + fmt.Sprintf("create table %s.dst1(id int, val varbinary(128), primary key(id))", vrepldb), "create table src2(id int, val1 int, val2 int, primary key(id))", - "create table dst2(id int, val1 int, sval2 int, rcount int, primary key(id))", + fmt.Sprintf("create table %s.dst2(id int, val1 int, sval2 int, rcount int, primary key(id))", vrepldb), + "create table src3(id int, val varbinary(128), primary key(id))", + fmt.Sprintf("create table %s.dst3(id int, val varbinary(128), primary key(id))", vrepldb), + "create table yes(id int, val varbinary(128), primary key(id))", + fmt.Sprintf("create table %s.yes(id int, val varbinary(128), primary key(id))", vrepldb), + "create table no(id int, val varbinary(128), primary key(id))", }) defer execStatements(t, []string{ "drop table src1", - "drop table dst1", + fmt.Sprintf("drop table %s.dst1", vrepldb), "drop table src2", - //"drop table dst2", + fmt.Sprintf("drop table %s.dst2", vrepldb), + "drop table src3", + fmt.Sprintf("drop table %s.dst3", vrepldb), + "drop table yes", + fmt.Sprintf("drop table %s.yes", vrepldb), + "drop table no", }) env.SchemaEngine.Reload(context.Background()) @@ -52,45 +62,216 @@ func TestSimple(t *testing.T) { }, { Match: "dst2", Filter: "select id, val1, sum(val2) as sval2, count(*) as rcount from src2 group by id", + }, { + Match: "dst3", + Filter: "select id, val from src3 group by id, val", + }, { + Match: "/yes", }}, } - cancel := startVReplication(t, playerEngine, filter, "") + cancel, _ := startVReplication(t, playerEngine, filter, binlogdatapb.OnDDLAction_IGNORE, "") defer cancel() testcases := []struct { input string - output string + output []string }{{ - input: "insert into src1 values(1, 'aaa')", - output: "insert into dst1 set id=1, val='aaa'", + // insert with insertNormal + input: "insert into src1 values(1, 'aaa')", + output: []string{ + "begin", + "insert into dst1 set id=1, val='aaa'", + "/update _vt.vreplication set pos=", + "commit", + }, + }, { + // update with insertNormal + input: "update src1 set val='bbb'", + output: []string{ + "begin", + "update dst1 set id=1, val='bbb' where id=1", + "/update _vt.vreplication set pos=", + "commit", + }, + }, { + // delete with insertNormal + input: "delete from src1 where id=1", + output: []string{ + "begin", + "delete from dst1 where id=1", + "/update _vt.vreplication set pos=", + "commit", + }, + }, { + // insert with insertOnDup + input: "insert into src2 values(1, 2, 3)", + output: []string{ + "begin", + "insert into dst2 set id=1, val1=2, sval2=3, rcount=1 on duplicate key update val1=2, sval2=sval2+3, rcount=rcount+1", + "/update _vt.vreplication set pos=", + "commit", + }, + }, { + // update with insertOnDup + input: "update src2 set val1=5, val2=1 where id=1", + output: []string{ + "begin", + "update dst2 set val1=5, sval2=sval2-3+1, rcount=rcount-1+1 where id=1", + "/update _vt.vreplication set pos=", + "commit", + }, }, { - input: "update src1 set val='bbb'", - output: "update dst1 set id=1, val='bbb' where id=1", + // delete with insertOnDup + input: "delete from src2 where id=1", + output: []string{ + "begin", + "update dst2 set val1=NULL, sval2=sval2-1, rcount=rcount-1 where id=1", + "/update _vt.vreplication set pos=", + "commit", + }, + }, { + // insert with insertIgnore + input: "insert into src3 values(1, 'aaa')", + output: []string{ + "begin", + "insert ignore into dst3 set id=1, val='aaa'", + "/update _vt.vreplication set pos=", + "commit", + }, + }, { + // update with insertIgnore + input: "update src3 set val='bbb'", + output: []string{ + "begin", + "insert ignore into dst3 set id=1, val='bbb'", + "/update _vt.vreplication set pos=", + "commit", + }, }, { - input: "delete from src1 where id=1", - output: "delete from dst1 where id=1", + // delete with insertIgnore + input: "delete from src3 where id=1", + output: []string{ + "begin", + "/update _vt.vreplication set pos=", + "commit", + }, }, { - input: "insert into src2 values(1, 2, 3)", - output: "insert into dst2 set id=1, val1=2, sval2=3, rcount=1 on duplicate key update val1=2, sval2=sval2+3, rcount=rcount+1", + // insert: regular expression filter + input: "insert into yes values(1, 'aaa')", + output: []string{ + "begin", + "insert into yes set id=1, val='aaa'", + "/update _vt.vreplication set pos=", + "commit", + }, }, { - input: "update src2 set val1=5, val2=1 where id=1", - output: "update dst2 set val1=5, sval2=sval2-3+1, rcount=rcount-1+1 where id=1", + // update: regular expression filter + input: "update yes set val='bbb'", + output: []string{ + "begin", + "update yes set id=1, val='bbb' where id=1", + "/update _vt.vreplication set pos=", + "commit", + }, }, { - input: "delete from src2 where id=1", - output: "update dst2 set val1=NULL, sval2=sval2-1, rcount=rcount-1 where id=1", + // table should not match a rule + input: "insert into no values(1, 'aaa')", + output: []string{}, }} for _, tcases := range testcases { - execStatements(t, []string{ - tcases.input, - }) - expectDBClientQueries(t, []string{ - "begin", - tcases.output, - "/update _vt.vreplication set pos=.*", - "commit", - }) + execStatements(t, []string{tcases.input}) + expectDBClientQueries(t, tcases.output) + } +} + +func TestDDL(t *testing.T) { + defer deleteTablet(addTablet(100, "0", topodatapb.TabletType_REPLICA, true, true)) + + filter := &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{{ + Match: "/.*", + }}, + } + + cancel, _ := startVReplication(t, playerEngine, filter, binlogdatapb.OnDDLAction_IGNORE, "") + execStatements(t, []string{"create table t1(id int, primary key(id))"}) + execStatements(t, []string{"drop table t1"}) + expectDBClientQueries(t, []string{}) + cancel() + + cancel, id := startVReplication(t, playerEngine, filter, binlogdatapb.OnDDLAction_STOP, "") + execStatements(t, []string{"create table t1(id int, primary key(id))"}) + pos1 := masterPosition(t) + execStatements(t, []string{"drop table t1"}) + pos2 := masterPosition(t) + // The stop position must be the GTID of the first DDL + expectDBClientQueries(t, []string{ + "begin", + fmt.Sprintf("/update _vt.vreplication set pos='%s'", pos1), + "/update _vt.vreplication set state='Stopped'", + "commit", + }) + // Restart vreplication + if _, err := playerEngine.Exec(fmt.Sprintf(`update _vt.vreplication set state = 'Running', message='' where id=%d`, id)); err != nil { + t.Fatal(err) } + // It should stop at the next DDL + expectDBClientQueries(t, []string{ + "/update.*'Running'", + "/update.*'Running'", + "begin", + fmt.Sprintf("/update.*'%s'", pos2), + "/update _vt.vreplication set state='Stopped'", + "commit", + }) + cancel() + + execStatements(t, []string{fmt.Sprintf("create table %s.t2(id int, primary key(id))", vrepldb)}) + cancel, _ = startVReplication(t, playerEngine, filter, binlogdatapb.OnDDLAction_EXEC, "") + execStatements(t, []string{"create table t1(id int, primary key(id))"}) + expectDBClientQueries(t, []string{ + "create table t1(id int, primary key(id))", + "/update _vt.vreplication set pos=", + }) + execStatements(t, []string{"create table t2(id int, primary key(id))"}) + expectDBClientQueries(t, []string{ + "create table t2(id int, primary key(id))", + "/update _vt.vreplication set state='Error'", + }) + cancel() + + // Don't test drop. + // MySQL rewrites them by uppercasing, which may be version specific. + execStatements(t, []string{ + "drop table t1", + fmt.Sprintf("drop table %s.t1", vrepldb), + "drop table t2", + fmt.Sprintf("drop table %s.t2", vrepldb), + }) + + execStatements(t, []string{fmt.Sprintf("create table %s.t2(id int, primary key(id))", vrepldb)}) + cancel, _ = startVReplication(t, playerEngine, filter, binlogdatapb.OnDDLAction_EXEC_IGNORE, "") + execStatements(t, []string{"create table t1(id int, primary key(id))"}) + expectDBClientQueries(t, []string{ + "create table t1(id int, primary key(id))", + "/update _vt.vreplication set pos=", + }) + execStatements(t, []string{"create table t2(id int, primary key(id))"}) + expectDBClientQueries(t, []string{ + "create table t2(id int, primary key(id))", + "/update _vt.vreplication set pos=", + }) + cancel() + + // Don't test drop. + // MySQL rewrites them by uppercasing, which may be version specific. + execStatements(t, []string{ + "drop table t1", + fmt.Sprintf("drop table %s.t1", vrepldb), + "drop table t2", + fmt.Sprintf("drop table %s.t2", vrepldb), + }) } func execStatements(t *testing.T, queries []string) { @@ -100,13 +281,14 @@ func execStatements(t *testing.T, queries []string) { } } -func startVReplication(t *testing.T, pe *Engine, filter *binlogdatapb.Filter, pos string) (cancelFunc func()) { +func startVReplication(t *testing.T, pe *Engine, filter *binlogdatapb.Filter, onddl binlogdatapb.OnDDLAction, pos string) (cancelFunc func(), id int) { t.Helper() bls := &binlogdatapb.BinlogSource{ Keyspace: env.KeyspaceName, Shard: env.ShardName, Filter: filter, + OnDdl: onddl, } if pos == "" { pos = masterPosition(t) @@ -127,11 +309,15 @@ func startVReplication(t *testing.T, pe *Engine, filter *binlogdatapb.Filter, po } } return func() { + t.Helper() query := fmt.Sprintf("delete from _vt.vreplication where id = %d", qr.InsertID) if _, err := pe.Exec(query); err != nil { t.Fatal(err) } - } + expectDBClientQueries(t, []string{ + "/delete", + }) + }, int(qr.InsertID) } func masterPosition(t *testing.T) string { diff --git a/go/vt/vttablet/tabletserver/vstreamer/vstreamer.go b/go/vt/vttablet/tabletserver/vstreamer/vstreamer.go index 6c8631a49ba..4bf378d9f81 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/vstreamer.go +++ b/go/vt/vttablet/tabletserver/vstreamer/vstreamer.go @@ -20,6 +20,7 @@ import ( "context" "flag" "fmt" + "io" "vitess.io/vitess/go/mysql" "vitess.io/vitess/go/sqltypes" @@ -183,6 +184,9 @@ func (vs *vstreamer) parseEvents(ctx context.Context, events <-chan mysql.Binlog } for _, vevent := range vevents { if err := bufferAndTransmit(vevent); err != nil { + if err == io.EOF { + return nil + } return fmt.Errorf("error sending event: %v", err) } } diff --git a/go/vt/vttablet/tabletserver/vstreamer/vstreamer_test.go b/go/vt/vttablet/tabletserver/vstreamer/vstreamer_test.go index 7c345cd3cdd..9cf671a3b7b 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/vstreamer_test.go +++ b/go/vt/vttablet/tabletserver/vstreamer/vstreamer_test.go @@ -954,7 +954,7 @@ func startStream(ctx context.Context, t *testing.T, filter *binlogdatapb.Filter) go func() { defer close(ch) if err := vstream(ctx, t, pos, filter, ch); err != nil { - t.Fatal(err) + t.Error(err) } }() return ch From 4b6d22f034902b861fd3d0d568558ab25f4b36ae Mon Sep 17 00:00:00 2001 From: Sugu Sougoumarane Date: Sat, 19 Jan 2019 16:00:11 -0800 Subject: [PATCH 070/115] vplayer: fix tests and mariadb103 issues Signed-off-by: Sugu Sougoumarane --- go/vt/vttablet/endtoend/compatibility_test.go | 9 ++++++- go/vt/vttablet/endtoend/misc_test.go | 14 ++++++++--- .../tabletmanager/vreplication/engine.go | 24 +++++++------------ .../tabletmanager/vreplication/engine_test.go | 20 +++++++++++----- .../tabletserver/vstreamer/vstreamer_test.go | 4 +--- .../testlib/migrate_served_from_test.go | 6 +++-- .../testlib/migrate_served_types_test.go | 12 ++++++---- 7 files changed, 55 insertions(+), 34 deletions(-) diff --git a/go/vt/vttablet/endtoend/compatibility_test.go b/go/vt/vttablet/endtoend/compatibility_test.go index 6edc6628e4b..1bf90904633 100644 --- a/go/vt/vttablet/endtoend/compatibility_test.go +++ b/go/vt/vttablet/endtoend/compatibility_test.go @@ -794,7 +794,14 @@ func TestJSONType(t *testing.T) { }, } if !reflect.DeepEqual(*qr, want) { - t.Errorf("Execute: \n%v, want \n%v", prettyPrint(*qr), prettyPrint(want)) + // MariaDB 10.3 has different behavior. + want2 := want.Copy() + want2.Fields[1].Type = sqltypes.Blob + want2.Fields[1].Charset = 33 + want2.Rows[0][1] = sqltypes.TestValue(sqltypes.Blob, "{\"foo\": \"bar\"}") + if !reflect.DeepEqual(*qr, *want2) { + t.Errorf("Execute:\n%v, want\n%v or\n%v", prettyPrint(*qr), prettyPrint(want), prettyPrint(*want2)) + } } } diff --git a/go/vt/vttablet/endtoend/misc_test.go b/go/vt/vttablet/endtoend/misc_test.go index 5e961a9ae32..81fb606ba0a 100644 --- a/go/vt/vttablet/endtoend/misc_test.go +++ b/go/vt/vttablet/endtoend/misc_test.go @@ -364,7 +364,13 @@ func TestBindInSelect(t *testing.T) { }, } if !qr.Equal(want) { - t.Errorf("Execute: \n%#v, want \n%#v", prettyPrint(*qr), prettyPrint(*want)) + // MariaDB 10.3 has different behavior. + want2 := want.Copy() + want2.Fields[0].Type = sqltypes.Int32 + want2.Rows[0][0] = sqltypes.NewInt32(1) + if !qr.Equal(want2) { + t.Errorf("Execute:\n%v, want\n%v or\n%v", prettyPrint(*qr), prettyPrint(*want), prettyPrint(*want2)) + } } // String bind var. @@ -382,7 +388,6 @@ func TestBindInSelect(t *testing.T) { Type: sqltypes.VarChar, ColumnLength: 12, Charset: 33, - Decimals: 31, Flags: 1, }}, RowsAffected: 1, @@ -392,6 +397,8 @@ func TestBindInSelect(t *testing.T) { }, }, } + // MariaDB 10.3 has different behavior. + qr.Fields[0].Decimals = 0 if !qr.Equal(want) { t.Errorf("Execute: \n%#v, want \n%#v", prettyPrint(*qr), prettyPrint(*want)) } @@ -411,7 +418,6 @@ func TestBindInSelect(t *testing.T) { Type: sqltypes.VarChar, ColumnLength: 6, Charset: 33, - Decimals: 31, Flags: 1, }}, RowsAffected: 1, @@ -421,6 +427,8 @@ func TestBindInSelect(t *testing.T) { }, }, } + // MariaDB 10.3 has different behavior. + qr.Fields[0].Decimals = 0 if !qr.Equal(want) { t.Errorf("Execute: \n%#v, want \n%#v", prettyPrint(*qr), prettyPrint(*want)) } diff --git a/go/vt/vttablet/tabletmanager/vreplication/engine.go b/go/vt/vttablet/tabletmanager/vreplication/engine.go index e5f47456cd7..740c497626d 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/engine.go +++ b/go/vt/vttablet/tabletmanager/vreplication/engine.go @@ -288,17 +288,15 @@ func (vre *Engine) WaitForPos(ctx context.Context, id int, pos string) error { if !vre.isOpen { return errors.New("vreplication engine is closed") } - ct, ok := vre.controllers[id] - if !ok { - return fmt.Errorf("vreplication stream %d not found", id) - } - mpos, err := mysql.DecodePosition(pos) - if err != nil { - return err + if ct, ok := vre.controllers[id]; ok { + mpos, err := mysql.DecodePosition(pos) + if err != nil { + return err + } + // vplayer doesn't export all the positions it receives unless + // we specifically request it for one. + ct.exportPosition(mpos) } - // vplayer doesn't export all the positions it receives unless - // we specifically request it for one. - ct.exportPosition(mpos) // Ensure that the engine won't be closed while this is running. vre.wg.Add(1) @@ -329,12 +327,8 @@ func (vre *Engine) WaitForPos(ctx context.Context, id int, pos string) error { return err } - if current.Equal(mPos) { - return nil - } - if current.AtLeast(mPos) { - return fmt.Errorf("postion %v has been overshot, current position is %v", mPos, current) + return nil } if qr.Rows[0][1].ToString() == binlogplayer.BlpStopped { diff --git a/go/vt/vttablet/tabletmanager/vreplication/engine_test.go b/go/vt/vttablet/tabletmanager/vreplication/engine_test.go index 8394a8328f0..9bf21378e85 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/engine_test.go +++ b/go/vt/vttablet/tabletmanager/vreplication/engine_test.go @@ -286,11 +286,15 @@ func TestWaitForPos(t *testing.T) { // hack a controller into vre. vre.controllers[1] = &controller{} - dbClient.ExpectRequest("select pos from _vt.vreplication where id=1", &sqltypes.Result{Rows: [][]sqltypes.Value{{ + dbClient.ExpectRequest("select pos, state, message from _vt.vreplication where id=1", &sqltypes.Result{Rows: [][]sqltypes.Value{{ sqltypes.NewVarBinary("MariaDB/0-1-1083"), + sqltypes.NewVarBinary("Running"), + sqltypes.NewVarBinary(""), }}}, nil) - dbClient.ExpectRequest("select pos from _vt.vreplication where id=1", &sqltypes.Result{Rows: [][]sqltypes.Value{{ + dbClient.ExpectRequest("select pos, state, message from _vt.vreplication where id=1", &sqltypes.Result{Rows: [][]sqltypes.Value{{ sqltypes.NewVarBinary("MariaDB/0-1-1084"), + sqltypes.NewVarBinary("Running"), + sqltypes.NewVarBinary(""), }}}, nil) start := time.Now() if err := vre.WaitForPos(context.Background(), 1, "MariaDB/0-1-1084"); err != nil { @@ -326,14 +330,14 @@ func TestWaitForPosError(t *testing.T) { t.Errorf("WaitForPos: %v, want %v", err, want) } - dbClient.ExpectRequest("select pos from _vt.vreplication where id=1", &sqltypes.Result{Rows: [][]sqltypes.Value{{}}}, nil) + dbClient.ExpectRequest("select pos, state, message from _vt.vreplication where id=1", &sqltypes.Result{Rows: [][]sqltypes.Value{{}}}, nil) err = vre.WaitForPos(context.Background(), 1, "MariaDB/0-1-1084") want = "unexpected result: &{[] 0 0 [[]] }" if err == nil || err.Error() != want { t.Errorf("WaitForPos: %v, want %v", err, want) } - dbClient.ExpectRequest("select pos from _vt.vreplication where id=1", &sqltypes.Result{Rows: [][]sqltypes.Value{{ + dbClient.ExpectRequest("select pos, state, message from _vt.vreplication where id=1", &sqltypes.Result{Rows: [][]sqltypes.Value{{ sqltypes.NewVarBinary("MariaDB/0-1-1083"), }, { sqltypes.NewVarBinary("MariaDB/0-1-1083"), @@ -356,8 +360,10 @@ func TestWaitForPosCancel(t *testing.T) { t.Fatal(err) } - dbClient.ExpectRequest("select pos from _vt.vreplication where id=1", &sqltypes.Result{Rows: [][]sqltypes.Value{{ + dbClient.ExpectRequest("select pos, state, message from _vt.vreplication where id=1", &sqltypes.Result{Rows: [][]sqltypes.Value{{ sqltypes.NewVarBinary("MariaDB/0-1-1083"), + sqltypes.NewVarBinary("Running"), + sqltypes.NewVarBinary(""), }}}, nil) ctx, cancel := context.WithCancel(context.Background()) cancel() @@ -378,8 +384,10 @@ func TestWaitForPosCancel(t *testing.T) { time.Sleep(5 * time.Millisecond) vre.Close() }() - dbClient.ExpectRequest("select pos from _vt.vreplication where id=1", &sqltypes.Result{Rows: [][]sqltypes.Value{{ + dbClient.ExpectRequest("select pos, state, message from _vt.vreplication where id=1", &sqltypes.Result{Rows: [][]sqltypes.Value{{ sqltypes.NewVarBinary("MariaDB/0-1-1083"), + sqltypes.NewVarBinary("Running"), + sqltypes.NewVarBinary(""), }}}, nil) err = vre.WaitForPos(context.Background(), 1, "MariaDB/0-1-1084") want := "vreplication is closing: context canceled" diff --git a/go/vt/vttablet/tabletserver/vstreamer/vstreamer_test.go b/go/vt/vttablet/tabletserver/vstreamer/vstreamer_test.go index 9cf671a3b7b..5d39189e9f2 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/vstreamer_test.go +++ b/go/vt/vttablet/tabletserver/vstreamer/vstreamer_test.go @@ -741,9 +741,7 @@ func TestTypes(t *testing.T) { } func TestJSON(t *testing.T) { - if testing.Short() { - t.Skip() - } + t.Skip("This test is disabled because every flavor of mysql has a different behavior.") // JSON is supported only after mysql57. if err := env.Mysqld.ExecuteSuperQuery(context.Background(), "create table vitess_json(id int default 1, val json, primary key(id))"); err != nil { diff --git a/go/vt/wrangler/testlib/migrate_served_from_test.go b/go/vt/wrangler/testlib/migrate_served_from_test.go index 6194e2150ed..303e820e5b5 100644 --- a/go/vt/wrangler/testlib/migrate_served_from_test.go +++ b/go/vt/wrangler/testlib/migrate_served_from_test.go @@ -111,9 +111,11 @@ func TestMigrateServedFrom(t *testing.T) { if err := destMaster.Agent.VREngine.Open(context.Background()); err != nil { t.Fatal(err) } - // select pos from _vt.vreplication - dbClient.ExpectRequest("select pos from _vt.vreplication where id=1", &sqltypes.Result{Rows: [][]sqltypes.Value{{ + // select pos, state, message from _vt.vreplication + dbClient.ExpectRequest("select pos, state, message from _vt.vreplication where id=1", &sqltypes.Result{Rows: [][]sqltypes.Value{{ sqltypes.NewVarBinary("MariaDB/5-456-892"), + sqltypes.NewVarBinary("Running"), + sqltypes.NewVarBinary(""), }}}, nil) dbClient.ExpectRequest("use _vt", &sqltypes.Result{}, nil) dbClient.ExpectRequest("delete from _vt.vreplication where id = 1", &sqltypes.Result{RowsAffected: 1}, nil) diff --git a/go/vt/wrangler/testlib/migrate_served_types_test.go b/go/vt/wrangler/testlib/migrate_served_types_test.go index 28ae7789ffe..e0e8b849420 100644 --- a/go/vt/wrangler/testlib/migrate_served_types_test.go +++ b/go/vt/wrangler/testlib/migrate_served_types_test.go @@ -147,9 +147,11 @@ func TestMigrateServedTypes(t *testing.T) { if err := dest1Master.Agent.VREngine.Open(context.Background()); err != nil { t.Fatal(err) } - // select pos from _vt.vreplication - dbClient1.ExpectRequest("select pos from _vt.vreplication where id=1", &sqltypes.Result{Rows: [][]sqltypes.Value{{ + // select pos, state, message from _vt.vreplication + dbClient1.ExpectRequest("select pos, state, message from _vt.vreplication where id=1", &sqltypes.Result{Rows: [][]sqltypes.Value{{ sqltypes.NewVarBinary("MariaDB/5-456-892"), + sqltypes.NewVarBinary("Running"), + sqltypes.NewVarBinary(""), }}}, nil) dbClient1.ExpectRequest("use _vt", &sqltypes.Result{}, nil) dbClient1.ExpectRequest("delete from _vt.vreplication where id = 1", &sqltypes.Result{RowsAffected: 1}, nil) @@ -174,9 +176,11 @@ func TestMigrateServedTypes(t *testing.T) { if err := dest2Master.Agent.VREngine.Open(context.Background()); err != nil { t.Fatal(err) } - // select pos from _vt.vreplication - dbClient2.ExpectRequest("select pos from _vt.vreplication where id=1", &sqltypes.Result{Rows: [][]sqltypes.Value{{ + // select pos, state, message from _vt.vreplication + dbClient2.ExpectRequest("select pos, state, message from _vt.vreplication where id=1", &sqltypes.Result{Rows: [][]sqltypes.Value{{ sqltypes.NewVarBinary("MariaDB/5-456-892"), + sqltypes.NewVarBinary("Running"), + sqltypes.NewVarBinary(""), }}}, nil) dbClient2.ExpectRequest("use _vt", &sqltypes.Result{}, nil) dbClient2.ExpectRequest("delete from _vt.vreplication where id = 1", &sqltypes.Result{RowsAffected: 1}, nil) From 4126ddbf45e9c6ce06e45a55cb6ce90046c8a838 Mon Sep 17 00:00:00 2001 From: Sugu Sougoumarane Date: Sun, 20 Jan 2019 01:20:05 -0800 Subject: [PATCH 071/115] vplayer: test stopPos Signed-off-by: Sugu Sougoumarane --- .../tabletmanager/vreplication/vplayer.go | 33 ++++-- .../vreplication/vplayer_test.go | 101 +++++++++++++++++- 2 files changed, 119 insertions(+), 15 deletions(-) diff --git a/go/vt/vttablet/tabletmanager/vreplication/vplayer.go b/go/vt/vttablet/tabletmanager/vreplication/vplayer.go index c53973a28e0..0168c063898 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/vplayer.go +++ b/go/vt/vttablet/tabletmanager/vreplication/vplayer.go @@ -113,7 +113,7 @@ func (vp *vplayer) play(ctx context.Context) error { } vp.pos, err = mysql.DecodePosition(startPos) if err != nil { - return fmt.Errorf("error decoding start position %v: %v", startPos, err) + return vp.setState(binlogplayer.BlpStopped, fmt.Sprintf("error decoding start position %v: %v", startPos, err)) } if stopPos != "" { vp.stopPos, err = mysql.DecodePosition(stopPos) @@ -168,9 +168,9 @@ func (vp *vplayer) play(ctx context.Context) error { cancel() <-streamErr }() - // If the apply thread ends with io.EOF, it means the context - // was canceled, which can only happen if Engine is shutting down. - // If so, we return nil which will cause the vplayer to shut down. + // If the apply thread ends with io.EOF, it means either the Engine + // is shutting down and canceled the context, or stop position was reached. + // If so, we return nil which will cause the controller to not retry. if err == io.EOF { return nil } @@ -187,10 +187,9 @@ func (vp *vplayer) play(ctx context.Context) error { return nil default: } - // If the stream ends normally without context being canceled, - // we have to return an error indicating that the controller - // has to retry a different vttablet. - if err == nil { + // If the stream ends normally we have to return an error indicating + // that the controller has to retry a different vttablet. + if err == nil || err == io.EOF { return errors.New("vstream ended") } return err @@ -288,18 +287,32 @@ func (vp *vplayer) applyEvent(event *binlogdatapb.VEvent) error { return nil } if !vp.pos.Equal(vp.stopPos) && vp.pos.AtLeast(vp.stopPos) { - return vp.setState(binlogplayer.BlpStopped, fmt.Sprintf("next event position %v exceeds stop pos %v, exiting without applying", vp.pos, vp.stopPos)) + // Code is unreachable, but bad data can cause this to happen. + if err := vp.setState(binlogplayer.BlpStopped, fmt.Sprintf("next event position %v exceeds stop pos %v, exiting without applying", vp.pos, vp.stopPos)); err != nil { + return err + } + return io.EOF } case binlogdatapb.VEventType_BEGIN: // No-op: begin is called as needed. case binlogdatapb.VEventType_COMMIT: + posReached := !vp.stopPos.IsZero() && vp.pos.Equal(vp.stopPos) + // If stop pos is reached, then we must commit. + // So, if we haven't started a transaction (vp.mustCommit==false), + // we must start one. + if posReached && !vp.mustCommit { + if err := vp.dbClient.Begin(); err != nil { + return err + } + vp.mustCommit = true + } + if !vp.mustCommit { return nil } if err := vp.updatePos(event.Timestamp); err != nil { return err } - posReached := !vp.stopPos.IsZero() && vp.pos.Equal(vp.stopPos) if posReached { if err := vp.setState(binlogplayer.BlpStopped, fmt.Sprintf("Stopped at position %v", vp.stopPos)); err != nil { return err diff --git a/go/vt/vttablet/tabletmanager/vreplication/vplayer_test.go b/go/vt/vttablet/tabletmanager/vreplication/vplayer_test.go index c0082879697..2d9d796a431 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/vplayer_test.go +++ b/go/vt/vttablet/tabletmanager/vreplication/vplayer_test.go @@ -24,6 +24,7 @@ import ( "golang.org/x/net/context" "vitess.io/vitess/go/mysql" + "vitess.io/vitess/go/vt/binlog/binlogplayer" binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" topodatapb "vitess.io/vitess/go/vt/proto/topodata" ) @@ -274,6 +275,100 @@ func TestDDL(t *testing.T) { }) } +func TestStopPos(t *testing.T) { + defer deleteTablet(addTablet(100, "0", topodatapb.TabletType_REPLICA, true, true)) + + execStatements(t, []string{ + "create table yes(id int, val varbinary(128), primary key(id))", + fmt.Sprintf("create table %s.yes(id int, val varbinary(128), primary key(id))", vrepldb), + "create table no(id int, val varbinary(128), primary key(id))", + }) + defer execStatements(t, []string{ + "drop table yes", + fmt.Sprintf("drop table %s.yes", vrepldb), + "drop table no", + }) + env.SchemaEngine.Reload(context.Background()) + + filter := &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{{ + Match: "/yes", + }}, + } + bls := &binlogdatapb.BinlogSource{ + Keyspace: env.KeyspaceName, + Shard: env.ShardName, + Filter: filter, + OnDdl: binlogdatapb.OnDDLAction_IGNORE, + } + startPos := masterPosition(t) + query := binlogplayer.CreateVReplicationStopped("test", bls, startPos) + qr, err := playerEngine.Exec(query) + if err != nil { + t.Fatal(err) + } + id := uint32(qr.InsertID) + for q := range globalDBQueries { + if strings.HasPrefix(q, "insert into _vt.vreplication") { + break + } + } + + // Test normal stop. + execStatements(t, []string{ + "insert into yes values(1, 'aaa')", + }) + stopPos := masterPosition(t) + query = binlogplayer.StartVReplicationUntil(id, stopPos) + if _, err := playerEngine.Exec(query); err != nil { + t.Fatal(err) + } + expectDBClientQueries(t, []string{ + "/update.*'Running'", // done by Engine + "/update.*'Running'", // done by vplayer on start + "begin", + "insert into yes set id=1, val='aaa'", + fmt.Sprintf("/update.*'%s'", stopPos), + "/update.*'Stopped'", + "commit", + }) + + // Test stopping at empty transaction. + execStatements(t, []string{ + "insert into no values(2, 'aaa')", + "insert into no values(3, 'aaa')", + }) + stopPos = masterPosition(t) + execStatements(t, []string{ + "insert into no values(4, 'aaa')", + }) + query = binlogplayer.StartVReplicationUntil(id, stopPos) + if _, err := playerEngine.Exec(query); err != nil { + t.Fatal(err) + } + expectDBClientQueries(t, []string{ + "/update.*'Running'", // done by Engine + "/update.*'Running'", // done by vplayer on start + "begin", + // Since 'no' generates empty transactions that are skipped by + // vplayer, a commit is done only for the stop position event. + fmt.Sprintf("/update.*'%s'", stopPos), + "/update.*'Stopped'", + "commit", + }) + + // Test stopping when position is already reached. + query = binlogplayer.StartVReplicationUntil(id, stopPos) + if _, err := playerEngine.Exec(query); err != nil { + t.Fatal(err) + } + expectDBClientQueries(t, []string{ + "/update.*'Running'", // done by Engine + "/update.*'Running'", // done by vplayer on start + "/update.*'Stopped'.*already reached", + }) +} + func execStatements(t *testing.T, queries []string) { t.Helper() if err := env.Mysqld.ExecuteSuperQueryList(context.Background(), queries); err != nil { @@ -293,11 +388,7 @@ func startVReplication(t *testing.T, pe *Engine, filter *binlogdatapb.Filter, on if pos == "" { pos = masterPosition(t) } - query := fmt.Sprintf(`insert into _vt.vreplication`+ - `(workflow, source, pos, max_tps, max_replication_lag, time_updated, transaction_timestamp, state)`+ - `values('test', '%v', '%s', 9223372036854775807, 9223372036854775807, 481823, 0, 'Running')`, - bls, pos, - ) + query := binlogplayer.CreateVReplication("test", bls, pos, 9223372036854775807, 9223372036854775807, 0) qr, err := pe.Exec(query) if err != nil { t.Fatal(err) From 9a63e3864748dc665d29bb83a320e895cc011b84 Mon Sep 17 00:00:00 2001 From: Sugu Sougoumarane Date: Sun, 20 Jan 2019 13:29:06 -0800 Subject: [PATCH 072/115] vplayer: improved state management Signed-off-by: Sugu Sougoumarane --- .../tabletmanager/vreplication/controller.go | 8 +- .../tabletmanager/vreplication/relaylog.go | 56 ++++++----- .../tabletmanager/vreplication/vplayer.go | 93 ++++++++++++------- .../vreplication/vplayer_test.go | 23 ++++- 4 files changed, 120 insertions(+), 60 deletions(-) diff --git a/go/vt/vttablet/tabletmanager/vreplication/controller.go b/go/vt/vttablet/tabletmanager/vreplication/controller.go index 574b1484d21..37186eb21f7 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/controller.go +++ b/go/vt/vttablet/tabletmanager/vreplication/controller.go @@ -136,7 +136,13 @@ func (ct *controller) run(ctx context.Context) { default: } log.Errorf("stream %v: %v, retrying after %v", ct.id, err, *retryDelay) - time.Sleep(*retryDelay) + timer := time.NewTimer(*retryDelay) + select { + case <-ctx.Done(): + timer.Stop() + return + case <-timer.C: + } } } diff --git a/go/vt/vttablet/tabletmanager/vreplication/relaylog.go b/go/vt/vttablet/tabletmanager/vreplication/relaylog.go index 3830d632a4e..64504b5457a 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/relaylog.go +++ b/go/vt/vttablet/tabletmanager/vreplication/relaylog.go @@ -23,7 +23,6 @@ import ( "golang.org/x/net/context" - "vitess.io/vitess/go/sync2" binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" ) @@ -35,13 +34,14 @@ type relayLog struct { // mu controls all variables below and is shared by canAccept and hasItems. // Broadcasting must be done while holding mu. This is mainly necessary because both // conditions depend on ctx.Done(), which can change state asynchronously. - mu sync.Mutex - curSize int - items [][]*binlogdatapb.VEvent - err error + mu sync.Mutex + curSize int + items [][]*binlogdatapb.VEvent + interruptFetch bool + err error // canAccept is true if: curSize<=maxSize, len(items)0, ctx is not Done, and call has not timedout. + // hasItems is true if len(items)>0, ctx is not Done, and interuptFetch is false. hasItems sync.Cond } @@ -91,28 +91,15 @@ func (rl *relayLog) Fetch() ([][]*binlogdatapb.VEvent, error) { if err := rl.checkDone(); err != nil { return nil, err } - timer := time.NewTimer(idleTimeout) - defer timer.Stop() - var timedout sync2.AtomicBool - go func() { - select { - case <-timer.C: - rl.mu.Lock() - defer rl.mu.Unlock() - timedout.Set(true) - rl.hasItems.Broadcast() - default: - } - }() - for len(rl.items) == 0 { + cancelTimer := rl.startTimer() + defer cancelTimer() + for len(rl.items) == 0 && !rl.interruptFetch { rl.hasItems.Wait() if err := rl.checkDone(); err != nil { return nil, err } - if timedout.Get() { - return nil, nil - } } + rl.interruptFetch = false items := rl.items rl.items = nil rl.curSize = 0 @@ -129,6 +116,29 @@ func (rl *relayLog) checkDone() error { return nil } +func (rl *relayLog) startTimer() (cancel func()) { + timer := time.NewTimer(idleTimeout) + timerDone := make(chan struct{}) + go func() { + select { + case <-timer.C: + rl.InterruptFetch() + case <-timerDone: + } + }() + return func() { + timer.Stop() + close(timerDone) + } +} + +func (rl *relayLog) InterruptFetch() { + rl.mu.Lock() + defer rl.mu.Unlock() + rl.interruptFetch = true + rl.hasItems.Broadcast() +} + func eventsSize(events []*binlogdatapb.VEvent) int { size := 0 for _, event := range events { diff --git a/go/vt/vttablet/tabletmanager/vreplication/vplayer.go b/go/vt/vttablet/tabletmanager/vreplication/vplayer.go index 0168c063898..0528c920230 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/vplayer.go +++ b/go/vt/vttablet/tabletmanager/vreplication/vplayer.go @@ -57,7 +57,9 @@ type vplayer struct { unsavedGTID *binlogdatapb.VEvent timeLastSaved time.Time stopPos mysql.Position - mustCommit bool + // inTransaction is true if we've started a transaction. + // It remains true until the next commit or rollback. + inTransaction bool // mu protects exportPositions. // exportPositions specifies a list of positions. @@ -202,32 +204,30 @@ func (vp *vplayer) applyEvents(relay *relayLog) error { if err != nil { return err } - // This covers two situations: - // 1. Fetch was idle for idleTimeout. - // 2. We've been receiving empty events for longer than idleTimeout. - // In both cases, now > timeLastSaved. If so, any unsaved GTID should be saved - // to prevent us from falling behind on tracking the source binlog position. - if time.Now().Sub(vp.timeLastSaved) >= idleTimeout && vp.unsavedGTID != nil { + // Don't do special things in the middle of a transaction. + if !vp.inTransaction && vp.mustExport() { if err := vp.updatePos(vp.unsavedGTID.Timestamp); err != nil { return err } } for i, events := range items { for j, event := range events { + mustSave := false switch event.Type { case binlogdatapb.VEventType_COMMIT: if vp.pos.Equal(vp.stopPos) { - // If stop pos is reached, we have to commit. + mustSave = true break } if vp.mustExport() { + mustSave = true break } if hasAnotherCommit(items, i, j+1) { continue } } - if err := vp.applyEvent(event); err != nil { + if err := vp.applyEvent(event, mustSave); err != nil { return err } } @@ -236,6 +236,15 @@ func (vp *vplayer) applyEvents(relay *relayLog) error { } func (vp *vplayer) mustExport() bool { + // This covers two situations: + // 1. Fetch was idle for idleTimeout. + // 2. We've been receiving empty events for longer than idleTimeout. + // In both cases, now > timeLastSaved. If so, any unsaved GTID should be saved + // to prevent us from falling behind on tracking the source binlog position. + if time.Now().Sub(vp.timeLastSaved) >= idleTimeout && vp.unsavedGTID != nil { + return true + } + vp.mu.Lock() defer vp.mu.Unlock() @@ -274,7 +283,7 @@ func hasAnotherCommit(items [][]*binlogdatapb.VEvent, i, j int) bool { return false } -func (vp *vplayer) applyEvent(event *binlogdatapb.VEvent) error { +func (vp *vplayer) applyEvent(event *binlogdatapb.VEvent, mustSave bool) error { switch event.Type { case binlogdatapb.VEventType_GTID: pos, err := mysql.DecodePosition(event.Gtid) @@ -296,64 +305,53 @@ func (vp *vplayer) applyEvent(event *binlogdatapb.VEvent) error { case binlogdatapb.VEventType_BEGIN: // No-op: begin is called as needed. case binlogdatapb.VEventType_COMMIT: - posReached := !vp.stopPos.IsZero() && vp.pos.Equal(vp.stopPos) - // If stop pos is reached, then we must commit. - // So, if we haven't started a transaction (vp.mustCommit==false), - // we must start one. - if posReached && !vp.mustCommit { - if err := vp.dbClient.Begin(); err != nil { + if mustSave { + if err := vp.begin(); err != nil { return err } - vp.mustCommit = true } - if !vp.mustCommit { + if !vp.inTransaction { return nil } if err := vp.updatePos(event.Timestamp); err != nil { return err } + posReached := !vp.stopPos.IsZero() && vp.pos.Equal(vp.stopPos) if posReached { if err := vp.setState(binlogplayer.BlpStopped, fmt.Sprintf("Stopped at position %v", vp.stopPos)); err != nil { return err } } - if err := vp.dbClient.Commit(); err != nil { + if err := vp.commit(); err != nil { return err } - vp.mustCommit = false if posReached { return io.EOF } case binlogdatapb.VEventType_FIELD: - if !vp.mustCommit { - if err := vp.dbClient.Begin(); err != nil { - return err - } - vp.mustCommit = true + if err := vp.begin(); err != nil { + return err } if err := vp.updatePlan(event.FieldEvent); err != nil { return err } case binlogdatapb.VEventType_ROW: - if !vp.mustCommit { - if err := vp.dbClient.Begin(); err != nil { - return err - } - vp.mustCommit = true + if err := vp.begin(); err != nil { + return err } if err := vp.applyRowEvent(event.RowEvent); err != nil { return err } case binlogdatapb.VEventType_DDL: - if vp.mustCommit { + if vp.inTransaction { return fmt.Errorf("unexpected state: DDL encountered in the middle of a transaction: %v", event.Ddl) } switch vp.source.OnDdl { case binlogdatapb.OnDDLAction_IGNORE: // no-op case binlogdatapb.OnDDLAction_STOP: - if err := vp.dbClient.Begin(); err != nil { + if err := vp.begin(); err != nil { return err } if err := vp.updatePos(event.Timestamp); err != nil { @@ -362,7 +360,7 @@ func (vp *vplayer) applyEvent(event *binlogdatapb.VEvent) error { if err := vp.setState(binlogplayer.BlpStopped, fmt.Sprintf("Stopped at DDL %s", event.Ddl)); err != nil { return err } - if err := vp.dbClient.Commit(); err != nil { + if err := vp.commit(); err != nil { return err } return io.EOF @@ -385,6 +383,33 @@ func (vp *vplayer) applyEvent(event *binlogdatapb.VEvent) error { return nil } +func (vp *vplayer) begin() error { + if vp.inTransaction { + return nil + } + if err := vp.dbClient.Begin(); err != nil { + return err + } + vp.inTransaction = true + return nil +} + +func (vp *vplayer) commit() error { + if !vp.inTransaction { + return nil + } + if err := vp.dbClient.Commit(); err != nil { + return err + } + vp.inTransaction = false + return nil +} + +func (vp *vplayer) rollback() { + vp.inTransaction = false + _ = vp.dbClient.Rollback() +} + func (vp *vplayer) setState(state, message string) error { return binlogplayer.SetVReplicationState(vp.dbClient, vp.id, state, message) } @@ -592,7 +617,7 @@ func (vp *vplayer) writeWhereValues(sql *sqlparser.TrackedBuffer, tplan *tablePl func (vp *vplayer) updatePos(ts int64) error { updatePos := binlogplayer.GenerateUpdatePos(vp.id, vp.pos, time.Now().Unix(), ts) if _, err := vp.dbClient.ExecuteFetch(updatePos, 0); err != nil { - _ = vp.dbClient.Rollback() + vp.rollback() return fmt.Errorf("error %v updating position", err) } vp.unsavedGTID = nil diff --git a/go/vt/vttablet/tabletmanager/vreplication/vplayer_test.go b/go/vt/vttablet/tabletmanager/vreplication/vplayer_test.go index 2d9d796a431..04f11689974 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/vplayer_test.go +++ b/go/vt/vttablet/tabletmanager/vreplication/vplayer_test.go @@ -188,6 +188,15 @@ func TestFilters(t *testing.T) { func TestDDL(t *testing.T) { defer deleteTablet(addTablet(100, "0", topodatapb.TabletType_REPLICA, true, true)) + execStatements(t, []string{ + "create table dummy(id int, primary key(id))", + fmt.Sprintf("create table %s.dummy(id int, primary key(id))", vrepldb), + }) + defer execStatements(t, []string{ + "drop table dummy", + fmt.Sprintf("drop table %s.dummy", vrepldb), + }) + env.SchemaEngine.Reload(context.Background()) filter := &binlogdatapb.Filter{ Rules: []*binlogdatapb.Rule{{ @@ -196,6 +205,18 @@ func TestDDL(t *testing.T) { } cancel, _ := startVReplication(t, playerEngine, filter, binlogdatapb.OnDDLAction_IGNORE, "") + // Issue a dummy change to ensure vreplication is initialized. Otherwise there + // is a race between the DDLs and the schema loader of vstreamer. + // Root cause seems to be with MySQL where t1 shows up in information_schema before + // the actual table is created. + execStatements(t, []string{"insert into dummy values(1)"}) + expectDBClientQueries(t, []string{ + "begin", + "insert into dummy set id=1", + "/update _vt.vreplication set pos=", + "commit", + }) + execStatements(t, []string{"create table t1(id int, primary key(id))"}) execStatements(t, []string{"drop table t1"}) expectDBClientQueries(t, []string{}) @@ -265,8 +286,6 @@ func TestDDL(t *testing.T) { }) cancel() - // Don't test drop. - // MySQL rewrites them by uppercasing, which may be version specific. execStatements(t, []string{ "drop table t1", fmt.Sprintf("drop table %s.t1", vrepldb), From 519aa2127c92258dbffcb1e14973844c46ebaf6b Mon Sep 17 00:00:00 2001 From: Derek Perkins Date: Sun, 20 Jan 2019 14:59:16 -0700 Subject: [PATCH 073/115] helm: update orchestrator from 3.0.13 to 3.0.14 Signed-off-by: Derek Perkins --- docker/k8s/orchestrator/Dockerfile | 13 +++++-------- helm/vitess/values.yaml | 2 +- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/docker/k8s/orchestrator/Dockerfile b/docker/k8s/orchestrator/Dockerfile index 02c4e1e3851..b41d38d82b6 100644 --- a/docker/k8s/orchestrator/Dockerfile +++ b/docker/k8s/orchestrator/Dockerfile @@ -4,19 +4,16 @@ FROM debian:stretch-slim RUN apt-get update && \ apt-get upgrade -qq && \ - apt-get install wget -qq --no-install-recommends && \ - wget https://github.com/github/orchestrator/releases/download/v3.0.13/orchestrator_3.0.13_amd64.deb && \ - dpkg -i orchestrator_3.0.13_amd64.deb && \ - rm orchestrator_3.0.13_amd64.deb && \ + apt-get install wget ca-certificates jq -qq --no-install-recommends && \ + wget https://github.com/github/orchestrator/releases/download/v3.0.14/orchestrator_3.0.14_amd64.deb && \ + dpkg -i orchestrator_3.0.14_amd64.deb && \ + rm orchestrator_3.0.14_amd64.deb && \ apt-get purge wget -qq && \ apt-get autoremove -qq && \ apt-get clean && \ rm -rf /var/lib/apt/lists/* -# Copy certs to allow https calls -COPY --from=k8s /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt - -# Copy vtctlclient to be used to notify +# Copy vtctlclient to be used to notify COPY --from=k8s /vt/bin/vtctlclient /usr/bin/ WORKDIR /usr/local/orchestrator diff --git a/helm/vitess/values.yaml b/helm/vitess/values.yaml index 3b85d6c2d54..4488fdd934b 100644 --- a/helm/vitess/values.yaml +++ b/helm/vitess/values.yaml @@ -376,7 +376,7 @@ pmm: # Default values for orchestrator resources orchestrator: enabled: false - image: vitess/orchestrator:3.0.13 + image: vitess/orchestrator:3.0.14 replicas: 3 resources: requests: From c9d727f683a102f713a225d358be4f3ed4f5a600 Mon Sep 17 00:00:00 2001 From: Derek Perkins Date: Sun, 20 Jan 2019 15:00:29 -0700 Subject: [PATCH 074/115] helm: run pmm-admin repair to fix server data loss Signed-off-by: Derek Perkins --- helm/vitess/templates/_pmm.tpl | 1 + 1 file changed, 1 insertion(+) diff --git a/helm/vitess/templates/_pmm.tpl b/helm/vitess/templates/_pmm.tpl index afc9a57e31d..d25a759ccc8 100644 --- a/helm/vitess/templates/_pmm.tpl +++ b/helm/vitess/templates/_pmm.tpl @@ -197,6 +197,7 @@ spec: # and we want to stop/remove running services, in case pod ips have changed if pmm-admin info; then pmm-admin stop --all + pmm-admin repair pmm-admin rm --all fi From 5831222ddcbd3f1a465308d9b57e8a5c7535b2f9 Mon Sep 17 00:00:00 2001 From: Derek Perkins Date: Sun, 20 Jan 2019 15:02:34 -0700 Subject: [PATCH 075/115] helm: release 1.0.6 Signed-off-by: Derek Perkins --- helm/release.sh | 2 +- helm/vitess/CHANGELOG.md | 7 +++++++ helm/vitess/Chart.yaml | 2 +- helm/vitess/templates/_orchestrator.tpl | 4 ++-- helm/vitess/templates/_pmm.tpl | 2 +- helm/vitess/templates/_vttablet.tpl | 8 ++++---- helm/vitess/values.yaml | 10 +++++----- 7 files changed, 21 insertions(+), 14 deletions(-) diff --git a/helm/release.sh b/helm/release.sh index 890a1d76182..7c8bb639b6a 100755 --- a/helm/release.sh +++ b/helm/release.sh @@ -1,6 +1,6 @@ #!/bin/bash -version_tag=1.0.5 +version_tag=1.0.6 docker pull vitess/k8s:latest docker tag vitess/k8s:latest vitess/k8s:helm-$version_tag diff --git a/helm/vitess/CHANGELOG.md b/helm/vitess/CHANGELOG.md index 2e30bf4fea2..77c035acdfe 100644 --- a/helm/vitess/CHANGELOG.md +++ b/helm/vitess/CHANGELOG.md @@ -1,3 +1,10 @@ +## 1.0.6 - 2019-01-20 + +### Changes +* Update Orchestrator default to 3.0.14 +* Run `pmm-admin repair` on `pmm-client` startup to recover failures on `pmm-server` +* Backups now only run on `replica` (non-master), `rdonly`, or `spare` tablet types + ## 1.0.5 - 2019-01-12 ### Changes diff --git a/helm/vitess/Chart.yaml b/helm/vitess/Chart.yaml index b10a00bb2b4..c070e4b07c9 100644 --- a/helm/vitess/Chart.yaml +++ b/helm/vitess/Chart.yaml @@ -1,6 +1,6 @@ apiVersion: v1 name: vitess -version: 1.0.5 +version: 1.0.6 description: Single-Chart Vitess Cluster keywords: - vitess diff --git a/helm/vitess/templates/_orchestrator.tpl b/helm/vitess/templates/_orchestrator.tpl index 9f061154454..45b3f65f1a8 100644 --- a/helm/vitess/templates/_orchestrator.tpl +++ b/helm/vitess/templates/_orchestrator.tpl @@ -123,7 +123,7 @@ spec: value: "15999" - name: recovery-log - image: vitess/logtail:helm-1.0.5 + image: vitess/logtail:helm-1.0.6 imagePullPolicy: IfNotPresent env: - name: TAIL_FILEPATH @@ -133,7 +133,7 @@ spec: mountPath: /tmp - name: audit-log - image: vitess/logtail:helm-1.0.5 + image: vitess/logtail:helm-1.0.6 imagePullPolicy: IfNotPresent env: - name: TAIL_FILEPATH diff --git a/helm/vitess/templates/_pmm.tpl b/helm/vitess/templates/_pmm.tpl index d25a759ccc8..b6b4bdf22ef 100644 --- a/helm/vitess/templates/_pmm.tpl +++ b/helm/vitess/templates/_pmm.tpl @@ -219,7 +219,7 @@ spec: trap : TERM INT; sleep infinity & wait - name: pmm-client-metrics-log - image: vitess/logtail:helm-1.0.5 + image: vitess/logtail:helm-1.0.6 imagePullPolicy: IfNotPresent env: - name: TAIL_FILEPATH diff --git a/helm/vitess/templates/_vttablet.tpl b/helm/vitess/templates/_vttablet.tpl index 7523b796b49..a480acaf33e 100644 --- a/helm/vitess/templates/_vttablet.tpl +++ b/helm/vitess/templates/_vttablet.tpl @@ -533,7 +533,7 @@ spec: {{ define "cont-logrotate" }} - name: logrotate - image: vitess/logrotate:helm-1.0.5 + image: vitess/logrotate:helm-1.0.6 imagePullPolicy: IfNotPresent volumeMounts: - name: vtdataroot @@ -547,7 +547,7 @@ spec: {{ define "cont-mysql-errorlog" }} - name: error-log - image: vitess/logtail:helm-1.0.5 + image: vitess/logtail:helm-1.0.6 imagePullPolicy: IfNotPresent env: @@ -565,7 +565,7 @@ spec: {{ define "cont-mysql-slowlog" }} - name: slow-log - image: vitess/logtail:helm-1.0.5 + image: vitess/logtail:helm-1.0.6 imagePullPolicy: IfNotPresent env: @@ -583,7 +583,7 @@ spec: {{ define "cont-mysql-generallog" }} - name: general-log - image: vitess/logtail:helm-1.0.5 + image: vitess/logtail:helm-1.0.6 imagePullPolicy: IfNotPresent env: diff --git a/helm/vitess/values.yaml b/helm/vitess/values.yaml index 4488fdd934b..c4e5563a464 100644 --- a/helm/vitess/values.yaml +++ b/helm/vitess/values.yaml @@ -177,7 +177,7 @@ etcd: # Default values for vtctld resources defined in 'topology' vtctld: serviceType: ClusterIP - vitessTag: helm-1.0.5 + vitessTag: helm-1.0.6 resources: # requests: # cpu: 100m @@ -188,7 +188,7 @@ vtctld: # Default values for vtgate resources defined in 'topology' vtgate: serviceType: ClusterIP - vitessTag: helm-1.0.5 + vitessTag: helm-1.0.6 resources: # requests: # cpu: 500m @@ -207,13 +207,13 @@ vtgate: # Default values for vtctlclient resources defined in 'topology' vtctlclient: - vitessTag: helm-1.0.5 + vitessTag: helm-1.0.6 extraFlags: {} secrets: [] # secrets are mounted under /vt/usersecrets/{secretname} # Default values for vtworker resources defined in 'jobs' vtworker: - vitessTag: helm-1.0.5 + vitessTag: helm-1.0.6 extraFlags: {} resources: # requests: @@ -224,7 +224,7 @@ vtworker: # Default values for vttablet resources defined in 'topology' vttablet: - vitessTag: helm-1.0.5 + vitessTag: helm-1.0.6 # valid values are # - mysql56 (for MySQL 8.0) From 28392444a563351d4320a7ef97d3c847b7dec170 Mon Sep 17 00:00:00 2001 From: Sugu Sougoumarane Date: Sun, 20 Jan 2019 22:40:34 -0800 Subject: [PATCH 076/115] vplayer: go with shorter idle timeouts This allows us to avoid the whole mess about WaitForPos asking for specific positions to be exported. Signed-off-by: Sugu Sougoumarane --- .../tabletmanager/vreplication/controller.go | 14 +--- .../tabletmanager/vreplication/engine.go | 10 --- .../tabletmanager/vreplication/engine_test.go | 11 --- .../tabletmanager/vreplication/vplayer.go | 76 ++++--------------- 4 files changed, 17 insertions(+), 94 deletions(-) diff --git a/go/vt/vttablet/tabletmanager/vreplication/controller.go b/go/vt/vttablet/tabletmanager/vreplication/controller.go index 37186eb21f7..665d0f8a2a7 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/controller.go +++ b/go/vt/vttablet/tabletmanager/vreplication/controller.go @@ -22,7 +22,6 @@ import ( "strconv" "time" - "vitess.io/vitess/go/mysql" "vitess.io/vitess/go/vt/vterrors" "github.com/golang/protobuf/proto" @@ -48,9 +47,6 @@ type controller struct { mysqld mysqlctl.MysqlDaemon blpStats *binlogplayer.Stats - // vplayer is set only if we launch vplayer. - vplayer *vplayer - id uint32 source binlogdatapb.BinlogSource stopPos string @@ -193,18 +189,12 @@ func (ct *controller) runBlp(ctx context.Context) (err error) { player := binlogplayer.NewBinlogPlayerKeyRange(dbClient, tablet, ct.source.KeyRange, ct.id, ct.blpStats) return player.ApplyBinlogEvents(ctx) case ct.source.Filter != nil: - ct.vplayer = newVPlayer(ct.id, &ct.source, tablet, ct.blpStats, dbClient, ct.mysqld) - return ct.vplayer.Play(ctx) + vplayer := newVPlayer(ct.id, &ct.source, tablet, ct.blpStats, dbClient, ct.mysqld) + return vplayer.Play(ctx) } return fmt.Errorf("missing source") } -func (ct *controller) exportPosition(pos mysql.Position) { - if ct.vplayer != nil { - ct.vplayer.exportPosition(pos) - } -} - func (ct *controller) Stop() { ct.cancel() <-ct.done diff --git a/go/vt/vttablet/tabletmanager/vreplication/engine.go b/go/vt/vttablet/tabletmanager/vreplication/engine.go index 740c497626d..3577508abdc 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/engine.go +++ b/go/vt/vttablet/tabletmanager/vreplication/engine.go @@ -284,19 +284,9 @@ func (vre *Engine) WaitForPos(ctx context.Context, id int, pos string) error { if err := func() error { vre.mu.Lock() defer vre.mu.Unlock() - if !vre.isOpen { return errors.New("vreplication engine is closed") } - if ct, ok := vre.controllers[id]; ok { - mpos, err := mysql.DecodePosition(pos) - if err != nil { - return err - } - // vplayer doesn't export all the positions it receives unless - // we specifically request it for one. - ct.exportPosition(mpos) - } // Ensure that the engine won't be closed while this is running. vre.wg.Add(1) diff --git a/go/vt/vttablet/tabletmanager/vreplication/engine_test.go b/go/vt/vttablet/tabletmanager/vreplication/engine_test.go index 9bf21378e85..eb106370b56 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/engine_test.go +++ b/go/vt/vttablet/tabletmanager/vreplication/engine_test.go @@ -283,8 +283,6 @@ func TestWaitForPos(t *testing.T) { if err := vre.Open(context.Background()); err != nil { t.Fatal(err) } - // hack a controller into vre. - vre.controllers[1] = &controller{} dbClient.ExpectRequest("select pos, state, message from _vt.vreplication where id=1", &sqltypes.Result{Rows: [][]sqltypes.Value{{ sqltypes.NewVarBinary("MariaDB/0-1-1083"), @@ -321,8 +319,6 @@ func TestWaitForPosError(t *testing.T) { if err := vre.Open(context.Background()); err != nil { t.Fatal(err) } - // hack a controller into vre. - vre.controllers[1] = &controller{} err = vre.WaitForPos(context.Background(), 1, "BadFlavor/0-1-1084") want = `parse error: unknown GTIDSet flavor "BadFlavor"` @@ -367,13 +363,6 @@ func TestWaitForPosCancel(t *testing.T) { }}}, nil) ctx, cancel := context.WithCancel(context.Background()) cancel() - // hack a controller that can handle Close - done := make(chan struct{}) - close(done) - vre.controllers[1] = &controller{ - cancel: func() {}, - done: done, - } err := vre.WaitForPos(ctx, 1, "MariaDB/0-1-1084") if err == nil || err != context.Canceled { t.Errorf("WaitForPos: %v, want %v", err, context.Canceled) diff --git a/go/vt/vttablet/tabletmanager/vreplication/vplayer.go b/go/vt/vttablet/tabletmanager/vreplication/vplayer.go index 0528c920230..6d06ab802fa 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/vplayer.go +++ b/go/vt/vttablet/tabletmanager/vreplication/vplayer.go @@ -21,7 +21,6 @@ import ( "errors" "fmt" "io" - "sync" "time" "golang.org/x/net/context" @@ -41,8 +40,8 @@ import ( ) var ( - idleTimeout = 1 * time.Hour - dblockRetryDelay = 1 * time.Second + idleTimeout = 1 * time.Second + dbLockRetryDelay = 1 * time.Second ) type vplayer struct { @@ -61,18 +60,6 @@ type vplayer struct { // It remains true until the next commit or rollback. inTransaction bool - // mu protects exportPositions. - // exportPositions specifies a list of positions. - // Anytime the vplayer reaches or exceeds one of these - // positions, it will update the position even if it's - // an empty transaction. This is used for cases where - // a target is stopped, and a request is initiated to - // wait for vreplication to reach the source's position. - // Since vreplication only updates state on non-empty - // transactions, this list is used to force such updates. - mu sync.Mutex - exportPositions []mysql.Position - pplan *playerPlan tplans map[string]*tablePlan } @@ -204,10 +191,17 @@ func (vp *vplayer) applyEvents(relay *relayLog) error { if err != nil { return err } - // Don't do special things in the middle of a transaction. - if !vp.inTransaction && vp.mustExport() { - if err := vp.updatePos(vp.unsavedGTID.Timestamp); err != nil { - return err + // This covers two situations: + // 1. Fetch was idle for idleTimeout. + // 2. We've been receiving empty events for longer than idleTimeout. + // In both cases, now > timeLastSaved. If so, any unsaved GTID should be saved. + if time.Now().Sub(vp.timeLastSaved) >= idleTimeout && vp.unsavedGTID != nil { + // Although unlikely, we should not save if a transaction is still open. + // This can happen if a large transaction is split as multiple events. + if !vp.inTransaction { + if err := vp.updatePos(vp.unsavedGTID.Timestamp); err != nil { + return err + } } } for i, events := range items { @@ -219,10 +213,6 @@ func (vp *vplayer) applyEvents(relay *relayLog) error { mustSave = true break } - if vp.mustExport() { - mustSave = true - break - } if hasAnotherCommit(items, i, j+1) { continue } @@ -235,36 +225,6 @@ func (vp *vplayer) applyEvents(relay *relayLog) error { } } -func (vp *vplayer) mustExport() bool { - // This covers two situations: - // 1. Fetch was idle for idleTimeout. - // 2. We've been receiving empty events for longer than idleTimeout. - // In both cases, now > timeLastSaved. If so, any unsaved GTID should be saved - // to prevent us from falling behind on tracking the source binlog position. - if time.Now().Sub(vp.timeLastSaved) >= idleTimeout && vp.unsavedGTID != nil { - return true - } - - vp.mu.Lock() - defer vp.mu.Unlock() - - mustExport := false - for { - found := false - for i, export := range vp.exportPositions { - if vp.pos.AtLeast(export) { - mustExport = true - found = true - vp.exportPositions = append(vp.exportPositions[:i], vp.exportPositions[i+1:]...) - break - } - } - if !found { - return mustExport - } - } -} - func hasAnotherCommit(items [][]*binlogdatapb.VEvent, i, j int) bool { for i < len(items) { for j < len(items[i]) { @@ -631,8 +591,8 @@ func (vp *vplayer) exec(sql string) error { for err != nil { // 1213: deadlock, 1205: lock wait timeout if sqlErr, ok := err.(*mysql.SQLError); ok && sqlErr.Number() == 1213 || sqlErr.Number() == 1205 { - log.Infof("retryable error: %v, waiting for %v and retrying", sqlErr, dblockRetryDelay) - time.Sleep(dblockRetryDelay) + log.Infof("retryable error: %v, waiting for %v and retrying", sqlErr, dbLockRetryDelay) + time.Sleep(dbLockRetryDelay) err = vp.dbClient.Retry() continue } @@ -641,12 +601,6 @@ func (vp *vplayer) exec(sql string) error { return nil } -func (vp *vplayer) exportPosition(pos mysql.Position) { - vp.mu.Lock() - defer vp.mu.Unlock() - vp.exportPositions = append(vp.exportPositions, pos) -} - func encodeValue(sql *sqlparser.TrackedBuffer, value sqltypes.Value) { if value.Type() == querypb.Type_TIMESTAMP && !bytes.HasPrefix(value.ToBytes(), mysql.ZeroTimestamp) { // Values in the binary log are UTC. Let's convert them From 8199e401e5effa0027158e53936b819a7268bd08 Mon Sep 17 00:00:00 2001 From: Sugu Sougoumarane Date: Mon, 21 Jan 2019 01:54:21 -0800 Subject: [PATCH 077/115] vplayer: more tests Signed-off-by: Sugu Sougoumarane --- .../tabletmanager/vreplication/relaylog.go | 26 +++-- .../vreplication/vplayer_test.go | 98 ++++++++++++++++++- 2 files changed, 105 insertions(+), 19 deletions(-) diff --git a/go/vt/vttablet/tabletmanager/vreplication/relaylog.go b/go/vt/vttablet/tabletmanager/vreplication/relaylog.go index 64504b5457a..f0714390d2e 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/relaylog.go +++ b/go/vt/vttablet/tabletmanager/vreplication/relaylog.go @@ -34,11 +34,11 @@ type relayLog struct { // mu controls all variables below and is shared by canAccept and hasItems. // Broadcasting must be done while holding mu. This is mainly necessary because both // conditions depend on ctx.Done(), which can change state asynchronously. - mu sync.Mutex - curSize int - items [][]*binlogdatapb.VEvent - interruptFetch bool - err error + mu sync.Mutex + curSize int + items [][]*binlogdatapb.VEvent + timedout bool + err error // canAccept is true if: curSize<=maxSize, len(items)0, ctx is not Done, and interuptFetch is false. @@ -93,13 +93,13 @@ func (rl *relayLog) Fetch() ([][]*binlogdatapb.VEvent, error) { } cancelTimer := rl.startTimer() defer cancelTimer() - for len(rl.items) == 0 && !rl.interruptFetch { + for len(rl.items) == 0 && !rl.timedout { rl.hasItems.Wait() if err := rl.checkDone(); err != nil { return nil, err } } - rl.interruptFetch = false + rl.timedout = false items := rl.items rl.items = nil rl.curSize = 0 @@ -122,7 +122,10 @@ func (rl *relayLog) startTimer() (cancel func()) { go func() { select { case <-timer.C: - rl.InterruptFetch() + rl.mu.Lock() + defer rl.mu.Unlock() + rl.timedout = true + rl.hasItems.Broadcast() case <-timerDone: } }() @@ -132,13 +135,6 @@ func (rl *relayLog) startTimer() (cancel func()) { } } -func (rl *relayLog) InterruptFetch() { - rl.mu.Lock() - defer rl.mu.Unlock() - rl.interruptFetch = true - rl.hasItems.Broadcast() -} - func eventsSize(events []*binlogdatapb.VEvent) int { size := 0 for _, event := range events { diff --git a/go/vt/vttablet/tabletmanager/vreplication/vplayer_test.go b/go/vt/vttablet/tabletmanager/vreplication/vplayer_test.go index 04f11689974..38006ff3d56 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/vplayer_test.go +++ b/go/vt/vttablet/tabletmanager/vreplication/vplayer_test.go @@ -17,9 +17,11 @@ limitations under the License. package vreplication import ( + "flag" "fmt" "strings" "testing" + "time" "golang.org/x/net/context" "vitess.io/vitess/go/mysql" @@ -29,7 +31,7 @@ import ( topodatapb "vitess.io/vitess/go/vt/proto/topodata" ) -func TestFilters(t *testing.T) { +func TestPlayerFilters(t *testing.T) { defer deleteTablet(addTablet(100, "0", topodatapb.TabletType_REPLICA, true, true)) execStatements(t, []string{ @@ -186,7 +188,7 @@ func TestFilters(t *testing.T) { } } -func TestDDL(t *testing.T) { +func TestPlayerDDL(t *testing.T) { defer deleteTablet(addTablet(100, "0", topodatapb.TabletType_REPLICA, true, true)) execStatements(t, []string{ "create table dummy(id int, primary key(id))", @@ -294,7 +296,7 @@ func TestDDL(t *testing.T) { }) } -func TestStopPos(t *testing.T) { +func TestPlayerStopPos(t *testing.T) { defer deleteTablet(addTablet(100, "0", topodatapb.TabletType_REPLICA, true, true)) execStatements(t, []string{ @@ -388,10 +390,98 @@ func TestStopPos(t *testing.T) { }) } +func TestPlayerIdleUpdate(t *testing.T) { + defer deleteTablet(addTablet(100, "0", topodatapb.TabletType_REPLICA, true, true)) + + savedIdleTimeout := idleTimeout + defer func() { idleTimeout = savedIdleTimeout }() + idleTimeout = 100 * time.Millisecond + + execStatements(t, []string{ + "create table t1(id int, val varbinary(128), primary key(id))", + fmt.Sprintf("create table %s.t1(id int, val varbinary(128), primary key(id))", vrepldb), + }) + defer execStatements(t, []string{ + "drop table t1", + fmt.Sprintf("drop table %s.t1", vrepldb), + }) + env.SchemaEngine.Reload(context.Background()) + + filter := &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{{ + Match: "/.*", + }}, + } + cancel, _ := startVReplication(t, playerEngine, filter, binlogdatapb.OnDDLAction_IGNORE, "") + defer cancel() + + execStatements(t, []string{ + "insert into t1 values(1, 'aaa')", + }) + start := time.Now() + expectDBClientQueries(t, []string{ + "begin", + "insert into t1 set id=1, val='aaa'", + "/update _vt.vreplication set pos=", + "commit", + }) + // The above write will generate a new binlog event, and + // that event will loopback into player as an empty event. + // But it must not get saved until idleTimeout has passed. + // The exact positions are hard to verify because of this + // loopback mechanism. + expectDBClientQueries(t, []string{ + "/update _vt.vreplication set pos=", + }) + if duration := time.Now().Sub(start); duration < idleTimeout { + t.Errorf("duration: %v, must be at least %v", duration, idleTimeout) + } +} + +func TestPlayerSplitTransaction(t *testing.T) { + defer deleteTablet(addTablet(100, "0", topodatapb.TabletType_REPLICA, true, true)) + flag.Set("vstream_packet_size", "10") + defer flag.Set("vstream_packet_size", "10000") + + execStatements(t, []string{ + "create table t1(id int, val varbinary(128), primary key(id))", + fmt.Sprintf("create table %s.t1(id int, val varbinary(128), primary key(id))", vrepldb), + }) + defer execStatements(t, []string{ + "drop table t1", + fmt.Sprintf("drop table %s.t1", vrepldb), + }) + env.SchemaEngine.Reload(context.Background()) + + filter := &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{{ + Match: "/.*", + }}, + } + cancel, _ := startVReplication(t, playerEngine, filter, binlogdatapb.OnDDLAction_IGNORE, "") + defer cancel() + + execStatements(t, []string{ + "begin", + "insert into t1 values(1, '123456')", + "insert into t1 values(2, '789012')", + "commit", + }) + // Because the packet size is 10, this is received as two events, + // but still combined as one transaction. + expectDBClientQueries(t, []string{ + "begin", + "insert into t1 set id=1, val='123456'", + "insert into t1 set id=2, val='789012'", + "/update _vt.vreplication set pos=", + "commit", + }) +} + func execStatements(t *testing.T, queries []string) { t.Helper() if err := env.Mysqld.ExecuteSuperQueryList(context.Background(), queries); err != nil { - t.Fatal(err) + t.Error(err) } } From d7e5c3f3a412f7bd253f74086fd80019a3852f60 Mon Sep 17 00:00:00 2001 From: Dongyan Xu Date: Mon, 21 Jan 2019 10:45:35 +0000 Subject: [PATCH 078/115] Make kmysql.sh work on Vitess on a single K8s node setup by Kubeadm.( Accordiing to https://kubernetes.io/docs/setup/independent/create-cluster-kubeadm/) The change is backward compatible with Vitess on Minikube. Signed-off-by: Dongyan Xu --- examples/helm/kmysql.sh | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/examples/helm/kmysql.sh b/examples/helm/kmysql.sh index 5c997dfee26..d2a07e4cb84 100755 --- a/examples/helm/kmysql.sh +++ b/examples/helm/kmysql.sh @@ -19,4 +19,18 @@ host=$(minikube service vtgate-zone1 --format "{{.IP}}" | tail -n 1) port=$(minikube service vtgate-zone1 --format "{{.Port}}" | tail -n 1) +if [ -z $port ]; then + #This checks K8s runing on an single node by kubeadm + if [ $(kubectl get nodes | grep -v NAM | wc -l) -eq 1 -o $(kubectl get nodes | grep -v NAM | grep master | wc -l ) -eq 1 ]; then + host="127.0.0.1" + port=`kubectl describe service vtgate-zone1 | grep NodePort | grep mysql | awk '{print $3}' | awk -F'/' '{print $1}'` + fi +fi + +if [ -z $port ]; then + echo "Error: failed to obtain [host:port] minikube or kubectl." + exit 1; + +fi + mysql -h "$host" -P "$port" $* From c98ab1af2d5e25b750bcdeb59d27d2131531b908 Mon Sep 17 00:00:00 2001 From: Sugu Sougoumarane Date: Tue, 22 Jan 2019 01:26:17 -0800 Subject: [PATCH 079/115] vplayer: more tests and timestamp fixes Signed-off-by: Sugu Sougoumarane --- .../vreplication/framework_test.go | 19 +- ...retryableClient.go => retryable_client.go} | 31 +- .../tabletmanager/vreplication/vplayer.go | 72 +-- .../vreplication/vplayer_test.go | 450 +++++++++++++++++- 4 files changed, 514 insertions(+), 58 deletions(-) rename go/vt/vttablet/tabletmanager/vreplication/{retryableClient.go => retryable_client.go} (77%) diff --git a/go/vt/vttablet/tabletmanager/vreplication/framework_test.go b/go/vt/vttablet/tabletmanager/vreplication/framework_test.go index 5149b3bf00d..ea1cd2dc63d 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/framework_test.go +++ b/go/vt/vttablet/tabletmanager/vreplication/framework_test.go @@ -95,6 +95,11 @@ func TestMain(m *testing.M) { return 1 } + if err := env.Mysqld.ExecuteSuperQuery(context.Background(), "set @@global.innodb_lock_wait_timeout=1"); err != nil { + fmt.Fprintf(os.Stderr, "%v", err) + return 1 + } + playerEngine = NewEngine(env.TopoServ, env.Cells[0], env.Mysqld, realDBClientFactory) if err := playerEngine.Open(context.Background()); err != nil { fmt.Fprintf(os.Stderr, "%v", err) @@ -278,7 +283,8 @@ func realDBClientFactory() binlogplayer.DBClient { } type realDBClient struct { - conn *mysql.Conn + conn *mysql.Conn + nolog bool } func (dbc *realDBClient) DBName() string { @@ -297,20 +303,17 @@ func (dbc *realDBClient) Connect() error { } func (dbc *realDBClient) Begin() error { - _, err := dbc.conn.ExecuteFetch("begin", 10000, true) - globalDBQueries <- "begin" + _, err := dbc.ExecuteFetch("begin", 10000) return err } func (dbc *realDBClient) Commit() error { - _, err := dbc.conn.ExecuteFetch("commit", 10000, true) - globalDBQueries <- "commit" + _, err := dbc.ExecuteFetch("commit", 10000) return err } func (dbc *realDBClient) Rollback() error { - _, err := dbc.conn.ExecuteFetch("rollback", 10000, true) - globalDBQueries <- "rollback" + _, err := dbc.ExecuteFetch("rollback", 10000) return err } @@ -324,7 +327,7 @@ func (dbc *realDBClient) ExecuteFetch(query string, maxrows int) (*sqltypes.Resu return nil, nil } qr, err := dbc.conn.ExecuteFetch(query, 10000, true) - if !strings.HasPrefix(query, "select") { + if !strings.HasPrefix(query, "select") && !dbc.nolog { globalDBQueries <- query } return qr, err diff --git a/go/vt/vttablet/tabletmanager/vreplication/retryableClient.go b/go/vt/vttablet/tabletmanager/vreplication/retryable_client.go similarity index 77% rename from go/vt/vttablet/tabletmanager/vreplication/retryableClient.go rename to go/vt/vttablet/tabletmanager/vreplication/retryable_client.go index 30deacf155b..f08cd99cf37 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/retryableClient.go +++ b/go/vt/vttablet/tabletmanager/vreplication/retryable_client.go @@ -21,16 +21,29 @@ import ( "vitess.io/vitess/go/vt/binlog/binlogplayer" ) +// retryableClient is a wrapper on binlogplayer.DBClient. +// It allows us to retry a failed transactions on lock errors. type retryableClient struct { binlogplayer.DBClient inTransaction bool queries []string } +func (rt *retryableClient) Connect() error { + if err := rt.Connect(); err != nil { + return err + } + if _, err := rt.DBClient.ExecuteFetch("set @@session.time_zone = '+00:00'", 10000); err != nil { + return err + } + return nil +} + func (rt *retryableClient) Begin() error { if err := rt.DBClient.Begin(); err != nil { return err } + rt.queries = append(rt.queries, "begin") rt.inTransaction = true return nil } @@ -49,7 +62,7 @@ func (rt *retryableClient) Rollback() error { return err } rt.inTransaction = false - rt.queries = nil + // Don't reset queries to allow for vplayer to retry. return nil } @@ -63,17 +76,13 @@ func (rt *retryableClient) ExecuteFetch(query string, maxrows int) (*sqltypes.Re } func (rt *retryableClient) Retry() error { - if !rt.inTransaction { - _, err := rt.DBClient.ExecuteFetch(rt.queries[0], 10000) - return err - } - if err := rt.DBClient.Rollback(); err != nil { - return err - } - if err := rt.DBClient.Begin(); err != nil { - return err - } for _, q := range rt.queries { + if q == "begin" { + if err := rt.Begin(); err != nil { + return err + } + continue + } if _, err := rt.DBClient.ExecuteFetch(q, 10000); err != nil { return err } diff --git a/go/vt/vttablet/tabletmanager/vreplication/vplayer.go b/go/vt/vttablet/tabletmanager/vreplication/vplayer.go index 6d06ab802fa..66b2937d7a4 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/vplayer.go +++ b/go/vt/vttablet/tabletmanager/vreplication/vplayer.go @@ -17,7 +17,6 @@ limitations under the License. package vreplication import ( - "bytes" "errors" "fmt" "io" @@ -42,6 +41,8 @@ import ( var ( idleTimeout = 1 * time.Second dbLockRetryDelay = 1 * time.Second + relayLogMaxSize = 10000 + relayLogMaxItems = 1000 ) type vplayer struct { @@ -50,17 +51,25 @@ type vplayer struct { sourceTablet *topodatapb.Tablet stats *binlogplayer.Stats dbClient *retryableClient - mysqld mysqlctl.MysqlDaemon - - pos mysql.Position - unsavedGTID *binlogdatapb.VEvent + // mysqld is used to fetch the local schema. + mysqld mysqlctl.MysqlDaemon + + pos mysql.Position + // unsavedGTID when we receive a GTID event and reset + // if it gets saved. If Fetch returns on idleTimeout, + // we save the last unsavedGTID. + unsavedGTID *binlogdatapb.VEvent + // timeLastSaved is set every time a GTID is saved. timeLastSaved time.Time stopPos mysql.Position // inTransaction is true if we've started a transaction. // It remains true until the next commit or rollback. inTransaction bool - pplan *playerPlan + // pplan is built based on the source Filter at the beginning. + pplan *playerPlan + // tplans[table] is built for each table based on pplan and schema info + // about the table. tplans map[string]*tablePlan } @@ -130,7 +139,7 @@ func (vp *vplayer) play(ctx context.Context) error { ctx, cancel := context.WithCancel(ctx) defer cancel() - relay := newRelayLog(ctx, 10, 10) + relay := newRelayLog(ctx, relayLogMaxItems, relayLogMaxSize) target := &querypb.Target{ Keyspace: vp.sourceTablet.Keyspace, @@ -147,7 +156,7 @@ func (vp *vplayer) play(ctx context.Context) error { applyErr := make(chan error, 1) go func() { - applyErr <- vp.applyEvents(relay) + applyErr <- vp.applyEvents(ctx, relay) }() select { @@ -185,7 +194,7 @@ func (vp *vplayer) play(ctx context.Context) error { } } -func (vp *vplayer) applyEvents(relay *relayLog) error { +func (vp *vplayer) applyEvents(ctx context.Context, relay *relayLog) error { for { items, err := relay.Fetch() if err != nil { @@ -217,7 +226,7 @@ func (vp *vplayer) applyEvents(relay *relayLog) error { continue } } - if err := vp.applyEvent(event, mustSave); err != nil { + if err := vp.applyEvent(ctx, event, mustSave); err != nil { return err } } @@ -243,7 +252,7 @@ func hasAnotherCommit(items [][]*binlogdatapb.VEvent, i, j int) bool { return false } -func (vp *vplayer) applyEvent(event *binlogdatapb.VEvent, mustSave bool) error { +func (vp *vplayer) applyEvent(ctx context.Context, event *binlogdatapb.VEvent, mustSave bool) error { switch event.Type { case binlogdatapb.VEventType_GTID: pos, err := mysql.DecodePosition(event.Gtid) @@ -300,7 +309,7 @@ func (vp *vplayer) applyEvent(event *binlogdatapb.VEvent, mustSave bool) error { if err := vp.begin(); err != nil { return err } - if err := vp.applyRowEvent(event.RowEvent); err != nil { + if err := vp.applyRowEvent(ctx, event.RowEvent); err != nil { return err } case binlogdatapb.VEventType_DDL: @@ -325,14 +334,14 @@ func (vp *vplayer) applyEvent(event *binlogdatapb.VEvent, mustSave bool) error { } return io.EOF case binlogdatapb.OnDDLAction_EXEC: - if err := vp.exec(event.Ddl); err != nil { + if err := vp.exec(ctx, event.Ddl); err != nil { return err } if err := vp.updatePos(event.Timestamp); err != nil { return err } case binlogdatapb.OnDDLAction_EXEC_IGNORE: - if err := vp.exec(event.Ddl); err != nil { + if err := vp.exec(ctx, event.Ddl); err != nil { log.Infof("Ignoring error: %v for DDL: %s", err, event.Ddl) } if err := vp.updatePos(event.Timestamp); err != nil { @@ -425,20 +434,20 @@ func (vp *vplayer) updatePlan(fieldEvent *binlogdatapb.FieldEvent) error { return nil } -func (vp *vplayer) applyRowEvent(rowEvent *binlogdatapb.RowEvent) error { +func (vp *vplayer) applyRowEvent(ctx context.Context, rowEvent *binlogdatapb.RowEvent) error { tplan := vp.tplans[rowEvent.TableName] if tplan == nil { return fmt.Errorf("unexpected event on table %s", rowEvent.TableName) } for _, change := range rowEvent.RowChanges { - if err := vp.applyRowChange(tplan, change); err != nil { + if err := vp.applyRowChange(ctx, tplan, change); err != nil { return err } } return nil } -func (vp *vplayer) applyRowChange(tplan *tablePlan, rowChange *binlogdatapb.RowChange) error { +func (vp *vplayer) applyRowChange(ctx context.Context, tplan *tablePlan, rowChange *binlogdatapb.RowChange) error { // MakeRowTrusted is needed here because because Proto3ToResult is not convenient. var before, after []sqltypes.Value if rowChange.Before != nil { @@ -461,7 +470,7 @@ func (vp *vplayer) applyRowChange(tplan *tablePlan, rowChange *binlogdatapb.RowC if query == "" { return nil } - return vp.exec(query) + return vp.exec(ctx, query) } func (vp *vplayer) generateInsert(tplan *tablePlan, after []sqltypes.Value) string { @@ -585,14 +594,23 @@ func (vp *vplayer) updatePos(ts int64) error { return nil } -func (vp *vplayer) exec(sql string) error { +func (vp *vplayer) exec(ctx context.Context, sql string) error { vp.stats.Timings.Record("query", time.Now()) _, err := vp.dbClient.ExecuteFetch(sql, 0) for err != nil { // 1213: deadlock, 1205: lock wait timeout if sqlErr, ok := err.(*mysql.SQLError); ok && sqlErr.Number() == 1213 || sqlErr.Number() == 1205 { log.Infof("retryable error: %v, waiting for %v and retrying", sqlErr, dbLockRetryDelay) + if err := vp.dbClient.Rollback(); err != nil { + return err + } time.Sleep(dbLockRetryDelay) + // Check context here. Otherwise this can become an infinite loop. + select { + case <-ctx.Done(): + return io.EOF + default: + } err = vp.dbClient.Retry() continue } @@ -602,14 +620,10 @@ func (vp *vplayer) exec(sql string) error { } func encodeValue(sql *sqlparser.TrackedBuffer, value sqltypes.Value) { - if value.Type() == querypb.Type_TIMESTAMP && !bytes.HasPrefix(value.ToBytes(), mysql.ZeroTimestamp) { - // Values in the binary log are UTC. Let's convert them - // to whatever timezone the connection is using, - // so MySQL properly converts them back to UTC. - sql.WriteString("convert_tz(") - value.EncodeSQL(sql) - sql.WriteString(", '+00:00', @@session.time_zone)") - } else { - value.EncodeSQL(sql) - } + // This is currently a separate function because special handling + // may be needed for certain types. + // Previously, this function used to convert timestamp to the session + // time zone, but we now set the session timezone to UTC. So, the timestamp + // value we receive as UTC can be sent as is. + value.EncodeSQL(sql) } diff --git a/go/vt/vttablet/tabletmanager/vreplication/vplayer_test.go b/go/vt/vttablet/tabletmanager/vreplication/vplayer_test.go index 38006ff3d56..a1b06f4b609 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/vplayer_test.go +++ b/go/vt/vttablet/tabletmanager/vreplication/vplayer_test.go @@ -72,7 +72,7 @@ func TestPlayerFilters(t *testing.T) { Match: "/yes", }}, } - cancel, _ := startVReplication(t, playerEngine, filter, binlogdatapb.OnDDLAction_IGNORE, "") + cancel, _ := startVReplication(t, filter, binlogdatapb.OnDDLAction_IGNORE, "") defer cancel() testcases := []struct { @@ -206,7 +206,7 @@ func TestPlayerDDL(t *testing.T) { }}, } - cancel, _ := startVReplication(t, playerEngine, filter, binlogdatapb.OnDDLAction_IGNORE, "") + cancel, _ := startVReplication(t, filter, binlogdatapb.OnDDLAction_IGNORE, "") // Issue a dummy change to ensure vreplication is initialized. Otherwise there // is a race between the DDLs and the schema loader of vstreamer. // Root cause seems to be with MySQL where t1 shows up in information_schema before @@ -224,7 +224,7 @@ func TestPlayerDDL(t *testing.T) { expectDBClientQueries(t, []string{}) cancel() - cancel, id := startVReplication(t, playerEngine, filter, binlogdatapb.OnDDLAction_STOP, "") + cancel, id := startVReplication(t, filter, binlogdatapb.OnDDLAction_STOP, "") execStatements(t, []string{"create table t1(id int, primary key(id))"}) pos1 := masterPosition(t) execStatements(t, []string{"drop table t1"}) @@ -252,7 +252,7 @@ func TestPlayerDDL(t *testing.T) { cancel() execStatements(t, []string{fmt.Sprintf("create table %s.t2(id int, primary key(id))", vrepldb)}) - cancel, _ = startVReplication(t, playerEngine, filter, binlogdatapb.OnDDLAction_EXEC, "") + cancel, _ = startVReplication(t, filter, binlogdatapb.OnDDLAction_EXEC, "") execStatements(t, []string{"create table t1(id int, primary key(id))"}) expectDBClientQueries(t, []string{ "create table t1(id int, primary key(id))", @@ -275,7 +275,7 @@ func TestPlayerDDL(t *testing.T) { }) execStatements(t, []string{fmt.Sprintf("create table %s.t2(id int, primary key(id))", vrepldb)}) - cancel, _ = startVReplication(t, playerEngine, filter, binlogdatapb.OnDDLAction_EXEC_IGNORE, "") + cancel, _ = startVReplication(t, filter, binlogdatapb.OnDDLAction_EXEC_IGNORE, "") execStatements(t, []string{"create table t1(id int, primary key(id))"}) expectDBClientQueries(t, []string{ "create table t1(id int, primary key(id))", @@ -412,7 +412,7 @@ func TestPlayerIdleUpdate(t *testing.T) { Match: "/.*", }}, } - cancel, _ := startVReplication(t, playerEngine, filter, binlogdatapb.OnDDLAction_IGNORE, "") + cancel, _ := startVReplication(t, filter, binlogdatapb.OnDDLAction_IGNORE, "") defer cancel() execStatements(t, []string{ @@ -458,7 +458,7 @@ func TestPlayerSplitTransaction(t *testing.T) { Match: "/.*", }}, } - cancel, _ := startVReplication(t, playerEngine, filter, binlogdatapb.OnDDLAction_IGNORE, "") + cancel, _ := startVReplication(t, filter, binlogdatapb.OnDDLAction_IGNORE, "") defer cancel() execStatements(t, []string{ @@ -478,6 +478,436 @@ func TestPlayerSplitTransaction(t *testing.T) { }) } +func TestPlayerLockErrors(t *testing.T) { + defer deleteTablet(addTablet(100, "0", topodatapb.TabletType_REPLICA, true, true)) + + execStatements(t, []string{ + "create table t1(id int, val varbinary(128), primary key(id))", + fmt.Sprintf("create table %s.t1(id int, val varbinary(128), primary key(id))", vrepldb), + }) + defer execStatements(t, []string{ + "drop table t1", + fmt.Sprintf("drop table %s.t1", vrepldb), + }) + env.SchemaEngine.Reload(context.Background()) + + filter := &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{{ + Match: "/.*", + }}, + } + cancel, _ := startVReplication(t, filter, binlogdatapb.OnDDLAction_IGNORE, "") + defer cancel() + + execStatements(t, []string{ + "begin", + "insert into t1 values(1, 'aaa')", + "insert into t1 values(2, 'bbb')", + "commit", + }) + expectDBClientQueries(t, []string{ + "begin", + "insert into t1 set id=1, val='aaa'", + "insert into t1 set id=2, val='bbb'", + "/update _vt.vreplication set pos=", + "commit", + }) + + vconn := &realDBClient{nolog: true} + if err := vconn.Connect(); err != nil { + t.Error(err) + } + defer vconn.Close() + + // Start a transaction and lock the second row. + if _, err := vconn.ExecuteFetch("begin", 1); err != nil { + t.Error(err) + } + if _, err := vconn.ExecuteFetch("update t1 set val='bbb' where id=2", 1); err != nil { + t.Error(err) + } + + execStatements(t, []string{ + "begin", + "update t1 set val='ccc' where id=1", + "update t1 set val='ccc' where id=2", + "commit", + }) + // The innodb lock wait timeout is set to 1s. + expectDBClientQueries(t, []string{ + "begin", + "update t1 set id=1, val='ccc' where id=1", + "update t1 set id=2, val='ccc' where id=2", + "rollback", + }) + + // Release the lock, and watch the retry go through. + _, _ = vconn.ExecuteFetch("rollback", 1) + expectDBClientQueries(t, []string{ + "begin", + "update t1 set id=1, val='ccc' where id=1", + "update t1 set id=2, val='ccc' where id=2", + "/update _vt.vreplication set pos=", + "commit", + }) +} + +func TestPlayerCancelOnLock(t *testing.T) { + defer deleteTablet(addTablet(100, "0", topodatapb.TabletType_REPLICA, true, true)) + + execStatements(t, []string{ + "create table t1(id int, val varbinary(128), primary key(id))", + fmt.Sprintf("create table %s.t1(id int, val varbinary(128), primary key(id))", vrepldb), + }) + defer execStatements(t, []string{ + "drop table t1", + fmt.Sprintf("drop table %s.t1", vrepldb), + }) + env.SchemaEngine.Reload(context.Background()) + + filter := &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{{ + Match: "/.*", + }}, + } + cancel, _ := startVReplication(t, filter, binlogdatapb.OnDDLAction_IGNORE, "") + defer cancel() + + execStatements(t, []string{ + "begin", + "insert into t1 values(1, 'aaa')", + "commit", + }) + expectDBClientQueries(t, []string{ + "begin", + "insert into t1 set id=1, val='aaa'", + "/update _vt.vreplication set pos=", + "commit", + }) + + vconn := &realDBClient{nolog: true} + if err := vconn.Connect(); err != nil { + t.Error(err) + } + defer vconn.Close() + + // Start a transaction and lock the row. + if _, err := vconn.ExecuteFetch("begin", 1); err != nil { + t.Error(err) + } + if _, err := vconn.ExecuteFetch("update t1 set val='bbb' where id=1", 1); err != nil { + t.Error(err) + } + + execStatements(t, []string{ + "begin", + "update t1 set val='ccc' where id=1", + "commit", + }) + // The innodb lock wait timeout is set to 1s. + expectDBClientQueries(t, []string{ + "begin", + "update t1 set id=1, val='ccc' where id=1", + "rollback", + }) + + // VReplication should not get stuck if you cancel now. + done := make(chan bool) + go func() { + cancel() + close(done) + }() + select { + case <-done: + case <-time.After(5 * time.Second): + t.Error("cancel is hung") + } +} + +func TestPlayerBatching(t *testing.T) { + defer deleteTablet(addTablet(100, "0", topodatapb.TabletType_REPLICA, true, true)) + + execStatements(t, []string{ + "create table t1(id int, val varbinary(128), primary key(id))", + fmt.Sprintf("create table %s.t1(id int, val varbinary(128), primary key(id))", vrepldb), + }) + defer execStatements(t, []string{ + "drop table t1", + fmt.Sprintf("drop table %s.t1", vrepldb), + }) + env.SchemaEngine.Reload(context.Background()) + + filter := &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{{ + Match: "/.*", + }}, + } + cancel, _ := startVReplication(t, filter, binlogdatapb.OnDDLAction_IGNORE, "") + defer cancel() + + execStatements(t, []string{ + "insert into t1 values(1, 'aaa')", + }) + expectDBClientQueries(t, []string{ + "begin", + "insert into t1 set id=1, val='aaa'", + "/update _vt.vreplication set pos=", + "commit", + }) + + vconn := &realDBClient{nolog: true} + if err := vconn.Connect(); err != nil { + t.Error(err) + } + defer vconn.Close() + + // Start a transaction and lock the row. + if _, err := vconn.ExecuteFetch("begin", 1); err != nil { + t.Error(err) + } + if _, err := vconn.ExecuteFetch("update t1 set val='bbb' where id=1", 1); err != nil { + t.Error(err) + } + + // create one transaction + execStatements(t, []string{ + "update t1 set val='ccc' where id=1", + }) + // Wait for the begin. The update will be blocked. + expectDBClientQueries(t, []string{ + "begin", + }) + + // Create two more transactions. They will go and wait in the relayLog. + execStatements(t, []string{ + "insert into t1 values(2, 'aaa')", + "insert into t1 values(3, 'aaa')", + }) + + // Release the lock. + _, _ = vconn.ExecuteFetch("rollback", 1) + // First transaction will complete. The other two + // transactions must be batched into one + expectDBClientQueries(t, []string{ + "update t1 set id=1, val='ccc' where id=1", + "/update _vt.vreplication set pos=", + "commit", + "begin", + "insert into t1 set id=2, val='aaa'", + "insert into t1 set id=3, val='aaa'", + "/update _vt.vreplication set pos=", + "commit", + }) +} + +func TestPlayerRelayLogMaxSize(t *testing.T) { + defer deleteTablet(addTablet(100, "0", topodatapb.TabletType_REPLICA, true, true)) + + for i := 0; i < 2; i++ { + // First iteration checks max size, second checks max items + func() { + switch i { + case 0: + savedSize := relayLogMaxSize + defer func() { relayLogMaxSize = savedSize }() + relayLogMaxSize = 10 + case 1: + savedLen := relayLogMaxItems + defer func() { relayLogMaxItems = savedLen }() + relayLogMaxItems = 2 + } + + execStatements(t, []string{ + "create table t1(id int, val varbinary(128), primary key(id))", + fmt.Sprintf("create table %s.t1(id int, val varbinary(128), primary key(id))", vrepldb), + }) + defer execStatements(t, []string{ + "drop table t1", + fmt.Sprintf("drop table %s.t1", vrepldb), + }) + env.SchemaEngine.Reload(context.Background()) + + filter := &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{{ + Match: "/.*", + }}, + } + cancel, _ := startVReplication(t, filter, binlogdatapb.OnDDLAction_IGNORE, "") + defer cancel() + + execStatements(t, []string{ + "insert into t1 values(1, '123456')", + }) + expectDBClientQueries(t, []string{ + "begin", + "insert into t1 set id=1, val='123456'", + "/update _vt.vreplication set pos=", + "commit", + }) + + vconn := &realDBClient{nolog: true} + if err := vconn.Connect(); err != nil { + t.Error(err) + } + defer vconn.Close() + + // Start a transaction and lock the row. + if _, err := vconn.ExecuteFetch("begin", 1); err != nil { + t.Error(err) + } + if _, err := vconn.ExecuteFetch("update t1 set val='bbb' where id=1", 1); err != nil { + t.Error(err) + } + + // create one transaction + execStatements(t, []string{ + "update t1 set val='ccc' where id=1", + }) + // Wait for the begin. The update will be blocked. + expectDBClientQueries(t, []string{ + "begin", + }) + + // Create two more transactions. They will go and wait in the relayLog. + execStatements(t, []string{ + "insert into t1 values(2, '789012')", + "insert into t1 values(3, '345678')", + "insert into t1 values(4, '901234')", + }) + + // Release the lock. + _, _ = vconn.ExecuteFetch("rollback", 1) + // First transaction will complete. The other two + // transactions must be batched into one. The last transaction + // will wait to be sent to the relay until the player fetches + // them. + expectDBClientQueries(t, []string{ + "update t1 set id=1, val='ccc' where id=1", + "/update _vt.vreplication set pos=", + "commit", + "begin", + "insert into t1 set id=2, val='789012'", + "insert into t1 set id=3, val='345678'", + "/update _vt.vreplication set pos=", + "commit", + "begin", + "insert into t1 set id=4, val='901234'", + "/update _vt.vreplication set pos=", + "commit", + }) + }() + } +} + +func TestRestartOnVStreamEnd(t *testing.T) { + defer deleteTablet(addTablet(100, "0", topodatapb.TabletType_REPLICA, true, true)) + + savedDelay := *retryDelay + defer func() { *retryDelay = savedDelay }() + *retryDelay = 1 * time.Millisecond + + execStatements(t, []string{ + "create table t1(id int, val varbinary(128), primary key(id))", + fmt.Sprintf("create table %s.t1(id int, val varbinary(128), primary key(id))", vrepldb), + }) + defer execStatements(t, []string{ + "drop table t1", + fmt.Sprintf("drop table %s.t1", vrepldb), + }) + env.SchemaEngine.Reload(context.Background()) + + filter := &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{{ + Match: "/.*", + }}, + } + cancel, _ := startVReplication(t, filter, binlogdatapb.OnDDLAction_IGNORE, "") + defer cancel() + + execStatements(t, []string{ + "insert into t1 values(1, 'aaa')", + }) + expectDBClientQueries(t, []string{ + "begin", + "insert into t1 set id=1, val='aaa'", + "/update _vt.vreplication set pos=", + "commit", + }) + + streamerEngine.Close() + expectDBClientQueries(t, []string{ + "/update.*'Error'.*vstream ended", + }) + if err := streamerEngine.Open(env.KeyspaceName, env.ShardName); err != nil { + t.Fatal(err) + } + + execStatements(t, []string{ + "insert into t1 values(2, 'aaa')", + }) + expectDBClientQueries(t, []string{ + "/update.*'Running'", + "begin", + "insert into t1 set id=2, val='aaa'", + "/update _vt.vreplication set pos=", + "commit", + }) +} + +func TestTimestamp(t *testing.T) { + defer deleteTablet(addTablet(100, "0", topodatapb.TabletType_REPLICA, true, true)) + + execStatements(t, []string{ + "create table t1(id int, ts timestamp, dt datetime)", + fmt.Sprintf("create table %s.t1(id int, ts timestamp, dt datetime)", vrepldb), + }) + defer execStatements(t, []string{ + "drop table t1", + fmt.Sprintf("drop table %s.t1", vrepldb), + }) + env.SchemaEngine.Reload(context.Background()) + + filter := &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{{ + Match: "/.*", + }}, + } + cancel, _ := startVReplication(t, filter, binlogdatapb.OnDDLAction_IGNORE, "") + defer cancel() + + qr, err := env.Mysqld.FetchSuperQuery(context.Background(), "select now()") + if err != nil { + t.Fatal(err) + } + want := qr.Rows[0][0].ToString() + t.Logf("want: %s", want) + + execStatements(t, []string{ + fmt.Sprintf("insert into t1 values(1, '%s', '%s')", want, want), + }) + expectDBClientQueries(t, []string{ + "begin", + // The insert value for ts will be in UTC. + // We'll check the row instead. + "/insert into t1 set id=", + "/update _vt.vreplication set pos=", + "commit", + }) + + qr, err = env.Mysqld.FetchSuperQuery(context.Background(), "select ts, dt from t1 where id=1") + if err != nil { + t.Fatal(err) + } + // The value for dt should come back in the local timezone. + if got := qr.Rows[0][0].ToString(); got != want { + t.Errorf("ts: %s, want %s", got, want) + } + // The value for dt should be as is. + if got := qr.Rows[0][1].ToString(); got != want { + t.Errorf("ts: %s, want %s", got, want) + } +} + func execStatements(t *testing.T, queries []string) { t.Helper() if err := env.Mysqld.ExecuteSuperQueryList(context.Background(), queries); err != nil { @@ -485,7 +915,7 @@ func execStatements(t *testing.T, queries []string) { } } -func startVReplication(t *testing.T, pe *Engine, filter *binlogdatapb.Filter, onddl binlogdatapb.OnDDLAction, pos string) (cancelFunc func(), id int) { +func startVReplication(t *testing.T, filter *binlogdatapb.Filter, onddl binlogdatapb.OnDDLAction, pos string) (cancelFunc func(), id int) { t.Helper() bls := &binlogdatapb.BinlogSource{ @@ -498,7 +928,7 @@ func startVReplication(t *testing.T, pe *Engine, filter *binlogdatapb.Filter, on pos = masterPosition(t) } query := binlogplayer.CreateVReplication("test", bls, pos, 9223372036854775807, 9223372036854775807, 0) - qr, err := pe.Exec(query) + qr, err := playerEngine.Exec(query) if err != nil { t.Fatal(err) } @@ -511,7 +941,7 @@ func startVReplication(t *testing.T, pe *Engine, filter *binlogdatapb.Filter, on return func() { t.Helper() query := fmt.Sprintf("delete from _vt.vreplication where id = %d", qr.InsertID) - if _, err := pe.Exec(query); err != nil { + if _, err := playerEngine.Exec(query); err != nil { t.Fatal(err) } expectDBClientQueries(t, []string{ From f19985e69151f266ac63b0d7132e2fbf8085d71f Mon Sep 17 00:00:00 2001 From: Andres Taylor Date: Tue, 22 Jan 2019 11:11:17 +0100 Subject: [PATCH 080/115] Make MultiSplitDiff work with consistent snapshot Signed-off-by: Andres Taylor --- go/vt/worker/defaults.go | 15 +- go/vt/worker/diff_utils.go | 143 +++++++- go/vt/worker/legacy_split_clone_cmd.go | 4 +- go/vt/worker/multi_split_diff.go | 396 ++++++++++++++++------- go/vt/worker/multi_split_diff_cmd.go | 49 ++- go/vt/worker/multi_split_diff_test.go | 2 +- go/vt/worker/split_clone_cmd.go | 4 +- go/vt/worker/split_diff_cmd.go | 4 +- go/vt/worker/vertical_split_clone_cmd.go | 4 +- go/vt/worker/vertical_split_diff_cmd.go | 4 +- 10 files changed, 467 insertions(+), 158 deletions(-) diff --git a/go/vt/worker/defaults.go b/go/vt/worker/defaults.go index 7bf60295f71..adf2ccf3546 100644 --- a/go/vt/worker/defaults.go +++ b/go/vt/worker/defaults.go @@ -46,11 +46,12 @@ const ( // StreamExecute response. As of 06/2015, the default for it was 32 kB. // Note that higher values for this flag --destination_pack_count will // increase memory consumption in vtworker, vttablet and mysql. - defaultDestinationPackCount = 10 - defaultDestinationWriterCount = 20 - defaultMinHealthyRdonlyTablets = 2 - defaultDestTabletType = "RDONLY" - defaultParallelDiffsCount = 8 - defaultMaxTPS = throttler.MaxRateModuleDisabled - defaultMaxReplicationLag = throttler.ReplicationLagModuleDisabled + defaultDestinationPackCount = 10 + defaultDestinationWriterCount = 20 + defaultMinHealthyTablets = 2 + defaultDestTabletType = "RDONLY" + defaultParallelDiffsCount = 8 + defaultMaxTPS = throttler.MaxRateModuleDisabled + defaultMaxReplicationLag = throttler.ReplicationLagModuleDisabled + defaultUseConsistentSnapshot = false ) diff --git a/go/vt/worker/diff_utils.go b/go/vt/worker/diff_utils.go index 551e12281fa..4ff6ebc92ad 100644 --- a/go/vt/worker/diff_utils.go +++ b/go/vt/worker/diff_utils.go @@ -27,6 +27,8 @@ import ( "time" "vitess.io/vitess/go/vt/vterrors" + "vitess.io/vitess/go/vt/vttablet/tmclient" + "vitess.io/vitess/go/vt/wrangler" "golang.org/x/net/context" @@ -36,6 +38,7 @@ import ( "vitess.io/vitess/go/vt/grpcclient" "vitess.io/vitess/go/vt/key" "vitess.io/vitess/go/vt/logutil" + "vitess.io/vitess/go/vt/proto/query" "vitess.io/vitess/go/vt/topo" "vitess.io/vitess/go/vt/topo/topoproto" "vitess.io/vitess/go/vt/vtgate/vindexes" @@ -157,8 +160,8 @@ func (qrr *QueryResultReader) Fields() []*querypb.Field { } // Close closes the connection to the tablet. -func (qrr *QueryResultReader) Close(ctx context.Context) error { - return qrr.conn.Close(ctx) +func (qrr *QueryResultReader) Close(ctx context.Context) { + qrr.conn.Close(ctx) } // v3KeyRangeFilter is a sqltypes.ResultStream implementation that filters @@ -266,6 +269,16 @@ func TransactionalTableScan(ctx context.Context, log logutil.Logger, ts *topo.Se return NewTransactionalQueryResultReaderForTablet(ctx, ts, tabletAlias, sql, txID) } +// CreateTargetFrom is a helper function +func CreateTargetFrom(tablet *topodatapb.Tablet) *query.Target { + return &query.Target{ + Cell: tablet.Alias.Cell, + Keyspace: tablet.Keyspace, + Shard: tablet.Shard, + TabletType: tablet.Type, + } +} + // TableScanByKeyRange returns a QueryResultReader that gets all the // rows from a table that match the supplied KeyRange, ordered by // Primary Key. The returned columns are ordered with the Primary Key @@ -637,3 +650,129 @@ func (rd *RowDiffer) Go(log logutil.Logger) (dr DiffReport, err error) { advanceRight = true } } + +// createTransactions returns an array of transactions that all share the same view of the data. +// It will check that no new transactions have been seen between the creation of the underlying transactions, +// to guarantee that all TransactionalTableScanner are pointing to the same point +func createTransactions(ctx context.Context, numberOfScanners int, wr *wrangler.Wrangler, cleaner *wrangler.Cleaner, queryService queryservice.QueryService, target *query.Target, tabletInfo *topodatapb.Tablet) ([]int64, error) { + scanners := make([]int64, numberOfScanners) + for i := 0; i < numberOfScanners; i++ { + + tx, err := queryService.Begin(ctx, target, &query.ExecuteOptions{ + // Make sure our tx is not killed by tx sniper + Workload: query.ExecuteOptions_DBA, + TransactionIsolation: query.ExecuteOptions_CONSISTENT_SNAPSHOT_READ_ONLY, + }) + if err != nil { + return nil, fmt.Errorf("could not open transaction on %v\n%v", topoproto.TabletAliasString(tabletInfo.Alias), err) + } + + // Remember to rollback the transactions + cleaner.Record("CloseTransaction", topoproto.TabletAliasString(tabletInfo.Alias), func(ctx context.Context, wr *wrangler.Wrangler) error { + queryService, err := tabletconn.GetDialer()(tabletInfo, true) + if err != nil { + return err + } + return queryService.Rollback(ctx, target, tx) + }) + + scanners[i] = tx + } + + return scanners, nil +} + +// TableScanner is a simple abstraction that allows a TableScanner user to remain impervious +// by the transactionality of the connection +type TableScanner interface { + ScanTable(ctx context.Context, td *tabletmanagerdatapb.TableDefinition) (*QueryResultReader, error) +} + +// TransactionalTableScanner works inside of a transaction set up with CONSISTENT SNAPSHOT +type TransactionalTableScanner struct { + wr *wrangler.Wrangler + cleaner *wrangler.Cleaner + tabletAlias *topodatapb.TabletAlias + queryService queryservice.QueryService + tx int64 +} + +// ScanTable performs a full table scan, ordered by the primary keys, if any +func (tt TransactionalTableScanner) ScanTable(ctx context.Context, td *tabletmanagerdatapb.TableDefinition) (*QueryResultReader, error) { + return TransactionalTableScan(ctx, tt.wr.Logger(), tt.wr.TopoServer(), tt.tabletAlias, tt.tx, td) +} + +// NonTransactionalTableScanner just passes through the queries, and relies on paused replication traffic taking care of the consistent snapshot part +type NonTransactionalTableScanner struct { + wr *wrangler.Wrangler + cleaner *wrangler.Cleaner + tabletAlias *topodatapb.TabletAlias + queryService queryservice.QueryService +} + +// ScanTable performs a full table scan, ordered by the primary keys, if any +func (ntts NonTransactionalTableScanner) ScanTable(ctx context.Context, td *tabletmanagerdatapb.TableDefinition) (*QueryResultReader, error) { + return TableScan(ctx, ntts.wr.Logger(), ntts.wr.TopoServer(), ntts.tabletAlias, td) +} + +// CreateConsistentTableScanners will momentarily stop updates on the tablet, and then create connections that are all +// consistent snapshots of the same point in the transaction history +func CreateConsistentTableScanners(ctx context.Context, tablet *topo.TabletInfo, wr *wrangler.Wrangler, cleaner *wrangler.Cleaner, numberOfScanners int) ([]TableScanner, string, error) { + txs, gtid, err := CreateConsistentTransactions(ctx, tablet, wr, cleaner, numberOfScanners) + if err != nil { + return nil, "", err + } + + queryService, err := tabletconn.GetDialer()(tablet.Tablet, true) + defer queryService.Close(ctx) + + scanners := make([]TableScanner, numberOfScanners) + for i, tx := range txs { + scanners[i] = TransactionalTableScanner{ + wr: wr, + cleaner: cleaner, + tabletAlias: tablet.Alias, + queryService: queryService, + tx: tx, + } + } + + return scanners, gtid, nil +} + +// CreateConsistentTransactions creates a number of consistent snapshot transactions, +// all starting from the same spot in the tx log +func CreateConsistentTransactions(ctx context.Context, tablet *topo.TabletInfo, wr *wrangler.Wrangler, cleaner *wrangler.Cleaner, numberOfScanners int) ([]int64, string, error) { + tm := tmclient.NewTabletManagerClient() + defer tm.Close() + + // Lock all tables with a read lock to pause replication + err := tm.LockTables(ctx, tablet.Tablet) + if err != nil { + return nil, "", fmt.Errorf("could not lock tables on %v\n%v", topoproto.TabletAliasString(tablet.Tablet.Alias), err) + } + defer func() { + tm := tmclient.NewTabletManagerClient() + defer tm.Close() + tm.UnlockTables(ctx, tablet.Tablet) + wr.Logger().Infof("tables unlocked on %v", topoproto.TabletAliasString(tablet.Tablet.Alias)) + }() + + wr.Logger().Infof("tables locked on %v", topoproto.TabletAliasString(tablet.Tablet.Alias)) + target := CreateTargetFrom(tablet.Tablet) + + // Create transactions + queryService, err := tabletconn.GetDialer()(tablet.Tablet, true) + defer queryService.Close(ctx) + connections, err := createTransactions(ctx, numberOfScanners, wr, cleaner, queryService, target, tablet.Tablet) + if err != nil { + return nil, "", fmt.Errorf("failed to create transactions on %v: %v", topoproto.TabletAliasString(tablet.Tablet.Alias), err) + } + wr.Logger().Infof("transactions created on %v", topoproto.TabletAliasString(tablet.Tablet.Alias)) + executedGtid, err := tm.MasterPosition(ctx, tablet.Tablet) + if err != nil { + return nil, "", fmt.Errorf("could not read executed GTID set on %v\n%v", topoproto.TabletAliasString(tablet.Tablet.Alias), err) + } + + return connections, executedGtid, nil +} diff --git a/go/vt/worker/legacy_split_clone_cmd.go b/go/vt/worker/legacy_split_clone_cmd.go index ff48c291d4b..ab73cca3903 100644 --- a/go/vt/worker/legacy_split_clone_cmd.go +++ b/go/vt/worker/legacy_split_clone_cmd.go @@ -92,7 +92,7 @@ func commandLegacySplitClone(wi *Instance, wr *wrangler.Wrangler, subFlags *flag sourceReaderCount := subFlags.Int("source_reader_count", defaultSourceReaderCount, "number of concurrent streaming queries to use on the source") destinationPackCount := subFlags.Int("destination_pack_count", defaultDestinationPackCount, "number of packets to pack in one destination insert") destinationWriterCount := subFlags.Int("destination_writer_count", defaultDestinationWriterCount, "number of concurrent RPCs to execute on the destination") - minHealthyRdonlyTablets := subFlags.Int("min_healthy_rdonly_tablets", defaultMinHealthyRdonlyTablets, "minimum number of healthy RDONLY tablets before taking out one") + minHealthyRdonlyTablets := subFlags.Int("min_healthy_rdonly_tablets", defaultMinHealthyTablets, "minimum number of healthy RDONLY tablets before taking out one") maxTPS := subFlags.Int64("max_tps", defaultMaxTPS, "if non-zero, limit copy to maximum number of (write) transactions/second on the destination (unlimited by default)") if err := subFlags.Parse(args); err != nil { return nil, err @@ -146,7 +146,7 @@ func interactiveLegacySplitClone(ctx context.Context, wi *Instance, wr *wrangler result["DefaultSourceReaderCount"] = fmt.Sprintf("%v", defaultSourceReaderCount) result["DefaultDestinationPackCount"] = fmt.Sprintf("%v", defaultDestinationPackCount) result["DefaultDestinationWriterCount"] = fmt.Sprintf("%v", defaultDestinationWriterCount) - result["DefaultMinHealthyRdonlyTablets"] = fmt.Sprintf("%v", defaultMinHealthyRdonlyTablets) + result["DefaultMinHealthyRdonlyTablets"] = fmt.Sprintf("%v", defaultMinHealthyTablets) result["DefaultMaxTPS"] = fmt.Sprintf("%v", defaultMaxTPS) return nil, legacySplitCloneTemplate2, result, nil } diff --git a/go/vt/worker/multi_split_diff.go b/go/vt/worker/multi_split_diff.go index 71ee4c22c28..56ec444d4f9 100644 --- a/go/vt/worker/multi_split_diff.go +++ b/go/vt/worker/multi_split_diff.go @@ -24,18 +24,32 @@ import ( "time" "golang.org/x/net/context" - "vitess.io/vitess/go/sqltypes" - "vitess.io/vitess/go/vt/binlog/binlogplayer" + "vitess.io/vitess/go/vt/proto/vtrpc" + "vitess.io/vitess/go/vt/vttablet/queryservice" + "vitess.io/vitess/go/vt/vttablet/tabletconn" + "vitess.io/vitess/go/vt/concurrency" "vitess.io/vitess/go/vt/mysqlctl/tmutils" + "vitess.io/vitess/go/vt/topo" + "vitess.io/vitess/go/vt/wrangler" + + "vitess.io/vitess/go/sqltypes" + "vitess.io/vitess/go/vt/binlog/binlogplayer" 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/vterrors" "vitess.io/vitess/go/vt/vtgate/vindexes" - "vitess.io/vitess/go/vt/wrangler" ) +// One of these per paralell runner +type Scanners struct { + // this is how we get data from the source shard + sourceScanner TableScanner + + // this is how we get data from the destination shards - we'll have one scanner per shard we are reading from + destinationScanner []TableScanner +} + // MultiSplitDiffWorker executes a diff between a destination shard and its // source shards in a shard split case. type MultiSplitDiffWorker struct { @@ -46,10 +60,12 @@ type MultiSplitDiffWorker struct { keyspace string shard string excludeTables []string - minHealthyRdonlyTablets int + minHealthyTablets int parallelDiffsCount int waitForFixedTimeRatherThanGtidSet bool cleaner *wrangler.Cleaner + useConsistentSnapshot bool + tabletType topodatapb.TabletType // populated during WorkerStateInit, read-only after that keyspaceInfo *topo.KeyspaceInfo @@ -60,21 +76,24 @@ type MultiSplitDiffWorker struct { // populated during WorkerStateFindTargets, read-only after that sourceAlias *topodatapb.TabletAlias destinationAliases []*topodatapb.TabletAlias // matches order of destinationShards + scanners []Scanners } // NewMultiSplitDiffWorker returns a new MultiSplitDiffWorker object. -func NewMultiSplitDiffWorker(wr *wrangler.Wrangler, cell, keyspace, shard string, excludeTables []string, minHealthyRdonlyTablets, parallelDiffsCount int, waitForFixedTimeRatherThanGtidSet bool) Worker { +func NewMultiSplitDiffWorker(wr *wrangler.Wrangler, cell, keyspace, shard string, excludeTables []string, minHealthyTablets, parallelDiffsCount int, waitForFixedTimeRatherThanGtidSet bool, useConsistentSnapshot bool, tabletType topodatapb.TabletType) Worker { return &MultiSplitDiffWorker{ - waitForFixedTimeRatherThanGtidSet: waitForFixedTimeRatherThanGtidSet, StatusWorker: NewStatusWorker(), wr: wr, cell: cell, keyspace: keyspace, shard: shard, excludeTables: excludeTables, - minHealthyRdonlyTablets: minHealthyRdonlyTablets, + minHealthyTablets: minHealthyTablets, parallelDiffsCount: parallelDiffsCount, cleaner: &wrangler.Cleaner{}, + useConsistentSnapshot: useConsistentSnapshot, + waitForFixedTimeRatherThanGtidSet: waitForFixedTimeRatherThanGtidSet, + tabletType: tabletType, } } @@ -139,7 +158,7 @@ func (msdw *MultiSplitDiffWorker) Run(ctx context.Context) error { func (msdw *MultiSplitDiffWorker) run(ctx context.Context) error { // first state: read what we need to do if err := msdw.init(ctx); err != nil { - return fmt.Errorf("init() failed: %v", err) + return vterrors.Wrap(err, "init() failed") } if err := checkDone(ctx); err != nil { return err @@ -147,15 +166,15 @@ func (msdw *MultiSplitDiffWorker) run(ctx context.Context) error { // second state: find targets if err := msdw.findTargets(ctx); err != nil { - return fmt.Errorf("findTargets() failed: %v", err) + return vterrors.Wrap(err, "findTargets() failed") } if err := checkDone(ctx); err != nil { return err } // third phase: synchronize replication - if err := msdw.synchronizeReplication(ctx); err != nil { - return fmt.Errorf("synchronizeReplication() failed: %v", err) + if err := msdw.synchronizeSrcAndDestTxState(ctx); err != nil { + return vterrors.Wrap(err, "synchronizeSrcAndDestTxState() failed") } if err := checkDone(ctx); err != nil { return err @@ -163,7 +182,7 @@ func (msdw *MultiSplitDiffWorker) run(ctx context.Context) error { // fourth phase: diff if err := msdw.diff(ctx); err != nil { - return fmt.Errorf("diff() failed: %v", err) + return vterrors.Wrap(err, "diff() failed") } return checkDone(ctx) @@ -174,27 +193,33 @@ func (msdw *MultiSplitDiffWorker) run(ctx context.Context) error { func (msdw *MultiSplitDiffWorker) init(ctx context.Context) error { msdw.SetState(WorkerStateInit) + if msdw.useConsistentSnapshot { + msdw.wr.Logger().Infof("splitting using consistent snapshot") + } else { + msdw.wr.Logger().Infof("splitting using STOP SLAVE") + } + var err error shortCtx, cancel := context.WithTimeout(ctx, *remoteActionsTimeout) msdw.keyspaceInfo, err = msdw.wr.TopoServer().GetKeyspace(shortCtx, msdw.keyspace) cancel() if err != nil { - return fmt.Errorf("cannot read keyspace %v: %v", msdw.keyspace, err) + return vterrors.Wrapf(err, "cannot read keyspace %v", msdw.keyspace) } shortCtx, cancel = context.WithTimeout(ctx, *remoteActionsTimeout) msdw.shardInfo, err = msdw.wr.TopoServer().GetShard(shortCtx, msdw.keyspace, msdw.shard) cancel() if err != nil { - return fmt.Errorf("cannot read shard %v/%v: %v", msdw.keyspace, msdw.shard, err) + return vterrors.Wrapf(err, "cannot read shard %v/%v", msdw.keyspace, msdw.shard) } if !msdw.shardInfo.HasMaster() { - return fmt.Errorf("shard %v/%v has no master", msdw.keyspace, msdw.shard) + return vterrors.Errorf(vtrpc.Code_UNAVAILABLE, "shard %v/%v has no master", msdw.keyspace, msdw.shard) } destinationShards, err := msdw.findDestinationShards(ctx) if err != nil { - return fmt.Errorf("findDestinationShards() failed for %v/%v/%v: %v", msdw.cell, msdw.keyspace, msdw.shard, err) + return vterrors.Wrapf(err, "findDestinationShards() failed for %v/%v/%v", msdw.cell, msdw.keyspace, msdw.shard) } msdw.destinationShards = destinationShards @@ -221,7 +246,7 @@ func (msdw *MultiSplitDiffWorker) findDestinationShards(ctx context.Context) ([] } if len(resultArray) == 0 { - return nil, fmt.Errorf("there are no destination shards") + return nil, vterrors.Errorf(vtrpc.Code_UNAVAILABLE, "there are no destination shards") } return resultArray, nil } @@ -248,7 +273,7 @@ func (msdw *MultiSplitDiffWorker) findShardsInKeyspace(ctx context.Context, keys msdw.sourceUID = uid first = false } else if msdw.sourceUID != uid { - return nil, fmt.Errorf("found a source ID that was different, aborting. %v vs %v", msdw.sourceUID, uid) + return nil, vterrors.Errorf(vtrpc.Code_FAILED_PRECONDITION, "found a source ID that was different, aborting. %v vs %v", msdw.sourceUID, uid) } resultArray = append(resultArray, shardInfo) @@ -282,47 +307,34 @@ func (msdw *MultiSplitDiffWorker) getShardInfo(ctx context.Context, keyspace str // - mark them all as 'worker' pointing back to us func (msdw *MultiSplitDiffWorker) findTargets(ctx context.Context) error { msdw.SetState(WorkerStateFindTargets) - var err error - // find an appropriate tablet in the source shard - msdw.sourceAlias, err = FindWorkerTablet( - ctx, - msdw.wr, - msdw.cleaner, - nil, /* tsc */ - msdw.cell, - msdw.keyspace, - msdw.shard, - 1, /* minHealthyTablets */ - topodatapb.TabletType_RDONLY) + var finderFunc func(keyspace string, shard string) (*topodatapb.TabletAlias, error) + if msdw.tabletType == topodatapb.TabletType_RDONLY { + finderFunc = func(keyspace string, shard string) (*topodatapb.TabletAlias, error) { + return FindWorkerTablet(ctx, msdw.wr, msdw.cleaner, nil /*tsc*/, msdw.cell, keyspace, shard, 1, topodatapb.TabletType_RDONLY) + } + } else { + finderFunc = func(keyspace string, shard string) (*topodatapb.TabletAlias, error) { + return FindHealthyTablet(ctx, msdw.wr, nil /*tsc*/, msdw.cell, keyspace, shard, 1, msdw.tabletType) + } + } + + msdw.sourceAlias, err = finderFunc(msdw.keyspace, msdw.shard) if err != nil { - return fmt.Errorf("FindWorkerTablet() failed for %v/%v/%v: %v", msdw.cell, msdw.keyspace, msdw.shard, err) + return vterrors.Wrapf(err, "finding source failed for %v/%v/%v", msdw.cell, msdw.keyspace, msdw.shard) } - // find an appropriate tablet in each destination shard msdw.destinationAliases = make([]*topodatapb.TabletAlias, len(msdw.destinationShards)) for i, destinationShard := range msdw.destinationShards { keyspace := destinationShard.Keyspace() shard := destinationShard.ShardName() - destinationAlias, err := FindWorkerTablet( - ctx, - msdw.wr, - msdw.cleaner, - nil, /* tsc */ - msdw.cell, - keyspace, - shard, - msdw.minHealthyRdonlyTablets, - topodatapb.TabletType_RDONLY) + destinationAlias, err := finderFunc(keyspace, shard) if err != nil { - return fmt.Errorf("FindWorkerTablet() failed for %v/%v/%v: %v", msdw.cell, keyspace, shard, err) + return vterrors.Wrapf(err, "finding destination failed for %v/%v/%v", msdw.cell, keyspace, shard) } msdw.destinationAliases[i] = destinationAlias } - if err != nil { - return fmt.Errorf("FindWorkerTablet() failed for %v/%v/%v: %v", msdw.cell, msdw.keyspace, msdw.shard, err) - } return nil } @@ -330,44 +342,44 @@ func (msdw *MultiSplitDiffWorker) findTargets(ctx context.Context) error { // ask the master of the destination shard to pause filtered replication, // and return the source binlog positions // (add a cleanup task to restart filtered replication on master) -func (msdw *MultiSplitDiffWorker) stopReplicationOnAllDestinationMasters(ctx context.Context, masterInfos []*topo.TabletInfo) ([]string, error) { +func (msdw *MultiSplitDiffWorker) stopVreplicationOnAll(ctx context.Context, tabletInfo []*topo.TabletInfo) ([]string, error) { destVreplicationPos := make([]string, len(msdw.destinationShards)) for i, shardInfo := range msdw.destinationShards { - masterInfo := masterInfos[i] + tablet := tabletInfo[i].Tablet - msdw.wr.Logger().Infof("Stopping master binlog replication on %v", shardInfo.MasterAlias) + msdw.wr.Logger().Infof("stopping master binlog replication on %v", shardInfo.MasterAlias) shortCtx, cancel := context.WithTimeout(ctx, *remoteActionsTimeout) - _, err := msdw.wr.TabletManagerClient().VReplicationExec(shortCtx, masterInfo.Tablet, binlogplayer.StopVReplication(msdw.sourceUID, "for split diff")) + _, err := msdw.wr.TabletManagerClient().VReplicationExec(shortCtx, tablet, binlogplayer.StopVReplication(msdw.sourceUID, "for split diff")) cancel() if err != nil { - return nil, fmt.Errorf("VReplicationExec(stop) for %v failed: %v", shardInfo.MasterAlias, err) + return nil, vterrors.Wrapf(err, "VReplicationExec(stop) for %v failed", shardInfo.MasterAlias) } - wrangler.RecordVReplicationAction(msdw.cleaner, masterInfo.Tablet, binlogplayer.StartVReplication(msdw.sourceUID)) + wrangler.RecordVReplicationAction(msdw.cleaner, tablet, binlogplayer.StartVReplication(msdw.sourceUID)) shortCtx, cancel = context.WithTimeout(ctx, *remoteActionsTimeout) - p3qr, err := msdw.wr.TabletManagerClient().VReplicationExec(shortCtx, masterInfo.Tablet, binlogplayer.ReadVReplicationPos(msdw.sourceUID)) + p3qr, err := msdw.wr.TabletManagerClient().VReplicationExec(shortCtx, tablet, binlogplayer.ReadVReplicationPos(msdw.sourceUID)) cancel() if err != nil { - return nil, fmt.Errorf("VReplicationExec(stop) for %v failed: %v", msdw.shardInfo.MasterAlias, err) + return nil, vterrors.Wrapf(err, "VReplicationExec(stop) for %v failed", msdw.shardInfo.MasterAlias) } qr := sqltypes.Proto3ToResult(p3qr) if len(qr.Rows) != 1 || len(qr.Rows[0]) != 1 { - return nil, fmt.Errorf("unexpected result while reading position: %v", qr) + return nil, vterrors.Errorf(vtrpc.Code_FAILED_PRECONDITION, "unexpected result while reading position: %v", qr) } destVreplicationPos[i] = qr.Rows[0][0].ToString() if err != nil { - return nil, fmt.Errorf("StopBlp for %v failed: %v", msdw.shardInfo.MasterAlias, err) + return nil, vterrors.Wrapf(err, "StopBlp for %v failed", msdw.shardInfo.MasterAlias) } } return destVreplicationPos, nil } -func (msdw *MultiSplitDiffWorker) getTabletInfoForShard(ctx context.Context, shardInfo *topo.ShardInfo) (*topo.TabletInfo, error) { +func (msdw *MultiSplitDiffWorker) getMasterTabletInfoForShard(ctx context.Context, shardInfo *topo.ShardInfo) (*topo.TabletInfo, error) { shortCtx, cancel := context.WithTimeout(ctx, *remoteActionsTimeout) masterInfo, err := msdw.wr.TopoServer().GetTablet(shortCtx, shardInfo.MasterAlias) cancel() if err != nil { - return nil, fmt.Errorf("synchronizeReplication: cannot get Tablet record for master %v: %v", msdw.shardInfo.MasterAlias, err) + return nil, vterrors.Wrapf(err, "synchronizeSrcAndDestTxState: cannot get Tablet record for master %v", msdw.shardInfo.MasterAlias) } return masterInfo, nil } @@ -376,7 +388,7 @@ func (msdw *MultiSplitDiffWorker) getTabletInfoForShard(ctx context.Context, sha // destination masters. Return the reached position // (add a cleanup task to restart binlog replication on the source tablet, and // change the existing ChangeSlaveType cleanup action to 'spare' type) -func (msdw *MultiSplitDiffWorker) stopReplicationOnSourceRdOnlyTabletAt(ctx context.Context, destVreplicationPos []string) (string, error) { +func (msdw *MultiSplitDiffWorker) stopReplicationOnSourceTabletAt(ctx context.Context, destVreplicationPos []string) (string, error) { shortCtx, cancel := context.WithTimeout(ctx, *remoteActionsTimeout) sourceTablet, err := msdw.wr.TopoServer().GetTablet(shortCtx, msdw.sourceAlias) cancel() @@ -392,12 +404,8 @@ func (msdw *MultiSplitDiffWorker) stopReplicationOnSourceRdOnlyTabletAt(ctx cont // if we make StopSlaveMinimum take multiple blp positions then this will be a lot more efficient because you just // check for each position using WAIT_UNTIL_SQL_THREAD_AFTER_GTIDS and then stop replication. - msdw.wr.Logger().Infof("Stopping slave %v at a minimum of %v", msdw.sourceAlias, vreplicationPos) - // read the tablet - sourceTablet, err := msdw.wr.TopoServer().GetTablet(shortCtx, msdw.sourceAlias) - if err != nil { - return "", err - } + msdw.wr.Logger().Infof("stopping slave %v at a minimum of %v", msdw.sourceAlias, vreplicationPos) + shortCtx, cancel = context.WithTimeout(ctx, *remoteActionsTimeout) msdw.wr.TabletManagerClient().StartSlave(shortCtx, sourceTablet.Tablet) cancel() @@ -409,7 +417,7 @@ func (msdw *MultiSplitDiffWorker) stopReplicationOnSourceRdOnlyTabletAt(ctx cont mysqlPos, err = msdw.wr.TabletManagerClient().StopSlaveMinimum(shortCtx, sourceTablet.Tablet, vreplicationPos, *remoteActionsTimeout) cancel() if err != nil { - return "", fmt.Errorf("cannot stop slave %v at right binlog position %v: %v", msdw.sourceAlias, vreplicationPos, err) + return "", vterrors.Wrapf(err, "cannot stop slave %v at right binlog position %v", msdw.sourceAlias, vreplicationPos) } } // change the cleaner actions from ChangeSlaveType(rdonly) @@ -420,27 +428,28 @@ func (msdw *MultiSplitDiffWorker) stopReplicationOnSourceRdOnlyTabletAt(ctx cont } // ask the master of the destination shard to resume filtered replication -// up to the new list of positions, and return its binlog position. -func (msdw *MultiSplitDiffWorker) resumeReplicationOnDestinationMasterUntil(ctx context.Context, shardInfo *topo.ShardInfo, mysqlPos string, masterInfo *topo.TabletInfo) (string, error) { - msdw.wr.Logger().Infof("Restarting master %v until it catches up to %v", shardInfo.MasterAlias, mysqlPos) +// up to the specified source position, and return the destination position. +func (msdw *MultiSplitDiffWorker) stopVreplicationAt(ctx context.Context, shardInfo *topo.ShardInfo, sourcePosition string, masterInfo *topo.TabletInfo) (string, error) { + msdw.wr.Logger().Infof("Restarting master %v until it catches up to %v", shardInfo.MasterAlias, sourcePosition) shortCtx, cancel := context.WithTimeout(ctx, *remoteActionsTimeout) - _, err := msdw.wr.TabletManagerClient().VReplicationExec(shortCtx, masterInfo.Tablet, binlogplayer.StartVReplicationUntil(msdw.sourceUID, mysqlPos)) + _, err := msdw.wr.TabletManagerClient().VReplicationExec(shortCtx, masterInfo.Tablet, binlogplayer.StartVReplicationUntil(msdw.sourceUID, sourcePosition)) cancel() if err != nil { - return "", fmt.Errorf("VReplication(start until) for %v until %v failed: %v", shardInfo.MasterAlias, mysqlPos, err) + return "", vterrors.Wrapf(err, "VReplication(start until) for %v until %v failed", shardInfo.MasterAlias, sourcePosition) } + shortCtx, cancel = context.WithTimeout(ctx, *remoteActionsTimeout) - if err := msdw.wr.TabletManagerClient().VReplicationWaitForPos(shortCtx, masterInfo.Tablet, int(msdw.sourceUID), mysqlPos); err != nil { - cancel() - return "", fmt.Errorf("VReplicationWaitForPos for %v until %v failed: %v", shardInfo.MasterAlias, mysqlPos, err) - } + err = msdw.wr.TabletManagerClient().VReplicationWaitForPos(shortCtx, masterInfo.Tablet, int(msdw.sourceUID), sourcePosition) cancel() + if err != nil { + return "", vterrors.Wrapf(err, "VReplicationWaitForPos for %v until %v failed", shardInfo.MasterAlias, sourcePosition) + } shortCtx, cancel = context.WithTimeout(ctx, *remoteActionsTimeout) masterPos, err := msdw.wr.TabletManagerClient().MasterPosition(shortCtx, masterInfo.Tablet) cancel() if err != nil { - return "", fmt.Errorf("MasterPosition for %v failed: %v", msdw.shardInfo.MasterAlias, err) + return "", vterrors.Wrapf(err, "MasterPosition for %v failed", msdw.shardInfo.MasterAlias) } return masterPos, nil } @@ -449,11 +458,11 @@ func (msdw *MultiSplitDiffWorker) resumeReplicationOnDestinationMasterUntil(ctx // binlog position, and stop its replication. // (add a cleanup task to restart binlog replication on it, and change // the existing ChangeSlaveType cleanup action to 'spare' type) -func (msdw *MultiSplitDiffWorker) stopReplicationOnDestinationRdOnlys(ctx context.Context, destinationAlias *topodatapb.TabletAlias, masterPos string) error { +func (msdw *MultiSplitDiffWorker) stopReplicationAt(ctx context.Context, destinationAlias *topodatapb.TabletAlias, masterPos string) error { if msdw.waitForFixedTimeRatherThanGtidSet { - msdw.wr.Logger().Infof("Workaround for broken GTID set in destination RDONLY. Just waiting for 1 minute for %v and assuming replication has caught up. (should be at %v)", destinationAlias, masterPos) + msdw.wr.Logger().Infof("workaround for broken GTID set in destination RDONLY. Just waiting for 1 minute for %v and assuming replication has caught up. (should be at %v)", destinationAlias, masterPos) } else { - msdw.wr.Logger().Infof("Waiting for destination tablet %v to catch up to %v", destinationAlias, masterPos) + msdw.wr.Logger().Infof("waiting for destination tablet %v to catch up to %v", destinationAlias, masterPos) } shortCtx, cancel := context.WithTimeout(ctx, *remoteActionsTimeout) destinationTablet, err := msdw.wr.TopoServer().GetTablet(shortCtx, destinationAlias) @@ -474,7 +483,7 @@ func (msdw *MultiSplitDiffWorker) stopReplicationOnDestinationRdOnlys(ctx contex } cancel() if err != nil { - return fmt.Errorf("StopSlaveMinimum for %v at %v failed: %v", destinationAlias, masterPos, err) + return vterrors.Wrapf(err, "StopSlaveMinimum for %v at %v failed", destinationAlias, masterPos) } wrangler.RecordStartSlaveAction(msdw.cleaner, destinationTablet.Tablet) return nil @@ -482,87 +491,208 @@ func (msdw *MultiSplitDiffWorker) stopReplicationOnDestinationRdOnlys(ctx contex // restart filtered replication on the destination master. // (remove the cleanup task that does the same) -func (msdw *MultiSplitDiffWorker) restartReplicationOn(ctx context.Context, shardInfo *topo.ShardInfo, masterInfo *topo.TabletInfo) error { - msdw.wr.Logger().Infof("Restarting filtered replication on master %v", shardInfo.MasterAlias) +func (msdw *MultiSplitDiffWorker) startVreplication(ctx context.Context, shardInfo *topo.ShardInfo, masterInfo *topo.TabletInfo) error { + msdw.wr.Logger().Infof("restarting filtered replication on master %v", shardInfo.MasterAlias) shortCtx, cancel := context.WithTimeout(ctx, *remoteActionsTimeout) _, err := msdw.wr.TabletManagerClient().VReplicationExec(shortCtx, masterInfo.Tablet, binlogplayer.StartVReplication(msdw.sourceUID)) if err != nil { - return fmt.Errorf("VReplicationExec(start) failed for %v: %v", shardInfo.MasterAlias, err) + return vterrors.Wrapf(err, "VReplicationExec(start) failed for %v", shardInfo.MasterAlias) } cancel() return nil } -// synchronizeReplication phase: -// At this point, the source and the destination tablet are stopped at the same -// point. +func (msdw *MultiSplitDiffWorker) createNonTransactionalTableScanners(ctx context.Context, queryService queryservice.QueryService, source *topo.TabletInfo) ([]TableScanner, error) { + // If we are not using consistent snapshot, we'll use the NonTransactionalTableScanner, + // which does not have any instance state and so can be used by all connections + scanners := make([]TableScanner, msdw.parallelDiffsCount) + scanner := NonTransactionalTableScanner{ + queryService: queryService, + cleaner: msdw.cleaner, + wr: msdw.wr, + tabletAlias: source.Alias, + } + + for i := 0; i < msdw.parallelDiffsCount; i++ { + scanners[i] = scanner + } + + return scanners, nil +} + +func (msdw *MultiSplitDiffWorker) useTransactionScanners(ctx context.Context, source *topo.TabletInfo) (string, []TableScanner, error) { + connections, pos, err := CreateConsistentTableScanners(ctx, source, msdw.wr, msdw.cleaner, msdw.parallelDiffsCount) + if err != nil { + return "", nil, vterrors.Wrapf(err, "failed to create %d transactional connections", msdw.parallelDiffsCount) + } + return pos, connections, nil +} +func (msdw *MultiSplitDiffWorker) useNonTransactionalScanners(ctx context.Context, source *topo.TabletInfo, destVreplicationPos []string) (string, []TableScanner, error) { + pos, err := msdw.stopReplicationOnSourceTabletAt(ctx, destVreplicationPos) + if err != nil { + return "", nil, err + } + + queryService, err := tabletconn.GetDialer()(source.Tablet, true) + if err != nil { + return "", nil, vterrors.Wrapf(err, "failed to instantiate query service for %v", source.Tablet) + } + sourceScanners, err := msdw.createNonTransactionalTableScanners(ctx, queryService, source) + if err != nil { + return "", nil, err + } -func (msdw *MultiSplitDiffWorker) synchronizeReplication(ctx context.Context) error { + return pos, sourceScanners, nil +} + +// synchronizeSrcAndDestTxState phase: +// After this point, the source and the destination tablet are stopped at the same point. +func (msdw *MultiSplitDiffWorker) synchronizeSrcAndDestTxState(ctx context.Context) error { msdw.SetState(WorkerStateSyncReplication) var err error + // 1. Find all the tablets we will need to work with masterInfos := make([]*topo.TabletInfo, len(msdw.destinationAliases)) for i, shardInfo := range msdw.destinationShards { - masterInfos[i], err = msdw.getTabletInfoForShard(ctx, shardInfo) + masterInfos[i], err = msdw.getMasterTabletInfoForShard(ctx, shardInfo) if err != nil { return err } } - destVreplicationPos, err := msdw.stopReplicationOnAllDestinationMasters(ctx, masterInfos) + shortCtx, cancel := context.WithTimeout(ctx, *remoteActionsTimeout) + source, err := msdw.wr.TopoServer().GetTablet(shortCtx, msdw.sourceAlias) + cancel() + + var sourcePosition string + + // 2. Stop replication on destination + destVreplicationPos, err := msdw.stopVreplicationOnAll(ctx, masterInfos) if err != nil { return err } - mysqlPos, err := msdw.stopReplicationOnSourceRdOnlyTabletAt(ctx, destVreplicationPos) + // 3. Pause updates on the source and create consistent snapshot connections + var scanners []TableScanner + if msdw.useConsistentSnapshot { + sourcePosition, scanners, err = msdw.useTransactionScanners(ctx, source) + } else { + sourcePosition, scanners, err = msdw.useNonTransactionalScanners(ctx, source, destVreplicationPos) + } if err != nil { return err } + msdw.scanners = make([]Scanners, msdw.parallelDiffsCount) + for i := 0; i < msdw.parallelDiffsCount; i++ { + // We'll create one of these Scanners struct per thread we want to run in parallel + scanner := scanners[i] + i2 := Scanners{ + sourceScanner: scanner, + destinationScanner: make([]TableScanner, len(msdw.destinationShards)), + } + msdw.scanners[i] = i2 + } + + // 4. Make sure all replicas have caught up with the master for i, shardInfo := range msdw.destinationShards { masterInfo := masterInfos[i] destinationAlias := msdw.destinationAliases[i] - masterPos, err := msdw.resumeReplicationOnDestinationMasterUntil(ctx, shardInfo, mysqlPos, masterInfo) + destinationPosition, err := msdw.stopVreplicationAt(ctx, shardInfo, sourcePosition, masterInfo) if err != nil { return err } - err = msdw.stopReplicationOnDestinationRdOnlys(ctx, destinationAlias, masterPos) + shortCtx, cancel := context.WithTimeout(ctx, *remoteActionsTimeout) + destTabletInfo, err := msdw.wr.TopoServer().GetTablet(shortCtx, destinationAlias) + cancel() if err != nil { - return err + return vterrors.Wrapf(err, "waitForDestinationTabletToReach: cannot get Tablet record for master %v", msdw.shardInfo.MasterAlias) + } + + queryService, err := tabletconn.GetDialer()(source.Tablet, true) + var destScanners []TableScanner + + if msdw.useConsistentSnapshot { + // loop to wait for the destinationAlias tablet in shardInfo to have reached destinationPosition + err = msdw.waitForDestinationTabletToReach(ctx, destTabletInfo.Tablet, destinationPosition) + if err != nil { + return err + } + + destScanners, _, err = CreateConsistentTableScanners(ctx, destTabletInfo, msdw.wr, msdw.cleaner, msdw.parallelDiffsCount) + if err != nil { + return err + } + } else { + err = msdw.stopReplicationAt(ctx, destinationAlias, destinationPosition) + if err != nil { + return vterrors.Wrapf(err, "failed to stop replication on %v at position %v", destinationAlias, destinationPosition) + } + destScanners, err = msdw.createNonTransactionalTableScanners(ctx, queryService, destTabletInfo) + if err != nil { + return vterrors.Wrapf(err, "failed to stop create table scanners for %v using %v", destTabletInfo, queryService) + } } - err = msdw.restartReplicationOn(ctx, shardInfo, masterInfo) + // 5. Spread out destination scanners between the goroutines + for j := 0; j < msdw.parallelDiffsCount; j++ { + msdw.scanners[j].destinationScanner[i] = destScanners[j] + } + + err = msdw.startVreplication(ctx, shardInfo, masterInfo) if err != nil { - return err + return vterrors.Wrapf(err, "failed to restart vreplication for shard %v on tablet %v", shardInfo, masterInfo) } - } + } return nil } -func (msdw *MultiSplitDiffWorker) diffSingleTable(ctx context.Context, wg *sync.WaitGroup, tableDefinition *tabletmanagerdatapb.TableDefinition, keyspaceSchema *vindexes.KeyspaceSchema) error { +func (msdw *MultiSplitDiffWorker) waitForDestinationTabletToReach(ctx context.Context, tablet *topodatapb.Tablet, mysqlPos string) error { + for i := 0; i < 20; i++ { + shortCtx, cancel := context.WithTimeout(ctx, *remoteActionsTimeout) + pos, err := msdw.wr.TabletManagerClient().MasterPosition(shortCtx, tablet) + cancel() + if err != nil { + return vterrors.Wrapf(err, "get MasterPosition for %v failed", tablet) + } + + if pos == mysqlPos { + return nil + } + time.Sleep(time.Second) + } + return vterrors.Errorf(vtrpc.Code_UNAVAILABLE, "failed to reach transaction position after multiple attempts. it is safe to try again") +} + +func (msdw *MultiSplitDiffWorker) diffSingleTable(ctx context.Context, wg *sync.WaitGroup, tableDefinition *tabletmanagerdatapb.TableDefinition, keyspaceSchema *vindexes.KeyspaceSchema, sourceScanner TableScanner, destinationScanners []TableScanner) error { msdw.wr.Logger().Infof("Starting the diff on table %v", tableDefinition.Name) - sourceQueryResultReader, err := TableScan(ctx, msdw.wr.Logger(), msdw.wr.TopoServer(), msdw.sourceAlias, tableDefinition) + if len(destinationScanners) != len(msdw.destinationAliases) { + return vterrors.Errorf(vtrpc.Code_FAILED_PRECONDITION, "did not receive the expected amount of destination connections") + } + + sourceQueryResultReader, err := sourceScanner.ScanTable(ctx, tableDefinition) if err != nil { - return fmt.Errorf("TableScan(source) failed: %v", err) + return err } defer sourceQueryResultReader.Close(ctx) destinationQueryResultReaders := make([]ResultReader, len(msdw.destinationAliases)) - for i, destinationAlias := range msdw.destinationAliases { - destinationQueryResultReader, err := TableScan(ctx, msdw.wr.Logger(), msdw.wr.TopoServer(), destinationAlias, tableDefinition) + for i := range msdw.destinationAliases { + scanner := destinationScanners[i] + destinationQueryResultReader, err := scanner.ScanTable(ctx, tableDefinition) if err != nil { - return fmt.Errorf("TableScan(destination) failed: %v", err) + return vterrors.Wrapf(err, "TableScan(destination) on %v failed", tableDefinition.String()) } // For the first result scanner, let's check the PKs are of types that we can work with if i == 0 { err = CheckValidTypesForResultMerger(destinationQueryResultReader.fields, len(tableDefinition.PrimaryKeyColumns)) if err != nil { - return fmt.Errorf("invalid types for multi split diff. use the regular split diff instead %v", err.Error()) + return vterrors.Wrapf(err, "invalid types for multi split diff. use the regular split diff instead") } } @@ -574,35 +704,41 @@ func (msdw *MultiSplitDiffWorker) diffSingleTable(ctx context.Context, wg *sync. } mergedResultReader, err := NewResultMerger(destinationQueryResultReaders, len(tableDefinition.PrimaryKeyColumns)) if err != nil { - return fmt.Errorf("NewResultMerger failed: %v", err) + return err } // Create the row differ. differ, err := NewRowDiffer(sourceQueryResultReader, mergedResultReader, tableDefinition) if err != nil { - return fmt.Errorf("NewRowDiffer() failed: %v", err) + return err } // And run the diff. report, err := differ.Go(msdw.wr.Logger()) if err != nil { - return fmt.Errorf("Differ.Go failed: %v", err.Error()) + return err } if report.HasDifferences() { - return fmt.Errorf("table %v has differences: %v", tableDefinition.Name, report.String()) + return vterrors.Errorf(vtrpc.Code_FAILED_PRECONDITION, "table %v has differences: %v", tableDefinition.Name, report.String()) } - msdw.wr.Logger().Infof("Table %v checks out (%v rows processed, %v qps)", tableDefinition.Name, report.processedRows, report.processingQPS) + msdw.wr.Logger().Infof("table %v checks out (%v rows processed, %v qps)", tableDefinition.Name, report.processedRows, report.processingQPS) return nil } -func (msdw *MultiSplitDiffWorker) tableDiffingConsumer(ctx context.Context, wg *sync.WaitGroup, tableChan chan *tabletmanagerdatapb.TableDefinition, rec *concurrency.AllErrorRecorder, keyspaceSchema *vindexes.KeyspaceSchema) { +func (msdw *MultiSplitDiffWorker) tableDiffingConsumer(ctx context.Context, wg *sync.WaitGroup, tableChan chan *tabletmanagerdatapb.TableDefinition, rec *concurrency.AllErrorRecorder, keyspaceSchema *vindexes.KeyspaceSchema, sourceScanner TableScanner, destinationScanners []TableScanner) { + if destinationScanners == nil || sourceScanner == nil { + err := vterrors.Errorf(vtrpc.Code_INTERNAL, "should not be nil %v %v", destinationScanners, sourceScanner) + msdw.markAsWillFail(rec, err) + msdw.wr.Logger().Errorf("%v", err) + return + } defer wg.Done() for tableDefinition := range tableChan { - err := msdw.diffSingleTable(ctx, wg, tableDefinition, keyspaceSchema) + err := msdw.diffSingleTable(ctx, wg, tableDefinition, keyspaceSchema, sourceScanner, destinationScanners) if err != nil { msdw.markAsWillFail(rec, err) msdw.wr.Logger().Errorf("%v", err) @@ -611,7 +747,7 @@ func (msdw *MultiSplitDiffWorker) tableDiffingConsumer(ctx context.Context, wg * } func (msdw *MultiSplitDiffWorker) gatherSchemaInfo(ctx context.Context) ([]*tabletmanagerdatapb.SchemaDefinition, *tabletmanagerdatapb.SchemaDefinition, error) { - msdw.wr.Logger().Infof("Gathering schema information...") + msdw.wr.Logger().Infof("gathering schema information...") wg := sync.WaitGroup{} rec := &concurrency.AllErrorRecorder{} @@ -630,7 +766,7 @@ func (msdw *MultiSplitDiffWorker) gatherSchemaInfo(ctx context.Context) ([]*tabl msdw.markAsWillFail(rec, err) } destinationSchemaDefinitions[i] = destinationSchemaDefinition - msdw.wr.Logger().Infof("Got schema from destination %v", destinationAlias) + msdw.wr.Logger().Infof("got schema from destination %v", destinationAlias) wg.Done() }(i, destinationAlias) } @@ -644,7 +780,7 @@ func (msdw *MultiSplitDiffWorker) gatherSchemaInfo(ctx context.Context) ([]*tabl if err != nil { msdw.markAsWillFail(rec, err) } - msdw.wr.Logger().Infof("Got schema from source %v", msdw.sourceAlias) + msdw.wr.Logger().Infof("got schema from source %v", msdw.sourceAlias) wg.Done() }() @@ -656,8 +792,8 @@ func (msdw *MultiSplitDiffWorker) gatherSchemaInfo(ctx context.Context) ([]*tabl return destinationSchemaDefinitions, sourceSchemaDefinition, nil } -func (msdw *MultiSplitDiffWorker) diffSchemaInformation(ctx context.Context, destinationSchemaDefinitions []*tabletmanagerdatapb.SchemaDefinition, sourceSchemaDefinition *tabletmanagerdatapb.SchemaDefinition) { - msdw.wr.Logger().Infof("Diffing the schema...") +func (msdw *MultiSplitDiffWorker) diffSchemaInformation(ctx context.Context, destinationSchemaDefinitions []*tabletmanagerdatapb.SchemaDefinition, sourceSchemaDefinition *tabletmanagerdatapb.SchemaDefinition) error { + msdw.wr.Logger().Infof("diffing the schema...") rec := &concurrency.AllErrorRecorder{} sourceShardName := fmt.Sprintf("%v/%v", msdw.shardInfo.Keyspace(), msdw.shardInfo.ShardName()) for i, destinationSchemaDefinition := range destinationSchemaDefinitions { @@ -666,10 +802,12 @@ func (msdw *MultiSplitDiffWorker) diffSchemaInformation(ctx context.Context, des tmutils.DiffSchema(destinationShardName, destinationSchemaDefinition, sourceShardName, sourceSchemaDefinition, rec) } if rec.HasErrors() { - msdw.wr.Logger().Warningf("Different schemas: %v", rec.Error().Error()) - } else { - msdw.wr.Logger().Infof("Schema match, good.") + msdw.wr.Logger().Warningf("different schemas: %v", rec.Error().Error()) + return rec.Error() } + + msdw.wr.Logger().Infof("schema match, good.") + return nil } func (msdw *MultiSplitDiffWorker) loadVSchema(ctx context.Context) (*vindexes.KeyspaceSchema, error) { @@ -677,15 +815,15 @@ func (msdw *MultiSplitDiffWorker) loadVSchema(ctx context.Context) (*vindexes.Ke kschema, err := msdw.wr.TopoServer().GetVSchema(shortCtx, msdw.keyspace) cancel() if err != nil { - return nil, fmt.Errorf("cannot load VSchema for keyspace %v: %v", msdw.keyspace, err) + return nil, vterrors.Wrapf(err, "cannot load VSchema for keyspace %v", msdw.keyspace) } if kschema == nil { - return nil, fmt.Errorf("no VSchema for keyspace %v", msdw.keyspace) + return nil, vterrors.Errorf(vtrpc.Code_UNAVAILABLE, "no VSchema for keyspace %v", msdw.keyspace) } keyspaceSchema, err := vindexes.BuildKeyspaceSchema(kschema, msdw.keyspace) if err != nil { - return nil, fmt.Errorf("cannot build vschema for keyspace %v: %v", msdw.keyspace, err) + return nil, vterrors.Wrapf(err, "cannot build vschema for keyspace %v", msdw.keyspace) } return keyspaceSchema, nil } @@ -702,7 +840,10 @@ func (msdw *MultiSplitDiffWorker) diff(ctx context.Context) error { if err != nil { return err } - msdw.diffSchemaInformation(ctx, destinationSchemaDefinitions, sourceSchemaDefinition) + err = msdw.diffSchemaInformation(ctx, destinationSchemaDefinitions, sourceSchemaDefinition) + if err != nil { + return err + } // read the vschema if needed var keyspaceSchema *vindexes.KeyspaceSchema @@ -713,7 +854,7 @@ func (msdw *MultiSplitDiffWorker) diff(ctx context.Context) error { } } - msdw.wr.Logger().Infof("Running the diffs...") + msdw.wr.Logger().Infof("running the diffs...") tableDefinitions := sourceSchemaDefinition.TableDefinitions rec := &concurrency.AllErrorRecorder{} @@ -729,8 +870,13 @@ func (msdw *MultiSplitDiffWorker) diff(ctx context.Context) error { consumers := sync.WaitGroup{} // start as many goroutines we want parallel diffs running for i := 0; i < msdw.parallelDiffsCount; i++ { + scanners := msdw.scanners[i] + if scanners.sourceScanner == nil || scanners.destinationScanner == nil { + return vterrors.Errorf(vtrpc.Code_INTERNAL, "should not be nil [%v] OR [%v]", scanners.sourceScanner, scanners.destinationScanner) + } + consumers.Add(1) - go msdw.tableDiffingConsumer(ctx, &consumers, tableChan, rec, keyspaceSchema) + go msdw.tableDiffingConsumer(ctx, &consumers, tableChan, rec, keyspaceSchema, scanners.sourceScanner, scanners.destinationScanner) } // wait for all consumers to wrap up their work diff --git a/go/vt/worker/multi_split_diff_cmd.go b/go/vt/worker/multi_split_diff_cmd.go index 353e47790e7..8d54df60c35 100644 --- a/go/vt/worker/multi_split_diff_cmd.go +++ b/go/vt/worker/multi_split_diff_cmd.go @@ -25,6 +25,8 @@ import ( "strings" "sync" + "vitess.io/vitess/go/vt/proto/topodata" + "golang.org/x/net/context" "vitess.io/vitess/go/vt/concurrency" "vitess.io/vitess/go/vt/topo/topoproto" @@ -60,14 +62,22 @@ const multiSplitDiffHTML2 = `

+ + +

- -
+ +


+ + ?
@@ -79,10 +89,12 @@ var multiSplitDiffTemplate = mustParseTemplate("multiSplitDiff", multiSplitDiffH var multiSplitDiffTemplate2 = mustParseTemplate("multiSplitDiff2", multiSplitDiffHTML2) func commandMultiSplitDiff(wi *Instance, wr *wrangler.Wrangler, subFlags *flag.FlagSet, args []string) (Worker, error) { + tabletTypeStr := subFlags.String("tablet_type", "RDONLY", "type of tablet used") excludeTables := subFlags.String("exclude_tables", "", "comma separated list of tables to exclude") - minHealthyRdonlyTablets := subFlags.Int("min_healthy_rdonly_tablets", defaultMinHealthyRdonlyTablets, "minimum number of healthy RDONLY tablets before taking out one") + minHealthyTablets := subFlags.Int("min_healthy_tablets", defaultMinHealthyTablets, "minimum number of healthy tablets before taking out one") parallelDiffsCount := subFlags.Int("parallel_diffs_count", defaultParallelDiffsCount, "number of tables to diff in parallel") waitForFixedTimeRatherThanGtidSet := subFlags.Bool("wait_for_fixed_time_rather_than_gtid_set", false, "wait for 1m when syncing up the destination RDONLY tablet rather than using the GTID set. Use this when the GTID set on the RDONLY is broken. Make sure the RDONLY is not behind in replication when using this flag.") + useConsistentSnapshot := subFlags.Bool("use_consistent_snapshot", defaultUseConsistentSnapshot, "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 nil, err } @@ -98,7 +110,13 @@ func commandMultiSplitDiff(wi *Instance, wr *wrangler.Wrangler, subFlags *flag.F if *excludeTables != "" { excludeTableArray = strings.Split(*excludeTables, ",") } - return NewMultiSplitDiffWorker(wr, wi.cell, keyspace, shard, excludeTableArray, *minHealthyRdonlyTablets, *parallelDiffsCount, *waitForFixedTimeRatherThanGtidSet), nil + + tabletType, ok := topodata.TabletType_value[*tabletTypeStr] + if !ok { + return nil, fmt.Errorf("failed to find this tablet type %v", tabletTypeStr) + } + + return NewMultiSplitDiffWorker(wr, wi.cell, keyspace, shard, excludeTableArray, *minHealthyTablets, *parallelDiffsCount, *waitForFixedTimeRatherThanGtidSet, *useConsistentSnapshot, topodata.TabletType(tabletType)), nil } // shardSources returns all the shards that are SourceShards of at least one other shard. @@ -168,7 +186,7 @@ func shardSources(ctx context.Context, wr *wrangler.Wrangler) ([]map[string]stri return result, nil } -func interactiveMultiSplitDiff(ctx context.Context, wi *Instance, wr *wrangler.Wrangler, w http.ResponseWriter, r *http.Request) (Worker, *template.Template, map[string]interface{}, error) { +func interactiveMultiSplitDiff(ctx context.Context, wi *Instance, wr *wrangler.Wrangler, _ http.ResponseWriter, r *http.Request) (Worker, *template.Template, map[string]interface{}, error) { if err := r.ParseForm(); err != nil { return nil, nil, nil, fmt.Errorf("cannot parse form: %s", err) } @@ -194,7 +212,7 @@ func interactiveMultiSplitDiff(ctx context.Context, wi *Instance, wr *wrangler.W result["Keyspace"] = keyspace result["Shard"] = shard result["DefaultSourceUID"] = "0" - result["DefaultMinHealthyRdonlyTablets"] = fmt.Sprintf("%v", defaultMinHealthyRdonlyTablets) + result["DefaultMinHealthyTablets"] = fmt.Sprintf("%v", defaultMinHealthyTablets) result["DefaultParallelDiffsCount"] = fmt.Sprintf("%v", defaultParallelDiffsCount) return nil, multiSplitDiffTemplate2, result, nil } @@ -205,21 +223,26 @@ func interactiveMultiSplitDiff(ctx context.Context, wi *Instance, wr *wrangler.W if excludeTables != "" { excludeTableArray = strings.Split(excludeTables, ",") } - minHealthyRdonlyTabletsStr := r.FormValue("minHealthyRdonlyTablets") + minHealthyTabletsStr := r.FormValue("minHealthyTablets") parallelDiffsCountStr := r.FormValue("parallelDiffsCount") - minHealthyRdonlyTablets, err := strconv.ParseInt(minHealthyRdonlyTabletsStr, 0, 64) + minHealthyTablets, err := strconv.ParseInt(minHealthyTabletsStr, 0, 64) parallelDiffsCount, err := strconv.ParseInt(parallelDiffsCountStr, 0, 64) if err != nil { - return nil, nil, nil, fmt.Errorf("cannot parse minHealthyRdonlyTablets: %s", err) + return nil, nil, nil, fmt.Errorf("cannot parse minHealthyTablets: %s", err) } waitForFixedTimeRatherThanGtidSetStr := r.FormValue("waitForFixedTimeRatherThanGtidSet") waitForFixedTimeRatherThanGtidSet := waitForFixedTimeRatherThanGtidSetStr == "true" - if err != nil { - return nil, nil, nil, fmt.Errorf("cannot parse minHealthyRdonlyTablets: %s", err) + useConsistentSnapshotStr := r.FormValue("useConsistentSnapshot") + useConsistentSnapshot := useConsistentSnapshotStr == "true" + + tabletTypeStr := r.FormValue("tabletType") + tabletType, ok := topodata.TabletType_value[tabletTypeStr] + if !ok { + return nil, nil, nil, fmt.Errorf("cannot parse tabletType: %s", tabletTypeStr) } // start the diff job - wrk := NewMultiSplitDiffWorker(wr, wi.cell, keyspace, shard, excludeTableArray, int(minHealthyRdonlyTablets), int(parallelDiffsCount), waitForFixedTimeRatherThanGtidSet) + wrk := NewMultiSplitDiffWorker(wr, wi.cell, keyspace, shard, excludeTableArray, int(minHealthyTablets), int(parallelDiffsCount), waitForFixedTimeRatherThanGtidSet, useConsistentSnapshot, topodata.TabletType(tabletType)) return wrk, nil, nil, nil } @@ -228,4 +251,4 @@ func init() { commandMultiSplitDiff, interactiveMultiSplitDiff, "[--exclude_tables=''] ", "Diffs a rdonly destination shard against its SourceShards"}) -} +} \ No newline at end of file diff --git a/go/vt/worker/multi_split_diff_test.go b/go/vt/worker/multi_split_diff_test.go index 8195fb5628c..90316e22a05 100644 --- a/go/vt/worker/multi_split_diff_test.go +++ b/go/vt/worker/multi_split_diff_test.go @@ -323,7 +323,7 @@ func testMultiSplitDiff(t *testing.T, v3 bool) { // necessary for synchronizing replication. wr := wrangler.New(logutil.NewConsoleLogger(), ts, newFakeTMCTopo(ts)) if err := runCommand(t, wi, wr, args); err != nil { - t.Fatal(err) + t.Fatalf("%+v", err) } } diff --git a/go/vt/worker/split_clone_cmd.go b/go/vt/worker/split_clone_cmd.go index 9285ae2f4cb..770af7797c5 100644 --- a/go/vt/worker/split_clone_cmd.go +++ b/go/vt/worker/split_clone_cmd.go @@ -108,7 +108,7 @@ func commandSplitClone(wi *Instance, wr *wrangler.Wrangler, subFlags *flag.FlagS writeQueryMaxRows := subFlags.Int("write_query_max_rows", defaultWriteQueryMaxRows, "maximum number of rows per write query") writeQueryMaxSize := subFlags.Int("write_query_max_size", defaultWriteQueryMaxSize, "maximum size (in bytes) per write query") destinationWriterCount := subFlags.Int("destination_writer_count", defaultDestinationWriterCount, "number of concurrent RPCs to execute on the destination") - minHealthyRdonlyTablets := subFlags.Int("min_healthy_rdonly_tablets", defaultMinHealthyRdonlyTablets, "minimum number of healthy RDONLY tablets in the source and destination shard at start") + minHealthyRdonlyTablets := subFlags.Int("min_healthy_rdonly_tablets", defaultMinHealthyTablets, "minimum number of healthy RDONLY tablets in the source and destination shard at start") maxTPS := subFlags.Int64("max_tps", defaultMaxTPS, "rate limit of maximum number of (write) transactions/second on the destination (unlimited by default)") maxReplicationLag := subFlags.Int64("max_replication_lag", defaultMaxReplicationLag, "if set, the adapative throttler will be enabled and automatically adjust the write rate to keep the lag below the set value in seconds (disabled by default)") if err := subFlags.Parse(args); err != nil { @@ -212,7 +212,7 @@ func interactiveSplitClone(ctx context.Context, wi *Instance, wr *wrangler.Wrang result["DefaultWriteQueryMaxRows"] = fmt.Sprintf("%v", defaultWriteQueryMaxRows) result["DefaultWriteQueryMaxSize"] = fmt.Sprintf("%v", defaultWriteQueryMaxSize) result["DefaultDestinationWriterCount"] = fmt.Sprintf("%v", defaultDestinationWriterCount) - result["DefaultMinHealthyRdonlyTablets"] = fmt.Sprintf("%v", defaultMinHealthyRdonlyTablets) + result["DefaultMinHealthyRdonlyTablets"] = fmt.Sprintf("%v", defaultMinHealthyTablets) result["DefaultMaxTPS"] = fmt.Sprintf("%v", defaultMaxTPS) result["DefaultMaxReplicationLag"] = fmt.Sprintf("%v", defaultMaxReplicationLag) return nil, splitCloneTemplate2, result, nil diff --git a/go/vt/worker/split_diff_cmd.go b/go/vt/worker/split_diff_cmd.go index 39178646f8f..460c8587c92 100644 --- a/go/vt/worker/split_diff_cmd.go +++ b/go/vt/worker/split_diff_cmd.go @@ -83,7 +83,7 @@ var splitDiffTemplate2 = mustParseTemplate("splitDiff2", splitDiffHTML2) func commandSplitDiff(wi *Instance, wr *wrangler.Wrangler, subFlags *flag.FlagSet, args []string) (Worker, error) { sourceUID := subFlags.Int("source_uid", 0, "uid of the source shard to run the diff against") excludeTables := subFlags.String("exclude_tables", "", "comma separated list of tables to exclude") - minHealthyRdonlyTablets := subFlags.Int("min_healthy_rdonly_tablets", defaultMinHealthyRdonlyTablets, "minimum number of healthy RDONLY tablets before taking out one") + minHealthyRdonlyTablets := subFlags.Int("min_healthy_rdonly_tablets", defaultMinHealthyTablets, "minimum number of healthy RDONLY tablets before taking out one") destTabletTypeStr := subFlags.String("dest_tablet_type", defaultDestTabletType, "destination tablet type (RDONLY or REPLICA) that will be used to compare the shards") parallelDiffsCount := subFlags.Int("parallel_diffs_count", defaultParallelDiffsCount, "number of tables to diff in parallel") if err := subFlags.Parse(args); err != nil { @@ -196,7 +196,7 @@ func interactiveSplitDiff(ctx context.Context, wi *Instance, wr *wrangler.Wrangl result["Keyspace"] = keyspace result["Shard"] = shard result["DefaultSourceUID"] = "0" - result["DefaultMinHealthyRdonlyTablets"] = fmt.Sprintf("%v", defaultMinHealthyRdonlyTablets) + result["DefaultMinHealthyRdonlyTablets"] = fmt.Sprintf("%v", defaultMinHealthyTablets) result["DefaultParallelDiffsCount"] = fmt.Sprintf("%v", defaultParallelDiffsCount) return nil, splitDiffTemplate2, result, nil } diff --git a/go/vt/worker/vertical_split_clone_cmd.go b/go/vt/worker/vertical_split_clone_cmd.go index c2d5a0b074c..3d812003eac 100644 --- a/go/vt/worker/vertical_split_clone_cmd.go +++ b/go/vt/worker/vertical_split_clone_cmd.go @@ -106,7 +106,7 @@ func commandVerticalSplitClone(wi *Instance, wr *wrangler.Wrangler, subFlags *fl writeQueryMaxRows := subFlags.Int("write_query_max_rows", defaultWriteQueryMaxRows, "maximum number of rows per write query") writeQueryMaxSize := subFlags.Int("write_query_max_size", defaultWriteQueryMaxSize, "maximum size (in bytes) per write query") destinationWriterCount := subFlags.Int("destination_writer_count", defaultDestinationWriterCount, "number of concurrent RPCs to execute on the destination") - minHealthyRdonlyTablets := subFlags.Int("min_healthy_rdonly_tablets", defaultMinHealthyRdonlyTablets, "minimum number of healthy RDONLY tablets before taking out one") + minHealthyRdonlyTablets := subFlags.Int("min_healthy_rdonly_tablets", defaultMinHealthyTablets, "minimum number of healthy RDONLY tablets before taking out one") maxTPS := subFlags.Int64("max_tps", defaultMaxTPS, "if non-zero, limit copy to maximum number of (write) transactions/second on the destination (unlimited by default)") maxReplicationLag := subFlags.Int64("max_replication_lag", defaultMaxReplicationLag, "if set, the adapative throttler will be enabled and automatically adjust the write rate to keep the lag below the set value in seconds (disabled by default)") if err := subFlags.Parse(args); err != nil { @@ -208,7 +208,7 @@ func interactiveVerticalSplitClone(ctx context.Context, wi *Instance, wr *wrangl result["DefaultWriteQueryMaxRows"] = fmt.Sprintf("%v", defaultWriteQueryMaxRows) result["DefaultWriteQueryMaxSize"] = fmt.Sprintf("%v", defaultWriteQueryMaxSize) result["DefaultDestinationWriterCount"] = fmt.Sprintf("%v", defaultDestinationWriterCount) - result["DefaultMinHealthyRdonlyTablets"] = fmt.Sprintf("%v", defaultMinHealthyRdonlyTablets) + result["DefaultMinHealthyRdonlyTablets"] = fmt.Sprintf("%v", defaultMinHealthyTablets) result["DefaultMaxTPS"] = fmt.Sprintf("%v", defaultMaxTPS) result["DefaultMaxReplicationLag"] = fmt.Sprintf("%v", defaultMaxReplicationLag) return nil, verticalSplitCloneTemplate2, result, nil diff --git a/go/vt/worker/vertical_split_diff_cmd.go b/go/vt/worker/vertical_split_diff_cmd.go index 7eebf106f5a..e4cfd4d34c4 100644 --- a/go/vt/worker/vertical_split_diff_cmd.go +++ b/go/vt/worker/vertical_split_diff_cmd.go @@ -75,7 +75,7 @@ var verticalSplitDiffTemplate = mustParseTemplate("verticalSplitDiff", verticalS var verticalSplitDiffTemplate2 = mustParseTemplate("verticalSplitDiff2", verticalSplitDiffHTML2) func commandVerticalSplitDiff(wi *Instance, wr *wrangler.Wrangler, subFlags *flag.FlagSet, args []string) (Worker, error) { - minHealthyRdonlyTablets := subFlags.Int("min_healthy_rdonly_tablets", defaultMinHealthyRdonlyTablets, "minimum number of healthy RDONLY tablets before taking out one") + minHealthyRdonlyTablets := subFlags.Int("min_healthy_rdonly_tablets", defaultMinHealthyTablets, "minimum number of healthy RDONLY tablets before taking out one") parallelDiffsCount := subFlags.Int("parallel_diffs_count", defaultParallelDiffsCount, "number of tables to diff in parallel") destTabletTypeStr := subFlags.String("dest_tablet_type", defaultDestTabletType, "destination tablet type (RDONLY or REPLICA) that will be used to compare the shards") if err := subFlags.Parse(args); err != nil { @@ -183,7 +183,7 @@ func interactiveVerticalSplitDiff(ctx context.Context, wi *Instance, wr *wrangle result := make(map[string]interface{}) result["Keyspace"] = keyspace result["Shard"] = shard - result["DefaultMinHealthyRdonlyTablets"] = fmt.Sprintf("%v", defaultMinHealthyRdonlyTablets) + result["DefaultMinHealthyRdonlyTablets"] = fmt.Sprintf("%v", defaultMinHealthyTablets) result["DefaultParallelDiffsCount"] = fmt.Sprintf("%v", defaultParallelDiffsCount) return nil, verticalSplitDiffTemplate2, result, nil } From f9c0f3122b8624c2fc064bff0dd80558a86e9972 Mon Sep 17 00:00:00 2001 From: Sugu Sougoumarane Date: Tue, 22 Jan 2019 02:14:12 -0800 Subject: [PATCH 081/115] vplayer: timezone fix and more tests Signed-off-by: Sugu Sougoumarane --- .../tabletmanager/vreplication/controller.go | 4 ++++ .../tabletmanager/vreplication/framework_test.go | 2 +- .../tabletmanager/vreplication/retryable_client.go | 10 ---------- .../vttablet/tabletmanager/vreplication/vplayer.go | 1 + .../tabletmanager/vreplication/vplayer_test.go | 13 ++++++++++--- 5 files changed, 16 insertions(+), 14 deletions(-) diff --git a/go/vt/vttablet/tabletmanager/vreplication/controller.go b/go/vt/vttablet/tabletmanager/vreplication/controller.go index 665d0f8a2a7..75d1c7c32de 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/controller.go +++ b/go/vt/vttablet/tabletmanager/vreplication/controller.go @@ -189,6 +189,10 @@ func (ct *controller) runBlp(ctx context.Context) (err error) { player := binlogplayer.NewBinlogPlayerKeyRange(dbClient, tablet, ct.source.KeyRange, ct.id, ct.blpStats) return player.ApplyBinlogEvents(ctx) case ct.source.Filter != nil: + // VPlayer requires the timezone to be UTC. + if _, err := dbClient.ExecuteFetch("set @@session.time_zone = '+00:00'", 10000); err != nil { + return err + } vplayer := newVPlayer(ct.id, &ct.source, tablet, ct.blpStats, dbClient, ct.mysqld) return vplayer.Play(ctx) } diff --git a/go/vt/vttablet/tabletmanager/vreplication/framework_test.go b/go/vt/vttablet/tabletmanager/vreplication/framework_test.go index ea1cd2dc63d..421a046ccfa 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/framework_test.go +++ b/go/vt/vttablet/tabletmanager/vreplication/framework_test.go @@ -327,7 +327,7 @@ func (dbc *realDBClient) ExecuteFetch(query string, maxrows int) (*sqltypes.Resu return nil, nil } qr, err := dbc.conn.ExecuteFetch(query, 10000, true) - if !strings.HasPrefix(query, "select") && !dbc.nolog { + if !strings.HasPrefix(query, "select") && !strings.HasPrefix(query, "set") && !dbc.nolog { globalDBQueries <- query } return qr, err diff --git a/go/vt/vttablet/tabletmanager/vreplication/retryable_client.go b/go/vt/vttablet/tabletmanager/vreplication/retryable_client.go index f08cd99cf37..e1edaf78966 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/retryable_client.go +++ b/go/vt/vttablet/tabletmanager/vreplication/retryable_client.go @@ -29,16 +29,6 @@ type retryableClient struct { queries []string } -func (rt *retryableClient) Connect() error { - if err := rt.Connect(); err != nil { - return err - } - if _, err := rt.DBClient.ExecuteFetch("set @@session.time_zone = '+00:00'", 10000); err != nil { - return err - } - return nil -} - func (rt *retryableClient) Begin() error { if err := rt.DBClient.Begin(); err != nil { return err diff --git a/go/vt/vttablet/tabletmanager/vreplication/vplayer.go b/go/vt/vttablet/tabletmanager/vreplication/vplayer.go index 66b2937d7a4..328fa34b4e6 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/vplayer.go +++ b/go/vt/vttablet/tabletmanager/vreplication/vplayer.go @@ -625,5 +625,6 @@ func encodeValue(sql *sqlparser.TrackedBuffer, value sqltypes.Value) { // Previously, this function used to convert timestamp to the session // time zone, but we now set the session timezone to UTC. So, the timestamp // value we receive as UTC can be sent as is. + // TODO(sougou): handle BIT data type here? value.EncodeSQL(sql) } diff --git a/go/vt/vttablet/tabletmanager/vreplication/vplayer_test.go b/go/vt/vttablet/tabletmanager/vreplication/vplayer_test.go index a1b06f4b609..bd98ed9ecc4 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/vplayer_test.go +++ b/go/vt/vttablet/tabletmanager/vreplication/vplayer_test.go @@ -642,7 +642,7 @@ func TestPlayerBatching(t *testing.T) { Match: "/.*", }}, } - cancel, _ := startVReplication(t, filter, binlogdatapb.OnDDLAction_IGNORE, "") + cancel, _ := startVReplication(t, filter, binlogdatapb.OnDDLAction_EXEC, "") defer cancel() execStatements(t, []string{ @@ -682,12 +682,15 @@ func TestPlayerBatching(t *testing.T) { execStatements(t, []string{ "insert into t1 values(2, 'aaa')", "insert into t1 values(3, 'aaa')", + "create table t2(id int, val varbinary(128), primary key(id))", + "drop table t2", }) // Release the lock. _, _ = vconn.ExecuteFetch("rollback", 1) // First transaction will complete. The other two - // transactions must be batched into one + // transactions must be batched into one. But the + // DDLs should be on their own. expectDBClientQueries(t, []string{ "update t1 set id=1, val='ccc' where id=1", "/update _vt.vreplication set pos=", @@ -697,6 +700,10 @@ func TestPlayerBatching(t *testing.T) { "insert into t1 set id=3, val='aaa'", "/update _vt.vreplication set pos=", "commit", + "create table t2(id int, val varbinary(128), primary key(id))", + "/update _vt.vreplication set pos=", + "/", // drop table is rewritten by mysql. Don't check. + "/update _vt.vreplication set pos=", }) } @@ -894,7 +901,7 @@ func TestTimestamp(t *testing.T) { "commit", }) - qr, err = env.Mysqld.FetchSuperQuery(context.Background(), "select ts, dt from t1 where id=1") + qr, err = env.Mysqld.FetchSuperQuery(context.Background(), fmt.Sprintf("select ts, dt from %s.t1 where id=1", vrepldb)) if err != nil { t.Fatal(err) } From 8a963318320524cf3cd6ec6d38066ca9f5c68b02 Mon Sep 17 00:00:00 2001 From: Sugu Sougoumarane Date: Tue, 22 Jan 2019 16:40:01 -0800 Subject: [PATCH 082/115] vplayer: tables with no pk and more tests Signed-off-by: Sugu Sougoumarane --- .../fakemysqldaemon/fakemysqldaemon.go | 5 + go/vt/mysqlctl/mysql_daemon.go | 1 + .../vreplication/framework_test.go | 23 ++++ .../vreplication/retryable_client.go | 13 ++- .../tabletmanager/vreplication/vplayer.go | 59 +++------- .../vreplication/vplayer_test.go | 103 ++++++++++++++++-- 6 files changed, 146 insertions(+), 58 deletions(-) diff --git a/go/vt/mysqlctl/fakemysqldaemon/fakemysqldaemon.go b/go/vt/mysqlctl/fakemysqldaemon/fakemysqldaemon.go index e2dda296fb0..5688624ba5e 100644 --- a/go/vt/mysqlctl/fakemysqldaemon/fakemysqldaemon.go +++ b/go/vt/mysqlctl/fakemysqldaemon/fakemysqldaemon.go @@ -383,6 +383,11 @@ func (fmd *FakeMysqlDaemon) GetSchema(dbName string, tables, excludeTables []str return tmutils.FilterTables(fmd.Schema, tables, excludeTables, includeViews) } +// GetColumns is part of the MysqlDaemon interface +func (fmd *FakeMysqlDaemon) GetColumns(dbName, table string) ([]string, error) { + return []string{}, nil +} + // GetPrimaryKeyColumns is part of the MysqlDaemon interface func (fmd *FakeMysqlDaemon) GetPrimaryKeyColumns(dbName, table string) ([]string, error) { return []string{}, nil diff --git a/go/vt/mysqlctl/mysql_daemon.go b/go/vt/mysqlctl/mysql_daemon.go index 49b30dbf65e..60e59ee3b71 100644 --- a/go/vt/mysqlctl/mysql_daemon.go +++ b/go/vt/mysqlctl/mysql_daemon.go @@ -69,6 +69,7 @@ type MysqlDaemon interface { // Schema related methods GetSchema(dbName string, tables, excludeTables []string, includeViews bool) (*tabletmanagerdatapb.SchemaDefinition, error) + GetColumns(dbName, table string) ([]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/vttablet/tabletmanager/vreplication/framework_test.go b/go/vt/vttablet/tabletmanager/vreplication/framework_test.go index 421a046ccfa..9d44d314cb2 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/framework_test.go +++ b/go/vt/vttablet/tabletmanager/vreplication/framework_test.go @@ -371,3 +371,26 @@ func expectDBClientQueries(t *testing.T, queries []string) { } } } + +func expectData(t *testing.T, table string, values [][]string) { + t.Helper() + + qr, err := env.Mysqld.FetchSuperQuery(context.Background(), fmt.Sprintf("select * from %s.%s", vrepldb, table)) + if err != nil { + t.Error(err) + return + } + for i, row := range values { + if i >= len(qr.Rows) { + t.Errorf("Result too short, row: %d, want: %v", i, row) + } + for j, val := range row { + if j >= len(qr.Rows[i]) { + t.Errorf("Too few columns, result: %v, row: %d, want: %v", qr.Rows[i], i, row) + } + if got := qr.Rows[i][j].ToString(); got != val { + t.Errorf("Mismatch at (%d, %d): %v, want %s", i, j, qr.Rows[i][j], val) + } + } + } +} diff --git a/go/vt/vttablet/tabletmanager/vreplication/retryable_client.go b/go/vt/vttablet/tabletmanager/vreplication/retryable_client.go index e1edaf78966..f5e8eaa4efc 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/retryable_client.go +++ b/go/vt/vttablet/tabletmanager/vreplication/retryable_client.go @@ -25,16 +25,19 @@ import ( // It allows us to retry a failed transactions on lock errors. type retryableClient struct { binlogplayer.DBClient - inTransaction bool + InTransaction bool queries []string } func (rt *retryableClient) Begin() error { + if rt.InTransaction { + return nil + } if err := rt.DBClient.Begin(); err != nil { return err } rt.queries = append(rt.queries, "begin") - rt.inTransaction = true + rt.InTransaction = true return nil } @@ -42,7 +45,7 @@ func (rt *retryableClient) Commit() error { if err := rt.DBClient.Commit(); err != nil { return err } - rt.inTransaction = false + rt.InTransaction = false rt.queries = nil return nil } @@ -51,13 +54,13 @@ func (rt *retryableClient) Rollback() error { if err := rt.DBClient.Rollback(); err != nil { return err } - rt.inTransaction = false + rt.InTransaction = false // Don't reset queries to allow for vplayer to retry. return nil } func (rt *retryableClient) ExecuteFetch(query string, maxrows int) (*sqltypes.Result, error) { - if !rt.inTransaction { + if !rt.InTransaction { rt.queries = []string{query} } else { rt.queries = append(rt.queries, query) diff --git a/go/vt/vttablet/tabletmanager/vreplication/vplayer.go b/go/vt/vttablet/tabletmanager/vreplication/vplayer.go index 328fa34b4e6..c9c90a1b2b9 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/vplayer.go +++ b/go/vt/vttablet/tabletmanager/vreplication/vplayer.go @@ -62,9 +62,6 @@ type vplayer struct { // timeLastSaved is set every time a GTID is saved. timeLastSaved time.Time stopPos mysql.Position - // inTransaction is true if we've started a transaction. - // It remains true until the next commit or rollback. - inTransaction bool // pplan is built based on the source Filter at the beginning. pplan *playerPlan @@ -207,7 +204,7 @@ func (vp *vplayer) applyEvents(ctx context.Context, relay *relayLog) error { if time.Now().Sub(vp.timeLastSaved) >= idleTimeout && vp.unsavedGTID != nil { // Although unlikely, we should not save if a transaction is still open. // This can happen if a large transaction is split as multiple events. - if !vp.inTransaction { + if !vp.dbClient.InTransaction { if err := vp.updatePos(vp.unsavedGTID.Timestamp); err != nil { return err } @@ -275,12 +272,12 @@ func (vp *vplayer) applyEvent(ctx context.Context, event *binlogdatapb.VEvent, m // No-op: begin is called as needed. case binlogdatapb.VEventType_COMMIT: if mustSave { - if err := vp.begin(); err != nil { + if err := vp.dbClient.Begin(); err != nil { return err } } - if !vp.inTransaction { + if !vp.dbClient.InTransaction { return nil } if err := vp.updatePos(event.Timestamp); err != nil { @@ -292,35 +289,35 @@ func (vp *vplayer) applyEvent(ctx context.Context, event *binlogdatapb.VEvent, m return err } } - if err := vp.commit(); err != nil { + if err := vp.dbClient.Commit(); err != nil { return err } if posReached { return io.EOF } case binlogdatapb.VEventType_FIELD: - if err := vp.begin(); err != nil { + if err := vp.dbClient.Begin(); err != nil { return err } if err := vp.updatePlan(event.FieldEvent); err != nil { return err } case binlogdatapb.VEventType_ROW: - if err := vp.begin(); err != nil { + if err := vp.dbClient.Begin(); err != nil { return err } if err := vp.applyRowEvent(ctx, event.RowEvent); err != nil { return err } case binlogdatapb.VEventType_DDL: - if vp.inTransaction { + if vp.dbClient.InTransaction { return fmt.Errorf("unexpected state: DDL encountered in the middle of a transaction: %v", event.Ddl) } switch vp.source.OnDdl { case binlogdatapb.OnDDLAction_IGNORE: // no-op case binlogdatapb.OnDDLAction_STOP: - if err := vp.begin(); err != nil { + if err := vp.dbClient.Begin(); err != nil { return err } if err := vp.updatePos(event.Timestamp); err != nil { @@ -329,7 +326,7 @@ func (vp *vplayer) applyEvent(ctx context.Context, event *binlogdatapb.VEvent, m if err := vp.setState(binlogplayer.BlpStopped, fmt.Sprintf("Stopped at DDL %s", event.Ddl)); err != nil { return err } - if err := vp.commit(); err != nil { + if err := vp.dbClient.Commit(); err != nil { return err } return io.EOF @@ -352,33 +349,6 @@ func (vp *vplayer) applyEvent(ctx context.Context, event *binlogdatapb.VEvent, m return nil } -func (vp *vplayer) begin() error { - if vp.inTransaction { - return nil - } - if err := vp.dbClient.Begin(); err != nil { - return err - } - vp.inTransaction = true - return nil -} - -func (vp *vplayer) commit() error { - if !vp.inTransaction { - return nil - } - if err := vp.dbClient.Commit(); err != nil { - return err - } - vp.inTransaction = false - return nil -} - -func (vp *vplayer) rollback() { - vp.inTransaction = false - _ = vp.dbClient.Rollback() -} - func (vp *vplayer) setState(state, message string) error { return binlogplayer.SetVReplicationState(vp.dbClient, vp.id, state, message) } @@ -414,6 +384,13 @@ func (vp *vplayer) updatePlan(fieldEvent *binlogdatapb.FieldEvent) error { if err != nil { return fmt.Errorf("error fetching pk columns for %s: %v", tplan.name, err) } + if len(pkcols) == 0 { + // If the table doesn't have a PK, then we treat all columns as PK. + pkcols, err = vp.mysqld.GetColumns(vp.dbClient.DBName(), tplan.name) + if err != nil { + return fmt.Errorf("error fetching pk columns for %s: %v", tplan.name, err) + } + } for _, pkcol := range pkcols { found := false for i, cExpr := range tplan.colExprs { @@ -577,7 +554,7 @@ func (vp *vplayer) writeWhereValues(sql *sqlparser.TrackedBuffer, tplan *tablePl for _, cExpr := range tplan.pkCols { sql.Myprintf("%s%v=", separator, cExpr.colname) if separator == "" { - separator = " AND " + separator = " and " } encodeValue(sql, before[cExpr.colnum]) } @@ -586,7 +563,7 @@ func (vp *vplayer) writeWhereValues(sql *sqlparser.TrackedBuffer, tplan *tablePl func (vp *vplayer) updatePos(ts int64) error { updatePos := binlogplayer.GenerateUpdatePos(vp.id, vp.pos, time.Now().Unix(), ts) if _, err := vp.dbClient.ExecuteFetch(updatePos, 0); err != nil { - vp.rollback() + vp.dbClient.Rollback() return fmt.Errorf("error %v updating position", err) } vp.unsavedGTID = nil diff --git a/go/vt/vttablet/tabletmanager/vreplication/vplayer_test.go b/go/vt/vttablet/tabletmanager/vreplication/vplayer_test.go index bd98ed9ecc4..d8be7ddf287 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/vplayer_test.go +++ b/go/vt/vttablet/tabletmanager/vreplication/vplayer_test.go @@ -44,6 +44,8 @@ func TestPlayerFilters(t *testing.T) { "create table yes(id int, val varbinary(128), primary key(id))", fmt.Sprintf("create table %s.yes(id int, val varbinary(128), primary key(id))", vrepldb), "create table no(id int, val varbinary(128), primary key(id))", + "create table nopk(id int, val varbinary(128))", + fmt.Sprintf("create table %s.nopk(id int, val varbinary(128))", vrepldb), }) defer execStatements(t, []string{ "drop table src1", @@ -55,6 +57,8 @@ func TestPlayerFilters(t *testing.T) { "drop table yes", fmt.Sprintf("drop table %s.yes", vrepldb), "drop table no", + "drop table nopk", + fmt.Sprintf("drop table %s.nopk", vrepldb), }) env.SchemaEngine.Reload(context.Background()) @@ -70,6 +74,8 @@ func TestPlayerFilters(t *testing.T) { Filter: "select id, val from src3 group by id, val", }, { Match: "/yes", + }, { + Match: "/nopk", }}, } cancel, _ := startVReplication(t, filter, binlogdatapb.OnDDLAction_IGNORE, "") @@ -78,6 +84,8 @@ func TestPlayerFilters(t *testing.T) { testcases := []struct { input string output []string + table string + data [][]string }{{ // insert with insertNormal input: "insert into src1 values(1, 'aaa')", @@ -87,6 +95,10 @@ func TestPlayerFilters(t *testing.T) { "/update _vt.vreplication set pos=", "commit", }, + table: "dst1", + data: [][]string{ + {"1", "aaa"}, + }, }, { // update with insertNormal input: "update src1 set val='bbb'", @@ -96,6 +108,10 @@ func TestPlayerFilters(t *testing.T) { "/update _vt.vreplication set pos=", "commit", }, + table: "dst1", + data: [][]string{ + {"1", "bbb"}, + }, }, { // delete with insertNormal input: "delete from src1 where id=1", @@ -105,6 +121,8 @@ func TestPlayerFilters(t *testing.T) { "/update _vt.vreplication set pos=", "commit", }, + table: "dst1", + data: [][]string{}, }, { // insert with insertOnDup input: "insert into src2 values(1, 2, 3)", @@ -114,6 +132,10 @@ func TestPlayerFilters(t *testing.T) { "/update _vt.vreplication set pos=", "commit", }, + table: "dst2", + data: [][]string{ + {"1", "2", "3"}, + }, }, { // update with insertOnDup input: "update src2 set val1=5, val2=1 where id=1", @@ -123,6 +145,10 @@ func TestPlayerFilters(t *testing.T) { "/update _vt.vreplication set pos=", "commit", }, + table: "dst2", + data: [][]string{ + {"1", "5", "1"}, + }, }, { // delete with insertOnDup input: "delete from src2 where id=1", @@ -132,6 +158,10 @@ func TestPlayerFilters(t *testing.T) { "/update _vt.vreplication set pos=", "commit", }, + table: "dst2", + data: [][]string{ + {"1", "", "0"}, + }, }, { // insert with insertIgnore input: "insert into src3 values(1, 'aaa')", @@ -141,6 +171,10 @@ func TestPlayerFilters(t *testing.T) { "/update _vt.vreplication set pos=", "commit", }, + table: "dst3", + data: [][]string{ + {"1", "aaa"}, + }, }, { // update with insertIgnore input: "update src3 set val='bbb'", @@ -150,6 +184,10 @@ func TestPlayerFilters(t *testing.T) { "/update _vt.vreplication set pos=", "commit", }, + table: "dst3", + data: [][]string{ + {"1", "aaa"}, + }, }, { // delete with insertIgnore input: "delete from src3 where id=1", @@ -158,6 +196,10 @@ func TestPlayerFilters(t *testing.T) { "/update _vt.vreplication set pos=", "commit", }, + table: "dst3", + data: [][]string{ + {"1", "aaa"}, + }, }, { // insert: regular expression filter input: "insert into yes values(1, 'aaa')", @@ -167,6 +209,10 @@ func TestPlayerFilters(t *testing.T) { "/update _vt.vreplication set pos=", "commit", }, + table: "yes", + data: [][]string{ + {"1", "aaa"}, + }, }, { // update: regular expression filter input: "update yes set val='bbb'", @@ -176,15 +222,59 @@ func TestPlayerFilters(t *testing.T) { "/update _vt.vreplication set pos=", "commit", }, + table: "yes", + data: [][]string{ + {"1", "bbb"}, + }, }, { // table should not match a rule input: "insert into no values(1, 'aaa')", output: []string{}, + }, { + // nopk: insert + input: "insert into nopk values(1, 'aaa')", + output: []string{ + "begin", + "insert into nopk set id=1, val='aaa'", + "/update _vt.vreplication set pos=", + "commit", + }, + table: "nopk", + data: [][]string{ + {"1", "aaa"}, + }, + }, { + // nopk: update + input: "update nopk set val='bbb' where id=1", + output: []string{ + "begin", + "update nopk set id=1, val='bbb' where id=1 and val='aaa'", + "/update _vt.vreplication set pos=", + "commit", + }, + table: "nopk", + data: [][]string{ + {"1", "bbb"}, + }, + }, { + // nopk: delete + input: "delete from nopk where id=1", + output: []string{ + "begin", + "delete from nopk where id=1 and val='bbb'", + "/update _vt.vreplication set pos=", + "commit", + }, + table: "nopk", + data: [][]string{}, }} for _, tcases := range testcases { execStatements(t, []string{tcases.input}) expectDBClientQueries(t, tcases.output) + if tcases.table != "" { + expectData(t, tcases.table, tcases.data) + } } } @@ -901,18 +991,7 @@ func TestTimestamp(t *testing.T) { "commit", }) - qr, err = env.Mysqld.FetchSuperQuery(context.Background(), fmt.Sprintf("select ts, dt from %s.t1 where id=1", vrepldb)) - if err != nil { - t.Fatal(err) - } - // The value for dt should come back in the local timezone. - if got := qr.Rows[0][0].ToString(); got != want { - t.Errorf("ts: %s, want %s", got, want) - } - // The value for dt should be as is. - if got := qr.Rows[0][1].ToString(); got != want { - t.Errorf("ts: %s, want %s", got, want) - } + expectData(t, "t1", [][]string{{"1", want, want}}) } func execStatements(t *testing.T, queries []string) { From 349a564beb6877a47f1e824add36bc91aa50d9ce Mon Sep 17 00:00:00 2001 From: David Weitzman Date: Wed, 23 Jan 2019 19:04:31 -0800 Subject: [PATCH 083/115] Reduce the number of unit tests that require VTROOT by moving testdata closer to the tests Signed-off-by: David Weitzman --- doc/FAQ.md | 2 +- go/cgzip/eof_read_test.go | 5 +- {data/test => go/cgzip/testdata}/cgzip_eof.gz | Bin go/testfiles/locate.go | 64 ------------------ .../vtexplain/testdata}/comments-queries.sql | 0 .../testdata}/deletesharded-queries.sql | 0 .../testdata}/insertsharded-queries.sql | 0 .../multi-output/comments-output.txt | 0 .../multi-output/deletesharded-output.txt | 0 .../multi-output/insertsharded-output.txt | 0 .../testdata}/multi-output/options-output.txt | 0 .../multi-output/selectsharded-output.txt | 0 .../testdata}/multi-output/target-output.txt | 0 .../multi-output/unsharded-output.txt | 0 .../multi-output/updatesharded-output.txt | 0 .../vtexplain/testdata}/options-queries.sql | 0 .../testdata}/selectsharded-queries.sql | 0 .../vt/vtexplain/testdata}/target-queries.sql | 0 .../vt/vtexplain/testdata}/test-schema.sql | 0 .../vt/vtexplain/testdata}/test-vschema.json | 0 .../twopc-output/comments-output.txt | 0 .../twopc-output/deletesharded-output.txt | 0 .../twopc-output/insertsharded-output.txt | 0 .../testdata}/twopc-output/options-output.txt | 0 .../twopc-output/selectsharded-output.txt | 0 .../twopc-output/unsharded-output.txt | 0 .../twopc-output/updatesharded-output.txt | 0 .../vtexplain/testdata}/unsharded-queries.sql | 0 .../testdata}/updatesharded-queries.sql | 0 go/vt/vtexplain/vtexplain_flaky_test.go | 10 ++- go/vt/vtgate/planbuilder/plan_test.go | 7 +- .../planbuilder/testdata}/aggr_cases.txt | 0 .../planbuilder/testdata}/dml_cases.txt | 0 .../planbuilder/testdata}/filter_cases.txt | 0 .../planbuilder/testdata}/from_cases.txt | 0 .../vtgate/planbuilder/testdata}/onecase.txt | 0 .../testdata}/postprocess_cases.txt | 0 .../planbuilder/testdata}/schema_test.json | 0 .../planbuilder/testdata}/select_cases.txt | 0 .../planbuilder/testdata}/symtab_cases.txt | 0 .../testdata}/unsupported_cases.txt | 0 .../testdata}/vindex_func_cases.txt | 0 .../planbuilder/testdata}/wireup_cases.txt | 0 .../vindexes/numeric_static_map_test.go | 7 +- .../testdata}/numeric_static_map_test.json | 0 .../tabletserver/planbuilder/plan_test.go | 9 +-- .../planbuilder/testdata}/ddl_cases.txt | 0 .../planbuilder/testdata}/exec_cases.txt | 0 .../planbuilder/testdata}/schema_test.json | 0 .../planbuilder/testdata}/stream_cases.txt | 0 50 files changed, 10 insertions(+), 94 deletions(-) rename {data/test => go/cgzip/testdata}/cgzip_eof.gz (100%) delete mode 100644 go/testfiles/locate.go rename {data/test/vtexplain => go/vt/vtexplain/testdata}/comments-queries.sql (100%) rename {data/test/vtexplain => go/vt/vtexplain/testdata}/deletesharded-queries.sql (100%) rename {data/test/vtexplain => go/vt/vtexplain/testdata}/insertsharded-queries.sql (100%) rename {data/test/vtexplain => go/vt/vtexplain/testdata}/multi-output/comments-output.txt (100%) rename {data/test/vtexplain => go/vt/vtexplain/testdata}/multi-output/deletesharded-output.txt (100%) rename {data/test/vtexplain => go/vt/vtexplain/testdata}/multi-output/insertsharded-output.txt (100%) rename {data/test/vtexplain => go/vt/vtexplain/testdata}/multi-output/options-output.txt (100%) rename {data/test/vtexplain => go/vt/vtexplain/testdata}/multi-output/selectsharded-output.txt (100%) rename {data/test/vtexplain => go/vt/vtexplain/testdata}/multi-output/target-output.txt (100%) rename {data/test/vtexplain => go/vt/vtexplain/testdata}/multi-output/unsharded-output.txt (100%) rename {data/test/vtexplain => go/vt/vtexplain/testdata}/multi-output/updatesharded-output.txt (100%) rename {data/test/vtexplain => go/vt/vtexplain/testdata}/options-queries.sql (100%) rename {data/test/vtexplain => go/vt/vtexplain/testdata}/selectsharded-queries.sql (100%) rename {data/test/vtexplain => go/vt/vtexplain/testdata}/target-queries.sql (100%) rename {data/test/vtexplain => go/vt/vtexplain/testdata}/test-schema.sql (100%) rename {data/test/vtexplain => go/vt/vtexplain/testdata}/test-vschema.json (100%) rename {data/test/vtexplain => go/vt/vtexplain/testdata}/twopc-output/comments-output.txt (100%) rename {data/test/vtexplain => go/vt/vtexplain/testdata}/twopc-output/deletesharded-output.txt (100%) rename {data/test/vtexplain => go/vt/vtexplain/testdata}/twopc-output/insertsharded-output.txt (100%) rename {data/test/vtexplain => go/vt/vtexplain/testdata}/twopc-output/options-output.txt (100%) rename {data/test/vtexplain => go/vt/vtexplain/testdata}/twopc-output/selectsharded-output.txt (100%) rename {data/test/vtexplain => go/vt/vtexplain/testdata}/twopc-output/unsharded-output.txt (100%) rename {data/test/vtexplain => go/vt/vtexplain/testdata}/twopc-output/updatesharded-output.txt (100%) rename {data/test/vtexplain => go/vt/vtexplain/testdata}/unsharded-queries.sql (100%) rename {data/test/vtexplain => go/vt/vtexplain/testdata}/updatesharded-queries.sql (100%) rename {data/test/vtgate => go/vt/vtgate/planbuilder/testdata}/aggr_cases.txt (100%) rename {data/test/vtgate => go/vt/vtgate/planbuilder/testdata}/dml_cases.txt (100%) rename {data/test/vtgate => go/vt/vtgate/planbuilder/testdata}/filter_cases.txt (100%) rename {data/test/vtgate => go/vt/vtgate/planbuilder/testdata}/from_cases.txt (100%) rename {data/test/vtgate => go/vt/vtgate/planbuilder/testdata}/onecase.txt (100%) rename {data/test/vtgate => go/vt/vtgate/planbuilder/testdata}/postprocess_cases.txt (100%) rename {data/test/vtgate => go/vt/vtgate/planbuilder/testdata}/schema_test.json (100%) rename {data/test/vtgate => go/vt/vtgate/planbuilder/testdata}/select_cases.txt (100%) rename {data/test/vtgate => go/vt/vtgate/planbuilder/testdata}/symtab_cases.txt (100%) rename {data/test/vtgate => go/vt/vtgate/planbuilder/testdata}/unsupported_cases.txt (100%) rename {data/test/vtgate => go/vt/vtgate/planbuilder/testdata}/vindex_func_cases.txt (100%) rename {data/test/vtgate => go/vt/vtgate/planbuilder/testdata}/wireup_cases.txt (100%) rename {data/test/vtgate => go/vt/vtgate/vindexes/testdata}/numeric_static_map_test.json (100%) rename {data/test/tabletserver => go/vt/vttablet/tabletserver/planbuilder/testdata}/ddl_cases.txt (100%) rename {data/test/tabletserver => go/vt/vttablet/tabletserver/planbuilder/testdata}/exec_cases.txt (100%) rename {data/test/tabletserver => go/vt/vttablet/tabletserver/planbuilder/testdata}/schema_test.json (100%) rename {data/test/tabletserver => go/vt/vttablet/tabletserver/planbuilder/testdata}/stream_cases.txt (100%) diff --git a/doc/FAQ.md b/doc/FAQ.md index b84d14740d0..1eddd677e0c 100644 --- a/doc/FAQ.md +++ b/doc/FAQ.md @@ -32,7 +32,7 @@ The general convention is to send OLTP queries to `REPLICA` tablet types, and OL ## Is there a list of supported/unsupported queries? -The list of unsupported constructs is currently in the form of test cases contained in this [test file](https://github.com/vitessio/vitess/blob/master/data/test/vtgate/unsupported_cases.txt). However, contrary to the test cases, there is limited support for SET, DDL and DBA constructs. This will be documented soon. +The list of unsupported constructs is currently in the form of test cases contained in this [test file](https://github.com/vitessio/vitess/blob/master/go/vt/vtgate/planbuilder/testdata/unsupported_cases.txt). However, contrary to the test cases, there is limited support for SET, DDL and DBA constructs. This will be documented soon. ## If I have a log of all queries from my app. Is there a way I can try them against vitess to see how they’ll work? diff --git a/go/cgzip/eof_read_test.go b/go/cgzip/eof_read_test.go index 3cdd9faaa1b..e884b324527 100644 --- a/go/cgzip/eof_read_test.go +++ b/go/cgzip/eof_read_test.go @@ -20,8 +20,6 @@ import ( "io" "io/ioutil" "testing" - - "vitess.io/vitess/go/testfiles" ) // specialReader is a test class that will return bytes it reads from a file, @@ -33,7 +31,6 @@ type specialReader struct { } func newSpecialReader(t *testing.T, filename string) *specialReader { - filename = testfiles.Locate(filename) b, err := ioutil.ReadFile(filename) if err != nil { t.Fatalf("Cannot read file %v: %v", filename, err) @@ -61,7 +58,7 @@ func (sr *specialReader) Read(p []byte) (int, error) { // So it will be read as 32k + 22k, and decompressed into 2MB + 2MB + 1M and // then 2MB + 2MB + 1M again. So it's a great test for corner cases. func TestEofAndData(t *testing.T) { - r := newSpecialReader(t, "cgzip_eof.gz") + r := newSpecialReader(t, "testdata/cgzip_eof.gz") gz, err := NewReader(r) if err != nil { t.Fatalf("NewReader failed: %v", err) diff --git a/data/test/cgzip_eof.gz b/go/cgzip/testdata/cgzip_eof.gz similarity index 100% rename from data/test/cgzip_eof.gz rename to go/cgzip/testdata/cgzip_eof.gz diff --git a/go/testfiles/locate.go b/go/testfiles/locate.go deleted file mode 100644 index 6ba6b32afaf..00000000000 --- a/go/testfiles/locate.go +++ /dev/null @@ -1,64 +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 testfiles locates test files within the Vitess directory tree. -// It also handles test port allocation. -package testfiles - -import ( - "fmt" - "os" - "path" - "path/filepath" -) - -// Locate returns a file path that came from $VTROOT/data/test. -func Locate(filename string) string { - vtroot := os.Getenv("VTROOT") - if vtroot == "" { - panic(fmt.Errorf("VTROOT is not set")) - } - return path.Join(vtroot, "data", "test", filename) -} - -// Glob returns all files matching a pattern in $VTROOT/data/test. -func Glob(pattern string) []string { - vtroot := os.Getenv("VTROOT") - if vtroot == "" { - panic(fmt.Errorf("VTROOT is not set")) - } - dir := path.Join(vtroot, "data", "test") - if exists, err := exists(dir); !exists { - panic(err) - } - resolved := path.Join(dir, pattern) - out, err := filepath.Glob(resolved) - if err != nil { - panic(err) - } - return out -} - -func exists(path string) (bool, error) { - _, err := os.Stat(path) - if err == nil { - return true, nil - } - if os.IsNotExist(err) { - return false, err - } - return false, err -} diff --git a/data/test/vtexplain/comments-queries.sql b/go/vt/vtexplain/testdata/comments-queries.sql similarity index 100% rename from data/test/vtexplain/comments-queries.sql rename to go/vt/vtexplain/testdata/comments-queries.sql diff --git a/data/test/vtexplain/deletesharded-queries.sql b/go/vt/vtexplain/testdata/deletesharded-queries.sql similarity index 100% rename from data/test/vtexplain/deletesharded-queries.sql rename to go/vt/vtexplain/testdata/deletesharded-queries.sql diff --git a/data/test/vtexplain/insertsharded-queries.sql b/go/vt/vtexplain/testdata/insertsharded-queries.sql similarity index 100% rename from data/test/vtexplain/insertsharded-queries.sql rename to go/vt/vtexplain/testdata/insertsharded-queries.sql diff --git a/data/test/vtexplain/multi-output/comments-output.txt b/go/vt/vtexplain/testdata/multi-output/comments-output.txt similarity index 100% rename from data/test/vtexplain/multi-output/comments-output.txt rename to go/vt/vtexplain/testdata/multi-output/comments-output.txt diff --git a/data/test/vtexplain/multi-output/deletesharded-output.txt b/go/vt/vtexplain/testdata/multi-output/deletesharded-output.txt similarity index 100% rename from data/test/vtexplain/multi-output/deletesharded-output.txt rename to go/vt/vtexplain/testdata/multi-output/deletesharded-output.txt diff --git a/data/test/vtexplain/multi-output/insertsharded-output.txt b/go/vt/vtexplain/testdata/multi-output/insertsharded-output.txt similarity index 100% rename from data/test/vtexplain/multi-output/insertsharded-output.txt rename to go/vt/vtexplain/testdata/multi-output/insertsharded-output.txt diff --git a/data/test/vtexplain/multi-output/options-output.txt b/go/vt/vtexplain/testdata/multi-output/options-output.txt similarity index 100% rename from data/test/vtexplain/multi-output/options-output.txt rename to go/vt/vtexplain/testdata/multi-output/options-output.txt diff --git a/data/test/vtexplain/multi-output/selectsharded-output.txt b/go/vt/vtexplain/testdata/multi-output/selectsharded-output.txt similarity index 100% rename from data/test/vtexplain/multi-output/selectsharded-output.txt rename to go/vt/vtexplain/testdata/multi-output/selectsharded-output.txt diff --git a/data/test/vtexplain/multi-output/target-output.txt b/go/vt/vtexplain/testdata/multi-output/target-output.txt similarity index 100% rename from data/test/vtexplain/multi-output/target-output.txt rename to go/vt/vtexplain/testdata/multi-output/target-output.txt diff --git a/data/test/vtexplain/multi-output/unsharded-output.txt b/go/vt/vtexplain/testdata/multi-output/unsharded-output.txt similarity index 100% rename from data/test/vtexplain/multi-output/unsharded-output.txt rename to go/vt/vtexplain/testdata/multi-output/unsharded-output.txt diff --git a/data/test/vtexplain/multi-output/updatesharded-output.txt b/go/vt/vtexplain/testdata/multi-output/updatesharded-output.txt similarity index 100% rename from data/test/vtexplain/multi-output/updatesharded-output.txt rename to go/vt/vtexplain/testdata/multi-output/updatesharded-output.txt diff --git a/data/test/vtexplain/options-queries.sql b/go/vt/vtexplain/testdata/options-queries.sql similarity index 100% rename from data/test/vtexplain/options-queries.sql rename to go/vt/vtexplain/testdata/options-queries.sql diff --git a/data/test/vtexplain/selectsharded-queries.sql b/go/vt/vtexplain/testdata/selectsharded-queries.sql similarity index 100% rename from data/test/vtexplain/selectsharded-queries.sql rename to go/vt/vtexplain/testdata/selectsharded-queries.sql diff --git a/data/test/vtexplain/target-queries.sql b/go/vt/vtexplain/testdata/target-queries.sql similarity index 100% rename from data/test/vtexplain/target-queries.sql rename to go/vt/vtexplain/testdata/target-queries.sql diff --git a/data/test/vtexplain/test-schema.sql b/go/vt/vtexplain/testdata/test-schema.sql similarity index 100% rename from data/test/vtexplain/test-schema.sql rename to go/vt/vtexplain/testdata/test-schema.sql diff --git a/data/test/vtexplain/test-vschema.json b/go/vt/vtexplain/testdata/test-vschema.json similarity index 100% rename from data/test/vtexplain/test-vschema.json rename to go/vt/vtexplain/testdata/test-vschema.json diff --git a/data/test/vtexplain/twopc-output/comments-output.txt b/go/vt/vtexplain/testdata/twopc-output/comments-output.txt similarity index 100% rename from data/test/vtexplain/twopc-output/comments-output.txt rename to go/vt/vtexplain/testdata/twopc-output/comments-output.txt diff --git a/data/test/vtexplain/twopc-output/deletesharded-output.txt b/go/vt/vtexplain/testdata/twopc-output/deletesharded-output.txt similarity index 100% rename from data/test/vtexplain/twopc-output/deletesharded-output.txt rename to go/vt/vtexplain/testdata/twopc-output/deletesharded-output.txt diff --git a/data/test/vtexplain/twopc-output/insertsharded-output.txt b/go/vt/vtexplain/testdata/twopc-output/insertsharded-output.txt similarity index 100% rename from data/test/vtexplain/twopc-output/insertsharded-output.txt rename to go/vt/vtexplain/testdata/twopc-output/insertsharded-output.txt diff --git a/data/test/vtexplain/twopc-output/options-output.txt b/go/vt/vtexplain/testdata/twopc-output/options-output.txt similarity index 100% rename from data/test/vtexplain/twopc-output/options-output.txt rename to go/vt/vtexplain/testdata/twopc-output/options-output.txt diff --git a/data/test/vtexplain/twopc-output/selectsharded-output.txt b/go/vt/vtexplain/testdata/twopc-output/selectsharded-output.txt similarity index 100% rename from data/test/vtexplain/twopc-output/selectsharded-output.txt rename to go/vt/vtexplain/testdata/twopc-output/selectsharded-output.txt diff --git a/data/test/vtexplain/twopc-output/unsharded-output.txt b/go/vt/vtexplain/testdata/twopc-output/unsharded-output.txt similarity index 100% rename from data/test/vtexplain/twopc-output/unsharded-output.txt rename to go/vt/vtexplain/testdata/twopc-output/unsharded-output.txt diff --git a/data/test/vtexplain/twopc-output/updatesharded-output.txt b/go/vt/vtexplain/testdata/twopc-output/updatesharded-output.txt similarity index 100% rename from data/test/vtexplain/twopc-output/updatesharded-output.txt rename to go/vt/vtexplain/testdata/twopc-output/updatesharded-output.txt diff --git a/data/test/vtexplain/unsharded-queries.sql b/go/vt/vtexplain/testdata/unsharded-queries.sql similarity index 100% rename from data/test/vtexplain/unsharded-queries.sql rename to go/vt/vtexplain/testdata/unsharded-queries.sql diff --git a/data/test/vtexplain/updatesharded-queries.sql b/go/vt/vtexplain/testdata/updatesharded-queries.sql similarity index 100% rename from data/test/vtexplain/updatesharded-queries.sql rename to go/vt/vtexplain/testdata/updatesharded-queries.sql diff --git a/go/vt/vtexplain/vtexplain_flaky_test.go b/go/vt/vtexplain/vtexplain_flaky_test.go index 190bd949894..370f59fcccd 100644 --- a/go/vt/vtexplain/vtexplain_flaky_test.go +++ b/go/vt/vtexplain/vtexplain_flaky_test.go @@ -24,8 +24,6 @@ import ( "path" "strings" "testing" - - "vitess.io/vitess/go/testfiles" ) var testOutputTempDir string @@ -40,12 +38,12 @@ func defaultTestOpts() *Options { } func initTest(mode string, opts *Options, t *testing.T) { - schema, err := ioutil.ReadFile(testfiles.Locate("vtexplain/test-schema.sql")) + schema, err := ioutil.ReadFile("testdata/test-schema.sql") if err != nil { t.Fatalf("error: %v", err) } - vSchema, err := ioutil.ReadFile(testfiles.Locate("vtexplain/test-vschema.json")) + vSchema, err := ioutil.ReadFile("testdata/test-vschema.json") if err != nil { t.Fatalf("error: %v", err) } @@ -75,13 +73,13 @@ func runTestCase(testcase, mode string, opts *Options, t *testing.T) { t.Logf("vtexplain test: %s mode: %s", testcase, mode) initTest(mode, opts, t) - sqlFile := testfiles.Locate(fmt.Sprintf("vtexplain/%s-queries.sql", testcase)) + sqlFile := fmt.Sprintf("testdata/%s-queries.sql", testcase) sql, err := ioutil.ReadFile(sqlFile) if err != nil { t.Fatalf("vtexplain error: %v", err) } - textOutFile := testfiles.Locate(fmt.Sprintf("vtexplain/%s-output/%s-output.txt", mode, testcase)) + textOutFile := fmt.Sprintf("testdata/%s-output/%s-output.txt", mode, testcase) textOut, _ := ioutil.ReadFile(textOutFile) explains, err := Run(string(sql)) diff --git a/go/vt/vtgate/planbuilder/plan_test.go b/go/vt/vtgate/planbuilder/plan_test.go index d6bcd90d667..c98686fba91 100644 --- a/go/vt/vtgate/planbuilder/plan_test.go +++ b/go/vt/vtgate/planbuilder/plan_test.go @@ -23,12 +23,10 @@ import ( "fmt" "io" "os" - "path" "strings" "testing" "vitess.io/vitess/go/sqltypes" - "vitess.io/vitess/go/testfiles" "vitess.io/vitess/go/vt/key" "vitess.io/vitess/go/vt/sqlparser" "vitess.io/vitess/go/vt/topo/topoproto" @@ -334,8 +332,5 @@ func iterateExecFile(name string) (testCaseIterator chan testCase) { } func locateFile(name string) string { - if path.IsAbs(name) { - return name - } - return testfiles.Locate("vtgate/" + name) + return "testdata/" + name } diff --git a/data/test/vtgate/aggr_cases.txt b/go/vt/vtgate/planbuilder/testdata/aggr_cases.txt similarity index 100% rename from data/test/vtgate/aggr_cases.txt rename to go/vt/vtgate/planbuilder/testdata/aggr_cases.txt diff --git a/data/test/vtgate/dml_cases.txt b/go/vt/vtgate/planbuilder/testdata/dml_cases.txt similarity index 100% rename from data/test/vtgate/dml_cases.txt rename to go/vt/vtgate/planbuilder/testdata/dml_cases.txt diff --git a/data/test/vtgate/filter_cases.txt b/go/vt/vtgate/planbuilder/testdata/filter_cases.txt similarity index 100% rename from data/test/vtgate/filter_cases.txt rename to go/vt/vtgate/planbuilder/testdata/filter_cases.txt diff --git a/data/test/vtgate/from_cases.txt b/go/vt/vtgate/planbuilder/testdata/from_cases.txt similarity index 100% rename from data/test/vtgate/from_cases.txt rename to go/vt/vtgate/planbuilder/testdata/from_cases.txt diff --git a/data/test/vtgate/onecase.txt b/go/vt/vtgate/planbuilder/testdata/onecase.txt similarity index 100% rename from data/test/vtgate/onecase.txt rename to go/vt/vtgate/planbuilder/testdata/onecase.txt diff --git a/data/test/vtgate/postprocess_cases.txt b/go/vt/vtgate/planbuilder/testdata/postprocess_cases.txt similarity index 100% rename from data/test/vtgate/postprocess_cases.txt rename to go/vt/vtgate/planbuilder/testdata/postprocess_cases.txt diff --git a/data/test/vtgate/schema_test.json b/go/vt/vtgate/planbuilder/testdata/schema_test.json similarity index 100% rename from data/test/vtgate/schema_test.json rename to go/vt/vtgate/planbuilder/testdata/schema_test.json diff --git a/data/test/vtgate/select_cases.txt b/go/vt/vtgate/planbuilder/testdata/select_cases.txt similarity index 100% rename from data/test/vtgate/select_cases.txt rename to go/vt/vtgate/planbuilder/testdata/select_cases.txt diff --git a/data/test/vtgate/symtab_cases.txt b/go/vt/vtgate/planbuilder/testdata/symtab_cases.txt similarity index 100% rename from data/test/vtgate/symtab_cases.txt rename to go/vt/vtgate/planbuilder/testdata/symtab_cases.txt diff --git a/data/test/vtgate/unsupported_cases.txt b/go/vt/vtgate/planbuilder/testdata/unsupported_cases.txt similarity index 100% rename from data/test/vtgate/unsupported_cases.txt rename to go/vt/vtgate/planbuilder/testdata/unsupported_cases.txt diff --git a/data/test/vtgate/vindex_func_cases.txt b/go/vt/vtgate/planbuilder/testdata/vindex_func_cases.txt similarity index 100% rename from data/test/vtgate/vindex_func_cases.txt rename to go/vt/vtgate/planbuilder/testdata/vindex_func_cases.txt diff --git a/data/test/vtgate/wireup_cases.txt b/go/vt/vtgate/planbuilder/testdata/wireup_cases.txt similarity index 100% rename from data/test/vtgate/wireup_cases.txt rename to go/vt/vtgate/planbuilder/testdata/wireup_cases.txt diff --git a/go/vt/vtgate/vindexes/numeric_static_map_test.go b/go/vt/vtgate/vindexes/numeric_static_map_test.go index fe9f0ae37cc..78829c6d68c 100644 --- a/go/vt/vtgate/vindexes/numeric_static_map_test.go +++ b/go/vt/vtgate/vindexes/numeric_static_map_test.go @@ -23,19 +23,14 @@ import ( "strings" "vitess.io/vitess/go/sqltypes" - "vitess.io/vitess/go/testfiles" "vitess.io/vitess/go/vt/key" ) // createVindex creates the "numeric_static_map" vindex object which is used by // each test. -// -// IMPORTANT: This code is called per test and must not be called from init() -// because our internal implementation of testfiles.Locate() does not support to -// be called from init(). func createVindex() (Vindex, error) { m := make(map[string]string) - m["json_path"] = testfiles.Locate("vtgate/numeric_static_map_test.json") + m["json_path"] = "testdata/numeric_static_map_test.json" return CreateVindex("numeric_static_map", "numericStaticMap", m) } diff --git a/data/test/vtgate/numeric_static_map_test.json b/go/vt/vtgate/vindexes/testdata/numeric_static_map_test.json similarity index 100% rename from data/test/vtgate/numeric_static_map_test.json rename to go/vt/vtgate/vindexes/testdata/numeric_static_map_test.json diff --git a/go/vt/vttablet/tabletserver/planbuilder/plan_test.go b/go/vt/vttablet/tabletserver/planbuilder/plan_test.go index f6f2e671a05..9f8b95debc6 100644 --- a/go/vt/vttablet/tabletserver/planbuilder/plan_test.go +++ b/go/vt/vttablet/tabletserver/planbuilder/plan_test.go @@ -25,13 +25,11 @@ import ( "io/ioutil" "log" "os" - "path" "path/filepath" "strings" "testing" "vitess.io/vitess/go/sqltypes" - "vitess.io/vitess/go/testfiles" "vitess.io/vitess/go/vt/sqlparser" "vitess.io/vitess/go/vt/tableacl" "vitess.io/vitess/go/vt/vttablet/tabletserver/schema" @@ -112,7 +110,7 @@ func TestPlan(t *testing.T) { } func TestCustom(t *testing.T) { - testSchemas := testfiles.Glob("tabletserver/*_schema.json") + testSchemas, _ := filepath.Glob("testdata/*_schema.json") if len(testSchemas) == 0 { t.Log("No schemas to test") return @@ -325,8 +323,5 @@ func iterateExecFile(name string) (testCaseIterator chan testCase) { } func locateFile(name string) string { - if path.IsAbs(name) { - return name - } - return testfiles.Locate("tabletserver/" + name) + return "testdata/" + name } diff --git a/data/test/tabletserver/ddl_cases.txt b/go/vt/vttablet/tabletserver/planbuilder/testdata/ddl_cases.txt similarity index 100% rename from data/test/tabletserver/ddl_cases.txt rename to go/vt/vttablet/tabletserver/planbuilder/testdata/ddl_cases.txt diff --git a/data/test/tabletserver/exec_cases.txt b/go/vt/vttablet/tabletserver/planbuilder/testdata/exec_cases.txt similarity index 100% rename from data/test/tabletserver/exec_cases.txt rename to go/vt/vttablet/tabletserver/planbuilder/testdata/exec_cases.txt diff --git a/data/test/tabletserver/schema_test.json b/go/vt/vttablet/tabletserver/planbuilder/testdata/schema_test.json similarity index 100% rename from data/test/tabletserver/schema_test.json rename to go/vt/vttablet/tabletserver/planbuilder/testdata/schema_test.json diff --git a/data/test/tabletserver/stream_cases.txt b/go/vt/vttablet/tabletserver/planbuilder/testdata/stream_cases.txt similarity index 100% rename from data/test/tabletserver/stream_cases.txt rename to go/vt/vttablet/tabletserver/planbuilder/testdata/stream_cases.txt From ade04fe7663e0eed42cad3202ef539ca3758f679 Mon Sep 17 00:00:00 2001 From: Simon J Mudd Date: Thu, 24 Jan 2019 14:05:11 +0100 Subject: [PATCH 084/115] Change common unhandled packet error message to clarify origin Signed-off-by: Simon J Mudd --- go/mysql/conn.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/go/mysql/conn.go b/go/mysql/conn.go index 2cf2ab99786..e14ffa941dd 100644 --- a/go/mysql/conn.go +++ b/go/mysql/conn.go @@ -780,7 +780,7 @@ func (c *Conn) handleNextCommand(handler Handler) error { case 1: c.Capabilities &^= CapabilityClientMultiStatements default: - log.Errorf("Got unhandled packet from client %v, returning error: %v", c.ConnectionID, data) + log.Errorf("Got unhandled packet (ComSetOption default) from client %v, returning error: %v", c.ConnectionID, data) if err := c.writeErrorPacket(ERUnknownComError, SSUnknownComError, "error handling packet: %v", data); err != nil { log.Errorf("Error writing error packet to client: %v", err) return err @@ -791,14 +791,14 @@ func (c *Conn) handleNextCommand(handler Handler) error { return err } } else { - log.Errorf("Got unhandled packet from client %v, returning error: %v", c.ConnectionID, data) + log.Errorf("Got unhandled packet (ComSetOption else) from client %v, returning error: %v", c.ConnectionID, data) if err := c.writeErrorPacket(ERUnknownComError, SSUnknownComError, "error handling packet: %v", data); err != nil { log.Errorf("Error writing error packet to client: %v", err) return err } } default: - log.Errorf("Got unhandled packet from %s, returning error: %v", c, data) + log.Errorf("Got unhandled packet (default) from %s, returning error: %v", c, data) c.recycleReadPacket() if err := c.writeErrorPacket(ERUnknownComError, SSUnknownComError, "command handling not implemented yet: %v", data[0]); err != nil { log.Errorf("Error writing error packet to %s: %s", c, err) From 4f5ae09517ca3c658fe4500c315b0269a88444e2 Mon Sep 17 00:00:00 2001 From: Derek Perkins Date: Thu, 24 Jan 2019 13:58:06 -0700 Subject: [PATCH 085/115] mysqlctl: add MyRocks dir/files to backups Signed-off-by: Derek Perkins --- go/vt/mysqlctl/backup.go | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/go/vt/mysqlctl/backup.go b/go/vt/mysqlctl/backup.go index ccecaee9431..6afeb774d52 100644 --- a/go/vt/mysqlctl/backup.go +++ b/go/vt/mysqlctl/backup.go @@ -164,7 +164,7 @@ func isDbDir(p string) bool { return true } - // Look for at least one .frm file + // Look for at least one database file fis, err := ioutil.ReadDir(p) if err != nil { return false @@ -174,6 +174,12 @@ func isDbDir(p string) bool { 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") { From 023f62e7f2a67745a7fd25530cd940b6bba644da Mon Sep 17 00:00:00 2001 From: Aaron Young Date: Wed, 9 Jan 2019 12:16:27 -0500 Subject: [PATCH 086/115] Add a special plan type for impossible queries Signed-off-by: Aaron Young --- go/vt/sqlparser/ast.go | 26 +++++++++++++ go/vt/sqlparser/ast_test.go | 29 ++++++++++++++ go/vt/vttablet/endtoend/queries_test.go | 32 ++++++++++++++++ .../vttablet/tabletserver/planbuilder/dml.go | 8 ++++ .../vttablet/tabletserver/planbuilder/plan.go | 38 ++++++++++--------- go/vt/vttablet/tabletserver/query_executor.go | 15 +++++++- .../tabletserver/query_executor_test.go | 27 ++++++++++++- 7 files changed, 155 insertions(+), 20 deletions(-) diff --git a/go/vt/sqlparser/ast.go b/go/vt/sqlparser/ast.go index df3dfd75dd8..7881f24398a 100644 --- a/go/vt/sqlparser/ast.go +++ b/go/vt/sqlparser/ast.go @@ -2379,6 +2379,32 @@ func (node *ComparisonExpr) replace(from, to Expr) bool { return replaceExprs(from, to, &node.Left, &node.Right, &node.Escape) } +// IsImpossible returns true if the comparison in the expression can never evaluate to true. +// Note that this is not currently exhaustive to ALL impossible comparisons. +func (node *ComparisonExpr) IsImpossible() bool { + var left, right *SQLVal + var ok bool + if left, ok = node.Left.(*SQLVal); !ok { + return false + } + if right, ok = node.Right.(*SQLVal); !ok { + return false + } + if node.Operator == NotEqualStr && left.Type == right.Type { + if len(left.Val) != len(right.Val) { + return false + } + + for i := range left.Val { + if left.Val[i] != right.Val[i] { + return false + } + } + return true + } + return false +} + // RangeCond represents a BETWEEN or a NOT BETWEEN expression. type RangeCond struct { Operator string diff --git a/go/vt/sqlparser/ast_test.go b/go/vt/sqlparser/ast_test.go index 08bd05d96d8..cf66c254001 100644 --- a/go/vt/sqlparser/ast_test.go +++ b/go/vt/sqlparser/ast_test.go @@ -412,6 +412,35 @@ func TestIsAggregate(t *testing.T) { } } +func TestIsImpossible(t *testing.T) { + f := ComparisonExpr{ + Operator: NotEqualStr, + Left: newIntVal("1"), + Right: newIntVal("1"), + } + if !f.IsImpossible() { + t.Error("IsImpossible: false, want true") + } + + f = ComparisonExpr{ + Operator: EqualStr, + Left: newIntVal("1"), + Right: newIntVal("1"), + } + if f.IsImpossible() { + t.Error("IsImpossible: true, want false") + } + + f = ComparisonExpr{ + Operator: NotEqualStr, + Left: newIntVal("1"), + Right: newIntVal("2"), + } + if f.IsImpossible() { + t.Error("IsImpossible: true, want false") + } +} + func TestReplaceExpr(t *testing.T) { tcases := []struct { in, out string diff --git a/go/vt/vttablet/endtoend/queries_test.go b/go/vt/vttablet/endtoend/queries_test.go index 56021b831da..f407e08b91f 100644 --- a/go/vt/vttablet/endtoend/queries_test.go +++ b/go/vt/vttablet/endtoend/queries_test.go @@ -1789,6 +1789,38 @@ func TestQueries(t *testing.T) { }, }, }, + &framework.MultiCase{ + Name: "impossible queries", + Cases: []framework.Testable{ + &framework.TestCase{ + Name: "specific column", + Query: "select eid from vitess_a where 1 != 1", + Rewritten: []string{ + "select eid from vitess_a where 1 != 1", + }, + RowsAffected: 0, + }, + &framework.TestCase{ + Name: "all columns", + Query: "select * from vitess_a where 1 != 1", + Rewritten: []string{ + "select * from vitess_a where 1 != 1", + }, + RowsAffected: 0, + }, + &framework.TestCase{ + Name: "bind vars", + Query: "select :bv from vitess_a where 1 != 1", + BindVars: map[string]*querypb.BindVariable{ + "bv": sqltypes.Int64BindVariable(1), + }, + Rewritten: []string{ + "select 1 from vitess_a where 1 != 1 limit 10001", + }, + RowsAffected: 0, + }, + }, + }, } for _, tcase := range testCases { if err := tcase.Test("", client); err != nil { diff --git a/go/vt/vttablet/tabletserver/planbuilder/dml.go b/go/vt/vttablet/tabletserver/planbuilder/dml.go index bdaed0ac5f8..c1cadcc4d73 100644 --- a/go/vt/vttablet/tabletserver/planbuilder/dml.go +++ b/go/vt/vttablet/tabletserver/planbuilder/dml.go @@ -202,6 +202,14 @@ func analyzeSelect(sel *sqlparser.Select, tables map[string]*schema.Table) (plan return nil, err } + if sel.Where != nil { + comp, ok := sel.Where.Expr.(*sqlparser.ComparisonExpr) + if ok && comp.IsImpossible() { + plan.PlanID = PlanSelectImpossible + return plan, nil + } + } + // Check if it's a NEXT VALUE statement. if nextVal, ok := sel.SelectExprs[0].(sqlparser.Nextval); ok { if table.Type != schema.Sequence { diff --git a/go/vt/vttablet/tabletserver/planbuilder/plan.go b/go/vt/vttablet/tabletserver/planbuilder/plan.go index bbeecd963ea..befeae05e40 100644 --- a/go/vt/vttablet/tabletserver/planbuilder/plan.go +++ b/go/vt/vttablet/tabletserver/planbuilder/plan.go @@ -83,6 +83,8 @@ const ( PlanOtherAdmin // PlanMessageStream is used for streaming messages. PlanMessageStream + // PlanSelectImpossible is used for where or having clauses that can never be true. + PlanSelectImpossible // NumPlans stores the total number of plans NumPlans ) @@ -105,6 +107,7 @@ var planName = [NumPlans]string{ "OTHER_READ", "OTHER_ADMIN", "MESSAGE_STREAM", + "SELECT_IMPOSSIBLE", } func (pt PlanType) String() string { @@ -126,7 +129,7 @@ func PlanByName(s string) (pt PlanType, ok bool) { // IsSelect returns true if PlanType is about a select query. func (pt PlanType) IsSelect() bool { - return pt == PlanPassSelect || pt == PlanSelectLock + return pt == PlanPassSelect || pt == PlanSelectLock || pt == PlanSelectImpossible } // MarshalJSON returns a json string for PlanType. @@ -140,22 +143,23 @@ func (pt PlanType) MinRole() tableacl.Role { } var tableACLRoles = map[PlanType]tableacl.Role{ - PlanPassSelect: tableacl.READER, - PlanSelectLock: tableacl.READER, - PlanSet: tableacl.READER, - PlanPassDML: tableacl.WRITER, - PlanDMLPK: tableacl.WRITER, - PlanDMLSubquery: tableacl.WRITER, - PlanInsertPK: tableacl.WRITER, - PlanInsertSubquery: tableacl.WRITER, - PlanInsertMessage: tableacl.WRITER, - PlanDDL: tableacl.ADMIN, - PlanSelectStream: tableacl.READER, - PlanOtherRead: tableacl.READER, - PlanOtherAdmin: tableacl.ADMIN, - PlanUpsertPK: tableacl.WRITER, - PlanNextval: tableacl.WRITER, - PlanMessageStream: tableacl.WRITER, + PlanPassSelect: tableacl.READER, + PlanSelectLock: tableacl.READER, + PlanSet: tableacl.READER, + PlanPassDML: tableacl.WRITER, + PlanDMLPK: tableacl.WRITER, + PlanDMLSubquery: tableacl.WRITER, + PlanInsertPK: tableacl.WRITER, + PlanInsertSubquery: tableacl.WRITER, + PlanInsertMessage: tableacl.WRITER, + PlanDDL: tableacl.ADMIN, + PlanSelectStream: tableacl.READER, + PlanOtherRead: tableacl.READER, + PlanOtherAdmin: tableacl.ADMIN, + PlanUpsertPK: tableacl.WRITER, + PlanNextval: tableacl.WRITER, + PlanMessageStream: tableacl.WRITER, + PlanSelectImpossible: tableacl.READER, } //_______________________________________________ diff --git a/go/vt/vttablet/tabletserver/query_executor.go b/go/vt/vttablet/tabletserver/query_executor.go index 28b9c42eeec..6e8747e952c 100644 --- a/go/vt/vttablet/tabletserver/query_executor.go +++ b/go/vt/vttablet/tabletserver/query_executor.go @@ -106,6 +106,17 @@ func (qre *QueryExecutor) Execute() (reply *sqltypes.Result, err error) { return qre.execDDL() case planbuilder.PlanNextval: return qre.execNextval() + case planbuilder.PlanSelectImpossible: + if qre.plan.Fields != nil { + return &sqltypes.Result{ + Fields: qre.plan.Fields, + RowsAffected: 0, + InsertID: 0, + Rows: nil, + Extras: nil, + }, nil + } + break } if qre.transactionID != 0 { @@ -137,7 +148,7 @@ func (qre *QueryExecutor) Execute() (reply *sqltypes.Result, err error) { return qre.execUpsertPK(conn) case planbuilder.PlanSet: return qre.txFetch(conn, qre.plan.FullQuery, qre.bindVars, nil, nil, true, true) - case planbuilder.PlanPassSelect, planbuilder.PlanSelectLock: + case planbuilder.PlanPassSelect, planbuilder.PlanSelectLock, planbuilder.PlanSelectImpossible: return qre.execDirect(conn) default: // handled above: @@ -151,7 +162,7 @@ func (qre *QueryExecutor) Execute() (reply *sqltypes.Result, err error) { } } else { switch qre.plan.PlanID { - case planbuilder.PlanPassSelect: + case planbuilder.PlanPassSelect, planbuilder.PlanSelectImpossible: return qre.execSelect() case planbuilder.PlanSelectLock: return nil, vterrors.Errorf(vtrpcpb.Code_FAILED_PRECONDITION, "%s disallowed outside transaction", qre.plan.PlanID.String()) diff --git a/go/vt/vttablet/tabletserver/query_executor_test.go b/go/vt/vttablet/tabletserver/query_executor_test.go index 84ff6fd6016..334c026a28b 100644 --- a/go/vt/vttablet/tabletserver/query_executor_test.go +++ b/go/vt/vttablet/tabletserver/query_executor_test.go @@ -1242,6 +1242,31 @@ func TestQueryExecutorPlanPassSelect(t *testing.T) { } } +func TestQueryExecutorPlanSelectImpossible(t *testing.T) { + db := setUpQueryExecutorTest(t) + defer db.Close() + query := "select * from test_table where 1 != 1" + want := &sqltypes.Result{ + Fields: getTestTableFields(), + } + db.AddQuery(query, want) + db.AddQuery("select * from test_table where 1 != 1", &sqltypes.Result{ + Fields: getTestTableFields(), + }) + ctx := context.Background() + tsv := newTestTabletServer(ctx, noFlags, db) + qre := newTestQueryExecutor(ctx, tsv, query, 0) + defer tsv.StopService() + checkPlanID(t, planbuilder.PlanSelectImpossible, qre.plan.PlanID) + got, err := qre.Execute() + if err != nil { + t.Fatalf("qre.Execute() = %v, want nil", err) + } + if !reflect.DeepEqual(got, want) { + t.Fatalf("got: %v, want: %v", got, want) + } +} + func TestQueryExecutorPlanPassSelectSqlSelectLimit(t *testing.T) { db := setUpQueryExecutorTest(t) defer db.Close() @@ -1732,7 +1757,7 @@ func TestQueryExecutorTableAclDualTableExempt(t *testing.T) { query := "select * from test_table where 1 != 1" qre := newTestQueryExecutor(ctx, tsv, query, 0) defer tsv.StopService() - checkPlanID(t, planbuilder.PlanPassSelect, qre.plan.PlanID) + checkPlanID(t, planbuilder.PlanSelectImpossible, qre.plan.PlanID) // query should fail because nobody has read access to test_table _, err := qre.Execute() if code := vterrors.Code(err); code != vtrpcpb.Code_PERMISSION_DENIED { From fdd5e9ba644712fd7789f478b365db79046dba9b Mon Sep 17 00:00:00 2001 From: Dan Kozlowski Date: Thu, 24 Jan 2019 22:14:39 -0800 Subject: [PATCH 087/115] Adding a reset of the slave on blank restore In the event we are restoring from a backup, but there is no backup we need to reset master to accomidate flavors that write to the binlog on startup ( I'm looking at you MariaDB ) Signed-off-by: Dan Kozlowski --- go/vt/mysqlctl/backup.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/go/vt/mysqlctl/backup.go b/go/vt/mysqlctl/backup.go index ccecaee9431..92671803a58 100644 --- a/go/vt/mysqlctl/backup.go +++ b/go/vt/mysqlctl/backup.go @@ -820,6 +820,12 @@ func Restore( 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) + // Since this Was 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) + err = ErrNoBackup + } + if err = PopulateMetadataTables(mysqld, localMetadata); err == nil { err = ErrNoBackup } From 11177847cfb7ee2fe74f99c3ee4b10deef08e15a Mon Sep 17 00:00:00 2001 From: Andres Taylor Date: Tue, 22 Jan 2019 16:31:20 +0100 Subject: [PATCH 088/115] Make SplitClone work with consistent snapshot Signed-off-by: Andres Taylor --- go/cmd/vtworkerclient/vtworkerclient.go | 2 +- go/vt/worker/restartable_result_reader.go | 61 +- go/vt/worker/result_merger.go | 10 + go/vt/worker/result_merger_test.go | 9 + go/vt/worker/result_reader.go | 3 + go/vt/worker/split_clone.go | 750 +++++++++++++--------- go/vt/worker/split_clone_cmd.go | 52 +- go/vt/worker/split_clone_test.go | 2 +- go/vt/worker/vertical_split_clone_cmd.go | 20 +- 9 files changed, 595 insertions(+), 314 deletions(-) diff --git a/go/cmd/vtworkerclient/vtworkerclient.go b/go/cmd/vtworkerclient/vtworkerclient.go index 0e1874453ba..997da727657 100644 --- a/go/cmd/vtworkerclient/vtworkerclient.go +++ b/go/cmd/vtworkerclient/vtworkerclient.go @@ -55,7 +55,7 @@ func main() { logutil.LogEvent(logger, e) }) if err != nil { - log.Error(err) + log.Errorf("%+v", err) os.Exit(1) } } diff --git a/go/vt/worker/restartable_result_reader.go b/go/vt/worker/restartable_result_reader.go index 73fadf04145..84649be867d 100644 --- a/go/vt/worker/restartable_result_reader.go +++ b/go/vt/worker/restartable_result_reader.go @@ -23,6 +23,8 @@ import ( "strings" "time" + "github.com/golang/glog" + "vitess.io/vitess/go/vt/vterrors" "golang.org/x/net/context" @@ -53,6 +55,8 @@ type RestartableResultReader struct { chunk chunk // allowMultipleRetries is true if we are allowed to retry more than once. allowMultipleRetries bool + // if we are running inside a transaction, this will hold a non-zero value + txID int64 query string @@ -82,6 +86,15 @@ func NewRestartableResultReader(ctx context.Context, logger logutil.Logger, tp t allowMultipleRetries: allowMultipleRetries, } + err := tryToConnect(r) + if err != nil { + return nil, err + } + return r, nil +} + +func tryToConnect(r *RestartableResultReader) error { + // If the initial connection fails we retry once. // Note: The first retry will be the second attempt. attempt := 0 @@ -97,15 +110,35 @@ func NewRestartableResultReader(ctx context.Context, logger logutil.Logger, tp t err = fmt.Errorf("tablet=%v: %v", topoproto.TabletAliasString(r.tablet.Alias), err) goto retry } - return r, nil + return nil retry: if !retryable || attempt > 1 { - return nil, fmt.Errorf("failed to initialize tablet connection: retryable %v, %v", retryable, err) + return fmt.Errorf("failed to initialize tablet connection: retryable %v, %v", retryable, err) } statsRetryCount.Add(1) - logger.Infof("retrying after error: %v", err) + glog.Infof("retrying after error: %v", err) + } + +} + +// NewTransactionalRestartableResultReader does the same thing that NewRestartableResultReader does, +// but works inside of a single transaction +func NewTransactionalRestartableResultReader(ctx context.Context, logger logutil.Logger, tp tabletProvider, td *tabletmanagerdatapb.TableDefinition, chunk chunk, allowMultipleRetries bool, txID int64) (*RestartableResultReader, error) { + r := &RestartableResultReader{ + ctx: ctx, + logger: logger, + tp: tp, + td: td, + chunk: chunk, + allowMultipleRetries: allowMultipleRetries, + txID: txID, } + err := tryToConnect(r) + if err != nil { + return nil, err + } + return r, nil } // getTablet (re)sets the tablet which is used for the streaming query. @@ -145,11 +178,21 @@ func (r *RestartableResultReader) getTablet() (bool, error) { func (r *RestartableResultReader) startStream() (bool, error) { // Start the streaming query. r.generateQuery() - stream := queryservice.ExecuteWithStreamer(r.ctx, r.conn, &querypb.Target{ - Keyspace: r.tablet.Keyspace, - Shard: r.tablet.Shard, - TabletType: r.tablet.Type, - }, r.query, make(map[string]*querypb.BindVariable), nil) + var stream sqltypes.ResultStream + + if r.txID == 0 { + stream = queryservice.ExecuteWithStreamer(r.ctx, r.conn, &querypb.Target{ + Keyspace: r.tablet.Keyspace, + Shard: r.tablet.Shard, + TabletType: r.tablet.Type, + }, r.query, make(map[string]*querypb.BindVariable), nil) + } else { + stream = queryservice.ExecuteWithTransactionalStreamer(r.ctx, r.conn, &querypb.Target{ + Keyspace: r.tablet.Keyspace, + Shard: r.tablet.Shard, + TabletType: r.tablet.Type, + }, r.query, make(map[string]*querypb.BindVariable), r.txID, nil) + } // Read the fields information. cols, err := stream.Recv() @@ -387,4 +430,4 @@ func greaterThanTupleWhereClause(columns []string, row []sqltypes.Value) []strin clauses = append(clauses, b.String()) return clauses -} +} \ No newline at end of file diff --git a/go/vt/worker/result_merger.go b/go/vt/worker/result_merger.go index 68250d06ad0..87213242b94 100644 --- a/go/vt/worker/result_merger.go +++ b/go/vt/worker/result_merger.go @@ -21,6 +21,7 @@ import ( "fmt" "io" + "golang.org/x/net/context" "vitess.io/vitess/go/vt/vterrors" "github.com/golang/protobuf/proto" @@ -177,6 +178,15 @@ func (rm *ResultMerger) Next() (*sqltypes.Result, error) { return result, nil } +// Close closes all inputs +func (rm *ResultMerger) Close(ctx context.Context) { + for _, i := range rm.inputs { + i.Close(ctx) + } +} + + + func (rm *ResultMerger) deleteInput(deleteMe ResultReader) { for i, input := range rm.inputs { if input == deleteMe { diff --git a/go/vt/worker/result_merger_test.go b/go/vt/worker/result_merger_test.go index 10b37f3261f..66bfa65eddf 100644 --- a/go/vt/worker/result_merger_test.go +++ b/go/vt/worker/result_merger_test.go @@ -23,6 +23,7 @@ import ( "testing" "time" + "golang.org/x/net/context" "vitess.io/vitess/go/sqltypes" querypb "vitess.io/vitess/go/vt/proto/query" @@ -110,6 +111,10 @@ func (f *fakeResultReader) Fields() []*querypb.Field { return f.fields } +// Close closes nothing +func (f *fakeResultReader) Close(ctx context.Context) { +} + // Next returns the next fake result. It is part of the ResultReader interface. func (f *fakeResultReader) Next() (*sqltypes.Result, error) { if f.rowsReturned == f.rowsTotal { @@ -387,6 +392,10 @@ func (m *memoryResultReader) Next() (*sqltypes.Result, error) { return result, nil } +func (m *memoryResultReader) Close(ctx context.Context) { + // intentionally blank. we have nothing we need to close +} + // benchmarkResult is a package level variable whose sole purpose is to // reference output from the Benchmark* functions below. // This was suggested by http://dave.cheney.net/2013/06/30/how-to-write-benchmarks-in-go diff --git a/go/vt/worker/result_reader.go b/go/vt/worker/result_reader.go index 51ccda42367..efc0fc1f7bb 100644 --- a/go/vt/worker/result_reader.go +++ b/go/vt/worker/result_reader.go @@ -17,6 +17,8 @@ limitations under the License. package worker import ( + "context" + "vitess.io/vitess/go/sqltypes" querypb "vitess.io/vitess/go/vt/proto/query" @@ -39,4 +41,5 @@ type ResultReader interface { // It returns the next result on the stream. // It will return io.EOF if the stream ended. Next() (*sqltypes.Result, error) + Close(ctx context.Context) } diff --git a/go/vt/worker/split_clone.go b/go/vt/worker/split_clone.go index 3cc7638d4a1..8eb5fefa2b6 100644 --- a/go/vt/worker/split_clone.go +++ b/go/vt/worker/split_clone.go @@ -24,14 +24,16 @@ import ( "sync" "time" + "vitess.io/vitess/go/vt/vttablet/tabletconn" + + "vitess.io/vitess/go/vt/binlog/binlogplayer" + "vitess.io/vitess/go/vt/vterrors" "golang.org/x/net/context" "vitess.io/vitess/go/event" "vitess.io/vitess/go/stats" - "vitess.io/vitess/go/sync2" - "vitess.io/vitess/go/vt/binlog/binlogplayer" "vitess.io/vitess/go/vt/concurrency" "vitess.io/vitess/go/vt/discovery" "vitess.io/vitess/go/vt/throttler" @@ -64,28 +66,30 @@ var servingTypes = []topodatapb.TabletType{topodatapb.TabletType_MASTER, topodat type SplitCloneWorker struct { StatusWorker - wr *wrangler.Wrangler - cloneType cloneType - cell string - destinationKeyspace string - shard string - online bool - offline bool + wr *wrangler.Wrangler + cloneType cloneType + cell string + destinationKeyspace string + shard string + online bool + offline bool + useConsistentSnapshot bool // verticalSplit only: List of tables which should be split out. tables []string // horizontalResharding only: List of tables which will be skipped. - excludeTables []string - chunkCount int - minRowsPerChunk int - sourceReaderCount int - writeQueryMaxRows int - writeQueryMaxSize int - destinationWriterCount int - minHealthyRdonlyTablets int - maxTPS int64 - maxReplicationLag int64 - cleaner *wrangler.Cleaner - tabletTracker *TabletTracker + excludeTables []string + chunkCount int + minRowsPerChunk int + sourceReaderCount int + writeQueryMaxRows int + writeQueryMaxSize int + destinationWriterCount int + minHealthyTablets int + tabletType topodatapb.TabletType + maxTPS int64 + maxReplicationLag int64 + cleaner *wrangler.Cleaner + tabletTracker *TabletTracker // populated during WorkerStateInit, read-only after that destinationKeyspaceInfo *topo.KeyspaceInfo @@ -101,6 +105,9 @@ type SplitCloneWorker struct { // populated during WorkerStateFindTargets, read-only after that sourceTablets []*topodatapb.Tablet + lastPos string // contains the GTID position for the source + transactions []int64 + // shardWatchers contains a TopologyWatcher for each source and destination // shard. It updates the list of tablets in the healthcheck if replicas are // added/removed. @@ -118,15 +125,15 @@ type SplitCloneWorker struct { // Throttlers will be added/removed during WorkerStateClone(Online|Offline). throttlers map[string]*throttler.Throttler - // offlineSourceAliases has the list of tablets (per source shard) we took + // sourceAliases has the list of tablets (per source shard) we took // offline for the WorkerStateCloneOffline phase. // Populated shortly before WorkerStateCloneOffline, read-only after that. - offlineSourceAliases []*topodatapb.TabletAlias + sourceAliases []*topodatapb.TabletAlias // formattedOfflineSourcesMu guards all fields in this group. formattedOfflineSourcesMu sync.Mutex // formattedOfflineSources is a space separated list of - // "offlineSourceAliases". It is used by the StatusAs* methods to output the + // "sourceAliases". It is used by the StatusAs* methods to output the // used source tablets during the offline clone phase. formattedOfflineSources string @@ -140,20 +147,20 @@ type SplitCloneWorker struct { } // newSplitCloneWorker returns a new worker object for the SplitClone command. -func newSplitCloneWorker(wr *wrangler.Wrangler, cell, keyspace, shard string, online, offline bool, excludeTables []string, chunkCount, minRowsPerChunk, sourceReaderCount, writeQueryMaxRows, writeQueryMaxSize, destinationWriterCount, minHealthyRdonlyTablets int, maxTPS, maxReplicationLag int64) (Worker, error) { - return newCloneWorker(wr, horizontalResharding, cell, keyspace, shard, online, offline, nil /* tables */, excludeTables, chunkCount, minRowsPerChunk, sourceReaderCount, writeQueryMaxRows, writeQueryMaxSize, destinationWriterCount, minHealthyRdonlyTablets, maxTPS, maxReplicationLag) +func newSplitCloneWorker(wr *wrangler.Wrangler, cell, keyspace, shard string, online, offline bool, excludeTables []string, chunkCount, minRowsPerChunk, sourceReaderCount, writeQueryMaxRows, writeQueryMaxSize, destinationWriterCount, minHealthyTablets int, tabletType topodatapb.TabletType, maxTPS, maxReplicationLag int64, useConsistentSnapshot bool) (Worker, error) { + return newCloneWorker(wr, horizontalResharding, cell, keyspace, shard, online, offline, nil /* tables */, excludeTables, chunkCount, minRowsPerChunk, sourceReaderCount, writeQueryMaxRows, writeQueryMaxSize, destinationWriterCount, minHealthyTablets, tabletType, maxTPS, maxReplicationLag, useConsistentSnapshot) } // newVerticalSplitCloneWorker returns a new worker object for the // VerticalSplitClone command. -func newVerticalSplitCloneWorker(wr *wrangler.Wrangler, cell, keyspace, shard string, online, offline bool, tables []string, chunkCount, minRowsPerChunk, sourceReaderCount, writeQueryMaxRows, writeQueryMaxSize, destinationWriterCount, minHealthyRdonlyTablets int, maxTPS, maxReplicationLag int64) (Worker, error) { - return newCloneWorker(wr, verticalSplit, cell, keyspace, shard, online, offline, tables, nil /* excludeTables */, chunkCount, minRowsPerChunk, sourceReaderCount, writeQueryMaxRows, writeQueryMaxSize, destinationWriterCount, minHealthyRdonlyTablets, maxTPS, maxReplicationLag) +func newVerticalSplitCloneWorker(wr *wrangler.Wrangler, cell, keyspace, shard string, online, offline bool, tables []string, chunkCount, minRowsPerChunk, sourceReaderCount, writeQueryMaxRows, writeQueryMaxSize, destinationWriterCount, minHealthyTablets int, tabletType topodatapb.TabletType, maxTPS, maxReplicationLag int64, useConsistentSnapshot bool) (Worker, error) { + return newCloneWorker(wr, verticalSplit, cell, keyspace, shard, online, offline, tables, nil /* excludeTables */, chunkCount, minRowsPerChunk, sourceReaderCount, writeQueryMaxRows, writeQueryMaxSize, destinationWriterCount, minHealthyTablets, tabletType, maxTPS, maxReplicationLag, useConsistentSnapshot) } // newCloneWorker returns a new SplitCloneWorker object which is used both by // the SplitClone and VerticalSplitClone command. // TODO(mberlin): Rename SplitCloneWorker to cloneWorker. -func newCloneWorker(wr *wrangler.Wrangler, cloneType cloneType, cell, keyspace, shard string, online, offline bool, tables, excludeTables []string, chunkCount, minRowsPerChunk, sourceReaderCount, writeQueryMaxRows, writeQueryMaxSize, destinationWriterCount, minHealthyRdonlyTablets int, maxTPS, maxReplicationLag int64) (Worker, error) { +func newCloneWorker(wr *wrangler.Wrangler, cloneType cloneType, cell, keyspace, shard string, online, offline bool, tables, excludeTables []string, chunkCount, minRowsPerChunk, sourceReaderCount, writeQueryMaxRows, writeQueryMaxSize, destinationWriterCount, minHealthyTablets int, tabletType topodatapb.TabletType, maxTPS, maxReplicationLag int64, useConsistentSnapshot bool) (Worker, error) { if cloneType != horizontalResharding && cloneType != verticalSplit { return nil, fmt.Errorf("unknown cloneType: %v This is a bug. Please report", cloneType) } @@ -183,8 +190,8 @@ func newCloneWorker(wr *wrangler.Wrangler, cloneType cloneType, cell, keyspace, if destinationWriterCount <= 0 { return nil, fmt.Errorf("destination_writer_count must be > 0: %v", destinationWriterCount) } - if minHealthyRdonlyTablets < 0 { - return nil, fmt.Errorf("min_healthy_rdonly_tablets must be >= 0: %v", minHealthyRdonlyTablets) + if minHealthyTablets < 0 { + return nil, fmt.Errorf("min_healthy_tablets must be >= 0: %v", minHealthyTablets) } if maxTPS != throttler.MaxRateModuleDisabled { wr.Logger().Infof("throttling enabled and set to a max of %v transactions/second", maxTPS) @@ -195,35 +202,39 @@ func newCloneWorker(wr *wrangler.Wrangler, cloneType cloneType, cell, keyspace, if maxReplicationLag <= 0 { return nil, fmt.Errorf("max_replication_lag must be >= 1s: %v", maxReplicationLag) } + if tabletType != topodatapb.TabletType_REPLICA && tabletType != topodatapb.TabletType_RDONLY { + return nil, fmt.Errorf("tablet_type must be RDONLY or REPLICA: %v", topodatapb.TabletType_name[int32(tabletType)]) + } scw := &SplitCloneWorker{ - StatusWorker: NewStatusWorker(), - wr: wr, - cloneType: cloneType, - cell: cell, - destinationKeyspace: keyspace, - shard: shard, - online: online, - offline: offline, - tables: tables, - excludeTables: excludeTables, - chunkCount: chunkCount, - minRowsPerChunk: minRowsPerChunk, - sourceReaderCount: sourceReaderCount, - writeQueryMaxRows: writeQueryMaxRows, - writeQueryMaxSize: writeQueryMaxSize, - destinationWriterCount: destinationWriterCount, - minHealthyRdonlyTablets: minHealthyRdonlyTablets, - maxTPS: maxTPS, - maxReplicationLag: maxReplicationLag, - cleaner: &wrangler.Cleaner{}, - tabletTracker: NewTabletTracker(), - throttlers: make(map[string]*throttler.Throttler), - - destinationDbNames: make(map[string]string), - + StatusWorker: NewStatusWorker(), + wr: wr, + cloneType: cloneType, + cell: cell, + destinationKeyspace: keyspace, + shard: shard, + online: online, + offline: offline, + tables: tables, + excludeTables: excludeTables, + chunkCount: chunkCount, + minRowsPerChunk: minRowsPerChunk, + sourceReaderCount: sourceReaderCount, + writeQueryMaxRows: writeQueryMaxRows, + writeQueryMaxSize: writeQueryMaxSize, + destinationWriterCount: destinationWriterCount, + minHealthyTablets: minHealthyTablets, + maxTPS: maxTPS, + maxReplicationLag: maxReplicationLag, + cleaner: &wrangler.Cleaner{}, + tabletTracker: NewTabletTracker(), + tabletType: tabletType, tableStatusListOnline: &tableStatusList{}, tableStatusListOffline: &tableStatusList{}, + useConsistentSnapshot: useConsistentSnapshot, + + throttlers: make(map[string]*throttler.Throttler), + destinationDbNames: make(map[string]string), } scw.initializeEventDescriptor() return scw, nil @@ -424,6 +435,29 @@ func (scw *SplitCloneWorker) Run(ctx context.Context) error { return nil } +func (scw *SplitCloneWorker) disableUniquenessCheckOnDestinationTablets(ctx context.Context) error { + for _, si := range scw.destinationShards { + tablets := scw.tsc.GetHealthyTabletStats(si.Keyspace(), si.ShardName(), topodatapb.TabletType_MASTER) + if len(tablets) != 1 { + return fmt.Errorf("should have exactly one MASTER tablet, have %v", len(tablets)) + } + tablet := tablets[0].Tablet + cmd := "SET UNIQUE_CHECKS=0" + scw.wr.Logger().Infof("disabling uniqueness checks on %v", topoproto.TabletAliasString(tablet.Alias)) + _, err := scw.wr.TabletManagerClient().ExecuteFetchAsApp(ctx, tablet, true, []byte(cmd), 0) + if err != nil { + return fmt.Errorf("should have exactly one MASTER tablet, have %v", len(tablets)) + } + scw.cleaner.Record("EnableUniquenessChecks", topoproto.TabletAliasString(tablet.Alias), func(ctx context.Context, wr *wrangler.Wrangler) error { + cmd := "SET UNIQUE_CHECKS=1" + _, err := scw.wr.TabletManagerClient().ExecuteFetchAsApp(ctx, tablet, true, []byte(cmd), 0) + return err + }) + } + + return nil +} + func (scw *SplitCloneWorker) run(ctx context.Context) error { // Phase 1: read what we need to do. if err := scw.init(ctx); err != nil { @@ -476,9 +510,15 @@ func (scw *SplitCloneWorker) run(ctx context.Context) error { time.Sleep(1 * time.Second) } - // 4a: Take source tablets out of serving for an exact snapshot. - if err := scw.findOfflineSourceTablets(ctx); err != nil { - return vterrors.Wrap(err, "findSourceTablets() failed") + // 4a: Make sure the sources are producing a stable view of the data + if scw.useConsistentSnapshot { + if err := scw.findTransactionalSources(ctx); err != nil { + return vterrors.Wrap(err, "findSourceTablets() failed") + } + } else { + if err := scw.findOfflineSourceTablets(ctx); err != nil { + return vterrors.Wrap(err, "findSourceTablets() failed") + } } if err := checkDone(ctx); err != nil { return err @@ -489,6 +529,10 @@ func (scw *SplitCloneWorker) run(ctx context.Context) error { if err := scw.clone(ctx, WorkerStateCloneOffline); err != nil { return vterrors.Wrap(err, "offline clone() failed") } + if err := scw.setUpVReplication(ctx); err != nil { + return fmt.Errorf("failed to set up replication: %v", err) + } + d := time.Since(start) if err := checkDone(ctx); err != nil { return err @@ -583,6 +627,10 @@ func (scw *SplitCloneWorker) initShardsForHorizontalResharding(ctx context.Conte scw.destinationShards = os.Left } + if scw.useConsistentSnapshot && len(scw.sourceShards) > 1 { + return fmt.Errorf("cannot use consistent snapshot against multiple source shards") + } + return nil } @@ -705,20 +753,20 @@ func (scw *SplitCloneWorker) findOfflineSourceTablets(ctx context.Context) error scw.setState(WorkerStateFindTargets) // find an appropriate tablet in the source shards - scw.offlineSourceAliases = make([]*topodatapb.TabletAlias, len(scw.sourceShards)) + scw.sourceAliases = make([]*topodatapb.TabletAlias, len(scw.sourceShards)) for i, si := range scw.sourceShards { var err error - scw.offlineSourceAliases[i], err = FindWorkerTablet(ctx, scw.wr, scw.cleaner, scw.tsc, scw.cell, si.Keyspace(), si.ShardName(), scw.minHealthyRdonlyTablets, topodatapb.TabletType_RDONLY) + scw.sourceAliases[i], err = FindWorkerTablet(ctx, scw.wr, scw.cleaner, scw.tsc, scw.cell, si.Keyspace(), si.ShardName(), scw.minHealthyTablets, scw.tabletType) if err != nil { return vterrors.Wrapf(err, "FindWorkerTablet() failed for %v/%v/%v", scw.cell, si.Keyspace(), si.ShardName()) } - scw.wr.Logger().Infof("Using tablet %v as source for %v/%v", topoproto.TabletAliasString(scw.offlineSourceAliases[i]), si.Keyspace(), si.ShardName()) + scw.wr.Logger().Infof("Using tablet %v as source for %v/%v", topoproto.TabletAliasString(scw.sourceAliases[i]), si.Keyspace(), si.ShardName()) } - scw.setFormattedOfflineSources(scw.offlineSourceAliases) + scw.setFormattedOfflineSources(scw.sourceAliases) // get the tablet info for them, and stop their replication - scw.sourceTablets = make([]*topodatapb.Tablet, len(scw.offlineSourceAliases)) - for i, alias := range scw.offlineSourceAliases { + scw.sourceTablets = make([]*topodatapb.Tablet, len(scw.sourceAliases)) + for i, alias := range scw.sourceAliases { shortCtx, cancel := context.WithTimeout(ctx, *remoteActionsTimeout) ti, err := scw.wr.TopoServer().GetTablet(shortCtx, alias) cancel() @@ -740,6 +788,44 @@ func (scw *SplitCloneWorker) findOfflineSourceTablets(ctx context.Context) error return nil } +// findTransactionalSources phase: +// - get the aliases of all the source tablets +func (scw *SplitCloneWorker) findTransactionalSources(ctx context.Context) error { + scw.setState(WorkerStateFindTargets) + + if len(scw.sourceShards) > 1 { + return fmt.Errorf("consistent snapshot can only be used with a single source shard") + } + var err error + + // find an appropriate tablet in the source shard + si := scw.sourceShards[0] + scw.sourceAliases = make([]*topodatapb.TabletAlias, 1) + scw.sourceAliases[0], err = FindHealthyTablet(ctx, scw.wr, scw.tsc, scw.cell, si.Keyspace(), si.ShardName(), scw.minHealthyTablets, scw.tabletType) + if err != nil { + return fmt.Errorf("FindHealthyTablet() failed for %v/%v/%v: %v", scw.cell, si.Keyspace(), si.ShardName(), err) + } + scw.wr.Logger().Infof("Using tablet %v as source for %v/%v", topoproto.TabletAliasString(scw.sourceAliases[0]), si.Keyspace(), si.ShardName()) + scw.setFormattedOfflineSources(scw.sourceAliases) + + // get the tablet info + scw.sourceTablets = make([]*topodatapb.Tablet, 1) + shortCtx, cancel := context.WithTimeout(ctx, *remoteActionsTimeout) + ti, err := scw.wr.TopoServer().GetTablet(shortCtx, scw.sourceAliases[0]) + cancel() + if err != nil { + return fmt.Errorf("cannot read tablet %v: %v", topoproto.TabletAliasString(scw.sourceAliases[0]), err) + } + scw.sourceTablets[0] = ti.Tablet + + // stop replication and create transactions to work on + txs, gtid, err := CreateConsistentTransactions(ctx, ti, scw.wr, scw.cleaner, scw.sourceReaderCount) + scw.wr.Logger().Infof("created %v transactions", len(txs)) + scw.lastPos = gtid + scw.transactions = txs + return nil +} + // findDestinationMasters finds for each destination shard the current master. func (scw *SplitCloneWorker) findDestinationMasters(ctx context.Context) error { scw.setState(WorkerStateFindTargets) @@ -748,8 +834,9 @@ 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) - defer waitCancel() - if err := scw.tsc.WaitForTablets(waitCtx, scw.cell, si.Keyspace(), si.ShardName(), topodatapb.TabletType_MASTER); err != nil { + err := scw.tsc.WaitForTablets(waitCtx, scw.cell, 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) } masters := scw.tsc.GetHealthyTabletStats(si.Keyspace(), si.ShardName(), topodatapb.TabletType_MASTER) @@ -775,18 +862,18 @@ func (scw *SplitCloneWorker) waitForTablets(ctx context.Context, shardInfos []*t var wg sync.WaitGroup rec := concurrency.AllErrorRecorder{} - if scw.minHealthyRdonlyTablets > 0 && len(shardInfos) > 0 { - scw.wr.Logger().Infof("Waiting %v for %d %s/%s RDONLY tablet(s)", timeout, scw.minHealthyRdonlyTablets, shardInfos[0].Keyspace(), shardInfos[0].ShardName()) + if scw.minHealthyTablets > 0 && len(shardInfos) > 0 { + scw.wr.Logger().Infof("Waiting %v for %d %s/%s RDONLY tablet(s)", timeout, scw.minHealthyTablets, shardInfos[0].Keyspace(), shardInfos[0].ShardName()) } for _, si := range shardInfos { wg.Add(1) go func(keyspace, shard string) { defer wg.Done() - // We wait for --min_healthy_rdonly_tablets because we will use several + // We wait for --min_healthy_tablets because we will use several // tablets per shard to spread reading the chunks of rows across as many // tablets as possible. - if _, err := waitForHealthyTablets(ctx, scw.wr, scw.tsc, scw.cell, keyspace, shard, scw.minHealthyRdonlyTablets, timeout, topodatapb.TabletType_RDONLY); err != nil { + if _, err := waitForHealthyTablets(ctx, scw.wr, scw.tsc, scw.cell, keyspace, shard, scw.minHealthyTablets, timeout, scw.tabletType); err != nil { rec.RecordError(err) } }(si.Keyspace(), si.ShardName()) @@ -795,6 +882,228 @@ func (scw *SplitCloneWorker) waitForTablets(ctx context.Context, shardInfos []*t return rec.Error() } +func (scw *SplitCloneWorker) findFirstSourceTablet(ctx context.Context, state StatusWorkerState) (*topodatapb.Tablet, error) { + if state == WorkerStateCloneOffline { + // Use the first source tablet which we took offline. + return scw.sourceTablets[0], nil + } + + // Pick any healthy serving source tablet. + si := scw.sourceShards[0] + tablets := scw.tsc.GetHealthyTabletStats(si.Keyspace(), si.ShardName(), scw.tabletType) + if len(tablets) == 0 { + // We fail fast on this problem and don't retry because at the start all tablets should be healthy. + return nil, fmt.Errorf("no healthy %v tablet in source shard (%v) available (required to find out the schema)", topodatapb.TabletType_name[int32(scw.tabletType)], topoproto.KeyspaceShardString(si.Keyspace(), si.ShardName())) + } + return tablets[0].Tablet, nil +} + +func (scw *SplitCloneWorker) getCounters(state StatusWorkerState) ([]*stats.CountersWithSingleLabel, *tableStatusList) { + switch state { + case WorkerStateCloneOnline: + return []*stats.CountersWithSingleLabel{statsOnlineInsertsCounters, statsOnlineUpdatesCounters, statsOnlineDeletesCounters, statsOnlineEqualRowsCounters}, + scw.tableStatusListOnline + case WorkerStateCloneOffline: + return []*stats.CountersWithSingleLabel{statsOfflineInsertsCounters, statsOfflineUpdatesCounters, statsOfflineDeletesCounters, statsOfflineEqualRowsCounters}, + scw.tableStatusListOffline + default: + panic("should not happen") + } +} + +func (scw *SplitCloneWorker) startExecutor(ctx context.Context, wg *sync.WaitGroup, keyspace, shard string, insertChannel chan string, threadID int, processError func(string, ...interface{})) { + defer wg.Done() + t := scw.getThrottler(keyspace, shard) + //defer t.ThreadFinished(threadID) + + executor := newExecutor(scw.wr, scw.tsc, t, keyspace, shard, threadID) + if err := executor.fetchLoop(ctx, insertChannel); err != nil { + processError("executer.FetchLoop failed: %v", err) + } +} + +func mergeOrSingle(readers []ResultReader, td *tabletmanagerdatapb.TableDefinition) (ResultReader, error) { + if len(readers) == 1 { + return readers[0], nil + } + + sourceReader, err := NewResultMerger(readers, len(td.PrimaryKeyColumns)) + if err != nil { + return nil, err + } + + return sourceReader, nil +} + +func (scw *SplitCloneWorker) getSourceResultReader(ctx context.Context, td *tabletmanagerdatapb.TableDefinition, state StatusWorkerState, chunk chunk, txID int64) (ResultReader, error) { + sourceReaders := make([]ResultReader, len(scw.sourceShards)) + for shardIndex, si := range scw.sourceShards { + var sourceResultReader ResultReader + var err error + if state == WorkerStateCloneOffline && scw.useConsistentSnapshot { + if txID < 1 { + return nil, fmt.Errorf("tried using consistent snapshot without a valid transaction") + } + tp := newShardTabletProvider(scw.tsc, scw.tabletTracker, si.Keyspace(), si.ShardName(), scw.tabletType) + sourceResultReader, err = NewTransactionalRestartableResultReader(ctx, scw.wr.Logger(), tp, td, chunk, false, txID) + } else { + var tp tabletProvider + allowMultipleRetries := true + if state == WorkerStateCloneOffline { + tp = newSingleTabletProvider(ctx, scw.wr.TopoServer(), scw.sourceAliases[shardIndex]) + // allowMultipleRetries is false to avoid that we'll keep retrying + // on the same tablet alias for hours. This guards us against the + // situation that an offline tablet gets restarted and serves again. + // In that case we cannot use it because its replication is no + // longer stopped at the same point as we took it offline initially. + allowMultipleRetries = false + } else { + tp = newShardTabletProvider(scw.tsc, scw.tabletTracker, si.Keyspace(), si.ShardName(), scw.tabletType) + } + sourceResultReader, err = NewRestartableResultReader(ctx, scw.wr.Logger(), tp, td, chunk, allowMultipleRetries) + if err != nil { + return nil, fmt.Errorf("NewRestartableResultReader for source: %v failed: %v", tp.description(), err) + } + } + // TODO: We could end up in a situation where some readers have been created but not all. In this situation, we would not close up all readers + sourceReaders[shardIndex] = sourceResultReader + } + return mergeOrSingle(sourceReaders, td) +} + +func (scw *SplitCloneWorker) getDestinationResultReader(ctx context.Context, td *tabletmanagerdatapb.TableDefinition, state StatusWorkerState, chunk chunk) (ResultReader, error) { + destReaders := make([]ResultReader, len(scw.destinationShards)) + for shardIndex, si := range scw.destinationShards { + tp := newShardTabletProvider(scw.tsc, scw.tabletTracker, si.Keyspace(), si.ShardName(), topodatapb.TabletType_MASTER) + destResultReader, err := NewRestartableResultReader(ctx, scw.wr.Logger(), tp, td, chunk, true /* allowMultipleRetries */) + if err != nil { + return nil, fmt.Errorf("NewRestartableResultReader for destination: %v failed: %v", tp.description(), err) + } + destReaders[shardIndex] = destResultReader + } + return mergeOrSingle(destReaders, td) +} + +func (scw *SplitCloneWorker) cloneAChunk(ctx context.Context, td *tabletmanagerdatapb.TableDefinition, tableIndex int, chunk chunk, processError func(string, ...interface{}), state StatusWorkerState, tableStatusList *tableStatusList, keyResolver keyspaceIDResolver, start time.Time, insertChannels []chan string, txID int64, statsCounters []*stats.CountersWithSingleLabel) { + errPrefix := fmt.Sprintf("table=%v chunk=%v", td.Name, chunk) + + var err error + + if err := checkDone(ctx); err != nil { + processError("%v: Context expired while this thread was waiting for its turn. Context error: %v", errPrefix, err) + return + } + + tableStatusList.threadStarted(tableIndex) + defer tableStatusList.threadDone(tableIndex) + + if state == WorkerStateCloneOnline { + // Wait for enough healthy tablets (they might have become unhealthy + // and their replication lag might have increased since we started.) + if err := scw.waitForTablets(ctx, scw.sourceShards, *retryDuration); err != nil { + processError("%v: No healthy source tablets found (gave up after %v): %v", errPrefix, time.Since(start), err) + return + } + } + + // Set up readers for the diff. There will be one reader for every + // source and destination shard. + sourceReader, err := scw.getSourceResultReader(ctx, td, state, chunk, txID) + if err != nil { + processError("%v NewResultMerger for source tablets failed: %v", errPrefix, err) + return + } + defer sourceReader.Close(ctx) + destReader, err := scw.getDestinationResultReader(ctx, td, state, chunk) + if err != nil { + processError("%v NewResultMerger for destinations tablets failed: %v", errPrefix, err) + return + } + defer destReader.Close(ctx) + dbNames := make([]string, len(scw.destinationShards)) + for i, si := range scw.destinationShards { + keyspaceAndShard := topoproto.KeyspaceShardString(si.Keyspace(), si.ShardName()) + dbNames[i] = scw.destinationDbNames[keyspaceAndShard] + } + // Compare the data and reconcile any differences. + differ, err := NewRowDiffer2(ctx, sourceReader, destReader, td, tableStatusList, tableIndex, + scw.destinationShards, keyResolver, + insertChannels, ctx.Done(), dbNames, scw.writeQueryMaxRows, scw.writeQueryMaxSize, statsCounters) + if err != nil { + processError("%v: NewRowDiffer2 failed: %v", errPrefix, err) + return + } + // Ignore the diff report because all diffs should get reconciled. + _ /* DiffReport */, err = differ.Diff() + if err != nil { + processError("%v: RowDiffer2 failed: %v", errPrefix, err) + return + } +} + +type workUnit struct { + td *tabletmanagerdatapb.TableDefinition + chunk chunk + threadID int + resolver keyspaceIDResolver +} + +func (scw *SplitCloneWorker) startCloningData(ctx context.Context, state StatusWorkerState, sourceSchemaDefinition *tabletmanagerdatapb.SchemaDefinition, + processError func(string, ...interface{}), firstSourceTablet *topodatapb.Tablet, tableStatusList *tableStatusList, + start time.Time, statsCounters []*stats.CountersWithSingleLabel, insertChannels []chan string, wg *sync.WaitGroup) error { + + workPipeline := make(chan workUnit, 10) // We'll use a small buffer so producers do not run too far ahead of consumers + queryService, err := tabletconn.GetDialer()(firstSourceTablet, true) + if err != nil { + return fmt.Errorf("failed to create queryService: %v", err) + } + defer queryService.Close(ctx) + + // Let's start the work consumers + for i := 0; i < scw.sourceReaderCount; i++ { + var txID int64 + if scw.useConsistentSnapshot && state == WorkerStateCloneOffline { + txID = scw.transactions[i] + } else { + txID = -1 + } + + wg.Add(1) + go func() { + defer wg.Done() + for work := range workPipeline { + scw.cloneAChunk(ctx, work.td, work.threadID, work.chunk, processError, state, tableStatusList, work.resolver, start, insertChannels, txID, statsCounters) + } + }() + } + + // And now let's start producing work units + for tableIndex, td := range sourceSchemaDefinition.TableDefinitions { + td = reorderColumnsPrimaryKeyFirst(td) + + keyResolver, err := scw.createKeyResolver(td) + if err != nil { + return fmt.Errorf("cannot resolve sharding keys for keyspace %v: %v", scw.destinationKeyspace, err) + } + + // TODO(mberlin): We're going to chunk *all* source shards based on the MIN + // and MAX values of the *first* source shard. Is this going to be a problem? + chunks, err := generateChunks(ctx, scw.wr, firstSourceTablet, td, scw.chunkCount, scw.minRowsPerChunk) + if err != nil { + return fmt.Errorf("failed to split table into chunks: %v", err) + } + tableStatusList.setThreadCount(tableIndex, len(chunks)) + + for _, c := range chunks { + workPipeline <- workUnit{td: td, chunk: c, threadID: tableIndex, resolver: keyResolver} + } + } + + close(workPipeline) + + return nil +} + // copy phase: // - copy the data from source tablets to destination masters (with replication on) // Assumes that the schema has already been created on each destination tablet @@ -809,31 +1118,13 @@ func (scw *SplitCloneWorker) clone(ctx context.Context, state StatusWorkerState) statsStateDurationsNs.Set(string(state), time.Now().Sub(start).Nanoseconds()) }() - var firstSourceTablet *topodatapb.Tablet - if state == WorkerStateCloneOffline { - // Use the first source tablet which we took offline. - firstSourceTablet = scw.sourceTablets[0] - } else { - // Pick any healthy serving source tablet. - si := scw.sourceShards[0] - tablets := scw.tsc.GetHealthyTabletStats(si.Keyspace(), si.ShardName(), topodatapb.TabletType_RDONLY) - if len(tablets) == 0 { - // We fail fast on this problem and don't retry because at the start all tablets should be healthy. - return fmt.Errorf("no healthy RDONLY tablet in source shard (%v) available (required to find out the schema)", topoproto.KeyspaceShardString(si.Keyspace(), si.ShardName())) - } - firstSourceTablet = tablets[0].Tablet - } - var statsCounters []*stats.CountersWithSingleLabel - var tableStatusList *tableStatusList - switch state { - case WorkerStateCloneOnline: - statsCounters = []*stats.CountersWithSingleLabel{statsOnlineInsertsCounters, statsOnlineUpdatesCounters, statsOnlineDeletesCounters, statsOnlineEqualRowsCounters} - tableStatusList = scw.tableStatusListOnline - case WorkerStateCloneOffline: - statsCounters = []*stats.CountersWithSingleLabel{statsOfflineInsertsCounters, statsOfflineUpdatesCounters, statsOfflineDeletesCounters, statsOfflineEqualRowsCounters} - tableStatusList = scw.tableStatusListOffline + var firstSourceTablet, err = scw.findFirstSourceTablet(ctx, state) + if err != nil { + return err } + statsCounters, tableStatusList := scw.getCounters(state) + // The throttlers exist only for the duration of this clone() call. // That means a SplitClone invocation with both online and offline phases // will create throttlers for each phase. @@ -849,22 +1140,19 @@ func (scw *SplitCloneWorker) clone(ctx context.Context, state StatusWorkerState) scw.wr.Logger().Infof("Source tablet 0 has %v tables to copy", len(sourceSchemaDefinition.TableDefinitions)) tableStatusList.initialize(sourceSchemaDefinition) - // In parallel, setup the channels to send SQL data chunks to for each destination tablet: - // - // mu protects the context for cancelation, and firstError - mu := sync.Mutex{} var firstError error ctx, cancelCopy := context.WithCancel(ctx) defer cancelCopy() processError := func(format string, args ...interface{}) { - mu.Lock() + // in theory we could have two threads see firstError as null and both write to the variable + // that should not cause any problems though - canceling and logging is concurrently safe, + // and overwriting the variable will not cause any problems + scw.wr.Logger().Errorf(format, args...) if firstError == nil { - scw.wr.Logger().Errorf(format, args...) firstError = fmt.Errorf(format, args...) cancelCopy() } - mu.Unlock() } // NOTE: Code below this point must *not* use "return" to exit this Go routine @@ -877,6 +1165,7 @@ func (scw *SplitCloneWorker) clone(ctx context.Context, state StatusWorkerState) // races between "defer throttler.ThreadFinished()" (must be executed first) // and "defer scw.closeThrottlers()". Otherwise, vtworker will panic. + // In parallel, setup the channels to send SQL data chunks to for each destination tablet: insertChannels := make([]chan string, len(scw.destinationShards)) destinationWaitGroup := sync.WaitGroup{} for shardIndex, si := range scw.destinationShards { @@ -888,168 +1177,41 @@ func (scw *SplitCloneWorker) clone(ctx context.Context, state StatusWorkerState) for j := 0; j < scw.destinationWriterCount; j++ { destinationWaitGroup.Add(1) - go func(keyspace, shard string, insertChannel chan string, throttler *throttler.Throttler, threadID int) { - defer destinationWaitGroup.Done() - defer throttler.ThreadFinished(threadID) - - executor := newExecutor(scw.wr, scw.tsc, throttler, keyspace, shard, threadID) - if err := executor.fetchLoop(ctx, insertChannel); err != nil { - processError("executer.FetchLoop failed: %v", err) - } - }(si.Keyspace(), si.ShardName(), insertChannels[shardIndex], scw.getThrottler(si.Keyspace(), si.ShardName()), j) + go scw.startExecutor(ctx, &destinationWaitGroup, si.Keyspace(), si.ShardName(), insertChannels[shardIndex], j, processError) } } // Now for each table, read data chunks and send them to all // insertChannels - sourceWaitGroup := sync.WaitGroup{} - sema := sync2.NewSemaphore(scw.sourceReaderCount, 0) - for tableIndex, td := range sourceSchemaDefinition.TableDefinitions { - td = reorderColumnsPrimaryKeyFirst(td) - - keyResolver, err := scw.createKeyResolver(td) - if err != nil { - processError("cannot resolve sharding keys for keyspace %v: %v", scw.destinationKeyspace, err) - break - } - - // TODO(mberlin): We're going to chunk *all* source shards based on the MIN - // and MAX values of the *first* source shard. Is this going to be a problem? - chunks, err := generateChunks(ctx, scw.wr, firstSourceTablet, td, scw.chunkCount, scw.minRowsPerChunk) - if err != nil { - processError("failed to split table into chunks: %v", err) - break - } - tableStatusList.setThreadCount(tableIndex, len(chunks)) - - for _, c := range chunks { - sourceWaitGroup.Add(1) - go func(td *tabletmanagerdatapb.TableDefinition, tableIndex int, chunk chunk) { - defer sourceWaitGroup.Done() - errPrefix := fmt.Sprintf("table=%v chunk=%v", td.Name, chunk) - - // We need our own error per Go routine to avoid races. - var err error - - sema.Acquire() - defer sema.Release() - - if err := checkDone(ctx); err != nil { - processError("%v: Context expired while this thread was waiting for its turn. Context error: %v", errPrefix, err) - return - } - - tableStatusList.threadStarted(tableIndex) - defer tableStatusList.threadDone(tableIndex) - - if state == WorkerStateCloneOnline { - // Wait for enough healthy tablets (they might have become unhealthy - // and their replication lag might have increased since we started.) - if err := scw.waitForTablets(ctx, scw.sourceShards, *retryDuration); err != nil { - processError("%v: No healthy source tablets found (gave up after %v): %v", errPrefix, time.Since(start), err) - return - } - } - - // Set up readers for the diff. There will be one reader for every - // source and destination shard. - sourceReaders := make([]ResultReader, len(scw.sourceShards)) - destReaders := make([]ResultReader, len(scw.destinationShards)) - for shardIndex, si := range scw.sourceShards { - var tp tabletProvider - allowMultipleRetries := true - if state == WorkerStateCloneOffline { - tp = newSingleTabletProvider(ctx, scw.wr.TopoServer(), scw.offlineSourceAliases[shardIndex]) - // allowMultipleRetries is false to avoid that we'll keep retrying - // on the same tablet alias for hours. This guards us against the - // situation that an offline tablet gets restarted and serves again. - // In that case we cannot use it because its replication is no - // longer stopped at the same point as we took it offline initially. - allowMultipleRetries = false - } else { - tp = newShardTabletProvider(scw.tsc, scw.tabletTracker, si.Keyspace(), si.ShardName(), topodatapb.TabletType_RDONLY) - } - sourceResultReader, err := NewRestartableResultReader(ctx, scw.wr.Logger(), tp, td, chunk, allowMultipleRetries) - if err != nil { - processError("%v: NewRestartableResultReader for source: %v failed: %v", errPrefix, tp.description(), err) - return - } - defer sourceResultReader.Close(ctx) - sourceReaders[shardIndex] = sourceResultReader - } - - for shardIndex, si := range scw.destinationShards { - tp := newShardTabletProvider(scw.tsc, scw.tabletTracker, si.Keyspace(), si.ShardName(), topodatapb.TabletType_MASTER) - destResultReader, err := NewRestartableResultReader(ctx, scw.wr.Logger(), tp, td, chunk, true /* allowMultipleRetries */) - if err != nil { - processError("%v: NewRestartableResultReader for destination: %v failed: %v", errPrefix, tp.description(), err) - return - } - defer destResultReader.Close(ctx) - destReaders[shardIndex] = destResultReader - } - - var sourceReader ResultReader - var destReader ResultReader - if len(sourceReaders) >= 2 { - sourceReader, err = NewResultMerger(sourceReaders, len(td.PrimaryKeyColumns)) - if err != nil { - processError("%v: NewResultMerger for source tablets failed: %v", errPrefix, err) - return - } - } else { - sourceReader = sourceReaders[0] - } - if len(destReaders) >= 2 { - destReader, err = NewResultMerger(destReaders, len(td.PrimaryKeyColumns)) - if err != nil { - processError("%v: NewResultMerger for destination tablets failed: %v", errPrefix, err) - return - } - } else { - destReader = destReaders[0] - } + readers := sync.WaitGroup{} - dbNames := make([]string, len(scw.destinationShards)) - for i, si := range scw.destinationShards { - keyspaceAndShard := topoproto.KeyspaceShardString(si.Keyspace(), si.ShardName()) - dbNames[i] = scw.destinationDbNames[keyspaceAndShard] - } - // Compare the data and reconcile any differences. - differ, err := NewRowDiffer2(ctx, sourceReader, destReader, td, tableStatusList, tableIndex, - scw.destinationShards, keyResolver, - insertChannels, ctx.Done(), dbNames, scw.writeQueryMaxRows, scw.writeQueryMaxSize, statsCounters) - if err != nil { - processError("%v: NewRowDiffer2 failed: %v", errPrefix, err) - return - } - // Ignore the diff report because all diffs should get reconciled. - _ /* DiffReport */, err = differ.Diff() - if err != nil { - processError("%v: RowDiffer2 failed: %v", errPrefix, err) - return - } - }(td, tableIndex, c) - } + err = scw.startCloningData(ctx, state, sourceSchemaDefinition, processError, firstSourceTablet, tableStatusList, start, statsCounters, insertChannels, &readers) + if err != nil { + return fmt.Errorf("failed to startCloningData : %v", err) } - sourceWaitGroup.Wait() + readers.Wait() for shardIndex := range scw.destinationShards { close(insertChannels[shardIndex]) } destinationWaitGroup.Wait() - if firstError != nil { - return firstError - } - if state == WorkerStateCloneOffline { - // Create and populate the vreplication table to give filtered replication - // a starting point. - queries := make([]string, 0, 4) - queries = append(queries, binlogplayer.CreateVReplicationTable()...) + return firstError +} + +func (scw *SplitCloneWorker) setUpVReplication(ctx context.Context) error { + wg := sync.WaitGroup{} + // Create and populate the vreplication table to give filtered replication + // a starting point. + queries := make([]string, 0, 4) + queries = append(queries, binlogplayer.CreateVReplicationTable()...) - // get the current position from the sources - sourcePositions := make([]string, len(scw.sourceShards)) + // get the current position from the sources + sourcePositions := make([]string, len(scw.sourceShards)) + + if scw.useConsistentSnapshot { + sourcePositions[0] = scw.lastPos + } else { for shardIndex := range scw.sourceShards { shortCtx, cancel := context.WithTimeout(ctx, *remoteActionsTimeout) status, err := scw.wr.TabletManagerClient().SlaveStatus(shortCtx, scw.sourceTablets[shardIndex]) @@ -1059,46 +1221,60 @@ func (scw *SplitCloneWorker) clone(ctx context.Context, state StatusWorkerState) } sourcePositions[shardIndex] = status.Position } + } + cancelableCtx, cancel := context.WithCancel(ctx) + rec := concurrency.AllErrorRecorder{} + handleError := func(e error) { + rec.RecordError(e) + cancel() + } - for _, si := range scw.destinationShards { - destinationWaitGroup.Add(1) - go func(keyspace, shard string, kr *topodatapb.KeyRange) { - defer destinationWaitGroup.Done() - scw.wr.Logger().Infof("Making and populating vreplication table") - - exc := newExecutor(scw.wr, scw.tsc, nil, keyspace, shard, 0) - for shardIndex, src := range scw.sourceShards { - bls := &binlogdatapb.BinlogSource{ - Keyspace: src.Keyspace(), - Shard: src.ShardName(), - } - if scw.tables == nil { - bls.KeyRange = kr - } else { - bls.Tables = scw.tables - } - // TODO(mberlin): Fill in scw.maxReplicationLag once the adapative - // throttler is enabled by default. - qr, err := exc.vreplicationExec(ctx, binlogplayer.CreateVReplication("SplitClone", bls, sourcePositions[shardIndex], scw.maxTPS, throttler.ReplicationLagModuleDisabled, time.Now().Unix())) - if err != nil { - processError("vreplication queries failed: %v", err) - break - } - if err := scw.wr.SourceShardAdd(ctx, keyspace, shard, uint32(qr.InsertID), src.Keyspace(), src.ShardName(), src.Shard.KeyRange, scw.tables); err != nil { - processError("could not add source shard: %v", err) - break - } + for _, si := range scw.destinationShards { + wg.Add(1) + go func(keyspace, shard string, kr *topodatapb.KeyRange) { + defer wg.Done() + scw.wr.Logger().Infof("Making and populating vreplication table") + + exc := newExecutor(scw.wr, scw.tsc, nil, keyspace, shard, 0) + for shardIndex, src := range scw.sourceShards { + // Check if any error occurred in any other gorouties: + select { + case <-cancelableCtx.Done(): + return // Error somewhere, terminate + default: } - // refreshState will cause the destination to become non-serving because - // it's now participating in the resharding workflow. - if err := exc.refreshState(ctx); err != nil { - processError("RefreshState failed on tablet %v/%v: %v", keyspace, shard, err) + + bls := &binlogdatapb.BinlogSource{ + Keyspace: src.Keyspace(), + Shard: src.ShardName(), } - }(si.Keyspace(), si.ShardName(), si.KeyRange) - } - destinationWaitGroup.Wait() - } // clonePhase == offline - return firstError + if scw.tables == nil { + bls.KeyRange = kr + } else { + bls.Tables = scw.tables + } + // TODO(mberlin): Fill in scw.maxReplicationLag once the adapative throttler is enabled by default. + qr, err := exc.vreplicationExec(cancelableCtx, binlogplayer.CreateVReplication("SplitClone", bls, sourcePositions[shardIndex], scw.maxTPS, throttler.ReplicationLagModuleDisabled, time.Now().Unix())) + if err != nil { + handleError(fmt.Errorf("vreplication queries failed: %v", err)) + cancel() + return + } + if err := scw.wr.SourceShardAdd(cancelableCtx, keyspace, shard, uint32(qr.InsertID), src.Keyspace(), src.ShardName(), src.Shard.KeyRange, scw.tables); err != nil { + handleError(fmt.Errorf("could not add source shard: %v", err)) + break + } + } + // refreshState will cause the destination to become non-serving because + // it's now participating in the resharding workflow. + if err := exc.refreshState(ctx); err != nil { + handleError(fmt.Errorf("RefreshState failed on tablet %v/%v: %v", keyspace, shard, err)) + } + }(si.Keyspace(), si.ShardName(), si.KeyRange) + } + wg.Wait() + + return rec.Error() } func (scw *SplitCloneWorker) getSourceSchema(ctx context.Context, tablet *topodatapb.Tablet) (*tabletmanagerdatapb.SchemaDefinition, error) { @@ -1201,4 +1377,4 @@ func (scw *SplitCloneWorker) closeThrottlers() { t.Close() delete(scw.throttlers, keyspaceAndShard) } -} +} \ No newline at end of file diff --git a/go/vt/worker/split_clone_cmd.go b/go/vt/worker/split_clone_cmd.go index 770af7797c5..f349fb25f89 100644 --- a/go/vt/worker/split_clone_cmd.go +++ b/go/vt/worker/split_clone_cmd.go @@ -25,12 +25,13 @@ import ( "strings" "sync" - "vitess.io/vitess/go/vt/vterrors" - "golang.org/x/net/context" "vitess.io/vitess/go/vt/concurrency" + "vitess.io/vitess/go/vt/proto/topodata" + "vitess.io/vitess/go/vt/proto/vtrpc" "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" ) @@ -82,14 +83,22 @@ const splitCloneHTML2 = `

- -
+ + +
+ +


+ + ?
@@ -108,7 +117,9 @@ func commandSplitClone(wi *Instance, wr *wrangler.Wrangler, subFlags *flag.FlagS writeQueryMaxRows := subFlags.Int("write_query_max_rows", defaultWriteQueryMaxRows, "maximum number of rows per write query") writeQueryMaxSize := subFlags.Int("write_query_max_size", defaultWriteQueryMaxSize, "maximum size (in bytes) per write query") destinationWriterCount := subFlags.Int("destination_writer_count", defaultDestinationWriterCount, "number of concurrent RPCs to execute on the destination") - minHealthyRdonlyTablets := subFlags.Int("min_healthy_rdonly_tablets", defaultMinHealthyTablets, "minimum number of healthy RDONLY tablets in the source and destination shard at start") + tabletTypeStr := subFlags.String("tablet_type", "RDONLY", "tablet type to use (RDONLY or REPLICA)") + minHealthyTablets := subFlags.Int("min_healthy_rdonly_tablets", defaultMinHealthyTablets, "minimum number of healthy tablets in the source and destination shard at start") + useConsistentSnapshot := subFlags.Bool("use_consistent_snapshot", defaultUseConsistentSnapshot, "Instead of pausing replication on the source, uses transactions with consistent snapshot to have a stable view of the data.") maxTPS := subFlags.Int64("max_tps", defaultMaxTPS, "rate limit of maximum number of (write) transactions/second on the destination (unlimited by default)") maxReplicationLag := subFlags.Int64("max_replication_lag", defaultMaxReplicationLag, "if set, the adapative throttler will be enabled and automatically adjust the write rate to keep the lag below the set value in seconds (disabled by default)") if err := subFlags.Parse(args); err != nil { @@ -116,7 +127,7 @@ func commandSplitClone(wi *Instance, wr *wrangler.Wrangler, subFlags *flag.FlagS } if subFlags.NArg() != 1 { subFlags.Usage() - return nil, fmt.Errorf("command SplitClone requires ") + return nil, vterrors.New(vtrpc.Code_INVALID_ARGUMENT, "command SplitClone requires ") } keyspace, shard, err := topoproto.ParseKeyspaceShard(subFlags.Arg(0)) @@ -127,7 +138,11 @@ func commandSplitClone(wi *Instance, wr *wrangler.Wrangler, subFlags *flag.FlagS if *excludeTables != "" { excludeTableArray = strings.Split(*excludeTables, ",") } - worker, err := newSplitCloneWorker(wr, wi.cell, keyspace, shard, *online, *offline, excludeTableArray, *chunkCount, *minRowsPerChunk, *sourceReaderCount, *writeQueryMaxRows, *writeQueryMaxSize, *destinationWriterCount, *minHealthyRdonlyTablets, *maxTPS, *maxReplicationLag) + tabletType, ok := topodata.TabletType_value[*tabletTypeStr] + if !ok { + return nil, vterrors.Errorf(vtrpc.Code_INVALID_ARGUMENT, "command SplitClone invalid tablet_type: %v", tabletType) + } + worker, err := newSplitCloneWorker(wr, wi.cell, keyspace, shard, *online, *offline, excludeTableArray, *chunkCount, *minRowsPerChunk, *sourceReaderCount, *writeQueryMaxRows, *writeQueryMaxSize, *destinationWriterCount, *minHealthyTablets, topodata.TabletType(tabletType), *maxTPS, *maxReplicationLag, *useConsistentSnapshot) if err != nil { return nil, vterrors.Wrap(err, "cannot create split clone worker") } @@ -173,7 +188,7 @@ func keyspacesWithOverlappingShards(ctx context.Context, wr *wrangler.Wrangler) return nil, rec.Error() } if len(result) == 0 { - return nil, fmt.Errorf("There are no keyspaces with overlapping shards") + return nil, vterrors.Errorf(vtrpc.Code_FAILED_PRECONDITION, "there are no keyspaces with overlapping shards") } return result, nil } @@ -212,9 +227,10 @@ func interactiveSplitClone(ctx context.Context, wi *Instance, wr *wrangler.Wrang result["DefaultWriteQueryMaxRows"] = fmt.Sprintf("%v", defaultWriteQueryMaxRows) result["DefaultWriteQueryMaxSize"] = fmt.Sprintf("%v", defaultWriteQueryMaxSize) result["DefaultDestinationWriterCount"] = fmt.Sprintf("%v", defaultDestinationWriterCount) - result["DefaultMinHealthyRdonlyTablets"] = fmt.Sprintf("%v", defaultMinHealthyTablets) + result["DefaultMinHealthyTablets"] = fmt.Sprintf("%v", defaultMinHealthyTablets) result["DefaultMaxTPS"] = fmt.Sprintf("%v", defaultMaxTPS) result["DefaultMaxReplicationLag"] = fmt.Sprintf("%v", defaultMaxReplicationLag) + result["DefaultUseConsistentSnapshot"] = fmt.Sprintf("%v", defaultUseConsistentSnapshot) return nil, splitCloneTemplate2, result, nil } @@ -257,10 +273,15 @@ func interactiveSplitClone(ctx context.Context, wi *Instance, wr *wrangler.Wrang if err != nil { return nil, nil, nil, vterrors.Wrap(err, "cannot parse destinationWriterCount") } - minHealthyRdonlyTabletsStr := r.FormValue("minHealthyRdonlyTablets") - minHealthyRdonlyTablets, err := strconv.ParseInt(minHealthyRdonlyTabletsStr, 0, 64) + minHealthyTabletsStr := r.FormValue("minHealthyTablets") + minHealthyTablets, err := strconv.ParseInt(minHealthyTabletsStr, 0, 64) if err != nil { - return nil, nil, nil, vterrors.Wrap(err, "cannot parse minHealthyRdonlyTablets") + return nil, nil, nil, vterrors.Wrap(err, "cannot parse minHealthyTablets") + } + tabletTypeStr := r.FormValue("tabletType") + tabletType, ok := topodata.TabletType_value[tabletTypeStr] + if !ok { + return nil, nil, nil, vterrors.Errorf(vtrpc.Code_INVALID_ARGUMENT, "command SplitClone invalid tablet_type: %v", tabletType) } maxTPSStr := r.FormValue("maxTPS") maxTPS, err := strconv.ParseInt(maxTPSStr, 0, 64) @@ -273,8 +294,11 @@ func interactiveSplitClone(ctx context.Context, wi *Instance, wr *wrangler.Wrang return nil, nil, nil, vterrors.Wrap(err, "cannot parse maxReplicationLag") } + useConsistentSnapshotStr := r.FormValue("useConsistentSnapshot") + useConsistentSnapshot := useConsistentSnapshotStr == "true" + // start the clone job - wrk, err := newSplitCloneWorker(wr, wi.cell, keyspace, shard, online, offline, excludeTableArray, int(chunkCount), int(minRowsPerChunk), int(sourceReaderCount), int(writeQueryMaxRows), int(writeQueryMaxSize), int(destinationWriterCount), int(minHealthyRdonlyTablets), maxTPS, maxReplicationLag) + wrk, err := newSplitCloneWorker(wr, wi.cell, keyspace, shard, online, offline, excludeTableArray, int(chunkCount), int(minRowsPerChunk), int(sourceReaderCount), int(writeQueryMaxRows), int(writeQueryMaxSize), int(destinationWriterCount), int(minHealthyTablets), topodata.TabletType(tabletType), maxTPS, maxReplicationLag, useConsistentSnapshot) if err != nil { return nil, nil, nil, vterrors.Wrap(err, "cannot create worker") } @@ -286,4 +310,4 @@ func init() { commandSplitClone, interactiveSplitClone, "[--online=false] [--offline=false] [--exclude_tables=''] ", "Replicates the data and creates configuration for a horizontal split."}) -} +} \ No newline at end of file diff --git a/go/vt/worker/split_clone_test.go b/go/vt/worker/split_clone_test.go index 6e219171ed2..2d8994f11b1 100644 --- a/go/vt/worker/split_clone_test.go +++ b/go/vt/worker/split_clone_test.go @@ -522,7 +522,7 @@ func TestSplitCloneV2_Offline(t *testing.T) { // Run the vtworker command. if err := runCommand(t, tc.wi, tc.wi.wr, tc.defaultWorkerArgs); err != nil { - t.Fatal(err) + t.Fatalf("%+v", err) } } diff --git a/go/vt/worker/vertical_split_clone_cmd.go b/go/vt/worker/vertical_split_clone_cmd.go index 3d812003eac..f221ee5d677 100644 --- a/go/vt/worker/vertical_split_clone_cmd.go +++ b/go/vt/worker/vertical_split_clone_cmd.go @@ -25,6 +25,7 @@ import ( "strings" "sync" + "vitess.io/vitess/go/vt/proto/topodata" "vitess.io/vitess/go/vt/vterrors" "golang.org/x/net/context" @@ -107,6 +108,7 @@ func commandVerticalSplitClone(wi *Instance, wr *wrangler.Wrangler, subFlags *fl writeQueryMaxSize := subFlags.Int("write_query_max_size", defaultWriteQueryMaxSize, "maximum size (in bytes) per write query") destinationWriterCount := subFlags.Int("destination_writer_count", defaultDestinationWriterCount, "number of concurrent RPCs to execute on the destination") minHealthyRdonlyTablets := subFlags.Int("min_healthy_rdonly_tablets", defaultMinHealthyTablets, "minimum number of healthy RDONLY tablets before taking out one") + tabletTypeStr := subFlags.String("tablet_type", "RDONLY", "tablet type to use (RDONLY or REPLICA)") maxTPS := subFlags.Int64("max_tps", defaultMaxTPS, "if non-zero, limit copy to maximum number of (write) transactions/second on the destination (unlimited by default)") maxReplicationLag := subFlags.Int64("max_replication_lag", defaultMaxReplicationLag, "if set, the adapative throttler will be enabled and automatically adjust the write rate to keep the lag below the set value in seconds (disabled by default)") if err := subFlags.Parse(args); err != nil { @@ -127,7 +129,12 @@ func commandVerticalSplitClone(wi *Instance, wr *wrangler.Wrangler, subFlags *fl if *tables != "" { tableArray = strings.Split(*tables, ",") } - worker, err := newVerticalSplitCloneWorker(wr, wi.cell, keyspace, shard, *online, *offline, tableArray, *chunkCount, *minRowsPerChunk, *sourceReaderCount, *writeQueryMaxRows, *writeQueryMaxSize, *destinationWriterCount, *minHealthyRdonlyTablets, *maxTPS, *maxReplicationLag) + tabletType, ok := topodata.TabletType_value[*tabletTypeStr] + if !ok { + return nil, fmt.Errorf("command SplitClone invalid tablet_type: %v", tabletType) + } + + worker, err := newVerticalSplitCloneWorker(wr, wi.cell, keyspace, shard, *online, *offline, tableArray, *chunkCount, *minRowsPerChunk, *sourceReaderCount, *writeQueryMaxRows, *writeQueryMaxSize, *destinationWriterCount, *minHealthyRdonlyTablets, topodata.TabletType(tabletType), *maxTPS, *maxReplicationLag, /*useConsistentSnapshot*/false) if err != nil { return nil, vterrors.Wrap(err, "cannot create worker") } @@ -265,6 +272,12 @@ func interactiveVerticalSplitClone(ctx context.Context, wi *Instance, wr *wrangl if err != nil { return nil, nil, nil, vterrors.Wrap(err, "cannot parse maxReplicationLag") } + tabletTypeStr := r.FormValue("tabletType") + tabletType, ok := topodata.TabletType_value[tabletTypeStr] + if !ok { + return nil, nil, nil, fmt.Errorf("cannot parse tabletType: %v", tabletType) + } + // Figure out the shard shortCtx, cancel := context.WithTimeout(ctx, *remoteActionsTimeout) @@ -282,7 +295,10 @@ func interactiveVerticalSplitClone(ctx context.Context, wi *Instance, wr *wrangl } // start the clone job - wrk, err := newVerticalSplitCloneWorker(wr, wi.cell, keyspace, shard, online, offline, tableArray, int(chunkCount), int(minRowsPerChunk), int(sourceReaderCount), int(writeQueryMaxRows), int(writeQueryMaxSize), int(destinationWriterCount), int(minHealthyRdonlyTablets), maxTPS, maxReplicationLag) + wrk, err := newVerticalSplitCloneWorker(wr, wi.cell, keyspace, shard, online, offline, tableArray, int(chunkCount), + int(minRowsPerChunk), int(sourceReaderCount), int(writeQueryMaxRows), int(writeQueryMaxSize), + int(destinationWriterCount), int(minHealthyRdonlyTablets), topodata.TabletType(tabletType), maxTPS, + maxReplicationLag, false) if err != nil { return nil, nil, nil, vterrors.Wrap(err, "cannot create worker") } From 1d8fb2046208dcd25211948888f672c381e0c0a8 Mon Sep 17 00:00:00 2001 From: Andres Taylor Date: Fri, 25 Jan 2019 13:36:58 +0100 Subject: [PATCH 089/115] Close test resources Signed-off-by: Andres Taylor --- go/vt/worker/split_clone_test.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/go/vt/worker/split_clone_test.go b/go/vt/worker/split_clone_test.go index 2d8994f11b1..7e73330b273 100644 --- a/go/vt/worker/split_clone_test.go +++ b/go/vt/worker/split_clone_test.go @@ -27,7 +27,6 @@ import ( "time" "golang.org/x/net/context" - "vitess.io/vitess/go/mysql" "vitess.io/vitess/go/mysql/fakesqldb" "vitess.io/vitess/go/sqltypes" @@ -291,6 +290,11 @@ func (tc *splitCloneTestCase) tearDown() { for _, ft := range tc.tablets { ft.StopActionLoop(tc.t) + ft.RPCServer.Stop() + ft.FakeMysqlDaemon.Close() + ft.Agent = nil + ft.RPCServer = nil + ft.FakeMysqlDaemon = nil } tc.leftMasterFakeDb.VerifyAllExecutedOrFail() tc.leftReplicaFakeDb.VerifyAllExecutedOrFail() From 0eb3b4e30854a831ff9a57860552ed62b9cbb0ef Mon Sep 17 00:00:00 2001 From: Derek Perkins Date: Fri, 25 Jan 2019 11:44:09 -0700 Subject: [PATCH 090/115] mysqlctl: add backup test for rockdb and sdi files Signed-off-by: Derek Perkins --- go/vt/mysqlctl/backup_test.go | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/go/vt/mysqlctl/backup_test.go b/go/vt/mysqlctl/backup_test.go index ae08b5321c0..6fa324ae11a 100644 --- a/go/vt/mysqlctl/backup_test.go +++ b/go/vt/mysqlctl/backup_test.go @@ -39,7 +39,9 @@ func TestFindFilesToBackup(t *testing.T) { dataDbDir := path.Join(dataDir, "vt_db") extraDir := path.Join(dataDir, "extra_dir") outsideDbDir := path.Join(root, "outside_db") - for _, s := range []string{innodbDataDir, innodbLogDir, dataDbDir, extraDir, outsideDbDir} { + rocksdbDir := path.Join(dataDir, ".rocksdb") + sdiOnlyDir := path.Join(dataDir, "sdi_dir") + for _, s := range []string{innodbDataDir, innodbLogDir, dataDbDir, extraDir, outsideDbDir, rocksdbDir, sdiOnlyDir} { if err := os.MkdirAll(s, os.ModePerm); err != nil { t.Fatalf("failed to create directory %v: %v", s, err) } @@ -62,6 +64,12 @@ func TestFindFilesToBackup(t *testing.T) { if err := os.Symlink(outsideDbDir, path.Join(dataDir, "vt_symlink")); err != nil { t.Fatalf("failed to symlink vt_symlink: %v", err) } + if err := ioutil.WriteFile(path.Join(rocksdbDir, "000011.sst"), []byte("rocksdb file"), os.ModePerm); err != nil { + t.Fatalf("failed to write file 000011.sst: %v", err) + } + if err := ioutil.WriteFile(path.Join(sdiOnlyDir, "table1.sdi"), []byte("sdi file"), os.ModePerm); err != nil { + t.Fatalf("failed to write file table1.sdi: %v", err) + } cnf := &Mycnf{ InnodbDataHomeDir: innodbDataDir, @@ -76,6 +84,14 @@ func TestFindFilesToBackup(t *testing.T) { sort.Sort(forTest(result)) t.Logf("findFilesToBackup returned: %v", result) expected := []FileEntry{ + { + Base: "Data", + Name: ".rocksdb/000011.sst", + }, + { + Base: "Data", + Name: "sdi_dir/table1.sdi", + }, { Base: "Data", Name: "vt_db/db.opt", From 3d915580ceb27b5bd958aecb18cb131a6cfacd5a Mon Sep 17 00:00:00 2001 From: xichengliudui Date: Fri, 25 Jan 2019 13:59:29 -0500 Subject: [PATCH 091/115] Wrong code comment Signed-off-by: xichengliudui --- go/vt/mysqlctl/mysqld.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go/vt/mysqlctl/mysqld.go b/go/vt/mysqlctl/mysqld.go index 03a3b10eea4..713e1679a7b 100644 --- a/go/vt/mysqlctl/mysqld.go +++ b/go/vt/mysqlctl/mysqld.go @@ -210,7 +210,7 @@ func (mysqld *Mysqld) startNoWait(ctx context.Context, cnf *Mycnf, mysqldArgs .. name, err = binaryPath(dir, "mysqld_safe") if err != nil { // The movement to use systemd means that mysqld_safe is not always provided. - // This should not be considered an issue do do not generate a warning. + // This should not be considered an issue do not generate a warning. log.Infof("%v: trying to launch mysqld instead", err) name, err = binaryPath(dir, "mysqld") // If this also fails, return an error. From a4cf44bc4f651171f2816e5007784eb832f82a73 Mon Sep 17 00:00:00 2001 From: xichengliudui <1693291525@qq.com> Date: Fri, 25 Jan 2019 14:21:25 -0500 Subject: [PATCH 092/115] Update doc Signed-off-by: xichengliudui --- doc/HorizontalReshardingWorkflowGuide.md | 2 +- doc/Monitoring.md | 2 +- doc/SchemaManagement.md | 2 +- doc/V3HighLevelDesign.md | 2 +- doc/V3VindexDesign.md | 2 +- doc/VitessApi.md | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/doc/HorizontalReshardingWorkflowGuide.md b/doc/HorizontalReshardingWorkflowGuide.md index f28be1a0a34..a287e194664 100644 --- a/doc/HorizontalReshardingWorkflowGuide.md +++ b/doc/HorizontalReshardingWorkflowGuide.md @@ -132,7 +132,7 @@ on the clicked button. The approval buttons are cleared after the phase has finished. The next phase will only starts if its previous phase has finished successfully. -If the workflow is restored from a checkpoint, you will still see the the +If the workflow is restored from a checkpoint, you will still see the approval button with approved message when there are running tasks under this approval. But you don't need to approve the same tasks again for a restarted workflow. diff --git a/doc/Monitoring.md b/doc/Monitoring.md index 9722ea0ba0b..3864ea87266 100644 --- a/doc/Monitoring.md +++ b/doc/Monitoring.md @@ -22,7 +22,7 @@ Scraping Vitess variables is a good way to integrate Vitess into an existing mon Vitess also includes support for push-based metrics systems via plug-ins. Each Vitess component would need to be run with the `--emit_stats` flag. -By default, the stats_emit_period is 60s, so each component will push stats to the the selected backend every minute. This is configurable via the `--stats_emit_period` flag. +By default, the stats_emit_period is 60s, so each component will push stats to the selected backend every minute. This is configurable via the `--stats_emit_period` flag. Vitess has preliminary plug-ins to support OpenTSDB as a push-based metrics backend. diff --git a/doc/SchemaManagement.md b/doc/SchemaManagement.md index c83e049153a..1bdfcc6da66 100644 --- a/doc/SchemaManagement.md +++ b/doc/SchemaManagement.md @@ -64,7 +64,7 @@ ValidateSchemaShard user/0 The [ValidateSchemaKeyspace]({% link reference/vtctl.md %}#validateschemakeyspace) command confirms that all of the tablets in a given keyspace have -the the same schema as the master tablet on shard 0 +the same schema as the master tablet on shard 0 in that keyspace. Thus, whereas the ValidateSchemaShard command confirms the consistency of the schema on tablets within a shard for a given keyspace, ValidateSchemaKeyspace confirms the diff --git a/doc/V3HighLevelDesign.md b/doc/V3HighLevelDesign.md index ebbd647fff7..6e87e140043 100644 --- a/doc/V3HighLevelDesign.md +++ b/doc/V3HighLevelDesign.md @@ -1491,7 +1491,7 @@ If a, b and c where in different groups, the output would be: a b where (b.id=a.id) and (cond1(a.col, b.col)) ``` -The cond2 expression gets pushed into the the where clause for table ‘c’ because it’s the right-most group that’s referenced by the condition. External references will be changed to appropriate bind variables by the rewiring phase. +The cond2 expression gets pushed into the where clause for table ‘c’ because it’s the right-most group that’s referenced by the condition. External references will be changed to appropriate bind variables by the rewiring phase. *Once VTGate acquires the ability to perform its own filters, should we stop pushing these conditions into the dependent queries and do it ourselves instead? The answer will usually be no. You almost always want to push down filters. This is because it will let the underlying database scan fewer rows, or choose better indexes. The more restrictive the query is, the better.* diff --git a/doc/V3VindexDesign.md b/doc/V3VindexDesign.md index f6d051b77d5..a0f4e930b5f 100644 --- a/doc/V3VindexDesign.md +++ b/doc/V3VindexDesign.md @@ -251,7 +251,7 @@ When you fire up the schema editor, it should take you to the load workflow. The The schema picks up the loaded JSON, parse it and display the various components of the schema in a page where the relationships are easily visualized. The vschema has four main components: keyspaces, tables, table classes and vindexes. -Keyspaces can be on a left navbar. Once you select the keyspaces, it will display the the rest of the three components in one column each. +Keyspaces can be on a left navbar. Once you select the keyspaces, it will display the rest of the three components in one column each. The schema editor will sanity check the JSON file for inconsistencies and flag them using various color codes: diff --git a/doc/VitessApi.md b/doc/VitessApi.md index 5333b61cb49..d4696429bdb 100644 --- a/doc/VitessApi.md +++ b/doc/VitessApi.md @@ -488,7 +488,7 @@ Split a query into non-overlapping sub queries #### Request - SplitQueryRequest is the payload to SplitQuery. SplitQuery takes a "SELECT" query and generates a list of queries called "query-parts". Each query-part consists of the original query with an added WHERE clause that restricts the query-part to operate only on rows whose values in the the columns listed in the "split_column" field of the request (see below) are in a particular range. It is guaranteed that the set of rows obtained from executing each query-part on a database snapshot and merging (without deduping) the results is equal to the set of rows obtained from executing the original query on the same snapshot with the rows containing NULL values in any of the split_column's excluded. This is typically called by the MapReduce master when reading from Vitess. There it's desirable that the sets of rows returned by the query-parts have roughly the same size. + SplitQueryRequest is the payload to SplitQuery. SplitQuery takes a "SELECT" query and generates a list of queries called "query-parts". Each query-part consists of the original query with an added WHERE clause that restricts the query-part to operate only on rows whose values in the columns listed in the "split_column" field of the request (see below) are in a particular range. It is guaranteed that the set of rows obtained from executing each query-part on a database snapshot and merging (without deduping) the results is equal to the set of rows obtained from executing the original query on the same snapshot with the rows containing NULL values in any of the split_column's excluded. This is typically called by the MapReduce master when reading from Vitess. There it's desirable that the sets of rows returned by the query-parts have roughly the same size. ##### Parameters From c3167300a35e1ff539618b07c7673bf0a1b72fcd Mon Sep 17 00:00:00 2001 From: Derek Perkins Date: Fri, 25 Jan 2019 16:55:19 -0700 Subject: [PATCH 093/115] docker: don't chown nonexistent /vt dir Signed-off-by: Derek Perkins --- docker/k8s/vtctlclient/Dockerfile | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/docker/k8s/vtctlclient/Dockerfile b/docker/k8s/vtctlclient/Dockerfile index bfe12e24f26..554fe3e816f 100644 --- a/docker/k8s/vtctlclient/Dockerfile +++ b/docker/k8s/vtctlclient/Dockerfile @@ -13,8 +13,6 @@ COPY --from=k8s /vt/bin/vtctlclient /usr/bin/ # add vitess user/group and add permissions RUN groupadd -r --gid 2000 vitess && \ - useradd -r -g vitess --uid 1000 vitess && \ - chown -R vitess:vitess /vt && \ - chown -R vitess:vitess /vtdataroot + useradd -r -g vitess --uid 1000 vitess CMD ["/usr/bin/vtctlclient"] From c0dbf473e730ddbfc6a1dfba9256bf7b48a19ef3 Mon Sep 17 00:00:00 2001 From: Sugu Sougoumarane Date: Sat, 26 Jan 2019 03:07:19 -0800 Subject: [PATCH 094/115] vplayer: PlayerPlan tests Signed-off-by: Sugu Sougoumarane --- .../vreplication/controller_plan_test.go | 2 +- .../tabletmanager/vreplication/player_plan.go | 132 +++--- .../vreplication/player_plan_test.go | 435 ++++++++++++++++++ .../tabletmanager/vreplication/vplayer.go | 142 +++--- 4 files changed, 580 insertions(+), 131 deletions(-) create mode 100644 go/vt/vttablet/tabletmanager/vreplication/player_plan_test.go diff --git a/go/vt/vttablet/tabletmanager/vreplication/controller_plan_test.go b/go/vt/vttablet/tabletmanager/vreplication/controller_plan_test.go index 6d9a7c54caf..533668a2955 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/controller_plan_test.go +++ b/go/vt/vttablet/tabletmanager/vreplication/controller_plan_test.go @@ -21,7 +21,7 @@ import ( "testing" ) -func TestPlanBuilder(t *testing.T) { +func TestControllerPlan(t *testing.T) { tcases := []struct { in string plan *controllerPlan diff --git a/go/vt/vttablet/tabletmanager/vreplication/player_plan.go b/go/vt/vttablet/tabletmanager/vreplication/player_plan.go index 25100ae3773..77ecde44d5d 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/player_plan.go +++ b/go/vt/vttablet/tabletmanager/vreplication/player_plan.go @@ -26,78 +26,89 @@ import ( querypb "vitess.io/vitess/go/vt/proto/query" ) -type playerPlan struct { - vstreamFilter *binlogdatapb.Filter - tablePlans map[string]*tablePlan +// PlayerPlan is the execution plan for a player stream. +type PlayerPlan struct { + VStreamFilter *binlogdatapb.Filter + TablePlans map[string]*TablePlan } -type tablePlan struct { - name string - colExprs []*colExpr - onInsert insertType - - fields []*querypb.Field - pkCols []*colExpr +// TablePlan is the execution plan for a table within a player stream. +// There are two incarantions of this per table. The first one is built +// while analyzing the inital stream request. A tentative plan is built +// without knowing the table info. The second incarnation is built when +// we receive the field info for a table. At that time, we copy the +// original TablePlan into a separtae map and populate the Fields and +// PKCols members. +type TablePlan struct { + Name string + ColExprs []*ColExpr `json:",omitempty"` + OnInsert InsertType `json:",omitempty"` + + Fields []*querypb.Field `json:",omitempty"` + PKCols []*ColExpr `json:",omitempty"` } -func (tp *tablePlan) findCol(name sqlparser.ColIdent) *colExpr { - for _, cExpr := range tp.colExprs { - if cExpr.colname.Equal(name) { +func (tp *TablePlan) findCol(name sqlparser.ColIdent) *ColExpr { + for _, cExpr := range tp.ColExprs { + if cExpr.ColName.Equal(name) { return cExpr } } return nil } -type colExpr struct { - colname sqlparser.ColIdent - colnum int - op operation - isGrouped bool +// ColExpr describes the processing to be performed to +// compute the value of the target table column. +type ColExpr struct { + ColName sqlparser.ColIdent + ColNum int + Operation Operation `json:",omitempty"` + IsGrouped bool `json:",omitempty"` } -type operation int +// Operation is the opcode for the ColExpr. +type Operation int +// The following values are the various ColExpr opcodes. const ( - opNone = operation(iota) - opCount - opSum + OpNone = Operation(iota) + OpCount + OpSum ) -type insertType int +// InsertType describes the type of insert statement to generate. +type InsertType int +// The following values are the various insert types. const ( - insertNormal = insertType(iota) - insertOndup - insertIgnore + InsertNormal = InsertType(iota) + InsertOndup + InsertIgnore ) -func buildPlayerPlan(filter *binlogdatapb.Filter) (*playerPlan, error) { - plan := &playerPlan{ - vstreamFilter: &binlogdatapb.Filter{ +func buildPlayerPlan(filter *binlogdatapb.Filter) (*PlayerPlan, error) { + plan := &PlayerPlan{ + VStreamFilter: &binlogdatapb.Filter{ Rules: make([]*binlogdatapb.Rule, len(filter.Rules)), }, - tablePlans: make(map[string]*tablePlan), + TablePlans: make(map[string]*TablePlan), } for i, rule := range filter.Rules { if strings.HasPrefix(rule.Match, "/") { - plan.vstreamFilter.Rules[i] = rule + plan.VStreamFilter.Rules[i] = rule continue } sendRule, tplan, err := buildTablePlan(rule) if err != nil { return nil, err } - if tplan == nil { - continue - } - plan.vstreamFilter.Rules[i] = sendRule - plan.tablePlans[sendRule.Match] = tplan + plan.VStreamFilter.Rules[i] = sendRule + plan.TablePlans[sendRule.Match] = tplan } return plan, nil } -func buildTablePlan(rule *binlogdatapb.Rule) (*binlogdatapb.Rule, *tablePlan, error) { +func buildTablePlan(rule *binlogdatapb.Rule) (*binlogdatapb.Rule, *TablePlan, error) { statement, err := sqlparser.Parse(rule.Filter) if err != nil { return nil, nil, err @@ -106,6 +117,9 @@ func buildTablePlan(rule *binlogdatapb.Rule) (*binlogdatapb.Rule, *tablePlan, er if !ok { return nil, nil, fmt.Errorf("unexpected: %v", sqlparser.String(statement)) } + if sel.Distinct != "" { + return nil, nil, fmt.Errorf("unexpected: %v", sqlparser.String(sel)) + } if len(sel.From) > 1 { return nil, nil, fmt.Errorf("unexpected: %v", sqlparser.String(sel)) } @@ -126,11 +140,11 @@ func buildTablePlan(rule *binlogdatapb.Rule) (*binlogdatapb.Rule, *tablePlan, er Match: fromTable.String(), Filter: rule.Filter, } - return sendRule, &tablePlan{name: rule.Match}, nil + return sendRule, &TablePlan{Name: rule.Match}, nil } - tplan := &tablePlan{ - name: rule.Match, + tplan := &TablePlan{ + Name: rule.Match, } sendSelect := &sqlparser.Select{ From: sel.From, @@ -143,19 +157,19 @@ func buildTablePlan(rule *binlogdatapb.Rule) (*binlogdatapb.Rule, *tablePlan, er } if selExpr != nil { sendSelect.SelectExprs = append(sendSelect.SelectExprs, selExpr) - cExpr.colnum = len(sendSelect.SelectExprs) - 1 + cExpr.ColNum = len(sendSelect.SelectExprs) - 1 } - tplan.colExprs = append(tplan.colExprs, cExpr) + tplan.ColExprs = append(tplan.ColExprs, cExpr) } if sel.GroupBy != nil { if err := analyzeGroupBy(sel.GroupBy, tplan); err != nil { return nil, nil, err } - tplan.onInsert = insertIgnore - for _, cExpr := range tplan.colExprs { - if !cExpr.isGrouped { - tplan.onInsert = insertOndup + tplan.OnInsert = InsertIgnore + for _, cExpr := range tplan.ColExprs { + if !cExpr.IsGrouped { + tplan.OnInsert = InsertOndup break } } @@ -167,7 +181,7 @@ func buildTablePlan(rule *binlogdatapb.Rule) (*binlogdatapb.Rule, *tablePlan, er return sendRule, tplan, nil } -func analyzeExpr(selExpr sqlparser.SelectExpr) (sqlparser.SelectExpr, *colExpr, error) { +func analyzeExpr(selExpr sqlparser.SelectExpr) (sqlparser.SelectExpr, *ColExpr, error) { aliased, ok := selExpr.(*sqlparser.AliasedExpr) if !ok { return nil, nil, fmt.Errorf("unexpected: %v", sqlparser.String(selExpr)) @@ -178,54 +192,54 @@ func analyzeExpr(selExpr sqlparser.SelectExpr) (sqlparser.SelectExpr, *colExpr, } switch expr := aliased.Expr.(type) { case *sqlparser.ColName: - return selExpr, &colExpr{colname: as}, nil + return selExpr, &ColExpr{ColName: as}, nil case *sqlparser.FuncExpr: if expr.Distinct || len(expr.Exprs) != 1 { - return nil, nil, fmt.Errorf("unsupported: %v", sqlparser.String(expr)) + return nil, nil, fmt.Errorf("unexpected: %v", sqlparser.String(expr)) } if aliased.As.IsEmpty() { return nil, nil, fmt.Errorf("expression needs an alias: %v", sqlparser.String(expr)) } switch fname := expr.Name.Lowered(); fname { case "month", "day", "hour": - return selExpr, &colExpr{colname: as}, nil + return selExpr, &ColExpr{ColName: as}, nil case "count": if _, ok := expr.Exprs[0].(*sqlparser.StarExpr); !ok { return nil, nil, fmt.Errorf("only count(*) is supported: %v", sqlparser.String(expr)) } - return nil, &colExpr{colname: as, op: opCount}, nil + return nil, &ColExpr{ColName: as, Operation: OpCount}, nil case "sum": aInner, ok := expr.Exprs[0].(*sqlparser.AliasedExpr) if !ok { - return nil, nil, fmt.Errorf("unsupported: %v", sqlparser.String(expr)) + return nil, nil, fmt.Errorf("unexpected: %v", sqlparser.String(expr)) } innerCol, ok := aInner.Expr.(*sqlparser.ColName) if !ok { - return nil, nil, fmt.Errorf("unsupported: %v", sqlparser.String(expr)) + return nil, nil, fmt.Errorf("unexpected: %v", sqlparser.String(expr)) } - return &sqlparser.AliasedExpr{Expr: innerCol}, &colExpr{colname: as, op: opSum}, nil + return &sqlparser.AliasedExpr{Expr: innerCol}, &ColExpr{ColName: as, Operation: OpSum}, nil default: - return nil, nil, fmt.Errorf("unsupported: %v", sqlparser.String(expr)) + return nil, nil, fmt.Errorf("unexpected: %v", sqlparser.String(expr)) } default: return nil, nil, fmt.Errorf("unexpected: %v", sqlparser.String(expr)) } } -func analyzeGroupBy(groupBy sqlparser.GroupBy, tplan *tablePlan) error { +func analyzeGroupBy(groupBy sqlparser.GroupBy, tplan *TablePlan) error { for _, expr := range groupBy { colname, ok := expr.(*sqlparser.ColName) if !ok { - return fmt.Errorf("unsupported: %v", sqlparser.String(expr)) + return fmt.Errorf("unexpected: %v", sqlparser.String(expr)) } cExpr := tplan.findCol(colname.Name) if cExpr == nil { return fmt.Errorf("group by expression does not reference an alias in the select list: %v", sqlparser.String(expr)) } - if cExpr.op != opNone { + if cExpr.Operation != OpNone { return fmt.Errorf("group by expression is not allowed to reference an aggregate expression: %v", sqlparser.String(expr)) } - cExpr.isGrouped = true + cExpr.IsGrouped = true } return nil } diff --git a/go/vt/vttablet/tabletmanager/vreplication/player_plan_test.go b/go/vt/vttablet/tabletmanager/vreplication/player_plan_test.go new file mode 100644 index 00000000000..bf5066002f2 --- /dev/null +++ b/go/vt/vttablet/tabletmanager/vreplication/player_plan_test.go @@ -0,0 +1,435 @@ +/* +Copyright 2019 The Vitess Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this 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 ( + "encoding/json" + "testing" + + binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" + "vitess.io/vitess/go/vt/sqlparser" +) + +func TestPlayerPlan(t *testing.T) { + testcases := []struct { + input *binlogdatapb.Filter + plan *PlayerPlan + err string + }{{ + // Regular expression + input: &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{{ + Match: "/.*", + }}, + }, + plan: &PlayerPlan{ + VStreamFilter: &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{{ + Match: "/.*", + }}, + }, + TablePlans: map[string]*TablePlan{}, + }, + }, { + // '*' expression + input: &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{{ + Match: "t1", + Filter: "select * from t2", + }}, + }, + plan: &PlayerPlan{ + VStreamFilter: &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{{ + Match: "t2", + Filter: "select * from t2", + }}, + }, + TablePlans: map[string]*TablePlan{ + "t2": { + Name: "t1", + }, + }, + }, + }, { + // Explicit columns + input: &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{{ + Match: "t1", + Filter: "select c1, c2 from t2", + }}, + }, + plan: &PlayerPlan{ + VStreamFilter: &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{{ + Match: "t2", + Filter: "select c1, c2 from t2", + }}, + }, + TablePlans: map[string]*TablePlan{ + "t2": { + Name: "t1", + ColExprs: []*ColExpr{{ + ColName: sqlparser.NewColIdent("c1"), + ColNum: 0, + }, { + ColName: sqlparser.NewColIdent("c2"), + ColNum: 1, + }}, + }, + }, + }, + }, { + // func expr + input: &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{{ + Match: "t1", + Filter: "select hour(c1) as hc1, day(c2) as dc2 from t2", + }}, + }, + plan: &PlayerPlan{ + VStreamFilter: &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{{ + Match: "t2", + Filter: "select hour(c1) as hc1, day(c2) as dc2 from t2", + }}, + }, + TablePlans: map[string]*TablePlan{ + "t2": { + Name: "t1", + ColExprs: []*ColExpr{{ + ColName: sqlparser.NewColIdent("hc1"), + ColNum: 0, + }, { + ColName: sqlparser.NewColIdent("dc2"), + ColNum: 1, + }}, + }, + }, + }, + }, { + // count expr + input: &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{{ + Match: "t1", + Filter: "select hour(c1) as hc1, count(*) as c, day(c2) as dc2 from t2", + }}, + }, + plan: &PlayerPlan{ + VStreamFilter: &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{{ + Match: "t2", + Filter: "select hour(c1) as hc1, day(c2) as dc2 from t2", + }}, + }, + TablePlans: map[string]*TablePlan{ + "t2": { + Name: "t1", + ColExprs: []*ColExpr{{ + ColName: sqlparser.NewColIdent("hc1"), + ColNum: 0, + }, { + ColName: sqlparser.NewColIdent("c"), + Operation: OpCount, + }, { + ColName: sqlparser.NewColIdent("dc2"), + ColNum: 1, + }}, + }, + }, + }, + }, { + // sum expr + input: &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{{ + Match: "t1", + Filter: "select hour(c1) as hc1, sum(c3) as s, day(c2) as dc2 from t2", + }}, + }, + plan: &PlayerPlan{ + VStreamFilter: &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{{ + Match: "t2", + Filter: "select hour(c1) as hc1, c3, day(c2) as dc2 from t2", + }}, + }, + TablePlans: map[string]*TablePlan{ + "t2": { + Name: "t1", + ColExprs: []*ColExpr{{ + ColName: sqlparser.NewColIdent("hc1"), + ColNum: 0, + }, { + ColName: sqlparser.NewColIdent("s"), + ColNum: 1, + Operation: OpSum, + }, { + ColName: sqlparser.NewColIdent("dc2"), + ColNum: 2, + }}, + }, + }, + }, + }, { + // partial group by + input: &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{{ + Match: "t1", + Filter: "select c1, c2, c3 from t2 group by c3, c1", + }}, + }, + plan: &PlayerPlan{ + VStreamFilter: &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{{ + Match: "t2", + Filter: "select c1, c2, c3 from t2", + }}, + }, + TablePlans: map[string]*TablePlan{ + "t2": { + Name: "t1", + ColExprs: []*ColExpr{{ + ColName: sqlparser.NewColIdent("c1"), + ColNum: 0, + IsGrouped: true, + }, { + ColName: sqlparser.NewColIdent("c2"), + ColNum: 1, + }, { + ColName: sqlparser.NewColIdent("c3"), + ColNum: 2, + IsGrouped: true, + }}, + OnInsert: InsertOndup, + }, + }, + }, + }, { + // full group by + input: &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{{ + Match: "t1", + Filter: "select c1, c2, c3 from t2 group by c3, c1, c2", + }}, + }, + plan: &PlayerPlan{ + VStreamFilter: &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{{ + Match: "t2", + Filter: "select c1, c2, c3 from t2", + }}, + }, + TablePlans: map[string]*TablePlan{ + "t2": { + Name: "t1", + ColExprs: []*ColExpr{{ + ColName: sqlparser.NewColIdent("c1"), + ColNum: 0, + IsGrouped: true, + }, { + ColName: sqlparser.NewColIdent("c2"), + ColNum: 1, + IsGrouped: true, + }, { + ColName: sqlparser.NewColIdent("c3"), + ColNum: 2, + IsGrouped: true, + }}, + OnInsert: InsertIgnore, + }, + }, + }, + }, { + // syntax error + input: &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{{ + Match: "t1", + Filter: "bad query", + }}, + }, + err: "syntax error at position 4 near 'bad'", + }, { + // not a select + input: &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{{ + Match: "t1", + Filter: "update t1 set val=1", + }}, + }, + err: "unexpected: update t1 set val = 1", + }, { + // no distinct + input: &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{{ + Match: "t1", + Filter: "select distinct c1 from t1", + }}, + }, + err: "unexpected: select distinct c1 from t1", + }, { + // no ',' join + input: &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{{ + Match: "t1", + Filter: "select * from t1, t2", + }}, + }, + err: "unexpected: select * from t1, t2", + }, { + // no join + input: &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{{ + Match: "t1", + Filter: "select * from t1 join t2", + }}, + }, + err: "unexpected: select * from t1 join t2", + }, { + // no subqueries + input: &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{{ + Match: "t1", + Filter: "select * from (select * from t2) as a", + }}, + }, + err: "unexpected: select * from (select * from t2) as a", + }, { + // cannot combine '*' with other + input: &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{{ + Match: "t1", + Filter: "select *, c1 from t1", + }}, + }, + err: "unexpected: select *, c1 from t1", + }, { + // cannot combine '*' with other (different code path) + input: &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{{ + Match: "t1", + Filter: "select c1, * from t1", + }}, + }, + err: "unexpected: *", + }, { + // no distinct in func + input: &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{{ + Match: "t1", + Filter: "select hour(distinct c1) from t1", + }}, + }, + err: "unexpected: hour(distinct c1)", + }, { + // funcs need alias + input: &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{{ + Match: "t1", + Filter: "select hour(c1) from t1", + }}, + }, + err: "expression needs an alias: hour(c1)", + }, { + // only count(*) + input: &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{{ + Match: "t1", + Filter: "select count(c1) as c from t1", + }}, + }, + err: "only count(*) is supported: count(c1)", + }, { + // no sum(*) + input: &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{{ + Match: "t1", + Filter: "select sum(*) as c from t1", + }}, + }, + err: "unexpected: sum(*)", + }, { + // no complex expr in sum + input: &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{{ + Match: "t1", + Filter: "select sum(a + b) as c from t1", + }}, + }, + err: "unexpected: sum(a + b)", + }, { + // unsupported func + input: &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{{ + Match: "t1", + Filter: "select foo(a) as c from t1", + }}, + }, + err: "unexpected: foo(a)", + }, { + // no complex expr in select + input: &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{{ + Match: "t1", + Filter: "select a + b from t1", + }}, + }, + err: "unexpected: a + b", + }, { + // no complex expr in group by + input: &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{{ + Match: "t1", + Filter: "select a from t1 group by a + 1", + }}, + }, + err: "unexpected: a + 1", + }, { + // group by does not reference alias + input: &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{{ + Match: "t1", + Filter: "select a as b from t1 group by a", + }}, + }, + err: "group by expression does not reference an alias in the select list: a", + }, { + // cannot group by aggr + input: &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{{ + Match: "t1", + Filter: "select count(*) as a from t1 group by a", + }}, + }, + err: "group by expression is not allowed to reference an aggregate expression: a", + }} + + for _, tcase := range testcases { + plan, err := buildPlayerPlan(tcase.input) + gotPlan, _ := json.Marshal(plan) + wantPlan, _ := json.Marshal(tcase.plan) + if string(gotPlan) != string(wantPlan) { + t.Errorf("Filter(%v):\n%s, want\n%s", tcase.input, gotPlan, wantPlan) + } + gotErr := "" + if err != nil { + gotErr = err.Error() + } + if gotErr != tcase.err { + t.Errorf("Filter err(%v): %s, want %v", tcase.input, gotErr, tcase.err) + } + } +} diff --git a/go/vt/vttablet/tabletmanager/vreplication/vplayer.go b/go/vt/vttablet/tabletmanager/vreplication/vplayer.go index c9c90a1b2b9..4315c10c8cc 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/vplayer.go +++ b/go/vt/vttablet/tabletmanager/vreplication/vplayer.go @@ -64,10 +64,10 @@ type vplayer struct { stopPos mysql.Position // pplan is built based on the source Filter at the beginning. - pplan *playerPlan + pplan *PlayerPlan // tplans[table] is built for each table based on pplan and schema info // about the table. - tplans map[string]*tablePlan + tplans map[string]*TablePlan } func newVPlayer(id uint32, source *binlogdatapb.BinlogSource, sourceTablet *topodatapb.Tablet, stats *binlogplayer.Stats, dbClient binlogplayer.DBClient, mysqld mysqlctl.MysqlDaemon) *vplayer { @@ -79,7 +79,7 @@ func newVPlayer(id uint32, source *binlogdatapb.BinlogSource, sourceTablet *topo dbClient: &retryableClient{DBClient: dbClient}, mysqld: mysqld, timeLastSaved: time.Now(), - tplans: make(map[string]*tablePlan), + tplans: make(map[string]*TablePlan), } } @@ -143,10 +143,10 @@ func (vp *vplayer) play(ctx context.Context) error { Shard: vp.sourceTablet.Shard, TabletType: vp.sourceTablet.Type, } - log.Infof("Sending vstream command: %v", plan.vstreamFilter) + log.Infof("Sending vstream command: %v", plan.VStreamFilter) streamErr := make(chan error, 1) go func() { - streamErr <- vsClient.VStream(ctx, target, startPos, plan.vstreamFilter, func(events []*binlogdatapb.VEvent) error { + streamErr <- vsClient.VStream(ctx, target, startPos, plan.VStreamFilter, func(events []*binlogdatapb.VEvent) error { return relay.Send(events) }) }() @@ -354,57 +354,57 @@ func (vp *vplayer) setState(state, message string) error { } func (vp *vplayer) updatePlan(fieldEvent *binlogdatapb.FieldEvent) error { - prelim := vp.pplan.tablePlans[fieldEvent.TableName] - tplan := &tablePlan{ - name: fieldEvent.TableName, + prelim := vp.pplan.TablePlans[fieldEvent.TableName] + tplan := &TablePlan{ + Name: fieldEvent.TableName, } if prelim != nil { *tplan = *prelim } - tplan.fields = fieldEvent.Fields + tplan.Fields = fieldEvent.Fields - if tplan.colExprs == nil { - tplan.colExprs = make([]*colExpr, len(tplan.fields)) - for i, field := range tplan.fields { - tplan.colExprs[i] = &colExpr{ - colname: sqlparser.NewColIdent(field.Name), - colnum: i, + if tplan.ColExprs == nil { + tplan.ColExprs = make([]*ColExpr, len(tplan.Fields)) + for i, field := range tplan.Fields { + tplan.ColExprs[i] = &ColExpr{ + ColName: sqlparser.NewColIdent(field.Name), + ColNum: i, } } } else { - for _, cExpr := range tplan.colExprs { - if cExpr.colnum >= len(tplan.fields) { + for _, cExpr := range tplan.ColExprs { + if cExpr.ColNum >= len(tplan.Fields) { // Unreachable code. - return fmt.Errorf("columns received from vreplication: %v, do not match expected: %v", tplan.fields, tplan.colExprs) + return fmt.Errorf("columns received from vreplication: %v, do not match expected: %v", tplan.Fields, tplan.ColExprs) } } } - pkcols, err := vp.mysqld.GetPrimaryKeyColumns(vp.dbClient.DBName(), tplan.name) + pkcols, err := vp.mysqld.GetPrimaryKeyColumns(vp.dbClient.DBName(), tplan.Name) if err != nil { - return fmt.Errorf("error fetching pk columns for %s: %v", tplan.name, err) + return fmt.Errorf("error fetching pk columns for %s: %v", tplan.Name, err) } if len(pkcols) == 0 { // If the table doesn't have a PK, then we treat all columns as PK. - pkcols, err = vp.mysqld.GetColumns(vp.dbClient.DBName(), tplan.name) + pkcols, err = vp.mysqld.GetColumns(vp.dbClient.DBName(), tplan.Name) if err != nil { - return fmt.Errorf("error fetching pk columns for %s: %v", tplan.name, err) + return fmt.Errorf("error fetching pk columns for %s: %v", tplan.Name, err) } } for _, pkcol := range pkcols { found := false - for i, cExpr := range tplan.colExprs { - if cExpr.colname.EqualString(pkcol) { + for i, cExpr := range tplan.ColExprs { + if cExpr.ColName.EqualString(pkcol) { found = true - tplan.pkCols = append(tplan.pkCols, &colExpr{ - colname: cExpr.colname, - colnum: i, + tplan.PKCols = append(tplan.PKCols, &ColExpr{ + ColName: cExpr.ColName, + ColNum: i, }) break } } if !found { - return fmt.Errorf("primary key column %s missing from select list for table %s", pkcol, tplan.name) + return fmt.Errorf("primary key column %s missing from select list for table %s", pkcol, tplan.Name) } } vp.tplans[fieldEvent.TableName] = tplan @@ -424,14 +424,14 @@ func (vp *vplayer) applyRowEvent(ctx context.Context, rowEvent *binlogdatapb.Row return nil } -func (vp *vplayer) applyRowChange(ctx context.Context, tplan *tablePlan, rowChange *binlogdatapb.RowChange) error { +func (vp *vplayer) applyRowChange(ctx context.Context, tplan *TablePlan, rowChange *binlogdatapb.RowChange) error { // MakeRowTrusted is needed here because because Proto3ToResult is not convenient. var before, after []sqltypes.Value if rowChange.Before != nil { - before = sqltypes.MakeRowTrusted(tplan.fields, rowChange.Before) + before = sqltypes.MakeRowTrusted(tplan.Fields, rowChange.Before) } if rowChange.After != nil { - after = sqltypes.MakeRowTrusted(tplan.fields, rowChange.After) + after = sqltypes.MakeRowTrusted(tplan.Fields, rowChange.After) } var query string switch { @@ -450,113 +450,113 @@ func (vp *vplayer) applyRowChange(ctx context.Context, tplan *tablePlan, rowChan return vp.exec(ctx, query) } -func (vp *vplayer) generateInsert(tplan *tablePlan, after []sqltypes.Value) string { +func (vp *vplayer) generateInsert(tplan *TablePlan, after []sqltypes.Value) string { sql := sqlparser.NewTrackedBuffer(nil) - if tplan.onInsert == insertIgnore { - sql.Myprintf("insert ignore into %v set ", sqlparser.NewTableIdent(tplan.name)) + if tplan.OnInsert == InsertIgnore { + sql.Myprintf("insert ignore into %v set ", sqlparser.NewTableIdent(tplan.Name)) } else { - sql.Myprintf("insert into %v set ", sqlparser.NewTableIdent(tplan.name)) + sql.Myprintf("insert into %v set ", sqlparser.NewTableIdent(tplan.Name)) } vp.writeInsertValues(sql, tplan, after) - if tplan.onInsert == insertOndup { + if tplan.OnInsert == InsertOndup { sql.Myprintf(" on duplicate key update ") vp.writeUpdateValues(sql, tplan, nil, after) } return sql.String() } -func (vp *vplayer) generateUpdate(tplan *tablePlan, before, after []sqltypes.Value) string { - if tplan.onInsert == insertIgnore { +func (vp *vplayer) generateUpdate(tplan *TablePlan, before, after []sqltypes.Value) string { + if tplan.OnInsert == InsertIgnore { return vp.generateInsert(tplan, after) } sql := sqlparser.NewTrackedBuffer(nil) - sql.Myprintf("update %v set ", sqlparser.NewTableIdent(tplan.name)) + sql.Myprintf("update %v set ", sqlparser.NewTableIdent(tplan.Name)) vp.writeUpdateValues(sql, tplan, before, after) sql.Myprintf(" where ") vp.writeWhereValues(sql, tplan, before) return sql.String() } -func (vp *vplayer) generateDelete(tplan *tablePlan, before []sqltypes.Value) string { +func (vp *vplayer) generateDelete(tplan *TablePlan, before []sqltypes.Value) string { sql := sqlparser.NewTrackedBuffer(nil) - switch tplan.onInsert { - case insertOndup: - sql.Myprintf("update %v set ", sqlparser.NewTableIdent(tplan.name)) + switch tplan.OnInsert { + case InsertOndup: + sql.Myprintf("update %v set ", sqlparser.NewTableIdent(tplan.Name)) vp.writeUpdateValues(sql, tplan, before, nil) sql.Myprintf(" where ") vp.writeWhereValues(sql, tplan, before) - case insertIgnore: + case InsertIgnore: return "" default: // insertNormal - sql.Myprintf("delete from %v where ", sqlparser.NewTableIdent(tplan.name)) + sql.Myprintf("delete from %v where ", sqlparser.NewTableIdent(tplan.Name)) vp.writeWhereValues(sql, tplan, before) } return sql.String() } -func (vp *vplayer) writeInsertValues(sql *sqlparser.TrackedBuffer, tplan *tablePlan, after []sqltypes.Value) { +func (vp *vplayer) writeInsertValues(sql *sqlparser.TrackedBuffer, tplan *TablePlan, after []sqltypes.Value) { separator := "" - for _, cExpr := range tplan.colExprs { - sql.Myprintf("%s%v=", separator, cExpr.colname) + for _, cExpr := range tplan.ColExprs { + sql.Myprintf("%s%v=", separator, cExpr.ColName) if separator == "" { separator = ", " } - if cExpr.op == opCount { + if cExpr.Operation == OpCount { sql.WriteString("1") } else { - encodeValue(sql, after[cExpr.colnum]) + encodeValue(sql, after[cExpr.ColNum]) } } } -func (vp *vplayer) writeUpdateValues(sql *sqlparser.TrackedBuffer, tplan *tablePlan, before, after []sqltypes.Value) { +func (vp *vplayer) writeUpdateValues(sql *sqlparser.TrackedBuffer, tplan *TablePlan, before, after []sqltypes.Value) { separator := "" - for _, cExpr := range tplan.colExprs { - if cExpr.isGrouped { + for _, cExpr := range tplan.ColExprs { + if cExpr.IsGrouped { continue } - sql.Myprintf("%s%v=", separator, cExpr.colname) + sql.Myprintf("%s%v=", separator, cExpr.ColName) if separator == "" { separator = ", " } - if cExpr.op == opCount || cExpr.op == opSum { - sql.Myprintf("%v", cExpr.colname) + if cExpr.Operation == OpCount || cExpr.Operation == OpSum { + sql.Myprintf("%v", cExpr.ColName) } if len(before) != 0 { - switch cExpr.op { - case opNone: + switch cExpr.Operation { + case OpNone: if len(after) == 0 { sql.WriteString("NULL") } - case opCount: + case OpCount: sql.WriteString("-1") - case opSum: + case OpSum: sql.WriteString("-") - encodeValue(sql, before[cExpr.colnum]) + encodeValue(sql, before[cExpr.ColNum]) } } if len(after) != 0 { - switch cExpr.op { - case opNone: - encodeValue(sql, after[cExpr.colnum]) - case opCount: + switch cExpr.Operation { + case OpNone: + encodeValue(sql, after[cExpr.ColNum]) + case OpCount: sql.WriteString("+1") - case opSum: + case OpSum: sql.WriteString("+") - encodeValue(sql, after[cExpr.colnum]) + encodeValue(sql, after[cExpr.ColNum]) } } } } -func (vp *vplayer) writeWhereValues(sql *sqlparser.TrackedBuffer, tplan *tablePlan, before []sqltypes.Value) { +func (vp *vplayer) writeWhereValues(sql *sqlparser.TrackedBuffer, tplan *TablePlan, before []sqltypes.Value) { separator := "" - for _, cExpr := range tplan.pkCols { - sql.Myprintf("%s%v=", separator, cExpr.colname) + for _, cExpr := range tplan.PKCols { + sql.Myprintf("%s%v=", separator, cExpr.ColName) if separator == "" { separator = " and " } - encodeValue(sql, before[cExpr.colnum]) + encodeValue(sql, before[cExpr.ColNum]) } } From fab917f9ec8251a7fe8fc9111719d283bc302641 Mon Sep 17 00:00:00 2001 From: Sugu Sougoumarane Date: Sat, 26 Jan 2019 04:18:43 -0800 Subject: [PATCH 095/115] vplayer: types test Signed-off-by: Sugu Sougoumarane --- .../vreplication/framework_test.go | 4 +- .../vreplication/vplayer_test.go | 95 +++++++++++++++++++ 2 files changed, 97 insertions(+), 2 deletions(-) diff --git a/go/vt/vttablet/tabletmanager/vreplication/framework_test.go b/go/vt/vttablet/tabletmanager/vreplication/framework_test.go index 9d44d314cb2..c3044b3bbcc 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/framework_test.go +++ b/go/vt/vttablet/tabletmanager/vreplication/framework_test.go @@ -382,11 +382,11 @@ func expectData(t *testing.T, table string, values [][]string) { } for i, row := range values { if i >= len(qr.Rows) { - t.Errorf("Result too short, row: %d, want: %v", i, row) + t.Fatalf("Result too short, row: %d, want: %v", i, row) } for j, val := range row { if j >= len(qr.Rows[i]) { - t.Errorf("Too few columns, result: %v, row: %d, want: %v", qr.Rows[i], i, row) + t.Fatalf("Too few columns, result: %v, row: %d, want: %v", qr.Rows[i], i, row) } if got := qr.Rows[i][j].ToString(); got != val { t.Errorf("Mismatch at (%d, %d): %v, want %s", i, j, qr.Rows[i][j], val) diff --git a/go/vt/vttablet/tabletmanager/vreplication/vplayer_test.go b/go/vt/vttablet/tabletmanager/vreplication/vplayer_test.go index d8be7ddf287..7b9e6c7c8f1 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/vplayer_test.go +++ b/go/vt/vttablet/tabletmanager/vreplication/vplayer_test.go @@ -278,6 +278,101 @@ func TestPlayerFilters(t *testing.T) { } } +func TestPlayerTypes(t *testing.T) { + defer deleteTablet(addTablet(100, "0", topodatapb.TabletType_REPLICA, true, true)) + + 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))", + fmt.Sprintf("create table %s.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))", vrepldb), + "create table vitess_fracts(id int, deci decimal(5,2), num numeric(5,2), f float, d double, primary key(id))", + fmt.Sprintf("create table %s.vitess_fracts(id int, deci decimal(5,2), num numeric(5,2), f float, d double, primary key(id))", vrepldb), + "create table vitess_strings(vb varbinary(16), c char(16), vc varchar(16), b binary(4), tb tinyblob, bl blob, ttx tinytext, tx text, en enum('a','b'), s set('a','b'), primary key(vb))", + fmt.Sprintf("create table %s.vitess_strings(vb varbinary(16), c char(16), vc varchar(16), b binary(4), tb tinyblob, bl blob, ttx tinytext, tx text, en enum('a','b'), s set('a','b'), primary key(vb))", vrepldb), + "create table vitess_misc(id int, b bit(8), d date, dt datetime, t time, g geometry, primary key(id))", + fmt.Sprintf("create table %s.vitess_misc(id int, b bit(8), d date, dt datetime, t time, g geometry, primary key(id))", vrepldb), + "create table vitess_null(id int, val varbinary(128), primary key(id))", + fmt.Sprintf("create table %s.vitess_null(id int, val varbinary(128), primary key(id))", vrepldb), + "create table src1(id int, val varbinary(128), primary key(id))", + fmt.Sprintf("create table %s.src1(id int, val varbinary(128), primary key(id))", vrepldb), + }) + defer execStatements(t, []string{ + "drop table vitess_ints", + fmt.Sprintf("drop table %s.vitess_ints", vrepldb), + "drop table vitess_fracts", + fmt.Sprintf("drop table %s.vitess_fracts", vrepldb), + "drop table vitess_strings", + fmt.Sprintf("drop table %s.vitess_strings", vrepldb), + "drop table vitess_misc", + fmt.Sprintf("drop table %s.vitess_misc", vrepldb), + "drop table vitess_null", + fmt.Sprintf("drop table %s.vitess_null", vrepldb), + }) + env.SchemaEngine.Reload(context.Background()) + + filter := &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{{ + Match: "/.*", + }}, + } + cancel, _ := startVReplication(t, filter, binlogdatapb.OnDDLAction_IGNORE, "") + defer cancel() + testcases := []struct { + input string + output string + table string + data [][]string + }{{ + input: "insert into vitess_ints values(-128, 255, -32768, 65535, -8388608, 16777215, -2147483648, 4294967295, -9223372036854775808, 18446744073709551615, 2012)", + output: "insert into vitess_ints set tiny=-128, tinyu=255, small=-32768, smallu=65535, medium=-8388608, mediumu=16777215, normal=-2147483648, normalu=4294967295, big=-9223372036854775808, bigu=18446744073709551615, y=2012", + table: "vitess_ints", + data: [][]string{ + {"-128", "255", "-32768", "65535", "-8388608", "16777215", "-2147483648", "4294967295", "-9223372036854775808", "18446744073709551615", "2012"}, + }, + }, { + input: "insert into vitess_fracts values(1, 1.99, 2.99, 3.99, 4.99)", + output: "insert into vitess_fracts set id=1, deci=1.99, num=2.99, f=3.99E+00, d=4.99E+00", + table: "vitess_fracts", + data: [][]string{ + {"1", "1.99", "2.99", "3.99", "4.99"}, + }, + }, { + input: "insert into vitess_strings values('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'a', 'a,b')", + output: "insert into vitess_strings set vb='a', c='b', vc='c', b='d', tb='e', bl='f', ttx='g', tx='h', en='1', s='3'", + table: "vitess_strings", + data: [][]string{ + {"a", "b", "c", "d\x00\x00\x00", "e", "f", "g", "h", "a", "a,b"}, + }, + }, { + input: "insert into vitess_misc values(1, '\x01', '2012-01-01', '2012-01-01 15:45:45', '15:45:45', point(1, 2))", + output: "insert into vitess_misc set id=1, b=b'00000001', d='2012-01-01', dt='2012-01-01 15:45:45', t='15:45:45', g='\\0\\0\\0\\0\x01\x01\\0\\0\\0\\0\\0\\0\\0\\0\\0\xf0?\\0\\0\\0\\0\\0\\0\\0@'", + table: "vitess_misc", + data: [][]string{ + {"1", "\x01", "2012-01-01", "2012-01-01 15:45:45", "15:45:45", "\x00\x00\x00\x00\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf0?\x00\x00\x00\x00\x00\x00\x00@"}, + }, + }, { + input: "insert into vitess_null values(1, null)", + output: "insert into vitess_null set id=1, val=null", + table: "vitess_null", + data: [][]string{ + {"1", ""}, + }, + }} + + for _, tcases := range testcases { + execStatements(t, []string{tcases.input}) + want := []string{ + "begin", + tcases.output, + "/update _vt.vreplication set pos=", + "commit", + } + expectDBClientQueries(t, want) + if tcases.table != "" { + expectData(t, tcases.table, tcases.data) + } + } +} + func TestPlayerDDL(t *testing.T) { defer deleteTablet(addTablet(100, "0", topodatapb.TabletType_REPLICA, true, true)) execStatements(t, []string{ From d74e120530dde9899bc3bee987d3f33ed03c095c Mon Sep 17 00:00:00 2001 From: Sugu Sougoumarane Date: Sat, 26 Jan 2019 17:48:45 -0800 Subject: [PATCH 096/115] vplayer: fix for binary column data type Fixes #3984 Signed-off-by: Sugu Sougoumarane --- go/mysql/binlog_event_rbr.go | 16 ++++++++++++-- .../vreplication/vplayer_test.go | 21 ++++++++++++++++++- .../tabletserver/vstreamer/vstreamer_test.go | 4 ++-- 3 files changed, 36 insertions(+), 5 deletions(-) diff --git a/go/mysql/binlog_event_rbr.go b/go/mysql/binlog_event_rbr.go index 7e61f83b205..a8ec52dd05b 100644 --- a/go/mysql/binlog_event_rbr.go +++ b/go/mysql/binlog_event_rbr.go @@ -853,14 +853,26 @@ func CellValue(data []byte, pos int, typ byte, metadata uint16, styp querypb.Typ max := int((((metadata >> 4) & 0x300) ^ 0x300) + (metadata & 0xff)) // Length is encoded in 1 or 2 bytes. if max > 255 { + // This code path exists due to https://bugs.mysql.com/bug.php?id=37426. + // CHAR types need to allocate 3 bytes per char. So, the length for CHAR(255) + // cannot be represented in 1 byte. This also means that this rule does not + // apply to BINARY data. l := int(uint64(data[pos]) | uint64(data[pos+1])<<8) return sqltypes.MakeTrusted(querypb.Type_VARCHAR, data[pos+2:pos+2+l]), l + 2, nil } l := int(data[pos]) - return sqltypes.MakeTrusted(querypb.Type_VARCHAR, - data[pos+1:pos+1+l]), l + 1, nil + mdata := data[pos+1 : pos+1+l] + if sqltypes.IsBinary(styp) { + // Fixed length binaries have to be padded with zeroes + // up to the length of the field. Otherwise, equality checks + // fail against saved data. See https://github.com/vitessio/vitess/issues/3984. + ret := make([]byte, max) + copy(ret, mdata) + return sqltypes.MakeTrusted(querypb.Type_BINARY, ret), l + 1, nil + } + return sqltypes.MakeTrusted(querypb.Type_VARCHAR, mdata), l + 1, nil case TypeGeometry: l := 0 diff --git a/go/vt/vttablet/tabletmanager/vreplication/vplayer_test.go b/go/vt/vttablet/tabletmanager/vreplication/vplayer_test.go index 7b9e6c7c8f1..660b0a1da96 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/vplayer_test.go +++ b/go/vt/vttablet/tabletmanager/vreplication/vplayer_test.go @@ -294,6 +294,8 @@ func TestPlayerTypes(t *testing.T) { fmt.Sprintf("create table %s.vitess_null(id int, val varbinary(128), primary key(id))", vrepldb), "create table src1(id int, val varbinary(128), primary key(id))", fmt.Sprintf("create table %s.src1(id int, val varbinary(128), primary key(id))", vrepldb), + "create table binary_pk(b binary(4), val varbinary(4), primary key(b))", + fmt.Sprintf("create table %s.binary_pk(b binary(4), val varbinary(4), primary key(b))", vrepldb), }) defer execStatements(t, []string{ "drop table vitess_ints", @@ -306,6 +308,8 @@ func TestPlayerTypes(t *testing.T) { fmt.Sprintf("drop table %s.vitess_misc", vrepldb), "drop table vitess_null", fmt.Sprintf("drop table %s.vitess_null", vrepldb), + "drop table binary_pk", + fmt.Sprintf("drop table %s.binary_pk", vrepldb), }) env.SchemaEngine.Reload(context.Background()) @@ -337,7 +341,7 @@ func TestPlayerTypes(t *testing.T) { }, }, { input: "insert into vitess_strings values('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'a', 'a,b')", - output: "insert into vitess_strings set vb='a', c='b', vc='c', b='d', tb='e', bl='f', ttx='g', tx='h', en='1', s='3'", + output: "insert into vitess_strings set vb='a', c='b', vc='c', b='d\\0\\0\\0', tb='e', bl='f', ttx='g', tx='h', en='1', s='3'", table: "vitess_strings", data: [][]string{ {"a", "b", "c", "d\x00\x00\x00", "e", "f", "g", "h", "a", "a,b"}, @@ -356,6 +360,21 @@ func TestPlayerTypes(t *testing.T) { data: [][]string{ {"1", ""}, }, + }, { + input: "insert into binary_pk values('a', 'aaa')", + output: "insert into binary_pk set b='a\\0\\0\\0', val='aaa'", + table: "binary_pk", + data: [][]string{ + {"a\x00\x00\x00", "aaa"}, + }, + }, { + // Binary pk is a special case: https://github.com/vitessio/vitess/issues/3984 + input: "update binary_pk set val='bbb' where b='a\\0\\0\\0'", + output: "update binary_pk set b='a\\0\\0\\0', val='bbb' where b='a\\0\\0\\0'", + table: "binary_pk", + data: [][]string{ + {"a\x00\x00\x00", "bbb"}, + }, }} for _, tcases := range testcases { diff --git a/go/vt/vttablet/tabletserver/vstreamer/vstreamer_test.go b/go/vt/vttablet/tabletserver/vstreamer/vstreamer_test.go index 5d39189e9f2..517e19534ac 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/vstreamer_test.go +++ b/go/vt/vttablet/tabletserver/vstreamer/vstreamer_test.go @@ -696,8 +696,8 @@ func TestTypes(t *testing.T) { `fields: ` + `fields: ` + `fields: > `, - `type:ROW row_event: > > `, + `type:ROW row_event: > > `, `commit`, }}, }, { From a7f0dca59e042160bfd11ea5e768bc42b1ce4565 Mon Sep 17 00:00:00 2001 From: Sugu Sougoumarane Date: Sat, 26 Jan 2019 20:33:30 -0800 Subject: [PATCH 097/115] vplayer: update only what has changed Signed-off-by: Sugu Sougoumarane --- .../vreplication/framework_test.go | 10 +- .../tabletmanager/vreplication/vplayer.go | 67 ++++++--- .../vreplication/vplayer_test.go | 142 ++++++++++++++++-- 3 files changed, 177 insertions(+), 42 deletions(-) diff --git a/go/vt/vttablet/tabletmanager/vreplication/framework_test.go b/go/vt/vttablet/tabletmanager/vreplication/framework_test.go index c3044b3bbcc..23c019bd638 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/framework_test.go +++ b/go/vt/vttablet/tabletmanager/vreplication/framework_test.go @@ -380,14 +380,14 @@ func expectData(t *testing.T, table string, values [][]string) { t.Error(err) return } + if len(values) != len(qr.Rows) { + t.Fatalf("row counts don't match: %v, want %v", qr.Rows, values) + } for i, row := range values { - if i >= len(qr.Rows) { - t.Fatalf("Result too short, row: %d, want: %v", i, row) + if len(row) != len(qr.Rows[i]) { + t.Fatalf("Too few columns, result: %v, row: %d, want: %v", qr.Rows[i], i, row) } for j, val := range row { - if j >= len(qr.Rows[i]) { - t.Fatalf("Too few columns, result: %v, row: %d, want: %v", qr.Rows[i], i, row) - } if got := qr.Rows[i][j].ToString(); got != val { t.Errorf("Mismatch at (%d, %d): %v, want %s", i, j, qr.Rows[i][j], val) } diff --git a/go/vt/vttablet/tabletmanager/vreplication/vplayer.go b/go/vt/vttablet/tabletmanager/vreplication/vplayer.go index 4315c10c8cc..f49c2b16583 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/vplayer.go +++ b/go/vt/vttablet/tabletmanager/vreplication/vplayer.go @@ -460,7 +460,7 @@ func (vp *vplayer) generateInsert(tplan *TablePlan, after []sqltypes.Value) stri vp.writeInsertValues(sql, tplan, after) if tplan.OnInsert == InsertOndup { sql.Myprintf(" on duplicate key update ") - vp.writeUpdateValues(sql, tplan, nil, after) + _ = vp.writeUpdateValues(sql, tplan, nil, after) } return sql.String() } @@ -471,7 +471,9 @@ func (vp *vplayer) generateUpdate(tplan *TablePlan, before, after []sqltypes.Val } sql := sqlparser.NewTrackedBuffer(nil) sql.Myprintf("update %v set ", sqlparser.NewTableIdent(tplan.Name)) - vp.writeUpdateValues(sql, tplan, before, after) + if ok := vp.writeUpdateValues(sql, tplan, before, after); !ok { + return "" + } sql.Myprintf(" where ") vp.writeWhereValues(sql, tplan, before) return sql.String() @@ -481,10 +483,7 @@ func (vp *vplayer) generateDelete(tplan *TablePlan, before []sqltypes.Value) str sql := sqlparser.NewTrackedBuffer(nil) switch tplan.OnInsert { case InsertOndup: - sql.Myprintf("update %v set ", sqlparser.NewTableIdent(tplan.Name)) - vp.writeUpdateValues(sql, tplan, before, nil) - sql.Myprintf(" where ") - vp.writeWhereValues(sql, tplan, before) + return vp.generateUpdate(tplan, before, nil) case InsertIgnore: return "" default: // insertNormal @@ -498,27 +497,50 @@ func (vp *vplayer) writeInsertValues(sql *sqlparser.TrackedBuffer, tplan *TableP separator := "" for _, cExpr := range tplan.ColExprs { sql.Myprintf("%s%v=", separator, cExpr.ColName) - if separator == "" { - separator = ", " - } + separator = ", " if cExpr.Operation == OpCount { sql.WriteString("1") } else { - encodeValue(sql, after[cExpr.ColNum]) + if cExpr.Operation == OpSum && after[cExpr.ColNum].IsNull() { + sql.WriteString("0") + } else { + encodeValue(sql, after[cExpr.ColNum]) + } } } } -func (vp *vplayer) writeUpdateValues(sql *sqlparser.TrackedBuffer, tplan *TablePlan, before, after []sqltypes.Value) { +// writeUpdateValues returns true if at least one value was set. Otherwise, it returns false. +func (vp *vplayer) writeUpdateValues(sql *sqlparser.TrackedBuffer, tplan *TablePlan, before, after []sqltypes.Value) bool { separator := "" + hasSet := false for _, cExpr := range tplan.ColExprs { if cExpr.IsGrouped { continue } - sql.Myprintf("%s%v=", separator, cExpr.ColName) - if separator == "" { - separator = ", " + if len(before) != 0 && len(after) != 0 { + if cExpr.Operation == OpCount { + continue + } + bef := before[cExpr.ColNum] + aft := after[cExpr.ColNum] + // If both are null, there's no change + if bef.IsNull() && aft.IsNull() { + continue + } + // If any one of them is null, something has changed. + if bef.IsNull() || aft.IsNull() { + goto mustSet + } + // Compare content only if none are null. + if bef.ToString() == aft.ToString() { + continue + } } + mustSet: + sql.Myprintf("%s%v=", separator, cExpr.ColName) + separator = ", " + hasSet = true if cExpr.Operation == OpCount || cExpr.Operation == OpSum { sql.Myprintf("%v", cExpr.ColName) } @@ -531,8 +553,10 @@ func (vp *vplayer) writeUpdateValues(sql *sqlparser.TrackedBuffer, tplan *TableP case OpCount: sql.WriteString("-1") case OpSum: - sql.WriteString("-") - encodeValue(sql, before[cExpr.ColNum]) + if !before[cExpr.ColNum].IsNull() { + sql.WriteString("-") + encodeValue(sql, before[cExpr.ColNum]) + } } } if len(after) != 0 { @@ -542,20 +566,21 @@ func (vp *vplayer) writeUpdateValues(sql *sqlparser.TrackedBuffer, tplan *TableP case OpCount: sql.WriteString("+1") case OpSum: - sql.WriteString("+") - encodeValue(sql, after[cExpr.ColNum]) + if !after[cExpr.ColNum].IsNull() { + sql.WriteString("+") + encodeValue(sql, after[cExpr.ColNum]) + } } } } + return hasSet } func (vp *vplayer) writeWhereValues(sql *sqlparser.TrackedBuffer, tplan *TablePlan, before []sqltypes.Value) { separator := "" for _, cExpr := range tplan.PKCols { sql.Myprintf("%s%v=", separator, cExpr.ColName) - if separator == "" { - separator = " and " - } + separator = " and " encodeValue(sql, before[cExpr.ColNum]) } } diff --git a/go/vt/vttablet/tabletmanager/vreplication/vplayer_test.go b/go/vt/vttablet/tabletmanager/vreplication/vplayer_test.go index 660b0a1da96..1996015d82a 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/vplayer_test.go +++ b/go/vt/vttablet/tabletmanager/vreplication/vplayer_test.go @@ -24,9 +24,10 @@ import ( "time" "golang.org/x/net/context" - "vitess.io/vitess/go/mysql" + "vitess.io/vitess/go/mysql" "vitess.io/vitess/go/vt/binlog/binlogplayer" + binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" topodatapb "vitess.io/vitess/go/vt/proto/topodata" ) @@ -104,7 +105,7 @@ func TestPlayerFilters(t *testing.T) { input: "update src1 set val='bbb'", output: []string{ "begin", - "update dst1 set id=1, val='bbb' where id=1", + "update dst1 set val='bbb' where id=1", "/update _vt.vreplication set pos=", "commit", }, @@ -134,20 +135,20 @@ func TestPlayerFilters(t *testing.T) { }, table: "dst2", data: [][]string{ - {"1", "2", "3"}, + {"1", "2", "3", "1"}, }, }, { // update with insertOnDup input: "update src2 set val1=5, val2=1 where id=1", output: []string{ "begin", - "update dst2 set val1=5, sval2=sval2-3+1, rcount=rcount-1+1 where id=1", + "update dst2 set val1=5, sval2=sval2-3+1 where id=1", "/update _vt.vreplication set pos=", "commit", }, table: "dst2", data: [][]string{ - {"1", "5", "1"}, + {"1", "5", "1", "1"}, }, }, { // delete with insertOnDup @@ -160,7 +161,7 @@ func TestPlayerFilters(t *testing.T) { }, table: "dst2", data: [][]string{ - {"1", "", "0"}, + {"1", "", "0", "0"}, }, }, { // insert with insertIgnore @@ -218,7 +219,7 @@ func TestPlayerFilters(t *testing.T) { input: "update yes set val='bbb'", output: []string{ "begin", - "update yes set id=1, val='bbb' where id=1", + "update yes set val='bbb' where id=1", "/update _vt.vreplication set pos=", "commit", }, @@ -248,7 +249,7 @@ func TestPlayerFilters(t *testing.T) { input: "update nopk set val='bbb' where id=1", output: []string{ "begin", - "update nopk set id=1, val='bbb' where id=1 and val='aaa'", + "update nopk set val='bbb' where id=1 and val='aaa'", "/update _vt.vreplication set pos=", "commit", }, @@ -278,6 +279,115 @@ func TestPlayerFilters(t *testing.T) { } } +func TestPlayerUpdates(t *testing.T) { + defer deleteTablet(addTablet(100, "0", topodatapb.TabletType_REPLICA, true, true)) + + execStatements(t, []string{ + "create table t1(id int, grouped int, ungrouped int, summed int, primary key(id))", + fmt.Sprintf("create table %s.t1(id int, grouped int, ungrouped int, summed int, rcount int, primary key(id))", vrepldb), + }) + defer execStatements(t, []string{ + "drop table t1", + fmt.Sprintf("drop table %s.t1", vrepldb), + }) + env.SchemaEngine.Reload(context.Background()) + + filter := &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{{ + Match: "t1", + Filter: "select id, grouped, ungrouped, sum(summed) as summed, count(*) as rcount from t1 group by id, grouped", + }}, + } + cancel, _ := startVReplication(t, filter, binlogdatapb.OnDDLAction_IGNORE, "") + defer cancel() + + testcases := []struct { + input string + output string + table string + data [][]string + }{{ + // Start with all nulls + input: "insert into t1 values(1, null, null, null)", + output: "insert into t1 set id=1, grouped=null, ungrouped=null, summed=0, rcount=1 on duplicate key update ungrouped=null, summed=summed, rcount=rcount+1", + table: "t1", + data: [][]string{ + {"1", "", "", "0", "1"}, + }, + }, { + // null to null values + input: "update t1 set grouped=1 where id=1", + output: "", + table: "t1", + data: [][]string{ + {"1", "", "", "0", "1"}, + }, + }, { + // null to non-null values + input: "update t1 set ungrouped=1, summed=1 where id=1", + output: "update t1 set ungrouped=1, summed=summed+1 where id=1", + table: "t1", + data: [][]string{ + {"1", "", "1", "1", "1"}, + }, + }, { + // non-null to non-null values + input: "update t1 set ungrouped=2, summed=2 where id=1", + output: "update t1 set ungrouped=2, summed=summed-1+2 where id=1", + table: "t1", + data: [][]string{ + {"1", "", "2", "2", "1"}, + }, + }, { + // non-null to null values + input: "update t1 set ungrouped=null, summed=null where id=1", + output: "update t1 set ungrouped=null, summed=summed-2 where id=1", + table: "t1", + data: [][]string{ + {"1", "", "", "0", "1"}, + }, + }, { + // insert non-null values + input: "insert into t1 values(2, 2, 3, 4)", + output: "insert into t1 set id=2, grouped=2, ungrouped=3, summed=4, rcount=1 on duplicate key update ungrouped=3, summed=summed+4, rcount=rcount+1", + table: "t1", + data: [][]string{ + {"1", "", "", "0", "1"}, + {"2", "2", "3", "4", "1"}, + }, + }, { + // delete non-null values + input: "delete from t1 where id=2", + output: "update t1 set ungrouped=NULL, summed=summed-4, rcount=rcount-1 where id=2", + table: "t1", + data: [][]string{ + {"1", "", "", "0", "1"}, + {"2", "2", "", "0", "0"}, + }, + }} + + for _, tcases := range testcases { + execStatements(t, []string{tcases.input}) + output := []string{ + "begin", + tcases.output, + "/update _vt.vreplication set pos=", + "commit", + } + if tcases.output == "" { + output = []string{ + "begin", + "/update _vt.vreplication set pos=", + "commit", + } + } + expectDBClientQueries(t, output) + if tcases.table != "" { + expectData(t, tcases.table, tcases.data) + } + } +} + func TestPlayerTypes(t *testing.T) { defer deleteTablet(addTablet(100, "0", topodatapb.TabletType_REPLICA, true, true)) @@ -370,7 +480,7 @@ func TestPlayerTypes(t *testing.T) { }, { // Binary pk is a special case: https://github.com/vitessio/vitess/issues/3984 input: "update binary_pk set val='bbb' where b='a\\0\\0\\0'", - output: "update binary_pk set b='a\\0\\0\\0', val='bbb' where b='a\\0\\0\\0'", + output: "update binary_pk set val='bbb' where b='a\\0\\0\\0'", table: "binary_pk", data: [][]string{ {"a\x00\x00\x00", "bbb"}, @@ -740,8 +850,8 @@ func TestPlayerLockErrors(t *testing.T) { // The innodb lock wait timeout is set to 1s. expectDBClientQueries(t, []string{ "begin", - "update t1 set id=1, val='ccc' where id=1", - "update t1 set id=2, val='ccc' where id=2", + "update t1 set val='ccc' where id=1", + "update t1 set val='ccc' where id=2", "rollback", }) @@ -749,8 +859,8 @@ func TestPlayerLockErrors(t *testing.T) { _, _ = vconn.ExecuteFetch("rollback", 1) expectDBClientQueries(t, []string{ "begin", - "update t1 set id=1, val='ccc' where id=1", - "update t1 set id=2, val='ccc' where id=2", + "update t1 set val='ccc' where id=1", + "update t1 set val='ccc' where id=2", "/update _vt.vreplication set pos=", "commit", }) @@ -811,7 +921,7 @@ func TestPlayerCancelOnLock(t *testing.T) { // The innodb lock wait timeout is set to 1s. expectDBClientQueries(t, []string{ "begin", - "update t1 set id=1, val='ccc' where id=1", + "update t1 set val='ccc' where id=1", "rollback", }) @@ -896,7 +1006,7 @@ func TestPlayerBatching(t *testing.T) { // transactions must be batched into one. But the // DDLs should be on their own. expectDBClientQueries(t, []string{ - "update t1 set id=1, val='ccc' where id=1", + "update t1 set val='ccc' where id=1", "/update _vt.vreplication set pos=", "commit", "begin", @@ -993,7 +1103,7 @@ func TestPlayerRelayLogMaxSize(t *testing.T) { // will wait to be sent to the relay until the player fetches // them. expectDBClientQueries(t, []string{ - "update t1 set id=1, val='ccc' where id=1", + "update t1 set val='ccc' where id=1", "/update _vt.vreplication set pos=", "commit", "begin", From 4b4da3ade9129efa104b495c5b376dcd0951ab5a Mon Sep 17 00:00:00 2001 From: Andres Taylor Date: Mon, 28 Jan 2019 12:35:38 +0100 Subject: [PATCH 098/115] Minor cleanups Signed-off-by: Andres Taylor --- go/cmd/vtworkerclient/vtworkerclient.go | 2 +- go/vt/worker/restartable_result_reader.go | 4 +--- go/vt/worker/split_clone.go | 23 ----------------------- 3 files changed, 2 insertions(+), 27 deletions(-) diff --git a/go/cmd/vtworkerclient/vtworkerclient.go b/go/cmd/vtworkerclient/vtworkerclient.go index 997da727657..0e1874453ba 100644 --- a/go/cmd/vtworkerclient/vtworkerclient.go +++ b/go/cmd/vtworkerclient/vtworkerclient.go @@ -55,7 +55,7 @@ func main() { logutil.LogEvent(logger, e) }) if err != nil { - log.Errorf("%+v", err) + log.Error(err) os.Exit(1) } } diff --git a/go/vt/worker/restartable_result_reader.go b/go/vt/worker/restartable_result_reader.go index 84649be867d..90a5e8c20ea 100644 --- a/go/vt/worker/restartable_result_reader.go +++ b/go/vt/worker/restartable_result_reader.go @@ -23,8 +23,6 @@ import ( "strings" "time" - "github.com/golang/glog" - "vitess.io/vitess/go/vt/vterrors" "golang.org/x/net/context" @@ -117,7 +115,7 @@ func tryToConnect(r *RestartableResultReader) error { return fmt.Errorf("failed to initialize tablet connection: retryable %v, %v", retryable, err) } statsRetryCount.Add(1) - glog.Infof("retrying after error: %v", err) + log.Infof("retrying after error: %v", err) } } diff --git a/go/vt/worker/split_clone.go b/go/vt/worker/split_clone.go index 8eb5fefa2b6..8537be596e2 100644 --- a/go/vt/worker/split_clone.go +++ b/go/vt/worker/split_clone.go @@ -435,29 +435,6 @@ func (scw *SplitCloneWorker) Run(ctx context.Context) error { return nil } -func (scw *SplitCloneWorker) disableUniquenessCheckOnDestinationTablets(ctx context.Context) error { - for _, si := range scw.destinationShards { - tablets := scw.tsc.GetHealthyTabletStats(si.Keyspace(), si.ShardName(), topodatapb.TabletType_MASTER) - if len(tablets) != 1 { - return fmt.Errorf("should have exactly one MASTER tablet, have %v", len(tablets)) - } - tablet := tablets[0].Tablet - cmd := "SET UNIQUE_CHECKS=0" - scw.wr.Logger().Infof("disabling uniqueness checks on %v", topoproto.TabletAliasString(tablet.Alias)) - _, err := scw.wr.TabletManagerClient().ExecuteFetchAsApp(ctx, tablet, true, []byte(cmd), 0) - if err != nil { - return fmt.Errorf("should have exactly one MASTER tablet, have %v", len(tablets)) - } - scw.cleaner.Record("EnableUniquenessChecks", topoproto.TabletAliasString(tablet.Alias), func(ctx context.Context, wr *wrangler.Wrangler) error { - cmd := "SET UNIQUE_CHECKS=1" - _, err := scw.wr.TabletManagerClient().ExecuteFetchAsApp(ctx, tablet, true, []byte(cmd), 0) - return err - }) - } - - return nil -} - func (scw *SplitCloneWorker) run(ctx context.Context) error { // Phase 1: read what we need to do. if err := scw.init(ctx); err != nil { From df60fec661ec6d696fca127c89d1bb57a5e88815 Mon Sep 17 00:00:00 2001 From: Scott Lanning Date: Mon, 28 Jan 2019 13:14:05 +0100 Subject: [PATCH 099/115] parse TIMESTAMP{ADD,DIFF} functions Otherwise, get something like this error: vtgate.go:1091] Execute: symbol MINUTE not found in table or subquery, request: map[Sql:SELECT TIMESTAMPDIFF(MINUTE, .... reference: https://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html#function_timestampadd Signed-off-by: Scott Lanning --- go/vt/sqlparser/ast.go | 91 +- go/vt/sqlparser/parse_test.go | 6 + go/vt/sqlparser/sql.go | 4249 +++++++++++++++++---------------- go/vt/sqlparser/sql.y | 11 + go/vt/sqlparser/token.go | 2 + 5 files changed, 2227 insertions(+), 2132 deletions(-) diff --git a/go/vt/sqlparser/ast.go b/go/vt/sqlparser/ast.go index 7881f24398a..83ee5657440 100644 --- a/go/vt/sqlparser/ast.go +++ b/go/vt/sqlparser/ast.go @@ -2151,34 +2151,35 @@ type Expr interface { SQLNode } -func (*AndExpr) iExpr() {} -func (*OrExpr) iExpr() {} -func (*NotExpr) iExpr() {} -func (*ParenExpr) iExpr() {} -func (*ComparisonExpr) iExpr() {} -func (*RangeCond) iExpr() {} -func (*IsExpr) iExpr() {} -func (*ExistsExpr) iExpr() {} -func (*SQLVal) iExpr() {} -func (*NullVal) iExpr() {} -func (BoolVal) iExpr() {} -func (*ColName) iExpr() {} -func (ValTuple) iExpr() {} -func (*Subquery) iExpr() {} -func (ListArg) iExpr() {} -func (*BinaryExpr) iExpr() {} -func (*UnaryExpr) iExpr() {} -func (*IntervalExpr) iExpr() {} -func (*CollateExpr) iExpr() {} -func (*FuncExpr) iExpr() {} -func (*CaseExpr) iExpr() {} -func (*ValuesFuncExpr) iExpr() {} -func (*ConvertExpr) iExpr() {} -func (*SubstrExpr) iExpr() {} -func (*ConvertUsingExpr) iExpr() {} -func (*MatchExpr) iExpr() {} -func (*GroupConcatExpr) iExpr() {} -func (*Default) iExpr() {} +func (*AndExpr) iExpr() {} +func (*OrExpr) iExpr() {} +func (*NotExpr) iExpr() {} +func (*ParenExpr) iExpr() {} +func (*ComparisonExpr) iExpr() {} +func (*RangeCond) iExpr() {} +func (*IsExpr) iExpr() {} +func (*ExistsExpr) iExpr() {} +func (*SQLVal) iExpr() {} +func (*NullVal) iExpr() {} +func (BoolVal) iExpr() {} +func (*ColName) iExpr() {} +func (ValTuple) iExpr() {} +func (*Subquery) iExpr() {} +func (ListArg) iExpr() {} +func (*BinaryExpr) iExpr() {} +func (*UnaryExpr) iExpr() {} +func (*IntervalExpr) iExpr() {} +func (*CollateExpr) iExpr() {} +func (*FuncExpr) iExpr() {} +func (*TimestampFuncExpr) iExpr() {} +func (*CaseExpr) iExpr() {} +func (*ValuesFuncExpr) iExpr() {} +func (*ConvertExpr) iExpr() {} +func (*SubstrExpr) iExpr() {} +func (*ConvertUsingExpr) iExpr() {} +func (*MatchExpr) iExpr() {} +func (*GroupConcatExpr) iExpr() {} +func (*Default) iExpr() {} // ReplaceExpr finds the from expression from root // and replaces it with to. If from matches root, @@ -2868,6 +2869,40 @@ func (node *IntervalExpr) replace(from, to Expr) bool { return replaceExprs(from, to, &node.Expr) } +// TimestampFuncExpr represents the function and arguments for TIMESTAMP{ADD,DIFF} functions. +type TimestampFuncExpr struct { + Name string + Expr1 Expr + Expr2 Expr + Unit string +} + +// Format formats the node. +func (node *TimestampFuncExpr) Format(buf *TrackedBuffer) { + buf.Myprintf("%s(%s, %v, %v)", node.Name, node.Unit, node.Expr1, node.Expr2) +} + +func (node *TimestampFuncExpr) walkSubtree(visit Visit) error { + if node == nil { + return nil + } + return Walk( + visit, + node.Expr1, + node.Expr2, + ) +} + +func (node *TimestampFuncExpr) replace(from, to Expr) bool { + if replaceExprs(from, to, &node.Expr1) { + return true + } + if replaceExprs(from, to, &node.Expr2) { + return true + } + return false +} + // CollateExpr represents dynamic collate operator. type CollateExpr struct { Expr Expr diff --git a/go/vt/sqlparser/parse_test.go b/go/vt/sqlparser/parse_test.go index bdafd2061ae..a0141afd880 100644 --- a/go/vt/sqlparser/parse_test.go +++ b/go/vt/sqlparser/parse_test.go @@ -532,6 +532,12 @@ var ( input: "select /* interval */ adddate('2008-01-02', interval 31 day) from t", }, { input: "select /* interval keyword */ adddate('2008-01-02', interval 1 year) from t", + }, { + input: "select /* TIMESTAMPADD */ TIMESTAMPADD(MINUTE, 1, '2008-01-04') from t", + output: "select /* TIMESTAMPADD */ timestampadd(MINUTE, 1, '2008-01-04') from t", + }, { + input: "select /* TIMESTAMPDIFF */ TIMESTAMPDIFF(MINUTE, '2008-01-02', '2008-01-04') from t", + output: "select /* TIMESTAMPDIFF */ timestampdiff(MINUTE, '2008-01-02', '2008-01-04') from t", }, { input: "select /* dual */ 1 from dual", }, { diff --git a/go/vt/sqlparser/sql.go b/go/vt/sqlparser/sql.go index 7575306054c..24382a6f1c2 100644 --- a/go/vt/sqlparser/sql.go +++ b/go/vt/sqlparser/sql.go @@ -343,14 +343,16 @@ const SUBSTR = 57579 const SUBSTRING = 57580 const GROUP_CONCAT = 57581 const SEPARATOR = 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 TIMESTAMPADD = 57583 +const TIMESTAMPDIFF = 57584 +const MATCH = 57585 +const AGAINST = 57586 +const BOOLEAN = 57587 +const LANGUAGE = 57588 +const WITH = 57589 +const QUERY = 57590 +const EXPANSION = 57591 +const UNUSED = 57592 var yyToknames = [...]string{ "$end", @@ -610,6 +612,8 @@ var yyToknames = [...]string{ "SUBSTRING", "GROUP_CONCAT", "SEPARATOR", + "TIMESTAMPADD", + "TIMESTAMPDIFF", "MATCH", "AGAINST", "BOOLEAN", @@ -639,24 +643,24 @@ var yyExca = [...]int{ 160, 300, -2, 290, -1, 267, - 112, 636, - -2, 632, + 112, 638, + -2, 634, -1, 268, - 112, 637, - -2, 633, - -1, 331, - 82, 807, + 112, 639, + -2, 635, + -1, 333, + 82, 811, -2, 60, - -1, 332, - 82, 764, + -1, 334, + 82, 768, -2, 61, - -1, 337, - 82, 743, - -2, 598, -1, 339, - 82, 785, + 82, 747, -2, 600, - -1, 597, + -1, 341, + 82, 789, + -2, 602, + -1, 603, 1, 352, 5, 352, 12, 352, @@ -678,622 +682,738 @@ var yyExca = [...]int{ 53, 352, 55, 352, 56, 352, - 266, 352, + 268, 352, -2, 370, - -1, 600, + -1, 606, 53, 43, 55, 43, -2, 45, - -1, 740, - 112, 639, - -2, 635, - -1, 958, + -1, 746, + 112, 641, + -2, 637, + -1, 966, 5, 30, -2, 436, - -1, 987, + -1, 997, 5, 29, - -2, 572, - -1, 1240, + -2, 574, + -1, 1254, 5, 30, - -2, 573, - -1, 1295, - 5, 29, -2, 575, - -1, 1376, + -1, 1311, + 5, 29, + -2, 577, + -1, 1394, 5, 30, - -2, 576, + -2, 578, } const yyPrivate = 57344 -const yyLast = 12140 +const yyLast = 12360 var yyAct = [...]int{ - 268, 1411, 1401, 1197, 1364, 1079, 272, 990, 562, 844, - 1008, 1274, 1132, 1166, 991, 1260, 57, 821, 246, 1133, - 1129, 1307, 840, 887, 873, 853, 923, 843, 1139, 1033, - 1014, 1102, 81, 561, 3, 819, 208, 336, 1145, 208, - 765, 775, 705, 1059, 1050, 857, 950, 298, 808, 823, - 772, 742, 793, 593, 610, 237, 494, 500, 609, 594, - 255, 330, 883, 514, 325, 801, 435, 208, 81, 327, - 932, 506, 208, 56, 208, 1404, 774, 1388, 1399, 1374, - 1396, 1198, 1387, 1373, 867, 245, 1124, 1234, 440, 1318, - 468, 203, 199, 200, 201, 1161, 1162, 1160, 270, 61, - 238, 239, 240, 241, 834, 259, 244, 576, 488, 1340, - 527, 526, 536, 537, 529, 530, 531, 532, 533, 534, - 535, 528, 243, 906, 538, 63, 64, 65, 66, 67, - 1174, 1175, 1176, 835, 836, 242, 1041, 905, 1179, 1177, - 1021, 484, 611, 1020, 612, 195, 1022, 197, 866, 485, - 482, 483, 218, 1263, 453, 874, 470, 1280, 472, 1217, - 1215, 236, 477, 478, 680, 910, 487, 1082, 1081, 678, - 1398, 1395, 1365, 1078, 904, 802, 231, 1356, 858, 1419, - 1103, 454, 1415, 442, 1308, 197, 1009, 1011, 469, 471, - 1083, 684, 671, 860, 860, 1345, 208, 1310, 679, 208, - 860, 599, 1155, 1154, 1153, 208, 438, 681, 445, 210, - 198, 208, 202, 1316, 81, 1243, 81, 1105, 81, 81, - 1183, 81, 1034, 81, 901, 898, 899, 211, 897, 436, - 917, 841, 81, 916, 214, 550, 551, 205, 1089, 968, - 196, 1075, 222, 217, 944, 714, 518, 1077, 528, 460, - 1107, 538, 1111, 450, 1106, 538, 1104, 513, 1354, 908, - 911, 1109, 81, 1010, 436, 1309, 502, 706, 326, 711, - 1108, 1184, 70, 437, 220, 439, 467, 963, 1066, 1341, - 230, 1326, 1143, 1110, 1112, 503, 613, 874, 1413, 859, - 859, 1414, 1126, 1412, 1372, 903, 859, 434, 490, 491, - 925, 856, 854, 511, 855, 794, 212, 1064, 71, 852, - 858, 299, 51, 1178, 1317, 1315, 447, 902, 448, 513, - 794, 449, 977, 208, 208, 208, 441, 512, 511, 81, - 1039, 673, 1359, 224, 215, 81, 225, 226, 227, 229, - 508, 228, 234, 1076, 513, 1074, 216, 219, 707, 213, - 233, 232, 504, 512, 511, 1420, 456, 457, 458, 592, - 907, 749, 1378, 51, 531, 532, 533, 534, 535, 528, - 513, 251, 538, 909, 1065, 747, 748, 746, 924, 1070, - 1067, 1060, 1068, 1063, 863, 512, 511, 1061, 1062, 601, - 864, 261, 1128, 1270, 1421, 717, 718, 446, 607, 1380, - 452, 1069, 513, 443, 444, 54, 459, 732, 734, 735, - 1269, 194, 461, 733, 1054, 745, 274, 1053, 466, 578, - 579, 580, 581, 582, 583, 584, 529, 530, 531, 532, - 533, 534, 535, 528, 1042, 208, 538, 1355, 1291, 962, - 81, 961, 1267, 512, 511, 208, 208, 81, 713, 22, - 1086, 208, 1352, 766, 208, 767, 1200, 208, 512, 511, - 513, 208, 1051, 81, 81, 941, 942, 943, 81, 81, - 81, 81, 81, 81, 1034, 513, 322, 323, 81, 81, - 1023, 1029, 1024, 1313, 1397, 712, 333, 526, 536, 537, - 529, 530, 531, 532, 533, 534, 535, 528, 693, 768, - 538, 690, 512, 511, 297, 689, 81, 1383, 493, 250, - 208, 1313, 1368, 1313, 493, 604, 81, 674, 685, 513, - 672, 719, 1313, 1346, 591, 465, 600, 465, 669, 465, - 465, 691, 465, 462, 465, 455, 79, 1313, 1312, 1258, - 1257, 1245, 493, 465, 527, 526, 536, 537, 529, 530, - 531, 532, 533, 534, 535, 528, 740, 605, 538, 603, - 81, 1242, 493, 51, 493, 721, 1190, 1189, 1381, 743, - 1186, 1187, 335, 1186, 1185, 1323, 784, 788, 547, 736, - 1322, 549, 795, 288, 287, 290, 291, 292, 293, 738, - 1319, 208, 289, 294, 956, 493, 1180, 951, 779, 208, - 208, 805, 493, 208, 208, 777, 493, 81, 1015, 560, - 861, 564, 565, 566, 567, 568, 569, 570, 571, 572, - 81, 575, 577, 577, 577, 577, 577, 577, 577, 577, - 585, 586, 587, 588, 1092, 598, 621, 798, 829, 497, - 501, 1142, 780, 781, 791, 804, 675, 676, 790, 769, - 770, 805, 682, 620, 619, 326, 519, 58, 688, 875, - 876, 877, 797, 1015, 799, 800, 827, 832, 831, 972, - 805, 24, 208, 81, 1130, 81, 24, 1142, 956, 81, - 81, 208, 208, 777, 208, 208, 548, 848, 208, 81, - 970, 563, 889, 967, 965, 985, 828, 956, 603, 986, - 574, 492, 1238, 1325, 1294, 208, 1142, 208, 208, 805, - 208, 728, 1188, 971, 869, 870, 871, 872, 335, 54, - 335, 24, 335, 335, 54, 335, 1025, 335, 885, 886, - 880, 881, 882, 833, 969, 956, 335, 966, 964, 603, - 597, 606, 810, 813, 814, 815, 811, 333, 812, 816, - 715, 465, 740, 810, 813, 814, 815, 811, 465, 812, - 816, 683, 54, 1146, 1147, 252, 516, 1389, 1362, 54, - 1276, 1265, 868, 933, 465, 465, 934, 1250, 888, 465, - 465, 465, 465, 465, 465, 1171, 1146, 1147, 1080, 465, - 465, 1028, 803, 884, 743, 879, 878, 891, 946, 1406, - 1402, 1173, 1149, 940, 1130, 830, 208, 208, 208, 208, - 208, 992, 1055, 54, 709, 687, 727, 1002, 208, 1000, - 1152, 208, 1003, 1151, 1001, 208, 999, 998, 1004, 208, - 814, 815, 1393, 335, 1386, 987, 256, 257, 1088, 615, - 929, 507, 1391, 939, 81, 976, 938, 1046, 618, 463, - 955, 495, 1038, 1026, 779, 1361, 505, 1360, 1292, 993, - 1017, 51, 996, 496, 1016, 1005, 994, 995, 974, 997, - 1036, 1030, 1236, 892, 1013, 1272, 564, 894, 708, 686, - 818, 507, 914, 915, 247, 918, 919, 1035, 1018, 920, - 253, 254, 81, 81, 1043, 1044, 1045, 937, 1047, 1048, - 1049, 1031, 1032, 729, 730, 936, 922, 1330, 248, 58, - 820, 928, 1329, 1278, 598, 1015, 486, 1408, 1407, 1408, - 704, 81, 509, 1342, 1052, 1264, 710, 60, 62, 602, - 55, 1, 1400, 1199, 1273, 900, 208, 739, 744, 1363, - 1306, 1165, 1071, 851, 335, 81, 842, 69, 433, 68, - 1353, 335, 1058, 850, 849, 1314, 563, 1262, 862, 782, - 783, 1040, 865, 1172, 1358, 1085, 1037, 335, 335, 626, - 624, 625, 335, 335, 335, 335, 335, 335, 623, 628, - 627, 622, 335, 335, 465, 221, 465, 328, 817, 81, - 81, 1125, 992, 1131, 1096, 1114, 1095, 614, 1101, 890, - 465, 510, 72, 1113, 1073, 839, 740, 1072, 896, 480, - 723, 481, 223, 81, 546, 597, 935, 1019, 334, 597, - 516, 1141, 1136, 335, 1137, 333, 81, 716, 81, 81, - 499, 1157, 1328, 1277, 1134, 1150, 975, 1164, 845, 573, - 792, 1156, 265, 273, 731, 286, 283, 1159, 285, 284, - 722, 945, 984, 1163, 520, 1168, 208, 271, 263, 596, - 589, 1169, 1170, 809, 771, 807, 1181, 1182, 806, 1148, - 1144, 595, 1091, 208, 786, 786, 1233, 1339, 726, 81, - 786, 26, 81, 81, 208, 59, 258, 19, 18, 17, - 81, 20, 16, 208, 536, 537, 529, 530, 531, 532, - 533, 534, 535, 528, 930, 931, 538, 501, 15, 14, - 451, 335, 1204, 988, 989, 1192, 30, 598, 598, 598, - 598, 598, 1205, 21, 335, 13, 12, 1193, 1206, 1195, - 11, 1213, 820, 739, 1012, 10, 9, 1090, 8, 7, - 598, 6, 5, 4, 249, 23, 2, 0, 0, 992, - 0, 0, 1237, 0, 0, 0, 0, 1247, 1246, 0, - 0, 0, 0, 744, 81, 0, 0, 0, 0, 957, - 0, 0, 81, 1026, 0, 0, 1256, 335, 0, 335, - 0, 0, 0, 912, 913, 0, 978, 0, 1210, 1211, - 0, 1212, 81, 335, 1214, 0, 1216, 0, 0, 81, - 0, 0, 0, 0, 465, 720, 0, 0, 0, 0, - 1266, 0, 1268, 0, 0, 0, 464, 0, 0, 335, - 0, 0, 597, 597, 597, 597, 597, 0, 0, 0, - 0, 0, 465, 0, 0, 0, 1279, 597, 0, 0, - 0, 0, 0, 81, 81, 597, 81, 0, 0, 0, - 0, 81, 1259, 81, 81, 81, 208, 1191, 1293, 81, - 0, 0, 845, 776, 778, 1300, 1301, 0, 1302, 1303, - 1304, 0, 1311, 1305, 1194, 1295, 0, 81, 0, 796, - 0, 0, 0, 0, 0, 1203, 1134, 0, 0, 1320, - 0, 1321, 1327, 0, 0, 0, 0, 0, 1135, 0, - 51, 0, 0, 0, 0, 0, 0, 1343, 0, 786, - 0, 0, 0, 0, 81, 0, 1350, 1087, 552, 553, - 554, 555, 556, 557, 558, 559, 81, 81, 1351, 0, - 1344, 0, 0, 0, 0, 0, 1367, 1366, 0, 1370, - 0, 0, 1134, 0, 0, 0, 81, 0, 335, 992, - 1375, 0, 0, 0, 0, 0, 0, 208, 0, 0, - 0, 0, 0, 1094, 0, 0, 81, 0, 0, 1127, - 0, 0, 0, 0, 1385, 1230, 493, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1119, 1390, 1392, - 81, 0, 0, 0, 0, 0, 1056, 335, 0, 0, - 0, 0, 0, 1405, 598, 1394, 0, 1158, 0, 0, - 1416, 0, 0, 527, 526, 536, 537, 529, 530, 531, - 532, 533, 534, 535, 528, 335, 0, 538, 0, 0, - 1097, 0, 473, 0, 474, 475, 1232, 476, 0, 479, - 0, 0, 0, 0, 845, 0, 845, 0, 489, 335, - 527, 526, 536, 537, 529, 530, 531, 532, 533, 534, - 535, 528, 0, 0, 538, 1252, 1253, 1254, 0, 0, - 953, 0, 0, 335, 954, 0, 0, 0, 0, 0, - 0, 958, 959, 960, 0, 0, 0, 0, 0, 0, - 786, 0, 973, 1138, 1140, 0, 0, 979, 0, 980, - 981, 982, 983, 465, 0, 0, 0, 0, 1094, 597, - 0, 0, 0, 0, 0, 0, 0, 1140, 0, 0, - 1235, 1007, 0, 0, 0, 0, 0, 563, 0, 0, - 335, 0, 335, 1167, 0, 1248, 0, 0, 1249, 0, - 0, 1251, 0, 0, 0, 0, 0, 0, 0, 0, - 1135, 0, 0, 1296, 0, 0, 0, 0, 1379, 0, - 0, 0, 0, 741, 0, 0, 750, 751, 752, 753, - 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, - 764, 0, 845, 1196, 1324, 0, 1201, 1202, 0, 0, - 0, 0, 0, 0, 335, 0, 0, 498, 0, 0, - 0, 0, 522, 0, 525, 0, 1135, 0, 51, 0, - 539, 540, 541, 542, 543, 544, 545, 1275, 523, 524, - 521, 527, 526, 536, 537, 529, 530, 531, 532, 533, - 534, 535, 528, 206, 0, 538, 235, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 786, 0, 0, - 0, 0, 0, 0, 0, 0, 670, 1100, 0, 0, - 0, 262, 0, 677, 206, 0, 0, 0, 335, 206, - 0, 206, 0, 0, 0, 0, 1261, 0, 0, 694, - 695, 0, 0, 0, 696, 697, 698, 699, 700, 701, - 1227, 493, 0, 0, 702, 703, 335, 0, 0, 0, - 0, 0, 0, 335, 0, 0, 0, 0, 0, 0, - 1403, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1369, 563, 0, 0, 0, 1224, 493, 527, 526, - 536, 537, 529, 530, 531, 532, 533, 534, 535, 528, - 0, 0, 538, 0, 1275, 845, 0, 1297, 1298, 0, - 1299, 0, 0, 0, 0, 1261, 0, 1261, 1261, 1261, - 0, 0, 0, 1167, 527, 526, 536, 537, 529, 530, - 531, 532, 533, 534, 535, 528, 0, 0, 538, 0, - 0, 1261, 0, 0, 0, 0, 0, 0, 0, 0, - 947, 948, 949, 206, 0, 0, 206, 1207, 0, 0, - 0, 0, 206, 0, 1209, 0, 0, 0, 206, 0, - 0, 0, 0, 0, 0, 1218, 1219, 1220, 1357, 1223, - 0, 0, 1226, 0, 1229, 0, 0, 0, 0, 0, - 335, 335, 0, 0, 0, 0, 0, 1239, 1240, 1241, - 0, 1244, 0, 0, 0, 0, 0, 786, 0, 0, - 1377, 0, 0, 0, 0, 0, 0, 0, 1255, 0, - 24, 25, 52, 27, 28, 0, 0, 0, 0, 0, - 1384, 0, 0, 0, 0, 0, 0, 0, 0, 43, - 0, 0, 0, 0, 29, 48, 49, 0, 0, 893, - 0, 895, 0, 0, 1261, 0, 0, 0, 1221, 493, - 0, 0, 0, 0, 38, 921, 0, 0, 54, 0, - 0, 0, 0, 0, 493, 0, 0, 0, 0, 0, - 206, 206, 206, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1290, 527, 526, 536, 537, - 529, 530, 531, 532, 533, 534, 535, 528, 0, 0, - 538, 527, 526, 536, 537, 529, 530, 531, 532, 533, - 534, 535, 528, 0, 0, 538, 0, 0, 0, 31, - 32, 34, 33, 36, 0, 50, 0, 0, 0, 0, - 0, 0, 0, 1331, 1332, 1333, 1334, 1335, 1336, 1337, - 1338, 0, 0, 1231, 1098, 1099, 37, 44, 45, 0, - 0, 46, 47, 35, 1347, 1348, 1349, 1115, 1116, 1117, - 1118, 1228, 1120, 1121, 1122, 1123, 39, 40, 0, 41, - 42, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 268, 1209, 1382, 1089, 852, 1429, 1288, 566, 272, 1323, + 1144, 1018, 1000, 298, 1419, 1178, 829, 1141, 1145, 1001, + 861, 246, 931, 895, 881, 851, 781, 1274, 1151, 1112, + 848, 237, 81, 57, 771, 778, 208, 1157, 338, 208, + 1024, 711, 1069, 1060, 831, 1043, 958, 780, 799, 816, + 299, 51, 616, 865, 748, 498, 504, 439, 615, 827, + 891, 332, 809, 565, 3, 270, 599, 208, 81, 510, + 940, 255, 208, 327, 208, 518, 238, 239, 240, 241, + 329, 580, 244, 56, 1422, 1406, 1417, 1392, 1414, 1210, + 259, 1405, 1391, 1134, 1246, 444, 1334, 1031, 1172, 472, + 1030, 842, 51, 1032, 600, 203, 199, 200, 201, 243, + 251, 1173, 1174, 843, 844, 245, 1356, 531, 530, 540, + 541, 533, 534, 535, 536, 537, 538, 539, 532, 61, + 617, 542, 618, 1186, 1187, 1188, 488, 492, 242, 1051, + 914, 1191, 1189, 874, 489, 486, 487, 1277, 1294, 882, + 1229, 236, 1227, 686, 913, 63, 64, 65, 66, 67, + 195, 1416, 197, 481, 482, 474, 1092, 476, 1091, 684, + 1413, 1383, 1088, 810, 1374, 1433, 457, 866, 1332, 1324, + 1437, 458, 918, 446, 1019, 1021, 197, 685, 1093, 690, + 677, 912, 1326, 868, 1167, 491, 208, 473, 475, 208, + 1166, 868, 1085, 1165, 442, 208, 687, 449, 1087, 210, + 198, 208, 925, 1363, 81, 924, 81, 1257, 81, 81, + 1113, 81, 1044, 81, 554, 555, 202, 1099, 976, 952, + 454, 720, 81, 522, 868, 464, 1195, 532, 849, 542, + 542, 909, 906, 907, 717, 905, 496, 712, 535, 536, + 537, 538, 539, 532, 933, 196, 542, 1115, 440, 517, + 1325, 1020, 81, 440, 469, 1372, 469, 70, 469, 469, + 1342, 469, 1155, 469, 494, 495, 916, 919, 882, 1333, + 1331, 1431, 469, 506, 1432, 471, 1430, 1196, 1357, 867, + 1117, 438, 1121, 451, 1116, 452, 1114, 867, 453, 619, + 1136, 1119, 51, 71, 1086, 1390, 1084, 800, 800, 985, + 1118, 1076, 911, 515, 1049, 507, 1190, 551, 679, 1377, + 553, 512, 1396, 1120, 1122, 208, 208, 208, 713, 517, + 867, 81, 932, 871, 910, 864, 862, 81, 863, 872, + 1074, 1284, 1438, 860, 866, 949, 950, 951, 564, 470, + 568, 569, 570, 571, 572, 573, 574, 575, 576, 875, + 579, 581, 581, 581, 581, 581, 581, 581, 581, 589, + 590, 591, 592, 593, 594, 755, 604, 915, 460, 461, + 462, 1439, 508, 1283, 1249, 598, 1064, 971, 1063, 753, + 754, 752, 917, 582, 583, 584, 585, 586, 587, 588, + 607, 1052, 516, 515, 723, 724, 1398, 1075, 54, 1138, + 22, 613, 1080, 1077, 1070, 1078, 1073, 335, 751, 517, + 1071, 1072, 531, 530, 540, 541, 533, 534, 535, 536, + 537, 538, 539, 532, 1079, 445, 542, 516, 515, 208, + 516, 515, 194, 970, 81, 969, 1373, 1305, 1370, 208, + 208, 81, 516, 515, 517, 208, 1281, 517, 208, 1096, + 274, 208, 516, 515, 772, 208, 773, 81, 81, 517, + 250, 1061, 81, 81, 81, 81, 81, 81, 1033, 517, + 1034, 1212, 81, 81, 540, 541, 533, 534, 535, 536, + 537, 538, 539, 532, 469, 1044, 542, 1039, 738, 740, + 741, 469, 774, 699, 739, 1329, 1415, 324, 325, 696, + 81, 695, 447, 448, 208, 1401, 497, 469, 469, 680, + 81, 678, 469, 469, 469, 469, 469, 469, 725, 1242, + 497, 691, 469, 469, 675, 697, 1329, 1386, 497, 749, + 466, 531, 530, 540, 541, 533, 534, 535, 536, 537, + 538, 539, 532, 1329, 497, 542, 1329, 1364, 1329, 1328, + 1399, 746, 1272, 1271, 81, 1259, 497, 531, 530, 540, + 541, 533, 534, 535, 536, 537, 538, 539, 532, 459, + 727, 542, 790, 794, 1256, 497, 1202, 1201, 801, 1339, + 81, 81, 1338, 744, 959, 742, 1154, 208, 288, 287, + 290, 291, 292, 293, 51, 208, 208, 289, 294, 208, + 208, 1198, 1199, 81, 1198, 1197, 24, 786, 787, 568, + 775, 776, 1335, 796, 964, 497, 81, 1192, 806, 813, + 497, 58, 785, 783, 497, 626, 625, 869, 719, 805, + 995, 807, 808, 783, 996, 1102, 797, 533, 534, 535, + 536, 537, 538, 539, 532, 828, 1025, 542, 610, 604, + 1142, 261, 980, 1154, 54, 883, 884, 885, 837, 835, + 1252, 964, 297, 840, 839, 718, 812, 24, 208, 81, + 335, 81, 1341, 813, 856, 81, 81, 208, 208, 964, + 208, 208, 516, 515, 208, 81, 1025, 978, 897, 813, + 611, 813, 609, 975, 79, 1310, 979, 973, 836, 517, + 609, 208, 24, 208, 208, 1200, 208, 818, 821, 822, + 823, 819, 1035, 820, 824, 54, 252, 1158, 1159, 469, + 552, 469, 893, 894, 841, 989, 988, 964, 609, 1154, + 337, 977, 612, 721, 689, 469, 1090, 974, 54, 1407, + 899, 972, 1380, 1290, 726, 1279, 876, 1264, 896, 746, + 54, 818, 821, 822, 823, 819, 749, 820, 824, 1183, + 1158, 1159, 733, 1411, 54, 1038, 892, 887, 941, 886, + 948, 942, 1424, 1420, 1185, 1161, 603, 1142, 1065, 715, + 693, 1164, 1012, 1010, 1163, 1009, 953, 1013, 1011, 1014, + 1008, 822, 823, 256, 257, 1404, 1098, 954, 937, 511, + 1409, 947, 782, 784, 208, 208, 208, 208, 208, 946, + 499, 1002, 1056, 624, 509, 467, 208, 963, 802, 208, + 1250, 1048, 500, 208, 1379, 1378, 1308, 208, 1046, 1040, + 1286, 902, 692, 826, 511, 982, 945, 984, 253, 254, + 247, 58, 81, 1346, 944, 248, 1036, 1345, 1292, 1025, + 998, 999, 490, 710, 604, 604, 604, 604, 604, 1426, + 1425, 1426, 745, 997, 1015, 513, 1360, 1023, 1027, 828, + 1003, 1022, 1278, 1006, 716, 60, 337, 604, 337, 265, + 337, 337, 785, 337, 1028, 337, 1026, 62, 608, 55, + 81, 81, 1053, 1054, 337, 1, 1418, 1211, 1287, 501, + 505, 1045, 1055, 908, 1057, 1058, 1059, 1041, 1042, 1004, + 1005, 1381, 1007, 1322, 1177, 859, 523, 850, 69, 81, + 437, 1062, 68, 1371, 520, 858, 1068, 857, 1330, 1276, + 870, 1050, 873, 1184, 208, 1376, 1047, 632, 630, 1081, + 631, 469, 629, 81, 634, 633, 628, 221, 330, 825, + 620, 567, 335, 898, 514, 72, 1083, 1082, 904, 484, + 578, 485, 1095, 223, 550, 853, 943, 1029, 336, 469, + 1149, 722, 503, 1344, 1291, 983, 750, 577, 798, 1105, + 273, 1111, 737, 286, 283, 877, 878, 879, 880, 81, + 81, 1124, 1106, 337, 1002, 1123, 285, 284, 1143, 621, + 1146, 888, 889, 890, 728, 746, 1135, 994, 524, 271, + 263, 961, 602, 81, 595, 962, 817, 815, 814, 1160, + 1156, 601, 966, 967, 968, 1101, 81, 1245, 81, 81, + 1355, 1153, 1176, 981, 1162, 732, 26, 1147, 987, 51, + 59, 1168, 990, 991, 992, 993, 258, 19, 1169, 18, + 1180, 1175, 1148, 17, 20, 603, 208, 1171, 16, 603, + 745, 15, 14, 455, 1017, 30, 21, 13, 12, 11, + 10, 9, 8, 208, 1193, 1194, 1248, 1181, 1182, 81, + 7, 6, 81, 81, 208, 5, 4, 249, 23, 2, + 81, 1204, 0, 208, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1205, 0, 1207, 337, 0, 1216, 0, + 0, 0, 0, 337, 531, 530, 540, 541, 533, 534, + 535, 536, 537, 538, 539, 532, 0, 0, 542, 337, + 337, 1225, 1217, 0, 337, 337, 337, 337, 337, 337, + 0, 0, 714, 604, 337, 337, 0, 0, 0, 0, + 0, 1251, 1218, 1002, 0, 556, 557, 558, 559, 560, + 561, 562, 563, 0, 1261, 0, 81, 735, 736, 0, + 1036, 0, 729, 0, 81, 1244, 0, 1260, 0, 0, + 0, 1270, 520, 0, 0, 337, 0, 0, 0, 0, + 0, 853, 0, 0, 81, 0, 0, 0, 0, 0, + 1110, 81, 0, 750, 0, 0, 1266, 1267, 1268, 0, + 0, 0, 1280, 0, 1282, 0, 0, 0, 0, 0, + 567, 0, 0, 788, 789, 0, 777, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 792, 792, 1293, 0, + 0, 0, 792, 0, 469, 0, 0, 81, 81, 0, + 81, 0, 803, 804, 605, 81, 1146, 81, 81, 81, + 208, 1309, 0, 81, 603, 603, 603, 603, 603, 0, + 0, 847, 1316, 0, 0, 337, 1321, 0, 1327, 603, + 0, 81, 1317, 0, 1318, 1319, 1320, 603, 337, 0, + 205, 0, 1104, 1147, 0, 0, 1312, 0, 0, 0, + 0, 1336, 0, 1337, 0, 0, 0, 0, 1343, 1311, + 0, 1361, 0, 0, 1146, 0, 1129, 0, 0, 0, + 81, 328, 1369, 1368, 0, 0, 441, 1340, 443, 0, + 0, 0, 81, 81, 0, 0, 0, 1385, 1384, 0, + 0, 337, 1219, 337, 1388, 0, 0, 920, 921, 1221, + 0, 1147, 0, 51, 81, 0, 0, 337, 0, 1002, + 1230, 1231, 1232, 1393, 1235, 208, 1362, 1238, 0, 1241, + 938, 939, 0, 505, 81, 853, 0, 853, 0, 0, + 1403, 0, 0, 337, 1253, 1254, 1255, 0, 1258, 0, + 0, 0, 0, 0, 1408, 1410, 0, 0, 81, 0, + 0, 0, 0, 0, 747, 1269, 0, 756, 757, 758, + 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, + 769, 770, 1434, 1423, 0, 1412, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 965, 0, 0, 0, 1104, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 450, 0, 986, 456, 0, 0, 0, 1421, 0, 463, + 0, 0, 0, 1222, 1223, 465, 1224, 0, 0, 1226, + 0, 1228, 0, 0, 0, 792, 526, 0, 529, 1239, + 497, 0, 1304, 0, 543, 544, 545, 546, 547, 548, + 549, 0, 527, 528, 525, 531, 530, 540, 541, 533, + 534, 535, 536, 537, 538, 539, 532, 0, 0, 542, + 0, 0, 0, 0, 337, 853, 0, 531, 530, 540, + 541, 533, 534, 535, 536, 537, 538, 539, 532, 1273, + 0, 542, 1347, 1348, 1349, 1350, 1351, 1352, 1353, 1354, + 0, 0, 0, 1358, 1359, 0, 1107, 0, 0, 0, + 1289, 0, 0, 603, 0, 1365, 1366, 1367, 0, 0, + 0, 0, 1066, 337, 1236, 497, 531, 530, 540, 541, + 533, 534, 535, 536, 537, 538, 539, 532, 502, 597, + 542, 606, 0, 0, 0, 1097, 0, 0, 0, 0, + 0, 337, 1389, 0, 0, 0, 0, 0, 0, 1394, + 468, 0, 531, 530, 540, 541, 533, 534, 535, 536, + 537, 538, 539, 532, 206, 337, 542, 235, 1400, 0, + 0, 0, 24, 25, 52, 27, 28, 0, 0, 0, + 0, 0, 0, 955, 956, 957, 0, 1137, 0, 337, + 0, 43, 262, 0, 0, 206, 29, 48, 49, 0, + 206, 0, 206, 0, 0, 0, 0, 0, 792, 0, + 0, 1150, 1152, 0, 1435, 1436, 38, 0, 0, 0, + 54, 0, 0, 0, 0, 0, 0, 1170, 1233, 497, + 0, 1289, 853, 0, 0, 1152, 0, 0, 0, 0, + 0, 0, 0, 627, 0, 0, 0, 0, 337, 0, + 337, 1179, 497, 681, 682, 0, 0, 0, 0, 688, + 0, 0, 328, 0, 0, 694, 531, 530, 540, 541, + 533, 534, 535, 536, 537, 538, 539, 532, 0, 0, + 542, 31, 32, 34, 33, 36, 0, 50, 0, 531, + 530, 540, 541, 533, 534, 535, 536, 537, 538, 539, + 532, 1208, 0, 542, 1213, 1214, 0, 0, 37, 44, + 45, 0, 337, 46, 47, 35, 0, 0, 734, 0, + 0, 0, 0, 0, 206, 0, 0, 206, 39, 40, + 0, 41, 42, 206, 0, 0, 0, 0, 0, 206, + 1247, 0, 0, 0, 0, 0, 218, 0, 0, 567, + 0, 0, 0, 0, 0, 0, 0, 1262, 0, 0, + 1263, 0, 0, 1265, 1243, 0, 477, 792, 478, 479, + 231, 480, 0, 483, 0, 0, 0, 0, 0, 0, + 0, 0, 493, 0, 0, 0, 0, 0, 337, 1108, + 1109, 0, 0, 0, 0, 0, 1275, 0, 0, 0, + 0, 811, 1125, 1126, 1127, 1128, 0, 1130, 1131, 1132, + 1133, 0, 0, 0, 838, 0, 337, 53, 1139, 1140, + 0, 211, 0, 337, 0, 0, 0, 0, 214, 0, + 0, 0, 0, 0, 0, 0, 222, 217, 531, 530, + 540, 541, 533, 534, 535, 536, 537, 538, 539, 532, + 0, 0, 542, 206, 206, 206, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 220, 1313, + 1314, 0, 1315, 0, 230, 0, 0, 1275, 0, 1275, + 1275, 1275, 900, 0, 0, 1179, 0, 0, 0, 0, + 0, 922, 923, 0, 926, 927, 0, 0, 928, 0, + 212, 0, 0, 1275, 530, 540, 541, 533, 534, 535, + 536, 537, 538, 539, 532, 930, 0, 542, 0, 0, + 936, 0, 0, 0, 0, 0, 0, 224, 215, 0, + 225, 226, 227, 229, 0, 228, 234, 1220, 0, 0, + 216, 219, 1375, 213, 233, 232, 0, 1387, 567, 0, + 0, 0, 0, 0, 337, 337, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 206, 0, 0, + 0, 0, 0, 792, 0, 0, 1395, 206, 206, 0, + 0, 0, 0, 206, 0, 960, 206, 0, 0, 206, + 0, 0, 0, 698, 676, 0, 1402, 0, 0, 0, + 0, 683, 0, 0, 649, 531, 530, 540, 541, 533, + 534, 535, 536, 537, 538, 539, 532, 700, 701, 542, + 1275, 0, 702, 703, 704, 705, 706, 707, 0, 0, + 0, 0, 708, 709, 0, 0, 0, 0, 0, 0, 0, 0, 206, 0, 0, 0, 0, 0, 0, 0, - 0, 1371, 206, 206, 1225, 0, 1376, 0, 206, 0, - 0, 206, 0, 0, 206, 0, 0, 0, 692, 0, - 0, 0, 0, 0, 0, 1382, 643, 527, 526, 536, - 537, 529, 530, 531, 532, 533, 534, 535, 528, 0, - 0, 538, 0, 0, 0, 527, 526, 536, 537, 529, - 530, 531, 532, 533, 534, 535, 528, 0, 0, 538, - 0, 0, 0, 0, 0, 53, 0, 206, 0, 1057, - 0, 1417, 1418, 0, 0, 0, 692, 0, 527, 526, - 536, 537, 529, 530, 531, 532, 533, 534, 535, 528, - 0, 0, 538, 0, 0, 0, 0, 1084, 0, 0, - 1208, 0, 0, 0, 631, 527, 526, 536, 537, 529, - 530, 531, 532, 533, 534, 535, 528, 0, 262, 538, - 0, 0, 0, 262, 262, 0, 0, 787, 787, 262, - 1222, 0, 0, 787, 0, 0, 0, 0, 0, 0, - 0, 644, 0, 262, 262, 262, 262, 0, 206, 0, - 0, 0, 0, 0, 0, 0, 206, 825, 0, 0, - 206, 206, 0, 657, 658, 659, 660, 661, 662, 663, - 0, 664, 665, 666, 667, 668, 645, 646, 647, 648, - 629, 630, 0, 0, 632, 0, 633, 634, 635, 636, - 637, 638, 639, 640, 641, 642, 649, 650, 651, 652, - 653, 654, 655, 656, 527, 526, 536, 537, 529, 530, - 531, 532, 533, 534, 535, 528, 0, 0, 538, 0, - 0, 0, 0, 0, 1281, 1282, 952, 1283, 1284, 206, - 1285, 1286, 0, 1287, 1288, 1289, 0, 0, 206, 206, - 0, 206, 206, 0, 0, 206, 527, 526, 536, 537, - 529, 530, 531, 532, 533, 534, 535, 528, 0, 0, - 538, 0, 206, 0, 926, 927, 0, 206, 0, 0, - 0, 0, 692, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 262, 0, 0, 0, 0, 0, + 0, 698, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1295, 1296, 0, 1297, 1298, 0, 1299, + 1300, 0, 1301, 1302, 1303, 0, 0, 0, 1306, 1307, + 0, 0, 637, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 262, 0, 0, 0, 0, 262, 262, + 0, 0, 793, 793, 262, 0, 0, 0, 793, 1240, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 650, + 262, 262, 262, 262, 0, 206, 0, 0, 0, 0, + 0, 0, 0, 206, 833, 0, 0, 206, 206, 0, + 0, 663, 664, 665, 666, 667, 668, 669, 1100, 670, + 671, 672, 673, 674, 651, 652, 653, 654, 635, 636, + 0, 0, 638, 0, 639, 640, 641, 642, 643, 644, + 645, 646, 647, 648, 655, 656, 657, 658, 659, 660, + 661, 662, 0, 531, 530, 540, 541, 533, 534, 535, + 536, 537, 538, 539, 532, 0, 0, 542, 1237, 0, + 0, 0, 0, 0, 0, 0, 206, 0, 0, 0, + 0, 0, 0, 0, 0, 206, 206, 0, 206, 206, + 0, 0, 206, 0, 0, 0, 0, 0, 0, 901, + 0, 903, 0, 0, 0, 1234, 0, 0, 0, 206, + 0, 934, 935, 0, 206, 929, 0, 0, 0, 698, + 0, 1427, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 262, 0, 0, 0, 0, 0, 0, 0, 0, + 1203, 0, 531, 530, 540, 541, 533, 534, 535, 536, + 537, 538, 539, 532, 0, 0, 542, 1206, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1215, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 262, 531, + 530, 540, 541, 533, 534, 535, 536, 537, 538, 539, + 532, 0, 0, 542, 0, 0, 262, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 793, 206, 206, 206, 206, 206, 0, 0, 0, + 0, 0, 0, 0, 1016, 0, 0, 206, 0, 0, + 0, 833, 0, 0, 0, 206, 531, 530, 540, 541, + 533, 534, 535, 536, 537, 538, 539, 532, 0, 0, + 542, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 787, 206, 206, 206, 206, 206, 1271, 0, - 0, 0, 0, 0, 0, 1006, 0, 0, 206, 0, - 0, 0, 825, 0, 0, 0, 206, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1409, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1067, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 206, 0, 0, 0, 0, 0, 0, 1094, + 0, 0, 262, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 262, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 698, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 793, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1397, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 206, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 262, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 262, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 692, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 787, 138, 0, 0, 0, 0, 269, - 0, 0, 0, 102, 0, 266, 0, 0, 0, 119, - 309, 121, 0, 0, 158, 130, 0, 0, 0, 0, - 300, 301, 0, 0, 0, 0, 0, 0, 837, 0, - 54, 0, 0, 267, 288, 287, 290, 291, 292, 293, - 0, 0, 95, 289, 294, 295, 296, 838, 0, 0, - 264, 281, 0, 308, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 206, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 278, 279, 0, 0, 0, 0, 320, - 206, 280, 0, 0, 275, 276, 277, 282, 0, 0, - 0, 206, 0, 0, 0, 0, 0, 108, 0, 0, - 206, 209, 0, 0, 318, 0, 145, 0, 161, 110, - 118, 83, 89, 0, 109, 136, 150, 154, 0, 0, - 0, 98, 0, 152, 140, 174, 0, 141, 151, 122, - 166, 146, 173, 181, 182, 163, 180, 189, 84, 162, - 172, 96, 155, 86, 170, 160, 128, 114, 115, 85, - 787, 149, 101, 106, 100, 137, 167, 168, 99, 192, - 90, 179, 88, 91, 178, 135, 165, 171, 129, 126, - 87, 169, 127, 125, 117, 104, 111, 143, 124, 144, - 112, 132, 131, 133, 0, 0, 0, 159, 176, 193, - 93, 0, 164, 183, 184, 185, 186, 187, 188, 0, - 0, 94, 107, 103, 142, 134, 92, 113, 156, 116, - 123, 148, 191, 139, 153, 97, 175, 157, 310, 319, - 316, 317, 314, 315, 313, 312, 311, 321, 302, 303, - 304, 305, 307, 0, 306, 82, 0, 120, 190, 147, - 105, 177, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 825, 0, 0, 0, 421, 412, 0, - 383, 424, 361, 375, 432, 376, 377, 405, 347, 391, - 138, 373, 0, 364, 342, 370, 343, 362, 385, 102, - 388, 360, 414, 394, 423, 119, 430, 121, 399, 0, - 158, 130, 0, 0, 387, 416, 389, 410, 382, 406, - 352, 398, 425, 374, 403, 426, 0, 0, 0, 80, - 0, 846, 847, 0, 0, 0, 0, 0, 95, 0, - 401, 420, 372, 402, 404, 341, 400, 0, 345, 348, - 431, 418, 367, 368, 1027, 0, 0, 0, 0, 0, - 787, 386, 390, 407, 380, 0, 0, 0, 0, 0, - 0, 0, 0, 365, 206, 397, 0, 0, 0, 349, - 346, 0, 0, 384, 0, 0, 0, 351, 0, 366, - 408, 0, 340, 108, 411, 417, 381, 209, 419, 379, - 378, 422, 145, 0, 161, 110, 118, 83, 89, 0, - 109, 136, 150, 154, 415, 363, 371, 98, 369, 152, - 140, 174, 396, 141, 151, 122, 166, 146, 173, 181, + 0, 0, 0, 0, 206, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 206, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 206, 0, 0, 0, 0, 0, 0, 0, + 0, 206, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 793, 425, 414, 0, 385, 428, 363, + 377, 436, 378, 379, 407, 349, 393, 138, 375, 0, + 366, 344, 372, 345, 364, 387, 102, 390, 362, 416, + 396, 427, 119, 434, 121, 401, 0, 158, 130, 0, + 0, 389, 418, 391, 412, 384, 408, 354, 400, 429, + 376, 405, 430, 0, 0, 0, 80, 0, 854, 855, + 0, 0, 0, 0, 0, 95, 0, 403, 424, 374, + 404, 406, 343, 402, 1285, 347, 350, 435, 420, 369, + 370, 1037, 0, 0, 0, 0, 0, 0, 388, 392, + 409, 382, 0, 0, 0, 0, 0, 0, 0, 0, + 367, 0, 399, 0, 0, 0, 351, 348, 0, 0, + 386, 0, 0, 0, 353, 0, 368, 410, 833, 342, + 108, 413, 419, 383, 209, 423, 381, 380, 426, 145, + 0, 161, 110, 118, 83, 89, 0, 109, 136, 150, + 154, 417, 365, 373, 98, 371, 152, 140, 174, 398, + 141, 151, 122, 166, 146, 173, 181, 182, 163, 180, + 189, 84, 162, 172, 96, 155, 86, 170, 160, 128, + 114, 115, 85, 0, 149, 101, 106, 100, 137, 167, + 168, 99, 192, 90, 179, 88, 91, 178, 135, 165, + 171, 129, 126, 87, 169, 127, 125, 117, 104, 111, + 143, 124, 144, 112, 132, 131, 133, 0, 346, 793, + 159, 176, 193, 93, 361, 164, 183, 184, 185, 186, + 187, 188, 0, 206, 94, 107, 103, 142, 134, 92, + 113, 156, 116, 123, 148, 191, 139, 153, 97, 175, + 157, 357, 360, 355, 356, 394, 395, 431, 432, 433, + 411, 352, 0, 358, 359, 0, 415, 421, 422, 397, + 82, 0, 120, 190, 147, 105, 177, 425, 414, 0, + 385, 428, 363, 377, 436, 378, 379, 407, 349, 393, + 138, 375, 0, 366, 344, 372, 345, 364, 387, 102, + 390, 362, 416, 396, 427, 119, 434, 121, 401, 0, + 158, 130, 0, 0, 389, 418, 391, 412, 384, 408, + 354, 400, 429, 376, 405, 430, 0, 0, 0, 80, + 0, 854, 855, 0, 0, 0, 0, 0, 95, 0, + 403, 424, 374, 404, 406, 343, 402, 0, 347, 350, + 435, 420, 369, 370, 0, 0, 0, 0, 0, 0, + 0, 388, 392, 409, 382, 0, 0, 0, 0, 0, + 0, 0, 0, 367, 0, 399, 0, 0, 0, 351, + 348, 0, 0, 386, 0, 0, 0, 353, 0, 368, + 410, 0, 342, 108, 413, 419, 383, 209, 423, 381, + 380, 426, 145, 0, 161, 110, 118, 83, 89, 0, + 109, 136, 150, 154, 417, 365, 373, 98, 371, 152, + 140, 174, 398, 141, 151, 122, 166, 146, 173, 181, 182, 163, 180, 189, 84, 162, 172, 96, 155, 86, 170, 160, 128, 114, 115, 85, 0, 149, 101, 106, 100, 137, 167, 168, 99, 192, 90, 179, 88, 91, 178, 135, 165, 171, 129, 126, 87, 169, 127, 125, 117, 104, 111, 143, 124, 144, 112, 132, 131, 133, - 0, 344, 0, 159, 176, 193, 93, 359, 164, 183, + 0, 346, 0, 159, 176, 193, 93, 361, 164, 183, 184, 185, 186, 187, 188, 0, 0, 94, 107, 103, 142, 134, 92, 113, 156, 116, 123, 148, 191, 139, - 153, 97, 175, 157, 355, 358, 353, 354, 392, 393, - 427, 428, 429, 409, 350, 0, 356, 357, 0, 413, - 395, 82, 0, 120, 190, 147, 105, 177, 421, 412, - 0, 383, 424, 361, 375, 432, 376, 377, 405, 347, - 391, 138, 373, 0, 364, 342, 370, 343, 362, 385, - 102, 388, 360, 414, 394, 423, 119, 430, 121, 399, - 0, 158, 130, 0, 0, 387, 416, 389, 410, 382, - 406, 352, 398, 425, 374, 403, 426, 0, 0, 0, - 80, 0, 846, 847, 0, 0, 0, 0, 0, 95, - 0, 401, 420, 372, 402, 404, 341, 400, 0, 345, - 348, 431, 418, 367, 368, 0, 0, 0, 0, 0, - 0, 0, 386, 390, 407, 380, 0, 0, 0, 0, - 0, 0, 0, 0, 365, 0, 397, 0, 0, 0, - 349, 346, 0, 0, 384, 0, 0, 0, 351, 0, - 366, 408, 0, 340, 108, 411, 417, 381, 209, 419, - 379, 378, 422, 145, 0, 161, 110, 118, 83, 89, - 0, 109, 136, 150, 154, 415, 363, 371, 98, 369, - 152, 140, 174, 396, 141, 151, 122, 166, 146, 173, - 181, 182, 163, 180, 189, 84, 162, 172, 96, 155, - 86, 170, 160, 128, 114, 115, 85, 0, 149, 101, - 106, 100, 137, 167, 168, 99, 192, 90, 179, 88, - 91, 178, 135, 165, 171, 129, 126, 87, 169, 127, - 125, 117, 104, 111, 143, 124, 144, 112, 132, 131, - 133, 0, 344, 0, 159, 176, 193, 93, 359, 164, - 183, 184, 185, 186, 187, 188, 0, 0, 94, 107, - 103, 142, 134, 92, 113, 156, 116, 123, 148, 191, - 139, 153, 97, 175, 157, 355, 358, 353, 354, 392, - 393, 427, 428, 429, 409, 350, 0, 356, 357, 0, - 413, 395, 82, 0, 120, 190, 147, 105, 177, 421, - 412, 0, 383, 424, 361, 375, 432, 376, 377, 405, - 347, 391, 138, 373, 0, 364, 342, 370, 343, 362, - 385, 102, 388, 360, 414, 394, 423, 119, 430, 121, - 399, 0, 158, 130, 0, 0, 387, 416, 389, 410, - 382, 406, 352, 398, 425, 374, 403, 426, 54, 0, - 0, 80, 0, 0, 0, 0, 0, 0, 0, 0, - 95, 0, 401, 420, 372, 402, 404, 341, 400, 0, - 345, 348, 431, 418, 367, 368, 0, 0, 0, 0, - 0, 0, 0, 386, 390, 407, 380, 0, 0, 0, - 0, 0, 0, 0, 0, 365, 0, 397, 0, 0, - 0, 349, 346, 0, 0, 384, 0, 0, 0, 351, - 0, 366, 408, 0, 340, 108, 411, 417, 381, 209, - 419, 379, 378, 422, 145, 0, 161, 110, 118, 83, - 89, 0, 109, 136, 150, 154, 415, 363, 371, 98, - 369, 152, 140, 174, 396, 141, 151, 122, 166, 146, - 173, 181, 182, 163, 180, 189, 84, 162, 172, 96, - 155, 86, 170, 160, 128, 114, 115, 85, 0, 149, - 101, 106, 100, 137, 167, 168, 99, 192, 90, 179, - 88, 91, 178, 135, 165, 171, 129, 126, 87, 169, - 127, 125, 117, 104, 111, 143, 124, 144, 112, 132, - 131, 133, 0, 344, 0, 159, 176, 193, 93, 359, - 164, 183, 184, 185, 186, 187, 188, 0, 0, 94, - 107, 103, 142, 134, 92, 113, 156, 116, 123, 148, - 191, 139, 153, 97, 175, 157, 355, 358, 353, 354, - 392, 393, 427, 428, 429, 409, 350, 0, 356, 357, - 0, 413, 395, 82, 0, 120, 190, 147, 105, 177, - 421, 412, 0, 383, 424, 361, 375, 432, 376, 377, - 405, 347, 391, 138, 373, 0, 364, 342, 370, 343, - 362, 385, 102, 388, 360, 414, 394, 423, 119, 430, - 121, 399, 0, 158, 130, 0, 0, 387, 416, 389, - 410, 382, 406, 352, 398, 425, 374, 403, 426, 0, + 153, 97, 175, 157, 357, 360, 355, 356, 394, 395, + 431, 432, 433, 411, 352, 0, 358, 359, 0, 415, + 421, 422, 397, 82, 0, 120, 190, 147, 105, 177, + 425, 414, 0, 385, 428, 363, 377, 436, 378, 379, + 407, 349, 393, 138, 375, 0, 366, 344, 372, 345, + 364, 387, 102, 390, 362, 416, 396, 427, 119, 434, + 121, 401, 0, 158, 130, 0, 0, 389, 418, 391, + 412, 384, 408, 354, 400, 429, 376, 405, 430, 54, 0, 0, 80, 0, 0, 0, 0, 0, 0, 0, - 0, 95, 0, 401, 420, 372, 402, 404, 341, 400, - 0, 345, 348, 431, 418, 367, 368, 0, 0, 0, - 0, 0, 0, 0, 386, 390, 407, 380, 0, 0, - 0, 0, 0, 0, 1093, 0, 365, 0, 397, 0, - 0, 0, 349, 346, 0, 0, 384, 0, 0, 0, - 351, 0, 366, 408, 0, 340, 108, 411, 417, 381, - 209, 419, 379, 378, 422, 145, 0, 161, 110, 118, - 83, 89, 0, 109, 136, 150, 154, 415, 363, 371, - 98, 369, 152, 140, 174, 396, 141, 151, 122, 166, + 0, 95, 0, 403, 424, 374, 404, 406, 343, 402, + 0, 347, 350, 435, 420, 369, 370, 0, 0, 0, + 0, 0, 0, 0, 388, 392, 409, 382, 0, 0, + 0, 0, 0, 0, 0, 0, 367, 0, 399, 0, + 0, 0, 351, 348, 0, 0, 386, 0, 0, 0, + 353, 0, 368, 410, 0, 342, 108, 413, 419, 383, + 209, 423, 381, 380, 426, 145, 0, 161, 110, 118, + 83, 89, 0, 109, 136, 150, 154, 417, 365, 373, + 98, 371, 152, 140, 174, 398, 141, 151, 122, 166, 146, 173, 181, 182, 163, 180, 189, 84, 162, 172, 96, 155, 86, 170, 160, 128, 114, 115, 85, 0, 149, 101, 106, 100, 137, 167, 168, 99, 192, 90, 179, 88, 91, 178, 135, 165, 171, 129, 126, 87, 169, 127, 125, 117, 104, 111, 143, 124, 144, 112, - 132, 131, 133, 0, 344, 0, 159, 176, 193, 93, - 359, 164, 183, 184, 185, 186, 187, 188, 0, 0, + 132, 131, 133, 0, 346, 0, 159, 176, 193, 93, + 361, 164, 183, 184, 185, 186, 187, 188, 0, 0, 94, 107, 103, 142, 134, 92, 113, 156, 116, 123, - 148, 191, 139, 153, 97, 175, 157, 355, 358, 353, - 354, 392, 393, 427, 428, 429, 409, 350, 0, 356, - 357, 0, 413, 395, 82, 0, 120, 190, 147, 105, - 177, 421, 412, 0, 383, 424, 361, 375, 432, 376, - 377, 405, 347, 391, 138, 373, 0, 364, 342, 370, - 343, 362, 385, 102, 388, 360, 414, 394, 423, 119, - 430, 121, 399, 0, 158, 130, 0, 0, 387, 416, - 389, 410, 382, 406, 352, 398, 425, 374, 403, 426, - 0, 0, 0, 267, 0, 0, 0, 0, 0, 0, - 0, 0, 95, 0, 401, 420, 372, 402, 404, 341, - 400, 0, 345, 348, 431, 418, 367, 368, 0, 0, - 0, 0, 0, 0, 0, 386, 390, 407, 380, 0, - 0, 0, 0, 0, 0, 737, 0, 365, 0, 397, - 0, 0, 0, 349, 346, 0, 0, 384, 0, 0, - 0, 351, 0, 366, 408, 0, 340, 108, 411, 417, - 381, 209, 419, 379, 378, 422, 145, 0, 161, 110, - 118, 83, 89, 0, 109, 136, 150, 154, 415, 363, - 371, 98, 369, 152, 140, 174, 396, 141, 151, 122, - 166, 146, 173, 181, 182, 163, 180, 189, 84, 162, - 172, 96, 155, 86, 170, 160, 128, 114, 115, 85, - 0, 149, 101, 106, 100, 137, 167, 168, 99, 192, - 90, 179, 88, 91, 178, 135, 165, 171, 129, 126, - 87, 169, 127, 125, 117, 104, 111, 143, 124, 144, - 112, 132, 131, 133, 0, 344, 0, 159, 176, 193, - 93, 359, 164, 183, 184, 185, 186, 187, 188, 0, - 0, 94, 107, 103, 142, 134, 92, 113, 156, 116, - 123, 148, 191, 139, 153, 97, 175, 157, 355, 358, - 353, 354, 392, 393, 427, 428, 429, 409, 350, 0, - 356, 357, 0, 413, 395, 82, 0, 120, 190, 147, - 105, 177, 421, 412, 0, 383, 424, 361, 375, 432, - 376, 377, 405, 347, 391, 138, 373, 0, 364, 342, - 370, 343, 362, 385, 102, 388, 360, 414, 394, 423, - 119, 430, 121, 399, 0, 158, 130, 0, 0, 387, - 416, 389, 410, 382, 406, 352, 398, 425, 374, 403, - 426, 0, 0, 0, 80, 0, 0, 0, 0, 0, - 0, 0, 0, 95, 0, 401, 420, 372, 402, 404, - 341, 400, 0, 345, 348, 431, 418, 367, 368, 0, - 0, 0, 0, 0, 0, 0, 386, 390, 407, 380, - 0, 0, 0, 0, 0, 0, 0, 0, 365, 0, - 397, 0, 0, 0, 349, 346, 0, 0, 384, 0, - 0, 0, 351, 0, 366, 408, 0, 340, 108, 411, - 417, 381, 209, 419, 379, 378, 422, 145, 0, 161, - 110, 118, 83, 89, 0, 109, 136, 150, 154, 415, - 363, 371, 98, 369, 152, 140, 174, 396, 141, 151, - 122, 166, 146, 173, 181, 182, 163, 180, 189, 84, - 162, 172, 96, 155, 86, 170, 160, 128, 114, 115, - 85, 0, 149, 101, 106, 100, 137, 167, 168, 99, - 192, 90, 179, 88, 91, 178, 135, 165, 171, 129, - 126, 87, 169, 127, 125, 117, 104, 111, 143, 124, - 144, 112, 132, 131, 133, 0, 344, 0, 159, 176, - 193, 93, 359, 164, 183, 184, 185, 186, 187, 188, - 0, 0, 94, 107, 103, 142, 134, 92, 113, 156, - 116, 123, 148, 191, 139, 153, 97, 175, 157, 355, - 358, 353, 354, 392, 393, 427, 428, 429, 409, 350, - 0, 356, 357, 0, 413, 395, 82, 0, 120, 190, - 147, 105, 177, 421, 412, 0, 383, 424, 361, 375, - 432, 376, 377, 405, 347, 391, 138, 373, 0, 364, - 342, 370, 343, 362, 385, 102, 388, 360, 414, 394, - 423, 119, 430, 121, 399, 0, 158, 130, 0, 0, - 387, 416, 389, 410, 382, 406, 352, 398, 425, 374, - 403, 426, 0, 0, 0, 267, 0, 0, 0, 0, - 0, 0, 0, 0, 95, 0, 401, 420, 372, 402, - 404, 341, 400, 0, 345, 348, 431, 418, 367, 368, - 0, 0, 0, 0, 0, 0, 0, 386, 390, 407, - 380, 0, 0, 0, 0, 0, 0, 0, 0, 365, - 0, 397, 0, 0, 0, 349, 346, 0, 0, 384, - 0, 0, 0, 351, 0, 366, 408, 0, 340, 108, - 411, 417, 381, 209, 419, 379, 378, 422, 145, 0, + 148, 191, 139, 153, 97, 175, 157, 357, 360, 355, + 356, 394, 395, 431, 432, 433, 411, 352, 0, 358, + 359, 0, 415, 421, 422, 397, 82, 0, 120, 190, + 147, 105, 177, 425, 414, 0, 385, 428, 363, 377, + 436, 378, 379, 407, 349, 393, 138, 375, 0, 366, + 344, 372, 345, 364, 387, 102, 390, 362, 416, 396, + 427, 119, 434, 121, 401, 0, 158, 130, 0, 0, + 389, 418, 391, 412, 384, 408, 354, 400, 429, 376, + 405, 430, 0, 0, 0, 80, 0, 0, 0, 0, + 0, 0, 0, 0, 95, 0, 403, 424, 374, 404, + 406, 343, 402, 0, 347, 350, 435, 420, 369, 370, + 0, 0, 0, 0, 0, 0, 0, 388, 392, 409, + 382, 0, 0, 0, 0, 0, 0, 1103, 0, 367, + 0, 399, 0, 0, 0, 351, 348, 0, 0, 386, + 0, 0, 0, 353, 0, 368, 410, 0, 342, 108, + 413, 419, 383, 209, 423, 381, 380, 426, 145, 0, 161, 110, 118, 83, 89, 0, 109, 136, 150, 154, - 415, 363, 371, 98, 369, 152, 140, 174, 396, 141, + 417, 365, 373, 98, 371, 152, 140, 174, 398, 141, 151, 122, 166, 146, 173, 181, 182, 163, 180, 189, 84, 162, 172, 96, 155, 86, 170, 160, 128, 114, 115, 85, 0, 149, 101, 106, 100, 137, 167, 168, 99, 192, 90, 179, 88, 91, 178, 135, 165, 171, 129, 126, 87, 169, 127, 125, 117, 104, 111, 143, - 124, 144, 112, 132, 131, 133, 0, 344, 0, 159, - 176, 193, 93, 359, 164, 183, 184, 185, 186, 187, + 124, 144, 112, 132, 131, 133, 0, 346, 0, 159, + 176, 193, 93, 361, 164, 183, 184, 185, 186, 187, 188, 0, 0, 94, 107, 103, 142, 134, 92, 113, 156, 116, 123, 148, 191, 139, 153, 97, 175, 157, - 355, 358, 353, 354, 392, 393, 427, 428, 429, 409, - 350, 0, 356, 357, 0, 413, 395, 82, 0, 120, - 190, 147, 105, 177, 421, 412, 0, 383, 424, 361, - 375, 432, 376, 377, 405, 347, 391, 138, 373, 0, - 364, 342, 370, 343, 362, 385, 102, 388, 360, 414, - 394, 423, 119, 430, 121, 399, 0, 158, 130, 0, - 0, 387, 416, 389, 410, 382, 406, 352, 398, 425, - 374, 403, 426, 0, 0, 0, 80, 0, 0, 0, - 0, 0, 0, 0, 0, 95, 0, 401, 420, 372, - 402, 404, 341, 400, 0, 345, 348, 431, 418, 367, - 368, 0, 0, 0, 0, 0, 0, 0, 386, 390, - 407, 380, 0, 0, 0, 0, 0, 0, 0, 0, - 365, 0, 397, 0, 0, 0, 349, 346, 0, 0, - 384, 0, 0, 0, 351, 0, 366, 408, 0, 340, - 108, 411, 417, 381, 209, 419, 379, 378, 422, 145, + 357, 360, 355, 356, 394, 395, 431, 432, 433, 411, + 352, 0, 358, 359, 0, 415, 421, 422, 397, 82, + 0, 120, 190, 147, 105, 177, 425, 414, 0, 385, + 428, 363, 377, 436, 378, 379, 407, 349, 393, 138, + 375, 0, 366, 344, 372, 345, 364, 387, 102, 390, + 362, 416, 396, 427, 119, 434, 121, 401, 0, 158, + 130, 0, 0, 389, 418, 391, 412, 384, 408, 354, + 400, 429, 376, 405, 430, 0, 0, 0, 267, 0, + 0, 0, 0, 0, 0, 0, 0, 95, 0, 403, + 424, 374, 404, 406, 343, 402, 0, 347, 350, 435, + 420, 369, 370, 0, 0, 0, 0, 0, 0, 0, + 388, 392, 409, 382, 0, 0, 0, 0, 0, 0, + 743, 0, 367, 0, 399, 0, 0, 0, 351, 348, + 0, 0, 386, 0, 0, 0, 353, 0, 368, 410, + 0, 342, 108, 413, 419, 383, 209, 423, 381, 380, + 426, 145, 0, 161, 110, 118, 83, 89, 0, 109, + 136, 150, 154, 417, 365, 373, 98, 371, 152, 140, + 174, 398, 141, 151, 122, 166, 146, 173, 181, 182, + 163, 180, 189, 84, 162, 172, 96, 155, 86, 170, + 160, 128, 114, 115, 85, 0, 149, 101, 106, 100, + 137, 167, 168, 99, 192, 90, 179, 88, 91, 178, + 135, 165, 171, 129, 126, 87, 169, 127, 125, 117, + 104, 111, 143, 124, 144, 112, 132, 131, 133, 0, + 346, 0, 159, 176, 193, 93, 361, 164, 183, 184, + 185, 186, 187, 188, 0, 0, 94, 107, 103, 142, + 134, 92, 113, 156, 116, 123, 148, 191, 139, 153, + 97, 175, 157, 357, 360, 355, 356, 394, 395, 431, + 432, 433, 411, 352, 0, 358, 359, 0, 415, 421, + 422, 397, 82, 0, 120, 190, 147, 105, 177, 425, + 414, 0, 385, 428, 363, 377, 436, 378, 379, 407, + 349, 393, 138, 375, 0, 366, 344, 372, 345, 364, + 387, 102, 390, 362, 416, 396, 427, 119, 434, 121, + 401, 0, 158, 130, 0, 0, 389, 418, 391, 412, + 384, 408, 354, 400, 429, 376, 405, 430, 0, 0, + 0, 80, 0, 0, 0, 0, 0, 0, 0, 0, + 95, 0, 403, 424, 374, 404, 406, 343, 402, 0, + 347, 350, 435, 420, 369, 370, 0, 0, 0, 0, + 0, 0, 0, 388, 392, 409, 382, 0, 0, 0, + 0, 0, 0, 0, 0, 367, 0, 399, 0, 0, + 0, 351, 348, 0, 0, 386, 0, 0, 0, 353, + 0, 368, 410, 0, 342, 108, 413, 419, 383, 209, + 423, 381, 380, 426, 145, 0, 161, 110, 118, 83, + 89, 0, 109, 136, 150, 154, 417, 365, 373, 98, + 371, 152, 140, 174, 398, 141, 151, 122, 166, 146, + 173, 181, 182, 163, 180, 189, 84, 162, 172, 96, + 155, 86, 170, 160, 128, 114, 115, 85, 0, 149, + 101, 106, 100, 137, 167, 168, 99, 192, 90, 179, + 88, 91, 178, 135, 165, 171, 129, 126, 87, 169, + 127, 125, 117, 104, 111, 143, 124, 144, 112, 132, + 131, 133, 0, 346, 0, 159, 176, 193, 93, 361, + 164, 183, 184, 185, 186, 187, 188, 0, 0, 94, + 107, 103, 142, 134, 92, 113, 156, 116, 123, 148, + 191, 139, 153, 97, 175, 157, 357, 360, 355, 356, + 394, 395, 431, 432, 433, 411, 352, 0, 358, 359, + 0, 415, 421, 422, 397, 82, 0, 120, 190, 147, + 105, 177, 425, 414, 0, 385, 428, 363, 377, 436, + 378, 379, 407, 349, 393, 138, 375, 0, 366, 344, + 372, 345, 364, 387, 102, 390, 362, 416, 396, 427, + 119, 434, 121, 401, 0, 158, 130, 0, 0, 389, + 418, 391, 412, 384, 408, 354, 400, 429, 376, 405, + 430, 0, 0, 0, 267, 0, 0, 0, 0, 0, + 0, 0, 0, 95, 0, 403, 424, 374, 404, 406, + 343, 402, 0, 347, 350, 435, 420, 369, 370, 0, + 0, 0, 0, 0, 0, 0, 388, 392, 409, 382, + 0, 0, 0, 0, 0, 0, 0, 0, 367, 0, + 399, 0, 0, 0, 351, 348, 0, 0, 386, 0, + 0, 0, 353, 0, 368, 410, 0, 342, 108, 413, + 419, 383, 209, 423, 381, 380, 426, 145, 0, 161, + 110, 118, 83, 89, 0, 109, 136, 150, 154, 417, + 365, 373, 98, 371, 152, 140, 174, 398, 141, 151, + 122, 166, 146, 173, 181, 182, 163, 180, 189, 84, + 162, 172, 96, 155, 86, 170, 160, 128, 114, 115, + 85, 0, 149, 101, 106, 100, 137, 167, 168, 99, + 192, 90, 179, 88, 91, 178, 135, 165, 171, 129, + 126, 87, 169, 127, 125, 117, 104, 111, 143, 124, + 144, 112, 132, 131, 133, 0, 346, 0, 159, 176, + 193, 93, 361, 164, 183, 184, 185, 186, 187, 188, + 0, 0, 94, 107, 103, 142, 134, 92, 113, 156, + 116, 123, 148, 191, 139, 153, 97, 175, 157, 357, + 360, 355, 356, 394, 395, 431, 432, 433, 411, 352, + 0, 358, 359, 0, 415, 421, 422, 397, 82, 0, + 120, 190, 147, 105, 177, 425, 414, 0, 385, 428, + 363, 377, 436, 378, 379, 407, 349, 393, 138, 375, + 0, 366, 344, 372, 345, 364, 387, 102, 390, 362, + 416, 396, 427, 119, 434, 121, 401, 0, 158, 130, + 0, 0, 389, 418, 391, 412, 384, 408, 354, 400, + 429, 376, 405, 430, 0, 0, 0, 80, 0, 0, + 0, 0, 0, 0, 0, 0, 95, 0, 403, 424, + 374, 404, 406, 343, 402, 0, 347, 350, 435, 420, + 369, 370, 0, 0, 0, 0, 0, 0, 0, 388, + 392, 409, 382, 0, 0, 0, 0, 0, 0, 0, + 0, 367, 0, 399, 0, 0, 0, 351, 348, 0, + 0, 386, 0, 0, 0, 353, 0, 368, 410, 0, + 342, 108, 413, 419, 383, 209, 423, 381, 380, 426, + 145, 0, 161, 110, 118, 83, 89, 0, 109, 136, + 150, 154, 417, 365, 373, 98, 371, 152, 140, 174, + 398, 141, 151, 122, 166, 146, 173, 181, 182, 163, + 180, 189, 84, 162, 172, 96, 155, 86, 170, 160, + 128, 114, 115, 85, 0, 149, 101, 106, 100, 137, + 167, 168, 99, 192, 90, 179, 88, 340, 178, 135, + 165, 171, 129, 126, 87, 169, 127, 125, 117, 104, + 111, 143, 124, 144, 112, 132, 131, 133, 0, 346, + 0, 159, 176, 193, 93, 361, 164, 183, 184, 185, + 186, 187, 188, 0, 0, 94, 107, 103, 142, 341, + 339, 113, 156, 116, 123, 148, 191, 139, 153, 97, + 175, 157, 357, 360, 355, 356, 394, 395, 431, 432, + 433, 411, 352, 0, 358, 359, 0, 415, 421, 422, + 397, 82, 0, 120, 190, 147, 105, 177, 425, 414, + 0, 385, 428, 363, 377, 436, 378, 379, 407, 349, + 393, 138, 375, 0, 366, 344, 372, 345, 364, 387, + 102, 390, 362, 416, 396, 427, 119, 434, 121, 401, + 0, 158, 130, 0, 0, 389, 418, 391, 412, 384, + 408, 354, 400, 429, 376, 405, 430, 0, 0, 0, + 207, 0, 0, 0, 0, 0, 0, 0, 0, 95, + 0, 403, 424, 374, 404, 406, 343, 402, 0, 347, + 350, 435, 420, 369, 370, 0, 0, 0, 0, 0, + 0, 0, 388, 392, 409, 382, 0, 0, 0, 0, + 0, 0, 0, 0, 367, 0, 399, 0, 0, 0, + 351, 348, 0, 0, 386, 0, 0, 0, 353, 0, + 368, 410, 0, 342, 108, 413, 419, 383, 209, 423, + 381, 380, 426, 145, 0, 161, 110, 118, 83, 89, + 0, 109, 136, 150, 154, 417, 365, 373, 98, 371, + 152, 140, 174, 398, 141, 151, 122, 166, 146, 173, + 181, 182, 163, 180, 189, 84, 162, 172, 96, 155, + 86, 170, 160, 128, 114, 115, 85, 0, 149, 101, + 106, 100, 137, 167, 168, 99, 192, 90, 179, 88, + 91, 178, 135, 165, 171, 129, 126, 87, 169, 127, + 125, 117, 104, 111, 143, 124, 144, 112, 132, 131, + 133, 0, 346, 0, 159, 176, 193, 93, 361, 164, + 183, 184, 185, 186, 187, 188, 0, 0, 94, 107, + 103, 142, 134, 92, 113, 156, 116, 123, 148, 191, + 139, 153, 97, 175, 157, 357, 360, 355, 356, 394, + 395, 431, 432, 433, 411, 352, 0, 358, 359, 0, + 415, 421, 422, 397, 82, 0, 120, 190, 147, 105, + 177, 425, 414, 0, 385, 428, 363, 377, 436, 378, + 379, 407, 349, 393, 138, 375, 0, 366, 344, 372, + 345, 364, 387, 102, 390, 362, 416, 396, 427, 119, + 434, 121, 401, 0, 158, 130, 0, 0, 389, 418, + 391, 412, 384, 408, 354, 400, 429, 376, 405, 430, + 0, 0, 0, 80, 0, 0, 0, 0, 0, 0, + 0, 0, 95, 0, 403, 424, 374, 404, 406, 343, + 402, 0, 347, 350, 435, 420, 369, 370, 0, 0, + 0, 0, 0, 0, 0, 388, 392, 409, 382, 0, + 0, 0, 0, 0, 0, 0, 0, 367, 0, 399, + 0, 0, 0, 351, 348, 0, 0, 386, 0, 0, + 0, 353, 0, 368, 410, 0, 342, 108, 413, 419, + 383, 209, 423, 381, 380, 426, 145, 0, 161, 110, + 118, 83, 89, 0, 109, 136, 150, 154, 417, 365, + 373, 98, 371, 152, 140, 174, 398, 141, 151, 122, + 166, 146, 173, 181, 182, 163, 180, 189, 84, 162, + 614, 96, 155, 86, 170, 160, 128, 114, 115, 85, + 0, 149, 101, 106, 100, 137, 167, 168, 99, 192, + 90, 179, 88, 340, 178, 135, 165, 171, 129, 126, + 87, 169, 127, 125, 117, 104, 111, 143, 124, 144, + 112, 132, 131, 133, 0, 346, 0, 159, 176, 193, + 93, 361, 164, 183, 184, 185, 186, 187, 188, 0, + 0, 94, 107, 103, 142, 341, 339, 113, 156, 116, + 123, 148, 191, 139, 153, 97, 175, 157, 357, 360, + 355, 356, 394, 395, 431, 432, 433, 411, 352, 0, + 358, 359, 0, 415, 421, 422, 397, 82, 0, 120, + 190, 147, 105, 177, 425, 414, 0, 385, 428, 363, + 377, 436, 378, 379, 407, 349, 393, 138, 375, 0, + 366, 344, 372, 345, 364, 387, 102, 390, 362, 416, + 396, 427, 119, 434, 121, 401, 0, 158, 130, 0, + 0, 389, 418, 391, 412, 384, 408, 354, 400, 429, + 376, 405, 430, 0, 0, 0, 80, 0, 0, 0, + 0, 0, 0, 0, 0, 95, 0, 403, 424, 374, + 404, 406, 343, 402, 0, 347, 350, 435, 420, 369, + 370, 0, 0, 0, 0, 0, 0, 0, 388, 392, + 409, 382, 0, 0, 0, 0, 0, 0, 0, 0, + 367, 0, 399, 0, 0, 0, 351, 348, 0, 0, + 386, 0, 0, 0, 353, 0, 368, 410, 0, 342, + 108, 413, 419, 383, 209, 423, 381, 380, 426, 145, + 0, 161, 110, 118, 83, 89, 0, 109, 136, 150, + 154, 417, 365, 373, 98, 371, 152, 140, 174, 398, + 141, 151, 122, 166, 146, 173, 181, 182, 163, 180, + 189, 84, 162, 331, 96, 155, 86, 170, 160, 128, + 114, 115, 85, 0, 149, 101, 106, 100, 137, 167, + 168, 99, 192, 90, 179, 88, 340, 178, 135, 165, + 171, 129, 126, 87, 169, 127, 125, 117, 104, 111, + 143, 124, 144, 112, 132, 131, 133, 0, 346, 0, + 159, 176, 193, 93, 361, 164, 183, 184, 185, 186, + 187, 188, 0, 0, 94, 107, 103, 142, 341, 339, + 334, 333, 116, 123, 148, 191, 139, 153, 97, 175, + 157, 357, 360, 355, 356, 394, 395, 431, 432, 433, + 411, 352, 0, 358, 359, 0, 415, 421, 422, 397, + 82, 0, 120, 190, 147, 105, 177, 138, 0, 0, + 0, 0, 269, 0, 0, 0, 102, 0, 266, 0, + 0, 0, 119, 309, 121, 0, 0, 158, 130, 0, + 0, 0, 0, 300, 301, 0, 0, 0, 0, 0, + 0, 845, 0, 54, 0, 0, 267, 288, 287, 290, + 291, 292, 293, 0, 0, 95, 289, 294, 295, 296, + 846, 0, 0, 264, 281, 0, 308, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 278, 279, 0, 0, + 0, 0, 322, 0, 280, 0, 0, 275, 276, 277, + 282, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 108, 0, 0, 0, 209, 0, 0, 320, 0, 145, + 0, 161, 110, 118, 83, 89, 0, 109, 136, 150, + 154, 0, 0, 0, 98, 0, 152, 140, 174, 0, + 141, 151, 122, 166, 146, 173, 181, 182, 163, 180, + 189, 84, 162, 172, 96, 155, 86, 170, 160, 128, + 114, 115, 85, 0, 149, 101, 106, 100, 137, 167, + 168, 99, 192, 90, 179, 88, 91, 178, 135, 165, + 171, 129, 126, 87, 169, 127, 125, 117, 104, 111, + 143, 124, 144, 112, 132, 131, 133, 0, 0, 0, + 159, 176, 193, 93, 0, 164, 183, 184, 185, 186, + 187, 188, 0, 0, 94, 107, 103, 142, 134, 92, + 113, 156, 116, 123, 148, 191, 139, 153, 97, 175, + 157, 310, 321, 316, 317, 314, 315, 313, 312, 311, + 323, 302, 303, 304, 305, 307, 0, 318, 319, 306, + 82, 0, 120, 190, 147, 105, 177, 138, 0, 0, + 779, 0, 269, 0, 0, 0, 102, 0, 266, 0, + 0, 0, 119, 309, 121, 0, 0, 158, 130, 0, + 0, 0, 0, 300, 301, 0, 0, 0, 0, 0, + 0, 0, 0, 54, 0, 0, 267, 288, 287, 290, + 291, 292, 293, 0, 0, 95, 289, 294, 295, 296, + 0, 0, 0, 264, 281, 0, 308, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 278, 279, 260, 0, + 0, 0, 322, 0, 280, 0, 0, 275, 276, 277, + 282, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 108, 0, 0, 0, 209, 0, 0, 320, 0, 145, + 0, 161, 110, 118, 83, 89, 0, 109, 136, 150, + 154, 0, 0, 0, 98, 0, 152, 140, 174, 0, + 141, 151, 122, 166, 146, 173, 181, 182, 163, 180, + 189, 84, 162, 172, 96, 155, 86, 170, 160, 128, + 114, 115, 85, 0, 149, 101, 106, 100, 137, 167, + 168, 99, 192, 90, 179, 88, 91, 178, 135, 165, + 171, 129, 126, 87, 169, 127, 125, 117, 104, 111, + 143, 124, 144, 112, 132, 131, 133, 0, 0, 0, + 159, 176, 193, 93, 0, 164, 183, 184, 185, 186, + 187, 188, 0, 0, 94, 107, 103, 142, 134, 92, + 113, 156, 116, 123, 148, 191, 139, 153, 97, 175, + 157, 310, 321, 316, 317, 314, 315, 313, 312, 311, + 323, 302, 303, 304, 305, 307, 0, 318, 319, 306, + 82, 0, 120, 190, 147, 105, 177, 138, 0, 0, + 0, 0, 269, 0, 0, 0, 102, 0, 266, 0, + 0, 0, 119, 309, 121, 0, 0, 158, 130, 0, + 0, 0, 0, 300, 301, 0, 0, 0, 0, 0, + 0, 0, 0, 54, 0, 497, 267, 288, 287, 290, + 291, 292, 293, 0, 0, 95, 289, 294, 295, 296, + 0, 0, 0, 264, 281, 0, 308, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 278, 279, 0, 0, + 0, 0, 322, 0, 280, 0, 0, 275, 276, 277, + 282, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 108, 0, 0, 0, 209, 0, 0, 320, 0, 145, + 0, 161, 110, 118, 83, 89, 0, 109, 136, 150, + 154, 0, 0, 0, 98, 0, 152, 140, 174, 0, + 141, 151, 122, 166, 146, 173, 181, 182, 163, 180, + 189, 84, 162, 172, 96, 155, 86, 170, 160, 128, + 114, 115, 85, 0, 149, 101, 106, 100, 137, 167, + 168, 99, 192, 90, 179, 88, 91, 178, 135, 165, + 171, 129, 126, 87, 169, 127, 125, 117, 104, 111, + 143, 124, 144, 112, 132, 131, 133, 0, 0, 0, + 159, 176, 193, 93, 0, 164, 183, 184, 185, 186, + 187, 188, 0, 0, 94, 107, 103, 142, 134, 92, + 113, 156, 116, 123, 148, 191, 139, 153, 97, 175, + 157, 310, 321, 316, 317, 314, 315, 313, 312, 311, + 323, 302, 303, 304, 305, 307, 0, 318, 319, 306, + 82, 0, 120, 190, 147, 105, 177, 138, 0, 0, + 0, 0, 269, 0, 0, 0, 102, 0, 266, 0, + 0, 0, 119, 309, 121, 0, 0, 158, 130, 0, + 0, 0, 0, 300, 301, 0, 0, 0, 0, 0, + 0, 0, 0, 54, 0, 0, 267, 288, 287, 290, + 291, 292, 293, 0, 0, 95, 289, 294, 295, 296, + 0, 0, 0, 264, 281, 0, 308, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 278, 279, 260, 0, + 0, 0, 322, 0, 280, 0, 0, 275, 276, 277, + 282, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 108, 0, 0, 0, 209, 0, 0, 320, 0, 145, 0, 161, 110, 118, 83, 89, 0, 109, 136, 150, - 154, 415, 363, 371, 98, 369, 152, 140, 174, 396, + 154, 0, 0, 0, 98, 0, 152, 140, 174, 0, 141, 151, 122, 166, 146, 173, 181, 182, 163, 180, 189, 84, 162, 172, 96, 155, 86, 170, 160, 128, 114, 115, 85, 0, 149, 101, 106, 100, 137, 167, - 168, 99, 192, 90, 179, 88, 338, 178, 135, 165, + 168, 99, 192, 90, 179, 88, 91, 178, 135, 165, 171, 129, 126, 87, 169, 127, 125, 117, 104, 111, - 143, 124, 144, 112, 132, 131, 133, 0, 344, 0, - 159, 176, 193, 93, 359, 164, 183, 184, 185, 186, - 187, 188, 0, 0, 94, 107, 103, 142, 339, 337, + 143, 124, 144, 112, 132, 131, 133, 0, 0, 0, + 159, 176, 193, 93, 0, 164, 183, 184, 185, 186, + 187, 188, 0, 0, 94, 107, 103, 142, 134, 92, 113, 156, 116, 123, 148, 191, 139, 153, 97, 175, - 157, 355, 358, 353, 354, 392, 393, 427, 428, 429, - 409, 350, 0, 356, 357, 0, 413, 395, 82, 0, - 120, 190, 147, 105, 177, 421, 412, 0, 383, 424, - 361, 375, 432, 376, 377, 405, 347, 391, 138, 373, - 0, 364, 342, 370, 343, 362, 385, 102, 388, 360, - 414, 394, 423, 119, 430, 121, 399, 0, 158, 130, - 0, 0, 387, 416, 389, 410, 382, 406, 352, 398, - 425, 374, 403, 426, 0, 0, 0, 207, 0, 0, - 0, 0, 0, 0, 0, 0, 95, 0, 401, 420, - 372, 402, 404, 341, 400, 0, 345, 348, 431, 418, - 367, 368, 0, 0, 0, 0, 0, 0, 0, 386, - 390, 407, 380, 0, 0, 0, 0, 0, 0, 0, - 0, 365, 0, 397, 0, 0, 0, 349, 346, 0, - 0, 384, 0, 0, 0, 351, 0, 366, 408, 0, - 340, 108, 411, 417, 381, 209, 419, 379, 378, 422, + 157, 310, 321, 316, 317, 314, 315, 313, 312, 311, + 323, 302, 303, 304, 305, 307, 24, 318, 319, 306, + 82, 0, 120, 190, 147, 105, 177, 0, 138, 0, + 0, 0, 0, 269, 0, 0, 0, 102, 0, 266, + 0, 0, 0, 119, 309, 121, 0, 0, 158, 130, + 0, 0, 0, 0, 300, 301, 0, 0, 0, 0, + 0, 0, 0, 0, 54, 0, 0, 267, 288, 287, + 290, 291, 292, 293, 0, 0, 95, 289, 294, 295, + 296, 0, 0, 0, 264, 281, 0, 308, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 278, 279, 0, + 0, 0, 0, 322, 0, 280, 0, 0, 275, 276, + 277, 282, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 108, 0, 0, 0, 209, 0, 0, 320, 0, 145, 0, 161, 110, 118, 83, 89, 0, 109, 136, - 150, 154, 415, 363, 371, 98, 369, 152, 140, 174, - 396, 141, 151, 122, 166, 146, 173, 181, 182, 163, + 150, 154, 0, 0, 0, 98, 0, 152, 140, 174, + 0, 141, 151, 122, 166, 146, 173, 181, 182, 163, 180, 189, 84, 162, 172, 96, 155, 86, 170, 160, 128, 114, 115, 85, 0, 149, 101, 106, 100, 137, 167, 168, 99, 192, 90, 179, 88, 91, 178, 135, 165, 171, 129, 126, 87, 169, 127, 125, 117, 104, - 111, 143, 124, 144, 112, 132, 131, 133, 0, 344, - 0, 159, 176, 193, 93, 359, 164, 183, 184, 185, + 111, 143, 124, 144, 112, 132, 131, 133, 0, 0, + 0, 159, 176, 193, 93, 0, 164, 183, 184, 185, 186, 187, 188, 0, 0, 94, 107, 103, 142, 134, 92, 113, 156, 116, 123, 148, 191, 139, 153, 97, - 175, 157, 355, 358, 353, 354, 392, 393, 427, 428, - 429, 409, 350, 0, 356, 357, 0, 413, 395, 82, - 0, 120, 190, 147, 105, 177, 421, 412, 0, 383, - 424, 361, 375, 432, 376, 377, 405, 347, 391, 138, - 373, 0, 364, 342, 370, 343, 362, 385, 102, 388, - 360, 414, 394, 423, 119, 430, 121, 399, 0, 158, - 130, 0, 0, 387, 416, 389, 410, 382, 406, 352, - 398, 425, 374, 403, 426, 0, 0, 0, 80, 0, - 0, 0, 0, 0, 0, 0, 0, 95, 0, 401, - 420, 372, 402, 404, 341, 400, 0, 345, 348, 431, - 418, 367, 368, 0, 0, 0, 0, 0, 0, 0, - 386, 390, 407, 380, 0, 0, 0, 0, 0, 0, - 0, 0, 365, 0, 397, 0, 0, 0, 349, 346, - 0, 0, 384, 0, 0, 0, 351, 0, 366, 408, - 0, 340, 108, 411, 417, 381, 209, 419, 379, 378, - 422, 145, 0, 161, 110, 118, 83, 89, 0, 109, - 136, 150, 154, 415, 363, 371, 98, 369, 152, 140, - 174, 396, 141, 151, 122, 166, 146, 173, 181, 182, - 163, 180, 189, 84, 162, 608, 96, 155, 86, 170, - 160, 128, 114, 115, 85, 0, 149, 101, 106, 100, - 137, 167, 168, 99, 192, 90, 179, 88, 338, 178, - 135, 165, 171, 129, 126, 87, 169, 127, 125, 117, - 104, 111, 143, 124, 144, 112, 132, 131, 133, 0, - 344, 0, 159, 176, 193, 93, 359, 164, 183, 184, - 185, 186, 187, 188, 0, 0, 94, 107, 103, 142, - 339, 337, 113, 156, 116, 123, 148, 191, 139, 153, - 97, 175, 157, 355, 358, 353, 354, 392, 393, 427, - 428, 429, 409, 350, 0, 356, 357, 0, 413, 395, - 82, 0, 120, 190, 147, 105, 177, 421, 412, 0, - 383, 424, 361, 375, 432, 376, 377, 405, 347, 391, - 138, 373, 0, 364, 342, 370, 343, 362, 385, 102, - 388, 360, 414, 394, 423, 119, 430, 121, 399, 0, - 158, 130, 0, 0, 387, 416, 389, 410, 382, 406, - 352, 398, 425, 374, 403, 426, 0, 0, 0, 80, - 0, 0, 0, 0, 0, 0, 0, 0, 95, 0, - 401, 420, 372, 402, 404, 341, 400, 0, 345, 348, - 431, 418, 367, 368, 0, 0, 0, 0, 0, 0, - 0, 386, 390, 407, 380, 0, 0, 0, 0, 0, - 0, 0, 0, 365, 0, 397, 0, 0, 0, 349, - 346, 0, 0, 384, 0, 0, 0, 351, 0, 366, - 408, 0, 340, 108, 411, 417, 381, 209, 419, 379, - 378, 422, 145, 0, 161, 110, 118, 83, 89, 0, - 109, 136, 150, 154, 415, 363, 371, 98, 369, 152, - 140, 174, 396, 141, 151, 122, 166, 146, 173, 181, - 182, 163, 180, 189, 84, 162, 329, 96, 155, 86, - 170, 160, 128, 114, 115, 85, 0, 149, 101, 106, - 100, 137, 167, 168, 99, 192, 90, 179, 88, 338, - 178, 135, 165, 171, 129, 126, 87, 169, 127, 125, - 117, 104, 111, 143, 124, 144, 112, 132, 131, 133, - 0, 344, 0, 159, 176, 193, 93, 359, 164, 183, - 184, 185, 186, 187, 188, 0, 0, 94, 107, 103, - 142, 339, 337, 332, 331, 116, 123, 148, 191, 139, - 153, 97, 175, 157, 355, 358, 353, 354, 392, 393, - 427, 428, 429, 409, 350, 0, 356, 357, 0, 413, - 395, 82, 0, 120, 190, 147, 105, 177, 138, 0, - 0, 773, 0, 269, 0, 0, 0, 102, 0, 266, + 175, 157, 310, 321, 316, 317, 314, 315, 313, 312, + 311, 323, 302, 303, 304, 305, 307, 0, 318, 319, + 306, 82, 0, 120, 190, 147, 105, 177, 138, 0, + 0, 0, 0, 269, 0, 0, 0, 102, 0, 266, 0, 0, 0, 119, 309, 121, 0, 0, 158, 130, 0, 0, 0, 0, 300, 301, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 267, 288, 287, 290, 291, 292, 293, 0, 0, 95, 289, 294, 295, 296, 0, 0, 0, 264, 281, 0, 308, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 278, 279, 260, - 0, 0, 0, 320, 0, 280, 0, 0, 275, 276, + 0, 0, 0, 0, 0, 0, 0, 278, 279, 0, + 0, 0, 0, 322, 0, 280, 0, 0, 275, 276, 277, 282, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 108, 0, 0, 0, 209, 0, 0, 318, 0, + 0, 108, 0, 0, 0, 209, 0, 0, 320, 0, 145, 0, 161, 110, 118, 83, 89, 0, 109, 136, 150, 154, 0, 0, 0, 98, 0, 152, 140, 174, 0, 141, 151, 122, 166, 146, 173, 181, 182, 163, @@ -1305,20 +1425,44 @@ var yyAct = [...]int{ 0, 159, 176, 193, 93, 0, 164, 183, 184, 185, 186, 187, 188, 0, 0, 94, 107, 103, 142, 134, 92, 113, 156, 116, 123, 148, 191, 139, 153, 97, - 175, 157, 310, 319, 316, 317, 314, 315, 313, 312, - 311, 321, 302, 303, 304, 305, 307, 0, 306, 82, - 0, 120, 190, 147, 105, 177, 138, 0, 0, 0, - 0, 269, 0, 0, 0, 102, 0, 266, 0, 0, + 175, 157, 310, 321, 316, 317, 314, 315, 313, 312, + 311, 323, 302, 303, 304, 305, 307, 0, 318, 319, + 306, 82, 138, 120, 190, 147, 105, 177, 0, 0, + 0, 102, 0, 0, 0, 0, 0, 119, 309, 121, + 0, 0, 158, 130, 0, 0, 0, 0, 300, 301, + 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, + 0, 267, 288, 287, 290, 291, 292, 293, 0, 0, + 95, 289, 294, 295, 296, 0, 0, 0, 0, 281, + 0, 308, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 278, 279, 0, 0, 0, 0, 322, 0, 280, + 0, 0, 275, 276, 277, 282, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 108, 0, 0, 0, 209, + 0, 0, 320, 0, 145, 0, 161, 110, 118, 83, + 89, 0, 109, 136, 150, 154, 0, 0, 0, 98, + 0, 152, 140, 174, 1428, 141, 151, 122, 166, 146, + 173, 181, 182, 163, 180, 189, 84, 162, 172, 96, + 155, 86, 170, 160, 128, 114, 115, 85, 0, 149, + 101, 106, 100, 137, 167, 168, 99, 192, 90, 179, + 88, 91, 178, 135, 165, 171, 129, 126, 87, 169, + 127, 125, 117, 104, 111, 143, 124, 144, 112, 132, + 131, 133, 0, 0, 0, 159, 176, 193, 93, 0, + 164, 183, 184, 185, 186, 187, 188, 0, 0, 94, + 107, 103, 142, 134, 92, 113, 156, 116, 123, 148, + 191, 139, 153, 97, 175, 157, 310, 321, 316, 317, + 314, 315, 313, 312, 311, 323, 302, 303, 304, 305, + 307, 0, 318, 319, 306, 82, 138, 120, 190, 147, + 105, 177, 0, 0, 0, 102, 0, 0, 0, 0, 0, 119, 309, 121, 0, 0, 158, 130, 0, 0, 0, 0, 300, 301, 0, 0, 0, 0, 0, 0, - 0, 0, 54, 0, 493, 267, 288, 287, 290, 291, + 0, 0, 54, 0, 0, 267, 288, 287, 290, 291, 292, 293, 0, 0, 95, 289, 294, 295, 296, 0, - 0, 0, 264, 281, 0, 308, 0, 0, 0, 0, + 0, 0, 0, 281, 0, 308, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 278, 279, 0, 0, 0, - 0, 320, 0, 280, 0, 0, 275, 276, 277, 282, + 0, 322, 0, 280, 0, 0, 275, 276, 277, 282, 0, 0, 0, 0, 0, 0, 0, 0, 0, 108, - 0, 0, 0, 209, 0, 0, 318, 0, 145, 0, + 0, 0, 0, 209, 0, 0, 320, 0, 145, 0, 161, 110, 118, 83, 89, 0, 109, 136, 150, 154, 0, 0, 0, 98, 0, 152, 140, 174, 0, 141, 151, 122, 166, 146, 173, 181, 182, 163, 180, 189, @@ -1330,45 +1474,43 @@ var yyAct = [...]int{ 176, 193, 93, 0, 164, 183, 184, 185, 186, 187, 188, 0, 0, 94, 107, 103, 142, 134, 92, 113, 156, 116, 123, 148, 191, 139, 153, 97, 175, 157, - 310, 319, 316, 317, 314, 315, 313, 312, 311, 321, - 302, 303, 304, 305, 307, 0, 306, 82, 0, 120, - 190, 147, 105, 177, 138, 0, 0, 0, 0, 269, - 0, 0, 0, 102, 0, 266, 0, 0, 0, 119, - 309, 121, 0, 0, 158, 130, 0, 0, 0, 0, - 300, 301, 0, 0, 0, 0, 0, 0, 0, 0, - 54, 0, 0, 267, 288, 287, 290, 291, 292, 293, - 0, 0, 95, 289, 294, 295, 296, 0, 0, 0, - 264, 281, 0, 308, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 278, 279, 260, 0, 0, 0, 320, - 0, 280, 0, 0, 275, 276, 277, 282, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 108, 0, 0, - 0, 209, 0, 0, 318, 0, 145, 0, 161, 110, - 118, 83, 89, 0, 109, 136, 150, 154, 0, 0, - 0, 98, 0, 152, 140, 174, 0, 141, 151, 122, - 166, 146, 173, 181, 182, 163, 180, 189, 84, 162, - 172, 96, 155, 86, 170, 160, 128, 114, 115, 85, - 0, 149, 101, 106, 100, 137, 167, 168, 99, 192, - 90, 179, 88, 91, 178, 135, 165, 171, 129, 126, - 87, 169, 127, 125, 117, 104, 111, 143, 124, 144, - 112, 132, 131, 133, 0, 0, 0, 159, 176, 193, - 93, 0, 164, 183, 184, 185, 186, 187, 188, 0, - 0, 94, 107, 103, 142, 134, 92, 113, 156, 116, - 123, 148, 191, 139, 153, 97, 175, 157, 310, 319, - 316, 317, 314, 315, 313, 312, 311, 321, 302, 303, - 304, 305, 307, 24, 306, 82, 0, 120, 190, 147, - 105, 177, 0, 0, 0, 138, 0, 0, 0, 0, - 269, 0, 0, 0, 102, 0, 266, 0, 0, 0, - 119, 309, 121, 0, 0, 158, 130, 0, 0, 0, - 0, 300, 301, 0, 0, 0, 0, 0, 0, 0, - 0, 54, 0, 0, 267, 288, 287, 290, 291, 292, - 293, 0, 0, 95, 289, 294, 295, 296, 0, 0, - 0, 264, 281, 0, 308, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 278, 279, 0, 0, 0, 0, - 320, 0, 280, 0, 0, 275, 276, 277, 282, 0, + 310, 321, 316, 317, 314, 315, 313, 312, 311, 323, + 302, 303, 304, 305, 307, 0, 318, 319, 306, 82, + 138, 120, 190, 147, 105, 177, 0, 0, 0, 102, + 0, 0, 0, 0, 0, 119, 0, 121, 0, 0, + 158, 130, 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, 95, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 531, 530, 540, 541, 533, + 534, 535, 536, 537, 538, 539, 532, 0, 0, 542, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 108, 0, 0, 0, 209, 0, 0, + 0, 0, 145, 0, 161, 110, 118, 83, 89, 0, + 109, 136, 150, 154, 0, 0, 0, 98, 0, 152, + 140, 174, 0, 141, 151, 122, 166, 146, 173, 181, + 182, 163, 180, 189, 84, 162, 172, 96, 155, 86, + 170, 160, 128, 114, 115, 85, 0, 149, 101, 106, + 100, 137, 167, 168, 99, 192, 90, 179, 88, 91, + 178, 135, 165, 171, 129, 126, 87, 169, 127, 125, + 117, 104, 111, 143, 124, 144, 112, 132, 131, 133, + 0, 0, 0, 159, 176, 193, 93, 0, 164, 183, + 184, 185, 186, 187, 188, 0, 0, 94, 107, 103, + 142, 134, 92, 113, 156, 116, 123, 148, 191, 139, + 153, 97, 175, 157, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 138, 0, 0, 0, 519, + 0, 0, 0, 82, 102, 120, 190, 147, 105, 177, + 119, 0, 121, 0, 0, 158, 130, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 80, 0, 521, 0, 0, 0, + 0, 0, 0, 95, 0, 0, 0, 0, 0, 516, + 515, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 517, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 108, 0, - 0, 0, 209, 0, 0, 318, 0, 145, 0, 161, + 0, 0, 209, 0, 0, 0, 0, 145, 0, 161, 110, 118, 83, 89, 0, 109, 136, 150, 154, 0, 0, 0, 98, 0, 152, 140, 174, 0, 141, 151, 122, 166, 146, 173, 181, 182, 163, 180, 189, 84, @@ -1379,93 +1521,20 @@ var yyAct = [...]int{ 144, 112, 132, 131, 133, 0, 0, 0, 159, 176, 193, 93, 0, 164, 183, 184, 185, 186, 187, 188, 0, 0, 94, 107, 103, 142, 134, 92, 113, 156, - 116, 123, 148, 191, 139, 153, 97, 175, 157, 310, - 319, 316, 317, 314, 315, 313, 312, 311, 321, 302, - 303, 304, 305, 307, 0, 306, 82, 0, 120, 190, - 147, 105, 177, 138, 0, 0, 0, 0, 269, 0, - 0, 0, 102, 0, 266, 0, 0, 0, 119, 309, - 121, 0, 0, 158, 130, 0, 0, 0, 0, 300, - 301, 0, 0, 0, 0, 0, 0, 0, 0, 54, - 0, 0, 267, 288, 287, 290, 291, 292, 293, 0, - 0, 95, 289, 294, 295, 296, 0, 0, 0, 264, - 281, 0, 308, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 278, 279, 0, 0, 0, 0, 320, 0, - 280, 0, 0, 275, 276, 277, 282, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 108, 0, 0, 0, - 209, 0, 0, 318, 0, 145, 0, 161, 110, 118, - 83, 89, 0, 109, 136, 150, 154, 0, 0, 0, - 98, 0, 152, 140, 174, 0, 141, 151, 122, 166, - 146, 173, 181, 182, 163, 180, 189, 84, 162, 172, - 96, 155, 86, 170, 160, 128, 114, 115, 85, 0, - 149, 101, 106, 100, 137, 167, 168, 99, 192, 90, - 179, 88, 91, 178, 135, 165, 171, 129, 126, 87, - 169, 127, 125, 117, 104, 111, 143, 124, 144, 112, - 132, 131, 133, 0, 0, 0, 159, 176, 193, 93, - 0, 164, 183, 184, 185, 186, 187, 188, 0, 0, - 94, 107, 103, 142, 134, 92, 113, 156, 116, 123, - 148, 191, 139, 153, 97, 175, 157, 310, 319, 316, - 317, 314, 315, 313, 312, 311, 321, 302, 303, 304, - 305, 307, 138, 306, 82, 0, 120, 190, 147, 105, - 177, 102, 0, 0, 0, 0, 0, 119, 309, 121, - 0, 0, 158, 130, 0, 0, 0, 0, 300, 301, - 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, - 0, 267, 288, 287, 290, 291, 292, 293, 0, 0, - 95, 289, 294, 295, 296, 0, 0, 0, 0, 281, - 0, 308, 0, 0, 0, 0, 0, 0, 0, 0, + 116, 123, 148, 191, 139, 153, 97, 175, 157, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 278, 279, 0, 0, 0, 0, 320, 0, 280, - 0, 0, 275, 276, 277, 282, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 108, 0, 0, 0, 209, - 0, 0, 318, 0, 145, 0, 161, 110, 118, 83, - 89, 0, 109, 136, 150, 154, 0, 0, 0, 98, - 0, 152, 140, 174, 1410, 141, 151, 122, 166, 146, - 173, 181, 182, 163, 180, 189, 84, 162, 172, 96, - 155, 86, 170, 160, 128, 114, 115, 85, 0, 149, - 101, 106, 100, 137, 167, 168, 99, 192, 90, 179, - 88, 91, 178, 135, 165, 171, 129, 126, 87, 169, - 127, 125, 117, 104, 111, 143, 124, 144, 112, 132, - 131, 133, 0, 0, 0, 159, 176, 193, 93, 0, - 164, 183, 184, 185, 186, 187, 188, 0, 0, 94, - 107, 103, 142, 134, 92, 113, 156, 116, 123, 148, - 191, 139, 153, 97, 175, 157, 310, 319, 316, 317, - 314, 315, 313, 312, 311, 321, 302, 303, 304, 305, - 307, 138, 306, 82, 0, 120, 190, 147, 105, 177, - 102, 0, 0, 0, 0, 0, 119, 309, 121, 0, - 0, 158, 130, 0, 0, 0, 0, 300, 301, 0, - 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, - 267, 288, 287, 290, 291, 292, 293, 0, 0, 95, - 289, 294, 295, 296, 0, 0, 0, 0, 281, 0, - 308, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 278, 279, 0, 0, 0, 0, 320, 0, 280, 0, - 0, 275, 276, 277, 282, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 108, 0, 0, 0, 209, 0, - 0, 318, 0, 145, 0, 161, 110, 118, 83, 89, - 0, 109, 136, 150, 154, 0, 0, 0, 98, 0, - 152, 140, 174, 0, 141, 151, 122, 166, 146, 173, - 181, 182, 163, 180, 189, 84, 162, 172, 96, 155, - 86, 170, 160, 128, 114, 115, 85, 0, 149, 101, - 106, 100, 137, 167, 168, 99, 192, 90, 179, 88, - 91, 178, 135, 165, 171, 129, 126, 87, 169, 127, - 125, 117, 104, 111, 143, 124, 144, 112, 132, 131, - 133, 0, 0, 0, 159, 176, 193, 93, 0, 164, - 183, 184, 185, 186, 187, 188, 0, 0, 94, 107, - 103, 142, 134, 92, 113, 156, 116, 123, 148, 191, - 139, 153, 97, 175, 157, 310, 319, 316, 317, 314, - 315, 313, 312, 311, 321, 302, 303, 304, 305, 307, - 138, 306, 82, 0, 120, 190, 147, 105, 177, 102, - 0, 0, 0, 0, 0, 119, 0, 121, 0, 0, + 138, 0, 0, 0, 0, 0, 0, 0, 82, 102, + 120, 190, 147, 105, 177, 119, 0, 121, 0, 0, 158, 130, 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, 95, 0, + 0, 0, 0, 0, 74, 0, 0, 0, 0, 0, 0, 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, 108, 0, 0, 0, 209, 0, 0, - 0, 0, 145, 0, 161, 110, 118, 83, 89, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 108, 76, 77, 0, 73, 0, 0, + 0, 78, 145, 0, 161, 110, 118, 83, 89, 0, 109, 136, 150, 154, 0, 0, 0, 98, 0, 152, 140, 174, 0, 141, 151, 122, 166, 146, 173, 181, 182, 163, 180, 189, 84, 162, 172, 96, 155, 86, @@ -1476,42 +1545,43 @@ var yyAct = [...]int{ 0, 0, 0, 159, 176, 193, 93, 0, 164, 183, 184, 185, 186, 187, 188, 0, 0, 94, 107, 103, 142, 134, 92, 113, 156, 116, 123, 148, 191, 139, - 153, 97, 175, 157, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 138, 0, 0, 0, 515, 0, 0, - 0, 82, 102, 120, 190, 147, 105, 177, 119, 0, - 121, 0, 0, 158, 130, 0, 0, 0, 0, 0, + 153, 97, 175, 157, 0, 75, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 138, 0, 0, 0, 832, + 0, 0, 0, 82, 102, 120, 190, 147, 105, 177, + 119, 0, 121, 0, 0, 158, 130, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 80, 0, 517, 0, 0, 0, 0, 0, - 0, 95, 0, 0, 0, 0, 0, 512, 511, 0, + 0, 0, 0, 0, 207, 0, 834, 0, 0, 0, + 0, 0, 0, 95, 0, 0, 0, 0, 0, 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, 108, 0, 0, 0, - 209, 0, 0, 0, 0, 145, 0, 161, 110, 118, - 83, 89, 0, 109, 136, 150, 154, 0, 0, 0, - 98, 0, 152, 140, 174, 0, 141, 151, 122, 166, - 146, 173, 181, 182, 163, 180, 189, 84, 162, 172, - 96, 155, 86, 170, 160, 128, 114, 115, 85, 0, - 149, 101, 106, 100, 137, 167, 168, 99, 192, 90, - 179, 88, 91, 178, 135, 165, 171, 129, 126, 87, - 169, 127, 125, 117, 104, 111, 143, 124, 144, 112, - 132, 131, 133, 0, 0, 0, 159, 176, 193, 93, - 0, 164, 183, 184, 185, 186, 187, 188, 0, 0, - 94, 107, 103, 142, 134, 92, 113, 156, 116, 123, - 148, 191, 139, 153, 97, 175, 157, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 138, 0, 0, 0, - 0, 0, 0, 0, 82, 102, 120, 190, 147, 105, - 177, 119, 0, 121, 0, 0, 158, 130, 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, 0, 0, 0, 0, 108, 0, + 0, 0, 209, 0, 0, 0, 0, 145, 0, 161, + 110, 118, 83, 89, 0, 109, 136, 150, 154, 0, + 0, 0, 98, 0, 152, 140, 174, 0, 141, 151, + 122, 166, 146, 173, 181, 182, 163, 180, 189, 84, + 162, 172, 96, 155, 86, 170, 160, 128, 114, 115, + 85, 0, 149, 101, 106, 100, 137, 167, 168, 99, + 192, 90, 179, 88, 91, 178, 135, 165, 171, 129, + 126, 87, 169, 127, 125, 117, 104, 111, 143, 124, + 144, 112, 132, 131, 133, 0, 0, 0, 159, 176, + 193, 93, 0, 164, 183, 184, 185, 186, 187, 188, + 0, 0, 94, 107, 103, 142, 134, 92, 113, 156, + 116, 123, 148, 191, 139, 153, 97, 175, 157, 0, + 0, 0, 0, 0, 24, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 138, 0, 82, 0, + 120, 190, 147, 105, 177, 102, 0, 0, 0, 0, + 0, 119, 0, 121, 0, 0, 158, 130, 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, 95, 0, 0, 0, 0, 0, - 74, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 108, - 76, 77, 0, 73, 0, 0, 0, 78, 145, 0, + 0, 0, 0, 209, 0, 0, 0, 0, 145, 0, 161, 110, 118, 83, 89, 0, 109, 136, 150, 154, 0, 0, 0, 98, 0, 152, 140, 174, 0, 141, 151, 122, 166, 146, 173, 181, 182, 163, 180, 189, @@ -1523,60 +1593,60 @@ var yyAct = [...]int{ 176, 193, 93, 0, 164, 183, 184, 185, 186, 187, 188, 0, 0, 94, 107, 103, 142, 134, 92, 113, 156, 116, 123, 148, 191, 139, 153, 97, 175, 157, - 0, 75, 0, 0, 0, 0, 0, 0, 0, 138, - 0, 0, 0, 824, 0, 0, 0, 82, 102, 120, - 190, 147, 105, 177, 119, 0, 121, 0, 0, 158, - 130, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 207, 0, - 826, 0, 0, 0, 0, 0, 0, 95, 0, 0, + 0, 0, 0, 0, 0, 24, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 138, 0, 82, + 0, 120, 190, 147, 105, 177, 102, 0, 0, 0, + 0, 0, 119, 0, 121, 0, 0, 158, 130, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 54, 0, 0, 207, 0, 0, 0, + 0, 0, 0, 0, 0, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 108, 0, 0, 0, 209, 0, 0, 0, - 0, 145, 0, 161, 110, 118, 83, 89, 0, 109, - 136, 150, 154, 0, 0, 0, 98, 0, 152, 140, - 174, 0, 141, 151, 122, 166, 146, 173, 181, 182, - 163, 180, 189, 84, 162, 172, 96, 155, 86, 170, - 160, 128, 114, 115, 85, 0, 149, 101, 106, 100, - 137, 167, 168, 99, 192, 90, 179, 88, 91, 178, - 135, 165, 171, 129, 126, 87, 169, 127, 125, 117, - 104, 111, 143, 124, 144, 112, 132, 131, 133, 0, - 0, 0, 159, 176, 193, 93, 0, 164, 183, 184, - 185, 186, 187, 188, 0, 0, 94, 107, 103, 142, - 134, 92, 113, 156, 116, 123, 148, 191, 139, 153, - 97, 175, 157, 0, 0, 0, 24, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 138, 0, - 82, 0, 120, 190, 147, 105, 177, 102, 0, 0, - 0, 0, 0, 119, 0, 121, 0, 0, 158, 130, 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, 95, 0, 0, 0, + 108, 0, 0, 0, 209, 0, 0, 0, 0, 145, + 0, 161, 110, 118, 83, 89, 0, 109, 136, 150, + 154, 0, 0, 0, 98, 0, 152, 140, 174, 0, + 141, 151, 122, 166, 146, 173, 181, 182, 163, 180, + 189, 84, 162, 172, 96, 155, 86, 170, 160, 128, + 114, 115, 85, 0, 149, 101, 106, 100, 137, 167, + 168, 99, 192, 90, 179, 88, 91, 178, 135, 165, + 171, 129, 126, 87, 169, 127, 125, 117, 104, 111, + 143, 124, 144, 112, 132, 131, 133, 0, 0, 0, + 159, 176, 193, 93, 0, 164, 183, 184, 185, 186, + 187, 188, 0, 0, 94, 107, 103, 142, 134, 92, + 113, 156, 116, 123, 148, 191, 139, 153, 97, 175, + 157, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 138, 0, 0, 0, 832, 0, 0, 0, + 82, 102, 120, 190, 147, 105, 177, 119, 0, 121, + 0, 0, 158, 130, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 207, 0, 834, 0, 0, 0, 0, 0, 0, + 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 108, 0, 0, 0, 209, 0, 0, 0, 0, - 145, 0, 161, 110, 118, 83, 89, 0, 109, 136, - 150, 154, 0, 0, 0, 98, 0, 152, 140, 174, - 0, 141, 151, 122, 166, 146, 173, 181, 182, 163, - 180, 189, 84, 162, 172, 96, 155, 86, 170, 160, - 128, 114, 115, 85, 0, 149, 101, 106, 100, 137, - 167, 168, 99, 192, 90, 179, 88, 91, 178, 135, - 165, 171, 129, 126, 87, 169, 127, 125, 117, 104, - 111, 143, 124, 144, 112, 132, 131, 133, 0, 0, - 0, 159, 176, 193, 93, 0, 164, 183, 184, 185, - 186, 187, 188, 0, 0, 94, 107, 103, 142, 134, - 92, 113, 156, 116, 123, 148, 191, 139, 153, 97, - 175, 157, 0, 0, 0, 24, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 138, 0, 82, - 0, 120, 190, 147, 105, 177, 102, 0, 0, 0, - 0, 0, 119, 0, 121, 0, 0, 158, 130, 0, + 0, 0, 0, 0, 0, 108, 0, 0, 0, 209, + 0, 0, 0, 0, 145, 0, 161, 110, 118, 83, + 89, 0, 109, 136, 150, 154, 0, 0, 0, 98, + 0, 152, 140, 174, 0, 830, 151, 122, 166, 146, + 173, 181, 182, 163, 180, 189, 84, 162, 172, 96, + 155, 86, 170, 160, 128, 114, 115, 85, 0, 149, + 101, 106, 100, 137, 167, 168, 99, 192, 90, 179, + 88, 91, 178, 135, 165, 171, 129, 126, 87, 169, + 127, 125, 117, 104, 111, 143, 124, 144, 112, 132, + 131, 133, 0, 0, 0, 159, 176, 193, 93, 0, + 164, 183, 184, 185, 186, 187, 188, 0, 0, 94, + 107, 103, 142, 134, 92, 113, 156, 116, 123, 148, + 191, 139, 153, 97, 175, 157, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 138, 0, 0, + 0, 0, 0, 0, 0, 82, 102, 120, 190, 147, + 105, 177, 119, 0, 121, 0, 0, 158, 130, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 54, 0, 0, 207, 0, 0, 0, - 0, 0, 0, 0, 0, 95, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 80, 0, 0, 730, + 0, 0, 731, 0, 0, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -1595,34 +1665,35 @@ var yyAct = [...]int{ 187, 188, 0, 0, 94, 107, 103, 142, 134, 92, 113, 156, 116, 123, 148, 191, 139, 153, 97, 175, 157, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 138, 0, 0, 0, 824, 0, 0, 0, 82, 102, - 120, 190, 147, 105, 177, 119, 0, 121, 0, 0, - 158, 130, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 207, - 0, 826, 0, 0, 0, 0, 0, 0, 95, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 138, 0, + 82, 0, 120, 190, 147, 105, 177, 102, 0, 623, + 0, 0, 0, 119, 0, 121, 0, 0, 158, 130, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 80, 0, 622, + 0, 0, 0, 0, 0, 0, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 108, 0, 0, 0, 209, 0, 0, - 0, 0, 145, 0, 161, 110, 118, 83, 89, 0, - 109, 136, 150, 154, 0, 0, 0, 98, 0, 152, - 140, 174, 0, 822, 151, 122, 166, 146, 173, 181, - 182, 163, 180, 189, 84, 162, 172, 96, 155, 86, - 170, 160, 128, 114, 115, 85, 0, 149, 101, 106, - 100, 137, 167, 168, 99, 192, 90, 179, 88, 91, - 178, 135, 165, 171, 129, 126, 87, 169, 127, 125, - 117, 104, 111, 143, 124, 144, 112, 132, 131, 133, - 0, 0, 0, 159, 176, 193, 93, 0, 164, 183, - 184, 185, 186, 187, 188, 0, 0, 94, 107, 103, - 142, 134, 92, 113, 156, 116, 123, 148, 191, 139, - 153, 97, 175, 157, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 108, 0, 0, 0, 209, 0, 0, 0, 0, + 145, 0, 161, 110, 118, 83, 89, 0, 109, 136, + 150, 154, 0, 0, 0, 98, 0, 152, 140, 174, + 0, 141, 151, 122, 166, 146, 173, 181, 182, 163, + 180, 189, 84, 162, 172, 96, 155, 86, 170, 160, + 128, 114, 115, 85, 0, 149, 101, 106, 100, 137, + 167, 168, 99, 192, 90, 179, 88, 91, 178, 135, + 165, 171, 129, 126, 87, 169, 127, 125, 117, 104, + 111, 143, 124, 144, 112, 132, 131, 133, 0, 0, + 0, 159, 176, 193, 93, 0, 164, 183, 184, 185, + 186, 187, 188, 0, 0, 94, 107, 103, 142, 134, + 92, 113, 156, 116, 123, 148, 191, 139, 153, 97, + 175, 157, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 138, 0, 0, 0, 0, 0, 0, 0, 82, 102, 120, 190, 147, 105, 177, 119, 0, 121, 0, 0, 158, 130, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 80, 0, 0, 724, 0, 0, 725, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, + 0, 0, 207, 0, 0, 0, 0, 0, 0, 0, 0, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -1641,58 +1712,11 @@ var yyAct = [...]int{ 0, 164, 183, 184, 185, 186, 187, 188, 0, 0, 94, 107, 103, 142, 134, 92, 113, 156, 116, 123, 148, 191, 139, 153, 97, 175, 157, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 138, 0, 82, 0, 120, 190, 147, 105, - 177, 102, 0, 617, 0, 0, 0, 119, 0, 121, - 0, 0, 158, 130, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 80, 0, 616, 0, 0, 0, 0, 0, 0, - 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 108, 0, 0, 0, 209, - 0, 0, 0, 0, 145, 0, 161, 110, 118, 83, - 89, 0, 109, 136, 150, 154, 0, 0, 0, 98, - 0, 152, 140, 174, 0, 141, 151, 122, 166, 146, - 173, 181, 182, 163, 180, 189, 84, 162, 172, 96, - 155, 86, 170, 160, 128, 114, 115, 85, 0, 149, - 101, 106, 100, 137, 167, 168, 99, 192, 90, 179, - 88, 91, 178, 135, 165, 171, 129, 126, 87, 169, - 127, 125, 117, 104, 111, 143, 124, 144, 112, 132, - 131, 133, 0, 0, 0, 159, 176, 193, 93, 0, - 164, 183, 184, 185, 186, 187, 188, 0, 0, 94, - 107, 103, 142, 134, 92, 113, 156, 116, 123, 148, - 191, 139, 153, 97, 175, 157, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 138, 0, 0, 0, 0, - 0, 0, 0, 82, 102, 120, 190, 147, 105, 177, - 119, 0, 121, 0, 0, 158, 130, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 54, 0, 0, 207, 0, 0, 0, 0, 0, - 0, 0, 0, 95, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 108, 0, - 0, 0, 209, 0, 0, 0, 0, 145, 0, 161, - 110, 118, 83, 89, 0, 109, 136, 150, 154, 0, - 0, 0, 98, 0, 152, 140, 174, 0, 141, 151, - 122, 166, 146, 173, 181, 182, 163, 180, 189, 84, - 162, 172, 96, 155, 86, 170, 160, 128, 114, 115, - 85, 0, 149, 101, 106, 100, 137, 167, 168, 99, - 192, 90, 179, 88, 91, 178, 135, 165, 171, 129, - 126, 87, 169, 127, 125, 117, 104, 111, 143, 124, - 144, 112, 132, 131, 133, 0, 0, 0, 159, 176, - 193, 93, 0, 164, 183, 184, 185, 186, 187, 188, - 0, 0, 94, 107, 103, 142, 134, 92, 113, 156, - 116, 123, 148, 191, 139, 153, 97, 175, 157, 0, 0, 0, 0, 0, 0, 0, 0, 0, 138, 0, 0, 0, 0, 0, 0, 0, 82, 102, 120, 190, 147, 105, 177, 119, 0, 121, 0, 0, 158, 130, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 207, 0, 826, + 0, 0, 0, 0, 0, 0, 0, 207, 0, 834, 0, 0, 0, 0, 0, 0, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -1712,100 +1736,101 @@ var yyAct = [...]int{ 186, 187, 188, 0, 0, 94, 107, 103, 142, 134, 92, 113, 156, 116, 123, 148, 191, 139, 153, 97, 175, 157, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 138, 0, 0, 0, 0, 0, 0, 0, 82, - 102, 120, 190, 147, 105, 177, 119, 0, 121, 0, - 0, 158, 130, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 267, 0, 789, 0, 0, 0, 0, 0, 0, 95, + 0, 0, 0, 138, 0, 0, 0, 0, 0, 0, + 0, 82, 102, 120, 190, 147, 105, 177, 119, 0, + 121, 0, 0, 158, 130, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 267, 0, 795, 0, 0, 0, 0, 0, + 0, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 108, 0, 0, 0, 209, 0, - 0, 0, 0, 145, 0, 161, 110, 118, 83, 89, - 0, 109, 136, 150, 154, 0, 0, 0, 98, 0, - 152, 140, 174, 0, 141, 151, 122, 166, 146, 173, - 181, 182, 163, 180, 189, 84, 162, 172, 96, 155, - 86, 170, 160, 128, 114, 115, 85, 0, 149, 101, - 106, 100, 137, 167, 168, 99, 192, 90, 179, 88, - 91, 178, 135, 165, 171, 129, 126, 87, 169, 127, - 125, 117, 104, 111, 143, 124, 144, 112, 132, 131, - 133, 0, 0, 0, 159, 176, 193, 93, 0, 164, - 183, 184, 185, 186, 187, 188, 0, 0, 94, 107, - 103, 142, 134, 92, 113, 156, 116, 123, 148, 191, - 139, 153, 97, 175, 157, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 138, 0, 0, 0, 0, 0, - 0, 0, 82, 102, 120, 190, 147, 105, 177, 119, - 0, 121, 0, 0, 158, 130, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 267, 0, 785, 0, 0, 0, 0, - 0, 0, 95, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 108, 0, 0, 0, + 209, 0, 0, 0, 0, 145, 0, 161, 110, 118, + 83, 89, 0, 109, 136, 150, 154, 0, 0, 0, + 98, 0, 152, 140, 174, 0, 141, 151, 122, 166, + 146, 173, 181, 182, 163, 180, 189, 84, 162, 172, + 96, 155, 86, 170, 160, 128, 114, 115, 85, 0, + 149, 101, 106, 100, 137, 167, 168, 99, 192, 90, + 179, 88, 91, 178, 135, 165, 171, 129, 126, 87, + 169, 127, 125, 117, 104, 111, 143, 124, 144, 112, + 132, 131, 133, 0, 0, 0, 159, 176, 193, 93, + 0, 164, 183, 184, 185, 186, 187, 188, 0, 0, + 94, 107, 103, 142, 134, 92, 113, 156, 116, 123, + 148, 191, 139, 153, 97, 175, 157, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 138, 0, + 0, 0, 0, 0, 0, 0, 82, 102, 120, 190, + 147, 105, 177, 119, 0, 121, 0, 0, 158, 130, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 267, 0, 791, + 0, 0, 0, 0, 0, 0, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 108, 0, 0, - 0, 209, 0, 0, 0, 0, 145, 0, 161, 110, - 118, 83, 89, 0, 109, 136, 150, 154, 0, 0, - 0, 98, 0, 152, 140, 174, 0, 141, 151, 122, - 166, 146, 173, 181, 182, 163, 180, 189, 84, 162, - 172, 96, 155, 86, 170, 160, 128, 114, 115, 85, - 0, 149, 101, 106, 100, 137, 167, 168, 99, 192, - 90, 179, 88, 91, 178, 135, 165, 171, 129, 126, - 87, 169, 127, 125, 117, 104, 111, 143, 124, 144, - 112, 132, 131, 133, 0, 0, 0, 159, 176, 193, - 93, 0, 164, 183, 184, 185, 186, 187, 188, 0, - 0, 94, 107, 103, 142, 134, 92, 113, 156, 116, - 123, 148, 191, 139, 153, 97, 175, 157, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 138, 0, 0, - 0, 0, 0, 0, 0, 82, 102, 120, 190, 147, - 105, 177, 119, 0, 121, 0, 0, 158, 130, 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, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 108, 0, 0, 0, 209, 0, 0, 0, 0, + 145, 0, 161, 110, 118, 83, 89, 0, 109, 136, + 150, 154, 0, 0, 0, 98, 0, 152, 140, 174, + 0, 141, 151, 122, 166, 146, 173, 181, 182, 163, + 180, 189, 84, 162, 172, 96, 155, 86, 170, 160, + 128, 114, 115, 85, 0, 149, 101, 106, 100, 137, + 167, 168, 99, 192, 90, 179, 88, 91, 178, 135, + 165, 171, 129, 126, 87, 169, 127, 125, 117, 104, + 111, 143, 124, 144, 112, 132, 131, 133, 0, 0, + 0, 159, 176, 193, 93, 0, 164, 183, 184, 185, + 186, 187, 188, 0, 0, 94, 107, 103, 142, 134, + 92, 113, 156, 116, 123, 148, 191, 139, 153, 97, + 175, 157, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 138, 0, 0, 0, 0, 0, 0, + 0, 82, 102, 120, 190, 147, 105, 177, 119, 0, + 121, 0, 0, 158, 130, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 80, 0, 521, 0, 0, 0, 0, 0, + 0, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 108, 0, 0, 0, 209, 0, 0, 0, 0, 145, - 0, 161, 110, 118, 83, 89, 0, 109, 136, 150, - 154, 0, 0, 0, 98, 0, 152, 140, 174, 0, - 141, 151, 122, 166, 146, 173, 181, 182, 163, 180, - 189, 84, 162, 172, 96, 155, 86, 170, 160, 128, - 114, 115, 85, 0, 149, 101, 106, 100, 137, 167, - 168, 99, 192, 90, 179, 88, 91, 178, 135, 165, - 171, 129, 126, 87, 169, 127, 125, 117, 104, 111, - 143, 124, 144, 112, 132, 131, 133, 0, 0, 0, - 159, 176, 193, 93, 0, 164, 183, 184, 185, 186, - 187, 188, 0, 0, 94, 107, 103, 142, 134, 92, - 113, 156, 116, 123, 148, 191, 139, 153, 97, 175, - 157, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 138, 82, 0, - 120, 190, 147, 105, 177, 590, 102, 0, 0, 0, - 0, 0, 119, 0, 121, 0, 0, 158, 130, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 207, 0, 0, 0, - 0, 0, 0, 0, 0, 95, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 108, 0, 0, 0, + 209, 0, 0, 0, 0, 145, 0, 161, 110, 118, + 83, 89, 0, 109, 136, 150, 154, 0, 0, 0, + 98, 0, 152, 140, 174, 0, 141, 151, 122, 166, + 146, 173, 181, 182, 163, 180, 189, 84, 162, 172, + 96, 155, 86, 170, 160, 128, 114, 115, 85, 0, + 149, 101, 106, 100, 137, 167, 168, 99, 192, 90, + 179, 88, 91, 178, 135, 165, 171, 129, 126, 87, + 169, 127, 125, 117, 104, 111, 143, 124, 144, 112, + 132, 131, 133, 0, 0, 0, 159, 176, 193, 93, + 0, 164, 183, 184, 185, 186, 187, 188, 0, 0, + 94, 107, 103, 142, 134, 92, 113, 156, 116, 123, + 148, 191, 139, 153, 97, 175, 157, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 138, 82, 0, 120, 190, + 147, 105, 177, 596, 102, 0, 0, 0, 0, 0, + 119, 0, 121, 0, 0, 158, 130, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 207, 0, 0, 0, 0, 0, + 0, 0, 0, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 108, 0, 0, 0, 209, 0, 0, 0, 0, 145, - 0, 161, 110, 118, 83, 89, 0, 109, 136, 150, - 154, 0, 0, 0, 98, 0, 152, 140, 174, 0, - 141, 151, 122, 166, 146, 173, 181, 182, 163, 180, - 189, 84, 162, 172, 96, 155, 86, 170, 160, 128, - 114, 115, 85, 0, 149, 101, 106, 100, 137, 167, - 168, 99, 192, 90, 179, 88, 91, 178, 135, 165, - 171, 129, 126, 87, 169, 127, 125, 117, 104, 111, - 143, 124, 144, 112, 132, 131, 133, 0, 0, 0, - 159, 176, 193, 93, 0, 164, 183, 184, 185, 186, - 187, 188, 0, 0, 94, 107, 103, 142, 134, 92, - 113, 156, 116, 123, 148, 191, 139, 153, 97, 175, - 157, 0, 0, 324, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 108, 0, + 0, 0, 209, 0, 0, 0, 0, 145, 0, 161, + 110, 118, 83, 89, 0, 109, 136, 150, 154, 0, + 0, 0, 98, 0, 152, 140, 174, 0, 141, 151, + 122, 166, 146, 173, 181, 182, 163, 180, 189, 84, + 162, 172, 96, 155, 86, 170, 160, 128, 114, 115, + 85, 0, 149, 101, 106, 100, 137, 167, 168, 99, + 192, 90, 179, 88, 91, 178, 135, 165, 171, 129, + 126, 87, 169, 127, 125, 117, 104, 111, 143, 124, + 144, 112, 132, 131, 133, 0, 0, 0, 159, 176, + 193, 93, 0, 164, 183, 184, 185, 186, 187, 188, + 0, 0, 94, 107, 103, 142, 134, 92, 113, 156, + 116, 123, 148, 191, 139, 153, 97, 175, 157, 0, + 0, 0, 0, 326, 0, 0, 0, 0, 0, 0, 138, 0, 0, 0, 0, 0, 0, 0, 82, 102, 120, 190, 147, 105, 177, 119, 0, 121, 0, 0, 158, 130, 0, 0, 0, 0, 0, 0, 0, 0, @@ -1829,113 +1854,113 @@ var yyAct = [...]int{ 184, 185, 186, 187, 188, 0, 0, 94, 107, 103, 142, 134, 92, 113, 156, 116, 123, 148, 191, 139, 153, 97, 175, 157, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 138, 0, 0, 0, 0, 0, 0, - 0, 82, 102, 120, 190, 147, 105, 177, 119, 0, - 121, 0, 0, 158, 130, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 138, 0, 0, 0, 0, + 0, 0, 0, 82, 102, 120, 190, 147, 105, 177, + 119, 0, 121, 0, 0, 158, 130, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 207, 0, 0, 0, 0, 0, 0, 0, - 0, 95, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 207, 0, 0, 0, 0, 0, + 0, 0, 0, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 108, 0, 204, 0, - 209, 0, 0, 0, 0, 145, 0, 161, 110, 118, - 83, 89, 0, 109, 136, 150, 154, 0, 0, 0, - 98, 0, 152, 140, 174, 0, 141, 151, 122, 166, - 146, 173, 181, 182, 163, 180, 189, 84, 162, 172, - 96, 155, 86, 170, 160, 128, 114, 115, 85, 0, - 149, 101, 106, 100, 137, 167, 168, 99, 192, 90, - 179, 88, 91, 178, 135, 165, 171, 129, 126, 87, - 169, 127, 125, 117, 104, 111, 143, 124, 144, 112, - 132, 131, 133, 0, 0, 0, 159, 176, 193, 93, - 0, 164, 183, 184, 185, 186, 187, 188, 0, 0, - 94, 107, 103, 142, 134, 92, 113, 156, 116, 123, - 148, 191, 139, 153, 97, 175, 157, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 138, 0, 0, 0, - 0, 0, 0, 0, 82, 102, 120, 190, 147, 105, - 177, 119, 0, 121, 0, 0, 158, 130, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 108, 0, + 204, 0, 209, 0, 0, 0, 0, 145, 0, 161, + 110, 118, 83, 89, 0, 109, 136, 150, 154, 0, + 0, 0, 98, 0, 152, 140, 174, 0, 141, 151, + 122, 166, 146, 173, 181, 182, 163, 180, 189, 84, + 162, 172, 96, 155, 86, 170, 160, 128, 114, 115, + 85, 0, 149, 101, 106, 100, 137, 167, 168, 99, + 192, 90, 179, 88, 91, 178, 135, 165, 171, 129, + 126, 87, 169, 127, 125, 117, 104, 111, 143, 124, + 144, 112, 132, 131, 133, 0, 0, 0, 159, 176, + 193, 93, 0, 164, 183, 184, 185, 186, 187, 188, + 0, 0, 94, 107, 103, 142, 134, 92, 113, 156, + 116, 123, 148, 191, 139, 153, 97, 175, 157, 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, 95, 0, 0, 0, 0, 0, + 138, 0, 0, 0, 0, 0, 0, 0, 82, 102, + 120, 190, 147, 105, 177, 119, 0, 121, 0, 0, + 158, 130, 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, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 108, - 0, 0, 0, 209, 0, 0, 0, 0, 145, 0, - 161, 110, 118, 83, 89, 0, 109, 136, 150, 154, - 0, 0, 0, 98, 0, 152, 140, 174, 0, 141, - 151, 122, 166, 146, 173, 181, 182, 163, 180, 189, - 84, 162, 172, 96, 155, 86, 170, 160, 128, 114, - 115, 85, 0, 149, 101, 106, 100, 137, 167, 168, - 99, 192, 90, 179, 88, 91, 178, 135, 165, 171, - 129, 126, 87, 169, 127, 125, 117, 104, 111, 143, - 124, 144, 112, 132, 131, 133, 0, 0, 0, 159, - 176, 193, 93, 0, 164, 183, 184, 185, 186, 187, - 188, 0, 0, 94, 107, 103, 142, 134, 92, 113, - 156, 116, 123, 148, 191, 139, 153, 97, 175, 157, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 138, - 0, 0, 0, 0, 0, 0, 0, 82, 102, 120, - 190, 147, 105, 177, 119, 0, 121, 0, 0, 158, - 130, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 207, 0, - 0, 0, 0, 0, 0, 0, 0, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 108, 0, 0, 0, 209, 0, 0, + 0, 0, 145, 0, 161, 110, 118, 83, 89, 0, + 109, 136, 150, 154, 0, 0, 0, 98, 0, 152, + 140, 174, 0, 141, 151, 122, 166, 146, 173, 181, + 182, 163, 180, 189, 84, 162, 172, 96, 155, 86, + 170, 160, 128, 114, 115, 85, 0, 149, 101, 106, + 100, 137, 167, 168, 99, 192, 90, 179, 88, 91, + 178, 135, 165, 171, 129, 126, 87, 169, 127, 125, + 117, 104, 111, 143, 124, 144, 112, 132, 131, 133, + 0, 0, 0, 159, 176, 193, 93, 0, 164, 183, + 184, 185, 186, 187, 188, 0, 0, 94, 107, 103, + 142, 134, 92, 113, 156, 116, 123, 148, 191, 139, + 153, 97, 175, 157, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 138, 0, 0, 0, 0, + 0, 0, 0, 82, 102, 120, 190, 147, 105, 177, + 119, 0, 121, 0, 0, 158, 130, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 207, 0, 0, 0, 0, 0, + 0, 0, 0, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 108, 0, 0, 0, 209, 0, 0, 0, - 0, 145, 0, 161, 110, 118, 83, 89, 0, 109, - 136, 150, 154, 0, 0, 0, 98, 0, 152, 140, - 174, 0, 141, 151, 122, 166, 146, 173, 181, 182, - 163, 180, 189, 84, 162, 172, 96, 155, 86, 170, - 160, 128, 114, 115, 85, 0, 149, 101, 106, 100, - 137, 167, 168, 99, 192, 90, 179, 88, 91, 178, - 135, 165, 171, 129, 126, 87, 169, 127, 125, 117, - 104, 111, 143, 124, 144, 112, 132, 131, 133, 0, - 0, 0, 159, 176, 193, 93, 0, 164, 183, 184, - 185, 186, 187, 188, 0, 0, 94, 107, 103, 142, - 134, 92, 113, 156, 116, 123, 148, 191, 139, 153, - 97, 175, 157, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 138, 0, 0, 0, 0, 0, 0, 0, - 82, 102, 120, 190, 147, 105, 177, 119, 0, 121, - 0, 0, 158, 130, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 108, 0, + 0, 0, 209, 0, 0, 0, 0, 145, 0, 161, + 110, 118, 83, 89, 0, 109, 136, 150, 154, 0, + 0, 0, 98, 0, 152, 140, 174, 0, 141, 151, + 122, 166, 146, 173, 181, 182, 163, 180, 189, 84, + 162, 172, 96, 155, 86, 170, 160, 128, 114, 115, + 85, 0, 149, 101, 106, 100, 137, 167, 168, 99, + 192, 90, 179, 88, 91, 178, 135, 165, 171, 129, + 126, 87, 169, 127, 125, 117, 104, 111, 143, 124, + 144, 112, 132, 131, 133, 0, 0, 0, 159, 176, + 193, 93, 0, 164, 183, 184, 185, 186, 187, 188, + 0, 0, 94, 107, 103, 142, 134, 92, 113, 156, + 116, 123, 148, 191, 139, 153, 97, 175, 157, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 267, 0, 0, 0, 0, 0, 0, 0, 0, - 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 138, 0, 0, 0, 0, 0, 0, 0, 82, 102, + 120, 190, 147, 105, 177, 119, 0, 121, 0, 0, + 158, 130, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 267, + 0, 0, 0, 0, 0, 0, 0, 0, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 108, 0, 0, 0, 209, - 0, 0, 0, 0, 145, 0, 161, 110, 118, 83, - 89, 0, 109, 136, 150, 154, 0, 0, 0, 98, - 0, 152, 140, 174, 0, 141, 151, 122, 166, 146, - 173, 181, 182, 163, 180, 189, 84, 162, 172, 96, - 155, 86, 170, 160, 128, 114, 115, 85, 0, 149, - 101, 106, 100, 137, 167, 168, 99, 192, 90, 179, - 88, 91, 178, 135, 165, 171, 129, 126, 87, 169, - 127, 125, 117, 104, 111, 143, 124, 144, 112, 132, - 131, 133, 0, 0, 0, 159, 176, 193, 93, 0, - 164, 183, 184, 185, 186, 187, 188, 0, 0, 94, - 107, 103, 142, 134, 92, 113, 156, 116, 123, 148, - 191, 139, 153, 97, 175, 157, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 108, 0, 0, 0, 209, 0, 0, + 0, 0, 145, 0, 161, 110, 118, 83, 89, 0, + 109, 136, 150, 154, 0, 0, 0, 98, 0, 152, + 140, 174, 0, 141, 151, 122, 166, 146, 173, 181, + 182, 163, 180, 189, 84, 162, 172, 96, 155, 86, + 170, 160, 128, 114, 115, 85, 0, 149, 101, 106, + 100, 137, 167, 168, 99, 192, 90, 179, 88, 91, + 178, 135, 165, 171, 129, 126, 87, 169, 127, 125, + 117, 104, 111, 143, 124, 144, 112, 132, 131, 133, + 0, 0, 0, 159, 176, 193, 93, 0, 164, 183, + 184, 185, 186, 187, 188, 0, 0, 94, 107, 103, + 142, 134, 92, 113, 156, 116, 123, 148, 191, 139, + 153, 97, 175, 157, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 0, 120, 190, 147, 105, 177, } var yyPact = [...]int{ - 1854, -1000, -193, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, 894, 922, -1000, -1000, -1000, -1000, -1000, -1000, - 218, 7888, 20, 87, -31, 11175, 86, 119, 11641, -1000, - -3, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -81, -94, - -1000, 715, -1000, -1000, -1000, -1000, -1000, 867, 892, 759, - 870, 796, -1000, 6206, 58, 58, 10942, 5462, -1000, -1000, - 207, 11641, 82, 11641, -163, 55, 55, 55, -1000, -1000, + 1626, -1000, -185, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, 836, 880, -1000, -1000, -1000, -1000, -1000, -1000, + 213, 8072, 35, 87, -17, 11387, 86, 1773, 11857, -1000, + -13, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -78, -107, + -1000, 706, -1000, -1000, -1000, -1000, -1000, 833, 839, 720, + 828, 763, -1000, 6369, 59, 59, 11152, 5369, -1000, -1000, + 201, 11857, 80, 11857, -156, 55, 55, 55, -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, @@ -1946,22 +1971,23 @@ var yyPact = [...]int{ -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, 85, 11641, 201, -1000, 11641, 53, - 478, 53, 53, 53, 11641, -1000, 137, -1000, -1000, -1000, - 11641, 476, 819, 3374, 33, 3374, -1000, 3374, 3374, -1000, - 3374, 3, 3374, -75, 904, -1000, -1000, -1000, -1000, -50, - -1000, 3374, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, 508, 832, 6705, 6705, 894, - -1000, 715, -1000, -1000, -1000, 820, -1000, -1000, 275, 911, - -1000, 7655, 134, -1000, 6705, 1528, 708, -1000, -1000, 708, - -1000, -1000, 122, -1000, -1000, 7183, 7183, 7183, 7183, 7183, - 7183, 7183, 7183, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, -1000, 708, -1000, 6457, - 708, 708, 708, 708, 708, 708, 708, 708, 6705, 708, - 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, - 708, 708, 10709, 9537, 11641, 504, -1000, 686, 5201, -91, - -1000, -1000, -1000, 204, 9304, -1000, -1000, -1000, 818, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, 84, 11857, 178, -1000, 11857, 53, + 522, 53, 53, 53, 11857, -1000, 123, -1000, -1000, -1000, + 11857, 483, 795, 3265, 42, 3265, -1000, 3265, 3265, -1000, + 3265, 4, 3265, -80, 850, -1000, -1000, -1000, -1000, -21, + -1000, 3265, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, 482, 801, 6870, 6870, 836, + -1000, 706, -1000, -1000, -1000, 788, -1000, -1000, 256, 864, + -1000, 7837, 121, -1000, 6870, 1412, 694, -1000, -1000, 694, + -1000, -1000, 111, -1000, -1000, 7358, 7358, 7358, 7358, 7358, + 7358, 7358, 7358, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, 694, -1000, 6620, + 694, 694, 694, 694, 694, 694, 694, 694, 6870, 694, + 694, 694, 694, 694, 694, 694, 694, 694, 694, 694, + 694, 694, 694, 694, 10917, 9735, 11857, 647, -1000, 687, + 5106, -103, -1000, -1000, -1000, 217, 9500, -1000, -1000, -1000, + 793, -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, @@ -1970,129 +1996,130 @@ 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, 598, 11641, -1000, 2036, -1000, 471, 3374, - 67, 463, 257, 460, 11641, 11641, 3374, 12, 41, 84, - 11641, 706, 65, 11641, 856, 763, 11641, 448, 444, -1000, - 4940, -1000, 3374, 3374, -1000, -1000, -1000, 3374, 3374, 3374, - 3374, 3374, 3374, -1000, -1000, -1000, -1000, 3374, 3374, -1000, - 909, 256, -1000, -1000, -1000, -1000, 6705, -1000, 762, -1000, - -1000, -1000, -1000, -1000, -1000, 917, 177, 430, 133, 695, - -1000, 371, 867, 508, 796, 9065, 773, -1000, -1000, 11641, - -1000, 6705, 6705, 339, -1000, 10469, -1000, -1000, 3896, 168, - 7183, 351, 285, 7183, 7183, 7183, 7183, 7183, 7183, 7183, - 7183, 7183, 7183, 7183, 7183, 7183, 7183, 7183, 396, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, -1000, 442, -1000, 715, - 525, 525, 148, 148, 148, 148, 148, 148, 148, 7422, - 5710, 508, 550, 281, 6457, 6206, 6206, 6705, 6705, 10236, - 10003, 6206, 860, 227, 281, 11874, -1000, 508, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, 6206, 6206, 6206, 6206, 24, - 11641, -1000, 615, 700, -1000, -1000, -1000, 858, 8599, 8832, - 24, 643, 9537, 11641, -1000, -1000, 4679, 686, -91, 678, - -1000, -130, -103, 2566, 124, -1000, -1000, -1000, -1000, 3113, - 172, 554, 316, -64, -1000, -1000, -1000, 718, -1000, 718, - 718, 718, 718, -32, -32, -32, -32, -1000, -1000, -1000, - -1000, -1000, 742, 741, -1000, 718, 718, 718, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, 580, 11857, -1000, + 2034, -1000, 477, 3265, 65, 464, 244, 462, 11857, 11857, + 3265, 12, 30, 83, 11857, 689, 63, 11857, 819, 738, + 11857, 454, 452, -1000, 4843, -1000, 3265, 3265, -1000, -1000, + -1000, 3265, 3265, 3265, 3265, 3265, 3265, -1000, -1000, -1000, + -1000, 3265, 3265, -1000, 852, 236, -1000, -1000, -1000, -1000, + 6870, -1000, 737, -1000, -1000, -1000, -1000, -1000, -1000, 875, + 152, 620, 119, 688, -1000, 380, 833, 482, 763, 9259, + 729, -1000, -1000, 11857, -1000, 6870, 6870, 430, -1000, 10675, + -1000, -1000, 3791, 170, 7358, 354, 299, 7358, 7358, 7358, + 7358, 7358, 7358, 7358, 7358, 7358, 7358, 7358, 7358, 7358, + 7358, 7358, 407, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, 445, -1000, 706, 540, 540, 132, 132, 132, 132, + 132, 132, 132, 7602, 5869, 482, 578, 368, 6620, 6369, + 6369, 6870, 6870, 10440, 10205, 6369, 823, 230, 368, 12092, + -1000, 482, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 11622, + 11622, 6369, 6369, 6369, 6369, 22, 11857, -1000, 646, 719, + -1000, -1000, -1000, 821, 8789, 9024, 22, 655, 9735, 11857, + -1000, -1000, 4580, 687, -103, 679, -1000, -133, -123, 5619, + 131, -1000, -1000, -1000, -1000, 3002, 206, 581, 265, -69, + -1000, -1000, -1000, 702, -1000, 702, 702, 702, 702, -38, + -38, -38, -38, -1000, -1000, -1000, -1000, -1000, 725, 723, + -1000, 702, 702, 702, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, 739, 739, 739, 724, 724, 744, - -1000, 11641, 3374, 854, 3374, -1000, 108, -1000, 11408, 11408, - 11641, 11641, 113, 11641, 11641, 684, -1000, 11641, 3374, -1000, + 722, 722, 722, 704, 704, 697, -1000, 11857, 3265, 818, + 3265, -1000, 125, -1000, 11622, 11622, 11857, 11857, 95, 11857, + 11857, 683, -1000, 11857, 3265, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, 11641, 288, 11641, 11641, 281, 11641, - -1000, 802, 6705, 6705, 4418, 6705, -1000, -1000, -1000, 832, - -1000, 860, 886, -1000, 812, 809, 6206, -1000, -1000, 168, - 230, -1000, -1000, 397, -1000, -1000, -1000, -1000, 132, 708, - -1000, 2052, -1000, -1000, -1000, -1000, 351, 7183, 7183, 7183, - 451, 2052, 2193, 999, 393, 148, 265, 265, 144, 144, - 144, 144, 144, 329, 329, -1000, -1000, -1000, 508, -1000, - -1000, -1000, 508, 6206, 680, -1000, -1000, 6705, -1000, 508, - 539, 539, 386, 255, 683, 682, -1000, 127, 679, 658, - 539, 6206, 242, -1000, 6705, 508, -1000, 539, 508, 539, - 539, 665, 708, -1000, 11874, 9537, 9537, 9537, 9537, 9537, - -1000, 785, 784, -1000, 777, 775, 786, 11641, -1000, 546, - 8599, 136, 708, -1000, 9770, -1000, -1000, 903, 9537, 596, - -1000, -1000, 678, -91, -95, -1000, -1000, -1000, -1000, 281, - -1000, 423, 671, 2852, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, 737, 424, -1000, 843, 166, 165, 417, 842, -1000, - -1000, -1000, 823, -1000, 262, -77, -1000, -1000, 374, -32, - -32, -1000, -1000, 124, 817, 124, 124, 124, 403, 403, - -1000, -1000, -1000, -1000, 357, -1000, -1000, -1000, 354, -1000, - 760, 11408, 3374, -1000, -1000, -1000, -1000, 250, 250, 219, + 11857, 242, 11857, 11857, 368, 11857, -1000, 770, 6870, 6870, + 4317, 6870, -1000, -1000, -1000, 801, -1000, 823, 835, -1000, + 785, 777, 6369, -1000, -1000, 170, 240, -1000, -1000, 277, + -1000, -1000, -1000, -1000, 117, 694, -1000, 2333, -1000, -1000, + -1000, -1000, 354, 7358, 7358, 7358, 448, 2333, 1972, 389, + 1870, 132, 149, 149, 133, 133, 133, 133, 133, 550, + 550, -1000, -1000, -1000, 482, -1000, -1000, -1000, 482, 6369, + 682, -1000, -1000, 6870, -1000, 482, 569, 569, 390, 365, + 696, 692, -1000, 116, 686, 651, 569, 6369, 229, -1000, + 6870, 482, -1000, 681, 680, 569, 482, 569, 569, 610, + 694, -1000, 12092, 9735, 9735, 9735, 9735, 9735, -1000, 758, + 753, -1000, 751, 750, 757, 11857, -1000, 574, 8789, 134, + 694, -1000, 9970, -1000, -1000, 847, 9735, 644, -1000, -1000, + 679, -103, -138, -1000, -1000, -1000, -1000, 368, -1000, 421, + 667, 2739, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 721, + 440, -1000, 811, 173, 165, 438, 810, -1000, -1000, -1000, + 802, -1000, 246, -74, -1000, -1000, 341, -38, -38, -1000, + -1000, 131, 792, 131, 131, 131, 412, 412, -1000, -1000, + -1000, -1000, 328, -1000, -1000, -1000, 326, -1000, 736, 11622, + 3265, -1000, -1000, -1000, -1000, 283, 283, 180, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 21, + 693, -1000, -1000, -1000, 11, 9, 62, -1000, 3265, -1000, + 236, -1000, 400, 6870, -1000, -1000, -1000, 767, 368, 368, + 115, -1000, -1000, 11857, -1000, -1000, -1000, -1000, 634, -1000, + -1000, -1000, 3528, 6369, -1000, 448, 2333, 1483, -1000, 7358, + 7358, -1000, -1000, 569, 6369, 368, -1000, -1000, -1000, 112, + 407, 112, 7358, 7358, 7358, 7358, 4317, 7358, 7358, 7358, + 7358, -168, 616, 219, -1000, 6870, 330, -1000, 7358, 7358, + -1000, -1000, -1000, -1000, 735, 12092, 694, -1000, 8548, 11622, + 684, -1000, 190, 719, 718, 733, 675, -1000, -1000, -1000, + -1000, 752, -1000, 749, -1000, -1000, -1000, -1000, -1000, 79, + 76, 70, 11622, -1000, 836, 6870, 644, -1000, -1000, -1000, + -137, -128, -1000, -1000, -1000, 3002, -1000, 3002, 11622, 39, + -1000, 438, 438, -1000, -1000, -1000, 715, 732, 74, -1000, + -1000, -1000, 571, 131, 131, -1000, 179, -1000, -1000, -1000, + 559, -1000, 556, 660, 531, 11857, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, 22, 735, -1000, -1000, -1000, 11, 10, 64, -1000, - 3374, -1000, 256, -1000, 391, 6705, -1000, -1000, -1000, 799, - 281, 281, 126, -1000, -1000, 11641, -1000, -1000, -1000, -1000, - 623, -1000, -1000, -1000, 3635, 6206, -1000, 451, 2052, 1357, - -1000, 7183, 7183, -1000, -1000, 539, 6206, 281, -1000, -1000, - -1000, 72, 396, 72, 7183, 7183, 7183, 7183, 4418, 7183, - 7183, 7183, 7183, -173, 642, 211, -1000, 6705, 313, -1000, - -1000, -1000, -1000, -1000, 752, 11874, 708, -1000, 8360, 11408, - 651, -1000, 200, 700, 734, 750, 711, -1000, -1000, -1000, - -1000, 781, -1000, 778, -1000, -1000, -1000, -1000, -1000, 80, - 79, 78, 11408, -1000, 894, 6705, 596, -1000, -1000, -1000, - -138, -144, -1000, -1000, -1000, 3113, -1000, 3113, 11408, 40, - -1000, 417, 417, -1000, -1000, -1000, 731, 749, 71, -1000, - -1000, -1000, 540, 124, 124, -1000, 163, -1000, -1000, -1000, - 518, -1000, 515, 657, 511, 11641, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, 11641, -1000, -1000, -1000, -1000, -1000, 11408, -181, - 399, 11408, 11408, 11641, -1000, 288, -1000, 281, -1000, 4157, - -1000, 903, 9537, -1000, -1000, 508, -1000, 7183, 2052, 2052, - -1000, -1000, 508, 718, 718, -1000, 718, 724, -1000, 718, - -12, 718, -13, 508, 508, 1843, 2151, 1671, 2025, -1000, - 1635, 1992, 1320, 1974, 708, -170, -1000, 281, 6705, -1000, - 845, 622, 647, -1000, -1000, 5958, 508, 506, 103, 486, - -1000, 894, 11874, 6705, -1000, -1000, 6705, 723, -1000, 6705, - -1000, -1000, -1000, 708, 708, 708, 486, 867, 281, -1000, - -1000, -1000, -1000, 2852, -1000, 484, -1000, 718, -1000, -1000, - -1000, 11408, -56, 916, -1000, -1000, -1000, -1000, 717, -1000, - -1000, -1000, -1000, -1000, -1000, -32, 383, -32, 350, -1000, - 333, 3374, -1000, -1000, -1000, -1000, 849, -1000, 4157, -1000, - -1000, 716, -1000, -1000, -1000, 900, 654, -1000, 2052, -1000, - -1000, 100, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, 7183, 7183, -1000, 7183, 7183, -1000, 7183, 7183, -1000, - 7183, 7183, 7183, 508, 379, 281, 830, -1000, 708, -1000, - -1000, 670, 11408, 11408, -1000, 11408, 867, -1000, 281, 281, - 11408, 281, 11408, 11408, 11408, 8121, -1000, 131, 11408, -1000, - 482, -1000, 185, -1000, -153, 534, 124, -1000, 124, 524, - 519, -1000, 708, 648, -1000, 199, 11408, 898, 891, -1000, - -1000, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858, 17, - -1000, -1000, 914, -1000, 708, -1000, 715, 83, -1000, -1000, - -1000, 467, 458, 458, 458, 136, 131, -1000, 395, 176, - 378, -1000, 37, 11408, 266, 829, -1000, 827, 714, -1000, - -1000, -1000, -1000, -1000, 21, 4157, 3113, 456, -1000, 6705, - 6705, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 508, - 34, -184, 11874, 647, 508, 11408, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, 302, -1000, -1000, 11641, -1000, -1000, 340, - -1000, -1000, 512, 452, -1000, 11408, -1000, -1000, 735, 281, - 628, -1000, 795, -179, -187, 586, -1000, -1000, -1000, 713, - -1000, -1000, -1000, 21, 808, -181, -1000, 793, -1000, 11408, - -1000, 18, -1000, -182, 428, 16, -185, 748, 708, -189, - 747, -1000, 908, 6944, -1000, -1000, 910, 152, 152, 1858, - 508, -1000, -1000, -1000, 44, 326, -1000, -1000, -1000, -1000, - -1000, -1000, + -1000, -1000, 11857, -1000, -1000, -1000, -1000, -1000, 11622, -175, + 424, 11622, 11622, 11857, -1000, 242, -1000, 368, -1000, 4054, + -1000, 847, 9735, -1000, -1000, 482, -1000, 7358, 2333, 2333, + -1000, -1000, 482, 702, 702, -1000, 702, 704, -1000, 702, + -20, 702, -22, 482, 482, 1633, 2276, 1519, 2239, -1000, + 1434, 2150, 474, 1805, 694, -163, -1000, 368, 6870, 1031, + 329, -1000, 803, 608, 615, -1000, -1000, 6119, 482, 529, + 105, 510, -1000, 836, 12092, 6870, -1000, -1000, 6870, 703, + -1000, 6870, -1000, -1000, -1000, 694, 694, 694, 510, 833, + 368, -1000, -1000, -1000, -1000, 2739, -1000, 507, -1000, 702, + -1000, -1000, -1000, 11622, -62, 873, -1000, -1000, -1000, -1000, + 701, -1000, -1000, -1000, -1000, -1000, -1000, -38, 397, -38, + 323, -1000, 281, 3265, -1000, -1000, -1000, -1000, 814, -1000, + 4054, -1000, -1000, 699, -1000, -1000, -1000, 845, 628, -1000, + 2333, -1000, -1000, 91, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, 7358, 7358, -1000, 7358, 7358, -1000, 7358, + 7358, -1000, 7358, 7358, 7358, 482, 388, 368, 7358, 7358, + 808, -1000, 694, -1000, -1000, 671, 11622, 11622, -1000, 11622, + 833, -1000, 368, 368, 11622, 368, 11622, 11622, 11622, 8307, + -1000, 126, 11622, -1000, 503, -1000, 150, -1000, -146, 566, + 131, -1000, 131, 536, 533, -1000, 694, 627, -1000, 188, + 11622, 843, 837, -1000, -1000, 1656, 1656, 1656, 1656, 1656, + 1656, 1656, 1656, 24, -1000, -1000, 1656, 1656, 867, -1000, + 694, -1000, 706, 101, -1000, -1000, -1000, 501, 498, 498, + 498, 134, 126, -1000, 391, 183, 387, -1000, 34, 11622, + 253, 807, -1000, 806, 698, -1000, -1000, -1000, -1000, -1000, + 20, 4054, 3002, 481, -1000, 6870, 6870, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, 482, 43, -178, -1000, -1000, + 12092, 615, 482, 11622, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, 262, -1000, -1000, 11857, -1000, -1000, 347, -1000, -1000, + 504, 460, -1000, 11622, -1000, -1000, 693, 368, 588, -1000, + 766, -172, -181, 541, -1000, -1000, -1000, 695, -1000, -1000, + -1000, 20, 776, -175, -1000, 734, -1000, 11622, -1000, 17, + -1000, -176, 450, 7, -179, 731, 694, -182, 730, -1000, + 860, 7114, -1000, -1000, 862, 145, 145, 1656, 482, -1000, + -1000, -1000, 45, 313, -1000, -1000, -1000, -1000, -1000, -1000, } var yyPgo = [...]int{ - 0, 1146, 33, 449, 1145, 1144, 1143, 1142, 1141, 1139, - 1138, 1136, 1135, 1130, 1126, 1125, 1123, 1116, 1110, 1109, - 1108, 1092, 1091, 1089, 1088, 1087, 99, 1086, 1085, 1081, - 71, 1078, 60, 1077, 1076, 46, 76, 50, 41, 391, - 1072, 35, 53, 59, 1071, 38, 1070, 1069, 64, 1068, - 48, 1065, 1063, 201, 1060, 1059, 10, 30, 1058, 1057, - 1054, 1052, 98, 1042, 1050, 1049, 1048, 1046, 1045, 1044, - 51, 8, 12, 47, 19, 1043, 416, 6, 1040, 52, - 1039, 1036, 1033, 1032, 16, 1030, 57, 1027, 18, 56, - 1024, 15, 65, 28, 20, 7, 69, 58, 1018, 14, - 61, 54, 1017, 1016, 411, 1014, 1012, 42, 1011, 1009, - 26, 154, 326, 1008, 1007, 1004, 1002, 37, 0, 504, - 418, 63, 1001, 999, 997, 1597, 70, 49, 17, 988, - 55, 1216, 40, 987, 985, 31, 981, 980, 979, 978, - 971, 970, 969, 84, 966, 964, 963, 24, 22, 962, - 961, 62, 23, 958, 957, 955, 44, 66, 954, 953, - 45, 29, 950, 949, 948, 947, 946, 27, 9, 943, - 13, 941, 21, 940, 25, 939, 4, 935, 11, 934, - 3, 933, 5, 43, 1, 932, 2, 931, 930, 311, - 701, 929, 928, 107, + 0, 1099, 63, 410, 1098, 1097, 1096, 1095, 1091, 1090, + 1082, 1081, 1080, 1079, 1078, 1077, 1076, 1075, 1073, 1072, + 1071, 1068, 1064, 1063, 1059, 1057, 129, 1056, 1050, 1046, + 69, 1045, 71, 1040, 1037, 46, 47, 35, 26, 661, + 1035, 59, 66, 104, 1031, 37, 1030, 1029, 73, 1028, + 49, 1027, 1026, 1264, 1024, 1022, 11, 40, 1020, 1019, + 1018, 1017, 65, 889, 1014, 1007, 1006, 994, 993, 992, + 54, 7, 10, 13, 18, 990, 460, 8, 988, 48, + 987, 985, 984, 983, 33, 982, 56, 981, 21, 55, + 980, 27, 62, 28, 17, 12, 80, 58, 978, 19, + 61, 52, 977, 976, 442, 974, 973, 41, 971, 969, + 22, 176, 435, 968, 967, 966, 965, 38, 0, 672, + 349, 75, 964, 963, 960, 1588, 70, 44, 16, 959, + 31, 1610, 34, 958, 957, 29, 956, 955, 954, 952, + 950, 948, 947, 359, 946, 945, 943, 24, 30, 942, + 941, 60, 23, 940, 939, 938, 43, 57, 937, 935, + 53, 45, 933, 932, 930, 928, 927, 25, 4, 925, + 15, 924, 9, 923, 20, 921, 2, 913, 6, 908, + 1, 907, 3, 42, 5, 906, 14, 905, 899, 50, + 246, 898, 897, 81, } var yyR1 = [...]int{ @@ -2146,21 +2173,21 @@ var yyR1 = [...]int{ 63, 67, 67, 67, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 66, 66, 66, 66, 66, - 66, 66, 66, 193, 193, 68, 68, 68, 68, 33, - 33, 33, 33, 33, 132, 132, 135, 135, 135, 135, - 135, 135, 135, 135, 135, 135, 135, 135, 135, 80, - 80, 34, 34, 78, 78, 79, 81, 81, 77, 77, - 77, 62, 62, 62, 62, 62, 62, 62, 62, 64, - 64, 64, 82, 82, 83, 83, 84, 84, 85, 85, - 86, 87, 87, 87, 88, 88, 88, 88, 89, 89, - 89, 61, 61, 61, 61, 61, 61, 90, 90, 90, - 90, 94, 94, 72, 72, 74, 74, 73, 75, 95, - 95, 99, 96, 96, 100, 100, 100, 100, 98, 98, - 98, 124, 124, 124, 103, 103, 111, 111, 112, 112, - 104, 104, 113, 113, 113, 113, 113, 113, 113, 113, - 113, 113, 114, 114, 114, 115, 115, 116, 116, 116, - 123, 123, 119, 119, 120, 120, 125, 125, 126, 126, - 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, + 66, 66, 66, 66, 66, 193, 193, 68, 68, 68, + 68, 33, 33, 33, 33, 33, 132, 132, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, + 135, 80, 80, 34, 34, 78, 78, 79, 81, 81, + 77, 77, 77, 62, 62, 62, 62, 62, 62, 62, + 62, 64, 64, 64, 82, 82, 83, 83, 84, 84, + 85, 85, 86, 87, 87, 87, 88, 88, 88, 88, + 89, 89, 89, 61, 61, 61, 61, 61, 61, 90, + 90, 90, 90, 94, 94, 72, 72, 74, 74, 73, + 75, 95, 95, 99, 96, 96, 100, 100, 100, 100, + 98, 98, 98, 124, 124, 124, 103, 103, 111, 111, + 112, 112, 104, 104, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 114, 114, 114, 115, 115, 116, + 116, 116, 123, 123, 119, 119, 120, 120, 125, 125, + 126, 126, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, @@ -2169,7 +2196,7 @@ var yyR1 = [...]int{ 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, - 117, 117, 117, 118, 118, 118, 118, 118, 118, 118, + 117, 117, 117, 117, 117, 117, 117, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, @@ -2180,8 +2207,8 @@ var yyR1 = [...]int{ 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, - 118, 118, 118, 118, 118, 118, 189, 190, 130, 131, - 131, 131, + 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, + 189, 190, 130, 131, 131, 131, } var yyR2 = [...]int{ @@ -2235,20 +2262,21 @@ var yyR2 = [...]int{ 1, 4, 5, 6, 4, 4, 6, 6, 6, 6, 8, 8, 6, 8, 8, 6, 8, 8, 6, 8, 8, 9, 7, 5, 4, 2, 2, 2, 2, 2, - 2, 2, 2, 0, 2, 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, + 2, 2, 2, 8, 8, 0, 2, 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, @@ -2269,8 +2297,7 @@ 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, 1, 0, 0, - 1, 1, + 1, 1, 0, 0, 1, 1, } var yyChk = [...]int{ @@ -2279,21 +2306,21 @@ var yyChk = [...]int{ -22, -16, -3, -4, 6, 7, -29, 9, 10, 30, -17, 115, 116, 118, 117, 149, 119, 142, 50, 162, 163, 165, 166, 25, 143, 144, 147, 148, 31, 32, - 121, -189, 8, 251, 54, -188, 266, -84, 15, -28, + 121, -189, 8, 251, 54, -188, 268, -84, 15, -28, 5, -26, -192, -26, -26, -26, -26, -26, -163, -165, 54, 90, -116, 125, 72, 243, 122, 123, 129, -119, - 57, -118, 259, 135, 162, 173, 167, 194, 186, 136, + 57, -118, 261, 135, 162, 173, 167, 194, 186, 136, 184, 187, 230, 214, 225, 66, 165, 239, 145, 182, - 178, 176, 27, 227, 199, 264, 177, 226, 121, 138, + 178, 176, 27, 227, 199, 266, 177, 226, 121, 138, 133, 200, 204, 231, 171, 172, 233, 198, 134, 33, - 261, 35, 153, 234, 202, 197, 193, 196, 170, 192, + 263, 35, 153, 234, 202, 197, 193, 196, 170, 192, 39, 206, 205, 207, 229, 189, 139, 179, 18, 237, - 148, 151, 228, 201, 203, 130, 155, 263, 235, 175, + 148, 151, 228, 201, 203, 130, 155, 265, 235, 175, 140, 152, 147, 238, 141, 166, 232, 241, 38, 211, 169, 132, 163, 159, 216, 190, 154, 180, 181, 195, - 168, 191, 164, 156, 149, 240, 212, 265, 188, 185, + 168, 191, 164, 156, 149, 240, 212, 267, 188, 185, 160, 157, 158, 217, 218, 219, 220, 221, 222, 161, - 262, 236, 183, 213, -104, 125, 220, 127, 123, 123, + 264, 236, 183, 213, -104, 125, 220, 127, 123, 123, 124, 125, 243, 122, 123, -53, -125, 57, -118, 125, 123, 108, 187, 230, 115, 215, 227, 124, 33, 228, 155, -134, 123, -106, 214, 217, 218, 219, 222, 220, @@ -2304,74 +2331,75 @@ var yyChk = [...]int{ -62, -59, -77, -75, -76, 108, 109, 110, 97, 98, 105, 75, 111, -67, -65, -66, -68, 59, 58, 67, 60, 61, 62, 63, 68, 69, 70, -119, -73, -189, - 44, 45, 252, 253, 254, 255, 258, 256, 77, 34, - 242, 250, 249, 248, 246, 247, 244, 245, 128, 243, - 103, 251, -104, -104, 11, -48, -53, -96, -133, 164, - -100, 232, 231, -120, -98, -119, -117, 230, 187, 229, - 120, 73, 22, 24, 209, 76, 108, 16, 77, 107, - 252, 115, 48, 244, 245, 242, 254, 255, 243, 215, - 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, 246, 247, 31, 258, 150, 103, 49, 36, - 74, 68, 71, 52, 72, 15, 47, 91, 118, 251, - 45, 122, 6, 257, 30, 142, 43, 123, 79, 126, - 69, 5, 129, 32, 9, 50, 53, 248, 249, 250, - 34, 78, 12, -164, 90, -157, 57, -53, 124, -53, - 251, -112, 128, -112, -112, 123, -53, 115, 117, 120, - 52, -18, -53, -111, 128, 57, -111, -111, -111, -53, - 112, -53, 57, 30, -131, -189, -120, 243, 57, 155, - 123, 156, 125, -131, -131, -131, -131, 159, 160, -131, - -109, -108, 225, 226, 216, 224, 12, 216, 158, -131, - -130, -130, -190, 56, -89, 19, 31, -39, -125, -85, - -86, -39, -84, -2, -26, 36, -30, 21, 65, 11, - -122, 73, 72, 89, -121, 22, -119, 59, 112, -39, - -60, 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, -105, -189, -76, -189, - 113, 114, -63, -63, -63, -63, -63, -63, -63, -63, - -189, -2, -71, -39, -189, -189, -189, -189, -189, -189, - -189, -189, -189, -80, -39, -189, -193, -189, -193, -193, - -193, -193, -193, -193, -193, -189, -189, -189, -189, -54, - 26, -53, -41, -42, -43, -44, -55, -76, -189, -53, - -53, -48, -191, 55, 11, 53, 55, -96, 164, -97, - -101, 233, 235, 82, -124, -119, 59, 29, 30, 56, - 55, -53, -136, -139, -141, -140, -142, -137, -138, 184, - 185, 108, 188, 190, 191, 192, 193, 194, 195, 196, - 197, 198, 199, 30, 145, 180, 181, 182, 183, 200, - 201, 202, 203, 204, 205, 206, 207, 167, 168, 169, - 170, 171, 172, 173, 175, 176, 177, 178, 179, 57, - -131, 125, 57, 74, 57, -53, -53, -131, 157, 157, - 123, 123, -53, 55, 126, -48, 23, 52, -53, 57, - 57, -126, -125, -117, -131, -131, -131, -131, -131, -131, - -131, -131, -131, -131, 11, -107, 11, 92, -39, 52, - 9, 92, 55, 18, 112, 55, -87, 24, 25, -88, - -190, -32, -64, -119, 60, 63, -31, 43, -53, -39, - -39, -69, 68, 74, 69, 70, -121, 99, -126, -120, - -117, -63, -70, -73, -76, 64, 92, 90, 91, 76, + 44, 45, 252, 253, 254, 255, 260, 256, 77, 34, + 242, 250, 249, 248, 246, 247, 244, 245, 258, 259, + 128, 243, 103, 251, -104, -104, 11, -48, -53, -96, + -133, 164, -100, 232, 231, -120, -98, -119, -117, 230, + 187, 229, 120, 73, 22, 24, 209, 76, 108, 16, + 77, 107, 252, 115, 48, 244, 245, 242, 254, 255, + 243, 215, 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, 246, 247, 31, 260, 150, 103, + 49, 36, 74, 68, 71, 52, 72, 15, 47, 91, + 118, 251, 45, 122, 6, 257, 30, 142, 43, 123, + 79, 258, 259, 126, 69, 5, 129, 32, 9, 50, + 53, 248, 249, 250, 34, 78, 12, -164, 90, -157, + 57, -53, 124, -53, 251, -112, 128, -112, -112, 123, + -53, 115, 117, 120, 52, -18, -53, -111, 128, 57, + -111, -111, -111, -53, 112, -53, 57, 30, -131, -189, + -120, 243, 57, 155, 123, 156, 125, -131, -131, -131, + -131, 159, 160, -131, -109, -108, 225, 226, 216, 224, + 12, 216, 158, -131, -130, -130, -190, 56, -89, 19, + 31, -39, -125, -85, -86, -39, -84, -2, -26, 36, + -30, 21, 65, 11, -122, 73, 72, 89, -121, 22, + -119, 59, 112, -39, -60, 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, + -105, -189, -76, -189, 113, 114, -63, -63, -63, -63, + -63, -63, -63, -63, -189, -2, -71, -39, -189, -189, + -189, -189, -189, -189, -189, -189, -189, -80, -39, -189, + -193, -189, -193, -193, -193, -193, -193, -193, -193, -189, + -189, -189, -189, -189, -189, -54, 26, -53, -41, -42, + -43, -44, -55, -76, -189, -53, -53, -48, -191, 55, + 11, 53, 55, -96, 164, -97, -101, 233, 235, 82, + -124, -119, 59, 29, 30, 56, 55, -53, -136, -139, + -141, -140, -142, -137, -138, 184, 185, 108, 188, 190, + 191, 192, 193, 194, 195, 196, 197, 198, 199, 30, + 145, 180, 181, 182, 183, 200, 201, 202, 203, 204, + 205, 206, 207, 167, 168, 169, 170, 171, 172, 173, + 175, 176, 177, 178, 179, 57, -131, 125, 57, 74, + 57, -53, -53, -131, 157, 157, 123, 123, -53, 55, + 126, -48, 23, 52, -53, 57, 57, -126, -125, -117, + -131, -131, -131, -131, -131, -131, -131, -131, -131, -131, + 11, -107, 11, 92, -39, 52, 9, 92, 55, 18, + 112, 55, -87, 24, 25, -88, -190, -32, -64, -119, + 60, 63, -31, 43, -53, -39, -39, -69, 68, 74, + 69, 70, -121, 99, -126, -120, -117, -63, -70, -73, + -76, 64, 92, 90, 91, 76, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, - -63, -63, -63, -63, -63, -132, 57, 59, 57, -62, - -62, -119, -37, 21, -36, -38, -190, 55, -190, -2, - -36, -36, -39, -39, -77, 59, -119, -125, -77, 59, - -36, -30, -78, -79, 78, -77, -190, -36, -37, -36, - -36, -92, 151, -53, 30, 55, -49, -51, -50, -52, - 42, 46, 48, 43, 44, 45, 49, -129, 22, -41, - -189, -128, 151, -127, 22, -125, 59, -92, 53, -41, - -53, -100, -97, 55, 234, 236, 237, 52, 71, -39, - -148, 107, -166, -167, -168, -120, 59, 60, -157, -158, - -159, -169, 137, -174, 130, 132, 129, -160, 138, 124, - 28, 56, -153, 68, 74, -149, 212, -143, 54, -143, - -143, -143, -143, -147, 187, -147, -147, -147, 54, 54, - -143, -143, -143, -151, 54, -151, -151, -152, 54, -152, - -123, 53, -53, -131, 23, -131, -113, 120, 117, 118, - -177, 116, 209, 187, 66, 29, 15, 252, 151, 265, - 57, 152, -119, -119, -53, -53, 120, 117, -53, -53, - -53, -131, -53, -110, 90, 12, -125, -125, -53, 38, - -39, -39, -126, -86, -89, -103, 19, 11, 34, 34, - -36, 68, 69, 70, 112, -189, -70, -63, -63, -63, - -35, 146, 73, -190, -190, -36, 55, -39, -190, -190, - -190, 55, 53, 22, 55, 11, 55, 11, 112, 55, - 11, 55, 11, -190, -36, -81, -79, 80, -39, -190, + -63, -132, 57, 59, 57, -62, -62, -119, -37, 21, + -36, -38, -190, 55, -190, -2, -36, -36, -39, -39, + -77, 59, -119, -125, -77, 59, -36, -30, -78, -79, + 78, -77, -190, -119, -119, -36, -37, -36, -36, -92, + 151, -53, 30, 55, -49, -51, -50, -52, 42, 46, + 48, 43, 44, 45, 49, -129, 22, -41, -189, -128, + 151, -127, 22, -125, 59, -92, 53, -41, -53, -100, + -97, 55, 234, 236, 237, 52, 71, -39, -148, 107, + -166, -167, -168, -120, 59, 60, -157, -158, -159, -169, + 137, -174, 130, 132, 129, -160, 138, 124, 28, 56, + -153, 68, 74, -149, 212, -143, 54, -143, -143, -143, + -143, -147, 187, -147, -147, -147, 54, 54, -143, -143, + -143, -151, 54, -151, -151, -152, 54, -152, -123, 53, + -53, -131, 23, -131, -113, 120, 117, 118, -177, 116, + 209, 187, 66, 29, 15, 252, 151, 267, 57, 152, + -119, -119, -53, -53, 120, 117, -53, -53, -53, -131, + -53, -110, 90, 12, -125, -125, -53, 38, -39, -39, + -126, -86, -89, -103, 19, 11, 34, 34, -36, 68, + 69, 70, 112, -189, -70, -63, -63, -63, -35, 146, + 73, -190, -190, -36, 55, -39, -190, -190, -190, 55, + 53, 22, 55, 11, 55, 11, 112, 55, 11, 55, + 11, -190, -36, -81, -79, 80, -39, -190, 55, 55, -190, -190, -190, -190, -61, 30, 34, -2, -189, -189, -95, -99, -77, -42, -43, -43, -42, -43, 42, 42, 42, 47, 42, 47, 42, -50, -125, -190, -56, 50, @@ -2386,75 +2414,75 @@ var yyChk = [...]int{ -53, -40, 11, 99, -120, -37, -35, 73, -63, -63, -190, -38, -135, 108, 184, 145, 182, 178, 198, 189, 211, 180, 212, -132, -135, -63, -63, -63, -63, -120, - -63, -63, -63, -63, 259, -84, 81, -39, 79, -94, - 52, -95, -72, -74, -73, -189, -2, -90, -119, -93, - -119, -57, 55, 82, -46, -45, 52, 53, -47, 52, - -45, 42, 42, 124, 124, 124, -93, -84, -39, -57, - 235, 239, 240, -167, -168, -171, -170, -119, -174, -161, - -161, 54, -146, 52, 59, 60, 61, 68, 242, 67, - 56, -148, -148, 57, 108, 56, 55, 56, 55, 56, - 55, -53, -130, -130, -53, -130, -119, -180, 262, -181, - 57, -119, -119, -53, -110, -57, -41, -190, -63, -190, - -143, -143, -143, -152, -143, 172, -143, 172, -190, -190, - -190, 55, 19, -190, 55, 19, -190, 55, 19, -190, - 55, 19, -189, -34, 257, -39, 27, -94, 55, -190, - -190, -190, 55, 112, -190, 55, -84, -99, -39, -39, - 54, -39, -189, -189, -189, -190, -88, 56, 55, -143, - -91, -119, -154, 209, 9, 54, -147, 59, -147, 60, - 60, -131, 26, -179, -178, -120, 54, -82, 13, -147, - 57, -63, -63, -63, -63, -63, -63, -63, -63, -63, - -190, 59, 28, -74, 34, -2, -189, -119, -119, -119, - -88, -91, -91, -91, -91, -128, -173, -172, 53, 134, - 66, -170, 56, 55, -155, 130, 28, 129, 242, 56, - -148, -148, 56, 56, -189, 55, 82, -91, -83, 14, - 16, -190, -190, -190, -190, -190, -190, -190, -190, -33, - 92, 262, 9, -72, -2, 112, 56, -190, -190, -190, - -56, -172, 57, -162, 82, 59, 140, -119, -145, 66, - 28, 28, 54, -175, -176, 151, -178, -168, 56, -39, - -71, -190, 260, 49, 263, -95, -190, -119, 60, -53, - 59, 56, -190, 55, -119, -182, 39, 261, 264, 54, - -176, 34, -180, 39, -91, 153, 262, 56, 154, 263, - -185, -186, 52, -189, 264, -186, 52, 10, 9, -63, - 150, -184, 141, 136, 139, 30, -184, -190, -190, 135, - 29, 68, + -63, -63, -63, -63, 261, -84, 81, -39, 79, -63, + -63, -94, 52, -95, -72, -74, -73, -189, -2, -90, + -119, -93, -119, -57, 55, 82, -46, -45, 52, 53, + -47, 52, -45, 42, 42, 124, 124, 124, -93, -84, + -39, -57, 235, 239, 240, -167, -168, -171, -170, -119, + -174, -161, -161, 54, -146, 52, 59, 60, 61, 68, + 242, 67, 56, -148, -148, 57, 108, 56, 55, 56, + 55, 56, 55, -53, -130, -130, -53, -130, -119, -180, + 264, -181, 57, -119, -119, -53, -110, -57, -41, -190, + -63, -190, -143, -143, -143, -152, -143, 172, -143, 172, + -190, -190, -190, 55, 19, -190, 55, 19, -190, 55, + 19, -190, 55, 19, -189, -34, 257, -39, 55, 55, + 27, -94, 55, -190, -190, -190, 55, 112, -190, 55, + -84, -99, -39, -39, 54, -39, -189, -189, -189, -190, + -88, 56, 55, -143, -91, -119, -154, 209, 9, 54, + -147, 59, -147, 60, 60, -131, 26, -179, -178, -120, + 54, -82, 13, -147, 57, -63, -63, -63, -63, -63, + -63, -63, -63, -63, -190, 59, -63, -63, 28, -74, + 34, -2, -189, -119, -119, -119, -88, -91, -91, -91, + -91, -128, -173, -172, 53, 134, 66, -170, 56, 55, + -155, 130, 28, 129, 242, 56, -148, -148, 56, 56, + -189, 55, 82, -91, -83, 14, 16, -190, -190, -190, + -190, -190, -190, -190, -190, -33, 92, 264, -190, -190, + 9, -72, -2, 112, 56, -190, -190, -190, -56, -172, + 57, -162, 82, 59, 140, -119, -145, 66, 28, 28, + 54, -175, -176, 151, -178, -168, 56, -39, -71, -190, + 262, 49, 265, -95, -190, -119, 60, -53, 59, 56, + -190, 55, -119, -182, 39, 263, 266, 54, -176, 34, + -180, 39, -91, 153, 264, 56, 154, 265, -185, -186, + 52, -189, 266, -186, 52, 10, 9, -63, 150, -184, + 141, 136, 139, 30, -184, -190, -190, 135, 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, 317, 317, 317, 317, 317, 317, - 0, 627, 610, 0, 0, 0, 0, -2, 304, 305, - 0, 307, 308, 848, 848, 848, 848, 848, 0, 0, - 848, 0, 35, 36, 846, 1, 3, 564, 0, 0, - 321, 324, 319, 0, 610, 610, 0, 0, 62, 63, - 0, 0, 0, 832, 0, 608, 608, 608, 628, 629, - 632, 633, 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, - 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, 833, 834, 835, 836, 837, 838, 839, 840, 841, - 842, 843, 844, 845, 0, 0, 0, 611, 0, 606, - 0, 606, 606, 606, 0, 255, 389, 636, 637, 832, - 0, 0, 0, 849, 0, 849, 267, 849, 849, 270, - 849, 0, 849, 0, 277, 279, 280, 281, 282, 0, - 286, 849, 301, 302, 291, 303, 306, 309, 310, 311, - 312, 313, 848, 848, 316, 29, 568, 0, 0, 556, + 21, 22, 558, 0, 317, 317, 317, 317, 317, 317, + 0, 629, 612, 0, 0, 0, 0, -2, 304, 305, + 0, 307, 308, 852, 852, 852, 852, 852, 0, 0, + 852, 0, 35, 36, 850, 1, 3, 566, 0, 0, + 321, 324, 319, 0, 612, 612, 0, 0, 62, 63, + 0, 0, 0, 836, 0, 610, 610, 610, 630, 631, + 634, 635, 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, 845, + 846, 847, 848, 849, 0, 0, 0, 613, 0, 608, + 0, 608, 608, 608, 0, 255, 389, 638, 639, 836, + 0, 0, 0, 853, 0, 853, 267, 853, 853, 270, + 853, 0, 853, 0, 277, 279, 280, 281, 282, 0, + 286, 853, 301, 302, 291, 303, 306, 309, 310, 311, + 312, 313, 852, 852, 316, 29, 570, 0, 0, 558, 31, 0, 317, 322, 323, 327, 325, 326, 318, 0, 335, 339, 0, 397, 0, 402, 404, -2, -2, 0, 439, 440, 441, 442, 443, 0, 0, 0, 0, 0, - 0, 0, 0, 467, 468, 469, 470, 541, 542, 543, - 544, 545, 546, 547, 548, 406, 407, 538, 588, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 529, 0, - 503, 503, 503, 503, 503, 503, 503, 503, 0, 0, - 0, 0, 0, 0, 0, 0, 43, 47, 0, 823, - 592, -2, -2, 0, 0, 634, 635, -2, 742, -2, - 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, + 0, 0, 0, 467, 468, 469, 470, 543, 544, 545, + 546, 547, 548, 549, 550, 406, 407, 540, 590, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 531, 0, + 505, 505, 505, 505, 505, 505, 505, 505, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 43, 47, + 0, 827, 594, -2, -2, 0, 0, 636, 637, -2, + 746, -2, 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, @@ -2463,106 +2491,107 @@ var yyDef = [...]int{ 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, 0, 0, 81, 0, 79, 0, 849, - 0, 0, 0, 0, 0, 0, 849, 0, 0, 0, - 0, 246, 0, 0, 0, 0, 0, 0, 0, 254, - 0, 256, 849, 849, 259, 850, 851, 849, 849, 849, - 849, 849, 849, 266, 268, 269, 271, 849, 849, 273, - 0, 294, 292, 293, 288, 289, 0, 283, 284, 287, - 314, 315, 30, 847, 24, 0, 0, 565, 0, 557, - 558, 561, 564, 29, 324, 0, 329, 328, 320, 0, - 336, 0, 0, 0, 340, 0, 342, 343, 0, 400, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 424, - 425, 426, 427, 428, 429, 430, 403, 0, 417, 0, - 0, 0, 459, 460, 461, 462, 463, 464, 465, 0, - 331, 29, 0, 437, 0, 0, 0, 0, 0, 0, - 0, 0, 327, 0, 530, 0, 495, 0, 496, 497, - 498, 499, 500, 501, 502, 0, 331, 0, 0, 45, - 0, 388, 0, 346, 348, 349, 350, -2, 0, 372, - -2, 0, 0, 0, 41, 42, 0, 48, 823, 50, - 51, 0, 0, 0, 164, 601, 602, 603, 599, 208, - 0, 0, 145, 141, 87, 88, 89, 134, 91, 134, - 134, 134, 134, 161, 161, 161, 161, 117, 118, 119, - 120, 121, 0, 0, 104, 134, 134, 134, 108, 124, - 125, 126, 127, 128, 129, 130, 131, 92, 93, 94, - 95, 96, 97, 98, 136, 136, 136, 138, 138, 630, - 65, 0, 849, 0, 849, 77, 0, 222, 0, 0, - 0, 0, 0, 0, 0, 249, 607, 0, 849, 252, - 253, 390, 638, 639, 257, 258, 260, 261, 262, 263, - 264, 265, 272, 276, 0, 297, 0, 0, 278, 0, - 569, 0, 0, 0, 0, 0, 560, 562, 563, 568, - 32, 327, 0, 549, 0, 0, 0, 330, 27, 398, - 399, 401, 418, 0, 420, 422, 341, 337, 0, 539, - -2, 408, 409, 433, 434, 435, 0, 0, 0, 0, - 431, 413, 0, 444, 445, 446, 447, 448, 449, 450, - 451, 452, 453, 454, 455, 458, 514, 515, 0, 456, - 457, 466, 0, 0, 332, 333, 436, 0, 587, 29, - 0, 0, 0, 0, 0, 0, 538, 0, 0, 0, - 0, 0, 536, 533, 0, 0, 504, 0, 0, 0, - 0, 0, 0, 387, 0, 0, 0, 0, 0, 0, - 377, 0, 0, 380, 0, 0, 0, 0, 371, 0, - 0, 391, 792, 373, 0, 375, 376, 395, 0, 395, - 44, 593, 49, 0, 0, 54, 55, 594, 595, 596, - 597, 0, 78, 209, 211, 214, 215, 216, 82, 83, - 84, 0, 0, 196, 0, 0, 190, 190, 0, 188, - 189, 80, 148, 146, 0, 143, 142, 90, 0, 161, - 161, 111, 112, 164, 0, 164, 164, 164, 0, 0, - 105, 106, 107, 99, 0, 100, 101, 102, 0, 103, - 0, 0, 849, 67, 609, 68, 848, 0, 0, 622, - 223, 612, 613, 614, 615, 616, 617, 618, 619, 620, - 621, 0, 69, 225, 227, 226, 0, 0, 0, 247, - 849, 251, 294, 275, 0, 0, 295, 296, 285, 0, - 566, 567, 0, 559, 25, 0, 604, 605, 550, 551, - 344, 419, 421, 423, 0, 331, 410, 431, 414, 0, - 411, 0, 0, 405, 471, 0, 0, 438, -2, 474, - 475, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 556, 0, 534, 0, 0, 494, - 505, 506, 507, 508, 581, 0, 0, -2, 0, 0, - 395, 589, 0, 347, 366, 368, 0, 363, 378, 379, + 730, 731, 732, 733, 734, 735, 736, 0, 0, 81, + 0, 79, 0, 853, 0, 0, 0, 0, 0, 0, + 853, 0, 0, 0, 0, 246, 0, 0, 0, 0, + 0, 0, 0, 254, 0, 256, 853, 853, 259, 854, + 855, 853, 853, 853, 853, 853, 853, 266, 268, 269, + 271, 853, 853, 273, 0, 294, 292, 293, 288, 289, + 0, 283, 284, 287, 314, 315, 30, 851, 24, 0, + 0, 567, 0, 559, 560, 563, 566, 29, 324, 0, + 329, 328, 320, 0, 336, 0, 0, 0, 340, 0, + 342, 343, 0, 400, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 424, 425, 426, 427, 428, 429, 430, + 403, 0, 417, 0, 0, 0, 459, 460, 461, 462, + 463, 464, 465, 0, 331, 29, 0, 437, 0, 0, + 0, 0, 0, 0, 0, 0, 327, 0, 532, 0, + 495, 0, 496, 497, 498, 499, 500, 501, 502, 0, + 0, 0, 331, 0, 0, 45, 0, 388, 0, 346, + 348, 349, 350, -2, 0, 372, -2, 0, 0, 0, + 41, 42, 0, 48, 827, 50, 51, 0, 0, 0, + 164, 603, 604, 605, 601, 208, 0, 0, 145, 141, + 87, 88, 89, 134, 91, 134, 134, 134, 134, 161, + 161, 161, 161, 117, 118, 119, 120, 121, 0, 0, + 104, 134, 134, 134, 108, 124, 125, 126, 127, 128, + 129, 130, 131, 92, 93, 94, 95, 96, 97, 98, + 136, 136, 136, 138, 138, 632, 65, 0, 853, 0, + 853, 77, 0, 222, 0, 0, 0, 0, 0, 0, + 0, 249, 609, 0, 853, 252, 253, 390, 640, 641, + 257, 258, 260, 261, 262, 263, 264, 265, 272, 276, + 0, 297, 0, 0, 278, 0, 571, 0, 0, 0, + 0, 0, 562, 564, 565, 570, 32, 327, 0, 551, + 0, 0, 0, 330, 27, 398, 399, 401, 418, 0, + 420, 422, 341, 337, 0, 541, -2, 408, 409, 433, + 434, 435, 0, 0, 0, 0, 431, 413, 0, 444, + 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, + 455, 458, 516, 517, 0, 456, 457, 466, 0, 0, + 332, 333, 436, 0, 589, 29, 0, 0, 0, 0, + 0, 0, 540, 0, 0, 0, 0, 0, 538, 535, + 0, 0, 506, 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, 391, + 796, 373, 0, 375, 376, 395, 0, 395, 44, 595, + 49, 0, 0, 54, 55, 596, 597, 598, 599, 0, + 78, 209, 211, 214, 215, 216, 82, 83, 84, 0, + 0, 196, 0, 0, 190, 190, 0, 188, 189, 80, + 148, 146, 0, 143, 142, 90, 0, 161, 161, 111, + 112, 164, 0, 164, 164, 164, 0, 0, 105, 106, + 107, 99, 0, 100, 101, 102, 0, 103, 0, 0, + 853, 67, 611, 68, 852, 0, 0, 624, 223, 614, + 615, 616, 617, 618, 619, 620, 621, 622, 623, 0, + 69, 225, 227, 226, 0, 0, 0, 247, 853, 251, + 294, 275, 0, 0, 295, 296, 285, 0, 568, 569, + 0, 561, 25, 0, 606, 607, 552, 553, 344, 419, + 421, 423, 0, 331, 410, 431, 414, 0, 411, 0, + 0, 405, 471, 0, 0, 438, -2, 474, 475, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 558, 0, 536, 0, 0, 494, 0, 0, + 507, 508, 509, 510, 583, 0, 0, -2, 0, 0, + 395, 591, 0, 347, 366, 368, 0, 363, 378, 379, 381, 0, 383, 0, 385, 386, 351, 353, 354, 0, - 0, 0, 0, 374, 556, 0, 395, 40, 52, 53, + 0, 0, 0, 374, 558, 0, 395, 40, 52, 53, 0, 0, 59, 165, 166, 0, 212, 0, 0, 0, 183, 190, 190, 186, 191, 187, 0, 156, 0, 147, 86, 144, 0, 164, 164, 113, 0, 114, 115, 116, - 0, 132, 0, 0, 0, 0, 631, 66, 217, 848, + 0, 132, 0, 0, 0, 0, 633, 66, 217, 852, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, - 240, 848, 0, 848, 623, 624, 625, 626, 0, 72, - 0, 0, 0, 0, 250, 297, 298, 299, 570, 0, - 26, 395, 0, 338, 540, 0, 412, 0, 432, 415, - 472, 334, 0, 134, 134, 519, 134, 138, 522, 134, - 524, 134, 527, 0, 0, 0, 0, 0, 0, 539, - 0, 0, 0, 0, 0, 531, 493, 537, 0, 33, - 0, 581, 571, 583, 585, 0, 29, 0, 577, 0, - 358, 556, 0, 0, 360, 367, 0, 0, 361, 0, - 362, 382, 384, 0, 0, 0, 0, 564, 396, 39, - 56, 57, 58, 210, 213, 0, 192, 134, 195, 184, - 185, 0, 159, 0, 149, 150, 151, 152, 153, 155, - 135, 109, 110, 162, 163, 161, 0, 161, 0, 139, - 0, 849, 218, 219, 220, 221, 0, 224, 0, 70, - 71, 0, 229, 248, 274, 552, 345, 473, 416, 476, - 516, 161, 520, 521, 523, 525, 526, 528, 478, 477, - 479, 0, 0, 485, 0, 0, 482, 0, 0, 488, - 0, 0, 0, 0, 0, 535, 0, 34, 0, 586, - -2, 0, 0, 0, 46, 0, 564, 590, 591, 364, - 0, 369, 0, 0, 0, 372, 38, 175, 0, 194, - 0, 356, 167, 160, 0, 0, 164, 133, 164, 0, - 0, 64, 0, 73, 74, 0, 0, 554, 0, 517, - 518, 0, 0, 0, 0, 0, 0, 0, 0, 509, - 492, 532, 0, 584, 0, -2, 0, 579, 578, 359, - 37, 0, 0, 0, 0, 391, 174, 176, 0, 181, - 0, 193, 0, 0, 172, 0, 169, 171, 157, 154, - 122, 123, 137, 140, 0, 0, 0, 0, 28, 0, - 0, 480, 481, 486, 487, 483, 484, 489, 490, 0, - 0, 0, 0, 574, 29, 0, 365, 392, 393, 394, - 355, 177, 178, 0, 182, 180, 0, 357, 85, 0, - 168, 170, 0, 0, 242, 0, 75, 76, 69, 555, - 553, 491, 0, 0, 0, 582, -2, 580, 179, 0, - 173, 158, 241, 0, 0, 72, 510, 0, 513, 0, - 243, 0, 228, 511, 0, 0, 0, 197, 0, 0, - 198, 199, 0, 0, 512, 200, 0, 0, 0, 0, - 0, 201, 203, 204, 0, 0, 202, 244, 245, 205, - 206, 207, + 240, 852, 0, 852, 625, 626, 627, 628, 0, 72, + 0, 0, 0, 0, 250, 297, 298, 299, 572, 0, + 26, 395, 0, 338, 542, 0, 412, 0, 432, 415, + 472, 334, 0, 134, 134, 521, 134, 138, 524, 134, + 526, 134, 529, 0, 0, 0, 0, 0, 0, 541, + 0, 0, 0, 0, 0, 533, 493, 539, 0, 0, + 0, 33, 0, 583, 573, 585, 587, 0, 29, 0, + 579, 0, 358, 558, 0, 0, 360, 367, 0, 0, + 361, 0, 362, 382, 384, 0, 0, 0, 0, 566, + 396, 39, 56, 57, 58, 210, 213, 0, 192, 134, + 195, 184, 185, 0, 159, 0, 149, 150, 151, 152, + 153, 155, 135, 109, 110, 162, 163, 161, 0, 161, + 0, 139, 0, 853, 218, 219, 220, 221, 0, 224, + 0, 70, 71, 0, 229, 248, 274, 554, 345, 473, + 416, 476, 518, 161, 522, 523, 525, 527, 528, 530, + 478, 477, 479, 0, 0, 485, 0, 0, 482, 0, + 0, 488, 0, 0, 0, 0, 0, 537, 0, 0, + 0, 34, 0, 588, -2, 0, 0, 0, 46, 0, + 566, 592, 593, 364, 0, 369, 0, 0, 0, 372, + 38, 175, 0, 194, 0, 356, 167, 160, 0, 0, + 164, 133, 164, 0, 0, 64, 0, 73, 74, 0, + 0, 556, 0, 519, 520, 0, 0, 0, 0, 0, + 0, 0, 0, 511, 492, 534, 0, 0, 0, 586, + 0, -2, 0, 581, 580, 359, 37, 0, 0, 0, + 0, 391, 174, 176, 0, 181, 0, 193, 0, 0, + 172, 0, 169, 171, 157, 154, 122, 123, 137, 140, + 0, 0, 0, 0, 28, 0, 0, 480, 481, 486, + 487, 483, 484, 489, 490, 0, 0, 0, 503, 504, + 0, 576, 29, 0, 365, 392, 393, 394, 355, 177, + 178, 0, 182, 180, 0, 357, 85, 0, 168, 170, + 0, 0, 242, 0, 75, 76, 69, 557, 555, 491, + 0, 0, 0, 584, -2, 582, 179, 0, 173, 158, + 241, 0, 0, 72, 512, 0, 515, 0, 243, 0, + 228, 513, 0, 0, 0, 197, 0, 0, 198, 199, + 0, 0, 514, 200, 0, 0, 0, 0, 0, 201, + 203, 204, 0, 0, 202, 244, 245, 205, 206, 207, } var yyTok1 = [...]int{ @@ -2571,7 +2600,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, 266, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 268, 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, @@ -2606,7 +2635,7 @@ 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, 264, 265, + 259, 260, 261, 262, 263, 264, 265, 266, 267, } var yyTok3 = [...]int{ 0, @@ -2951,35 +2980,35 @@ yydefault: case 1: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:313 +//line sql.y:314 { setParseTree(yylex, yyDollar[1].statement) } case 2: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:318 +//line sql.y:319 { } case 3: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:319 +//line sql.y:320 { } case 4: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:323 +//line sql.y:324 { yyVAL.statement = yyDollar[1].selStmt } case 23: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:345 +//line sql.y:346 { setParseTree(yylex, nil) } case 24: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:351 +//line sql.y:352 { sel := yyDollar[1].selStmt.(*Select) sel.OrderBy = yyDollar[2].orderBy @@ -2989,55 +3018,55 @@ yydefault: } case 25: yyDollar = yyS[yypt-6 : yypt+1] -//line sql.y:359 +//line sql.y:360 { 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:363 +//line sql.y:364 { 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:369 +//line sql.y:370 { 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:376 +//line sql.y:377 { 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:382 +//line sql.y:383 { yyVAL.selStmt = yyDollar[1].selStmt } case 30: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:386 +//line sql.y:387 { yyVAL.selStmt = &ParenSelect{Select: yyDollar[2].selStmt} } case 31: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:392 +//line sql.y:393 { yyVAL.selStmt = yyDollar[1].selStmt } case 32: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:396 +//line sql.y:397 { yyVAL.selStmt = &ParenSelect{Select: yyDollar[2].selStmt} } case 33: yyDollar = yyS[yypt-7 : yypt+1] -//line sql.y:403 +//line sql.y:404 { // insert_data returns a *Insert pre-filled with Columns & Values ins := yyDollar[6].ins @@ -3051,7 +3080,7 @@ yydefault: } case 34: yyDollar = yyS[yypt-8 : yypt+1] -//line sql.y:415 +//line sql.y:416 { cols := make(Columns, 0, len(yyDollar[7].updateExprs)) vals := make(ValTuple, 0, len(yyDollar[8].updateExprs)) @@ -3063,174 +3092,174 @@ yydefault: } case 35: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:427 +//line sql.y:428 { yyVAL.str = InsertStr } case 36: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:431 +//line sql.y:432 { yyVAL.str = ReplaceStr } case 37: yyDollar = yyS[yypt-9 : yypt+1] -//line sql.y:437 +//line sql.y:438 { 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:443 +//line sql.y:444 { 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:447 +//line sql.y:448 { 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:451 +//line sql.y:452 { 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-1 : yypt+1] -//line sql.y:456 +//line sql.y:457 { } case 42: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:457 +//line sql.y:458 { } case 43: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:461 +//line sql.y:462 { yyVAL.tableNames = TableNames{yyDollar[1].tableName} } case 44: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:465 +//line sql.y:466 { yyVAL.tableNames = append(yyVAL.tableNames, yyDollar[3].tableName) } case 45: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:470 +//line sql.y:471 { yyVAL.partitions = nil } case 46: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:474 +//line sql.y:475 { yyVAL.partitions = yyDollar[3].partitions } case 47: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:480 +//line sql.y:481 { yyVAL.statement = &Set{Comments: Comments(yyDollar[2].bytes2), Exprs: yyDollar[3].setExprs} } case 48: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:484 +//line sql.y:485 { yyVAL.statement = &Set{Comments: Comments(yyDollar[2].bytes2), Scope: yyDollar[3].str, Exprs: yyDollar[4].setExprs} } case 49: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:488 +//line sql.y:489 { yyVAL.statement = &Set{Comments: Comments(yyDollar[2].bytes2), Scope: yyDollar[3].str, Exprs: yyDollar[5].setExprs} } case 50: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:492 +//line sql.y:493 { yyVAL.statement = &Set{Comments: Comments(yyDollar[2].bytes2), Exprs: yyDollar[4].setExprs} } case 51: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:498 +//line sql.y:499 { yyVAL.setExprs = SetExprs{yyDollar[1].setExpr} } case 52: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:502 +//line sql.y:503 { yyVAL.setExprs = append(yyVAL.setExprs, yyDollar[3].setExpr) } case 53: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:508 +//line sql.y:509 { yyVAL.setExpr = &SetExpr{Name: NewColIdent(TransactionStr), Expr: NewStrVal([]byte(yyDollar[3].str))} } case 54: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:512 +//line sql.y:513 { yyVAL.setExpr = &SetExpr{Name: NewColIdent(TransactionStr), Expr: NewStrVal([]byte(TxReadWrite))} } case 55: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:516 +//line sql.y:517 { yyVAL.setExpr = &SetExpr{Name: NewColIdent(TransactionStr), Expr: NewStrVal([]byte(TxReadOnly))} } case 56: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:522 +//line sql.y:523 { yyVAL.str = IsolationLevelRepeatableRead } case 57: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:526 +//line sql.y:527 { yyVAL.str = IsolationLevelReadCommitted } case 58: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:530 +//line sql.y:531 { yyVAL.str = IsolationLevelReadUncommitted } case 59: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:534 +//line sql.y:535 { yyVAL.str = IsolationLevelSerializable } case 60: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:540 +//line sql.y:541 { yyVAL.str = SessionStr } case 61: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:544 +//line sql.y:545 { yyVAL.str = GlobalStr } case 62: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:550 +//line sql.y:551 { yyDollar[1].ddl.TableSpec = yyDollar[2].TableSpec yyVAL.statement = yyDollar[1].ddl } case 63: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:555 +//line sql.y:556 { // Create table [name] like [name] yyDollar[1].ddl.OptLike = yyDollar[2].optLike @@ -3238,139 +3267,139 @@ yydefault: } case 64: yyDollar = yyS[yypt-8 : yypt+1] -//line sql.y:561 +//line sql.y:562 { // Change this to an alter statement yyVAL.statement = &DDL{Action: AlterStr, Table: yyDollar[7].tableName} } case 65: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:566 +//line sql.y:567 { yyVAL.statement = &DDL{Action: CreateStr, Table: yyDollar[3].tableName.ToViewName()} } case 66: yyDollar = yyS[yypt-6 : yypt+1] -//line sql.y:570 +//line sql.y:571 { yyVAL.statement = &DDL{Action: CreateStr, Table: yyDollar[5].tableName.ToViewName()} } case 67: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:574 +//line sql.y:575 { yyVAL.statement = &DBDDL{Action: CreateStr, DBName: string(yyDollar[4].bytes)} } case 68: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:578 +//line sql.y:579 { yyVAL.statement = &DBDDL{Action: CreateStr, DBName: string(yyDollar[4].bytes)} } case 69: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:583 +//line sql.y:584 { yyVAL.colIdent = NewColIdent("") } case 70: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:587 +//line sql.y:588 { yyVAL.colIdent = yyDollar[2].colIdent } case 71: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:593 +//line sql.y:594 { yyVAL.colIdent = NewColIdent(string(yyDollar[1].bytes)) } case 72: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:598 +//line sql.y:599 { var v []VindexParam yyVAL.vindexParams = v } case 73: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:603 +//line sql.y:604 { yyVAL.vindexParams = yyDollar[2].vindexParams } case 74: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:609 +//line sql.y:610 { yyVAL.vindexParams = make([]VindexParam, 0, 4) yyVAL.vindexParams = append(yyVAL.vindexParams, yyDollar[1].vindexParam) } case 75: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:614 +//line sql.y:615 { yyVAL.vindexParams = append(yyVAL.vindexParams, yyDollar[3].vindexParam) } case 76: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:620 +//line sql.y:621 { yyVAL.vindexParam = VindexParam{Key: yyDollar[1].colIdent, Val: yyDollar[3].str} } case 77: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:626 +//line sql.y:627 { yyVAL.ddl = &DDL{Action: CreateStr, Table: yyDollar[4].tableName} setDDL(yylex, yyVAL.ddl) } case 78: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:633 +//line sql.y:634 { yyVAL.TableSpec = yyDollar[2].TableSpec yyVAL.TableSpec.Options = yyDollar[4].str } case 79: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:640 +//line sql.y:641 { yyVAL.optLike = &OptLike{LikeTable: yyDollar[2].tableName} } case 80: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:644 +//line sql.y:645 { yyVAL.optLike = &OptLike{LikeTable: yyDollar[3].tableName} } case 81: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:650 +//line sql.y:651 { yyVAL.TableSpec = &TableSpec{} yyVAL.TableSpec.AddColumn(yyDollar[1].columnDefinition) } case 82: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:655 +//line sql.y:656 { yyVAL.TableSpec.AddColumn(yyDollar[3].columnDefinition) } case 83: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:659 +//line sql.y:660 { yyVAL.TableSpec.AddIndex(yyDollar[3].indexDefinition) } case 84: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:663 +//line sql.y:664 { yyVAL.TableSpec.AddConstraint(yyDollar[3].constraintDefinition) } case 85: yyDollar = yyS[yypt-8 : yypt+1] -//line sql.y:669 +//line sql.y:670 { yyDollar[2].columnType.NotNull = yyDollar[3].boolVal yyDollar[2].columnType.Default = yyDollar[4].optVal @@ -3382,7 +3411,7 @@ yydefault: } case 86: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:680 +//line sql.y:681 { yyVAL.columnType = yyDollar[1].columnType yyVAL.columnType.Unsigned = yyDollar[2].boolVal @@ -3390,62 +3419,62 @@ yydefault: } case 90: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:691 +//line sql.y:692 { yyVAL.columnType = yyDollar[1].columnType yyVAL.columnType.Length = yyDollar[2].optVal } case 91: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:696 +//line sql.y:697 { yyVAL.columnType = yyDollar[1].columnType } case 92: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:702 +//line sql.y:703 { yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} } case 93: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:706 +//line sql.y:707 { yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} } case 94: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:710 +//line sql.y:711 { yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} } case 95: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:714 +//line sql.y:715 { yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} } case 96: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:718 +//line sql.y:719 { yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} } case 97: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:722 +//line sql.y:723 { yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} } case 98: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:726 +//line sql.y:727 { yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} } case 99: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:732 +//line sql.y:733 { yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} yyVAL.columnType.Length = yyDollar[2].LengthScaleOption.Length @@ -3453,7 +3482,7 @@ yydefault: } case 100: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:738 +//line sql.y:739 { yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} yyVAL.columnType.Length = yyDollar[2].LengthScaleOption.Length @@ -3461,7 +3490,7 @@ yydefault: } case 101: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:744 +//line sql.y:745 { yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} yyVAL.columnType.Length = yyDollar[2].LengthScaleOption.Length @@ -3469,7 +3498,7 @@ yydefault: } case 102: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:750 +//line sql.y:751 { yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} yyVAL.columnType.Length = yyDollar[2].LengthScaleOption.Length @@ -3477,7 +3506,7 @@ yydefault: } case 103: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:756 +//line sql.y:757 { yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} yyVAL.columnType.Length = yyDollar[2].LengthScaleOption.Length @@ -3485,206 +3514,206 @@ yydefault: } case 104: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:764 +//line sql.y:765 { yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} } case 105: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:768 +//line sql.y:769 { yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes), Length: yyDollar[2].optVal} } case 106: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:772 +//line sql.y:773 { yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes), Length: yyDollar[2].optVal} } case 107: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:776 +//line sql.y:777 { yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes), Length: yyDollar[2].optVal} } case 108: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:780 +//line sql.y:781 { yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} } case 109: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:786 +//line sql.y:787 { yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes), Length: yyDollar[2].optVal, Charset: yyDollar[3].str, Collate: yyDollar[4].str} } case 110: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:790 +//line sql.y:791 { yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes), Length: yyDollar[2].optVal, Charset: yyDollar[3].str, Collate: yyDollar[4].str} } case 111: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:794 +//line sql.y:795 { yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes), Length: yyDollar[2].optVal} } case 112: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:798 +//line sql.y:799 { yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes), Length: yyDollar[2].optVal} } case 113: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:802 +//line sql.y:803 { yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes), Charset: yyDollar[2].str, Collate: yyDollar[3].str} } case 114: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:806 +//line sql.y:807 { yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes), Charset: yyDollar[2].str, Collate: yyDollar[3].str} } case 115: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:810 +//line sql.y:811 { yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes), Charset: yyDollar[2].str, Collate: yyDollar[3].str} } case 116: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:814 +//line sql.y:815 { yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes), Charset: yyDollar[2].str, Collate: yyDollar[3].str} } case 117: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:818 +//line sql.y:819 { yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} } case 118: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:822 +//line sql.y:823 { yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} } case 119: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:826 +//line sql.y:827 { yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} } case 120: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:830 +//line sql.y:831 { yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} } case 121: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:834 +//line sql.y:835 { yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} } case 122: yyDollar = yyS[yypt-6 : yypt+1] -//line sql.y:838 +//line sql.y:839 { yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes), EnumValues: yyDollar[3].strs, Charset: yyDollar[5].str, Collate: yyDollar[6].str} } case 123: yyDollar = yyS[yypt-6 : yypt+1] -//line sql.y:843 +//line sql.y:844 { yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes), EnumValues: yyDollar[3].strs, Charset: yyDollar[5].str, Collate: yyDollar[6].str} } case 124: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:849 +//line sql.y:850 { yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} } case 125: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:853 +//line sql.y:854 { yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} } case 126: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:857 +//line sql.y:858 { yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} } case 127: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:861 +//line sql.y:862 { yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} } case 128: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:865 +//line sql.y:866 { yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} } case 129: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:869 +//line sql.y:870 { yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} } case 130: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:873 +//line sql.y:874 { yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} } case 131: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:877 +//line sql.y:878 { yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} } case 132: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:883 +//line sql.y:884 { yyVAL.strs = make([]string, 0, 4) yyVAL.strs = append(yyVAL.strs, "'"+string(yyDollar[1].bytes)+"'") } case 133: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:888 +//line sql.y:889 { yyVAL.strs = append(yyDollar[1].strs, "'"+string(yyDollar[3].bytes)+"'") } case 134: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:893 +//line sql.y:894 { yyVAL.optVal = nil } case 135: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:897 +//line sql.y:898 { yyVAL.optVal = NewIntVal(yyDollar[2].bytes) } case 136: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:902 +//line sql.y:903 { yyVAL.LengthScaleOption = LengthScaleOption{} } case 137: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:906 +//line sql.y:907 { yyVAL.LengthScaleOption = LengthScaleOption{ Length: NewIntVal(yyDollar[2].bytes), @@ -3693,13 +3722,13 @@ yydefault: } case 138: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:914 +//line sql.y:915 { yyVAL.LengthScaleOption = LengthScaleOption{} } case 139: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:918 +//line sql.y:919 { yyVAL.LengthScaleOption = LengthScaleOption{ Length: NewIntVal(yyDollar[2].bytes), @@ -3707,7 +3736,7 @@ yydefault: } case 140: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:924 +//line sql.y:925 { yyVAL.LengthScaleOption = LengthScaleOption{ Length: NewIntVal(yyDollar[2].bytes), @@ -3716,508 +3745,508 @@ yydefault: } case 141: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:932 +//line sql.y:933 { yyVAL.boolVal = BoolVal(false) } case 142: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:936 +//line sql.y:937 { yyVAL.boolVal = BoolVal(true) } case 143: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:941 +//line sql.y:942 { yyVAL.boolVal = BoolVal(false) } case 144: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:945 +//line sql.y:946 { yyVAL.boolVal = BoolVal(true) } case 145: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:951 +//line sql.y:952 { yyVAL.boolVal = BoolVal(false) } case 146: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:955 +//line sql.y:956 { yyVAL.boolVal = BoolVal(false) } case 147: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:959 +//line sql.y:960 { yyVAL.boolVal = BoolVal(true) } case 148: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:964 +//line sql.y:965 { yyVAL.optVal = nil } case 149: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:968 +//line sql.y:969 { yyVAL.optVal = NewStrVal(yyDollar[2].bytes) } case 150: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:972 +//line sql.y:973 { yyVAL.optVal = NewIntVal(yyDollar[2].bytes) } case 151: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:976 +//line sql.y:977 { yyVAL.optVal = NewFloatVal(yyDollar[2].bytes) } case 152: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:980 +//line sql.y:981 { yyVAL.optVal = NewValArg(yyDollar[2].bytes) } case 153: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:984 +//line sql.y:985 { yyVAL.optVal = NewValArg(yyDollar[2].bytes) } case 154: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:988 +//line sql.y:989 { yyVAL.optVal = NewValArg(yyDollar[2].bytes) } case 155: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:992 +//line sql.y:993 { yyVAL.optVal = NewBitVal(yyDollar[2].bytes) } case 156: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:997 +//line sql.y:998 { yyVAL.optVal = nil } case 157: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1001 +//line sql.y:1002 { yyVAL.optVal = NewValArg(yyDollar[3].bytes) } case 158: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:1005 +//line sql.y:1006 { yyVAL.optVal = NewValArg(yyDollar[3].bytes) } case 159: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:1010 +//line sql.y:1011 { yyVAL.boolVal = BoolVal(false) } case 160: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1014 +//line sql.y:1015 { yyVAL.boolVal = BoolVal(true) } case 161: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:1019 +//line sql.y:1020 { yyVAL.str = "" } case 162: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1023 +//line sql.y:1024 { yyVAL.str = string(yyDollar[3].bytes) } case 163: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1027 +//line sql.y:1028 { yyVAL.str = string(yyDollar[3].bytes) } case 164: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:1032 +//line sql.y:1033 { yyVAL.str = "" } case 165: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1036 +//line sql.y:1037 { yyVAL.str = string(yyDollar[2].bytes) } case 166: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1040 +//line sql.y:1041 { yyVAL.str = string(yyDollar[2].bytes) } case 167: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:1045 +//line sql.y:1046 { yyVAL.colKeyOpt = colKeyNone } case 168: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1049 +//line sql.y:1050 { yyVAL.colKeyOpt = colKeyPrimary } case 169: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1053 +//line sql.y:1054 { yyVAL.colKeyOpt = colKey } case 170: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1057 +//line sql.y:1058 { yyVAL.colKeyOpt = colKeyUniqueKey } case 171: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1061 +//line sql.y:1062 { yyVAL.colKeyOpt = colKeyUnique } case 172: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:1066 +//line sql.y:1067 { yyVAL.optVal = nil } case 173: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1070 +//line sql.y:1071 { yyVAL.optVal = NewStrVal(yyDollar[2].bytes) } case 174: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:1076 +//line sql.y:1077 { yyVAL.indexDefinition = &IndexDefinition{Info: yyDollar[1].indexInfo, Columns: yyDollar[3].indexColumns, Options: yyDollar[5].indexOptions} } case 175: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:1080 +//line sql.y:1081 { yyVAL.indexDefinition = &IndexDefinition{Info: yyDollar[1].indexInfo, Columns: yyDollar[3].indexColumns} } case 176: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1086 +//line sql.y:1087 { yyVAL.indexOptions = []*IndexOption{yyDollar[1].indexOption} } case 177: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1090 +//line sql.y:1091 { yyVAL.indexOptions = append(yyVAL.indexOptions, yyDollar[2].indexOption) } case 178: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1096 +//line sql.y:1097 { yyVAL.indexOption = &IndexOption{Name: string(yyDollar[1].bytes), Using: string(yyDollar[2].bytes)} } case 179: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1100 +//line sql.y:1101 { // should not be string yyVAL.indexOption = &IndexOption{Name: string(yyDollar[1].bytes), Value: NewIntVal(yyDollar[3].bytes)} } case 180: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1105 +//line sql.y:1106 { yyVAL.indexOption = &IndexOption{Name: string(yyDollar[1].bytes), Value: NewStrVal(yyDollar[2].bytes)} } case 181: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:1111 +//line sql.y:1112 { yyVAL.str = "" } case 182: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1115 +//line sql.y:1116 { yyVAL.str = string(yyDollar[1].bytes) } case 183: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1121 +//line sql.y:1122 { yyVAL.indexInfo = &IndexInfo{Type: string(yyDollar[1].bytes) + " " + string(yyDollar[2].bytes), Name: NewColIdent("PRIMARY"), Primary: true, Unique: true} } case 184: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1125 +//line sql.y:1126 { yyVAL.indexInfo = &IndexInfo{Type: string(yyDollar[1].bytes) + " " + string(yyDollar[2].str), Name: NewColIdent(yyDollar[3].str), Spatial: true, Unique: false} } case 185: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1129 +//line sql.y:1130 { yyVAL.indexInfo = &IndexInfo{Type: string(yyDollar[1].bytes) + " " + string(yyDollar[2].str), Name: NewColIdent(yyDollar[3].str), Unique: true} } case 186: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1133 +//line sql.y:1134 { yyVAL.indexInfo = &IndexInfo{Type: string(yyDollar[1].bytes), Name: NewColIdent(yyDollar[2].str), Unique: true} } case 187: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1137 +//line sql.y:1138 { yyVAL.indexInfo = &IndexInfo{Type: string(yyDollar[1].str), Name: NewColIdent(yyDollar[2].str), Unique: false} } case 188: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1143 +//line sql.y:1144 { yyVAL.str = string(yyDollar[1].bytes) } case 189: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1147 +//line sql.y:1148 { yyVAL.str = string(yyDollar[1].bytes) } case 190: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:1152 +//line sql.y:1153 { yyVAL.str = "" } case 191: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1156 +//line sql.y:1157 { yyVAL.str = string(yyDollar[1].bytes) } case 192: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1162 +//line sql.y:1163 { yyVAL.indexColumns = []*IndexColumn{yyDollar[1].indexColumn} } case 193: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1166 +//line sql.y:1167 { yyVAL.indexColumns = append(yyVAL.indexColumns, yyDollar[3].indexColumn) } case 194: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1172 +//line sql.y:1173 { yyVAL.indexColumn = &IndexColumn{Column: yyDollar[1].colIdent, Length: yyDollar[2].optVal} } case 195: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1178 +//line sql.y:1179 { yyVAL.constraintDefinition = &ConstraintDefinition{Name: string(yyDollar[2].bytes), Details: yyDollar[3].constraintInfo} } case 196: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1182 +//line sql.y:1183 { yyVAL.constraintDefinition = &ConstraintDefinition{Details: yyDollar[1].constraintInfo} } case 197: yyDollar = yyS[yypt-10 : yypt+1] -//line sql.y:1189 +//line sql.y:1190 { yyVAL.constraintInfo = &ForeignKeyDefinition{Source: yyDollar[4].columns, ReferencedTable: yyDollar[7].tableName, ReferencedColumns: yyDollar[9].columns} } case 198: yyDollar = yyS[yypt-11 : yypt+1] -//line sql.y:1193 +//line sql.y:1194 { yyVAL.constraintInfo = &ForeignKeyDefinition{Source: yyDollar[4].columns, ReferencedTable: yyDollar[7].tableName, ReferencedColumns: yyDollar[9].columns, OnDelete: yyDollar[11].ReferenceAction} } case 199: yyDollar = yyS[yypt-11 : yypt+1] -//line sql.y:1197 +//line sql.y:1198 { yyVAL.constraintInfo = &ForeignKeyDefinition{Source: yyDollar[4].columns, ReferencedTable: yyDollar[7].tableName, ReferencedColumns: yyDollar[9].columns, OnUpdate: yyDollar[11].ReferenceAction} } case 200: yyDollar = yyS[yypt-12 : yypt+1] -//line sql.y:1201 +//line sql.y:1202 { yyVAL.constraintInfo = &ForeignKeyDefinition{Source: yyDollar[4].columns, ReferencedTable: yyDollar[7].tableName, ReferencedColumns: yyDollar[9].columns, OnDelete: yyDollar[11].ReferenceAction, OnUpdate: yyDollar[12].ReferenceAction} } case 201: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1207 +//line sql.y:1208 { yyVAL.ReferenceAction = yyDollar[3].ReferenceAction } case 202: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1213 +//line sql.y:1214 { yyVAL.ReferenceAction = yyDollar[3].ReferenceAction } case 203: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1219 +//line sql.y:1220 { yyVAL.ReferenceAction = Restrict } case 204: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1223 +//line sql.y:1224 { yyVAL.ReferenceAction = Cascade } case 205: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1227 +//line sql.y:1228 { yyVAL.ReferenceAction = NoAction } case 206: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1231 +//line sql.y:1232 { yyVAL.ReferenceAction = SetDefault } case 207: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1235 +//line sql.y:1236 { yyVAL.ReferenceAction = SetNull } case 208: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:1240 +//line sql.y:1241 { yyVAL.str = "" } case 209: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1244 +//line sql.y:1245 { yyVAL.str = " " + string(yyDollar[1].str) } case 210: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1248 +//line sql.y:1249 { yyVAL.str = string(yyDollar[1].str) + ", " + string(yyDollar[3].str) } case 211: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1256 +//line sql.y:1257 { yyVAL.str = yyDollar[1].str } case 212: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1260 +//line sql.y:1261 { yyVAL.str = yyDollar[1].str + " " + yyDollar[2].str } case 213: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1264 +//line sql.y:1265 { yyVAL.str = yyDollar[1].str + "=" + yyDollar[3].str } case 214: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1270 +//line sql.y:1271 { yyVAL.str = yyDollar[1].colIdent.String() } case 215: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1274 +//line sql.y:1275 { yyVAL.str = "'" + string(yyDollar[1].bytes) + "'" } case 216: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1278 +//line sql.y:1279 { yyVAL.str = string(yyDollar[1].bytes) } case 217: yyDollar = yyS[yypt-6 : yypt+1] -//line sql.y:1284 +//line sql.y:1285 { yyVAL.statement = &DDL{Action: AlterStr, Table: yyDollar[4].tableName} } case 218: yyDollar = yyS[yypt-7 : yypt+1] -//line sql.y:1288 +//line sql.y:1289 { yyVAL.statement = &DDL{Action: AlterStr, Table: yyDollar[4].tableName} } case 219: yyDollar = yyS[yypt-7 : yypt+1] -//line sql.y:1292 +//line sql.y:1293 { yyVAL.statement = &DDL{Action: AlterStr, Table: yyDollar[4].tableName} } case 220: yyDollar = yyS[yypt-7 : yypt+1] -//line sql.y:1296 +//line sql.y:1297 { // Change this to a rename statement yyVAL.statement = &DDL{Action: RenameStr, FromTables: TableNames{yyDollar[4].tableName}, ToTables: TableNames{yyDollar[7].tableName}} } case 221: yyDollar = yyS[yypt-7 : yypt+1] -//line sql.y:1301 +//line sql.y:1302 { // Rename an index can just be an alter yyVAL.statement = &DDL{Action: AlterStr, Table: yyDollar[4].tableName} } case 222: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:1306 +//line sql.y:1307 { yyVAL.statement = &DDL{Action: AlterStr, Table: yyDollar[3].tableName.ToViewName()} } case 223: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:1310 +//line sql.y:1311 { yyVAL.statement = &DDL{Action: AlterStr, Table: yyDollar[4].tableName, PartitionSpec: yyDollar[5].partSpec} } case 224: yyDollar = yyS[yypt-7 : yypt+1] -//line sql.y:1314 +//line sql.y:1315 { yyVAL.statement = &DDL{Action: CreateVindexStr, VindexSpec: &VindexSpec{ Name: yyDollar[5].colIdent, @@ -4227,7 +4256,7 @@ yydefault: } case 225: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:1322 +//line sql.y:1323 { yyVAL.statement = &DDL{Action: DropVindexStr, VindexSpec: &VindexSpec{ Name: yyDollar[5].colIdent, @@ -4235,19 +4264,19 @@ yydefault: } case 226: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:1328 +//line sql.y:1329 { yyVAL.statement = &DDL{Action: AddVschemaTableStr, Table: yyDollar[5].tableName} } case 227: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:1332 +//line sql.y:1333 { yyVAL.statement = &DDL{Action: DropVschemaTableStr, Table: yyDollar[5].tableName} } case 228: yyDollar = yyS[yypt-12 : yypt+1] -//line sql.y:1336 +//line sql.y:1337 { yyVAL.statement = &DDL{ Action: AddColVindexStr, @@ -4262,7 +4291,7 @@ yydefault: } case 229: yyDollar = yyS[yypt-7 : yypt+1] -//line sql.y:1349 +//line sql.y:1350 { yyVAL.statement = &DDL{ Action: DropColVindexStr, @@ -4274,49 +4303,49 @@ yydefault: } case 241: yyDollar = yyS[yypt-7 : yypt+1] -//line sql.y:1374 +//line sql.y:1375 { yyVAL.partSpec = &PartitionSpec{Action: ReorganizeStr, Name: yyDollar[3].colIdent, Definitions: yyDollar[6].partDefs} } case 242: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1380 +//line sql.y:1381 { yyVAL.partDefs = []*PartitionDefinition{yyDollar[1].partDef} } case 243: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1384 +//line sql.y:1385 { yyVAL.partDefs = append(yyDollar[1].partDefs, yyDollar[3].partDef) } case 244: yyDollar = yyS[yypt-8 : yypt+1] -//line sql.y:1390 +//line sql.y:1391 { yyVAL.partDef = &PartitionDefinition{Name: yyDollar[2].colIdent, Limit: yyDollar[7].expr} } case 245: yyDollar = yyS[yypt-8 : yypt+1] -//line sql.y:1394 +//line sql.y:1395 { yyVAL.partDef = &PartitionDefinition{Name: yyDollar[2].colIdent, Maxvalue: true} } case 246: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1400 +//line sql.y:1401 { yyVAL.statement = yyDollar[3].ddl } case 247: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1406 +//line sql.y:1407 { yyVAL.ddl = &DDL{Action: RenameStr, FromTables: TableNames{yyDollar[1].tableName}, ToTables: TableNames{yyDollar[3].tableName}} } case 248: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:1410 +//line sql.y:1411 { yyVAL.ddl = yyDollar[1].ddl yyVAL.ddl.FromTables = append(yyVAL.ddl.FromTables, yyDollar[3].tableName) @@ -4324,7 +4353,7 @@ yydefault: } case 249: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:1418 +//line sql.y:1419 { var exists bool if yyDollar[3].byt != 0 { @@ -4334,14 +4363,14 @@ yydefault: } case 250: yyDollar = yyS[yypt-6 : yypt+1] -//line sql.y:1426 +//line sql.y:1427 { // Change this to an alter statement yyVAL.statement = &DDL{Action: AlterStr, Table: yyDollar[5].tableName} } case 251: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:1431 +//line sql.y:1432 { var exists bool if yyDollar[3].byt != 0 { @@ -4351,146 +4380,146 @@ yydefault: } case 252: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:1439 +//line sql.y:1440 { yyVAL.statement = &DBDDL{Action: DropStr, DBName: string(yyDollar[4].bytes)} } case 253: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:1443 +//line sql.y:1444 { yyVAL.statement = &DBDDL{Action: DropStr, DBName: string(yyDollar[4].bytes)} } case 254: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1449 +//line sql.y:1450 { yyVAL.statement = &DDL{Action: TruncateStr, Table: yyDollar[3].tableName} } case 255: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1453 +//line sql.y:1454 { yyVAL.statement = &DDL{Action: TruncateStr, Table: yyDollar[2].tableName} } case 256: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1458 +//line sql.y:1459 { yyVAL.statement = &DDL{Action: AlterStr, Table: yyDollar[3].tableName} } case 257: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:1464 +//line sql.y:1465 { yyVAL.statement = &Show{Type: string(yyDollar[2].bytes) + " " + string(yyDollar[3].bytes)} } case 258: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:1469 +//line sql.y:1470 { yyVAL.statement = &Show{Type: CharsetStr} } case 259: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1473 +//line sql.y:1474 { yyVAL.statement = &Show{Type: string(yyDollar[2].bytes)} } case 260: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:1477 +//line sql.y:1478 { yyVAL.statement = &Show{Type: string(yyDollar[2].bytes) + " " + string(yyDollar[3].bytes)} } case 261: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:1482 +//line sql.y:1483 { yyVAL.statement = &Show{Type: string(yyDollar[2].bytes) + " " + string(yyDollar[3].bytes)} } case 262: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:1486 +//line sql.y:1487 { yyVAL.statement = &Show{Type: string(yyDollar[2].bytes) + " " + string(yyDollar[3].bytes)} } case 263: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:1490 +//line sql.y:1491 { yyVAL.statement = &Show{Type: string(yyDollar[2].bytes) + " " + string(yyDollar[3].bytes)} } case 264: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:1494 +//line sql.y:1495 { yyVAL.statement = &Show{Type: string(yyDollar[2].bytes) + " " + string(yyDollar[3].bytes)} } case 265: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:1498 +//line sql.y:1499 { yyVAL.statement = &Show{Type: string(yyDollar[2].bytes) + " " + string(yyDollar[3].bytes)} } case 266: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1502 +//line sql.y:1503 { yyVAL.statement = &Show{Type: string(yyDollar[2].bytes)} } case 267: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1506 +//line sql.y:1507 { yyVAL.statement = &Show{Type: string(yyDollar[2].bytes)} } case 268: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1510 +//line sql.y:1511 { yyVAL.statement = &Show{Type: string(yyDollar[2].bytes)} } case 269: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1514 +//line sql.y:1515 { yyVAL.statement = &Show{Type: string(yyDollar[2].bytes)} } case 270: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1518 +//line sql.y:1519 { yyVAL.statement = &Show{Type: string(yyDollar[2].bytes)} } case 271: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1522 +//line sql.y:1523 { yyVAL.statement = &Show{Type: string(yyDollar[2].bytes)} } case 272: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:1526 +//line sql.y:1527 { yyVAL.statement = &Show{Scope: yyDollar[2].str, Type: string(yyDollar[3].bytes)} } case 273: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1530 +//line sql.y:1531 { yyVAL.statement = &Show{Type: string(yyDollar[2].bytes)} } case 274: yyDollar = yyS[yypt-7 : yypt+1] -//line sql.y:1534 +//line sql.y:1535 { 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: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:1539 +//line sql.y:1540 { // this is ugly, but I couldn't find a better way for now if yyDollar[3].str == "processlist" { @@ -4502,19 +4531,19 @@ yydefault: } case 276: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:1549 +//line sql.y:1550 { yyVAL.statement = &Show{Scope: yyDollar[2].str, Type: string(yyDollar[3].bytes)} } case 277: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1553 +//line sql.y:1554 { yyVAL.statement = &Show{Type: string(yyDollar[2].bytes)} } case 278: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:1557 +//line sql.y:1558 { // Cannot dereference $4 directly, or else the parser stackcannot be pooled. See yyParsePooled showCollationFilterOpt := yyDollar[4].expr @@ -4522,428 +4551,428 @@ yydefault: } case 279: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1563 +//line sql.y:1564 { yyVAL.statement = &Show{Type: string(yyDollar[2].bytes)} } case 280: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1567 +//line sql.y:1568 { yyVAL.statement = &Show{Type: string(yyDollar[2].bytes)} } case 281: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1571 +//line sql.y:1572 { yyVAL.statement = &Show{Type: string(yyDollar[2].bytes)} } case 282: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1575 +//line sql.y:1576 { yyVAL.statement = &Show{Type: string(yyDollar[2].bytes)} } case 283: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1579 +//line sql.y:1580 { yyVAL.statement = &Show{Type: string(yyDollar[2].bytes) + " " + string(yyDollar[3].bytes)} } case 284: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1583 +//line sql.y:1584 { yyVAL.statement = &Show{Type: string(yyDollar[2].bytes) + " " + string(yyDollar[3].bytes)} } case 285: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:1587 +//line sql.y:1588 { yyVAL.statement = &Show{Type: string(yyDollar[2].bytes) + " " + string(yyDollar[3].bytes), OnTable: yyDollar[5].tableName} } case 286: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1591 +//line sql.y:1592 { yyVAL.statement = &Show{Type: string(yyDollar[2].bytes)} } case 287: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1601 +//line sql.y:1602 { yyVAL.statement = &Show{Type: string(yyDollar[2].bytes)} } case 288: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1607 +//line sql.y:1608 { yyVAL.str = string(yyDollar[1].bytes) } case 289: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1611 +//line sql.y:1612 { yyVAL.str = string(yyDollar[1].bytes) } case 290: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:1617 +//line sql.y:1618 { yyVAL.str = "" } case 291: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1621 +//line sql.y:1622 { yyVAL.str = "full " } case 292: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1627 +//line sql.y:1628 { yyVAL.str = string(yyDollar[1].bytes) } case 293: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1631 +//line sql.y:1632 { yyVAL.str = string(yyDollar[1].bytes) } case 294: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:1637 +//line sql.y:1638 { yyVAL.str = "" } case 295: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1641 +//line sql.y:1642 { yyVAL.str = yyDollar[2].tableIdent.v } case 296: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1645 +//line sql.y:1646 { yyVAL.str = yyDollar[2].tableIdent.v } case 297: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:1651 +//line sql.y:1652 { yyVAL.showFilter = nil } case 298: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1655 +//line sql.y:1656 { yyVAL.showFilter = &ShowFilter{Like: string(yyDollar[2].bytes)} } case 299: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1659 +//line sql.y:1660 { yyVAL.showFilter = &ShowFilter{Filter: yyDollar[2].expr} } case 300: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:1665 +//line sql.y:1666 { yyVAL.str = "" } case 301: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1669 +//line sql.y:1670 { yyVAL.str = SessionStr } case 302: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1673 +//line sql.y:1674 { yyVAL.str = GlobalStr } case 303: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1679 +//line sql.y:1680 { yyVAL.statement = &Use{DBName: yyDollar[2].tableIdent} } case 304: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1683 +//line sql.y:1684 { yyVAL.statement = &Use{DBName: TableIdent{v: ""}} } case 305: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1689 +//line sql.y:1690 { yyVAL.statement = &Begin{} } case 306: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1693 +//line sql.y:1694 { yyVAL.statement = &Begin{} } case 307: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1699 +//line sql.y:1700 { yyVAL.statement = &Commit{} } case 308: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1705 +//line sql.y:1706 { yyVAL.statement = &Rollback{} } case 309: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1711 +//line sql.y:1712 { yyVAL.statement = &OtherRead{} } case 310: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1715 +//line sql.y:1716 { yyVAL.statement = &OtherRead{} } case 311: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1719 +//line sql.y:1720 { yyVAL.statement = &OtherRead{} } case 312: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1723 +//line sql.y:1724 { yyVAL.statement = &OtherAdmin{} } case 313: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1727 +//line sql.y:1728 { yyVAL.statement = &OtherAdmin{} } case 314: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1731 +//line sql.y:1732 { yyVAL.statement = &OtherAdmin{} } case 315: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1735 +//line sql.y:1736 { yyVAL.statement = &OtherAdmin{} } case 316: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1741 +//line sql.y:1742 { yyVAL.statement = &DDL{Action: FlushStr} } case 317: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:1745 +//line sql.y:1746 { setAllowComments(yylex, true) } case 318: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1749 +//line sql.y:1750 { yyVAL.bytes2 = yyDollar[2].bytes2 setAllowComments(yylex, false) } case 319: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:1755 +//line sql.y:1756 { yyVAL.bytes2 = nil } case 320: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1759 +//line sql.y:1760 { yyVAL.bytes2 = append(yyDollar[1].bytes2, yyDollar[2].bytes) } case 321: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1765 +//line sql.y:1766 { yyVAL.str = UnionStr } case 322: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1769 +//line sql.y:1770 { yyVAL.str = UnionAllStr } case 323: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1773 +//line sql.y:1774 { yyVAL.str = UnionDistinctStr } case 324: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:1778 +//line sql.y:1779 { yyVAL.str = "" } case 325: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1782 +//line sql.y:1783 { yyVAL.str = SQLNoCacheStr } case 326: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1786 +//line sql.y:1787 { yyVAL.str = SQLCacheStr } case 327: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:1791 +//line sql.y:1792 { yyVAL.str = "" } case 328: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1795 +//line sql.y:1796 { yyVAL.str = DistinctStr } case 329: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:1800 +//line sql.y:1801 { yyVAL.str = "" } case 330: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1804 +//line sql.y:1805 { yyVAL.str = StraightJoinHint } case 331: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:1809 +//line sql.y:1810 { yyVAL.selectExprs = nil } case 332: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1813 +//line sql.y:1814 { yyVAL.selectExprs = yyDollar[1].selectExprs } case 333: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1819 +//line sql.y:1820 { yyVAL.selectExprs = SelectExprs{yyDollar[1].selectExpr} } case 334: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1823 +//line sql.y:1824 { yyVAL.selectExprs = append(yyVAL.selectExprs, yyDollar[3].selectExpr) } case 335: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1829 +//line sql.y:1830 { yyVAL.selectExpr = &StarExpr{} } case 336: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1833 +//line sql.y:1834 { yyVAL.selectExpr = &AliasedExpr{Expr: yyDollar[1].expr, As: yyDollar[2].colIdent} } case 337: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1837 +//line sql.y:1838 { yyVAL.selectExpr = &StarExpr{TableName: TableName{Name: yyDollar[1].tableIdent}} } case 338: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:1841 +//line sql.y:1842 { yyVAL.selectExpr = &StarExpr{TableName: TableName{Qualifier: yyDollar[1].tableIdent, Name: yyDollar[3].tableIdent}} } case 339: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:1846 +//line sql.y:1847 { yyVAL.colIdent = ColIdent{} } case 340: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1850 +//line sql.y:1851 { yyVAL.colIdent = yyDollar[1].colIdent } case 341: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1854 +//line sql.y:1855 { yyVAL.colIdent = yyDollar[2].colIdent } case 343: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1861 +//line sql.y:1862 { yyVAL.colIdent = NewColIdent(string(yyDollar[1].bytes)) } case 344: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:1866 +//line sql.y:1867 { yyVAL.tableExprs = TableExprs{&AliasedTableExpr{Expr: TableName{Name: NewTableIdent("dual")}}} } case 345: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1870 +//line sql.y:1871 { yyVAL.tableExprs = yyDollar[2].tableExprs } case 346: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1876 +//line sql.y:1877 { yyVAL.tableExprs = TableExprs{yyDollar[1].tableExpr} } case 347: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1880 +//line sql.y:1881 { yyVAL.tableExprs = append(yyVAL.tableExprs, yyDollar[3].tableExpr) } case 350: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1890 +//line sql.y:1891 { yyVAL.tableExpr = yyDollar[1].aliasedTableName } case 351: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1894 +//line sql.y:1895 { yyVAL.tableExpr = &AliasedTableExpr{Expr: yyDollar[1].subquery, As: yyDollar[3].tableIdent} } case 352: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1898 +//line sql.y:1899 { // missed alias for subquery yylex.Error("Every derived table must have its own alias") @@ -4951,199 +4980,199 @@ yydefault: } case 353: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1904 +//line sql.y:1905 { yyVAL.tableExpr = &ParenTableExpr{Exprs: yyDollar[2].tableExprs} } case 354: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1910 +//line sql.y:1911 { yyVAL.aliasedTableName = &AliasedTableExpr{Expr: yyDollar[1].tableName, As: yyDollar[2].tableIdent, Hints: yyDollar[3].indexHints} } case 355: yyDollar = yyS[yypt-7 : yypt+1] -//line sql.y:1914 +//line sql.y:1915 { yyVAL.aliasedTableName = &AliasedTableExpr{Expr: yyDollar[1].tableName, Partitions: yyDollar[4].partitions, As: yyDollar[6].tableIdent, Hints: yyDollar[7].indexHints} } case 356: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1920 +//line sql.y:1921 { yyVAL.columns = Columns{yyDollar[1].colIdent} } case 357: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1924 +//line sql.y:1925 { yyVAL.columns = append(yyVAL.columns, yyDollar[3].colIdent) } case 358: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1930 +//line sql.y:1931 { yyVAL.partitions = Partitions{yyDollar[1].colIdent} } case 359: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1934 +//line sql.y:1935 { yyVAL.partitions = append(yyVAL.partitions, yyDollar[3].colIdent) } case 360: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:1947 +//line sql.y:1948 { yyVAL.tableExpr = &JoinTableExpr{LeftExpr: yyDollar[1].tableExpr, Join: yyDollar[2].str, RightExpr: yyDollar[3].tableExpr, Condition: yyDollar[4].joinCondition} } case 361: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:1951 +//line sql.y:1952 { yyVAL.tableExpr = &JoinTableExpr{LeftExpr: yyDollar[1].tableExpr, Join: yyDollar[2].str, RightExpr: yyDollar[3].tableExpr, Condition: yyDollar[4].joinCondition} } case 362: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:1955 +//line sql.y:1956 { yyVAL.tableExpr = &JoinTableExpr{LeftExpr: yyDollar[1].tableExpr, Join: yyDollar[2].str, RightExpr: yyDollar[3].tableExpr, Condition: yyDollar[4].joinCondition} } case 363: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1959 +//line sql.y:1960 { yyVAL.tableExpr = &JoinTableExpr{LeftExpr: yyDollar[1].tableExpr, Join: yyDollar[2].str, RightExpr: yyDollar[3].tableExpr} } case 364: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1965 +//line sql.y:1966 { yyVAL.joinCondition = JoinCondition{On: yyDollar[2].expr} } case 365: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:1967 +//line sql.y:1968 { yyVAL.joinCondition = JoinCondition{Using: yyDollar[3].columns} } case 366: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:1971 +//line sql.y:1972 { yyVAL.joinCondition = JoinCondition{} } case 367: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1973 +//line sql.y:1974 { yyVAL.joinCondition = yyDollar[1].joinCondition } case 368: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:1977 +//line sql.y:1978 { yyVAL.joinCondition = JoinCondition{} } case 369: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1979 +//line sql.y:1980 { yyVAL.joinCondition = JoinCondition{On: yyDollar[2].expr} } case 370: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:1982 +//line sql.y:1983 { yyVAL.empty = struct{}{} } case 371: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1984 +//line sql.y:1985 { yyVAL.empty = struct{}{} } case 372: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:1987 +//line sql.y:1988 { yyVAL.tableIdent = NewTableIdent("") } case 373: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1991 +//line sql.y:1992 { yyVAL.tableIdent = yyDollar[1].tableIdent } case 374: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1995 +//line sql.y:1996 { yyVAL.tableIdent = yyDollar[2].tableIdent } case 376: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2002 +//line sql.y:2003 { yyVAL.tableIdent = NewTableIdent(string(yyDollar[1].bytes)) } case 377: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2008 +//line sql.y:2009 { yyVAL.str = JoinStr } case 378: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2012 +//line sql.y:2013 { yyVAL.str = JoinStr } case 379: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2016 +//line sql.y:2017 { yyVAL.str = JoinStr } case 380: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2022 +//line sql.y:2023 { yyVAL.str = StraightJoinStr } case 381: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2028 +//line sql.y:2029 { yyVAL.str = LeftJoinStr } case 382: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2032 +//line sql.y:2033 { yyVAL.str = LeftJoinStr } case 383: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2036 +//line sql.y:2037 { yyVAL.str = RightJoinStr } case 384: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2040 +//line sql.y:2041 { yyVAL.str = RightJoinStr } case 385: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2046 +//line sql.y:2047 { yyVAL.str = NaturalJoinStr } case 386: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2050 +//line sql.y:2051 { if yyDollar[2].str == LeftJoinStr { yyVAL.str = NaturalLeftJoinStr @@ -5153,457 +5182,457 @@ yydefault: } case 387: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2060 +//line sql.y:2061 { yyVAL.tableName = yyDollar[2].tableName } case 388: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2064 +//line sql.y:2065 { yyVAL.tableName = yyDollar[1].tableName } case 389: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2070 +//line sql.y:2071 { yyVAL.tableName = TableName{Name: yyDollar[1].tableIdent} } case 390: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2074 +//line sql.y:2075 { yyVAL.tableName = TableName{Qualifier: yyDollar[1].tableIdent, Name: yyDollar[3].tableIdent} } case 391: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:2079 +//line sql.y:2080 { yyVAL.indexHints = nil } case 392: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:2083 +//line sql.y:2084 { yyVAL.indexHints = &IndexHints{Type: UseStr, Indexes: yyDollar[4].columns} } case 393: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:2087 +//line sql.y:2088 { yyVAL.indexHints = &IndexHints{Type: IgnoreStr, Indexes: yyDollar[4].columns} } case 394: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:2091 +//line sql.y:2092 { yyVAL.indexHints = &IndexHints{Type: ForceStr, Indexes: yyDollar[4].columns} } case 395: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:2096 +//line sql.y:2097 { yyVAL.expr = nil } case 396: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2100 +//line sql.y:2101 { yyVAL.expr = yyDollar[2].expr } case 397: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2106 +//line sql.y:2107 { yyVAL.expr = yyDollar[1].expr } case 398: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2110 +//line sql.y:2111 { yyVAL.expr = &AndExpr{Left: yyDollar[1].expr, Right: yyDollar[3].expr} } case 399: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2114 +//line sql.y:2115 { yyVAL.expr = &OrExpr{Left: yyDollar[1].expr, Right: yyDollar[3].expr} } case 400: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2118 +//line sql.y:2119 { yyVAL.expr = &NotExpr{Expr: yyDollar[2].expr} } case 401: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2122 +//line sql.y:2123 { yyVAL.expr = &IsExpr{Operator: yyDollar[3].str, Expr: yyDollar[1].expr} } case 402: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2126 +//line sql.y:2127 { yyVAL.expr = yyDollar[1].expr } case 403: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2130 +//line sql.y:2131 { yyVAL.expr = &Default{ColName: yyDollar[2].str} } case 404: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:2136 +//line sql.y:2137 { yyVAL.str = "" } case 405: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2140 +//line sql.y:2141 { yyVAL.str = string(yyDollar[2].bytes) } case 406: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2146 +//line sql.y:2147 { yyVAL.boolVal = BoolVal(true) } case 407: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2150 +//line sql.y:2151 { yyVAL.boolVal = BoolVal(false) } case 408: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2156 +//line sql.y:2157 { yyVAL.expr = &ComparisonExpr{Left: yyDollar[1].expr, Operator: yyDollar[2].str, Right: yyDollar[3].expr} } case 409: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2160 +//line sql.y:2161 { yyVAL.expr = &ComparisonExpr{Left: yyDollar[1].expr, Operator: InStr, Right: yyDollar[3].colTuple} } case 410: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:2164 +//line sql.y:2165 { yyVAL.expr = &ComparisonExpr{Left: yyDollar[1].expr, Operator: NotInStr, Right: yyDollar[4].colTuple} } case 411: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:2168 +//line sql.y:2169 { yyVAL.expr = &ComparisonExpr{Left: yyDollar[1].expr, Operator: LikeStr, Right: yyDollar[3].expr, Escape: yyDollar[4].expr} } case 412: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:2172 +//line sql.y:2173 { yyVAL.expr = &ComparisonExpr{Left: yyDollar[1].expr, Operator: NotLikeStr, Right: yyDollar[4].expr, Escape: yyDollar[5].expr} } case 413: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2176 +//line sql.y:2177 { yyVAL.expr = &ComparisonExpr{Left: yyDollar[1].expr, Operator: RegexpStr, Right: yyDollar[3].expr} } case 414: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:2180 +//line sql.y:2181 { yyVAL.expr = &ComparisonExpr{Left: yyDollar[1].expr, Operator: NotRegexpStr, Right: yyDollar[4].expr} } case 415: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:2184 +//line sql.y:2185 { yyVAL.expr = &RangeCond{Left: yyDollar[1].expr, Operator: BetweenStr, From: yyDollar[3].expr, To: yyDollar[5].expr} } case 416: yyDollar = yyS[yypt-6 : yypt+1] -//line sql.y:2188 +//line sql.y:2189 { yyVAL.expr = &RangeCond{Left: yyDollar[1].expr, Operator: NotBetweenStr, From: yyDollar[4].expr, To: yyDollar[6].expr} } case 417: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2192 +//line sql.y:2193 { yyVAL.expr = &ExistsExpr{Subquery: yyDollar[2].subquery} } case 418: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2198 +//line sql.y:2199 { yyVAL.str = IsNullStr } case 419: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2202 +//line sql.y:2203 { yyVAL.str = IsNotNullStr } case 420: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2206 +//line sql.y:2207 { yyVAL.str = IsTrueStr } case 421: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2210 +//line sql.y:2211 { yyVAL.str = IsNotTrueStr } case 422: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2214 +//line sql.y:2215 { yyVAL.str = IsFalseStr } case 423: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2218 +//line sql.y:2219 { yyVAL.str = IsNotFalseStr } case 424: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2224 +//line sql.y:2225 { yyVAL.str = EqualStr } case 425: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2228 +//line sql.y:2229 { yyVAL.str = LessThanStr } case 426: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2232 +//line sql.y:2233 { yyVAL.str = GreaterThanStr } case 427: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2236 +//line sql.y:2237 { yyVAL.str = LessEqualStr } case 428: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2240 +//line sql.y:2241 { yyVAL.str = GreaterEqualStr } case 429: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2244 +//line sql.y:2245 { yyVAL.str = NotEqualStr } case 430: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2248 +//line sql.y:2249 { yyVAL.str = NullSafeEqualStr } case 431: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:2253 +//line sql.y:2254 { yyVAL.expr = nil } case 432: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2257 +//line sql.y:2258 { yyVAL.expr = yyDollar[2].expr } case 433: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2263 +//line sql.y:2264 { yyVAL.colTuple = yyDollar[1].valTuple } case 434: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2267 +//line sql.y:2268 { yyVAL.colTuple = yyDollar[1].subquery } case 435: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2271 +//line sql.y:2272 { yyVAL.colTuple = ListArg(yyDollar[1].bytes) } case 436: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2277 +//line sql.y:2278 { yyVAL.subquery = &Subquery{yyDollar[2].selStmt} } case 437: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2283 +//line sql.y:2284 { yyVAL.exprs = Exprs{yyDollar[1].expr} } case 438: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2287 +//line sql.y:2288 { yyVAL.exprs = append(yyDollar[1].exprs, yyDollar[3].expr) } case 439: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2293 +//line sql.y:2294 { yyVAL.expr = yyDollar[1].expr } case 440: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2297 +//line sql.y:2298 { yyVAL.expr = yyDollar[1].boolVal } case 441: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2301 +//line sql.y:2302 { yyVAL.expr = yyDollar[1].colName } case 442: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2305 +//line sql.y:2306 { yyVAL.expr = yyDollar[1].expr } case 443: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2309 +//line sql.y:2310 { yyVAL.expr = yyDollar[1].subquery } case 444: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2313 +//line sql.y:2314 { yyVAL.expr = &BinaryExpr{Left: yyDollar[1].expr, Operator: BitAndStr, Right: yyDollar[3].expr} } case 445: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2317 +//line sql.y:2318 { yyVAL.expr = &BinaryExpr{Left: yyDollar[1].expr, Operator: BitOrStr, Right: yyDollar[3].expr} } case 446: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2321 +//line sql.y:2322 { yyVAL.expr = &BinaryExpr{Left: yyDollar[1].expr, Operator: BitXorStr, Right: yyDollar[3].expr} } case 447: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2325 +//line sql.y:2326 { yyVAL.expr = &BinaryExpr{Left: yyDollar[1].expr, Operator: PlusStr, Right: yyDollar[3].expr} } case 448: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2329 +//line sql.y:2330 { yyVAL.expr = &BinaryExpr{Left: yyDollar[1].expr, Operator: MinusStr, Right: yyDollar[3].expr} } case 449: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2333 +//line sql.y:2334 { yyVAL.expr = &BinaryExpr{Left: yyDollar[1].expr, Operator: MultStr, Right: yyDollar[3].expr} } case 450: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2337 +//line sql.y:2338 { yyVAL.expr = &BinaryExpr{Left: yyDollar[1].expr, Operator: DivStr, Right: yyDollar[3].expr} } case 451: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2341 +//line sql.y:2342 { yyVAL.expr = &BinaryExpr{Left: yyDollar[1].expr, Operator: IntDivStr, Right: yyDollar[3].expr} } case 452: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2345 +//line sql.y:2346 { yyVAL.expr = &BinaryExpr{Left: yyDollar[1].expr, Operator: ModStr, Right: yyDollar[3].expr} } case 453: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2349 +//line sql.y:2350 { yyVAL.expr = &BinaryExpr{Left: yyDollar[1].expr, Operator: ModStr, Right: yyDollar[3].expr} } case 454: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2353 +//line sql.y:2354 { yyVAL.expr = &BinaryExpr{Left: yyDollar[1].expr, Operator: ShiftLeftStr, Right: yyDollar[3].expr} } case 455: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2357 +//line sql.y:2358 { yyVAL.expr = &BinaryExpr{Left: yyDollar[1].expr, Operator: ShiftRightStr, Right: yyDollar[3].expr} } case 456: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2361 +//line sql.y:2362 { yyVAL.expr = &BinaryExpr{Left: yyDollar[1].colName, Operator: JSONExtractOp, Right: yyDollar[3].expr} } case 457: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2365 +//line sql.y:2366 { yyVAL.expr = &BinaryExpr{Left: yyDollar[1].colName, Operator: JSONUnquoteExtractOp, Right: yyDollar[3].expr} } case 458: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2369 +//line sql.y:2370 { yyVAL.expr = &CollateExpr{Expr: yyDollar[1].expr, Charset: yyDollar[3].str} } case 459: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2373 +//line sql.y:2374 { yyVAL.expr = &UnaryExpr{Operator: BinaryStr, Expr: yyDollar[2].expr} } case 460: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2377 +//line sql.y:2378 { yyVAL.expr = &UnaryExpr{Operator: UBinaryStr, Expr: yyDollar[2].expr} } case 461: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2381 +//line sql.y:2382 { yyVAL.expr = &UnaryExpr{Operator: Utf8mb4Str, Expr: yyDollar[2].expr} } case 462: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2385 +//line sql.y:2386 { if num, ok := yyDollar[2].expr.(*SQLVal); ok && num.Type == IntVal { yyVAL.expr = num @@ -5613,7 +5642,7 @@ yydefault: } case 463: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2393 +//line sql.y:2394 { if num, ok := yyDollar[2].expr.(*SQLVal); ok && num.Type == IntVal { // Handle double negative @@ -5629,19 +5658,19 @@ yydefault: } case 464: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2407 +//line sql.y:2408 { yyVAL.expr = &UnaryExpr{Operator: TildaStr, Expr: yyDollar[2].expr} } case 465: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2411 +//line sql.y:2412 { yyVAL.expr = &UnaryExpr{Operator: BangStr, Expr: yyDollar[2].expr} } case 466: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2415 +//line sql.y:2416 { // This rule prevents the usage of INTERVAL // as a function. If support is needed for that, @@ -5651,465 +5680,477 @@ yydefault: } case 471: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:2433 +//line sql.y:2434 { yyVAL.expr = &FuncExpr{Name: yyDollar[1].colIdent, Exprs: yyDollar[3].selectExprs} } case 472: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:2437 +//line sql.y:2438 { yyVAL.expr = &FuncExpr{Name: yyDollar[1].colIdent, Distinct: true, Exprs: yyDollar[4].selectExprs} } case 473: yyDollar = yyS[yypt-6 : yypt+1] -//line sql.y:2441 +//line sql.y:2442 { yyVAL.expr = &FuncExpr{Qualifier: yyDollar[1].tableIdent, Name: yyDollar[3].colIdent, Exprs: yyDollar[5].selectExprs} } case 474: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:2451 +//line sql.y:2452 { yyVAL.expr = &FuncExpr{Name: NewColIdent("left"), Exprs: yyDollar[3].selectExprs} } case 475: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:2455 +//line sql.y:2456 { yyVAL.expr = &FuncExpr{Name: NewColIdent("right"), Exprs: yyDollar[3].selectExprs} } case 476: yyDollar = yyS[yypt-6 : yypt+1] -//line sql.y:2459 +//line sql.y:2460 { yyVAL.expr = &ConvertExpr{Expr: yyDollar[3].expr, Type: yyDollar[5].convertType} } case 477: yyDollar = yyS[yypt-6 : yypt+1] -//line sql.y:2463 +//line sql.y:2464 { yyVAL.expr = &ConvertExpr{Expr: yyDollar[3].expr, Type: yyDollar[5].convertType} } case 478: yyDollar = yyS[yypt-6 : yypt+1] -//line sql.y:2467 +//line sql.y:2468 { yyVAL.expr = &ConvertUsingExpr{Expr: yyDollar[3].expr, Type: yyDollar[5].str} } case 479: yyDollar = yyS[yypt-6 : yypt+1] -//line sql.y:2471 +//line sql.y:2472 { yyVAL.expr = &SubstrExpr{Name: yyDollar[3].colName, From: yyDollar[5].expr, To: nil} } case 480: yyDollar = yyS[yypt-8 : yypt+1] -//line sql.y:2475 +//line sql.y:2476 { yyVAL.expr = &SubstrExpr{Name: yyDollar[3].colName, From: yyDollar[5].expr, To: yyDollar[7].expr} } case 481: yyDollar = yyS[yypt-8 : yypt+1] -//line sql.y:2479 +//line sql.y:2480 { yyVAL.expr = &SubstrExpr{Name: yyDollar[3].colName, From: yyDollar[5].expr, To: yyDollar[7].expr} } case 482: yyDollar = yyS[yypt-6 : yypt+1] -//line sql.y:2483 +//line sql.y:2484 { yyVAL.expr = &SubstrExpr{Name: yyDollar[3].colName, From: yyDollar[5].expr, To: nil} } case 483: yyDollar = yyS[yypt-8 : yypt+1] -//line sql.y:2487 +//line sql.y:2488 { yyVAL.expr = &SubstrExpr{Name: yyDollar[3].colName, From: yyDollar[5].expr, To: yyDollar[7].expr} } case 484: yyDollar = yyS[yypt-8 : yypt+1] -//line sql.y:2491 +//line sql.y:2492 { yyVAL.expr = &SubstrExpr{Name: yyDollar[3].colName, From: yyDollar[5].expr, To: yyDollar[7].expr} } case 485: yyDollar = yyS[yypt-6 : yypt+1] -//line sql.y:2495 +//line sql.y:2496 { yyVAL.expr = &SubstrExpr{StrVal: NewStrVal(yyDollar[3].bytes), From: yyDollar[5].expr, To: nil} } case 486: yyDollar = yyS[yypt-8 : yypt+1] -//line sql.y:2499 +//line sql.y:2500 { yyVAL.expr = &SubstrExpr{StrVal: NewStrVal(yyDollar[3].bytes), From: yyDollar[5].expr, To: yyDollar[7].expr} } case 487: yyDollar = yyS[yypt-8 : yypt+1] -//line sql.y:2503 +//line sql.y:2504 { yyVAL.expr = &SubstrExpr{StrVal: NewStrVal(yyDollar[3].bytes), From: yyDollar[5].expr, To: yyDollar[7].expr} } case 488: yyDollar = yyS[yypt-6 : yypt+1] -//line sql.y:2507 +//line sql.y:2508 { yyVAL.expr = &SubstrExpr{StrVal: NewStrVal(yyDollar[3].bytes), From: yyDollar[5].expr, To: nil} } case 489: yyDollar = yyS[yypt-8 : yypt+1] -//line sql.y:2511 +//line sql.y:2512 { yyVAL.expr = &SubstrExpr{StrVal: NewStrVal(yyDollar[3].bytes), From: yyDollar[5].expr, To: yyDollar[7].expr} } case 490: yyDollar = yyS[yypt-8 : yypt+1] -//line sql.y:2515 +//line sql.y:2516 { yyVAL.expr = &SubstrExpr{StrVal: NewStrVal(yyDollar[3].bytes), From: yyDollar[5].expr, To: yyDollar[7].expr} } case 491: yyDollar = yyS[yypt-9 : yypt+1] -//line sql.y:2519 +//line sql.y:2520 { yyVAL.expr = &MatchExpr{Columns: yyDollar[3].selectExprs, Expr: yyDollar[7].expr, Option: yyDollar[8].str} } case 492: yyDollar = yyS[yypt-7 : yypt+1] -//line sql.y:2523 +//line sql.y:2524 { yyVAL.expr = &GroupConcatExpr{Distinct: yyDollar[3].str, Exprs: yyDollar[4].selectExprs, OrderBy: yyDollar[5].orderBy, Separator: yyDollar[6].str} } case 493: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:2527 +//line sql.y:2528 { yyVAL.expr = &CaseExpr{Expr: yyDollar[2].expr, Whens: yyDollar[3].whens, Else: yyDollar[4].expr} } case 494: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:2531 +//line sql.y:2532 { yyVAL.expr = &ValuesFuncExpr{Name: yyDollar[3].colName} } case 495: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2541 +//line sql.y:2542 { yyVAL.expr = &FuncExpr{Name: NewColIdent("current_timestamp")} } case 496: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2545 +//line sql.y:2546 { yyVAL.expr = &FuncExpr{Name: NewColIdent("utc_timestamp")} } case 497: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2549 +//line sql.y:2550 { yyVAL.expr = &FuncExpr{Name: NewColIdent("utc_time")} } case 498: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2553 +//line sql.y:2554 { yyVAL.expr = &FuncExpr{Name: NewColIdent("utc_date")} } case 499: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2558 +//line sql.y:2559 { yyVAL.expr = &FuncExpr{Name: NewColIdent("localtime")} } case 500: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2563 +//line sql.y:2564 { yyVAL.expr = &FuncExpr{Name: NewColIdent("localtimestamp")} } case 501: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2568 +//line sql.y:2569 { yyVAL.expr = &FuncExpr{Name: NewColIdent("current_date")} } case 502: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2573 +//line sql.y:2574 { yyVAL.expr = &FuncExpr{Name: NewColIdent("current_time")} } - case 505: + case 503: + yyDollar = yyS[yypt-8 : yypt+1] +//line sql.y:2578 + { + yyVAL.expr = &TimestampFuncExpr{Name: string("timestampadd"), Unit: yyDollar[3].colIdent.String(), Expr1: yyDollar[5].expr, Expr2: yyDollar[7].expr} + } + case 504: + yyDollar = yyS[yypt-8 : yypt+1] +//line sql.y:2582 + { + yyVAL.expr = &TimestampFuncExpr{Name: string("timestampdiff"), Unit: yyDollar[3].colIdent.String(), Expr1: yyDollar[5].expr, Expr2: yyDollar[7].expr} + } + case 507: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:2587 +//line sql.y:2596 { yyVAL.expr = &FuncExpr{Name: NewColIdent("if"), Exprs: yyDollar[3].selectExprs} } - case 506: + case 508: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:2591 +//line sql.y:2600 { yyVAL.expr = &FuncExpr{Name: NewColIdent("database"), Exprs: yyDollar[3].selectExprs} } - case 507: + case 509: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:2595 +//line sql.y:2604 { yyVAL.expr = &FuncExpr{Name: NewColIdent("mod"), Exprs: yyDollar[3].selectExprs} } - case 508: + case 510: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:2599 +//line sql.y:2608 { yyVAL.expr = &FuncExpr{Name: NewColIdent("replace"), Exprs: yyDollar[3].selectExprs} } - case 509: + case 511: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:2605 +//line sql.y:2614 { yyVAL.str = "" } - case 510: + case 512: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2609 +//line sql.y:2618 { yyVAL.str = BooleanModeStr } - case 511: + case 513: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:2613 +//line sql.y:2622 { yyVAL.str = NaturalLanguageModeStr } - case 512: + case 514: yyDollar = yyS[yypt-7 : yypt+1] -//line sql.y:2617 +//line sql.y:2626 { yyVAL.str = NaturalLanguageModeWithQueryExpansionStr } - case 513: + case 515: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2621 +//line sql.y:2630 { yyVAL.str = QueryExpansionStr } - case 514: + case 516: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2627 +//line sql.y:2636 { yyVAL.str = string(yyDollar[1].bytes) } - case 515: + case 517: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2631 +//line sql.y:2640 { yyVAL.str = string(yyDollar[1].bytes) } - case 516: + case 518: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2637 +//line sql.y:2646 { yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes), Length: yyDollar[2].optVal} } - case 517: + case 519: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2641 +//line sql.y:2650 { yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes), Length: yyDollar[2].optVal, Charset: yyDollar[3].str, Operator: CharacterSetStr} } - case 518: + case 520: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2645 +//line sql.y:2654 { yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes), Length: yyDollar[2].optVal, Charset: string(yyDollar[3].bytes)} } - case 519: + case 521: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2649 +//line sql.y:2658 { yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes)} } - case 520: + case 522: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2653 +//line sql.y:2662 { yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes), Length: yyDollar[2].optVal} } - case 521: + case 523: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2657 +//line sql.y:2666 { 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 524: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2663 +//line sql.y:2672 { yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes)} } - case 523: + case 525: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2667 +//line sql.y:2676 { yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes), Length: yyDollar[2].optVal} } - case 524: + case 526: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2671 +//line sql.y:2680 { yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes)} } - case 525: + case 527: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2675 +//line sql.y:2684 { yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes)} } - case 526: + case 528: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2679 +//line sql.y:2688 { yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes), Length: yyDollar[2].optVal} } - case 527: + case 529: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2683 +//line sql.y:2692 { yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes)} } - case 528: + case 530: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2687 +//line sql.y:2696 { yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes)} } - case 529: + case 531: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:2692 +//line sql.y:2701 { yyVAL.expr = nil } - case 530: + case 532: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2696 +//line sql.y:2705 { yyVAL.expr = yyDollar[1].expr } - case 531: + case 533: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:2701 +//line sql.y:2710 { yyVAL.str = string("") } - case 532: + case 534: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2705 +//line sql.y:2714 { yyVAL.str = " separator '" + string(yyDollar[2].bytes) + "'" } - case 533: + case 535: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2711 +//line sql.y:2720 { yyVAL.whens = []*When{yyDollar[1].when} } - case 534: + case 536: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2715 +//line sql.y:2724 { yyVAL.whens = append(yyDollar[1].whens, yyDollar[2].when) } - case 535: + case 537: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:2721 +//line sql.y:2730 { yyVAL.when = &When{Cond: yyDollar[2].expr, Val: yyDollar[4].expr} } - case 536: + case 538: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:2726 +//line sql.y:2735 { yyVAL.expr = nil } - case 537: + case 539: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2730 +//line sql.y:2739 { yyVAL.expr = yyDollar[2].expr } - case 538: + case 540: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2736 +//line sql.y:2745 { yyVAL.colName = &ColName{Name: yyDollar[1].colIdent} } - case 539: + case 541: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2740 +//line sql.y:2749 { yyVAL.colName = &ColName{Qualifier: TableName{Name: yyDollar[1].tableIdent}, Name: yyDollar[3].colIdent} } - case 540: + case 542: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:2744 +//line sql.y:2753 { yyVAL.colName = &ColName{Qualifier: TableName{Qualifier: yyDollar[1].tableIdent, Name: yyDollar[3].tableIdent}, Name: yyDollar[5].colIdent} } - case 541: + case 543: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2750 +//line sql.y:2759 { yyVAL.expr = NewStrVal(yyDollar[1].bytes) } - case 542: + case 544: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2754 +//line sql.y:2763 { yyVAL.expr = NewHexVal(yyDollar[1].bytes) } - case 543: + case 545: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2758 +//line sql.y:2767 { yyVAL.expr = NewBitVal(yyDollar[1].bytes) } - case 544: + case 546: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2762 +//line sql.y:2771 { yyVAL.expr = NewIntVal(yyDollar[1].bytes) } - case 545: + case 547: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2766 +//line sql.y:2775 { yyVAL.expr = NewFloatVal(yyDollar[1].bytes) } - case 546: + case 548: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2770 +//line sql.y:2779 { yyVAL.expr = NewHexNum(yyDollar[1].bytes) } - case 547: + case 549: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2774 +//line sql.y:2783 { yyVAL.expr = NewValArg(yyDollar[1].bytes) } - case 548: + case 550: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2778 +//line sql.y:2787 { yyVAL.expr = &NullVal{} } - case 549: + case 551: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2784 +//line sql.y:2793 { // TODO(sougou): Deprecate this construct. if yyDollar[1].colIdent.Lowered() != "value" { @@ -6118,239 +6159,239 @@ yydefault: } yyVAL.expr = NewIntVal([]byte("1")) } - case 550: + case 552: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2793 +//line sql.y:2802 { yyVAL.expr = NewIntVal(yyDollar[1].bytes) } - case 551: + case 553: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2797 +//line sql.y:2806 { yyVAL.expr = NewValArg(yyDollar[1].bytes) } - case 552: + case 554: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:2802 +//line sql.y:2811 { yyVAL.exprs = nil } - case 553: + case 555: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2806 +//line sql.y:2815 { yyVAL.exprs = yyDollar[3].exprs } - case 554: + case 556: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:2811 +//line sql.y:2820 { yyVAL.expr = nil } - case 555: + case 557: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2815 +//line sql.y:2824 { yyVAL.expr = yyDollar[2].expr } - case 556: + case 558: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:2820 +//line sql.y:2829 { yyVAL.orderBy = nil } - case 557: + case 559: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2824 +//line sql.y:2833 { yyVAL.orderBy = yyDollar[3].orderBy } - case 558: + case 560: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2830 +//line sql.y:2839 { yyVAL.orderBy = OrderBy{yyDollar[1].order} } - case 559: + case 561: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2834 +//line sql.y:2843 { yyVAL.orderBy = append(yyDollar[1].orderBy, yyDollar[3].order) } - case 560: + case 562: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2840 +//line sql.y:2849 { yyVAL.order = &Order{Expr: yyDollar[1].expr, Direction: yyDollar[2].str} } - case 561: + case 563: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:2845 +//line sql.y:2854 { yyVAL.str = AscScr } - case 562: + case 564: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2849 +//line sql.y:2858 { yyVAL.str = AscScr } - case 563: + case 565: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2853 +//line sql.y:2862 { yyVAL.str = DescScr } - case 564: + case 566: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:2858 +//line sql.y:2867 { yyVAL.limit = nil } - case 565: + case 567: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2862 +//line sql.y:2871 { yyVAL.limit = &Limit{Rowcount: yyDollar[2].expr} } - case 566: + case 568: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:2866 +//line sql.y:2875 { yyVAL.limit = &Limit{Offset: yyDollar[2].expr, Rowcount: yyDollar[4].expr} } - case 567: + case 569: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:2870 +//line sql.y:2879 { yyVAL.limit = &Limit{Offset: yyDollar[4].expr, Rowcount: yyDollar[2].expr} } - case 568: + case 570: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:2875 +//line sql.y:2884 { yyVAL.str = "" } - case 569: + case 571: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2879 +//line sql.y:2888 { yyVAL.str = ForUpdateStr } - case 570: + case 572: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:2883 +//line sql.y:2892 { yyVAL.str = ShareModeStr } - case 571: + case 573: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2896 +//line sql.y:2905 { yyVAL.ins = &Insert{Rows: yyDollar[2].values} } - case 572: + case 574: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2900 +//line sql.y:2909 { yyVAL.ins = &Insert{Rows: yyDollar[1].selStmt} } - case 573: + case 575: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2904 +//line sql.y:2913 { // Drop the redundant parenthesis. yyVAL.ins = &Insert{Rows: yyDollar[2].selStmt} } - case 574: + case 576: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:2909 +//line sql.y:2918 { yyVAL.ins = &Insert{Columns: yyDollar[2].columns, Rows: yyDollar[5].values} } - case 575: + case 577: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:2913 +//line sql.y:2922 { yyVAL.ins = &Insert{Columns: yyDollar[2].columns, Rows: yyDollar[4].selStmt} } - case 576: + case 578: yyDollar = yyS[yypt-6 : yypt+1] -//line sql.y:2917 +//line sql.y:2926 { // Drop the redundant parenthesis. yyVAL.ins = &Insert{Columns: yyDollar[2].columns, Rows: yyDollar[5].selStmt} } - case 577: + case 579: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2924 +//line sql.y:2933 { yyVAL.columns = Columns{yyDollar[1].colIdent} } - case 578: + case 580: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2928 +//line sql.y:2937 { yyVAL.columns = Columns{yyDollar[3].colIdent} } - case 579: + case 581: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2932 +//line sql.y:2941 { yyVAL.columns = append(yyVAL.columns, yyDollar[3].colIdent) } - case 580: + case 582: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:2936 +//line sql.y:2945 { yyVAL.columns = append(yyVAL.columns, yyDollar[5].colIdent) } - case 581: + case 583: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:2941 +//line sql.y:2950 { yyVAL.updateExprs = nil } - case 582: + case 584: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:2945 +//line sql.y:2954 { yyVAL.updateExprs = yyDollar[5].updateExprs } - case 583: + case 585: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2951 +//line sql.y:2960 { yyVAL.values = Values{yyDollar[1].valTuple} } - case 584: + case 586: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2955 +//line sql.y:2964 { yyVAL.values = append(yyDollar[1].values, yyDollar[3].valTuple) } - case 585: + case 587: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2961 +//line sql.y:2970 { yyVAL.valTuple = yyDollar[1].valTuple } - case 586: + case 588: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2965 +//line sql.y:2974 { yyVAL.valTuple = ValTuple{} } - case 587: + case 589: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2971 +//line sql.y:2980 { yyVAL.valTuple = ValTuple(yyDollar[2].exprs) } - case 588: + case 590: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2977 +//line sql.y:2986 { if len(yyDollar[1].valTuple) == 1 { yyVAL.expr = &ParenExpr{yyDollar[1].valTuple[0]} @@ -6358,312 +6399,312 @@ yydefault: yyVAL.expr = yyDollar[1].valTuple } } - case 589: + case 591: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2987 +//line sql.y:2996 { yyVAL.updateExprs = UpdateExprs{yyDollar[1].updateExpr} } - case 590: + case 592: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2991 +//line sql.y:3000 { yyVAL.updateExprs = append(yyDollar[1].updateExprs, yyDollar[3].updateExpr) } - case 591: + case 593: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2997 +//line sql.y:3006 { yyVAL.updateExpr = &UpdateExpr{Name: yyDollar[1].colName, Expr: yyDollar[3].expr} } - case 592: + case 594: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3003 +//line sql.y:3012 { yyVAL.setExprs = SetExprs{yyDollar[1].setExpr} } - case 593: + case 595: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:3007 +//line sql.y:3016 { yyVAL.setExprs = append(yyDollar[1].setExprs, yyDollar[3].setExpr) } - case 594: + case 596: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:3013 +//line sql.y:3022 { yyVAL.setExpr = &SetExpr{Name: yyDollar[1].colIdent, Expr: NewStrVal([]byte("on"))} } - case 595: + case 597: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:3017 +//line sql.y:3026 { yyVAL.setExpr = &SetExpr{Name: yyDollar[1].colIdent, Expr: NewStrVal([]byte("off"))} } - case 596: + case 598: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:3021 +//line sql.y:3030 { yyVAL.setExpr = &SetExpr{Name: yyDollar[1].colIdent, Expr: yyDollar[3].expr} } - case 597: + case 599: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:3025 +//line sql.y:3034 { yyVAL.setExpr = &SetExpr{Name: NewColIdent(string(yyDollar[1].bytes)), Expr: yyDollar[2].expr} } - case 599: + case 601: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:3032 +//line sql.y:3041 { yyVAL.bytes = []byte("charset") } - case 601: + case 603: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3039 +//line sql.y:3048 { yyVAL.expr = NewStrVal([]byte(yyDollar[1].colIdent.String())) } - case 602: + case 604: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3043 +//line sql.y:3052 { yyVAL.expr = NewStrVal(yyDollar[1].bytes) } - case 603: + case 605: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3047 +//line sql.y:3056 { yyVAL.expr = &Default{} } - case 606: + case 608: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:3056 +//line sql.y:3065 { yyVAL.byt = 0 } - case 607: + case 609: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:3058 +//line sql.y:3067 { yyVAL.byt = 1 } - case 608: + case 610: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:3061 +//line sql.y:3070 { yyVAL.empty = struct{}{} } - case 609: + case 611: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:3063 +//line sql.y:3072 { yyVAL.empty = struct{}{} } - case 610: + case 612: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:3066 +//line sql.y:3075 { yyVAL.str = "" } - case 611: - yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3068 - { - yyVAL.str = IgnoreStr - } - case 612: - yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3072 - { - yyVAL.empty = struct{}{} - } case 613: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3074 +//line sql.y:3077 { - yyVAL.empty = struct{}{} + yyVAL.str = IgnoreStr } case 614: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3076 +//line sql.y:3081 { yyVAL.empty = struct{}{} } case 615: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3078 +//line sql.y:3083 { yyVAL.empty = struct{}{} } case 616: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3080 +//line sql.y:3085 { yyVAL.empty = struct{}{} } case 617: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3082 +//line sql.y:3087 { yyVAL.empty = struct{}{} } case 618: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3084 +//line sql.y:3089 { yyVAL.empty = struct{}{} } case 619: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3086 +//line sql.y:3091 { yyVAL.empty = struct{}{} } case 620: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3088 +//line sql.y:3093 { yyVAL.empty = struct{}{} } case 621: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3090 +//line sql.y:3095 { yyVAL.empty = struct{}{} } case 622: - yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:3093 + yyDollar = yyS[yypt-1 : yypt+1] +//line sql.y:3097 { yyVAL.empty = struct{}{} } case 623: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3095 +//line sql.y:3099 { yyVAL.empty = struct{}{} } case 624: - yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3097 + yyDollar = yyS[yypt-0 : yypt+1] +//line sql.y:3102 { yyVAL.empty = struct{}{} } case 625: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3101 +//line sql.y:3104 { yyVAL.empty = struct{}{} } case 626: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3103 +//line sql.y:3106 { yyVAL.empty = struct{}{} } case 627: - yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:3106 + yyDollar = yyS[yypt-1 : yypt+1] +//line sql.y:3110 { yyVAL.empty = struct{}{} } case 628: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3108 +//line sql.y:3112 { yyVAL.empty = struct{}{} } case 629: - yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3110 + yyDollar = yyS[yypt-0 : yypt+1] +//line sql.y:3115 { yyVAL.empty = struct{}{} } case 630: + yyDollar = yyS[yypt-1 : yypt+1] +//line sql.y:3117 + { + yyVAL.empty = struct{}{} + } + case 631: + yyDollar = yyS[yypt-1 : yypt+1] +//line sql.y:3119 + { + yyVAL.empty = struct{}{} + } + case 632: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:3113 +//line sql.y:3122 { yyVAL.colIdent = ColIdent{} } - case 631: + case 633: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:3115 +//line sql.y:3124 { yyVAL.colIdent = yyDollar[2].colIdent } - case 632: + case 634: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3119 +//line sql.y:3128 { yyVAL.colIdent = NewColIdent(string(yyDollar[1].bytes)) } - case 633: + case 635: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3123 +//line sql.y:3132 { yyVAL.colIdent = NewColIdent(string(yyDollar[1].bytes)) } - case 635: + case 637: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3130 +//line sql.y:3139 { yyVAL.colIdent = NewColIdent(string(yyDollar[1].bytes)) } - case 636: + case 638: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3136 +//line sql.y:3145 { yyVAL.tableIdent = NewTableIdent(string(yyDollar[1].bytes)) } - case 637: + case 639: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3140 +//line sql.y:3149 { yyVAL.tableIdent = NewTableIdent(string(yyDollar[1].bytes)) } - case 639: + case 641: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3147 +//line sql.y:3156 { yyVAL.tableIdent = NewTableIdent(string(yyDollar[1].bytes)) } - case 846: + case 850: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3379 +//line sql.y:3390 { if incNesting(yylex) { yylex.Error("max nesting level reached") return 1 } } - case 847: + case 851: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3388 +//line sql.y:3399 { decNesting(yylex) } - case 848: + case 852: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:3393 +//line sql.y:3404 { skipToEnd(yylex) } - case 849: + case 853: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:3398 +//line sql.y:3409 { skipToEnd(yylex) } - case 850: + case 854: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3402 +//line sql.y:3413 { skipToEnd(yylex) } - case 851: + case 855: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3406 +//line sql.y:3417 { skipToEnd(yylex) } diff --git a/go/vt/sqlparser/sql.y b/go/vt/sqlparser/sql.y index 07dc55ca4c7..b05d0421f04 100644 --- a/go/vt/sqlparser/sql.y +++ b/go/vt/sqlparser/sql.y @@ -193,6 +193,7 @@ func skipToEnd(yylex interface{}) { %token CONVERT CAST %token SUBSTR SUBSTRING %token GROUP_CONCAT SEPARATOR +%token TIMESTAMPADD TIMESTAMPDIFF // Match %token MATCH AGAINST BOOLEAN LANGUAGE WITH QUERY EXPANSION @@ -2573,6 +2574,14 @@ function_call_nonkeyword: { $$ = &FuncExpr{Name:NewColIdent("current_time")} } +| TIMESTAMPADD openb sql_id ',' value_expression ',' value_expression closeb + { + $$ = &TimestampFuncExpr{Name:string("timestampadd"), Unit:$3.String(), Expr1:$5, Expr2:$7} + } +| TIMESTAMPDIFF openb sql_id ',' value_expression ',' value_expression closeb + { + $$ = &TimestampFuncExpr{Name:string("timestampdiff"), Unit:$3.String(), Expr1:$5, Expr2:$7} + } func_datetime_precision_opt: /* empty */ @@ -3237,6 +3246,8 @@ reserved_keyword: | STRAIGHT_JOIN | TABLE | THEN +| TIMESTAMPADD +| TIMESTAMPDIFF | TO | TRUE | UNION diff --git a/go/vt/sqlparser/token.go b/go/vt/sqlparser/token.go index 31b3bc33d75..dee429af007 100644 --- a/go/vt/sqlparser/token.go +++ b/go/vt/sqlparser/token.go @@ -357,6 +357,8 @@ var keywords = map[string]int{ "then": THEN, "time": TIME, "timestamp": TIMESTAMP, + "timestampadd": TIMESTAMPADD, + "timestampdiff": TIMESTAMPDIFF, "tinyblob": TINYBLOB, "tinyint": TINYINT, "tinytext": TINYTEXT, From dbc94c0c5aeb2b5fc386dd32600f43b2e5b31c86 Mon Sep 17 00:00:00 2001 From: "Iskander (Alex) Sharipov" Date: Tue, 29 Jan 2019 00:42:11 +0300 Subject: [PATCH 100/115] go/mysql: remove excessive []byte(s) conversion `copy` permits using to mix `[]byte` and `string` arguments without explicit conversion. I removed explicit conversion to make code simpler. Signed-off-by: Iskander Sharipov --- go/mysql/binlog_event_make.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/go/mysql/binlog_event_make.go b/go/mysql/binlog_event_make.go index d5250fa05d3..b898c0a4dce 100644 --- a/go/mysql/binlog_event_make.go +++ b/go/mysql/binlog_event_make.go @@ -127,7 +127,7 @@ func NewFormatDescriptionEvent(f BinlogFormat, s *FakeBinlogStream) BinlogEvent 1 // (undocumented) checksum algorithm data := make([]byte, length) binary.LittleEndian.PutUint16(data[0:2], f.FormatVersion) - copy(data[2:52], []byte(f.ServerVersion)) + copy(data[2:52], f.ServerVersion) binary.LittleEndian.PutUint32(data[52:56], s.Timestamp) data[56] = f.HeaderLength copy(data[57:], f.HeaderSizes) @@ -197,7 +197,7 @@ func NewQueryEvent(f BinlogFormat, s *FakeBinlogStream, q Query) BinlogEvent { data[pos+6] = byte(q.Charset.Server >> 8) pos += 7 } - pos += copy(data[pos:pos+len(q.Database)], []byte(q.Database)) + pos += copy(data[pos:pos+len(q.Database)], q.Database) data[pos] = 0 pos++ copy(data[pos:], q.SQL) @@ -310,11 +310,11 @@ func NewTableMapEvent(f BinlogFormat, s *FakeBinlogStream, tableID uint64, tm *T data[6] = byte(tm.Flags) data[7] = byte(tm.Flags >> 8) data[8] = byte(len(tm.Database)) - pos := 6 + 2 + 1 + copy(data[9:], []byte(tm.Database)) + pos := 6 + 2 + 1 + copy(data[9:], tm.Database) data[pos] = 0 pos++ data[pos] = byte(len(tm.Name)) - pos += 1 + copy(data[pos+1:], []byte(tm.Name)) + pos += 1 + copy(data[pos+1:], tm.Name) data[pos] = 0 pos++ From c00469e3bdcf83d99f6a2e7de8747a48c31c041f Mon Sep 17 00:00:00 2001 From: Andres Taylor Date: Tue, 29 Jan 2019 06:32:40 +0100 Subject: [PATCH 101/115] Mkwe consistent snapshot the default Signed-off-by: Andres Taylor --- go/vt/worker/split_clone_cmd.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go/vt/worker/split_clone_cmd.go b/go/vt/worker/split_clone_cmd.go index f349fb25f89..e3d1085560d 100644 --- a/go/vt/worker/split_clone_cmd.go +++ b/go/vt/worker/split_clone_cmd.go @@ -98,7 +98,7 @@ const splitCloneHTML2 = ` - ?
+ ?
From 4a5d58ead6a4acfb69c46935d0dac1760b0e87a0 Mon Sep 17 00:00:00 2001 From: xichengliudui Date: Tue, 29 Jan 2019 10:10:23 -0500 Subject: [PATCH 102/115] Update comments in functions Signed-off-by: xichengliudui --- go/vt/binlog/binlogplayertest/player.go | 6 +++--- go/vt/proto/vtgate/vtgate.pb.go | 2 +- go/vt/schemamanager/schemaswap/schema_swap.go | 2 +- go/vt/vtgate/planbuilder/insert.go | 2 +- go/vt/vtgate/planbuilder/ordered_aggregate.go | 2 +- go/vt/vtgate/scatter_conn.go | 2 +- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/go/vt/binlog/binlogplayertest/player.go b/go/vt/binlog/binlogplayertest/player.go index 5c6a76cd949..c8c0155a8d0 100644 --- a/go/vt/binlog/binlogplayertest/player.go +++ b/go/vt/binlog/binlogplayertest/player.go @@ -96,7 +96,7 @@ var testBinlogTransaction = &binlogdatapb.BinlogTransaction{ }, } -// StreamKeyRange is part of the the UpdateStream interface +// StreamKeyRange is part of the UpdateStream interface func (fake *FakeBinlogStreamer) StreamKeyRange(ctx context.Context, position string, keyRange *topodatapb.KeyRange, charset *binlogdatapb.Charset, callback func(reply *binlogdatapb.BinlogTransaction) error) error { if fake.panics { panic(fmt.Errorf("test-triggered panic")) @@ -162,7 +162,7 @@ var testTablesRequest = &tablesRequest{ }, } -// StreamTables is part of the the UpdateStream interface +// StreamTables is part of the UpdateStream interface func (fake *FakeBinlogStreamer) StreamTables(ctx context.Context, position string, tables []string, charset *binlogdatapb.Charset, callback func(reply *binlogdatapb.BinlogTransaction) error) error { if fake.panics { panic(fmt.Errorf("test-triggered panic")) @@ -214,7 +214,7 @@ func testStreamTablesPanics(t *testing.T, bpc binlogplayer.Client) { } } -// HandlePanic is part of the the UpdateStream interface +// HandlePanic is part of the UpdateStream interface func (fake *FakeBinlogStreamer) HandlePanic(err *error) { if x := recover(); x != nil { *err = fmt.Errorf("Caught panic: %v", x) diff --git a/go/vt/proto/vtgate/vtgate.pb.go b/go/vt/proto/vtgate/vtgate.pb.go index d5bebcf6c71..ae204d1e8ac 100644 --- a/go/vt/proto/vtgate/vtgate.pb.go +++ b/go/vt/proto/vtgate/vtgate.pb.go @@ -2803,7 +2803,7 @@ var xxx_messageInfo_ResolveTransactionResponse proto.InternalMessageInfo // SplitQuery takes a "SELECT" query and generates a list of queries called // "query-parts". Each query-part consists of the original query with an // added WHERE clause that restricts the query-part to operate only on -// rows whose values in the the columns listed in the "split_column" field +// rows whose values in the columns listed in the "split_column" field // of the request (see below) are in a particular range. // // It is guaranteed that the set of rows obtained from diff --git a/go/vt/schemamanager/schemaswap/schema_swap.go b/go/vt/schemamanager/schemaswap/schema_swap.go index 6b39ccfb210..2e8e232b54f 100644 --- a/go/vt/schemamanager/schemaswap/schema_swap.go +++ b/go/vt/schemamanager/schemaswap/schema_swap.go @@ -459,7 +459,7 @@ func (schemaSwap *Swap) stopAllHealthWatchers() { } // initializeSwap starts the schema swap process. If there is already a schema swap process started -// the the method just picks up that. Otherwise it starts a new one and writes into the database that +// the method just picks up that. Otherwise it starts a new one and writes into the database that // the process was started. func (schemaSwap *Swap) initializeSwap() error { var waitGroup sync.WaitGroup diff --git a/go/vt/vtgate/planbuilder/insert.go b/go/vt/vtgate/planbuilder/insert.go index 7046dfcdee6..5bef6cde7e4 100644 --- a/go/vt/vtgate/planbuilder/insert.go +++ b/go/vt/vtgate/planbuilder/insert.go @@ -206,7 +206,7 @@ func modifyForAutoinc(ins *sqlparser.Insert, eins *engine.Insert) error { return nil } -// swapBindVariables swaps in bind variable names at the the specified +// 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) { diff --git a/go/vt/vtgate/planbuilder/ordered_aggregate.go b/go/vt/vtgate/planbuilder/ordered_aggregate.go index 905fe37bdce..30c4ec28317 100644 --- a/go/vt/vtgate/planbuilder/ordered_aggregate.go +++ b/go/vt/vtgate/planbuilder/ordered_aggregate.go @@ -272,7 +272,7 @@ func (oa *orderedAggregate) PushFilter(_ *primitiveBuilder, _ sqlparser.Expr, wh // be performed 'as they come'. In this respect, oa is the originator for // aggregate expressions like MAX, which will be added to symtab. The underlying // MAX sent to the route will not be added to symtab and will not be reachable by -// others. This functionality depends on the the PushOrderBy to request that +// others. This functionality depends on the PushOrderBy to request that // the rows be correctly ordered for a merge sort. func (oa *orderedAggregate) PushSelect(expr *sqlparser.AliasedExpr, origin builder) (rc *resultColumn, colnum int, err error) { if inner, ok := expr.Expr.(*sqlparser.FuncExpr); ok { diff --git a/go/vt/vtgate/scatter_conn.go b/go/vt/vtgate/scatter_conn.go index 8c42c0fa26c..da72bc52787 100644 --- a/go/vt/vtgate/scatter_conn.go +++ b/go/vt/vtgate/scatter_conn.go @@ -700,7 +700,7 @@ func injectShuffleQueryPartsRandomGenerator( return oldRandGen } -// shuffleQueryParts performs an in-place shuffle of the the given array. +// shuffleQueryParts performs an in-place shuffle of the given array. // The result is a psuedo-random permutation of the array chosen uniformally // from the space of all permutations. func shuffleQueryParts(splits []*vtgatepb.SplitQueryResponse_Part) { From a185df4329af63c55a6c13f98d984057c201e7e2 Mon Sep 17 00:00:00 2001 From: xichengliudui Date: Tue, 29 Jan 2019 10:17:43 -0500 Subject: [PATCH 103/115] Update log Signed-off-by: xichengliudui --- test/vtgate_buffer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/vtgate_buffer.py b/test/vtgate_buffer.py index 00bc7ea6c23..77104272140 100755 --- a/test/vtgate_buffer.py +++ b/test/vtgate_buffer.py @@ -172,7 +172,7 @@ def execute(self, cursor): if self.ignore_error_func and self.ignore_error_func(e): logging.debug('UPDATE %d failed during COMMIT. But we cannot buffer' - ' this error and and ignore it. err: %s', attempt, str(e)) + ' this error and ignore it. err: %s', attempt, str(e)) else: self._commit_errors += 1 if self._commit_errors > 1: From 76b1a6b6f95c7ae94e15e72369729de6ac091bcc Mon Sep 17 00:00:00 2001 From: xichengliudui Date: Tue, 29 Jan 2019 21:02:35 -0500 Subject: [PATCH 104/115] Update func Signed-off-by: xichengliudui --- go/vt/vtgate/executor_select_test.go | 4 ++-- go/vt/vtgate/executor_test.go | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/go/vt/vtgate/executor_select_test.go b/go/vt/vtgate/executor_select_test.go index 0499b0d60b6..b96c248aa7d 100644 --- a/go/vt/vtgate/executor_select_test.go +++ b/go/vt/vtgate/executor_select_test.go @@ -596,7 +596,7 @@ func TestSelectKeyRangeUnique(t *testing.T) { func TestSelectIN(t *testing.T) { executor, sbc1, sbc2, sbclookup := createExecutorEnv() - // Constant in IN is just a number, not a bind variable. + // Constant IN is just a number, not a bind variable. _, err := executorExec(executor, "select id from user where id in (1)", nil) if err != nil { t.Error(err) @@ -614,7 +614,7 @@ func TestSelectIN(t *testing.T) { t.Errorf("sbc2.Queries: %+v, want nil\n", sbc2.Queries) } - // Constant in IN is just a couple numbers, not bind variables. + // Constant IN is just a couple numbers, not bind variables. // They result in two different queries on two shards. sbc1.Queries = nil sbc2.Queries = nil diff --git a/go/vt/vtgate/executor_test.go b/go/vt/vtgate/executor_test.go index df2e6d1e335..af5e488cb0a 100644 --- a/go/vt/vtgate/executor_test.go +++ b/go/vt/vtgate/executor_test.go @@ -1841,7 +1841,7 @@ func TestExecutorUnrecognized(t *testing.T) { func TestExecutorMessageAckSharded(t *testing.T) { executor, sbc1, sbc2, _ := createExecutorEnv() - // Constant in IN is just a number, not a bind variable. + // Constant IN is just a number, not a bind variable. ids := []*querypb.Value{{ Type: sqltypes.VarChar, Value: []byte("1"), @@ -1860,7 +1860,7 @@ func TestExecutorMessageAckSharded(t *testing.T) { t.Errorf("sbc2.MessageIDs: %+v, want nil\n", sbc2.MessageIDs) } - // Constant in IN is just a couple numbers, not bind variables. + // Constant IN is just a couple numbers, not bind variables. // They result in two different MessageIDs on two shards. sbc1.MessageIDs = nil sbc2.MessageIDs = nil From d1be759ebceca1d96b9971804864ee3680b70290 Mon Sep 17 00:00:00 2001 From: xichengliudui Date: Tue, 29 Jan 2019 21:28:58 -0500 Subject: [PATCH 105/115] Update func and md and txt Signed-off-by: xichengliudui --- doc/Upgrading.md | 2 +- doc/V3HighLevelDesign.md | 2 +- go/vt/automation/wait_for_filtered_replication_task.go | 2 +- go/vt/throttler/max_replication_lag_module_test.go | 2 +- go/vt/vttablet/tabletserver/connpool/dbconn_test.go | 2 +- go/vt/workflow/parallel_runner.go | 2 +- test/TestingStrategy.md | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/doc/Upgrading.md b/doc/Upgrading.md index efc5f59361a..625c61aaafa 100644 --- a/doc/Upgrading.md +++ b/doc/Upgrading.md @@ -2,7 +2,7 @@ This document highlights things to look after when upgrading a Vitess production installation to a newer Vitess release. -Generally speaking, upgrading Vitess is a safe and and easy process because it is explicitly designed for it. This is because in YouTube we follow the practice of releasing new versions often (usually from the tip of the Git master branch). +Generally speaking, upgrading Vitess is a safe and easy process because it is explicitly designed for it. This is because in YouTube we follow the practice of releasing new versions often (usually from the tip of the Git master branch). ## Compatibility diff --git a/doc/V3HighLevelDesign.md b/doc/V3HighLevelDesign.md index 6e87e140043..b599f7e89ba 100644 --- a/doc/V3HighLevelDesign.md +++ b/doc/V3HighLevelDesign.md @@ -1311,7 +1311,7 @@ When two nodes are grouped, the current join condition becomes the root of the n * If it’s a JOIN, the new property is the more restrictive of the two nodes. So, if one of them is a Route, then the new node is also a Route. * For a LEFT JOIN, the new property is the same as the LHS node. -If the grouping conditions are not met, then the node remains a join node. In this case, we have to see if the ON clause conditions can be pushed down into the left and/or right nodes. By the fact that the current join is split into two, the ON clause cannot be be pushed as is. Instead, we use associativity rules to our benefit and merge the ON clause conditions into the WHERE clauses of the underlying nodes. The rules are the same as the ones described for a normal WHERE clause. +If the grouping conditions are not met, then the node remains a join node. In this case, we have to see if the ON clause conditions can be pushed down into the left and/or right nodes. By the fact that the current join is split into two, the ON clause cannot be pushed as is. Instead, we use associativity rules to our benefit and merge the ON clause conditions into the WHERE clauses of the underlying nodes. The rules are the same as the ones described for a normal WHERE clause. But left joins are slightly different, because the join condition is applied *to the RHS only*. Also, the condition cannot be further pushed into other nested left joins, because they will change the meaning of the statement. For example: diff --git a/go/vt/automation/wait_for_filtered_replication_task.go b/go/vt/automation/wait_for_filtered_replication_task.go index 63d910f4d5c..c820a75801c 100644 --- a/go/vt/automation/wait_for_filtered_replication_task.go +++ b/go/vt/automation/wait_for_filtered_replication_task.go @@ -23,7 +23,7 @@ import ( ) // WaitForFilteredReplicationTask runs vtctl WaitForFilteredReplication to block until the destination master -// (i.e. the receiving side of the filtered replication) has caught up up to max_delay with the source shard. +// (i.e. the receiving side of the filtered replication) has caught up to max_delay with the source shard. type WaitForFilteredReplicationTask struct { } diff --git a/go/vt/throttler/max_replication_lag_module_test.go b/go/vt/throttler/max_replication_lag_module_test.go index 0d57a68d3fc..e5537e64f24 100644 --- a/go/vt/throttler/max_replication_lag_module_test.go +++ b/go/vt/throttler/max_replication_lag_module_test.go @@ -283,7 +283,7 @@ func TestMaxReplicationLagModule_ReplicaUnderTest_Timeout(t *testing.T) { } // r2 as "replica under test" did not report its lag for too long. - // We'll ignore it from now and and let other replicas trigger rate changes. + // We'll ignore it from now and let other replicas trigger rate changes. // r1 @ 173s, 0s lag // time for r1 must be > 172s (70s + 40s + 62s) which is // (last rate change + test duration + max duration between increases). diff --git a/go/vt/vttablet/tabletserver/connpool/dbconn_test.go b/go/vt/vttablet/tabletserver/connpool/dbconn_test.go index ba7f25a2f2d..594f2d80d3a 100644 --- a/go/vt/vttablet/tabletserver/connpool/dbconn_test.go +++ b/go/vt/vttablet/tabletserver/connpool/dbconn_test.go @@ -102,7 +102,7 @@ func TestDBConnExec(t *testing.T) { startCounts = tabletenv.MySQLStats.Counts() - // Set the connection fail flag and and try again. + // Set the connection fail flag and try again. // This time the initial query fails as does the reconnect attempt. db.EnableConnFail() _, err = dbConn.Exec(ctx, sql, 1, false) diff --git a/go/vt/workflow/parallel_runner.go b/go/vt/workflow/parallel_runner.go index 847bfb8b868..da8d0e30479 100644 --- a/go/vt/workflow/parallel_runner.go +++ b/go/vt/workflow/parallel_runner.go @@ -138,7 +138,7 @@ func (p *ParallelRunner) Run() error { } select { case <-p.ctx.Done(): - // Break this run and return early. Do not try to to execute any subsequent tasks. + // Break this run and return early. Do not try to execute any subsequent tasks. log.Infof("Workflow is cancelled, remaining tasks will be aborted") return nil default: diff --git a/test/TestingStrategy.md b/test/TestingStrategy.md index 234fe9bd941..bc742ffcae5 100644 --- a/test/TestingStrategy.md +++ b/test/TestingStrategy.md @@ -36,7 +36,7 @@ Due to its constant nature, this is not an appropriate framework to test cluster These tests run more complicated setups, and take a lot more resources. They are meant to test end-to-end behaviors of the Vitess ecosystem, and complement the unit tests. -For instance, we test each RPC interaction independently (client to vtgate, vtgate to vttablet, vttablet to MySQL, see previous sections). But is is also good to have an end-to-end test that validates everything works together. +For instance, we test each RPC interaction independently (client to vtgate, vtgate to vttablet, vttablet to MySQL, see previous sections). But is also good to have an end-to-end test that validates everything works together. These tests almost always launch a topology service, a few mysqld instances, a few vttablets, a vtctld process, a few vtgates, ... They use the real production processes, and real replication. This setup is mandatory for properly testing re-sharding, cluster operations, ... They all however run on the same machine, so they might be limited by the environment. From 9ccdac91461a162bda10f3a646f4fc9e8f73bc2b Mon Sep 17 00:00:00 2001 From: xichengliudui Date: Tue, 29 Jan 2019 21:35:33 -0500 Subject: [PATCH 106/115] Update FAQ.md Signed-off-by: xichengliudui --- doc/FAQ.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/FAQ.md b/doc/FAQ.md index 1eddd677e0c..d34acbc4b0a 100644 --- a/doc/FAQ.md +++ b/doc/FAQ.md @@ -20,7 +20,7 @@ If no tablet type was specified, then VTGate chooses its default, which can be o Vitess supports different modes. In OLTP mode, the result size is typically limited to a preset number (10,000 rows by default). This limit can be adjusted based on your needs. -However, OLAP mode has no limit to the number of rows returned. In order to change to this mode, you may issue the following command command before executing your query: +However, OLAP mode has no limit to the number of rows returned. In order to change to this mode, you may issue the following command before executing your query: ``` set workload='olap' From 9dfff49449f30cde036274faa3f9a83077003d1e Mon Sep 17 00:00:00 2001 From: xichengliudui Date: Tue, 29 Jan 2019 21:41:56 -0500 Subject: [PATCH 107/115] update pull request Signed-off-by: xichengliudui --- go/vt/vtgate/executor_select_test.go | 2 +- go/vt/vtgate/executor_test.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/go/vt/vtgate/executor_select_test.go b/go/vt/vtgate/executor_select_test.go index b96c248aa7d..d781931a71c 100644 --- a/go/vt/vtgate/executor_select_test.go +++ b/go/vt/vtgate/executor_select_test.go @@ -614,7 +614,7 @@ func TestSelectIN(t *testing.T) { t.Errorf("sbc2.Queries: %+v, want nil\n", sbc2.Queries) } - // Constant IN is just a couple numbers, not bind variables. + // Constant in IN clause, not bind variables. // They result in two different queries on two shards. sbc1.Queries = nil sbc2.Queries = nil diff --git a/go/vt/vtgate/executor_test.go b/go/vt/vtgate/executor_test.go index af5e488cb0a..5e3349db10f 100644 --- a/go/vt/vtgate/executor_test.go +++ b/go/vt/vtgate/executor_test.go @@ -1841,7 +1841,7 @@ func TestExecutorUnrecognized(t *testing.T) { func TestExecutorMessageAckSharded(t *testing.T) { executor, sbc1, sbc2, _ := createExecutorEnv() - // Constant IN is just a number, not a bind variable. + // Constant in IN clause, not a bind variable. ids := []*querypb.Value{{ Type: sqltypes.VarChar, Value: []byte("1"), From 2b6dda483f9f983ae1cbd3b4d38b5895e7cda38e Mon Sep 17 00:00:00 2001 From: xichengliudui Date: Tue, 29 Jan 2019 21:47:33 -0500 Subject: [PATCH 108/115] update pull request Signed-off-by: xichengliudui --- go/vt/vtgate/executor_select_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/go/vt/vtgate/executor_select_test.go b/go/vt/vtgate/executor_select_test.go index d781931a71c..e83090f1eec 100644 --- a/go/vt/vtgate/executor_select_test.go +++ b/go/vt/vtgate/executor_select_test.go @@ -596,7 +596,7 @@ func TestSelectKeyRangeUnique(t *testing.T) { func TestSelectIN(t *testing.T) { executor, sbc1, sbc2, sbclookup := createExecutorEnv() - // Constant IN is just a number, not a bind variable. + // Constant in IN clause, not a bind variable. _, err := executorExec(executor, "select id from user where id in (1)", nil) if err != nil { t.Error(err) @@ -614,7 +614,7 @@ func TestSelectIN(t *testing.T) { t.Errorf("sbc2.Queries: %+v, want nil\n", sbc2.Queries) } - // Constant in IN clause, not bind variables. + // Constant IN is just a couple numbers, not bind variables. // They result in two different queries on two shards. sbc1.Queries = nil sbc2.Queries = nil From c68ed2dc09dd8e375c148bbc7a5de8348ebdb682 Mon Sep 17 00:00:00 2001 From: xichengliudui Date: Wed, 30 Jan 2019 03:03:36 -0500 Subject: [PATCH 109/115] Update the function name in the comment Signed-off-by: xichengliudui --- go/mysql/binlog_event.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/go/mysql/binlog_event.go b/go/mysql/binlog_event.go index 3e3909f78fa..dd0faa17c9d 100644 --- a/go/mysql/binlog_event.go +++ b/go/mysql/binlog_event.go @@ -70,13 +70,13 @@ type BinlogEvent interface { // RBR events. - // IsTableMapEvent returns true if this is a TABLE_MAP_EVENT. + // IsTableMap returns true if this is a TABLE_MAP_EVENT. IsTableMap() bool - // IsWriteRowsEvent returns true if this is a WRITE_ROWS_EVENT. + // IsWriteRows returns true if this is a WRITE_ROWS_EVENT. IsWriteRows() bool - // IsUpdateRowsEvent returns true if this is a UPDATE_ROWS_EVENT. + // IsUpdateRows returns true if this is a UPDATE_ROWS_EVENT. IsUpdateRows() bool - // IsDeleteRowsEvent returns true if this is a DELETE_ROWS_EVENT. + // IsDeleteRows returns true if this is a DELETE_ROWS_EVENT. IsDeleteRows() bool // Timestamp returns the timestamp from the event header. From 332bd415a5a59012c38419e6d2c22f3f7465f4c0 Mon Sep 17 00:00:00 2001 From: David Weitzman Date: Wed, 30 Jan 2019 01:14:21 -0800 Subject: [PATCH 110/115] Don't panic in binlogplayer if the vreplication table omits key range See https://github.com/vitessio/vitess/issues/4551 Signed-off-by: David Weitzman --- go/vt/binlog/binlogplayer/binlog_player.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/go/vt/binlog/binlogplayer/binlog_player.go b/go/vt/binlog/binlogplayer/binlog_player.go index b76fa52f42c..afcb0f065de 100644 --- a/go/vt/binlog/binlogplayer/binlog_player.go +++ b/go/vt/binlog/binlogplayer/binlog_player.go @@ -233,8 +233,8 @@ func (blp *BinlogPlayer) applyEvents(ctx context.Context) error { } else { log.Infof("BinlogPlayer client %v for keyrange '%v-%v' starting @ '%v', server: %v", blp.uid, - hex.EncodeToString(blp.keyRange.Start), - hex.EncodeToString(blp.keyRange.End), + hex.EncodeToString(blp.keyRange.GetStart()), + hex.EncodeToString(blp.keyRange.GetEnd()), blp.position, blp.tablet, ) From 20d7100c5aa37dd9418409c042eb4fb66592ef28 Mon Sep 17 00:00:00 2001 From: xichengliudui Date: Wed, 30 Jan 2019 06:49:48 -0500 Subject: [PATCH 111/115] update .go and .py files Signed-off-by: xichengliudui --- go/vt/vttablet/tabletserver/connpool/dbconn.go | 2 +- test/base_sharding.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/go/vt/vttablet/tabletserver/connpool/dbconn.go b/go/vt/vttablet/tabletserver/connpool/dbconn.go index 2a189676a44..abeef3e68b2 100644 --- a/go/vt/vttablet/tabletserver/connpool/dbconn.go +++ b/go/vt/vttablet/tabletserver/connpool/dbconn.go @@ -37,7 +37,7 @@ import ( querypb "vitess.io/vitess/go/vt/proto/query" ) -// BinlogFormat is used for for specifying the binlog format. +// BinlogFormat is used for specifying the binlog format. type BinlogFormat int // The following constants specify the possible binlog format values. diff --git a/test/base_sharding.py b/test/base_sharding.py index 3fcc92c1fb1..acc6d3a6f3d 100644 --- a/test/base_sharding.py +++ b/test/base_sharding.py @@ -383,7 +383,7 @@ def check_throttler_service_configuration(self, throttler_server, names): auto_log=True, trap_output=True) for name in names: # The max should be set and have a non-zero value. - # We test only the the first field 'target_replication_lag_sec'. + # We test only the first field 'target_replication_lag_sec'. self.assertIn('| %s | target_replication_lag_sec:12345 ' % (name), stdout) # protobuf omits fields with a zero value in the text output. self.assertNotIn('ignore_n_slowest_replicas', stdout) From dee0fe35d9075158e8f413c89391282c305b2ff7 Mon Sep 17 00:00:00 2001 From: Sugu Sougoumarane Date: Wed, 30 Jan 2019 05:39:04 -0800 Subject: [PATCH 112/115] vplayer: address review comments Signed-off-by: Sugu Sougoumarane --- go/vt/vttablet/tabletmanager/vreplication/vplayer.go | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/go/vt/vttablet/tabletmanager/vreplication/vplayer.go b/go/vt/vttablet/tabletmanager/vreplication/vplayer.go index f49c2b16583..fd4bc4746e9 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/vplayer.go +++ b/go/vt/vttablet/tabletmanager/vreplication/vplayer.go @@ -197,6 +197,15 @@ func (vp *vplayer) applyEvents(ctx context.Context, relay *relayLog) error { if err != nil { return err } + // Filtered replication often ends up receiving a large number of empty transactions. + // This is required because the player needs to know the latest position of the source. + // This allows it to stop at that position if requested. + // This position also needs to be saved, which will allow an external request + // to check if a required position has been reached. + // However, this leads to a large number of empty commits which not only slow + // down the replay, but also generate binlog bloat on the target. + // In order to mitigate this problem, empty transactions are saved at most + // once every idleTimeout. // This covers two situations: // 1. Fetch was idle for idleTimeout. // 2. We've been receiving empty events for longer than idleTimeout. From 16284e34f1b0fbc97b50f426aec5334f6c0d3a37 Mon Sep 17 00:00:00 2001 From: deepthi Date: Wed, 30 Jan 2019 14:41:55 -0800 Subject: [PATCH 113/115] Revert "change ClusterAlias in _vt.local_metadata to be keyspace/shard instead of keyspace.shard" This reverts commit 8ea39c31a45ff97385247b32535ca181b0e2e5e2. Signed-off-by: deepthi --- go/vt/vttablet/tabletmanager/restore.go | 2 +- test/backup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/go/vt/vttablet/tabletmanager/restore.go b/go/vt/vttablet/tabletmanager/restore.go index d61bfff2d85..55a3a57285d 100644 --- a/go/vt/vttablet/tabletmanager/restore.go +++ b/go/vt/vttablet/tabletmanager/restore.go @@ -189,7 +189,7 @@ func (agent *ActionAgent) getLocalMetadataValues(tabletType topodatapb.TabletTyp tablet := agent.Tablet() values := map[string]string{ "Alias": topoproto.TabletAliasString(tablet.Alias), - "ClusterAlias": fmt.Sprintf("%s/%s", tablet.Keyspace, tablet.Shard), + "ClusterAlias": fmt.Sprintf("%s.%s", tablet.Keyspace, tablet.Shard), "DataCenter": tablet.Alias.Cell, "PromotionRule": "must_not", } diff --git a/test/backup.py b/test/backup.py index 7de8b683851..78e8735fb9b 100755 --- a/test/backup.py +++ b/test/backup.py @@ -297,7 +297,7 @@ def _test_backup(self, tablet_type): for row in result: metadata[row[0]] = row[1] self.assertEqual(metadata['Alias'], 'test_nj-0000062346') - self.assertEqual(metadata['ClusterAlias'], 'test_keyspace/0') + self.assertEqual(metadata['ClusterAlias'], 'test_keyspace.0') self.assertEqual(metadata['DataCenter'], 'test_nj') if tablet_type == 'replica': self.assertEqual(metadata['PromotionRule'], 'neutral') From fd87a7ebe231f382fd240248a1d64ce65bc9ca98 Mon Sep 17 00:00:00 2001 From: deepthi Date: Wed, 30 Jan 2019 16:21:17 -0800 Subject: [PATCH 114/115] fix comments in tests Signed-off-by: deepthi --- go/vt/vtgate/executor_select_test.go | 4 ++-- go/vt/vtgate/executor_test.go | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/go/vt/vtgate/executor_select_test.go b/go/vt/vtgate/executor_select_test.go index e83090f1eec..997757330df 100644 --- a/go/vt/vtgate/executor_select_test.go +++ b/go/vt/vtgate/executor_select_test.go @@ -596,7 +596,7 @@ func TestSelectKeyRangeUnique(t *testing.T) { func TestSelectIN(t *testing.T) { executor, sbc1, sbc2, sbclookup := createExecutorEnv() - // Constant in IN clause, not a bind variable. + // Constant in IN clause is just a number, not a bind variable. _, err := executorExec(executor, "select id from user where id in (1)", nil) if err != nil { t.Error(err) @@ -614,7 +614,7 @@ func TestSelectIN(t *testing.T) { t.Errorf("sbc2.Queries: %+v, want nil\n", sbc2.Queries) } - // Constant IN is just a couple numbers, not bind variables. + // Constants in IN clause are just numbers, not bind variables. // They result in two different queries on two shards. sbc1.Queries = nil sbc2.Queries = nil diff --git a/go/vt/vtgate/executor_test.go b/go/vt/vtgate/executor_test.go index 5e3349db10f..8af068afeed 100644 --- a/go/vt/vtgate/executor_test.go +++ b/go/vt/vtgate/executor_test.go @@ -1841,7 +1841,7 @@ func TestExecutorUnrecognized(t *testing.T) { func TestExecutorMessageAckSharded(t *testing.T) { executor, sbc1, sbc2, _ := createExecutorEnv() - // Constant in IN clause, not a bind variable. + // Constant in IN clause is just a number, not a bind variable. ids := []*querypb.Value{{ Type: sqltypes.VarChar, Value: []byte("1"), @@ -1860,7 +1860,7 @@ func TestExecutorMessageAckSharded(t *testing.T) { t.Errorf("sbc2.MessageIDs: %+v, want nil\n", sbc2.MessageIDs) } - // Constant IN is just a couple numbers, not bind variables. + // Constants in IN clause are just numbers, not bind variables. // They result in two different MessageIDs on two shards. sbc1.MessageIDs = nil sbc2.MessageIDs = nil From 1c69d83d8d23303613cd042c18e5963a15ca8981 Mon Sep 17 00:00:00 2001 From: David Weitzman Date: Wed, 30 Jan 2019 17:15:04 -0800 Subject: [PATCH 115/115] Use a more specific "in use" message for the tx killer's rollback Someone who accidentally made a huge transaction asked what this error meant: "vttablet: rpc error: code = Aborted desc = transaction 1548379105148705713: in use: for rollback" It's less clear than the typical transaction killed error because the transaction was so large that rolling it back probably took some time. This diff changes the in use reason to "for tx killer rollback" which will hopefully be more clear. Signed-off-by: David Weitzman --- go/vt/vttablet/tabletserver/tx_pool.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go/vt/vttablet/tabletserver/tx_pool.go b/go/vt/vttablet/tabletserver/tx_pool.go index 44b07e125ef..0c47f93f33c 100644 --- a/go/vt/vttablet/tabletserver/tx_pool.go +++ b/go/vt/vttablet/tabletserver/tx_pool.go @@ -178,7 +178,7 @@ func (axp *TxPool) RollbackNonBusy(ctx context.Context) { func (axp *TxPool) transactionKiller() { defer tabletenv.LogError() - for _, v := range axp.activePool.GetOutdated(time.Duration(axp.Timeout()), "for rollback") { + for _, v := range axp.activePool.GetOutdated(time.Duration(axp.Timeout()), "for tx killer rollback") { conn := v.(*TxConnection) log.Warningf("killing transaction (exceeded timeout: %v): %s", axp.Timeout(), conn.Format(nil)) tabletenv.KillStats.Add("Transactions", 1)