From cf7fe76d303468bbfef0f044e47d4e4d523ae85f Mon Sep 17 00:00:00 2001 From: Sugu Sougoumarane Date: Tue, 2 Jul 2019 18:05:35 -0700 Subject: [PATCH 001/425] consistent lookup: handle insert ignore Fixes #4974 Insert ignore wasn't working correctly because the verify was using the normal transaction instead of the 'pre' transaction where the rows were actually created. This implementation changes the consistent lookup's Verify function to also use the 'pre' transaction always. There is another code path that gets used if the vindex is unowned. That will also cause a 'pre' transaction to be created. Without this change, the transaction would have been a normal one. This mildly affects the commit order, but there should be no material difference. Signed-off-by: Sugu Sougoumarane --- go/vt/vtgate/endtoend/lookup_test.go | 42 ++++++++++++++++++- go/vt/vtgate/vindexes/consistent_lookup.go | 3 +- .../vtgate/vindexes/consistent_lookup_test.go | 4 +- go/vt/vtgate/vindexes/lookup_internal.go | 16 +++---- 4 files changed, 54 insertions(+), 11 deletions(-) diff --git a/go/vt/vtgate/endtoend/lookup_test.go b/go/vt/vtgate/endtoend/lookup_test.go index 46d8e189aae..5adad26a1c4 100644 --- a/go/vt/vtgate/endtoend/lookup_test.go +++ b/go/vt/vtgate/endtoend/lookup_test.go @@ -220,7 +220,7 @@ func TestConsistentLookupMultiInsert(t *testing.T) { exec(t, conn, "delete from t1_id2_idx where id2=4") } -func TestHashLookupMultiInsertIgnore(t *testing.T) { +func TestLookupMultiInsertIgnore(t *testing.T) { ctx := context.Background() conn, err := mysql.Connect(ctx, &vtParams) if err != nil { @@ -260,6 +260,46 @@ func TestHashLookupMultiInsertIgnore(t *testing.T) { } } +func TestConsistentLookupMultiInsertIgnore(t *testing.T) { + ctx := context.Background() + conn, err := mysql.Connect(ctx, &vtParams) + if err != nil { + t.Fatal(err) + } + defer conn.Close() + // conn2 is for queries that target shards. + conn2, err := mysql.Connect(ctx, &vtParams) + if err != nil { + t.Fatal(err) + } + defer conn2.Close() + + // DB should start out clean + qr := exec(t, conn, "select count(*) from t1_id2_idx") + if got, want := fmt.Sprintf("%v", qr.Rows), "[[INT64(0)]]"; got != want { + t.Errorf("select:\n%v want\n%v", got, want) + } + qr = exec(t, conn, "select count(*) from t1") + if got, want := fmt.Sprintf("%v", qr.Rows), "[[INT64(0)]]"; got != want { + t.Errorf("select:\n%v want\n%v", got, want) + } + + // Try inserting a bunch of ids at once + exec(t, conn, "begin") + exec(t, conn, "insert ignore into t1(id1, id2) values(50,60), (30,40), (10,20)") + exec(t, conn, "commit") + + // Verify + qr = exec(t, conn, "select id1, id2 from t1 order by id1") + if got, want := fmt.Sprintf("%v", qr.Rows), "[[INT64(10) INT64(20)] [INT64(30) INT64(40)] [INT64(50) INT64(60)]]"; got != want { + t.Errorf("select:\n%v want\n%v", got, want) + } + qr = exec(t, conn, "select id2 from t1_id2_idx order by id2") + if got, want := fmt.Sprintf("%v", qr.Rows), "[[INT64(20)] [INT64(40)] [INT64(60)]]"; got != want { + t.Errorf("select:\n%v want\n%v", got, want) + } +} + func exec(t *testing.T, conn *mysql.Conn, query string) *sqltypes.Result { t.Helper() qr, err := conn.ExecuteFetch(query, 1000, true) diff --git a/go/vt/vtgate/vindexes/consistent_lookup.go b/go/vt/vtgate/vindexes/consistent_lookup.go index f040947a7f4..3432816db02 100644 --- a/go/vt/vtgate/vindexes/consistent_lookup.go +++ b/go/vt/vtgate/vindexes/consistent_lookup.go @@ -25,6 +25,7 @@ import ( "vitess.io/vitess/go/sqltypes" "vitess.io/vitess/go/vt/key" querypb "vitess.io/vitess/go/vt/proto/query" + "vitess.io/vitess/go/vt/proto/vtgate" vtgatepb "vitess.io/vitess/go/vt/proto/vtgate" vtrpcpb "vitess.io/vitess/go/vt/proto/vtrpc" "vitess.io/vitess/go/vt/sqlparser" @@ -205,7 +206,7 @@ func (lu *clCommon) IsFunctional() bool { // Verify returns true if ids maps to ksids. func (lu *clCommon) Verify(vcursor VCursor, ids []sqltypes.Value, ksids [][]byte) ([]bool, error) { - return lu.lkp.Verify(vcursor, ids, ksidsToValues(ksids)) + return lu.lkp.VerifyCustom(vcursor, ids, ksidsToValues(ksids), vtgate.CommitOrder_PRE) } // Create reserves the id by inserting it into the vindex table. diff --git a/go/vt/vtgate/vindexes/consistent_lookup_test.go b/go/vt/vtgate/vindexes/consistent_lookup_test.go index 51a4261402d..ee17dd88f8f 100644 --- a/go/vt/vtgate/vindexes/consistent_lookup_test.go +++ b/go/vt/vtgate/vindexes/consistent_lookup_test.go @@ -178,8 +178,8 @@ func TestConsistentLookupVerify(t *testing.T) { t.Error(err) } vc.verifyLog(t, []string{ - "Execute select fromc1 from t where fromc1 = :fromc1 and toc = :toc [{fromc1 1} {toc test1}] false", - "Execute select fromc1 from t where fromc1 = :fromc1 and toc = :toc [{fromc1 2} {toc test2}] false", + "ExecutePre select fromc1 from t where fromc1 = :fromc1 and toc = :toc [{fromc1 1} {toc test1}] false", + "ExecutePre select fromc1 from t where fromc1 = :fromc1 and toc = :toc [{fromc1 2} {toc test2}] false", }) // Test query fail. diff --git a/go/vt/vtgate/vindexes/lookup_internal.go b/go/vt/vtgate/vindexes/lookup_internal.go index 1eae733425e..6fc95eb4b8e 100644 --- a/go/vt/vtgate/vindexes/lookup_internal.go +++ b/go/vt/vtgate/vindexes/lookup_internal.go @@ -84,19 +84,21 @@ func (lkp *lookupInternal) Lookup(vcursor VCursor, ids []sqltypes.Value) ([]*sql // Verify returns true if ids map to values. func (lkp *lookupInternal) Verify(vcursor VCursor, ids, values []sqltypes.Value) ([]bool, error) { + co := vtgatepb.CommitOrder_NORMAL + if lkp.Autocommit { + co = vtgatepb.CommitOrder_AUTOCOMMIT + } + return lkp.VerifyCustom(vcursor, ids, values, co) +} + +func (lkp *lookupInternal) VerifyCustom(vcursor VCursor, ids, values []sqltypes.Value, co vtgatepb.CommitOrder) ([]bool, error) { out := make([]bool, len(ids)) for i, id := range ids { bindVars := map[string]*querypb.BindVariable{ lkp.FromColumns[0]: sqltypes.ValueBindVariable(id), lkp.To: sqltypes.ValueBindVariable(values[i]), } - var err error - var result *sqltypes.Result - co := vtgatepb.CommitOrder_NORMAL - if lkp.Autocommit { - co = vtgatepb.CommitOrder_AUTOCOMMIT - } - result, err = vcursor.Execute("VindexVerify", lkp.ver, bindVars, false /* isDML */, co) + result, err := vcursor.Execute("VindexVerify", lkp.ver, bindVars, false /* isDML */, co) if err != nil { return nil, fmt.Errorf("lookup.Verify: %v", err) } From df290b5d6d9be56c79867157377db9776808593f Mon Sep 17 00:00:00 2001 From: Morgan Tocker Date: Fri, 16 Aug 2019 09:18:43 -0600 Subject: [PATCH 002/425] go mod branch Signed-off-by: Morgan Tocker --- .travis.yml | 2 +- Makefile | 13 - bootstrap.sh | 81 +- build.env | 1 + dev.env | 3 - docker/bootstrap/Dockerfile.common | 9 - docker/test/run.sh | 2 +- go.mod | 77 ++ go.sum | 234 ++++ vendor/README.md | 19 - vendor/vendor.json | 2035 ---------------------------- 11 files changed, 317 insertions(+), 2159 deletions(-) create mode 100644 go.mod create mode 100644 go.sum delete mode 100644 vendor/README.md delete mode 100644 vendor/vendor.json diff --git a/.travis.yml b/.travis.yml index 312dfda58eb..326f289f60f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -17,7 +17,7 @@ # # Open TODOs: # - Re-add travis/check_make_proto.sh, ideally as part of test/config.json. -# - Add a presubmit which checks that vendor/vendor.json is the same as in the Docker image. This will prevent people from making changes to it without pushing new bootstrap Docker images. +# - Add a presubmit which checks that if bootstrap has changed, and docker image is out of date. # sudo is required because we run Docker in our builds. # See: https://docs.travis-ci.com/user/docker/ diff --git a/Makefile b/Makefile index f8ae541f167..bc80f423c7a 100644 --- a/Makefile +++ b/Makefile @@ -81,11 +81,6 @@ cleanall: # directories created by bootstrap.sh # - exclude vtdataroot and vthook as they may have data we want rm -rf ../../../../bin ../../../../dist ../../../../lib ../../../../pkg - # keep the vendor.json file but nothing else under the vendor directory as it's not actually part of the Vitess repo - rm -rf vendor/cloud.google.com vendor/github.com vendor/golang.org vendor/google.golang.org vendor/gopkg.in - # other stuff in the go hierarchy that is not under vendor/ - rm -rf ../../../golang.org ../../../honnef.co - rm -rf ../../../github.com/golang ../../../github.com/kardianos ../../../github.com/kisielk # Remind people to run bootstrap.sh again echo "Please run bootstrap.sh again to setup your environment" @@ -117,13 +112,6 @@ java_test: go install ./go/cmd/vtgateclienttest ./go/cmd/vtcombo mvn -f java/pom.xml clean verify -# TODO(mberlin): Remove the manual copy once govendor supports a way to -# install vendor'd programs: https://github.com/kardianos/govendor/issues/117 -install_protoc-gen-go: - mkdir -p $${GOPATH}/src/github.com/golang/ - cp -a vendor/github.com/golang/protobuf $${GOPATH}/src/github.com/golang/ - go install github.com/golang/protobuf/protoc-gen-go - # Find protoc compiler. # NOTE: We are *not* using the "protoc" binary (as suggested by the grpc Go # quickstart for example). Instead, we run "protoc" via the Python @@ -268,7 +256,6 @@ rebalance_tests: # Release a version. # This will generate a tar.gz file into the releases folder with the current source -# as well as the vendored libs. release: docker_base @if [ -z "$VERSION" ]; then \ echo "Set the env var VERSION with the release version"; exit 1;\ diff --git a/bootstrap.sh b/bootstrap.sh index 29bf96e4522..3cefd65f6c0 100755 --- a/bootstrap.sh +++ b/bootstrap.sh @@ -19,8 +19,6 @@ # Outline of this file. # 0. Initialization and helper methods. # 1. Installation of dependencies. -# 2. Installation of Go tools and vendored Go dependencies. -# 3. Detection of installed MySQL and setting MYSQL_FLAVOR. BUILD_TESTS=${BUILD_TESTS:-1} BUILD_PYTHON=${BUILD_PYTHON:-1} @@ -54,7 +52,9 @@ ln -sf "$VTTOP/misc/git/commit-msg" "$VTTOP/.git/hooks/commit-msg" (cd "$VTTOP" && git config core.hooksPath "$VTTOP/.git/hooks") -# Set up the proper GOPATH for go get below. +# This is required for VIRTUALENV +# Used by Python below + if [ "$BUILD_TESTS" == 1 ] ; then source ./dev.env else @@ -288,81 +288,6 @@ if [ "$BUILD_PYTHON" == 1 ] ; then install_dep "chromedriver" "73.0.3683.20" "$VTROOT/dist/chromedriver" install_chromedriver fi - -# -# 2. Installation of Go tools and vendored Go dependencies. -# - - -# Install third-party Go tools used as part of the development workflow. -# -# DO NOT ADD LIBRARY DEPENDENCIES HERE. Instead use govendor as described below. -# -# Note: We explicitly do not vendor the tools below because a) we want to stay -# on their latest version and b) it's easier to "go install" them this way. -gotools=" \ - github.com/golang/mock/mockgen \ - github.com/kardianos/govendor \ - golang.org/x/lint/golint \ - golang.org/x/tools/cmd/cover \ - golang.org/x/tools/cmd/goimports \ - golang.org/x/tools/cmd/goyacc \ -" -echo "Installing dev tools with 'go get'..." -# shellcheck disable=SC2086 -go get -u $gotools || fail "Failed to download some Go tools with 'go get'. Please re-run bootstrap.sh in case of transient errors." - -# Download dependencies that are version-pinned via govendor. -# -# To add a new dependency, run: -# govendor fetch -# -# Existing dependencies can be updated to the latest version with 'fetch' as well. -# -# Then: -# git add vendor/vendor.json -# git commit -# -# See https://github.com/kardianos/govendor for more options. -echo "Updating govendor dependencies..." -govendor sync || fail "Failed to download/update dependencies with govendor. Please re-run bootstrap.sh in case of transient errors." - - -# -# 3. Detection of installed MySQL and setting MYSQL_FLAVOR. -# - - -# find mysql and prepare to use libmysqlclient - -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" | "MySQL80") - 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" | "MariaDB103") - 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 - if [ "$BUILD_PYTHON" == 1 ] ; then PYTHONPATH='' $PIP install mysql-connector-python fi diff --git a/build.env b/build.env index a9d46a99b92..896524887d2 100644 --- a/build.env +++ b/build.env @@ -37,3 +37,4 @@ if [[ "$VTTOP" == "${VTTOP/\/src\/vitess.io\/vitess/}" ]]; then echo "WARNING: VTTOP($VTTOP) does not contain src/vitess.io/vitess" fi +GO111MODULE=on diff --git a/dev.env b/dev.env index ca7bc608721..4619c9f9efa 100644 --- a/dev.env +++ b/dev.env @@ -98,9 +98,6 @@ fi PKG_CONFIG_PATH=$(prepend_path "$PKG_CONFIG_PATH" "$VTROOT/lib") export PKG_CONFIG_PATH -GOPATH=$(prepend_path "$GOPATH" "$VTROOT") -export GOPATH - # Useful aliases. Remove if inconvenient. alias gt='cd $GOTOP' alias pt='cd $PYTOP' diff --git a/docker/bootstrap/Dockerfile.common b/docker/bootstrap/Dockerfile.common index 2dc72b8de40..7acfee18d8d 100644 --- a/docker/bootstrap/Dockerfile.common +++ b/docker/bootstrap/Dockerfile.common @@ -46,9 +46,7 @@ ENV VTDATAROOT $VTROOT/vtdataroot ENV VTPORTSTART 15000 ENV PYTHONPATH $VTROOT/dist/grpc/usr/local/lib/python2.7/site-packages:$VTROOT/dist/py-mock-1.0.1/lib/python2.7/site-packages:$VTROOT/py-vtdb:$VTROOT/dist/selenium/lib/python2.7/site-packages ENV GOBIN $VTROOT/bin -ENV GOPATH $VTROOT ENV PATH $VTROOT/bin:$VTROOT/dist/maven/bin:$VTROOT/dist/chromedriver:$PATH -ENV VT_MYSQL_ROOT /usr ENV PKG_CONFIG_PATH $VTROOT/lib ENV USER vitess @@ -58,13 +56,6 @@ COPY config /vt/src/vitess.io/vitess/config COPY third_party /vt/src/vitess.io/vitess/third_party COPY tools /vt/src/vitess.io/vitess/tools COPY travis /vt/src/vitess.io/vitess/travis -COPY vendor/vendor.json /vt/src/vitess.io/vitess/vendor/ - -# Download vendored Go dependencies -RUN cd /vt/src/vitess.io/vitess && \ - go get -u github.com/kardianos/govendor && \ - govendor sync && \ - rm -rf /vt/.cache # Create vitess user RUN groupadd -r vitess && useradd -r -g vitess vitess && \ diff --git a/docker/test/run.sh b/docker/test/run.sh index dc59fad26f4..599e9dbd716 100755 --- a/docker/test/run.sh +++ b/docker/test/run.sh @@ -181,7 +181,7 @@ run_bootstrap_cmd="if [[ \$(diff -w vendor/vendor.json /tmp/src/vendor/vendor.js # Copy bootstrap.sh if it changed run_bootstrap_cmd=$(append_cmd "$run_bootstrap_cmd" "if [[ \$(diff -w bootstrap.sh /tmp/src/bootstrap.sh) ]]; then cp -f /tmp/src/bootstrap.sh .; bootstrap=1; fi") # run bootstrap.sh if necessary -run_bootstrap_cmd=$(append_cmd "$run_bootstrap_cmd" "if [[ -n \$bootstrap ]]; then ./bootstrap.sh; else if [[ -n \$sync_vendor ]]; then govendor sync; fi; fi") +run_bootstrap_cmd=$(append_cmd "$run_bootstrap_cmd" "if [[ -n \$bootstrap ]]; then ./bootstrap.sh; fi") copy_src_cmd=$(append_cmd "$copy_src_cmd" "$run_bootstrap_cmd") # Construct the command we will actually run. diff --git a/go.mod b/go.mod new file mode 100644 index 00000000000..2ce411d025c --- /dev/null +++ b/go.mod @@ -0,0 +1,77 @@ +module vitess.io/vitess + +go 1.12 + +require ( + cloud.google.com/go v0.43.0 + github.com/aws/aws-sdk-go v0.0.0-20180223184012-ebef4262e06a + github.com/beorn7/perks v0.0.0-20160229213445-3ac7bf7a47d1 + github.com/coreos/etcd v0.0.0-20170626015032-703663d1f6ed + github.com/coreos/go-etcd v2.0.0+incompatible + github.com/davecgh/go-spew v0.0.0-20151105211317-5215b55f46b2 + github.com/ghodss/yaml v0.0.0-20161207003320-04f313413ffd + github.com/go-ini/ini v1.12.0 + github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b + github.com/golang/mock v1.3.1 + github.com/golang/protobuf v1.3.2 + github.com/golang/snappy v0.0.0-20170215233205-553a64147049 + github.com/google/go-cmp v0.3.0 + github.com/googleapis/gax-go v1.0.3 + github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e + github.com/gorilla/websocket v0.0.0-20160912153041-2d1e4548da23 + github.com/grpc-ecosystem/go-grpc-middleware v0.0.0-20190118093823-f849b5445de4 + github.com/grpc-ecosystem/go-grpc-prometheus v0.0.0-20180418170936-39de4380c2e0 + github.com/grpc-ecosystem/grpc-gateway v0.0.0-20161128002007-199c40a060d1 + github.com/hashicorp/consul v1.4.0 + github.com/hashicorp/go-cleanhttp v0.0.0-20160407174126-ad28ea4487f0 + github.com/hashicorp/go-rootcerts v0.0.0-20160503143440-6bb64b370b90 + github.com/hashicorp/golang-lru v0.5.3 + github.com/hashicorp/serf v0.0.0-20161207011743-d3a67ab21bc8 + github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8 + github.com/jtolds/gls v4.2.1+incompatible + github.com/klauspost/compress v0.0.0-20180801095237-b50017755d44 + github.com/klauspost/cpuid v1.2.0 + github.com/klauspost/crc32 v1.2.0 + github.com/klauspost/pgzip v1.2.0 + github.com/mattn/go-runewidth v0.0.1 + github.com/matttproud/golang_protobuf_extensions v1.0.1 + github.com/minio/minio-go v0.0.0-20190131015406-c8a261de75c1 + github.com/mitchellh/go-homedir v1.1.0 + github.com/mitchellh/mapstructure v1.1.2 + github.com/olekukonko/tablewriter v0.0.0-20160115111002-cca8bbc07984 + github.com/opentracing-contrib/go-grpc v0.0.0-20180928155321-4b5a12d3ff02 + github.com/opentracing/opentracing-go v1.0.2 + github.com/pborman/uuid v0.0.0-20160824210600-b984ec7fa9ff + github.com/pkg/errors v0.0.0-20190109061628-ffb6e22f0193 + github.com/pmezard/go-difflib v1.0.0 + github.com/prometheus/client_golang v0.0.0-20180319131721-d49167c4b9f3 + github.com/prometheus/client_model v0.0.0-20150212101744-fa8ad6fec335 + github.com/prometheus/common v0.0.0-20160607094339-3a184ff7dfd4 + github.com/prometheus/procfs v0.0.0-20160411190841-abf152e5f3e9 + github.com/satori/go.uuid v0.0.0-20160713180306-0aa62d5ddceb + github.com/sergi/go-diff v0.0.0-20170409071739-feef008d51ad + github.com/smartystreets/assertions v0.0.0-20190116191733-b6c0e53d7304 + github.com/smartystreets/goconvey v0.0.0-20181108003508-044398e4856c + github.com/stretchr/testify v0.0.0-20160524234229-8d64eb7173c7 + github.com/tchap/go-patricia v0.0.0-20160729071656-dd168db6051b + github.com/uber/jaeger-client-go v2.16.0+incompatible + github.com/uber/jaeger-lib v2.0.0+incompatible + github.com/yudai/gojsondiff v0.0.0-20170626131258-081cda2ee950 + github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82 + github.com/z-division/go-zookeeper v0.0.0-20190128072838-6d7457066b9b + go.opencensus.io v0.22.0 + golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5 + golang.org/x/net v0.0.0-20190620200207-3b0461eec859 + golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 + golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0 + golang.org/x/text v0.3.2 + golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 + google.golang.org/api v0.7.0 + google.golang.org/appengine v1.6.1 + google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64 + google.golang.org/grpc v1.21.1 + gopkg.in/asn1-ber.v1 v1.0.0-20150924051756-4e86f4367175 + gopkg.in/ini.v1 v1.41.0 + gopkg.in/ldap.v2 v2.5.0 + gopkg.in/yaml.v2 v2.0.0-20160928153709-a5b47d31c556 +) diff --git a/go.sum b/go.sum new file mode 100644 index 00000000000..30092e25680 --- /dev/null +++ b/go.sum @@ -0,0 +1,234 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= +cloud.google.com/go v0.43.0 h1:banaiRPAM8kUVYneOSkhgcDsLzEvL25FinuiSZaH/2w= +cloud.google.com/go v0.43.0/go.mod h1:BOSR3VbTLkk6FDC/TcffxP4NF/FFBGA5ku+jvKOP7pg= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/aws/aws-sdk-go v0.0.0-20180223184012-ebef4262e06a h1:Ed33uJE74ksDaYfdY72gK7Cg//o2FgsqlqUfBW079T8= +github.com/aws/aws-sdk-go v0.0.0-20180223184012-ebef4262e06a/go.mod h1:ZRmQr0FajVIyZ4ZzBYKG5P3ZqPz9IHG41ZoMu1ADI3k= +github.com/beorn7/perks v0.0.0-20160229213445-3ac7bf7a47d1 h1:OnJHjoVbY69GG4gclp0ngXfywigLhR6rrgUxmxQRWO4= +github.com/beorn7/perks v0.0.0-20160229213445-3ac7bf7a47d1/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/coreos/etcd v0.0.0-20170626015032-703663d1f6ed h1:uycR38QXnpc8YtCCTsNnQfeq6nPQ55F4ld6/WtGAIlM= +github.com/coreos/etcd v0.0.0-20170626015032-703663d1f6ed/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= +github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= +github.com/davecgh/go-spew v0.0.0-20151105211317-5215b55f46b2/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/ghodss/yaml v0.0.0-20161207003320-04f313413ffd/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/go-ini/ini v1.12.0 h1:K324HQuOp7fYRWIW84d39Y7MqlH/0JU9fImSXUJ2TWk= +github.com/go-ini/ini v1.12.0/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E= +github.com/golang/mock v1.0.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.3.1 h1:qGJ6qTW+x6xX/my+8YUVl4WNpX9B7+/l2tRsHGZ7f2s= +github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/snappy v0.0.0-20170215233205-553a64147049 h1:K9KHZbXKpGydfDN0aZrsoHpLJlZsBrGMFWbgLDGnPZk= +github.com/golang/snappy v0.0.0-20170215233205-553a64147049/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/go-cmp v0.0.0-20190801213755-6d8cafd2f64f/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/googleapis/gax-go v1.0.3 h1:9dMLqhaibYONnDRcnHdUs9P8Mw64jLlZTYlDe3leBtQ= +github.com/googleapis/gax-go v1.0.3/go.mod h1:QyXYajJFdARxGzjwUfbDFIse7Spkw81SJ4LrBJXtlQ8= +github.com/googleapis/gax-go/v2 v2.0.2/go.mod h1:LLvjysVCY1JZeum8Z6l8qUty8fiNwE08qbEPm1M08qg= +github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= +github.com/googleapis/gax-go/v2 v2.0.5 h1:sjZBwGj9Jlw33ImPtvFviGYvseOtDM7hkSKB7+Tv3SM= +github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= +github.com/gopherjs/gopherjs v0.0.0-20160612211759-a727a4a1dd2f/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gorilla/websocket v0.0.0-20160912153041-2d1e4548da23 h1:NqeYYy/q+eU5bXzLrVTFSEMp5/VFwp3eJ6nkDsi7wos= +github.com/gorilla/websocket v0.0.0-20160912153041-2d1e4548da23/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/grpc-ecosystem/go-grpc-middleware v0.0.0-20190118093823-f849b5445de4 h1:Wx79jmadGrMPEWZHn8Rogt6aMcpwbHMoO3MeehDJAGs= +github.com/grpc-ecosystem/go-grpc-middleware v0.0.0-20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= +github.com/grpc-ecosystem/go-grpc-prometheus v0.0.0-20180418170936-39de4380c2e0 h1:6kldmIygVGmNHiCpXorySJ3/iICRLC20KBy2h1OzCUw= +github.com/grpc-ecosystem/go-grpc-prometheus v0.0.0-20180418170936-39de4380c2e0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= +github.com/grpc-ecosystem/grpc-gateway v0.0.0-20161128002007-199c40a060d1/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw= +github.com/hashicorp/consul v1.4.0 h1:PQTW4xCuAExEiSbhrsFsikzbW5gVBoi74BjUvYFyKHw= +github.com/hashicorp/consul v1.4.0/go.mod h1:mFrjN1mfidgJfYP1xrJCF+AfRhr6Eaqhb2+sfyn/OOI= +github.com/hashicorp/go-cleanhttp v0.0.0-20160407174126-ad28ea4487f0 h1:2l0haPDqCzZEO160UR5DSrrl8RWptFCoxFsSbRLJBaI= +github.com/hashicorp/go-cleanhttp v0.0.0-20160407174126-ad28ea4487f0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-rootcerts v0.0.0-20160503143440-6bb64b370b90 h1:VBj0QYQ0u2MCJzBfeYXGexnAl17GsH1yidnoxCqqD9E= +github.com/hashicorp/go-rootcerts v0.0.0-20160503143440-6bb64b370b90/go.mod h1:o4zcYY1e0GEZI6eSEr+43QDYmuGglw1qSO6qdHUHCgg= +github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.3 h1:YPkqC67at8FYaadspW/6uE0COsBxS2656RLEr8Bppgk= +github.com/hashicorp/golang-lru v0.5.3/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= +github.com/hashicorp/serf v0.0.0-20161207011743-d3a67ab21bc8 h1:Vd9tjFEMH3X1AMV1BzVAZRwnjy9MoxOsOl+1pqpCVQs= +github.com/hashicorp/serf v0.0.0-20161207011743-d3a67ab21bc8/go.mod h1:h/Ru6tmZazX7WO/GDmwdpS975F019L4t5ng5IgwbNrE= +github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8 h1:12VvqtR6Aowv3l/EQUlocDHW2Cp4G9WJVH7uyH8QFJE= +github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= +github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= +github.com/jtolds/gls v4.2.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/klauspost/compress v0.0.0-20180801095237-b50017755d44 h1:uDhun+KVSncSm1UeN8A4llsQ6E+xAIBmhh816Q2zeOk= +github.com/klauspost/compress v0.0.0-20180801095237-b50017755d44/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= +github.com/klauspost/cpuid v1.2.0 h1:NMpwD2G9JSFOE1/TJjGSo5zG7Yb2bTe7eq1jH+irmeE= +github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= +github.com/klauspost/crc32 v1.2.0 h1:0VuyqOCruD33/lJ/ojXNvzVyl8Zr5zdTmj9l9qLZ86I= +github.com/klauspost/crc32 v1.2.0/go.mod h1:+ZoRqAPRLkC4NPOvfYeR5KNOrY6TD+/sAC3HXPZgDYg= +github.com/klauspost/pgzip v1.2.0 h1:SPtjjC68wy5g65KwQS4TcYtm6x/O8H4jSxtKZfhN4s0= +github.com/klauspost/pgzip v1.2.0/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs= +github.com/mattn/go-runewidth v0.0.1 h1:+EiaBVXhogb1Klb4tRJ7hYnuGK6PkKOZlK04D/GMOqk= +github.com/mattn/go-runewidth v0.0.1/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= +github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= +github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/minio/minio-go v0.0.0-20190131015406-c8a261de75c1 h1:jw16EimP5oAEM/2wt+SiEUov/YDyTCTDuPtIKgQIvk0= +github.com/minio/minio-go v0.0.0-20190131015406-c8a261de75c1/go.mod h1:vuvdOZLJuf5HmJAJrKV64MmozrSsk+or0PB5dzdfspg= +github.com/mitchellh/go-homedir v0.0.0-20161203194507-b8bc1bf76747/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= +github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE= +github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/olekukonko/tablewriter v0.0.0-20160115111002-cca8bbc07984 h1:c9gVtoY8wPlhJIN2V2I1V+Fn9UcXM8mDG8IHv/1c3r8= +github.com/olekukonko/tablewriter v0.0.0-20160115111002-cca8bbc07984/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= +github.com/opentracing-contrib/go-grpc v0.0.0-20180928155321-4b5a12d3ff02 h1:0R5mDLI66Qw13qN80TRz85zthQ2nf2+uDyiV23w6c3Q= +github.com/opentracing-contrib/go-grpc v0.0.0-20180928155321-4b5a12d3ff02/go.mod h1:JNdpVEzCpXBgIiv4ds+TzhN1hrtxq6ClLrTlT9OQRSc= +github.com/opentracing/opentracing-go v1.0.2 h1:3jA2P6O1F9UOrWVpwrIo17pu01KWvNWg4X946/Y5Zwg= +github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/pborman/uuid v0.0.0-20160824210600-b984ec7fa9ff h1:pTiDfW+iOjIxjZeCm88gKn/AmR09UGZYZdqif2yPRrM= +github.com/pborman/uuid v0.0.0-20160824210600-b984ec7fa9ff/go.mod h1:VyrYX9gd7irzKovcSS6BIIEwPRkP2Wm2m9ufcdFSJ34= +github.com/pkg/errors v0.0.0-20190109061628-ffb6e22f0193 h1:G+3hOJb+jr4ruKVe4WWvC0wXvPmVuKyb/tTlOyjAisU= +github.com/pkg/errors v0.0.0-20190109061628-ffb6e22f0193/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_golang v0.0.0-20180319131721-d49167c4b9f3 h1:IlkKMWpcBADSCBBkzSukNTFPfhEV+3VyGN4b0Wc2IUA= +github.com/prometheus/client_golang v0.0.0-20180319131721-d49167c4b9f3/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_model v0.0.0-20150212101744-fa8ad6fec335 h1:0E/5GnGmzoDCtmzTycjGDWW33H0UBmAhR0h+FC8hWLs= +github.com/prometheus/client_model v0.0.0-20150212101744-fa8ad6fec335/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/common v0.0.0-20160607094339-3a184ff7dfd4 h1:mj5hNmXtX1FzwvmFDf11SH19Q6paZCVkpa1R2UBLapQ= +github.com/prometheus/common v0.0.0-20160607094339-3a184ff7dfd4/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= +github.com/prometheus/procfs v0.0.0-20160411190841-abf152e5f3e9 h1:ex32PG6WhE5zviWS08vcXTwX2IkaH9zpeYZZvrmj3/U= +github.com/prometheus/procfs v0.0.0-20160411190841-abf152e5f3e9/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/satori/go.uuid v0.0.0-20160713180306-0aa62d5ddceb/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= +github.com/sergi/go-diff v0.0.0-20170409071739-feef008d51ad/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= +github.com/smartystreets/assertions v0.0.0-20160422195351-40711f774818/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= +github.com/smartystreets/assertions v0.0.0-20190116191733-b6c0e53d7304/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= +github.com/smartystreets/goconvey v0.0.0-20160523153147-c53abc99456f/go.mod h1:XDJAKZRPZ1CvBcN2aX5YOUTYGHki24fSF0Iv48Ibg0s= +github.com/smartystreets/goconvey v0.0.0-20181108003508-044398e4856c/go.mod h1:XDJAKZRPZ1CvBcN2aX5YOUTYGHki24fSF0Iv48Ibg0s= +github.com/stretchr/testify v0.0.0-20160524234229-8d64eb7173c7/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/tchap/go-patricia v0.0.0-20160729071656-dd168db6051b h1:i3lm+BZX5fAaH95wJavMgsSYU95LhSxdNCMa8nLv2gk= +github.com/tchap/go-patricia v0.0.0-20160729071656-dd168db6051b/go.mod h1:bmLyhP68RS6kStMGxByiQ23RP/odRBOTVjwp2cDyi6I= +github.com/uber/jaeger-client-go v2.16.0+incompatible h1:Q2Pp6v3QYiocMxomCaJuwQGFt7E53bPYqEgug/AoBtY= +github.com/uber/jaeger-client-go v2.16.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= +github.com/uber/jaeger-lib v2.0.0+incompatible h1:iMSCV0rmXEogjNWPh2D0xk9YVKvrtGoHJNe9ebLu/pw= +github.com/uber/jaeger-lib v2.0.0+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U= +github.com/yudai/gojsondiff v0.0.0-20170626131258-081cda2ee950/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg= +github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM= +github.com/z-division/go-zookeeper v0.0.0-20190128072838-6d7457066b9b h1:Itr7GbuXoM1PK/eCeNNia4Qd3ib9IgX9g9SpXgo8BwQ= +github.com/z-division/go-zookeeper v0.0.0-20190128072838-6d7457066b9b/go.mod h1:JNALoWa+nCXR8SmgLluHcBNVJgyejzpKPZk9pX2yXXE= +go.opencensus.io v0.0.0-20190713072201-b4a14686f0a9/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= +go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= +go.opencensus.io v0.22.0 h1:C9hSCOW830chIVkdja34wa6Ky+IzWllkUinR+BtRZd4= +go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= +golang.org/x/crypto v0.0.0-20190128193316-c7b33c32a30b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190131182504-b8fe1690c613/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5 h1:58fnuSXlxZmFdJyvtTFVmVhcMLU6v5fEb/ok4wyqtNU= +golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190221220918-438050ddec5e/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= +golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= +golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190206173232-65e2d4e15006/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859 h1:R/3boaszxrf1GEUWTVDzSKVwLmSJpwZ1yqXm8j0v2QI= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0= +golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190124100055-b90733256f2e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190204203706-41f3e6584952/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0 h1:HyfiK1WMnHj5FXFXatD+Qs1A/xC2Run6RzeW1SyHxpc= +golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/text v0.0.0-20181030141323-6f44c5a2ea40/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/time v0.0.0-20161028155119-f51c12702a4d/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 h1:SvFZT6jyqRaOeXpc5h/JSfZenJ2O330aBsf7JfSUXmQ= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= +google.golang.org/api v0.7.0 h1:9sdfJOzWlkqPltHAuzT2Cp+yrBeY1KRVYgms8soxMwM= +google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190716160619-c506a9f90610/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64 h1:iKtrH9Y8mcbADOP0YFaEMth7OfuHY9xHOwNj4znpM1A= +google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +google.golang.org/grpc v1.21.1 h1:j6XxA85m/6txkUCHvzlV5f+HBNl/1r5cZ2A/3IEFOO8= +google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +gopkg.in/asn1-ber.v1 v1.0.0-20150924051756-4e86f4367175 h1:nn6Zav2sOQHCFJHEspya8KqxhFwKci30UxHy3HXPTyQ= +gopkg.in/asn1-ber.v1 v1.0.0-20150924051756-4e86f4367175/go.mod h1:cuepJuh7vyXfUyUwEgHQXw849cJrilpS5NeIjOWESAw= +gopkg.in/ini.v1 v1.41.0 h1:Ka3ViY6gNYSKiVy71zXBEqKplnV35ImDLVG+8uoIklE= +gopkg.in/ini.v1 v1.41.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/ldap.v2 v2.5.0 h1:1rO3ojzsHUk+gq4ZYhC4Pg+EzWaaKIV8+DJwExS5/QQ= +gopkg.in/ldap.v2 v2.5.0/go.mod h1:oI0cpe/D7HRtBQl8aTg+ZmzFUAvu4lsv3eLXMLGFxWk= +gopkg.in/yaml.v2 v2.0.0-20160928153709-a5b47d31c556/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= +honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= diff --git a/vendor/README.md b/vendor/README.md deleted file mode 100644 index 50fefa8917d..00000000000 --- a/vendor/README.md +++ /dev/null @@ -1,19 +0,0 @@ -# govendor - -We manage the file `vendor.json` through the [govendor](https://github.com/kardianos/govendor) command. - -## Add a new dependency - -```sh -govendor fetch @ -``` - -If available, please always use a release version. If not, you can omit `@`. - -## Update a dependency - -Example gRPC: - -```sh -govendor fetch google.golang.org/grpc/...@v1.11.2 -``` diff --git a/vendor/vendor.json b/vendor/vendor.json deleted file mode 100644 index fa174afbc19..00000000000 --- a/vendor/vendor.json +++ /dev/null @@ -1,2035 +0,0 @@ -{ - "comment": "", - "ignore": "appengine test", - "package": [ - { - "checksumSHA1": "b1KgRkWqz0RmrEBK6IJ8kOJva6w=", - "path": "cloud.google.com/go/compute/metadata", - "revision": "cdaaf98f9226c39dc162b8e55083b2fbc67b4674", - "revisionTime": "2019-07-12T19:01:42Z", - "version": "v0.43.0", - "versionExact": "v0.43.0" - }, - { - "checksumSHA1": "+S/9jBntS1iHZwxkR64vsy97Gh8=", - "path": "cloud.google.com/go/iam", - "revision": "cdaaf98f9226c39dc162b8e55083b2fbc67b4674", - "revisionTime": "2019-07-12T19:01:42Z", - "version": "v0.43.0", - "versionExact": "v0.43.0" - }, - { - "checksumSHA1": "JfGXEtr79UaxukcL05IERkjYm/g=", - "path": "cloud.google.com/go/internal", - "revision": "cdaaf98f9226c39dc162b8e55083b2fbc67b4674", - "revisionTime": "2019-07-12T19:01:42Z", - "version": "v0.43.0", - "versionExact": "v0.43.0" - }, - { - "checksumSHA1": "wQ4uGuRwMb24vG16pPQDOOCPkFo=", - "path": "cloud.google.com/go/internal/optional", - "revision": "cdaaf98f9226c39dc162b8e55083b2fbc67b4674", - "revisionTime": "2019-07-12T19:01:42Z", - "version": "v0.43.0", - "versionExact": "v0.43.0" - }, - { - "checksumSHA1": "5Jz6j0verpzBzMwIEZai+EbV6Ls=", - "path": "cloud.google.com/go/internal/testutil", - "revision": "cdaaf98f9226c39dc162b8e55083b2fbc67b4674", - "revisionTime": "2019-07-12T19:01:42Z", - "version": "v0.43.0", - "versionExact": "v0.43.0" - }, - { - "checksumSHA1": "jHOn3QLqvr1luNqyOg24/BXLrsM=", - "path": "cloud.google.com/go/internal/trace", - "revision": "cdaaf98f9226c39dc162b8e55083b2fbc67b4674", - "revisionTime": "2019-07-12T19:01:42Z", - "version": "v0.43.0", - "versionExact": "v0.43.0" - }, - { - "checksumSHA1": "FSifvUBJjm4OsSU5rp5s5+bqvN0=", - "path": "cloud.google.com/go/internal/version", - "revision": "cdaaf98f9226c39dc162b8e55083b2fbc67b4674", - "revisionTime": "2019-07-12T19:01:42Z", - "version": "v0.43.0", - "versionExact": "v0.43.0" - }, - { - "checksumSHA1": "tof7cbQFVwy2rN/iJfKXDKUf4rs=", - "path": "cloud.google.com/go/storage", - "revision": "cdaaf98f9226c39dc162b8e55083b2fbc67b4674", - "revisionTime": "2019-07-12T19:01:42Z", - "version": "v0.43.0", - "versionExact": "v0.43.0" - }, - { - "checksumSHA1": "t5pzf8AGtuCmECrPlJM9oAky+dk=", - "path": "github.com/aws/aws-sdk-go/aws", - "revision": "f07b33eb84960583bbb72889ae0f98d300e107fe", - "revisionTime": "2018-02-23T17:39:05Z" - }, - { - "checksumSHA1": "Y9W+4GimK4Fuxq+vyIskVYFRnX4=", - "path": "github.com/aws/aws-sdk-go/aws/awserr", - "revision": "f07b33eb84960583bbb72889ae0f98d300e107fe", - "revisionTime": "2018-02-23T17:39:05Z" - }, - { - "checksumSHA1": "yyYr41HZ1Aq0hWc3J5ijXwYEcac=", - "path": "github.com/aws/aws-sdk-go/aws/awsutil", - "revision": "f07b33eb84960583bbb72889ae0f98d300e107fe", - "revisionTime": "2018-02-23T17:39:05Z" - }, - { - "checksumSHA1": "wGf8GkrbZe2VFXOo28K0jq68A+g=", - "path": "github.com/aws/aws-sdk-go/aws/client", - "revision": "f07b33eb84960583bbb72889ae0f98d300e107fe", - "revisionTime": "2018-02-23T17:39:05Z" - }, - { - "checksumSHA1": "ieAJ+Cvp/PKv1LpUEnUXpc3OI6E=", - "path": "github.com/aws/aws-sdk-go/aws/client/metadata", - "revision": "f07b33eb84960583bbb72889ae0f98d300e107fe", - "revisionTime": "2018-02-23T17:39:05Z" - }, - { - "checksumSHA1": "U2W3pMTHfONS6R/QP/Zg18+89TQ=", - "path": "github.com/aws/aws-sdk-go/aws/corehandlers", - "revision": "f07b33eb84960583bbb72889ae0f98d300e107fe", - "revisionTime": "2018-02-23T17:39:05Z" - }, - { - "checksumSHA1": "Y+cPwQL0dZMyqp3wI+KJWmA9KQ8=", - "path": "github.com/aws/aws-sdk-go/aws/credentials", - "revision": "f07b33eb84960583bbb72889ae0f98d300e107fe", - "revisionTime": "2018-02-23T17:39:05Z" - }, - { - "checksumSHA1": "u3GOAJLmdvbuNUeUEcZSEAOeL/0=", - "path": "github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds", - "revision": "f07b33eb84960583bbb72889ae0f98d300e107fe", - "revisionTime": "2018-02-23T17:39:05Z" - }, - { - "checksumSHA1": "NUJUTWlc1sV8b7WjfiYc4JZbXl0=", - "path": "github.com/aws/aws-sdk-go/aws/credentials/endpointcreds", - "revision": "ebef4262e06a772a06a80aaee8e952c2514e1606", - "revisionTime": "2018-02-23T18:40:12Z" - }, - { - "checksumSHA1": "JEYqmF83O5n5bHkupAzA6STm0no=", - "path": "github.com/aws/aws-sdk-go/aws/credentials/stscreds", - "revision": "ebef4262e06a772a06a80aaee8e952c2514e1606", - "revisionTime": "2018-02-23T18:40:12Z" - }, - { - "checksumSHA1": "OnU/n7R33oYXiB4SAGd5pK7I0Bs=", - "path": "github.com/aws/aws-sdk-go/aws/defaults", - "revision": "f07b33eb84960583bbb72889ae0f98d300e107fe", - "revisionTime": "2018-02-23T17:39:05Z" - }, - { - "checksumSHA1": "pDnK93CqjQ4ROSW8Y/RuHXjv52M=", - "path": "github.com/aws/aws-sdk-go/aws/ec2metadata", - "revision": "f07b33eb84960583bbb72889ae0f98d300e107fe", - "revisionTime": "2018-02-23T17:39:05Z" - }, - { - "checksumSHA1": "dUurC4Vz9SYV3ZSSP+aM+DH4F14=", - "path": "github.com/aws/aws-sdk-go/aws/endpoints", - "revision": "ebef4262e06a772a06a80aaee8e952c2514e1606", - "revisionTime": "2018-02-23T18:40:12Z" - }, - { - "checksumSHA1": "FpjCPoRNsVKM1hOg9EpC7jn5pRI=", - "path": "github.com/aws/aws-sdk-go/aws/request", - "revision": "f07b33eb84960583bbb72889ae0f98d300e107fe", - "revisionTime": "2018-02-23T17:39:05Z" - }, - { - "checksumSHA1": "DIn7B+oP++/nw603OB95fmupzu8=", - "path": "github.com/aws/aws-sdk-go/aws/session", - "revision": "f07b33eb84960583bbb72889ae0f98d300e107fe", - "revisionTime": "2018-02-23T17:39:05Z" - }, - { - "checksumSHA1": "4gwCpxPnVQISJGF/skyWpzzxFAc=", - "path": "github.com/aws/aws-sdk-go/aws/signer/v4", - "revision": "ebef4262e06a772a06a80aaee8e952c2514e1606", - "revisionTime": "2018-02-23T18:40:12Z" - }, - { - "checksumSHA1": "MxSiiCoPpY1mCRjyEFClUu3e14w=", - "path": "github.com/aws/aws-sdk-go/awstesting", - "revision": "f07b33eb84960583bbb72889ae0f98d300e107fe", - "revisionTime": "2018-02-23T17:39:05Z" - }, - { - "checksumSHA1": "iOAj9X968hli6R2oCTjFVQPH5Ug=", - "path": "github.com/aws/aws-sdk-go/awstesting/mock", - "revision": "f07b33eb84960583bbb72889ae0f98d300e107fe", - "revisionTime": "2018-02-23T17:39:05Z" - }, - { - "checksumSHA1": "MIp5H1niMhCZFAwYsjJx9NxmHIc=", - "path": "github.com/aws/aws-sdk-go/awstesting/unit", - "revision": "f07b33eb84960583bbb72889ae0f98d300e107fe", - "revisionTime": "2018-02-23T17:39:05Z" - }, - { - "checksumSHA1": "MYLldFRnsZh21TfCkgkXCT3maPU=", - "path": "github.com/aws/aws-sdk-go/internal/sdkrand", - "revision": "ebef4262e06a772a06a80aaee8e952c2514e1606", - "revisionTime": "2018-02-23T18:40:12Z" - }, - { - "checksumSHA1": "04ypv4x12l4q0TksA1zEVsmgpvw=", - "path": "github.com/aws/aws-sdk-go/internal/shareddefaults", - "revision": "ebef4262e06a772a06a80aaee8e952c2514e1606", - "revisionTime": "2018-02-23T18:40:12Z" - }, - { - "checksumSHA1": "sgft7A0lRCVD7QBogydg46lr3NM=", - "path": "github.com/aws/aws-sdk-go/private/endpoints", - "revision": "2e1a49c71fb7d8f6b7e8cca2259ed9b68d9b97ce", - "revisionTime": "2016-06-13T21:28:44Z" - }, - { - "checksumSHA1": "NStHCXEvYqG72GknZyv1jaKaeH0=", - "path": "github.com/aws/aws-sdk-go/private/protocol", - "revision": "f07b33eb84960583bbb72889ae0f98d300e107fe", - "revisionTime": "2018-02-23T17:39:05Z" - }, - { - "checksumSHA1": "1QmQ3FqV37w0Zi44qv8pA1GeR0A=", - "path": "github.com/aws/aws-sdk-go/private/protocol/ec2query", - "revision": "f07b33eb84960583bbb72889ae0f98d300e107fe", - "revisionTime": "2018-02-23T17:39:05Z" - }, - { - "checksumSHA1": "yHfT5DTbeCLs4NE2Rgnqrhe15ls=", - "path": "github.com/aws/aws-sdk-go/private/protocol/json/jsonutil", - "revision": "f07b33eb84960583bbb72889ae0f98d300e107fe", - "revisionTime": "2018-02-23T17:39:05Z" - }, - { - "checksumSHA1": "R00RL5jJXRYq1iiK1+PGvMfvXyM=", - "path": "github.com/aws/aws-sdk-go/private/protocol/jsonrpc", - "revision": "f07b33eb84960583bbb72889ae0f98d300e107fe", - "revisionTime": "2018-02-23T17:39:05Z" - }, - { - "checksumSHA1": "ZqY5RWavBLWTo6j9xqdyBEaNFRk=", - "path": "github.com/aws/aws-sdk-go/private/protocol/query", - "revision": "f07b33eb84960583bbb72889ae0f98d300e107fe", - "revisionTime": "2018-02-23T17:39:05Z" - }, - { - "checksumSHA1": "9V1PvtFQ9MObZTc3sa86WcuOtOU=", - "path": "github.com/aws/aws-sdk-go/private/protocol/query/queryutil", - "revision": "f07b33eb84960583bbb72889ae0f98d300e107fe", - "revisionTime": "2018-02-23T17:39:05Z" - }, - { - "checksumSHA1": "pkeoOfZpHRvFG/AOZeTf0lwtsFg=", - "path": "github.com/aws/aws-sdk-go/private/protocol/rest", - "revision": "f07b33eb84960583bbb72889ae0f98d300e107fe", - "revisionTime": "2018-02-23T17:39:05Z" - }, - { - "checksumSHA1": "Rpu8KBtHZgvhkwHxUfaky+qW+G4=", - "path": "github.com/aws/aws-sdk-go/private/protocol/restjson", - "revision": "f07b33eb84960583bbb72889ae0f98d300e107fe", - "revisionTime": "2018-02-23T17:39:05Z" - }, - { - "checksumSHA1": "ODo+ko8D6unAxZuN1jGzMcN4QCc=", - "path": "github.com/aws/aws-sdk-go/private/protocol/restxml", - "revision": "f07b33eb84960583bbb72889ae0f98d300e107fe", - "revisionTime": "2018-02-23T17:39:05Z" - }, - { - "checksumSHA1": "0qYPUga28aQVkxZgBR3Z86AbGUQ=", - "path": "github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil", - "revision": "f07b33eb84960583bbb72889ae0f98d300e107fe", - "revisionTime": "2018-02-23T17:39:05Z" - }, - { - "checksumSHA1": "wZbHPxkyYsr5h6GW5OVh9qIMZR8=", - "path": "github.com/aws/aws-sdk-go/private/signer/v4", - "revision": "2e1a49c71fb7d8f6b7e8cca2259ed9b68d9b97ce", - "revisionTime": "2016-06-13T21:28:44Z" - }, - { - "checksumSHA1": "01b4hmyUzoReoOyEDylDinWBSdA=", - "path": "github.com/aws/aws-sdk-go/private/util", - "revision": "f07b33eb84960583bbb72889ae0f98d300e107fe", - "revisionTime": "2018-02-23T17:39:05Z" - }, - { - "checksumSHA1": "Eo9yODN5U99BK0pMzoqnBm7PCrY=", - "path": "github.com/aws/aws-sdk-go/private/waiter", - "revision": "2e1a49c71fb7d8f6b7e8cca2259ed9b68d9b97ce", - "revisionTime": "2016-06-13T21:28:44Z" - }, - { - "checksumSHA1": "0nPnGWlegQG7bn/iIIfjJFoljyU=", - "path": "github.com/aws/aws-sdk-go/service/cloudfront", - "revision": "f07b33eb84960583bbb72889ae0f98d300e107fe", - "revisionTime": "2018-02-23T17:39:05Z" - }, - { - "checksumSHA1": "8JiVrxMjFSdBOfVWCy1QU+JzB08=", - "path": "github.com/aws/aws-sdk-go/service/dynamodb", - "revision": "f07b33eb84960583bbb72889ae0f98d300e107fe", - "revisionTime": "2018-02-23T17:39:05Z" - }, - { - "checksumSHA1": "/I6I2nR59isqKtSpEnTfLRWZ8Mc=", - "path": "github.com/aws/aws-sdk-go/service/dynamodb/dynamodbattribute", - "revision": "f07b33eb84960583bbb72889ae0f98d300e107fe", - "revisionTime": "2018-02-23T17:39:05Z" - }, - { - "checksumSHA1": "roq8pXva49Jq13gh5n6iiZ+LXBc=", - "path": "github.com/aws/aws-sdk-go/service/ec2", - "revision": "f07b33eb84960583bbb72889ae0f98d300e107fe", - "revisionTime": "2018-02-23T17:39:05Z" - }, - { - "checksumSHA1": "SZ7yLDZ6RvMhpWe0Goyem64kgyA=", - "path": "github.com/aws/aws-sdk-go/service/elastictranscoder", - "revision": "f07b33eb84960583bbb72889ae0f98d300e107fe", - "revisionTime": "2018-02-23T17:39:05Z" - }, - { - "checksumSHA1": "DfzNze8B3ME2tV3TtXP7eQXUjD0=", - "path": "github.com/aws/aws-sdk-go/service/kinesis", - "revision": "f07b33eb84960583bbb72889ae0f98d300e107fe", - "revisionTime": "2018-02-23T17:39:05Z" - }, - { - "checksumSHA1": "KPRDrVt4hrFBmJ2le8HebKphfjE=", - "path": "github.com/aws/aws-sdk-go/service/route53", - "revision": "f07b33eb84960583bbb72889ae0f98d300e107fe", - "revisionTime": "2018-02-23T17:39:05Z" - }, - { - "checksumSHA1": "fXQn3V0ZRBZpTXUEHl4/yOjR4mQ=", - "path": "github.com/aws/aws-sdk-go/service/s3", - "revision": "f07b33eb84960583bbb72889ae0f98d300e107fe", - "revisionTime": "2018-02-23T17:39:05Z" - }, - { - "checksumSHA1": "ZP6QI0X9BNKk8o1p3AyLfjabS20=", - "path": "github.com/aws/aws-sdk-go/service/s3/s3iface", - "revision": "f07b33eb84960583bbb72889ae0f98d300e107fe", - "revisionTime": "2018-02-23T17:39:05Z" - }, - { - "checksumSHA1": "N+U01iPy566cfzEY+dliw/fYEdE=", - "path": "github.com/aws/aws-sdk-go/service/s3/s3manager", - "revision": "f07b33eb84960583bbb72889ae0f98d300e107fe", - "revisionTime": "2018-02-23T17:39:05Z" - }, - { - "checksumSHA1": "x7HCNPJnQi+4P6FKpBTY1hm3m6o=", - "path": "github.com/aws/aws-sdk-go/service/sts", - "revision": "ebef4262e06a772a06a80aaee8e952c2514e1606", - "revisionTime": "2018-02-23T18:40:12Z" - }, - { - "checksumSHA1": "4QnLdmB1kG3N+KlDd1N+G9TWAGQ=", - "path": "github.com/beorn7/perks/quantile", - "revision": "3ac7bf7a47d159a033b107610db8a1b6575507a4", - "revisionTime": "2016-02-29T21:34:45Z" - }, - { - "checksumSHA1": "7BC2/27NId9xaPDB5w3nWN2mn9A=", - "path": "github.com/coreos/etcd/auth/authpb", - "revision": "703663d1f6ed070ab83b01386f0b023091c5e016", - "revisionTime": "2017-06-26T01:50:32Z" - }, - { - "checksumSHA1": "MljqP0GJ8+FxtIDFxmCtkmt+Auo=", - "path": "github.com/coreos/etcd/clientv3", - "revision": "703663d1f6ed070ab83b01386f0b023091c5e016", - "revisionTime": "2017-06-26T01:50:32Z" - }, - { - "checksumSHA1": "PnBbh5xS4/RtluD+Vatock/WZts=", - "path": "github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes", - "revision": "703663d1f6ed070ab83b01386f0b023091c5e016", - "revisionTime": "2017-06-26T01:50:32Z" - }, - { - "checksumSHA1": "7xBiCrhCPYjgh2TAsZP9hBLzDgA=", - "path": "github.com/coreos/etcd/etcdserver/etcdserverpb", - "revision": "703663d1f6ed070ab83b01386f0b023091c5e016", - "revisionTime": "2017-06-26T01:50:32Z" - }, - { - "checksumSHA1": "JAkX9DfIBrSe0vUa07xl5cikxVQ=", - "path": "github.com/coreos/etcd/mvcc/mvccpb", - "revision": "703663d1f6ed070ab83b01386f0b023091c5e016", - "revisionTime": "2017-06-26T01:50:32Z" - }, - { - "checksumSHA1": "Ggn+h7g45yWJ9QWZtZ3Vu2qevcQ=", - "path": "github.com/coreos/go-etcd/etcd", - "revision": "f02171fbd43c7b9b53ce8679b03235a1ef3c7b12", - "revisionTime": "2015-04-16T20:55:17Z", - "version": "=v2.0.0", - "versionExact": "v2.0.0" - }, - { - "checksumSHA1": "5rPfda8jFccr3A6heL+JAmi9K9g=", - "path": "github.com/davecgh/go-spew/spew", - "revision": "5215b55f46b2b919f50a1df0eaa5886afe4e3b3d", - "revisionTime": "2015-11-05T21:09:06Z" - }, - { - "checksumSHA1": "a2yC46a1qsJomgY6rb+FkTFiqmE=", - "path": "github.com/davecgh/go-spew/spew/testdata", - "revision": "5215b55f46b2b919f50a1df0eaa5886afe4e3b3d", - "revisionTime": "2015-11-05T21:09:06Z" - }, - { - "checksumSHA1": "muGVyM8mY3/gcap6kr4Ib3F5Xn4=", - "path": "github.com/ghodss/yaml", - "revision": "04f313413ffd65ce25f2541bfd2b2ceec5c0908c", - "revisionTime": "2016-12-07T00:33:20Z" - }, - { - "checksumSHA1": "FfdxnQ4CZVJJvG4BC1fWavgperI=", - "path": "github.com/go-ini/ini", - "revision": "72ba3e6b9e6b87e0c74c9a7a4dc86e8dd8ba4355", - "revisionTime": "2016-06-01T19:11:21Z" - }, - { - "checksumSHA1": "HmbftipkadrLlCfzzVQ+iFHbl6g=", - "path": "github.com/golang/glog", - "revision": "23def4e6c14b4da8ac2ed8007337bc5eb5007998", - "revisionTime": "2016-01-25T20:49:56Z" - }, - { - "checksumSHA1": "M3BUApw7nNipzKvYbHSpxqE04FY=", - "path": "github.com/golang/mock/gomock", - "revision": "13f360950a79f5864a972c786a10a50e44b69541", - "revisionTime": "2017-07-22T14:45:13Z", - "version": "v1.0.0", - "versionExact": "v1.0.0" - }, - { - "checksumSHA1": "ks9nCA68MefWDMUIjIF/zJwpTuw=", - "path": "github.com/golang/mock/gomock/mock_matcher", - "revision": "bd3c8e81be01eef76d4b503f5e687d2d1354d2d9", - "revisionTime": "2016-01-21T18:51:14Z" - }, - { - "checksumSHA1": "MgBmXopyMTVxPYgWfLrSsMIFE84=", - "path": "github.com/golang/protobuf/jsonpb", - "revision": "6c65a5562fc06764971b7c5d05c76c75e84bdbf7", - "revisionTime": "2019-07-01T18:22:01Z", - "version": "v1.3.2", - "versionExact": "v1.3.2" - }, - { - "checksumSHA1": "78dam9bgu36kpCiQPsy5ni3s1cs=", - "path": "github.com/golang/protobuf/jsonpb/jsonpb_test_proto", - "revision": "6c65a5562fc06764971b7c5d05c76c75e84bdbf7", - "revisionTime": "2019-07-01T18:22:01Z", - "version": "v1.3.2", - "versionExact": "v1.3.2" - }, - { - "checksumSHA1": "CGj8VcI/CpzxaNqlqpEVM7qElD4=", - "path": "github.com/golang/protobuf/proto", - "revision": "6c65a5562fc06764971b7c5d05c76c75e84bdbf7", - "revisionTime": "2019-07-01T18:22:01Z", - "version": "v1.3.2", - "versionExact": "v1.3.2" - }, - { - "checksumSHA1": "cQvjaQ6YsQ2s/QOmJeSGMjbyLhU=", - "path": "github.com/golang/protobuf/proto/proto3_proto", - "revision": "6c65a5562fc06764971b7c5d05c76c75e84bdbf7", - "revisionTime": "2019-07-01T18:22:01Z", - "version": "v1.3.2", - "versionExact": "v1.3.2" - }, - { - "checksumSHA1": "Ap3fxoENMwxwOM77e56TlCVt+7o=", - "path": "github.com/golang/protobuf/proto/test_proto", - "revision": "6c65a5562fc06764971b7c5d05c76c75e84bdbf7", - "revisionTime": "2019-07-01T18:22:01Z", - "version": "v1.3.2", - "versionExact": "v1.3.2" - }, - { - "checksumSHA1": "A0DxiyxXV4u8PmwUwlVkQ2CKyiQ=", - "path": "github.com/golang/protobuf/proto/testdata", - "revision": "1909bc2f63dc92bb931deace8b8312c4db72d12f", - "revisionTime": "2017-08-08T02:16:21Z", - "version": "v1.3.2", - "versionExact": "v1.3.2" - }, - { - "checksumSHA1": "iqWBA0GWNr+cwAdF2KVy1eq9mlU=", - "path": "github.com/golang/protobuf/protoc-gen-go", - "revision": "6c65a5562fc06764971b7c5d05c76c75e84bdbf7", - "revisionTime": "2019-07-01T18:22:01Z", - "version": "v1.3.2", - "versionExact": "v1.3.2" - }, - { - "checksumSHA1": "WOkXetG3AqJnfVVuqTJvdukcHps=", - "path": "github.com/golang/protobuf/protoc-gen-go/descriptor", - "revision": "6c65a5562fc06764971b7c5d05c76c75e84bdbf7", - "revisionTime": "2019-07-01T18:22:01Z", - "version": "v1.3.2", - "versionExact": "v1.3.2" - }, - { - "checksumSHA1": "dqkZJ8o1Hj3gbN30RyZ7G3CxhfU=", - "path": "github.com/golang/protobuf/protoc-gen-go/generator", - "revision": "6c65a5562fc06764971b7c5d05c76c75e84bdbf7", - "revisionTime": "2019-07-01T18:22:01Z", - "version": "v1.3.2", - "versionExact": "v1.3.2" - }, - { - "checksumSHA1": "uY4dEtqaAe5gsU8gbpCI1JgEIII=", - "path": "github.com/golang/protobuf/protoc-gen-go/generator/internal/remap", - "revision": "6c65a5562fc06764971b7c5d05c76c75e84bdbf7", - "revisionTime": "2019-07-01T18:22:01Z", - "version": "v1.3.2", - "versionExact": "v1.3.2" - }, - { - "checksumSHA1": "fejUXovU2abLTPX7kU8fzwT8Kmo=", - "path": "github.com/golang/protobuf/protoc-gen-go/grpc", - "revision": "6c65a5562fc06764971b7c5d05c76c75e84bdbf7", - "revisionTime": "2019-07-01T18:22:01Z", - "version": "v1.3.2", - "versionExact": "v1.3.2" - }, - { - "checksumSHA1": "h4PLbJDYnRmcUuf56USJ5K3xJOg=", - "path": "github.com/golang/protobuf/protoc-gen-go/plugin", - "revision": "6c65a5562fc06764971b7c5d05c76c75e84bdbf7", - "revisionTime": "2019-07-01T18:22:01Z", - "version": "v1.3.2", - "versionExact": "v1.3.2" - }, - { - "checksumSHA1": "/vLtyN6HK5twSZIFerD199YTmjk=", - "path": "github.com/golang/protobuf/protoc-gen-go/testdata/multi", - "revision": "2bc9827a78f95c6665b5fe0abd1fd66b496ae2d8", - "revisionTime": "2016-11-03T22:44:32Z" - }, - { - "checksumSHA1": "aEiR2m3NGaMGTbUW5P+w5gKFyc8=", - "path": "github.com/golang/protobuf/ptypes", - "revision": "6c65a5562fc06764971b7c5d05c76c75e84bdbf7", - "revisionTime": "2019-07-01T18:22:01Z", - "version": "v1.3.2", - "versionExact": "v1.3.2" - }, - { - "checksumSHA1": "2/Xg4L9IVGQRJB8zCELZx7/Z4HU=", - "path": "github.com/golang/protobuf/ptypes/any", - "revision": "6c65a5562fc06764971b7c5d05c76c75e84bdbf7", - "revisionTime": "2019-07-01T18:22:01Z", - "version": "v1.3.2", - "versionExact": "v1.3.2" - }, - { - "checksumSHA1": "RE9rLveNHapyMKQC8p10tbkUE9w=", - "path": "github.com/golang/protobuf/ptypes/duration", - "revision": "6c65a5562fc06764971b7c5d05c76c75e84bdbf7", - "revisionTime": "2019-07-01T18:22:01Z", - "version": "v1.3.2", - "versionExact": "v1.3.2" - }, - { - "checksumSHA1": "RT/PGRMtH/yBCbIJfZftaz5yc3M=", - "path": "github.com/golang/protobuf/ptypes/struct", - "revision": "6c65a5562fc06764971b7c5d05c76c75e84bdbf7", - "revisionTime": "2019-07-01T18:22:01Z", - "version": "v1.3.2", - "versionExact": "v1.3.2" - }, - { - "checksumSHA1": "seEwY2xETpK9yHJ9+bHqkLZ0VMU=", - "path": "github.com/golang/protobuf/ptypes/timestamp", - "revision": "6c65a5562fc06764971b7c5d05c76c75e84bdbf7", - "revisionTime": "2019-07-01T18:22:01Z", - "version": "v1.3.2", - "versionExact": "v1.3.2" - }, - { - "checksumSHA1": "KlQCb83HC090bojw4ofNDxn2nho=", - "path": "github.com/golang/protobuf/ptypes/wrappers", - "revision": "6c65a5562fc06764971b7c5d05c76c75e84bdbf7", - "revisionTime": "2019-07-01T18:22:01Z", - "version": "v1.3.2", - "versionExact": "v1.3.2" - }, - { - "checksumSHA1": "p/8vSviYF91gFflhrt5vkyksroo=", - "path": "github.com/golang/snappy", - "revision": "553a641470496b2327abcac10b36396bd98e45c9", - "revisionTime": "2017-02-15T23:32:05Z" - }, - { - "checksumSHA1": "HYqCnwjrsx9RYvx7uA0EkzLGnxA=", - "path": "github.com/google/go-cmp/cmp", - "revision": "6d8cafd2f64fe3cd66b7530d95df066b00bdd777", - "revisionTime": "2019-08-01T21:37:55Z" - }, - { - "checksumSHA1": "FUnTgtE5i3f8asIvicGkJSFlrts=", - "path": "github.com/google/go-cmp/cmp/internal/diff", - "revision": "6d8cafd2f64fe3cd66b7530d95df066b00bdd777", - "revisionTime": "2019-08-01T21:37:55Z" - }, - { - "checksumSHA1": "nR8EJ8i8lqxxmtLPnXI7WlYANiE=", - "path": "github.com/google/go-cmp/cmp/internal/flags", - "revision": "6d8cafd2f64fe3cd66b7530d95df066b00bdd777", - "revisionTime": "2019-08-01T21:37:55Z" - }, - { - "checksumSHA1": "0pcLJsUQUaBdPXM5LuL9uFeuETs=", - "path": "github.com/google/go-cmp/cmp/internal/function", - "revision": "6d8cafd2f64fe3cd66b7530d95df066b00bdd777", - "revisionTime": "2019-08-01T21:37:55Z" - }, - { - "checksumSHA1": "ZNN1jJuHnBCpo21lSv25VvkotIM=", - "path": "github.com/google/go-cmp/cmp/internal/value", - "revision": "6d8cafd2f64fe3cd66b7530d95df066b00bdd777", - "revisionTime": "2019-08-01T21:37:55Z" - }, - { - "checksumSHA1": "V/53BpqgOkSDZCX6snQCAkdO2fM=", - "path": "github.com/googleapis/gax-go", - "revision": "da06d194a00e19ce00d9011a13931c3f6f6887c7", - "revisionTime": "2016-11-07T00:24:06Z" - }, - { - "checksumSHA1": "WZoHSeTnVjnPIX2+U1Otst5MUKw=", - "path": "github.com/googleapis/gax-go/v2", - "revision": "bd5b16380fd03dc758d11cef74ba2e3bc8b0e8c2", - "revisionTime": "2019-05-13T18:38:25Z" - }, - { - "checksumSHA1": "P3zGmsNjW8m15a+nks4FdVpFKwE=", - "path": "github.com/gopherjs/gopherjs/js", - "revision": "a727a4a1dd2f292e948cebe6ec9aef1a7863f145", - "revisionTime": "2016-06-12T21:17:59Z" - }, - { - "checksumSHA1": "klfNfdEPsrWYLps2qBkLgfJsNYI=", - "path": "github.com/gorilla/websocket", - "revision": "2d1e4548da234d9cb742cc3628556fef86aafbac", - "revisionTime": "2016-09-12T15:30:41Z" - }, - { - "checksumSHA1": "Naa1qU7ykpIyDUZktjbqAU3V6bY=", - "path": "github.com/grpc-ecosystem/go-grpc-middleware", - "revision": "f849b5445de4819127e123ca96ba0eeb62b5e479", - "revisionTime": "2019-01-18T09:38:23Z" - }, - { - "checksumSHA1": "9dP53doJ/haDqTJyD0iuv8g0XFs=", - "path": "github.com/grpc-ecosystem/go-grpc-prometheus", - "revision": "39de4380c2e0353a115b80b1c730719c79bfb771", - "revisionTime": "2018-04-18T17:09:36Z" - }, - { - "checksumSHA1": "LoEQ+t5UoMm4InaYVPVn0XqHPwA=", - "path": "github.com/grpc-ecosystem/grpc-gateway/runtime", - "revision": "199c40a060d1e55508b3b85182ce6f3895ae6302", - "revisionTime": "2016-11-28T00:20:07Z" - }, - { - "checksumSHA1": "x396LPNfci/5x8aVJbliQHH11HQ=", - "path": "github.com/grpc-ecosystem/grpc-gateway/runtime/internal", - "revision": "199c40a060d1e55508b3b85182ce6f3895ae6302", - "revisionTime": "2016-11-28T00:20:07Z" - }, - { - "checksumSHA1": "vqiK5r5dntV7JNZ+ZsGlD0Samos=", - "path": "github.com/grpc-ecosystem/grpc-gateway/utilities", - "revision": "199c40a060d1e55508b3b85182ce6f3895ae6302", - "revisionTime": "2016-11-28T00:20:07Z" - }, - { - "checksumSHA1": "LQOVduohnld12Px2o0MfYDPI7oQ=", - "path": "github.com/hashicorp/consul/api", - "revision": "0bddfa23a2ebe3c0773d917fc104f53d74f7a5ec", - "revisionTime": "2018-11-14T22:37:47Z", - "version": "v1.4.0", - "versionExact": "v1.4.0" - }, - { - "checksumSHA1": "Uzyon2091lmwacNsl1hCytjhHtg=", - "path": "github.com/hashicorp/go-cleanhttp", - "revision": "ad28ea4487f05916463e2423a55166280e8254b5", - "revisionTime": "2016-04-07T17:41:26Z" - }, - { - "checksumSHA1": "A1PcINvF3UiwHRKn8UcgARgvGRs=", - "path": "github.com/hashicorp/go-rootcerts", - "revision": "6bb64b370b90e7ef1fa532be9e591a81c3493e00", - "revisionTime": "2016-05-03T14:34:40Z" - }, - { - "checksumSHA1": "UThRII2e7MEeIJ2sTHbCXC+4tKU=", - "path": "github.com/hashicorp/golang-lru/simplelru", - "revision": "7f827b33c0f158ec5dfbba01bb0b14a4541fd81d", - "revisionTime": "2019-07-26T16:11:22Z" - }, - { - "checksumSHA1": "E3Xcanc9ouQwL+CZGOUyA/+giLg=", - "path": "github.com/hashicorp/serf/coordinate", - "revision": "d3a67ab21bc8a4643fa53a3633f2d951dd50c6ca", - "revisionTime": "2016-12-07T01:17:43Z" - }, - { - "checksumSHA1": "0ZrwvB6KoGPj2PoDNSEJwxQ6Mog=", - "path": "github.com/jmespath/go-jmespath", - "revision": "0b12d6b521d83fc7f755e7cfc1b1fbdd35a01a74", - "revisionTime": "2016-02-02T18:50:14Z" - }, - { - "checksumSHA1": "tewA7jXVGCw1zb5mA0BDecWi4iQ=", - "path": "github.com/jtolds/gls", - "revision": "8ddce2a84170772b95dd5d576c48d517b22cac63", - "revisionTime": "2016-01-05T22:08:40Z" - }, - { - "checksumSHA1": "rmCbOBewXcbEdHRerzoanS+kI2U=", - "path": "github.com/klauspost/compress/flate", - "revision": "b50017755d442260d792c34c7c43216d9ba7ffc7", - "revisionTime": "2018-08-01T09:52:37Z" - }, - { - "checksumSHA1": "vGHBCcWkLCbAc3PJcRs7vFbvaYM=", - "path": "github.com/klauspost/cpuid", - "revision": "e7e905edc00ea8827e58662220139109efea09db", - "revisionTime": "2018-04-05T13:32:22Z" - }, - { - "checksumSHA1": "6/zXof97s7P9tlNp3mUioXgeEVI=", - "path": "github.com/klauspost/crc32", - "revision": "bab58d77464aa9cf4e84200c3276da0831fe0c03", - "revisionTime": "2017-06-28T07:24:49Z" - }, - { - "checksumSHA1": "N4EMcnfxHl1f4TQsKQWX/yLF/BE=", - "path": "github.com/klauspost/pgzip", - "revision": "c4ad2ed77aece7b3270909769a30a3fcea262a66", - "revisionTime": "2018-07-17T08:42:24Z" - }, - { - "checksumSHA1": "DdH3xAkzAWJ4B/LGYJyCeRsly2I=", - "path": "github.com/mattn/go-runewidth", - "revision": "d6bea18f789704b5f83375793155289da36a3c7f", - "revisionTime": "2016-03-15T04:07:12Z" - }, - { - "checksumSHA1": "bKMZjd2wPw13VwoE7mBeSv5djFA=", - "path": "github.com/matttproud/golang_protobuf_extensions/pbutil", - "revision": "c12348ce28de40eed0136aa2b644d0ee0650e56c", - "revisionTime": "2016-04-24T11:30:07Z" - }, - { - "checksumSHA1": "fROk3NEFAz88JXptqo4kpwD15Ic=", - "path": "github.com/matttproud/golang_protobuf_extensions/testdata", - "revision": "c12348ce28de40eed0136aa2b644d0ee0650e56c", - "revisionTime": "2016-04-24T11:30:07Z" - }, - { - "checksumSHA1": "Yi/mSgnMkG30eC61vcQWVwmxQQ8=", - "path": "github.com/minio/minio-go", - "revision": "c8a261de75c1a9a9ece4dcc0c81ff6db525bcf27", - "revisionTime": "2019-01-31T01:53:50Z", - "version": "v6.0.16", - "versionExact": "v6.0.16" - }, - { - "checksumSHA1": "pw8e6bgWfeEZUIMnD0Zge4d/KPo=", - "path": "github.com/minio/minio-go/pkg/credentials", - "revision": "c8a261de75c1a9a9ece4dcc0c81ff6db525bcf27", - "revisionTime": "2019-01-31T01:53:50Z", - "version": "v6.0.16", - "versionExact": "v6.0.16" - }, - { - "checksumSHA1": "Md5pOKYfoKtrG7xNvs2FtiDPfDc=", - "path": "github.com/minio/minio-go/pkg/encrypt", - "revision": "c8a261de75c1a9a9ece4dcc0c81ff6db525bcf27", - "revisionTime": "2019-01-31T01:53:50Z", - "version": "v6.0.16", - "versionExact": "v6.0.16" - }, - { - "checksumSHA1": "1KcTZxPRRQ0BWLt1zDVG1bSjm/4=", - "path": "github.com/minio/minio-go/pkg/s3signer", - "revision": "c8a261de75c1a9a9ece4dcc0c81ff6db525bcf27", - "revisionTime": "2019-01-31T01:53:50Z", - "version": "v6.0.16", - "versionExact": "v6.0.16" - }, - { - "checksumSHA1": "7iUaZkEJdhkyAu3F07vrX8pyavI=", - "path": "github.com/minio/minio-go/pkg/s3utils", - "revision": "c8a261de75c1a9a9ece4dcc0c81ff6db525bcf27", - "revisionTime": "2019-01-31T01:53:50Z", - "version": "v6.0.16", - "versionExact": "v6.0.16" - }, - { - "checksumSHA1": "Wt8ej+rZXTdNBR9Xyw1eGo3Iq5o=", - "path": "github.com/minio/minio-go/pkg/set", - "revision": "c8a261de75c1a9a9ece4dcc0c81ff6db525bcf27", - "revisionTime": "2019-01-31T01:53:50Z", - "version": "v6.0.16", - "versionExact": "v6.0.16" - }, - { - "checksumSHA1": "V/quM7+em2ByJbWBLOsEwnY3j/Q=", - "path": "github.com/mitchellh/go-homedir", - "revision": "b8bc1bf767474819792c23f32d8286a45736f1c6", - "revisionTime": "2016-12-03T19:45:07Z" - }, - { - "checksumSHA1": "J+g0oZePWp2zSIISD2dZZKTxmgg=", - "path": "github.com/mitchellh/mapstructure", - "revision": "3536a929edddb9a5b34bd6861dc4a9647cb459fe", - "revisionTime": "2018-10-05T04:51:35Z" - }, - { - "checksumSHA1": "txj5yUDiaSATtBLDlT0f6uaiIP8=", - "path": "github.com/olekukonko/tablewriter", - "revision": "cca8bbc0798408af109aaaa239cbd2634846b340", - "revisionTime": "2016-01-15T11:10:02Z" - }, - { - "checksumSHA1": "n38KWy7vkTd5/n7QqyRveENyZ98=", - "path": "github.com/opentracing-contrib/go-grpc", - "revision": "4b5a12d3ff02ba61ae861b7797e17a0c4f0ecea9", - "revisionTime": "2018-09-28T15:53:21Z" - }, - { - "checksumSHA1": "N+a8z9+g8MnuPN0aItiVP2CVFQs=", - "path": "github.com/opentracing/opentracing-go", - "revision": "1949ddbfd147afd4d964a9f00b24eb291e0e7c38", - "revisionTime": "2017-04-26T17:58:16Z", - "version": "v1.0.2", - "versionExact": "v1.0.2" - }, - { - "checksumSHA1": "XPOyfxsryU1pByZESwduVu9OEQU=", - "path": "github.com/opentracing/opentracing-go/ext", - "revision": "1949ddbfd147afd4d964a9f00b24eb291e0e7c38", - "revisionTime": "2017-04-26T17:58:16Z", - "version": "v1.0.2", - "versionExact": "v1.0.2" - }, - { - "checksumSHA1": "+rbKrafLHDnrQFgeWawo9tfZhV4=", - "path": "github.com/opentracing/opentracing-go/log", - "revision": "1949ddbfd147afd4d964a9f00b24eb291e0e7c38", - "revisionTime": "2017-04-26T17:58:16Z", - "version": "v1.0.2", - "versionExact": "v1.0.2" - }, - { - "checksumSHA1": "mhvIMH8oAtOiEyg37zWKmgb+6v4=", - "path": "github.com/pborman/uuid", - "revision": "b984ec7fa9ff9e428bd0cf0abf429384dfbe3e37", - "revisionTime": "2016-08-24T21:06:00Z" - }, - { - "checksumSHA1": "0H/VjT8w1CB702qWpbYMqr65Mf0=", - "path": "github.com/pkg/errors", - "revision": "ffb6e22f01932bf7ac35e0bad9be11f01d1c8685", - "revisionTime": "2019-01-09T06:16:28Z" - }, - { - "checksumSHA1": "LuFv4/jlrmFNnDb/5SCSEPAM9vU=", - "path": "github.com/pmezard/go-difflib/difflib", - "revision": "792786c7400a136282c1664665ae0a8db921c6c2", - "revisionTime": "2016-01-10T10:55:54Z" - }, - { - "checksumSHA1": "I87tkF1e/hrl4d/XIKFfkPRq1ww=", - "path": "github.com/prometheus/client_golang/prometheus", - "revision": "d49167c4b9f3c4451707560c5c71471ff5291aaa", - "revisionTime": "2018-03-19T13:17:21Z" - }, - { - "checksumSHA1": "mIWVz1E1QJ6yZnf7ELNwLboyK4w=", - "path": "github.com/prometheus/client_golang/prometheus/promhttp", - "revision": "d49167c4b9f3c4451707560c5c71471ff5291aaa", - "revisionTime": "2018-03-19T13:17:21Z" - }, - { - "checksumSHA1": "DvwvOlPNAgRntBzt3b3OSRMS2N4=", - "path": "github.com/prometheus/client_model/go", - "revision": "fa8ad6fec33561be4280a8f0514318c79d7f6cb6", - "revisionTime": "2015-02-12T10:17:44Z" - }, - { - "checksumSHA1": "m+nrHcRrjgi0wEa5PODKnY5yNX8=", - "path": "github.com/prometheus/common/expfmt", - "revision": "3a184ff7dfd46b9091030bf2e56c71112b0ddb0e", - "revisionTime": "2016-06-07T09:43:39Z" - }, - { - "checksumSHA1": "GWlM3d2vPYyNATtTFgftS10/A9w=", - "path": "github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg", - "revision": "3a184ff7dfd46b9091030bf2e56c71112b0ddb0e", - "revisionTime": "2016-06-07T09:43:39Z" - }, - { - "checksumSHA1": "Jx0GXl5hGnO25s3ryyvtdWHdCpw=", - "path": "github.com/prometheus/common/model", - "revision": "3a184ff7dfd46b9091030bf2e56c71112b0ddb0e", - "revisionTime": "2016-06-07T09:43:39Z" - }, - { - "checksumSHA1": "W218eJZPXJG783fUr/z6IaAZyes=", - "path": "github.com/prometheus/procfs", - "revision": "abf152e5f3e97f2fafac028d2cc06c1feb87ffa5", - "revisionTime": "2016-04-11T19:08:41Z" - }, - { - "checksumSHA1": "zmC8/3V4ls53DJlNTKDZwPSC/dA=", - "path": "github.com/satori/go.uuid", - "revision": "0aa62d5ddceb50dbcb909d790b5345affd3669b6", - "revisionTime": "2016-07-13T18:03:06Z" - }, - { - "checksumSHA1": "v7C+aJ1D/z3MEeCte6bxvpoGjM4=", - "path": "github.com/sergi/go-diff/diffmatchpatch", - "revision": "feef008d51ad2b3778f85d387ccf91735543008d", - "revisionTime": "2017-04-09T07:17:39Z" - }, - { - "checksumSHA1": "6AYg4fjEvFuAVN3wHakGApjhZAM=", - "path": "github.com/smartystreets/assertions", - "revision": "40711f7748186bbf9c99977cd89f21ce1a229447", - "revisionTime": "2016-04-22T19:53:51Z" - }, - { - "checksumSHA1": "Vzb+dEH/LTYbvr8RXHmt6xJHz04=", - "path": "github.com/smartystreets/assertions/internal/go-render/render", - "revision": "40711f7748186bbf9c99977cd89f21ce1a229447", - "revisionTime": "2016-04-22T19:53:51Z" - }, - { - "checksumSHA1": "SLC6TfV4icQA9l8YJQu8acJYbuo=", - "path": "github.com/smartystreets/assertions/internal/oglematchers", - "revision": "40711f7748186bbf9c99977cd89f21ce1a229447", - "revisionTime": "2016-04-22T19:53:51Z" - }, - { - "checksumSHA1": "SrDo9JDu6DyZ7I+4uQABY6EkW90=", - "path": "github.com/smartystreets/assertions/internal/oglemock", - "revision": "40711f7748186bbf9c99977cd89f21ce1a229447", - "revisionTime": "2016-04-22T19:53:51Z" - }, - { - "checksumSHA1": "fqmDhb1Vu5Ian6bKOIK/qKHbfDY=", - "path": "github.com/smartystreets/assertions/internal/oglemock/sample/mock_io", - "revision": "40711f7748186bbf9c99977cd89f21ce1a229447", - "revisionTime": "2016-04-22T19:53:51Z" - }, - { - "checksumSHA1": "iZ6XlO018Wjbq08EmI/gF98wWuI=", - "path": "github.com/smartystreets/assertions/internal/ogletest", - "revision": "40711f7748186bbf9c99977cd89f21ce1a229447", - "revisionTime": "2016-04-22T19:53:51Z" - }, - { - "checksumSHA1": "Ji1ubfT/e0/n/ABIjm+SkAnB2nI=", - "path": "github.com/smartystreets/assertions/internal/ogletest/srcutil", - "revision": "40711f7748186bbf9c99977cd89f21ce1a229447", - "revisionTime": "2016-04-22T19:53:51Z" - }, - { - "checksumSHA1": "Lq4IjivEPadH4fnuG/3uXyMZHEQ=", - "path": "github.com/smartystreets/assertions/internal/reqtrace", - "revision": "40711f7748186bbf9c99977cd89f21ce1a229447", - "revisionTime": "2016-04-22T19:53:51Z" - }, - { - "checksumSHA1": "/mwAihy9AmznMzmbPQ5nWJXBiRU=", - "path": "github.com/smartystreets/goconvey/convey", - "revision": "c53abc99456fa3402dd33c15ee51c3e545e04a3f", - "revisionTime": "2016-05-23T15:31:47Z" - }, - { - "checksumSHA1": "9LakndErFi5uCXtY1KWl0iRnT4c=", - "path": "github.com/smartystreets/goconvey/convey/gotest", - "revision": "c53abc99456fa3402dd33c15ee51c3e545e04a3f", - "revisionTime": "2016-05-23T15:31:47Z" - }, - { - "checksumSHA1": "FWDhk37bhAwZ2363D/L2xePwR64=", - "path": "github.com/smartystreets/goconvey/convey/reporting", - "revision": "c53abc99456fa3402dd33c15ee51c3e545e04a3f", - "revisionTime": "2016-05-23T15:31:47Z" - }, - { - "checksumSHA1": "Bn333k9lTndxU3D6n/G5c+GMcYY=", - "path": "github.com/stretchr/testify/assert", - "revision": "8d64eb7173c7753d6419fd4a9caf057398611364", - "revisionTime": "2016-05-24T23:42:29Z" - }, - { - "checksumSHA1": "P9FJpir2c4G5PA46qEkaWy3l60U=", - "path": "github.com/stretchr/testify/require", - "revision": "8d64eb7173c7753d6419fd4a9caf057398611364", - "revisionTime": "2016-05-24T23:42:29Z" - }, - { - "checksumSHA1": "fi13nRs6FDnhY5kL/9eMcNF8rQ8=", - "path": "github.com/tchap/go-patricia/patricia", - "revision": "dd168db6051b704a01881df7e003cb7ec9a7a440", - "revisionTime": "2016-07-29T07:16:56Z" - }, - { - "checksumSHA1": "DPkZT4nujrbAaKzqiWe+nmsNw2M=", - "path": "github.com/uber/jaeger-client-go", - "revision": "2f47546e3facd43297739439600bcf43f44cce5d", - "revisionTime": "2019-03-24T18:29:16Z", - "version": "v2.16.0", - "versionExact": "v2.16.0" - }, - { - "checksumSHA1": "/PA9bYu1glNCL5ucsKj8s+NkkHc=", - "path": "github.com/uber/jaeger-client-go/config", - "revision": "2f47546e3facd43297739439600bcf43f44cce5d", - "revisionTime": "2019-03-24T18:29:16Z", - "version": "v2.16.0", - "versionExact": "v2.16.0" - }, - { - "checksumSHA1": "KM5UXTWkHULmw0dDRNuk8ogWyGs=", - "path": "github.com/uber/jaeger-client-go/internal/baggage", - "revision": "2f47546e3facd43297739439600bcf43f44cce5d", - "revisionTime": "2019-03-24T18:29:16Z", - "version": "v2.16.0", - "versionExact": "v2.16.0" - }, - { - "checksumSHA1": "tZqlcHV1XoLdZp9jfnydzsZAvYo=", - "path": "github.com/uber/jaeger-client-go/internal/baggage/remote", - "revision": "2f47546e3facd43297739439600bcf43f44cce5d", - "revisionTime": "2019-03-24T18:29:16Z", - "version": "v2.16.0", - "versionExact": "v2.16.0" - }, - { - "checksumSHA1": "QB0L0GrzyMGQp6ivkkxp7a1DPsE=", - "path": "github.com/uber/jaeger-client-go/internal/spanlog", - "revision": "2f47546e3facd43297739439600bcf43f44cce5d", - "revisionTime": "2019-03-24T18:29:16Z", - "version": "v2.16.0", - "versionExact": "v2.16.0" - }, - { - "checksumSHA1": "79HRO/+ekkpwqDB/OMiW+AHJtlE=", - "path": "github.com/uber/jaeger-client-go/internal/throttler", - "revision": "2f47546e3facd43297739439600bcf43f44cce5d", - "revisionTime": "2019-03-24T18:29:16Z", - "version": "v2.16.0", - "versionExact": "v2.16.0" - }, - { - "checksumSHA1": "OVQDWFtFMs+NODe0F/S5kYViQco=", - "path": "github.com/uber/jaeger-client-go/internal/throttler/remote", - "revision": "2f47546e3facd43297739439600bcf43f44cce5d", - "revisionTime": "2019-03-24T18:29:16Z", - "version": "v2.16.0", - "versionExact": "v2.16.0" - }, - { - "checksumSHA1": "tMP/vxbHwNAbOEaUhic5/meKfac=", - "path": "github.com/uber/jaeger-client-go/log", - "revision": "2f47546e3facd43297739439600bcf43f44cce5d", - "revisionTime": "2019-03-24T18:29:16Z", - "version": "v2.16.0", - "versionExact": "v2.16.0" - }, - { - "checksumSHA1": "empqDwPkKUkGNeGHCu/EWoGI21o=", - "path": "github.com/uber/jaeger-client-go/rpcmetrics", - "revision": "2f47546e3facd43297739439600bcf43f44cce5d", - "revisionTime": "2019-03-24T18:29:16Z", - "version": "v2.16.0", - "versionExact": "v2.16.0" - }, - { - "checksumSHA1": "+ffspyTBQLql2UiU6muvfWR/m1o=", - "path": "github.com/uber/jaeger-client-go/thrift", - "revision": "2f47546e3facd43297739439600bcf43f44cce5d", - "revisionTime": "2019-03-24T18:29:16Z", - "version": "v2.16.0", - "versionExact": "v2.16.0" - }, - { - "checksumSHA1": "fMIQ4sJFCkqFYhXvvLKIlofqxvY=", - "path": "github.com/uber/jaeger-client-go/thrift-gen/agent", - "revision": "2f47546e3facd43297739439600bcf43f44cce5d", - "revisionTime": "2019-03-24T18:29:16Z", - "version": "v2.16.0", - "versionExact": "v2.16.0" - }, - { - "checksumSHA1": "fRR2p+JAp7paApf32YuQuWU7yzY=", - "path": "github.com/uber/jaeger-client-go/thrift-gen/baggage", - "revision": "2f47546e3facd43297739439600bcf43f44cce5d", - "revisionTime": "2019-03-24T18:29:16Z", - "version": "v2.16.0", - "versionExact": "v2.16.0" - }, - { - "checksumSHA1": "JZkMEOmiOFFEuGCsDOVLK5RzvMM=", - "path": "github.com/uber/jaeger-client-go/thrift-gen/jaeger", - "revision": "2f47546e3facd43297739439600bcf43f44cce5d", - "revisionTime": "2019-03-24T18:29:16Z", - "version": "v2.16.0", - "versionExact": "v2.16.0" - }, - { - "checksumSHA1": "0teQUhTqTE1fLs+vbnTTzWOqdEQ=", - "path": "github.com/uber/jaeger-client-go/thrift-gen/sampling", - "revision": "2f47546e3facd43297739439600bcf43f44cce5d", - "revisionTime": "2019-03-24T18:29:16Z", - "version": "v2.16.0", - "versionExact": "v2.16.0" - }, - { - "checksumSHA1": "jB+fvt3/iJYRDDp6+twGm5gGIXQ=", - "path": "github.com/uber/jaeger-client-go/thrift-gen/zipkincore", - "revision": "2f47546e3facd43297739439600bcf43f44cce5d", - "revisionTime": "2019-03-24T18:29:16Z", - "version": "v2.16.0", - "versionExact": "v2.16.0" - }, - { - "checksumSHA1": "UlW+AcyeItWM0x1W4vT9hbUiOJs=", - "path": "github.com/uber/jaeger-client-go/transport", - "revision": "2f47546e3facd43297739439600bcf43f44cce5d", - "revisionTime": "2019-03-24T18:29:16Z", - "version": "v2.16.0", - "versionExact": "v2.16.0" - }, - { - "checksumSHA1": "DKwwIk9vq53IKO7RKccat9cnqeo=", - "path": "github.com/uber/jaeger-client-go/utils", - "revision": "2f47546e3facd43297739439600bcf43f44cce5d", - "revisionTime": "2019-03-24T18:29:16Z", - "version": "v2.16.0", - "versionExact": "v2.16.0" - }, - { - "checksumSHA1": "gF1WPb3/R8RoZw/wqEQmkwntrQc=", - "path": "github.com/uber/jaeger-lib/metrics", - "revision": "0e30338a695636fe5bcf7301e8030ce8dd2a8530", - "revisionTime": "2018-12-17T19:14:06Z", - "version": "v2.0.0", - "versionExact": "v2.0.0" - }, - { - "checksumSHA1": "8Kj0VH496b0exuyv4wAF4CXa7Y4=", - "path": "github.com/yudai/gojsondiff", - "revision": "081cda2ee95045a2c26da52c2ba80860838549de", - "revisionTime": "2017-06-26T13:12:58Z" - }, - { - "checksumSHA1": "50gdo5Kq0/gEKG1A4agCPOZ26JA=", - "path": "github.com/yudai/gojsondiff/formatter", - "revision": "081cda2ee95045a2c26da52c2ba80860838549de", - "revisionTime": "2017-06-26T13:12:58Z" - }, - { - "checksumSHA1": "5xoBoioS8LWHn9FC0pL+vo7wDjs=", - "path": "github.com/yudai/golcs", - "revision": "ecda9a501e8220fae3b4b600c3db4b0ba22cfc68", - "revisionTime": "2017-03-16T03:48:04Z" - }, - { - "checksumSHA1": "az5f5DY8K9vZizIo4mjHNPAALUA=", - "path": "github.com/z-division/go-zookeeper/zk", - "revision": "6d7457066b9b62f64b9a884659d89ad5c5ad5173", - "revisionTime": "2019-01-28T07:28:38Z" - }, - { - "checksumSHA1": "w+WRj7WpdItd5iR7PcaQQKMrVB0=", - "path": "go.opencensus.io", - "revision": "b4a14686f0a98096416fe1b4cb848e384fb2b22b", - "revisionTime": "2019-07-13T07:22:01Z" - }, - { - "checksumSHA1": "KLZy3Nh+8JlI04JmBa/Jc8fxrVQ=", - "path": "go.opencensus.io/internal", - "revision": "b4a14686f0a98096416fe1b4cb848e384fb2b22b", - "revisionTime": "2019-07-13T07:22:01Z" - }, - { - "checksumSHA1": "Dw3rpna1DwTa7TCzijInKcU49g4=", - "path": "go.opencensus.io/internal/tagencoding", - "revision": "b4a14686f0a98096416fe1b4cb848e384fb2b22b", - "revisionTime": "2019-07-13T07:22:01Z" - }, - { - "checksumSHA1": "r6fbtPwxK4/TYUOWc7y0hXdAG4Q=", - "path": "go.opencensus.io/metric/metricdata", - "revision": "b4a14686f0a98096416fe1b4cb848e384fb2b22b", - "revisionTime": "2019-07-13T07:22:01Z" - }, - { - "checksumSHA1": "kWj13srwY1SH5KgFecPhEfHnzVc=", - "path": "go.opencensus.io/metric/metricproducer", - "revision": "b4a14686f0a98096416fe1b4cb848e384fb2b22b", - "revisionTime": "2019-07-13T07:22:01Z" - }, - { - "checksumSHA1": "kZAPvdijG2qWdS00Vt2NS4kH02k=", - "path": "go.opencensus.io/plugin/ocgrpc", - "revision": "b4a14686f0a98096416fe1b4cb848e384fb2b22b", - "revisionTime": "2019-07-13T07:22:01Z" - }, - { - "checksumSHA1": "Ur+xijNXCbNHR8Q5VjW1czSAabo=", - "path": "go.opencensus.io/plugin/ochttp", - "revision": "b4a14686f0a98096416fe1b4cb848e384fb2b22b", - "revisionTime": "2019-07-13T07:22:01Z" - }, - { - "checksumSHA1": "UZhIoErIy1tKLmVT/5huwlp6KFQ=", - "path": "go.opencensus.io/plugin/ochttp/propagation/b3", - "revision": "b4a14686f0a98096416fe1b4cb848e384fb2b22b", - "revisionTime": "2019-07-13T07:22:01Z" - }, - { - "checksumSHA1": "q+y8X+5nDONIlJlxfkv+OtA18ds=", - "path": "go.opencensus.io/resource", - "revision": "b4a14686f0a98096416fe1b4cb848e384fb2b22b", - "revisionTime": "2019-07-13T07:22:01Z" - }, - { - "checksumSHA1": "Cc4tRuW0IjlfAFY8BcdfMDqG0R8=", - "path": "go.opencensus.io/stats", - "revision": "b4a14686f0a98096416fe1b4cb848e384fb2b22b", - "revisionTime": "2019-07-13T07:22:01Z" - }, - { - "checksumSHA1": "oIo4NRi6AVCfcwVfHzCXAsoZsdI=", - "path": "go.opencensus.io/stats/internal", - "revision": "b4a14686f0a98096416fe1b4cb848e384fb2b22b", - "revisionTime": "2019-07-13T07:22:01Z" - }, - { - "checksumSHA1": "vN9GN1vwD4RU/3ld2tKK00K0i94=", - "path": "go.opencensus.io/stats/view", - "revision": "b4a14686f0a98096416fe1b4cb848e384fb2b22b", - "revisionTime": "2019-07-13T07:22:01Z" - }, - { - "checksumSHA1": "AoqL/neZwl05Fv08vcXXlhbY12g=", - "path": "go.opencensus.io/tag", - "revision": "b4a14686f0a98096416fe1b4cb848e384fb2b22b", - "revisionTime": "2019-07-13T07:22:01Z" - }, - { - "checksumSHA1": "0O3djqX4bcg5O9LZdcinEoYeQKs=", - "path": "go.opencensus.io/trace", - "revision": "b4a14686f0a98096416fe1b4cb848e384fb2b22b", - "revisionTime": "2019-07-13T07:22:01Z" - }, - { - "checksumSHA1": "JkvEb8oMEFjic5K/03Tyr5Lok+w=", - "path": "go.opencensus.io/trace/internal", - "revision": "b4a14686f0a98096416fe1b4cb848e384fb2b22b", - "revisionTime": "2019-07-13T07:22:01Z" - }, - { - "checksumSHA1": "FHJParRi8f1GHO7Cx+lk3bMWBq0=", - "path": "go.opencensus.io/trace/propagation", - "revision": "b4a14686f0a98096416fe1b4cb848e384fb2b22b", - "revisionTime": "2019-07-13T07:22:01Z" - }, - { - "checksumSHA1": "UHbxxaMqpEPsubh8kPwzSlyEwqI=", - "path": "go.opencensus.io/trace/tracestate", - "revision": "b4a14686f0a98096416fe1b4cb848e384fb2b22b", - "revisionTime": "2019-07-13T07:22:01Z" - }, - { - "checksumSHA1": "FwW3Vv4jW0Nv7V2SZC7x/Huj5M4=", - "path": "golang.org/x/crypto/argon2", - "revision": "b8fe1690c61389d7d2a8074a507d1d40c5d30448", - "revisionTime": "2019-01-30T22:18:58Z" - }, - { - "checksumSHA1": "eaK7NuGdfEVypOnqYniZSuF2S6s=", - "path": "golang.org/x/crypto/blake2b", - "revision": "b8fe1690c61389d7d2a8074a507d1d40c5d30448", - "revisionTime": "2019-01-30T22:18:58Z" - }, - { - "checksumSHA1": "N5fb5y92DFIP+wUhi1rSwPp9vyk=", - "path": "golang.org/x/crypto/ssh/terminal", - "revision": "1777f3ba8c1fed80fcaec3317e3aaa4f627764d2", - "revisionTime": "2016-03-18T12:12:46Z" - }, - { - "checksumSHA1": "GtamqiJoL7PGHsN454AoffBFMa8=", - "path": "golang.org/x/net/context", - "revision": "adae6a3d119ae4890b46832a2e88a95adc62b8e7", - "revisionTime": "2018-11-14T21:44:15Z" - }, - { - "checksumSHA1": "EJMLw8rk55bsqmIpSMtVORJpSGo=", - "path": "golang.org/x/net/context/ctxhttp", - "revision": "fb93926129b8ec0056f2f458b1f519654814edf0", - "revisionTime": "2016-04-12T22:48:50Z" - }, - { - "checksumSHA1": "pCY4YtdNKVBYRbNvODjx8hj0hIs=", - "path": "golang.org/x/net/http/httpguts", - "revision": "adae6a3d119ae4890b46832a2e88a95adc62b8e7", - "revisionTime": "2018-11-14T21:44:15Z" - }, - { - "checksumSHA1": "QmfYRV9T2HIj1cvl2ZQCd6bXXKo=", - "path": "golang.org/x/net/http2", - "revision": "adae6a3d119ae4890b46832a2e88a95adc62b8e7", - "revisionTime": "2018-11-14T21:44:15Z" - }, - { - "checksumSHA1": "KZniwnfpWkaTPhUQDUTvgex/7y0=", - "path": "golang.org/x/net/http2/hpack", - "revision": "adae6a3d119ae4890b46832a2e88a95adc62b8e7", - "revisionTime": "2018-11-14T21:44:15Z" - }, - { - "checksumSHA1": "RcrB7tgYS/GMW4QrwVdMOTNqIU8=", - "path": "golang.org/x/net/idna", - "revision": "adae6a3d119ae4890b46832a2e88a95adc62b8e7", - "revisionTime": "2018-11-14T21:44:15Z" - }, - { - "checksumSHA1": "UxahDzW2v4mf/+aFxruuupaoIwo=", - "path": "golang.org/x/net/internal/timeseries", - "revision": "adae6a3d119ae4890b46832a2e88a95adc62b8e7", - "revisionTime": "2018-11-14T21:44:15Z" - }, - { - "checksumSHA1": "3xyuaSNmClqG4YWC7g0isQIbUTc=", - "path": "golang.org/x/net/lex/httplex", - "revision": "5f8847ae0d0e90b6a9dc8148e7ad616874625171", - "revisionTime": "2017-06-23T17:10:45Z" - }, - { - "checksumSHA1": "j6leSoJatxWHJGLjRxIjZ8GbaDQ=", - "path": "golang.org/x/net/publicsuffix", - "revision": "65e2d4e15006aab9813ff8769e768bbf4bb667a0", - "revisionTime": "2019-02-01T23:59:58Z" - }, - { - "checksumSHA1": "4vGl3N46SAJwQl/uSlQvZQvc734=", - "path": "golang.org/x/net/trace", - "revision": "adae6a3d119ae4890b46832a2e88a95adc62b8e7", - "revisionTime": "2018-11-14T21:44:15Z" - }, - { - "checksumSHA1": "uRlaEkyMCxyjj57KBa81GEfvCwg=", - "path": "golang.org/x/oauth2", - "revision": "0f29369cfe4552d0e4bcddc57cc75f4d7e672a33", - "revisionTime": "2019-05-07T23:52:07Z" - }, - { - "checksumSHA1": "UmEcak5EiFA6UpbMnlfkQzHyw3M=", - "path": "golang.org/x/oauth2/google", - "revision": "0f29369cfe4552d0e4bcddc57cc75f4d7e672a33", - "revisionTime": "2019-05-07T23:52:07Z" - }, - { - "checksumSHA1": "+9KSfsjsC3F2CldDDb+Dt+d/H3Q=", - "path": "golang.org/x/oauth2/internal", - "revision": "0f29369cfe4552d0e4bcddc57cc75f4d7e672a33", - "revisionTime": "2019-05-07T23:52:07Z" - }, - { - "checksumSHA1": "huVltYnXdRFDJLgp/ZP9IALzG7g=", - "path": "golang.org/x/oauth2/jws", - "revision": "0f29369cfe4552d0e4bcddc57cc75f4d7e672a33", - "revisionTime": "2019-05-07T23:52:07Z" - }, - { - "checksumSHA1": "HGS6ig1GfcE2CBHBsi965ZVn9Xw=", - "path": "golang.org/x/oauth2/jwt", - "revision": "0f29369cfe4552d0e4bcddc57cc75f4d7e672a33", - "revisionTime": "2019-05-07T23:52:07Z" - }, - { - "checksumSHA1": "1CmUDjhZlyKZcbLYlWI7cRzK3fI=", - "path": "golang.org/x/sys/cpu", - "revision": "41f3e6584952bb034a481797859f6ab34b6803bd", - "revisionTime": "2019-02-04T12:38:20Z" - }, - { - "checksumSHA1": "QmmEQv1jLvjlVGPsWewqeNYNoyk=", - "path": "golang.org/x/sys/unix", - "revision": "62eef0e2fa9b2c385f7b2778e763486da6880d37", - "revisionTime": "2018-11-22T14:36:24Z" - }, - { - "checksumSHA1": "Gwx30TD3lMSgskBCmXTDXbICPRQ=", - "path": "golang.org/x/text/collate", - "revision": "fc7fa097411d30e6708badff276c4c164425590c", - "revisionTime": "2017-03-23T10:04:54Z" - }, - { - "checksumSHA1": "gRurdsue4RAi2xYzy89YDzO2c2I=", - "path": "golang.org/x/text/collate/build", - "revision": "fc7fa097411d30e6708badff276c4c164425590c", - "revisionTime": "2017-03-23T10:04:54Z" - }, - { - "checksumSHA1": "fM/n4f1c26uIh3wB9g+1flJkSAo=", - "path": "golang.org/x/text/internal/colltab", - "revision": "fc7fa097411d30e6708badff276c4c164425590c", - "revisionTime": "2017-03-23T10:04:54Z" - }, - { - "checksumSHA1": "ZQdHbB9VYCXwQ+9/CmZPhJv0+SM=", - "path": "golang.org/x/text/internal/gen", - "revision": "fc7fa097411d30e6708badff276c4c164425590c", - "revisionTime": "2017-03-23T10:04:54Z" - }, - { - "checksumSHA1": "hyNCcTwMQnV6/MK8uUW9E5H0J0M=", - "path": "golang.org/x/text/internal/tag", - "revision": "fc7fa097411d30e6708badff276c4c164425590c", - "revisionTime": "2017-03-23T10:04:54Z" - }, - { - "checksumSHA1": "47nwiUyVBY2RKoEGXmCSvusY4Js=", - "path": "golang.org/x/text/internal/triegen", - "revision": "fc7fa097411d30e6708badff276c4c164425590c", - "revisionTime": "2017-03-23T10:04:54Z" - }, - { - "checksumSHA1": "Yd5wMObzagIfCiKLpZbtBIrOUA4=", - "path": "golang.org/x/text/internal/ucd", - "revision": "fc7fa097411d30e6708badff276c4c164425590c", - "revisionTime": "2017-03-23T10:04:54Z" - }, - { - "checksumSHA1": "ckawpDnd22U/0HjSPKF4yY5pIeg=", - "path": "golang.org/x/text/language", - "revision": "fc7fa097411d30e6708badff276c4c164425590c", - "revisionTime": "2017-03-23T10:04:54Z" - }, - { - "checksumSHA1": "CbpjEkkOeh0fdM/V8xKDdI0AA88=", - "path": "golang.org/x/text/secure/bidirule", - "revision": "6f44c5a2ea40ee3593d98cdcc905cc1fdaa660e2", - "revisionTime": "2018-10-29T18:00:05Z" - }, - { - "checksumSHA1": "o3YChxWLvyCmkAn/ZNBj9HC9zKw=", - "path": "golang.org/x/text/transform", - "revision": "6f44c5a2ea40ee3593d98cdcc905cc1fdaa660e2", - "revisionTime": "2018-10-29T18:00:05Z" - }, - { - "checksumSHA1": "qjFbU4RWY+Caxaa5/TlMJW82E+A=", - "path": "golang.org/x/text/unicode/bidi", - "revision": "6f44c5a2ea40ee3593d98cdcc905cc1fdaa660e2", - "revisionTime": "2018-10-29T18:00:05Z" - }, - { - "checksumSHA1": "+U+vu5UQXoIB4egXy7uX3GYBxVo=", - "path": "golang.org/x/text/unicode/cldr", - "revision": "fc7fa097411d30e6708badff276c4c164425590c", - "revisionTime": "2017-03-23T10:04:54Z" - }, - { - "checksumSHA1": "vAScJLvb0ucuuclyN9vmJUyWTBA=", - "path": "golang.org/x/text/unicode/norm", - "revision": "6f44c5a2ea40ee3593d98cdcc905cc1fdaa660e2", - "revisionTime": "2018-10-29T18:00:05Z" - }, - { - "checksumSHA1": "bLoGyjxHeYpHKEzU1g9f3m5qsnQ=", - "path": "golang.org/x/text/unicode/rangetable", - "revision": "4e9ab9ee170f2a39bd66c92b3e0a47ff47a4bc77", - "revisionTime": "2017-06-09T11:26:06Z" - }, - { - "checksumSHA1": "eFQDEix/mGnhwnFu/Hq63zMfrX8=", - "path": "golang.org/x/time/rate", - "revision": "f51c12702a4d776e4c1fa9b0fabab841babae631", - "revisionTime": "2016-10-28T04:02:39Z" - }, - { - "checksumSHA1": "FhzGDPlkW5SaQGtSgKnjQAiYVk0=", - "path": "google.golang.org/api/gensupport", - "revision": "02490b97dff7cfde1995bd77de808fd27053bc87", - "revisionTime": "2019-06-24T17:16:18Z", - "version": "v0.7.0", - "versionExact": "v0.7.0" - }, - { - "checksumSHA1": "YIDE68w/xMptf6Nu9hHiOwXOvho=", - "path": "google.golang.org/api/googleapi", - "revision": "02490b97dff7cfde1995bd77de808fd27053bc87", - "revisionTime": "2019-06-24T17:16:18Z", - "version": "v0.7.0", - "versionExact": "v0.7.0" - }, - { - "checksumSHA1": "1K0JxrUfDqAB3MyRiU1LKjfHyf4=", - "path": "google.golang.org/api/googleapi/internal/uritemplates", - "revision": "02490b97dff7cfde1995bd77de808fd27053bc87", - "revisionTime": "2019-06-24T17:16:18Z", - "version": "v0.7.0", - "versionExact": "v0.7.0" - }, - { - "checksumSHA1": "Mr2fXhMRzlQCgANFm91s536pG7E=", - "path": "google.golang.org/api/googleapi/transport", - "revision": "02490b97dff7cfde1995bd77de808fd27053bc87", - "revisionTime": "2019-06-24T17:16:18Z", - "version": "v0.7.0", - "versionExact": "v0.7.0" - }, - { - "checksumSHA1": "6Tg4dDJKzoSrAA5beVknvnjluOU=", - "path": "google.golang.org/api/internal", - "revision": "02490b97dff7cfde1995bd77de808fd27053bc87", - "revisionTime": "2019-06-24T17:16:18Z", - "version": "v0.7.0", - "versionExact": "v0.7.0" - }, - { - "checksumSHA1": "zh9AcT6oNvhnOqb7w7njY48TkvI=", - "path": "google.golang.org/api/iterator", - "revision": "02490b97dff7cfde1995bd77de808fd27053bc87", - "revisionTime": "2019-06-24T17:16:18Z", - "version": "v0.7.0", - "versionExact": "v0.7.0" - }, - { - "checksumSHA1": "XdTB13Pxzd95rhckAEBpCeMp69M=", - "path": "google.golang.org/api/iterator/testing", - "revision": "02490b97dff7cfde1995bd77de808fd27053bc87", - "revisionTime": "2019-06-24T17:16:18Z", - "version": "v0.7.0", - "versionExact": "v0.7.0" - }, - { - "checksumSHA1": "2AyxThTPscWdy49fGsU2tg0Uyw8=", - "path": "google.golang.org/api/option", - "revision": "02490b97dff7cfde1995bd77de808fd27053bc87", - "revisionTime": "2019-06-24T17:16:18Z", - "version": "v0.7.0", - "versionExact": "v0.7.0" - }, - { - "checksumSHA1": "Aka6Sle3vs6xGP70PADl9lAlZIE=", - "path": "google.golang.org/api/storage/v1", - "revision": "02490b97dff7cfde1995bd77de808fd27053bc87", - "revisionTime": "2019-06-24T17:16:18Z", - "version": "v0.7.0", - "versionExact": "v0.7.0" - }, - { - "checksumSHA1": "hOQM3ns9t81o566ge8UNFEtoXX8=", - "path": "google.golang.org/api/transport", - "revision": "02490b97dff7cfde1995bd77de808fd27053bc87", - "revisionTime": "2019-06-24T17:16:18Z", - "version": "v0.7.0", - "versionExact": "v0.7.0" - }, - { - "checksumSHA1": "XeonlHuXpmHUQDqIK2qJ/DSKg0o=", - "path": "google.golang.org/api/transport/grpc", - "revision": "02490b97dff7cfde1995bd77de808fd27053bc87", - "revisionTime": "2019-06-24T17:16:18Z", - "version": "v0.7.0", - "versionExact": "v0.7.0" - }, - { - "checksumSHA1": "WzZfHJ4G6jO/qf3n6DI9a9awJQk=", - "path": "google.golang.org/api/transport/http", - "revision": "02490b97dff7cfde1995bd77de808fd27053bc87", - "revisionTime": "2019-06-24T17:16:18Z", - "version": "v0.7.0", - "versionExact": "v0.7.0" - }, - { - "checksumSHA1": "sJcKCvjPtoysqyelsB2CQzC5oQI=", - "path": "google.golang.org/api/transport/http/internal/propagation", - "revision": "02490b97dff7cfde1995bd77de808fd27053bc87", - "revisionTime": "2019-06-24T17:16:18Z", - "version": "v0.7.0", - "versionExact": "v0.7.0" - }, - { - "checksumSHA1": "buWXkeU6VNtym88sZ7lKJvsCVXk=", - "path": "google.golang.org/appengine", - "revision": "54a98f90d1c46b7731eb8fb305d2a321c30ef610", - "revisionTime": "2019-02-15T20:43:44Z", - "version": "v1.5.0", - "versionExact": "v1.5.0" - }, - { - "checksumSHA1": "61EFkyXUswt3Su1R/C8JHJWF+jw=", - "path": "google.golang.org/appengine/internal", - "revision": "54a98f90d1c46b7731eb8fb305d2a321c30ef610", - "revisionTime": "2019-02-15T20:43:44Z", - "version": "v1.5.0", - "versionExact": "v1.5.0" - }, - { - "checksumSHA1": "GyzSDzUj78G9nyNhmlFGg5IufHc=", - "path": "google.golang.org/appengine/internal/app_identity", - "revision": "54a98f90d1c46b7731eb8fb305d2a321c30ef610", - "revisionTime": "2019-02-15T20:43:44Z", - "version": "v1.5.0", - "versionExact": "v1.5.0" - }, - { - "checksumSHA1": "5PakGXEgSbyFptkhGO8MnGf7uH0=", - "path": "google.golang.org/appengine/internal/base", - "revision": "54a98f90d1c46b7731eb8fb305d2a321c30ef610", - "revisionTime": "2019-02-15T20:43:44Z", - "version": "v1.5.0", - "versionExact": "v1.5.0" - }, - { - "checksumSHA1": "3DZ+Ah5hFQb1/nh1+li2VE+kkfk=", - "path": "google.golang.org/appengine/internal/datastore", - "revision": "54a98f90d1c46b7731eb8fb305d2a321c30ef610", - "revisionTime": "2019-02-15T20:43:44Z", - "version": "v1.5.0", - "versionExact": "v1.5.0" - }, - { - "checksumSHA1": "HJQ4JM9YWfwIe4vmAgXC7J/1T3E=", - "path": "google.golang.org/appengine/internal/log", - "revision": "54a98f90d1c46b7731eb8fb305d2a321c30ef610", - "revisionTime": "2019-02-15T20:43:44Z", - "version": "v1.5.0", - "versionExact": "v1.5.0" - }, - { - "checksumSHA1": "rPcVt7Td1StpB6Z9DiShhu753PM=", - "path": "google.golang.org/appengine/internal/modules", - "revision": "54a98f90d1c46b7731eb8fb305d2a321c30ef610", - "revisionTime": "2019-02-15T20:43:44Z", - "version": "v1.5.0", - "versionExact": "v1.5.0" - }, - { - "checksumSHA1": "hApgRLSl7w9XG2waJxdH/o0A398=", - "path": "google.golang.org/appengine/internal/remote_api", - "revision": "54a98f90d1c46b7731eb8fb305d2a321c30ef610", - "revisionTime": "2019-02-15T20:43:44Z", - "version": "v1.5.0", - "versionExact": "v1.5.0" - }, - { - "checksumSHA1": "GlPZsxfa/OYvumlfU8+2j4cVai8=", - "path": "google.golang.org/genproto/googleapis/api/annotations", - "revision": "fa694d86fc64c7654a660f8908de4e879866748d", - "revisionTime": "2019-08-01T16:59:51Z" - }, - { - "checksumSHA1": "nTQH9H1cWFc4Ft8sJylUT9ANl/Y=", - "path": "google.golang.org/genproto/googleapis/iam/v1", - "revision": "fa694d86fc64c7654a660f8908de4e879866748d", - "revisionTime": "2019-08-01T16:59:51Z" - }, - { - "checksumSHA1": "EOkBjXBkCQcsEf9fk2KOQZcJO08=", - "path": "google.golang.org/genproto/googleapis/rpc/code", - "revision": "fa694d86fc64c7654a660f8908de4e879866748d", - "revisionTime": "2019-08-01T16:59:51Z" - }, - { - "checksumSHA1": "dU5fToNngC22+3DsebkdYv+T3jE=", - "path": "google.golang.org/genproto/googleapis/rpc/status", - "revision": "fa694d86fc64c7654a660f8908de4e879866748d", - "revisionTime": "2019-08-01T16:59:51Z" - }, - { - "checksumSHA1": "F1znYp6CXz3gZ0WGdy89d7jZgP4=", - "path": "google.golang.org/genproto/googleapis/type/expr", - "revision": "fa694d86fc64c7654a660f8908de4e879866748d", - "revisionTime": "2019-08-01T16:59:51Z" - }, - { - "checksumSHA1": "O6SQTcVdhL+4betKp/7ketCc/AU=", - "path": "google.golang.org/grpc", - "revision": "2e463a05d100327ca47ac218281906921038fd95", - "revisionTime": "2018-10-23T17:37:47Z", - "version": "v1.16.0", - "versionExact": "v1.16.0" - }, - { - "checksumSHA1": "9KEKKMRAdFnz2sMBXbb33ZLS8Oo=", - "path": "google.golang.org/grpc/balancer", - "revision": "2e463a05d100327ca47ac218281906921038fd95", - "revisionTime": "2018-10-23T17:37:47Z", - "version": "v1.16.0", - "versionExact": "v1.16.0" - }, - { - "checksumSHA1": "lw+L836hLeH8+//le+C+ycddCCU=", - "path": "google.golang.org/grpc/balancer/base", - "revision": "2e463a05d100327ca47ac218281906921038fd95", - "revisionTime": "2018-10-23T17:37:47Z", - "version": "v1.16.0", - "versionExact": "v1.16.0" - }, - { - "checksumSHA1": "ZD8cJs3NtFy3pzofoTThBvVVdKU=", - "path": "google.golang.org/grpc/balancer/grpclb", - "revision": "2e463a05d100327ca47ac218281906921038fd95", - "revisionTime": "2018-10-23T17:37:47Z", - "version": "v1.16.0", - "versionExact": "v1.16.0" - }, - { - "checksumSHA1": "CWf3yHL+DCM8pZETYCGA70C4JGM=", - "path": "google.golang.org/grpc/balancer/grpclb/grpc_lb_v1", - "revision": "2e463a05d100327ca47ac218281906921038fd95", - "revisionTime": "2018-10-23T17:37:47Z", - "version": "v1.16.0", - "versionExact": "v1.16.0" - }, - { - "checksumSHA1": "DJ1AtOk4Pu7bqtUMob95Hw8HPNw=", - "path": "google.golang.org/grpc/balancer/roundrobin", - "revision": "2e463a05d100327ca47ac218281906921038fd95", - "revisionTime": "2018-10-23T17:37:47Z", - "version": "v1.16.0", - "versionExact": "v1.16.0" - }, - { - "checksumSHA1": "R3tuACGAPyK4lr+oSNt1saUzC0M=", - "path": "google.golang.org/grpc/codes", - "revision": "2e463a05d100327ca47ac218281906921038fd95", - "revisionTime": "2018-10-23T17:37:47Z", - "version": "v1.16.0", - "versionExact": "v1.16.0" - }, - { - "checksumSHA1": "XH2WYcDNwVO47zYShREJjcYXm0Y=", - "path": "google.golang.org/grpc/connectivity", - "revision": "2e463a05d100327ca47ac218281906921038fd95", - "revisionTime": "2018-10-23T17:37:47Z", - "version": "v1.16.0", - "versionExact": "v1.16.0" - }, - { - "checksumSHA1": "5r6NIQY1c3NjwLtxUOo/BcUOqFo=", - "path": "google.golang.org/grpc/credentials", - "revision": "2e463a05d100327ca47ac218281906921038fd95", - "revisionTime": "2018-10-23T17:37:47Z", - "version": "v1.16.0", - "versionExact": "v1.16.0" - }, - { - "checksumSHA1": "RqDVFWVRXNIzSEge/L8JSMskEME=", - "path": "google.golang.org/grpc/credentials/alts", - "revision": "2e463a05d100327ca47ac218281906921038fd95", - "revisionTime": "2018-10-23T17:37:47Z", - "version": "v1.16.0", - "versionExact": "v1.16.0" - }, - { - "checksumSHA1": "qAUIOU0aukDblUKBw9Pbjzc+nW8=", - "path": "google.golang.org/grpc/credentials/alts/internal", - "revision": "2e463a05d100327ca47ac218281906921038fd95", - "revisionTime": "2018-10-23T17:37:47Z", - "version": "v1.16.0", - "versionExact": "v1.16.0" - }, - { - "checksumSHA1": "PTVv5w1hd88sHf2TJbctBasS4ck=", - "path": "google.golang.org/grpc/credentials/alts/internal/authinfo", - "revision": "2e463a05d100327ca47ac218281906921038fd95", - "revisionTime": "2018-10-23T17:37:47Z", - "version": "v1.16.0", - "versionExact": "v1.16.0" - }, - { - "checksumSHA1": "/s6U8ulRJiogFjFygs450dOeIoI=", - "path": "google.golang.org/grpc/credentials/alts/internal/conn", - "revision": "2e463a05d100327ca47ac218281906921038fd95", - "revisionTime": "2018-10-23T17:37:47Z", - "version": "v1.16.0", - "versionExact": "v1.16.0" - }, - { - "checksumSHA1": "znhrvWfbdiviJiZpekYHOi4TRmw=", - "path": "google.golang.org/grpc/credentials/alts/internal/handshaker", - "revision": "2e463a05d100327ca47ac218281906921038fd95", - "revisionTime": "2018-10-23T17:37:47Z", - "version": "v1.16.0", - "versionExact": "v1.16.0" - }, - { - "checksumSHA1": "CliKuySSTAK7m5iZuEA3fRiLHjg=", - "path": "google.golang.org/grpc/credentials/alts/internal/handshaker/service", - "revision": "2e463a05d100327ca47ac218281906921038fd95", - "revisionTime": "2018-10-23T17:37:47Z", - "version": "v1.16.0", - "versionExact": "v1.16.0" - }, - { - "checksumSHA1": "3/WS7uTk/B23ijy0PoHmIS/A76M=", - "path": "google.golang.org/grpc/credentials/alts/internal/proto/grpc_gcp", - "revision": "2e463a05d100327ca47ac218281906921038fd95", - "revisionTime": "2018-10-23T17:37:47Z", - "version": "v1.16.0", - "versionExact": "v1.16.0" - }, - { - "checksumSHA1": "KreBPF6lZnpT8psfiyRson0C9lI=", - "path": "google.golang.org/grpc/credentials/google", - "revision": "2e463a05d100327ca47ac218281906921038fd95", - "revisionTime": "2018-10-23T17:37:47Z", - "version": "v1.16.0", - "versionExact": "v1.16.0" - }, - { - "checksumSHA1": "QbufP1o0bXrtd5XecqdRCK/Vl0M=", - "path": "google.golang.org/grpc/credentials/oauth", - "revision": "8dea3dc473e90c8179e519d91302d0597c0ca1d1", - "revisionTime": "2018-09-11T17:48:51Z", - "version": "v1.15.0", - "versionExact": "v1.15.0" - }, - { - "checksumSHA1": "cfLb+pzWB+Glwp82rgfcEST1mv8=", - "path": "google.golang.org/grpc/encoding", - "revision": "2e463a05d100327ca47ac218281906921038fd95", - "revisionTime": "2018-10-23T17:37:47Z", - "version": "v1.16.0", - "versionExact": "v1.16.0" - }, - { - "checksumSHA1": "LKKkn7EYA+Do9Qwb2/SUKLFNxoo=", - "path": "google.golang.org/grpc/encoding/proto", - "revision": "2e463a05d100327ca47ac218281906921038fd95", - "revisionTime": "2018-10-23T17:37:47Z", - "version": "v1.16.0", - "versionExact": "v1.16.0" - }, - { - "checksumSHA1": "H7SuPUqbPcdbNqgl+k3ohuwMAwE=", - "path": "google.golang.org/grpc/grpclb/grpc_lb_v1/messages", - "revision": "d89cded64628466c4ab532d1f0ba5c220459ebe8", - "revisionTime": "2018-04-04T21:41:50Z", - "version": "v1.16.0", - "versionExact": "v1.16.0" - }, - { - "checksumSHA1": "ZPPSFisPDz2ANO4FBZIft+fRxyk=", - "path": "google.golang.org/grpc/grpclog", - "revision": "2e463a05d100327ca47ac218281906921038fd95", - "revisionTime": "2018-10-23T17:37:47Z", - "version": "v1.16.0", - "versionExact": "v1.16.0" - }, - { - "checksumSHA1": "QyasSHZlgle+PHSIQ2/p+fr+ihY=", - "path": "google.golang.org/grpc/grpclog/glogger", - "revision": "d89cded64628466c4ab532d1f0ba5c220459ebe8", - "revisionTime": "2018-04-04T21:41:50Z", - "version": "v1.11.2", - "versionExact": "v1.11.2" - }, - { - "checksumSHA1": "LVvnj/+AVrdZMDw0DZ8D/vI24+M=", - "path": "google.golang.org/grpc/internal", - "revision": "2e463a05d100327ca47ac218281906921038fd95", - "revisionTime": "2018-10-23T17:37:47Z", - "version": "v1.16.0", - "versionExact": "v1.16.0" - }, - { - "checksumSHA1": "uDJA7QK2iGnEwbd9TPqkLaM+xuU=", - "path": "google.golang.org/grpc/internal/backoff", - "revision": "2e463a05d100327ca47ac218281906921038fd95", - "revisionTime": "2018-10-23T17:37:47Z", - "version": "v1.16.0", - "versionExact": "v1.16.0" - }, - { - "checksumSHA1": "V6eyqZJfYh+cX+I/AxPVjkQLjTM=", - "path": "google.golang.org/grpc/internal/channelz", - "revision": "2e463a05d100327ca47ac218281906921038fd95", - "revisionTime": "2018-10-23T17:37:47Z", - "version": "v1.16.0", - "versionExact": "v1.16.0" - }, - { - "checksumSHA1": "5dFUCEaPjKwza9kwKqgljp8ckU4=", - "path": "google.golang.org/grpc/internal/envconfig", - "revision": "2e463a05d100327ca47ac218281906921038fd95", - "revisionTime": "2018-10-23T17:37:47Z", - "version": "v1.16.0", - "versionExact": "v1.16.0" - }, - { - "checksumSHA1": "70gndc/uHwyAl3D45zqp7vyHWlo=", - "path": "google.golang.org/grpc/internal/grpcrand", - "revision": "2e463a05d100327ca47ac218281906921038fd95", - "revisionTime": "2018-10-23T17:37:47Z", - "version": "v1.16.0", - "versionExact": "v1.16.0" - }, - { - "checksumSHA1": "0r7S4jTgUIatKqL/8ra0J7Q5iO0=", - "path": "google.golang.org/grpc/internal/transport", - "revision": "2e463a05d100327ca47ac218281906921038fd95", - "revisionTime": "2018-10-23T17:37:47Z", - "version": "v1.16.0", - "versionExact": "v1.16.0" - }, - { - "checksumSHA1": "350+v+N+AuknxomqjND19nR969g=", - "path": "google.golang.org/grpc/keepalive", - "revision": "2e463a05d100327ca47ac218281906921038fd95", - "revisionTime": "2018-10-23T17:37:47Z", - "version": "v1.16.0", - "versionExact": "v1.16.0" - }, - { - "checksumSHA1": "OjIAi5AzqlQ7kLtdAyjvdgMf6hc=", - "path": "google.golang.org/grpc/metadata", - "revision": "2e463a05d100327ca47ac218281906921038fd95", - "revisionTime": "2018-10-23T17:37:47Z", - "version": "v1.16.0", - "versionExact": "v1.16.0" - }, - { - "checksumSHA1": "VvGBoawND0urmYDy11FT+U1IHtU=", - "path": "google.golang.org/grpc/naming", - "revision": "2e463a05d100327ca47ac218281906921038fd95", - "revisionTime": "2018-10-23T17:37:47Z", - "version": "v1.16.0", - "versionExact": "v1.16.0" - }, - { - "checksumSHA1": "n5EgDdBqFMa2KQFhtl+FF/4gIFo=", - "path": "google.golang.org/grpc/peer", - "revision": "2e463a05d100327ca47ac218281906921038fd95", - "revisionTime": "2018-10-23T17:37:47Z", - "version": "v1.16.0", - "versionExact": "v1.16.0" - }, - { - "checksumSHA1": "GEq6wwE1qWLmkaM02SjxBmmnHDo=", - "path": "google.golang.org/grpc/resolver", - "revision": "2e463a05d100327ca47ac218281906921038fd95", - "revisionTime": "2018-10-23T17:37:47Z", - "version": "v1.16.0", - "versionExact": "v1.16.0" - }, - { - "checksumSHA1": "grHAHa6Fi3WBsXJpmlEOlRbWWVg=", - "path": "google.golang.org/grpc/resolver/dns", - "revision": "2e463a05d100327ca47ac218281906921038fd95", - "revisionTime": "2018-10-23T17:37:47Z", - "version": "v1.16.0", - "versionExact": "v1.16.0" - }, - { - "checksumSHA1": "zs9M4xE8Lyg4wvuYvR00XoBxmuw=", - "path": "google.golang.org/grpc/resolver/passthrough", - "revision": "2e463a05d100327ca47ac218281906921038fd95", - "revisionTime": "2018-10-23T17:37:47Z", - "version": "v1.16.0", - "versionExact": "v1.16.0" - }, - { - "checksumSHA1": "YclPgme2gT3S0hTkHVdE1zAxJdo=", - "path": "google.golang.org/grpc/stats", - "revision": "2e463a05d100327ca47ac218281906921038fd95", - "revisionTime": "2018-10-23T17:37:47Z", - "version": "v1.16.0", - "versionExact": "v1.16.0" - }, - { - "checksumSHA1": "hFyBO5vgsMamKhUOSyPCqROk1vo=", - "path": "google.golang.org/grpc/status", - "revision": "2e463a05d100327ca47ac218281906921038fd95", - "revisionTime": "2018-10-23T17:37:47Z", - "version": "v1.16.0", - "versionExact": "v1.16.0" - }, - { - "checksumSHA1": "qvArRhlrww5WvRmbyMF2mUfbJew=", - "path": "google.golang.org/grpc/tap", - "revision": "2e463a05d100327ca47ac218281906921038fd95", - "revisionTime": "2018-10-23T17:37:47Z", - "version": "v1.16.0", - "versionExact": "v1.16.0" - }, - { - "checksumSHA1": "sg7RY87LaWXaZMj0cuLQQaJJQYo=", - "path": "google.golang.org/grpc/transport", - "revision": "d89cded64628466c4ab532d1f0ba5c220459ebe8", - "revisionTime": "2018-04-04T21:41:50Z", - "version": "v1.16.0", - "versionExact": "v1.16.0" - }, - { - "checksumSHA1": "wSu8owMAP7GixsYoSZ4CmKUVhnU=", - "path": "gopkg.in/asn1-ber.v1", - "revision": "4e86f4367175e39f69d9358a5f17b4dda270378d", - "revisionTime": "2015-09-24T05:17:56Z" - }, - { - "checksumSHA1": "8yg3QdSXVEmuHm2CgWXEMFN3K6Q=", - "path": "gopkg.in/ini.v1", - "revision": "6ed8d5f64cd79a498d1f3fab5880cc376ce41bbe", - "revisionTime": "2019-01-03T01:53:35Z" - }, - { - "checksumSHA1": "itYnRitfdzJjy2mZlvJ+hCJZvtY=", - "path": "gopkg.in/ldap.v2", - "revision": "8168ee085ee43257585e50c6441aadf54ecb2c9f", - "revisionTime": "2016-12-01T20:47:33Z" - }, - { - "checksumSHA1": "12GqsW8PiRPnezDDy0v4brZrndM=", - "path": "gopkg.in/yaml.v2", - "revision": "a5b47d31c556af34a302ce5d659e6fea44d90de0", - "revisionTime": "2016-09-28T15:37:09Z" - } - ], - "rootPath": "vitess.io/vitess" -} From b845c016eeb6f7196d7356add14e0ba947b32ac9 Mon Sep 17 00:00:00 2001 From: Andres Taylor Date: Mon, 19 Aug 2019 12:28:39 +0200 Subject: [PATCH 003/425] Make it possible to serialize span contexts over strings Signed-off-by: Andres Taylor --- go/trace/fake.go | 1 + go/trace/opentracing.go | 16 ++++++++++++++-- go/trace/plugin_jaeger.go | 16 +++++++++++++++- go/trace/trace.go | 5 ++++- go/trace/trace_test.go | 2 +- 5 files changed, 35 insertions(+), 5 deletions(-) diff --git a/go/trace/fake.go b/go/trace/fake.go index f1f8be19dac..86691410335 100644 --- a/go/trace/fake.go +++ b/go/trace/fake.go @@ -28,6 +28,7 @@ type fakeSpanFactory struct{} func (fakeSpanFactory) New(Span, string) Span { return fakeSpan{} } func (fakeSpanFactory) NewClientSpan(parent Span, serviceName, label string) Span { return fakeSpan{} } func (fakeSpanFactory) FromContext(context.Context) (Span, bool) { return nil, false } +func (fakeSpanFactory) NewFromString(parent, label string) (Span, error) { return fakeSpan{}, nil } func (fakeSpanFactory) NewContext(parent context.Context, _ Span) context.Context { return parent } func (fakeSpanFactory) AddGrpcServerOptions(addInterceptors func(s grpc.StreamServerInterceptor, u grpc.UnaryServerInterceptor)) { } diff --git a/go/trace/opentracing.go b/go/trace/opentracing.go index ea41443de70..ec5244aa1be 100644 --- a/go/trace/opentracing.go +++ b/go/trace/opentracing.go @@ -16,10 +16,11 @@ limitations under the License. package trace import ( - "github.com/opentracing-contrib/go-grpc" + otgrpc "github.com/opentracing-contrib/go-grpc" "github.com/opentracing/opentracing-go" "golang.org/x/net/context" "google.golang.org/grpc" + "vitess.io/vitess/go/vt/vterrors" ) var _ Span = (*openTracingSpan)(nil) @@ -41,7 +42,9 @@ func (js openTracingSpan) Annotate(key string, value interface{}) { var _ tracingService = (*openTracingService)(nil) type openTracingService struct { - Tracer opentracing.Tracer + Tracer opentracing.Tracer + fromString func(string) (opentracing.SpanContext, error) + toString func(Span) string } // AddGrpcServerOptions is part of an interface implementation @@ -74,6 +77,15 @@ func (jf openTracingService) New(parent Span, label string) Span { return openTracingSpan{otSpan: innerSpan} } +func (jf openTracingService) NewFromString(parent, label string) (Span, error) { + spanContext, err := jf.fromString(parent) + if err != nil { + return nil, vterrors.Wrap(err, "failed to deserialize span context") + } + innerSpan := jf.Tracer.StartSpan(label, opentracing.ChildOf(spanContext)) + return openTracingSpan{otSpan: innerSpan}, nil +} + // FromContext is part of an interface implementation func (jf openTracingService) FromContext(ctx context.Context) (Span, bool) { innerSpan := opentracing.SpanFromContext(ctx) diff --git a/go/trace/plugin_jaeger.go b/go/trace/plugin_jaeger.go index 652cb42352c..abae1bfbe6d 100644 --- a/go/trace/plugin_jaeger.go +++ b/go/trace/plugin_jaeger.go @@ -56,6 +56,9 @@ var ( // JAEGER_AGENT_PORT func newJagerTracerFromEnv(serviceName string) (tracingService, io.Closer, error) { cfg, err := config.FromEnv() + if err != nil { + return nil, nil, err + } if cfg.ServiceName == "" { cfg.ServiceName = serviceName } @@ -79,7 +82,18 @@ func newJagerTracerFromEnv(serviceName string) (tracingService, io.Closer, error opentracing.SetGlobalTracer(tracer) - return openTracingService{tracer}, closer, nil + f1 := func(s string) (context opentracing.SpanContext, e error) { + // I don't understand why I have to do this and not just use `jaeger.ContextFromString` directly + return jaeger.ContextFromString(s) + } + + f2 := func(in Span) string { + otSpan := in.(*openTracingSpan) + jaegerSpanContext := otSpan.otSpan.Context().(*jaeger.SpanContext) + return jaegerSpanContext.String() + } + + return openTracingService{Tracer: tracer, fromString: f1, toString: f2}, closer, nil } func init() { diff --git a/go/trace/trace.go b/go/trace/trace.go index b52c4ceb901..e8e6923191b 100644 --- a/go/trace/trace.go +++ b/go/trace/trace.go @@ -91,7 +91,10 @@ type tracingService interface { // New creates a new span from an existing one, if provided. The parent can also be nil New(parent Span, label string) Span - // FromContext extracts a span from a context, making it possible to annotate the span with additional information. + // NewFromString creates a new span and uses the provided string to reconstitute the parent span + NewFromString(parent, label string) (Span, error) + + // FromContext extracts a span from a context, making it possible to annotate the span with additional information FromContext(ctx context.Context) (Span, bool) // NewContext creates a new context containing the provided span diff --git a/go/trace/trace_test.go b/go/trace/trace_test.go index 97cc3b2c2dd..97e86f4de93 100644 --- a/go/trace/trace_test.go +++ b/go/trace/trace_test.go @@ -93,7 +93,7 @@ type fakeTracer struct { log []string } -func (f *fakeTracer) NewClientSpan(parent Span, serviceName, label string) Span { +func (f *fakeTracer) NewFromString(parent, label string) (Span, error) { panic("implement me") } From 8d174a810194d9250a2911a199168965ffaea243 Mon Sep 17 00:00:00 2001 From: Andres Taylor Date: Mon, 19 Aug 2019 13:06:52 +0200 Subject: [PATCH 004/425] Minor clean ups Signed-off-by: Andres Taylor --- go/trace/fake.go | 20 ++++++++++---------- go/trace/opentracing.go | 5 ++--- go/trace/trace.go | 22 +++++++++++++--------- go/trace/trace_test.go | 2 +- 4 files changed, 26 insertions(+), 23 deletions(-) diff --git a/go/trace/fake.go b/go/trace/fake.go index 86691410335..7b5bd0d9b15 100644 --- a/go/trace/fake.go +++ b/go/trace/fake.go @@ -23,16 +23,16 @@ import ( "google.golang.org/grpc" ) -type fakeSpanFactory struct{} - -func (fakeSpanFactory) New(Span, string) Span { return fakeSpan{} } -func (fakeSpanFactory) NewClientSpan(parent Span, serviceName, label string) Span { return fakeSpan{} } -func (fakeSpanFactory) FromContext(context.Context) (Span, bool) { return nil, false } -func (fakeSpanFactory) NewFromString(parent, label string) (Span, error) { return fakeSpan{}, nil } -func (fakeSpanFactory) NewContext(parent context.Context, _ Span) context.Context { return parent } -func (fakeSpanFactory) AddGrpcServerOptions(addInterceptors func(s grpc.StreamServerInterceptor, u grpc.UnaryServerInterceptor)) { +type fakeTracingServer struct{} + +func (fakeTracingServer) New(Span, string) Span { return fakeSpan{} } +func (fakeTracingServer) NewClientSpan(parent Span, serviceName, label string) Span { return fakeSpan{} } +func (fakeTracingServer) FromContext(context.Context) (Span, bool) { return nil, false } +func (fakeTracingServer) NewFromString(parent, label string) (Span, error) { return fakeSpan{}, nil } +func (fakeTracingServer) NewContext(parent context.Context, _ Span) context.Context { return parent } +func (fakeTracingServer) AddGrpcServerOptions(addInterceptors func(s grpc.StreamServerInterceptor, u grpc.UnaryServerInterceptor)) { } -func (fakeSpanFactory) AddGrpcClientOptions(addInterceptors func(s grpc.StreamClientInterceptor, u grpc.UnaryClientInterceptor)) { +func (fakeTracingServer) AddGrpcClientOptions(addInterceptors func(s grpc.StreamClientInterceptor, u grpc.UnaryClientInterceptor)) { } // fakeSpan implements Span with no-op methods. @@ -43,6 +43,6 @@ func (fakeSpan) Annotate(string, interface{}) {} func init() { tracingBackendFactories["noop"] = func(_ string) (tracingService, io.Closer, error) { - return fakeSpanFactory{}, &nilCloser{}, nil + return fakeTracingServer{}, &nilCloser{}, nil } } diff --git a/go/trace/opentracing.go b/go/trace/opentracing.go index ec5244aa1be..6b47177d45b 100644 --- a/go/trace/opentracing.go +++ b/go/trace/opentracing.go @@ -90,11 +90,10 @@ func (jf openTracingService) NewFromString(parent, label string) (Span, error) { func (jf openTracingService) FromContext(ctx context.Context) (Span, bool) { innerSpan := opentracing.SpanFromContext(ctx) - if innerSpan != nil { - return openTracingSpan{otSpan: innerSpan}, true - } else { + if innerSpan == nil { return nil, false } + return openTracingSpan{otSpan: innerSpan}, true } // NewContext is part of an interface implementation diff --git a/go/trace/trace.go b/go/trace/trace.go index e8e6923191b..f1a4d0f639c 100644 --- a/go/trace/trace.go +++ b/go/trace/trace.go @@ -45,9 +45,9 @@ type Span interface { // NewSpan creates a new Span with the currently installed tracing plugin. // If no tracing plugin is installed, it returns a fake Span that does nothing. func NewSpan(inCtx context.Context, label string) (Span, context.Context) { - parent, _ := spanFactory.FromContext(inCtx) - span := spanFactory.New(parent, label) - outCtx := spanFactory.NewContext(inCtx, span) + parent, _ := currentTracer.FromContext(inCtx) + span := currentTracer.New(parent, label) + outCtx := currentTracer.NewContext(inCtx, span) return span, outCtx } @@ -61,12 +61,12 @@ func AnnotateSQL(span Span, sql string) { // FromContext returns the Span from a Context if present. The bool return // value indicates whether a Span was present in the Context. func FromContext(ctx context.Context) (Span, bool) { - return spanFactory.FromContext(ctx) + return currentTracer.FromContext(ctx) } // NewContext returns a context based on parent with a new Span value. func NewContext(parent context.Context, span Span) context.Context { - return spanFactory.NewContext(parent, span) + return currentTracer.NewContext(parent, span) } // CopySpan creates a new context from parentCtx, with only the trace span @@ -78,12 +78,14 @@ func CopySpan(parentCtx, spanCtx context.Context) context.Context { return parentCtx } +// AddGrpcServerOptions adds GRPC interceptors that read the parent span from the grpc packets func AddGrpcServerOptions(addInterceptors func(s grpc.StreamServerInterceptor, u grpc.UnaryServerInterceptor)) { - spanFactory.AddGrpcServerOptions(addInterceptors) + currentTracer.AddGrpcServerOptions(addInterceptors) } +// AddGrpcClientOptions adds GRPC interceptors that add parent information to outgoing grpc packets func AddGrpcClientOptions(addInterceptors func(s grpc.StreamClientInterceptor, u grpc.UnaryClientInterceptor)) { - spanFactory.AddGrpcClientOptions(addInterceptors) + currentTracer.AddGrpcClientOptions(addInterceptors) } // tracingService is an interface for creating spans or extracting them from Contexts. @@ -107,12 +109,14 @@ type tracingService interface { AddGrpcClientOptions(addInterceptors func(s grpc.StreamClientInterceptor, u grpc.UnaryClientInterceptor)) } +// TracerFactory creates a tracing service for the service provided. It's important to close the provided io.Closer +// object to make sure that all spans are sent to the backend before the process exits. type TracerFactory func(serviceName string) (tracingService, io.Closer, error) // tracingBackendFactories should be added to by a plugin during init() to install itself var tracingBackendFactories = make(map[string]TracerFactory) -var spanFactory tracingService = fakeSpanFactory{} +var currentTracer tracingService = fakeTracingServer{} var ( tracingServer = flag.String("tracer", "noop", "tracing service to use") @@ -131,7 +135,7 @@ func StartTracing(serviceName string) io.Closer { return &nilCloser{} } - spanFactory = tracer + currentTracer = tracer log.Infof("successfully started tracing with [%s]", *tracingServer) diff --git a/go/trace/trace_test.go b/go/trace/trace_test.go index 97e86f4de93..f7414b9bf31 100644 --- a/go/trace/trace_test.go +++ b/go/trace/trace_test.go @@ -37,7 +37,7 @@ func TestFakeSpan(t *testing.T) { span2.Annotate("key", 42) span2.Finish() - span3, ctx := NewSpan(ctx, "label") + span3, _ := NewSpan(ctx, "label") span3.Annotate("key", 42) span3.Finish() } From 930f6faa35c0e19de17015f38d028804befad613 Mon Sep 17 00:00:00 2001 From: Andres Taylor Date: Tue, 20 Aug 2019 11:02:49 +0200 Subject: [PATCH 005/425] Add functionality to extract spans from strings Signed-off-by: Andres Taylor --- go/trace/trace.go | 11 ++++++++++ go/vt/vtgate/plugin_mysql_server.go | 31 +++++++++++++++++++++++++++-- 2 files changed, 40 insertions(+), 2 deletions(-) diff --git a/go/trace/trace.go b/go/trace/trace.go index f1a4d0f639c..0e72cc21837 100644 --- a/go/trace/trace.go +++ b/go/trace/trace.go @@ -52,6 +52,17 @@ func NewSpan(inCtx context.Context, label string) (Span, context.Context) { return span, outCtx } +// NewFromString creates a new Span with the currently installed tracing plugin, extracting the span context from +// the provided string. +func NewFromString(inCtx context.Context, parent, label string) (Span, context.Context, error) { + span, err := currentTracer.NewFromString(parent, label) + if err != nil { + return nil, nil, err + } + outCtx := currentTracer.NewContext(inCtx, span) + return span, outCtx, nil +} + // AnnotateSQL annotates information about a sql query in the span. This is done in a way // so as to not leak personally identifying information (PII), or sensitive personal information (SPI) func AnnotateSQL(span Span, sql string) { diff --git a/go/vt/vtgate/plugin_mysql_server.go b/go/vt/vtgate/plugin_mysql_server.go index 85240db4804..050b9048f3f 100644 --- a/go/vt/vtgate/plugin_mysql_server.go +++ b/go/vt/vtgate/plugin_mysql_server.go @@ -21,10 +21,14 @@ import ( "fmt" "net" "os" + "regexp" "sync/atomic" "syscall" "time" + "vitess.io/vitess/go/vt/sqlparser" + "vitess.io/vitess/go/vt/vterrors" + "golang.org/x/net/context" "vitess.io/vitess/go/trace" @@ -99,6 +103,26 @@ func (vh *vtgateHandler) ConnectionClosed(c *mysql.Conn) { } } +// Regexp to extract parent span id over the sql query +var r = regexp.MustCompile("/\\*VT_SPAN_CONTEXT=(.*)\\*/") + +func startSpan(query, label string) (trace.Span, context.Context, error) { + _, comments := sqlparser.SplitMarginComments(query) + match := r.FindStringSubmatch(comments.Leading) + background := context.Background() + if len(match) == 0 { + span, ctx := trace.NewSpan(background, label) + trace.AnnotateSQL(span, query) + return span, ctx, nil + } + + span, ctx, err := trace.NewFromString(background, match[1], label) + if err != nil { + return nil, nil, err + } + return span, ctx, nil +} + func (vh *vtgateHandler) ComQuery(c *mysql.Conn, query string, callback func(*sqltypes.Result) error) error { ctx := context.Background() var cancel context.CancelFunc @@ -106,8 +130,11 @@ func (vh *vtgateHandler) ComQuery(c *mysql.Conn, query string, callback func(*sq ctx, cancel = context.WithTimeout(ctx, *mysqlQueryTimeout) defer cancel() } - span, ctx := trace.NewSpan(ctx, "vtgateHandler.ComQuery") - trace.AnnotateSQL(span, query) + + span, ctx, err := startSpan(query, "vtgateHandler.ComQuery") + if err != nil { + return vterrors.Wrap(err, "failed to extract span") + } defer span.Finish() ctx = callinfo.MysqlCallInfo(ctx, c) From fd131c8540b40b5e5734817f65180e22dbeb8885 Mon Sep 17 00:00:00 2001 From: Andres Taylor Date: Wed, 21 Aug 2019 09:54:07 +0200 Subject: [PATCH 006/425] Made span context extraction testable and added tests Signed-off-by: Andres Taylor --- go/trace/fake.go | 28 ++++++++--------- go/trace/trace.go | 2 +- go/vt/vtgate/plugin_mysql_server.go | 27 +++++++++++----- go/vt/vtgate/plugin_mysql_server_test.go | 40 ++++++++++++++++++++++++ 4 files changed, 74 insertions(+), 23 deletions(-) diff --git a/go/trace/fake.go b/go/trace/fake.go index 7b5bd0d9b15..a5394e05868 100644 --- a/go/trace/fake.go +++ b/go/trace/fake.go @@ -23,26 +23,26 @@ import ( "google.golang.org/grpc" ) -type fakeTracingServer struct{} - -func (fakeTracingServer) New(Span, string) Span { return fakeSpan{} } -func (fakeTracingServer) NewClientSpan(parent Span, serviceName, label string) Span { return fakeSpan{} } -func (fakeTracingServer) FromContext(context.Context) (Span, bool) { return nil, false } -func (fakeTracingServer) NewFromString(parent, label string) (Span, error) { return fakeSpan{}, nil } -func (fakeTracingServer) NewContext(parent context.Context, _ Span) context.Context { return parent } -func (fakeTracingServer) AddGrpcServerOptions(addInterceptors func(s grpc.StreamServerInterceptor, u grpc.UnaryServerInterceptor)) { +type noopTracingServer struct{} + +func (noopTracingServer) New(Span, string) Span { return NoopSpan{} } +func (noopTracingServer) NewClientSpan(parent Span, serviceName, label string) Span { return NoopSpan{} } +func (noopTracingServer) FromContext(context.Context) (Span, bool) { return nil, false } +func (noopTracingServer) NewFromString(parent, label string) (Span, error) { return NoopSpan{}, nil } +func (noopTracingServer) NewContext(parent context.Context, _ Span) context.Context { return parent } +func (noopTracingServer) AddGrpcServerOptions(addInterceptors func(s grpc.StreamServerInterceptor, u grpc.UnaryServerInterceptor)) { } -func (fakeTracingServer) AddGrpcClientOptions(addInterceptors func(s grpc.StreamClientInterceptor, u grpc.UnaryClientInterceptor)) { +func (noopTracingServer) AddGrpcClientOptions(addInterceptors func(s grpc.StreamClientInterceptor, u grpc.UnaryClientInterceptor)) { } -// fakeSpan implements Span with no-op methods. -type fakeSpan struct{} +// NoopSpan implements Span with no-op methods. +type NoopSpan struct{} -func (fakeSpan) Finish() {} -func (fakeSpan) Annotate(string, interface{}) {} +func (NoopSpan) Finish() {} +func (NoopSpan) Annotate(string, interface{}) {} func init() { tracingBackendFactories["noop"] = func(_ string) (tracingService, io.Closer, error) { - return fakeTracingServer{}, &nilCloser{}, nil + return noopTracingServer{}, &nilCloser{}, nil } } diff --git a/go/trace/trace.go b/go/trace/trace.go index 0e72cc21837..7d495bda4f7 100644 --- a/go/trace/trace.go +++ b/go/trace/trace.go @@ -127,7 +127,7 @@ type TracerFactory func(serviceName string) (tracingService, io.Closer, error) // tracingBackendFactories should be added to by a plugin during init() to install itself var tracingBackendFactories = make(map[string]TracerFactory) -var currentTracer tracingService = fakeTracingServer{} +var currentTracer tracingService = noopTracingServer{} var ( tracingServer = flag.String("tracer", "noop", "tracing service to use") diff --git a/go/vt/vtgate/plugin_mysql_server.go b/go/vt/vtgate/plugin_mysql_server.go index 050b9048f3f..9faf7f3201b 100644 --- a/go/vt/vtgate/plugin_mysql_server.go +++ b/go/vt/vtgate/plugin_mysql_server.go @@ -106,23 +106,34 @@ func (vh *vtgateHandler) ConnectionClosed(c *mysql.Conn) { // Regexp to extract parent span id over the sql query var r = regexp.MustCompile("/\\*VT_SPAN_CONTEXT=(.*)\\*/") -func startSpan(query, label string) (trace.Span, context.Context, error) { +// this function is here to make this logic easy to test by decoupling the logic from the `trace.NewSpan` and `trace.NewFromString` functions +func startSpanTestable(query, label string, + newSpan func(context.Context, string) (trace.Span, context.Context), + newSpanFromString func(context.Context, string, string) (trace.Span, context.Context, error)) (trace.Span, context.Context, error) { _, comments := sqlparser.SplitMarginComments(query) match := r.FindStringSubmatch(comments.Leading) background := context.Background() + var span trace.Span + var ctx context.Context if len(match) == 0 { - span, ctx := trace.NewSpan(background, label) - trace.AnnotateSQL(span, query) - return span, ctx, nil + span, ctx = newSpan(background, label) + } else { + var err error + span, ctx, err = newSpanFromString(background, match[1], label) + if err != nil { + return nil, nil, err + } } - span, ctx, err := trace.NewFromString(background, match[1], label) - if err != nil { - return nil, nil, err - } + trace.AnnotateSQL(span, query) + return span, ctx, nil } +func startSpan(query, label string) (trace.Span, context.Context, error) { + return startSpanTestable(query, label, trace.NewSpan, trace.NewFromString) +} + func (vh *vtgateHandler) ComQuery(c *mysql.Conn, query string, callback func(*sqltypes.Result) error) error { ctx := context.Background() var cancel context.CancelFunc diff --git a/go/vt/vtgate/plugin_mysql_server_test.go b/go/vt/vtgate/plugin_mysql_server_test.go index c190f053e83..14449a18575 100644 --- a/go/vt/vtgate/plugin_mysql_server_test.go +++ b/go/vt/vtgate/plugin_mysql_server_test.go @@ -22,6 +22,9 @@ import ( "strings" "testing" + "github.com/stretchr/testify/assert" + "vitess.io/vitess/go/trace" + "golang.org/x/net/context" "vitess.io/vitess/go/mysql" @@ -168,3 +171,40 @@ func TestConnectionRespectsExistingUnixSocket(t *testing.T) { t.Errorf("Error: %v, want prefix %s", err, want) } } + +var newSpanOK = func(ctx context.Context, label string) (trace.Span, context.Context) { + return trace.NoopSpan{}, context.Background() +} + +var newFromStringOK = func(ctx context.Context, spanContext, label string) (trace.Span, context.Context, error) { + return trace.NoopSpan{}, context.Background(), nil +} + +func newFromStringFail(t *testing.T) func(ctx context.Context, parentSpan string, label string) (trace.Span, context.Context, error) { + return func(ctx context.Context, parentSpan string, label string) (trace.Span, context.Context, error) { + t.Fatalf("we didn't provide a parent span in the sql query. this should not have been called. got: %v", parentSpan) + return trace.NoopSpan{}, context.Background(), nil + } +} + +func newSpanFail(t *testing.T) func(ctx context.Context, label string) (trace.Span, context.Context) { + return func(ctx context.Context, label string) (trace.Span, context.Context) { + t.Fatalf("we provided a span context but newFromString was not used as expected") + return trace.NoopSpan{}, context.Background() + } +} + +func TestNoSpanContextPassed(t *testing.T) { + _, _, err := startSpanTestable("sql without comments", "someLabel", newSpanOK, newFromStringFail(t)) + assert.NoError(t, err) +} + +func TestSpanContextNoPassedInButExistsInString(t *testing.T) { + _, _, err := startSpanTestable("SELECT * FROM SOMETABLE WHERE COL = \"/*VT_SPAN_CONTEXT=123*/", "someLabel", newSpanOK, newFromStringFail(t)) + assert.NoError(t, err) +} + +func TestSpanContextPassedIn(t *testing.T) { + _, _, err := startSpanTestable("/*VT_SPAN_CONTEXT=123*/SQL QUERY", "someLabel", newSpanFail(t), newFromStringOK) + assert.NoError(t, err) +} From dd2e2bc7e4bb64245bb6555f14ecb1389376efe5 Mon Sep 17 00:00:00 2001 From: Andres Taylor Date: Wed, 21 Aug 2019 15:29:08 +0200 Subject: [PATCH 007/425] Added test to make sure comments are handled correctly Signed-off-by: Andres Taylor --- .../planbuilder/testdata/select_cases.txt | 26 +++++++++++++++++++ go/vt/vtgate/plugin_mysql_server_test.go | 14 ++++++++++ 2 files changed, 40 insertions(+) diff --git a/go/vt/vtgate/planbuilder/testdata/select_cases.txt b/go/vt/vtgate/planbuilder/testdata/select_cases.txt index da728217844..e8885a33a28 100644 --- a/go/vt/vtgate/planbuilder/testdata/select_cases.txt +++ b/go/vt/vtgate/planbuilder/testdata/select_cases.txt @@ -154,6 +154,32 @@ } } +# select aggregation with partial scatter directive - added comments to try to confuse the hint extraction +"/*VT_SPAN_CONTEXT=123*/select /*vt+ SCATTER_ERRORS_AS_WARNINGS=1 */ count(*) from user" +{ + "Original": "/*VT_SPAN_CONTEXT=123*/select /*vt+ SCATTER_ERRORS_AS_WARNINGS=1 */ count(*) from user", + "Instructions": { + "Aggregates": [ + { + "Opcode": "count", + "Col": 0 + } + ], + "Keys": null, + "Input": { + "Opcode": "SelectScatter", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "Query": "select /*vt+ SCATTER_ERRORS_AS_WARNINGS=1 */ count(*) from user", + "FieldQuery": "select count(*) from user where 1 != 1", + "ScatterErrorsAsWarnings": true, + "Table": "user" + } + } +} + # select limit with partial scatter directive "select /*vt+ SCATTER_ERRORS_AS_WARNINGS=1 */ * from user limit 10" { diff --git a/go/vt/vtgate/plugin_mysql_server_test.go b/go/vt/vtgate/plugin_mysql_server_test.go index 14449a18575..4ac5f307c96 100644 --- a/go/vt/vtgate/plugin_mysql_server_test.go +++ b/go/vt/vtgate/plugin_mysql_server_test.go @@ -187,6 +187,13 @@ func newFromStringFail(t *testing.T) func(ctx context.Context, parentSpan string } } +func newFromStringExpect(t *testing.T, expected string) func(ctx context.Context, parentSpan string, label string) (trace.Span, context.Context, error) { + return func(ctx context.Context, parentSpan string, label string) (trace.Span, context.Context, error) { + assert.Equal(t, expected, parentSpan) + return trace.NoopSpan{}, context.Background(), nil + } +} + func newSpanFail(t *testing.T) func(ctx context.Context, label string) (trace.Span, context.Context) { return func(ctx context.Context, label string) (trace.Span, context.Context) { t.Fatalf("we provided a span context but newFromString was not used as expected") @@ -208,3 +215,10 @@ func TestSpanContextPassedIn(t *testing.T) { _, _, err := startSpanTestable("/*VT_SPAN_CONTEXT=123*/SQL QUERY", "someLabel", newSpanFail(t), newFromStringOK) assert.NoError(t, err) } + +func TestSpanContextPassedInEvenAroundOtherComments(t *testing.T) { + _, _, err := startSpanTestable("/*VT_SPAN_CONTEXT=123*/SELECT /*vt+ SCATTER_ERRORS_AS_WARNINGS */ col1, col2 FROM TABLE ", "someLabel", + newSpanFail(t), + newFromStringExpect(t, "123")) + assert.NoError(t, err) +} From 9e58664e5d2164a6d48a4584b2bfa6c08b251c04 Mon Sep 17 00:00:00 2001 From: Alex Charis Date: Wed, 21 Aug 2019 10:41:02 -0400 Subject: [PATCH 008/425] make vtgate query_plans endpoint return json; also fix comment typos Signed-off-by: Alex Charis --- go/cache/lru_cache.go | 4 ++-- go/vt/vtgate/executor.go | 22 ++++++++-------------- 2 files changed, 10 insertions(+), 16 deletions(-) diff --git a/go/cache/lru_cache.go b/go/cache/lru_cache.go index 819240ca6f4..a94482e74a3 100644 --- a/go/cache/lru_cache.go +++ b/go/cache/lru_cache.go @@ -222,7 +222,7 @@ func (lru *LRUCache) Oldest() (oldest time.Time) { } // Keys returns all the keys for the cache, ordered from most recently -// used to last recently used. +// used to least recently used. func (lru *LRUCache) Keys() []string { lru.mu.Lock() defer lru.mu.Unlock() @@ -235,7 +235,7 @@ func (lru *LRUCache) Keys() []string { } // Items returns all the values for the cache, ordered from most recently -// used to last recently used. +// used to least recently used. func (lru *LRUCache) Items() []Item { lru.mu.Lock() defer lru.mu.Unlock() diff --git a/go/vt/vtgate/executor.go b/go/vt/vtgate/executor.go index dba611676b2..1c6f8e04133 100644 --- a/go/vt/vtgate/executor.go +++ b/go/vt/vtgate/executor.go @@ -1345,20 +1345,15 @@ func (e *Executor) ServeHTTP(response http.ResponseWriter, request *http.Request return } if request.URL.Path == "/debug/query_plans" { - keys := e.plans.Keys() - response.Header().Set("Content-Type", "text/plain") - response.Write([]byte(fmt.Sprintf("Length: %d\n", len(keys)))) - for _, v := range keys { - response.Write([]byte(fmt.Sprintf("%#v\n", sqlparser.TruncateForUI(v)))) - if plan, ok := e.plans.Peek(v); ok { - if b, err := json.MarshalIndent(plan, "", " "); err != nil { - response.Write([]byte(err.Error())) - } else { - response.Write(b) - } - response.Write(([]byte)("\n\n")) - } + response.Header().Set("Content-Type", "application/json; charset=utf-8") + buf, err := json.MarshalIndent(e.plans.Items(), "", " ") + if err != nil { + response.Write([]byte(err.Error())) + return } + ebuf := bytes.NewBuffer(nil) + json.HTMLEscape(ebuf, buf) + response.Write(ebuf.Bytes()) } else if request.URL.Path == "/debug/vschema" { response.Header().Set("Content-Type", "application/json; charset=utf-8") b, err := json.MarshalIndent(e.VSchema(), "", " ") @@ -1384,7 +1379,6 @@ func (e *Executor) updateQueryCounts(planType, keyspace, tableName string, shard queriesRouted.Add(planType, shardQueries) queriesProcessedByTable.Add([]string{planType, keyspace, tableName}, 1) queriesRoutedByTable.Add([]string{planType, keyspace, tableName}, shardQueries) - return } // VSchemaStats returns the loaded vschema stats. From c5a3bcf38a734ba0737d4ad7336d6ba6a05cdb7d Mon Sep 17 00:00:00 2001 From: Sugu Sougoumarane Date: Fri, 23 Aug 2019 12:29:16 -0700 Subject: [PATCH 009/425] vreplication: improved rowstreamer For composite primary keys, mysql comes up with a full table scan for conditions like (pk1,pk2) > (1, 2). This change rewrites that condition to: (pk1 = 1 and pk2 > 2) or (pk1 > 1) Also removed the autocommit=0. It's not material to set that for obtaining read locks. Signed-off-by: Sugu Sougoumarane --- .../tabletserver/vstreamer/rowstreamer.go | 28 ++++++++----------- .../vstreamer/rowstreamer_test.go | 6 ++-- 2 files changed, 15 insertions(+), 19 deletions(-) diff --git a/go/vt/vttablet/tabletserver/vstreamer/rowstreamer.go b/go/vt/vttablet/tabletserver/vstreamer/rowstreamer.go index 82d3b04ad5b..c4114d451c0 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/rowstreamer.go +++ b/go/vt/vttablet/tabletserver/vstreamer/rowstreamer.go @@ -147,20 +147,20 @@ func (rs *rowStreamer) buildSelect() (string, error) { if len(rs.lastpk) != len(rs.pkColumns) { return "", fmt.Errorf("primary key values don't match length: %v vs %v", rs.lastpk, rs.pkColumns) } - buf.WriteString(" where (") + buf.WriteString(" where ") prefix := "" - for _, pk := range rs.pkColumns { - buf.Myprintf("%s%v", prefix, rs.plan.Table.Columns[pk].Name) - prefix = "," - } - buf.WriteString(") > (") - prefix = "" - for _, val := range rs.lastpk { - buf.WriteString(prefix) - prefix = "," - val.EncodeSQL(buf) + for lastcol := len(rs.pkColumns) - 1; lastcol >= 0; lastcol-- { + buf.Myprintf("%s(", prefix) + prefix = " or " + for i, pk := range rs.pkColumns[:lastcol] { + buf.Myprintf("%v = ", rs.plan.Table.Columns[pk].Name) + rs.lastpk[i].EncodeSQL(buf) + buf.Myprintf(" and ") + } + buf.Myprintf("%v > ", rs.plan.Table.Columns[rs.pkColumns[lastcol]].Name) + rs.lastpk[lastcol].EncodeSQL(buf) + buf.Myprintf(")") } - buf.WriteString(")") } buf.Myprintf(" order by ", sqlparser.NewTableIdent(rs.plan.Table.Name)) prefix = "" @@ -271,10 +271,6 @@ func (rs *rowStreamer) startStreaming(conn *mysql.Conn) (string, error) { }() log.Infof("Locking table %s for copying", rs.plan.Table.Name) - // mysql recommends this before locking tables. - if _, err := lockConn.ExecuteFetch("set autocommit=0", 0, false); err != nil { - return "", err - } if _, err := lockConn.ExecuteFetch(fmt.Sprintf("lock tables %s read", sqlparser.String(sqlparser.NewTableIdent(rs.plan.Table.Name))), 0, false); err != nil { return "", err } diff --git a/go/vt/vttablet/tabletserver/vstreamer/rowstreamer_test.go b/go/vt/vttablet/tabletserver/vstreamer/rowstreamer_test.go index 5266b3fe864..184496c8eb5 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/rowstreamer_test.go +++ b/go/vt/vttablet/tabletserver/vstreamer/rowstreamer_test.go @@ -63,7 +63,7 @@ func TestStreamRowsScan(t *testing.T) { `fields: fields: pkfields: `, `rows: lastpk: `, } - wantQuery = "select id, val from t1 where (id) > (1) order by id" + wantQuery = "select id, val from t1 where (id > 1) order by id" checkStream(t, "select * from t1", []sqltypes.Value{sqltypes.NewInt64(1)}, wantQuery, wantStream) // t1: different column ordering @@ -87,7 +87,7 @@ func TestStreamRowsScan(t *testing.T) { `fields: fields: fields: pkfields: pkfields: `, `rows: lastpk: `, } - wantQuery = "select id1, id2, val from t2 where (id1,id2) > (1,2) order by id1, id2" + wantQuery = "select id1, id2, val from t2 where (id1 = 1 and id2 > 2) or (id1 > 1) order by id1, id2" checkStream(t, "select * from t2", []sqltypes.Value{sqltypes.NewInt64(1), sqltypes.NewInt64(2)}, wantQuery, wantStream) // t3: all rows @@ -103,7 +103,7 @@ func TestStreamRowsScan(t *testing.T) { `fields: fields: pkfields: pkfields: `, `rows: lastpk: `, } - wantQuery = "select id, val from t3 where (id,val) > (1,'aaa') order by id, val" + wantQuery = "select id, val from t3 where (id = 1 and val > 'aaa') or (id > 1) order by id, val" checkStream(t, "select * from t3", []sqltypes.Value{sqltypes.NewInt64(1), sqltypes.NewVarBinary("aaa")}, wantQuery, wantStream) } From 1a43e41322b6028ba345dc8da67e88e9fa620a1e Mon Sep 17 00:00:00 2001 From: chentanjun <2799194073@qq.com> Date: Mon, 26 Aug 2019 11:23:07 +0800 Subject: [PATCH 010/425] fix-up typo Signed-off-by: chentanjun <2799194073@qq.com> --- .../src/main/java/io/vitess/hadoop/VitessRecordReader.java | 2 +- java/jdbc/src/main/java/io/vitess/jdbc/VitessConnection.java | 2 +- .../test/java/io/vitess/jdbc/VitessDatabaseMetadataTest.java | 2 +- proto/query.proto | 2 +- proto/tabletmanagerservice.proto | 2 +- proto/topodata.proto | 2 +- proto/vtrpc.proto | 2 +- py/vtdb/__init__.py | 2 +- py/vtdb/proto3_encoding.py | 2 +- py/vtdb/vtrouting.py | 2 +- py/vtproto/tabletmanagerservice_pb2_grpc.py | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/java/hadoop/src/main/java/io/vitess/hadoop/VitessRecordReader.java b/java/hadoop/src/main/java/io/vitess/hadoop/VitessRecordReader.java index e8b83d9d6ce..34461b1c7e1 100644 --- a/java/hadoop/src/main/java/io/vitess/hadoop/VitessRecordReader.java +++ b/java/hadoop/src/main/java/io/vitess/hadoop/VitessRecordReader.java @@ -51,7 +51,7 @@ public class VitessRecordReader extends RecordReader private Query.ExecuteOptions.IncludedFields includedFields; /** - * Fetch connection parameters from Configuraiton and open VtGate connection. + * Fetch connection parameters from Configuration and open VtGate connection. */ @Override public void initialize(InputSplit split, TaskAttemptContext context) diff --git a/java/jdbc/src/main/java/io/vitess/jdbc/VitessConnection.java b/java/jdbc/src/main/java/io/vitess/jdbc/VitessConnection.java index 1dac94c92a6..ab8effe5223 100644 --- a/java/jdbc/src/main/java/io/vitess/jdbc/VitessConnection.java +++ b/java/jdbc/src/main/java/io/vitess/jdbc/VitessConnection.java @@ -339,7 +339,7 @@ public void setTransactionIsolation(int level) throws SQLException { /** * Return Warnings *

- * TODO: Not implementing as Error is Thrown when occured + * TODO: Not implementing as Error is Thrown when occurred * * @return SQLWarning or null */ diff --git a/java/jdbc/src/test/java/io/vitess/jdbc/VitessDatabaseMetadataTest.java b/java/jdbc/src/test/java/io/vitess/jdbc/VitessDatabaseMetadataTest.java index 9da77d6f039..bb60534761c 100644 --- a/java/jdbc/src/test/java/io/vitess/jdbc/VitessDatabaseMetadataTest.java +++ b/java/jdbc/src/test/java/io/vitess/jdbc/VitessDatabaseMetadataTest.java @@ -1436,7 +1436,7 @@ public void getUserNameTest() { Assert.assertEquals("username", vitessDatabaseMetaData.getUserName()); } catch (SQLException e) { - Assert.fail("Exception Occured: " + e.getMessage()); + Assert.fail("Exception occurred: " + e.getMessage()); } } diff --git a/proto/query.proto b/proto/query.proto index 7c902f68631..f94a7aa7399 100644 --- a/proto/query.proto +++ b/proto/query.proto @@ -327,7 +327,7 @@ message Field { // charset is actually a uint16. Only the lower 16 bits are used. uint32 charset = 8; - // decimals is actualy a uint8. Only the lower 8 bits are used. + // decimals is actually a uint8. Only the lower 8 bits are used. uint32 decimals = 9; // flags is actually a uint16. Only the lower 16 bits are used. diff --git a/proto/tabletmanagerservice.proto b/proto/tabletmanagerservice.proto index 467f249851d..24ae6af881f 100644 --- a/proto/tabletmanagerservice.proto +++ b/proto/tabletmanagerservice.proto @@ -151,7 +151,7 @@ service TabletManager { // reparent journal rpc PopulateReparentJournal(tabletmanagerdata.PopulateReparentJournalRequest) returns (tabletmanagerdata.PopulateReparentJournalResponse) {}; - // InitSlave tells the tablet to reparent to the master unconditionnally + // InitSlave tells the tablet to reparent to the master unconditionally rpc InitSlave(tabletmanagerdata.InitSlaveRequest) returns (tabletmanagerdata.InitSlaveResponse) {}; // DemoteMaster tells the soon-to-be-former master it's gonna change diff --git a/proto/topodata.proto b/proto/topodata.proto index 2677f721911..87758a1f930 100644 --- a/proto/topodata.proto +++ b/proto/topodata.proto @@ -185,7 +185,7 @@ message Shard { repeated ServedType served_types = 3; // SourceShard represents a data source for filtered replication - // accross shards. When this is used in a destination shard, the master + // across shards. When this is used in a destination shard, the master // of that shard will run filtered replication. message SourceShard { // Uid is the unique ID for this SourceShard object. diff --git a/proto/vtrpc.proto b/proto/vtrpc.proto index 9d659ff4347..32c46090990 100644 --- a/proto/vtrpc.proto +++ b/proto/vtrpc.proto @@ -174,7 +174,7 @@ enum Code { // LegacyErrorCode is the enum values for Errors. This type is deprecated. // Use Code instead. Background: In the initial design, we thought // that we may end up with a different list of canonical error codes -// than the ones defined by grpc. In hindisght, we realize that +// than the ones defined by grpc. In hindsight, we realize that // the grpc error codes are fairly generic and mostly sufficient. // In order to avoid confusion, this type will be deprecated in // favor of the new Code that matches exactly what grpc defines. diff --git a/py/vtdb/__init__.py b/py/vtdb/__init__.py index 302cdcb6eb6..d6f10bd6b56 100644 --- a/py/vtdb/__init__.py +++ b/py/vtdb/__init__.py @@ -21,7 +21,7 @@ apilevel = '2.0' # Threads may share the module, but not connections. -# (we store session information in the conection now, that should be in the +# (we store session information in the connection now, that should be in the # cursor but are not for historical reasons). threadsafety = 2 diff --git a/py/vtdb/proto3_encoding.py b/py/vtdb/proto3_encoding.py index 5ed551242fc..446dac3e23b 100644 --- a/py/vtdb/proto3_encoding.py +++ b/py/vtdb/proto3_encoding.py @@ -68,7 +68,7 @@ } # legacy_code_to_code_map maps legacy error codes -# to the new code that matches grpc's cannonical error codes. +# to the new code that matches grpc's canonical error codes. legacy_code_to_code_map = { vtrpc_pb2.SUCCESS_LEGACY: vtrpc_pb2.OK, vtrpc_pb2.CANCELLED_LEGACY: vtrpc_pb2.CANCELED, diff --git a/py/vtdb/vtrouting.py b/py/vtdb/vtrouting.py index 3265f2e0be1..5ceba775276 100644 --- a/py/vtdb/vtrouting.py +++ b/py/vtdb/vtrouting.py @@ -24,7 +24,7 @@ information. The routing information object is supposed to be opaque to the client but VTGate uses it to route queries. It is also used to compute the associated where clause to be added -to the query, wich is needed to prevent returning duplicate result +to the query, which is needed to prevent returning duplicate result from two parallelized queries running over the same shard. API usage - diff --git a/py/vtproto/tabletmanagerservice_pb2_grpc.py b/py/vtproto/tabletmanagerservice_pb2_grpc.py index d7133c24429..0cdae4b3898 100644 --- a/py/vtproto/tabletmanagerservice_pb2_grpc.py +++ b/py/vtproto/tabletmanagerservice_pb2_grpc.py @@ -514,7 +514,7 @@ def PopulateReparentJournal(self, request, context): raise NotImplementedError('Method not implemented!') def InitSlave(self, request, context): - """InitSlave tells the tablet to reparent to the master unconditionnally + """InitSlave tells the tablet to reparent to the master unconditionally """ context.set_code(grpc.StatusCode.UNIMPLEMENTED) context.set_details('Method not implemented!') From 453d54b4c181c3e42deb7ff3c296886c5883d13c Mon Sep 17 00:00:00 2001 From: Karel Alfonso Sague Date: Fri, 16 Aug 2019 11:56:31 +1000 Subject: [PATCH 011/425] Allow setting key/value metadata stored in the topology Signed-off-by: Karel Alfonso Sague --- go/vt/sqlparser/analyzer.go | 3 + go/vt/sqlparser/ast.go | 7 +- go/vt/sqlparser/like_filter.go | 34 + go/vt/sqlparser/like_filter_test.go | 73 + go/vt/sqlparser/sql.go | 4838 +++++++++++++------------- go/vt/sqlparser/sql.y | 20 +- go/vt/sqlparser/token.go | 1 + go/vt/topo/events/metadata_change.go | 7 + go/vt/topo/metadata.go | 92 + go/vt/topo/server.go | 1 + go/vt/vtgate/executor.go | 67 +- go/vt/vtgate/executor_test.go | 63 + 12 files changed, 2781 insertions(+), 2425 deletions(-) create mode 100644 go/vt/sqlparser/like_filter.go create mode 100644 go/vt/sqlparser/like_filter_test.go create mode 100644 go/vt/topo/events/metadata_change.go create mode 100644 go/vt/topo/metadata.go diff --git a/go/vt/sqlparser/analyzer.go b/go/vt/sqlparser/analyzer.go index 6d4db548ad0..5a73541de8d 100644 --- a/go/vt/sqlparser/analyzer.go +++ b/go/vt/sqlparser/analyzer.go @@ -285,6 +285,9 @@ func ExtractSetValues(sql string) (keyValues map[SetKey]interface{}, scope strin case strings.HasPrefix(key, "@@session."): scope = SessionStr key = strings.TrimPrefix(key, "@@session.") + case strings.HasPrefix(key, "@@vitess_metadata."): + scope = VitessMetadataStr + key = strings.TrimPrefix(key, "@@vitess_metadata.") case strings.HasPrefix(key, "@@"): key = strings.TrimPrefix(key, "@@") } diff --git a/go/vt/sqlparser/ast.go b/go/vt/sqlparser/ast.go index 2ea7762ac31..f10a7abe9f3 100644 --- a/go/vt/sqlparser/ast.go +++ b/go/vt/sqlparser/ast.go @@ -662,9 +662,10 @@ type Set struct { // Set.Scope or Show.Scope const ( - SessionStr = "session" - GlobalStr = "global" - ImplicitStr = "" + SessionStr = "session" + GlobalStr = "global" + VitessMetadataStr = "vitess_metadata" + ImplicitStr = "" ) // Format formats the node. diff --git a/go/vt/sqlparser/like_filter.go b/go/vt/sqlparser/like_filter.go new file mode 100644 index 00000000000..598cb491185 --- /dev/null +++ b/go/vt/sqlparser/like_filter.go @@ -0,0 +1,34 @@ +package sqlparser + +import ( + "fmt" + "regexp" + "strings" +) + +var ( + re = regexp.MustCompile(`([^\\]?|[\\]{2})[%_]`) +) + +func replacer(s string) string { + if strings.HasPrefix(s, `\\`) { + return s[2:] + } + + result := strings.Replace(s, "%" ,".*", -1) + result = strings.Replace(result, "_", ".", -1) + + return result +} + +// LikeToRegexp converts a like sql expression to regular expression +func LikeToRegexp(likeExpr string) *regexp.Regexp { + if likeExpr == "" { + return regexp.MustCompile("^.*$") // Can never fail + } + + keyPattern := regexp.QuoteMeta(likeExpr) + keyPattern = re.ReplaceAllStringFunc(keyPattern, replacer) + keyPattern = fmt.Sprintf("^%s$", keyPattern) + return regexp.MustCompile(keyPattern) // Can never fail +} diff --git a/go/vt/sqlparser/like_filter_test.go b/go/vt/sqlparser/like_filter_test.go new file mode 100644 index 00000000000..c44d6ff65ef --- /dev/null +++ b/go/vt/sqlparser/like_filter_test.go @@ -0,0 +1,73 @@ +package sqlparser + +import ( + "github.com/stretchr/testify/assert" + "testing" +) + +func TestEmptyLike(t *testing.T) { + want := "^.*$" + got := LikeToRegexp("").String() + + assert.Equal(t, want, got) +} + +func TestLikePrefixRegexp(t *testing.T) { + show, e := Parse("show vitess_metadata variables like 'key%'") + if e != nil { + t.Error(e) + } + + want := "^key.*$" + got := LikeToRegexp(show.(*Show).ShowTablesOpt.Filter.Like).String() + + assert.Equal(t, want, got) +} + +func TestLikeAnyCharsRegexp(t *testing.T) { + show, e := Parse("show vitess_metadata variables like '%val1%val2%'") + if e != nil { + t.Error(e) + } + + want := "^.*val1.*val2.*$" + got := LikeToRegexp(show.(*Show).ShowTablesOpt.Filter.Like).String() + + assert.Equal(t, want, got) +} + +func TestSingleAndMultipleCharsRegexp(t *testing.T) { + show, e := Parse("show vitess_metadata variables like '_val1_val2%'") + if e != nil { + t.Error(e) + } + + want := "^.val1.val2.*$" + got := LikeToRegexp(show.(*Show).ShowTablesOpt.Filter.Like).String() + + assert.Equal(t, want, got) +} + +func TestSpecialCharactersRegexp(t *testing.T) { + show, e := Parse("show vitess_metadata variables like '?.*?'") + if e != nil { + t.Error(e) + } + + want := "^\\?\\.\\*\\?$" + got := LikeToRegexp(show.(*Show).ShowTablesOpt.Filter.Like).String() + + assert.Equal(t, want, got) +} + +func TestQuoteLikeSpecialCharacters(t *testing.T) { + show, e := Parse(`show vitess_metadata variables like 'part1_part2\\%part3_part4\\_part5%'`) + if e != nil { + t.Error(e) + } + + want := "^part1.part2%part3.part4_part5.*$" + got := LikeToRegexp(show.(*Show).ShowTablesOpt.Filter.Like).String() + + assert.Equal(t, want, got) +} diff --git a/go/vt/sqlparser/sql.go b/go/vt/sqlparser/sql.go index 94b2965fc5b..36987cd9297 100644 --- a/go/vt/sqlparser/sql.go +++ b/go/vt/sqlparser/sql.go @@ -304,52 +304,53 @@ const ZEROFILL = 57539 const COLLATION = 57540 const DATABASES = 57541 const TABLES = 57542 -const VSCHEMA = 57543 -const FULL = 57544 -const PROCESSLIST = 57545 -const COLUMNS = 57546 -const FIELDS = 57547 -const ENGINES = 57548 -const PLUGINS = 57549 -const NAMES = 57550 -const CHARSET = 57551 -const GLOBAL = 57552 -const SESSION = 57553 -const ISOLATION = 57554 -const LEVEL = 57555 -const READ = 57556 -const WRITE = 57557 -const ONLY = 57558 -const REPEATABLE = 57559 -const COMMITTED = 57560 -const UNCOMMITTED = 57561 -const SERIALIZABLE = 57562 -const CURRENT_TIMESTAMP = 57563 -const DATABASE = 57564 -const CURRENT_DATE = 57565 -const CURRENT_TIME = 57566 -const LOCALTIME = 57567 -const LOCALTIMESTAMP = 57568 -const UTC_DATE = 57569 -const UTC_TIME = 57570 -const UTC_TIMESTAMP = 57571 -const REPLACE = 57572 -const CONVERT = 57573 -const CAST = 57574 -const SUBSTR = 57575 -const SUBSTRING = 57576 -const GROUP_CONCAT = 57577 -const SEPARATOR = 57578 -const TIMESTAMPADD = 57579 -const TIMESTAMPDIFF = 57580 -const MATCH = 57581 -const AGAINST = 57582 -const BOOLEAN = 57583 -const LANGUAGE = 57584 -const WITH = 57585 -const QUERY = 57586 -const EXPANSION = 57587 -const UNUSED = 57588 +const VITESS_METADATA = 57543 +const VSCHEMA = 57544 +const FULL = 57545 +const PROCESSLIST = 57546 +const COLUMNS = 57547 +const FIELDS = 57548 +const ENGINES = 57549 +const PLUGINS = 57550 +const NAMES = 57551 +const CHARSET = 57552 +const GLOBAL = 57553 +const SESSION = 57554 +const ISOLATION = 57555 +const LEVEL = 57556 +const READ = 57557 +const WRITE = 57558 +const ONLY = 57559 +const REPEATABLE = 57560 +const COMMITTED = 57561 +const UNCOMMITTED = 57562 +const SERIALIZABLE = 57563 +const CURRENT_TIMESTAMP = 57564 +const DATABASE = 57565 +const CURRENT_DATE = 57566 +const CURRENT_TIME = 57567 +const LOCALTIME = 57568 +const LOCALTIMESTAMP = 57569 +const UTC_DATE = 57570 +const UTC_TIME = 57571 +const UTC_TIMESTAMP = 57572 +const REPLACE = 57573 +const CONVERT = 57574 +const CAST = 57575 +const SUBSTR = 57576 +const SUBSTRING = 57577 +const GROUP_CONCAT = 57578 +const SEPARATOR = 57579 +const TIMESTAMPADD = 57580 +const TIMESTAMPDIFF = 57581 +const MATCH = 57582 +const AGAINST = 57583 +const BOOLEAN = 57584 +const LANGUAGE = 57585 +const WITH = 57586 +const QUERY = 57587 +const EXPANSION = 57588 +const UNUSED = 57589 var yyToknames = [...]string{ "$end", @@ -569,6 +570,7 @@ var yyToknames = [...]string{ "COLLATION", "DATABASES", "TABLES", + "VITESS_METADATA", "VSCHEMA", "FULL", "PROCESSLIST", @@ -632,1358 +634,1340 @@ var yyExca = [...]int{ 5, 29, -2, 4, -1, 37, - 159, 296, - 160, 296, - -2, 286, - -1, 260, - 112, 636, - -2, 632, - -1, 261, - 112, 637, - -2, 633, - -1, 329, - 82, 811, + 159, 299, + 160, 299, + -2, 287, + -1, 262, + 112, 639, + -2, 635, + -1, 263, + 112, 640, + -2, 636, + -1, 331, + 82, 814, -2, 63, - -1, 330, - 82, 767, + -1, 332, + 82, 770, -2, 64, - -1, 335, - 82, 746, - -2, 598, -1, 337, - 82, 788, - -2, 600, - -1, 606, - 1, 348, - 5, 348, - 12, 348, - 13, 348, - 14, 348, - 15, 348, - 17, 348, - 19, 348, - 30, 348, - 31, 348, - 42, 348, - 43, 348, - 44, 348, - 45, 348, - 46, 348, - 48, 348, - 49, 348, - 52, 348, - 53, 348, - 55, 348, - 56, 348, - 264, 348, - -2, 366, + 82, 749, + -2, 601, + -1, 339, + 82, 791, + -2, 603, -1, 609, + 1, 351, + 5, 351, + 12, 351, + 13, 351, + 14, 351, + 15, 351, + 17, 351, + 19, 351, + 30, 351, + 31, 351, + 42, 351, + 43, 351, + 44, 351, + 45, 351, + 46, 351, + 48, 351, + 49, 351, + 52, 351, + 53, 351, + 55, 351, + 56, 351, + 265, 351, + -2, 369, + -1, 612, 53, 44, 55, 44, -2, 48, - -1, 755, - 112, 639, - -2, 635, - -1, 983, + -1, 760, + 112, 642, + -2, 638, + -1, 989, 5, 30, - -2, 433, - -1, 1013, - 5, 29, - -2, 572, - -1, 1257, - 5, 30, - -2, 573, - -1, 1310, + -2, 436, + -1, 1019, 5, 29, -2, 575, - -1, 1388, + -1, 1263, 5, 30, -2, 576, + -1, 1316, + 5, 29, + -2, 578, + -1, 1394, + 5, 30, + -2, 579, } const yyPrivate = 57344 -const yyLast = 12651 +const yyLast = 12449 var yyAct = [...]int{ - 261, 1412, 1219, 1422, 1322, 1376, 1107, 265, 1016, 1277, - 562, 1290, 1034, 868, 1159, 278, 1193, 841, 239, 897, - 891, 57, 291, 864, 839, 1156, 1017, 1160, 911, 948, - 1040, 1166, 81, 230, 867, 877, 205, 1061, 1172, 205, - 706, 1131, 334, 780, 790, 561, 3, 622, 975, 1087, - 843, 1078, 787, 881, 500, 828, 808, 757, 720, 494, - 621, 292, 51, 328, 907, 435, 603, 205, 81, 514, - 248, 602, 205, 323, 205, 821, 506, 263, 231, 232, - 233, 234, 320, 611, 237, 56, 1415, 325, 1399, 1410, - 1386, 1407, 608, 1220, 1398, 577, 1385, 238, 930, 1148, - 267, 1249, 440, 1049, 1188, 1189, 1048, 468, 252, 1050, - 859, 860, 929, 51, 1187, 576, 200, 196, 197, 198, - 623, 244, 624, 858, 192, 236, 194, 303, 202, 309, - 310, 307, 308, 306, 305, 304, 488, 235, 1069, 890, - 934, 1109, 61, 311, 312, 1280, 898, 484, 453, 928, - 485, 482, 483, 1297, 1240, 1238, 229, 1111, 695, 322, - 477, 478, 692, 1409, 437, 1406, 439, 1377, 63, 64, - 65, 66, 67, 470, 464, 472, 1351, 527, 526, 536, - 537, 529, 530, 531, 532, 533, 534, 535, 528, 694, - 1106, 538, 822, 205, 1110, 487, 205, 696, 1369, 925, - 922, 923, 205, 921, 1430, 469, 471, 1094, 205, 882, - 454, 81, 1331, 81, 1323, 81, 81, 193, 81, 442, - 81, 1035, 1037, 693, 1103, 81, 1426, 1325, 194, 1112, - 1105, 699, 685, 199, 932, 935, 1092, 1182, 527, 526, - 536, 537, 529, 530, 531, 532, 533, 534, 535, 528, - 1181, 1180, 538, 438, 884, 81, 445, 884, 207, 195, - 942, 550, 551, 941, 502, 1358, 1260, 1118, 1045, 490, - 491, 927, 465, 450, 465, 1002, 465, 465, 969, 465, - 992, 465, 989, 1062, 898, 446, 465, 729, 452, 467, - 503, 976, 617, 926, 459, 1324, 865, 518, 1036, 460, - 461, 528, 538, 1093, 538, 1384, 51, 854, 1098, 1095, - 1088, 1096, 1091, 1332, 1330, 726, 1089, 1090, 205, 205, - 205, 547, 512, 511, 549, 513, 1104, 81, 1102, 1152, - 1097, 931, 1424, 81, 721, 1425, 447, 1423, 448, 513, - 1205, 449, 1367, 601, 1352, 1340, 933, 456, 457, 458, - 883, 1150, 560, 883, 564, 565, 566, 567, 568, 569, - 570, 571, 572, 548, 575, 578, 578, 578, 584, 578, - 578, 584, 578, 592, 593, 594, 595, 596, 597, 884, - 607, 764, 550, 551, 550, 551, 988, 473, 504, 474, - 475, 1206, 476, 1170, 479, 762, 763, 761, 950, 489, - 580, 582, 610, 586, 588, 615, 591, 70, 436, 436, - 600, 511, 609, 789, 619, 722, 512, 511, 625, 606, - 579, 581, 583, 585, 587, 589, 590, 513, 809, 987, - 999, 986, 466, 513, 441, 205, 512, 511, 809, 687, - 81, 1067, 434, 71, 1372, 205, 205, 81, 512, 511, - 887, 205, 191, 513, 205, 1392, 888, 205, 966, 967, - 968, 205, 508, 81, 81, 513, 1431, 258, 81, 81, - 81, 205, 81, 81, 1390, 883, 949, 54, 81, 81, - 880, 878, 1286, 879, 747, 749, 750, 760, 876, 882, - 748, 1132, 529, 530, 531, 532, 533, 534, 535, 528, - 331, 465, 538, 708, 1285, 1432, 81, 781, 465, 782, - 205, 443, 444, 1082, 1081, 1070, 81, 317, 318, 22, - 1368, 734, 732, 733, 465, 465, 1304, 633, 1134, 465, - 465, 465, 1283, 465, 465, 728, 700, 689, 690, 465, - 465, 1115, 1079, 697, 758, 1051, 322, 1052, 1365, 703, - 531, 532, 533, 534, 535, 528, 1328, 1408, 538, 753, - 81, 755, 1136, 714, 1140, 1222, 1135, 1062, 1133, 1057, - 512, 511, 727, 1138, 493, 736, 783, 799, 802, 243, - 1394, 493, 1137, 810, 705, 751, 704, 513, 688, 512, - 511, 1328, 1380, 81, 81, 1139, 1141, 1328, 493, 1337, - 205, 813, 743, 1328, 1359, 1336, 513, 686, 205, 205, - 794, 51, 205, 205, 684, 683, 205, 205, 205, 81, - 462, 691, 759, 1328, 1327, 1202, 564, 455, 784, 785, - 1275, 1274, 81, 1262, 493, 885, 849, 709, 710, 848, - 851, 612, 711, 712, 713, 1169, 715, 716, 818, 806, - 1259, 493, 717, 718, 1212, 1211, 1208, 1209, 1208, 1207, - 708, 792, 893, 894, 895, 896, 899, 900, 901, 840, - 981, 493, 1041, 607, 825, 493, 1041, 607, 904, 905, - 906, 856, 855, 792, 493, 847, 205, 81, 613, 81, - 852, 613, 823, 81, 81, 205, 205, 205, 872, 205, - 205, 632, 631, 205, 81, 850, 1157, 58, 606, 1169, - 1255, 913, 606, 1339, 1121, 825, 606, 825, 24, 1169, - 205, 24, 205, 205, 1210, 205, 824, 1053, 857, 1005, - 614, 1004, 616, 614, 981, 612, 552, 553, 554, 555, - 556, 557, 558, 559, 909, 910, 1309, 981, 465, 54, - 465, 825, 281, 280, 283, 284, 285, 286, 981, 331, - 493, 282, 287, 612, 618, 465, 54, 245, 730, 54, - 957, 698, 755, 830, 833, 834, 835, 831, 916, 832, - 836, 1400, 1292, 892, 758, 958, 24, 938, 939, 940, - 1267, 943, 944, 912, 959, 945, 1198, 527, 526, 536, - 537, 529, 530, 531, 532, 533, 534, 535, 528, 1056, - 1011, 538, 947, 908, 1012, 54, 970, 953, 903, 971, - 1173, 1174, 1417, 902, 1108, 1293, 205, 205, 205, 205, - 205, 915, 1018, 1413, 54, 1200, 1176, 1157, 205, 1083, - 492, 205, 724, 702, 742, 205, 1028, 1026, 1179, 205, - 1178, 1029, 1027, 1030, 1025, 834, 835, 1024, 249, 250, - 1404, 917, 759, 919, 998, 1397, 1117, 1013, 81, 954, - 507, 1402, 964, 1042, 290, 963, 1074, 630, 946, 1066, - 1043, 1054, 1044, 1014, 1015, 505, 794, 607, 607, 607, - 607, 607, 1031, 1020, 1021, 1039, 1023, 1019, 463, 495, - 1022, 1374, 840, 1373, 1038, 1046, 79, 1307, 1288, 1064, - 607, 496, 1058, 1071, 1072, 1253, 81, 81, 918, 1063, - 701, 1073, 838, 1075, 1076, 1077, 606, 606, 606, 606, - 606, 246, 247, 1059, 1060, 962, 507, 240, 1345, 241, - 58, 606, 333, 961, 1344, 1295, 81, 1041, 486, 606, - 993, 754, 990, 254, 1086, 1080, 830, 833, 834, 835, - 831, 205, 832, 836, 1419, 1418, 1173, 1174, 719, 509, - 81, 1419, 1099, 1355, 1281, 725, 60, 62, 465, 795, - 796, 55, 1, 801, 804, 805, 1411, 1221, 756, 1289, - 924, 765, 766, 767, 768, 769, 770, 771, 772, 773, - 774, 775, 776, 777, 778, 779, 1114, 465, 817, 1375, - 819, 820, 1321, 1192, 875, 81, 81, 866, 1149, 1018, - 1158, 1125, 69, 1124, 433, 68, 1130, 1366, 874, 873, - 1143, 1142, 1329, 1279, 886, 1161, 1068, 889, 1199, 81, - 1065, 1371, 638, 957, 636, 755, 814, 1168, 637, 635, - 640, 331, 639, 1119, 81, 634, 81, 81, 218, 326, - 1163, 1177, 1184, 837, 869, 626, 914, 510, 72, 1191, - 1183, 1101, 1100, 1186, 1162, 920, 51, 480, 481, 220, - 546, 960, 1047, 332, 205, 333, 1164, 333, 1190, 333, - 333, 1085, 333, 1195, 333, 1203, 1204, 1196, 1197, 333, - 731, 205, 499, 1343, 1294, 735, 997, 81, 573, 807, - 81, 81, 81, 205, 266, 746, 279, 276, 277, 81, - 1113, 1214, 205, 737, 1010, 520, 264, 256, 605, 516, - 598, 829, 827, 1215, 826, 1217, 321, 1175, 1171, 604, - 1120, 1248, 1350, 741, 1227, 26, 1229, 59, 251, 19, - 18, 1228, 17, 1233, 1234, 965, 1235, 20, 16, 1237, - 15, 1239, 754, 791, 793, 1236, 536, 537, 529, 530, - 531, 532, 533, 534, 535, 528, 1213, 1018, 538, 14, - 451, 30, 21, 607, 1254, 13, 12, 11, 10, 9, - 1263, 81, 8, 1216, 497, 501, 1264, 7, 6, 81, - 5, 333, 980, 1273, 1054, 1226, 4, 627, 242, 23, - 1247, 519, 2, 0, 81, 1276, 0, 0, 0, 0, - 996, 81, 606, 0, 0, 0, 0, 1282, 0, 1284, - 972, 973, 974, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1269, 1270, 1271, 0, 563, 0, 0, 0, - 0, 0, 0, 0, 1296, 574, 0, 0, 0, 0, - 81, 81, 0, 81, 0, 0, 0, 0, 81, 0, - 81, 81, 81, 205, 0, 465, 81, 1316, 1161, 1317, - 1318, 1319, 1315, 1308, 0, 0, 0, 0, 0, 0, - 1320, 0, 1326, 81, 205, 0, 0, 1333, 0, 0, - 869, 0, 1341, 0, 1310, 0, 1334, 0, 1335, 0, - 0, 0, 0, 0, 333, 0, 0, 1162, 0, 0, - 1311, 333, 0, 0, 1356, 0, 1364, 0, 0, 81, - 0, 0, 1161, 1363, 0, 0, 0, 333, 333, 0, - 81, 81, 333, 333, 333, 0, 333, 333, 0, 0, - 1338, 1378, 333, 333, 1379, 0, 1382, 1357, 0, 81, - 0, 0, 0, 1018, 1387, 0, 0, 0, 0, 0, - 205, 1162, 0, 51, 0, 0, 0, 0, 81, 0, - 738, 0, 0, 0, 0, 978, 1342, 1396, 1287, 979, - 516, 0, 0, 333, 0, 0, 983, 984, 985, 1403, - 1401, 81, 1123, 991, 0, 0, 994, 995, 0, 0, - 1405, 0, 1001, 1416, 0, 0, 1003, 0, 0, 1006, - 1007, 1008, 1009, 1427, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 786, 1153, 0, 0, 0, 0, - 723, 1033, 0, 0, 1127, 1128, 0, 0, 0, 0, - 811, 0, 0, 0, 0, 0, 0, 1144, 1145, 0, - 1146, 1147, 1391, 0, 0, 744, 745, 815, 816, 0, - 0, 1414, 1154, 1155, 0, 24, 25, 52, 27, 28, - 0, 0, 0, 0, 0, 0, 869, 0, 869, 0, - 0, 0, 0, 333, 43, 0, 0, 1252, 0, 29, - 48, 49, 0, 0, 0, 0, 333, 526, 536, 537, - 529, 530, 531, 532, 533, 534, 535, 528, 563, 38, - 538, 797, 798, 54, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1201, 527, 526, 536, 537, 529, - 530, 531, 532, 533, 534, 535, 528, 0, 0, 538, - 0, 1123, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 333, 0, 333, 0, 0, 0, 936, 937, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 333, 863, - 0, 0, 1129, 0, 31, 32, 34, 33, 36, 0, - 50, 0, 0, 0, 1231, 1246, 0, 0, 0, 0, - 0, 0, 1251, 0, 333, 0, 0, 0, 0, 0, - 0, 37, 44, 45, 0, 215, 46, 47, 35, 0, - 0, 0, 0, 869, 0, 0, 0, 0, 0, 498, - 0, 0, 39, 40, 0, 41, 42, 0, 0, 224, - 527, 526, 536, 537, 529, 530, 531, 532, 533, 534, - 535, 528, 0, 1291, 538, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 203, 0, 0, 228, 527, - 526, 536, 537, 529, 530, 531, 532, 533, 534, 535, - 528, 955, 956, 538, 501, 0, 0, 0, 0, 0, - 208, 0, 0, 255, 0, 0, 324, 211, 0, 811, - 0, 203, 0, 203, 0, 219, 214, 0, 0, 0, - 0, 1298, 1299, 1300, 1301, 1302, 53, 0, 0, 1305, - 1306, 0, 0, 0, 0, 0, 1230, 1126, 0, 0, - 0, 0, 0, 1232, 0, 0, 0, 217, 0, 0, - 0, 0, 333, 223, 1241, 1242, 982, 527, 526, 536, - 537, 529, 530, 531, 532, 533, 534, 535, 528, 0, - 0, 538, 0, 1000, 1256, 1257, 1258, 0, 1261, 0, - 209, 0, 1291, 869, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1272, 0, 0, 0, 0, - 1084, 333, 0, 0, 0, 0, 0, 221, 212, 0, - 222, 227, 0, 0, 0, 213, 216, 0, 210, 226, - 225, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 333, 0, 203, 0, 0, 203, 0, 0, 0, 0, - 0, 203, 0, 0, 0, 0, 0, 203, 0, 0, - 0, 0, 0, 522, 333, 525, 0, 0, 0, 0, - 1303, 539, 540, 541, 542, 543, 544, 545, 1245, 523, - 524, 521, 527, 526, 536, 537, 529, 530, 531, 532, - 533, 534, 535, 528, 0, 0, 538, 333, 0, 0, - 0, 0, 1420, 0, 0, 0, 811, 1244, 0, 1165, - 1167, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1346, 1347, 1348, 1349, 1116, 0, 0, 1353, 1354, 0, - 0, 0, 0, 1167, 0, 0, 0, 0, 0, 1360, - 1361, 1362, 1243, 0, 0, 0, 0, 0, 333, 0, - 333, 1194, 527, 526, 536, 537, 529, 530, 531, 532, - 533, 534, 535, 528, 0, 0, 538, 203, 203, 203, - 0, 0, 1383, 1151, 0, 0, 0, 0, 0, 1388, - 0, 527, 526, 536, 537, 529, 530, 531, 532, 533, - 534, 535, 528, 0, 0, 538, 0, 1393, 0, 0, - 0, 1218, 0, 0, 1223, 1224, 1225, 0, 0, 0, - 0, 0, 0, 333, 0, 1185, 527, 526, 536, 537, - 529, 530, 531, 532, 533, 534, 535, 528, 977, 0, - 538, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1428, 1429, 0, 0, 0, 0, 527, 526, - 536, 537, 529, 530, 531, 532, 533, 534, 535, 528, - 0, 0, 538, 0, 811, 527, 526, 536, 537, 529, - 530, 531, 532, 533, 534, 535, 528, 0, 0, 538, - 0, 0, 0, 0, 203, 333, 0, 0, 0, 0, - 0, 0, 0, 1278, 203, 203, 0, 0, 0, 0, - 203, 0, 0, 203, 0, 0, 203, 0, 333, 0, - 707, 0, 0, 0, 0, 333, 0, 0, 0, 0, - 203, 0, 0, 0, 0, 0, 1250, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 563, 0, 0, 0, - 0, 0, 0, 0, 1265, 0, 0, 1266, 0, 0, - 1268, 0, 0, 0, 1312, 1313, 0, 1314, 0, 203, - 0, 0, 1278, 0, 1278, 1278, 1278, 0, 707, 0, - 1194, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1278, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 255, 0, 0, 0, 0, 255, 255, 0, 0, 255, - 255, 255, 0, 1370, 0, 812, 0, 0, 0, 0, - 0, 0, 0, 0, 333, 333, 0, 0, 0, 0, - 0, 0, 0, 0, 255, 255, 255, 255, 0, 203, - 811, 0, 0, 1389, 0, 0, 0, 203, 845, 0, - 0, 203, 203, 0, 0, 203, 853, 707, 0, 0, - 0, 0, 1395, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1278, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1381, 563, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 203, 0, 0, 0, 0, - 0, 0, 0, 0, 203, 203, 203, 0, 203, 203, - 0, 0, 203, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 203, - 0, 951, 952, 0, 203, 0, 0, 0, 0, 707, - 0, 0, 0, 0, 0, 139, 0, 0, 0, 844, - 0, 255, 0, 0, 103, 0, 0, 0, 0, 0, - 120, 0, 122, 0, 0, 160, 131, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 204, 0, 846, 0, 0, 0, - 0, 0, 0, 96, 0, 0, 0, 0, 255, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 812, 203, 203, 203, 203, 203, - 0, 0, 0, 0, 0, 0, 0, 1032, 109, 0, - 203, 0, 206, 0, 845, 0, 0, 146, 203, 163, - 111, 119, 83, 90, 0, 110, 137, 151, 155, 0, - 0, 0, 99, 0, 153, 141, 176, 0, 142, 152, - 123, 168, 147, 175, 183, 184, 165, 182, 186, 157, - 84, 164, 174, 97, 156, 86, 172, 162, 129, 115, - 116, 85, 0, 150, 102, 107, 101, 138, 169, 170, - 100, 189, 91, 181, 88, 92, 180, 136, 167, 173, - 130, 127, 87, 171, 128, 126, 118, 105, 112, 144, - 125, 145, 113, 133, 132, 134, 0, 0, 0, 161, - 178, 190, 94, 0, 166, 185, 0, 0, 95, 108, - 104, 143, 135, 93, 114, 158, 117, 124, 149, 188, - 140, 154, 98, 177, 159, 0, 0, 0, 0, 0, - 203, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 255, 0, 0, 0, 82, 89, 121, 187, 148, 106, - 179, 255, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 707, 0, 0, 0, 0, 0, 0, 0, - 0, 812, 139, 0, 0, 0, 0, 262, 0, 0, - 0, 103, 0, 259, 0, 0, 0, 120, 302, 122, - 0, 0, 160, 131, 0, 0, 0, 0, 293, 294, - 0, 0, 0, 0, 0, 0, 861, 0, 54, 0, - 0, 260, 281, 280, 283, 284, 285, 286, 0, 0, - 96, 282, 287, 288, 289, 862, 0, 0, 257, 274, - 0, 301, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 203, 0, 0, 0, 0, 0, 0, - 0, 271, 272, 0, 0, 0, 0, 315, 0, 273, - 203, 0, 268, 269, 270, 275, 0, 0, 0, 0, - 0, 0, 203, 0, 0, 109, 0, 0, 0, 206, - 0, 203, 313, 0, 146, 0, 163, 111, 119, 83, - 90, 0, 110, 137, 151, 155, 0, 0, 0, 99, - 0, 153, 141, 176, 0, 142, 152, 123, 168, 147, - 175, 183, 184, 165, 182, 186, 157, 84, 164, 174, - 97, 156, 86, 172, 162, 129, 115, 116, 85, 812, - 150, 102, 107, 101, 138, 169, 170, 100, 189, 91, - 181, 88, 92, 180, 136, 167, 173, 130, 127, 87, - 171, 128, 126, 118, 105, 112, 144, 125, 145, 113, - 133, 132, 134, 0, 0, 0, 161, 178, 190, 94, - 0, 166, 185, 0, 0, 95, 108, 104, 143, 135, - 93, 114, 158, 117, 124, 149, 188, 140, 154, 98, - 177, 159, 303, 314, 309, 310, 307, 308, 306, 305, - 304, 316, 295, 296, 297, 298, 300, 0, 311, 312, - 299, 82, 89, 121, 187, 148, 106, 179, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 845, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 203, 0, 0, 0, 0, 0, 421, - 410, 0, 381, 424, 359, 373, 432, 374, 375, 403, - 345, 389, 139, 371, 0, 362, 340, 368, 341, 360, - 383, 103, 386, 358, 412, 392, 423, 120, 430, 122, - 397, 0, 160, 131, 0, 0, 385, 414, 387, 408, - 380, 404, 350, 396, 425, 372, 401, 426, 0, 0, - 0, 80, 0, 870, 871, 812, 0, 0, 0, 0, - 96, 0, 399, 420, 370, 400, 402, 339, 398, 203, - 343, 346, 431, 416, 365, 366, 1055, 0, 0, 0, - 0, 0, 0, 384, 388, 405, 378, 0, 0, 0, - 0, 0, 0, 0, 0, 363, 0, 395, 0, 0, - 0, 347, 344, 0, 0, 382, 0, 0, 0, 349, - 0, 364, 406, 0, 338, 109, 409, 415, 379, 206, - 419, 377, 376, 422, 146, 0, 163, 111, 119, 83, - 90, 0, 110, 137, 151, 155, 413, 361, 369, 99, - 367, 153, 141, 176, 394, 142, 152, 123, 168, 147, - 175, 183, 184, 165, 182, 186, 157, 84, 164, 174, - 97, 156, 86, 172, 162, 129, 115, 116, 85, 0, - 150, 102, 107, 101, 138, 169, 170, 100, 189, 91, - 181, 88, 92, 180, 136, 167, 173, 130, 127, 87, - 171, 128, 126, 118, 105, 112, 144, 125, 145, 113, - 133, 132, 134, 0, 342, 0, 161, 178, 190, 94, - 357, 166, 185, 0, 0, 95, 108, 104, 143, 135, - 93, 114, 158, 117, 124, 149, 188, 140, 154, 98, - 177, 159, 353, 356, 351, 352, 390, 391, 427, 428, - 429, 407, 348, 0, 354, 355, 0, 411, 417, 418, - 393, 82, 89, 121, 187, 148, 106, 179, 421, 410, - 0, 381, 424, 359, 373, 432, 374, 375, 403, 345, - 389, 139, 371, 0, 362, 340, 368, 341, 360, 383, - 103, 386, 358, 412, 392, 423, 120, 430, 122, 397, - 0, 160, 131, 0, 0, 385, 414, 387, 408, 380, - 404, 350, 396, 425, 372, 401, 426, 0, 0, 0, - 80, 0, 870, 871, 0, 0, 0, 0, 0, 96, - 0, 399, 420, 370, 400, 402, 339, 398, 0, 343, - 346, 431, 416, 365, 366, 0, 0, 0, 0, 0, - 0, 0, 384, 388, 405, 378, 0, 0, 0, 0, - 0, 0, 0, 0, 363, 0, 395, 0, 0, 0, - 347, 344, 0, 0, 382, 0, 0, 0, 349, 0, - 364, 406, 0, 338, 109, 409, 415, 379, 206, 419, - 377, 376, 422, 146, 0, 163, 111, 119, 83, 90, - 0, 110, 137, 151, 155, 413, 361, 369, 99, 367, - 153, 141, 176, 394, 142, 152, 123, 168, 147, 175, - 183, 184, 165, 182, 186, 157, 84, 164, 174, 97, - 156, 86, 172, 162, 129, 115, 116, 85, 0, 150, - 102, 107, 101, 138, 169, 170, 100, 189, 91, 181, - 88, 92, 180, 136, 167, 173, 130, 127, 87, 171, - 128, 126, 118, 105, 112, 144, 125, 145, 113, 133, - 132, 134, 0, 342, 0, 161, 178, 190, 94, 357, - 166, 185, 0, 0, 95, 108, 104, 143, 135, 93, - 114, 158, 117, 124, 149, 188, 140, 154, 98, 177, - 159, 353, 356, 351, 352, 390, 391, 427, 428, 429, - 407, 348, 0, 354, 355, 0, 411, 417, 418, 393, - 82, 89, 121, 187, 148, 106, 179, 421, 410, 0, - 381, 424, 359, 373, 432, 374, 375, 403, 345, 389, - 139, 371, 0, 362, 340, 368, 341, 360, 383, 103, - 386, 358, 412, 392, 423, 120, 430, 122, 397, 0, - 160, 131, 0, 0, 385, 414, 387, 408, 380, 404, - 350, 396, 425, 372, 401, 426, 54, 0, 0, 80, - 0, 0, 0, 0, 0, 0, 0, 0, 96, 0, - 399, 420, 370, 400, 402, 339, 398, 0, 343, 346, - 431, 416, 365, 366, 0, 0, 0, 0, 0, 0, - 0, 384, 388, 405, 378, 0, 0, 0, 0, 0, - 0, 0, 0, 363, 0, 395, 0, 0, 0, 347, - 344, 0, 0, 382, 0, 0, 0, 349, 0, 364, - 406, 0, 338, 109, 409, 415, 379, 206, 419, 377, - 376, 422, 146, 0, 163, 111, 119, 83, 90, 0, - 110, 137, 151, 155, 413, 361, 369, 99, 367, 153, - 141, 176, 394, 142, 152, 123, 168, 147, 175, 183, - 184, 165, 182, 186, 157, 84, 164, 174, 97, 156, - 86, 172, 162, 129, 115, 116, 85, 0, 150, 102, - 107, 101, 138, 169, 170, 100, 189, 91, 181, 88, - 92, 180, 136, 167, 173, 130, 127, 87, 171, 128, - 126, 118, 105, 112, 144, 125, 145, 113, 133, 132, - 134, 0, 342, 0, 161, 178, 190, 94, 357, 166, - 185, 0, 0, 95, 108, 104, 143, 135, 93, 114, - 158, 117, 124, 149, 188, 140, 154, 98, 177, 159, - 353, 356, 351, 352, 390, 391, 427, 428, 429, 407, - 348, 0, 354, 355, 0, 411, 417, 418, 393, 82, - 89, 121, 187, 148, 106, 179, 421, 410, 0, 381, - 424, 359, 373, 432, 374, 375, 403, 345, 389, 139, - 371, 0, 362, 340, 368, 341, 360, 383, 103, 386, - 358, 412, 392, 423, 120, 430, 122, 397, 0, 160, - 131, 0, 0, 385, 414, 387, 408, 380, 404, 350, - 396, 425, 372, 401, 426, 0, 0, 0, 80, 0, - 0, 0, 0, 0, 0, 0, 0, 96, 0, 399, - 420, 370, 400, 402, 339, 398, 0, 343, 346, 431, - 416, 365, 366, 0, 0, 0, 0, 0, 0, 0, - 384, 388, 405, 378, 0, 0, 0, 0, 0, 0, - 1122, 0, 363, 0, 395, 0, 0, 0, 347, 344, - 0, 0, 382, 0, 0, 0, 349, 0, 364, 406, - 0, 338, 109, 409, 415, 379, 206, 419, 377, 376, - 422, 146, 0, 163, 111, 119, 83, 90, 0, 110, - 137, 151, 155, 413, 361, 369, 99, 367, 153, 141, - 176, 394, 142, 152, 123, 168, 147, 175, 183, 184, - 165, 182, 186, 157, 84, 164, 174, 97, 156, 86, + 263, 1428, 1418, 1225, 1382, 1022, 267, 565, 1165, 1283, + 873, 1040, 1296, 1328, 280, 1199, 846, 1113, 902, 1023, + 1162, 844, 1166, 916, 869, 953, 57, 293, 882, 872, + 1172, 241, 81, 1067, 709, 1137, 206, 1178, 785, 206, + 795, 1093, 336, 723, 1084, 833, 606, 625, 981, 886, + 813, 497, 762, 848, 792, 437, 1046, 503, 624, 330, + 826, 294, 51, 912, 232, 325, 509, 206, 81, 265, + 517, 614, 206, 250, 206, 327, 579, 56, 322, 1421, + 1405, 1416, 1392, 1413, 1226, 605, 1357, 530, 529, 539, + 540, 532, 533, 534, 535, 536, 537, 538, 531, 564, + 3, 541, 580, 1404, 254, 1391, 1154, 1255, 442, 233, + 234, 235, 236, 51, 626, 239, 627, 61, 1194, 1195, + 305, 246, 311, 312, 309, 310, 308, 307, 306, 1193, + 470, 201, 197, 198, 199, 1055, 313, 314, 1054, 864, + 865, 1056, 863, 63, 64, 65, 66, 67, 486, 1138, + 238, 240, 487, 484, 485, 237, 193, 935, 195, 491, + 1075, 895, 1115, 1286, 1303, 896, 903, 231, 1246, 1244, + 489, 934, 698, 479, 480, 1117, 697, 695, 1415, 1412, + 1383, 1112, 1375, 827, 887, 1436, 1140, 1041, 1043, 1337, + 1432, 1329, 455, 456, 206, 444, 472, 206, 474, 939, + 688, 195, 611, 206, 1331, 1118, 702, 1109, 933, 206, + 696, 699, 81, 1111, 81, 1116, 81, 81, 490, 81, + 1142, 81, 1146, 889, 1141, 1188, 1139, 81, 471, 473, + 1187, 1144, 889, 1186, 440, 889, 468, 447, 203, 208, + 1143, 196, 452, 947, 553, 554, 946, 998, 1364, 200, + 194, 1266, 438, 1145, 1147, 1358, 1124, 81, 930, 927, + 928, 1068, 926, 1051, 1042, 1008, 975, 734, 466, 324, + 620, 505, 1330, 467, 439, 467, 441, 467, 467, 521, + 467, 462, 467, 1211, 531, 870, 541, 541, 467, 731, + 1338, 1336, 859, 937, 940, 903, 1430, 1373, 728, 1431, + 995, 1429, 493, 494, 333, 449, 516, 450, 51, 1110, + 451, 1108, 438, 469, 256, 1390, 724, 1346, 1100, 888, + 206, 206, 206, 550, 885, 883, 552, 884, 888, 81, + 932, 888, 881, 887, 1212, 81, 534, 535, 536, 537, + 538, 531, 604, 1176, 541, 436, 506, 1098, 955, 553, + 554, 628, 931, 733, 563, 1156, 567, 568, 569, 570, + 571, 572, 573, 574, 575, 507, 578, 581, 581, 581, + 587, 581, 581, 587, 581, 595, 596, 597, 598, 599, + 600, 70, 610, 582, 584, 586, 588, 590, 592, 593, + 732, 936, 458, 459, 460, 618, 448, 725, 814, 454, + 613, 443, 553, 554, 622, 461, 938, 515, 514, 583, + 585, 463, 589, 591, 1099, 594, 814, 71, 1005, 1104, + 1101, 1094, 1102, 1097, 516, 690, 954, 1095, 1096, 532, + 533, 534, 535, 536, 537, 538, 531, 206, 514, 541, + 994, 1103, 81, 972, 973, 974, 769, 206, 206, 81, + 737, 738, 892, 206, 516, 1073, 206, 1378, 893, 206, + 767, 768, 766, 206, 511, 81, 81, 1437, 1396, 1292, + 81, 81, 81, 206, 81, 81, 515, 514, 445, 446, + 81, 81, 475, 1158, 476, 477, 54, 478, 192, 481, + 515, 514, 993, 516, 992, 492, 765, 1291, 515, 514, + 515, 514, 786, 467, 787, 711, 1438, 516, 1088, 81, + 467, 515, 514, 206, 1087, 516, 1076, 516, 1057, 81, + 1058, 1398, 603, 22, 612, 1374, 467, 467, 516, 818, + 1310, 467, 467, 467, 703, 467, 467, 739, 752, 754, + 755, 467, 467, 1289, 753, 292, 1121, 1085, 958, 1334, + 1414, 496, 763, 319, 320, 1371, 758, 500, 504, 1400, + 496, 1334, 1386, 81, 760, 333, 283, 282, 285, 286, + 287, 288, 1334, 496, 522, 284, 289, 79, 1228, 804, + 807, 741, 1068, 245, 1063, 815, 1334, 1365, 1343, 756, + 1334, 1333, 1281, 1280, 1268, 496, 81, 81, 1265, 496, + 1218, 1217, 1342, 206, 1214, 1215, 1214, 1213, 1208, 566, + 788, 206, 206, 335, 51, 206, 206, 24, 577, 206, + 206, 206, 81, 789, 790, 987, 496, 830, 496, 567, + 797, 496, 54, 708, 707, 81, 854, 691, 689, 636, + 856, 1017, 811, 686, 616, 1018, 635, 634, 890, 692, + 693, 616, 464, 823, 457, 700, 24, 1163, 324, 1175, + 1175, 706, 829, 711, 1127, 54, 1406, 799, 904, 905, + 906, 1047, 845, 852, 797, 717, 610, 1047, 58, 1261, + 610, 860, 861, 24, 1315, 857, 617, 830, 619, 206, + 81, 877, 81, 617, 1345, 615, 81, 81, 206, 206, + 206, 830, 206, 206, 54, 1298, 206, 81, 987, 918, + 687, 853, 1216, 615, 830, 748, 1059, 694, 987, 862, + 1175, 1011, 1010, 206, 987, 206, 206, 615, 621, 735, + 206, 54, 897, 712, 713, 701, 1273, 917, 714, 715, + 716, 496, 718, 719, 1204, 1062, 914, 915, 720, 721, + 247, 467, 913, 467, 1179, 1180, 1114, 335, 759, 335, + 908, 335, 335, 907, 335, 1299, 335, 920, 467, 963, + 495, 1423, 335, 1419, 1206, 1182, 1163, 760, 530, 529, + 539, 540, 532, 533, 534, 535, 536, 537, 538, 531, + 1089, 965, 541, 964, 763, 729, 1034, 705, 54, 1032, + 1185, 1035, 519, 726, 1033, 828, 1036, 1184, 839, 840, + 898, 899, 900, 901, 747, 1031, 1030, 1410, 855, 977, + 1403, 976, 251, 252, 1123, 960, 909, 910, 911, 749, + 750, 206, 206, 206, 206, 206, 1024, 510, 1408, 794, + 970, 969, 1080, 206, 498, 633, 206, 465, 1072, 1380, + 206, 1379, 508, 1259, 206, 1313, 499, 269, 333, 1070, + 1064, 1294, 260, 1004, 923, 704, 843, 248, 249, 510, + 242, 874, 1351, 81, 335, 1048, 968, 243, 1026, 1027, + 630, 1029, 566, 1060, 967, 802, 803, 1037, 1020, 1021, + 58, 921, 610, 610, 610, 610, 610, 1350, 1301, 1047, + 943, 944, 945, 1045, 948, 949, 488, 845, 950, 1044, + 1052, 1049, 999, 1050, 996, 610, 1025, 1077, 1078, 1028, + 1069, 81, 81, 1425, 1424, 952, 1019, 1079, 722, 1081, + 1082, 1083, 959, 512, 1065, 1066, 1425, 1361, 1287, 730, + 60, 62, 55, 868, 1, 799, 1417, 1227, 1295, 929, + 1381, 81, 1327, 1086, 1198, 880, 871, 69, 922, 435, + 924, 68, 1372, 879, 878, 1335, 1285, 206, 891, 1105, + 1074, 759, 894, 1205, 1071, 951, 81, 1377, 835, 838, + 839, 840, 836, 467, 837, 841, 641, 335, 1179, 1180, + 1092, 639, 640, 638, 335, 643, 1120, 539, 540, 532, + 533, 534, 535, 536, 537, 538, 531, 642, 637, 541, + 335, 335, 467, 219, 328, 335, 335, 335, 842, 335, + 335, 81, 81, 1164, 1024, 335, 335, 1131, 1136, 1155, + 1149, 1130, 1148, 629, 919, 513, 740, 72, 1107, 1106, + 925, 727, 482, 963, 483, 81, 1167, 961, 962, 221, + 504, 760, 549, 966, 743, 1053, 334, 1170, 736, 502, + 81, 1349, 81, 81, 519, 1300, 1183, 335, 1003, 576, + 812, 268, 1197, 1190, 751, 1189, 281, 278, 279, 1174, + 1168, 742, 51, 1016, 523, 266, 258, 608, 601, 1196, + 206, 834, 1201, 832, 796, 798, 831, 323, 1181, 1202, + 1203, 1177, 1209, 1210, 607, 1192, 1126, 206, 791, 874, + 1254, 1356, 988, 81, 746, 26, 81, 81, 81, 206, + 1169, 59, 551, 253, 816, 81, 19, 18, 206, 1006, + 17, 20, 16, 555, 556, 557, 558, 559, 560, 561, + 562, 820, 821, 15, 14, 453, 1233, 30, 21, 1235, + 835, 838, 839, 840, 836, 13, 837, 841, 1220, 12, + 11, 10, 9, 8, 7, 6, 1242, 335, 5, 1125, + 1221, 4, 1223, 244, 23, 2, 0, 0, 609, 0, + 335, 0, 1024, 1234, 0, 1260, 0, 0, 0, 610, + 1091, 0, 0, 0, 0, 1270, 0, 81, 0, 0, + 0, 1269, 0, 0, 0, 81, 0, 1060, 0, 0, + 0, 0, 1129, 0, 0, 0, 1253, 0, 0, 1119, + 81, 0, 1279, 0, 0, 0, 0, 81, 0, 0, + 0, 0, 1288, 0, 1290, 335, 0, 335, 0, 0, + 0, 941, 942, 0, 0, 1159, 0, 0, 1275, 1276, + 1277, 0, 335, 0, 0, 0, 0, 0, 0, 1302, + 0, 0, 0, 0, 0, 0, 81, 81, 0, 81, + 1122, 0, 0, 0, 81, 0, 81, 81, 81, 206, + 335, 467, 81, 1322, 1314, 1323, 1324, 1325, 0, 1167, + 0, 0, 1219, 0, 0, 1326, 874, 1332, 874, 81, + 206, 1321, 1339, 0, 1239, 1240, 0, 1241, 1347, 1222, + 1243, 0, 1245, 1340, 0, 1341, 0, 0, 984, 0, + 1157, 1232, 985, 1168, 1362, 0, 1317, 0, 0, 989, + 990, 991, 0, 0, 0, 81, 997, 0, 1369, 1000, + 1001, 1370, 0, 1167, 0, 1007, 81, 81, 0, 1009, + 0, 0, 1012, 1013, 1014, 1015, 1344, 1385, 1384, 1388, + 0, 1129, 1191, 0, 1316, 81, 1282, 1393, 1024, 0, + 0, 0, 0, 0, 1039, 816, 206, 1168, 0, 51, + 0, 0, 764, 0, 81, 0, 761, 0, 0, 770, + 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, + 781, 782, 783, 784, 1402, 1407, 1409, 81, 800, 801, + 0, 0, 806, 809, 810, 0, 1411, 1363, 335, 0, + 1422, 0, 0, 0, 0, 0, 0, 1433, 0, 0, + 0, 0, 0, 874, 0, 0, 0, 822, 0, 824, + 825, 0, 0, 0, 819, 530, 529, 539, 540, 532, + 533, 534, 535, 536, 537, 538, 531, 0, 0, 541, + 0, 0, 0, 1297, 0, 0, 1090, 335, 609, 0, + 0, 0, 609, 1256, 0, 0, 609, 1420, 501, 0, + 0, 0, 0, 566, 1258, 0, 0, 0, 1293, 0, + 0, 1271, 0, 0, 1272, 0, 335, 1274, 982, 0, + 0, 0, 1348, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 204, 0, 1135, 230, 0, 0, + 0, 335, 530, 529, 539, 540, 532, 533, 534, 535, + 536, 537, 538, 531, 0, 0, 541, 0, 0, 0, + 0, 0, 257, 0, 0, 326, 0, 0, 0, 0, + 204, 0, 204, 0, 335, 0, 0, 0, 0, 0, + 0, 0, 0, 816, 0, 0, 1171, 1173, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1397, 0, + 0, 0, 1297, 874, 0, 0, 971, 0, 0, 0, + 1173, 0, 0, 0, 216, 0, 0, 24, 25, 52, + 27, 28, 0, 0, 0, 335, 0, 335, 1200, 0, + 0, 0, 0, 0, 0, 0, 43, 0, 226, 0, + 0, 29, 48, 49, 764, 0, 0, 0, 0, 0, + 978, 979, 980, 986, 0, 0, 0, 0, 0, 0, + 0, 38, 0, 0, 0, 54, 0, 0, 0, 0, + 0, 1002, 0, 0, 0, 0, 0, 0, 1224, 0, + 1236, 1229, 1230, 1231, 0, 1387, 566, 1238, 0, 209, + 335, 0, 204, 0, 0, 204, 212, 0, 1247, 1248, + 0, 204, 0, 0, 220, 215, 0, 204, 609, 609, + 609, 609, 609, 0, 0, 0, 0, 0, 1262, 1263, + 1264, 0, 1267, 609, 0, 0, 31, 32, 34, 33, + 36, 609, 50, 0, 0, 0, 218, 0, 0, 1278, + 0, 816, 225, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 37, 44, 45, 0, 0, 46, 47, + 35, 0, 335, 0, 0, 0, 0, 0, 0, 210, + 1284, 0, 0, 0, 39, 40, 0, 41, 42, 0, + 0, 0, 0, 0, 0, 335, 0, 0, 0, 0, + 0, 0, 335, 0, 0, 0, 222, 213, 0, 223, + 224, 229, 0, 0, 1309, 214, 217, 0, 211, 228, + 227, 0, 0, 0, 0, 0, 0, 0, 204, 204, + 204, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1318, 1319, 0, 1320, 0, 0, 0, 0, 1284, + 0, 1284, 1284, 1284, 0, 0, 0, 1200, 0, 0, + 0, 0, 0, 0, 1352, 1353, 1354, 1355, 0, 53, + 0, 1359, 1360, 0, 1284, 1133, 1134, 0, 0, 0, + 0, 0, 0, 1366, 1367, 1368, 1257, 0, 1150, 1151, + 0, 1152, 1153, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1160, 1161, 0, 0, 0, 0, 0, + 1376, 0, 0, 0, 1252, 0, 1389, 0, 0, 0, + 0, 335, 335, 1394, 530, 529, 539, 540, 532, 533, + 534, 535, 536, 537, 538, 531, 0, 816, 541, 0, + 1395, 1399, 0, 0, 0, 204, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 204, 204, 0, 0, 1401, + 0, 204, 0, 0, 204, 1207, 0, 204, 0, 0, + 0, 710, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 204, 1284, 1132, 0, 1251, 1434, 1435, 530, 529, + 539, 540, 532, 533, 534, 535, 536, 537, 538, 531, + 0, 0, 541, 530, 529, 539, 540, 532, 533, 534, + 535, 536, 537, 538, 531, 609, 658, 541, 0, 0, + 0, 204, 0, 0, 525, 1237, 528, 0, 0, 0, + 710, 0, 542, 543, 544, 545, 546, 547, 548, 0, + 526, 527, 524, 530, 529, 539, 540, 532, 533, 534, + 535, 536, 537, 538, 531, 0, 0, 541, 0, 530, + 529, 539, 540, 532, 533, 534, 535, 536, 537, 538, + 531, 0, 257, 541, 0, 0, 0, 257, 257, 0, + 0, 257, 257, 257, 0, 0, 0, 817, 0, 0, + 0, 0, 0, 0, 646, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 257, 257, 257, 257, + 0, 204, 0, 0, 0, 0, 0, 0, 0, 204, + 850, 0, 0, 204, 204, 0, 0, 204, 858, 710, + 0, 659, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1250, 1304, 1305, 1306, 1307, 1308, 0, 0, 0, + 1311, 1312, 0, 0, 672, 675, 676, 677, 678, 679, + 680, 0, 681, 682, 683, 684, 685, 660, 661, 662, + 663, 644, 645, 673, 0, 647, 0, 648, 649, 650, + 651, 652, 653, 654, 655, 656, 657, 664, 665, 666, + 667, 668, 669, 670, 671, 0, 0, 204, 1249, 0, + 0, 0, 0, 0, 0, 0, 204, 204, 204, 0, + 204, 204, 0, 0, 204, 530, 529, 539, 540, 532, + 533, 534, 535, 536, 537, 538, 531, 0, 0, 541, + 0, 204, 0, 956, 957, 0, 0, 0, 204, 0, + 0, 0, 0, 710, 0, 674, 0, 0, 0, 139, + 0, 0, 0, 849, 0, 257, 0, 0, 103, 0, + 0, 0, 0, 0, 120, 0, 122, 0, 0, 160, + 131, 0, 530, 529, 539, 540, 532, 533, 534, 535, + 536, 537, 538, 531, 0, 0, 541, 0, 205, 0, + 851, 0, 0, 0, 0, 0, 0, 96, 0, 0, + 0, 983, 257, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1426, 0, 0, 0, 0, 0, 0, + 257, 530, 529, 539, 540, 532, 533, 534, 535, 536, + 537, 538, 531, 0, 0, 541, 0, 0, 817, 204, + 204, 204, 204, 204, 0, 0, 0, 0, 0, 0, + 0, 1038, 109, 0, 204, 0, 207, 0, 850, 0, + 0, 146, 204, 163, 111, 119, 83, 90, 0, 110, + 137, 151, 155, 0, 0, 0, 99, 0, 153, 141, + 176, 0, 142, 152, 123, 168, 147, 175, 183, 184, + 165, 182, 187, 157, 84, 164, 174, 97, 156, 86, 172, 162, 129, 115, 116, 85, 0, 150, 102, 107, - 101, 138, 169, 170, 100, 189, 91, 181, 88, 92, + 101, 138, 169, 170, 100, 190, 91, 181, 88, 92, 180, 136, 167, 173, 130, 127, 87, 171, 128, 126, 118, 105, 112, 144, 125, 145, 113, 133, 132, 134, - 0, 342, 0, 161, 178, 190, 94, 357, 166, 185, - 0, 0, 95, 108, 104, 143, 135, 93, 114, 158, - 117, 124, 149, 188, 140, 154, 98, 177, 159, 353, - 356, 351, 352, 390, 391, 427, 428, 429, 407, 348, - 0, 354, 355, 0, 411, 417, 418, 393, 82, 89, - 121, 187, 148, 106, 179, 421, 410, 0, 381, 424, - 359, 373, 432, 374, 375, 403, 345, 389, 139, 371, - 0, 362, 340, 368, 341, 360, 383, 103, 386, 358, - 412, 392, 423, 120, 430, 122, 397, 0, 160, 131, - 0, 0, 385, 414, 387, 408, 380, 404, 350, 396, - 425, 372, 401, 426, 0, 0, 0, 204, 0, 0, - 0, 0, 0, 0, 0, 0, 96, 0, 399, 420, - 370, 400, 402, 339, 398, 0, 343, 346, 431, 416, - 365, 366, 0, 0, 0, 0, 0, 0, 0, 384, - 388, 405, 378, 0, 0, 0, 0, 0, 0, 854, - 0, 363, 0, 395, 0, 0, 0, 347, 344, 0, - 0, 382, 0, 0, 0, 349, 0, 364, 406, 0, - 338, 109, 409, 415, 379, 206, 419, 377, 376, 422, - 146, 0, 163, 111, 119, 83, 90, 0, 110, 137, - 151, 155, 413, 361, 369, 99, 367, 153, 141, 176, - 394, 142, 152, 123, 168, 147, 175, 183, 184, 165, - 182, 186, 157, 84, 164, 174, 97, 156, 86, 172, - 162, 129, 115, 116, 85, 0, 150, 102, 107, 101, - 138, 169, 170, 100, 189, 91, 181, 88, 92, 180, - 136, 167, 173, 130, 127, 87, 171, 128, 126, 118, - 105, 112, 144, 125, 145, 113, 133, 132, 134, 0, - 342, 0, 161, 178, 190, 94, 357, 166, 185, 0, + 0, 0, 0, 161, 178, 191, 94, 0, 166, 185, + 186, 0, 0, 95, 108, 104, 143, 135, 93, 114, + 158, 117, 124, 149, 189, 140, 154, 98, 177, 159, + 0, 0, 0, 0, 0, 204, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 257, 0, 0, 0, 82, + 89, 121, 188, 148, 106, 179, 257, 530, 529, 539, + 540, 532, 533, 534, 535, 536, 537, 538, 531, 0, + 0, 541, 0, 0, 0, 0, 0, 710, 0, 0, + 0, 0, 0, 0, 0, 0, 817, 139, 0, 0, + 0, 0, 264, 0, 0, 0, 103, 0, 261, 0, + 0, 0, 120, 304, 122, 0, 0, 160, 131, 0, + 0, 0, 0, 295, 296, 0, 0, 0, 0, 0, + 0, 866, 0, 54, 0, 0, 262, 283, 282, 285, + 286, 287, 288, 0, 0, 96, 284, 289, 290, 291, + 867, 0, 0, 259, 276, 0, 303, 529, 539, 540, + 532, 533, 534, 535, 536, 537, 538, 531, 204, 0, + 541, 0, 0, 0, 0, 0, 273, 274, 0, 0, + 0, 0, 317, 0, 275, 204, 0, 270, 271, 272, + 277, 0, 0, 0, 0, 0, 0, 204, 0, 0, + 109, 0, 0, 0, 207, 0, 204, 315, 0, 146, + 0, 163, 111, 119, 83, 90, 0, 110, 137, 151, + 155, 0, 0, 0, 99, 0, 153, 141, 176, 0, + 142, 152, 123, 168, 147, 175, 183, 184, 165, 182, + 187, 157, 84, 164, 174, 97, 156, 86, 172, 162, + 129, 115, 116, 85, 817, 150, 102, 107, 101, 138, + 169, 170, 100, 190, 91, 181, 88, 92, 180, 136, + 167, 173, 130, 127, 87, 171, 128, 126, 118, 105, + 112, 144, 125, 145, 113, 133, 132, 134, 0, 0, + 0, 161, 178, 191, 94, 0, 166, 185, 186, 0, + 0, 95, 108, 104, 143, 135, 93, 114, 158, 117, + 124, 149, 189, 140, 154, 98, 177, 159, 305, 316, + 311, 312, 309, 310, 308, 307, 306, 318, 297, 298, + 299, 300, 302, 0, 313, 314, 301, 82, 89, 121, + 188, 148, 106, 179, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 850, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 204, 0, + 0, 0, 0, 0, 423, 412, 0, 383, 426, 361, + 375, 434, 376, 377, 405, 347, 391, 139, 373, 0, + 364, 342, 370, 343, 362, 385, 103, 388, 360, 414, + 394, 425, 120, 432, 122, 399, 0, 160, 131, 0, + 0, 387, 416, 389, 410, 382, 406, 352, 398, 427, + 374, 403, 428, 0, 0, 0, 80, 0, 875, 876, + 817, 0, 0, 0, 0, 96, 0, 401, 422, 372, + 402, 404, 341, 400, 204, 345, 348, 433, 418, 367, + 368, 1061, 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, + 109, 411, 417, 381, 207, 421, 379, 378, 424, 146, + 0, 163, 111, 119, 83, 90, 0, 110, 137, 151, + 155, 415, 363, 371, 99, 369, 153, 141, 176, 396, + 142, 152, 123, 168, 147, 175, 183, 184, 165, 182, + 187, 157, 84, 164, 174, 97, 156, 86, 172, 162, + 129, 115, 116, 85, 0, 150, 102, 107, 101, 138, + 169, 170, 100, 190, 91, 181, 88, 92, 180, 136, + 167, 173, 130, 127, 87, 171, 128, 126, 118, 105, + 112, 144, 125, 145, 113, 133, 132, 134, 0, 344, + 0, 161, 178, 191, 94, 359, 166, 185, 186, 0, 0, 95, 108, 104, 143, 135, 93, 114, 158, 117, - 124, 149, 188, 140, 154, 98, 177, 159, 353, 356, - 351, 352, 390, 391, 427, 428, 429, 407, 348, 0, - 354, 355, 0, 411, 417, 418, 393, 82, 89, 121, - 187, 148, 106, 179, 421, 410, 0, 381, 424, 359, - 373, 432, 374, 375, 403, 345, 389, 139, 371, 0, - 362, 340, 368, 341, 360, 383, 103, 386, 358, 412, - 392, 423, 120, 430, 122, 397, 0, 160, 131, 0, - 0, 385, 414, 387, 408, 380, 404, 350, 396, 425, - 372, 401, 426, 0, 0, 0, 260, 0, 0, 0, - 0, 0, 0, 0, 0, 96, 0, 399, 420, 370, - 400, 402, 339, 398, 0, 343, 346, 431, 416, 365, - 366, 0, 0, 0, 0, 0, 0, 0, 384, 388, - 405, 378, 0, 0, 0, 0, 0, 0, 752, 0, - 363, 0, 395, 0, 0, 0, 347, 344, 0, 0, - 382, 0, 0, 0, 349, 0, 364, 406, 0, 338, - 109, 409, 415, 379, 206, 419, 377, 376, 422, 146, + 124, 149, 189, 140, 154, 98, 177, 159, 355, 358, + 353, 354, 392, 393, 429, 430, 431, 409, 350, 0, + 356, 357, 0, 413, 419, 420, 395, 82, 89, 121, + 188, 148, 106, 179, 423, 412, 0, 383, 426, 361, + 375, 434, 376, 377, 405, 347, 391, 139, 373, 0, + 364, 342, 370, 343, 362, 385, 103, 388, 360, 414, + 394, 425, 120, 432, 122, 399, 0, 160, 131, 0, + 0, 387, 416, 389, 410, 382, 406, 352, 398, 427, + 374, 403, 428, 0, 0, 0, 80, 0, 875, 876, + 0, 0, 0, 0, 0, 96, 0, 401, 422, 372, + 402, 404, 341, 400, 0, 345, 348, 433, 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, + 109, 411, 417, 381, 207, 421, 379, 378, 424, 146, 0, 163, 111, 119, 83, 90, 0, 110, 137, 151, - 155, 413, 361, 369, 99, 367, 153, 141, 176, 394, + 155, 415, 363, 371, 99, 369, 153, 141, 176, 396, 142, 152, 123, 168, 147, 175, 183, 184, 165, 182, - 186, 157, 84, 164, 174, 97, 156, 86, 172, 162, + 187, 157, 84, 164, 174, 97, 156, 86, 172, 162, 129, 115, 116, 85, 0, 150, 102, 107, 101, 138, - 169, 170, 100, 189, 91, 181, 88, 92, 180, 136, + 169, 170, 100, 190, 91, 181, 88, 92, 180, 136, 167, 173, 130, 127, 87, 171, 128, 126, 118, 105, - 112, 144, 125, 145, 113, 133, 132, 134, 0, 342, - 0, 161, 178, 190, 94, 357, 166, 185, 0, 0, - 95, 108, 104, 143, 135, 93, 114, 158, 117, 124, - 149, 188, 140, 154, 98, 177, 159, 353, 356, 351, - 352, 390, 391, 427, 428, 429, 407, 348, 0, 354, - 355, 0, 411, 417, 418, 393, 82, 89, 121, 187, - 148, 106, 179, 421, 410, 0, 381, 424, 359, 373, - 432, 374, 375, 403, 345, 389, 139, 371, 0, 362, - 340, 368, 341, 360, 383, 103, 386, 358, 412, 392, - 423, 120, 430, 122, 397, 0, 160, 131, 0, 0, - 385, 414, 387, 408, 380, 404, 350, 396, 425, 372, - 401, 426, 0, 0, 0, 80, 0, 0, 0, 0, - 0, 0, 0, 0, 96, 0, 399, 420, 370, 400, - 402, 339, 398, 0, 343, 346, 431, 416, 365, 366, - 0, 0, 0, 0, 0, 0, 0, 384, 388, 405, - 378, 0, 0, 0, 0, 0, 0, 0, 0, 363, - 0, 395, 0, 0, 0, 347, 344, 0, 0, 382, - 0, 0, 0, 349, 0, 364, 406, 0, 338, 109, - 409, 415, 379, 206, 419, 377, 376, 422, 146, 0, - 163, 111, 119, 83, 90, 0, 110, 137, 151, 155, - 413, 361, 369, 99, 367, 153, 141, 176, 394, 142, - 152, 123, 168, 147, 175, 183, 184, 165, 182, 186, - 157, 84, 164, 174, 97, 156, 86, 172, 162, 129, - 115, 116, 85, 0, 150, 102, 107, 101, 138, 169, - 170, 100, 189, 91, 181, 88, 92, 180, 136, 167, - 173, 130, 127, 87, 171, 128, 126, 118, 105, 112, - 144, 125, 145, 113, 133, 132, 134, 0, 342, 0, - 161, 178, 190, 94, 357, 166, 185, 0, 0, 95, - 108, 104, 143, 135, 93, 114, 158, 117, 124, 149, - 188, 140, 154, 98, 177, 159, 353, 356, 351, 352, - 390, 391, 427, 428, 429, 407, 348, 0, 354, 355, - 0, 411, 417, 418, 393, 82, 89, 121, 187, 148, - 106, 179, 421, 410, 0, 381, 424, 359, 373, 432, - 374, 375, 403, 345, 389, 139, 371, 0, 362, 340, - 368, 341, 360, 383, 103, 386, 358, 412, 392, 423, - 120, 430, 122, 397, 0, 160, 131, 0, 0, 385, - 414, 387, 408, 380, 404, 350, 396, 425, 372, 401, - 426, 0, 0, 0, 260, 0, 0, 0, 0, 0, - 0, 0, 0, 96, 0, 399, 420, 370, 400, 402, - 339, 398, 0, 343, 346, 431, 416, 365, 366, 0, - 0, 0, 0, 0, 0, 0, 384, 388, 405, 378, - 0, 0, 0, 0, 0, 0, 0, 0, 363, 0, - 395, 0, 0, 0, 347, 344, 0, 0, 382, 0, - 0, 0, 349, 0, 364, 406, 0, 338, 109, 409, - 415, 379, 206, 419, 377, 376, 422, 146, 0, 163, - 111, 119, 83, 90, 0, 110, 137, 151, 155, 413, - 361, 369, 99, 367, 153, 141, 176, 394, 142, 152, - 123, 168, 147, 175, 183, 184, 165, 182, 186, 157, - 84, 164, 174, 97, 156, 86, 172, 162, 129, 115, - 116, 85, 0, 150, 102, 107, 101, 138, 169, 170, - 100, 189, 91, 181, 88, 92, 180, 136, 167, 173, - 130, 127, 87, 171, 128, 126, 118, 105, 112, 144, - 125, 145, 113, 133, 132, 134, 0, 342, 0, 161, - 178, 190, 94, 357, 166, 185, 0, 0, 95, 108, - 104, 143, 135, 93, 114, 158, 117, 124, 149, 188, - 140, 154, 98, 177, 159, 353, 356, 351, 352, 390, - 391, 427, 428, 429, 407, 348, 0, 354, 355, 0, - 411, 417, 418, 393, 82, 89, 121, 187, 148, 106, - 179, 421, 410, 0, 381, 424, 359, 373, 432, 374, - 375, 403, 345, 389, 139, 371, 0, 362, 340, 368, - 341, 360, 383, 103, 386, 358, 412, 392, 423, 120, - 430, 122, 397, 0, 160, 131, 0, 0, 385, 414, - 387, 408, 380, 404, 350, 396, 425, 372, 401, 426, - 0, 0, 0, 80, 0, 0, 0, 0, 0, 0, - 0, 0, 96, 0, 399, 420, 370, 400, 402, 339, - 398, 0, 343, 346, 431, 416, 365, 366, 0, 0, - 0, 0, 0, 0, 0, 384, 388, 405, 378, 0, - 0, 0, 0, 0, 0, 0, 0, 363, 0, 395, - 0, 0, 0, 347, 344, 0, 0, 382, 0, 0, - 0, 349, 0, 364, 406, 0, 338, 109, 409, 415, - 379, 206, 419, 377, 376, 422, 146, 0, 163, 111, - 119, 83, 90, 0, 110, 137, 151, 155, 413, 361, - 369, 99, 367, 153, 141, 176, 394, 142, 152, 123, - 168, 147, 175, 183, 184, 165, 182, 186, 157, 84, - 164, 174, 97, 156, 86, 172, 162, 129, 115, 116, - 85, 0, 150, 102, 107, 101, 138, 169, 170, 100, - 189, 91, 181, 88, 336, 180, 136, 167, 173, 130, - 127, 87, 171, 128, 126, 118, 105, 112, 144, 125, - 145, 113, 133, 132, 134, 0, 342, 0, 161, 178, - 190, 94, 357, 166, 185, 0, 0, 95, 108, 104, - 143, 337, 335, 114, 158, 117, 124, 149, 188, 140, - 154, 98, 177, 159, 353, 356, 351, 352, 390, 391, - 427, 428, 429, 407, 348, 0, 354, 355, 0, 411, - 417, 418, 393, 82, 89, 121, 187, 148, 106, 179, - 421, 410, 0, 381, 424, 359, 373, 432, 374, 375, - 403, 345, 389, 139, 371, 0, 362, 340, 368, 341, - 360, 383, 103, 386, 358, 412, 392, 423, 120, 430, - 122, 397, 0, 160, 131, 0, 0, 385, 414, 387, - 408, 380, 404, 350, 396, 425, 372, 401, 426, 0, - 0, 0, 204, 0, 0, 0, 0, 0, 0, 0, - 0, 96, 0, 399, 420, 370, 400, 402, 339, 398, - 0, 343, 346, 431, 416, 365, 366, 0, 0, 0, - 0, 0, 0, 0, 384, 388, 405, 378, 0, 0, - 0, 0, 0, 0, 0, 0, 363, 0, 395, 0, - 0, 0, 347, 344, 0, 0, 382, 0, 0, 0, - 349, 0, 364, 406, 0, 338, 109, 409, 415, 379, - 206, 419, 377, 376, 422, 146, 0, 163, 111, 119, - 83, 90, 0, 110, 137, 151, 155, 413, 361, 369, - 99, 367, 153, 141, 176, 394, 142, 152, 123, 168, - 147, 175, 183, 184, 165, 182, 186, 157, 84, 164, - 174, 97, 156, 86, 172, 162, 129, 115, 116, 85, - 0, 150, 102, 107, 101, 138, 169, 170, 100, 189, - 91, 181, 88, 92, 180, 136, 167, 173, 130, 127, - 87, 171, 128, 126, 118, 105, 112, 144, 125, 145, - 113, 133, 132, 134, 0, 342, 0, 161, 178, 190, - 94, 357, 166, 185, 0, 0, 95, 108, 104, 143, - 135, 93, 114, 158, 117, 124, 149, 188, 140, 154, - 98, 177, 159, 353, 356, 351, 352, 390, 391, 427, - 428, 429, 407, 348, 0, 354, 355, 0, 411, 417, - 418, 393, 82, 89, 121, 187, 148, 106, 179, 421, - 410, 0, 381, 424, 359, 373, 432, 374, 375, 403, - 345, 389, 139, 371, 0, 362, 340, 368, 341, 360, - 383, 103, 386, 358, 412, 392, 423, 120, 430, 122, - 397, 0, 160, 131, 0, 0, 385, 414, 387, 408, - 380, 404, 350, 396, 425, 372, 401, 426, 0, 0, - 0, 80, 0, 0, 0, 0, 0, 0, 0, 0, - 96, 0, 399, 420, 370, 400, 402, 339, 398, 0, - 343, 346, 431, 416, 365, 366, 0, 0, 0, 0, - 0, 0, 0, 384, 388, 405, 378, 0, 0, 0, - 0, 0, 0, 0, 0, 363, 0, 395, 0, 0, - 0, 347, 344, 0, 0, 382, 0, 0, 0, 349, - 0, 364, 406, 0, 338, 109, 409, 415, 379, 206, - 419, 377, 376, 422, 146, 0, 163, 111, 119, 83, - 90, 0, 110, 137, 151, 155, 413, 361, 369, 99, - 367, 153, 141, 176, 394, 142, 152, 123, 168, 147, - 175, 183, 184, 165, 182, 186, 157, 84, 164, 620, - 97, 156, 86, 172, 162, 129, 115, 116, 85, 0, - 150, 102, 107, 101, 138, 169, 170, 100, 189, 91, - 181, 88, 336, 180, 136, 167, 173, 130, 127, 87, - 171, 128, 126, 118, 105, 112, 144, 125, 145, 113, - 133, 132, 134, 0, 342, 0, 161, 178, 190, 94, - 357, 166, 185, 0, 0, 95, 108, 104, 143, 337, - 335, 114, 158, 117, 124, 149, 188, 140, 154, 98, - 177, 159, 353, 356, 351, 352, 390, 391, 427, 428, - 429, 407, 348, 0, 354, 355, 0, 411, 417, 418, - 393, 82, 89, 121, 187, 148, 106, 179, 421, 410, - 0, 381, 424, 359, 373, 432, 374, 375, 403, 345, - 389, 139, 371, 0, 362, 340, 368, 341, 360, 383, - 103, 386, 358, 412, 392, 423, 120, 430, 122, 397, - 0, 160, 131, 0, 0, 385, 414, 387, 408, 380, - 404, 350, 396, 425, 372, 401, 426, 0, 0, 0, - 80, 0, 0, 0, 0, 0, 0, 0, 0, 96, - 0, 399, 420, 370, 400, 402, 339, 398, 0, 343, - 346, 431, 416, 365, 366, 0, 0, 0, 0, 0, - 0, 0, 384, 388, 405, 378, 0, 0, 0, 0, - 0, 0, 0, 0, 363, 0, 395, 0, 0, 0, - 347, 344, 0, 0, 382, 0, 0, 0, 349, 0, - 364, 406, 0, 338, 109, 409, 415, 379, 206, 419, - 377, 376, 422, 146, 0, 163, 111, 119, 83, 90, - 0, 110, 137, 151, 155, 413, 361, 369, 99, 367, - 153, 141, 176, 394, 142, 152, 123, 168, 147, 175, - 183, 184, 165, 182, 186, 157, 84, 164, 327, 97, - 156, 86, 172, 162, 129, 115, 116, 85, 0, 150, - 102, 107, 101, 138, 169, 170, 100, 189, 91, 181, - 88, 336, 180, 136, 167, 173, 130, 127, 87, 171, - 128, 126, 118, 105, 112, 144, 125, 145, 113, 133, - 132, 134, 0, 342, 0, 161, 178, 190, 94, 357, - 166, 185, 0, 0, 95, 108, 104, 143, 337, 335, - 330, 329, 117, 124, 149, 188, 140, 154, 98, 177, - 159, 353, 356, 351, 352, 390, 391, 427, 428, 429, - 407, 348, 0, 354, 355, 0, 411, 417, 418, 393, - 82, 89, 121, 187, 148, 106, 179, 139, 0, 0, - 788, 0, 262, 0, 0, 0, 103, 0, 259, 0, - 0, 0, 120, 302, 122, 0, 0, 160, 131, 0, - 0, 0, 0, 293, 294, 0, 0, 0, 0, 0, - 0, 0, 0, 54, 0, 0, 260, 281, 280, 283, - 284, 285, 286, 0, 0, 96, 282, 287, 288, 289, - 0, 0, 0, 257, 274, 0, 301, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 271, 272, 253, 0, - 0, 0, 315, 0, 273, 0, 0, 268, 269, 270, - 275, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 109, 0, 0, 0, 206, 0, 0, 313, 0, 146, + 112, 144, 125, 145, 113, 133, 132, 134, 0, 344, + 0, 161, 178, 191, 94, 359, 166, 185, 186, 0, + 0, 95, 108, 104, 143, 135, 93, 114, 158, 117, + 124, 149, 189, 140, 154, 98, 177, 159, 355, 358, + 353, 354, 392, 393, 429, 430, 431, 409, 350, 0, + 356, 357, 0, 413, 419, 420, 395, 82, 89, 121, + 188, 148, 106, 179, 423, 412, 0, 383, 426, 361, + 375, 434, 376, 377, 405, 347, 391, 139, 373, 0, + 364, 342, 370, 343, 362, 385, 103, 388, 360, 414, + 394, 425, 120, 432, 122, 399, 0, 160, 131, 0, + 0, 387, 416, 389, 410, 382, 406, 352, 398, 427, + 374, 403, 428, 54, 0, 0, 80, 0, 0, 0, + 0, 0, 0, 0, 0, 96, 0, 401, 422, 372, + 402, 404, 341, 400, 0, 345, 348, 433, 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, + 109, 411, 417, 381, 207, 421, 379, 378, 424, 146, 0, 163, 111, 119, 83, 90, 0, 110, 137, 151, - 155, 0, 0, 0, 99, 0, 153, 141, 176, 0, + 155, 415, 363, 371, 99, 369, 153, 141, 176, 396, 142, 152, 123, 168, 147, 175, 183, 184, 165, 182, - 186, 157, 84, 164, 174, 97, 156, 86, 172, 162, + 187, 157, 84, 164, 174, 97, 156, 86, 172, 162, 129, 115, 116, 85, 0, 150, 102, 107, 101, 138, - 169, 170, 100, 189, 91, 181, 88, 92, 180, 136, + 169, 170, 100, 190, 91, 181, 88, 92, 180, 136, 167, 173, 130, 127, 87, 171, 128, 126, 118, 105, - 112, 144, 125, 145, 113, 133, 132, 134, 0, 0, - 0, 161, 178, 190, 94, 0, 166, 185, 0, 0, - 95, 108, 104, 143, 135, 93, 114, 158, 117, 124, - 149, 188, 140, 154, 98, 177, 159, 303, 314, 309, - 310, 307, 308, 306, 305, 304, 316, 295, 296, 297, - 298, 300, 0, 311, 312, 299, 82, 89, 121, 187, - 148, 106, 179, 139, 0, 0, 0, 0, 262, 0, - 0, 0, 103, 0, 259, 0, 0, 0, 120, 302, - 122, 0, 0, 160, 131, 0, 0, 0, 0, 293, - 294, 0, 0, 0, 0, 0, 0, 0, 0, 54, - 0, 493, 260, 281, 280, 283, 284, 285, 286, 0, - 0, 96, 282, 287, 288, 289, 0, 0, 0, 257, - 274, 0, 301, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 271, 272, 0, 0, 0, 0, 315, 0, - 273, 0, 0, 268, 269, 270, 275, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 109, 0, 0, 0, - 206, 0, 0, 313, 0, 146, 0, 163, 111, 119, - 83, 90, 0, 110, 137, 151, 155, 0, 0, 0, - 99, 0, 153, 141, 176, 0, 142, 152, 123, 168, - 147, 175, 183, 184, 165, 182, 186, 157, 84, 164, - 174, 97, 156, 86, 172, 162, 129, 115, 116, 85, - 0, 150, 102, 107, 101, 138, 169, 170, 100, 189, - 91, 181, 88, 92, 180, 136, 167, 173, 130, 127, - 87, 171, 128, 126, 118, 105, 112, 144, 125, 145, - 113, 133, 132, 134, 0, 0, 0, 161, 178, 190, - 94, 0, 166, 185, 0, 0, 95, 108, 104, 143, - 135, 93, 114, 158, 117, 124, 149, 188, 140, 154, - 98, 177, 159, 303, 314, 309, 310, 307, 308, 306, - 305, 304, 316, 295, 296, 297, 298, 300, 0, 311, - 312, 299, 82, 89, 121, 187, 148, 106, 179, 139, - 0, 0, 0, 0, 262, 0, 0, 0, 103, 0, - 259, 0, 0, 0, 120, 302, 122, 0, 0, 160, - 131, 0, 0, 0, 0, 293, 294, 0, 0, 0, - 0, 0, 0, 0, 0, 54, 0, 0, 260, 281, - 280, 283, 284, 285, 286, 0, 0, 96, 282, 287, - 288, 289, 0, 0, 0, 257, 274, 0, 301, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 271, 272, - 253, 0, 0, 0, 315, 0, 273, 0, 0, 268, - 269, 270, 275, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 109, 0, 0, 0, 206, 0, 0, 313, - 0, 146, 0, 163, 111, 119, 83, 90, 0, 110, - 137, 151, 155, 0, 0, 0, 99, 0, 153, 141, - 176, 0, 142, 152, 123, 168, 147, 175, 183, 184, - 165, 182, 186, 157, 84, 164, 174, 97, 156, 86, - 172, 162, 129, 115, 116, 85, 0, 150, 102, 107, - 101, 138, 169, 170, 100, 189, 91, 181, 88, 92, - 180, 136, 167, 173, 130, 127, 87, 171, 128, 126, - 118, 105, 112, 144, 125, 145, 113, 133, 132, 134, - 0, 0, 0, 161, 178, 190, 94, 0, 166, 185, - 0, 0, 95, 108, 104, 143, 135, 93, 114, 158, - 117, 124, 149, 188, 140, 154, 98, 177, 159, 303, - 314, 309, 310, 307, 308, 306, 305, 304, 316, 295, - 296, 297, 298, 300, 0, 311, 312, 299, 82, 89, - 121, 187, 148, 106, 179, 139, 0, 0, 0, 0, - 262, 0, 0, 0, 103, 0, 259, 0, 0, 0, - 120, 302, 122, 0, 0, 160, 131, 0, 0, 0, - 0, 293, 294, 0, 0, 0, 0, 0, 0, 0, - 0, 54, 0, 0, 260, 281, 803, 283, 284, 285, - 286, 0, 0, 96, 282, 287, 288, 289, 0, 0, - 0, 257, 274, 0, 301, 0, 0, 0, 0, 0, + 112, 144, 125, 145, 113, 133, 132, 134, 0, 344, + 0, 161, 178, 191, 94, 359, 166, 185, 186, 0, + 0, 95, 108, 104, 143, 135, 93, 114, 158, 117, + 124, 149, 189, 140, 154, 98, 177, 159, 355, 358, + 353, 354, 392, 393, 429, 430, 431, 409, 350, 0, + 356, 357, 0, 413, 419, 420, 395, 82, 89, 121, + 188, 148, 106, 179, 423, 412, 0, 383, 426, 361, + 375, 434, 376, 377, 405, 347, 391, 139, 373, 0, + 364, 342, 370, 343, 362, 385, 103, 388, 360, 414, + 394, 425, 120, 432, 122, 399, 0, 160, 131, 0, + 0, 387, 416, 389, 410, 382, 406, 352, 398, 427, + 374, 403, 428, 0, 0, 0, 80, 0, 0, 0, + 0, 0, 0, 0, 0, 96, 0, 401, 422, 372, + 402, 404, 341, 400, 0, 345, 348, 433, 418, 367, + 368, 0, 0, 0, 0, 0, 0, 0, 386, 390, + 407, 380, 0, 0, 0, 0, 0, 0, 1128, 0, + 365, 0, 397, 0, 0, 0, 349, 346, 0, 0, + 384, 0, 0, 0, 351, 0, 366, 408, 0, 340, + 109, 411, 417, 381, 207, 421, 379, 378, 424, 146, + 0, 163, 111, 119, 83, 90, 0, 110, 137, 151, + 155, 415, 363, 371, 99, 369, 153, 141, 176, 396, + 142, 152, 123, 168, 147, 175, 183, 184, 165, 182, + 187, 157, 84, 164, 174, 97, 156, 86, 172, 162, + 129, 115, 116, 85, 0, 150, 102, 107, 101, 138, + 169, 170, 100, 190, 91, 181, 88, 92, 180, 136, + 167, 173, 130, 127, 87, 171, 128, 126, 118, 105, + 112, 144, 125, 145, 113, 133, 132, 134, 0, 344, + 0, 161, 178, 191, 94, 359, 166, 185, 186, 0, + 0, 95, 108, 104, 143, 135, 93, 114, 158, 117, + 124, 149, 189, 140, 154, 98, 177, 159, 355, 358, + 353, 354, 392, 393, 429, 430, 431, 409, 350, 0, + 356, 357, 0, 413, 419, 420, 395, 82, 89, 121, + 188, 148, 106, 179, 423, 412, 0, 383, 426, 361, + 375, 434, 376, 377, 405, 347, 391, 139, 373, 0, + 364, 342, 370, 343, 362, 385, 103, 388, 360, 414, + 394, 425, 120, 432, 122, 399, 0, 160, 131, 0, + 0, 387, 416, 389, 410, 382, 406, 352, 398, 427, + 374, 403, 428, 0, 0, 0, 205, 0, 0, 0, + 0, 0, 0, 0, 0, 96, 0, 401, 422, 372, + 402, 404, 341, 400, 0, 345, 348, 433, 418, 367, + 368, 0, 0, 0, 0, 0, 0, 0, 386, 390, + 407, 380, 0, 0, 0, 0, 0, 0, 859, 0, + 365, 0, 397, 0, 0, 0, 349, 346, 0, 0, + 384, 0, 0, 0, 351, 0, 366, 408, 0, 340, + 109, 411, 417, 381, 207, 421, 379, 378, 424, 146, + 0, 163, 111, 119, 83, 90, 0, 110, 137, 151, + 155, 415, 363, 371, 99, 369, 153, 141, 176, 396, + 142, 152, 123, 168, 147, 175, 183, 184, 165, 182, + 187, 157, 84, 164, 174, 97, 156, 86, 172, 162, + 129, 115, 116, 85, 0, 150, 102, 107, 101, 138, + 169, 170, 100, 190, 91, 181, 88, 92, 180, 136, + 167, 173, 130, 127, 87, 171, 128, 126, 118, 105, + 112, 144, 125, 145, 113, 133, 132, 134, 0, 344, + 0, 161, 178, 191, 94, 359, 166, 185, 186, 0, + 0, 95, 108, 104, 143, 135, 93, 114, 158, 117, + 124, 149, 189, 140, 154, 98, 177, 159, 355, 358, + 353, 354, 392, 393, 429, 430, 431, 409, 350, 0, + 356, 357, 0, 413, 419, 420, 395, 82, 89, 121, + 188, 148, 106, 179, 423, 412, 0, 383, 426, 361, + 375, 434, 376, 377, 405, 347, 391, 139, 373, 0, + 364, 342, 370, 343, 362, 385, 103, 388, 360, 414, + 394, 425, 120, 432, 122, 399, 0, 160, 131, 0, + 0, 387, 416, 389, 410, 382, 406, 352, 398, 427, + 374, 403, 428, 0, 0, 0, 262, 0, 0, 0, + 0, 0, 0, 0, 0, 96, 0, 401, 422, 372, + 402, 404, 341, 400, 0, 345, 348, 433, 418, 367, + 368, 0, 0, 0, 0, 0, 0, 0, 386, 390, + 407, 380, 0, 0, 0, 0, 0, 0, 757, 0, + 365, 0, 397, 0, 0, 0, 349, 346, 0, 0, + 384, 0, 0, 0, 351, 0, 366, 408, 0, 340, + 109, 411, 417, 381, 207, 421, 379, 378, 424, 146, + 0, 163, 111, 119, 83, 90, 0, 110, 137, 151, + 155, 415, 363, 371, 99, 369, 153, 141, 176, 396, + 142, 152, 123, 168, 147, 175, 183, 184, 165, 182, + 187, 157, 84, 164, 174, 97, 156, 86, 172, 162, + 129, 115, 116, 85, 0, 150, 102, 107, 101, 138, + 169, 170, 100, 190, 91, 181, 88, 92, 180, 136, + 167, 173, 130, 127, 87, 171, 128, 126, 118, 105, + 112, 144, 125, 145, 113, 133, 132, 134, 0, 344, + 0, 161, 178, 191, 94, 359, 166, 185, 186, 0, + 0, 95, 108, 104, 143, 135, 93, 114, 158, 117, + 124, 149, 189, 140, 154, 98, 177, 159, 355, 358, + 353, 354, 392, 393, 429, 430, 431, 409, 350, 0, + 356, 357, 0, 413, 419, 420, 395, 82, 89, 121, + 188, 148, 106, 179, 423, 412, 0, 383, 426, 361, + 375, 434, 376, 377, 405, 347, 391, 139, 373, 0, + 364, 342, 370, 343, 362, 385, 103, 388, 360, 414, + 394, 425, 120, 432, 122, 399, 0, 160, 131, 0, + 0, 387, 416, 389, 410, 382, 406, 352, 398, 427, + 374, 403, 428, 0, 0, 0, 80, 0, 0, 0, + 0, 0, 0, 0, 0, 96, 0, 401, 422, 372, + 402, 404, 341, 400, 0, 345, 348, 433, 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, + 109, 411, 417, 381, 207, 421, 379, 378, 424, 146, + 0, 163, 111, 119, 83, 90, 0, 110, 137, 151, + 155, 415, 363, 371, 99, 369, 153, 141, 176, 396, + 142, 152, 123, 168, 147, 175, 183, 184, 165, 182, + 187, 157, 84, 164, 174, 97, 156, 86, 172, 162, + 129, 115, 116, 85, 0, 150, 102, 107, 101, 138, + 169, 170, 100, 190, 91, 181, 88, 92, 180, 136, + 167, 173, 130, 127, 87, 171, 128, 126, 118, 105, + 112, 144, 125, 145, 113, 133, 132, 134, 0, 344, + 0, 161, 178, 191, 94, 359, 166, 185, 186, 0, + 0, 95, 108, 104, 143, 135, 93, 114, 158, 117, + 124, 149, 189, 140, 154, 98, 177, 159, 355, 358, + 353, 354, 392, 393, 429, 430, 431, 409, 350, 0, + 356, 357, 0, 413, 419, 420, 395, 82, 89, 121, + 188, 148, 106, 179, 423, 412, 0, 383, 426, 361, + 375, 434, 376, 377, 405, 347, 391, 139, 373, 0, + 364, 342, 370, 343, 362, 385, 103, 388, 360, 414, + 394, 425, 120, 432, 122, 399, 0, 160, 131, 0, + 0, 387, 416, 389, 410, 382, 406, 352, 398, 427, + 374, 403, 428, 0, 0, 0, 262, 0, 0, 0, + 0, 0, 0, 0, 0, 96, 0, 401, 422, 372, + 402, 404, 341, 400, 0, 345, 348, 433, 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, + 109, 411, 417, 381, 207, 421, 379, 378, 424, 146, + 0, 163, 111, 119, 83, 90, 0, 110, 137, 151, + 155, 415, 363, 371, 99, 369, 153, 141, 176, 396, + 142, 152, 123, 168, 147, 175, 183, 184, 165, 182, + 187, 157, 84, 164, 174, 97, 156, 86, 172, 162, + 129, 115, 116, 85, 0, 150, 102, 107, 101, 138, + 169, 170, 100, 190, 91, 181, 88, 92, 180, 136, + 167, 173, 130, 127, 87, 171, 128, 126, 118, 105, + 112, 144, 125, 145, 113, 133, 132, 134, 0, 344, + 0, 161, 178, 191, 94, 359, 166, 185, 186, 0, + 0, 95, 108, 104, 143, 135, 93, 114, 158, 117, + 124, 149, 189, 140, 154, 98, 177, 159, 355, 358, + 353, 354, 392, 393, 429, 430, 431, 409, 350, 0, + 356, 357, 0, 413, 419, 420, 395, 82, 89, 121, + 188, 148, 106, 179, 423, 412, 0, 383, 426, 361, + 375, 434, 376, 377, 405, 347, 391, 139, 373, 0, + 364, 342, 370, 343, 362, 385, 103, 388, 360, 414, + 394, 425, 120, 432, 122, 399, 0, 160, 131, 0, + 0, 387, 416, 389, 410, 382, 406, 352, 398, 427, + 374, 403, 428, 0, 0, 0, 80, 0, 0, 0, + 0, 0, 0, 0, 0, 96, 0, 401, 422, 372, + 402, 404, 341, 400, 0, 345, 348, 433, 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, + 109, 411, 417, 381, 207, 421, 379, 378, 424, 146, + 0, 163, 111, 119, 83, 90, 0, 110, 137, 151, + 155, 415, 363, 371, 99, 369, 153, 141, 176, 396, + 142, 152, 123, 168, 147, 175, 183, 184, 165, 182, + 187, 157, 84, 164, 174, 97, 156, 86, 172, 162, + 129, 115, 116, 85, 0, 150, 102, 107, 101, 138, + 169, 170, 100, 190, 91, 181, 88, 338, 180, 136, + 167, 173, 130, 127, 87, 171, 128, 126, 118, 105, + 112, 144, 125, 145, 113, 133, 132, 134, 0, 344, + 0, 161, 178, 191, 94, 359, 166, 185, 186, 0, + 0, 95, 108, 104, 143, 339, 337, 114, 158, 117, + 124, 149, 189, 140, 154, 98, 177, 159, 355, 358, + 353, 354, 392, 393, 429, 430, 431, 409, 350, 0, + 356, 357, 0, 413, 419, 420, 395, 82, 89, 121, + 188, 148, 106, 179, 423, 412, 0, 383, 426, 361, + 375, 434, 376, 377, 405, 347, 391, 139, 373, 0, + 364, 342, 370, 343, 362, 385, 103, 388, 360, 414, + 394, 425, 120, 432, 122, 399, 0, 160, 131, 0, + 0, 387, 416, 389, 410, 382, 406, 352, 398, 427, + 374, 403, 428, 0, 0, 0, 205, 0, 0, 0, + 0, 0, 0, 0, 0, 96, 0, 401, 422, 372, + 402, 404, 341, 400, 0, 345, 348, 433, 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, + 109, 411, 417, 381, 207, 421, 379, 378, 424, 146, + 0, 163, 111, 119, 83, 90, 0, 110, 137, 151, + 155, 415, 363, 371, 99, 369, 153, 141, 176, 396, + 142, 152, 123, 168, 147, 175, 183, 184, 165, 182, + 187, 157, 84, 164, 174, 97, 156, 86, 172, 162, + 129, 115, 116, 85, 0, 150, 102, 107, 101, 138, + 169, 170, 100, 190, 91, 181, 88, 92, 180, 136, + 167, 173, 130, 127, 87, 171, 128, 126, 118, 105, + 112, 144, 125, 145, 113, 133, 132, 134, 0, 344, + 0, 161, 178, 191, 94, 359, 166, 185, 186, 0, + 0, 95, 108, 104, 143, 135, 93, 114, 158, 117, + 124, 149, 189, 140, 154, 98, 177, 159, 355, 358, + 353, 354, 392, 393, 429, 430, 431, 409, 350, 0, + 356, 357, 0, 413, 419, 420, 395, 82, 89, 121, + 188, 148, 106, 179, 423, 412, 0, 383, 426, 361, + 375, 434, 376, 377, 405, 347, 391, 139, 373, 0, + 364, 342, 370, 343, 362, 385, 103, 388, 360, 414, + 394, 425, 120, 432, 122, 399, 0, 160, 131, 0, + 0, 387, 416, 389, 410, 382, 406, 352, 398, 427, + 374, 403, 428, 0, 0, 0, 80, 0, 0, 0, + 0, 0, 0, 0, 0, 96, 0, 401, 422, 372, + 402, 404, 341, 400, 0, 345, 348, 433, 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, + 109, 411, 417, 381, 207, 421, 379, 378, 424, 146, + 0, 163, 111, 119, 83, 90, 0, 110, 137, 151, + 155, 415, 363, 371, 99, 369, 153, 141, 176, 396, + 142, 152, 123, 168, 147, 175, 183, 184, 165, 182, + 187, 157, 84, 164, 623, 97, 156, 86, 172, 162, + 129, 115, 116, 85, 0, 150, 102, 107, 101, 138, + 169, 170, 100, 190, 91, 181, 88, 338, 180, 136, + 167, 173, 130, 127, 87, 171, 128, 126, 118, 105, + 112, 144, 125, 145, 113, 133, 132, 134, 0, 344, + 0, 161, 178, 191, 94, 359, 166, 185, 186, 0, + 0, 95, 108, 104, 143, 339, 337, 114, 158, 117, + 124, 149, 189, 140, 154, 98, 177, 159, 355, 358, + 353, 354, 392, 393, 429, 430, 431, 409, 350, 0, + 356, 357, 0, 413, 419, 420, 395, 82, 89, 121, + 188, 148, 106, 179, 423, 412, 0, 383, 426, 361, + 375, 434, 376, 377, 405, 347, 391, 139, 373, 0, + 364, 342, 370, 343, 362, 385, 103, 388, 360, 414, + 394, 425, 120, 432, 122, 399, 0, 160, 131, 0, + 0, 387, 416, 389, 410, 382, 406, 352, 398, 427, + 374, 403, 428, 0, 0, 0, 80, 0, 0, 0, + 0, 0, 0, 0, 0, 96, 0, 401, 422, 372, + 402, 404, 341, 400, 0, 345, 348, 433, 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, + 109, 411, 417, 381, 207, 421, 379, 378, 424, 146, + 0, 163, 111, 119, 83, 90, 0, 110, 137, 151, + 155, 415, 363, 371, 99, 369, 153, 141, 176, 396, + 142, 152, 123, 168, 147, 175, 183, 184, 165, 182, + 187, 157, 84, 164, 329, 97, 156, 86, 172, 162, + 129, 115, 116, 85, 0, 150, 102, 107, 101, 138, + 169, 170, 100, 190, 91, 181, 88, 338, 180, 136, + 167, 173, 130, 127, 87, 171, 128, 126, 118, 105, + 112, 144, 125, 145, 113, 133, 132, 134, 0, 344, + 0, 161, 178, 191, 94, 359, 166, 185, 186, 0, + 0, 95, 108, 104, 143, 339, 337, 332, 331, 117, + 124, 149, 189, 140, 154, 98, 177, 159, 355, 358, + 353, 354, 392, 393, 429, 430, 431, 409, 350, 0, + 356, 357, 0, 413, 419, 420, 395, 82, 89, 121, + 188, 148, 106, 179, 139, 0, 0, 793, 0, 264, + 0, 0, 0, 103, 0, 261, 0, 0, 0, 120, + 304, 122, 0, 0, 160, 131, 0, 0, 0, 0, + 295, 296, 0, 0, 0, 0, 0, 0, 0, 0, + 54, 0, 0, 262, 283, 282, 285, 286, 287, 288, + 0, 0, 96, 284, 289, 290, 291, 0, 0, 0, + 259, 276, 0, 303, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 271, 272, 253, 0, 0, 0, - 315, 0, 273, 0, 0, 268, 269, 270, 275, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 109, 0, - 0, 0, 206, 0, 0, 313, 0, 146, 0, 163, - 111, 119, 83, 90, 0, 110, 137, 151, 155, 0, - 0, 0, 99, 0, 153, 141, 176, 0, 142, 152, - 123, 168, 147, 175, 183, 184, 165, 182, 186, 157, - 84, 164, 174, 97, 156, 86, 172, 162, 129, 115, - 116, 85, 0, 150, 102, 107, 101, 138, 169, 170, - 100, 189, 91, 181, 88, 92, 180, 136, 167, 173, - 130, 127, 87, 171, 128, 126, 118, 105, 112, 144, - 125, 145, 113, 133, 132, 134, 0, 0, 0, 161, - 178, 190, 94, 0, 166, 185, 0, 0, 95, 108, - 104, 143, 135, 93, 114, 158, 117, 124, 149, 188, - 140, 154, 98, 177, 159, 303, 314, 309, 310, 307, - 308, 306, 305, 304, 316, 295, 296, 297, 298, 300, - 0, 311, 312, 299, 82, 89, 121, 187, 148, 106, - 179, 139, 0, 0, 0, 0, 262, 0, 0, 0, - 103, 0, 259, 0, 0, 0, 120, 302, 122, 0, - 0, 160, 131, 0, 0, 0, 0, 293, 294, 0, - 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, - 260, 281, 800, 283, 284, 285, 286, 0, 0, 96, - 282, 287, 288, 289, 0, 0, 0, 257, 274, 0, - 301, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 273, 274, 255, 0, 0, 0, 317, + 0, 275, 0, 0, 270, 271, 272, 277, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 109, 0, 0, + 0, 207, 0, 0, 315, 0, 146, 0, 163, 111, + 119, 83, 90, 0, 110, 137, 151, 155, 0, 0, + 0, 99, 0, 153, 141, 176, 0, 142, 152, 123, + 168, 147, 175, 183, 184, 165, 182, 187, 157, 84, + 164, 174, 97, 156, 86, 172, 162, 129, 115, 116, + 85, 0, 150, 102, 107, 101, 138, 169, 170, 100, + 190, 91, 181, 88, 92, 180, 136, 167, 173, 130, + 127, 87, 171, 128, 126, 118, 105, 112, 144, 125, + 145, 113, 133, 132, 134, 0, 0, 0, 161, 178, + 191, 94, 0, 166, 185, 186, 0, 0, 95, 108, + 104, 143, 135, 93, 114, 158, 117, 124, 149, 189, + 140, 154, 98, 177, 159, 305, 316, 311, 312, 309, + 310, 308, 307, 306, 318, 297, 298, 299, 300, 302, + 0, 313, 314, 301, 82, 89, 121, 188, 148, 106, + 179, 139, 0, 0, 0, 0, 264, 0, 0, 0, + 103, 0, 261, 0, 0, 0, 120, 304, 122, 0, + 0, 160, 131, 0, 0, 0, 0, 295, 296, 0, + 0, 0, 0, 0, 0, 0, 0, 54, 0, 496, + 262, 283, 282, 285, 286, 287, 288, 0, 0, 96, + 284, 289, 290, 291, 0, 0, 0, 259, 276, 0, + 303, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 271, 272, 253, 0, 0, 0, 315, 0, 273, 0, - 0, 268, 269, 270, 275, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 109, 0, 0, 0, 206, 0, - 0, 313, 0, 146, 0, 163, 111, 119, 83, 90, + 273, 274, 0, 0, 0, 0, 317, 0, 275, 0, + 0, 270, 271, 272, 277, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 109, 0, 0, 0, 207, 0, + 0, 315, 0, 146, 0, 163, 111, 119, 83, 90, 0, 110, 137, 151, 155, 0, 0, 0, 99, 0, 153, 141, 176, 0, 142, 152, 123, 168, 147, 175, - 183, 184, 165, 182, 186, 157, 84, 164, 174, 97, + 183, 184, 165, 182, 187, 157, 84, 164, 174, 97, 156, 86, 172, 162, 129, 115, 116, 85, 0, 150, - 102, 107, 101, 138, 169, 170, 100, 189, 91, 181, + 102, 107, 101, 138, 169, 170, 100, 190, 91, 181, 88, 92, 180, 136, 167, 173, 130, 127, 87, 171, 128, 126, 118, 105, 112, 144, 125, 145, 113, 133, - 132, 134, 0, 0, 0, 161, 178, 190, 94, 0, - 166, 185, 0, 0, 95, 108, 104, 143, 135, 93, - 114, 158, 117, 124, 149, 188, 140, 154, 98, 177, - 159, 303, 314, 309, 310, 307, 308, 306, 305, 304, - 316, 295, 296, 297, 298, 300, 24, 311, 312, 299, - 82, 89, 121, 187, 148, 106, 179, 0, 139, 0, - 0, 0, 0, 262, 0, 0, 0, 103, 0, 259, - 0, 0, 0, 120, 302, 122, 0, 0, 160, 131, - 0, 0, 0, 0, 293, 294, 0, 0, 0, 0, - 0, 0, 0, 0, 54, 0, 0, 260, 281, 280, - 283, 284, 285, 286, 0, 0, 96, 282, 287, 288, - 289, 0, 0, 0, 257, 274, 0, 301, 0, 0, + 132, 134, 0, 0, 0, 161, 178, 191, 94, 0, + 166, 185, 186, 0, 0, 95, 108, 104, 143, 135, + 93, 114, 158, 117, 124, 149, 189, 140, 154, 98, + 177, 159, 305, 316, 311, 312, 309, 310, 308, 307, + 306, 318, 297, 298, 299, 300, 302, 0, 313, 314, + 301, 82, 89, 121, 188, 148, 106, 179, 139, 0, + 0, 0, 0, 264, 0, 0, 0, 103, 0, 261, + 0, 0, 0, 120, 304, 122, 0, 0, 160, 131, + 0, 0, 0, 0, 295, 296, 0, 0, 0, 0, + 0, 0, 0, 0, 54, 0, 0, 262, 283, 282, + 285, 286, 287, 288, 0, 0, 96, 284, 289, 290, + 291, 0, 0, 0, 259, 276, 0, 303, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 271, 272, 0, - 0, 0, 0, 315, 0, 273, 0, 0, 268, 269, - 270, 275, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 109, 0, 0, 0, 206, 0, 0, 313, 0, + 0, 0, 0, 0, 0, 0, 0, 273, 274, 255, + 0, 0, 0, 317, 0, 275, 0, 0, 270, 271, + 272, 277, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 109, 0, 0, 0, 207, 0, 0, 315, 0, 146, 0, 163, 111, 119, 83, 90, 0, 110, 137, 151, 155, 0, 0, 0, 99, 0, 153, 141, 176, 0, 142, 152, 123, 168, 147, 175, 183, 184, 165, - 182, 186, 157, 84, 164, 174, 97, 156, 86, 172, + 182, 187, 157, 84, 164, 174, 97, 156, 86, 172, 162, 129, 115, 116, 85, 0, 150, 102, 107, 101, - 138, 169, 170, 100, 189, 91, 181, 88, 92, 180, + 138, 169, 170, 100, 190, 91, 181, 88, 92, 180, 136, 167, 173, 130, 127, 87, 171, 128, 126, 118, 105, 112, 144, 125, 145, 113, 133, 132, 134, 0, - 0, 0, 161, 178, 190, 94, 0, 166, 185, 0, - 0, 95, 108, 104, 143, 135, 93, 114, 158, 117, - 124, 149, 188, 140, 154, 98, 177, 159, 303, 314, - 309, 310, 307, 308, 306, 305, 304, 316, 295, 296, - 297, 298, 300, 0, 311, 312, 299, 82, 89, 121, - 187, 148, 106, 179, 139, 0, 0, 0, 0, 262, - 0, 0, 0, 103, 0, 259, 0, 0, 0, 120, - 302, 122, 0, 0, 160, 131, 0, 0, 0, 0, - 293, 294, 0, 0, 0, 0, 0, 0, 0, 0, - 54, 0, 0, 260, 281, 280, 283, 284, 285, 286, - 0, 0, 96, 282, 287, 288, 289, 0, 0, 0, - 257, 274, 0, 301, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 271, 272, 0, 0, 0, 0, 315, - 0, 273, 0, 0, 268, 269, 270, 275, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 109, 0, 0, - 0, 206, 0, 0, 313, 0, 146, 0, 163, 111, - 119, 83, 90, 0, 110, 137, 151, 155, 0, 0, - 0, 99, 0, 153, 141, 176, 0, 142, 152, 123, - 168, 147, 175, 183, 184, 165, 182, 186, 157, 84, - 164, 174, 97, 156, 86, 172, 162, 129, 115, 116, - 85, 0, 150, 102, 107, 101, 138, 169, 170, 100, - 189, 91, 181, 88, 92, 180, 136, 167, 173, 130, - 127, 87, 171, 128, 126, 118, 105, 112, 144, 125, - 145, 113, 133, 132, 134, 0, 0, 0, 161, 178, - 190, 94, 0, 166, 185, 0, 0, 95, 108, 104, - 143, 135, 93, 114, 158, 117, 124, 149, 188, 140, - 154, 98, 177, 159, 303, 314, 309, 310, 307, 308, - 306, 305, 304, 316, 295, 296, 297, 298, 300, 0, - 311, 312, 299, 82, 89, 121, 187, 148, 106, 179, - 139, 0, 0, 0, 0, 0, 0, 0, 0, 103, - 0, 0, 0, 0, 0, 120, 302, 122, 0, 0, - 160, 131, 0, 0, 0, 0, 293, 294, 0, 0, - 0, 0, 0, 0, 0, 0, 54, 0, 0, 260, - 281, 280, 283, 284, 285, 286, 0, 0, 96, 282, - 287, 288, 289, 0, 0, 0, 0, 274, 0, 301, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 271, - 272, 0, 0, 0, 0, 315, 0, 273, 0, 0, - 268, 269, 270, 275, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 109, 0, 0, 0, 206, 0, 0, - 313, 0, 146, 0, 163, 111, 119, 83, 90, 0, - 110, 137, 151, 155, 0, 0, 0, 99, 0, 153, - 141, 176, 1421, 142, 152, 123, 168, 147, 175, 183, - 184, 165, 182, 186, 157, 84, 164, 174, 97, 156, - 86, 172, 162, 129, 115, 116, 85, 0, 150, 102, - 107, 101, 138, 169, 170, 100, 189, 91, 181, 88, - 92, 180, 136, 167, 173, 130, 127, 87, 171, 128, - 126, 118, 105, 112, 144, 125, 145, 113, 133, 132, - 134, 0, 0, 0, 161, 178, 190, 94, 0, 166, - 185, 0, 0, 95, 108, 104, 143, 135, 93, 114, - 158, 117, 124, 149, 188, 140, 154, 98, 177, 159, - 303, 314, 309, 310, 307, 308, 306, 305, 304, 316, - 295, 296, 297, 298, 300, 0, 311, 312, 299, 82, - 89, 121, 187, 148, 106, 179, 139, 0, 0, 0, - 0, 0, 0, 0, 0, 103, 0, 0, 0, 0, - 0, 120, 302, 122, 0, 0, 160, 131, 0, 0, - 0, 0, 293, 294, 0, 0, 0, 0, 0, 0, - 0, 0, 54, 0, 493, 260, 281, 280, 283, 284, - 285, 286, 0, 0, 96, 282, 287, 288, 289, 0, - 0, 0, 0, 274, 0, 301, 0, 0, 0, 0, + 0, 0, 161, 178, 191, 94, 0, 166, 185, 186, + 0, 0, 95, 108, 104, 143, 135, 93, 114, 158, + 117, 124, 149, 189, 140, 154, 98, 177, 159, 305, + 316, 311, 312, 309, 310, 308, 307, 306, 318, 297, + 298, 299, 300, 302, 0, 313, 314, 301, 82, 89, + 121, 188, 148, 106, 179, 139, 0, 0, 0, 0, + 264, 0, 0, 0, 103, 0, 261, 0, 0, 0, + 120, 304, 122, 0, 0, 160, 131, 0, 0, 0, + 0, 295, 296, 0, 0, 0, 0, 0, 0, 0, + 0, 54, 0, 0, 262, 283, 808, 285, 286, 287, + 288, 0, 0, 96, 284, 289, 290, 291, 0, 0, + 0, 259, 276, 0, 303, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 271, 272, 0, 0, 0, - 0, 315, 0, 273, 0, 0, 268, 269, 270, 275, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, - 0, 0, 0, 206, 0, 0, 313, 0, 146, 0, - 163, 111, 119, 83, 90, 0, 110, 137, 151, 155, - 0, 0, 0, 99, 0, 153, 141, 176, 0, 142, - 152, 123, 168, 147, 175, 183, 184, 165, 182, 186, - 157, 84, 164, 174, 97, 156, 86, 172, 162, 129, - 115, 116, 85, 0, 150, 102, 107, 101, 138, 169, - 170, 100, 189, 91, 181, 88, 92, 180, 136, 167, - 173, 130, 127, 87, 171, 128, 126, 118, 105, 112, - 144, 125, 145, 113, 133, 132, 134, 0, 0, 0, - 161, 178, 190, 94, 0, 166, 185, 0, 0, 95, + 0, 0, 0, 0, 273, 274, 255, 0, 0, 0, + 317, 0, 275, 0, 0, 270, 271, 272, 277, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 109, 0, + 0, 0, 207, 0, 0, 315, 0, 146, 0, 163, + 111, 119, 83, 90, 0, 110, 137, 151, 155, 0, + 0, 0, 99, 0, 153, 141, 176, 0, 142, 152, + 123, 168, 147, 175, 183, 184, 165, 182, 187, 157, + 84, 164, 174, 97, 156, 86, 172, 162, 129, 115, + 116, 85, 0, 150, 102, 107, 101, 138, 169, 170, + 100, 190, 91, 181, 88, 92, 180, 136, 167, 173, + 130, 127, 87, 171, 128, 126, 118, 105, 112, 144, + 125, 145, 113, 133, 132, 134, 0, 0, 0, 161, + 178, 191, 94, 0, 166, 185, 186, 0, 0, 95, 108, 104, 143, 135, 93, 114, 158, 117, 124, 149, - 188, 140, 154, 98, 177, 159, 303, 314, 309, 310, - 307, 308, 306, 305, 304, 316, 295, 296, 297, 298, - 300, 0, 311, 312, 299, 82, 89, 121, 187, 148, - 106, 179, 139, 0, 0, 0, 0, 0, 0, 0, - 0, 103, 0, 0, 0, 0, 0, 120, 302, 122, - 0, 0, 160, 131, 0, 0, 0, 0, 293, 294, + 189, 140, 154, 98, 177, 159, 305, 316, 311, 312, + 309, 310, 308, 307, 306, 318, 297, 298, 299, 300, + 302, 0, 313, 314, 301, 82, 89, 121, 188, 148, + 106, 179, 139, 0, 0, 0, 0, 264, 0, 0, + 0, 103, 0, 261, 0, 0, 0, 120, 304, 122, + 0, 0, 160, 131, 0, 0, 0, 0, 295, 296, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, - 0, 260, 281, 280, 283, 284, 285, 286, 0, 0, - 96, 282, 287, 288, 289, 0, 0, 0, 0, 274, - 0, 301, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 262, 283, 805, 285, 286, 287, 288, 0, 0, + 96, 284, 289, 290, 291, 0, 0, 0, 259, 276, + 0, 303, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 271, 272, 0, 0, 0, 0, 315, 0, 273, - 0, 0, 268, 269, 270, 275, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 109, 0, 0, 0, 206, - 0, 0, 313, 0, 146, 0, 163, 111, 119, 83, + 0, 273, 274, 255, 0, 0, 0, 317, 0, 275, + 0, 0, 270, 271, 272, 277, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 109, 0, 0, 0, 207, + 0, 0, 315, 0, 146, 0, 163, 111, 119, 83, 90, 0, 110, 137, 151, 155, 0, 0, 0, 99, 0, 153, 141, 176, 0, 142, 152, 123, 168, 147, - 175, 183, 184, 165, 182, 186, 157, 84, 164, 174, + 175, 183, 184, 165, 182, 187, 157, 84, 164, 174, 97, 156, 86, 172, 162, 129, 115, 116, 85, 0, - 150, 102, 107, 101, 138, 169, 170, 100, 189, 91, + 150, 102, 107, 101, 138, 169, 170, 100, 190, 91, 181, 88, 92, 180, 136, 167, 173, 130, 127, 87, 171, 128, 126, 118, 105, 112, 144, 125, 145, 113, - 133, 132, 134, 0, 0, 0, 161, 178, 190, 94, - 0, 166, 185, 0, 0, 95, 108, 104, 143, 135, - 93, 114, 158, 117, 124, 149, 188, 140, 154, 98, - 177, 159, 303, 314, 309, 310, 307, 308, 306, 305, - 304, 316, 295, 296, 297, 298, 300, 0, 311, 312, - 299, 82, 89, 121, 187, 148, 106, 179, 139, 0, - 0, 0, 0, 0, 0, 0, 0, 103, 0, 0, - 0, 0, 0, 120, 0, 122, 0, 0, 160, 131, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 80, 0, 0, - 0, 0, 0, 0, 0, 0, 96, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 133, 132, 134, 0, 0, 0, 161, 178, 191, 94, + 0, 166, 185, 186, 0, 0, 95, 108, 104, 143, + 135, 93, 114, 158, 117, 124, 149, 189, 140, 154, + 98, 177, 159, 305, 316, 311, 312, 309, 310, 308, + 307, 306, 318, 297, 298, 299, 300, 302, 24, 313, + 314, 301, 82, 89, 121, 188, 148, 106, 179, 0, + 139, 0, 0, 0, 0, 264, 0, 0, 0, 103, + 0, 261, 0, 0, 0, 120, 304, 122, 0, 0, + 160, 131, 0, 0, 0, 0, 295, 296, 0, 0, + 0, 0, 0, 0, 0, 0, 54, 0, 0, 262, + 283, 282, 285, 286, 287, 288, 0, 0, 96, 284, + 289, 290, 291, 0, 0, 0, 259, 276, 0, 303, 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, 273, + 274, 0, 0, 0, 0, 317, 0, 275, 0, 0, + 270, 271, 272, 277, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 109, 0, 0, 0, 207, 0, 0, + 315, 0, 146, 0, 163, 111, 119, 83, 90, 0, + 110, 137, 151, 155, 0, 0, 0, 99, 0, 153, + 141, 176, 0, 142, 152, 123, 168, 147, 175, 183, + 184, 165, 182, 187, 157, 84, 164, 174, 97, 156, + 86, 172, 162, 129, 115, 116, 85, 0, 150, 102, + 107, 101, 138, 169, 170, 100, 190, 91, 181, 88, + 92, 180, 136, 167, 173, 130, 127, 87, 171, 128, + 126, 118, 105, 112, 144, 125, 145, 113, 133, 132, + 134, 0, 0, 0, 161, 178, 191, 94, 0, 166, + 185, 186, 0, 0, 95, 108, 104, 143, 135, 93, + 114, 158, 117, 124, 149, 189, 140, 154, 98, 177, + 159, 305, 316, 311, 312, 309, 310, 308, 307, 306, + 318, 297, 298, 299, 300, 302, 0, 313, 314, 301, + 82, 89, 121, 188, 148, 106, 179, 139, 0, 0, + 0, 0, 264, 0, 0, 0, 103, 0, 261, 0, + 0, 0, 120, 304, 122, 0, 0, 160, 131, 0, + 0, 0, 0, 295, 296, 0, 0, 0, 0, 0, + 0, 0, 0, 54, 0, 0, 262, 283, 282, 285, + 286, 287, 288, 0, 0, 96, 284, 289, 290, 291, + 0, 0, 0, 259, 276, 0, 303, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 109, 0, 0, 0, 206, 0, 0, 0, 0, - 146, 0, 163, 111, 119, 83, 90, 0, 110, 137, - 151, 155, 0, 0, 0, 99, 0, 153, 141, 176, - 0, 142, 152, 123, 168, 147, 175, 183, 184, 165, - 182, 186, 157, 84, 164, 174, 97, 156, 86, 172, - 162, 129, 115, 116, 85, 0, 150, 102, 107, 101, - 138, 169, 170, 100, 189, 91, 181, 88, 92, 180, - 136, 167, 173, 130, 127, 87, 171, 128, 126, 118, - 105, 112, 144, 125, 145, 113, 133, 132, 134, 0, - 0, 0, 161, 178, 190, 94, 0, 166, 185, 0, + 0, 0, 0, 0, 0, 0, 273, 274, 0, 0, + 0, 0, 317, 0, 275, 0, 0, 270, 271, 272, + 277, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 109, 0, 0, 0, 207, 0, 0, 315, 0, 146, + 0, 163, 111, 119, 83, 90, 0, 110, 137, 151, + 155, 0, 0, 0, 99, 0, 153, 141, 176, 0, + 142, 152, 123, 168, 147, 175, 183, 184, 165, 182, + 187, 157, 84, 164, 174, 97, 156, 86, 172, 162, + 129, 115, 116, 85, 0, 150, 102, 107, 101, 138, + 169, 170, 100, 190, 91, 181, 88, 92, 180, 136, + 167, 173, 130, 127, 87, 171, 128, 126, 118, 105, + 112, 144, 125, 145, 113, 133, 132, 134, 0, 0, + 0, 161, 178, 191, 94, 0, 166, 185, 186, 0, 0, 95, 108, 104, 143, 135, 93, 114, 158, 117, - 124, 149, 188, 140, 154, 98, 177, 159, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 82, 89, 121, - 187, 148, 106, 179, 139, 0, 0, 0, 515, 0, + 124, 149, 189, 140, 154, 98, 177, 159, 305, 316, + 311, 312, 309, 310, 308, 307, 306, 318, 297, 298, + 299, 300, 302, 0, 313, 314, 301, 82, 89, 121, + 188, 148, 106, 179, 139, 0, 0, 0, 0, 0, 0, 0, 0, 103, 0, 0, 0, 0, 0, 120, - 0, 122, 0, 0, 160, 131, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 80, 0, 517, 0, 0, 0, 0, - 0, 0, 96, 0, 0, 0, 0, 0, 512, 511, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 513, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 304, 122, 0, 0, 160, 131, 0, 0, 0, 0, + 295, 296, 0, 0, 0, 0, 0, 0, 0, 0, + 54, 0, 0, 262, 283, 282, 285, 286, 287, 288, + 0, 0, 96, 284, 289, 290, 291, 0, 0, 0, + 0, 276, 0, 303, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 273, 274, 0, 0, 0, 0, 317, + 0, 275, 0, 0, 270, 271, 272, 277, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 0, 0, - 0, 206, 0, 0, 0, 0, 146, 0, 163, 111, + 0, 207, 0, 0, 315, 0, 146, 0, 163, 111, 119, 83, 90, 0, 110, 137, 151, 155, 0, 0, - 0, 99, 0, 153, 141, 176, 0, 142, 152, 123, - 168, 147, 175, 183, 184, 165, 182, 186, 157, 84, + 0, 99, 0, 153, 141, 176, 1427, 142, 152, 123, + 168, 147, 175, 183, 184, 165, 182, 187, 157, 84, 164, 174, 97, 156, 86, 172, 162, 129, 115, 116, 85, 0, 150, 102, 107, 101, 138, 169, 170, 100, - 189, 91, 181, 88, 92, 180, 136, 167, 173, 130, + 190, 91, 181, 88, 92, 180, 136, 167, 173, 130, 127, 87, 171, 128, 126, 118, 105, 112, 144, 125, 145, 113, 133, 132, 134, 0, 0, 0, 161, 178, - 190, 94, 0, 166, 185, 0, 0, 95, 108, 104, - 143, 135, 93, 114, 158, 117, 124, 149, 188, 140, - 154, 98, 177, 159, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 139, 0, 82, 89, 121, 187, 148, 106, 179, - 103, 0, 0, 0, 0, 0, 120, 0, 122, 0, - 0, 160, 131, 0, 0, 0, 0, 0, 0, 0, + 191, 94, 0, 166, 185, 186, 0, 0, 95, 108, + 104, 143, 135, 93, 114, 158, 117, 124, 149, 189, + 140, 154, 98, 177, 159, 305, 316, 311, 312, 309, + 310, 308, 307, 306, 318, 297, 298, 299, 300, 302, + 0, 313, 314, 301, 82, 89, 121, 188, 148, 106, + 179, 139, 0, 0, 0, 0, 0, 0, 0, 0, + 103, 0, 0, 0, 0, 0, 120, 304, 122, 0, + 0, 160, 131, 0, 0, 0, 0, 295, 296, 0, + 0, 0, 0, 0, 0, 0, 0, 54, 0, 496, + 262, 283, 282, 285, 286, 287, 288, 0, 0, 96, + 284, 289, 290, 291, 0, 0, 0, 0, 276, 0, + 303, 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, 96, - 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, 163, 111, 119, 83, 90, + 273, 274, 0, 0, 0, 0, 317, 0, 275, 0, + 0, 270, 271, 272, 277, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 109, 0, 0, 0, 207, 0, + 0, 315, 0, 146, 0, 163, 111, 119, 83, 90, 0, 110, 137, 151, 155, 0, 0, 0, 99, 0, 153, 141, 176, 0, 142, 152, 123, 168, 147, 175, - 183, 184, 165, 182, 186, 157, 84, 164, 174, 97, + 183, 184, 165, 182, 187, 157, 84, 164, 174, 97, 156, 86, 172, 162, 129, 115, 116, 85, 0, 150, - 102, 107, 101, 138, 169, 170, 100, 189, 91, 181, + 102, 107, 101, 138, 169, 170, 100, 190, 91, 181, 88, 92, 180, 136, 167, 173, 130, 127, 87, 171, 128, 126, 118, 105, 112, 144, 125, 145, 113, 133, - 132, 134, 0, 0, 0, 161, 178, 190, 94, 0, - 166, 185, 0, 0, 95, 108, 104, 143, 135, 93, - 114, 158, 117, 124, 149, 188, 140, 154, 98, 177, - 159, 0, 75, 0, 0, 0, 24, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 139, 0, - 82, 89, 121, 187, 148, 106, 179, 103, 0, 0, - 0, 0, 0, 120, 0, 122, 0, 0, 160, 131, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 54, 0, 0, 80, 0, 0, - 0, 0, 0, 0, 0, 0, 96, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 132, 134, 0, 0, 0, 161, 178, 191, 94, 0, + 166, 185, 186, 0, 0, 95, 108, 104, 143, 135, + 93, 114, 158, 117, 124, 149, 189, 140, 154, 98, + 177, 159, 305, 316, 311, 312, 309, 310, 308, 307, + 306, 318, 297, 298, 299, 300, 302, 0, 313, 314, + 301, 82, 89, 121, 188, 148, 106, 179, 139, 0, + 0, 0, 0, 0, 0, 0, 0, 103, 0, 0, + 0, 0, 0, 120, 304, 122, 0, 0, 160, 131, + 0, 0, 0, 0, 295, 296, 0, 0, 0, 0, + 0, 0, 0, 0, 54, 0, 0, 262, 283, 282, + 285, 286, 287, 288, 0, 0, 96, 284, 289, 290, + 291, 0, 0, 0, 0, 276, 0, 303, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 109, 0, 0, 0, 206, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 273, 274, 0, + 0, 0, 0, 317, 0, 275, 0, 0, 270, 271, + 272, 277, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 109, 0, 0, 0, 207, 0, 0, 315, 0, 146, 0, 163, 111, 119, 83, 90, 0, 110, 137, 151, 155, 0, 0, 0, 99, 0, 153, 141, 176, 0, 142, 152, 123, 168, 147, 175, 183, 184, 165, - 182, 186, 157, 84, 164, 174, 97, 156, 86, 172, + 182, 187, 157, 84, 164, 174, 97, 156, 86, 172, 162, 129, 115, 116, 85, 0, 150, 102, 107, 101, - 138, 169, 170, 100, 189, 91, 181, 88, 92, 180, + 138, 169, 170, 100, 190, 91, 181, 88, 92, 180, 136, 167, 173, 130, 127, 87, 171, 128, 126, 118, 105, 112, 144, 125, 145, 113, 133, 132, 134, 0, - 0, 0, 161, 178, 190, 94, 0, 166, 185, 0, - 0, 95, 108, 104, 143, 135, 93, 114, 158, 117, - 124, 149, 188, 140, 154, 98, 177, 159, 0, 0, - 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 139, 0, 82, 89, 121, - 187, 148, 106, 179, 103, 0, 0, 0, 0, 0, + 0, 0, 161, 178, 191, 94, 0, 166, 185, 186, + 0, 0, 95, 108, 104, 143, 135, 93, 114, 158, + 117, 124, 149, 189, 140, 154, 98, 177, 159, 305, + 316, 311, 312, 309, 310, 308, 307, 306, 318, 297, + 298, 299, 300, 302, 0, 313, 314, 301, 82, 89, + 121, 188, 148, 106, 179, 139, 0, 0, 0, 0, + 0, 0, 0, 0, 103, 0, 0, 0, 0, 0, 120, 0, 122, 0, 0, 160, 131, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 54, 0, 0, 204, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 80, 0, 0, 0, 0, 0, 0, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 530, 529, 539, 540, 532, 533, 534, 535, 536, 537, + 538, 531, 0, 0, 541, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 0, - 0, 0, 206, 0, 0, 0, 0, 146, 0, 163, + 0, 0, 207, 0, 0, 0, 0, 146, 0, 163, 111, 119, 83, 90, 0, 110, 137, 151, 155, 0, 0, 0, 99, 0, 153, 141, 176, 0, 142, 152, - 123, 168, 147, 175, 183, 184, 165, 182, 186, 157, + 123, 168, 147, 175, 183, 184, 165, 182, 187, 157, 84, 164, 174, 97, 156, 86, 172, 162, 129, 115, 116, 85, 0, 150, 102, 107, 101, 138, 169, 170, - 100, 189, 91, 181, 88, 92, 180, 136, 167, 173, + 100, 190, 91, 181, 88, 92, 180, 136, 167, 173, 130, 127, 87, 171, 128, 126, 118, 105, 112, 144, 125, 145, 113, 133, 132, 134, 0, 0, 0, 161, - 178, 190, 94, 0, 166, 185, 0, 0, 95, 108, - 104, 143, 135, 93, 114, 158, 117, 124, 149, 188, - 140, 154, 98, 177, 159, 0, 0, 0, 0, 0, + 178, 191, 94, 0, 166, 185, 186, 0, 0, 95, + 108, 104, 143, 135, 93, 114, 158, 117, 124, 149, + 189, 140, 154, 98, 177, 159, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 82, 89, 121, 187, 148, 106, - 179, 139, 0, 0, 0, 844, 0, 0, 0, 0, - 103, 0, 0, 0, 0, 0, 120, 0, 122, 0, - 0, 160, 131, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 82, 89, 121, 188, 148, + 106, 179, 139, 0, 0, 0, 518, 0, 0, 0, + 0, 103, 0, 0, 0, 0, 0, 120, 0, 122, + 0, 0, 160, 131, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 204, 0, 846, 0, 0, 0, 0, 0, 0, 96, + 0, 80, 0, 520, 0, 0, 0, 0, 0, 0, + 96, 0, 0, 0, 0, 0, 515, 514, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 516, 0, 0, 0, 0, 0, 0, 0, 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, 207, + 0, 0, 0, 0, 146, 0, 163, 111, 119, 83, + 90, 0, 110, 137, 151, 155, 0, 0, 0, 99, + 0, 153, 141, 176, 0, 142, 152, 123, 168, 147, + 175, 183, 184, 165, 182, 187, 157, 84, 164, 174, + 97, 156, 86, 172, 162, 129, 115, 116, 85, 0, + 150, 102, 107, 101, 138, 169, 170, 100, 190, 91, + 181, 88, 92, 180, 136, 167, 173, 130, 127, 87, + 171, 128, 126, 118, 105, 112, 144, 125, 145, 113, + 133, 132, 134, 0, 0, 0, 161, 178, 191, 94, + 0, 166, 185, 186, 0, 0, 95, 108, 104, 143, + 135, 93, 114, 158, 117, 124, 149, 189, 140, 154, + 98, 177, 159, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 139, 0, 82, 89, 121, 188, 148, 106, 179, 103, + 0, 0, 0, 0, 0, 120, 0, 122, 0, 0, + 160, 131, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, + 0, 0, 0, 0, 0, 0, 0, 0, 96, 0, + 0, 0, 0, 0, 74, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 109, 0, 0, 0, 206, 0, - 0, 0, 0, 146, 0, 163, 111, 119, 83, 90, - 0, 110, 137, 151, 155, 0, 0, 0, 99, 0, - 153, 141, 176, 0, 842, 152, 123, 168, 147, 175, - 183, 184, 165, 182, 186, 157, 84, 164, 174, 97, - 156, 86, 172, 162, 129, 115, 116, 85, 0, 150, - 102, 107, 101, 138, 169, 170, 100, 189, 91, 181, - 88, 92, 180, 136, 167, 173, 130, 127, 87, 171, - 128, 126, 118, 105, 112, 144, 125, 145, 113, 133, - 132, 134, 0, 0, 0, 161, 178, 190, 94, 0, - 166, 185, 0, 0, 95, 108, 104, 143, 135, 93, - 114, 158, 117, 124, 149, 188, 140, 154, 98, 177, - 159, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 163, 111, 119, 83, 90, 0, + 110, 137, 151, 155, 0, 0, 0, 99, 0, 153, + 141, 176, 0, 142, 152, 123, 168, 147, 175, 183, + 184, 165, 182, 187, 157, 84, 164, 174, 97, 156, + 86, 172, 162, 129, 115, 116, 85, 0, 150, 102, + 107, 101, 138, 169, 170, 100, 190, 91, 181, 88, + 92, 180, 136, 167, 173, 130, 127, 87, 171, 128, + 126, 118, 105, 112, 144, 125, 145, 113, 133, 132, + 134, 0, 0, 0, 161, 178, 191, 94, 0, 166, + 185, 186, 0, 0, 95, 108, 104, 143, 135, 93, + 114, 158, 117, 124, 149, 189, 140, 154, 98, 177, + 159, 0, 75, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 139, 0, - 82, 89, 121, 187, 148, 106, 179, 103, 0, 0, + 82, 89, 121, 188, 148, 106, 179, 103, 0, 0, 0, 0, 0, 120, 0, 122, 0, 0, 160, 131, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 80, 0, 0, - 739, 0, 0, 740, 0, 0, 96, 0, 0, 0, + 0, 0, 0, 0, 54, 0, 0, 80, 0, 0, + 0, 0, 0, 0, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 109, 0, 0, 0, 206, 0, 0, 0, 0, + 0, 109, 0, 0, 0, 207, 0, 0, 0, 0, 146, 0, 163, 111, 119, 83, 90, 0, 110, 137, 151, 155, 0, 0, 0, 99, 0, 153, 141, 176, 0, 142, 152, 123, 168, 147, 175, 183, 184, 165, - 182, 186, 157, 84, 164, 174, 97, 156, 86, 172, + 182, 187, 157, 84, 164, 174, 97, 156, 86, 172, 162, 129, 115, 116, 85, 0, 150, 102, 107, 101, - 138, 169, 170, 100, 189, 91, 181, 88, 92, 180, + 138, 169, 170, 100, 190, 91, 181, 88, 92, 180, 136, 167, 173, 130, 127, 87, 171, 128, 126, 118, 105, 112, 144, 125, 145, 113, 133, 132, 134, 0, - 0, 0, 161, 178, 190, 94, 0, 166, 185, 0, - 0, 95, 108, 104, 143, 135, 93, 114, 158, 117, - 124, 149, 188, 140, 154, 98, 177, 159, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 139, 0, 82, 89, 121, - 187, 148, 106, 179, 103, 0, 629, 0, 0, 0, - 120, 0, 122, 0, 0, 160, 131, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 80, 0, 628, 0, 0, 0, - 0, 0, 0, 96, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 109, 0, - 0, 0, 206, 0, 0, 0, 0, 146, 0, 163, - 111, 119, 83, 90, 0, 110, 137, 151, 155, 0, - 0, 0, 99, 0, 153, 141, 176, 0, 142, 152, - 123, 168, 147, 175, 183, 184, 165, 182, 186, 157, - 84, 164, 174, 97, 156, 86, 172, 162, 129, 115, - 116, 85, 0, 150, 102, 107, 101, 138, 169, 170, - 100, 189, 91, 181, 88, 92, 180, 136, 167, 173, - 130, 127, 87, 171, 128, 126, 118, 105, 112, 144, - 125, 145, 113, 133, 132, 134, 0, 0, 0, 161, - 178, 190, 94, 0, 166, 185, 0, 0, 95, 108, - 104, 143, 135, 93, 114, 158, 117, 124, 149, 188, - 140, 154, 98, 177, 159, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 139, 0, 82, 89, 121, 187, 148, 106, - 179, 103, 0, 0, 0, 0, 0, 120, 0, 122, - 0, 0, 160, 131, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, - 0, 204, 0, 0, 0, 0, 0, 0, 0, 0, - 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 109, 0, 0, 0, 206, - 0, 0, 0, 0, 146, 0, 163, 111, 119, 83, - 90, 0, 110, 137, 151, 155, 0, 0, 0, 99, - 0, 153, 141, 176, 0, 142, 152, 123, 168, 147, - 175, 183, 184, 165, 182, 186, 157, 84, 164, 174, - 97, 156, 86, 172, 162, 129, 115, 116, 85, 0, - 150, 102, 107, 101, 138, 169, 170, 100, 189, 91, - 181, 88, 92, 180, 136, 167, 173, 130, 127, 87, - 171, 128, 126, 118, 105, 112, 144, 125, 145, 113, - 133, 132, 134, 0, 0, 0, 161, 178, 190, 94, - 0, 166, 185, 0, 0, 95, 108, 104, 143, 135, - 93, 114, 158, 117, 124, 149, 188, 140, 154, 98, - 177, 159, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 139, - 0, 82, 89, 121, 187, 148, 106, 179, 103, 0, - 0, 0, 0, 0, 120, 0, 122, 0, 0, 160, - 131, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 204, 0, - 846, 0, 0, 0, 0, 0, 0, 96, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 109, 0, 0, 0, 206, 0, 0, 0, - 0, 146, 0, 163, 111, 119, 83, 90, 0, 110, - 137, 151, 155, 0, 0, 0, 99, 0, 153, 141, - 176, 0, 142, 152, 123, 168, 147, 175, 183, 184, - 165, 182, 186, 157, 84, 164, 174, 97, 156, 86, - 172, 162, 129, 115, 116, 85, 0, 150, 102, 107, - 101, 138, 169, 170, 100, 189, 91, 181, 88, 92, - 180, 136, 167, 173, 130, 127, 87, 171, 128, 126, - 118, 105, 112, 144, 125, 145, 113, 133, 132, 134, - 0, 0, 0, 161, 178, 190, 94, 0, 166, 185, + 0, 0, 161, 178, 191, 94, 0, 166, 185, 186, 0, 0, 95, 108, 104, 143, 135, 93, 114, 158, - 117, 124, 149, 188, 140, 154, 98, 177, 159, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 117, 124, 149, 189, 140, 154, 98, 177, 159, 0, + 0, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 139, 0, 82, 89, - 121, 187, 148, 106, 179, 103, 0, 0, 0, 0, + 121, 188, 148, 106, 179, 103, 0, 0, 0, 0, 0, 120, 0, 122, 0, 0, 160, 131, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 80, 0, 517, 0, 0, + 0, 0, 54, 0, 0, 205, 0, 0, 0, 0, 0, 0, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, - 0, 0, 0, 206, 0, 0, 0, 0, 146, 0, + 0, 0, 0, 207, 0, 0, 0, 0, 146, 0, 163, 111, 119, 83, 90, 0, 110, 137, 151, 155, 0, 0, 0, 99, 0, 153, 141, 176, 0, 142, - 152, 123, 168, 147, 175, 183, 184, 165, 182, 186, + 152, 123, 168, 147, 175, 183, 184, 165, 182, 187, 157, 84, 164, 174, 97, 156, 86, 172, 162, 129, 115, 116, 85, 0, 150, 102, 107, 101, 138, 169, - 170, 100, 189, 91, 181, 88, 92, 180, 136, 167, + 170, 100, 190, 91, 181, 88, 92, 180, 136, 167, 173, 130, 127, 87, 171, 128, 126, 118, 105, 112, 144, 125, 145, 113, 133, 132, 134, 0, 0, 0, - 161, 178, 190, 94, 0, 166, 185, 0, 0, 95, - 108, 104, 143, 135, 93, 114, 158, 117, 124, 149, - 188, 140, 154, 98, 177, 159, 0, 0, 0, 0, + 161, 178, 191, 94, 0, 166, 185, 186, 0, 0, + 95, 108, 104, 143, 135, 93, 114, 158, 117, 124, + 149, 189, 140, 154, 98, 177, 159, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 139, 82, 89, 121, 187, 148, - 106, 179, 599, 103, 0, 0, 0, 0, 0, 120, - 0, 122, 0, 0, 160, 131, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 82, 89, 121, 188, + 148, 106, 179, 139, 0, 0, 0, 849, 0, 0, + 0, 0, 103, 0, 0, 0, 0, 0, 120, 0, + 122, 0, 0, 160, 131, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 204, 0, 0, 0, 0, 0, 0, - 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 205, 0, 851, 0, 0, 0, 0, 0, + 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 109, 0, 0, - 0, 206, 0, 0, 0, 0, 146, 0, 163, 111, - 119, 83, 90, 0, 110, 137, 151, 155, 0, 0, - 0, 99, 0, 153, 141, 176, 0, 142, 152, 123, - 168, 147, 175, 183, 184, 165, 182, 186, 157, 84, - 164, 174, 97, 156, 86, 172, 162, 129, 115, 116, - 85, 0, 150, 102, 107, 101, 138, 169, 170, 100, - 189, 91, 181, 88, 92, 180, 136, 167, 173, 130, - 127, 87, 171, 128, 126, 118, 105, 112, 144, 125, - 145, 113, 133, 132, 134, 0, 0, 0, 161, 178, - 190, 94, 0, 166, 185, 0, 0, 95, 108, 104, - 143, 135, 93, 114, 158, 117, 124, 149, 188, 140, + 0, 0, 0, 0, 0, 0, 109, 0, 0, 0, + 207, 0, 0, 0, 0, 146, 0, 163, 111, 119, + 83, 90, 0, 110, 137, 151, 155, 0, 0, 0, + 99, 0, 153, 141, 176, 0, 847, 152, 123, 168, + 147, 175, 183, 184, 165, 182, 187, 157, 84, 164, + 174, 97, 156, 86, 172, 162, 129, 115, 116, 85, + 0, 150, 102, 107, 101, 138, 169, 170, 100, 190, + 91, 181, 88, 92, 180, 136, 167, 173, 130, 127, + 87, 171, 128, 126, 118, 105, 112, 144, 125, 145, + 113, 133, 132, 134, 0, 0, 0, 161, 178, 191, + 94, 0, 166, 185, 186, 0, 0, 95, 108, 104, + 143, 135, 93, 114, 158, 117, 124, 149, 189, 140, 154, 98, 177, 159, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 319, 0, 0, 0, 0, 0, - 0, 139, 0, 82, 89, 121, 187, 148, 106, 179, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 139, 0, 82, 89, 121, 188, 148, 106, 179, 103, 0, 0, 0, 0, 0, 120, 0, 122, 0, 0, 160, 131, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 204, 0, 0, 0, 0, 0, 0, 0, 0, 96, + 80, 0, 0, 744, 0, 0, 745, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 109, 0, 0, 0, 206, 0, + 0, 0, 0, 0, 109, 0, 0, 0, 207, 0, 0, 0, 0, 146, 0, 163, 111, 119, 83, 90, 0, 110, 137, 151, 155, 0, 0, 0, 99, 0, 153, 141, 176, 0, 142, 152, 123, 168, 147, 175, - 183, 184, 165, 182, 186, 157, 84, 164, 174, 97, + 183, 184, 165, 182, 187, 157, 84, 164, 174, 97, 156, 86, 172, 162, 129, 115, 116, 85, 0, 150, - 102, 107, 101, 138, 169, 170, 100, 189, 91, 181, + 102, 107, 101, 138, 169, 170, 100, 190, 91, 181, 88, 92, 180, 136, 167, 173, 130, 127, 87, 171, 128, 126, 118, 105, 112, 144, 125, 145, 113, 133, - 132, 134, 0, 0, 0, 161, 178, 190, 94, 0, - 166, 185, 0, 0, 95, 108, 104, 143, 135, 93, - 114, 158, 117, 124, 149, 188, 140, 154, 98, 177, - 159, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 139, 0, - 82, 89, 121, 187, 148, 106, 179, 103, 0, 0, - 0, 0, 0, 120, 0, 122, 0, 0, 160, 131, + 132, 134, 0, 0, 0, 161, 178, 191, 94, 0, + 166, 185, 186, 0, 0, 95, 108, 104, 143, 135, + 93, 114, 158, 117, 124, 149, 189, 140, 154, 98, + 177, 159, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 139, + 0, 82, 89, 121, 188, 148, 106, 179, 103, 0, + 632, 0, 0, 0, 120, 0, 122, 0, 0, 160, + 131, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 80, 0, + 631, 0, 0, 0, 0, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 204, 0, 0, - 0, 0, 0, 0, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 109, 0, 0, 0, 207, 0, 0, 0, + 0, 146, 0, 163, 111, 119, 83, 90, 0, 110, + 137, 151, 155, 0, 0, 0, 99, 0, 153, 141, + 176, 0, 142, 152, 123, 168, 147, 175, 183, 184, + 165, 182, 187, 157, 84, 164, 174, 97, 156, 86, + 172, 162, 129, 115, 116, 85, 0, 150, 102, 107, + 101, 138, 169, 170, 100, 190, 91, 181, 88, 92, + 180, 136, 167, 173, 130, 127, 87, 171, 128, 126, + 118, 105, 112, 144, 125, 145, 113, 133, 132, 134, + 0, 0, 0, 161, 178, 191, 94, 0, 166, 185, + 186, 0, 0, 95, 108, 104, 143, 135, 93, 114, + 158, 117, 124, 149, 189, 140, 154, 98, 177, 159, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 109, 0, 201, 0, 206, 0, 0, 0, 0, - 146, 0, 163, 111, 119, 83, 90, 0, 110, 137, - 151, 155, 0, 0, 0, 99, 0, 153, 141, 176, - 0, 142, 152, 123, 168, 147, 175, 183, 184, 165, - 182, 186, 157, 84, 164, 174, 97, 156, 86, 172, - 162, 129, 115, 116, 85, 0, 150, 102, 107, 101, - 138, 169, 170, 100, 189, 91, 181, 88, 92, 180, - 136, 167, 173, 130, 127, 87, 171, 128, 126, 118, - 105, 112, 144, 125, 145, 113, 133, 132, 134, 0, - 0, 0, 161, 178, 190, 94, 0, 166, 185, 0, + 0, 0, 0, 0, 0, 0, 0, 139, 0, 82, + 89, 121, 188, 148, 106, 179, 103, 0, 0, 0, + 0, 0, 120, 0, 122, 0, 0, 160, 131, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 54, 0, 0, 205, 0, 0, 0, + 0, 0, 0, 0, 0, 96, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 109, 0, 0, 0, 207, 0, 0, 0, 0, 146, + 0, 163, 111, 119, 83, 90, 0, 110, 137, 151, + 155, 0, 0, 0, 99, 0, 153, 141, 176, 0, + 142, 152, 123, 168, 147, 175, 183, 184, 165, 182, + 187, 157, 84, 164, 174, 97, 156, 86, 172, 162, + 129, 115, 116, 85, 0, 150, 102, 107, 101, 138, + 169, 170, 100, 190, 91, 181, 88, 92, 180, 136, + 167, 173, 130, 127, 87, 171, 128, 126, 118, 105, + 112, 144, 125, 145, 113, 133, 132, 134, 0, 0, + 0, 161, 178, 191, 94, 0, 166, 185, 186, 0, 0, 95, 108, 104, 143, 135, 93, 114, 158, 117, - 124, 149, 188, 140, 154, 98, 177, 159, 0, 0, + 124, 149, 189, 140, 154, 98, 177, 159, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 139, 0, 82, 89, 121, - 187, 148, 106, 179, 103, 0, 0, 0, 0, 0, + 188, 148, 106, 179, 103, 0, 0, 0, 0, 0, 120, 0, 122, 0, 0, 160, 131, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 80, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 205, 0, 851, 0, 0, 0, 0, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 0, - 0, 0, 206, 0, 0, 0, 0, 146, 0, 163, + 0, 0, 207, 0, 0, 0, 0, 146, 0, 163, 111, 119, 83, 90, 0, 110, 137, 151, 155, 0, 0, 0, 99, 0, 153, 141, 176, 0, 142, 152, - 123, 168, 147, 175, 183, 184, 165, 182, 186, 157, + 123, 168, 147, 175, 183, 184, 165, 182, 187, 157, 84, 164, 174, 97, 156, 86, 172, 162, 129, 115, 116, 85, 0, 150, 102, 107, 101, 138, 169, 170, - 100, 189, 91, 181, 88, 92, 180, 136, 167, 173, + 100, 190, 91, 181, 88, 92, 180, 136, 167, 173, 130, 127, 87, 171, 128, 126, 118, 105, 112, 144, 125, 145, 113, 133, 132, 134, 0, 0, 0, 161, - 178, 190, 94, 0, 166, 185, 0, 0, 95, 108, - 104, 143, 135, 93, 114, 158, 117, 124, 149, 188, - 140, 154, 98, 177, 159, 0, 0, 0, 0, 0, + 178, 191, 94, 0, 166, 185, 186, 0, 0, 95, + 108, 104, 143, 135, 93, 114, 158, 117, 124, 149, + 189, 140, 154, 98, 177, 159, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 139, 0, 82, 89, 121, 187, 148, 106, - 179, 103, 0, 0, 0, 0, 0, 120, 0, 122, + 0, 0, 0, 139, 0, 82, 89, 121, 188, 148, + 106, 179, 103, 0, 0, 0, 0, 0, 120, 0, + 122, 0, 0, 160, 131, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 80, 0, 520, 0, 0, 0, 0, 0, + 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 109, 0, 0, 0, + 207, 0, 0, 0, 0, 146, 0, 163, 111, 119, + 83, 90, 0, 110, 137, 151, 155, 0, 0, 0, + 99, 0, 153, 141, 176, 0, 142, 152, 123, 168, + 147, 175, 183, 184, 165, 182, 187, 157, 84, 164, + 174, 97, 156, 86, 172, 162, 129, 115, 116, 85, + 0, 150, 102, 107, 101, 138, 169, 170, 100, 190, + 91, 181, 88, 92, 180, 136, 167, 173, 130, 127, + 87, 171, 128, 126, 118, 105, 112, 144, 125, 145, + 113, 133, 132, 134, 0, 0, 0, 161, 178, 191, + 94, 0, 166, 185, 186, 0, 0, 95, 108, 104, + 143, 135, 93, 114, 158, 117, 124, 149, 189, 140, + 154, 98, 177, 159, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 139, 82, 89, 121, 188, 148, 106, 179, + 602, 103, 0, 0, 0, 0, 0, 120, 0, 122, 0, 0, 160, 131, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 204, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 205, 0, 0, 0, 0, 0, 0, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 109, 0, 0, 0, 206, + 0, 0, 0, 0, 0, 109, 0, 0, 0, 207, 0, 0, 0, 0, 146, 0, 163, 111, 119, 83, 90, 0, 110, 137, 151, 155, 0, 0, 0, 99, 0, 153, 141, 176, 0, 142, 152, 123, 168, 147, - 175, 183, 184, 165, 182, 186, 157, 84, 164, 174, + 175, 183, 184, 165, 182, 187, 157, 84, 164, 174, 97, 156, 86, 172, 162, 129, 115, 116, 85, 0, - 150, 102, 107, 101, 138, 169, 170, 100, 189, 91, + 150, 102, 107, 101, 138, 169, 170, 100, 190, 91, 181, 88, 92, 180, 136, 167, 173, 130, 127, 87, 171, 128, 126, 118, 105, 112, 144, 125, 145, 113, - 133, 132, 134, 0, 0, 0, 161, 178, 190, 94, - 0, 166, 185, 0, 0, 95, 108, 104, 143, 135, - 93, 114, 158, 117, 124, 149, 188, 140, 154, 98, - 177, 159, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 139, - 0, 82, 89, 121, 187, 148, 106, 179, 103, 0, - 0, 0, 0, 0, 120, 0, 122, 0, 0, 160, - 131, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 260, 0, - 0, 0, 0, 0, 0, 0, 0, 96, 0, 0, + 133, 132, 134, 0, 0, 0, 161, 178, 191, 94, + 0, 166, 185, 186, 0, 0, 95, 108, 104, 143, + 135, 93, 114, 158, 117, 124, 149, 189, 140, 154, + 98, 177, 159, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 321, 0, 0, 0, 0, 0, 0, + 139, 0, 82, 89, 121, 188, 148, 106, 179, 103, + 0, 0, 0, 0, 0, 120, 0, 122, 0, 0, + 160, 131, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 205, + 0, 0, 0, 0, 0, 0, 0, 0, 96, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 109, 0, 0, 0, 207, 0, 0, + 0, 0, 146, 0, 163, 111, 119, 83, 90, 0, + 110, 137, 151, 155, 0, 0, 0, 99, 0, 153, + 141, 176, 0, 142, 152, 123, 168, 147, 175, 183, + 184, 165, 182, 187, 157, 84, 164, 174, 97, 156, + 86, 172, 162, 129, 115, 116, 85, 0, 150, 102, + 107, 101, 138, 169, 170, 100, 190, 91, 181, 88, + 92, 180, 136, 167, 173, 130, 127, 87, 171, 128, + 126, 118, 105, 112, 144, 125, 145, 113, 133, 132, + 134, 0, 0, 0, 161, 178, 191, 94, 0, 166, + 185, 186, 0, 0, 95, 108, 104, 143, 135, 93, + 114, 158, 117, 124, 149, 189, 140, 154, 98, 177, + 159, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 139, 0, + 82, 89, 121, 188, 148, 106, 179, 103, 0, 0, + 0, 0, 0, 120, 0, 122, 0, 0, 160, 131, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 205, 0, 0, + 0, 0, 0, 0, 0, 0, 96, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 109, 0, 202, 0, 207, 0, 0, 0, 0, + 146, 0, 163, 111, 119, 83, 90, 0, 110, 137, + 151, 155, 0, 0, 0, 99, 0, 153, 141, 176, + 0, 142, 152, 123, 168, 147, 175, 183, 184, 165, + 182, 187, 157, 84, 164, 174, 97, 156, 86, 172, + 162, 129, 115, 116, 85, 0, 150, 102, 107, 101, + 138, 169, 170, 100, 190, 91, 181, 88, 92, 180, + 136, 167, 173, 130, 127, 87, 171, 128, 126, 118, + 105, 112, 144, 125, 145, 113, 133, 132, 134, 0, + 0, 0, 161, 178, 191, 94, 0, 166, 185, 186, + 0, 0, 95, 108, 104, 143, 135, 93, 114, 158, + 117, 124, 149, 189, 140, 154, 98, 177, 159, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 139, 0, 82, 89, + 121, 188, 148, 106, 179, 103, 0, 0, 0, 0, + 0, 120, 0, 122, 0, 0, 160, 131, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 80, 0, 0, 0, 0, + 0, 0, 0, 0, 96, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, + 0, 0, 0, 207, 0, 0, 0, 0, 146, 0, + 163, 111, 119, 83, 90, 0, 110, 137, 151, 155, + 0, 0, 0, 99, 0, 153, 141, 176, 0, 142, + 152, 123, 168, 147, 175, 183, 184, 165, 182, 187, + 157, 84, 164, 174, 97, 156, 86, 172, 162, 129, + 115, 116, 85, 0, 150, 102, 107, 101, 138, 169, + 170, 100, 190, 91, 181, 88, 92, 180, 136, 167, + 173, 130, 127, 87, 171, 128, 126, 118, 105, 112, + 144, 125, 145, 113, 133, 132, 134, 0, 0, 0, + 161, 178, 191, 94, 0, 166, 185, 186, 0, 0, + 95, 108, 104, 143, 135, 93, 114, 158, 117, 124, + 149, 189, 140, 154, 98, 177, 159, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 139, 0, 82, 89, 121, 188, + 148, 106, 179, 103, 0, 0, 0, 0, 0, 120, + 0, 122, 0, 0, 160, 131, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 205, 0, 0, 0, 0, 0, 0, + 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 109, 0, 0, + 0, 207, 0, 0, 0, 0, 146, 0, 163, 111, + 119, 83, 90, 0, 110, 137, 151, 155, 0, 0, + 0, 99, 0, 153, 141, 176, 0, 142, 152, 123, + 168, 147, 175, 183, 184, 165, 182, 187, 157, 84, + 164, 174, 97, 156, 86, 172, 162, 129, 115, 116, + 85, 0, 150, 102, 107, 101, 138, 169, 170, 100, + 190, 91, 181, 88, 92, 180, 136, 167, 173, 130, + 127, 87, 171, 128, 126, 118, 105, 112, 144, 125, + 145, 113, 133, 132, 134, 0, 0, 0, 161, 178, + 191, 94, 0, 166, 185, 186, 0, 0, 95, 108, + 104, 143, 135, 93, 114, 158, 117, 124, 149, 189, + 140, 154, 98, 177, 159, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 139, 0, 82, 89, 121, 188, 148, 106, + 179, 103, 0, 0, 0, 0, 0, 120, 0, 122, + 0, 0, 160, 131, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 262, 0, 0, 0, 0, 0, 0, 0, 0, + 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 109, 0, 0, 0, 206, 0, 0, 0, - 0, 146, 655, 163, 111, 119, 83, 90, 0, 110, - 137, 151, 155, 0, 0, 0, 99, 0, 153, 141, - 176, 0, 142, 152, 123, 168, 147, 175, 183, 184, - 165, 182, 186, 157, 84, 164, 174, 97, 156, 86, - 172, 162, 129, 115, 116, 85, 0, 150, 102, 107, - 101, 138, 169, 170, 100, 189, 91, 181, 88, 92, - 180, 136, 167, 173, 130, 127, 87, 171, 128, 126, - 118, 105, 112, 144, 125, 145, 113, 133, 132, 134, - 643, 0, 0, 161, 178, 190, 94, 0, 166, 185, - 0, 0, 95, 108, 104, 143, 135, 93, 114, 158, - 117, 124, 149, 188, 140, 154, 98, 177, 159, 0, - 0, 0, 0, 0, 0, 0, 0, 656, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 82, 89, - 121, 187, 148, 106, 179, 0, 0, 0, 0, 0, - 669, 672, 673, 674, 675, 676, 677, 0, 678, 679, - 680, 681, 682, 657, 658, 659, 660, 641, 642, 670, - 0, 644, 0, 645, 646, 647, 648, 649, 650, 651, - 652, 653, 654, 661, 662, 663, 664, 665, 666, 667, - 668, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 109, 0, 0, 0, 207, + 0, 0, 0, 0, 146, 0, 163, 111, 119, 83, + 90, 0, 110, 137, 151, 155, 0, 0, 0, 99, + 0, 153, 141, 176, 0, 142, 152, 123, 168, 147, + 175, 183, 184, 165, 182, 187, 157, 84, 164, 174, + 97, 156, 86, 172, 162, 129, 115, 116, 85, 0, + 150, 102, 107, 101, 138, 169, 170, 100, 190, 91, + 181, 88, 92, 180, 136, 167, 173, 130, 127, 87, + 171, 128, 126, 118, 105, 112, 144, 125, 145, 113, + 133, 132, 134, 0, 0, 0, 161, 178, 191, 94, + 0, 166, 185, 186, 0, 0, 95, 108, 104, 143, + 135, 93, 114, 158, 117, 124, 149, 189, 140, 154, + 98, 177, 159, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 671, + 0, 0, 82, 89, 121, 188, 148, 106, 179, } var yyPact = [...]int{ - 1469, -1000, -179, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + 1591, -1000, -188, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, 875, 935, -1000, -1000, -1000, -1000, -1000, -1000, + 327, 8842, 31, 118, 9, 11470, 116, 1561, 11946, -1000, + 2, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -62, -67, + -1000, 677, -1000, -1000, -1000, -1000, -1000, 853, 861, 744, + 847, 782, -1000, 6380, 74, 74, 11232, 5639, -1000, -1000, + 255, 11946, 110, 11946, -140, 67, 67, 67, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, 925, 971, -1000, -1000, -1000, -1000, -1000, -1000, - 353, 8963, -1, 136, -6, 11580, 135, 1582, 12054, -1000, - -9, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -80, -92, - -1000, 715, -1000, -1000, -1000, -1000, -1000, 920, 923, 761, - 911, 818, -1000, 6511, 101, 101, 11343, 5773, -1000, -1000, - 352, 12054, 129, 12054, -145, 91, 91, 91, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, @@ -1992,24 +1976,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, 114, 11946, 190, -1000, 11946, 65, 597, 65, + 65, 65, 11946, -1000, 169, -1000, -1000, -1000, 11946, 595, + 817, 3299, 73, 3299, -1000, 3299, 3299, -1000, 3299, 14, + 3299, -69, 894, 10, 1, -1000, 3299, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + 495, 825, 7369, 7369, 875, -1000, 677, -1000, -1000, -1000, + 816, -1000, -1000, 399, 922, -1000, 8604, 167, -1000, 7369, + 1920, 578, -1000, -1000, 578, -1000, -1000, 131, -1000, -1000, + 8110, 8110, 8110, 8110, 8110, 8110, 8110, 8110, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, 578, -1000, 7122, 578, 578, 578, 578, 578, + 578, 578, 578, 7369, 578, 578, 578, 578, 578, 578, + 578, 578, 578, 578, 578, 578, 578, 578, 578, 10994, + 10279, 11946, 640, 633, -1000, -1000, 158, 673, 5379, -116, + -1000, -1000, -1000, 269, 10041, -1000, -1000, -1000, 815, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, 133, 12054, 221, -1000, 12054, 82, 570, 82, 82, - 82, 12054, -1000, 187, -1000, -1000, -1000, 12054, 563, 868, - 3442, 50, 3442, -1000, 3442, 3442, -1000, 3442, 1, 3442, - -70, 936, -22, -1000, 3442, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 518, 880, - 7496, 7496, 925, -1000, 715, -1000, -1000, -1000, 849, -1000, - -1000, 397, 958, -1000, 8726, 185, -1000, 7496, 1769, 695, - -1000, -1000, 695, -1000, -1000, 148, -1000, -1000, 8234, 8234, - 8234, 8234, 8234, 8234, 8234, 8234, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - 695, -1000, 7250, 695, 695, 695, 695, 695, 695, 695, - 695, 7496, 695, 695, 695, 695, 695, 695, 695, 695, - 695, 695, 695, 695, 695, 695, 695, 11106, 10394, 12054, - 680, 677, -1000, -1000, 180, 709, 5514, -109, -1000, -1000, - -1000, 336, 10157, -1000, -1000, -1000, 847, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, @@ -2017,210 +2000,198 @@ var yyPact = [...]int{ -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, 591, 11946, -1000, 1956, -1000, + 586, 3299, 75, 581, 351, 580, 11946, 11946, 3299, 20, + 53, 49, 11946, 680, 80, 11946, 842, 745, 11946, 577, + 576, -1000, 5119, -1000, 3299, 3299, -1000, -1000, -1000, 3299, + 3299, 3299, 11946, 3299, 3299, -1000, -1000, -1000, -1000, 3299, + 3299, -1000, 917, 305, -1000, -1000, -1000, -1000, 7369, 208, + -1000, 743, -1000, -1000, -1000, -1000, -1000, -1000, 930, 197, + 335, 155, 674, -1000, 426, 853, 495, 782, 9803, 771, + -1000, -1000, 11946, -1000, 7369, 7369, 470, -1000, 10755, -1000, + -1000, 4079, 217, 8110, 432, 370, 8110, 8110, 8110, 8110, + 8110, 8110, 8110, 8110, 8110, 8110, 8110, 8110, 8110, 8110, + 8110, 445, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + 553, -1000, 677, 508, 508, 179, 179, 179, 179, 179, + 179, 179, 8357, 5886, 495, 575, 428, 7122, 6380, 6380, + 7369, 7369, 6874, 6627, 6380, 848, 320, 428, 12184, -1000, + -1000, 7863, -1000, -1000, -1000, -1000, -1000, 495, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, 11708, 11708, 6380, 6380, 6380, + 6380, 32, 11946, -1000, 632, 1108, -1000, -1000, -1000, 844, + 9318, 9565, 32, 658, 10279, 11946, -1000, -1000, 10279, 11946, + 3819, 4859, 673, -116, 664, -1000, -89, -94, 2479, 178, + -1000, -1000, -1000, -1000, 3039, 195, 592, 384, -52, -1000, + -1000, -1000, 678, -1000, 678, 678, 678, 678, -22, -22, + -22, -22, -1000, -1000, -1000, -1000, -1000, 709, 706, -1000, + 678, 678, 678, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, 698, 698, 698, 683, 683, 714, -1000, 11946, 3299, + 841, 3299, -1000, 142, -1000, 11708, 11708, 11946, 11946, 11946, + 126, 11946, 11946, 672, -1000, 11946, 3299, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, 646, 12054, -1000, 12392, -1000, 558, 3442, - 107, 550, 365, 531, 12054, 12054, 3442, 5, 66, 35, - 12054, 716, 105, 12054, 897, 791, 12054, 529, 527, -1000, - 5255, -1000, 3442, 3442, -1000, -1000, -1000, 3442, 3442, 3442, - 12054, 3442, 3442, -1000, -1000, -1000, -1000, 3442, 3442, -1000, - 957, 323, -1000, -1000, -1000, -1000, 7496, -1000, 790, -1000, - -1000, -1000, -1000, -1000, -1000, 966, 223, 517, 175, 713, - -1000, 498, 920, 518, 818, 9920, 801, -1000, -1000, 12054, - -1000, 7496, 7496, 416, -1000, 10868, -1000, -1000, 4219, 236, - 8234, 423, 305, 8234, 8234, 8234, 8234, 8234, 8234, 8234, - 8234, 8234, 8234, 8234, 8234, 8234, 8234, 8234, 450, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, -1000, 519, -1000, 715, - 694, 694, 195, 195, 195, 195, 195, 195, 195, 8480, - 6019, 518, 628, 344, 7250, 6511, 6511, 7496, 7496, 7003, - 6757, 6511, 915, 360, 344, 12291, -1000, -1000, 7988, -1000, - -1000, -1000, -1000, -1000, 518, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, 11817, 11817, 6511, 6511, 6511, 6511, 41, 12054, - -1000, 696, 731, -1000, -1000, -1000, 900, 9437, 9683, 41, - 586, 10394, 12054, -1000, -1000, 10394, 12054, 3960, 4996, 709, - -109, 673, -1000, -107, -122, 2624, 189, -1000, -1000, -1000, - -1000, 3183, 351, 579, 382, -74, -1000, -1000, -1000, 729, - -1000, 729, 729, 729, 729, -42, -42, -42, -42, -1000, - -1000, -1000, -1000, -1000, 769, 764, -1000, 729, 729, 729, + -1000, -1000, 11946, 336, 11946, 11946, 428, -1000, 489, 11946, + -1000, 787, 7369, 7369, 4599, 7369, -1000, -1000, -1000, 825, + -1000, 848, 865, -1000, 807, 806, 6380, -1000, -1000, 217, + 365, -1000, -1000, 375, -1000, -1000, -1000, -1000, 154, 578, + -1000, 2374, -1000, -1000, -1000, -1000, 432, 8110, 8110, 8110, + 1352, 2374, 2198, 902, 2463, 179, 237, 237, 180, 180, + 180, 180, 180, 332, 332, -1000, -1000, -1000, 495, -1000, + -1000, -1000, 495, 6380, 669, -1000, -1000, 7369, -1000, 495, + 570, 570, 439, 418, 289, 903, 570, 236, 901, 570, + 570, 6380, 338, -1000, 7369, 495, -1000, 153, -1000, 685, + 667, 666, 570, 495, 570, 570, 611, 578, -1000, 12184, + 10279, 10279, 10279, 10279, 10279, -1000, 774, 773, -1000, 757, + 754, 764, 11946, -1000, 572, 9318, 137, 578, -1000, 10517, + -1000, -1000, 887, 10279, 659, -1000, 659, -1000, 151, -1000, + -1000, 664, -116, -97, -1000, -1000, -1000, -1000, 428, -1000, + 461, 661, 2779, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + 691, 527, -1000, 832, 207, 204, 525, 831, -1000, -1000, + -1000, 819, -1000, 387, -54, -1000, -1000, 456, -22, -22, + -1000, -1000, 178, 812, 178, 178, 178, 488, 488, -1000, + -1000, -1000, -1000, 454, -1000, -1000, -1000, 448, -1000, 738, + 11708, 3299, -1000, -1000, -1000, -1000, 290, 290, 185, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 759, 759, - 759, 739, 739, 778, -1000, 12054, 3442, 895, 3442, -1000, - 83, -1000, 11817, 11817, 12054, 12054, 12054, 143, 12054, 12054, - 708, -1000, 12054, 3442, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 12054, - 386, 12054, 12054, 344, 12054, -1000, 831, 7496, 7496, 4737, - 7496, -1000, -1000, -1000, 880, -1000, 915, 924, -1000, 841, - 838, 6511, -1000, -1000, 236, 338, -1000, -1000, 390, -1000, - -1000, -1000, -1000, 166, 695, -1000, 1952, -1000, -1000, -1000, - -1000, 423, 8234, 8234, 8234, 145, 1952, 1935, 1071, 1413, - 195, 451, 451, 197, 197, 197, 197, 197, 395, 395, - -1000, -1000, -1000, 518, -1000, -1000, -1000, 518, 6511, 679, - -1000, -1000, 7496, -1000, 518, 615, 615, 376, 364, 271, - 941, 615, 269, 939, 615, 615, 6511, 350, -1000, 7496, - 518, -1000, 163, -1000, 704, 676, 674, 615, 518, 615, - 615, 780, 695, -1000, 12291, 10394, 10394, 10394, 10394, 10394, - -1000, 815, 812, -1000, 805, 804, 811, 12054, -1000, 619, - 9437, 171, 695, -1000, 10631, -1000, -1000, 935, 10394, 660, - -1000, 660, -1000, 156, -1000, -1000, 673, -109, -128, -1000, - -1000, -1000, -1000, 344, -1000, 488, 672, 2924, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, 755, 512, -1000, 884, 229, - 226, 510, 881, -1000, -1000, -1000, 850, -1000, 373, -76, - -1000, -1000, 455, -42, -42, -1000, -1000, 189, 846, 189, - 189, 189, 483, 483, -1000, -1000, -1000, -1000, 454, -1000, - -1000, -1000, 453, -1000, 787, 11817, 3442, -1000, -1000, -1000, - -1000, 179, 179, 202, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, 39, 771, -1000, -1000, -1000, - -1000, -16, 0, 103, -1000, 3442, -1000, 323, -1000, 482, - 7496, -1000, -1000, -1000, 827, 344, 344, 155, -1000, -1000, - 12054, -1000, -1000, -1000, -1000, 703, -1000, -1000, -1000, 3701, - 6511, -1000, 145, 1952, 1654, -1000, 8234, 8234, -1000, -1000, - 615, 6511, 344, -1000, -1000, -1000, 383, 450, 383, 8234, - 8234, -1000, 8234, 8234, -1000, -158, 692, 270, -1000, 7496, - 250, -1000, 4737, -1000, 8234, 8234, -1000, -1000, -1000, -1000, - 785, 12291, 695, -1000, 9200, 11817, 664, -1000, 311, 731, - 768, 784, 914, -1000, -1000, -1000, -1000, 808, -1000, 806, - -1000, -1000, -1000, -1000, -1000, 127, 126, 113, 11817, -1000, - 925, 7496, 660, -1000, -1000, 208, -1000, -1000, -117, -131, - -1000, -1000, -1000, 3183, -1000, 3183, 11817, 71, -1000, 510, - 510, -1000, -1000, -1000, 742, 783, 8234, -1000, -1000, -1000, - 569, 189, 189, -1000, 283, -1000, -1000, -1000, 603, -1000, - 601, 669, 599, 12054, -1000, -1000, -1000, -1000, -1000, -1000, + 30, 703, -1000, -1000, -1000, -1000, 5, 18, 79, -1000, + 3299, -1000, 305, -1000, 487, 7369, -1000, -1000, -1000, -1000, + 785, 428, 428, 144, -1000, -1000, 11946, -1000, -1000, -1000, + -1000, 653, -1000, -1000, -1000, 3559, 6380, -1000, 1352, 2374, + 1880, -1000, 8110, 8110, -1000, -1000, 570, 6380, 428, -1000, + -1000, -1000, 41, 445, 41, 8110, 8110, -1000, 8110, 8110, + -1000, -152, 663, 274, -1000, 7369, 404, -1000, 4599, -1000, + 8110, 8110, -1000, -1000, -1000, -1000, 724, 12184, 578, -1000, + 9080, 11708, 665, -1000, 261, 1108, 702, 723, 936, -1000, + -1000, -1000, -1000, 765, -1000, 758, -1000, -1000, -1000, -1000, + -1000, 109, 106, 101, 11708, -1000, 875, 7369, 659, -1000, + -1000, 193, -1000, -1000, -103, -118, -1000, -1000, -1000, 3039, + -1000, 3039, 11708, 46, -1000, 525, 525, -1000, -1000, -1000, + 690, 722, 8110, -1000, -1000, -1000, 552, 178, 178, -1000, + 226, -1000, -1000, -1000, 551, -1000, 549, 657, 545, 11946, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - 12054, -1000, -1000, -1000, -1000, -1000, 11817, -167, 508, 11817, - 11817, 11817, 12054, -1000, 386, -1000, 344, -1000, 4478, -1000, - 935, 10394, -1000, -1000, 518, -1000, 8234, 1952, 1952, -1000, - -1000, 518, 729, 729, -1000, 729, 739, -1000, 729, -18, - 729, -19, 518, 518, 1903, 1868, 1839, 1576, 695, -152, - -1000, 344, 7496, -1000, 1547, 1442, -1000, 888, 654, 655, - -1000, -1000, 6265, 518, 595, 154, 578, -1000, 925, 12291, - 7496, -1000, -1000, 7496, 736, -1000, 7496, -1000, -1000, -1000, - 695, 695, 695, 578, 920, 344, -1000, -1000, -1000, -1000, - 2924, -1000, 575, -1000, 729, -1000, -1000, -1000, 11817, -65, - 965, 1952, -1000, -1000, -1000, -1000, -1000, -42, 473, -42, - 444, -1000, 422, 3442, -1000, -1000, -1000, -1000, 882, -1000, - 4478, -1000, -1000, 728, 772, -1000, -1000, -1000, 932, 662, - -1000, 1952, -1000, -1000, 96, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, 8234, 8234, 8234, 8234, 8234, 518, 467, - 344, 8234, 8234, 879, -1000, 695, -1000, -1000, 712, 11817, - 11817, -1000, 11817, 920, -1000, 344, 344, 11817, 344, 11817, - 11817, 11817, 2347, -1000, 161, 11817, -1000, 568, -1000, 184, - -1000, -111, 189, -1000, 189, 549, 543, -1000, 695, 658, - -1000, 263, 11817, 12054, 930, 922, -1000, -1000, 704, 704, - 704, 704, 84, -1000, -1000, 704, 704, 964, -1000, 695, - -1000, 715, 153, -1000, -1000, -1000, 548, 542, 542, 542, - 171, 161, -1000, 491, 260, 461, -1000, 58, 11817, 378, - 875, -1000, 873, -1000, -1000, -1000, -1000, -1000, 16, 4478, - 3183, 536, -1000, -1000, 7496, 7496, -1000, -1000, -1000, -1000, - 518, 47, -171, -1000, -1000, 12291, 655, 518, 11817, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, 414, -1000, -1000, 12054, - -1000, -1000, 396, -1000, -1000, 525, -1000, 11817, -1000, -1000, - 771, 344, 606, -1000, 826, -165, -174, 590, -1000, -1000, - -1000, 727, -1000, -1000, 16, 837, -167, -1000, 821, -1000, - 11817, -1000, 12, -1000, -169, 501, 9, -172, 781, 695, - -176, 770, -1000, 955, 7742, -1000, -1000, 962, 196, 196, - 704, 518, -1000, -1000, -1000, 69, 437, -1000, -1000, -1000, - -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, 11946, -1000, -1000, -1000, + -1000, -1000, 11708, -177, 521, 11708, 11708, 11708, 11946, -1000, + 336, -1000, 428, -1000, 4339, -1000, 887, 10279, -1000, -1000, + 495, -1000, 8110, 2374, 2374, -1000, -1000, 495, 678, 678, + -1000, 678, 683, -1000, 678, -4, 678, -5, 495, 495, + 2149, 2092, 1936, 1865, 578, -147, -1000, 428, 7369, -1000, + 1801, 1429, -1000, 826, 605, 624, -1000, -1000, 6133, 495, + 543, 139, 539, -1000, 875, 12184, 7369, -1000, -1000, 7369, + 682, -1000, 7369, -1000, -1000, -1000, 578, 578, 578, 539, + 853, 428, -1000, -1000, -1000, -1000, 2779, -1000, 537, -1000, + 678, -1000, -1000, -1000, 11708, -47, 929, 2374, -1000, -1000, + -1000, -1000, -1000, -22, 484, -22, 437, -1000, 409, 3299, + -1000, -1000, -1000, -1000, 835, -1000, 4339, -1000, -1000, 651, + 712, -1000, -1000, -1000, 885, 646, -1000, 2374, -1000, -1000, + 107, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 8110, + 8110, 8110, 8110, 8110, 495, 471, 428, 8110, 8110, 827, + -1000, 578, -1000, -1000, 650, 11708, 11708, -1000, 11708, 853, + -1000, 428, 428, 11708, 428, 11708, 11708, 11708, 2201, -1000, + 138, 11708, -1000, 535, -1000, 161, -1000, -119, 178, -1000, + 178, 546, 532, -1000, 578, 639, -1000, 235, 11708, 11946, + 883, 856, -1000, -1000, 685, 685, 685, 685, -6, -1000, + -1000, 685, 685, 928, -1000, 578, -1000, 677, 136, -1000, + -1000, -1000, 531, 517, 517, 517, 137, 138, -1000, 498, + 215, 466, -1000, 42, 11708, 391, 823, -1000, 821, -1000, + -1000, -1000, -1000, -1000, 29, 4339, 3039, 506, -1000, -1000, + 7369, 7369, -1000, -1000, -1000, -1000, 495, 56, -180, -1000, + -1000, 12184, 624, 495, 11708, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, 408, -1000, -1000, 11946, -1000, -1000, 462, -1000, + -1000, 504, -1000, 11708, -1000, -1000, 703, 428, 619, -1000, + 781, -157, -183, 604, -1000, -1000, -1000, 612, -1000, -1000, + 29, 804, -177, -1000, 778, -1000, 11708, -1000, 26, -1000, + -178, 494, 24, -181, 721, 578, -184, 719, -1000, 914, + 7616, -1000, -1000, 927, 160, 160, 685, 495, -1000, -1000, + -1000, 50, 438, -1000, -1000, -1000, -1000, -1000, -1000, } var yyPgo = [...]int{ - 0, 1212, 45, 519, 1209, 1208, 1206, 1200, 1198, 1197, - 1192, 1189, 1188, 1187, 1186, 1185, 1182, 1181, 1180, 1179, - 1160, 1158, 1157, 1152, 1150, 1149, 142, 1148, 1147, 1145, - 76, 1143, 70, 1142, 1141, 48, 413, 52, 44, 953, - 1140, 24, 71, 66, 1139, 38, 1138, 1137, 82, 1136, - 1134, 55, 1132, 1131, 92, 1130, 73, 1128, 12, 30, - 1127, 1126, 1125, 1124, 77, 467, 1123, 1118, 15, 1117, - 1116, 95, 1115, 57, 10, 14, 22, 27, 1114, 100, - 7, 1109, 56, 1108, 1106, 1104, 1103, 21, 1102, 54, - 1100, 18, 59, 1086, 9, 75, 31, 25, 8, 87, - 60, 1083, 26, 63, 47, 1082, 1081, 452, 1080, 1079, - 58, 1078, 1077, 29, 148, 434, 1075, 1072, 1071, 1068, - 42, 0, 874, 432, 69, 1067, 1066, 1065, 1629, 40, - 50, 17, 1063, 33, 174, 43, 1059, 1058, 41, 1055, - 1052, 1050, 1049, 1048, 1044, 1042, 20, 1041, 1040, 1038, - 19, 23, 1037, 1036, 64, 28, 1034, 1033, 1032, 51, - 65, 1029, 1028, 53, 37, 1027, 1025, 1024, 1022, 1017, - 34, 13, 1014, 16, 1013, 4, 1012, 35, 1009, 5, - 990, 11, 989, 2, 987, 6, 49, 3, 986, 1, - 982, 981, 61, 601, 83, 977, 115, + 0, 1175, 99, 523, 1174, 1173, 1171, 1168, 1165, 1164, + 1163, 1162, 1161, 1160, 1159, 1155, 1148, 1147, 1145, 1144, + 1143, 1132, 1131, 1130, 1127, 1126, 117, 1123, 1121, 1115, + 66, 1114, 73, 1111, 1110, 48, 839, 54, 40, 314, + 1106, 21, 85, 46, 1104, 37, 1101, 1098, 78, 1097, + 1096, 45, 1093, 1091, 202, 1088, 65, 1087, 11, 56, + 1086, 1085, 1084, 1083, 69, 862, 1081, 1078, 14, 1077, + 1076, 102, 1074, 52, 7, 8, 27, 22, 1071, 857, + 6, 1070, 50, 1069, 1068, 1065, 1061, 26, 1059, 57, + 1058, 31, 51, 1057, 9, 60, 30, 20, 5, 75, + 58, 1056, 19, 59, 47, 1055, 1053, 488, 1052, 1049, + 43, 1044, 1042, 25, 1041, 192, 401, 1040, 1039, 1038, + 1037, 42, 0, 545, 236, 70, 1035, 1034, 1033, 1478, + 34, 53, 16, 1018, 64, 268, 38, 1014, 1013, 35, + 1008, 1007, 995, 993, 992, 991, 986, 165, 977, 974, + 973, 18, 24, 972, 970, 63, 23, 968, 966, 965, + 44, 55, 964, 963, 49, 33, 962, 961, 959, 957, + 956, 29, 10, 955, 15, 954, 13, 952, 28, 950, + 4, 949, 12, 948, 3, 947, 17, 41, 1, 946, + 2, 944, 942, 61, 529, 71, 941, 76, } var yyR1 = [...]int{ - 0, 190, 191, 191, 1, 1, 1, 1, 1, 1, + 0, 191, 192, 192, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 6, 3, 4, 4, 5, 5, 7, 7, 29, 29, 8, 9, 9, - 9, 9, 194, 194, 48, 48, 49, 49, 95, 95, + 9, 9, 195, 195, 48, 48, 49, 49, 95, 95, 10, 10, 10, 10, 100, 100, 104, 104, 104, 105, - 105, 105, 105, 136, 136, 11, 11, 11, 11, 11, - 11, 11, 185, 185, 184, 183, 183, 182, 182, 181, - 17, 166, 168, 168, 167, 167, 167, 167, 160, 139, - 139, 139, 139, 142, 142, 140, 140, 140, 140, 140, - 140, 140, 140, 140, 141, 141, 141, 141, 141, 143, - 143, 143, 143, 143, 144, 144, 144, 144, 144, 144, - 144, 144, 144, 144, 144, 144, 144, 144, 144, 145, - 145, 145, 145, 145, 145, 145, 145, 159, 159, 146, - 146, 154, 154, 155, 155, 155, 152, 152, 153, 153, - 156, 156, 156, 148, 148, 149, 149, 157, 157, 150, - 150, 150, 151, 151, 151, 158, 158, 158, 158, 158, - 147, 147, 161, 161, 176, 176, 175, 175, 175, 165, - 165, 172, 172, 172, 172, 172, 163, 163, 164, 164, - 174, 174, 173, 162, 162, 177, 177, 177, 177, 188, - 189, 187, 187, 187, 187, 187, 169, 169, 169, 170, - 170, 170, 171, 171, 171, 12, 12, 12, 12, 12, + 105, 105, 105, 137, 137, 11, 11, 11, 11, 11, + 11, 11, 186, 186, 185, 184, 184, 183, 183, 182, + 17, 167, 169, 169, 168, 168, 168, 168, 161, 140, + 140, 140, 140, 143, 143, 141, 141, 141, 141, 141, + 141, 141, 141, 141, 142, 142, 142, 142, 142, 144, + 144, 144, 144, 144, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 146, + 146, 146, 146, 146, 146, 146, 146, 160, 160, 147, + 147, 155, 155, 156, 156, 156, 153, 153, 154, 154, + 157, 157, 157, 149, 149, 150, 150, 158, 158, 151, + 151, 151, 152, 152, 152, 159, 159, 159, 159, 159, + 148, 148, 162, 162, 177, 177, 176, 176, 176, 166, + 166, 173, 173, 173, 173, 173, 164, 164, 165, 165, + 175, 175, 174, 163, 163, 178, 178, 178, 178, 189, + 190, 188, 188, 188, 188, 188, 170, 170, 170, 171, + 171, 171, 172, 172, 172, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, - 186, 180, 178, 178, 179, 179, 13, 18, 18, 14, + 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, + 187, 181, 179, 179, 180, 180, 13, 18, 18, 14, 14, 14, 14, 14, 15, 15, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 111, 111, 109, 109, 112, 112, - 110, 110, 110, 113, 113, 113, 137, 137, 137, 21, - 21, 23, 23, 24, 25, 22, 22, 22, 22, 22, - 22, 22, 16, 195, 26, 27, 27, 28, 28, 28, - 32, 32, 32, 30, 30, 31, 31, 37, 37, 36, - 36, 38, 38, 38, 38, 125, 125, 125, 124, 124, - 40, 40, 41, 41, 42, 42, 43, 43, 43, 43, - 57, 57, 94, 94, 96, 96, 44, 44, 44, 44, - 45, 45, 46, 46, 47, 47, 132, 132, 131, 131, - 131, 130, 130, 50, 50, 50, 52, 51, 51, 51, - 51, 53, 53, 55, 55, 54, 54, 56, 58, 58, - 58, 58, 59, 59, 39, 39, 39, 39, 39, 39, - 39, 108, 108, 61, 61, 60, 60, 60, 60, 60, - 60, 60, 60, 60, 60, 72, 72, 72, 72, 72, - 72, 62, 62, 62, 62, 62, 62, 62, 35, 35, - 73, 73, 73, 79, 74, 74, 65, 65, 65, 65, + 20, 20, 20, 20, 20, 111, 111, 109, 109, 112, + 112, 110, 110, 110, 113, 113, 113, 114, 114, 138, + 138, 138, 21, 21, 23, 23, 24, 25, 22, 22, + 22, 22, 22, 22, 22, 16, 196, 26, 27, 27, + 28, 28, 28, 32, 32, 32, 30, 30, 31, 31, + 37, 37, 36, 36, 38, 38, 38, 38, 126, 126, + 126, 125, 125, 40, 40, 41, 41, 42, 42, 43, + 43, 43, 43, 57, 57, 94, 94, 96, 96, 44, + 44, 44, 44, 45, 45, 46, 46, 47, 47, 133, + 133, 132, 132, 132, 131, 131, 50, 50, 50, 52, + 51, 51, 51, 51, 53, 53, 55, 55, 54, 54, + 56, 58, 58, 58, 58, 59, 59, 39, 39, 39, + 39, 39, 39, 39, 108, 108, 61, 61, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, 72, 72, + 72, 72, 72, 72, 62, 62, 62, 62, 62, 62, + 62, 35, 35, 73, 73, 73, 79, 74, 74, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, - 65, 65, 65, 65, 65, 65, 65, 65, 69, 69, - 69, 67, 67, 67, 67, 67, 67, 67, 67, 67, - 67, 67, 67, 67, 68, 68, 68, 68, 68, 68, + 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, + 65, 69, 69, 69, 67, 67, 67, 67, 67, 67, + 67, 67, 67, 67, 67, 67, 67, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, - 196, 196, 71, 70, 70, 70, 70, 70, 70, 33, - 33, 33, 33, 33, 135, 135, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 83, - 83, 34, 34, 81, 81, 82, 84, 84, 80, 80, - 80, 64, 64, 64, 64, 64, 64, 64, 64, 66, - 66, 66, 85, 85, 86, 86, 87, 87, 88, 88, - 89, 90, 90, 90, 91, 91, 91, 91, 92, 92, - 92, 63, 63, 63, 63, 63, 63, 93, 93, 93, - 93, 97, 97, 75, 75, 77, 77, 76, 78, 98, - 98, 102, 99, 99, 103, 103, 103, 103, 101, 101, - 101, 127, 127, 127, 106, 106, 114, 114, 115, 115, - 107, 107, 116, 116, 116, 116, 116, 116, 116, 116, - 116, 116, 117, 117, 117, 118, 118, 119, 119, 119, - 126, 126, 122, 122, 123, 123, 128, 128, 129, 129, - 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, - 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, - 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, - 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, - 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, - 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, - 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, - 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, - 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, - 120, 120, 120, 120, 120, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 68, 68, 68, 197, 197, 71, 70, 70, 70, 70, + 70, 70, 33, 33, 33, 33, 33, 136, 136, 139, + 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, + 139, 139, 83, 83, 34, 34, 81, 81, 82, 84, + 84, 80, 80, 80, 64, 64, 64, 64, 64, 64, + 64, 64, 66, 66, 66, 85, 85, 86, 86, 87, + 87, 88, 88, 89, 90, 90, 90, 91, 91, 91, + 91, 92, 92, 92, 63, 63, 63, 63, 63, 63, + 93, 93, 93, 93, 97, 97, 75, 75, 77, 77, + 76, 78, 98, 98, 102, 99, 99, 103, 103, 103, + 103, 101, 101, 101, 128, 128, 128, 106, 106, 115, + 115, 116, 116, 107, 107, 117, 117, 117, 117, 117, + 117, 117, 117, 117, 117, 118, 118, 118, 119, 119, + 120, 120, 120, 127, 127, 123, 123, 124, 124, 129, + 129, 130, 130, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, @@ -2229,9 +2200,19 @@ var yyR1 = [...]int{ 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 192, 193, 133, 134, 134, - 134, + 121, 121, 121, 121, 121, 121, 121, 121, 122, 122, + 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, + 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, + 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, + 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, + 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, + 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, + 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, + 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, + 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, + 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, + 122, 122, 122, 122, 122, 122, 122, 122, 122, 193, + 194, 134, 135, 135, 135, } var yyR2 = [...]int{ @@ -2262,43 +2243,43 @@ var yyR2 = [...]int{ 1, 7, 1, 3, 8, 8, 3, 3, 5, 4, 6, 5, 4, 4, 3, 2, 3, 4, 4, 3, 4, 4, 4, 4, 4, 4, 3, 2, 3, 3, - 2, 3, 4, 3, 7, 5, 4, 2, 4, 3, - 3, 5, 2, 3, 1, 1, 0, 1, 1, 1, - 0, 2, 2, 0, 2, 2, 0, 1, 1, 2, - 1, 1, 2, 1, 1, 2, 2, 2, 2, 2, - 3, 3, 2, 0, 2, 0, 2, 1, 2, 2, - 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, - 3, 1, 2, 3, 5, 0, 1, 2, 1, 1, - 0, 2, 1, 3, 1, 1, 1, 3, 1, 3, - 3, 7, 1, 3, 1, 3, 4, 4, 4, 3, - 2, 4, 0, 1, 0, 2, 0, 1, 0, 1, - 2, 1, 1, 1, 2, 2, 1, 2, 3, 2, - 3, 2, 2, 2, 1, 1, 3, 3, 0, 5, - 5, 5, 0, 2, 1, 3, 3, 2, 3, 1, - 2, 0, 3, 1, 1, 3, 3, 4, 4, 5, - 3, 4, 5, 6, 2, 1, 2, 1, 2, 1, - 2, 1, 1, 1, 1, 1, 1, 1, 0, 2, - 1, 1, 1, 3, 1, 3, 1, 1, 1, 1, - 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, - 2, 2, 2, 3, 1, 1, 1, 1, 4, 5, - 6, 4, 4, 6, 6, 6, 8, 8, 8, 8, - 9, 7, 5, 4, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 8, 8, - 0, 2, 3, 4, 4, 4, 4, 4, 4, 0, - 3, 4, 7, 3, 1, 1, 2, 3, 3, 1, - 2, 2, 1, 2, 1, 2, 2, 1, 2, 0, - 1, 0, 2, 1, 2, 4, 0, 2, 1, 3, - 5, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 2, 2, 0, 3, 0, 2, 0, 3, 1, 3, - 2, 0, 1, 1, 0, 2, 4, 4, 0, 2, - 4, 2, 1, 3, 5, 4, 6, 1, 3, 3, - 5, 0, 5, 1, 3, 1, 2, 3, 1, 1, - 3, 3, 1, 3, 3, 3, 3, 3, 1, 2, - 1, 1, 1, 1, 1, 1, 0, 2, 0, 3, - 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, - 0, 2, 1, 1, 1, 1, 1, 1, 1, 1, + 2, 3, 4, 3, 7, 5, 4, 2, 4, 4, + 3, 3, 5, 2, 3, 1, 1, 0, 1, 1, + 1, 0, 2, 2, 0, 2, 2, 0, 2, 0, + 1, 1, 2, 1, 1, 2, 1, 1, 2, 2, + 2, 2, 2, 3, 3, 2, 0, 2, 0, 2, + 1, 2, 2, 0, 1, 1, 0, 1, 0, 1, + 0, 1, 1, 3, 1, 2, 3, 5, 0, 1, + 2, 1, 1, 0, 2, 1, 3, 1, 1, 1, + 3, 1, 3, 3, 7, 1, 3, 1, 3, 4, + 4, 4, 3, 2, 4, 0, 1, 0, 2, 0, + 1, 0, 1, 2, 1, 1, 1, 2, 2, 1, + 2, 3, 2, 3, 2, 2, 2, 1, 1, 3, + 3, 0, 5, 5, 5, 0, 2, 1, 3, 3, + 2, 3, 1, 2, 0, 3, 1, 1, 3, 3, + 4, 4, 5, 3, 4, 5, 6, 2, 1, 2, + 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, + 1, 0, 2, 1, 1, 1, 3, 1, 3, 1, + 1, 1, 1, 1, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, + 2, 2, 2, 2, 2, 2, 3, 1, 1, 1, + 1, 4, 5, 6, 4, 4, 6, 6, 6, 8, + 8, 8, 8, 9, 7, 5, 4, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 8, 8, 0, 2, 3, 4, 4, 4, 4, + 4, 4, 0, 3, 4, 7, 3, 1, 1, 2, + 3, 3, 1, 2, 2, 1, 2, 1, 2, 2, + 1, 2, 0, 1, 0, 2, 1, 2, 4, 0, + 2, 1, 3, 5, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 2, 2, 0, 3, 0, 2, 0, + 3, 1, 3, 2, 0, 1, 1, 0, 2, 4, + 4, 0, 2, 4, 2, 1, 3, 5, 4, 6, + 1, 3, 3, 5, 0, 5, 1, 3, 1, 2, + 3, 1, 1, 3, 3, 1, 3, 3, 3, 3, + 3, 1, 2, 1, 1, 1, 1, 1, 1, 0, + 2, 0, 3, 0, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, + 0, 1, 1, 0, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -2319,302 +2300,302 @@ var yyR2 = [...]int{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, - 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 0, 0, 1, 1, } var yyChk = [...]int{ - -1000, -190, -1, -2, -6, -7, -8, -9, -10, -11, + -1000, -191, -1, -2, -6, -7, -8, -9, -10, -11, -12, -13, -14, -15, -19, -20, -21, -23, -24, -25, -22, -16, -3, -4, 6, 7, -29, 9, 10, 30, -17, 115, 116, 118, 117, 149, 119, 142, 50, 163, 164, 166, 167, 25, 143, 144, 147, 148, 31, 32, - 121, -192, 8, 247, 54, -191, 264, -87, 15, -28, - 5, -26, -195, -26, -26, -26, -26, -26, -166, -168, - 54, 90, -119, 125, 72, 239, 122, 123, 129, -122, - 57, -121, 257, 135, 163, 174, 168, 195, 187, 258, - 136, 185, 188, 226, 215, 221, 66, 166, 235, 145, - 183, 179, 177, 27, 223, 200, 262, 178, 222, 121, - 138, 133, 201, 205, 227, 172, 173, 229, 199, 134, - 33, 259, 35, 153, 230, 203, 198, 194, 197, 171, - 193, 39, 207, 206, 208, 225, 190, 139, 180, 18, - 233, 148, 151, 224, 202, 204, 130, 155, 261, 231, - 176, 140, 152, 147, 234, 141, 167, 162, 228, 237, + 121, -193, 8, 248, 54, -192, 265, -87, 15, -28, + 5, -26, -196, -26, -26, -26, -26, -26, -167, -169, + 54, 90, -120, 125, 72, 240, 122, 123, 129, -123, + 57, -122, 258, 135, 163, 174, 168, 195, 187, 259, + 136, 185, 188, 227, 215, 222, 66, 166, 236, 145, + 183, 179, 177, 27, 224, 200, 263, 178, 223, 121, + 138, 133, 201, 205, 228, 172, 173, 230, 199, 134, + 33, 260, 35, 153, 231, 203, 198, 194, 197, 171, + 193, 39, 207, 206, 208, 226, 190, 139, 180, 18, + 234, 148, 151, 225, 202, 204, 130, 155, 262, 232, + 176, 140, 152, 147, 235, 141, 167, 162, 229, 238, 38, 212, 170, 132, 164, 159, 217, 191, 154, 181, - 182, 196, 169, 192, 165, 156, 149, 236, 213, 263, - 189, 186, 160, 157, 158, 218, 161, 260, 232, 184, - 214, -107, 125, 218, 127, 123, 123, 124, 125, 239, - 122, 123, -54, -128, 57, -121, 125, 123, 108, 188, - 226, 115, 216, 223, 124, 33, 224, 155, -137, 123, - -109, 215, 218, 161, 57, 228, 227, 219, -128, 165, - -133, -133, -133, -133, -133, 217, 217, -133, -2, -91, - 17, 16, -5, -3, -192, 6, 20, 21, -32, 40, - 41, -27, -38, 99, -39, -128, -60, 74, -65, 29, - 57, -121, 23, -64, -61, -80, -78, -79, 108, 109, - 110, 97, 98, 105, 75, 111, -69, -67, -68, -70, - 59, 58, 67, 60, 61, 62, 63, 68, 69, 70, - -122, -76, -192, 44, 45, 248, 249, 250, 251, 256, - 252, 77, 34, 238, 246, 245, 244, 242, 243, 240, - 241, 254, 255, 128, 239, 103, 247, -107, -107, 11, - -48, -49, -54, -56, -128, -99, -136, 165, -103, 228, - 227, -123, -101, -122, -120, 226, 188, 225, 120, 73, - 22, 24, 210, 76, 108, 16, 77, 107, 248, 115, - 48, 240, 241, 238, 250, 251, 239, 216, 29, 10, - 25, 143, 21, 101, 117, 80, 81, 146, 23, 144, - 70, 19, 51, 11, 13, 14, 128, 127, 92, 124, - 46, 8, 111, 26, 89, 42, 28, 44, 90, 17, - 242, 243, 31, 256, 150, 103, 49, 36, 74, 68, - 71, 52, 72, 15, 47, 91, 118, 247, 45, 122, - 6, 253, 30, 142, 43, 123, 79, 254, 255, 126, - 69, 5, 129, 32, 9, 50, 53, 244, 245, 246, - 34, 78, 12, -167, 90, -160, 57, -54, 124, -54, - 247, -115, 128, -115, -115, 123, -54, 115, 117, 120, - 52, -18, -54, -114, 128, 57, -114, -114, -114, -54, - 112, -54, 57, 30, -134, -192, -123, 239, 57, 155, - 123, 156, 125, -134, -134, -134, -134, 159, 160, -134, - -112, -111, 221, 222, 217, 220, 12, 217, 158, -134, - -133, -133, -193, 56, -92, 19, 31, -39, -128, -88, - -89, -39, -87, -2, -26, 36, -30, 21, 65, 11, - -125, 73, 72, 89, -124, 22, -122, 59, 112, -39, - -62, 92, 74, 90, 91, 76, 94, 93, 104, 97, - 98, 99, 100, 101, 102, 103, 95, 96, 107, 82, - 83, 84, 85, 86, 87, 88, -108, -192, -79, -192, - 113, 114, -65, -65, -65, -65, -65, -65, -65, -65, - -192, -2, -74, -39, -192, -192, -192, -192, -192, -192, - -192, -192, -192, -83, -39, -192, -196, -71, -192, -196, - -71, -196, -71, -196, -192, -196, -71, -196, -71, -196, - -196, -71, -192, -192, -192, -192, -192, -192, -55, 26, - -54, -41, -42, -43, -44, -57, -79, -192, -54, -54, - -48, -194, 55, 11, 53, -194, 55, 112, 55, -99, - 165, -100, -104, 229, 231, 82, -127, -122, 59, 29, - 30, 56, 55, -54, -139, -142, -144, -143, -145, -140, - -141, 185, 186, 108, 189, 191, 192, 193, 194, 195, - 196, 197, 198, 199, 200, 30, 145, 181, 182, 183, - 184, 201, 202, 203, 204, 205, 206, 207, 208, 168, - 187, 258, 169, 170, 171, 172, 173, 174, 176, 177, - 178, 179, 180, 57, -134, 125, 57, 74, 57, -54, - -54, -134, 157, 157, 123, 123, 162, -54, 55, 126, - -48, 23, 52, -54, 57, 57, -129, -128, -120, -134, - -134, -134, -134, -134, -54, -134, -134, -134, -134, 11, - -110, 11, 92, -39, 52, 9, 92, 55, 18, 112, - 55, -90, 24, 25, -91, -193, -32, -66, -122, 60, - 63, -31, 43, -54, -39, -39, -72, 68, 74, 69, - 70, -124, 99, -129, -123, -120, -65, -73, -76, -79, - 64, 92, 90, 91, 76, -65, -65, -65, -65, -65, + 182, 196, 169, 192, 165, 156, 149, 237, 213, 264, + 189, 186, 160, 157, 158, 218, 219, 161, 261, 233, + 184, 214, -107, 125, 219, 127, 123, 123, 124, 125, + 240, 122, 123, -54, -129, 57, -122, 125, 123, 108, + 188, 227, 115, 216, 224, 124, 33, 225, 155, -138, + 123, -109, 215, 218, 219, 161, 57, 229, 228, 220, + -129, 165, -134, -134, -134, -134, -134, 217, 217, -134, + -2, -91, 17, 16, -5, -3, -193, 6, 20, 21, + -32, 40, 41, -27, -38, 99, -39, -129, -60, 74, + -65, 29, 57, -122, 23, -64, -61, -80, -78, -79, + 108, 109, 110, 97, 98, 105, 75, 111, -69, -67, + -68, -70, 59, 58, 67, 60, 61, 62, 63, 68, + 69, 70, -123, -76, -193, 44, 45, 249, 250, 251, + 252, 257, 253, 77, 34, 239, 247, 246, 245, 243, + 244, 241, 242, 255, 256, 128, 240, 103, 248, -107, + -107, 11, -48, -49, -54, -56, -129, -99, -137, 165, + -103, 229, 228, -124, -101, -123, -121, 227, 188, 226, + 120, 73, 22, 24, 210, 76, 108, 16, 77, 107, + 249, 115, 48, 241, 242, 239, 251, 252, 240, 216, + 29, 10, 25, 143, 21, 101, 117, 80, 81, 146, + 23, 144, 70, 19, 51, 11, 13, 14, 128, 127, + 92, 124, 46, 8, 111, 26, 89, 42, 28, 44, + 90, 17, 243, 244, 31, 257, 150, 103, 49, 36, + 74, 68, 71, 52, 72, 15, 47, 91, 118, 248, + 45, 122, 6, 254, 30, 142, 43, 123, 79, 255, + 256, 126, 69, 5, 129, 32, 9, 50, 53, 245, + 246, 247, 34, 78, 12, -168, 90, -161, 57, -54, + 124, -54, 248, -116, 128, -116, -116, 123, -54, 115, + 117, 120, 52, -18, -54, -115, 128, 57, -115, -115, + -115, -54, 112, -54, 57, 30, -135, -193, -124, 240, + 57, 155, 123, 156, 125, -135, -135, -135, -135, 159, + 160, -135, -112, -111, 222, 223, 217, 221, 12, 160, + 217, 158, -135, -134, -134, -194, 56, -92, 19, 31, + -39, -129, -88, -89, -39, -87, -2, -26, 36, -30, + 21, 65, 11, -126, 73, 72, 89, -125, 22, -123, + 59, 112, -39, -62, 92, 74, 90, 91, 76, 94, + 93, 104, 97, 98, 99, 100, 101, 102, 103, 95, + 96, 107, 82, 83, 84, 85, 86, 87, 88, -108, + -193, -79, -193, 113, 114, -65, -65, -65, -65, -65, + -65, -65, -65, -193, -2, -74, -39, -193, -193, -193, + -193, -193, -193, -193, -193, -193, -83, -39, -193, -197, + -71, -193, -197, -71, -197, -71, -197, -193, -197, -71, + -197, -71, -197, -197, -71, -193, -193, -193, -193, -193, + -193, -55, 26, -54, -41, -42, -43, -44, -57, -79, + -193, -54, -54, -48, -195, 55, 11, 53, -195, 55, + 112, 55, -99, 165, -100, -104, 230, 232, 82, -128, + -123, 59, 29, 30, 56, 55, -54, -140, -143, -145, + -144, -146, -141, -142, 185, 186, 108, 189, 191, 192, + 193, 194, 195, 196, 197, 198, 199, 200, 30, 145, + 181, 182, 183, 184, 201, 202, 203, 204, 205, 206, + 207, 208, 168, 187, 259, 169, 170, 171, 172, 173, + 174, 176, 177, 178, 179, 180, 57, -135, 125, 57, + 74, 57, -54, -54, -135, 157, 157, 123, 123, 162, + -54, 55, 126, -48, 23, 52, -54, 57, 57, -130, + -129, -121, -135, -135, -135, -135, -135, -54, -135, -135, + -135, -135, 11, -110, 11, 92, -39, -114, 90, 52, + 9, 92, 55, 18, 112, 55, -90, 24, 25, -91, + -194, -32, -66, -123, 60, 63, -31, 43, -54, -39, + -39, -72, 68, 74, 69, 70, -125, 99, -130, -124, + -121, -65, -73, -76, -79, 64, 92, 90, 91, 76, -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, - -135, 57, 59, 57, -64, -64, -122, -37, 21, -36, - -38, -193, 55, -193, -2, -36, -36, -39, -39, -80, - 59, -36, -80, 59, -36, -36, -30, -81, -82, 78, - -80, -122, -128, -193, -65, -122, -122, -36, -37, -36, - -36, -95, 151, -54, 30, 55, -50, -52, -51, -53, - 42, 46, 48, 43, 44, 45, 49, -132, 22, -41, - -192, -131, 151, -130, 22, -128, 59, -95, 53, -41, - -54, -41, -56, -128, 99, -103, -100, 55, 230, 232, - 233, 52, 71, -39, -151, 107, -169, -170, -171, -123, - 59, 60, -160, -161, -162, -172, 137, -177, 130, 132, - 129, -163, 138, 124, 28, 56, -156, 68, 74, -152, - 213, -146, 54, -146, -146, -146, -146, -150, 188, -150, - -150, -150, 54, 54, -146, -146, -146, -154, 54, -154, - -154, -155, 54, -155, -126, 53, -54, -134, 23, -134, - -116, 120, 117, 118, -180, 116, 210, 188, 66, 29, - 15, 248, 151, 263, 57, 152, -122, -122, -54, -54, - -54, 120, 117, -54, -54, -54, -134, -54, -113, 90, - 12, -128, -128, -54, 38, -39, -39, -129, -89, -92, - -106, 19, 11, 34, 34, -36, 68, 69, 70, 112, - -192, -73, -65, -65, -65, -35, 146, 73, -193, -193, - -36, 55, -39, -193, -193, -193, 55, 53, 22, 11, - 11, -193, 11, 11, -193, -193, -36, -84, -82, 80, - -39, -193, 112, -193, 55, 55, -193, -193, -193, -193, - -63, 30, 34, -2, -192, -192, -98, -102, -80, -42, - -43, -43, -42, -43, 42, 42, 42, 47, 42, 47, - 42, -51, -128, -193, -58, 50, 127, 51, -192, -130, - -59, 12, -41, -59, -59, 112, -104, -105, 234, 231, - 237, 57, 59, 55, -171, 82, 54, 57, 28, -163, - -163, -164, 57, -164, 28, -148, 29, 68, -153, 214, - 60, -150, -150, -151, 30, -151, -151, -151, -159, 59, - -159, 60, 60, 52, -122, -134, -133, -186, 131, 137, - 138, 133, 57, 124, 28, 130, 132, 151, 129, -186, - -117, -118, 126, 22, 124, 28, 151, -185, 53, 157, - 210, 157, 126, -134, -110, 59, -39, 39, 112, -54, - -40, 11, 99, -123, -37, -35, 73, -65, -65, -193, - -38, -138, 108, 185, 145, 183, 179, 199, 190, 212, - 181, 213, -135, -138, -65, -65, -65, -65, 257, -87, - 81, -39, 79, -123, -65, -65, -97, 52, -98, -75, - -77, -76, -192, -2, -93, -122, -96, -122, -59, 55, - 82, -46, -45, 52, 53, -47, 52, -45, 42, 42, - 124, 124, 124, -96, -87, -39, -59, 231, 235, 236, - -170, -171, -174, -173, -122, -177, -164, -164, 54, -149, - 52, -65, 56, -151, -151, 57, 108, 56, 55, 56, - 55, 56, 55, -54, -133, -133, -54, -133, -122, -183, - 260, -184, 57, -122, -122, -122, -54, -113, -59, -41, - -193, -65, -193, -146, -146, -146, -155, -146, 173, -146, - 173, -193, -193, 19, 19, 19, 19, -192, -34, 253, - -39, 55, 55, 27, -97, 55, -193, -193, -193, 55, - 112, -193, 55, -87, -102, -39, -39, 54, -39, -192, - -192, -192, -193, -91, 56, 55, -146, -94, -122, -157, - 210, 9, -150, 59, -150, 60, 60, -134, 26, -182, - -181, -123, 54, 53, -85, 13, -150, 57, -65, -65, - -65, -65, -65, -193, 59, -65, -65, 28, -77, 34, - -2, -192, -122, -122, -122, -91, -94, -94, -94, -94, - -131, -176, -175, 53, 134, 66, -173, 56, 55, -158, - 130, 28, 129, -68, -151, -151, 56, 56, -192, 55, - 82, -94, -54, -86, 14, 16, -193, -193, -193, -193, - -33, 92, 260, -193, -193, 9, -75, -2, 112, 56, - -193, -193, -193, -58, -175, 57, -165, 82, 59, 140, - -122, -147, 66, 28, 28, -178, -179, 151, -181, -171, - 56, -39, -74, -193, 258, 49, 261, -98, -193, -122, - 60, -54, 59, -193, 55, -122, -185, 39, 259, 262, - 54, -179, 34, -183, 39, -94, 153, 260, 56, 154, - 261, -188, -189, 52, -192, 262, -189, 52, 10, 9, - -65, 150, -187, 141, 136, 139, 30, -187, -193, -193, - 135, 29, 68, + -65, -65, -65, -65, -65, -136, 57, 59, 57, -64, + -64, -123, -37, 21, -36, -38, -194, 55, -194, -2, + -36, -36, -39, -39, -80, 59, -36, -80, 59, -36, + -36, -30, -81, -82, 78, -80, -123, -129, -194, -65, + -123, -123, -36, -37, -36, -36, -95, 151, -54, 30, + 55, -50, -52, -51, -53, 42, 46, 48, 43, 44, + 45, 49, -133, 22, -41, -193, -132, 151, -131, 22, + -129, 59, -95, 53, -41, -54, -41, -56, -129, 99, + -103, -100, 55, 231, 233, 234, 52, 71, -39, -152, + 107, -170, -171, -172, -124, 59, 60, -161, -162, -163, + -173, 137, -178, 130, 132, 129, -164, 138, 124, 28, + 56, -157, 68, 74, -153, 213, -147, 54, -147, -147, + -147, -147, -151, 188, -151, -151, -151, 54, 54, -147, + -147, -147, -155, 54, -155, -155, -156, 54, -156, -127, + 53, -54, -135, 23, -135, -117, 120, 117, 118, -181, + 116, 210, 188, 66, 29, 15, 249, 151, 264, 57, + 152, -123, -123, -54, -54, -54, 120, 117, -54, -54, + -54, -135, -54, -113, 90, 12, -129, -129, 59, -54, + 38, -39, -39, -130, -89, -92, -106, 19, 11, 34, + 34, -36, 68, 69, 70, 112, -193, -73, -65, -65, + -65, -35, 146, 73, -194, -194, -36, 55, -39, -194, + -194, -194, 55, 53, 22, 11, 11, -194, 11, 11, + -194, -194, -36, -84, -82, 80, -39, -194, 112, -194, + 55, 55, -194, -194, -194, -194, -63, 30, 34, -2, + -193, -193, -98, -102, -80, -42, -43, -43, -42, -43, + 42, 42, 42, 47, 42, 47, 42, -51, -129, -194, + -58, 50, 127, 51, -193, -131, -59, 12, -41, -59, + -59, 112, -104, -105, 235, 232, 238, 57, 59, 55, + -172, 82, 54, 57, 28, -164, -164, -165, 57, -165, + 28, -149, 29, 68, -154, 214, 60, -151, -151, -152, + 30, -152, -152, -152, -160, 59, -160, 60, 60, 52, + -123, -135, -134, -187, 131, 137, 138, 133, 57, 124, + 28, 130, 132, 151, 129, -187, -118, -119, 126, 22, + 124, 28, 151, -186, 53, 157, 210, 157, 126, -135, + -110, 59, -39, 39, 112, -54, -40, 11, 99, -124, + -37, -35, 73, -65, -65, -194, -38, -139, 108, 185, + 145, 183, 179, 199, 190, 212, 181, 213, -136, -139, + -65, -65, -65, -65, 258, -87, 81, -39, 79, -124, + -65, -65, -97, 52, -98, -75, -77, -76, -193, -2, + -93, -123, -96, -123, -59, 55, 82, -46, -45, 52, + 53, -47, 52, -45, 42, 42, 124, 124, 124, -96, + -87, -39, -59, 232, 236, 237, -171, -172, -175, -174, + -123, -178, -165, -165, 54, -150, 52, -65, 56, -152, + -152, 57, 108, 56, 55, 56, 55, 56, 55, -54, + -134, -134, -54, -134, -123, -184, 261, -185, 57, -123, + -123, -123, -54, -113, -59, -41, -194, -65, -194, -147, + -147, -147, -156, -147, 173, -147, 173, -194, -194, 19, + 19, 19, 19, -193, -34, 254, -39, 55, 55, 27, + -97, 55, -194, -194, -194, 55, 112, -194, 55, -87, + -102, -39, -39, 54, -39, -193, -193, -193, -194, -91, + 56, 55, -147, -94, -123, -158, 210, 9, -151, 59, + -151, 60, 60, -135, 26, -183, -182, -124, 54, 53, + -85, 13, -151, 57, -65, -65, -65, -65, -65, -194, + 59, -65, -65, 28, -77, 34, -2, -193, -123, -123, + -123, -91, -94, -94, -94, -94, -132, -177, -176, 53, + 134, 66, -174, 56, 55, -159, 130, 28, 129, -68, + -152, -152, 56, 56, -193, 55, 82, -94, -54, -86, + 14, 16, -194, -194, -194, -194, -33, 92, 261, -194, + -194, 9, -75, -2, 112, 56, -194, -194, -194, -58, + -176, 57, -166, 82, 59, 140, -123, -148, 66, 28, + 28, -179, -180, 151, -182, -172, 56, -39, -74, -194, + 259, 49, 262, -98, -194, -123, 60, -54, 59, -194, + 55, -123, -186, 39, 260, 263, 54, -180, 34, -184, + 39, -94, 153, 261, 56, 154, 262, -189, -190, 52, + -193, 263, -190, 52, 10, 9, -65, 150, -188, 141, + 136, 139, 30, -188, -194, -194, 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, 313, 313, 313, 313, 313, 313, - 0, 627, 610, 0, 0, 0, 0, -2, 300, 301, - 0, 303, 304, 847, 847, 847, 847, 847, 0, 0, - 847, 0, 35, 36, 845, 1, 3, 564, 0, 0, - 317, 320, 315, 0, 610, 610, 0, 0, 65, 66, - 0, 0, 0, 836, 0, 608, 608, 608, 628, 629, - 632, 633, 735, 736, 737, 738, 739, 740, 741, 742, - 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, - 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, - 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, - 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, - 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, - 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, - 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, - 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, - 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, - 833, 834, 835, 837, 838, 839, 840, 841, 842, 843, - 844, 0, 0, 0, 611, 0, 606, 0, 606, 606, - 606, 0, 255, 385, 636, 637, 836, 0, 0, 0, - 848, 0, 848, 267, 848, 848, 270, 848, 0, 848, - 0, 277, 0, 282, 848, 297, 298, 287, 299, 302, - 305, 306, 307, 308, 309, 847, 847, 312, 29, 568, - 0, 0, 556, 31, 0, 313, 318, 319, 323, 321, - 322, 314, 0, 331, 335, 0, 394, 0, 399, 401, - -2, -2, 0, 436, 437, 438, 439, 440, 0, 0, - 0, 0, 0, 0, 0, 0, 464, 465, 466, 467, - 541, 542, 543, 544, 545, 546, 547, 548, 403, 404, - 538, 588, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 529, 0, 500, 500, 500, 500, 500, 500, 500, - 500, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 44, 46, 385, 50, 0, 827, 592, -2, - -2, 0, 0, 634, 635, -2, 745, -2, 640, 641, - 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, - 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, - 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, - 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, - 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, - 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, - 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, - 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, - 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, - 732, 733, 734, 0, 0, 84, 0, 82, 0, 848, - 0, 0, 0, 0, 0, 0, 848, 0, 0, 0, - 0, 246, 0, 0, 0, 0, 0, 0, 0, 254, - 0, 256, 848, 848, 259, 849, 850, 848, 848, 848, - 0, 848, 848, 266, 268, 269, 271, 848, 848, 273, - 0, 290, 288, 289, 284, 285, 0, 279, 280, 283, - 310, 311, 30, 846, 24, 0, 0, 565, 0, 557, - 558, 561, 564, 29, 320, 0, 325, 324, 316, 0, - 332, 0, 0, 0, 336, 0, 338, 339, 0, 397, + 21, 22, 559, 0, 316, 316, 316, 316, 316, 316, + 0, 630, 613, 0, 0, 0, 0, -2, 303, 304, + 0, 306, 307, 851, 851, 851, 851, 851, 0, 0, + 851, 0, 35, 36, 849, 1, 3, 567, 0, 0, + 320, 323, 318, 0, 613, 613, 0, 0, 65, 66, + 0, 0, 0, 839, 0, 611, 611, 611, 631, 632, + 635, 636, 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, + 836, 837, 838, 840, 841, 842, 843, 844, 845, 846, + 847, 848, 0, 0, 0, 614, 0, 609, 0, 609, + 609, 609, 0, 255, 388, 639, 640, 839, 0, 0, + 0, 852, 0, 852, 267, 852, 852, 270, 852, 0, + 852, 0, 277, 0, 0, 283, 852, 300, 301, 288, + 302, 305, 308, 309, 310, 311, 312, 851, 851, 315, + 29, 571, 0, 0, 559, 31, 0, 316, 321, 322, + 326, 324, 325, 317, 0, 334, 338, 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, 544, 545, 546, 547, 548, 549, 550, 551, + 406, 407, 541, 591, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 532, 0, 503, 503, 503, 503, 503, + 503, 503, 503, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 44, 46, 388, 50, 0, 830, + 595, -2, -2, 0, 0, 637, 638, -2, 748, -2, + 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, + 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, + 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, + 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, + 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, + 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, + 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, + 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, + 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, + 733, 734, 735, 736, 737, 0, 0, 84, 0, 82, + 0, 852, 0, 0, 0, 0, 0, 0, 852, 0, + 0, 0, 0, 246, 0, 0, 0, 0, 0, 0, + 0, 254, 0, 256, 852, 852, 259, 853, 854, 852, + 852, 852, 0, 852, 852, 266, 268, 269, 271, 852, + 852, 273, 0, 291, 289, 290, 285, 286, 0, 297, + 280, 281, 284, 313, 314, 30, 850, 24, 0, 0, + 568, 0, 560, 561, 564, 567, 29, 323, 0, 328, + 327, 319, 0, 335, 0, 0, 0, 339, 0, 341, + 342, 0, 400, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 421, - 422, 423, 424, 425, 426, 427, 400, 0, 414, 0, - 0, 0, 456, 457, 458, 459, 460, 461, 462, 0, - 327, 29, 0, 434, 0, 0, 0, 0, 0, 0, - 0, 0, 323, 0, 530, 0, 484, 492, 0, 485, - 493, 486, 494, 487, 0, 488, 495, 489, 496, 490, - 491, 497, 0, 0, 0, 327, 0, 0, 48, 0, - 384, 0, 342, 344, 345, 346, -2, 0, 368, -2, - 0, 0, 0, 42, 43, 0, 0, 0, 0, 51, - 827, 53, 54, 0, 0, 0, 162, 601, 602, 603, - 599, 206, 0, 0, 150, 146, 90, 91, 92, 139, - 94, 139, 139, 139, 139, 159, 159, 159, 159, 122, - 123, 124, 125, 126, 0, 0, 109, 139, 139, 139, - 113, 129, 130, 131, 132, 133, 134, 135, 136, 95, - 96, 97, 98, 99, 100, 101, 102, 103, 141, 141, - 141, 143, 143, 630, 68, 0, 848, 0, 848, 80, - 0, 220, 0, 0, 0, 0, 0, 0, 0, 0, - 249, 607, 0, 848, 252, 253, 386, 638, 639, 257, - 258, 260, 261, 262, 263, 264, 265, 272, 276, 0, - 293, 0, 0, 278, 0, 569, 0, 0, 0, 0, - 0, 560, 562, 563, 568, 32, 323, 0, 549, 0, - 0, 0, 326, 27, 395, 396, 398, 415, 0, 417, - 419, 337, 333, 0, 539, -2, 405, 406, 430, 431, - 432, 0, 0, 0, 0, 428, 410, 0, 441, 442, - 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, - 455, 514, 515, 0, 453, 454, 463, 0, 0, 328, - 329, 433, 0, 587, 29, 0, 0, 0, 0, 438, - 541, 0, 438, 541, 0, 0, 0, 536, 533, 0, - 0, 538, 0, 501, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 383, 0, 0, 0, 0, 0, 0, - 373, 0, 0, 376, 0, 0, 0, 0, 367, 0, - 0, 388, 795, 369, 0, 371, 372, 392, 0, 392, - 45, 392, 47, 0, 387, 593, 52, 0, 0, 57, - 58, 594, 595, 596, 597, 0, 81, 207, 209, 212, - 213, 214, 85, 86, 87, 0, 0, 194, 0, 0, - 188, 188, 0, 186, 187, 83, 153, 151, 0, 148, - 147, 93, 0, 159, 159, 116, 117, 162, 0, 162, - 162, 162, 0, 0, 110, 111, 112, 104, 0, 105, - 106, 107, 0, 108, 0, 0, 848, 70, 609, 71, - 847, 0, 0, 622, 221, 612, 613, 614, 615, 616, - 617, 618, 619, 620, 621, 0, 72, 223, 225, 224, - 228, 0, 0, 0, 247, 848, 251, 290, 275, 0, - 0, 291, 292, 281, 0, 566, 567, 0, 559, 25, - 0, 604, 605, 550, 551, 340, 416, 418, 420, 0, - 327, 407, 428, 411, 0, 408, 0, 0, 402, 468, - 0, 0, 435, -2, 471, 472, 0, 0, 0, 0, - 0, 507, 0, 0, 508, 0, 556, 0, 534, 0, - 0, 483, 0, 502, 0, 0, 503, 504, 505, 506, - 581, 0, 0, -2, 0, 0, 392, 589, 0, 343, - 362, 364, 0, 359, 374, 375, 377, 0, 379, 0, - 381, 382, 347, 349, 350, 0, 0, 0, 0, 370, - 556, 0, 392, 40, 41, 0, 55, 56, 0, 0, - 62, 163, 164, 0, 210, 0, 0, 0, 181, 188, - 188, 184, 189, 185, 0, 155, 0, 152, 89, 149, - 0, 162, 162, 118, 0, 119, 120, 121, 0, 137, - 0, 0, 0, 0, 631, 69, 215, 847, 230, 231, - 232, 233, 234, 235, 236, 237, 238, 239, 240, 847, - 0, 847, 623, 624, 625, 626, 0, 75, 0, 0, - 0, 0, 0, 250, 293, 294, 295, 570, 0, 26, - 392, 0, 334, 540, 0, 409, 0, 429, 412, 469, - 330, 0, 139, 139, 519, 139, 143, 522, 139, 524, - 139, 527, 0, 0, 0, 0, 0, 0, 0, 531, - 482, 537, 0, 539, 0, 0, 33, 0, 581, 571, - 583, 585, 0, 29, 0, 577, 0, 354, 556, 0, - 0, 356, 363, 0, 0, 357, 0, 358, 378, 380, - 0, 0, 0, 0, 564, 393, 39, 59, 60, 61, - 208, 211, 0, 190, 139, 193, 182, 183, 0, 157, - 0, 154, 140, 114, 115, 160, 161, 159, 0, 159, - 0, 144, 0, 848, 216, 217, 218, 219, 0, 222, - 0, 73, 74, 0, 0, 227, 248, 274, 552, 341, - 470, 413, 473, 516, 159, 520, 521, 523, 525, 526, - 528, 475, 474, 0, 0, 0, 0, 0, 0, 0, - 535, 0, 0, 0, 34, 0, 586, -2, 0, 0, - 0, 49, 0, 564, 590, 591, 360, 0, 365, 0, - 0, 0, 368, 38, 173, 0, 192, 0, 352, 165, - 158, 0, 162, 138, 162, 0, 0, 67, 0, 76, - 77, 0, 0, 0, 554, 0, 517, 518, 0, 0, - 0, 0, 509, 481, 532, 0, 0, 0, 584, 0, - -2, 0, 579, 578, 355, 37, 0, 0, 0, 0, - 388, 172, 174, 0, 179, 0, 191, 0, 0, 170, - 0, 167, 169, 156, 127, 128, 142, 145, 0, 0, - 0, 0, 229, 28, 0, 0, 476, 478, 477, 479, - 0, 0, 0, 498, 499, 0, 574, 29, 0, 361, - 389, 390, 391, 351, 175, 176, 0, 180, 178, 0, - 353, 88, 0, 166, 168, 0, 242, 0, 78, 79, - 72, 555, 553, 480, 0, 0, 0, 582, -2, 580, - 177, 0, 171, 241, 0, 0, 75, 510, 0, 513, - 0, 243, 0, 226, 511, 0, 0, 0, 195, 0, - 0, 196, 197, 0, 0, 512, 198, 0, 0, 0, - 0, 0, 199, 201, 202, 0, 0, 200, 244, 245, - 203, 204, 205, + 0, 0, 424, 425, 426, 427, 428, 429, 430, 403, + 0, 417, 0, 0, 0, 459, 460, 461, 462, 463, + 464, 465, 0, 330, 29, 0, 437, 0, 0, 0, + 0, 0, 0, 0, 0, 326, 0, 533, 0, 487, + 495, 0, 488, 496, 489, 497, 490, 0, 491, 498, + 492, 499, 493, 494, 500, 0, 0, 0, 330, 0, + 0, 48, 0, 387, 0, 345, 347, 348, 349, -2, + 0, 371, -2, 0, 0, 0, 42, 43, 0, 0, + 0, 0, 51, 830, 53, 54, 0, 0, 0, 162, + 604, 605, 606, 602, 206, 0, 0, 150, 146, 90, + 91, 92, 139, 94, 139, 139, 139, 139, 159, 159, + 159, 159, 122, 123, 124, 125, 126, 0, 0, 109, + 139, 139, 139, 113, 129, 130, 131, 132, 133, 134, + 135, 136, 95, 96, 97, 98, 99, 100, 101, 102, + 103, 141, 141, 141, 143, 143, 633, 68, 0, 852, + 0, 852, 80, 0, 220, 0, 0, 0, 0, 0, + 0, 0, 0, 249, 610, 0, 852, 252, 253, 389, + 641, 642, 257, 258, 260, 261, 262, 263, 264, 265, + 272, 276, 0, 294, 0, 0, 278, 279, 0, 0, + 572, 0, 0, 0, 0, 0, 563, 565, 566, 571, + 32, 326, 0, 552, 0, 0, 0, 329, 27, 398, + 399, 401, 418, 0, 420, 422, 340, 336, 0, 542, + -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, 517, 518, 0, 456, + 457, 466, 0, 0, 331, 332, 436, 0, 590, 29, + 0, 0, 0, 0, 441, 544, 0, 441, 544, 0, + 0, 0, 539, 536, 0, 0, 541, 0, 504, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 386, 0, + 0, 0, 0, 0, 0, 376, 0, 0, 379, 0, + 0, 0, 0, 370, 0, 0, 391, 798, 372, 0, + 374, 375, 395, 0, 395, 45, 395, 47, 0, 390, + 596, 52, 0, 0, 57, 58, 597, 598, 599, 600, + 0, 81, 207, 209, 212, 213, 214, 85, 86, 87, + 0, 0, 194, 0, 0, 188, 188, 0, 186, 187, + 83, 153, 151, 0, 148, 147, 93, 0, 159, 159, + 116, 117, 162, 0, 162, 162, 162, 0, 0, 110, + 111, 112, 104, 0, 105, 106, 107, 0, 108, 0, + 0, 852, 70, 612, 71, 851, 0, 0, 625, 221, + 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, + 0, 72, 223, 225, 224, 228, 0, 0, 0, 247, + 852, 251, 291, 275, 0, 0, 292, 293, 298, 282, + 0, 569, 570, 0, 562, 25, 0, 607, 608, 553, + 554, 343, 419, 421, 423, 0, 330, 410, 431, 414, + 0, 411, 0, 0, 405, 471, 0, 0, 438, -2, + 474, 475, 0, 0, 0, 0, 0, 510, 0, 0, + 511, 0, 559, 0, 537, 0, 0, 486, 0, 505, + 0, 0, 506, 507, 508, 509, 584, 0, 0, -2, + 0, 0, 395, 592, 0, 346, 365, 367, 0, 362, + 377, 378, 380, 0, 382, 0, 384, 385, 350, 352, + 353, 0, 0, 0, 0, 373, 559, 0, 395, 40, + 41, 0, 55, 56, 0, 0, 62, 163, 164, 0, + 210, 0, 0, 0, 181, 188, 188, 184, 189, 185, + 0, 155, 0, 152, 89, 149, 0, 162, 162, 118, + 0, 119, 120, 121, 0, 137, 0, 0, 0, 0, + 634, 69, 215, 851, 230, 231, 232, 233, 234, 235, + 236, 237, 238, 239, 240, 851, 0, 851, 626, 627, + 628, 629, 0, 75, 0, 0, 0, 0, 0, 250, + 294, 295, 296, 573, 0, 26, 395, 0, 337, 543, + 0, 412, 0, 432, 415, 472, 333, 0, 139, 139, + 522, 139, 143, 525, 139, 527, 139, 530, 0, 0, + 0, 0, 0, 0, 0, 534, 485, 540, 0, 542, + 0, 0, 33, 0, 584, 574, 586, 588, 0, 29, + 0, 580, 0, 357, 559, 0, 0, 359, 366, 0, + 0, 360, 0, 361, 381, 383, 0, 0, 0, 0, + 567, 396, 39, 59, 60, 61, 208, 211, 0, 190, + 139, 193, 182, 183, 0, 157, 0, 154, 140, 114, + 115, 160, 161, 159, 0, 159, 0, 144, 0, 852, + 216, 217, 218, 219, 0, 222, 0, 73, 74, 0, + 0, 227, 248, 274, 555, 344, 473, 416, 476, 519, + 159, 523, 524, 526, 528, 529, 531, 478, 477, 0, + 0, 0, 0, 0, 0, 0, 538, 0, 0, 0, + 34, 0, 589, -2, 0, 0, 0, 49, 0, 567, + 593, 594, 363, 0, 368, 0, 0, 0, 371, 38, + 173, 0, 192, 0, 355, 165, 158, 0, 162, 138, + 162, 0, 0, 67, 0, 76, 77, 0, 0, 0, + 557, 0, 520, 521, 0, 0, 0, 0, 512, 484, + 535, 0, 0, 0, 587, 0, -2, 0, 582, 581, + 358, 37, 0, 0, 0, 0, 391, 172, 174, 0, + 179, 0, 191, 0, 0, 170, 0, 167, 169, 156, + 127, 128, 142, 145, 0, 0, 0, 0, 229, 28, + 0, 0, 479, 481, 480, 482, 0, 0, 0, 501, + 502, 0, 577, 29, 0, 364, 392, 393, 394, 354, + 175, 176, 0, 180, 178, 0, 356, 88, 0, 166, + 168, 0, 242, 0, 78, 79, 72, 558, 556, 483, + 0, 0, 0, 585, -2, 583, 177, 0, 171, 241, + 0, 0, 75, 513, 0, 516, 0, 243, 0, 226, + 514, 0, 0, 0, 195, 0, 0, 196, 197, 0, + 0, 515, 198, 0, 0, 0, 0, 0, 199, 201, + 202, 0, 0, 200, 244, 245, 203, 204, 205, } var yyTok1 = [...]int{ @@ -2623,7 +2604,7 @@ var yyTok1 = [...]int{ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 75, 3, 3, 3, 102, 94, 3, 54, 56, 99, 97, 55, 98, 112, 100, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 264, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 265, 83, 82, 84, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, @@ -2658,7 +2639,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, + 259, 260, 261, 262, 263, 264, } var yyTok3 = [...]int{ 0, @@ -4580,605 +4561,624 @@ yydefault: yyVAL.statement = &Show{Type: string(yyDollar[2].bytes), ShowCollationFilterOpt: &showCollationFilterOpt} } case 279: - yyDollar = yyS[yypt-3 : yypt+1] + yyDollar = yyS[yypt-4 : yypt+1] //line sql.y:1576 { - yyVAL.statement = &Show{Type: string(yyDollar[2].bytes) + " " + string(yyDollar[3].bytes)} + showTablesOpt := &ShowTablesOpt{Filter: yyDollar[4].showFilter} + yyVAL.statement = &Show{Scope: string(yyDollar[2].bytes), Type: string(yyDollar[3].bytes), ShowTablesOpt: showTablesOpt} } case 280: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1580 +//line sql.y:1581 { yyVAL.statement = &Show{Type: string(yyDollar[2].bytes) + " " + string(yyDollar[3].bytes)} } case 281: + yyDollar = yyS[yypt-3 : yypt+1] +//line sql.y:1585 + { + yyVAL.statement = &Show{Type: string(yyDollar[2].bytes) + " " + string(yyDollar[3].bytes)} + } + case 282: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:1584 +//line sql.y:1589 { yyVAL.statement = &Show{Type: string(yyDollar[2].bytes) + " " + string(yyDollar[3].bytes), OnTable: yyDollar[5].tableName} } - case 282: + case 283: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1588 +//line sql.y:1593 { yyVAL.statement = &Show{Type: string(yyDollar[2].bytes)} } - case 283: + case 284: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1602 +//line sql.y:1607 { yyVAL.statement = &Show{Type: string(yyDollar[2].bytes)} } - case 284: + case 285: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1608 +//line sql.y:1613 { yyVAL.str = string(yyDollar[1].bytes) } - case 285: + case 286: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1612 +//line sql.y:1617 { yyVAL.str = string(yyDollar[1].bytes) } - case 286: + case 287: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:1618 +//line sql.y:1623 { yyVAL.str = "" } - case 287: + case 288: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1622 +//line sql.y:1627 { yyVAL.str = "full " } - case 288: + case 289: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1628 +//line sql.y:1633 { yyVAL.str = string(yyDollar[1].bytes) } - case 289: + case 290: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1632 +//line sql.y:1637 { yyVAL.str = string(yyDollar[1].bytes) } - case 290: + case 291: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:1638 +//line sql.y:1643 { yyVAL.str = "" } - case 291: + case 292: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1642 +//line sql.y:1647 { yyVAL.str = yyDollar[2].tableIdent.v } - case 292: + case 293: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1646 +//line sql.y:1651 { yyVAL.str = yyDollar[2].tableIdent.v } - case 293: + case 294: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:1652 +//line sql.y:1657 { yyVAL.showFilter = nil } - case 294: + case 295: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1656 +//line sql.y:1661 { yyVAL.showFilter = &ShowFilter{Like: string(yyDollar[2].bytes)} } - case 295: + case 296: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1660 +//line sql.y:1665 { yyVAL.showFilter = &ShowFilter{Filter: yyDollar[2].expr} } - case 296: + case 297: + yyDollar = yyS[yypt-0 : yypt+1] +//line sql.y:1671 + { + yyVAL.showFilter = nil + } + case 298: + yyDollar = yyS[yypt-2 : yypt+1] +//line sql.y:1675 + { + yyVAL.showFilter = &ShowFilter{Like: string(yyDollar[2].bytes)} + } + case 299: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:1666 +//line sql.y:1681 { yyVAL.str = "" } - case 297: + case 300: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1670 +//line sql.y:1685 { yyVAL.str = SessionStr } - case 298: + case 301: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1674 +//line sql.y:1689 { yyVAL.str = GlobalStr } - case 299: + case 302: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1680 +//line sql.y:1695 { yyVAL.statement = &Use{DBName: yyDollar[2].tableIdent} } - case 300: + case 303: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1684 +//line sql.y:1699 { yyVAL.statement = &Use{DBName: TableIdent{v: ""}} } - case 301: + case 304: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1690 +//line sql.y:1705 { yyVAL.statement = &Begin{} } - case 302: + case 305: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1694 +//line sql.y:1709 { yyVAL.statement = &Begin{} } - case 303: + case 306: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1700 +//line sql.y:1715 { yyVAL.statement = &Commit{} } - case 304: + case 307: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1706 +//line sql.y:1721 { yyVAL.statement = &Rollback{} } - case 305: + case 308: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1712 +//line sql.y:1727 { yyVAL.statement = &OtherRead{} } - case 306: + case 309: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1716 +//line sql.y:1731 { yyVAL.statement = &OtherRead{} } - case 307: + case 310: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1720 +//line sql.y:1735 { yyVAL.statement = &OtherRead{} } - case 308: + case 311: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1724 +//line sql.y:1739 { yyVAL.statement = &OtherAdmin{} } - case 309: + case 312: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1728 +//line sql.y:1743 { yyVAL.statement = &OtherAdmin{} } - case 310: + case 313: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1732 +//line sql.y:1747 { yyVAL.statement = &OtherAdmin{} } - case 311: + case 314: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1736 +//line sql.y:1751 { yyVAL.statement = &OtherAdmin{} } - case 312: + case 315: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1742 +//line sql.y:1757 { yyVAL.statement = &DDL{Action: FlushStr} } - case 313: + case 316: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:1746 +//line sql.y:1761 { setAllowComments(yylex, true) } - case 314: + case 317: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1750 +//line sql.y:1765 { yyVAL.bytes2 = yyDollar[2].bytes2 setAllowComments(yylex, false) } - case 315: + case 318: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:1756 +//line sql.y:1771 { yyVAL.bytes2 = nil } - case 316: + case 319: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1760 +//line sql.y:1775 { yyVAL.bytes2 = append(yyDollar[1].bytes2, yyDollar[2].bytes) } - case 317: + case 320: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1766 +//line sql.y:1781 { yyVAL.str = UnionStr } - case 318: + case 321: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1770 +//line sql.y:1785 { yyVAL.str = UnionAllStr } - case 319: + case 322: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1774 +//line sql.y:1789 { yyVAL.str = UnionDistinctStr } - case 320: + case 323: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:1779 +//line sql.y:1794 { yyVAL.str = "" } - case 321: + case 324: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1783 +//line sql.y:1798 { yyVAL.str = SQLNoCacheStr } - case 322: + case 325: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1787 +//line sql.y:1802 { yyVAL.str = SQLCacheStr } - case 323: + case 326: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:1792 +//line sql.y:1807 { yyVAL.str = "" } - case 324: + case 327: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1796 +//line sql.y:1811 { yyVAL.str = DistinctStr } - case 325: + case 328: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:1801 +//line sql.y:1816 { yyVAL.str = "" } - case 326: + case 329: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1805 +//line sql.y:1820 { yyVAL.str = StraightJoinHint } - case 327: + case 330: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:1810 +//line sql.y:1825 { yyVAL.selectExprs = nil } - case 328: + case 331: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1814 +//line sql.y:1829 { yyVAL.selectExprs = yyDollar[1].selectExprs } - case 329: + case 332: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1820 +//line sql.y:1835 { yyVAL.selectExprs = SelectExprs{yyDollar[1].selectExpr} } - case 330: + case 333: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1824 +//line sql.y:1839 { yyVAL.selectExprs = append(yyVAL.selectExprs, yyDollar[3].selectExpr) } - case 331: + case 334: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1830 +//line sql.y:1845 { yyVAL.selectExpr = &StarExpr{} } - case 332: + case 335: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1834 +//line sql.y:1849 { yyVAL.selectExpr = &AliasedExpr{Expr: yyDollar[1].expr, As: yyDollar[2].colIdent} } - case 333: + case 336: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1838 +//line sql.y:1853 { yyVAL.selectExpr = &StarExpr{TableName: TableName{Name: yyDollar[1].tableIdent}} } - case 334: + case 337: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:1842 +//line sql.y:1857 { yyVAL.selectExpr = &StarExpr{TableName: TableName{Qualifier: yyDollar[1].tableIdent, Name: yyDollar[3].tableIdent}} } - case 335: + case 338: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:1847 +//line sql.y:1862 { yyVAL.colIdent = ColIdent{} } - case 336: + case 339: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1851 +//line sql.y:1866 { yyVAL.colIdent = yyDollar[1].colIdent } - case 337: + case 340: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1855 +//line sql.y:1870 { yyVAL.colIdent = yyDollar[2].colIdent } - case 339: + case 342: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1862 +//line sql.y:1877 { yyVAL.colIdent = NewColIdent(string(yyDollar[1].bytes)) } - case 340: + case 343: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:1867 +//line sql.y:1882 { yyVAL.tableExprs = TableExprs{&AliasedTableExpr{Expr: TableName{Name: NewTableIdent("dual")}}} } - case 341: + case 344: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1871 +//line sql.y:1886 { yyVAL.tableExprs = yyDollar[2].tableExprs } - case 342: + case 345: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1877 +//line sql.y:1892 { yyVAL.tableExprs = TableExprs{yyDollar[1].tableExpr} } - case 343: + case 346: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1881 +//line sql.y:1896 { yyVAL.tableExprs = append(yyVAL.tableExprs, yyDollar[3].tableExpr) } - case 346: + case 349: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1891 +//line sql.y:1906 { yyVAL.tableExpr = yyDollar[1].aliasedTableName } - case 347: + case 350: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1895 +//line sql.y:1910 { yyVAL.tableExpr = &AliasedTableExpr{Expr: yyDollar[1].subquery, As: yyDollar[3].tableIdent} } - case 348: + case 351: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1899 +//line sql.y:1914 { // missed alias for subquery yylex.Error("Every derived table must have its own alias") return 1 } - case 349: + case 352: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1905 +//line sql.y:1920 { yyVAL.tableExpr = &ParenTableExpr{Exprs: yyDollar[2].tableExprs} } - case 350: + case 353: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1911 +//line sql.y:1926 { yyVAL.aliasedTableName = &AliasedTableExpr{Expr: yyDollar[1].tableName, As: yyDollar[2].tableIdent, Hints: yyDollar[3].indexHints} } - case 351: + case 354: yyDollar = yyS[yypt-7 : yypt+1] -//line sql.y:1915 +//line sql.y:1930 { yyVAL.aliasedTableName = &AliasedTableExpr{Expr: yyDollar[1].tableName, Partitions: yyDollar[4].partitions, As: yyDollar[6].tableIdent, Hints: yyDollar[7].indexHints} } - case 352: + case 355: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1921 +//line sql.y:1936 { yyVAL.columns = Columns{yyDollar[1].colIdent} } - case 353: + case 356: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1925 +//line sql.y:1940 { yyVAL.columns = append(yyVAL.columns, yyDollar[3].colIdent) } - case 354: + case 357: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1931 +//line sql.y:1946 { yyVAL.partitions = Partitions{yyDollar[1].colIdent} } - case 355: + case 358: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1935 +//line sql.y:1950 { yyVAL.partitions = append(yyVAL.partitions, yyDollar[3].colIdent) } - case 356: + case 359: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:1948 +//line sql.y:1963 { yyVAL.tableExpr = &JoinTableExpr{LeftExpr: yyDollar[1].tableExpr, Join: yyDollar[2].str, RightExpr: yyDollar[3].tableExpr, Condition: yyDollar[4].joinCondition} } - case 357: + case 360: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:1952 +//line sql.y:1967 { yyVAL.tableExpr = &JoinTableExpr{LeftExpr: yyDollar[1].tableExpr, Join: yyDollar[2].str, RightExpr: yyDollar[3].tableExpr, Condition: yyDollar[4].joinCondition} } - case 358: + case 361: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:1956 +//line sql.y:1971 { yyVAL.tableExpr = &JoinTableExpr{LeftExpr: yyDollar[1].tableExpr, Join: yyDollar[2].str, RightExpr: yyDollar[3].tableExpr, Condition: yyDollar[4].joinCondition} } - case 359: + case 362: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1960 +//line sql.y:1975 { yyVAL.tableExpr = &JoinTableExpr{LeftExpr: yyDollar[1].tableExpr, Join: yyDollar[2].str, RightExpr: yyDollar[3].tableExpr} } - case 360: + case 363: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1966 +//line sql.y:1981 { yyVAL.joinCondition = JoinCondition{On: yyDollar[2].expr} } - case 361: + case 364: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:1968 +//line sql.y:1983 { yyVAL.joinCondition = JoinCondition{Using: yyDollar[3].columns} } - case 362: + case 365: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:1972 +//line sql.y:1987 { yyVAL.joinCondition = JoinCondition{} } - case 363: + case 366: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1974 +//line sql.y:1989 { yyVAL.joinCondition = yyDollar[1].joinCondition } - case 364: + case 367: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:1978 +//line sql.y:1993 { yyVAL.joinCondition = JoinCondition{} } - case 365: + case 368: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1980 +//line sql.y:1995 { yyVAL.joinCondition = JoinCondition{On: yyDollar[2].expr} } - case 366: + case 369: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:1983 +//line sql.y:1998 { yyVAL.empty = struct{}{} } - case 367: + case 370: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1985 +//line sql.y:2000 { yyVAL.empty = struct{}{} } - case 368: + case 371: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:1988 +//line sql.y:2003 { yyVAL.tableIdent = NewTableIdent("") } - case 369: + case 372: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1992 +//line sql.y:2007 { yyVAL.tableIdent = yyDollar[1].tableIdent } - case 370: + case 373: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1996 +//line sql.y:2011 { yyVAL.tableIdent = yyDollar[2].tableIdent } - case 372: + case 375: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2003 +//line sql.y:2018 { yyVAL.tableIdent = NewTableIdent(string(yyDollar[1].bytes)) } - case 373: + case 376: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2009 +//line sql.y:2024 { yyVAL.str = JoinStr } - case 374: + case 377: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2013 +//line sql.y:2028 { yyVAL.str = JoinStr } - case 375: + case 378: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2017 +//line sql.y:2032 { yyVAL.str = JoinStr } - case 376: + case 379: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2023 +//line sql.y:2038 { yyVAL.str = StraightJoinStr } - case 377: + case 380: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2029 +//line sql.y:2044 { yyVAL.str = LeftJoinStr } - case 378: + case 381: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2033 +//line sql.y:2048 { yyVAL.str = LeftJoinStr } - case 379: + case 382: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2037 +//line sql.y:2052 { yyVAL.str = RightJoinStr } - case 380: + case 383: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2041 +//line sql.y:2056 { yyVAL.str = RightJoinStr } - case 381: + case 384: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2047 +//line sql.y:2062 { yyVAL.str = NaturalJoinStr } - case 382: + case 385: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2051 +//line sql.y:2066 { if yyDollar[2].str == LeftJoinStr { yyVAL.str = NaturalLeftJoinStr @@ -5186,465 +5186,465 @@ yydefault: yyVAL.str = NaturalRightJoinStr } } - case 383: + case 386: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2061 +//line sql.y:2076 { yyVAL.tableName = yyDollar[2].tableName } - case 384: + case 387: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2065 +//line sql.y:2080 { yyVAL.tableName = yyDollar[1].tableName } - case 385: + case 388: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2071 +//line sql.y:2086 { yyVAL.tableName = TableName{Name: yyDollar[1].tableIdent} } - case 386: + case 389: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2075 +//line sql.y:2090 { yyVAL.tableName = TableName{Qualifier: yyDollar[1].tableIdent, Name: yyDollar[3].tableIdent} } - case 387: + case 390: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2081 +//line sql.y:2096 { yyVAL.tableName = TableName{Name: yyDollar[1].tableIdent} } - case 388: + case 391: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:2086 +//line sql.y:2101 { yyVAL.indexHints = nil } - case 389: + case 392: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:2090 +//line sql.y:2105 { yyVAL.indexHints = &IndexHints{Type: UseStr, Indexes: yyDollar[4].columns} } - case 390: + case 393: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:2094 +//line sql.y:2109 { yyVAL.indexHints = &IndexHints{Type: IgnoreStr, Indexes: yyDollar[4].columns} } - case 391: + case 394: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:2098 +//line sql.y:2113 { yyVAL.indexHints = &IndexHints{Type: ForceStr, Indexes: yyDollar[4].columns} } - case 392: + case 395: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:2103 +//line sql.y:2118 { yyVAL.expr = nil } - case 393: + case 396: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2107 +//line sql.y:2122 { yyVAL.expr = yyDollar[2].expr } - case 394: + case 397: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2113 +//line sql.y:2128 { yyVAL.expr = yyDollar[1].expr } - case 395: + case 398: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2117 +//line sql.y:2132 { yyVAL.expr = &AndExpr{Left: yyDollar[1].expr, Right: yyDollar[3].expr} } - case 396: + case 399: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2121 +//line sql.y:2136 { yyVAL.expr = &OrExpr{Left: yyDollar[1].expr, Right: yyDollar[3].expr} } - case 397: + case 400: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2125 +//line sql.y:2140 { yyVAL.expr = &NotExpr{Expr: yyDollar[2].expr} } - case 398: + case 401: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2129 +//line sql.y:2144 { yyVAL.expr = &IsExpr{Operator: yyDollar[3].str, Expr: yyDollar[1].expr} } - case 399: + case 402: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2133 +//line sql.y:2148 { yyVAL.expr = yyDollar[1].expr } - case 400: + case 403: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2137 +//line sql.y:2152 { yyVAL.expr = &Default{ColName: yyDollar[2].str} } - case 401: + case 404: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:2143 +//line sql.y:2158 { yyVAL.str = "" } - case 402: + case 405: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2147 +//line sql.y:2162 { yyVAL.str = string(yyDollar[2].bytes) } - case 403: + case 406: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2153 +//line sql.y:2168 { yyVAL.boolVal = BoolVal(true) } - case 404: + case 407: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2157 +//line sql.y:2172 { yyVAL.boolVal = BoolVal(false) } - case 405: + case 408: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2163 +//line sql.y:2178 { yyVAL.expr = &ComparisonExpr{Left: yyDollar[1].expr, Operator: yyDollar[2].str, Right: yyDollar[3].expr} } - case 406: + case 409: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2167 +//line sql.y:2182 { yyVAL.expr = &ComparisonExpr{Left: yyDollar[1].expr, Operator: InStr, Right: yyDollar[3].colTuple} } - case 407: + case 410: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:2171 +//line sql.y:2186 { yyVAL.expr = &ComparisonExpr{Left: yyDollar[1].expr, Operator: NotInStr, Right: yyDollar[4].colTuple} } - case 408: + case 411: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:2175 +//line sql.y:2190 { yyVAL.expr = &ComparisonExpr{Left: yyDollar[1].expr, Operator: LikeStr, Right: yyDollar[3].expr, Escape: yyDollar[4].expr} } - case 409: + case 412: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:2179 +//line sql.y:2194 { yyVAL.expr = &ComparisonExpr{Left: yyDollar[1].expr, Operator: NotLikeStr, Right: yyDollar[4].expr, Escape: yyDollar[5].expr} } - case 410: + case 413: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2183 +//line sql.y:2198 { yyVAL.expr = &ComparisonExpr{Left: yyDollar[1].expr, Operator: RegexpStr, Right: yyDollar[3].expr} } - case 411: + case 414: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:2187 +//line sql.y:2202 { yyVAL.expr = &ComparisonExpr{Left: yyDollar[1].expr, Operator: NotRegexpStr, Right: yyDollar[4].expr} } - case 412: + case 415: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:2191 +//line sql.y:2206 { yyVAL.expr = &RangeCond{Left: yyDollar[1].expr, Operator: BetweenStr, From: yyDollar[3].expr, To: yyDollar[5].expr} } - case 413: + case 416: yyDollar = yyS[yypt-6 : yypt+1] -//line sql.y:2195 +//line sql.y:2210 { yyVAL.expr = &RangeCond{Left: yyDollar[1].expr, Operator: NotBetweenStr, From: yyDollar[4].expr, To: yyDollar[6].expr} } - case 414: + case 417: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2199 +//line sql.y:2214 { yyVAL.expr = &ExistsExpr{Subquery: yyDollar[2].subquery} } - case 415: + case 418: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2205 +//line sql.y:2220 { yyVAL.str = IsNullStr } - case 416: + case 419: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2209 +//line sql.y:2224 { yyVAL.str = IsNotNullStr } - case 417: + case 420: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2213 +//line sql.y:2228 { yyVAL.str = IsTrueStr } - case 418: + case 421: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2217 +//line sql.y:2232 { yyVAL.str = IsNotTrueStr } - case 419: + case 422: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2221 +//line sql.y:2236 { yyVAL.str = IsFalseStr } - case 420: + case 423: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2225 +//line sql.y:2240 { yyVAL.str = IsNotFalseStr } - case 421: + case 424: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2231 +//line sql.y:2246 { yyVAL.str = EqualStr } - case 422: + case 425: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2235 +//line sql.y:2250 { yyVAL.str = LessThanStr } - case 423: + case 426: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2239 +//line sql.y:2254 { yyVAL.str = GreaterThanStr } - case 424: + case 427: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2243 +//line sql.y:2258 { yyVAL.str = LessEqualStr } - case 425: + case 428: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2247 +//line sql.y:2262 { yyVAL.str = GreaterEqualStr } - case 426: + case 429: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2251 +//line sql.y:2266 { yyVAL.str = NotEqualStr } - case 427: + case 430: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2255 +//line sql.y:2270 { yyVAL.str = NullSafeEqualStr } - case 428: + case 431: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:2260 +//line sql.y:2275 { yyVAL.expr = nil } - case 429: + case 432: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2264 +//line sql.y:2279 { yyVAL.expr = yyDollar[2].expr } - case 430: + case 433: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2270 +//line sql.y:2285 { yyVAL.colTuple = yyDollar[1].valTuple } - case 431: + case 434: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2274 +//line sql.y:2289 { yyVAL.colTuple = yyDollar[1].subquery } - case 432: + case 435: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2278 +//line sql.y:2293 { yyVAL.colTuple = ListArg(yyDollar[1].bytes) } - case 433: + case 436: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2284 +//line sql.y:2299 { yyVAL.subquery = &Subquery{yyDollar[2].selStmt} } - case 434: + case 437: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2290 +//line sql.y:2305 { yyVAL.exprs = Exprs{yyDollar[1].expr} } - case 435: + case 438: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2294 +//line sql.y:2309 { yyVAL.exprs = append(yyDollar[1].exprs, yyDollar[3].expr) } - case 436: + case 439: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2300 +//line sql.y:2315 { yyVAL.expr = yyDollar[1].expr } - case 437: + case 440: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2304 +//line sql.y:2319 { yyVAL.expr = yyDollar[1].boolVal } - case 438: + case 441: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2308 +//line sql.y:2323 { yyVAL.expr = yyDollar[1].colName } - case 439: + case 442: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2312 +//line sql.y:2327 { yyVAL.expr = yyDollar[1].expr } - case 440: + case 443: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2316 +//line sql.y:2331 { yyVAL.expr = yyDollar[1].subquery } - case 441: + case 444: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2320 +//line sql.y:2335 { yyVAL.expr = &BinaryExpr{Left: yyDollar[1].expr, Operator: BitAndStr, Right: yyDollar[3].expr} } - case 442: + case 445: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2324 +//line sql.y:2339 { yyVAL.expr = &BinaryExpr{Left: yyDollar[1].expr, Operator: BitOrStr, Right: yyDollar[3].expr} } - case 443: + case 446: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2328 +//line sql.y:2343 { yyVAL.expr = &BinaryExpr{Left: yyDollar[1].expr, Operator: BitXorStr, Right: yyDollar[3].expr} } - case 444: + case 447: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2332 +//line sql.y:2347 { yyVAL.expr = &BinaryExpr{Left: yyDollar[1].expr, Operator: PlusStr, Right: yyDollar[3].expr} } - case 445: + case 448: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2336 +//line sql.y:2351 { yyVAL.expr = &BinaryExpr{Left: yyDollar[1].expr, Operator: MinusStr, Right: yyDollar[3].expr} } - case 446: + case 449: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2340 +//line sql.y:2355 { yyVAL.expr = &BinaryExpr{Left: yyDollar[1].expr, Operator: MultStr, Right: yyDollar[3].expr} } - case 447: + case 450: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2344 +//line sql.y:2359 { yyVAL.expr = &BinaryExpr{Left: yyDollar[1].expr, Operator: DivStr, Right: yyDollar[3].expr} } - case 448: + case 451: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2348 +//line sql.y:2363 { yyVAL.expr = &BinaryExpr{Left: yyDollar[1].expr, Operator: IntDivStr, Right: yyDollar[3].expr} } - case 449: + case 452: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2352 +//line sql.y:2367 { yyVAL.expr = &BinaryExpr{Left: yyDollar[1].expr, Operator: ModStr, Right: yyDollar[3].expr} } - case 450: + case 453: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2356 +//line sql.y:2371 { yyVAL.expr = &BinaryExpr{Left: yyDollar[1].expr, Operator: ModStr, Right: yyDollar[3].expr} } - case 451: + case 454: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2360 +//line sql.y:2375 { yyVAL.expr = &BinaryExpr{Left: yyDollar[1].expr, Operator: ShiftLeftStr, Right: yyDollar[3].expr} } - case 452: + case 455: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2364 +//line sql.y:2379 { yyVAL.expr = &BinaryExpr{Left: yyDollar[1].expr, Operator: ShiftRightStr, Right: yyDollar[3].expr} } - case 453: + case 456: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2368 +//line sql.y:2383 { yyVAL.expr = &BinaryExpr{Left: yyDollar[1].colName, Operator: JSONExtractOp, Right: yyDollar[3].expr} } - case 454: + case 457: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2372 +//line sql.y:2387 { yyVAL.expr = &BinaryExpr{Left: yyDollar[1].colName, Operator: JSONUnquoteExtractOp, Right: yyDollar[3].expr} } - case 455: + case 458: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2376 +//line sql.y:2391 { yyVAL.expr = &CollateExpr{Expr: yyDollar[1].expr, Charset: yyDollar[3].str} } - case 456: + case 459: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2380 +//line sql.y:2395 { yyVAL.expr = &UnaryExpr{Operator: BinaryStr, Expr: yyDollar[2].expr} } - case 457: + case 460: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2384 +//line sql.y:2399 { yyVAL.expr = &UnaryExpr{Operator: UBinaryStr, Expr: yyDollar[2].expr} } - case 458: + case 461: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2388 +//line sql.y:2403 { yyVAL.expr = &UnaryExpr{Operator: Utf8mb4Str, Expr: yyDollar[2].expr} } - case 459: + case 462: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2392 +//line sql.y:2407 { if num, ok := yyDollar[2].expr.(*SQLVal); ok && num.Type == IntVal { yyVAL.expr = num @@ -5652,9 +5652,9 @@ yydefault: yyVAL.expr = &UnaryExpr{Operator: UPlusStr, Expr: yyDollar[2].expr} } } - case 460: + case 463: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2400 +//line sql.y:2415 { if num, ok := yyDollar[2].expr.(*SQLVal); ok && num.Type == IntVal { // Handle double negative @@ -5668,21 +5668,21 @@ yydefault: yyVAL.expr = &UnaryExpr{Operator: UMinusStr, Expr: yyDollar[2].expr} } } - case 461: + case 464: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2414 +//line sql.y:2429 { yyVAL.expr = &UnaryExpr{Operator: TildaStr, Expr: yyDollar[2].expr} } - case 462: + case 465: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2418 +//line sql.y:2433 { yyVAL.expr = &UnaryExpr{Operator: BangStr, Expr: yyDollar[2].expr} } - case 463: + case 466: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2422 +//line sql.y:2437 { // This rule prevents the usage of INTERVAL // as a function. If support is needed for that, @@ -5690,485 +5690,485 @@ yydefault: // will be non-trivial because of grammar conflicts. yyVAL.expr = &IntervalExpr{Expr: yyDollar[2].expr, Unit: yyDollar[3].colIdent.String()} } - case 468: + case 471: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:2440 +//line sql.y:2455 { yyVAL.expr = &FuncExpr{Name: yyDollar[1].colIdent, Exprs: yyDollar[3].selectExprs} } - case 469: + case 472: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:2444 +//line sql.y:2459 { yyVAL.expr = &FuncExpr{Name: yyDollar[1].colIdent, Distinct: true, Exprs: yyDollar[4].selectExprs} } - case 470: + case 473: yyDollar = yyS[yypt-6 : yypt+1] -//line sql.y:2448 +//line sql.y:2463 { yyVAL.expr = &FuncExpr{Qualifier: yyDollar[1].tableIdent, Name: yyDollar[3].colIdent, Exprs: yyDollar[5].selectExprs} } - case 471: + case 474: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:2458 +//line sql.y:2473 { yyVAL.expr = &FuncExpr{Name: NewColIdent("left"), Exprs: yyDollar[3].selectExprs} } - case 472: + case 475: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:2462 +//line sql.y:2477 { yyVAL.expr = &FuncExpr{Name: NewColIdent("right"), Exprs: yyDollar[3].selectExprs} } - case 473: + case 476: yyDollar = yyS[yypt-6 : yypt+1] -//line sql.y:2466 +//line sql.y:2481 { yyVAL.expr = &ConvertExpr{Expr: yyDollar[3].expr, Type: yyDollar[5].convertType} } - case 474: + case 477: yyDollar = yyS[yypt-6 : yypt+1] -//line sql.y:2470 +//line sql.y:2485 { yyVAL.expr = &ConvertExpr{Expr: yyDollar[3].expr, Type: yyDollar[5].convertType} } - case 475: + case 478: yyDollar = yyS[yypt-6 : yypt+1] -//line sql.y:2474 +//line sql.y:2489 { yyVAL.expr = &ConvertUsingExpr{Expr: yyDollar[3].expr, Type: yyDollar[5].str} } - case 476: + case 479: yyDollar = yyS[yypt-8 : yypt+1] -//line sql.y:2478 +//line sql.y:2493 { yyVAL.expr = &SubstrExpr{Name: yyDollar[3].colName, From: yyDollar[5].expr, To: yyDollar[7].expr} } - case 477: + case 480: yyDollar = yyS[yypt-8 : yypt+1] -//line sql.y:2482 +//line sql.y:2497 { yyVAL.expr = &SubstrExpr{Name: yyDollar[3].colName, From: yyDollar[5].expr, To: yyDollar[7].expr} } - case 478: + case 481: yyDollar = yyS[yypt-8 : yypt+1] -//line sql.y:2486 +//line sql.y:2501 { yyVAL.expr = &SubstrExpr{StrVal: NewStrVal(yyDollar[3].bytes), From: yyDollar[5].expr, To: yyDollar[7].expr} } - case 479: + case 482: yyDollar = yyS[yypt-8 : yypt+1] -//line sql.y:2490 +//line sql.y:2505 { yyVAL.expr = &SubstrExpr{StrVal: NewStrVal(yyDollar[3].bytes), From: yyDollar[5].expr, To: yyDollar[7].expr} } - case 480: + case 483: yyDollar = yyS[yypt-9 : yypt+1] -//line sql.y:2494 +//line sql.y:2509 { yyVAL.expr = &MatchExpr{Columns: yyDollar[3].selectExprs, Expr: yyDollar[7].expr, Option: yyDollar[8].str} } - case 481: + case 484: yyDollar = yyS[yypt-7 : yypt+1] -//line sql.y:2498 +//line sql.y:2513 { yyVAL.expr = &GroupConcatExpr{Distinct: yyDollar[3].str, Exprs: yyDollar[4].selectExprs, OrderBy: yyDollar[5].orderBy, Separator: yyDollar[6].str} } - case 482: + case 485: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:2502 +//line sql.y:2517 { yyVAL.expr = &CaseExpr{Expr: yyDollar[2].expr, Whens: yyDollar[3].whens, Else: yyDollar[4].expr} } - case 483: + case 486: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:2506 +//line sql.y:2521 { yyVAL.expr = &ValuesFuncExpr{Name: yyDollar[3].colName} } - case 484: + case 487: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2516 +//line sql.y:2531 { yyVAL.expr = &FuncExpr{Name: NewColIdent("current_timestamp")} } - case 485: + case 488: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2520 +//line sql.y:2535 { yyVAL.expr = &FuncExpr{Name: NewColIdent("utc_timestamp")} } - case 486: + case 489: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2524 +//line sql.y:2539 { yyVAL.expr = &FuncExpr{Name: NewColIdent("utc_time")} } - case 487: + case 490: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2529 +//line sql.y:2544 { yyVAL.expr = &FuncExpr{Name: NewColIdent("utc_date")} } - case 488: + case 491: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2534 +//line sql.y:2549 { yyVAL.expr = &FuncExpr{Name: NewColIdent("localtime")} } - case 489: + case 492: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2539 +//line sql.y:2554 { yyVAL.expr = &FuncExpr{Name: NewColIdent("localtimestamp")} } - case 490: + case 493: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2545 +//line sql.y:2560 { yyVAL.expr = &FuncExpr{Name: NewColIdent("current_date")} } - case 491: + case 494: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2550 +//line sql.y:2565 { yyVAL.expr = &FuncExpr{Name: NewColIdent("current_time")} } - case 492: + case 495: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2555 +//line sql.y:2570 { yyVAL.expr = &CurTimeFuncExpr{Name: NewColIdent("current_timestamp"), Fsp: yyDollar[2].expr} } - case 493: + case 496: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2559 +//line sql.y:2574 { yyVAL.expr = &CurTimeFuncExpr{Name: NewColIdent("utc_timestamp"), Fsp: yyDollar[2].expr} } - case 494: + case 497: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2563 +//line sql.y:2578 { yyVAL.expr = &CurTimeFuncExpr{Name: NewColIdent("utc_time"), Fsp: yyDollar[2].expr} } - case 495: + case 498: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2568 +//line sql.y:2583 { yyVAL.expr = &CurTimeFuncExpr{Name: NewColIdent("localtime"), Fsp: yyDollar[2].expr} } - case 496: + case 499: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2573 +//line sql.y:2588 { yyVAL.expr = &CurTimeFuncExpr{Name: NewColIdent("localtimestamp"), Fsp: yyDollar[2].expr} } - case 497: + case 500: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2578 +//line sql.y:2593 { yyVAL.expr = &CurTimeFuncExpr{Name: NewColIdent("current_time"), Fsp: yyDollar[2].expr} } - case 498: + case 501: yyDollar = yyS[yypt-8 : yypt+1] -//line sql.y:2582 +//line sql.y:2597 { yyVAL.expr = &TimestampFuncExpr{Name: string("timestampadd"), Unit: yyDollar[3].colIdent.String(), Expr1: yyDollar[5].expr, Expr2: yyDollar[7].expr} } - case 499: + case 502: yyDollar = yyS[yypt-8 : yypt+1] -//line sql.y:2586 +//line sql.y:2601 { yyVAL.expr = &TimestampFuncExpr{Name: string("timestampdiff"), Unit: yyDollar[3].colIdent.String(), Expr1: yyDollar[5].expr, Expr2: yyDollar[7].expr} } - case 502: + case 505: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2596 +//line sql.y:2611 { yyVAL.expr = yyDollar[2].expr } - case 503: + case 506: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:2606 +//line sql.y:2621 { yyVAL.expr = &FuncExpr{Name: NewColIdent("if"), Exprs: yyDollar[3].selectExprs} } - case 504: + case 507: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:2610 +//line sql.y:2625 { yyVAL.expr = &FuncExpr{Name: NewColIdent("database"), Exprs: yyDollar[3].selectExprs} } - case 505: + case 508: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:2614 +//line sql.y:2629 { yyVAL.expr = &FuncExpr{Name: NewColIdent("mod"), Exprs: yyDollar[3].selectExprs} } - case 506: + case 509: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:2618 +//line sql.y:2633 { yyVAL.expr = &FuncExpr{Name: NewColIdent("replace"), Exprs: yyDollar[3].selectExprs} } - case 507: + case 510: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:2622 +//line sql.y:2637 { yyVAL.expr = &FuncExpr{Name: NewColIdent("substr"), Exprs: yyDollar[3].selectExprs} } - case 508: + case 511: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:2626 +//line sql.y:2641 { yyVAL.expr = &FuncExpr{Name: NewColIdent("substr"), Exprs: yyDollar[3].selectExprs} } - case 509: + case 512: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:2632 +//line sql.y:2647 { yyVAL.str = "" } - case 510: + case 513: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2636 +//line sql.y:2651 { yyVAL.str = BooleanModeStr } - case 511: + case 514: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:2640 +//line sql.y:2655 { yyVAL.str = NaturalLanguageModeStr } - case 512: + case 515: yyDollar = yyS[yypt-7 : yypt+1] -//line sql.y:2644 +//line sql.y:2659 { yyVAL.str = NaturalLanguageModeWithQueryExpansionStr } - case 513: + case 516: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2648 +//line sql.y:2663 { yyVAL.str = QueryExpansionStr } - case 514: + case 517: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2654 +//line sql.y:2669 { yyVAL.str = string(yyDollar[1].bytes) } - case 515: + case 518: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2658 +//line sql.y:2673 { yyVAL.str = string(yyDollar[1].bytes) } - case 516: + case 519: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2664 +//line sql.y:2679 { yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes), Length: yyDollar[2].sqlVal} } - case 517: + case 520: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2668 +//line sql.y:2683 { yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes), Length: yyDollar[2].sqlVal, Charset: yyDollar[3].str, Operator: CharacterSetStr} } - case 518: + case 521: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2672 +//line sql.y:2687 { yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes), Length: yyDollar[2].sqlVal, Charset: string(yyDollar[3].bytes)} } - case 519: + case 522: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2676 +//line sql.y:2691 { yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes)} } - case 520: + case 523: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2680 +//line sql.y:2695 { yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes), Length: yyDollar[2].sqlVal} } - case 521: + case 524: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2684 +//line sql.y:2699 { 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 525: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2690 +//line sql.y:2705 { yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes)} } - case 523: + case 526: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2694 +//line sql.y:2709 { yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes), Length: yyDollar[2].sqlVal} } - case 524: + case 527: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2698 +//line sql.y:2713 { yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes)} } - case 525: + case 528: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2702 +//line sql.y:2717 { yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes)} } - case 526: + case 529: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2706 +//line sql.y:2721 { yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes), Length: yyDollar[2].sqlVal} } - case 527: + case 530: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2710 +//line sql.y:2725 { yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes)} } - case 528: + case 531: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2714 +//line sql.y:2729 { yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes)} } - case 529: + case 532: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:2719 +//line sql.y:2734 { yyVAL.expr = nil } - case 530: + case 533: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2723 +//line sql.y:2738 { yyVAL.expr = yyDollar[1].expr } - case 531: + case 534: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:2728 +//line sql.y:2743 { yyVAL.str = string("") } - case 532: + case 535: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2732 +//line sql.y:2747 { yyVAL.str = " separator '" + string(yyDollar[2].bytes) + "'" } - case 533: + case 536: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2738 +//line sql.y:2753 { yyVAL.whens = []*When{yyDollar[1].when} } - case 534: + case 537: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2742 +//line sql.y:2757 { yyVAL.whens = append(yyDollar[1].whens, yyDollar[2].when) } - case 535: + case 538: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:2748 +//line sql.y:2763 { yyVAL.when = &When{Cond: yyDollar[2].expr, Val: yyDollar[4].expr} } - case 536: + case 539: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:2753 +//line sql.y:2768 { yyVAL.expr = nil } - case 537: + case 540: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2757 +//line sql.y:2772 { yyVAL.expr = yyDollar[2].expr } - case 538: + case 541: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2763 +//line sql.y:2778 { yyVAL.colName = &ColName{Name: yyDollar[1].colIdent} } - case 539: + case 542: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2767 +//line sql.y:2782 { yyVAL.colName = &ColName{Qualifier: TableName{Name: yyDollar[1].tableIdent}, Name: yyDollar[3].colIdent} } - case 540: + case 543: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:2771 +//line sql.y:2786 { yyVAL.colName = &ColName{Qualifier: TableName{Qualifier: yyDollar[1].tableIdent, Name: yyDollar[3].tableIdent}, Name: yyDollar[5].colIdent} } - case 541: + case 544: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2777 +//line sql.y:2792 { yyVAL.expr = NewStrVal(yyDollar[1].bytes) } - case 542: + case 545: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2781 +//line sql.y:2796 { yyVAL.expr = NewHexVal(yyDollar[1].bytes) } - case 543: + case 546: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2785 +//line sql.y:2800 { yyVAL.expr = NewBitVal(yyDollar[1].bytes) } - case 544: + case 547: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2789 +//line sql.y:2804 { yyVAL.expr = NewIntVal(yyDollar[1].bytes) } - case 545: + case 548: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2793 +//line sql.y:2808 { yyVAL.expr = NewFloatVal(yyDollar[1].bytes) } - case 546: + case 549: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2797 +//line sql.y:2812 { yyVAL.expr = NewHexNum(yyDollar[1].bytes) } - case 547: + case 550: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2801 +//line sql.y:2816 { yyVAL.expr = NewValArg(yyDollar[1].bytes) } - case 548: + case 551: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2805 +//line sql.y:2820 { yyVAL.expr = &NullVal{} } - case 549: + case 552: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2811 +//line sql.y:2826 { // TODO(sougou): Deprecate this construct. if yyDollar[1].colIdent.Lowered() != "value" { @@ -6177,239 +6177,239 @@ yydefault: } yyVAL.expr = NewIntVal([]byte("1")) } - case 550: + case 553: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2820 +//line sql.y:2835 { yyVAL.expr = NewIntVal(yyDollar[1].bytes) } - case 551: + case 554: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2824 +//line sql.y:2839 { yyVAL.expr = NewValArg(yyDollar[1].bytes) } - case 552: + case 555: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:2829 +//line sql.y:2844 { yyVAL.exprs = nil } - case 553: + case 556: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2833 +//line sql.y:2848 { yyVAL.exprs = yyDollar[3].exprs } - case 554: + case 557: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:2838 +//line sql.y:2853 { yyVAL.expr = nil } - case 555: + case 558: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2842 +//line sql.y:2857 { yyVAL.expr = yyDollar[2].expr } - case 556: + case 559: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:2847 +//line sql.y:2862 { yyVAL.orderBy = nil } - case 557: + case 560: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2851 +//line sql.y:2866 { yyVAL.orderBy = yyDollar[3].orderBy } - case 558: + case 561: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2857 +//line sql.y:2872 { yyVAL.orderBy = OrderBy{yyDollar[1].order} } - case 559: + case 562: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2861 +//line sql.y:2876 { yyVAL.orderBy = append(yyDollar[1].orderBy, yyDollar[3].order) } - case 560: + case 563: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2867 +//line sql.y:2882 { yyVAL.order = &Order{Expr: yyDollar[1].expr, Direction: yyDollar[2].str} } - case 561: + case 564: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:2872 +//line sql.y:2887 { yyVAL.str = AscScr } - case 562: + case 565: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2876 +//line sql.y:2891 { yyVAL.str = AscScr } - case 563: + case 566: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2880 +//line sql.y:2895 { yyVAL.str = DescScr } - case 564: + case 567: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:2885 +//line sql.y:2900 { yyVAL.limit = nil } - case 565: + case 568: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2889 +//line sql.y:2904 { yyVAL.limit = &Limit{Rowcount: yyDollar[2].expr} } - case 566: + case 569: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:2893 +//line sql.y:2908 { yyVAL.limit = &Limit{Offset: yyDollar[2].expr, Rowcount: yyDollar[4].expr} } - case 567: + case 570: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:2897 +//line sql.y:2912 { yyVAL.limit = &Limit{Offset: yyDollar[4].expr, Rowcount: yyDollar[2].expr} } - case 568: + case 571: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:2902 +//line sql.y:2917 { yyVAL.str = "" } - case 569: + case 572: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2906 +//line sql.y:2921 { yyVAL.str = ForUpdateStr } - case 570: + case 573: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:2910 +//line sql.y:2925 { yyVAL.str = ShareModeStr } - case 571: + case 574: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2923 +//line sql.y:2938 { yyVAL.ins = &Insert{Rows: yyDollar[2].values} } - case 572: + case 575: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2927 +//line sql.y:2942 { yyVAL.ins = &Insert{Rows: yyDollar[1].selStmt} } - case 573: + case 576: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2931 +//line sql.y:2946 { // Drop the redundant parenthesis. yyVAL.ins = &Insert{Rows: yyDollar[2].selStmt} } - case 574: + case 577: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:2936 +//line sql.y:2951 { yyVAL.ins = &Insert{Columns: yyDollar[2].columns, Rows: yyDollar[5].values} } - case 575: + case 578: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:2940 +//line sql.y:2955 { yyVAL.ins = &Insert{Columns: yyDollar[2].columns, Rows: yyDollar[4].selStmt} } - case 576: + case 579: yyDollar = yyS[yypt-6 : yypt+1] -//line sql.y:2944 +//line sql.y:2959 { // Drop the redundant parenthesis. yyVAL.ins = &Insert{Columns: yyDollar[2].columns, Rows: yyDollar[5].selStmt} } - case 577: + case 580: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2951 +//line sql.y:2966 { yyVAL.columns = Columns{yyDollar[1].colIdent} } - case 578: + case 581: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2955 +//line sql.y:2970 { yyVAL.columns = Columns{yyDollar[3].colIdent} } - case 579: + case 582: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2959 +//line sql.y:2974 { yyVAL.columns = append(yyVAL.columns, yyDollar[3].colIdent) } - case 580: + case 583: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:2963 +//line sql.y:2978 { yyVAL.columns = append(yyVAL.columns, yyDollar[5].colIdent) } - case 581: + case 584: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:2968 +//line sql.y:2983 { yyVAL.updateExprs = nil } - case 582: + case 585: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:2972 +//line sql.y:2987 { yyVAL.updateExprs = yyDollar[5].updateExprs } - case 583: + case 586: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2978 +//line sql.y:2993 { yyVAL.values = Values{yyDollar[1].valTuple} } - case 584: + case 587: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2982 +//line sql.y:2997 { yyVAL.values = append(yyDollar[1].values, yyDollar[3].valTuple) } - case 585: + case 588: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2988 +//line sql.y:3003 { yyVAL.valTuple = yyDollar[1].valTuple } - case 586: + case 589: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2992 +//line sql.y:3007 { yyVAL.valTuple = ValTuple{} } - case 587: + case 590: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2998 +//line sql.y:3013 { yyVAL.valTuple = ValTuple(yyDollar[2].exprs) } - case 588: + case 591: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3004 +//line sql.y:3019 { if len(yyDollar[1].valTuple) == 1 { yyVAL.expr = &ParenExpr{yyDollar[1].valTuple[0]} @@ -6417,312 +6417,312 @@ yydefault: yyVAL.expr = yyDollar[1].valTuple } } - case 589: + case 592: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3014 +//line sql.y:3029 { yyVAL.updateExprs = UpdateExprs{yyDollar[1].updateExpr} } - case 590: + case 593: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:3018 +//line sql.y:3033 { yyVAL.updateExprs = append(yyDollar[1].updateExprs, yyDollar[3].updateExpr) } - case 591: + case 594: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:3024 +//line sql.y:3039 { yyVAL.updateExpr = &UpdateExpr{Name: yyDollar[1].colName, Expr: yyDollar[3].expr} } - case 592: + case 595: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3030 +//line sql.y:3045 { yyVAL.setExprs = SetExprs{yyDollar[1].setExpr} } - case 593: + case 596: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:3034 +//line sql.y:3049 { yyVAL.setExprs = append(yyDollar[1].setExprs, yyDollar[3].setExpr) } - case 594: + case 597: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:3040 +//line sql.y:3055 { yyVAL.setExpr = &SetExpr{Name: yyDollar[1].colIdent, Expr: NewStrVal([]byte("on"))} } - case 595: + case 598: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:3044 +//line sql.y:3059 { yyVAL.setExpr = &SetExpr{Name: yyDollar[1].colIdent, Expr: NewStrVal([]byte("off"))} } - case 596: + case 599: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:3048 +//line sql.y:3063 { yyVAL.setExpr = &SetExpr{Name: yyDollar[1].colIdent, Expr: yyDollar[3].expr} } - case 597: + case 600: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:3052 +//line sql.y:3067 { yyVAL.setExpr = &SetExpr{Name: NewColIdent(string(yyDollar[1].bytes)), Expr: yyDollar[2].expr} } - case 599: + case 602: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:3059 +//line sql.y:3074 { yyVAL.bytes = []byte("charset") } - case 601: + case 604: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3066 +//line sql.y:3081 { yyVAL.expr = NewStrVal([]byte(yyDollar[1].colIdent.String())) } - case 602: + case 605: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3070 +//line sql.y:3085 { yyVAL.expr = NewStrVal(yyDollar[1].bytes) } - case 603: + case 606: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3074 +//line sql.y:3089 { yyVAL.expr = &Default{} } - case 606: + case 609: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:3083 +//line sql.y:3098 { yyVAL.byt = 0 } - case 607: + case 610: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:3085 +//line sql.y:3100 { yyVAL.byt = 1 } - case 608: + case 611: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:3088 +//line sql.y:3103 { yyVAL.empty = struct{}{} } - case 609: + case 612: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:3090 +//line sql.y:3105 { yyVAL.empty = struct{}{} } - case 610: + case 613: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:3093 +//line sql.y:3108 { yyVAL.str = "" } - case 611: - yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3095 - { - yyVAL.str = IgnoreStr - } - case 612: - yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3099 - { - yyVAL.empty = struct{}{} - } - case 613: - yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3101 - { - yyVAL.empty = struct{}{} - } case 614: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3103 +//line sql.y:3110 { - yyVAL.empty = struct{}{} + yyVAL.str = IgnoreStr } case 615: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3105 +//line sql.y:3114 { yyVAL.empty = struct{}{} } case 616: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3107 +//line sql.y:3116 { yyVAL.empty = struct{}{} } case 617: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3109 +//line sql.y:3118 { yyVAL.empty = struct{}{} } case 618: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3111 +//line sql.y:3120 { yyVAL.empty = struct{}{} } case 619: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3113 +//line sql.y:3122 { yyVAL.empty = struct{}{} } case 620: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3115 +//line sql.y:3124 { yyVAL.empty = struct{}{} } case 621: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3117 +//line sql.y:3126 { yyVAL.empty = struct{}{} } case 622: - yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:3120 + yyDollar = yyS[yypt-1 : yypt+1] +//line sql.y:3128 { yyVAL.empty = struct{}{} } case 623: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3122 +//line sql.y:3130 { yyVAL.empty = struct{}{} } case 624: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3124 +//line sql.y:3132 { yyVAL.empty = struct{}{} } case 625: - yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3128 + yyDollar = yyS[yypt-0 : yypt+1] +//line sql.y:3135 { yyVAL.empty = struct{}{} } case 626: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3130 +//line sql.y:3137 { yyVAL.empty = struct{}{} } case 627: - yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:3133 + yyDollar = yyS[yypt-1 : yypt+1] +//line sql.y:3139 { yyVAL.empty = struct{}{} } case 628: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3135 +//line sql.y:3143 { yyVAL.empty = struct{}{} } case 629: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3137 +//line sql.y:3145 { yyVAL.empty = struct{}{} } case 630: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:3140 +//line sql.y:3148 { - yyVAL.colIdent = ColIdent{} + yyVAL.empty = struct{}{} } case 631: + yyDollar = yyS[yypt-1 : yypt+1] +//line sql.y:3150 + { + yyVAL.empty = struct{}{} + } + case 632: + yyDollar = yyS[yypt-1 : yypt+1] +//line sql.y:3152 + { + yyVAL.empty = struct{}{} + } + case 633: + yyDollar = yyS[yypt-0 : yypt+1] +//line sql.y:3155 + { + yyVAL.colIdent = ColIdent{} + } + case 634: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:3142 +//line sql.y:3157 { yyVAL.colIdent = yyDollar[2].colIdent } - case 632: + case 635: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3146 +//line sql.y:3161 { yyVAL.colIdent = NewColIdent(string(yyDollar[1].bytes)) } - case 633: + case 636: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3150 +//line sql.y:3165 { yyVAL.colIdent = NewColIdent(string(yyDollar[1].bytes)) } - case 635: + case 638: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3157 +//line sql.y:3172 { yyVAL.colIdent = NewColIdent(string(yyDollar[1].bytes)) } - case 636: + case 639: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3163 +//line sql.y:3178 { yyVAL.tableIdent = NewTableIdent(string(yyDollar[1].bytes)) } - case 637: + case 640: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3167 +//line sql.y:3182 { yyVAL.tableIdent = NewTableIdent(string(yyDollar[1].bytes)) } - case 639: + case 642: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3174 +//line sql.y:3189 { yyVAL.tableIdent = NewTableIdent(string(yyDollar[1].bytes)) } - case 845: + case 849: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3405 +//line sql.y:3421 { if incNesting(yylex) { yylex.Error("max nesting level reached") return 1 } } - case 846: + case 850: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3414 +//line sql.y:3430 { decNesting(yylex) } - case 847: + case 851: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:3419 +//line sql.y:3435 { skipToEnd(yylex) } - case 848: + case 852: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:3424 +//line sql.y:3440 { skipToEnd(yylex) } - case 849: + case 853: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3428 +//line sql.y:3444 { skipToEnd(yylex) } - case 850: + case 854: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3432 +//line sql.y:3448 { skipToEnd(yylex) } diff --git a/go/vt/sqlparser/sql.y b/go/vt/sqlparser/sql.y index ed5fda40263..af2bba3a92b 100644 --- a/go/vt/sqlparser/sql.y +++ b/go/vt/sqlparser/sql.y @@ -182,7 +182,7 @@ func skipToEnd(yylex interface{}) { %token NULLX AUTO_INCREMENT APPROXNUM SIGNED UNSIGNED ZEROFILL // Supported SHOW tokens -%token COLLATION DATABASES TABLES VSCHEMA FULL PROCESSLIST COLUMNS FIELDS ENGINES PLUGINS +%token COLLATION DATABASES TABLES VITESS_METADATA VSCHEMA FULL PROCESSLIST COLUMNS FIELDS ENGINES PLUGINS // SET tokens %token NAMES CHARSET GLOBAL SESSION ISOLATION LEVEL READ WRITE ONLY REPEATABLE COMMITTED UNCOMMITTED SERIALIZABLE @@ -262,7 +262,7 @@ func skipToEnd(yylex interface{}) { %type for_from %type ignore_opt default_opt %type full_opt from_database_opt tables_or_processlist columns_or_fields -%type like_or_where_opt +%type like_or_where_opt like_opt %type exists_opt %type not_exists_opt non_add_drop_or_rename_operation to_opt index_opt constraint_opt %type reserved_keyword non_reserved_keyword @@ -1572,6 +1572,11 @@ show_statement: showCollationFilterOpt := $4 $$ = &Show{Type: string($2), ShowCollationFilterOpt: &showCollationFilterOpt} } +| SHOW VITESS_METADATA VARIABLES like_opt + { + showTablesOpt := &ShowTablesOpt{Filter: $4} + $$ = &Show{Scope: string($2), Type: string($3), ShowTablesOpt: showTablesOpt} + } | SHOW VSCHEMA TABLES { $$ = &Show{Type: string($2) + " " + string($3)} @@ -1661,6 +1666,16 @@ like_or_where_opt: $$ = &ShowFilter{Filter:$2} } +like_opt: + /* empty */ + { + $$ = nil + } + | LIKE STRING + { + $$ = &ShowFilter{Like:string($2)} + } + show_session_or_global: /* empty */ { @@ -3393,6 +3408,7 @@ non_reserved_keyword: | VIEW | VINDEX | VINDEXES +| VITESS_METADATA | VSCHEMA | WARNINGS | WITH diff --git a/go/vt/sqlparser/token.go b/go/vt/sqlparser/token.go index 0247cbf3cc6..d623138c88d 100644 --- a/go/vt/sqlparser/token.go +++ b/go/vt/sqlparser/token.go @@ -391,6 +391,7 @@ var keywords = map[string]int{ "vindex": VINDEX, "vindexes": VINDEXES, "view": VIEW, + "vitess_metadata": VITESS_METADATA, "vschema": VSCHEMA, "warnings": WARNINGS, "when": WHEN, diff --git a/go/vt/topo/events/metadata_change.go b/go/vt/topo/events/metadata_change.go new file mode 100644 index 00000000000..1163e14ae1a --- /dev/null +++ b/go/vt/topo/events/metadata_change.go @@ -0,0 +1,7 @@ +package events + +// MetadataChange is an event that describes changes to topology metadata +type MetadataChange struct { + Key string + Status string +} diff --git a/go/vt/topo/metadata.go b/go/vt/topo/metadata.go new file mode 100644 index 00000000000..349ea7f8084 --- /dev/null +++ b/go/vt/topo/metadata.go @@ -0,0 +1,92 @@ +/* +Copyright 2017 Google Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package topo + +import ( + "context" + "path" + "vitess.io/vitess/go/vt/sqlparser" + + "vitess.io/vitess/go/event" + "vitess.io/vitess/go/vt/topo/events" +) + +// UpsertMetadata sets the key/value in the metadata if it doesn't exist, otherwise it updates the content +func (ts *Server) UpsertMetadata(ctx context.Context, key string, val string) error { + keyPath := path.Join(MetadataPath, key) + + _, _, err := ts.globalCell.Get(ctx, keyPath) + status := "updated" + + if err != nil { + if !IsErrType(err, NoNode) { + return err + } + + status = "created" + } + + // nil version means that it will insert if keyPath does not exist + if _, err := ts.globalCell.Update(ctx, keyPath, []byte(val), nil); err != nil { + return err + } + + dispatchEvent(keyPath, status) + return nil +} + +// GetMetadata retrieves all metadata value that matches the given key regular expression. If empty all values are returned. +func (ts *Server) GetMetadata(ctx context.Context, keyFilter string) (map[string]string, error) { + keys, err := ts.globalCell.ListDir(ctx, MetadataPath, false) + if err != nil { + return nil, err + } + + re := sqlparser.LikeToRegexp(keyFilter) + + result := make(map[string]string) + for _, k := range keys { + if !re.MatchString(k.Name) { + continue + } + + val, err := ts.getMetadata(ctx, k.Name) + if err != nil { + return nil, err + } + result[k.Name] = val + } + + return result, nil +} + +func (ts *Server) getMetadata(ctx context.Context, key string) (string, error) { + keyPath := path.Join(MetadataPath, key) + contents, _, err := ts.globalCell.Get(ctx, keyPath) + if err != nil { + return "", err + } + + return string(contents), nil +} + +func dispatchEvent(key string, status string) { + event.Dispatch(&events.MetadataChange{ + Key: key, + Status: status, + }) +} diff --git a/go/vt/topo/server.go b/go/vt/topo/server.go index e28facc0486..6fb7795330e 100644 --- a/go/vt/topo/server.go +++ b/go/vt/topo/server.go @@ -84,6 +84,7 @@ const ( KeyspacesPath = "keyspaces" ShardsPath = "shards" TabletsPath = "tablets" + MetadataPath = "vitess_metadata" ) // Factory is a factory interface to create Conn objects. diff --git a/go/vt/vtgate/executor.go b/go/vt/vtgate/executor.go index cf38a9dec55..a21476e6b35 100644 --- a/go/vt/vtgate/executor.go +++ b/go/vt/vtgate/executor.go @@ -462,9 +462,13 @@ func (e *Executor) handleSet(ctx context.Context, safeSession *SafeSession, sql } for k, v := range vals { - if k.Scope == sqlparser.GlobalStr { + switch k.Scope { + case sqlparser.GlobalStr: return &sqltypes.Result{}, vterrors.New(vtrpcpb.Code_INVALID_ARGUMENT, "unsupported in set: global") + case sqlparser.VitessMetadataStr: + return e.handleSetVitessMetadata(ctx, safeSession, k, v) } + switch k.Key { case "autocommit": val, err := validateSetOnOff(v, k.Key) @@ -645,6 +649,63 @@ func (e *Executor) handleSet(ctx context.Context, safeSession *SafeSession, sql return &sqltypes.Result{}, nil } +func (e *Executor) handleSetVitessMetadata(ctx context.Context, session *SafeSession, k sqlparser.SetKey, v interface{}) (*sqltypes.Result, error) { + //TODO(kalfonso): move to its own acl check and consolidate into an acl component that can handle multiple operations (vschema, metadata) + allowed := vschemaacl.Authorized(callerid.ImmediateCallerIDFromContext(ctx)) + if !allowed { + return nil, vterrors.Errorf(vtrpcpb.Code_PERMISSION_DENIED, "not authorized to perform vitess metadata operations") + + } + + val, ok := v.(string) + if !ok { + return nil, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "unexpected value type for charset: %T", v) + } + + ts, err := e.serv.GetTopoServer() + if err != nil { + return nil, err + } + + if err := ts.UpsertMetadata(ctx, k.Key, val); err != nil { + return nil, err + } + + return &sqltypes.Result{}, nil +} + +func (e *Executor) handleShowVitessMetadata(ctx context.Context, session *SafeSession, opt *sqlparser.ShowTablesOpt) (*sqltypes.Result, error) { + ts, err := e.serv.GetTopoServer() + if err != nil { + return nil, err + } + + var metadata map[string]string + if opt.Filter == nil { + metadata, err = ts.GetMetadata(ctx, "") + if err != nil { + return nil, err + } + } else { + metadata, err = ts.GetMetadata(ctx, opt.Filter.Like) + if err != nil { + return nil, err + } + } + + rows := make([][]sqltypes.Value, 0, len(metadata)) + for k, v := range metadata { + row := buildVarCharRow(k, v) + rows = append(rows, row) + } + + return &sqltypes.Result{ + Fields: buildVarCharFields("Key", "Value"), + Rows: rows, + RowsAffected: uint64(len(rows)), + }, nil +} + func validateSetOnOff(v interface{}, typ string) (int64, error) { var val int64 switch v := v.(type) { @@ -680,6 +741,10 @@ func (e *Executor) handleShow(ctx context.Context, safeSession *SafeSession, sql switch strings.ToLower(show.Type) { case sqlparser.KeywordString(sqlparser.COLLATION), sqlparser.KeywordString(sqlparser.VARIABLES): + if show.Scope == sqlparser.VitessMetadataStr { + return e.handleShowVitessMetadata(ctx, safeSession, show.ShowTablesOpt) + } + if destKeyspace == "" { keyspaces, err := e.resolver.resolver.GetAllKeyspaces(ctx) if err != nil { diff --git a/go/vt/vtgate/executor_test.go b/go/vt/vtgate/executor_test.go index 6cb3f71f8e4..48224bc4266 100644 --- a/go/vt/vtgate/executor_test.go +++ b/go/vt/vtgate/executor_test.go @@ -28,6 +28,7 @@ import ( "strings" "testing" "time" + "vitess.io/vitess/go/vt/vterrors" "context" @@ -44,6 +45,8 @@ import ( vschemapb "vitess.io/vitess/go/vt/proto/vschema" vtgatepb "vitess.io/vitess/go/vt/proto/vtgate" vtrpcpb "vitess.io/vitess/go/vt/proto/vtrpc" + + "github.com/stretchr/testify/assert" ) func TestExecutorResultsExceeded(t *testing.T) { @@ -468,6 +471,66 @@ func TestExecutorSet(t *testing.T) { } } } + +func TestExecutorSetMetadata(t *testing.T) { + executor, _, _, _ := createExecutorEnv() + session := NewSafeSession(&vtgatepb.Session{TargetString: "@master", Autocommit: true}) + + set := "set @@vitess_metadata.app_keyspace_v1= '1'" + _, err := executor.Execute(context.Background(), "TestExecute", session, set, nil) + assert.Equalf(t, vtrpcpb.Code_PERMISSION_DENIED, vterrors.Code(err), "expected error %v, got error: %v", vtrpcpb.Code_PERMISSION_DENIED, err) + + *vschemaacl.AuthorizedDDLUsers = "%" + defer func() { + *vschemaacl.AuthorizedDDLUsers = "" + }() + + executor, _, _, _ = createExecutorEnv() + session = NewSafeSession(&vtgatepb.Session{TargetString: "@master", Autocommit: true}) + + set = "set @@vitess_metadata.app_keyspace_v1= '1'" + _, err = executor.Execute(context.Background(), "TestExecute", session, set, nil) + assert.NoError(t, err, "%s error: %v", set, err) + + show := `show vitess_metadata variables like 'app\\_keyspace\\_v_'` + result, err := executor.Execute(context.Background(), "TestExecute", session, show, nil) + assert.NoError(t, err) + + want := "1" + got := string(result.Rows[0][1].ToString()) + assert.Equalf(t, want, got, "want migrations %s, result %s", want, got) + + // Update metadata + set = "set @@vitess_metadata.app_keyspace_v2='2'" + _, err = executor.Execute(context.Background(), "TestExecute", session, set, nil) + assert.NoError(t, err, "%s error: %v", set, err) + + show = `show vitess_metadata variables like 'app\\_keyspace\\_v%'` + gotqr, err := executor.Execute(context.Background(), "TestExecute", session, show, nil) + assert.NoError(t, err) + + wantqr := &sqltypes.Result{ + Fields: buildVarCharFields("Key", "Value"), + Rows: [][]sqltypes.Value{ + buildVarCharRow("app_keyspace_v1", "1"), + buildVarCharRow("app_keyspace_v2", "2"), + }, + RowsAffected: 2, + } + + assert.Equal(t, wantqr.Fields, gotqr.Fields) + assert.ElementsMatch(t, wantqr.Rows, gotqr.Rows) + + show = "show vitess_metadata variables" + gotqr, err = executor.Execute(context.Background(), "TestExecute", session, show, nil) + if err != nil { + t.Error(err) + } + + assert.Equal(t, wantqr.Fields, gotqr.Fields) + assert.ElementsMatch(t, wantqr.Rows, gotqr.Rows) +} + func TestExecutorAutocommit(t *testing.T) { executor, _, _, sbclookup := createExecutorEnv() session := NewSafeSession(&vtgatepb.Session{TargetString: "@master"}) From ad420aa1e23ff745648a50e4950102da28aad232 Mon Sep 17 00:00:00 2001 From: Jon Tirsen Date: Tue, 27 Aug 2019 07:53:49 +1000 Subject: [PATCH 012/425] Only override session.TargetString if it has not been set Signed-off-by: Jon Tirsen --- go/vt/vtgate/mysql_protocol_test.go | 31 ++++++++++++++++++++++ go/vt/vtgate/plugin_mysql_server.go | 6 ++--- go/vt/vtqueryserver/plugin_mysql_server.go | 2 +- 3 files changed, 35 insertions(+), 4 deletions(-) diff --git a/go/vt/vtgate/mysql_protocol_test.go b/go/vt/vtgate/mysql_protocol_test.go index b8f420c888b..00f4990e164 100644 --- a/go/vt/vtgate/mysql_protocol_test.go +++ b/go/vt/vtgate/mysql_protocol_test.go @@ -22,6 +22,8 @@ import ( "strconv" "testing" + "github.com/stretchr/testify/assert" + "golang.org/x/net/context" "github.com/golang/protobuf/proto" @@ -92,6 +94,35 @@ func TestMySQLProtocolStreamExecute(t *testing.T) { } } +func TestMySQLProtocolExecuteUseStatement(t *testing.T) { + createSandbox(KsTestUnsharded) + hcVTGateTest.Reset() + hcVTGateTest.AddTestTablet("aa", "1.1.1.1", 1001, KsTestUnsharded, "0", topodatapb.TabletType_MASTER, true, 1, nil) + + c, err := mysqlConnect(&mysql.ConnParams{DbName: "@master"}) + if err != nil { + t.Fatal(err) + } + defer c.Close() + + qr, err := c.ExecuteFetch("show vitess_target", 1, false) + if err != nil { + t.Error(err) + } + assert.Equal(t, "VARCHAR(\"@master\")", qr.Rows[0][0].String()) + + _, err = c.ExecuteFetch("use TestUnsharded", 0, false) + if err != nil { + t.Error(err) + } + + qr, err = c.ExecuteFetch("show vitess_target", 1, false) + if err != nil { + t.Error(err) + } + assert.Equal(t, "VARCHAR(\"TestUnsharded\")", qr.Rows[0][0].String()) +} + func TestMysqlProtocolInvalidDB(t *testing.T) { c, err := mysqlConnect(&mysql.ConnParams{DbName: "invalidDB"}) if err != nil { diff --git a/go/vt/vtgate/plugin_mysql_server.go b/go/vt/vtgate/plugin_mysql_server.go index 85240db4804..f908ace6496 100644 --- a/go/vt/vtgate/plugin_mysql_server.go +++ b/go/vt/vtgate/plugin_mysql_server.go @@ -146,7 +146,7 @@ func (vh *vtgateHandler) ComQuery(c *mysql.Conn, query string, callback func(*sq } }() - if c.SchemaName != "" { + if session.TargetString == "" && c.SchemaName != "" { session.TargetString = c.SchemaName } if session.Options.Workload == querypb.ExecuteOptions_OLAP { @@ -209,7 +209,7 @@ func (vh *vtgateHandler) ComPrepare(c *mysql.Conn, query string) ([]*querypb.Fie } }() - if c.SchemaName != "" { + if session.TargetString == "" && c.SchemaName != "" { session.TargetString = c.SchemaName } @@ -268,7 +268,7 @@ func (vh *vtgateHandler) ComStmtExecute(c *mysql.Conn, prepare *mysql.PrepareDat } }() - if c.SchemaName != "" { + if session.TargetString == "" && c.SchemaName != "" { session.TargetString = c.SchemaName } if session.Options.Workload == querypb.ExecuteOptions_OLAP { diff --git a/go/vt/vtqueryserver/plugin_mysql_server.go b/go/vt/vtqueryserver/plugin_mysql_server.go index a900472d6bf..a2593b95af1 100644 --- a/go/vt/vtqueryserver/plugin_mysql_server.go +++ b/go/vt/vtqueryserver/plugin_mysql_server.go @@ -119,7 +119,7 @@ func (mh *proxyHandler) ComQuery(c *mysql.Conn, query string, callback func(*sql session.Options.ClientFoundRows = true } } - if c.SchemaName != "" { + if session.TargetString == "" && c.SchemaName != "" { session.TargetString = c.SchemaName } session, result, err := mh.mp.Execute(ctx, session, query, make(map[string]*querypb.BindVariable)) From 9e4ea01ccaee45685e0bdefecfd26ecbf25c5415 Mon Sep 17 00:00:00 2001 From: Rasika Kale Date: Tue, 13 Aug 2019 13:44:09 -0700 Subject: [PATCH 013/425] sqltypes: Subtract functionality Signed-off-by: Rasika Kale Signed-off-by: Sugu Sougoumarane --- go/sqltypes/arithmetic.go | 63 +++++++++++++++++++++++-- go/sqltypes/arithmetic_test.go | 85 ++++++++++++++++++++++++++++++++++ 2 files changed, 145 insertions(+), 3 deletions(-) diff --git a/go/sqltypes/arithmetic.go b/go/sqltypes/arithmetic.go index f5c18dd43a1..24fe939550d 100644 --- a/go/sqltypes/arithmetic.go +++ b/go/sqltypes/arithmetic.go @@ -28,9 +28,6 @@ import ( "vitess.io/vitess/go/vt/vterrors" ) -// TODO(sougou): change these functions to be more permissive. -// Most string to number conversions should quietly convert to 0. - // numeric represents a numeric value extracted from // a Value, used for arithmetic operations. type numeric struct { @@ -61,6 +58,24 @@ func Add(v1, v2 Value) (Value, error) { return castFromNumeric(lresult, lresult.typ), nil } +//Subtract takes two values and subtracts them +func Subtract(v1, v2 Value) (Value, error) { + if v1.IsNull() || v2.IsNull() { + return NULL, nil + } + + lv1, err := newNumeric(v1) + + lv2, err := newNumeric(v2) + + lresult, err := subtractNumericWithError(lv1, lv2) + if err != nil { + return NULL, err + } + + return castFromNumeric(lresult, lresult.typ), nil +} + // NullsafeAdd adds two Values in a null-safe manner. A null value // is treated as 0. If both values are null, then a null is returned. // If both values are not null, a numeric value is built @@ -376,6 +391,25 @@ func addNumericWithError(v1, v2 numeric) (numeric, error) { } +func subtractNumericWithError(v1, v2 numeric) (numeric, error) { + v1, v2 = prioritize(v1, v2) + switch v1.typ { + case Int64: + return intMinusIntWithError(v1.ival, v2.ival) + case Uint64: + switch v2.typ { + case Int64: + return uintMinusIntWithError(v1.uval, v2.ival) + case Uint64: + return uintMinusUintWithError(v1.uval, v2.uval) + } + case Float64: + return floatPlusAny(v1.fval, v2), nil + } + panic("unreachable") + +} + // prioritize reorders the input parameters // to be Float64, Uint64, Int64. func prioritize(v1, v2 numeric) (altv1, altv2 numeric) { @@ -415,6 +449,15 @@ func intPlusIntWithError(v1, v2 int64) (numeric, error) { return numeric{typ: Int64, ival: result}, nil } +func intMinusIntWithError(v1, v2 int64) (numeric, error) { + result := v1 - v2 + if v1 > 0 && v2 > math.MaxInt64 || v1 > math.MaxInt64 && v2 > 0 || v1 <= math.MinInt64 && v2 > 0 || v1 > 0 && v2 <= math.MinInt64 { + return numeric{}, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "BIGINT value is out of range in %v - %v", v1, v2) + } + + return numeric{typ: Int64, ival: result}, nil +} + func uintPlusInt(v1 uint64, v2 int64) numeric { return uintPlusUint(v1, uint64(v2)) } @@ -429,6 +472,14 @@ func uintPlusIntWithError(v1 uint64, v2 int64) (numeric, error) { return uintPlusUintWithError(v1, uint64(v2)) } +func uintMinusIntWithError(v1 uint64, v2 int64) (numeric, error) { + if v1 < uint64(v2) { + return numeric{}, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "BIGINT UNSIGNED value is out of range in %v - %v", v1, v2) + } + + return uintMinusUintWithError(v1, uint64(v2)) +} + func uintPlusUint(v1, v2 uint64) numeric { result := v1 + v2 if result < v2 { @@ -448,6 +499,12 @@ func uintPlusUintWithError(v1, v2 uint64) (numeric, error) { return numeric{typ: Uint64, uval: result}, nil } +func uintMinusUintWithError(v1, v2 uint64) (numeric, error) { + result := v1 - v2 + + return numeric{typ: Uint64, uval: result}, nil +} + func floatPlusAny(v1 float64, v2 numeric) numeric { switch v2.typ { case Int64: diff --git a/go/sqltypes/arithmetic_test.go b/go/sqltypes/arithmetic_test.go index 81aeba0cf30..f3de7542051 100644 --- a/go/sqltypes/arithmetic_test.go +++ b/go/sqltypes/arithmetic_test.go @@ -29,6 +29,91 @@ import ( "vitess.io/vitess/go/vt/vterrors" ) +func TestSubtract(t *testing.T) { + tcases := []struct { + v1, v2 Value + out Value + err error + }{{ + + //All Nulls + v1: NULL, + v2: NULL, + out: NULL, + }, { + + // First value null. + v1: NewInt32(1), + v2: NULL, + out: NULL, + }, { + + // Second value null. + v1: NULL, + v2: NewInt32(1), + out: NULL, + }, { + + // case with negative value + v1: NewInt64(-1), + v2: NewInt64(-2), + out: NewInt64(1), + }, { + + // testing for int64 overflow with min negative value + v1: NewInt64(math.MinInt64), + v2: NewInt64(1), + err: vterrors.New(vtrpcpb.Code_INVALID_ARGUMENT, "BIGINT value is out of range in -9223372036854775808 - 1"), + }, { + + v1: NewUint64(4), + v2: NewInt64(5), + err: vterrors.New(vtrpcpb.Code_INVALID_ARGUMENT, "BIGINT UNSIGNED value is out of range in 4 - 5"), + }, { + + v1: NewUint64(7), + v2: NewInt64(5), + out: NewUint64(2), + }, { + + v1: NewUint64(math.MaxUint64), + v2: NewInt64(0), + out: NewUint64(math.MaxUint64), + }, { + + // testing for int64 overflow + v1: NewInt64(math.MinInt64), + v2: NewUint64(0), + err: vterrors.New(vtrpcpb.Code_INVALID_ARGUMENT, "BIGINT UNSIGNED value is out of range in 0 - -9223372036854775808"), + }, { + + v1: TestValue(VarChar, "c"), + v2: NewInt64(1), + out: NewInt64(-1), + }, { + v1: NewUint64(1), + v2: TestValue(VarChar, "c"), + out: NewUint64(1), + }} + + for _, tcase := range tcases { + + got, err := Subtract(tcase.v1, tcase.v2) + + if !vterrors.Equals(err, tcase.err) { + t.Errorf("Subtract(%v, %v) error: %v, want %v", printValue(tcase.v1), printValue(tcase.v2), vterrors.Print(err), vterrors.Print(tcase.err)) + } + if tcase.err != nil { + continue + } + + if !reflect.DeepEqual(got, tcase.out) { + t.Errorf("Subtraction(%v, %v): %v, want %v", printValue(tcase.v1), printValue(tcase.v2), printValue(got), printValue(tcase.out)) + } + } + +} + func TestAdd(t *testing.T) { tcases := []struct { v1, v2 Value From 6a936d2844969fd311908cdc50fdbdaeecd83d73 Mon Sep 17 00:00:00 2001 From: Jon Tirsen Date: Tue, 27 Aug 2019 09:44:35 +1000 Subject: [PATCH 014/425] Test to prove we're using the target for routing Signed-off-by: Jon Tirsen --- go/vt/vtgate/mysql_protocol_test.go | 37 +++++++++++++++++++++-------- 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/go/vt/vtgate/mysql_protocol_test.go b/go/vt/vtgate/mysql_protocol_test.go index 00f4990e164..5d9f6ddc2c4 100644 --- a/go/vt/vtgate/mysql_protocol_test.go +++ b/go/vt/vtgate/mysql_protocol_test.go @@ -23,6 +23,7 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "golang.org/x/net/context" @@ -105,22 +106,38 @@ func TestMySQLProtocolExecuteUseStatement(t *testing.T) { } defer c.Close() - qr, err := c.ExecuteFetch("show vitess_target", 1, false) - if err != nil { - t.Error(err) - } + qr, err := c.ExecuteFetch("select id from t1", 10, true /* wantfields */) + require.NoError(t, err) + require.Equal(t, sandboxconn.SingleRowResult, qr) + + qr, err = c.ExecuteFetch("show vitess_target", 1, false) + require.NoError(t, err) assert.Equal(t, "VARCHAR(\"@master\")", qr.Rows[0][0].String()) _, err = c.ExecuteFetch("use TestUnsharded", 0, false) - if err != nil { - t.Error(err) - } + require.NoError(t, err) + + qr, err = c.ExecuteFetch("select id from t1", 10, true /* wantfields */) + require.NoError(t, err) + assert.Equal(t, sandboxconn.SingleRowResult, qr) + // No such keyspace this will fail + _, err = c.ExecuteFetch("use InvalidKeyspace", 0, false) + require.Error(t, err) + assert.Contains(t, err.Error(), "invalid keyspace provided: InvalidKeyspace") + + // That doesn't reset the vitess_target qr, err = c.ExecuteFetch("show vitess_target", 1, false) - if err != nil { - t.Error(err) - } + require.NoError(t, err) assert.Equal(t, "VARCHAR(\"TestUnsharded\")", qr.Rows[0][0].String()) + + _, err = c.ExecuteFetch("use @replica", 0, false) + require.NoError(t, err) + + // No replica tablets, this should also fail + qr, err = c.ExecuteFetch("select id from t1", 10, true /* wantfields */) + require.Error(t, err) + assert.Contains(t, err.Error(), "no valid tablet") } func TestMysqlProtocolInvalidDB(t *testing.T) { From d570b99a14503fb8882048c3bf8781104d26a07c Mon Sep 17 00:00:00 2001 From: Michael Demmer Date: Mon, 26 Aug 2019 20:49:14 -0700 Subject: [PATCH 015/425] support more expression types in vtexplain Rework the vtexplain simulated mysql to handle more expression types when calculating fake column results based on inferences off the select expression. Also change the engine so that it logs an error instead of failing outright, since the column values aren't always needed for it to effectively simulate a query. Signed-off-by: Michael Demmer --- .../multi-output/selectsharded-output.txt | 35 ++++++++ .../testdata/selectsharded-queries.sql | 12 ++- go/vt/vtexplain/vtexplain_vttablet.go | 79 +++++++++++-------- 3 files changed, 91 insertions(+), 35 deletions(-) diff --git a/go/vt/vtexplain/testdata/multi-output/selectsharded-output.txt b/go/vt/vtexplain/testdata/multi-output/selectsharded-output.txt index 6f458bdd8b5..198307bed3a 100644 --- a/go/vt/vtexplain/testdata/multi-output/selectsharded-output.txt +++ b/go/vt/vtexplain/testdata/multi-output/selectsharded-output.txt @@ -126,3 +126,38 @@ select * from name_info order by info /* select * and order by varchar column */ 1 ks_sharded/c0-: select name, info, weight_string(info) from name_info order by info asc limit 10001 /* select * and order by varchar column */ ---------------------------------------------------------------------- +select distinct(name) from user where id = 1 /* select distinct */ + +1 ks_sharded/-40: select distinct (name) from user where id = 1 limit 10001 /* select distinct */ + +---------------------------------------------------------------------- +select distinct name from user where id = 1 /* select distinct */ + +1 ks_sharded/-40: select distinct name from user where id = 1 limit 10001 /* select distinct */ + +---------------------------------------------------------------------- +select id, substring(name, 1, -1) from user where id = 123 /* select substring */ + +1 ks_sharded/-40: select id, substr(name, 1, -1) from user where id = 123 limit 10001 /* select substring */ + +---------------------------------------------------------------------- +select id, substring_index(name, '123456', -1) from user where id = 123 /* select substring_index */ + +1 ks_sharded/-40: select id, substring_index(name, '123456', -1) from user where id = 123 limit 10001 /* select substring_index */ + +---------------------------------------------------------------------- +select id, case when name = 'alice' then 'ALICE' when name = 'bob' then 'BOB' end as name from user where id = 1 /* select case */ + +1 ks_sharded/-40: select id, case when name = 'alice' then 'ALICE' when name = 'bob' then 'BOB' end as name from user where id = 1 limit 10001 /* select case */ + +---------------------------------------------------------------------- +select id, case when name = 'alice' then 'ALICE' when name = 'bob' then 'BOB' else 'OTHER' end as name from user where id = 1 /* select case */ + +1 ks_sharded/-40: select id, case when name = 'alice' then 'ALICE' when name = 'bob' then 'BOB' else 'OTHER' end as name from user where id = 1 limit 10001 /* select case */ + +---------------------------------------------------------------------- +select id, case when substr(name, 1, 5) = 'alice' then 'ALICE' when name = 'bob' then 'BOB' else 'OTHER' end as name from user where id = 1 /* select case */ + +1 ks_sharded/-40: select id, case when substr(name, 1, 5) = 'alice' then 'ALICE' when name = 'bob' then 'BOB' else 'OTHER' end as name from user where id = 1 limit 10001 /* select case */ + +---------------------------------------------------------------------- diff --git a/go/vt/vtexplain/testdata/selectsharded-queries.sql b/go/vt/vtexplain/testdata/selectsharded-queries.sql index a51570ca833..6c3f7476f04 100644 --- a/go/vt/vtexplain/testdata/selectsharded-queries.sql +++ b/go/vt/vtexplain/testdata/selectsharded-queries.sql @@ -19,4 +19,14 @@ select name from user where id in (select id from t1) /* non-correlated subquery select name from user where id not in (select id from t1) /* non-correlated subquery in NOT IN clause */; select name from user where exists (select id from t1) /* non-correlated subquery as EXISTS */; -select * from name_info order by info /* select * and order by varchar column */ +select * from name_info order by info /* select * and order by varchar column */; + +select distinct(name) from user where id = 1 /* select distinct */; +select distinct name from user where id = 1 /* select distinct */; + +select id, substring(name, 1, -1) from user where id = 123 /* select substring */; +select id, substring_index(name, '123456', -1) from user where id = 123 /* select substring_index */; + +select id, case when name = 'alice' then 'ALICE' when name = 'bob' then 'BOB' end as name from user where id = 1 /* select case */; +select id, case when name = 'alice' then 'ALICE' when name = 'bob' then 'BOB' else 'OTHER' end as name from user where id = 1 /* select case */; +select id, case when substr(name, 1, 5) = 'alice' then 'ALICE' when name = 'bob' then 'BOB' else 'OTHER' end as name from user where id = 1 /* select case */; diff --git a/go/vt/vtexplain/vtexplain_vttablet.go b/go/vt/vtexplain/vtexplain_vttablet.go index 7c00864f2c8..e45a822d375 100644 --- a/go/vt/vtexplain/vtexplain_vttablet.go +++ b/go/vt/vtexplain/vtexplain_vttablet.go @@ -19,6 +19,7 @@ package vtexplain import ( "encoding/json" "fmt" + "reflect" "strings" "sync" @@ -531,40 +532,7 @@ func (t *explainTablet) HandleQuery(c *mysql.Conn, query string, callback func(* for _, node := range selStmt.SelectExprs { switch node := node.(type) { case *sqlparser.AliasedExpr: - switch node := node.Expr.(type) { - case *sqlparser.ColName: - col := strings.ToLower(node.Name.String()) - colType := colTypeMap[col] - if colType == querypb.Type_NULL_TYPE { - return fmt.Errorf("invalid column %s", col) - } - colNames = append(colNames, col) - colTypes = append(colTypes, colType) - case *sqlparser.FuncExpr: - // As a shortcut, functions are integral types - colNames = append(colNames, sqlparser.String(node)) - colTypes = append(colTypes, querypb.Type_INT32) - case *sqlparser.SQLVal: - colNames = append(colNames, sqlparser.String(node)) - switch node.Type { - case sqlparser.IntVal: - fallthrough - case sqlparser.HexNum: - fallthrough - case sqlparser.HexVal: - fallthrough - case sqlparser.BitVal: - colTypes = append(colTypes, querypb.Type_INT32) - case sqlparser.StrVal: - colTypes = append(colTypes, querypb.Type_VARCHAR) - case sqlparser.FloatVal: - colTypes = append(colTypes, querypb.Type_FLOAT64) - default: - return fmt.Errorf("unsupported sql value %s", sqlparser.String(node)) - } - default: - return fmt.Errorf("unsupported select expression %s", sqlparser.String(node)) - } + colNames, colTypes = inferColTypeFromExpr(node.Expr, colTypeMap, colNames, colTypes) case *sqlparser.StarExpr: for col, colType := range colTypeMap { colNames = append(colNames, col) @@ -615,3 +583,46 @@ func (t *explainTablet) HandleQuery(c *mysql.Conn, query string, callback func(* return callback(result) } + +func inferColTypeFromExpr(node sqlparser.Expr, colTypeMap map[string]querypb.Type, colNames []string, colTypes []querypb.Type) ([]string, []querypb.Type) { + switch node := node.(type) { + case *sqlparser.ColName: + col := strings.ToLower(node.Name.String()) + colType := colTypeMap[col] + if colType == querypb.Type_NULL_TYPE { + log.Errorf("vtexplain: invalid column %s, typeMap +%v", col, colTypeMap) + } + colNames = append(colNames, col) + colTypes = append(colTypes, colType) + case *sqlparser.FuncExpr: + // As a shortcut, functions are integral types + colNames = append(colNames, sqlparser.String(node)) + colTypes = append(colTypes, querypb.Type_INT32) + case *sqlparser.SQLVal: + colNames = append(colNames, sqlparser.String(node)) + switch node.Type { + case sqlparser.IntVal: + fallthrough + case sqlparser.HexNum: + fallthrough + case sqlparser.HexVal: + fallthrough + case sqlparser.BitVal: + colTypes = append(colTypes, querypb.Type_INT32) + case sqlparser.StrVal: + colTypes = append(colTypes, querypb.Type_VARCHAR) + case sqlparser.FloatVal: + colTypes = append(colTypes, querypb.Type_FLOAT64) + default: + log.Errorf("vtexplain: unsupported sql value %s", sqlparser.String(node)) + } + case *sqlparser.ParenExpr: + colNames, colTypes = inferColTypeFromExpr(node.Expr, colTypeMap, colNames, colTypes) + case *sqlparser.CaseExpr: + colNames, colTypes = inferColTypeFromExpr(node.Whens[0].Val, colTypeMap, colNames, colTypes) + default: + log.Errorf("vtexplain: unsupported select expression type +%v node %s", reflect.TypeOf(node), sqlparser.String(node)) + } + + return colNames, colTypes +} From 8de216c8037e25bae680999f7e3fd75e78a28852 Mon Sep 17 00:00:00 2001 From: Michael Demmer Date: Tue, 27 Aug 2019 10:24:28 -0700 Subject: [PATCH 016/425] add vtexplain support for union statements Signed-off-by: Michael Demmer --- .../testdata/multi-output/selectsharded-output.txt | 5 +++++ go/vt/vtexplain/testdata/selectsharded-queries.sql | 2 ++ go/vt/vtexplain/vtexplain_vttablet.go | 10 +++++++++- 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/go/vt/vtexplain/testdata/multi-output/selectsharded-output.txt b/go/vt/vtexplain/testdata/multi-output/selectsharded-output.txt index 198307bed3a..43ef9e6e108 100644 --- a/go/vt/vtexplain/testdata/multi-output/selectsharded-output.txt +++ b/go/vt/vtexplain/testdata/multi-output/selectsharded-output.txt @@ -161,3 +161,8 @@ select id, case when substr(name, 1, 5) = 'alice' then 'ALICE' when name = 'bob' 1 ks_sharded/-40: select id, case when substr(name, 1, 5) = 'alice' then 'ALICE' when name = 'bob' then 'BOB' else 'OTHER' end as name from user where id = 1 limit 10001 /* select case */ ---------------------------------------------------------------------- +select id, 'abc' as test from user where id = 1 union all select id, 'def' as test from user where id = 1 /* union all */ + +1 ks_sharded/-40: select id, 'abc' as test from user where id = 1 union all select id, 'def' as test from user where id = 1 limit 10001 /* union all */ + +---------------------------------------------------------------------- diff --git a/go/vt/vtexplain/testdata/selectsharded-queries.sql b/go/vt/vtexplain/testdata/selectsharded-queries.sql index 6c3f7476f04..ccee352396b 100644 --- a/go/vt/vtexplain/testdata/selectsharded-queries.sql +++ b/go/vt/vtexplain/testdata/selectsharded-queries.sql @@ -30,3 +30,5 @@ select id, substring_index(name, '123456', -1) from user where id = 123 /* selec select id, case when name = 'alice' then 'ALICE' when name = 'bob' then 'BOB' end as name from user where id = 1 /* select case */; select id, case when name = 'alice' then 'ALICE' when name = 'bob' then 'BOB' else 'OTHER' end as name from user where id = 1 /* select case */; select id, case when substr(name, 1, 5) = 'alice' then 'ALICE' when name = 'bob' then 'BOB' else 'OTHER' end as name from user where id = 1 /* select case */; + +select id, 'abc' as test from user where id = 1 union all select id, 'def' as test from user where id = 1 /* union all */; \ No newline at end of file diff --git a/go/vt/vtexplain/vtexplain_vttablet.go b/go/vt/vtexplain/vtexplain_vttablet.go index e45a822d375..1dc67537a8f 100644 --- a/go/vt/vtexplain/vtexplain_vttablet.go +++ b/go/vt/vtexplain/vtexplain_vttablet.go @@ -502,7 +502,15 @@ func (t *explainTablet) HandleQuery(c *mysql.Conn, query string, callback func(* return err } - selStmt := stmt.(*sqlparser.Select) + var selStmt *sqlparser.Select + switch stmt.(type) { + case *sqlparser.Select: + selStmt = stmt.(*sqlparser.Select) + case *sqlparser.Union: + selStmt = stmt.(*sqlparser.Union).Left.(*sqlparser.Select) + default: + return fmt.Errorf("vtexplain: unsupported statement type +%v", reflect.TypeOf(stmt)) + } if len(selStmt.From) != 1 { return fmt.Errorf("unsupported select with multiple from clauses") From f3ba59e6861ddb0c8d602f17b21a7c1d82624add Mon Sep 17 00:00:00 2001 From: Michael Demmer Date: Tue, 27 Aug 2019 10:27:08 -0700 Subject: [PATCH 017/425] make union all work for three or more statements Signed-off-by: Michael Demmer --- .../vtexplain/testdata/multi-output/selectsharded-output.txt | 4 ++-- go/vt/vtexplain/testdata/selectsharded-queries.sql | 2 +- go/vt/vtexplain/vtexplain_vttablet.go | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/go/vt/vtexplain/testdata/multi-output/selectsharded-output.txt b/go/vt/vtexplain/testdata/multi-output/selectsharded-output.txt index 43ef9e6e108..fa6637e58ce 100644 --- a/go/vt/vtexplain/testdata/multi-output/selectsharded-output.txt +++ b/go/vt/vtexplain/testdata/multi-output/selectsharded-output.txt @@ -161,8 +161,8 @@ select id, case when substr(name, 1, 5) = 'alice' then 'ALICE' when name = 'bob' 1 ks_sharded/-40: select id, case when substr(name, 1, 5) = 'alice' then 'ALICE' when name = 'bob' then 'BOB' else 'OTHER' end as name from user where id = 1 limit 10001 /* select case */ ---------------------------------------------------------------------- -select id, 'abc' as test from user where id = 1 union all select id, 'def' as test from user where id = 1 /* union all */ +select id, 'abc' as test from user where id = 1 union all select id, 'def' as test from user where id = 1 union all select id, 'ghi' as test from user where id = 1 /* union all */ -1 ks_sharded/-40: select id, 'abc' as test from user where id = 1 union all select id, 'def' as test from user where id = 1 limit 10001 /* union all */ +1 ks_sharded/-40: select id, 'abc' as test from user where id = 1 union all select id, 'def' as test from user where id = 1 union all select id, 'ghi' as test from user where id = 1 limit 10001 /* union all */ ---------------------------------------------------------------------- diff --git a/go/vt/vtexplain/testdata/selectsharded-queries.sql b/go/vt/vtexplain/testdata/selectsharded-queries.sql index ccee352396b..b9c42e3f05d 100644 --- a/go/vt/vtexplain/testdata/selectsharded-queries.sql +++ b/go/vt/vtexplain/testdata/selectsharded-queries.sql @@ -31,4 +31,4 @@ select id, case when name = 'alice' then 'ALICE' when name = 'bob' then 'BOB' en select id, case when name = 'alice' then 'ALICE' when name = 'bob' then 'BOB' else 'OTHER' end as name from user where id = 1 /* select case */; select id, case when substr(name, 1, 5) = 'alice' then 'ALICE' when name = 'bob' then 'BOB' else 'OTHER' end as name from user where id = 1 /* select case */; -select id, 'abc' as test from user where id = 1 union all select id, 'def' as test from user where id = 1 /* union all */; \ No newline at end of file +select id, 'abc' as test from user where id = 1 union all select id, 'def' as test from user where id = 1 union all select id, 'ghi' as test from user where id = 1 /* union all */; \ No newline at end of file diff --git a/go/vt/vtexplain/vtexplain_vttablet.go b/go/vt/vtexplain/vtexplain_vttablet.go index 1dc67537a8f..d16b94ea7e5 100644 --- a/go/vt/vtexplain/vtexplain_vttablet.go +++ b/go/vt/vtexplain/vtexplain_vttablet.go @@ -507,7 +507,7 @@ func (t *explainTablet) HandleQuery(c *mysql.Conn, query string, callback func(* case *sqlparser.Select: selStmt = stmt.(*sqlparser.Select) case *sqlparser.Union: - selStmt = stmt.(*sqlparser.Union).Left.(*sqlparser.Select) + selStmt = stmt.(*sqlparser.Union).Right.(*sqlparser.Select) default: return fmt.Errorf("vtexplain: unsupported statement type +%v", reflect.TypeOf(stmt)) } From 2c30eb41d0186bc412bed97926a44d303107d814 Mon Sep 17 00:00:00 2001 From: Rasika Kale Date: Tue, 27 Aug 2019 11:08:25 -0700 Subject: [PATCH 018/425] Fixed code coverage in arithmetic.go - Added more tests in arithmetic_test.go to fix code coverage - Added error checking into arithmetic.go - Implemented function floatMinusAny() for subtraction expression Signed-off-by: Rasika Kale --- go/sqltypes/arithmetic.go | 34 +++++++++++++++++++++++++-- go/sqltypes/arithmetic_test.go | 42 ++++++++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+), 2 deletions(-) diff --git a/go/sqltypes/arithmetic.go b/go/sqltypes/arithmetic.go index 24fe939550d..66f7b51b6e2 100644 --- a/go/sqltypes/arithmetic.go +++ b/go/sqltypes/arithmetic.go @@ -47,8 +47,14 @@ func Add(v1, v2 Value) (Value, error) { } lv1, err := newNumeric(v1) + if err != nil { + return NULL, err + } lv2, err := newNumeric(v2) + if err != nil { + return NULL, err + } lresult, err := addNumericWithError(lv1, lv2) if err != nil { @@ -65,8 +71,14 @@ func Subtract(v1, v2 Value) (Value, error) { } lv1, err := newNumeric(v1) + if err != nil { + return NULL, err + } lv2, err := newNumeric(v2) + if err != nil { + return NULL, err + } lresult, err := subtractNumericWithError(lv1, lv2) if err != nil { @@ -258,7 +270,10 @@ func ToInt64(v Value) (int64, error) { // ToFloat64 converts Value to float64. func ToFloat64(v Value) (float64, error) { - num, _ := newNumeric(v) + num, err := newNumeric(v) + if err != nil { + return 0, err + } switch num.typ { case Int64: return float64(num.ival), nil @@ -404,7 +419,7 @@ func subtractNumericWithError(v1, v2 numeric) (numeric, error) { return uintMinusUintWithError(v1.uval, v2.uval) } case Float64: - return floatPlusAny(v1.fval, v2), nil + return floatMinusAny(v1.fval, v2), nil } panic("unreachable") @@ -467,6 +482,10 @@ func uintPlusIntWithError(v1 uint64, v2 int64) (numeric, error) { return numeric{}, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "BIGINT value is out of range in %v + %v", v1, v2) } + if v1 >= math.MaxUint64 && v2 > 0 { + return numeric{}, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "BIGINT UNSIGNED value is out of range in %v + %v", v1, v2) + } + //convert to int -> uint is because for numeric operators (such as + or -) //where one of the operands is an unsigned integer, the result is unsigned by default. return uintPlusUintWithError(v1, uint64(v2)) @@ -515,6 +534,17 @@ func floatPlusAny(v1 float64, v2 numeric) numeric { return numeric{typ: Float64, fval: v1 + v2.fval} } +func floatMinusAny(v1 float64, v2 numeric) numeric { + switch v2.typ { + case Int64: + v2.fval = float64(v2.ival) + case Uint64: + v2.fval = float64(v2.uval) + } + return numeric{typ: Float64, fval: v1 - v2.fval} + +} + func castFromNumeric(v numeric, resultType querypb.Type) Value { switch { case IsSigned(resultType): diff --git a/go/sqltypes/arithmetic_test.go b/go/sqltypes/arithmetic_test.go index f3de7542051..381421bf554 100644 --- a/go/sqltypes/arithmetic_test.go +++ b/go/sqltypes/arithmetic_test.go @@ -94,6 +94,31 @@ func TestSubtract(t *testing.T) { v1: NewUint64(1), v2: TestValue(VarChar, "c"), out: NewUint64(1), + }, { + + v1: TestValue(Uint64, "1.2"), + v2: NewInt64(2), + err: vterrors.New(vtrpcpb.Code_INVALID_ARGUMENT, "strconv.ParseUint: parsing \"1.2\": invalid syntax"), + }, { + + v1: NewUint64(2), + v2: TestValue(Uint64, "1.2"), + err: vterrors.New(vtrpcpb.Code_INVALID_ARGUMENT, "strconv.ParseUint: parsing \"1.2\": invalid syntax"), + }, { + // uint64 - uint64 + v1: NewUint64(8), + v2: NewUint64(4), + out: NewUint64(4), + }, { + // testing for float subtraction: float - int + v1: NewFloat64(1.2), + v2: NewInt64(2), + out: NewFloat64(-0.8), + }, { + // testin for float subtraction: float - uint + v1: NewFloat64(1.2), + v2: NewUint64(2), + out: NewFloat64(-0.8), }} for _, tcase := range tcases { @@ -199,6 +224,20 @@ func TestAdd(t *testing.T) { v1: NewUint64(1), v2: TestValue(VarChar, "1.2"), out: NewFloat64(2.2), + }, { + + v1: TestValue(Int64, "1.2"), + v2: NewInt64(2), + err: vterrors.New(vtrpcpb.Code_INVALID_ARGUMENT, "strconv.ParseInt: parsing \"1.2\": invalid syntax"), + }, { + v1: NewInt64(2), + v2: TestValue(Int64, "1.2"), + err: vterrors.New(vtrpcpb.Code_INVALID_ARGUMENT, "strconv.ParseInt: parsing \"1.2\": invalid syntax"), + }, { + // testing for uint64 overflow with max uint64 + int value + v1: NewUint64(math.MaxUint64), + v2: NewInt64(2), + err: vterrors.New(vtrpcpb.Code_INVALID_ARGUMENT, "BIGINT UNSIGNED value is out of range in 18446744073709551615 + 2"), }} for _, tcase := range tcases { @@ -541,6 +580,9 @@ func TestToFloat64(t *testing.T) { }, { v: NewFloat64(1.2), out: 1.2, + }, { + v: TestValue(Int64, "1.2"), + err: vterrors.New(vtrpcpb.Code_INVALID_ARGUMENT, "strconv.ParseInt: parsing \"1.2\": invalid syntax"), }} for _, tcase := range tcases { got, err := ToFloat64(tcase.v) From 6ab4c17bd926ce4a2511718a9dfd19e1f49ed2ca Mon Sep 17 00:00:00 2001 From: Rasika Kale Date: Tue, 27 Aug 2019 11:29:23 -0700 Subject: [PATCH 019/425] Fixed spacing between // and comment Signed-off-by: Rasika Kale --- go/sqltypes/arithmetic.go | 10 +++------- go/sqltypes/arithmetic_test.go | 2 +- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/go/sqltypes/arithmetic.go b/go/sqltypes/arithmetic.go index 66f7b51b6e2..ef6914467e1 100644 --- a/go/sqltypes/arithmetic.go +++ b/go/sqltypes/arithmetic.go @@ -64,7 +64,7 @@ func Add(v1, v2 Value) (Value, error) { return castFromNumeric(lresult, lresult.typ), nil } -//Subtract takes two values and subtracts them +// Subtract takes two values and subtracts them func Subtract(v1, v2 Value) (Value, error) { if v1.IsNull() || v2.IsNull() { return NULL, nil @@ -486,8 +486,8 @@ func uintPlusIntWithError(v1 uint64, v2 int64) (numeric, error) { return numeric{}, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "BIGINT UNSIGNED value is out of range in %v + %v", v1, v2) } - //convert to int -> uint is because for numeric operators (such as + or -) - //where one of the operands is an unsigned integer, the result is unsigned by default. + // convert to int -> uint is because for numeric operators (such as + or -) + // where one of the operands is an unsigned integer, the result is unsigned by default. return uintPlusUintWithError(v1, uint64(v2)) } @@ -495,7 +495,6 @@ func uintMinusIntWithError(v1 uint64, v2 int64) (numeric, error) { if v1 < uint64(v2) { return numeric{}, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "BIGINT UNSIGNED value is out of range in %v - %v", v1, v2) } - return uintMinusUintWithError(v1, uint64(v2)) } @@ -503,7 +502,6 @@ func uintPlusUint(v1, v2 uint64) numeric { result := v1 + v2 if result < v2 { return numeric{typ: Float64, fval: float64(v1) + float64(v2)} - } return numeric{typ: Uint64, uval: result} } @@ -514,7 +512,6 @@ func uintPlusUintWithError(v1, v2 uint64) (numeric, error) { if result < v2 { return numeric{}, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "BIGINT UNSIGNED value is out of range in %v + %v", v1, v2) } - return numeric{typ: Uint64, uval: result}, nil } @@ -542,7 +539,6 @@ func floatMinusAny(v1 float64, v2 numeric) numeric { v2.fval = float64(v2.uval) } return numeric{typ: Float64, fval: v1 - v2.fval} - } func castFromNumeric(v numeric, resultType querypb.Type) Value { diff --git a/go/sqltypes/arithmetic_test.go b/go/sqltypes/arithmetic_test.go index 381421bf554..124cf14636f 100644 --- a/go/sqltypes/arithmetic_test.go +++ b/go/sqltypes/arithmetic_test.go @@ -36,7 +36,7 @@ func TestSubtract(t *testing.T) { err error }{{ - //All Nulls + // All Nulls v1: NULL, v2: NULL, out: NULL, From 2141b6338c95ea9ee8f3b60ae6d933449caad244 Mon Sep 17 00:00:00 2001 From: Rasika Kale Date: Tue, 27 Aug 2019 12:50:45 -0700 Subject: [PATCH 020/425] Fixed comment spacing and cleaned up code Signed-off-by: Rasika Kale --- go/sqltypes/arithmetic.go | 1 - go/sqltypes/arithmetic_test.go | 29 ++++------------------------- 2 files changed, 4 insertions(+), 26 deletions(-) diff --git a/go/sqltypes/arithmetic.go b/go/sqltypes/arithmetic.go index ef6914467e1..1b1875a579c 100644 --- a/go/sqltypes/arithmetic.go +++ b/go/sqltypes/arithmetic.go @@ -437,7 +437,6 @@ func prioritize(v1, v2 numeric) (altv1, altv2 numeric) { if v2.typ == Float64 { return v2, v1 } - } return v1, v2 } diff --git a/go/sqltypes/arithmetic_test.go b/go/sqltypes/arithmetic_test.go index 124cf14636f..98dcb8dbbaf 100644 --- a/go/sqltypes/arithmetic_test.go +++ b/go/sqltypes/arithmetic_test.go @@ -35,58 +35,48 @@ func TestSubtract(t *testing.T) { out Value err error }{{ - // All Nulls v1: NULL, v2: NULL, out: NULL, }, { - // First value null. v1: NewInt32(1), v2: NULL, out: NULL, }, { - // Second value null. v1: NULL, v2: NewInt32(1), out: NULL, }, { - // case with negative value v1: NewInt64(-1), v2: NewInt64(-2), out: NewInt64(1), }, { - // testing for int64 overflow with min negative value v1: NewInt64(math.MinInt64), v2: NewInt64(1), err: vterrors.New(vtrpcpb.Code_INVALID_ARGUMENT, "BIGINT value is out of range in -9223372036854775808 - 1"), }, { - v1: NewUint64(4), v2: NewInt64(5), err: vterrors.New(vtrpcpb.Code_INVALID_ARGUMENT, "BIGINT UNSIGNED value is out of range in 4 - 5"), }, { - v1: NewUint64(7), v2: NewInt64(5), out: NewUint64(2), }, { - v1: NewUint64(math.MaxUint64), v2: NewInt64(0), out: NewUint64(math.MaxUint64), }, { - // testing for int64 overflow v1: NewInt64(math.MinInt64), v2: NewUint64(0), err: vterrors.New(vtrpcpb.Code_INVALID_ARGUMENT, "BIGINT UNSIGNED value is out of range in 0 - -9223372036854775808"), }, { - v1: TestValue(VarChar, "c"), v2: NewInt64(1), out: NewInt64(-1), @@ -95,12 +85,12 @@ func TestSubtract(t *testing.T) { v2: TestValue(VarChar, "c"), out: NewUint64(1), }, { - + // testing for error for parsing float value to uint64 v1: TestValue(Uint64, "1.2"), v2: NewInt64(2), err: vterrors.New(vtrpcpb.Code_INVALID_ARGUMENT, "strconv.ParseUint: parsing \"1.2\": invalid syntax"), }, { - + // testing for error for parsing float value to uint64 v1: NewUint64(2), v2: TestValue(Uint64, "1.2"), err: vterrors.New(vtrpcpb.Code_INVALID_ARGUMENT, "strconv.ParseUint: parsing \"1.2\": invalid syntax"), @@ -115,7 +105,7 @@ func TestSubtract(t *testing.T) { v2: NewInt64(2), out: NewFloat64(-0.8), }, { - // testin for float subtraction: float - uint + // testing for float subtraction: float - uint v1: NewFloat64(1.2), v2: NewUint64(2), out: NewFloat64(-0.8), @@ -145,8 +135,7 @@ func TestAdd(t *testing.T) { out Value err error }{{ - - //All Nulls + // All Nulls v1: NULL, v2: NULL, out: NULL, @@ -161,24 +150,20 @@ func TestAdd(t *testing.T) { v2: NewInt32(1), out: NULL, }, { - // case with negatives v1: NewInt64(-1), v2: NewInt64(-2), out: NewInt64(-3), }, { - // testing for overflow int64 v1: NewInt64(math.MaxInt64), v2: NewUint64(2), err: vterrors.New(vtrpcpb.Code_INVALID_ARGUMENT, "BIGINT value is out of range in 2 + 9223372036854775807"), }, { - v1: NewInt64(-2), v2: NewUint64(1), out: NewUint64(math.MaxUint64), }, { - v1: NewInt64(math.MaxInt64), v2: NewInt64(-2), out: NewInt64(9223372036854775805), @@ -193,30 +178,25 @@ func TestAdd(t *testing.T) { v2: NewUint64(2), err: vterrors.New(vtrpcpb.Code_INVALID_ARGUMENT, "BIGINT UNSIGNED value is out of range in 18446744073709551615 + 2"), }, { - // int64 underflow v1: NewInt64(math.MinInt64), v2: NewInt64(-2), err: vterrors.New(vtrpcpb.Code_INVALID_ARGUMENT, "BIGINT value is out of range in -9223372036854775808 + -2"), }, { - // checking int64 max value can be returned v1: NewInt64(math.MaxInt64), v2: NewUint64(0), out: NewUint64(9223372036854775807), }, { - // testing whether uint64 max value can be returned v1: NewUint64(math.MaxUint64), v2: NewInt64(0), out: NewUint64(math.MaxUint64), }, { - v1: NewUint64(math.MaxInt64), v2: NewInt64(1), out: NewUint64(9223372036854775808), }, { - v1: NewUint64(1), v2: TestValue(VarChar, "c"), out: NewUint64(1), @@ -225,7 +205,6 @@ func TestAdd(t *testing.T) { v2: TestValue(VarChar, "1.2"), out: NewFloat64(2.2), }, { - v1: TestValue(Int64, "1.2"), v2: NewInt64(2), err: vterrors.New(vtrpcpb.Code_INVALID_ARGUMENT, "strconv.ParseInt: parsing \"1.2\": invalid syntax"), From 829f3d3891c1bad032768965458ebf61f9d273ab Mon Sep 17 00:00:00 2001 From: Rasika Kale Date: Tue, 27 Aug 2019 12:53:23 -0700 Subject: [PATCH 021/425] Fixed error print statements Signed-off-by: Rasika Kale --- go/sqltypes/arithmetic_test.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/go/sqltypes/arithmetic_test.go b/go/sqltypes/arithmetic_test.go index 98dcb8dbbaf..4c9e56beddc 100644 --- a/go/sqltypes/arithmetic_test.go +++ b/go/sqltypes/arithmetic_test.go @@ -123,7 +123,7 @@ func TestSubtract(t *testing.T) { } if !reflect.DeepEqual(got, tcase.out) { - t.Errorf("Subtraction(%v, %v): %v, want %v", printValue(tcase.v1), printValue(tcase.v2), printValue(got), printValue(tcase.out)) + t.Errorf("Subtract(%v, %v): %v, want %v", printValue(tcase.v1), printValue(tcase.v2), printValue(got), printValue(tcase.out)) } } @@ -231,7 +231,7 @@ func TestAdd(t *testing.T) { } if !reflect.DeepEqual(got, tcase.out) { - t.Errorf("Addition(%v, %v): %v, want %v", printValue(tcase.v1), printValue(tcase.v2), printValue(got), printValue(tcase.out)) + t.Errorf("Add(%v, %v): %v, want %v", printValue(tcase.v1), printValue(tcase.v2), printValue(got), printValue(tcase.out)) } } @@ -287,7 +287,7 @@ func TestNullsafeAdd(t *testing.T) { got := NullsafeAdd(tcase.v1, tcase.v2, Int64) if !reflect.DeepEqual(got, tcase.out) { - t.Errorf("Add(%v, %v): %v, want %v", printValue(tcase.v1), printValue(tcase.v2), printValue(got), printValue(tcase.out)) + t.Errorf("NullsafeAdd(%v, %v): %v, want %v", printValue(tcase.v1), printValue(tcase.v2), printValue(got), printValue(tcase.out)) } } } From 5da88874b2f9b7b42169fc72a8876e579f210e0f Mon Sep 17 00:00:00 2001 From: Rasika Kale Date: Tue, 27 Aug 2019 15:42:09 -0700 Subject: [PATCH 022/425] Implemented Multiply() along with appropricate functions in arithmetic.go - Added tests for Multiply() in arithmetic_test.go to cover code coverage - Implemented additional function floatTimesAny() to account for float values Signed-off-by: Rasika Kale --- go/sqltypes/arithmetic.go | 67 ++++++++++++++++++++++++- go/sqltypes/arithmetic_test.go | 90 ++++++++++++++++++++++++++++++++++ 2 files changed, 156 insertions(+), 1 deletion(-) diff --git a/go/sqltypes/arithmetic.go b/go/sqltypes/arithmetic.go index 1b1875a579c..c448af3263f 100644 --- a/go/sqltypes/arithmetic.go +++ b/go/sqltypes/arithmetic.go @@ -88,6 +88,28 @@ func Subtract(v1, v2 Value) (Value, error) { return castFromNumeric(lresult, lresult.typ), nil } +// Multiply takes two values and multiplies it together +func Multiply(v1, v2 Value) (Value, error) { + if v1.IsNull() || v2.IsNull() { + return NULL, nil + } + + lv1, err := newNumeric(v1) + if err != nil { + return NULL, err + } + lv2, err := newNumeric(v2) + if err != nil { + return NULL, err + } + lresult, err := multiplyNumericWithError(lv1, lv2) + if err != nil { + return NULL, err + } + + return castFromNumeric(lresult, lresult.typ), nil +} + // NullsafeAdd adds two Values in a null-safe manner. A null value // is treated as 0. If both values are null, then a null is returned. // If both values are not null, a numeric value is built @@ -403,7 +425,6 @@ func addNumericWithError(v1, v2 numeric) (numeric, error) { return floatPlusAny(v1.fval, v2), nil } panic("unreachable") - } func subtractNumericWithError(v1, v2 numeric) (numeric, error) { @@ -422,7 +443,24 @@ func subtractNumericWithError(v1, v2 numeric) (numeric, error) { return floatMinusAny(v1.fval, v2), nil } panic("unreachable") +} +func multiplyNumericWithError(v1, v2 numeric) (numeric, error) { + v1, v2 = prioritize(v1, v2) + switch v1.typ { + case Int64: + return intTimesIntWithError(v1.ival, v2.ival) + case Uint64: + switch v2.typ { + case Int64: + return uintTimesIntWithError(v1.uval, v2.ival) + case Uint64: + return uintTimesUintWithError(v1.uval, v2.uval) + } + case Float64: + return floatTimesAny(v1.fval, v2), nil + } + panic("unreachable") } // prioritize reorders the input parameters @@ -472,6 +510,15 @@ func intMinusIntWithError(v1, v2 int64) (numeric, error) { return numeric{typ: Int64, ival: result}, nil } +func intTimesIntWithError(v1, v2 int64) (numeric, error) { + result := v1 * v2 + if v1 >= math.MaxInt64 && v2 > 1 || v2 >= math.MaxInt64 && v1 > 1 || v1 <= math.MinInt64 && v2 > 1 || v2 <= math.MinInt64 && v1 > 1 { + return numeric{}, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "BIGINT value is out of range in %v * %v", v1, v2) + } + + return numeric{typ: Int64, ival: result}, nil +} + func uintPlusInt(v1 uint64, v2 int64) numeric { return uintPlusUint(v1, uint64(v2)) } @@ -497,6 +544,10 @@ func uintMinusIntWithError(v1 uint64, v2 int64) (numeric, error) { return uintMinusUintWithError(v1, uint64(v2)) } +func uintTimesIntWithError(v1 uint64, v2 int64) (numeric, error) { + return uintTimesUintWithError(v1, uint64(v2)) +} + func uintPlusUint(v1, v2 uint64) numeric { result := v1 + v2 if result < v2 { @@ -516,7 +567,11 @@ func uintPlusUintWithError(v1, v2 uint64) (numeric, error) { func uintMinusUintWithError(v1, v2 uint64) (numeric, error) { result := v1 - v2 + return numeric{typ: Uint64, uval: result}, nil +} +func uintTimesUintWithError(v1, v2 uint64) (numeric, error) { + result := v1 * v2 return numeric{typ: Uint64, uval: result}, nil } @@ -540,6 +595,16 @@ func floatMinusAny(v1 float64, v2 numeric) numeric { return numeric{typ: Float64, fval: v1 - v2.fval} } +func floatTimesAny(v1 float64, v2 numeric) numeric { + switch v2.typ { + case Int64: + v2.fval = float64(v2.ival) + case Uint64: + v2.fval = float64(v2.uval) + } + return numeric{typ: Float64, fval: v1 * v2.fval} +} + func castFromNumeric(v numeric, resultType querypb.Type) Value { switch { case IsSigned(resultType): diff --git a/go/sqltypes/arithmetic_test.go b/go/sqltypes/arithmetic_test.go index 4c9e56beddc..23d8687b0b1 100644 --- a/go/sqltypes/arithmetic_test.go +++ b/go/sqltypes/arithmetic_test.go @@ -29,6 +29,96 @@ import ( "vitess.io/vitess/go/vt/vterrors" ) +func TestMultiply(t *testing.T) { + tcases := []struct { + v1, v2 Value + out Value + err error + }{{ + + //All Nulls + v1: NULL, + v2: NULL, + out: NULL, + }, { + + // First value null. + v1: NewInt32(1), + v2: NULL, + out: NULL, + }, { + + // Second value null. + v1: NULL, + v2: NewInt32(1), + out: NULL, + }, { + + // case with negative value + v1: NewInt64(-1), + v2: NewInt64(-2), + out: NewInt64(2), + }, { + + // testing for int64 overflow with min negative value + v1: NewInt64(math.MinInt64), + v2: NewInt64(1), + out: NewInt64(math.MinInt64), + }, { + // testing for error in types + v1: TestValue(Int64, "1.2"), + v2: NewInt64(2), + err: vterrors.New(vtrpcpb.Code_INVALID_ARGUMENT, "strconv.ParseInt: parsing \"1.2\": invalid syntax"), + }, { + // testing for error in types + v1: NewInt64(2), + v2: TestValue(Int64, "1.2"), + err: vterrors.New(vtrpcpb.Code_INVALID_ARGUMENT, "strconv.ParseInt: parsing \"1.2\": invalid syntax"), + }, { + // testing for uint*int + v1: NewUint64(4), + v2: NewInt64(5), + out: NewUint64(20), + }, { + // testing for uint*uint + v1: NewUint64(1), + v2: NewUint64(2), + out: NewUint64(2), + }, { + // testing for float64*int64 + v1: TestValue(Float64, "1.2"), + v2: NewInt64(-2), + out: NewFloat64(-2.4), + }, { + // testing for float64*uint64 + v1: TestValue(Float64, "1.2"), + v2: NewUint64(2), + out: NewFloat64(2.4), + }, { + // testing for overflow of int64 + v1: NewInt64(math.MaxInt64), + v2: NewInt64(2), + err: vterrors.New(vtrpcpb.Code_INVALID_ARGUMENT, "BIGINT value is out of range in 9223372036854775807 * 2"), + }} + + for _, tcase := range tcases { + + got, err := Multiply(tcase.v1, tcase.v2) + + if !vterrors.Equals(err, tcase.err) { + t.Errorf("Multiply(%v, %v) error: %v, want %v", printValue(tcase.v1), printValue(tcase.v2), vterrors.Print(err), vterrors.Print(tcase.err)) + } + if tcase.err != nil { + continue + } + + if !reflect.DeepEqual(got, tcase.out) { + t.Errorf("Multiply(%v, %v): %v, want %v", printValue(tcase.v1), printValue(tcase.v2), printValue(got), printValue(tcase.out)) + } + } + +} + func TestSubtract(t *testing.T) { tcases := []struct { v1, v2 Value From d5fda2b25854bbb7d53cea5da4605ed169285ae9 Mon Sep 17 00:00:00 2001 From: hwdef Date: Mon, 26 Aug 2019 10:03:24 +0800 Subject: [PATCH 023/425] fix some misspell Signed-off-by: hwdef --- test/backup_only.py | 2 +- test/prepared_statement_test.py | 2 +- test/vtbackup.py | 2 +- web/vtctld2/app/plotly-latest.min.js | 2 +- web/vtctld2/src/app/status/heatmap.component.ts | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/test/backup_only.py b/test/backup_only.py index 2148409d8bd..9f8a17d44ea 100755 --- a/test/backup_only.py +++ b/test/backup_only.py @@ -286,7 +286,7 @@ def _backup_only(self, t, initial_backup=False): def test_tablet_initial_backup(self): self._test_initial_backup() - # Restore the Shard from the inital backup + # Restore the Shard from the initial backup self._init_tablets(init=False,start=False) # Restore the Tablets diff --git a/test/prepared_statement_test.py b/test/prepared_statement_test.py index 963f2550c6f..ec479e68157 100755 --- a/test/prepared_statement_test.py +++ b/test/prepared_statement_test.py @@ -51,7 +51,7 @@ "options": [ "New York Bulls", "Los Angeles Kings", - "Golden State Warriros", + "Golden State Warriors", "Huston Rocket" ], "answer": "Huston Rocket" diff --git a/test/vtbackup.py b/test/vtbackup.py index 5eeef3cf8d5..f42831ea4e0 100644 --- a/test/vtbackup.py +++ b/test/vtbackup.py @@ -134,7 +134,7 @@ def start_vtbackup(self, "-init_db_sql_file",init_db ]) - # Pass through inital_backup flag to vtbackup + # Pass through initial_backup flag to vtbackup if initial_backup: args.extend(["-initial_backup"]) diff --git a/web/vtctld2/app/plotly-latest.min.js b/web/vtctld2/app/plotly-latest.min.js index 8cfc20f8a09..47b50b69421 100644 --- a/web/vtctld2/app/plotly-latest.min.js +++ b/web/vtctld2/app/plotly-latest.min.js @@ -45,7 +45,7 @@ e.exports=function(t,e,r,a){return t="left"===r?0:"center"===r?1:"right"===r?2:n e.each(function(t){var e=t[0],n=e.height;h.setTranslate(this,0,5+a+r+n/2),r+=n}),i.height=Math.max(i.height,r)}),i.height+=10+2*a,i.width+=2*a,i.width=Math.ceil(i.width),i.height=Math.ceil(i.height),r.each(function(e){var r=e[0],n=u.select(this).select(".legendtoggle");n.call(g.setRect,0,-r.height/2,t._context.editable?0:i.width,r.height)})}else{i.width=0,i.height=0;var m=0,v=0,y=0,x=0;r.each(function(t){y=Math.max(40+t[0].width,y)}),r.each(function(t){var e=t[0],r=y,o=i.tracegroupgap||5;a+x+o+r>n.width-(n.margin.r+n.margin.l)&&(x=0,m+=v,i.height=i.height+v,v=0),h.setTranslate(this,a+x,5+a+e.height/2+m),i.width+=o+r,i.height=Math.max(i.height,e.height),x+=o+r,v=Math.max(e.height,v)}),i.width+=2*a,i.height+=10+2*a,i.width=Math.ceil(i.width),i.height=Math.ceil(i.height),r.each(function(e){var r=e[0],n=u.select(this).select(".legendtoggle");n.call(g.setRect,0,-r.height/2,t._context.editable?0:i.width,r.height)})}}function s(t){var e=t._fullLayout,r=e.legend,n="left";w.isRightAnchor(r)?n="right":w.isCenterAnchor(r)&&(n="center");var i="top";w.isBottomAnchor(r)?i="bottom":w.isMiddleAnchor(r)&&(i="middle"),f.autoMargin(t,"legend",{x:r.x,y:r.y,l:r.width*({right:1,center:.5}[n]||0),r:r.width*({left:1,center:.5}[n]||0),b:r.height*({top:1,middle:.5}[i]||0),t:r.height*({bottom:1,middle:.5}[i]||0)})}function l(t){var e=t._fullLayout,r=e.legend,n="left";w.isRightAnchor(r)?n="right":w.isCenterAnchor(r)&&(n="center"),f.autoMargin(t,"legend",{x:r.x,y:.5,l:r.width*({right:1,center:.5}[n]||0),r:r.width*({left:1,center:.5}[n]||0),b:0,t:0})}var u=t("d3"),c=t("../../plotly"),h=t("../../lib"),f=t("../../plots/plots"),d=t("../../registry"),p=t("../dragelement"),g=t("../drawing"),m=t("../color"),v=t("../../lib/svg_text_utils"),y=t("./constants"),x=t("./get_legend_data"),b=t("./style"),_=t("./helpers"),w=t("./anchor_utils");e.exports=function(t){function e(t,e){E.attr("data-scroll",e).call(h.setTranslate,0,e),S.call(g.setRect,N,t,y.scrollBarWidth,y.scrollBarHeight),k.select("rect").attr({y:v.borderwidth-e})}var r=t._fullLayout,a="legend"+r._uid;if(r._infolayer&&t.calcdata){var v=r.legend,_=r.showlegend&&x(t.calcdata,v),M=r.hiddenlabels||[];if(!r.showlegend||!_.length)return r._infolayer.selectAll(".legend").remove(),r._topdefs.select("#"+a).remove(),void f.autoMargin(t,"legend");var A=r._infolayer.selectAll("g.legend").data([0]);A.enter().append("g").attr({class:"legend","pointer-events":"all"});var k=r._topdefs.selectAll("#"+a).data([0]);k.enter().append("clipPath").attr("id",a).append("rect");var T=A.selectAll("rect.bg").data([0]);T.enter().append("rect").attr({class:"bg","shape-rendering":"crispEdges"}),T.call(m.stroke,v.bordercolor),T.call(m.fill,v.bgcolor),T.style("stroke-width",v.borderwidth+"px");var E=A.selectAll("g.scrollbox").data([0]);E.enter().append("g").attr("class","scrollbox");var S=A.selectAll("rect.scrollbar").data([0]);S.enter().append("rect").attr({class:"scrollbar",rx:20,ry:2,width:0,height:0}).call(m.fill,"#808BA4");var L=E.selectAll("g.groups").data(_);L.enter().append("g").attr("class","groups"),L.exit().remove();var z=L.selectAll("g.traces").data(h.identity);z.enter().append("g").attr("class","traces"),z.exit().remove(),z.call(b).style("opacity",function(t){var e=t[0].trace;return d.traceIs(e,"pie")?M.indexOf(t[0].label)!==-1?.5:1:"legendonly"===e.visible?.5:1}).each(function(){u.select(this).call(n,t).call(i,t)});var C=0!==A.enter().size();C&&(o(t,L,z),s(t));var I=0,P=r.width,D=0,O=r.height;o(t,L,z),v.height>O?l(t):s(t);var R=r._size,F=R.l+R.w*v.x,j=R.t+R.h*(1-v.y);w.isRightAnchor(v)?F-=v.width:w.isCenterAnchor(v)&&(F-=v.width/2),w.isBottomAnchor(v)?j-=v.height:w.isMiddleAnchor(v)&&(j-=v.height/2);var N=v.width,B=R.w;N>B?(F=R.l,N=B):(F+N>P&&(F=P-N),FV?(j=R.t,U=V):(j+U>O&&(j=O-U),jr[1])return r[1]}return i}function r(t){return t[0]}var n,i,a=t[0],o=a.trace,s=d.hasMarkers(o),u=d.hasText(o),f=d.hasLines(o);if(s||u||f){var p={},g={};s&&(p.mc=e("marker.color",r),p.mo=e("marker.opacity",c.mean,[.2,1]),p.ms=e("marker.size",c.mean,[2,16]),p.mlc=e("marker.line.color",r),p.mlw=e("marker.line.width",c.mean,[0,5]),g.marker={sizeref:1,sizemin:1,sizemode:"diameter"}),f&&(g.line={width:e("line.width",r,[0,10])}),u&&(p.tx="Aa",p.tp=e("textposition",r),p.ts=10,p.tc=e("textfont.color",r),p.tf=e("textfont.family",r)),n=[c.minExtend(a,p)],i=c.minExtend(o,g)}var m=l.select(this).select("g.legendpoints"),v=m.selectAll("path.scatterpts").data(s?n:[]);v.enter().append("path").classed("scatterpts",!0).attr("transform","translate(20,0)"),v.exit().remove(),v.call(h.pointStyle,i),s&&(n[0].mrc=3);var y=m.selectAll("g.pointtext").data(u?n:[]);y.enter().append("g").classed("pointtext",!0).append("text").attr("transform","translate(20,0)"),y.exit().remove(),y.selectAll("text").call(h.textPointStyle,i)}function a(t){var e=t[0].trace,r=e.marker||{},n=r.line||{},i=l.select(this).select("g.legendpoints").selectAll("path.legendbar").data(u.traceIs(e,"bar")?[t]:[]);i.enter().append("path").classed("legendbar",!0).attr("d","M6,6H-6V-6H6Z").attr("transform","translate(20,0)"),i.exit().remove(),i.each(function(t){var e=(t.mlw+1||n.width+1)-1,i=l.select(this);i.style("stroke-width",e+"px").call(f.fill,t.mc||r.color),e&&i.call(f.stroke,t.mlc||n.color)})}function o(t){var e=t[0].trace,r=l.select(this).select("g.legendpoints").selectAll("path.legendbox").data(u.traceIs(e,"box")&&e.visible?[t]:[]);r.enter().append("path").classed("legendbox",!0).attr("d","M6,6H-6V-6H6Z").attr("transform","translate(20,0)"),r.exit().remove(),r.each(function(t){var r=(t.lw+1||e.line.width+1)-1,n=l.select(this);n.style("stroke-width",r+"px").call(f.fill,t.fc||e.fillcolor),r&&n.call(f.stroke,t.lc||e.line.color)})}function s(t){var e=t[0].trace,r=l.select(this).select("g.legendpoints").selectAll("path.legendpie").data(u.traceIs(e,"pie")&&e.visible?[t]:[]);r.enter().append("path").classed("legendpie",!0).attr("d","M6,6H-6V-6H6Z").attr("transform","translate(20,0)"),r.exit().remove(),r.size()&&r.call(p,t[0],e)}var l=t("d3"),u=t("../../registry"),c=t("../../lib"),h=t("../drawing"),f=t("../color"),d=t("../../traces/scatter/subtypes"),p=t("../../traces/pie/style_one");e.exports=function(t){t.each(function(t){var e=l.select(this),r=e.selectAll("g.legendfill").data([t]);r.enter().append("g").classed("legendfill",!0);var n=e.selectAll("g.legendlines").data([t]);n.enter().append("g").classed("legendlines",!0);var i=e.selectAll("g.legendsymbols").data([t]);i.enter().append("g").classed("legendsymbols",!0),i.style("opacity",t[0].trace.opacity),i.selectAll("g.legendpoints").data([t]).enter().append("g").classed("legendpoints",!0)}).each(a).each(o).each(s).each(n).each(i)}},{"../../lib":633,"../../registry":739,"../../traces/pie/style_one":840,"../../traces/scatter/subtypes":866,"../color":533,"../drawing":556,d3:95}],578:[function(t,e,r){"use strict";function n(t,e){var r=e.currentTarget,n=r.getAttribute("data-attr"),i=r.getAttribute("data-val")||!0,a=t._fullLayout,o={};if("zoom"===n){for(var s,l,c="in"===i?.5:2,f=(1+c)/2,d=(1-c)/2,p=h.list(t,null,!0),g=0;g1)return n(["resetViews","toggleHover"]),o(m,r);c&&(n(["zoom3d","pan3d","orbitRotation","tableRotation"]),n(["resetCameraDefault3d","resetCameraLastSave3d"]),n(["hoverClosest3d"])),f&&(n(["zoomInGeo","zoomOutGeo","resetGeo"]),n(["hoverClosestGeo"]));var v=i(s),y=[];return((u||p)&&!v||g)&&(y=["zoom2d","pan2d"]),(u||g)&&a(l)&&(y.push("select2d"),y.push("lasso2d")),y.length&&n(y),!u&&!p||v||g||n(["zoomIn2d","zoomOut2d","autoScale2d","resetScale2d"]),u&&d?n(["toggleHover"]):p?n(["hoverClosestGl2d"]):u?n(["hoverClosestCartesian","hoverCompareCartesian"]):d&&n(["hoverClosestPie"]),o(m,r)}function i(t){for(var e=l.list({_fullLayout:t},null,!0),r=!0,n=0;n0);if(p){var g=i(e,r,l);c("x",g[0]),c("y",g[1]),a.noneOrAll(t,e,["x","y"]),c("xanchor"),c("yanchor"),a.coerceFont(c,"font",r.font);var m=c("bgcolor");c("activecolor",o.contrast(m,u.lightAmount,u.darkAmount)),c("bordercolor"),c("borderwidth")}}},{"../../lib":633,"../color":533,"./attributes":582,"./button_attributes":583,"./constants":584}],586:[function(t,e,r){"use strict";function n(t){for(var e=v.list(t,"x",!0),r=[],n=0;np&&(p=f)));return p>=d?[d,p]:void 0}}var i=t("../../lib"),a=t("../../plots/cartesian/axes"),o=t("./constants"),s=t("./helpers");e.exports=function(t){var e=t._fullLayout,r=i.filterVisible(e.shapes);if(r.length&&t._fullData.length)for(var s=0;se;a--)f(t,a).selectAll('[data-index="'+(a-1)+'"]').attr("data-index",a),i(t,a)}function c(t,e,r,n){function i(r){var n={"data-index":e,"fill-rule":"evenodd",d:p(t,L)},i=L.line.width?L.line.color:"rgba(0,0,0,0)",a=r.append("path").attr(n).style("opacity",L.opacity).call(_.stroke,i).call(_.fill,L.fillcolor).call(w.dashLine,L.line.dash,L.line.width);z&&a.call(w.setClipUrl,"clip"+t._fullLayout._uid+z),t._context.editable&&h(t,a,L,e)}var a,o;f(t,e).selectAll('[data-index="'+e+'"]').remove();var s=t.layout.shapes[e];if(s){var l={};"string"==typeof r&&r?l[r]=n:x.isPlainObject(r)&&(l=r);var u=Object.keys(l);for(a=0;aX&&n>Y&&!t.shiftKey?M.getCursor(i/r,1-a/n):"move";A(e,o),G=o.split("-")[0]}function a(e){N=b.getFromId(t,r.xref),B=b.getFromId(t,r.yref),U=T.getDataToPixel(t,N),V=T.getDataToPixel(t,B,!0),q=T.getPixelToData(t,N),H=T.getPixelToData(t,B,!0);var a="shapes["+n+"]";"path"===r.type?(F=r.path,j=a+".path"):(c=U(r.x0),h=V(r.y0),f=U(r.x1),d=V(r.y1),g=a+".x0",v=a+".y0",x=a+".x1",_=a+".y1"),cY&&(u[L]=r[P]=H(s),u[z]=r[D]=H(l)),h-c>X&&(u[C]=r[O]=q(c),u[I]=r[R]=q(h))}e.attr("d",p(t,r))}var u,c,h,f,d,g,v,x,_,w,k,E,S,L,z,C,I,P,D,O,R,F,j,N,B,U,V,q,H,G,X=10,Y=10,W={setCursor:i,element:e.node(),prepFn:a,doneFn:o},Z=W.element.getBoundingClientRect();M.init(W)}function f(t,e){var r=t._fullLayout.shapes[e],n=t._fullLayout._shapeUpperLayer;return r?"below"===r.layer&&(n="paper"===r.xref&&"paper"===r.yref?t._fullLayout._shapeLowerLayer:t._fullLayout._shapeSubplotLayer):x.log("getShapeLayer: undefined shape: index",e),n}function d(t,e,r){var n=b.getFromId(t,r.id,"x")._id,i=b.getFromId(t,r.id,"y")._id,a="below"===e.layer,o=n===e.xref||i===e.yref,s=!!r.shapelayer;return a&&o&&s}function p(t,e){var r,n,i,a,o=e.type,s=b.getFromId(t,e.xref),l=b.getFromId(t,e.yref),u=t._fullLayout._size;if(s?(r=T.shapePositionToRange(s),n=function(t){return s._offset+s.r2p(r(t,!0))}):n=function(t){return u.l+u.w*t},l?(i=T.shapePositionToRange(l),a=function(t){return l._offset+l.r2p(i(t,!0))}):a=function(t){return u.t+u.h*(1-t)},"path"===o)return s&&"date"===s.type&&(n=T.decodeDate(n)),l&&"date"===l.type&&(a=T.decodeDate(a)),g(e.path,n,a);var c=n(e.x0),h=n(e.x1),f=a(e.y0),d=a(e.y1);if("line"===o)return"M"+c+","+f+"L"+h+","+d;if("rect"===o)return"M"+c+","+f+"H"+h+"V"+d+"H"+c+"Z";var p=(c+h)/2,m=(f+d)/2,v=Math.abs(p-c),y=Math.abs(m-f),x="A"+v+","+y,_=p+v+","+m,w=p+","+(m-y);return"M"+_+x+" 0 1,1 "+w+x+" 0 0,1 "+_+"Z"}function g(t,e,r){return t.replace(k.segmentRE,function(t){var n=0,i=t.charAt(0),a=k.paramIsX[i],o=k.paramIsY[i],s=k.numParams[i],l=t.substr(1).replace(k.paramRE,function(t){return a[n]?t=e(t):o[n]&&(t=r(t)),n++,n>s&&(t="X"),t});return n>s&&(l=l.replace(/[\s,]*X.*/,""),x.log("Ignoring extra params in segment "+t)),i+l})}function m(t,e,r){return t.replace(k.segmentRE,function(t){var n=0,i=t.charAt(0),a=k.paramIsX[i],o=k.paramIsY[i],s=k.numParams[i],l=t.substr(1).replace(k.paramRE,function(t){return n>=s?t:(a[n]?t=e(t):o[n]&&(t=r(t)),n++,t)});return i+l})}var v=t("fast-isnumeric"),y=t("../../plotly"),x=t("../../lib"),b=t("../../plots/cartesian/axes"),_=t("../color"),w=t("../drawing"),M=t("../dragelement"),A=t("../../lib/setcursor"),k=t("./constants"),T=t("./helpers"),E=t("./shape_defaults"),S=t("./defaults");e.exports={draw:n,drawOne:i}},{"../../lib":633,"../../lib/setcursor":643,"../../plotly":659,"../../plots/cartesian/axes":664,"../color":533,"../dragelement":554,"../drawing":556,"./constants":596,"./defaults":597,"./helpers":599,"./shape_defaults":601,"fast-isnumeric":104}],599:[function(t,e,r){"use strict";r.rangeToShapePosition=function(t){return"log"===t.type?t.r2d:function(t){return t}},r.shapePositionToRange=function(t){return"log"===t.type?t.d2r:function(t){return t}},r.decodeDate=function(t){return function(e){return e.replace&&(e=e.replace("_"," ")),t(e)}},r.encodeDate=function(t){return function(e){return t(e).replace(" ","_")}},r.getDataToPixel=function(t,e,n){var i,a=t._fullLayout._size;if(e){var o=r.shapePositionToRange(e);i=function(t){return e._offset+e.r2p(o(t,!0))},"date"===e.type&&(i=r.decodeDate(i))}else i=n?function(t){return a.t+a.h*(1-t)}:function(t){return a.l+a.w*t};return i},r.getPixelToData=function(t,e,n){var i,a=t._fullLayout._size;if(e){var o=r.rangeToShapePosition(e);i=function(t){return o(e.p2r(t-e._offset))}}else i=n?function(t){return 1-(t-a.t)/a.h}:function(t){return(t-a.l)/a.w};return i}},{}],600:[function(t,e,r){"use strict";var n=t("./draw");e.exports={moduleType:"component",name:"shapes",layoutAttributes:t("./attributes"),supplyLayoutDefaults:t("./defaults"),calcAutorange:t("./calc_autorange"),draw:n.draw,drawOne:n.drawOne}},{"./attributes":594,"./calc_autorange":595,"./defaults":597,"./draw":598}],601:[function(t,e,r){"use strict";var n=t("../../lib"),i=t("../../plots/cartesian/axes"),a=t("./attributes"),o=t("./helpers");e.exports=function(t,e,r,s,l){function u(r,i){return n.coerce(t,e,a,r,i)}s=s||{},l=l||{};var c=u("visible",!l.itemIsNotPlainObject);if(!c)return e;u("layer"),u("opacity"),u("fillcolor"),u("line.color"),u("line.width"),u("line.dash");for(var h=t.path?"path":"rect",f=u("type",h),d=["x","y"],p=0;p<2;p++){var g=d[p],m={_fullLayout:r},v=i.coerceRef(t,e,m,g,"","paper");if("path"!==f){var y,x,b,_=.25,w=.75;"paper"!==v?(y=i.getFromId(m,v),b=o.rangeToShapePosition(y),x=o.shapePositionToRange(y)):x=b=n.identity;var M=g+"0",A=g+"1",k=t[M],T=t[A];t[M]=x(t[M],!0),t[A]=x(t[A],!0),i.coercePosition(e,m,u,v,M,_),i.coercePosition(e,m,u,v,A,w),e[M]=b(e[M]),e[A]=b(e[A]),t[M]=k,t[A]=T}}return"path"===f?u("path"):n.noneOrAll(t,e,["x0","x1","y0","y1"]),e}},{"../../lib":633,"../../plots/cartesian/axes":664,"./attributes":594,"./helpers":599}],602:[function(t,e,r){"use strict";var n=t("../../plots/font_attributes"),i=t("../../plots/pad_attributes"),a=t("../../lib/extend").extendFlat,o=t("../../lib/extend").extendDeep,s=t("../../plots/animation_attributes"),l=t("./constants"),u={_isLinkedToArray:"step",method:{valType:"enumerated",values:["restyle","relayout","animate","update"],dflt:"restyle"},args:{valType:"info_array",freeLength:!0,items:[{valType:"any"},{valType:"any"},{valType:"any"}]},label:{valType:"string"},value:{valType:"string"}};e.exports={_isLinkedToArray:"slider",visible:{valType:"boolean",dflt:!0},active:{valType:"number",min:0,dflt:0},steps:u,lenmode:{valType:"enumerated",values:["fraction","pixels"],dflt:"fraction"},len:{valType:"number",min:0,dflt:1},x:{valType:"number",min:-2,max:3,dflt:0},pad:o({},i,{},{t:{dflt:20}}),xanchor:{valType:"enumerated",values:["auto","left","center","right"],dflt:"left"},y:{valType:"number",min:-2,max:3,dflt:0},yanchor:{valType:"enumerated",values:["auto","top","middle","bottom"],dflt:"top"},transition:{duration:{valType:"number",min:0,dflt:150},easing:{valType:"enumerated",values:s.transition.easing.values,dflt:"cubic-in-out"}},currentvalue:{visible:{valType:"boolean",dflt:!0},xanchor:{valType:"enumerated",values:["left","center","right"],dflt:"left"},offset:{valType:"number",dflt:10},prefix:{valType:"string"},suffix:{valType:"string"},font:a({},n,{})},font:a({},n,{}),activebgcolor:{valType:"color",dflt:l.gripBgActiveColor},bgcolor:{valType:"color",dflt:l.railBgColor},bordercolor:{valType:"color",dflt:l.railBorderColor},borderwidth:{valType:"number",min:0,dflt:l.railBorderWidth},ticklen:{valType:"number",min:0,dflt:l.tickLength},tickcolor:{valType:"color",dflt:l.tickColor},tickwidth:{valType:"number",min:0,dflt:1},minorticklen:{valType:"number",min:0,dflt:l.minorTickLength}}},{"../../lib/extend":626,"../../plots/animation_attributes":660,"../../plots/font_attributes":684,"../../plots/pad_attributes":723,"./constants":603}],603:[function(t,e,r){"use strict";e.exports={name:"sliders",containerClassName:"slider-container",groupClassName:"slider-group",inputAreaClass:"slider-input-area",railRectClass:"slider-rail-rect",railTouchRectClass:"slider-rail-touch-rect",gripRectClass:"slider-grip-rect",tickRectClass:"slider-tick-rect",inputProxyClass:"slider-input-proxy",labelsClass:"slider-labels",labelGroupClass:"slider-label-group",labelClass:"slider-label",currentValueClass:"slider-current-value",railHeight:5,menuIndexAttrName:"slider-active-index",autoMarginIdRoot:"slider-",minWidth:30,minHeight:30,textPadX:40,fontSizeToHeight:1.3,arrowOffsetX:4,railRadius:2,railWidth:5,railBorder:4,railBorderWidth:1,railBorderColor:"#bec8d9",railBgColor:"#f8fafc",railInset:8,stepInset:10,gripRadius:10,gripWidth:20,gripHeight:20,gripBorder:20,gripBorderWidth:1,gripBorderColor:"#bec8d9",gripBgColor:"#f6f8fa",gripBgActiveColor:"#dbdde0",labelPadding:8,labelOffset:0,tickWidth:1,tickColor:"#333",tickOffset:25,tickLength:7,minorTickOffset:25,minorTickColor:"#333",minorTickLength:4,currentValuePadding:8,currentValueInset:0}},{}],604:[function(t,e,r){"use strict";function n(t,e,r){function n(r,n){return a.coerce(t,e,s,r,n)}var o=i(t,e),l=n("visible",o.length>0);if(l){n("active"),n("x"),n("y"),a.noneOrAll(t,e,["x","y"]),n("xanchor"),n("yanchor"),n("len"),n("lenmode"),n("pad.t"),n("pad.r"),n("pad.b"),n("pad.l"),a.coerceFont(n,"font",r.font);var u=n("currentvalue.visible");u&&(n("currentvalue.xanchor"),n("currentvalue.prefix"),n("currentvalue.suffix"),n("currentvalue.offset"),a.coerceFont(n,"currentvalue.font",e.font)),n("transition.duration"),n("transition.easing"),n("bgcolor"),n("activebgcolor"),n("bordercolor"),n("borderwidth"),n("ticklen"),n("tickwidth"),n("tickcolor"),n("minorticklen")}}function i(t,e){function r(t,e){return a.coerce(n,i,c,t,e)}for(var n,i,o=t.steps||[],s=e.steps=[],l=0;l0&&(o=o.transition().duration(e.transition.duration).ease(e.transition.easing)),o.attr("transform","translate("+(a-.5*L.gripWidth)+","+e.currentValueTotalHeight+")")}}function v(t,e){return t.inputAreaStart+L.stepInset+(t.inputAreaLength-2*L.stepInset)*Math.min(1,Math.max(0,e))}function y(t,e){return Math.min(1,Math.max(0,(e-L.stepInset-t.inputAreaStart)/(t.inputAreaLength-2*L.stepInset-2*t.inputAreaStart)))}function x(t,e,r){var n=t.selectAll("rect."+L.railTouchRectClass).data([0]);n.enter().append("rect").classed(L.railTouchRectClass,!0).call(d,e,t,r).style("pointer-events","all"),n.attr({width:r.inputAreaLength,height:Math.max(r.inputAreaWidth,L.tickOffset+r.ticklen+r.labelHeight)}).call(k.fill,r.bgcolor).attr("opacity",0),A.setTranslate(n,0,r.currentValueTotalHeight)}function b(t,e){var r=t.selectAll("rect."+L.railRectClass).data([0]);r.enter().append("rect").classed(L.railRectClass,!0);var n=e.inputAreaLength-2*L.railInset;r.attr({width:n,height:L.railWidth,rx:L.railRadius,ry:L.railRadius,"shape-rendering":"crispEdges"}).call(k.stroke,e.bordercolor).call(k.fill,e.bgcolor).style("stroke-width",e.borderwidth+"px"),A.setTranslate(r,L.railInset,.5*(e.inputAreaWidth-L.railWidth)+e.currentValueTotalHeight)}function _(t){for(var e=t._fullLayout._pushmargin||{},r=Object.keys(e),n=0;n0?[0]:[]);if(s.enter().append("g").classed(L.containerClassName,!0).style("cursor","ew-resize"),s.exit().remove(),s.exit().size()&&_(t),0!==r.length){var l=s.selectAll("g."+L.groupClassName).data(r,i);l.enter().append("g").classed(L.groupClassName,!0),l.exit().each(function(e){w.select(this).remove(),e._commandObserver.remove(),delete e._commandObserver,M.autoMargin(t,L.autoMarginIdRoot+e._index)});for(var u=0;u0||f<0){var d={left:[-r,0],right:[r,0],top:[0,-r],bottom:[0,r]}[x.side];e.attr("transform","translate("+d+")")}}}function p(){E=0,S=!0,L=C,M._infolayer.select("."+e).attr({"data-unformatted":L}).text(L).on("mouseover.opacity",function(){n.select(this).transition().duration(100).style("opacity",1)}).on("mouseout.opacity",function(){n.select(this).transition().duration(1e3).style("opacity",0); })}var g=r.propContainer,m=r.propName,v=r.traceIndex,y=r.dfltName,x=r.avoid||{},b=r.attributes,_=r.transform,w=r.containerGroup,M=t._fullLayout,A=g.titlefont.family,k=g.titlefont.size,T=g.titlefont.color,E=1,S=!1,L=g.title.trim();""===L&&(E=0),L.match(/Click to enter .+ title/)&&(E=.2,S=!0),w||(w=M._infolayer.selectAll(".g-"+e).data([0]),w.enter().append("g").classed("g-"+e,!0));var z=w.selectAll("text").data([0]);z.enter().append("text"),z.text(L).attr("class",e),z.attr({"data-unformatted":L}).call(h);var C="Click to enter "+y+" title";t._context.editable?(L||p(),z.call(c.makeEditable).on("edit",function(e){void 0!==v?a.restyle(t,m,e,v):a.relayout(t,m,e)}).on("cancel",function(){this.text(this.attr("data-unformatted")).call(h)}).on("input",function(t){this.text(t||" ").attr(b).selectAll("tspan.line").attr(b)})):L&&!L.match(/Click to enter .+ title/)||z.remove(),z.classed("js-placeholder",S)}},{"../../lib":633,"../../lib/svg_text_utils":647,"../../plotly":659,"../../plots/plots":724,"../color":533,"../drawing":556,d3:95,"fast-isnumeric":104}],608:[function(t,e,r){"use strict";var n=t("../../plots/font_attributes"),i=t("../color/attributes"),a=t("../../lib/extend").extendFlat,o=t("../../plots/pad_attributes"),s={_isLinkedToArray:"button",method:{valType:"enumerated",values:["restyle","relayout","animate","update"],dflt:"restyle"},args:{valType:"info_array",freeLength:!0,items:[{valType:"any"},{valType:"any"},{valType:"any"}]},label:{valType:"string",dflt:""}};e.exports={_isLinkedToArray:"updatemenu",visible:{valType:"boolean"},type:{valType:"enumerated",values:["dropdown","buttons"],dflt:"dropdown"},direction:{valType:"enumerated",values:["left","right","up","down"],dflt:"down"},active:{valType:"integer",min:-1,dflt:0},showactive:{valType:"boolean",dflt:!0},buttons:s,x:{valType:"number",min:-2,max:3,dflt:-.05},xanchor:{valType:"enumerated",values:["auto","left","center","right"],dflt:"right"},y:{valType:"number",min:-2,max:3,dflt:1},yanchor:{valType:"enumerated",values:["auto","top","middle","bottom"],dflt:"top"},pad:a({},o,{}),font:a({},n,{}),bgcolor:{valType:"color"},bordercolor:{valType:"color",dflt:i.borderLine},borderwidth:{valType:"number",min:0,dflt:1}}},{"../../lib/extend":626,"../../plots/font_attributes":684,"../../plots/pad_attributes":723,"../color/attributes":532}],609:[function(t,e,r){"use strict";e.exports={name:"updatemenus",containerClassName:"updatemenu-container",headerGroupClassName:"updatemenu-header-group",headerClassName:"updatemenu-header",headerArrowClassName:"updatemenu-header-arrow",dropdownButtonGroupClassName:"updatemenu-dropdown-button-group",dropdownButtonClassName:"updatemenu-dropdown-button",buttonClassName:"updatemenu-button",itemRectClassName:"updatemenu-item-rect",itemTextClassName:"updatemenu-item-text",menuIndexAttrName:"updatemenu-active-index",autoMarginIdRoot:"updatemenu-",blankHeaderOpts:{label:" "},minWidth:30,minHeight:30,textPadX:24,arrowPadX:16,fontSizeToHeight:1.3,rx:2,ry:2,textOffsetX:12,textOffsetY:3,arrowOffsetX:4,gapButtonHeader:5,gapButton:2,activeColor:"#F4FAFF",hoverColor:"#F4FAFF"}},{}],610:[function(t,e,r){"use strict";function n(t,e,r){function n(r,n){return a.coerce(t,e,s,r,n)}var o=i(t,e),l=n("visible",o.length>0);l&&(n("active"),n("direction"),n("type"),n("showactive"),n("x"),n("y"),a.noneOrAll(t,e,["x","y"]),n("xanchor"),n("yanchor"),n("pad.t"),n("pad.r"),n("pad.b"),n("pad.l"),a.coerceFont(n,"font",r.font),n("bgcolor",r.paper_bgcolor),n("bordercolor"),n("borderwidth"))}function i(t,e){function r(t,e){return a.coerce(n,i,c,t,e)}for(var n,i,o=t.buttons||[],s=e.buttons=[],l=0;l0?[0]:[]);if(u.enter().append("g").classed(T.containerClassName,!0).style("cursor","pointer"),u.exit().remove(),u.exit().size()&&y(t),0!==r.length){var c=u.selectAll("g."+T.headerGroupClassName).data(r,i);c.enter().append("g").classed(T.headerGroupClassName,!0);var h=u.selectAll("g."+T.dropdownButtonGroupClassName).data([0]);h.enter().append("g").classed(T.dropdownButtonGroupClassName,!0).style("pointer-events","all"),c.enter().size()&&h.call(v).attr(T.menuIndexAttrName,"-1"),c.exit().each(function(e){x.select(this).remove(),h.call(v).attr(T.menuIndexAttrName,"-1"),b.autoMargin(t,T.autoMarginIdRoot+e._index)});for(var f=0;f",nbsp:"\xa0",times:"\xd7",plusmn:"\xb1",deg:"\xb0"},unicodeToEntity:{"&":"amp","<":"lt",">":"gt",'"':"quot","'":"#x27","/":"#x2F"}}},{}],618:[function(t,e,r){"use strict";r.xmlns="http://www.w3.org/2000/xmlns/",r.svg="http://www.w3.org/2000/svg",r.xlink="http://www.w3.org/1999/xlink",r.svgAttrs={xmlns:r.svg,"xmlns:xlink":r.xlink}},{}],619:[function(t,e,r){"use strict";var n=t("./plotly");r.version="1.20.5",t("es6-promise").polyfill(),t("../build/plotcss"),t("./fonts/mathjax_config"),r.plot=n.plot,r.newPlot=n.newPlot,r.restyle=n.restyle,r.relayout=n.relayout,r.redraw=n.redraw,r.update=n.update,r.extendTraces=n.extendTraces,r.prependTraces=n.prependTraces,r.addTraces=n.addTraces,r.deleteTraces=n.deleteTraces,r.moveTraces=n.moveTraces,r.purge=n.purge,r.setPlotConfig=t("./plot_api/set_plot_config"),r.register=t("./plot_api/register"),r.toImage=t("./plot_api/to_image"),r.downloadImage=t("./snapshot/download"),r.validate=t("./plot_api/validate"),r.addFrames=n.addFrames,r.deleteFrames=n.deleteFrames,r.animate=n.animate,r.register(t("./traces/scatter")),r.register([t("./components/legend"),t("./components/annotations"),t("./components/shapes"),t("./components/images"),t("./components/updatemenus"),t("./components/sliders"),t("./components/rangeslider"),t("./components/rangeselector")]),r.Icons=t("../build/ploticon"),r.Plots=n.Plots,r.Fx=n.Fx,r.Snapshot=t("./snapshot"),r.PlotSchema=t("./plot_api/plot_schema"),r.Queue=t("./lib/queue"),r.d3=t("d3")},{"../build/plotcss":1,"../build/ploticon":2,"./components/annotations":531,"./components/images":568,"./components/legend":576,"./components/rangeselector":588,"./components/rangeslider":593,"./components/shapes":600,"./components/sliders":606,"./components/updatemenus":612,"./fonts/mathjax_config":620,"./lib/queue":641,"./plot_api/plot_schema":653,"./plot_api/register":654,"./plot_api/set_plot_config":655,"./plot_api/to_image":657,"./plot_api/validate":658,"./plotly":659,"./snapshot":744,"./snapshot/download":741,"./traces/scatter":856,d3:95,"es6-promise":101}],620:[function(t,e,r){"use strict";"undefined"!=typeof MathJax?(r.MathJax=!0,MathJax.Hub.Config({messageStyle:"none",skipStartupTypeset:!0,displayAlign:"left",tex2jax:{inlineMath:[["$","$"],["\\(","\\)"]]}}),MathJax.Hub.Configured()):r.MathJax=!1},{}],621:[function(t,e,r){"use strict";e.exports=function(t,e,r,n){Array.isArray(t)&&(e[r]=t[n])}},{}],622:[function(t,e,r){"use strict";var n=t("fast-isnumeric"),i=t("../constants/numerical").BADNUM,a=/^['"%,$#\s']+|[, ]|['"%,$#\s']+$/g;e.exports=function(t){return"string"==typeof t&&(t=t.replace(a,"")),n(t)?Number(t):i}},{"../constants/numerical":616,"fast-isnumeric":104}],623:[function(t,e,r){"use strict";var n=t("fast-isnumeric"),i=t("tinycolor2"),a=t("../components/colorscale/get_scale"),o=(Object.keys(t("../components/colorscale/scales")),t("./nested_property")),s=/^([2-9]|[1-9][0-9]+)$/;r.valObjects={data_array:{coerceFunction:function(t,e,r){Array.isArray(t)?e.set(t):void 0!==r&&e.set(r)}},enumerated:{coerceFunction:function(t,e,r,n){n.coerceNumber&&(t=+t),n.values.indexOf(t)===-1?e.set(r):e.set(t)}},boolean:{coerceFunction:function(t,e,r){t===!0||t===!1?e.set(t):e.set(r)}},number:{coerceFunction:function(t,e,r,i){!n(t)||void 0!==i.min&&ti.max?e.set(r):e.set(+t)}},integer:{coerceFunction:function(t,e,r,i){t%1||!n(t)||void 0!==i.min&&ti.max?e.set(r):e.set(+t)}},string:{coerceFunction:function(t,e,r,n){if("string"!=typeof t){var i="number"==typeof t;n.strict!==!0&&i?e.set(String(t)):e.set(r)}else n.noBlank&&!t?e.set(r):e.set(t)}},color:{coerceFunction:function(t,e,r){i(t).isValid()?e.set(t):e.set(r)}},colorscale:{coerceFunction:function(t,e,r){e.set(a(t,r))}},angle:{coerceFunction:function(t,e,r){"auto"===t?e.set("auto"):n(t)?(Math.abs(t)>180&&(t-=360*Math.round(t/360)),e.set(+t)):e.set(r)}},subplotid:{coerceFunction:function(t,e,r){var n=r.length;return"string"==typeof t&&t.substr(0,n)===r&&s.test(t.substr(n))?void e.set(t):void e.set(r)},validateFunction:function(t,e){var r=e.dflt,n=r.length;return t===r||"string"==typeof t&&!(t.substr(0,n)!==r||!s.test(t.substr(n)))}},flaglist:{coerceFunction:function(t,e,r,n){if("string"!=typeof t)return void e.set(r);if((n.extras||[]).indexOf(t)!==-1)return void e.set(t);for(var i=t.split("+"),a=0;a=d&&t<=p?t:l;if("string"!=typeof t&&"number"!=typeof t)return l;var e,n,i,o,s=String(t).trim().split(" ");if(s.length>2)return l;var u=s[0].split("-"),c=!0;""===u[0]&&(c=!1,u.splice(0,1));var g=u.length;if(g>3||3!==g&&s[1]||!g)return l;if(4===u[0].length)e=Number(u[0]);else{if(2!==u[0].length)return l;if(!c)return l;var m=(new Date).getFullYear();e=((Number(u[0])-m+70)%100+200)%100+m-70}if(!a(e))return l;var v=new Date(0,0,1);if(v.setFullYear(c?e:-e),u.length>1){if(n=Number(u[1])-1,u[1].length>2||!(n>=0&&n<=11))return l;if(v.setMonth(n),u.length>2){if(i=Number(u[2]),u[2].length>2||!(i>=1&&i<=31))return l;if(v.setDate(i),v.getDate()!==i)return l;if(s[1]){if(u=s[1].split(":"),u.length>3)return l;if(o=Number(u[0]),u[0].length>2||!u[0].length||!(o>=0&&o<=23))return l;if(v.setHours(o),v.getHours()!==o)return l;if(u.length>1)return i=v.getTime(),n=Number(u[1]),2===u[1].length&&n>=0&&n<=59?(i+=h*n,2===u.length?i:2!==u[2].split(".")[0].length?l:(t=Number(u[2]),t>=0&&t<60?i+t*f:l)):l}}}return v.getTime()},d=r.MIN_MS=r.dateTime2ms("-9999"),p=r.MAX_MS=r.dateTime2ms("9999-12-31 23:59:59.9999"),r.isDateTime=function(t){return r.dateTime2ms(t)!==l};var g=90*u,m=3*c,v=5*h;r.ms2DateTime=function(t,e){if("number"!=typeof t||!(t>=d&&t<=p))return l;e||(e=0);var r=new Date(Math.floor(t)),a=i.time.format("%Y-%m-%d")(r),o=e0&&(n.push(i),i=[])}return n.push(i),n},r.makeLine=function(t,e){var r={};return r=1===t.length?{type:"LineString",coordinates:t[0]}:{type:"MultiLineString",coordinates:t},e&&(r.trace=e),r},r.makePolygon=function(t,e){var r={};if(1===t.length)r={type:"Polygon",coordinates:t};else{for(var n=new Array(t.length),i=0;i",e))>=0;){var r=t.indexOf("",e);if(r/g,"\n")}function a(t){return t.replace(/\<.*\>/g,"")}function o(t){for(var e=u.entityToUnicode,r=0;(r=t.indexOf("&",r))>=0;){var n=t.indexOf(";",r);if(nr?Math.max(r,Math.min(e,t)):Math.max(e,Math.min(r,t))},i.bBoxIntersect=function(t,e,r){return r=r||0,t.left<=e.right+r&&e.left<=t.right+r&&t.top<=e.bottom+r&&e.top<=t.bottom+r},i.identity=function(t){return t},i.noop=function(){},i.randstr=function t(e,r,n){if(n||(n=16),void 0===r&&(r=24),r<=0)return"0";var i,a,o,s=Math.log(Math.pow(2,r))/Math.log(n),l="";for(i=2;s===1/0;i*=2)s=Math.log(Math.pow(2,r/i))/Math.log(n)*i;var u=s-Math.floor(s);for(i=0;i-1||c!==1/0&&c>=Math.pow(2,r)?t(e,r,n):l},i.OptionControl=function(t,e){t||(t={}),e||(e="opt");var r={};return r.optionList=[],r._newoption=function(n){n[e]=t,r[n.name]=n,r.optionList.push(n)},r["_"+e]=t,r},i.smooth=function(t,e){if(e=Math.round(e)||0,e<2)return t;var r,n,i,a,o=t.length,s=2*o,l=2*e-1,u=new Array(l),c=new Array(o);for(r=0;r=s&&(i-=s*Math.floor(i/s)),i<0?i=-1-i:i>=o&&(i=s-1-i),a+=t[i]*u[n];c[r]=a}return c},i.syncOrAsync=function(t,e,r){function n(){return i.syncOrAsync(t,e,r)}for(var a,o;t.length;)if(o=t.splice(0,1)[0],a=o(e),a&&a.then)return a.then(n).then(void 0,i.promiseError);return r&&r(e)},i.stripTrailingSlash=function(t){return"/"===t.substr(-1)?t.substr(0,t.length-1):t},i.noneOrAll=function(t,e,r){if(t){var n,i,a=!1,o=!0;for(n=0;n1?i+o[1]:"";if(a&&(o.length>1||s.length>4||r))for(;n.test(s);)s=s.replace(n,"$1"+a+"$2");return s+l}},{"./clean_number":622,"./coerce":623,"./dates":624,"./extend":626,"./filter_unique":627,"./filter_visible":628,"./is_array":634,"./is_plain_object":635,"./loggers":636,"./matrix":637,"./nested_property":638,"./notifier":639,"./search":642,"./stats":645,d3:95}],634:[function(t,e,r){"use strict";e.exports=function(t){return Array.isArray(t)||ArrayBuffer.isView(t)}},{}],635:[function(t,e,r){"use strict";e.exports=function(t){return window&&window.process&&window.process.versions?"[object Object]"===Object.prototype.toString.call(t):"[object Object]"===Object.prototype.toString.call(t)&&Object.getPrototypeOf(t)===Object.prototype}},{}],636:[function(t,e,r){"use strict";var n=t("../plot_api/plot_config"),i=e.exports={};i.log=function(){if(n.logging>1){for(var t=["LOG:"],e=0;e0){for(var t=["WARN:"],e=0;e0){for(var t=["ERROR:"],e=0;e=0;e--){if(n=t[e],o=!1,f(n))for(r=n.length-1;r>=0;r--)u(n[r])?o?n[r]=void 0:n.pop():o=!0;else if("object"==typeof n&&null!==n)for(a=Object.keys(n),o=!1,r=a.length-1;r>=0;r--)u(n[a[r]])&&!i(n[a[r]],a[r])?delete n[a[r]]:o=!0;if(o)return}}function u(t){return void 0===t||null===t||"object"==typeof t&&(f(t)?!t.length:!Object.keys(t).length)}function c(t,e,r){return{set:function(){throw"bad container"},get:function(){},astr:e,parts:r,obj:t}}var h=t("fast-isnumeric"),f=t("./is_array");e.exports=function(t,e){if(h(e))e=String(e);else if("string"!=typeof e||"[-1]"===e.substr(e.length-4))throw"bad property string";for(var r,i,o,s=0,l=e.split(".");sa||ns)&&(!e||!u(t))}function r(t,e){var r=t[0],l=t[1];if(ra||ls)return!1;var u,c,h,f,d,p=n.length,g=n[0][0],m=n[0][1],v=0;for(u=1;uMath.max(c,g)||l>Math.max(h,m)))if(lc||Math.abs(n(o,f))>i)return!0;return!1};i.filter=function(t,e){function r(r){t.push(r);var s=n.length,l=i;n.splice(o+1);for(var u=l+1;u1){var s=t.pop();r(s)}return{addPt:r,raw:t,filtered:n}}},{"./matrix":637}],641:[function(t,e,r){"use strict";function n(t,e){for(var r,n=[],a=0;aa.queueLength&&(t.undoQueue.queue.shift(),t.undoQueue.index--)))},o.startSequence=function(t){t.undoQueue=t.undoQueue||{index:0,queue:[],sequence:!1},t.undoQueue.sequence=!0,t.undoQueue.beginSequence=!0},o.stopSequence=function(t){t.undoQueue=t.undoQueue||{index:0,queue:[],sequence:!1},t.undoQueue.sequence=!1,t.undoQueue.beginSequence=!1},o.undo=function(t){var e,r;if(t.framework&&t.framework.isPolar)return void t.framework.undo();if(!(void 0===t.undoQueue||isNaN(t.undoQueue.index)||t.undoQueue.index<=0)){for(t.undoQueue.index--,e=t.undoQueue.queue[t.undoQueue.index],t.undoQueue.inSequence=!0,r=0;r=t.undoQueue.queue.length)){for(e=t.undoQueue.queue[t.undoQueue.index],t.undoQueue.inSequence=!0,r=0;re}function o(t,e){return t>=e}var s=t("fast-isnumeric"),l=t("./loggers");r.findBin=function(t,e,r){if(s(e.start))return r?Math.ceil((t-e.start)/e.size)-1:Math.floor((t-e.start)/e.size);var u,c,h=0,f=e.length,d=0;for(c=e[e.length-1]>=e[0]?r?n:i:r?o:a;h90&&l.log("Long binary search..."),h-1},r.sorterAsc=function(t,e){return t-e},r.sorterDes=function(t,e){return e-t},r.distinctVals=function(t){var e=t.slice();e.sort(r.sorterAsc);for(var n=e.length-1,i=e[n]-e[0]||1,a=i/(n||1)/1e4,o=[e[0]],s=0;se[s]+a&&(i=Math.min(i,e[s+1]-e[s]),o.push(e[s+1]));return{vals:o,minDiff:i}},r.roundUp=function(t,e,r){for(var n,i=0,a=e.length-1,o=0,s=r?0:1,l=r?1:0,u=r?Math.ceil:Math.floor;it.length-1)return t[t.length-1];var r=e%1;return r*t[Math.ceil(e)]+(1-r)*t[Math.floor(e)]}},{"fast-isnumeric":104}],646:[function(t,e,r){"use strict";function n(t){return t=i(t),a.str2RgbaArray(t.toRgbString())}var i=t("tinycolor2"),a=t("arraytools");e.exports=n},{arraytools:33,tinycolor2:489}],647:[function(t,e,r){"use strict";function n(t,e){return t.node().getBoundingClientRect()[e]}function i(t){return t.replace(/(<|<|<)/g,"\\lt ").replace(/(>|>|>)/g,"\\gt ")}function a(t,e,r){var n="math-output-"+f.randstr([],64),a=h.select("body").append("div").attr({id:n}).style({visibility:"hidden",position:"absolute"}).style({"font-size":e.fontSize+"px"}).text(i(t));MathJax.Hub.Queue(["Typeset",MathJax.Hub,a.node()],function(){var e=h.select("body").select("#MathJax_SVG_glyphs");if(a.select(".MathJax_SVG").empty()||!a.select("svg").node())f.log("There was an error in the tex syntax.",t),r();else{var n=a.select("svg").node().getBoundingClientRect();r(a.select(".MathJax_SVG"),e,n)}a.remove()})}function o(t,e){for(var r=t||"",n=0;n]*>)/).map(function(t){var e=t.match(/<(\/?)([^ >]*)\s*(.*)>/i),n=e&&e[2].toLowerCase(),i=g[n];if(void 0!==i){var a=e[1],o=e[3],s=o.match(/^style\s*=\s*"([^"]+)"\s*/i);if("a"===n){if(a)return"";if("href"!==o.substr(0,4).toLowerCase())return"";var u=o.substr(4).replace(/["']/g,"").replace(/=/,""),c=document.createElement("a");return c.href=u,m.indexOf(c.protocol)===-1?"":''}if("br"===n)return"
";if(a)return"sup"===n?'':"sub"===n?'':"";var h=""}return r.xml_entity_encode(t).replace(/");i>0;i=e.indexOf("
",i+1))n.push(i);var a=0;n.forEach(function(t){for(var r=t+a,n=e.slice(0,r),i="",o=n.length-1;o>=0;o--){var s=n[o].match(/<(\/?).*>/i);if(s&&"
"!==n[o]){s[1]||(i=n[o]);break}}i&&(e.splice(r+1,0,i),e.splice(r,0,""),a+=2)});var o=e.join(""),u=o.split(/
/gi);return u.length>1&&(e=u.map(function(t,e){return''+t+""})),e.join("")}function c(t,e,r){var n,i,a,o=r.horizontalAlign,s=r.verticalAlign||"top",l=t.node().getBoundingClientRect(),u=e.node().getBoundingClientRect();return i="bottom"===s?function(){return l.bottom-n.height}:"middle"===s?function(){return l.top+(l.height-n.height)/2}:function(){return l.top},a="right"===o?function(){return l.right-n.width}:"center"===o?function(){return l.left+(l.width-n.width)/2}:function(){return l.left},function(){return n=this.node().getBoundingClientRect(),this.style({top:i()-u.top+"px",left:a()-u.left+"px","z-index":1e3}),this}}var h=t("d3"),f=t("../lib"),d=t("../constants/xmlns_namespaces"),p=t("../constants/string_mappings");h.selection.prototype.appendSVG=function(t){for(var e=['',t,""].join(""),r=(new DOMParser).parseFromString(e,"application/xml"),n=r.documentElement.firstChild;n;)this.node().appendChild(this.node().ownerDocument.importNode(n,!0)),n=n.nextSibling;return r.querySelector("parsererror")?(f.log(r.querySelector("parsererror div").textContent),null):h.select(this.node().lastChild)},r.html_entity_decode=function(t){var e=h.select("body").append("div").style({display:"none"}).html(""),r=t.replace(/(&[^;]*;)/gi,function(t){return"<"===t?"<":"&rt;"===t?">":e.html(t).text()});return e.remove(),r},r.xml_entity_encode=function(t){return t.replace(/&(?!\w+;|\#[0-9]+;| \#x[0-9A-F]+;)/g,"&")},r.convertToTspans=function(t,e){function r(){d.empty()||(p=s.attr("class")+"-math",d.select("svg."+p).remove()),t.text("").style({visibility:"inherit","white-space":"pre"}),c=t.appendSVG(o),c||t.text(i),t.select("a").size()&&t.style("pointer-events","all"),e&&e.call(s)}var i=t.text(),o=u(i),s=t,l=!s.attr("data-notex")&&o.match(/([^$]*)([$]+[^$]*[$]+)([^$]*)/),c=i,d=h.select(s.node().parentNode);if(!d.empty()){var p=s.attr("class")?s.attr("class").split(" ")[0]:"text";p+="-math",d.selectAll("svg."+p).remove(),d.selectAll("g."+p+"-group").remove(),t.style({visibility:null});for(var g=t.node();g&&g.removeAttribute;g=g.parentNode)g.removeAttribute("data-bb");if(l){var m=f.getPlotDiv(s.node());(m&&m._promises||[]).push(new Promise(function(t){s.style({visibility:"hidden"});var i={fontSize:parseInt(s.style("font-size"),10)};a(l[2],i,function(i,a,o){d.selectAll("svg."+p).remove(),d.selectAll("g."+p+"-group").remove();var l=i&&i.select("svg");if(!l||!l.node())return r(),void t();var u=d.append("g").classed(p+"-group",!0).attr({"pointer-events":"none"});u.node().appendChild(l.node()),a&&a.node()&&l.node().insertBefore(a.node().cloneNode(!0),l.node().firstChild),l.attr({class:p,height:o.height,preserveAspectRatio:"xMinYMin meet"}).style({overflow:"visible","pointer-events":"none"});var c=s.style("fill")||"black";l.select("g").attr({fill:c,stroke:c});var h=n(l,"width"),f=n(l,"height"),g=+s.attr("x")-h*{start:0,middle:.5,end:1}[s.attr("text-anchor")||"start"],m=parseInt(s.style("font-size"),10)||n(s,"height"),v=-m/4;"y"===p[0]?(u.attr({transform:"rotate("+[-90,+s.attr("x"),+s.attr("y")]+") translate("+[-h/2,v-f/2]+")"}),l.attr({x:+s.attr("x"),y:+s.attr("y")})):"l"===p[0]?l.attr({x:s.attr("x"),y:v-f/2}):"a"===p[0]?l.attr({x:0,y:v}):l.attr({x:g,y:+s.attr("y")+v-f/2}),e&&e.call(s,u),t(u)})}))}else r();return t}};var g={sup:'font-size:70%" dy="-0.6em',sub:'font-size:70%" dy="0.3em',b:"font-weight:bold",i:"font-style:italic",a:"",span:"",br:"",em:"font-style:italic;font-weight:bold"},m=["http:","https:","mailto:"],v=new RegExp("]*)?/?>","g"),y=Object.keys(p.entityToUnicode).map(function(t){return{regExp:new RegExp("&"+t+";","g"),sub:p.entityToUnicode[t]}}),x=Object.keys(p.unicodeToEntity).map(function(t){return{regExp:new RegExp(t,"g"),sub:"&"+p.unicodeToEntity[t]+";"}});r.plainText=function(t){return(t||"").replace(v," ")},r.makeEditable=function(t,e,r){function n(){a(),o.style({opacity:0});var t,e=u.attr("class");t=e?"."+e.split(" ")[0]+"-math-group":"[class*=-math-group]",t&&h.select(o.node().parentNode).select(t).style({opacity:0})}function i(t){var e=t.node(),r=document.createRange();r.selectNodeContents(e);var n=window.getSelection();n.removeAllRanges(),n.addRange(r),e.focus()}function a(){var t=h.select(f.getPlotDiv(o.node())),e=t.select(".svg-container"),n=e.append("div");n.classed("plugin-editable editable",!0).style({position:"absolute","font-family":o.style("font-family")||"Arial","font-size":o.style("font-size")||12,color:r.fill||o.style("fill")||"black",opacity:1,"background-color":r.background||"transparent",outline:"#ffffff33 1px solid",margin:[-parseFloat(o.style("font-size"))/8+1,0,0,-1].join("px ")+"px",padding:"0","box-sizing":"border-box"}).attr({contenteditable:!0}).text(r.text||o.attr("data-unformatted")).call(c(o,e,r)).on("blur",function(){o.text(this.textContent).style({opacity:1});var t,e=h.select(this).attr("class");t=e?"."+e.split(" ")[0]+"-math-group":"[class*=-math-group]",t&&h.select(o.node().parentNode).select(t).style({opacity:0});var r=this.textContent;h.select(this).transition().duration(0).remove(),h.select(document).on("mouseup",null),s.edit.call(o,r)}).on("focus",function(){var t=this;h.select(document).on("mouseup",function(){return h.event.target!==t&&void(document.activeElement===n.node()&&n.node().blur())})}).on("keyup",function(){27===h.event.which?(o.style({opacity:1}),h.select(this).style({opacity:0}).on("blur",function(){return!1}).transition().remove(),s.cancel.call(o,this.textContent)):(s.input.call(o,this.textContent),h.select(this).call(c(o,e,r)))}).on("keydown",function(){13===h.event.which&&this.blur()}).call(i)}r||(r={});var o=this,s=h.dispatch("edit","input","cancel"),l=h.select(this.node()).style({"pointer-events":"all"}),u=e||l;return e&&l.style({"pointer-events":"none"}),r.immediate?n():u.on("click",n),h.rebind(this,s,"on")}},{"../constants/string_mappings":617,"../constants/xmlns_namespaces":618,"../lib":633,d3:95}],648:[function(t,e,r){"use strict";var n=e.exports={},i=t("../plots/geo/constants").locationmodeToLayer,a=t("topojson-client").feature;n.getTopojsonName=function(t){return[t.scope.replace(/ /g,"-"),"_",t.resolution.toString(),"m"].join("")},n.getTopojsonPath=function(t,e){return t+e+".json"},n.getTopojsonFeatures=function(t,e){var r=i[t.locationmode],n=e.objects[r];return a(e,n).features}},{"../plots/geo/constants":686,"topojson-client":491}],649:[function(t,e,r){"use strict";function n(t,e){for(var r=new Float32Array(e),n=0;n0&&u.log("Clearing previous rejected promises from queue."),t._promises=[]},r.cleanLayout=function(t){var e,r;t||(t={}),t.xaxis1&&(t.xaxis||(t.xaxis=t.xaxis1),delete t.xaxis1),t.yaxis1&&(t.yaxis||(t.yaxis=t.yaxis1),delete t.yaxis1);var i=h.list({_fullLayout:t});for(e=0;e3?(m.x=1.02,m.xanchor="left"):m.x<-2&&(m.x=-.02,m.xanchor="right"),m.y>3?(m.y=1.02,m.yanchor="bottom"):m.y<-2&&(m.y=-.02,m.yanchor="top")),"rotate"===t.dragmode&&(t.dragmode="orbit"),t.scene1&&(t.scene||(t.scene=t.scene1),delete t.scene1);var v=c.getSubplotIds(t,"gl3d");for(e=0;e=t.data.length||i<-t.data.length)throw new Error(r+" must be valid indices for gd.data.");if(e.indexOf(i,n+1)>-1||i>=0&&e.indexOf(-t.data.length+i)>-1||i<0&&e.indexOf(t.data.length+i)>-1)throw new Error("each index in "+r+" must be unique.")}}function l(t,e,r){if(!Array.isArray(t.data))throw new Error("gd.data must be an array.");if("undefined"==typeof e)throw new Error("currentIndices is a required argument.");if(Array.isArray(e)||(e=[e]),s(t,e,"currentIndices"),"undefined"==typeof r||Array.isArray(r)||(r=[r]),"undefined"!=typeof r&&s(t,r,"newIndices"),"undefined"!=typeof r&&e.length!==r.length)throw new Error("current and new indices must be of equal length.")}function u(t,e,r){var n,i;if(!Array.isArray(t.data))throw new Error("gd.data must be an array.");if("undefined"==typeof e)throw new Error("traces must be defined.");for(Array.isArray(e)||(e=[e]),n=0;n=0&&l1?i+o[1]:"";if(a&&(o.length>1||s.length>4||r))for(;n.test(s);)s=s.replace(n,"$1"+a+"$2");return s+l}},{"./clean_number":622,"./coerce":623,"./dates":624,"./extend":626,"./filter_unique":627,"./filter_visible":628,"./is_array":634,"./is_plain_object":635,"./loggers":636,"./matrix":637,"./nested_property":638,"./notifier":639,"./search":642,"./stats":645,d3:95}],634:[function(t,e,r){"use strict";e.exports=function(t){return Array.isArray(t)||ArrayBuffer.isView(t)}},{}],635:[function(t,e,r){"use strict";e.exports=function(t){return window&&window.process&&window.process.versions?"[object Object]"===Object.prototype.toString.call(t):"[object Object]"===Object.prototype.toString.call(t)&&Object.getPrototypeOf(t)===Object.prototype}},{}],636:[function(t,e,r){"use strict";var n=t("../plot_api/plot_config"),i=e.exports={};i.log=function(){if(n.logging>1){for(var t=["LOG:"],e=0;e0){for(var t=["WARN:"],e=0;e0){for(var t=["ERROR:"],e=0;e=0;e--){if(n=t[e],o=!1,f(n))for(r=n.length-1;r>=0;r--)u(n[r])?o?n[r]=void 0:n.pop():o=!0;else if("object"==typeof n&&null!==n)for(a=Object.keys(n),o=!1,r=a.length-1;r>=0;r--)u(n[a[r]])&&!i(n[a[r]],a[r])?delete n[a[r]]:o=!0;if(o)return}}function u(t){return void 0===t||null===t||"object"==typeof t&&(f(t)?!t.length:!Object.keys(t).length)}function c(t,e,r){return{set:function(){throw"bad container"},get:function(){},astr:e,parts:r,obj:t}}var h=t("fast-isnumeric"),f=t("./is_array");e.exports=function(t,e){if(h(e))e=String(e);else if("string"!=typeof e||"[-1]"===e.substr(e.length-4))throw"bad property string";for(var r,i,o,s=0,l=e.split(".");sa||ns)&&(!e||!u(t))}function r(t,e){var r=t[0],l=t[1];if(ra||ls)return!1;var u,c,h,f,d,p=n.length,g=n[0][0],m=n[0][1],v=0;for(u=1;uMath.max(c,g)||l>Math.max(h,m)))if(lc||Math.abs(n(o,f))>i)return!0;return!1};i.filter=function(t,e){function r(r){t.push(r);var s=n.length,l=i;n.splice(o+1);for(var u=l+1;u1){var s=t.pop();r(s)}return{addPt:r,raw:t,filtered:n}}},{"./matrix":637}],641:[function(t,e,r){"use strict";function n(t,e){for(var r,n=[],a=0;aa.queueLength&&(t.undoQueue.queue.shift(),t.undoQueue.index--)))},o.startSequence=function(t){t.undoQueue=t.undoQueue||{index:0,queue:[],sequence:!1},t.undoQueue.sequence=!0,t.undoQueue.beginSequence=!0},o.stopSequence=function(t){t.undoQueue=t.undoQueue||{index:0,queue:[],sequence:!1},t.undoQueue.sequence=!1,t.undoQueue.beginSequence=!1},o.undo=function(t){var e,r;if(t.framework&&t.framework.isPolar)return void t.framework.undo();if(!(void 0===t.undoQueue||isNaN(t.undoQueue.index)||t.undoQueue.index<=0)){for(t.undoQueue.index--,e=t.undoQueue.queue[t.undoQueue.index],t.undoQueue.inSequence=!0,r=0;r=t.undoQueue.queue.length)){for(e=t.undoQueue.queue[t.undoQueue.index],t.undoQueue.inSequence=!0,r=0;re}function o(t,e){return t>=e}var s=t("fast-isnumeric"),l=t("./loggers");r.findBin=function(t,e,r){if(s(e.start))return r?Math.ceil((t-e.start)/e.size)-1:Math.floor((t-e.start)/e.size);var u,c,h=0,f=e.length,d=0;for(c=e[e.length-1]>=e[0]?r?n:i:r?o:a;h90&&l.log("Long binary search..."),h-1},r.sorterAsc=function(t,e){return t-e},r.sorterDes=function(t,e){return e-t},r.distinctVals=function(t){var e=t.slice();e.sort(r.sorterAsc);for(var n=e.length-1,i=e[n]-e[0]||1,a=i/(n||1)/1e4,o=[e[0]],s=0;se[s]+a&&(i=Math.min(i,e[s+1]-e[s]),o.push(e[s+1]));return{vals:o,minDiff:i}},r.roundUp=function(t,e,r){for(var n,i=0,a=e.length-1,o=0,s=r?0:1,l=r?1:0,u=r?Math.ceil:Math.floor;it.length-1)return t[t.length-1];var r=e%1;return r*t[Math.ceil(e)]+(1-r)*t[Math.floor(e)]}},{"fast-isnumeric":104}],646:[function(t,e,r){"use strict";function n(t){return t=i(t),a.str2RgbaArray(t.toRgbString())}var i=t("tinycolor2"),a=t("arraytools");e.exports=n},{arraytools:33,tinycolor2:489}],647:[function(t,e,r){"use strict";function n(t,e){return t.node().getBoundingClientRect()[e]}function i(t){return t.replace(/(<|<|<)/g,"\\lt ").replace(/(>|>|>)/g,"\\gt ")}function a(t,e,r){var n="math-output-"+f.randstr([],64),a=h.select("body").append("div").attr({id:n}).style({visibility:"hidden",position:"absolute"}).style({"font-size":e.fontSize+"px"}).text(i(t));MathJax.Hub.Queue(["Typeset",MathJax.Hub,a.node()],function(){var e=h.select("body").select("#MathJax_SVG_glyphs");if(a.select(".MathJax_SVG").empty()||!a.select("svg").node())f.log("There was an error in the tex syntax.",t),r();else{var n=a.select("svg").node().getBoundingClientRect();r(a.select(".MathJax_SVG"),e,n)}a.remove()})}function o(t,e){for(var r=t||"",n=0;n]*>)/).map(function(t){var e=t.match(/<(\/?)([^ >]*)\s*(.*)>/i),n=e&&e[2].toLowerCase(),i=g[n];if(void 0!==i){var a=e[1],o=e[3],s=o.match(/^style\s*=\s*"([^"]+)"\s*/i);if("a"===n){if(a)return"
";if("href"!==o.substr(0,4).toLowerCase())return"";var u=o.substr(4).replace(/["']/g,"").replace(/=/,""),c=document.createElement("a");return c.href=u,m.indexOf(c.protocol)===-1?"":''}if("br"===n)return"
";if(a)return"sup"===n?'':"sub"===n?'':"";var h=""}return r.xml_entity_encode(t).replace(/");i>0;i=e.indexOf("
",i+1))n.push(i);var a=0;n.forEach(function(t){for(var r=t+a,n=e.slice(0,r),i="",o=n.length-1;o>=0;o--){var s=n[o].match(/<(\/?).*>/i);if(s&&"
"!==n[o]){s[1]||(i=n[o]);break}}i&&(e.splice(r+1,0,i),e.splice(r,0,""),a+=2)});var o=e.join(""),u=o.split(/
/gi);return u.length>1&&(e=u.map(function(t,e){return''+t+""})),e.join("")}function c(t,e,r){var n,i,a,o=r.horizontalAlign,s=r.verticalAlign||"top",l=t.node().getBoundingClientRect(),u=e.node().getBoundingClientRect();return i="bottom"===s?function(){return l.bottom-n.height}:"middle"===s?function(){return l.top+(l.height-n.height)/2}:function(){return l.top},a="right"===o?function(){return l.right-n.width}:"center"===o?function(){return l.left+(l.width-n.width)/2}:function(){return l.left},function(){return n=this.node().getBoundingClientRect(),this.style({top:i()-u.top+"px",left:a()-u.left+"px","z-index":1e3}),this}}var h=t("d3"),f=t("../lib"),d=t("../constants/xmlns_namespaces"),p=t("../constants/string_mappings");h.selection.prototype.appendSVG=function(t){for(var e=['',t,""].join(""),r=(new DOMParser).parseFromString(e,"application/xml"),n=r.documentElement.firstChild;n;)this.node().appendChild(this.node().ownerDocument.importNode(n,!0)),n=n.nextSibling;return r.querySelector("parsererror")?(f.log(r.querySelector("parsererror div").textContent),null):h.select(this.node().lastChild)},r.html_entity_decode=function(t){var e=h.select("body").append("div").style({display:"none"}).html(""),r=t.replace(/(&[^;]*;)/gi,function(t){return"<"===t?"<":"&rt;"===t?">":e.html(t).text()});return e.remove(),r},r.xml_entity_encode=function(t){return t.replace(/&(?!\w+;|\#[0-9]+;| \#x[0-9A-F]+;)/g,"&")},r.convertToTspans=function(t,e){function r(){d.empty()||(p=s.attr("class")+"-math",d.select("svg."+p).remove()),t.text("").style({visibility:"inherit","white-space":"pre"}),c=t.appendSVG(o),c||t.text(i),t.select("a").size()&&t.style("pointer-events","all"),e&&e.call(s)}var i=t.text(),o=u(i),s=t,l=!s.attr("data-notex")&&o.match(/([^$]*)([$]+[^$]*[$]+)([^$]*)/),c=i,d=h.select(s.node().parentNode);if(!d.empty()){var p=s.attr("class")?s.attr("class").split(" ")[0]:"text";p+="-math",d.selectAll("svg."+p).remove(),d.selectAll("g."+p+"-group").remove(),t.style({visibility:null});for(var g=t.node();g&&g.removeAttribute;g=g.parentNode)g.removeAttribute("data-bb");if(l){var m=f.getPlotDiv(s.node());(m&&m._promises||[]).push(new Promise(function(t){s.style({visibility:"hidden"});var i={fontSize:parseInt(s.style("font-size"),10)};a(l[2],i,function(i,a,o){d.selectAll("svg."+p).remove(),d.selectAll("g."+p+"-group").remove();var l=i&&i.select("svg");if(!l||!l.node())return r(),void t();var u=d.append("g").classed(p+"-group",!0).attr({"pointer-events":"none"});u.node().appendChild(l.node()),a&&a.node()&&l.node().insertBefore(a.node().cloneNode(!0),l.node().firstChild),l.attr({class:p,height:o.height,preserveAspectRatio:"xMinYMin meet"}).style({overflow:"visible","pointer-events":"none"});var c=s.style("fill")||"black";l.select("g").attr({fill:c,stroke:c});var h=n(l,"width"),f=n(l,"height"),g=+s.attr("x")-h*{start:0,middle:.5,end:1}[s.attr("text-anchor")||"start"],m=parseInt(s.style("font-size"),10)||n(s,"height"),v=-m/4;"y"===p[0]?(u.attr({transform:"rotate("+[-90,+s.attr("x"),+s.attr("y")]+") translate("+[-h/2,v-f/2]+")"}),l.attr({x:+s.attr("x"),y:+s.attr("y")})):"l"===p[0]?l.attr({x:s.attr("x"),y:v-f/2}):"a"===p[0]?l.attr({x:0,y:v}):l.attr({x:g,y:+s.attr("y")+v-f/2}),e&&e.call(s,u),t(u)})}))}else r();return t}};var g={sup:'font-size:70%" dy="-0.6em',sub:'font-size:70%" dy="0.3em',b:"font-weight:bold",i:"font-style:italic",a:"",span:"",br:"",em:"font-style:italic;font-weight:bold"},m=["http:","https:","mailto:"],v=new RegExp("]*)?/?>","g"),y=Object.keys(p.entityToUnicode).map(function(t){return{regExp:new RegExp("&"+t+";","g"),sub:p.entityToUnicode[t]}}),x=Object.keys(p.unicodeToEntity).map(function(t){return{regExp:new RegExp(t,"g"),sub:"&"+p.unicodeToEntity[t]+";"}});r.plainText=function(t){return(t||"").replace(v," ")},r.makeEditable=function(t,e,r){function n(){a(),o.style({opacity:0});var t,e=u.attr("class");t=e?"."+e.split(" ")[0]+"-math-group":"[class*=-math-group]",t&&h.select(o.node().parentNode).select(t).style({opacity:0})}function i(t){var e=t.node(),r=document.createRange();r.selectNodeContents(e);var n=window.getSelection();n.removeAllRanges(),n.addRange(r),e.focus()}function a(){var t=h.select(f.getPlotDiv(o.node())),e=t.select(".svg-container"),n=e.append("div");n.classed("plugin-editable editable",!0).style({position:"absolute","font-family":o.style("font-family")||"Arial","font-size":o.style("font-size")||12,color:r.fill||o.style("fill")||"black",opacity:1,"background-color":r.background||"transparent",outline:"#ffffff33 1px solid",margin:[-parseFloat(o.style("font-size"))/8+1,0,0,-1].join("px ")+"px",padding:"0","box-sizing":"border-box"}).attr({contenteditable:!0}).text(r.text||o.attr("data-unformatted")).call(c(o,e,r)).on("blur",function(){o.text(this.textContent).style({opacity:1});var t,e=h.select(this).attr("class");t=e?"."+e.split(" ")[0]+"-math-group":"[class*=-math-group]",t&&h.select(o.node().parentNode).select(t).style({opacity:0});var r=this.textContent;h.select(this).transition().duration(0).remove(),h.select(document).on("mouseup",null),s.edit.call(o,r)}).on("focus",function(){var t=this;h.select(document).on("mouseup",function(){return h.event.target!==t&&void(document.activeElement===n.node()&&n.node().blur())})}).on("keyup",function(){27===h.event.which?(o.style({opacity:1}),h.select(this).style({opacity:0}).on("blur",function(){return!1}).transition().remove(),s.cancel.call(o,this.textContent)):(s.input.call(o,this.textContent),h.select(this).call(c(o,e,r)))}).on("keydown",function(){13===h.event.which&&this.blur()}).call(i)}r||(r={});var o=this,s=h.dispatch("edit","input","cancel"),l=h.select(this.node()).style({"pointer-events":"all"}),u=e||l;return e&&l.style({"pointer-events":"none"}),r.immediate?n():u.on("click",n),h.rebind(this,s,"on")}},{"../constants/string_mappings":617,"../constants/xmlns_namespaces":618,"../lib":633,d3:95}],648:[function(t,e,r){"use strict";var n=e.exports={},i=t("../plots/geo/constants").locationmodeToLayer,a=t("topojson-client").feature;n.getTopojsonName=function(t){return[t.scope.replace(/ /g,"-"),"_",t.resolution.toString(),"m"].join("")},n.getTopojsonPath=function(t,e){return t+e+".json"},n.getTopojsonFeatures=function(t,e){var r=i[t.locationmode],n=e.objects[r];return a(e,n).features}},{"../plots/geo/constants":686,"topojson-client":491}],649:[function(t,e,r){"use strict";function n(t,e){for(var r=new Float32Array(e),n=0;n0&&u.log("Clearing previous rejected promises from queue."),t._promises=[]},r.cleanLayout=function(t){var e,r;t||(t={}),t.xaxis1&&(t.xaxis||(t.xaxis=t.xaxis1),delete t.xaxis1),t.yaxis1&&(t.yaxis||(t.yaxis=t.yaxis1),delete t.yaxis1);var i=h.list({_fullLayout:t});for(e=0;e3?(m.x=1.02,m.xanchor="left"):m.x<-2&&(m.x=-.02,m.xanchor="right"),m.y>3?(m.y=1.02,m.yanchor="bottom"):m.y<-2&&(m.y=-.02,m.yanchor="top")),"rotate"===t.dragmode&&(t.dragmode="orbit"),t.scene1&&(t.scene||(t.scene=t.scene1),delete t.scene1);var v=c.getSubplotIds(t,"gl3d");for(e=0;e=t.data.length||i<-t.data.length)throw new Error(r+" must be valid indices for gd.data.");if(e.indexOf(i,n+1)>-1||i>=0&&e.indexOf(-t.data.length+i)>-1||i<0&&e.indexOf(t.data.length+i)>-1)throw new Error("each index in "+r+" must be unique.")}}function l(t,e,r){if(!Array.isArray(t.data))throw new Error("gd.data must be an array.");if("undefined"==typeof e)throw new Error("currentIndices is a required argument.");if(Array.isArray(e)||(e=[e]),s(t,e,"currentIndices"),"undefined"==typeof r||Array.isArray(r)||(r=[r]),"undefined"!=typeof r&&s(t,r,"newIndices"),"undefined"!=typeof r&&e.length!==r.length)throw new Error("current and new indices must be of equal length.")}function u(t,e,r){var n,i;if(!Array.isArray(t.data))throw new Error("gd.data must be an array.");if("undefined"==typeof e)throw new Error("traces must be defined.");for(Array.isArray(e)||(e=[e]),n=0;n=0&&lC.range[0]?[1,2]:[2,1]);else{var I=C.range[0],P=C.range[1];"log"===b?(I<=0&&P<=0&&r(E+".autorange",!0),I<=0?I=P/1e6:P<=0&&(P=I/1e6),r(E+".range[0]",Math.log(I)/Math.LN10),r(E+".range[1]",Math.log(P)/Math.LN10)):(r(E+".range[0]",Math.pow(10,I)),r(E+".range[1]",Math.pow(10,P)))}else r(E+".autorange",!0)}if("reverse"===k)S.range?S.range.reverse():(r(E+".autorange",!0),S.range=[1,0]),L.autorange?d.docalc=!0:d.doplot=!0;else if("annotations"===v.parts[0]||"shapes"===v.parts[0]){var D=v.parts[1],O=v.parts[0],R=a[O]||[],F=R[D]||{};2===v.parts.length&&(null===b&&(e[m]="remove"),"add"===e[m]||x.isPlainObject(e[m])?g[m]="remove":"remove"===e[m]?D===-1?(g[O]=R,delete g[m]):g[m]=F:x.log("???",e)),!n(F,"x")&&!n(F,"y")||x.containsAny(m,["color","opacity","align","dash"])||(d.docalc=!0);var j=w.getComponentMethod(O,"drawOne");j(t,D,v.parts.slice(2).join("."),e[m]),delete e[m]}else if(M.layoutArrayContainers.indexOf(v.parts[0])!==-1||"mapbox"===v.parts[0]&&"layers"===v.parts[1])z.manageArrayContainers(v,b,g),d.doplot=!0;else{var N=String(v.parts[1]||"");0===v.parts[0].indexOf("scene")?d.doplot=!0:0===v.parts[0].indexOf("geo")?d.doplot=!0:0===v.parts[0].indexOf("ternary")?d.doplot=!0:"paper_bgcolor"===m?d.doplot=!0:!o._has("gl2d")||m.indexOf("axis")===-1&&"plot_bgcolor"!==v.parts[0]?"hiddenlabels"===m?d.docalc=!0:v.parts[0].indexOf("legend")!==-1?d.dolegend=!0:m.indexOf("title")!==-1?d.doticks=!0:v.parts[0].indexOf("bgcolor")!==-1?d.dolayoutstyle=!0:v.parts.length>1&&x.containsAny(N,["tick","exponent","grid","zeroline"])?d.doticks=!0:m.indexOf(".linewidth")!==-1&&m.indexOf("axis")!==-1?d.doticks=d.dolayoutstyle=!0:v.parts.length>1&&N.indexOf("line")!==-1?d.dolayoutstyle=!0:v.parts.length>1&&"mirror"===N?d.doticks=d.dolayoutstyle=!0:"margin.pad"===m?d.doticks=d.dolayoutstyle=!0:"margin"===v.parts[0]||"autorange"===v.parts[1]||"rangemode"===v.parts[1]||"type"===v.parts[1]||"domain"===v.parts[1]||m.match(/^(bar|box|font)/)?d.docalc=!0:["hovermode","dragmode"].indexOf(m)!==-1?d.domodebar=!0:["hovermode","dragmode","height","width","autosize"].indexOf(m)===-1&&(d.doplot=!0):d.doplot=!0,v.set(b)}}}var B=t._fullLayout.width,U=t._fullLayout.height;M.supplyDefaults(t),t.layout.autosize&&M.plotAutoSize(t,t.layout,t._fullLayout);var V=e.height||e.width||t._fullLayout.width!==B||t._fullLayout.height!==U;return V&&(d.docalc=!0),(d.doplot||d.docalc)&&(d.layoutReplot=!0),{flags:d,undoit:g,redoit:p,eventData:x.extendDeep({},p)}}function g(t){var e=m.select(t),r=t._fullLayout;if(r._container=e.selectAll(".plot-container").data([0]),r._container.enter().insert("div",":first-child").classed("plot-container",!0).classed("plotly",!0),r._paperdiv=r._container.selectAll(".svg-container").data([0]),r._paperdiv.enter().append("div").classed("svg-container",!0).style("position","relative"),r._glcontainer=r._paperdiv.selectAll(".gl-container").data([0]),r._glcontainer.enter().append("div").classed("gl-container",!0),r._geocontainer=r._paperdiv.selectAll(".geo-container").data([0]),r._geocontainer.enter().append("div").classed("geo-container",!0),r._paperdiv.selectAll(".main-svg").remove(),r._paper=r._paperdiv.insert("svg",":first-child").classed("main-svg",!0),r._toppaper=r._paperdiv.append("svg").classed("main-svg",!0),!r._uid){var n=[];m.selectAll("defs").each(function(){this.id&&n.push(this.id.split("-")[1])}),r._uid=x.randstr(n)}r._paperdiv.selectAll(".main-svg").attr(S.svgAttrs),r._defs=r._paper.append("defs").attr("id","defs-"+r._uid),r._topdefs=r._toppaper.append("defs").attr("id","topdefs-"+r._uid),r._draggers=r._paper.append("g").classed("draglayer",!0);var i=r._paper.append("g").classed("layer-below",!0);r._imageLowerLayer=i.append("g").classed("imagelayer",!0),r._shapeLowerLayer=i.append("g").classed("shapelayer",!0),r._cartesianlayer=r._paper.append("g").classed("cartesianlayer",!0),r._ternarylayer=r._paper.append("g").classed("ternarylayer",!0);var a=r._paper.append("g").classed("layer-above",!0);r._imageUpperLayer=a.append("g").classed("imagelayer",!0),r._shapeUpperLayer=a.append("g").classed("shapelayer",!0),r._pielayer=r._paper.append("g").classed("pielayer",!0),r._glimages=r._paper.append("g").classed("glimages",!0),r._geoimages=r._paper.append("g").classed("geoimages",!0),r._infolayer=r._toppaper.append("g").classed("infolayer",!0),r._zoomlayer=r._toppaper.append("g").classed("zoomlayer",!0),r._hoverlayer=r._toppaper.append("g").classed("hoverlayer",!0),t.emit("plotly_framework")}var m=t("d3"),v=t("fast-isnumeric"),y=t("../plotly"),x=t("../lib"),b=t("../lib/events"),_=t("../lib/queue"),w=t("../registry"),M=t("../plots/plots"),A=t("../plots/cartesian/graph_interact"),k=t("../plots/polar"),T=t("../components/drawing"),E=t("../components/errorbars"),S=t("../constants/xmlns_namespaces"),L=t("../lib/svg_text_utils"),z=t("./helpers"),C=t("./subroutines");y.plot=function(t,e,r,n){function o(){if(_)return y.addFrames(t,_)}function s(){for(var e=I._basePlotModules,r=0;r=s.length?s[0]:s[t]:s}function i(t){return Array.isArray(l)?t>=l.length?l[0]:l[t]:l}function a(t,e){var r=0;return function(){if(t&&++r===e)return t()}}if(t=z.getGraphDiv(t),!x.isPlotDiv(t))throw new Error("This element is not a Plotly plot: "+t+". It's likely that you've failed to create a plot before animating it. For more details, see https://plot.ly/javascript/animations/");var o=t._transitionData;o._frameQueue||(o._frameQueue=[]),r=M.supplyAnimationDefaults(r);var s=r.transition,l=r.frame;return void 0===o._frameWaitingCnt&&(o._frameWaitingCnt=0),new Promise(function(l,u){function c(){if(0!==o._frameQueue.length){for(;o._frameQueue.length;){var e=o._frameQueue.pop();e.onInterrupt&&e.onInterrupt()}t.emit("plotly_animationinterrupted",[])}}function h(e){if(0!==e.length){for(var s=0;so._timeToNext&&d()};e()}function g(t){return Array.isArray(s)?y>=s.length?t.transitionOpts=s[y]:t.transitionOpts=s[0]:t.transitionOpts=s,y++,t}var m,v,y=0,b=[],_=void 0===e||null===e,w=Array.isArray(e),A=!_&&!w&&x.isPlainObject(e);if(A)b.push({type:"object",data:g(x.extendFlat({},e))});else if(_||"string"==typeof e)for(m=0;m0&&EE)&&S.push(v);b=S}}b.length>0?h(b):(t.emit("plotly_animated"),l())})},y.addFrames=function(t,e,r){if(t=z.getGraphDiv(t),null===e||void 0===e)return Promise.resolve();if(!x.isPlotDiv(t))throw new Error("This element is not a Plotly plot: "+t+". It's likely that you've failed to create a plot before adding frames. For more details, see https://plot.ly/javascript/animations/");var n,i,a,o,s=t._transitionData._frames,l=t._transitionData._frameHash;if(!Array.isArray(e))throw new Error("addFrames failure: frameList must be an Array of frame definitions"+e);var u=s.length+2*e.length,c=[];for(n=e.length-1;n>=0;n--)c.push({frame:M.supplyFrameDefaults(e[n]),index:r&&void 0!==r[n]&&null!==r[n]?r[n]:u+n});c.sort(function(t,e){return t.index>e.index?-1:t.index=0;n--){if(i=c[n].frame,!i.name)for(;l[i.name="frame "+t._transitionData._counter++];);if(l[i.name]){for(a=0;a=0;r--)n=e[r],a.push({type:"delete",index:n}),o.unshift({type:"insert",index:n,value:i[n]});var s=M.modifyFrames,l=M.modifyFrames,u=[t,o],c=[t,a];return _&&_.add(t,s,u,l,c),M.modifyFrames(t,a)},y.purge=function(t){t=z.getGraphDiv(t);var e=t._fullLayout||{},r=t._fullData||[];return M.cleanPlot([],{},r,e),M.purge(t),b.purge(t),e._container&&e._container.remove(),delete t._context,delete t._replotPending,delete t._mouseDownTime,delete t._hmpixcount,delete t._hmlumcount,t}},{"../components/drawing":556,"../components/errorbars":562,"../constants/xmlns_namespaces":618,"../lib":633,"../lib/events":625,"../lib/queue":641,"../lib/svg_text_utils":647,"../plotly":659,"../plots/cartesian/graph_interact":671,"../plots/plots":724,"../plots/polar":727,"../registry":739,"./helpers":650,"./subroutines":656,d3:95,"fast-isnumeric":104}],652:[function(t,e,r){"use strict";function n(t,r){try{t._fullLayout._paper.style("background",r)}catch(t){e.exports.logging>0&&console.error(t)}}e.exports={staticPlot:!1,editable:!1,autosizable:!1,queueLength:0,fillFrame:!1,frameMargins:0,scrollZoom:!1,doubleClick:"reset+autosize",showTips:!0,showLink:!1,sendData:!0,linkText:"Edit chart",showSources:!1,displayModeBar:"hover",modeBarButtonsToRemove:[],modeBarButtonsToAdd:[],modeBarButtons:!1,displaylogo:!0,plotGlPixelRatio:2,setBackground:n,topojsonURL:"https://cdn.plot.ly/",mapboxAccessToken:null,logging:!1,globalTransforms:[]}},{}],653:[function(t,e,r){"use strict";function n(t){var e,r;"area"===t?(e={attributes:y},r={}):(e=f.modules[t]._module,r=e.basePlotModule);var n={};n.type=null,_(n,p),_(n,e.attributes),r.attributes&&_(n,r.attributes),n.type=t;var i={meta:e.meta||{},attributes:o(n)};if(e.layoutAttributes){var a={};_(a,e.layoutAttributes),i.layoutAttributes=o(a)}return i}function i(){var t={};return _(t,g),Object.keys(f.subplotsRegistry).forEach(function(e){var r=f.subplotsRegistry[e];if(r.layoutAttributes)if("cartesian"===r.name)c(t,r,"xaxis"),c(t,r,"yaxis");else{var n="subplot"===r.attr?r.name:r.attr;c(t,r,n)}}),t=u(t),Object.keys(f.componentsRegistry).forEach(function(e){var r=f.componentsRegistry[e];r.layoutAttributes&&(Array.isArray(r.layoutNodes)?r.layoutNodes.forEach(function(e){h(t,r,e+r.name)}):h(t,r,r.name))}),{layoutAttributes:o(t)}}function a(t){var e=f.transformsRegistry[t];return{attributes:o(e.attributes)}}function o(t){return s(t),l(t),t}function s(t){function e(t){return{valType:"string"}}function n(t,n,i){r.isValObject(t)?"data_array"===t.valType?(t.role="data",i[n+"src"]=e(n)):t.arrayOk===!0&&(i[n+"src"]=e(n)):d.isPlainObject(t)&&(t.role="object")}r.crawl(t,n)}function l(t){function e(t,e,r){if(t){var n=t[M];n&&(delete t[M],r[e]={items:{}},r[e].items[n]=t,r[e].role="object")}}r.crawl(t,e)}function u(t){return b(t,{radialaxis:x.radialaxis,angularaxis:x.angularaxis}),b(t,x.layout),t}function c(t,e,r){var n=d.nestedProperty(t,r),i=_({},e.layoutAttributes);i[w]=!0,n.set(i)}function h(t,e,r){var n=d.nestedProperty(t,r),i=_(n.get()||{},e.layoutAttributes);n.set(i)}var f=t("../registry"),d=t("../lib"),p=t("../plots/attributes"),g=t("../plots/layout_attributes"),m=t("../plots/frame_attributes"),v=t("../plots/animation_attributes"),y=t("../plots/polar/area_attributes"),x=t("../plots/polar/axis_attributes"),b=d.extendFlat,_=d.extendDeep,w="_isSubplotObj",M="_isLinkedToArray",A="_deprecated",k=[w,M,A];r.IS_SUBPLOT_OBJ=w,r.IS_LINKED_TO_ARRAY=M,r.DEPRECATED=A,r.UNDERSCORE_ATTRS=k,r.get=function(){var t={};f.allTypes.concat("area").forEach(function(e){t[e]=n(e)});var e={};return Object.keys(f.transformsRegistry).forEach(function(t){e[t]=a(t)}),{defs:{valObjects:d.valObjects,metaKeys:k.concat(["description","role"])},traces:t,layout:i(),transforms:e,frames:o(m),animation:o(v)}},r.crawl=function(t,e,n){var i=n||0;Object.keys(t).forEach(function(n){var a=t[n];k.indexOf(n)===-1&&(e(a,n,t,i),r.isValObject(a)||d.isPlainObject(a)&&r.crawl(a,e,i+1))})},r.isValObject=function(t){return t&&void 0!==t.valType},r.findArrayAttributes=function(t){function e(e,r,o,s){a=a.slice(0,s).concat([r]);var l="data_array"===e.valType||e.arrayOk===!0;if(l){var u=n(a),c=d.nestedProperty(t,u).get();Array.isArray(c)&&i.push(u)}}function n(t){return t.join(".")}var i=[],a=[];if(r.crawl(t._module.attributes,e),t.transforms)for(var o=t.transforms,s=0;s1)};f(e.width)&&f(e.height)||n(new Error("Height and width should be pixel values."));var d=l(t,{format:"png",height:e.height,width:e.width}),p=d.gd;p.style.position="absolute",p.style.left="-5000px",document.body.appendChild(p);var g=s.getRedrawFunc(p);a.plot(p,d.data,d.layout,d.config).then(g).then(h).then(function(t){r(t)}).catch(function(t){n(t)})});return r}var i=t("fast-isnumeric"),a=t("../plotly"),o=t("../lib"),s=t("../snapshot/helpers"),l=t("../snapshot/cloneplot"),u=t("../snapshot/tosvg"),c=t("../snapshot/svgtoimg");e.exports=n},{"../lib":633,"../plotly":659,"../snapshot/cloneplot":740,"../snapshot/helpers":743,"../snapshot/svgtoimg":745,"../snapshot/tosvg":747,"fast-isnumeric":104}],658:[function(t,e,r){"use strict";function n(t,e,r,i,a,u){u=u||[];for(var c=Object.keys(t),f=0;f1&&l.push(o("object","layout"))),f.supplyDefaults(u);for(var c=u._fullData,m=r.length,v=0;vc&&e10||"01-01"!==n.substr(5)?t._tickround="d":t._tickround=+e.substr(1)%12===0?"y":"m";else if(e>=z&&i<=10||e>=15*z)t._tickround="d";else if(e>=I&&i<=16||e>=C)t._tickround="M";else if(e>=P&&i<=19||e>=I)t._tickround="S";else{var a=_.ms2DateTime(r+e).replace(/^-/,"").length;t._tickround=Math.max(i,a)-20}}else if(x(e)||"L"===e.charAt(0)){var o=t.range.map(t.r2d||Number);x(e)||(e=Number(e.substr(1))),t._tickround=2-Math.floor(Math.log(e)/Math.LN10+.01);var s=Math.max(Math.abs(o[0]),Math.abs(o[1])),l=Math.floor(Math.log(s)/Math.LN10+.01);Math.abs(l)>3&&("SI"===t.exponentformat||"B"===t.exponentformat?t._tickexponent=3*Math.round((l-1)/3):t._tickexponent=l)}else t._tickround=null}function o(t,e){var r=t.match(W),n=new Date(e);if(r){var i=Math.min(+r[1]||6,6),a=String(e/1e3%1+2.0000005).substr(2,i).replace(/0+$/,"")||"0";return y.time.format(t.replace(W,a))(n)}return y.time.format(t)(n)}function s(t,e,r){var n=t.tickfont||t._gd._fullLayout.font;return{x:e,dx:0,dy:0,text:r||"",fontSize:n.size,font:n.family,fontColor:n.color}}function l(t,e,r,n){var i,a,s=e.x,l=t._tickround,u=new Date(s);r&&t.hoverformat?a=o(t.hoverformat,s):t.tickformat?a=o(t.tickformat,s):(n&&(x(l)?l+=2:l={y:"m",m:"d",d:"M",M:"S",S:2}[l]),"y"===l?a=V(u):"m"===l?a=q(u):"d"===l?(i=V(u),a=H(u)):(i=G(u),a=X(u),"M"!==l&&(a+=Y(u),"S"!==l&&(a+=f(y.round(v(s/1e3,1),4),t,"none",r).substr(1))))),(r||"array"===t.tickmode)&&("00:00:00"===a||"00:00"===a?(a=i,i=""):8===a.length&&(a=a.replace(/:00$/,""))),i&&(r?"d"===l?a+=", "+i:a=i+(a?", "+a:""):t._inCalcTicks&&i===t._prevDateHead||(a+="
"+i,t._prevDateHead=i)),e.text=a}function u(t,e,r,n,i){var a=t.dtick,o=e.x;if(!n||"string"==typeof a&&"L"===a.charAt(0)||(a="L3"),t.tickformat||"string"==typeof a&&"L"===a.charAt(0))e.text=f(Math.pow(10,o),t,i,n);else if(x(a)||"D"===a.charAt(0)&&v(o+.01,1)<.1)if(["e","E","power"].indexOf(t.exponentformat)!==-1){var s=Math.round(o);0===s?e.text=1:1===s?e.text="10":s>1?e.text="10"+s+"":e.text="10\u2212"+-s+"",e.fontSize*=1.25}else e.text=f(Math.pow(10,o),t,"","fakehover"),"D1"===a&&"y"===t._id.charAt(0)&&(e.dy-=e.fontSize/6);else{if("D"!==a.charAt(0))throw"unrecognized dtick "+String(a);e.text=String(Math.round(Math.pow(10,v(o,1)))),e.fontSize*=.75}if("D1"===t.dtick){var l=String(e.text).charAt(0);"0"!==l&&"1"!==l||("y"===t._id.charAt(0)?e.dx-=e.fontSize/4:(e.dy+=e.fontSize/2,e.dx+=(t.range[1]>t.range[0]?1:-1)*e.fontSize*(o<0?.5:.25)))}}function c(t,e){var r=t._categories[Math.round(e.x)];void 0===r&&(r=""),e.text=String(r)}function h(t,e,r,n,i){"all"===t.showexponent&&Math.abs(e.x/t.dtick)<1e-6&&(i="hide"),e.text=f(e.x,t,i,n)}function f(t,e,r,n){var i=t<0,o=e._tickround,s=r||e.exponentformat||"B",l=e._tickexponent,u=e.tickformat,c=e.separatethousands;if(n){var h={exponentformat:e.exponentformat,dtick:"none"===e.showexponent?e.dtick:x(t)?Math.abs(t)||1:1,range:"none"===e.showexponent?e.range.map(e.r2d):[0,t||1]};a(h),o=(Number(h._tickround)||0)+4,l=h._tickexponent,e.hoverformat&&(u=e.hoverformat)}if(u)return y.format(u)(t).replace(/-/g,"\u2212");var f=Math.pow(10,-o)/2;if("none"===s&&(l=0),t=Math.abs(t),t12||l<-15)?t+="e"+g:"E"===s?t+="E"+g:"power"===s?t+="\xd710"+g+"":"B"===s&&9===l?t+="B":"SI"!==s&&"B"!==s||(t+=Z[l/3+5])}return i?"\u2212"+t:t}function d(t,e){var r,n,i=[];for(r=0;r1)for(n=1;n2e-6||((r-t._forceTick0)/t._minDtick%1+1.000001)%1>2e-6)&&(t._minDtick=0)):t._minDtick=0},D.getAutoRange=function(t){var e,r=[],n=t._min[0].val,i=t._max[0].val;for(e=1;e0&&c>0&&h/c>f&&(l=o,u=s,f=h/c);if(n===i){var g=n-1,m=n+1;r="tozero"===t.rangemode?n<0?[g,0]:[0,m]:"nonnegative"===t.rangemode?[Math.max(0,g),Math.max(0,m)]:[g,m]}else f&&("linear"!==t.type&&"-"!==t.type||("tozero"===t.rangemode?(l.val>=0&&(l={val:0,pad:0}),u.val<=0&&(u={val:0,pad:0})):"nonnegative"===t.rangemode&&(l.val-f*l.pad<0&&(l={val:0,pad:0}),u.val<0&&(u={val:1,pad:0})),f=(u.val-l.val)/(t._length-l.pad-u.pad)),r=[l.val-f*l.pad,u.val+f*u.pad]);return r[0]===r[1]&&("tozero"===t.rangemode?r=r[0]<0?[r[0],0]:r[0]>0?[0,r[0]]:[0,1]:(r=[r[0]-1,r[0]+1],"nonnegative"===t.rangemode&&(r[0]=Math.max(0,r[0])))),d&&r.reverse(),r.map(t.l2r||Number)},D.doAutoRange=function(t){t._length||t.setScale();var e=t._min&&t._max&&t._min.length&&t._max.length;if(t.autorange&&e){t.range=D.getAutoRange(t);var r=t._gd.layout[t._name];r||(t._gd.layout[t._name]=r={}),r!==t&&(r.range=t.range.slice(),r.autorange=t.autorange)}},D.saveRangeInitial=function(t,e){for(var r=D.list(t,"",!0),n=!1,i=0;i=f?d=!1:s.val>=u&&s.pad<=f&&(t._min.splice(o,1),o--);d&&t._min.push({val:u,pad:y&&0===u?0:f})}if(n(c)){for(d=!0,o=0;o=c&&s.pad>=h?d=!1:s.val<=c&&s.pad<=h&&(t._max.splice(o,1),o--);d&&t._max.push({val:c,pad:y&&0===c?0:h})}}}if((t.autorange||t._needsExpand)&&e){t._min||(t._min=[]),t._max||(t._max=[]),r||(r={}),t._m||t.setScale();var a,o,s,l,u,c,h,f,d,p,g,m=e.length,v=r.padded?.05*t._length:0,y=r.tozero&&("linear"===t.type||"-"===t.type),b=n((t._m>0?r.ppadplus:r.ppadminus)||r.ppad||0),_=n((t._m>0?r.ppadminus:r.ppadplus)||r.ppad||0),w=n(r.vpadplus||r.vpad),M=n(r.vpadminus||r.vpad);for(a=0;a<6;a++)i(a);for(a=m-1;a>5;a--)i(a)}},D.autoBin=function(t,e,r,n){function i(t){return(1+100*(t-d)/h.dtick)%100<2}var a=_.aggNums(Math.min,null,t),o=_.aggNums(Math.max,null,t);if("category"===e.type)return{start:a-.5,end:o+.5,size:1};var s;if(r)s=(o-a)/r;else{var l=_.distinctVals(t),u=Math.pow(10,Math.floor(Math.log(l.minDiff)/Math.LN10)),c=u*_.roundUp(l.minDiff/u,[.9,1.9,4.9,9.9],!0);s=Math.max(c,2*_.stdev(t)/Math.pow(t.length,n?.25:.4))}var h;h="log"===e.type?{type:"linear",range:[a,o],r2l:Number}:{type:e.type,range:[a,o].map(e.l2r),r2l:e.r2l},D.autoTicks(h,s);var f,d=D.tickIncrement(D.tickFirst(h),h.dtick,"reverse");if("number"==typeof h.dtick){for(var p=0,g=0,m=0,v=0,y=0;y.3*b||i(a)||i(o))){var w=h.dtick/2;d+=d+w0&&t.dtick<2*t._minDtick&&(t.dtick=t._minDtick,t.tick0=t.l2r(t._forceTick0))}if(t.tick0||(t.tick0="date"===t.type?"2000-01-01":0),a(t),"array"===t.tickmode)return n(t);t._tmin=D.tickFirst(t);var o=e[1]=l:u<=l)&&(s.push(u),!(s.length>1e3));u=D.tickIncrement(u,t.dtick,o));t._tmax=s[s.length-1],t._prevDateHead="",t._inCalcTicks=!0;for(var c=new Array(s.length),h=0;hS?(e/=S,r=Math.pow(10,Math.floor(Math.log(e)/Math.LN10)),t.dtick="M"+12*i(e,r,R)):n>L?(e/=L,t.dtick="M"+i(e,1,F)):n>z?(t.dtick=i(e,z,N),t.tick0="2000-01-02"):n>C?t.dtick=i(e,C,F):n>I?t.dtick=i(e,I,j):n>P?t.dtick=i(e,P,j):(r=Math.pow(10,Math.floor(Math.log(e)/Math.LN10)),t.dtick=i(e,r,R))}else if("log"===t.type){t.tick0=0;var a=t.range.map(t.r2l);if(e>.7)t.dtick=Math.ceil(e);else if(Math.abs(a[1]-a[0])<1){var o=1.5*Math.abs((a[1]-a[0])/e);e=Math.abs(Math.pow(10,a[1])-Math.pow(10,a[0]))/o,r=Math.pow(10,Math.floor(Math.log(e)/Math.LN10)),t.dtick="L"+i(e,r,R)}else t.dtick=e>.3?"D2":"D1"}else"category"===t.type?(t.tick0=0,t.dtick=Math.ceil(Math.max(e,1))):(t.tick0=0,r=Math.pow(10,Math.floor(Math.log(e)/Math.LN10)),t.dtick=i(e,r,R));if(0===t.dtick&&(t.dtick=1),!x(t.dtick)&&"string"!=typeof t.dtick){var s=t.dtick;throw t.dtick=1,"ax.dtick error: "+String(s)}},D.tickIncrement=function(t,e,r){var n=r?-1:1;if(x(e))return t+n*e;var i=e.charAt(0),a=n*Number(e.substr(1));if("M"===i){var o=new Date(t);return o.setMonth(o.getMonth()+a)}if("L"===i)return Math.log(Math.pow(10,t)+a)/Math.LN10;if("D"===i){var s="D2"===e?U:B,l=t+.01*n,u=_.roundUp(v(l,1),s,r);return Math.floor(l)+Math.log(y.round(Math.pow(10,u),1))/Math.LN10}throw"unrecognized dtick "+String(e)},D.tickFirst=function(t){var e=t.r2l||Number,r=t.range.map(e),n=r[1]a:h1&&e2*n}function a(t){for(var e,r=Math.max(1,(t.length-1)/1e3),n=0,i=0,a=0;a2*n}var o=t("fast-isnumeric"),s=t("../../lib"),l=t("../../constants/numerical").BADNUM;e.exports=function(t){return i(t)?"date":a(t)?"category":n(t)?"linear":"-"}},{"../../constants/numerical":616,"../../lib":633,"fast-isnumeric":104}],666:[function(t,e,r){"use strict";function n(t,e){if("-"===t.type){var r=t._id,n=r.charAt(0);r.indexOf("scene")!==-1&&(r=n);var s=o(e,r,n);if(s){if("histogram"===s.type&&n==={v:"y",h:"x"}[s.orientation||"v"])return void(t.type="linear");if(a(s,n)){for(var l,c=i(s),h=[],f=0;f0;a&&(n="array");var o=r("categoryorder",n);"array"===o&&r("categoryarray"),a||"array"!==o||(e.categoryorder="trace")}}},{}],669:[function(t,e,r){"use strict";e.exports={idRegex:{x:/^x([2-9]|[1-9][0-9]+)?$/,y:/^y([2-9]|[1-9][0-9]+)?$/},attrRegex:{x:/^xaxis([2-9]|[1-9][0-9]+)?$/,y:/^yaxis([2-9]|[1-9][0-9]+)?$/},xAxisMatch:/^xaxis[0-9]*$/,yAxisMatch:/^yaxis[0-9]*$/,AX_ID_PATTERN:/^[xyz][0-9]*$/,AX_NAME_PATTERN:/^[xyz]axis[0-9]*$/,DBLCLICKDELAY:300,MINDRAG:8,MINSELECT:12,MINZOOM:20,DRAGGERSIZE:20,MAXDIST:20,YANGLE:60,HOVERARROWSIZE:6,HOVERTEXTPAD:3,HOVERFONTSIZE:13,HOVERFONT:"Arial, sans-serif",HOVERMINTIME:50,BENDPX:1.5,REDRAWDELAY:50,DFLTRANGEX:[-1,6],DFLTRANGEY:[-1,4],DFLTRANGEDATE:["2000-01-01","2001-01-01"]}},{}],670:[function(t,e,r){"use strict";function n(t,e){var r,n=t.range[e],i=Math.abs(n-t.range[1-e]);return"date"===t.type?n:"log"===t.type?(r=Math.ceil(Math.max(0,-Math.log(i)/Math.LN10))+3,s.format("."+r+"g")(Math.pow(10,n))):(r=Math.floor(Math.log(Math.abs(n))/Math.LN10)-Math.floor(Math.log(i)/Math.LN10)+4,s.format("."+String(r)+"g")(n))}function i(t,e){return t?"nsew"===t?"pan"===e?"move":"crosshair":t.toLowerCase()+"-resize":"pointer"}function a(t){s.select(t).selectAll(".zoombox,.js-zoombox-backdrop,.js-zoombox-menu,.zoombox-corners").remove()}function o(t){var e=["lasso","select"];return e.indexOf(t)!==-1}var s=t("d3"),l=t("tinycolor2"),u=t("../../plotly"),c=t("../../registry"),h=t("../../lib"),f=t("../../lib/svg_text_utils"),d=t("../../components/color"),p=t("../../components/drawing"),g=t("../../lib/setcursor"),m=t("../../components/dragelement"),v=t("./axes"),y=t("./select"),x=t("./constants"),b=!0;e.exports=function(t,e,r,s,_,w,M,A){function k(t,e){for(var r=0;r.2?"rgba(0,0,0,0)":"rgba(255,255,255,0)","stroke-width":0}).attr("transform","translate("+gt+", "+mt+")").attr("d",ut+"Z"),dt=pt.append("path").attr("class","zoombox-corners").style({fill:d.background,stroke:d.defaultLine,"stroke-width":1,opacity:0}).attr("transform","translate("+gt+", "+mt+")").attr("d","M0,0Z"),S()}function S(){pt.selectAll(".select-outline").remove()}function L(e,r){if(t._transitioningWithDuration)return!1;var n=Math.max(0,Math.min(q,e+at)),i=Math.max(0,Math.min(H,r+ot)),a=Math.abs(n-at),o=Math.abs(i-ot),s=Math.floor(Math.min(o,a,X)/2);st.l=Math.min(at,n),st.r=Math.max(at,n),st.t=Math.min(ot,i),st.b=Math.max(ot,i),!J||o.2?"rgba(0,0,0,0.4)":"rgba(255,255,255,0.3)").duration(200),dt.transition().style("opacity",1).duration(200),ct=!0)}function z(t,e,r){var n,i,a;for(n=0;nzoom back out","long"),b=!1)))}function I(e,r){var i=1===(M+A).length;if(e)F();else if(2!==r||i){if(1===r&&i){var a=M?V[0]:U[0],o="s"===M||"w"===A?0:1,s=a._name+".range["+o+"]",l=n(a,o),c="left",h="middle";if(a.fixedrange)return;M?(h="n"===M?"top":"bottom","right"===a.side&&(c="right")):"e"===A&&(c="right"),rt.call(f.makeEditable,null,{immediate:!0,background:N.paper_bgcolor,text:String(l),fill:a.tickfont?a.tickfont.color:"#444",horizontalAlign:c,verticalAlign:h}).on("edit",function(e){var r=a.d2r(e);void 0!==r&&u.relayout(t,s,r)})}}else R()}function P(e){function r(t,e,r){function n(e){return t.l2r(a+(e-a)*r)}if(!t.fixedrange){var i=t.range.map(t.r2l),a=i[0]+(i[1]-i[0])*e;t.range=i.map(n)}}if(t._context.scrollZoom||N._enablescrollzoom){if(t._transitioningWithDuration)return h.pauseEvent(e);var n=t.querySelector(".plotly");if(T(),!(n.scrollHeight-n.clientHeight>10||n.scrollWidth-n.clientWidth>10)){clearTimeout(yt);var i=-e.deltaY;if(isFinite(i)||(i=e.wheelDelta/10),!isFinite(i))return void h.log("Did not find wheel motion attributes: ",e);var a,o=Math.exp(-Math.min(Math.max(i,-20),20)/100),s=bt.draglayer.select(".nsewdrag").node().getBoundingClientRect(),l=(e.clientX-s.left)/s.width,u=vt[0]+vt[2]*l,c=(s.bottom-e.clientY)/s.height,f=vt[1]+vt[3]*(1-c);if(A){for(a=0;a=0?Math.min(t,.9):1/(1/Math.max(t,-.3)+3.222))}function a(t,e,r){for(var n,a,o=1-e,s=0;s0;n--)r.push(e);return r}function i(t,e){for(var r=[],n=0;nW.width||Y<0||Y>W.height)return _.unhoverRaw(t,e)}else X="xpx"in e?e.xpx:A[0]._length/2,Y="ypx"in e?e.ypx:k[0]._length/2;if(C="xval"in e?n(a,e.xval):i(A,X),I="yval"in e?n(a,e.yval):i(k,Y),!g(C[0])||!g(I[0]))return m.warn("Fx.hover failed",e,t),_.unhoverRaw(t,e)}var Z=1/0;for(D=0;D1||R.hoverinfo.indexOf("name")!==-1?R.name:void 0,index:!1,distance:Math.min(Z,M.MAXDIST),color:x.defaultLine,x0:void 0,x1:void 0,y0:void 0,y1:void 0,xLabelVal:void 0,yLabelVal:void 0,zLabelVal:void 0,text:void 0},o[F]&&(V.subplot=o[F]._subplot),q=H.length,"array"===N){var Q=e[D];"pointNumber"in Q?(V.index=Q.pointNumber,N="closest"):(N="","xval"in Q&&(B=Q.xval,N="x"),"yval"in Q&&(U=Q.yval,N=N?"closest":"y"))}else B=C[j],U=I[j];if(R._module&&R._module.hoverPoints){var K=R._module.hoverPoints(V,B,U,N);if(K)for(var $,J=0;Jq&&(H.splice(0,q),Z=H[0].distance)}if(0===H.length)return _.unhoverRaw(t,e);var tt="y"===z&&G.length>1;H.sort(function(t,e){return t.distance-e.distance});var et=x.combine(o.plot_bgcolor||x.background,o.paper_bgcolor),rt={hovermode:z,rotateLabels:tt,bgColor:et,container:o._hoverlayer,outerContainer:o._paperdiv},nt=u(H,rt);c(H,tt?"xa":"ya"),h(nt,tt);var it=t._hoverdata,at=[];for(P=0;P128?"#000":x.background;if(t.name&&void 0===t.zLabelVal){var c=document.createElement("p");c.innerHTML=t.name,r=c.textContent||"",r.length>15&&(r=r.substr(0,12)+"...")}void 0!==t.extraText&&(n+=t.extraText),void 0!==t.zLabel?(void 0!==t.xLabel&&(n+="x: "+t.xLabel+"
"),void 0!==t.yLabel&&(n+="y: "+t.yLabel+"
"),n+=(n?"z: ":"")+t.zLabel):k&&t[i+"Label"]===g?n=t[("x"===i?"y":"x")+"Label"]||"":void 0===t.xLabel?void 0!==t.yLabel&&(n=t.yLabel):n=void 0===t.yLabel?t.xLabel:"("+t.xLabel+", "+t.yLabel+")",t.text&&!Array.isArray(t.text)&&(n+=(n?"
":"")+t.text),""===n&&(""===r&&e.remove(),n=r);var h=e.select("text.nums").style("fill",u).call(b.setPosition,0,0).text(n).attr("data-notex",1).call(y.convertToTspans);h.selectAll("tspan.line").call(b.setPosition,0,0);var f=e.select("text.name"),m=0;r&&r!==n?(f.style("fill",l).text(r).call(b.setPosition,0,0).attr("data-notex",1).call(y.convertToTspans),f.selectAll("tspan.line").call(b.setPosition,0,0),m=f.node().getBoundingClientRect().width+2*P):(f.remove(),e.select("rect").remove()),e.select("path").style({fill:l,stroke:u});var v,M,T=h.node().getBoundingClientRect(),S=t.xa._offset+(t.x0+t.x1)/2,L=t.ya._offset+(t.y0+t.y1)/2,z=Math.abs(t.x1-t.x0),C=Math.abs(t.y1-t.y0),D=T.width+I+P+m;t.ty0=_-T.top,t.bx=T.width+2*P,t.by=T.height+2*P,t.anchor="start",t.txwidth=T.width,t.tx2width=m,t.offset=0,a?(t.pos=S,v=L+C/2+D<=A,M=L-C/2-D>=0,"top"!==t.idealAlign&&v||!M?v?(L+=C/2,t.anchor="start"):t.anchor="middle":(L-=C/2,t.anchor="end")):(t.pos=L,v=S+z/2+D<=w,M=S-z/2-D>=0,"left"!==t.idealAlign&&v||!M?v?(S+=z/2,t.anchor="start"):t.anchor="middle":(S-=z/2,t.anchor="end")),h.attr("text-anchor",t.anchor),m&&f.attr("text-anchor",t.anchor),e.attr("transform","translate("+S+","+L+")"+(a?"rotate("+E+")":""))}),L}function c(t,e){function r(t){var e=t[0],r=t[t.length-1];if(i=e.pmin-e.pos-e.dp+e.size,a=r.pos+r.dp+r.size-e.pmax,i>.01){for(s=t.length-1;s>=0;s--)t[s].dp+=i;n=!1}if(!(a<.01)){if(i<-.01){for(s=t.length-1;s>=0;s--)t[s].dp-=a;n=!1}if(n){var u=0;for(o=0;oe.pmax&&u++;for(o=t.length-1;o>=0&&!(u<=0);o--)l=t[o],l.pos>e.pmax-1&&(l.del=!0,u--);for(o=0;o=0;s--)t[s].dp-=a;for(o=t.length-1;o>=0&&!(u<=0);o--)l=t[o],l.pos+l.dp+l.size>e.pmax&&(l.del=!0,u--)}}}for(var n,i,a,o,s,l,u,c=0,h=t.map(function(t,r){var n=t[e];return[{i:r,dp:0,pos:t.pos,posref:t.posref,size:t.by*("x"===n._id.charAt(0)?L:1)/2,pmin:n._offset,pmax:n._offset+n._length}]}).sort(function(t,e){return t[0].posref-e[0].posref});!n&&c<=t.length;){for(c++,n=!0,o=0;o.01&&p.pmin===g.pmin&&p.pmax===g.pmax){for(s=d.length-1;s>=0;s--)d[s].dp+=i;for(f.push.apply(f,d),h.splice(o+1,1),u=0,s=f.length-1;s>=0;s--)u+=f[s].dp;for(a=u/f.length,s=f.length-1;s>=0;s--)f[s].dp-=a;n=!1}else o++}h.forEach(r)}for(o=h.length-1;o>=0;o--){var m=h[o];for(s=m.length-1;s>=0;s--){var v=m[s],y=t[v.i];y.offset=v.dp,y.del=v.del}}}function h(t,e){t.each(function(t){var r=d.select(this);if(t.del)return void r.remove();var n="end"===t.anchor?-1:1,i=r.select("text.nums"),a={start:1,end:-1,middle:0}[t.anchor],o=a*(I+P),s=o+a*(t.txwidth+P),l=0,u=t.offset;"middle"===t.anchor&&(o-=t.tx2width/2,s-=t.tx2width/2),e&&(u*=-C,l=t.offset*z),r.select("path").attr("d","middle"===t.anchor?"M-"+t.bx/2+",-"+t.by/2+"h"+t.bx+"v"+t.by+"h-"+t.bx+"Z":"M0,0L"+(n*I+l)+","+(I+u)+"v"+(t.by/2-I)+"h"+n*t.bx+"v-"+t.by+"H"+(n*I+l)+"V"+(u-I)+"Z"),i.call(b.setPosition,o+l,u+t.ty0-t.by/2+P).selectAll("tspan.line").attr({x:i.attr("x"),y:i.attr("y")}),t.tx2width&&(r.select("text.name, text.name tspan.line").call(b.setPosition,s+a*P+l,u+t.ty0-t.by/2+P),r.select("rect").call(b.setRect,s+(a-1)*t.tx2width/2+l,u-t.by/2-1,t.tx2width,t.by+2))})}function f(t,e,r){if(!e.target)return!1;if(!r||r.length!==t._hoverdata.length)return!0;for(var n=r.length-1;n>=0;n--){var i=r[n],a=t._hoverdata[n];if(i.curveNumber!==a.curveNumber||String(i.pointNumber)!==String(a.pointNumber))return!0}return!1}var d=t("d3"),p=t("tinycolor2"),g=t("fast-isnumeric"),m=t("../../lib"),v=t("../../lib/events"),y=t("../../lib/svg_text_utils"),x=t("../../components/color"),b=t("../../components/drawing"),_=t("../../components/dragelement"),w=t("./axes"),M=t("./constants"),A=t("./dragbox"),k=t("../layout_attributes"),T=e.exports={}; diff --git a/web/vtctld2/src/app/status/heatmap.component.ts b/web/vtctld2/src/app/status/heatmap.component.ts index 36c02d81e41..928683693ee 100644 --- a/web/vtctld2/src/app/status/heatmap.component.ts +++ b/web/vtctld2/src/app/status/heatmap.component.ts @@ -124,7 +124,7 @@ export class HeatmapComponent implements AfterViewInit, OnInit { let elem = (document.getElementById(this.name)); // onClick handler for the heatmap. - // Upon clicking, the popup will display all relevent data for that data point. + // Upon clicking, the popup will display all relevant data for that data point. elem.on('plotly_click', function(data) { this.zone.run(() => { this.showPopup = false; }); let shardIndex = this.xLabels.indexOf(data.points[0].x); From cfbc7c9269cd07f097ba074c119c886a5453ade0 Mon Sep 17 00:00:00 2001 From: Mark Solters Date: Wed, 28 Aug 2019 12:09:49 -0400 Subject: [PATCH 024/425] Orc basic auth with vttablet flags Signed-off-by: Mark Solters --- go/vt/vttablet/tabletmanager/orchestrator.go | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/go/vt/vttablet/tabletmanager/orchestrator.go b/go/vt/vttablet/tabletmanager/orchestrator.go index 66d8222d221..65e0b4141a5 100644 --- a/go/vt/vttablet/tabletmanager/orchestrator.go +++ b/go/vt/vttablet/tabletmanager/orchestrator.go @@ -37,6 +37,8 @@ import ( var ( orcAddr = flag.String("orc_api_url", "", "Address of Orchestrator's HTTP API (e.g. http://host:port/api/). Leave empty to disable Orchestrator integration.") + orcUser = flag.String("orc_api_user", "", "(Optional) Basic auth username to authenticate with Orchestrator's HTTP API. Leave empty to disable basic auth.") + orcPassword = flag.String("orc_api_password", "", "(Optional) Basic auth password to authenticate with Orchestrator's HTTP API.") orcTimeout = flag.Duration("orc_timeout", 30*time.Second, "Timeout for calls to Orchestrator's HTTP API") orcInterval = flag.Duration("orc_discover_interval", 0, "How often to ping Orchestrator's HTTP API endpoint to tell it we exist. 0 means never.") ) @@ -183,7 +185,11 @@ func (orc *orcClient) apiGet(pathParts ...string) ([]byte, error) { url.Path = path.Join(fullPath...) // Note that url.String() will URL-escape the path we gave it above. - resp, err := orc.httpClient.Get(url.String()) + req, err := http.NewRequest("GET", url.String(), nil) + if *orcUser != "" { + req.SetBasicAuth(*orcUser, *orcPassword) + } + resp, err := orc.httpClient.Do(req) if err != nil { return nil, err } From fc75af7cb1a4bbb07d73a45ec0b876ae38dc180f Mon Sep 17 00:00:00 2001 From: Connor Barnhill Date: Wed, 28 Aug 2019 14:29:03 -0400 Subject: [PATCH 025/425] fix indent error Signed-off-by: Connor Barnhill --- helm/vitess/templates/_orchestrator-conf.tpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/helm/vitess/templates/_orchestrator-conf.tpl b/helm/vitess/templates/_orchestrator-conf.tpl index 93d8183e00f..950c0768ea0 100644 --- a/helm/vitess/templates/_orchestrator-conf.tpl +++ b/helm/vitess/templates/_orchestrator-conf.tpl @@ -14,7 +14,7 @@ metadata: name: orchestrator-cm data: orchestrator.conf.json: |- - { + { "ActiveNodeExpireSeconds": 5, "ApplyMySQLPromotionAfterMasterFailover": true, "AuditLogFile": "/tmp/orchestrator-audit.log", From c9697027eeb9813a385a312fef042e477d232f1c Mon Sep 17 00:00:00 2001 From: Rasika Kale Date: Wed, 28 Aug 2019 12:58:43 -0700 Subject: [PATCH 026/425] Fixed runtime error in Multiply() Signed-off-by: Rasika Kale --- go/sqltypes/arithmetic.go | 3 +++ go/sqltypes/arithmetic_test.go | 9 +++++++++ 2 files changed, 12 insertions(+) diff --git a/go/sqltypes/arithmetic.go b/go/sqltypes/arithmetic.go index c448af3263f..06b702f1a62 100644 --- a/go/sqltypes/arithmetic.go +++ b/go/sqltypes/arithmetic.go @@ -572,6 +572,9 @@ func uintMinusUintWithError(v1, v2 uint64) (numeric, error) { func uintTimesUintWithError(v1, v2 uint64) (numeric, error) { result := v1 * v2 + if v1 >= math.MaxUint64 && v2 > 1 || v2 >= math.MaxUint64 && v1 > 1 { + return numeric{}, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "BIGINT UNSIGNED value is out of range in %v * %v", v1, v2) + } return numeric{typ: Uint64, uval: result}, nil } diff --git a/go/sqltypes/arithmetic_test.go b/go/sqltypes/arithmetic_test.go index 23d8687b0b1..3af89d2c5f2 100644 --- a/go/sqltypes/arithmetic_test.go +++ b/go/sqltypes/arithmetic_test.go @@ -99,6 +99,15 @@ func TestMultiply(t *testing.T) { v1: NewInt64(math.MaxInt64), v2: NewInt64(2), err: vterrors.New(vtrpcpb.Code_INVALID_ARGUMENT, "BIGINT value is out of range in 9223372036854775807 * 2"), + }, { + // testing for underflow of uint64*max.uint64 + v1: NewUint64(2), + v2: NewUint64(math.MaxUint64), + err: vterrors.New(vtrpcpb.Code_INVALID_ARGUMENT, "BIGINT UNSIGNED value is out of range in 2 * 18446744073709551615"), + }, { + v1: NewUint64(math.MaxUint64), + v2: NewUint64(1), + out: NewUint64(math.MaxUint64), }} for _, tcase := range tcases { From 54d3a68403e6366f0d1d993db41f8ca3d3d234ff Mon Sep 17 00:00:00 2001 From: Karel Alfonso Sague Date: Thu, 29 Aug 2019 16:24:42 +1000 Subject: [PATCH 027/425] Delete vitess metadata by setting empty key Signed-off-by: Karel Alfonso Sague --- go/vt/topo/metadata.go | 14 ++++++++++++++ go/vt/vtgate/executor.go | 10 ++++++++-- go/vt/vtgate/executor_test.go | 34 ++++++++++++++++++++++++++++++++++ 3 files changed, 56 insertions(+), 2 deletions(-) diff --git a/go/vt/topo/metadata.go b/go/vt/topo/metadata.go index 349ea7f8084..ab235da2719 100644 --- a/go/vt/topo/metadata.go +++ b/go/vt/topo/metadata.go @@ -19,6 +19,7 @@ package topo import ( "context" "path" + "vitess.io/vitess/go/vt/sqlparser" "vitess.io/vitess/go/event" @@ -74,6 +75,19 @@ func (ts *Server) GetMetadata(ctx context.Context, keyFilter string) (map[string return result, nil } +// DeleteMetadata deletes the key in the metadata +func (ts *Server) DeleteMetadata(ctx context.Context, key string) error { + keyPath := path.Join(MetadataPath, key) + + // nil version means that it will insert if keyPath does not exist + if err := ts.globalCell.Delete(ctx, keyPath, nil); err != nil { + return err + } + + dispatchEvent(keyPath, "deleted") + return nil +} + func (ts *Server) getMetadata(ctx context.Context, key string) (string, error) { keyPath := path.Join(MetadataPath, key) contents, _, err := ts.globalCell.Get(ctx, keyPath) diff --git a/go/vt/vtgate/executor.go b/go/vt/vtgate/executor.go index a21476e6b35..e1bc9ee252c 100644 --- a/go/vt/vtgate/executor.go +++ b/go/vt/vtgate/executor.go @@ -667,11 +667,17 @@ func (e *Executor) handleSetVitessMetadata(ctx context.Context, session *SafeSes return nil, err } - if err := ts.UpsertMetadata(ctx, k.Key, val); err != nil { + if val == "" { + err = ts.DeleteMetadata(ctx, k.Key) + } else { + err = ts.UpsertMetadata(ctx, k.Key, val) + } + + if err != nil { return nil, err } - return &sqltypes.Result{}, nil + return &sqltypes.Result{RowsAffected: 1}, nil } func (e *Executor) handleShowVitessMetadata(ctx context.Context, session *SafeSession, opt *sqlparser.ShowTablesOpt) (*sqltypes.Result, error) { diff --git a/go/vt/vtgate/executor_test.go b/go/vt/vtgate/executor_test.go index 54aa1ac7b8c..bbb158bfebb 100644 --- a/go/vt/vtgate/executor_test.go +++ b/go/vt/vtgate/executor_test.go @@ -28,6 +28,8 @@ import ( "strings" "testing" "time" + + "vitess.io/vitess/go/vt/topo" "vitess.io/vitess/go/vt/vterrors" "context" @@ -531,6 +533,38 @@ func TestExecutorSetMetadata(t *testing.T) { assert.ElementsMatch(t, wantqr.Rows, gotqr.Rows) } +func TestExecutorDeleteMetadata(t *testing.T) { + *vschemaacl.AuthorizedDDLUsers = "%" + defer func() { + *vschemaacl.AuthorizedDDLUsers = "" + }() + + executor, _, _, _ := createExecutorEnv() + session := NewSafeSession(&vtgatepb.Session{TargetString: "@master", Autocommit: true}) + + set := "set @@vitess_metadata.app_v1= '1'" + _, err := executor.Execute(context.Background(), "TestExecute", session, set, nil) + assert.NoError(t, err, "%s error: %v", set, err) + + show := `show vitess_metadata variables like 'app\\_%'` + result, _ := executor.Execute(context.Background(), "TestExecute", session, show, nil) + assert.Len(t, result.Rows, 1) + + // Fails if deleting key that doesn't exist + delete := "set @@vitess_metadata.doesnt_exist=''" + _, err = executor.Execute(context.Background(), "TestExecute", session, delete, nil) + assert.True(t, topo.IsErrType(err, topo.NoNode)) + + // Delete existing key, show should fail given the node doesn't exist + delete = "set @@vitess_metadata.app_v1=''" + _, err = executor.Execute(context.Background(), "TestExecute", session, delete, nil) + assert.NoError(t, err) + + show = `show vitess_metadata variables like 'app\\_%'` + result, err = executor.Execute(context.Background(), "TestExecute", session, show, nil) + assert.True(t, topo.IsErrType(err, topo.NoNode)) +} + func TestExecutorAutocommit(t *testing.T) { executor, _, _, sbclookup := createExecutorEnv() session := NewSafeSession(&vtgatepb.Session{TargetString: "@master"}) From 7c526e867accc353ed1fc6cc40b0a99b08d0be38 Mon Sep 17 00:00:00 2001 From: Adam Saponara Date: Thu, 29 Aug 2019 12:04:00 -0400 Subject: [PATCH 028/425] Fix bug in `sqlparser.Preview` Signed-off-by: Adam Saponara --- go/vt/sqlparser/analyzer.go | 9 +++++---- go/vt/sqlparser/analyzer_test.go | 1 + 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/go/vt/sqlparser/analyzer.go b/go/vt/sqlparser/analyzer.go index 5a73541de8d..a8bca820ba7 100644 --- a/go/vt/sqlparser/analyzer.go +++ b/go/vt/sqlparser/analyzer.go @@ -56,11 +56,12 @@ const ( func Preview(sql string) int { trimmed := StripLeadingComments(sql) - firstWord := trimmed - if end := strings.IndexFunc(trimmed, unicode.IsSpace); end != -1 { - firstWord = trimmed[:end] + isNotLetter := func(r rune) bool { return !unicode.IsLetter(r) } + firstWord := strings.TrimLeftFunc(trimmed, isNotLetter) + + if end := strings.IndexFunc(firstWord, unicode.IsSpace); end != -1 { + firstWord = firstWord[:end] } - firstWord = strings.TrimLeftFunc(firstWord, func(r rune) bool { return !unicode.IsLetter(r) }) // Comparison is done in order of priority. loweredFirstWord := strings.ToLower(firstWord) switch loweredFirstWord { diff --git a/go/vt/sqlparser/analyzer_test.go b/go/vt/sqlparser/analyzer_test.go index 68e24d75ca5..ba1ca19ec96 100644 --- a/go/vt/sqlparser/analyzer_test.go +++ b/go/vt/sqlparser/analyzer_test.go @@ -32,6 +32,7 @@ func TestPreview(t *testing.T) { {"select ...", StmtSelect}, {" select ...", StmtSelect}, {"(select ...", StmtSelect}, + {"( select ...", StmtSelect}, {"insert ...", StmtInsert}, {"replace ....", StmtReplace}, {" update ...", StmtUpdate}, From 3a05a41b9fb0343f47a7dc62bfb49a1fbc5114c8 Mon Sep 17 00:00:00 2001 From: Anthony Yeh Date: Thu, 29 Aug 2019 10:11:20 -0700 Subject: [PATCH 029/425] vtbackup: Make initial backup idempotent again. The check for a complete backup already existing was supposed to make the initial backup idempotent, such that running it after an initial backup already exists will simply do nothing and return success. However, that property was broken when I added the check for serving tablets above the check for a complete backup. I should have kept the check for a complete backup first, because if there's already a complete backup and we're doing nothing, then it's fine that some tablets may already be serving. Signed-off-by: Anthony Yeh --- go/cmd/vtbackup/vtbackup.go | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/go/cmd/vtbackup/vtbackup.go b/go/cmd/vtbackup/vtbackup.go index 690271a0e63..6f5e72813a1 100644 --- a/go/cmd/vtbackup/vtbackup.go +++ b/go/cmd/vtbackup/vtbackup.go @@ -468,13 +468,21 @@ func parseBackupTime(name string) (time.Time, error) { } func shouldBackup(ctx context.Context, topoServer *topo.Server, backupStorage backupstorage.BackupStorage, backupDir string) (bool, error) { + // Look for the most recent, complete backup. backups, err := backupStorage.ListBackups(ctx, backupDir) if err != nil { return false, fmt.Errorf("can't list backups: %v", err) } + lastBackup := lastCompleteBackup(ctx, backups) // Check preconditions for initial_backup mode. if *initialBackup { + // Check if any backups for the shard already exist in this backup storage location. + if lastBackup != nil { + log.Infof("At least one complete backup already exists, so there's no need to seed an empty backup. Doing nothing.") + return false, nil + } + // Check whether the shard exists. _, shardErr := topoServer.GetShard(ctx, *initKeyspace, *initShard) switch { @@ -505,11 +513,6 @@ func shouldBackup(ctx context.Context, topoServer *topo.Server, backupStorage ba return false, fmt.Errorf("failed to check whether shard %v/%v exists before doing initial backup: %v", *initKeyspace, *initShard, err) } - // Check if any backups for the shard exist in this backup storage location. - if len(backups) > 0 { - log.Infof("At least one backup already exists, so there's no need to seed an empty backup. Doing nothing.") - return false, nil - } log.Infof("Shard %v/%v has no existing backups. Creating initial backup.", *initKeyspace, *initShard) return true, nil } @@ -518,8 +521,6 @@ func shouldBackup(ctx context.Context, topoServer *topo.Server, backupStorage ba if len(backups) == 0 && !*allowFirstBackup { return false, fmt.Errorf("no existing backups to restore from; backup is not possible since -initial_backup flag was not enabled") } - // Look for the most recent, complete backup. - lastBackup := lastCompleteBackup(ctx, backups) if lastBackup == nil { if *allowFirstBackup { // There's no complete backup, but we were told to take one from scratch anyway. From 880072cc8fb484d71b0423bc885a5217f1e37b27 Mon Sep 17 00:00:00 2001 From: Adam Saponara Date: Thu, 29 Aug 2019 18:03:10 -0400 Subject: [PATCH 030/425] Prioritize executable comment in `sqlparser.Preview` Signed-off-by: Adam Saponara --- go/vt/sqlparser/analyzer.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/go/vt/sqlparser/analyzer.go b/go/vt/sqlparser/analyzer.go index a8bca820ba7..83ced5e3d32 100644 --- a/go/vt/sqlparser/analyzer.go +++ b/go/vt/sqlparser/analyzer.go @@ -56,6 +56,10 @@ const ( func Preview(sql string) int { trimmed := StripLeadingComments(sql) + if strings.Index(trimmed, "/*!") == 0 { + return StmtComment + } + isNotLetter := func(r rune) bool { return !unicode.IsLetter(r) } firstWord := strings.TrimLeftFunc(trimmed, isNotLetter) @@ -104,9 +108,6 @@ func Preview(sql string) int { case "analyze", "describe", "desc", "explain", "repair", "optimize": return StmtOther } - if strings.Index(trimmed, "/*!") == 0 { - return StmtComment - } return StmtUnknown } From 750408236822125f4d78050b80565f4dd48f97bf Mon Sep 17 00:00:00 2001 From: Adam Saponara Date: Thu, 29 Aug 2019 18:28:36 -0400 Subject: [PATCH 031/425] Handle case where mysqld replies to Initial Handshake Packet with an ERR packet. From mysql docs: ``` It starts with the client connect()ing to the server which may send a ERR packet and finish the handshake or send a Initial Handshake Packet... ``` `sql_state` fields are skipped because they are not set according to docs. ``` Note In case the server sent a ERR packet as first packet it will happen before the client and server negotiated any capabilities. Therefore the ERR packet will not contain the SQL-state. ``` Signed-off-by: Adam Saponara --- go/mysql/client.go | 10 ++++++++++ go/mysql/encoding.go | 8 ++++++++ go/mysql/encoding_test.go | 26 ++++++++++++++++++++------ 3 files changed, 38 insertions(+), 6 deletions(-) diff --git a/go/mysql/client.go b/go/mysql/client.go index 34dcacbc0f2..ee9ff368fda 100644 --- a/go/mysql/client.go +++ b/go/mysql/client.go @@ -373,6 +373,16 @@ func (c *Conn) parseInitialHandshakePacket(data []byte) (uint32, []byte, error) if !ok { return 0, nil, NewSQLError(CRVersionError, SSUnknownSQLState, "parseInitialHandshakePacket: packet has no protocol version") } + + // Server is allowed to immediately send ERR packet + if pver == ErrPacket { + errorCode, pos, _ := readUint16(data, pos) + // Normally there would be a 1-byte sql_state_marker field and a 5-byte + // sql_state field here, but docs say these will not be present in this case. + errorMsg, pos, _ := readEOFString(data, pos) + return 0, nil, NewSQLError(CRServerHandshakeErr, SSUnknownSQLState, "immediate error from server errorCode=%v errorMsg=%v", errorCode, errorMsg) + } + if pver != protocolVersion { return 0, nil, NewSQLError(CRVersionError, SSUnknownSQLState, "bad protocol version: %v", pver) } diff --git a/go/mysql/encoding.go b/go/mysql/encoding.go index 018da8a8f9b..7926c5bd498 100644 --- a/go/mysql/encoding.go +++ b/go/mysql/encoding.go @@ -80,6 +80,10 @@ func lenNullString(value string) int { return len(value) + 1 } +func lenEOFString(value string) int { + return len(value) +} + func writeNullString(data []byte, pos int, value string) int { pos += copy(data[pos:], value) data[pos] = 0 @@ -180,6 +184,10 @@ func readNullString(data []byte, pos int) (string, int, bool) { return string(data[pos : pos+end]), pos + end + 1, true } +func readEOFString(data []byte, pos int) (string, int, bool) { + return string(data[pos:]), len(data) - pos, true +} + func readUint16(data []byte, pos int) (uint16, int, bool) { if pos+1 >= len(data) { return 0, 0, false diff --git a/go/mysql/encoding_test.go b/go/mysql/encoding_test.go index 7f56f583c86..8d1bb804936 100644 --- a/go/mysql/encoding_test.go +++ b/go/mysql/encoding_test.go @@ -190,21 +190,25 @@ func TestEncString(t *testing.T) { value string lenEncoded []byte nullEncoded []byte + eofEncoded []byte }{ { "", []byte{0x00}, []byte{0x00}, + []byte{}, }, { "a", []byte{0x01, 'a'}, []byte{'a', 0x00}, + []byte{'a'}, }, { "0123456789", []byte{0x0a, '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'}, []byte{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 0x00}, + []byte{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'}, }, } for _, test := range tests { @@ -220,6 +224,11 @@ func TestEncString(t *testing.T) { t.Errorf("lenNullString returned %v but expected %v for %v", got, len(test.nullEncoded), test.value) } + // Check lenEOFString + if got := lenEOFString(test.value); got != len(test.eofEncoded) { + t.Errorf("lenNullString returned %v but expected %v for %v", got, len(test.eofEncoded), test.value) + } + // Check successful encoding. data := make([]byte, len(test.lenEncoded)) pos := writeLenEncString(data, 0, test.value) @@ -319,16 +328,21 @@ func TestEncString(t *testing.T) { } // EOF encoded tests. - // We use the nullEncoded value, removing the 0 at the end. // Check successful encoding. - data = make([]byte, len(test.nullEncoded)-1) + data = make([]byte, len(test.eofEncoded)) pos = writeEOFString(data, 0, test.value) - if pos != len(test.nullEncoded)-1 { - t.Errorf("unexpected pos %v after writeEOFString(%v), expected %v", pos, test.value, len(test.nullEncoded)-1) + if pos != len(test.eofEncoded) { + t.Errorf("unexpected pos %v after writeEOFString(%v), expected %v", pos, test.value, len(test.eofEncoded)) } - if !bytes.Equal(data, test.nullEncoded[:len(test.nullEncoded)-1]) { - t.Errorf("unexpected nullEncoded value for %v, got %v expected %v", test.value, data, test.nullEncoded) + if !bytes.Equal(data, test.eofEncoded[:len(test.eofEncoded)]) { + t.Errorf("unexpected eofEncoded value for %v, got %v expected %v", test.value, data, test.eofEncoded) + } + + // Check successful decoding. + got, pos, ok = readEOFString(test.eofEncoded, 0) + if !ok || got != test.value || pos != len(test.eofEncoded) { + t.Errorf("readEOFString returned %v/%v/%v but expected %v/%v/%v", got, pos, ok, test.value, len(test.eofEncoded), true) } } } From fc1ad423ba79980283d032db64df4b002f1c584e Mon Sep 17 00:00:00 2001 From: Karel Alfonso Sague Date: Wed, 28 Aug 2019 15:51:28 +1000 Subject: [PATCH 032/425] Execute "ALTER VSCHEMA" statements without specifying keyspace in the target connection. If the keyspace is not present in the target string, it will be derived in this case from the vindex and table qualifiers in the vschema sql statements Signed-off-by: Karel Alfonso Sague --- go/vt/sqlparser/ast.go | 4 +- go/vt/sqlparser/parse_test.go | 19 + go/vt/sqlparser/sql.go | 1484 +++++++++++++++++---------------- go/vt/sqlparser/sql.y | 28 +- go/vt/topo/server.go | 2 +- go/vt/vtgate/executor_test.go | 29 + 6 files changed, 815 insertions(+), 751 deletions(-) diff --git a/go/vt/sqlparser/ast.go b/go/vt/sqlparser/ast.go index f10a7abe9f3..13dd963af9a 100644 --- a/go/vt/sqlparser/ast.go +++ b/go/vt/sqlparser/ast.go @@ -797,9 +797,9 @@ func (node *DDL) Format(buf *TrackedBuffer) { case FlushStr: buf.Myprintf("%s", node.Action) case CreateVindexStr: - buf.Myprintf("alter vschema create vindex %v %v", node.VindexSpec.Name, node.VindexSpec) + buf.Myprintf("alter vschema create vindex %v %v", node.Table, node.VindexSpec) case DropVindexStr: - buf.Myprintf("alter vschema drop vindex %v", node.VindexSpec.Name) + buf.Myprintf("alter vschema drop vindex %v", node.Table) case AddVschemaTableStr: buf.Myprintf("alter vschema add table %v", node.Table) case DropVschemaTableStr: diff --git a/go/vt/sqlparser/parse_test.go b/go/vt/sqlparser/parse_test.go index d321b2bc932..8af2941cd9f 100644 --- a/go/vt/sqlparser/parse_test.go +++ b/go/vt/sqlparser/parse_test.go @@ -971,25 +971,42 @@ var ( output: "create table a (\n\tb1 bool not null primary key,\n\tb2 boolean not null\n)", }, { input: "alter vschema create vindex hash_vdx using hash", + }, { + input: "alter vschema create vindex keyspace.hash_vdx using hash", }, { input: "alter vschema create vindex lookup_vdx using lookup with owner=user, table=name_user_idx, from=name, to=user_id", }, { input: "alter vschema create vindex xyz_vdx using xyz with param1=hello, param2='world', param3=123", }, { input: "alter vschema drop vindex hash_vdx", + }, { + input: "alter vschema drop vindex ks.hash_vdx", }, { input: "alter vschema add table a", + }, { + input: "alter vschema add table ks.a", }, { input: "alter vschema add sequence a_seq", + }, { + input: "alter vschema add sequence ks.a_seq", }, { input: "alter vschema on a add auto_increment id using a_seq", + }, { + input: "alter vschema on ks.a add auto_increment id using a_seq", }, { input: "alter vschema drop table a", + }, { + input: "alter vschema drop table ks.a", }, { input: "alter vschema on a add vindex hash (id)", + }, { + input: "alter vschema on ks.a add vindex hash (id)", }, { input: "alter vschema on a add vindex `hash` (`id`)", output: "alter vschema on a add vindex hash (id)", + }, { + input: "alter vschema on `ks`.a add vindex `hash` (`id`)", + output: "alter vschema on ks.a add vindex hash (id)", }, { input: "alter vschema on a add vindex hash (id) using `hash`", output: "alter vschema on a add vindex hash (id) using hash", @@ -1007,6 +1024,8 @@ var ( output: "alter vschema on user2 add vindex name_lastname_lookup_vdx (name, lastname) using lookup with owner=user, table=name_lastname_keyspace_id_map, from=name,lastname, to=keyspace_id", }, { input: "alter vschema on a drop vindex hash", + }, { + input: "alter vschema on ks.a drop vindex hash", }, { input: "alter vschema on a drop vindex `hash`", output: "alter vschema on a drop vindex hash", diff --git a/go/vt/sqlparser/sql.go b/go/vt/sqlparser/sql.go index 36987cd9297..46b8da47869 100644 --- a/go/vt/sqlparser/sql.go +++ b/go/vt/sqlparser/sql.go @@ -710,204 +710,204 @@ const yyLast = 12449 var yyAct = [...]int{ 263, 1428, 1418, 1225, 1382, 1022, 267, 565, 1165, 1283, - 873, 1040, 1296, 1328, 280, 1199, 846, 1113, 902, 1023, - 1162, 844, 1166, 916, 869, 953, 57, 293, 882, 872, - 1172, 241, 81, 1067, 709, 1137, 206, 1178, 785, 206, - 795, 1093, 336, 723, 1084, 833, 606, 625, 981, 886, - 813, 497, 762, 848, 792, 437, 1046, 503, 624, 330, - 826, 294, 51, 912, 232, 325, 509, 206, 81, 265, - 517, 614, 206, 250, 206, 327, 579, 56, 322, 1421, - 1405, 1416, 1392, 1413, 1226, 605, 1357, 530, 529, 539, - 540, 532, 533, 534, 535, 536, 537, 538, 531, 564, - 3, 541, 580, 1404, 254, 1391, 1154, 1255, 442, 233, - 234, 235, 236, 51, 626, 239, 627, 61, 1194, 1195, - 305, 246, 311, 312, 309, 310, 308, 307, 306, 1193, - 470, 201, 197, 198, 199, 1055, 313, 314, 1054, 864, - 865, 1056, 863, 63, 64, 65, 66, 67, 486, 1138, - 238, 240, 487, 484, 485, 237, 193, 935, 195, 491, - 1075, 895, 1115, 1286, 1303, 896, 903, 231, 1246, 1244, - 489, 934, 698, 479, 480, 1117, 697, 695, 1415, 1412, - 1383, 1112, 1375, 827, 887, 1436, 1140, 1041, 1043, 1337, - 1432, 1329, 455, 456, 206, 444, 472, 206, 474, 939, - 688, 195, 611, 206, 1331, 1118, 702, 1109, 933, 206, - 696, 699, 81, 1111, 81, 1116, 81, 81, 490, 81, - 1142, 81, 1146, 889, 1141, 1188, 1139, 81, 471, 473, - 1187, 1144, 889, 1186, 440, 889, 468, 447, 203, 208, - 1143, 196, 452, 947, 553, 554, 946, 998, 1364, 200, - 194, 1266, 438, 1145, 1147, 1358, 1124, 81, 930, 927, - 928, 1068, 926, 1051, 1042, 1008, 975, 734, 466, 324, - 620, 505, 1330, 467, 439, 467, 441, 467, 467, 521, - 467, 462, 467, 1211, 531, 870, 541, 541, 467, 731, - 1338, 1336, 859, 937, 940, 903, 1430, 1373, 728, 1431, - 995, 1429, 493, 494, 333, 449, 516, 450, 51, 1110, - 451, 1108, 438, 469, 256, 1390, 724, 1346, 1100, 888, - 206, 206, 206, 550, 885, 883, 552, 884, 888, 81, - 932, 888, 881, 887, 1212, 81, 534, 535, 536, 537, - 538, 531, 604, 1176, 541, 436, 506, 1098, 955, 553, - 554, 628, 931, 733, 563, 1156, 567, 568, 569, 570, + 873, 1040, 1199, 1328, 1296, 280, 1023, 1113, 846, 241, + 466, 869, 1166, 896, 953, 564, 3, 844, 1162, 882, + 916, 902, 81, 1172, 293, 1137, 206, 872, 57, 206, + 1178, 785, 336, 709, 795, 723, 1093, 625, 1067, 981, + 1084, 886, 232, 848, 792, 833, 1046, 813, 762, 497, + 503, 294, 51, 912, 624, 437, 826, 206, 81, 330, + 265, 509, 206, 325, 206, 517, 250, 240, 322, 327, + 614, 56, 579, 1421, 606, 1405, 1416, 1392, 305, 605, + 311, 312, 309, 310, 308, 307, 306, 233, 234, 235, + 236, 1413, 580, 239, 313, 314, 1226, 1404, 254, 1391, + 1154, 1255, 442, 51, 1194, 1195, 1055, 61, 626, 1054, + 627, 246, 1056, 269, 1357, 530, 529, 539, 540, 532, + 533, 534, 535, 536, 537, 538, 531, 864, 865, 541, + 1193, 863, 491, 63, 64, 65, 66, 67, 201, 197, + 198, 199, 486, 238, 470, 237, 487, 484, 485, 1075, + 193, 895, 195, 1286, 1303, 1115, 903, 1246, 1244, 231, + 489, 698, 479, 480, 697, 1117, 695, 1415, 1412, 1383, + 1112, 827, 1375, 887, 1436, 455, 1329, 1041, 1043, 456, + 444, 195, 1109, 1432, 206, 1118, 889, 206, 1111, 1331, + 702, 490, 611, 206, 688, 1188, 794, 889, 696, 206, + 699, 1337, 81, 889, 81, 1187, 81, 81, 1116, 81, + 472, 81, 474, 1186, 440, 438, 447, 81, 208, 1100, + 1364, 196, 947, 468, 475, 946, 476, 477, 203, 478, + 1266, 481, 1068, 553, 554, 859, 1124, 492, 998, 870, + 1051, 1008, 471, 473, 194, 975, 734, 81, 1098, 620, + 521, 462, 541, 731, 1042, 1211, 200, 1330, 531, 324, + 769, 541, 506, 467, 439, 467, 441, 467, 467, 70, + 467, 452, 467, 505, 767, 768, 766, 728, 467, 516, + 493, 494, 888, 1358, 1110, 903, 1108, 885, 883, 1430, + 884, 333, 1431, 888, 1429, 881, 887, 438, 51, 888, + 515, 514, 1338, 1336, 256, 71, 1212, 724, 1373, 1390, + 206, 206, 206, 550, 995, 1099, 552, 516, 1346, 81, + 1104, 1101, 1094, 1102, 1097, 81, 955, 469, 1095, 1096, + 436, 1176, 628, 1156, 449, 814, 450, 1138, 604, 451, + 553, 554, 1103, 814, 563, 1005, 567, 568, 569, 570, 571, 572, 573, 574, 575, 507, 578, 581, 581, 581, 587, 581, 581, 587, 581, 595, 596, 597, 598, 599, - 600, 70, 610, 582, 584, 586, 588, 590, 592, 593, - 732, 936, 458, 459, 460, 618, 448, 725, 814, 454, - 613, 443, 553, 554, 622, 461, 938, 515, 514, 583, - 585, 463, 589, 591, 1099, 594, 814, 71, 1005, 1104, - 1101, 1094, 1102, 1097, 516, 690, 954, 1095, 1096, 532, - 533, 534, 535, 536, 537, 538, 531, 206, 514, 541, - 994, 1103, 81, 972, 973, 974, 769, 206, 206, 81, - 737, 738, 892, 206, 516, 1073, 206, 1378, 893, 206, - 767, 768, 766, 206, 511, 81, 81, 1437, 1396, 1292, - 81, 81, 81, 206, 81, 81, 515, 514, 445, 446, - 81, 81, 475, 1158, 476, 477, 54, 478, 192, 481, - 515, 514, 993, 516, 992, 492, 765, 1291, 515, 514, - 515, 514, 786, 467, 787, 711, 1438, 516, 1088, 81, - 467, 515, 514, 206, 1087, 516, 1076, 516, 1057, 81, - 1058, 1398, 603, 22, 612, 1374, 467, 467, 516, 818, - 1310, 467, 467, 467, 703, 467, 467, 739, 752, 754, - 755, 467, 467, 1289, 753, 292, 1121, 1085, 958, 1334, - 1414, 496, 763, 319, 320, 1371, 758, 500, 504, 1400, - 496, 1334, 1386, 81, 760, 333, 283, 282, 285, 286, - 287, 288, 1334, 496, 522, 284, 289, 79, 1228, 804, - 807, 741, 1068, 245, 1063, 815, 1334, 1365, 1343, 756, - 1334, 1333, 1281, 1280, 1268, 496, 81, 81, 1265, 496, - 1218, 1217, 1342, 206, 1214, 1215, 1214, 1213, 1208, 566, - 788, 206, 206, 335, 51, 206, 206, 24, 577, 206, - 206, 206, 81, 789, 790, 987, 496, 830, 496, 567, - 797, 496, 54, 708, 707, 81, 854, 691, 689, 636, - 856, 1017, 811, 686, 616, 1018, 635, 634, 890, 692, - 693, 616, 464, 823, 457, 700, 24, 1163, 324, 1175, - 1175, 706, 829, 711, 1127, 54, 1406, 799, 904, 905, - 906, 1047, 845, 852, 797, 717, 610, 1047, 58, 1261, - 610, 860, 861, 24, 1315, 857, 617, 830, 619, 206, - 81, 877, 81, 617, 1345, 615, 81, 81, 206, 206, - 206, 830, 206, 206, 54, 1298, 206, 81, 987, 918, - 687, 853, 1216, 615, 830, 748, 1059, 694, 987, 862, - 1175, 1011, 1010, 206, 987, 206, 206, 615, 621, 735, - 206, 54, 897, 712, 713, 701, 1273, 917, 714, 715, - 716, 496, 718, 719, 1204, 1062, 914, 915, 720, 721, - 247, 467, 913, 467, 1179, 1180, 1114, 335, 759, 335, - 908, 335, 335, 907, 335, 1299, 335, 920, 467, 963, - 495, 1423, 335, 1419, 1206, 1182, 1163, 760, 530, 529, - 539, 540, 532, 533, 534, 535, 536, 537, 538, 531, - 1089, 965, 541, 964, 763, 729, 1034, 705, 54, 1032, - 1185, 1035, 519, 726, 1033, 828, 1036, 1184, 839, 840, - 898, 899, 900, 901, 747, 1031, 1030, 1410, 855, 977, - 1403, 976, 251, 252, 1123, 960, 909, 910, 911, 749, - 750, 206, 206, 206, 206, 206, 1024, 510, 1408, 794, - 970, 969, 1080, 206, 498, 633, 206, 465, 1072, 1380, - 206, 1379, 508, 1259, 206, 1313, 499, 269, 333, 1070, - 1064, 1294, 260, 1004, 923, 704, 843, 248, 249, 510, - 242, 874, 1351, 81, 335, 1048, 968, 243, 1026, 1027, - 630, 1029, 566, 1060, 967, 802, 803, 1037, 1020, 1021, - 58, 921, 610, 610, 610, 610, 610, 1350, 1301, 1047, - 943, 944, 945, 1045, 948, 949, 488, 845, 950, 1044, - 1052, 1049, 999, 1050, 996, 610, 1025, 1077, 1078, 1028, - 1069, 81, 81, 1425, 1424, 952, 1019, 1079, 722, 1081, - 1082, 1083, 959, 512, 1065, 1066, 1425, 1361, 1287, 730, - 60, 62, 55, 868, 1, 799, 1417, 1227, 1295, 929, - 1381, 81, 1327, 1086, 1198, 880, 871, 69, 922, 435, - 924, 68, 1372, 879, 878, 1335, 1285, 206, 891, 1105, - 1074, 759, 894, 1205, 1071, 951, 81, 1377, 835, 838, - 839, 840, 836, 467, 837, 841, 641, 335, 1179, 1180, - 1092, 639, 640, 638, 335, 643, 1120, 539, 540, 532, - 533, 534, 535, 536, 537, 538, 531, 642, 637, 541, - 335, 335, 467, 219, 328, 335, 335, 335, 842, 335, - 335, 81, 81, 1164, 1024, 335, 335, 1131, 1136, 1155, - 1149, 1130, 1148, 629, 919, 513, 740, 72, 1107, 1106, - 925, 727, 482, 963, 483, 81, 1167, 961, 962, 221, - 504, 760, 549, 966, 743, 1053, 334, 1170, 736, 502, - 81, 1349, 81, 81, 519, 1300, 1183, 335, 1003, 576, - 812, 268, 1197, 1190, 751, 1189, 281, 278, 279, 1174, - 1168, 742, 51, 1016, 523, 266, 258, 608, 601, 1196, - 206, 834, 1201, 832, 796, 798, 831, 323, 1181, 1202, - 1203, 1177, 1209, 1210, 607, 1192, 1126, 206, 791, 874, - 1254, 1356, 988, 81, 746, 26, 81, 81, 81, 206, - 1169, 59, 551, 253, 816, 81, 19, 18, 206, 1006, - 17, 20, 16, 555, 556, 557, 558, 559, 560, 561, - 562, 820, 821, 15, 14, 453, 1233, 30, 21, 1235, - 835, 838, 839, 840, 836, 13, 837, 841, 1220, 12, - 11, 10, 9, 8, 7, 6, 1242, 335, 5, 1125, - 1221, 4, 1223, 244, 23, 2, 0, 0, 609, 0, - 335, 0, 1024, 1234, 0, 1260, 0, 0, 0, 610, - 1091, 0, 0, 0, 0, 1270, 0, 81, 0, 0, - 0, 1269, 0, 0, 0, 81, 0, 1060, 0, 0, - 0, 0, 1129, 0, 0, 0, 1253, 0, 0, 1119, - 81, 0, 1279, 0, 0, 0, 0, 81, 0, 0, - 0, 0, 1288, 0, 1290, 335, 0, 335, 0, 0, - 0, 941, 942, 0, 0, 1159, 0, 0, 1275, 1276, - 1277, 0, 335, 0, 0, 0, 0, 0, 0, 1302, - 0, 0, 0, 0, 0, 0, 81, 81, 0, 81, - 1122, 0, 0, 0, 81, 0, 81, 81, 81, 206, - 335, 467, 81, 1322, 1314, 1323, 1324, 1325, 0, 1167, - 0, 0, 1219, 0, 0, 1326, 874, 1332, 874, 81, - 206, 1321, 1339, 0, 1239, 1240, 0, 1241, 1347, 1222, - 1243, 0, 1245, 1340, 0, 1341, 0, 0, 984, 0, + 600, 514, 610, 690, 1140, 458, 459, 460, 551, 582, + 584, 586, 588, 590, 592, 593, 448, 516, 725, 454, + 613, 443, 1073, 1378, 618, 461, 733, 1437, 622, 583, + 585, 463, 589, 591, 954, 594, 1396, 994, 1142, 892, + 1146, 993, 1141, 992, 1139, 893, 553, 554, 511, 1144, + 1292, 534, 535, 536, 537, 538, 531, 206, 1143, 541, + 515, 514, 81, 732, 609, 1291, 1438, 206, 206, 81, + 1088, 1145, 1147, 206, 54, 192, 206, 516, 1087, 206, + 515, 514, 687, 206, 765, 81, 81, 515, 514, 694, + 81, 81, 81, 206, 81, 81, 1076, 516, 445, 446, + 81, 81, 515, 514, 516, 712, 713, 1371, 1398, 1158, + 714, 715, 716, 1374, 718, 719, 752, 754, 755, 516, + 720, 721, 753, 467, 1310, 711, 737, 738, 22, 81, + 467, 1289, 1121, 206, 972, 973, 974, 1085, 958, 81, + 319, 320, 603, 1228, 612, 739, 467, 467, 786, 818, + 787, 467, 467, 467, 703, 467, 467, 1057, 1068, 1058, + 1063, 467, 467, 1334, 1414, 292, 532, 533, 534, 535, + 536, 537, 538, 531, 515, 514, 541, 500, 504, 763, + 1400, 496, 333, 81, 760, 758, 1334, 1386, 245, 1334, + 496, 516, 1334, 1365, 522, 1334, 1333, 79, 788, 804, + 807, 1281, 1280, 496, 741, 815, 1268, 496, 1265, 496, + 1218, 1217, 1343, 799, 756, 708, 81, 81, 1214, 1215, + 1214, 1213, 1342, 206, 987, 496, 830, 496, 1208, 566, + 707, 206, 206, 335, 51, 206, 206, 691, 577, 206, + 206, 206, 81, 689, 789, 790, 797, 496, 890, 567, + 835, 838, 839, 840, 836, 81, 837, 841, 686, 636, + 1179, 1180, 854, 464, 635, 634, 856, 811, 764, 692, + 693, 457, 1047, 823, 1163, 700, 1175, 1175, 324, 797, + 1261, 706, 1047, 711, 1127, 1345, 24, 616, 898, 899, + 900, 901, 845, 58, 24, 717, 610, 616, 830, 852, + 610, 904, 905, 906, 909, 910, 911, 1216, 861, 206, + 81, 860, 81, 857, 1315, 830, 206, 206, 206, 206, + 206, 877, 206, 206, 24, 1175, 206, 81, 987, 617, + 922, 619, 924, 987, 54, 748, 918, 1059, 853, 617, + 615, 615, 54, 206, 829, 206, 206, 951, 1017, 862, + 206, 1011, 1018, 1010, 609, 987, 615, 621, 609, 735, + 701, 54, 609, 1406, 1298, 1114, 914, 915, 1299, 830, + 897, 467, 54, 467, 1273, 759, 917, 335, 1204, 335, + 1062, 335, 335, 913, 335, 908, 335, 920, 467, 907, + 495, 247, 335, 1179, 1180, 800, 801, 760, 963, 806, + 809, 810, 1423, 1419, 530, 529, 539, 540, 532, 533, + 534, 535, 536, 537, 538, 531, 964, 1206, 541, 965, + 1182, 763, 519, 726, 822, 828, 824, 825, 539, 540, + 532, 533, 534, 535, 536, 537, 538, 531, 855, 54, + 541, 976, 1163, 1089, 729, 977, 705, 747, 1185, 749, + 750, 206, 206, 206, 206, 206, 1024, 982, 835, 838, + 839, 840, 836, 206, 837, 841, 206, 1184, 1034, 1031, + 206, 1030, 1019, 1035, 206, 333, 283, 282, 285, 286, + 287, 288, 260, 1410, 1032, 284, 289, 1403, 874, 1033, + 1004, 799, 960, 81, 335, 1036, 1123, 839, 840, 1408, + 630, 1048, 566, 1060, 970, 802, 803, 969, 1020, 1021, + 764, 921, 610, 610, 610, 610, 610, 1037, 941, 942, + 943, 944, 945, 1045, 948, 949, 498, 845, 950, 1044, + 1052, 1049, 1080, 1050, 633, 610, 1026, 1027, 499, 1029, + 1025, 81, 81, 1028, 1079, 952, 1081, 1082, 1083, 510, + 1077, 1078, 959, 251, 252, 1069, 1065, 1066, 1380, 465, + 1072, 1379, 1091, 868, 508, 1313, 1070, 1064, 1259, 1294, + 923, 81, 704, 971, 609, 609, 609, 609, 609, 1086, + 843, 248, 249, 510, 968, 242, 1351, 206, 759, 609, + 243, 1119, 967, 58, 1105, 1350, 81, 609, 1092, 1301, + 1047, 488, 999, 467, 1425, 1424, 60, 335, 996, 722, + 512, 1425, 1361, 1287, 335, 730, 62, 55, 1120, 1, + 986, 1417, 1227, 1295, 929, 1381, 1327, 1198, 880, 871, + 335, 335, 467, 69, 435, 335, 335, 335, 1002, 335, + 335, 81, 81, 1164, 1024, 335, 335, 68, 1131, 1372, + 1149, 1130, 1136, 879, 878, 1148, 740, 1335, 1285, 891, + 1074, 1155, 894, 1205, 1071, 81, 1169, 961, 962, 1377, + 504, 760, 963, 1167, 743, 641, 639, 640, 638, 643, + 81, 642, 81, 81, 519, 637, 219, 335, 328, 1183, + 842, 629, 1197, 919, 513, 72, 1107, 1106, 1189, 1174, + 1168, 925, 51, 727, 482, 1190, 483, 221, 549, 966, + 206, 1053, 334, 1201, 796, 798, 1170, 1196, 736, 1209, + 1210, 502, 1349, 1300, 1003, 1192, 874, 206, 791, 576, + 812, 268, 988, 81, 1202, 1203, 81, 81, 81, 206, + 751, 281, 278, 279, 816, 81, 742, 1016, 206, 1006, + 523, 266, 258, 555, 556, 557, 558, 559, 560, 561, + 562, 820, 821, 608, 601, 1233, 1220, 834, 832, 831, + 323, 1181, 1177, 607, 1126, 1235, 1254, 1356, 1221, 746, + 1223, 26, 1239, 1240, 59, 1241, 253, 335, 1243, 1125, + 1245, 19, 18, 1242, 17, 20, 16, 15, 14, 453, + 335, 30, 1024, 1234, 21, 13, 12, 11, 10, 610, + 9, 8, 1270, 1260, 7, 6, 5, 81, 4, 244, + 23, 2, 0, 0, 0, 81, 0, 1060, 0, 1129, + 1279, 0, 0, 1269, 0, 0, 1253, 496, 0, 0, + 81, 0, 0, 0, 1282, 0, 0, 81, 0, 0, + 0, 0, 0, 0, 0, 335, 0, 335, 0, 0, + 1293, 0, 1159, 0, 0, 1288, 0, 1290, 1275, 1276, + 1277, 609, 335, 0, 530, 529, 539, 540, 532, 533, + 534, 535, 536, 537, 538, 531, 81, 81, 541, 81, + 1122, 0, 1302, 0, 81, 0, 81, 81, 81, 206, + 335, 467, 81, 1322, 1314, 1323, 1324, 1325, 0, 1321, + 1316, 0, 1219, 874, 1332, 874, 1167, 1326, 0, 81, + 206, 0, 0, 1339, 0, 0, 0, 0, 1347, 1222, + 1340, 0, 1341, 0, 0, 0, 0, 0, 984, 0, 1157, 1232, 985, 1168, 1362, 0, 1317, 0, 0, 989, 990, 991, 0, 0, 0, 81, 997, 0, 1369, 1000, - 1001, 1370, 0, 1167, 0, 1007, 81, 81, 0, 1009, - 0, 0, 1012, 1013, 1014, 1015, 1344, 1385, 1384, 1388, - 0, 1129, 1191, 0, 1316, 81, 1282, 1393, 1024, 0, + 1001, 1370, 0, 1363, 0, 1007, 81, 81, 0, 1009, + 1167, 0, 1012, 1013, 1014, 1015, 1344, 1385, 1129, 1388, + 1384, 0, 1191, 0, 0, 81, 0, 1393, 1024, 0, 0, 0, 0, 0, 1039, 816, 206, 1168, 0, 51, - 0, 0, 764, 0, 81, 0, 761, 0, 0, 770, + 0, 0, 0, 0, 81, 0, 761, 0, 0, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, - 781, 782, 783, 784, 1402, 1407, 1409, 81, 800, 801, - 0, 0, 806, 809, 810, 0, 1411, 1363, 335, 0, + 781, 782, 783, 784, 1402, 1407, 1409, 81, 0, 0, + 0, 1132, 0, 0, 0, 0, 1411, 0, 335, 0, 1422, 0, 0, 0, 0, 0, 0, 1433, 0, 0, - 0, 0, 0, 874, 0, 0, 0, 822, 0, 824, - 825, 0, 0, 0, 819, 530, 529, 539, 540, 532, - 533, 534, 535, 536, 537, 538, 531, 0, 0, 541, - 0, 0, 0, 1297, 0, 0, 1090, 335, 609, 0, - 0, 0, 609, 1256, 0, 0, 609, 1420, 501, 0, - 0, 0, 0, 566, 1258, 0, 0, 0, 1293, 0, - 0, 1271, 0, 0, 1272, 0, 335, 1274, 982, 0, - 0, 0, 1348, 0, 0, 0, 0, 0, 0, 0, + 874, 530, 529, 539, 540, 532, 533, 534, 535, 536, + 537, 538, 531, 0, 819, 541, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 935, 0, 0, 0, + 1297, 24, 25, 52, 27, 28, 1090, 335, 0, 0, + 934, 0, 0, 1256, 0, 0, 0, 1420, 501, 0, + 43, 0, 0, 566, 1258, 29, 48, 49, 0, 0, + 0, 1271, 0, 0, 1272, 0, 335, 1274, 939, 0, + 0, 0, 1348, 0, 0, 38, 0, 933, 0, 54, 0, 0, 0, 0, 204, 0, 1135, 230, 0, 0, 0, 335, 530, 529, 539, 540, 532, 533, 534, 535, 536, 537, 538, 531, 0, 0, 541, 0, 0, 0, 0, 0, 257, 0, 0, 326, 0, 0, 0, 0, - 204, 0, 204, 0, 335, 0, 0, 0, 0, 0, - 0, 0, 0, 816, 0, 0, 1171, 1173, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1397, 0, - 0, 0, 1297, 874, 0, 0, 971, 0, 0, 0, - 1173, 0, 0, 0, 216, 0, 0, 24, 25, 52, - 27, 28, 0, 0, 0, 335, 0, 335, 1200, 0, - 0, 0, 0, 0, 0, 0, 43, 0, 226, 0, - 0, 29, 48, 49, 764, 0, 0, 0, 0, 0, - 978, 979, 980, 986, 0, 0, 0, 0, 0, 0, - 0, 38, 0, 0, 0, 54, 0, 0, 0, 0, - 0, 1002, 0, 0, 0, 0, 0, 0, 1224, 0, - 1236, 1229, 1230, 1231, 0, 1387, 566, 1238, 0, 209, - 335, 0, 204, 0, 0, 204, 212, 0, 1247, 1248, - 0, 204, 0, 0, 220, 215, 0, 204, 609, 609, - 609, 609, 609, 0, 0, 0, 0, 0, 1262, 1263, - 1264, 0, 1267, 609, 0, 0, 31, 32, 34, 33, - 36, 609, 50, 0, 0, 0, 218, 0, 0, 1278, - 0, 816, 225, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 37, 44, 45, 0, 0, 46, 47, - 35, 0, 335, 0, 0, 0, 0, 0, 0, 210, - 1284, 0, 0, 0, 39, 40, 0, 41, 42, 0, - 0, 0, 0, 0, 0, 335, 0, 0, 0, 0, - 0, 0, 335, 0, 0, 0, 222, 213, 0, 223, - 224, 229, 0, 0, 1309, 214, 217, 0, 211, 228, - 227, 0, 0, 0, 0, 0, 0, 0, 204, 204, - 204, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 204, 0, 204, 0, 335, 0, 0, 930, 927, 928, + 0, 926, 0, 816, 0, 0, 1171, 1173, 0, 0, + 31, 32, 34, 33, 36, 0, 50, 0, 1397, 1297, + 874, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1173, 0, 937, 940, 0, 1257, 0, 37, 44, 45, + 0, 0, 46, 47, 35, 335, 0, 335, 1200, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 39, 40, + 0, 41, 42, 0, 0, 0, 0, 0, 0, 932, + 978, 979, 980, 530, 529, 539, 540, 532, 533, 534, + 535, 536, 537, 538, 531, 0, 0, 541, 1252, 0, + 0, 931, 0, 0, 0, 0, 0, 0, 1224, 0, + 1236, 1229, 1230, 1231, 0, 1387, 566, 1238, 0, 0, + 335, 0, 204, 0, 0, 204, 0, 0, 1247, 1248, + 0, 204, 0, 0, 0, 0, 983, 204, 0, 0, + 936, 0, 0, 0, 0, 0, 0, 0, 1262, 1263, + 1264, 0, 1267, 53, 0, 938, 530, 529, 539, 540, + 532, 533, 534, 535, 536, 537, 538, 531, 0, 1278, + 541, 816, 530, 529, 539, 540, 532, 533, 534, 535, + 536, 537, 538, 531, 0, 0, 541, 0, 0, 0, + 0, 0, 335, 0, 0, 0, 0, 0, 0, 0, + 1284, 0, 530, 529, 539, 540, 532, 533, 534, 535, + 536, 537, 538, 531, 0, 335, 541, 0, 0, 0, + 0, 0, 335, 0, 0, 0, 0, 0, 0, 0, + 0, 216, 0, 0, 1309, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 204, 204, + 204, 0, 0, 0, 0, 226, 0, 0, 0, 0, 0, 1318, 1319, 0, 1320, 0, 0, 0, 0, 1284, 0, 1284, 1284, 1284, 0, 0, 0, 1200, 0, 0, - 0, 0, 0, 0, 1352, 1353, 1354, 1355, 0, 53, + 0, 0, 0, 0, 1352, 1353, 1354, 1355, 0, 0, 0, 1359, 1360, 0, 1284, 1133, 1134, 0, 0, 0, - 0, 0, 0, 1366, 1367, 1368, 1257, 0, 1150, 1151, - 0, 1152, 1153, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1160, 1161, 0, 0, 0, 0, 0, - 1376, 0, 0, 0, 1252, 0, 1389, 0, 0, 0, - 0, 335, 335, 1394, 530, 529, 539, 540, 532, 533, - 534, 535, 536, 537, 538, 531, 0, 816, 541, 0, + 0, 0, 0, 1366, 1367, 1368, 209, 0, 1150, 1151, + 0, 1152, 1153, 212, 0, 0, 0, 0, 0, 0, + 0, 220, 215, 1160, 1161, 0, 0, 0, 0, 0, + 1376, 0, 0, 0, 0, 0, 1389, 0, 0, 0, + 0, 335, 335, 1394, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 218, 0, 0, 0, 816, 0, 225, 1395, 1399, 0, 0, 0, 204, 0, 0, 0, 0, 0, 0, 0, 0, 0, 204, 204, 0, 0, 1401, - 0, 204, 0, 0, 204, 1207, 0, 204, 0, 0, + 0, 204, 0, 0, 204, 1207, 210, 204, 0, 0, 0, 710, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 204, 1284, 1132, 0, 1251, 1434, 1435, 530, 529, - 539, 540, 532, 533, 534, 535, 536, 537, 538, 531, - 0, 0, 541, 530, 529, 539, 540, 532, 533, 534, - 535, 536, 537, 538, 531, 609, 658, 541, 0, 0, + 0, 204, 1284, 0, 0, 1251, 1434, 1435, 0, 0, + 0, 0, 0, 222, 213, 0, 223, 224, 229, 0, + 0, 0, 214, 217, 0, 211, 228, 227, 0, 0, + 0, 0, 0, 0, 0, 658, 0, 0, 0, 0, 0, 204, 0, 0, 525, 1237, 528, 0, 0, 0, 710, 0, 542, 543, 544, 545, 546, 547, 548, 0, 526, 527, 524, 530, 529, 539, 540, 532, 533, 534, @@ -915,31 +915,31 @@ var yyAct = [...]int{ 529, 539, 540, 532, 533, 534, 535, 536, 537, 538, 531, 0, 257, 541, 0, 0, 0, 257, 257, 0, 0, 257, 257, 257, 0, 0, 0, 817, 0, 0, - 0, 0, 0, 0, 646, 0, 0, 0, 0, 0, + 0, 0, 0, 646, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 257, 257, 257, 257, 0, 204, 0, 0, 0, 0, 0, 0, 0, 204, 850, 0, 0, 204, 204, 0, 0, 204, 858, 710, - 0, 659, 0, 0, 0, 0, 0, 0, 0, 0, + 659, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1250, 1304, 1305, 1306, 1307, 1308, 0, 0, 0, - 1311, 1312, 0, 0, 672, 675, 676, 677, 678, 679, - 680, 0, 681, 682, 683, 684, 685, 660, 661, 662, - 663, 644, 645, 673, 0, 647, 0, 648, 649, 650, - 651, 652, 653, 654, 655, 656, 657, 664, 665, 666, - 667, 668, 669, 670, 671, 0, 0, 204, 1249, 0, - 0, 0, 0, 0, 0, 0, 204, 204, 204, 0, + 1311, 1312, 0, 672, 675, 676, 677, 678, 679, 680, + 0, 681, 682, 683, 684, 685, 660, 661, 662, 663, + 644, 645, 673, 0, 647, 0, 648, 649, 650, 651, + 652, 653, 654, 655, 656, 657, 664, 665, 666, 667, + 668, 669, 670, 671, 0, 0, 0, 204, 1249, 0, + 0, 0, 0, 0, 204, 204, 204, 204, 204, 0, 204, 204, 0, 0, 204, 530, 529, 539, 540, 532, 533, 534, 535, 536, 537, 538, 531, 0, 0, 541, 0, 204, 0, 956, 957, 0, 0, 0, 204, 0, - 0, 0, 0, 710, 0, 674, 0, 0, 0, 139, + 0, 0, 0, 710, 674, 0, 0, 0, 0, 139, 0, 0, 0, 849, 0, 257, 0, 0, 103, 0, 0, 0, 0, 0, 120, 0, 122, 0, 0, 160, 131, 0, 530, 529, 539, 540, 532, 533, 534, 535, 536, 537, 538, 531, 0, 0, 541, 0, 205, 0, 851, 0, 0, 0, 0, 0, 0, 96, 0, 0, - 0, 983, 257, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 257, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1426, 0, 0, 0, 0, 0, 0, - 257, 530, 529, 539, 540, 532, 533, 534, 535, 536, - 537, 538, 531, 0, 0, 541, 0, 0, 817, 204, + 257, 529, 539, 540, 532, 533, 534, 535, 536, 537, + 538, 531, 0, 0, 541, 0, 0, 0, 817, 204, 204, 204, 204, 204, 0, 0, 0, 0, 0, 0, 0, 1038, 109, 0, 204, 0, 207, 0, 850, 0, 0, 146, 204, 163, 111, 119, 83, 90, 0, 110, @@ -955,18 +955,18 @@ var yyAct = [...]int{ 158, 117, 124, 149, 189, 140, 154, 98, 177, 159, 0, 0, 0, 0, 0, 204, 0, 0, 0, 0, 0, 0, 0, 0, 0, 257, 0, 0, 0, 82, - 89, 121, 188, 148, 106, 179, 257, 530, 529, 539, - 540, 532, 533, 534, 535, 536, 537, 538, 531, 0, - 0, 541, 0, 0, 0, 0, 0, 710, 0, 0, + 89, 121, 188, 148, 106, 179, 257, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 710, 0, 0, 0, 0, 0, 0, 0, 0, 817, 139, 0, 0, 0, 0, 264, 0, 0, 0, 103, 0, 261, 0, 0, 0, 120, 304, 122, 0, 0, 160, 131, 0, 0, 0, 0, 295, 296, 0, 0, 0, 0, 0, 0, 866, 0, 54, 0, 0, 262, 283, 282, 285, 286, 287, 288, 0, 0, 96, 284, 289, 290, 291, - 867, 0, 0, 259, 276, 0, 303, 529, 539, 540, - 532, 533, 534, 535, 536, 537, 538, 531, 204, 0, - 541, 0, 0, 0, 0, 0, 273, 274, 0, 0, + 867, 0, 0, 259, 276, 0, 303, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 204, 0, + 0, 0, 0, 0, 0, 0, 273, 274, 0, 0, 0, 0, 317, 0, 275, 204, 0, 270, 271, 272, 277, 0, 0, 0, 0, 0, 0, 204, 0, 0, 109, 0, 0, 0, 207, 0, 204, 315, 0, 146, @@ -1957,14 +1957,14 @@ var yyAct = [...]int{ } var yyPact = [...]int{ - 1591, -1000, -188, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + 1455, -1000, -184, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, 875, 935, -1000, -1000, -1000, -1000, -1000, -1000, - 327, 8842, 31, 118, 9, 11470, 116, 1561, 11946, -1000, - 2, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -62, -67, - -1000, 677, -1000, -1000, -1000, -1000, -1000, 853, 861, 744, - 847, 782, -1000, 6380, 74, 74, 11232, 5639, -1000, -1000, - 255, 11946, 110, 11946, -140, 67, 67, 67, -1000, -1000, + -1000, -1000, 958, 981, -1000, -1000, -1000, -1000, -1000, -1000, + 225, 8842, 35, 108, 26, 11470, 105, 1748, 11946, -1000, + 4, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -62, -64, + -1000, 668, -1000, -1000, -1000, -1000, -1000, 948, 954, 765, + 941, 893, -1000, 6380, 64, 64, 11232, 5639, -1000, -1000, + 250, 11946, 100, 11946, -136, 62, 62, 62, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, @@ -1976,21 +1976,21 @@ 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, 114, 11946, 190, -1000, 11946, 65, 597, 65, - 65, 65, 11946, -1000, 169, -1000, -1000, -1000, 11946, 595, - 817, 3299, 73, 3299, -1000, 3299, 3299, -1000, 3299, 14, - 3299, -69, 894, 10, 1, -1000, 3299, -1000, -1000, -1000, + -1000, -1000, 103, 11946, 229, -1000, 11946, 61, 594, 61, + 61, 61, 11946, -1000, 149, -1000, -1000, -1000, 11946, 586, + 909, 3299, 97, 3299, -1000, 3299, 3299, -1000, 3299, 13, + 3299, -65, 969, 10, -16, -1000, 3299, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - 495, 825, 7369, 7369, 875, -1000, 677, -1000, -1000, -1000, - 816, -1000, -1000, 399, 922, -1000, 8604, 167, -1000, 7369, - 1920, 578, -1000, -1000, 578, -1000, -1000, 131, -1000, -1000, + 527, 887, 7369, 7369, 958, -1000, 668, -1000, -1000, -1000, + 908, -1000, -1000, 363, 979, -1000, 8604, 148, -1000, 7369, + 1920, 687, -1000, -1000, 687, -1000, -1000, 130, -1000, -1000, 8110, 8110, 8110, 8110, 8110, 8110, 8110, 8110, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, 578, -1000, 7122, 578, 578, 578, 578, 578, - 578, 578, 578, 7369, 578, 578, 578, 578, 578, 578, - 578, 578, 578, 578, 578, 578, 578, 578, 578, 10994, - 10279, 11946, 640, 633, -1000, -1000, 158, 673, 5379, -116, - -1000, -1000, -1000, 269, 10041, -1000, -1000, -1000, 815, -1000, + -1000, -1000, 687, -1000, 7122, 687, 687, 687, 687, 687, + 687, 687, 687, 7369, 687, 687, 687, 687, 687, 687, + 687, 687, 687, 687, 687, 687, 687, 687, 687, 10994, + 10279, 11946, 666, 656, -1000, -1000, 147, 682, 5379, -112, + -1000, -1000, -1000, 260, 10041, -1000, -1000, -1000, 884, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, @@ -2000,130 +2000,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, -1000, -1000, 591, 11946, -1000, 1956, -1000, - 586, 3299, 75, 581, 351, 580, 11946, 11946, 3299, 20, - 53, 49, 11946, 680, 80, 11946, 842, 745, 11946, 577, - 576, -1000, 5119, -1000, 3299, 3299, -1000, -1000, -1000, 3299, + -1000, -1000, -1000, -1000, -1000, 589, 11946, -1000, 1955, -1000, + 581, 3299, 79, 566, 309, 560, 11946, 11946, 3299, 19, + 51, 48, 11946, 685, 74, 11946, 929, 774, 11946, 553, + 538, -1000, 5119, -1000, 3299, 3299, -1000, -1000, -1000, 3299, 3299, 3299, 11946, 3299, 3299, -1000, -1000, -1000, -1000, 3299, - 3299, -1000, 917, 305, -1000, -1000, -1000, -1000, 7369, 208, - -1000, 743, -1000, -1000, -1000, -1000, -1000, -1000, 930, 197, - 335, 155, 674, -1000, 426, 853, 495, 782, 9803, 771, - -1000, -1000, 11946, -1000, 7369, 7369, 470, -1000, 10755, -1000, - -1000, 4079, 217, 8110, 432, 370, 8110, 8110, 8110, 8110, + 3299, -1000, 978, 306, -1000, -1000, -1000, -1000, 7369, 197, + -1000, 772, -1000, -1000, -1000, -1000, -1000, -1000, 986, 171, + 388, 144, 684, -1000, 482, 948, 527, 893, 9803, 784, + -1000, -1000, 11946, -1000, 7369, 7369, 428, -1000, 10755, -1000, + -1000, 4079, 200, 8110, 400, 194, 8110, 8110, 8110, 8110, 8110, 8110, 8110, 8110, 8110, 8110, 8110, 8110, 8110, 8110, - 8110, 445, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - 553, -1000, 677, 508, 508, 179, 179, 179, 179, 179, - 179, 179, 8357, 5886, 495, 575, 428, 7122, 6380, 6380, - 7369, 7369, 6874, 6627, 6380, 848, 320, 428, 12184, -1000, - -1000, 7863, -1000, -1000, -1000, -1000, -1000, 495, -1000, -1000, + 8110, 471, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + 521, -1000, 668, 798, 798, 155, 155, 155, 155, 155, + 155, 155, 8357, 5886, 527, 571, 238, 7122, 6380, 6380, + 7369, 7369, 6874, 6627, 6380, 942, 267, 238, 12184, -1000, + -1000, 7863, -1000, -1000, -1000, -1000, -1000, 527, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 11708, 11708, 6380, 6380, 6380, - 6380, 32, 11946, -1000, 632, 1108, -1000, -1000, -1000, 844, - 9318, 9565, 32, 658, 10279, 11946, -1000, -1000, 10279, 11946, - 3819, 4859, 673, -116, 664, -1000, -89, -94, 2479, 178, - -1000, -1000, -1000, -1000, 3039, 195, 592, 384, -52, -1000, - -1000, -1000, 678, -1000, 678, 678, 678, 678, -22, -22, - -22, -22, -1000, -1000, -1000, -1000, -1000, 709, 706, -1000, - 678, 678, 678, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + 6380, 30, 11946, -1000, 694, 796, -1000, -1000, -1000, 938, + 9318, 9565, 30, 665, 10279, 11946, -1000, -1000, 10279, 11946, + 3819, 4859, 682, -112, 674, -1000, -90, -96, 2479, 142, + -1000, -1000, -1000, -1000, 3039, 168, 572, 351, -52, -1000, + -1000, -1000, 696, -1000, 696, 696, 696, 696, -22, -22, + -22, -22, -1000, -1000, -1000, -1000, -1000, 715, 711, -1000, + 696, 696, 696, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, 698, 698, 698, 683, 683, 714, -1000, 11946, 3299, - 841, 3299, -1000, 142, -1000, 11708, 11708, 11946, 11946, 11946, - 126, 11946, 11946, 672, -1000, 11946, 3299, -1000, -1000, -1000, + -1000, 709, 709, 709, 702, 702, 714, -1000, 11946, 3299, + 927, 3299, -1000, 1441, -1000, 11946, 11946, 11946, 11946, 11946, + 115, 11946, 11946, 681, -1000, 11946, 3299, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, 11946, 336, 11946, 11946, 428, -1000, 489, 11946, - -1000, 787, 7369, 7369, 4599, 7369, -1000, -1000, -1000, 825, - -1000, 848, 865, -1000, 807, 806, 6380, -1000, -1000, 217, - 365, -1000, -1000, 375, -1000, -1000, -1000, -1000, 154, 578, - -1000, 2374, -1000, -1000, -1000, -1000, 432, 8110, 8110, 8110, - 1352, 2374, 2198, 902, 2463, 179, 237, 237, 180, 180, - 180, 180, 180, 332, 332, -1000, -1000, -1000, 495, -1000, - -1000, -1000, 495, 6380, 669, -1000, -1000, 7369, -1000, 495, - 570, 570, 439, 418, 289, 903, 570, 236, 901, 570, - 570, 6380, 338, -1000, 7369, 495, -1000, 153, -1000, 685, - 667, 666, 570, 495, 570, 570, 611, 578, -1000, 12184, - 10279, 10279, 10279, 10279, 10279, -1000, 774, 773, -1000, 757, - 754, 764, 11946, -1000, 572, 9318, 137, 578, -1000, 10517, - -1000, -1000, 887, 10279, 659, -1000, 659, -1000, 151, -1000, - -1000, 664, -116, -97, -1000, -1000, -1000, -1000, 428, -1000, - 461, 661, 2779, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - 691, 527, -1000, 832, 207, 204, 525, 831, -1000, -1000, - -1000, 819, -1000, 387, -54, -1000, -1000, 456, -22, -22, - -1000, -1000, 178, 812, 178, 178, 178, 488, 488, -1000, - -1000, -1000, -1000, 454, -1000, -1000, -1000, 448, -1000, 738, - 11708, 3299, -1000, -1000, -1000, -1000, 290, 290, 185, -1000, + -1000, -1000, 11946, 324, 11946, 11946, 238, -1000, 459, 11946, + -1000, 834, 7369, 7369, 4599, 7369, -1000, -1000, -1000, 887, + -1000, 942, 953, -1000, 853, 850, 6380, -1000, -1000, 200, + 308, -1000, -1000, 446, -1000, -1000, -1000, -1000, 143, 687, + -1000, 1659, -1000, -1000, -1000, -1000, 400, 8110, 8110, 8110, + 691, 1659, 1613, 713, 2197, 155, 332, 332, 164, 164, + 164, 164, 164, 449, 449, -1000, -1000, -1000, 527, -1000, + -1000, -1000, 527, 6380, 680, -1000, -1000, 7369, -1000, 527, + 549, 549, 368, 395, 313, 977, 549, 237, 971, 549, + 549, 6380, 275, -1000, 7369, 527, -1000, 139, -1000, 1161, + 678, 676, 549, 527, 549, 549, 698, 687, -1000, 12184, + 10279, 10279, 10279, 10279, 10279, -1000, 809, 807, -1000, 822, + 806, 833, 11946, -1000, 551, 9318, 137, 687, -1000, 10517, + -1000, -1000, 968, 10279, 640, -1000, 640, -1000, 138, -1000, + -1000, 674, -112, -116, -1000, -1000, -1000, -1000, 238, -1000, + 480, 662, 2779, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + 706, 483, -1000, 919, 179, 185, 481, 918, -1000, -1000, + -1000, 911, -1000, 334, -55, -1000, -1000, 416, -22, -22, + -1000, -1000, 142, 882, 142, 142, 142, 458, 458, -1000, + -1000, -1000, -1000, 398, -1000, -1000, -1000, 390, -1000, 771, + 11708, 3299, -1000, -1000, -1000, -1000, 201, 201, 170, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - 30, 703, -1000, -1000, -1000, -1000, 5, 18, 79, -1000, - 3299, -1000, 305, -1000, 487, 7369, -1000, -1000, -1000, -1000, - 785, 428, 428, 144, -1000, -1000, 11946, -1000, -1000, -1000, - -1000, 653, -1000, -1000, -1000, 3559, 6380, -1000, 1352, 2374, - 1880, -1000, 8110, 8110, -1000, -1000, 570, 6380, 428, -1000, - -1000, -1000, 41, 445, 41, 8110, 8110, -1000, 8110, 8110, - -1000, -152, 663, 274, -1000, 7369, 404, -1000, 4599, -1000, - 8110, 8110, -1000, -1000, -1000, -1000, 724, 12184, 578, -1000, - 9080, 11708, 665, -1000, 261, 1108, 702, 723, 936, -1000, - -1000, -1000, -1000, 765, -1000, 758, -1000, -1000, -1000, -1000, - -1000, 109, 106, 101, 11708, -1000, 875, 7369, 659, -1000, - -1000, 193, -1000, -1000, -103, -118, -1000, -1000, -1000, 3039, - -1000, 3039, 11708, 46, -1000, 525, 525, -1000, -1000, -1000, - 690, 722, 8110, -1000, -1000, -1000, 552, 178, 178, -1000, - 226, -1000, -1000, -1000, 551, -1000, 549, 657, 545, 11946, + 29, 692, -1000, -1000, -1000, -1000, 8, 18, 69, -1000, + 3299, -1000, 306, -1000, 453, 7369, -1000, -1000, -1000, -1000, + 837, 238, 238, 134, -1000, -1000, 11946, -1000, -1000, -1000, + -1000, 653, -1000, -1000, -1000, 3559, 6380, -1000, 691, 1659, + 1338, -1000, 8110, 8110, -1000, -1000, 549, 6380, 238, -1000, + -1000, -1000, 239, 471, 239, 8110, 8110, -1000, 8110, 8110, + -1000, -148, 658, 262, -1000, 7369, 410, -1000, 4599, -1000, + 8110, 8110, -1000, -1000, -1000, -1000, 770, 12184, 687, -1000, + 9080, 11708, 650, -1000, 259, 796, 721, 748, 588, -1000, + -1000, -1000, -1000, 805, -1000, 786, -1000, -1000, -1000, -1000, + -1000, 99, 91, 81, 11708, -1000, 958, 7369, 640, -1000, + -1000, 146, -1000, -1000, -92, -122, -1000, -1000, -1000, 3039, + -1000, 3039, 11708, 45, -1000, 481, 481, -1000, -1000, -1000, + 704, 745, 8110, -1000, -1000, -1000, 552, 142, 142, -1000, + 208, -1000, -1000, -1000, 545, -1000, 543, 632, 535, 11946, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 11946, -1000, -1000, -1000, - -1000, -1000, 11708, -177, 521, 11708, 11708, 11708, 11946, -1000, - 336, -1000, 428, -1000, 4339, -1000, 887, 10279, -1000, -1000, - 495, -1000, 8110, 2374, 2374, -1000, -1000, 495, 678, 678, - -1000, 678, 683, -1000, 678, -4, 678, -5, 495, 495, - 2149, 2092, 1936, 1865, 578, -147, -1000, 428, 7369, -1000, - 1801, 1429, -1000, 826, 605, 624, -1000, -1000, 6133, 495, - 543, 139, 539, -1000, 875, 12184, 7369, -1000, -1000, 7369, - 682, -1000, 7369, -1000, -1000, -1000, 578, 578, 578, 539, - 853, 428, -1000, -1000, -1000, -1000, 2779, -1000, 537, -1000, - 678, -1000, -1000, -1000, 11708, -47, 929, 2374, -1000, -1000, - -1000, -1000, -1000, -22, 484, -22, 437, -1000, 409, 3299, - -1000, -1000, -1000, -1000, 835, -1000, 4339, -1000, -1000, 651, - 712, -1000, -1000, -1000, 885, 646, -1000, 2374, -1000, -1000, + -1000, -1000, 11708, -155, 466, 11708, 11708, 11708, 11946, -1000, + 324, -1000, 238, -1000, 4339, -1000, 968, 10279, -1000, -1000, + 527, -1000, 8110, 1659, 1659, -1000, -1000, 527, 696, 696, + -1000, 696, 702, -1000, 696, -5, 696, -6, 527, 527, + 2149, 2092, 1936, 1629, 687, -143, -1000, 238, 7369, -1000, + 1540, 1429, -1000, 921, 602, 605, -1000, -1000, 6133, 527, + 533, 128, 531, -1000, 958, 12184, 7369, -1000, -1000, 7369, + 700, -1000, 7369, -1000, -1000, -1000, 687, 687, 687, 531, + 948, 238, -1000, -1000, -1000, -1000, 2779, -1000, 526, -1000, + 696, -1000, -1000, -1000, 11708, -47, 984, 1659, -1000, -1000, + -1000, -1000, -1000, -22, 452, -22, 385, -1000, 370, 3299, + -1000, -1000, -1000, -1000, 923, -1000, 4339, -1000, -1000, 690, + 695, -1000, -1000, -1000, 966, 623, -1000, 1659, -1000, -1000, 107, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 8110, - 8110, 8110, 8110, 8110, 495, 471, 428, 8110, 8110, 827, - -1000, 578, -1000, -1000, 650, 11708, 11708, -1000, 11708, 853, - -1000, 428, 428, 11708, 428, 11708, 11708, 11708, 2201, -1000, - 138, 11708, -1000, 535, -1000, 161, -1000, -119, 178, -1000, - 178, 546, 532, -1000, 578, 639, -1000, 235, 11708, 11946, - 883, 856, -1000, -1000, 685, 685, 685, 685, -6, -1000, - -1000, 685, 685, 928, -1000, 578, -1000, 677, 136, -1000, - -1000, -1000, 531, 517, 517, 517, 137, 138, -1000, 498, - 215, 466, -1000, 42, 11708, 391, 823, -1000, 821, -1000, - -1000, -1000, -1000, -1000, 29, 4339, 3039, 506, -1000, -1000, - 7369, 7369, -1000, -1000, -1000, -1000, 495, 56, -180, -1000, - -1000, 12184, 624, 495, 11708, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, 408, -1000, -1000, 11946, -1000, -1000, 462, -1000, - -1000, 504, -1000, 11708, -1000, -1000, 703, 428, 619, -1000, - 781, -157, -183, 604, -1000, -1000, -1000, 612, -1000, -1000, - 29, 804, -177, -1000, 778, -1000, 11708, -1000, 26, -1000, - -178, 494, 24, -181, 721, 578, -184, 719, -1000, 914, - 7616, -1000, -1000, 927, 160, 160, 685, 495, -1000, -1000, - -1000, 50, 438, -1000, -1000, -1000, -1000, -1000, -1000, + 8110, 8110, 8110, 8110, 527, 445, 238, 8110, 8110, 917, + -1000, 687, -1000, -1000, 660, 11708, 11708, -1000, 11708, 948, + -1000, 238, 238, 11708, 238, 11708, 11708, 11708, 2201, -1000, + 133, 11708, -1000, 520, -1000, 183, -1000, -151, 142, -1000, + 142, 546, 536, -1000, 687, 610, -1000, 246, 11708, 11946, + 961, 950, -1000, -1000, 1161, 1161, 1161, 1161, 32, -1000, + -1000, 1161, 1161, 983, -1000, 687, -1000, 668, 118, -1000, + -1000, -1000, 517, 514, 514, 514, 137, 133, -1000, 430, + 236, 434, -1000, 42, 11708, 337, 913, -1000, 910, -1000, + -1000, -1000, -1000, -1000, 28, 4339, 3039, 511, -1000, -1000, + 7369, 7369, -1000, -1000, -1000, -1000, 527, 60, -175, -1000, + -1000, 12184, 605, 527, 11708, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, 356, -1000, -1000, 11946, -1000, -1000, 429, -1000, + -1000, 505, -1000, 11708, -1000, -1000, 692, 238, 604, -1000, + 828, -153, -178, 601, -1000, -1000, -1000, 689, -1000, -1000, + 28, 845, -155, -1000, 824, -1000, 11708, -1000, 25, -1000, + -160, 488, 23, -176, 731, 687, -180, 730, -1000, 975, + 7616, -1000, -1000, 982, 163, 163, 1161, 527, -1000, -1000, + -1000, 49, 378, -1000, -1000, -1000, -1000, -1000, -1000, } var yyPgo = [...]int{ - 0, 1175, 99, 523, 1174, 1173, 1171, 1168, 1165, 1164, - 1163, 1162, 1161, 1160, 1159, 1155, 1148, 1147, 1145, 1144, - 1143, 1132, 1131, 1130, 1127, 1126, 117, 1123, 1121, 1115, - 66, 1114, 73, 1111, 1110, 48, 839, 54, 40, 314, - 1106, 21, 85, 46, 1104, 37, 1101, 1098, 78, 1097, - 1096, 45, 1093, 1091, 202, 1088, 65, 1087, 11, 56, - 1086, 1085, 1084, 1083, 69, 862, 1081, 1078, 14, 1077, - 1076, 102, 1074, 52, 7, 8, 27, 22, 1071, 857, - 6, 1070, 50, 1069, 1068, 1065, 1061, 26, 1059, 57, - 1058, 31, 51, 1057, 9, 60, 30, 20, 5, 75, - 58, 1056, 19, 59, 47, 1055, 1053, 488, 1052, 1049, - 43, 1044, 1042, 25, 1041, 192, 401, 1040, 1039, 1038, - 1037, 42, 0, 545, 236, 70, 1035, 1034, 1033, 1478, - 34, 53, 16, 1018, 64, 268, 38, 1014, 1013, 35, - 1008, 1007, 995, 993, 992, 991, 986, 165, 977, 974, - 973, 18, 24, 972, 970, 63, 23, 968, 966, 965, - 44, 55, 964, 963, 49, 33, 962, 961, 959, 957, - 956, 29, 10, 955, 15, 954, 13, 952, 28, 950, - 4, 949, 12, 948, 3, 947, 17, 41, 1, 946, - 2, 944, 942, 61, 529, 71, 941, 76, + 0, 1201, 25, 508, 1200, 1199, 1198, 1196, 1195, 1194, + 1191, 1190, 1188, 1187, 1186, 1185, 1184, 1181, 1179, 1178, + 1177, 1176, 1175, 1174, 1172, 1171, 117, 1166, 1164, 1161, + 71, 1159, 76, 1157, 1156, 49, 206, 54, 44, 314, + 1154, 27, 89, 84, 1153, 40, 1152, 1151, 78, 1150, + 1149, 55, 1148, 1147, 202, 1144, 73, 1143, 11, 56, + 1132, 1131, 1130, 1127, 70, 862, 1126, 1123, 15, 1122, + 1121, 102, 1120, 58, 7, 8, 34, 22, 1111, 123, + 6, 1110, 57, 1109, 1104, 1103, 1102, 38, 1101, 60, + 1098, 19, 59, 1096, 9, 66, 33, 28, 5, 79, + 64, 1092, 16, 69, 47, 1091, 1089, 455, 1088, 1087, + 45, 1086, 1084, 24, 1083, 185, 401, 1081, 1077, 1076, + 1075, 42, 0, 545, 233, 75, 1074, 1073, 1071, 1478, + 43, 53, 18, 1070, 52, 20, 41, 1068, 1066, 35, + 1065, 1061, 1059, 1058, 1057, 1056, 1055, 23, 1049, 1044, + 1043, 31, 21, 1042, 1040, 63, 30, 1039, 1038, 1037, + 50, 65, 1034, 1033, 51, 48, 1029, 1027, 1014, 1013, + 1009, 37, 10, 1008, 12, 1007, 13, 1006, 29, 1005, + 4, 1004, 14, 1003, 3, 1002, 17, 46, 1, 1001, + 2, 999, 997, 61, 529, 80, 996, 82, } var yyR1 = [...]int{ @@ -2399,7 +2399,7 @@ var yyChk = [...]int{ -147, -147, -155, 54, -155, -155, -156, 54, -156, -127, 53, -54, -135, 23, -135, -117, 120, 117, 118, -181, 116, 210, 188, 66, 29, 15, 249, 151, 264, 57, - 152, -123, -123, -54, -54, -54, 120, 117, -54, -54, + 152, -54, -54, -54, -54, -54, 120, 117, -54, -54, -54, -135, -54, -113, 90, 12, -129, -129, 59, -54, 38, -39, -39, -130, -89, -92, -106, 19, 11, 34, 34, -36, 68, 69, 70, 112, -193, -73, -65, -65, @@ -4240,35 +4240,43 @@ yydefault: yyDollar = yyS[yypt-7 : yypt+1] //line sql.y:1312 { - yyVAL.statement = &DDL{Action: CreateVindexStr, VindexSpec: &VindexSpec{ - Name: yyDollar[5].colIdent, - Type: yyDollar[6].colIdent, - Params: yyDollar[7].vindexParams, - }} + yyVAL.statement = &DDL{ + Action: CreateVindexStr, + Table: yyDollar[5].tableName, + VindexSpec: &VindexSpec{ + Name: NewColIdent(yyDollar[5].tableName.Name.String()), + Type: yyDollar[6].colIdent, + Params: yyDollar[7].vindexParams, + }, + } } case 223: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:1320 +//line sql.y:1324 { - yyVAL.statement = &DDL{Action: DropVindexStr, VindexSpec: &VindexSpec{ - Name: yyDollar[5].colIdent, - }} + yyVAL.statement = &DDL{ + Action: DropVindexStr, + Table: yyDollar[5].tableName, + VindexSpec: &VindexSpec{ + Name: NewColIdent(yyDollar[5].tableName.Name.String()), + }, + } } case 224: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:1326 +//line sql.y:1334 { yyVAL.statement = &DDL{Action: AddVschemaTableStr, Table: yyDollar[5].tableName} } case 225: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:1330 +//line sql.y:1338 { yyVAL.statement = &DDL{Action: DropVschemaTableStr, Table: yyDollar[5].tableName} } case 226: yyDollar = yyS[yypt-12 : yypt+1] -//line sql.y:1334 +//line sql.y:1342 { yyVAL.statement = &DDL{ Action: AddColVindexStr, @@ -4283,7 +4291,7 @@ yydefault: } case 227: yyDollar = yyS[yypt-7 : yypt+1] -//line sql.y:1347 +//line sql.y:1355 { yyVAL.statement = &DDL{ Action: DropColVindexStr, @@ -4295,13 +4303,13 @@ yydefault: } case 228: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:1357 +//line sql.y:1365 { yyVAL.statement = &DDL{Action: AddSequenceStr, Table: yyDollar[5].tableName} } case 229: yyDollar = yyS[yypt-9 : yypt+1] -//line sql.y:1361 +//line sql.y:1369 { yyVAL.statement = &DDL{ Action: AddAutoIncStr, @@ -4314,49 +4322,49 @@ yydefault: } case 241: yyDollar = yyS[yypt-7 : yypt+1] -//line sql.y:1387 +//line sql.y:1395 { yyVAL.partSpec = &PartitionSpec{Action: ReorganizeStr, Name: yyDollar[3].colIdent, Definitions: yyDollar[6].partDefs} } case 242: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1393 +//line sql.y:1401 { yyVAL.partDefs = []*PartitionDefinition{yyDollar[1].partDef} } case 243: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1397 +//line sql.y:1405 { yyVAL.partDefs = append(yyDollar[1].partDefs, yyDollar[3].partDef) } case 244: yyDollar = yyS[yypt-8 : yypt+1] -//line sql.y:1403 +//line sql.y:1411 { yyVAL.partDef = &PartitionDefinition{Name: yyDollar[2].colIdent, Limit: yyDollar[7].expr} } case 245: yyDollar = yyS[yypt-8 : yypt+1] -//line sql.y:1407 +//line sql.y:1415 { yyVAL.partDef = &PartitionDefinition{Name: yyDollar[2].colIdent, Maxvalue: true} } case 246: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1413 +//line sql.y:1421 { yyVAL.statement = yyDollar[3].ddl } case 247: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1419 +//line sql.y:1427 { 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:1423 +//line sql.y:1431 { yyVAL.ddl = yyDollar[1].ddl yyVAL.ddl.FromTables = append(yyVAL.ddl.FromTables, yyDollar[3].tableName) @@ -4364,7 +4372,7 @@ yydefault: } case 249: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:1431 +//line sql.y:1439 { var exists bool if yyDollar[3].byt != 0 { @@ -4374,14 +4382,14 @@ yydefault: } case 250: yyDollar = yyS[yypt-6 : yypt+1] -//line sql.y:1439 +//line sql.y:1447 { // 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:1444 +//line sql.y:1452 { var exists bool if yyDollar[3].byt != 0 { @@ -4391,146 +4399,146 @@ yydefault: } case 252: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:1452 +//line sql.y:1460 { yyVAL.statement = &DBDDL{Action: DropStr, DBName: string(yyDollar[4].bytes)} } case 253: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:1456 +//line sql.y:1464 { yyVAL.statement = &DBDDL{Action: DropStr, DBName: string(yyDollar[4].bytes)} } case 254: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1462 +//line sql.y:1470 { yyVAL.statement = &DDL{Action: TruncateStr, Table: yyDollar[3].tableName} } case 255: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1466 +//line sql.y:1474 { yyVAL.statement = &DDL{Action: TruncateStr, Table: yyDollar[2].tableName} } case 256: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1471 +//line sql.y:1479 { yyVAL.statement = &DDL{Action: AlterStr, Table: yyDollar[3].tableName} } case 257: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:1477 +//line sql.y:1485 { yyVAL.statement = &Show{Type: string(yyDollar[2].bytes) + " " + string(yyDollar[3].bytes)} } case 258: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:1482 +//line sql.y:1490 { yyVAL.statement = &Show{Type: CharsetStr} } case 259: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1486 +//line sql.y:1494 { yyVAL.statement = &Show{Type: string(yyDollar[2].bytes)} } case 260: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:1490 +//line sql.y:1498 { yyVAL.statement = &Show{Type: string(yyDollar[2].bytes) + " " + string(yyDollar[3].bytes)} } case 261: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:1495 +//line sql.y:1503 { yyVAL.statement = &Show{Type: string(yyDollar[2].bytes) + " " + string(yyDollar[3].bytes)} } case 262: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:1499 +//line sql.y:1507 { yyVAL.statement = &Show{Type: string(yyDollar[2].bytes) + " " + string(yyDollar[3].bytes)} } case 263: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:1503 +//line sql.y:1511 { yyVAL.statement = &Show{Type: string(yyDollar[2].bytes) + " " + string(yyDollar[3].bytes), Table: yyDollar[4].tableName} } case 264: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:1507 +//line sql.y:1515 { yyVAL.statement = &Show{Type: string(yyDollar[2].bytes) + " " + string(yyDollar[3].bytes)} } case 265: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:1511 +//line sql.y:1519 { yyVAL.statement = &Show{Type: string(yyDollar[2].bytes) + " " + string(yyDollar[3].bytes)} } case 266: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1515 +//line sql.y:1523 { yyVAL.statement = &Show{Type: string(yyDollar[2].bytes)} } case 267: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1519 +//line sql.y:1527 { yyVAL.statement = &Show{Type: string(yyDollar[2].bytes)} } case 268: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1523 +//line sql.y:1531 { yyVAL.statement = &Show{Type: string(yyDollar[2].bytes)} } case 269: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1527 +//line sql.y:1535 { yyVAL.statement = &Show{Type: string(yyDollar[2].bytes)} } case 270: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1531 +//line sql.y:1539 { yyVAL.statement = &Show{Type: string(yyDollar[2].bytes)} } case 271: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1535 +//line sql.y:1543 { yyVAL.statement = &Show{Type: string(yyDollar[2].bytes)} } case 272: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:1539 +//line sql.y:1547 { yyVAL.statement = &Show{Scope: yyDollar[2].str, Type: string(yyDollar[3].bytes)} } case 273: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1543 +//line sql.y:1551 { yyVAL.statement = &Show{Type: string(yyDollar[2].bytes)} } case 274: yyDollar = yyS[yypt-7 : yypt+1] -//line sql.y:1547 +//line sql.y:1555 { 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:1552 +//line sql.y:1560 { // this is ugly, but I couldn't find a better way for now if yyDollar[3].str == "processlist" { @@ -4542,19 +4550,19 @@ yydefault: } case 276: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:1562 +//line sql.y:1570 { yyVAL.statement = &Show{Scope: yyDollar[2].str, Type: string(yyDollar[3].bytes)} } case 277: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1566 +//line sql.y:1574 { yyVAL.statement = &Show{Type: string(yyDollar[2].bytes)} } case 278: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:1570 +//line sql.y:1578 { // Cannot dereference $4 directly, or else the parser stackcannot be pooled. See yyParsePooled showCollationFilterOpt := yyDollar[4].expr @@ -4562,423 +4570,423 @@ yydefault: } case 279: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:1576 +//line sql.y:1584 { showTablesOpt := &ShowTablesOpt{Filter: yyDollar[4].showFilter} yyVAL.statement = &Show{Scope: string(yyDollar[2].bytes), Type: string(yyDollar[3].bytes), ShowTablesOpt: showTablesOpt} } case 280: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1581 +//line sql.y:1589 { yyVAL.statement = &Show{Type: string(yyDollar[2].bytes) + " " + string(yyDollar[3].bytes)} } case 281: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1585 +//line sql.y:1593 { yyVAL.statement = &Show{Type: string(yyDollar[2].bytes) + " " + string(yyDollar[3].bytes)} } case 282: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:1589 +//line sql.y:1597 { yyVAL.statement = &Show{Type: string(yyDollar[2].bytes) + " " + string(yyDollar[3].bytes), OnTable: yyDollar[5].tableName} } case 283: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1593 +//line sql.y:1601 { yyVAL.statement = &Show{Type: string(yyDollar[2].bytes)} } case 284: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1607 +//line sql.y:1615 { yyVAL.statement = &Show{Type: string(yyDollar[2].bytes)} } case 285: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1613 +//line sql.y:1621 { yyVAL.str = string(yyDollar[1].bytes) } case 286: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1617 +//line sql.y:1625 { yyVAL.str = string(yyDollar[1].bytes) } case 287: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:1623 +//line sql.y:1631 { yyVAL.str = "" } case 288: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1627 +//line sql.y:1635 { yyVAL.str = "full " } case 289: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1633 +//line sql.y:1641 { yyVAL.str = string(yyDollar[1].bytes) } case 290: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1637 +//line sql.y:1645 { yyVAL.str = string(yyDollar[1].bytes) } case 291: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:1643 +//line sql.y:1651 { yyVAL.str = "" } case 292: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1647 +//line sql.y:1655 { yyVAL.str = yyDollar[2].tableIdent.v } case 293: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1651 +//line sql.y:1659 { yyVAL.str = yyDollar[2].tableIdent.v } case 294: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:1657 +//line sql.y:1665 { yyVAL.showFilter = nil } case 295: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1661 +//line sql.y:1669 { yyVAL.showFilter = &ShowFilter{Like: string(yyDollar[2].bytes)} } case 296: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1665 +//line sql.y:1673 { yyVAL.showFilter = &ShowFilter{Filter: yyDollar[2].expr} } case 297: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:1671 +//line sql.y:1679 { yyVAL.showFilter = nil } case 298: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1675 +//line sql.y:1683 { yyVAL.showFilter = &ShowFilter{Like: string(yyDollar[2].bytes)} } case 299: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:1681 +//line sql.y:1689 { yyVAL.str = "" } case 300: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1685 +//line sql.y:1693 { yyVAL.str = SessionStr } case 301: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1689 +//line sql.y:1697 { yyVAL.str = GlobalStr } case 302: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1695 +//line sql.y:1703 { yyVAL.statement = &Use{DBName: yyDollar[2].tableIdent} } case 303: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1699 +//line sql.y:1707 { yyVAL.statement = &Use{DBName: TableIdent{v: ""}} } case 304: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1705 +//line sql.y:1713 { yyVAL.statement = &Begin{} } case 305: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1709 +//line sql.y:1717 { yyVAL.statement = &Begin{} } case 306: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1715 +//line sql.y:1723 { yyVAL.statement = &Commit{} } case 307: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1721 +//line sql.y:1729 { yyVAL.statement = &Rollback{} } case 308: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1727 +//line sql.y:1735 { yyVAL.statement = &OtherRead{} } case 309: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1731 +//line sql.y:1739 { yyVAL.statement = &OtherRead{} } case 310: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1735 +//line sql.y:1743 { yyVAL.statement = &OtherRead{} } case 311: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1739 +//line sql.y:1747 { yyVAL.statement = &OtherAdmin{} } case 312: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1743 +//line sql.y:1751 { yyVAL.statement = &OtherAdmin{} } case 313: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1747 +//line sql.y:1755 { yyVAL.statement = &OtherAdmin{} } case 314: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1751 +//line sql.y:1759 { yyVAL.statement = &OtherAdmin{} } case 315: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1757 +//line sql.y:1765 { yyVAL.statement = &DDL{Action: FlushStr} } case 316: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:1761 +//line sql.y:1769 { setAllowComments(yylex, true) } case 317: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1765 +//line sql.y:1773 { yyVAL.bytes2 = yyDollar[2].bytes2 setAllowComments(yylex, false) } case 318: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:1771 +//line sql.y:1779 { yyVAL.bytes2 = nil } case 319: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1775 +//line sql.y:1783 { yyVAL.bytes2 = append(yyDollar[1].bytes2, yyDollar[2].bytes) } case 320: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1781 +//line sql.y:1789 { yyVAL.str = UnionStr } case 321: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1785 +//line sql.y:1793 { yyVAL.str = UnionAllStr } case 322: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1789 +//line sql.y:1797 { yyVAL.str = UnionDistinctStr } case 323: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:1794 +//line sql.y:1802 { yyVAL.str = "" } case 324: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1798 +//line sql.y:1806 { yyVAL.str = SQLNoCacheStr } case 325: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1802 +//line sql.y:1810 { yyVAL.str = SQLCacheStr } case 326: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:1807 +//line sql.y:1815 { yyVAL.str = "" } case 327: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1811 +//line sql.y:1819 { yyVAL.str = DistinctStr } case 328: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:1816 +//line sql.y:1824 { yyVAL.str = "" } case 329: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1820 +//line sql.y:1828 { yyVAL.str = StraightJoinHint } case 330: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:1825 +//line sql.y:1833 { yyVAL.selectExprs = nil } case 331: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1829 +//line sql.y:1837 { yyVAL.selectExprs = yyDollar[1].selectExprs } case 332: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1835 +//line sql.y:1843 { yyVAL.selectExprs = SelectExprs{yyDollar[1].selectExpr} } case 333: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1839 +//line sql.y:1847 { yyVAL.selectExprs = append(yyVAL.selectExprs, yyDollar[3].selectExpr) } case 334: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1845 +//line sql.y:1853 { yyVAL.selectExpr = &StarExpr{} } case 335: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1849 +//line sql.y:1857 { yyVAL.selectExpr = &AliasedExpr{Expr: yyDollar[1].expr, As: yyDollar[2].colIdent} } case 336: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1853 +//line sql.y:1861 { yyVAL.selectExpr = &StarExpr{TableName: TableName{Name: yyDollar[1].tableIdent}} } case 337: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:1857 +//line sql.y:1865 { yyVAL.selectExpr = &StarExpr{TableName: TableName{Qualifier: yyDollar[1].tableIdent, Name: yyDollar[3].tableIdent}} } case 338: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:1862 +//line sql.y:1870 { yyVAL.colIdent = ColIdent{} } case 339: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1866 +//line sql.y:1874 { yyVAL.colIdent = yyDollar[1].colIdent } case 340: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1870 +//line sql.y:1878 { yyVAL.colIdent = yyDollar[2].colIdent } case 342: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1877 +//line sql.y:1885 { yyVAL.colIdent = NewColIdent(string(yyDollar[1].bytes)) } case 343: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:1882 +//line sql.y:1890 { yyVAL.tableExprs = TableExprs{&AliasedTableExpr{Expr: TableName{Name: NewTableIdent("dual")}}} } case 344: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1886 +//line sql.y:1894 { yyVAL.tableExprs = yyDollar[2].tableExprs } case 345: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1892 +//line sql.y:1900 { yyVAL.tableExprs = TableExprs{yyDollar[1].tableExpr} } case 346: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1896 +//line sql.y:1904 { yyVAL.tableExprs = append(yyVAL.tableExprs, yyDollar[3].tableExpr) } case 349: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1906 +//line sql.y:1914 { yyVAL.tableExpr = yyDollar[1].aliasedTableName } case 350: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1910 +//line sql.y:1918 { yyVAL.tableExpr = &AliasedTableExpr{Expr: yyDollar[1].subquery, As: yyDollar[3].tableIdent} } case 351: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1914 +//line sql.y:1922 { // missed alias for subquery yylex.Error("Every derived table must have its own alias") @@ -4986,199 +4994,199 @@ yydefault: } case 352: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1920 +//line sql.y:1928 { yyVAL.tableExpr = &ParenTableExpr{Exprs: yyDollar[2].tableExprs} } case 353: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1926 +//line sql.y:1934 { yyVAL.aliasedTableName = &AliasedTableExpr{Expr: yyDollar[1].tableName, As: yyDollar[2].tableIdent, Hints: yyDollar[3].indexHints} } case 354: yyDollar = yyS[yypt-7 : yypt+1] -//line sql.y:1930 +//line sql.y:1938 { yyVAL.aliasedTableName = &AliasedTableExpr{Expr: yyDollar[1].tableName, Partitions: yyDollar[4].partitions, As: yyDollar[6].tableIdent, Hints: yyDollar[7].indexHints} } case 355: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1936 +//line sql.y:1944 { yyVAL.columns = Columns{yyDollar[1].colIdent} } case 356: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1940 +//line sql.y:1948 { yyVAL.columns = append(yyVAL.columns, yyDollar[3].colIdent) } case 357: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1946 +//line sql.y:1954 { yyVAL.partitions = Partitions{yyDollar[1].colIdent} } case 358: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1950 +//line sql.y:1958 { yyVAL.partitions = append(yyVAL.partitions, yyDollar[3].colIdent) } case 359: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:1963 +//line sql.y:1971 { yyVAL.tableExpr = &JoinTableExpr{LeftExpr: yyDollar[1].tableExpr, Join: yyDollar[2].str, RightExpr: yyDollar[3].tableExpr, Condition: yyDollar[4].joinCondition} } case 360: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:1967 +//line sql.y:1975 { 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:1971 +//line sql.y:1979 { yyVAL.tableExpr = &JoinTableExpr{LeftExpr: yyDollar[1].tableExpr, Join: yyDollar[2].str, RightExpr: yyDollar[3].tableExpr, Condition: yyDollar[4].joinCondition} } case 362: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1975 +//line sql.y:1983 { yyVAL.tableExpr = &JoinTableExpr{LeftExpr: yyDollar[1].tableExpr, Join: yyDollar[2].str, RightExpr: yyDollar[3].tableExpr} } case 363: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1981 +//line sql.y:1989 { yyVAL.joinCondition = JoinCondition{On: yyDollar[2].expr} } case 364: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:1983 +//line sql.y:1991 { yyVAL.joinCondition = JoinCondition{Using: yyDollar[3].columns} } case 365: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:1987 +//line sql.y:1995 { yyVAL.joinCondition = JoinCondition{} } case 366: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1989 +//line sql.y:1997 { yyVAL.joinCondition = yyDollar[1].joinCondition } case 367: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:1993 +//line sql.y:2001 { yyVAL.joinCondition = JoinCondition{} } case 368: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1995 +//line sql.y:2003 { yyVAL.joinCondition = JoinCondition{On: yyDollar[2].expr} } case 369: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:1998 +//line sql.y:2006 { yyVAL.empty = struct{}{} } case 370: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2000 +//line sql.y:2008 { yyVAL.empty = struct{}{} } case 371: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:2003 +//line sql.y:2011 { yyVAL.tableIdent = NewTableIdent("") } case 372: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2007 +//line sql.y:2015 { yyVAL.tableIdent = yyDollar[1].tableIdent } case 373: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2011 +//line sql.y:2019 { yyVAL.tableIdent = yyDollar[2].tableIdent } case 375: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2018 +//line sql.y:2026 { yyVAL.tableIdent = NewTableIdent(string(yyDollar[1].bytes)) } case 376: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2024 +//line sql.y:2032 { yyVAL.str = JoinStr } case 377: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2028 +//line sql.y:2036 { yyVAL.str = JoinStr } case 378: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2032 +//line sql.y:2040 { yyVAL.str = JoinStr } case 379: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2038 +//line sql.y:2046 { yyVAL.str = StraightJoinStr } case 380: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2044 +//line sql.y:2052 { yyVAL.str = LeftJoinStr } case 381: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2048 +//line sql.y:2056 { yyVAL.str = LeftJoinStr } case 382: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2052 +//line sql.y:2060 { yyVAL.str = RightJoinStr } case 383: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2056 +//line sql.y:2064 { yyVAL.str = RightJoinStr } case 384: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2062 +//line sql.y:2070 { yyVAL.str = NaturalJoinStr } case 385: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2066 +//line sql.y:2074 { if yyDollar[2].str == LeftJoinStr { yyVAL.str = NaturalLeftJoinStr @@ -5188,463 +5196,463 @@ yydefault: } case 386: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2076 +//line sql.y:2084 { yyVAL.tableName = yyDollar[2].tableName } case 387: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2080 +//line sql.y:2088 { yyVAL.tableName = yyDollar[1].tableName } case 388: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2086 +//line sql.y:2094 { yyVAL.tableName = TableName{Name: yyDollar[1].tableIdent} } case 389: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2090 +//line sql.y:2098 { yyVAL.tableName = TableName{Qualifier: yyDollar[1].tableIdent, Name: yyDollar[3].tableIdent} } case 390: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2096 +//line sql.y:2104 { yyVAL.tableName = TableName{Name: yyDollar[1].tableIdent} } case 391: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:2101 +//line sql.y:2109 { yyVAL.indexHints = nil } case 392: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:2105 +//line sql.y:2113 { yyVAL.indexHints = &IndexHints{Type: UseStr, Indexes: yyDollar[4].columns} } case 393: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:2109 +//line sql.y:2117 { yyVAL.indexHints = &IndexHints{Type: IgnoreStr, Indexes: yyDollar[4].columns} } case 394: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:2113 +//line sql.y:2121 { yyVAL.indexHints = &IndexHints{Type: ForceStr, Indexes: yyDollar[4].columns} } case 395: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:2118 +//line sql.y:2126 { yyVAL.expr = nil } case 396: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2122 +//line sql.y:2130 { yyVAL.expr = yyDollar[2].expr } case 397: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2128 +//line sql.y:2136 { yyVAL.expr = yyDollar[1].expr } case 398: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2132 +//line sql.y:2140 { yyVAL.expr = &AndExpr{Left: yyDollar[1].expr, Right: yyDollar[3].expr} } case 399: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2136 +//line sql.y:2144 { yyVAL.expr = &OrExpr{Left: yyDollar[1].expr, Right: yyDollar[3].expr} } case 400: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2140 +//line sql.y:2148 { yyVAL.expr = &NotExpr{Expr: yyDollar[2].expr} } case 401: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2144 +//line sql.y:2152 { yyVAL.expr = &IsExpr{Operator: yyDollar[3].str, Expr: yyDollar[1].expr} } case 402: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2148 +//line sql.y:2156 { yyVAL.expr = yyDollar[1].expr } case 403: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2152 +//line sql.y:2160 { yyVAL.expr = &Default{ColName: yyDollar[2].str} } case 404: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:2158 +//line sql.y:2166 { yyVAL.str = "" } case 405: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2162 +//line sql.y:2170 { yyVAL.str = string(yyDollar[2].bytes) } case 406: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2168 +//line sql.y:2176 { yyVAL.boolVal = BoolVal(true) } case 407: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2172 +//line sql.y:2180 { yyVAL.boolVal = BoolVal(false) } case 408: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2178 +//line sql.y:2186 { 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:2182 +//line sql.y:2190 { yyVAL.expr = &ComparisonExpr{Left: yyDollar[1].expr, Operator: InStr, Right: yyDollar[3].colTuple} } case 410: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:2186 +//line sql.y:2194 { yyVAL.expr = &ComparisonExpr{Left: yyDollar[1].expr, Operator: NotInStr, Right: yyDollar[4].colTuple} } case 411: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:2190 +//line sql.y:2198 { 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:2194 +//line sql.y:2202 { 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:2198 +//line sql.y:2206 { yyVAL.expr = &ComparisonExpr{Left: yyDollar[1].expr, Operator: RegexpStr, Right: yyDollar[3].expr} } case 414: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:2202 +//line sql.y:2210 { yyVAL.expr = &ComparisonExpr{Left: yyDollar[1].expr, Operator: NotRegexpStr, Right: yyDollar[4].expr} } case 415: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:2206 +//line sql.y:2214 { 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:2210 +//line sql.y:2218 { 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:2214 +//line sql.y:2222 { yyVAL.expr = &ExistsExpr{Subquery: yyDollar[2].subquery} } case 418: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2220 +//line sql.y:2228 { yyVAL.str = IsNullStr } case 419: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2224 +//line sql.y:2232 { yyVAL.str = IsNotNullStr } case 420: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2228 +//line sql.y:2236 { yyVAL.str = IsTrueStr } case 421: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2232 +//line sql.y:2240 { yyVAL.str = IsNotTrueStr } case 422: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2236 +//line sql.y:2244 { yyVAL.str = IsFalseStr } case 423: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2240 +//line sql.y:2248 { yyVAL.str = IsNotFalseStr } case 424: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2246 +//line sql.y:2254 { yyVAL.str = EqualStr } case 425: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2250 +//line sql.y:2258 { yyVAL.str = LessThanStr } case 426: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2254 +//line sql.y:2262 { yyVAL.str = GreaterThanStr } case 427: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2258 +//line sql.y:2266 { yyVAL.str = LessEqualStr } case 428: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2262 +//line sql.y:2270 { yyVAL.str = GreaterEqualStr } case 429: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2266 +//line sql.y:2274 { yyVAL.str = NotEqualStr } case 430: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2270 +//line sql.y:2278 { yyVAL.str = NullSafeEqualStr } case 431: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:2275 +//line sql.y:2283 { yyVAL.expr = nil } case 432: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2279 +//line sql.y:2287 { yyVAL.expr = yyDollar[2].expr } case 433: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2285 +//line sql.y:2293 { yyVAL.colTuple = yyDollar[1].valTuple } case 434: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2289 +//line sql.y:2297 { yyVAL.colTuple = yyDollar[1].subquery } case 435: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2293 +//line sql.y:2301 { yyVAL.colTuple = ListArg(yyDollar[1].bytes) } case 436: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2299 +//line sql.y:2307 { yyVAL.subquery = &Subquery{yyDollar[2].selStmt} } case 437: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2305 +//line sql.y:2313 { yyVAL.exprs = Exprs{yyDollar[1].expr} } case 438: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2309 +//line sql.y:2317 { yyVAL.exprs = append(yyDollar[1].exprs, yyDollar[3].expr) } case 439: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2315 +//line sql.y:2323 { yyVAL.expr = yyDollar[1].expr } case 440: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2319 +//line sql.y:2327 { yyVAL.expr = yyDollar[1].boolVal } case 441: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2323 +//line sql.y:2331 { yyVAL.expr = yyDollar[1].colName } case 442: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2327 +//line sql.y:2335 { yyVAL.expr = yyDollar[1].expr } case 443: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2331 +//line sql.y:2339 { yyVAL.expr = yyDollar[1].subquery } case 444: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2335 +//line sql.y:2343 { yyVAL.expr = &BinaryExpr{Left: yyDollar[1].expr, Operator: BitAndStr, Right: yyDollar[3].expr} } case 445: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2339 +//line sql.y:2347 { yyVAL.expr = &BinaryExpr{Left: yyDollar[1].expr, Operator: BitOrStr, Right: yyDollar[3].expr} } case 446: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2343 +//line sql.y:2351 { yyVAL.expr = &BinaryExpr{Left: yyDollar[1].expr, Operator: BitXorStr, Right: yyDollar[3].expr} } case 447: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2347 +//line sql.y:2355 { yyVAL.expr = &BinaryExpr{Left: yyDollar[1].expr, Operator: PlusStr, Right: yyDollar[3].expr} } case 448: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2351 +//line sql.y:2359 { yyVAL.expr = &BinaryExpr{Left: yyDollar[1].expr, Operator: MinusStr, Right: yyDollar[3].expr} } case 449: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2355 +//line sql.y:2363 { yyVAL.expr = &BinaryExpr{Left: yyDollar[1].expr, Operator: MultStr, Right: yyDollar[3].expr} } case 450: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2359 +//line sql.y:2367 { yyVAL.expr = &BinaryExpr{Left: yyDollar[1].expr, Operator: DivStr, Right: yyDollar[3].expr} } case 451: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2363 +//line sql.y:2371 { yyVAL.expr = &BinaryExpr{Left: yyDollar[1].expr, Operator: IntDivStr, Right: yyDollar[3].expr} } case 452: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2367 +//line sql.y:2375 { yyVAL.expr = &BinaryExpr{Left: yyDollar[1].expr, Operator: ModStr, Right: yyDollar[3].expr} } case 453: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2371 +//line sql.y:2379 { yyVAL.expr = &BinaryExpr{Left: yyDollar[1].expr, Operator: ModStr, Right: yyDollar[3].expr} } case 454: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2375 +//line sql.y:2383 { yyVAL.expr = &BinaryExpr{Left: yyDollar[1].expr, Operator: ShiftLeftStr, Right: yyDollar[3].expr} } case 455: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2379 +//line sql.y:2387 { yyVAL.expr = &BinaryExpr{Left: yyDollar[1].expr, Operator: ShiftRightStr, Right: yyDollar[3].expr} } case 456: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2383 +//line sql.y:2391 { yyVAL.expr = &BinaryExpr{Left: yyDollar[1].colName, Operator: JSONExtractOp, Right: yyDollar[3].expr} } case 457: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2387 +//line sql.y:2395 { yyVAL.expr = &BinaryExpr{Left: yyDollar[1].colName, Operator: JSONUnquoteExtractOp, Right: yyDollar[3].expr} } case 458: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2391 +//line sql.y:2399 { yyVAL.expr = &CollateExpr{Expr: yyDollar[1].expr, Charset: yyDollar[3].str} } case 459: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2395 +//line sql.y:2403 { yyVAL.expr = &UnaryExpr{Operator: BinaryStr, Expr: yyDollar[2].expr} } case 460: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2399 +//line sql.y:2407 { yyVAL.expr = &UnaryExpr{Operator: UBinaryStr, Expr: yyDollar[2].expr} } case 461: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2403 +//line sql.y:2411 { yyVAL.expr = &UnaryExpr{Operator: Utf8mb4Str, Expr: yyDollar[2].expr} } case 462: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2407 +//line sql.y:2415 { if num, ok := yyDollar[2].expr.(*SQLVal); ok && num.Type == IntVal { yyVAL.expr = num @@ -5654,7 +5662,7 @@ yydefault: } case 463: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2415 +//line sql.y:2423 { if num, ok := yyDollar[2].expr.(*SQLVal); ok && num.Type == IntVal { // Handle double negative @@ -5670,19 +5678,19 @@ yydefault: } case 464: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2429 +//line sql.y:2437 { yyVAL.expr = &UnaryExpr{Operator: TildaStr, Expr: yyDollar[2].expr} } case 465: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2433 +//line sql.y:2441 { yyVAL.expr = &UnaryExpr{Operator: BangStr, Expr: yyDollar[2].expr} } case 466: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2437 +//line sql.y:2445 { // This rule prevents the usage of INTERVAL // as a function. If support is needed for that, @@ -5692,313 +5700,313 @@ yydefault: } case 471: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:2455 +//line sql.y:2463 { yyVAL.expr = &FuncExpr{Name: yyDollar[1].colIdent, Exprs: yyDollar[3].selectExprs} } case 472: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:2459 +//line sql.y:2467 { yyVAL.expr = &FuncExpr{Name: yyDollar[1].colIdent, Distinct: true, Exprs: yyDollar[4].selectExprs} } case 473: yyDollar = yyS[yypt-6 : yypt+1] -//line sql.y:2463 +//line sql.y:2471 { 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:2473 +//line sql.y:2481 { yyVAL.expr = &FuncExpr{Name: NewColIdent("left"), Exprs: yyDollar[3].selectExprs} } case 475: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:2477 +//line sql.y:2485 { yyVAL.expr = &FuncExpr{Name: NewColIdent("right"), Exprs: yyDollar[3].selectExprs} } case 476: yyDollar = yyS[yypt-6 : yypt+1] -//line sql.y:2481 +//line sql.y:2489 { yyVAL.expr = &ConvertExpr{Expr: yyDollar[3].expr, Type: yyDollar[5].convertType} } case 477: yyDollar = yyS[yypt-6 : yypt+1] -//line sql.y:2485 +//line sql.y:2493 { yyVAL.expr = &ConvertExpr{Expr: yyDollar[3].expr, Type: yyDollar[5].convertType} } case 478: yyDollar = yyS[yypt-6 : yypt+1] -//line sql.y:2489 +//line sql.y:2497 { yyVAL.expr = &ConvertUsingExpr{Expr: yyDollar[3].expr, Type: yyDollar[5].str} } case 479: yyDollar = yyS[yypt-8 : yypt+1] -//line sql.y:2493 +//line sql.y:2501 { yyVAL.expr = &SubstrExpr{Name: yyDollar[3].colName, From: yyDollar[5].expr, To: yyDollar[7].expr} } case 480: yyDollar = yyS[yypt-8 : yypt+1] -//line sql.y:2497 +//line sql.y:2505 { 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:2501 +//line sql.y:2509 { yyVAL.expr = &SubstrExpr{StrVal: NewStrVal(yyDollar[3].bytes), From: yyDollar[5].expr, To: yyDollar[7].expr} } case 482: yyDollar = yyS[yypt-8 : yypt+1] -//line sql.y:2505 +//line sql.y:2513 { yyVAL.expr = &SubstrExpr{StrVal: NewStrVal(yyDollar[3].bytes), From: yyDollar[5].expr, To: yyDollar[7].expr} } case 483: yyDollar = yyS[yypt-9 : yypt+1] -//line sql.y:2509 +//line sql.y:2517 { yyVAL.expr = &MatchExpr{Columns: yyDollar[3].selectExprs, Expr: yyDollar[7].expr, Option: yyDollar[8].str} } case 484: yyDollar = yyS[yypt-7 : yypt+1] -//line sql.y:2513 +//line sql.y:2521 { yyVAL.expr = &GroupConcatExpr{Distinct: yyDollar[3].str, Exprs: yyDollar[4].selectExprs, OrderBy: yyDollar[5].orderBy, Separator: yyDollar[6].str} } case 485: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:2517 +//line sql.y:2525 { yyVAL.expr = &CaseExpr{Expr: yyDollar[2].expr, Whens: yyDollar[3].whens, Else: yyDollar[4].expr} } case 486: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:2521 +//line sql.y:2529 { yyVAL.expr = &ValuesFuncExpr{Name: yyDollar[3].colName} } case 487: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2531 +//line sql.y:2539 { yyVAL.expr = &FuncExpr{Name: NewColIdent("current_timestamp")} } case 488: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2535 +//line sql.y:2543 { yyVAL.expr = &FuncExpr{Name: NewColIdent("utc_timestamp")} } case 489: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2539 +//line sql.y:2547 { yyVAL.expr = &FuncExpr{Name: NewColIdent("utc_time")} } case 490: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2544 +//line sql.y:2552 { yyVAL.expr = &FuncExpr{Name: NewColIdent("utc_date")} } case 491: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2549 +//line sql.y:2557 { yyVAL.expr = &FuncExpr{Name: NewColIdent("localtime")} } case 492: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2554 +//line sql.y:2562 { yyVAL.expr = &FuncExpr{Name: NewColIdent("localtimestamp")} } case 493: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2560 +//line sql.y:2568 { yyVAL.expr = &FuncExpr{Name: NewColIdent("current_date")} } case 494: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2565 +//line sql.y:2573 { yyVAL.expr = &FuncExpr{Name: NewColIdent("current_time")} } case 495: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2570 +//line sql.y:2578 { yyVAL.expr = &CurTimeFuncExpr{Name: NewColIdent("current_timestamp"), Fsp: yyDollar[2].expr} } case 496: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2574 +//line sql.y:2582 { yyVAL.expr = &CurTimeFuncExpr{Name: NewColIdent("utc_timestamp"), Fsp: yyDollar[2].expr} } case 497: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2578 +//line sql.y:2586 { yyVAL.expr = &CurTimeFuncExpr{Name: NewColIdent("utc_time"), Fsp: yyDollar[2].expr} } case 498: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2583 +//line sql.y:2591 { yyVAL.expr = &CurTimeFuncExpr{Name: NewColIdent("localtime"), Fsp: yyDollar[2].expr} } case 499: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2588 +//line sql.y:2596 { yyVAL.expr = &CurTimeFuncExpr{Name: NewColIdent("localtimestamp"), Fsp: yyDollar[2].expr} } case 500: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2593 +//line sql.y:2601 { yyVAL.expr = &CurTimeFuncExpr{Name: NewColIdent("current_time"), Fsp: yyDollar[2].expr} } case 501: yyDollar = yyS[yypt-8 : yypt+1] -//line sql.y:2597 +//line sql.y:2605 { yyVAL.expr = &TimestampFuncExpr{Name: string("timestampadd"), Unit: yyDollar[3].colIdent.String(), Expr1: yyDollar[5].expr, Expr2: yyDollar[7].expr} } case 502: yyDollar = yyS[yypt-8 : yypt+1] -//line sql.y:2601 +//line sql.y:2609 { yyVAL.expr = &TimestampFuncExpr{Name: string("timestampdiff"), Unit: yyDollar[3].colIdent.String(), Expr1: yyDollar[5].expr, Expr2: yyDollar[7].expr} } case 505: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2611 +//line sql.y:2619 { yyVAL.expr = yyDollar[2].expr } case 506: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:2621 +//line sql.y:2629 { yyVAL.expr = &FuncExpr{Name: NewColIdent("if"), Exprs: yyDollar[3].selectExprs} } case 507: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:2625 +//line sql.y:2633 { yyVAL.expr = &FuncExpr{Name: NewColIdent("database"), Exprs: yyDollar[3].selectExprs} } case 508: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:2629 +//line sql.y:2637 { yyVAL.expr = &FuncExpr{Name: NewColIdent("mod"), Exprs: yyDollar[3].selectExprs} } case 509: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:2633 +//line sql.y:2641 { yyVAL.expr = &FuncExpr{Name: NewColIdent("replace"), Exprs: yyDollar[3].selectExprs} } case 510: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:2637 +//line sql.y:2645 { yyVAL.expr = &FuncExpr{Name: NewColIdent("substr"), Exprs: yyDollar[3].selectExprs} } case 511: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:2641 +//line sql.y:2649 { yyVAL.expr = &FuncExpr{Name: NewColIdent("substr"), Exprs: yyDollar[3].selectExprs} } case 512: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:2647 +//line sql.y:2655 { yyVAL.str = "" } case 513: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2651 +//line sql.y:2659 { yyVAL.str = BooleanModeStr } case 514: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:2655 +//line sql.y:2663 { yyVAL.str = NaturalLanguageModeStr } case 515: yyDollar = yyS[yypt-7 : yypt+1] -//line sql.y:2659 +//line sql.y:2667 { yyVAL.str = NaturalLanguageModeWithQueryExpansionStr } case 516: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2663 +//line sql.y:2671 { yyVAL.str = QueryExpansionStr } case 517: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2669 +//line sql.y:2677 { yyVAL.str = string(yyDollar[1].bytes) } case 518: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2673 +//line sql.y:2681 { yyVAL.str = string(yyDollar[1].bytes) } case 519: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2679 +//line sql.y:2687 { yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes), Length: yyDollar[2].sqlVal} } case 520: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2683 +//line sql.y:2691 { yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes), Length: yyDollar[2].sqlVal, Charset: yyDollar[3].str, Operator: CharacterSetStr} } case 521: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2687 +//line sql.y:2695 { yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes), Length: yyDollar[2].sqlVal, Charset: string(yyDollar[3].bytes)} } case 522: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2691 +//line sql.y:2699 { yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes)} } case 523: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2695 +//line sql.y:2703 { yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes), Length: yyDollar[2].sqlVal} } case 524: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2699 +//line sql.y:2707 { yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes)} yyVAL.convertType.Length = yyDollar[2].LengthScaleOption.Length @@ -6006,169 +6014,169 @@ yydefault: } case 525: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2705 +//line sql.y:2713 { yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes)} } case 526: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2709 +//line sql.y:2717 { yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes), Length: yyDollar[2].sqlVal} } case 527: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2713 +//line sql.y:2721 { yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes)} } case 528: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2717 +//line sql.y:2725 { yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes)} } case 529: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2721 +//line sql.y:2729 { yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes), Length: yyDollar[2].sqlVal} } case 530: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2725 +//line sql.y:2733 { yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes)} } case 531: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2729 +//line sql.y:2737 { yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes)} } case 532: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:2734 +//line sql.y:2742 { yyVAL.expr = nil } case 533: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2738 +//line sql.y:2746 { yyVAL.expr = yyDollar[1].expr } case 534: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:2743 +//line sql.y:2751 { yyVAL.str = string("") } case 535: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2747 +//line sql.y:2755 { yyVAL.str = " separator '" + string(yyDollar[2].bytes) + "'" } case 536: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2753 +//line sql.y:2761 { yyVAL.whens = []*When{yyDollar[1].when} } case 537: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2757 +//line sql.y:2765 { yyVAL.whens = append(yyDollar[1].whens, yyDollar[2].when) } case 538: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:2763 +//line sql.y:2771 { yyVAL.when = &When{Cond: yyDollar[2].expr, Val: yyDollar[4].expr} } case 539: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:2768 +//line sql.y:2776 { yyVAL.expr = nil } case 540: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2772 +//line sql.y:2780 { yyVAL.expr = yyDollar[2].expr } case 541: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2778 +//line sql.y:2786 { yyVAL.colName = &ColName{Name: yyDollar[1].colIdent} } case 542: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2782 +//line sql.y:2790 { yyVAL.colName = &ColName{Qualifier: TableName{Name: yyDollar[1].tableIdent}, Name: yyDollar[3].colIdent} } case 543: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:2786 +//line sql.y:2794 { yyVAL.colName = &ColName{Qualifier: TableName{Qualifier: yyDollar[1].tableIdent, Name: yyDollar[3].tableIdent}, Name: yyDollar[5].colIdent} } case 544: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2792 +//line sql.y:2800 { yyVAL.expr = NewStrVal(yyDollar[1].bytes) } case 545: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2796 +//line sql.y:2804 { yyVAL.expr = NewHexVal(yyDollar[1].bytes) } case 546: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2800 +//line sql.y:2808 { yyVAL.expr = NewBitVal(yyDollar[1].bytes) } case 547: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2804 +//line sql.y:2812 { yyVAL.expr = NewIntVal(yyDollar[1].bytes) } case 548: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2808 +//line sql.y:2816 { yyVAL.expr = NewFloatVal(yyDollar[1].bytes) } case 549: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2812 +//line sql.y:2820 { yyVAL.expr = NewHexNum(yyDollar[1].bytes) } case 550: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2816 +//line sql.y:2824 { yyVAL.expr = NewValArg(yyDollar[1].bytes) } case 551: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2820 +//line sql.y:2828 { yyVAL.expr = &NullVal{} } case 552: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2826 +//line sql.y:2834 { // TODO(sougou): Deprecate this construct. if yyDollar[1].colIdent.Lowered() != "value" { @@ -6179,237 +6187,237 @@ yydefault: } case 553: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2835 +//line sql.y:2843 { yyVAL.expr = NewIntVal(yyDollar[1].bytes) } case 554: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2839 +//line sql.y:2847 { yyVAL.expr = NewValArg(yyDollar[1].bytes) } case 555: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:2844 +//line sql.y:2852 { yyVAL.exprs = nil } case 556: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2848 +//line sql.y:2856 { yyVAL.exprs = yyDollar[3].exprs } case 557: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:2853 +//line sql.y:2861 { yyVAL.expr = nil } case 558: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2857 +//line sql.y:2865 { yyVAL.expr = yyDollar[2].expr } case 559: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:2862 +//line sql.y:2870 { yyVAL.orderBy = nil } case 560: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2866 +//line sql.y:2874 { yyVAL.orderBy = yyDollar[3].orderBy } case 561: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2872 +//line sql.y:2880 { yyVAL.orderBy = OrderBy{yyDollar[1].order} } case 562: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2876 +//line sql.y:2884 { yyVAL.orderBy = append(yyDollar[1].orderBy, yyDollar[3].order) } case 563: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2882 +//line sql.y:2890 { yyVAL.order = &Order{Expr: yyDollar[1].expr, Direction: yyDollar[2].str} } case 564: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:2887 +//line sql.y:2895 { yyVAL.str = AscScr } case 565: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2891 +//line sql.y:2899 { yyVAL.str = AscScr } case 566: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2895 +//line sql.y:2903 { yyVAL.str = DescScr } case 567: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:2900 +//line sql.y:2908 { yyVAL.limit = nil } case 568: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2904 +//line sql.y:2912 { yyVAL.limit = &Limit{Rowcount: yyDollar[2].expr} } case 569: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:2908 +//line sql.y:2916 { yyVAL.limit = &Limit{Offset: yyDollar[2].expr, Rowcount: yyDollar[4].expr} } case 570: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:2912 +//line sql.y:2920 { yyVAL.limit = &Limit{Offset: yyDollar[4].expr, Rowcount: yyDollar[2].expr} } case 571: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:2917 +//line sql.y:2925 { yyVAL.str = "" } case 572: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2921 +//line sql.y:2929 { yyVAL.str = ForUpdateStr } case 573: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:2925 +//line sql.y:2933 { yyVAL.str = ShareModeStr } case 574: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2938 +//line sql.y:2946 { yyVAL.ins = &Insert{Rows: yyDollar[2].values} } case 575: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2942 +//line sql.y:2950 { yyVAL.ins = &Insert{Rows: yyDollar[1].selStmt} } case 576: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2946 +//line sql.y:2954 { // Drop the redundant parenthesis. yyVAL.ins = &Insert{Rows: yyDollar[2].selStmt} } case 577: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:2951 +//line sql.y:2959 { yyVAL.ins = &Insert{Columns: yyDollar[2].columns, Rows: yyDollar[5].values} } case 578: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:2955 +//line sql.y:2963 { yyVAL.ins = &Insert{Columns: yyDollar[2].columns, Rows: yyDollar[4].selStmt} } case 579: yyDollar = yyS[yypt-6 : yypt+1] -//line sql.y:2959 +//line sql.y:2967 { // Drop the redundant parenthesis. yyVAL.ins = &Insert{Columns: yyDollar[2].columns, Rows: yyDollar[5].selStmt} } case 580: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2966 +//line sql.y:2974 { yyVAL.columns = Columns{yyDollar[1].colIdent} } case 581: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2970 +//line sql.y:2978 { yyVAL.columns = Columns{yyDollar[3].colIdent} } case 582: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2974 +//line sql.y:2982 { yyVAL.columns = append(yyVAL.columns, yyDollar[3].colIdent) } case 583: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:2978 +//line sql.y:2986 { yyVAL.columns = append(yyVAL.columns, yyDollar[5].colIdent) } case 584: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:2983 +//line sql.y:2991 { yyVAL.updateExprs = nil } case 585: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:2987 +//line sql.y:2995 { yyVAL.updateExprs = yyDollar[5].updateExprs } case 586: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2993 +//line sql.y:3001 { yyVAL.values = Values{yyDollar[1].valTuple} } case 587: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2997 +//line sql.y:3005 { yyVAL.values = append(yyDollar[1].values, yyDollar[3].valTuple) } case 588: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3003 +//line sql.y:3011 { yyVAL.valTuple = yyDollar[1].valTuple } case 589: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:3007 +//line sql.y:3015 { yyVAL.valTuple = ValTuple{} } case 590: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:3013 +//line sql.y:3021 { yyVAL.valTuple = ValTuple(yyDollar[2].exprs) } case 591: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3019 +//line sql.y:3027 { if len(yyDollar[1].valTuple) == 1 { yyVAL.expr = &ParenExpr{yyDollar[1].valTuple[0]} @@ -6419,277 +6427,277 @@ yydefault: } case 592: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3029 +//line sql.y:3037 { yyVAL.updateExprs = UpdateExprs{yyDollar[1].updateExpr} } case 593: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:3033 +//line sql.y:3041 { yyVAL.updateExprs = append(yyDollar[1].updateExprs, yyDollar[3].updateExpr) } case 594: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:3039 +//line sql.y:3047 { yyVAL.updateExpr = &UpdateExpr{Name: yyDollar[1].colName, Expr: yyDollar[3].expr} } case 595: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3045 +//line sql.y:3053 { yyVAL.setExprs = SetExprs{yyDollar[1].setExpr} } case 596: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:3049 +//line sql.y:3057 { yyVAL.setExprs = append(yyDollar[1].setExprs, yyDollar[3].setExpr) } case 597: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:3055 +//line sql.y:3063 { yyVAL.setExpr = &SetExpr{Name: yyDollar[1].colIdent, Expr: NewStrVal([]byte("on"))} } case 598: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:3059 +//line sql.y:3067 { yyVAL.setExpr = &SetExpr{Name: yyDollar[1].colIdent, Expr: NewStrVal([]byte("off"))} } case 599: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:3063 +//line sql.y:3071 { yyVAL.setExpr = &SetExpr{Name: yyDollar[1].colIdent, Expr: yyDollar[3].expr} } case 600: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:3067 +//line sql.y:3075 { yyVAL.setExpr = &SetExpr{Name: NewColIdent(string(yyDollar[1].bytes)), Expr: yyDollar[2].expr} } case 602: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:3074 +//line sql.y:3082 { yyVAL.bytes = []byte("charset") } case 604: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3081 +//line sql.y:3089 { yyVAL.expr = NewStrVal([]byte(yyDollar[1].colIdent.String())) } case 605: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3085 +//line sql.y:3093 { yyVAL.expr = NewStrVal(yyDollar[1].bytes) } case 606: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3089 +//line sql.y:3097 { yyVAL.expr = &Default{} } case 609: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:3098 +//line sql.y:3106 { yyVAL.byt = 0 } case 610: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:3100 +//line sql.y:3108 { yyVAL.byt = 1 } case 611: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:3103 +//line sql.y:3111 { yyVAL.empty = struct{}{} } case 612: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:3105 +//line sql.y:3113 { yyVAL.empty = struct{}{} } case 613: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:3108 +//line sql.y:3116 { yyVAL.str = "" } case 614: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3110 +//line sql.y:3118 { yyVAL.str = IgnoreStr } case 615: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3114 +//line sql.y:3122 { yyVAL.empty = struct{}{} } case 616: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3116 +//line sql.y:3124 { yyVAL.empty = struct{}{} } case 617: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3118 +//line sql.y:3126 { yyVAL.empty = struct{}{} } case 618: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3120 +//line sql.y:3128 { yyVAL.empty = struct{}{} } case 619: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3122 +//line sql.y:3130 { yyVAL.empty = struct{}{} } case 620: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3124 +//line sql.y:3132 { yyVAL.empty = struct{}{} } case 621: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3126 +//line sql.y:3134 { yyVAL.empty = struct{}{} } case 622: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3128 +//line sql.y:3136 { yyVAL.empty = struct{}{} } case 623: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3130 +//line sql.y:3138 { yyVAL.empty = struct{}{} } case 624: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3132 +//line sql.y:3140 { yyVAL.empty = struct{}{} } case 625: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:3135 +//line sql.y:3143 { yyVAL.empty = struct{}{} } case 626: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3137 +//line sql.y:3145 { yyVAL.empty = struct{}{} } case 627: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3139 +//line sql.y:3147 { yyVAL.empty = struct{}{} } case 628: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3143 +//line sql.y:3151 { yyVAL.empty = struct{}{} } case 629: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3145 +//line sql.y:3153 { yyVAL.empty = struct{}{} } case 630: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:3148 +//line sql.y:3156 { yyVAL.empty = struct{}{} } case 631: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3150 +//line sql.y:3158 { yyVAL.empty = struct{}{} } case 632: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3152 +//line sql.y:3160 { yyVAL.empty = struct{}{} } case 633: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:3155 +//line sql.y:3163 { yyVAL.colIdent = ColIdent{} } case 634: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:3157 +//line sql.y:3165 { yyVAL.colIdent = yyDollar[2].colIdent } case 635: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3161 +//line sql.y:3169 { yyVAL.colIdent = NewColIdent(string(yyDollar[1].bytes)) } case 636: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3165 +//line sql.y:3173 { yyVAL.colIdent = NewColIdent(string(yyDollar[1].bytes)) } case 638: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3172 +//line sql.y:3180 { yyVAL.colIdent = NewColIdent(string(yyDollar[1].bytes)) } case 639: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3178 +//line sql.y:3186 { yyVAL.tableIdent = NewTableIdent(string(yyDollar[1].bytes)) } case 640: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3182 +//line sql.y:3190 { yyVAL.tableIdent = NewTableIdent(string(yyDollar[1].bytes)) } case 642: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3189 +//line sql.y:3197 { yyVAL.tableIdent = NewTableIdent(string(yyDollar[1].bytes)) } case 849: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3421 +//line sql.y:3429 { if incNesting(yylex) { yylex.Error("max nesting level reached") @@ -6698,31 +6706,31 @@ yydefault: } case 850: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3430 +//line sql.y:3438 { decNesting(yylex) } case 851: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:3435 +//line sql.y:3443 { skipToEnd(yylex) } case 852: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:3440 +//line sql.y:3448 { skipToEnd(yylex) } case 853: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3444 +//line sql.y:3452 { skipToEnd(yylex) } case 854: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3448 +//line sql.y:3456 { skipToEnd(yylex) } diff --git a/go/vt/sqlparser/sql.y b/go/vt/sqlparser/sql.y index af2bba3a92b..586cdec597e 100644 --- a/go/vt/sqlparser/sql.y +++ b/go/vt/sqlparser/sql.y @@ -1308,19 +1308,27 @@ alter_statement: { $$ = &DDL{Action: AlterStr, Table: $4, PartitionSpec: $5} } -| ALTER VSCHEMA CREATE VINDEX sql_id vindex_type_opt vindex_params_opt +| ALTER VSCHEMA CREATE VINDEX table_name vindex_type_opt vindex_params_opt { - $$ = &DDL{Action: CreateVindexStr, VindexSpec: &VindexSpec{ - Name: $5, - Type: $6, - Params: $7, - }} + $$ = &DDL{ + Action: CreateVindexStr, + Table: $5, + VindexSpec: &VindexSpec{ + Name: NewColIdent($5.Name.String()), + Type: $6, + Params: $7, + }, + } } -| ALTER VSCHEMA DROP VINDEX sql_id +| ALTER VSCHEMA DROP VINDEX table_name { - $$ = &DDL{Action: DropVindexStr, VindexSpec: &VindexSpec{ - Name: $5, - }} + $$ = &DDL{ + Action: DropVindexStr, + Table: $5, + VindexSpec: &VindexSpec{ + Name: NewColIdent($5.Name.String()), + }, + } } | ALTER VSCHEMA ADD TABLE table_name { diff --git a/go/vt/topo/server.go b/go/vt/topo/server.go index 6fb7795330e..8966f84f8dd 100644 --- a/go/vt/topo/server.go +++ b/go/vt/topo/server.go @@ -84,7 +84,7 @@ const ( KeyspacesPath = "keyspaces" ShardsPath = "shards" TabletsPath = "tablets" - MetadataPath = "vitess_metadata" + MetadataPath = "metadata" ) // Factory is a factory interface to create Conn objects. diff --git a/go/vt/vtgate/executor_test.go b/go/vt/vtgate/executor_test.go index bbb158bfebb..756c867d98a 100644 --- a/go/vt/vtgate/executor_test.go +++ b/go/vt/vtgate/executor_test.go @@ -1409,6 +1409,35 @@ func waitForColVindexes(t *testing.T, ks, table string, names []string, executor return nil } +func TestExecutorAlterVSchemaKeyspace(t *testing.T) { + *vschemaacl.AuthorizedDDLUsers = "%" + defer func() { + *vschemaacl.AuthorizedDDLUsers = "" + }() + executor, _, _, _ := createExecutorEnv() + session := NewSafeSession(&vtgatepb.Session{TargetString: "@master", Autocommit: true}) + + vschemaUpdates := make(chan *vschemapb.SrvVSchema, 2) + executor.serv.WatchSrvVSchema(context.Background(), "aa", func(vschema *vschemapb.SrvVSchema, err error) { + vschemaUpdates <- vschema + }) + + vschema := <-vschemaUpdates + _, ok := vschema.Keyspaces["TestExecutor"].Vindexes["test_vindex"] + if ok { + t.Fatalf("test_vindex should not exist in original vschema") + } + + stmt := "alter vschema create vindex TestExecutor.test_vindex using hash" + _, err := executor.Execute(context.Background(), "TestExecute", session, stmt, nil) + if err != nil { + t.Error(err) + } + + _, vindex := waitForVindex(t, "TestExecutor", "test_vindex", vschemaUpdates, executor) + assert.Equal(t, vindex.Type, "hash") +} + func TestExecutorCreateVindexDDL(t *testing.T) { *vschemaacl.AuthorizedDDLUsers = "%" defer func() { From 4d8a6a90c9151cea8ea71630ab23f656040ccb81 Mon Sep 17 00:00:00 2001 From: Morgan Tocker Date: Sat, 17 Aug 2019 13:21:48 -0600 Subject: [PATCH 033/425] Change to use tools/tools.go for go get dependencies Signed-off-by: Morgan Tocker --- bootstrap.sh | 16 ++-- go.mod | 93 ++++++++++---------- go.sum | 169 +++++++++++++++++++++++++++---------- misc/git/hooks/golint | 13 +-- misc/git/hooks/staticcheck | 13 +-- tools/tools.go | 14 +++ 6 files changed, 202 insertions(+), 116 deletions(-) create mode 100644 tools/tools.go diff --git a/bootstrap.sh b/bootstrap.sh index fecd19f6f2e..6c9ef84988f 100755 --- a/bootstrap.sh +++ b/bootstrap.sh @@ -44,14 +44,6 @@ mkdir -p "$VTROOT/bin" mkdir -p "$VTROOT/lib" mkdir -p "$VTROOT/vthook" -# Install git hooks. -echo "creating git hooks" -mkdir -p "$VTTOP/.git/hooks" -ln -sf "$VTTOP/misc/git/pre-commit" "$VTTOP/.git/hooks/pre-commit" -ln -sf "$VTTOP/misc/git/commit-msg" "$VTTOP/.git/hooks/commit-msg" -(cd "$VTTOP" && git config core.hooksPath "$VTTOP/.git/hooks") - - # This is required for VIRTUALENV # Used by Python below @@ -77,6 +69,14 @@ else ln -snf "$VTTOP/go/vt/zkctl/zksrv.sh" "$VTROOT/bin/zksrv.sh" fi +# git hooks are only required if someone intends to contribute. + +echo "creating git hooks" +mkdir -p "$VTTOP/.git/hooks" +ln -sf "$VTTOP/misc/git/pre-commit" "$VTTOP/.git/hooks/pre-commit" +ln -sf "$VTTOP/misc/git/commit-msg" "$VTTOP/.git/hooks/commit-msg" +(cd "$VTTOP" && git config core.hooksPath "$VTTOP/.git/hooks") + # install_dep is a helper function to generalize the download and installation of dependencies. # # If the installation is successful, it puts the installed version string into diff --git a/go.mod b/go.mod index 2ce411d025c..80246bb8b50 100644 --- a/go.mod +++ b/go.mod @@ -4,74 +4,75 @@ go 1.12 require ( cloud.google.com/go v0.43.0 + github.com/armon/go-metrics v0.0.0-20190430140413-ec5e00d3c878 // indirect github.com/aws/aws-sdk-go v0.0.0-20180223184012-ebef4262e06a - github.com/beorn7/perks v0.0.0-20160229213445-3ac7bf7a47d1 + github.com/boltdb/bolt v1.3.1 // indirect + github.com/cockroachdb/cmux v0.0.0-20170110192607-30d10be49292 // indirect + github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd // indirect github.com/coreos/etcd v0.0.0-20170626015032-703663d1f6ed - github.com/coreos/go-etcd v2.0.0+incompatible - github.com/davecgh/go-spew v0.0.0-20151105211317-5215b55f46b2 - github.com/ghodss/yaml v0.0.0-20161207003320-04f313413ffd - github.com/go-ini/ini v1.12.0 + github.com/coreos/go-semver v0.3.0 // indirect + github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f // indirect + github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f // indirect + github.com/dgrijalva/jwt-go v3.2.0+incompatible // indirect + github.com/ghodss/yaml v0.0.0-20161207003320-04f313413ffd // indirect + github.com/go-ini/ini v1.12.0 // indirect + github.com/gogo/protobuf v1.2.1 // indirect github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b + github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6 // indirect github.com/golang/mock v1.3.1 github.com/golang/protobuf v1.3.2 github.com/golang/snappy v0.0.0-20170215233205-553a64147049 - github.com/google/go-cmp v0.3.0 - github.com/googleapis/gax-go v1.0.3 - github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e github.com/gorilla/websocket v0.0.0-20160912153041-2d1e4548da23 github.com/grpc-ecosystem/go-grpc-middleware v0.0.0-20190118093823-f849b5445de4 github.com/grpc-ecosystem/go-grpc-prometheus v0.0.0-20180418170936-39de4380c2e0 - github.com/grpc-ecosystem/grpc-gateway v0.0.0-20161128002007-199c40a060d1 + github.com/grpc-ecosystem/grpc-gateway v0.0.0-20161128002007-199c40a060d1 // indirect github.com/hashicorp/consul v1.4.0 - github.com/hashicorp/go-cleanhttp v0.0.0-20160407174126-ad28ea4487f0 - github.com/hashicorp/go-rootcerts v0.0.0-20160503143440-6bb64b370b90 - github.com/hashicorp/golang-lru v0.5.3 - github.com/hashicorp/serf v0.0.0-20161207011743-d3a67ab21bc8 - github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8 - github.com/jtolds/gls v4.2.1+incompatible - github.com/klauspost/compress v0.0.0-20180801095237-b50017755d44 - github.com/klauspost/cpuid v1.2.0 - github.com/klauspost/crc32 v1.2.0 + github.com/hashicorp/go-msgpack v0.5.5 // indirect + github.com/hashicorp/go-rootcerts v0.0.0-20160503143440-6bb64b370b90 // indirect + github.com/hashicorp/go-uuid v1.0.1 // indirect + github.com/hashicorp/golang-lru v0.5.3 // indirect + github.com/hashicorp/memberlist v0.1.4 // indirect + github.com/hashicorp/serf v0.0.0-20161207011743-d3a67ab21bc8 // indirect + github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8 // indirect + github.com/jonboulle/clockwork v0.1.0 // indirect + github.com/klauspost/compress v0.0.0-20180801095237-b50017755d44 // indirect + github.com/klauspost/cpuid v1.2.0 // indirect + github.com/klauspost/crc32 v1.2.0 // indirect github.com/klauspost/pgzip v1.2.0 - github.com/mattn/go-runewidth v0.0.1 - github.com/matttproud/golang_protobuf_extensions v1.0.1 + github.com/kr/pretty v0.1.0 // indirect + github.com/mattn/go-runewidth v0.0.1 // indirect github.com/minio/minio-go v0.0.0-20190131015406-c8a261de75c1 - github.com/mitchellh/go-homedir v1.1.0 - github.com/mitchellh/mapstructure v1.1.2 + github.com/mitchellh/go-testing-interface v1.0.0 // indirect + github.com/mitchellh/mapstructure v1.1.2 // indirect github.com/olekukonko/tablewriter v0.0.0-20160115111002-cca8bbc07984 github.com/opentracing-contrib/go-grpc v0.0.0-20180928155321-4b5a12d3ff02 - github.com/opentracing/opentracing-go v1.0.2 + github.com/opentracing/opentracing-go v1.1.0 github.com/pborman/uuid v0.0.0-20160824210600-b984ec7fa9ff - github.com/pkg/errors v0.0.0-20190109061628-ffb6e22f0193 - github.com/pmezard/go-difflib v1.0.0 - github.com/prometheus/client_golang v0.0.0-20180319131721-d49167c4b9f3 - github.com/prometheus/client_model v0.0.0-20150212101744-fa8ad6fec335 - github.com/prometheus/common v0.0.0-20160607094339-3a184ff7dfd4 - github.com/prometheus/procfs v0.0.0-20160411190841-abf152e5f3e9 - github.com/satori/go.uuid v0.0.0-20160713180306-0aa62d5ddceb - github.com/sergi/go-diff v0.0.0-20170409071739-feef008d51ad - github.com/smartystreets/assertions v0.0.0-20190116191733-b6c0e53d7304 - github.com/smartystreets/goconvey v0.0.0-20181108003508-044398e4856c - github.com/stretchr/testify v0.0.0-20160524234229-8d64eb7173c7 + github.com/prometheus/client_golang v0.9.2 + github.com/satori/go.uuid v0.0.0-20160713180306-0aa62d5ddceb // indirect + github.com/stretchr/testify v1.3.0 github.com/tchap/go-patricia v0.0.0-20160729071656-dd168db6051b + github.com/uber-go/atomic v1.4.0 // indirect github.com/uber/jaeger-client-go v2.16.0+incompatible - github.com/uber/jaeger-lib v2.0.0+incompatible - github.com/yudai/gojsondiff v0.0.0-20170626131258-081cda2ee950 - github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82 + github.com/uber/jaeger-lib v2.0.0+incompatible // indirect + github.com/ugorji/go/codec v1.1.7 // indirect + github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 // indirect github.com/z-division/go-zookeeper v0.0.0-20190128072838-6d7457066b9b - go.opencensus.io v0.22.0 - golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5 - golang.org/x/net v0.0.0-20190620200207-3b0461eec859 + go.uber.org/atomic v1.4.0 // indirect + golang.org/x/crypto v0.0.0-20190829043050-9756ffdc2472 + golang.org/x/lint v0.0.0-20190409202823-959b441ac422 + golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297 golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 - golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0 + golang.org/x/sys v0.0.0-20190830142957-1e83adbbebd0 // indirect golang.org/x/text v0.3.2 golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 + golang.org/x/tools v0.0.0-20190830154057-c17b040389b9 google.golang.org/api v0.7.0 - google.golang.org/appengine v1.6.1 - google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64 + google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64 // indirect google.golang.org/grpc v1.21.1 - gopkg.in/asn1-ber.v1 v1.0.0-20150924051756-4e86f4367175 - gopkg.in/ini.v1 v1.41.0 + gopkg.in/asn1-ber.v1 v1.0.0-20150924051756-4e86f4367175 // indirect + gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect gopkg.in/ldap.v2 v2.5.0 - gopkg.in/yaml.v2 v2.0.0-20160928153709-a5b47d31c556 + gopkg.in/yaml.v2 v2.0.0-20160928153709-a5b47d31c556 // indirect + honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a ) diff --git a/go.sum b/go.sum index 30092e25680..63bae706de9 100644 --- a/go.sum +++ b/go.sum @@ -3,24 +3,49 @@ cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMT cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= cloud.google.com/go v0.43.0 h1:banaiRPAM8kUVYneOSkhgcDsLzEvL25FinuiSZaH/2w= cloud.google.com/go v0.43.0/go.mod h1:BOSR3VbTLkk6FDC/TcffxP4NF/FFBGA5ku+jvKOP7pg= +github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/DataDog/datadog-go v2.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= +github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= +github.com/armon/go-metrics v0.0.0-20190430140413-ec5e00d3c878 h1:EFSB7Zo9Eg91v7MJPVsifUysc/wPdN+NOnVe6bWbdBM= +github.com/armon/go-metrics v0.0.0-20190430140413-ec5e00d3c878/go.mod h1:3AMJUQhVx52RsWOnlkpikZr01T/yAVN2gn0861vByNg= github.com/aws/aws-sdk-go v0.0.0-20180223184012-ebef4262e06a h1:Ed33uJE74ksDaYfdY72gK7Cg//o2FgsqlqUfBW079T8= github.com/aws/aws-sdk-go v0.0.0-20180223184012-ebef4262e06a/go.mod h1:ZRmQr0FajVIyZ4ZzBYKG5P3ZqPz9IHG41ZoMu1ADI3k= -github.com/beorn7/perks v0.0.0-20160229213445-3ac7bf7a47d1 h1:OnJHjoVbY69GG4gclp0ngXfywigLhR6rrgUxmxQRWO4= -github.com/beorn7/perks v0.0.0-20160229213445-3ac7bf7a47d1/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973 h1:xJ4a3vCFaGF/jqvzLMYoU8P317H5OQ+Via4RmuPwCS0= +github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/boltdb/bolt v1.3.1 h1:JQmyP4ZBrce+ZQu0dY660FMfatumYDLun9hBCUVIkF4= +github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps= +github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag= +github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cockroachdb/cmux v0.0.0-20170110192607-30d10be49292 h1:dzj1/xcivGjNPwwifh/dWTczkwcuqsXXFHY1X/TZMtw= +github.com/cockroachdb/cmux v0.0.0-20170110192607-30d10be49292/go.mod h1:qRiX68mZX1lGBkTWyp3CLcenw9I94W2dLeRvMzcn9N4= +github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd h1:qMd81Ts1T2OTKmB4acZcyKaMtRnY5Y44NuXGX2GFJ1w= +github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= github.com/coreos/etcd v0.0.0-20170626015032-703663d1f6ed h1:uycR38QXnpc8YtCCTsNnQfeq6nPQ55F4ld6/WtGAIlM= github.com/coreos/etcd v0.0.0-20170626015032-703663d1f6ed/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= -github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= -github.com/davecgh/go-spew v0.0.0-20151105211317-5215b55f46b2/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmfM= +github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f h1:JOrtw2xFKzlg+cbHpyrpLDmnN1HqhBfnX7WDiW7eG2c= +github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f h1:lBNOc5arjvs8E5mO2tbpBpLoyyu8B6e44T7hJy6potg= +github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM= +github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/ghodss/yaml v0.0.0-20161207003320-04f313413ffd h1:U3yHrYB7NWH2o3UFzJ1J+TknZqM9QQtF8KVIE6Qzrfs= github.com/ghodss/yaml v0.0.0-20161207003320-04f313413ffd/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/go-ini/ini v1.12.0 h1:K324HQuOp7fYRWIW84d39Y7MqlH/0JU9fImSXUJ2TWk= github.com/go-ini/ini v1.12.0/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8= +github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E= -github.com/golang/mock v1.0.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6 h1:ZgQEtGgCBiWRM39fZuwSd1LwSqqSW0hOdXCYYDX0R3I= +github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.3.1 h1:qGJ6qTW+x6xX/my+8YUVl4WNpX9B7+/l2tRsHGZ7f2s= @@ -32,20 +57,19 @@ github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5y github.com/golang/snappy v0.0.0-20170215233205-553a64147049 h1:K9KHZbXKpGydfDN0aZrsoHpLJlZsBrGMFWbgLDGnPZk= github.com/golang/snappy v0.0.0-20170215233205-553a64147049/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/go-cmp v0.0.0-20190801213755-6d8cafd2f64f/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPgecwXBIDzw5no= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/googleapis/gax-go v1.0.3 h1:9dMLqhaibYONnDRcnHdUs9P8Mw64jLlZTYlDe3leBtQ= -github.com/googleapis/gax-go v1.0.3/go.mod h1:QyXYajJFdARxGzjwUfbDFIse7Spkw81SJ4LrBJXtlQ8= -github.com/googleapis/gax-go/v2 v2.0.2/go.mod h1:LLvjysVCY1JZeum8Z6l8qUty8fiNwE08qbEPm1M08qg= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5 h1:sjZBwGj9Jlw33ImPtvFviGYvseOtDM7hkSKB7+Tv3SM= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= -github.com/gopherjs/gopherjs v0.0.0-20160612211759-a727a4a1dd2f/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e h1:JKmoR8x90Iww1ks85zJ1lfDGgIiMDuIptTOhJq+zKyg= github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/websocket v0.0.0-20160912153041-2d1e4548da23 h1:NqeYYy/q+eU5bXzLrVTFSEMp5/VFwp3eJ6nkDsi7wos= github.com/gorilla/websocket v0.0.0-20160912153041-2d1e4548da23/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= @@ -53,24 +77,45 @@ github.com/grpc-ecosystem/go-grpc-middleware v0.0.0-20190118093823-f849b5445de4 github.com/grpc-ecosystem/go-grpc-middleware v0.0.0-20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-prometheus v0.0.0-20180418170936-39de4380c2e0 h1:6kldmIygVGmNHiCpXorySJ3/iICRLC20KBy2h1OzCUw= github.com/grpc-ecosystem/go-grpc-prometheus v0.0.0-20180418170936-39de4380c2e0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= +github.com/grpc-ecosystem/grpc-gateway v0.0.0-20161128002007-199c40a060d1 h1:HpW72214zD3cWQsV9DW4Sd9piuuw8rPmE4/TAjTgYIE= github.com/grpc-ecosystem/grpc-gateway v0.0.0-20161128002007-199c40a060d1/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw= github.com/hashicorp/consul v1.4.0 h1:PQTW4xCuAExEiSbhrsFsikzbW5gVBoi74BjUvYFyKHw= github.com/hashicorp/consul v1.4.0/go.mod h1:mFrjN1mfidgJfYP1xrJCF+AfRhr6Eaqhb2+sfyn/OOI= -github.com/hashicorp/go-cleanhttp v0.0.0-20160407174126-ad28ea4487f0 h1:2l0haPDqCzZEO160UR5DSrrl8RWptFCoxFsSbRLJBaI= -github.com/hashicorp/go-cleanhttp v0.0.0-20160407174126-ad28ea4487f0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA= +github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-cleanhttp v0.5.0 h1:wvCrVc9TjDls6+YGAF2hAifE1E5U1+b4tH6KdvN3Gig= +github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-immutable-radix v1.0.0 h1:AKDB1HM5PWEA7i4nhcpwOrO2byshxBjXVn/J/3+z5/0= +github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= +github.com/hashicorp/go-msgpack v0.5.5 h1:i9R9JSrqIz0QVLz3sz+i3YJdT7TTSLcfLLzJi9aZTuI= +github.com/hashicorp/go-msgpack v0.5.5/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= +github.com/hashicorp/go-multierror v1.0.0 h1:iVjPR7a6H0tWELX5NxNe7bYopibicUzc7uPribsnS6o= +github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= +github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= github.com/hashicorp/go-rootcerts v0.0.0-20160503143440-6bb64b370b90 h1:VBj0QYQ0u2MCJzBfeYXGexnAl17GsH1yidnoxCqqD9E= github.com/hashicorp/go-rootcerts v0.0.0-20160503143440-6bb64b370b90/go.mod h1:o4zcYY1e0GEZI6eSEr+43QDYmuGglw1qSO6qdHUHCgg= +github.com/hashicorp/go-sockaddr v1.0.0 h1:GeH6tui99pF4NJgfnhp+L6+FfobzVW3Ah46sLo0ICXs= +github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= +github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.1 h1:fv1ep09latC32wFoVwnqcnKJGnMSdBanPczbHAYm1BE= +github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.3 h1:YPkqC67at8FYaadspW/6uE0COsBxS2656RLEr8Bppgk= github.com/hashicorp/golang-lru v0.5.3/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= +github.com/hashicorp/memberlist v0.1.4 h1:gkyML/r71w3FL8gUi74Vk76avkj/9lYAY9lvg0OcoGs= +github.com/hashicorp/memberlist v0.1.4/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= github.com/hashicorp/serf v0.0.0-20161207011743-d3a67ab21bc8 h1:Vd9tjFEMH3X1AMV1BzVAZRwnjy9MoxOsOl+1pqpCVQs= github.com/hashicorp/serf v0.0.0-20161207011743-d3a67ab21bc8/go.mod h1:h/Ru6tmZazX7WO/GDmwdpS975F019L4t5ng5IgwbNrE= github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8 h1:12VvqtR6Aowv3l/EQUlocDHW2Cp4G9WJVH7uyH8QFJE= github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= +github.com/jonboulle/clockwork v0.1.0 h1:VKV+ZcuP6l3yW9doeqz6ziZGgcynBVQO+obU0+0hcPo= +github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= -github.com/jtolds/gls v4.2.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +github.com/jtolds/gls v4.2.1+incompatible h1:fSuqC+Gmlu6l/ZYAoZzx2pyucC8Xza35fpRVWLVmUEE= github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v0.0.0-20180801095237-b50017755d44 h1:uDhun+KVSncSm1UeN8A4llsQ6E+xAIBmhh816Q2zeOk= github.com/klauspost/compress v0.0.0-20180801095237-b50017755d44/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= @@ -80,78 +125,105 @@ github.com/klauspost/crc32 v1.2.0 h1:0VuyqOCruD33/lJ/ojXNvzVyl8Zr5zdTmj9l9qLZ86I github.com/klauspost/crc32 v1.2.0/go.mod h1:+ZoRqAPRLkC4NPOvfYeR5KNOrY6TD+/sAC3HXPZgDYg= github.com/klauspost/pgzip v1.2.0 h1:SPtjjC68wy5g65KwQS4TcYtm6x/O8H4jSxtKZfhN4s0= github.com/klauspost/pgzip v1.2.0/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs= +github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/mattn/go-runewidth v0.0.1 h1:+EiaBVXhogb1Klb4tRJ7hYnuGK6PkKOZlK04D/GMOqk= github.com/mattn/go-runewidth v0.0.1/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/miekg/dns v1.0.14 h1:9jZdLNd/P4+SfEJ0TNyxYpsK8N4GtfylBLqtbYN1sbA= +github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/minio/minio-go v0.0.0-20190131015406-c8a261de75c1 h1:jw16EimP5oAEM/2wt+SiEUov/YDyTCTDuPtIKgQIvk0= github.com/minio/minio-go v0.0.0-20190131015406-c8a261de75c1/go.mod h1:vuvdOZLJuf5HmJAJrKV64MmozrSsk+or0PB5dzdfspg= -github.com/mitchellh/go-homedir v0.0.0-20161203194507-b8bc1bf76747/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-testing-interface v1.0.0 h1:fzU/JVNcaqHQEcVFAKeR41fkiLdIPrefOvVG1VZ96U0= +github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/olekukonko/tablewriter v0.0.0-20160115111002-cca8bbc07984 h1:c9gVtoY8wPlhJIN2V2I1V+Fn9UcXM8mDG8IHv/1c3r8= github.com/olekukonko/tablewriter v0.0.0-20160115111002-cca8bbc07984/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= github.com/opentracing-contrib/go-grpc v0.0.0-20180928155321-4b5a12d3ff02 h1:0R5mDLI66Qw13qN80TRz85zthQ2nf2+uDyiV23w6c3Q= github.com/opentracing-contrib/go-grpc v0.0.0-20180928155321-4b5a12d3ff02/go.mod h1:JNdpVEzCpXBgIiv4ds+TzhN1hrtxq6ClLrTlT9OQRSc= -github.com/opentracing/opentracing-go v1.0.2 h1:3jA2P6O1F9UOrWVpwrIo17pu01KWvNWg4X946/Y5Zwg= -github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/opentracing/opentracing-go v1.1.0 h1:pWlfV3Bxv7k65HYwkikxat0+s3pV4bsqf19k25Ur8rU= +github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY= +github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pborman/uuid v0.0.0-20160824210600-b984ec7fa9ff h1:pTiDfW+iOjIxjZeCm88gKn/AmR09UGZYZdqif2yPRrM= github.com/pborman/uuid v0.0.0-20160824210600-b984ec7fa9ff/go.mod h1:VyrYX9gd7irzKovcSS6BIIEwPRkP2Wm2m9ufcdFSJ34= -github.com/pkg/errors v0.0.0-20190109061628-ffb6e22f0193 h1:G+3hOJb+jr4ruKVe4WWvC0wXvPmVuKyb/tTlOyjAisU= -github.com/pkg/errors v0.0.0-20190109061628-ffb6e22f0193/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/prometheus/client_golang v0.0.0-20180319131721-d49167c4b9f3 h1:IlkKMWpcBADSCBBkzSukNTFPfhEV+3VyGN4b0Wc2IUA= -github.com/prometheus/client_golang v0.0.0-20180319131721-d49167c4b9f3/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= -github.com/prometheus/client_model v0.0.0-20150212101744-fa8ad6fec335 h1:0E/5GnGmzoDCtmzTycjGDWW33H0UBmAhR0h+FC8hWLs= -github.com/prometheus/client_model v0.0.0-20150212101744-fa8ad6fec335/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= -github.com/prometheus/common v0.0.0-20160607094339-3a184ff7dfd4 h1:mj5hNmXtX1FzwvmFDf11SH19Q6paZCVkpa1R2UBLapQ= -github.com/prometheus/common v0.0.0-20160607094339-3a184ff7dfd4/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= -github.com/prometheus/procfs v0.0.0-20160411190841-abf152e5f3e9 h1:ex32PG6WhE5zviWS08vcXTwX2IkaH9zpeYZZvrmj3/U= -github.com/prometheus/procfs v0.0.0-20160411190841-abf152e5f3e9/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/client_golang v0.9.2 h1:awm861/B8OKDd2I/6o1dy3ra4BamzKhYOiGItCeZ740= +github.com/prometheus/client_golang v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4xf/QclQDMrYNZzcM= +github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910 h1:idejC8f05m9MGOsuEi1ATq9shN03HrxNkD/luQvxCv8= +github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/common v0.0.0-20181126121408-4724e9255275 h1:PnBWHBf+6L0jOqq0gIVUe6Yk0/QMZ640k6NvkxcBf+8= +github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= +github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a h1:9a8MnZMP0X2nLJdBg+pBmGgkJlSaKC2KaQmTCk1XDtE= +github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/satori/go.uuid v0.0.0-20160713180306-0aa62d5ddceb h1:1r/p6yT1FfHR1+qBm7UYBPgfqCmzz/8mpNvfc+iKlfU= github.com/satori/go.uuid v0.0.0-20160713180306-0aa62d5ddceb/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= -github.com/sergi/go-diff v0.0.0-20170409071739-feef008d51ad/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= -github.com/smartystreets/assertions v0.0.0-20160422195351-40711f774818/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= +github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUtVbo7ada43DJhG55ua/hjS5I= +github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= +github.com/smartystreets/assertions v0.0.0-20190116191733-b6c0e53d7304 h1:Jpy1PXuP99tXNrhbq2BaPz9B+jNAvH1JPQQpG/9GCXY= github.com/smartystreets/assertions v0.0.0-20190116191733-b6c0e53d7304/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= -github.com/smartystreets/goconvey v0.0.0-20160523153147-c53abc99456f/go.mod h1:XDJAKZRPZ1CvBcN2aX5YOUTYGHki24fSF0Iv48Ibg0s= +github.com/smartystreets/goconvey v0.0.0-20181108003508-044398e4856c h1:Ho+uVpkel/udgjbwB5Lktg9BtvJSh2DT0Hi6LPSyI2w= github.com/smartystreets/goconvey v0.0.0-20181108003508-044398e4856c/go.mod h1:XDJAKZRPZ1CvBcN2aX5YOUTYGHki24fSF0Iv48Ibg0s= -github.com/stretchr/testify v0.0.0-20160524234229-8d64eb7173c7/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/tchap/go-patricia v0.0.0-20160729071656-dd168db6051b h1:i3lm+BZX5fAaH95wJavMgsSYU95LhSxdNCMa8nLv2gk= github.com/tchap/go-patricia v0.0.0-20160729071656-dd168db6051b/go.mod h1:bmLyhP68RS6kStMGxByiQ23RP/odRBOTVjwp2cDyi6I= +github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= +github.com/uber-go/atomic v1.4.0 h1:yOuPqEq4ovnhEjpHmfFwsqBXDYbQeT6Nb0bwD6XnD5o= +github.com/uber-go/atomic v1.4.0/go.mod h1:/Ct5t2lcmbJ4OSe/waGBoaVvVqtO0bmtfVNex1PFV8g= github.com/uber/jaeger-client-go v2.16.0+incompatible h1:Q2Pp6v3QYiocMxomCaJuwQGFt7E53bPYqEgug/AoBtY= github.com/uber/jaeger-client-go v2.16.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= github.com/uber/jaeger-lib v2.0.0+incompatible h1:iMSCV0rmXEogjNWPh2D0xk9YVKvrtGoHJNe9ebLu/pw= github.com/uber/jaeger-lib v2.0.0+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U= -github.com/yudai/gojsondiff v0.0.0-20170626131258-081cda2ee950/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg= -github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM= +github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo= +github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= +github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs= +github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= +github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 h1:eY9dn8+vbi4tKz5Qo6v2eYzo7kUS51QINcR5jNpbZS8= +github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/z-division/go-zookeeper v0.0.0-20190128072838-6d7457066b9b h1:Itr7GbuXoM1PK/eCeNNia4Qd3ib9IgX9g9SpXgo8BwQ= github.com/z-division/go-zookeeper v0.0.0-20190128072838-6d7457066b9b/go.mod h1:JNALoWa+nCXR8SmgLluHcBNVJgyejzpKPZk9pX2yXXE= -go.opencensus.io v0.0.0-20190713072201-b4a14686f0a9/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0 h1:C9hSCOW830chIVkdja34wa6Ky+IzWllkUinR+BtRZd4= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= +go.uber.org/atomic v1.4.0 h1:cxzIVoETapQEqDhQu3QfnvXAV4AlzcvUCxkVUFw3+EU= +go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190128193316-c7b33c32a30b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20190131182504-b8fe1690c613/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5 h1:58fnuSXlxZmFdJyvtTFVmVhcMLU6v5fEb/ok4wyqtNU= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190829043050-9756ffdc2472 h1:Gv7RPwsi3eZ2Fgewe3CBsuOebPwO27PoXzRpJPsvSSM= +golang.org/x/crypto v0.0.0-20190829043050-9756ffdc2472/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190221220918-438050ddec5e/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= -golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190409202823-959b441ac422 h1:QzoH/1pFpZguR8NrRHLcO6jKqfv2zpuSqZLgdm7ZmjI= golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190206173232-65e2d4e15006/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -160,6 +232,8 @@ golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190620200207-3b0461eec859 h1:R/3boaszxrf1GEUWTVDzSKVwLmSJpwZ1yqXm8j0v2QI= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297 h1:k7pJ2yAPLPgbskkFdhRCsA77k2fySZ1zf2zCjvQCiIM= +golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0= @@ -168,10 +242,11 @@ golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58 h1:8gQV6CLnAEikrhgkHFbMAEhagSSnXWGV915qUMm9mrU= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190124100055-b90733256f2e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190204203706-41f3e6584952/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -180,16 +255,16 @@ golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0 h1:HyfiK1WMnHj5FXFXatD+Qs1A/xC2Run6RzeW1SyHxpc= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/text v0.0.0-20181030141323-6f44c5a2ea40/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/sys v0.0.0-20190830142957-1e83adbbebd0 h1:7z820YPX9pxWR59qM7BE5+fglp4D/mKqAwCvGt11b+8= +golang.org/x/sys v0.0.0-20190830142957-1e83adbbebd0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= -golang.org/x/time v0.0.0-20161028155119-f51c12702a4d/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 h1:SvFZT6jyqRaOeXpc5h/JSfZenJ2O330aBsf7JfSUXmQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= @@ -200,12 +275,16 @@ golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBn golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190830154057-c17b040389b9 h1:5/jaG/gKlo3xxvUn85ReNyTlN7BvlPPsxC6sHZKjGEE= +golang.org/x/tools v0.0.0-20190830154057-c17b040389b9/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0 h1:9sdfJOzWlkqPltHAuzT2Cp+yrBeY1KRVYgms8soxMwM= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.6.1 h1:QzqyMA1tlu6CgqCDUtU9V+ZKhLFT2dkJuANu5QaxI3I= google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= @@ -215,20 +294,22 @@ google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRn google.golang.org/genproto v0.0.0-20190716160619-c506a9f90610/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64 h1:iKtrH9Y8mcbADOP0YFaEMth7OfuHY9xHOwNj4znpM1A= google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1 h1:j6XxA85m/6txkUCHvzlV5f+HBNl/1r5cZ2A/3IEFOO8= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= gopkg.in/asn1-ber.v1 v1.0.0-20150924051756-4e86f4367175 h1:nn6Zav2sOQHCFJHEspya8KqxhFwKci30UxHy3HXPTyQ= gopkg.in/asn1-ber.v1 v1.0.0-20150924051756-4e86f4367175/go.mod h1:cuepJuh7vyXfUyUwEgHQXw849cJrilpS5NeIjOWESAw= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/ini.v1 v1.41.0 h1:Ka3ViY6gNYSKiVy71zXBEqKplnV35ImDLVG+8uoIklE= gopkg.in/ini.v1 v1.41.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ldap.v2 v2.5.0 h1:1rO3ojzsHUk+gq4ZYhC4Pg+EzWaaKIV8+DJwExS5/QQ= gopkg.in/ldap.v2 v2.5.0/go.mod h1:oI0cpe/D7HRtBQl8aTg+ZmzFUAvu4lsv3eLXMLGFxWk= +gopkg.in/yaml.v2 v2.0.0-20160928153709-a5b47d31c556 h1:hKXbLW5oaJoQgs8KrzTLdF4PoHi+0oQPgea9TNtvE3E= gopkg.in/yaml.v2 v2.0.0-20160928153709-a5b47d31c556/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= -honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a h1:LJwr7TCTghdatWv40WobzlKXc9c4s8oGa7QKJUtHhWA= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= diff --git a/misc/git/hooks/golint b/misc/git/hooks/golint index 641d7d17f00..67f56b58393 100755 --- a/misc/git/hooks/golint +++ b/misc/git/hooks/golint @@ -23,11 +23,6 @@ if [ -z "$GOPATH" ]; then exit 1 fi -if [ -z "$(which golint)" ]; then - echo "golint not found, please run: go get github.com/golang/lint/golint" - exit 1 -fi - # This script does not handle file names that contain spaces. gofiles=$(git diff --cached --name-only --diff-filter=ACM | grep '^go/.*\.go$' | grep -v '^go/vt/proto/' | grep -v 'go/vt/sqlparser/sql.go') @@ -38,11 +33,11 @@ errors= gofiles_with_warnings=() for gofile in $gofiles do - errcount=$(golint $gofile | wc -l) + errcount=$(go run golang.org/x/lint/golint $gofile | wc -l) if [ "$errcount" -gt "0" ]; then errors=YES echo "$errcount suggestions for:" - echo "golint $gofile" + echo "go run golang.org/x/lint/golint $gofile" gofiles_with_warnings+=($gofile) fi done @@ -70,7 +65,7 @@ if [[ $? -eq 0 ]]; then echo "Press enter to show the warnings for the next file." read fi - golint $gofile + go run golang.org/x/lint/golint $gofile first_file="false" done fi @@ -78,7 +73,7 @@ else # non-interactive shell (e.g. called from Eclipse). Just display the errors. for gofile in "${gofiles_with_warnings[@]}" do - golint $gofile + go run golang.org/x/lint/golint $gofile done fi exit 1 diff --git a/misc/git/hooks/staticcheck b/misc/git/hooks/staticcheck index 61ca139f8a9..f0ea8d5d543 100755 --- a/misc/git/hooks/staticcheck +++ b/misc/git/hooks/staticcheck @@ -7,11 +7,6 @@ if [ -z "$GOPATH" ]; then exit 1 fi -if [ -z "$(which staticcheck)" ]; then - echo "staticcheck not found, please run: go get honnef.co/go/tools/cmd/staticcheck" - exit 1 -fi - # This script does not handle file names that contain spaces. # Exclude auto-generated files (from proto or yacc compile). gofiles=$(git diff --cached --name-only --diff-filter=ACM | grep '^go/.*\.go$' | grep -v '^go/vt/proto/' | grep -v 'go/vt/sqlparser/sql.go') @@ -28,11 +23,11 @@ warnings= gopackages_with_warnings=() for gopackage in $gopackages do - warningcount="$(staticcheck "vitess.io/vitess/$gopackage" | wc -l)" + warningcount="$(go run honnef.co/go/tools/cmd/staticcheck "vitess.io/vitess/$gopackage" | wc -l)" if [ "$warningcount" -gt "0" ]; then warnings=YES echo "$warningcount reports for:" - echo "staticcheck vitess.io/vitess/$gopackage" + echo "go run honnef.co/go/tools/cmd/staticcheck vitess.io/vitess/$gopackage" gopackages_with_warnings+=($gopackage) fi done @@ -61,7 +56,7 @@ if [[ $? -eq 0 ]]; then echo "Press enter to show the warnings for the next file." read fi - staticcheck "vitess.io/vitess/$gopackage" + go run honnef.co/go/tools/cmd/staticcheck "vitess.io/vitess/$gopackage" first_file="false" done fi @@ -69,7 +64,7 @@ else # non-interactive shell (e.g. called from Eclipse). Just display the warnings. for gopackage in "${gopackages_with_warnings[@]}" do - staticcheck "vitess.io/vitess/$gopackage" + go run honnef.co/go/tools/cmd/staticcheck "vitess.io/vitess/$gopackage" done fi exit 1 diff --git a/tools/tools.go b/tools/tools.go new file mode 100644 index 00000000000..341a800f86c --- /dev/null +++ b/tools/tools.go @@ -0,0 +1,14 @@ +// +build tools + +package tools + +// These imports ensure that "go mod tidy" won't remove deps +// for build-time dependencies like linters and code generators +import ( + _ "github.com/golang/mock/mockgen" + _ "golang.org/x/lint" + _ "golang.org/x/tools/cmd/cover" + _ "golang.org/x/tools/cmd/goimports" + _ "golang.org/x/tools/cmd/goyacc" + _ "honnef.co/go/tools/cmd/staticcheck" +) From 0a1a9afe4803b84c92deacdaa3a03327b2915288 Mon Sep 17 00:00:00 2001 From: Rasika Kale Date: Fri, 30 Aug 2019 11:22:47 -0700 Subject: [PATCH 034/425] Fixed arithmetic.go and arithmetic_test.go through comments via github - Added intMinusUintWithError() in arithmetic.go - Fixed error checking in arithmetic.go for intMinusIntWithError() Signed-off-by: Rasika Kale --- go/sqltypes/arithmetic.go | 16 +++++++++++++--- go/sqltypes/arithmetic_test.go | 14 +++++++++++++- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/go/sqltypes/arithmetic.go b/go/sqltypes/arithmetic.go index 1b1875a579c..6423490be1a 100644 --- a/go/sqltypes/arithmetic.go +++ b/go/sqltypes/arithmetic.go @@ -407,10 +407,15 @@ func addNumericWithError(v1, v2 numeric) (numeric, error) { } func subtractNumericWithError(v1, v2 numeric) (numeric, error) { - v1, v2 = prioritize(v1, v2) + //v1, v2 = prioritize(v1, v2) switch v1.typ { case Int64: - return intMinusIntWithError(v1.ival, v2.ival) + switch v2.typ { + case Int64: + return intMinusIntWithError(v1.ival, v2.ival) + case Uint64: + return intMinusUintWithError(v1.ival, v2.uval) + } case Uint64: switch v2.typ { case Int64: @@ -465,13 +470,18 @@ func intPlusIntWithError(v1, v2 int64) (numeric, error) { func intMinusIntWithError(v1, v2 int64) (numeric, error) { result := v1 - v2 - if v1 > 0 && v2 > math.MaxInt64 || v1 > math.MaxInt64 && v2 > 0 || v1 <= math.MinInt64 && v2 > 0 || v1 > 0 && v2 <= math.MinInt64 { + + if (result < v1) != (v2 > 0) { return numeric{}, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "BIGINT value is out of range in %v - %v", v1, v2) } return numeric{typ: Int64, ival: result}, nil } +func intMinusUintWithError(v1 int64, v2 uint64) (numeric, error) { + return intMinusIntWithError(v1, int64(v2)) +} + func uintPlusInt(v1 uint64, v2 int64) numeric { return uintPlusUint(v1, uint64(v2)) } diff --git a/go/sqltypes/arithmetic_test.go b/go/sqltypes/arithmetic_test.go index 4c9e56beddc..72a0e47206e 100644 --- a/go/sqltypes/arithmetic_test.go +++ b/go/sqltypes/arithmetic_test.go @@ -75,7 +75,7 @@ func TestSubtract(t *testing.T) { // testing for int64 overflow v1: NewInt64(math.MinInt64), v2: NewUint64(0), - err: vterrors.New(vtrpcpb.Code_INVALID_ARGUMENT, "BIGINT UNSIGNED value is out of range in 0 - -9223372036854775808"), + out: NewInt64(math.MinInt64), }, { v1: TestValue(VarChar, "c"), v2: NewInt64(1), @@ -109,6 +109,18 @@ func TestSubtract(t *testing.T) { v1: NewFloat64(1.2), v2: NewUint64(2), out: NewFloat64(-0.8), + }, { + v1: NewInt64(-1), + v2: NewUint64(2), + out: NewInt64(-3), + }, { + v1: NewInt64(5), + v2: NewUint64(7), + out: NewInt64(-2), + }, { + v1: NewInt64(-2), + v2: NewInt64(1), + out: NewInt64(-3), }} for _, tcase := range tcases { From 1141f5ae4bba2c8538639fde990eb52d010c0eec Mon Sep 17 00:00:00 2001 From: Rasika Kale Date: Fri, 30 Aug 2019 14:54:49 -0700 Subject: [PATCH 035/425] Deleted extra comments and tests in arithmetic.go and arithmetic_test.go Signed-off-by: Rasika Kale --- go/sqltypes/arithmetic.go | 1 - go/sqltypes/arithmetic_test.go | 8 -------- 2 files changed, 9 deletions(-) diff --git a/go/sqltypes/arithmetic.go b/go/sqltypes/arithmetic.go index 6423490be1a..f547e25b5c7 100644 --- a/go/sqltypes/arithmetic.go +++ b/go/sqltypes/arithmetic.go @@ -407,7 +407,6 @@ func addNumericWithError(v1, v2 numeric) (numeric, error) { } func subtractNumericWithError(v1, v2 numeric) (numeric, error) { - //v1, v2 = prioritize(v1, v2) switch v1.typ { case Int64: switch v2.typ { diff --git a/go/sqltypes/arithmetic_test.go b/go/sqltypes/arithmetic_test.go index 72a0e47206e..da076670a4c 100644 --- a/go/sqltypes/arithmetic_test.go +++ b/go/sqltypes/arithmetic_test.go @@ -113,14 +113,6 @@ func TestSubtract(t *testing.T) { v1: NewInt64(-1), v2: NewUint64(2), out: NewInt64(-3), - }, { - v1: NewInt64(5), - v2: NewUint64(7), - out: NewInt64(-2), - }, { - v1: NewInt64(-2), - v2: NewInt64(1), - out: NewInt64(-3), }} for _, tcase := range tcases { From 40af468221c45c60aa70f9642ebb757007995a94 Mon Sep 17 00:00:00 2001 From: Sugu Sougoumarane Date: Fri, 30 Aug 2019 16:00:00 -0700 Subject: [PATCH 036/425] vreplication: address review comments Signed-off-by: Sugu Sougoumarane --- .../vstreamer/rowstreamer_test.go | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/go/vt/vttablet/tabletserver/vstreamer/rowstreamer_test.go b/go/vt/vttablet/tabletserver/vstreamer/rowstreamer_test.go index 184496c8eb5..c57135f4d12 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/rowstreamer_test.go +++ b/go/vt/vttablet/tabletserver/vstreamer/rowstreamer_test.go @@ -42,11 +42,15 @@ func TestStreamRowsScan(t *testing.T) { // No PK "create table t3(id int, val varbinary(128))", "insert into t3 values (1, 'aaa'), (2, 'bbb')", + // Three-column PK + "create table t4(id1 int, id2 int, id3 int, val varbinary(128), primary key(id1, id2, id3))", + "insert into t4 values (1, 2, 3, 'aaa'), (2, 3, 4, 'bbb')", }) defer execStatements(t, []string{ "drop table t1", "drop table t2", "drop table t3", + "drop table t4", }) engine.se.Reload(context.Background()) @@ -105,6 +109,22 @@ func TestStreamRowsScan(t *testing.T) { } wantQuery = "select id, val from t3 where (id = 1 and val > 'aaa') or (id > 1) order by id, val" checkStream(t, "select * from t3", []sqltypes.Value{sqltypes.NewInt64(1), sqltypes.NewVarBinary("aaa")}, wantQuery, wantStream) + + // t4: all rows + wantStream = []string{ + `fields: fields: fields: fields: pkfields: pkfields: pkfields: `, + `rows: rows: lastpk: `, + } + wantQuery = "select id1, id2, id3, val from t4 order by id1, id2, id3" + checkStream(t, "select * from t4", nil, wantQuery, wantStream) + + // t4: lastpk: 1,2,3 + wantStream = []string{ + `fields: fields: fields: fields: pkfields: pkfields: pkfields: `, + `rows: lastpk: `, + } + wantQuery = "select id1, id2, id3, val from t4 where (id1 = 1 and id2 = 2 and id3 > 3) or (id1 = 1 and id2 > 2) or (id1 > 1) order by id1, id2, id3" + checkStream(t, "select * from t4", []sqltypes.Value{sqltypes.NewInt64(1), sqltypes.NewInt64(2), sqltypes.NewInt64(3)}, wantQuery, wantStream) } func TestStreamRowsUnicode(t *testing.T) { From 4dfa6a5478aac0529f916bb6d6e7549a57ea6ba1 Mon Sep 17 00:00:00 2001 From: Rasika Kale Date: Fri, 30 Aug 2019 16:43:12 -0700 Subject: [PATCH 037/425] Fixed error checking for overflow of integer multiplication Signed-off-by: Rasika Kale --- go/sqltypes/arithmetic.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/go/sqltypes/arithmetic.go b/go/sqltypes/arithmetic.go index 06b702f1a62..9af23dd36ce 100644 --- a/go/sqltypes/arithmetic.go +++ b/go/sqltypes/arithmetic.go @@ -512,10 +512,9 @@ func intMinusIntWithError(v1, v2 int64) (numeric, error) { func intTimesIntWithError(v1, v2 int64) (numeric, error) { result := v1 * v2 - if v1 >= math.MaxInt64 && v2 > 1 || v2 >= math.MaxInt64 && v1 > 1 || v1 <= math.MinInt64 && v2 > 1 || v2 <= math.MinInt64 && v1 > 1 { + if v1 != 0 && result/v1 != v2 { return numeric{}, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "BIGINT value is out of range in %v * %v", v1, v2) } - return numeric{typ: Int64, ival: result}, nil } From d5860b312cf019fa815e516e6e81c5388ff8890c Mon Sep 17 00:00:00 2001 From: Andres Taylor Date: Fri, 30 Aug 2019 14:37:34 +0200 Subject: [PATCH 038/425] Handle more situations with empty results and no grouping keys Fixes #5148 Signed-off-by: Andres Taylor --- go/vt/vtgate/engine/ordered_aggregate.go | 19 ++- go/vt/vtgate/engine/ordered_aggregate_test.go | 111 ++++++++++++------ 2 files changed, 87 insertions(+), 43 deletions(-) diff --git a/go/vt/vtgate/engine/ordered_aggregate.go b/go/vt/vtgate/engine/ordered_aggregate.go index 9e652727ec8..db4eb1df219 100644 --- a/go/vt/vtgate/engine/ordered_aggregate.go +++ b/go/vt/vtgate/engine/ordered_aggregate.go @@ -255,21 +255,21 @@ func (oa *OrderedAggregate) StreamExecute(vcursor VCursor, bindVars map[string]* return nil } -func (oa *OrderedAggregate) convertFields(fields []*querypb.Field) (newFields []*querypb.Field) { +func (oa *OrderedAggregate) convertFields(fields []*querypb.Field) []*querypb.Field { if !oa.HasDistinct { return fields } - newFields = append(newFields, fields...) + for _, aggr := range oa.Aggregates { if !aggr.isDistinct() { continue } - newFields[aggr.Col] = &querypb.Field{ + fields[aggr.Col] = &querypb.Field{ Name: aggr.Alias, Type: opcodeType[aggr.Opcode], } } - return newFields + return fields } func (oa *OrderedAggregate) convertRow(row []sqltypes.Value) (newRow []sqltypes.Value, curDistinct sqltypes.Value) { @@ -375,10 +375,17 @@ func (oa *OrderedAggregate) createEmptyRow() ([]sqltypes.Value, error) { func createEmptyValueFor(opcode AggregateOpcode) (sqltypes.Value, error) { switch opcode { - case AggregateCountDistinct: + case + AggregateCountDistinct, + AggregateCount: return countZero, nil - case AggregateSumDistinct: + case + AggregateSumDistinct, + AggregateSum, + AggregateMin, + AggregateMax: return sqltypes.NULL, nil + } return sqltypes.NULL, vterrors.Errorf(vtrpc.Code_INVALID_ARGUMENT, "unknown aggregation %v", opcode) } diff --git a/go/vt/vtgate/engine/ordered_aggregate_test.go b/go/vt/vtgate/engine/ordered_aggregate_test.go index d4201fad66c..9028b83d11a 100644 --- a/go/vt/vtgate/engine/ordered_aggregate_test.go +++ b/go/vt/vtgate/engine/ordered_aggregate_test.go @@ -666,42 +666,79 @@ func TestMerge(t *testing.T) { assert.Equal(want, merged) } -func TestNoInputAndNoGroupingKeys(t *testing.T) { - assert := assert.New(t) - fp := &fakePrimitive{ - results: []*sqltypes.Result{sqltypes.MakeTestResult( - sqltypes.MakeTestFields( - "col1|col2", - "int64|int64", - ), - // Empty input table - )}, +func TestNoInputAndNoGroupingKeys(outer *testing.T) { + testCases := []struct { + name string + opcode AggregateOpcode + expectedVal string + expectedTyp string + }{{ + "count(distinct col1)", + AggregateCountDistinct, + "0", + "int64", + }, { + "col1", + AggregateCount, + "0", + "int64", + }, { + "sum(distinct col1)", + AggregateSumDistinct, + "null", + "decimal", + }, { + "col1", + AggregateSum, + "null", + "int64", + }, { + "col1", + AggregateMax, + "null", + "int64", + }, { + "col1", + AggregateMin, + "null", + "int64", + }} + + for _, test := range testCases { + outer.Run(test.name, func(t *testing.T) { + assert := assert.New(t) + fp := &fakePrimitive{ + results: []*sqltypes.Result{sqltypes.MakeTestResult( + sqltypes.MakeTestFields( + "col1", + "int64", + ), + // Empty input table + )}, + } + + oa := &OrderedAggregate{ + HasDistinct: true, + Aggregates: []AggregateParams{{ + Opcode: test.opcode, + Col: 0, + Alias: test.name, + }}, + Keys: []int{}, + Input: fp, + } + + result, err := oa.Execute(nil, nil, false) + assert.NoError(err) + + wantResult := sqltypes.MakeTestResult( + sqltypes.MakeTestFields( + test.name, + test.expectedTyp, + ), + test.expectedVal, + ) + assert.Equal(wantResult, result) + }) } - - oa := &OrderedAggregate{ - HasDistinct: true, - Aggregates: []AggregateParams{{ - Opcode: AggregateCountDistinct, - Col: 0, - Alias: "count(distinct col2)", - }, { - Opcode: AggregateSumDistinct, - Col: 1, - Alias: "sum(distinct col2)", - }}, - Keys: []int{}, - Input: fp, - } - - result, err := oa.Execute(nil, nil, false) - assert.NoError(err) - - wantResult := sqltypes.MakeTestResult( - sqltypes.MakeTestFields( - "count(distinct col2)|sum(distinct col2)", - "int64|decimal", - ), - "0|null", - ) - assert.Equal(wantResult, result) } From 2172ab91c98991bbdb00d7d365ad4ca2e298c351 Mon Sep 17 00:00:00 2001 From: Rasika Kale Date: Tue, 3 Sep 2019 10:48:49 -0700 Subject: [PATCH 039/425] Changed error checking in uintTimesUintWithError() in arithmetic.go Signed-off-by: Rasika Kale --- go/sqltypes/arithmetic.go | 2 +- go/sqltypes/arithmetic_test.go | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go/sqltypes/arithmetic.go b/go/sqltypes/arithmetic.go index 9af23dd36ce..3abb7974da6 100644 --- a/go/sqltypes/arithmetic.go +++ b/go/sqltypes/arithmetic.go @@ -571,7 +571,7 @@ func uintMinusUintWithError(v1, v2 uint64) (numeric, error) { func uintTimesUintWithError(v1, v2 uint64) (numeric, error) { result := v1 * v2 - if v1 >= math.MaxUint64 && v2 > 1 || v2 >= math.MaxUint64 && v1 > 1 { + if result < v2 { return numeric{}, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "BIGINT UNSIGNED value is out of range in %v * %v", v1, v2) } return numeric{typ: Uint64, uval: result}, nil diff --git a/go/sqltypes/arithmetic_test.go b/go/sqltypes/arithmetic_test.go index 3af89d2c5f2..648f673320f 100644 --- a/go/sqltypes/arithmetic_test.go +++ b/go/sqltypes/arithmetic_test.go @@ -101,9 +101,9 @@ func TestMultiply(t *testing.T) { err: vterrors.New(vtrpcpb.Code_INVALID_ARGUMENT, "BIGINT value is out of range in 9223372036854775807 * 2"), }, { // testing for underflow of uint64*max.uint64 - v1: NewUint64(2), + v1: NewInt64(2), v2: NewUint64(math.MaxUint64), - err: vterrors.New(vtrpcpb.Code_INVALID_ARGUMENT, "BIGINT UNSIGNED value is out of range in 2 * 18446744073709551615"), + err: vterrors.New(vtrpcpb.Code_INVALID_ARGUMENT, "BIGINT UNSIGNED value is out of range in 18446744073709551615 * 2"), }, { v1: NewUint64(math.MaxUint64), v2: NewUint64(1), From 45fb488af4737d546ef603b393d2f27cfa02721a Mon Sep 17 00:00:00 2001 From: Anthony Yeh Date: Tue, 3 Sep 2019 14:57:38 -0700 Subject: [PATCH 040/425] vtbackup: Stop slave before trying to change master address. (#5153) Signed-off-by: Anthony Yeh --- go/cmd/vtbackup/vtbackup.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/go/cmd/vtbackup/vtbackup.go b/go/cmd/vtbackup/vtbackup.go index 6f5e72813a1..64ef47a961f 100644 --- a/go/cmd/vtbackup/vtbackup.go +++ b/go/cmd/vtbackup/vtbackup.go @@ -376,8 +376,8 @@ func startReplication(ctx context.Context, mysqld mysqlctl.MysqlDaemon, topoServ return vterrors.Wrapf(err, "Cannot read master tablet %v", si.MasterAlias) } - // Set master and start slave. - if err := mysqld.SetMaster(ctx, topoproto.MysqlHostname(ti.Tablet), int(topoproto.MysqlPort(ti.Tablet)), false /* slaveStopBefore */, true /* slaveStartAfter */); err != nil { + // Stop slave (in case we're restarting), set master, and start slave. + if err := mysqld.SetMaster(ctx, topoproto.MysqlHostname(ti.Tablet), int(topoproto.MysqlPort(ti.Tablet)), true /* slaveStopBefore */, true /* slaveStartAfter */); err != nil { return vterrors.Wrap(err, "MysqlDaemon.SetMaster failed") } return nil From 2299f941f09dbfd6b69a57b9710bd8a0f34fc756 Mon Sep 17 00:00:00 2001 From: Jon Tirsen Date: Wed, 4 Sep 2019 09:29:11 +1000 Subject: [PATCH 041/425] Don't cache Zookeeper DNS Make sure we re-resolve the DNS name every time we reconnect to a server. In environments where DNS changes often such as Kubernetes we can't cache the IP address. Signed-off-by: Jon Tirsen --- go/vt/topo/zk2topo/zk_conn.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/go/vt/topo/zk2topo/zk_conn.go b/go/vt/topo/zk2topo/zk_conn.go index b6890273e7e..848b7e6d45b 100644 --- a/go/vt/topo/zk2topo/zk_conn.go +++ b/go/vt/topo/zk2topo/zk_conn.go @@ -377,6 +377,9 @@ func dialZk(ctx context.Context, addr string) (*zk.Conn, <-chan zk.Event, error) return tls.DialWithDialer(&d, network, address, tlsConfig) }) } + // Make sure we re-resolve the DNS name every time we reconnect to a server + // In environments where DNS changes such as Kubernetes we can't cache the IP address + options = zk.WithHostProvider(&zk.SimpleDNSHostProvider{}) // zk.Connect automatically shuffles the servers zconn, session, err := zk.Connect(servers, *baseTimeout, options) From ccdb796b2bd7c9b6992052f5c985e62e1aa3160c Mon Sep 17 00:00:00 2001 From: Andres Taylor Date: Wed, 4 Sep 2019 05:49:54 +0200 Subject: [PATCH 042/425] Make sure to use the timeout context Signed-off-by: Andres Taylor --- go/vt/vtgate/plugin_mysql_server.go | 14 ++++++-------- go/vt/vtgate/plugin_mysql_server_test.go | 8 ++++---- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/go/vt/vtgate/plugin_mysql_server.go b/go/vt/vtgate/plugin_mysql_server.go index 9faf7f3201b..1e93fb6e024 100644 --- a/go/vt/vtgate/plugin_mysql_server.go +++ b/go/vt/vtgate/plugin_mysql_server.go @@ -107,19 +107,17 @@ func (vh *vtgateHandler) ConnectionClosed(c *mysql.Conn) { var r = regexp.MustCompile("/\\*VT_SPAN_CONTEXT=(.*)\\*/") // this function is here to make this logic easy to test by decoupling the logic from the `trace.NewSpan` and `trace.NewFromString` functions -func startSpanTestable(query, label string, +func startSpanTestable(ctx context.Context, query, label string, newSpan func(context.Context, string) (trace.Span, context.Context), newSpanFromString func(context.Context, string, string) (trace.Span, context.Context, error)) (trace.Span, context.Context, error) { _, comments := sqlparser.SplitMarginComments(query) match := r.FindStringSubmatch(comments.Leading) - background := context.Background() var span trace.Span - var ctx context.Context if len(match) == 0 { - span, ctx = newSpan(background, label) + span, ctx = newSpan(ctx, label) } else { var err error - span, ctx, err = newSpanFromString(background, match[1], label) + span, ctx, err = newSpanFromString(ctx, match[1], label) if err != nil { return nil, nil, err } @@ -130,8 +128,8 @@ func startSpanTestable(query, label string, return span, ctx, nil } -func startSpan(query, label string) (trace.Span, context.Context, error) { - return startSpanTestable(query, label, trace.NewSpan, trace.NewFromString) +func startSpan(ctx context.Context, query, label string) (trace.Span, context.Context, error) { + return startSpanTestable(ctx, query, label, trace.NewSpan, trace.NewFromString) } func (vh *vtgateHandler) ComQuery(c *mysql.Conn, query string, callback func(*sqltypes.Result) error) error { @@ -142,7 +140,7 @@ func (vh *vtgateHandler) ComQuery(c *mysql.Conn, query string, callback func(*sq defer cancel() } - span, ctx, err := startSpan(query, "vtgateHandler.ComQuery") + span, ctx, err := startSpan(ctx, query, "vtgateHandler.ComQuery") if err != nil { return vterrors.Wrap(err, "failed to extract span") } diff --git a/go/vt/vtgate/plugin_mysql_server_test.go b/go/vt/vtgate/plugin_mysql_server_test.go index 4ac5f307c96..1a4ee4e8a6c 100644 --- a/go/vt/vtgate/plugin_mysql_server_test.go +++ b/go/vt/vtgate/plugin_mysql_server_test.go @@ -202,22 +202,22 @@ func newSpanFail(t *testing.T) func(ctx context.Context, label string) (trace.Sp } func TestNoSpanContextPassed(t *testing.T) { - _, _, err := startSpanTestable("sql without comments", "someLabel", newSpanOK, newFromStringFail(t)) + _, _, err := startSpanTestable(context.Background(), "sql without comments", "someLabel", newSpanOK, newFromStringFail(t)) assert.NoError(t, err) } func TestSpanContextNoPassedInButExistsInString(t *testing.T) { - _, _, err := startSpanTestable("SELECT * FROM SOMETABLE WHERE COL = \"/*VT_SPAN_CONTEXT=123*/", "someLabel", newSpanOK, newFromStringFail(t)) + _, _, err := startSpanTestable(context.Background(), "SELECT * FROM SOMETABLE WHERE COL = \"/*VT_SPAN_CONTEXT=123*/", "someLabel", newSpanOK, newFromStringFail(t)) assert.NoError(t, err) } func TestSpanContextPassedIn(t *testing.T) { - _, _, err := startSpanTestable("/*VT_SPAN_CONTEXT=123*/SQL QUERY", "someLabel", newSpanFail(t), newFromStringOK) + _, _, err := startSpanTestable(context.Background(), "/*VT_SPAN_CONTEXT=123*/SQL QUERY", "someLabel", newSpanFail(t), newFromStringOK) assert.NoError(t, err) } func TestSpanContextPassedInEvenAroundOtherComments(t *testing.T) { - _, _, err := startSpanTestable("/*VT_SPAN_CONTEXT=123*/SELECT /*vt+ SCATTER_ERRORS_AS_WARNINGS */ col1, col2 FROM TABLE ", "someLabel", + _, _, err := startSpanTestable(context.Background(), "/*VT_SPAN_CONTEXT=123*/SELECT /*vt+ SCATTER_ERRORS_AS_WARNINGS */ col1, col2 FROM TABLE ", "someLabel", newSpanFail(t), newFromStringExpect(t, "123")) assert.NoError(t, err) From 985695fd05089860e32f954f7dec521dc1738af2 Mon Sep 17 00:00:00 2001 From: Morgan Tocker Date: Tue, 3 Sep 2019 22:09:48 -0600 Subject: [PATCH 043/425] Fix CI test failing Signed-off-by: Morgan Tocker --- build.env | 2 +- docker/test/run.sh | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/build.env b/build.env index 896524887d2..4155f9c7713 100644 --- a/build.env +++ b/build.env @@ -37,4 +37,4 @@ if [[ "$VTTOP" == "${VTTOP/\/src\/vitess.io\/vitess/}" ]]; then echo "WARNING: VTTOP($VTTOP) does not contain src/vitess.io/vitess" fi -GO111MODULE=on +export GO111MODULE=on diff --git a/docker/test/run.sh b/docker/test/run.sh index 599e9dbd716..32bc4d2cda3 100755 --- a/docker/test/run.sh +++ b/docker/test/run.sh @@ -176,8 +176,8 @@ copy_src_cmd="cp -R /tmp/src/!(vendor|bootstrap.sh) ." # Git repository. copy_src_cmd=$(append_cmd "$copy_src_cmd" "cp -R /tmp/src/.git .") -# Copy vendor/vendor.json file if it changed -run_bootstrap_cmd="if [[ \$(diff -w vendor/vendor.json /tmp/src/vendor/vendor.json) ]]; then cp -f /tmp/src/vendor/vendor.json vendor/; sync_vendor=1; fi" +# Enable gomodules +run_bootstrap_cmd="export GO111MODULE=on" # Copy bootstrap.sh if it changed run_bootstrap_cmd=$(append_cmd "$run_bootstrap_cmd" "if [[ \$(diff -w bootstrap.sh /tmp/src/bootstrap.sh) ]]; then cp -f /tmp/src/bootstrap.sh .; bootstrap=1; fi") # run bootstrap.sh if necessary From 189f5eb32146757b115e3b3845a09107bfdf01cf Mon Sep 17 00:00:00 2001 From: Jon Tirsen Date: Wed, 4 Sep 2019 15:36:39 +1000 Subject: [PATCH 044/425] Revert "Don't cache Zookeeper DNS" --- go/vt/topo/zk2topo/zk_conn.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/go/vt/topo/zk2topo/zk_conn.go b/go/vt/topo/zk2topo/zk_conn.go index 848b7e6d45b..b6890273e7e 100644 --- a/go/vt/topo/zk2topo/zk_conn.go +++ b/go/vt/topo/zk2topo/zk_conn.go @@ -377,9 +377,6 @@ func dialZk(ctx context.Context, addr string) (*zk.Conn, <-chan zk.Event, error) return tls.DialWithDialer(&d, network, address, tlsConfig) }) } - // Make sure we re-resolve the DNS name every time we reconnect to a server - // In environments where DNS changes such as Kubernetes we can't cache the IP address - options = zk.WithHostProvider(&zk.SimpleDNSHostProvider{}) // zk.Connect automatically shuffles the servers zconn, session, err := zk.Connect(servers, *baseTimeout, options) From 6f791c7a0328c17db7fd43cfbc2c31352f9fe7be Mon Sep 17 00:00:00 2001 From: Anthony Yeh Date: Tue, 3 Sep 2019 23:47:15 -0700 Subject: [PATCH 045/425] replication_reporter: Don't try to reparent to yourself. We've seen it happen that a master tablet restarts and becomes a replica. If the shard record still says we are master, we might end up trying to reparent to ourselves. I don't know yet how the tablet is getting forced to replica type, but in any case we should enforce the invariant that we don't try to reparent to ourselves. Signed-off-by: Anthony Yeh --- go/vt/vttablet/tabletmanager/replication_reporter.go | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/go/vt/vttablet/tabletmanager/replication_reporter.go b/go/vt/vttablet/tabletmanager/replication_reporter.go index 027a11f6bfd..4ec3b12416f 100644 --- a/go/vt/vttablet/tabletmanager/replication_reporter.go +++ b/go/vt/vttablet/tabletmanager/replication_reporter.go @@ -30,6 +30,7 @@ import ( "vitess.io/vitess/go/vt/health" "vitess.io/vitess/go/vt/log" "vitess.io/vitess/go/vt/mysqlctl" + "vitess.io/vitess/go/vt/topo/topoproto" ) var ( @@ -126,6 +127,14 @@ func repairReplication(ctx context.Context, agent *ActionAgent) error { return fmt.Errorf("no master tablet for shard %v/%v", tablet.Keyspace, tablet.Shard) } + if topoproto.TabletAliasEqual(si.MasterAlias, tablet.Alias) { + // The shard record says we are master, but we disagree; we wouldn't + // reach this point unless we were told to check replication as a slave + // type. Hopefully someone is working on fixing that, but in any case, + // we should not try to reparent to ourselves. + return fmt.Errorf("shard %v/%v record claims tablet %v is master, but its type is %v", tablet.Keyspace, tablet.Shard, topoproto.TabletAliasString(tablet.Alias), tablet.Type) + } + // If Orchestrator is configured and if Orchestrator is actively reparenting, we should not repairReplication if agent.orc != nil { re, err := agent.orc.InActiveShardRecovery(tablet) From fb4eec3e3de3d4f186dac1e05f501be397bf48a2 Mon Sep 17 00:00:00 2001 From: Morgan Tocker Date: Wed, 4 Sep 2019 08:49:54 -0600 Subject: [PATCH 046/425] Add go mod download to Docker base Signed-off-by: Morgan Tocker --- docker/bootstrap/Dockerfile.common | 3 +++ tools/unit_test_race.sh | 3 +++ tools/unit_test_runner.sh | 3 +++ 3 files changed, 9 insertions(+) diff --git a/docker/bootstrap/Dockerfile.common b/docker/bootstrap/Dockerfile.common index e17d3e88155..01d461228db 100644 --- a/docker/bootstrap/Dockerfile.common +++ b/docker/bootstrap/Dockerfile.common @@ -49,6 +49,7 @@ ENV GOBIN $VTROOT/bin ENV PATH $VTROOT/bin:$VTROOT/dist/maven/bin:$VTROOT/dist/chromedriver:$PATH ENV PKG_CONFIG_PATH $VTROOT/lib ENV USER vitess +ENV GO111MODULE on # Copy files needed for bootstrap COPY bootstrap.sh dev.env build.env /vt/src/vitess.io/vitess/ @@ -57,6 +58,8 @@ COPY third_party /vt/src/vitess.io/vitess/third_party COPY tools /vt/src/vitess.io/vitess/tools COPY travis /vt/src/vitess.io/vitess/travis +RUN go mod download + # Create vitess user RUN groupadd -r vitess && useradd -r -g vitess vitess && \ mkdir -p /vt/vtdataroot /home/vitess && \ diff --git a/tools/unit_test_race.sh b/tools/unit_test_race.sh index c7861c9db8a..e7073a82bb9 100755 --- a/tools/unit_test_race.sh +++ b/tools/unit_test_race.sh @@ -17,6 +17,9 @@ temp_log_file="$(mktemp --suffix .unit_test_race.log)" trap '[ -f "$temp_log_file" ] && rm $temp_log_file' EXIT +# This can be removed once the docker images are rebuilt +export GO111MODULE=on + # Wrapper around go test -race. # This script exists because the -race test doesn't allow to distinguish diff --git a/tools/unit_test_runner.sh b/tools/unit_test_runner.sh index 7e0c8150f05..ef2fb394d24 100755 --- a/tools/unit_test_runner.sh +++ b/tools/unit_test_runner.sh @@ -33,6 +33,9 @@ if [[ -z $VT_GO_PARALLEL && -n $VT_GO_PARALLEL_VALUE ]]; then VT_GO_PARALLEL="-p $VT_GO_PARALLEL_VALUE" fi +# This can be removed once the docker images are rebuilt +export GO111MODULE=on + # All Go packages with test files. # Output per line: * packages_with_tests=$(go list -f '{{if len .TestGoFiles}}{{.ImportPath}} {{join .TestGoFiles " "}}{{end}}' ./go/... | sort) From 4c8a888b05dfceee11b4f06eb5b255723eb7757f Mon Sep 17 00:00:00 2001 From: chentanjun <2799194073@qq.com> Date: Thu, 5 Sep 2019 00:16:54 +0800 Subject: [PATCH 047/425] fix-up typo Signed-off-by: chentanjun <2799194073@qq.com> --- go/vt/topotools/utils.go | 4 ++-- go/vt/vtgate/planbuilder/testdata/wireup_cases.txt | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go/vt/topotools/utils.go b/go/vt/topotools/utils.go index a94ec67f745..5937ec63e48 100644 --- a/go/vt/topotools/utils.go +++ b/go/vt/topotools/utils.go @@ -119,7 +119,7 @@ func SortedTabletMap(tabletMap map[string]*topo.TabletInfo) (map[string]*topo.Ta return slaveMap, masterMap } -// CopyMapKeys copies keys from from map m into a new slice with the +// CopyMapKeys copies keys from map m into a new slice with the // type specified by typeHint. Reflection can't make a new slice type // just based on the key type AFAICT. func CopyMapKeys(m interface{}, typeHint interface{}) interface{} { @@ -131,7 +131,7 @@ func CopyMapKeys(m interface{}, typeHint interface{}) interface{} { return keys.Interface() } -// CopyMapValues copies values from from map m into a new slice with the +// CopyMapValues copies values from map m into a new slice with the // type specified by typeHint. Reflection can't make a new slice type // just based on the key type AFAICT. func CopyMapValues(m interface{}, typeHint interface{}) interface{} { diff --git a/go/vt/vtgate/planbuilder/testdata/wireup_cases.txt b/go/vt/vtgate/planbuilder/testdata/wireup_cases.txt index 6cda6f1750d..df5433d2349 100644 --- a/go/vt/vtgate/planbuilder/testdata/wireup_cases.txt +++ b/go/vt/vtgate/planbuilder/testdata/wireup_cases.txt @@ -538,7 +538,7 @@ } } -# Wire-up in in underlying primitive after pullout +# Wire-up in underlying primitive after pullout "select u.id, e.id, (select col from user) from user u join user_extra e where e.id = u.col limit 10" { "Original": "select u.id, e.id, (select col from user) from user u join user_extra e where e.id = u.col limit 10", From 5b111fe6bde08c8e962855edcc4213d86c4a3b9d Mon Sep 17 00:00:00 2001 From: Morgan Tocker Date: Wed, 4 Sep 2019 10:22:10 -0600 Subject: [PATCH 048/425] Empty push Signed-off-by: Morgan Tocker From bbb32fe247bf5ab96e6bef16f2acc1640d3184ef Mon Sep 17 00:00:00 2001 From: Sugu Sougoumarane Date: Sat, 24 Aug 2019 13:58:54 -0700 Subject: [PATCH 049/425] vreplication: refactor table_plan_builder Unify the code path for wildcard and exact table name matches. The diverging paths have been a source of bugs. This unification will also help with the next feature that will allow us to exclude tables in the filtering rules. Signed-off-by: Sugu Sougoumarane --- go/vt/key/key.go | 8 ++ go/vt/key/key_test.go | 44 ++++++++- .../vreplication/replicator_plan_test.go | 38 ++++++++ .../vreplication/table_plan_builder.go | 96 +++++++++---------- .../tabletserver/vstreamer/planbuilder.go | 1 + 5 files changed, 136 insertions(+), 51 deletions(-) diff --git a/go/vt/key/key.go b/go/vt/key/key.go index 367311ba5c8..9b2408619e9 100644 --- a/go/vt/key/key.go +++ b/go/vt/key/key.go @@ -22,6 +22,7 @@ import ( "encoding/hex" "fmt" "math" + "regexp" "strings" topodatapb "vitess.io/vitess/go/vt/proto/topodata" @@ -296,3 +297,10 @@ func ParseShardingSpec(spec string) ([]*topodatapb.KeyRange, error) { } return ranges, nil } + +var krRegexp = regexp.MustCompile(`^[0-9a-fA-F]*-[0-9a-fA-F]*$`) + +// IsKeyRange returns true if the string represents a keyrange. +func IsKeyRange(kr string) bool { + return krRegexp.MatchString(kr) +} diff --git a/go/vt/key/key_test.go b/go/vt/key/key_test.go index b6e2229e760..1c369a9accc 100644 --- a/go/vt/key/key_test.go +++ b/go/vt/key/key_test.go @@ -22,6 +22,7 @@ import ( "testing" "github.com/golang/protobuf/proto" + "github.com/stretchr/testify/assert" topodatapb "vitess.io/vitess/go/vt/proto/topodata" ) @@ -381,7 +382,7 @@ func BenchmarkUint64KeyString(b *testing.B) { for i := 0; i < b.N; i++ { for _, key := range keys { - key.String() + _ = key.String() } } } @@ -435,3 +436,44 @@ func BenchmarkKeyRangesOverlap(b *testing.B) { KeyRangesOverlap(kr1, kr2) } } + +func TestIsKeyRange(t *testing.T) { + testcases := []struct { + in string + out bool + }{{ + in: "-", + out: true, + }, { + in: "-80", + out: true, + }, { + in: "40-80", + out: true, + }, { + in: "80-", + out: true, + }, { + in: "a0-", + out: true, + }, { + in: "-A0", + out: true, + }, { + in: "", + out: false, + }, { + in: "x-80", + out: false, + }, { + in: "-80x", + out: false, + }, { + in: "select", + out: false, + }} + + for _, tcase := range testcases { + assert.Equal(t, IsKeyRange(tcase.in), tcase.out, tcase.in) + } +} diff --git a/go/vt/vttablet/tabletmanager/vreplication/replicator_plan_test.go b/go/vt/vttablet/tabletmanager/vreplication/replicator_plan_test.go index 4474b305129..547ce60cd32 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/replicator_plan_test.go +++ b/go/vt/vttablet/tabletmanager/vreplication/replicator_plan_test.go @@ -85,6 +85,44 @@ func TestBuildPlayerPlan(t *testing.T) { }, }, }, + }, { + // Regular with keyrange + input: &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{{ + Match: "/.*", + Filter: "-80", + }}, + }, + plan: &TestReplicatorPlan{ + VStreamFilter: &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{{ + Match: "t1", + Filter: "select * from t1 where in_keyrange('-80')", + }}, + }, + TargetTables: []string{"t1"}, + TablePlans: map[string]*TestTablePlan{ + "t1": { + TargetName: "t1", + SendRule: "t1", + }, + }, + }, + planpk: &TestReplicatorPlan{ + VStreamFilter: &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{{ + Match: "t1", + Filter: "select * from t1 where in_keyrange('-80')", + }}, + }, + TargetTables: []string{"t1"}, + TablePlans: map[string]*TestTablePlan{ + "t1": { + TargetName: "t1", + SendRule: "t1", + }, + }, + }, }, { // '*' expression input: &binlogdatapb.Filter{ diff --git a/go/vt/vttablet/tabletmanager/vreplication/table_plan_builder.go b/go/vt/vttablet/tabletmanager/vreplication/table_plan_builder.go index 3c8d3bc27a4..1fe5c8bd96b 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/table_plan_builder.go +++ b/go/vt/vttablet/tabletmanager/vreplication/table_plan_builder.go @@ -23,6 +23,7 @@ import ( "strings" "vitess.io/vitess/go/sqltypes" + "vitess.io/vitess/go/vt/key" binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" "vitess.io/vitess/go/vt/sqlparser" ) @@ -88,69 +89,64 @@ func buildReplicatorPlan(filter *binlogdatapb.Filter, tableKeys map[string][]str TablePlans: make(map[string]*TablePlan), tableKeys: tableKeys, } -nextTable: for tableName := range tableKeys { lastpk, ok := copyState[tableName] if ok && lastpk == nil { // Don't replicate uncopied tables. continue } - for _, rule := range filter.Rules { - switch { - case strings.HasPrefix(rule.Match, "/"): - expr := strings.Trim(rule.Match, "/") - result, err := regexp.MatchString(expr, tableName) - if err != nil { - return nil, err - } - if !result { - continue - } - sendRule := &binlogdatapb.Rule{ - Match: tableName, - Filter: buildQuery(tableName, rule.Filter), - } - plan.VStreamFilter.Rules = append(plan.VStreamFilter.Rules, sendRule) - tablePlan := &TablePlan{ - TargetName: tableName, - SendRule: sendRule, - Lastpk: lastpk, - } - plan.TargetTables[tableName] = tablePlan - plan.TablePlans[tableName] = tablePlan - continue nextTable - case rule.Match == tableName: - tablePlan, err := buildTablePlan(rule, tableKeys, lastpk) - if err != nil { - return nil, err - } - if _, ok := plan.TablePlans[tablePlan.SendRule.Match]; ok { - continue - } - plan.VStreamFilter.Rules = append(plan.VStreamFilter.Rules, tablePlan.SendRule) - plan.TargetTables[tableName] = tablePlan - plan.TablePlans[tablePlan.SendRule.Match] = tablePlan - continue nextTable - } + rule, err := tableMatches(tableName, filter) + if err != nil { + return nil, err + } + if rule == nil { + continue + } + tablePlan, err := buildTablePlan(tableName, rule.Filter, tableKeys, lastpk) + if err != nil { + return nil, err + } + if _, ok := plan.TablePlans[tablePlan.SendRule.Match]; ok { + continue } + plan.VStreamFilter.Rules = append(plan.VStreamFilter.Rules, tablePlan.SendRule) + plan.TargetTables[tableName] = tablePlan + plan.TablePlans[tablePlan.SendRule.Match] = tablePlan } return plan, nil } -func buildQuery(tableName, filter string) string { - buf := sqlparser.NewTrackedBuffer(nil) - buf.Myprintf("select * from %v", sqlparser.NewTableIdent(tableName)) - if filter != "" { - buf.Myprintf(" where in_keyrange(%v)", sqlparser.NewStrVal([]byte(filter))) +// tableMatches is similar to the one defined in vstreamer. +func tableMatches(tableName string, filter *binlogdatapb.Filter) (*binlogdatapb.Rule, error) { + for _, rule := range filter.Rules { + switch { + case strings.HasPrefix(rule.Match, "/"): + expr := strings.Trim(rule.Match, "/") + result, err := regexp.MatchString(expr, tableName) + if err != nil { + return nil, err + } + if !result { + continue + } + return rule, nil + case tableName == rule.Match: + return rule, nil + } } - return buf.String() + return nil, nil } -func buildTablePlan(rule *binlogdatapb.Rule, tableKeys map[string][]string, lastpk *sqltypes.Result) (*TablePlan, error) { - query := rule.Filter - if query == "" { +func buildTablePlan(tableName, filter string, tableKeys map[string][]string, lastpk *sqltypes.Result) (*TablePlan, error) { + query := filter + switch { + case filter == "": + buf := sqlparser.NewTrackedBuffer(nil) + buf.Myprintf("select * from %v", sqlparser.NewTableIdent(tableName)) + query = buf.String() + case key.IsKeyRange(filter): buf := sqlparser.NewTrackedBuffer(nil) - buf.Myprintf("select * from %v", sqlparser.NewTableIdent(rule.Match)) + buf.Myprintf("select * from %v where in_keyrange(%v)", sqlparser.NewTableIdent(tableName), sqlparser.NewStrVal([]byte(filter))) query = buf.String() } sel, fromTable, err := analyzeSelectFrom(query) @@ -170,7 +166,7 @@ func buildTablePlan(rule *binlogdatapb.Rule, tableKeys map[string][]string, last } sendRule.Filter = query tablePlan := &TablePlan{ - TargetName: rule.Match, + TargetName: tableName, SendRule: sendRule, Lastpk: lastpk, } @@ -178,7 +174,7 @@ func buildTablePlan(rule *binlogdatapb.Rule, tableKeys map[string][]string, last } tpb := &tablePlanBuilder{ - name: sqlparser.NewTableIdent(rule.Match), + name: sqlparser.NewTableIdent(tableName), sendSelect: &sqlparser.Select{ From: sel.From, Where: sel.Where, diff --git a/go/vt/vttablet/tabletserver/vstreamer/planbuilder.go b/go/vt/vttablet/tabletserver/vstreamer/planbuilder.go index a9e593c0136..dc241c73b78 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/planbuilder.go +++ b/go/vt/vttablet/tabletserver/vstreamer/planbuilder.go @@ -128,6 +128,7 @@ func mustSendDDL(query mysql.Query, dbname string, filter *binlogdatapb.Filter) return true } +// tableMatches is similar to the one defined in vreplication. func tableMatches(table sqlparser.TableName, dbname string, filter *binlogdatapb.Filter) bool { if !table.Qualifier.IsEmpty() && table.Qualifier.String() != dbname { return false From e7f3ef81a8c0fe94a1295608ddd4d8e10f96faab Mon Sep 17 00:00:00 2001 From: Adam Saponara Date: Tue, 3 Sep 2019 17:28:23 -0400 Subject: [PATCH 050/425] Prevent log purging of symlinks Signed-off-by: Adam Saponara --- go/vt/logutil/logutil_test.go | 15 +++++++++------ go/vt/logutil/purge.go | 8 +++++++- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/go/vt/logutil/logutil_test.go b/go/vt/logutil/logutil_test.go index 605adad4ffa..4d07abf7ad0 100644 --- a/go/vt/logutil/logutil_test.go +++ b/go/vt/logutil/logutil_test.go @@ -103,9 +103,8 @@ func TestPurgeByMtime(t *testing.T) { t.Fatalf("os.Chtimes: %v", err) } } - now := time.Date(2020, 1, 1, 12, 15, 0, 0, time.UTC) + now := time.Date(2020, 1, 1, 12, 0, 0, 0, time.UTC) filenameMtimeMap := map[string]string{ - "vtadam.localhost.vitess.log.INFO.20200101-120000.00000": "2020-01-01T12:00:00.000Z", "vtadam.localhost.vitess.log.INFO.20200101-113000.00000": "2020-01-01T11:30:00.000Z", "vtadam.localhost.vitess.log.INFO.20200101-100000.00000": "2020-01-01T10:00:00.000Z", "vtadam.localhost.vitess.log.INFO.20200101-090000.00000": "2020-01-01T09:00:00.000Z", @@ -114,7 +113,11 @@ func TestPurgeByMtime(t *testing.T) { for filename, mtimeStr := range filenameMtimeMap { createFileWithMtime(filename, mtimeStr) } - if err := os.Symlink("vtadam.localhost.vitess.log.INFO.20200101-120000.00000", path.Join(logDir, "vtadam.INFO")); err != nil { + + // Create vtadam.INFO symlink to 100000. This is a contrived example in that + // current log (100000) is not the latest log (113000). This will not happen + // IRL but it helps us test edge cases of purging by mtime. + if err := os.Symlink("vtadam.localhost.vitess.log.INFO.20200101-100000.00000", path.Join(logDir, "vtadam.INFO")); err != nil { t.Fatalf("os.Symlink: %v", err) } @@ -126,9 +129,9 @@ func TestPurgeByMtime(t *testing.T) { } if len(left) != 3 { - // 20200101-120000 is current - // 20200101-113000 is within 1 hour - // symlink remains + // 1. 113000 is within 1 hour + // 2. 100000 is current (vtadam.INFO) + // 3. vtadam.INFO symlink remains // rest are removed t.Errorf("wrong number of files remain: want %v, got %v", 3, len(left)) } diff --git a/go/vt/logutil/purge.go b/go/vt/logutil/purge.go index c7825098a11..55701c37db6 100644 --- a/go/vt/logutil/purge.go +++ b/go/vt/logutil/purge.go @@ -70,7 +70,13 @@ func purgeLogsOnce(now time.Time, dir, program string, ctimeDelta time.Duration, return } for _, file := range files { - if current[file] { + statInfo, err := os.Lstat(file) + if err != nil { + // Failed to stat file + continue + } + if current[file] || !statInfo.Mode().IsRegular() { + // Do not purge current file or any non-regular files (symlinks etc) continue } purgeFile := false From c9987b73fdc0302a3a708b52de650e57c63ef33b Mon Sep 17 00:00:00 2001 From: Morgan Tocker Date: Thu, 5 Sep 2019 09:19:22 -0600 Subject: [PATCH 051/425] Improve errror when capabiility detect fails ALso removes unused capabiltities code to silence staticcheck warning. Signed-off-by: Morgan Tocker --- go/vt/mysqlctl/capabilityset.go | 24 ------------------------ go/vt/mysqlctl/mysqld.go | 33 ++++++++++++++++++++++++++++++--- 2 files changed, 30 insertions(+), 27 deletions(-) diff --git a/go/vt/mysqlctl/capabilityset.go b/go/vt/mysqlctl/capabilityset.go index 68319450f53..17bb251a83b 100644 --- a/go/vt/mysqlctl/capabilityset.go +++ b/go/vt/mysqlctl/capabilityset.go @@ -46,24 +46,6 @@ func (c *capabilitySet) hasMySQLUpgradeInServer() bool { func (c *capabilitySet) hasInitializeInServer() bool { return c.isMySQLLike() && c.version.atLeast(serverVersion{Major: 5, Minor: 7, Patch: 0}) } -func (c *capabilitySet) hasMySQLxEnabledByDefault() bool { - return c.isMySQLLike() && c.version.atLeast(serverVersion{Major: 8, Minor: 0, Patch: 11}) -} -func (c *capabilitySet) hasPersistConfig() bool { - return c.isMySQLLike() && c.version.atLeast(serverVersion{Major: 8, Minor: 0, Patch: 0}) -} -func (c *capabilitySet) hasShutdownCommand() bool { - return (c.isMySQLLike() && c.version.atLeast(serverVersion{Major: 5, Minor: 7, Patch: 9})) || (c.isMariaDB() && c.version.atLeast(serverVersion{Major: 10, Minor: 0, Patch: 4})) -} -func (c *capabilitySet) hasBackupLocks() bool { - return c.isMySQLLike() && c.version.atLeast(serverVersion{Major: 8, Minor: 0, Patch: 0}) -} -func (c *capabilitySet) hasDefaultUft8mb4() bool { - return c.isMySQLLike() && c.version.atLeast(serverVersion{Major: 8, Minor: 0, Patch: 0}) -} -func (c *capabilitySet) hasSemiSyncEnabledByDefault() bool { - return c.isMariaDB() && c.version.atLeast(serverVersion{Major: 10, Minor: 3, Patch: 3}) -} // IsMySQLLike tests if the server is either MySQL // or Percona Server. At least currently, Vitess doesn't @@ -71,9 +53,3 @@ func (c *capabilitySet) hasSemiSyncEnabledByDefault() bool { func (c *capabilitySet) isMySQLLike() bool { return c.flavor == flavorMySQL || c.flavor == flavorPercona } - -// IsMariaDB tests if the server is MariaDB. -// IsMySQLLike() and IsMariaDB() are mutually exclusive -func (c *capabilitySet) isMariaDB() bool { - return c.flavor == flavorMariaDB -} diff --git a/go/vt/mysqlctl/mysqld.go b/go/vt/mysqlctl/mysqld.go index e99f63ec33d..139b0974277 100644 --- a/go/vt/mysqlctl/mysqld.go +++ b/go/vt/mysqlctl/mysqld.go @@ -115,13 +115,40 @@ func NewMysqld(dbcfgs *dbconfigs.DBConfigs) *Mysqld { version, getErr := getVersionString() f, v, err := parseVersionString(version) - // Fallback if required + /* + By default Vitess searches in vtenv.VtMysqlRoot() for a mysqld binary. + This is usually the VT_MYSQL_ROOT env, but if it is unset or empty, it + will substitute VtRoot(). See go/vt/env/env.go. + + A number of subdirs inside vtenv.VtMysqlRoot() will be searched, see + func binaryPath() for context. If no mysqld binary is found (possibly + because it is in a container or both VT_MYSQL_ROOT and VTROOT are set + incorrectly), there will be a fallback to using the MYSQL_FLAVOR env + variable. + + If MYSQL_FLAVOR is not defined, there will be a panic. + + Note: relying on MySQL_FLAVOR is not recommended, since for historical + purposes "MySQL56" actually means MySQL 5.7, which is a very strange + behavior. + */ + if getErr != nil || err != nil { f, v, err = getVersionFromEnv() if err != nil { - panic("could not detect version from mysqld --version or MYSQL_FLAVOR") + vtenvMysqlRoot, _ := vtenv.VtMysqlRoot() + message := fmt.Sprintf(`could not auto-detect MySQL version. You may need to set VT_MYSQL_ROOT so a mysqld binary can be found, or set the environment variable MYSQL_FLAVOR if mysqld is not available locally: + VT_MYSQL_ROOT: %s + VTROOT: %s + vtenv.VtMysqlRoot(): %s + MYSQL_FLAVOR: %s + `, + os.Getenv("VT_MYSQL_ROOT"), + os.Getenv("VTROOT"), + vtenvMysqlRoot, + os.Getenv("MYSQL_FLAVOR")) + panic(message) } - } log.Infof("Using flavor: %v, version: %v", f, v) From 667e410506b4174a3dc148c5a6a337954017f35a Mon Sep 17 00:00:00 2001 From: Rasika Kale Date: Thu, 5 Sep 2019 11:28:23 -0700 Subject: [PATCH 052/425] Changed Error Checking for subtraction in intMinusUintWithError() - Added test for method in arithmetic_test.go to maximize code coverage Signed-off-by: Rasika Kale --- go/sqltypes/arithmetic.go | 5 ++++- go/sqltypes/arithmetic_test.go | 9 +++++++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/go/sqltypes/arithmetic.go b/go/sqltypes/arithmetic.go index f547e25b5c7..b4507670c1e 100644 --- a/go/sqltypes/arithmetic.go +++ b/go/sqltypes/arithmetic.go @@ -478,7 +478,10 @@ func intMinusIntWithError(v1, v2 int64) (numeric, error) { } func intMinusUintWithError(v1 int64, v2 uint64) (numeric, error) { - return intMinusIntWithError(v1, int64(v2)) + if v1 < 0 { + return numeric{}, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "BIGINT UNSIGNED value is out of range in %v - %v", v1, v2) + } + return uintMinusUintWithError(uint64(v1), v2) } func uintPlusInt(v1 uint64, v2 int64) numeric { diff --git a/go/sqltypes/arithmetic_test.go b/go/sqltypes/arithmetic_test.go index da076670a4c..2f354b50d2f 100644 --- a/go/sqltypes/arithmetic_test.go +++ b/go/sqltypes/arithmetic_test.go @@ -64,6 +64,7 @@ func TestSubtract(t *testing.T) { v2: NewInt64(5), err: vterrors.New(vtrpcpb.Code_INVALID_ARGUMENT, "BIGINT UNSIGNED value is out of range in 4 - 5"), }, { + // testing uint - int v1: NewUint64(7), v2: NewInt64(5), out: NewUint64(2), @@ -75,7 +76,7 @@ func TestSubtract(t *testing.T) { // testing for int64 overflow v1: NewInt64(math.MinInt64), v2: NewUint64(0), - out: NewInt64(math.MinInt64), + err: vterrors.New(vtrpcpb.Code_INVALID_ARGUMENT, "BIGINT UNSIGNED value is out of range in -9223372036854775808 - 0"), }, { v1: TestValue(VarChar, "c"), v2: NewInt64(1), @@ -112,7 +113,11 @@ func TestSubtract(t *testing.T) { }, { v1: NewInt64(-1), v2: NewUint64(2), - out: NewInt64(-3), + err: vterrors.New(vtrpcpb.Code_INVALID_ARGUMENT, "BIGINT UNSIGNED value is out of range in -1 - 2"), + }, { + v1: NewInt64(2), + v2: NewUint64(1), + out: NewUint64(1), }} for _, tcase := range tcases { From 00b3a085e31f08b148a4b6b72e720e9a1dc1dc97 Mon Sep 17 00:00:00 2001 From: Rasika Kale Date: Thu, 5 Sep 2019 14:54:59 -0700 Subject: [PATCH 053/425] Fixed error checking in arithmetic.go under uintPlusIntWithError() - Fixed tests in TestAdd() in arithmetic_test.go Signed-off-by: Rasika Kale --- go/sqltypes/arithmetic.go | 8 +------- go/sqltypes/arithmetic_test.go | 6 +++--- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/go/sqltypes/arithmetic.go b/go/sqltypes/arithmetic.go index b4507670c1e..94488494536 100644 --- a/go/sqltypes/arithmetic.go +++ b/go/sqltypes/arithmetic.go @@ -19,7 +19,6 @@ package sqltypes import ( "bytes" "fmt" - "math" "strconv" @@ -489,14 +488,9 @@ func uintPlusInt(v1 uint64, v2 int64) numeric { } func uintPlusIntWithError(v1 uint64, v2 int64) (numeric, error) { - if v2 >= math.MaxInt64 && v1 > 0 { - return numeric{}, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "BIGINT value is out of range in %v + %v", v1, v2) - } - - if v1 >= math.MaxUint64 && v2 > 0 { + if v2 < 0 && v1 < uint64(v2) { return numeric{}, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "BIGINT UNSIGNED value is out of range in %v + %v", v1, v2) } - // convert to int -> uint is because for numeric operators (such as + or -) // where one of the operands is an unsigned integer, the result is unsigned by default. return uintPlusUintWithError(v1, uint64(v2)) diff --git a/go/sqltypes/arithmetic_test.go b/go/sqltypes/arithmetic_test.go index 2f354b50d2f..6c99d081d4e 100644 --- a/go/sqltypes/arithmetic_test.go +++ b/go/sqltypes/arithmetic_test.go @@ -164,14 +164,14 @@ func TestAdd(t *testing.T) { v2: NewInt64(-2), out: NewInt64(-3), }, { - // testing for overflow int64 + // testing for overflow int64, result will be unsigned int v1: NewInt64(math.MaxInt64), v2: NewUint64(2), - err: vterrors.New(vtrpcpb.Code_INVALID_ARGUMENT, "BIGINT value is out of range in 2 + 9223372036854775807"), + out: NewUint64(9223372036854775809), }, { v1: NewInt64(-2), v2: NewUint64(1), - out: NewUint64(math.MaxUint64), + err: vterrors.New(vtrpcpb.Code_INVALID_ARGUMENT, "BIGINT UNSIGNED value is out of range in 1 + -2"), }, { v1: NewInt64(math.MaxInt64), v2: NewInt64(-2), From 3b985e8ca6072df7b5c67e6ea66fd3cc890e0b04 Mon Sep 17 00:00:00 2001 From: Jon Tirsen Date: Thu, 5 Sep 2019 17:24:28 +1000 Subject: [PATCH 054/425] Don't cache Zookeeper DNS Make sure we re-resolve the DNS name every time we reconnect to a server. In environments where DNS changes often such as Kubernetes we can't cache the IP address. Signed-off-by: Jon Tirsen --- go/vt/topo/zk2topo/zk_conn.go | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/go/vt/topo/zk2topo/zk_conn.go b/go/vt/topo/zk2topo/zk_conn.go index b6890273e7e..5301af6774d 100644 --- a/go/vt/topo/zk2topo/zk_conn.go +++ b/go/vt/topo/zk2topo/zk_conn.go @@ -340,7 +340,7 @@ func (c *ZkConn) handleSessionEvents(conn *zk.Conn, session <-chan zk.Event) { // dialZk dials the server, and waits until connection. func dialZk(ctx context.Context, addr string) (*zk.Conn, <-chan zk.Event, error) { servers := strings.Split(addr, ",") - options := zk.WithDialer(net.DialTimeout) + dialer := zk.WithDialer(net.DialTimeout) // If TLS is enabled use a TLS enabled dialer option if *certPath != "" && *keyPath != "" { if strings.Contains(addr, ",") { @@ -371,15 +371,18 @@ func dialZk(ctx context.Context, addr string) (*zk.Conn, <-chan zk.Event, error) tlsConfig.BuildNameToCertificate() - options = zk.WithDialer(func(network, address string, timeout time.Duration) (net.Conn, error) { + dialer = zk.WithDialer(func(network, address string, timeout time.Duration) (net.Conn, error) { d := net.Dialer{Timeout: timeout} return tls.DialWithDialer(&d, network, address, tlsConfig) }) } + // Make sure we re-resolve the DNS name every time we reconnect to a server + // In environments where DNS changes such as Kubernetes we can't cache the IP address + hostProvider := zk.WithHostProvider(&zk.SimpleDNSHostProvider{}) // zk.Connect automatically shuffles the servers - zconn, session, err := zk.Connect(servers, *baseTimeout, options) + zconn, session, err := zk.Connect(servers, *baseTimeout, dialer, hostProvider) if err != nil { return nil, nil, err } From 0b85a9d32cbb02bd792c7f76c558e3815497edfa Mon Sep 17 00:00:00 2001 From: Sugu Sougoumarane Date: Sat, 24 Aug 2019 16:47:19 -0700 Subject: [PATCH 055/425] vreplication: ability to exclude tables Signed-off-by: Sugu Sougoumarane --- .../vreplication/replicator_plan_test.go | 57 +++++++++++++++++++ .../vreplication/table_plan_builder.go | 8 ++- 2 files changed, 64 insertions(+), 1 deletion(-) diff --git a/go/vt/vttablet/tabletmanager/vreplication/replicator_plan_test.go b/go/vt/vttablet/tabletmanager/vreplication/replicator_plan_test.go index 547ce60cd32..5dfdb7b0072 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/replicator_plan_test.go +++ b/go/vt/vttablet/tabletmanager/vreplication/replicator_plan_test.go @@ -20,6 +20,7 @@ import ( "encoding/json" "testing" + "github.com/stretchr/testify/assert" "vitess.io/vitess/go/sqltypes" binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" ) @@ -654,3 +655,59 @@ func TestBuildPlayerPlan(t *testing.T) { } } } + +func TestBuildPlayerPlanNoDup(t *testing.T) { + tableKeys := map[string][]string{ + "t1": {"c1"}, + "t2": {"c2"}, + } + input := &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{{ + Match: "t1", + Filter: "select * from t", + }, { + Match: "t2", + Filter: "select * from t", + }}, + } + _, err := buildReplicatorPlan(input, tableKeys, nil) + assert.EqualError(t, err, "more than one target for source table t: t1 and t2") +} + +func TestBuildPlayerPlanExclude(t *testing.T) { + tableKeys := map[string][]string{ + "t1": {"c1"}, + "t2": {"c2"}, + } + input := &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{{ + Match: "t2", + Filter: "exclude", + }, { + Match: "/.*", + Filter: "", + }}, + } + plan, err := buildReplicatorPlan(input, tableKeys, nil) + assert.NoError(t, err) + + want := &TestReplicatorPlan{ + VStreamFilter: &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{{ + Match: "t1", + Filter: "select * from t1", + }}, + }, + TargetTables: []string{"t1"}, + TablePlans: map[string]*TestTablePlan{ + "t1": { + TargetName: "t1", + SendRule: "t1", + }, + }, + } + + gotPlan, _ := json.Marshal(plan) + wantPlan, _ := json.Marshal(want) + assert.Equal(t, string(gotPlan), string(wantPlan)) +} diff --git a/go/vt/vttablet/tabletmanager/vreplication/table_plan_builder.go b/go/vt/vttablet/tabletmanager/vreplication/table_plan_builder.go index 1fe5c8bd96b..bc9bd76dd5c 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/table_plan_builder.go +++ b/go/vt/vttablet/tabletmanager/vreplication/table_plan_builder.go @@ -106,9 +106,13 @@ func buildReplicatorPlan(filter *binlogdatapb.Filter, tableKeys map[string][]str if err != nil { return nil, err } - if _, ok := plan.TablePlans[tablePlan.SendRule.Match]; ok { + if tablePlan == nil { + // Table was excluded. continue } + if dup, ok := plan.TablePlans[tablePlan.SendRule.Match]; ok { + return nil, fmt.Errorf("more than one target for source table %s: %s and %s", tablePlan.SendRule.Match, dup.TargetName, tableName) + } plan.VStreamFilter.Rules = append(plan.VStreamFilter.Rules, tablePlan.SendRule) plan.TargetTables[tableName] = tablePlan plan.TablePlans[tablePlan.SendRule.Match] = tablePlan @@ -148,6 +152,8 @@ func buildTablePlan(tableName, filter string, tableKeys map[string][]string, las buf := sqlparser.NewTrackedBuffer(nil) buf.Myprintf("select * from %v where in_keyrange(%v)", sqlparser.NewTableIdent(tableName), sqlparser.NewStrVal([]byte(filter))) query = buf.String() + case filter == "exclude": + return nil, nil } sel, fromTable, err := analyzeSelectFrom(query) if err != nil { From 95a52bdb95e81d030fb70af44eccf2a3101d4e61 Mon Sep 17 00:00:00 2001 From: Rasika Kale Date: Fri, 6 Sep 2019 10:17:01 -0700 Subject: [PATCH 056/425] Fixed error checking for uintTimesIntWithError() in arithmetic.go - Added more tests in TestMultiply() in arithmetic_test.go to increase code coverage Signed-off-by: Rasika Kale --- go/sqltypes/arithmetic.go | 3 +++ go/sqltypes/arithmetic_test.go | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/go/sqltypes/arithmetic.go b/go/sqltypes/arithmetic.go index 3abb7974da6..4d65fbb2a4b 100644 --- a/go/sqltypes/arithmetic.go +++ b/go/sqltypes/arithmetic.go @@ -544,6 +544,9 @@ func uintMinusIntWithError(v1 uint64, v2 int64) (numeric, error) { } func uintTimesIntWithError(v1 uint64, v2 int64) (numeric, error) { + if v2 < 0 || v1 >= math.MaxUint64 && v2 > 0 { + return numeric{}, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "BIGINT UNSIGNED value is out of range in %v * %v", v1, v2) + } return uintTimesUintWithError(v1, uint64(v2)) } diff --git a/go/sqltypes/arithmetic_test.go b/go/sqltypes/arithmetic_test.go index 648f673320f..6b811d70735 100644 --- a/go/sqltypes/arithmetic_test.go +++ b/go/sqltypes/arithmetic_test.go @@ -108,6 +108,10 @@ func TestMultiply(t *testing.T) { v1: NewUint64(math.MaxUint64), v2: NewUint64(1), out: NewUint64(math.MaxUint64), + }, { + v1: NewUint64(2), + v2: NewUint64(math.MaxUint64), + err: vterrors.New(vtrpcpb.Code_INVALID_ARGUMENT, "BIGINT UNSIGNED value is out of range in 2 * 18446744073709551615"), }} for _, tcase := range tcases { From 0b191d648ae7f3302322b2e1e54a4e120b7f509c Mon Sep 17 00:00:00 2001 From: Morgan Tocker Date: Fri, 6 Sep 2019 14:57:28 -0600 Subject: [PATCH 057/425] fix docker pre-fetch of go modules Signed-off-by: Morgan Tocker --- docker/bootstrap/Dockerfile.common | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/docker/bootstrap/Dockerfile.common b/docker/bootstrap/Dockerfile.common index 01d461228db..8288a479eea 100644 --- a/docker/bootstrap/Dockerfile.common +++ b/docker/bootstrap/Dockerfile.common @@ -52,19 +52,21 @@ ENV USER vitess ENV GO111MODULE on # Copy files needed for bootstrap -COPY bootstrap.sh dev.env build.env /vt/src/vitess.io/vitess/ +COPY bootstrap.sh dev.env build.env go.mod go.sum /vt/src/vitess.io/vitess/ COPY config /vt/src/vitess.io/vitess/config COPY third_party /vt/src/vitess.io/vitess/third_party COPY tools /vt/src/vitess.io/vitess/tools COPY travis /vt/src/vitess.io/vitess/travis -RUN go mod download - # Create vitess user RUN groupadd -r vitess && useradd -r -g vitess vitess && \ mkdir -p /vt/vtdataroot /home/vitess && \ chown -R vitess:vitess /vt /home/vitess +# Download vendored Go dependencies +RUN cd /vt/src/vitess.io/vitess && \ + su vitess -c "/usr/local/go/bin/go mod download" + # Create mount point for actual data (e.g. MySQL data dir) VOLUME /vt/vtdataroot From a52ce844ed163d4690d392b3bb418608d42cfdea Mon Sep 17 00:00:00 2001 From: Rasika Kale Date: Fri, 6 Sep 2019 15:59:34 -0700 Subject: [PATCH 058/425] Completed error checking for uintTimesIntWithError() - Added more tests in arithmetic_test.go to confirm code is covered and error checking works Signed-off-by: Rasika Kale --- go/sqltypes/arithmetic.go | 2 +- go/sqltypes/arithmetic_test.go | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/go/sqltypes/arithmetic.go b/go/sqltypes/arithmetic.go index 4d65fbb2a4b..dcbc1a2380b 100644 --- a/go/sqltypes/arithmetic.go +++ b/go/sqltypes/arithmetic.go @@ -544,7 +544,7 @@ func uintMinusIntWithError(v1 uint64, v2 int64) (numeric, error) { } func uintTimesIntWithError(v1 uint64, v2 int64) (numeric, error) { - if v2 < 0 || v1 >= math.MaxUint64 && v2 > 0 { + if v2 < 0 || v1 >= math.MaxInt64 && v2 > 2 || int64(v1) < 0 { return numeric{}, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "BIGINT UNSIGNED value is out of range in %v * %v", v1, v2) } return uintTimesUintWithError(v1, uint64(v2)) diff --git a/go/sqltypes/arithmetic_test.go b/go/sqltypes/arithmetic_test.go index 6b811d70735..857b6b715ce 100644 --- a/go/sqltypes/arithmetic_test.go +++ b/go/sqltypes/arithmetic_test.go @@ -35,31 +35,26 @@ func TestMultiply(t *testing.T) { out Value err error }{{ - //All Nulls v1: NULL, v2: NULL, out: NULL, }, { - // First value null. v1: NewInt32(1), v2: NULL, out: NULL, }, { - // Second value null. v1: NULL, v2: NewInt32(1), out: NULL, }, { - // case with negative value v1: NewInt64(-1), v2: NewInt64(-2), out: NewInt64(2), }, { - // testing for int64 overflow with min negative value v1: NewInt64(math.MinInt64), v2: NewInt64(1), @@ -112,6 +107,11 @@ func TestMultiply(t *testing.T) { v1: NewUint64(2), v2: NewUint64(math.MaxUint64), err: vterrors.New(vtrpcpb.Code_INVALID_ARGUMENT, "BIGINT UNSIGNED value is out of range in 2 * 18446744073709551615"), + }, { + //Checking whether maxInt value can be passed as uint value + v1: NewUint64(math.MaxInt64), + v2: NewInt64(3), + err: vterrors.New(vtrpcpb.Code_INVALID_ARGUMENT, "BIGINT UNSIGNED value is out of range in 9223372036854775807 * 3"), }} for _, tcase := range tcases { From f955b700aeae21d4d23f168526dc6a44983dd276 Mon Sep 17 00:00:00 2001 From: Morgan Tocker Date: Fri, 6 Sep 2019 17:22:51 -0600 Subject: [PATCH 059/425] Empty commit Signed-off-by: Morgan Tocker From de1ca3dc6ec52d130f2ee0f3fae74fb2305ec22d Mon Sep 17 00:00:00 2001 From: Yufei Chen Date: Fri, 6 Sep 2019 16:17:54 +1000 Subject: [PATCH 060/425] making sure fresh state works before turning off query service during a split Signed-off-by: Yufei Chen --- go/vt/wrangler/keyspace.go | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/go/vt/wrangler/keyspace.go b/go/vt/wrangler/keyspace.go index a95672f227f..b31f20d83c2 100644 --- a/go/vt/wrangler/keyspace.go +++ b/go/vt/wrangler/keyspace.go @@ -641,11 +641,22 @@ func (wr *Wrangler) masterMigrateServedType(ctx context.Context, keyspace string }() // Phase 1 + // - check topology service can successfully refresh both source and target master // - switch the source shards to read-only by disabling query service // - gather all replication points // - wait for filtered replication to catch up // - mark source shards as frozen event.DispatchUpdate(ev, "disabling query service on all source masters") + // making sure the refreshMaster on both source and target are working before turning off query service on source + if err := wr.refreshMasters(ctx, sourceShards); err != nil { + wr.cancelMasterMigrateServedTypes(ctx, keyspace, sourceShards) + return err + } + if err := wr.refreshMasters(ctx, destinationShards); err != nil { + wr.cancelMasterMigrateServedTypes(ctx, keyspace, sourceShards) + return err + } + if err := wr.updateShardRecords(ctx, keyspace, sourceShards, nil, topodatapb.TabletType_MASTER, true, false); err != nil { wr.cancelMasterMigrateServedTypes(ctx, keyspace, sourceShards) return err From c024f956cc19687f294baa3dded92c7f82480ebb Mon Sep 17 00:00:00 2001 From: deepthi Date: Mon, 9 Sep 2019 11:43:26 -0700 Subject: [PATCH 061/425] change fatal to error if we are unable to update local_metadata or shard_metadata Signed-off-by: deepthi --- go/vt/mysqlctl/metadata_tables.go | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/go/vt/mysqlctl/metadata_tables.go b/go/vt/mysqlctl/metadata_tables.go index d1607723467..a3d64d9c869 100644 --- a/go/vt/mysqlctl/metadata_tables.go +++ b/go/vt/mysqlctl/metadata_tables.go @@ -96,8 +96,9 @@ func PopulateMetadataTables(mysqld MysqlDaemon, localMetadata map[string]string, } } } - if _, err := conn.ExecuteFetch(fmt.Sprintf(sqlUpdateLocalMetadataTable, dbName), 0, false); err != nil { - return err + sql := fmt.Sprintf(sqlUpdateLocalMetadataTable, dbName) + if _, err := conn.ExecuteFetch(sql, 0, false); err != nil { + log.Errorf("unexpected error executing %v: %v, continuing. Please check the data in _vt.local_metadata and take corrective action", sql, err) } if _, err := conn.ExecuteFetch(sqlCreateShardMetadataTable, 0, false); err != nil { return err @@ -112,8 +113,9 @@ func PopulateMetadataTables(mysqld MysqlDaemon, localMetadata map[string]string, } } } - if _, err := conn.ExecuteFetch(fmt.Sprintf(sqlUpdateShardMetadataTable, dbName), 0, false); err != nil { - return err + sql = fmt.Sprintf(sqlUpdateShardMetadataTable, dbName) + if _, err := conn.ExecuteFetch(sql, 0, false); err != nil { + log.Errorf("unexpected error executing %v: %v, continuing. Please check the data in _vt.shard_metadata and take corrective action", sql, err) } // Populate local_metadata from the passed list of values. From a65a7f6fa7191a05a86da80d79a909052d85b0d6 Mon Sep 17 00:00:00 2001 From: deepthi Date: Fri, 30 Aug 2019 17:59:34 -0700 Subject: [PATCH 062/425] along with old master also update any other tablet that thinks it is master to REPLICA Signed-off-by: deepthi --- .../tabletmanager/rpc_external_reparent.go | 51 +++++++++++++++---- .../testlib/reparent_external_test.go | 2 +- 2 files changed, 42 insertions(+), 11 deletions(-) diff --git a/go/vt/vttablet/tabletmanager/rpc_external_reparent.go b/go/vt/vttablet/tabletmanager/rpc_external_reparent.go index 7b066ed1e1a..d53c88740d4 100644 --- a/go/vt/vttablet/tabletmanager/rpc_external_reparent.go +++ b/go/vt/vttablet/tabletmanager/rpc_external_reparent.go @@ -143,11 +143,12 @@ func (agent *ActionAgent) finalizeTabletExternallyReparented(ctx context.Context var oldMasterTablet *topodatapb.Tablet oldMasterAlias := si.MasterAlias - // Update the tablet records concurrently. + // Update the new and old master tablet records concurrently. event.DispatchUpdate(ev, "updating old and new master tablet records") log.Infof("finalizeTabletExternallyReparented: updating tablet records") wg.Add(1) go func() { + log.Infof("finalizeTabletExternallyReparented: updating tablet record for new master: %v", agent.TabletAlias) defer wg.Done() // Update our own record to master. _, err := agent.TopoServer.UpdateTabletFields(ctx, agent.TabletAlias, @@ -160,9 +161,14 @@ func (agent *ActionAgent) finalizeTabletExternallyReparented(ctx context.Context } }() + tablet := agent.Tablet() + tabletMap, err := agent.TopoServer.GetTabletMapForShard(ctx, tablet.Keyspace, tablet.Shard) + // make the channel buffer big enough that it doesn't block senders + tablets := make(chan topodatapb.Tablet, len(tabletMap)) if !topoproto.TabletAliasIsZero(oldMasterAlias) { wg.Add(1) go func() { + log.Infof("finalizeTabletExternallyReparented: updating tablet record for old master: %v", oldMasterAlias) defer wg.Done() // Forcibly demote the old master in topology, since we can't rely on the @@ -180,15 +186,38 @@ func (agent *ActionAgent) finalizeTabletExternallyReparented(ctx context.Context // We now know more about the old master, so add it to event data. ev.OldMaster = *oldMasterTablet + tablets <- *oldMasterTablet }() } - tablet := agent.Tablet() + // update any other tablets claiming to be MASTER also to REPLICA + for alias, tabletInfo := range tabletMap { + if alias != topoproto.TabletAliasString(agent.TabletAlias) && alias != topoproto.TabletAliasString(oldMasterAlias) && tabletInfo.Tablet.Type == topodatapb.TabletType_MASTER { + log.Infof("finalizeTabletExternallyReparented: updating tablet record for another old master: %v", alias) + wg.Add(1) + go func() { + defer wg.Done() + var err error + tab, err := agent.TopoServer.UpdateTabletFields(ctx, tabletInfo.Tablet.Alias, + func(tablet *topodatapb.Tablet) error { + tablet.Type = topodatapb.TabletType_REPLICA + return nil + }) + if err != nil { + errs.RecordError(err) + return + } + tablets <- *tab + }() + } + } // Wait for the tablet records to be updated. At that point, any rebuild will // see the new master, so we're ready to mark the reparent as done in the // global shard record. wg.Wait() + // we waited for all goroutines to complete, so now close the channel + close(tablets) if errs.HasErrors() { return errs.Error() } @@ -221,22 +250,24 @@ func (agent *ActionAgent) finalizeTabletExternallyReparented(ctx context.Context errs.RecordError(err) } }() - if !topoproto.TabletAliasIsZero(oldMasterAlias) { + wg.Wait() + + for tab := range tablets { + log.Infof("finalizeTabletExternallyReparented: Refresh state for tablet: %v", topoproto.TabletAliasString(tab.Alias)) wg.Add(1) - go func() { + go func(tablet *topodatapb.Tablet) { defer wg.Done() - // Tell the old master to re-read its tablet record and change its state. + // Tell the old master(s) to re-read its tablet record and change its state. // We don't need to put error into errs if this fails, but we need to wait - // for it to make sure that old master tablet is not stuck in the MASTER + // for it to make sure that an old master tablet is not stuck in the MASTER // state. tmc := tmclient.NewTabletManagerClient() - if err := tmc.RefreshState(ctx, oldMasterTablet); err != nil { - log.Warningf("Error calling RefreshState on old master %v: %v", topoproto.TabletAliasString(oldMasterTablet.Alias), err) + if err := tmc.RefreshState(ctx, tablet); err != nil { + log.Warningf("Error calling RefreshState on old master %v: %v", topoproto.TabletAliasString(tablet.Alias), err) } - }() + }(&tab) } - wg.Wait() if errs.HasErrors() { return errs.Error() diff --git a/go/vt/wrangler/testlib/reparent_external_test.go b/go/vt/wrangler/testlib/reparent_external_test.go index 153bb8d0a72..79176b82cb4 100644 --- a/go/vt/wrangler/testlib/reparent_external_test.go +++ b/go/vt/wrangler/testlib/reparent_external_test.go @@ -300,7 +300,7 @@ func TestTabletExternallyReparentedFailedOldMaster(t *testing.T) { t.Fatalf("GetTablet(%v) failed: %v", oldMaster.Tablet.Alias, err) } if tablet.Type != topodatapb.TabletType_REPLICA { - t.Fatalf("old master should be spare but is: %v", tablet.Type) + t.Fatalf("old master should be replica but is: %v", tablet.Type) } } From bd17a0004042b40cfce1de9c5f636e1179099ac9 Mon Sep 17 00:00:00 2001 From: Sugu Sougoumarane Date: Mon, 9 Sep 2019 16:59:06 -0700 Subject: [PATCH 063/425] maintainers: add morgo and systay Signed-off-by: Sugu Sougoumarane --- MAINTAINERS.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/MAINTAINERS.md b/MAINTAINERS.md index 7b527586cb0..911b58cfd67 100644 --- a/MAINTAINERS.md +++ b/MAINTAINERS.md @@ -2,6 +2,7 @@ This page lists all active maintainers and their areas of expertise. This can be The following is the full list, alphabetically ordered. +* Andres Taylor ([systay](https://github.com/systay)) antaylor@squareup.com * Dan Kozlowski ([dkhenry](https://github.com/dkhenry)) koz@planetscale.com * David Weitzman ([dweitzman](https://github.com/dweitzman)) dweitzman@pinterest.com * Deepthi Sigireddi ([deepthi](https://github.com/deepthi)) deepthi@planetscale.com @@ -11,22 +12,23 @@ The following is the full list, alphabetically ordered. * Leo X. Lin ([leoxlin](https://github.com/leoxlin)) llin@hubspot.com * Michael Demmer ([demmer](https://github.com/demmer)) mdemmer@slack-corp.com * Michael Pawliszyn ([mpawliszyn](https://github.com/mpawliszyn)) mikepaw@squareup.com +* Morgan Tocker ([morgo](https://github.com/morgo)) morgan@planetscale.com * Rafael Chacon ([rafael](https://github.com/rafael)) rchacon@slack-corp.com * Sugu Sougoumarane ([sougou](https://github.com/sougou)) sougou@planetscale.com ## Areas of expertise ### General Vitess -sougou, demmer, rafael, dweitzman, tirsen +sougou, demmer, rafael, dweitzman, tirsen, morgo ### Builds -dkhenry +dkhenry, morgo ### Resharding -sougou, rafael, tirsen, dweitzman +sougou, rafael, tirsen, dweitzman, systay ### Parser -sougou, dweitzman, deepthi +sougou, dweitzman, deepthi, systay ### Backups deepthi, rafael From 7bd6618620ccfc6ec45a71ba09f95ad66310afb5 Mon Sep 17 00:00:00 2001 From: deepthi Date: Mon, 9 Sep 2019 20:10:19 -0700 Subject: [PATCH 064/425] address review comments Signed-off-by: deepthi --- .../tabletmanager/rpc_external_reparent.go | 30 +++++++++++-------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/go/vt/vttablet/tabletmanager/rpc_external_reparent.go b/go/vt/vttablet/tabletmanager/rpc_external_reparent.go index d53c88740d4..5b5a172c580 100644 --- a/go/vt/vttablet/tabletmanager/rpc_external_reparent.go +++ b/go/vt/vttablet/tabletmanager/rpc_external_reparent.go @@ -148,8 +148,8 @@ func (agent *ActionAgent) finalizeTabletExternallyReparented(ctx context.Context log.Infof("finalizeTabletExternallyReparented: updating tablet records") wg.Add(1) go func() { - log.Infof("finalizeTabletExternallyReparented: updating tablet record for new master: %v", agent.TabletAlias) defer wg.Done() + log.Infof("finalizeTabletExternallyReparented: updating tablet record for new master: %v", agent.TabletAlias) // Update our own record to master. _, err := agent.TopoServer.UpdateTabletFields(ctx, agent.TabletAlias, func(tablet *topodatapb.Tablet) error { @@ -163,13 +163,17 @@ func (agent *ActionAgent) finalizeTabletExternallyReparented(ctx context.Context tablet := agent.Tablet() tabletMap, err := agent.TopoServer.GetTabletMapForShard(ctx, tablet.Keyspace, tablet.Shard) + if err != nil { + log.Errorf("ignoring error %v from GetTabletMapForShard so that we can process any partial results", err) + } + // make the channel buffer big enough that it doesn't block senders - tablets := make(chan topodatapb.Tablet, len(tabletMap)) + tabletsToRefresh := make(chan topodatapb.Tablet, len(tabletMap)+1) if !topoproto.TabletAliasIsZero(oldMasterAlias) { wg.Add(1) go func() { - log.Infof("finalizeTabletExternallyReparented: updating tablet record for old master: %v", oldMasterAlias) defer wg.Done() + log.Infof("finalizeTabletExternallyReparented: updating tablet record for old master: %v", oldMasterAlias) // Forcibly demote the old master in topology, since we can't rely on the // old master to be up to change its own record. @@ -186,19 +190,20 @@ func (agent *ActionAgent) finalizeTabletExternallyReparented(ctx context.Context // We now know more about the old master, so add it to event data. ev.OldMaster = *oldMasterTablet - tablets <- *oldMasterTablet + tabletsToRefresh <- *oldMasterTablet }() } // update any other tablets claiming to be MASTER also to REPLICA - for alias, tabletInfo := range tabletMap { - if alias != topoproto.TabletAliasString(agent.TabletAlias) && alias != topoproto.TabletAliasString(oldMasterAlias) && tabletInfo.Tablet.Type == topodatapb.TabletType_MASTER { + for _, tabletInfo := range tabletMap { + alias := tabletInfo.Tablet.Alias + if !topoproto.TabletAliasEqual(alias, agent.TabletAlias) && !topoproto.TabletAliasEqual(alias, oldMasterAlias) && tabletInfo.Tablet.Type == topodatapb.TabletType_MASTER { log.Infof("finalizeTabletExternallyReparented: updating tablet record for another old master: %v", alias) wg.Add(1) - go func() { + go func(alias *topodatapb.TabletAlias) { defer wg.Done() var err error - tab, err := agent.TopoServer.UpdateTabletFields(ctx, tabletInfo.Tablet.Alias, + tab, err := agent.TopoServer.UpdateTabletFields(ctx, alias, func(tablet *topodatapb.Tablet) error { tablet.Type = topodatapb.TabletType_REPLICA return nil @@ -207,8 +212,8 @@ func (agent *ActionAgent) finalizeTabletExternallyReparented(ctx context.Context errs.RecordError(err) return } - tablets <- *tab - }() + tabletsToRefresh <- *tab + }(alias) } } @@ -217,7 +222,7 @@ func (agent *ActionAgent) finalizeTabletExternallyReparented(ctx context.Context // global shard record. wg.Wait() // we waited for all goroutines to complete, so now close the channel - close(tablets) + close(tabletsToRefresh) if errs.HasErrors() { return errs.Error() } @@ -250,9 +255,8 @@ func (agent *ActionAgent) finalizeTabletExternallyReparented(ctx context.Context errs.RecordError(err) } }() - wg.Wait() - for tab := range tablets { + for tab := range tabletsToRefresh { log.Infof("finalizeTabletExternallyReparented: Refresh state for tablet: %v", topoproto.TabletAliasString(tab.Alias)) wg.Add(1) go func(tablet *topodatapb.Tablet) { From 9db6df7057a57e9339b648486423c9f8b702b11a Mon Sep 17 00:00:00 2001 From: Andres Taylor Date: Tue, 10 Sep 2019 07:34:09 +0200 Subject: [PATCH 065/425] Use interfaces instead of functions I believe this is more idiomatic golang, and it makes it easier to work with the code base on modern IDEs. Signed-off-by: Andres Taylor --- go/trace/opentracing.go | 23 ++++++++++++++--------- go/trace/plugin_jaeger.go | 27 +++++++++++++++------------ 2 files changed, 29 insertions(+), 21 deletions(-) diff --git a/go/trace/opentracing.go b/go/trace/opentracing.go index 6b47177d45b..4413d808a14 100644 --- a/go/trace/opentracing.go +++ b/go/trace/opentracing.go @@ -41,20 +41,25 @@ func (js openTracingSpan) Annotate(key string, value interface{}) { var _ tracingService = (*openTracingService)(nil) +type tracer interface { + GetOpenTracingTracer() opentracing.Tracer + FromString(string) (opentracing.SpanContext, error) +} + type openTracingService struct { - Tracer opentracing.Tracer - fromString func(string) (opentracing.SpanContext, error) - toString func(Span) string + Tracer tracer } // AddGrpcServerOptions is part of an interface implementation func (jf openTracingService) AddGrpcServerOptions(addInterceptors func(s grpc.StreamServerInterceptor, u grpc.UnaryServerInterceptor)) { - addInterceptors(otgrpc.OpenTracingStreamServerInterceptor(jf.Tracer), otgrpc.OpenTracingServerInterceptor(jf.Tracer)) + ot := jf.Tracer.GetOpenTracingTracer() + addInterceptors(otgrpc.OpenTracingStreamServerInterceptor(ot), otgrpc.OpenTracingServerInterceptor(ot)) } // AddGrpcClientOptions is part of an interface implementation func (jf openTracingService) AddGrpcClientOptions(addInterceptors func(s grpc.StreamClientInterceptor, u grpc.UnaryClientInterceptor)) { - addInterceptors(otgrpc.OpenTracingStreamClientInterceptor(jf.Tracer), otgrpc.OpenTracingClientInterceptor(jf.Tracer)) + ot := jf.Tracer.GetOpenTracingTracer() + addInterceptors(otgrpc.OpenTracingStreamClientInterceptor(ot), otgrpc.OpenTracingClientInterceptor(ot)) } // NewClientSpan is part of an interface implementation @@ -68,21 +73,21 @@ func (jf openTracingService) NewClientSpan(parent Span, serviceName, label strin func (jf openTracingService) New(parent Span, label string) Span { var innerSpan opentracing.Span if parent == nil { - innerSpan = jf.Tracer.StartSpan(label) + innerSpan = jf.Tracer.GetOpenTracingTracer().StartSpan(label) } else { jaegerParent := parent.(openTracingSpan) span := jaegerParent.otSpan - innerSpan = jf.Tracer.StartSpan(label, opentracing.ChildOf(span.Context())) + innerSpan = jf.Tracer.GetOpenTracingTracer().StartSpan(label, opentracing.ChildOf(span.Context())) } return openTracingSpan{otSpan: innerSpan} } func (jf openTracingService) NewFromString(parent, label string) (Span, error) { - spanContext, err := jf.fromString(parent) + spanContext, err := jf.Tracer.FromString(parent) if err != nil { return nil, vterrors.Wrap(err, "failed to deserialize span context") } - innerSpan := jf.Tracer.StartSpan(label, opentracing.ChildOf(spanContext)) + innerSpan := jf.Tracer.GetOpenTracingTracer().StartSpan(label, opentracing.ChildOf(spanContext)) return openTracingSpan{otSpan: innerSpan}, nil } diff --git a/go/trace/plugin_jaeger.go b/go/trace/plugin_jaeger.go index abae1bfbe6d..b8053a4e2c8 100644 --- a/go/trace/plugin_jaeger.go +++ b/go/trace/plugin_jaeger.go @@ -82,20 +82,23 @@ func newJagerTracerFromEnv(serviceName string) (tracingService, io.Closer, error opentracing.SetGlobalTracer(tracer) - f1 := func(s string) (context opentracing.SpanContext, e error) { - // I don't understand why I have to do this and not just use `jaeger.ContextFromString` directly - return jaeger.ContextFromString(s) - } - - f2 := func(in Span) string { - otSpan := in.(*openTracingSpan) - jaegerSpanContext := otSpan.otSpan.Context().(*jaeger.SpanContext) - return jaegerSpanContext.String() - } - - return openTracingService{Tracer: tracer, fromString: f1, toString: f2}, closer, nil + return openTracingService{Tracer: &jaegerTracer{actual: tracer}}, closer, nil } func init() { tracingBackendFactories["opentracing-jaeger"] = newJagerTracerFromEnv } + +var _ tracer = (*jaegerTracer)(nil) + +type jaegerTracer struct { + actual opentracing.Tracer +} + +func (*jaegerTracer) FromString(s string) (opentracing.SpanContext, error) { + return jaeger.ContextFromString(s) +} + +func (jt *jaegerTracer) GetOpenTracingTracer() opentracing.Tracer { + return jt.actual +} From 7d05ab564e7e9bcd7f18785d618b980838fe822c Mon Sep 17 00:00:00 2001 From: yuxiaobo Date: Tue, 10 Sep 2019 15:07:52 +0800 Subject: [PATCH 066/425] Grammar tweak Signed-off-by: yuxiaobo --- doc/meetups_notes/05-10-2018.md | 4 ++-- doc/meetups_notes/06-14-2018.md | 2 +- doc/meetups_notes/details.md | 2 +- go/vt/vttablet/tabletmanager/healthcheck_test.go | 10 +++++----- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/doc/meetups_notes/05-10-2018.md b/doc/meetups_notes/05-10-2018.md index 4f9b0381055..8423c882e07 100644 --- a/doc/meetups_notes/05-10-2018.md +++ b/doc/meetups_notes/05-10-2018.md @@ -13,7 +13,7 @@ * Finish full subquery support. * Multi shard DML’s support of PR’s that are already opened. -* Getting all the docs done is too big of a project, for the next release we will go through all the pull requests that have been merged and create a release note based on that. +* Getting all the docs done is too big of a project, for the next release we will go through all the pull requests that have been merged and create a release note based on that. * Once Planet Scale has a team in place, cadence for releases should be every couple months. ### Planet scale update @@ -25,7 +25,7 @@ ### Kubecon update from Sugu: -* It was awesome. Sugu presented in front of 4000 people. +* It was awesome. Sugu presented in front of 4000 people. * Most people have heard about vitess before, but didn’t know exactly what vitess does. After Sugu’s presentation they do! * Documentation keeps being a big debt on the project. Some ideas that were discussed: diff --git a/doc/meetups_notes/06-14-2018.md b/doc/meetups_notes/06-14-2018.md index cb174fd8a88..b207eb2d5db 100644 --- a/doc/meetups_notes/06-14-2018.md +++ b/doc/meetups_notes/06-14-2018.md @@ -25,7 +25,7 @@ Or iPhone one-tap : Or join by phone: - Dial(for higher quality, dial a number based on your current location): + Dial(for higher quality, dial a number based on your current location): US: +1 646 558 8656 or +1 669 900 6833 or +1 877 369 0926 (Toll Free) or +1 877 853 5247 (Toll Free) +1 855 703 8985 (Canada Toll-Free) diff --git a/doc/meetups_notes/details.md b/doc/meetups_notes/details.md index 1c67224dd25..643d8f619d3 100644 --- a/doc/meetups_notes/details.md +++ b/doc/meetups_notes/details.md @@ -20,7 +20,7 @@ Or iPhone one-tap : Or other phone: -Dial(for higher quality, dial a number based on your current location): +Dial(for higher quality, dial a number based on your current location): US: +1 669 900 6833 or +1 646 558 8656 or +1 877 853 5247 (Toll Free) or +1 877 369 0926 (Toll Free) Canada: +1 855 703 8985 (Canada Toll-Free) diff --git a/go/vt/vttablet/tabletmanager/healthcheck_test.go b/go/vt/vttablet/tabletmanager/healthcheck_test.go index 5f59d0e6173..a499fc1f03e 100644 --- a/go/vt/vttablet/tabletmanager/healthcheck_test.go +++ b/go/vt/vttablet/tabletmanager/healthcheck_test.go @@ -173,7 +173,7 @@ func TestHealthCheckControlsQueryService(t *testing.T) { ctx := context.Background() agent := createTestAgent(ctx, t, nil) - /// Consume the first health broadcast triggered by ActionAgent.Start(): + // Consume the first health broadcast triggered by ActionAgent.Start(): // (REPLICA, NOT_SERVING) goes to (REPLICA, SERVING). And we // should be serving. if _, err := expectBroadcastData(agent.QueryServiceControl, true, "healthcheck not run yet", 0); err != nil { @@ -281,7 +281,7 @@ func TestErrSlaveNotRunningIsHealthy(t *testing.T) { ctx := context.Background() agent := createTestAgent(ctx, t, nil) - /// Consume the first health broadcast triggered by ActionAgent.Start(): + // Consume the first health broadcast triggered by ActionAgent.Start(): // (REPLICA, NOT_SERVING) goes to (REPLICA, SERVING). And we // should be serving. if _, err := expectBroadcastData(agent.QueryServiceControl, true, "healthcheck not run yet", 0); err != nil { @@ -390,7 +390,7 @@ func TestQueryServiceStopped(t *testing.T) { ctx := context.Background() agent := createTestAgent(ctx, t, nil) - /// Consume the first health broadcast triggered by ActionAgent.Start(): + // Consume the first health broadcast triggered by ActionAgent.Start(): // (REPLICA, NOT_SERVING) goes to (REPLICA, SERVING). And we // should be serving. if _, err := expectBroadcastData(agent.QueryServiceControl, true, "healthcheck not run yet", 0); err != nil { @@ -488,7 +488,7 @@ func TestTabletControl(t *testing.T) { ctx := context.Background() agent := createTestAgent(ctx, t, nil) - /// Consume the first health broadcast triggered by ActionAgent.Start(): + // Consume the first health broadcast triggered by ActionAgent.Start(): // (REPLICA, NOT_SERVING) goes to (REPLICA, SERVING). And we // should be serving. if _, err := expectBroadcastData(agent.QueryServiceControl, true, "healthcheck not run yet", 0); err != nil { @@ -691,7 +691,7 @@ func TestStateChangeImmediateHealthBroadcast(t *testing.T) { ctx := context.Background() agent := createTestAgent(ctx, t, nil) - /// Consume the first health broadcast triggered by ActionAgent.Start(): + // Consume the first health broadcast triggered by ActionAgent.Start(): // (REPLICA, NOT_SERVING) goes to (REPLICA, SERVING). And we // should be serving. if _, err := expectBroadcastData(agent.QueryServiceControl, true, "healthcheck not run yet", 0); err != nil { From d53de4f4f273aaee0bc7aed268b9607541e45394 Mon Sep 17 00:00:00 2001 From: Anthony Yeh Date: Tue, 10 Sep 2019 09:36:10 -0700 Subject: [PATCH 067/425] xtrabackup: Make sure all files are closed before writing MANIFEST. (#5177) * Update to latest GCS client. Signed-off-by: Anthony Yeh * xtrabackup: Make sure all files are closed before writing MANIFEST. We've observed a backup that was missing files, yet had a MANIFEST. In the built-in backup engine, the contract was that the MANIFEST file must not be written unless all files were confirmed to have been uploaded successfully. In XtraBackup mode, we were not meeting this contract because an error that occurred while closing a file would not be noticed until after we had written the MANIFEST. Signed-off-by: Anthony Yeh --- go.mod | 6 +- go.sum | 11 +++ go/vt/mysqlctl/xtrabackupengine.go | 133 ++++++++++++++++------------- 3 files changed, 90 insertions(+), 60 deletions(-) diff --git a/go.mod b/go.mod index c4ba3b740f7..65d441910d2 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module vitess.io/vitess go 1.12 require ( - cloud.google.com/go v0.43.0 + cloud.google.com/go v0.45.1 github.com/armon/go-metrics v0.0.0-20190430140413-ec5e00d3c878 // indirect github.com/aws/aws-sdk-go v0.0.0-20180223184012-ebef4262e06a github.com/boltdb/bolt v1.3.1 // indirect @@ -22,6 +22,7 @@ require ( github.com/golang/mock v1.3.1 github.com/golang/protobuf v1.3.2 github.com/golang/snappy v0.0.0-20170215233205-553a64147049 + github.com/google/btree v1.0.0 // indirect github.com/gorilla/websocket v0.0.0-20160912153041-2d1e4548da23 github.com/grpc-ecosystem/go-grpc-middleware v0.0.0-20190118093823-f849b5445de4 github.com/grpc-ecosystem/go-grpc-prometheus v0.0.0-20180418170936-39de4380c2e0 @@ -67,8 +68,7 @@ require ( golang.org/x/text v0.3.2 golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 golang.org/x/tools v0.0.0-20190830154057-c17b040389b9 - google.golang.org/api v0.7.0 - google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64 // indirect + google.golang.org/api v0.9.0 google.golang.org/grpc v1.21.1 gopkg.in/asn1-ber.v1 v1.0.0-20150924051756-4e86f4367175 // indirect gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect diff --git a/go.sum b/go.sum index 37c48e4115c..18f93540941 100644 --- a/go.sum +++ b/go.sum @@ -3,6 +3,12 @@ cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMT cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= cloud.google.com/go v0.43.0 h1:banaiRPAM8kUVYneOSkhgcDsLzEvL25FinuiSZaH/2w= cloud.google.com/go v0.43.0/go.mod h1:BOSR3VbTLkk6FDC/TcffxP4NF/FFBGA5ku+jvKOP7pg= +cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= +cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= +cloud.google.com/go v0.45.1 h1:lRi0CHyU+ytlvylOlFKKq0af6JncuyoRh1J+QJBqQx0= +cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= +cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= +cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= @@ -280,6 +286,9 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0 h1:9sdfJOzWlkqPltHAuzT2Cp+yrBeY1KRVYgms8soxMwM= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= +google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.9.0 h1:jbyannxz0XFD3zdjgrSUsaJbgpH4eTrkdhRChkHPfO8= +google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -293,6 +302,8 @@ google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRn google.golang.org/genproto v0.0.0-20190716160619-c506a9f90610/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64 h1:iKtrH9Y8mcbADOP0YFaEMth7OfuHY9xHOwNj4znpM1A= google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55 h1:gSJIx1SDwno+2ElGhA4+qG2zF97qiUzTM+rQ0klBOcE= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1 h1:j6XxA85m/6txkUCHvzlV5f+HBNl/1r5cZ2A/3IEFOO8= diff --git a/go/vt/mysqlctl/xtrabackupengine.go b/go/vt/mysqlctl/xtrabackupengine.go index 31158dba7d9..8ce8fb31dd4 100644 --- a/go/vt/mysqlctl/xtrabackupengine.go +++ b/go/vt/mysqlctl/xtrabackupengine.go @@ -106,6 +106,15 @@ func (be *XtrabackupEngine) backupFileName() string { return fileName } +func closeFile(wc io.WriteCloser, fileName string, logger logutil.Logger, finalErr *error) { + if closeErr := wc.Close(); *finalErr == nil { + *finalErr = closeErr + } else if closeErr != nil { + // since we already have an error just log this + logger.Errorf("error closing file %v: %v", fileName, closeErr) + } +} + // ExecuteBackup returns a boolean that indicates if the backup is usable, // and an overall error. func (be *XtrabackupEngine) ExecuteBackup(ctx context.Context, cnf *Mycnf, mysqld MysqlDaemon, logger logutil.Logger, bh backupstorage.BackupHandle, backupConcurrency int, hookExtraEnv map[string]string) (complete bool, finalErr error) { @@ -128,6 +137,56 @@ func (be *XtrabackupEngine) ExecuteBackup(ctx context.Context, cnf *Mycnf, mysql flavor := pos.GTIDSet.Flavor() logger.Infof("Detected MySQL flavor: %v", flavor) + backupFileName := be.backupFileName() + numStripes := int(*xtrabackupStripes) + + // Perform backups in a separate function, so deferred calls to Close() are + // all done before we continue to write the MANIFEST. This ensures that we + // do not write the MANIFEST unless all files were closed successfully, + // maintaining the contract that a MANIFEST file should only exist if the + // backup was created successfully. + replicationPosition, err := be.backupFiles(ctx, cnf, logger, bh, backupFileName, numStripes, flavor) + if err != nil { + return false, err + } + + // open the MANIFEST + mwc, err := bh.AddFile(ctx, backupManifestFileName, 0) + if err != nil { + return false, vterrors.Wrapf(err, "cannot add %v to backup", backupManifestFileName) + } + defer closeFile(mwc, backupManifestFileName, logger, &finalErr) + + // JSON-encode and write the MANIFEST + bm := &xtraBackupManifest{ + // Common base fields + BackupManifest: BackupManifest{ + BackupMethod: xtrabackupEngineName, + Position: replicationPosition, + FinishedTime: time.Now().UTC().Format(time.RFC3339), + }, + + // XtraBackup-specific fields + FileName: backupFileName, + StreamMode: *xtrabackupStreamMode, + SkipCompress: !*backupStorageCompress, + Params: *xtrabackupBackupFlags, + NumStripes: int32(numStripes), + StripeBlockSize: int32(*xtrabackupStripeBlockSize), + } + + data, err := json.MarshalIndent(bm, "", " ") + if err != nil { + return false, vterrors.Wrapf(err, "cannot JSON encode %v", backupManifestFileName) + } + if _, err := mwc.Write([]byte(data)); err != nil { + return false, vterrors.Wrapf(err, "cannot write %v", backupManifestFileName) + } + + return true, nil +} + +func (be *XtrabackupEngine) backupFiles(ctx context.Context, cnf *Mycnf, logger logutil.Logger, bh backupstorage.BackupHandle, backupFileName string, numStripes int, flavor string) (replicationPosition mysql.Position, finalErr error) { backupProgram := path.Join(*xtrabackupEnginePath, xtrabackupBinaryName) flagsToExec := []string{"--defaults-file=" + cnf.path, @@ -140,40 +199,32 @@ func (be *XtrabackupEngine) ExecuteBackup(ctx context.Context, cnf *Mycnf, mysql if *xtrabackupStreamMode != "" { flagsToExec = append(flagsToExec, "--stream="+*xtrabackupStreamMode) } - if *xtrabackupBackupFlags != "" { flagsToExec = append(flagsToExec, strings.Fields(*xtrabackupBackupFlags)...) } - backupFileName := be.backupFileName() - numStripes := int(*xtrabackupStripes) - destFiles, err := addStripeFiles(ctx, bh, backupFileName, numStripes, logger) if err != nil { - return false, vterrors.Wrapf(err, "cannot create backup file %v", backupFileName) - } - closeFile := func(wc io.WriteCloser, fileName string) { - if closeErr := wc.Close(); finalErr == nil { - finalErr = closeErr - } else if closeErr != nil { - // since we already have an error just log this - logger.Errorf("error closing file %v: %v", fileName, closeErr) - } + return replicationPosition, vterrors.Wrapf(err, "cannot create backup file %v", backupFileName) } defer func() { - for _, file := range destFiles { - closeFile(file, backupFileName) + filename := backupFileName + for i, file := range destFiles { + if numStripes > 1 { + filename = stripeFileName(backupFileName, i) + } + closeFile(file, filename, logger, &finalErr) } }() backupCmd := exec.CommandContext(ctx, backupProgram, flagsToExec...) backupOut, err := backupCmd.StdoutPipe() if err != nil { - return false, vterrors.Wrap(err, "cannot create stdout pipe") + return replicationPosition, vterrors.Wrap(err, "cannot create stdout pipe") } backupErr, err := backupCmd.StderrPipe() if err != nil { - return false, vterrors.Wrap(err, "cannot create stderr pipe") + return replicationPosition, vterrors.Wrap(err, "cannot create stderr pipe") } destWriters := []io.Writer{} @@ -188,7 +239,7 @@ func (be *XtrabackupEngine) ExecuteBackup(ctx context.Context, cnf *Mycnf, mysql if *backupStorageCompress { compressor, err := pgzip.NewWriterLevel(writer, pgzip.BestSpeed) if err != nil { - return false, vterrors.Wrap(err, "cannot create gzip compressor") + return replicationPosition, vterrors.Wrap(err, "cannot create gzip compressor") } compressor.SetConcurrency(*backupCompressBlockSize, *backupCompressBlocks) writer = compressor @@ -199,7 +250,7 @@ func (be *XtrabackupEngine) ExecuteBackup(ctx context.Context, cnf *Mycnf, mysql } if err = backupCmd.Start(); err != nil { - return false, vterrors.Wrap(err, "unable to start backup") + return replicationPosition, vterrors.Wrap(err, "unable to start backup") } // Read stderr in the background, so we can log progress as xtrabackup runs. @@ -240,20 +291,20 @@ func (be *XtrabackupEngine) ExecuteBackup(ctx context.Context, cnf *Mycnf, mysql blockSize = 1024 } if _, err := copyToStripes(destWriters, backupOut, blockSize); err != nil { - return false, vterrors.Wrap(err, "cannot copy output from xtrabackup command") + return replicationPosition, vterrors.Wrap(err, "cannot copy output from xtrabackup command") } // Close compressor to flush it. After that all data is sent to the buffer. for _, compressor := range destCompressors { if err := compressor.Close(); err != nil { - return false, vterrors.Wrap(err, "cannot close gzip compressor") + return replicationPosition, vterrors.Wrap(err, "cannot close gzip compressor") } } // Flush the buffer to finish writing on destination. for _, buffer := range destBuffers { if err = buffer.Flush(); err != nil { - return false, vterrors.Wrapf(err, "cannot flush destination: %v", backupFileName) + return replicationPosition, vterrors.Wrapf(err, "cannot flush destination: %v", backupFileName) } } @@ -263,47 +314,15 @@ func (be *XtrabackupEngine) ExecuteBackup(ctx context.Context, cnf *Mycnf, mysql sterrOutput := stderrBuilder.String() if err := backupCmd.Wait(); err != nil { - return false, vterrors.Wrap(err, "xtrabackup failed with error") + return replicationPosition, vterrors.Wrap(err, "xtrabackup failed with error") } replicationPosition, rerr := findReplicationPosition(sterrOutput, flavor, logger) if rerr != nil { - return false, vterrors.Wrap(rerr, "backup failed trying to find replication position") + return replicationPosition, vterrors.Wrap(rerr, "backup failed trying to find replication position") } - // open the MANIFEST - mwc, err := bh.AddFile(ctx, backupManifestFileName, 0) - if err != nil { - return false, vterrors.Wrapf(err, "cannot add %v to backup", backupManifestFileName) - } - defer closeFile(mwc, backupManifestFileName) - // JSON-encode and write the MANIFEST - bm := &xtraBackupManifest{ - // Common base fields - BackupManifest: BackupManifest{ - BackupMethod: xtrabackupEngineName, - Position: replicationPosition, - FinishedTime: time.Now().UTC().Format(time.RFC3339), - }, - - // XtraBackup-specific fields - FileName: backupFileName, - StreamMode: *xtrabackupStreamMode, - SkipCompress: !*backupStorageCompress, - Params: *xtrabackupBackupFlags, - NumStripes: int32(numStripes), - StripeBlockSize: int32(*xtrabackupStripeBlockSize), - } - - data, err := json.MarshalIndent(bm, "", " ") - if err != nil { - return false, vterrors.Wrapf(err, "cannot JSON encode %v", backupManifestFileName) - } - if _, err := mwc.Write([]byte(data)); err != nil { - return false, vterrors.Wrapf(err, "cannot write %v", backupManifestFileName) - } - - return true, nil + return replicationPosition, nil } // ExecuteRestore restores from a backup. Any error is returned. From 355c915a09b87b440433b8cf5ce6f82c91174a30 Mon Sep 17 00:00:00 2001 From: Rasika Kale Date: Tue, 10 Sep 2019 09:51:40 -0700 Subject: [PATCH 068/425] Changed error checking to account for corner cases - checked if v1 < 0 in intMinusUintWithError() - checked if v2 is greater that v1 and greater than 0 in uintMinusIntWithError()_ - within uintMinusIntWithError() checked if v2 < 0, then returned uintPlusIntWithError(v1, -v2) - checked if v2 > v1 in uintMinusUintWithError() - Added function floatMinusAny() in subtractNumericWithError() to account for float - value expressions Signed-off-by: Rasika Kale --- go/sqltypes/arithmetic.go | 30 +++++++++++++++++++++++------- go/sqltypes/arithmetic_test.go | 25 +++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 7 deletions(-) diff --git a/go/sqltypes/arithmetic.go b/go/sqltypes/arithmetic.go index 94488494536..cde014116eb 100644 --- a/go/sqltypes/arithmetic.go +++ b/go/sqltypes/arithmetic.go @@ -402,7 +402,6 @@ func addNumericWithError(v1, v2 numeric) (numeric, error) { return floatPlusAny(v1.fval, v2), nil } panic("unreachable") - } func subtractNumericWithError(v1, v2 numeric) (numeric, error) { @@ -413,6 +412,8 @@ func subtractNumericWithError(v1, v2 numeric) (numeric, error) { return intMinusIntWithError(v1.ival, v2.ival) case Uint64: return intMinusUintWithError(v1.ival, v2.uval) + case Float64: + return anyMinusFloat(v1, v2.fval), nil } case Uint64: switch v2.typ { @@ -420,12 +421,13 @@ func subtractNumericWithError(v1, v2 numeric) (numeric, error) { return uintMinusIntWithError(v1.uval, v2.ival) case Uint64: return uintMinusUintWithError(v1.uval, v2.uval) + case Float64: + return anyMinusFloat(v1, v2.fval), nil } case Float64: return floatMinusAny(v1.fval, v2), nil } panic("unreachable") - } // prioritize reorders the input parameters @@ -472,12 +474,11 @@ func intMinusIntWithError(v1, v2 int64) (numeric, error) { if (result < v1) != (v2 > 0) { return numeric{}, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "BIGINT value is out of range in %v - %v", v1, v2) } - return numeric{typ: Int64, ival: result}, nil } func intMinusUintWithError(v1 int64, v2 uint64) (numeric, error) { - if v1 < 0 { + if v1 < 0 || v1 < int64(v2) { return numeric{}, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "BIGINT UNSIGNED value is out of range in %v - %v", v1, v2) } return uintMinusUintWithError(uint64(v1), v2) @@ -497,9 +498,13 @@ func uintPlusIntWithError(v1 uint64, v2 int64) (numeric, error) { } func uintMinusIntWithError(v1 uint64, v2 int64) (numeric, error) { - if v1 < uint64(v2) { + if int64(v1) < v2 && v2 > 0 { return numeric{}, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "BIGINT UNSIGNED value is out of range in %v - %v", v1, v2) } + // uint - (- int) = uint + int + if v2 < 0 { + return uintPlusIntWithError(v1, -v2) + } return uintMinusUintWithError(v1, uint64(v2)) } @@ -513,7 +518,6 @@ func uintPlusUint(v1, v2 uint64) numeric { func uintPlusUintWithError(v1, v2 uint64) (numeric, error) { result := v1 + v2 - if result < v2 { return numeric{}, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "BIGINT UNSIGNED value is out of range in %v + %v", v1, v2) } @@ -522,7 +526,9 @@ func uintPlusUintWithError(v1, v2 uint64) (numeric, error) { func uintMinusUintWithError(v1, v2 uint64) (numeric, error) { result := v1 - v2 - + if v2 > v1 { + return numeric{}, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "BIGINT UNSIGNED value is out of range in %v - %v", v1, v2) + } return numeric{typ: Uint64, uval: result}, nil } @@ -546,6 +552,16 @@ func floatMinusAny(v1 float64, v2 numeric) numeric { return numeric{typ: Float64, fval: v1 - v2.fval} } +func anyMinusFloat(v1 numeric, v2 float64) numeric { + switch v1.typ { + case Int64: + v1.fval = float64(v1.ival) + case Uint64: + v1.fval = float64(v1.uval) + } + return numeric{typ: Float64, fval: v1.fval - v2} +} + func castFromNumeric(v numeric, resultType querypb.Type) Value { switch { case IsSigned(resultType): diff --git a/go/sqltypes/arithmetic_test.go b/go/sqltypes/arithmetic_test.go index 6c99d081d4e..81fc378e198 100644 --- a/go/sqltypes/arithmetic_test.go +++ b/go/sqltypes/arithmetic_test.go @@ -118,6 +118,31 @@ func TestSubtract(t *testing.T) { v1: NewInt64(2), v2: NewUint64(1), out: NewUint64(1), + }, { + // testing int64 - float64 method + v1: NewInt64(-2), + v2: NewFloat64(1.0), + out: NewFloat64(-3.0), + }, { + // testing uint64 - float64 method + v1: NewUint64(1), + v2: NewFloat64(-2.0), + out: NewFloat64(3.0), + }, { + // testing uint - int to return uintplusint + v1: NewUint64(1), + v2: NewInt64(-2), + out: NewUint64(3), + }, { + // testing for float - float + v1: NewFloat64(1.2), + v2: NewFloat64(3.2), + out: NewFloat64(-2), + }, { + // testing uint - uint if v2 > v1 + v1: NewUint64(2), + v2: NewUint64(4), + err: vterrors.New(vtrpcpb.Code_INVALID_ARGUMENT, "BIGINT UNSIGNED value is out of range in 2 - 4"), }} for _, tcase := range tcases { From 2b718e9d93f4a7100ee3566afa1e7c5000f8498c Mon Sep 17 00:00:00 2001 From: deepthi Date: Tue, 10 Sep 2019 10:57:27 -0700 Subject: [PATCH 069/425] check tablet is really master before changing type, add unit test Signed-off-by: deepthi --- .../tabletmanager/rpc_external_reparent.go | 20 ++++-- .../testlib/reparent_external_test.go | 70 ++++++++++++++++++- 2 files changed, 84 insertions(+), 6 deletions(-) diff --git a/go/vt/vttablet/tabletmanager/rpc_external_reparent.go b/go/vt/vttablet/tabletmanager/rpc_external_reparent.go index 5b5a172c580..80988aabdbe 100644 --- a/go/vt/vttablet/tabletmanager/rpc_external_reparent.go +++ b/go/vt/vttablet/tabletmanager/rpc_external_reparent.go @@ -180,7 +180,9 @@ func (agent *ActionAgent) finalizeTabletExternallyReparented(ctx context.Context var err error oldMasterTablet, err = agent.TopoServer.UpdateTabletFields(ctx, oldMasterAlias, func(tablet *topodatapb.Tablet) error { - tablet.Type = topodatapb.TabletType_REPLICA + if tablet.Type == topodatapb.TabletType_MASTER { + tablet.Type = topodatapb.TabletType_REPLICA + } return nil }) if err != nil { @@ -189,8 +191,11 @@ func (agent *ActionAgent) finalizeTabletExternallyReparented(ctx context.Context } // We now know more about the old master, so add it to event data. - ev.OldMaster = *oldMasterTablet - tabletsToRefresh <- *oldMasterTablet + // oldMasterTablet will be nil if no update was needed + if oldMasterTablet != nil { + ev.OldMaster = *oldMasterTablet + tabletsToRefresh <- *oldMasterTablet + } }() } @@ -205,14 +210,19 @@ func (agent *ActionAgent) finalizeTabletExternallyReparented(ctx context.Context var err error tab, err := agent.TopoServer.UpdateTabletFields(ctx, alias, func(tablet *topodatapb.Tablet) error { - tablet.Type = topodatapb.TabletType_REPLICA + if tablet.Type == topodatapb.TabletType_MASTER { + tablet.Type = topodatapb.TabletType_REPLICA + } return nil }) if err != nil { errs.RecordError(err) return } - tabletsToRefresh <- *tab + // tab will be nil if no update was needed + if tab != nil { + tabletsToRefresh <- *tab + } }(alias) } } diff --git a/go/vt/wrangler/testlib/reparent_external_test.go b/go/vt/wrangler/testlib/reparent_external_test.go index 79176b82cb4..509b911c974 100644 --- a/go/vt/wrangler/testlib/reparent_external_test.go +++ b/go/vt/wrangler/testlib/reparent_external_test.go @@ -253,7 +253,7 @@ func TestTabletExternallyReparentedContinueOnUnexpectedMaster(t *testing.T) { } func TestTabletExternallyReparentedFailedOldMaster(t *testing.T) { - // The 'RefreshState' clal on the old master will timeout on + // The 'RefreshState' call on the old master will timeout on // this value, so it has to be smaller than the 10s of the // wait for the 'finished' state of waitForExternalReparent. tabletmanager.SetReparentFlags(2 * time.Second /* finalizeTimeout */) @@ -304,6 +304,74 @@ func TestTabletExternallyReparentedFailedOldMaster(t *testing.T) { } } +func TestTabletExternallyReparentedImpostorMaster(t *testing.T) { + tabletmanager.SetReparentFlags(time.Minute /* finalizeTimeout */) + + ctx := context.Background() + ts := memorytopo.NewServer("cell1", "cell2") + wr := wrangler.New(logutil.NewConsoleLogger(), ts, tmclient.NewTabletManagerClient()) + + // Create an old master, a new master, and a bad slave. + badSlave := NewFakeTablet(t, wr, "cell1", 2, topodatapb.TabletType_MASTER, nil) + // do this after badSlave so that the shard record has the expected master + oldMaster := NewFakeTablet(t, wr, "cell1", 0, topodatapb.TabletType_MASTER, nil, ForceInitTablet()) + newMaster := NewFakeTablet(t, wr, "cell1", 1, topodatapb.TabletType_REPLICA, nil) + + // check the old master is really master + tablet, err := ts.GetTablet(ctx, oldMaster.Tablet.Alias) + if err != nil { + t.Fatalf("GetTablet(%v) failed: %v", oldMaster.Tablet.Alias, err) + } + if tablet.Type != topodatapb.TabletType_MASTER { + t.Fatalf("old master should be MASTER but is: %v", tablet.Type) + } + + // On the elected master, we will respond to + // TabletActionSlaveWasPromoted. + newMaster.StartActionLoop(t, wr) + defer newMaster.StopActionLoop(t) + + // On the old master, we will only respond to + // TabletActionSlaveWasRestarted. + oldMaster.StartActionLoop(t, wr) + defer oldMaster.StopActionLoop(t) + + // On the bad slave, we will respond to + // TabletActionSlaveWasRestarted. + badSlave.StartActionLoop(t, wr) + defer badSlave.StopActionLoop(t) + + // The reparent should work as expected here + tmc := tmclient.NewTabletManagerClient() + ti, err := ts.GetTablet(ctx, newMaster.Tablet.Alias) + if err != nil { + t.Fatalf("GetTablet failed: %v", err) + } + waitID := makeWaitID() + if err := tmc.TabletExternallyReparented(context.Background(), ti.Tablet, waitID); err != nil { + t.Fatalf("TabletExternallyReparented(replica) failed: %v", err) + } + waitForExternalReparent(t, "TestTabletExternallyReparentedImpostorMaster: good case", waitID) + + // check the old master was converted to replica + tablet, err = ts.GetTablet(ctx, oldMaster.Tablet.Alias) + if err != nil { + t.Fatalf("GetTablet(%v) failed: %v", oldMaster.Tablet.Alias, err) + } + if tablet.Type != topodatapb.TabletType_REPLICA { + t.Fatalf("old master should be replica but is: %v", tablet.Type) + } + + // check the impostor master was converted to replica + tablet, err = ts.GetTablet(ctx, badSlave.Tablet.Alias) + if err != nil { + t.Fatalf("GetTablet(%v) failed: %v", badSlave.Tablet.Alias, err) + } + if tablet.Type != topodatapb.TabletType_REPLICA { + t.Fatalf("bad slave should be replica but is: %v", tablet.Type) + } +} + var ( externalReparents = make(map[string]chan struct{}) externalReparentsMutex sync.Mutex From dd2f51f94547d1e2613eef22e99eedc6ff713cd4 Mon Sep 17 00:00:00 2001 From: Rasika Kale Date: Tue, 10 Sep 2019 11:42:09 -0700 Subject: [PATCH 070/425] Added test for uint - (- int) Signed-off-by: Rasika Kale --- go/sqltypes/arithmetic_test.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/go/sqltypes/arithmetic_test.go b/go/sqltypes/arithmetic_test.go index 81fc378e198..227b20c7d4c 100644 --- a/go/sqltypes/arithmetic_test.go +++ b/go/sqltypes/arithmetic_test.go @@ -143,6 +143,11 @@ func TestSubtract(t *testing.T) { v1: NewUint64(2), v2: NewUint64(4), err: vterrors.New(vtrpcpb.Code_INVALID_ARGUMENT, "BIGINT UNSIGNED value is out of range in 2 - 4"), + }, { + // testing uint - (- int) + v1: NewUint64(1), + v2: NewInt64(-2), + out: NewUint64(3), }} for _, tcase := range tcases { From 8ec326606de2d8e0f5489c9f2e88312f567bb363 Mon Sep 17 00:00:00 2001 From: Sugu Sougoumarane Date: Sat, 24 Aug 2019 19:32:47 -0700 Subject: [PATCH 071/425] migrater: identify shard migration differently Previously, we identifid a migration as SHARD of the source and target keyspaces matched. But it's possible to have table migrations within a keyspace. This new way identifies a migration as SHARD only if the source and target shards don't match. Signed-off-by: Sugu Sougoumarane --- go/vt/wrangler/migrater.go | 15 +++++++++------ go/vt/wrangler/migrater_test.go | 28 ---------------------------- 2 files changed, 9 insertions(+), 34 deletions(-) diff --git a/go/vt/wrangler/migrater.go b/go/vt/wrangler/migrater.go index 4832d85965f..0f5c368a263 100644 --- a/go/vt/wrangler/migrater.go +++ b/go/vt/wrangler/migrater.go @@ -239,7 +239,16 @@ func (wr *Wrangler) buildMigrater(ctx context.Context, targetKeyspace, workflow if mi.sourceKeyspace != mi.targetKeyspace { mi.migrationType = binlogdatapb.MigrationType_TABLES } else { + // TODO(sougou): for shard migration, validate that source and target combined + // keyranges match. mi.migrationType = binlogdatapb.MigrationType_SHARDS + for sourceShard := range mi.sources { + if _, ok := mi.targets[sourceShard]; ok { + // If shards are overlapping, then this is a table migration. + mi.migrationType = binlogdatapb.MigrationType_TABLES + break + } + } } return mi, nil } @@ -332,12 +341,6 @@ func (mi *migrater) validate(ctx context.Context, isWrite bool) error { return mi.validateTableForWrite(ctx) } } else { // binlogdatapb.MigrationType_SHARDS - // Source and target shards must not match. - for sourceShard := range mi.sources { - if _, ok := mi.targets[sourceShard]; ok { - return fmt.Errorf("target shard matches a source shard: %v", sourceShard) - } - } if isWrite { return mi.validateShardForWrite(ctx) } diff --git a/go/vt/wrangler/migrater_test.go b/go/vt/wrangler/migrater_test.go index 0e9f25995de..2895ed6b46a 100644 --- a/go/vt/wrangler/migrater_test.go +++ b/go/vt/wrangler/migrater_test.go @@ -902,34 +902,6 @@ func TestMigrateNoTableWildcards(t *testing.T) { } } -func TestShardMigrateTargetMatchesSource(t *testing.T) { - ctx := context.Background() - tme := newTestShardMigrater(ctx, t) - defer tme.stopTablets(t) - - bls := &binlogdatapb.BinlogSource{ - Keyspace: "ks", - Shard: "-80", - Filter: &binlogdatapb.Filter{ - Rules: []*binlogdatapb.Rule{{ - Match: "/.*", - Filter: "-80", - }}, - }, - } - tme.dbDest1Client.addQuery(vreplQueryks, sqltypes.MakeTestResult(sqltypes.MakeTestFields( - "id|source", - "int64|varchar"), - fmt.Sprintf("1|%v", bls), - ), nil) - - err := tme.wr.MigrateReads(ctx, tme.targetKeyspace, "test", topodatapb.TabletType_RDONLY, nil, DirectionForward) - want := "target shard matches a source shard" - if err == nil || !strings.Contains(err.Error(), want) { - t.Errorf("MigrateReads: %v, must contain %v", err, want) - } -} - func checkRouting(t *testing.T, wr *Wrangler, want map[string][]string) { t.Helper() ctx := context.Background() From 8236bdb1733de40ab9f971303e3437ffc2cae9eb Mon Sep 17 00:00:00 2001 From: deepthi Date: Tue, 10 Sep 2019 15:52:39 -0700 Subject: [PATCH 072/425] fix race condition, one more unit test Signed-off-by: deepthi --- .../tabletmanager/rpc_external_reparent.go | 6 +- .../testlib/reparent_external_test.go | 101 ++++++++++++++++++ 2 files changed, 104 insertions(+), 3 deletions(-) diff --git a/go/vt/vttablet/tabletmanager/rpc_external_reparent.go b/go/vt/vttablet/tabletmanager/rpc_external_reparent.go index 80988aabdbe..83904ab1ca0 100644 --- a/go/vt/vttablet/tabletmanager/rpc_external_reparent.go +++ b/go/vt/vttablet/tabletmanager/rpc_external_reparent.go @@ -269,7 +269,7 @@ func (agent *ActionAgent) finalizeTabletExternallyReparented(ctx context.Context for tab := range tabletsToRefresh { log.Infof("finalizeTabletExternallyReparented: Refresh state for tablet: %v", topoproto.TabletAliasString(tab.Alias)) wg.Add(1) - go func(tablet *topodatapb.Tablet) { + go func(tablet topodatapb.Tablet) { defer wg.Done() // Tell the old master(s) to re-read its tablet record and change its state. @@ -277,10 +277,10 @@ func (agent *ActionAgent) finalizeTabletExternallyReparented(ctx context.Context // for it to make sure that an old master tablet is not stuck in the MASTER // state. tmc := tmclient.NewTabletManagerClient() - if err := tmc.RefreshState(ctx, tablet); err != nil { + if err := tmc.RefreshState(ctx, &tablet); err != nil { log.Warningf("Error calling RefreshState on old master %v: %v", topoproto.TabletAliasString(tablet.Alias), err) } - }(&tab) + }(tab) } wg.Wait() if errs.HasErrors() { diff --git a/go/vt/wrangler/testlib/reparent_external_test.go b/go/vt/wrangler/testlib/reparent_external_test.go index 509b911c974..11d785f96ac 100644 --- a/go/vt/wrangler/testlib/reparent_external_test.go +++ b/go/vt/wrangler/testlib/reparent_external_test.go @@ -326,6 +326,15 @@ func TestTabletExternallyReparentedImpostorMaster(t *testing.T) { t.Fatalf("old master should be MASTER but is: %v", tablet.Type) } + // check the impostor also claims to be master + tablet, err = ts.GetTablet(ctx, badSlave.Tablet.Alias) + if err != nil { + t.Fatalf("GetTablet(%v) failed: %v", badSlave.Tablet.Alias, err) + } + if tablet.Type != topodatapb.TabletType_MASTER { + t.Fatalf("old master should be MASTER but is: %v", tablet.Type) + } + // On the elected master, we will respond to // TabletActionSlaveWasPromoted. newMaster.StartActionLoop(t, wr) @@ -353,6 +362,98 @@ func TestTabletExternallyReparentedImpostorMaster(t *testing.T) { } waitForExternalReparent(t, "TestTabletExternallyReparentedImpostorMaster: good case", waitID) + // check the new master is really master + tablet, err = ts.GetTablet(ctx, newMaster.Tablet.Alias) + if err != nil { + t.Fatalf("GetTablet(%v) failed: %v", newMaster.Tablet.Alias, err) + } + if tablet.Type != topodatapb.TabletType_MASTER { + t.Fatalf("new master should be MASTER but is: %v", tablet.Type) + } + + // check the old master was converted to replica + tablet, err = ts.GetTablet(ctx, oldMaster.Tablet.Alias) + if err != nil { + t.Fatalf("GetTablet(%v) failed: %v", oldMaster.Tablet.Alias, err) + } + if tablet.Type != topodatapb.TabletType_REPLICA { + t.Fatalf("old master should be replica but is: %v", tablet.Type) + } + + // check the impostor master was converted to replica + tablet, err = ts.GetTablet(ctx, badSlave.Tablet.Alias) + if err != nil { + t.Fatalf("GetTablet(%v) failed: %v", badSlave.Tablet.Alias, err) + } + if tablet.Type != topodatapb.TabletType_REPLICA { + t.Fatalf("bad slave should be replica but is: %v", tablet.Type) + } +} + +func TestTabletExternallyReparentedFailedImpostorMaster(t *testing.T) { + tabletmanager.SetReparentFlags(2 * time.Second /* finalizeTimeout */) + + ctx := context.Background() + ts := memorytopo.NewServer("cell1", "cell2") + wr := wrangler.New(logutil.NewConsoleLogger(), ts, tmclient.NewTabletManagerClient()) + + // Create an old master, a new master, and a bad slave. + badSlave := NewFakeTablet(t, wr, "cell1", 2, topodatapb.TabletType_MASTER, nil) + // do this after badSlave so that the shard record has the expected master + oldMaster := NewFakeTablet(t, wr, "cell1", 0, topodatapb.TabletType_MASTER, nil, ForceInitTablet()) + newMaster := NewFakeTablet(t, wr, "cell1", 1, topodatapb.TabletType_REPLICA, nil) + + // check the old master is really master + tablet, err := ts.GetTablet(ctx, oldMaster.Tablet.Alias) + if err != nil { + t.Fatalf("GetTablet(%v) failed: %v", oldMaster.Tablet.Alias, err) + } + if tablet.Type != topodatapb.TabletType_MASTER { + t.Fatalf("old master should be MASTER but is: %v", tablet.Type) + } + + // check the impostor also claims to be master + tablet, err = ts.GetTablet(ctx, badSlave.Tablet.Alias) + if err != nil { + t.Fatalf("GetTablet(%v) failed: %v", badSlave.Tablet.Alias, err) + } + if tablet.Type != topodatapb.TabletType_MASTER { + t.Fatalf("old master should be MASTER but is: %v", tablet.Type) + } + + // On the elected master, we will respond to + // TabletActionSlaveWasPromoted. + newMaster.StartActionLoop(t, wr) + defer newMaster.StopActionLoop(t) + + // On the old master, we will only respond to + // TabletActionSlaveWasRestarted. + oldMaster.StartActionLoop(t, wr) + defer oldMaster.StopActionLoop(t) + + // Reparent to a replica, and pretend the impostor master is not responding. + + // The reparent should work as expected here + tmc := tmclient.NewTabletManagerClient() + ti, err := ts.GetTablet(ctx, newMaster.Tablet.Alias) + if err != nil { + t.Fatalf("GetTablet failed: %v", err) + } + waitID := makeWaitID() + if err := tmc.TabletExternallyReparented(context.Background(), ti.Tablet, waitID); err != nil { + t.Fatalf("TabletExternallyReparented(replica) failed: %v", err) + } + waitForExternalReparent(t, "TestTabletExternallyReparentedImpostorMaster: good case", waitID) + + // check the new master is really master + tablet, err = ts.GetTablet(ctx, newMaster.Tablet.Alias) + if err != nil { + t.Fatalf("GetTablet(%v) failed: %v", newMaster.Tablet.Alias, err) + } + if tablet.Type != topodatapb.TabletType_MASTER { + t.Fatalf("new master should be MASTER but is: %v", tablet.Type) + } + // check the old master was converted to replica tablet, err = ts.GetTablet(ctx, oldMaster.Tablet.Alias) if err != nil { From 6e1daea4fae2b7b33eb0d39b81804c9260a19529 Mon Sep 17 00:00:00 2001 From: Sugu Sougoumarane Date: Sun, 25 Aug 2019 20:19:48 -0700 Subject: [PATCH 073/425] vreplication: more VReplicationExec constructs Previously, only single row queries were allowed for VReplicationExec. With this change, queries with arbitrary where clauses are supported. Signed-off-by: Sugu Sougoumarane --- .../vreplication/controller_plan.go | 129 +++++++------- .../vreplication/controller_plan_test.go | 162 +++++++++++------- .../vreplication/controller_test.go | 6 +- .../tabletmanager/vreplication/engine.go | 114 +++++++++--- .../tabletmanager/vreplication/engine_test.go | 52 +++++- .../vreplication/vplayer_test.go | 15 +- go/vt/wrangler/migrater_env_test.go | 4 +- go/vt/wrangler/migrater_test.go | 106 ++++++++---- .../testlib/migrate_served_types_test.go | 5 +- 9 files changed, 387 insertions(+), 206 deletions(-) diff --git a/go/vt/vttablet/tabletmanager/vreplication/controller_plan.go b/go/vt/vttablet/tabletmanager/vreplication/controller_plan.go index e3c73415a1f..e1ee1a5734b 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/controller_plan.go +++ b/go/vt/vttablet/tabletmanager/vreplication/controller_plan.go @@ -18,18 +18,24 @@ package vreplication import ( "fmt" - "strconv" "vitess.io/vitess/go/vt/sqlparser" ) // controllerPlan is the plan for vreplication control statements. type controllerPlan struct { - opcode int query string - // delCopySate is set for deletes. - delCopyState string - id int + opcode int + + // numInserts is set for insertQuery. + numInserts int + + // selector and applier are set for updateQuery and deleteQuery. + selector string + applier *sqlparser.ParsedQuery + + // delCopyState is set of deletes. + delCopyState *sqlparser.ParsedQuery } const ( @@ -46,18 +52,24 @@ func buildControllerPlan(query string) (*controllerPlan, error) { if err != nil { return nil, err } + var plan *controllerPlan switch stmt := stmt.(type) { case *sqlparser.Insert: - return buildInsertPlan(stmt) + plan, err = buildInsertPlan(stmt) case *sqlparser.Update: - return buildUpdatePlan(stmt) + plan, err = buildUpdatePlan(stmt) case *sqlparser.Delete: - return buildDeletePlan(stmt) + plan, err = buildDeletePlan(stmt) case *sqlparser.Select: - return buildSelectPlan(stmt) + plan, err = buildSelectPlan(stmt) default: return nil, fmt.Errorf("unsupported construct: %s", sqlparser.String(stmt)) } + if err != nil { + return nil, err + } + plan.query = query + return plan, nil } func buildInsertPlan(ins *sqlparser.Insert) (*controllerPlan, error) { @@ -65,7 +77,6 @@ func buildInsertPlan(ins *sqlparser.Insert) (*controllerPlan, error) { case reshardingJournalTableName: return &controllerPlan{ opcode: reshardingJournalQuery, - query: sqlparser.String(ins), }, nil case vreplicationTableName: // no-op @@ -88,15 +99,8 @@ func buildInsertPlan(ins *sqlparser.Insert) (*controllerPlan, error) { if !ok { return nil, fmt.Errorf("unsupported construct: %v", sqlparser.String(ins)) } - if len(rows) != 1 { - return nil, fmt.Errorf("unsupported construct: %v", sqlparser.String(ins)) - } - row := rows[0] idPos := 0 if len(ins.Columns) != 0 { - if len(ins.Columns) != len(row) { - return nil, fmt.Errorf("malformed statement: %v", sqlparser.String(ins)) - } idPos = -1 for i, col := range ins.Columns { if col.EqualString("id") { @@ -106,13 +110,18 @@ func buildInsertPlan(ins *sqlparser.Insert) (*controllerPlan, error) { } } if idPos >= 0 { - if _, ok := row[idPos].(*sqlparser.NullVal); !ok { - return nil, fmt.Errorf("id should not have a value: %v", sqlparser.String(ins)) + for _, row := range rows { + if idPos >= len(row) { + return nil, fmt.Errorf("malformed statement: %v", sqlparser.String(ins)) + } + if _, ok := row[idPos].(*sqlparser.NullVal); !ok { + return nil, fmt.Errorf("id should not have a value: %v", sqlparser.String(ins)) + } } } return &controllerPlan{ - opcode: insertQuery, - query: sqlparser.String(ins), + opcode: insertQuery, + numInserts: len(rows), }, nil } @@ -121,7 +130,6 @@ func buildUpdatePlan(upd *sqlparser.Update) (*controllerPlan, error) { case reshardingJournalTableName: return &controllerPlan{ opcode: reshardingJournalQuery, - query: sqlparser.String(upd), }, nil case vreplicationTableName: // no-op @@ -137,15 +145,24 @@ func buildUpdatePlan(upd *sqlparser.Update) (*controllerPlan, error) { } } - id, err := extractID(upd.Where) - if err != nil { - return nil, err + buf1 := sqlparser.NewTrackedBuffer(nil) + buf1.Myprintf("select id from %s%v", vreplicationTableName, upd.Where) + upd.Where = &sqlparser.Where{ + Type: sqlparser.WhereStr, + Expr: &sqlparser.ComparisonExpr{ + Left: &sqlparser.ColName{Name: sqlparser.NewColIdent("id")}, + Operator: sqlparser.InStr, + Right: sqlparser.ListArg("::ids"), + }, } + buf2 := sqlparser.NewTrackedBuffer(nil) + buf2.Myprintf("%v", upd) + return &controllerPlan{ - opcode: updateQuery, - query: sqlparser.String(upd), - id: id, + opcode: updateQuery, + selector: buf1.String(), + applier: buf2.ParsedQuery(), }, nil } @@ -154,7 +171,6 @@ func buildDeletePlan(del *sqlparser.Delete) (*controllerPlan, error) { case reshardingJournalTableName: return &controllerPlan{ opcode: reshardingJournalQuery, - query: sqlparser.String(del), }, nil case vreplicationTableName: // no-op @@ -171,16 +187,36 @@ func buildDeletePlan(del *sqlparser.Delete) (*controllerPlan, error) { return nil, fmt.Errorf("unsupported construct: %v", sqlparser.String(del)) } - id, err := extractID(del.Where) - if err != nil { - return nil, err + buf1 := sqlparser.NewTrackedBuffer(nil) + buf1.Myprintf("select id from %s%v", vreplicationTableName, del.Where) + del.Where = &sqlparser.Where{ + Type: sqlparser.WhereStr, + Expr: &sqlparser.ComparisonExpr{ + Left: &sqlparser.ColName{Name: sqlparser.NewColIdent("id")}, + Operator: sqlparser.InStr, + Right: sqlparser.ListArg("::ids"), + }, + } + + buf2 := sqlparser.NewTrackedBuffer(nil) + buf2.Myprintf("%v", del) + + copyStateWhere := &sqlparser.Where{ + Type: sqlparser.WhereStr, + Expr: &sqlparser.ComparisonExpr{ + Left: &sqlparser.ColName{Name: sqlparser.NewColIdent("vrepl_id")}, + Operator: sqlparser.InStr, + Right: sqlparser.ListArg("::ids"), + }, } + buf3 := sqlparser.NewTrackedBuffer(nil) + buf3.Myprintf("delete from %s%v", copySateTableName, copyStateWhere) return &controllerPlan{ opcode: deleteQuery, - query: sqlparser.String(del), - delCopyState: fmt.Sprintf("delete from %s where vrepl_id = %d", copySateTableName, id), - id: id, + selector: buf1.String(), + applier: buf2.ParsedQuery(), + delCopyState: buf3.ParsedQuery(), }, nil } @@ -189,31 +225,8 @@ func buildSelectPlan(sel *sqlparser.Select) (*controllerPlan, error) { case vreplicationTableName, reshardingJournalTableName, copySateTableName: return &controllerPlan{ opcode: selectQuery, - query: sqlparser.String(sel), }, nil default: return nil, fmt.Errorf("invalid table name: %v", sqlparser.String(sel.From)) } } - -func extractID(where *sqlparser.Where) (int, error) { - if where == nil { - return 0, fmt.Errorf("invalid where clause:%v", sqlparser.String(where)) - } - comp, ok := where.Expr.(*sqlparser.ComparisonExpr) - if !ok { - return 0, fmt.Errorf("invalid where clause:%v", sqlparser.String(where)) - } - if sqlparser.String(comp.Left) != "id" { - return 0, fmt.Errorf("invalid where clause:%v", sqlparser.String(where)) - } - if comp.Operator != sqlparser.EqualStr { - return 0, fmt.Errorf("invalid where clause:%v", sqlparser.String(where)) - } - - id, err := strconv.Atoi(sqlparser.String(comp.Right)) - if err != nil { - return 0, fmt.Errorf("invalid where clause:%v", sqlparser.String(where)) - } - return id, nil -} diff --git a/go/vt/vttablet/tabletmanager/vreplication/controller_plan_test.go b/go/vt/vttablet/tabletmanager/vreplication/controller_plan_test.go index ecdb32e6483..096dbb1593f 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/controller_plan_test.go +++ b/go/vt/vttablet/tabletmanager/vreplication/controller_plan_test.go @@ -21,35 +21,54 @@ import ( "testing" ) +type testControllerPlan struct { + query string + opcode int + numInserts int + selector string + applier string + delCopyState string +} + func TestControllerPlan(t *testing.T) { tcases := []struct { in string - plan *controllerPlan + plan *testControllerPlan err string }{{ // Insert in: "insert into _vt.vreplication values(null)", - plan: &controllerPlan{ - opcode: insertQuery, - query: "insert into _vt.vreplication values (null)", + plan: &testControllerPlan{ + query: "insert into _vt.vreplication values(null)", + opcode: insertQuery, + numInserts: 1, }, }, { in: "insert into _vt.vreplication(id) values(null)", - plan: &controllerPlan{ - opcode: insertQuery, - query: "insert into _vt.vreplication(id) values (null)", + plan: &testControllerPlan{ + query: "insert into _vt.vreplication(id) values(null)", + opcode: insertQuery, + numInserts: 1, }, }, { in: "insert into _vt.vreplication(workflow, id) values('', null)", - plan: &controllerPlan{ - opcode: insertQuery, - query: "insert into _vt.vreplication(workflow, id) values ('', null)", + plan: &testControllerPlan{ + query: "insert into _vt.vreplication(workflow, id) values('', null)", + opcode: insertQuery, + numInserts: 1, + }, + }, { + in: "insert into _vt.vreplication values(null), (null)", + plan: &testControllerPlan{ + query: "insert into _vt.vreplication values(null), (null)", + opcode: insertQuery, + numInserts: 2, }, }, { in: "insert into _vt.resharding_journal values (1)", - plan: &controllerPlan{ - opcode: reshardingJournalQuery, + plan: &testControllerPlan{ query: "insert into _vt.resharding_journal values (1)", + opcode: reshardingJournalQuery, }, }, { in: "replace into _vt.vreplication values(null)", @@ -70,11 +89,8 @@ func TestControllerPlan(t *testing.T) { in: "insert into _vt.vreplication select * from a", err: "unsupported construct: insert into _vt.vreplication select * from a", }, { - in: "insert into _vt.vreplication values(null), (null)", - err: "unsupported construct: insert into _vt.vreplication values (null), (null)", - }, { - in: "insert into _vt.vreplication(a, b, c) values(null)", - err: "malformed statement: insert into _vt.vreplication(a, b, c) values (null)", + in: "insert into _vt.vreplication(a, b, id) values(null)", + err: "malformed statement: insert into _vt.vreplication(a, b, id) values (null)", }, { in: "insert into _vt.vreplication(workflow, id) values('aa', 1)", err: "id should not have a value: insert into _vt.vreplication(workflow, id) values ('aa', 1)", @@ -85,16 +101,33 @@ func TestControllerPlan(t *testing.T) { // Update }, { in: "update _vt.vreplication set state='Running' where id = 1", - plan: &controllerPlan{ - opcode: updateQuery, - query: "update _vt.vreplication set state = 'Running' where id = 1", - id: 1, + plan: &testControllerPlan{ + query: "update _vt.vreplication set state='Running' where id = 1", + opcode: updateQuery, + selector: "select id from _vt.vreplication where id = 1", + applier: "update _vt.vreplication set state = 'Running' where id in ::ids", + }, + }, { + in: "update _vt.vreplication set state='Running'", + plan: &testControllerPlan{ + query: "update _vt.vreplication set state='Running'", + opcode: updateQuery, + selector: "select id from _vt.vreplication", + applier: "update _vt.vreplication set state = 'Running' where id in ::ids", + }, + }, { + in: "update _vt.vreplication set state='Running' where a = 1", + plan: &testControllerPlan{ + query: "update _vt.vreplication set state='Running' where a = 1", + opcode: updateQuery, + selector: "select id from _vt.vreplication where a = 1", + applier: "update _vt.vreplication set state = 'Running' where id in ::ids", }, }, { in: "update _vt.resharding_journal set col = 1", - plan: &controllerPlan{ - opcode: reshardingJournalQuery, + plan: &testControllerPlan{ query: "update _vt.resharding_journal set col = 1", + opcode: reshardingJournalQuery, }, }, { in: "update a set state='Running' where id = 1", @@ -108,36 +141,40 @@ func TestControllerPlan(t *testing.T) { }, { in: "update _vt.vreplication set state='Running', id = 2 where id = 1", err: "id cannot be changed: id = 2", - }, { - in: "update _vt.vreplication set state='Running'", - err: "invalid where clause:", - }, { - in: "update _vt.vreplication set state='Running' where a = 1 and id = 2", - err: "invalid where clause: where a = 1 and id = 2", - }, { - in: "update _vt.vreplication set state='Running' where a = 1", - err: "invalid where clause: where a = 1", - }, { - in: "update _vt.vreplication set state='Running' where id > 1", - err: "invalid where clause: where id > 1", - }, { - in: "update _vt.vreplication set state='Running' where id = 1.1", - err: "invalid where clause: where id = 1.1", // Delete }, { in: "delete from _vt.vreplication where id = 1", - plan: &controllerPlan{ - opcode: deleteQuery, + plan: &testControllerPlan{ query: "delete from _vt.vreplication where id = 1", - delCopyState: "delete from _vt.copy_state where vrepl_id = 1", - id: 1, + opcode: deleteQuery, + selector: "select id from _vt.vreplication where id = 1", + applier: "delete from _vt.vreplication where id in ::ids", + delCopyState: "delete from _vt.copy_state where vrepl_id in ::ids", + }, + }, { + in: "delete from _vt.vreplication", + plan: &testControllerPlan{ + query: "delete from _vt.vreplication", + opcode: deleteQuery, + selector: "select id from _vt.vreplication", + applier: "delete from _vt.vreplication where id in ::ids", + delCopyState: "delete from _vt.copy_state where vrepl_id in ::ids", + }, + }, { + in: "delete from _vt.vreplication where a = 1", + plan: &testControllerPlan{ + query: "delete from _vt.vreplication where a = 1", + opcode: deleteQuery, + selector: "select id from _vt.vreplication where a = 1", + applier: "delete from _vt.vreplication where id in ::ids", + delCopyState: "delete from _vt.copy_state where vrepl_id in ::ids", }, }, { in: "delete from _vt.resharding_journal where id = 1", - plan: &controllerPlan{ - opcode: reshardingJournalQuery, + plan: &testControllerPlan{ query: "delete from _vt.resharding_journal where id = 1", + opcode: reshardingJournalQuery, }, }, { in: "delete from a where id = 1", @@ -154,38 +191,23 @@ func TestControllerPlan(t *testing.T) { }, { in: "delete from _vt.vreplication partition (a) where id = 1 limit 1", err: "unsupported construct: delete from _vt.vreplication partition (a) where id = 1 limit 1", - }, { - in: "delete from _vt.vreplication", - err: "invalid where clause:", - }, { - in: "delete from _vt.vreplication where a = 1 and id = 2", - err: "invalid where clause: where a = 1 and id = 2", - }, { - in: "delete from _vt.vreplication where a = 1", - err: "invalid where clause: where a = 1", - }, { - in: "delete from _vt.vreplication where id > 1", - err: "invalid where clause: where id > 1", - }, { - in: "delete from _vt.vreplication where id = 1.1", - err: "invalid where clause: where id = 1.1", // Select }, { in: "select * from _vt.vreplication", - plan: &controllerPlan{ + plan: &testControllerPlan{ opcode: selectQuery, query: "select * from _vt.vreplication", }, }, { in: "select * from _vt.resharding_journal", - plan: &controllerPlan{ + plan: &testControllerPlan{ opcode: selectQuery, query: "select * from _vt.resharding_journal", }, }, { in: "select * from _vt.copy_state", - plan: &controllerPlan{ + plan: &testControllerPlan{ opcode: selectQuery, query: "select * from _vt.copy_state", }, @@ -213,8 +235,20 @@ func TestControllerPlan(t *testing.T) { t.Errorf("getPlan(%v) error:\n%v, want\n%v", tcase.in, err, tcase.err) continue } - if !reflect.DeepEqual(pl, tcase.plan) { - t.Errorf("getPlan(%v):\n%+v, want\n%+v", tcase.in, pl, tcase.plan) + gotPlan := &testControllerPlan{ + query: pl.query, + opcode: pl.opcode, + numInserts: pl.numInserts, + selector: pl.selector, + } + if pl.applier != nil { + gotPlan.applier = pl.applier.Query + } + if pl.delCopyState != nil { + gotPlan.delCopyState = pl.delCopyState.Query + } + if !reflect.DeepEqual(gotPlan, tcase.plan) { + t.Errorf("getPlan(%v):\n%+v, want\n%+v", tcase.in, gotPlan, tcase.plan) } } } diff --git a/go/vt/vttablet/tabletmanager/vreplication/controller_test.go b/go/vt/vttablet/tabletmanager/vreplication/controller_test.go index ba858cf04d3..f330985c4c9 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/controller_test.go +++ b/go/vt/vttablet/tabletmanager/vreplication/controller_test.go @@ -48,8 +48,10 @@ var ( }, }, } - testDMLResponse = &sqltypes.Result{RowsAffected: 1} - testPos = "MariaDB/0-1-1083" + testSelectorResponse1 = &sqltypes.Result{Rows: [][]sqltypes.Value{{sqltypes.NewInt64(1)}}} + testSelectorResponse2 = &sqltypes.Result{Rows: [][]sqltypes.Value{{sqltypes.NewInt64(1)}, {sqltypes.NewInt64(2)}}} + testDMLResponse = &sqltypes.Result{RowsAffected: 1} + testPos = "MariaDB/0-1-1083" ) func TestControllerKeyRange(t *testing.T) { diff --git a/go/vt/vttablet/tabletmanager/vreplication/engine.go b/go/vt/vttablet/tabletmanager/vreplication/engine.go index 9a08a974696..db08a0f07c3 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/engine.go +++ b/go/vt/vttablet/tabletmanager/vreplication/engine.go @@ -29,6 +29,7 @@ import ( "vitess.io/vitess/go/vt/binlog/binlogplayer" "vitess.io/vitess/go/vt/log" "vitess.io/vitess/go/vt/mysqlctl" + querypb "vitess.io/vitess/go/vt/proto/query" "vitess.io/vitess/go/vt/topo" ) @@ -269,54 +270,92 @@ func (vre *Engine) Exec(query string) (*sqltypes.Result, error) { if qr.InsertID == 0 { return nil, fmt.Errorf("insert failed to generate an id") } - params, err := readRow(dbClient, int(qr.InsertID)) - if err != nil { - return nil, err - } - // Create a controller for the newly created row. - ct, err := newController(vre.ctx, params, vre.dbClientFactory, vre.mysqld, vre.ts, vre.cell, *tabletTypesStr, nil) - if err != nil { - return nil, err + for id := int(qr.InsertID); id < int(qr.InsertID)+plan.numInserts; id++ { + if ct := vre.controllers[id]; ct != nil { + // Unreachable. Just a failsafe. + ct.Stop() + delete(vre.controllers, id) + } + params, err := readRow(dbClient, id) + if err != nil { + return nil, err + } + ct, err := newController(vre.ctx, params, vre.dbClientFactory, vre.mysqld, vre.ts, vre.cell, *tabletTypesStr, nil) + if err != nil { + return nil, err + } + vre.controllers[id] = ct } - vre.controllers[int(qr.InsertID)] = ct return qr, nil case updateQuery: - var blpStats *binlogplayer.Stats - if ct := vre.controllers[plan.id]; ct != nil { - // Stop the current controller. - ct.Stop() - blpStats = ct.blpStats - } - qr, err := vre.executeFetchMaybeCreateTable(dbClient, plan.query, 1) + ids, bv, err := vre.fetchIDs(dbClient, plan.selector) if err != nil { return nil, err } - params, err := readRow(dbClient, plan.id) + if len(ids) == 0 { + return &sqltypes.Result{}, nil + } + blpStats := make(map[int]*binlogplayer.Stats) + for _, id := range ids { + if ct := vre.controllers[id]; ct != nil { + // Stop the current controller. + ct.Stop() + blpStats[id] = ct.blpStats + } + } + query, err := plan.applier.GenerateQuery(bv, nil) if err != nil { return nil, err } - // Create a new controller in place of the old one. - // For continuity, the new controller inherits the previous stats. - ct, err := newController(vre.ctx, params, vre.dbClientFactory, vre.mysqld, vre.ts, vre.cell, *tabletTypesStr, blpStats) + qr, err := vre.executeFetchMaybeCreateTable(dbClient, query, 1) if err != nil { return nil, err } - vre.controllers[plan.id] = ct + for _, id := range ids { + params, err := readRow(dbClient, id) + if err != nil { + return nil, err + } + // Create a new controller in place of the old one. + // For continuity, the new controller inherits the previous stats. + ct, err := newController(vre.ctx, params, vre.dbClientFactory, vre.mysqld, vre.ts, vre.cell, *tabletTypesStr, blpStats[id]) + if err != nil { + return nil, err + } + vre.controllers[id] = ct + } return qr, nil case deleteQuery: - // Stop and delete the current controller. - if ct := vre.controllers[plan.id]; ct != nil { - ct.Stop() - delete(vre.controllers, plan.id) + ids, bv, err := vre.fetchIDs(dbClient, plan.selector) + if err != nil { + return nil, err + } + if len(ids) == 0 { + return &sqltypes.Result{}, nil + } + // Stop and delete the current controllers. + for _, id := range ids { + if ct := vre.controllers[id]; ct != nil { + ct.Stop() + delete(vre.controllers, id) + } } if err := dbClient.Begin(); err != nil { return nil, err } - qr, err := dbClient.ExecuteFetch(plan.query, 10000) + query, err := plan.applier.GenerateQuery(bv, nil) + if err != nil { + return nil, err + } + qr, err := vre.executeFetchMaybeCreateTable(dbClient, query, 1) + if err != nil { + return nil, err + } + delQuery, err := plan.delCopyState.GenerateQuery(bv, nil) if err != nil { return nil, err } - if _, err := dbClient.ExecuteFetch(plan.delCopyState, 10000); err != nil { + if _, err := dbClient.ExecuteFetch(delQuery, 10000); err != nil { // Legacy vreplication won't create this table. So, ignore table not found error. merr, isSQLErr := err.(*mysql.SQLError) if !isSQLErr || !(merr.Num == mysql.ERNoSuchTable) { @@ -334,6 +373,27 @@ func (vre *Engine) Exec(query string) (*sqltypes.Result, error) { panic("unreachable") } +func (vre *Engine) fetchIDs(dbClient binlogplayer.DBClient, selector string) (ids []int, bv map[string]*querypb.BindVariable, err error) { + qr, err := dbClient.ExecuteFetch(selector, 10000) + if err != nil { + return nil, nil, err + } + for _, row := range qr.Rows { + id, err := sqltypes.ToInt64(row[0]) + if err != nil { + return nil, nil, err + } + ids = append(ids, int(id)) + } + bvval, err := sqltypes.BuildBindVariable(ids) + if err != nil { + // Unreachable. + return nil, nil, err + } + bv = map[string]*querypb.BindVariable{"ids": bvval} + return ids, bv, nil +} + // WaitForPos waits for the replication to reach the specified position. func (vre *Engine) WaitForPos(ctx context.Context, id int, pos string) error { mPos, err := mysql.DecodePosition(pos) diff --git a/go/vt/vttablet/tabletmanager/vreplication/engine_test.go b/go/vt/vttablet/tabletmanager/vreplication/engine_test.go index 27f2d31d676..d16ca35cc4b 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/engine_test.go +++ b/go/vt/vttablet/tabletmanager/vreplication/engine_test.go @@ -98,7 +98,7 @@ func TestEngineExec(t *testing.T) { defer vre.Close() dbClient.ExpectRequest("use _vt", &sqltypes.Result{}, nil) - dbClient.ExpectRequest("insert into _vt.vreplication values (null)", &sqltypes.Result{InsertID: 1}, nil) + dbClient.ExpectRequest("insert into _vt.vreplication values(null)", &sqltypes.Result{InsertID: 1}, nil) dbClient.ExpectRequest("select * from _vt.vreplication where id = 1", sqltypes.MakeTestResult( sqltypes.MakeTestFields( "id|state|source", @@ -138,7 +138,8 @@ func TestEngineExec(t *testing.T) { savedBlp := ct.blpStats dbClient.ExpectRequest("use _vt", &sqltypes.Result{}, nil) - dbClient.ExpectRequest("update _vt.vreplication set pos = 'MariaDB/0-1-1084', state = 'Running' where id = 1", testDMLResponse, nil) + dbClient.ExpectRequest("select id from _vt.vreplication where id = 1", testSelectorResponse1, nil) + dbClient.ExpectRequest("update _vt.vreplication set pos = 'MariaDB/0-1-1084', state = 'Running' where id in (1)", testDMLResponse, nil) dbClient.ExpectRequest("select * from _vt.vreplication where id = 1", sqltypes.MakeTestResult( sqltypes.MakeTestFields( "id|state|source", @@ -175,16 +176,25 @@ func TestEngineExec(t *testing.T) { t.Errorf("stats are mismatched: %v, want %v", globalStats.controllers, vre.controllers) } + // Test no update + dbClient.ExpectRequest("use _vt", &sqltypes.Result{}, nil) + dbClient.ExpectRequest("select id from _vt.vreplication where id = 2", &sqltypes.Result{}, nil) + _, err = vre.Exec("update _vt.vreplication set pos = 'MariaDB/0-1-1084', state = 'Running' where id = 2") + if err != nil { + t.Fatal(err) + } + dbClient.Wait() + // Test Delete dbClient.ExpectRequest("use _vt", &sqltypes.Result{}, nil) - delQuery := "delete from _vt.vreplication where id = 1" + dbClient.ExpectRequest("select id from _vt.vreplication where id = 1", testSelectorResponse1, nil) dbClient.ExpectRequest("begin", nil, nil) - dbClient.ExpectRequest(delQuery, testDMLResponse, nil) - dbClient.ExpectRequest("delete from _vt.copy_state where vrepl_id = 1", nil, nil) + dbClient.ExpectRequest("delete from _vt.vreplication where id in (1)", testDMLResponse, nil) + dbClient.ExpectRequest("delete from _vt.copy_state where vrepl_id in (1)", nil, nil) dbClient.ExpectRequest("commit", nil, nil) - qr, err = vre.Exec(delQuery) + qr, err = vre.Exec("delete from _vt.vreplication where id = 1") if err != nil { t.Fatal(err) } @@ -203,6 +213,30 @@ func TestEngineExec(t *testing.T) { if !reflect.DeepEqual(globalStats.controllers, vre.controllers) { t.Errorf("stats are mismatched: %v, want %v", globalStats.controllers, vre.controllers) } + + // Test Delete of multiple rows + + dbClient.ExpectRequest("use _vt", &sqltypes.Result{}, nil) + dbClient.ExpectRequest("select id from _vt.vreplication where id > 1", testSelectorResponse2, nil) + dbClient.ExpectRequest("begin", nil, nil) + dbClient.ExpectRequest("delete from _vt.vreplication where id in (1, 2)", testDMLResponse, nil) + dbClient.ExpectRequest("delete from _vt.copy_state where vrepl_id in (1, 2)", nil, nil) + dbClient.ExpectRequest("commit", nil, nil) + + _, err = vre.Exec("delete from _vt.vreplication where id > 1") + if err != nil { + t.Fatal(err) + } + dbClient.Wait() + + // Test no delete + dbClient.ExpectRequest("use _vt", &sqltypes.Result{}, nil) + dbClient.ExpectRequest("select id from _vt.vreplication where id = 3", &sqltypes.Result{}, nil) + _, err = vre.Exec("delete from _vt.vreplication where id = 3") + if err != nil { + t.Fatal(err) + } + dbClient.Wait() } func TestEngineBadInsert(t *testing.T) { @@ -224,7 +258,7 @@ func TestEngineBadInsert(t *testing.T) { defer vre.Close() dbClient.ExpectRequest("use _vt", &sqltypes.Result{}, nil) - dbClient.ExpectRequest("insert into _vt.vreplication values (null)", &sqltypes.Result{}, nil) + dbClient.ExpectRequest("insert into _vt.vreplication values(null)", &sqltypes.Result{}, nil) _, err := vre.Exec("insert into _vt.vreplication values(null)") want := "insert failed to generate an id" if err == nil || err.Error() != want { @@ -424,14 +458,14 @@ func TestCreateDBAndTable(t *testing.T) { // Missing table. Statement should get retried after creating everything. dbClient.ExpectRequest("use _vt", &sqltypes.Result{}, nil) - dbClient.ExpectRequest("insert into _vt.vreplication values (null)", &sqltypes.Result{}, &tableNotFound) + dbClient.ExpectRequest("insert into _vt.vreplication values(null)", &sqltypes.Result{}, &tableNotFound) dbClient.ExpectRequest("CREATE DATABASE IF NOT EXISTS _vt", &sqltypes.Result{}, nil) dbClient.ExpectRequest("DROP TABLE IF EXISTS _vt.blp_checkpoint", &sqltypes.Result{}, nil) dbClient.ExpectRequestRE("CREATE TABLE IF NOT EXISTS _vt.vreplication.*", &sqltypes.Result{}, nil) dbClient.ExpectRequestRE("create table if not exists _vt.resharding_journal.*", &sqltypes.Result{}, nil) - dbClient.ExpectRequest("insert into _vt.vreplication values (null)", &sqltypes.Result{InsertID: 1}, nil) + dbClient.ExpectRequest("insert into _vt.vreplication values(null)", &sqltypes.Result{InsertID: 1}, nil) // The rest of this test is normal with no db errors or extra queries. diff --git a/go/vt/vttablet/tabletmanager/vreplication/vplayer_test.go b/go/vt/vttablet/tabletmanager/vreplication/vplayer_test.go index e2c0e80c9b1..110e5bc8775 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/vplayer_test.go +++ b/go/vt/vttablet/tabletmanager/vreplication/vplayer_test.go @@ -20,6 +20,7 @@ import ( "flag" "fmt" "strings" + "sync" "testing" "time" @@ -1532,13 +1533,17 @@ func startVReplication(t *testing.T, filter *binlogdatapb.Filter, onddl binlogda "/insert into _vt.vreplication", "/update _vt.vreplication set state='Running'", }) + + var once sync.Once return func() { t.Helper() - query := fmt.Sprintf("delete from _vt.vreplication where id = %d", qr.InsertID) - if _, err := playerEngine.Exec(query); err != nil { - t.Fatal(err) - } - expectDeleteQueries(t) + once.Do(func() { + query := fmt.Sprintf("delete from _vt.vreplication where id = %d", qr.InsertID) + if _, err := playerEngine.Exec(query); err != nil { + t.Fatal(err) + } + expectDeleteQueries(t) + }) }, int(qr.InsertID) } diff --git a/go/vt/wrangler/migrater_env_test.go b/go/vt/wrangler/migrater_env_test.go index 5384591ba48..1f9dd8ddf13 100644 --- a/go/vt/wrangler/migrater_env_test.go +++ b/go/vt/wrangler/migrater_env_test.go @@ -35,8 +35,8 @@ import ( "vitess.io/vitess/go/vt/vttablet/tmclient" ) -const vreplQueryks = "select id, source from _vt.vreplication where workflow = 'test' and db_name = 'vt_ks'" -const vreplQueryks2 = "select id, source from _vt.vreplication where workflow = 'test' and db_name = 'vt_ks2'" +const vreplQueryks = "select id, source from _vt.vreplication where workflow='test' and db_name='vt_ks'" +const vreplQueryks2 = "select id, source from _vt.vreplication where workflow='test' and db_name='vt_ks2'" type testMigraterEnv struct { ts *topo.Server diff --git a/go/vt/wrangler/migrater_test.go b/go/vt/wrangler/migrater_test.go index 2895ed6b46a..a4983f0df86 100644 --- a/go/vt/wrangler/migrater_test.go +++ b/go/vt/wrangler/migrater_test.go @@ -31,6 +31,11 @@ import ( "vitess.io/vitess/go/vt/topo" ) +var ( + resultid1 = &sqltypes.Result{Rows: [][]sqltypes.Value{{sqltypes.NewInt64(1)}}} + resultid2 = &sqltypes.Result{Rows: [][]sqltypes.Value{{sqltypes.NewInt64(2)}}} +) + // TestTableMigrate tests table mode migrations. // This has to be kept in sync with TestShardMigrate. func TestTableMigrate(t *testing.T) { @@ -243,8 +248,8 @@ func TestTableMigrate(t *testing.T) { }) // Check for journals. - tme.dbSource1Client.addQuery("select 1 from _vt.resharding_journal where id = 9113431017721636330", &sqltypes.Result{}, nil) - tme.dbSource2Client.addQuery("select 1 from _vt.resharding_journal where id = 9113431017721636330", &sqltypes.Result{}, nil) + tme.dbSource1Client.addQuery("select 1 from _vt.resharding_journal where id=9113431017721636330", &sqltypes.Result{}, nil) + tme.dbSource2Client.addQuery("select 1 from _vt.resharding_journal where id=9113431017721636330", &sqltypes.Result{}, nil) // Wait for position: Reads current state, updates to Stopped, and re-reads. state := sqltypes.MakeTestResult(sqltypes.MakeTestFields( @@ -255,9 +260,12 @@ func TestTableMigrate(t *testing.T) { tme.dbDest1Client.addQuery("select pos, state, message from _vt.vreplication where id=1", state, nil) tme.dbDest2Client.addQuery("select pos, state, message from _vt.vreplication where id=1", state, nil) tme.dbDest1Client.addQuery("select pos, state, message from _vt.vreplication where id=2", state, nil) - tme.dbDest1Client.addQuery("update _vt.vreplication set state = 'Stopped', message = 'stopped for cutover' where id = 1", &sqltypes.Result{}, nil) - tme.dbDest2Client.addQuery("update _vt.vreplication set state = 'Stopped', message = 'stopped for cutover' where id = 1", &sqltypes.Result{}, nil) - tme.dbDest1Client.addQuery("update _vt.vreplication set state = 'Stopped', message = 'stopped for cutover' where id = 2", &sqltypes.Result{}, nil) + tme.dbDest1Client.addQuery("select id from _vt.vreplication where id = 1", resultid1, nil) + tme.dbDest1Client.addQuery("update _vt.vreplication set state = 'Stopped', message = 'stopped for cutover' where id in (1)", &sqltypes.Result{}, nil) + tme.dbDest1Client.addQuery("select id from _vt.vreplication where id = 2", resultid2, nil) + tme.dbDest1Client.addQuery("update _vt.vreplication set state = 'Stopped', message = 'stopped for cutover' where id in (2)", &sqltypes.Result{}, nil) + tme.dbDest2Client.addQuery("select id from _vt.vreplication where id = 1", resultid1, nil) + tme.dbDest2Client.addQuery("update _vt.vreplication set state = 'Stopped', message = 'stopped for cutover' where id in (1)", &sqltypes.Result{}, nil) stopped := sqltypes.MakeTestResult(sqltypes.MakeTestFields( "id|state", "int64|varchar"), @@ -268,8 +276,8 @@ func TestTableMigrate(t *testing.T) { tme.dbDest1Client.addQuery("select * from _vt.vreplication where id = 2", stopped, nil) // Cancel Migration - cancel1 := "update _vt.vreplication set state = 'Running', stop_pos = null where id = 1" - cancel2 := "update _vt.vreplication set state = 'Running', stop_pos = null where id = 2" + cancel1 := "update _vt.vreplication set state = 'Running', stop_pos = null where id in (1)" + cancel2 := "update _vt.vreplication set state = 'Running', stop_pos = null where id in (2)" tme.dbDest1Client.addQuery(cancel1, &sqltypes.Result{}, nil) tme.dbDest2Client.addQuery(cancel1, &sqltypes.Result{}, nil) tme.dbDest1Client.addQuery(cancel2, &sqltypes.Result{}, nil) @@ -320,9 +328,12 @@ func TestTableMigrate(t *testing.T) { tme.dbSource2Client.addQuery("select * from _vt.vreplication where id = 2", stopped, nil) // Delete the target replications. - tme.dbDest1Client.addQuery("delete from _vt.vreplication where id = 1", &sqltypes.Result{}, nil) - tme.dbDest2Client.addQuery("delete from _vt.vreplication where id = 1", &sqltypes.Result{}, nil) - tme.dbDest1Client.addQuery("delete from _vt.vreplication where id = 2", &sqltypes.Result{}, nil) + tme.dbDest1Client.addQuery("delete from _vt.vreplication where id in (1)", &sqltypes.Result{}, nil) + tme.dbDest1Client.addQuery("delete from _vt.copy_state where vrepl_id in (1)", &sqltypes.Result{}, nil) + tme.dbDest2Client.addQuery("delete from _vt.vreplication where id in (1)", &sqltypes.Result{}, nil) + tme.dbDest2Client.addQuery("delete from _vt.copy_state where vrepl_id in (1)", &sqltypes.Result{}, nil) + tme.dbDest1Client.addQuery("delete from _vt.vreplication where id in (2)", &sqltypes.Result{}, nil) + tme.dbDest1Client.addQuery("delete from _vt.copy_state where vrepl_id in (2)", &sqltypes.Result{}, nil) journalID, err := tme.wr.MigrateWrites(ctx, tme.targetKeyspace, "test", 1*time.Second) if err != nil { @@ -482,8 +493,8 @@ func TestShardMigrate(t *testing.T) { checkIsMasterServing(t, tme.ts, "ks:80-", false) // Check for journals. - tme.dbSource1Client.addQuery("select 1 from _vt.resharding_journal where id = 6432976123657117098", &sqltypes.Result{}, nil) - tme.dbSource2Client.addQuery("select 1 from _vt.resharding_journal where id = 6432976123657117098", &sqltypes.Result{}, nil) + tme.dbSource1Client.addQuery("select 1 from _vt.resharding_journal where id=6432976123657117098", &sqltypes.Result{}, nil) + tme.dbSource2Client.addQuery("select 1 from _vt.resharding_journal where id=6432976123657117098", &sqltypes.Result{}, nil) // Wait for position: Reads current state, updates to Stopped, and re-reads. state := sqltypes.MakeTestResult(sqltypes.MakeTestFields( @@ -494,9 +505,12 @@ func TestShardMigrate(t *testing.T) { tme.dbDest1Client.addQuery("select pos, state, message from _vt.vreplication where id=1", state, nil) tme.dbDest2Client.addQuery("select pos, state, message from _vt.vreplication where id=1", state, nil) tme.dbDest1Client.addQuery("select pos, state, message from _vt.vreplication where id=2", state, nil) - tme.dbDest1Client.addQuery("update _vt.vreplication set state = 'Stopped', message = 'stopped for cutover' where id = 1", &sqltypes.Result{}, nil) - tme.dbDest2Client.addQuery("update _vt.vreplication set state = 'Stopped', message = 'stopped for cutover' where id = 1", &sqltypes.Result{}, nil) - tme.dbDest1Client.addQuery("update _vt.vreplication set state = 'Stopped', message = 'stopped for cutover' where id = 2", &sqltypes.Result{}, nil) + tme.dbDest1Client.addQuery("select id from _vt.vreplication where id = 1", resultid1, nil) + tme.dbDest1Client.addQuery("update _vt.vreplication set state = 'Stopped', message = 'stopped for cutover' where id in (1)", &sqltypes.Result{}, nil) + tme.dbDest1Client.addQuery("select id from _vt.vreplication where id = 2", resultid2, nil) + tme.dbDest1Client.addQuery("update _vt.vreplication set state = 'Stopped', message = 'stopped for cutover' where id in (2)", &sqltypes.Result{}, nil) + tme.dbDest2Client.addQuery("select id from _vt.vreplication where id = 1", resultid1, nil) + tme.dbDest2Client.addQuery("update _vt.vreplication set state = 'Stopped', message = 'stopped for cutover' where id in (1)", &sqltypes.Result{}, nil) stopped := sqltypes.MakeTestResult(sqltypes.MakeTestFields( "id|state", "int64|varchar"), @@ -507,8 +521,8 @@ func TestShardMigrate(t *testing.T) { tme.dbDest1Client.addQuery("select * from _vt.vreplication where id = 2", stopped, nil) // Cancel Migration - cancel1 := "update _vt.vreplication set state = 'Running', stop_pos = null where id = 1" - cancel2 := "update _vt.vreplication set state = 'Running', stop_pos = null where id = 2" + cancel1 := "update _vt.vreplication set state = 'Running', stop_pos = null where id in (1)" + cancel2 := "update _vt.vreplication set state = 'Running', stop_pos = null where id in (2)" tme.dbDest1Client.addQuery(cancel1, &sqltypes.Result{}, nil) tme.dbDest2Client.addQuery(cancel1, &sqltypes.Result{}, nil) tme.dbDest1Client.addQuery(cancel2, &sqltypes.Result{}, nil) @@ -545,9 +559,12 @@ func TestShardMigrate(t *testing.T) { tme.dbSource2Client.addQuery("select * from _vt.vreplication where id = 2", stopped, nil) // Delete the target replications. - tme.dbDest1Client.addQuery("delete from _vt.vreplication where id = 1", &sqltypes.Result{}, nil) - tme.dbDest2Client.addQuery("delete from _vt.vreplication where id = 1", &sqltypes.Result{}, nil) - tme.dbDest1Client.addQuery("delete from _vt.vreplication where id = 2", &sqltypes.Result{}, nil) + tme.dbDest1Client.addQuery("delete from _vt.vreplication where id in (1)", &sqltypes.Result{}, nil) + tme.dbDest1Client.addQuery("delete from _vt.copy_state where vrepl_id in (1)", &sqltypes.Result{}, nil) + tme.dbDest2Client.addQuery("delete from _vt.vreplication where id in (1)", &sqltypes.Result{}, nil) + tme.dbDest2Client.addQuery("delete from _vt.copy_state where vrepl_id in (1)", &sqltypes.Result{}, nil) + tme.dbDest1Client.addQuery("delete from _vt.vreplication where id in (2)", &sqltypes.Result{}, nil) + tme.dbDest1Client.addQuery("delete from _vt.copy_state where vrepl_id in (2)", &sqltypes.Result{}, nil) journalID, err := tme.wr.MigrateWrites(ctx, tme.targetKeyspace, "test", 1*time.Second) if err != nil { @@ -587,8 +604,8 @@ func TestMigrateFailJournal(t *testing.T) { } // Check for journals. - tme.dbSource1Client.addQuery("select 1 from _vt.resharding_journal where id = 9113431017721636330", &sqltypes.Result{}, nil) - tme.dbSource2Client.addQuery("select 1 from _vt.resharding_journal where id = 9113431017721636330", &sqltypes.Result{}, nil) + tme.dbSource1Client.addQuery("select 1 from _vt.resharding_journal where id=9113431017721636330", &sqltypes.Result{}, nil) + tme.dbSource2Client.addQuery("select 1 from _vt.resharding_journal where id=9113431017721636330", &sqltypes.Result{}, nil) // Wait for position: Reads current state, updates to Stopped, and re-reads. state := sqltypes.MakeTestResult(sqltypes.MakeTestFields( @@ -599,9 +616,12 @@ func TestMigrateFailJournal(t *testing.T) { tme.dbDest1Client.addQuery("select pos, state, message from _vt.vreplication where id=1", state, nil) tme.dbDest2Client.addQuery("select pos, state, message from _vt.vreplication where id=1", state, nil) tme.dbDest1Client.addQuery("select pos, state, message from _vt.vreplication where id=2", state, nil) - tme.dbDest1Client.addQuery("update _vt.vreplication set state = 'Stopped', message = 'stopped for cutover' where id = 1", &sqltypes.Result{}, nil) - tme.dbDest2Client.addQuery("update _vt.vreplication set state = 'Stopped', message = 'stopped for cutover' where id = 1", &sqltypes.Result{}, nil) - tme.dbDest1Client.addQuery("update _vt.vreplication set state = 'Stopped', message = 'stopped for cutover' where id = 2", &sqltypes.Result{}, nil) + tme.dbDest1Client.addQuery("select id from _vt.vreplication where id = 1", resultid1, nil) + tme.dbDest1Client.addQuery("update _vt.vreplication set state = 'Stopped', message = 'stopped for cutover' where id in (1)", &sqltypes.Result{}, nil) + tme.dbDest1Client.addQuery("select id from _vt.vreplication where id = 2", resultid2, nil) + tme.dbDest1Client.addQuery("update _vt.vreplication set state = 'Stopped', message = 'stopped for cutover' where id in (2)", &sqltypes.Result{}, nil) + tme.dbDest2Client.addQuery("select id from _vt.vreplication where id = 1", resultid1, nil) + tme.dbDest2Client.addQuery("update _vt.vreplication set state = 'Stopped', message = 'stopped for cutover' where id in (1)", &sqltypes.Result{}, nil) stopped := sqltypes.MakeTestResult(sqltypes.MakeTestFields( "id|state", "int64|varchar"), @@ -612,8 +632,8 @@ func TestMigrateFailJournal(t *testing.T) { tme.dbDest1Client.addQuery("select * from _vt.vreplication where id = 2", stopped, nil) // Cancel Migration: these must not get called. - cancel1 := "update _vt.vreplication set state = 'Running', stop_pos = null where id = 1" - cancel2 := "update _vt.vreplication set state = 'Running', stop_pos = null where id = 2" + cancel1 := "update _vt.vreplication set state = 'Running', stop_pos = null where id in (1)" + cancel2 := "update _vt.vreplication set state = 'Running', stop_pos = null where id in (2)" tme.dbDest1Client.addQuery(cancel1, &sqltypes.Result{}, nil) tme.dbDest2Client.addQuery(cancel1, &sqltypes.Result{}, nil) tme.dbDest1Client.addQuery(cancel2, &sqltypes.Result{}, nil) @@ -655,8 +675,8 @@ func TestTableMigrateJournalExists(t *testing.T) { } // Show one journal as created. - tme.dbSource1Client.addQuery("select 1 from _vt.resharding_journal where id = 9113431017721636330", sqltypes.MakeTestResult(sqltypes.MakeTestFields("1", "int64"), "1"), nil) - tme.dbSource2Client.addQuery("select 1 from _vt.resharding_journal where id = 9113431017721636330", &sqltypes.Result{}, nil) + tme.dbSource1Client.addQuery("select 1 from _vt.resharding_journal where id=9113431017721636330", sqltypes.MakeTestResult(sqltypes.MakeTestFields("1", "int64"), "1"), nil) + tme.dbSource2Client.addQuery("select 1 from _vt.resharding_journal where id=9113431017721636330", &sqltypes.Result{}, nil) // Create the missing journal. journal2 := "insert into _vt.resharding_journal.*9113431017721636330.*tables.*t1.*t2.*local_position.*MariaDB/5-456-892.*shard_gtids.*80.*MariaDB/5-456-893.*80.*participants.*40.*40" @@ -676,9 +696,15 @@ func TestTableMigrateJournalExists(t *testing.T) { tme.dbSource2Client.addQuery("select * from _vt.vreplication where id = 2", stopped, nil) // Delete the target replications. - tme.dbDest1Client.addQuery("delete from _vt.vreplication where id = 1", &sqltypes.Result{}, nil) - tme.dbDest2Client.addQuery("delete from _vt.vreplication where id = 1", &sqltypes.Result{}, nil) - tme.dbDest1Client.addQuery("delete from _vt.vreplication where id = 2", &sqltypes.Result{}, nil) + tme.dbDest1Client.addQuery("select id from _vt.vreplication where id = 1", resultid1, nil) + tme.dbDest1Client.addQuery("delete from _vt.vreplication where id in (1)", &sqltypes.Result{}, nil) + tme.dbDest1Client.addQuery("delete from _vt.copy_state where vrepl_id in (1)", &sqltypes.Result{}, nil) + tme.dbDest1Client.addQuery("select id from _vt.vreplication where id = 2", resultid2, nil) + tme.dbDest1Client.addQuery("delete from _vt.vreplication where id in (2)", &sqltypes.Result{}, nil) + tme.dbDest1Client.addQuery("delete from _vt.copy_state where vrepl_id in (2)", &sqltypes.Result{}, nil) + tme.dbDest2Client.addQuery("select id from _vt.vreplication where id = 1", resultid1, nil) + tme.dbDest2Client.addQuery("delete from _vt.vreplication where id in (1)", &sqltypes.Result{}, nil) + tme.dbDest2Client.addQuery("delete from _vt.copy_state where vrepl_id in (1)", &sqltypes.Result{}, nil) _, err = tme.wr.MigrateWrites(ctx, tme.targetKeyspace, "test", 1*time.Second) if err != nil { @@ -717,8 +743,8 @@ func TestShardMigrateJournalExists(t *testing.T) { } // Show one journal as created. - tme.dbSource1Client.addQuery("select 1 from _vt.resharding_journal where id = 6432976123657117098", sqltypes.MakeTestResult(sqltypes.MakeTestFields("1", "int64"), "1"), nil) - tme.dbSource2Client.addQuery("select 1 from _vt.resharding_journal where id = 6432976123657117098", &sqltypes.Result{}, nil) + tme.dbSource1Client.addQuery("select 1 from _vt.resharding_journal where id=6432976123657117098", sqltypes.MakeTestResult(sqltypes.MakeTestFields("1", "int64"), "1"), nil) + tme.dbSource2Client.addQuery("select 1 from _vt.resharding_journal where id=6432976123657117098", &sqltypes.Result{}, nil) // Create the missing journal. journal2 := "insert into _vt.resharding_journal.*6432976123657117098.*migration_type:SHARDS.*local_position.*MariaDB/5-456-892.*shard_gtids.*80.*MariaDB/5-456-893.*shard_gtids.*80.*MariaDB/5-456-893.*participants.*40.*40" @@ -738,9 +764,15 @@ func TestShardMigrateJournalExists(t *testing.T) { tme.dbSource2Client.addQuery("select * from _vt.vreplication where id = 2", stopped, nil) // Delete the target replications. - tme.dbDest1Client.addQuery("delete from _vt.vreplication where id = 1", &sqltypes.Result{}, nil) - tme.dbDest2Client.addQuery("delete from _vt.vreplication where id = 1", &sqltypes.Result{}, nil) - tme.dbDest1Client.addQuery("delete from _vt.vreplication where id = 2", &sqltypes.Result{}, nil) + tme.dbDest1Client.addQuery("select id from _vt.vreplication where id = 1", resultid1, nil) + tme.dbDest1Client.addQuery("delete from _vt.vreplication where id in (1)", &sqltypes.Result{}, nil) + tme.dbDest1Client.addQuery("delete from _vt.copy_state where vrepl_id in (1)", &sqltypes.Result{}, nil) + tme.dbDest1Client.addQuery("select id from _vt.vreplication where id = 2", resultid2, nil) + tme.dbDest1Client.addQuery("delete from _vt.vreplication where id in (2)", &sqltypes.Result{}, nil) + tme.dbDest1Client.addQuery("delete from _vt.copy_state where vrepl_id in (2)", &sqltypes.Result{}, nil) + tme.dbDest2Client.addQuery("select id from _vt.vreplication where id = 1", resultid1, nil) + tme.dbDest2Client.addQuery("delete from _vt.vreplication where id in (1)", &sqltypes.Result{}, nil) + tme.dbDest2Client.addQuery("delete from _vt.copy_state where vrepl_id in (1)", &sqltypes.Result{}, nil) _, err = tme.wr.MigrateWrites(ctx, tme.targetKeyspace, "test", 1*time.Second) if err != nil { diff --git a/go/vt/wrangler/testlib/migrate_served_types_test.go b/go/vt/wrangler/testlib/migrate_served_types_test.go index 3db2caa496e..5cd05514b44 100644 --- a/go/vt/wrangler/testlib/migrate_served_types_test.go +++ b/go/vt/wrangler/testlib/migrate_served_types_test.go @@ -585,8 +585,9 @@ func TestMultiShardMigrateServedTypes(t *testing.T) { func expectDeleteVRepl(dbClient *binlogplayer.MockDBClient) { dbClient.ExpectRequest("use _vt", &sqltypes.Result{}, nil) + dbClient.ExpectRequest("select id from _vt.vreplication where id = 1", &sqltypes.Result{Rows: [][]sqltypes.Value{{sqltypes.NewInt64(1)}}}, nil) dbClient.ExpectRequest("begin", nil, nil) - dbClient.ExpectRequest("delete from _vt.vreplication where id = 1", &sqltypes.Result{RowsAffected: 1}, nil) - dbClient.ExpectRequest("delete from _vt.copy_state where vrepl_id = 1", nil, nil) + dbClient.ExpectRequest("delete from _vt.vreplication where id in (1)", &sqltypes.Result{RowsAffected: 1}, nil) + dbClient.ExpectRequest("delete from _vt.copy_state where vrepl_id in (1)", nil, nil) dbClient.ExpectRequest("commit", nil, nil) } From e68a3c5021d431941866d3c43b647c94b753cddf Mon Sep 17 00:00:00 2001 From: Rasika Kale Date: Tue, 10 Sep 2019 17:01:05 -0700 Subject: [PATCH 074/425] Fixed error checking for multiplication of uint*int and uint*int Signed-off-by: Rasika Kale --- go/sqltypes/arithmetic.go | 4 ++-- go/sqltypes/arithmetic_test.go | 4 ---- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/go/sqltypes/arithmetic.go b/go/sqltypes/arithmetic.go index dcbc1a2380b..7521dfd3fb4 100644 --- a/go/sqltypes/arithmetic.go +++ b/go/sqltypes/arithmetic.go @@ -544,7 +544,7 @@ func uintMinusIntWithError(v1 uint64, v2 int64) (numeric, error) { } func uintTimesIntWithError(v1 uint64, v2 int64) (numeric, error) { - if v2 < 0 || v1 >= math.MaxInt64 && v2 > 2 || int64(v1) < 0 { + if v2 < 0 || int64(v1) < 0 { return numeric{}, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "BIGINT UNSIGNED value is out of range in %v * %v", v1, v2) } return uintTimesUintWithError(v1, uint64(v2)) @@ -574,7 +574,7 @@ func uintMinusUintWithError(v1, v2 uint64) (numeric, error) { func uintTimesUintWithError(v1, v2 uint64) (numeric, error) { result := v1 * v2 - if result < v2 { + if result < v2 || result < v1 { return numeric{}, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "BIGINT UNSIGNED value is out of range in %v * %v", v1, v2) } return numeric{typ: Uint64, uval: result}, nil diff --git a/go/sqltypes/arithmetic_test.go b/go/sqltypes/arithmetic_test.go index 857b6b715ce..aaecf98f328 100644 --- a/go/sqltypes/arithmetic_test.go +++ b/go/sqltypes/arithmetic_test.go @@ -103,10 +103,6 @@ func TestMultiply(t *testing.T) { v1: NewUint64(math.MaxUint64), v2: NewUint64(1), out: NewUint64(math.MaxUint64), - }, { - v1: NewUint64(2), - v2: NewUint64(math.MaxUint64), - err: vterrors.New(vtrpcpb.Code_INVALID_ARGUMENT, "BIGINT UNSIGNED value is out of range in 2 * 18446744073709551615"), }, { //Checking whether maxInt value can be passed as uint value v1: NewUint64(math.MaxInt64), From ccba3dba83a1de24c40c071407abadcbb15c43f7 Mon Sep 17 00:00:00 2001 From: deepthi Date: Wed, 11 Sep 2019 14:09:50 -0700 Subject: [PATCH 075/425] make TER idempotent so that it can be called again if the first call does not complete all steps Signed-off-by: deepthi --- .../tabletmanager/rpc_external_reparent.go | 215 ++++++++++-------- 1 file changed, 119 insertions(+), 96 deletions(-) diff --git a/go/vt/vttablet/tabletmanager/rpc_external_reparent.go b/go/vt/vttablet/tabletmanager/rpc_external_reparent.go index 83904ab1ca0..426f5782834 100644 --- a/go/vt/vttablet/tabletmanager/rpc_external_reparent.go +++ b/go/vt/vttablet/tabletmanager/rpc_external_reparent.go @@ -81,13 +81,6 @@ func (agent *ActionAgent) TabletExternallyReparented(ctx context.Context, extern // timestamp to the current time. agent.setExternallyReparentedTime(startTime) - if topoproto.TabletAliasEqual(si.MasterAlias, tablet.Alias) { - // We may get called on the current master even when nothing has changed. - // If the global shard record is already updated, it means we successfully - // finished a previous reparent to this tablet. - return nil - } - // Create a reusable Reparent event with available info. ev := &events.Reparent{ ShardInfo: *si, @@ -107,14 +100,18 @@ func (agent *ActionAgent) TabletExternallyReparented(ctx context.Context, extern // Execute state change to master by force-updating only the local copy of the // tablet record. The actual record in topo will be updated later. - log.Infof("fastTabletExternallyReparented: executing change callback for state change to MASTER") newTablet := proto.Clone(tablet).(*topodatapb.Tablet) - newTablet.Type = topodatapb.TabletType_MASTER - // This is where updateState will block for gracePeriod, while it gives - // vtgate a chance to stop sending replica queries. - agent.updateState(ctx, newTablet, "fastTabletExternallyReparented") + // We may get called on the current master multiple times in order to fix incomplete external reparents + // update tablet only if it is not currently master + if newTablet.Type != topodatapb.TabletType_MASTER { + log.Infof("fastTabletExternallyReparented: executing change callback for state change to MASTER") + newTablet.Type = topodatapb.TabletType_MASTER + // This is where updateState will block for gracePeriod, while it gives + // vtgate a chance to stop sending replica queries. + agent.updateState(ctx, newTablet, "fastTabletExternallyReparented") + } // Start the finalize stage with a background context, but connect the trace. bgCtx, cancel := context.WithTimeout(agent.batchCtx, *finalizeReparentTimeout) bgCtx = trace.CopySpan(bgCtx, ctx) @@ -135,8 +132,12 @@ func (agent *ActionAgent) TabletExternallyReparented(ctx context.Context, extern } // finalizeTabletExternallyReparented performs slow, synchronized reconciliation -// tasks that ensure topology is self-consistent, and then marks the reparent as -// finished by updating the global shard record. +// tasks that ensure topology is self-consistent +// it first updates new and old master tablet records, then updates +// the global shard record, then refreshes the old master +// after that it attempts to detect and clean up any lingering old masters +// note that an up-to-date shard record does not necessarily mean that +// the reparent completed all the actions successfully func (agent *ActionAgent) finalizeTabletExternallyReparented(ctx context.Context, si *topo.ShardInfo, ev *events.Reparent) (err error) { var wg sync.WaitGroup var errs concurrency.AllErrorRecorder @@ -150,10 +151,12 @@ func (agent *ActionAgent) finalizeTabletExternallyReparented(ctx context.Context go func() { defer wg.Done() log.Infof("finalizeTabletExternallyReparented: updating tablet record for new master: %v", agent.TabletAlias) - // Update our own record to master. + // Update our own record to master if needed _, err := agent.TopoServer.UpdateTabletFields(ctx, agent.TabletAlias, func(tablet *topodatapb.Tablet) error { - tablet.Type = topodatapb.TabletType_MASTER + if tablet.Type != topodatapb.TabletType_MASTER { + tablet.Type = topodatapb.TabletType_MASTER + } return nil }) if err != nil { @@ -161,14 +164,6 @@ func (agent *ActionAgent) finalizeTabletExternallyReparented(ctx context.Context } }() - tablet := agent.Tablet() - tabletMap, err := agent.TopoServer.GetTabletMapForShard(ctx, tablet.Keyspace, tablet.Shard) - if err != nil { - log.Errorf("ignoring error %v from GetTabletMapForShard so that we can process any partial results", err) - } - - // make the channel buffer big enough that it doesn't block senders - tabletsToRefresh := make(chan topodatapb.Tablet, len(tabletMap)+1) if !topoproto.TabletAliasIsZero(oldMasterAlias) { wg.Add(1) go func() { @@ -194,95 +189,123 @@ func (agent *ActionAgent) finalizeTabletExternallyReparented(ctx context.Context // oldMasterTablet will be nil if no update was needed if oldMasterTablet != nil { ev.OldMaster = *oldMasterTablet - tabletsToRefresh <- *oldMasterTablet } }() } - - // update any other tablets claiming to be MASTER also to REPLICA - for _, tabletInfo := range tabletMap { - alias := tabletInfo.Tablet.Alias - if !topoproto.TabletAliasEqual(alias, agent.TabletAlias) && !topoproto.TabletAliasEqual(alias, oldMasterAlias) && tabletInfo.Tablet.Type == topodatapb.TabletType_MASTER { - log.Infof("finalizeTabletExternallyReparented: updating tablet record for another old master: %v", alias) - wg.Add(1) - go func(alias *topodatapb.TabletAlias) { - defer wg.Done() - var err error - tab, err := agent.TopoServer.UpdateTabletFields(ctx, alias, - func(tablet *topodatapb.Tablet) error { - if tablet.Type == topodatapb.TabletType_MASTER { - tablet.Type = topodatapb.TabletType_REPLICA - } - return nil - }) - if err != nil { - errs.RecordError(err) - return - } - // tab will be nil if no update was needed - if tab != nil { - tabletsToRefresh <- *tab - } - }(alias) - } - } - // Wait for the tablet records to be updated. At that point, any rebuild will // see the new master, so we're ready to mark the reparent as done in the // global shard record. wg.Wait() - // we waited for all goroutines to complete, so now close the channel - close(tabletsToRefresh) if errs.HasErrors() { return errs.Error() } - wg.Add(1) - go func() { - defer wg.Done() + masterTablet := agent.Tablet() + + // Update the master field in the global shard record. We don't use a lock + // here anymore. The lock was only to ensure that the global shard record + // didn't get modified between the time when we read it and the time when we + // write it back. Now we use an update loop pattern to do that instead. + event.DispatchUpdate(ev, "updating global shard record") + log.Infof("finalizeTabletExternallyReparented: updating global shard record if needed") + _, err = agent.TopoServer.UpdateShardFields(ctx, masterTablet.Keyspace, masterTablet.Shard, func(currentSi *topo.ShardInfo) error { + if topoproto.TabletAliasEqual(currentSi.MasterAlias, masterTablet.Alias) { + // It is correct to return this error here, UpdateShardFields will ignore it + return topo.NewError(topo.NoUpdateNeeded, masterTablet.Alias.String()) + } + if !topoproto.TabletAliasEqual(currentSi.MasterAlias, oldMasterAlias) { + log.Warningf("old master alias (%v) not found in the global Shard record i.e. it has changed in the meantime."+ + " We're not overwriting the value with the new master (%v) because the current value is probably newer."+ + " (initial Shard record = %#v, current Shard record = %#v)", + oldMasterAlias, masterTablet.Alias, si, currentSi) + // It is correct to return this error here, UpdateShardFields will ignore it + return topo.NewError(topo.NoUpdateNeeded, oldMasterAlias.String()) + } + currentSi.MasterAlias = masterTablet.Alias + return nil + }) + if err != nil { + errs.RecordError(err) + } - // Update the master field in the global shard record. We don't use a lock - // here anymore. The lock was only to ensure that the global shard record - // didn't get modified between the time when we read it and the time when we - // write it back. Now we use an update loop pattern to do that instead. - event.DispatchUpdate(ev, "updating global shard record") - log.Infof("finalizeTabletExternallyReparented: updating global shard record if needed") - _, err = agent.TopoServer.UpdateShardFields(ctx, tablet.Keyspace, tablet.Shard, func(currentSi *topo.ShardInfo) error { - if topoproto.TabletAliasEqual(currentSi.MasterAlias, tablet.Alias) { - return topo.NewError(topo.NoUpdateNeeded, tablet.Alias.String()) - } - if !topoproto.TabletAliasEqual(currentSi.MasterAlias, oldMasterAlias) { - log.Warningf("old master alias (%v) not found in the global Shard record i.e. it has changed in the meantime."+ - " We're not overwriting the value with the new master (%v) because the current value is probably newer."+ - " (initial Shard record = %#v, current Shard record = %#v)", - oldMasterAlias, tablet.Alias, si, currentSi) - return topo.NewError(topo.NoUpdateNeeded, oldMasterAlias.String()) - } - currentSi.MasterAlias = tablet.Alias - return nil - }) - if err != nil { - errs.RecordError(err) + if errs.HasErrors() { + return errs.Error() + } + + if !topoproto.TabletAliasIsZero(oldMasterAlias) { + // Tell the old master to re-read its tablet record and change its state. + // We don't need to put error into errs if this fails, but we need to wait + // for it to make sure that old master tablet is not stuck in the MASTER + // state. + tmc := tmclient.NewTabletManagerClient() + if err := tmc.RefreshState(ctx, oldMasterTablet); err != nil { + log.Warningf("Error calling RefreshState on old master %v: %v", topoproto.TabletAliasString(oldMasterTablet.Alias), err) } - }() + } - for tab := range tabletsToRefresh { - log.Infof("finalizeTabletExternallyReparented: Refresh state for tablet: %v", topoproto.TabletAliasString(tab.Alias)) - wg.Add(1) - go func(tablet topodatapb.Tablet) { - defer wg.Done() + tabletMap, err := agent.TopoServer.GetTabletMapForShard(ctx, masterTablet.Keyspace, masterTablet.Shard) + if err != nil { + log.Errorf("ignoring error %v from GetTabletMapForShard so that we can process any partial results", err) + } - // Tell the old master(s) to re-read its tablet record and change its state. - // We don't need to put error into errs if this fails, but we need to wait - // for it to make sure that an old master tablet is not stuck in the MASTER - // state. - tmc := tmclient.NewTabletManagerClient() - if err := tmc.RefreshState(ctx, &tablet); err != nil { - log.Warningf("Error calling RefreshState on old master %v: %v", topoproto.TabletAliasString(tablet.Alias), err) + if len(tabletMap) > 0 { + // make the channel buffer big enough that it doesn't block senders + tabletsToRefresh := make(chan topodatapb.Tablet, len(tabletMap)) + // update any other tablets claiming to be MASTER also to REPLICA + for _, tabletInfo := range tabletMap { + alias := tabletInfo.Tablet.Alias + if !topoproto.TabletAliasEqual(alias, agent.TabletAlias) && !topoproto.TabletAliasEqual(alias, oldMasterAlias) && tabletInfo.Tablet.Type == topodatapb.TabletType_MASTER { + log.Infof("finalizeTabletExternallyReparented: updating tablet record for another old master: %v", alias) + wg.Add(1) + go func(alias *topodatapb.TabletAlias) { + defer wg.Done() + var err error + tab, err := agent.TopoServer.UpdateTabletFields(ctx, alias, + func(tablet *topodatapb.Tablet) error { + if tablet.Type == topodatapb.TabletType_MASTER { + tablet.Type = topodatapb.TabletType_REPLICA + } + return nil + }) + if err != nil { + errs.RecordError(err) + return + } + // tab will be nil if no update was needed + if tab != nil { + tabletsToRefresh <- *tab + } + }(alias) } - }(tab) + } + // Wait for the tablet records to be updated. At that point, any rebuild will + // see the new master, so we're ready to mark the reparent as done in the + // global shard record. + wg.Wait() + // we waited for all goroutines to complete, so now close the channel + close(tabletsToRefresh) + if errs.HasErrors() { + return errs.Error() + } + + for tab := range tabletsToRefresh { + log.Infof("finalizeTabletExternallyReparented: Refresh state for tablet: %v", topoproto.TabletAliasString(tab.Alias)) + wg.Add(1) + go func(tablet topodatapb.Tablet) { + defer wg.Done() + + // Tell the old master(s) to re-read its tablet record and change its state. + // We don't need to put error into errs if this fails, but we need to wait + // for it to make sure that an old master tablet is not stuck in the MASTER + // state. + tmc := tmclient.NewTabletManagerClient() + if err := tmc.RefreshState(ctx, &tablet); err != nil { + log.Warningf("Error calling RefreshState on old master %v: %v", topoproto.TabletAliasString(tablet.Alias), err) + } + }(tab) + } + wg.Wait() } - wg.Wait() if errs.HasErrors() { return errs.Error() } From 55157408f6afcb5a87d5496c899c7c6139125ee8 Mon Sep 17 00:00:00 2001 From: deepthi Date: Wed, 11 Sep 2019 21:23:45 -0700 Subject: [PATCH 076/425] add comments explaining why some synchronization has been removed Signed-off-by: deepthi --- go/vt/vttablet/tabletmanager/rpc_external_reparent.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/go/vt/vttablet/tabletmanager/rpc_external_reparent.go b/go/vt/vttablet/tabletmanager/rpc_external_reparent.go index 426f5782834..fb8b48e3fa3 100644 --- a/go/vt/vttablet/tabletmanager/rpc_external_reparent.go +++ b/go/vt/vttablet/tabletmanager/rpc_external_reparent.go @@ -206,6 +206,11 @@ func (agent *ActionAgent) finalizeTabletExternallyReparented(ctx context.Context // here anymore. The lock was only to ensure that the global shard record // didn't get modified between the time when we read it and the time when we // write it back. Now we use an update loop pattern to do that instead. + + // We also used to do this in parallel with RefreshState on the old master + // we don't do that any more. we want to update the shard record first + // and only then attempt to refresh the old master because it is possible + // that the old master is unreachable event.DispatchUpdate(ev, "updating global shard record") log.Infof("finalizeTabletExternallyReparented: updating global shard record if needed") _, err = agent.TopoServer.UpdateShardFields(ctx, masterTablet.Keyspace, masterTablet.Shard, func(currentSi *topo.ShardInfo) error { From 6b2d0d14435e6a33b902be2fcfe9687d1582d0f7 Mon Sep 17 00:00:00 2001 From: deepthi Date: Thu, 12 Sep 2019 09:03:40 -0700 Subject: [PATCH 077/425] fix/add descriptive comments, avoid unnecessary topo calls, merge 2 loops into 1 and remove use of channel that is no longer needed Signed-off-by: deepthi --- .../tabletmanager/rpc_external_reparent.go | 186 ++++++++---------- 1 file changed, 82 insertions(+), 104 deletions(-) diff --git a/go/vt/vttablet/tabletmanager/rpc_external_reparent.go b/go/vt/vttablet/tabletmanager/rpc_external_reparent.go index fb8b48e3fa3..eb44b1d3d42 100644 --- a/go/vt/vttablet/tabletmanager/rpc_external_reparent.go +++ b/go/vt/vttablet/tabletmanager/rpc_external_reparent.go @@ -91,19 +91,14 @@ func (agent *ActionAgent) TabletExternallyReparented(ctx context.Context, extern }, ExternalID: externalID, } - defer func() { - if err != nil { - event.DispatchUpdate(ev, "failed: "+err.Error()) - } - }() event.DispatchUpdate(ev, "starting external from tablet (fast)") // Execute state change to master by force-updating only the local copy of the // tablet record. The actual record in topo will be updated later. newTablet := proto.Clone(tablet).(*topodatapb.Tablet) - // We may get called on the current master multiple times in order to fix incomplete external reparents - // update tablet only if it is not currently master + // We may get called on the current master multiple times in order to fix incomplete external reparents. + // We update the tablet here only if it is not currently master if newTablet.Type != topodatapb.TabletType_MASTER { log.Infof("fastTabletExternallyReparented: executing change callback for state change to MASTER") newTablet.Type = topodatapb.TabletType_MASTER @@ -132,11 +127,11 @@ func (agent *ActionAgent) TabletExternallyReparented(ctx context.Context, extern } // finalizeTabletExternallyReparented performs slow, synchronized reconciliation -// tasks that ensure topology is self-consistent -// it first updates new and old master tablet records, then updates -// the global shard record, then refreshes the old master -// after that it attempts to detect and clean up any lingering old masters -// note that an up-to-date shard record does not necessarily mean that +// tasks that ensure topology is self-consistent. +// It first updates new and old master tablet records, then updates +// the global shard record, then refreshes the old master. +// After that it attempts to detect and clean up any lingering old masters. +// Note that an up-to-date shard record does not necessarily mean that // the reparent completed all the actions successfully func (agent *ActionAgent) finalizeTabletExternallyReparented(ctx context.Context, si *topo.ShardInfo, ev *events.Reparent) (err error) { var wg sync.WaitGroup @@ -156,8 +151,10 @@ func (agent *ActionAgent) finalizeTabletExternallyReparented(ctx context.Context func(tablet *topodatapb.Tablet) error { if tablet.Type != topodatapb.TabletType_MASTER { tablet.Type = topodatapb.TabletType_MASTER + return nil } - return nil + // returning NoUpdateNeeded avoids unnecessary calls to UpdateTablet + return topo.NewError(topo.NoUpdateNeeded, agent.TabletAlias.String()) }) if err != nil { errs.RecordError(err) @@ -177,8 +174,10 @@ func (agent *ActionAgent) finalizeTabletExternallyReparented(ctx context.Context func(tablet *topodatapb.Tablet) error { if tablet.Type == topodatapb.TabletType_MASTER { tablet.Type = topodatapb.TabletType_REPLICA + return nil } - return nil + // returning NoUpdateNeeded avoids unnecessary calls to UpdateTablet + return topo.NewError(topo.NoUpdateNeeded, oldMasterAlias.String()) }) if err != nil { errs.RecordError(err) @@ -202,115 +201,94 @@ func (agent *ActionAgent) finalizeTabletExternallyReparented(ctx context.Context masterTablet := agent.Tablet() - // Update the master field in the global shard record. We don't use a lock - // here anymore. The lock was only to ensure that the global shard record - // didn't get modified between the time when we read it and the time when we - // write it back. Now we use an update loop pattern to do that instead. - - // We also used to do this in parallel with RefreshState on the old master - // we don't do that any more. we want to update the shard record first - // and only then attempt to refresh the old master because it is possible - // that the old master is unreachable event.DispatchUpdate(ev, "updating global shard record") log.Infof("finalizeTabletExternallyReparented: updating global shard record if needed") - _, err = agent.TopoServer.UpdateShardFields(ctx, masterTablet.Keyspace, masterTablet.Shard, func(currentSi *topo.ShardInfo) error { - if topoproto.TabletAliasEqual(currentSi.MasterAlias, masterTablet.Alias) { - // It is correct to return this error here, UpdateShardFields will ignore it - return topo.NewError(topo.NoUpdateNeeded, masterTablet.Alias.String()) - } - if !topoproto.TabletAliasEqual(currentSi.MasterAlias, oldMasterAlias) { - log.Warningf("old master alias (%v) not found in the global Shard record i.e. it has changed in the meantime."+ - " We're not overwriting the value with the new master (%v) because the current value is probably newer."+ - " (initial Shard record = %#v, current Shard record = %#v)", - oldMasterAlias, masterTablet.Alias, si, currentSi) - // It is correct to return this error here, UpdateShardFields will ignore it - return topo.NewError(topo.NoUpdateNeeded, oldMasterAlias.String()) + wg.Add(1) + go func() { + defer wg.Done() + // Update the master field in the global shard record. We don't use a lock + // here anymore. The lock was only to ensure that the global shard record + // didn't get modified between the time when we read it and the time when we + // write it back. Now we use an update loop pattern to do that instead. + _, err = agent.TopoServer.UpdateShardFields(ctx, masterTablet.Keyspace, masterTablet.Shard, func(currentSi *topo.ShardInfo) error { + if topoproto.TabletAliasEqual(currentSi.MasterAlias, masterTablet.Alias) { + // returning NoUpdateNeeded avoids unnecessary calls to UpdateTablet + return topo.NewError(topo.NoUpdateNeeded, masterTablet.Alias.String()) + } + if !topoproto.TabletAliasEqual(currentSi.MasterAlias, oldMasterAlias) { + log.Warningf("old master alias (%v) not found in the global Shard record i.e. it has changed in the meantime."+ + " We're not overwriting the value with the new master (%v) because the current value is probably newer."+ + " (initial Shard record = %#v, current Shard record = %#v)", + oldMasterAlias, masterTablet.Alias, si, currentSi) + // returning NoUpdateNeeded avoids unnecessary calls to UpdateTablet + return topo.NewError(topo.NoUpdateNeeded, oldMasterAlias.String()) + } + currentSi.MasterAlias = masterTablet.Alias + return nil + }) + if err != nil { + errs.RecordError(err) } - currentSi.MasterAlias = masterTablet.Alias - return nil - }) - if err != nil { - errs.RecordError(err) + }() + + if !topoproto.TabletAliasIsZero(oldMasterAlias) && oldMasterTablet != nil { + wg.Add(1) + go func() { + defer wg.Done() + // Tell the old master to re-read its tablet record and change its state. + // We don't need to put error into errs if this fails, but we need to wait + // for it to make sure that old master tablet is not stuck in the MASTER + // state. + tmc := tmclient.NewTabletManagerClient() + if err := tmc.RefreshState(ctx, oldMasterTablet); err != nil { + log.Warningf("Error calling RefreshState on old master %v: %v", topoproto.TabletAliasString(oldMasterTablet.Alias), err) + } + }() } + wg.Wait() if errs.HasErrors() { return errs.Error() } - if !topoproto.TabletAliasIsZero(oldMasterAlias) { - // Tell the old master to re-read its tablet record and change its state. - // We don't need to put error into errs if this fails, but we need to wait - // for it to make sure that old master tablet is not stuck in the MASTER - // state. - tmc := tmclient.NewTabletManagerClient() - if err := tmc.RefreshState(ctx, oldMasterTablet); err != nil { - log.Warningf("Error calling RefreshState on old master %v: %v", topoproto.TabletAliasString(oldMasterTablet.Alias), err) - } - } - + // Look for any other tablets claiming to be master and fix them up on a best-effort basis tabletMap, err := agent.TopoServer.GetTabletMapForShard(ctx, masterTablet.Keyspace, masterTablet.Shard) if err != nil { log.Errorf("ignoring error %v from GetTabletMapForShard so that we can process any partial results", err) } - if len(tabletMap) > 0 { - // make the channel buffer big enough that it doesn't block senders - tabletsToRefresh := make(chan topodatapb.Tablet, len(tabletMap)) - // update any other tablets claiming to be MASTER also to REPLICA - for _, tabletInfo := range tabletMap { - alias := tabletInfo.Tablet.Alias - if !topoproto.TabletAliasEqual(alias, agent.TabletAlias) && !topoproto.TabletAliasEqual(alias, oldMasterAlias) && tabletInfo.Tablet.Type == topodatapb.TabletType_MASTER { - log.Infof("finalizeTabletExternallyReparented: updating tablet record for another old master: %v", alias) - wg.Add(1) - go func(alias *topodatapb.TabletAlias) { - defer wg.Done() - var err error - tab, err := agent.TopoServer.UpdateTabletFields(ctx, alias, - func(tablet *topodatapb.Tablet) error { - if tablet.Type == topodatapb.TabletType_MASTER { - tablet.Type = topodatapb.TabletType_REPLICA - } - return nil - }) - if err != nil { - errs.RecordError(err) - return - } - // tab will be nil if no update was needed - if tab != nil { - tabletsToRefresh <- *tab - } - }(alias) - } - } - // Wait for the tablet records to be updated. At that point, any rebuild will - // see the new master, so we're ready to mark the reparent as done in the - // global shard record. - wg.Wait() - // we waited for all goroutines to complete, so now close the channel - close(tabletsToRefresh) - if errs.HasErrors() { - return errs.Error() - } - - for tab := range tabletsToRefresh { - log.Infof("finalizeTabletExternallyReparented: Refresh state for tablet: %v", topoproto.TabletAliasString(tab.Alias)) + for _, tabletInfo := range tabletMap { + alias := tabletInfo.Tablet.Alias + if !topoproto.TabletAliasEqual(alias, agent.TabletAlias) && !topoproto.TabletAliasEqual(alias, oldMasterAlias) && tabletInfo.Tablet.Type == topodatapb.TabletType_MASTER { + log.Infof("finalizeTabletExternallyReparented: updating tablet record for another old master: %v", alias) wg.Add(1) - go func(tablet topodatapb.Tablet) { + go func(alias *topodatapb.TabletAlias) { defer wg.Done() - - // Tell the old master(s) to re-read its tablet record and change its state. - // We don't need to put error into errs if this fails, but we need to wait - // for it to make sure that an old master tablet is not stuck in the MASTER - // state. - tmc := tmclient.NewTabletManagerClient() - if err := tmc.RefreshState(ctx, &tablet); err != nil { - log.Warningf("Error calling RefreshState on old master %v: %v", topoproto.TabletAliasString(tablet.Alias), err) + var err error + tab, err := agent.TopoServer.UpdateTabletFields(ctx, alias, + func(tablet *topodatapb.Tablet) error { + if tablet.Type == topodatapb.TabletType_MASTER { + tablet.Type = topodatapb.TabletType_REPLICA + return nil + } + return topo.NewError(topo.NoUpdateNeeded, alias.String()) + }) + if err != nil { + errs.RecordError(err) + return } - }(tab) + // tab will be nil if no update was needed + if tab != nil { + log.Infof("finalizeTabletExternallyReparented: Refresh state for tablet: %v", topoproto.TabletAliasString(tab.Alias)) + tmc := tmclient.NewTabletManagerClient() + if err := tmc.RefreshState(ctx, tab); err != nil { + log.Warningf("Error calling RefreshState on old master %v: %v", topoproto.TabletAliasString(tab.Alias), err) + } + } + }(alias) } - wg.Wait() } + wg.Wait() if errs.HasErrors() { return errs.Error() } From 0426fc324f831b6b5e118ecf74bbafb0ea76248f Mon Sep 17 00:00:00 2001 From: Adam Saponara Date: Thu, 12 Sep 2019 13:40:01 -0400 Subject: [PATCH 078/425] Track number of times pool had zero available slots Signed-off-by: Adam Saponara --- go/pools/resource_pool.go | 13 +++++++++++-- go/pools/resource_pool_test.go | 10 +++++----- go/vt/dbconnpool/connection_pool.go | 10 ++++++++++ go/vt/vttablet/tabletserver/connpool/pool.go | 10 ++++++++++ 4 files changed, 36 insertions(+), 7 deletions(-) diff --git a/go/pools/resource_pool.go b/go/pools/resource_pool.go index 8e92f0bf5ee..945393c792e 100644 --- a/go/pools/resource_pool.go +++ b/go/pools/resource_pool.go @@ -60,6 +60,7 @@ type ResourcePool struct { waitCount sync2.AtomicInt64 waitTime sync2.AtomicDuration idleClosed sync2.AtomicInt64 + exhausted sync2.AtomicInt64 capacity sync2.AtomicInt64 idleTimeout sync2.AtomicDuration @@ -230,7 +231,9 @@ func (rp *ResourcePool) get(ctx context.Context) (resource Resource, err error) } rp.active.Add(1) } - rp.available.Add(-1) + if rp.available.Add(-1) <= 0 { + rp.exhausted.Add(1) + } rp.inUse.Add(1) return wrapper.resource, err } @@ -334,7 +337,7 @@ func (rp *ResourcePool) SetIdleTimeout(idleTimeout time.Duration) { // StatsJSON returns the stats in JSON format. func (rp *ResourcePool) StatsJSON() string { - return fmt.Sprintf(`{"Capacity": %v, "Available": %v, "Active": %v, "InUse": %v, "MaxCapacity": %v, "WaitCount": %v, "WaitTime": %v, "IdleTimeout": %v, "IdleClosed": %v}`, + return fmt.Sprintf(`{"Capacity": %v, "Available": %v, "Active": %v, "InUse": %v, "MaxCapacity": %v, "WaitCount": %v, "WaitTime": %v, "IdleTimeout": %v, "IdleClosed": %v, "Exhausted": %v}`, rp.Capacity(), rp.Available(), rp.Active(), @@ -344,6 +347,7 @@ func (rp *ResourcePool) StatsJSON() string { rp.WaitTime().Nanoseconds(), rp.IdleTimeout().Nanoseconds(), rp.IdleClosed(), + rp.Exhausted(), ) } @@ -392,3 +396,8 @@ func (rp *ResourcePool) IdleTimeout() time.Duration { func (rp *ResourcePool) IdleClosed() int64 { return rp.idleClosed.Get() } + +// Exhausted returns the number of times Available dropped below 1 +func (rp *ResourcePool) Exhausted() int64 { + return rp.exhausted.Get() +} diff --git a/go/pools/resource_pool_test.go b/go/pools/resource_pool_test.go index 15c21c9202e..f9a7c9ac3a7 100644 --- a/go/pools/resource_pool_test.go +++ b/go/pools/resource_pool_test.go @@ -247,7 +247,7 @@ func TestShrinking(t *testing.T) { p.SetCapacity(3) done <- true }() - expected := `{"Capacity": 3, "Available": 0, "Active": 4, "InUse": 4, "MaxCapacity": 5, "WaitCount": 0, "WaitTime": 0, "IdleTimeout": 1000000000, "IdleClosed": 0}` + expected := `{"Capacity": 3, "Available": 0, "Active": 4, "InUse": 4, "MaxCapacity": 5, "WaitCount": 0, "WaitTime": 0, "IdleTimeout": 1000000000, "IdleClosed": 0, "Exhausted": 0}` for i := 0; i < 10; i++ { time.Sleep(10 * time.Millisecond) stats := p.StatsJSON() @@ -266,7 +266,7 @@ func TestShrinking(t *testing.T) { p.Put(resources[i]) } stats := p.StatsJSON() - expected = `{"Capacity": 3, "Available": 3, "Active": 3, "InUse": 0, "MaxCapacity": 5, "WaitCount": 0, "WaitTime": 0, "IdleTimeout": 1000000000, "IdleClosed": 0}` + expected = `{"Capacity": 3, "Available": 3, "Active": 3, "InUse": 0, "MaxCapacity": 5, "WaitCount": 0, "WaitTime": 0, "IdleTimeout": 1000000000, "IdleClosed": 0, "Exhausted": 0}` if stats != expected { t.Errorf(`expecting '%s', received '%s'`, expected, stats) } @@ -389,7 +389,7 @@ func TestClosing(t *testing.T) { // Wait for goroutine to call Close time.Sleep(10 * time.Millisecond) stats := p.StatsJSON() - expected := `{"Capacity": 0, "Available": 0, "Active": 5, "InUse": 5, "MaxCapacity": 5, "WaitCount": 0, "WaitTime": 0, "IdleTimeout": 1000000000, "IdleClosed": 0}` + expected := `{"Capacity": 0, "Available": 0, "Active": 5, "InUse": 5, "MaxCapacity": 5, "WaitCount": 0, "WaitTime": 0, "IdleTimeout": 1000000000, "IdleClosed": 0, "Exhausted": 1}` if stats != expected { t.Errorf(`expecting '%s', received '%s'`, expected, stats) } @@ -409,7 +409,7 @@ func TestClosing(t *testing.T) { } stats = p.StatsJSON() - expected = `{"Capacity": 0, "Available": 0, "Active": 0, "InUse": 0, "MaxCapacity": 5, "WaitCount": 0, "WaitTime": 0, "IdleTimeout": 1000000000, "IdleClosed": 0}` + expected = `{"Capacity": 0, "Available": 0, "Active": 0, "InUse": 0, "MaxCapacity": 5, "WaitCount": 0, "WaitTime": 0, "IdleTimeout": 1000000000, "IdleClosed": 0, "Exhausted": 1}` if stats != expected { t.Errorf(`expecting '%s', received '%s'`, expected, stats) } @@ -563,7 +563,7 @@ func TestCreateFail(t *testing.T) { t.Errorf("Expecting Failed, received %v", err) } stats := p.StatsJSON() - expected := `{"Capacity": 5, "Available": 5, "Active": 0, "InUse": 0, "MaxCapacity": 5, "WaitCount": 0, "WaitTime": 0, "IdleTimeout": 1000000000, "IdleClosed": 0}` + expected := `{"Capacity": 5, "Available": 5, "Active": 0, "InUse": 0, "MaxCapacity": 5, "WaitCount": 0, "WaitTime": 0, "IdleTimeout": 1000000000, "IdleClosed": 0, "Exhausted": 0}` if stats != expected { t.Errorf(`expecting '%s', received '%s'`, expected, stats) } diff --git a/go/vt/dbconnpool/connection_pool.go b/go/vt/dbconnpool/connection_pool.go index eedee5ddff9..7480540a691 100644 --- a/go/vt/dbconnpool/connection_pool.go +++ b/go/vt/dbconnpool/connection_pool.go @@ -84,6 +84,7 @@ func NewConnectionPool(name string, capacity int, idleTimeout time.Duration, dns stats.NewCounterDurationFunc(name+"WaitTime", "Connection pool wait time", cp.WaitTime) stats.NewGaugeDurationFunc(name+"IdleTimeout", "Connection pool idle timeout", cp.IdleTimeout) stats.NewGaugeFunc(name+"IdleClosed", "Connection pool idle closed", cp.IdleClosed) + stats.NewCounterFunc(name+"Exhausted", "Number of times pool had zero available slots", cp.Exhausted) return cp } @@ -355,3 +356,12 @@ func (cp *ConnectionPool) IdleClosed() int64 { } return p.IdleClosed() } + +// Exhausted returns the number of times available went to zero for the pool. +func (cp *ConnectionPool) Exhausted() int64 { + p := cp.pool() + if p == nil { + return 0 + } + return p.Exhausted() +} diff --git a/go/vt/vttablet/tabletserver/connpool/pool.go b/go/vt/vttablet/tabletserver/connpool/pool.go index eee178b36f7..ed2fbc9e745 100644 --- a/go/vt/vttablet/tabletserver/connpool/pool.go +++ b/go/vt/vttablet/tabletserver/connpool/pool.go @@ -98,6 +98,7 @@ func New( stats.NewCounterDurationFunc(name+"WaitTime", "Tablet server wait time", cp.WaitTime) stats.NewGaugeDurationFunc(name+"IdleTimeout", "Tablet server idle timeout", cp.IdleTimeout) stats.NewCounterFunc(name+"IdleClosed", "Tablet server conn pool idle closed", cp.IdleClosed) + stats.NewCounterFunc(name+"Exhausted", "Number of times pool had zero available slots", cp.Exhausted) return cp } @@ -296,6 +297,15 @@ func (cp *Pool) IdleClosed() int64 { return p.IdleClosed() } +// Exhausted returns the number of times available went to zero for the pool. +func (cp *Pool) Exhausted() int64 { + p := cp.pool() + if p == nil { + return 0 + } + return p.Exhausted() +} + func (cp *Pool) isCallerIDAppDebug(ctx context.Context) bool { if cp.appDebugParams == nil || cp.appDebugParams.Uname == "" { return false From 9f9c2e04b014913c4e594ef0162f45a7906bf3dc Mon Sep 17 00:00:00 2001 From: Rasika Kale Date: Tue, 13 Aug 2019 13:44:09 -0700 Subject: [PATCH 079/425] sqltypes: Subtract functionality Signed-off-by: Rasika Kale Signed-off-by: Sugu Sougoumarane --- go/sqltypes/arithmetic.go | 63 +++++++++++++++++++++++-- go/sqltypes/arithmetic_test.go | 85 ++++++++++++++++++++++++++++++++++ 2 files changed, 145 insertions(+), 3 deletions(-) diff --git a/go/sqltypes/arithmetic.go b/go/sqltypes/arithmetic.go index f5c18dd43a1..24fe939550d 100644 --- a/go/sqltypes/arithmetic.go +++ b/go/sqltypes/arithmetic.go @@ -28,9 +28,6 @@ import ( "vitess.io/vitess/go/vt/vterrors" ) -// TODO(sougou): change these functions to be more permissive. -// Most string to number conversions should quietly convert to 0. - // numeric represents a numeric value extracted from // a Value, used for arithmetic operations. type numeric struct { @@ -61,6 +58,24 @@ func Add(v1, v2 Value) (Value, error) { return castFromNumeric(lresult, lresult.typ), nil } +//Subtract takes two values and subtracts them +func Subtract(v1, v2 Value) (Value, error) { + if v1.IsNull() || v2.IsNull() { + return NULL, nil + } + + lv1, err := newNumeric(v1) + + lv2, err := newNumeric(v2) + + lresult, err := subtractNumericWithError(lv1, lv2) + if err != nil { + return NULL, err + } + + return castFromNumeric(lresult, lresult.typ), nil +} + // NullsafeAdd adds two Values in a null-safe manner. A null value // is treated as 0. If both values are null, then a null is returned. // If both values are not null, a numeric value is built @@ -376,6 +391,25 @@ func addNumericWithError(v1, v2 numeric) (numeric, error) { } +func subtractNumericWithError(v1, v2 numeric) (numeric, error) { + v1, v2 = prioritize(v1, v2) + switch v1.typ { + case Int64: + return intMinusIntWithError(v1.ival, v2.ival) + case Uint64: + switch v2.typ { + case Int64: + return uintMinusIntWithError(v1.uval, v2.ival) + case Uint64: + return uintMinusUintWithError(v1.uval, v2.uval) + } + case Float64: + return floatPlusAny(v1.fval, v2), nil + } + panic("unreachable") + +} + // prioritize reorders the input parameters // to be Float64, Uint64, Int64. func prioritize(v1, v2 numeric) (altv1, altv2 numeric) { @@ -415,6 +449,15 @@ func intPlusIntWithError(v1, v2 int64) (numeric, error) { return numeric{typ: Int64, ival: result}, nil } +func intMinusIntWithError(v1, v2 int64) (numeric, error) { + result := v1 - v2 + if v1 > 0 && v2 > math.MaxInt64 || v1 > math.MaxInt64 && v2 > 0 || v1 <= math.MinInt64 && v2 > 0 || v1 > 0 && v2 <= math.MinInt64 { + return numeric{}, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "BIGINT value is out of range in %v - %v", v1, v2) + } + + return numeric{typ: Int64, ival: result}, nil +} + func uintPlusInt(v1 uint64, v2 int64) numeric { return uintPlusUint(v1, uint64(v2)) } @@ -429,6 +472,14 @@ func uintPlusIntWithError(v1 uint64, v2 int64) (numeric, error) { return uintPlusUintWithError(v1, uint64(v2)) } +func uintMinusIntWithError(v1 uint64, v2 int64) (numeric, error) { + if v1 < uint64(v2) { + return numeric{}, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "BIGINT UNSIGNED value is out of range in %v - %v", v1, v2) + } + + return uintMinusUintWithError(v1, uint64(v2)) +} + func uintPlusUint(v1, v2 uint64) numeric { result := v1 + v2 if result < v2 { @@ -448,6 +499,12 @@ func uintPlusUintWithError(v1, v2 uint64) (numeric, error) { return numeric{typ: Uint64, uval: result}, nil } +func uintMinusUintWithError(v1, v2 uint64) (numeric, error) { + result := v1 - v2 + + return numeric{typ: Uint64, uval: result}, nil +} + func floatPlusAny(v1 float64, v2 numeric) numeric { switch v2.typ { case Int64: diff --git a/go/sqltypes/arithmetic_test.go b/go/sqltypes/arithmetic_test.go index 81aeba0cf30..f3de7542051 100644 --- a/go/sqltypes/arithmetic_test.go +++ b/go/sqltypes/arithmetic_test.go @@ -29,6 +29,91 @@ import ( "vitess.io/vitess/go/vt/vterrors" ) +func TestSubtract(t *testing.T) { + tcases := []struct { + v1, v2 Value + out Value + err error + }{{ + + //All Nulls + v1: NULL, + v2: NULL, + out: NULL, + }, { + + // First value null. + v1: NewInt32(1), + v2: NULL, + out: NULL, + }, { + + // Second value null. + v1: NULL, + v2: NewInt32(1), + out: NULL, + }, { + + // case with negative value + v1: NewInt64(-1), + v2: NewInt64(-2), + out: NewInt64(1), + }, { + + // testing for int64 overflow with min negative value + v1: NewInt64(math.MinInt64), + v2: NewInt64(1), + err: vterrors.New(vtrpcpb.Code_INVALID_ARGUMENT, "BIGINT value is out of range in -9223372036854775808 - 1"), + }, { + + v1: NewUint64(4), + v2: NewInt64(5), + err: vterrors.New(vtrpcpb.Code_INVALID_ARGUMENT, "BIGINT UNSIGNED value is out of range in 4 - 5"), + }, { + + v1: NewUint64(7), + v2: NewInt64(5), + out: NewUint64(2), + }, { + + v1: NewUint64(math.MaxUint64), + v2: NewInt64(0), + out: NewUint64(math.MaxUint64), + }, { + + // testing for int64 overflow + v1: NewInt64(math.MinInt64), + v2: NewUint64(0), + err: vterrors.New(vtrpcpb.Code_INVALID_ARGUMENT, "BIGINT UNSIGNED value is out of range in 0 - -9223372036854775808"), + }, { + + v1: TestValue(VarChar, "c"), + v2: NewInt64(1), + out: NewInt64(-1), + }, { + v1: NewUint64(1), + v2: TestValue(VarChar, "c"), + out: NewUint64(1), + }} + + for _, tcase := range tcases { + + got, err := Subtract(tcase.v1, tcase.v2) + + if !vterrors.Equals(err, tcase.err) { + t.Errorf("Subtract(%v, %v) error: %v, want %v", printValue(tcase.v1), printValue(tcase.v2), vterrors.Print(err), vterrors.Print(tcase.err)) + } + if tcase.err != nil { + continue + } + + if !reflect.DeepEqual(got, tcase.out) { + t.Errorf("Subtraction(%v, %v): %v, want %v", printValue(tcase.v1), printValue(tcase.v2), printValue(got), printValue(tcase.out)) + } + } + +} + func TestAdd(t *testing.T) { tcases := []struct { v1, v2 Value From eeebadb2978074297f190212582c50a8e2afbbed Mon Sep 17 00:00:00 2001 From: Rasika Kale Date: Tue, 27 Aug 2019 11:08:25 -0700 Subject: [PATCH 080/425] Fixed code coverage in arithmetic.go - Added more tests in arithmetic_test.go to fix code coverage - Added error checking into arithmetic.go - Implemented function floatMinusAny() for subtraction expression Signed-off-by: Rasika Kale --- go/sqltypes/arithmetic.go | 34 +++++++++++++++++++++++++-- go/sqltypes/arithmetic_test.go | 42 ++++++++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+), 2 deletions(-) diff --git a/go/sqltypes/arithmetic.go b/go/sqltypes/arithmetic.go index 24fe939550d..66f7b51b6e2 100644 --- a/go/sqltypes/arithmetic.go +++ b/go/sqltypes/arithmetic.go @@ -47,8 +47,14 @@ func Add(v1, v2 Value) (Value, error) { } lv1, err := newNumeric(v1) + if err != nil { + return NULL, err + } lv2, err := newNumeric(v2) + if err != nil { + return NULL, err + } lresult, err := addNumericWithError(lv1, lv2) if err != nil { @@ -65,8 +71,14 @@ func Subtract(v1, v2 Value) (Value, error) { } lv1, err := newNumeric(v1) + if err != nil { + return NULL, err + } lv2, err := newNumeric(v2) + if err != nil { + return NULL, err + } lresult, err := subtractNumericWithError(lv1, lv2) if err != nil { @@ -258,7 +270,10 @@ func ToInt64(v Value) (int64, error) { // ToFloat64 converts Value to float64. func ToFloat64(v Value) (float64, error) { - num, _ := newNumeric(v) + num, err := newNumeric(v) + if err != nil { + return 0, err + } switch num.typ { case Int64: return float64(num.ival), nil @@ -404,7 +419,7 @@ func subtractNumericWithError(v1, v2 numeric) (numeric, error) { return uintMinusUintWithError(v1.uval, v2.uval) } case Float64: - return floatPlusAny(v1.fval, v2), nil + return floatMinusAny(v1.fval, v2), nil } panic("unreachable") @@ -467,6 +482,10 @@ func uintPlusIntWithError(v1 uint64, v2 int64) (numeric, error) { return numeric{}, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "BIGINT value is out of range in %v + %v", v1, v2) } + if v1 >= math.MaxUint64 && v2 > 0 { + return numeric{}, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "BIGINT UNSIGNED value is out of range in %v + %v", v1, v2) + } + //convert to int -> uint is because for numeric operators (such as + or -) //where one of the operands is an unsigned integer, the result is unsigned by default. return uintPlusUintWithError(v1, uint64(v2)) @@ -515,6 +534,17 @@ func floatPlusAny(v1 float64, v2 numeric) numeric { return numeric{typ: Float64, fval: v1 + v2.fval} } +func floatMinusAny(v1 float64, v2 numeric) numeric { + switch v2.typ { + case Int64: + v2.fval = float64(v2.ival) + case Uint64: + v2.fval = float64(v2.uval) + } + return numeric{typ: Float64, fval: v1 - v2.fval} + +} + func castFromNumeric(v numeric, resultType querypb.Type) Value { switch { case IsSigned(resultType): diff --git a/go/sqltypes/arithmetic_test.go b/go/sqltypes/arithmetic_test.go index f3de7542051..381421bf554 100644 --- a/go/sqltypes/arithmetic_test.go +++ b/go/sqltypes/arithmetic_test.go @@ -94,6 +94,31 @@ func TestSubtract(t *testing.T) { v1: NewUint64(1), v2: TestValue(VarChar, "c"), out: NewUint64(1), + }, { + + v1: TestValue(Uint64, "1.2"), + v2: NewInt64(2), + err: vterrors.New(vtrpcpb.Code_INVALID_ARGUMENT, "strconv.ParseUint: parsing \"1.2\": invalid syntax"), + }, { + + v1: NewUint64(2), + v2: TestValue(Uint64, "1.2"), + err: vterrors.New(vtrpcpb.Code_INVALID_ARGUMENT, "strconv.ParseUint: parsing \"1.2\": invalid syntax"), + }, { + // uint64 - uint64 + v1: NewUint64(8), + v2: NewUint64(4), + out: NewUint64(4), + }, { + // testing for float subtraction: float - int + v1: NewFloat64(1.2), + v2: NewInt64(2), + out: NewFloat64(-0.8), + }, { + // testin for float subtraction: float - uint + v1: NewFloat64(1.2), + v2: NewUint64(2), + out: NewFloat64(-0.8), }} for _, tcase := range tcases { @@ -199,6 +224,20 @@ func TestAdd(t *testing.T) { v1: NewUint64(1), v2: TestValue(VarChar, "1.2"), out: NewFloat64(2.2), + }, { + + v1: TestValue(Int64, "1.2"), + v2: NewInt64(2), + err: vterrors.New(vtrpcpb.Code_INVALID_ARGUMENT, "strconv.ParseInt: parsing \"1.2\": invalid syntax"), + }, { + v1: NewInt64(2), + v2: TestValue(Int64, "1.2"), + err: vterrors.New(vtrpcpb.Code_INVALID_ARGUMENT, "strconv.ParseInt: parsing \"1.2\": invalid syntax"), + }, { + // testing for uint64 overflow with max uint64 + int value + v1: NewUint64(math.MaxUint64), + v2: NewInt64(2), + err: vterrors.New(vtrpcpb.Code_INVALID_ARGUMENT, "BIGINT UNSIGNED value is out of range in 18446744073709551615 + 2"), }} for _, tcase := range tcases { @@ -541,6 +580,9 @@ func TestToFloat64(t *testing.T) { }, { v: NewFloat64(1.2), out: 1.2, + }, { + v: TestValue(Int64, "1.2"), + err: vterrors.New(vtrpcpb.Code_INVALID_ARGUMENT, "strconv.ParseInt: parsing \"1.2\": invalid syntax"), }} for _, tcase := range tcases { got, err := ToFloat64(tcase.v) From 32fa645344d96988e36d9190dae1b327e42fcb20 Mon Sep 17 00:00:00 2001 From: Rasika Kale Date: Tue, 27 Aug 2019 11:29:23 -0700 Subject: [PATCH 081/425] Fixed spacing between // and comment Signed-off-by: Rasika Kale --- go/sqltypes/arithmetic.go | 10 +++------- go/sqltypes/arithmetic_test.go | 2 +- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/go/sqltypes/arithmetic.go b/go/sqltypes/arithmetic.go index 66f7b51b6e2..ef6914467e1 100644 --- a/go/sqltypes/arithmetic.go +++ b/go/sqltypes/arithmetic.go @@ -64,7 +64,7 @@ func Add(v1, v2 Value) (Value, error) { return castFromNumeric(lresult, lresult.typ), nil } -//Subtract takes two values and subtracts them +// Subtract takes two values and subtracts them func Subtract(v1, v2 Value) (Value, error) { if v1.IsNull() || v2.IsNull() { return NULL, nil @@ -486,8 +486,8 @@ func uintPlusIntWithError(v1 uint64, v2 int64) (numeric, error) { return numeric{}, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "BIGINT UNSIGNED value is out of range in %v + %v", v1, v2) } - //convert to int -> uint is because for numeric operators (such as + or -) - //where one of the operands is an unsigned integer, the result is unsigned by default. + // convert to int -> uint is because for numeric operators (such as + or -) + // where one of the operands is an unsigned integer, the result is unsigned by default. return uintPlusUintWithError(v1, uint64(v2)) } @@ -495,7 +495,6 @@ func uintMinusIntWithError(v1 uint64, v2 int64) (numeric, error) { if v1 < uint64(v2) { return numeric{}, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "BIGINT UNSIGNED value is out of range in %v - %v", v1, v2) } - return uintMinusUintWithError(v1, uint64(v2)) } @@ -503,7 +502,6 @@ func uintPlusUint(v1, v2 uint64) numeric { result := v1 + v2 if result < v2 { return numeric{typ: Float64, fval: float64(v1) + float64(v2)} - } return numeric{typ: Uint64, uval: result} } @@ -514,7 +512,6 @@ func uintPlusUintWithError(v1, v2 uint64) (numeric, error) { if result < v2 { return numeric{}, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "BIGINT UNSIGNED value is out of range in %v + %v", v1, v2) } - return numeric{typ: Uint64, uval: result}, nil } @@ -542,7 +539,6 @@ func floatMinusAny(v1 float64, v2 numeric) numeric { v2.fval = float64(v2.uval) } return numeric{typ: Float64, fval: v1 - v2.fval} - } func castFromNumeric(v numeric, resultType querypb.Type) Value { diff --git a/go/sqltypes/arithmetic_test.go b/go/sqltypes/arithmetic_test.go index 381421bf554..124cf14636f 100644 --- a/go/sqltypes/arithmetic_test.go +++ b/go/sqltypes/arithmetic_test.go @@ -36,7 +36,7 @@ func TestSubtract(t *testing.T) { err error }{{ - //All Nulls + // All Nulls v1: NULL, v2: NULL, out: NULL, From 9214c940cf5b875d3f46f5acb0c6003fe4279daf Mon Sep 17 00:00:00 2001 From: Rasika Kale Date: Tue, 27 Aug 2019 12:50:45 -0700 Subject: [PATCH 082/425] Fixed comment spacing and cleaned up code Signed-off-by: Rasika Kale --- go/sqltypes/arithmetic.go | 1 - go/sqltypes/arithmetic_test.go | 29 ++++------------------------- 2 files changed, 4 insertions(+), 26 deletions(-) diff --git a/go/sqltypes/arithmetic.go b/go/sqltypes/arithmetic.go index ef6914467e1..1b1875a579c 100644 --- a/go/sqltypes/arithmetic.go +++ b/go/sqltypes/arithmetic.go @@ -437,7 +437,6 @@ func prioritize(v1, v2 numeric) (altv1, altv2 numeric) { if v2.typ == Float64 { return v2, v1 } - } return v1, v2 } diff --git a/go/sqltypes/arithmetic_test.go b/go/sqltypes/arithmetic_test.go index 124cf14636f..98dcb8dbbaf 100644 --- a/go/sqltypes/arithmetic_test.go +++ b/go/sqltypes/arithmetic_test.go @@ -35,58 +35,48 @@ func TestSubtract(t *testing.T) { out Value err error }{{ - // All Nulls v1: NULL, v2: NULL, out: NULL, }, { - // First value null. v1: NewInt32(1), v2: NULL, out: NULL, }, { - // Second value null. v1: NULL, v2: NewInt32(1), out: NULL, }, { - // case with negative value v1: NewInt64(-1), v2: NewInt64(-2), out: NewInt64(1), }, { - // testing for int64 overflow with min negative value v1: NewInt64(math.MinInt64), v2: NewInt64(1), err: vterrors.New(vtrpcpb.Code_INVALID_ARGUMENT, "BIGINT value is out of range in -9223372036854775808 - 1"), }, { - v1: NewUint64(4), v2: NewInt64(5), err: vterrors.New(vtrpcpb.Code_INVALID_ARGUMENT, "BIGINT UNSIGNED value is out of range in 4 - 5"), }, { - v1: NewUint64(7), v2: NewInt64(5), out: NewUint64(2), }, { - v1: NewUint64(math.MaxUint64), v2: NewInt64(0), out: NewUint64(math.MaxUint64), }, { - // testing for int64 overflow v1: NewInt64(math.MinInt64), v2: NewUint64(0), err: vterrors.New(vtrpcpb.Code_INVALID_ARGUMENT, "BIGINT UNSIGNED value is out of range in 0 - -9223372036854775808"), }, { - v1: TestValue(VarChar, "c"), v2: NewInt64(1), out: NewInt64(-1), @@ -95,12 +85,12 @@ func TestSubtract(t *testing.T) { v2: TestValue(VarChar, "c"), out: NewUint64(1), }, { - + // testing for error for parsing float value to uint64 v1: TestValue(Uint64, "1.2"), v2: NewInt64(2), err: vterrors.New(vtrpcpb.Code_INVALID_ARGUMENT, "strconv.ParseUint: parsing \"1.2\": invalid syntax"), }, { - + // testing for error for parsing float value to uint64 v1: NewUint64(2), v2: TestValue(Uint64, "1.2"), err: vterrors.New(vtrpcpb.Code_INVALID_ARGUMENT, "strconv.ParseUint: parsing \"1.2\": invalid syntax"), @@ -115,7 +105,7 @@ func TestSubtract(t *testing.T) { v2: NewInt64(2), out: NewFloat64(-0.8), }, { - // testin for float subtraction: float - uint + // testing for float subtraction: float - uint v1: NewFloat64(1.2), v2: NewUint64(2), out: NewFloat64(-0.8), @@ -145,8 +135,7 @@ func TestAdd(t *testing.T) { out Value err error }{{ - - //All Nulls + // All Nulls v1: NULL, v2: NULL, out: NULL, @@ -161,24 +150,20 @@ func TestAdd(t *testing.T) { v2: NewInt32(1), out: NULL, }, { - // case with negatives v1: NewInt64(-1), v2: NewInt64(-2), out: NewInt64(-3), }, { - // testing for overflow int64 v1: NewInt64(math.MaxInt64), v2: NewUint64(2), err: vterrors.New(vtrpcpb.Code_INVALID_ARGUMENT, "BIGINT value is out of range in 2 + 9223372036854775807"), }, { - v1: NewInt64(-2), v2: NewUint64(1), out: NewUint64(math.MaxUint64), }, { - v1: NewInt64(math.MaxInt64), v2: NewInt64(-2), out: NewInt64(9223372036854775805), @@ -193,30 +178,25 @@ func TestAdd(t *testing.T) { v2: NewUint64(2), err: vterrors.New(vtrpcpb.Code_INVALID_ARGUMENT, "BIGINT UNSIGNED value is out of range in 18446744073709551615 + 2"), }, { - // int64 underflow v1: NewInt64(math.MinInt64), v2: NewInt64(-2), err: vterrors.New(vtrpcpb.Code_INVALID_ARGUMENT, "BIGINT value is out of range in -9223372036854775808 + -2"), }, { - // checking int64 max value can be returned v1: NewInt64(math.MaxInt64), v2: NewUint64(0), out: NewUint64(9223372036854775807), }, { - // testing whether uint64 max value can be returned v1: NewUint64(math.MaxUint64), v2: NewInt64(0), out: NewUint64(math.MaxUint64), }, { - v1: NewUint64(math.MaxInt64), v2: NewInt64(1), out: NewUint64(9223372036854775808), }, { - v1: NewUint64(1), v2: TestValue(VarChar, "c"), out: NewUint64(1), @@ -225,7 +205,6 @@ func TestAdd(t *testing.T) { v2: TestValue(VarChar, "1.2"), out: NewFloat64(2.2), }, { - v1: TestValue(Int64, "1.2"), v2: NewInt64(2), err: vterrors.New(vtrpcpb.Code_INVALID_ARGUMENT, "strconv.ParseInt: parsing \"1.2\": invalid syntax"), From 9afca1ca001d2e08ae40553a4c0b8e8ccba23341 Mon Sep 17 00:00:00 2001 From: Rasika Kale Date: Tue, 27 Aug 2019 12:53:23 -0700 Subject: [PATCH 083/425] Fixed error print statements Signed-off-by: Rasika Kale --- go/sqltypes/arithmetic_test.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/go/sqltypes/arithmetic_test.go b/go/sqltypes/arithmetic_test.go index 98dcb8dbbaf..4c9e56beddc 100644 --- a/go/sqltypes/arithmetic_test.go +++ b/go/sqltypes/arithmetic_test.go @@ -123,7 +123,7 @@ func TestSubtract(t *testing.T) { } if !reflect.DeepEqual(got, tcase.out) { - t.Errorf("Subtraction(%v, %v): %v, want %v", printValue(tcase.v1), printValue(tcase.v2), printValue(got), printValue(tcase.out)) + t.Errorf("Subtract(%v, %v): %v, want %v", printValue(tcase.v1), printValue(tcase.v2), printValue(got), printValue(tcase.out)) } } @@ -231,7 +231,7 @@ func TestAdd(t *testing.T) { } if !reflect.DeepEqual(got, tcase.out) { - t.Errorf("Addition(%v, %v): %v, want %v", printValue(tcase.v1), printValue(tcase.v2), printValue(got), printValue(tcase.out)) + t.Errorf("Add(%v, %v): %v, want %v", printValue(tcase.v1), printValue(tcase.v2), printValue(got), printValue(tcase.out)) } } @@ -287,7 +287,7 @@ func TestNullsafeAdd(t *testing.T) { got := NullsafeAdd(tcase.v1, tcase.v2, Int64) if !reflect.DeepEqual(got, tcase.out) { - t.Errorf("Add(%v, %v): %v, want %v", printValue(tcase.v1), printValue(tcase.v2), printValue(got), printValue(tcase.out)) + t.Errorf("NullsafeAdd(%v, %v): %v, want %v", printValue(tcase.v1), printValue(tcase.v2), printValue(got), printValue(tcase.out)) } } } From 8975b4749d5d6082c4d514d775298d4c334bfadf Mon Sep 17 00:00:00 2001 From: Rasika Kale Date: Tue, 27 Aug 2019 15:42:09 -0700 Subject: [PATCH 084/425] Implemented Multiply() along with appropricate functions in arithmetic.go - Added tests for Multiply() in arithmetic_test.go to cover code coverage - Implemented additional function floatTimesAny() to account for float values Signed-off-by: Rasika Kale --- go/sqltypes/arithmetic.go | 67 ++++++++++++++++++++++++- go/sqltypes/arithmetic_test.go | 90 ++++++++++++++++++++++++++++++++++ 2 files changed, 156 insertions(+), 1 deletion(-) diff --git a/go/sqltypes/arithmetic.go b/go/sqltypes/arithmetic.go index 1b1875a579c..c448af3263f 100644 --- a/go/sqltypes/arithmetic.go +++ b/go/sqltypes/arithmetic.go @@ -88,6 +88,28 @@ func Subtract(v1, v2 Value) (Value, error) { return castFromNumeric(lresult, lresult.typ), nil } +// Multiply takes two values and multiplies it together +func Multiply(v1, v2 Value) (Value, error) { + if v1.IsNull() || v2.IsNull() { + return NULL, nil + } + + lv1, err := newNumeric(v1) + if err != nil { + return NULL, err + } + lv2, err := newNumeric(v2) + if err != nil { + return NULL, err + } + lresult, err := multiplyNumericWithError(lv1, lv2) + if err != nil { + return NULL, err + } + + return castFromNumeric(lresult, lresult.typ), nil +} + // NullsafeAdd adds two Values in a null-safe manner. A null value // is treated as 0. If both values are null, then a null is returned. // If both values are not null, a numeric value is built @@ -403,7 +425,6 @@ func addNumericWithError(v1, v2 numeric) (numeric, error) { return floatPlusAny(v1.fval, v2), nil } panic("unreachable") - } func subtractNumericWithError(v1, v2 numeric) (numeric, error) { @@ -422,7 +443,24 @@ func subtractNumericWithError(v1, v2 numeric) (numeric, error) { return floatMinusAny(v1.fval, v2), nil } panic("unreachable") +} +func multiplyNumericWithError(v1, v2 numeric) (numeric, error) { + v1, v2 = prioritize(v1, v2) + switch v1.typ { + case Int64: + return intTimesIntWithError(v1.ival, v2.ival) + case Uint64: + switch v2.typ { + case Int64: + return uintTimesIntWithError(v1.uval, v2.ival) + case Uint64: + return uintTimesUintWithError(v1.uval, v2.uval) + } + case Float64: + return floatTimesAny(v1.fval, v2), nil + } + panic("unreachable") } // prioritize reorders the input parameters @@ -472,6 +510,15 @@ func intMinusIntWithError(v1, v2 int64) (numeric, error) { return numeric{typ: Int64, ival: result}, nil } +func intTimesIntWithError(v1, v2 int64) (numeric, error) { + result := v1 * v2 + if v1 >= math.MaxInt64 && v2 > 1 || v2 >= math.MaxInt64 && v1 > 1 || v1 <= math.MinInt64 && v2 > 1 || v2 <= math.MinInt64 && v1 > 1 { + return numeric{}, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "BIGINT value is out of range in %v * %v", v1, v2) + } + + return numeric{typ: Int64, ival: result}, nil +} + func uintPlusInt(v1 uint64, v2 int64) numeric { return uintPlusUint(v1, uint64(v2)) } @@ -497,6 +544,10 @@ func uintMinusIntWithError(v1 uint64, v2 int64) (numeric, error) { return uintMinusUintWithError(v1, uint64(v2)) } +func uintTimesIntWithError(v1 uint64, v2 int64) (numeric, error) { + return uintTimesUintWithError(v1, uint64(v2)) +} + func uintPlusUint(v1, v2 uint64) numeric { result := v1 + v2 if result < v2 { @@ -516,7 +567,11 @@ func uintPlusUintWithError(v1, v2 uint64) (numeric, error) { func uintMinusUintWithError(v1, v2 uint64) (numeric, error) { result := v1 - v2 + return numeric{typ: Uint64, uval: result}, nil +} +func uintTimesUintWithError(v1, v2 uint64) (numeric, error) { + result := v1 * v2 return numeric{typ: Uint64, uval: result}, nil } @@ -540,6 +595,16 @@ func floatMinusAny(v1 float64, v2 numeric) numeric { return numeric{typ: Float64, fval: v1 - v2.fval} } +func floatTimesAny(v1 float64, v2 numeric) numeric { + switch v2.typ { + case Int64: + v2.fval = float64(v2.ival) + case Uint64: + v2.fval = float64(v2.uval) + } + return numeric{typ: Float64, fval: v1 * v2.fval} +} + func castFromNumeric(v numeric, resultType querypb.Type) Value { switch { case IsSigned(resultType): diff --git a/go/sqltypes/arithmetic_test.go b/go/sqltypes/arithmetic_test.go index 4c9e56beddc..23d8687b0b1 100644 --- a/go/sqltypes/arithmetic_test.go +++ b/go/sqltypes/arithmetic_test.go @@ -29,6 +29,96 @@ import ( "vitess.io/vitess/go/vt/vterrors" ) +func TestMultiply(t *testing.T) { + tcases := []struct { + v1, v2 Value + out Value + err error + }{{ + + //All Nulls + v1: NULL, + v2: NULL, + out: NULL, + }, { + + // First value null. + v1: NewInt32(1), + v2: NULL, + out: NULL, + }, { + + // Second value null. + v1: NULL, + v2: NewInt32(1), + out: NULL, + }, { + + // case with negative value + v1: NewInt64(-1), + v2: NewInt64(-2), + out: NewInt64(2), + }, { + + // testing for int64 overflow with min negative value + v1: NewInt64(math.MinInt64), + v2: NewInt64(1), + out: NewInt64(math.MinInt64), + }, { + // testing for error in types + v1: TestValue(Int64, "1.2"), + v2: NewInt64(2), + err: vterrors.New(vtrpcpb.Code_INVALID_ARGUMENT, "strconv.ParseInt: parsing \"1.2\": invalid syntax"), + }, { + // testing for error in types + v1: NewInt64(2), + v2: TestValue(Int64, "1.2"), + err: vterrors.New(vtrpcpb.Code_INVALID_ARGUMENT, "strconv.ParseInt: parsing \"1.2\": invalid syntax"), + }, { + // testing for uint*int + v1: NewUint64(4), + v2: NewInt64(5), + out: NewUint64(20), + }, { + // testing for uint*uint + v1: NewUint64(1), + v2: NewUint64(2), + out: NewUint64(2), + }, { + // testing for float64*int64 + v1: TestValue(Float64, "1.2"), + v2: NewInt64(-2), + out: NewFloat64(-2.4), + }, { + // testing for float64*uint64 + v1: TestValue(Float64, "1.2"), + v2: NewUint64(2), + out: NewFloat64(2.4), + }, { + // testing for overflow of int64 + v1: NewInt64(math.MaxInt64), + v2: NewInt64(2), + err: vterrors.New(vtrpcpb.Code_INVALID_ARGUMENT, "BIGINT value is out of range in 9223372036854775807 * 2"), + }} + + for _, tcase := range tcases { + + got, err := Multiply(tcase.v1, tcase.v2) + + if !vterrors.Equals(err, tcase.err) { + t.Errorf("Multiply(%v, %v) error: %v, want %v", printValue(tcase.v1), printValue(tcase.v2), vterrors.Print(err), vterrors.Print(tcase.err)) + } + if tcase.err != nil { + continue + } + + if !reflect.DeepEqual(got, tcase.out) { + t.Errorf("Multiply(%v, %v): %v, want %v", printValue(tcase.v1), printValue(tcase.v2), printValue(got), printValue(tcase.out)) + } + } + +} + func TestSubtract(t *testing.T) { tcases := []struct { v1, v2 Value From ba19e18573a21168a070b6ae89454560983fe0de Mon Sep 17 00:00:00 2001 From: Rasika Kale Date: Wed, 28 Aug 2019 12:58:43 -0700 Subject: [PATCH 085/425] Fixed runtime error in Multiply() Signed-off-by: Rasika Kale --- go/sqltypes/arithmetic.go | 3 +++ go/sqltypes/arithmetic_test.go | 9 +++++++++ 2 files changed, 12 insertions(+) diff --git a/go/sqltypes/arithmetic.go b/go/sqltypes/arithmetic.go index c448af3263f..06b702f1a62 100644 --- a/go/sqltypes/arithmetic.go +++ b/go/sqltypes/arithmetic.go @@ -572,6 +572,9 @@ func uintMinusUintWithError(v1, v2 uint64) (numeric, error) { func uintTimesUintWithError(v1, v2 uint64) (numeric, error) { result := v1 * v2 + if v1 >= math.MaxUint64 && v2 > 1 || v2 >= math.MaxUint64 && v1 > 1 { + return numeric{}, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "BIGINT UNSIGNED value is out of range in %v * %v", v1, v2) + } return numeric{typ: Uint64, uval: result}, nil } diff --git a/go/sqltypes/arithmetic_test.go b/go/sqltypes/arithmetic_test.go index 23d8687b0b1..3af89d2c5f2 100644 --- a/go/sqltypes/arithmetic_test.go +++ b/go/sqltypes/arithmetic_test.go @@ -99,6 +99,15 @@ func TestMultiply(t *testing.T) { v1: NewInt64(math.MaxInt64), v2: NewInt64(2), err: vterrors.New(vtrpcpb.Code_INVALID_ARGUMENT, "BIGINT value is out of range in 9223372036854775807 * 2"), + }, { + // testing for underflow of uint64*max.uint64 + v1: NewUint64(2), + v2: NewUint64(math.MaxUint64), + err: vterrors.New(vtrpcpb.Code_INVALID_ARGUMENT, "BIGINT UNSIGNED value is out of range in 2 * 18446744073709551615"), + }, { + v1: NewUint64(math.MaxUint64), + v2: NewUint64(1), + out: NewUint64(math.MaxUint64), }} for _, tcase := range tcases { From e2558a66d5dadf90e950264f53a32c9f28fb8f45 Mon Sep 17 00:00:00 2001 From: Rasika Kale Date: Fri, 30 Aug 2019 16:43:12 -0700 Subject: [PATCH 086/425] Fixed error checking for overflow of integer multiplication Signed-off-by: Rasika Kale --- go/sqltypes/arithmetic.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/go/sqltypes/arithmetic.go b/go/sqltypes/arithmetic.go index 06b702f1a62..9af23dd36ce 100644 --- a/go/sqltypes/arithmetic.go +++ b/go/sqltypes/arithmetic.go @@ -512,10 +512,9 @@ func intMinusIntWithError(v1, v2 int64) (numeric, error) { func intTimesIntWithError(v1, v2 int64) (numeric, error) { result := v1 * v2 - if v1 >= math.MaxInt64 && v2 > 1 || v2 >= math.MaxInt64 && v1 > 1 || v1 <= math.MinInt64 && v2 > 1 || v2 <= math.MinInt64 && v1 > 1 { + if v1 != 0 && result/v1 != v2 { return numeric{}, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "BIGINT value is out of range in %v * %v", v1, v2) } - return numeric{typ: Int64, ival: result}, nil } From 52b0974f0e958cf176260ae084add62cb47ed5fd Mon Sep 17 00:00:00 2001 From: Rasika Kale Date: Tue, 3 Sep 2019 10:48:49 -0700 Subject: [PATCH 087/425] Changed error checking in uintTimesUintWithError() in arithmetic.go Signed-off-by: Rasika Kale --- go/sqltypes/arithmetic.go | 2 +- go/sqltypes/arithmetic_test.go | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go/sqltypes/arithmetic.go b/go/sqltypes/arithmetic.go index 9af23dd36ce..3abb7974da6 100644 --- a/go/sqltypes/arithmetic.go +++ b/go/sqltypes/arithmetic.go @@ -571,7 +571,7 @@ func uintMinusUintWithError(v1, v2 uint64) (numeric, error) { func uintTimesUintWithError(v1, v2 uint64) (numeric, error) { result := v1 * v2 - if v1 >= math.MaxUint64 && v2 > 1 || v2 >= math.MaxUint64 && v1 > 1 { + if result < v2 { return numeric{}, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "BIGINT UNSIGNED value is out of range in %v * %v", v1, v2) } return numeric{typ: Uint64, uval: result}, nil diff --git a/go/sqltypes/arithmetic_test.go b/go/sqltypes/arithmetic_test.go index 3af89d2c5f2..648f673320f 100644 --- a/go/sqltypes/arithmetic_test.go +++ b/go/sqltypes/arithmetic_test.go @@ -101,9 +101,9 @@ func TestMultiply(t *testing.T) { err: vterrors.New(vtrpcpb.Code_INVALID_ARGUMENT, "BIGINT value is out of range in 9223372036854775807 * 2"), }, { // testing for underflow of uint64*max.uint64 - v1: NewUint64(2), + v1: NewInt64(2), v2: NewUint64(math.MaxUint64), - err: vterrors.New(vtrpcpb.Code_INVALID_ARGUMENT, "BIGINT UNSIGNED value is out of range in 2 * 18446744073709551615"), + err: vterrors.New(vtrpcpb.Code_INVALID_ARGUMENT, "BIGINT UNSIGNED value is out of range in 18446744073709551615 * 2"), }, { v1: NewUint64(math.MaxUint64), v2: NewUint64(1), From bdb6bf83206656ec24ddba75bf20e575ad98b1cc Mon Sep 17 00:00:00 2001 From: Rasika Kale Date: Fri, 6 Sep 2019 10:17:01 -0700 Subject: [PATCH 088/425] Fixed error checking for uintTimesIntWithError() in arithmetic.go - Added more tests in TestMultiply() in arithmetic_test.go to increase code coverage Signed-off-by: Rasika Kale --- go/sqltypes/arithmetic.go | 3 +++ go/sqltypes/arithmetic_test.go | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/go/sqltypes/arithmetic.go b/go/sqltypes/arithmetic.go index 3abb7974da6..4d65fbb2a4b 100644 --- a/go/sqltypes/arithmetic.go +++ b/go/sqltypes/arithmetic.go @@ -544,6 +544,9 @@ func uintMinusIntWithError(v1 uint64, v2 int64) (numeric, error) { } func uintTimesIntWithError(v1 uint64, v2 int64) (numeric, error) { + if v2 < 0 || v1 >= math.MaxUint64 && v2 > 0 { + return numeric{}, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "BIGINT UNSIGNED value is out of range in %v * %v", v1, v2) + } return uintTimesUintWithError(v1, uint64(v2)) } diff --git a/go/sqltypes/arithmetic_test.go b/go/sqltypes/arithmetic_test.go index 648f673320f..6b811d70735 100644 --- a/go/sqltypes/arithmetic_test.go +++ b/go/sqltypes/arithmetic_test.go @@ -108,6 +108,10 @@ func TestMultiply(t *testing.T) { v1: NewUint64(math.MaxUint64), v2: NewUint64(1), out: NewUint64(math.MaxUint64), + }, { + v1: NewUint64(2), + v2: NewUint64(math.MaxUint64), + err: vterrors.New(vtrpcpb.Code_INVALID_ARGUMENT, "BIGINT UNSIGNED value is out of range in 2 * 18446744073709551615"), }} for _, tcase := range tcases { From ffd573a6d6bb2f11b0a44a5c71f9acee1ebd116c Mon Sep 17 00:00:00 2001 From: Rasika Kale Date: Fri, 6 Sep 2019 15:59:34 -0700 Subject: [PATCH 089/425] Completed error checking for uintTimesIntWithError() - Added more tests in arithmetic_test.go to confirm code is covered and error checking works Signed-off-by: Rasika Kale --- go/sqltypes/arithmetic.go | 2 +- go/sqltypes/arithmetic_test.go | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/go/sqltypes/arithmetic.go b/go/sqltypes/arithmetic.go index 4d65fbb2a4b..dcbc1a2380b 100644 --- a/go/sqltypes/arithmetic.go +++ b/go/sqltypes/arithmetic.go @@ -544,7 +544,7 @@ func uintMinusIntWithError(v1 uint64, v2 int64) (numeric, error) { } func uintTimesIntWithError(v1 uint64, v2 int64) (numeric, error) { - if v2 < 0 || v1 >= math.MaxUint64 && v2 > 0 { + if v2 < 0 || v1 >= math.MaxInt64 && v2 > 2 || int64(v1) < 0 { return numeric{}, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "BIGINT UNSIGNED value is out of range in %v * %v", v1, v2) } return uintTimesUintWithError(v1, uint64(v2)) diff --git a/go/sqltypes/arithmetic_test.go b/go/sqltypes/arithmetic_test.go index 6b811d70735..857b6b715ce 100644 --- a/go/sqltypes/arithmetic_test.go +++ b/go/sqltypes/arithmetic_test.go @@ -35,31 +35,26 @@ func TestMultiply(t *testing.T) { out Value err error }{{ - //All Nulls v1: NULL, v2: NULL, out: NULL, }, { - // First value null. v1: NewInt32(1), v2: NULL, out: NULL, }, { - // Second value null. v1: NULL, v2: NewInt32(1), out: NULL, }, { - // case with negative value v1: NewInt64(-1), v2: NewInt64(-2), out: NewInt64(2), }, { - // testing for int64 overflow with min negative value v1: NewInt64(math.MinInt64), v2: NewInt64(1), @@ -112,6 +107,11 @@ func TestMultiply(t *testing.T) { v1: NewUint64(2), v2: NewUint64(math.MaxUint64), err: vterrors.New(vtrpcpb.Code_INVALID_ARGUMENT, "BIGINT UNSIGNED value is out of range in 2 * 18446744073709551615"), + }, { + //Checking whether maxInt value can be passed as uint value + v1: NewUint64(math.MaxInt64), + v2: NewInt64(3), + err: vterrors.New(vtrpcpb.Code_INVALID_ARGUMENT, "BIGINT UNSIGNED value is out of range in 9223372036854775807 * 3"), }} for _, tcase := range tcases { From cb9c05ec56616a0f0feaa6b5696481ce8687b280 Mon Sep 17 00:00:00 2001 From: Rasika Kale Date: Tue, 10 Sep 2019 17:01:05 -0700 Subject: [PATCH 090/425] Fixed error checking for multiplication of uint*int and uint*int Signed-off-by: Rasika Kale --- go/sqltypes/arithmetic.go | 4 ++-- go/sqltypes/arithmetic_test.go | 4 ---- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/go/sqltypes/arithmetic.go b/go/sqltypes/arithmetic.go index dcbc1a2380b..7521dfd3fb4 100644 --- a/go/sqltypes/arithmetic.go +++ b/go/sqltypes/arithmetic.go @@ -544,7 +544,7 @@ func uintMinusIntWithError(v1 uint64, v2 int64) (numeric, error) { } func uintTimesIntWithError(v1 uint64, v2 int64) (numeric, error) { - if v2 < 0 || v1 >= math.MaxInt64 && v2 > 2 || int64(v1) < 0 { + if v2 < 0 || int64(v1) < 0 { return numeric{}, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "BIGINT UNSIGNED value is out of range in %v * %v", v1, v2) } return uintTimesUintWithError(v1, uint64(v2)) @@ -574,7 +574,7 @@ func uintMinusUintWithError(v1, v2 uint64) (numeric, error) { func uintTimesUintWithError(v1, v2 uint64) (numeric, error) { result := v1 * v2 - if result < v2 { + if result < v2 || result < v1 { return numeric{}, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "BIGINT UNSIGNED value is out of range in %v * %v", v1, v2) } return numeric{typ: Uint64, uval: result}, nil diff --git a/go/sqltypes/arithmetic_test.go b/go/sqltypes/arithmetic_test.go index 857b6b715ce..aaecf98f328 100644 --- a/go/sqltypes/arithmetic_test.go +++ b/go/sqltypes/arithmetic_test.go @@ -103,10 +103,6 @@ func TestMultiply(t *testing.T) { v1: NewUint64(math.MaxUint64), v2: NewUint64(1), out: NewUint64(math.MaxUint64), - }, { - v1: NewUint64(2), - v2: NewUint64(math.MaxUint64), - err: vterrors.New(vtrpcpb.Code_INVALID_ARGUMENT, "BIGINT UNSIGNED value is out of range in 2 * 18446744073709551615"), }, { //Checking whether maxInt value can be passed as uint value v1: NewUint64(math.MaxInt64), From 0cf6371f330682a9011c16b25922dc8b5e0cf3f0 Mon Sep 17 00:00:00 2001 From: Morgan Tocker Date: Fri, 6 Sep 2019 14:57:28 -0600 Subject: [PATCH 091/425] fix docker pre-fetch of go modules Signed-off-by: Morgan Tocker --- docker/bootstrap/Dockerfile.common | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/docker/bootstrap/Dockerfile.common b/docker/bootstrap/Dockerfile.common index 01d461228db..8288a479eea 100644 --- a/docker/bootstrap/Dockerfile.common +++ b/docker/bootstrap/Dockerfile.common @@ -52,19 +52,21 @@ ENV USER vitess ENV GO111MODULE on # Copy files needed for bootstrap -COPY bootstrap.sh dev.env build.env /vt/src/vitess.io/vitess/ +COPY bootstrap.sh dev.env build.env go.mod go.sum /vt/src/vitess.io/vitess/ COPY config /vt/src/vitess.io/vitess/config COPY third_party /vt/src/vitess.io/vitess/third_party COPY tools /vt/src/vitess.io/vitess/tools COPY travis /vt/src/vitess.io/vitess/travis -RUN go mod download - # Create vitess user RUN groupadd -r vitess && useradd -r -g vitess vitess && \ mkdir -p /vt/vtdataroot /home/vitess && \ chown -R vitess:vitess /vt /home/vitess +# Download vendored Go dependencies +RUN cd /vt/src/vitess.io/vitess && \ + su vitess -c "/usr/local/go/bin/go mod download" + # Create mount point for actual data (e.g. MySQL data dir) VOLUME /vt/vtdataroot From c5c67add62c8ab4ec091777e13592654d683ff13 Mon Sep 17 00:00:00 2001 From: Yufei Chen Date: Fri, 6 Sep 2019 16:17:54 +1000 Subject: [PATCH 092/425] making sure fresh state works before turning off query service during a split Signed-off-by: Yufei Chen --- go/vt/wrangler/keyspace.go | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/go/vt/wrangler/keyspace.go b/go/vt/wrangler/keyspace.go index a95672f227f..b31f20d83c2 100644 --- a/go/vt/wrangler/keyspace.go +++ b/go/vt/wrangler/keyspace.go @@ -641,11 +641,22 @@ func (wr *Wrangler) masterMigrateServedType(ctx context.Context, keyspace string }() // Phase 1 + // - check topology service can successfully refresh both source and target master // - switch the source shards to read-only by disabling query service // - gather all replication points // - wait for filtered replication to catch up // - mark source shards as frozen event.DispatchUpdate(ev, "disabling query service on all source masters") + // making sure the refreshMaster on both source and target are working before turning off query service on source + if err := wr.refreshMasters(ctx, sourceShards); err != nil { + wr.cancelMasterMigrateServedTypes(ctx, keyspace, sourceShards) + return err + } + if err := wr.refreshMasters(ctx, destinationShards); err != nil { + wr.cancelMasterMigrateServedTypes(ctx, keyspace, sourceShards) + return err + } + if err := wr.updateShardRecords(ctx, keyspace, sourceShards, nil, topodatapb.TabletType_MASTER, true, false); err != nil { wr.cancelMasterMigrateServedTypes(ctx, keyspace, sourceShards) return err From ea327d7279e73fb5a9ecdd4365dda49613e6bd06 Mon Sep 17 00:00:00 2001 From: Morgan Tocker Date: Thu, 5 Sep 2019 09:19:22 -0600 Subject: [PATCH 093/425] Improve errror when capabiility detect fails ALso removes unused capabiltities code to silence staticcheck warning. Signed-off-by: Morgan Tocker --- go/vt/mysqlctl/capabilityset.go | 24 ------------------------ go/vt/mysqlctl/mysqld.go | 33 ++++++++++++++++++++++++++++++--- 2 files changed, 30 insertions(+), 27 deletions(-) diff --git a/go/vt/mysqlctl/capabilityset.go b/go/vt/mysqlctl/capabilityset.go index 68319450f53..17bb251a83b 100644 --- a/go/vt/mysqlctl/capabilityset.go +++ b/go/vt/mysqlctl/capabilityset.go @@ -46,24 +46,6 @@ func (c *capabilitySet) hasMySQLUpgradeInServer() bool { func (c *capabilitySet) hasInitializeInServer() bool { return c.isMySQLLike() && c.version.atLeast(serverVersion{Major: 5, Minor: 7, Patch: 0}) } -func (c *capabilitySet) hasMySQLxEnabledByDefault() bool { - return c.isMySQLLike() && c.version.atLeast(serverVersion{Major: 8, Minor: 0, Patch: 11}) -} -func (c *capabilitySet) hasPersistConfig() bool { - return c.isMySQLLike() && c.version.atLeast(serverVersion{Major: 8, Minor: 0, Patch: 0}) -} -func (c *capabilitySet) hasShutdownCommand() bool { - return (c.isMySQLLike() && c.version.atLeast(serverVersion{Major: 5, Minor: 7, Patch: 9})) || (c.isMariaDB() && c.version.atLeast(serverVersion{Major: 10, Minor: 0, Patch: 4})) -} -func (c *capabilitySet) hasBackupLocks() bool { - return c.isMySQLLike() && c.version.atLeast(serverVersion{Major: 8, Minor: 0, Patch: 0}) -} -func (c *capabilitySet) hasDefaultUft8mb4() bool { - return c.isMySQLLike() && c.version.atLeast(serverVersion{Major: 8, Minor: 0, Patch: 0}) -} -func (c *capabilitySet) hasSemiSyncEnabledByDefault() bool { - return c.isMariaDB() && c.version.atLeast(serverVersion{Major: 10, Minor: 3, Patch: 3}) -} // IsMySQLLike tests if the server is either MySQL // or Percona Server. At least currently, Vitess doesn't @@ -71,9 +53,3 @@ func (c *capabilitySet) hasSemiSyncEnabledByDefault() bool { func (c *capabilitySet) isMySQLLike() bool { return c.flavor == flavorMySQL || c.flavor == flavorPercona } - -// IsMariaDB tests if the server is MariaDB. -// IsMySQLLike() and IsMariaDB() are mutually exclusive -func (c *capabilitySet) isMariaDB() bool { - return c.flavor == flavorMariaDB -} diff --git a/go/vt/mysqlctl/mysqld.go b/go/vt/mysqlctl/mysqld.go index e99f63ec33d..139b0974277 100644 --- a/go/vt/mysqlctl/mysqld.go +++ b/go/vt/mysqlctl/mysqld.go @@ -115,13 +115,40 @@ func NewMysqld(dbcfgs *dbconfigs.DBConfigs) *Mysqld { version, getErr := getVersionString() f, v, err := parseVersionString(version) - // Fallback if required + /* + By default Vitess searches in vtenv.VtMysqlRoot() for a mysqld binary. + This is usually the VT_MYSQL_ROOT env, but if it is unset or empty, it + will substitute VtRoot(). See go/vt/env/env.go. + + A number of subdirs inside vtenv.VtMysqlRoot() will be searched, see + func binaryPath() for context. If no mysqld binary is found (possibly + because it is in a container or both VT_MYSQL_ROOT and VTROOT are set + incorrectly), there will be a fallback to using the MYSQL_FLAVOR env + variable. + + If MYSQL_FLAVOR is not defined, there will be a panic. + + Note: relying on MySQL_FLAVOR is not recommended, since for historical + purposes "MySQL56" actually means MySQL 5.7, which is a very strange + behavior. + */ + if getErr != nil || err != nil { f, v, err = getVersionFromEnv() if err != nil { - panic("could not detect version from mysqld --version or MYSQL_FLAVOR") + vtenvMysqlRoot, _ := vtenv.VtMysqlRoot() + message := fmt.Sprintf(`could not auto-detect MySQL version. You may need to set VT_MYSQL_ROOT so a mysqld binary can be found, or set the environment variable MYSQL_FLAVOR if mysqld is not available locally: + VT_MYSQL_ROOT: %s + VTROOT: %s + vtenv.VtMysqlRoot(): %s + MYSQL_FLAVOR: %s + `, + os.Getenv("VT_MYSQL_ROOT"), + os.Getenv("VTROOT"), + vtenvMysqlRoot, + os.Getenv("MYSQL_FLAVOR")) + panic(message) } - } log.Infof("Using flavor: %v, version: %v", f, v) From 297345fc590aa25e23fd637222833503bf960b80 Mon Sep 17 00:00:00 2001 From: Sugu Sougoumarane Date: Mon, 9 Sep 2019 16:59:06 -0700 Subject: [PATCH 094/425] maintainers: add morgo and systay Signed-off-by: Sugu Sougoumarane --- MAINTAINERS.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/MAINTAINERS.md b/MAINTAINERS.md index 7b527586cb0..911b58cfd67 100644 --- a/MAINTAINERS.md +++ b/MAINTAINERS.md @@ -2,6 +2,7 @@ This page lists all active maintainers and their areas of expertise. This can be The following is the full list, alphabetically ordered. +* Andres Taylor ([systay](https://github.com/systay)) antaylor@squareup.com * Dan Kozlowski ([dkhenry](https://github.com/dkhenry)) koz@planetscale.com * David Weitzman ([dweitzman](https://github.com/dweitzman)) dweitzman@pinterest.com * Deepthi Sigireddi ([deepthi](https://github.com/deepthi)) deepthi@planetscale.com @@ -11,22 +12,23 @@ The following is the full list, alphabetically ordered. * Leo X. Lin ([leoxlin](https://github.com/leoxlin)) llin@hubspot.com * Michael Demmer ([demmer](https://github.com/demmer)) mdemmer@slack-corp.com * Michael Pawliszyn ([mpawliszyn](https://github.com/mpawliszyn)) mikepaw@squareup.com +* Morgan Tocker ([morgo](https://github.com/morgo)) morgan@planetscale.com * Rafael Chacon ([rafael](https://github.com/rafael)) rchacon@slack-corp.com * Sugu Sougoumarane ([sougou](https://github.com/sougou)) sougou@planetscale.com ## Areas of expertise ### General Vitess -sougou, demmer, rafael, dweitzman, tirsen +sougou, demmer, rafael, dweitzman, tirsen, morgo ### Builds -dkhenry +dkhenry, morgo ### Resharding -sougou, rafael, tirsen, dweitzman +sougou, rafael, tirsen, dweitzman, systay ### Parser -sougou, dweitzman, deepthi +sougou, dweitzman, deepthi, systay ### Backups deepthi, rafael From 8278be029e0f2453613e48b8d2ad3ac9826fd478 Mon Sep 17 00:00:00 2001 From: Anthony Yeh Date: Thu, 12 Sep 2019 20:37:04 +0000 Subject: [PATCH 095/425] docker/bootstrap: Add back VT_MYSQL_ROOT. Without this, all tests fail because Vitess can't find mysqld: failed init mysql: mysqld not found in any of /vt/{sbin,bin,libexec,scripts} Signed-off-by: Anthony Yeh --- docker/bootstrap/Dockerfile.common | 1 + 1 file changed, 1 insertion(+) diff --git a/docker/bootstrap/Dockerfile.common b/docker/bootstrap/Dockerfile.common index 8288a479eea..4b6a21beb49 100644 --- a/docker/bootstrap/Dockerfile.common +++ b/docker/bootstrap/Dockerfile.common @@ -47,6 +47,7 @@ ENV VTPORTSTART 15000 ENV PYTHONPATH $VTROOT/dist/grpc/usr/local/lib/python2.7/site-packages:$VTROOT/dist/py-mock-1.0.1/lib/python2.7/site-packages:$VTROOT/py-vtdb:$VTROOT/dist/selenium/lib/python2.7/site-packages ENV GOBIN $VTROOT/bin ENV PATH $VTROOT/bin:$VTROOT/dist/maven/bin:$VTROOT/dist/chromedriver:$PATH +ENV VT_MYSQL_ROOT /usr ENV PKG_CONFIG_PATH $VTROOT/lib ENV USER vitess ENV GO111MODULE on From f97a82bfe7a37f3a2cca2454f645fb2333050e48 Mon Sep 17 00:00:00 2001 From: Anthony Yeh Date: Thu, 12 Sep 2019 21:09:38 +0000 Subject: [PATCH 096/425] Use Go modules to run goyacc. Since all Go tools have been removed from bootstrap. Signed-off-by: Anthony Yeh --- go/vt/sqlparser/Makefile | 2 +- tools/check_make_parser.sh | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/go/vt/sqlparser/Makefile b/go/vt/sqlparser/Makefile index 215f422e624..a4ad16ce2bf 100644 --- a/go/vt/sqlparser/Makefile +++ b/go/vt/sqlparser/Makefile @@ -15,7 +15,7 @@ MAKEFLAGS = -s sql.go: sql.y - goyacc -o sql.go sql.y + go run golang.org/x/tools/cmd/goyacc -o sql.go sql.y gofmt -w sql.go clean: diff --git a/tools/check_make_parser.sh b/tools/check_make_parser.sh index 139e18199a8..d28d4f18f09 100755 --- a/tools/check_make_parser.sh +++ b/tools/check_make_parser.sh @@ -9,6 +9,7 @@ CUR="sql.go" TMP="/tmp/sql.$$.go" +set -e if ! cd go/vt/sqlparser/ ; then echo "ERROR: $0 must be run in the root project directory" @@ -16,7 +17,7 @@ if ! cd go/vt/sqlparser/ ; then fi mv $CUR $TMP -output=`goyacc -o $CUR sql.y` +output=$(go run golang.org/x/tools/cmd/goyacc -o $CUR sql.y) if [ -n "$output" ]; then echo "Expected empty output from goyacc, got:" From cf020fbfca188bc5f7be9714a5144b90c3f65471 Mon Sep 17 00:00:00 2001 From: deepthi Date: Thu, 12 Sep 2019 20:18:11 -0700 Subject: [PATCH 097/425] fix flaky test Signed-off-by: deepthi --- .../vttablet/tabletmanager/vreplication/replicator_plan_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go/vt/vttablet/tabletmanager/vreplication/replicator_plan_test.go b/go/vt/vttablet/tabletmanager/vreplication/replicator_plan_test.go index 5dfdb7b0072..a4a00afbcf3 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/replicator_plan_test.go +++ b/go/vt/vttablet/tabletmanager/vreplication/replicator_plan_test.go @@ -671,7 +671,7 @@ func TestBuildPlayerPlanNoDup(t *testing.T) { }}, } _, err := buildReplicatorPlan(input, tableKeys, nil) - assert.EqualError(t, err, "more than one target for source table t: t1 and t2") + assert.Contains(t, err.Error(), "more than one target for source table t:") } func TestBuildPlayerPlanExclude(t *testing.T) { From 91e4977e0d47c8719dbb71fbabe5cea60a4546e8 Mon Sep 17 00:00:00 2001 From: deepthi Date: Thu, 12 Sep 2019 21:07:46 -0700 Subject: [PATCH 098/425] fix unit_race failures Signed-off-by: deepthi --- go/mysql/fakesqldb/server.go | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/go/mysql/fakesqldb/server.go b/go/mysql/fakesqldb/server.go index 14d9869095b..2d8f079dd02 100644 --- a/go/mysql/fakesqldb/server.go +++ b/go/mysql/fakesqldb/server.go @@ -307,12 +307,8 @@ func (db *DB) ConnectionClosed(c *mysql.Conn) { db.mu.Lock() defer db.mu.Unlock() - if db.t != nil { - db.t.Logf("ConnectionClosed(%v): client %v", db.name, c.ConnectionID) - } - if _, ok := db.connections[c.ConnectionID]; !ok { - db.t.Fatalf("BUG: Cannot delete connection from list of open connections because it is not registered. ID: %v Conn: %v", c.ConnectionID, c) + panic(fmt.Errorf("BUG: Cannot delete connection from list of open connections because it is not registered. ID: %v Conn: %v", c.ConnectionID, c)) } delete(db.connections, c.ConnectionID) } From 90d3b8a8d7f58db5dad86e3ca9fbcbc04a7f66e6 Mon Sep 17 00:00:00 2001 From: deepthi Date: Fri, 13 Sep 2019 14:24:23 -0700 Subject: [PATCH 099/425] defer event update, only make a copy of tablet if we are changing it, use one tmc for all calls to RefreshState Signed-off-by: deepthi --- go/vt/vtcombo/tablet_map.go | 14 ++++++++------ .../vttablet/tabletmanager/healthcheck_test.go | 5 ++++- .../tabletmanager/rpc_external_reparent.go | 18 +++++++++++------- 3 files changed, 23 insertions(+), 14 deletions(-) diff --git a/go/vt/vtcombo/tablet_map.go b/go/vt/vtcombo/tablet_map.go index a4cd2baab50..fac8ab155a2 100644 --- a/go/vt/vtcombo/tablet_map.go +++ b/go/vt/vtcombo/tablet_map.go @@ -111,6 +111,14 @@ func InitTabletMap(ts *topo.Server, tpb *vttestpb.VTTestTopology, mysqld mysqlct ctx := context.Background() + // Register the tablet manager client factory for tablet manager + // Do this before any tablets are created so that they respect the protocol, + // otherwise it defaults to grpc + tmclient.RegisterTabletManagerClientFactory("internal", func() tmclient.TabletManagerClient { + return &internalTabletManagerClient{} + }) + *tmclient.TabletManagerProtocol = "internal" + // iterate through the keyspaces wr := wrangler.New(logutil.NewConsoleLogger(), ts, nil) var uid uint32 = 1 @@ -246,12 +254,6 @@ func InitTabletMap(ts *topo.Server, tpb *vttestpb.VTTestTopology, mysqld mysqlct tabletconn.RegisterDialer("internal", dialer) *tabletconn.TabletProtocol = "internal" - // Register the tablet manager client factory for tablet manager - tmclient.RegisterTabletManagerClientFactory("internal", func() tmclient.TabletManagerClient { - return &internalTabletManagerClient{} - }) - *tmclient.TabletManagerProtocol = "internal" - // run healthcheck on all vttablets tmc := tmclient.NewTabletManagerClient() for _, tablet := range tabletMap { diff --git a/go/vt/vttablet/tabletmanager/healthcheck_test.go b/go/vt/vttablet/tabletmanager/healthcheck_test.go index 5f59d0e6173..4cdc8e29d80 100644 --- a/go/vt/vttablet/tabletmanager/healthcheck_test.go +++ b/go/vt/vttablet/tabletmanager/healthcheck_test.go @@ -38,6 +38,9 @@ import ( "vitess.io/vitess/go/vt/vttablet/tabletservermock" topodatapb "vitess.io/vitess/go/vt/proto/topodata" + + // needed so that grpc client is registered + _ "vitess.io/vitess/go/vt/vttablet/grpctmclient" ) func TestHealthRecordDeduplication(t *testing.T) { @@ -717,7 +720,7 @@ func TestStateChangeImmediateHealthBroadcast(t *testing.T) { // Run TER to turn us into a proper master, wait for it to finish. agent.HealthReporter.(*fakeHealthCheck).reportReplicationDelay = 19 * time.Second if err := agent.TabletExternallyReparented(ctx, "unused_id"); err != nil { - t.Fatal(err) + t.Fatalf("TabletExternallyReparented failed: %v", err) } <-agent.finalizeReparentCtx.Done() ti, err := agent.TopoServer.GetTablet(ctx, tabletAlias) diff --git a/go/vt/vttablet/tabletmanager/rpc_external_reparent.go b/go/vt/vttablet/tabletmanager/rpc_external_reparent.go index eb44b1d3d42..848ba234f0c 100644 --- a/go/vt/vttablet/tabletmanager/rpc_external_reparent.go +++ b/go/vt/vttablet/tabletmanager/rpc_external_reparent.go @@ -91,16 +91,20 @@ func (agent *ActionAgent) TabletExternallyReparented(ctx context.Context, extern }, ExternalID: externalID, } + defer func() { + if err != nil { + event.DispatchUpdate(ev, "failed: "+err.Error()) + } + }() event.DispatchUpdate(ev, "starting external from tablet (fast)") - // Execute state change to master by force-updating only the local copy of the - // tablet record. The actual record in topo will be updated later. - newTablet := proto.Clone(tablet).(*topodatapb.Tablet) - // We may get called on the current master multiple times in order to fix incomplete external reparents. // We update the tablet here only if it is not currently master - if newTablet.Type != topodatapb.TabletType_MASTER { + if tablet.Type != topodatapb.TabletType_MASTER { log.Infof("fastTabletExternallyReparented: executing change callback for state change to MASTER") + // Execute state change to master by force-updating only the local copy of the + // tablet record. The actual record in topo will be updated later. + newTablet := proto.Clone(tablet).(*topodatapb.Tablet) newTablet.Type = topodatapb.TabletType_MASTER // This is where updateState will block for gracePeriod, while it gives @@ -231,6 +235,8 @@ func (agent *ActionAgent) finalizeTabletExternallyReparented(ctx context.Context } }() + tmc := tmclient.NewTabletManagerClient() + defer tmc.Close() if !topoproto.TabletAliasIsZero(oldMasterAlias) && oldMasterTablet != nil { wg.Add(1) go func() { @@ -239,7 +245,6 @@ func (agent *ActionAgent) finalizeTabletExternallyReparented(ctx context.Context // We don't need to put error into errs if this fails, but we need to wait // for it to make sure that old master tablet is not stuck in the MASTER // state. - tmc := tmclient.NewTabletManagerClient() if err := tmc.RefreshState(ctx, oldMasterTablet); err != nil { log.Warningf("Error calling RefreshState on old master %v: %v", topoproto.TabletAliasString(oldMasterTablet.Alias), err) } @@ -280,7 +285,6 @@ func (agent *ActionAgent) finalizeTabletExternallyReparented(ctx context.Context // tab will be nil if no update was needed if tab != nil { log.Infof("finalizeTabletExternallyReparented: Refresh state for tablet: %v", topoproto.TabletAliasString(tab.Alias)) - tmc := tmclient.NewTabletManagerClient() if err := tmc.RefreshState(ctx, tab); err != nil { log.Warningf("Error calling RefreshState on old master %v: %v", topoproto.TabletAliasString(tab.Alias), err) } From dafaae1a90eacbe32a3aa1b30a1b9900b9e2e621 Mon Sep 17 00:00:00 2001 From: deepthi Date: Fri, 13 Sep 2019 12:09:05 -0700 Subject: [PATCH 100/425] remove non-informative error message that is printed on every restart, cleanup error messages Signed-off-by: deepthi --- go/vt/mysqlctl/metadata_tables.go | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/go/vt/mysqlctl/metadata_tables.go b/go/vt/mysqlctl/metadata_tables.go index a3d64d9c869..37e5becd80a 100644 --- a/go/vt/mysqlctl/metadata_tables.go +++ b/go/vt/mysqlctl/metadata_tables.go @@ -88,34 +88,32 @@ func PopulateMetadataTables(mysqld MysqlDaemon, localMetadata map[string]string, } for _, sql := range sqlAlterLocalMetadataTable { if _, err := conn.ExecuteFetch(sql, 0, false); err != nil { - if merr, ok := err.(*mysql.SQLError); ok && merr.Num == mysql.ERDupFieldName { - log.Errorf("Expected error executing %v: %v", sql, err) - } else { - log.Errorf("Unexpected error executing %v: %v", sql, err) + // Ignore "Duplicate column name 'db_name'" errors which can happen on every restart. + if merr, ok := err.(*mysql.SQLError); !ok || merr.Num != mysql.ERDupFieldName { + log.Errorf("Error executing %v: %v", sql, err) return err } } } sql := fmt.Sprintf(sqlUpdateLocalMetadataTable, dbName) if _, err := conn.ExecuteFetch(sql, 0, false); err != nil { - log.Errorf("unexpected error executing %v: %v, continuing. Please check the data in _vt.local_metadata and take corrective action", sql, err) + log.Errorf("Error executing %v: %v, continuing. Please check the data in _vt.local_metadata and take corrective action.", sql, err) } if _, err := conn.ExecuteFetch(sqlCreateShardMetadataTable, 0, false); err != nil { return err } for _, sql := range sqlAlterShardMetadataTable { if _, err := conn.ExecuteFetch(sql, 0, false); err != nil { - if merr, ok := err.(*mysql.SQLError); ok && merr.Num == mysql.ERDupFieldName { - log.Errorf("Expected error executing %v: %v", sql, err) - } else { - log.Errorf("Unexpected error executing %v: %v", sql, err) + // Ignore "Duplicate column name 'db_name'" errors which can happen on every restart. + if merr, ok := err.(*mysql.SQLError); !ok || merr.Num != mysql.ERDupFieldName { + log.Errorf("Error executing %v: %v", sql, err) return err } } } sql = fmt.Sprintf(sqlUpdateShardMetadataTable, dbName) if _, err := conn.ExecuteFetch(sql, 0, false); err != nil { - log.Errorf("unexpected error executing %v: %v, continuing. Please check the data in _vt.shard_metadata and take corrective action", sql, err) + log.Errorf("Error executing %v: %v, continuing. Please check the data in _vt.shard_metadata and take corrective action.", sql, err) } // Populate local_metadata from the passed list of values. From 428c46866fb1103508e262710b43364c2394665b Mon Sep 17 00:00:00 2001 From: Sugu Sougoumarane Date: Sat, 14 Sep 2019 10:43:22 -0700 Subject: [PATCH 101/425] vreplication: address review comments Signed-off-by: Sugu Sougoumarane --- go/vt/vttablet/tabletmanager/vreplication/controller_plan.go | 4 ++-- go/vt/vttablet/tabletmanager/vreplication/engine.go | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go/vt/vttablet/tabletmanager/vreplication/controller_plan.go b/go/vt/vttablet/tabletmanager/vreplication/controller_plan.go index e1ee1a5734b..06ce98f77f1 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/controller_plan.go +++ b/go/vt/vttablet/tabletmanager/vreplication/controller_plan.go @@ -210,7 +210,7 @@ func buildDeletePlan(del *sqlparser.Delete) (*controllerPlan, error) { }, } buf3 := sqlparser.NewTrackedBuffer(nil) - buf3.Myprintf("delete from %s%v", copySateTableName, copyStateWhere) + buf3.Myprintf("delete from %s%v", copyStateTableName, copyStateWhere) return &controllerPlan{ opcode: deleteQuery, @@ -222,7 +222,7 @@ func buildDeletePlan(del *sqlparser.Delete) (*controllerPlan, error) { func buildSelectPlan(sel *sqlparser.Select) (*controllerPlan, error) { switch sqlparser.String(sel.From) { - case vreplicationTableName, reshardingJournalTableName, copySateTableName: + case vreplicationTableName, reshardingJournalTableName, copyStateTableName: return &controllerPlan{ opcode: selectQuery, }, nil diff --git a/go/vt/vttablet/tabletmanager/vreplication/engine.go b/go/vt/vttablet/tabletmanager/vreplication/engine.go index db08a0f07c3..4baad2ac62c 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/engine.go +++ b/go/vt/vttablet/tabletmanager/vreplication/engine.go @@ -36,7 +36,7 @@ import ( const ( reshardingJournalTableName = "_vt.resharding_journal" vreplicationTableName = "_vt.vreplication" - copySateTableName = "_vt.copy_state" + copyStateTableName = "_vt.copy_state" createReshardingJournalTable = `create table if not exists _vt.resharding_journal( id bigint, From 978108243af4c3404df59683af65323c27a3450b Mon Sep 17 00:00:00 2001 From: Andres Taylor Date: Mon, 16 Sep 2019 05:42:08 +0200 Subject: [PATCH 102/425] Use standard opentracing TextMap instead of custom backend code Signed-off-by: Andres Taylor --- go/trace/opentracing.go | 26 +++++++++++++++++++++-- go/trace/opentracing_test.go | 41 ++++++++++++++++++++++++++++++++++++ go/trace/plugin_jaeger.go | 4 ---- 3 files changed, 65 insertions(+), 6 deletions(-) create mode 100644 go/trace/opentracing_test.go diff --git a/go/trace/opentracing.go b/go/trace/opentracing.go index 4413d808a14..6a33f120691 100644 --- a/go/trace/opentracing.go +++ b/go/trace/opentracing.go @@ -16,10 +16,13 @@ limitations under the License. package trace import ( + "strings" + otgrpc "github.com/opentracing-contrib/go-grpc" "github.com/opentracing/opentracing-go" "golang.org/x/net/context" "google.golang.org/grpc" + "vitess.io/vitess/go/vt/proto/vtrpc" "vitess.io/vitess/go/vt/vterrors" ) @@ -43,7 +46,6 @@ var _ tracingService = (*openTracingService)(nil) type tracer interface { GetOpenTracingTracer() opentracing.Tracer - FromString(string) (opentracing.SpanContext, error) } type openTracingService struct { @@ -82,8 +84,28 @@ func (jf openTracingService) New(parent Span, label string) Span { return openTracingSpan{otSpan: innerSpan} } +func extractMapFromString(in string) (opentracing.TextMapCarrier, error) { + m := make(opentracing.TextMapCarrier) + items := strings.Split(in, ":") + if len(items) < 2 { + return nil, vterrors.Errorf(vtrpc.Code_INVALID_ARGUMENT, "expected transmitted context to contain at least span id and trace id") + } + for _, v := range items { + idx := strings.Index(v, "=") + if idx < 1 { + return nil, vterrors.Errorf(vtrpc.Code_INVALID_ARGUMENT, "every element in the context string has to be in the form key=value") + } + m[v[0:idx]] = v[idx+1:] + } + return m, nil +} + func (jf openTracingService) NewFromString(parent, label string) (Span, error) { - spanContext, err := jf.Tracer.FromString(parent) + carrier, err := extractMapFromString(parent) + if err != nil { + return nil, err + } + spanContext, err := jf.Tracer.GetOpenTracingTracer().Extract(opentracing.TextMap, carrier) if err != nil { return nil, vterrors.Wrap(err, "failed to deserialize span context") } diff --git a/go/trace/opentracing_test.go b/go/trace/opentracing_test.go new file mode 100644 index 00000000000..9f6f9203ef4 --- /dev/null +++ b/go/trace/opentracing_test.go @@ -0,0 +1,41 @@ +/* +Copyright 2019 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 trace + +import ( + "testing" + + "github.com/opentracing/opentracing-go" + "github.com/stretchr/testify/assert" +) + +func TestExtractMapFromString(t *testing.T) { + expected := make(opentracing.TextMapCarrier) + expected["apa"] = "12" + expected["banan"] = "x-tracing-backend-12" + result, err := extractMapFromString("apa=12:banan=x-tracing-backend-12") + assert.NoError(t, err) + assert.Equal(t, expected, result) +} + +func TestErrorConditions(t *testing.T) { + _, err := extractMapFromString("") + assert.Error(t, err) + + _, err = extractMapFromString("key=value:keywithnovalue") + assert.Error(t, err) +} diff --git a/go/trace/plugin_jaeger.go b/go/trace/plugin_jaeger.go index b8053a4e2c8..efbfff8f020 100644 --- a/go/trace/plugin_jaeger.go +++ b/go/trace/plugin_jaeger.go @@ -95,10 +95,6 @@ type jaegerTracer struct { actual opentracing.Tracer } -func (*jaegerTracer) FromString(s string) (opentracing.SpanContext, error) { - return jaeger.ContextFromString(s) -} - func (jt *jaegerTracer) GetOpenTracingTracer() opentracing.Tracer { return jt.actual } From 250a2fe1b2abb1006576742563a79970195ca9aa Mon Sep 17 00:00:00 2001 From: Anthony Yeh Date: Mon, 16 Sep 2019 12:05:16 -0700 Subject: [PATCH 103/425] vtbackup: Retry fetching master position. (#5192) We've seen that this could get stuck if vtbackup happens to read the master tablet record while the tablet is unreachable, and then the tablet comes back up with a different address. This adds a retry that re-reads the shard and tablet records to pick up any changes in the master alias or tablet address. Signed-off-by: Anthony Yeh --- go/cmd/vtbackup/vtbackup.go | 73 ++++++++++++++++++++++++++++++++++--- 1 file changed, 67 insertions(+), 6 deletions(-) diff --git a/go/cmd/vtbackup/vtbackup.go b/go/cmd/vtbackup/vtbackup.go index 64ef47a961f..3f9eecb8fd2 100644 --- a/go/cmd/vtbackup/vtbackup.go +++ b/go/cmd/vtbackup/vtbackup.go @@ -65,7 +65,9 @@ import ( "math" "math/big" "os" + "os/signal" "strings" + "syscall" "time" "vitess.io/vitess/go/exit" @@ -88,11 +90,19 @@ import ( const ( backupTimestampFormat = "2006-01-02.150405" manifestFileName = "MANIFEST" + + // operationTimeout is the timeout for individual operations like fetching + // the master position. This does not impose an overall timeout on + // long-running processes like taking the backup. It only applies to + // steps along the way that should complete quickly. This ensures we don't + // place a hard cap on the overall time for a backup, while also not waiting + // forever for things that should be quick. + operationTimeout = 1 * time.Minute ) var ( // vtbackup-specific flags - // We used to have timeouts, but these did more harm than good. If a backup + // We used to have overall timeouts, but these did more harm than good. If a backup // has been going for a while, giving up and starting over from scratch is // pretty much never going to help. We should just keep trying and have a // system that alerts a human if it's taking longer than expected. @@ -133,7 +143,15 @@ func main() { exit.Return(1) } - ctx := context.Background() + // Catch SIGTERM and SIGINT so we get a chance to clean up. + ctx, cancel := context.WithCancel(context.Background()) + sigChan := make(chan os.Signal, 1) + signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM) + go func() { + sig := <-sigChan + log.Infof("Cancelling due to signal: %v", sig) + cancel() + }() // Open connection backup storage. backupDir := fmt.Sprintf("%v/%v", *initKeyspace, *initShard) @@ -229,7 +247,9 @@ func takeBackup(ctx context.Context, topoServer *topo.Server, backupStorage back // produces a result that can be used to skip InitShardMaster entirely. // This involves resetting replication (to erase any history) and then // creating the main database and some Vitess system tables. - mysqld.ResetReplication(ctx) + if err := mysqld.ResetReplication(ctx); err != nil { + return fmt.Errorf("can't reset replication: %v", err) + } cmds := mysqlctl.CreateReparentJournal() cmds = append(cmds, fmt.Sprintf("CREATE DATABASE IF NOT EXISTS %s", sqlescape.EscapeID(dbName))) if err := mysqld.ExecuteSuperQueryList(ctx, cmds); err != nil { @@ -277,9 +297,22 @@ func takeBackup(ctx context.Context, topoServer *topo.Server, backupStorage back // catch up to live changes, we'd rather take a backup of something rather // than timing out. tmc := tmclient.NewTabletManagerClient() - masterPos, err := getMasterPosition(ctx, tmc, topoServer) + // Keep retrying if we can't contact the master. The master might be + // changing, moving, or down temporarily. + var masterPos mysql.Position + err = retryOnError(ctx, func() error { + // Add a per-operation timeout so we re-read topo if the master is unreachable. + opCtx, cancel := context.WithTimeout(ctx, operationTimeout) + defer cancel() + pos, err := getMasterPosition(opCtx, tmc, topoServer) + if err != nil { + return fmt.Errorf("can't get the master replication position: %v", err) + } + masterPos = pos + return nil + }) if err != nil { - return fmt.Errorf("can't get the master replication position: %v", err) + return err } // Remember the time when we fetched the master position, not when we caught @@ -290,7 +323,11 @@ func takeBackup(ctx context.Context, topoServer *topo.Server, backupStorage back // Wait for replication to catch up. waitStartTime := time.Now() for { - time.Sleep(time.Second) + select { + case <-ctx.Done(): + return ctx.Err() + case <-time.After(time.Second): + } status, statusErr := mysqld.SlaveStatus() if statusErr != nil { @@ -408,6 +445,30 @@ func getMasterPosition(ctx context.Context, tmc tmclient.TabletManagerClient, ts return pos, nil } +// retryOnError keeps calling the given function until it succeeds, or the given +// Context is done. It waits an exponentially increasing amount of time between +// retries to avoid hot-looping. The only time this returns an error is if the +// Context is cancelled. +func retryOnError(ctx context.Context, fn func() error) error { + waitTime := 1 * time.Second + + for { + err := fn() + if err == nil { + return nil + } + log.Errorf("Waiting %v to retry after error: %v", waitTime, err) + + select { + case <-ctx.Done(): + log.Errorf("Not retrying after error: %v", ctx.Err()) + return ctx.Err() + case <-time.After(waitTime): + waitTime *= 2 + } + } +} + func backupName(backupTime time.Time, tabletAlias *topodatapb.TabletAlias) string { return fmt.Sprintf("%v.%v", backupTime.UTC().Format(backupTimestampFormat), topoproto.TabletAliasString(tabletAlias)) } From 9cd0b116201893bb4b948ffc50c09b836f9b6e5a Mon Sep 17 00:00:00 2001 From: Anthony Yeh Date: Mon, 16 Sep 2019 12:05:35 -0700 Subject: [PATCH 104/425] xtrabackup: Add a timeout on closing backup files. (#5193) * xtrabackup: Add a timeout on closing backup files. We've seen backup attempts that apparently stalled while waiting for Close() on the file returned by AddFile() to return. We've only seen this on xtrabackup backups, likely because we perform a small number of long-running file uploads, instead of uploading each file individually. This adds a timeout to the Close() step. If it times out, the backup will be aborted and will need to be retried from scratch. However, that's better than getting stuck forever. Signed-off-by: Anthony Yeh * Add comment to document intentional hang. Signed-off-by: Anthony Yeh --- go/vt/mysqlctl/xtrabackupengine.go | 42 ++++++++++++++++++++++++++++-- 1 file changed, 40 insertions(+), 2 deletions(-) diff --git a/go/vt/mysqlctl/xtrabackupengine.go b/go/vt/mysqlctl/xtrabackupengine.go index 8ce8fb31dd4..7fdb5911495 100644 --- a/go/vt/mysqlctl/xtrabackupengine.go +++ b/go/vt/mysqlctl/xtrabackupengine.go @@ -66,6 +66,9 @@ const ( xtrabackupBinaryName = "xtrabackup" xtrabackupEngineName = "xtrabackup" xbstream = "xbstream" + + // closeTimeout is the timeout for closing backup files after writing. + closeTimeout = 10 * time.Minute ) // xtraBackupManifest represents a backup. @@ -107,6 +110,7 @@ func (be *XtrabackupEngine) backupFileName() string { } func closeFile(wc io.WriteCloser, fileName string, logger logutil.Logger, finalErr *error) { + logger.Infof("Closing backup file %v", fileName) if closeErr := wc.Close(); *finalErr == nil { *finalErr = closeErr } else if closeErr != nil { @@ -145,12 +149,14 @@ func (be *XtrabackupEngine) ExecuteBackup(ctx context.Context, cnf *Mycnf, mysql // do not write the MANIFEST unless all files were closed successfully, // maintaining the contract that a MANIFEST file should only exist if the // backup was created successfully. + logger.Infof("Starting backup with %v stripe(s)", numStripes) replicationPosition, err := be.backupFiles(ctx, cnf, logger, bh, backupFileName, numStripes, flavor) if err != nil { return false, err } // open the MANIFEST + logger.Infof("Writing backup MANIFEST") mwc, err := bh.AddFile(ctx, backupManifestFileName, 0) if err != nil { return false, vterrors.Wrapf(err, "cannot add %v to backup", backupManifestFileName) @@ -183,6 +189,7 @@ func (be *XtrabackupEngine) ExecuteBackup(ctx context.Context, cnf *Mycnf, mysql return false, vterrors.Wrapf(err, "cannot write %v", backupManifestFileName) } + logger.Infof("Backup completed") return true, nil } @@ -203,11 +210,40 @@ func (be *XtrabackupEngine) backupFiles(ctx context.Context, cnf *Mycnf, logger flagsToExec = append(flagsToExec, strings.Fields(*xtrabackupBackupFlags)...) } - destFiles, err := addStripeFiles(ctx, bh, backupFileName, numStripes, logger) + // Create a cancellable Context for calls to bh.AddFile(). + // This allows us to decide later if we need to cancel an attempt to Close() + // the file returned from AddFile(), since Close() itself does not accept a + // Context value. We can't use a context.WithTimeout() here because that + // would impose a timeout that starts counting right now, so it would + // include the time spent uploading the file content. We only want to impose + // a timeout on the final Close() step. + addFilesCtx, cancelAddFiles := context.WithCancel(ctx) + defer cancelAddFiles() + destFiles, err := addStripeFiles(addFilesCtx, bh, backupFileName, numStripes, logger) if err != nil { return replicationPosition, vterrors.Wrapf(err, "cannot create backup file %v", backupFileName) } defer func() { + // Impose a timeout on the process of closing files. + go func() { + timer := time.NewTimer(closeTimeout) + + select { + case <-addFilesCtx.Done(): + timer.Stop() + return + case <-timer.C: + logger.Errorf("Timed out waiting for Close() on backup file to complete") + // Cancelling the Context that was originally passed to bh.AddFile() + // should hopefully cause Close() calls on the file that AddFile() + // returned to abort. If the underlying implementation doesn't + // respect cancellation of the AddFile() Context while inside + // Close(), then we just hang because it's unsafe to return and + // leave Close() running indefinitely in the background. + cancelAddFiles() + } + }() + filename := backupFileName for i, file := range destFiles { if numStripes > 1 { @@ -627,7 +663,9 @@ func addStripeFiles(ctx context.Context, backupHandle backupstorage.BackupHandle files := []io.WriteCloser{} for i := 0; i < numStripes; i++ { - file, err := backupHandle.AddFile(ctx, stripeFileName(baseFileName, i), 0) + filename := stripeFileName(baseFileName, i) + logger.Infof("Opening backup stripe file %v", filename) + file, err := backupHandle.AddFile(ctx, filename, 0) if err != nil { // Close any files we already opened and clear them from the result. for _, file := range files { From 639b695bd8dc21d2ed1a99dd7fa36e127a04df91 Mon Sep 17 00:00:00 2001 From: deepthi Date: Mon, 15 Jul 2019 13:07:45 -0700 Subject: [PATCH 105/425] update replicationDelay for all serving non-master tablet types Signed-off-by: deepthi --- .../tabletmanager/healthcheck_test.go | 110 +++++++++++++++++- go/vt/vttablet/tabletmanager/state_change.go | 14 +++ 2 files changed, 123 insertions(+), 1 deletion(-) diff --git a/go/vt/vttablet/tabletmanager/healthcheck_test.go b/go/vt/vttablet/tabletmanager/healthcheck_test.go index 6420f48c632..88b8eec0e7c 100644 --- a/go/vt/vttablet/tabletmanager/healthcheck_test.go +++ b/go/vt/vttablet/tabletmanager/healthcheck_test.go @@ -888,6 +888,114 @@ func TestOldHealthCheck(t *testing.T) { } } +// TestBackupStateChange verifies that after backup we check +// the replication delay before setting REPLICA tablet to SERVING +func TestBackupStateChange(t *testing.T) { + ctx := context.Background() + agent := createTestAgent(ctx, t, nil) + + *degradedThreshold = 7 * time.Second + *unhealthyThreshold = 15 * time.Second + + if _, err := expectBroadcastData(agent.QueryServiceControl, true, "healthcheck not run yet", 0); err != nil { + t.Fatal(err) + } + if err := expectStateChange(agent.QueryServiceControl, true, topodatapb.TabletType_REPLICA); err != nil { + t.Fatal(err) + } + + agent.HealthReporter.(*fakeHealthCheck).reportReplicationDelay = 16 * time.Second + + // change to BACKUP, query service will turn off + if _, err := topotools.ChangeType(ctx, agent.TopoServer, agent.TabletAlias, topodatapb.TabletType_BACKUP); err != nil { + t.Fatal(err) + } + if err := agent.RefreshState(ctx); err != nil { + t.Fatal(err) + } + if agent.QueryServiceControl.IsServing() { + t.Errorf("Query service should NOT be running") + } + if err := expectStateChange(agent.QueryServiceControl, false, topodatapb.TabletType_BACKUP); err != nil { + t.Fatal(err) + } + // change back to REPLICA, query service should not start + // because replication delay > unhealthyThreshold + if _, err := topotools.ChangeType(ctx, agent.TopoServer, agent.TabletAlias, topodatapb.TabletType_REPLICA); err != nil { + t.Fatal(err) + } + if err := agent.RefreshState(ctx); err != nil { + t.Fatal(err) + } + if agent.QueryServiceControl.IsServing() { + t.Errorf("Query service should NOT be running") + } + if err := expectStateChange(agent.QueryServiceControl, false, topodatapb.TabletType_REPLICA); err != nil { + t.Fatal(err) + } + + // run healthcheck + // now query service should still be OFF + agent.runHealthCheck() + if agent.QueryServiceControl.IsServing() { + t.Errorf("Query service should NOT be running") + } +} + +// TestRestoreStateChange verifies that after restore we check +// the replication delay before setting REPLICA tablet to SERVING +func TestRestoreStateChange(t *testing.T) { + ctx := context.Background() + agent := createTestAgent(ctx, t, nil) + + *degradedThreshold = 7 * time.Second + *unhealthyThreshold = 15 * time.Second + + if _, err := expectBroadcastData(agent.QueryServiceControl, true, "healthcheck not run yet", 0); err != nil { + t.Fatal(err) + } + if err := expectStateChange(agent.QueryServiceControl, true, topodatapb.TabletType_REPLICA); err != nil { + t.Fatal(err) + } + + agent.HealthReporter.(*fakeHealthCheck).reportReplicationDelay = 16 * time.Second + + // change to RESTORE, query service will turn off + if _, err := topotools.ChangeType(ctx, agent.TopoServer, agent.TabletAlias, topodatapb.TabletType_RESTORE); err != nil { + t.Fatal(err) + } + if err := agent.RefreshState(ctx); err != nil { + t.Fatal(err) + } + if agent.QueryServiceControl.IsServing() { + t.Errorf("Query service should NOT be running") + } + if err := expectStateChange(agent.QueryServiceControl, false, topodatapb.TabletType_RESTORE); err != nil { + t.Fatal(err) + } + // change back to REPLICA, query service should not start + // because replication delay > unhealthyThreshold + if _, err := topotools.ChangeType(ctx, agent.TopoServer, agent.TabletAlias, topodatapb.TabletType_REPLICA); err != nil { + t.Fatal(err) + } + if err := agent.RefreshState(ctx); err != nil { + t.Fatal(err) + } + if agent.QueryServiceControl.IsServing() { + t.Errorf("Query service should NOT be running") + } + if err := expectStateChange(agent.QueryServiceControl, false, topodatapb.TabletType_REPLICA); err != nil { + t.Fatal(err) + } + + // run healthcheck + // now query service should still be OFF + agent.runHealthCheck() + if agent.QueryServiceControl.IsServing() { + t.Errorf("Query service should NOT be running") + } +} + // expectBroadcastData checks that runHealthCheck() broadcasted the expected // stats (going the value for secondsBehindMaster). func expectBroadcastData(qsc tabletserver.Controller, serving bool, healthError string, secondsBehindMaster uint32) (*tabletservermock.BroadcastData, error) { @@ -925,7 +1033,7 @@ func expectStateChange(qsc tabletserver.Controller, serving bool, tabletType top } got := <-qsc.(*tabletservermock.Controller).StateChanges if !reflect.DeepEqual(got, want) { - return fmt.Errorf("unexpected state change. got: %v want: %v got", got, want) + return fmt.Errorf("unexpected state change. got: %v want: %v", got, want) } return nil } diff --git a/go/vt/vttablet/tabletmanager/state_change.go b/go/vt/vttablet/tabletmanager/state_change.go index 4654f8f32c2..e0147f07a2d 100644 --- a/go/vt/vttablet/tabletmanager/state_change.go +++ b/go/vt/vttablet/tabletmanager/state_change.go @@ -217,6 +217,20 @@ func (agent *ActionAgent) changeCallback(ctx context.Context, oldTablet, newTabl allowQuery = false disallowQueryReason = "master tablet with filtered replication on" } + } else { + replicationDelay, healthErr := agent.HealthReporter.Report(true, true) + if healthErr != nil { + allowQuery = false + disallowQueryReason = "Unable to get health" + } else { + agent.mutex.Lock() + agent._replicationDelay = replicationDelay + agent.mutex.Unlock() + if agent._replicationDelay > *unhealthyThreshold { + allowQuery = false + disallowQueryReason = "replica tablet with unhealthy replication lag" + } + } } srvKeyspace, err := agent.TopoServer.GetSrvKeyspace(ctx, newTablet.Alias.Cell, newTablet.Keyspace) if err != nil { From 8fe0fb8837ba023f112be5ce05b69f2abed333aa Mon Sep 17 00:00:00 2001 From: deepthi Date: Mon, 26 Aug 2019 17:24:59 -0700 Subject: [PATCH 106/425] start restored tablets in NON-SERVING state Signed-off-by: deepthi --- go/vt/vttablet/tabletmanager/state_change.go | 24 +++++++++++++------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/go/vt/vttablet/tabletmanager/state_change.go b/go/vt/vttablet/tabletmanager/state_change.go index e0147f07a2d..40e47d63a30 100644 --- a/go/vt/vttablet/tabletmanager/state_change.go +++ b/go/vt/vttablet/tabletmanager/state_change.go @@ -218,17 +218,25 @@ func (agent *ActionAgent) changeCallback(ctx context.Context, oldTablet, newTabl disallowQueryReason = "master tablet with filtered replication on" } } else { - replicationDelay, healthErr := agent.HealthReporter.Report(true, true) - if healthErr != nil { + if oldTablet.Type == topodatapb.TabletType_RESTORE { + // always start as NON-SERVING after a restore because + // healthcheck has not been initialized yet allowQuery = false - disallowQueryReason = "Unable to get health" + disallowQueryReason = "After restore from backup" } else { - agent.mutex.Lock() - agent._replicationDelay = replicationDelay - agent.mutex.Unlock() - if agent._replicationDelay > *unhealthyThreshold { + replicationDelay, healthErr := agent.HealthReporter.Report(true, true) + log.Infof("4426: replication delay during changeCallback: %v", replicationDelay) + if healthErr != nil { allowQuery = false - disallowQueryReason = "replica tablet with unhealthy replication lag" + disallowQueryReason = "Unable to get health" + } else { + agent.mutex.Lock() + agent._replicationDelay = replicationDelay + agent.mutex.Unlock() + if agent._replicationDelay > *unhealthyThreshold { + allowQuery = false + disallowQueryReason = "replica tablet with unhealthy replication lag" + } } } } From b557848d945e4cad421a15546b90759acecea45f Mon Sep 17 00:00:00 2001 From: deepthi Date: Wed, 11 Sep 2019 20:47:07 -0700 Subject: [PATCH 107/425] ensure slave is caught up or progressing before trusting SecondsBehindMaster during backup/restore. separate disallowQueryService from disallowQueryReason. disallowQueryReason was being used to permanently disable query service, but for lagging tablets we want to disable it temporarily. change ExecuteBackup and ExecuteRestore to accept BackupParams and RestoreParams instead of a long list of arguments. Signed-off-by: deepthi --- go/cmd/vtbackup/vtbackup.go | 27 ++++- go/vt/mysqlctl/backup.go | 34 ++++--- go/vt/mysqlctl/backupengine.go | 32 +++++- go/vt/mysqlctl/builtinbackupengine.go | 101 ++++++++++++++++--- go/vt/mysqlctl/xtrabackupengine.go | 29 ++++-- go/vt/vttablet/tabletmanager/restore.go | 49 ++++++++- go/vt/vttablet/tabletmanager/rpc_backup.go | 13 ++- go/vt/vttablet/tabletmanager/state_change.go | 34 ++++--- go/vt/wrangler/testlib/backup_test.go | 18 +++- 9 files changed, 280 insertions(+), 57 deletions(-) diff --git a/go/cmd/vtbackup/vtbackup.go b/go/cmd/vtbackup/vtbackup.go index 3f9eecb8fd2..0abdab9522a 100644 --- a/go/cmd/vtbackup/vtbackup.go +++ b/go/cmd/vtbackup/vtbackup.go @@ -240,6 +240,16 @@ func takeBackup(ctx context.Context, topoServer *topo.Server, backupStorage back dbName = fmt.Sprintf("vt_%s", *initKeyspace) } + backupParams := mysqlctl.BackupParams{ + Cnf: mycnf, + Mysqld: mysqld, + Logger: logutil.NewConsoleLogger(), + Concurrency: *concurrency, + HookExtraEnv: extraEnv, + TopoServer: topoServer, + Keyspace: *initKeyspace, + Shard: *initShard, + } // In initial_backup mode, just take a backup of this empty database. if *initialBackup { // Take a backup of this empty DB without restoring anything. @@ -257,7 +267,7 @@ func takeBackup(ctx context.Context, topoServer *topo.Server, backupStorage back } // Now we're ready to take the backup. name := backupName(time.Now(), tabletAlias) - if err := mysqlctl.Backup(ctx, mycnf, mysqld, logutil.NewConsoleLogger(), backupDir, name, *concurrency, extraEnv); err != nil { + if err := mysqlctl.Backup(ctx, backupDir, name, backupParams); err != nil { return fmt.Errorf("backup failed: %v", err) } log.Info("Initial backup successful.") @@ -265,7 +275,18 @@ func takeBackup(ctx context.Context, topoServer *topo.Server, backupStorage back } log.Infof("Restoring latest backup from directory %v", backupDir) - restorePos, err := mysqlctl.Restore(ctx, mycnf, mysqld, backupDir, *concurrency, extraEnv, map[string]string{}, logutil.NewConsoleLogger(), true, dbName) + params := mysqlctl.RestoreParams{ + Cnf: mycnf, + Mysqld: mysqld, + Logger: logutil.NewConsoleLogger(), + Concurrency: *concurrency, + HookExtraEnv: extraEnv, + LocalMetadata: map[string]string{}, + DeleteBeforeRestore: true, + DbName: dbName, + Dir: backupDir, + } + restorePos, err := mysqlctl.Restore(ctx, params) switch err { case nil: log.Infof("Successfully restored from backup at replication position %v", restorePos) @@ -360,7 +381,7 @@ func takeBackup(ctx context.Context, topoServer *topo.Server, backupStorage back // Now we can take a new backup. name := backupName(backupTime, tabletAlias) - if err := mysqlctl.Backup(ctx, mycnf, mysqld, logutil.NewConsoleLogger(), backupDir, name, *concurrency, extraEnv); err != nil { + if err := mysqlctl.Backup(ctx, backupDir, name, backupParams); err != nil { return fmt.Errorf("error taking backup: %v", err) } diff --git a/go/vt/mysqlctl/backup.go b/go/vt/mysqlctl/backup.go index 12a7651146c..62004772ba0 100644 --- a/go/vt/mysqlctl/backup.go +++ b/go/vt/mysqlctl/backup.go @@ -28,7 +28,6 @@ import ( "vitess.io/vitess/go/mysql" "vitess.io/vitess/go/sqlescape" "vitess.io/vitess/go/vt/log" - "vitess.io/vitess/go/vt/logutil" "vitess.io/vitess/go/vt/mysqlctl/backupstorage" "vitess.io/vitess/go/vt/proto/vtrpc" "vitess.io/vitess/go/vt/vterrors" @@ -90,7 +89,7 @@ var ( // - uses the BackupStorage service to store a new backup // - shuts down Mysqld during the backup // - remember if we were replicating, restore the exact same state -func Backup(ctx context.Context, cnf *Mycnf, mysqld MysqlDaemon, logger logutil.Logger, dir, name string, backupConcurrency int, hookExtraEnv map[string]string) error { +func Backup(ctx context.Context, dir, name string, params BackupParams) error { // Start the backup with the BackupStorage. bs, err := backupstorage.GetBackupStorage() if err != nil { @@ -101,6 +100,8 @@ func Backup(ctx context.Context, cnf *Mycnf, mysqld MysqlDaemon, logger logutil. if err != nil { return vterrors.Wrap(err, "StartBackup failed") } + // Set params.BackupHandle to the selected backup + params.BackupHandle = bh be, err := GetBackupEngine() if err != nil { @@ -108,7 +109,8 @@ func Backup(ctx context.Context, cnf *Mycnf, mysqld MysqlDaemon, logger logutil. } // Take the backup, and either AbortBackup or EndBackup. - usable, err := be.ExecuteBackup(ctx, cnf, mysqld, logger, bh, backupConcurrency, hookExtraEnv) + usable, err := be.ExecuteBackup(ctx, params) + logger := params.Logger var finishErr error if usable { finishErr = bh.EndBackup(ctx) @@ -215,17 +217,16 @@ func removeExistingFiles(cnf *Mycnf) error { // Restore is the main entry point for backup restore. If there is no // appropriate backup on the BackupStorage, Restore logs an error // and returns ErrNoBackup. Any other error is returned. -func Restore( - ctx context.Context, - cnf *Mycnf, - mysqld MysqlDaemon, - dir string, - restoreConcurrency int, - hookExtraEnv map[string]string, - localMetadata map[string]string, - logger logutil.Logger, - deleteBeforeRestore bool, - dbName string) (mysql.Position, error) { +func Restore(ctx context.Context, params RestoreParams) (mysql.Position, error) { + + // extract params + cnf := params.Cnf + mysqld := params.Mysqld + logger := params.Logger + localMetadata := params.LocalMetadata + deleteBeforeRestore := params.DeleteBeforeRestore + dbName := params.DbName + dir := params.Dir rval := mysql.Position{} @@ -290,12 +291,15 @@ func Restore( if err != nil { return rval, err } + // Set params.BackupHandle to the selected backup + params.BackupHandle = bh re, err := GetRestoreEngine(ctx, bh) if err != nil { return mysql.Position{}, vterrors.Wrap(err, "Failed to find restore engine") } - if rval, err = re.ExecuteRestore(ctx, cnf, mysqld, logger, dir, bh, restoreConcurrency, hookExtraEnv); err != nil { + + if rval, err = re.ExecuteRestore(ctx, params); err != nil { return rval, err } diff --git a/go/vt/mysqlctl/backupengine.go b/go/vt/mysqlctl/backupengine.go index 50f07739dab..8e48aa4189d 100644 --- a/go/vt/mysqlctl/backupengine.go +++ b/go/vt/mysqlctl/backupengine.go @@ -29,6 +29,7 @@ import ( "vitess.io/vitess/go/vt/logutil" "vitess.io/vitess/go/vt/mysqlctl/backupstorage" "vitess.io/vitess/go/vt/proto/vtrpc" + "vitess.io/vitess/go/vt/topo" "vitess.io/vitess/go/vt/vterrors" ) @@ -39,13 +40,40 @@ var ( // BackupEngine is the interface to take a backup with a given engine. type BackupEngine interface { - ExecuteBackup(ctx context.Context, cnf *Mycnf, mysqld MysqlDaemon, logger logutil.Logger, bh backupstorage.BackupHandle, backupConcurrency int, hookExtraEnv map[string]string) (bool, error) + ExecuteBackup(ctx context.Context, params BackupParams) (bool, error) ShouldDrainForBackup() bool } +// BackupParams is the struct that holds all params passed to ExecuteBackup +type BackupParams struct { + Cnf *Mycnf + Mysqld MysqlDaemon + Logger logutil.Logger + BackupHandle backupstorage.BackupHandle + Concurrency int + HookExtraEnv map[string]string + TopoServer *topo.Server + Keyspace string + Shard string +} + +// RestoreParams is the struct that holds all params passed to ExecuteRestore +type RestoreParams struct { + Cnf *Mycnf + Mysqld MysqlDaemon + Logger logutil.Logger + BackupHandle backupstorage.BackupHandle + Concurrency int + HookExtraEnv map[string]string + LocalMetadata map[string]string + DeleteBeforeRestore bool + DbName string + Dir string +} + // RestoreEngine is the interface to restore a backup with a given engine. type RestoreEngine interface { - ExecuteRestore(ctx context.Context, cnf *Mycnf, mysqld MysqlDaemon, logger logutil.Logger, dir string, bh backupstorage.BackupHandle, restoreConcurrency int, hookExtraEnv map[string]string) (mysql.Position, error) + ExecuteRestore(ctx context.Context, params RestoreParams) (mysql.Position, error) } // BackupRestoreEngine is a combination of BackupEngine and RestoreEngine. diff --git a/go/vt/mysqlctl/builtinbackupengine.go b/go/vt/mysqlctl/builtinbackupengine.go index eba829a16bc..7fa0a93dcfc 100644 --- a/go/vt/mysqlctl/builtinbackupengine.go +++ b/go/vt/mysqlctl/builtinbackupengine.go @@ -38,7 +38,10 @@ import ( "vitess.io/vitess/go/vt/logutil" "vitess.io/vitess/go/vt/mysqlctl/backupstorage" "vitess.io/vitess/go/vt/proto/vtrpc" + "vitess.io/vitess/go/vt/topo" + "vitess.io/vitess/go/vt/topo/topoproto" "vitess.io/vitess/go/vt/vterrors" + "vitess.io/vitess/go/vt/vttablet/tmclient" ) const ( @@ -236,7 +239,22 @@ func findFilesToBackup(cnf *Mycnf) ([]FileEntry, error) { // ExecuteBackup returns a boolean that indicates if the backup is usable, // and an overall error. -func (be *BuiltinBackupEngine) ExecuteBackup(ctx context.Context, cnf *Mycnf, mysqld MysqlDaemon, logger logutil.Logger, bh backupstorage.BackupHandle, backupConcurrency int, hookExtraEnv map[string]string) (bool, error) { +func (be *BuiltinBackupEngine) ExecuteBackup(ctx context.Context, params BackupParams) (bool, error) { + + // extract all params from BackupParams + cnf := params.Cnf + mysqld := params.Mysqld + logger := params.Logger + bh := params.BackupHandle + backupConcurrency := params.Concurrency + hookExtraEnv := params.HookExtraEnv + topoServer := params.TopoServer + keyspace := params.Keyspace + shard := params.Shard + + if bh == nil { + return false, vterrors.New(vtrpc.Code_INVALID_ARGUMENT, "ExecuteBackup must be called with a valid BackupHandle") + } logger.Infof("Hook: %v, Compress: %v", *backupStorageHook, *backupStorageCompress) @@ -307,6 +325,12 @@ func (be *BuiltinBackupEngine) ExecuteBackup(ctx context.Context, cnf *Mycnf, my return usable, vterrors.Wrap(err, "can't restart mysqld") } + // And set read-only mode + logger.Infof("resetting mysqld read-only to %v", readOnly) + if err := mysqld.SetReadOnly(readOnly); err != nil { + return usable, err + } + // Restore original mysqld state that we saved above. if semiSyncMaster || semiSyncSlave { // Only do this if one of them was on, since both being off could mean @@ -328,12 +352,35 @@ func (be *BuiltinBackupEngine) ExecuteBackup(ctx context.Context, cnf *Mycnf, my if err := WaitForSlaveStart(mysqld, slaveStartDeadline); err != nil { return usable, vterrors.Wrap(err, "slave is not restarting") } - } - // And set read-only mode - logger.Infof("resetting mysqld read-only to %v", readOnly) - if err := mysqld.SetReadOnly(readOnly); err != nil { - return usable, err + // wait for reliable seconds behind master + // we have replicationPosition where we stopped + // if MasterPosition is the same, that means no writes + // have happened to master, so we are up-to-date + // otherwise, wait for replica's Position to change from + // the saved replicationPosition before proceeding + tmc := tmclient.NewTabletManagerClient() + defer tmc.Close() + remoteCtx, remoteCancel := context.WithTimeout(ctx, *topo.RemoteOperationTimeout) + defer remoteCancel() + + masterPos, err := getMasterPosition(remoteCtx, tmc, topoServer, keyspace, shard) + // if we are unable to get master position, return error + if err != nil { + return usable, err + } + if !replicationPosition.Equal(masterPos) { + for { + status, err := mysqld.SlaveStatus() + if err != nil { + return usable, err + } + newPos := status.Position + if !newPos.Equal(replicationPosition) { + break + } + } + } } return usable, backupErr @@ -515,15 +562,20 @@ func (be *BuiltinBackupEngine) backupFile(ctx context.Context, cnf *Mycnf, mysql // otherwise an error is returned func (be *BuiltinBackupEngine) ExecuteRestore( ctx context.Context, - cnf *Mycnf, - mysqld MysqlDaemon, - logger logutil.Logger, - dir string, - bh backupstorage.BackupHandle, - restoreConcurrency int, - hookExtraEnv map[string]string) (mysql.Position, error) { + params RestoreParams) (mysql.Position, error) { + + cnf := params.Cnf + mysqld := params.Mysqld + logger := params.Logger + bh := params.BackupHandle + restoreConcurrency := params.Concurrency + hookExtraEnv := params.HookExtraEnv zeroPosition := mysql.Position{} + if bh == nil { + return zeroPosition, vterrors.New(vtrpc.Code_INVALID_ARGUMENT, "ExecuteRestore must be called with a valid BackupHandle") + } + var bm builtinBackupManifest if err := getBackupManifestInto(ctx, bh, &bm); err != nil { @@ -683,6 +735,29 @@ func (be *BuiltinBackupEngine) ShouldDrainForBackup() bool { return true } +func getMasterPosition(ctx context.Context, tmc tmclient.TabletManagerClient, ts *topo.Server, keyspace, shard string) (mysql.Position, error) { + si, err := ts.GetShard(ctx, keyspace, shard) + if err != nil { + return mysql.Position{}, vterrors.Wrap(err, "can't read shard") + } + if topoproto.TabletAliasIsZero(si.MasterAlias) { + return mysql.Position{}, fmt.Errorf("shard %v/%v has no master", keyspace, shard) + } + ti, err := ts.GetTablet(ctx, si.MasterAlias) + if err != nil { + return mysql.Position{}, fmt.Errorf("can't get master tablet record %v: %v", topoproto.TabletAliasString(si.MasterAlias), err) + } + posStr, err := tmc.MasterPosition(ctx, ti.Tablet) + if err != nil { + return mysql.Position{}, fmt.Errorf("can't get master replication position: %v", err) + } + pos, err := mysql.DecodePosition(posStr) + if err != nil { + return mysql.Position{}, fmt.Errorf("can't decode master replication position %q: %v", posStr, err) + } + return pos, nil +} + func init() { BackupRestoreEngineMap["builtin"] = &BuiltinBackupEngine{} } diff --git a/go/vt/mysqlctl/xtrabackupengine.go b/go/vt/mysqlctl/xtrabackupengine.go index 7fdb5911495..2b7acb277eb 100644 --- a/go/vt/mysqlctl/xtrabackupengine.go +++ b/go/vt/mysqlctl/xtrabackupengine.go @@ -121,7 +121,17 @@ func closeFile(wc io.WriteCloser, fileName string, logger logutil.Logger, finalE // ExecuteBackup returns a boolean that indicates if the backup is usable, // and an overall error. -func (be *XtrabackupEngine) ExecuteBackup(ctx context.Context, cnf *Mycnf, mysqld MysqlDaemon, logger logutil.Logger, bh backupstorage.BackupHandle, backupConcurrency int, hookExtraEnv map[string]string) (complete bool, finalErr error) { +func (be *XtrabackupEngine) ExecuteBackup(ctx context.Context, params BackupParams) (complete bool, finalErr error) { + // extract all params from BackupParams + cnf := params.Cnf + mysqld := params.Mysqld + logger := params.Logger + bh := params.BackupHandle + + if bh == nil { + return false, vterrors.New(vtrpc.Code_INVALID_ARGUMENT, "ExecuteBackup must be called with a valid BackupHandle") + } + if *xtrabackupUser == "" { return false, vterrors.New(vtrpc.Code_INVALID_ARGUMENT, "xtrabackupUser must be specified.") } @@ -364,15 +374,18 @@ func (be *XtrabackupEngine) backupFiles(ctx context.Context, cnf *Mycnf, logger // ExecuteRestore restores from a backup. Any error is returned. func (be *XtrabackupEngine) ExecuteRestore( ctx context.Context, - cnf *Mycnf, - mysqld MysqlDaemon, - logger logutil.Logger, - dir string, - bh backupstorage.BackupHandle, - restoreConcurrency int, - hookExtraEnv map[string]string) (mysql.Position, error) { + params RestoreParams) (mysql.Position, error) { + + cnf := params.Cnf + mysqld := params.Mysqld + logger := params.Logger + bh := params.BackupHandle zeroPosition := mysql.Position{} + if bh == nil { + return zeroPosition, vterrors.New(vtrpc.Code_INVALID_ARGUMENT, "ExecuteRestore must be called with a valid BackupHandle") + } + var bm xtraBackupManifest if err := getBackupManifestInto(ctx, bh, &bm); err != nil { diff --git a/go/vt/vttablet/tabletmanager/restore.go b/go/vt/vttablet/tabletmanager/restore.go index d01a3ad4fd6..6cd629a50ce 100644 --- a/go/vt/vttablet/tabletmanager/restore.go +++ b/go/vt/vttablet/tabletmanager/restore.go @@ -21,7 +21,9 @@ import ( "fmt" "time" + "vitess.io/vitess/go/vt/topo" "vitess.io/vitess/go/vt/vterrors" + "vitess.io/vitess/go/vt/vttablet/tmclient" "golang.org/x/net/context" "vitess.io/vitess/go/vt/log" @@ -83,11 +85,23 @@ func (agent *ActionAgent) restoreDataLocked(ctx context.Context, logger logutil. tablet := agent.Tablet() dir := fmt.Sprintf("%v/%v", tablet.Keyspace, tablet.Shard) + params := mysqlctl.RestoreParams{ + Cnf: agent.Cnf, + Mysqld: agent.MysqlDaemon, + Logger: logger, + Concurrency: *restoreConcurrency, + HookExtraEnv: agent.hookExtraEnv(), + LocalMetadata: localMetadata, + DeleteBeforeRestore: deleteBeforeRestore, + DbName: topoproto.TabletDbName(tablet), + Dir: dir, + } + // Loop until a backup exists, unless we were told to give up immediately. var pos mysql.Position var err error for { - pos, err = mysqlctl.Restore(ctx, agent.Cnf, agent.MysqlDaemon, dir, *restoreConcurrency, agent.hookExtraEnv(), localMetadata, logger, deleteBeforeRestore, topoproto.TabletDbName(tablet)) + pos, err = mysqlctl.Restore(ctx, params) if waitForBackupInterval == 0 { break } @@ -205,6 +219,39 @@ func (agent *ActionAgent) startReplication(ctx context.Context, pos mysql.Positi if err := agent.MysqlDaemon.SetMaster(ctx, topoproto.MysqlHostname(ti.Tablet), int(topoproto.MysqlPort(ti.Tablet)), false /* slaveStopBefore */, true /* slaveStartAfter */); err != nil { return vterrors.Wrap(err, "MysqlDaemon.SetMaster failed") } + + // wait for reliable seconds behind master + // we have pos where we want to resume from + // if MasterPosition is the same, that means no writes + // have happened to master, so we are up-to-date + // otherwise, wait for replica's Position to change from + // the initial pos before proceeding + tmc := tmclient.NewTabletManagerClient() + defer tmc.Close() + remoteCtx, remoteCancel := context.WithTimeout(ctx, *topo.RemoteOperationTimeout) + defer remoteCancel() + posStr, err := tmc.MasterPosition(remoteCtx, ti.Tablet) + if err != nil { + return vterrors.Wrap(err, "can't get master replication position") + } + masterPos, err := mysql.DecodePosition(posStr) + if err != nil { + return vterrors.Wrapf(err, "can't decode master replication position: %q", posStr) + } + + if !pos.Equal(masterPos) { + for { + status, err := agent.MysqlDaemon.SlaveStatus() + if err != nil { + return vterrors.Wrap(err, "can't get slave status") + } + newPos := status.Position + if !newPos.Equal(pos) { + break + } + } + } + return nil } diff --git a/go/vt/vttablet/tabletmanager/rpc_backup.go b/go/vt/vttablet/tabletmanager/rpc_backup.go index d7387b7c941..5ebf261a4e6 100644 --- a/go/vt/vttablet/tabletmanager/rpc_backup.go +++ b/go/vt/vttablet/tabletmanager/rpc_backup.go @@ -99,7 +99,18 @@ func (agent *ActionAgent) Backup(ctx context.Context, concurrency int, logger lo // now we can run the backup dir := fmt.Sprintf("%v/%v", tablet.Keyspace, tablet.Shard) name := fmt.Sprintf("%v.%v", time.Now().UTC().Format("2006-01-02.150405"), topoproto.TabletAliasString(tablet.Alias)) - returnErr := mysqlctl.Backup(ctx, agent.Cnf, agent.MysqlDaemon, l, dir, name, concurrency, agent.hookExtraEnv()) + backupParams := mysqlctl.BackupParams{ + Cnf: agent.Cnf, + Mysqld: agent.MysqlDaemon, + Logger: l, + Concurrency: concurrency, + HookExtraEnv: agent.hookExtraEnv(), + TopoServer: agent.TopoServer, + Keyspace: tablet.Keyspace, + Shard: tablet.Shard, + } + + returnErr := mysqlctl.Backup(ctx, dir, name, backupParams) if engine.ShouldDrainForBackup() { bgCtx := context.Background() diff --git a/go/vt/vttablet/tabletmanager/state_change.go b/go/vt/vttablet/tabletmanager/state_change.go index 40e47d63a30..3d08d3a7f22 100644 --- a/go/vt/vttablet/tabletmanager/state_change.go +++ b/go/vt/vttablet/tabletmanager/state_change.go @@ -203,7 +203,10 @@ func (agent *ActionAgent) changeCallback(ctx context.Context, oldTablet, newTabl // we're going to use it. var shardInfo *topo.ShardInfo var err error + // this is just for logging var disallowQueryReason string + // this is actually used to set state + var disallowQueryService string var blacklistedTables []string updateBlacklistedTables := true if allowQuery { @@ -212,23 +215,26 @@ func (agent *ActionAgent) changeCallback(ctx context.Context, oldTablet, newTabl log.Errorf("Cannot read shard for this tablet %v, might have inaccurate SourceShards and TabletControls: %v", newTablet.Alias, err) updateBlacklistedTables = false } else { - if newTablet.Type == topodatapb.TabletType_MASTER { - if len(shardInfo.SourceShards) > 0 { - allowQuery = false - disallowQueryReason = "master tablet with filtered replication on" - } + if oldTablet.Type == topodatapb.TabletType_RESTORE { + // always start as NON-SERVING after a restore because + // healthcheck has not been initialized yet + allowQuery = false + // setting disallowQueryService permanently turns off query service + // since we want it to be temporary (until tablet is healthy) we don't set it + // disallowQueryReason is only used for logging + disallowQueryReason = "after restore from backup" } else { - if oldTablet.Type == topodatapb.TabletType_RESTORE { - // always start as NON-SERVING after a restore because - // healthcheck has not been initialized yet - allowQuery = false - disallowQueryReason = "After restore from backup" + if newTablet.Type == topodatapb.TabletType_MASTER { + if len(shardInfo.SourceShards) > 0 { + allowQuery = false + disallowQueryReason = "master tablet with filtered replication on" + disallowQueryService = disallowQueryReason + } } else { replicationDelay, healthErr := agent.HealthReporter.Report(true, true) - log.Infof("4426: replication delay during changeCallback: %v", replicationDelay) if healthErr != nil { allowQuery = false - disallowQueryReason = "Unable to get health" + disallowQueryReason = "unable to get health" } else { agent.mutex.Lock() agent._replicationDelay = replicationDelay @@ -255,6 +261,7 @@ func (agent *ActionAgent) changeCallback(ctx context.Context, oldTablet, newTabl if tabletControl.QueryServiceDisabled { allowQuery = false disallowQueryReason = "TabletControl.DisableQueryService set" + disallowQueryService = disallowQueryReason } break } @@ -270,8 +277,9 @@ func (agent *ActionAgent) changeCallback(ctx context.Context, oldTablet, newTabl } } else { disallowQueryReason = fmt.Sprintf("not a serving tablet type(%v)", newTablet.Type) + disallowQueryService = disallowQueryReason } - agent.setServicesDesiredState(disallowQueryReason, runUpdateStream) + agent.setServicesDesiredState(disallowQueryService, runUpdateStream) if updateBlacklistedTables { if err := agent.loadBlacklistRules(newTablet, blacklistedTables); err != nil { // FIXME(alainjobart) how to handle this error? diff --git a/go/vt/wrangler/testlib/backup_test.go b/go/vt/wrangler/testlib/backup_test.go index d4d68690ee2..9916268b083 100644 --- a/go/vt/wrangler/testlib/backup_test.go +++ b/go/vt/wrangler/testlib/backup_test.go @@ -94,10 +94,26 @@ func TestBackupRestore(t *testing.T) { t.Fatalf("failed to write file db.opt: %v", err) } - // create a master tablet, not started, just for shard health + // create a master tablet, set its master position master := NewFakeTablet(t, wr, "cell1", 0, topodatapb.TabletType_MASTER, db) + master.FakeMysqlDaemon.ReadOnly = false + master.FakeMysqlDaemon.Replicating = false + master.FakeMysqlDaemon.CurrentMasterPosition = mysql.Position{ + GTIDSet: mysql.MariadbGTIDSet{ + mysql.MariadbGTID{ + Domain: 2, + Server: 123, + Sequence: 457, + }, + }, + } + + // start master so that slave can fetch master position from it + master.StartActionLoop(t, wr) + defer master.StopActionLoop(t) // create a single tablet, set it up so we can do backups + // set its position same as that of master so that backup doesn't wait for catchup sourceTablet := NewFakeTablet(t, wr, "cell1", 1, topodatapb.TabletType_REPLICA, db) sourceTablet.FakeMysqlDaemon.ReadOnly = true sourceTablet.FakeMysqlDaemon.Replicating = true From 06e5a5fc9f4d3c487d614d071aa572658786eaf3 Mon Sep 17 00:00:00 2001 From: deepthi Date: Fri, 13 Sep 2019 18:38:58 -0700 Subject: [PATCH 108/425] keep BackupHandle out of Params structs, document struct fiels, other minor edits Signed-off-by: deepthi --- go/vt/mysqlctl/backup.go | 8 ++--- go/vt/mysqlctl/backupengine.go | 49 ++++++++++++++++----------- go/vt/mysqlctl/builtinbackupengine.go | 29 +++++----------- go/vt/mysqlctl/xtrabackupengine.go | 16 ++------- 4 files changed, 43 insertions(+), 59 deletions(-) diff --git a/go/vt/mysqlctl/backup.go b/go/vt/mysqlctl/backup.go index 62004772ba0..324f61c3444 100644 --- a/go/vt/mysqlctl/backup.go +++ b/go/vt/mysqlctl/backup.go @@ -100,8 +100,6 @@ func Backup(ctx context.Context, dir, name string, params BackupParams) error { if err != nil { return vterrors.Wrap(err, "StartBackup failed") } - // Set params.BackupHandle to the selected backup - params.BackupHandle = bh be, err := GetBackupEngine() if err != nil { @@ -109,7 +107,7 @@ func Backup(ctx context.Context, dir, name string, params BackupParams) error { } // Take the backup, and either AbortBackup or EndBackup. - usable, err := be.ExecuteBackup(ctx, params) + usable, err := be.ExecuteBackup(ctx, params, bh) logger := params.Logger var finishErr error if usable { @@ -291,15 +289,13 @@ func Restore(ctx context.Context, params RestoreParams) (mysql.Position, error) if err != nil { return rval, err } - // Set params.BackupHandle to the selected backup - params.BackupHandle = bh re, err := GetRestoreEngine(ctx, bh) if err != nil { return mysql.Position{}, vterrors.Wrap(err, "Failed to find restore engine") } - if rval, err = re.ExecuteRestore(ctx, params); err != nil { + if rval, err = re.ExecuteRestore(ctx, params, bh); err != nil { return rval, err } diff --git a/go/vt/mysqlctl/backupengine.go b/go/vt/mysqlctl/backupengine.go index 8e48aa4189d..e65ecd97c55 100644 --- a/go/vt/mysqlctl/backupengine.go +++ b/go/vt/mysqlctl/backupengine.go @@ -40,40 +40,51 @@ var ( // BackupEngine is the interface to take a backup with a given engine. type BackupEngine interface { - ExecuteBackup(ctx context.Context, params BackupParams) (bool, error) + ExecuteBackup(ctx context.Context, params BackupParams, bh backupstorage.BackupHandle) (bool, error) ShouldDrainForBackup() bool } // BackupParams is the struct that holds all params passed to ExecuteBackup type BackupParams struct { - Cnf *Mycnf - Mysqld MysqlDaemon - Logger logutil.Logger - BackupHandle backupstorage.BackupHandle - Concurrency int + Cnf *Mycnf + Mysqld MysqlDaemon + Logger logutil.Logger + // Concurrency is the value of -concurrency flag given to Backup command + // It determines how many files are processed in parallel + Concurrency int + // Extra env variables for pre-backup and post-backup transform hooks HookExtraEnv map[string]string - TopoServer *topo.Server - Keyspace string - Shard string + // TopoServer, Keyspace and Shard are used to discover master tablet + TopoServer *topo.Server + Keyspace string + Shard string } // RestoreParams is the struct that holds all params passed to ExecuteRestore type RestoreParams struct { - Cnf *Mycnf - Mysqld MysqlDaemon - Logger logutil.Logger - BackupHandle backupstorage.BackupHandle - Concurrency int - HookExtraEnv map[string]string - LocalMetadata map[string]string + Cnf *Mycnf + Mysqld MysqlDaemon + Logger logutil.Logger + // Concurrency is the value of -restore_concurrency flag (init restore parameter) + // It determines how many files are processed in parallel + Concurrency int + // Extra env variables for pre-restore and post-restore transform hooks + HookExtraEnv map[string]string + // Metadata to write into database after restore. See PopulateMetadataTables + LocalMetadata map[string]string + // DeleteBeforeRestore tells us whether existing data should be deleted before + // restoring. This is always set to false when starting a tablet with -restore_from_backup, + // but is set to true when executing a RestoreFromBackup command on an already running vttablet DeleteBeforeRestore bool - DbName string - Dir string + // Name of the managed database / schema + DbName string + // Directory location to search for a usable backup + Dir string } // RestoreEngine is the interface to restore a backup with a given engine. type RestoreEngine interface { - ExecuteRestore(ctx context.Context, params RestoreParams) (mysql.Position, error) + ExecuteRestore(ctx context.Context, params RestoreParams, bh backupstorage.BackupHandle) (mysql.Position, error) } // BackupRestoreEngine is a combination of BackupEngine and RestoreEngine. diff --git a/go/vt/mysqlctl/builtinbackupengine.go b/go/vt/mysqlctl/builtinbackupengine.go index 7fa0a93dcfc..e975c04bdfa 100644 --- a/go/vt/mysqlctl/builtinbackupengine.go +++ b/go/vt/mysqlctl/builtinbackupengine.go @@ -239,23 +239,18 @@ func findFilesToBackup(cnf *Mycnf) ([]FileEntry, error) { // ExecuteBackup returns a boolean that indicates if the backup is usable, // and an overall error. -func (be *BuiltinBackupEngine) ExecuteBackup(ctx context.Context, params BackupParams) (bool, error) { +func (be *BuiltinBackupEngine) ExecuteBackup(ctx context.Context, params BackupParams, bh backupstorage.BackupHandle) (bool, error) { // extract all params from BackupParams cnf := params.Cnf mysqld := params.Mysqld logger := params.Logger - bh := params.BackupHandle backupConcurrency := params.Concurrency hookExtraEnv := params.HookExtraEnv topoServer := params.TopoServer keyspace := params.Keyspace shard := params.Shard - if bh == nil { - return false, vterrors.New(vtrpc.Code_INVALID_ARGUMENT, "ExecuteBackup must be called with a valid BackupHandle") - } - logger.Infof("Hook: %v, Compress: %v", *backupStorageHook, *backupStorageCompress) // Save initial state so we can restore. @@ -353,11 +348,12 @@ func (be *BuiltinBackupEngine) ExecuteBackup(ctx context.Context, params BackupP return usable, vterrors.Wrap(err, "slave is not restarting") } - // wait for reliable seconds behind master - // we have replicationPosition where we stopped - // if MasterPosition is the same, that means no writes - // have happened to master, so we are up-to-date - // otherwise, wait for replica's Position to change from + // Wait for a reliable value for SecondsBehindMaster from SlaveStatus() + + // We know that we stopped at replicationPosition. + // If MasterPosition is the same, that means no writes + // have happened to master, so we are up-to-date. + // Otherwise, we wait for replica's Position to change from // the saved replicationPosition before proceeding tmc := tmclient.NewTabletManagerClient() defer tmc.Close() @@ -365,7 +361,7 @@ func (be *BuiltinBackupEngine) ExecuteBackup(ctx context.Context, params BackupP defer remoteCancel() masterPos, err := getMasterPosition(remoteCtx, tmc, topoServer, keyspace, shard) - // if we are unable to get master position, return error + // If we are unable to get master position, return error. if err != nil { return usable, err } @@ -560,22 +556,15 @@ func (be *BuiltinBackupEngine) backupFile(ctx context.Context, cnf *Mycnf, mysql // ExecuteRestore restores from a backup. If the restore is successful // we return the position from which replication should start // otherwise an error is returned -func (be *BuiltinBackupEngine) ExecuteRestore( - ctx context.Context, - params RestoreParams) (mysql.Position, error) { +func (be *BuiltinBackupEngine) ExecuteRestore(ctx context.Context, params RestoreParams, bh backupstorage.BackupHandle) (mysql.Position, error) { cnf := params.Cnf mysqld := params.Mysqld logger := params.Logger - bh := params.BackupHandle restoreConcurrency := params.Concurrency hookExtraEnv := params.HookExtraEnv zeroPosition := mysql.Position{} - if bh == nil { - return zeroPosition, vterrors.New(vtrpc.Code_INVALID_ARGUMENT, "ExecuteRestore must be called with a valid BackupHandle") - } - var bm builtinBackupManifest if err := getBackupManifestInto(ctx, bh, &bm); err != nil { diff --git a/go/vt/mysqlctl/xtrabackupengine.go b/go/vt/mysqlctl/xtrabackupengine.go index 2b7acb277eb..a2a035b1bed 100644 --- a/go/vt/mysqlctl/xtrabackupengine.go +++ b/go/vt/mysqlctl/xtrabackupengine.go @@ -121,16 +121,11 @@ func closeFile(wc io.WriteCloser, fileName string, logger logutil.Logger, finalE // ExecuteBackup returns a boolean that indicates if the backup is usable, // and an overall error. -func (be *XtrabackupEngine) ExecuteBackup(ctx context.Context, params BackupParams) (complete bool, finalErr error) { +func (be *XtrabackupEngine) ExecuteBackup(ctx context.Context, params BackupParams, bh backupstorage.BackupHandle) (complete bool, finalErr error) { // extract all params from BackupParams cnf := params.Cnf mysqld := params.Mysqld logger := params.Logger - bh := params.BackupHandle - - if bh == nil { - return false, vterrors.New(vtrpc.Code_INVALID_ARGUMENT, "ExecuteBackup must be called with a valid BackupHandle") - } if *xtrabackupUser == "" { return false, vterrors.New(vtrpc.Code_INVALID_ARGUMENT, "xtrabackupUser must be specified.") @@ -372,20 +367,13 @@ func (be *XtrabackupEngine) backupFiles(ctx context.Context, cnf *Mycnf, logger } // ExecuteRestore restores from a backup. Any error is returned. -func (be *XtrabackupEngine) ExecuteRestore( - ctx context.Context, - params RestoreParams) (mysql.Position, error) { +func (be *XtrabackupEngine) ExecuteRestore(ctx context.Context, params RestoreParams, bh backupstorage.BackupHandle) (mysql.Position, error) { cnf := params.Cnf mysqld := params.Mysqld logger := params.Logger - bh := params.BackupHandle zeroPosition := mysql.Position{} - if bh == nil { - return zeroPosition, vterrors.New(vtrpc.Code_INVALID_ARGUMENT, "ExecuteRestore must be called with a valid BackupHandle") - } - var bm xtraBackupManifest if err := getBackupManifestInto(ctx, bh, &bm); err != nil { From 7922f45c34631fd99995c55de698f9f9a81014e4 Mon Sep 17 00:00:00 2001 From: Rafael Chacon Date: Tue, 17 Sep 2019 10:09:36 -0700 Subject: [PATCH 109/425] The error coming from mysql could have the password. We need to redact Signed-off-by: Rafael Chacon --- go/vt/mysqlctl/query.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go/vt/mysqlctl/query.go b/go/vt/mysqlctl/query.go index 0051f5bd6d5..984fa34113b 100644 --- a/go/vt/mysqlctl/query.go +++ b/go/vt/mysqlctl/query.go @@ -72,7 +72,7 @@ func (mysqld *Mysqld) executeSuperQueryListConn(ctx context.Context, conn *dbcon for _, query := range queryList { log.Infof("exec %v", redactMasterPassword(query)) if _, err := mysqld.executeFetchContext(ctx, conn, query, 10000, false); err != nil { - return fmt.Errorf("ExecuteFetch(%v) failed: %v", redactMasterPassword(query), err.Error()) + return fmt.Errorf("ExecuteFetch(%v) failed: %v", redactMasterPassword(query), redactMasterPassword(err.Error())) } } return nil From f950b3c25c6c304ab31d0593145bb0b4823d5f40 Mon Sep 17 00:00:00 2001 From: Karel Alfonso Sague Date: Wed, 18 Sep 2019 12:09:14 +1000 Subject: [PATCH 110/425] Enable selecting consistent snapshot during resharding workflows via vtctld ui Signed-off-by: Karel Alfonso Sague --- .../reshardingworkflowgen/workflow.go | 8 ++- .../workflow_flaky_test.go | 2 +- .../src/app/shared/flags/workflow.flags.ts | 49 ++++++++++++------- 3 files changed, 39 insertions(+), 20 deletions(-) diff --git a/go/vt/workflow/reshardingworkflowgen/workflow.go b/go/vt/workflow/reshardingworkflowgen/workflow.go index 00e6c9949d0..43c48cda772 100644 --- a/go/vt/workflow/reshardingworkflowgen/workflow.go +++ b/go/vt/workflow/reshardingworkflowgen/workflow.go @@ -64,6 +64,7 @@ func (*Factory) Init(m *workflow.Manager, w *workflowpb.Workflow, args []string) skipStartWorkflows := subFlags.Bool("skip_start_workflows", true, "If true, newly created workflows will have skip_start set") phaseEnableApprovalsDesc := fmt.Sprintf("Comma separated phases that require explicit approval in the UI to execute. Phase names are: %v", strings.Join(resharding.WorkflowPhases(), ",")) phaseEnableApprovalsStr := subFlags.String("phase_enable_approvals", strings.Join(resharding.WorkflowPhases(), ","), phaseEnableApprovalsDesc) + useConsistentSnapshot := subFlags.Bool("use_consistent_snapshot", false, "Instead of pausing replication on the source, uses transactions with consistent snapshot to have a stable view of the data.") if err := subFlags.Parse(args); err != nil { return err @@ -89,6 +90,7 @@ func (*Factory) Init(m *workflow.Manager, w *workflowpb.Workflow, args []string) *splitDiffDestTabletType, *phaseEnableApprovalsStr, *skipStartWorkflows, + *useConsistentSnapshot, ) if err != nil { return err @@ -127,6 +129,7 @@ func (*Factory) Instantiate(m *workflow.Manager, w *workflowpb.Workflow, rootNod keyspaceParam: checkpoint.Settings["keyspace"], splitDiffDestTabletTypeParam: checkpoint.Settings["split_diff_dest_tablet_type"], splitCmdParam: checkpoint.Settings["split_cmd"], + useConsistentSnapshot: checkpoint.Settings["use_consistent_snapshot"], workflowsCount: workflowsCount, } createWorkflowsUINode := &workflow.Node{ @@ -188,7 +191,7 @@ func findSourceAndDestinationShards(ts *topo.Server, keyspace string) ([][][]str } // initCheckpoint initialize the checkpoint for keyspace reshard -func initCheckpoint(keyspace string, vtworkers []string, shardsToSplit [][][]string, minHealthyRdonlyTablets, splitCmd, splitDiffDestTabletType, phaseEnableApprovals string, skipStartWorkflows bool) (*workflowpb.WorkflowCheckpoint, error) { +func initCheckpoint(keyspace string, vtworkers []string, shardsToSplit [][][]string, minHealthyRdonlyTablets, splitCmd, splitDiffDestTabletType, phaseEnableApprovals string, skipStartWorkflows bool, useConsistentSnapshot bool) (*workflowpb.WorkflowCheckpoint, error) { sourceShards := 0 destShards := 0 for _, shardToSplit := range shardsToSplit { @@ -234,6 +237,7 @@ func initCheckpoint(keyspace string, vtworkers []string, shardsToSplit [][][]str "skip_start_workflows": fmt.Sprintf("%v", skipStartWorkflows), "workflows_count": fmt.Sprintf("%v", len(shardsToSplit)), "keyspace": keyspace, + "use_consistent_snapshot": fmt.Sprintf("%v", useConsistentSnapshot), }, }, nil } @@ -263,6 +267,7 @@ type reshardingWorkflowGen struct { splitDiffDestTabletTypeParam string splitCmdParam string skipStartWorkflowParam string + useConsistentSnapshot string } // Run implements workflow.Workflow interface. It creates one horizontal resharding workflow per shard to split @@ -302,6 +307,7 @@ func (hw *reshardingWorkflowGen) workflowCreator(ctx context.Context, task *work "-source_shards=" + task.Attributes["source_shards"], "-destination_shards=" + task.Attributes["destination_shards"], "-phase_enable_approvals=" + hw.phaseEnableApprovalsParam, + "-use_consistent_snapshot=" + hw.useConsistentSnapshot, } skipStart, err := strconv.ParseBool(hw.skipStartWorkflowParam) diff --git a/go/vt/workflow/reshardingworkflowgen/workflow_flaky_test.go b/go/vt/workflow/reshardingworkflowgen/workflow_flaky_test.go index 2291d28afb5..bdb4ffc5fe8 100644 --- a/go/vt/workflow/reshardingworkflowgen/workflow_flaky_test.go +++ b/go/vt/workflow/reshardingworkflowgen/workflow_flaky_test.go @@ -53,7 +53,7 @@ func TestWorfklowGenerator(t *testing.T) { workflow.StartManager(m) // Create the workflow. vtworkersParameter := testVtworkers + "," + testVtworkers - uuid, err := m.Create(ctx, keyspaceReshardingFactoryName, []string{"-keyspace=" + testKeyspace, "-vtworkers=" + vtworkersParameter, "-min_healthy_rdonly_tablets=2"}) + uuid, err := m.Create(ctx, keyspaceReshardingFactoryName, []string{"-keyspace=" + testKeyspace, "-vtworkers=" + vtworkersParameter, "-min_healthy_rdonly_tablets=2", "-use_consistent_snapshot=true"}) if err != nil { t.Fatalf("cannot create resharding workflow: %v", err) } diff --git a/web/vtctld2/src/app/shared/flags/workflow.flags.ts b/web/vtctld2/src/app/shared/flags/workflow.flags.ts index 341e19a24a5..83cdda28c8d 100644 --- a/web/vtctld2/src/app/shared/flags/workflow.flags.ts +++ b/web/vtctld2/src/app/shared/flags/workflow.flags.ts @@ -45,65 +45,71 @@ export class NewWorkflowFlags { this.flags['horizontal_resharding_min_healthy_rdonly_tablets'] = new HorizontalReshardingMinHealthyRdonlyTablets(11, 'horizontal_resharding_min_healthy_rdonly_tablets', 'horizontal_resharding'); this.flags['horizontal_resharding_min_healthy_rdonly_tablets'].positional = true; this.flags['horizontal_resharding_min_healthy_rdonly_tablets'].namedPositional = 'min_healthy_rdonly_tablets'; - this.flags['horizontal_resharding_enable_approvals_copy_schema'] = new HorizontalReshardingEnableApprovalsFlag(12, 'horizontal_resharding_enable_approvals_copy_schema', 'Copy Schema enable approvals', 'horizontal_resharding'); + this.flags['horizontal_resharding_use_consistent_snapshot'] = new HorizontalReshardingConsistentSnapshotFlag(12, 'horizontal_resharding_use_consistent_snapshot', 'Use Consistent Snapshot', 'horizontal_resharding'); + this.flags['horizontal_resharding_use_consistent_snapshot'].positional = true; + this.flags['horizontal_resharding_use_consistent_snapshot'].namedPositional = 'use_consistent_snapshot'; + this.flags['horizontal_resharding_enable_approvals_copy_schema'] = new HorizontalReshardingEnableApprovalsFlag(13, 'horizontal_resharding_enable_approvals_copy_schema', 'Copy Schema enable approvals', 'horizontal_resharding'); this.flags['horizontal_resharding_enable_approvals_copy_schema'].positional = true; this.flags['horizontal_resharding_enable_approvals_copy_schema'].namedPositional = 'copy_schema'; - this.flags['horizontal_resharding_enable_approvals_clone'] = new HorizontalReshardingEnableApprovalsFlag(13, 'horizontal_resharding_enable_approvals_clone', 'Clone enable approvals', 'horizontal_resharding'); + this.flags['horizontal_resharding_enable_approvals_clone'] = new HorizontalReshardingEnableApprovalsFlag(14, 'horizontal_resharding_enable_approvals_clone', 'Clone enable approvals', 'horizontal_resharding'); this.flags['horizontal_resharding_enable_approvals_clone'].positional = true; this.flags['horizontal_resharding_enable_approvals_clone'].namedPositional = 'clone'; - this.flags['horizontal_resharding_enable_approvals_wait_filtered_replication'] = new HorizontalReshardingEnableApprovalsFlag(14, 'horizontal_resharding_enable_approvals_wait_filtered_replication', 'Wait filtered replication enable approvals', 'horizontal_resharding'); + this.flags['horizontal_resharding_enable_approvals_wait_filtered_replication'] = new HorizontalReshardingEnableApprovalsFlag(15, 'horizontal_resharding_enable_approvals_wait_filtered_replication', 'Wait filtered replication enable approvals', 'horizontal_resharding'); this.flags['horizontal_resharding_enable_approvals_wait_filtered_replication'].positional = true; this.flags['horizontal_resharding_enable_approvals_wait_filtered_replication'].namedPositional = 'wait_for_filtered_replication'; - this.flags['horizontal_resharding_enable_approvals_diff'] = new HorizontalReshardingEnableApprovalsFlag(15, 'horizontal_resharding_enable_approvals_diff', 'Diff enable approvals', 'horizontal_resharding'); + this.flags['horizontal_resharding_enable_approvals_diff'] = new HorizontalReshardingEnableApprovalsFlag(16, 'horizontal_resharding_enable_approvals_diff', 'Diff enable approvals', 'horizontal_resharding'); this.flags['horizontal_resharding_enable_approvals_diff'].positional = true; this.flags['horizontal_resharding_enable_approvals_diff'].namedPositional = 'diff'; - this.flags['horizontal_resharding_enable_approvals_migrate_serving_types'] = new HorizontalReshardingEnableApprovalsFlag(16, 'horizontal_resharding_enable_approvals_migrate_serving_types', 'Migrate serving types enable approvals', 'horizontal_resharding'); + this.flags['horizontal_resharding_enable_approvals_migrate_serving_types'] = new HorizontalReshardingEnableApprovalsFlag(17, 'horizontal_resharding_enable_approvals_migrate_serving_types', 'Migrate serving types enable approvals', 'horizontal_resharding'); this.flags['horizontal_resharding_enable_approvals_migrate_serving_types'].positional = true; this.flags['horizontal_resharding_enable_approvals_migrate_serving_types'].namedPositional = 'migrate_rdonly,migrate_replica,migrate_master'; - this.flags['horizontal_resharding_phase_enable_approvals'] = new HorizontalReshardingPhaseEnableApprovalFlag(17, 'horizontal_resharding_phase_enable_approvals'); + this.flags['horizontal_resharding_phase_enable_approvals'] = new HorizontalReshardingPhaseEnableApprovalFlag(18, 'horizontal_resharding_phase_enable_approvals'); this.flags['horizontal_resharding_phase_enable_approvals'].positional = true; this.flags['horizontal_resharding_phase_enable_approvals'].namedPositional = 'phase_enable_approvals'; // // Flags for keyspace resharding workflow. - this.flags['hr_workflow_gen_keyspace'] = new HorizontalReshardingKeyspaceFlag(18, 'hr_workflow_gen_keyspace', 'hr_workflow_gen'); + this.flags['hr_workflow_gen_keyspace'] = new HorizontalReshardingKeyspaceFlag(19, 'hr_workflow_gen_keyspace', 'hr_workflow_gen'); this.flags['hr_workflow_gen_keyspace'].positional = true; this.flags['hr_workflow_gen_keyspace'].namedPositional = 'keyspace'; - this.flags['hr_workflow_gen_vtworkers'] = new HorizontalReshardingVtworkerFlag(19, 'hr_workflow_gen_vtworkers', 'hr_workflow_gen'); + this.flags['hr_workflow_gen_vtworkers'] = new HorizontalReshardingVtworkerFlag(20, 'hr_workflow_gen_vtworkers', 'hr_workflow_gen'); this.flags['hr_workflow_gen_vtworkers'].positional = true; this.flags['hr_workflow_gen_vtworkers'].namedPositional = 'vtworkers'; - this.flags['hr_workflow_gen_split_cmd'] = new SplitCloneCommand(20, 'hr_workflow_gen_split_cmd', 'hr_workflow_gen'); + this.flags['hr_workflow_gen_split_cmd'] = new SplitCloneCommand(21, 'hr_workflow_gen_split_cmd', 'hr_workflow_gen'); this.flags['hr_workflow_gen_split_cmd'].positional = true; this.flags['hr_workflow_gen_split_cmd'].namedPositional = 'split_cmd'; - this.flags['hr_workflow_gen_split_diff_dest_tablet_type'] = new SplitDiffTabletType(21, 'hr_workflow_gen_split_diff_dest_tablet_type', 'hr_workflow_gen'); + this.flags['hr_workflow_gen_split_diff_dest_tablet_type'] = new SplitDiffTabletType(22, 'hr_workflow_gen_split_diff_dest_tablet_type', 'hr_workflow_gen'); this.flags['hr_workflow_gen_split_diff_dest_tablet_type'].positional = true; this.flags['hr_workflow_gen_split_diff_dest_tablet_type'].namedPositional = 'split_diff_dest_tablet_type'; - this.flags['hr_workflow_gen_min_healthy_rdonly_tablets'] = new HorizontalReshardingMinHealthyRdonlyTablets(22, 'hr_workflow_gen_min_healthy_rdonly_tablets', 'hr_workflow_gen'); + this.flags['hr_workflow_gen_min_healthy_rdonly_tablets'] = new HorizontalReshardingMinHealthyRdonlyTablets(23, 'hr_workflow_gen_min_healthy_rdonly_tablets', 'hr_workflow_gen'); this.flags['hr_workflow_gen_min_healthy_rdonly_tablets'].positional = true; this.flags['hr_workflow_gen_min_healthy_rdonly_tablets'].namedPositional = 'min_healthy_rdonly_tablets'; - this.flags['hr_workflow_gen_enable_approvals_copy_schema'] = new HorizontalReshardingEnableApprovalsFlag(23, 'hr_workflow_gen_enable_approvals_copy_schema', 'Copy Schema enable approvals', 'hr_workflow_gen'); + this.flags['hr_workflow_gen_use_consistent_snapshot'] = new HorizontalReshardingConsistentSnapshotFlag(24, 'hr_workflow_gen_use_consistent_snapshot', 'Use Consistent Snapshot', 'hr_workflow_gen'); + this.flags['hr_workflow_gen_use_consistent_snapshot'].positional = true; + this.flags['hr_workflow_gen_use_consistent_snapshot'].namedPositional = 'use_consistent_snapshot'; + this.flags['hr_workflow_gen_enable_approvals_copy_schema'] = new HorizontalReshardingEnableApprovalsFlag(25, 'hr_workflow_gen_enable_approvals_copy_schema', 'Copy Schema enable approvals', 'hr_workflow_gen'); this.flags['hr_workflow_gen_enable_approvals_copy_schema'].positional = true; this.flags['hr_workflow_gen_enable_approvals_copy_schema'].namedPositional = 'copy_schema'; - this.flags['hr_workflow_gen_enable_approvals_clone'] = new HorizontalReshardingEnableApprovalsFlag(24, 'hr_workflow_gen_enable_approvals_clone', 'Clone enable approvals', 'hr_workflow_gen'); + this.flags['hr_workflow_gen_enable_approvals_clone'] = new HorizontalReshardingEnableApprovalsFlag(26, 'hr_workflow_gen_enable_approvals_clone', 'Clone enable approvals', 'hr_workflow_gen'); this.flags['hr_workflow_gen_enable_approvals_clone'].positional = true; this.flags['hr_workflow_gen_enable_approvals_clone'].namedPositional = 'clone'; - this.flags['hr_workflow_gen_enable_approvals_wait_filtered_replication'] = new HorizontalReshardingEnableApprovalsFlag(25, 'hr_workflow_gen_enable_approvals_wait_filtered_replication', 'Wait filtered replication enable approvals', 'hr_workflow_gen'); + this.flags['hr_workflow_gen_enable_approvals_wait_filtered_replication'] = new HorizontalReshardingEnableApprovalsFlag(27, 'hr_workflow_gen_enable_approvals_wait_filtered_replication', 'Wait filtered replication enable approvals', 'hr_workflow_gen'); this.flags['hr_workflow_gen_enable_approvals_wait_filtered_replication'].positional = true; this.flags['hr_workflow_gen_enable_approvals_wait_filtered_replication'].namedPositional = 'wait_for_filtered_replication'; - this.flags['hr_workflow_gen_enable_approvals_diff'] = new HorizontalReshardingEnableApprovalsFlag(26, 'hr_workflow_gen_enable_approvals_diff', 'Diff enable approvals', 'hr_workflow_gen'); + this.flags['hr_workflow_gen_enable_approvals_diff'] = new HorizontalReshardingEnableApprovalsFlag(28, 'hr_workflow_gen_enable_approvals_diff', 'Diff enable approvals', 'hr_workflow_gen'); this.flags['hr_workflow_gen_enable_approvals_diff'].positional = true; this.flags['hr_workflow_gen_enable_approvals_diff'].namedPositional = 'diff'; - this.flags['hr_workflow_gen_enable_approvals_migrate_serving_types'] = new HorizontalReshardingEnableApprovalsFlag(27, 'hr_workflow_gen_enable_approvals_migrate_serving_types', 'Migrate serving types enable approvals', 'hr_workflow_gen'); + this.flags['hr_workflow_gen_enable_approvals_migrate_serving_types'] = new HorizontalReshardingEnableApprovalsFlag(29, 'hr_workflow_gen_enable_approvals_migrate_serving_types', 'Migrate serving types enable approvals', 'hr_workflow_gen'); this.flags['hr_workflow_gen_enable_approvals_migrate_serving_types'].positional = true; this.flags['hr_workflow_gen_enable_approvals_migrate_serving_types'].namedPositional = 'migrate_rdonly,migrate_replica,migrate_master'; - this.flags['hr_workflow_gen_phase_enable_approvals'] = new HorizontalReshardingPhaseEnableApprovalFlag(28, 'hr_workflow_gen_phase_enable_approvals'); + this.flags['hr_workflow_gen_phase_enable_approvals'] = new HorizontalReshardingPhaseEnableApprovalFlag(30, 'hr_workflow_gen_phase_enable_approvals'); this.flags['hr_workflow_gen_phase_enable_approvals'].positional = true; this.flags['hr_workflow_gen_phase_enable_approvals'].namedPositional = 'phase_enable_approvals'; - this.flags['hr_workflow_gen_skip_start_workflows'] = new ReshardingWorkflowGenSkipStartFlag(30, 'hr_workflow_gen_skip_start_workflows'); + this.flags['hr_workflow_gen_skip_start_workflows'] = new ReshardingWorkflowGenSkipStartFlag(31, 'hr_workflow_gen_skip_start_workflows'); this.flags['hr_workflow_gen_skip_start_workflows'].positional = true; this.flags['hr_workflow_gen_skip_start_workflows'].namedPositional = 'skip_start_workflows'; @@ -268,6 +274,13 @@ export class HorizontalReshardingEnableApprovalsFlag extends CheckBoxFlag { } } +export class HorizontalReshardingConsistentSnapshotFlag extends CheckBoxFlag { + constructor(position: number, id: string, name: string, setDisplayOn: string, value = false) { + super(position, id, name, 'Use consistent snapshot to have a stable view of the data.', value); + this.setDisplayOn('factory_name', setDisplayOn); + } +} + // WorkflowFlags is used by the Start / Stop / Delete dialogs. export class WorkflowFlags { flags= {}; From 6400e9be7a271609f54df93eb2422485ccd3ae8f Mon Sep 17 00:00:00 2001 From: yuxiaobo Date: Wed, 18 Sep 2019 11:16:44 +0800 Subject: [PATCH 111/425] Grammar tweak Signed-off-by: yuxiaobo --- doc/TwoPhaseCommitDesign.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/TwoPhaseCommitDesign.md b/doc/TwoPhaseCommitDesign.md index 14a8efbc8f2..38b93b3f891 100644 --- a/doc/TwoPhaseCommitDesign.md +++ b/doc/TwoPhaseCommitDesign.md @@ -197,7 +197,7 @@ If VTTablet is asked to shut down or change state from master, the code that wai Eventually, a different VTTablet will be transitioned to become the master. At that point, it will recreate the unresolved transactions from redo logs. If the replays fail, we’ll raise an alert and start the query service anyway. -Typically, a replay is not expected to fail because vttablet does not allow writes to the database until the replays are done. Also, no external agent should be allowed to perform writes to MySQL, which is a loosely enforced Vitess requirement. Other vitess processes do write to MySQL directly, but they’re not the kind that interfere with the normal flow of transactions. +Typically, a replay is not expected to fail because vttablet does not allow writing to the database until the replays are done. Also, no external agent should be allowed to perform writes to MySQL, which is a loosely enforced Vitess requirement. Other vitess processes do write to MySQL directly, but they’re not the kind that interfere with the normal flow of transactions. *Unresolved issue: If a resharding happens in the middle of a prepare, such a transaction potentially becomes multiple different transactions in a target shard. For now, this means that a resharding failover has to wait for all prepared transactions to be resolved. Special code has to be written in vttablet to handle this specific workflow.* From 2722a14ae9e3a9a66964dffe97c1e2205cdf5801 Mon Sep 17 00:00:00 2001 From: Andres Taylor Date: Thu, 19 Sep 2019 06:18:59 +0200 Subject: [PATCH 112/425] Add startup argument to stop tablet from reparent Signed-off-by: Andres Taylor --- .../tabletmanager/rpc_external_reparent.go | 17 +++++++++++++++++ .../tabletmanager/rpc_external_reparent_test.go | 12 ++++++++++++ go/vt/wrangler/reparent.go | 11 +++++++++++ 3 files changed, 40 insertions(+) diff --git a/go/vt/vttablet/tabletmanager/rpc_external_reparent.go b/go/vt/vttablet/tabletmanager/rpc_external_reparent.go index 7b066ed1e1a..23745cf1aa3 100644 --- a/go/vt/vttablet/tabletmanager/rpc_external_reparent.go +++ b/go/vt/vttablet/tabletmanager/rpc_external_reparent.go @@ -21,6 +21,9 @@ import ( "sync" "time" + "vitess.io/vitess/go/vt/proto/vtrpc" + "vitess.io/vitess/go/vt/vterrors" + "github.com/golang/protobuf/proto" "golang.org/x/net/context" "vitess.io/vitess/go/event" @@ -40,8 +43,18 @@ var ( finalizeReparentTimeout = flag.Duration("finalize_external_reparent_timeout", 30*time.Second, "Timeout for the finalize stage of a fast external reparent reconciliation.") externalReparentStats = stats.NewTimings("ExternalReparents", "External reparenting time", "stage", "NewMasterVisible", "FullRebuild") + + neverParent = flag.Bool("never_reparent", false, "if set to true, Vitess will never reparent. When running on a system that handles master/follower and replication, such as Amazon Aurora, Vitess should not try to reparent") ) +// IsItSafeToReparent returns nil if we can reparent, and an error if we shouldn't +func IsItSafeToReparent() error { + if *neverParent { + return vterrors.New(vtrpc.Code_INVALID_ARGUMENT, "never_parent set to true, so will not reparent") + } + return nil +} + // SetReparentFlags changes flag values. It should only be used in tests. func SetReparentFlags(timeout time.Duration) { *finalizeReparentTimeout = timeout @@ -50,6 +63,10 @@ func SetReparentFlags(timeout time.Duration) { // TabletExternallyReparented updates all topo records so the current // tablet is the new master for this shard. func (agent *ActionAgent) TabletExternallyReparented(ctx context.Context, externalID string) error { + err := IsItSafeToReparent() + if err != nil { + return err + } if err := agent.lock(ctx); err != nil { return err } diff --git a/go/vt/vttablet/tabletmanager/rpc_external_reparent_test.go b/go/vt/vttablet/tabletmanager/rpc_external_reparent_test.go index 05cf42110b6..6ade1551cf6 100644 --- a/go/vt/vttablet/tabletmanager/rpc_external_reparent_test.go +++ b/go/vt/vttablet/tabletmanager/rpc_external_reparent_test.go @@ -19,6 +19,8 @@ package tabletmanager import ( "context" "testing" + + "github.com/stretchr/testify/assert" ) func TestTabletExternallyReparentedAlwaysUpdatesTimestamp(t *testing.T) { @@ -43,3 +45,13 @@ func TestTabletExternallyReparentedAlwaysUpdatesTimestamp(t *testing.T) { t.Fatalf("subsequent TER call did not update the timestamp: %v = %v", ter1, ter2) } } + +func TestShouldNotReparent(t *testing.T) { + ctx := context.Background() + agent := createTestAgent(ctx, t, nil) + soTrue := true + neverParent = &soTrue + + err := agent.TabletExternallyReparented(ctx, "unused_id") + assert.Error(t, err) +} diff --git a/go/vt/wrangler/reparent.go b/go/vt/wrangler/reparent.go index 06b99e21f32..a1c1d30a174 100644 --- a/go/vt/wrangler/reparent.go +++ b/go/vt/wrangler/reparent.go @@ -26,6 +26,8 @@ import ( "sync" "time" + "vitess.io/vitess/go/vt/vttablet/tabletmanager" + "vitess.io/vitess/go/event" "vitess.io/vitess/go/mysql" "vitess.io/vitess/go/sqlescape" @@ -329,6 +331,10 @@ func (wr *Wrangler) initShardMasterLocked(ctx context.Context, ev *events.Repare // PlannedReparentShard will make the provided tablet the master for the shard, // when both the current and new master are reachable and in good shape. func (wr *Wrangler) PlannedReparentShard(ctx context.Context, keyspace, shard string, masterElectTabletAlias, avoidMasterAlias *topodatapb.TabletAlias, waitSlaveTimeout time.Duration) (err error) { + err = tabletmanager.IsItSafeToReparent() + if err != nil { + return err + } // lock the shard lockAction := fmt.Sprintf( "PlannedReparentShard(%v, avoid_master=%v)", @@ -604,6 +610,11 @@ func (wr *Wrangler) chooseNewMaster( // EmergencyReparentShard will make the provided tablet the master for // the shard, when the old master is completely unreachable. func (wr *Wrangler) EmergencyReparentShard(ctx context.Context, keyspace, shard string, masterElectTabletAlias *topodatapb.TabletAlias, waitSlaveTimeout time.Duration) (err error) { + err = tabletmanager.IsItSafeToReparent() + if err != nil { + return err + } + // lock the shard ctx, unlock, lockErr := wr.ts.LockShard(ctx, keyspace, shard, fmt.Sprintf("EmergencyReparentShard(%v)", topoproto.TabletAliasString(masterElectTabletAlias))) if lockErr != nil { From 4e21d898726fc48ce84bbd09ad1c8a3ce8b33f07 Mon Sep 17 00:00:00 2001 From: Andres Taylor Date: Thu, 19 Sep 2019 07:35:24 +0200 Subject: [PATCH 113/425] Typos Signed-off-by: Andres Taylor --- go/vt/vttablet/tabletmanager/rpc_external_reparent.go | 6 +++--- go/vt/vttablet/tabletmanager/rpc_external_reparent_test.go | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/go/vt/vttablet/tabletmanager/rpc_external_reparent.go b/go/vt/vttablet/tabletmanager/rpc_external_reparent.go index 23745cf1aa3..4cdebdb5ab0 100644 --- a/go/vt/vttablet/tabletmanager/rpc_external_reparent.go +++ b/go/vt/vttablet/tabletmanager/rpc_external_reparent.go @@ -44,13 +44,13 @@ var ( externalReparentStats = stats.NewTimings("ExternalReparents", "External reparenting time", "stage", "NewMasterVisible", "FullRebuild") - neverParent = flag.Bool("never_reparent", false, "if set to true, Vitess will never reparent. When running on a system that handles master/follower and replication, such as Amazon Aurora, Vitess should not try to reparent") + neverReparent = flag.Bool("never_reparent", false, "if set to true, this tablet will not become MASTER") ) // IsItSafeToReparent returns nil if we can reparent, and an error if we shouldn't func IsItSafeToReparent() error { - if *neverParent { - return vterrors.New(vtrpc.Code_INVALID_ARGUMENT, "never_parent set to true, so will not reparent") + if *neverReparent { + return vterrors.New(vtrpc.Code_INVALID_ARGUMENT, "never_reparent set to true, so will not reparent") } return nil } diff --git a/go/vt/vttablet/tabletmanager/rpc_external_reparent_test.go b/go/vt/vttablet/tabletmanager/rpc_external_reparent_test.go index 6ade1551cf6..98d566d73ef 100644 --- a/go/vt/vttablet/tabletmanager/rpc_external_reparent_test.go +++ b/go/vt/vttablet/tabletmanager/rpc_external_reparent_test.go @@ -50,7 +50,7 @@ func TestShouldNotReparent(t *testing.T) { ctx := context.Background() agent := createTestAgent(ctx, t, nil) soTrue := true - neverParent = &soTrue + neverReparent = &soTrue err := agent.TabletExternallyReparented(ctx, "unused_id") assert.Error(t, err) From ba93b15fb76a1093096294981b6a6de9105b0ae7 Mon Sep 17 00:00:00 2001 From: Saif Alharthi Date: Fri, 20 Sep 2019 15:11:21 -0700 Subject: [PATCH 114/425] Fixed Panic for handlePrepare Signed-off-by: Saif Alharthi --- go/vt/vtgate/executor.go | 4 ++-- test/prepared_statement_test.py | 10 ++++++++++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/go/vt/vtgate/executor.go b/go/vt/vtgate/executor.go index 0350d8bc7b7..fdee70a266c 100644 --- a/go/vt/vtgate/executor.go +++ b/go/vt/vtgate/executor.go @@ -1573,9 +1573,9 @@ func (e *Executor) handlePrepare(ctx context.Context, safeSession *SafeSession, if err != nil { logStats.Error = err errCount = 1 - } else { - logStats.RowsAffected = qr.RowsAffected + return nil, err } + logStats.RowsAffected = qr.RowsAffected plan.AddStats(1, time.Since(logStats.StartTime), uint64(logStats.ShardQueries), logStats.RowsAffected, errCount) diff --git a/test/prepared_statement_test.py b/test/prepared_statement_test.py index ec479e68157..e4b7ca89f42 100755 --- a/test/prepared_statement_test.py +++ b/test/prepared_statement_test.py @@ -255,6 +255,16 @@ def test_prepared_statements(self): cursor.fetchone() cursor.close() + # Send an invalid table name to ensure that python's mysql client will not fail before entering vtgate + cursor = conn.cursor(cursor_class=MySQLCursorPrepared) + try: + cursor.execute('select * from prepare_stmt_test where id = %s', (1,)) + except mysql.connector.Error as err: + if err.errno == 1105: + print "Could not find the table" + else: + raise + cursor = conn.cursor(cursor_class=MySQLCursorPrepared) cursor.execute('select * from vt_prepare_stmt_test where id = %s', (1,)) result = cursor.fetchall() From 5a1c6842ccba0a958e604fa1b16a5a638ff9068e Mon Sep 17 00:00:00 2001 From: deepthi Date: Fri, 20 Sep 2019 17:55:01 -0700 Subject: [PATCH 115/425] TER should not demote current master if it is run with current master Signed-off-by: deepthi --- .../tabletmanager/rpc_external_reparent.go | 5 +- .../testlib/reparent_external_test.go | 68 +++++++++++++++++++ 2 files changed, 71 insertions(+), 2 deletions(-) diff --git a/go/vt/vttablet/tabletmanager/rpc_external_reparent.go b/go/vt/vttablet/tabletmanager/rpc_external_reparent.go index 848ba234f0c..5efaccb0d19 100644 --- a/go/vt/vttablet/tabletmanager/rpc_external_reparent.go +++ b/go/vt/vttablet/tabletmanager/rpc_external_reparent.go @@ -165,7 +165,8 @@ func (agent *ActionAgent) finalizeTabletExternallyReparented(ctx context.Context } }() - if !topoproto.TabletAliasIsZero(oldMasterAlias) { + // If TER is called twice, then oldMasterAlias is the same as agent.TabletAlias + if !topoproto.TabletAliasIsZero(oldMasterAlias) && !topoproto.TabletAliasEqual(oldMasterAlias, agent.TabletAlias) { wg.Add(1) go func() { defer wg.Done() @@ -237,7 +238,7 @@ func (agent *ActionAgent) finalizeTabletExternallyReparented(ctx context.Context tmc := tmclient.NewTabletManagerClient() defer tmc.Close() - if !topoproto.TabletAliasIsZero(oldMasterAlias) && oldMasterTablet != nil { + if !topoproto.TabletAliasIsZero(oldMasterAlias) && !topoproto.TabletAliasEqual(oldMasterAlias, agent.TabletAlias) && oldMasterTablet != nil { wg.Add(1) go func() { defer wg.Done() diff --git a/go/vt/wrangler/testlib/reparent_external_test.go b/go/vt/wrangler/testlib/reparent_external_test.go index 11d785f96ac..dfd86e55564 100644 --- a/go/vt/wrangler/testlib/reparent_external_test.go +++ b/go/vt/wrangler/testlib/reparent_external_test.go @@ -473,6 +473,74 @@ func TestTabletExternallyReparentedFailedImpostorMaster(t *testing.T) { } } +func TestTabletExternallyReparentedRerun(t *testing.T) { + tabletmanager.SetReparentFlags(time.Minute /* finalizeTimeout */) + + ctx := context.Background() + ts := memorytopo.NewServer("cell1", "cell2") + wr := wrangler.New(logutil.NewConsoleLogger(), ts, tmclient.NewTabletManagerClient()) + + // Create an old master, a new master, and a good slave. + oldMaster := NewFakeTablet(t, wr, "cell1", 0, topodatapb.TabletType_MASTER, nil) + newMaster := NewFakeTablet(t, wr, "cell1", 1, topodatapb.TabletType_REPLICA, nil) + goodSlave := NewFakeTablet(t, wr, "cell1", 2, topodatapb.TabletType_REPLICA, nil) + + // Reparent to a replica, and pretend the old master is not responding. + + // On the elected master, we will respond to + // TabletActionSlaveWasPromoted. + newMaster.StartActionLoop(t, wr) + defer newMaster.StopActionLoop(t) + + // On the old master, we will only respond to + // TabletActionSlaveWasRestarted. + oldMaster.StartActionLoop(t, wr) + defer oldMaster.StopActionLoop(t) + + // On the good slave, we will respond to + // TabletActionSlaveWasRestarted. + goodSlave.StartActionLoop(t, wr) + defer goodSlave.StopActionLoop(t) + + // The reparent should work as expected here + tmc := tmclient.NewTabletManagerClient() + ti, err := ts.GetTablet(ctx, newMaster.Tablet.Alias) + if err != nil { + t.Fatalf("GetTablet failed: %v", err) + } + waitID := makeWaitID() + if err := tmc.TabletExternallyReparented(context.Background(), ti.Tablet, waitID); err != nil { + t.Fatalf("TabletExternallyReparented(replica) failed: %v", err) + } + waitForExternalReparent(t, "TestTabletExternallyReparentedFailedOldMaster: good case", waitID) + + // check the old master was converted to replica + tablet, err := ts.GetTablet(ctx, oldMaster.Tablet.Alias) + if err != nil { + t.Fatalf("GetTablet(%v) failed: %v", oldMaster.Tablet.Alias, err) + } + if tablet.Type != topodatapb.TabletType_REPLICA { + t.Fatalf("old master should be replica but is: %v", tablet.Type) + } + + // run TER again and make sure the master is still correct + waitID = makeWaitID() + if err := tmc.TabletExternallyReparented(context.Background(), ti.Tablet, waitID); err != nil { + t.Fatalf("TabletExternallyReparented(replica) failed: %v", err) + } + waitForExternalReparent(t, "TestTabletExternallyReparentedFailedOldMaster: good case", waitID) + + // check the new master is still master + tablet, err = ts.GetTablet(ctx, newMaster.Tablet.Alias) + if err != nil { + t.Fatalf("GetTablet(%v) failed: %v", newMaster.Tablet.Alias, err) + } + if tablet.Type != topodatapb.TabletType_MASTER { + t.Fatalf("new master should be MASTER but is: %v", tablet.Type) + } + +} + var ( externalReparents = make(map[string]chan struct{}) externalReparentsMutex sync.Mutex From 03cc7e171763a641700970a37867cd809831c0a3 Mon Sep 17 00:00:00 2001 From: Karel Alfonso Sague Date: Mon, 23 Sep 2019 11:00:53 +1000 Subject: [PATCH 116/425] Allow enabling workflow manager in vttestserver Signed-off-by: Karel Alfonso Sague --- go/cmd/vttestserver/main.go | 2 ++ go/vt/vttest/local_cluster.go | 3 +++ go/vt/vttest/vtprocess.go | 3 +++ 3 files changed, 8 insertions(+) diff --git a/go/cmd/vttestserver/main.go b/go/cmd/vttestserver/main.go index e6280af194e..8c28cbc553b 100644 --- a/go/cmd/vttestserver/main.go +++ b/go/cmd/vttestserver/main.go @@ -154,6 +154,8 @@ func parseFlags() (config vttest.Config, env vttest.Environment, err error) { flag.StringVar(&config.TabletHostName, "tablet_hostname", "localhost", "The hostname to use for the tablet otherwise it will be derived from OS' hostname") + flag.BoolVar(&config.InitWorkflowManager, "workflow_manager_init", false, "Enable workflow manager") + flag.Parse() if basePort != 0 { diff --git a/go/vt/vttest/local_cluster.go b/go/vt/vttest/local_cluster.go index 8532052dded..4c6980baa54 100644 --- a/go/vt/vttest/local_cluster.go +++ b/go/vt/vttest/local_cluster.go @@ -110,6 +110,9 @@ type Config struct { // The host name to use for the table otherwise it will be resolved from the local hostname TabletHostName string + + // Whether to enable/disable workflow manager + InitWorkflowManager bool } // InitSchemas is a shortcut for tests that just want to setup a single diff --git a/go/vt/vttest/vtprocess.go b/go/vt/vttest/vtprocess.go index 1e917282102..9da5068fadc 100644 --- a/go/vt/vttest/vtprocess.go +++ b/go/vt/vttest/vtprocess.go @@ -243,6 +243,9 @@ func VtcomboProcess(env Environment, args *Config, mysql MySQLManager) *VtProces if args.TabletHostName != "" { vt.ExtraArgs = append(vt.ExtraArgs, []string{"-tablet_hostname", args.TabletHostName}...) } + if args.InitWorkflowManager { + vt.ExtraArgs = append(vt.ExtraArgs, []string{"-workflow_manager_init"}...) + } if socket != "" { vt.ExtraArgs = append(vt.ExtraArgs, []string{ From 0c493d6bb21854c592c1598325b987520aa1b946 Mon Sep 17 00:00:00 2001 From: Jacques Grove Date: Mon, 23 Sep 2019 17:33:28 -0700 Subject: [PATCH 117/425] Fix for #5214 by adding back bits of install_protoc-gen-go Signed-off-by: Jacques Grove --- Makefile | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Makefile b/Makefile index bc80f423c7a..cf693d775bc 100644 --- a/Makefile +++ b/Makefile @@ -112,6 +112,9 @@ java_test: go install ./go/cmd/vtgateclienttest ./go/cmd/vtcombo mvn -f java/pom.xml clean verify +install_protoc-gen-go: + go install github.com/golang/protobuf/protoc-gen-go + # Find protoc compiler. # NOTE: We are *not* using the "protoc" binary (as suggested by the grpc Go # quickstart for example). Instead, we run "protoc" via the Python From b600193b8cf417a88f5fd6b7e01c6ab41691f198 Mon Sep 17 00:00:00 2001 From: Yun Lai Date: Tue, 24 Sep 2019 09:26:21 +1000 Subject: [PATCH 118/425] Added exclude_tables flag in workflow and pass it down to vtworker Signed-off-by: Yun Lai --- go/vt/workflow/resharding/tasks.go | 15 +++- go/vt/workflow/resharding/workflow.go | 9 +- go/vt/workflow/resharding/workflow_test.go | 40 ++++++--- .../reshardingworkflowgen/workflow.go | 7 +- .../workflow_flaky_test.go | 2 +- web/vtctld2/app/index.html | 2 +- web/vtctld2/app/inline.js | 2 +- ...js => main.38a1a560f8f628e31552.bundle.js} | 84 +++++++++--------- .../main.38a1a560f8f628e31552.bundle.js.gz | Bin 0 -> 366809 bytes .../main.f08922949ce1705e18fe.bundle.js.gz | Bin 366329 -> 0 bytes web/vtctld2/app/plotly-latest.min.js | 2 +- .../src/app/shared/flags/workflow.flags.ts | 59 +++++++----- 12 files changed, 136 insertions(+), 86 deletions(-) rename web/vtctld2/app/{main.f08922949ce1705e18fe.bundle.js => main.38a1a560f8f628e31552.bundle.js} (81%) create mode 100644 web/vtctld2/app/main.38a1a560f8f628e31552.bundle.js.gz delete mode 100644 web/vtctld2/app/main.f08922949ce1705e18fe.bundle.js.gz diff --git a/go/vt/workflow/resharding/tasks.go b/go/vt/workflow/resharding/tasks.go index c5fc64aa357..7ad4d04ad2f 100644 --- a/go/vt/workflow/resharding/tasks.go +++ b/go/vt/workflow/resharding/tasks.go @@ -61,7 +61,8 @@ func (hw *horizontalReshardingWorkflow) runCopySchema(ctx context.Context, t *wo keyspace := t.Attributes["keyspace"] sourceShard := t.Attributes["source_shard"] destShard := t.Attributes["destination_shard"] - return hw.wr.CopySchemaShardFromShard(ctx, nil /* tableArray*/, nil /* excludeTableArray */, true, /*includeViews*/ + excludeTables := strings.Split(t.Attributes["exclude_tables"], ",") + return hw.wr.CopySchemaShardFromShard(ctx, nil /* tableArray*/, excludeTables /* excludeTableArray */, true, /*includeViews*/ keyspace, sourceShard, keyspace, destShard, wrangler.DefaultWaitSlaveTimeout) } @@ -74,6 +75,7 @@ func (hw *horizontalReshardingWorkflow) runSplitClone(ctx context.Context, t *wo useConsistentSnapshot := t.Attributes["use_consistent_snapshot"] sourceKeyspaceShard := topoproto.KeyspaceShardString(keyspace, sourceShard) + excludeTables := t.Attributes["exclude_tables"] // Reset the vtworker to avoid error if vtworker command has been called elsewhere. // This is because vtworker class doesn't cleanup the environment after execution. if _, err := automation.ExecuteVtworker(ctx, worker, []string{"Reset"}); err != nil { @@ -84,6 +86,11 @@ func (hw *horizontalReshardingWorkflow) runSplitClone(ctx context.Context, t *wo if useConsistentSnapshot != "" { args = append(args, "--use_consistent_snapshot") } + + if excludeTables != "" { + args = append(args, "--exclude_tables="+excludeTables) + } + _, err := automation.ExecuteVtworker(hw.ctx, worker, args) return err } @@ -100,6 +107,7 @@ func (hw *horizontalReshardingWorkflow) runSplitDiff(ctx context.Context, t *wor destinationTabletType := t.Attributes["dest_tablet_type"] worker := t.Attributes["vtworker"] useConsistentSnapshot := t.Attributes["use_consistent_snapshot"] + excludeTables := t.Attributes["exclude_tables"] if _, err := automation.ExecuteVtworker(hw.ctx, worker, []string{"Reset"}); err != nil { return err @@ -108,6 +116,11 @@ func (hw *horizontalReshardingWorkflow) runSplitDiff(ctx context.Context, t *wor if useConsistentSnapshot != "" { args = append(args, "--use_consistent_snapshot") } + + if excludeTables != "" { + args = append(args, "--exclude_tables="+excludeTables) + } + _, err := automation.ExecuteVtworker(ctx, worker, args) return err } diff --git a/go/vt/workflow/resharding/workflow.go b/go/vt/workflow/resharding/workflow.go index dedd4f7989b..8f714afb690 100644 --- a/go/vt/workflow/resharding/workflow.go +++ b/go/vt/workflow/resharding/workflow.go @@ -68,6 +68,7 @@ func (*Factory) Init(m *workflow.Manager, w *workflowpb.Workflow, args []string) subFlags := flag.NewFlagSet(horizontalReshardingFactoryName, flag.ContinueOnError) keyspace := subFlags.String("keyspace", "", "Name of keyspace to perform horizontal resharding") vtworkersStr := subFlags.String("vtworkers", "", "A comma-separated list of vtworker addresses") + excludeTablesStr := subFlags.String("exclude_tables", "", "A comma-separated list of tables to exclude") sourceShardsStr := subFlags.String("source_shards", "", "A comma-separated list of source shards") destinationShardsStr := subFlags.String("destination_shards", "", "A comma-separated list of destination shards") minHealthyRdonlyTablets := subFlags.String("min_healthy_rdonly_tablets", "1", "Minimum number of healthy RDONLY tablets required in source shards") @@ -85,6 +86,7 @@ func (*Factory) Init(m *workflow.Manager, w *workflowpb.Workflow, args []string) } vtworkers := strings.Split(*vtworkersStr, ",") + excludeTables := strings.Split(*excludeTablesStr, ",") sourceShards := strings.Split(*sourceShardsStr, ",") destinationShards := strings.Split(*destinationShardsStr, ",") phaseEnableApprovals := parsePhaseEnableApprovals(*phaseEnableApprovalsStr) @@ -110,7 +112,7 @@ func (*Factory) Init(m *workflow.Manager, w *workflowpb.Workflow, args []string) } w.Name = fmt.Sprintf("Reshard shards %v into shards %v of keyspace %v.", *keyspace, *sourceShardsStr, *destinationShardsStr) - checkpoint, err := initCheckpoint(*keyspace, vtworkers, sourceShards, destinationShards, *minHealthyRdonlyTablets, *splitCmd, *splitDiffDestTabletType, useConsistentSnapshotArg) + checkpoint, err := initCheckpoint(*keyspace, vtworkers, excludeTables, sourceShards, destinationShards, *minHealthyRdonlyTablets, *splitCmd, *splitDiffDestTabletType, useConsistentSnapshotArg) if err != nil { return err } @@ -269,13 +271,14 @@ func validateWorkflow(m *workflow.Manager, keyspace string, vtworkers, sourceSha } // initCheckpoint initialize the checkpoint for the horizontal workflow. -func initCheckpoint(keyspace string, vtworkers, sourceShards, destinationShards []string, minHealthyRdonlyTablets, splitCmd, splitDiffDestTabletType string, useConsistentSnapshot string) (*workflowpb.WorkflowCheckpoint, error) { +func initCheckpoint(keyspace string, vtworkers, excludeTables, sourceShards, destinationShards []string, minHealthyRdonlyTablets, splitCmd, splitDiffDestTabletType string, useConsistentSnapshot string) (*workflowpb.WorkflowCheckpoint, error) { tasks := make(map[string]*workflowpb.Task) initTasks(tasks, phaseCopySchema, destinationShards, func(i int, shard string) map[string]string { return map[string]string{ "keyspace": keyspace, "source_shard": sourceShards[0], "destination_shard": shard, + "exclude_tables": strings.Join(excludeTables, ","), } }) initTasks(tasks, phaseClone, sourceShards, func(i int, shard string) map[string]string { @@ -286,6 +289,7 @@ func initCheckpoint(keyspace string, vtworkers, sourceShards, destinationShards "split_cmd": splitCmd, "vtworker": vtworkers[i], "use_consistent_snapshot": useConsistentSnapshot, + "exclude_tables": strings.Join(excludeTables, ","), } }) initTasks(tasks, phaseWaitForFilteredReplication, destinationShards, func(i int, shard string) map[string]string { @@ -301,6 +305,7 @@ func initCheckpoint(keyspace string, vtworkers, sourceShards, destinationShards "dest_tablet_type": splitDiffDestTabletType, "vtworker": vtworkers[i], "use_consistent_snapshot": useConsistentSnapshot, + "exclude_tables": strings.Join(excludeTables, ","), } }) initTasks(tasks, phaseMigrateRdonly, sourceShards, func(i int, shard string) map[string]string { diff --git a/go/vt/workflow/resharding/workflow_test.go b/go/vt/workflow/resharding/workflow_test.go index bc3d7478240..2af2703d50b 100644 --- a/go/vt/workflow/resharding/workflow_test.go +++ b/go/vt/workflow/resharding/workflow_test.go @@ -55,7 +55,7 @@ func TestSourceDestShards(t *testing.T) { defer ctrl.Finish() // Set up the fakeworkerclient. It is used at SplitClone and SplitDiff phase. - fakeVtworkerClient := setupFakeVtworker(testKeyspace, testVtworkers, false) + fakeVtworkerClient := setupFakeVtworker(testKeyspace, testVtworkers, false, "") vtworkerclient.RegisterFactory("fake", fakeVtworkerClient.FakeVtworkerClientFactory) defer vtworkerclient.UnregisterFactoryForTest("fake") @@ -90,15 +90,20 @@ func TestSourceDestShards(t *testing.T) { // TestHorizontalResharding runs the happy path of HorizontalReshardingWorkflow. func TestHorizontalResharding(t *testing.T) { - testHorizontalReshardingWorkflow(t, false) + testHorizontalReshardingWorkflow(t, false, "") } // TestHorizontalReshardingWithConsistentSnapshot runs the happy path of HorizontalReshardingWorkflow with consistent snapshot. func TestHorizontalReshardingWithConsistentSnapshot(t *testing.T) { - testHorizontalReshardingWorkflow(t, true) + testHorizontalReshardingWorkflow(t, true, "") } -func testHorizontalReshardingWorkflow(t *testing.T, useConsistentSnapshot bool) { +// TestHorizontalReshardingWithExcludedTables runs the happy path of HorizontalReshardingWorkflow with excluded tables. +func TestHorizontalReshardingWithExcludedTables(t *testing.T) { + testHorizontalReshardingWorkflow(t, true, "table_a,table_b") +} + +func testHorizontalReshardingWorkflow(t *testing.T, useConsistentSnapshot bool, excludeTables string) { ctx := context.Background() // Set up the mock wrangler. It is used for the CopySchema, // WaitforFilteredReplication and Migrate phase. @@ -106,7 +111,7 @@ func testHorizontalReshardingWorkflow(t *testing.T, useConsistentSnapshot bool) defer ctrl.Finish() mockWranglerInterface := setupMockWrangler(ctrl, testKeyspace) // Set up the fakeworkerclient. It is used at SplitClone and SplitDiff phase. - fakeVtworkerClient := setupFakeVtworker(testKeyspace, testVtworkers, useConsistentSnapshot) + fakeVtworkerClient := setupFakeVtworker(testKeyspace, testVtworkers, useConsistentSnapshot, excludeTables) vtworkerclient.RegisterFactory("fake", fakeVtworkerClient.FakeVtworkerClientFactory) defer vtworkerclient.UnregisterFactoryForTest("fake") // Initialize the topology. @@ -120,6 +125,9 @@ func testHorizontalReshardingWorkflow(t *testing.T, useConsistentSnapshot bool) if useConsistentSnapshot { args = append(args, "-use_consistent_snapshot") } + if excludeTables != "" { + args = append(args, "-exclude_tables="+excludeTables) + } uuid, err := m.Create(ctx, horizontalReshardingFactoryName, args) if err != nil { t.Fatalf("cannot create resharding workflow: %v", err) @@ -148,15 +156,15 @@ func testHorizontalReshardingWorkflow(t *testing.T, useConsistentSnapshot bool) wg.Wait() } -func setupFakeVtworker(keyspace, vtworkers string, useConsistentSnapshot bool) *fakevtworkerclient.FakeVtworkerClient { +func setupFakeVtworker(keyspace, vtworkers string, useConsistentSnapshot bool, excludeTables string) *fakevtworkerclient.FakeVtworkerClient { flag.Set("vtworker_client_protocol", "fake") fakeVtworkerClient := fakevtworkerclient.NewFakeVtworkerClient() fakeVtworkerClient.RegisterResultForAddr(vtworkers, resetCommand(), "", nil) - fakeVtworkerClient.RegisterResultForAddr(vtworkers, splitCloneCommand(keyspace, useConsistentSnapshot), "", nil) + fakeVtworkerClient.RegisterResultForAddr(vtworkers, splitCloneCommand(keyspace, useConsistentSnapshot, excludeTables), "", nil) fakeVtworkerClient.RegisterResultForAddr(vtworkers, resetCommand(), "", nil) - fakeVtworkerClient.RegisterResultForAddr(vtworkers, splitDiffCommand(keyspace, "-80", useConsistentSnapshot), "", nil) + fakeVtworkerClient.RegisterResultForAddr(vtworkers, splitDiffCommand(keyspace, "-80", useConsistentSnapshot, excludeTables), "", nil) fakeVtworkerClient.RegisterResultForAddr(vtworkers, resetCommand(), "", nil) - fakeVtworkerClient.RegisterResultForAddr(vtworkers, splitDiffCommand(keyspace, "80-", useConsistentSnapshot), "", nil) + fakeVtworkerClient.RegisterResultForAddr(vtworkers, splitDiffCommand(keyspace, "80-", useConsistentSnapshot, excludeTables), "", nil) return fakeVtworkerClient } @@ -164,27 +172,33 @@ func resetCommand() []string { return []string{"Reset"} } -func splitCloneCommand(keyspace string, useConsistentSnapshot bool) []string { +func splitCloneCommand(keyspace string, useConsistentSnapshot bool, excludeTables string) []string { args := []string{"SplitClone", "--min_healthy_rdonly_tablets=2", keyspace + "/0"} if useConsistentSnapshot { args = append(args, "--use_consistent_snapshot") } + if excludeTables != "" { + args = append(args, "--exclude_tables="+excludeTables) + } return args } -func splitDiffCommand(keyspace string, shardId string, useConsistentSnapshot bool) []string { +func splitDiffCommand(keyspace string, shardId string, useConsistentSnapshot bool, excludeTables string) []string { args := []string{"SplitDiff", "--min_healthy_rdonly_tablets=1", "--dest_tablet_type=RDONLY", keyspace + "/" + shardId} if useConsistentSnapshot { args = append(args, "--use_consistent_snapshot") } + if excludeTables != "" { + args = append(args, "--exclude_tables="+excludeTables) + } return args } func setupMockWrangler(ctrl *gomock.Controller, keyspace string) *MockReshardingWrangler { mockWranglerInterface := NewMockReshardingWrangler(ctrl) // Set the expected behaviors for mock wrangler. - mockWranglerInterface.EXPECT().CopySchemaShardFromShard(gomock.Any(), nil /* tableArray*/, nil /* excludeTableArray */, true /*includeViews*/, keyspace, "0", keyspace, "-80", wrangler.DefaultWaitSlaveTimeout).Return(nil) - mockWranglerInterface.EXPECT().CopySchemaShardFromShard(gomock.Any(), nil /* tableArray*/, nil /* excludeTableArray */, true /*includeViews*/, keyspace, "0", keyspace, "80-", wrangler.DefaultWaitSlaveTimeout).Return(nil) + mockWranglerInterface.EXPECT().CopySchemaShardFromShard(gomock.Any(), nil /* tableArray*/, gomock.Any() /* excludeTableArray */, true /*includeViews*/, keyspace, "0", keyspace, "-80", wrangler.DefaultWaitSlaveTimeout).Return(nil) + mockWranglerInterface.EXPECT().CopySchemaShardFromShard(gomock.Any(), nil /* tableArray*/, gomock.Any() /* excludeTableArray */, true /*includeViews*/, keyspace, "0", keyspace, "80-", wrangler.DefaultWaitSlaveTimeout).Return(nil) mockWranglerInterface.EXPECT().WaitForFilteredReplication(gomock.Any(), keyspace, "-80", wrangler.DefaultWaitForFilteredReplicationMaxDelay).Return(nil) mockWranglerInterface.EXPECT().WaitForFilteredReplication(gomock.Any(), keyspace, "80-", wrangler.DefaultWaitForFilteredReplicationMaxDelay).Return(nil) diff --git a/go/vt/workflow/reshardingworkflowgen/workflow.go b/go/vt/workflow/reshardingworkflowgen/workflow.go index 43c48cda772..4a6cee33835 100644 --- a/go/vt/workflow/reshardingworkflowgen/workflow.go +++ b/go/vt/workflow/reshardingworkflowgen/workflow.go @@ -58,6 +58,7 @@ func (*Factory) Init(m *workflow.Manager, w *workflowpb.Workflow, args []string) subFlags := flag.NewFlagSet(keyspaceReshardingFactoryName, flag.ContinueOnError) keyspace := subFlags.String("keyspace", "", "Name of keyspace to perform horizontal resharding") vtworkersStr := subFlags.String("vtworkers", "", "A comma-separated list of vtworker addresses") + excludeTablesStr := subFlags.String("exclude_tables", "", "A comma-separated list of tables to exclude") minHealthyRdonlyTablets := subFlags.String("min_healthy_rdonly_tablets", "1", "Minimum number of healthy RDONLY tablets required in source shards") splitCmd := subFlags.String("split_cmd", "SplitClone", "Split command to use to perform horizontal resharding (either SplitClone or LegacySplitClone)") splitDiffDestTabletType := subFlags.String("split_diff_dest_tablet_type", "RDONLY", "Specifies tablet type to use in destination shards while performing SplitDiff operation") @@ -74,6 +75,7 @@ func (*Factory) Init(m *workflow.Manager, w *workflowpb.Workflow, args []string) } vtworkers := strings.Split(*vtworkersStr, ",") + excludeTables := strings.Split(*excludeTablesStr, ",") w.Name = fmt.Sprintf("Keyspace reshard on %s", *keyspace) shardsToSplit, err := findSourceAndDestinationShards(m.TopoServer(), *keyspace) @@ -84,6 +86,7 @@ func (*Factory) Init(m *workflow.Manager, w *workflowpb.Workflow, args []string) checkpoint, err := initCheckpoint( *keyspace, vtworkers, + excludeTables, shardsToSplit, *minHealthyRdonlyTablets, *splitCmd, @@ -191,7 +194,7 @@ func findSourceAndDestinationShards(ts *topo.Server, keyspace string) ([][][]str } // initCheckpoint initialize the checkpoint for keyspace reshard -func initCheckpoint(keyspace string, vtworkers []string, shardsToSplit [][][]string, minHealthyRdonlyTablets, splitCmd, splitDiffDestTabletType, phaseEnableApprovals string, skipStartWorkflows bool, useConsistentSnapshot bool) (*workflowpb.WorkflowCheckpoint, error) { +func initCheckpoint(keyspace string, vtworkers, excludeTables []string, shardsToSplit [][][]string, minHealthyRdonlyTablets, splitCmd, splitDiffDestTabletType, phaseEnableApprovals string, skipStartWorkflows bool, useConsistentSnapshot bool) (*workflowpb.WorkflowCheckpoint, error) { sourceShards := 0 destShards := 0 for _, shardToSplit := range shardsToSplit { @@ -238,6 +241,7 @@ func initCheckpoint(keyspace string, vtworkers []string, shardsToSplit [][][]str "workflows_count": fmt.Sprintf("%v", len(shardsToSplit)), "keyspace": keyspace, "use_consistent_snapshot": fmt.Sprintf("%v", useConsistentSnapshot), + "exclude_tables": fmt.Sprintf("%v", strings.Join(excludeTables, ",")), }, }, nil } @@ -301,6 +305,7 @@ func (hw *reshardingWorkflowGen) workflowCreator(ctx context.Context, task *work horizontalReshardingParams := []string{ "-keyspace=" + hw.keyspaceParam, "-vtworkers=" + task.Attributes["vtworkers"], + "-exclude_tables=" + task.Attributes["exclude_tables"], "-split_cmd=" + hw.splitCmdParam, "-split_diff_dest_tablet_type=" + hw.splitDiffDestTabletTypeParam, "-min_healthy_rdonly_tablets=" + hw.minHealthyRdonlyTabletsParam, diff --git a/go/vt/workflow/reshardingworkflowgen/workflow_flaky_test.go b/go/vt/workflow/reshardingworkflowgen/workflow_flaky_test.go index bdb4ffc5fe8..d929b8daf39 100644 --- a/go/vt/workflow/reshardingworkflowgen/workflow_flaky_test.go +++ b/go/vt/workflow/reshardingworkflowgen/workflow_flaky_test.go @@ -53,7 +53,7 @@ func TestWorfklowGenerator(t *testing.T) { workflow.StartManager(m) // Create the workflow. vtworkersParameter := testVtworkers + "," + testVtworkers - uuid, err := m.Create(ctx, keyspaceReshardingFactoryName, []string{"-keyspace=" + testKeyspace, "-vtworkers=" + vtworkersParameter, "-min_healthy_rdonly_tablets=2", "-use_consistent_snapshot=true"}) + uuid, err := m.Create(ctx, keyspaceReshardingFactoryName, []string{"-keyspace=" + testKeyspace, "-vtworkers=" + vtworkersParameter, "-min_healthy_rdonly_tablets=2", "-use_consistent_snapshot=true", "-exclude_tables=table_a,table_b"}) if err != nil { t.Fatalf("cannot create resharding workflow: %v", err) } diff --git a/web/vtctld2/app/index.html b/web/vtctld2/app/index.html index 70ef85f14ed..0c7fa761667 100644 --- a/web/vtctld2/app/index.html +++ b/web/vtctld2/app/index.html @@ -27,5 +27,5 @@ Loading... - + diff --git a/web/vtctld2/app/inline.js b/web/vtctld2/app/inline.js index 2ac73298ee9..37bbf2184d3 100644 --- a/web/vtctld2/app/inline.js +++ b/web/vtctld2/app/inline.js @@ -1 +1 @@ -!function(e){function __webpack_require__(r){if(t[r])return t[r].exports;var n=t[r]={i:r,l:!1,exports:{}};return e[r].call(n.exports,n,n.exports,__webpack_require__),n.l=!0,n.exports}var r=window.webpackJsonp;window.webpackJsonp=function(t,o,c){for(var _,a,i,u=0,p=[];u1;){var o=r.shift();i=i.hasOwnProperty(o)&&isPresent(i[o])?i[o]:i[o]={}}void 0!==i&&null!==i||(i={}),i[r.shift()]=n}function getSymbolIterator(){if(isBlank(h))if(isPresent(n.Symbol)&&isPresent(Symbol.iterator))h=Symbol.iterator;else for(var e=Object.getOwnPropertyNames(Map.prototype),t=0;t=0&&e[r]==t;r--)n--;e=e.substring(0,n)}return e},StringWrapper.replace=function(e,t,n){return e.replace(t,n)},StringWrapper.replaceAll=function(e,t,n){return e.replace(t,n)},StringWrapper.slice=function(e,t,n){return void 0===t&&(t=0),void 0===n&&(n=null),e.slice(t,null===n?void 0:n)},StringWrapper.replaceAllMapped=function(e,t,n){return e.replace(t,function(){for(var e=[],t=0;tt?1:0},StringWrapper}();t.StringWrapper=s;var a=function(){function StringJoiner(e){void 0===e&&(e=[]),this.parts=e}return StringJoiner.prototype.add=function(e){this.parts.push(e)},StringJoiner.prototype.toString=function(){return this.parts.join("")},StringJoiner}();t.StringJoiner=a;var l=function(e){function NumberParseError(t){e.call(this),this.message=t}return r(NumberParseError,e),NumberParseError.prototype.toString=function(){return this.message},NumberParseError}(Error);t.NumberParseError=l;var c=function(){function NumberWrapper(){}return NumberWrapper.toFixed=function(e,t){return e.toFixed(t)},NumberWrapper.equal=function(e,t){return e===t},NumberWrapper.parseIntAutoRadix=function(e){var t=parseInt(e);if(isNaN(t))throw new l("Invalid integer literal when parsing "+e);return t},NumberWrapper.parseInt=function(e,t){if(10==t){if(/^(\-|\+)?[0-9]+$/.test(e))return parseInt(e,t)}else if(16==t){if(/^(\-|\+)?[0-9ABCDEFabcdef]+$/.test(e))return parseInt(e,t)}else{var n=parseInt(e,t);if(!isNaN(n))return n}throw new l("Invalid integer literal when parsing "+e+" in base "+t)},NumberWrapper.parseFloat=function(e){return parseFloat(e)},Object.defineProperty(NumberWrapper,"NaN",{get:function(){return NaN},enumerable:!0,configurable:!0}),NumberWrapper.isNumeric=function(e){return!isNaN(e-parseFloat(e))},NumberWrapper.isNaN=function(e){return isNaN(e)},NumberWrapper.isInteger=function(e){return Number.isInteger(e)},NumberWrapper}();t.NumberWrapper=c,t.RegExp=i.RegExp;var u=function(){function FunctionWrapper(){}return FunctionWrapper.apply=function(e,t){return e.apply(null,t)},FunctionWrapper.bind=function(e,t){return e.bind(t)},FunctionWrapper}();t.FunctionWrapper=u,t.looseIdentical=looseIdentical,t.getMapKey=getMapKey,t.normalizeBlank=normalizeBlank,t.normalizeBool=normalizeBool,t.isJsObject=isJsObject,t.print=print,t.warn=warn;var p=function(){function Json(){}return Json.parse=function(e){return i.JSON.parse(e)},Json.stringify=function(e){return i.JSON.stringify(e,null,2)},Json}();t.Json=p;var d=function(){function DateWrapper(){}return DateWrapper.create=function(e,n,r,i,o,s,a){return void 0===n&&(n=1),void 0===r&&(r=1),void 0===i&&(i=0),void 0===o&&(o=0),void 0===s&&(s=0),void 0===a&&(a=0),new t.Date(e,n-1,r,i,o,s,a)},DateWrapper.fromISOString=function(e){return new t.Date(e)},DateWrapper.fromMillis=function(e){return new t.Date(e)},DateWrapper.toMillis=function(e){return e.getTime()},DateWrapper.now=function(){return new t.Date},DateWrapper.toJson=function(e){return e.toJSON()},DateWrapper}();t.DateWrapper=d,t.setValueOnPath=setValueOnPath;var h=null;t.getSymbolIterator=getSymbolIterator,t.evalExpression=evalExpression,t.isPrimitive=isPrimitive,t.hasConstructor=hasConstructor,t.escape=escape,t.escapeRegExp=escapeRegExp}).call(t,n(82))},4,function(e,t,n){"use strict";var r=this&&this.__extends||function(e,t){function __(){this.constructor=e}for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n]);e.prototype=null===t?Object.create(t):(__.prototype=t.prototype,new __)},i=n(217),o=n(41),s=n(215),a=n(897),l=function(e){function Subscriber(t,n,r){switch(e.call(this),this.syncErrorValue=null,this.syncErrorThrown=!1,this.syncErrorThrowable=!1,this.isStopped=!1,arguments.length){case 0:this.destination=a.empty;break;case 1:if(!t){this.destination=a.empty;break}if("object"==typeof t){t instanceof Subscriber?(this.destination=t,this.destination.add(this)):(this.syncErrorThrowable=!0,this.destination=new c(this,t));break}default:this.syncErrorThrowable=!0,this.destination=new c(this,t,n,r)}}return r(Subscriber,e),Subscriber.create=function(e,t,n){var r=new Subscriber(e,t,n);return r.syncErrorThrowable=!1,r},Subscriber.prototype.next=function(e){this.isStopped||this._next(e)},Subscriber.prototype.error=function(e){this.isStopped||(this.isStopped=!0,this._error(e))},Subscriber.prototype.complete=function(){this.isStopped||(this.isStopped=!0,this._complete())},Subscriber.prototype.unsubscribe=function(){this.isUnsubscribed||(this.isStopped=!0,e.prototype.unsubscribe.call(this))},Subscriber.prototype._next=function(e){this.destination.next(e)},Subscriber.prototype._error=function(e){this.destination.error(e),this.unsubscribe()},Subscriber.prototype._complete=function(){this.destination.complete(),this.unsubscribe()},Subscriber.prototype[s.$$rxSubscriber]=function(){return this},Subscriber}(o.Subscription);t.Subscriber=l;var c=function(e){function SafeSubscriber(t,n,r,o){e.call(this),this._parent=t;var s,a=this;i.isFunction(n)?s=n:n&&(a=n,s=n.next,r=n.error,o=n.complete,i.isFunction(a.unsubscribe)&&this.add(a.unsubscribe.bind(a)),a.unsubscribe=this.unsubscribe.bind(this)),this._context=a,this._next=s,this._error=r,this._complete=o}return r(SafeSubscriber,e),SafeSubscriber.prototype.next=function(e){if(!this.isStopped&&this._next){var t=this._parent;t.syncErrorThrowable?this.__tryOrSetError(t,this._next,e)&&this.unsubscribe():this.__tryOrUnsub(this._next,e)}},SafeSubscriber.prototype.error=function(e){if(!this.isStopped){var t=this._parent;if(this._error)t.syncErrorThrowable?(this.__tryOrSetError(t,this._error,e),this.unsubscribe()):(this.__tryOrUnsub(this._error,e),this.unsubscribe());else{if(!t.syncErrorThrowable)throw this.unsubscribe(),e;t.syncErrorValue=e,t.syncErrorThrown=!0,this.unsubscribe()}}},SafeSubscriber.prototype.complete=function(){if(!this.isStopped){var e=this._parent;this._complete?e.syncErrorThrowable?(this.__tryOrSetError(e,this._complete),this.unsubscribe()):(this.__tryOrUnsub(this._complete),this.unsubscribe()):this.unsubscribe()}},SafeSubscriber.prototype.__tryOrUnsub=function(e,t){try{e.call(this._context,t)}catch(n){throw this.unsubscribe(),n}},SafeSubscriber.prototype.__tryOrSetError=function(e,t,n){try{t.call(this._context,n)}catch(r){return e.syncErrorValue=r,e.syncErrorThrown=!0,!0}return!1},SafeSubscriber.prototype._unsubscribe=function(){var e=this._parent;this._context=null,this._parent=null,e.unsubscribe()},SafeSubscriber}(l)},4,function(e,t,n){var r=n(15);e.exports=function(e){if(!r(e))throw TypeError(e+" is not an object!");return e}},function(e,t,n){"use strict";var r=this&&this.__decorate||function(e,t,n,r){var i,o=arguments.length,s=o<3?t:null===r?r=Object.getOwnPropertyDescriptor(t,n):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(e,t,n,r);else for(var a=e.length-1;a>=0;a--)(i=e[a])&&(s=(o<3?i(s):o>3?i(t,n,s):i(t,n))||s);return o>3&&s&&Object.defineProperty(t,n,s),s},i=this&&this.__metadata||function(e,t){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(e,t)},o=n(0),s=function(){function DomHandler(){}return DomHandler.prototype.addClass=function(e,t){e.classList?e.classList.add(t):e.className+=" "+t},DomHandler.prototype.addMultipleClasses=function(e,t){if(e.classList)for(var n=t.split(" "),r=0;rwindow.innerHeight?-1*i.height:o,r=a.left+i.width>window.innerWidth?s-i.width:0,e.style.top=n+"px",e.style.left=r+"px"},DomHandler.prototype.absolutePosition=function(e,t){var n,r,i=e.offsetParent?{width:e.offsetWidth,height:e.offsetHeight}:this.getHiddenElementDimensions(e),o=i.height,s=i.width,a=t.offsetHeight,l=t.offsetWidth,c=t.getBoundingClientRect(),u=this.getWindowScrollTop(),p=this.getWindowScrollLeft();n=c.top+a+o>window.innerHeight?c.top+u-o:a+c.top+u,r=c.left+l+s>window.innerWidth?c.left+p+l-s:c.left+p,e.style.top=n+"px",e.style.left=r+"px"},DomHandler.prototype.getHiddenElementOuterHeight=function(e){e.style.visibility="hidden",e.style.display="block";var t=e.offsetHeight;return e.style.display="none",e.style.visibility="visible",t},DomHandler.prototype.getHiddenElementOuterWidth=function(e){e.style.visibility="hidden",e.style.display="block";var t=e.offsetWidth;return e.style.display="none",e.style.visibility="visible",t},DomHandler.prototype.getHiddenElementDimensions=function(e){var t={};return e.style.visibility="hidden",e.style.display="block",t.width=e.offsetWidth,t.height=e.offsetHeight,e.style.display="none",e.style.visibility="visible",t},DomHandler.prototype.scrollInView=function(e,t){var n=getComputedStyle(e).getPropertyValue("borderTopWidth"),r=n?parseFloat(n):0,i=getComputedStyle(e).getPropertyValue("paddingTop"),o=i?parseFloat(i):0,s=e.getBoundingClientRect(),a=t.getBoundingClientRect(),l=a.top+document.body.scrollTop-(s.top+document.body.scrollTop)-r-o,c=e.scrollTop,u=e.clientHeight,p=this.getOuterHeight(t);l<0?e.scrollTop=c+l:l+p>u&&(e.scrollTop=c+l-u+p)},DomHandler.prototype.fadeIn=function(e,t){e.style.opacity=0;var n=+new Date,r=function(){e.style.opacity=+e.style.opacity+((new Date).getTime()-n)/t,n=+new Date,+e.style.opacity<1&&(window.requestAnimationFrame&&requestAnimationFrame(r)||setTimeout(r,16))};r()},DomHandler.prototype.fadeOut=function(e,t){var n=1,r=50,i=t,o=r/i,s=setInterval(function(){n-=o,e.style.opacity=n,n<=0&&clearInterval(s)},r)},DomHandler.prototype.getWindowScrollTop=function(){var e=document.documentElement;return(window.pageYOffset||e.scrollTop)-(e.clientTop||0)},DomHandler.prototype.getWindowScrollLeft=function(){var e=document.documentElement;return(window.pageXOffset||e.scrollLeft)-(e.clientLeft||0)},DomHandler.prototype.matches=function(e,t){var n=Element.prototype,r=n.matches||n.webkitMatchesSelector||n.mozMatchesSelector||n.msMatchesSelector||function(e){return[].indexOf.call(document.querySelectorAll(e),this)!==-1};return r.call(e,t)},DomHandler.prototype.getOuterWidth=function(e,t){var n=e.offsetWidth;if(t){var r=getComputedStyle(e);n+=parseInt(r.paddingLeft)+parseInt(r.paddingRight)}return n},DomHandler.prototype.getHorizontalMargin=function(e){var t=getComputedStyle(e);return parseInt(t.marginLeft)+parseInt(t.marginRight)},DomHandler.prototype.innerWidth=function(e){var t=e.offsetWidth,n=getComputedStyle(e);return t+=parseInt(n.paddingLeft)+parseInt(n.paddingRight)},DomHandler.prototype.width=function(e){var t=e.offsetWidth,n=getComputedStyle(e);return t-=parseInt(n.paddingLeft)+parseInt(n.paddingRight)},DomHandler.prototype.getOuterHeight=function(e,t){var n=e.offsetHeight;if(t){var r=getComputedStyle(e);n+=parseInt(r.marginTop)+parseInt(r.marginBottom)}return n},DomHandler.prototype.getHeight=function(e){var t=e.offsetHeight,n=getComputedStyle(e);return t-=parseInt(n.paddingTop)+parseInt(n.paddingBottom)+parseInt(n.borderTopWidth)+parseInt(n.borderBottomWidth)},DomHandler.prototype.getViewport=function(){var e=window,t=document,n=t.documentElement,r=t.getElementsByTagName("body")[0],i=e.innerWidth||n.clientWidth||r.clientWidth,o=e.innerHeight||n.clientHeight||r.clientHeight;return{width:i,height:o}},DomHandler.prototype.equals=function(e,t){if(null==e||null==t)return!1;if(e==t)return!0;if("object"==typeof e&&"object"==typeof t){for(var n in e){if(e.hasOwnProperty(n)!==t.hasOwnProperty(n))return!1;switch(typeof e[n]){case"object":if(!this.equals(e[n],t[n]))return!1;break;case"function":if("undefined"==typeof t[n]||"compare"!=n&&e[n].toString()!=t[n].toString())return!1;break;default:if(e[n]!=t[n])return!1}}for(var n in t)if("undefined"==typeof e[n])return!1;return!0}return!1},DomHandler.zindex=1e3,DomHandler=r([o.Injectable(),i("design:paramtypes",[])],DomHandler)}();t.DomHandler=s},[1104,5],function(e,t,n){"use strict";var r=this&&this.__extends||function(e,t){function __(){this.constructor=e}for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n]);e.prototype=null===t?Object.create(t):(__.prototype=t.prototype,new __)},i=n(6),o=function(e){function OuterSubscriber(){e.apply(this,arguments)}return r(OuterSubscriber,e),OuterSubscriber.prototype.notifyNext=function(e,t,n,r,i){this.destination.next(t)},OuterSubscriber.prototype.notifyError=function(e,t){this.destination.error(e)},OuterSubscriber.prototype.notifyComplete=function(e){this.destination.complete()},OuterSubscriber}(i.Subscriber);t.OuterSubscriber=o},function(e,t,n){"use strict";function subscribeToResult(e,t,n,u){var p=new c.InnerSubscriber(e,n,u);if(!p.isUnsubscribed){if(t instanceof s.Observable)return t._isScalar?(p.next(t.value),void p.complete()):t.subscribe(p);if(i.isArray(t)){for(var d=0,h=t.length;d=0;a--)(i=e[a])&&(s=(o<3?i(s):o>3?i(t,n,s):i(t,n))||s);return o>3&&s&&Object.defineProperty(t,n,s),s},i=this&&this.__metadata||function(e,t){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(e,t)},o=n(0),s=n(3),a=n(0),l=function(){function Header(){}return Header=r([a.Component({selector:"header",template:""}),i("design:paramtypes",[])],Header)}();t.Header=l;var c=function(){function Footer(){}return Footer=r([a.Component({selector:"footer",template:""}),i("design:paramtypes",[])],Footer)}();t.Footer=c;var u=function(){function TemplateWrapper(e){this.viewContainer=e}return TemplateWrapper.prototype.ngOnInit=function(){this.viewContainer.createEmbeddedView(this.templateRef,{$implicit:this.item})},r([o.Input(),i("design:type",Object)],TemplateWrapper.prototype,"item",void 0),r([o.Input("pTemplateWrapper"),i("design:type",o.TemplateRef)],TemplateWrapper.prototype,"templateRef",void 0),TemplateWrapper=r([o.Directive({selector:"[pTemplateWrapper]"}),i("design:paramtypes",[o.ViewContainerRef])],TemplateWrapper)}();t.TemplateWrapper=u;var p=function(){function Column(){this.sortFunction=new o.EventEmitter}return r([o.Input(),i("design:type",String)],Column.prototype,"field",void 0),r([o.Input(),i("design:type",String)],Column.prototype,"header",void 0),r([o.Input(),i("design:type",String)],Column.prototype,"footer",void 0),r([o.Input(),i("design:type",Object)],Column.prototype,"sortable",void 0),r([o.Input(),i("design:type",Boolean)],Column.prototype,"editable",void 0),r([o.Input(),i("design:type",Boolean)],Column.prototype,"filter",void 0),r([o.Input(),i("design:type",String)],Column.prototype,"filterMatchMode",void 0),r([o.Input(),i("design:type",Number)],Column.prototype,"rowspan",void 0),r([o.Input(),i("design:type",Number)],Column.prototype,"colspan",void 0),r([o.Input(),i("design:type",Object)],Column.prototype,"style",void 0),r([o.Input(),i("design:type",String)],Column.prototype,"styleClass",void 0),r([o.Input(),i("design:type",Boolean)],Column.prototype,"hidden",void 0),r([o.Input(),i("design:type",Boolean)],Column.prototype,"expander",void 0),r([o.Input(),i("design:type",String)],Column.prototype,"selectionMode",void 0),r([o.Output(),i("design:type",o.EventEmitter)],Column.prototype,"sortFunction",void 0),r([o.ContentChild(o.TemplateRef),i("design:type",o.TemplateRef)],Column.prototype,"template",void 0),Column=r([a.Component({selector:"p-column",template:""}),i("design:paramtypes",[])],Column)}();t.Column=p;var d=function(){function ColumnTemplateLoader(e){this.viewContainer=e}return ColumnTemplateLoader.prototype.ngOnInit=function(){this.viewContainer.createEmbeddedView(this.column.template,{$implicit:this.column,rowData:this.rowData,rowIndex:this.rowIndex})},r([o.Input(),i("design:type",Object)],ColumnTemplateLoader.prototype,"column",void 0),r([o.Input(),i("design:type",Object)],ColumnTemplateLoader.prototype,"rowData",void 0),r([o.Input(),i("design:type",Number)],ColumnTemplateLoader.prototype,"rowIndex",void 0),ColumnTemplateLoader=r([a.Component({selector:"p-columnTemplateLoader",template:""}),i("design:paramtypes",[o.ViewContainerRef])],ColumnTemplateLoader)}();t.ColumnTemplateLoader=d;var h=function(){function SharedModule(){}return SharedModule=r([o.NgModule({imports:[s.CommonModule],exports:[l,c,p,u,d],declarations:[l,c,p,u,d]}),i("design:paramtypes",[])],SharedModule)}();t.SharedModule=h},function(e,t,n){"use strict";var r=this&&this.__extends||function(e,t){function __(){this.constructor=e}for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n]);e.prototype=null===t?Object.create(t):(__.prototype=t.prototype,new __)},i=n(1),o=n(6),s=n(41),a=n(899),l=n(215),c=n(517),u=n(317),p=function(e){function Subject(t,n){e.call(this),this.destination=t,this.source=n,this.observers=[],this.isUnsubscribed=!1,this.isStopped=!1,this.hasErrored=!1,this.dispatching=!1,this.hasCompleted=!1,this.source=n}return r(Subject,e),Subject.prototype.lift=function(e){var t=new Subject(this.destination||this,this);return t.operator=e,t},Subject.prototype.add=function(e){return s.Subscription.prototype.add.call(this,e)},Subject.prototype.remove=function(e){s.Subscription.prototype.remove.call(this,e)},Subject.prototype.unsubscribe=function(){s.Subscription.prototype.unsubscribe.call(this)},Subject.prototype._subscribe=function(e){if(this.source)return this.source.subscribe(e);if(!e.isUnsubscribed){if(this.hasErrored)return e.error(this.errorValue);if(this.hasCompleted)return e.complete();this.throwIfUnsubscribed();var t=new a.SubjectSubscription(this,e);return this.observers.push(e),t}},Subject.prototype._unsubscribe=function(){this.source=null,this.isStopped=!0,this.observers=null,this.destination=null},Subject.prototype.next=function(e){this.throwIfUnsubscribed(),this.isStopped||(this.dispatching=!0,this._next(e),this.dispatching=!1,this.hasErrored?this._error(this.errorValue):this.hasCompleted&&this._complete())},Subject.prototype.error=function(e){this.throwIfUnsubscribed(),this.isStopped||(this.isStopped=!0,this.hasErrored=!0,this.errorValue=e,this.dispatching||this._error(e))},Subject.prototype.complete=function(){this.throwIfUnsubscribed(),this.isStopped||(this.isStopped=!0,this.hasCompleted=!0,this.dispatching||this._complete())},Subject.prototype.asObservable=function(){var e=new d(this);return e},Subject.prototype._next=function(e){this.destination?this.destination.next(e):this._finalNext(e)},Subject.prototype._finalNext=function(e){for(var t=-1,n=this.observers.slice(0),r=n.length;++t"+i+""};e.exports=function(e,t){var n={};n[e]=t(a),r(r.P+r.F*i(function(){var t=""[e]('"');return t!==t.toLowerCase()||t.split('"').length>3}),"String",n)}},function(e,t,n){"use strict";var r=n(81),i=n(514),o=n(217),s=n(42),a=n(38),l=n(513),c=function(){function Subscription(e){this.isUnsubscribed=!1,e&&(this._unsubscribe=e)}return Subscription.prototype.unsubscribe=function(){var e,t=!1;if(!this.isUnsubscribed){this.isUnsubscribed=!0;var n=this,c=n._unsubscribe,u=n._subscriptions;if(this._subscriptions=null,o.isFunction(c)){var p=s.tryCatch(c).call(this);p===a.errorObject&&(t=!0,(e=e||[]).push(a.errorObject.e))}if(r.isArray(u))for(var d=-1,h=u.length;++d0?i(r(e),9007199254740991):0}},function(e,t,n){"use strict";var r=n(1082);t.async=new r.AsyncScheduler},function(e,t,n){"use strict";function __export(e){for(var n in e)t.hasOwnProperty(n)||(t[n]=e[n])}var r=n(86);t.HostMetadata=r.HostMetadata,t.InjectMetadata=r.InjectMetadata,t.InjectableMetadata=r.InjectableMetadata,t.OptionalMetadata=r.OptionalMetadata,t.SelfMetadata=r.SelfMetadata,t.SkipSelfMetadata=r.SkipSelfMetadata,__export(n(115));var i=n(162);t.forwardRef=i.forwardRef,t.resolveForwardRef=i.resolveForwardRef;var o=n(163);t.Injector=o.Injector;var s=n(571);t.ReflectiveInjector=s.ReflectiveInjector;var a=n(250);t.Binding=a.Binding,t.ProviderBuilder=a.ProviderBuilder,t.bind=a.bind,t.Provider=a.Provider,t.provide=a.provide;var l=n(253);t.ResolvedReflectiveFactory=l.ResolvedReflectiveFactory;var c=n(252);t.ReflectiveKey=c.ReflectiveKey;var u=n(251);t.NoProviderError=u.NoProviderError,t.AbstractProviderError=u.AbstractProviderError,t.CyclicDependencyError=u.CyclicDependencyError,t.InstantiationError=u.InstantiationError,t.InvalidProviderError=u.InvalidProviderError,t.NoAnnotationError=u.NoAnnotationError,t.OutOfBoundsError=u.OutOfBoundsError;var p=n(374);t.OpaqueToken=p.OpaqueToken},[1104,32],function(e,t){var n={}.hasOwnProperty;e.exports=function(e,t){return n.call(e,t)}},function(e,t,n){"use strict";var r=n(13);e.exports=function(e,t){return!!e&&r(function(){t?e.call(null,function(){},1):e.call(null)})}},function(e,t,n){var r=n(75);e.exports=function(e){return Object(r(e))}},function(e,t,n){"use strict";(function(e,n){var r={"boolean":!1,"function":!0,object:!0,number:!1,string:!1,undefined:!1};t.root=r[typeof self]&&self||r[typeof window]&&window;var i=(r[typeof t]&&t&&!t.nodeType&&t,r[typeof e]&&e&&!e.nodeType&&e,r[typeof n]&&n);!i||i.global!==i&&i.window!==i||(t.root=i)}).call(t,n(1100)(e),n(82))},function(e,t,n){"use strict";var r=n(0);t.NG_VALUE_ACCESSOR=new r.OpaqueToken("NgValueAccessor")},52,function(e,t,n){"use strict";function _convertToPromise(e){return s.isPromise(e)?e:i.toPromise.call(e)}function _executeValidators(e,t){return t.map(function(t){return t(e)})}function _executeAsyncValidators(e,t){return t.map(function(t){return t(e)})}function _mergeErrors(e){var t=e.reduce(function(e,t){return s.isPresent(t)?o.StringMapWrapper.merge(e,t):e},{});return o.StringMapWrapper.isEmpty(t)?null:t}var r=n(0),i=n(313),o=n(47),s=n(32);t.NG_VALIDATORS=new r.OpaqueToken("NgValidators"),t.NG_ASYNC_VALIDATORS=new r.OpaqueToken("NgAsyncValidators");var a=function(){function Validators(){}return Validators.required=function(e){return s.isBlank(e.value)||s.isString(e.value)&&""==e.value?{required:!0}:null},Validators.minLength=function(e){return function(t){if(s.isPresent(Validators.required(t)))return null;var n=t.value;return n.lengthe?{maxlength:{requiredLength:e,actualLength:n.length}}:null}},Validators.pattern=function(e){return function(t){if(s.isPresent(Validators.required(t)))return null;var n=new RegExp("^"+e+"$"),r=t.value;return n.test(r)?null:{pattern:{requiredPattern:"^"+e+"$",actualValue:r}}}},Validators.nullValidator=function(e){return null},Validators.compose=function(e){if(s.isBlank(e))return null;var t=e.filter(s.isPresent);return 0==t.length?null:function(e){return _mergeErrors(_executeValidators(e,t))}},Validators.composeAsync=function(e){if(s.isBlank(e))return null;var t=e.filter(s.isPresent);return 0==t.length?null:function(e){var n=_executeAsyncValidators(e,t).map(_convertToPromise);return Promise.all(n).then(_mergeErrors)}},Validators}();t.Validators=a},function(e,t,n){"use strict";var r=n(0),i=n(123),o=n(72),s=n(16),a=n(126),l=n(278);t.PRIMITIVE=String;var c=function(){function Serializer(e){this._renderStore=e}return Serializer.prototype.serialize=function(e,n){var i=this;if(!s.isPresent(e))return null;if(s.isArray(e))return e.map(function(e){return i.serialize(e,n)});if(n==t.PRIMITIVE)return e;if(n==u)return this._renderStore.serialize(e);if(n===r.RenderComponentType)return this._serializeRenderComponentType(e);if(n===r.ViewEncapsulation)return s.serializeEnum(e);if(n===l.LocationType)return this._serializeLocation(e);throw new o.BaseException("No serializer for "+n.toString())},Serializer.prototype.deserialize=function(e,n,a){var c=this;if(!s.isPresent(e))return null;if(s.isArray(e)){var p=[];return e.forEach(function(e){return p.push(c.deserialize(e,n,a))}),p}if(n==t.PRIMITIVE)return e;if(n==u)return this._renderStore.deserialize(e);if(n===r.RenderComponentType)return this._deserializeRenderComponentType(e);if(n===r.ViewEncapsulation)return i.VIEW_ENCAPSULATION_VALUES[e];if(n===l.LocationType)return this._deserializeLocation(e);throw new o.BaseException("No deserializer for "+n.toString())},Serializer.prototype._serializeLocation=function(e){return{href:e.href,protocol:e.protocol,host:e.host,hostname:e.hostname,port:e.port,pathname:e.pathname,search:e.search,hash:e.hash,origin:e.origin}},Serializer.prototype._deserializeLocation=function(e){return new l.LocationType(e.href,e.protocol,e.host,e.hostname,e.port,e.pathname,e.search,e.hash,e.origin)},Serializer.prototype._serializeRenderComponentType=function(e){return{id:e.id,templateUrl:e.templateUrl,slotCount:e.slotCount,encapsulation:this.serialize(e.encapsulation,r.ViewEncapsulation),styles:this.serialize(e.styles,t.PRIMITIVE)}},Serializer.prototype._deserializeRenderComponentType=function(e){return new r.RenderComponentType(e.id,e.templateUrl,e.slotCount,this.deserialize(e.encapsulation,r.ViewEncapsulation),this.deserialize(e.styles,t.PRIMITIVE),{})},Serializer.decorators=[{type:r.Injectable}],Serializer.ctorParameters=[{type:a.RenderStore}],Serializer}();t.Serializer=c;var u=function(){function RenderStoreObject(){}return RenderStoreObject}();t.RenderStoreObject=u},function(e,t,n){var r=n(2),i=n(24),o=n(13);e.exports=function(e,t){var n=(i.Object||{})[e]||Object[e],s={};s[e]=t(n),r(r.S+r.F*o(function(){n(1)}),"Object",s)}},function(e,t,n){var r=n(133),i=n(75);e.exports=function(e){return r(i(e))}},function(e,t,n){"use strict";function _convertToPromise(e){return s.isPromise(e)?e:i.toPromise.call(e)}function _executeValidators(e,t){return t.map(function(t){return t(e)})}function _executeAsyncValidators(e,t){return t.map(function(t){return t(e)})}function _mergeErrors(e){var t=e.reduce(function(e,t){return s.isPresent(t)?o.StringMapWrapper.merge(e,t):e},{});return o.StringMapWrapper.isEmpty(t)?null:t}var r=n(0),i=n(313),o=n(34),s=n(7);t.NG_VALIDATORS=new r.OpaqueToken("NgValidators"),t.NG_ASYNC_VALIDATORS=new r.OpaqueToken("NgAsyncValidators");var a=function(){function Validators(){}return Validators.required=function(e){return s.isBlank(e.value)||s.isString(e.value)&&""==e.value?{required:!0}:null},Validators.minLength=function(e){return function(t){if(s.isPresent(Validators.required(t)))return null;var n=t.value;return n.lengthe?{maxlength:{requiredLength:e,actualLength:n.length}}:null}},Validators.pattern=function(e){return function(t){if(s.isPresent(Validators.required(t)))return null;var n=new RegExp("^"+e+"$"),r=t.value;return n.test(r)?null:{pattern:{requiredPattern:"^"+e+"$",actualValue:r}}}},Validators.nullValidator=function(e){return null},Validators.compose=function(e){if(s.isBlank(e))return null;var t=e.filter(s.isPresent);return 0==t.length?null:function(e){return _mergeErrors(_executeValidators(e,t))}},Validators.composeAsync=function(e){if(s.isBlank(e))return null;var t=e.filter(s.isPresent);return 0==t.length?null:function(e){var n=_executeAsyncValidators(e,t).map(_convertToPromise);return Promise.all(n).then(_mergeErrors)}},Validators}();t.Validators=a},function(e,t,n){"use strict";var r=this&&this.__extends||function(e,t){function __(){this.constructor=e}for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n]);e.prototype=null===t?Object.create(t):(__.prototype=t.prototype,new __)},i=n(83),o=n(7),s=function(e){function InvalidPipeArgumentException(t,n){e.call(this,"Invalid argument '"+n+"' for pipe '"+o.stringify(t)+"'")}return r(InvalidPipeArgumentException,e),InvalidPipeArgumentException}(i.BaseException);t.InvalidPipeArgumentException=s},function(e,t,n){"use strict";/** +webpackJsonp([0,2],[function(e,t,n){"use strict";function __export(e){for(var n in e)t.hasOwnProperty(n)||(t[n]=e[n])}__export(n(386)),__export(n(585)),__export(n(46));var r=n(248);t.createPlatform=r.createPlatform,t.assertPlatform=r.assertPlatform,t.disposePlatform=r.disposePlatform,t.getPlatform=r.getPlatform,t.coreBootstrap=r.coreBootstrap,t.coreLoadAndBootstrap=r.coreLoadAndBootstrap,t.PlatformRef=r.PlatformRef,t.ApplicationRef=r.ApplicationRef,t.enableProdMode=r.enableProdMode,t.lockRunMode=r.lockRunMode,t.isDevMode=r.isDevMode,t.createPlatformFactory=r.createPlatformFactory;var i=n(157);t.APP_ID=i.APP_ID,t.PACKAGE_ROOT_URL=i.PACKAGE_ROOT_URL,t.PLATFORM_INITIALIZER=i.PLATFORM_INITIALIZER,t.APP_BOOTSTRAP_LISTENER=i.APP_BOOTSTRAP_LISTENER;var o=n(247);t.APP_INITIALIZER=o.APP_INITIALIZER,t.ApplicationInitStatus=o.ApplicationInitStatus,__export(n(586)),__export(n(584)),__export(n(573));var s=n(373);t.DebugElement=s.DebugElement,t.DebugNode=s.DebugNode,t.asNativeElements=s.asNativeElements,t.getDebugNode=s.getDebugNode,__export(n(261)),__export(n(568)),__export(n(581)),__export(n(580));var a=n(567);t.APPLICATION_COMMON_PROVIDERS=a.APPLICATION_COMMON_PROVIDERS,t.ApplicationModule=a.ApplicationModule;var l=n(167);t.wtfCreateScope=l.wtfCreateScope,t.wtfLeave=l.wtfLeave,t.wtfStartTimeRange=l.wtfStartTimeRange,t.wtfEndTimeRange=l.wtfEndTimeRange;var c=n(4);t.Type=c.Type;var u=n(254);t.EventEmitter=u.EventEmitter;var p=n(14);t.ExceptionHandler=p.ExceptionHandler,t.WrappedException=p.WrappedException,t.BaseException=p.BaseException,__export(n(561)),__export(n(369));var d=n(246);t.AnimationPlayer=d.AnimationPlayer;var h=n(394);t.SanitizationService=h.SanitizationService,t.SecurityContext=h.SecurityContext},function(e,t,n){"use strict";var r=n(51),i=n(214),o=n(1089),s=function(){function Observable(e){this._isScalar=!1,e&&(this._subscribe=e)}return Observable.prototype.lift=function(e){var t=new Observable;return t.source=this,t.operator=e,t},Observable.prototype.subscribe=function(e,t,n){var r=this.operator,i=o.toSubscriber(e,t,n);if(i.add(r?r.call(i,this):this._subscribe(i)),i.syncErrorThrowable&&(i.syncErrorThrowable=!1,i.syncErrorThrown))throw i.syncErrorValue;return i},Observable.prototype.forEach=function(e,t){var n=this;if(t||(r.root.Rx&&r.root.Rx.config&&r.root.Rx.config.Promise?t=r.root.Rx.config.Promise:r.root.Promise&&(t=r.root.Promise)),!t)throw new Error("no Promise impl found");return new t(function(t,r){var i=n.subscribe(function(t){if(i)try{e(t)}catch(n){r(n),i.unsubscribe()}else e(t)},r,t)})},Observable.prototype._subscribe=function(e){return this.source.subscribe(e)},Observable.prototype[i.$$observable]=function(){return this},Observable.create=function(e){return new Observable(e)},Observable}();t.Observable=s},function(e,t,n){var r=n(26),i=n(24),o=n(65),s=n(39),a=n(106),l="prototype",c=function(e,t,n){var u,p,d,h,f=e&c.F,m=e&c.G,g=e&c.S,y=e&c.P,v=e&c.B,b=m?r:g?r[t]||(r[t]={}):(r[t]||{})[l],_=m?i:i[t]||(i[t]={}),w=_[l]||(_[l]={});m&&(n=t);for(u in n)p=!f&&b&&void 0!==b[u],d=(p?b:n)[u],h=v&&p?a(d,r):y&&"function"==typeof d?a(Function.call,d):d,b&&s(b,u,d,e&c.U),_[u]!=d&&o(_,u,h),y&&w[u]!=d&&(w[u]=d)};r.core=i,c.F=1,c.G=2,c.S=4,c.P=8,c.B=16,c.W=32,c.U=64,c.R=128,e.exports=c},function(e,t,n){"use strict";function __export(e){for(var n in e)t.hasOwnProperty(n)||(t[n]=e[n])}var r=n(0),i=n(321),o=n(334);__export(n(334)),__export(n(322)),__export(n(525)),__export(n(321)),__export(n(527));var s=n(230);t.NgLocalization=s.NgLocalization;var a=function(){function CommonModule(){}return CommonModule.decorators=[{type:r.NgModule,args:[{declarations:[i.COMMON_DIRECTIVES,o.COMMON_PIPES],exports:[i.COMMON_DIRECTIVES,o.COMMON_PIPES]}]}],CommonModule}();t.CommonModule=a},function(e,t,n){"use strict";(function(e){function scheduleMicroTask(e){Zone.current.scheduleMicroTask("scheduleMicrotask",e)}function getTypeNameForDebugging(e){return e.name?e.name:typeof e}function isPresent(e){return void 0!==e&&null!==e}function isBlank(e){return void 0===e||null===e}function isBoolean(e){return"boolean"==typeof e}function isNumber(e){return"number"==typeof e}function isString(e){return"string"==typeof e}function isFunction(e){return"function"==typeof e}function isType(e){return isFunction(e)}function isStringMap(e){return"object"==typeof e&&null!==e}function isStrictStringMap(e){return isStringMap(e)&&Object.getPrototypeOf(e)===o}function isPromise(e){return isPresent(e)&&isFunction(e.then)}function isArray(e){return Array.isArray(e)}function isDate(e){return e instanceof t.Date&&!isNaN(e.valueOf())}function noop(){}function stringify(e){if("string"==typeof e)return e;if(void 0===e||null===e)return""+e;if(e.overriddenName)return e.overriddenName;if(e.name)return e.name;var t=e.toString(),n=t.indexOf("\n");return n===-1?t:t.substring(0,n)}function serializeEnum(e){return e}function deserializeEnum(e,t){return e}function resolveEnumToken(e,t){return e[t]}function looseIdentical(e,t){return e===t||"number"==typeof e&&"number"==typeof t&&isNaN(e)&&isNaN(t)}function getMapKey(e){return e}function normalizeBlank(e){return isBlank(e)?null:e}function normalizeBool(e){return!isBlank(e)&&e}function isJsObject(e){return null!==e&&("function"==typeof e||"object"==typeof e)}function print(e){console.log(e)}function warn(e){console.warn(e)}function setValueOnPath(e,t,n){for(var r=t.split("."),i=e;r.length>1;){var o=r.shift();i=i.hasOwnProperty(o)&&isPresent(i[o])?i[o]:i[o]={}}void 0!==i&&null!==i||(i={}),i[r.shift()]=n}function getSymbolIterator(){if(isBlank(h))if(isPresent(n.Symbol)&&isPresent(Symbol.iterator))h=Symbol.iterator;else for(var e=Object.getOwnPropertyNames(Map.prototype),t=0;t=0&&e[r]==t;r--)n--;e=e.substring(0,n)}return e},StringWrapper.replace=function(e,t,n){return e.replace(t,n)},StringWrapper.replaceAll=function(e,t,n){return e.replace(t,n)},StringWrapper.slice=function(e,t,n){return void 0===t&&(t=0),void 0===n&&(n=null),e.slice(t,null===n?void 0:n)},StringWrapper.replaceAllMapped=function(e,t,n){return e.replace(t,function(){for(var e=[],t=0;tt?1:0},StringWrapper}();t.StringWrapper=s;var a=function(){function StringJoiner(e){void 0===e&&(e=[]),this.parts=e}return StringJoiner.prototype.add=function(e){this.parts.push(e)},StringJoiner.prototype.toString=function(){return this.parts.join("")},StringJoiner}();t.StringJoiner=a;var l=function(e){function NumberParseError(t){e.call(this),this.message=t}return r(NumberParseError,e),NumberParseError.prototype.toString=function(){return this.message},NumberParseError}(Error);t.NumberParseError=l;var c=function(){function NumberWrapper(){}return NumberWrapper.toFixed=function(e,t){return e.toFixed(t)},NumberWrapper.equal=function(e,t){return e===t},NumberWrapper.parseIntAutoRadix=function(e){var t=parseInt(e);if(isNaN(t))throw new l("Invalid integer literal when parsing "+e);return t},NumberWrapper.parseInt=function(e,t){if(10==t){if(/^(\-|\+)?[0-9]+$/.test(e))return parseInt(e,t)}else if(16==t){if(/^(\-|\+)?[0-9ABCDEFabcdef]+$/.test(e))return parseInt(e,t)}else{var n=parseInt(e,t);if(!isNaN(n))return n}throw new l("Invalid integer literal when parsing "+e+" in base "+t)},NumberWrapper.parseFloat=function(e){return parseFloat(e)},Object.defineProperty(NumberWrapper,"NaN",{get:function(){return NaN},enumerable:!0,configurable:!0}),NumberWrapper.isNumeric=function(e){return!isNaN(e-parseFloat(e))},NumberWrapper.isNaN=function(e){return isNaN(e)},NumberWrapper.isInteger=function(e){return Number.isInteger(e)},NumberWrapper}();t.NumberWrapper=c,t.RegExp=i.RegExp;var u=function(){function FunctionWrapper(){}return FunctionWrapper.apply=function(e,t){return e.apply(null,t)},FunctionWrapper.bind=function(e,t){return e.bind(t)},FunctionWrapper}();t.FunctionWrapper=u,t.looseIdentical=looseIdentical,t.getMapKey=getMapKey,t.normalizeBlank=normalizeBlank,t.normalizeBool=normalizeBool,t.isJsObject=isJsObject,t.print=print,t.warn=warn;var p=function(){function Json(){}return Json.parse=function(e){return i.JSON.parse(e)},Json.stringify=function(e){return i.JSON.stringify(e,null,2)},Json}();t.Json=p;var d=function(){function DateWrapper(){}return DateWrapper.create=function(e,n,r,i,o,s,a){return void 0===n&&(n=1),void 0===r&&(r=1),void 0===i&&(i=0),void 0===o&&(o=0),void 0===s&&(s=0),void 0===a&&(a=0),new t.Date(e,n-1,r,i,o,s,a)},DateWrapper.fromISOString=function(e){return new t.Date(e)},DateWrapper.fromMillis=function(e){return new t.Date(e)},DateWrapper.toMillis=function(e){return e.getTime()},DateWrapper.now=function(){return new t.Date},DateWrapper.toJson=function(e){return e.toJSON()},DateWrapper}();t.DateWrapper=d,t.setValueOnPath=setValueOnPath;var h=null;t.getSymbolIterator=getSymbolIterator,t.evalExpression=evalExpression,t.isPrimitive=isPrimitive,t.hasConstructor=hasConstructor,t.escape=escape,t.escapeRegExp=escapeRegExp}).call(t,n(82))},4,function(e,t,n){"use strict";var r=this&&this.__extends||function(e,t){function __(){this.constructor=e}for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n]);e.prototype=null===t?Object.create(t):(__.prototype=t.prototype,new __)},i=n(217),o=n(41),s=n(215),a=n(897),l=function(e){function Subscriber(t,n,r){switch(e.call(this),this.syncErrorValue=null,this.syncErrorThrown=!1,this.syncErrorThrowable=!1,this.isStopped=!1,arguments.length){case 0:this.destination=a.empty;break;case 1:if(!t){this.destination=a.empty;break}if("object"==typeof t){t instanceof Subscriber?(this.destination=t,this.destination.add(this)):(this.syncErrorThrowable=!0,this.destination=new c(this,t));break}default:this.syncErrorThrowable=!0,this.destination=new c(this,t,n,r)}}return r(Subscriber,e),Subscriber.create=function(e,t,n){var r=new Subscriber(e,t,n);return r.syncErrorThrowable=!1,r},Subscriber.prototype.next=function(e){this.isStopped||this._next(e)},Subscriber.prototype.error=function(e){this.isStopped||(this.isStopped=!0,this._error(e))},Subscriber.prototype.complete=function(){this.isStopped||(this.isStopped=!0,this._complete())},Subscriber.prototype.unsubscribe=function(){this.isUnsubscribed||(this.isStopped=!0,e.prototype.unsubscribe.call(this))},Subscriber.prototype._next=function(e){this.destination.next(e)},Subscriber.prototype._error=function(e){this.destination.error(e),this.unsubscribe()},Subscriber.prototype._complete=function(){this.destination.complete(),this.unsubscribe()},Subscriber.prototype[s.$$rxSubscriber]=function(){return this},Subscriber}(o.Subscription);t.Subscriber=l;var c=function(e){function SafeSubscriber(t,n,r,o){e.call(this),this._parent=t;var s,a=this;i.isFunction(n)?s=n:n&&(a=n,s=n.next,r=n.error,o=n.complete,i.isFunction(a.unsubscribe)&&this.add(a.unsubscribe.bind(a)),a.unsubscribe=this.unsubscribe.bind(this)),this._context=a,this._next=s,this._error=r,this._complete=o}return r(SafeSubscriber,e),SafeSubscriber.prototype.next=function(e){if(!this.isStopped&&this._next){var t=this._parent;t.syncErrorThrowable?this.__tryOrSetError(t,this._next,e)&&this.unsubscribe():this.__tryOrUnsub(this._next,e)}},SafeSubscriber.prototype.error=function(e){if(!this.isStopped){var t=this._parent;if(this._error)t.syncErrorThrowable?(this.__tryOrSetError(t,this._error,e),this.unsubscribe()):(this.__tryOrUnsub(this._error,e),this.unsubscribe());else{if(!t.syncErrorThrowable)throw this.unsubscribe(),e;t.syncErrorValue=e,t.syncErrorThrown=!0,this.unsubscribe()}}},SafeSubscriber.prototype.complete=function(){if(!this.isStopped){var e=this._parent;this._complete?e.syncErrorThrowable?(this.__tryOrSetError(e,this._complete),this.unsubscribe()):(this.__tryOrUnsub(this._complete),this.unsubscribe()):this.unsubscribe()}},SafeSubscriber.prototype.__tryOrUnsub=function(e,t){try{e.call(this._context,t)}catch(n){throw this.unsubscribe(),n}},SafeSubscriber.prototype.__tryOrSetError=function(e,t,n){try{t.call(this._context,n)}catch(r){return e.syncErrorValue=r,e.syncErrorThrown=!0,!0}return!1},SafeSubscriber.prototype._unsubscribe=function(){var e=this._parent;this._context=null,this._parent=null,e.unsubscribe()},SafeSubscriber}(l)},4,function(e,t,n){var r=n(15);e.exports=function(e){if(!r(e))throw TypeError(e+" is not an object!");return e}},function(e,t,n){"use strict";var r=this&&this.__decorate||function(e,t,n,r){var i,o=arguments.length,s=o<3?t:null===r?r=Object.getOwnPropertyDescriptor(t,n):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(e,t,n,r);else for(var a=e.length-1;a>=0;a--)(i=e[a])&&(s=(o<3?i(s):o>3?i(t,n,s):i(t,n))||s);return o>3&&s&&Object.defineProperty(t,n,s),s},i=this&&this.__metadata||function(e,t){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(e,t)},o=n(0),s=function(){function DomHandler(){}return DomHandler.prototype.addClass=function(e,t){e.classList?e.classList.add(t):e.className+=" "+t},DomHandler.prototype.addMultipleClasses=function(e,t){if(e.classList)for(var n=t.split(" "),r=0;rwindow.innerHeight?-1*i.height:o,r=a.left+i.width>window.innerWidth?s-i.width:0,e.style.top=n+"px",e.style.left=r+"px"},DomHandler.prototype.absolutePosition=function(e,t){var n,r,i=e.offsetParent?{width:e.offsetWidth,height:e.offsetHeight}:this.getHiddenElementDimensions(e),o=i.height,s=i.width,a=t.offsetHeight,l=t.offsetWidth,c=t.getBoundingClientRect(),u=this.getWindowScrollTop(),p=this.getWindowScrollLeft();n=c.top+a+o>window.innerHeight?c.top+u-o:a+c.top+u,r=c.left+l+s>window.innerWidth?c.left+p+l-s:c.left+p,e.style.top=n+"px",e.style.left=r+"px"},DomHandler.prototype.getHiddenElementOuterHeight=function(e){e.style.visibility="hidden",e.style.display="block";var t=e.offsetHeight;return e.style.display="none",e.style.visibility="visible",t},DomHandler.prototype.getHiddenElementOuterWidth=function(e){e.style.visibility="hidden",e.style.display="block";var t=e.offsetWidth;return e.style.display="none",e.style.visibility="visible",t},DomHandler.prototype.getHiddenElementDimensions=function(e){var t={};return e.style.visibility="hidden",e.style.display="block",t.width=e.offsetWidth,t.height=e.offsetHeight,e.style.display="none",e.style.visibility="visible",t},DomHandler.prototype.scrollInView=function(e,t){var n=getComputedStyle(e).getPropertyValue("borderTopWidth"),r=n?parseFloat(n):0,i=getComputedStyle(e).getPropertyValue("paddingTop"),o=i?parseFloat(i):0,s=e.getBoundingClientRect(),a=t.getBoundingClientRect(),l=a.top+document.body.scrollTop-(s.top+document.body.scrollTop)-r-o,c=e.scrollTop,u=e.clientHeight,p=this.getOuterHeight(t);l<0?e.scrollTop=c+l:l+p>u&&(e.scrollTop=c+l-u+p)},DomHandler.prototype.fadeIn=function(e,t){e.style.opacity=0;var n=+new Date,r=function(){e.style.opacity=+e.style.opacity+((new Date).getTime()-n)/t,n=+new Date,+e.style.opacity<1&&(window.requestAnimationFrame&&requestAnimationFrame(r)||setTimeout(r,16))};r()},DomHandler.prototype.fadeOut=function(e,t){var n=1,r=50,i=t,o=r/i,s=setInterval(function(){n-=o,e.style.opacity=n,n<=0&&clearInterval(s)},r)},DomHandler.prototype.getWindowScrollTop=function(){var e=document.documentElement;return(window.pageYOffset||e.scrollTop)-(e.clientTop||0)},DomHandler.prototype.getWindowScrollLeft=function(){var e=document.documentElement;return(window.pageXOffset||e.scrollLeft)-(e.clientLeft||0)},DomHandler.prototype.matches=function(e,t){var n=Element.prototype,r=n.matches||n.webkitMatchesSelector||n.mozMatchesSelector||n.msMatchesSelector||function(e){return[].indexOf.call(document.querySelectorAll(e),this)!==-1};return r.call(e,t)},DomHandler.prototype.getOuterWidth=function(e,t){var n=e.offsetWidth;if(t){var r=getComputedStyle(e);n+=parseInt(r.paddingLeft)+parseInt(r.paddingRight)}return n},DomHandler.prototype.getHorizontalMargin=function(e){var t=getComputedStyle(e);return parseInt(t.marginLeft)+parseInt(t.marginRight)},DomHandler.prototype.innerWidth=function(e){var t=e.offsetWidth,n=getComputedStyle(e);return t+=parseInt(n.paddingLeft)+parseInt(n.paddingRight)},DomHandler.prototype.width=function(e){var t=e.offsetWidth,n=getComputedStyle(e);return t-=parseInt(n.paddingLeft)+parseInt(n.paddingRight)},DomHandler.prototype.getOuterHeight=function(e,t){var n=e.offsetHeight;if(t){var r=getComputedStyle(e);n+=parseInt(r.marginTop)+parseInt(r.marginBottom)}return n},DomHandler.prototype.getHeight=function(e){var t=e.offsetHeight,n=getComputedStyle(e);return t-=parseInt(n.paddingTop)+parseInt(n.paddingBottom)+parseInt(n.borderTopWidth)+parseInt(n.borderBottomWidth)},DomHandler.prototype.getViewport=function(){var e=window,t=document,n=t.documentElement,r=t.getElementsByTagName("body")[0],i=e.innerWidth||n.clientWidth||r.clientWidth,o=e.innerHeight||n.clientHeight||r.clientHeight;return{width:i,height:o}},DomHandler.prototype.equals=function(e,t){if(null==e||null==t)return!1;if(e==t)return!0;if("object"==typeof e&&"object"==typeof t){for(var n in e){if(e.hasOwnProperty(n)!==t.hasOwnProperty(n))return!1;switch(typeof e[n]){case"object":if(!this.equals(e[n],t[n]))return!1;break;case"function":if("undefined"==typeof t[n]||"compare"!=n&&e[n].toString()!=t[n].toString())return!1;break;default:if(e[n]!=t[n])return!1}}for(var n in t)if("undefined"==typeof e[n])return!1;return!0}return!1},DomHandler.zindex=1e3,DomHandler=r([o.Injectable(),i("design:paramtypes",[])],DomHandler)}();t.DomHandler=s},[1104,5],function(e,t,n){"use strict";var r=this&&this.__extends||function(e,t){function __(){this.constructor=e}for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n]);e.prototype=null===t?Object.create(t):(__.prototype=t.prototype,new __)},i=n(6),o=function(e){function OuterSubscriber(){e.apply(this,arguments)}return r(OuterSubscriber,e),OuterSubscriber.prototype.notifyNext=function(e,t,n,r,i){this.destination.next(t)},OuterSubscriber.prototype.notifyError=function(e,t){this.destination.error(e)},OuterSubscriber.prototype.notifyComplete=function(e){this.destination.complete()},OuterSubscriber}(i.Subscriber);t.OuterSubscriber=o},function(e,t,n){"use strict";function subscribeToResult(e,t,n,u){var p=new c.InnerSubscriber(e,n,u);if(!p.isUnsubscribed){if(t instanceof s.Observable)return t._isScalar?(p.next(t.value),void p.complete()):t.subscribe(p);if(i.isArray(t)){for(var d=0,h=t.length;d=0;a--)(i=e[a])&&(s=(o<3?i(s):o>3?i(t,n,s):i(t,n))||s);return o>3&&s&&Object.defineProperty(t,n,s),s},i=this&&this.__metadata||function(e,t){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(e,t)},o=n(0),s=n(3),a=n(0),l=function(){function Header(){}return Header=r([a.Component({selector:"header",template:""}),i("design:paramtypes",[])],Header)}();t.Header=l;var c=function(){function Footer(){}return Footer=r([a.Component({selector:"footer",template:""}),i("design:paramtypes",[])],Footer)}();t.Footer=c;var u=function(){function TemplateWrapper(e){this.viewContainer=e}return TemplateWrapper.prototype.ngOnInit=function(){this.viewContainer.createEmbeddedView(this.templateRef,{$implicit:this.item})},r([o.Input(),i("design:type",Object)],TemplateWrapper.prototype,"item",void 0),r([o.Input("pTemplateWrapper"),i("design:type",o.TemplateRef)],TemplateWrapper.prototype,"templateRef",void 0),TemplateWrapper=r([o.Directive({selector:"[pTemplateWrapper]"}),i("design:paramtypes",[o.ViewContainerRef])],TemplateWrapper)}();t.TemplateWrapper=u;var p=function(){function Column(){this.sortFunction=new o.EventEmitter}return r([o.Input(),i("design:type",String)],Column.prototype,"field",void 0),r([o.Input(),i("design:type",String)],Column.prototype,"header",void 0),r([o.Input(),i("design:type",String)],Column.prototype,"footer",void 0),r([o.Input(),i("design:type",Object)],Column.prototype,"sortable",void 0),r([o.Input(),i("design:type",Boolean)],Column.prototype,"editable",void 0),r([o.Input(),i("design:type",Boolean)],Column.prototype,"filter",void 0),r([o.Input(),i("design:type",String)],Column.prototype,"filterMatchMode",void 0),r([o.Input(),i("design:type",Number)],Column.prototype,"rowspan",void 0),r([o.Input(),i("design:type",Number)],Column.prototype,"colspan",void 0),r([o.Input(),i("design:type",Object)],Column.prototype,"style",void 0),r([o.Input(),i("design:type",String)],Column.prototype,"styleClass",void 0),r([o.Input(),i("design:type",Boolean)],Column.prototype,"hidden",void 0),r([o.Input(),i("design:type",Boolean)],Column.prototype,"expander",void 0),r([o.Input(),i("design:type",String)],Column.prototype,"selectionMode",void 0),r([o.Output(),i("design:type",o.EventEmitter)],Column.prototype,"sortFunction",void 0),r([o.ContentChild(o.TemplateRef),i("design:type",o.TemplateRef)],Column.prototype,"template",void 0),Column=r([a.Component({selector:"p-column",template:""}),i("design:paramtypes",[])],Column)}();t.Column=p;var d=function(){function ColumnTemplateLoader(e){this.viewContainer=e}return ColumnTemplateLoader.prototype.ngOnInit=function(){this.viewContainer.createEmbeddedView(this.column.template,{$implicit:this.column,rowData:this.rowData,rowIndex:this.rowIndex})},r([o.Input(),i("design:type",Object)],ColumnTemplateLoader.prototype,"column",void 0),r([o.Input(),i("design:type",Object)],ColumnTemplateLoader.prototype,"rowData",void 0),r([o.Input(),i("design:type",Number)],ColumnTemplateLoader.prototype,"rowIndex",void 0),ColumnTemplateLoader=r([a.Component({selector:"p-columnTemplateLoader",template:""}),i("design:paramtypes",[o.ViewContainerRef])],ColumnTemplateLoader)}();t.ColumnTemplateLoader=d;var h=function(){function SharedModule(){}return SharedModule=r([o.NgModule({imports:[s.CommonModule],exports:[l,c,p,u,d],declarations:[l,c,p,u,d]}),i("design:paramtypes",[])],SharedModule)}();t.SharedModule=h},function(e,t,n){"use strict";var r=this&&this.__extends||function(e,t){function __(){this.constructor=e}for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n]);e.prototype=null===t?Object.create(t):(__.prototype=t.prototype,new __)},i=n(1),o=n(6),s=n(41),a=n(899),l=n(215),c=n(517),u=n(317),p=function(e){function Subject(t,n){e.call(this),this.destination=t,this.source=n,this.observers=[],this.isUnsubscribed=!1,this.isStopped=!1,this.hasErrored=!1,this.dispatching=!1,this.hasCompleted=!1,this.source=n}return r(Subject,e),Subject.prototype.lift=function(e){var t=new Subject(this.destination||this,this);return t.operator=e,t},Subject.prototype.add=function(e){return s.Subscription.prototype.add.call(this,e)},Subject.prototype.remove=function(e){s.Subscription.prototype.remove.call(this,e)},Subject.prototype.unsubscribe=function(){s.Subscription.prototype.unsubscribe.call(this)},Subject.prototype._subscribe=function(e){if(this.source)return this.source.subscribe(e);if(!e.isUnsubscribed){if(this.hasErrored)return e.error(this.errorValue);if(this.hasCompleted)return e.complete();this.throwIfUnsubscribed();var t=new a.SubjectSubscription(this,e);return this.observers.push(e),t}},Subject.prototype._unsubscribe=function(){this.source=null,this.isStopped=!0,this.observers=null,this.destination=null},Subject.prototype.next=function(e){this.throwIfUnsubscribed(),this.isStopped||(this.dispatching=!0,this._next(e),this.dispatching=!1,this.hasErrored?this._error(this.errorValue):this.hasCompleted&&this._complete())},Subject.prototype.error=function(e){this.throwIfUnsubscribed(),this.isStopped||(this.isStopped=!0,this.hasErrored=!0,this.errorValue=e,this.dispatching||this._error(e))},Subject.prototype.complete=function(){this.throwIfUnsubscribed(),this.isStopped||(this.isStopped=!0,this.hasCompleted=!0,this.dispatching||this._complete())},Subject.prototype.asObservable=function(){var e=new d(this);return e},Subject.prototype._next=function(e){this.destination?this.destination.next(e):this._finalNext(e)},Subject.prototype._finalNext=function(e){for(var t=-1,n=this.observers.slice(0),r=n.length;++t"+i+""};e.exports=function(e,t){var n={};n[e]=t(a),r(r.P+r.F*i(function(){var t=""[e]('"');return t!==t.toLowerCase()||t.split('"').length>3}),"String",n)}},function(e,t,n){"use strict";var r=n(81),i=n(514),o=n(217),s=n(42),a=n(38),l=n(513),c=function(){function Subscription(e){this.isUnsubscribed=!1,e&&(this._unsubscribe=e)}return Subscription.prototype.unsubscribe=function(){var e,t=!1;if(!this.isUnsubscribed){this.isUnsubscribed=!0;var n=this,c=n._unsubscribe,u=n._subscriptions;if(this._subscriptions=null,o.isFunction(c)){var p=s.tryCatch(c).call(this);p===a.errorObject&&(t=!0,(e=e||[]).push(a.errorObject.e))}if(r.isArray(u))for(var d=-1,h=u.length;++d0?i(r(e),9007199254740991):0}},function(e,t,n){"use strict";var r=n(1082);t.async=new r.AsyncScheduler},function(e,t,n){"use strict";function __export(e){for(var n in e)t.hasOwnProperty(n)||(t[n]=e[n])}var r=n(86);t.HostMetadata=r.HostMetadata,t.InjectMetadata=r.InjectMetadata,t.InjectableMetadata=r.InjectableMetadata,t.OptionalMetadata=r.OptionalMetadata,t.SelfMetadata=r.SelfMetadata,t.SkipSelfMetadata=r.SkipSelfMetadata,__export(n(115));var i=n(162);t.forwardRef=i.forwardRef,t.resolveForwardRef=i.resolveForwardRef;var o=n(163);t.Injector=o.Injector;var s=n(571);t.ReflectiveInjector=s.ReflectiveInjector;var a=n(250);t.Binding=a.Binding,t.ProviderBuilder=a.ProviderBuilder,t.bind=a.bind,t.Provider=a.Provider,t.provide=a.provide;var l=n(253);t.ResolvedReflectiveFactory=l.ResolvedReflectiveFactory;var c=n(252);t.ReflectiveKey=c.ReflectiveKey;var u=n(251);t.NoProviderError=u.NoProviderError,t.AbstractProviderError=u.AbstractProviderError,t.CyclicDependencyError=u.CyclicDependencyError,t.InstantiationError=u.InstantiationError,t.InvalidProviderError=u.InvalidProviderError,t.NoAnnotationError=u.NoAnnotationError,t.OutOfBoundsError=u.OutOfBoundsError;var p=n(374);t.OpaqueToken=p.OpaqueToken},[1104,32],function(e,t){var n={}.hasOwnProperty;e.exports=function(e,t){return n.call(e,t)}},function(e,t,n){"use strict";var r=n(13);e.exports=function(e,t){return!!e&&r(function(){t?e.call(null,function(){},1):e.call(null)})}},function(e,t,n){var r=n(75);e.exports=function(e){return Object(r(e))}},function(e,t,n){"use strict";(function(e,n){var r={"boolean":!1,"function":!0,object:!0,number:!1,string:!1,undefined:!1};t.root=r[typeof self]&&self||r[typeof window]&&window;var i=(r[typeof t]&&t&&!t.nodeType&&t,r[typeof e]&&e&&!e.nodeType&&e,r[typeof n]&&n);!i||i.global!==i&&i.window!==i||(t.root=i)}).call(t,n(1100)(e),n(82))},function(e,t,n){"use strict";var r=n(0);t.NG_VALUE_ACCESSOR=new r.OpaqueToken("NgValueAccessor")},52,function(e,t,n){"use strict";function _convertToPromise(e){return s.isPromise(e)?e:i.toPromise.call(e)}function _executeValidators(e,t){return t.map(function(t){return t(e)})}function _executeAsyncValidators(e,t){return t.map(function(t){return t(e)})}function _mergeErrors(e){var t=e.reduce(function(e,t){return s.isPresent(t)?o.StringMapWrapper.merge(e,t):e},{});return o.StringMapWrapper.isEmpty(t)?null:t}var r=n(0),i=n(313),o=n(47),s=n(32);t.NG_VALIDATORS=new r.OpaqueToken("NgValidators"),t.NG_ASYNC_VALIDATORS=new r.OpaqueToken("NgAsyncValidators");var a=function(){function Validators(){}return Validators.required=function(e){return s.isBlank(e.value)||s.isString(e.value)&&""==e.value?{required:!0}:null},Validators.minLength=function(e){return function(t){if(s.isPresent(Validators.required(t)))return null;var n=t.value;return n.lengthe?{maxlength:{requiredLength:e,actualLength:n.length}}:null}},Validators.pattern=function(e){return function(t){if(s.isPresent(Validators.required(t)))return null;var n=new RegExp("^"+e+"$"),r=t.value;return n.test(r)?null:{pattern:{requiredPattern:"^"+e+"$",actualValue:r}}}},Validators.nullValidator=function(e){return null},Validators.compose=function(e){if(s.isBlank(e))return null;var t=e.filter(s.isPresent);return 0==t.length?null:function(e){return _mergeErrors(_executeValidators(e,t))}},Validators.composeAsync=function(e){if(s.isBlank(e))return null;var t=e.filter(s.isPresent);return 0==t.length?null:function(e){var n=_executeAsyncValidators(e,t).map(_convertToPromise);return Promise.all(n).then(_mergeErrors)}},Validators}();t.Validators=a},function(e,t,n){"use strict";var r=n(0),i=n(123),o=n(72),s=n(16),a=n(126),l=n(278);t.PRIMITIVE=String;var c=function(){function Serializer(e){this._renderStore=e}return Serializer.prototype.serialize=function(e,n){var i=this;if(!s.isPresent(e))return null;if(s.isArray(e))return e.map(function(e){return i.serialize(e,n)});if(n==t.PRIMITIVE)return e;if(n==u)return this._renderStore.serialize(e);if(n===r.RenderComponentType)return this._serializeRenderComponentType(e);if(n===r.ViewEncapsulation)return s.serializeEnum(e);if(n===l.LocationType)return this._serializeLocation(e);throw new o.BaseException("No serializer for "+n.toString())},Serializer.prototype.deserialize=function(e,n,a){var c=this;if(!s.isPresent(e))return null;if(s.isArray(e)){var p=[];return e.forEach(function(e){return p.push(c.deserialize(e,n,a))}),p}if(n==t.PRIMITIVE)return e;if(n==u)return this._renderStore.deserialize(e);if(n===r.RenderComponentType)return this._deserializeRenderComponentType(e);if(n===r.ViewEncapsulation)return i.VIEW_ENCAPSULATION_VALUES[e];if(n===l.LocationType)return this._deserializeLocation(e);throw new o.BaseException("No deserializer for "+n.toString())},Serializer.prototype._serializeLocation=function(e){return{href:e.href,protocol:e.protocol,host:e.host,hostname:e.hostname,port:e.port,pathname:e.pathname,search:e.search,hash:e.hash,origin:e.origin}},Serializer.prototype._deserializeLocation=function(e){return new l.LocationType(e.href,e.protocol,e.host,e.hostname,e.port,e.pathname,e.search,e.hash,e.origin)},Serializer.prototype._serializeRenderComponentType=function(e){return{id:e.id,templateUrl:e.templateUrl,slotCount:e.slotCount,encapsulation:this.serialize(e.encapsulation,r.ViewEncapsulation),styles:this.serialize(e.styles,t.PRIMITIVE)}},Serializer.prototype._deserializeRenderComponentType=function(e){return new r.RenderComponentType(e.id,e.templateUrl,e.slotCount,this.deserialize(e.encapsulation,r.ViewEncapsulation),this.deserialize(e.styles,t.PRIMITIVE),{})},Serializer.decorators=[{type:r.Injectable}],Serializer.ctorParameters=[{type:a.RenderStore}],Serializer}();t.Serializer=c;var u=function(){function RenderStoreObject(){}return RenderStoreObject}();t.RenderStoreObject=u},function(e,t,n){var r=n(2),i=n(24),o=n(13);e.exports=function(e,t){var n=(i.Object||{})[e]||Object[e],s={};s[e]=t(n),r(r.S+r.F*o(function(){n(1)}),"Object",s)}},function(e,t,n){var r=n(133),i=n(75);e.exports=function(e){return r(i(e))}},function(e,t,n){"use strict";function _convertToPromise(e){return s.isPromise(e)?e:i.toPromise.call(e)}function _executeValidators(e,t){return t.map(function(t){return t(e)})}function _executeAsyncValidators(e,t){return t.map(function(t){return t(e)})}function _mergeErrors(e){var t=e.reduce(function(e,t){return s.isPresent(t)?o.StringMapWrapper.merge(e,t):e},{});return o.StringMapWrapper.isEmpty(t)?null:t}var r=n(0),i=n(313),o=n(34),s=n(7);t.NG_VALIDATORS=new r.OpaqueToken("NgValidators"),t.NG_ASYNC_VALIDATORS=new r.OpaqueToken("NgAsyncValidators");var a=function(){function Validators(){}return Validators.required=function(e){return s.isBlank(e.value)||s.isString(e.value)&&""==e.value?{required:!0}:null},Validators.minLength=function(e){return function(t){if(s.isPresent(Validators.required(t)))return null;var n=t.value;return n.lengthe?{maxlength:{requiredLength:e,actualLength:n.length}}:null}},Validators.pattern=function(e){return function(t){if(s.isPresent(Validators.required(t)))return null;var n=new RegExp("^"+e+"$"),r=t.value;return n.test(r)?null:{pattern:{requiredPattern:"^"+e+"$",actualValue:r}}}},Validators.nullValidator=function(e){return null},Validators.compose=function(e){if(s.isBlank(e))return null;var t=e.filter(s.isPresent);return 0==t.length?null:function(e){return _mergeErrors(_executeValidators(e,t))}},Validators.composeAsync=function(e){if(s.isBlank(e))return null;var t=e.filter(s.isPresent);return 0==t.length?null:function(e){var n=_executeAsyncValidators(e,t).map(_convertToPromise);return Promise.all(n).then(_mergeErrors)}},Validators}();t.Validators=a},function(e,t,n){"use strict";var r=this&&this.__extends||function(e,t){function __(){this.constructor=e}for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n]);e.prototype=null===t?Object.create(t):(__.prototype=t.prototype,new __)},i=n(83),o=n(7),s=function(e){function InvalidPipeArgumentException(t,n){e.call(this,"Invalid argument '"+n+"' for pipe '"+o.stringify(t)+"'")}return r(InvalidPipeArgumentException,e),InvalidPipeArgumentException}(i.BaseException);t.InvalidPipeArgumentException=s},function(e,t,n){"use strict";/** * @license * Copyright Google Inc. All Rights Reserved. * * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://angular.io/license */ -var r=n(5),i=function(){function ParseLocation(e,t,n,r){this.file=e,this.offset=t,this.line=n,this.col=r}return ParseLocation.prototype.toString=function(){return r.isPresent(this.offset)?this.file.url+"@"+this.line+":"+this.col:this.file.url},ParseLocation}();t.ParseLocation=i;var o=function(){function ParseSourceFile(e,t){this.content=e,this.url=t}return ParseSourceFile}();t.ParseSourceFile=o;var s=function(){function ParseSourceSpan(e,t,n){void 0===n&&(n=null),this.start=e,this.end=t,this.details=n}return ParseSourceSpan.prototype.toString=function(){return this.start.file.content.substring(this.start.offset,this.end.offset)},ParseSourceSpan}();t.ParseSourceSpan=s,function(e){e[e.WARNING=0]="WARNING",e[e.FATAL=1]="FATAL"}(t.ParseErrorLevel||(t.ParseErrorLevel={}));var a=t.ParseErrorLevel,l=function(){function ParseError(e,t,n){void 0===n&&(n=a.FATAL),this.span=e,this.msg=t,this.level=n}return ParseError.prototype.toString=function(){var e=this.span.start.file.content,t=this.span.start.offset,n="",i="";if(r.isPresent(t)){t>e.length-1&&(t=e.length-1);for(var o=t,s=0,a=0;s<100&&t>0&&(t--,s++,"\n"!=e[t]||3!=++a););for(s=0,a=0;s<100&&o]"+e.substring(this.span.start.offset,o+1);n=' ("'+l+'")'}return this.span.details&&(i=", "+this.span.details),""+this.msg+n+": "+this.span.start+i},ParseError}();t.ParseError=l},function(e,t,n){"use strict";function templateVisitAll(e,t,n){void 0===n&&(n=null);var i=[];return t.forEach(function(t){var o=t.visit(e,n);r.isPresent(o)&&i.push(o)}),i}var r=n(5),i=function(){function TextAst(e,t,n){this.value=e,this.ngContentIndex=t,this.sourceSpan=n}return TextAst.prototype.visit=function(e,t){return e.visitText(this,t)},TextAst}();t.TextAst=i;var o=function(){function BoundTextAst(e,t,n){this.value=e,this.ngContentIndex=t,this.sourceSpan=n}return BoundTextAst.prototype.visit=function(e,t){return e.visitBoundText(this,t)},BoundTextAst}();t.BoundTextAst=o;var s=function(){function AttrAst(e,t,n){this.name=e,this.value=t,this.sourceSpan=n}return AttrAst.prototype.visit=function(e,t){return e.visitAttr(this,t)},AttrAst}();t.AttrAst=s;var a=function(){function BoundElementPropertyAst(e,t,n,r,i,o){this.name=e,this.type=t,this.securityContext=n,this.value=r,this.unit=i,this.sourceSpan=o}return BoundElementPropertyAst.prototype.visit=function(e,t){return e.visitElementProperty(this,t)},BoundElementPropertyAst}();t.BoundElementPropertyAst=a;var l=function(){function BoundEventAst(e,t,n,r){this.name=e,this.target=t,this.handler=n,this.sourceSpan=r}return BoundEventAst.prototype.visit=function(e,t){return e.visitEvent(this,t)},Object.defineProperty(BoundEventAst.prototype,"fullName",{get:function(){return r.isPresent(this.target)?this.target+":"+this.name:this.name},enumerable:!0,configurable:!0}),BoundEventAst}();t.BoundEventAst=l;var c=function(){function ReferenceAst(e,t,n){this.name=e,this.value=t,this.sourceSpan=n}return ReferenceAst.prototype.visit=function(e,t){return e.visitReference(this,t)},ReferenceAst}();t.ReferenceAst=c;var u=function(){function VariableAst(e,t,n){this.name=e,this.value=t,this.sourceSpan=n}return VariableAst.prototype.visit=function(e,t){return e.visitVariable(this,t)},VariableAst}();t.VariableAst=u;var p=function(){function ElementAst(e,t,n,r,i,o,s,a,l,c,u){this.name=e,this.attrs=t,this.inputs=n,this.outputs=r,this.references=i,this.directives=o,this.providers=s,this.hasViewContainer=a,this.children=l,this.ngContentIndex=c,this.sourceSpan=u}return ElementAst.prototype.visit=function(e,t){return e.visitElement(this,t)},ElementAst}();t.ElementAst=p;var d=function(){function EmbeddedTemplateAst(e,t,n,r,i,o,s,a,l,c){this.attrs=e,this.outputs=t,this.references=n,this.variables=r,this.directives=i,this.providers=o,this.hasViewContainer=s,this.children=a,this.ngContentIndex=l,this.sourceSpan=c}return EmbeddedTemplateAst.prototype.visit=function(e,t){return e.visitEmbeddedTemplate(this,t)},EmbeddedTemplateAst}();t.EmbeddedTemplateAst=d;var h=function(){function BoundDirectivePropertyAst(e,t,n,r){this.directiveName=e,this.templateName=t,this.value=n,this.sourceSpan=r}return BoundDirectivePropertyAst.prototype.visit=function(e,t){return e.visitDirectiveProperty(this,t)},BoundDirectivePropertyAst}();t.BoundDirectivePropertyAst=h;var f=function(){function DirectiveAst(e,t,n,r,i){this.directive=e,this.inputs=t,this.hostProperties=n,this.hostEvents=r,this.sourceSpan=i}return DirectiveAst.prototype.visit=function(e,t){return e.visitDirective(this,t)},DirectiveAst}();t.DirectiveAst=f;var m=function(){function ProviderAst(e,t,n,r,i,o,s){this.token=e,this.multiProvider=t,this.eager=n,this.providers=r,this.providerType=i,this.lifecycleHooks=o,this.sourceSpan=s}return ProviderAst.prototype.visit=function(e,t){return null},ProviderAst}();t.ProviderAst=m,function(e){e[e.PublicService=0]="PublicService",e[e.PrivateService=1]="PrivateService",e[e.Component=2]="Component",e[e.Directive=3]="Directive",e[e.Builtin=4]="Builtin"}(t.ProviderAstType||(t.ProviderAstType={}));var y=(t.ProviderAstType,function(){function NgContentAst(e,t,n){this.index=e,this.ngContentIndex=t,this.sourceSpan=n}return NgContentAst.prototype.visit=function(e,t){return e.visitNgContent(this,t)},NgContentAst}());t.NgContentAst=y,function(e){e[e.Property=0]="Property",e[e.Attribute=1]="Attribute",e[e.Class=2]="Class",e[e.Style=3]="Style",e[e.Animation=4]="Animation"}(t.PropertyBindingType||(t.PropertyBindingType={}));t.PropertyBindingType;t.templateVisitAll=templateVisitAll},function(e,t){"use strict";var n=function(){function MessageBus(){}return MessageBus}();t.MessageBus=n},function(e,t){"use strict";t.PRIMARY_OUTLET="primary"},function(e,t,n){var r=n(106),i=n(133),o=n(50),s=n(44),a=n(676);e.exports=function(e,t){var n=1==e,l=2==e,c=3==e,u=4==e,p=6==e,d=5==e||p,h=t||a;return function(t,a,f){for(var m,y,g=o(t),v=i(g),b=r(a,f,3),_=s(v.length),w=0,S=n?h(t,_):l?h(t,0):void 0;_>w;w++)if((d||w in v)&&(m=v[w],y=b(m,w,g),e))if(n)S[w]=y;else if(y)switch(e){case 3:return!0;case 5:return m;case 6:return w;case 2:S.push(m)}else if(u)return!1;return p?-1:c||u?u:S}}},function(e,t,n){var r=n(30),i=n(109);e.exports=n(35)?function(e,t,n){return r.f(e,t,i(1,n))}:function(e,t,n){return e[t]=n,e}},function(e,t,n){var r=n(472),i=n(2),o=n(199)("metadata"),s=o.store||(o.store=new(n(798))),a=function(e,t,n){var i=s.get(e);if(!i){if(!n)return;s.set(e,i=new r)}var o=i.get(t);if(!o){if(!n)return;i.set(t,o=new r)}return o},l=function(e,t,n){var r=a(t,n,!1);return void 0!==r&&r.has(e)},c=function(e,t,n){var r=a(t,n,!1);return void 0===r?void 0:r.get(e)},u=function(e,t,n,r){a(n,r,!0).set(e,t)},p=function(e,t){var n=a(e,t,!1),r=[];return n&&n.forEach(function(e,t){r.push(t)}),r},d=function(e){return void 0===e||"symbol"==typeof e?e:String(e)},h=function(e){i(i.S,"Reflect",e)};e.exports={store:s,map:a,has:l,get:c,set:u,keys:p,key:d,exp:h}},function(e,t,n){var r=n(48),i=n(50),o=n(300)("IE_PROTO"),s=Object.prototype;e.exports=Object.getPrototypeOf||function(e){return e=i(e),r(e,o)?e[o]:"function"==typeof e.constructor&&e instanceof e.constructor?e.constructor.prototype:e instanceof Object?s:null}},function(e,t,n){"use strict";var r=n(347),i=function(){function InterpolationConfig(e,t){this.start=e,this.end=t}return InterpolationConfig.fromArray=function(e){return e?(r.assertInterpolationSymbols("interpolation",e),new InterpolationConfig(e[0],e[1])):t.DEFAULT_INTERPOLATION_CONFIG},InterpolationConfig}();t.InterpolationConfig=i,t.DEFAULT_INTERPOLATION_CONFIG=new i("{{","}}")},[1107,263],function(e,t,n){"use strict";function controlPath(e,t){var n=r.ListWrapper.clone(t.path);return n.push(e),n}function setUpControl(e,t){o.isBlank(e)&&_throwError(t,"Cannot find control with"),o.isBlank(t.valueAccessor)&&_throwError(t,"No value accessor for form control with"),e.validator=s.Validators.compose([e.validator,t.validator]),e.asyncValidator=s.Validators.composeAsync([e.asyncValidator,t.asyncValidator]),t.valueAccessor.writeValue(e.value),t.valueAccessor.registerOnChange(function(n){t.viewToModelUpdate(n),e.markAsDirty(),e.setValue(n,{emitModelToViewChange:!1})}),e.registerOnChange(function(e,n){t.valueAccessor.writeValue(e),n&&t.viewToModelUpdate(e)}),t.valueAccessor.registerOnTouched(function(){return e.markAsTouched()})}function setUpFormContainer(e,t){o.isBlank(e)&&_throwError(t,"Cannot find control with"),e.validator=s.Validators.compose([e.validator,t.validator]),e.asyncValidator=s.Validators.composeAsync([e.asyncValidator,t.asyncValidator])}function _throwError(e,t){var n;throw n=e.path.length>1?"path: '"+e.path.join(" -> ")+"'":e.path[0]?"name: '"+e.path+"'":"unspecified name attribute",new i.BaseException(t+" "+n)}function composeValidators(e){return o.isPresent(e)?s.Validators.compose(e.map(c.normalizeValidator)):null}function composeAsyncValidators(e){return o.isPresent(e)?s.Validators.composeAsync(e.map(c.normalizeAsyncValidator)):null}function isPropertyUpdated(e,t){if(!r.StringMapWrapper.contains(e,"model"))return!1;var n=e.model;return!!n.isFirstChange()||!o.looseIdentical(t,n.currentValue)}function selectValueAccessor(e,t){if(o.isBlank(t))return null;var n,r,i;return t.forEach(function(t){o.hasConstructor(t,l.DefaultValueAccessor)?n=t:o.hasConstructor(t,a.CheckboxControlValueAccessor)||o.hasConstructor(t,u.NumberValueAccessor)||o.hasConstructor(t,d.SelectControlValueAccessor)||o.hasConstructor(t,h.SelectMultipleControlValueAccessor)||o.hasConstructor(t,p.RadioControlValueAccessor)?(o.isPresent(r)&&_throwError(e,"More than one built-in value accessor matches form control with"),r=t):(o.isPresent(i)&&_throwError(e,"More than one custom value accessor matches form control with"),i=t)}),o.isPresent(i)?i:o.isPresent(r)?r:o.isPresent(n)?n:(_throwError(e,"No valid value accessor for form control with"),null)}var r=n(47),i=n(88),o=n(32),s=n(54),a=n(169),l=n(170),c=n(587),u=n(266),p=n(172),d=n(173),h=n(174);t.controlPath=controlPath,t.setUpControl=setUpControl,t.setUpFormContainer=setUpFormContainer,t.composeValidators=composeValidators,t.composeAsyncValidators=composeAsyncValidators,t.isPropertyUpdated=isPropertyUpdated,t.selectValueAccessor=selectValueAccessor},function(e,t){"use strict";!function(e){e[e.Get=0]="Get",e[e.Post=1]="Post",e[e.Put=2]="Put",e[e.Delete=3]="Delete",e[e.Options=4]="Options",e[e.Head=5]="Head",e[e.Patch=6]="Patch"}(t.RequestMethod||(t.RequestMethod={}));t.RequestMethod;!function(e){e[e.Unsent=0]="Unsent",e[e.Open=1]="Open",e[e.HeadersReceived=2]="HeadersReceived",e[e.Loading=3]="Loading",e[e.Done=4]="Done",e[e.Cancelled=5]="Cancelled"}(t.ReadyState||(t.ReadyState={}));t.ReadyState;!function(e){e[e.Basic=0]="Basic",e[e.Cors=1]="Cors",e[e.Default=2]="Default",e[e.Error=3]="Error",e[e.Opaque=4]="Opaque"}(t.ResponseType||(t.ResponseType={}));t.ResponseType;!function(e){e[e.NONE=0]="NONE",e[e.JSON=1]="JSON",e[e.FORM=2]="FORM",e[e.FORM_DATA=3]="FORM_DATA",e[e.TEXT=4]="TEXT",e[e.BLOB=5]="BLOB",e[e.ARRAY_BUFFER=6]="ARRAY_BUFFER"}(t.ContentType||(t.ContentType={}));t.ContentType;!function(e){e[e.Text=0]="Text",e[e.Json=1]="Json",e[e.ArrayBuffer=2]="ArrayBuffer",e[e.Blob=3]="Blob"}(t.ResponseContentType||(t.ResponseContentType={}));t.ResponseContentType},[1106,418,419,419],function(e,t,n){"use strict";function createEmptyUrlTree(){return new o(new s([],{}),{},null)}function containsTree(e,t,n){return n?equalSegmentGroups(e.root,t.root):containsSegmentGroup(e.root,t.root)}function equalSegmentGroups(e,t){if(!equalPath(e.segments,t.segments))return!1;if(e.numberOfChildren!==t.numberOfChildren)return!1;for(var n in t.children){if(!e.children[n])return!1;if(!equalSegmentGroups(e.children[n],t.children[n]))return!1}return!0}function containsSegmentGroup(e,t){return containsSegmentGroupHelper(e,t,t.segments)}function containsSegmentGroupHelper(e,t,n){if(e.segments.length>n.length){var i=e.segments.slice(0,n.length);return!!equalPath(i,n)&&!t.hasChildren()}if(e.segments.length===n.length){if(!equalPath(e.segments,n))return!1;for(var o in t.children){if(!e.children[o])return!1;if(!containsSegmentGroup(e.children[o],t.children[o]))return!1}return!0}var i=n.slice(0,e.segments.length),s=n.slice(e.segments.length);return!!equalPath(e.segments,i)&&(!!e.children[r.PRIMARY_OUTLET]&&containsSegmentGroupHelper(e.children[r.PRIMARY_OUTLET],t,s))}function equalSegments(e,t){if(e.length!==t.length)return!1;for(var n=0;n0?n+"("+o.join("//")+")":""+n}if(e.hasChildren()&&!t){var s=mapChildrenIntoArray(e,function(t,n){return n===r.PRIMARY_OUTLET?[serializeSegment(e.children[r.PRIMARY_OUTLET],!1)]:[n+":"+serializeSegment(t,!1)]});return serializePaths(e)+"/("+s.join("//")+")"}return serializePaths(e)}function encode(e){return encodeURIComponent(e)}function decode(e){return decodeURIComponent(e)}function serializePath(e){return""+encode(e.path)+serializeParams(e.parameters)}function serializeParams(e){return pairs(e).map(function(e){return";"+encode(e.first)+"="+encode(e.second)}).join("")}function serializeQueryParams(e){var t=pairs(e).map(function(e){return encode(e.first)+"="+encode(e.second)});return t.length>0?"?"+t.join("&"):""}function pairs(e){var t=[];for(var n in e)e.hasOwnProperty(n)&&t.push(new u(n,e[n]));return t}function matchSegments(e){p.lastIndex=0;var t=e.match(p);return t?t[0]:""}function matchQueryParams(e){d.lastIndex=0;var t=e.match(p);return t?t[0]:""}function matchUrlQueryParamValue(e){h.lastIndex=0;var t=e.match(h);return t?t[0]:""}var r=n(63),i=n(74);t.createEmptyUrlTree=createEmptyUrlTree,t.containsTree=containsTree;var o=function(){function UrlTree(e,t,n){this.root=e,this.queryParams=t,this.fragment=n}return UrlTree.prototype.toString=function(){return(new c).serialize(this)},UrlTree}();t.UrlTree=o;var s=function(){function UrlSegmentGroup(e,t){var n=this;this.segments=e,this.children=t,this.parent=null,i.forEach(t,function(e,t){return e.parent=n})}return UrlSegmentGroup.prototype.hasChildren=function(){return this.numberOfChildren>0},Object.defineProperty(UrlSegmentGroup.prototype,"numberOfChildren",{get:function(){return Object.keys(this.children).length},enumerable:!0,configurable:!0}),UrlSegmentGroup.prototype.toString=function(){return serializePaths(this)},UrlSegmentGroup}();t.UrlSegmentGroup=s;var a=function(){function UrlSegment(e,t){this.path=e,this.parameters=t}return UrlSegment.prototype.toString=function(){return serializePath(this)},UrlSegment}();t.UrlSegment=a,t.equalSegments=equalSegments,t.equalPath=equalPath,t.mapChildrenIntoArray=mapChildrenIntoArray;var l=function(){function UrlSerializer(){}return UrlSerializer}();t.UrlSerializer=l;var c=function(){function DefaultUrlSerializer(){}return DefaultUrlSerializer.prototype.parse=function(e){var t=new f(e);return new o(t.parseRootSegment(),t.parseQueryParams(),t.parseFragment())},DefaultUrlSerializer.prototype.serialize=function(e){var t="/"+serializeSegment(e.root,!0),n=serializeQueryParams(e.queryParams),r=null!==e.fragment&&void 0!==e.fragment?"#"+encodeURIComponent(e.fragment):"";return""+t+n+r},DefaultUrlSerializer}();t.DefaultUrlSerializer=c,t.serializePaths=serializePaths,t.encode=encode,t.decode=decode,t.serializePath=serializePath;var u=function(){function Pair(e,t){this.first=e,this.second=t}return Pair}(),p=/^[^\/\(\)\?;=&#]+/,d=/^[^=\?&#]+/,h=/^[^\?&#]+/,f=function(){function UrlParser(e){this.url=e,this.remaining=e}return UrlParser.prototype.peekStartsWith=function(e){return this.remaining.startsWith(e)},UrlParser.prototype.capture=function(e){if(!this.remaining.startsWith(e))throw new Error('Expected "'+e+'".');this.remaining=this.remaining.substring(e.length)},UrlParser.prototype.parseRootSegment=function(){return this.remaining.startsWith("/")&&this.capture("/"),""===this.remaining||this.remaining.startsWith("?")||this.remaining.startsWith("#")?new s([],{}):new s([],this.parseChildren())},UrlParser.prototype.parseChildren=function(){if(0==this.remaining.length)return{};this.peekStartsWith("/")&&this.capture("/");var e=[];for(this.peekStartsWith("(")||e.push(this.parseSegments());this.peekStartsWith("/")&&!this.peekStartsWith("//")&&!this.peekStartsWith("/(");)this.capture("/"),e.push(this.parseSegments());var t={};this.peekStartsWith("/(")&&(this.capture("/"),t=this.parseParens(!0));var n={};return this.peekStartsWith("(")&&(n=this.parseParens(!1)),(e.length>0||Object.keys(t).length>0)&&(n[r.PRIMARY_OUTLET]=new s(e,t)),n},UrlParser.prototype.parseSegments=function(){var e=matchSegments(this.remaining);if(""===e&&this.peekStartsWith(";"))throw new Error("Empty path url segment cannot have parameters: '"+this.remaining+"'.");this.capture(e);var t={};return this.peekStartsWith(";")&&(t=this.parseMatrixParams()),new a(decode(e),t)},UrlParser.prototype.parseQueryParams=function(){var e={};if(this.peekStartsWith("?"))for(this.capture("?"),this.parseQueryParam(e);this.remaining.length>0&&this.peekStartsWith("&");)this.capture("&"),this.parseQueryParam(e);return e},UrlParser.prototype.parseFragment=function(){return this.peekStartsWith("#")?decode(this.remaining.substring(1)):null},UrlParser.prototype.parseMatrixParams=function(){for(var e={};this.remaining.length>0&&this.peekStartsWith(";");)this.capture(";"),this.parseParam(e);return e},UrlParser.prototype.parseParam=function(e){var t=matchSegments(this.remaining);if(t){this.capture(t);var n="true";if(this.peekStartsWith("=")){this.capture("=");var r=matchSegments(this.remaining);r&&(n=r,this.capture(n))}e[decode(t)]=decode(n)}},UrlParser.prototype.parseQueryParam=function(e){var t=matchQueryParams(this.remaining);if(t){this.capture(t);var n="";if(this.peekStartsWith("=")){this.capture("=");var r=matchUrlQueryParamValue(this.remaining);r&&(n=r,this.capture(n))}e[decode(t)]=decode(n)}},UrlParser.prototype.parseParens=function(e){var t={};for(this.capture("(");!this.peekStartsWith(")")&&this.remaining.length>0;){var n=matchSegments(this.remaining),i=this.remaining[n.length];if("/"!==i&&")"!==i&&";"!==i)throw new Error("Cannot parse url '"+this.url+"'");var o=void 0;n.indexOf(":")>-1?(o=n.substr(0,n.indexOf(":")),this.capture(o),this.capture(":")):e&&(o=r.PRIMARY_OUTLET);var a=this.parseChildren();t[o]=1===Object.keys(a).length?a[r.PRIMARY_OUTLET]:new s([],a),this.peekStartsWith("//")&&this.capture("//")}return this.capture(")"),t},UrlParser}()},function(e,t,n){"use strict";function shallowEqualArrays(e,t){if(e.length!==t.length)return!1;for(var n=0;n0?e[0]:null}function last(e){return e.length>0?e[e.length-1]:null}function and(e){return e.reduce(function(e,t){return e&&t},!0)}function merge(e,t){var n={};for(var r in e)e.hasOwnProperty(r)&&(n[r]=e[r]);for(var r in t)t.hasOwnProperty(r)&&(n[r]=t[r]);return n}function forEach(e,t){for(var n in e)e.hasOwnProperty(n)&&t(e[n],n)}function waitForMap(e,t){var n=[],r={};return forEach(e,function(e,i){i===s.PRIMARY_OUTLET&&n.push(t(i,e).map(function(e){return r[i]=e,e}))}),forEach(e,function(e,i){i!==s.PRIMARY_OUTLET&&n.push(t(i,e).map(function(e){return r[i]=e,e}))}),n.length>0?o.of.apply(void 0,n).concatAll().last().map(function(e){return r}):o.of(r)}function andObservables(e){return e.mergeAll().every(function(e){return e===!0})}function wrapIntoObservable(e){return e instanceof r.Observable?e:e instanceof Promise?i.fromPromise(e):o.of(e)}n(304),n(497);var r=n(1),i=n(211),o=n(141),s=n(63);t.shallowEqualArrays=shallowEqualArrays,t.shallowEqual=shallowEqual,t.flatten=flatten,t.first=first,t.last=last,t.and=and,t.merge=merge,t.forEach=forEach,t.waitForMap=waitForMap,t.andObservables=andObservables,t.wrapIntoObservable=wrapIntoObservable},function(e,t){e.exports=function(e){if(void 0==e)throw TypeError("Can't call method on "+e);return e}},function(e,t,n){var r=n(137)("meta"),i=n(15),o=n(48),s=n(30).f,a=0,l=Object.isExtensible||function(){return!0},c=!n(13)(function(){return l(Object.preventExtensions({}))}),u=function(e){s(e,r,{value:{i:"O"+ ++a,w:{}}})},p=function(e,t){if(!i(e))return"symbol"==typeof e?e:("string"==typeof e?"S":"P")+e;if(!o(e,r)){if(!l(e))return"F";if(!t)return"E";u(e)}return e[r].i},d=function(e,t){if(!o(e,r)){if(!l(e))return!0;if(!t)return!1;u(e)}return e[r].w},h=function(e){return c&&f.NEED&&l(e)&&!o(e,r)&&u(e),e},f=e.exports={KEY:r,NEED:!1,fastKey:p,getWeak:d,onFreeze:h}},function(e,t,n){var r=n(197),i=n(109),o=n(57),s=n(97),a=n(48),l=n(453),c=Object.getOwnPropertyDescriptor;t.f=n(35)?c:function(e,t){if(e=o(e),t=s(t,!0),l)try{return c(e,t)}catch(n){}if(a(e,t))return i(!r.f.call(e,t),e[t])}},function(e,t){e.exports=".vt-row {\n display: flex;\n flex-wrap: wrap;\n height: 100%;\n width: 100%;\n}\n\n.vt-card {\n display: inline-table;\n margin-left: 25px;\n margin-bottom: 10px;\n margin-top: 10px;\n}\n\n.stats-container {\n width: 100%;\n}\n\n.vt-padding{\n padding-left: 25px;\n padding-right: 25px;\n}\n\n>>> p-dialog .ui-dialog{\n position: fixed !important;\n top: 50% !important;\n left: 50% !important;\n transform: translate(-50%, -50%);\n margin: 0;\n width: auto !important;\n}\n\n.vt-popUpContainer{\n position: fixed;\n padding: 0;\n margin: 0;\n z-index: 0;\n bottom: 0;\n right: 0;\n top: 0;\n left: 0;\n min-height: 1000vh;\n min-width: 1000vw;\n height: 100%;\n width: 100%;\n background: rgba(0,0,0,0.6);\n}\n\n.vt-dark-link:link {\n text-decoration: none;\n color: black;\n}\n\n.vt-dark-link:visited {\n text-decoration: none;\n color: black;\n}\n\n.vt-dark-link:hover {\n text-decoration: none;\n color: black;\n}\n\n.vt-dark-link:active {\n text-decoration: none;\n color: black;\n}\n\n/* Toolbar */\n.vt-toolbar {\n width: 100%;\n text-align: center;\n}\n\n>>> p-accordiontab a {\n padding-left: 25px! important;\n}\n\n>>> .ui-accordion-content button {\n margin-top: 2px;\n}\n\n>>> p-menu .ui-menu {\n margin-top: 19px;\n display: inline-block;\n top: auto !important;\n left: auto !important;\n float: right;\n \n}\n\np-menu {\n display: inline-block;\n float: left;\n}\n\n.vt-toolbar .vt-menu {\n padding-top: 19px;\n float: left;\n}\n\n.vt-toolbar .vt-right-menu {\n padding-top: 19px;\n position: fixed;\n right: 25px;\n top: 19px;\n}\n\n.vt-card-toolbar {\n display: inline-block;\n width: 100%;\n}\n\n.vt-card-toolbar .vt-menu {\n float: left;\n}\n.vt-card-toolbar .vt-title {\n float: right;\n margin: 0;\n padding-left: 25px;\n}\n\nmd-list:hover {\n background: #E8E8E8\n}\n"},function(e,t,n){"use strict";var r=this&&this.__extends||function(e,t){function __(){this.constructor=e}for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n]);e.prototype=null===t?Object.create(t):(__.prototype=t.prototype,new __)},i=n(1),o=n(308),s=n(80),a=n(98),l=function(e){function ArrayObservable(t,n){e.call(this),this.array=t,this.scheduler=n,n||1!==t.length||(this._isScalar=!0,this.value=t[0])}return r(ArrayObservable,e),ArrayObservable.create=function(e,t){return new ArrayObservable(e,t)},ArrayObservable.of=function(){for(var e=[],t=0;t1?new ArrayObservable(e,n):1===r?new o.ScalarObservable(e[0],n):new s.EmptyObservable(n)},ArrayObservable.dispatch=function(e){var t=e.array,n=e.index,r=e.count,i=e.subscriber;return n>=r?void i.complete():(i.next(t[n]),void(i.isUnsubscribed||(e.index=n+1,this.schedule(e))))},ArrayObservable.prototype._subscribe=function(e){var t=0,n=this.array,r=n.length,i=this.scheduler;if(i)return i.schedule(ArrayObservable.dispatch,0,{array:n,index:t,count:r,subscriber:e});for(var o=0;o0?" { "+e.children.map(serializeNode).join(", ")+" } ":"";return""+e.value+t}function advanceActivatedRoute(e){e.snapshot?(a.shallowEqual(e.snapshot.queryParams,e._futureSnapshot.queryParams)||e.queryParams.next(e._futureSnapshot.queryParams),e.snapshot.fragment!==e._futureSnapshot.fragment&&e.fragment.next(e._futureSnapshot.fragment),a.shallowEqual(e.snapshot.params,e._futureSnapshot.params)||(e.params.next(e._futureSnapshot.params),e.data.next(e._futureSnapshot.data)),a.shallowEqualArrays(e.snapshot.url,e._futureSnapshot.url)||e.url.next(e._futureSnapshot.url),e.snapshot=e._futureSnapshot):(e.snapshot=e._futureSnapshot,e.data.next(e._futureSnapshot.data))}var r=this&&this.__extends||function(e,t){function __(){this.constructor=e}for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n]);e.prototype=null===t?Object.create(t):(__.prototype=t.prototype,new __)},i=n(207),o=n(63),s=n(73),a=n(74),l=n(281),c=function(e){function RouterState(t,n){e.call(this,t),this.snapshot=n,setRouterStateSnapshot(this,t)}return r(RouterState,e),Object.defineProperty(RouterState.prototype,"queryParams",{get:function(){return this.root.queryParams},enumerable:!0,configurable:!0}),Object.defineProperty(RouterState.prototype,"fragment",{get:function(){return this.root.fragment},enumerable:!0,configurable:!0}),RouterState.prototype.toString=function(){return this.snapshot.toString()},RouterState}(l.Tree);t.RouterState=c,t.createEmptyState=createEmptyState;var u=function(){function ActivatedRoute(e,t,n,r,i,o,s,a){this.url=e,this.params=t,this.queryParams=n,this.fragment=r,this.data=i,this.outlet=o,this.component=s,this._futureSnapshot=a}return Object.defineProperty(ActivatedRoute.prototype,"routeConfig",{get:function(){return this._futureSnapshot.routeConfig},enumerable:!0,configurable:!0}),Object.defineProperty(ActivatedRoute.prototype,"root",{get:function(){return this._routerState.root},enumerable:!0,configurable:!0}),Object.defineProperty(ActivatedRoute.prototype,"parent",{get:function(){return this._routerState.parent(this)},enumerable:!0,configurable:!0}),Object.defineProperty(ActivatedRoute.prototype,"firstChild",{get:function(){return this._routerState.firstChild(this)},enumerable:!0,configurable:!0}),Object.defineProperty(ActivatedRoute.prototype,"children",{get:function(){return this._routerState.children(this)},enumerable:!0,configurable:!0}),Object.defineProperty(ActivatedRoute.prototype,"pathFromRoot",{get:function(){return this._routerState.pathFromRoot(this)},enumerable:!0,configurable:!0}),ActivatedRoute.prototype.toString=function(){return this.snapshot?this.snapshot.toString():"Future("+this._futureSnapshot+")"},ActivatedRoute}();t.ActivatedRoute=u;var p=function(){function InheritedResolve(e,t){this.parent=e,this.current=t,this.resolvedData={}}return Object.defineProperty(InheritedResolve.prototype,"flattenedResolvedData",{get:function(){return this.parent?a.merge(this.parent.flattenedResolvedData,this.resolvedData):this.resolvedData},enumerable:!0,configurable:!0}),Object.defineProperty(InheritedResolve,"empty",{get:function(){return new InheritedResolve(null,{})},enumerable:!0,configurable:!0}),InheritedResolve}();t.InheritedResolve=p;var d=function(){function ActivatedRouteSnapshot(e,t,n,r,i,o,s,a,l,c,u){this.url=e,this.params=t,this.queryParams=n,this.fragment=r,this.data=i,this.outlet=o,this.component=s,this._routeConfig=a,this._urlSegment=l,this._lastPathIndex=c,this._resolve=u}return Object.defineProperty(ActivatedRouteSnapshot.prototype,"routeConfig",{get:function(){return this._routeConfig},enumerable:!0,configurable:!0}),Object.defineProperty(ActivatedRouteSnapshot.prototype,"root",{get:function(){return this._routerState.root},enumerable:!0,configurable:!0}),Object.defineProperty(ActivatedRouteSnapshot.prototype,"parent",{get:function(){return this._routerState.parent(this)},enumerable:!0,configurable:!0}),Object.defineProperty(ActivatedRouteSnapshot.prototype,"firstChild",{get:function(){return this._routerState.firstChild(this)},enumerable:!0,configurable:!0}),Object.defineProperty(ActivatedRouteSnapshot.prototype,"children",{get:function(){return this._routerState.children(this)},enumerable:!0,configurable:!0}),Object.defineProperty(ActivatedRouteSnapshot.prototype,"pathFromRoot",{get:function(){return this._routerState.pathFromRoot(this)},enumerable:!0,configurable:!0}),ActivatedRouteSnapshot.prototype.toString=function(){var e=this.url.map(function(e){return e.toString()}).join("/"),t=this._routeConfig?this._routeConfig.path:"";return"Route(url:'"+e+"', path:'"+t+"')"},ActivatedRouteSnapshot}();t.ActivatedRouteSnapshot=d;var h=function(e){function RouterStateSnapshot(t,n){e.call(this,n),this.url=t,setRouterStateSnapshot(this,n)}return r(RouterStateSnapshot,e),Object.defineProperty(RouterStateSnapshot.prototype,"queryParams",{get:function(){return this.root.queryParams},enumerable:!0,configurable:!0}),Object.defineProperty(RouterStateSnapshot.prototype,"fragment",{get:function(){return this.root.fragment},enumerable:!0,configurable:!0}),RouterStateSnapshot.prototype.toString=function(){return serializeNode(this._root)},RouterStateSnapshot}(l.Tree);t.RouterStateSnapshot=h,t.advanceActivatedRoute=advanceActivatedRoute},function(e,t,n){"use strict";var r=n(43),i=(n.n(r),n(0));n.n(i);n.d(t,"a",function(){return a});var o=this&&this.__decorate||function(e,t,n,r){var i,o=arguments.length,s=o<3?t:null===r?r=Object.getOwnPropertyDescriptor(t,n):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(e,t,n,r);else for(var a=e.length-1;a>=0;a--)(i=e[a])&&(s=(o<3?i(s):o>3?i(t,n,s):i(t,n))||s);return o>3&&s&&Object.defineProperty(t,n,s),s},s=this&&this.__metadata||function(e,t){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(e,t)},a=function(){function VtctlService(e){this.http=e,this.vtctlUrl="../api/vtctl/"}return VtctlService.prototype.sendPostRequest=function(e,t){var n=new r.Headers({"Content-Type":"application/json"}),i=new r.RequestOptions({headers:n});return this.http.post(e,JSON.stringify(t),i).map(function(e){return e.json()})},VtctlService.prototype.runCommand=function(e){return this.sendPostRequest(this.vtctlUrl,e)},VtctlService=o([n.i(i.Injectable)(),s("design:paramtypes",["function"==typeof(e="undefined"!=typeof r.Http&&r.Http)&&e||Object])],VtctlService);var e}()},function(e,t,n){"use strict";var r=n(192);n.d(t,"a",function(){return i});var i=function(){function DialogContent(e,t,n,r,i){void 0===e&&(e=""),void 0===t&&(t={}),void 0===n&&(n={}),void 0===r&&(r=void 0),void 0===i&&(i=""),this.nameId=e,this.flags=t,this.requiredFlags=n,this.prepareFunction=r,this.action=i}return DialogContent.prototype.getName=function(){return this.flags[this.nameId]?this.flags[this.nameId].getStrValue():""},DialogContent.prototype.setName=function(e){this.flags[this.nameId]&&this.flags[this.nameId].setValue(e)},DialogContent.prototype.getPostBody=function(e){void 0===e&&(e=void 0),e||(e=this.getFlags());var t=[],n=[];t.push(this.action);for(var r=0,i=e;r1?"path: '"+e.path.join(" -> ")+"'":e.path[0]?"name: '"+e.path+"'":"unspecified name",new i.BaseException(t+" "+n)}function composeValidators(e){return o.isPresent(e)?s.Validators.compose(e.map(c.normalizeValidator)):null}function composeAsyncValidators(e){return o.isPresent(e)?s.Validators.composeAsync(e.map(c.normalizeAsyncValidator)):null}function isPropertyUpdated(e,t){if(!r.StringMapWrapper.contains(e,"model"))return!1;var n=e.model;return!!n.isFirstChange()||!o.looseIdentical(t,n.currentValue)}function selectValueAccessor(e,t){if(o.isBlank(t))return null;var n,r,i;return t.forEach(function(t){o.hasConstructor(t,l.DefaultValueAccessor)?n=t:o.hasConstructor(t,a.CheckboxControlValueAccessor)||o.hasConstructor(t,u.NumberValueAccessor)||o.hasConstructor(t,d.SelectControlValueAccessor)||o.hasConstructor(t,h.SelectMultipleControlValueAccessor)||o.hasConstructor(t,p.RadioControlValueAccessor)?(o.isPresent(r)&&_throwError(e,"More than one built-in value accessor matches form control with"),r=t):(o.isPresent(i)&&_throwError(e,"More than one custom value accessor matches form control with"),i=t)}),o.isPresent(i)?i:o.isPresent(r)?r:o.isPresent(n)?n:(_throwError(e,"No valid value accessor for form control with"),null)}var r=n(34),i=n(83),o=n(7),s=n(58),a=n(144),l=n(145),c=n(526),u=n(227),p=n(146),d=n(147),h=n(228);t.controlPath=controlPath,t.setUpControl=setUpControl,t.setUpControlGroup=setUpControlGroup,t.composeValidators=composeValidators,t.composeAsyncValidators=composeAsyncValidators,t.isPropertyUpdated=isPropertyUpdated,t.selectValueAccessor=selectValueAccessor},function(e,t,n){"use strict";var r=n(0),i=n(18),o=n(28),s=function(){function CompilerConfig(e){var t=void 0===e?{}:e,n=t.renderTypes,i=void 0===n?new l:n,o=t.defaultEncapsulation,s=void 0===o?r.ViewEncapsulation.Emulated:o,a=t.genDebugInfo,c=t.logBindingUpdate,u=t.useJit,p=void 0===u||u,d=t.deprecatedPlatformDirectives,h=void 0===d?[]:d,f=t.deprecatedPlatformPipes,m=void 0===f?[]:f;this.renderTypes=i,this.defaultEncapsulation=s,this._genDebugInfo=a,this._logBindingUpdate=c,this.useJit=p,this.platformDirectives=h,this.platformPipes=m}return Object.defineProperty(CompilerConfig.prototype,"genDebugInfo",{get:function(){return void 0===this._genDebugInfo?r.isDevMode():this._genDebugInfo},enumerable:!0,configurable:!0}),Object.defineProperty(CompilerConfig.prototype,"logBindingUpdate",{get:function(){return void 0===this._logBindingUpdate?r.isDevMode():this._logBindingUpdate},enumerable:!0,configurable:!0}),CompilerConfig}();t.CompilerConfig=s;var a=function(){function RenderTypes(){}return Object.defineProperty(RenderTypes.prototype,"renderer",{get:function(){return i.unimplemented()},enumerable:!0,configurable:!0}),Object.defineProperty(RenderTypes.prototype,"renderText",{get:function(){return i.unimplemented()},enumerable:!0,configurable:!0}),Object.defineProperty(RenderTypes.prototype,"renderElement",{get:function(){return i.unimplemented()},enumerable:!0,configurable:!0}),Object.defineProperty(RenderTypes.prototype,"renderComment",{get:function(){return i.unimplemented()},enumerable:!0,configurable:!0}),Object.defineProperty(RenderTypes.prototype,"renderNode",{get:function(){return i.unimplemented()},enumerable:!0,configurable:!0}),Object.defineProperty(RenderTypes.prototype,"renderEvent",{get:function(){return i.unimplemented()},enumerable:!0,configurable:!0}),RenderTypes}();t.RenderTypes=a;var l=function(){function DefaultRenderTypes(){this.renderer=o.Identifiers.Renderer,this.renderText=null,this.renderElement=null,this.renderComment=null,this.renderNode=null,this.renderEvent=null}return DefaultRenderTypes}();t.DefaultRenderTypes=l},function(e,t){"use strict";function splitNsName(e){if(":"!=e[0])return[null,e];var t=e.indexOf(":",1);if(t==-1)throw new Error('Unsupported format "'+e+'" expecting ":namespace:name"');return[e.slice(1,t),e.slice(t+1)]}function getNsPrefix(e){return null===e?null:splitNsName(e)[0]}function mergeNsAndName(e,t){return e?":"+e+":"+t:t}!function(e){e[e.RAW_TEXT=0]="RAW_TEXT",e[e.ESCAPABLE_RAW_TEXT=1]="ESCAPABLE_RAW_TEXT",e[e.PARSABLE_DATA=2]="PARSABLE_DATA"}(t.TagContentType||(t.TagContentType={}));t.TagContentType;t.splitNsName=splitNsName,t.getNsPrefix=getNsPrefix,t.mergeNsAndName=mergeNsAndName,t.NAMED_ENTITIES={Aacute:"Á",aacute:"á",Acirc:"Â",acirc:"â",acute:"´",AElig:"Æ",aelig:"æ",Agrave:"À",agrave:"à",alefsym:"ℵ",Alpha:"Α",alpha:"α",amp:"&",and:"∧",ang:"∠",apos:"'",Aring:"Å",aring:"å",asymp:"≈",Atilde:"Ã",atilde:"ã",Auml:"Ä",auml:"ä",bdquo:"„",Beta:"Β",beta:"β",brvbar:"¦",bull:"•",cap:"∩",Ccedil:"Ç",ccedil:"ç",cedil:"¸",cent:"¢",Chi:"Χ",chi:"χ",circ:"ˆ",clubs:"♣",cong:"≅",copy:"©",crarr:"↵",cup:"∪",curren:"¤",dagger:"†",Dagger:"‡",darr:"↓",dArr:"⇓",deg:"°",Delta:"Δ",delta:"δ",diams:"♦",divide:"÷",Eacute:"É",eacute:"é",Ecirc:"Ê",ecirc:"ê",Egrave:"È",egrave:"è",empty:"∅",emsp:" ",ensp:" ",Epsilon:"Ε",epsilon:"ε",equiv:"≡",Eta:"Η",eta:"η",ETH:"Ð",eth:"ð",Euml:"Ë",euml:"ë",euro:"€",exist:"∃",fnof:"ƒ",forall:"∀",frac12:"½",frac14:"¼",frac34:"¾",frasl:"⁄",Gamma:"Γ",gamma:"γ",ge:"≥",gt:">",harr:"↔",hArr:"⇔",hearts:"♥",hellip:"…",Iacute:"Í",iacute:"í",Icirc:"Î",icirc:"î",iexcl:"¡",Igrave:"Ì",igrave:"ì",image:"ℑ",infin:"∞","int":"∫",Iota:"Ι",iota:"ι",iquest:"¿",isin:"∈",Iuml:"Ï",iuml:"ï",Kappa:"Κ",kappa:"κ",Lambda:"Λ",lambda:"λ",lang:"⟨",laquo:"«",larr:"←",lArr:"⇐",lceil:"⌈",ldquo:"“",le:"≤",lfloor:"⌊",lowast:"∗",loz:"◊",lrm:"‎",lsaquo:"‹",lsquo:"‘",lt:"<",macr:"¯",mdash:"—",micro:"µ",middot:"·",minus:"−",Mu:"Μ",mu:"μ",nabla:"∇",nbsp:" ",ndash:"–",ne:"≠",ni:"∋",not:"¬",notin:"∉",nsub:"⊄",Ntilde:"Ñ",ntilde:"ñ",Nu:"Ν",nu:"ν",Oacute:"Ó",oacute:"ó",Ocirc:"Ô",ocirc:"ô",OElig:"Œ",oelig:"œ",Ograve:"Ò",ograve:"ò",oline:"‾",Omega:"Ω",omega:"ω",Omicron:"Ο",omicron:"ο",oplus:"⊕",or:"∨",ordf:"ª",ordm:"º",Oslash:"Ø",oslash:"ø",Otilde:"Õ",otilde:"õ",otimes:"⊗",Ouml:"Ö",ouml:"ö",para:"¶",permil:"‰",perp:"⊥",Phi:"Φ",phi:"φ",Pi:"Π",pi:"π",piv:"ϖ",plusmn:"±",pound:"£",prime:"′",Prime:"″",prod:"∏",prop:"∝",Psi:"Ψ",psi:"ψ",quot:'"',radic:"√",rang:"⟩",raquo:"»",rarr:"→",rArr:"⇒",rceil:"⌉",rdquo:"”",real:"ℜ",reg:"®",rfloor:"⌋",Rho:"Ρ",rho:"ρ",rlm:"‏",rsaquo:"›",rsquo:"’",sbquo:"‚",Scaron:"Š",scaron:"š",sdot:"⋅",sect:"§",shy:"­",Sigma:"Σ",sigma:"σ",sigmaf:"ς",sim:"∼",spades:"♠",sub:"⊂",sube:"⊆",sum:"∑",sup:"⊃",sup1:"¹",sup2:"²",sup3:"³",supe:"⊇",szlig:"ß",Tau:"Τ",tau:"τ",there4:"∴",Theta:"Θ",theta:"θ",thetasym:"ϑ",thinsp:" ",THORN:"Þ",thorn:"þ",tilde:"˜",times:"×",trade:"™",Uacute:"Ú",uacute:"ú",uarr:"↑",uArr:"⇑",Ucirc:"Û",ucirc:"û",Ugrave:"Ù",ugrave:"ù",uml:"¨",upsih:"ϒ",Upsilon:"Υ",upsilon:"υ",Uuml:"Ü",uuml:"ü",weierp:"℘",Xi:"Ξ",xi:"ξ",Yacute:"Ý",yacute:"ý",yen:"¥",yuml:"ÿ",Yuml:"Ÿ",Zeta:"Ζ",zeta:"ζ",zwj:"‍",zwnj:"‌"}},function(e,t,n){"use strict";function createUrlResolverWithoutPackagePrefix(){return new s}function createOfflineCompileUrlResolver(){return new s(o)}function getUrlScheme(e){var t=_split(e);return t&&t[a.Scheme]||""}function _buildFromEncodedParts(e,t,n,r,o,s,a){var l=[];return i.isPresent(e)&&l.push(e+":"),i.isPresent(n)&&(l.push("//"),i.isPresent(t)&&l.push(t+"@"),l.push(n),i.isPresent(r)&&l.push(":"+r)),i.isPresent(o)&&l.push(o),i.isPresent(s)&&l.push("?"+s),i.isPresent(a)&&l.push("#"+a),l.join("")}function _split(e){return e.match(l)}function _removeDotSegments(e){if("/"==e)return"/";for(var t="/"==e[0]?"/":"",n="/"===e[e.length-1]?"/":"",r=e.split("/"),i=[],o=0,s=0;s0?i.pop():o++;break;default:i.push(a)}}if(""==t){for(;o-- >0;)i.unshift("..");0===i.length&&i.push(".")}return t+i.join("/")+n}function _joinAndCanonicalizePath(e){var t=e[a.Path];return t=i.isBlank(t)?"":_removeDotSegments(t),e[a.Path]=t,_buildFromEncodedParts(e[a.Scheme],e[a.UserInfo],e[a.Domain],e[a.Port],t,e[a.QueryData],e[a.Fragment])}function _resolveUrl(e,t){var n=_split(encodeURI(t)),r=_split(e);if(i.isPresent(n[a.Scheme]))return _joinAndCanonicalizePath(n);n[a.Scheme]=r[a.Scheme];for(var o=a.Scheme;o<=a.Port;o++)i.isBlank(n[o])&&(n[o]=r[o]);if("/"==n[a.Path][0])return _joinAndCanonicalizePath(n);var s=r[a.Path];i.isBlank(s)&&(s="/");var l=s.lastIndexOf("/");return s=s.substring(0,l+1)+n[a.Path],n[a.Path]=s,_joinAndCanonicalizePath(n)}var r=n(0),i=n(5),o="asset:";t.createUrlResolverWithoutPackagePrefix=createUrlResolverWithoutPackagePrefix,t.createOfflineCompileUrlResolver=createOfflineCompileUrlResolver,t.DEFAULT_PACKAGE_URL_PROVIDER={provide:r.PACKAGE_ROOT_URL,useValue:"/"};var s=function(){function UrlResolver(e){void 0===e&&(e=null),this._packagePrefix=e}return UrlResolver.prototype.resolve=function(e,t){var n=t;i.isPresent(e)&&e.length>0&&(n=_resolveUrl(e,n));var r=_split(n),s=this._packagePrefix;if(i.isPresent(s)&&i.isPresent(r)&&"package"==r[a.Scheme]){var l=r[a.Path];if(this._packagePrefix!==o)return s=i.StringWrapper.stripRight(s,"/"),l=i.StringWrapper.stripLeft(l,"/"),s+"/"+l;var c=l.split(/\//);n="asset:"+c[0]+"/lib/"+c.slice(1).join("/")}return n},UrlResolver.decorators=[{type:r.Injectable}],UrlResolver.ctorParameters=[{type:void 0,decorators:[{type:r.Inject,args:[r.PACKAGE_ROOT_URL]}]}],UrlResolver}();t.UrlResolver=s,t.getUrlScheme=getUrlScheme;var a,l=new RegExp("^(?:([^:/?#.]+):)?(?://(?:([^/?#]*)@)?([\\w\\d\\-\\u0100-\\uffff.%]*)(?::([0-9]+))?)?([^?#]+)?(?:\\?([^#]*))?(?:#(.*))?$");!function(e){e[e.Scheme=1]="Scheme",e[e.UserInfo=2]="UserInfo",e[e.Domain=3]="Domain",e[e.Port=4]="Port",e[e.Path=5]="Path",e[e.QueryData=6]="QueryData",e[e.Fragment=7]="Fragment"}(a||(a={}))},function(e,t,n){"use strict";function _enumExpression(e,t){if(s.isBlank(t))return l.NULL_EXPR;var n=s.resolveEnumToken(e.runtime,t);return l.importExpr(new o.CompileIdentifierMetadata({name:e.name+"."+n,moduleUrl:e.moduleUrl,runtime:t}))}var r=n(0),i=n(27),o=n(31),s=n(5),a=n(28),l=n(17),c=function(){function ViewTypeEnum(){}return ViewTypeEnum.fromValue=function(e){return _enumExpression(a.Identifiers.ViewType,e)},ViewTypeEnum.HOST=ViewTypeEnum.fromValue(i.ViewType.HOST),ViewTypeEnum.COMPONENT=ViewTypeEnum.fromValue(i.ViewType.COMPONENT),ViewTypeEnum.EMBEDDED=ViewTypeEnum.fromValue(i.ViewType.EMBEDDED),ViewTypeEnum}();t.ViewTypeEnum=c;var u=function(){function ViewEncapsulationEnum(){}return ViewEncapsulationEnum.fromValue=function(e){return _enumExpression(a.Identifiers.ViewEncapsulation,e)},ViewEncapsulationEnum.Emulated=ViewEncapsulationEnum.fromValue(r.ViewEncapsulation.Emulated),ViewEncapsulationEnum.Native=ViewEncapsulationEnum.fromValue(r.ViewEncapsulation.Native),ViewEncapsulationEnum.None=ViewEncapsulationEnum.fromValue(r.ViewEncapsulation.None),ViewEncapsulationEnum}();t.ViewEncapsulationEnum=u;var p=function(){function ChangeDetectionStrategyEnum(){}return ChangeDetectionStrategyEnum.fromValue=function(e){return _enumExpression(a.Identifiers.ChangeDetectionStrategy,e)},ChangeDetectionStrategyEnum.OnPush=ChangeDetectionStrategyEnum.fromValue(r.ChangeDetectionStrategy.OnPush),ChangeDetectionStrategyEnum.Default=ChangeDetectionStrategyEnum.fromValue(r.ChangeDetectionStrategy.Default),ChangeDetectionStrategyEnum}();t.ChangeDetectionStrategyEnum=p;var d=function(){function ChangeDetectorStatusEnum(){}return ChangeDetectorStatusEnum.fromValue=function(e){return _enumExpression(a.Identifiers.ChangeDetectorStatus,e)},ChangeDetectorStatusEnum.CheckOnce=ChangeDetectorStatusEnum.fromValue(i.ChangeDetectorStatus.CheckOnce),ChangeDetectorStatusEnum.Checked=ChangeDetectorStatusEnum.fromValue(i.ChangeDetectorStatus.Checked),ChangeDetectorStatusEnum.CheckAlways=ChangeDetectorStatusEnum.fromValue(i.ChangeDetectorStatus.CheckAlways),ChangeDetectorStatusEnum.Detached=ChangeDetectorStatusEnum.fromValue(i.ChangeDetectorStatus.Detached),ChangeDetectorStatusEnum.Errored=ChangeDetectorStatusEnum.fromValue(i.ChangeDetectorStatus.Errored),ChangeDetectorStatusEnum.Destroyed=ChangeDetectorStatusEnum.fromValue(i.ChangeDetectorStatus.Destroyed),ChangeDetectorStatusEnum}();t.ChangeDetectorStatusEnum=d;var h=function(){function ViewConstructorVars(){}return ViewConstructorVars.viewUtils=l.variable("viewUtils"),ViewConstructorVars.parentInjector=l.variable("parentInjector"),ViewConstructorVars.declarationEl=l.variable("declarationEl"),ViewConstructorVars}();t.ViewConstructorVars=h;var f=function(){function ViewProperties(){}return ViewProperties.renderer=l.THIS_EXPR.prop("renderer"),ViewProperties.projectableNodes=l.THIS_EXPR.prop("projectableNodes"),ViewProperties.viewUtils=l.THIS_EXPR.prop("viewUtils"),ViewProperties}();t.ViewProperties=f;var m=function(){function EventHandlerVars(){}return EventHandlerVars.event=l.variable("$event"),EventHandlerVars}();t.EventHandlerVars=m;var y=function(){function InjectMethodVars(){}return InjectMethodVars.token=l.variable("token"),InjectMethodVars.requestNodeIndex=l.variable("requestNodeIndex"),InjectMethodVars.notFoundResult=l.variable("notFoundResult"),InjectMethodVars}();t.InjectMethodVars=y;var g=function(){function DetectChangesVars(){}return DetectChangesVars.throwOnChange=l.variable("throwOnChange"),DetectChangesVars.changes=l.variable("changes"),DetectChangesVars.changed=l.variable("changed"),DetectChangesVars.valUnwrapper=l.variable("valUnwrapper"),DetectChangesVars}();t.DetectChangesVars=g},99,function(e,t,n){var r=n(95);e.exports=function(e,t,n){if(r(e),void 0===t)return e;switch(n){case 1:return function(n){return e.call(t,n)};case 2:return function(n,r){return e.call(t,n,r)};case 3:return function(n,r,i){return e.call(t,n,r,i)}}return function(){return e.apply(t,arguments)}}},function(e,t,n){var r=n(8),i=n(462),o=n(288),s=n(300)("IE_PROTO"),a=function(){},l="prototype",c=function(){var e,t=n(451)("iframe"),r=o.length,i="<",s=">";for(t.style.display="none",n(452).appendChild(t),t.src="javascript:",e=t.contentWindow.document,e.open(),e.write(i+"script"+s+"document.F=Object"+i+"/script"+s),e.close(),c=e.F;r--;)delete c[l][o[r]];return c()};e.exports=Object.create||function(e,t){var n;return null!==e?(a[l]=r(e),n=new a,a[l]=null,n[s]=e):n=c(),void 0===t?n:i(n,t)}},function(e,t,n){var r=n(464),i=n(288);e.exports=Object.keys||function(e){return r(e,i)}},function(e,t){e.exports=function(e,t){return{enumerable:!(1&e),configurable:!(2&e),writable:!(4&e),value:t}}},function(e,t){var n=Math.ceil,r=Math.floor;e.exports=function(e){return isNaN(e=+e)?0:(e>0?r:n)(e)}},function(e,t,n){"use strict";function multicast(e){var t;return t="function"==typeof e?e:function(){return e},new r.ConnectableObservable(this,t)}var r=n(502);t.multicast=multicast},[1107,219],function(e,t){"use strict";var n=function(){function ElementSchemaRegistry(){}return ElementSchemaRegistry}();t.ElementSchemaRegistry=n},function(e,t,n){"use strict";function getPropertyInView(e,t,n){if(t===n)return e;for(var o=s.THIS_EXPR,a=t;a!==n&&i.isPresent(a.declarationElement.view);)a=a.declarationElement.view,o=o.prop("parent");if(a!==n)throw new r.BaseException("Internal error: Could not calculate a property in a parent view: "+e);if(e instanceof s.ReadPropExpr){var l=e;(n.fields.some(function(e){return e.name==l.name})||n.getters.some(function(e){return e.name==l.name}))&&(o=o.cast(n.classType))}return s.replaceVarInExpression(s.THIS_EXPR.name,o,e)}function injectFromViewParentInjector(e,t){var n=[a.createDiTokenExpression(e)];return t&&n.push(s.NULL_EXPR),s.THIS_EXPR.prop("parentInjector").callMethod("get",n)}function getViewFactoryName(e,t){return"viewFactory_"+e.type.name+t}function createFlatArray(e){for(var t=[],n=s.literalArr([]),r=0;r0&&(n=n.callMethod(s.BuiltinMethod.ConcatArray,[s.literalArr(t)]),t=[]),n=n.callMethod(s.BuiltinMethod.ConcatArray,[i])):t.push(i)}return t.length>0&&(n=n.callMethod(s.BuiltinMethod.ConcatArray,[s.literalArr(t)])),n}function createPureProxy(e,t,n,a){a.fields.push(new s.ClassField(n.name,null));var l=t0){var r=e.substring(0,n),i=e.substring(n+1).trim();t.set(r,i)}}),t},Headers.prototype.append=function(e,t){e=normalize(e);var n=this._headersMap.get(e),i=r.isListLikeIterable(n)?n:[];i.push(t),this._headersMap.set(e,i)},Headers.prototype.delete=function(e){this._headersMap.delete(normalize(e))},Headers.prototype.forEach=function(e){this._headersMap.forEach(e)},Headers.prototype.get=function(e){return r.ListWrapper.first(this._headersMap.get(normalize(e)))},Headers.prototype.has=function(e){return this._headersMap.has(normalize(e))},Headers.prototype.keys=function(){return r.MapWrapper.keys(this._headersMap)},Headers.prototype.set=function(e,t){var n=[];if(r.isListLikeIterable(t)){var i=t.join(",");n.push(i)}else n.push(t);this._headersMap.set(normalize(e),n)},Headers.prototype.values=function(){return r.MapWrapper.values(this._headersMap)},Headers.prototype.toJSON=function(){var e={};return this._headersMap.forEach(function(t,n){var i=[];r.iterateListLike(t,function(e){return i=r.ListWrapper.concat(i,e.split(","))}),e[normalize(n)]=i}),e},Headers.prototype.getAll=function(e){var t=this._headersMap.get(normalize(e));return r.isListLikeIterable(t)?t:[]},Headers.prototype.entries=function(){throw new i.BaseException('"entries" method is not implemented on Headers class')},Headers}();t.Headers=s},function(e,t){"use strict";var n=function(){function ConnectionBackend(){}return ConnectionBackend}();t.ConnectionBackend=n;var r=function(){function Connection(){}return Connection}();t.Connection=r;var i=function(){function XSRFStrategy(){}return XSRFStrategy}();t.XSRFStrategy=i},function(e,t,n){"use strict";var r=n(0);t.RenderDebugInfo=r.__core_private__.RenderDebugInfo,t.wtfInit=r.__core_private__.wtfInit,t.ReflectionCapabilities=r.__core_private__.ReflectionCapabilities,t.VIEW_ENCAPSULATION_VALUES=r.__core_private__.VIEW_ENCAPSULATION_VALUES,t.DebugDomRootRenderer=r.__core_private__.DebugDomRootRenderer,t.reflector=r.__core_private__.reflector,t.NoOpAnimationPlayer=r.__core_private__.NoOpAnimationPlayer,t.AnimationPlayer=r.__core_private__.AnimationPlayer,t.AnimationSequencePlayer=r.__core_private__.AnimationSequencePlayer,t.AnimationGroupPlayer=r.__core_private__.AnimationGroupPlayer,t.AnimationKeyframe=r.__core_private__.AnimationKeyframe,t.AnimationStyles=r.__core_private__.AnimationStyles,t.prepareFinalAnimationStyles=r.__core_private__.prepareFinalAnimationStyles,t.balanceAnimationKeyframes=r.__core_private__.balanceAnimationKeyframes,t.flattenStyles=r.__core_private__.flattenStyles,t.clearStyles=r.__core_private__.clearStyles,t.collectAndResolveStyles=r.__core_private__.collectAndResolveStyles},function(e,t,n){"use strict";var r=n(0);t.DOCUMENT=new r.OpaqueToken("DocumentToken")},function(e,t,n){"use strict";var r=this&&this.__extends||function(e,t){function __(){this.constructor=e}for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n]);e.prototype=null===t?Object.create(t):(__.prototype=t.prototype,new __)},i=n(0),o=n(33),s=n(16),a=n(62),l=n(55),c=function(){function ClientMessageBrokerFactory(){}return ClientMessageBrokerFactory}();t.ClientMessageBrokerFactory=c;var u=function(e){function ClientMessageBrokerFactory_(t,n){e.call(this),this._messageBus=t,this._serializer=n}return r(ClientMessageBrokerFactory_,e),ClientMessageBrokerFactory_.prototype.createMessageBroker=function(e,t){return void 0===t&&(t=!0),this._messageBus.initChannel(e,t),new d(this._messageBus,this._serializer,e)},ClientMessageBrokerFactory_.decorators=[{type:i.Injectable}],ClientMessageBrokerFactory_.ctorParameters=[{type:a.MessageBus},{type:l.Serializer}],ClientMessageBrokerFactory_}(c);t.ClientMessageBrokerFactory_=u;var p=function(){function ClientMessageBroker(){}return ClientMessageBroker}();t.ClientMessageBroker=p;var d=function(e){function ClientMessageBroker_(t,n,r){var i=this;e.call(this),this.channel=r,this._pending=new Map,this._sink=t.to(r),this._serializer=n;var o=t.from(r);o.subscribe({next:function(e){return i._handleMessage(e)}})}return r(ClientMessageBroker_,e),ClientMessageBroker_.prototype._generateMessageId=function(e){for(var t=s.stringify(s.DateWrapper.toMillis(s.DateWrapper.now())),n=0,r=e+t+s.stringify(n);s.isPresent(this._pending[r]);)r=""+e+t+n,n++;return r},ClientMessageBroker_.prototype.runOnService=function(e,t){var n=this,r=[];s.isPresent(e.args)&&e.args.forEach(function(e){null!=e.type?r.push(n._serializer.serialize(e.value,e.type)):r.push(e.value)});var i,o=null;if(null!=t){var a;i=new Promise(function(e,t){a={resolve:e,reject:t}}),o=this._generateMessageId(e.method),this._pending.set(o,a),i.catch(function(e){s.print(e),a.reject(e)}),i=i.then(function(e){return null==n._serializer?e:n._serializer.deserialize(e,t)})}else i=null;var l={method:e.method,args:r};return null!=o&&(l.id=o),this._sink.emit(l),i},ClientMessageBroker_.prototype._handleMessage=function(e){var t=new h(e);if(s.StringWrapper.equals(t.type,"result")||s.StringWrapper.equals(t.type,"error")){var n=t.id;this._pending.has(n)&&(s.StringWrapper.equals(t.type,"result")?this._pending.get(n).resolve(t.value):this._pending.get(n).reject(t.value),this._pending.delete(n))}},ClientMessageBroker_}(p);t.ClientMessageBroker_=d;var h=function(){function MessageData(e){this.type=o.StringMapWrapper.get(e,"type"),this.id=this._getValueIfPresent(e,"id"),this.value=this._getValueIfPresent(e,"value")}return MessageData.prototype._getValueIfPresent=function(e,t){return o.StringMapWrapper.contains(e,t)?o.StringMapWrapper.get(e,t):null},MessageData}(),f=function(){function FnArg(e,t){this.value=e,this.type=t}return FnArg}();t.FnArg=f;var m=function(){function UiArguments(e,t){this.method=e,this.args=t}return UiArguments}();t.UiArguments=m},function(e,t,n){"use strict";var r=n(0),i=function(){function RenderStore(){this._nextIndex=0,this._lookupById=new Map,this._lookupByObject=new Map}return RenderStore.prototype.allocateId=function(){return this._nextIndex++},RenderStore.prototype.store=function(e,t){this._lookupById.set(t,e),this._lookupByObject.set(e,t)},RenderStore.prototype.remove=function(e){var t=this._lookupByObject.get(e);this._lookupByObject.delete(e),this._lookupById.delete(t)},RenderStore.prototype.deserialize=function(e){return null==e?null:this._lookupById.has(e)?this._lookupById.get(e):null},RenderStore.prototype.serialize=function(e){return null==e?null:this._lookupByObject.get(e)},RenderStore.decorators=[{type:r.Injectable}],RenderStore.ctorParameters=[],RenderStore}();t.RenderStore=i},function(e,t,n){"use strict";var r=this&&this.__extends||function(e,t){function __(){this.constructor=e}for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n]);e.prototype=null===t?Object.create(t):(__.prototype=t.prototype,new __)},i=n(0),o=n(33),s=n(16),a=n(62),l=n(55),c=function(){function ServiceMessageBrokerFactory(){}return ServiceMessageBrokerFactory}();t.ServiceMessageBrokerFactory=c;var u=function(e){function ServiceMessageBrokerFactory_(t,n){e.call(this),this._messageBus=t,this._serializer=n}return r(ServiceMessageBrokerFactory_,e),ServiceMessageBrokerFactory_.prototype.createMessageBroker=function(e,t){return void 0===t&&(t=!0),this._messageBus.initChannel(e,t),new d(this._messageBus,this._serializer,e)},ServiceMessageBrokerFactory_.decorators=[{type:i.Injectable}],ServiceMessageBrokerFactory_.ctorParameters=[{type:a.MessageBus},{type:l.Serializer}],ServiceMessageBrokerFactory_}(c);t.ServiceMessageBrokerFactory_=u;var p=function(){function ServiceMessageBroker(){}return ServiceMessageBroker}();t.ServiceMessageBroker=p;var d=function(e){function ServiceMessageBroker_(t,n,r){var i=this;e.call(this),this._serializer=n,this.channel=r,this._methods=new o.Map,this._sink=t.to(r);var s=t.from(r);s.subscribe({next:function(e){return i._handleMessage(e)}})}return r(ServiceMessageBroker_,e),ServiceMessageBroker_.prototype.registerMethod=function(e,t,n,r){var i=this;this._methods.set(e,function(e){for(var a=e.args,l=null===t?0:t.length,c=o.ListWrapper.createFixedSize(l),u=0;u0?n[n.length-1]._routeConfig._loadedConfig:null}function nodeChildrenAsMap(e){return e?e.children.reduce(function(e,t){return e[t.value.outlet]=t,e},{}):{}}function getOutlet(e,t){var n=e._outlets[t.outlet];if(!n){var r=t.component.name;throw t.outlet===y.PRIMARY_OUTLET?new Error("Cannot find primary outlet to load '"+r+"'"):new Error("Cannot find the outlet "+t.outlet+" to load '"+r+"'")}return n}n(140),n(499),n(305),n(500),n(493);var r=n(0),i=n(20),o=n(309),s=n(141),a=n(623),l=n(624),c=n(625),u=n(626),p=n(627),d=n(628),h=n(187),f=n(129),m=n(91),y=n(63),g=n(73),v=n(74),b=function(){function NavigationStart(e,t){this.id=e,this.url=t}return NavigationStart.prototype.toString=function(){return"NavigationStart(id: "+this.id+", url: '"+this.url+"')"},NavigationStart}();t.NavigationStart=b;var _=function(){function NavigationEnd(e,t,n){this.id=e,this.url=t,this.urlAfterRedirects=n}return NavigationEnd.prototype.toString=function(){return"NavigationEnd(id: "+this.id+", url: '"+this.url+"', urlAfterRedirects: '"+this.urlAfterRedirects+"')"},NavigationEnd}();t.NavigationEnd=_;var w=function(){function NavigationCancel(e,t){this.id=e,this.url=t}return NavigationCancel.prototype.toString=function(){return"NavigationCancel(id: "+this.id+", url: '"+this.url+"')"},NavigationCancel}();t.NavigationCancel=w;var S=function(){function NavigationError(e,t,n){this.id=e,this.url=t,this.error=n}return NavigationError.prototype.toString=function(){return"NavigationError(id: "+this.id+", url: '"+this.url+"', error: "+this.error+")"},NavigationError}();t.NavigationError=S;var C=function(){function RoutesRecognized(e,t,n,r){this.id=e,this.url=t,this.urlAfterRedirects=n,this.state=r}return RoutesRecognized.prototype.toString=function(){return"RoutesRecognized(id: "+this.id+", url: '"+this.url+"', urlAfterRedirects: '"+this.urlAfterRedirects+"', state: "+this.state+")"},RoutesRecognized}();t.RoutesRecognized=C;var E=function(){function Router(e,t,n,r,o,s,a,l){this.rootComponentType=e,this.resolver=t,this.urlSerializer=n,this.outletMap=r,this.location=o,this.injector=s,this.navigationId=0,this.navigated=!1,this.resetConfig(l),this.routerEvents=new i.Subject,this.currentUrlTree=g.createEmptyUrlTree(),this.configLoader=new h.RouterConfigLoader(a),this.currentRouterState=m.createEmptyState(this.currentUrlTree,this.rootComponentType)}return Router.prototype.initialNavigation=function(){this.setUpLocationChangeListener(),this.navigateByUrl(this.location.path(!0))},Object.defineProperty(Router.prototype,"routerState",{get:function(){return this.currentRouterState},enumerable:!0,configurable:!0}),Object.defineProperty(Router.prototype,"url",{get:function(){return this.serializeUrl(this.currentUrlTree)},enumerable:!0,configurable:!0}),Object.defineProperty(Router.prototype,"events",{get:function(){return this.routerEvents},enumerable:!0,configurable:!0}),Router.prototype.resetConfig=function(e){l.validateConfig(e),this.config=e},Router.prototype.ngOnDestroy=function(){this.dispose()},Router.prototype.dispose=function(){this.locationSubscription.unsubscribe()},Router.prototype.createUrlTree=function(e,t){var n=void 0===t?{}:t,r=n.relativeTo,i=n.queryParams,o=n.fragment,s=n.preserveQueryParams,a=n.preserveFragment,l=r?r:this.routerState.root,c=s?this.currentUrlTree.queryParams:i,p=a?this.currentUrlTree.fragment:o;return u.createUrlTree(l,this.currentUrlTree,e,c,p)},Router.prototype.navigateByUrl=function(e,t){if(void 0===t&&(t={skipLocationChange:!1}),e instanceof g.UrlTree)return this.scheduleNavigation(e,t);var n=this.urlSerializer.parse(e);return this.scheduleNavigation(n,t)},Router.prototype.navigate=function(e,t){return void 0===t&&(t={skipLocationChange:!1}),this.scheduleNavigation(this.createUrlTree(e,t),t)},Router.prototype.serializeUrl=function(e){return this.urlSerializer.serialize(e)},Router.prototype.parseUrl=function(e){return this.urlSerializer.parse(e)},Router.prototype.isActive=function(e,t){if(e instanceof g.UrlTree)return g.containsTree(this.currentUrlTree,e,t);var n=this.urlSerializer.parse(e);return g.containsTree(this.currentUrlTree,n,t)},Router.prototype.scheduleNavigation=function(e,t){var n=this,r=++this.navigationId;return this.routerEvents.next(new b(r,this.serializeUrl(e))),Promise.resolve().then(function(i){return n.runNavigate(e,t.skipLocationChange,r)})},Router.prototype.setUpLocationChangeListener=function(){var e=this;this.locationSubscription=this.location.subscribe(Zone.current.wrap(function(t){var n=e.urlSerializer.parse(t.url);return e.currentUrlTree.toString()!==n.toString()?e.scheduleNavigation(n,t.pop):null}))},Router.prototype.runNavigate=function(e,t,n){var r=this;return n!==this.navigationId?(this.location.go(this.urlSerializer.serialize(this.currentUrlTree)),this.routerEvents.next(new w(n,this.serializeUrl(e))),Promise.resolve(!1)):new Promise(function(i,o){var l,u,h,f,m=r.currentRouterState,y=r.currentUrlTree;a.applyRedirects(r.injector,r.configLoader,e,r.config).mergeMap(function(e){return f=e,p.recognize(r.rootComponentType,r.config,f,r.serializeUrl(f))}).mergeMap(function(t){return r.routerEvents.next(new C(n,r.serializeUrl(e),r.serializeUrl(f),t)),d.resolve(r.resolver,t)}).map(function(e){return c.createRouterState(e,r.currentRouterState)}).map(function(e){l=e,h=new P(l.snapshot,r.currentRouterState.snapshot,r.injector),h.traverse(r.outletMap)}).mergeMap(function(e){return h.checkGuards()}).mergeMap(function(e){return e?h.resolveData().map(function(){return e}):s.of(e)}).forEach(function(i){if(!i||n!==r.navigationId)return r.routerEvents.next(new w(n,r.serializeUrl(e))),void(u=!1);if(r.currentUrlTree=f,r.currentRouterState=l,new x(l,m).activate(r.outletMap),!t){var o=r.urlSerializer.serialize(f);r.location.isCurrentPathEqualTo(o)?r.location.replaceState(o):r.location.go(o)}u=!0}).then(function(){r.navigated=!0,r.routerEvents.next(new _(n,r.serializeUrl(e),r.serializeUrl(f))),i(u)},function(t){r.currentRouterState=m,r.currentUrlTree=y,r.routerEvents.next(new S(n,r.serializeUrl(e),t)),o(t)})})},Router}();t.Router=E;var T=function(){function CanActivate(e){this.path=e}return Object.defineProperty(CanActivate.prototype,"route",{get:function(){return this.path[this.path.length-1]},enumerable:!0,configurable:!0}),CanActivate}(),R=function(){function CanDeactivate(e,t){this.component=e,this.route=t}return CanDeactivate}(),P=function(){function PreActivation(e,t,n){this.future=e,this.curr=t,this.injector=n,this.checks=[]}return PreActivation.prototype.traverse=function(e){var t=this.future._root,n=this.curr?this.curr._root:null;this.traverseChildRoutes(t,n,e,[t.value])},PreActivation.prototype.checkGuards=function(){var e=this;return 0===this.checks.length?s.of(!0):o.from(this.checks).map(function(t){if(t instanceof T)return v.andObservables(o.from([e.runCanActivate(t.route),e.runCanActivateChild(t.path)]));if(t instanceof R){var n=t;return e.runCanDeactivate(n.component,n.route)}throw new Error("Cannot be reached")}).mergeAll().every(function(e){return e===!0})},PreActivation.prototype.resolveData=function(){var e=this;return 0===this.checks.length?s.of(null):o.from(this.checks).mergeMap(function(t){return t instanceof T?e.runResolve(t.route):s.of(null)}).reduce(function(e,t){return e})},PreActivation.prototype.traverseChildRoutes=function(e,t,n,r){var i=this,o=nodeChildrenAsMap(t);e.children.forEach(function(e){i.traverseRoutes(e,o[e.value.outlet],n,r.concat([e.value])),delete o[e.value.outlet]}),v.forEach(o,function(e,t){return i.deactivateOutletAndItChildren(e,n._outlets[t])})},PreActivation.prototype.traverseRoutes=function(e,t,n,r){var i=e.value,o=t?t.value:null,s=n?n._outlets[e.value.outlet]:null;o&&i._routeConfig===o._routeConfig?(v.shallowEqual(i.params,o.params)||this.checks.push(new R(s.component,o),new T(r)),i.component?this.traverseChildRoutes(e,t,s?s.outletMap:null,r):this.traverseChildRoutes(e,t,n,r)):(o&&(o.component?this.deactivateOutletAndItChildren(o,s):this.deactivateOutletMap(n)),this.checks.push(new T(r)),i.component?this.traverseChildRoutes(e,null,s?s.outletMap:null,r):this.traverseChildRoutes(e,null,n,r))},PreActivation.prototype.deactivateOutletAndItChildren=function(e,t){t&&t.isActivated&&(this.deactivateOutletMap(t.outletMap),this.checks.push(new R(t.component,e)))},PreActivation.prototype.deactivateOutletMap=function(e){var t=this;v.forEach(e._outlets,function(e){e.isActivated&&t.deactivateOutletAndItChildren(e.activatedRoute.snapshot,e)})},PreActivation.prototype.runCanActivate=function(e){var t=this,n=e._routeConfig?e._routeConfig.canActivate:null;if(!n||0===n.length)return s.of(!0);var r=o.from(n).map(function(n){var r=t.getToken(n,e,t.future);return r.canActivate?v.wrapIntoObservable(r.canActivate(e,t.future)):v.wrapIntoObservable(r(e,t.future))});return v.andObservables(r)},PreActivation.prototype.runCanActivateChild=function(e){var t=this,n=e[e.length-1],r=e.slice(0,e.length-1).reverse().map(function(e){return t.extractCanActivateChild(e)}).filter(function(e){return null!==e});return v.andObservables(o.from(r).map(function(e){var r=o.from(e.guards).map(function(e){var r=t.getToken(e,e.node,t.future);return r.canActivateChild?v.wrapIntoObservable(r.canActivateChild(n,t.future)):v.wrapIntoObservable(r(n,t.future))});return v.andObservables(r)}))},PreActivation.prototype.extractCanActivateChild=function(e){var t=e._routeConfig?e._routeConfig.canActivateChild:null;return t&&0!==t.length?{node:e,guards:t}:null},PreActivation.prototype.runCanDeactivate=function(e,t){var n=this,r=t&&t._routeConfig?t._routeConfig.canDeactivate:null;return r&&0!==r.length?o.from(r).map(function(r){var i=n.getToken(r,t,n.curr);return i.canDeactivate?v.wrapIntoObservable(i.canDeactivate(e,t,n.curr)):v.wrapIntoObservable(i(e,t,n.curr))}).mergeAll().every(function(e){return e===!0}):s.of(!0)},PreActivation.prototype.runResolve=function(e){var t=e._resolve;return this.resolveNode(t.current,e).map(function(n){return t.resolvedData=n,e.data=v.merge(e.data,t.flattenedResolvedData),null})},PreActivation.prototype.resolveNode=function(e,t){var n=this;return v.waitForMap(e,function(e,r){var i=n.getToken(r,t,n.future);return i.resolve?v.wrapIntoObservable(i.resolve(t,n.future)):v.wrapIntoObservable(i(t,n.future))})},PreActivation.prototype.getToken=function(e,t,n){var r=closestLoadedConfig(n,t),i=r?r.injector:this.injector;return i.get(e)},PreActivation}(),x=function(){function ActivateRoutes(e,t){this.futureState=e,this.currState=t}return ActivateRoutes.prototype.activate=function(e){var t=this.futureState._root,n=this.currState?this.currState._root:null;m.advanceActivatedRoute(this.futureState.root),this.activateChildRoutes(t,n,e)},ActivateRoutes.prototype.activateChildRoutes=function(e,t,n){var r=this,i=nodeChildrenAsMap(t);e.children.forEach(function(e){r.activateRoutes(e,i[e.value.outlet],n),delete i[e.value.outlet]}),v.forEach(i,function(e,t){return r.deactivateOutletAndItChildren(n._outlets[t])})},ActivateRoutes.prototype.activateRoutes=function(e,t,n){ +var r=n(5),i=function(){function ParseLocation(e,t,n,r){this.file=e,this.offset=t,this.line=n,this.col=r}return ParseLocation.prototype.toString=function(){return r.isPresent(this.offset)?this.file.url+"@"+this.line+":"+this.col:this.file.url},ParseLocation}();t.ParseLocation=i;var o=function(){function ParseSourceFile(e,t){this.content=e,this.url=t}return ParseSourceFile}();t.ParseSourceFile=o;var s=function(){function ParseSourceSpan(e,t,n){void 0===n&&(n=null),this.start=e,this.end=t,this.details=n}return ParseSourceSpan.prototype.toString=function(){return this.start.file.content.substring(this.start.offset,this.end.offset)},ParseSourceSpan}();t.ParseSourceSpan=s,function(e){e[e.WARNING=0]="WARNING",e[e.FATAL=1]="FATAL"}(t.ParseErrorLevel||(t.ParseErrorLevel={}));var a=t.ParseErrorLevel,l=function(){function ParseError(e,t,n){void 0===n&&(n=a.FATAL),this.span=e,this.msg=t,this.level=n}return ParseError.prototype.toString=function(){var e=this.span.start.file.content,t=this.span.start.offset,n="",i="";if(r.isPresent(t)){t>e.length-1&&(t=e.length-1);for(var o=t,s=0,a=0;s<100&&t>0&&(t--,s++,"\n"!=e[t]||3!=++a););for(s=0,a=0;s<100&&o]"+e.substring(this.span.start.offset,o+1);n=' ("'+l+'")'}return this.span.details&&(i=", "+this.span.details),""+this.msg+n+": "+this.span.start+i},ParseError}();t.ParseError=l},function(e,t,n){"use strict";function templateVisitAll(e,t,n){void 0===n&&(n=null);var i=[];return t.forEach(function(t){var o=t.visit(e,n);r.isPresent(o)&&i.push(o)}),i}var r=n(5),i=function(){function TextAst(e,t,n){this.value=e,this.ngContentIndex=t,this.sourceSpan=n}return TextAst.prototype.visit=function(e,t){return e.visitText(this,t)},TextAst}();t.TextAst=i;var o=function(){function BoundTextAst(e,t,n){this.value=e,this.ngContentIndex=t,this.sourceSpan=n}return BoundTextAst.prototype.visit=function(e,t){return e.visitBoundText(this,t)},BoundTextAst}();t.BoundTextAst=o;var s=function(){function AttrAst(e,t,n){this.name=e,this.value=t,this.sourceSpan=n}return AttrAst.prototype.visit=function(e,t){return e.visitAttr(this,t)},AttrAst}();t.AttrAst=s;var a=function(){function BoundElementPropertyAst(e,t,n,r,i,o){this.name=e,this.type=t,this.securityContext=n,this.value=r,this.unit=i,this.sourceSpan=o}return BoundElementPropertyAst.prototype.visit=function(e,t){return e.visitElementProperty(this,t)},BoundElementPropertyAst}();t.BoundElementPropertyAst=a;var l=function(){function BoundEventAst(e,t,n,r){this.name=e,this.target=t,this.handler=n,this.sourceSpan=r}return BoundEventAst.prototype.visit=function(e,t){return e.visitEvent(this,t)},Object.defineProperty(BoundEventAst.prototype,"fullName",{get:function(){return r.isPresent(this.target)?this.target+":"+this.name:this.name},enumerable:!0,configurable:!0}),BoundEventAst}();t.BoundEventAst=l;var c=function(){function ReferenceAst(e,t,n){this.name=e,this.value=t,this.sourceSpan=n}return ReferenceAst.prototype.visit=function(e,t){return e.visitReference(this,t)},ReferenceAst}();t.ReferenceAst=c;var u=function(){function VariableAst(e,t,n){this.name=e,this.value=t,this.sourceSpan=n}return VariableAst.prototype.visit=function(e,t){return e.visitVariable(this,t)},VariableAst}();t.VariableAst=u;var p=function(){function ElementAst(e,t,n,r,i,o,s,a,l,c,u){this.name=e,this.attrs=t,this.inputs=n,this.outputs=r,this.references=i,this.directives=o,this.providers=s,this.hasViewContainer=a,this.children=l,this.ngContentIndex=c,this.sourceSpan=u}return ElementAst.prototype.visit=function(e,t){return e.visitElement(this,t)},ElementAst}();t.ElementAst=p;var d=function(){function EmbeddedTemplateAst(e,t,n,r,i,o,s,a,l,c){this.attrs=e,this.outputs=t,this.references=n,this.variables=r,this.directives=i,this.providers=o,this.hasViewContainer=s,this.children=a,this.ngContentIndex=l,this.sourceSpan=c}return EmbeddedTemplateAst.prototype.visit=function(e,t){return e.visitEmbeddedTemplate(this,t)},EmbeddedTemplateAst}();t.EmbeddedTemplateAst=d;var h=function(){function BoundDirectivePropertyAst(e,t,n,r){this.directiveName=e,this.templateName=t,this.value=n,this.sourceSpan=r}return BoundDirectivePropertyAst.prototype.visit=function(e,t){return e.visitDirectiveProperty(this,t)},BoundDirectivePropertyAst}();t.BoundDirectivePropertyAst=h;var f=function(){function DirectiveAst(e,t,n,r,i){this.directive=e,this.inputs=t,this.hostProperties=n,this.hostEvents=r,this.sourceSpan=i}return DirectiveAst.prototype.visit=function(e,t){return e.visitDirective(this,t)},DirectiveAst}();t.DirectiveAst=f;var m=function(){function ProviderAst(e,t,n,r,i,o,s){this.token=e,this.multiProvider=t,this.eager=n,this.providers=r,this.providerType=i,this.lifecycleHooks=o,this.sourceSpan=s}return ProviderAst.prototype.visit=function(e,t){return null},ProviderAst}();t.ProviderAst=m,function(e){e[e.PublicService=0]="PublicService",e[e.PrivateService=1]="PrivateService",e[e.Component=2]="Component",e[e.Directive=3]="Directive",e[e.Builtin=4]="Builtin"}(t.ProviderAstType||(t.ProviderAstType={}));var g=(t.ProviderAstType,function(){function NgContentAst(e,t,n){this.index=e,this.ngContentIndex=t,this.sourceSpan=n}return NgContentAst.prototype.visit=function(e,t){return e.visitNgContent(this,t)},NgContentAst}());t.NgContentAst=g,function(e){e[e.Property=0]="Property",e[e.Attribute=1]="Attribute",e[e.Class=2]="Class",e[e.Style=3]="Style",e[e.Animation=4]="Animation"}(t.PropertyBindingType||(t.PropertyBindingType={}));t.PropertyBindingType;t.templateVisitAll=templateVisitAll},function(e,t){"use strict";var n=function(){function MessageBus(){}return MessageBus}();t.MessageBus=n},function(e,t){"use strict";t.PRIMARY_OUTLET="primary"},function(e,t,n){var r=n(106),i=n(133),o=n(50),s=n(44),a=n(676);e.exports=function(e,t){var n=1==e,l=2==e,c=3==e,u=4==e,p=6==e,d=5==e||p,h=t||a;return function(t,a,f){for(var m,g,y=o(t),v=i(y),b=r(a,f,3),_=s(v.length),w=0,S=n?h(t,_):l?h(t,0):void 0;_>w;w++)if((d||w in v)&&(m=v[w],g=b(m,w,y),e))if(n)S[w]=g;else if(g)switch(e){case 3:return!0;case 5:return m;case 6:return w;case 2:S.push(m)}else if(u)return!1;return p?-1:c||u?u:S}}},function(e,t,n){var r=n(30),i=n(109);e.exports=n(35)?function(e,t,n){return r.f(e,t,i(1,n))}:function(e,t,n){return e[t]=n,e}},function(e,t,n){var r=n(472),i=n(2),o=n(199)("metadata"),s=o.store||(o.store=new(n(798))),a=function(e,t,n){var i=s.get(e);if(!i){if(!n)return;s.set(e,i=new r)}var o=i.get(t);if(!o){if(!n)return;i.set(t,o=new r)}return o},l=function(e,t,n){var r=a(t,n,!1);return void 0!==r&&r.has(e)},c=function(e,t,n){var r=a(t,n,!1);return void 0===r?void 0:r.get(e)},u=function(e,t,n,r){a(n,r,!0).set(e,t)},p=function(e,t){var n=a(e,t,!1),r=[];return n&&n.forEach(function(e,t){r.push(t)}),r},d=function(e){return void 0===e||"symbol"==typeof e?e:String(e)},h=function(e){i(i.S,"Reflect",e)};e.exports={store:s,map:a,has:l,get:c,set:u,keys:p,key:d,exp:h}},function(e,t,n){var r=n(48),i=n(50),o=n(300)("IE_PROTO"),s=Object.prototype;e.exports=Object.getPrototypeOf||function(e){return e=i(e),r(e,o)?e[o]:"function"==typeof e.constructor&&e instanceof e.constructor?e.constructor.prototype:e instanceof Object?s:null}},function(e,t,n){"use strict";var r=n(347),i=function(){function InterpolationConfig(e,t){this.start=e,this.end=t}return InterpolationConfig.fromArray=function(e){return e?(r.assertInterpolationSymbols("interpolation",e),new InterpolationConfig(e[0],e[1])):t.DEFAULT_INTERPOLATION_CONFIG},InterpolationConfig}();t.InterpolationConfig=i,t.DEFAULT_INTERPOLATION_CONFIG=new i("{{","}}")},[1107,263],function(e,t,n){"use strict";function controlPath(e,t){var n=r.ListWrapper.clone(t.path);return n.push(e),n}function setUpControl(e,t){o.isBlank(e)&&_throwError(t,"Cannot find control with"),o.isBlank(t.valueAccessor)&&_throwError(t,"No value accessor for form control with"),e.validator=s.Validators.compose([e.validator,t.validator]),e.asyncValidator=s.Validators.composeAsync([e.asyncValidator,t.asyncValidator]),t.valueAccessor.writeValue(e.value),t.valueAccessor.registerOnChange(function(n){t.viewToModelUpdate(n),e.markAsDirty(),e.setValue(n,{emitModelToViewChange:!1})}),e.registerOnChange(function(e,n){t.valueAccessor.writeValue(e),n&&t.viewToModelUpdate(e)}),t.valueAccessor.registerOnTouched(function(){return e.markAsTouched()})}function setUpFormContainer(e,t){o.isBlank(e)&&_throwError(t,"Cannot find control with"),e.validator=s.Validators.compose([e.validator,t.validator]),e.asyncValidator=s.Validators.composeAsync([e.asyncValidator,t.asyncValidator])}function _throwError(e,t){var n;throw n=e.path.length>1?"path: '"+e.path.join(" -> ")+"'":e.path[0]?"name: '"+e.path+"'":"unspecified name attribute",new i.BaseException(t+" "+n)}function composeValidators(e){return o.isPresent(e)?s.Validators.compose(e.map(c.normalizeValidator)):null}function composeAsyncValidators(e){return o.isPresent(e)?s.Validators.composeAsync(e.map(c.normalizeAsyncValidator)):null}function isPropertyUpdated(e,t){if(!r.StringMapWrapper.contains(e,"model"))return!1;var n=e.model;return!!n.isFirstChange()||!o.looseIdentical(t,n.currentValue)}function selectValueAccessor(e,t){if(o.isBlank(t))return null;var n,r,i;return t.forEach(function(t){o.hasConstructor(t,l.DefaultValueAccessor)?n=t:o.hasConstructor(t,a.CheckboxControlValueAccessor)||o.hasConstructor(t,u.NumberValueAccessor)||o.hasConstructor(t,d.SelectControlValueAccessor)||o.hasConstructor(t,h.SelectMultipleControlValueAccessor)||o.hasConstructor(t,p.RadioControlValueAccessor)?(o.isPresent(r)&&_throwError(e,"More than one built-in value accessor matches form control with"),r=t):(o.isPresent(i)&&_throwError(e,"More than one custom value accessor matches form control with"),i=t)}),o.isPresent(i)?i:o.isPresent(r)?r:o.isPresent(n)?n:(_throwError(e,"No valid value accessor for form control with"),null)}var r=n(47),i=n(88),o=n(32),s=n(54),a=n(169),l=n(170),c=n(587),u=n(266),p=n(172),d=n(173),h=n(174);t.controlPath=controlPath,t.setUpControl=setUpControl,t.setUpFormContainer=setUpFormContainer,t.composeValidators=composeValidators,t.composeAsyncValidators=composeAsyncValidators,t.isPropertyUpdated=isPropertyUpdated,t.selectValueAccessor=selectValueAccessor},function(e,t){"use strict";!function(e){e[e.Get=0]="Get",e[e.Post=1]="Post",e[e.Put=2]="Put",e[e.Delete=3]="Delete",e[e.Options=4]="Options",e[e.Head=5]="Head",e[e.Patch=6]="Patch"}(t.RequestMethod||(t.RequestMethod={}));t.RequestMethod;!function(e){e[e.Unsent=0]="Unsent",e[e.Open=1]="Open",e[e.HeadersReceived=2]="HeadersReceived",e[e.Loading=3]="Loading",e[e.Done=4]="Done",e[e.Cancelled=5]="Cancelled"}(t.ReadyState||(t.ReadyState={}));t.ReadyState;!function(e){e[e.Basic=0]="Basic",e[e.Cors=1]="Cors",e[e.Default=2]="Default",e[e.Error=3]="Error",e[e.Opaque=4]="Opaque"}(t.ResponseType||(t.ResponseType={}));t.ResponseType;!function(e){e[e.NONE=0]="NONE",e[e.JSON=1]="JSON",e[e.FORM=2]="FORM",e[e.FORM_DATA=3]="FORM_DATA",e[e.TEXT=4]="TEXT",e[e.BLOB=5]="BLOB",e[e.ARRAY_BUFFER=6]="ARRAY_BUFFER"}(t.ContentType||(t.ContentType={}));t.ContentType;!function(e){e[e.Text=0]="Text",e[e.Json=1]="Json",e[e.ArrayBuffer=2]="ArrayBuffer",e[e.Blob=3]="Blob"}(t.ResponseContentType||(t.ResponseContentType={}));t.ResponseContentType},[1106,418,419,419],function(e,t,n){"use strict";function createEmptyUrlTree(){return new o(new s([],{}),{},null)}function containsTree(e,t,n){return n?equalSegmentGroups(e.root,t.root):containsSegmentGroup(e.root,t.root)}function equalSegmentGroups(e,t){if(!equalPath(e.segments,t.segments))return!1;if(e.numberOfChildren!==t.numberOfChildren)return!1;for(var n in t.children){if(!e.children[n])return!1;if(!equalSegmentGroups(e.children[n],t.children[n]))return!1}return!0}function containsSegmentGroup(e,t){return containsSegmentGroupHelper(e,t,t.segments)}function containsSegmentGroupHelper(e,t,n){if(e.segments.length>n.length){var i=e.segments.slice(0,n.length);return!!equalPath(i,n)&&!t.hasChildren()}if(e.segments.length===n.length){if(!equalPath(e.segments,n))return!1;for(var o in t.children){if(!e.children[o])return!1;if(!containsSegmentGroup(e.children[o],t.children[o]))return!1}return!0}var i=n.slice(0,e.segments.length),s=n.slice(e.segments.length);return!!equalPath(e.segments,i)&&(!!e.children[r.PRIMARY_OUTLET]&&containsSegmentGroupHelper(e.children[r.PRIMARY_OUTLET],t,s))}function equalSegments(e,t){if(e.length!==t.length)return!1;for(var n=0;n0?n+"("+o.join("//")+")":""+n}if(e.hasChildren()&&!t){var s=mapChildrenIntoArray(e,function(t,n){return n===r.PRIMARY_OUTLET?[serializeSegment(e.children[r.PRIMARY_OUTLET],!1)]:[n+":"+serializeSegment(t,!1)]});return serializePaths(e)+"/("+s.join("//")+")"}return serializePaths(e)}function encode(e){return encodeURIComponent(e)}function decode(e){return decodeURIComponent(e)}function serializePath(e){return""+encode(e.path)+serializeParams(e.parameters)}function serializeParams(e){return pairs(e).map(function(e){return";"+encode(e.first)+"="+encode(e.second)}).join("")}function serializeQueryParams(e){var t=pairs(e).map(function(e){return encode(e.first)+"="+encode(e.second)});return t.length>0?"?"+t.join("&"):""}function pairs(e){var t=[];for(var n in e)e.hasOwnProperty(n)&&t.push(new u(n,e[n]));return t}function matchSegments(e){p.lastIndex=0;var t=e.match(p);return t?t[0]:""}function matchQueryParams(e){d.lastIndex=0;var t=e.match(p);return t?t[0]:""}function matchUrlQueryParamValue(e){h.lastIndex=0;var t=e.match(h);return t?t[0]:""}var r=n(63),i=n(74);t.createEmptyUrlTree=createEmptyUrlTree,t.containsTree=containsTree;var o=function(){function UrlTree(e,t,n){this.root=e,this.queryParams=t,this.fragment=n}return UrlTree.prototype.toString=function(){return(new c).serialize(this)},UrlTree}();t.UrlTree=o;var s=function(){function UrlSegmentGroup(e,t){var n=this;this.segments=e,this.children=t,this.parent=null,i.forEach(t,function(e,t){return e.parent=n})}return UrlSegmentGroup.prototype.hasChildren=function(){return this.numberOfChildren>0},Object.defineProperty(UrlSegmentGroup.prototype,"numberOfChildren",{get:function(){return Object.keys(this.children).length},enumerable:!0,configurable:!0}),UrlSegmentGroup.prototype.toString=function(){return serializePaths(this)},UrlSegmentGroup}();t.UrlSegmentGroup=s;var a=function(){function UrlSegment(e,t){this.path=e,this.parameters=t}return UrlSegment.prototype.toString=function(){return serializePath(this)},UrlSegment}();t.UrlSegment=a,t.equalSegments=equalSegments,t.equalPath=equalPath,t.mapChildrenIntoArray=mapChildrenIntoArray;var l=function(){function UrlSerializer(){}return UrlSerializer}();t.UrlSerializer=l;var c=function(){function DefaultUrlSerializer(){}return DefaultUrlSerializer.prototype.parse=function(e){var t=new f(e);return new o(t.parseRootSegment(),t.parseQueryParams(),t.parseFragment())},DefaultUrlSerializer.prototype.serialize=function(e){var t="/"+serializeSegment(e.root,!0),n=serializeQueryParams(e.queryParams),r=null!==e.fragment&&void 0!==e.fragment?"#"+encodeURIComponent(e.fragment):"";return""+t+n+r},DefaultUrlSerializer}();t.DefaultUrlSerializer=c,t.serializePaths=serializePaths,t.encode=encode,t.decode=decode,t.serializePath=serializePath;var u=function(){function Pair(e,t){this.first=e,this.second=t}return Pair}(),p=/^[^\/\(\)\?;=&#]+/,d=/^[^=\?&#]+/,h=/^[^\?&#]+/,f=function(){function UrlParser(e){this.url=e,this.remaining=e}return UrlParser.prototype.peekStartsWith=function(e){return this.remaining.startsWith(e)},UrlParser.prototype.capture=function(e){if(!this.remaining.startsWith(e))throw new Error('Expected "'+e+'".');this.remaining=this.remaining.substring(e.length)},UrlParser.prototype.parseRootSegment=function(){return this.remaining.startsWith("/")&&this.capture("/"),""===this.remaining||this.remaining.startsWith("?")||this.remaining.startsWith("#")?new s([],{}):new s([],this.parseChildren())},UrlParser.prototype.parseChildren=function(){if(0==this.remaining.length)return{};this.peekStartsWith("/")&&this.capture("/");var e=[];for(this.peekStartsWith("(")||e.push(this.parseSegments());this.peekStartsWith("/")&&!this.peekStartsWith("//")&&!this.peekStartsWith("/(");)this.capture("/"),e.push(this.parseSegments());var t={};this.peekStartsWith("/(")&&(this.capture("/"),t=this.parseParens(!0));var n={};return this.peekStartsWith("(")&&(n=this.parseParens(!1)),(e.length>0||Object.keys(t).length>0)&&(n[r.PRIMARY_OUTLET]=new s(e,t)),n},UrlParser.prototype.parseSegments=function(){var e=matchSegments(this.remaining);if(""===e&&this.peekStartsWith(";"))throw new Error("Empty path url segment cannot have parameters: '"+this.remaining+"'.");this.capture(e);var t={};return this.peekStartsWith(";")&&(t=this.parseMatrixParams()),new a(decode(e),t)},UrlParser.prototype.parseQueryParams=function(){var e={};if(this.peekStartsWith("?"))for(this.capture("?"),this.parseQueryParam(e);this.remaining.length>0&&this.peekStartsWith("&");)this.capture("&"),this.parseQueryParam(e);return e},UrlParser.prototype.parseFragment=function(){return this.peekStartsWith("#")?decode(this.remaining.substring(1)):null},UrlParser.prototype.parseMatrixParams=function(){for(var e={};this.remaining.length>0&&this.peekStartsWith(";");)this.capture(";"),this.parseParam(e);return e},UrlParser.prototype.parseParam=function(e){var t=matchSegments(this.remaining);if(t){this.capture(t);var n="true";if(this.peekStartsWith("=")){this.capture("=");var r=matchSegments(this.remaining);r&&(n=r,this.capture(n))}e[decode(t)]=decode(n)}},UrlParser.prototype.parseQueryParam=function(e){var t=matchQueryParams(this.remaining);if(t){this.capture(t);var n="";if(this.peekStartsWith("=")){this.capture("=");var r=matchUrlQueryParamValue(this.remaining);r&&(n=r,this.capture(n))}e[decode(t)]=decode(n)}},UrlParser.prototype.parseParens=function(e){var t={};for(this.capture("(");!this.peekStartsWith(")")&&this.remaining.length>0;){var n=matchSegments(this.remaining),i=this.remaining[n.length];if("/"!==i&&")"!==i&&";"!==i)throw new Error("Cannot parse url '"+this.url+"'");var o=void 0;n.indexOf(":")>-1?(o=n.substr(0,n.indexOf(":")),this.capture(o),this.capture(":")):e&&(o=r.PRIMARY_OUTLET);var a=this.parseChildren();t[o]=1===Object.keys(a).length?a[r.PRIMARY_OUTLET]:new s([],a),this.peekStartsWith("//")&&this.capture("//")}return this.capture(")"),t},UrlParser}()},function(e,t,n){"use strict";function shallowEqualArrays(e,t){if(e.length!==t.length)return!1;for(var n=0;n0?e[0]:null}function last(e){return e.length>0?e[e.length-1]:null}function and(e){return e.reduce(function(e,t){return e&&t},!0)}function merge(e,t){var n={};for(var r in e)e.hasOwnProperty(r)&&(n[r]=e[r]);for(var r in t)t.hasOwnProperty(r)&&(n[r]=t[r]);return n}function forEach(e,t){for(var n in e)e.hasOwnProperty(n)&&t(e[n],n)}function waitForMap(e,t){var n=[],r={};return forEach(e,function(e,i){i===s.PRIMARY_OUTLET&&n.push(t(i,e).map(function(e){return r[i]=e,e}))}),forEach(e,function(e,i){i!==s.PRIMARY_OUTLET&&n.push(t(i,e).map(function(e){return r[i]=e,e}))}),n.length>0?o.of.apply(void 0,n).concatAll().last().map(function(e){return r}):o.of(r)}function andObservables(e){return e.mergeAll().every(function(e){return e===!0})}function wrapIntoObservable(e){return e instanceof r.Observable?e:e instanceof Promise?i.fromPromise(e):o.of(e)}n(304),n(497);var r=n(1),i=n(211),o=n(141),s=n(63);t.shallowEqualArrays=shallowEqualArrays,t.shallowEqual=shallowEqual,t.flatten=flatten,t.first=first,t.last=last,t.and=and,t.merge=merge,t.forEach=forEach,t.waitForMap=waitForMap,t.andObservables=andObservables,t.wrapIntoObservable=wrapIntoObservable},function(e,t){e.exports=function(e){if(void 0==e)throw TypeError("Can't call method on "+e);return e}},function(e,t,n){var r=n(137)("meta"),i=n(15),o=n(48),s=n(30).f,a=0,l=Object.isExtensible||function(){return!0},c=!n(13)(function(){return l(Object.preventExtensions({}))}),u=function(e){s(e,r,{value:{i:"O"+ ++a,w:{}}})},p=function(e,t){if(!i(e))return"symbol"==typeof e?e:("string"==typeof e?"S":"P")+e;if(!o(e,r)){if(!l(e))return"F";if(!t)return"E";u(e)}return e[r].i},d=function(e,t){if(!o(e,r)){if(!l(e))return!0;if(!t)return!1;u(e)}return e[r].w},h=function(e){return c&&f.NEED&&l(e)&&!o(e,r)&&u(e),e},f=e.exports={KEY:r,NEED:!1,fastKey:p,getWeak:d,onFreeze:h}},function(e,t,n){var r=n(197),i=n(109),o=n(57),s=n(97),a=n(48),l=n(453),c=Object.getOwnPropertyDescriptor;t.f=n(35)?c:function(e,t){if(e=o(e),t=s(t,!0),l)try{return c(e,t)}catch(n){}if(a(e,t))return i(!r.f.call(e,t),e[t])}},function(e,t){e.exports=".vt-row {\n display: flex;\n flex-wrap: wrap;\n height: 100%;\n width: 100%;\n}\n\n.vt-card {\n display: inline-table;\n margin-left: 25px;\n margin-bottom: 10px;\n margin-top: 10px;\n}\n\n.stats-container {\n width: 100%;\n}\n\n.vt-padding{\n padding-left: 25px;\n padding-right: 25px;\n}\n\n>>> p-dialog .ui-dialog{\n position: fixed !important;\n top: 50% !important;\n left: 50% !important;\n transform: translate(-50%, -50%);\n margin: 0;\n width: auto !important;\n}\n\n.vt-popUpContainer{\n position: fixed;\n padding: 0;\n margin: 0;\n z-index: 0;\n bottom: 0;\n right: 0;\n top: 0;\n left: 0;\n min-height: 1000vh;\n min-width: 1000vw;\n height: 100%;\n width: 100%;\n background: rgba(0,0,0,0.6);\n}\n\n.vt-dark-link:link {\n text-decoration: none;\n color: black;\n}\n\n.vt-dark-link:visited {\n text-decoration: none;\n color: black;\n}\n\n.vt-dark-link:hover {\n text-decoration: none;\n color: black;\n}\n\n.vt-dark-link:active {\n text-decoration: none;\n color: black;\n}\n\n/* Toolbar */\n.vt-toolbar {\n width: 100%;\n text-align: center;\n}\n\n>>> p-accordiontab a {\n padding-left: 25px! important;\n}\n\n>>> .ui-accordion-content button {\n margin-top: 2px;\n}\n\n>>> p-menu .ui-menu {\n margin-top: 19px;\n display: inline-block;\n top: auto !important;\n left: auto !important;\n float: right;\n \n}\n\np-menu {\n display: inline-block;\n float: left;\n}\n\n.vt-toolbar .vt-menu {\n padding-top: 19px;\n float: left;\n}\n\n.vt-toolbar .vt-right-menu {\n padding-top: 19px;\n position: fixed;\n right: 25px;\n top: 19px;\n}\n\n.vt-card-toolbar {\n display: inline-block;\n width: 100%;\n}\n\n.vt-card-toolbar .vt-menu {\n float: left;\n}\n.vt-card-toolbar .vt-title {\n float: right;\n margin: 0;\n padding-left: 25px;\n}\n\nmd-list:hover {\n background: #E8E8E8\n}\n"},function(e,t,n){"use strict";var r=this&&this.__extends||function(e,t){function __(){this.constructor=e}for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n]);e.prototype=null===t?Object.create(t):(__.prototype=t.prototype,new __)},i=n(1),o=n(308),s=n(80),a=n(98),l=function(e){function ArrayObservable(t,n){e.call(this),this.array=t,this.scheduler=n,n||1!==t.length||(this._isScalar=!0,this.value=t[0])}return r(ArrayObservable,e),ArrayObservable.create=function(e,t){return new ArrayObservable(e,t)},ArrayObservable.of=function(){for(var e=[],t=0;t1?new ArrayObservable(e,n):1===r?new o.ScalarObservable(e[0],n):new s.EmptyObservable(n)},ArrayObservable.dispatch=function(e){var t=e.array,n=e.index,r=e.count,i=e.subscriber;return n>=r?void i.complete():(i.next(t[n]),void(i.isUnsubscribed||(e.index=n+1,this.schedule(e))))},ArrayObservable.prototype._subscribe=function(e){var t=0,n=this.array,r=n.length,i=this.scheduler;if(i)return i.schedule(ArrayObservable.dispatch,0,{array:n,index:t,count:r,subscriber:e});for(var o=0;o0?" { "+e.children.map(serializeNode).join(", ")+" } ":"";return""+e.value+t}function advanceActivatedRoute(e){e.snapshot?(a.shallowEqual(e.snapshot.queryParams,e._futureSnapshot.queryParams)||e.queryParams.next(e._futureSnapshot.queryParams),e.snapshot.fragment!==e._futureSnapshot.fragment&&e.fragment.next(e._futureSnapshot.fragment),a.shallowEqual(e.snapshot.params,e._futureSnapshot.params)||(e.params.next(e._futureSnapshot.params),e.data.next(e._futureSnapshot.data)),a.shallowEqualArrays(e.snapshot.url,e._futureSnapshot.url)||e.url.next(e._futureSnapshot.url),e.snapshot=e._futureSnapshot):(e.snapshot=e._futureSnapshot,e.data.next(e._futureSnapshot.data))}var r=this&&this.__extends||function(e,t){function __(){this.constructor=e}for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n]);e.prototype=null===t?Object.create(t):(__.prototype=t.prototype,new __)},i=n(207),o=n(63),s=n(73),a=n(74),l=n(281),c=function(e){function RouterState(t,n){e.call(this,t),this.snapshot=n,setRouterStateSnapshot(this,t)}return r(RouterState,e),Object.defineProperty(RouterState.prototype,"queryParams",{get:function(){return this.root.queryParams},enumerable:!0,configurable:!0}),Object.defineProperty(RouterState.prototype,"fragment",{get:function(){return this.root.fragment},enumerable:!0,configurable:!0}),RouterState.prototype.toString=function(){return this.snapshot.toString()},RouterState}(l.Tree);t.RouterState=c,t.createEmptyState=createEmptyState;var u=function(){function ActivatedRoute(e,t,n,r,i,o,s,a){this.url=e,this.params=t,this.queryParams=n,this.fragment=r,this.data=i,this.outlet=o,this.component=s,this._futureSnapshot=a}return Object.defineProperty(ActivatedRoute.prototype,"routeConfig",{get:function(){return this._futureSnapshot.routeConfig},enumerable:!0,configurable:!0}),Object.defineProperty(ActivatedRoute.prototype,"root",{get:function(){return this._routerState.root},enumerable:!0,configurable:!0}),Object.defineProperty(ActivatedRoute.prototype,"parent",{get:function(){return this._routerState.parent(this)},enumerable:!0,configurable:!0}),Object.defineProperty(ActivatedRoute.prototype,"firstChild",{get:function(){return this._routerState.firstChild(this)},enumerable:!0,configurable:!0}),Object.defineProperty(ActivatedRoute.prototype,"children",{get:function(){return this._routerState.children(this)},enumerable:!0,configurable:!0}),Object.defineProperty(ActivatedRoute.prototype,"pathFromRoot",{get:function(){return this._routerState.pathFromRoot(this)},enumerable:!0,configurable:!0}),ActivatedRoute.prototype.toString=function(){return this.snapshot?this.snapshot.toString():"Future("+this._futureSnapshot+")"},ActivatedRoute}();t.ActivatedRoute=u;var p=function(){function InheritedResolve(e,t){this.parent=e,this.current=t,this.resolvedData={}}return Object.defineProperty(InheritedResolve.prototype,"flattenedResolvedData",{get:function(){return this.parent?a.merge(this.parent.flattenedResolvedData,this.resolvedData):this.resolvedData},enumerable:!0,configurable:!0}),Object.defineProperty(InheritedResolve,"empty",{get:function(){return new InheritedResolve(null,{})},enumerable:!0,configurable:!0}),InheritedResolve}();t.InheritedResolve=p;var d=function(){function ActivatedRouteSnapshot(e,t,n,r,i,o,s,a,l,c,u){this.url=e,this.params=t,this.queryParams=n,this.fragment=r,this.data=i,this.outlet=o,this.component=s,this._routeConfig=a,this._urlSegment=l,this._lastPathIndex=c,this._resolve=u}return Object.defineProperty(ActivatedRouteSnapshot.prototype,"routeConfig",{get:function(){return this._routeConfig},enumerable:!0,configurable:!0}),Object.defineProperty(ActivatedRouteSnapshot.prototype,"root",{get:function(){return this._routerState.root},enumerable:!0,configurable:!0}),Object.defineProperty(ActivatedRouteSnapshot.prototype,"parent",{get:function(){return this._routerState.parent(this)},enumerable:!0,configurable:!0}),Object.defineProperty(ActivatedRouteSnapshot.prototype,"firstChild",{get:function(){return this._routerState.firstChild(this)},enumerable:!0,configurable:!0}),Object.defineProperty(ActivatedRouteSnapshot.prototype,"children",{get:function(){return this._routerState.children(this)},enumerable:!0,configurable:!0}),Object.defineProperty(ActivatedRouteSnapshot.prototype,"pathFromRoot",{get:function(){return this._routerState.pathFromRoot(this)},enumerable:!0,configurable:!0}),ActivatedRouteSnapshot.prototype.toString=function(){var e=this.url.map(function(e){return e.toString()}).join("/"),t=this._routeConfig?this._routeConfig.path:"";return"Route(url:'"+e+"', path:'"+t+"')"},ActivatedRouteSnapshot}();t.ActivatedRouteSnapshot=d;var h=function(e){function RouterStateSnapshot(t,n){e.call(this,n),this.url=t,setRouterStateSnapshot(this,n)}return r(RouterStateSnapshot,e),Object.defineProperty(RouterStateSnapshot.prototype,"queryParams",{get:function(){return this.root.queryParams},enumerable:!0,configurable:!0}),Object.defineProperty(RouterStateSnapshot.prototype,"fragment",{get:function(){return this.root.fragment},enumerable:!0,configurable:!0}),RouterStateSnapshot.prototype.toString=function(){return serializeNode(this._root)},RouterStateSnapshot}(l.Tree);t.RouterStateSnapshot=h,t.advanceActivatedRoute=advanceActivatedRoute},function(e,t,n){"use strict";var r=n(43),i=(n.n(r),n(0));n.n(i);n.d(t,"a",function(){return a});var o=this&&this.__decorate||function(e,t,n,r){var i,o=arguments.length,s=o<3?t:null===r?r=Object.getOwnPropertyDescriptor(t,n):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(e,t,n,r);else for(var a=e.length-1;a>=0;a--)(i=e[a])&&(s=(o<3?i(s):o>3?i(t,n,s):i(t,n))||s);return o>3&&s&&Object.defineProperty(t,n,s),s},s=this&&this.__metadata||function(e,t){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(e,t)},a=function(){function VtctlService(e){this.http=e,this.vtctlUrl="../api/vtctl/"}return VtctlService.prototype.sendPostRequest=function(e,t){var n=new r.Headers({"Content-Type":"application/json"}),i=new r.RequestOptions({headers:n});return this.http.post(e,JSON.stringify(t),i).map(function(e){return e.json()})},VtctlService.prototype.runCommand=function(e){return this.sendPostRequest(this.vtctlUrl,e)},VtctlService=o([n.i(i.Injectable)(),s("design:paramtypes",["function"==typeof(e="undefined"!=typeof r.Http&&r.Http)&&e||Object])],VtctlService);var e}()},function(e,t,n){"use strict";var r=n(192);n.d(t,"a",function(){return i});var i=function(){function DialogContent(e,t,n,r,i){void 0===e&&(e=""),void 0===t&&(t={}),void 0===n&&(n={}),void 0===r&&(r=void 0),void 0===i&&(i=""),this.nameId=e,this.flags=t,this.requiredFlags=n,this.prepareFunction=r,this.action=i}return DialogContent.prototype.getName=function(){return this.flags[this.nameId]?this.flags[this.nameId].getStrValue():""},DialogContent.prototype.setName=function(e){this.flags[this.nameId]&&this.flags[this.nameId].setValue(e)},DialogContent.prototype.getPostBody=function(e){void 0===e&&(e=void 0),e||(e=this.getFlags());var t=[],n=[];t.push(this.action);for(var r=0,i=e;r1?"path: '"+e.path.join(" -> ")+"'":e.path[0]?"name: '"+e.path+"'":"unspecified name",new i.BaseException(t+" "+n)}function composeValidators(e){return o.isPresent(e)?s.Validators.compose(e.map(c.normalizeValidator)):null}function composeAsyncValidators(e){return o.isPresent(e)?s.Validators.composeAsync(e.map(c.normalizeAsyncValidator)):null}function isPropertyUpdated(e,t){if(!r.StringMapWrapper.contains(e,"model"))return!1;var n=e.model;return!!n.isFirstChange()||!o.looseIdentical(t,n.currentValue)}function selectValueAccessor(e,t){if(o.isBlank(t))return null;var n,r,i;return t.forEach(function(t){o.hasConstructor(t,l.DefaultValueAccessor)?n=t:o.hasConstructor(t,a.CheckboxControlValueAccessor)||o.hasConstructor(t,u.NumberValueAccessor)||o.hasConstructor(t,d.SelectControlValueAccessor)||o.hasConstructor(t,h.SelectMultipleControlValueAccessor)||o.hasConstructor(t,p.RadioControlValueAccessor)?(o.isPresent(r)&&_throwError(e,"More than one built-in value accessor matches form control with"),r=t):(o.isPresent(i)&&_throwError(e,"More than one custom value accessor matches form control with"),i=t)}),o.isPresent(i)?i:o.isPresent(r)?r:o.isPresent(n)?n:(_throwError(e,"No valid value accessor for form control with"),null)}var r=n(34),i=n(83),o=n(7),s=n(58),a=n(144),l=n(145),c=n(526),u=n(227),p=n(146),d=n(147),h=n(228);t.controlPath=controlPath,t.setUpControl=setUpControl,t.setUpControlGroup=setUpControlGroup,t.composeValidators=composeValidators,t.composeAsyncValidators=composeAsyncValidators,t.isPropertyUpdated=isPropertyUpdated,t.selectValueAccessor=selectValueAccessor},function(e,t,n){"use strict";var r=n(0),i=n(18),o=n(28),s=function(){function CompilerConfig(e){var t=void 0===e?{}:e,n=t.renderTypes,i=void 0===n?new l:n,o=t.defaultEncapsulation,s=void 0===o?r.ViewEncapsulation.Emulated:o,a=t.genDebugInfo,c=t.logBindingUpdate,u=t.useJit,p=void 0===u||u,d=t.deprecatedPlatformDirectives,h=void 0===d?[]:d,f=t.deprecatedPlatformPipes,m=void 0===f?[]:f;this.renderTypes=i,this.defaultEncapsulation=s,this._genDebugInfo=a,this._logBindingUpdate=c,this.useJit=p,this.platformDirectives=h,this.platformPipes=m}return Object.defineProperty(CompilerConfig.prototype,"genDebugInfo",{get:function(){return void 0===this._genDebugInfo?r.isDevMode():this._genDebugInfo},enumerable:!0,configurable:!0}),Object.defineProperty(CompilerConfig.prototype,"logBindingUpdate",{get:function(){return void 0===this._logBindingUpdate?r.isDevMode():this._logBindingUpdate},enumerable:!0,configurable:!0}),CompilerConfig}();t.CompilerConfig=s;var a=function(){function RenderTypes(){}return Object.defineProperty(RenderTypes.prototype,"renderer",{get:function(){return i.unimplemented()},enumerable:!0,configurable:!0}),Object.defineProperty(RenderTypes.prototype,"renderText",{get:function(){return i.unimplemented()},enumerable:!0,configurable:!0}),Object.defineProperty(RenderTypes.prototype,"renderElement",{get:function(){return i.unimplemented()},enumerable:!0,configurable:!0}),Object.defineProperty(RenderTypes.prototype,"renderComment",{get:function(){return i.unimplemented()},enumerable:!0,configurable:!0}),Object.defineProperty(RenderTypes.prototype,"renderNode",{get:function(){return i.unimplemented()},enumerable:!0,configurable:!0}),Object.defineProperty(RenderTypes.prototype,"renderEvent",{get:function(){return i.unimplemented()},enumerable:!0,configurable:!0}),RenderTypes}();t.RenderTypes=a;var l=function(){function DefaultRenderTypes(){this.renderer=o.Identifiers.Renderer,this.renderText=null,this.renderElement=null,this.renderComment=null,this.renderNode=null,this.renderEvent=null}return DefaultRenderTypes}();t.DefaultRenderTypes=l},function(e,t){"use strict";function splitNsName(e){if(":"!=e[0])return[null,e];var t=e.indexOf(":",1);if(t==-1)throw new Error('Unsupported format "'+e+'" expecting ":namespace:name"');return[e.slice(1,t),e.slice(t+1)]}function getNsPrefix(e){return null===e?null:splitNsName(e)[0]}function mergeNsAndName(e,t){return e?":"+e+":"+t:t}!function(e){e[e.RAW_TEXT=0]="RAW_TEXT",e[e.ESCAPABLE_RAW_TEXT=1]="ESCAPABLE_RAW_TEXT",e[e.PARSABLE_DATA=2]="PARSABLE_DATA"}(t.TagContentType||(t.TagContentType={}));t.TagContentType;t.splitNsName=splitNsName,t.getNsPrefix=getNsPrefix,t.mergeNsAndName=mergeNsAndName,t.NAMED_ENTITIES={Aacute:"Á",aacute:"á",Acirc:"Â",acirc:"â",acute:"´",AElig:"Æ",aelig:"æ",Agrave:"À",agrave:"à",alefsym:"ℵ",Alpha:"Α",alpha:"α",amp:"&",and:"∧",ang:"∠",apos:"'",Aring:"Å",aring:"å",asymp:"≈",Atilde:"Ã",atilde:"ã",Auml:"Ä",auml:"ä",bdquo:"„",Beta:"Β",beta:"β",brvbar:"¦",bull:"•",cap:"∩",Ccedil:"Ç",ccedil:"ç",cedil:"¸",cent:"¢",Chi:"Χ",chi:"χ",circ:"ˆ",clubs:"♣",cong:"≅",copy:"©",crarr:"↵",cup:"∪",curren:"¤",dagger:"†",Dagger:"‡",darr:"↓",dArr:"⇓",deg:"°",Delta:"Δ",delta:"δ",diams:"♦",divide:"÷",Eacute:"É",eacute:"é",Ecirc:"Ê",ecirc:"ê",Egrave:"È",egrave:"è",empty:"∅",emsp:" ",ensp:" ",Epsilon:"Ε",epsilon:"ε",equiv:"≡",Eta:"Η",eta:"η",ETH:"Ð",eth:"ð",Euml:"Ë",euml:"ë",euro:"€",exist:"∃",fnof:"ƒ",forall:"∀",frac12:"½",frac14:"¼",frac34:"¾",frasl:"⁄",Gamma:"Γ",gamma:"γ",ge:"≥",gt:">",harr:"↔",hArr:"⇔",hearts:"♥",hellip:"…",Iacute:"Í",iacute:"í",Icirc:"Î",icirc:"î",iexcl:"¡",Igrave:"Ì",igrave:"ì",image:"ℑ",infin:"∞","int":"∫",Iota:"Ι",iota:"ι",iquest:"¿",isin:"∈",Iuml:"Ï",iuml:"ï",Kappa:"Κ",kappa:"κ",Lambda:"Λ",lambda:"λ",lang:"⟨",laquo:"«",larr:"←",lArr:"⇐",lceil:"⌈",ldquo:"“",le:"≤",lfloor:"⌊",lowast:"∗",loz:"◊",lrm:"‎",lsaquo:"‹",lsquo:"‘",lt:"<",macr:"¯",mdash:"—",micro:"µ",middot:"·",minus:"−",Mu:"Μ",mu:"μ",nabla:"∇",nbsp:" ",ndash:"–",ne:"≠",ni:"∋",not:"¬",notin:"∉",nsub:"⊄",Ntilde:"Ñ",ntilde:"ñ",Nu:"Ν",nu:"ν",Oacute:"Ó",oacute:"ó",Ocirc:"Ô",ocirc:"ô",OElig:"Œ",oelig:"œ",Ograve:"Ò",ograve:"ò",oline:"‾",Omega:"Ω",omega:"ω",Omicron:"Ο",omicron:"ο",oplus:"⊕",or:"∨",ordf:"ª",ordm:"º",Oslash:"Ø",oslash:"ø",Otilde:"Õ",otilde:"õ",otimes:"⊗",Ouml:"Ö",ouml:"ö",para:"¶",permil:"‰",perp:"⊥",Phi:"Φ",phi:"φ",Pi:"Π",pi:"π",piv:"ϖ",plusmn:"±",pound:"£",prime:"′",Prime:"″",prod:"∏",prop:"∝",Psi:"Ψ",psi:"ψ",quot:'"',radic:"√",rang:"⟩",raquo:"»",rarr:"→",rArr:"⇒",rceil:"⌉",rdquo:"”",real:"ℜ",reg:"®",rfloor:"⌋",Rho:"Ρ",rho:"ρ",rlm:"‏",rsaquo:"›",rsquo:"’",sbquo:"‚",Scaron:"Š",scaron:"š",sdot:"⋅",sect:"§",shy:"­",Sigma:"Σ",sigma:"σ",sigmaf:"ς",sim:"∼",spades:"♠",sub:"⊂",sube:"⊆",sum:"∑",sup:"⊃",sup1:"¹",sup2:"²",sup3:"³",supe:"⊇",szlig:"ß",Tau:"Τ",tau:"τ",there4:"∴",Theta:"Θ",theta:"θ",thetasym:"ϑ",thinsp:" ",THORN:"Þ",thorn:"þ",tilde:"˜",times:"×",trade:"™",Uacute:"Ú",uacute:"ú",uarr:"↑",uArr:"⇑",Ucirc:"Û",ucirc:"û",Ugrave:"Ù",ugrave:"ù",uml:"¨",upsih:"ϒ",Upsilon:"Υ",upsilon:"υ",Uuml:"Ü",uuml:"ü",weierp:"℘",Xi:"Ξ",xi:"ξ",Yacute:"Ý",yacute:"ý",yen:"¥",yuml:"ÿ",Yuml:"Ÿ",Zeta:"Ζ",zeta:"ζ",zwj:"‍",zwnj:"‌"}},function(e,t,n){"use strict";function createUrlResolverWithoutPackagePrefix(){return new s}function createOfflineCompileUrlResolver(){return new s(o)}function getUrlScheme(e){var t=_split(e);return t&&t[a.Scheme]||""}function _buildFromEncodedParts(e,t,n,r,o,s,a){var l=[];return i.isPresent(e)&&l.push(e+":"),i.isPresent(n)&&(l.push("//"),i.isPresent(t)&&l.push(t+"@"),l.push(n),i.isPresent(r)&&l.push(":"+r)),i.isPresent(o)&&l.push(o),i.isPresent(s)&&l.push("?"+s),i.isPresent(a)&&l.push("#"+a),l.join("")}function _split(e){return e.match(l)}function _removeDotSegments(e){if("/"==e)return"/";for(var t="/"==e[0]?"/":"",n="/"===e[e.length-1]?"/":"",r=e.split("/"),i=[],o=0,s=0;s0?i.pop():o++;break;default:i.push(a)}}if(""==t){for(;o-- >0;)i.unshift("..");0===i.length&&i.push(".")}return t+i.join("/")+n}function _joinAndCanonicalizePath(e){var t=e[a.Path];return t=i.isBlank(t)?"":_removeDotSegments(t),e[a.Path]=t,_buildFromEncodedParts(e[a.Scheme],e[a.UserInfo],e[a.Domain],e[a.Port],t,e[a.QueryData],e[a.Fragment])}function _resolveUrl(e,t){var n=_split(encodeURI(t)),r=_split(e);if(i.isPresent(n[a.Scheme]))return _joinAndCanonicalizePath(n);n[a.Scheme]=r[a.Scheme];for(var o=a.Scheme;o<=a.Port;o++)i.isBlank(n[o])&&(n[o]=r[o]);if("/"==n[a.Path][0])return _joinAndCanonicalizePath(n);var s=r[a.Path];i.isBlank(s)&&(s="/");var l=s.lastIndexOf("/");return s=s.substring(0,l+1)+n[a.Path],n[a.Path]=s,_joinAndCanonicalizePath(n)}var r=n(0),i=n(5),o="asset:";t.createUrlResolverWithoutPackagePrefix=createUrlResolverWithoutPackagePrefix,t.createOfflineCompileUrlResolver=createOfflineCompileUrlResolver,t.DEFAULT_PACKAGE_URL_PROVIDER={provide:r.PACKAGE_ROOT_URL,useValue:"/"};var s=function(){function UrlResolver(e){void 0===e&&(e=null),this._packagePrefix=e}return UrlResolver.prototype.resolve=function(e,t){var n=t;i.isPresent(e)&&e.length>0&&(n=_resolveUrl(e,n));var r=_split(n),s=this._packagePrefix;if(i.isPresent(s)&&i.isPresent(r)&&"package"==r[a.Scheme]){var l=r[a.Path];if(this._packagePrefix!==o)return s=i.StringWrapper.stripRight(s,"/"),l=i.StringWrapper.stripLeft(l,"/"),s+"/"+l;var c=l.split(/\//);n="asset:"+c[0]+"/lib/"+c.slice(1).join("/")}return n},UrlResolver.decorators=[{type:r.Injectable}],UrlResolver.ctorParameters=[{type:void 0,decorators:[{type:r.Inject,args:[r.PACKAGE_ROOT_URL]}]}],UrlResolver}();t.UrlResolver=s,t.getUrlScheme=getUrlScheme;var a,l=new RegExp("^(?:([^:/?#.]+):)?(?://(?:([^/?#]*)@)?([\\w\\d\\-\\u0100-\\uffff.%]*)(?::([0-9]+))?)?([^?#]+)?(?:\\?([^#]*))?(?:#(.*))?$");!function(e){e[e.Scheme=1]="Scheme",e[e.UserInfo=2]="UserInfo",e[e.Domain=3]="Domain",e[e.Port=4]="Port",e[e.Path=5]="Path",e[e.QueryData=6]="QueryData",e[e.Fragment=7]="Fragment"}(a||(a={}))},function(e,t,n){"use strict";function _enumExpression(e,t){if(s.isBlank(t))return l.NULL_EXPR;var n=s.resolveEnumToken(e.runtime,t);return l.importExpr(new o.CompileIdentifierMetadata({name:e.name+"."+n,moduleUrl:e.moduleUrl,runtime:t}))}var r=n(0),i=n(27),o=n(31),s=n(5),a=n(28),l=n(17),c=function(){function ViewTypeEnum(){}return ViewTypeEnum.fromValue=function(e){return _enumExpression(a.Identifiers.ViewType,e)},ViewTypeEnum.HOST=ViewTypeEnum.fromValue(i.ViewType.HOST),ViewTypeEnum.COMPONENT=ViewTypeEnum.fromValue(i.ViewType.COMPONENT),ViewTypeEnum.EMBEDDED=ViewTypeEnum.fromValue(i.ViewType.EMBEDDED),ViewTypeEnum}();t.ViewTypeEnum=c;var u=function(){function ViewEncapsulationEnum(){}return ViewEncapsulationEnum.fromValue=function(e){return _enumExpression(a.Identifiers.ViewEncapsulation,e)},ViewEncapsulationEnum.Emulated=ViewEncapsulationEnum.fromValue(r.ViewEncapsulation.Emulated),ViewEncapsulationEnum.Native=ViewEncapsulationEnum.fromValue(r.ViewEncapsulation.Native),ViewEncapsulationEnum.None=ViewEncapsulationEnum.fromValue(r.ViewEncapsulation.None),ViewEncapsulationEnum}();t.ViewEncapsulationEnum=u;var p=function(){function ChangeDetectionStrategyEnum(){}return ChangeDetectionStrategyEnum.fromValue=function(e){return _enumExpression(a.Identifiers.ChangeDetectionStrategy,e)},ChangeDetectionStrategyEnum.OnPush=ChangeDetectionStrategyEnum.fromValue(r.ChangeDetectionStrategy.OnPush),ChangeDetectionStrategyEnum.Default=ChangeDetectionStrategyEnum.fromValue(r.ChangeDetectionStrategy.Default),ChangeDetectionStrategyEnum}();t.ChangeDetectionStrategyEnum=p;var d=function(){function ChangeDetectorStatusEnum(){}return ChangeDetectorStatusEnum.fromValue=function(e){return _enumExpression(a.Identifiers.ChangeDetectorStatus,e)},ChangeDetectorStatusEnum.CheckOnce=ChangeDetectorStatusEnum.fromValue(i.ChangeDetectorStatus.CheckOnce),ChangeDetectorStatusEnum.Checked=ChangeDetectorStatusEnum.fromValue(i.ChangeDetectorStatus.Checked),ChangeDetectorStatusEnum.CheckAlways=ChangeDetectorStatusEnum.fromValue(i.ChangeDetectorStatus.CheckAlways),ChangeDetectorStatusEnum.Detached=ChangeDetectorStatusEnum.fromValue(i.ChangeDetectorStatus.Detached),ChangeDetectorStatusEnum.Errored=ChangeDetectorStatusEnum.fromValue(i.ChangeDetectorStatus.Errored),ChangeDetectorStatusEnum.Destroyed=ChangeDetectorStatusEnum.fromValue(i.ChangeDetectorStatus.Destroyed),ChangeDetectorStatusEnum}();t.ChangeDetectorStatusEnum=d;var h=function(){function ViewConstructorVars(){}return ViewConstructorVars.viewUtils=l.variable("viewUtils"),ViewConstructorVars.parentInjector=l.variable("parentInjector"),ViewConstructorVars.declarationEl=l.variable("declarationEl"),ViewConstructorVars}();t.ViewConstructorVars=h;var f=function(){function ViewProperties(){}return ViewProperties.renderer=l.THIS_EXPR.prop("renderer"),ViewProperties.projectableNodes=l.THIS_EXPR.prop("projectableNodes"),ViewProperties.viewUtils=l.THIS_EXPR.prop("viewUtils"),ViewProperties}();t.ViewProperties=f;var m=function(){function EventHandlerVars(){}return EventHandlerVars.event=l.variable("$event"),EventHandlerVars}();t.EventHandlerVars=m;var g=function(){function InjectMethodVars(){}return InjectMethodVars.token=l.variable("token"),InjectMethodVars.requestNodeIndex=l.variable("requestNodeIndex"),InjectMethodVars.notFoundResult=l.variable("notFoundResult"),InjectMethodVars}();t.InjectMethodVars=g;var y=function(){function DetectChangesVars(){}return DetectChangesVars.throwOnChange=l.variable("throwOnChange"),DetectChangesVars.changes=l.variable("changes"),DetectChangesVars.changed=l.variable("changed"),DetectChangesVars.valUnwrapper=l.variable("valUnwrapper"),DetectChangesVars}();t.DetectChangesVars=y},99,function(e,t,n){var r=n(95);e.exports=function(e,t,n){if(r(e),void 0===t)return e;switch(n){case 1:return function(n){return e.call(t,n)};case 2:return function(n,r){return e.call(t,n,r)};case 3:return function(n,r,i){return e.call(t,n,r,i)}}return function(){return e.apply(t,arguments)}}},function(e,t,n){var r=n(8),i=n(462),o=n(288),s=n(300)("IE_PROTO"),a=function(){},l="prototype",c=function(){var e,t=n(451)("iframe"),r=o.length,i="<",s=">";for(t.style.display="none",n(452).appendChild(t),t.src="javascript:",e=t.contentWindow.document,e.open(),e.write(i+"script"+s+"document.F=Object"+i+"/script"+s),e.close(),c=e.F;r--;)delete c[l][o[r]];return c()};e.exports=Object.create||function(e,t){var n;return null!==e?(a[l]=r(e),n=new a,a[l]=null,n[s]=e):n=c(),void 0===t?n:i(n,t)}},function(e,t,n){var r=n(464),i=n(288);e.exports=Object.keys||function(e){return r(e,i)}},function(e,t){e.exports=function(e,t){return{enumerable:!(1&e),configurable:!(2&e),writable:!(4&e),value:t}}},function(e,t){var n=Math.ceil,r=Math.floor;e.exports=function(e){return isNaN(e=+e)?0:(e>0?r:n)(e)}},function(e,t,n){"use strict";function multicast(e){var t;return t="function"==typeof e?e:function(){return e},new r.ConnectableObservable(this,t)}var r=n(502);t.multicast=multicast},[1107,219],function(e,t){"use strict";var n=function(){function ElementSchemaRegistry(){}return ElementSchemaRegistry}();t.ElementSchemaRegistry=n},function(e,t,n){"use strict";function getPropertyInView(e,t,n){if(t===n)return e;for(var o=s.THIS_EXPR,a=t;a!==n&&i.isPresent(a.declarationElement.view);)a=a.declarationElement.view,o=o.prop("parent");if(a!==n)throw new r.BaseException("Internal error: Could not calculate a property in a parent view: "+e);if(e instanceof s.ReadPropExpr){var l=e;(n.fields.some(function(e){return e.name==l.name})||n.getters.some(function(e){return e.name==l.name}))&&(o=o.cast(n.classType))}return s.replaceVarInExpression(s.THIS_EXPR.name,o,e)}function injectFromViewParentInjector(e,t){var n=[a.createDiTokenExpression(e)];return t&&n.push(s.NULL_EXPR),s.THIS_EXPR.prop("parentInjector").callMethod("get",n)}function getViewFactoryName(e,t){return"viewFactory_"+e.type.name+t}function createFlatArray(e){for(var t=[],n=s.literalArr([]),r=0;r0&&(n=n.callMethod(s.BuiltinMethod.ConcatArray,[s.literalArr(t)]),t=[]),n=n.callMethod(s.BuiltinMethod.ConcatArray,[i])):t.push(i)}return t.length>0&&(n=n.callMethod(s.BuiltinMethod.ConcatArray,[s.literalArr(t)])),n}function createPureProxy(e,t,n,a){a.fields.push(new s.ClassField(n.name,null));var l=t0){var r=e.substring(0,n),i=e.substring(n+1).trim();t.set(r,i)}}),t},Headers.prototype.append=function(e,t){e=normalize(e);var n=this._headersMap.get(e),i=r.isListLikeIterable(n)?n:[];i.push(t),this._headersMap.set(e,i)},Headers.prototype.delete=function(e){this._headersMap.delete(normalize(e))},Headers.prototype.forEach=function(e){this._headersMap.forEach(e)},Headers.prototype.get=function(e){return r.ListWrapper.first(this._headersMap.get(normalize(e)))},Headers.prototype.has=function(e){return this._headersMap.has(normalize(e))},Headers.prototype.keys=function(){return r.MapWrapper.keys(this._headersMap)},Headers.prototype.set=function(e,t){var n=[];if(r.isListLikeIterable(t)){var i=t.join(",");n.push(i)}else n.push(t);this._headersMap.set(normalize(e),n)},Headers.prototype.values=function(){return r.MapWrapper.values(this._headersMap)},Headers.prototype.toJSON=function(){var e={};return this._headersMap.forEach(function(t,n){var i=[];r.iterateListLike(t,function(e){return i=r.ListWrapper.concat(i,e.split(","))}),e[normalize(n)]=i}),e},Headers.prototype.getAll=function(e){var t=this._headersMap.get(normalize(e));return r.isListLikeIterable(t)?t:[]},Headers.prototype.entries=function(){throw new i.BaseException('"entries" method is not implemented on Headers class')},Headers}();t.Headers=s},function(e,t){"use strict";var n=function(){function ConnectionBackend(){}return ConnectionBackend}();t.ConnectionBackend=n;var r=function(){function Connection(){}return Connection}();t.Connection=r;var i=function(){function XSRFStrategy(){}return XSRFStrategy}();t.XSRFStrategy=i},function(e,t,n){"use strict";var r=n(0);t.RenderDebugInfo=r.__core_private__.RenderDebugInfo,t.wtfInit=r.__core_private__.wtfInit,t.ReflectionCapabilities=r.__core_private__.ReflectionCapabilities,t.VIEW_ENCAPSULATION_VALUES=r.__core_private__.VIEW_ENCAPSULATION_VALUES,t.DebugDomRootRenderer=r.__core_private__.DebugDomRootRenderer,t.reflector=r.__core_private__.reflector,t.NoOpAnimationPlayer=r.__core_private__.NoOpAnimationPlayer,t.AnimationPlayer=r.__core_private__.AnimationPlayer,t.AnimationSequencePlayer=r.__core_private__.AnimationSequencePlayer,t.AnimationGroupPlayer=r.__core_private__.AnimationGroupPlayer,t.AnimationKeyframe=r.__core_private__.AnimationKeyframe,t.AnimationStyles=r.__core_private__.AnimationStyles,t.prepareFinalAnimationStyles=r.__core_private__.prepareFinalAnimationStyles,t.balanceAnimationKeyframes=r.__core_private__.balanceAnimationKeyframes,t.flattenStyles=r.__core_private__.flattenStyles,t.clearStyles=r.__core_private__.clearStyles,t.collectAndResolveStyles=r.__core_private__.collectAndResolveStyles},function(e,t,n){"use strict";var r=n(0);t.DOCUMENT=new r.OpaqueToken("DocumentToken")},function(e,t,n){"use strict";var r=this&&this.__extends||function(e,t){function __(){this.constructor=e}for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n]);e.prototype=null===t?Object.create(t):(__.prototype=t.prototype,new __)},i=n(0),o=n(33),s=n(16),a=n(62),l=n(55),c=function(){function ClientMessageBrokerFactory(){}return ClientMessageBrokerFactory}();t.ClientMessageBrokerFactory=c;var u=function(e){function ClientMessageBrokerFactory_(t,n){e.call(this),this._messageBus=t,this._serializer=n}return r(ClientMessageBrokerFactory_,e),ClientMessageBrokerFactory_.prototype.createMessageBroker=function(e,t){return void 0===t&&(t=!0),this._messageBus.initChannel(e,t),new d(this._messageBus,this._serializer,e)},ClientMessageBrokerFactory_.decorators=[{type:i.Injectable}],ClientMessageBrokerFactory_.ctorParameters=[{type:a.MessageBus},{type:l.Serializer}],ClientMessageBrokerFactory_}(c);t.ClientMessageBrokerFactory_=u;var p=function(){function ClientMessageBroker(){}return ClientMessageBroker}();t.ClientMessageBroker=p;var d=function(e){function ClientMessageBroker_(t,n,r){var i=this;e.call(this),this.channel=r,this._pending=new Map,this._sink=t.to(r),this._serializer=n;var o=t.from(r);o.subscribe({next:function(e){return i._handleMessage(e)}})}return r(ClientMessageBroker_,e),ClientMessageBroker_.prototype._generateMessageId=function(e){for(var t=s.stringify(s.DateWrapper.toMillis(s.DateWrapper.now())),n=0,r=e+t+s.stringify(n);s.isPresent(this._pending[r]);)r=""+e+t+n,n++;return r},ClientMessageBroker_.prototype.runOnService=function(e,t){var n=this,r=[];s.isPresent(e.args)&&e.args.forEach(function(e){null!=e.type?r.push(n._serializer.serialize(e.value,e.type)):r.push(e.value)});var i,o=null;if(null!=t){var a;i=new Promise(function(e,t){a={resolve:e,reject:t}}),o=this._generateMessageId(e.method),this._pending.set(o,a),i.catch(function(e){s.print(e),a.reject(e)}),i=i.then(function(e){return null==n._serializer?e:n._serializer.deserialize(e,t)})}else i=null;var l={method:e.method,args:r};return null!=o&&(l.id=o),this._sink.emit(l),i},ClientMessageBroker_.prototype._handleMessage=function(e){var t=new h(e);if(s.StringWrapper.equals(t.type,"result")||s.StringWrapper.equals(t.type,"error")){var n=t.id;this._pending.has(n)&&(s.StringWrapper.equals(t.type,"result")?this._pending.get(n).resolve(t.value):this._pending.get(n).reject(t.value),this._pending.delete(n))}},ClientMessageBroker_}(p);t.ClientMessageBroker_=d;var h=function(){function MessageData(e){this.type=o.StringMapWrapper.get(e,"type"),this.id=this._getValueIfPresent(e,"id"),this.value=this._getValueIfPresent(e,"value")}return MessageData.prototype._getValueIfPresent=function(e,t){return o.StringMapWrapper.contains(e,t)?o.StringMapWrapper.get(e,t):null},MessageData}(),f=function(){function FnArg(e,t){this.value=e,this.type=t}return FnArg}();t.FnArg=f;var m=function(){function UiArguments(e,t){this.method=e,this.args=t}return UiArguments}();t.UiArguments=m},function(e,t,n){"use strict";var r=n(0),i=function(){function RenderStore(){this._nextIndex=0,this._lookupById=new Map,this._lookupByObject=new Map}return RenderStore.prototype.allocateId=function(){return this._nextIndex++},RenderStore.prototype.store=function(e,t){this._lookupById.set(t,e),this._lookupByObject.set(e,t)},RenderStore.prototype.remove=function(e){var t=this._lookupByObject.get(e);this._lookupByObject.delete(e),this._lookupById.delete(t)},RenderStore.prototype.deserialize=function(e){return null==e?null:this._lookupById.has(e)?this._lookupById.get(e):null},RenderStore.prototype.serialize=function(e){return null==e?null:this._lookupByObject.get(e)},RenderStore.decorators=[{type:r.Injectable}],RenderStore.ctorParameters=[],RenderStore}();t.RenderStore=i},function(e,t,n){"use strict";var r=this&&this.__extends||function(e,t){function __(){this.constructor=e}for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n]);e.prototype=null===t?Object.create(t):(__.prototype=t.prototype,new __)},i=n(0),o=n(33),s=n(16),a=n(62),l=n(55),c=function(){function ServiceMessageBrokerFactory(){}return ServiceMessageBrokerFactory}();t.ServiceMessageBrokerFactory=c;var u=function(e){function ServiceMessageBrokerFactory_(t,n){e.call(this),this._messageBus=t,this._serializer=n}return r(ServiceMessageBrokerFactory_,e),ServiceMessageBrokerFactory_.prototype.createMessageBroker=function(e,t){return void 0===t&&(t=!0),this._messageBus.initChannel(e,t),new d(this._messageBus,this._serializer,e)},ServiceMessageBrokerFactory_.decorators=[{type:i.Injectable}],ServiceMessageBrokerFactory_.ctorParameters=[{type:a.MessageBus},{type:l.Serializer}],ServiceMessageBrokerFactory_}(c);t.ServiceMessageBrokerFactory_=u;var p=function(){function ServiceMessageBroker(){}return ServiceMessageBroker}();t.ServiceMessageBroker=p;var d=function(e){function ServiceMessageBroker_(t,n,r){var i=this;e.call(this),this._serializer=n,this.channel=r,this._methods=new o.Map,this._sink=t.to(r);var s=t.from(r);s.subscribe({next:function(e){return i._handleMessage(e)}})}return r(ServiceMessageBroker_,e),ServiceMessageBroker_.prototype.registerMethod=function(e,t,n,r){var i=this;this._methods.set(e,function(e){for(var a=e.args,l=null===t?0:t.length,c=o.ListWrapper.createFixedSize(l),u=0;u0?n[n.length-1]._routeConfig._loadedConfig:null}function nodeChildrenAsMap(e){return e?e.children.reduce(function(e,t){return e[t.value.outlet]=t,e},{}):{}}function getOutlet(e,t){var n=e._outlets[t.outlet];if(!n){var r=t.component.name;throw t.outlet===g.PRIMARY_OUTLET?new Error("Cannot find primary outlet to load '"+r+"'"):new Error("Cannot find the outlet "+t.outlet+" to load '"+r+"'")}return n}n(140),n(499),n(305),n(500),n(493);var r=n(0),i=n(20),o=n(309),s=n(141),a=n(623),l=n(624),c=n(625),u=n(626),p=n(627),d=n(628),h=n(187),f=n(129),m=n(91),g=n(63),y=n(73),v=n(74),b=function(){function NavigationStart(e,t){this.id=e,this.url=t}return NavigationStart.prototype.toString=function(){return"NavigationStart(id: "+this.id+", url: '"+this.url+"')"},NavigationStart}();t.NavigationStart=b;var _=function(){function NavigationEnd(e,t,n){this.id=e,this.url=t,this.urlAfterRedirects=n}return NavigationEnd.prototype.toString=function(){return"NavigationEnd(id: "+this.id+", url: '"+this.url+"', urlAfterRedirects: '"+this.urlAfterRedirects+"')"},NavigationEnd}();t.NavigationEnd=_;var w=function(){function NavigationCancel(e,t){this.id=e,this.url=t}return NavigationCancel.prototype.toString=function(){return"NavigationCancel(id: "+this.id+", url: '"+this.url+"')"},NavigationCancel}();t.NavigationCancel=w;var S=function(){function NavigationError(e,t,n){this.id=e,this.url=t,this.error=n}return NavigationError.prototype.toString=function(){return"NavigationError(id: "+this.id+", url: '"+this.url+"', error: "+this.error+")"},NavigationError}();t.NavigationError=S;var C=function(){function RoutesRecognized(e,t,n,r){this.id=e,this.url=t,this.urlAfterRedirects=n,this.state=r}return RoutesRecognized.prototype.toString=function(){return"RoutesRecognized(id: "+this.id+", url: '"+this.url+"', urlAfterRedirects: '"+this.urlAfterRedirects+"', state: "+this.state+")"},RoutesRecognized}();t.RoutesRecognized=C;var E=function(){function Router(e,t,n,r,o,s,a,l){this.rootComponentType=e,this.resolver=t,this.urlSerializer=n,this.outletMap=r,this.location=o,this.injector=s,this.navigationId=0,this.navigated=!1,this.resetConfig(l),this.routerEvents=new i.Subject,this.currentUrlTree=y.createEmptyUrlTree(),this.configLoader=new h.RouterConfigLoader(a),this.currentRouterState=m.createEmptyState(this.currentUrlTree,this.rootComponentType)}return Router.prototype.initialNavigation=function(){this.setUpLocationChangeListener(),this.navigateByUrl(this.location.path(!0))},Object.defineProperty(Router.prototype,"routerState",{get:function(){return this.currentRouterState},enumerable:!0,configurable:!0}),Object.defineProperty(Router.prototype,"url",{get:function(){return this.serializeUrl(this.currentUrlTree)},enumerable:!0,configurable:!0}),Object.defineProperty(Router.prototype,"events",{get:function(){return this.routerEvents},enumerable:!0,configurable:!0}),Router.prototype.resetConfig=function(e){l.validateConfig(e),this.config=e},Router.prototype.ngOnDestroy=function(){this.dispose()},Router.prototype.dispose=function(){this.locationSubscription.unsubscribe()},Router.prototype.createUrlTree=function(e,t){var n=void 0===t?{}:t,r=n.relativeTo,i=n.queryParams,o=n.fragment,s=n.preserveQueryParams,a=n.preserveFragment,l=r?r:this.routerState.root,c=s?this.currentUrlTree.queryParams:i,p=a?this.currentUrlTree.fragment:o;return u.createUrlTree(l,this.currentUrlTree,e,c,p)},Router.prototype.navigateByUrl=function(e,t){if(void 0===t&&(t={skipLocationChange:!1}),e instanceof y.UrlTree)return this.scheduleNavigation(e,t);var n=this.urlSerializer.parse(e);return this.scheduleNavigation(n,t)},Router.prototype.navigate=function(e,t){return void 0===t&&(t={skipLocationChange:!1}),this.scheduleNavigation(this.createUrlTree(e,t),t)},Router.prototype.serializeUrl=function(e){return this.urlSerializer.serialize(e)},Router.prototype.parseUrl=function(e){return this.urlSerializer.parse(e)},Router.prototype.isActive=function(e,t){if(e instanceof y.UrlTree)return y.containsTree(this.currentUrlTree,e,t);var n=this.urlSerializer.parse(e);return y.containsTree(this.currentUrlTree,n,t)},Router.prototype.scheduleNavigation=function(e,t){var n=this,r=++this.navigationId;return this.routerEvents.next(new b(r,this.serializeUrl(e))),Promise.resolve().then(function(i){return n.runNavigate(e,t.skipLocationChange,r)})},Router.prototype.setUpLocationChangeListener=function(){var e=this;this.locationSubscription=this.location.subscribe(Zone.current.wrap(function(t){var n=e.urlSerializer.parse(t.url);return e.currentUrlTree.toString()!==n.toString()?e.scheduleNavigation(n,t.pop):null}))},Router.prototype.runNavigate=function(e,t,n){var r=this;return n!==this.navigationId?(this.location.go(this.urlSerializer.serialize(this.currentUrlTree)),this.routerEvents.next(new w(n,this.serializeUrl(e))),Promise.resolve(!1)):new Promise(function(i,o){var l,u,h,f,m=r.currentRouterState,g=r.currentUrlTree;a.applyRedirects(r.injector,r.configLoader,e,r.config).mergeMap(function(e){return f=e,p.recognize(r.rootComponentType,r.config,f,r.serializeUrl(f))}).mergeMap(function(t){return r.routerEvents.next(new C(n,r.serializeUrl(e),r.serializeUrl(f),t)),d.resolve(r.resolver,t)}).map(function(e){return c.createRouterState(e,r.currentRouterState)}).map(function(e){l=e,h=new P(l.snapshot,r.currentRouterState.snapshot,r.injector),h.traverse(r.outletMap)}).mergeMap(function(e){return h.checkGuards()}).mergeMap(function(e){return e?h.resolveData().map(function(){return e}):s.of(e)}).forEach(function(i){if(!i||n!==r.navigationId)return r.routerEvents.next(new w(n,r.serializeUrl(e))),void(u=!1);if(r.currentUrlTree=f,r.currentRouterState=l,new x(l,m).activate(r.outletMap),!t){var o=r.urlSerializer.serialize(f);r.location.isCurrentPathEqualTo(o)?r.location.replaceState(o):r.location.go(o)}u=!0}).then(function(){r.navigated=!0,r.routerEvents.next(new _(n,r.serializeUrl(e),r.serializeUrl(f))),i(u)},function(t){r.currentRouterState=m,r.currentUrlTree=g,r.routerEvents.next(new S(n,r.serializeUrl(e),t)),o(t)})})},Router}();t.Router=E;var T=function(){function CanActivate(e){this.path=e}return Object.defineProperty(CanActivate.prototype,"route",{get:function(){return this.path[this.path.length-1]},enumerable:!0,configurable:!0}),CanActivate}(),R=function(){function CanDeactivate(e,t){this.component=e,this.route=t}return CanDeactivate}(),P=function(){function PreActivation(e,t,n){this.future=e,this.curr=t,this.injector=n,this.checks=[]}return PreActivation.prototype.traverse=function(e){var t=this.future._root,n=this.curr?this.curr._root:null;this.traverseChildRoutes(t,n,e,[t.value])},PreActivation.prototype.checkGuards=function(){var e=this;return 0===this.checks.length?s.of(!0):o.from(this.checks).map(function(t){if(t instanceof T)return v.andObservables(o.from([e.runCanActivate(t.route),e.runCanActivateChild(t.path)]));if(t instanceof R){var n=t;return e.runCanDeactivate(n.component,n.route)}throw new Error("Cannot be reached")}).mergeAll().every(function(e){return e===!0})},PreActivation.prototype.resolveData=function(){var e=this;return 0===this.checks.length?s.of(null):o.from(this.checks).mergeMap(function(t){return t instanceof T?e.runResolve(t.route):s.of(null)}).reduce(function(e,t){return e})},PreActivation.prototype.traverseChildRoutes=function(e,t,n,r){var i=this,o=nodeChildrenAsMap(t);e.children.forEach(function(e){i.traverseRoutes(e,o[e.value.outlet],n,r.concat([e.value])),delete o[e.value.outlet]}),v.forEach(o,function(e,t){return i.deactivateOutletAndItChildren(e,n._outlets[t])})},PreActivation.prototype.traverseRoutes=function(e,t,n,r){var i=e.value,o=t?t.value:null,s=n?n._outlets[e.value.outlet]:null;o&&i._routeConfig===o._routeConfig?(v.shallowEqual(i.params,o.params)||this.checks.push(new R(s.component,o),new T(r)),i.component?this.traverseChildRoutes(e,t,s?s.outletMap:null,r):this.traverseChildRoutes(e,t,n,r)):(o&&(o.component?this.deactivateOutletAndItChildren(o,s):this.deactivateOutletMap(n)),this.checks.push(new T(r)),i.component?this.traverseChildRoutes(e,null,s?s.outletMap:null,r):this.traverseChildRoutes(e,null,n,r))},PreActivation.prototype.deactivateOutletAndItChildren=function(e,t){t&&t.isActivated&&(this.deactivateOutletMap(t.outletMap),this.checks.push(new R(t.component,e)))},PreActivation.prototype.deactivateOutletMap=function(e){var t=this;v.forEach(e._outlets,function(e){e.isActivated&&t.deactivateOutletAndItChildren(e.activatedRoute.snapshot,e)})},PreActivation.prototype.runCanActivate=function(e){var t=this,n=e._routeConfig?e._routeConfig.canActivate:null;if(!n||0===n.length)return s.of(!0);var r=o.from(n).map(function(n){var r=t.getToken(n,e,t.future);return r.canActivate?v.wrapIntoObservable(r.canActivate(e,t.future)):v.wrapIntoObservable(r(e,t.future))});return v.andObservables(r)},PreActivation.prototype.runCanActivateChild=function(e){var t=this,n=e[e.length-1],r=e.slice(0,e.length-1).reverse().map(function(e){return t.extractCanActivateChild(e)}).filter(function(e){return null!==e});return v.andObservables(o.from(r).map(function(e){var r=o.from(e.guards).map(function(e){var r=t.getToken(e,e.node,t.future);return r.canActivateChild?v.wrapIntoObservable(r.canActivateChild(n,t.future)):v.wrapIntoObservable(r(n,t.future))});return v.andObservables(r)}))},PreActivation.prototype.extractCanActivateChild=function(e){var t=e._routeConfig?e._routeConfig.canActivateChild:null;return t&&0!==t.length?{node:e,guards:t}:null},PreActivation.prototype.runCanDeactivate=function(e,t){var n=this,r=t&&t._routeConfig?t._routeConfig.canDeactivate:null;return r&&0!==r.length?o.from(r).map(function(r){var i=n.getToken(r,t,n.curr);return i.canDeactivate?v.wrapIntoObservable(i.canDeactivate(e,t,n.curr)):v.wrapIntoObservable(i(e,t,n.curr))}).mergeAll().every(function(e){return e===!0}):s.of(!0)},PreActivation.prototype.runResolve=function(e){var t=e._resolve;return this.resolveNode(t.current,e).map(function(n){return t.resolvedData=n,e.data=v.merge(e.data,t.flattenedResolvedData),null})},PreActivation.prototype.resolveNode=function(e,t){var n=this;return v.waitForMap(e,function(e,r){var i=n.getToken(r,t,n.future);return i.resolve?v.wrapIntoObservable(i.resolve(t,n.future)):v.wrapIntoObservable(i(t,n.future))})},PreActivation.prototype.getToken=function(e,t,n){var r=closestLoadedConfig(n,t),i=r?r.injector:this.injector;return i.get(e)},PreActivation}(),x=function(){function ActivateRoutes(e,t){this.futureState=e,this.currState=t}return ActivateRoutes.prototype.activate=function(e){var t=this.futureState._root,n=this.currState?this.currState._root:null;m.advanceActivatedRoute(this.futureState.root),this.activateChildRoutes(t,n,e)},ActivateRoutes.prototype.activateChildRoutes=function(e,t,n){var r=this,i=nodeChildrenAsMap(t);e.children.forEach(function(e){r.activateRoutes(e,i[e.value.outlet],n),delete i[e.value.outlet]}),v.forEach(i,function(e,t){return r.deactivateOutletAndItChildren(n._outlets[t])})},ActivateRoutes.prototype.activateRoutes=function(e,t,n){ var r=e.value,i=t?t.value:null;if(r===i)if(m.advanceActivatedRoute(r),r.component){var o=getOutlet(n,e.value);this.activateChildRoutes(e,t,o.outletMap)}else this.activateChildRoutes(e,t,n);else{if(i)if(i.component){var o=getOutlet(n,e.value);this.deactivateOutletAndItChildren(o)}else this.deactivateOutletMap(n);if(r.component){m.advanceActivatedRoute(r);var o=getOutlet(n,e.value),s=new f.RouterOutletMap;this.placeComponentIntoOutlet(s,r,o),this.activateChildRoutes(e,null,s)}else m.advanceActivatedRoute(r),this.activateChildRoutes(e,null,n)}},ActivateRoutes.prototype.placeComponentIntoOutlet=function(e,t,n){var i=[{provide:m.ActivatedRoute,useValue:t},{provide:f.RouterOutletMap,useValue:e}],o=closestLoadedConfig(this.futureState.snapshot,t.snapshot),s=null,a=null;o&&(s=o.factoryResolver,a=o.injector,i.push({provide:r.ComponentFactoryResolver,useValue:s})),n.activate(t,s,a,r.ReflectiveInjector.resolve(i),e)},ActivateRoutes.prototype.deactivateOutletAndItChildren=function(e){e&&e.isActivated&&(this.deactivateOutletMap(e.outletMap),e.deactivate())},ActivateRoutes.prototype.deactivateOutletMap=function(e){var t=this;v.forEach(e._outlets,function(e){return t.deactivateOutletAndItChildren(e)})},ActivateRoutes}()},function(e,t){"use strict";var n=function(){function RouterOutletMap(){this._outlets={}}return RouterOutletMap.prototype.registerOutlet=function(e,t){this._outlets[e]=t},RouterOutletMap.prototype.removeOutlet=function(e){this._outlets[e]=void 0},RouterOutletMap}();t.RouterOutletMap=n},function(e,t,n){"use strict";var r=n(43),i=(n.n(r),n(0));n.n(i);n.d(t,"a",function(){return a});var o=this&&this.__decorate||function(e,t,n,r){var i,o=arguments.length,s=o<3?t:null===r?r=Object.getOwnPropertyDescriptor(t,n):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(e,t,n,r);else for(var a=e.length-1;a>=0;a--)(i=e[a])&&(s=(o<3?i(s):o>3?i(t,n,s):i(t,n))||s);return o>3&&s&&Object.defineProperty(t,n,s),s},s=this&&this.__metadata||function(e,t){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(e,t)},a=function(){function FeaturesService(e){var t=this;this.http=e,this.activeReparents=!1,this.showStatus=!1,this.showTopologyCRUD=!1,this.showWorkflows=!1,this.workflows=[],this.featuresUrl="../api/features",this.getFeatures().subscribe(function(e){t.activeReparents=e.activeReparents,t.showStatus=e.showStatus,t.showTopologyCRUD=e.showTopologyCRUD,t.showWorkflows=e.showWorkflows,t.workflows=e.workflows})}return FeaturesService.prototype.getFeatures=function(){return this.http.get(this.featuresUrl).map(function(e){return e.json()})},FeaturesService=o([n.i(i.Injectable)(),s("design:paramtypes",["function"==typeof(e="undefined"!=typeof r.Http&&r.Http)&&e||Object])],FeaturesService);var e}()},function(e,t,n){"use strict";var r=n(43),i=(n.n(r),n(0)),o=(n.n(i),n(484)),s=(n.n(o),n(283)),a=n(644),l=n(284);n.d(t,"a",function(){return p});var c=this&&this.__decorate||function(e,t,n,r){var i,o=arguments.length,s=o<3?t:null===r?r=Object.getOwnPropertyDescriptor(t,n):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(e,t,n,r);else for(var a=e.length-1;a>=0;a--)(i=e[a])&&(s=(o<3?i(s):o>3?i(t,n,s):i(t,n))||s);return o>3&&s&&Object.defineProperty(t,n,s),s},u=this&&this.__metadata||function(e,t){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(e,t)},p=function(){function KeyspaceService(e,t){this.http=e,this.shardService=t,this.keyspacesUrl="../api/keyspaces/",this.srvKeyspaceUrl="../api/srv_keyspace/local/"}return KeyspaceService.prototype.getShards=function(e){return this.shardService.getShards(e)},KeyspaceService.prototype.getKeyspaceNames=function(){return this.http.get(this.keyspacesUrl).map(function(e){return e.json()})},KeyspaceService.prototype.getSrvKeyspaces=function(){return this.http.get(this.srvKeyspaceUrl).map(function(e){return e.json()})},KeyspaceService.prototype.SrvKeyspaceAndNamesObservable=function(){var e=this.getKeyspaceNames(),t=this.getSrvKeyspaces();return e.combineLatest(t)},KeyspaceService.prototype.getKeyspaceShardingData=function(e){return this.http.get(this.keyspacesUrl+e).map(function(e){return e.json()})},KeyspaceService.prototype.getShardsAndShardingData=function(e){var t=this.getShards(e),n=this.getKeyspaceShardingData(e);return t.combineLatest(n)},KeyspaceService.prototype.buildKeyspace=function(e,t){return this.getShardsAndShardingData(e).map(function(n){var r=n[0],i=n[1],o=new a.a(e);return t.forEach(function(e){return o.addServingShard(e)}),r.forEach(function(e){o.contains(e)||o.addNonservingShard(e)}),o.shardingColumnName=i.sharding_column_name||"",o.shardingColumnType=i.sharding_column_type||"",o})},KeyspaceService.prototype.getServingShards=function(e,t){if(t&&t[e]){var n=t[e].partitions;if(void 0===n)return[];for(var r=0;r=0;a--)(i=e[a])&&(s=(o<3?i(s):o>3?i(t,n,s):i(t,n))||s);return o>3&&s&&Object.defineProperty(t,n,s),s},i=this&&this.__metadata||function(e,t){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(e,t)},o=n(0),s=n(9),a=n(3),l=function(){function Button(e,t){this.el=e,this.domHandler=t,this.iconPos="left"}return Button.prototype.ngAfterViewInit=function(){if(this.domHandler.addMultipleClasses(this.el.nativeElement,this.getStyleClass()),this.icon){var e=document.createElement("span"),t="right"==this.iconPos?"ui-button-icon-right":"ui-button-icon-left";e.className=t+" ui-c fa fa-fw "+this.icon,this.el.nativeElement.appendChild(e)}var n=document.createElement("span");n.className="ui-button-text ui-c",n.appendChild(document.createTextNode(this.label||"ui-button")),this.el.nativeElement.appendChild(n),this.initialized=!0},Button.prototype.onMouseenter=function(e){this.hover=!0},Button.prototype.onMouseleave=function(e){this.hover=!1,this.active=!1},Button.prototype.onMouseDown=function(e){this.active=!0},Button.prototype.onMouseUp=function(e){this.active=!1},Button.prototype.onFocus=function(e){this.focus=!0},Button.prototype.onBlur=function(e){this.focus=!1},Button.prototype.isDisabled=function(){return this.el.nativeElement.disabled},Button.prototype.getStyleClass=function(){var e="ui-button ui-widget ui-state-default ui-corner-all";return e+=this.icon?null!=this.label&&void 0!=this.label?"left"==this.iconPos?" ui-button-text-icon-left":" ui-button-text-icon-right":" ui-button-icon-only":" ui-button-text-only"},Object.defineProperty(Button.prototype,"label",{get:function(){return this._label},set:function(e){this._label=e,this.initialized&&(this.domHandler.findSingle(this.el.nativeElement,".ui-button-text").textContent=this._label)},enumerable:!0,configurable:!0}),Button.prototype.ngOnDestroy=function(){for(;this.el.nativeElement.hasChildNodes();)this.el.nativeElement.removeChild(this.el.nativeElement.lastChild);this.initialized=!1},r([o.Input(),i("design:type",String)],Button.prototype,"icon",void 0),r([o.Input(),i("design:type",String)],Button.prototype,"iconPos",void 0),r([o.HostListener("mouseenter",["$event"]),i("design:type",Function),i("design:paramtypes",[Object]),i("design:returntype",void 0)],Button.prototype,"onMouseenter",null),r([o.HostListener("mouseleave",["$event"]),i("design:type",Function),i("design:paramtypes",[Object]),i("design:returntype",void 0)],Button.prototype,"onMouseleave",null),r([o.HostListener("mousedown",["$event"]),i("design:type",Function),i("design:paramtypes",[Object]),i("design:returntype",void 0)],Button.prototype,"onMouseDown",null),r([o.HostListener("mouseup",["$event"]),i("design:type",Function),i("design:paramtypes",[Object]),i("design:returntype",void 0)],Button.prototype,"onMouseUp",null),r([o.HostListener("focus",["$event"]),i("design:type",Function),i("design:paramtypes",[Object]),i("design:returntype",void 0)],Button.prototype,"onFocus",null),r([o.HostListener("blur",["$event"]),i("design:type",Function),i("design:paramtypes",[Object]),i("design:returntype",void 0)],Button.prototype,"onBlur",null),r([o.Input(),i("design:type",String)],Button.prototype,"label",null),Button=r([o.Directive({selector:"[pButton]",host:{"[class.ui-state-hover]":"hover&&!isDisabled()","[class.ui-state-focus]":"focus","[class.ui-state-active]":"active","[class.ui-state-disabled]":"isDisabled()"},providers:[s.DomHandler]}),i("design:paramtypes",[o.ElementRef,s.DomHandler])],Button)}();t.Button=l;var c=function(){function ButtonModule(){}return ButtonModule=r([o.NgModule({imports:[a.CommonModule],exports:[l],declarations:[l]}),i("design:paramtypes",[])],ButtonModule)}();t.ButtonModule=c},function(e,t,n){"use strict";var r=n(1),i=n(505);r.Observable.prototype.map=i.map},function(e,t,n){"use strict";var r=n(79);t.of=r.ArrayObservable.of},function(e,t,n){"use strict";var r=n(51),i=r.root.Symbol;if("function"==typeof i)i.iterator?t.$$iterator=i.iterator:"function"==typeof i.for&&(t.$$iterator=i.for("iterator"));else if(r.root.Set&&"function"==typeof(new r.root.Set)["@@iterator"])t.$$iterator="@@iterator";else if(r.root.Map)for(var o=Object.getOwnPropertyNames(r.root.Map.prototype),s=0;s=this.length?i.$EOF:o.StringWrapper.charCodeAt(this.input,this.index)},_Scanner.prototype.scanToken=function(){for(var e=this.input,t=this.length,n=this.peek,r=this.index;n<=i.$SPACE;){if(++r>=t){n=i.$EOF;break}n=o.StringWrapper.charCodeAt(e,r)}if(this.peek=n,this.index=r,r>=t)return null;if(isIdentifierStart(n))return this.scanIdentifier();if(i.isDigit(n))return this.scanNumber(r);var s=r;switch(n){case i.$PERIOD:return this.advance(),i.isDigit(this.peek)?this.scanNumber(s):newCharacterToken(s,i.$PERIOD);case i.$LPAREN:case i.$RPAREN:case i.$LBRACE:case i.$RBRACE:case i.$LBRACKET:case i.$RBRACKET:case i.$COMMA:case i.$COLON:case i.$SEMICOLON:return this.scanCharacter(s,n);case i.$SQ:case i.$DQ:return this.scanString();case i.$HASH:case i.$PLUS:case i.$MINUS:case i.$STAR:case i.$SLASH:case i.$PERCENT:case i.$CARET:return this.scanOperator(s,o.StringWrapper.fromCharCode(n));case i.$QUESTION:return this.scanComplexOperator(s,"?",i.$PERIOD,".");case i.$LT:case i.$GT:return this.scanComplexOperator(s,o.StringWrapper.fromCharCode(n),i.$EQ,"=");case i.$BANG:case i.$EQ:return this.scanComplexOperator(s,o.StringWrapper.fromCharCode(n),i.$EQ,"=",i.$EQ,"=");case i.$AMPERSAND:return this.scanComplexOperator(s,"&",i.$AMPERSAND,"&");case i.$BAR:return this.scanComplexOperator(s,"|",i.$BAR,"|");case i.$NBSP:for(;i.isWhitespace(this.peek);)this.advance();return this.scanToken()}return this.advance(),this.error("Unexpected character ["+o.StringWrapper.fromCharCode(n)+"]",0)},_Scanner.prototype.scanCharacter=function(e,t){return this.advance(),newCharacterToken(e,t)},_Scanner.prototype.scanOperator=function(e,t){return this.advance(),newOperatorToken(e,t)},_Scanner.prototype.scanComplexOperator=function(e,t,n,r,i,s){this.advance();var a=t;return this.peek==n&&(this.advance(),a+=r),o.isPresent(i)&&this.peek==i&&(this.advance(),a+=s),newOperatorToken(e,a)},_Scanner.prototype.scanIdentifier=function(){var e=this.index;for(this.advance();isIdentifierPart(this.peek);)this.advance();var t=this.input.substring(e,this.index);return a.indexOf(t)>-1?newKeywordToken(e,t):newIdentifierToken(e,t)},_Scanner.prototype.scanNumber=function(e){var t=this.index===e;for(this.advance();;){if(i.isDigit(this.peek));else if(this.peek==i.$PERIOD)t=!1;else{if(!isExponentStart(this.peek))break;if(this.advance(),isExponentSign(this.peek)&&this.advance(),!i.isDigit(this.peek))return this.error("Invalid exponent",-1);t=!1}this.advance()}var n=this.input.substring(e,this.index),r=t?o.NumberWrapper.parseIntAutoRadix(n):o.NumberWrapper.parseFloat(n);return newNumberToken(e,r)},_Scanner.prototype.scanString=function(){var e=this.index,t=this.peek;this.advance();for(var n,r=this.index,s=this.input;this.peek!=t;)if(this.peek==i.$BACKSLASH){null==n&&(n=new o.StringJoiner),n.add(s.substring(r,this.index)),this.advance();var a;if(this.peek==i.$u){var l=s.substring(this.index+1,this.index+5);try{a=o.NumberWrapper.parseInt(l,16)}catch(c){return this.error("Invalid unicode escape [\\u"+l+"]",0)}for(var u=0;u<5;u++)this.advance()}else a=unescape(this.peek),this.advance();n.add(o.StringWrapper.fromCharCode(a)),r=this.index}else{if(this.peek==i.$EOF)return this.error("Unterminated quote",0);this.advance()}var p=s.substring(r,this.index);this.advance();var d=p;return null!=n&&(n.add(p),d=n.toString()),newStringToken(e,d)},_Scanner.prototype.error=function(e,t){var n=this.index+t;return newErrorToken(n,"Lexer Error: "+e+" at column "+n+" in expression ["+this.input+"]")},_Scanner}();t.isIdentifier=isIdentifier,t.isQuote=isQuote},function(e,t,n){"use strict";function _createInterpolateRegExp(e){var t=o.escapeRegExp(e.start)+"([\\s\\S]*?)"+o.escapeRegExp(e.end);return new RegExp(t,"g")}var r=n(0),i=n(233),o=n(5),s=n(68),a=n(236),l=n(151),c=function(){function SplitInterpolation(e,t){this.strings=e,this.expressions=t}return SplitInterpolation}();t.SplitInterpolation=c;var u=function(){function TemplateBindingParseResult(e,t,n){this.templateBindings=e,this.warnings=t,this.errors=n}return TemplateBindingParseResult}();t.TemplateBindingParseResult=u;var p=function(){function Parser(e){this._lexer=e,this.errors=[]}return Parser.prototype.parseAction=function(e,t,n){void 0===n&&(n=s.DEFAULT_INTERPOLATION_CONFIG),this._checkNoInterpolation(e,t,n);var r=this._lexer.tokenize(this._stripComments(e)),i=new d(e,t,r,(!0),this.errors).parseChain();return new a.ASTWithSource(i,e,t,this.errors)},Parser.prototype.parseBinding=function(e,t,n){void 0===n&&(n=s.DEFAULT_INTERPOLATION_CONFIG);var r=this._parseBindingAst(e,t,n);return new a.ASTWithSource(r,e,t,this.errors)},Parser.prototype.parseSimpleBinding=function(e,t,n){void 0===n&&(n=s.DEFAULT_INTERPOLATION_CONFIG);var r=this._parseBindingAst(e,t,n);return h.check(r)||this._reportError("Host binding expression can only contain field access and constants",e,t),new a.ASTWithSource(r,e,t,this.errors)},Parser.prototype._reportError=function(e,t,n,r){this.errors.push(new a.ParserError(e,t,n,r))},Parser.prototype._parseBindingAst=function(e,t,n){var r=this._parseQuote(e,t);if(o.isPresent(r))return r;this._checkNoInterpolation(e,t,n);var i=this._lexer.tokenize(this._stripComments(e));return new d(e,t,i,(!1),this.errors).parseChain()},Parser.prototype._parseQuote=function(e,t){if(o.isBlank(e))return null;var n=e.indexOf(":");if(n==-1)return null;var r=e.substring(0,n).trim();if(!l.isIdentifier(r))return null;var i=e.substring(n+1);return new a.Quote(new a.ParseSpan(0,e.length),r,i,t)},Parser.prototype.parseTemplateBindings=function(e,t){var n=this._lexer.tokenize(e);return new d(e,t,n,(!1),this.errors).parseTemplateBindings()},Parser.prototype.parseInterpolation=function(e,t,n){void 0===n&&(n=s.DEFAULT_INTERPOLATION_CONFIG);var r=this.splitInterpolation(e,t,n);if(null==r)return null;for(var i=[],l=0;l0?l.push(p):this._reportError("Blank expressions are not allowed in interpolated strings",e,"at column "+this._findInterpolationErrorColumn(i,u,n)+" in",t)}return new c(a,l)},Parser.prototype.wrapLiteralPrimitive=function(e,t){return new a.ASTWithSource(new a.LiteralPrimitive(new a.ParseSpan(0,o.isBlank(e)?0:e.length),e),e,t,this.errors)},Parser.prototype._stripComments=function(e){var t=this._commentStart(e);return o.isPresent(t)?e.substring(0,t).trim():e},Parser.prototype._commentStart=function(e){for(var t=null,n=0;n1&&this._reportError("Got interpolation ("+n.start+n.end+") where expression was expected",e,"at column "+this._findInterpolationErrorColumn(i,1,n)+" in",t)},Parser.prototype._findInterpolationErrorColumn=function(e,t,n){for(var r="",i=0;i":case"<=":case">=":this.advance();var n=this.parseAdditive();e=new a.Binary(this.span(e.span.start),t,e,n);continue}break}return e},_ParseAST.prototype.parseAdditive=function(){for(var e=this.parseMultiplicative();this.next.type==l.TokenType.Operator;){var t=this.next.strValue;switch(t){case"+":case"-":this.advance();var n=this.parseMultiplicative();e=new a.Binary(this.span(e.span.start),t,e,n);continue}break}return e},_ParseAST.prototype.parseMultiplicative=function(){for(var e=this.parsePrefix();this.next.type==l.TokenType.Operator;){var t=this.next.strValue;switch(t){case"*":case"%":case"/":this.advance();var n=this.parsePrefix();e=new a.Binary(this.span(e.span.start),t,e,n);continue}break}return e},_ParseAST.prototype.parsePrefix=function(){if(this.next.type==l.TokenType.Operator){var e=this.inputIndex,t=this.next.strValue,n=void 0;switch(t){case"+":return this.advance(),this.parsePrefix();case"-":return this.advance(),n=this.parsePrefix(),new a.Binary(this.span(e),t,new a.LiteralPrimitive(new a.ParseSpan(e,e),0),n);case"!":return this.advance(),n=this.parsePrefix(),new a.PrefixNot(this.span(e),n)}}return this.parseCallChain()},_ParseAST.prototype.parseCallChain=function(){for(var e=this.parsePrimary();;)if(this.optionalCharacter(i.$PERIOD))e=this.parseAccessMemberOrMethodCall(e,!1);else if(this.optionalOperator("?."))e=this.parseAccessMemberOrMethodCall(e,!0);else if(this.optionalCharacter(i.$LBRACKET)){this.rbracketsExpected++;var t=this.parsePipe();if(this.rbracketsExpected--,this.expectCharacter(i.$RBRACKET),this.optionalOperator("=")){var n=this.parseConditional();e=new a.KeyedWrite(this.span(e.span.start),e,t,n)}else e=new a.KeyedRead(this.span(e.span.start),e,t)}else{if(!this.optionalCharacter(i.$LPAREN))return e;this.rparensExpected++;var r=this.parseCallArguments();this.rparensExpected--,this.expectCharacter(i.$RPAREN),e=new a.FunctionCall(this.span(e.span.start),e,r)}},_ParseAST.prototype.parsePrimary=function(){var e=this.inputIndex;if(this.optionalCharacter(i.$LPAREN)){this.rparensExpected++;var t=this.parsePipe();return this.rparensExpected--,this.expectCharacter(i.$RPAREN),t}if(this.next.isKeywordNull())return this.advance(),new a.LiteralPrimitive(this.span(e),null);if(this.next.isKeywordUndefined())return this.advance(),new a.LiteralPrimitive(this.span(e),(void 0));if(this.next.isKeywordTrue())return this.advance(),new a.LiteralPrimitive(this.span(e),(!0));if(this.next.isKeywordFalse())return this.advance(),new a.LiteralPrimitive(this.span(e),(!1));if(this.next.isKeywordThis())return this.advance(),new a.ImplicitReceiver(this.span(e));if(this.optionalCharacter(i.$LBRACKET)){this.rbracketsExpected++;var n=this.parseExpressionList(i.$RBRACKET);return this.rbracketsExpected--,this.expectCharacter(i.$RBRACKET),new a.LiteralArray(this.span(e),n)}if(this.next.isCharacter(i.$LBRACE))return this.parseLiteralMap();if(this.next.isIdentifier())return this.parseAccessMemberOrMethodCall(new a.ImplicitReceiver(this.span(e)),!1);if(this.next.isNumber()){var r=this.next.toNumber();return this.advance(),new a.LiteralPrimitive(this.span(e),r)}if(this.next.isString()){var o=this.next.toString();return this.advance(),new a.LiteralPrimitive(this.span(e),o)}return this.index>=this.tokens.length?(this.error("Unexpected end of expression: "+this.input),new a.EmptyExpr(this.span(e))):(this.error("Unexpected token "+this.next),new a.EmptyExpr(this.span(e)))},_ParseAST.prototype.parseExpressionList=function(e){var t=[];if(!this.next.isCharacter(e))do t.push(this.parsePipe());while(this.optionalCharacter(i.$COMMA));return t},_ParseAST.prototype.parseLiteralMap=function(){var e=[],t=[],n=this.inputIndex;if(this.expectCharacter(i.$LBRACE),!this.optionalCharacter(i.$RBRACE)){this.rbracesExpected++;do{var r=this.expectIdentifierOrKeywordOrString();e.push(r),this.expectCharacter(i.$COLON),t.push(this.parsePipe())}while(this.optionalCharacter(i.$COMMA));this.rbracesExpected--,this.expectCharacter(i.$RBRACE)}return new a.LiteralMap(this.span(n),e,t)},_ParseAST.prototype.parseAccessMemberOrMethodCall=function(e,t){void 0===t&&(t=!1);var n=e.span.start,r=this.expectIdentifierOrKeyword();if(this.optionalCharacter(i.$LPAREN)){this.rparensExpected++;var o=this.parseCallArguments();this.expectCharacter(i.$RPAREN),this.rparensExpected--;var s=this.span(n);return t?new a.SafeMethodCall(s,e,r,o):new a.MethodCall(s,e,r,o)}if(t)return this.optionalOperator("=")?(this.error("The '?.' operator cannot be used in the assignment"),new a.EmptyExpr(this.span(n))):new a.SafePropertyRead(this.span(n),e,r);if(this.optionalOperator("=")){if(!this.parseAction)return this.error("Bindings cannot contain assignments"),new a.EmptyExpr(this.span(n));var l=this.parseConditional();return new a.PropertyWrite(this.span(n),e,r,l)}return new a.PropertyRead(this.span(n),e,r)},_ParseAST.prototype.parseCallArguments=function(){if(this.next.isCharacter(i.$RPAREN))return[];var e=[];do e.push(this.parsePipe());while(this.optionalCharacter(i.$COMMA));return e},_ParseAST.prototype.expectTemplateBindingKey=function(){var e="",t=!1;do e+=this.expectIdentifierOrKeywordOrString(),t=this.optionalOperator("-"),t&&(e+="-");while(t);return e.toString()},_ParseAST.prototype.parseTemplateBindings=function(){for(var e=[],t=null,n=[];this.index0&&e[e.length-1]===t}var r=this&&this.__extends||function(e,t){function __(){this.constructor=e}for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n]);e.prototype=null===t?Object.create(t):(__.prototype=t.prototype,new __)},i=n(10),o=n(5),s=n(60),a=n(85),l=n(68),c=n(546),u=n(102),p=function(e){function TreeError(t,n,r){e.call(this,n,r),this.elementName=t}return r(TreeError,e),TreeError.create=function(e,t,n){return new TreeError(e,t,n)},TreeError}(s.ParseError);t.TreeError=p;var d=function(){function ParseTreeResult(e,t){this.rootNodes=e,this.errors=t}return ParseTreeResult}();t.ParseTreeResult=d;var h=function(){function Parser(e){this._getTagDefinition=e}return Parser.prototype.parse=function(e,t,n,r){void 0===n&&(n=!1),void 0===r&&(r=l.DEFAULT_INTERPOLATION_CONFIG);var i=c.tokenize(e,t,this._getTagDefinition,n,r),o=new f(i.tokens,this._getTagDefinition).build();return new d(o.rootNodes,i.errors.concat(o.errors))},Parser}();t.Parser=h;var f=function(){function _TreeBuilder(e,t){this.tokens=e,this.getTagDefinition=t,this._index=-1,this._rootNodes=[],this._errors=[],this._elementStack=[],this._advance()}return _TreeBuilder.prototype.build=function(){for(;this._peek.type!==c.TokenType.EOF;)this._peek.type===c.TokenType.TAG_OPEN_START?this._consumeStartTag(this._advance()):this._peek.type===c.TokenType.TAG_CLOSE?this._consumeEndTag(this._advance()):this._peek.type===c.TokenType.CDATA_START?(this._closeVoidElement(),this._consumeCdata(this._advance())):this._peek.type===c.TokenType.COMMENT_START?(this._closeVoidElement(),this._consumeComment(this._advance())):this._peek.type===c.TokenType.TEXT||this._peek.type===c.TokenType.RAW_TEXT||this._peek.type===c.TokenType.ESCAPABLE_RAW_TEXT?(this._closeVoidElement(),this._consumeText(this._advance())):this._peek.type===c.TokenType.EXPANSION_FORM_START?this._consumeExpansion(this._advance()):this._advance();return new d(this._rootNodes,this._errors)},_TreeBuilder.prototype._advance=function(){var e=this._peek;return this._index0)return this._errors=this._errors.concat(i.errors),null;var l=new s.ParseSourceSpan(e.sourceSpan.start,r.sourceSpan.end),u=new s.ParseSourceSpan(t.sourceSpan.start,r.sourceSpan.end);return new a.ExpansionCase(e.parts[0],i.rootNodes,l,e.sourceSpan,u)},_TreeBuilder.prototype._collectExpansionExpTokens=function(e){for(var t=[],n=[c.TokenType.EXPANSION_CASE_EXP_START];;){if(this._peek.type!==c.TokenType.EXPANSION_FORM_START&&this._peek.type!==c.TokenType.EXPANSION_CASE_EXP_START||n.push(this._peek.type),this._peek.type===c.TokenType.EXPANSION_CASE_EXP_END){if(!lastOnStack(n,c.TokenType.EXPANSION_CASE_EXP_START))return this._errors.push(p.create(null,e.sourceSpan,"Invalid ICU message. Missing '}'.")),null;if(n.pop(),0==n.length)return t}if(this._peek.type===c.TokenType.EXPANSION_FORM_END){if(!lastOnStack(n,c.TokenType.EXPANSION_FORM_START))return this._errors.push(p.create(null,e.sourceSpan,"Invalid ICU message. Missing '}'.")),null;n.pop()}if(this._peek.type===c.TokenType.EOF)return this._errors.push(p.create(null,e.sourceSpan,"Invalid ICU message. Missing '}'.")),null;t.push(this._advance())}},_TreeBuilder.prototype._consumeText=function(e){var t=e.parts[0];if(t.length>0&&"\n"==t[0]){var n=this._getParentElement();o.isPresent(n)&&0==n.children.length&&this.getTagDefinition(n.name).ignoreFirstLf&&(t=t.substring(1))}t.length>0&&this._addToParent(new a.Text(t,e.sourceSpan))},_TreeBuilder.prototype._closeVoidElement=function(){if(this._elementStack.length>0){var e=i.ListWrapper.last(this._elementStack);this.getTagDefinition(e.name).isVoid&&this._elementStack.pop()}},_TreeBuilder.prototype._consumeStartTag=function(e){for(var t=e.parts[0],n=e.parts[1],r=[];this._peek.type===c.TokenType.ATTR_NAME;)r.push(this._consumeAttr(this._advance()));var i=this._getElementFullName(t,n,this._getParentElement()),o=!1;if(this._peek.type===c.TokenType.TAG_OPEN_END_VOID){this._advance(),o=!0;var l=this.getTagDefinition(i);l.canSelfClose||null!==u.getNsPrefix(i)||l.isVoid||this._errors.push(p.create(i,e.sourceSpan,'Only void and foreign elements can be self closed "'+e.parts[1]+'"'))}else this._peek.type===c.TokenType.TAG_OPEN_END&&(this._advance(),o=!1);var d=this._peek.sourceSpan.start,h=new s.ParseSourceSpan(e.sourceSpan.start,d),f=new a.Element(i,r,[],h,h,null);this._pushElement(f),o&&(this._popElement(i),f.endSourceSpan=h)},_TreeBuilder.prototype._pushElement=function(e){if(this._elementStack.length>0){var t=i.ListWrapper.last(this._elementStack);this.getTagDefinition(t.name).isClosedByChild(e.name)&&this._elementStack.pop()}var n=this.getTagDefinition(e.name),r=this._getParentElementSkippingContainers(),s=r.parent,l=r.container;if(o.isPresent(s)&&n.requireExtraParent(s.name)){var c=new a.Element(n.parentToAdd,[],[],e.sourceSpan,e.startSourceSpan,e.endSourceSpan);this._insertBeforeContainer(s,l,c)}this._addToParent(e),this._elementStack.push(e)},_TreeBuilder.prototype._consumeEndTag=function(e){var t=this._getElementFullName(e.parts[0],e.parts[1],this._getParentElement());this._getParentElement()&&(this._getParentElement().endSourceSpan=e.sourceSpan),this.getTagDefinition(t).isVoid?this._errors.push(p.create(t,e.sourceSpan,'Void elements do not have end tags "'+e.parts[1]+'"')):this._popElement(t)||this._errors.push(p.create(t,e.sourceSpan,'Unexpected closing tag "'+e.parts[1]+'"'))},_TreeBuilder.prototype._popElement=function(e){for(var t=this._elementStack.length-1;t>=0;t--){var n=this._elementStack[t];if(n.name==e)return i.ListWrapper.splice(this._elementStack,t,this._elementStack.length-t),!0;if(!this.getTagDefinition(n.name).closedByParent)return!1}return!1},_TreeBuilder.prototype._consumeAttr=function(e){var t=u.mergeNsAndName(e.parts[0],e.parts[1]),n=e.sourceSpan.end,r="";if(this._peek.type===c.TokenType.ATTR_VALUE){var i=this._advance();r=i.parts[0],n=i.sourceSpan.end}return new a.Attribute(t,r,new s.ParseSourceSpan(e.sourceSpan.start,n))},_TreeBuilder.prototype._getParentElement=function(){return this._elementStack.length>0?i.ListWrapper.last(this._elementStack):null},_TreeBuilder.prototype._getParentElementSkippingContainers=function(){for(var e=null,t=this._elementStack.length-1;t>=0;t--){if("ng-container"!==this._elementStack[t].name)return{parent:this._elementStack[t],container:e};e=this._elementStack[t]}return{parent:i.ListWrapper.last(this._elementStack),container:e}},_TreeBuilder.prototype._addToParent=function(e){var t=this._getParentElement();o.isPresent(t)?t.children.push(e):this._rootNodes.push(e)},_TreeBuilder.prototype._insertBeforeContainer=function(e,t,n){if(t){if(e){var r=e.children.indexOf(t);e.children[r]=n}else this._rootNodes.push(n);n.children.push(t),this._elementStack.splice(this._elementStack.indexOf(t),0,n)}else this._addToParent(n),this._elementStack.push(n)},_TreeBuilder.prototype._getElementFullName=function(e,t,n){return o.isBlank(e)&&(e=this.getTagDefinition(t).implicitNamespacePrefix,o.isBlank(e)&&o.isPresent(n)&&(e=u.getNsPrefix(n.name))),u.mergeNsAndName(e,t)},_TreeBuilder}()},function(e,t,n){"use strict";function splitClasses(e){return e.trim().split(/\s+/g)}function createElementCssSelector(e,t){var n=new w.CssSelector,r=g.splitNsName(e)[1];n.setElement(r);for(var i=0;i0&&this._console.warn("Template parse warnings:\n"+a.join("\n")),l.length>0){var c=l.join("\n");throw new u.BaseException("Template parse errors:\n"+c)}return s.templateAst},TemplateParser.prototype.tryParse=function(e,t,n,r,i,o){var a;e.template&&(a=y.InterpolationConfig.fromArray(e.template.interpolation));var l,c=this._htmlParser.parse(t,o,!0,a),u=c.errors;if(0==u.length){var d=m.expandNodes(c.rootNodes);u.push.apply(u,d.errors),c=new f.ParseTreeResult(d.nodes,u)}if(c.rootNodes.length>0){var g=s.removeIdentifierDuplicates(n),v=s.removeIdentifierDuplicates(r),_=new b.ProviderViewContext(e,c.rootNodes[0].sourceSpan),w=new j(_,g,v,i,this._exprParser,this._schemaRegistry);l=h.visitAll(w,c.rootNodes,z),u.push.apply(u,w.errors.concat(_.errors))}else l=[];return this._assertNoReferenceDuplicationOnTemplate(l,u),u.length>0?new L(l,u):(p.isPresent(this.transforms)&&this.transforms.forEach(function(e){l=E.templateVisitAll(e,l)}),new L(l,u))},TemplateParser.prototype._assertNoReferenceDuplicationOnTemplate=function(e,t){var n=[];e.filter(function(e){return!!e.references}).forEach(function(e){return e.references.forEach(function(e){var r=e.name;if(n.indexOf(r)<0)n.push(r);else{var i=new V('Reference "#'+r+'" is defined several times',e.sourceSpan,v.ParseErrorLevel.FATAL);t.push(i)}})})},TemplateParser.decorators=[{type:i.Injectable}],TemplateParser.ctorParameters=[{type:l.Parser},{type:_.ElementSchemaRegistry},{type:f.HtmlParser},{type:o.Console},{type:Array,decorators:[{type:i.Optional},{type:i.Inject,args:[t.TEMPLATE_TRANSFORMS]}]}],TemplateParser}();t.TemplateParser=F;var j=function(){function TemplateParseVisitor(e,t,n,r,i,o){var s=this;this.providerViewContext=e,this._schemas=r,this._exprParser=i,this._schemaRegistry=o,this.errors=[],this.directivesIndex=new Map,this.ngContentCount=0,this.selectorMatcher=new w.SelectorMatcher;var a=e.component.template;p.isPresent(a)&&p.isPresent(a.interpolation)&&(this._interpolationConfig={start:a.interpolation[0],end:a.interpolation[1]}),c.ListWrapper.forEachWithIndex(t,function(e,t){var n=w.CssSelector.parse(e.selector);s.selectorMatcher.addSelectables(n,e),s.directivesIndex.set(e,t)}),this.pipesByName=new Map,n.forEach(function(e){return s.pipesByName.set(e.name,e)})}return TemplateParseVisitor.prototype._reportError=function(e,t,n){void 0===n&&(n=v.ParseErrorLevel.FATAL),this.errors.push(new V(e,t,n))},TemplateParseVisitor.prototype._reportParserErors=function(e,t){for(var n=0,r=e;no.MAX_INTERPOLATION_VALUES)throw new u.BaseException("Only support at most "+o.MAX_INTERPOLATION_VALUES+" interpolation values!");return r}catch(i){return this._reportError(""+i,t),this._exprParser.wrapLiteralPrimitive("ERROR",n)}},TemplateParseVisitor.prototype._parseAction=function(e,t){var n=t.start.toString();try{var r=this._exprParser.parseAction(e,n,this._interpolationConfig);return r&&this._reportParserErors(r.errors,t),!r||r.ast instanceof a.EmptyExpr?(this._reportError("Empty expressions are not allowed",t),this._exprParser.wrapLiteralPrimitive("ERROR",n)):(this._checkPipes(r,t),r)}catch(i){return this._reportError(""+i,t),this._exprParser.wrapLiteralPrimitive("ERROR",n)}},TemplateParseVisitor.prototype._parseBinding=function(e,t){var n=t.start.toString();try{var r=this._exprParser.parseBinding(e,n,this._interpolationConfig);return r&&this._reportParserErors(r.errors,t),this._checkPipes(r,t),r}catch(i){return this._reportError(""+i,t),this._exprParser.wrapLiteralPrimitive("ERROR",n)}},TemplateParseVisitor.prototype._parseTemplateBindings=function(e,t){var n=this,r=t.start.toString();try{var i=this._exprParser.parseTemplateBindings(e,r);return this._reportParserErors(i.errors,t),i.templateBindings.forEach(function(e){p.isPresent(e.expression)&&n._checkPipes(e.expression,t)}),i.warnings.forEach(function(e){n._reportError(e,t,v.ParseErrorLevel.WARNING)}),i.templateBindings}catch(o){return this._reportError(""+o,t),[]}},TemplateParseVisitor.prototype._checkPipes=function(e,t){var n=this;if(p.isPresent(e)){var r=new q;e.visit(r),r.pipes.forEach(function(e){n.pipesByName.has(e)||n._reportError("The pipe '"+e+"' could not be found",t)})}},TemplateParseVisitor.prototype.visitExpansion=function(e,t){return null},TemplateParseVisitor.prototype.visitExpansionCase=function(e,t){return null},TemplateParseVisitor.prototype.visitText=function(e,t){var n=t.findNgContentIndex(N),r=this._parseInterpolation(e.value,e.sourceSpan);return p.isPresent(r)?new E.BoundTextAst(r,n,e.sourceSpan):new E.TextAst(e.value,n,e.sourceSpan)},TemplateParseVisitor.prototype.visitAttribute=function(e,t){return new E.AttrAst(e.name,e.value,e.sourceSpan)},TemplateParseVisitor.prototype.visitComment=function(e,t){return null},TemplateParseVisitor.prototype.visitElement=function(e,t){var n=this,r=e.name,i=T.preparseElement(e);if(i.type===T.PreparsedElementType.SCRIPT||i.type===T.PreparsedElementType.STYLE)return null;if(i.type===T.PreparsedElementType.STYLESHEET&&S.isStyleUrlResolvable(i.hrefAttr))return null;var o=[],s=[],a=[],l=[],c=[],u=[],d=[],f=[],m=[],y=!1,v=[],_=g.splitNsName(r.toLowerCase())[1],C=_==P;e.attrs.forEach(function(e){var t=n._parseAttr(C,e,o,s,c,u,a,l),r=n._parseInlineTemplateBinding(e,f,d,m);r&&y&&n._reportError("Can't have multiple template bindings on one element. Use only one attribute named 'template' or prefixed with *",e.sourceSpan),t||r||(v.push(n.visitAttribute(e,null)),o.push([e.name,e.value])),r&&(y=!0)});var R=createElementCssSelector(r,o),x=this._parseDirectives(this.selectorMatcher,R),M=[],I=this._createDirectiveAsts(C,e.name,x,s,a,e.sourceSpan,M),k=this._createElementPropertyAsts(e.name,s,I).concat(c),A=t.isTemplateElement||y,O=new b.ProviderElementContext(this.providerViewContext,t.providerContext,A,I,v,M,e.sourceSpan),D=h.visitAll(i.nonBindable?G:this,e.children,U.create(C,I,C?t.providerContext:O));O.afterElement();var N,V=p.isPresent(i.projectAs)?w.CssSelector.parse(i.projectAs)[0]:R,L=t.findNgContentIndex(V);if(i.type===T.PreparsedElementType.NG_CONTENT)p.isPresent(e.children)&&e.children.length>0&&this._reportError(" element cannot have content. must be immediately followed by ",e.sourceSpan),N=new E.NgContentAst((this.ngContentCount++),y?null:L,e.sourceSpan);else if(C)this._assertAllEventsPublishedByDirectives(I,u),this._assertNoComponentsNorElementBindingsOnTemplate(I,k,e.sourceSpan),N=new E.EmbeddedTemplateAst(v,u,M,l,O.transformedDirectiveAsts,O.transformProviders,O.transformedHasViewContainer,D,y?null:L,e.sourceSpan);else{this._assertOnlyOneComponent(I,e.sourceSpan);var F=y?null:t.findNgContentIndex(V);N=new E.ElementAst(r,v,k,u,M,O.transformedDirectiveAsts,O.transformProviders,O.transformedHasViewContainer,D,y?null:F,e.sourceSpan)}if(y){var j=createElementCssSelector(P,f),B=this._parseDirectives(this.selectorMatcher,j),W=this._createDirectiveAsts(!0,e.name,B,d,[],e.sourceSpan,[]),H=this._createElementPropertyAsts(e.name,d,W);this._assertNoComponentsNorElementBindingsOnTemplate(W,H,e.sourceSpan);var z=new b.ProviderElementContext(this.providerViewContext,t.providerContext,t.isTemplateElement,W,[],[],e.sourceSpan);z.afterElement(),N=new E.EmbeddedTemplateAst([],[],[],m,z.transformedDirectiveAsts,z.transformProviders,z.transformedHasViewContainer,[N],L,e.sourceSpan)}return N},TemplateParseVisitor.prototype._parseInlineTemplateBinding=function(e,t,n,r){var i=null;if(this._normalizeAttributeName(e.name)==x)i=e.value;else if(e.name.startsWith(M)){var o=e.name.substring(M.length);i=0==e.value.length?o:o+" "+e.value}if(p.isPresent(i)){for(var s=this._parseTemplateBindings(i,e.sourceSpan),a=0;a elements is deprecated. Use "let-" instead!',t.sourceSpan,v.ParseErrorLevel.WARNING),this._parseVariable(h,c,t.sourceSpan,a)):(this._reportError('"var-" on non