diff --git a/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/CONTRIBUTORS.md b/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/CONTRIBUTORS.md new file mode 100644 index 00000000..a44885cd --- /dev/null +++ b/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/CONTRIBUTORS.md @@ -0,0 +1,9 @@ +This project is originally a fork of [https://github.com/youtube/vitess](https://github.com/youtube/vitess) +Copyright Google Inc + +# Contributors +Wenbin Xiao 2015 +Started this project and maintained it. + +Andrew Brampton 2017 +Merged in multiple upstream fixes/changes. \ No newline at end of file diff --git a/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/LICENSE.md b/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/LICENSE.md new file mode 100644 index 00000000..f49a4e16 --- /dev/null +++ b/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/LICENSE.md @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "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. \ No newline at end of file diff --git a/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/Makefile b/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/Makefile new file mode 100644 index 00000000..215f422e --- /dev/null +++ b/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/Makefile @@ -0,0 +1,22 @@ +# 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. + +MAKEFLAGS = -s + +sql.go: sql.y + goyacc -o sql.go sql.y + gofmt -w sql.go + +clean: + rm -f y.output sql.go diff --git a/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/README.md b/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/README.md new file mode 100644 index 00000000..58d47596 --- /dev/null +++ b/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/README.md @@ -0,0 +1,150 @@ +# sqlparser [![Build Status](https://img.shields.io/travis/xwb1989/sqlparser.svg)](https://travis-ci.org/xwb1989/sqlparser) [![Coverage](https://img.shields.io/coveralls/xwb1989/sqlparser.svg)](https://coveralls.io/github/xwb1989/sqlparser) [![Report card](https://goreportcard.com/badge/github.com/xwb1989/sqlparser)](https://goreportcard.com/report/github.com/xwb1989/sqlparser) [![GoDoc](https://godoc.org/github.com/xwb1989/sqlparser?status.svg)](https://godoc.org/github.com/xwb1989/sqlparser) + +Go package for parsing MySQL SQL queries. + +## Notice + +The backbone of this repo is extracted from [vitessio/vitess](https://github.com/vitessio/vitess). + +Inside vitessio/vitess there is a very nicely written sql parser. However as it's not a self-contained application, I created this one. +It applies the same LICENSE as vitessio/vitess. + +## Usage + +```go +import ( + "github.com/xwb1989/sqlparser" +) +``` + +Then use: + +```go +sql := "SELECT * FROM table WHERE a = 'abc'" +stmt, err := sqlparser.Parse(sql) +if err != nil { + // Do something with the err +} + +// Otherwise do something with stmt +switch stmt := stmt.(type) { +case *sqlparser.Select: + _ = stmt +case *sqlparser.Insert: +} +``` + +Alternative to read many queries from a io.Reader: + +```go +r := strings.NewReader("INSERT INTO table1 VALUES (1, 'a'); INSERT INTO table2 VALUES (3, 4);") + +tokens := sqlparser.NewTokenizer(r) +for { + stmt, err := sqlparser.ParseNext(tokens) + if err == io.EOF { + break + } + // Do something with stmt or err. +} +``` + +See [parse_test.go](https://github.com/xwb1989/sqlparser/blob/master/parse_test.go) for more examples, or read the [godoc](https://godoc.org/github.com/xwb1989/sqlparser). + + +## Porting Instructions + +You only need the below if you plan to try and keep this library up to date with [vitessio/vitess](https://github.com/vitessio/vitess). + +### Keeping up to date + +```bash +shopt -s nullglob +VITESS=${GOPATH?}/src/vitess.io/vitess/go/ +XWB1989=${GOPATH?}/src/github.com/xwb1989/sqlparser/ + +# Create patches for everything that changed +LASTIMPORT=1b7879cb91f1dfe1a2dfa06fea96e951e3a7aec5 +for path in ${VITESS?}/{vt/sqlparser,sqltypes,bytes2,hack}; do + cd ${path} + git format-patch ${LASTIMPORT?} . +done; + +# Apply patches to the dependencies +cd ${XWB1989?} +git am --directory dependency -p2 ${VITESS?}/{sqltypes,bytes2,hack}/*.patch + +# Apply the main patches to the repo +cd ${XWB1989?} +git am -p4 ${VITESS?}/vt/sqlparser/*.patch + +# If you encounter diff failures, manually fix them with +patch -p4 < .git/rebase-apply/patch +... +git add name_of_files +git am --continue + +# Cleanup +rm ${VITESS?}/{sqltypes,bytes2,hack}/*.patch ${VITESS?}/*.patch + +# and Finally update the LASTIMPORT in this README. +``` + +### Fresh install + +TODO: Change these instructions to use git to copy the files, that'll make later patching easier. + +```bash +VITESS=${GOPATH?}/src/vitess.io/vitess/go/ +XWB1989=${GOPATH?}/src/github.com/xwb1989/sqlparser/ + +cd ${XWB1989?} + +# Copy all the code +cp -pr ${VITESS?}/vt/sqlparser/ . +cp -pr ${VITESS?}/sqltypes dependency +cp -pr ${VITESS?}/bytes2 dependency +cp -pr ${VITESS?}/hack dependency + +# Delete some code we haven't ported +rm dependency/sqltypes/arithmetic.go dependency/sqltypes/arithmetic_test.go dependency/sqltypes/event_token.go dependency/sqltypes/event_token_test.go dependency/sqltypes/proto3.go dependency/sqltypes/proto3_test.go dependency/sqltypes/query_response.go dependency/sqltypes/result.go dependency/sqltypes/result_test.go + +# Some automated fixes + +# Fix imports +sed -i '.bak' 's_vitess.io/vitess/go/vt/proto/query_github.com/xwb1989/sqlparser/dependency/querypb_g' *.go dependency/sqltypes/*.go +sed -i '.bak' 's_vitess.io/vitess/go/_github.com/xwb1989/sqlparser/dependency/_g' *.go dependency/sqltypes/*.go + +# Copy the proto, but basically drop everything we don't want +cp -pr ${VITESS?}/vt/proto/query dependency/querypb + +sed -i '.bak' 's_.*Descriptor.*__g' dependency/querypb/*.go +sed -i '.bak' 's_.*ProtoMessage.*__g' dependency/querypb/*.go + +sed -i '.bak' 's/proto.CompactTextString(m)/"TODO"/g' dependency/querypb/*.go +sed -i '.bak' 's/proto.EnumName/EnumName/g' dependency/querypb/*.go + +sed -i '.bak' 's/proto.Equal/reflect.DeepEqual/g' dependency/sqltypes/*.go + +# Remove the error library +sed -i '.bak' 's/vterrors.Errorf([^,]*, /fmt.Errorf(/g' *.go dependency/sqltypes/*.go +sed -i '.bak' 's/vterrors.New([^,]*, /errors.New(/g' *.go dependency/sqltypes/*.go +``` + +### Testing + +```bash +VITESS=${GOPATH?}/src/vitess.io/vitess/go/ +XWB1989=${GOPATH?}/src/github.com/xwb1989/sqlparser/ + +cd ${XWB1989?} + +# Test, fix and repeat +go test ./... + +# Finally make some diffs (for later reference) +diff -u ${VITESS?}/sqltypes/ ${XWB1989?}/dependency/sqltypes/ > ${XWB1989?}/patches/sqltypes.patch +diff -u ${VITESS?}/bytes2/ ${XWB1989?}/dependency/bytes2/ > ${XWB1989?}/patches/bytes2.patch +diff -u ${VITESS?}/vt/proto/query/ ${XWB1989?}/dependency/querypb/ > ${XWB1989?}/patches/querypb.patch +diff -u ${VITESS?}/vt/sqlparser/ ${XWB1989?}/ > ${XWB1989?}/patches/sqlparser.patch +``` \ No newline at end of file diff --git a/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/analyzer.go b/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/analyzer.go new file mode 100644 index 00000000..95f97d35 --- /dev/null +++ b/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/analyzer.go @@ -0,0 +1,343 @@ +/* +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 sqlparser + +// analyzer.go contains utility analysis functions. + +import ( + "errors" + "fmt" + "strconv" + "strings" + "unicode" + + "github.com/xwb1989/sqlparser/dependency/sqltypes" +) + +// These constants are used to identify the SQL statement type. +const ( + StmtSelect = iota + StmtStream + StmtInsert + StmtReplace + StmtUpdate + StmtDelete + StmtDDL + StmtBegin + StmtCommit + StmtRollback + StmtSet + StmtShow + StmtUse + StmtOther + StmtUnknown + StmtComment +) + +// Preview analyzes the beginning of the query using a simpler and faster +// textual comparison to identify the statement type. +func Preview(sql string) int { + trimmed := StripLeadingComments(sql) + + firstWord := trimmed + if end := strings.IndexFunc(trimmed, unicode.IsSpace); end != -1 { + firstWord = trimmed[: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 { + case "select": + return StmtSelect + case "stream": + return StmtStream + case "insert": + return StmtInsert + case "replace": + return StmtReplace + case "update": + return StmtUpdate + case "delete": + return StmtDelete + } + // For the following statements it is not sufficient to rely + // on loweredFirstWord. This is because they are not statements + // in the grammar and we are relying on Preview to parse them. + // For instance, we don't want: "BEGIN JUNK" to be parsed + // as StmtBegin. + trimmedNoComments, _ := SplitMarginComments(trimmed) + switch strings.ToLower(trimmedNoComments) { + case "begin", "start transaction": + return StmtBegin + case "commit": + return StmtCommit + case "rollback": + return StmtRollback + } + switch loweredFirstWord { + case "create", "alter", "rename", "drop", "truncate": + return StmtDDL + case "set": + return StmtSet + case "show": + return StmtShow + case "use": + return StmtUse + case "analyze", "describe", "desc", "explain", "repair", "optimize": + return StmtOther + } + if strings.Index(trimmed, "/*!") == 0 { + return StmtComment + } + return StmtUnknown +} + +// StmtType returns the statement type as a string +func StmtType(stmtType int) string { + switch stmtType { + case StmtSelect: + return "SELECT" + case StmtStream: + return "STREAM" + case StmtInsert: + return "INSERT" + case StmtReplace: + return "REPLACE" + case StmtUpdate: + return "UPDATE" + case StmtDelete: + return "DELETE" + case StmtDDL: + return "DDL" + case StmtBegin: + return "BEGIN" + case StmtCommit: + return "COMMIT" + case StmtRollback: + return "ROLLBACK" + case StmtSet: + return "SET" + case StmtShow: + return "SHOW" + case StmtUse: + return "USE" + case StmtOther: + return "OTHER" + default: + return "UNKNOWN" + } +} + +// IsDML returns true if the query is an INSERT, UPDATE or DELETE statement. +func IsDML(sql string) bool { + switch Preview(sql) { + case StmtInsert, StmtReplace, StmtUpdate, StmtDelete: + return true + } + return false +} + +// GetTableName returns the table name from the SimpleTableExpr +// only if it's a simple expression. Otherwise, it returns "". +func GetTableName(node SimpleTableExpr) TableIdent { + if n, ok := node.(TableName); ok && n.Qualifier.IsEmpty() { + return n.Name + } + // sub-select or '.' expression + return NewTableIdent("") +} + +// IsColName returns true if the Expr is a *ColName. +func IsColName(node Expr) bool { + _, ok := node.(*ColName) + return ok +} + +// IsValue returns true if the Expr is a string, integral or value arg. +// NULL is not considered to be a value. +func IsValue(node Expr) bool { + switch v := node.(type) { + case *SQLVal: + switch v.Type { + case StrVal, HexVal, IntVal, ValArg: + return true + } + } + return false +} + +// IsNull returns true if the Expr is SQL NULL +func IsNull(node Expr) bool { + switch node.(type) { + case *NullVal: + return true + } + return false +} + +// IsSimpleTuple returns true if the Expr is a ValTuple that +// contains simple values or if it's a list arg. +func IsSimpleTuple(node Expr) bool { + switch vals := node.(type) { + case ValTuple: + for _, n := range vals { + if !IsValue(n) { + return false + } + } + return true + case ListArg: + return true + } + // It's a subquery + return false +} + +// NewPlanValue builds a sqltypes.PlanValue from an Expr. +func NewPlanValue(node Expr) (sqltypes.PlanValue, error) { + switch node := node.(type) { + case *SQLVal: + switch node.Type { + case ValArg: + return sqltypes.PlanValue{Key: string(node.Val[1:])}, nil + case IntVal: + n, err := sqltypes.NewIntegral(string(node.Val)) + if err != nil { + return sqltypes.PlanValue{}, fmt.Errorf("%v", err) + } + return sqltypes.PlanValue{Value: n}, nil + case StrVal: + return sqltypes.PlanValue{Value: sqltypes.MakeTrusted(sqltypes.VarBinary, node.Val)}, nil + case HexVal: + v, err := node.HexDecode() + if err != nil { + return sqltypes.PlanValue{}, fmt.Errorf("%v", err) + } + return sqltypes.PlanValue{Value: sqltypes.MakeTrusted(sqltypes.VarBinary, v)}, nil + } + case ListArg: + return sqltypes.PlanValue{ListKey: string(node[2:])}, nil + case ValTuple: + pv := sqltypes.PlanValue{ + Values: make([]sqltypes.PlanValue, 0, len(node)), + } + for _, val := range node { + innerpv, err := NewPlanValue(val) + if err != nil { + return sqltypes.PlanValue{}, err + } + if innerpv.ListKey != "" || innerpv.Values != nil { + return sqltypes.PlanValue{}, errors.New("unsupported: nested lists") + } + pv.Values = append(pv.Values, innerpv) + } + return pv, nil + case *NullVal: + return sqltypes.PlanValue{}, nil + } + return sqltypes.PlanValue{}, fmt.Errorf("expression is too complex '%v'", String(node)) +} + +// StringIn is a convenience function that returns +// true if str matches any of the values. +func StringIn(str string, values ...string) bool { + for _, val := range values { + if str == val { + return true + } + } + return false +} + +// SetKey is the extracted key from one SetExpr +type SetKey struct { + Key string + Scope string +} + +// ExtractSetValues returns a map of key-value pairs +// if the query is a SET statement. Values can be bool, int64 or string. +// Since set variable names are case insensitive, all keys are returned +// as lower case. +func ExtractSetValues(sql string) (keyValues map[SetKey]interface{}, scope string, err error) { + stmt, err := Parse(sql) + if err != nil { + return nil, "", err + } + setStmt, ok := stmt.(*Set) + if !ok { + return nil, "", fmt.Errorf("ast did not yield *sqlparser.Set: %T", stmt) + } + result := make(map[SetKey]interface{}) + for _, expr := range setStmt.Exprs { + scope := SessionStr + key := expr.Name.Lowered() + switch { + case strings.HasPrefix(key, "@@global."): + scope = GlobalStr + key = strings.TrimPrefix(key, "@@global.") + case strings.HasPrefix(key, "@@session."): + key = strings.TrimPrefix(key, "@@session.") + case strings.HasPrefix(key, "@@"): + key = strings.TrimPrefix(key, "@@") + } + + if strings.HasPrefix(expr.Name.Lowered(), "@@") { + if setStmt.Scope != "" && scope != "" { + return nil, "", fmt.Errorf("unsupported in set: mixed using of variable scope") + } + _, out := NewStringTokenizer(key).Scan() + key = string(out) + } + + setKey := SetKey{ + Key: key, + Scope: scope, + } + + switch expr := expr.Expr.(type) { + case *SQLVal: + switch expr.Type { + case StrVal: + result[setKey] = strings.ToLower(string(expr.Val)) + case IntVal: + num, err := strconv.ParseInt(string(expr.Val), 0, 64) + if err != nil { + return nil, "", err + } + result[setKey] = num + default: + return nil, "", fmt.Errorf("invalid value type: %v", String(expr)) + } + case BoolVal: + var val int64 + if expr { + val = 1 + } + result[setKey] = val + case *ColName: + result[setKey] = expr.Name.String() + case *NullVal: + result[setKey] = nil + case *Default: + result[setKey] = "default" + default: + return nil, "", fmt.Errorf("invalid syntax: %s", String(expr)) + } + } + return result, strings.ToLower(setStmt.Scope), nil +} diff --git a/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/analyzer_test.go b/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/analyzer_test.go new file mode 100644 index 00000000..6d8c1ef1 --- /dev/null +++ b/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/analyzer_test.go @@ -0,0 +1,511 @@ +/* +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 sqlparser + +import ( + "reflect" + "strings" + "testing" + + "github.com/xwb1989/sqlparser/dependency/sqltypes" +) + +func TestPreview(t *testing.T) { + testcases := []struct { + sql string + want int + }{ + {"select ...", StmtSelect}, + {" select ...", StmtSelect}, + {"(select ...", StmtSelect}, + {"insert ...", StmtInsert}, + {"replace ....", StmtReplace}, + {" update ...", StmtUpdate}, + {"Update", StmtUpdate}, + {"UPDATE ...", StmtUpdate}, + {"\n\t delete ...", StmtDelete}, + {"", StmtUnknown}, + {" ", StmtUnknown}, + {"begin", StmtBegin}, + {" begin", StmtBegin}, + {" begin ", StmtBegin}, + {"\n\t begin ", StmtBegin}, + {"... begin ", StmtUnknown}, + {"begin ...", StmtUnknown}, + {"begin /* ... */", StmtBegin}, + {"begin /* ... *//*test*/", StmtBegin}, + {"start transaction", StmtBegin}, + {"commit", StmtCommit}, + {"commit /*...*/", StmtCommit}, + {"rollback", StmtRollback}, + {"rollback /*...*/", StmtRollback}, + {"create", StmtDDL}, + {"alter", StmtDDL}, + {"rename", StmtDDL}, + {"drop", StmtDDL}, + {"set", StmtSet}, + {"show", StmtShow}, + {"use", StmtUse}, + {"analyze", StmtOther}, + {"describe", StmtOther}, + {"desc", StmtOther}, + {"explain", StmtOther}, + {"repair", StmtOther}, + {"optimize", StmtOther}, + {"truncate", StmtDDL}, + {"unknown", StmtUnknown}, + + {"/* leading comment */ select ...", StmtSelect}, + {"/* leading comment */ (select ...", StmtSelect}, + {"/* leading comment */ /* leading comment 2 */ select ...", StmtSelect}, + {"/*! MySQL-specific comment */", StmtComment}, + {"/*!50708 MySQL-version comment */", StmtComment}, + {"-- leading single line comment \n select ...", StmtSelect}, + {"-- leading single line comment \n -- leading single line comment 2\n select ...", StmtSelect}, + + {"/* leading comment no end select ...", StmtUnknown}, + {"-- leading single line comment no end select ...", StmtUnknown}, + } + for _, tcase := range testcases { + if got := Preview(tcase.sql); got != tcase.want { + t.Errorf("Preview(%s): %v, want %v", tcase.sql, got, tcase.want) + } + } +} + +func TestIsDML(t *testing.T) { + testcases := []struct { + sql string + want bool + }{ + {" update ...", true}, + {"Update", true}, + {"UPDATE ...", true}, + {"\n\t delete ...", true}, + {"insert ...", true}, + {"replace ...", true}, + {"select ...", false}, + {" select ...", false}, + {"", false}, + {" ", false}, + } + for _, tcase := range testcases { + if got := IsDML(tcase.sql); got != tcase.want { + t.Errorf("IsDML(%s): %v, want %v", tcase.sql, got, tcase.want) + } + } +} + +func TestGetTableName(t *testing.T) { + testcases := []struct { + in, out string + }{{ + in: "select * from t", + out: "t", + }, { + in: "select * from t.t", + out: "", + }, { + in: "select * from (select * from t) as tt", + out: "", + }} + + for _, tc := range testcases { + tree, err := Parse(tc.in) + if err != nil { + t.Error(err) + continue + } + out := GetTableName(tree.(*Select).From[0].(*AliasedTableExpr).Expr) + if out.String() != tc.out { + t.Errorf("GetTableName('%s'): %s, want %s", tc.in, out, tc.out) + } + } +} + +func TestIsColName(t *testing.T) { + testcases := []struct { + in Expr + out bool + }{{ + in: &ColName{}, + out: true, + }, { + in: newHexVal(""), + }} + for _, tc := range testcases { + out := IsColName(tc.in) + if out != tc.out { + t.Errorf("IsColName(%T): %v, want %v", tc.in, out, tc.out) + } + } +} + +func TestIsValue(t *testing.T) { + testcases := []struct { + in Expr + out bool + }{{ + in: newStrVal("aa"), + out: true, + }, { + in: newHexVal("3131"), + out: true, + }, { + in: newIntVal("1"), + out: true, + }, { + in: newValArg(":a"), + out: true, + }, { + in: &NullVal{}, + out: false, + }} + for _, tc := range testcases { + out := IsValue(tc.in) + if out != tc.out { + t.Errorf("IsValue(%T): %v, want %v", tc.in, out, tc.out) + } + if tc.out { + // NewPlanValue should not fail for valid values. + if _, err := NewPlanValue(tc.in); err != nil { + t.Error(err) + } + } + } +} + +func TestIsNull(t *testing.T) { + testcases := []struct { + in Expr + out bool + }{{ + in: &NullVal{}, + out: true, + }, { + in: newStrVal(""), + }} + for _, tc := range testcases { + out := IsNull(tc.in) + if out != tc.out { + t.Errorf("IsNull(%T): %v, want %v", tc.in, out, tc.out) + } + } +} + +func TestIsSimpleTuple(t *testing.T) { + testcases := []struct { + in Expr + out bool + }{{ + in: ValTuple{newStrVal("aa")}, + out: true, + }, { + in: ValTuple{&ColName{}}, + }, { + in: ListArg("::a"), + out: true, + }, { + in: &ColName{}, + }} + for _, tc := range testcases { + out := IsSimpleTuple(tc.in) + if out != tc.out { + t.Errorf("IsSimpleTuple(%T): %v, want %v", tc.in, out, tc.out) + } + if tc.out { + // NewPlanValue should not fail for valid tuples. + if _, err := NewPlanValue(tc.in); err != nil { + t.Error(err) + } + } + } +} + +func TestNewPlanValue(t *testing.T) { + tcases := []struct { + in Expr + out sqltypes.PlanValue + err string + }{{ + in: &SQLVal{ + Type: ValArg, + Val: []byte(":valarg"), + }, + out: sqltypes.PlanValue{Key: "valarg"}, + }, { + in: &SQLVal{ + Type: IntVal, + Val: []byte("10"), + }, + out: sqltypes.PlanValue{Value: sqltypes.NewInt64(10)}, + }, { + in: &SQLVal{ + Type: IntVal, + Val: []byte("1111111111111111111111111111111111111111"), + }, + err: "value out of range", + }, { + in: &SQLVal{ + Type: StrVal, + Val: []byte("strval"), + }, + out: sqltypes.PlanValue{Value: sqltypes.NewVarBinary("strval")}, + }, { + in: &SQLVal{ + Type: HexVal, + Val: []byte("3131"), + }, + out: sqltypes.PlanValue{Value: sqltypes.NewVarBinary("11")}, + }, { + in: &SQLVal{ + Type: HexVal, + Val: []byte("313"), + }, + err: "odd length hex string", + }, { + in: ListArg("::list"), + out: sqltypes.PlanValue{ListKey: "list"}, + }, { + in: ValTuple{ + &SQLVal{ + Type: ValArg, + Val: []byte(":valarg"), + }, + &SQLVal{ + Type: StrVal, + Val: []byte("strval"), + }, + }, + out: sqltypes.PlanValue{ + Values: []sqltypes.PlanValue{{ + Key: "valarg", + }, { + Value: sqltypes.NewVarBinary("strval"), + }}, + }, + }, { + in: ValTuple{ + &ParenExpr{Expr: &SQLVal{ + Type: ValArg, + Val: []byte(":valarg"), + }}, + }, + err: "expression is too complex", + }, { + in: ValTuple{ + ListArg("::list"), + }, + err: "unsupported: nested lists", + }, { + in: &NullVal{}, + out: sqltypes.PlanValue{}, + }, { + in: &ParenExpr{Expr: &SQLVal{ + Type: ValArg, + Val: []byte(":valarg"), + }}, + err: "expression is too complex", + }} + for _, tc := range tcases { + got, err := NewPlanValue(tc.in) + if err != nil { + if !strings.Contains(err.Error(), tc.err) { + t.Errorf("NewPlanValue(%s) error: %v, want '%s'", String(tc.in), err, tc.err) + } + continue + } + if tc.err != "" { + t.Errorf("NewPlanValue(%s) error: nil, want '%s'", String(tc.in), tc.err) + continue + } + if !reflect.DeepEqual(got, tc.out) { + t.Errorf("NewPlanValue(%s): %v, want %v", String(tc.in), got, tc.out) + } + } +} + +func TestStringIn(t *testing.T) { + testcases := []struct { + in1 string + in2 []string + out bool + }{{ + in1: "v1", + in2: []string{"v1", "v2"}, + out: true, + }, { + in1: "v0", + in2: []string{"v1", "v2"}, + }} + for _, tc := range testcases { + out := StringIn(tc.in1, tc.in2...) + if out != tc.out { + t.Errorf("StringIn(%v,%v): %#v, want %#v", tc.in1, tc.in2, out, tc.out) + } + } +} + +func TestExtractSetValues(t *testing.T) { + testcases := []struct { + sql string + out map[SetKey]interface{} + scope string + err string + }{{ + sql: "invalid", + err: "syntax error at position 8 near 'invalid'", + }, { + sql: "select * from t", + err: "ast did not yield *sqlparser.Set: *sqlparser.Select", + }, { + sql: "set autocommit=1+1", + err: "invalid syntax: 1 + 1", + }, { + sql: "set transaction_mode='single'", + out: map[SetKey]interface{}{{Key: "transaction_mode", Scope: "session"}: "single"}, + }, { + sql: "set autocommit=1", + out: map[SetKey]interface{}{{Key: "autocommit", Scope: "session"}: int64(1)}, + }, { + sql: "set autocommit=true", + out: map[SetKey]interface{}{{Key: "autocommit", Scope: "session"}: int64(1)}, + }, { + sql: "set autocommit=false", + out: map[SetKey]interface{}{{Key: "autocommit", Scope: "session"}: int64(0)}, + }, { + sql: "set autocommit=on", + out: map[SetKey]interface{}{{Key: "autocommit", Scope: "session"}: "on"}, + }, { + sql: "set autocommit=off", + out: map[SetKey]interface{}{{Key: "autocommit", Scope: "session"}: "off"}, + }, { + sql: "set @@global.autocommit=1", + out: map[SetKey]interface{}{{Key: "autocommit", Scope: "global"}: int64(1)}, + }, { + sql: "set @@global.autocommit=1", + out: map[SetKey]interface{}{{Key: "autocommit", Scope: "global"}: int64(1)}, + }, { + sql: "set @@session.autocommit=1", + out: map[SetKey]interface{}{{Key: "autocommit", Scope: "session"}: int64(1)}, + }, { + sql: "set @@session.`autocommit`=1", + out: map[SetKey]interface{}{{Key: "autocommit", Scope: "session"}: int64(1)}, + }, { + sql: "set @@session.'autocommit'=1", + out: map[SetKey]interface{}{{Key: "autocommit", Scope: "session"}: int64(1)}, + }, { + sql: "set @@session.\"autocommit\"=1", + out: map[SetKey]interface{}{{Key: "autocommit", Scope: "session"}: int64(1)}, + }, { + sql: "set @@session.'\"autocommit'=1", + out: map[SetKey]interface{}{{Key: "\"autocommit", Scope: "session"}: int64(1)}, + }, { + sql: "set @@session.`autocommit'`=1", + out: map[SetKey]interface{}{{Key: "autocommit'", Scope: "session"}: int64(1)}, + }, { + sql: "set AUTOCOMMIT=1", + out: map[SetKey]interface{}{{Key: "autocommit", Scope: "session"}: int64(1)}, + }, { + sql: "SET character_set_results = NULL", + out: map[SetKey]interface{}{{Key: "character_set_results", Scope: "session"}: nil}, + }, { + sql: "SET foo = 0x1234", + err: "invalid value type: 0x1234", + }, { + sql: "SET names utf8", + out: map[SetKey]interface{}{{Key: "names", Scope: "session"}: "utf8"}, + }, { + sql: "SET names ascii collate ascii_bin", + out: map[SetKey]interface{}{{Key: "names", Scope: "session"}: "ascii"}, + }, { + sql: "SET charset default", + out: map[SetKey]interface{}{{Key: "charset", Scope: "session"}: "default"}, + }, { + sql: "SET character set ascii", + out: map[SetKey]interface{}{{Key: "charset", Scope: "session"}: "ascii"}, + }, { + sql: "SET SESSION wait_timeout = 3600", + out: map[SetKey]interface{}{{Key: "wait_timeout", Scope: "session"}: int64(3600)}, + scope: "session", + }, { + sql: "SET GLOBAL wait_timeout = 3600", + out: map[SetKey]interface{}{{Key: "wait_timeout", Scope: "session"}: int64(3600)}, + scope: "global", + }, { + sql: "set session transaction isolation level repeatable read", + out: map[SetKey]interface{}{{Key: "tx_isolation", Scope: "session"}: "repeatable read"}, + scope: "session", + }, { + sql: "set session transaction isolation level read committed", + out: map[SetKey]interface{}{{Key: "tx_isolation", Scope: "session"}: "read committed"}, + scope: "session", + }, { + sql: "set session transaction isolation level read uncommitted", + out: map[SetKey]interface{}{{Key: "tx_isolation", Scope: "session"}: "read uncommitted"}, + scope: "session", + }, { + sql: "set session transaction isolation level serializable", + out: map[SetKey]interface{}{{Key: "tx_isolation", Scope: "session"}: "serializable"}, + scope: "session", + }, { + sql: "set session tx_read_only = 0", + out: map[SetKey]interface{}{{Key: "tx_read_only", Scope: "session"}: int64(0)}, + scope: "session", + }, { + sql: "set session tx_read_only = 1", + out: map[SetKey]interface{}{{Key: "tx_read_only", Scope: "session"}: int64(1)}, + scope: "session", + }, { + sql: "set session sql_safe_updates = 0", + out: map[SetKey]interface{}{{Key: "sql_safe_updates", Scope: "session"}: int64(0)}, + scope: "session", + }, { + sql: "set session sql_safe_updates = 1", + out: map[SetKey]interface{}{{Key: "sql_safe_updates", Scope: "session"}: int64(1)}, + scope: "session", + }} + for _, tcase := range testcases { + out, _, err := ExtractSetValues(tcase.sql) + if tcase.err != "" { + if err == nil || err.Error() != tcase.err { + t.Errorf("ExtractSetValues(%s): %v, want '%s'", tcase.sql, err, tcase.err) + } + } else if err != nil { + t.Errorf("ExtractSetValues(%s): %v, want no error", tcase.sql, err) + } + if !reflect.DeepEqual(out, tcase.out) { + t.Errorf("ExtractSetValues(%s): %v, want '%v'", tcase.sql, out, tcase.out) + } + } +} + +func newStrVal(in string) *SQLVal { + return NewStrVal([]byte(in)) +} + +func newIntVal(in string) *SQLVal { + return NewIntVal([]byte(in)) +} + +func newHexVal(in string) *SQLVal { + return NewHexVal([]byte(in)) +} + +func newValArg(in string) *SQLVal { + return NewValArg([]byte(in)) +} diff --git a/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/ast.go b/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/ast.go new file mode 100644 index 00000000..c3a0d083 --- /dev/null +++ b/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/ast.go @@ -0,0 +1,3450 @@ +/* +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 sqlparser + +import ( + "bytes" + "encoding/hex" + "encoding/json" + "fmt" + "io" + "log" + "strings" + + "github.com/xwb1989/sqlparser/dependency/querypb" + "github.com/xwb1989/sqlparser/dependency/sqltypes" +) + +// Instructions for creating new types: If a type +// needs to satisfy an interface, declare that function +// along with that interface. This will help users +// identify the list of types to which they can assert +// those interfaces. +// If the member of a type has a string with a predefined +// list of values, declare those values as const following +// the type. +// For interfaces that define dummy functions to consolidate +// a set of types, define the function as iTypeName. +// This will help avoid name collisions. + +// Parse parses the SQL in full and returns a Statement, which +// is the AST representation of the query. If a DDL statement +// is partially parsed but still contains a syntax error, the +// error is ignored and the DDL is returned anyway. +func Parse(sql string) (Statement, error) { + tokenizer := NewStringTokenizer(sql) + if yyParse(tokenizer) != 0 { + if tokenizer.partialDDL != nil { + log.Printf("ignoring error parsing DDL '%s': %v", sql, tokenizer.LastError) + tokenizer.ParseTree = tokenizer.partialDDL + return tokenizer.ParseTree, nil + } + return nil, tokenizer.LastError + } + return tokenizer.ParseTree, nil +} + +// ParseStrictDDL is the same as Parse except it errors on +// partially parsed DDL statements. +func ParseStrictDDL(sql string) (Statement, error) { + tokenizer := NewStringTokenizer(sql) + if yyParse(tokenizer) != 0 { + return nil, tokenizer.LastError + } + return tokenizer.ParseTree, nil +} + +// ParseNext parses a single SQL statement from the tokenizer +// returning a Statement which is the AST representation of the query. +// The tokenizer will always read up to the end of the statement, allowing for +// the next call to ParseNext to parse any subsequent SQL statements. When +// there are no more statements to parse, a error of io.EOF is returned. +func ParseNext(tokenizer *Tokenizer) (Statement, error) { + if tokenizer.lastChar == ';' { + tokenizer.next() + tokenizer.skipBlank() + } + if tokenizer.lastChar == eofChar { + return nil, io.EOF + } + + tokenizer.reset() + tokenizer.multi = true + if yyParse(tokenizer) != 0 { + if tokenizer.partialDDL != nil { + tokenizer.ParseTree = tokenizer.partialDDL + return tokenizer.ParseTree, nil + } + return nil, tokenizer.LastError + } + return tokenizer.ParseTree, nil +} + +// SplitStatement returns the first sql statement up to either a ; or EOF +// and the remainder from the given buffer +func SplitStatement(blob string) (string, string, error) { + tokenizer := NewStringTokenizer(blob) + tkn := 0 + for { + tkn, _ = tokenizer.Scan() + if tkn == 0 || tkn == ';' || tkn == eofChar { + break + } + } + if tokenizer.LastError != nil { + return "", "", tokenizer.LastError + } + if tkn == ';' { + return blob[:tokenizer.Position-2], blob[tokenizer.Position-1:], nil + } + return blob, "", nil +} + +// SplitStatementToPieces split raw sql statement that may have multi sql pieces to sql pieces +// returns the sql pieces blob contains; or error if sql cannot be parsed +func SplitStatementToPieces(blob string) (pieces []string, err error) { + pieces = make([]string, 0, 16) + tokenizer := NewStringTokenizer(blob) + + tkn := 0 + var stmt string + stmtBegin := 0 + for { + tkn, _ = tokenizer.Scan() + if tkn == ';' { + stmt = blob[stmtBegin : tokenizer.Position-2] + pieces = append(pieces, stmt) + stmtBegin = tokenizer.Position - 1 + + } else if tkn == 0 || tkn == eofChar { + blobTail := tokenizer.Position - 2 + + if stmtBegin < blobTail { + stmt = blob[stmtBegin : blobTail+1] + pieces = append(pieces, stmt) + } + break + } + } + + err = tokenizer.LastError + return +} + +// SQLNode defines the interface for all nodes +// generated by the parser. +type SQLNode interface { + Format(buf *TrackedBuffer) + // walkSubtree calls visit on all underlying nodes + // of the subtree, but not the current one. Walking + // must be interrupted if visit returns an error. + walkSubtree(visit Visit) error +} + +// Visit defines the signature of a function that +// can be used to visit all nodes of a parse tree. +type Visit func(node SQLNode) (kontinue bool, err error) + +// Walk calls visit on every node. +// If visit returns true, the underlying nodes +// are also visited. If it returns an error, walking +// is interrupted, and the error is returned. +func Walk(visit Visit, nodes ...SQLNode) error { + for _, node := range nodes { + if node == nil { + continue + } + kontinue, err := visit(node) + if err != nil { + return err + } + if kontinue { + err = node.walkSubtree(visit) + if err != nil { + return err + } + } + } + return nil +} + +// String returns a string representation of an SQLNode. +func String(node SQLNode) string { + if node == nil { + return "" + } + + buf := NewTrackedBuffer(nil) + buf.Myprintf("%v", node) + return buf.String() +} + +// Append appends the SQLNode to the buffer. +func Append(buf *bytes.Buffer, node SQLNode) { + tbuf := &TrackedBuffer{ + Buffer: buf, + } + node.Format(tbuf) +} + +// Statement represents a statement. +type Statement interface { + iStatement() + SQLNode +} + +func (*Union) iStatement() {} +func (*Select) iStatement() {} +func (*Stream) iStatement() {} +func (*Insert) iStatement() {} +func (*Update) iStatement() {} +func (*Delete) iStatement() {} +func (*Set) iStatement() {} +func (*DBDDL) iStatement() {} +func (*DDL) iStatement() {} +func (*Show) iStatement() {} +func (*Use) iStatement() {} +func (*Begin) iStatement() {} +func (*Commit) iStatement() {} +func (*Rollback) iStatement() {} +func (*OtherRead) iStatement() {} +func (*OtherAdmin) iStatement() {} + +// ParenSelect can actually not be a top level statement, +// but we have to allow it because it's a requirement +// of SelectStatement. +func (*ParenSelect) iStatement() {} + +// SelectStatement any SELECT statement. +type SelectStatement interface { + iSelectStatement() + iStatement() + iInsertRows() + AddOrder(*Order) + SetLimit(*Limit) + SQLNode +} + +func (*Select) iSelectStatement() {} +func (*Union) iSelectStatement() {} +func (*ParenSelect) iSelectStatement() {} + +// Select represents a SELECT statement. +type Select struct { + Cache string + Comments Comments + Distinct string + Hints string + SelectExprs SelectExprs + From TableExprs + Where *Where + GroupBy GroupBy + Having *Where + OrderBy OrderBy + Limit *Limit + Lock string +} + +// Select.Distinct +const ( + DistinctStr = "distinct " + StraightJoinHint = "straight_join " +) + +// Select.Lock +const ( + ForUpdateStr = " for update" + ShareModeStr = " lock in share mode" +) + +// Select.Cache +const ( + SQLCacheStr = "sql_cache " + SQLNoCacheStr = "sql_no_cache " +) + +// AddOrder adds an order by element +func (node *Select) AddOrder(order *Order) { + node.OrderBy = append(node.OrderBy, order) +} + +// SetLimit sets the limit clause +func (node *Select) SetLimit(limit *Limit) { + node.Limit = limit +} + +// Format formats the node. +func (node *Select) Format(buf *TrackedBuffer) { + buf.Myprintf("select %v%s%s%s%v from %v%v%v%v%v%v%s", + node.Comments, node.Cache, node.Distinct, node.Hints, node.SelectExprs, + node.From, node.Where, + node.GroupBy, node.Having, node.OrderBy, + node.Limit, node.Lock) +} + +func (node *Select) walkSubtree(visit Visit) error { + if node == nil { + return nil + } + return Walk( + visit, + node.Comments, + node.SelectExprs, + node.From, + node.Where, + node.GroupBy, + node.Having, + node.OrderBy, + node.Limit, + ) +} + +// AddWhere adds the boolean expression to the +// WHERE clause as an AND condition. If the expression +// is an OR clause, it parenthesizes it. Currently, +// the OR operator is the only one that's lower precedence +// than AND. +func (node *Select) AddWhere(expr Expr) { + if _, ok := expr.(*OrExpr); ok { + expr = &ParenExpr{Expr: expr} + } + if node.Where == nil { + node.Where = &Where{ + Type: WhereStr, + Expr: expr, + } + return + } + node.Where.Expr = &AndExpr{ + Left: node.Where.Expr, + Right: expr, + } + return +} + +// AddHaving adds the boolean expression to the +// HAVING clause as an AND condition. If the expression +// is an OR clause, it parenthesizes it. Currently, +// the OR operator is the only one that's lower precedence +// than AND. +func (node *Select) AddHaving(expr Expr) { + if _, ok := expr.(*OrExpr); ok { + expr = &ParenExpr{Expr: expr} + } + if node.Having == nil { + node.Having = &Where{ + Type: HavingStr, + Expr: expr, + } + return + } + node.Having.Expr = &AndExpr{ + Left: node.Having.Expr, + Right: expr, + } + return +} + +// ParenSelect is a parenthesized SELECT statement. +type ParenSelect struct { + Select SelectStatement +} + +// AddOrder adds an order by element +func (node *ParenSelect) AddOrder(order *Order) { + panic("unreachable") +} + +// SetLimit sets the limit clause +func (node *ParenSelect) SetLimit(limit *Limit) { + panic("unreachable") +} + +// Format formats the node. +func (node *ParenSelect) Format(buf *TrackedBuffer) { + buf.Myprintf("(%v)", node.Select) +} + +func (node *ParenSelect) walkSubtree(visit Visit) error { + if node == nil { + return nil + } + return Walk( + visit, + node.Select, + ) +} + +// Union represents a UNION statement. +type Union struct { + Type string + Left, Right SelectStatement + OrderBy OrderBy + Limit *Limit + Lock string +} + +// Union.Type +const ( + UnionStr = "union" + UnionAllStr = "union all" + UnionDistinctStr = "union distinct" +) + +// AddOrder adds an order by element +func (node *Union) AddOrder(order *Order) { + node.OrderBy = append(node.OrderBy, order) +} + +// SetLimit sets the limit clause +func (node *Union) SetLimit(limit *Limit) { + node.Limit = limit +} + +// Format formats the node. +func (node *Union) Format(buf *TrackedBuffer) { + buf.Myprintf("%v %s %v%v%v%s", node.Left, node.Type, node.Right, + node.OrderBy, node.Limit, node.Lock) +} + +func (node *Union) walkSubtree(visit Visit) error { + if node == nil { + return nil + } + return Walk( + visit, + node.Left, + node.Right, + ) +} + +// Stream represents a SELECT statement. +type Stream struct { + Comments Comments + SelectExpr SelectExpr + Table TableName +} + +// Format formats the node. +func (node *Stream) Format(buf *TrackedBuffer) { + buf.Myprintf("stream %v%v from %v", + node.Comments, node.SelectExpr, node.Table) +} + +func (node *Stream) walkSubtree(visit Visit) error { + if node == nil { + return nil + } + return Walk( + visit, + node.Comments, + node.SelectExpr, + node.Table, + ) +} + +// Insert represents an INSERT or REPLACE statement. +// Per the MySQL docs, http://dev.mysql.com/doc/refman/5.7/en/replace.html +// Replace is the counterpart to `INSERT IGNORE`, and works exactly like a +// normal INSERT except if the row exists. In that case it first deletes +// the row and re-inserts with new values. For that reason we keep it as an Insert struct. +// Replaces are currently disallowed in sharded schemas because +// of the implications the deletion part may have on vindexes. +// If you add fields here, consider adding them to calls to validateSubquerySamePlan. +type Insert struct { + Action string + Comments Comments + Ignore string + Table TableName + Partitions Partitions + Columns Columns + Rows InsertRows + OnDup OnDup +} + +// DDL strings. +const ( + InsertStr = "insert" + ReplaceStr = "replace" +) + +// Format formats the node. +func (node *Insert) Format(buf *TrackedBuffer) { + buf.Myprintf("%s %v%sinto %v%v%v %v%v", + node.Action, + node.Comments, node.Ignore, + node.Table, node.Partitions, node.Columns, node.Rows, node.OnDup) +} + +func (node *Insert) walkSubtree(visit Visit) error { + if node == nil { + return nil + } + return Walk( + visit, + node.Comments, + node.Table, + node.Columns, + node.Rows, + node.OnDup, + ) +} + +// InsertRows represents the rows for an INSERT statement. +type InsertRows interface { + iInsertRows() + SQLNode +} + +func (*Select) iInsertRows() {} +func (*Union) iInsertRows() {} +func (Values) iInsertRows() {} +func (*ParenSelect) iInsertRows() {} + +// Update represents an UPDATE statement. +// If you add fields here, consider adding them to calls to validateSubquerySamePlan. +type Update struct { + Comments Comments + TableExprs TableExprs + Exprs UpdateExprs + Where *Where + OrderBy OrderBy + Limit *Limit +} + +// Format formats the node. +func (node *Update) Format(buf *TrackedBuffer) { + buf.Myprintf("update %v%v set %v%v%v%v", + node.Comments, node.TableExprs, + node.Exprs, node.Where, node.OrderBy, node.Limit) +} + +func (node *Update) walkSubtree(visit Visit) error { + if node == nil { + return nil + } + return Walk( + visit, + node.Comments, + node.TableExprs, + node.Exprs, + node.Where, + node.OrderBy, + node.Limit, + ) +} + +// Delete represents a DELETE statement. +// If you add fields here, consider adding them to calls to validateSubquerySamePlan. +type Delete struct { + Comments Comments + Targets TableNames + TableExprs TableExprs + Partitions Partitions + Where *Where + OrderBy OrderBy + Limit *Limit +} + +// Format formats the node. +func (node *Delete) Format(buf *TrackedBuffer) { + buf.Myprintf("delete %v", node.Comments) + if node.Targets != nil { + buf.Myprintf("%v ", node.Targets) + } + buf.Myprintf("from %v%v%v%v%v", node.TableExprs, node.Partitions, node.Where, node.OrderBy, node.Limit) +} + +func (node *Delete) walkSubtree(visit Visit) error { + if node == nil { + return nil + } + return Walk( + visit, + node.Comments, + node.Targets, + node.TableExprs, + node.Where, + node.OrderBy, + node.Limit, + ) +} + +// Set represents a SET statement. +type Set struct { + Comments Comments + Exprs SetExprs + Scope string +} + +// Set.Scope or Show.Scope +const ( + SessionStr = "session" + GlobalStr = "global" +) + +// Format formats the node. +func (node *Set) Format(buf *TrackedBuffer) { + if node.Scope == "" { + buf.Myprintf("set %v%v", node.Comments, node.Exprs) + } else { + buf.Myprintf("set %v%s %v", node.Comments, node.Scope, node.Exprs) + } +} + +func (node *Set) walkSubtree(visit Visit) error { + if node == nil { + return nil + } + return Walk( + visit, + node.Comments, + node.Exprs, + ) +} + +// DBDDL represents a CREATE, DROP database statement. +type DBDDL struct { + Action string + DBName string + IfExists bool + Collate string + Charset string +} + +// Format formats the node. +func (node *DBDDL) Format(buf *TrackedBuffer) { + switch node.Action { + case CreateStr: + buf.WriteString(fmt.Sprintf("%s database %s", node.Action, node.DBName)) + case DropStr: + exists := "" + if node.IfExists { + exists = " if exists" + } + buf.WriteString(fmt.Sprintf("%s database%s %v", node.Action, exists, node.DBName)) + } +} + +// walkSubtree walks the nodes of the subtree. +func (node *DBDDL) walkSubtree(visit Visit) error { + return nil +} + +// DDL represents a CREATE, ALTER, DROP, RENAME or TRUNCATE statement. +// Table is set for AlterStr, DropStr, RenameStr, TruncateStr +// NewName is set for AlterStr, CreateStr, RenameStr. +// VindexSpec is set for CreateVindexStr, DropVindexStr, AddColVindexStr, DropColVindexStr +// VindexCols is set for AddColVindexStr +type DDL struct { + Action string + Table TableName + NewName TableName + IfExists bool + TableSpec *TableSpec + PartitionSpec *PartitionSpec + VindexSpec *VindexSpec + VindexCols []ColIdent +} + +// DDL strings. +const ( + CreateStr = "create" + AlterStr = "alter" + DropStr = "drop" + RenameStr = "rename" + TruncateStr = "truncate" + CreateVindexStr = "create vindex" + AddColVindexStr = "add vindex" + DropColVindexStr = "drop vindex" + + // Vindex DDL param to specify the owner of a vindex + VindexOwnerStr = "owner" +) + +// Format formats the node. +func (node *DDL) Format(buf *TrackedBuffer) { + switch node.Action { + case CreateStr: + if node.TableSpec == nil { + buf.Myprintf("%s table %v", node.Action, node.NewName) + } else { + buf.Myprintf("%s table %v %v", node.Action, node.NewName, node.TableSpec) + } + case DropStr: + exists := "" + if node.IfExists { + exists = " if exists" + } + buf.Myprintf("%s table%s %v", node.Action, exists, node.Table) + case RenameStr: + buf.Myprintf("%s table %v to %v", node.Action, node.Table, node.NewName) + case AlterStr: + if node.PartitionSpec != nil { + buf.Myprintf("%s table %v %v", node.Action, node.Table, node.PartitionSpec) + } else { + buf.Myprintf("%s table %v", node.Action, node.Table) + } + case CreateVindexStr: + buf.Myprintf("%s %v %v", node.Action, node.VindexSpec.Name, node.VindexSpec) + case AddColVindexStr: + buf.Myprintf("alter table %v %s %v (", node.Table, node.Action, node.VindexSpec.Name) + for i, col := range node.VindexCols { + if i != 0 { + buf.Myprintf(", %v", col) + } else { + buf.Myprintf("%v", col) + } + } + buf.Myprintf(")") + if node.VindexSpec.Type.String() != "" { + buf.Myprintf(" %v", node.VindexSpec) + } + case DropColVindexStr: + buf.Myprintf("alter table %v %s %v", node.Table, node.Action, node.VindexSpec.Name) + default: + buf.Myprintf("%s table %v", node.Action, node.Table) + } +} + +func (node *DDL) walkSubtree(visit Visit) error { + if node == nil { + return nil + } + return Walk( + visit, + node.Table, + node.NewName, + ) +} + +// Partition strings +const ( + ReorganizeStr = "reorganize partition" +) + +// PartitionSpec describe partition actions (for alter and create) +type PartitionSpec struct { + Action string + Name ColIdent + Definitions []*PartitionDefinition +} + +// Format formats the node. +func (node *PartitionSpec) Format(buf *TrackedBuffer) { + switch node.Action { + case ReorganizeStr: + buf.Myprintf("%s %v into (", node.Action, node.Name) + var prefix string + for _, pd := range node.Definitions { + buf.Myprintf("%s%v", prefix, pd) + prefix = ", " + } + buf.Myprintf(")") + default: + panic("unimplemented") + } +} + +func (node *PartitionSpec) walkSubtree(visit Visit) error { + if node == nil { + return nil + } + if err := Walk(visit, node.Name); err != nil { + return err + } + for _, def := range node.Definitions { + if err := Walk(visit, def); err != nil { + return err + } + } + return nil +} + +// PartitionDefinition describes a very minimal partition definition +type PartitionDefinition struct { + Name ColIdent + Limit Expr + Maxvalue bool +} + +// Format formats the node +func (node *PartitionDefinition) Format(buf *TrackedBuffer) { + if !node.Maxvalue { + buf.Myprintf("partition %v values less than (%v)", node.Name, node.Limit) + } else { + buf.Myprintf("partition %v values less than (maxvalue)", node.Name) + } +} + +func (node *PartitionDefinition) walkSubtree(visit Visit) error { + if node == nil { + return nil + } + return Walk( + visit, + node.Name, + node.Limit, + ) +} + +// TableSpec describes the structure of a table from a CREATE TABLE statement +type TableSpec struct { + Columns []*ColumnDefinition + Indexes []*IndexDefinition + Options string +} + +// Format formats the node. +func (ts *TableSpec) Format(buf *TrackedBuffer) { + buf.Myprintf("(\n") + for i, col := range ts.Columns { + if i == 0 { + buf.Myprintf("\t%v", col) + } else { + buf.Myprintf(",\n\t%v", col) + } + } + for _, idx := range ts.Indexes { + buf.Myprintf(",\n\t%v", idx) + } + + buf.Myprintf("\n)%s", strings.Replace(ts.Options, ", ", ",\n ", -1)) +} + +// AddColumn appends the given column to the list in the spec +func (ts *TableSpec) AddColumn(cd *ColumnDefinition) { + ts.Columns = append(ts.Columns, cd) +} + +// AddIndex appends the given index to the list in the spec +func (ts *TableSpec) AddIndex(id *IndexDefinition) { + ts.Indexes = append(ts.Indexes, id) +} + +func (ts *TableSpec) walkSubtree(visit Visit) error { + if ts == nil { + return nil + } + + for _, n := range ts.Columns { + if err := Walk(visit, n); err != nil { + return err + } + } + + for _, n := range ts.Indexes { + if err := Walk(visit, n); err != nil { + return err + } + } + + return nil +} + +// ColumnDefinition describes a column in a CREATE TABLE statement +type ColumnDefinition struct { + Name ColIdent + Type ColumnType +} + +// Format formats the node. +func (col *ColumnDefinition) Format(buf *TrackedBuffer) { + buf.Myprintf("%v %v", col.Name, &col.Type) +} + +func (col *ColumnDefinition) walkSubtree(visit Visit) error { + if col == nil { + return nil + } + return Walk( + visit, + col.Name, + &col.Type, + ) +} + +// ColumnType represents a sql type in a CREATE TABLE statement +// All optional fields are nil if not specified +type ColumnType struct { + // The base type string + Type string + + // Generic field options. + NotNull BoolVal + Autoincrement BoolVal + Default *SQLVal + OnUpdate *SQLVal + Comment *SQLVal + + // Numeric field options + Length *SQLVal + Unsigned BoolVal + Zerofill BoolVal + Scale *SQLVal + + // Text field options + Charset string + Collate string + + // Enum values + EnumValues []string + + // Key specification + KeyOpt ColumnKeyOption +} + +// Format returns a canonical string representation of the type and all relevant options +func (ct *ColumnType) Format(buf *TrackedBuffer) { + buf.Myprintf("%s", ct.Type) + + if ct.Length != nil && ct.Scale != nil { + buf.Myprintf("(%v,%v)", ct.Length, ct.Scale) + + } else if ct.Length != nil { + buf.Myprintf("(%v)", ct.Length) + } + + if ct.EnumValues != nil { + buf.Myprintf("(%s)", strings.Join(ct.EnumValues, ", ")) + } + + opts := make([]string, 0, 16) + if ct.Unsigned { + opts = append(opts, keywordStrings[UNSIGNED]) + } + if ct.Zerofill { + opts = append(opts, keywordStrings[ZEROFILL]) + } + if ct.Charset != "" { + opts = append(opts, keywordStrings[CHARACTER], keywordStrings[SET], ct.Charset) + } + if ct.Collate != "" { + opts = append(opts, keywordStrings[COLLATE], ct.Collate) + } + if ct.NotNull { + opts = append(opts, keywordStrings[NOT], keywordStrings[NULL]) + } + if ct.Default != nil { + opts = append(opts, keywordStrings[DEFAULT], String(ct.Default)) + } + if ct.OnUpdate != nil { + opts = append(opts, keywordStrings[ON], keywordStrings[UPDATE], String(ct.OnUpdate)) + } + if ct.Autoincrement { + opts = append(opts, keywordStrings[AUTO_INCREMENT]) + } + if ct.Comment != nil { + opts = append(opts, keywordStrings[COMMENT_KEYWORD], String(ct.Comment)) + } + if ct.KeyOpt == colKeyPrimary { + opts = append(opts, keywordStrings[PRIMARY], keywordStrings[KEY]) + } + if ct.KeyOpt == colKeyUnique { + opts = append(opts, keywordStrings[UNIQUE]) + } + if ct.KeyOpt == colKeyUniqueKey { + opts = append(opts, keywordStrings[UNIQUE], keywordStrings[KEY]) + } + if ct.KeyOpt == colKeySpatialKey { + opts = append(opts, keywordStrings[SPATIAL], keywordStrings[KEY]) + } + if ct.KeyOpt == colKey { + opts = append(opts, keywordStrings[KEY]) + } + + if len(opts) != 0 { + buf.Myprintf(" %s", strings.Join(opts, " ")) + } +} + +// DescribeType returns the abbreviated type information as required for +// describe table +func (ct *ColumnType) DescribeType() string { + buf := NewTrackedBuffer(nil) + buf.Myprintf("%s", ct.Type) + if ct.Length != nil && ct.Scale != nil { + buf.Myprintf("(%v,%v)", ct.Length, ct.Scale) + } else if ct.Length != nil { + buf.Myprintf("(%v)", ct.Length) + } + + opts := make([]string, 0, 16) + if ct.Unsigned { + opts = append(opts, keywordStrings[UNSIGNED]) + } + if ct.Zerofill { + opts = append(opts, keywordStrings[ZEROFILL]) + } + if len(opts) != 0 { + buf.Myprintf(" %s", strings.Join(opts, " ")) + } + return buf.String() +} + +// SQLType returns the sqltypes type code for the given column +func (ct *ColumnType) SQLType() querypb.Type { + switch ct.Type { + case keywordStrings[TINYINT]: + if ct.Unsigned { + return sqltypes.Uint8 + } + return sqltypes.Int8 + case keywordStrings[SMALLINT]: + if ct.Unsigned { + return sqltypes.Uint16 + } + return sqltypes.Int16 + case keywordStrings[MEDIUMINT]: + if ct.Unsigned { + return sqltypes.Uint24 + } + return sqltypes.Int24 + case keywordStrings[INT]: + fallthrough + case keywordStrings[INTEGER]: + if ct.Unsigned { + return sqltypes.Uint32 + } + return sqltypes.Int32 + case keywordStrings[BIGINT]: + if ct.Unsigned { + return sqltypes.Uint64 + } + return sqltypes.Int64 + case keywordStrings[TEXT]: + return sqltypes.Text + case keywordStrings[TINYTEXT]: + return sqltypes.Text + case keywordStrings[MEDIUMTEXT]: + return sqltypes.Text + case keywordStrings[LONGTEXT]: + return sqltypes.Text + case keywordStrings[BLOB]: + return sqltypes.Blob + case keywordStrings[TINYBLOB]: + return sqltypes.Blob + case keywordStrings[MEDIUMBLOB]: + return sqltypes.Blob + case keywordStrings[LONGBLOB]: + return sqltypes.Blob + case keywordStrings[CHAR]: + return sqltypes.Char + case keywordStrings[VARCHAR]: + return sqltypes.VarChar + case keywordStrings[BINARY]: + return sqltypes.Binary + case keywordStrings[VARBINARY]: + return sqltypes.VarBinary + case keywordStrings[DATE]: + return sqltypes.Date + case keywordStrings[TIME]: + return sqltypes.Time + case keywordStrings[DATETIME]: + return sqltypes.Datetime + case keywordStrings[TIMESTAMP]: + return sqltypes.Timestamp + case keywordStrings[YEAR]: + return sqltypes.Year + case keywordStrings[FLOAT_TYPE]: + return sqltypes.Float32 + case keywordStrings[DOUBLE]: + return sqltypes.Float64 + case keywordStrings[DECIMAL]: + return sqltypes.Decimal + case keywordStrings[BIT]: + return sqltypes.Bit + case keywordStrings[ENUM]: + return sqltypes.Enum + case keywordStrings[SET]: + return sqltypes.Set + case keywordStrings[JSON]: + return sqltypes.TypeJSON + case keywordStrings[GEOMETRY]: + return sqltypes.Geometry + case keywordStrings[POINT]: + return sqltypes.Geometry + case keywordStrings[LINESTRING]: + return sqltypes.Geometry + case keywordStrings[POLYGON]: + return sqltypes.Geometry + case keywordStrings[GEOMETRYCOLLECTION]: + return sqltypes.Geometry + case keywordStrings[MULTIPOINT]: + return sqltypes.Geometry + case keywordStrings[MULTILINESTRING]: + return sqltypes.Geometry + case keywordStrings[MULTIPOLYGON]: + return sqltypes.Geometry + } + panic("unimplemented type " + ct.Type) +} + +func (ct *ColumnType) walkSubtree(visit Visit) error { + return nil +} + +// IndexDefinition describes an index in a CREATE TABLE statement +type IndexDefinition struct { + Info *IndexInfo + Columns []*IndexColumn + Options []*IndexOption +} + +// Format formats the node. +func (idx *IndexDefinition) Format(buf *TrackedBuffer) { + buf.Myprintf("%v (", idx.Info) + for i, col := range idx.Columns { + if i != 0 { + buf.Myprintf(", %v", col.Column) + } else { + buf.Myprintf("%v", col.Column) + } + if col.Length != nil { + buf.Myprintf("(%v)", col.Length) + } + } + buf.Myprintf(")") + + for _, opt := range idx.Options { + buf.Myprintf(" %s", opt.Name) + if opt.Using != "" { + buf.Myprintf(" %s", opt.Using) + } else { + buf.Myprintf(" %v", opt.Value) + } + } +} + +func (idx *IndexDefinition) walkSubtree(visit Visit) error { + if idx == nil { + return nil + } + + for _, n := range idx.Columns { + if err := Walk(visit, n.Column); err != nil { + return err + } + } + + return nil +} + +// IndexInfo describes the name and type of an index in a CREATE TABLE statement +type IndexInfo struct { + Type string + Name ColIdent + Primary bool + Spatial bool + Unique bool +} + +// Format formats the node. +func (ii *IndexInfo) Format(buf *TrackedBuffer) { + if ii.Primary { + buf.Myprintf("%s", ii.Type) + } else { + buf.Myprintf("%s %v", ii.Type, ii.Name) + } +} + +func (ii *IndexInfo) walkSubtree(visit Visit) error { + return Walk(visit, ii.Name) +} + +// IndexColumn describes a column in an index definition with optional length +type IndexColumn struct { + Column ColIdent + Length *SQLVal +} + +// LengthScaleOption is used for types that have an optional length +// and scale +type LengthScaleOption struct { + Length *SQLVal + Scale *SQLVal +} + +// IndexOption is used for trailing options for indexes: COMMENT, KEY_BLOCK_SIZE, USING +type IndexOption struct { + Name string + Value *SQLVal + Using string +} + +// ColumnKeyOption indicates whether or not the given column is defined as an +// index element and contains the type of the option +type ColumnKeyOption int + +const ( + colKeyNone ColumnKeyOption = iota + colKeyPrimary + colKeySpatialKey + colKeyUnique + colKeyUniqueKey + colKey +) + +// VindexSpec defines a vindex for a CREATE VINDEX or DROP VINDEX statement +type VindexSpec struct { + Name ColIdent + Type ColIdent + Params []VindexParam +} + +// ParseParams parses the vindex parameter list, pulling out the special-case +// "owner" parameter +func (node *VindexSpec) ParseParams() (string, map[string]string) { + var owner string + params := map[string]string{} + for _, p := range node.Params { + if p.Key.Lowered() == VindexOwnerStr { + owner = p.Val + } else { + params[p.Key.String()] = p.Val + } + } + return owner, params +} + +// Format formats the node. The "CREATE VINDEX" preamble was formatted in +// the containing DDL node Format, so this just prints the type, any +// parameters, and optionally the owner +func (node *VindexSpec) Format(buf *TrackedBuffer) { + buf.Myprintf("using %v", node.Type) + + numParams := len(node.Params) + if numParams != 0 { + buf.Myprintf(" with ") + for i, p := range node.Params { + if i != 0 { + buf.Myprintf(", ") + } + buf.Myprintf("%v", p) + } + } +} + +func (node *VindexSpec) walkSubtree(visit Visit) error { + err := Walk(visit, + node.Name, + ) + + if err != nil { + return err + } + + for _, p := range node.Params { + err := Walk(visit, p) + + if err != nil { + return err + } + } + return nil +} + +// VindexParam defines a key/value parameter for a CREATE VINDEX statement +type VindexParam struct { + Key ColIdent + Val string +} + +// Format formats the node. +func (node VindexParam) Format(buf *TrackedBuffer) { + buf.Myprintf("%s=%s", node.Key.String(), node.Val) +} + +func (node VindexParam) walkSubtree(visit Visit) error { + return Walk(visit, + node.Key, + ) +} + +// Show represents a show statement. +type Show struct { + Type string + OnTable TableName + ShowTablesOpt *ShowTablesOpt + Scope string +} + +// Format formats the node. +func (node *Show) Format(buf *TrackedBuffer) { + if node.Type == "tables" && node.ShowTablesOpt != nil { + opt := node.ShowTablesOpt + if opt.DbName != "" { + if opt.Filter != nil { + buf.Myprintf("show %s%stables from %s %v", opt.Extended, opt.Full, opt.DbName, opt.Filter) + } else { + buf.Myprintf("show %s%stables from %s", opt.Extended, opt.Full, opt.DbName) + } + } else { + if opt.Filter != nil { + buf.Myprintf("show %s%stables %v", opt.Extended, opt.Full, opt.Filter) + } else { + buf.Myprintf("show %s%stables", opt.Extended, opt.Full) + } + } + return + } + if node.Scope == "" { + buf.Myprintf("show %s", node.Type) + } else { + buf.Myprintf("show %s %s", node.Scope, node.Type) + } + if node.HasOnTable() { + buf.Myprintf(" on %v", node.OnTable) + } +} + +// HasOnTable returns true if the show statement has an "on" clause +func (node *Show) HasOnTable() bool { + return node.OnTable.Name.v != "" +} + +func (node *Show) walkSubtree(visit Visit) error { + return nil +} + +// ShowTablesOpt is show tables option +type ShowTablesOpt struct { + Extended string + Full string + DbName string + Filter *ShowFilter +} + +// ShowFilter is show tables filter +type ShowFilter struct { + Like string + Filter Expr +} + +// Format formats the node. +func (node *ShowFilter) Format(buf *TrackedBuffer) { + if node.Like != "" { + buf.Myprintf("like '%s'", node.Like) + } else { + buf.Myprintf("where %v", node.Filter) + } +} + +func (node *ShowFilter) walkSubtree(visit Visit) error { + return nil +} + +// Use represents a use statement. +type Use struct { + DBName TableIdent +} + +// Format formats the node. +func (node *Use) Format(buf *TrackedBuffer) { + if node.DBName.v != "" { + buf.Myprintf("use %v", node.DBName) + } else { + buf.Myprintf("use") + } +} + +func (node *Use) walkSubtree(visit Visit) error { + return Walk(visit, node.DBName) +} + +// Begin represents a Begin statement. +type Begin struct{} + +// Format formats the node. +func (node *Begin) Format(buf *TrackedBuffer) { + buf.WriteString("begin") +} + +func (node *Begin) walkSubtree(visit Visit) error { + return nil +} + +// Commit represents a Commit statement. +type Commit struct{} + +// Format formats the node. +func (node *Commit) Format(buf *TrackedBuffer) { + buf.WriteString("commit") +} + +func (node *Commit) walkSubtree(visit Visit) error { + return nil +} + +// Rollback represents a Rollback statement. +type Rollback struct{} + +// Format formats the node. +func (node *Rollback) Format(buf *TrackedBuffer) { + buf.WriteString("rollback") +} + +func (node *Rollback) walkSubtree(visit Visit) error { + return nil +} + +// OtherRead represents a DESCRIBE, or EXPLAIN statement. +// It should be used only as an indicator. It does not contain +// the full AST for the statement. +type OtherRead struct{} + +// Format formats the node. +func (node *OtherRead) Format(buf *TrackedBuffer) { + buf.WriteString("otherread") +} + +func (node *OtherRead) walkSubtree(visit Visit) error { + return nil +} + +// OtherAdmin represents a misc statement that relies on ADMIN privileges, +// such as REPAIR, OPTIMIZE, or TRUNCATE statement. +// It should be used only as an indicator. It does not contain +// the full AST for the statement. +type OtherAdmin struct{} + +// Format formats the node. +func (node *OtherAdmin) Format(buf *TrackedBuffer) { + buf.WriteString("otheradmin") +} + +func (node *OtherAdmin) walkSubtree(visit Visit) error { + return nil +} + +// Comments represents a list of comments. +type Comments [][]byte + +// Format formats the node. +func (node Comments) Format(buf *TrackedBuffer) { + for _, c := range node { + buf.Myprintf("%s ", c) + } +} + +func (node Comments) walkSubtree(visit Visit) error { + return nil +} + +// SelectExprs represents SELECT expressions. +type SelectExprs []SelectExpr + +// Format formats the node. +func (node SelectExprs) Format(buf *TrackedBuffer) { + var prefix string + for _, n := range node { + buf.Myprintf("%s%v", prefix, n) + prefix = ", " + } +} + +func (node SelectExprs) walkSubtree(visit Visit) error { + for _, n := range node { + if err := Walk(visit, n); err != nil { + return err + } + } + return nil +} + +// SelectExpr represents a SELECT expression. +type SelectExpr interface { + iSelectExpr() + SQLNode +} + +func (*StarExpr) iSelectExpr() {} +func (*AliasedExpr) iSelectExpr() {} +func (Nextval) iSelectExpr() {} + +// StarExpr defines a '*' or 'table.*' expression. +type StarExpr struct { + TableName TableName +} + +// Format formats the node. +func (node *StarExpr) Format(buf *TrackedBuffer) { + if !node.TableName.IsEmpty() { + buf.Myprintf("%v.", node.TableName) + } + buf.Myprintf("*") +} + +func (node *StarExpr) walkSubtree(visit Visit) error { + if node == nil { + return nil + } + return Walk( + visit, + node.TableName, + ) +} + +// AliasedExpr defines an aliased SELECT expression. +type AliasedExpr struct { + Expr Expr + As ColIdent +} + +// Format formats the node. +func (node *AliasedExpr) Format(buf *TrackedBuffer) { + buf.Myprintf("%v", node.Expr) + if !node.As.IsEmpty() { + buf.Myprintf(" as %v", node.As) + } +} + +func (node *AliasedExpr) walkSubtree(visit Visit) error { + if node == nil { + return nil + } + return Walk( + visit, + node.Expr, + node.As, + ) +} + +// Nextval defines the NEXT VALUE expression. +type Nextval struct { + Expr Expr +} + +// Format formats the node. +func (node Nextval) Format(buf *TrackedBuffer) { + buf.Myprintf("next %v values", node.Expr) +} + +func (node Nextval) walkSubtree(visit Visit) error { + return Walk(visit, node.Expr) +} + +// Columns represents an insert column list. +type Columns []ColIdent + +// Format formats the node. +func (node Columns) Format(buf *TrackedBuffer) { + if node == nil { + return + } + prefix := "(" + for _, n := range node { + buf.Myprintf("%s%v", prefix, n) + prefix = ", " + } + buf.WriteString(")") +} + +func (node Columns) walkSubtree(visit Visit) error { + for _, n := range node { + if err := Walk(visit, n); err != nil { + return err + } + } + return nil +} + +// FindColumn finds a column in the column list, returning +// the index if it exists or -1 otherwise +func (node Columns) FindColumn(col ColIdent) int { + for i, colName := range node { + if colName.Equal(col) { + return i + } + } + return -1 +} + +// Partitions is a type alias for Columns so we can handle printing efficiently +type Partitions Columns + +// Format formats the node +func (node Partitions) Format(buf *TrackedBuffer) { + if node == nil { + return + } + prefix := " partition (" + for _, n := range node { + buf.Myprintf("%s%v", prefix, n) + prefix = ", " + } + buf.WriteString(")") +} + +func (node Partitions) walkSubtree(visit Visit) error { + for _, n := range node { + if err := Walk(visit, n); err != nil { + return err + } + } + return nil +} + +// TableExprs represents a list of table expressions. +type TableExprs []TableExpr + +// Format formats the node. +func (node TableExprs) Format(buf *TrackedBuffer) { + var prefix string + for _, n := range node { + buf.Myprintf("%s%v", prefix, n) + prefix = ", " + } +} + +func (node TableExprs) walkSubtree(visit Visit) error { + for _, n := range node { + if err := Walk(visit, n); err != nil { + return err + } + } + return nil +} + +// TableExpr represents a table expression. +type TableExpr interface { + iTableExpr() + SQLNode +} + +func (*AliasedTableExpr) iTableExpr() {} +func (*ParenTableExpr) iTableExpr() {} +func (*JoinTableExpr) iTableExpr() {} + +// AliasedTableExpr represents a table expression +// coupled with an optional alias or index hint. +// If As is empty, no alias was used. +type AliasedTableExpr struct { + Expr SimpleTableExpr + Partitions Partitions + As TableIdent + Hints *IndexHints +} + +// Format formats the node. +func (node *AliasedTableExpr) Format(buf *TrackedBuffer) { + buf.Myprintf("%v%v", node.Expr, node.Partitions) + if !node.As.IsEmpty() { + buf.Myprintf(" as %v", node.As) + } + if node.Hints != nil { + // Hint node provides the space padding. + buf.Myprintf("%v", node.Hints) + } +} + +func (node *AliasedTableExpr) walkSubtree(visit Visit) error { + if node == nil { + return nil + } + return Walk( + visit, + node.Expr, + node.As, + node.Hints, + ) +} + +// RemoveHints returns a new AliasedTableExpr with the hints removed. +func (node *AliasedTableExpr) RemoveHints() *AliasedTableExpr { + noHints := *node + noHints.Hints = nil + return &noHints +} + +// SimpleTableExpr represents a simple table expression. +type SimpleTableExpr interface { + iSimpleTableExpr() + SQLNode +} + +func (TableName) iSimpleTableExpr() {} +func (*Subquery) iSimpleTableExpr() {} + +// TableNames is a list of TableName. +type TableNames []TableName + +// Format formats the node. +func (node TableNames) Format(buf *TrackedBuffer) { + var prefix string + for _, n := range node { + buf.Myprintf("%s%v", prefix, n) + prefix = ", " + } +} + +func (node TableNames) walkSubtree(visit Visit) error { + for _, n := range node { + if err := Walk(visit, n); err != nil { + return err + } + } + return nil +} + +// TableName represents a table name. +// Qualifier, if specified, represents a database or keyspace. +// TableName is a value struct whose fields are case sensitive. +// This means two TableName vars can be compared for equality +// and a TableName can also be used as key in a map. +type TableName struct { + Name, Qualifier TableIdent +} + +// Format formats the node. +func (node TableName) Format(buf *TrackedBuffer) { + if node.IsEmpty() { + return + } + if !node.Qualifier.IsEmpty() { + buf.Myprintf("%v.", node.Qualifier) + } + buf.Myprintf("%v", node.Name) +} + +func (node TableName) walkSubtree(visit Visit) error { + return Walk( + visit, + node.Name, + node.Qualifier, + ) +} + +// IsEmpty returns true if TableName is nil or empty. +func (node TableName) IsEmpty() bool { + // If Name is empty, Qualifer is also empty. + return node.Name.IsEmpty() +} + +// ToViewName returns a TableName acceptable for use as a VIEW. VIEW names are +// always lowercase, so ToViewName lowercasese the name. Databases are case-sensitive +// so Qualifier is left untouched. +func (node TableName) ToViewName() TableName { + return TableName{ + Qualifier: node.Qualifier, + Name: NewTableIdent(strings.ToLower(node.Name.v)), + } +} + +// ParenTableExpr represents a parenthesized list of TableExpr. +type ParenTableExpr struct { + Exprs TableExprs +} + +// Format formats the node. +func (node *ParenTableExpr) Format(buf *TrackedBuffer) { + buf.Myprintf("(%v)", node.Exprs) +} + +func (node *ParenTableExpr) walkSubtree(visit Visit) error { + if node == nil { + return nil + } + return Walk( + visit, + node.Exprs, + ) +} + +// JoinCondition represents the join conditions (either a ON or USING clause) +// of a JoinTableExpr. +type JoinCondition struct { + On Expr + Using Columns +} + +// Format formats the node. +func (node JoinCondition) Format(buf *TrackedBuffer) { + if node.On != nil { + buf.Myprintf(" on %v", node.On) + } + if node.Using != nil { + buf.Myprintf(" using %v", node.Using) + } +} + +func (node JoinCondition) walkSubtree(visit Visit) error { + return Walk( + visit, + node.On, + node.Using, + ) +} + +// JoinTableExpr represents a TableExpr that's a JOIN operation. +type JoinTableExpr struct { + LeftExpr TableExpr + Join string + RightExpr TableExpr + Condition JoinCondition +} + +// JoinTableExpr.Join +const ( + JoinStr = "join" + StraightJoinStr = "straight_join" + LeftJoinStr = "left join" + RightJoinStr = "right join" + NaturalJoinStr = "natural join" + NaturalLeftJoinStr = "natural left join" + NaturalRightJoinStr = "natural right join" +) + +// Format formats the node. +func (node *JoinTableExpr) Format(buf *TrackedBuffer) { + buf.Myprintf("%v %s %v%v", node.LeftExpr, node.Join, node.RightExpr, node.Condition) +} + +func (node *JoinTableExpr) walkSubtree(visit Visit) error { + if node == nil { + return nil + } + return Walk( + visit, + node.LeftExpr, + node.RightExpr, + node.Condition, + ) +} + +// IndexHints represents a list of index hints. +type IndexHints struct { + Type string + Indexes []ColIdent +} + +// Index hints. +const ( + UseStr = "use " + IgnoreStr = "ignore " + ForceStr = "force " +) + +// Format formats the node. +func (node *IndexHints) Format(buf *TrackedBuffer) { + buf.Myprintf(" %sindex ", node.Type) + prefix := "(" + for _, n := range node.Indexes { + buf.Myprintf("%s%v", prefix, n) + prefix = ", " + } + buf.Myprintf(")") +} + +func (node *IndexHints) walkSubtree(visit Visit) error { + if node == nil { + return nil + } + for _, n := range node.Indexes { + if err := Walk(visit, n); err != nil { + return err + } + } + return nil +} + +// Where represents a WHERE or HAVING clause. +type Where struct { + Type string + Expr Expr +} + +// Where.Type +const ( + WhereStr = "where" + HavingStr = "having" +) + +// NewWhere creates a WHERE or HAVING clause out +// of a Expr. If the expression is nil, it returns nil. +func NewWhere(typ string, expr Expr) *Where { + if expr == nil { + return nil + } + return &Where{Type: typ, Expr: expr} +} + +// Format formats the node. +func (node *Where) Format(buf *TrackedBuffer) { + if node == nil || node.Expr == nil { + return + } + buf.Myprintf(" %s %v", node.Type, node.Expr) +} + +func (node *Where) walkSubtree(visit Visit) error { + if node == nil { + return nil + } + return Walk( + visit, + node.Expr, + ) +} + +// Expr represents an expression. +type Expr interface { + iExpr() + // replace replaces any subexpression that matches + // from with to. The implementation can use the + // replaceExprs convenience function. + replace(from, to Expr) bool + SQLNode +} + +func (*AndExpr) iExpr() {} +func (*OrExpr) iExpr() {} +func (*NotExpr) iExpr() {} +func (*ParenExpr) iExpr() {} +func (*ComparisonExpr) iExpr() {} +func (*RangeCond) iExpr() {} +func (*IsExpr) iExpr() {} +func (*ExistsExpr) iExpr() {} +func (*SQLVal) iExpr() {} +func (*NullVal) iExpr() {} +func (BoolVal) iExpr() {} +func (*ColName) iExpr() {} +func (ValTuple) iExpr() {} +func (*Subquery) iExpr() {} +func (ListArg) iExpr() {} +func (*BinaryExpr) iExpr() {} +func (*UnaryExpr) iExpr() {} +func (*IntervalExpr) iExpr() {} +func (*CollateExpr) iExpr() {} +func (*FuncExpr) iExpr() {} +func (*CaseExpr) iExpr() {} +func (*ValuesFuncExpr) iExpr() {} +func (*ConvertExpr) iExpr() {} +func (*SubstrExpr) iExpr() {} +func (*ConvertUsingExpr) iExpr() {} +func (*MatchExpr) iExpr() {} +func (*GroupConcatExpr) iExpr() {} +func (*Default) iExpr() {} + +// ReplaceExpr finds the from expression from root +// and replaces it with to. If from matches root, +// then to is returned. +func ReplaceExpr(root, from, to Expr) Expr { + if root == from { + return to + } + root.replace(from, to) + return root +} + +// replaceExprs is a convenience function used by implementors +// of the replace method. +func replaceExprs(from, to Expr, exprs ...*Expr) bool { + for _, expr := range exprs { + if *expr == nil { + continue + } + if *expr == from { + *expr = to + return true + } + if (*expr).replace(from, to) { + return true + } + } + return false +} + +// Exprs represents a list of value expressions. +// It's not a valid expression because it's not parenthesized. +type Exprs []Expr + +// Format formats the node. +func (node Exprs) Format(buf *TrackedBuffer) { + var prefix string + for _, n := range node { + buf.Myprintf("%s%v", prefix, n) + prefix = ", " + } +} + +func (node Exprs) walkSubtree(visit Visit) error { + for _, n := range node { + if err := Walk(visit, n); err != nil { + return err + } + } + return nil +} + +// AndExpr represents an AND expression. +type AndExpr struct { + Left, Right Expr +} + +// Format formats the node. +func (node *AndExpr) Format(buf *TrackedBuffer) { + buf.Myprintf("%v and %v", node.Left, node.Right) +} + +func (node *AndExpr) walkSubtree(visit Visit) error { + if node == nil { + return nil + } + return Walk( + visit, + node.Left, + node.Right, + ) +} + +func (node *AndExpr) replace(from, to Expr) bool { + return replaceExprs(from, to, &node.Left, &node.Right) +} + +// OrExpr represents an OR expression. +type OrExpr struct { + Left, Right Expr +} + +// Format formats the node. +func (node *OrExpr) Format(buf *TrackedBuffer) { + buf.Myprintf("%v or %v", node.Left, node.Right) +} + +func (node *OrExpr) walkSubtree(visit Visit) error { + if node == nil { + return nil + } + return Walk( + visit, + node.Left, + node.Right, + ) +} + +func (node *OrExpr) replace(from, to Expr) bool { + return replaceExprs(from, to, &node.Left, &node.Right) +} + +// NotExpr represents a NOT expression. +type NotExpr struct { + Expr Expr +} + +// Format formats the node. +func (node *NotExpr) Format(buf *TrackedBuffer) { + buf.Myprintf("not %v", node.Expr) +} + +func (node *NotExpr) walkSubtree(visit Visit) error { + if node == nil { + return nil + } + return Walk( + visit, + node.Expr, + ) +} + +func (node *NotExpr) replace(from, to Expr) bool { + return replaceExprs(from, to, &node.Expr) +} + +// ParenExpr represents a parenthesized boolean expression. +type ParenExpr struct { + Expr Expr +} + +// Format formats the node. +func (node *ParenExpr) Format(buf *TrackedBuffer) { + buf.Myprintf("(%v)", node.Expr) +} + +func (node *ParenExpr) walkSubtree(visit Visit) error { + if node == nil { + return nil + } + return Walk( + visit, + node.Expr, + ) +} + +func (node *ParenExpr) replace(from, to Expr) bool { + return replaceExprs(from, to, &node.Expr) +} + +// ComparisonExpr represents a two-value comparison expression. +type ComparisonExpr struct { + Operator string + Left, Right Expr + Escape Expr +} + +// ComparisonExpr.Operator +const ( + EqualStr = "=" + LessThanStr = "<" + GreaterThanStr = ">" + LessEqualStr = "<=" + GreaterEqualStr = ">=" + NotEqualStr = "!=" + NullSafeEqualStr = "<=>" + InStr = "in" + NotInStr = "not in" + LikeStr = "like" + NotLikeStr = "not like" + RegexpStr = "regexp" + NotRegexpStr = "not regexp" + JSONExtractOp = "->" + JSONUnquoteExtractOp = "->>" +) + +// Format formats the node. +func (node *ComparisonExpr) Format(buf *TrackedBuffer) { + buf.Myprintf("%v %s %v", node.Left, node.Operator, node.Right) + if node.Escape != nil { + buf.Myprintf(" escape %v", node.Escape) + } +} + +func (node *ComparisonExpr) walkSubtree(visit Visit) error { + if node == nil { + return nil + } + return Walk( + visit, + node.Left, + node.Right, + node.Escape, + ) +} + +func (node *ComparisonExpr) replace(from, to Expr) bool { + return replaceExprs(from, to, &node.Left, &node.Right, &node.Escape) +} + +// RangeCond represents a BETWEEN or a NOT BETWEEN expression. +type RangeCond struct { + Operator string + Left Expr + From, To Expr +} + +// RangeCond.Operator +const ( + BetweenStr = "between" + NotBetweenStr = "not between" +) + +// Format formats the node. +func (node *RangeCond) Format(buf *TrackedBuffer) { + buf.Myprintf("%v %s %v and %v", node.Left, node.Operator, node.From, node.To) +} + +func (node *RangeCond) walkSubtree(visit Visit) error { + if node == nil { + return nil + } + return Walk( + visit, + node.Left, + node.From, + node.To, + ) +} + +func (node *RangeCond) replace(from, to Expr) bool { + return replaceExprs(from, to, &node.Left, &node.From, &node.To) +} + +// IsExpr represents an IS ... or an IS NOT ... expression. +type IsExpr struct { + Operator string + Expr Expr +} + +// IsExpr.Operator +const ( + IsNullStr = "is null" + IsNotNullStr = "is not null" + IsTrueStr = "is true" + IsNotTrueStr = "is not true" + IsFalseStr = "is false" + IsNotFalseStr = "is not false" +) + +// Format formats the node. +func (node *IsExpr) Format(buf *TrackedBuffer) { + buf.Myprintf("%v %s", node.Expr, node.Operator) +} + +func (node *IsExpr) walkSubtree(visit Visit) error { + if node == nil { + return nil + } + return Walk( + visit, + node.Expr, + ) +} + +func (node *IsExpr) replace(from, to Expr) bool { + return replaceExprs(from, to, &node.Expr) +} + +// ExistsExpr represents an EXISTS expression. +type ExistsExpr struct { + Subquery *Subquery +} + +// Format formats the node. +func (node *ExistsExpr) Format(buf *TrackedBuffer) { + buf.Myprintf("exists %v", node.Subquery) +} + +func (node *ExistsExpr) walkSubtree(visit Visit) error { + if node == nil { + return nil + } + return Walk( + visit, + node.Subquery, + ) +} + +func (node *ExistsExpr) replace(from, to Expr) bool { + return false +} + +// ExprFromValue converts the given Value into an Expr or returns an error. +func ExprFromValue(value sqltypes.Value) (Expr, error) { + // The type checks here follow the rules defined in sqltypes/types.go. + switch { + case value.Type() == sqltypes.Null: + return &NullVal{}, nil + case value.IsIntegral(): + return NewIntVal(value.ToBytes()), nil + case value.IsFloat() || value.Type() == sqltypes.Decimal: + return NewFloatVal(value.ToBytes()), nil + case value.IsQuoted(): + return NewStrVal(value.ToBytes()), nil + default: + // We cannot support sqltypes.Expression, or any other invalid type. + return nil, fmt.Errorf("cannot convert value %v to AST", value) + } +} + +// ValType specifies the type for SQLVal. +type ValType int + +// These are the possible Valtype values. +// HexNum represents a 0x... value. It cannot +// be treated as a simple value because it can +// be interpreted differently depending on the +// context. +const ( + StrVal = ValType(iota) + IntVal + FloatVal + HexNum + HexVal + ValArg + BitVal +) + +// SQLVal represents a single value. +type SQLVal struct { + Type ValType + Val []byte +} + +// NewStrVal builds a new StrVal. +func NewStrVal(in []byte) *SQLVal { + return &SQLVal{Type: StrVal, Val: in} +} + +// NewIntVal builds a new IntVal. +func NewIntVal(in []byte) *SQLVal { + return &SQLVal{Type: IntVal, Val: in} +} + +// NewFloatVal builds a new FloatVal. +func NewFloatVal(in []byte) *SQLVal { + return &SQLVal{Type: FloatVal, Val: in} +} + +// NewHexNum builds a new HexNum. +func NewHexNum(in []byte) *SQLVal { + return &SQLVal{Type: HexNum, Val: in} +} + +// NewHexVal builds a new HexVal. +func NewHexVal(in []byte) *SQLVal { + return &SQLVal{Type: HexVal, Val: in} +} + +// NewBitVal builds a new BitVal containing a bit literal. +func NewBitVal(in []byte) *SQLVal { + return &SQLVal{Type: BitVal, Val: in} +} + +// NewValArg builds a new ValArg. +func NewValArg(in []byte) *SQLVal { + return &SQLVal{Type: ValArg, Val: in} +} + +// Format formats the node. +func (node *SQLVal) Format(buf *TrackedBuffer) { + switch node.Type { + case StrVal: + sqltypes.MakeTrusted(sqltypes.VarBinary, node.Val).EncodeSQL(buf) + case IntVal, FloatVal, HexNum: + buf.Myprintf("%s", []byte(node.Val)) + case HexVal: + buf.Myprintf("X'%s'", []byte(node.Val)) + case BitVal: + buf.Myprintf("B'%s'", []byte(node.Val)) + case ValArg: + buf.WriteArg(string(node.Val)) + default: + panic("unexpected") + } +} + +func (node *SQLVal) walkSubtree(visit Visit) error { + return nil +} + +func (node *SQLVal) replace(from, to Expr) bool { + return false +} + +// HexDecode decodes the hexval into bytes. +func (node *SQLVal) HexDecode() ([]byte, error) { + dst := make([]byte, hex.DecodedLen(len([]byte(node.Val)))) + _, err := hex.Decode(dst, []byte(node.Val)) + if err != nil { + return nil, err + } + return dst, err +} + +// NullVal represents a NULL value. +type NullVal struct{} + +// Format formats the node. +func (node *NullVal) Format(buf *TrackedBuffer) { + buf.Myprintf("null") +} + +func (node *NullVal) walkSubtree(visit Visit) error { + return nil +} + +func (node *NullVal) replace(from, to Expr) bool { + return false +} + +// BoolVal is true or false. +type BoolVal bool + +// Format formats the node. +func (node BoolVal) Format(buf *TrackedBuffer) { + if node { + buf.Myprintf("true") + } else { + buf.Myprintf("false") + } +} + +func (node BoolVal) walkSubtree(visit Visit) error { + return nil +} + +func (node BoolVal) replace(from, to Expr) bool { + return false +} + +// ColName represents a column name. +type ColName struct { + // Metadata is not populated by the parser. + // It's a placeholder for analyzers to store + // additional data, typically info about which + // table or column this node references. + Metadata interface{} + Name ColIdent + Qualifier TableName +} + +// Format formats the node. +func (node *ColName) Format(buf *TrackedBuffer) { + if !node.Qualifier.IsEmpty() { + buf.Myprintf("%v.", node.Qualifier) + } + buf.Myprintf("%v", node.Name) +} + +func (node *ColName) walkSubtree(visit Visit) error { + if node == nil { + return nil + } + return Walk( + visit, + node.Name, + node.Qualifier, + ) +} + +func (node *ColName) replace(from, to Expr) bool { + return false +} + +// Equal returns true if the column names match. +func (node *ColName) Equal(c *ColName) bool { + // Failsafe: ColName should not be empty. + if node == nil || c == nil { + return false + } + return node.Name.Equal(c.Name) && node.Qualifier == c.Qualifier +} + +// ColTuple represents a list of column values. +// It can be ValTuple, Subquery, ListArg. +type ColTuple interface { + iColTuple() + Expr +} + +func (ValTuple) iColTuple() {} +func (*Subquery) iColTuple() {} +func (ListArg) iColTuple() {} + +// ValTuple represents a tuple of actual values. +type ValTuple Exprs + +// Format formats the node. +func (node ValTuple) Format(buf *TrackedBuffer) { + buf.Myprintf("(%v)", Exprs(node)) +} + +func (node ValTuple) walkSubtree(visit Visit) error { + return Walk(visit, Exprs(node)) +} + +func (node ValTuple) replace(from, to Expr) bool { + for i := range node { + if replaceExprs(from, to, &node[i]) { + return true + } + } + return false +} + +// Subquery represents a subquery. +type Subquery struct { + Select SelectStatement +} + +// Format formats the node. +func (node *Subquery) Format(buf *TrackedBuffer) { + buf.Myprintf("(%v)", node.Select) +} + +func (node *Subquery) walkSubtree(visit Visit) error { + if node == nil { + return nil + } + return Walk( + visit, + node.Select, + ) +} + +func (node *Subquery) replace(from, to Expr) bool { + return false +} + +// ListArg represents a named list argument. +type ListArg []byte + +// Format formats the node. +func (node ListArg) Format(buf *TrackedBuffer) { + buf.WriteArg(string(node)) +} + +func (node ListArg) walkSubtree(visit Visit) error { + return nil +} + +func (node ListArg) replace(from, to Expr) bool { + return false +} + +// BinaryExpr represents a binary value expression. +type BinaryExpr struct { + Operator string + Left, Right Expr +} + +// BinaryExpr.Operator +const ( + BitAndStr = "&" + BitOrStr = "|" + BitXorStr = "^" + PlusStr = "+" + MinusStr = "-" + MultStr = "*" + DivStr = "/" + IntDivStr = "div" + ModStr = "%" + ShiftLeftStr = "<<" + ShiftRightStr = ">>" +) + +// Format formats the node. +func (node *BinaryExpr) Format(buf *TrackedBuffer) { + buf.Myprintf("%v %s %v", node.Left, node.Operator, node.Right) +} + +func (node *BinaryExpr) walkSubtree(visit Visit) error { + if node == nil { + return nil + } + return Walk( + visit, + node.Left, + node.Right, + ) +} + +func (node *BinaryExpr) replace(from, to Expr) bool { + return replaceExprs(from, to, &node.Left, &node.Right) +} + +// UnaryExpr represents a unary value expression. +type UnaryExpr struct { + Operator string + Expr Expr +} + +// UnaryExpr.Operator +const ( + UPlusStr = "+" + UMinusStr = "-" + TildaStr = "~" + BangStr = "!" + BinaryStr = "binary " + UBinaryStr = "_binary " +) + +// Format formats the node. +func (node *UnaryExpr) Format(buf *TrackedBuffer) { + if _, unary := node.Expr.(*UnaryExpr); unary { + buf.Myprintf("%s %v", node.Operator, node.Expr) + return + } + buf.Myprintf("%s%v", node.Operator, node.Expr) +} + +func (node *UnaryExpr) walkSubtree(visit Visit) error { + if node == nil { + return nil + } + return Walk( + visit, + node.Expr, + ) +} + +func (node *UnaryExpr) replace(from, to Expr) bool { + return replaceExprs(from, to, &node.Expr) +} + +// IntervalExpr represents a date-time INTERVAL expression. +type IntervalExpr struct { + Expr Expr + Unit string +} + +// Format formats the node. +func (node *IntervalExpr) Format(buf *TrackedBuffer) { + buf.Myprintf("interval %v %s", node.Expr, node.Unit) +} + +func (node *IntervalExpr) walkSubtree(visit Visit) error { + if node == nil { + return nil + } + return Walk( + visit, + node.Expr, + ) +} + +func (node *IntervalExpr) replace(from, to Expr) bool { + return replaceExprs(from, to, &node.Expr) +} + +// CollateExpr represents dynamic collate operator. +type CollateExpr struct { + Expr Expr + Charset string +} + +// Format formats the node. +func (node *CollateExpr) Format(buf *TrackedBuffer) { + buf.Myprintf("%v collate %s", node.Expr, node.Charset) +} + +func (node *CollateExpr) walkSubtree(visit Visit) error { + if node == nil { + return nil + } + return Walk( + visit, + node.Expr, + ) +} + +func (node *CollateExpr) replace(from, to Expr) bool { + return replaceExprs(from, to, &node.Expr) +} + +// FuncExpr represents a function call. +type FuncExpr struct { + Qualifier TableIdent + Name ColIdent + Distinct bool + Exprs SelectExprs +} + +// Format formats the node. +func (node *FuncExpr) Format(buf *TrackedBuffer) { + var distinct string + if node.Distinct { + distinct = "distinct " + } + if !node.Qualifier.IsEmpty() { + buf.Myprintf("%v.", node.Qualifier) + } + // Function names should not be back-quoted even + // if they match a reserved word. So, print the + // name as is. + buf.Myprintf("%s(%s%v)", node.Name.String(), distinct, node.Exprs) +} + +func (node *FuncExpr) walkSubtree(visit Visit) error { + if node == nil { + return nil + } + return Walk( + visit, + node.Qualifier, + node.Name, + node.Exprs, + ) +} + +func (node *FuncExpr) replace(from, to Expr) bool { + for _, sel := range node.Exprs { + aliased, ok := sel.(*AliasedExpr) + if !ok { + continue + } + if replaceExprs(from, to, &aliased.Expr) { + return true + } + } + return false +} + +// Aggregates is a map of all aggregate functions. +var Aggregates = map[string]bool{ + "avg": true, + "bit_and": true, + "bit_or": true, + "bit_xor": true, + "count": true, + "group_concat": true, + "max": true, + "min": true, + "std": true, + "stddev_pop": true, + "stddev_samp": true, + "stddev": true, + "sum": true, + "var_pop": true, + "var_samp": true, + "variance": true, +} + +// IsAggregate returns true if the function is an aggregate. +func (node *FuncExpr) IsAggregate() bool { + return Aggregates[node.Name.Lowered()] +} + +// GroupConcatExpr represents a call to GROUP_CONCAT +type GroupConcatExpr struct { + Distinct string + Exprs SelectExprs + OrderBy OrderBy + Separator string +} + +// Format formats the node +func (node *GroupConcatExpr) Format(buf *TrackedBuffer) { + buf.Myprintf("group_concat(%s%v%v%s)", node.Distinct, node.Exprs, node.OrderBy, node.Separator) +} + +func (node *GroupConcatExpr) walkSubtree(visit Visit) error { + if node == nil { + return nil + } + return Walk( + visit, + node.Exprs, + node.OrderBy, + ) +} + +func (node *GroupConcatExpr) replace(from, to Expr) bool { + for _, sel := range node.Exprs { + aliased, ok := sel.(*AliasedExpr) + if !ok { + continue + } + if replaceExprs(from, to, &aliased.Expr) { + return true + } + } + for _, order := range node.OrderBy { + if replaceExprs(from, to, &order.Expr) { + return true + } + } + return false +} + +// ValuesFuncExpr represents a function call. +type ValuesFuncExpr struct { + Name *ColName +} + +// Format formats the node. +func (node *ValuesFuncExpr) Format(buf *TrackedBuffer) { + buf.Myprintf("values(%v)", node.Name) +} + +func (node *ValuesFuncExpr) walkSubtree(visit Visit) error { + if node == nil { + return nil + } + return Walk( + visit, + node.Name, + ) +} + +func (node *ValuesFuncExpr) replace(from, to Expr) bool { + return false +} + +// SubstrExpr represents a call to SubstrExpr(column, value_expression) or SubstrExpr(column, value_expression,value_expression) +// also supported syntax SubstrExpr(column from value_expression for value_expression) +type SubstrExpr struct { + Name *ColName + From Expr + To Expr +} + +// Format formats the node. +func (node *SubstrExpr) Format(buf *TrackedBuffer) { + + if node.To == nil { + buf.Myprintf("substr(%v, %v)", node.Name, node.From) + } else { + buf.Myprintf("substr(%v, %v, %v)", node.Name, node.From, node.To) + } +} + +func (node *SubstrExpr) replace(from, to Expr) bool { + return replaceExprs(from, to, &node.From, &node.To) +} + +func (node *SubstrExpr) walkSubtree(visit Visit) error { + if node == nil { + return nil + } + return Walk( + visit, + node.Name, + node.From, + node.To, + ) +} + +// ConvertExpr represents a call to CONVERT(expr, type) +// or it's equivalent CAST(expr AS type). Both are rewritten to the former. +type ConvertExpr struct { + Expr Expr + Type *ConvertType +} + +// Format formats the node. +func (node *ConvertExpr) Format(buf *TrackedBuffer) { + buf.Myprintf("convert(%v, %v)", node.Expr, node.Type) +} + +func (node *ConvertExpr) walkSubtree(visit Visit) error { + if node == nil { + return nil + } + return Walk( + visit, + node.Expr, + node.Type, + ) +} + +func (node *ConvertExpr) replace(from, to Expr) bool { + return replaceExprs(from, to, &node.Expr) +} + +// ConvertUsingExpr represents a call to CONVERT(expr USING charset). +type ConvertUsingExpr struct { + Expr Expr + Type string +} + +// Format formats the node. +func (node *ConvertUsingExpr) Format(buf *TrackedBuffer) { + buf.Myprintf("convert(%v using %s)", node.Expr, node.Type) +} + +func (node *ConvertUsingExpr) walkSubtree(visit Visit) error { + if node == nil { + return nil + } + return Walk( + visit, + node.Expr, + ) +} + +func (node *ConvertUsingExpr) replace(from, to Expr) bool { + return replaceExprs(from, to, &node.Expr) +} + +// ConvertType represents the type in call to CONVERT(expr, type) +type ConvertType struct { + Type string + Length *SQLVal + Scale *SQLVal + Operator string + Charset string +} + +// this string is "character set" and this comment is required +const ( + CharacterSetStr = " character set" +) + +// Format formats the node. +func (node *ConvertType) Format(buf *TrackedBuffer) { + buf.Myprintf("%s", node.Type) + if node.Length != nil { + buf.Myprintf("(%v", node.Length) + if node.Scale != nil { + buf.Myprintf(", %v", node.Scale) + } + buf.Myprintf(")") + } + if node.Charset != "" { + buf.Myprintf("%s %s", node.Operator, node.Charset) + } +} + +func (node *ConvertType) walkSubtree(visit Visit) error { + return nil +} + +// MatchExpr represents a call to the MATCH function +type MatchExpr struct { + Columns SelectExprs + Expr Expr + Option string +} + +// MatchExpr.Option +const ( + BooleanModeStr = " in boolean mode" + NaturalLanguageModeStr = " in natural language mode" + NaturalLanguageModeWithQueryExpansionStr = " in natural language mode with query expansion" + QueryExpansionStr = " with query expansion" +) + +// Format formats the node +func (node *MatchExpr) Format(buf *TrackedBuffer) { + buf.Myprintf("match(%v) against (%v%s)", node.Columns, node.Expr, node.Option) +} + +func (node *MatchExpr) walkSubtree(visit Visit) error { + if node == nil { + return nil + } + return Walk( + visit, + node.Columns, + node.Expr, + ) +} + +func (node *MatchExpr) replace(from, to Expr) bool { + for _, sel := range node.Columns { + aliased, ok := sel.(*AliasedExpr) + if !ok { + continue + } + if replaceExprs(from, to, &aliased.Expr) { + return true + } + } + return replaceExprs(from, to, &node.Expr) +} + +// CaseExpr represents a CASE expression. +type CaseExpr struct { + Expr Expr + Whens []*When + Else Expr +} + +// Format formats the node. +func (node *CaseExpr) Format(buf *TrackedBuffer) { + buf.Myprintf("case ") + if node.Expr != nil { + buf.Myprintf("%v ", node.Expr) + } + for _, when := range node.Whens { + buf.Myprintf("%v ", when) + } + if node.Else != nil { + buf.Myprintf("else %v ", node.Else) + } + buf.Myprintf("end") +} + +func (node *CaseExpr) walkSubtree(visit Visit) error { + if node == nil { + return nil + } + if err := Walk(visit, node.Expr); err != nil { + return err + } + for _, n := range node.Whens { + if err := Walk(visit, n); err != nil { + return err + } + } + return Walk(visit, node.Else) +} + +func (node *CaseExpr) replace(from, to Expr) bool { + for _, when := range node.Whens { + if replaceExprs(from, to, &when.Cond, &when.Val) { + return true + } + } + return replaceExprs(from, to, &node.Expr, &node.Else) +} + +// Default represents a DEFAULT expression. +type Default struct { + ColName string +} + +// Format formats the node. +func (node *Default) Format(buf *TrackedBuffer) { + buf.Myprintf("default") + if node.ColName != "" { + buf.Myprintf("(%s)", node.ColName) + } +} + +func (node *Default) walkSubtree(visit Visit) error { + return nil +} + +func (node *Default) replace(from, to Expr) bool { + return false +} + +// When represents a WHEN sub-expression. +type When struct { + Cond Expr + Val Expr +} + +// Format formats the node. +func (node *When) Format(buf *TrackedBuffer) { + buf.Myprintf("when %v then %v", node.Cond, node.Val) +} + +func (node *When) walkSubtree(visit Visit) error { + if node == nil { + return nil + } + return Walk( + visit, + node.Cond, + node.Val, + ) +} + +// GroupBy represents a GROUP BY clause. +type GroupBy []Expr + +// Format formats the node. +func (node GroupBy) Format(buf *TrackedBuffer) { + prefix := " group by " + for _, n := range node { + buf.Myprintf("%s%v", prefix, n) + prefix = ", " + } +} + +func (node GroupBy) walkSubtree(visit Visit) error { + for _, n := range node { + if err := Walk(visit, n); err != nil { + return err + } + } + return nil +} + +// OrderBy represents an ORDER By clause. +type OrderBy []*Order + +// Format formats the node. +func (node OrderBy) Format(buf *TrackedBuffer) { + prefix := " order by " + for _, n := range node { + buf.Myprintf("%s%v", prefix, n) + prefix = ", " + } +} + +func (node OrderBy) walkSubtree(visit Visit) error { + for _, n := range node { + if err := Walk(visit, n); err != nil { + return err + } + } + return nil +} + +// Order represents an ordering expression. +type Order struct { + Expr Expr + Direction string +} + +// Order.Direction +const ( + AscScr = "asc" + DescScr = "desc" +) + +// Format formats the node. +func (node *Order) Format(buf *TrackedBuffer) { + if node, ok := node.Expr.(*NullVal); ok { + buf.Myprintf("%v", node) + return + } + if node, ok := node.Expr.(*FuncExpr); ok { + if node.Name.Lowered() == "rand" { + buf.Myprintf("%v", node) + return + } + } + + buf.Myprintf("%v %s", node.Expr, node.Direction) +} + +func (node *Order) walkSubtree(visit Visit) error { + if node == nil { + return nil + } + return Walk( + visit, + node.Expr, + ) +} + +// Limit represents a LIMIT clause. +type Limit struct { + Offset, Rowcount Expr +} + +// Format formats the node. +func (node *Limit) Format(buf *TrackedBuffer) { + if node == nil { + return + } + buf.Myprintf(" limit ") + if node.Offset != nil { + buf.Myprintf("%v, ", node.Offset) + } + buf.Myprintf("%v", node.Rowcount) +} + +func (node *Limit) walkSubtree(visit Visit) error { + if node == nil { + return nil + } + return Walk( + visit, + node.Offset, + node.Rowcount, + ) +} + +// Values represents a VALUES clause. +type Values []ValTuple + +// Format formats the node. +func (node Values) Format(buf *TrackedBuffer) { + prefix := "values " + for _, n := range node { + buf.Myprintf("%s%v", prefix, n) + prefix = ", " + } +} + +func (node Values) walkSubtree(visit Visit) error { + for _, n := range node { + if err := Walk(visit, n); err != nil { + return err + } + } + return nil +} + +// UpdateExprs represents a list of update expressions. +type UpdateExprs []*UpdateExpr + +// Format formats the node. +func (node UpdateExprs) Format(buf *TrackedBuffer) { + var prefix string + for _, n := range node { + buf.Myprintf("%s%v", prefix, n) + prefix = ", " + } +} + +func (node UpdateExprs) walkSubtree(visit Visit) error { + for _, n := range node { + if err := Walk(visit, n); err != nil { + return err + } + } + return nil +} + +// UpdateExpr represents an update expression. +type UpdateExpr struct { + Name *ColName + Expr Expr +} + +// Format formats the node. +func (node *UpdateExpr) Format(buf *TrackedBuffer) { + buf.Myprintf("%v = %v", node.Name, node.Expr) +} + +func (node *UpdateExpr) walkSubtree(visit Visit) error { + if node == nil { + return nil + } + return Walk( + visit, + node.Name, + node.Expr, + ) +} + +// SetExprs represents a list of set expressions. +type SetExprs []*SetExpr + +// Format formats the node. +func (node SetExprs) Format(buf *TrackedBuffer) { + var prefix string + for _, n := range node { + buf.Myprintf("%s%v", prefix, n) + prefix = ", " + } +} + +func (node SetExprs) walkSubtree(visit Visit) error { + for _, n := range node { + if err := Walk(visit, n); err != nil { + return err + } + } + return nil +} + +// SetExpr represents a set expression. +type SetExpr struct { + Name ColIdent + Expr Expr +} + +// Format formats the node. +func (node *SetExpr) Format(buf *TrackedBuffer) { + // We don't have to backtick set variable names. + if node.Name.EqualString("charset") || node.Name.EqualString("names") { + buf.Myprintf("%s %v", node.Name.String(), node.Expr) + } else { + buf.Myprintf("%s = %v", node.Name.String(), node.Expr) + } +} + +func (node *SetExpr) walkSubtree(visit Visit) error { + if node == nil { + return nil + } + return Walk( + visit, + node.Name, + node.Expr, + ) +} + +// OnDup represents an ON DUPLICATE KEY clause. +type OnDup UpdateExprs + +// Format formats the node. +func (node OnDup) Format(buf *TrackedBuffer) { + if node == nil { + return + } + buf.Myprintf(" on duplicate key update %v", UpdateExprs(node)) +} + +func (node OnDup) walkSubtree(visit Visit) error { + return Walk(visit, UpdateExprs(node)) +} + +// ColIdent is a case insensitive SQL identifier. It will be escaped with +// backquotes if necessary. +type ColIdent struct { + // This artifact prevents this struct from being compared + // with itself. It consumes no space as long as it's not the + // last field in the struct. + _ [0]struct{ _ []byte } + val, lowered string +} + +// NewColIdent makes a new ColIdent. +func NewColIdent(str string) ColIdent { + return ColIdent{ + val: str, + } +} + +// Format formats the node. +func (node ColIdent) Format(buf *TrackedBuffer) { + formatID(buf, node.val, node.Lowered()) +} + +func (node ColIdent) walkSubtree(visit Visit) error { + return nil +} + +// IsEmpty returns true if the name is empty. +func (node ColIdent) IsEmpty() bool { + return node.val == "" +} + +// String returns the unescaped column name. It must +// not be used for SQL generation. Use sqlparser.String +// instead. The Stringer conformance is for usage +// in templates. +func (node ColIdent) String() string { + return node.val +} + +// CompliantName returns a compliant id name +// that can be used for a bind var. +func (node ColIdent) CompliantName() string { + return compliantName(node.val) +} + +// Lowered returns a lower-cased column name. +// This function should generally be used only for optimizing +// comparisons. +func (node ColIdent) Lowered() string { + if node.val == "" { + return "" + } + if node.lowered == "" { + node.lowered = strings.ToLower(node.val) + } + return node.lowered +} + +// Equal performs a case-insensitive compare. +func (node ColIdent) Equal(in ColIdent) bool { + return node.Lowered() == in.Lowered() +} + +// EqualString performs a case-insensitive compare with str. +func (node ColIdent) EqualString(str string) bool { + return node.Lowered() == strings.ToLower(str) +} + +// MarshalJSON marshals into JSON. +func (node ColIdent) MarshalJSON() ([]byte, error) { + return json.Marshal(node.val) +} + +// UnmarshalJSON unmarshals from JSON. +func (node *ColIdent) UnmarshalJSON(b []byte) error { + var result string + err := json.Unmarshal(b, &result) + if err != nil { + return err + } + node.val = result + return nil +} + +// TableIdent is a case sensitive SQL identifier. It will be escaped with +// backquotes if necessary. +type TableIdent struct { + v string +} + +// NewTableIdent creates a new TableIdent. +func NewTableIdent(str string) TableIdent { + return TableIdent{v: str} +} + +// Format formats the node. +func (node TableIdent) Format(buf *TrackedBuffer) { + formatID(buf, node.v, strings.ToLower(node.v)) +} + +func (node TableIdent) walkSubtree(visit Visit) error { + return nil +} + +// IsEmpty returns true if TabIdent is empty. +func (node TableIdent) IsEmpty() bool { + return node.v == "" +} + +// String returns the unescaped table name. It must +// not be used for SQL generation. Use sqlparser.String +// instead. The Stringer conformance is for usage +// in templates. +func (node TableIdent) String() string { + return node.v +} + +// CompliantName returns a compliant id name +// that can be used for a bind var. +func (node TableIdent) CompliantName() string { + return compliantName(node.v) +} + +// MarshalJSON marshals into JSON. +func (node TableIdent) MarshalJSON() ([]byte, error) { + return json.Marshal(node.v) +} + +// UnmarshalJSON unmarshals from JSON. +func (node *TableIdent) UnmarshalJSON(b []byte) error { + var result string + err := json.Unmarshal(b, &result) + if err != nil { + return err + } + node.v = result + return nil +} + +// Backtick produces a backticked literal given an input string. +func Backtick(in string) string { + var buf bytes.Buffer + buf.WriteByte('`') + for _, c := range in { + buf.WriteRune(c) + if c == '`' { + buf.WriteByte('`') + } + } + buf.WriteByte('`') + return buf.String() +} + +func formatID(buf *TrackedBuffer, original, lowered string) { + isDbSystemVariable := false + if len(original) > 1 && original[:2] == "@@" { + isDbSystemVariable = true + } + + for i, c := range original { + if !isLetter(uint16(c)) && (!isDbSystemVariable || !isCarat(uint16(c))) { + if i == 0 || !isDigit(uint16(c)) { + goto mustEscape + } + } + } + if _, ok := keywords[lowered]; ok { + goto mustEscape + } + buf.Myprintf("%s", original) + return + +mustEscape: + buf.WriteByte('`') + for _, c := range original { + buf.WriteRune(c) + if c == '`' { + buf.WriteByte('`') + } + } + buf.WriteByte('`') +} + +func compliantName(in string) string { + var buf bytes.Buffer + for i, c := range in { + if !isLetter(uint16(c)) { + if i == 0 || !isDigit(uint16(c)) { + buf.WriteByte('_') + continue + } + } + buf.WriteRune(c) + } + return buf.String() +} diff --git a/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/ast_test.go b/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/ast_test.go new file mode 100644 index 00000000..c02d882e --- /dev/null +++ b/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/ast_test.go @@ -0,0 +1,636 @@ +/* +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 sqlparser + +import ( + "bytes" + "encoding/json" + "reflect" + "strings" + "testing" + "unsafe" + + "github.com/xwb1989/sqlparser/dependency/sqltypes" +) + +func TestAppend(t *testing.T) { + query := "select * from t where a = 1" + tree, err := Parse(query) + if err != nil { + t.Error(err) + } + var b bytes.Buffer + Append(&b, tree) + got := b.String() + want := query + if got != want { + t.Errorf("Append: %s, want %s", got, want) + } + Append(&b, tree) + got = b.String() + want = query + query + if got != want { + t.Errorf("Append: %s, want %s", got, want) + } +} + +func TestSelect(t *testing.T) { + tree, err := Parse("select * from t where a = 1") + if err != nil { + t.Error(err) + } + expr := tree.(*Select).Where.Expr + + sel := &Select{} + sel.AddWhere(expr) + buf := NewTrackedBuffer(nil) + sel.Where.Format(buf) + want := " where a = 1" + if buf.String() != want { + t.Errorf("where: %q, want %s", buf.String(), want) + } + sel.AddWhere(expr) + buf = NewTrackedBuffer(nil) + sel.Where.Format(buf) + want = " where a = 1 and a = 1" + if buf.String() != want { + t.Errorf("where: %q, want %s", buf.String(), want) + } + sel = &Select{} + sel.AddHaving(expr) + buf = NewTrackedBuffer(nil) + sel.Having.Format(buf) + want = " having a = 1" + if buf.String() != want { + t.Errorf("having: %q, want %s", buf.String(), want) + } + sel.AddHaving(expr) + buf = NewTrackedBuffer(nil) + sel.Having.Format(buf) + want = " having a = 1 and a = 1" + if buf.String() != want { + t.Errorf("having: %q, want %s", buf.String(), want) + } + + // OR clauses must be parenthesized. + tree, err = Parse("select * from t where a = 1 or b = 1") + if err != nil { + t.Error(err) + } + expr = tree.(*Select).Where.Expr + sel = &Select{} + sel.AddWhere(expr) + buf = NewTrackedBuffer(nil) + sel.Where.Format(buf) + want = " where (a = 1 or b = 1)" + if buf.String() != want { + t.Errorf("where: %q, want %s", buf.String(), want) + } + sel = &Select{} + sel.AddHaving(expr) + buf = NewTrackedBuffer(nil) + sel.Having.Format(buf) + want = " having (a = 1 or b = 1)" + if buf.String() != want { + t.Errorf("having: %q, want %s", buf.String(), want) + } +} + +func TestRemoveHints(t *testing.T) { + for _, query := range []string{ + "select * from t use index (i)", + "select * from t force index (i)", + } { + tree, err := Parse(query) + if err != nil { + t.Fatal(err) + } + sel := tree.(*Select) + sel.From = TableExprs{ + sel.From[0].(*AliasedTableExpr).RemoveHints(), + } + buf := NewTrackedBuffer(nil) + sel.Format(buf) + if got, want := buf.String(), "select * from t"; got != want { + t.Errorf("stripped query: %s, want %s", got, want) + } + } +} + +func TestAddOrder(t *testing.T) { + src, err := Parse("select foo, bar from baz order by foo") + if err != nil { + t.Error(err) + } + order := src.(*Select).OrderBy[0] + dst, err := Parse("select * from t") + if err != nil { + t.Error(err) + } + dst.(*Select).AddOrder(order) + buf := NewTrackedBuffer(nil) + dst.Format(buf) + want := "select * from t order by foo asc" + if buf.String() != want { + t.Errorf("order: %q, want %s", buf.String(), want) + } + dst, err = Parse("select * from t union select * from s") + if err != nil { + t.Error(err) + } + dst.(*Union).AddOrder(order) + buf = NewTrackedBuffer(nil) + dst.Format(buf) + want = "select * from t union select * from s order by foo asc" + if buf.String() != want { + t.Errorf("order: %q, want %s", buf.String(), want) + } +} + +func TestSetLimit(t *testing.T) { + src, err := Parse("select foo, bar from baz limit 4") + if err != nil { + t.Error(err) + } + limit := src.(*Select).Limit + dst, err := Parse("select * from t") + if err != nil { + t.Error(err) + } + dst.(*Select).SetLimit(limit) + buf := NewTrackedBuffer(nil) + dst.Format(buf) + want := "select * from t limit 4" + if buf.String() != want { + t.Errorf("limit: %q, want %s", buf.String(), want) + } + dst, err = Parse("select * from t union select * from s") + if err != nil { + t.Error(err) + } + dst.(*Union).SetLimit(limit) + buf = NewTrackedBuffer(nil) + dst.Format(buf) + want = "select * from t union select * from s limit 4" + if buf.String() != want { + t.Errorf("order: %q, want %s", buf.String(), want) + } +} + +func TestWhere(t *testing.T) { + var w *Where + buf := NewTrackedBuffer(nil) + w.Format(buf) + if buf.String() != "" { + t.Errorf("w.Format(nil): %q, want \"\"", buf.String()) + } + w = NewWhere(WhereStr, nil) + buf = NewTrackedBuffer(nil) + w.Format(buf) + if buf.String() != "" { + t.Errorf("w.Format(&Where{nil}: %q, want \"\"", buf.String()) + } +} + +func TestIsAggregate(t *testing.T) { + f := FuncExpr{Name: NewColIdent("avg")} + if !f.IsAggregate() { + t.Error("IsAggregate: false, want true") + } + + f = FuncExpr{Name: NewColIdent("Avg")} + if !f.IsAggregate() { + t.Error("IsAggregate: false, want true") + } + + f = FuncExpr{Name: NewColIdent("foo")} + if f.IsAggregate() { + t.Error("IsAggregate: true, want false") + } +} + +func TestReplaceExpr(t *testing.T) { + tcases := []struct { + in, out string + }{{ + in: "select * from t where (select a from b)", + out: ":a", + }, { + in: "select * from t where (select a from b) and b", + out: ":a and b", + }, { + in: "select * from t where a and (select a from b)", + out: "a and :a", + }, { + in: "select * from t where (select a from b) or b", + out: ":a or b", + }, { + in: "select * from t where a or (select a from b)", + out: "a or :a", + }, { + in: "select * from t where not (select a from b)", + out: "not :a", + }, { + in: "select * from t where ((select a from b))", + out: "(:a)", + }, { + in: "select * from t where (select a from b) = 1", + out: ":a = 1", + }, { + in: "select * from t where a = (select a from b)", + out: "a = :a", + }, { + in: "select * from t where a like b escape (select a from b)", + out: "a like b escape :a", + }, { + in: "select * from t where (select a from b) between a and b", + out: ":a between a and b", + }, { + in: "select * from t where a between (select a from b) and b", + out: "a between :a and b", + }, { + in: "select * from t where a between b and (select a from b)", + out: "a between b and :a", + }, { + in: "select * from t where (select a from b) is null", + out: ":a is null", + }, { + // exists should not replace. + in: "select * from t where exists (select a from b)", + out: "exists (select a from b)", + }, { + in: "select * from t where a in ((select a from b), 1)", + out: "a in (:a, 1)", + }, { + in: "select * from t where a in (0, (select a from b), 1)", + out: "a in (0, :a, 1)", + }, { + in: "select * from t where (select a from b) + 1", + out: ":a + 1", + }, { + in: "select * from t where 1+(select a from b)", + out: "1 + :a", + }, { + in: "select * from t where -(select a from b)", + out: "-:a", + }, { + in: "select * from t where interval (select a from b) aa", + out: "interval :a aa", + }, { + in: "select * from t where (select a from b) collate utf8", + out: ":a collate utf8", + }, { + in: "select * from t where func((select a from b), 1)", + out: "func(:a, 1)", + }, { + in: "select * from t where func(1, (select a from b), 1)", + out: "func(1, :a, 1)", + }, { + in: "select * from t where group_concat((select a from b), 1 order by a)", + out: "group_concat(:a, 1 order by a asc)", + }, { + in: "select * from t where group_concat(1 order by (select a from b), a)", + out: "group_concat(1 order by :a asc, a asc)", + }, { + in: "select * from t where group_concat(1 order by a, (select a from b))", + out: "group_concat(1 order by a asc, :a asc)", + }, { + in: "select * from t where substr(a, (select a from b), b)", + out: "substr(a, :a, b)", + }, { + in: "select * from t where substr(a, b, (select a from b))", + out: "substr(a, b, :a)", + }, { + in: "select * from t where convert((select a from b), json)", + out: "convert(:a, json)", + }, { + in: "select * from t where convert((select a from b) using utf8)", + out: "convert(:a using utf8)", + }, { + in: "select * from t where match((select a from b), 1) against (a)", + out: "match(:a, 1) against (a)", + }, { + in: "select * from t where match(1, (select a from b), 1) against (a)", + out: "match(1, :a, 1) against (a)", + }, { + in: "select * from t where match(1, a, 1) against ((select a from b))", + out: "match(1, a, 1) against (:a)", + }, { + in: "select * from t where case (select a from b) when a then b when b then c else d end", + out: "case :a when a then b when b then c else d end", + }, { + in: "select * from t where case a when (select a from b) then b when b then c else d end", + out: "case a when :a then b when b then c else d end", + }, { + in: "select * from t where case a when b then (select a from b) when b then c else d end", + out: "case a when b then :a when b then c else d end", + }, { + in: "select * from t where case a when b then c when (select a from b) then c else d end", + out: "case a when b then c when :a then c else d end", + }, { + in: "select * from t where case a when b then c when d then c else (select a from b) end", + out: "case a when b then c when d then c else :a end", + }} + to := NewValArg([]byte(":a")) + for _, tcase := range tcases { + tree, err := Parse(tcase.in) + if err != nil { + t.Fatal(err) + } + var from *Subquery + _ = Walk(func(node SQLNode) (kontinue bool, err error) { + if sq, ok := node.(*Subquery); ok { + from = sq + return false, nil + } + return true, nil + }, tree) + if from == nil { + t.Fatalf("from is nil for %s", tcase.in) + } + expr := ReplaceExpr(tree.(*Select).Where.Expr, from, to) + got := String(expr) + if tcase.out != got { + t.Errorf("ReplaceExpr(%s): %s, want %s", tcase.in, got, tcase.out) + } + } +} + +func TestExprFromValue(t *testing.T) { + tcases := []struct { + in sqltypes.Value + out SQLNode + err string + }{{ + in: sqltypes.NULL, + out: &NullVal{}, + }, { + in: sqltypes.NewInt64(1), + out: NewIntVal([]byte("1")), + }, { + in: sqltypes.NewFloat64(1.1), + out: NewFloatVal([]byte("1.1")), + }, { + in: sqltypes.MakeTrusted(sqltypes.Decimal, []byte("1.1")), + out: NewFloatVal([]byte("1.1")), + }, { + in: sqltypes.NewVarChar("aa"), + out: NewStrVal([]byte("aa")), + }, { + in: sqltypes.MakeTrusted(sqltypes.Expression, []byte("rand()")), + err: "cannot convert value EXPRESSION(rand()) to AST", + }} + for _, tcase := range tcases { + got, err := ExprFromValue(tcase.in) + if tcase.err != "" { + if err == nil || err.Error() != tcase.err { + t.Errorf("ExprFromValue(%v) err: %v, want %s", tcase.in, err, tcase.err) + } + continue + } + if err != nil { + t.Error(err) + } + if got, want := got, tcase.out; !reflect.DeepEqual(got, want) { + t.Errorf("ExprFromValue(%v): %v, want %s", tcase.in, got, want) + } + } +} + +func TestColNameEqual(t *testing.T) { + var c1, c2 *ColName + if c1.Equal(c2) { + t.Error("nil columns equal, want unequal") + } + c1 = &ColName{ + Name: NewColIdent("aa"), + } + c2 = &ColName{ + Name: NewColIdent("bb"), + } + if c1.Equal(c2) { + t.Error("columns equal, want unequal") + } + c2.Name = NewColIdent("aa") + if !c1.Equal(c2) { + t.Error("columns unequal, want equal") + } +} + +func TestColIdent(t *testing.T) { + str := NewColIdent("Ab") + if str.String() != "Ab" { + t.Errorf("String=%s, want Ab", str.String()) + } + if str.String() != "Ab" { + t.Errorf("Val=%s, want Ab", str.String()) + } + if str.Lowered() != "ab" { + t.Errorf("Val=%s, want ab", str.Lowered()) + } + if !str.Equal(NewColIdent("aB")) { + t.Error("str.Equal(NewColIdent(aB))=false, want true") + } + if !str.EqualString("ab") { + t.Error("str.EqualString(ab)=false, want true") + } + str = NewColIdent("") + if str.Lowered() != "" { + t.Errorf("Val=%s, want \"\"", str.Lowered()) + } +} + +func TestColIdentMarshal(t *testing.T) { + str := NewColIdent("Ab") + b, err := json.Marshal(str) + if err != nil { + t.Fatal(err) + } + got := string(b) + want := `"Ab"` + if got != want { + t.Errorf("json.Marshal()= %s, want %s", got, want) + } + var out ColIdent + if err := json.Unmarshal(b, &out); err != nil { + t.Errorf("Unmarshal err: %v, want nil", err) + } + if !reflect.DeepEqual(out, str) { + t.Errorf("Unmarshal: %v, want %v", out, str) + } +} + +func TestColIdentSize(t *testing.T) { + size := unsafe.Sizeof(NewColIdent("")) + want := 2 * unsafe.Sizeof("") + if size != want { + t.Errorf("Size of ColIdent: %d, want 32", want) + } +} + +func TestTableIdentMarshal(t *testing.T) { + str := NewTableIdent("Ab") + b, err := json.Marshal(str) + if err != nil { + t.Fatal(err) + } + got := string(b) + want := `"Ab"` + if got != want { + t.Errorf("json.Marshal()= %s, want %s", got, want) + } + var out TableIdent + if err := json.Unmarshal(b, &out); err != nil { + t.Errorf("Unmarshal err: %v, want nil", err) + } + if !reflect.DeepEqual(out, str) { + t.Errorf("Unmarshal: %v, want %v", out, str) + } +} + +func TestHexDecode(t *testing.T) { + testcase := []struct { + in, out string + }{{ + in: "313233", + out: "123", + }, { + in: "ag", + out: "encoding/hex: invalid byte: U+0067 'g'", + }, { + in: "777", + out: "encoding/hex: odd length hex string", + }} + for _, tc := range testcase { + out, err := newHexVal(tc.in).HexDecode() + if err != nil { + if err.Error() != tc.out { + t.Errorf("Decode(%q): %v, want %s", tc.in, err, tc.out) + } + continue + } + if !bytes.Equal(out, []byte(tc.out)) { + t.Errorf("Decode(%q): %s, want %s", tc.in, out, tc.out) + } + } +} + +func TestCompliantName(t *testing.T) { + testcases := []struct { + in, out string + }{{ + in: "aa", + out: "aa", + }, { + in: "1a", + out: "_a", + }, { + in: "a1", + out: "a1", + }, { + in: "a.b", + out: "a_b", + }, { + in: ".ab", + out: "_ab", + }} + for _, tc := range testcases { + out := NewColIdent(tc.in).CompliantName() + if out != tc.out { + t.Errorf("ColIdent(%s).CompliantNamt: %s, want %s", tc.in, out, tc.out) + } + out = NewTableIdent(tc.in).CompliantName() + if out != tc.out { + t.Errorf("TableIdent(%s).CompliantNamt: %s, want %s", tc.in, out, tc.out) + } + } +} + +func TestColumns_FindColumn(t *testing.T) { + cols := Columns{NewColIdent("a"), NewColIdent("c"), NewColIdent("b"), NewColIdent("0")} + + testcases := []struct { + in string + out int + }{{ + in: "a", + out: 0, + }, { + in: "b", + out: 2, + }, + { + in: "0", + out: 3, + }, + { + in: "f", + out: -1, + }} + + for _, tc := range testcases { + val := cols.FindColumn(NewColIdent(tc.in)) + if val != tc.out { + t.Errorf("FindColumn(%s): %d, want %d", tc.in, val, tc.out) + } + } +} + +func TestSplitStatementToPieces(t *testing.T) { + testcases := []struct { + input string + output string + }{{ + input: "select * from table", + }, { + input: "select * from table1; select * from table2;", + output: "select * from table1; select * from table2", + }, { + input: "select * from /* comment ; */ table;", + output: "select * from /* comment ; */ table", + }, { + input: "select * from table where semi = ';';", + output: "select * from table where semi = ';'", + }, { + input: "select * from table1;--comment;\nselect * from table2;", + output: "select * from table1;--comment;\nselect * from table2", + }, { + input: "CREATE TABLE `total_data` (`id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'id', " + + "`region` varchar(32) NOT NULL COMMENT 'region name, like zh; th; kepler'," + + "`data_size` bigint NOT NULL DEFAULT '0' COMMENT 'data size;'," + + "`createtime` datetime NOT NULL DEFAULT NOW() COMMENT 'create time;'," + + "`comment` varchar(100) NOT NULL DEFAULT '' COMMENT 'comment'," + + "PRIMARY KEY (`id`))", + }} + + for _, tcase := range testcases { + if tcase.output == "" { + tcase.output = tcase.input + } + + stmtPieces, err := SplitStatementToPieces(tcase.input) + if err != nil { + t.Errorf("input: %s, err: %v", tcase.input, err) + continue + } + + out := strings.Join(stmtPieces, ";") + if out != tcase.output { + t.Errorf("out: %s, want %s", out, tcase.output) + } + } +} diff --git a/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/comments.go b/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/comments.go new file mode 100644 index 00000000..a0f7f1b4 --- /dev/null +++ b/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/comments.go @@ -0,0 +1,293 @@ +/* +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 sqlparser + +import ( + "strconv" + "strings" + "unicode" +) + +const ( + // DirectiveMultiShardAutocommit is the query comment directive to allow + // single round trip autocommit with a multi-shard statement. + DirectiveMultiShardAutocommit = "MULTI_SHARD_AUTOCOMMIT" + // DirectiveSkipQueryPlanCache skips query plan cache when set. + DirectiveSkipQueryPlanCache = "SKIP_QUERY_PLAN_CACHE" + // DirectiveQueryTimeout sets a query timeout in vtgate. Only supported for SELECTS. + DirectiveQueryTimeout = "QUERY_TIMEOUT_MS" +) + +func isNonSpace(r rune) bool { + return !unicode.IsSpace(r) +} + +// leadingCommentEnd returns the first index after all leading comments, or +// 0 if there are no leading comments. +func leadingCommentEnd(text string) (end int) { + hasComment := false + pos := 0 + for pos < len(text) { + // Eat up any whitespace. Trailing whitespace will be considered part of + // the leading comments. + nextVisibleOffset := strings.IndexFunc(text[pos:], isNonSpace) + if nextVisibleOffset < 0 { + break + } + pos += nextVisibleOffset + remainingText := text[pos:] + + // Found visible characters. Look for '/*' at the beginning + // and '*/' somewhere after that. + if len(remainingText) < 4 || remainingText[:2] != "/*" { + break + } + commentLength := 4 + strings.Index(remainingText[2:], "*/") + if commentLength < 4 { + // Missing end comment :/ + break + } + + hasComment = true + pos += commentLength + } + + if hasComment { + return pos + } + return 0 +} + +// trailingCommentStart returns the first index of trailing comments. +// If there are no trailing comments, returns the length of the input string. +func trailingCommentStart(text string) (start int) { + hasComment := false + reducedLen := len(text) + for reducedLen > 0 { + // Eat up any whitespace. Leading whitespace will be considered part of + // the trailing comments. + nextReducedLen := strings.LastIndexFunc(text[:reducedLen], isNonSpace) + 1 + if nextReducedLen == 0 { + break + } + reducedLen = nextReducedLen + if reducedLen < 4 || text[reducedLen-2:reducedLen] != "*/" { + break + } + + // Find the beginning of the comment + startCommentPos := strings.LastIndex(text[:reducedLen-2], "/*") + if startCommentPos < 0 { + // Badly formatted sql :/ + break + } + + hasComment = true + reducedLen = startCommentPos + } + + if hasComment { + return reducedLen + } + return len(text) +} + +// MarginComments holds the leading and trailing comments that surround a query. +type MarginComments struct { + Leading string + Trailing string +} + +// SplitMarginComments pulls out any leading or trailing comments from a raw sql query. +// This function also trims leading (if there's a comment) and trailing whitespace. +func SplitMarginComments(sql string) (query string, comments MarginComments) { + trailingStart := trailingCommentStart(sql) + leadingEnd := leadingCommentEnd(sql[:trailingStart]) + comments = MarginComments{ + Leading: strings.TrimLeftFunc(sql[:leadingEnd], unicode.IsSpace), + Trailing: strings.TrimRightFunc(sql[trailingStart:], unicode.IsSpace), + } + return strings.TrimFunc(sql[leadingEnd:trailingStart], unicode.IsSpace), comments +} + +// StripLeadingComments trims the SQL string and removes any leading comments +func StripLeadingComments(sql string) string { + sql = strings.TrimFunc(sql, unicode.IsSpace) + + for hasCommentPrefix(sql) { + switch sql[0] { + case '/': + // Multi line comment + index := strings.Index(sql, "*/") + if index <= 1 { + return sql + } + // don't strip /*! ... */ or /*!50700 ... */ + if len(sql) > 2 && sql[2] == '!' { + return sql + } + sql = sql[index+2:] + case '-': + // Single line comment + index := strings.Index(sql, "\n") + if index == -1 { + return sql + } + sql = sql[index+1:] + } + + sql = strings.TrimFunc(sql, unicode.IsSpace) + } + + return sql +} + +func hasCommentPrefix(sql string) bool { + return len(sql) > 1 && ((sql[0] == '/' && sql[1] == '*') || (sql[0] == '-' && sql[1] == '-')) +} + +// ExtractMysqlComment extracts the version and SQL from a comment-only query +// such as /*!50708 sql here */ +func ExtractMysqlComment(sql string) (version string, innerSQL string) { + sql = sql[3 : len(sql)-2] + + digitCount := 0 + endOfVersionIndex := strings.IndexFunc(sql, func(c rune) bool { + digitCount++ + return !unicode.IsDigit(c) || digitCount == 6 + }) + version = sql[0:endOfVersionIndex] + innerSQL = strings.TrimFunc(sql[endOfVersionIndex:], unicode.IsSpace) + + return version, innerSQL +} + +const commentDirectivePreamble = "/*vt+" + +// CommentDirectives is the parsed representation for execution directives +// conveyed in query comments +type CommentDirectives map[string]interface{} + +// ExtractCommentDirectives parses the comment list for any execution directives +// of the form: +// +// /*vt+ OPTION_ONE=1 OPTION_TWO OPTION_THREE=abcd */ +// +// It returns the map of the directive values or nil if there aren't any. +func ExtractCommentDirectives(comments Comments) CommentDirectives { + if comments == nil { + return nil + } + + var vals map[string]interface{} + + for _, comment := range comments { + commentStr := string(comment) + if commentStr[0:5] != commentDirectivePreamble { + continue + } + + if vals == nil { + vals = make(map[string]interface{}) + } + + // Split on whitespace and ignore the first and last directive + // since they contain the comment start/end + directives := strings.Fields(commentStr) + for i := 1; i < len(directives)-1; i++ { + directive := directives[i] + sep := strings.IndexByte(directive, '=') + + // No value is equivalent to a true boolean + if sep == -1 { + vals[directive] = true + continue + } + + strVal := directive[sep+1:] + directive = directive[:sep] + + intVal, err := strconv.Atoi(strVal) + if err == nil { + vals[directive] = intVal + continue + } + + boolVal, err := strconv.ParseBool(strVal) + if err == nil { + vals[directive] = boolVal + continue + } + + vals[directive] = strVal + } + } + return vals +} + +// IsSet checks the directive map for the named directive and returns +// true if the directive is set and has a true/false or 0/1 value +func (d CommentDirectives) IsSet(key string) bool { + if d == nil { + return false + } + + val, ok := d[key] + if !ok { + return false + } + + boolVal, ok := val.(bool) + if ok { + return boolVal + } + + intVal, ok := val.(int) + if ok { + return intVal == 1 + } + return false +} + +// SkipQueryPlanCacheDirective returns true if skip query plan cache directive is set to true in query. +func SkipQueryPlanCacheDirective(stmt Statement) bool { + switch stmt := stmt.(type) { + case *Select: + directives := ExtractCommentDirectives(stmt.Comments) + if directives.IsSet(DirectiveSkipQueryPlanCache) { + return true + } + case *Insert: + directives := ExtractCommentDirectives(stmt.Comments) + if directives.IsSet(DirectiveSkipQueryPlanCache) { + return true + } + case *Update: + directives := ExtractCommentDirectives(stmt.Comments) + if directives.IsSet(DirectiveSkipQueryPlanCache) { + return true + } + case *Delete: + directives := ExtractCommentDirectives(stmt.Comments) + if directives.IsSet(DirectiveSkipQueryPlanCache) { + return true + } + default: + return false + } + return false +} diff --git a/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/comments_test.go b/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/comments_test.go new file mode 100644 index 00000000..430293bf --- /dev/null +++ b/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/comments_test.go @@ -0,0 +1,375 @@ +/* +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 sqlparser + +import ( + "reflect" + "testing" +) + +func TestSplitComments(t *testing.T) { + var testCases = []struct { + input, outSQL, outLeadingComments, outTrailingComments string + }{{ + input: "/", + outSQL: "/", + outLeadingComments: "", + outTrailingComments: "", + }, { + input: "*/", + outSQL: "*/", + outLeadingComments: "", + outTrailingComments: "", + }, { + input: "/*/", + outSQL: "/*/", + outLeadingComments: "", + outTrailingComments: "", + }, { + input: "a*/", + outSQL: "a*/", + outLeadingComments: "", + outTrailingComments: "", + }, { + input: "*a*/", + outSQL: "*a*/", + outLeadingComments: "", + outTrailingComments: "", + }, { + input: "**a*/", + outSQL: "**a*/", + outLeadingComments: "", + outTrailingComments: "", + }, { + input: "/*b**a*/", + outSQL: "", + outLeadingComments: "", + outTrailingComments: "/*b**a*/", + }, { + input: "/*a*/", + outSQL: "", + outLeadingComments: "", + outTrailingComments: "/*a*/", + }, { + input: "/**/", + outSQL: "", + outLeadingComments: "", + outTrailingComments: "/**/", + }, { + input: "/*b*/ /*a*/", + outSQL: "", + outLeadingComments: "", + outTrailingComments: "/*b*/ /*a*/", + }, { + input: "/* before */ foo /* bar */", + outSQL: "foo", + outLeadingComments: "/* before */ ", + outTrailingComments: " /* bar */", + }, { + input: "/* before1 */ /* before2 */ foo /* after1 */ /* after2 */", + outSQL: "foo", + outLeadingComments: "/* before1 */ /* before2 */ ", + outTrailingComments: " /* after1 */ /* after2 */", + }, { + input: "/** before */ foo /** bar */", + outSQL: "foo", + outLeadingComments: "/** before */ ", + outTrailingComments: " /** bar */", + }, { + input: "/*** before */ foo /*** bar */", + outSQL: "foo", + outLeadingComments: "/*** before */ ", + outTrailingComments: " /*** bar */", + }, { + input: "/** before **/ foo /** bar **/", + outSQL: "foo", + outLeadingComments: "/** before **/ ", + outTrailingComments: " /** bar **/", + }, { + input: "/*** before ***/ foo /*** bar ***/", + outSQL: "foo", + outLeadingComments: "/*** before ***/ ", + outTrailingComments: " /*** bar ***/", + }, { + input: " /*** before ***/ foo /*** bar ***/ ", + outSQL: "foo", + outLeadingComments: "/*** before ***/ ", + outTrailingComments: " /*** bar ***/", + }, { + input: "*** bar ***/", + outSQL: "*** bar ***/", + outLeadingComments: "", + outTrailingComments: "", + }, { + input: " foo ", + outSQL: "foo", + outLeadingComments: "", + outTrailingComments: "", + }} + for _, testCase := range testCases { + gotSQL, gotComments := SplitMarginComments(testCase.input) + gotLeadingComments, gotTrailingComments := gotComments.Leading, gotComments.Trailing + + if gotSQL != testCase.outSQL { + t.Errorf("test input: '%s', got SQL\n%+v, want\n%+v", testCase.input, gotSQL, testCase.outSQL) + } + if gotLeadingComments != testCase.outLeadingComments { + t.Errorf("test input: '%s', got LeadingComments\n%+v, want\n%+v", testCase.input, gotLeadingComments, testCase.outLeadingComments) + } + if gotTrailingComments != testCase.outTrailingComments { + t.Errorf("test input: '%s', got TrailingComments\n%+v, want\n%+v", testCase.input, gotTrailingComments, testCase.outTrailingComments) + } + } +} + +func TestStripLeadingComments(t *testing.T) { + var testCases = []struct { + input, outSQL string + }{{ + input: "/", + outSQL: "/", + }, { + input: "*/", + outSQL: "*/", + }, { + input: "/*/", + outSQL: "/*/", + }, { + input: "/*a", + outSQL: "/*a", + }, { + input: "/*a*", + outSQL: "/*a*", + }, { + input: "/*a**", + outSQL: "/*a**", + }, { + input: "/*b**a*/", + outSQL: "", + }, { + input: "/*a*/", + outSQL: "", + }, { + input: "/**/", + outSQL: "", + }, { + input: "/*!*/", + outSQL: "/*!*/", + }, { + input: "/*!a*/", + outSQL: "/*!a*/", + }, { + input: "/*b*/ /*a*/", + outSQL: "", + }, { + input: `/*b*/ --foo +bar`, + outSQL: "bar", + }, { + input: "foo /* bar */", + outSQL: "foo /* bar */", + }, { + input: "/* foo */ bar", + outSQL: "bar", + }, { + input: "-- /* foo */ bar", + outSQL: "-- /* foo */ bar", + }, { + input: "foo -- bar */", + outSQL: "foo -- bar */", + }, { + input: `/* +foo */ bar`, + outSQL: "bar", + }, { + input: `-- foo bar +a`, + outSQL: "a", + }, { + input: `-- foo bar`, + outSQL: "-- foo bar", + }} + for _, testCase := range testCases { + gotSQL := StripLeadingComments(testCase.input) + + if gotSQL != testCase.outSQL { + t.Errorf("test input: '%s', got SQL\n%+v, want\n%+v", testCase.input, gotSQL, testCase.outSQL) + } + } +} + +func TestExtractMysqlComment(t *testing.T) { + var testCases = []struct { + input, outSQL, outVersion string + }{{ + input: "/*!50708SET max_execution_time=5000 */", + outSQL: "SET max_execution_time=5000", + outVersion: "50708", + }, { + input: "/*!50708 SET max_execution_time=5000*/", + outSQL: "SET max_execution_time=5000", + outVersion: "50708", + }, { + input: "/*!50708* from*/", + outSQL: "* from", + outVersion: "50708", + }, { + input: "/*! SET max_execution_time=5000*/", + outSQL: "SET max_execution_time=5000", + outVersion: "", + }} + for _, testCase := range testCases { + gotVersion, gotSQL := ExtractMysqlComment(testCase.input) + + if gotVersion != testCase.outVersion { + t.Errorf("test input: '%s', got version\n%+v, want\n%+v", testCase.input, gotVersion, testCase.outVersion) + } + if gotSQL != testCase.outSQL { + t.Errorf("test input: '%s', got SQL\n%+v, want\n%+v", testCase.input, gotSQL, testCase.outSQL) + } + } +} + +func TestExtractCommentDirectives(t *testing.T) { + var testCases = []struct { + input string + vals CommentDirectives + }{{ + input: "", + vals: nil, + }, { + input: "/* not a vt comment */", + vals: nil, + }, { + input: "/*vt+ */", + vals: CommentDirectives{}, + }, { + input: "/*vt+ SINGLE_OPTION */", + vals: CommentDirectives{ + "SINGLE_OPTION": true, + }, + }, { + input: "/*vt+ ONE_OPT TWO_OPT */", + vals: CommentDirectives{ + "ONE_OPT": true, + "TWO_OPT": true, + }, + }, { + input: "/*vt+ ONE_OPT */ /* other comment */ /*vt+ TWO_OPT */", + vals: CommentDirectives{ + "ONE_OPT": true, + "TWO_OPT": true, + }, + }, { + input: "/*vt+ ONE_OPT=abc TWO_OPT=def */", + vals: CommentDirectives{ + "ONE_OPT": "abc", + "TWO_OPT": "def", + }, + }, { + input: "/*vt+ ONE_OPT=true TWO_OPT=false */", + vals: CommentDirectives{ + "ONE_OPT": true, + "TWO_OPT": false, + }, + }, { + input: "/*vt+ ONE_OPT=true TWO_OPT=\"false\" */", + vals: CommentDirectives{ + "ONE_OPT": true, + "TWO_OPT": "\"false\"", + }, + }, { + input: "/*vt+ RANGE_OPT=[a:b] ANOTHER ANOTHER_WITH_VALEQ=val= AND_ONE_WITH_EQ== */", + vals: CommentDirectives{ + "RANGE_OPT": "[a:b]", + "ANOTHER": true, + "ANOTHER_WITH_VALEQ": "val=", + "AND_ONE_WITH_EQ": "=", + }, + }} + + for _, testCase := range testCases { + sql := "select " + testCase.input + " 1 from dual" + stmt, _ := Parse(sql) + comments := stmt.(*Select).Comments + vals := ExtractCommentDirectives(comments) + + if !reflect.DeepEqual(vals, testCase.vals) { + t.Errorf("test input: '%v', got vals:\n%+v, want\n%+v", testCase.input, vals, testCase.vals) + } + } + + d := CommentDirectives{ + "ONE_OPT": true, + "TWO_OPT": false, + "three": 1, + "four": 2, + "five": 0, + "six": "true", + } + + if !d.IsSet("ONE_OPT") { + t.Errorf("d.IsSet(ONE_OPT) should be true") + } + + if d.IsSet("TWO_OPT") { + t.Errorf("d.IsSet(TWO_OPT) should be false") + } + + if !d.IsSet("three") { + t.Errorf("d.IsSet(three) should be true") + } + + if d.IsSet("four") { + t.Errorf("d.IsSet(four) should be false") + } + + if d.IsSet("five") { + t.Errorf("d.IsSet(five) should be false") + } + + if d.IsSet("six") { + t.Errorf("d.IsSet(six) should be false") + } +} + +func TestSkipQueryPlanCacheDirective(t *testing.T) { + stmt, _ := Parse("insert /*vt+ SKIP_QUERY_PLAN_CACHE=1 */ into user(id) values (1), (2)") + if !SkipQueryPlanCacheDirective(stmt) { + t.Errorf("d.SkipQueryPlanCacheDirective(stmt) should be true") + } + + stmt, _ = Parse("insert into user(id) values (1), (2)") + if SkipQueryPlanCacheDirective(stmt) { + t.Errorf("d.SkipQueryPlanCacheDirective(stmt) should be false") + } + + stmt, _ = Parse("update /*vt+ SKIP_QUERY_PLAN_CACHE=1 */ users set name=1") + if !SkipQueryPlanCacheDirective(stmt) { + t.Errorf("d.SkipQueryPlanCacheDirective(stmt) should be true") + } + + stmt, _ = Parse("select /*vt+ SKIP_QUERY_PLAN_CACHE=1 */ * from users") + if !SkipQueryPlanCacheDirective(stmt) { + t.Errorf("d.SkipQueryPlanCacheDirective(stmt) should be true") + } + + stmt, _ = Parse("delete /*vt+ SKIP_QUERY_PLAN_CACHE=1 */ from users") + if !SkipQueryPlanCacheDirective(stmt) { + t.Errorf("d.SkipQueryPlanCacheDirective(stmt) should be true") + } +} diff --git a/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/dependency/bytes2/buffer.go b/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/dependency/bytes2/buffer.go new file mode 100644 index 00000000..72f8fc6e --- /dev/null +++ b/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/dependency/bytes2/buffer.go @@ -0,0 +1,65 @@ +/* +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 bytes2 + +// Buffer implements a subset of the write portion of +// bytes.Buffer, but more efficiently. This is meant to +// be used in very high QPS operations, especially for +// WriteByte, and without abstracting it as a Writer. +// Function signatures contain errors for compatibility, +// but they do not return errors. +type Buffer struct { + bytes []byte +} + +// NewBuffer is equivalent to bytes.NewBuffer. +func NewBuffer(b []byte) *Buffer { + return &Buffer{bytes: b} +} + +// Write is equivalent to bytes.Buffer.Write. +func (buf *Buffer) Write(b []byte) (int, error) { + buf.bytes = append(buf.bytes, b...) + return len(b), nil +} + +// WriteString is equivalent to bytes.Buffer.WriteString. +func (buf *Buffer) WriteString(s string) (int, error) { + buf.bytes = append(buf.bytes, s...) + return len(s), nil +} + +// WriteByte is equivalent to bytes.Buffer.WriteByte. +func (buf *Buffer) WriteByte(b byte) error { + buf.bytes = append(buf.bytes, b) + return nil +} + +// Bytes is equivalent to bytes.Buffer.Bytes. +func (buf *Buffer) Bytes() []byte { + return buf.bytes +} + +// Strings is equivalent to bytes.Buffer.Strings. +func (buf *Buffer) String() string { + return string(buf.bytes) +} + +// Len is equivalent to bytes.Buffer.Len. +func (buf *Buffer) Len() int { + return len(buf.bytes) +} diff --git a/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/dependency/bytes2/buffer_test.go b/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/dependency/bytes2/buffer_test.go new file mode 100644 index 00000000..6f3b102f --- /dev/null +++ b/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/dependency/bytes2/buffer_test.go @@ -0,0 +1,36 @@ +/* +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 bytes2 + +import "testing" + +func TestBuffer(t *testing.T) { + b := NewBuffer(nil) + b.Write([]byte("ab")) + b.WriteString("cd") + b.WriteByte('e') + want := "abcde" + if got := string(b.Bytes()); got != want { + t.Errorf("b.Bytes(): %s, want %s", got, want) + } + if got := b.String(); got != want { + t.Errorf("b.String(): %s, want %s", got, want) + } + if got := b.Len(); got != 5 { + t.Errorf("b.Len(): %d, want 5", got) + } +} diff --git a/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/dependency/hack/hack.go b/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/dependency/hack/hack.go new file mode 100644 index 00000000..e6344ad9 --- /dev/null +++ b/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/dependency/hack/hack.go @@ -0,0 +1,79 @@ +/* +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 hack gives you some efficient functionality at the cost of +// breaking some Go rules. +package hack + +import ( + "reflect" + "unsafe" +) + +// StringArena lets you consolidate allocations for a group of strings +// that have similar life length +type StringArena struct { + buf []byte + str string +} + +// NewStringArena creates an arena of the specified size. +func NewStringArena(size int) *StringArena { + sa := &StringArena{buf: make([]byte, 0, size)} + pbytes := (*reflect.SliceHeader)(unsafe.Pointer(&sa.buf)) + pstring := (*reflect.StringHeader)(unsafe.Pointer(&sa.str)) + pstring.Data = pbytes.Data + pstring.Len = pbytes.Cap + return sa +} + +// NewString copies a byte slice into the arena and returns it as a string. +// If the arena is full, it returns a traditional go string. +func (sa *StringArena) NewString(b []byte) string { + if len(b) == 0 { + return "" + } + if len(sa.buf)+len(b) > cap(sa.buf) { + return string(b) + } + start := len(sa.buf) + sa.buf = append(sa.buf, b...) + return sa.str[start : start+len(b)] +} + +// SpaceLeft returns the amount of space left in the arena. +func (sa *StringArena) SpaceLeft() int { + return cap(sa.buf) - len(sa.buf) +} + +// String force casts a []byte to a string. +// USE AT YOUR OWN RISK +func String(b []byte) (s string) { + if len(b) == 0 { + return "" + } + pbytes := (*reflect.SliceHeader)(unsafe.Pointer(&b)) + pstring := (*reflect.StringHeader)(unsafe.Pointer(&s)) + pstring.Data = pbytes.Data + pstring.Len = pbytes.Len + return +} + +// StringPointer returns &s[0], which is not allowed in go +func StringPointer(s string) unsafe.Pointer { + pstring := (*reflect.StringHeader)(unsafe.Pointer(&s)) + return unsafe.Pointer(pstring.Data) +} diff --git a/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/dependency/hack/hack_test.go b/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/dependency/hack/hack_test.go new file mode 100644 index 00000000..d8208c6f --- /dev/null +++ b/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/dependency/hack/hack_test.go @@ -0,0 +1,91 @@ +/* +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 hack + +import "testing" + +func TestStringArena(t *testing.T) { + sarena := NewStringArena(10) + + s0 := sarena.NewString(nil) + checkint(t, len(sarena.buf), 0) + checkint(t, sarena.SpaceLeft(), 10) + checkstring(t, s0, "") + + s1 := sarena.NewString([]byte("01234")) + checkint(t, len(sarena.buf), 5) + checkint(t, sarena.SpaceLeft(), 5) + checkstring(t, s1, "01234") + + s2 := sarena.NewString([]byte("5678")) + checkint(t, len(sarena.buf), 9) + checkint(t, sarena.SpaceLeft(), 1) + checkstring(t, s2, "5678") + + // s3 will be allocated outside of sarena + s3 := sarena.NewString([]byte("ab")) + checkint(t, len(sarena.buf), 9) + checkint(t, sarena.SpaceLeft(), 1) + checkstring(t, s3, "ab") + + // s4 should still fit in sarena + s4 := sarena.NewString([]byte("9")) + checkint(t, len(sarena.buf), 10) + checkint(t, sarena.SpaceLeft(), 0) + checkstring(t, s4, "9") + + sarena.buf[0] = 'A' + checkstring(t, s1, "A1234") + + sarena.buf[5] = 'B' + checkstring(t, s2, "B678") + + sarena.buf[9] = 'C' + // s3 will not change + checkstring(t, s3, "ab") + checkstring(t, s4, "C") + checkstring(t, sarena.str, "A1234B678C") +} + +func checkstring(t *testing.T, actual, expected string) { + if actual != expected { + t.Errorf("received %s, expecting %s", actual, expected) + } +} + +func checkint(t *testing.T, actual, expected int) { + if actual != expected { + t.Errorf("received %d, expecting %d", actual, expected) + } +} + +func TestByteToString(t *testing.T) { + v1 := []byte("1234") + if s := String(v1); s != "1234" { + t.Errorf("String(\"1234\"): %q, want 1234", s) + } + + v1 = []byte("") + if s := String(v1); s != "" { + t.Errorf("String(\"\"): %q, want empty", s) + } + + v1 = nil + if s := String(v1); s != "" { + t.Errorf("String(\"\"): %q, want empty", s) + } +} diff --git a/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/dependency/querypb/query.pb.go b/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/dependency/querypb/query.pb.go new file mode 100644 index 00000000..db9f924c --- /dev/null +++ b/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/dependency/querypb/query.pb.go @@ -0,0 +1,2734 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: query.proto + +/* +Package query is a generated protocol buffer package. + +It is generated from these files: + query.proto + +It has these top-level messages: + Target + VTGateCallerID + EventToken + Value + BindVariable + BoundQuery + ExecuteOptions + Field + Row + ResultExtras + QueryResult + StreamEvent + ExecuteRequest + ExecuteResponse + ResultWithError + ExecuteBatchRequest + ExecuteBatchResponse + StreamExecuteRequest + StreamExecuteResponse + BeginRequest + BeginResponse + CommitRequest + CommitResponse + RollbackRequest + RollbackResponse + PrepareRequest + PrepareResponse + CommitPreparedRequest + CommitPreparedResponse + RollbackPreparedRequest + RollbackPreparedResponse + CreateTransactionRequest + CreateTransactionResponse + StartCommitRequest + StartCommitResponse + SetRollbackRequest + SetRollbackResponse + ConcludeTransactionRequest + ConcludeTransactionResponse + ReadTransactionRequest + ReadTransactionResponse + BeginExecuteRequest + BeginExecuteResponse + BeginExecuteBatchRequest + BeginExecuteBatchResponse + MessageStreamRequest + MessageStreamResponse + MessageAckRequest + MessageAckResponse + SplitQueryRequest + QuerySplit + SplitQueryResponse + StreamHealthRequest + RealtimeStats + StreamHealthResponse + UpdateStreamRequest + UpdateStreamResponse + TransactionMetadata +*/ +package querypb + +import "strconv" + +// EnumName is a helper function to simplify printing protocol buffer enums +// by name. Given an enum map and a value, it returns a useful string. +func EnumName(m map[int32]string, v int32) string { + s, ok := m[v] + if ok { + return s + } + return strconv.Itoa(int(v)) +} + +// Flags sent from the MySQL C API +type MySqlFlag int32 + +const ( + MySqlFlag_EMPTY MySqlFlag = 0 + MySqlFlag_NOT_NULL_FLAG MySqlFlag = 1 + MySqlFlag_PRI_KEY_FLAG MySqlFlag = 2 + MySqlFlag_UNIQUE_KEY_FLAG MySqlFlag = 4 + MySqlFlag_MULTIPLE_KEY_FLAG MySqlFlag = 8 + MySqlFlag_BLOB_FLAG MySqlFlag = 16 + MySqlFlag_UNSIGNED_FLAG MySqlFlag = 32 + MySqlFlag_ZEROFILL_FLAG MySqlFlag = 64 + MySqlFlag_BINARY_FLAG MySqlFlag = 128 + MySqlFlag_ENUM_FLAG MySqlFlag = 256 + MySqlFlag_AUTO_INCREMENT_FLAG MySqlFlag = 512 + MySqlFlag_TIMESTAMP_FLAG MySqlFlag = 1024 + MySqlFlag_SET_FLAG MySqlFlag = 2048 + MySqlFlag_NO_DEFAULT_VALUE_FLAG MySqlFlag = 4096 + MySqlFlag_ON_UPDATE_NOW_FLAG MySqlFlag = 8192 + MySqlFlag_NUM_FLAG MySqlFlag = 32768 + MySqlFlag_PART_KEY_FLAG MySqlFlag = 16384 + MySqlFlag_GROUP_FLAG MySqlFlag = 32768 + MySqlFlag_UNIQUE_FLAG MySqlFlag = 65536 + MySqlFlag_BINCMP_FLAG MySqlFlag = 131072 +) + +var MySqlFlag_name = map[int32]string{ + 0: "EMPTY", + 1: "NOT_NULL_FLAG", + 2: "PRI_KEY_FLAG", + 4: "UNIQUE_KEY_FLAG", + 8: "MULTIPLE_KEY_FLAG", + 16: "BLOB_FLAG", + 32: "UNSIGNED_FLAG", + 64: "ZEROFILL_FLAG", + 128: "BINARY_FLAG", + 256: "ENUM_FLAG", + 512: "AUTO_INCREMENT_FLAG", + 1024: "TIMESTAMP_FLAG", + 2048: "SET_FLAG", + 4096: "NO_DEFAULT_VALUE_FLAG", + 8192: "ON_UPDATE_NOW_FLAG", + 32768: "NUM_FLAG", + 16384: "PART_KEY_FLAG", + // Duplicate value: 32768: "GROUP_FLAG", + 65536: "UNIQUE_FLAG", + 131072: "BINCMP_FLAG", +} +var MySqlFlag_value = map[string]int32{ + "EMPTY": 0, + "NOT_NULL_FLAG": 1, + "PRI_KEY_FLAG": 2, + "UNIQUE_KEY_FLAG": 4, + "MULTIPLE_KEY_FLAG": 8, + "BLOB_FLAG": 16, + "UNSIGNED_FLAG": 32, + "ZEROFILL_FLAG": 64, + "BINARY_FLAG": 128, + "ENUM_FLAG": 256, + "AUTO_INCREMENT_FLAG": 512, + "TIMESTAMP_FLAG": 1024, + "SET_FLAG": 2048, + "NO_DEFAULT_VALUE_FLAG": 4096, + "ON_UPDATE_NOW_FLAG": 8192, + "NUM_FLAG": 32768, + "PART_KEY_FLAG": 16384, + "GROUP_FLAG": 32768, + "UNIQUE_FLAG": 65536, + "BINCMP_FLAG": 131072, +} + +func (x MySqlFlag) String() string { + return EnumName(MySqlFlag_name, int32(x)) +} + +// Flag allows us to qualify types by their common properties. +type Flag int32 + +const ( + Flag_NONE Flag = 0 + Flag_ISINTEGRAL Flag = 256 + Flag_ISUNSIGNED Flag = 512 + Flag_ISFLOAT Flag = 1024 + Flag_ISQUOTED Flag = 2048 + Flag_ISTEXT Flag = 4096 + Flag_ISBINARY Flag = 8192 +) + +var Flag_name = map[int32]string{ + 0: "NONE", + 256: "ISINTEGRAL", + 512: "ISUNSIGNED", + 1024: "ISFLOAT", + 2048: "ISQUOTED", + 4096: "ISTEXT", + 8192: "ISBINARY", +} +var Flag_value = map[string]int32{ + "NONE": 0, + "ISINTEGRAL": 256, + "ISUNSIGNED": 512, + "ISFLOAT": 1024, + "ISQUOTED": 2048, + "ISTEXT": 4096, + "ISBINARY": 8192, +} + +func (x Flag) String() string { + return EnumName(Flag_name, int32(x)) +} + +// Type defines the various supported data types in bind vars +// and query results. +type Type int32 + +const ( + // NULL_TYPE specifies a NULL type. + Type_NULL_TYPE Type = 0 + // INT8 specifies a TINYINT type. + // Properties: 1, IsNumber. + Type_INT8 Type = 257 + // UINT8 specifies a TINYINT UNSIGNED type. + // Properties: 2, IsNumber, IsUnsigned. + Type_UINT8 Type = 770 + // INT16 specifies a SMALLINT type. + // Properties: 3, IsNumber. + Type_INT16 Type = 259 + // UINT16 specifies a SMALLINT UNSIGNED type. + // Properties: 4, IsNumber, IsUnsigned. + Type_UINT16 Type = 772 + // INT24 specifies a MEDIUMINT type. + // Properties: 5, IsNumber. + Type_INT24 Type = 261 + // UINT24 specifies a MEDIUMINT UNSIGNED type. + // Properties: 6, IsNumber, IsUnsigned. + Type_UINT24 Type = 774 + // INT32 specifies a INTEGER type. + // Properties: 7, IsNumber. + Type_INT32 Type = 263 + // UINT32 specifies a INTEGER UNSIGNED type. + // Properties: 8, IsNumber, IsUnsigned. + Type_UINT32 Type = 776 + // INT64 specifies a BIGINT type. + // Properties: 9, IsNumber. + Type_INT64 Type = 265 + // UINT64 specifies a BIGINT UNSIGNED type. + // Properties: 10, IsNumber, IsUnsigned. + Type_UINT64 Type = 778 + // FLOAT32 specifies a FLOAT type. + // Properties: 11, IsFloat. + Type_FLOAT32 Type = 1035 + // FLOAT64 specifies a DOUBLE or REAL type. + // Properties: 12, IsFloat. + Type_FLOAT64 Type = 1036 + // TIMESTAMP specifies a TIMESTAMP type. + // Properties: 13, IsQuoted. + Type_TIMESTAMP Type = 2061 + // DATE specifies a DATE type. + // Properties: 14, IsQuoted. + Type_DATE Type = 2062 + // TIME specifies a TIME type. + // Properties: 15, IsQuoted. + Type_TIME Type = 2063 + // DATETIME specifies a DATETIME type. + // Properties: 16, IsQuoted. + Type_DATETIME Type = 2064 + // YEAR specifies a YEAR type. + // Properties: 17, IsNumber, IsUnsigned. + Type_YEAR Type = 785 + // DECIMAL specifies a DECIMAL or NUMERIC type. + // Properties: 18, None. + Type_DECIMAL Type = 18 + // TEXT specifies a TEXT type. + // Properties: 19, IsQuoted, IsText. + Type_TEXT Type = 6163 + // BLOB specifies a BLOB type. + // Properties: 20, IsQuoted, IsBinary. + Type_BLOB Type = 10260 + // VARCHAR specifies a VARCHAR type. + // Properties: 21, IsQuoted, IsText. + Type_VARCHAR Type = 6165 + // VARBINARY specifies a VARBINARY type. + // Properties: 22, IsQuoted, IsBinary. + Type_VARBINARY Type = 10262 + // CHAR specifies a CHAR type. + // Properties: 23, IsQuoted, IsText. + Type_CHAR Type = 6167 + // BINARY specifies a BINARY type. + // Properties: 24, IsQuoted, IsBinary. + Type_BINARY Type = 10264 + // BIT specifies a BIT type. + // Properties: 25, IsQuoted. + Type_BIT Type = 2073 + // ENUM specifies an ENUM type. + // Properties: 26, IsQuoted. + Type_ENUM Type = 2074 + // SET specifies a SET type. + // Properties: 27, IsQuoted. + Type_SET Type = 2075 + // TUPLE specifies a a tuple. This cannot + // be returned in a QueryResult, but it can + // be sent as a bind var. + // Properties: 28, None. + Type_TUPLE Type = 28 + // GEOMETRY specifies a GEOMETRY type. + // Properties: 29, IsQuoted. + Type_GEOMETRY Type = 2077 + // JSON specifies a JSON type. + // Properties: 30, IsQuoted. + Type_JSON Type = 2078 + // EXPRESSION specifies a SQL expression. + // This type is for internal use only. + // Properties: 31, None. + Type_EXPRESSION Type = 31 +) + +var Type_name = map[int32]string{ + 0: "NULL_TYPE", + 257: "INT8", + 770: "UINT8", + 259: "INT16", + 772: "UINT16", + 261: "INT24", + 774: "UINT24", + 263: "INT32", + 776: "UINT32", + 265: "INT64", + 778: "UINT64", + 1035: "FLOAT32", + 1036: "FLOAT64", + 2061: "TIMESTAMP", + 2062: "DATE", + 2063: "TIME", + 2064: "DATETIME", + 785: "YEAR", + 18: "DECIMAL", + 6163: "TEXT", + 10260: "BLOB", + 6165: "VARCHAR", + 10262: "VARBINARY", + 6167: "CHAR", + 10264: "BINARY", + 2073: "BIT", + 2074: "ENUM", + 2075: "SET", + 28: "TUPLE", + 2077: "GEOMETRY", + 2078: "JSON", + 31: "EXPRESSION", +} +var Type_value = map[string]int32{ + "NULL_TYPE": 0, + "INT8": 257, + "UINT8": 770, + "INT16": 259, + "UINT16": 772, + "INT24": 261, + "UINT24": 774, + "INT32": 263, + "UINT32": 776, + "INT64": 265, + "UINT64": 778, + "FLOAT32": 1035, + "FLOAT64": 1036, + "TIMESTAMP": 2061, + "DATE": 2062, + "TIME": 2063, + "DATETIME": 2064, + "YEAR": 785, + "DECIMAL": 18, + "TEXT": 6163, + "BLOB": 10260, + "VARCHAR": 6165, + "VARBINARY": 10262, + "CHAR": 6167, + "BINARY": 10264, + "BIT": 2073, + "ENUM": 2074, + "SET": 2075, + "TUPLE": 28, + "GEOMETRY": 2077, + "JSON": 2078, + "EXPRESSION": 31, +} + +func (x Type) String() string { + return EnumName(Type_name, int32(x)) +} + +// TransactionState represents the state of a distributed transaction. +type TransactionState int32 + +const ( + TransactionState_UNKNOWN TransactionState = 0 + TransactionState_PREPARE TransactionState = 1 + TransactionState_COMMIT TransactionState = 2 + TransactionState_ROLLBACK TransactionState = 3 +) + +var TransactionState_name = map[int32]string{ + 0: "UNKNOWN", + 1: "PREPARE", + 2: "COMMIT", + 3: "ROLLBACK", +} +var TransactionState_value = map[string]int32{ + "UNKNOWN": 0, + "PREPARE": 1, + "COMMIT": 2, + "ROLLBACK": 3, +} + +func (x TransactionState) String() string { + return EnumName(TransactionState_name, int32(x)) +} + +type ExecuteOptions_IncludedFields int32 + +const ( + ExecuteOptions_TYPE_AND_NAME ExecuteOptions_IncludedFields = 0 + ExecuteOptions_TYPE_ONLY ExecuteOptions_IncludedFields = 1 + ExecuteOptions_ALL ExecuteOptions_IncludedFields = 2 +) + +var ExecuteOptions_IncludedFields_name = map[int32]string{ + 0: "TYPE_AND_NAME", + 1: "TYPE_ONLY", + 2: "ALL", +} +var ExecuteOptions_IncludedFields_value = map[string]int32{ + "TYPE_AND_NAME": 0, + "TYPE_ONLY": 1, + "ALL": 2, +} + +func (x ExecuteOptions_IncludedFields) String() string { + return EnumName(ExecuteOptions_IncludedFields_name, int32(x)) +} + +type ExecuteOptions_Workload int32 + +const ( + ExecuteOptions_UNSPECIFIED ExecuteOptions_Workload = 0 + ExecuteOptions_OLTP ExecuteOptions_Workload = 1 + ExecuteOptions_OLAP ExecuteOptions_Workload = 2 + ExecuteOptions_DBA ExecuteOptions_Workload = 3 +) + +var ExecuteOptions_Workload_name = map[int32]string{ + 0: "UNSPECIFIED", + 1: "OLTP", + 2: "OLAP", + 3: "DBA", +} +var ExecuteOptions_Workload_value = map[string]int32{ + "UNSPECIFIED": 0, + "OLTP": 1, + "OLAP": 2, + "DBA": 3, +} + +func (x ExecuteOptions_Workload) String() string { + return EnumName(ExecuteOptions_Workload_name, int32(x)) +} + +type ExecuteOptions_TransactionIsolation int32 + +const ( + ExecuteOptions_DEFAULT ExecuteOptions_TransactionIsolation = 0 + ExecuteOptions_REPEATABLE_READ ExecuteOptions_TransactionIsolation = 1 + ExecuteOptions_READ_COMMITTED ExecuteOptions_TransactionIsolation = 2 + ExecuteOptions_READ_UNCOMMITTED ExecuteOptions_TransactionIsolation = 3 + ExecuteOptions_SERIALIZABLE ExecuteOptions_TransactionIsolation = 4 +) + +var ExecuteOptions_TransactionIsolation_name = map[int32]string{ + 0: "DEFAULT", + 1: "REPEATABLE_READ", + 2: "READ_COMMITTED", + 3: "READ_UNCOMMITTED", + 4: "SERIALIZABLE", +} +var ExecuteOptions_TransactionIsolation_value = map[string]int32{ + "DEFAULT": 0, + "REPEATABLE_READ": 1, + "READ_COMMITTED": 2, + "READ_UNCOMMITTED": 3, + "SERIALIZABLE": 4, +} + +func (x ExecuteOptions_TransactionIsolation) String() string { + return EnumName(ExecuteOptions_TransactionIsolation_name, int32(x)) +} + +// The category of one statement. +type StreamEvent_Statement_Category int32 + +const ( + StreamEvent_Statement_Error StreamEvent_Statement_Category = 0 + StreamEvent_Statement_DML StreamEvent_Statement_Category = 1 + StreamEvent_Statement_DDL StreamEvent_Statement_Category = 2 +) + +var StreamEvent_Statement_Category_name = map[int32]string{ + 0: "Error", + 1: "DML", + 2: "DDL", +} +var StreamEvent_Statement_Category_value = map[string]int32{ + "Error": 0, + "DML": 1, + "DDL": 2, +} + +func (x StreamEvent_Statement_Category) String() string { + return EnumName(StreamEvent_Statement_Category_name, int32(x)) +} + +type SplitQueryRequest_Algorithm int32 + +const ( + SplitQueryRequest_EQUAL_SPLITS SplitQueryRequest_Algorithm = 0 + SplitQueryRequest_FULL_SCAN SplitQueryRequest_Algorithm = 1 +) + +var SplitQueryRequest_Algorithm_name = map[int32]string{ + 0: "EQUAL_SPLITS", + 1: "FULL_SCAN", +} +var SplitQueryRequest_Algorithm_value = map[string]int32{ + "EQUAL_SPLITS": 0, + "FULL_SCAN": 1, +} + +func (x SplitQueryRequest_Algorithm) String() string { + return EnumName(SplitQueryRequest_Algorithm_name, int32(x)) +} + +/* +// Target describes what the client expects the tablet is. +// If the tablet does not match, an error is returned. +type Target struct { + Keyspace string `protobuf:"bytes,1,opt,name=keyspace" json:"keyspace,omitempty"` + Shard string `protobuf:"bytes,2,opt,name=shard" json:"shard,omitempty"` + TabletType topodata.TabletType `protobuf:"varint,3,opt,name=tablet_type,json=tabletType,enum=topodata.TabletType" json:"tablet_type,omitempty"` +} + +func (m *Target) Reset() { *m = Target{} } +func (m *Target) String() string { return "TODO" } + + + +func (m *Target) GetKeyspace() string { + if m != nil { + return m.Keyspace + } + return "" +} + +func (m *Target) GetShard() string { + if m != nil { + return m.Shard + } + return "" +} + +func (m *Target) GetTabletType() topodata.TabletType { + if m != nil { + return m.TabletType + } + return topodata.TabletType_UNKNOWN +} + + +// VTGateCallerID is sent by VTGate to VTTablet to describe the +// caller. If possible, this information is secure. For instance, +// if using unique certificates that guarantee that VTGate->VTTablet +// traffic cannot be spoofed, then VTTablet can trust this information, +// and VTTablet will use it for tablet ACLs, for instance. +// Because of this security guarantee, this is different than the CallerID +// structure, which is not secure at all, because it is provided +// by the Vitess client. +type VTGateCallerID struct { + Username string `protobuf:"bytes,1,opt,name=username" json:"username,omitempty"` + Groups []string `protobuf:"bytes,2,rep,name=groups" json:"groups,omitempty"` +} + +func (m *VTGateCallerID) Reset() { *m = VTGateCallerID{} } +func (m *VTGateCallerID) String() string { return "TODO" } + + + +func (m *VTGateCallerID) GetUsername() string { + if m != nil { + return m.Username + } + return "" +} + +func (m *VTGateCallerID) GetGroups() []string { + if m != nil { + return m.Groups + } + return nil +} + +// EventToken is a structure that describes a point in time in a +// replication stream on one shard. The most recent known replication +// position can be retrieved from vttablet when executing a query. It +// is also sent with the replication streams from the binlog service. +type EventToken struct { + // timestamp is the MySQL timestamp of the statements. Seconds since Epoch. + Timestamp int64 `protobuf:"varint,1,opt,name=timestamp" json:"timestamp,omitempty"` + // The shard name that applied the statements. Note this is not set when + // streaming from a vttablet. It is only used on the client -> vtgate link. + Shard string `protobuf:"bytes,2,opt,name=shard" json:"shard,omitempty"` + // The position on the replication stream after this statement was applied. + // It is not the transaction ID / GTID, but the position / GTIDSet. + Position string `protobuf:"bytes,3,opt,name=position" json:"position,omitempty"` +} + +func (m *EventToken) Reset() { *m = EventToken{} } +func (m *EventToken) String() string { return "TODO" } + + + +func (m *EventToken) GetTimestamp() int64 { + if m != nil { + return m.Timestamp + } + return 0 +} + +func (m *EventToken) GetShard() string { + if m != nil { + return m.Shard + } + return "" +} + +func (m *EventToken) GetPosition() string { + if m != nil { + return m.Position + } + return "" +} +*/ + +// Value represents a typed value. +type Value struct { + Type Type `protobuf:"varint,1,opt,name=type,enum=query.Type" json:"type,omitempty"` + Value []byte `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` +} + +func (m *Value) Reset() { *m = Value{} } +func (m *Value) String() string { return "TODO" } + +func (m *Value) GetType() Type { + if m != nil { + return m.Type + } + return Type_NULL_TYPE +} + +func (m *Value) GetValue() []byte { + if m != nil { + return m.Value + } + return nil +} + +// BindVariable represents a single bind variable in a Query. +type BindVariable struct { + Type Type `protobuf:"varint,1,opt,name=type,enum=query.Type" json:"type,omitempty"` + Value []byte `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` + // values are set if type is TUPLE. + Values []*Value `protobuf:"bytes,3,rep,name=values" json:"values,omitempty"` +} + +func (m *BindVariable) Reset() { *m = BindVariable{} } +func (m *BindVariable) String() string { return "TODO" } + +func (m *BindVariable) GetType() Type { + if m != nil { + return m.Type + } + return Type_NULL_TYPE +} + +func (m *BindVariable) GetValue() []byte { + if m != nil { + return m.Value + } + return nil +} + +func (m *BindVariable) GetValues() []*Value { + if m != nil { + return m.Values + } + return nil +} + +// BoundQuery is a query with its bind variables +type BoundQuery struct { + // sql is the SQL query to execute + Sql string `protobuf:"bytes,1,opt,name=sql" json:"sql,omitempty"` + // bind_variables is a map of all bind variables to expand in the query. + // nil values are not allowed. Use NULL_TYPE to express a NULL value. + BindVariables map[string]*BindVariable `protobuf:"bytes,2,rep,name=bind_variables,json=bindVariables" json:"bind_variables,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` +} + +func (m *BoundQuery) Reset() { *m = BoundQuery{} } +func (m *BoundQuery) String() string { return "TODO" } + +func (m *BoundQuery) GetSql() string { + if m != nil { + return m.Sql + } + return "" +} + +func (m *BoundQuery) GetBindVariables() map[string]*BindVariable { + if m != nil { + return m.BindVariables + } + return nil +} + +/* +// ExecuteOptions is passed around for all Execute calls. +type ExecuteOptions struct { + // If set, we will try to include an EventToken with the responses. + IncludeEventToken bool `protobuf:"varint,2,opt,name=include_event_token,json=includeEventToken" json:"include_event_token,omitempty"` + // If set, the fresher field may be set as a result comparison to this token. + // This is a shortcut so the application doesn't need to care about + // comparing EventTokens. + CompareEventToken *EventToken `protobuf:"bytes,3,opt,name=compare_event_token,json=compareEventToken" json:"compare_event_token,omitempty"` + // Controls what fields are returned in Field message responses from mysql, i.e. + // field name, table name, etc. This is an optimization for high-QPS queries where + // the client knows what it's getting + IncludedFields ExecuteOptions_IncludedFields `protobuf:"varint,4,opt,name=included_fields,json=includedFields,enum=query.ExecuteOptions_IncludedFields" json:"included_fields,omitempty"` + // client_rows_found specifies if rows_affected should return + // rows found instead of rows affected. Behavior is defined + // by MySQL's CLIENT_FOUND_ROWS flag. + ClientFoundRows bool `protobuf:"varint,5,opt,name=client_found_rows,json=clientFoundRows" json:"client_found_rows,omitempty"` + // workload specifies the type of workload: + // OLTP: DMLs allowed, results have row count limit, and + // query timeouts are shorter. + // OLAP: DMLS not allowed, no limit on row count, timeouts + // can be as high as desired. + // DBA: no limit on rowcount or timeout, all queries allowed + // but intended for long DMLs and DDLs. + Workload ExecuteOptions_Workload `protobuf:"varint,6,opt,name=workload,enum=query.ExecuteOptions_Workload" json:"workload,omitempty"` + // sql_select_limit sets an implicit limit on all select statements. Since + // vitess also sets a rowcount limit on queries, the smallest value wins. + SqlSelectLimit int64 `protobuf:"varint,8,opt,name=sql_select_limit,json=sqlSelectLimit" json:"sql_select_limit,omitempty"` + TransactionIsolation ExecuteOptions_TransactionIsolation `protobuf:"varint,9,opt,name=transaction_isolation,json=transactionIsolation,enum=query.ExecuteOptions_TransactionIsolation" json:"transaction_isolation,omitempty"` +} + +func (m *ExecuteOptions) Reset() { *m = ExecuteOptions{} } +func (m *ExecuteOptions) String() string { return "TODO" } + + + +func (m *ExecuteOptions) GetIncludeEventToken() bool { + if m != nil { + return m.IncludeEventToken + } + return false +} + +func (m *ExecuteOptions) GetCompareEventToken() *EventToken { + if m != nil { + return m.CompareEventToken + } + return nil +} + +func (m *ExecuteOptions) GetIncludedFields() ExecuteOptions_IncludedFields { + if m != nil { + return m.IncludedFields + } + return ExecuteOptions_TYPE_AND_NAME +} + +func (m *ExecuteOptions) GetClientFoundRows() bool { + if m != nil { + return m.ClientFoundRows + } + return false +} + +func (m *ExecuteOptions) GetWorkload() ExecuteOptions_Workload { + if m != nil { + return m.Workload + } + return ExecuteOptions_UNSPECIFIED +} + +func (m *ExecuteOptions) GetSqlSelectLimit() int64 { + if m != nil { + return m.SqlSelectLimit + } + return 0 +} + +func (m *ExecuteOptions) GetTransactionIsolation() ExecuteOptions_TransactionIsolation { + if m != nil { + return m.TransactionIsolation + } + return ExecuteOptions_DEFAULT +} + +// Field describes a single column returned by a query +type Field struct { + // name of the field as returned by mysql C API + Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` + // vitess-defined type. Conversion function is in sqltypes package. + Type Type `protobuf:"varint,2,opt,name=type,enum=query.Type" json:"type,omitempty"` + // Remaining fields from mysql C API. + // These fields are only populated when ExecuteOptions.included_fields + // is set to IncludedFields.ALL. + Table string `protobuf:"bytes,3,opt,name=table" json:"table,omitempty"` + OrgTable string `protobuf:"bytes,4,opt,name=org_table,json=orgTable" json:"org_table,omitempty"` + Database string `protobuf:"bytes,5,opt,name=database" json:"database,omitempty"` + OrgName string `protobuf:"bytes,6,opt,name=org_name,json=orgName" json:"org_name,omitempty"` + // column_length is really a uint32. All 32 bits can be used. + ColumnLength uint32 `protobuf:"varint,7,opt,name=column_length,json=columnLength" json:"column_length,omitempty"` + // charset is actually a uint16. Only the lower 16 bits are used. + Charset uint32 `protobuf:"varint,8,opt,name=charset" json:"charset,omitempty"` + // decimals is actualy a uint8. Only the lower 8 bits are used. + Decimals uint32 `protobuf:"varint,9,opt,name=decimals" json:"decimals,omitempty"` + // flags is actually a uint16. Only the lower 16 bits are used. + Flags uint32 `protobuf:"varint,10,opt,name=flags" json:"flags,omitempty"` +} + +func (m *Field) Reset() { *m = Field{} } +func (m *Field) String() string { return "TODO" } + + + +func (m *Field) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +func (m *Field) GetType() Type { + if m != nil { + return m.Type + } + return Type_NULL_TYPE +} + +func (m *Field) GetTable() string { + if m != nil { + return m.Table + } + return "" +} + +func (m *Field) GetOrgTable() string { + if m != nil { + return m.OrgTable + } + return "" +} + +func (m *Field) GetDatabase() string { + if m != nil { + return m.Database + } + return "" +} + +func (m *Field) GetOrgName() string { + if m != nil { + return m.OrgName + } + return "" +} + +func (m *Field) GetColumnLength() uint32 { + if m != nil { + return m.ColumnLength + } + return 0 +} + +func (m *Field) GetCharset() uint32 { + if m != nil { + return m.Charset + } + return 0 +} + +func (m *Field) GetDecimals() uint32 { + if m != nil { + return m.Decimals + } + return 0 +} + +func (m *Field) GetFlags() uint32 { + if m != nil { + return m.Flags + } + return 0 +} + +// Row is a database row. +type Row struct { + // lengths contains the length of each value in values. + // A length of -1 means that the field is NULL. While + // reading values, you have to accummulate the length + // to know the offset where the next value begins in values. + Lengths []int64 `protobuf:"zigzag64,1,rep,packed,name=lengths" json:"lengths,omitempty"` + // values contains a concatenation of all values in the row. + Values []byte `protobuf:"bytes,2,opt,name=values,proto3" json:"values,omitempty"` +} + +func (m *Row) Reset() { *m = Row{} } +func (m *Row) String() string { return "TODO" } + + + +func (m *Row) GetLengths() []int64 { + if m != nil { + return m.Lengths + } + return nil +} + +func (m *Row) GetValues() []byte { + if m != nil { + return m.Values + } + return nil +} + +// ResultExtras contains optional out-of-band information. Usually the +// extras are requested by adding ExecuteOptions flags. +type ResultExtras struct { + // event_token is populated if the include_event_token flag is set + // in ExecuteOptions. + EventToken *EventToken `protobuf:"bytes,1,opt,name=event_token,json=eventToken" json:"event_token,omitempty"` + // If set, it means the data returned with this result is fresher + // than the compare_token passed in the ExecuteOptions. + Fresher bool `protobuf:"varint,2,opt,name=fresher" json:"fresher,omitempty"` +} + +func (m *ResultExtras) Reset() { *m = ResultExtras{} } +func (m *ResultExtras) String() string { return "TODO" } + + + +func (m *ResultExtras) GetEventToken() *EventToken { + if m != nil { + return m.EventToken + } + return nil +} + +func (m *ResultExtras) GetFresher() bool { + if m != nil { + return m.Fresher + } + return false +} + +// QueryResult is returned by Execute and ExecuteStream. +// +// As returned by Execute, len(fields) is always equal to len(row) +// (for each row in rows). +// +// As returned by StreamExecute, the first QueryResult has the fields +// set, and subsequent QueryResult have rows set. And as Execute, +// len(QueryResult[0].fields) is always equal to len(row) (for each +// row in rows for each QueryResult in QueryResult[1:]). +type QueryResult struct { + Fields []*Field `protobuf:"bytes,1,rep,name=fields" json:"fields,omitempty"` + RowsAffected uint64 `protobuf:"varint,2,opt,name=rows_affected,json=rowsAffected" json:"rows_affected,omitempty"` + InsertId uint64 `protobuf:"varint,3,opt,name=insert_id,json=insertId" json:"insert_id,omitempty"` + Rows []*Row `protobuf:"bytes,4,rep,name=rows" json:"rows,omitempty"` + Extras *ResultExtras `protobuf:"bytes,5,opt,name=extras" json:"extras,omitempty"` +} + +func (m *QueryResult) Reset() { *m = QueryResult{} } +func (m *QueryResult) String() string { return "TODO" } + + + +func (m *QueryResult) GetFields() []*Field { + if m != nil { + return m.Fields + } + return nil +} + +func (m *QueryResult) GetRowsAffected() uint64 { + if m != nil { + return m.RowsAffected + } + return 0 +} + +func (m *QueryResult) GetInsertId() uint64 { + if m != nil { + return m.InsertId + } + return 0 +} + +func (m *QueryResult) GetRows() []*Row { + if m != nil { + return m.Rows + } + return nil +} + +func (m *QueryResult) GetExtras() *ResultExtras { + if m != nil { + return m.Extras + } + return nil +} + +// StreamEvent describes a set of transformations that happened as a +// single transactional unit on a server. It is streamed back by the +// Update Stream calls. +type StreamEvent struct { + // The statements in this transaction. + Statements []*StreamEvent_Statement `protobuf:"bytes,1,rep,name=statements" json:"statements,omitempty"` + // The Event Token for this event. + EventToken *EventToken `protobuf:"bytes,2,opt,name=event_token,json=eventToken" json:"event_token,omitempty"` +} + +func (m *StreamEvent) Reset() { *m = StreamEvent{} } +func (m *StreamEvent) String() string { return "TODO" } + + + +func (m *StreamEvent) GetStatements() []*StreamEvent_Statement { + if m != nil { + return m.Statements + } + return nil +} + +func (m *StreamEvent) GetEventToken() *EventToken { + if m != nil { + return m.EventToken + } + return nil +} + +// One individual Statement in a transaction. +type StreamEvent_Statement struct { + Category StreamEvent_Statement_Category `protobuf:"varint,1,opt,name=category,enum=query.StreamEvent_Statement_Category" json:"category,omitempty"` + // table_name, primary_key_fields and primary_key_values are set for DML. + TableName string `protobuf:"bytes,2,opt,name=table_name,json=tableName" json:"table_name,omitempty"` + PrimaryKeyFields []*Field `protobuf:"bytes,3,rep,name=primary_key_fields,json=primaryKeyFields" json:"primary_key_fields,omitempty"` + PrimaryKeyValues []*Row `protobuf:"bytes,4,rep,name=primary_key_values,json=primaryKeyValues" json:"primary_key_values,omitempty"` + // sql is set for all queries. + // FIXME(alainjobart) we may not need it for DMLs. + Sql []byte `protobuf:"bytes,5,opt,name=sql,proto3" json:"sql,omitempty"` +} + +func (m *StreamEvent_Statement) Reset() { *m = StreamEvent_Statement{} } +func (m *StreamEvent_Statement) String() string { return "TODO" } + + + +func (m *StreamEvent_Statement) GetCategory() StreamEvent_Statement_Category { + if m != nil { + return m.Category + } + return StreamEvent_Statement_Error +} + +func (m *StreamEvent_Statement) GetTableName() string { + if m != nil { + return m.TableName + } + return "" +} + +func (m *StreamEvent_Statement) GetPrimaryKeyFields() []*Field { + if m != nil { + return m.PrimaryKeyFields + } + return nil +} + +func (m *StreamEvent_Statement) GetPrimaryKeyValues() []*Row { + if m != nil { + return m.PrimaryKeyValues + } + return nil +} + +func (m *StreamEvent_Statement) GetSql() []byte { + if m != nil { + return m.Sql + } + return nil +} + + +// ExecuteRequest is the payload to Execute +type ExecuteRequest struct { + EffectiveCallerId *vtrpc.CallerID `protobuf:"bytes,1,opt,name=effective_caller_id,json=effectiveCallerId" json:"effective_caller_id,omitempty"` + ImmediateCallerId *VTGateCallerID `protobuf:"bytes,2,opt,name=immediate_caller_id,json=immediateCallerId" json:"immediate_caller_id,omitempty"` + Target *Target `protobuf:"bytes,3,opt,name=target" json:"target,omitempty"` + Query *BoundQuery `protobuf:"bytes,4,opt,name=query" json:"query,omitempty"` + TransactionId int64 `protobuf:"varint,5,opt,name=transaction_id,json=transactionId" json:"transaction_id,omitempty"` + Options *ExecuteOptions `protobuf:"bytes,6,opt,name=options" json:"options,omitempty"` +} + +func (m *ExecuteRequest) Reset() { *m = ExecuteRequest{} } +func (m *ExecuteRequest) String() string { return "TODO" } + + + +func (m *ExecuteRequest) GetEffectiveCallerId() *vtrpc.CallerID { + if m != nil { + return m.EffectiveCallerId + } + return nil +} + +func (m *ExecuteRequest) GetImmediateCallerId() *VTGateCallerID { + if m != nil { + return m.ImmediateCallerId + } + return nil +} + +func (m *ExecuteRequest) GetTarget() *Target { + if m != nil { + return m.Target + } + return nil +} + +func (m *ExecuteRequest) GetQuery() *BoundQuery { + if m != nil { + return m.Query + } + return nil +} + +func (m *ExecuteRequest) GetTransactionId() int64 { + if m != nil { + return m.TransactionId + } + return 0 +} + +func (m *ExecuteRequest) GetOptions() *ExecuteOptions { + if m != nil { + return m.Options + } + return nil +} + +// ExecuteResponse is the returned value from Execute +type ExecuteResponse struct { + Result *QueryResult `protobuf:"bytes,1,opt,name=result" json:"result,omitempty"` +} + +func (m *ExecuteResponse) Reset() { *m = ExecuteResponse{} } +func (m *ExecuteResponse) String() string { return "TODO" } + + + +func (m *ExecuteResponse) GetResult() *QueryResult { + if m != nil { + return m.Result + } + return nil +} + +// ResultWithError represents a query response +// in the form of result or error but not both. +// TODO: To be used in ExecuteBatchResponse and BeginExecuteBatchResponse. +type ResultWithError struct { + // error contains an query level error, only set if result is unset. + Error *vtrpc.RPCError `protobuf:"bytes,1,opt,name=error" json:"error,omitempty"` + // result contains the query result, only set if error is unset. + Result *QueryResult `protobuf:"bytes,2,opt,name=result" json:"result,omitempty"` +} + +func (m *ResultWithError) Reset() { *m = ResultWithError{} } +func (m *ResultWithError) String() string { return "TODO" } + + + +func (m *ResultWithError) GetError() *vtrpc.RPCError { + if m != nil { + return m.Error + } + return nil +} + +func (m *ResultWithError) GetResult() *QueryResult { + if m != nil { + return m.Result + } + return nil +} + +// ExecuteBatchRequest is the payload to ExecuteBatch +type ExecuteBatchRequest struct { + EffectiveCallerId *vtrpc.CallerID `protobuf:"bytes,1,opt,name=effective_caller_id,json=effectiveCallerId" json:"effective_caller_id,omitempty"` + ImmediateCallerId *VTGateCallerID `protobuf:"bytes,2,opt,name=immediate_caller_id,json=immediateCallerId" json:"immediate_caller_id,omitempty"` + Target *Target `protobuf:"bytes,3,opt,name=target" json:"target,omitempty"` + Queries []*BoundQuery `protobuf:"bytes,4,rep,name=queries" json:"queries,omitempty"` + AsTransaction bool `protobuf:"varint,5,opt,name=as_transaction,json=asTransaction" json:"as_transaction,omitempty"` + TransactionId int64 `protobuf:"varint,6,opt,name=transaction_id,json=transactionId" json:"transaction_id,omitempty"` + Options *ExecuteOptions `protobuf:"bytes,7,opt,name=options" json:"options,omitempty"` +} + +func (m *ExecuteBatchRequest) Reset() { *m = ExecuteBatchRequest{} } +func (m *ExecuteBatchRequest) String() string { return "TODO" } + + + +func (m *ExecuteBatchRequest) GetEffectiveCallerId() *vtrpc.CallerID { + if m != nil { + return m.EffectiveCallerId + } + return nil +} + +func (m *ExecuteBatchRequest) GetImmediateCallerId() *VTGateCallerID { + if m != nil { + return m.ImmediateCallerId + } + return nil +} + +func (m *ExecuteBatchRequest) GetTarget() *Target { + if m != nil { + return m.Target + } + return nil +} + +func (m *ExecuteBatchRequest) GetQueries() []*BoundQuery { + if m != nil { + return m.Queries + } + return nil +} + +func (m *ExecuteBatchRequest) GetAsTransaction() bool { + if m != nil { + return m.AsTransaction + } + return false +} + +func (m *ExecuteBatchRequest) GetTransactionId() int64 { + if m != nil { + return m.TransactionId + } + return 0 +} + +func (m *ExecuteBatchRequest) GetOptions() *ExecuteOptions { + if m != nil { + return m.Options + } + return nil +} + +// ExecuteBatchResponse is the returned value from ExecuteBatch +type ExecuteBatchResponse struct { + Results []*QueryResult `protobuf:"bytes,1,rep,name=results" json:"results,omitempty"` +} + +func (m *ExecuteBatchResponse) Reset() { *m = ExecuteBatchResponse{} } +func (m *ExecuteBatchResponse) String() string { return "TODO" } + + + +func (m *ExecuteBatchResponse) GetResults() []*QueryResult { + if m != nil { + return m.Results + } + return nil +} + +// StreamExecuteRequest is the payload to StreamExecute +type StreamExecuteRequest struct { + EffectiveCallerId *vtrpc.CallerID `protobuf:"bytes,1,opt,name=effective_caller_id,json=effectiveCallerId" json:"effective_caller_id,omitempty"` + ImmediateCallerId *VTGateCallerID `protobuf:"bytes,2,opt,name=immediate_caller_id,json=immediateCallerId" json:"immediate_caller_id,omitempty"` + Target *Target `protobuf:"bytes,3,opt,name=target" json:"target,omitempty"` + Query *BoundQuery `protobuf:"bytes,4,opt,name=query" json:"query,omitempty"` + Options *ExecuteOptions `protobuf:"bytes,5,opt,name=options" json:"options,omitempty"` +} + +func (m *StreamExecuteRequest) Reset() { *m = StreamExecuteRequest{} } +func (m *StreamExecuteRequest) String() string { return "TODO" } + + + +func (m *StreamExecuteRequest) GetEffectiveCallerId() *vtrpc.CallerID { + if m != nil { + return m.EffectiveCallerId + } + return nil +} + +func (m *StreamExecuteRequest) GetImmediateCallerId() *VTGateCallerID { + if m != nil { + return m.ImmediateCallerId + } + return nil +} + +func (m *StreamExecuteRequest) GetTarget() *Target { + if m != nil { + return m.Target + } + return nil +} + +func (m *StreamExecuteRequest) GetQuery() *BoundQuery { + if m != nil { + return m.Query + } + return nil +} + +func (m *StreamExecuteRequest) GetOptions() *ExecuteOptions { + if m != nil { + return m.Options + } + return nil +} + +// StreamExecuteResponse is the returned value from StreamExecute +type StreamExecuteResponse struct { + Result *QueryResult `protobuf:"bytes,1,opt,name=result" json:"result,omitempty"` +} + +func (m *StreamExecuteResponse) Reset() { *m = StreamExecuteResponse{} } +func (m *StreamExecuteResponse) String() string { return "TODO" } + + + +func (m *StreamExecuteResponse) GetResult() *QueryResult { + if m != nil { + return m.Result + } + return nil +} + +// BeginRequest is the payload to Begin +type BeginRequest struct { + EffectiveCallerId *vtrpc.CallerID `protobuf:"bytes,1,opt,name=effective_caller_id,json=effectiveCallerId" json:"effective_caller_id,omitempty"` + ImmediateCallerId *VTGateCallerID `protobuf:"bytes,2,opt,name=immediate_caller_id,json=immediateCallerId" json:"immediate_caller_id,omitempty"` + Target *Target `protobuf:"bytes,3,opt,name=target" json:"target,omitempty"` + Options *ExecuteOptions `protobuf:"bytes,4,opt,name=options" json:"options,omitempty"` +} + +func (m *BeginRequest) Reset() { *m = BeginRequest{} } +func (m *BeginRequest) String() string { return "TODO" } + + + +func (m *BeginRequest) GetEffectiveCallerId() *vtrpc.CallerID { + if m != nil { + return m.EffectiveCallerId + } + return nil +} + +func (m *BeginRequest) GetImmediateCallerId() *VTGateCallerID { + if m != nil { + return m.ImmediateCallerId + } + return nil +} + +func (m *BeginRequest) GetTarget() *Target { + if m != nil { + return m.Target + } + return nil +} + +func (m *BeginRequest) GetOptions() *ExecuteOptions { + if m != nil { + return m.Options + } + return nil +} + +// BeginResponse is the returned value from Begin +type BeginResponse struct { + TransactionId int64 `protobuf:"varint,1,opt,name=transaction_id,json=transactionId" json:"transaction_id,omitempty"` +} + +func (m *BeginResponse) Reset() { *m = BeginResponse{} } +func (m *BeginResponse) String() string { return "TODO" } + + + +func (m *BeginResponse) GetTransactionId() int64 { + if m != nil { + return m.TransactionId + } + return 0 +} + +// CommitRequest is the payload to Commit +type CommitRequest struct { + EffectiveCallerId *vtrpc.CallerID `protobuf:"bytes,1,opt,name=effective_caller_id,json=effectiveCallerId" json:"effective_caller_id,omitempty"` + ImmediateCallerId *VTGateCallerID `protobuf:"bytes,2,opt,name=immediate_caller_id,json=immediateCallerId" json:"immediate_caller_id,omitempty"` + Target *Target `protobuf:"bytes,3,opt,name=target" json:"target,omitempty"` + TransactionId int64 `protobuf:"varint,4,opt,name=transaction_id,json=transactionId" json:"transaction_id,omitempty"` +} + +func (m *CommitRequest) Reset() { *m = CommitRequest{} } +func (m *CommitRequest) String() string { return "TODO" } + + + +func (m *CommitRequest) GetEffectiveCallerId() *vtrpc.CallerID { + if m != nil { + return m.EffectiveCallerId + } + return nil +} + +func (m *CommitRequest) GetImmediateCallerId() *VTGateCallerID { + if m != nil { + return m.ImmediateCallerId + } + return nil +} + +func (m *CommitRequest) GetTarget() *Target { + if m != nil { + return m.Target + } + return nil +} + +func (m *CommitRequest) GetTransactionId() int64 { + if m != nil { + return m.TransactionId + } + return 0 +} + +// CommitResponse is the returned value from Commit +type CommitResponse struct { +} + +func (m *CommitResponse) Reset() { *m = CommitResponse{} } +func (m *CommitResponse) String() string { return "TODO" } + + + +// RollbackRequest is the payload to Rollback +type RollbackRequest struct { + EffectiveCallerId *vtrpc.CallerID `protobuf:"bytes,1,opt,name=effective_caller_id,json=effectiveCallerId" json:"effective_caller_id,omitempty"` + ImmediateCallerId *VTGateCallerID `protobuf:"bytes,2,opt,name=immediate_caller_id,json=immediateCallerId" json:"immediate_caller_id,omitempty"` + Target *Target `protobuf:"bytes,3,opt,name=target" json:"target,omitempty"` + TransactionId int64 `protobuf:"varint,4,opt,name=transaction_id,json=transactionId" json:"transaction_id,omitempty"` +} + +func (m *RollbackRequest) Reset() { *m = RollbackRequest{} } +func (m *RollbackRequest) String() string { return "TODO" } + + + +func (m *RollbackRequest) GetEffectiveCallerId() *vtrpc.CallerID { + if m != nil { + return m.EffectiveCallerId + } + return nil +} + +func (m *RollbackRequest) GetImmediateCallerId() *VTGateCallerID { + if m != nil { + return m.ImmediateCallerId + } + return nil +} + +func (m *RollbackRequest) GetTarget() *Target { + if m != nil { + return m.Target + } + return nil +} + +func (m *RollbackRequest) GetTransactionId() int64 { + if m != nil { + return m.TransactionId + } + return 0 +} + +// RollbackResponse is the returned value from Rollback +type RollbackResponse struct { +} + +func (m *RollbackResponse) Reset() { *m = RollbackResponse{} } +func (m *RollbackResponse) String() string { return "TODO" } + + + +// PrepareRequest is the payload to Prepare +type PrepareRequest struct { + EffectiveCallerId *vtrpc.CallerID `protobuf:"bytes,1,opt,name=effective_caller_id,json=effectiveCallerId" json:"effective_caller_id,omitempty"` + ImmediateCallerId *VTGateCallerID `protobuf:"bytes,2,opt,name=immediate_caller_id,json=immediateCallerId" json:"immediate_caller_id,omitempty"` + Target *Target `protobuf:"bytes,3,opt,name=target" json:"target,omitempty"` + TransactionId int64 `protobuf:"varint,4,opt,name=transaction_id,json=transactionId" json:"transaction_id,omitempty"` + Dtid string `protobuf:"bytes,5,opt,name=dtid" json:"dtid,omitempty"` +} + +func (m *PrepareRequest) Reset() { *m = PrepareRequest{} } +func (m *PrepareRequest) String() string { return "TODO" } + + + +func (m *PrepareRequest) GetEffectiveCallerId() *vtrpc.CallerID { + if m != nil { + return m.EffectiveCallerId + } + return nil +} + +func (m *PrepareRequest) GetImmediateCallerId() *VTGateCallerID { + if m != nil { + return m.ImmediateCallerId + } + return nil +} + +func (m *PrepareRequest) GetTarget() *Target { + if m != nil { + return m.Target + } + return nil +} + +func (m *PrepareRequest) GetTransactionId() int64 { + if m != nil { + return m.TransactionId + } + return 0 +} + +func (m *PrepareRequest) GetDtid() string { + if m != nil { + return m.Dtid + } + return "" +} + +// PrepareResponse is the returned value from Prepare +type PrepareResponse struct { +} + +func (m *PrepareResponse) Reset() { *m = PrepareResponse{} } +func (m *PrepareResponse) String() string { return "TODO" } + + + +// CommitPreparedRequest is the payload to CommitPrepared +type CommitPreparedRequest struct { + EffectiveCallerId *vtrpc.CallerID `protobuf:"bytes,1,opt,name=effective_caller_id,json=effectiveCallerId" json:"effective_caller_id,omitempty"` + ImmediateCallerId *VTGateCallerID `protobuf:"bytes,2,opt,name=immediate_caller_id,json=immediateCallerId" json:"immediate_caller_id,omitempty"` + Target *Target `protobuf:"bytes,3,opt,name=target" json:"target,omitempty"` + Dtid string `protobuf:"bytes,4,opt,name=dtid" json:"dtid,omitempty"` +} + +func (m *CommitPreparedRequest) Reset() { *m = CommitPreparedRequest{} } +func (m *CommitPreparedRequest) String() string { return "TODO" } + + + +func (m *CommitPreparedRequest) GetEffectiveCallerId() *vtrpc.CallerID { + if m != nil { + return m.EffectiveCallerId + } + return nil +} + +func (m *CommitPreparedRequest) GetImmediateCallerId() *VTGateCallerID { + if m != nil { + return m.ImmediateCallerId + } + return nil +} + +func (m *CommitPreparedRequest) GetTarget() *Target { + if m != nil { + return m.Target + } + return nil +} + +func (m *CommitPreparedRequest) GetDtid() string { + if m != nil { + return m.Dtid + } + return "" +} + +// CommitPreparedResponse is the returned value from CommitPrepared +type CommitPreparedResponse struct { +} + +func (m *CommitPreparedResponse) Reset() { *m = CommitPreparedResponse{} } +func (m *CommitPreparedResponse) String() string { return "TODO" } + + + +// RollbackPreparedRequest is the payload to RollbackPrepared +type RollbackPreparedRequest struct { + EffectiveCallerId *vtrpc.CallerID `protobuf:"bytes,1,opt,name=effective_caller_id,json=effectiveCallerId" json:"effective_caller_id,omitempty"` + ImmediateCallerId *VTGateCallerID `protobuf:"bytes,2,opt,name=immediate_caller_id,json=immediateCallerId" json:"immediate_caller_id,omitempty"` + Target *Target `protobuf:"bytes,3,opt,name=target" json:"target,omitempty"` + TransactionId int64 `protobuf:"varint,4,opt,name=transaction_id,json=transactionId" json:"transaction_id,omitempty"` + Dtid string `protobuf:"bytes,5,opt,name=dtid" json:"dtid,omitempty"` +} + +func (m *RollbackPreparedRequest) Reset() { *m = RollbackPreparedRequest{} } +func (m *RollbackPreparedRequest) String() string { return "TODO" } + + + +func (m *RollbackPreparedRequest) GetEffectiveCallerId() *vtrpc.CallerID { + if m != nil { + return m.EffectiveCallerId + } + return nil +} + +func (m *RollbackPreparedRequest) GetImmediateCallerId() *VTGateCallerID { + if m != nil { + return m.ImmediateCallerId + } + return nil +} + +func (m *RollbackPreparedRequest) GetTarget() *Target { + if m != nil { + return m.Target + } + return nil +} + +func (m *RollbackPreparedRequest) GetTransactionId() int64 { + if m != nil { + return m.TransactionId + } + return 0 +} + +func (m *RollbackPreparedRequest) GetDtid() string { + if m != nil { + return m.Dtid + } + return "" +} + +// RollbackPreparedResponse is the returned value from RollbackPrepared +type RollbackPreparedResponse struct { +} + +func (m *RollbackPreparedResponse) Reset() { *m = RollbackPreparedResponse{} } +func (m *RollbackPreparedResponse) String() string { return "TODO" } + + + +// CreateTransactionRequest is the payload to CreateTransaction +type CreateTransactionRequest struct { + EffectiveCallerId *vtrpc.CallerID `protobuf:"bytes,1,opt,name=effective_caller_id,json=effectiveCallerId" json:"effective_caller_id,omitempty"` + ImmediateCallerId *VTGateCallerID `protobuf:"bytes,2,opt,name=immediate_caller_id,json=immediateCallerId" json:"immediate_caller_id,omitempty"` + Target *Target `protobuf:"bytes,3,opt,name=target" json:"target,omitempty"` + Dtid string `protobuf:"bytes,4,opt,name=dtid" json:"dtid,omitempty"` + Participants []*Target `protobuf:"bytes,5,rep,name=participants" json:"participants,omitempty"` +} + +func (m *CreateTransactionRequest) Reset() { *m = CreateTransactionRequest{} } +func (m *CreateTransactionRequest) String() string { return "TODO" } + + + +func (m *CreateTransactionRequest) GetEffectiveCallerId() *vtrpc.CallerID { + if m != nil { + return m.EffectiveCallerId + } + return nil +} + +func (m *CreateTransactionRequest) GetImmediateCallerId() *VTGateCallerID { + if m != nil { + return m.ImmediateCallerId + } + return nil +} + +func (m *CreateTransactionRequest) GetTarget() *Target { + if m != nil { + return m.Target + } + return nil +} + +func (m *CreateTransactionRequest) GetDtid() string { + if m != nil { + return m.Dtid + } + return "" +} + +func (m *CreateTransactionRequest) GetParticipants() []*Target { + if m != nil { + return m.Participants + } + return nil +} + +// CreateTransactionResponse is the returned value from CreateTransaction +type CreateTransactionResponse struct { +} + +func (m *CreateTransactionResponse) Reset() { *m = CreateTransactionResponse{} } +func (m *CreateTransactionResponse) String() string { return "TODO" } + + + +// StartCommitRequest is the payload to StartCommit +type StartCommitRequest struct { + EffectiveCallerId *vtrpc.CallerID `protobuf:"bytes,1,opt,name=effective_caller_id,json=effectiveCallerId" json:"effective_caller_id,omitempty"` + ImmediateCallerId *VTGateCallerID `protobuf:"bytes,2,opt,name=immediate_caller_id,json=immediateCallerId" json:"immediate_caller_id,omitempty"` + Target *Target `protobuf:"bytes,3,opt,name=target" json:"target,omitempty"` + TransactionId int64 `protobuf:"varint,4,opt,name=transaction_id,json=transactionId" json:"transaction_id,omitempty"` + Dtid string `protobuf:"bytes,5,opt,name=dtid" json:"dtid,omitempty"` +} + +func (m *StartCommitRequest) Reset() { *m = StartCommitRequest{} } +func (m *StartCommitRequest) String() string { return "TODO" } + + + +func (m *StartCommitRequest) GetEffectiveCallerId() *vtrpc.CallerID { + if m != nil { + return m.EffectiveCallerId + } + return nil +} + +func (m *StartCommitRequest) GetImmediateCallerId() *VTGateCallerID { + if m != nil { + return m.ImmediateCallerId + } + return nil +} + +func (m *StartCommitRequest) GetTarget() *Target { + if m != nil { + return m.Target + } + return nil +} + +func (m *StartCommitRequest) GetTransactionId() int64 { + if m != nil { + return m.TransactionId + } + return 0 +} + +func (m *StartCommitRequest) GetDtid() string { + if m != nil { + return m.Dtid + } + return "" +} + +// StartCommitResponse is the returned value from StartCommit +type StartCommitResponse struct { +} + +func (m *StartCommitResponse) Reset() { *m = StartCommitResponse{} } +func (m *StartCommitResponse) String() string { return "TODO" } + + + +// SetRollbackRequest is the payload to SetRollback +type SetRollbackRequest struct { + EffectiveCallerId *vtrpc.CallerID `protobuf:"bytes,1,opt,name=effective_caller_id,json=effectiveCallerId" json:"effective_caller_id,omitempty"` + ImmediateCallerId *VTGateCallerID `protobuf:"bytes,2,opt,name=immediate_caller_id,json=immediateCallerId" json:"immediate_caller_id,omitempty"` + Target *Target `protobuf:"bytes,3,opt,name=target" json:"target,omitempty"` + TransactionId int64 `protobuf:"varint,4,opt,name=transaction_id,json=transactionId" json:"transaction_id,omitempty"` + Dtid string `protobuf:"bytes,5,opt,name=dtid" json:"dtid,omitempty"` +} + +func (m *SetRollbackRequest) Reset() { *m = SetRollbackRequest{} } +func (m *SetRollbackRequest) String() string { return "TODO" } + + + +func (m *SetRollbackRequest) GetEffectiveCallerId() *vtrpc.CallerID { + if m != nil { + return m.EffectiveCallerId + } + return nil +} + +func (m *SetRollbackRequest) GetImmediateCallerId() *VTGateCallerID { + if m != nil { + return m.ImmediateCallerId + } + return nil +} + +func (m *SetRollbackRequest) GetTarget() *Target { + if m != nil { + return m.Target + } + return nil +} + +func (m *SetRollbackRequest) GetTransactionId() int64 { + if m != nil { + return m.TransactionId + } + return 0 +} + +func (m *SetRollbackRequest) GetDtid() string { + if m != nil { + return m.Dtid + } + return "" +} + +// SetRollbackResponse is the returned value from SetRollback +type SetRollbackResponse struct { +} + +func (m *SetRollbackResponse) Reset() { *m = SetRollbackResponse{} } +func (m *SetRollbackResponse) String() string { return "TODO" } + + + +// ConcludeTransactionRequest is the payload to ConcludeTransaction +type ConcludeTransactionRequest struct { + EffectiveCallerId *vtrpc.CallerID `protobuf:"bytes,1,opt,name=effective_caller_id,json=effectiveCallerId" json:"effective_caller_id,omitempty"` + ImmediateCallerId *VTGateCallerID `protobuf:"bytes,2,opt,name=immediate_caller_id,json=immediateCallerId" json:"immediate_caller_id,omitempty"` + Target *Target `protobuf:"bytes,3,opt,name=target" json:"target,omitempty"` + Dtid string `protobuf:"bytes,4,opt,name=dtid" json:"dtid,omitempty"` +} + +func (m *ConcludeTransactionRequest) Reset() { *m = ConcludeTransactionRequest{} } +func (m *ConcludeTransactionRequest) String() string { return "TODO" } + + + +func (m *ConcludeTransactionRequest) GetEffectiveCallerId() *vtrpc.CallerID { + if m != nil { + return m.EffectiveCallerId + } + return nil +} + +func (m *ConcludeTransactionRequest) GetImmediateCallerId() *VTGateCallerID { + if m != nil { + return m.ImmediateCallerId + } + return nil +} + +func (m *ConcludeTransactionRequest) GetTarget() *Target { + if m != nil { + return m.Target + } + return nil +} + +func (m *ConcludeTransactionRequest) GetDtid() string { + if m != nil { + return m.Dtid + } + return "" +} + +// ConcludeTransactionResponse is the returned value from ConcludeTransaction +type ConcludeTransactionResponse struct { +} + +func (m *ConcludeTransactionResponse) Reset() { *m = ConcludeTransactionResponse{} } +func (m *ConcludeTransactionResponse) String() string { return "TODO" } + + + +// ReadTransactionRequest is the payload to ReadTransaction +type ReadTransactionRequest struct { + EffectiveCallerId *vtrpc.CallerID `protobuf:"bytes,1,opt,name=effective_caller_id,json=effectiveCallerId" json:"effective_caller_id,omitempty"` + ImmediateCallerId *VTGateCallerID `protobuf:"bytes,2,opt,name=immediate_caller_id,json=immediateCallerId" json:"immediate_caller_id,omitempty"` + Target *Target `protobuf:"bytes,3,opt,name=target" json:"target,omitempty"` + Dtid string `protobuf:"bytes,4,opt,name=dtid" json:"dtid,omitempty"` +} + +func (m *ReadTransactionRequest) Reset() { *m = ReadTransactionRequest{} } +func (m *ReadTransactionRequest) String() string { return "TODO" } + + + +func (m *ReadTransactionRequest) GetEffectiveCallerId() *vtrpc.CallerID { + if m != nil { + return m.EffectiveCallerId + } + return nil +} + +func (m *ReadTransactionRequest) GetImmediateCallerId() *VTGateCallerID { + if m != nil { + return m.ImmediateCallerId + } + return nil +} + +func (m *ReadTransactionRequest) GetTarget() *Target { + if m != nil { + return m.Target + } + return nil +} + +func (m *ReadTransactionRequest) GetDtid() string { + if m != nil { + return m.Dtid + } + return "" +} + +// ReadTransactionResponse is the returned value from ReadTransaction +type ReadTransactionResponse struct { + Metadata *TransactionMetadata `protobuf:"bytes,1,opt,name=metadata" json:"metadata,omitempty"` +} + +func (m *ReadTransactionResponse) Reset() { *m = ReadTransactionResponse{} } +func (m *ReadTransactionResponse) String() string { return "TODO" } + + + +func (m *ReadTransactionResponse) GetMetadata() *TransactionMetadata { + if m != nil { + return m.Metadata + } + return nil +} + +// BeginExecuteRequest is the payload to BeginExecute +type BeginExecuteRequest struct { + EffectiveCallerId *vtrpc.CallerID `protobuf:"bytes,1,opt,name=effective_caller_id,json=effectiveCallerId" json:"effective_caller_id,omitempty"` + ImmediateCallerId *VTGateCallerID `protobuf:"bytes,2,opt,name=immediate_caller_id,json=immediateCallerId" json:"immediate_caller_id,omitempty"` + Target *Target `protobuf:"bytes,3,opt,name=target" json:"target,omitempty"` + Query *BoundQuery `protobuf:"bytes,4,opt,name=query" json:"query,omitempty"` + Options *ExecuteOptions `protobuf:"bytes,5,opt,name=options" json:"options,omitempty"` +} + +func (m *BeginExecuteRequest) Reset() { *m = BeginExecuteRequest{} } +func (m *BeginExecuteRequest) String() string { return "TODO" } + + + +func (m *BeginExecuteRequest) GetEffectiveCallerId() *vtrpc.CallerID { + if m != nil { + return m.EffectiveCallerId + } + return nil +} + +func (m *BeginExecuteRequest) GetImmediateCallerId() *VTGateCallerID { + if m != nil { + return m.ImmediateCallerId + } + return nil +} + +func (m *BeginExecuteRequest) GetTarget() *Target { + if m != nil { + return m.Target + } + return nil +} + +func (m *BeginExecuteRequest) GetQuery() *BoundQuery { + if m != nil { + return m.Query + } + return nil +} + +func (m *BeginExecuteRequest) GetOptions() *ExecuteOptions { + if m != nil { + return m.Options + } + return nil +} + +// BeginExecuteResponse is the returned value from BeginExecute +type BeginExecuteResponse struct { + // error contains an application level error if necessary. Note the + // transaction_id may be set, even when an error is returned, if the begin + // worked but the execute failed. + Error *vtrpc.RPCError `protobuf:"bytes,1,opt,name=error" json:"error,omitempty"` + Result *QueryResult `protobuf:"bytes,2,opt,name=result" json:"result,omitempty"` + // transaction_id might be non-zero even if an error is present. + TransactionId int64 `protobuf:"varint,3,opt,name=transaction_id,json=transactionId" json:"transaction_id,omitempty"` +} + +func (m *BeginExecuteResponse) Reset() { *m = BeginExecuteResponse{} } +func (m *BeginExecuteResponse) String() string { return "TODO" } + + + +func (m *BeginExecuteResponse) GetError() *vtrpc.RPCError { + if m != nil { + return m.Error + } + return nil +} + +func (m *BeginExecuteResponse) GetResult() *QueryResult { + if m != nil { + return m.Result + } + return nil +} + +func (m *BeginExecuteResponse) GetTransactionId() int64 { + if m != nil { + return m.TransactionId + } + return 0 +} + +// BeginExecuteBatchRequest is the payload to BeginExecuteBatch +type BeginExecuteBatchRequest struct { + EffectiveCallerId *vtrpc.CallerID `protobuf:"bytes,1,opt,name=effective_caller_id,json=effectiveCallerId" json:"effective_caller_id,omitempty"` + ImmediateCallerId *VTGateCallerID `protobuf:"bytes,2,opt,name=immediate_caller_id,json=immediateCallerId" json:"immediate_caller_id,omitempty"` + Target *Target `protobuf:"bytes,3,opt,name=target" json:"target,omitempty"` + Queries []*BoundQuery `protobuf:"bytes,4,rep,name=queries" json:"queries,omitempty"` + AsTransaction bool `protobuf:"varint,5,opt,name=as_transaction,json=asTransaction" json:"as_transaction,omitempty"` + Options *ExecuteOptions `protobuf:"bytes,6,opt,name=options" json:"options,omitempty"` +} + +func (m *BeginExecuteBatchRequest) Reset() { *m = BeginExecuteBatchRequest{} } +func (m *BeginExecuteBatchRequest) String() string { return "TODO" } + + + +func (m *BeginExecuteBatchRequest) GetEffectiveCallerId() *vtrpc.CallerID { + if m != nil { + return m.EffectiveCallerId + } + return nil +} + +func (m *BeginExecuteBatchRequest) GetImmediateCallerId() *VTGateCallerID { + if m != nil { + return m.ImmediateCallerId + } + return nil +} + +func (m *BeginExecuteBatchRequest) GetTarget() *Target { + if m != nil { + return m.Target + } + return nil +} + +func (m *BeginExecuteBatchRequest) GetQueries() []*BoundQuery { + if m != nil { + return m.Queries + } + return nil +} + +func (m *BeginExecuteBatchRequest) GetAsTransaction() bool { + if m != nil { + return m.AsTransaction + } + return false +} + +func (m *BeginExecuteBatchRequest) GetOptions() *ExecuteOptions { + if m != nil { + return m.Options + } + return nil +} + +// BeginExecuteBatchResponse is the returned value from BeginExecuteBatch +type BeginExecuteBatchResponse struct { + // error contains an application level error if necessary. Note the + // transaction_id may be set, even when an error is returned, if the begin + // worked but the execute failed. + Error *vtrpc.RPCError `protobuf:"bytes,1,opt,name=error" json:"error,omitempty"` + Results []*QueryResult `protobuf:"bytes,2,rep,name=results" json:"results,omitempty"` + // transaction_id might be non-zero even if an error is present. + TransactionId int64 `protobuf:"varint,3,opt,name=transaction_id,json=transactionId" json:"transaction_id,omitempty"` +} + +func (m *BeginExecuteBatchResponse) Reset() { *m = BeginExecuteBatchResponse{} } +func (m *BeginExecuteBatchResponse) String() string { return "TODO" } + + + +func (m *BeginExecuteBatchResponse) GetError() *vtrpc.RPCError { + if m != nil { + return m.Error + } + return nil +} + +func (m *BeginExecuteBatchResponse) GetResults() []*QueryResult { + if m != nil { + return m.Results + } + return nil +} + +func (m *BeginExecuteBatchResponse) GetTransactionId() int64 { + if m != nil { + return m.TransactionId + } + return 0 +} + +// MessageStreamRequest is the request payload for MessageStream. +type MessageStreamRequest struct { + EffectiveCallerId *vtrpc.CallerID `protobuf:"bytes,1,opt,name=effective_caller_id,json=effectiveCallerId" json:"effective_caller_id,omitempty"` + ImmediateCallerId *VTGateCallerID `protobuf:"bytes,2,opt,name=immediate_caller_id,json=immediateCallerId" json:"immediate_caller_id,omitempty"` + Target *Target `protobuf:"bytes,3,opt,name=target" json:"target,omitempty"` + // name is the message table name. + Name string `protobuf:"bytes,4,opt,name=name" json:"name,omitempty"` +} + +func (m *MessageStreamRequest) Reset() { *m = MessageStreamRequest{} } +func (m *MessageStreamRequest) String() string { return "TODO" } + + + +func (m *MessageStreamRequest) GetEffectiveCallerId() *vtrpc.CallerID { + if m != nil { + return m.EffectiveCallerId + } + return nil +} + +func (m *MessageStreamRequest) GetImmediateCallerId() *VTGateCallerID { + if m != nil { + return m.ImmediateCallerId + } + return nil +} + +func (m *MessageStreamRequest) GetTarget() *Target { + if m != nil { + return m.Target + } + return nil +} + +func (m *MessageStreamRequest) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +// MessageStreamResponse is a response for MessageStream. +type MessageStreamResponse struct { + Result *QueryResult `protobuf:"bytes,1,opt,name=result" json:"result,omitempty"` +} + +func (m *MessageStreamResponse) Reset() { *m = MessageStreamResponse{} } +func (m *MessageStreamResponse) String() string { return "TODO" } + + + +func (m *MessageStreamResponse) GetResult() *QueryResult { + if m != nil { + return m.Result + } + return nil +} + +// MessageAckRequest is the request payload for MessageAck. +type MessageAckRequest struct { + EffectiveCallerId *vtrpc.CallerID `protobuf:"bytes,1,opt,name=effective_caller_id,json=effectiveCallerId" json:"effective_caller_id,omitempty"` + ImmediateCallerId *VTGateCallerID `protobuf:"bytes,2,opt,name=immediate_caller_id,json=immediateCallerId" json:"immediate_caller_id,omitempty"` + Target *Target `protobuf:"bytes,3,opt,name=target" json:"target,omitempty"` + // name is the message table name. + Name string `protobuf:"bytes,4,opt,name=name" json:"name,omitempty"` + Ids []*Value `protobuf:"bytes,5,rep,name=ids" json:"ids,omitempty"` +} + +func (m *MessageAckRequest) Reset() { *m = MessageAckRequest{} } +func (m *MessageAckRequest) String() string { return "TODO" } + + + +func (m *MessageAckRequest) GetEffectiveCallerId() *vtrpc.CallerID { + if m != nil { + return m.EffectiveCallerId + } + return nil +} + +func (m *MessageAckRequest) GetImmediateCallerId() *VTGateCallerID { + if m != nil { + return m.ImmediateCallerId + } + return nil +} + +func (m *MessageAckRequest) GetTarget() *Target { + if m != nil { + return m.Target + } + return nil +} + +func (m *MessageAckRequest) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +func (m *MessageAckRequest) GetIds() []*Value { + if m != nil { + return m.Ids + } + return nil +} + +// MessageAckResponse is the response for MessageAck. +type MessageAckResponse struct { + // result contains the result of the ack operation. + // Since this acts like a DML, only + // RowsAffected is returned in the result. + Result *QueryResult `protobuf:"bytes,1,opt,name=result" json:"result,omitempty"` +} + +func (m *MessageAckResponse) Reset() { *m = MessageAckResponse{} } +func (m *MessageAckResponse) String() string { return "TODO" } + + + +func (m *MessageAckResponse) GetResult() *QueryResult { + if m != nil { + return m.Result + } + return nil +} + +// SplitQueryRequest is the payload for SplitQuery sent by VTGate to a VTTablet. +// See vtgate.SplitQueryRequest for more details. +type SplitQueryRequest struct { + EffectiveCallerId *vtrpc.CallerID `protobuf:"bytes,1,opt,name=effective_caller_id,json=effectiveCallerId" json:"effective_caller_id,omitempty"` + ImmediateCallerId *VTGateCallerID `protobuf:"bytes,2,opt,name=immediate_caller_id,json=immediateCallerId" json:"immediate_caller_id,omitempty"` + Target *Target `protobuf:"bytes,3,opt,name=target" json:"target,omitempty"` + Query *BoundQuery `protobuf:"bytes,4,opt,name=query" json:"query,omitempty"` + SplitColumn []string `protobuf:"bytes,5,rep,name=split_column,json=splitColumn" json:"split_column,omitempty"` + // Exactly one of the following must be nonzero. + SplitCount int64 `protobuf:"varint,6,opt,name=split_count,json=splitCount" json:"split_count,omitempty"` + NumRowsPerQueryPart int64 `protobuf:"varint,8,opt,name=num_rows_per_query_part,json=numRowsPerQueryPart" json:"num_rows_per_query_part,omitempty"` + Algorithm SplitQueryRequest_Algorithm `protobuf:"varint,9,opt,name=algorithm,enum=query.SplitQueryRequest_Algorithm" json:"algorithm,omitempty"` +} + +func (m *SplitQueryRequest) Reset() { *m = SplitQueryRequest{} } +func (m *SplitQueryRequest) String() string { return "TODO" } + + + +func (m *SplitQueryRequest) GetEffectiveCallerId() *vtrpc.CallerID { + if m != nil { + return m.EffectiveCallerId + } + return nil +} + +func (m *SplitQueryRequest) GetImmediateCallerId() *VTGateCallerID { + if m != nil { + return m.ImmediateCallerId + } + return nil +} + +func (m *SplitQueryRequest) GetTarget() *Target { + if m != nil { + return m.Target + } + return nil +} + +func (m *SplitQueryRequest) GetQuery() *BoundQuery { + if m != nil { + return m.Query + } + return nil +} + +func (m *SplitQueryRequest) GetSplitColumn() []string { + if m != nil { + return m.SplitColumn + } + return nil +} + +func (m *SplitQueryRequest) GetSplitCount() int64 { + if m != nil { + return m.SplitCount + } + return 0 +} + +func (m *SplitQueryRequest) GetNumRowsPerQueryPart() int64 { + if m != nil { + return m.NumRowsPerQueryPart + } + return 0 +} + +func (m *SplitQueryRequest) GetAlgorithm() SplitQueryRequest_Algorithm { + if m != nil { + return m.Algorithm + } + return SplitQueryRequest_EQUAL_SPLITS +} + +// QuerySplit represents one query to execute on the tablet +type QuerySplit struct { + // query is the query to execute + Query *BoundQuery `protobuf:"bytes,1,opt,name=query" json:"query,omitempty"` + // row_count is the approximate row count the query will return + RowCount int64 `protobuf:"varint,2,opt,name=row_count,json=rowCount" json:"row_count,omitempty"` +} + +func (m *QuerySplit) Reset() { *m = QuerySplit{} } +func (m *QuerySplit) String() string { return "TODO" } + + + +func (m *QuerySplit) GetQuery() *BoundQuery { + if m != nil { + return m.Query + } + return nil +} + +func (m *QuerySplit) GetRowCount() int64 { + if m != nil { + return m.RowCount + } + return 0 +} + +// SplitQueryResponse is returned by SplitQuery and represents all the queries +// to execute in order to get the entire data set. +type SplitQueryResponse struct { + Queries []*QuerySplit `protobuf:"bytes,1,rep,name=queries" json:"queries,omitempty"` +} + +func (m *SplitQueryResponse) Reset() { *m = SplitQueryResponse{} } +func (m *SplitQueryResponse) String() string { return "TODO" } + + + +func (m *SplitQueryResponse) GetQueries() []*QuerySplit { + if m != nil { + return m.Queries + } + return nil +} + +// StreamHealthRequest is the payload for StreamHealth +type StreamHealthRequest struct { +} + +func (m *StreamHealthRequest) Reset() { *m = StreamHealthRequest{} } +func (m *StreamHealthRequest) String() string { return "TODO" } + + + +// RealtimeStats contains information about the tablet status +type RealtimeStats struct { + // health_error is the last error we got from health check, + // or empty is the server is healthy. This is used for subset selection, + // we do not send queries to servers that are not healthy. + HealthError string `protobuf:"bytes,1,opt,name=health_error,json=healthError" json:"health_error,omitempty"` + // seconds_behind_master is populated for slaves only. It indicates + // how far behind on (MySQL) replication a slave currently is. It is used + // by clients for subset selection (so we don't try to send traffic + // to tablets that are too far behind). + // NOTE: This field must not be evaluated if "health_error" is not empty. + // TODO(mberlin): Let's switch it to int64 instead? + SecondsBehindMaster uint32 `protobuf:"varint,2,opt,name=seconds_behind_master,json=secondsBehindMaster" json:"seconds_behind_master,omitempty"` + // bin_log_players_count is the number of currently running binlog players. + // if the value is 0, it means that filtered replication is currently not + // running on the tablet. If >0, filtered replication is running. + // NOTE: This field must not be evaluated if "health_error" is not empty. + BinlogPlayersCount int32 `protobuf:"varint,3,opt,name=binlog_players_count,json=binlogPlayersCount" json:"binlog_players_count,omitempty"` + // seconds_behind_master_filtered_replication is populated for the receiving + // master of an ongoing filtered replication only. + // It specifies how far the receiving master lags behind the sending master. + // NOTE: This field must not be evaluated if "health_error" is not empty. + // NOTE: This field must not be evaluated if "bin_log_players_count" is 0. + SecondsBehindMasterFilteredReplication int64 `protobuf:"varint,4,opt,name=seconds_behind_master_filtered_replication,json=secondsBehindMasterFilteredReplication" json:"seconds_behind_master_filtered_replication,omitempty"` + // cpu_usage is used for load-based balancing + CpuUsage float64 `protobuf:"fixed64,5,opt,name=cpu_usage,json=cpuUsage" json:"cpu_usage,omitempty"` + // qps is the average QPS (queries per second) rate in the last XX seconds + // where XX is usually 60 (See query_service_stats.go). + Qps float64 `protobuf:"fixed64,6,opt,name=qps" json:"qps,omitempty"` +} + +func (m *RealtimeStats) Reset() { *m = RealtimeStats{} } +func (m *RealtimeStats) String() string { return "TODO" } + + + +func (m *RealtimeStats) GetHealthError() string { + if m != nil { + return m.HealthError + } + return "" +} + +func (m *RealtimeStats) GetSecondsBehindMaster() uint32 { + if m != nil { + return m.SecondsBehindMaster + } + return 0 +} + +func (m *RealtimeStats) GetBinlogPlayersCount() int32 { + if m != nil { + return m.BinlogPlayersCount + } + return 0 +} + +func (m *RealtimeStats) GetSecondsBehindMasterFilteredReplication() int64 { + if m != nil { + return m.SecondsBehindMasterFilteredReplication + } + return 0 +} + +func (m *RealtimeStats) GetCpuUsage() float64 { + if m != nil { + return m.CpuUsage + } + return 0 +} + +func (m *RealtimeStats) GetQps() float64 { + if m != nil { + return m.Qps + } + return 0 +} + +// StreamHealthResponse is streamed by StreamHealth on a regular basis +type StreamHealthResponse struct { + // target is the current server type. Only queries with that exact Target + // record will be accepted. + Target *Target `protobuf:"bytes,1,opt,name=target" json:"target,omitempty"` + // serving is true iff the tablet is serving. A tablet may not be serving + // if filtered replication is enabled on a master for instance, + // or if a replica should not be used because the keyspace is being resharded. + Serving bool `protobuf:"varint,2,opt,name=serving" json:"serving,omitempty"` + // tablet_externally_reparented_timestamp can be interpreted as the last time + // we knew that this tablet was the MASTER of this shard. + // + // It is used by vtgate when determining the current MASTER of a shard. + // If vtgate sees more than one MASTER tablet, this timestamp is used + // as tiebreaker where the MASTER with the highest timestamp wins. + // Another usage of this timestamp is in go/vt/vtgate/buffer to detect the end + // of a reparent (failover) and stop buffering. + // + // In practice, this field is set to: + // a) the last time the RPC tabletmanager.TabletExternallyReparented was + // called on this tablet (usually done by an external failover tool e.g. + // Orchestrator). The failover tool can call this as long as we are the + // master i.e. even ages after the last reparent occurred. + // OR + // b) the last time an active reparent was executed through a vtctl command + // (InitShardMaster, PlannedReparentShard, EmergencyReparentShard) + // OR + // c) the last time vttablet was started and it initialized its tablet type + // as MASTER because it was recorded as the shard's current master in the + // topology (see go/vt/vttablet/tabletmanager/init_tablet.go) + // OR + // d) 0 if the vttablet was never a MASTER. + TabletExternallyReparentedTimestamp int64 `protobuf:"varint,3,opt,name=tablet_externally_reparented_timestamp,json=tabletExternallyReparentedTimestamp" json:"tablet_externally_reparented_timestamp,omitempty"` + // realtime_stats contains information about the tablet status + RealtimeStats *RealtimeStats `protobuf:"bytes,4,opt,name=realtime_stats,json=realtimeStats" json:"realtime_stats,omitempty"` + // tablet_alias is the alias of the sending tablet. The discovery/healthcheck.go + // code uses it to verify that it's talking to the correct tablet and that it + // hasn't changed in the meantime e.g. due to tablet restarts where ports or + // ips have been reused but assigned differently. + TabletAlias *topodata.TabletAlias `protobuf:"bytes,5,opt,name=tablet_alias,json=tabletAlias" json:"tablet_alias,omitempty"` +} + +func (m *StreamHealthResponse) Reset() { *m = StreamHealthResponse{} } +func (m *StreamHealthResponse) String() string { return "TODO" } + + + +func (m *StreamHealthResponse) GetTarget() *Target { + if m != nil { + return m.Target + } + return nil +} + +func (m *StreamHealthResponse) GetServing() bool { + if m != nil { + return m.Serving + } + return false +} + +func (m *StreamHealthResponse) GetTabletExternallyReparentedTimestamp() int64 { + if m != nil { + return m.TabletExternallyReparentedTimestamp + } + return 0 +} + +func (m *StreamHealthResponse) GetRealtimeStats() *RealtimeStats { + if m != nil { + return m.RealtimeStats + } + return nil +} + +func (m *StreamHealthResponse) GetTabletAlias() *topodata.TabletAlias { + if m != nil { + return m.TabletAlias + } + return nil +} + +// UpdateStreamRequest is the payload for UpdateStream. At most one of +// position and timestamp can be set. If neither is set, we will start +// streaming from the current binlog position. +type UpdateStreamRequest struct { + EffectiveCallerId *vtrpc.CallerID `protobuf:"bytes,1,opt,name=effective_caller_id,json=effectiveCallerId" json:"effective_caller_id,omitempty"` + ImmediateCallerId *VTGateCallerID `protobuf:"bytes,2,opt,name=immediate_caller_id,json=immediateCallerId" json:"immediate_caller_id,omitempty"` + Target *Target `protobuf:"bytes,3,opt,name=target" json:"target,omitempty"` + // If position is set, we will start the streaming from that replication + // position. Incompatible with timestamp. + Position string `protobuf:"bytes,4,opt,name=position" json:"position,omitempty"` + // If timestamp is set, we will start the streaming from the first + // event in the binlogs that have that timestamp. Incompatible with position. + Timestamp int64 `protobuf:"varint,5,opt,name=timestamp" json:"timestamp,omitempty"` +} + +func (m *UpdateStreamRequest) Reset() { *m = UpdateStreamRequest{} } +func (m *UpdateStreamRequest) String() string { return "TODO" } + + + +func (m *UpdateStreamRequest) GetEffectiveCallerId() *vtrpc.CallerID { + if m != nil { + return m.EffectiveCallerId + } + return nil +} + +func (m *UpdateStreamRequest) GetImmediateCallerId() *VTGateCallerID { + if m != nil { + return m.ImmediateCallerId + } + return nil +} + +func (m *UpdateStreamRequest) GetTarget() *Target { + if m != nil { + return m.Target + } + return nil +} + +func (m *UpdateStreamRequest) GetPosition() string { + if m != nil { + return m.Position + } + return "" +} + +func (m *UpdateStreamRequest) GetTimestamp() int64 { + if m != nil { + return m.Timestamp + } + return 0 +} + +// UpdateStreamResponse is returned by UpdateStream +type UpdateStreamResponse struct { + Event *StreamEvent `protobuf:"bytes,1,opt,name=event" json:"event,omitempty"` +} + +func (m *UpdateStreamResponse) Reset() { *m = UpdateStreamResponse{} } +func (m *UpdateStreamResponse) String() string { return "TODO" } + + + +func (m *UpdateStreamResponse) GetEvent() *StreamEvent { + if m != nil { + return m.Event + } + return nil +} + +// TransactionMetadata contains the metadata for a distributed transaction. +type TransactionMetadata struct { + Dtid string `protobuf:"bytes,1,opt,name=dtid" json:"dtid,omitempty"` + State TransactionState `protobuf:"varint,2,opt,name=state,enum=query.TransactionState" json:"state,omitempty"` + TimeCreated int64 `protobuf:"varint,3,opt,name=time_created,json=timeCreated" json:"time_created,omitempty"` + Participants []*Target `protobuf:"bytes,4,rep,name=participants" json:"participants,omitempty"` +} + +func (m *TransactionMetadata) Reset() { *m = TransactionMetadata{} } +func (m *TransactionMetadata) String() string { return "TODO" } + + + +func (m *TransactionMetadata) GetDtid() string { + if m != nil { + return m.Dtid + } + return "" +} + +func (m *TransactionMetadata) GetState() TransactionState { + if m != nil { + return m.State + } + return TransactionState_UNKNOWN +} + +func (m *TransactionMetadata) GetTimeCreated() int64 { + if m != nil { + return m.TimeCreated + } + return 0 +} + +func (m *TransactionMetadata) GetParticipants() []*Target { + if m != nil { + return m.Participants + } + return nil +} + +func init() { + proto.RegisterType((*Target)(nil), "query.Target") + proto.RegisterType((*VTGateCallerID)(nil), "query.VTGateCallerID") + proto.RegisterType((*EventToken)(nil), "query.EventToken") + proto.RegisterType((*Value)(nil), "query.Value") + proto.RegisterType((*BindVariable)(nil), "query.BindVariable") + proto.RegisterType((*BoundQuery)(nil), "query.BoundQuery") + proto.RegisterType((*ExecuteOptions)(nil), "query.ExecuteOptions") + proto.RegisterType((*Field)(nil), "query.Field") + proto.RegisterType((*Row)(nil), "query.Row") + proto.RegisterType((*ResultExtras)(nil), "query.ResultExtras") + proto.RegisterType((*QueryResult)(nil), "query.QueryResult") + proto.RegisterType((*StreamEvent)(nil), "query.StreamEvent") + proto.RegisterType((*StreamEvent_Statement)(nil), "query.StreamEvent.Statement") + proto.RegisterType((*ExecuteRequest)(nil), "query.ExecuteRequest") + proto.RegisterType((*ExecuteResponse)(nil), "query.ExecuteResponse") + proto.RegisterType((*ResultWithError)(nil), "query.ResultWithError") + proto.RegisterType((*ExecuteBatchRequest)(nil), "query.ExecuteBatchRequest") + proto.RegisterType((*ExecuteBatchResponse)(nil), "query.ExecuteBatchResponse") + proto.RegisterType((*StreamExecuteRequest)(nil), "query.StreamExecuteRequest") + proto.RegisterType((*StreamExecuteResponse)(nil), "query.StreamExecuteResponse") + proto.RegisterType((*BeginRequest)(nil), "query.BeginRequest") + proto.RegisterType((*BeginResponse)(nil), "query.BeginResponse") + proto.RegisterType((*CommitRequest)(nil), "query.CommitRequest") + proto.RegisterType((*CommitResponse)(nil), "query.CommitResponse") + proto.RegisterType((*RollbackRequest)(nil), "query.RollbackRequest") + proto.RegisterType((*RollbackResponse)(nil), "query.RollbackResponse") + proto.RegisterType((*PrepareRequest)(nil), "query.PrepareRequest") + proto.RegisterType((*PrepareResponse)(nil), "query.PrepareResponse") + proto.RegisterType((*CommitPreparedRequest)(nil), "query.CommitPreparedRequest") + proto.RegisterType((*CommitPreparedResponse)(nil), "query.CommitPreparedResponse") + proto.RegisterType((*RollbackPreparedRequest)(nil), "query.RollbackPreparedRequest") + proto.RegisterType((*RollbackPreparedResponse)(nil), "query.RollbackPreparedResponse") + proto.RegisterType((*CreateTransactionRequest)(nil), "query.CreateTransactionRequest") + proto.RegisterType((*CreateTransactionResponse)(nil), "query.CreateTransactionResponse") + proto.RegisterType((*StartCommitRequest)(nil), "query.StartCommitRequest") + proto.RegisterType((*StartCommitResponse)(nil), "query.StartCommitResponse") + proto.RegisterType((*SetRollbackRequest)(nil), "query.SetRollbackRequest") + proto.RegisterType((*SetRollbackResponse)(nil), "query.SetRollbackResponse") + proto.RegisterType((*ConcludeTransactionRequest)(nil), "query.ConcludeTransactionRequest") + proto.RegisterType((*ConcludeTransactionResponse)(nil), "query.ConcludeTransactionResponse") + proto.RegisterType((*ReadTransactionRequest)(nil), "query.ReadTransactionRequest") + proto.RegisterType((*ReadTransactionResponse)(nil), "query.ReadTransactionResponse") + proto.RegisterType((*BeginExecuteRequest)(nil), "query.BeginExecuteRequest") + proto.RegisterType((*BeginExecuteResponse)(nil), "query.BeginExecuteResponse") + proto.RegisterType((*BeginExecuteBatchRequest)(nil), "query.BeginExecuteBatchRequest") + proto.RegisterType((*BeginExecuteBatchResponse)(nil), "query.BeginExecuteBatchResponse") + proto.RegisterType((*MessageStreamRequest)(nil), "query.MessageStreamRequest") + proto.RegisterType((*MessageStreamResponse)(nil), "query.MessageStreamResponse") + proto.RegisterType((*MessageAckRequest)(nil), "query.MessageAckRequest") + proto.RegisterType((*MessageAckResponse)(nil), "query.MessageAckResponse") + proto.RegisterType((*SplitQueryRequest)(nil), "query.SplitQueryRequest") + proto.RegisterType((*QuerySplit)(nil), "query.QuerySplit") + proto.RegisterType((*SplitQueryResponse)(nil), "query.SplitQueryResponse") + proto.RegisterType((*StreamHealthRequest)(nil), "query.StreamHealthRequest") + proto.RegisterType((*RealtimeStats)(nil), "query.RealtimeStats") + proto.RegisterType((*StreamHealthResponse)(nil), "query.StreamHealthResponse") + proto.RegisterType((*UpdateStreamRequest)(nil), "query.UpdateStreamRequest") + proto.RegisterType((*UpdateStreamResponse)(nil), "query.UpdateStreamResponse") + proto.RegisterType((*TransactionMetadata)(nil), "query.TransactionMetadata") + proto.RegisterEnum("query.MySqlFlag", MySqlFlag_name, MySqlFlag_value) + proto.RegisterEnum("query.Flag", Flag_name, Flag_value) + proto.RegisterEnum("query.Type", Type_name, Type_value) + proto.RegisterEnum("query.TransactionState", TransactionState_name, TransactionState_value) + proto.RegisterEnum("query.ExecuteOptions_IncludedFields", ExecuteOptions_IncludedFields_name, ExecuteOptions_IncludedFields_value) + proto.RegisterEnum("query.ExecuteOptions_Workload", ExecuteOptions_Workload_name, ExecuteOptions_Workload_value) + proto.RegisterEnum("query.ExecuteOptions_TransactionIsolation", ExecuteOptions_TransactionIsolation_name, ExecuteOptions_TransactionIsolation_value) + proto.RegisterEnum("query.StreamEvent_Statement_Category", StreamEvent_Statement_Category_name, StreamEvent_Statement_Category_value) + proto.RegisterEnum("query.SplitQueryRequest_Algorithm", SplitQueryRequest_Algorithm_name, SplitQueryRequest_Algorithm_value) +} + +*/ diff --git a/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/dependency/sqltypes/bind_variables.go b/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/dependency/sqltypes/bind_variables.go new file mode 100644 index 00000000..1879e6db --- /dev/null +++ b/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/dependency/sqltypes/bind_variables.go @@ -0,0 +1,266 @@ +/* +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 sqltypes + +import ( + "errors" + "fmt" + "reflect" + "strconv" + + "github.com/xwb1989/sqlparser/dependency/querypb" +) + +// NullBindVariable is a bindvar with NULL value. +var NullBindVariable = &querypb.BindVariable{Type: querypb.Type_NULL_TYPE} + +// ValueToProto converts Value to a *querypb.Value. +func ValueToProto(v Value) *querypb.Value { + return &querypb.Value{Type: v.typ, Value: v.val} +} + +// ProtoToValue converts a *querypb.Value to a Value. +func ProtoToValue(v *querypb.Value) Value { + return MakeTrusted(v.Type, v.Value) +} + +// BuildBindVariables builds a map[string]*querypb.BindVariable from a map[string]interface{}. +func BuildBindVariables(in map[string]interface{}) (map[string]*querypb.BindVariable, error) { + if len(in) == 0 { + return nil, nil + } + + out := make(map[string]*querypb.BindVariable, len(in)) + for k, v := range in { + bv, err := BuildBindVariable(v) + if err != nil { + return nil, fmt.Errorf("%s: %v", k, err) + } + out[k] = bv + } + return out, nil +} + +// Int32BindVariable converts an int32 to a bind var. +func Int32BindVariable(v int32) *querypb.BindVariable { + return ValueBindVariable(NewInt32(v)) +} + +// Int64BindVariable converts an int64 to a bind var. +func Int64BindVariable(v int64) *querypb.BindVariable { + return ValueBindVariable(NewInt64(v)) +} + +// Uint64BindVariable converts a uint64 to a bind var. +func Uint64BindVariable(v uint64) *querypb.BindVariable { + return ValueBindVariable(NewUint64(v)) +} + +// Float64BindVariable converts a float64 to a bind var. +func Float64BindVariable(v float64) *querypb.BindVariable { + return ValueBindVariable(NewFloat64(v)) +} + +// StringBindVariable converts a string to a bind var. +func StringBindVariable(v string) *querypb.BindVariable { + return ValueBindVariable(NewVarChar(v)) +} + +// BytesBindVariable converts a []byte to a bind var. +func BytesBindVariable(v []byte) *querypb.BindVariable { + return &querypb.BindVariable{Type: VarBinary, Value: v} +} + +// ValueBindVariable converts a Value to a bind var. +func ValueBindVariable(v Value) *querypb.BindVariable { + return &querypb.BindVariable{Type: v.typ, Value: v.val} +} + +// BuildBindVariable builds a *querypb.BindVariable from a valid input type. +func BuildBindVariable(v interface{}) (*querypb.BindVariable, error) { + switch v := v.(type) { + case string: + return StringBindVariable(v), nil + case []byte: + return BytesBindVariable(v), nil + case int: + return &querypb.BindVariable{ + Type: querypb.Type_INT64, + Value: strconv.AppendInt(nil, int64(v), 10), + }, nil + case int64: + return Int64BindVariable(v), nil + case uint64: + return Uint64BindVariable(v), nil + case float64: + return Float64BindVariable(v), nil + case nil: + return NullBindVariable, nil + case Value: + return ValueBindVariable(v), nil + case *querypb.BindVariable: + return v, nil + case []interface{}: + bv := &querypb.BindVariable{ + Type: querypb.Type_TUPLE, + Values: make([]*querypb.Value, len(v)), + } + values := make([]querypb.Value, len(v)) + for i, lv := range v { + lbv, err := BuildBindVariable(lv) + if err != nil { + return nil, err + } + values[i].Type = lbv.Type + values[i].Value = lbv.Value + bv.Values[i] = &values[i] + } + return bv, nil + case []string: + bv := &querypb.BindVariable{ + Type: querypb.Type_TUPLE, + Values: make([]*querypb.Value, len(v)), + } + values := make([]querypb.Value, len(v)) + for i, lv := range v { + values[i].Type = querypb.Type_VARCHAR + values[i].Value = []byte(lv) + bv.Values[i] = &values[i] + } + return bv, nil + case [][]byte: + bv := &querypb.BindVariable{ + Type: querypb.Type_TUPLE, + Values: make([]*querypb.Value, len(v)), + } + values := make([]querypb.Value, len(v)) + for i, lv := range v { + values[i].Type = querypb.Type_VARBINARY + values[i].Value = lv + bv.Values[i] = &values[i] + } + return bv, nil + case []int: + bv := &querypb.BindVariable{ + Type: querypb.Type_TUPLE, + Values: make([]*querypb.Value, len(v)), + } + values := make([]querypb.Value, len(v)) + for i, lv := range v { + values[i].Type = querypb.Type_INT64 + values[i].Value = strconv.AppendInt(nil, int64(lv), 10) + bv.Values[i] = &values[i] + } + return bv, nil + case []int64: + bv := &querypb.BindVariable{ + Type: querypb.Type_TUPLE, + Values: make([]*querypb.Value, len(v)), + } + values := make([]querypb.Value, len(v)) + for i, lv := range v { + values[i].Type = querypb.Type_INT64 + values[i].Value = strconv.AppendInt(nil, lv, 10) + bv.Values[i] = &values[i] + } + return bv, nil + case []uint64: + bv := &querypb.BindVariable{ + Type: querypb.Type_TUPLE, + Values: make([]*querypb.Value, len(v)), + } + values := make([]querypb.Value, len(v)) + for i, lv := range v { + values[i].Type = querypb.Type_UINT64 + values[i].Value = strconv.AppendUint(nil, lv, 10) + bv.Values[i] = &values[i] + } + return bv, nil + case []float64: + bv := &querypb.BindVariable{ + Type: querypb.Type_TUPLE, + Values: make([]*querypb.Value, len(v)), + } + values := make([]querypb.Value, len(v)) + for i, lv := range v { + values[i].Type = querypb.Type_FLOAT64 + values[i].Value = strconv.AppendFloat(nil, lv, 'g', -1, 64) + bv.Values[i] = &values[i] + } + return bv, nil + } + return nil, fmt.Errorf("type %T not supported as bind var: %v", v, v) +} + +// ValidateBindVariables validates a map[string]*querypb.BindVariable. +func ValidateBindVariables(bv map[string]*querypb.BindVariable) error { + for k, v := range bv { + if err := ValidateBindVariable(v); err != nil { + return fmt.Errorf("%s: %v", k, err) + } + } + return nil +} + +// ValidateBindVariable returns an error if the bind variable has inconsistent +// fields. +func ValidateBindVariable(bv *querypb.BindVariable) error { + if bv == nil { + return errors.New("bind variable is nil") + } + + if bv.Type == querypb.Type_TUPLE { + if len(bv.Values) == 0 { + return errors.New("empty tuple is not allowed") + } + for _, val := range bv.Values { + if val.Type == querypb.Type_TUPLE { + return errors.New("tuple not allowed inside another tuple") + } + if err := ValidateBindVariable(&querypb.BindVariable{Type: val.Type, Value: val.Value}); err != nil { + return err + } + } + return nil + } + + // If NewValue succeeds, the value is valid. + _, err := NewValue(bv.Type, bv.Value) + return err +} + +// BindVariableToValue converts a bind var into a Value. +func BindVariableToValue(bv *querypb.BindVariable) (Value, error) { + if bv.Type == querypb.Type_TUPLE { + return NULL, errors.New("cannot convert a TUPLE bind var into a value") + } + return MakeTrusted(bv.Type, bv.Value), nil +} + +// BindVariablesEqual compares two maps of bind variables. +func BindVariablesEqual(x, y map[string]*querypb.BindVariable) bool { + return reflect.DeepEqual(&querypb.BoundQuery{BindVariables: x}, &querypb.BoundQuery{BindVariables: y}) +} + +// CopyBindVariables returns a shallow-copy of the given bindVariables map. +func CopyBindVariables(bindVariables map[string]*querypb.BindVariable) map[string]*querypb.BindVariable { + result := make(map[string]*querypb.BindVariable, len(bindVariables)) + for key, value := range bindVariables { + result[key] = value + } + return result +} diff --git a/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/dependency/sqltypes/bind_variables_test.go b/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/dependency/sqltypes/bind_variables_test.go new file mode 100644 index 00000000..ca0636c8 --- /dev/null +++ b/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/dependency/sqltypes/bind_variables_test.go @@ -0,0 +1,553 @@ +/* +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 sqltypes + +import ( + "reflect" + "strings" + "testing" + + "github.com/xwb1989/sqlparser/dependency/querypb" +) + +func TestProtoConversions(t *testing.T) { + v := TestValue(Int64, "1") + got := ValueToProto(v) + want := &querypb.Value{Type: Int64, Value: []byte("1")} + if !reflect.DeepEqual(got, want) { + t.Errorf("ValueToProto: %v, want %v", got, want) + } + gotback := ProtoToValue(got) + if !reflect.DeepEqual(gotback, v) { + t.Errorf("ProtoToValue: %v, want %v", gotback, v) + } +} + +func TestBuildBindVariables(t *testing.T) { + tcases := []struct { + in map[string]interface{} + out map[string]*querypb.BindVariable + err string + }{{ + in: nil, + out: nil, + }, { + in: map[string]interface{}{ + "k": int64(1), + }, + out: map[string]*querypb.BindVariable{ + "k": Int64BindVariable(1), + }, + }, { + in: map[string]interface{}{ + "k": byte(1), + }, + err: "k: type uint8 not supported as bind var: 1", + }} + for _, tcase := range tcases { + bindVars, err := BuildBindVariables(tcase.in) + if err != nil { + if err.Error() != tcase.err { + t.Errorf("MapToBindVars(%v) error: %v, want %s", tcase.in, err, tcase.err) + } + continue + } + if tcase.err != "" { + t.Errorf("MapToBindVars(%v) error: nil, want %s", tcase.in, tcase.err) + continue + } + if !BindVariablesEqual(bindVars, tcase.out) { + t.Errorf("MapToBindVars(%v): %v, want %s", tcase.in, bindVars, tcase.out) + } + } +} + +func TestBuildBindVariable(t *testing.T) { + tcases := []struct { + in interface{} + out *querypb.BindVariable + err string + }{{ + in: "aa", + out: &querypb.BindVariable{ + Type: querypb.Type_VARCHAR, + Value: []byte("aa"), + }, + }, { + in: []byte("aa"), + out: &querypb.BindVariable{ + Type: querypb.Type_VARBINARY, + Value: []byte("aa"), + }, + }, { + in: int(1), + out: &querypb.BindVariable{ + Type: querypb.Type_INT64, + Value: []byte("1"), + }, + }, { + in: int64(1), + out: &querypb.BindVariable{ + Type: querypb.Type_INT64, + Value: []byte("1"), + }, + }, { + in: uint64(1), + out: &querypb.BindVariable{ + Type: querypb.Type_UINT64, + Value: []byte("1"), + }, + }, { + in: float64(1), + out: &querypb.BindVariable{ + Type: querypb.Type_FLOAT64, + Value: []byte("1"), + }, + }, { + in: nil, + out: NullBindVariable, + }, { + in: MakeTrusted(Int64, []byte("1")), + out: &querypb.BindVariable{ + Type: querypb.Type_INT64, + Value: []byte("1"), + }, + }, { + in: &querypb.BindVariable{ + Type: querypb.Type_INT64, + Value: []byte("1"), + }, + out: &querypb.BindVariable{ + Type: querypb.Type_INT64, + Value: []byte("1"), + }, + }, { + in: []interface{}{"aa", int64(1)}, + out: &querypb.BindVariable{ + Type: querypb.Type_TUPLE, + Values: []*querypb.Value{{ + Type: querypb.Type_VARCHAR, + Value: []byte("aa"), + }, { + Type: querypb.Type_INT64, + Value: []byte("1"), + }}, + }, + }, { + in: []string{"aa", "bb"}, + out: &querypb.BindVariable{ + Type: querypb.Type_TUPLE, + Values: []*querypb.Value{{ + Type: querypb.Type_VARCHAR, + Value: []byte("aa"), + }, { + Type: querypb.Type_VARCHAR, + Value: []byte("bb"), + }}, + }, + }, { + in: [][]byte{[]byte("aa"), []byte("bb")}, + out: &querypb.BindVariable{ + Type: querypb.Type_TUPLE, + Values: []*querypb.Value{{ + Type: querypb.Type_VARBINARY, + Value: []byte("aa"), + }, { + Type: querypb.Type_VARBINARY, + Value: []byte("bb"), + }}, + }, + }, { + in: []int{1, 2}, + out: &querypb.BindVariable{ + Type: querypb.Type_TUPLE, + Values: []*querypb.Value{{ + Type: querypb.Type_INT64, + Value: []byte("1"), + }, { + Type: querypb.Type_INT64, + Value: []byte("2"), + }}, + }, + }, { + in: []int64{1, 2}, + out: &querypb.BindVariable{ + Type: querypb.Type_TUPLE, + Values: []*querypb.Value{{ + Type: querypb.Type_INT64, + Value: []byte("1"), + }, { + Type: querypb.Type_INT64, + Value: []byte("2"), + }}, + }, + }, { + in: []uint64{1, 2}, + out: &querypb.BindVariable{ + Type: querypb.Type_TUPLE, + Values: []*querypb.Value{{ + Type: querypb.Type_UINT64, + Value: []byte("1"), + }, { + Type: querypb.Type_UINT64, + Value: []byte("2"), + }}, + }, + }, { + in: []float64{1, 2}, + out: &querypb.BindVariable{ + Type: querypb.Type_TUPLE, + Values: []*querypb.Value{{ + Type: querypb.Type_FLOAT64, + Value: []byte("1"), + }, { + Type: querypb.Type_FLOAT64, + Value: []byte("2"), + }}, + }, + }, { + in: byte(1), + err: "type uint8 not supported as bind var: 1", + }, { + in: []interface{}{1, byte(1)}, + err: "type uint8 not supported as bind var: 1", + }} + for _, tcase := range tcases { + bv, err := BuildBindVariable(tcase.in) + if err != nil { + if err.Error() != tcase.err { + t.Errorf("ToBindVar(%T(%v)) error: %v, want %s", tcase.in, tcase.in, err, tcase.err) + } + continue + } + if tcase.err != "" { + t.Errorf("ToBindVar(%T(%v)) error: nil, want %s", tcase.in, tcase.in, tcase.err) + continue + } + if !reflect.DeepEqual(bv, tcase.out) { + t.Errorf("ToBindVar(%T(%v)): %v, want %s", tcase.in, tcase.in, bv, tcase.out) + } + } +} + +func TestValidateBindVarables(t *testing.T) { + tcases := []struct { + in map[string]*querypb.BindVariable + err string + }{{ + in: map[string]*querypb.BindVariable{ + "v": { + Type: querypb.Type_INT64, + Value: []byte("1"), + }, + }, + err: "", + }, { + in: map[string]*querypb.BindVariable{ + "v": { + Type: querypb.Type_INT64, + Value: []byte("a"), + }, + }, + err: `v: strconv.ParseInt: parsing "a": invalid syntax`, + }, { + in: map[string]*querypb.BindVariable{ + "v": { + Type: querypb.Type_TUPLE, + Values: []*querypb.Value{{ + Type: Int64, + Value: []byte("a"), + }}, + }, + }, + err: `v: strconv.ParseInt: parsing "a": invalid syntax`, + }} + for _, tcase := range tcases { + err := ValidateBindVariables(tcase.in) + if tcase.err != "" { + if err == nil || err.Error() != tcase.err { + t.Errorf("ValidateBindVars(%v): %v, want %s", tcase.in, err, tcase.err) + } + continue + } + if err != nil { + t.Errorf("ValidateBindVars(%v): %v, want nil", tcase.in, err) + } + } +} + +func TestValidateBindVariable(t *testing.T) { + testcases := []struct { + in *querypb.BindVariable + err string + }{{ + in: &querypb.BindVariable{ + Type: querypb.Type_INT8, + Value: []byte("1"), + }, + }, { + in: &querypb.BindVariable{ + Type: querypb.Type_INT16, + Value: []byte("1"), + }, + }, { + in: &querypb.BindVariable{ + Type: querypb.Type_INT24, + Value: []byte("1"), + }, + }, { + in: &querypb.BindVariable{ + Type: querypb.Type_INT32, + Value: []byte("1"), + }, + }, { + in: &querypb.BindVariable{ + Type: querypb.Type_INT64, + Value: []byte("1"), + }, + }, { + in: &querypb.BindVariable{ + Type: querypb.Type_UINT8, + Value: []byte("1"), + }, + }, { + in: &querypb.BindVariable{ + Type: querypb.Type_UINT16, + Value: []byte("1"), + }, + }, { + in: &querypb.BindVariable{ + Type: querypb.Type_UINT24, + Value: []byte("1"), + }, + }, { + in: &querypb.BindVariable{ + Type: querypb.Type_UINT32, + Value: []byte("1"), + }, + }, { + in: &querypb.BindVariable{ + Type: querypb.Type_UINT64, + Value: []byte("1"), + }, + }, { + in: &querypb.BindVariable{ + Type: querypb.Type_FLOAT32, + Value: []byte("1.00"), + }, + }, { + in: &querypb.BindVariable{ + Type: querypb.Type_FLOAT64, + Value: []byte("1.00"), + }, + }, { + in: &querypb.BindVariable{ + Type: querypb.Type_DECIMAL, + Value: []byte("1.00"), + }, + }, { + in: &querypb.BindVariable{ + Type: querypb.Type_TIMESTAMP, + Value: []byte("2012-02-24 23:19:43"), + }, + }, { + in: &querypb.BindVariable{ + Type: querypb.Type_DATE, + Value: []byte("2012-02-24"), + }, + }, { + in: &querypb.BindVariable{ + Type: querypb.Type_TIME, + Value: []byte("23:19:43"), + }, + }, { + in: &querypb.BindVariable{ + Type: querypb.Type_DATETIME, + Value: []byte("2012-02-24 23:19:43"), + }, + }, { + in: &querypb.BindVariable{ + Type: querypb.Type_YEAR, + Value: []byte("1"), + }, + }, { + in: &querypb.BindVariable{ + Type: querypb.Type_TEXT, + Value: []byte("a"), + }, + }, { + in: &querypb.BindVariable{ + Type: querypb.Type_BLOB, + Value: []byte("a"), + }, + }, { + in: &querypb.BindVariable{ + Type: querypb.Type_VARCHAR, + Value: []byte("a"), + }, + }, { + in: &querypb.BindVariable{ + Type: querypb.Type_BINARY, + Value: []byte("a"), + }, + }, { + in: &querypb.BindVariable{ + Type: querypb.Type_CHAR, + Value: []byte("a"), + }, + }, { + in: &querypb.BindVariable{ + Type: querypb.Type_BIT, + Value: []byte("1"), + }, + }, { + in: &querypb.BindVariable{ + Type: querypb.Type_ENUM, + Value: []byte("a"), + }, + }, { + in: &querypb.BindVariable{ + Type: querypb.Type_SET, + Value: []byte("a"), + }, + }, { + in: &querypb.BindVariable{ + Type: querypb.Type_VARBINARY, + Value: []byte("a"), + }, + }, { + in: &querypb.BindVariable{ + Type: querypb.Type_INT64, + Value: []byte(InvalidNeg), + }, + err: "out of range", + }, { + in: &querypb.BindVariable{ + Type: querypb.Type_INT64, + Value: []byte(InvalidPos), + }, + err: "out of range", + }, { + in: &querypb.BindVariable{ + Type: querypb.Type_UINT64, + Value: []byte("-1"), + }, + err: "invalid syntax", + }, { + in: &querypb.BindVariable{ + Type: querypb.Type_UINT64, + Value: []byte(InvalidPos), + }, + err: "out of range", + }, { + in: &querypb.BindVariable{ + Type: querypb.Type_FLOAT64, + Value: []byte("a"), + }, + err: "invalid syntax", + }, { + in: &querypb.BindVariable{ + Type: querypb.Type_EXPRESSION, + Value: []byte("a"), + }, + err: "invalid type specified for MakeValue: EXPRESSION", + }, { + in: &querypb.BindVariable{ + Type: querypb.Type_TUPLE, + Values: []*querypb.Value{{ + Type: querypb.Type_INT64, + Value: []byte("1"), + }}, + }, + }, { + in: &querypb.BindVariable{ + Type: querypb.Type_TUPLE, + }, + err: "empty tuple is not allowed", + }, { + in: &querypb.BindVariable{ + Type: querypb.Type_TUPLE, + Values: []*querypb.Value{{ + Type: querypb.Type_TUPLE, + }}, + }, + err: "tuple not allowed inside another tuple", + }} + for _, tcase := range testcases { + err := ValidateBindVariable(tcase.in) + if tcase.err != "" { + if err == nil || !strings.Contains(err.Error(), tcase.err) { + t.Errorf("ValidateBindVar(%v) error: %v, must contain %v", tcase.in, err, tcase.err) + } + continue + } + if err != nil { + t.Errorf("ValidateBindVar(%v) error: %v", tcase.in, err) + } + } + + // Special case: nil bind var. + err := ValidateBindVariable(nil) + want := "bind variable is nil" + if err == nil || err.Error() != want { + t.Errorf("ValidateBindVar(nil) error: %v, want %s", err, want) + } +} + +func TestBindVariableToValue(t *testing.T) { + v, err := BindVariableToValue(Int64BindVariable(1)) + if err != nil { + t.Error(err) + } + want := MakeTrusted(querypb.Type_INT64, []byte("1")) + if !reflect.DeepEqual(v, want) { + t.Errorf("BindVarToValue(1): %v, want %v", v, want) + } + + v, err = BindVariableToValue(&querypb.BindVariable{Type: querypb.Type_TUPLE}) + wantErr := "cannot convert a TUPLE bind var into a value" + if err == nil || err.Error() != wantErr { + t.Errorf(" BindVarToValue(TUPLE): %v, want %s", err, wantErr) + } +} + +func TestBindVariablesEqual(t *testing.T) { + bv1 := map[string]*querypb.BindVariable{ + "k": { + Type: querypb.Type_INT64, + Value: []byte("1"), + }, + } + bv2 := map[string]*querypb.BindVariable{ + "k": { + Type: querypb.Type_INT64, + Value: []byte("1"), + }, + } + bv3 := map[string]*querypb.BindVariable{ + "k": { + Type: querypb.Type_INT64, + Value: []byte("1"), + }, + } + if !BindVariablesEqual(bv1, bv2) { + t.Errorf("%v != %v, want equal", bv1, bv2) + } + if !BindVariablesEqual(bv1, bv3) { + t.Errorf("%v = %v, want not equal", bv1, bv3) + } +} diff --git a/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/dependency/sqltypes/plan_value.go b/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/dependency/sqltypes/plan_value.go new file mode 100644 index 00000000..7936a6ba --- /dev/null +++ b/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/dependency/sqltypes/plan_value.go @@ -0,0 +1,259 @@ +/* +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 sqltypes + +import ( + "encoding/json" + "errors" + "fmt" + + "github.com/xwb1989/sqlparser/dependency/querypb" +) + +// PlanValue represents a value or a list of values for +// a column that will later be resolved using bind vars and used +// to perform plan actions like generating the final query or +// deciding on a route. +// +// Plan values are typically used as a slice ([]planValue) +// where each entry is for one column. For situations where +// the required output is a list of rows (like in the case +// of multi-value inserts), the representation is pivoted. +// For example, a statement like this: +// INSERT INTO t VALUES (1, 2), (3, 4) +// will be represented as follows: +// []PlanValue{ +// Values: {1, 3}, +// Values: {2, 4}, +// } +// +// For WHERE clause items that contain a combination of +// equality expressions and IN clauses like this: +// WHERE pk1 = 1 AND pk2 IN (2, 3, 4) +// The plan values will be represented as follows: +// []PlanValue{ +// Value: 1, +// Values: {2, 3, 4}, +// } +// When converted into rows, columns with single values +// are replicated as the same for all rows: +// [][]Value{ +// {1, 2}, +// {1, 3}, +// {1, 4}, +// } +type PlanValue struct { + Key string + Value Value + ListKey string + Values []PlanValue +} + +// IsNull returns true if the PlanValue is NULL. +func (pv PlanValue) IsNull() bool { + return pv.Key == "" && pv.Value.IsNull() && pv.ListKey == "" && pv.Values == nil +} + +// IsList returns true if the PlanValue is a list. +func (pv PlanValue) IsList() bool { + return pv.ListKey != "" || pv.Values != nil +} + +// ResolveValue resolves a PlanValue as a single value based on the supplied bindvars. +func (pv PlanValue) ResolveValue(bindVars map[string]*querypb.BindVariable) (Value, error) { + switch { + case pv.Key != "": + bv, err := pv.lookupValue(bindVars) + if err != nil { + return NULL, err + } + return MakeTrusted(bv.Type, bv.Value), nil + case !pv.Value.IsNull(): + return pv.Value, nil + case pv.ListKey != "" || pv.Values != nil: + // This code is unreachable because the parser does not allow + // multi-value constructs where a single value is expected. + return NULL, errors.New("a list was supplied where a single value was expected") + } + return NULL, nil +} + +func (pv PlanValue) lookupValue(bindVars map[string]*querypb.BindVariable) (*querypb.BindVariable, error) { + bv, ok := bindVars[pv.Key] + if !ok { + return nil, fmt.Errorf("missing bind var %s", pv.Key) + } + if bv.Type == querypb.Type_TUPLE { + return nil, fmt.Errorf("TUPLE was supplied for single value bind var %s", pv.ListKey) + } + return bv, nil +} + +// ResolveList resolves a PlanValue as a list of values based on the supplied bindvars. +func (pv PlanValue) ResolveList(bindVars map[string]*querypb.BindVariable) ([]Value, error) { + switch { + case pv.ListKey != "": + bv, err := pv.lookupList(bindVars) + if err != nil { + return nil, err + } + values := make([]Value, 0, len(bv.Values)) + for _, val := range bv.Values { + values = append(values, MakeTrusted(val.Type, val.Value)) + } + return values, nil + case pv.Values != nil: + values := make([]Value, 0, len(pv.Values)) + for _, val := range pv.Values { + v, err := val.ResolveValue(bindVars) + if err != nil { + return nil, err + } + values = append(values, v) + } + return values, nil + } + // This code is unreachable because the parser does not allow + // single value constructs where multiple values are expected. + return nil, errors.New("a single value was supplied where a list was expected") +} + +func (pv PlanValue) lookupList(bindVars map[string]*querypb.BindVariable) (*querypb.BindVariable, error) { + bv, ok := bindVars[pv.ListKey] + if !ok { + return nil, fmt.Errorf("missing bind var %s", pv.ListKey) + } + if bv.Type != querypb.Type_TUPLE { + return nil, fmt.Errorf("single value was supplied for TUPLE bind var %s", pv.ListKey) + } + return bv, nil +} + +// MarshalJSON should be used only for testing. +func (pv PlanValue) MarshalJSON() ([]byte, error) { + switch { + case pv.Key != "": + return json.Marshal(":" + pv.Key) + case !pv.Value.IsNull(): + if pv.Value.IsIntegral() { + return pv.Value.ToBytes(), nil + } + return json.Marshal(pv.Value.ToString()) + case pv.ListKey != "": + return json.Marshal("::" + pv.ListKey) + case pv.Values != nil: + return json.Marshal(pv.Values) + } + return []byte("null"), nil +} + +func rowCount(pvs []PlanValue, bindVars map[string]*querypb.BindVariable) (int, error) { + count := -1 + setCount := func(l int) error { + switch count { + case -1: + count = l + return nil + case l: + return nil + default: + return errors.New("mismatch in number of column values") + } + } + + for _, pv := range pvs { + switch { + case pv.Key != "" || !pv.Value.IsNull(): + continue + case pv.Values != nil: + if err := setCount(len(pv.Values)); err != nil { + return 0, err + } + case pv.ListKey != "": + bv, err := pv.lookupList(bindVars) + if err != nil { + return 0, err + } + if err := setCount(len(bv.Values)); err != nil { + return 0, err + } + } + } + + if count == -1 { + // If there were no lists inside, it was a single row. + // Note that count can never be 0 because there is enough + // protection at the top level: list bind vars must have + // at least one value (enforced by vtgate), and AST lists + // must have at least one value (enforced by the parser). + // Also lists created internally after vtgate validation + // ensure at least one value. + // TODO(sougou): verify and change API to enforce this. + return 1, nil + } + return count, nil +} + +// ResolveRows resolves a []PlanValue as rows based on the supplied bindvars. +func ResolveRows(pvs []PlanValue, bindVars map[string]*querypb.BindVariable) ([][]Value, error) { + count, err := rowCount(pvs, bindVars) + if err != nil { + return nil, err + } + + // Allocate the rows. + rows := make([][]Value, count) + for i := range rows { + rows[i] = make([]Value, len(pvs)) + } + + // Using j becasue we're resolving by columns. + for j, pv := range pvs { + switch { + case pv.Key != "": + bv, err := pv.lookupValue(bindVars) + if err != nil { + return nil, err + } + for i := range rows { + rows[i][j] = MakeTrusted(bv.Type, bv.Value) + } + case !pv.Value.IsNull(): + for i := range rows { + rows[i][j] = pv.Value + } + case pv.ListKey != "": + bv, err := pv.lookupList(bindVars) + if err != nil { + // This code is unreachable because pvRowCount already checks this. + return nil, err + } + for i := range rows { + rows[i][j] = MakeTrusted(bv.Values[i].Type, bv.Values[i].Value) + } + case pv.Values != nil: + for i := range rows { + rows[i][j], err = pv.Values[i].ResolveValue(bindVars) + if err != nil { + return nil, err + } + } + // default case is a NULL value, which the row values are already initialized to. + } + } + return rows, nil +} diff --git a/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/dependency/sqltypes/plan_value_test.go b/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/dependency/sqltypes/plan_value_test.go new file mode 100644 index 00000000..ea85c9c6 --- /dev/null +++ b/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/dependency/sqltypes/plan_value_test.go @@ -0,0 +1,319 @@ +/* +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 sqltypes + +import ( + "reflect" + "strings" + "testing" + + "github.com/xwb1989/sqlparser/dependency/querypb" +) + +func TestPlanValueIsNull(t *testing.T) { + tcases := []struct { + in PlanValue + out bool + }{{ + in: PlanValue{}, + out: true, + }, { + in: PlanValue{Key: "aa"}, + out: false, + }, { + in: PlanValue{Value: NewVarBinary("aa")}, + out: false, + }, { + in: PlanValue{ListKey: "aa"}, + out: false, + }, { + in: PlanValue{Values: []PlanValue{}}, + out: false, + }} + for _, tc := range tcases { + got := tc.in.IsNull() + if got != tc.out { + t.Errorf("IsNull(%v): %v, want %v", tc.in, got, tc.out) + } + } +} + +func TestPlanValueIsList(t *testing.T) { + tcases := []struct { + in PlanValue + out bool + }{{ + in: PlanValue{}, + out: false, + }, { + in: PlanValue{Key: "aa"}, + out: false, + }, { + in: PlanValue{Value: NewVarBinary("aa")}, + out: false, + }, { + in: PlanValue{ListKey: "aa"}, + out: true, + }, { + in: PlanValue{Values: []PlanValue{}}, + out: true, + }} + for _, tc := range tcases { + got := tc.in.IsList() + if got != tc.out { + t.Errorf("IsList(%v): %v, want %v", tc.in, got, tc.out) + } + } +} + +func TestResolveRows(t *testing.T) { + testBindVars := map[string]*querypb.BindVariable{ + "int": Int64BindVariable(10), + "intstr": TestBindVariable([]interface{}{10, "aa"}), + } + intValue := MakeTrusted(Int64, []byte("10")) + strValue := MakeTrusted(VarChar, []byte("aa")) + tcases := []struct { + in []PlanValue + out [][]Value + err string + }{{ + // Simple cases. + in: []PlanValue{ + {Key: "int"}, + }, + out: [][]Value{ + {intValue}, + }, + }, { + in: []PlanValue{ + {Value: intValue}, + }, + out: [][]Value{ + {intValue}, + }, + }, { + in: []PlanValue{ + {ListKey: "intstr"}, + }, + out: [][]Value{ + {intValue}, + {strValue}, + }, + }, { + in: []PlanValue{ + {Values: []PlanValue{{Value: intValue}, {Value: strValue}}}, + }, + out: [][]Value{ + {intValue}, + {strValue}, + }, + }, { + in: []PlanValue{ + {Values: []PlanValue{{Key: "int"}, {Value: strValue}}}, + }, + out: [][]Value{ + {intValue}, + {strValue}, + }, + }, { + in: []PlanValue{{}}, + out: [][]Value{ + {NULL}, + }, + }, { + // Cases with varying rowcounts. + // All types of input.. + in: []PlanValue{ + {Key: "int"}, + {Value: strValue}, + {ListKey: "intstr"}, + {Values: []PlanValue{{Value: strValue}, {Value: intValue}}}, + }, + out: [][]Value{ + {intValue, strValue, intValue, strValue}, + {intValue, strValue, strValue, intValue}, + }, + }, { + // list, val, list. + in: []PlanValue{ + {Value: strValue}, + {Key: "int"}, + {Values: []PlanValue{{Value: strValue}, {Value: intValue}}}, + }, + out: [][]Value{ + {strValue, intValue, strValue}, + {strValue, intValue, intValue}, + }, + }, { + // list, list + in: []PlanValue{ + {ListKey: "intstr"}, + {Values: []PlanValue{{Value: strValue}, {Value: intValue}}}, + }, + out: [][]Value{ + {intValue, strValue}, + {strValue, intValue}, + }, + }, { + // Error cases + in: []PlanValue{ + {ListKey: "intstr"}, + {Values: []PlanValue{{Value: strValue}}}, + }, + err: "mismatch in number of column values", + }, { + // This is a different code path for a similar validation. + in: []PlanValue{ + {Values: []PlanValue{{Value: strValue}}}, + {ListKey: "intstr"}, + }, + err: "mismatch in number of column values", + }, { + in: []PlanValue{ + {Key: "absent"}, + }, + err: "missing bind var", + }, { + in: []PlanValue{ + {ListKey: "absent"}, + }, + err: "missing bind var", + }, { + in: []PlanValue{ + {Values: []PlanValue{{Key: "absent"}}}, + }, + err: "missing bind var", + }} + + for _, tc := range tcases { + got, err := ResolveRows(tc.in, testBindVars) + if err != nil { + if !strings.Contains(err.Error(), tc.err) { + t.Errorf("ResolveRows(%v) error: %v, want '%s'", tc.in, err, tc.err) + } + continue + } + if tc.err != "" { + t.Errorf("ResolveRows(%v) error: nil, want '%s'", tc.in, tc.err) + continue + } + if !reflect.DeepEqual(got, tc.out) { + t.Errorf("ResolveRows(%v): %v, want %v", tc.in, got, tc.out) + } + } +} + +func TestResolveList(t *testing.T) { + testBindVars := map[string]*querypb.BindVariable{ + "int": Int64BindVariable(10), + "intstr": TestBindVariable([]interface{}{10, "aa"}), + } + intValue := MakeTrusted(Int64, []byte("10")) + strValue := MakeTrusted(VarChar, []byte("aa")) + tcases := []struct { + in PlanValue + out []Value + err string + }{{ + in: PlanValue{ListKey: "intstr"}, + out: []Value{intValue, strValue}, + }, { + in: PlanValue{Values: []PlanValue{{Value: intValue}, {Value: strValue}}}, + out: []Value{intValue, strValue}, + }, { + in: PlanValue{Values: []PlanValue{{Key: "int"}, {Value: strValue}}}, + out: []Value{intValue, strValue}, + }, { + in: PlanValue{ListKey: "absent"}, + err: "missing bind var", + }, { + in: PlanValue{Values: []PlanValue{{Key: "absent"}, {Value: strValue}}}, + err: "missing bind var", + }, { + in: PlanValue{ListKey: "int"}, + err: "single value was supplied for TUPLE bind var", + }, { + in: PlanValue{Key: "int"}, + err: "a single value was supplied where a list was expected", + }} + + for _, tc := range tcases { + got, err := tc.in.ResolveList(testBindVars) + if err != nil { + if !strings.Contains(err.Error(), tc.err) { + t.Errorf("ResolveList(%v) error: %v, want '%s'", tc.in, err, tc.err) + } + continue + } + if tc.err != "" { + t.Errorf("ResolveList(%v) error: nil, want '%s'", tc.in, tc.err) + continue + } + if !reflect.DeepEqual(got, tc.out) { + t.Errorf("ResolveList(%v): %v, want %v", tc.in, got, tc.out) + } + } +} + +func TestResolveValue(t *testing.T) { + testBindVars := map[string]*querypb.BindVariable{ + "int": Int64BindVariable(10), + "intstr": TestBindVariable([]interface{}{10, "aa"}), + } + intValue := MakeTrusted(Int64, []byte("10")) + tcases := []struct { + in PlanValue + out Value + err string + }{{ + in: PlanValue{Key: "int"}, + out: intValue, + }, { + in: PlanValue{Value: intValue}, + out: intValue, + }, { + in: PlanValue{}, + out: NULL, + }, { + in: PlanValue{Key: "absent"}, + err: "missing bind var", + }, { + in: PlanValue{Key: "intstr"}, + err: "TUPLE was supplied for single value bind var", + }, { + in: PlanValue{ListKey: "intstr"}, + err: "a list was supplied where a single value was expected", + }} + + for _, tc := range tcases { + got, err := tc.in.ResolveValue(testBindVars) + if err != nil { + if !strings.Contains(err.Error(), tc.err) { + t.Errorf("ResolveValue(%v) error: %v, want '%s'", tc.in, err, tc.err) + } + continue + } + if tc.err != "" { + t.Errorf("ResolveValue(%v) error: nil, want '%s'", tc.in, tc.err) + continue + } + if !reflect.DeepEqual(got, tc.out) { + t.Errorf("ResolveValue(%v): %v, want %v", tc.in, got, tc.out) + } + } +} diff --git a/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/dependency/sqltypes/testing.go b/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/dependency/sqltypes/testing.go new file mode 100644 index 00000000..0acaedda --- /dev/null +++ b/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/dependency/sqltypes/testing.go @@ -0,0 +1,154 @@ +/* +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 sqltypes + +import ( + querypb "github.com/xwb1989/sqlparser/dependency/querypb" +) + +// Functions in this file should only be used for testing. +// This is an experiment to see if test code bloat can be +// reduced and readability improved. + +/* +// MakeTestFields builds a []*querypb.Field for testing. +// fields := sqltypes.MakeTestFields( +// "a|b", +// "int64|varchar", +// ) +// The field types are as defined in querypb and are case +// insensitive. Column delimiters must be used only to sepearate +// strings and not at the beginning or the end. +func MakeTestFields(names, types string) []*querypb.Field { + n := split(names) + t := split(types) + var fields []*querypb.Field + for i := range n { + fields = append(fields, &querypb.Field{ + Name: n[i], + Type: querypb.Type(querypb.Type_value[strings.ToUpper(t[i])]), + }) + } + return fields +} + +// MakeTestResult builds a *sqltypes.Result object for testing. +// result := sqltypes.MakeTestResult( +// fields, +// " 1|a", +// "10|abcd", +// ) +// The field type values are set as the types for the rows built. +// Spaces are trimmed from row values. "null" is treated as NULL. +func MakeTestResult(fields []*querypb.Field, rows ...string) *Result { + result := &Result{ + Fields: fields, + } + if len(rows) > 0 { + result.Rows = make([][]Value, len(rows)) + } + for i, row := range rows { + result.Rows[i] = make([]Value, len(fields)) + for j, col := range split(row) { + if col == "null" { + continue + } + result.Rows[i][j] = MakeTrusted(fields[j].Type, []byte(col)) + } + } + result.RowsAffected = uint64(len(result.Rows)) + return result +} + +// MakeTestStreamingResults builds a list of results for streaming. +// results := sqltypes.MakeStreamingResults( +// fields, +// "1|a", +// "2|b", +// "---", +// "c|c", +// ) +// The first result contains only the fields. Subsequent results +// are built using the field types. Every input that starts with a "-" +// is treated as streaming delimiter for one result. A final +// delimiter must not be supplied. +func MakeTestStreamingResults(fields []*querypb.Field, rows ...string) []*Result { + var results []*Result + results = append(results, &Result{Fields: fields}) + start := 0 + cur := 0 + // Add a final streaming delimiter to simplify the loop below. + rows = append(rows, "-") + for cur < len(rows) { + if rows[cur][0] != '-' { + cur++ + continue + } + result := MakeTestResult(fields, rows[start:cur]...) + result.Fields = nil + result.RowsAffected = 0 + results = append(results, result) + start = cur + 1 + cur = start + } + return results +} +*/ + +// TestBindVariable makes a *querypb.BindVariable from +// an interface{}.It panics on invalid input. +// This function should only be used for testing. +func TestBindVariable(v interface{}) *querypb.BindVariable { + if v == nil { + return NullBindVariable + } + bv, err := BuildBindVariable(v) + if err != nil { + panic(err) + } + return bv +} + +// TestValue builds a Value from typ and val. +// This function should only be used for testing. +func TestValue(typ querypb.Type, val string) Value { + return MakeTrusted(typ, []byte(val)) +} + +/* +// PrintResults prints []*Results into a string. +// This function should only be used for testing. +func PrintResults(results []*Result) string { + b := new(bytes.Buffer) + for i, r := range results { + if i == 0 { + fmt.Fprintf(b, "%v", r) + continue + } + fmt.Fprintf(b, ", %v", r) + } + return b.String() +} + +func split(str string) []string { + splits := strings.Split(str, "|") + for i, v := range splits { + splits[i] = strings.TrimSpace(v) + } + return splits +} +*/ diff --git a/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/dependency/sqltypes/type.go b/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/dependency/sqltypes/type.go new file mode 100644 index 00000000..49224e4b --- /dev/null +++ b/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/dependency/sqltypes/type.go @@ -0,0 +1,288 @@ +/* +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 sqltypes + +import ( + "fmt" + + "github.com/xwb1989/sqlparser/dependency/querypb" +) + +// This file provides wrappers and support +// functions for querypb.Type. + +// These bit flags can be used to query on the +// common properties of types. +const ( + flagIsIntegral = int(querypb.Flag_ISINTEGRAL) + flagIsUnsigned = int(querypb.Flag_ISUNSIGNED) + flagIsFloat = int(querypb.Flag_ISFLOAT) + flagIsQuoted = int(querypb.Flag_ISQUOTED) + flagIsText = int(querypb.Flag_ISTEXT) + flagIsBinary = int(querypb.Flag_ISBINARY) +) + +// IsIntegral returns true if querypb.Type is an integral +// (signed/unsigned) that can be represented using +// up to 64 binary bits. +// If you have a Value object, use its member function. +func IsIntegral(t querypb.Type) bool { + return int(t)&flagIsIntegral == flagIsIntegral +} + +// IsSigned returns true if querypb.Type is a signed integral. +// If you have a Value object, use its member function. +func IsSigned(t querypb.Type) bool { + return int(t)&(flagIsIntegral|flagIsUnsigned) == flagIsIntegral +} + +// IsUnsigned returns true if querypb.Type is an unsigned integral. +// Caution: this is not the same as !IsSigned. +// If you have a Value object, use its member function. +func IsUnsigned(t querypb.Type) bool { + return int(t)&(flagIsIntegral|flagIsUnsigned) == flagIsIntegral|flagIsUnsigned +} + +// IsFloat returns true is querypb.Type is a floating point. +// If you have a Value object, use its member function. +func IsFloat(t querypb.Type) bool { + return int(t)&flagIsFloat == flagIsFloat +} + +// IsQuoted returns true if querypb.Type is a quoted text or binary. +// If you have a Value object, use its member function. +func IsQuoted(t querypb.Type) bool { + return int(t)&flagIsQuoted == flagIsQuoted +} + +// IsText returns true if querypb.Type is a text. +// If you have a Value object, use its member function. +func IsText(t querypb.Type) bool { + return int(t)&flagIsText == flagIsText +} + +// IsBinary returns true if querypb.Type is a binary. +// If you have a Value object, use its member function. +func IsBinary(t querypb.Type) bool { + return int(t)&flagIsBinary == flagIsBinary +} + +// isNumber returns true if the type is any type of number. +func isNumber(t querypb.Type) bool { + return IsIntegral(t) || IsFloat(t) || t == Decimal +} + +// Vitess data types. These are idiomatically +// named synonyms for the querypb.Type values. +// Although these constants are interchangeable, +// they should be treated as different from querypb.Type. +// Use the synonyms only to refer to the type in Value. +// For proto variables, use the querypb.Type constants +// instead. +// The following conditions are non-overlapping +// and cover all types: IsSigned(), IsUnsigned(), +// IsFloat(), IsQuoted(), Null, Decimal, Expression. +// Also, IsIntegral() == (IsSigned()||IsUnsigned()). +// TestCategory needs to be updated accordingly if +// you add a new type. +// If IsBinary or IsText is true, then IsQuoted is +// also true. But there are IsQuoted types that are +// neither binary or text. +// querypb.Type_TUPLE is not included in this list +// because it's not a valid Value type. +// TODO(sougou): provide a categorization function +// that returns enums, which will allow for cleaner +// switch statements for those who want to cover types +// by their category. +const ( + Null = querypb.Type_NULL_TYPE + Int8 = querypb.Type_INT8 + Uint8 = querypb.Type_UINT8 + Int16 = querypb.Type_INT16 + Uint16 = querypb.Type_UINT16 + Int24 = querypb.Type_INT24 + Uint24 = querypb.Type_UINT24 + Int32 = querypb.Type_INT32 + Uint32 = querypb.Type_UINT32 + Int64 = querypb.Type_INT64 + Uint64 = querypb.Type_UINT64 + Float32 = querypb.Type_FLOAT32 + Float64 = querypb.Type_FLOAT64 + Timestamp = querypb.Type_TIMESTAMP + Date = querypb.Type_DATE + Time = querypb.Type_TIME + Datetime = querypb.Type_DATETIME + Year = querypb.Type_YEAR + Decimal = querypb.Type_DECIMAL + Text = querypb.Type_TEXT + Blob = querypb.Type_BLOB + VarChar = querypb.Type_VARCHAR + VarBinary = querypb.Type_VARBINARY + Char = querypb.Type_CHAR + Binary = querypb.Type_BINARY + Bit = querypb.Type_BIT + Enum = querypb.Type_ENUM + Set = querypb.Type_SET + Geometry = querypb.Type_GEOMETRY + TypeJSON = querypb.Type_JSON + Expression = querypb.Type_EXPRESSION +) + +// bit-shift the mysql flags by two byte so we +// can merge them with the mysql or vitess types. +const ( + mysqlUnsigned = 32 + mysqlBinary = 128 + mysqlEnum = 256 + mysqlSet = 2048 +) + +// If you add to this map, make sure you add a test case +// in tabletserver/endtoend. +var mysqlToType = map[int64]querypb.Type{ + 1: Int8, + 2: Int16, + 3: Int32, + 4: Float32, + 5: Float64, + 6: Null, + 7: Timestamp, + 8: Int64, + 9: Int24, + 10: Date, + 11: Time, + 12: Datetime, + 13: Year, + 16: Bit, + 245: TypeJSON, + 246: Decimal, + 249: Text, + 250: Text, + 251: Text, + 252: Text, + 253: VarChar, + 254: Char, + 255: Geometry, +} + +// modifyType modifies the vitess type based on the +// mysql flag. The function checks specific flags based +// on the type. This allows us to ignore stray flags +// that MySQL occasionally sets. +func modifyType(typ querypb.Type, flags int64) querypb.Type { + switch typ { + case Int8: + if flags&mysqlUnsigned != 0 { + return Uint8 + } + return Int8 + case Int16: + if flags&mysqlUnsigned != 0 { + return Uint16 + } + return Int16 + case Int32: + if flags&mysqlUnsigned != 0 { + return Uint32 + } + return Int32 + case Int64: + if flags&mysqlUnsigned != 0 { + return Uint64 + } + return Int64 + case Int24: + if flags&mysqlUnsigned != 0 { + return Uint24 + } + return Int24 + case Text: + if flags&mysqlBinary != 0 { + return Blob + } + return Text + case VarChar: + if flags&mysqlBinary != 0 { + return VarBinary + } + return VarChar + case Char: + if flags&mysqlBinary != 0 { + return Binary + } + if flags&mysqlEnum != 0 { + return Enum + } + if flags&mysqlSet != 0 { + return Set + } + return Char + } + return typ +} + +// MySQLToType computes the vitess type from mysql type and flags. +func MySQLToType(mysqlType, flags int64) (typ querypb.Type, err error) { + result, ok := mysqlToType[mysqlType] + if !ok { + return 0, fmt.Errorf("unsupported type: %d", mysqlType) + } + return modifyType(result, flags), nil +} + +// typeToMySQL is the reverse of mysqlToType. +var typeToMySQL = map[querypb.Type]struct { + typ int64 + flags int64 +}{ + Int8: {typ: 1}, + Uint8: {typ: 1, flags: mysqlUnsigned}, + Int16: {typ: 2}, + Uint16: {typ: 2, flags: mysqlUnsigned}, + Int32: {typ: 3}, + Uint32: {typ: 3, flags: mysqlUnsigned}, + Float32: {typ: 4}, + Float64: {typ: 5}, + Null: {typ: 6, flags: mysqlBinary}, + Timestamp: {typ: 7}, + Int64: {typ: 8}, + Uint64: {typ: 8, flags: mysqlUnsigned}, + Int24: {typ: 9}, + Uint24: {typ: 9, flags: mysqlUnsigned}, + Date: {typ: 10, flags: mysqlBinary}, + Time: {typ: 11, flags: mysqlBinary}, + Datetime: {typ: 12, flags: mysqlBinary}, + Year: {typ: 13, flags: mysqlUnsigned}, + Bit: {typ: 16, flags: mysqlUnsigned}, + TypeJSON: {typ: 245}, + Decimal: {typ: 246}, + Text: {typ: 252}, + Blob: {typ: 252, flags: mysqlBinary}, + VarChar: {typ: 253}, + VarBinary: {typ: 253, flags: mysqlBinary}, + Char: {typ: 254}, + Binary: {typ: 254, flags: mysqlBinary}, + Enum: {typ: 254, flags: mysqlEnum}, + Set: {typ: 254, flags: mysqlSet}, + Geometry: {typ: 255}, +} + +// TypeToMySQL returns the equivalent mysql type and flag for a vitess type. +func TypeToMySQL(typ querypb.Type) (mysqlType, flags int64) { + val := typeToMySQL[typ] + return val.typ, val.flags +} diff --git a/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/dependency/sqltypes/type_test.go b/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/dependency/sqltypes/type_test.go new file mode 100644 index 00000000..613fcda1 --- /dev/null +++ b/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/dependency/sqltypes/type_test.go @@ -0,0 +1,414 @@ +/* +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 sqltypes + +import ( + "testing" + + "github.com/xwb1989/sqlparser/dependency/querypb" +) + +func TestTypeValues(t *testing.T) { + testcases := []struct { + defined querypb.Type + expected int + }{{ + defined: Null, + expected: 0, + }, { + defined: Int8, + expected: 1 | flagIsIntegral, + }, { + defined: Uint8, + expected: 2 | flagIsIntegral | flagIsUnsigned, + }, { + defined: Int16, + expected: 3 | flagIsIntegral, + }, { + defined: Uint16, + expected: 4 | flagIsIntegral | flagIsUnsigned, + }, { + defined: Int24, + expected: 5 | flagIsIntegral, + }, { + defined: Uint24, + expected: 6 | flagIsIntegral | flagIsUnsigned, + }, { + defined: Int32, + expected: 7 | flagIsIntegral, + }, { + defined: Uint32, + expected: 8 | flagIsIntegral | flagIsUnsigned, + }, { + defined: Int64, + expected: 9 | flagIsIntegral, + }, { + defined: Uint64, + expected: 10 | flagIsIntegral | flagIsUnsigned, + }, { + defined: Float32, + expected: 11 | flagIsFloat, + }, { + defined: Float64, + expected: 12 | flagIsFloat, + }, { + defined: Timestamp, + expected: 13 | flagIsQuoted, + }, { + defined: Date, + expected: 14 | flagIsQuoted, + }, { + defined: Time, + expected: 15 | flagIsQuoted, + }, { + defined: Datetime, + expected: 16 | flagIsQuoted, + }, { + defined: Year, + expected: 17 | flagIsIntegral | flagIsUnsigned, + }, { + defined: Decimal, + expected: 18, + }, { + defined: Text, + expected: 19 | flagIsQuoted | flagIsText, + }, { + defined: Blob, + expected: 20 | flagIsQuoted | flagIsBinary, + }, { + defined: VarChar, + expected: 21 | flagIsQuoted | flagIsText, + }, { + defined: VarBinary, + expected: 22 | flagIsQuoted | flagIsBinary, + }, { + defined: Char, + expected: 23 | flagIsQuoted | flagIsText, + }, { + defined: Binary, + expected: 24 | flagIsQuoted | flagIsBinary, + }, { + defined: Bit, + expected: 25 | flagIsQuoted, + }, { + defined: Enum, + expected: 26 | flagIsQuoted, + }, { + defined: Set, + expected: 27 | flagIsQuoted, + }, { + defined: Geometry, + expected: 29 | flagIsQuoted, + }, { + defined: TypeJSON, + expected: 30 | flagIsQuoted, + }, { + defined: Expression, + expected: 31, + }} + for _, tcase := range testcases { + if int(tcase.defined) != tcase.expected { + t.Errorf("Type %s: %d, want: %d", tcase.defined, int(tcase.defined), tcase.expected) + } + } +} + +// TestCategory verifies that the type categorizations +// are non-overlapping and complete. +func TestCategory(t *testing.T) { + alltypes := []querypb.Type{ + Null, + Int8, + Uint8, + Int16, + Uint16, + Int24, + Uint24, + Int32, + Uint32, + Int64, + Uint64, + Float32, + Float64, + Timestamp, + Date, + Time, + Datetime, + Year, + Decimal, + Text, + Blob, + VarChar, + VarBinary, + Char, + Binary, + Bit, + Enum, + Set, + Geometry, + TypeJSON, + Expression, + } + for _, typ := range alltypes { + matched := false + if IsSigned(typ) { + if !IsIntegral(typ) { + t.Errorf("Signed type %v is not an integral", typ) + } + matched = true + } + if IsUnsigned(typ) { + if !IsIntegral(typ) { + t.Errorf("Unsigned type %v is not an integral", typ) + } + if matched { + t.Errorf("%v matched more than one category", typ) + } + matched = true + } + if IsFloat(typ) { + if matched { + t.Errorf("%v matched more than one category", typ) + } + matched = true + } + if IsQuoted(typ) { + if matched { + t.Errorf("%v matched more than one category", typ) + } + matched = true + } + if typ == Null || typ == Decimal || typ == Expression { + if matched { + t.Errorf("%v matched more than one category", typ) + } + matched = true + } + if !matched { + t.Errorf("%v matched no category", typ) + } + } +} + +func TestIsFunctions(t *testing.T) { + if IsIntegral(Null) { + t.Error("Null: IsIntegral, must be false") + } + if !IsIntegral(Int64) { + t.Error("Int64: !IsIntegral, must be true") + } + if IsSigned(Uint64) { + t.Error("Uint64: IsSigned, must be false") + } + if !IsSigned(Int64) { + t.Error("Int64: !IsSigned, must be true") + } + if IsUnsigned(Int64) { + t.Error("Int64: IsUnsigned, must be false") + } + if !IsUnsigned(Uint64) { + t.Error("Uint64: !IsUnsigned, must be true") + } + if IsFloat(Int64) { + t.Error("Int64: IsFloat, must be false") + } + if !IsFloat(Float64) { + t.Error("Uint64: !IsFloat, must be true") + } + if IsQuoted(Int64) { + t.Error("Int64: IsQuoted, must be false") + } + if !IsQuoted(Binary) { + t.Error("Binary: !IsQuoted, must be true") + } + if IsText(Int64) { + t.Error("Int64: IsText, must be false") + } + if !IsText(Char) { + t.Error("Char: !IsText, must be true") + } + if IsBinary(Int64) { + t.Error("Int64: IsBinary, must be false") + } + if !IsBinary(Binary) { + t.Error("Char: !IsBinary, must be true") + } + if !isNumber(Int64) { + t.Error("Int64: !isNumber, must be true") + } +} + +func TestTypeToMySQL(t *testing.T) { + v, f := TypeToMySQL(Bit) + if v != 16 { + t.Errorf("Bit: %d, want 16", v) + } + if f != mysqlUnsigned { + t.Errorf("Bit flag: %x, want %x", f, mysqlUnsigned) + } + v, f = TypeToMySQL(Date) + if v != 10 { + t.Errorf("Bit: %d, want 10", v) + } + if f != mysqlBinary { + t.Errorf("Bit flag: %x, want %x", f, mysqlBinary) + } +} + +func TestMySQLToType(t *testing.T) { + testcases := []struct { + intype int64 + inflags int64 + outtype querypb.Type + }{{ + intype: 1, + outtype: Int8, + }, { + intype: 1, + inflags: mysqlUnsigned, + outtype: Uint8, + }, { + intype: 2, + outtype: Int16, + }, { + intype: 2, + inflags: mysqlUnsigned, + outtype: Uint16, + }, { + intype: 3, + outtype: Int32, + }, { + intype: 3, + inflags: mysqlUnsigned, + outtype: Uint32, + }, { + intype: 4, + outtype: Float32, + }, { + intype: 5, + outtype: Float64, + }, { + intype: 6, + outtype: Null, + }, { + intype: 7, + outtype: Timestamp, + }, { + intype: 8, + outtype: Int64, + }, { + intype: 8, + inflags: mysqlUnsigned, + outtype: Uint64, + }, { + intype: 9, + outtype: Int24, + }, { + intype: 9, + inflags: mysqlUnsigned, + outtype: Uint24, + }, { + intype: 10, + outtype: Date, + }, { + intype: 11, + outtype: Time, + }, { + intype: 12, + outtype: Datetime, + }, { + intype: 13, + outtype: Year, + }, { + intype: 16, + outtype: Bit, + }, { + intype: 245, + outtype: TypeJSON, + }, { + intype: 246, + outtype: Decimal, + }, { + intype: 249, + outtype: Text, + }, { + intype: 250, + outtype: Text, + }, { + intype: 251, + outtype: Text, + }, { + intype: 252, + outtype: Text, + }, { + intype: 252, + inflags: mysqlBinary, + outtype: Blob, + }, { + intype: 253, + outtype: VarChar, + }, { + intype: 253, + inflags: mysqlBinary, + outtype: VarBinary, + }, { + intype: 254, + outtype: Char, + }, { + intype: 254, + inflags: mysqlBinary, + outtype: Binary, + }, { + intype: 254, + inflags: mysqlEnum, + outtype: Enum, + }, { + intype: 254, + inflags: mysqlSet, + outtype: Set, + }, { + intype: 255, + outtype: Geometry, + }, { + // Binary flag must be ignored. + intype: 8, + inflags: mysqlUnsigned | mysqlBinary, + outtype: Uint64, + }, { + // Unsigned flag must be ignored + intype: 252, + inflags: mysqlUnsigned | mysqlBinary, + outtype: Blob, + }} + for _, tcase := range testcases { + got, err := MySQLToType(tcase.intype, tcase.inflags) + if err != nil { + t.Error(err) + } + if got != tcase.outtype { + t.Errorf("MySQLToType(%d, %x): %v, want %v", tcase.intype, tcase.inflags, got, tcase.outtype) + } + } +} + +func TestTypeError(t *testing.T) { + _, err := MySQLToType(15, 0) + want := "unsupported type: 15" + if err == nil || err.Error() != want { + t.Errorf("MySQLToType: %v, want %s", err, want) + } +} diff --git a/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/dependency/sqltypes/value.go b/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/dependency/sqltypes/value.go new file mode 100644 index 00000000..a3bceeef --- /dev/null +++ b/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/dependency/sqltypes/value.go @@ -0,0 +1,376 @@ +/* +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 sqltypes implements interfaces and types that represent SQL values. +package sqltypes + +import ( + "encoding/base64" + "encoding/json" + "fmt" + "strconv" + + "github.com/xwb1989/sqlparser/dependency/bytes2" + "github.com/xwb1989/sqlparser/dependency/hack" + + "github.com/xwb1989/sqlparser/dependency/querypb" +) + +var ( + // NULL represents the NULL value. + NULL = Value{} + + // DontEscape tells you if a character should not be escaped. + DontEscape = byte(255) + + nullstr = []byte("null") +) + +// BinWriter interface is used for encoding values. +// Types like bytes.Buffer conform to this interface. +// We expect the writer objects to be in-memory buffers. +// So, we don't expect the write operations to fail. +type BinWriter interface { + Write([]byte) (int, error) +} + +// Value can store any SQL value. If the value represents +// an integral type, the bytes are always stored as a cannonical +// representation that matches how MySQL returns such values. +type Value struct { + typ querypb.Type + val []byte +} + +// NewValue builds a Value using typ and val. If the value and typ +// don't match, it returns an error. +func NewValue(typ querypb.Type, val []byte) (v Value, err error) { + switch { + case IsSigned(typ): + if _, err := strconv.ParseInt(string(val), 0, 64); err != nil { + return NULL, err + } + return MakeTrusted(typ, val), nil + case IsUnsigned(typ): + if _, err := strconv.ParseUint(string(val), 0, 64); err != nil { + return NULL, err + } + return MakeTrusted(typ, val), nil + case IsFloat(typ) || typ == Decimal: + if _, err := strconv.ParseFloat(string(val), 64); err != nil { + return NULL, err + } + return MakeTrusted(typ, val), nil + case IsQuoted(typ) || typ == Null: + return MakeTrusted(typ, val), nil + } + // All other types are unsafe or invalid. + return NULL, fmt.Errorf("invalid type specified for MakeValue: %v", typ) +} + +// MakeTrusted makes a new Value based on the type. +// This function should only be used if you know the value +// and type conform to the rules. Every place this function is +// called, a comment is needed that explains why it's justified. +// Exceptions: The current package and mysql package do not need +// comments. Other packages can also use the function to create +// VarBinary or VarChar values. +func MakeTrusted(typ querypb.Type, val []byte) Value { + if typ == Null { + return NULL + } + return Value{typ: typ, val: val} +} + +// NewInt64 builds an Int64 Value. +func NewInt64(v int64) Value { + return MakeTrusted(Int64, strconv.AppendInt(nil, v, 10)) +} + +// NewInt32 builds an Int64 Value. +func NewInt32(v int32) Value { + return MakeTrusted(Int32, strconv.AppendInt(nil, int64(v), 10)) +} + +// NewUint64 builds an Uint64 Value. +func NewUint64(v uint64) Value { + return MakeTrusted(Uint64, strconv.AppendUint(nil, v, 10)) +} + +// NewFloat64 builds an Float64 Value. +func NewFloat64(v float64) Value { + return MakeTrusted(Float64, strconv.AppendFloat(nil, v, 'g', -1, 64)) +} + +// NewVarChar builds a VarChar Value. +func NewVarChar(v string) Value { + return MakeTrusted(VarChar, []byte(v)) +} + +// NewVarBinary builds a VarBinary Value. +// The input is a string because it's the most common use case. +func NewVarBinary(v string) Value { + return MakeTrusted(VarBinary, []byte(v)) +} + +// NewIntegral builds an integral type from a string representaion. +// The type will be Int64 or Uint64. Int64 will be preferred where possible. +func NewIntegral(val string) (n Value, err error) { + signed, err := strconv.ParseInt(val, 0, 64) + if err == nil { + return MakeTrusted(Int64, strconv.AppendInt(nil, signed, 10)), nil + } + unsigned, err := strconv.ParseUint(val, 0, 64) + if err != nil { + return Value{}, err + } + return MakeTrusted(Uint64, strconv.AppendUint(nil, unsigned, 10)), nil +} + +// InterfaceToValue builds a value from a go type. +// Supported types are nil, int64, uint64, float64, +// string and []byte. +// This function is deprecated. Use the type-specific +// functions instead. +func InterfaceToValue(goval interface{}) (Value, error) { + switch goval := goval.(type) { + case nil: + return NULL, nil + case []byte: + return MakeTrusted(VarBinary, goval), nil + case int64: + return NewInt64(goval), nil + case uint64: + return NewUint64(goval), nil + case float64: + return NewFloat64(goval), nil + case string: + return NewVarChar(goval), nil + default: + return NULL, fmt.Errorf("unexpected type %T: %v", goval, goval) + } +} + +// Type returns the type of Value. +func (v Value) Type() querypb.Type { + return v.typ +} + +// Raw returns the internal represenation of the value. For newer types, +// this may not match MySQL's representation. +func (v Value) Raw() []byte { + return v.val +} + +// ToBytes returns the value as MySQL would return it as []byte. +// In contrast, Raw returns the internal representation of the Value, which may not +// match MySQL's representation for newer types. +// If the value is not convertible like in the case of Expression, it returns nil. +func (v Value) ToBytes() []byte { + if v.typ == Expression { + return nil + } + return v.val +} + +// Len returns the length. +func (v Value) Len() int { + return len(v.val) +} + +// ToString returns the value as MySQL would return it as string. +// If the value is not convertible like in the case of Expression, it returns nil. +func (v Value) ToString() string { + if v.typ == Expression { + return "" + } + return hack.String(v.val) +} + +// String returns a printable version of the value. +func (v Value) String() string { + if v.typ == Null { + return "NULL" + } + if v.IsQuoted() { + return fmt.Sprintf("%v(%q)", v.typ, v.val) + } + return fmt.Sprintf("%v(%s)", v.typ, v.val) +} + +// EncodeSQL encodes the value into an SQL statement. Can be binary. +func (v Value) EncodeSQL(b BinWriter) { + switch { + case v.typ == Null: + b.Write(nullstr) + case v.IsQuoted(): + encodeBytesSQL(v.val, b) + default: + b.Write(v.val) + } +} + +// EncodeASCII encodes the value using 7-bit clean ascii bytes. +func (v Value) EncodeASCII(b BinWriter) { + switch { + case v.typ == Null: + b.Write(nullstr) + case v.IsQuoted(): + encodeBytesASCII(v.val, b) + default: + b.Write(v.val) + } +} + +// IsNull returns true if Value is null. +func (v Value) IsNull() bool { + return v.typ == Null +} + +// IsIntegral returns true if Value is an integral. +func (v Value) IsIntegral() bool { + return IsIntegral(v.typ) +} + +// IsSigned returns true if Value is a signed integral. +func (v Value) IsSigned() bool { + return IsSigned(v.typ) +} + +// IsUnsigned returns true if Value is an unsigned integral. +func (v Value) IsUnsigned() bool { + return IsUnsigned(v.typ) +} + +// IsFloat returns true if Value is a float. +func (v Value) IsFloat() bool { + return IsFloat(v.typ) +} + +// IsQuoted returns true if Value must be SQL-quoted. +func (v Value) IsQuoted() bool { + return IsQuoted(v.typ) +} + +// IsText returns true if Value is a collatable text. +func (v Value) IsText() bool { + return IsText(v.typ) +} + +// IsBinary returns true if Value is binary. +func (v Value) IsBinary() bool { + return IsBinary(v.typ) +} + +// MarshalJSON should only be used for testing. +// It's not a complete implementation. +func (v Value) MarshalJSON() ([]byte, error) { + switch { + case v.IsQuoted(): + return json.Marshal(v.ToString()) + case v.typ == Null: + return nullstr, nil + } + return v.val, nil +} + +// UnmarshalJSON should only be used for testing. +// It's not a complete implementation. +func (v *Value) UnmarshalJSON(b []byte) error { + if len(b) == 0 { + return fmt.Errorf("error unmarshaling empty bytes") + } + var val interface{} + var err error + switch b[0] { + case '-': + var ival int64 + err = json.Unmarshal(b, &ival) + val = ival + case '"': + var bval []byte + err = json.Unmarshal(b, &bval) + val = bval + case 'n': // null + err = json.Unmarshal(b, &val) + default: + var uval uint64 + err = json.Unmarshal(b, &uval) + val = uval + } + if err != nil { + return err + } + *v, err = InterfaceToValue(val) + return err +} + +func encodeBytesSQL(val []byte, b BinWriter) { + buf := &bytes2.Buffer{} + buf.WriteByte('\'') + for _, ch := range val { + if encodedChar := SQLEncodeMap[ch]; encodedChar == DontEscape { + buf.WriteByte(ch) + } else { + buf.WriteByte('\\') + buf.WriteByte(encodedChar) + } + } + buf.WriteByte('\'') + b.Write(buf.Bytes()) +} + +func encodeBytesASCII(val []byte, b BinWriter) { + buf := &bytes2.Buffer{} + buf.WriteByte('\'') + encoder := base64.NewEncoder(base64.StdEncoding, buf) + encoder.Write(val) + encoder.Close() + buf.WriteByte('\'') + b.Write(buf.Bytes()) +} + +// SQLEncodeMap specifies how to escape binary data with '\'. +// Complies to http://dev.mysql.com/doc/refman/5.1/en/string-syntax.html +var SQLEncodeMap [256]byte + +// SQLDecodeMap is the reverse of SQLEncodeMap +var SQLDecodeMap [256]byte + +var encodeRef = map[byte]byte{ + '\x00': '0', + '\'': '\'', + '"': '"', + '\b': 'b', + '\n': 'n', + '\r': 'r', + '\t': 't', + 26: 'Z', // ctl-Z + '\\': '\\', +} + +func init() { + for i := range SQLEncodeMap { + SQLEncodeMap[i] = DontEscape + SQLDecodeMap[i] = DontEscape + } + for i := range SQLEncodeMap { + if to, ok := encodeRef[byte(i)]; ok { + SQLEncodeMap[byte(i)] = to + SQLDecodeMap[to] = byte(i) + } + } +} diff --git a/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/dependency/sqltypes/value_test.go b/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/dependency/sqltypes/value_test.go new file mode 100644 index 00000000..96b137d1 --- /dev/null +++ b/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/dependency/sqltypes/value_test.go @@ -0,0 +1,408 @@ +/* +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 sqltypes + +import ( + "bytes" + "reflect" + "strings" + "testing" + + "github.com/xwb1989/sqlparser/dependency/querypb" +) + +const ( + InvalidNeg = "-9223372036854775809" + MinNeg = "-9223372036854775808" + MinPos = "18446744073709551615" + InvalidPos = "18446744073709551616" +) + +func TestNewValue(t *testing.T) { + testcases := []struct { + inType querypb.Type + inVal string + outVal Value + outErr string + }{{ + inType: Null, + inVal: "", + outVal: NULL, + }, { + inType: Int8, + inVal: "1", + outVal: TestValue(Int8, "1"), + }, { + inType: Int16, + inVal: "1", + outVal: TestValue(Int16, "1"), + }, { + inType: Int24, + inVal: "1", + outVal: TestValue(Int24, "1"), + }, { + inType: Int32, + inVal: "1", + outVal: TestValue(Int32, "1"), + }, { + inType: Int64, + inVal: "1", + outVal: TestValue(Int64, "1"), + }, { + inType: Uint8, + inVal: "1", + outVal: TestValue(Uint8, "1"), + }, { + inType: Uint16, + inVal: "1", + outVal: TestValue(Uint16, "1"), + }, { + inType: Uint24, + inVal: "1", + outVal: TestValue(Uint24, "1"), + }, { + inType: Uint32, + inVal: "1", + outVal: TestValue(Uint32, "1"), + }, { + inType: Uint64, + inVal: "1", + outVal: TestValue(Uint64, "1"), + }, { + inType: Float32, + inVal: "1.00", + outVal: TestValue(Float32, "1.00"), + }, { + inType: Float64, + inVal: "1.00", + outVal: TestValue(Float64, "1.00"), + }, { + inType: Decimal, + inVal: "1.00", + outVal: TestValue(Decimal, "1.00"), + }, { + inType: Timestamp, + inVal: "2012-02-24 23:19:43", + outVal: TestValue(Timestamp, "2012-02-24 23:19:43"), + }, { + inType: Date, + inVal: "2012-02-24", + outVal: TestValue(Date, "2012-02-24"), + }, { + inType: Time, + inVal: "23:19:43", + outVal: TestValue(Time, "23:19:43"), + }, { + inType: Datetime, + inVal: "2012-02-24 23:19:43", + outVal: TestValue(Datetime, "2012-02-24 23:19:43"), + }, { + inType: Year, + inVal: "1", + outVal: TestValue(Year, "1"), + }, { + inType: Text, + inVal: "a", + outVal: TestValue(Text, "a"), + }, { + inType: Blob, + inVal: "a", + outVal: TestValue(Blob, "a"), + }, { + inType: VarChar, + inVal: "a", + outVal: TestValue(VarChar, "a"), + }, { + inType: Binary, + inVal: "a", + outVal: TestValue(Binary, "a"), + }, { + inType: Char, + inVal: "a", + outVal: TestValue(Char, "a"), + }, { + inType: Bit, + inVal: "1", + outVal: TestValue(Bit, "1"), + }, { + inType: Enum, + inVal: "a", + outVal: TestValue(Enum, "a"), + }, { + inType: Set, + inVal: "a", + outVal: TestValue(Set, "a"), + }, { + inType: VarBinary, + inVal: "a", + outVal: TestValue(VarBinary, "a"), + }, { + inType: Int64, + inVal: InvalidNeg, + outErr: "out of range", + }, { + inType: Int64, + inVal: InvalidPos, + outErr: "out of range", + }, { + inType: Uint64, + inVal: "-1", + outErr: "invalid syntax", + }, { + inType: Uint64, + inVal: InvalidPos, + outErr: "out of range", + }, { + inType: Float64, + inVal: "a", + outErr: "invalid syntax", + }, { + inType: Expression, + inVal: "a", + outErr: "invalid type specified for MakeValue: EXPRESSION", + }} + for _, tcase := range testcases { + v, err := NewValue(tcase.inType, []byte(tcase.inVal)) + if tcase.outErr != "" { + if err == nil || !strings.Contains(err.Error(), tcase.outErr) { + t.Errorf("ValueFromBytes(%v, %v) error: %v, must contain %v", tcase.inType, tcase.inVal, err, tcase.outErr) + } + continue + } + if err != nil { + t.Errorf("ValueFromBytes(%v, %v) error: %v", tcase.inType, tcase.inVal, err) + continue + } + if !reflect.DeepEqual(v, tcase.outVal) { + t.Errorf("ValueFromBytes(%v, %v) = %v, want %v", tcase.inType, tcase.inVal, v, tcase.outVal) + } + } +} + +// TestNew tests 'New' functions that are not tested +// through other code paths. +func TestNew(t *testing.T) { + got := NewInt32(1) + want := MakeTrusted(Int32, []byte("1")) + if !reflect.DeepEqual(got, want) { + t.Errorf("NewInt32(aa): %v, want %v", got, want) + } + + got = NewVarBinary("aa") + want = MakeTrusted(VarBinary, []byte("aa")) + if !reflect.DeepEqual(got, want) { + t.Errorf("NewVarBinary(aa): %v, want %v", got, want) + } +} + +func TestMakeTrusted(t *testing.T) { + v := MakeTrusted(Null, []byte("abcd")) + if !reflect.DeepEqual(v, NULL) { + t.Errorf("MakeTrusted(Null...) = %v, want null", v) + } + v = MakeTrusted(Int64, []byte("1")) + want := TestValue(Int64, "1") + if !reflect.DeepEqual(v, want) { + t.Errorf("MakeTrusted(Int64, \"1\") = %v, want %v", v, want) + } +} + +func TestIntegralValue(t *testing.T) { + testcases := []struct { + in string + outVal Value + outErr string + }{{ + in: MinNeg, + outVal: TestValue(Int64, MinNeg), + }, { + in: "1", + outVal: TestValue(Int64, "1"), + }, { + in: MinPos, + outVal: TestValue(Uint64, MinPos), + }, { + in: InvalidPos, + outErr: "out of range", + }} + for _, tcase := range testcases { + v, err := NewIntegral(tcase.in) + if tcase.outErr != "" { + if err == nil || !strings.Contains(err.Error(), tcase.outErr) { + t.Errorf("BuildIntegral(%v) error: %v, must contain %v", tcase.in, err, tcase.outErr) + } + continue + } + if err != nil { + t.Errorf("BuildIntegral(%v) error: %v", tcase.in, err) + continue + } + if !reflect.DeepEqual(v, tcase.outVal) { + t.Errorf("BuildIntegral(%v) = %v, want %v", tcase.in, v, tcase.outVal) + } + } +} + +func TestInerfaceValue(t *testing.T) { + testcases := []struct { + in interface{} + out Value + }{{ + in: nil, + out: NULL, + }, { + in: []byte("a"), + out: TestValue(VarBinary, "a"), + }, { + in: int64(1), + out: TestValue(Int64, "1"), + }, { + in: uint64(1), + out: TestValue(Uint64, "1"), + }, { + in: float64(1.2), + out: TestValue(Float64, "1.2"), + }, { + in: "a", + out: TestValue(VarChar, "a"), + }} + for _, tcase := range testcases { + v, err := InterfaceToValue(tcase.in) + if err != nil { + t.Errorf("BuildValue(%#v) error: %v", tcase.in, err) + continue + } + if !reflect.DeepEqual(v, tcase.out) { + t.Errorf("BuildValue(%#v) = %v, want %v", tcase.in, v, tcase.out) + } + } + + _, err := InterfaceToValue(make(chan bool)) + want := "unexpected" + if err == nil || !strings.Contains(err.Error(), want) { + t.Errorf("BuildValue(chan): %v, want %v", err, want) + } +} + +func TestAccessors(t *testing.T) { + v := TestValue(Int64, "1") + if v.Type() != Int64 { + t.Errorf("v.Type=%v, want Int64", v.Type()) + } + if !bytes.Equal(v.Raw(), []byte("1")) { + t.Errorf("v.Raw=%s, want 1", v.Raw()) + } + if v.Len() != 1 { + t.Errorf("v.Len=%d, want 1", v.Len()) + } + if v.ToString() != "1" { + t.Errorf("v.String=%s, want 1", v.ToString()) + } + if v.IsNull() { + t.Error("v.IsNull: true, want false") + } + if !v.IsIntegral() { + t.Error("v.IsIntegral: false, want true") + } + if !v.IsSigned() { + t.Error("v.IsSigned: false, want true") + } + if v.IsUnsigned() { + t.Error("v.IsUnsigned: true, want false") + } + if v.IsFloat() { + t.Error("v.IsFloat: true, want false") + } + if v.IsQuoted() { + t.Error("v.IsQuoted: true, want false") + } + if v.IsText() { + t.Error("v.IsText: true, want false") + } + if v.IsBinary() { + t.Error("v.IsBinary: true, want false") + } +} + +func TestToBytesAndString(t *testing.T) { + for _, v := range []Value{ + NULL, + TestValue(Int64, "1"), + TestValue(Int64, "12"), + } { + if b := v.ToBytes(); bytes.Compare(b, v.Raw()) != 0 { + t.Errorf("%v.ToBytes: %s, want %s", v, b, v.Raw()) + } + if s := v.ToString(); s != string(v.Raw()) { + t.Errorf("%v.ToString: %s, want %s", v, s, v.Raw()) + } + } + + tv := TestValue(Expression, "aa") + if b := tv.ToBytes(); b != nil { + t.Errorf("%v.ToBytes: %s, want nil", tv, b) + } + if s := tv.ToString(); s != "" { + t.Errorf("%v.ToString: %s, want \"\"", tv, s) + } +} + +func TestEncode(t *testing.T) { + testcases := []struct { + in Value + outSQL string + outASCII string + }{{ + in: NULL, + outSQL: "null", + outASCII: "null", + }, { + in: TestValue(Int64, "1"), + outSQL: "1", + outASCII: "1", + }, { + in: TestValue(VarChar, "foo"), + outSQL: "'foo'", + outASCII: "'Zm9v'", + }, { + in: TestValue(VarChar, "\x00'\"\b\n\r\t\x1A\\"), + outSQL: "'\\0\\'\\\"\\b\\n\\r\\t\\Z\\\\'", + outASCII: "'ACciCAoNCRpc'", + }} + for _, tcase := range testcases { + buf := &bytes.Buffer{} + tcase.in.EncodeSQL(buf) + if tcase.outSQL != buf.String() { + t.Errorf("%v.EncodeSQL = %q, want %q", tcase.in, buf.String(), tcase.outSQL) + } + buf = &bytes.Buffer{} + tcase.in.EncodeASCII(buf) + if tcase.outASCII != buf.String() { + t.Errorf("%v.EncodeASCII = %q, want %q", tcase.in, buf.String(), tcase.outASCII) + } + } +} + +// TestEncodeMap ensures DontEscape is not escaped +func TestEncodeMap(t *testing.T) { + if SQLEncodeMap[DontEscape] != DontEscape { + t.Errorf("SQLEncodeMap[DontEscape] = %v, want %v", SQLEncodeMap[DontEscape], DontEscape) + } + if SQLDecodeMap[DontEscape] != DontEscape { + t.Errorf("SQLDecodeMap[DontEscape] = %v, want %v", SQLEncodeMap[DontEscape], DontEscape) + } +} diff --git a/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/encodable.go b/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/encodable.go new file mode 100644 index 00000000..badfa42d --- /dev/null +++ b/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/encodable.go @@ -0,0 +1,99 @@ +/* +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 sqlparser + +import ( + "bytes" + + "github.com/xwb1989/sqlparser/dependency/sqltypes" +) + +// This file contains types that are 'Encodable'. + +// Encodable defines the interface for types that can +// be custom-encoded into SQL. +type Encodable interface { + EncodeSQL(buf *bytes.Buffer) +} + +// InsertValues is a custom SQL encoder for the values of +// an insert statement. +type InsertValues [][]sqltypes.Value + +// EncodeSQL performs the SQL encoding for InsertValues. +func (iv InsertValues) EncodeSQL(buf *bytes.Buffer) { + for i, rows := range iv { + if i != 0 { + buf.WriteString(", ") + } + buf.WriteByte('(') + for j, bv := range rows { + if j != 0 { + buf.WriteString(", ") + } + bv.EncodeSQL(buf) + } + buf.WriteByte(')') + } +} + +// TupleEqualityList is for generating equality constraints +// for tables that have composite primary keys. +type TupleEqualityList struct { + Columns []ColIdent + Rows [][]sqltypes.Value +} + +// EncodeSQL generates the where clause constraints for the tuple +// equality. +func (tpl *TupleEqualityList) EncodeSQL(buf *bytes.Buffer) { + if len(tpl.Columns) == 1 { + tpl.encodeAsIn(buf) + return + } + tpl.encodeAsEquality(buf) +} + +func (tpl *TupleEqualityList) encodeAsIn(buf *bytes.Buffer) { + Append(buf, tpl.Columns[0]) + buf.WriteString(" in (") + for i, r := range tpl.Rows { + if i != 0 { + buf.WriteString(", ") + } + r[0].EncodeSQL(buf) + } + buf.WriteByte(')') +} + +func (tpl *TupleEqualityList) encodeAsEquality(buf *bytes.Buffer) { + for i, r := range tpl.Rows { + if i != 0 { + buf.WriteString(" or ") + } + buf.WriteString("(") + for j, c := range tpl.Columns { + if j != 0 { + buf.WriteString(" and ") + } + Append(buf, c) + buf.WriteString(" = ") + r[j].EncodeSQL(buf) + } + buf.WriteByte(')') + } +} diff --git a/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/encodable_test.go b/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/encodable_test.go new file mode 100644 index 00000000..3bfc7748 --- /dev/null +++ b/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/encodable_test.go @@ -0,0 +1,73 @@ +/* +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 sqlparser + +import ( + "bytes" + "testing" + + "github.com/xwb1989/sqlparser/dependency/sqltypes" +) + +func TestEncodable(t *testing.T) { + tcases := []struct { + in Encodable + out string + }{{ + in: InsertValues{{ + sqltypes.NewInt64(1), + sqltypes.NewVarBinary("foo('a')"), + }, { + sqltypes.NewInt64(2), + sqltypes.NewVarBinary("bar(`b`)"), + }}, + out: "(1, 'foo(\\'a\\')'), (2, 'bar(`b`)')", + }, { + // Single column. + in: &TupleEqualityList{ + Columns: []ColIdent{NewColIdent("pk")}, + Rows: [][]sqltypes.Value{ + {sqltypes.NewInt64(1)}, + {sqltypes.NewVarBinary("aa")}, + }, + }, + out: "pk in (1, 'aa')", + }, { + // Multiple columns. + in: &TupleEqualityList{ + Columns: []ColIdent{NewColIdent("pk1"), NewColIdent("pk2")}, + Rows: [][]sqltypes.Value{ + { + sqltypes.NewInt64(1), + sqltypes.NewVarBinary("aa"), + }, + { + sqltypes.NewInt64(2), + sqltypes.NewVarBinary("bb"), + }, + }, + }, + out: "(pk1 = 1 and pk2 = 'aa') or (pk1 = 2 and pk2 = 'bb')", + }} + for _, tcase := range tcases { + buf := new(bytes.Buffer) + tcase.in.EncodeSQL(buf) + if out := buf.String(); out != tcase.out { + t.Errorf("EncodeSQL(%v): %s, want %s", tcase.in, out, tcase.out) + } + } +} diff --git a/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/github_test.go b/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/github_test.go new file mode 100644 index 00000000..01ab03ef --- /dev/null +++ b/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/github_test.go @@ -0,0 +1,82 @@ +/* +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 agreedto in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +package sqlparser + +// Additional tests to address the GitHub issues for this fork. + +import ( + "io" + "strings" + "testing" +) + +func TestParsing(t *testing.T) { + tests := []struct { + id int // Github issue ID + sql string + skip string + }{ + {id: 9, sql: "select 1 as 测试 from dual", skip: "Broken due to ReadByte()"}, + {id: 12, sql: "SELECT * FROM AccessToken LIMIT 10 OFFSET 13"}, + {id: 14, sql: "SELECT DATE_SUB(NOW(), INTERVAL 1 MONTH)"}, + {id: 15, sql: "select STRAIGHT_JOIN t1.* FROM t1 INNER JOIN t2 ON t1.CommonID = t2.CommonID WHERE t1.FilterID = 1"}, + {id: 16, sql: "SELECT a FROM t WHERE FUNC(a) = 1"}, // Doesn't seem broken, need better example + {id: 21, sql: `CREATE TABLE t (UpdateDatetime TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP)`}, + {id: 21, sql: `CREATE TABLE t (UpdateDatetime TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间')`}, + {id: 24, sql: `select * from t1 join t2 using(id)`}, + } + + for _, test := range tests { + if test.skip != "" { + continue + } + + if _, err := Parse(test.sql); err != nil { + t.Errorf("https://github.com/xwb1989/sqlparser/issues/%d:\nParse(%q) err = %s, want nil", test.id, test.sql, err) + } + } +} + +// ExampleParse is the first example from the README.md. +func ExampleParse() { + sql := "SELECT * FROM table WHERE a = 'abc'" + stmt, err := Parse(sql) + if err != nil { + // Do something with the err + } + + // Otherwise do something with stmt + switch stmt := stmt.(type) { + case *Select: + _ = stmt + case *Insert: + } +} + +// ExampleParseNext is the second example from the README.md. +func ExampleParseNext() { + r := strings.NewReader("INSERT INTO table1 VALUES (1, 'a'); INSERT INTO table2 VALUES (3, 4);") + + tokens := NewTokenizer(r) + for { + stmt, err := ParseNext(tokens) + if err == io.EOF { + break + } + // Do something with stmt or err. + _ = stmt + } +} diff --git a/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/impossible_query.go b/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/impossible_query.go new file mode 100644 index 00000000..1179b611 --- /dev/null +++ b/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/impossible_query.go @@ -0,0 +1,39 @@ +/* +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 agreedto in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package sqlparser + +// FormatImpossibleQuery creates an impossible query in a TrackedBuffer. +// An impossible query is a modified version of a query where all selects have where clauses that are +// impossible for mysql to resolve. This is used in the vtgate and vttablet: +// +// - In the vtgate it's used for joins: if the first query returns no result, then vtgate uses the impossible +// query just to fetch field info from vttablet +// - In the vttablet, it's just an optimization: the field info is fetched once form MySQL, cached and reused +// for subsequent queries +func FormatImpossibleQuery(buf *TrackedBuffer, node SQLNode) { + switch node := node.(type) { + case *Select: + buf.Myprintf("select %v from %v where 1 != 1", node.SelectExprs, node.From) + if node.GroupBy != nil { + node.GroupBy.Format(buf) + } + case *Union: + buf.Myprintf("%v %s %v", node.Left, node.Type, node.Right) + default: + node.Format(buf) + } +} diff --git a/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/normalizer.go b/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/normalizer.go new file mode 100644 index 00000000..f6520316 --- /dev/null +++ b/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/normalizer.go @@ -0,0 +1,224 @@ +/* +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 sqlparser + +import ( + "fmt" + + "github.com/xwb1989/sqlparser/dependency/sqltypes" + + "github.com/xwb1989/sqlparser/dependency/querypb" +) + +// Normalize changes the statement to use bind values, and +// updates the bind vars to those values. The supplied prefix +// is used to generate the bind var names. The function ensures +// that there are no collisions with existing bind vars. +// Within Select constructs, bind vars are deduped. This allows +// us to identify vindex equality. Otherwise, every value is +// treated as distinct. +func Normalize(stmt Statement, bindVars map[string]*querypb.BindVariable, prefix string) { + nz := newNormalizer(stmt, bindVars, prefix) + _ = Walk(nz.WalkStatement, stmt) +} + +type normalizer struct { + stmt Statement + bindVars map[string]*querypb.BindVariable + prefix string + reserved map[string]struct{} + counter int + vals map[string]string +} + +func newNormalizer(stmt Statement, bindVars map[string]*querypb.BindVariable, prefix string) *normalizer { + return &normalizer{ + stmt: stmt, + bindVars: bindVars, + prefix: prefix, + reserved: GetBindvars(stmt), + counter: 1, + vals: make(map[string]string), + } +} + +// WalkStatement is the top level walk function. +// If it encounters a Select, it switches to a mode +// where variables are deduped. +func (nz *normalizer) WalkStatement(node SQLNode) (bool, error) { + switch node := node.(type) { + case *Select: + _ = Walk(nz.WalkSelect, node) + // Don't continue + return false, nil + case *SQLVal: + nz.convertSQLVal(node) + case *ComparisonExpr: + nz.convertComparison(node) + } + return true, nil +} + +// WalkSelect normalizes the AST in Select mode. +func (nz *normalizer) WalkSelect(node SQLNode) (bool, error) { + switch node := node.(type) { + case *SQLVal: + nz.convertSQLValDedup(node) + case *ComparisonExpr: + nz.convertComparison(node) + } + return true, nil +} + +func (nz *normalizer) convertSQLValDedup(node *SQLVal) { + // If value is too long, don't dedup. + // Such values are most likely not for vindexes. + // We save a lot of CPU because we avoid building + // the key for them. + if len(node.Val) > 256 { + nz.convertSQLVal(node) + return + } + + // Make the bindvar + bval := nz.sqlToBindvar(node) + if bval == nil { + return + } + + // Check if there's a bindvar for that value already. + var key string + if bval.Type == sqltypes.VarBinary { + // Prefixing strings with "'" ensures that a string + // and number that have the same representation don't + // collide. + key = "'" + string(node.Val) + } else { + key = string(node.Val) + } + bvname, ok := nz.vals[key] + if !ok { + // If there's no such bindvar, make a new one. + bvname = nz.newName() + nz.vals[key] = bvname + nz.bindVars[bvname] = bval + } + + // Modify the AST node to a bindvar. + node.Type = ValArg + node.Val = append([]byte(":"), bvname...) +} + +// convertSQLVal converts an SQLVal without the dedup. +func (nz *normalizer) convertSQLVal(node *SQLVal) { + bval := nz.sqlToBindvar(node) + if bval == nil { + return + } + + bvname := nz.newName() + nz.bindVars[bvname] = bval + + node.Type = ValArg + node.Val = append([]byte(":"), bvname...) +} + +// convertComparison attempts to convert IN clauses to +// use the list bind var construct. If it fails, it returns +// with no change made. The walk function will then continue +// and iterate on converting each individual value into separate +// bind vars. +func (nz *normalizer) convertComparison(node *ComparisonExpr) { + if node.Operator != InStr && node.Operator != NotInStr { + return + } + tupleVals, ok := node.Right.(ValTuple) + if !ok { + return + } + // The RHS is a tuple of values. + // Make a list bindvar. + bvals := &querypb.BindVariable{ + Type: querypb.Type_TUPLE, + } + for _, val := range tupleVals { + bval := nz.sqlToBindvar(val) + if bval == nil { + return + } + bvals.Values = append(bvals.Values, &querypb.Value{ + Type: bval.Type, + Value: bval.Value, + }) + } + bvname := nz.newName() + nz.bindVars[bvname] = bvals + // Modify RHS to be a list bindvar. + node.Right = ListArg(append([]byte("::"), bvname...)) +} + +func (nz *normalizer) sqlToBindvar(node SQLNode) *querypb.BindVariable { + if node, ok := node.(*SQLVal); ok { + var v sqltypes.Value + var err error + switch node.Type { + case StrVal: + v, err = sqltypes.NewValue(sqltypes.VarBinary, node.Val) + case IntVal: + v, err = sqltypes.NewValue(sqltypes.Int64, node.Val) + case FloatVal: + v, err = sqltypes.NewValue(sqltypes.Float64, node.Val) + default: + return nil + } + if err != nil { + return nil + } + return sqltypes.ValueBindVariable(v) + } + return nil +} + +func (nz *normalizer) newName() string { + for { + newName := fmt.Sprintf("%s%d", nz.prefix, nz.counter) + if _, ok := nz.reserved[newName]; !ok { + nz.reserved[newName] = struct{}{} + return newName + } + nz.counter++ + } +} + +// GetBindvars returns a map of the bind vars referenced in the statement. +// TODO(sougou); This function gets called again from vtgate/planbuilder. +// Ideally, this should be done only once. +func GetBindvars(stmt Statement) map[string]struct{} { + bindvars := make(map[string]struct{}) + _ = Walk(func(node SQLNode) (kontinue bool, err error) { + switch node := node.(type) { + case *SQLVal: + if node.Type == ValArg { + bindvars[string(node.Val[1:])] = struct{}{} + } + case ListArg: + bindvars[string(node[2:])] = struct{}{} + } + return true, nil + }, stmt) + return bindvars +} diff --git a/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/normalizer_test.go b/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/normalizer_test.go new file mode 100644 index 00000000..20f7e39d --- /dev/null +++ b/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/normalizer_test.go @@ -0,0 +1,206 @@ +/* +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 sqlparser + +import ( + "fmt" + "reflect" + "testing" + + "github.com/xwb1989/sqlparser/dependency/querypb" + "github.com/xwb1989/sqlparser/dependency/sqltypes" +) + +func TestNormalize(t *testing.T) { + prefix := "bv" + testcases := []struct { + in string + outstmt string + outbv map[string]*querypb.BindVariable + }{{ + // str val + in: "select * from t where v1 = 'aa'", + outstmt: "select * from t where v1 = :bv1", + outbv: map[string]*querypb.BindVariable{ + "bv1": sqltypes.BytesBindVariable([]byte("aa")), + }, + }, { + // int val + in: "select * from t where v1 = 1", + outstmt: "select * from t where v1 = :bv1", + outbv: map[string]*querypb.BindVariable{ + "bv1": sqltypes.Int64BindVariable(1), + }, + }, { + // float val + in: "select * from t where v1 = 1.2", + outstmt: "select * from t where v1 = :bv1", + outbv: map[string]*querypb.BindVariable{ + "bv1": sqltypes.Float64BindVariable(1.2), + }, + }, { + // multiple vals + in: "select * from t where v1 = 1.2 and v2 = 2", + outstmt: "select * from t where v1 = :bv1 and v2 = :bv2", + outbv: map[string]*querypb.BindVariable{ + "bv1": sqltypes.Float64BindVariable(1.2), + "bv2": sqltypes.Int64BindVariable(2), + }, + }, { + // bv collision + in: "select * from t where v1 = :bv1 and v2 = 1", + outstmt: "select * from t where v1 = :bv1 and v2 = :bv2", + outbv: map[string]*querypb.BindVariable{ + "bv2": sqltypes.Int64BindVariable(1), + }, + }, { + // val reuse + in: "select * from t where v1 = 1 and v2 = 1", + outstmt: "select * from t where v1 = :bv1 and v2 = :bv1", + outbv: map[string]*querypb.BindVariable{ + "bv1": sqltypes.Int64BindVariable(1), + }, + }, { + // ints and strings are different + in: "select * from t where v1 = 1 and v2 = '1'", + outstmt: "select * from t where v1 = :bv1 and v2 = :bv2", + outbv: map[string]*querypb.BindVariable{ + "bv1": sqltypes.Int64BindVariable(1), + "bv2": sqltypes.BytesBindVariable([]byte("1")), + }, + }, { + // val should not be reused for non-select statements + in: "insert into a values(1, 1)", + outstmt: "insert into a values (:bv1, :bv2)", + outbv: map[string]*querypb.BindVariable{ + "bv1": sqltypes.Int64BindVariable(1), + "bv2": sqltypes.Int64BindVariable(1), + }, + }, { + // val should be reused only in subqueries of DMLs + in: "update a set v1=(select 5 from t), v2=5, v3=(select 5 from t), v4=5", + outstmt: "update a set v1 = (select :bv1 from t), v2 = :bv2, v3 = (select :bv1 from t), v4 = :bv3", + outbv: map[string]*querypb.BindVariable{ + "bv1": sqltypes.Int64BindVariable(5), + "bv2": sqltypes.Int64BindVariable(5), + "bv3": sqltypes.Int64BindVariable(5), + }, + }, { + // list vars should work for DMLs also + in: "update a set v1=5 where v2 in (1, 4, 5)", + outstmt: "update a set v1 = :bv1 where v2 in ::bv2", + outbv: map[string]*querypb.BindVariable{ + "bv1": sqltypes.Int64BindVariable(5), + "bv2": sqltypes.TestBindVariable([]interface{}{1, 4, 5}), + }, + }, { + // Hex value does not convert + in: "select * from t where v1 = 0x1234", + outstmt: "select * from t where v1 = 0x1234", + outbv: map[string]*querypb.BindVariable{}, + }, { + // Hex value does not convert for DMLs + in: "update a set v1 = 0x1234", + outstmt: "update a set v1 = 0x1234", + outbv: map[string]*querypb.BindVariable{}, + }, { + // Values up to len 256 will reuse. + in: fmt.Sprintf("select * from t where v1 = '%256s' and v2 = '%256s'", "a", "a"), + outstmt: "select * from t where v1 = :bv1 and v2 = :bv1", + outbv: map[string]*querypb.BindVariable{ + "bv1": sqltypes.BytesBindVariable([]byte(fmt.Sprintf("%256s", "a"))), + }, + }, { + // Values greater than len 256 will not reuse. + in: fmt.Sprintf("select * from t where v1 = '%257s' and v2 = '%257s'", "b", "b"), + outstmt: "select * from t where v1 = :bv1 and v2 = :bv2", + outbv: map[string]*querypb.BindVariable{ + "bv1": sqltypes.BytesBindVariable([]byte(fmt.Sprintf("%257s", "b"))), + "bv2": sqltypes.BytesBindVariable([]byte(fmt.Sprintf("%257s", "b"))), + }, + }, { + // bad int + in: "select * from t where v1 = 12345678901234567890", + outstmt: "select * from t where v1 = 12345678901234567890", + outbv: map[string]*querypb.BindVariable{}, + }, { + // comparison with no vals + in: "select * from t where v1 = v2", + outstmt: "select * from t where v1 = v2", + outbv: map[string]*querypb.BindVariable{}, + }, { + // IN clause with existing bv + in: "select * from t where v1 in ::list", + outstmt: "select * from t where v1 in ::list", + outbv: map[string]*querypb.BindVariable{}, + }, { + // IN clause with non-val values + in: "select * from t where v1 in (1, a)", + outstmt: "select * from t where v1 in (:bv1, a)", + outbv: map[string]*querypb.BindVariable{ + "bv1": sqltypes.Int64BindVariable(1), + }, + }, { + // IN clause with vals + in: "select * from t where v1 in (1, '2')", + outstmt: "select * from t where v1 in ::bv1", + outbv: map[string]*querypb.BindVariable{ + "bv1": sqltypes.TestBindVariable([]interface{}{1, []byte("2")}), + }, + }, { + // NOT IN clause + in: "select * from t where v1 not in (1, '2')", + outstmt: "select * from t where v1 not in ::bv1", + outbv: map[string]*querypb.BindVariable{ + "bv1": sqltypes.TestBindVariable([]interface{}{1, []byte("2")}), + }, + }} + for _, tc := range testcases { + stmt, err := Parse(tc.in) + if err != nil { + t.Error(err) + continue + } + bv := make(map[string]*querypb.BindVariable) + Normalize(stmt, bv, prefix) + outstmt := String(stmt) + if outstmt != tc.outstmt { + t.Errorf("Query:\n%s:\n%s, want\n%s", tc.in, outstmt, tc.outstmt) + } + if !reflect.DeepEqual(tc.outbv, bv) { + t.Errorf("Query:\n%s:\n%v, want\n%v", tc.in, bv, tc.outbv) + } + } +} + +func TestGetBindVars(t *testing.T) { + stmt, err := Parse("select * from t where :v1 = :v2 and :v2 = :v3 and :v4 in ::v5") + if err != nil { + t.Fatal(err) + } + got := GetBindvars(stmt) + want := map[string]struct{}{ + "v1": {}, + "v2": {}, + "v3": {}, + "v4": {}, + "v5": {}, + } + if !reflect.DeepEqual(got, want) { + t.Errorf("GetBindVars: %v, want: %v", got, want) + } +} diff --git a/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/parse_next_test.go b/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/parse_next_test.go new file mode 100644 index 00000000..bb92f9f2 --- /dev/null +++ b/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/parse_next_test.go @@ -0,0 +1,163 @@ +/* +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 sqlparser + +import ( + "bytes" + "io" + "strings" + "testing" +) + +// TestParseNextValid concatenates all the valid SQL test cases and check it can read +// them as one long string. +func TestParseNextValid(t *testing.T) { + var sql bytes.Buffer + for _, tcase := range validSQL { + sql.WriteString(strings.TrimSuffix(tcase.input, ";")) + sql.WriteRune(';') + } + + tokens := NewTokenizer(&sql) + for i, tcase := range validSQL { + input := tcase.input + ";" + want := tcase.output + if want == "" { + want = tcase.input + } + + tree, err := ParseNext(tokens) + if err != nil { + t.Fatalf("[%d] ParseNext(%q) err: %q, want nil", i, input, err) + continue + } + + if got := String(tree); got != want { + t.Fatalf("[%d] ParseNext(%q) = %q, want %q", i, input, got, want) + } + } + + // Read once more and it should be EOF. + if tree, err := ParseNext(tokens); err != io.EOF { + t.Errorf("ParseNext(tokens) = (%q, %v) want io.EOF", String(tree), err) + } +} + +// TestParseNextErrors tests all the error cases, and ensures a valid +// SQL statement can be passed afterwards. +func TestParseNextErrors(t *testing.T) { + for _, tcase := range invalidSQL { + if tcase.excludeMulti { + // Skip tests which leave unclosed strings, or comments. + continue + } + + sql := tcase.input + "; select 1 from t" + tokens := NewStringTokenizer(sql) + + // The first statement should be an error + _, err := ParseNext(tokens) + if err == nil || err.Error() != tcase.output { + t.Fatalf("[0] ParseNext(%q) err: %q, want %q", sql, err, tcase.output) + continue + } + + // The second should be valid + tree, err := ParseNext(tokens) + if err != nil { + t.Fatalf("[1] ParseNext(%q) err: %q, want nil", sql, err) + continue + } + + want := "select 1 from t" + if got := String(tree); got != want { + t.Fatalf("[1] ParseNext(%q) = %q, want %q", sql, got, want) + } + + // Read once more and it should be EOF. + if tree, err := ParseNext(tokens); err != io.EOF { + t.Errorf("ParseNext(tokens) = (%q, %v) want io.EOF", String(tree), err) + } + } +} + +// TestParseNextEdgeCases tests various ParseNext edge cases. +func TestParseNextEdgeCases(t *testing.T) { + tests := []struct { + name string + input string + want []string + }{{ + name: "Trailing ;", + input: "select 1 from a; update a set b = 2;", + want: []string{"select 1 from a", "update a set b = 2"}, + }, { + name: "No trailing ;", + input: "select 1 from a; update a set b = 2", + want: []string{"select 1 from a", "update a set b = 2"}, + }, { + name: "Trailing whitespace", + input: "select 1 from a; update a set b = 2 ", + want: []string{"select 1 from a", "update a set b = 2"}, + }, { + name: "Trailing whitespace and ;", + input: "select 1 from a; update a set b = 2 ; ", + want: []string{"select 1 from a", "update a set b = 2"}, + }, { + name: "Handle ForceEOF statements", + input: "set character set utf8; select 1 from a", + want: []string{"set charset 'utf8'", "select 1 from a"}, + }, { + name: "Semicolin inside a string", + input: "set character set ';'; select 1 from a", + want: []string{"set charset ';'", "select 1 from a"}, + }, { + name: "Partial DDL", + input: "create table a; select 1 from a", + want: []string{"create table a", "select 1 from a"}, + }, { + name: "Partial DDL", + input: "create table a ignore me this is garbage; select 1 from a", + want: []string{"create table a", "select 1 from a"}, + }} + + for _, test := range tests { + tokens := NewStringTokenizer(test.input) + + for i, want := range test.want { + tree, err := ParseNext(tokens) + if err != nil { + t.Fatalf("[%d] ParseNext(%q) err = %q, want nil", i, test.input, err) + continue + } + + if got := String(tree); got != want { + t.Fatalf("[%d] ParseNext(%q) = %q, want %q", i, test.input, got, want) + } + } + + // Read once more and it should be EOF. + if tree, err := ParseNext(tokens); err != io.EOF { + t.Errorf("ParseNext(%q) = (%q, %v) want io.EOF", test.input, String(tree), err) + } + + // And again, once more should be EOF. + if tree, err := ParseNext(tokens); err != io.EOF { + t.Errorf("ParseNext(%q) = (%q, %v) want io.EOF", test.input, String(tree), err) + } + } +} diff --git a/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/parse_test.go b/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/parse_test.go new file mode 100644 index 00000000..ac659621 --- /dev/null +++ b/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/parse_test.go @@ -0,0 +1,2126 @@ +/* +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 sqlparser + +import ( + "bytes" + "fmt" + "strings" + "testing" +) + +var ( + validSQL = []struct { + input string + output string + }{{ + input: "select 1", + output: "select 1 from dual", + }, { + input: "select 1 from t", + }, { + input: "select .1 from t", + }, { + input: "select 1.2e1 from t", + }, { + input: "select 1.2e+1 from t", + }, { + input: "select 1.2e-1 from t", + }, { + input: "select 08.3 from t", + }, { + input: "select -1 from t where b = -2", + }, { + input: "select - -1 from t", + output: "select 1 from t", + }, { + input: "select 1 from t // aa\n", + output: "select 1 from t", + }, { + input: "select 1 from t -- aa\n", + output: "select 1 from t", + }, { + input: "select 1 from t # aa\n", + output: "select 1 from t", + }, { + input: "select 1 --aa\nfrom t", + output: "select 1 from t", + }, { + input: "select 1 #aa\nfrom t", + output: "select 1 from t", + }, { + input: "select /* simplest */ 1 from t", + }, { + input: "select /* double star **/ 1 from t", + }, { + input: "select /* double */ /* comment */ 1 from t", + }, { + input: "select /* back-quote keyword */ `By` from t", + }, { + input: "select /* back-quote num */ `2a` from t", + }, { + input: "select /* back-quote . */ `a.b` from t", + }, { + input: "select /* back-quote back-quote */ `a``b` from t", + }, { + input: "select /* back-quote unnecessary */ 1 from `t`", + output: "select /* back-quote unnecessary */ 1 from t", + }, { + input: "select /* back-quote idnum */ 1 from `a1`", + output: "select /* back-quote idnum */ 1 from a1", + }, { + input: "select /* @ */ @@a from b", + }, { + input: "select /* \\0 */ '\\0' from a", + }, { + input: "select 1 /* drop this comment */ from t", + output: "select 1 from t", + }, { + input: "select /* union */ 1 from t union select 1 from t", + }, { + input: "select /* double union */ 1 from t union select 1 from t union select 1 from t", + }, { + input: "select /* union all */ 1 from t union all select 1 from t", + }, { + input: "select /* union distinct */ 1 from t union distinct select 1 from t", + }, { + input: "(select /* union parenthesized select */ 1 from t order by a) union select 1 from t", + output: "(select /* union parenthesized select */ 1 from t order by a asc) union select 1 from t", + }, { + input: "select /* union parenthesized select 2 */ 1 from t union (select 1 from t)", + }, { + input: "select /* union order by */ 1 from t union select 1 from t order by a", + output: "select /* union order by */ 1 from t union select 1 from t order by a asc", + }, { + input: "select /* union order by limit lock */ 1 from t union select 1 from t order by a limit 1 for update", + output: "select /* union order by limit lock */ 1 from t union select 1 from t order by a asc limit 1 for update", + }, { + input: "select /* union with limit on lhs */ 1 from t limit 1 union select 1 from t", + }, { + input: "(select id, a from t order by id limit 1) union (select id, b as a from s order by id limit 1) order by a limit 1", + output: "(select id, a from t order by id asc limit 1) union (select id, b as a from s order by id asc limit 1) order by a asc limit 1", + }, { + input: "select a from (select 1 as a from tbl1 union select 2 from tbl2) as t", + }, { + input: "select * from t1 join (select * from t2 union select * from t3) as t", + }, { + // Ensure this doesn't generate: ""select * from t1 join t2 on a = b join t3 on a = b". + input: "select * from t1 join t2 on a = b join t3", + }, { + input: "select * from t1 where col in (select 1 from dual union select 2 from dual)", + }, { + input: "select * from t1 where exists (select a from t2 union select b from t3)", + }, { + input: "select /* distinct */ distinct 1 from t", + }, { + input: "select /* straight_join */ straight_join 1 from t", + }, { + input: "select /* for update */ 1 from t for update", + }, { + input: "select /* lock in share mode */ 1 from t lock in share mode", + }, { + input: "select /* select list */ 1, 2 from t", + }, { + input: "select /* * */ * from t", + }, { + input: "select /* a.* */ a.* from t", + }, { + input: "select /* a.b.* */ a.b.* from t", + }, { + input: "select /* column alias */ a b from t", + output: "select /* column alias */ a as b from t", + }, { + input: "select /* column alias with as */ a as b from t", + }, { + input: "select /* keyword column alias */ a as `By` from t", + }, { + input: "select /* column alias as string */ a as \"b\" from t", + output: "select /* column alias as string */ a as b from t", + }, { + input: "select /* column alias as string without as */ a \"b\" from t", + output: "select /* column alias as string without as */ a as b from t", + }, { + input: "select /* a.* */ a.* from t", + }, { + input: "select next value for t", + output: "select next 1 values from t", + }, { + input: "select next value from t", + output: "select next 1 values from t", + }, { + input: "select next 10 values from t", + }, { + input: "select next :a values from t", + }, { + input: "select /* `By`.* */ `By`.* from t", + }, { + input: "select /* select with bool expr */ a = b from t", + }, { + input: "select /* case_when */ case when a = b then c end from t", + }, { + input: "select /* case_when_else */ case when a = b then c else d end from t", + }, { + input: "select /* case_when_when_else */ case when a = b then c when b = d then d else d end from t", + }, { + input: "select /* case */ case aa when a = b then c end from t", + }, { + input: "select /* parenthesis */ 1 from (t)", + }, { + input: "select /* parenthesis multi-table */ 1 from (t1, t2)", + }, { + input: "select /* table list */ 1 from t1, t2", + }, { + input: "select /* parenthessis in table list 1 */ 1 from (t1), t2", + }, { + input: "select /* parenthessis in table list 2 */ 1 from t1, (t2)", + }, { + input: "select /* use */ 1 from t1 use index (a) where b = 1", + }, { + input: "select /* keyword index */ 1 from t1 use index (`By`) where b = 1", + }, { + input: "select /* ignore */ 1 from t1 as t2 ignore index (a), t3 use index (b) where b = 1", + }, { + input: "select /* use */ 1 from t1 as t2 use index (a), t3 use index (b) where b = 1", + }, { + input: "select /* force */ 1 from t1 as t2 force index (a), t3 force index (b) where b = 1", + }, { + input: "select /* table alias */ 1 from t t1", + output: "select /* table alias */ 1 from t as t1", + }, { + input: "select /* table alias with as */ 1 from t as t1", + }, { + input: "select /* string table alias */ 1 from t as 't1'", + output: "select /* string table alias */ 1 from t as t1", + }, { + input: "select /* string table alias without as */ 1 from t 't1'", + output: "select /* string table alias without as */ 1 from t as t1", + }, { + input: "select /* keyword table alias */ 1 from t as `By`", + }, { + input: "select /* join */ 1 from t1 join t2", + }, { + input: "select /* join on */ 1 from t1 join t2 on a = b", + }, { + input: "select /* join on */ 1 from t1 join t2 using (a)", + }, { + input: "select /* inner join */ 1 from t1 inner join t2", + output: "select /* inner join */ 1 from t1 join t2", + }, { + input: "select /* cross join */ 1 from t1 cross join t2", + output: "select /* cross join */ 1 from t1 join t2", + }, { + input: "select /* straight_join */ 1 from t1 straight_join t2", + }, { + input: "select /* straight_join on */ 1 from t1 straight_join t2 on a = b", + }, { + input: "select /* left join */ 1 from t1 left join t2 on a = b", + }, { + input: "select /* left join */ 1 from t1 left join t2 using (a)", + }, { + input: "select /* left outer join */ 1 from t1 left outer join t2 on a = b", + output: "select /* left outer join */ 1 from t1 left join t2 on a = b", + }, { + input: "select /* left outer join */ 1 from t1 left outer join t2 using (a)", + output: "select /* left outer join */ 1 from t1 left join t2 using (a)", + }, { + input: "select /* right join */ 1 from t1 right join t2 on a = b", + }, { + input: "select /* right join */ 1 from t1 right join t2 using (a)", + }, { + input: "select /* right outer join */ 1 from t1 right outer join t2 on a = b", + output: "select /* right outer join */ 1 from t1 right join t2 on a = b", + }, { + input: "select /* right outer join */ 1 from t1 right outer join t2 using (a)", + output: "select /* right outer join */ 1 from t1 right join t2 using (a)", + }, { + input: "select /* natural join */ 1 from t1 natural join t2", + }, { + input: "select /* natural left join */ 1 from t1 natural left join t2", + }, { + input: "select /* natural left outer join */ 1 from t1 natural left join t2", + output: "select /* natural left outer join */ 1 from t1 natural left join t2", + }, { + input: "select /* natural right join */ 1 from t1 natural right join t2", + }, { + input: "select /* natural right outer join */ 1 from t1 natural right join t2", + output: "select /* natural right outer join */ 1 from t1 natural right join t2", + }, { + input: "select /* join on */ 1 from t1 join t2 on a = b", + }, { + input: "select /* join using */ 1 from t1 join t2 using (a)", + }, { + input: "select /* join using (a, b, c) */ 1 from t1 join t2 using (a, b, c)", + }, { + input: "select /* s.t */ 1 from s.t", + }, { + input: "select /* keyword schema & table name */ 1 from `By`.`bY`", + }, { + input: "select /* select in from */ 1 from (select 1 from t) as a", + }, { + input: "select /* select in from with no as */ 1 from (select 1 from t) a", + output: "select /* select in from with no as */ 1 from (select 1 from t) as a", + }, { + input: "select /* where */ 1 from t where a = b", + }, { + input: "select /* and */ 1 from t where a = b and a = c", + }, { + input: "select /* && */ 1 from t where a = b && a = c", + output: "select /* && */ 1 from t where a = b and a = c", + }, { + input: "select /* or */ 1 from t where a = b or a = c", + }, { + input: "select /* || */ 1 from t where a = b || a = c", + output: "select /* || */ 1 from t where a = b or a = c", + }, { + input: "select /* not */ 1 from t where not a = b", + }, { + input: "select /* ! */ 1 from t where a = !1", + }, { + input: "select /* bool is */ 1 from t where a = b is null", + }, { + input: "select /* bool is not */ 1 from t where a = b is not false", + }, { + input: "select /* true */ 1 from t where true", + }, { + input: "select /* false */ 1 from t where false", + }, { + input: "select /* false on left */ 1 from t where false = 0", + }, { + input: "select /* exists */ 1 from t where exists (select 1 from t)", + }, { + input: "select /* (boolean) */ 1 from t where not (a = b)", + }, { + input: "select /* in value list */ 1 from t where a in (b, c)", + }, { + input: "select /* in select */ 1 from t where a in (select 1 from t)", + }, { + input: "select /* not in */ 1 from t where a not in (b, c)", + }, { + input: "select /* like */ 1 from t where a like b", + }, { + input: "select /* like escape */ 1 from t where a like b escape '!'", + }, { + input: "select /* not like */ 1 from t where a not like b", + }, { + input: "select /* not like escape */ 1 from t where a not like b escape '$'", + }, { + input: "select /* regexp */ 1 from t where a regexp b", + }, { + input: "select /* not regexp */ 1 from t where a not regexp b", + }, { + input: "select /* rlike */ 1 from t where a rlike b", + output: "select /* rlike */ 1 from t where a regexp b", + }, { + input: "select /* not rlike */ 1 from t where a not rlike b", + output: "select /* not rlike */ 1 from t where a not regexp b", + }, { + input: "select /* between */ 1 from t where a between b and c", + }, { + input: "select /* not between */ 1 from t where a not between b and c", + }, { + input: "select /* is null */ 1 from t where a is null", + }, { + input: "select /* is not null */ 1 from t where a is not null", + }, { + input: "select /* is true */ 1 from t where a is true", + }, { + input: "select /* is not true */ 1 from t where a is not true", + }, { + input: "select /* is false */ 1 from t where a is false", + }, { + input: "select /* is not false */ 1 from t where a is not false", + }, { + input: "select /* < */ 1 from t where a < b", + }, { + input: "select /* <= */ 1 from t where a <= b", + }, { + input: "select /* >= */ 1 from t where a >= b", + }, { + input: "select /* > */ 1 from t where a > b", + }, { + input: "select /* != */ 1 from t where a != b", + }, { + input: "select /* <> */ 1 from t where a <> b", + output: "select /* <> */ 1 from t where a != b", + }, { + input: "select /* <=> */ 1 from t where a <=> b", + }, { + input: "select /* != */ 1 from t where a != b", + }, { + input: "select /* single value expre list */ 1 from t where a in (b)", + }, { + input: "select /* select as a value expression */ 1 from t where a = (select a from t)", + }, { + input: "select /* parenthesised value */ 1 from t where a = (b)", + }, { + input: "select /* over-parenthesize */ ((1)) from t where ((a)) in (((1))) and ((a, b)) in ((((1, 1))), ((2, 2)))", + }, { + input: "select /* dot-parenthesize */ (a.b) from t where (b.c) = 2", + }, { + input: "select /* & */ 1 from t where a = b & c", + }, { + input: "select /* & */ 1 from t where a = b & c", + }, { + input: "select /* | */ 1 from t where a = b | c", + }, { + input: "select /* ^ */ 1 from t where a = b ^ c", + }, { + input: "select /* + */ 1 from t where a = b + c", + }, { + input: "select /* - */ 1 from t where a = b - c", + }, { + input: "select /* * */ 1 from t where a = b * c", + }, { + input: "select /* / */ 1 from t where a = b / c", + }, { + input: "select /* % */ 1 from t where a = b % c", + }, { + input: "select /* div */ 1 from t where a = b div c", + }, { + input: "select /* MOD */ 1 from t where a = b MOD c", + output: "select /* MOD */ 1 from t where a = b % c", + }, { + input: "select /* << */ 1 from t where a = b << c", + }, { + input: "select /* >> */ 1 from t where a = b >> c", + }, { + input: "select /* % no space */ 1 from t where a = b%c", + output: "select /* % no space */ 1 from t where a = b % c", + }, { + input: "select /* u+ */ 1 from t where a = +b", + }, { + input: "select /* u- */ 1 from t where a = -b", + }, { + input: "select /* u~ */ 1 from t where a = ~b", + }, { + input: "select /* -> */ a.b -> 'ab' from t", + }, { + input: "select /* -> */ a.b ->> 'ab' from t", + }, { + input: "select /* empty function */ 1 from t where a = b()", + }, { + input: "select /* function with 1 param */ 1 from t where a = b(c)", + }, { + input: "select /* function with many params */ 1 from t where a = b(c, d)", + }, { + input: "select /* function with distinct */ count(distinct a) from t", + }, { + input: "select /* if as func */ 1 from t where a = if(b)", + }, { + input: "select /* current_timestamp as func */ current_timestamp() from t", + }, { + input: "select /* mod as func */ a from tab where mod(b, 2) = 0", + }, { + input: "select /* database as func no param */ database() from t", + }, { + input: "select /* database as func 1 param */ database(1) from t", + }, { + input: "select /* a */ a from t", + }, { + input: "select /* a.b */ a.b from t", + }, { + input: "select /* a.b.c */ a.b.c from t", + }, { + input: "select /* keyword a.b */ `By`.`bY` from t", + }, { + input: "select /* string */ 'a' from t", + }, { + input: "select /* double quoted string */ \"a\" from t", + output: "select /* double quoted string */ 'a' from t", + }, { + input: "select /* quote quote in string */ 'a''a' from t", + output: "select /* quote quote in string */ 'a\\'a' from t", + }, { + input: "select /* double quote quote in string */ \"a\"\"a\" from t", + output: "select /* double quote quote in string */ 'a\\\"a' from t", + }, { + input: "select /* quote in double quoted string */ \"a'a\" from t", + output: "select /* quote in double quoted string */ 'a\\'a' from t", + }, { + input: "select /* backslash quote in string */ 'a\\'a' from t", + }, { + input: "select /* literal backslash in string */ 'a\\\\na' from t", + }, { + input: "select /* all escapes */ '\\0\\'\\\"\\b\\n\\r\\t\\Z\\\\' from t", + }, { + input: "select /* non-escape */ '\\x' from t", + output: "select /* non-escape */ 'x' from t", + }, { + input: "select /* unescaped backslash */ '\\n' from t", + }, { + input: "select /* value argument */ :a from t", + }, { + input: "select /* value argument with digit */ :a1 from t", + }, { + input: "select /* value argument with dot */ :a.b from t", + }, { + input: "select /* positional argument */ ? from t", + output: "select /* positional argument */ :v1 from t", + }, { + input: "select /* multiple positional arguments */ ?, ? from t", + output: "select /* multiple positional arguments */ :v1, :v2 from t", + }, { + input: "select /* list arg */ * from t where a in ::list", + }, { + input: "select /* list arg not in */ * from t where a not in ::list", + }, { + input: "select /* null */ null from t", + }, { + input: "select /* octal */ 010 from t", + }, { + input: "select /* hex */ x'f0A1' from t", + output: "select /* hex */ X'f0A1' from t", + }, { + input: "select /* hex caps */ X'F0a1' from t", + }, { + input: "select /* bit literal */ b'0101' from t", + output: "select /* bit literal */ B'0101' from t", + }, { + input: "select /* bit literal caps */ B'010011011010' from t", + }, { + input: "select /* 0x */ 0xf0 from t", + }, { + input: "select /* float */ 0.1 from t", + }, { + input: "select /* group by */ 1 from t group by a", + }, { + input: "select /* having */ 1 from t having a = b", + }, { + input: "select /* simple order by */ 1 from t order by a", + output: "select /* simple order by */ 1 from t order by a asc", + }, { + input: "select /* order by asc */ 1 from t order by a asc", + }, { + input: "select /* order by desc */ 1 from t order by a desc", + }, { + input: "select /* order by null */ 1 from t order by null", + }, { + input: "select /* limit a */ 1 from t limit a", + }, { + input: "select /* limit a,b */ 1 from t limit a, b", + }, { + input: "select /* binary unary */ a- -b from t", + output: "select /* binary unary */ a - -b from t", + }, { + input: "select /* - - */ - -b from t", + }, { + input: "select /* binary binary */ binary binary b from t", + }, { + input: "select /* binary ~ */ binary ~b from t", + }, { + input: "select /* ~ binary */ ~ binary b from t", + }, { + input: "select /* interval */ adddate('2008-01-02', interval 31 day) from t", + }, { + input: "select /* interval keyword */ adddate('2008-01-02', interval 1 year) from t", + }, { + input: "select /* dual */ 1 from dual", + }, { + input: "select /* Dual */ 1 from Dual", + output: "select /* Dual */ 1 from dual", + }, { + input: "select /* DUAL */ 1 from Dual", + output: "select /* DUAL */ 1 from dual", + }, { + input: "select /* column as bool in where */ a from t where b", + }, { + input: "select /* OR of columns in where */ * from t where a or b", + }, { + input: "select /* OR of mixed columns in where */ * from t where a = 5 or b and c is not null", + }, { + input: "select /* OR in select columns */ (a or b) from t where c = 5", + }, { + input: "select /* bool as select value */ a, true from t", + }, { + input: "select /* bool column in ON clause */ * from t join s on t.id = s.id and s.foo where t.bar", + }, { + input: "select /* bool in order by */ * from t order by a is null or b asc", + }, { + input: "select /* string in case statement */ if(max(case a when 'foo' then 1 else 0 end) = 1, 'foo', 'bar') as foobar from t", + }, { + input: "/*!show databases*/", + output: "show databases", + }, { + input: "select /*!40101 * from*/ t", + output: "select * from t", + }, { + input: "select /*! * from*/ t", + output: "select * from t", + }, { + input: "select /*!* from*/ t", + output: "select * from t", + }, { + input: "select /*!401011 from*/ t", + output: "select 1 from t", + }, { + input: "select /* dual */ 1 from dual", + }, { + input: "insert /* simple */ into a values (1)", + }, { + input: "insert /* a.b */ into a.b values (1)", + }, { + input: "insert /* multi-value */ into a values (1, 2)", + }, { + input: "insert /* multi-value list */ into a values (1, 2), (3, 4)", + }, { + input: "insert /* no values */ into a values ()", + }, { + input: "insert /* set */ into a set a = 1, b = 2", + output: "insert /* set */ into a(a, b) values (1, 2)", + }, { + input: "insert /* set default */ into a set a = default, b = 2", + output: "insert /* set default */ into a(a, b) values (default, 2)", + }, { + input: "insert /* value expression list */ into a values (a + 1, 2 * 3)", + }, { + input: "insert /* default */ into a values (default, 2 * 3)", + }, { + input: "insert /* column list */ into a(a, b) values (1, 2)", + }, { + input: "insert into a(a, b) values (1, ifnull(null, default(b)))", + }, { + input: "insert /* qualified column list */ into a(a, b) values (1, 2)", + }, { + input: "insert /* qualified columns */ into t (t.a, t.b) values (1, 2)", + output: "insert /* qualified columns */ into t(a, b) values (1, 2)", + }, { + input: "insert /* select */ into a select b, c from d", + }, { + input: "insert /* no cols & paren select */ into a(select * from t)", + output: "insert /* no cols & paren select */ into a select * from t", + }, { + input: "insert /* cols & paren select */ into a(a,b,c) (select * from t)", + output: "insert /* cols & paren select */ into a(a, b, c) select * from t", + }, { + input: "insert /* cols & union with paren select */ into a(b, c) (select d, e from f) union (select g from h)", + }, { + input: "insert /* on duplicate */ into a values (1, 2) on duplicate key update b = func(a), c = d", + }, { + input: "insert /* bool in insert value */ into a values (1, true, false)", + }, { + input: "insert /* bool in on duplicate */ into a values (1, 2) on duplicate key update b = false, c = d", + }, { + input: "insert /* bool in on duplicate */ into a values (1, 2, 3) on duplicate key update b = values(b), c = d", + }, { + input: "insert /* bool in on duplicate */ into a values (1, 2, 3) on duplicate key update b = values(a.b), c = d", + }, { + input: "insert /* bool expression on duplicate */ into a values (1, 2) on duplicate key update b = func(a), c = a > d", + }, { + input: "update /* simple */ a set b = 3", + }, { + input: "update /* a.b */ a.b set b = 3", + }, { + input: "update /* list */ a set b = 3, c = 4", + }, { + input: "update /* expression */ a set b = 3 + 4", + }, { + input: "update /* where */ a set b = 3 where a = b", + }, { + input: "update /* order */ a set b = 3 order by c desc", + }, { + input: "update /* limit */ a set b = 3 limit c", + }, { + input: "update /* bool in update */ a set b = true", + }, { + input: "update /* bool expr in update */ a set b = 5 > 2", + }, { + input: "update /* bool in update where */ a set b = 5 where c", + }, { + input: "update /* table qualifier */ a set a.b = 3", + }, { + input: "update /* table qualifier */ a set t.a.b = 3", + }, { + input: "update /* table alias */ tt aa set aa.cc = 3", + output: "update /* table alias */ tt as aa set aa.cc = 3", + }, { + input: "update (select id from foo) subqalias set id = 4", + output: "update (select id from foo) as subqalias set id = 4", + }, { + input: "update foo f, bar b set f.id = b.id where b.name = 'test'", + output: "update foo as f, bar as b set f.id = b.id where b.name = 'test'", + }, { + input: "update foo f join bar b on f.name = b.name set f.id = b.id where b.name = 'test'", + output: "update foo as f join bar as b on f.name = b.name set f.id = b.id where b.name = 'test'", + }, { + input: "delete /* simple */ from a", + }, { + input: "delete /* a.b */ from a.b", + }, { + input: "delete /* where */ from a where a = b", + }, { + input: "delete /* order */ from a order by b desc", + }, { + input: "delete /* limit */ from a limit b", + }, { + input: "delete a from a join b on a.id = b.id where b.name = 'test'", + }, { + input: "delete a, b from a, b where a.id = b.id and b.name = 'test'", + }, { + input: "delete from a1, a2 using t1 as a1 inner join t2 as a2 where a1.id=a2.id", + output: "delete a1, a2 from t1 as a1 join t2 as a2 where a1.id = a2.id", + }, { + input: "set /* simple */ a = 3", + }, { + input: "set #simple\n b = 4", + }, { + input: "set character_set_results = utf8", + }, { + input: "set @@session.autocommit = true", + }, { + input: "set @@session.`autocommit` = true", + }, { + input: "set @@session.'autocommit' = true", + }, { + input: "set @@session.\"autocommit\" = true", + }, { + input: "set names utf8 collate foo", + output: "set names 'utf8'", + }, { + input: "set character set utf8", + output: "set charset 'utf8'", + }, { + input: "set character set 'utf8'", + output: "set charset 'utf8'", + }, { + input: "set character set \"utf8\"", + output: "set charset 'utf8'", + }, { + input: "set charset default", + output: "set charset default", + }, { + input: "set session wait_timeout = 3600", + output: "set session wait_timeout = 3600", + }, { + input: "set /* list */ a = 3, b = 4", + }, { + input: "set /* mixed list */ a = 3, names 'utf8', charset 'ascii', b = 4", + }, { + input: "set session transaction isolation level repeatable read", + output: "set session tx_isolation = 'repeatable read'", + }, { + input: "set global transaction isolation level repeatable read", + output: "set global tx_isolation = 'repeatable read'", + }, { + input: "set transaction isolation level repeatable read", + output: "set tx_isolation = 'repeatable read'", + }, { + input: "set transaction isolation level read committed", + output: "set tx_isolation = 'read committed'", + }, { + input: "set transaction isolation level read uncommitted", + output: "set tx_isolation = 'read uncommitted'", + }, { + input: "set transaction isolation level serializable", + output: "set tx_isolation = 'serializable'", + }, { + input: "set transaction read write", + output: "set tx_read_only = 0", + }, { + input: "set transaction read only", + output: "set tx_read_only = 1", + }, { + input: "set tx_read_only = 1", + }, { + input: "set tx_read_only = 0", + }, { + input: "set tx_isolation = 'repeatable read'", + }, { + input: "set tx_isolation = 'read committed'", + }, { + input: "set tx_isolation = 'read uncommitted'", + }, { + input: "set tx_isolation = 'serializable'", + }, { + input: "set sql_safe_updates = 0", + }, { + input: "set sql_safe_updates = 1", + }, { + input: "alter ignore table a add foo", + output: "alter table a", + }, { + input: "alter table a add foo", + output: "alter table a", + }, { + input: "alter table a add spatial key foo (column1)", + output: "alter table a", + }, { + input: "alter table a add unique key foo (column1)", + output: "alter table a", + }, { + input: "alter table `By` add foo", + output: "alter table `By`", + }, { + input: "alter table a alter foo", + output: "alter table a", + }, { + input: "alter table a change foo", + output: "alter table a", + }, { + input: "alter table a modify foo", + output: "alter table a", + }, { + input: "alter table a drop foo", + output: "alter table a", + }, { + input: "alter table a disable foo", + output: "alter table a", + }, { + input: "alter table a enable foo", + output: "alter table a", + }, { + input: "alter table a order foo", + output: "alter table a", + }, { + input: "alter table a default foo", + output: "alter table a", + }, { + input: "alter table a discard foo", + output: "alter table a", + }, { + input: "alter table a import foo", + output: "alter table a", + }, { + input: "alter table a rename b", + output: "rename table a to b", + }, { + input: "alter table `By` rename `bY`", + output: "rename table `By` to `bY`", + }, { + input: "alter table a rename to b", + output: "rename table a to b", + }, { + input: "alter table a rename as b", + output: "rename table a to b", + }, { + input: "alter table a rename index foo to bar", + output: "alter table a", + }, { + input: "alter table a rename key foo to bar", + output: "alter table a", + }, { + input: "alter table e auto_increment = 20", + output: "alter table e", + }, { + input: "alter table e character set = 'ascii'", + output: "alter table e", + }, { + input: "alter table e default character set = 'ascii'", + output: "alter table e", + }, { + input: "alter table e comment = 'hello'", + output: "alter table e", + }, { + input: "alter table a reorganize partition b into (partition c values less than (?), partition d values less than (maxvalue))", + output: "alter table a reorganize partition b into (partition c values less than (:v1), partition d values less than (maxvalue))", + }, { + input: "alter table a partition by range (id) (partition p0 values less than (10), partition p1 values less than (maxvalue))", + output: "alter table a", + }, { + input: "alter table a add column id int", + output: "alter table a", + }, { + input: "alter table a add index idx (id)", + output: "alter table a", + }, { + input: "alter table a add fulltext index idx (id)", + output: "alter table a", + }, { + input: "alter table a add spatial index idx (id)", + output: "alter table a", + }, { + input: "alter table a add foreign key", + output: "alter table a", + }, { + input: "alter table a add primary key", + output: "alter table a", + }, { + input: "alter table a add constraint", + output: "alter table a", + }, { + input: "alter table a add id", + output: "alter table a", + }, { + input: "alter table a drop column id int", + output: "alter table a", + }, { + input: "alter table a drop partition p2712", + output: "alter table a", + }, { + input: "alter table a drop index idx (id)", + output: "alter table a", + }, { + input: "alter table a drop fulltext index idx (id)", + output: "alter table a", + }, { + input: "alter table a drop spatial index idx (id)", + output: "alter table a", + }, { + input: "alter table a drop foreign key", + output: "alter table a", + }, { + input: "alter table a drop primary key", + output: "alter table a", + }, { + input: "alter table a drop constraint", + output: "alter table a", + }, { + input: "alter table a drop id", + output: "alter table a", + }, { + input: "alter table a add vindex hash (id)", + }, { + input: "alter table a add vindex `hash` (`id`)", + output: "alter table a add vindex hash (id)", + }, { + input: "alter table a add vindex hash (id) using `hash`", + output: "alter table a add vindex hash (id) using hash", + }, { + input: "alter table a add vindex `add` (`add`)", + }, { + input: "alter table a add vindex hash (id) using hash", + }, { + input: "alter table a add vindex hash (id) using `hash`", + output: "alter table a add vindex hash (id) using hash", + }, { + input: "alter table user add vindex name_lookup_vdx (name) using lookup_hash with owner=user, table=name_user_idx, from=name, to=user_id", + }, { + input: "alter table 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`", + output: "alter table 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 table a drop vindex hash", + }, { + input: "alter table a drop vindex `hash`", + output: "alter table a drop vindex hash", + }, { + input: "alter table a drop vindex hash", + output: "alter table a drop vindex hash", + }, { + input: "alter table a drop vindex `add`", + output: "alter table a drop vindex `add`", + }, { + input: "create table a", + }, { + input: "create table a (\n\t`a` int\n)", + output: "create table a (\n\ta int\n)", + }, { + input: "create table `by` (\n\t`by` char\n)", + }, { + input: "create table if not exists a (\n\t`a` int\n)", + output: "create table a (\n\ta int\n)", + }, { + input: "create table a ignore me this is garbage", + output: "create table a", + }, { + input: "create table a (a int, b char, c garbage)", + output: "create table a", + }, { + input: "create vindex hash_vdx using hash", + }, { + input: "create vindex lookup_vdx using lookup with owner=user, table=name_user_idx, from=name, to=user_id", + }, { + input: "create vindex xyz_vdx using xyz with param1=hello, param2='world', param3=123", + }, { + input: "create index a on b", + output: "alter table b", + }, { + input: "create unique index a on b", + output: "alter table b", + }, { + input: "create unique index a using foo on b", + output: "alter table b", + }, { + input: "create fulltext index a using foo on b", + output: "alter table b", + }, { + input: "create spatial index a using foo on b", + output: "alter table b", + }, { + input: "create view a", + output: "create table a", + }, { + input: "create or replace view a", + output: "create table a", + }, { + input: "alter view a", + output: "alter table a", + }, { + input: "drop view a", + output: "drop table a", + }, { + input: "drop table a", + output: "drop table a", + }, { + input: "drop table if exists a", + output: "drop table if exists a", + }, { + input: "drop view if exists a", + output: "drop table if exists a", + }, { + input: "drop index b on a", + output: "alter table a", + }, { + input: "analyze table a", + output: "alter table a", + }, { + input: "show binary logs", + output: "show binary logs", + }, { + input: "show binlog events", + output: "show binlog", + }, { + input: "show character set", + output: "show character set", + }, { + input: "show character set like '%foo'", + output: "show character set", + }, { + input: "show collation", + output: "show collation", + }, { + input: "show create database d", + output: "show create database", + }, { + input: "show create event e", + output: "show create event", + }, { + input: "show create function f", + output: "show create function", + }, { + input: "show create procedure p", + output: "show create procedure", + }, { + input: "show create table t", + output: "show create table", + }, { + input: "show create trigger t", + output: "show create trigger", + }, { + input: "show create user u", + output: "show create user", + }, { + input: "show create view v", + output: "show create view", + }, { + input: "show databases", + output: "show databases", + }, { + input: "show engine INNODB", + output: "show engine", + }, { + input: "show engines", + output: "show engines", + }, { + input: "show storage engines", + output: "show storage", + }, { + input: "show errors", + output: "show errors", + }, { + input: "show events", + output: "show events", + }, { + input: "show function code func", + output: "show function", + }, { + input: "show function status", + output: "show function", + }, { + input: "show grants for 'root@localhost'", + output: "show grants", + }, { + input: "show index from table", + output: "show index", + }, { + input: "show indexes from table", + output: "show indexes", + }, { + input: "show keys from table", + output: "show keys", + }, { + input: "show master status", + output: "show master", + }, { + input: "show open tables", + output: "show open", + }, { + input: "show plugins", + output: "show plugins", + }, { + input: "show privileges", + output: "show privileges", + }, { + input: "show procedure code p", + output: "show procedure", + }, { + input: "show procedure status", + output: "show procedure", + }, { + input: "show processlist", + output: "show processlist", + }, { + input: "show full processlist", + output: "show processlist", + }, { + input: "show profile cpu for query 1", + output: "show profile", + }, { + input: "show profiles", + output: "show profiles", + }, { + input: "show relaylog events", + output: "show relaylog", + }, { + input: "show slave hosts", + output: "show slave", + }, { + input: "show slave status", + output: "show slave", + }, { + input: "show status", + output: "show status", + }, { + input: "show global status", + output: "show global status", + }, { + input: "show session status", + output: "show session status", + }, { + input: "show table status", + output: "show table", + }, { + input: "show tables", + }, { + input: "show tables like '%keyspace%'", + }, { + input: "show tables where 1 = 0", + }, { + input: "show tables from a", + }, { + input: "show tables from a where 1 = 0", + }, { + input: "show tables from a like '%keyspace%'", + }, { + input: "show full tables", + }, { + input: "show full tables from a", + }, { + input: "show full tables in a", + output: "show full tables from a", + }, { + input: "show full tables from a like '%keyspace%'", + }, { + input: "show full tables from a where 1 = 0", + }, { + input: "show full tables like '%keyspace%'", + }, { + input: "show full tables where 1 = 0", + }, { + input: "show triggers", + output: "show triggers", + }, { + input: "show variables", + output: "show variables", + }, { + input: "show global variables", + output: "show global variables", + }, { + input: "show session variables", + output: "show session variables", + }, { + input: "show vindexes", + output: "show vindexes", + }, { + input: "show vindexes on t", + output: "show vindexes on t", + }, { + input: "show vitess_keyspaces", + }, { + input: "show vitess_shards", + }, { + input: "show vitess_tablets", + }, { + input: "show vschema_tables", + }, { + input: "show warnings", + output: "show warnings", + }, { + input: "show foobar", + output: "show foobar", + }, { + input: "show foobar like select * from table where syntax is 'ignored'", + output: "show foobar", + }, { + input: "use db", + output: "use db", + }, { + input: "use duplicate", + output: "use `duplicate`", + }, { + input: "use `ks:-80@master`", + output: "use `ks:-80@master`", + }, { + input: "describe foobar", + output: "otherread", + }, { + input: "desc foobar", + output: "otherread", + }, { + input: "explain foobar", + output: "otherread", + }, { + input: "truncate table foo", + output: "truncate table foo", + }, { + input: "truncate foo", + output: "truncate table foo", + }, { + input: "repair foo", + output: "otheradmin", + }, { + input: "optimize foo", + output: "otheradmin", + }, { + input: "select /* EQ true */ 1 from t where a = true", + }, { + input: "select /* EQ false */ 1 from t where a = false", + }, { + input: "select /* NE true */ 1 from t where a != true", + }, { + input: "select /* NE false */ 1 from t where a != false", + }, { + input: "select /* LT true */ 1 from t where a < true", + }, { + input: "select /* LT false */ 1 from t where a < false", + }, { + input: "select /* GT true */ 1 from t where a > true", + }, { + input: "select /* GT false */ 1 from t where a > false", + }, { + input: "select /* LE true */ 1 from t where a <= true", + }, { + input: "select /* LE false */ 1 from t where a <= false", + }, { + input: "select /* GE true */ 1 from t where a >= true", + }, { + input: "select /* GE false */ 1 from t where a >= false", + }, { + input: "select * from t order by a collate utf8_general_ci", + output: "select * from t order by a collate utf8_general_ci asc", + }, { + input: "select k collate latin1_german2_ci as k1 from t1 order by k1 asc", + }, { + input: "select * from t group by a collate utf8_general_ci", + }, { + input: "select MAX(k collate latin1_german2_ci) from t1", + }, { + input: "select distinct k collate latin1_german2_ci from t1", + }, { + input: "select * from t1 where 'Müller' collate latin1_german2_ci = k", + }, { + input: "select * from t1 where k like 'Müller' collate latin1_german2_ci", + }, { + input: "select k from t1 group by k having k = 'Müller' collate latin1_german2_ci", + }, { + input: "select k from t1 join t2 order by a collate latin1_german2_ci asc, b collate latin1_german2_ci asc", + }, { + input: "select k collate 'latin1_german2_ci' as k1 from t1 order by k1 asc", + output: "select k collate latin1_german2_ci as k1 from t1 order by k1 asc", + }, { + input: "select /* drop trailing semicolon */ 1 from dual;", + output: "select /* drop trailing semicolon */ 1 from dual", + }, { + input: "select /* cache directive */ sql_no_cache 'foo' from t", + }, { + input: "select binary 'a' = 'A' from t", + }, { + input: "select 1 from t where foo = _binary 'bar'", + }, { + input: "select 1 from t where foo = _binary'bar'", + output: "select 1 from t where foo = _binary 'bar'", + }, { + input: "select match(a) against ('foo') from t", + }, { + input: "select match(a1, a2) against ('foo' in natural language mode with query expansion) from t", + }, { + input: "select title from video as v where match(v.title, v.tag) against ('DEMO' in boolean mode)", + }, { + input: "select name, group_concat(score) from t group by name", + }, { + input: "select name, group_concat(distinct id, score order by id desc separator ':') from t group by name", + }, { + input: "select * from t partition (p0)", + }, { + input: "select * from t partition (p0, p1)", + }, { + input: "select e.id, s.city from employees as e join stores partition (p1) as s on e.store_id = s.id", + }, { + input: "select truncate(120.3333, 2) from dual", + }, { + input: "update t partition (p0) set a = 1", + }, { + input: "insert into t partition (p0) values (1, 'asdf')", + }, { + input: "insert into t1 select * from t2 partition (p0)", + }, { + input: "replace into t partition (p0) values (1, 'asdf')", + }, { + input: "delete from t partition (p0) where a = 1", + }, { + input: "stream * from t", + }, { + input: "stream /* comment */ * from t", + }, { + input: "begin", + }, { + input: "start transaction", + output: "begin", + }, { + input: "commit", + }, { + input: "rollback", + }, { + input: "create database test_db", + }, { + input: "create schema test_db", + output: "create database test_db", + }, { + input: "create database if not exists test_db", + output: "create database test_db", + }, { + input: "drop database test_db", + }, { + input: "drop schema test_db", + output: "drop database test_db", + }, { + input: "drop database if exists test_db", + output: "drop database test_db", + }} +) + +func TestValid(t *testing.T) { + for _, tcase := range validSQL { + if tcase.output == "" { + tcase.output = tcase.input + } + tree, err := Parse(tcase.input) + if err != nil { + t.Errorf("Parse(%q) err: %v, want nil", tcase.input, err) + continue + } + out := String(tree) + if out != tcase.output { + t.Errorf("Parse(%q) = %q, want: %q", tcase.input, out, tcase.output) + } + // This test just exercises the tree walking functionality. + // There's no way automated way to verify that a node calls + // all its children. But we can examine code coverage and + // ensure that all walkSubtree functions were called. + Walk(func(node SQLNode) (bool, error) { + return true, nil + }, tree) + } +} + +func TestCaseSensitivity(t *testing.T) { + validSQL := []struct { + input string + output string + }{{ + input: "create table A (\n\t`B` int\n)", + output: "create table A (\n\tB int\n)", + }, { + input: "create index b on A", + output: "alter table A", + }, { + input: "alter table A foo", + output: "alter table A", + }, { + input: "alter table A convert", + output: "alter table A", + }, { + // View names get lower-cased. + input: "alter view A foo", + output: "alter table a", + }, { + input: "alter table A rename to B", + output: "rename table A to B", + }, { + input: "rename table A to B", + }, { + input: "drop table B", + output: "drop table B", + }, { + input: "drop table if exists B", + output: "drop table if exists B", + }, { + input: "drop index b on A", + output: "alter table A", + }, { + input: "select a from B", + }, { + input: "select A as B from C", + }, { + input: "select B.* from c", + }, { + input: "select B.A from c", + }, { + input: "select * from B as C", + }, { + input: "select * from A.B", + }, { + input: "update A set b = 1", + }, { + input: "update A.B set b = 1", + }, { + input: "select A() from b", + }, { + input: "select A(B, C) from b", + }, { + input: "select A(distinct B, C) from b", + }, { + // IF is an exception. It's always lower-cased. + input: "select IF(B, C) from b", + output: "select if(B, C) from b", + }, { + input: "select * from b use index (A)", + }, { + input: "insert into A(A, B) values (1, 2)", + }, { + input: "CREATE TABLE A (\n\t`A` int\n)", + output: "create table A (\n\tA int\n)", + }, { + input: "create view A", + output: "create table a", + }, { + input: "alter view A", + output: "alter table a", + }, { + input: "drop view A", + output: "drop table a", + }, { + input: "drop view if exists A", + output: "drop table if exists a", + }, { + input: "select /* lock in SHARE MODE */ 1 from t lock in SHARE MODE", + output: "select /* lock in SHARE MODE */ 1 from t lock in share mode", + }, { + input: "select next VALUE from t", + output: "select next 1 values from t", + }, { + input: "select /* use */ 1 from t1 use index (A) where b = 1", + }} + for _, tcase := range validSQL { + if tcase.output == "" { + tcase.output = tcase.input + } + tree, err := Parse(tcase.input) + if err != nil { + t.Errorf("input: %s, err: %v", tcase.input, err) + continue + } + out := String(tree) + if out != tcase.output { + t.Errorf("out: %s, want %s", out, tcase.output) + } + } +} + +func TestKeywords(t *testing.T) { + validSQL := []struct { + input string + output string + }{{ + input: "select current_timestamp", + output: "select current_timestamp() from dual", + }, { + input: "update t set a = current_timestamp()", + }, { + input: "select a, current_date from t", + output: "select a, current_date() from t", + }, { + input: "insert into t(a, b) values (current_date, current_date())", + output: "insert into t(a, b) values (current_date(), current_date())", + }, { + input: "select * from t where a > utc_timestmp()", + }, { + input: "update t set b = utc_timestamp + 5", + output: "update t set b = utc_timestamp() + 5", + }, { + input: "select utc_time, utc_date", + output: "select utc_time(), utc_date() from dual", + }, { + input: "select 1 from dual where localtime > utc_time", + output: "select 1 from dual where localtime() > utc_time()", + }, { + input: "update t set a = localtimestamp(), b = utc_timestamp", + output: "update t set a = localtimestamp(), b = utc_timestamp()", + }, { + input: "insert into t(a) values (unix_timestamp)", + }, { + input: "select replace(a, 'foo', 'bar') from t", + }, { + input: "update t set a = replace('1234', '2', '1')", + }, { + input: "insert into t(a, b) values ('foo', 'bar') on duplicate key update a = replace(hex('foo'), 'f', 'b')", + }, { + input: "update t set a = left('1234', 3)", + }, { + input: "select left(a, 5) from t", + }, { + input: "update t set d = adddate(date('2003-12-31 01:02:03'), interval 5 days)", + }, { + input: "insert into t(a, b) values (left('foo', 1), 'b')", + }, { + input: "insert /* qualified function */ into t(a, b) values (test.PI(), 'b')", + }, { + input: "select /* keyword in qualified id */ * from t join z on t.key = z.key", + output: "select /* keyword in qualified id */ * from t join z on t.`key` = z.`key`", + }, { + input: "select /* non-reserved keywords as unqualified cols */ date, view, offset from t", + output: "select /* non-reserved keywords as unqualified cols */ `date`, `view`, `offset` from t", + }, { + input: "select /* share and mode as cols */ share, mode from t where share = 'foo'", + output: "select /* share and mode as cols */ `share`, `mode` from t where `share` = 'foo'", + }, { + input: "select /* unused keywords as cols */ write, varying from t where trailing = 'foo'", + output: "select /* unused keywords as cols */ `write`, `varying` from t where `trailing` = 'foo'", + }, { + input: "select status from t", + output: "select `status` from t", + }, { + input: "select variables from t", + output: "select `variables` from t", + }} + + for _, tcase := range validSQL { + if tcase.output == "" { + tcase.output = tcase.input + } + tree, err := Parse(tcase.input) + if err != nil { + t.Errorf("input: %s, err: %v", tcase.input, err) + continue + } + out := String(tree) + if out != tcase.output { + t.Errorf("out: %s, want %s", out, tcase.output) + } + } +} + +func TestConvert(t *testing.T) { + validSQL := []struct { + input string + output string + }{{ + input: "select cast('abc' as date) from t", + output: "select convert('abc', date) from t", + }, { + input: "select convert('abc', binary(4)) from t", + }, { + input: "select convert('abc', binary) from t", + }, { + input: "select convert('abc', char character set binary) from t", + }, { + input: "select convert('abc', char(4) ascii) from t", + }, { + input: "select convert('abc', char unicode) from t", + }, { + input: "select convert('abc', char(4)) from t", + }, { + input: "select convert('abc', char) from t", + }, { + input: "select convert('abc', nchar(4)) from t", + }, { + input: "select convert('abc', nchar) from t", + }, { + input: "select convert('abc', signed) from t", + }, { + input: "select convert('abc', signed integer) from t", + output: "select convert('abc', signed) from t", + }, { + input: "select convert('abc', unsigned) from t", + }, { + input: "select convert('abc', unsigned integer) from t", + output: "select convert('abc', unsigned) from t", + }, { + input: "select convert('abc', decimal(3, 4)) from t", + }, { + input: "select convert('abc', decimal(4)) from t", + }, { + input: "select convert('abc', decimal) from t", + }, { + input: "select convert('abc', date) from t", + }, { + input: "select convert('abc', time(4)) from t", + }, { + input: "select convert('abc', time) from t", + }, { + input: "select convert('abc', datetime(9)) from t", + }, { + input: "select convert('abc', datetime) from t", + }, { + input: "select convert('abc', json) from t", + }, { + input: "select convert('abc' using ascii) from t", + }} + + for _, tcase := range validSQL { + if tcase.output == "" { + tcase.output = tcase.input + } + tree, err := Parse(tcase.input) + if err != nil { + t.Errorf("input: %s, err: %v", tcase.input, err) + continue + } + out := String(tree) + if out != tcase.output { + t.Errorf("out: %s, want %s", out, tcase.output) + } + } + + invalidSQL := []struct { + input string + output string + }{{ + input: "select convert('abc' as date) from t", + output: "syntax error at position 24 near 'as'", + }, { + input: "select convert from t", + output: "syntax error at position 20 near 'from'", + }, { + input: "select cast('foo', decimal) from t", + output: "syntax error at position 19", + }, { + input: "select convert('abc', datetime(4+9)) from t", + output: "syntax error at position 34", + }, { + input: "select convert('abc', decimal(4+9)) from t", + output: "syntax error at position 33", + }} + + for _, tcase := range invalidSQL { + _, err := Parse(tcase.input) + if err == nil || err.Error() != tcase.output { + t.Errorf("%s: %v, want %s", tcase.input, err, tcase.output) + } + } +} + +func TestSubStr(t *testing.T) { + + validSQL := []struct { + input string + output string + }{{ + input: "select substr(a, 1) from t", + }, { + input: "select substr(a, 1, 6) from t", + }, { + input: "select substring(a, 1) from t", + output: "select substr(a, 1) from t", + }, { + input: "select substring(a, 1, 6) from t", + output: "select substr(a, 1, 6) from t", + }, { + input: "select substr(a from 1 for 6) from t", + output: "select substr(a, 1, 6) from t", + }, { + input: "select substring(a from 1 for 6) from t", + output: "select substr(a, 1, 6) from t", + }} + + for _, tcase := range validSQL { + if tcase.output == "" { + tcase.output = tcase.input + } + tree, err := Parse(tcase.input) + if err != nil { + t.Errorf("input: %s, err: %v", tcase.input, err) + continue + } + out := String(tree) + if out != tcase.output { + t.Errorf("out: %s, want %s", out, tcase.output) + } + } +} + +func TestCreateTable(t *testing.T) { + validSQL := []string{ + // test all the data types and options + "create table t (\n" + + " col_bit bit,\n" + + " col_tinyint tinyint auto_increment,\n" + + " col_tinyint3 tinyint(3) unsigned,\n" + + " col_smallint smallint,\n" + + " col_smallint4 smallint(4) zerofill,\n" + + " col_mediumint mediumint,\n" + + " col_mediumint5 mediumint(5) unsigned not null,\n" + + " col_int int,\n" + + " col_int10 int(10) not null,\n" + + " col_integer integer comment 'this is an integer',\n" + + " col_bigint bigint,\n" + + " col_bigint10 bigint(10) zerofill not null default 10,\n" + + " col_real real,\n" + + " col_real2 real(1,2) not null default 1.23,\n" + + " col_double double,\n" + + " col_double2 double(3,4) not null default 1.23,\n" + + " col_float float,\n" + + " col_float2 float(3,4) not null default 1.23,\n" + + " col_decimal decimal,\n" + + " col_decimal2 decimal(2),\n" + + " col_decimal3 decimal(2,3),\n" + + " col_numeric numeric,\n" + + " col_numeric2 numeric(2),\n" + + " col_numeric3 numeric(2,3),\n" + + " col_date date,\n" + + " col_time time,\n" + + " col_timestamp timestamp,\n" + + " col_datetime datetime,\n" + + " col_year year,\n" + + " col_char char,\n" + + " col_char2 char(2),\n" + + " col_char3 char(3) character set ascii,\n" + + " col_char4 char(4) character set ascii collate ascii_bin,\n" + + " col_varchar varchar,\n" + + " col_varchar2 varchar(2),\n" + + " col_varchar3 varchar(3) character set ascii,\n" + + " col_varchar4 varchar(4) character set ascii collate ascii_bin,\n" + + " col_binary binary,\n" + + " col_varbinary varbinary(10),\n" + + " col_tinyblob tinyblob,\n" + + " col_blob blob,\n" + + " col_mediumblob mediumblob,\n" + + " col_longblob longblob,\n" + + " col_tinytext tinytext,\n" + + " col_text text,\n" + + " col_mediumtext mediumtext,\n" + + " col_longtext longtext,\n" + + " col_text text character set ascii collate ascii_bin,\n" + + " col_json json,\n" + + " col_enum enum('a', 'b', 'c', 'd'),\n" + + " col_enum2 enum('a', 'b', 'c', 'd') character set ascii,\n" + + " col_enum3 enum('a', 'b', 'c', 'd') collate ascii_bin,\n" + + " col_enum4 enum('a', 'b', 'c', 'd') character set ascii collate ascii_bin,\n" + + " col_set set('a', 'b', 'c', 'd'),\n" + + " col_set2 set('a', 'b', 'c', 'd') character set ascii,\n" + + " col_set3 set('a', 'b', 'c', 'd') collate ascii_bin,\n" + + " col_set4 set('a', 'b', 'c', 'd') character set ascii collate ascii_bin,\n" + + " col_geometry1 geometry,\n" + + " col_geometry2 geometry not null,\n" + + " col_point1 point,\n" + + " col_point2 point not null,\n" + + " col_linestring1 linestring,\n" + + " col_linestring2 linestring not null,\n" + + " col_polygon1 polygon,\n" + + " col_polygon2 polygon not null,\n" + + " col_geometrycollection1 geometrycollection,\n" + + " col_geometrycollection2 geometrycollection not null,\n" + + " col_multipoint1 multipoint,\n" + + " col_multipoint2 multipoint not null,\n" + + " col_multilinestring1 multilinestring,\n" + + " col_multilinestring2 multilinestring not null,\n" + + " col_multipolygon1 multipolygon,\n" + + " col_multipolygon2 multipolygon not null\n" + + ")", + + // test defaults + "create table t (\n" + + " i1 int default 1,\n" + + " i2 int default null,\n" + + " f1 float default 1.23,\n" + + " s1 varchar default 'c',\n" + + " s2 varchar default 'this is a string',\n" + + " s3 varchar default null,\n" + + " s4 timestamp default current_timestamp,\n" + + " s5 bit(1) default B'0'\n" + + ")", + + // test key field options + "create table t (\n" + + " id int auto_increment primary key,\n" + + " username varchar unique key,\n" + + " email varchar unique,\n" + + " full_name varchar key,\n" + + " time1 timestamp on update current_timestamp,\n" + + " time2 timestamp default current_timestamp on update current_timestamp\n" + + ")", + + // test defining indexes separately + "create table t (\n" + + " id int auto_increment,\n" + + " username varchar,\n" + + " email varchar,\n" + + " full_name varchar,\n" + + " geom point not null,\n" + + " status_nonkeyword varchar,\n" + + " primary key (id),\n" + + " spatial key geom (geom),\n" + + " unique key by_username (username),\n" + + " unique by_username2 (username),\n" + + " unique index by_username3 (username),\n" + + " index by_status (status_nonkeyword),\n" + + " key by_full_name (full_name)\n" + + ")", + + // test that indexes support USING + "create table t (\n" + + " id int auto_increment,\n" + + " username varchar,\n" + + " email varchar,\n" + + " full_name varchar,\n" + + " status_nonkeyword varchar,\n" + + " primary key (id) using BTREE,\n" + + " unique key by_username (username) using HASH,\n" + + " unique by_username2 (username) using OTHER,\n" + + " unique index by_username3 (username) using XYZ,\n" + + " index by_status (status_nonkeyword) using PDQ,\n" + + " key by_full_name (full_name) using OTHER\n" + + ")", + // test other index options + "create table t (\n" + + " id int auto_increment,\n" + + " username varchar,\n" + + " email varchar,\n" + + " primary key (id) comment 'hi',\n" + + " unique key by_username (username) key_block_size 8,\n" + + " unique index by_username4 (username) comment 'hi' using BTREE,\n" + + " unique index by_username4 (username) using BTREE key_block_size 4 comment 'hi'\n" + + ")", + + // multi-column indexes + "create table t (\n" + + " id int auto_increment,\n" + + " username varchar,\n" + + " email varchar,\n" + + " full_name varchar,\n" + + " a int,\n" + + " b int,\n" + + " c int,\n" + + " primary key (id, username),\n" + + " unique key by_abc (a, b, c),\n" + + " key by_email (email(10), username)\n" + + ")", + + // table options + "create table t (\n" + + " id int auto_increment\n" + + ") engine InnoDB,\n" + + " auto_increment 123,\n" + + " avg_row_length 1,\n" + + " default character set utf8mb4,\n" + + " character set latin1,\n" + + " checksum 0,\n" + + " default collate binary,\n" + + " collate ascii_bin,\n" + + " comment 'this is a comment',\n" + + " compression 'zlib',\n" + + " connection 'connect_string',\n" + + " data directory 'absolute path to directory',\n" + + " delay_key_write 1,\n" + + " encryption 'n',\n" + + " index directory 'absolute path to directory',\n" + + " insert_method no,\n" + + " key_block_size 1024,\n" + + " max_rows 100,\n" + + " min_rows 10,\n" + + " pack_keys 0,\n" + + " password 'sekret',\n" + + " row_format default,\n" + + " stats_auto_recalc default,\n" + + " stats_persistent 0,\n" + + " stats_sample_pages 1,\n" + + " tablespace tablespace_name storage disk,\n" + + " tablespace tablespace_name\n", + } + for _, sql := range validSQL { + sql = strings.TrimSpace(sql) + tree, err := ParseStrictDDL(sql) + if err != nil { + t.Errorf("input: %s, err: %v", sql, err) + continue + } + got := String(tree.(*DDL)) + + if sql != got { + t.Errorf("want:\n%s\ngot:\n%s", sql, got) + } + } + + sql := "create table t garbage" + tree, err := Parse(sql) + if err != nil { + t.Errorf("input: %s, err: %v", sql, err) + } + + tree, err = ParseStrictDDL(sql) + if tree != nil || err == nil { + t.Errorf("ParseStrictDDL unexpectedly accepted input %s", sql) + } + + testCases := []struct { + input string + output string + }{{ + // test key_block_size + input: "create table t (\n" + + " id int auto_increment,\n" + + " username varchar,\n" + + " unique key by_username (username) key_block_size 8,\n" + + " unique key by_username2 (username) key_block_size=8,\n" + + " unique by_username3 (username) key_block_size = 4\n" + + ")", + output: "create table t (\n" + + " id int auto_increment,\n" + + " username varchar,\n" + + " unique key by_username (username) key_block_size 8,\n" + + " unique key by_username2 (username) key_block_size 8,\n" + + " unique by_username3 (username) key_block_size 4\n" + + ")", + }, + } + for _, tcase := range testCases { + tree, err := ParseStrictDDL(tcase.input) + if err != nil { + t.Errorf("input: %s, err: %v", tcase.input, err) + continue + } + if got, want := String(tree.(*DDL)), tcase.output; got != want { + t.Errorf("Parse(%s):\n%s, want\n%s", tcase.input, got, want) + } + } +} + +func TestCreateTableEscaped(t *testing.T) { + testCases := []struct { + input string + output string + }{{ + input: "create table `a`(`id` int, primary key(`id`))", + output: "create table a (\n" + + "\tid int,\n" + + "\tprimary key (id)\n" + + ")", + }, { + input: "create table `insert`(`update` int, primary key(`delete`))", + output: "create table `insert` (\n" + + "\t`update` int,\n" + + "\tprimary key (`delete`)\n" + + ")", + }} + for _, tcase := range testCases { + tree, err := ParseStrictDDL(tcase.input) + if err != nil { + t.Errorf("input: %s, err: %v", tcase.input, err) + continue + } + if got, want := String(tree.(*DDL)), tcase.output; got != want { + t.Errorf("Parse(%s):\n%s, want\n%s", tcase.input, got, want) + } + } +} + +var ( + invalidSQL = []struct { + input string + output string + excludeMulti bool // Don't use in the ParseNext multi-statement parsing tests. + }{{ + input: "select $ from t", + output: "syntax error at position 9 near '$'", + }, { + input: "select : from t", + output: "syntax error at position 9 near ':'", + }, { + input: "select 0xH from t", + output: "syntax error at position 10 near '0x'", + }, { + input: "select x'78 from t", + output: "syntax error at position 12 near '78'", + }, { + input: "select x'777' from t", + output: "syntax error at position 14 near '777'", + }, { + input: "select * from t where :1 = 2", + output: "syntax error at position 24 near ':'", + }, { + input: "select * from t where :. = 2", + output: "syntax error at position 24 near ':'", + }, { + input: "select * from t where ::1 = 2", + output: "syntax error at position 25 near '::'", + }, { + input: "select * from t where ::. = 2", + output: "syntax error at position 25 near '::'", + }, { + input: "update a set c = values(1)", + output: "syntax error at position 26 near '1'", + }, { + input: "select(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F" + + "(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(" + + "F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F" + + "(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(" + + "F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F" + + "(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(" + + "F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F" + + "(F(F(F(F(F(F(F(F(F(F(F(F(", + output: "max nesting level reached at position 406", + }, { + input: "select(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F" + + "(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(" + + "F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F" + + "(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(" + + "F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F" + + "(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(" + + "F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F" + + "(F(F(F(F(F(F(F(F(F(F(F(", + output: "syntax error at position 404", + }, { + // This construct is considered invalid due to a grammar conflict. + input: "insert into a select * from b join c on duplicate key update d=e", + output: "syntax error at position 54 near 'key'", + }, { + input: "select * from a left join b", + output: "syntax error at position 28", + }, { + input: "select * from a natural join b on c = d", + output: "syntax error at position 34 near 'on'", + }, { + input: "select * from a natural join b using (c)", + output: "syntax error at position 37 near 'using'", + }, { + input: "select next id from a", + output: "expecting value after next at position 15 near 'id'", + }, { + input: "select next 1+1 values from a", + output: "syntax error at position 15", + }, { + input: "insert into a values (select * from b)", + output: "syntax error at position 29 near 'select'", + }, { + input: "select database", + output: "syntax error at position 16", + }, { + input: "select mod from t", + output: "syntax error at position 16 near 'from'", + }, { + input: "select 1 from t where div 5", + output: "syntax error at position 26 near 'div'", + }, { + input: "select 1 from t where binary", + output: "syntax error at position 29", + }, { + input: "select match(a1, a2) against ('foo' in boolean mode with query expansion) from t", + output: "syntax error at position 57 near 'with'", + }, { + input: "select /* reserved keyword as unqualified column */ * from t where key = 'test'", + output: "syntax error at position 71 near 'key'", + }, { + input: "select /* vitess-reserved keyword as unqualified column */ * from t where escape = 'test'", + output: "syntax error at position 81 near 'escape'", + }, { + input: "(select /* parenthesized select */ * from t)", + output: "syntax error at position 45", + }, { + input: "select * from t where id = ((select a from t1 union select b from t2) order by a limit 1)", + output: "syntax error at position 76 near 'order'", + }, { + input: "select /* straight_join using */ 1 from t1 straight_join t2 using (a)", + output: "syntax error at position 66 near 'using'", + }, { + input: "select 'aa", + output: "syntax error at position 11 near 'aa'", + excludeMulti: true, + }, { + input: "select 'aa\\", + output: "syntax error at position 12 near 'aa'", + excludeMulti: true, + }, { + input: "select /* aa", + output: "syntax error at position 13 near '/* aa'", + excludeMulti: true, + }} +) + +func TestErrors(t *testing.T) { + for _, tcase := range invalidSQL { + _, err := Parse(tcase.input) + if err == nil || err.Error() != tcase.output { + t.Errorf("%s: %v, want %s", tcase.input, err, tcase.output) + } + } +} + +// Benchmark run on 6/23/17, prior to improvements: +// BenchmarkParse1-4 100000 16334 ns/op +// BenchmarkParse2-4 30000 44121 ns/op + +func BenchmarkParse1(b *testing.B) { + sql := "select 'abcd', 20, 30.0, eid from a where 1=eid and name='3'" + for i := 0; i < b.N; i++ { + ast, err := Parse(sql) + if err != nil { + b.Fatal(err) + } + _ = String(ast) + } +} + +func BenchmarkParse2(b *testing.B) { + sql := "select aaaa, bbb, ccc, ddd, eeee, ffff, gggg, hhhh, iiii from tttt, ttt1, ttt3 where aaaa = bbbb and bbbb = cccc and dddd+1 = eeee group by fff, gggg having hhhh = iiii and iiii = jjjj order by kkkk, llll limit 3, 4" + for i := 0; i < b.N; i++ { + ast, err := Parse(sql) + if err != nil { + b.Fatal(err) + } + _ = String(ast) + } +} + +var benchQuery string + +func init() { + // benchQuerySize is the approximate size of the query. + benchQuerySize := 1000000 + + // Size of value is 1/10 size of query. Then we add + // 10 such values to the where clause. + var baseval bytes.Buffer + for i := 0; i < benchQuerySize/100; i++ { + // Add an escape character: This will force the upcoming + // tokenizer improvement to still create a copy of the string. + // Then we can see if avoiding the copy will be worth it. + baseval.WriteString("\\'123456789") + } + + var buf bytes.Buffer + buf.WriteString("select a from t1 where v = 1") + for i := 0; i < 10; i++ { + fmt.Fprintf(&buf, " and v%d = \"%d%s\"", i, i, baseval.String()) + } + benchQuery = buf.String() +} + +func BenchmarkParse3(b *testing.B) { + for i := 0; i < b.N; i++ { + if _, err := Parse(benchQuery); err != nil { + b.Fatal(err) + } + } +} diff --git a/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/parsed_query.go b/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/parsed_query.go new file mode 100644 index 00000000..cf4ef03b --- /dev/null +++ b/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/parsed_query.go @@ -0,0 +1,119 @@ +/* +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 sqlparser + +import ( + "bytes" + "fmt" + + "github.com/xwb1989/sqlparser/dependency/querypb" + "github.com/xwb1989/sqlparser/dependency/sqltypes" +) + +// ParsedQuery represents a parsed query where +// bind locations are precompued for fast substitutions. +type ParsedQuery struct { + Query string + bindLocations []bindLocation +} + +type bindLocation struct { + offset, length int +} + +// NewParsedQuery returns a ParsedQuery of the ast. +func NewParsedQuery(node SQLNode) *ParsedQuery { + buf := NewTrackedBuffer(nil) + buf.Myprintf("%v", node) + return buf.ParsedQuery() +} + +// GenerateQuery generates a query by substituting the specified +// bindVariables. The extras parameter specifies special parameters +// that can perform custom encoding. +func (pq *ParsedQuery) GenerateQuery(bindVariables map[string]*querypb.BindVariable, extras map[string]Encodable) ([]byte, error) { + if len(pq.bindLocations) == 0 { + return []byte(pq.Query), nil + } + buf := bytes.NewBuffer(make([]byte, 0, len(pq.Query))) + current := 0 + for _, loc := range pq.bindLocations { + buf.WriteString(pq.Query[current:loc.offset]) + name := pq.Query[loc.offset : loc.offset+loc.length] + if encodable, ok := extras[name[1:]]; ok { + encodable.EncodeSQL(buf) + } else { + supplied, _, err := FetchBindVar(name, bindVariables) + if err != nil { + return nil, err + } + EncodeValue(buf, supplied) + } + current = loc.offset + loc.length + } + buf.WriteString(pq.Query[current:]) + return buf.Bytes(), nil +} + +// EncodeValue encodes one bind variable value into the query. +func EncodeValue(buf *bytes.Buffer, value *querypb.BindVariable) { + if value.Type != querypb.Type_TUPLE { + // Since we already check for TUPLE, we don't expect an error. + v, _ := sqltypes.BindVariableToValue(value) + v.EncodeSQL(buf) + return + } + + // It's a TUPLE. + buf.WriteByte('(') + for i, bv := range value.Values { + if i != 0 { + buf.WriteString(", ") + } + sqltypes.ProtoToValue(bv).EncodeSQL(buf) + } + buf.WriteByte(')') +} + +// FetchBindVar resolves the bind variable by fetching it from bindVariables. +func FetchBindVar(name string, bindVariables map[string]*querypb.BindVariable) (val *querypb.BindVariable, isList bool, err error) { + name = name[1:] + if name[0] == ':' { + name = name[1:] + isList = true + } + supplied, ok := bindVariables[name] + if !ok { + return nil, false, fmt.Errorf("missing bind var %s", name) + } + + if isList { + if supplied.Type != querypb.Type_TUPLE { + return nil, false, fmt.Errorf("unexpected list arg type (%v) for key %s", supplied.Type, name) + } + if len(supplied.Values) == 0 { + return nil, false, fmt.Errorf("empty list supplied for %s", name) + } + return supplied, true, nil + } + + if supplied.Type == querypb.Type_TUPLE { + return nil, false, fmt.Errorf("unexpected arg type (TUPLE) for non-list key %s", name) + } + + return supplied, false, nil +} diff --git a/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/parsed_query_test.go b/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/parsed_query_test.go new file mode 100644 index 00000000..dc0e1ac0 --- /dev/null +++ b/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/parsed_query_test.go @@ -0,0 +1,157 @@ +/* +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 sqlparser + +import ( + "reflect" + "testing" + + "github.com/xwb1989/sqlparser/dependency/sqltypes" + + "github.com/xwb1989/sqlparser/dependency/querypb" +) + +func TestNewParsedQuery(t *testing.T) { + stmt, err := Parse("select * from a where id =:id") + if err != nil { + t.Error(err) + return + } + pq := NewParsedQuery(stmt) + want := &ParsedQuery{ + Query: "select * from a where id = :id", + bindLocations: []bindLocation{{offset: 27, length: 3}}, + } + if !reflect.DeepEqual(pq, want) { + t.Errorf("GenerateParsedQuery: %+v, want %+v", pq, want) + } +} + +func TestGenerateQuery(t *testing.T) { + tcases := []struct { + desc string + query string + bindVars map[string]*querypb.BindVariable + extras map[string]Encodable + output string + }{ + { + desc: "no substitutions", + query: "select * from a where id = 2", + bindVars: map[string]*querypb.BindVariable{ + "id": sqltypes.Int64BindVariable(1), + }, + output: "select * from a where id = 2", + }, { + desc: "missing bind var", + query: "select * from a where id1 = :id1 and id2 = :id2", + bindVars: map[string]*querypb.BindVariable{ + "id1": sqltypes.Int64BindVariable(1), + }, + output: "missing bind var id2", + }, { + desc: "simple bindvar substitution", + query: "select * from a where id1 = :id1 and id2 = :id2", + bindVars: map[string]*querypb.BindVariable{ + "id1": sqltypes.Int64BindVariable(1), + "id2": sqltypes.NullBindVariable, + }, + output: "select * from a where id1 = 1 and id2 = null", + }, { + desc: "tuple *querypb.BindVariable", + query: "select * from a where id in ::vals", + bindVars: map[string]*querypb.BindVariable{ + "vals": sqltypes.TestBindVariable([]interface{}{1, "aa"}), + }, + output: "select * from a where id in (1, 'aa')", + }, { + desc: "list bind vars 0 arguments", + query: "select * from a where id in ::vals", + bindVars: map[string]*querypb.BindVariable{ + "vals": sqltypes.TestBindVariable([]interface{}{}), + }, + output: "empty list supplied for vals", + }, { + desc: "non-list bind var supplied", + query: "select * from a where id in ::vals", + bindVars: map[string]*querypb.BindVariable{ + "vals": sqltypes.Int64BindVariable(1), + }, + output: "unexpected list arg type (INT64) for key vals", + }, { + desc: "list bind var for non-list", + query: "select * from a where id = :vals", + bindVars: map[string]*querypb.BindVariable{ + "vals": sqltypes.TestBindVariable([]interface{}{1}), + }, + output: "unexpected arg type (TUPLE) for non-list key vals", + }, { + desc: "single column tuple equality", + query: "select * from a where b = :equality", + extras: map[string]Encodable{ + "equality": &TupleEqualityList{ + Columns: []ColIdent{NewColIdent("pk")}, + Rows: [][]sqltypes.Value{ + {sqltypes.NewInt64(1)}, + {sqltypes.NewVarBinary("aa")}, + }, + }, + }, + output: "select * from a where b = pk in (1, 'aa')", + }, { + desc: "multi column tuple equality", + query: "select * from a where b = :equality", + extras: map[string]Encodable{ + "equality": &TupleEqualityList{ + Columns: []ColIdent{NewColIdent("pk1"), NewColIdent("pk2")}, + Rows: [][]sqltypes.Value{ + { + sqltypes.NewInt64(1), + sqltypes.NewVarBinary("aa"), + }, + { + sqltypes.NewInt64(2), + sqltypes.NewVarBinary("bb"), + }, + }, + }, + }, + output: "select * from a where b = (pk1 = 1 and pk2 = 'aa') or (pk1 = 2 and pk2 = 'bb')", + }, + } + + for _, tcase := range tcases { + tree, err := Parse(tcase.query) + if err != nil { + t.Errorf("parse failed for %s: %v", tcase.desc, err) + continue + } + buf := NewTrackedBuffer(nil) + buf.Myprintf("%v", tree) + pq := buf.ParsedQuery() + bytes, err := pq.GenerateQuery(tcase.bindVars, tcase.extras) + var got string + if err != nil { + got = err.Error() + } else { + got = string(bytes) + } + if got != tcase.output { + t.Errorf("for test case: %s, got: '%s', want '%s'", tcase.desc, got, tcase.output) + } + } +} diff --git a/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/patches/bytes2.patch b/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/patches/bytes2.patch new file mode 100644 index 00000000..e69de29b diff --git a/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/patches/querypb.patch b/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/patches/querypb.patch new file mode 100644 index 00000000..abf19eac --- /dev/null +++ b/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/patches/querypb.patch @@ -0,0 +1,1315 @@ +diff -u /Users/bramp/go/src/vitess.io/vitess/go//vt/proto/query/query.pb.go /Users/bramp/go/src/github.com/xwb1989/sqlparser//dependency/querypb/query.pb.go +--- /Users/bramp/go/src/vitess.io/vitess/go//vt/proto/query/query.pb.go 2018-06-05 08:45:47.000000000 -0700 ++++ /Users/bramp/go/src/github.com/xwb1989/sqlparser//dependency/querypb/query.pb.go 2017-10-18 18:06:33.000000000 -0700 +@@ -62,30 +62,24 @@ + SplitQueryResponse + StreamHealthRequest + RealtimeStats +- AggregateStats + StreamHealthResponse + UpdateStreamRequest + UpdateStreamResponse + TransactionMetadata + */ +-package query ++package querypb + +-import proto "github.com/golang/protobuf/proto" +-import fmt "fmt" +-import math "math" +-import topodata "vitess.io/vitess/go/vt/proto/topodata" +-import vtrpc "vitess.io/vitess/go/vt/proto/vtrpc" +- +-// Reference imports to suppress errors if they are not otherwise used. +-var _ = proto.Marshal +-var _ = fmt.Errorf +-var _ = math.Inf +- +-// This is a compile-time assertion to ensure that this generated file +-// is compatible with the proto package it is being compiled against. +-// A compilation error at this line likely means your copy of the +-// proto package needs to be updated. +-const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package ++import "strconv" ++ ++// EnumName is a helper function to simplify printing protocol buffer enums ++// by name. Given an enum map and a value, it returns a useful string. ++func EnumName(m map[int32]string, v int32) string { ++ s, ok := m[v] ++ if ok { ++ return s ++ } ++ return strconv.Itoa(int(v)) ++} + + // Flags sent from the MySQL C API + type MySqlFlag int32 +@@ -159,9 +153,8 @@ + } + + func (x MySqlFlag) String() string { +- return proto.EnumName(MySqlFlag_name, int32(x)) ++ return EnumName(MySqlFlag_name, int32(x)) + } +-func (MySqlFlag) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{0} } + + // Flag allows us to qualify types by their common properties. + type Flag int32 +@@ -196,9 +189,8 @@ + } + + func (x Flag) String() string { +- return proto.EnumName(Flag_name, int32(x)) ++ return EnumName(Flag_name, int32(x)) + } +-func (Flag) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{1} } + + // Type defines the various supported data types in bind vars + // and query results. +@@ -375,9 +367,8 @@ + } + + func (x Type) String() string { +- return proto.EnumName(Type_name, int32(x)) ++ return EnumName(Type_name, int32(x)) + } +-func (Type) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{2} } + + // TransactionState represents the state of a distributed transaction. + type TransactionState int32 +@@ -403,9 +394,8 @@ + } + + func (x TransactionState) String() string { +- return proto.EnumName(TransactionState_name, int32(x)) ++ return EnumName(TransactionState_name, int32(x)) + } +-func (TransactionState) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{3} } + + type ExecuteOptions_IncludedFields int32 + +@@ -427,10 +417,7 @@ + } + + func (x ExecuteOptions_IncludedFields) String() string { +- return proto.EnumName(ExecuteOptions_IncludedFields_name, int32(x)) +-} +-func (ExecuteOptions_IncludedFields) EnumDescriptor() ([]byte, []int) { +- return fileDescriptor0, []int{6, 0} ++ return EnumName(ExecuteOptions_IncludedFields_name, int32(x)) + } + + type ExecuteOptions_Workload int32 +@@ -456,9 +443,8 @@ + } + + func (x ExecuteOptions_Workload) String() string { +- return proto.EnumName(ExecuteOptions_Workload_name, int32(x)) ++ return EnumName(ExecuteOptions_Workload_name, int32(x)) + } +-func (ExecuteOptions_Workload) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{6, 1} } + + type ExecuteOptions_TransactionIsolation int32 + +@@ -486,10 +472,7 @@ + } + + func (x ExecuteOptions_TransactionIsolation) String() string { +- return proto.EnumName(ExecuteOptions_TransactionIsolation_name, int32(x)) +-} +-func (ExecuteOptions_TransactionIsolation) EnumDescriptor() ([]byte, []int) { +- return fileDescriptor0, []int{6, 2} ++ return EnumName(ExecuteOptions_TransactionIsolation_name, int32(x)) + } + + // The category of one statement. +@@ -513,10 +496,7 @@ + } + + func (x StreamEvent_Statement_Category) String() string { +- return proto.EnumName(StreamEvent_Statement_Category_name, int32(x)) +-} +-func (StreamEvent_Statement_Category) EnumDescriptor() ([]byte, []int) { +- return fileDescriptor0, []int{11, 0, 0} ++ return EnumName(StreamEvent_Statement_Category_name, int32(x)) + } + + type SplitQueryRequest_Algorithm int32 +@@ -536,27 +516,22 @@ + } + + func (x SplitQueryRequest_Algorithm) String() string { +- return proto.EnumName(SplitQueryRequest_Algorithm_name, int32(x)) +-} +-func (SplitQueryRequest_Algorithm) EnumDescriptor() ([]byte, []int) { +- return fileDescriptor0, []int{49, 0} ++ return EnumName(SplitQueryRequest_Algorithm_name, int32(x)) + } + ++/* + // Target describes what the client expects the tablet is. + // If the tablet does not match, an error is returned. + type Target struct { + Keyspace string `protobuf:"bytes,1,opt,name=keyspace" json:"keyspace,omitempty"` + Shard string `protobuf:"bytes,2,opt,name=shard" json:"shard,omitempty"` + TabletType topodata.TabletType `protobuf:"varint,3,opt,name=tablet_type,json=tabletType,enum=topodata.TabletType" json:"tablet_type,omitempty"` +- // cell is used for routing queries between vtgate and vttablets. It +- // is not used when Target is part of the Session sent by the client. +- Cell string `protobuf:"bytes,4,opt,name=cell" json:"cell,omitempty"` + } + + func (m *Target) Reset() { *m = Target{} } +-func (m *Target) String() string { return proto.CompactTextString(m) } +-func (*Target) ProtoMessage() {} +-func (*Target) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} } ++func (m *Target) String() string { return "TODO" } ++ ++ + + func (m *Target) GetKeyspace() string { + if m != nil { +@@ -579,12 +554,6 @@ + return topodata.TabletType_UNKNOWN + } + +-func (m *Target) GetCell() string { +- if m != nil { +- return m.Cell +- } +- return "" +-} + + // VTGateCallerID is sent by VTGate to VTTablet to describe the + // caller. If possible, this information is secure. For instance, +@@ -600,9 +569,9 @@ + } + + func (m *VTGateCallerID) Reset() { *m = VTGateCallerID{} } +-func (m *VTGateCallerID) String() string { return proto.CompactTextString(m) } +-func (*VTGateCallerID) ProtoMessage() {} +-func (*VTGateCallerID) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} } ++func (m *VTGateCallerID) String() string { return "TODO" } ++ ++ + + func (m *VTGateCallerID) GetUsername() string { + if m != nil { +@@ -634,9 +603,9 @@ + } + + func (m *EventToken) Reset() { *m = EventToken{} } +-func (m *EventToken) String() string { return proto.CompactTextString(m) } +-func (*EventToken) ProtoMessage() {} +-func (*EventToken) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{2} } ++func (m *EventToken) String() string { return "TODO" } ++ ++ + + func (m *EventToken) GetTimestamp() int64 { + if m != nil { +@@ -658,6 +627,7 @@ + } + return "" + } ++*/ + + // Value represents a typed value. + type Value struct { +@@ -665,10 +635,8 @@ + Value []byte `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` + } + +-func (m *Value) Reset() { *m = Value{} } +-func (m *Value) String() string { return proto.CompactTextString(m) } +-func (*Value) ProtoMessage() {} +-func (*Value) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{3} } ++func (m *Value) Reset() { *m = Value{} } ++func (m *Value) String() string { return "TODO" } + + func (m *Value) GetType() Type { + if m != nil { +@@ -692,10 +660,8 @@ + Values []*Value `protobuf:"bytes,3,rep,name=values" json:"values,omitempty"` + } + +-func (m *BindVariable) Reset() { *m = BindVariable{} } +-func (m *BindVariable) String() string { return proto.CompactTextString(m) } +-func (*BindVariable) ProtoMessage() {} +-func (*BindVariable) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{4} } ++func (m *BindVariable) Reset() { *m = BindVariable{} } ++func (m *BindVariable) String() string { return "TODO" } + + func (m *BindVariable) GetType() Type { + if m != nil { +@@ -727,10 +693,8 @@ + BindVariables map[string]*BindVariable `protobuf:"bytes,2,rep,name=bind_variables,json=bindVariables" json:"bind_variables,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + } + +-func (m *BoundQuery) Reset() { *m = BoundQuery{} } +-func (m *BoundQuery) String() string { return proto.CompactTextString(m) } +-func (*BoundQuery) ProtoMessage() {} +-func (*BoundQuery) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{5} } ++func (m *BoundQuery) Reset() { *m = BoundQuery{} } ++func (m *BoundQuery) String() string { return "TODO" } + + func (m *BoundQuery) GetSql() string { + if m != nil { +@@ -746,6 +710,7 @@ + return nil + } + ++/* + // ExecuteOptions is passed around for all Execute calls. + type ExecuteOptions struct { + // If set, we will try to include an EventToken with the responses. +@@ -774,15 +739,12 @@ + // vitess also sets a rowcount limit on queries, the smallest value wins. + SqlSelectLimit int64 `protobuf:"varint,8,opt,name=sql_select_limit,json=sqlSelectLimit" json:"sql_select_limit,omitempty"` + TransactionIsolation ExecuteOptions_TransactionIsolation `protobuf:"varint,9,opt,name=transaction_isolation,json=transactionIsolation,enum=query.ExecuteOptions_TransactionIsolation" json:"transaction_isolation,omitempty"` +- // skip_query_plan_cache specifies if the query plan shoud be cached by vitess. +- // By default all query plans are cached. +- SkipQueryPlanCache bool `protobuf:"varint,10,opt,name=skip_query_plan_cache,json=skipQueryPlanCache" json:"skip_query_plan_cache,omitempty"` + } + + func (m *ExecuteOptions) Reset() { *m = ExecuteOptions{} } +-func (m *ExecuteOptions) String() string { return proto.CompactTextString(m) } +-func (*ExecuteOptions) ProtoMessage() {} +-func (*ExecuteOptions) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{6} } ++func (m *ExecuteOptions) String() string { return "TODO" } ++ ++ + + func (m *ExecuteOptions) GetIncludeEventToken() bool { + if m != nil { +@@ -833,13 +795,6 @@ + return ExecuteOptions_DEFAULT + } + +-func (m *ExecuteOptions) GetSkipQueryPlanCache() bool { +- if m != nil { +- return m.SkipQueryPlanCache +- } +- return false +-} +- + // Field describes a single column returned by a query + type Field struct { + // name of the field as returned by mysql C API +@@ -864,9 +819,9 @@ + } + + func (m *Field) Reset() { *m = Field{} } +-func (m *Field) String() string { return proto.CompactTextString(m) } +-func (*Field) ProtoMessage() {} +-func (*Field) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{7} } ++func (m *Field) String() string { return "TODO" } ++ ++ + + func (m *Field) GetName() string { + if m != nil { +@@ -950,9 +905,9 @@ + } + + func (m *Row) Reset() { *m = Row{} } +-func (m *Row) String() string { return proto.CompactTextString(m) } +-func (*Row) ProtoMessage() {} +-func (*Row) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{8} } ++func (m *Row) String() string { return "TODO" } ++ ++ + + func (m *Row) GetLengths() []int64 { + if m != nil { +@@ -980,9 +935,9 @@ + } + + func (m *ResultExtras) Reset() { *m = ResultExtras{} } +-func (m *ResultExtras) String() string { return proto.CompactTextString(m) } +-func (*ResultExtras) ProtoMessage() {} +-func (*ResultExtras) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{9} } ++func (m *ResultExtras) String() string { return "TODO" } ++ ++ + + func (m *ResultExtras) GetEventToken() *EventToken { + if m != nil { +@@ -1016,9 +971,9 @@ + } + + func (m *QueryResult) Reset() { *m = QueryResult{} } +-func (m *QueryResult) String() string { return proto.CompactTextString(m) } +-func (*QueryResult) ProtoMessage() {} +-func (*QueryResult) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{10} } ++func (m *QueryResult) String() string { return "TODO" } ++ ++ + + func (m *QueryResult) GetFields() []*Field { + if m != nil { +@@ -1066,9 +1021,9 @@ + } + + func (m *StreamEvent) Reset() { *m = StreamEvent{} } +-func (m *StreamEvent) String() string { return proto.CompactTextString(m) } +-func (*StreamEvent) ProtoMessage() {} +-func (*StreamEvent) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{11} } ++func (m *StreamEvent) String() string { return "TODO" } ++ ++ + + func (m *StreamEvent) GetStatements() []*StreamEvent_Statement { + if m != nil { +@@ -1097,9 +1052,9 @@ + } + + func (m *StreamEvent_Statement) Reset() { *m = StreamEvent_Statement{} } +-func (m *StreamEvent_Statement) String() string { return proto.CompactTextString(m) } +-func (*StreamEvent_Statement) ProtoMessage() {} +-func (*StreamEvent_Statement) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{11, 0} } ++func (m *StreamEvent_Statement) String() string { return "TODO" } ++ ++ + + func (m *StreamEvent_Statement) GetCategory() StreamEvent_Statement_Category { + if m != nil { +@@ -1136,6 +1091,7 @@ + return nil + } + ++ + // ExecuteRequest is the payload to Execute + type ExecuteRequest struct { + EffectiveCallerId *vtrpc.CallerID `protobuf:"bytes,1,opt,name=effective_caller_id,json=effectiveCallerId" json:"effective_caller_id,omitempty"` +@@ -1147,9 +1103,9 @@ + } + + func (m *ExecuteRequest) Reset() { *m = ExecuteRequest{} } +-func (m *ExecuteRequest) String() string { return proto.CompactTextString(m) } +-func (*ExecuteRequest) ProtoMessage() {} +-func (*ExecuteRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{12} } ++func (m *ExecuteRequest) String() string { return "TODO" } ++ ++ + + func (m *ExecuteRequest) GetEffectiveCallerId() *vtrpc.CallerID { + if m != nil { +@@ -1199,9 +1155,9 @@ + } + + func (m *ExecuteResponse) Reset() { *m = ExecuteResponse{} } +-func (m *ExecuteResponse) String() string { return proto.CompactTextString(m) } +-func (*ExecuteResponse) ProtoMessage() {} +-func (*ExecuteResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{13} } ++func (m *ExecuteResponse) String() string { return "TODO" } ++ ++ + + func (m *ExecuteResponse) GetResult() *QueryResult { + if m != nil { +@@ -1221,9 +1177,9 @@ + } + + func (m *ResultWithError) Reset() { *m = ResultWithError{} } +-func (m *ResultWithError) String() string { return proto.CompactTextString(m) } +-func (*ResultWithError) ProtoMessage() {} +-func (*ResultWithError) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{14} } ++func (m *ResultWithError) String() string { return "TODO" } ++ ++ + + func (m *ResultWithError) GetError() *vtrpc.RPCError { + if m != nil { +@@ -1251,9 +1207,9 @@ + } + + func (m *ExecuteBatchRequest) Reset() { *m = ExecuteBatchRequest{} } +-func (m *ExecuteBatchRequest) String() string { return proto.CompactTextString(m) } +-func (*ExecuteBatchRequest) ProtoMessage() {} +-func (*ExecuteBatchRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{15} } ++func (m *ExecuteBatchRequest) String() string { return "TODO" } ++ ++ + + func (m *ExecuteBatchRequest) GetEffectiveCallerId() *vtrpc.CallerID { + if m != nil { +@@ -1310,9 +1266,9 @@ + } + + func (m *ExecuteBatchResponse) Reset() { *m = ExecuteBatchResponse{} } +-func (m *ExecuteBatchResponse) String() string { return proto.CompactTextString(m) } +-func (*ExecuteBatchResponse) ProtoMessage() {} +-func (*ExecuteBatchResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{16} } ++func (m *ExecuteBatchResponse) String() string { return "TODO" } ++ ++ + + func (m *ExecuteBatchResponse) GetResults() []*QueryResult { + if m != nil { +@@ -1331,9 +1287,9 @@ + } + + func (m *StreamExecuteRequest) Reset() { *m = StreamExecuteRequest{} } +-func (m *StreamExecuteRequest) String() string { return proto.CompactTextString(m) } +-func (*StreamExecuteRequest) ProtoMessage() {} +-func (*StreamExecuteRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{17} } ++func (m *StreamExecuteRequest) String() string { return "TODO" } ++ ++ + + func (m *StreamExecuteRequest) GetEffectiveCallerId() *vtrpc.CallerID { + if m != nil { +@@ -1376,9 +1332,9 @@ + } + + func (m *StreamExecuteResponse) Reset() { *m = StreamExecuteResponse{} } +-func (m *StreamExecuteResponse) String() string { return proto.CompactTextString(m) } +-func (*StreamExecuteResponse) ProtoMessage() {} +-func (*StreamExecuteResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{18} } ++func (m *StreamExecuteResponse) String() string { return "TODO" } ++ ++ + + func (m *StreamExecuteResponse) GetResult() *QueryResult { + if m != nil { +@@ -1396,9 +1352,9 @@ + } + + func (m *BeginRequest) Reset() { *m = BeginRequest{} } +-func (m *BeginRequest) String() string { return proto.CompactTextString(m) } +-func (*BeginRequest) ProtoMessage() {} +-func (*BeginRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{19} } ++func (m *BeginRequest) String() string { return "TODO" } ++ ++ + + func (m *BeginRequest) GetEffectiveCallerId() *vtrpc.CallerID { + if m != nil { +@@ -1434,9 +1390,9 @@ + } + + func (m *BeginResponse) Reset() { *m = BeginResponse{} } +-func (m *BeginResponse) String() string { return proto.CompactTextString(m) } +-func (*BeginResponse) ProtoMessage() {} +-func (*BeginResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{20} } ++func (m *BeginResponse) String() string { return "TODO" } ++ ++ + + func (m *BeginResponse) GetTransactionId() int64 { + if m != nil { +@@ -1454,9 +1410,9 @@ + } + + func (m *CommitRequest) Reset() { *m = CommitRequest{} } +-func (m *CommitRequest) String() string { return proto.CompactTextString(m) } +-func (*CommitRequest) ProtoMessage() {} +-func (*CommitRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{21} } ++func (m *CommitRequest) String() string { return "TODO" } ++ ++ + + func (m *CommitRequest) GetEffectiveCallerId() *vtrpc.CallerID { + if m != nil { +@@ -1491,9 +1447,9 @@ + } + + func (m *CommitResponse) Reset() { *m = CommitResponse{} } +-func (m *CommitResponse) String() string { return proto.CompactTextString(m) } +-func (*CommitResponse) ProtoMessage() {} +-func (*CommitResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{22} } ++func (m *CommitResponse) String() string { return "TODO" } ++ ++ + + // RollbackRequest is the payload to Rollback + type RollbackRequest struct { +@@ -1504,9 +1460,9 @@ + } + + func (m *RollbackRequest) Reset() { *m = RollbackRequest{} } +-func (m *RollbackRequest) String() string { return proto.CompactTextString(m) } +-func (*RollbackRequest) ProtoMessage() {} +-func (*RollbackRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{23} } ++func (m *RollbackRequest) String() string { return "TODO" } ++ ++ + + func (m *RollbackRequest) GetEffectiveCallerId() *vtrpc.CallerID { + if m != nil { +@@ -1541,9 +1497,9 @@ + } + + func (m *RollbackResponse) Reset() { *m = RollbackResponse{} } +-func (m *RollbackResponse) String() string { return proto.CompactTextString(m) } +-func (*RollbackResponse) ProtoMessage() {} +-func (*RollbackResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{24} } ++func (m *RollbackResponse) String() string { return "TODO" } ++ ++ + + // PrepareRequest is the payload to Prepare + type PrepareRequest struct { +@@ -1555,9 +1511,9 @@ + } + + func (m *PrepareRequest) Reset() { *m = PrepareRequest{} } +-func (m *PrepareRequest) String() string { return proto.CompactTextString(m) } +-func (*PrepareRequest) ProtoMessage() {} +-func (*PrepareRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{25} } ++func (m *PrepareRequest) String() string { return "TODO" } ++ ++ + + func (m *PrepareRequest) GetEffectiveCallerId() *vtrpc.CallerID { + if m != nil { +@@ -1599,9 +1555,9 @@ + } + + func (m *PrepareResponse) Reset() { *m = PrepareResponse{} } +-func (m *PrepareResponse) String() string { return proto.CompactTextString(m) } +-func (*PrepareResponse) ProtoMessage() {} +-func (*PrepareResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{26} } ++func (m *PrepareResponse) String() string { return "TODO" } ++ ++ + + // CommitPreparedRequest is the payload to CommitPrepared + type CommitPreparedRequest struct { +@@ -1612,9 +1568,9 @@ + } + + func (m *CommitPreparedRequest) Reset() { *m = CommitPreparedRequest{} } +-func (m *CommitPreparedRequest) String() string { return proto.CompactTextString(m) } +-func (*CommitPreparedRequest) ProtoMessage() {} +-func (*CommitPreparedRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{27} } ++func (m *CommitPreparedRequest) String() string { return "TODO" } ++ ++ + + func (m *CommitPreparedRequest) GetEffectiveCallerId() *vtrpc.CallerID { + if m != nil { +@@ -1649,9 +1605,9 @@ + } + + func (m *CommitPreparedResponse) Reset() { *m = CommitPreparedResponse{} } +-func (m *CommitPreparedResponse) String() string { return proto.CompactTextString(m) } +-func (*CommitPreparedResponse) ProtoMessage() {} +-func (*CommitPreparedResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{28} } ++func (m *CommitPreparedResponse) String() string { return "TODO" } ++ ++ + + // RollbackPreparedRequest is the payload to RollbackPrepared + type RollbackPreparedRequest struct { +@@ -1663,9 +1619,9 @@ + } + + func (m *RollbackPreparedRequest) Reset() { *m = RollbackPreparedRequest{} } +-func (m *RollbackPreparedRequest) String() string { return proto.CompactTextString(m) } +-func (*RollbackPreparedRequest) ProtoMessage() {} +-func (*RollbackPreparedRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{29} } ++func (m *RollbackPreparedRequest) String() string { return "TODO" } ++ ++ + + func (m *RollbackPreparedRequest) GetEffectiveCallerId() *vtrpc.CallerID { + if m != nil { +@@ -1707,9 +1663,9 @@ + } + + func (m *RollbackPreparedResponse) Reset() { *m = RollbackPreparedResponse{} } +-func (m *RollbackPreparedResponse) String() string { return proto.CompactTextString(m) } +-func (*RollbackPreparedResponse) ProtoMessage() {} +-func (*RollbackPreparedResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{30} } ++func (m *RollbackPreparedResponse) String() string { return "TODO" } ++ ++ + + // CreateTransactionRequest is the payload to CreateTransaction + type CreateTransactionRequest struct { +@@ -1721,9 +1677,9 @@ + } + + func (m *CreateTransactionRequest) Reset() { *m = CreateTransactionRequest{} } +-func (m *CreateTransactionRequest) String() string { return proto.CompactTextString(m) } +-func (*CreateTransactionRequest) ProtoMessage() {} +-func (*CreateTransactionRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{31} } ++func (m *CreateTransactionRequest) String() string { return "TODO" } ++ ++ + + func (m *CreateTransactionRequest) GetEffectiveCallerId() *vtrpc.CallerID { + if m != nil { +@@ -1765,9 +1721,9 @@ + } + + func (m *CreateTransactionResponse) Reset() { *m = CreateTransactionResponse{} } +-func (m *CreateTransactionResponse) String() string { return proto.CompactTextString(m) } +-func (*CreateTransactionResponse) ProtoMessage() {} +-func (*CreateTransactionResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{32} } ++func (m *CreateTransactionResponse) String() string { return "TODO" } ++ ++ + + // StartCommitRequest is the payload to StartCommit + type StartCommitRequest struct { +@@ -1779,9 +1735,9 @@ + } + + func (m *StartCommitRequest) Reset() { *m = StartCommitRequest{} } +-func (m *StartCommitRequest) String() string { return proto.CompactTextString(m) } +-func (*StartCommitRequest) ProtoMessage() {} +-func (*StartCommitRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{33} } ++func (m *StartCommitRequest) String() string { return "TODO" } ++ ++ + + func (m *StartCommitRequest) GetEffectiveCallerId() *vtrpc.CallerID { + if m != nil { +@@ -1823,9 +1779,9 @@ + } + + func (m *StartCommitResponse) Reset() { *m = StartCommitResponse{} } +-func (m *StartCommitResponse) String() string { return proto.CompactTextString(m) } +-func (*StartCommitResponse) ProtoMessage() {} +-func (*StartCommitResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{34} } ++func (m *StartCommitResponse) String() string { return "TODO" } ++ ++ + + // SetRollbackRequest is the payload to SetRollback + type SetRollbackRequest struct { +@@ -1837,9 +1793,9 @@ + } + + func (m *SetRollbackRequest) Reset() { *m = SetRollbackRequest{} } +-func (m *SetRollbackRequest) String() string { return proto.CompactTextString(m) } +-func (*SetRollbackRequest) ProtoMessage() {} +-func (*SetRollbackRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{35} } ++func (m *SetRollbackRequest) String() string { return "TODO" } ++ ++ + + func (m *SetRollbackRequest) GetEffectiveCallerId() *vtrpc.CallerID { + if m != nil { +@@ -1881,9 +1837,9 @@ + } + + func (m *SetRollbackResponse) Reset() { *m = SetRollbackResponse{} } +-func (m *SetRollbackResponse) String() string { return proto.CompactTextString(m) } +-func (*SetRollbackResponse) ProtoMessage() {} +-func (*SetRollbackResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{36} } ++func (m *SetRollbackResponse) String() string { return "TODO" } ++ ++ + + // ConcludeTransactionRequest is the payload to ConcludeTransaction + type ConcludeTransactionRequest struct { +@@ -1894,9 +1850,9 @@ + } + + func (m *ConcludeTransactionRequest) Reset() { *m = ConcludeTransactionRequest{} } +-func (m *ConcludeTransactionRequest) String() string { return proto.CompactTextString(m) } +-func (*ConcludeTransactionRequest) ProtoMessage() {} +-func (*ConcludeTransactionRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{37} } ++func (m *ConcludeTransactionRequest) String() string { return "TODO" } ++ ++ + + func (m *ConcludeTransactionRequest) GetEffectiveCallerId() *vtrpc.CallerID { + if m != nil { +@@ -1931,9 +1887,9 @@ + } + + func (m *ConcludeTransactionResponse) Reset() { *m = ConcludeTransactionResponse{} } +-func (m *ConcludeTransactionResponse) String() string { return proto.CompactTextString(m) } +-func (*ConcludeTransactionResponse) ProtoMessage() {} +-func (*ConcludeTransactionResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{38} } ++func (m *ConcludeTransactionResponse) String() string { return "TODO" } ++ ++ + + // ReadTransactionRequest is the payload to ReadTransaction + type ReadTransactionRequest struct { +@@ -1944,9 +1900,9 @@ + } + + func (m *ReadTransactionRequest) Reset() { *m = ReadTransactionRequest{} } +-func (m *ReadTransactionRequest) String() string { return proto.CompactTextString(m) } +-func (*ReadTransactionRequest) ProtoMessage() {} +-func (*ReadTransactionRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{39} } ++func (m *ReadTransactionRequest) String() string { return "TODO" } ++ ++ + + func (m *ReadTransactionRequest) GetEffectiveCallerId() *vtrpc.CallerID { + if m != nil { +@@ -1982,9 +1938,9 @@ + } + + func (m *ReadTransactionResponse) Reset() { *m = ReadTransactionResponse{} } +-func (m *ReadTransactionResponse) String() string { return proto.CompactTextString(m) } +-func (*ReadTransactionResponse) ProtoMessage() {} +-func (*ReadTransactionResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{40} } ++func (m *ReadTransactionResponse) String() string { return "TODO" } ++ ++ + + func (m *ReadTransactionResponse) GetMetadata() *TransactionMetadata { + if m != nil { +@@ -2003,9 +1959,9 @@ + } + + func (m *BeginExecuteRequest) Reset() { *m = BeginExecuteRequest{} } +-func (m *BeginExecuteRequest) String() string { return proto.CompactTextString(m) } +-func (*BeginExecuteRequest) ProtoMessage() {} +-func (*BeginExecuteRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{41} } ++func (m *BeginExecuteRequest) String() string { return "TODO" } ++ ++ + + func (m *BeginExecuteRequest) GetEffectiveCallerId() *vtrpc.CallerID { + if m != nil { +@@ -2054,9 +2010,9 @@ + } + + func (m *BeginExecuteResponse) Reset() { *m = BeginExecuteResponse{} } +-func (m *BeginExecuteResponse) String() string { return proto.CompactTextString(m) } +-func (*BeginExecuteResponse) ProtoMessage() {} +-func (*BeginExecuteResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{42} } ++func (m *BeginExecuteResponse) String() string { return "TODO" } ++ ++ + + func (m *BeginExecuteResponse) GetError() *vtrpc.RPCError { + if m != nil { +@@ -2090,9 +2046,9 @@ + } + + func (m *BeginExecuteBatchRequest) Reset() { *m = BeginExecuteBatchRequest{} } +-func (m *BeginExecuteBatchRequest) String() string { return proto.CompactTextString(m) } +-func (*BeginExecuteBatchRequest) ProtoMessage() {} +-func (*BeginExecuteBatchRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{43} } ++func (m *BeginExecuteBatchRequest) String() string { return "TODO" } ++ ++ + + func (m *BeginExecuteBatchRequest) GetEffectiveCallerId() *vtrpc.CallerID { + if m != nil { +@@ -2148,9 +2104,9 @@ + } + + func (m *BeginExecuteBatchResponse) Reset() { *m = BeginExecuteBatchResponse{} } +-func (m *BeginExecuteBatchResponse) String() string { return proto.CompactTextString(m) } +-func (*BeginExecuteBatchResponse) ProtoMessage() {} +-func (*BeginExecuteBatchResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{44} } ++func (m *BeginExecuteBatchResponse) String() string { return "TODO" } ++ ++ + + func (m *BeginExecuteBatchResponse) GetError() *vtrpc.RPCError { + if m != nil { +@@ -2183,9 +2139,9 @@ + } + + func (m *MessageStreamRequest) Reset() { *m = MessageStreamRequest{} } +-func (m *MessageStreamRequest) String() string { return proto.CompactTextString(m) } +-func (*MessageStreamRequest) ProtoMessage() {} +-func (*MessageStreamRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{45} } ++func (m *MessageStreamRequest) String() string { return "TODO" } ++ ++ + + func (m *MessageStreamRequest) GetEffectiveCallerId() *vtrpc.CallerID { + if m != nil { +@@ -2221,9 +2177,9 @@ + } + + func (m *MessageStreamResponse) Reset() { *m = MessageStreamResponse{} } +-func (m *MessageStreamResponse) String() string { return proto.CompactTextString(m) } +-func (*MessageStreamResponse) ProtoMessage() {} +-func (*MessageStreamResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{46} } ++func (m *MessageStreamResponse) String() string { return "TODO" } ++ ++ + + func (m *MessageStreamResponse) GetResult() *QueryResult { + if m != nil { +@@ -2243,9 +2199,9 @@ + } + + func (m *MessageAckRequest) Reset() { *m = MessageAckRequest{} } +-func (m *MessageAckRequest) String() string { return proto.CompactTextString(m) } +-func (*MessageAckRequest) ProtoMessage() {} +-func (*MessageAckRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{47} } ++func (m *MessageAckRequest) String() string { return "TODO" } ++ ++ + + func (m *MessageAckRequest) GetEffectiveCallerId() *vtrpc.CallerID { + if m != nil { +@@ -2291,9 +2247,9 @@ + } + + func (m *MessageAckResponse) Reset() { *m = MessageAckResponse{} } +-func (m *MessageAckResponse) String() string { return proto.CompactTextString(m) } +-func (*MessageAckResponse) ProtoMessage() {} +-func (*MessageAckResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{48} } ++func (m *MessageAckResponse) String() string { return "TODO" } ++ ++ + + func (m *MessageAckResponse) GetResult() *QueryResult { + if m != nil { +@@ -2317,9 +2273,9 @@ + } + + func (m *SplitQueryRequest) Reset() { *m = SplitQueryRequest{} } +-func (m *SplitQueryRequest) String() string { return proto.CompactTextString(m) } +-func (*SplitQueryRequest) ProtoMessage() {} +-func (*SplitQueryRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{49} } ++func (m *SplitQueryRequest) String() string { return "TODO" } ++ ++ + + func (m *SplitQueryRequest) GetEffectiveCallerId() *vtrpc.CallerID { + if m != nil { +@@ -2386,9 +2342,9 @@ + } + + func (m *QuerySplit) Reset() { *m = QuerySplit{} } +-func (m *QuerySplit) String() string { return proto.CompactTextString(m) } +-func (*QuerySplit) ProtoMessage() {} +-func (*QuerySplit) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{50} } ++func (m *QuerySplit) String() string { return "TODO" } ++ ++ + + func (m *QuerySplit) GetQuery() *BoundQuery { + if m != nil { +@@ -2411,9 +2367,9 @@ + } + + func (m *SplitQueryResponse) Reset() { *m = SplitQueryResponse{} } +-func (m *SplitQueryResponse) String() string { return proto.CompactTextString(m) } +-func (*SplitQueryResponse) ProtoMessage() {} +-func (*SplitQueryResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{51} } ++func (m *SplitQueryResponse) String() string { return "TODO" } ++ ++ + + func (m *SplitQueryResponse) GetQueries() []*QuerySplit { + if m != nil { +@@ -2427,12 +2383,11 @@ + } + + func (m *StreamHealthRequest) Reset() { *m = StreamHealthRequest{} } +-func (m *StreamHealthRequest) String() string { return proto.CompactTextString(m) } +-func (*StreamHealthRequest) ProtoMessage() {} +-func (*StreamHealthRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{52} } ++func (m *StreamHealthRequest) String() string { return "TODO" } ++ + +-// RealtimeStats contains information about the tablet status. +-// It is only valid for a single tablet. ++ ++// RealtimeStats contains information about the tablet status + type RealtimeStats struct { + // health_error is the last error we got from health check, + // or empty is the server is healthy. This is used for subset selection, +@@ -2464,9 +2419,9 @@ + } + + func (m *RealtimeStats) Reset() { *m = RealtimeStats{} } +-func (m *RealtimeStats) String() string { return proto.CompactTextString(m) } +-func (*RealtimeStats) ProtoMessage() {} +-func (*RealtimeStats) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{53} } ++func (m *RealtimeStats) String() string { return "TODO" } ++ ++ + + func (m *RealtimeStats) GetHealthError() string { + if m != nil { +@@ -2510,80 +2465,17 @@ + return 0 + } + +-// AggregateStats contains information about the health of a group of +-// tablets for a Target. It is used to propagate stats from a vtgate +-// to another, or from the Gateway layer of a vtgate to the routing +-// layer. +-type AggregateStats struct { +- // healthy_tablet_count is the number of healthy tablets in the group. +- HealthyTabletCount int32 `protobuf:"varint,1,opt,name=healthy_tablet_count,json=healthyTabletCount" json:"healthy_tablet_count,omitempty"` +- // unhealthy_tablet_count is the number of unhealthy tablets in the group. +- UnhealthyTabletCount int32 `protobuf:"varint,2,opt,name=unhealthy_tablet_count,json=unhealthyTabletCount" json:"unhealthy_tablet_count,omitempty"` +- // seconds_behind_master_min is the minimum of the +- // seconds_behind_master values of the healthy tablets. It is unset +- // if the tablet type is master. +- SecondsBehindMasterMin uint32 `protobuf:"varint,3,opt,name=seconds_behind_master_min,json=secondsBehindMasterMin" json:"seconds_behind_master_min,omitempty"` +- // seconds_behind_master_max is the maximum of the +- // seconds_behind_master values of the healthy tablets. It is unset +- // if the tablet type is master. +- SecondsBehindMasterMax uint32 `protobuf:"varint,4,opt,name=seconds_behind_master_max,json=secondsBehindMasterMax" json:"seconds_behind_master_max,omitempty"` +-} +- +-func (m *AggregateStats) Reset() { *m = AggregateStats{} } +-func (m *AggregateStats) String() string { return proto.CompactTextString(m) } +-func (*AggregateStats) ProtoMessage() {} +-func (*AggregateStats) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{54} } +- +-func (m *AggregateStats) GetHealthyTabletCount() int32 { +- if m != nil { +- return m.HealthyTabletCount +- } +- return 0 +-} +- +-func (m *AggregateStats) GetUnhealthyTabletCount() int32 { +- if m != nil { +- return m.UnhealthyTabletCount +- } +- return 0 +-} +- +-func (m *AggregateStats) GetSecondsBehindMasterMin() uint32 { +- if m != nil { +- return m.SecondsBehindMasterMin +- } +- return 0 +-} +- +-func (m *AggregateStats) GetSecondsBehindMasterMax() uint32 { +- if m != nil { +- return m.SecondsBehindMasterMax +- } +- return 0 +-} +- +-// StreamHealthResponse is streamed by StreamHealth on a regular basis. +-// When StreamHealth is used between a vtgate and vttablet: +-// - target describes the tablet. +-// - realtime_stats is set. +-// - aggregate_stats is not set. +-// When StreamHealth is used between two vtgates: +-// - target describes the group of tablets. +-// - realtime_stats is not set. +-// - aggregate_stats is set. ++// StreamHealthResponse is streamed by StreamHealth on a regular basis + type StreamHealthResponse struct { + // target is the current server type. Only queries with that exact Target +- // record will be accepted (the cell may not match, however). ++ // record will be accepted. + Target *Target `protobuf:"bytes,1,opt,name=target" json:"target,omitempty"` + // serving is true iff the tablet is serving. A tablet may not be serving + // if filtered replication is enabled on a master for instance, + // or if a replica should not be used because the keyspace is being resharded. + Serving bool `protobuf:"varint,2,opt,name=serving" json:"serving,omitempty"` +- // tablet_externally_reparented_timestamp can be interpreted as the +- // last time we knew that this tablet was the MASTER of this shard +- // (if StreamHealthResponse describes a group of tablets, between +- // two vtgates, only one master will be present in the group, and +- // this is this master's value). ++ // tablet_externally_reparented_timestamp can be interpreted as the last time ++ // we knew that this tablet was the MASTER of this shard. + // + // It is used by vtgate when determining the current MASTER of a shard. + // If vtgate sees more than one MASTER tablet, this timestamp is used +@@ -2606,12 +2498,8 @@ + // OR + // d) 0 if the vttablet was never a MASTER. + TabletExternallyReparentedTimestamp int64 `protobuf:"varint,3,opt,name=tablet_externally_reparented_timestamp,json=tabletExternallyReparentedTimestamp" json:"tablet_externally_reparented_timestamp,omitempty"` +- // realtime_stats contains information about the tablet status. +- // It is only filled in if the information is about a tablet. ++ // realtime_stats contains information about the tablet status + RealtimeStats *RealtimeStats `protobuf:"bytes,4,opt,name=realtime_stats,json=realtimeStats" json:"realtime_stats,omitempty"` +- // AggregateStats constains information about the group of tablet status. +- // It is only filled in if the information is about a group of tablets. +- AggregateStats *AggregateStats `protobuf:"bytes,6,opt,name=aggregate_stats,json=aggregateStats" json:"aggregate_stats,omitempty"` + // tablet_alias is the alias of the sending tablet. The discovery/healthcheck.go + // code uses it to verify that it's talking to the correct tablet and that it + // hasn't changed in the meantime e.g. due to tablet restarts where ports or +@@ -2620,9 +2508,9 @@ + } + + func (m *StreamHealthResponse) Reset() { *m = StreamHealthResponse{} } +-func (m *StreamHealthResponse) String() string { return proto.CompactTextString(m) } +-func (*StreamHealthResponse) ProtoMessage() {} +-func (*StreamHealthResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{55} } ++func (m *StreamHealthResponse) String() string { return "TODO" } ++ ++ + + func (m *StreamHealthResponse) GetTarget() *Target { + if m != nil { +@@ -2652,13 +2540,6 @@ + return nil + } + +-func (m *StreamHealthResponse) GetAggregateStats() *AggregateStats { +- if m != nil { +- return m.AggregateStats +- } +- return nil +-} +- + func (m *StreamHealthResponse) GetTabletAlias() *topodata.TabletAlias { + if m != nil { + return m.TabletAlias +@@ -2682,9 +2563,9 @@ + } + + func (m *UpdateStreamRequest) Reset() { *m = UpdateStreamRequest{} } +-func (m *UpdateStreamRequest) String() string { return proto.CompactTextString(m) } +-func (*UpdateStreamRequest) ProtoMessage() {} +-func (*UpdateStreamRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{56} } ++func (m *UpdateStreamRequest) String() string { return "TODO" } ++ ++ + + func (m *UpdateStreamRequest) GetEffectiveCallerId() *vtrpc.CallerID { + if m != nil { +@@ -2727,9 +2608,9 @@ + } + + func (m *UpdateStreamResponse) Reset() { *m = UpdateStreamResponse{} } +-func (m *UpdateStreamResponse) String() string { return proto.CompactTextString(m) } +-func (*UpdateStreamResponse) ProtoMessage() {} +-func (*UpdateStreamResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{57} } ++func (m *UpdateStreamResponse) String() string { return "TODO" } ++ ++ + + func (m *UpdateStreamResponse) GetEvent() *StreamEvent { + if m != nil { +@@ -2747,9 +2628,9 @@ + } + + func (m *TransactionMetadata) Reset() { *m = TransactionMetadata{} } +-func (m *TransactionMetadata) String() string { return proto.CompactTextString(m) } +-func (*TransactionMetadata) ProtoMessage() {} +-func (*TransactionMetadata) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{58} } ++func (m *TransactionMetadata) String() string { return "TODO" } ++ ++ + + func (m *TransactionMetadata) GetDtid() string { + if m != nil { +@@ -2835,7 +2716,6 @@ + proto.RegisterType((*SplitQueryResponse)(nil), "query.SplitQueryResponse") + proto.RegisterType((*StreamHealthRequest)(nil), "query.StreamHealthRequest") + proto.RegisterType((*RealtimeStats)(nil), "query.RealtimeStats") +- proto.RegisterType((*AggregateStats)(nil), "query.AggregateStats") + proto.RegisterType((*StreamHealthResponse)(nil), "query.StreamHealthResponse") + proto.RegisterType((*UpdateStreamRequest)(nil), "query.UpdateStreamRequest") + proto.RegisterType((*UpdateStreamResponse)(nil), "query.UpdateStreamResponse") +@@ -2851,207 +2731,4 @@ + proto.RegisterEnum("query.SplitQueryRequest_Algorithm", SplitQueryRequest_Algorithm_name, SplitQueryRequest_Algorithm_value) + } + +-func init() { proto.RegisterFile("query.proto", fileDescriptor0) } +- +-var fileDescriptor0 = []byte{ +- // 3183 bytes of a gzipped FileDescriptorProto +- 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x5a, 0xcb, 0x73, 0x1b, 0xc7, +- 0x99, 0xd7, 0xe0, 0x41, 0x02, 0x1f, 0x08, 0xb0, 0xd9, 0x20, 0x25, 0x88, 0xf2, 0x83, 0x3b, 0xb6, +- 0x6c, 0x2e, 0xed, 0xe5, 0xca, 0x94, 0x56, 0xab, 0xb5, 0x77, 0xbd, 0x1a, 0x82, 0x43, 0x19, 0x16, +- 0x5e, 0x6a, 0x0c, 0x24, 0xcb, 0xe5, 0xaa, 0xa9, 0x21, 0xd0, 0x02, 0xa7, 0x38, 0xc0, 0x40, 0x33, +- 0x03, 0x51, 0xbc, 0x69, 0xd7, 0x71, 0xde, 0x0f, 0xe7, 0xe9, 0x38, 0xa9, 0x38, 0xa9, 0xca, 0x3d, +- 0x7f, 0x43, 0x2a, 0x7f, 0x40, 0x6e, 0x39, 0x24, 0x39, 0xe4, 0x90, 0x4a, 0xe5, 0x90, 0x2a, 0x57, +- 0x4e, 0x39, 0xe4, 0x90, 0x4a, 0xf5, 0x63, 0x06, 0x03, 0x12, 0x7a, 0x58, 0xc9, 0x85, 0xb2, 0x4f, +- 0xe8, 0xfe, 0xbe, 0xaf, 0x1f, 0xbf, 0xdf, 0xf7, 0xcd, 0xd7, 0x8d, 0xee, 0x86, 0xdc, 0xed, 0x11, +- 0xf5, 0x0e, 0xd6, 0x87, 0x9e, 0x1b, 0xb8, 0x38, 0xcd, 0x2b, 0xcb, 0x85, 0xc0, 0x1d, 0xba, 0x5d, +- 0x2b, 0xb0, 0x84, 0x78, 0x39, 0x77, 0x27, 0xf0, 0x86, 0x1d, 0x51, 0x51, 0xdf, 0x53, 0x60, 0xc6, +- 0xb0, 0xbc, 0x1e, 0x0d, 0xf0, 0x32, 0x64, 0xf6, 0xe8, 0x81, 0x3f, 0xb4, 0x3a, 0xb4, 0xa4, 0xac, +- 0x28, 0xab, 0x59, 0x12, 0xd5, 0xf1, 0x22, 0xa4, 0xfd, 0x5d, 0xcb, 0xeb, 0x96, 0x12, 0x5c, 0x21, +- 0x2a, 0xf8, 0x3f, 0x20, 0x17, 0x58, 0x3b, 0x0e, 0x0d, 0xcc, 0xe0, 0x60, 0x48, 0x4b, 0xc9, 0x15, +- 0x65, 0xb5, 0xb0, 0xb1, 0xb8, 0x1e, 0x8d, 0x67, 0x70, 0xa5, 0x71, 0x30, 0xa4, 0x04, 0x82, 0xa8, +- 0x8c, 0x31, 0xa4, 0x3a, 0xd4, 0x71, 0x4a, 0x29, 0xde, 0x17, 0x2f, 0xab, 0x5b, 0x50, 0xb8, 0x6e, +- 0x5c, 0xb1, 0x02, 0x5a, 0xb6, 0x1c, 0x87, 0x7a, 0x95, 0x2d, 0x36, 0x9d, 0x91, 0x4f, 0xbd, 0x81, +- 0xd5, 0x8f, 0xa6, 0x13, 0xd6, 0xf1, 0x49, 0x98, 0xe9, 0x79, 0xee, 0x68, 0xe8, 0x97, 0x12, 0x2b, +- 0xc9, 0xd5, 0x2c, 0x91, 0x35, 0xf5, 0x1d, 0x00, 0xfd, 0x0e, 0x1d, 0x04, 0x86, 0xbb, 0x47, 0x07, +- 0xf8, 0x29, 0xc8, 0x06, 0x76, 0x9f, 0xfa, 0x81, 0xd5, 0x1f, 0xf2, 0x2e, 0x92, 0x64, 0x2c, 0xb8, +- 0x0f, 0xa4, 0x65, 0xc8, 0x0c, 0x5d, 0xdf, 0x0e, 0x6c, 0x77, 0xc0, 0xf1, 0x64, 0x49, 0x54, 0x57, +- 0x5f, 0x87, 0xf4, 0x75, 0xcb, 0x19, 0x51, 0xfc, 0x2c, 0xa4, 0x38, 0x60, 0x85, 0x03, 0xce, 0xad, +- 0x0b, 0xd2, 0x39, 0x4e, 0xae, 0x60, 0x7d, 0xdf, 0x61, 0x96, 0xbc, 0xef, 0x39, 0x22, 0x2a, 0xea, +- 0x1e, 0xcc, 0x6d, 0xda, 0x83, 0xee, 0x75, 0xcb, 0xb3, 0x19, 0x19, 0x8f, 0xd9, 0x0d, 0x7e, 0x1e, +- 0x66, 0x78, 0xc1, 0x2f, 0x25, 0x57, 0x92, 0xab, 0xb9, 0x8d, 0x39, 0xd9, 0x90, 0xcf, 0x8d, 0x48, +- 0x9d, 0xfa, 0x0b, 0x05, 0x60, 0xd3, 0x1d, 0x0d, 0xba, 0xd7, 0x98, 0x12, 0x23, 0x48, 0xfa, 0xb7, +- 0x1d, 0x49, 0x24, 0x2b, 0xe2, 0xab, 0x50, 0xd8, 0xb1, 0x07, 0x5d, 0xf3, 0x8e, 0x9c, 0x8e, 0xe0, +- 0x32, 0xb7, 0xf1, 0xbc, 0xec, 0x6e, 0xdc, 0x78, 0x3d, 0x3e, 0x6b, 0x5f, 0x1f, 0x04, 0xde, 0x01, +- 0xc9, 0xef, 0xc4, 0x65, 0xcb, 0x6d, 0xc0, 0x47, 0x8d, 0xd8, 0xa0, 0x7b, 0xf4, 0x20, 0x1c, 0x74, +- 0x8f, 0x1e, 0xe0, 0x7f, 0x8d, 0x23, 0xca, 0x6d, 0x14, 0xc3, 0xb1, 0x62, 0x6d, 0x25, 0xcc, 0x57, +- 0x13, 0x97, 0x14, 0xf5, 0x4f, 0x69, 0x28, 0xe8, 0x77, 0x69, 0x67, 0x14, 0xd0, 0xc6, 0x90, 0xf9, +- 0xc0, 0xc7, 0xeb, 0x50, 0xb4, 0x07, 0x1d, 0x67, 0xd4, 0xa5, 0x26, 0x65, 0xae, 0x36, 0x03, 0xe6, +- 0x6b, 0xde, 0x5f, 0x86, 0x2c, 0x48, 0x55, 0x2c, 0x08, 0x34, 0x28, 0x76, 0xdc, 0xfe, 0xd0, 0xf2, +- 0x26, 0xed, 0x93, 0x7c, 0xfc, 0x05, 0x39, 0xfe, 0xd8, 0x9e, 0x2c, 0x48, 0xeb, 0x58, 0x17, 0x35, +- 0x98, 0x97, 0xfd, 0x76, 0xcd, 0x5b, 0x36, 0x75, 0xba, 0x3e, 0x0f, 0xdd, 0x42, 0x44, 0xd5, 0xe4, +- 0x14, 0xd7, 0x2b, 0xd2, 0x78, 0x9b, 0xdb, 0x92, 0x82, 0x3d, 0x51, 0xc7, 0x6b, 0xb0, 0xd0, 0x71, +- 0x6c, 0x36, 0x95, 0x5b, 0x8c, 0x62, 0xd3, 0x73, 0xf7, 0xfd, 0x52, 0x9a, 0xcf, 0x7f, 0x5e, 0x28, +- 0xb6, 0x99, 0x9c, 0xb8, 0xfb, 0x3e, 0x7e, 0x15, 0x32, 0xfb, 0xae, 0xb7, 0xe7, 0xb8, 0x56, 0xb7, +- 0x34, 0xc3, 0xc7, 0x7c, 0x66, 0xfa, 0x98, 0x37, 0xa4, 0x15, 0x89, 0xec, 0xf1, 0x2a, 0x20, 0xff, +- 0xb6, 0x63, 0xfa, 0xd4, 0xa1, 0x9d, 0xc0, 0x74, 0xec, 0xbe, 0x1d, 0x94, 0x32, 0xfc, 0x2b, 0x28, +- 0xf8, 0xb7, 0x9d, 0x16, 0x17, 0x57, 0x99, 0x14, 0x9b, 0xb0, 0x14, 0x78, 0xd6, 0xc0, 0xb7, 0x3a, +- 0xac, 0x33, 0xd3, 0xf6, 0x5d, 0xc7, 0xe2, 0x5f, 0x40, 0x96, 0x0f, 0xb9, 0x36, 0x7d, 0x48, 0x63, +- 0xdc, 0xa4, 0x12, 0xb6, 0x20, 0x8b, 0xc1, 0x14, 0x29, 0x7e, 0x05, 0x96, 0xfc, 0x3d, 0x7b, 0x68, +- 0xf2, 0x7e, 0xcc, 0xa1, 0x63, 0x0d, 0xcc, 0x8e, 0xd5, 0xd9, 0xa5, 0x25, 0xe0, 0xb0, 0x31, 0x53, +- 0xf2, 0x50, 0x6b, 0x3a, 0xd6, 0xa0, 0xcc, 0x34, 0xea, 0x6b, 0x50, 0x98, 0xe4, 0x11, 0x2f, 0x40, +- 0xde, 0xb8, 0xd9, 0xd4, 0x4d, 0xad, 0xbe, 0x65, 0xd6, 0xb5, 0x9a, 0x8e, 0x4e, 0xe0, 0x3c, 0x64, +- 0xb9, 0xa8, 0x51, 0xaf, 0xde, 0x44, 0x0a, 0x9e, 0x85, 0xa4, 0x56, 0xad, 0xa2, 0x84, 0x7a, 0x09, +- 0x32, 0x21, 0x21, 0x78, 0x1e, 0x72, 0xed, 0x7a, 0xab, 0xa9, 0x97, 0x2b, 0xdb, 0x15, 0x7d, 0x0b, +- 0x9d, 0xc0, 0x19, 0x48, 0x35, 0xaa, 0x46, 0x13, 0x29, 0xa2, 0xa4, 0x35, 0x51, 0x82, 0xb5, 0xdc, +- 0xda, 0xd4, 0x50, 0x52, 0x0d, 0x60, 0x71, 0x1a, 0x2e, 0x9c, 0x83, 0xd9, 0x2d, 0x7d, 0x5b, 0x6b, +- 0x57, 0x0d, 0x74, 0x02, 0x17, 0x61, 0x9e, 0xe8, 0x4d, 0x5d, 0x33, 0xb4, 0xcd, 0xaa, 0x6e, 0x12, +- 0x5d, 0xdb, 0x42, 0x0a, 0xc6, 0x50, 0x60, 0x25, 0xb3, 0xdc, 0xa8, 0xd5, 0x2a, 0x86, 0xa1, 0x6f, +- 0xa1, 0x04, 0x5e, 0x04, 0xc4, 0x65, 0xed, 0xfa, 0x58, 0x9a, 0xc4, 0x08, 0xe6, 0x5a, 0x3a, 0xa9, +- 0x68, 0xd5, 0xca, 0xdb, 0xac, 0x03, 0x94, 0x7a, 0x33, 0x95, 0x51, 0x50, 0x42, 0xfd, 0x20, 0x01, +- 0x69, 0x8e, 0x95, 0x65, 0xc8, 0x58, 0xde, 0xe3, 0xe5, 0x28, 0x5b, 0x24, 0x1e, 0x90, 0x2d, 0x78, +- 0x92, 0x95, 0x79, 0x4b, 0x54, 0xf0, 0x19, 0xc8, 0xba, 0x5e, 0xcf, 0x14, 0x1a, 0x91, 0x71, 0x33, +- 0xae, 0xd7, 0xe3, 0xa9, 0x99, 0x65, 0x3b, 0x96, 0xa8, 0x77, 0x2c, 0x9f, 0xf2, 0x08, 0xcc, 0x92, +- 0xa8, 0x8e, 0x4f, 0x03, 0xb3, 0x33, 0xf9, 0x3c, 0x66, 0xb8, 0x6e, 0xd6, 0xf5, 0x7a, 0x75, 0x36, +- 0x95, 0xe7, 0x20, 0xdf, 0x71, 0x9d, 0x51, 0x7f, 0x60, 0x3a, 0x74, 0xd0, 0x0b, 0x76, 0x4b, 0xb3, +- 0x2b, 0xca, 0x6a, 0x9e, 0xcc, 0x09, 0x61, 0x95, 0xcb, 0x70, 0x09, 0x66, 0x3b, 0xbb, 0x96, 0xe7, +- 0x53, 0x11, 0x75, 0x79, 0x12, 0x56, 0xf9, 0xa8, 0xb4, 0x63, 0xf7, 0x2d, 0xc7, 0xe7, 0x11, 0x96, +- 0x27, 0x51, 0x9d, 0x81, 0xb8, 0xe5, 0x58, 0x3d, 0x9f, 0x47, 0x46, 0x9e, 0x88, 0x8a, 0xfa, 0x9f, +- 0x90, 0x24, 0xee, 0x3e, 0xeb, 0x52, 0x0c, 0xe8, 0x97, 0x94, 0x95, 0xe4, 0x2a, 0x26, 0x61, 0x95, +- 0x2d, 0x08, 0x32, 0x27, 0x8a, 0x54, 0x19, 0x66, 0xc1, 0x77, 0x60, 0x8e, 0x50, 0x7f, 0xe4, 0x04, +- 0xfa, 0xdd, 0xc0, 0xb3, 0x7c, 0xbc, 0x01, 0xb9, 0x78, 0x16, 0x50, 0xee, 0x97, 0x05, 0x80, 0x8e, +- 0x3f, 0xff, 0x12, 0xcc, 0xde, 0xf2, 0xa8, 0xbf, 0x4b, 0x3d, 0x99, 0x65, 0xc2, 0x2a, 0xcb, 0xb1, +- 0x39, 0x1e, 0xb6, 0x62, 0x0c, 0x96, 0x99, 0x65, 0x7e, 0x50, 0x26, 0x32, 0x33, 0x77, 0x2a, 0x91, +- 0x3a, 0xc6, 0x1e, 0xfb, 0xe4, 0x4d, 0xeb, 0xd6, 0x2d, 0xda, 0x09, 0xa8, 0x58, 0x80, 0x52, 0x64, +- 0x8e, 0x09, 0x35, 0x29, 0x63, 0x6e, 0xb3, 0x07, 0x3e, 0xf5, 0x02, 0xd3, 0xee, 0x72, 0x87, 0xa6, +- 0x48, 0x46, 0x08, 0x2a, 0x5d, 0xfc, 0x0c, 0xa4, 0x78, 0xd2, 0x48, 0xf1, 0x51, 0x40, 0x8e, 0x42, +- 0xdc, 0x7d, 0xc2, 0xe5, 0xf8, 0x25, 0x98, 0xa1, 0x1c, 0x2f, 0x77, 0xea, 0x38, 0xcd, 0xc6, 0xa9, +- 0x20, 0xd2, 0x44, 0xfd, 0x49, 0x12, 0x72, 0xad, 0xc0, 0xa3, 0x56, 0x9f, 0xe3, 0xc7, 0xff, 0x0d, +- 0xe0, 0x07, 0x56, 0x40, 0xfb, 0x74, 0x10, 0x84, 0x40, 0x9e, 0x92, 0x1d, 0xc4, 0xec, 0xd6, 0x5b, +- 0xa1, 0x11, 0x89, 0xd9, 0x1f, 0x26, 0x38, 0xf1, 0x08, 0x04, 0x2f, 0x7f, 0x94, 0x80, 0x6c, 0xd4, +- 0x1b, 0xd6, 0x20, 0xd3, 0xb1, 0x02, 0xda, 0x73, 0xbd, 0x03, 0xb9, 0x32, 0x9e, 0x7d, 0xd0, 0xe8, +- 0xeb, 0x65, 0x69, 0x4c, 0xa2, 0x66, 0xf8, 0x69, 0x10, 0xdb, 0x0d, 0x11, 0xbc, 0x62, 0x7d, 0xcf, +- 0x72, 0x09, 0x0f, 0xdf, 0x57, 0x01, 0x0f, 0x3d, 0xbb, 0x6f, 0x79, 0x07, 0xe6, 0x1e, 0x3d, 0x08, +- 0x53, 0x7a, 0x72, 0x8a, 0xcb, 0x90, 0xb4, 0xbb, 0x4a, 0x0f, 0x64, 0x12, 0xba, 0x34, 0xd9, 0x56, +- 0x06, 0xdd, 0x51, 0x47, 0xc4, 0x5a, 0xf2, 0x75, 0xd9, 0x0f, 0x57, 0xe0, 0x34, 0x8f, 0x4f, 0x56, +- 0x54, 0x5f, 0x84, 0x4c, 0x38, 0x79, 0x9c, 0x85, 0xb4, 0xee, 0x79, 0xae, 0x87, 0x4e, 0xf0, 0x5c, +- 0x54, 0xab, 0x8a, 0x74, 0xb6, 0xb5, 0xc5, 0xd2, 0xd9, 0xcf, 0x13, 0xd1, 0x32, 0x48, 0xe8, 0xed, +- 0x11, 0xf5, 0x03, 0xfc, 0xbf, 0x50, 0xa4, 0x3c, 0x56, 0xec, 0x3b, 0xd4, 0xec, 0xf0, 0x3d, 0x13, +- 0x8b, 0x14, 0x11, 0xd0, 0xf3, 0xeb, 0x62, 0x8b, 0x17, 0xee, 0xa5, 0xc8, 0x42, 0x64, 0x2b, 0x45, +- 0x5d, 0xac, 0x43, 0xd1, 0xee, 0xf7, 0x69, 0xd7, 0xb6, 0x82, 0x78, 0x07, 0xc2, 0x61, 0x4b, 0xe1, +- 0x96, 0x62, 0x62, 0x4b, 0x46, 0x16, 0xa2, 0x16, 0x51, 0x37, 0x67, 0x61, 0x26, 0xe0, 0xdb, 0x47, +- 0xb9, 0xa2, 0xe6, 0xc3, 0xbc, 0xc4, 0x85, 0x44, 0x2a, 0xf1, 0x8b, 0x20, 0x36, 0xa3, 0x3c, 0x03, +- 0x8d, 0x03, 0x62, 0xbc, 0xc7, 0x20, 0x42, 0x8f, 0xcf, 0x42, 0x61, 0x62, 0x29, 0xea, 0x72, 0xc2, +- 0x92, 0x24, 0x1f, 0x5f, 0x57, 0xba, 0xf8, 0xdf, 0x61, 0xd6, 0x15, 0xcb, 0x10, 0xcf, 0x4d, 0xe3, +- 0x19, 0x4f, 0xae, 0x51, 0x24, 0xb4, 0x52, 0xff, 0x07, 0xe6, 0x23, 0x06, 0xfd, 0xa1, 0x3b, 0xf0, +- 0x29, 0x5e, 0x83, 0x19, 0x8f, 0x7f, 0x10, 0x92, 0x35, 0x2c, 0xbb, 0x88, 0x7d, 0xd1, 0x44, 0x5a, +- 0xa8, 0x5d, 0x98, 0x17, 0x92, 0x1b, 0x76, 0xb0, 0xcb, 0x1d, 0x85, 0xcf, 0x42, 0x9a, 0xb2, 0xc2, +- 0x21, 0xce, 0x49, 0xb3, 0xcc, 0xf5, 0x44, 0x68, 0x63, 0xa3, 0x24, 0x1e, 0x3a, 0xca, 0x9f, 0x13, +- 0x50, 0x94, 0xb3, 0xdc, 0xb4, 0x82, 0xce, 0xee, 0x31, 0x75, 0xf6, 0x4b, 0x30, 0xcb, 0xe4, 0x76, +- 0xf4, 0x61, 0x4c, 0x71, 0x77, 0x68, 0xc1, 0x1c, 0x6e, 0xf9, 0x66, 0xcc, 0xbb, 0x72, 0x2b, 0x94, +- 0xb7, 0xfc, 0xd8, 0x42, 0x3c, 0x25, 0x2e, 0x66, 0x1e, 0x12, 0x17, 0xb3, 0x8f, 0x14, 0x17, 0x5b, +- 0xb0, 0x38, 0xc9, 0xb8, 0x0c, 0x8e, 0x97, 0x61, 0x56, 0x38, 0x25, 0x4c, 0x81, 0xd3, 0xfc, 0x16, +- 0x9a, 0xa8, 0x3f, 0x4e, 0xc0, 0xa2, 0xcc, 0x4e, 0x9f, 0x8e, 0xcf, 0x34, 0xc6, 0x73, 0xfa, 0x91, +- 0x78, 0x2e, 0xc3, 0xd2, 0x21, 0x82, 0x1e, 0xe3, 0x2b, 0xfc, 0x58, 0x81, 0xb9, 0x4d, 0xda, 0xb3, +- 0x07, 0xc7, 0x94, 0xde, 0x18, 0x6b, 0xa9, 0x47, 0x62, 0xed, 0x22, 0xe4, 0x25, 0x5e, 0xc9, 0xd6, +- 0xd1, 0xcf, 0x40, 0x99, 0xf2, 0x19, 0xa8, 0x7f, 0x50, 0x20, 0x5f, 0x76, 0xfb, 0x7d, 0x3b, 0x38, +- 0xa6, 0x4c, 0x1d, 0xc5, 0x99, 0x9a, 0x86, 0x13, 0x41, 0x21, 0x84, 0x29, 0x08, 0x52, 0xff, 0xa8, +- 0xc0, 0x3c, 0x71, 0x1d, 0x67, 0xc7, 0xea, 0xec, 0x3d, 0xd9, 0xd8, 0x31, 0xa0, 0x31, 0x50, 0x89, +- 0xfe, 0xaf, 0x0a, 0x14, 0x9a, 0x1e, 0x65, 0xff, 0x5f, 0x9f, 0x68, 0xf0, 0xec, 0x0f, 0x52, 0x37, +- 0x90, 0x9b, 0x83, 0x2c, 0xe1, 0x65, 0x75, 0x01, 0xe6, 0x23, 0xec, 0x92, 0x8f, 0xdf, 0x28, 0xb0, +- 0x24, 0x02, 0x44, 0x6a, 0xba, 0xc7, 0x94, 0x96, 0x10, 0x6f, 0x2a, 0x86, 0xb7, 0x04, 0x27, 0x0f, +- 0x63, 0x93, 0xb0, 0xdf, 0x4d, 0xc0, 0xa9, 0x30, 0x36, 0x8e, 0x39, 0xf0, 0x7f, 0x20, 0x1e, 0x96, +- 0xa1, 0x74, 0x94, 0x04, 0xc9, 0xd0, 0xfb, 0x09, 0x28, 0x95, 0x3d, 0x6a, 0x05, 0x34, 0xb6, 0xc9, +- 0x78, 0x72, 0x62, 0x03, 0xbf, 0x02, 0x73, 0x43, 0xcb, 0x0b, 0xec, 0x8e, 0x3d, 0xb4, 0xd8, 0xdf, +- 0xb8, 0x34, 0xdf, 0xc3, 0x1c, 0xea, 0x60, 0xc2, 0x44, 0x3d, 0x03, 0xa7, 0xa7, 0x30, 0x22, 0xf9, +- 0xfa, 0x9b, 0x02, 0xb8, 0x15, 0x58, 0x5e, 0xf0, 0x29, 0x58, 0x55, 0xa6, 0x06, 0xd3, 0x12, 0x14, +- 0x27, 0xf0, 0xc7, 0x79, 0xa1, 0xc1, 0xa7, 0x62, 0xc5, 0xb9, 0x2f, 0x2f, 0x71, 0xfc, 0x92, 0x97, +- 0xdf, 0x29, 0xb0, 0x5c, 0x76, 0xc5, 0xf9, 0xdd, 0x13, 0xf9, 0x85, 0xa9, 0x4f, 0xc3, 0x99, 0xa9, +- 0x00, 0x25, 0x01, 0xbf, 0x55, 0xe0, 0x24, 0xa1, 0x56, 0xf7, 0xc9, 0x04, 0x7f, 0x0d, 0x4e, 0x1d, +- 0x01, 0x27, 0x77, 0xa8, 0x17, 0x21, 0xd3, 0xa7, 0x81, 0xd5, 0xb5, 0x02, 0x4b, 0x42, 0x5a, 0x0e, +- 0xfb, 0x1d, 0x5b, 0xd7, 0xa4, 0x05, 0x89, 0x6c, 0xd5, 0x8f, 0x12, 0x50, 0xe4, 0x7b, 0xdd, 0xcf, +- 0xfe, 0x41, 0x4d, 0xff, 0x2f, 0xf0, 0xbe, 0x02, 0x8b, 0x93, 0x04, 0x45, 0xff, 0x09, 0xfe, 0xd9, +- 0x07, 0x11, 0x53, 0x12, 0x42, 0x72, 0xda, 0x16, 0xf4, 0x97, 0x09, 0x28, 0xc5, 0xa7, 0xf4, 0xd9, +- 0xa1, 0xc5, 0xe4, 0xa1, 0xc5, 0x27, 0x3e, 0xa5, 0xfa, 0x40, 0x81, 0xd3, 0x53, 0x08, 0xfd, 0x64, +- 0x8e, 0x8e, 0x1d, 0x5d, 0x24, 0x1e, 0x7a, 0x74, 0xf1, 0xa8, 0xae, 0xfe, 0xb5, 0x02, 0x8b, 0x35, +- 0xea, 0xfb, 0x56, 0x8f, 0x8a, 0xff, 0xf1, 0xc7, 0x37, 0x9b, 0xf1, 0x43, 0xe1, 0xd4, 0xf8, 0x66, +- 0x45, 0x2d, 0xc3, 0xd2, 0x21, 0x68, 0x8f, 0x71, 0x36, 0xf1, 0x17, 0x05, 0x16, 0x64, 0x2f, 0xda, +- 0xb1, 0xdd, 0x08, 0x4c, 0x61, 0x07, 0x3f, 0x03, 0x49, 0xbb, 0x1b, 0xee, 0x20, 0x27, 0xef, 0x9a, +- 0x99, 0x42, 0xbd, 0x0c, 0x38, 0x8e, 0xfb, 0x31, 0xa8, 0xfb, 0x55, 0x12, 0x16, 0x5a, 0x43, 0xc7, +- 0x0e, 0xa4, 0xf2, 0xc9, 0x4e, 0xfc, 0xff, 0x02, 0x73, 0x3e, 0x03, 0x6b, 0x8a, 0xdb, 0x32, 0x4e, +- 0x6c, 0x96, 0xe4, 0xb8, 0xac, 0xcc, 0x45, 0xf8, 0x59, 0xc8, 0x85, 0x26, 0xa3, 0x41, 0x20, 0x4f, +- 0x3a, 0x41, 0x5a, 0x8c, 0x06, 0x01, 0xbe, 0x00, 0xa7, 0x06, 0xa3, 0x3e, 0xbf, 0x39, 0x36, 0x87, +- 0xd4, 0x0b, 0xef, 0x55, 0x2d, 0x2f, 0xbc, 0xe1, 0x2d, 0x0e, 0x46, 0x7d, 0xe2, 0xee, 0xfb, 0x4d, +- 0xea, 0x89, 0x7b, 0x55, 0xcb, 0x0b, 0xf0, 0x65, 0xc8, 0x5a, 0x4e, 0xcf, 0xf5, 0xec, 0x60, 0xb7, +- 0x2f, 0xaf, 0x76, 0xd5, 0xf0, 0x6a, 0xe5, 0x30, 0xfd, 0xeb, 0x5a, 0x68, 0x49, 0xc6, 0x8d, 0xd4, +- 0x97, 0x21, 0x1b, 0xc9, 0x31, 0x82, 0x39, 0xfd, 0x5a, 0x5b, 0xab, 0x9a, 0xad, 0x66, 0xb5, 0x62, +- 0xb4, 0xc4, 0x75, 0xec, 0x76, 0xbb, 0x5a, 0x35, 0x5b, 0x65, 0xad, 0x8e, 0x14, 0x95, 0x00, 0xf0, +- 0x2e, 0x79, 0xe7, 0x63, 0x82, 0x94, 0x87, 0x10, 0x74, 0x06, 0xb2, 0x9e, 0xbb, 0x2f, 0xb1, 0x27, +- 0x38, 0x9c, 0x8c, 0xe7, 0xee, 0x73, 0xe4, 0xaa, 0x06, 0x38, 0x3e, 0x57, 0x19, 0x6d, 0xb1, 0xe4, +- 0xad, 0x4c, 0x24, 0xef, 0xf1, 0xf8, 0x51, 0xf2, 0x16, 0x5b, 0x79, 0xf6, 0x9d, 0xbf, 0x41, 0x2d, +- 0x27, 0x08, 0xd7, 0x2b, 0xf5, 0xa7, 0x09, 0xc8, 0x13, 0x26, 0xb1, 0xfb, 0xb4, 0x15, 0x58, 0x81, +- 0xcf, 0x3c, 0xb5, 0xcb, 0x4d, 0xcc, 0x71, 0xda, 0xcd, 0x92, 0x9c, 0x90, 0x89, 0x4b, 0x80, 0x0d, +- 0x58, 0xf2, 0x69, 0xc7, 0x1d, 0x74, 0x7d, 0x73, 0x87, 0xee, 0xda, 0x83, 0xae, 0xd9, 0xb7, 0xfc, +- 0x40, 0xde, 0x14, 0xe6, 0x49, 0x51, 0x2a, 0x37, 0xb9, 0xae, 0xc6, 0x55, 0xf8, 0x1c, 0x2c, 0xee, +- 0xd8, 0x03, 0xc7, 0xed, 0x99, 0x43, 0xc7, 0x3a, 0xa0, 0x9e, 0x2f, 0xa1, 0xb2, 0xf0, 0x4a, 0x13, +- 0x2c, 0x74, 0x4d, 0xa1, 0x12, 0xee, 0x7e, 0x1b, 0xd6, 0xa6, 0x8e, 0x62, 0xde, 0xb2, 0x9d, 0x80, +- 0x7a, 0xb4, 0x6b, 0x7a, 0x74, 0xe8, 0xd8, 0x1d, 0x71, 0x69, 0x2f, 0xf6, 0xee, 0x2f, 0x4c, 0x19, +- 0x7a, 0x5b, 0x9a, 0x93, 0xb1, 0x35, 0x63, 0xbb, 0x33, 0x1c, 0x99, 0x23, 0xf6, 0x01, 0xf3, 0x55, +- 0x4c, 0x21, 0x99, 0xce, 0x70, 0xd4, 0x66, 0x75, 0x8c, 0x20, 0x79, 0x7b, 0x28, 0x16, 0x2f, 0x85, +- 0xb0, 0xa2, 0xfa, 0xb1, 0x02, 0x05, 0xad, 0xd7, 0xf3, 0x68, 0xcf, 0x0a, 0x24, 0x4d, 0xe7, 0x60, +- 0x51, 0x50, 0x72, 0x60, 0xca, 0xd7, 0x40, 0x02, 0x8f, 0x22, 0xf0, 0x48, 0x9d, 0x78, 0x0b, 0x14, +- 0x86, 0xef, 0xc9, 0xd1, 0x60, 0x6a, 0x9b, 0x04, 0x6f, 0xb3, 0x18, 0x69, 0xe3, 0xad, 0xfe, 0x0b, +- 0x4e, 0x4f, 0x67, 0xa1, 0x6f, 0x8b, 0xf7, 0x1c, 0x79, 0x72, 0x72, 0x0a, 0xe8, 0x9a, 0x3d, 0x78, +- 0x40, 0x53, 0xeb, 0x2e, 0xe7, 0xeb, 0x3e, 0x4d, 0xad, 0xbb, 0xea, 0xef, 0xa3, 0xa3, 0xfd, 0x30, +- 0x5c, 0xa2, 0xd5, 0x38, 0xcc, 0x0b, 0xca, 0x83, 0xf2, 0x42, 0x09, 0x66, 0x7d, 0xea, 0xdd, 0xb1, +- 0x07, 0xbd, 0xf0, 0xf6, 0x58, 0x56, 0x71, 0x0b, 0x5e, 0x90, 0xd8, 0xe9, 0xdd, 0x80, 0x7a, 0x03, +- 0xcb, 0x71, 0x0e, 0x4c, 0x71, 0x50, 0x31, 0x08, 0x68, 0xd7, 0x1c, 0xbf, 0x5d, 0x12, 0x2b, 0xf2, +- 0x73, 0xc2, 0x5a, 0x8f, 0x8c, 0x49, 0x64, 0x6b, 0x44, 0xaf, 0x9a, 0x5e, 0x83, 0x82, 0x27, 0x83, +- 0xd8, 0xf4, 0x99, 0x7b, 0x64, 0x3e, 0x5a, 0x8c, 0xae, 0x80, 0x63, 0x11, 0x4e, 0xf2, 0xde, 0x44, +- 0xc0, 0xbf, 0x0e, 0xf3, 0x56, 0xe8, 0x5b, 0xd9, 0x7a, 0x72, 0xdf, 0x32, 0xe9, 0x79, 0x52, 0xb0, +- 0x26, 0x23, 0xe1, 0x12, 0xcc, 0x49, 0x44, 0x96, 0x63, 0x5b, 0xe3, 0x8d, 0xed, 0xa1, 0x07, 0x61, +- 0x1a, 0x53, 0x12, 0xf9, 0x74, 0x8c, 0x57, 0xd8, 0xff, 0xe8, 0x62, 0x7b, 0xd8, 0xe5, 0x3d, 0x1d, +- 0xe3, 0xdd, 0x45, 0xfc, 0xf5, 0x58, 0x6a, 0xf2, 0xf5, 0xd8, 0xe4, 0x6b, 0xb4, 0xf4, 0xa1, 0xd7, +- 0x68, 0xea, 0x65, 0x58, 0x9c, 0xc4, 0x2f, 0xa3, 0x6c, 0x15, 0xd2, 0xfc, 0xa6, 0xfc, 0xd0, 0x32, +- 0x1a, 0xbb, 0x0a, 0x27, 0xc2, 0x40, 0xfd, 0x99, 0x02, 0xc5, 0x29, 0x7f, 0xb1, 0xa2, 0xff, 0x6f, +- 0x4a, 0xec, 0x78, 0xe8, 0xdf, 0x20, 0xcd, 0xef, 0xec, 0xe5, 0x63, 0x92, 0x53, 0x47, 0xff, 0xa1, +- 0xf1, 0xfb, 0x75, 0x22, 0xac, 0x58, 0x22, 0xe4, 0x01, 0xd5, 0xe1, 0xe7, 0x43, 0xe1, 0x0e, 0x31, +- 0xc7, 0x64, 0xe2, 0xc8, 0xe8, 0xe8, 0x81, 0x53, 0xea, 0xa1, 0x07, 0x4e, 0x6b, 0xdf, 0x4a, 0x42, +- 0xb6, 0x76, 0xd0, 0xba, 0xed, 0x6c, 0x3b, 0x56, 0x8f, 0x5f, 0x80, 0xd7, 0x9a, 0xc6, 0x4d, 0x74, +- 0x02, 0x2f, 0x40, 0xbe, 0xde, 0x30, 0xcc, 0x3a, 0x5b, 0x4a, 0xb6, 0xab, 0xda, 0x15, 0xa4, 0xb0, +- 0xb5, 0xa6, 0x49, 0x2a, 0xe6, 0x55, 0xfd, 0xa6, 0x90, 0x24, 0x70, 0x11, 0xe6, 0xdb, 0xf5, 0xca, +- 0xb5, 0xb6, 0x3e, 0x16, 0xa6, 0xf0, 0x12, 0x2c, 0xd4, 0xda, 0x55, 0xa3, 0xd2, 0xac, 0xc6, 0xc4, +- 0x19, 0xb6, 0x2e, 0x6d, 0x56, 0x1b, 0x9b, 0xa2, 0x8a, 0x58, 0xff, 0xed, 0x7a, 0xab, 0x72, 0xa5, +- 0xae, 0x6f, 0x09, 0xd1, 0x0a, 0x13, 0xbd, 0xad, 0x93, 0xc6, 0x76, 0x25, 0x1c, 0xf2, 0x32, 0x46, +- 0x90, 0xdb, 0xac, 0xd4, 0x35, 0x22, 0x7b, 0xb9, 0xa7, 0xe0, 0x02, 0x64, 0xf5, 0x7a, 0xbb, 0x26, +- 0xeb, 0x09, 0x5c, 0x82, 0xa2, 0xd6, 0x36, 0x1a, 0x66, 0xa5, 0x5e, 0x26, 0x7a, 0x4d, 0xaf, 0x1b, +- 0x52, 0x93, 0xc2, 0x45, 0x28, 0x18, 0x95, 0x9a, 0xde, 0x32, 0xb4, 0x5a, 0x53, 0x0a, 0xd9, 0x2c, +- 0x32, 0x2d, 0x3d, 0xb4, 0x41, 0x78, 0x19, 0x96, 0xea, 0x0d, 0x53, 0x3e, 0x2a, 0x32, 0xaf, 0x6b, +- 0xd5, 0xb6, 0x2e, 0x75, 0x2b, 0xf8, 0x14, 0xe0, 0x46, 0xdd, 0x6c, 0x37, 0xb7, 0x34, 0x43, 0x37, +- 0xeb, 0x8d, 0x1b, 0x52, 0x71, 0x19, 0x17, 0x20, 0x33, 0x9e, 0xc1, 0x3d, 0xc6, 0x42, 0xbe, 0xa9, +- 0x11, 0x63, 0x0c, 0xf6, 0xde, 0x3d, 0x46, 0x16, 0x5c, 0x21, 0x8d, 0x76, 0x73, 0x6c, 0xb6, 0x00, +- 0x39, 0x49, 0x96, 0x14, 0xa5, 0x98, 0x68, 0xb3, 0x52, 0x2f, 0x47, 0xf3, 0xbb, 0x97, 0x59, 0x4e, +- 0x20, 0x65, 0x6d, 0x0f, 0x52, 0xdc, 0x1d, 0x19, 0x48, 0xd5, 0x1b, 0x75, 0x1d, 0x9d, 0xc0, 0xf3, +- 0x00, 0x95, 0x56, 0xa5, 0x6e, 0xe8, 0x57, 0x88, 0x56, 0x65, 0xb0, 0xb9, 0x20, 0x24, 0x90, 0xa1, +- 0x9d, 0x83, 0xd9, 0x4a, 0x6b, 0xbb, 0xda, 0xd0, 0x0c, 0x09, 0xb3, 0xd2, 0xba, 0xd6, 0x6e, 0x18, +- 0x4c, 0x89, 0x70, 0x0e, 0x66, 0x2a, 0x2d, 0x43, 0x7f, 0xcb, 0x60, 0xb8, 0xb8, 0x4e, 0xb0, 0x8a, +- 0xee, 0x5d, 0x5e, 0xfb, 0x30, 0x09, 0x29, 0xfe, 0x22, 0x34, 0x0f, 0x59, 0xee, 0x6d, 0xe3, 0x66, +- 0x93, 0x0d, 0x99, 0x85, 0x54, 0xa5, 0x6e, 0x5c, 0x42, 0xff, 0x97, 0xc0, 0x00, 0xe9, 0x36, 0x2f, +- 0xff, 0xff, 0x0c, 0x2b, 0x57, 0xea, 0xc6, 0x2b, 0x17, 0xd1, 0xbb, 0x09, 0xd6, 0x6d, 0x5b, 0x54, +- 0x3e, 0x17, 0x2a, 0x36, 0x2e, 0xa0, 0xf7, 0x22, 0xc5, 0xc6, 0x05, 0xf4, 0xf9, 0x50, 0x71, 0x7e, +- 0x03, 0x7d, 0x21, 0x52, 0x9c, 0xdf, 0x40, 0x5f, 0x0c, 0x15, 0x17, 0x2f, 0xa0, 0x2f, 0x45, 0x8a, +- 0x8b, 0x17, 0xd0, 0x97, 0x67, 0x18, 0x16, 0x8e, 0xe4, 0xfc, 0x06, 0xfa, 0x4a, 0x26, 0xaa, 0x5d, +- 0xbc, 0x80, 0xbe, 0x9a, 0x61, 0xfe, 0x8f, 0xbc, 0x8a, 0xbe, 0x86, 0xd8, 0x34, 0x99, 0x83, 0xd0, +- 0xd7, 0x79, 0x91, 0xa9, 0xd0, 0x37, 0x10, 0xc3, 0xc8, 0xa4, 0xbc, 0xfa, 0x3e, 0xd7, 0xdc, 0xd4, +- 0x35, 0x82, 0xbe, 0x39, 0x23, 0xde, 0x90, 0x95, 0x2b, 0x35, 0xad, 0x8a, 0x30, 0x6f, 0xc1, 0x58, +- 0xf9, 0xf6, 0x39, 0x56, 0x64, 0xe1, 0x89, 0xbe, 0xd3, 0x64, 0x03, 0x5e, 0xd7, 0x48, 0xf9, 0x0d, +- 0x8d, 0xa0, 0xef, 0x9e, 0x63, 0x03, 0x5e, 0xd7, 0x88, 0xe4, 0xeb, 0x7b, 0x4d, 0x66, 0xc8, 0x55, +- 0x1f, 0x9c, 0x63, 0x93, 0x96, 0xf2, 0xef, 0x37, 0x71, 0x06, 0x92, 0x9b, 0x15, 0x03, 0x7d, 0xc8, +- 0x47, 0x63, 0x21, 0x8a, 0x7e, 0x80, 0x98, 0xb0, 0xa5, 0x1b, 0xe8, 0x87, 0x4c, 0x98, 0x36, 0xda, +- 0xcd, 0xaa, 0x8e, 0x9e, 0x62, 0x93, 0xbb, 0xa2, 0x37, 0x6a, 0xba, 0x41, 0x6e, 0xa2, 0x1f, 0x71, +- 0xf3, 0x37, 0x5b, 0x8d, 0x3a, 0xfa, 0x08, 0xe1, 0x02, 0x80, 0xfe, 0x56, 0x93, 0xe8, 0xad, 0x56, +- 0xa5, 0x51, 0x47, 0xcf, 0xae, 0x6d, 0x03, 0x3a, 0x9c, 0x0e, 0x18, 0x80, 0x76, 0xfd, 0x6a, 0xbd, +- 0x71, 0xa3, 0x8e, 0x4e, 0xb0, 0x4a, 0x93, 0xe8, 0x4d, 0x8d, 0xe8, 0x48, 0xc1, 0x00, 0x33, 0xe2, +- 0x85, 0x1b, 0x4a, 0xe0, 0x39, 0xc8, 0x90, 0x46, 0xb5, 0xba, 0xa9, 0x95, 0xaf, 0xa2, 0xe4, 0xe6, +- 0x02, 0xcc, 0xdb, 0xee, 0xfa, 0x1d, 0x3b, 0xa0, 0xbe, 0x2f, 0xde, 0x1c, 0xef, 0xcc, 0xf0, 0x9f, +- 0xf3, 0x7f, 0x0f, 0x00, 0x00, 0xff, 0xff, 0xde, 0xe3, 0xd2, 0x1e, 0xad, 0x2c, 0x00, 0x00, +-} ++*/ diff --git a/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/patches/sqlparser.patch b/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/patches/sqlparser.patch new file mode 100644 index 00000000..9cdc14e0 --- /dev/null +++ b/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/patches/sqlparser.patch @@ -0,0 +1,316 @@ +Only in /Users/bramp/go/src/github.com/xwb1989/sqlparser//: .git +Only in /Users/bramp/go/src/github.com/xwb1989/sqlparser//: .gitignore +Only in /Users/bramp/go/src/github.com/xwb1989/sqlparser//: .travis.yml +Only in /Users/bramp/go/src/github.com/xwb1989/sqlparser//: CONTRIBUTORS.md +Only in /Users/bramp/go/src/github.com/xwb1989/sqlparser//: LICENSE.md +Only in /Users/bramp/go/src/github.com/xwb1989/sqlparser//: README.md +diff -u /Users/bramp/go/src/vitess.io/vitess/go//vt/sqlparser/analyzer.go /Users/bramp/go/src/github.com/xwb1989/sqlparser//analyzer.go +--- /Users/bramp/go/src/vitess.io/vitess/go//vt/sqlparser/analyzer.go 2018-06-05 08:45:47.000000000 -0700 ++++ /Users/bramp/go/src/github.com/xwb1989/sqlparser//analyzer.go 2018-06-06 07:45:09.000000000 -0700 +@@ -19,15 +19,13 @@ + // analyzer.go contains utility analysis functions. + + import ( ++ "errors" + "fmt" + "strconv" + "strings" + "unicode" + +- "vitess.io/vitess/go/sqltypes" +- "vitess.io/vitess/go/vt/vterrors" +- +- vtrpcpb "vitess.io/vitess/go/vt/proto/vtrpc" ++ "github.com/xwb1989/sqlparser/dependency/sqltypes" + ) + + // These constants are used to identify the SQL statement type. +@@ -219,7 +217,7 @@ + case IntVal: + n, err := sqltypes.NewIntegral(string(node.Val)) + if err != nil { +- return sqltypes.PlanValue{}, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "%v", err) ++ return sqltypes.PlanValue{}, fmt.Errorf("%v", err) + } + return sqltypes.PlanValue{Value: n}, nil + case StrVal: +@@ -227,7 +225,7 @@ + case HexVal: + v, err := node.HexDecode() + if err != nil { +- return sqltypes.PlanValue{}, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "%v", err) ++ return sqltypes.PlanValue{}, fmt.Errorf("%v", err) + } + return sqltypes.PlanValue{Value: sqltypes.MakeTrusted(sqltypes.VarBinary, v)}, nil + } +@@ -243,7 +241,7 @@ + return sqltypes.PlanValue{}, err + } + if innerpv.ListKey != "" || innerpv.Values != nil { +- return sqltypes.PlanValue{}, vterrors.New(vtrpcpb.Code_UNIMPLEMENTED, "unsupported: nested lists") ++ return sqltypes.PlanValue{}, errors.New("unsupported: nested lists") + } + pv.Values = append(pv.Values, innerpv) + } +@@ -251,7 +249,7 @@ + case *NullVal: + return sqltypes.PlanValue{}, nil + } +- return sqltypes.PlanValue{}, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "expression is too complex '%v'", String(node)) ++ return sqltypes.PlanValue{}, fmt.Errorf("expression is too complex '%v'", String(node)) + } + + // StringIn is a convenience function that returns +diff -u /Users/bramp/go/src/vitess.io/vitess/go//vt/sqlparser/analyzer_test.go /Users/bramp/go/src/github.com/xwb1989/sqlparser//analyzer_test.go +--- /Users/bramp/go/src/vitess.io/vitess/go//vt/sqlparser/analyzer_test.go 2018-06-05 08:45:47.000000000 -0700 ++++ /Users/bramp/go/src/github.com/xwb1989/sqlparser//analyzer_test.go 2018-06-06 07:45:09.000000000 -0700 +@@ -21,7 +21,7 @@ + "strings" + "testing" + +- "vitess.io/vitess/go/sqltypes" ++ "github.com/xwb1989/sqlparser/dependency/sqltypes" + ) + + func TestPreview(t *testing.T) { +diff -u /Users/bramp/go/src/vitess.io/vitess/go//vt/sqlparser/ast.go /Users/bramp/go/src/github.com/xwb1989/sqlparser//ast.go +--- /Users/bramp/go/src/vitess.io/vitess/go//vt/sqlparser/ast.go 2018-06-05 08:45:47.000000000 -0700 ++++ /Users/bramp/go/src/github.com/xwb1989/sqlparser//ast.go 2018-06-06 07:45:09.000000000 -0700 +@@ -22,14 +22,11 @@ + "encoding/json" + "fmt" + "io" ++ "log" + "strings" + +- "vitess.io/vitess/go/sqltypes" +- "vitess.io/vitess/go/vt/log" +- "vitess.io/vitess/go/vt/vterrors" +- +- querypb "vitess.io/vitess/go/vt/proto/query" +- vtrpcpb "vitess.io/vitess/go/vt/proto/vtrpc" ++ "github.com/xwb1989/sqlparser/dependency/querypb" ++ "github.com/xwb1989/sqlparser/dependency/sqltypes" + ) + + // Instructions for creating new types: If a type +@@ -52,11 +49,11 @@ + tokenizer := NewStringTokenizer(sql) + if yyParse(tokenizer) != 0 { + if tokenizer.partialDDL != nil { +- log.Warningf("ignoring error parsing DDL '%s': %v", sql, tokenizer.LastError) ++ log.Printf("ignoring error parsing DDL '%s': %v", sql, tokenizer.LastError) + tokenizer.ParseTree = tokenizer.partialDDL + return tokenizer.ParseTree, nil + } +- return nil, vterrors.New(vtrpcpb.Code_INVALID_ARGUMENT, tokenizer.LastError.Error()) ++ return nil, tokenizer.LastError + } + return tokenizer.ParseTree, nil + } +@@ -2249,7 +2246,7 @@ + return NewStrVal(value.ToBytes()), nil + default: + // We cannot support sqltypes.Expression, or any other invalid type. +- return nil, vterrors.Errorf(vtrpcpb.Code_INTERNAL, "cannot convert value %v to AST", value) ++ return nil, fmt.Errorf("cannot convert value %v to AST", value) + } + } + +@@ -3394,6 +3391,20 @@ + return nil + } + ++// Backtick produces a backticked literal given an input string. ++func Backtick(in string) string { ++ var buf bytes.Buffer ++ buf.WriteByte('`') ++ for _, c := range in { ++ buf.WriteRune(c) ++ if c == '`' { ++ buf.WriteByte('`') ++ } ++ } ++ buf.WriteByte('`') ++ return buf.String() ++} ++ + func formatID(buf *TrackedBuffer, original, lowered string) { + isDbSystemVariable := false + if len(original) > 1 && original[:2] == "@@" { +diff -u /Users/bramp/go/src/vitess.io/vitess/go//vt/sqlparser/ast_test.go /Users/bramp/go/src/github.com/xwb1989/sqlparser//ast_test.go +--- /Users/bramp/go/src/vitess.io/vitess/go//vt/sqlparser/ast_test.go 2018-06-05 08:45:47.000000000 -0700 ++++ /Users/bramp/go/src/github.com/xwb1989/sqlparser//ast_test.go 2018-06-05 07:41:09.000000000 -0700 +@@ -24,7 +24,7 @@ + "testing" + "unsafe" + +- "vitess.io/vitess/go/sqltypes" ++ "github.com/xwb1989/sqlparser/dependency/sqltypes" + ) + + func TestAppend(t *testing.T) { +diff -u /Users/bramp/go/src/vitess.io/vitess/go//vt/sqlparser/comments.go /Users/bramp/go/src/github.com/xwb1989/sqlparser//comments.go +--- /Users/bramp/go/src/vitess.io/vitess/go//vt/sqlparser/comments.go 2018-06-05 08:45:47.000000000 -0700 ++++ /Users/bramp/go/src/github.com/xwb1989/sqlparser//comments.go 2018-06-06 07:45:09.000000000 -0700 +@@ -145,7 +145,7 @@ + // Single line comment + index := strings.Index(sql, "\n") + if index == -1 { +- return "" ++ return sql + } + sql = sql[index+1:] + } +diff -u /Users/bramp/go/src/vitess.io/vitess/go//vt/sqlparser/comments_test.go /Users/bramp/go/src/github.com/xwb1989/sqlparser//comments_test.go +--- /Users/bramp/go/src/vitess.io/vitess/go//vt/sqlparser/comments_test.go 2018-06-05 08:45:47.000000000 -0700 ++++ /Users/bramp/go/src/github.com/xwb1989/sqlparser//comments_test.go 2018-06-06 07:45:08.000000000 -0700 +@@ -187,7 +187,7 @@ + outSQL: "bar", + }, { + input: "-- /* foo */ bar", +- outSQL: "", ++ outSQL: "-- /* foo */ bar", + }, { + input: "foo -- bar */", + outSQL: "foo -- bar */", +@@ -201,7 +201,7 @@ + outSQL: "a", + }, { + input: `-- foo bar`, +- outSQL: "", ++ outSQL: "-- foo bar", + }} + for _, testCase := range testCases { + gotSQL := StripLeadingComments(testCase.input) +Only in /Users/bramp/go/src/github.com/xwb1989/sqlparser//: dependency +diff -u /Users/bramp/go/src/vitess.io/vitess/go//vt/sqlparser/encodable.go /Users/bramp/go/src/github.com/xwb1989/sqlparser//encodable.go +--- /Users/bramp/go/src/vitess.io/vitess/go//vt/sqlparser/encodable.go 2018-06-05 08:45:47.000000000 -0700 ++++ /Users/bramp/go/src/github.com/xwb1989/sqlparser//encodable.go 2017-10-18 18:06:33.000000000 -0700 +@@ -19,7 +19,7 @@ + import ( + "bytes" + +- "vitess.io/vitess/go/sqltypes" ++ "github.com/xwb1989/sqlparser/dependency/sqltypes" + ) + + // This file contains types that are 'Encodable'. +diff -u /Users/bramp/go/src/vitess.io/vitess/go//vt/sqlparser/encodable_test.go /Users/bramp/go/src/github.com/xwb1989/sqlparser//encodable_test.go +--- /Users/bramp/go/src/vitess.io/vitess/go//vt/sqlparser/encodable_test.go 2018-06-05 08:45:47.000000000 -0700 ++++ /Users/bramp/go/src/github.com/xwb1989/sqlparser//encodable_test.go 2017-10-18 18:06:33.000000000 -0700 +@@ -20,7 +20,7 @@ + "bytes" + "testing" + +- "vitess.io/vitess/go/sqltypes" ++ "github.com/xwb1989/sqlparser/dependency/sqltypes" + ) + + func TestEncodable(t *testing.T) { +Only in /Users/bramp/go/src/github.com/xwb1989/sqlparser//: github_test.go +diff -u /Users/bramp/go/src/vitess.io/vitess/go//vt/sqlparser/normalizer.go /Users/bramp/go/src/github.com/xwb1989/sqlparser//normalizer.go +--- /Users/bramp/go/src/vitess.io/vitess/go//vt/sqlparser/normalizer.go 2018-06-05 08:45:47.000000000 -0700 ++++ /Users/bramp/go/src/github.com/xwb1989/sqlparser//normalizer.go 2017-10-18 18:06:33.000000000 -0700 +@@ -19,9 +19,9 @@ + import ( + "fmt" + +- "vitess.io/vitess/go/sqltypes" ++ "github.com/xwb1989/sqlparser/dependency/sqltypes" + +- querypb "vitess.io/vitess/go/vt/proto/query" ++ "github.com/xwb1989/sqlparser/dependency/querypb" + ) + + // Normalize changes the statement to use bind values, and +diff -u /Users/bramp/go/src/vitess.io/vitess/go//vt/sqlparser/normalizer_test.go /Users/bramp/go/src/github.com/xwb1989/sqlparser//normalizer_test.go +--- /Users/bramp/go/src/vitess.io/vitess/go//vt/sqlparser/normalizer_test.go 2018-06-05 08:45:47.000000000 -0700 ++++ /Users/bramp/go/src/github.com/xwb1989/sqlparser//normalizer_test.go 2017-11-27 22:10:51.000000000 -0800 +@@ -21,8 +21,8 @@ + "reflect" + "testing" + +- "vitess.io/vitess/go/sqltypes" +- querypb "vitess.io/vitess/go/vt/proto/query" ++ "github.com/xwb1989/sqlparser/dependency/querypb" ++ "github.com/xwb1989/sqlparser/dependency/sqltypes" + ) + + func TestNormalize(t *testing.T) { +diff -u /Users/bramp/go/src/vitess.io/vitess/go//vt/sqlparser/parsed_query.go /Users/bramp/go/src/github.com/xwb1989/sqlparser//parsed_query.go +--- /Users/bramp/go/src/vitess.io/vitess/go//vt/sqlparser/parsed_query.go 2018-06-05 08:45:47.000000000 -0700 ++++ /Users/bramp/go/src/github.com/xwb1989/sqlparser//parsed_query.go 2017-10-22 13:30:37.000000000 -0700 +@@ -18,12 +18,10 @@ + + import ( + "bytes" +- "encoding/json" + "fmt" + +- "vitess.io/vitess/go/sqltypes" +- +- querypb "vitess.io/vitess/go/vt/proto/query" ++ "github.com/xwb1989/sqlparser/dependency/querypb" ++ "github.com/xwb1989/sqlparser/dependency/sqltypes" + ) + + // ParsedQuery represents a parsed query where +@@ -71,12 +69,6 @@ + return buf.Bytes(), nil + } + +-// MarshalJSON is a custom JSON marshaler for ParsedQuery. +-// Note that any queries longer that 512 bytes will be truncated. +-func (pq *ParsedQuery) MarshalJSON() ([]byte, error) { +- return json.Marshal(TruncateForUI(pq.Query)) +-} +- + // EncodeValue encodes one bind variable value into the query. + func EncodeValue(buf *bytes.Buffer, value *querypb.BindVariable) { + if value.Type != querypb.Type_TUPLE { +diff -u /Users/bramp/go/src/vitess.io/vitess/go//vt/sqlparser/parsed_query_test.go /Users/bramp/go/src/github.com/xwb1989/sqlparser//parsed_query_test.go +--- /Users/bramp/go/src/vitess.io/vitess/go//vt/sqlparser/parsed_query_test.go 2018-06-05 08:45:47.000000000 -0700 ++++ /Users/bramp/go/src/github.com/xwb1989/sqlparser//parsed_query_test.go 2017-10-18 18:06:33.000000000 -0700 +@@ -20,9 +20,9 @@ + "reflect" + "testing" + +- "vitess.io/vitess/go/sqltypes" ++ "github.com/xwb1989/sqlparser/dependency/sqltypes" + +- querypb "vitess.io/vitess/go/vt/proto/query" ++ "github.com/xwb1989/sqlparser/dependency/querypb" + ) + + func TestNewParsedQuery(t *testing.T) { +Only in /Users/bramp/go/src/github.com/xwb1989/sqlparser//: patches +Only in /Users/bramp/go/src/github.com/xwb1989/sqlparser//: quick +diff -u /Users/bramp/go/src/vitess.io/vitess/go//vt/sqlparser/redact_query.go /Users/bramp/go/src/github.com/xwb1989/sqlparser//redact_query.go +--- /Users/bramp/go/src/vitess.io/vitess/go//vt/sqlparser/redact_query.go 2018-06-05 08:45:47.000000000 -0700 ++++ /Users/bramp/go/src/github.com/xwb1989/sqlparser//redact_query.go 2018-06-06 07:42:56.000000000 -0700 +@@ -1,6 +1,6 @@ + package sqlparser + +-import querypb "vitess.io/vitess/go/vt/proto/query" ++import querypb "github.com/xwb1989/sqlparser/dependency/querypb" + + // RedactSQLQuery returns a sql string with the params stripped out for display + func RedactSQLQuery(sql string) (string, error) { +Only in /Users/bramp/go/src/github.com/xwb1989/sqlparser//: tests +diff -u /Users/bramp/go/src/vitess.io/vitess/go//vt/sqlparser/token.go /Users/bramp/go/src/github.com/xwb1989/sqlparser//token.go +--- /Users/bramp/go/src/vitess.io/vitess/go//vt/sqlparser/token.go 2018-06-05 08:45:47.000000000 -0700 ++++ /Users/bramp/go/src/github.com/xwb1989/sqlparser//token.go 2018-06-06 07:45:09.000000000 -0700 +@@ -22,8 +22,8 @@ + "fmt" + "io" + +- "vitess.io/vitess/go/bytes2" +- "vitess.io/vitess/go/sqltypes" ++ "github.com/xwb1989/sqlparser/dependency/bytes2" ++ "github.com/xwb1989/sqlparser/dependency/sqltypes" + ) + + const ( +Only in /Users/bramp/go/src/vitess.io/vitess/go//vt/sqlparser/: truncate_query.go +Only in /Users/bramp/go/src/github.com/xwb1989/sqlparser//: y.output diff --git a/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/patches/sqltypes.patch b/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/patches/sqltypes.patch new file mode 100644 index 00000000..215ba9d8 --- /dev/null +++ b/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/patches/sqltypes.patch @@ -0,0 +1,290 @@ +Only in /Users/bramp/go/src/vitess.io/vitess/go//sqltypes/: arithmetic.go +Only in /Users/bramp/go/src/vitess.io/vitess/go//sqltypes/: arithmetic_test.go +diff -u /Users/bramp/go/src/vitess.io/vitess/go//sqltypes/bind_variables.go /Users/bramp/go/src/github.com/xwb1989/sqlparser//dependency/sqltypes/bind_variables.go +--- /Users/bramp/go/src/vitess.io/vitess/go//sqltypes/bind_variables.go 2018-06-05 08:45:47.000000000 -0700 ++++ /Users/bramp/go/src/github.com/xwb1989/sqlparser//dependency/sqltypes/bind_variables.go 2018-06-04 08:05:24.000000000 -0700 +@@ -19,11 +19,10 @@ + import ( + "errors" + "fmt" ++ "reflect" + "strconv" + +- "github.com/golang/protobuf/proto" +- +- querypb "vitess.io/vitess/go/vt/proto/query" ++ "github.com/xwb1989/sqlparser/dependency/querypb" + ) + + // NullBindVariable is a bindvar with NULL value. +@@ -253,9 +252,8 @@ + } + + // BindVariablesEqual compares two maps of bind variables. +-// For protobuf messages we have to use "proto.Equal". + func BindVariablesEqual(x, y map[string]*querypb.BindVariable) bool { +- return proto.Equal(&querypb.BoundQuery{BindVariables: x}, &querypb.BoundQuery{BindVariables: y}) ++ return reflect.DeepEqual(&querypb.BoundQuery{BindVariables: x}, &querypb.BoundQuery{BindVariables: y}) + } + + // CopyBindVariables returns a shallow-copy of the given bindVariables map. +diff -u /Users/bramp/go/src/vitess.io/vitess/go//sqltypes/bind_variables_test.go /Users/bramp/go/src/github.com/xwb1989/sqlparser//dependency/sqltypes/bind_variables_test.go +--- /Users/bramp/go/src/vitess.io/vitess/go//sqltypes/bind_variables_test.go 2018-06-05 08:45:47.000000000 -0700 ++++ /Users/bramp/go/src/github.com/xwb1989/sqlparser//dependency/sqltypes/bind_variables_test.go 2018-06-04 08:05:24.000000000 -0700 +@@ -21,16 +21,14 @@ + "strings" + "testing" + +- "github.com/golang/protobuf/proto" +- +- querypb "vitess.io/vitess/go/vt/proto/query" ++ "github.com/xwb1989/sqlparser/dependency/querypb" + ) + + func TestProtoConversions(t *testing.T) { + v := TestValue(Int64, "1") + got := ValueToProto(v) + want := &querypb.Value{Type: Int64, Value: []byte("1")} +- if !proto.Equal(got, want) { ++ if !reflect.DeepEqual(got, want) { + t.Errorf("ValueToProto: %v, want %v", got, want) + } + gotback := ProtoToValue(got) +@@ -240,7 +238,7 @@ + t.Errorf("ToBindVar(%T(%v)) error: nil, want %s", tcase.in, tcase.in, tcase.err) + continue + } +- if !proto.Equal(bv, tcase.out) { ++ if !reflect.DeepEqual(bv, tcase.out) { + t.Errorf("ToBindVar(%T(%v)): %v, want %s", tcase.in, tcase.in, bv, tcase.out) + } + } +@@ -523,7 +521,7 @@ + v, err = BindVariableToValue(&querypb.BindVariable{Type: querypb.Type_TUPLE}) + wantErr := "cannot convert a TUPLE bind var into a value" + if err == nil || err.Error() != wantErr { +- t.Errorf(" BindVarToValue(TUPLE): (%v, %v), want %s", v, err, wantErr) ++ t.Errorf(" BindVarToValue(TUPLE): %v, want %s", err, wantErr) + } + } + +Only in /Users/bramp/go/src/vitess.io/vitess/go//sqltypes/: event_token.go +Only in /Users/bramp/go/src/vitess.io/vitess/go//sqltypes/: event_token_test.go +diff -u /Users/bramp/go/src/vitess.io/vitess/go//sqltypes/plan_value.go /Users/bramp/go/src/github.com/xwb1989/sqlparser//dependency/sqltypes/plan_value.go +--- /Users/bramp/go/src/vitess.io/vitess/go//sqltypes/plan_value.go 2018-06-05 08:45:47.000000000 -0700 ++++ /Users/bramp/go/src/github.com/xwb1989/sqlparser//dependency/sqltypes/plan_value.go 2018-06-04 08:05:24.000000000 -0700 +@@ -18,10 +18,10 @@ + + import ( + "encoding/json" ++ "errors" ++ "fmt" + +- querypb "vitess.io/vitess/go/vt/proto/query" +- vtrpcpb "vitess.io/vitess/go/vt/proto/vtrpc" +- "vitess.io/vitess/go/vt/vterrors" ++ "github.com/xwb1989/sqlparser/dependency/querypb" + ) + + // PlanValue represents a value or a list of values for +@@ -87,7 +87,7 @@ + case pv.ListKey != "" || pv.Values != nil: + // This code is unreachable because the parser does not allow + // multi-value constructs where a single value is expected. +- return NULL, vterrors.New(vtrpcpb.Code_INVALID_ARGUMENT, "a list was supplied where a single value was expected") ++ return NULL, errors.New("a list was supplied where a single value was expected") + } + return NULL, nil + } +@@ -95,10 +95,10 @@ + func (pv PlanValue) lookupValue(bindVars map[string]*querypb.BindVariable) (*querypb.BindVariable, error) { + bv, ok := bindVars[pv.Key] + if !ok { +- return nil, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "missing bind var %s", pv.Key) ++ return nil, fmt.Errorf("missing bind var %s", pv.Key) + } + if bv.Type == querypb.Type_TUPLE { +- return nil, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "TUPLE was supplied for single value bind var %s", pv.ListKey) ++ return nil, fmt.Errorf("TUPLE was supplied for single value bind var %s", pv.ListKey) + } + return bv, nil + } +@@ -129,16 +129,16 @@ + } + // This code is unreachable because the parser does not allow + // single value constructs where multiple values are expected. +- return nil, vterrors.New(vtrpcpb.Code_INVALID_ARGUMENT, "a single value was supplied where a list was expected") ++ return nil, errors.New("a single value was supplied where a list was expected") + } + + func (pv PlanValue) lookupList(bindVars map[string]*querypb.BindVariable) (*querypb.BindVariable, error) { + bv, ok := bindVars[pv.ListKey] + if !ok { +- return nil, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "missing bind var %s", pv.ListKey) ++ return nil, fmt.Errorf("missing bind var %s", pv.ListKey) + } + if bv.Type != querypb.Type_TUPLE { +- return nil, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "single value was supplied for TUPLE bind var %s", pv.ListKey) ++ return nil, fmt.Errorf("single value was supplied for TUPLE bind var %s", pv.ListKey) + } + return bv, nil + } +@@ -171,7 +171,7 @@ + case l: + return nil + default: +- return vterrors.New(vtrpcpb.Code_INVALID_ARGUMENT, "mismatch in number of column values") ++ return errors.New("mismatch in number of column values") + } + } + +@@ -221,7 +221,7 @@ + rows[i] = make([]Value, len(pvs)) + } + +- // Using j because we're resolving by columns. ++ // Using j becasue we're resolving by columns. + for j, pv := range pvs { + switch { + case pv.Key != "": +diff -u /Users/bramp/go/src/vitess.io/vitess/go//sqltypes/plan_value_test.go /Users/bramp/go/src/github.com/xwb1989/sqlparser//dependency/sqltypes/plan_value_test.go +--- /Users/bramp/go/src/vitess.io/vitess/go//sqltypes/plan_value_test.go 2018-06-05 08:45:47.000000000 -0700 ++++ /Users/bramp/go/src/github.com/xwb1989/sqlparser//dependency/sqltypes/plan_value_test.go 2018-06-04 08:05:24.000000000 -0700 +@@ -21,7 +21,7 @@ + "strings" + "testing" + +- querypb "vitess.io/vitess/go/vt/proto/query" ++ "github.com/xwb1989/sqlparser/dependency/querypb" + ) + + func TestPlanValueIsNull(t *testing.T) { +Only in /Users/bramp/go/src/vitess.io/vitess/go//sqltypes/: proto3.go +Only in /Users/bramp/go/src/vitess.io/vitess/go//sqltypes/: proto3_test.go +Only in /Users/bramp/go/src/vitess.io/vitess/go//sqltypes/: query_response.go +Only in /Users/bramp/go/src/vitess.io/vitess/go//sqltypes/: result.go +Only in /Users/bramp/go/src/vitess.io/vitess/go//sqltypes/: result_test.go +diff -u /Users/bramp/go/src/vitess.io/vitess/go//sqltypes/testing.go /Users/bramp/go/src/github.com/xwb1989/sqlparser//dependency/sqltypes/testing.go +--- /Users/bramp/go/src/vitess.io/vitess/go//sqltypes/testing.go 2018-06-05 08:45:47.000000000 -0700 ++++ /Users/bramp/go/src/github.com/xwb1989/sqlparser//dependency/sqltypes/testing.go 2018-06-04 08:06:27.000000000 -0700 +@@ -17,17 +17,14 @@ + package sqltypes + + import ( +- "bytes" +- "fmt" +- "strings" +- +- querypb "vitess.io/vitess/go/vt/proto/query" ++ querypb "github.com/xwb1989/sqlparser/dependency/querypb" + ) + + // Functions in this file should only be used for testing. + // This is an experiment to see if test code bloat can be + // reduced and readability improved. + ++/* + // MakeTestFields builds a []*querypb.Field for testing. + // fields := sqltypes.MakeTestFields( + // "a|b", +@@ -110,6 +107,7 @@ + } + return results + } ++*/ + + // TestBindVariable makes a *querypb.BindVariable from + // an interface{}.It panics on invalid input. +@@ -131,6 +129,7 @@ + return MakeTrusted(typ, []byte(val)) + } + ++/* + // PrintResults prints []*Results into a string. + // This function should only be used for testing. + func PrintResults(results []*Result) string { +@@ -152,3 +151,4 @@ + } + return splits + } ++*/ +diff -u /Users/bramp/go/src/vitess.io/vitess/go//sqltypes/type.go /Users/bramp/go/src/github.com/xwb1989/sqlparser//dependency/sqltypes/type.go +--- /Users/bramp/go/src/vitess.io/vitess/go//sqltypes/type.go 2018-06-05 08:45:47.000000000 -0700 ++++ /Users/bramp/go/src/github.com/xwb1989/sqlparser//dependency/sqltypes/type.go 2018-06-04 08:05:24.000000000 -0700 +@@ -19,7 +19,7 @@ + import ( + "fmt" + +- querypb "vitess.io/vitess/go/vt/proto/query" ++ "github.com/xwb1989/sqlparser/dependency/querypb" + ) + + // This file provides wrappers and support +diff -u /Users/bramp/go/src/vitess.io/vitess/go//sqltypes/type_test.go /Users/bramp/go/src/github.com/xwb1989/sqlparser//dependency/sqltypes/type_test.go +--- /Users/bramp/go/src/vitess.io/vitess/go//sqltypes/type_test.go 2018-06-05 08:45:47.000000000 -0700 ++++ /Users/bramp/go/src/github.com/xwb1989/sqlparser//dependency/sqltypes/type_test.go 2018-06-04 08:05:24.000000000 -0700 +@@ -19,7 +19,7 @@ + import ( + "testing" + +- querypb "vitess.io/vitess/go/vt/proto/query" ++ "github.com/xwb1989/sqlparser/dependency/querypb" + ) + + func TestTypeValues(t *testing.T) { +diff -u /Users/bramp/go/src/vitess.io/vitess/go//sqltypes/value.go /Users/bramp/go/src/github.com/xwb1989/sqlparser//dependency/sqltypes/value.go +--- /Users/bramp/go/src/vitess.io/vitess/go//sqltypes/value.go 2018-06-05 08:45:47.000000000 -0700 ++++ /Users/bramp/go/src/github.com/xwb1989/sqlparser//dependency/sqltypes/value.go 2018-06-04 08:05:24.000000000 -0700 +@@ -23,10 +23,10 @@ + "fmt" + "strconv" + +- "vitess.io/vitess/go/bytes2" +- "vitess.io/vitess/go/hack" ++ "github.com/xwb1989/sqlparser/dependency/bytes2" ++ "github.com/xwb1989/sqlparser/dependency/hack" + +- querypb "vitess.io/vitess/go/vt/proto/query" ++ "github.com/xwb1989/sqlparser/dependency/querypb" + ) + + var ( +@@ -48,7 +48,7 @@ + } + + // Value can store any SQL value. If the value represents +-// an integral type, the bytes are always stored as a canonical ++// an integral type, the bytes are always stored as a cannonical + // representation that matches how MySQL returns such values. + type Value struct { + typ querypb.Type +@@ -126,7 +126,7 @@ + return MakeTrusted(VarBinary, []byte(v)) + } + +-// NewIntegral builds an integral type from a string representation. ++// NewIntegral builds an integral type from a string representaion. + // The type will be Int64 or Uint64. Int64 will be preferred where possible. + func NewIntegral(val string) (n Value, err error) { + signed, err := strconv.ParseInt(val, 0, 64) +@@ -169,7 +169,7 @@ + return v.typ + } + +-// Raw returns the internal representation of the value. For newer types, ++// Raw returns the internal represenation of the value. For newer types, + // this may not match MySQL's representation. + func (v Value) Raw() []byte { + return v.val +diff -u /Users/bramp/go/src/vitess.io/vitess/go//sqltypes/value_test.go /Users/bramp/go/src/github.com/xwb1989/sqlparser//dependency/sqltypes/value_test.go +--- /Users/bramp/go/src/vitess.io/vitess/go//sqltypes/value_test.go 2018-06-05 08:45:47.000000000 -0700 ++++ /Users/bramp/go/src/github.com/xwb1989/sqlparser//dependency/sqltypes/value_test.go 2018-06-04 08:05:24.000000000 -0700 +@@ -22,7 +22,7 @@ + "strings" + "testing" + +- querypb "vitess.io/vitess/go/vt/proto/query" ++ "github.com/xwb1989/sqlparser/dependency/querypb" + ) + + const ( diff --git a/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/precedence_test.go b/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/precedence_test.go new file mode 100644 index 00000000..f6a1c93f --- /dev/null +++ b/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/precedence_test.go @@ -0,0 +1,112 @@ +/* +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 sqlparser + +import ( + "fmt" + "testing" +) + +func readable(node Expr) string { + switch node := node.(type) { + case *OrExpr: + return fmt.Sprintf("(%s or %s)", readable(node.Left), readable(node.Right)) + case *AndExpr: + return fmt.Sprintf("(%s and %s)", readable(node.Left), readable(node.Right)) + case *BinaryExpr: + return fmt.Sprintf("(%s %s %s)", readable(node.Left), node.Operator, readable(node.Right)) + case *IsExpr: + return fmt.Sprintf("(%s %s)", readable(node.Expr), node.Operator) + default: + return String(node) + } +} + +func TestAndOrPrecedence(t *testing.T) { + validSQL := []struct { + input string + output string + }{{ + input: "select * from a where a=b and c=d or e=f", + output: "((a = b and c = d) or e = f)", + }, { + input: "select * from a where a=b or c=d and e=f", + output: "(a = b or (c = d and e = f))", + }} + for _, tcase := range validSQL { + tree, err := Parse(tcase.input) + if err != nil { + t.Error(err) + continue + } + expr := readable(tree.(*Select).Where.Expr) + if expr != tcase.output { + t.Errorf("Parse: \n%s, want: \n%s", expr, tcase.output) + } + } +} + +func TestPlusStarPrecedence(t *testing.T) { + validSQL := []struct { + input string + output string + }{{ + input: "select 1+2*3 from a", + output: "(1 + (2 * 3))", + }, { + input: "select 1*2+3 from a", + output: "((1 * 2) + 3)", + }} + for _, tcase := range validSQL { + tree, err := Parse(tcase.input) + if err != nil { + t.Error(err) + continue + } + expr := readable(tree.(*Select).SelectExprs[0].(*AliasedExpr).Expr) + if expr != tcase.output { + t.Errorf("Parse: \n%s, want: \n%s", expr, tcase.output) + } + } +} + +func TestIsPrecedence(t *testing.T) { + validSQL := []struct { + input string + output string + }{{ + input: "select * from a where a+b is true", + output: "((a + b) is true)", + }, { + input: "select * from a where a=1 and b=2 is true", + output: "(a = 1 and (b = 2 is true))", + }, { + input: "select * from a where (a=1 and b=2) is true", + output: "((a = 1 and b = 2) is true)", + }} + for _, tcase := range validSQL { + tree, err := Parse(tcase.input) + if err != nil { + t.Error(err) + continue + } + expr := readable(tree.(*Select).Where.Expr) + if expr != tcase.output { + t.Errorf("Parse: \n%s, want: \n%s", expr, tcase.output) + } + } +} diff --git a/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/redact_query.go b/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/redact_query.go new file mode 100644 index 00000000..a50b9bcd --- /dev/null +++ b/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/redact_query.go @@ -0,0 +1,19 @@ +package sqlparser + +import querypb "github.com/xwb1989/sqlparser/dependency/querypb" + +// RedactSQLQuery returns a sql string with the params stripped out for display +func RedactSQLQuery(sql string) (string, error) { + bv := map[string]*querypb.BindVariable{} + sqlStripped, comments := SplitMarginComments(sql) + + stmt, err := Parse(sqlStripped) + if err != nil { + return "", err + } + + prefix := "redacted" + Normalize(stmt, bv, prefix) + + return comments.Leading + String(stmt) + comments.Trailing, nil +} diff --git a/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/redact_query_test.go b/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/redact_query_test.go new file mode 100644 index 00000000..553e6ee0 --- /dev/null +++ b/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/redact_query_test.go @@ -0,0 +1,17 @@ +package sqlparser + +import ( + "testing" +) + +func TestRedactSQLStatements(t *testing.T) { + sql := "select a,b,c from t where x = 1234 and y = 1234 and z = 'apple'" + redactedSQL, err := RedactSQLQuery(sql) + if err != nil { + t.Fatalf("redacting sql failed: %v", err) + } + + if redactedSQL != "select a, b, c from t where x = :redacted1 and y = :redacted1 and z = :redacted2" { + t.Fatalf("Unknown sql redaction: %v", redactedSQL) + } +} diff --git a/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/sql.go b/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/sql.go new file mode 100644 index 00000000..4c8f2657 --- /dev/null +++ b/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/sql.go @@ -0,0 +1,6136 @@ +//line sql.y:18 +package sqlparser + +import __yyfmt__ "fmt" + +//line sql.y:18 +func setParseTree(yylex interface{}, stmt Statement) { + yylex.(*Tokenizer).ParseTree = stmt +} + +func setAllowComments(yylex interface{}, allow bool) { + yylex.(*Tokenizer).AllowComments = allow +} + +func setDDL(yylex interface{}, ddl *DDL) { + yylex.(*Tokenizer).partialDDL = ddl +} + +func incNesting(yylex interface{}) bool { + yylex.(*Tokenizer).nesting++ + if yylex.(*Tokenizer).nesting == 200 { + return true + } + return false +} + +func decNesting(yylex interface{}) { + yylex.(*Tokenizer).nesting-- +} + +// forceEOF forces the lexer to end prematurely. Not all SQL statements +// are supported by the Parser, thus calling forceEOF will make the lexer +// return EOF early. +func forceEOF(yylex interface{}) { + yylex.(*Tokenizer).ForceEOF = true +} + +//line sql.y:53 +type yySymType struct { + yys int + empty struct{} + statement Statement + selStmt SelectStatement + ddl *DDL + ins *Insert + byt byte + bytes []byte + bytes2 [][]byte + str string + strs []string + selectExprs SelectExprs + selectExpr SelectExpr + columns Columns + partitions Partitions + colName *ColName + tableExprs TableExprs + tableExpr TableExpr + joinCondition JoinCondition + tableName TableName + tableNames TableNames + indexHints *IndexHints + expr Expr + exprs Exprs + boolVal BoolVal + colTuple ColTuple + values Values + valTuple ValTuple + subquery *Subquery + whens []*When + when *When + orderBy OrderBy + order *Order + limit *Limit + updateExprs UpdateExprs + setExprs SetExprs + updateExpr *UpdateExpr + setExpr *SetExpr + colIdent ColIdent + tableIdent TableIdent + convertType *ConvertType + aliasedTableName *AliasedTableExpr + TableSpec *TableSpec + columnType ColumnType + colKeyOpt ColumnKeyOption + optVal *SQLVal + LengthScaleOption LengthScaleOption + columnDefinition *ColumnDefinition + indexDefinition *IndexDefinition + indexInfo *IndexInfo + indexOption *IndexOption + indexOptions []*IndexOption + indexColumn *IndexColumn + indexColumns []*IndexColumn + partDefs []*PartitionDefinition + partDef *PartitionDefinition + partSpec *PartitionSpec + vindexParam VindexParam + vindexParams []VindexParam + showFilter *ShowFilter +} + +const LEX_ERROR = 57346 +const UNION = 57347 +const SELECT = 57348 +const STREAM = 57349 +const INSERT = 57350 +const UPDATE = 57351 +const DELETE = 57352 +const FROM = 57353 +const WHERE = 57354 +const GROUP = 57355 +const HAVING = 57356 +const ORDER = 57357 +const BY = 57358 +const LIMIT = 57359 +const OFFSET = 57360 +const FOR = 57361 +const ALL = 57362 +const DISTINCT = 57363 +const AS = 57364 +const EXISTS = 57365 +const ASC = 57366 +const DESC = 57367 +const INTO = 57368 +const DUPLICATE = 57369 +const KEY = 57370 +const DEFAULT = 57371 +const SET = 57372 +const LOCK = 57373 +const KEYS = 57374 +const VALUES = 57375 +const LAST_INSERT_ID = 57376 +const NEXT = 57377 +const VALUE = 57378 +const SHARE = 57379 +const MODE = 57380 +const SQL_NO_CACHE = 57381 +const SQL_CACHE = 57382 +const JOIN = 57383 +const STRAIGHT_JOIN = 57384 +const LEFT = 57385 +const RIGHT = 57386 +const INNER = 57387 +const OUTER = 57388 +const CROSS = 57389 +const NATURAL = 57390 +const USE = 57391 +const FORCE = 57392 +const ON = 57393 +const USING = 57394 +const ID = 57395 +const HEX = 57396 +const STRING = 57397 +const INTEGRAL = 57398 +const FLOAT = 57399 +const HEXNUM = 57400 +const VALUE_ARG = 57401 +const LIST_ARG = 57402 +const COMMENT = 57403 +const COMMENT_KEYWORD = 57404 +const BIT_LITERAL = 57405 +const NULL = 57406 +const TRUE = 57407 +const FALSE = 57408 +const OR = 57409 +const AND = 57410 +const NOT = 57411 +const BETWEEN = 57412 +const CASE = 57413 +const WHEN = 57414 +const THEN = 57415 +const ELSE = 57416 +const END = 57417 +const LE = 57418 +const GE = 57419 +const NE = 57420 +const NULL_SAFE_EQUAL = 57421 +const IS = 57422 +const LIKE = 57423 +const REGEXP = 57424 +const IN = 57425 +const SHIFT_LEFT = 57426 +const SHIFT_RIGHT = 57427 +const DIV = 57428 +const MOD = 57429 +const UNARY = 57430 +const COLLATE = 57431 +const BINARY = 57432 +const UNDERSCORE_BINARY = 57433 +const INTERVAL = 57434 +const JSON_EXTRACT_OP = 57435 +const JSON_UNQUOTE_EXTRACT_OP = 57436 +const CREATE = 57437 +const ALTER = 57438 +const DROP = 57439 +const RENAME = 57440 +const ANALYZE = 57441 +const ADD = 57442 +const SCHEMA = 57443 +const TABLE = 57444 +const INDEX = 57445 +const VIEW = 57446 +const TO = 57447 +const IGNORE = 57448 +const IF = 57449 +const UNIQUE = 57450 +const PRIMARY = 57451 +const COLUMN = 57452 +const CONSTRAINT = 57453 +const SPATIAL = 57454 +const FULLTEXT = 57455 +const FOREIGN = 57456 +const KEY_BLOCK_SIZE = 57457 +const SHOW = 57458 +const DESCRIBE = 57459 +const EXPLAIN = 57460 +const DATE = 57461 +const ESCAPE = 57462 +const REPAIR = 57463 +const OPTIMIZE = 57464 +const TRUNCATE = 57465 +const MAXVALUE = 57466 +const PARTITION = 57467 +const REORGANIZE = 57468 +const LESS = 57469 +const THAN = 57470 +const PROCEDURE = 57471 +const TRIGGER = 57472 +const VINDEX = 57473 +const VINDEXES = 57474 +const STATUS = 57475 +const VARIABLES = 57476 +const BEGIN = 57477 +const START = 57478 +const TRANSACTION = 57479 +const COMMIT = 57480 +const ROLLBACK = 57481 +const BIT = 57482 +const TINYINT = 57483 +const SMALLINT = 57484 +const MEDIUMINT = 57485 +const INT = 57486 +const INTEGER = 57487 +const BIGINT = 57488 +const INTNUM = 57489 +const REAL = 57490 +const DOUBLE = 57491 +const FLOAT_TYPE = 57492 +const DECIMAL = 57493 +const NUMERIC = 57494 +const TIME = 57495 +const TIMESTAMP = 57496 +const DATETIME = 57497 +const YEAR = 57498 +const CHAR = 57499 +const VARCHAR = 57500 +const BOOL = 57501 +const CHARACTER = 57502 +const VARBINARY = 57503 +const NCHAR = 57504 +const TEXT = 57505 +const TINYTEXT = 57506 +const MEDIUMTEXT = 57507 +const LONGTEXT = 57508 +const BLOB = 57509 +const TINYBLOB = 57510 +const MEDIUMBLOB = 57511 +const LONGBLOB = 57512 +const JSON = 57513 +const ENUM = 57514 +const GEOMETRY = 57515 +const POINT = 57516 +const LINESTRING = 57517 +const POLYGON = 57518 +const GEOMETRYCOLLECTION = 57519 +const MULTIPOINT = 57520 +const MULTILINESTRING = 57521 +const MULTIPOLYGON = 57522 +const NULLX = 57523 +const AUTO_INCREMENT = 57524 +const APPROXNUM = 57525 +const SIGNED = 57526 +const UNSIGNED = 57527 +const ZEROFILL = 57528 +const DATABASES = 57529 +const TABLES = 57530 +const VITESS_KEYSPACES = 57531 +const VITESS_SHARDS = 57532 +const VITESS_TABLETS = 57533 +const VSCHEMA_TABLES = 57534 +const EXTENDED = 57535 +const FULL = 57536 +const PROCESSLIST = 57537 +const NAMES = 57538 +const CHARSET = 57539 +const GLOBAL = 57540 +const SESSION = 57541 +const ISOLATION = 57542 +const LEVEL = 57543 +const READ = 57544 +const WRITE = 57545 +const ONLY = 57546 +const REPEATABLE = 57547 +const COMMITTED = 57548 +const UNCOMMITTED = 57549 +const SERIALIZABLE = 57550 +const CURRENT_TIMESTAMP = 57551 +const DATABASE = 57552 +const CURRENT_DATE = 57553 +const CURRENT_TIME = 57554 +const LOCALTIME = 57555 +const LOCALTIMESTAMP = 57556 +const UTC_DATE = 57557 +const UTC_TIME = 57558 +const UTC_TIMESTAMP = 57559 +const REPLACE = 57560 +const CONVERT = 57561 +const CAST = 57562 +const SUBSTR = 57563 +const SUBSTRING = 57564 +const GROUP_CONCAT = 57565 +const SEPARATOR = 57566 +const MATCH = 57567 +const AGAINST = 57568 +const BOOLEAN = 57569 +const LANGUAGE = 57570 +const WITH = 57571 +const QUERY = 57572 +const EXPANSION = 57573 +const UNUSED = 57574 + +var yyToknames = [...]string{ + "$end", + "error", + "$unk", + "LEX_ERROR", + "UNION", + "SELECT", + "STREAM", + "INSERT", + "UPDATE", + "DELETE", + "FROM", + "WHERE", + "GROUP", + "HAVING", + "ORDER", + "BY", + "LIMIT", + "OFFSET", + "FOR", + "ALL", + "DISTINCT", + "AS", + "EXISTS", + "ASC", + "DESC", + "INTO", + "DUPLICATE", + "KEY", + "DEFAULT", + "SET", + "LOCK", + "KEYS", + "VALUES", + "LAST_INSERT_ID", + "NEXT", + "VALUE", + "SHARE", + "MODE", + "SQL_NO_CACHE", + "SQL_CACHE", + "JOIN", + "STRAIGHT_JOIN", + "LEFT", + "RIGHT", + "INNER", + "OUTER", + "CROSS", + "NATURAL", + "USE", + "FORCE", + "ON", + "USING", + "'('", + "','", + "')'", + "ID", + "HEX", + "STRING", + "INTEGRAL", + "FLOAT", + "HEXNUM", + "VALUE_ARG", + "LIST_ARG", + "COMMENT", + "COMMENT_KEYWORD", + "BIT_LITERAL", + "NULL", + "TRUE", + "FALSE", + "OR", + "AND", + "NOT", + "'!'", + "BETWEEN", + "CASE", + "WHEN", + "THEN", + "ELSE", + "END", + "'='", + "'<'", + "'>'", + "LE", + "GE", + "NE", + "NULL_SAFE_EQUAL", + "IS", + "LIKE", + "REGEXP", + "IN", + "'|'", + "'&'", + "SHIFT_LEFT", + "SHIFT_RIGHT", + "'+'", + "'-'", + "'*'", + "'/'", + "DIV", + "'%'", + "MOD", + "'^'", + "'~'", + "UNARY", + "COLLATE", + "BINARY", + "UNDERSCORE_BINARY", + "INTERVAL", + "'.'", + "JSON_EXTRACT_OP", + "JSON_UNQUOTE_EXTRACT_OP", + "CREATE", + "ALTER", + "DROP", + "RENAME", + "ANALYZE", + "ADD", + "SCHEMA", + "TABLE", + "INDEX", + "VIEW", + "TO", + "IGNORE", + "IF", + "UNIQUE", + "PRIMARY", + "COLUMN", + "CONSTRAINT", + "SPATIAL", + "FULLTEXT", + "FOREIGN", + "KEY_BLOCK_SIZE", + "SHOW", + "DESCRIBE", + "EXPLAIN", + "DATE", + "ESCAPE", + "REPAIR", + "OPTIMIZE", + "TRUNCATE", + "MAXVALUE", + "PARTITION", + "REORGANIZE", + "LESS", + "THAN", + "PROCEDURE", + "TRIGGER", + "VINDEX", + "VINDEXES", + "STATUS", + "VARIABLES", + "BEGIN", + "START", + "TRANSACTION", + "COMMIT", + "ROLLBACK", + "BIT", + "TINYINT", + "SMALLINT", + "MEDIUMINT", + "INT", + "INTEGER", + "BIGINT", + "INTNUM", + "REAL", + "DOUBLE", + "FLOAT_TYPE", + "DECIMAL", + "NUMERIC", + "TIME", + "TIMESTAMP", + "DATETIME", + "YEAR", + "CHAR", + "VARCHAR", + "BOOL", + "CHARACTER", + "VARBINARY", + "NCHAR", + "TEXT", + "TINYTEXT", + "MEDIUMTEXT", + "LONGTEXT", + "BLOB", + "TINYBLOB", + "MEDIUMBLOB", + "LONGBLOB", + "JSON", + "ENUM", + "GEOMETRY", + "POINT", + "LINESTRING", + "POLYGON", + "GEOMETRYCOLLECTION", + "MULTIPOINT", + "MULTILINESTRING", + "MULTIPOLYGON", + "NULLX", + "AUTO_INCREMENT", + "APPROXNUM", + "SIGNED", + "UNSIGNED", + "ZEROFILL", + "DATABASES", + "TABLES", + "VITESS_KEYSPACES", + "VITESS_SHARDS", + "VITESS_TABLETS", + "VSCHEMA_TABLES", + "EXTENDED", + "FULL", + "PROCESSLIST", + "NAMES", + "CHARSET", + "GLOBAL", + "SESSION", + "ISOLATION", + "LEVEL", + "READ", + "WRITE", + "ONLY", + "REPEATABLE", + "COMMITTED", + "UNCOMMITTED", + "SERIALIZABLE", + "CURRENT_TIMESTAMP", + "DATABASE", + "CURRENT_DATE", + "CURRENT_TIME", + "LOCALTIME", + "LOCALTIMESTAMP", + "UTC_DATE", + "UTC_TIME", + "UTC_TIMESTAMP", + "REPLACE", + "CONVERT", + "CAST", + "SUBSTR", + "SUBSTRING", + "GROUP_CONCAT", + "SEPARATOR", + "MATCH", + "AGAINST", + "BOOLEAN", + "LANGUAGE", + "WITH", + "QUERY", + "EXPANSION", + "UNUSED", + "';'", +} +var yyStatenames = [...]string{} + +const yyEofCode = 1 +const yyErrCode = 2 +const yyInitialStackSize = 16 + +//line yacctab:1 +var yyExca = [...]int{ + -1, 1, + 1, -1, + -2, 0, + -1, 3, + 5, 27, + -2, 4, + -1, 36, + 150, 263, + 151, 263, + -2, 253, + -1, 238, + 109, 587, + -2, 583, + -1, 239, + 109, 588, + -2, 584, + -1, 308, + 80, 746, + -2, 58, + -1, 309, + 80, 707, + -2, 59, + -1, 314, + 80, 691, + -2, 549, + -1, 316, + 80, 728, + -2, 551, + -1, 575, + 52, 41, + 54, 41, + -2, 43, + -1, 708, + 109, 590, + -2, 586, + -1, 912, + 5, 28, + -2, 395, + -1, 937, + 5, 27, + -2, 524, + -1, 1161, + 5, 28, + -2, 525, + -1, 1205, + 5, 27, + -2, 527, + -1, 1267, + 5, 28, + -2, 528, +} + +const yyPrivate = 57344 + +const yyLast = 10949 + +var yyAct = [...]int{ + + 269, 47, 770, 854, 1258, 522, 646, 1069, 1216, 1097, + 810, 1070, 268, 521, 3, 243, 1167, 834, 998, 788, + 806, 217, 569, 1066, 809, 53, 848, 771, 956, 1043, + 743, 567, 313, 904, 989, 945, 211, 410, 585, 710, + 455, 940, 733, 1001, 820, 740, 461, 584, 47, 844, + 307, 556, 571, 767, 294, 759, 222, 467, 475, 886, + 241, 216, 299, 226, 52, 304, 1287, 1277, 1285, 1265, + 302, 1283, 855, 442, 1276, 1061, 1155, 414, 435, 1225, + 212, 213, 214, 215, 295, 871, 1103, 1104, 1105, 1091, + 230, 1092, 1093, 293, 1108, 1106, 586, 1264, 587, 870, + 181, 177, 178, 179, 57, 536, 1240, 488, 487, 497, + 498, 490, 491, 492, 493, 494, 495, 496, 489, 964, + 801, 499, 963, 802, 803, 965, 875, 245, 450, 59, + 60, 61, 62, 63, 980, 869, 827, 310, 675, 1179, + 423, 437, 1194, 439, 835, 676, 1144, 1142, 210, 1284, + 232, 446, 447, 1282, 1259, 1022, 768, 424, 417, 1217, + 1044, 1223, 174, 175, 175, 822, 654, 239, 436, 438, + 420, 645, 1219, 822, 789, 791, 955, 954, 953, 412, + 189, 176, 1245, 866, 863, 864, 1164, 862, 1030, 298, + 1046, 511, 512, 974, 441, 441, 441, 441, 76, 441, + 920, 1019, 186, 898, 682, 186, 441, 1021, 479, 180, + 430, 1112, 873, 876, 489, 807, 822, 499, 499, 881, + 679, 1026, 1048, 47, 1052, 742, 1047, 472, 1045, 186, + 186, 76, 1009, 1050, 474, 186, 464, 76, 508, 1218, + 1250, 510, 1049, 474, 411, 1122, 463, 868, 790, 434, + 473, 472, 943, 588, 1107, 1051, 1053, 821, 1224, 1222, + 1007, 1113, 1241, 835, 828, 821, 1063, 474, 520, 867, + 524, 525, 526, 527, 528, 529, 530, 531, 532, 760, + 535, 537, 537, 537, 537, 537, 537, 537, 537, 545, + 546, 547, 548, 1263, 760, 649, 927, 1025, 882, 1020, + 568, 1018, 685, 686, 1253, 978, 872, 469, 821, 416, + 1009, 717, 236, 819, 817, 1269, 1185, 818, 1184, 874, + 426, 427, 428, 453, 1008, 715, 716, 714, 465, 1013, + 1010, 1003, 1004, 1011, 1006, 1005, 993, 50, 1007, 992, + 824, 916, 186, 915, 186, 825, 1012, 713, 473, 472, + 186, 981, 1015, 700, 702, 703, 917, 186, 701, 473, + 472, 76, 76, 76, 76, 474, 76, 173, 509, 458, + 462, 582, 576, 76, 1270, 1251, 474, 473, 472, 310, + 1201, 418, 419, 734, 1065, 735, 480, 538, 539, 540, + 541, 542, 543, 544, 474, 895, 896, 897, 1182, 1130, + 76, 990, 1008, 1248, 473, 472, 1100, 1013, 1010, 1003, + 1004, 1011, 1006, 1005, 441, 1273, 454, 1209, 1256, 454, + 523, 474, 441, 1099, 1012, 1209, 454, 298, 292, 534, + 1002, 1209, 1210, 441, 441, 441, 441, 441, 441, 441, + 441, 1176, 1175, 1088, 454, 1163, 454, 441, 441, 487, + 497, 498, 490, 491, 492, 493, 494, 495, 496, 489, + 186, 1229, 499, 663, 1119, 1118, 267, 186, 186, 186, + 1115, 1116, 1228, 76, 1115, 1114, 1151, 454, 1109, 76, + 910, 454, 50, 975, 966, 687, 857, 553, 454, 941, + 661, 745, 454, 21, 736, 711, 660, 74, 497, 498, + 490, 491, 492, 493, 494, 495, 496, 489, 659, 650, + 499, 47, 708, 488, 487, 497, 498, 490, 491, 492, + 493, 494, 495, 496, 489, 524, 648, 499, 643, 689, + 312, 595, 594, 942, 432, 704, 415, 425, 747, 706, + 411, 1067, 579, 681, 941, 752, 755, 54, 745, 221, + 23, 761, 1159, 707, 299, 299, 299, 299, 299, 513, + 514, 515, 516, 517, 518, 519, 23, 553, 772, 568, + 1121, 792, 737, 738, 935, 553, 942, 936, 299, 680, + 1117, 76, 747, 580, 967, 578, 910, 186, 186, 76, + 757, 186, 764, 1204, 186, 473, 472, 50, 186, 23, + 76, 76, 76, 76, 76, 76, 76, 76, 773, 796, + 712, 776, 474, 50, 76, 76, 785, 552, 941, 186, + 795, 1033, 578, 697, 698, 793, 836, 837, 838, 794, + 922, 799, 798, 814, 76, 800, 910, 919, 186, 774, + 775, 553, 777, 581, 76, 683, 50, 1189, 829, 441, + 849, 441, 1082, 223, 970, 310, 946, 947, 647, 441, + 312, 312, 312, 312, 910, 312, 845, 840, 811, 850, + 839, 65, 312, 921, 852, 523, 1102, 952, 750, 751, + 918, 298, 298, 298, 298, 298, 1067, 76, 994, 846, + 847, 558, 561, 562, 563, 559, 298, 560, 564, 477, + 50, 946, 947, 949, 657, 298, 451, 695, 899, 492, + 493, 494, 495, 496, 489, 708, 951, 499, 186, 779, + 778, 186, 186, 186, 186, 186, 782, 711, 888, 780, + 887, 783, 883, 186, 781, 784, 186, 562, 563, 805, + 186, 227, 228, 1281, 1275, 186, 186, 1029, 1280, 76, + 468, 748, 749, 893, 900, 892, 707, 756, 456, 1157, + 985, 593, 76, 433, 466, 977, 1255, 1190, 938, 939, + 457, 763, 312, 765, 766, 1254, 1202, 971, 590, 859, + 656, 937, 258, 257, 260, 261, 262, 263, 688, 566, + 468, 259, 264, 218, 709, 1234, 299, 718, 719, 720, + 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, + 731, 732, 950, 186, 926, 219, 76, 54, 76, 1233, + 968, 891, 186, 224, 225, 186, 76, 959, 1192, 890, + 942, 884, 885, 470, 462, 1242, 958, 1180, 960, 961, + 678, 56, 712, 58, 577, 744, 746, 51, 982, 983, + 1, 856, 997, 865, 441, 984, 1257, 986, 987, 988, + 1215, 762, 1096, 972, 973, 816, 808, 409, 830, 831, + 832, 833, 64, 1249, 815, 991, 1221, 1178, 823, 441, + 312, 979, 826, 811, 841, 842, 843, 1101, 312, 1252, + 976, 787, 600, 598, 599, 597, 911, 602, 1000, 312, + 312, 312, 312, 312, 312, 312, 312, 1014, 601, 596, + 197, 928, 305, 312, 312, 558, 561, 562, 563, 559, + 894, 560, 564, 298, 565, 589, 851, 471, 66, 999, + 1017, 1016, 861, 691, 1024, 1037, 674, 1072, 1068, 47, + 880, 1042, 449, 477, 199, 1036, 312, 1055, 507, 1071, + 1062, 772, 1073, 708, 1084, 1085, 1086, 772, 889, 1054, + 76, 962, 311, 186, 1074, 684, 1077, 909, 1076, 1078, + 460, 1232, 1035, 1191, 925, 533, 758, 76, 244, 699, + 1095, 256, 253, 924, 1089, 255, 739, 254, 690, 934, + 481, 242, 1094, 234, 1058, 297, 753, 753, 549, 557, + 555, 1090, 753, 1110, 1111, 490, 491, 492, 493, 494, + 495, 496, 489, 554, 948, 499, 944, 296, 1032, 753, + 76, 76, 1154, 76, 1239, 694, 25, 55, 901, 902, + 903, 229, 19, 18, 299, 17, 20, 16, 1123, 15, + 14, 811, 29, 811, 13, 12, 76, 11, 312, 186, + 186, 1125, 10, 9, 1128, 8, 7, 186, 6, 5, + 907, 312, 1153, 4, 908, 1133, 76, 220, 22, 2, + 0, 912, 913, 914, 1132, 1140, 0, 0, 1064, 0, + 923, 0, 0, 0, 0, 929, 0, 930, 931, 932, + 933, 0, 1158, 1079, 1080, 0, 0, 1081, 0, 1166, + 1083, 1169, 1170, 1171, 1035, 968, 76, 76, 0, 0, + 1172, 1174, 0, 0, 0, 312, 0, 312, 0, 0, + 0, 441, 0, 0, 0, 312, 0, 0, 0, 0, + 0, 0, 1181, 1188, 1183, 76, 0, 76, 76, 0, + 1187, 0, 0, 0, 0, 0, 0, 0, 0, 312, + 0, 0, 0, 0, 0, 0, 1193, 0, 0, 0, + 1072, 298, 186, 1206, 0, 0, 0, 0, 811, 0, + 76, 1203, 1071, 0, 0, 0, 1205, 1131, 0, 0, + 0, 0, 0, 76, 186, 0, 1220, 0, 0, 0, + 76, 1231, 1214, 0, 0, 999, 811, 0, 76, 0, + 0, 186, 1226, 0, 1227, 1072, 1230, 47, 0, 0, + 0, 0, 1243, 0, 0, 0, 1156, 1071, 1039, 1040, + 1244, 0, 0, 523, 1247, 0, 0, 0, 0, 0, + 0, 1056, 1057, 1041, 1059, 1060, 0, 0, 0, 459, + 1261, 0, 0, 0, 0, 1266, 0, 440, 0, 0, + 76, 0, 76, 76, 76, 186, 76, 0, 772, 957, + 0, 0, 76, 1271, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 184, 1278, 312, 209, 1279, 0, + 1087, 0, 0, 0, 0, 1286, 0, 0, 76, 76, + 76, 0, 0, 300, 0, 0, 0, 0, 0, 233, + 0, 184, 184, 0, 0, 0, 0, 184, 0, 1137, + 1138, 0, 1139, 0, 0, 1141, 0, 1143, 0, 995, + 312, 0, 312, 0, 0, 0, 0, 0, 183, 0, + 0, 76, 76, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 76, 312, 0, 0, 0, 0, + 0, 1135, 0, 0, 0, 0, 303, 76, 0, 0, + 1134, 413, 0, 1177, 0, 312, 0, 1136, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 76, 1145, 1146, + 1147, 0, 0, 1150, 1260, 523, 0, 312, 0, 0, + 0, 0, 0, 0, 0, 0, 1160, 1161, 1162, 195, + 1165, 0, 753, 0, 0, 1075, 957, 0, 753, 0, + 0, 0, 0, 76, 184, 0, 184, 0, 0, 0, + 0, 0, 184, 205, 0, 0, 0, 76, 0, 184, + 0, 0, 0, 0, 312, 0, 312, 1098, 0, 0, + 0, 0, 443, 444, 445, 0, 448, 0, 0, 0, + 0, 0, 0, 452, 0, 0, 0, 0, 0, 0, + 0, 1195, 1196, 0, 1197, 1198, 1199, 0, 421, 1124, + 422, 0, 0, 190, 0, 0, 429, 0, 1200, 192, + 0, 0, 1126, 431, 0, 0, 198, 194, 0, 1129, + 0, 0, 0, 1211, 1212, 1213, 0, 312, 0, 0, + 488, 487, 497, 498, 490, 491, 492, 493, 494, 495, + 496, 489, 0, 196, 499, 0, 200, 0, 0, 1235, + 1236, 1237, 1238, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 184, 0, 0, 0, 0, 0, 0, 184, + 573, 184, 0, 0, 191, 0, 905, 0, 0, 1168, + 0, 1168, 1168, 1168, 0, 1173, 0, 0, 0, 0, + 0, 312, 0, 1262, 454, 0, 0, 0, 1267, 0, + 0, 193, 1152, 201, 202, 203, 204, 208, 1148, 454, + 0, 1272, 207, 206, 0, 0, 551, 312, 312, 312, + 0, 0, 0, 0, 0, 575, 0, 0, 0, 1288, + 488, 487, 497, 498, 490, 491, 492, 493, 494, 495, + 496, 489, 1290, 1291, 499, 488, 487, 497, 498, 490, + 491, 492, 493, 494, 495, 496, 489, 0, 0, 499, + 1207, 1208, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1098, 488, 487, 497, 498, 490, 491, + 492, 493, 494, 495, 496, 489, 1168, 0, 499, 184, + 184, 644, 0, 184, 0, 0, 184, 0, 0, 653, + 662, 0, 0, 0, 0, 0, 1246, 1038, 0, 0, + 664, 665, 666, 667, 668, 669, 670, 671, 0, 0, + 0, 184, 0, 0, 672, 673, 0, 488, 487, 497, + 498, 490, 491, 492, 493, 494, 495, 496, 489, 753, + 184, 499, 1268, 651, 652, 0, 0, 655, 0, 662, + 658, 0, 0, 0, 0, 0, 1274, 0, 0, 23, + 24, 48, 26, 27, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 677, 0, 1149, 42, 0, + 0, 0, 0, 28, 0, 0, 0, 0, 0, 0, + 233, 0, 0, 0, 696, 233, 233, 0, 0, 754, + 754, 233, 37, 0, 0, 754, 50, 0, 0, 0, + 0, 0, 0, 0, 0, 233, 233, 233, 233, 0, + 184, 0, 754, 184, 184, 184, 184, 184, 0, 0, + 0, 0, 0, 0, 0, 786, 0, 0, 184, 0, + 0, 0, 573, 0, 0, 0, 0, 184, 184, 488, + 487, 497, 498, 490, 491, 492, 493, 494, 495, 496, + 489, 0, 0, 499, 0, 30, 31, 33, 32, 35, + 0, 0, 0, 0, 769, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 36, 43, 44, 0, + 0, 45, 46, 34, 0, 0, 0, 0, 0, 0, + 0, 0, 797, 0, 0, 38, 39, 0, 40, 41, + 0, 0, 0, 0, 0, 184, 617, 0, 0, 0, + 0, 483, 0, 486, 184, 0, 858, 184, 860, 500, + 501, 502, 503, 504, 505, 506, 879, 484, 485, 482, + 488, 487, 497, 498, 490, 491, 492, 493, 494, 495, + 496, 489, 662, 0, 499, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 233, 0, 0, 0, 0, 853, + 0, 0, 0, 906, 0, 0, 0, 0, 877, 0, + 0, 878, 0, 0, 0, 0, 0, 0, 49, 0, + 0, 0, 605, 488, 487, 497, 498, 490, 491, 492, + 493, 494, 495, 496, 489, 0, 0, 499, 0, 0, + 0, 233, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 618, 0, 0, 0, 0, 233, 488, 487, + 497, 498, 490, 491, 492, 493, 494, 495, 496, 489, + 0, 0, 499, 631, 632, 633, 634, 635, 636, 637, + 0, 638, 639, 640, 641, 642, 619, 620, 621, 622, + 603, 604, 0, 0, 606, 184, 607, 608, 609, 610, + 611, 612, 613, 614, 615, 616, 623, 624, 625, 626, + 627, 628, 629, 630, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 996, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1027, 1028, 0, 0, 0, 1023, 0, 0, 184, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 233, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 233, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 662, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 754, 0, 0, 0, 0, + 0, 754, 0, 1031, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 184, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 184, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 184, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1120, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1127, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 573, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1186, 0, + 0, 398, 388, 0, 360, 400, 338, 352, 408, 353, + 354, 381, 324, 368, 125, 350, 0, 341, 319, 347, + 320, 339, 362, 93, 365, 337, 390, 371, 107, 406, + 109, 376, 0, 142, 118, 0, 0, 364, 392, 366, + 386, 359, 382, 329, 375, 401, 351, 379, 402, 0, + 0, 0, 75, 0, 812, 813, 0, 0, 0, 0, + 0, 86, 0, 378, 397, 349, 380, 318, 377, 0, + 322, 325, 407, 395, 344, 345, 969, 0, 0, 0, + 0, 0, 0, 363, 367, 383, 357, 0, 0, 0, + 0, 0, 0, 0, 0, 342, 0, 374, 0, 0, + 0, 326, 323, 0, 361, 0, 0, 0, 328, 0, + 343, 384, 754, 317, 387, 393, 358, 187, 396, 356, + 355, 399, 131, 0, 0, 145, 98, 97, 106, 391, + 340, 348, 89, 346, 137, 127, 157, 373, 128, 136, + 110, 149, 132, 156, 188, 164, 147, 163, 78, 146, + 155, 87, 139, 80, 153, 144, 116, 102, 103, 79, + 0, 135, 92, 96, 91, 124, 150, 151, 90, 171, + 83, 162, 82, 84, 161, 123, 148, 154, 117, 114, + 81, 152, 115, 113, 105, 94, 99, 129, 112, 130, + 100, 120, 119, 121, 0, 321, 0, 143, 159, 172, + 336, 394, 165, 166, 167, 168, 0, 0, 0, 122, + 85, 101, 140, 104, 111, 134, 170, 126, 138, 88, + 158, 141, 332, 335, 330, 331, 369, 370, 403, 404, + 405, 385, 327, 0, 333, 334, 0, 389, 372, 77, + 0, 108, 169, 133, 95, 160, 398, 388, 0, 360, + 400, 338, 352, 408, 353, 354, 381, 324, 368, 125, + 350, 0, 341, 319, 347, 320, 339, 362, 93, 365, + 337, 390, 371, 107, 406, 109, 376, 0, 142, 118, + 0, 0, 364, 392, 366, 386, 359, 382, 329, 375, + 401, 351, 379, 402, 0, 0, 0, 75, 0, 812, + 813, 0, 0, 0, 0, 0, 86, 0, 378, 397, + 349, 380, 318, 377, 0, 322, 325, 407, 395, 344, + 345, 0, 0, 0, 0, 0, 0, 0, 363, 367, + 383, 357, 0, 0, 0, 0, 0, 0, 0, 0, + 342, 0, 374, 0, 0, 0, 326, 323, 0, 361, + 0, 0, 0, 328, 0, 343, 384, 0, 317, 387, + 393, 358, 187, 396, 356, 355, 399, 131, 0, 0, + 145, 98, 97, 106, 391, 340, 348, 89, 346, 137, + 127, 157, 373, 128, 136, 110, 149, 132, 156, 188, + 164, 147, 163, 78, 146, 155, 87, 139, 80, 153, + 144, 116, 102, 103, 79, 0, 135, 92, 96, 91, + 124, 150, 151, 90, 171, 83, 162, 82, 84, 161, + 123, 148, 154, 117, 114, 81, 152, 115, 113, 105, + 94, 99, 129, 112, 130, 100, 120, 119, 121, 0, + 321, 0, 143, 159, 172, 336, 394, 165, 166, 167, + 168, 0, 0, 0, 122, 85, 101, 140, 104, 111, + 134, 170, 126, 138, 88, 158, 141, 332, 335, 330, + 331, 369, 370, 403, 404, 405, 385, 327, 0, 333, + 334, 0, 389, 372, 77, 0, 108, 169, 133, 95, + 160, 398, 388, 0, 360, 400, 338, 352, 408, 353, + 354, 381, 324, 368, 125, 350, 0, 341, 319, 347, + 320, 339, 362, 93, 365, 337, 390, 371, 107, 406, + 109, 376, 0, 142, 118, 0, 0, 364, 392, 366, + 386, 359, 382, 329, 375, 401, 351, 379, 402, 50, + 0, 0, 75, 0, 0, 0, 0, 0, 0, 0, + 0, 86, 0, 378, 397, 349, 380, 318, 377, 0, + 322, 325, 407, 395, 344, 345, 0, 0, 0, 0, + 0, 0, 0, 363, 367, 383, 357, 0, 0, 0, + 0, 0, 0, 0, 0, 342, 0, 374, 0, 0, + 0, 326, 323, 0, 361, 0, 0, 0, 328, 0, + 343, 384, 0, 317, 387, 393, 358, 187, 396, 356, + 355, 399, 131, 0, 0, 145, 98, 97, 106, 391, + 340, 348, 89, 346, 137, 127, 157, 373, 128, 136, + 110, 149, 132, 156, 188, 164, 147, 163, 78, 146, + 155, 87, 139, 80, 153, 144, 116, 102, 103, 79, + 0, 135, 92, 96, 91, 124, 150, 151, 90, 171, + 83, 162, 82, 84, 161, 123, 148, 154, 117, 114, + 81, 152, 115, 113, 105, 94, 99, 129, 112, 130, + 100, 120, 119, 121, 0, 321, 0, 143, 159, 172, + 336, 394, 165, 166, 167, 168, 0, 0, 0, 122, + 85, 101, 140, 104, 111, 134, 170, 126, 138, 88, + 158, 141, 332, 335, 330, 331, 369, 370, 403, 404, + 405, 385, 327, 0, 333, 334, 0, 389, 372, 77, + 0, 108, 169, 133, 95, 160, 398, 388, 0, 360, + 400, 338, 352, 408, 353, 354, 381, 324, 368, 125, + 350, 0, 341, 319, 347, 320, 339, 362, 93, 365, + 337, 390, 371, 107, 406, 109, 376, 0, 142, 118, + 0, 0, 364, 392, 366, 386, 359, 382, 329, 375, + 401, 351, 379, 402, 0, 0, 0, 75, 0, 0, + 0, 0, 0, 0, 0, 0, 86, 0, 378, 397, + 349, 380, 318, 377, 0, 322, 325, 407, 395, 344, + 345, 0, 0, 0, 0, 0, 0, 0, 363, 367, + 383, 357, 0, 0, 0, 0, 0, 0, 1034, 0, + 342, 0, 374, 0, 0, 0, 326, 323, 0, 361, + 0, 0, 0, 328, 0, 343, 384, 0, 317, 387, + 393, 358, 187, 396, 356, 355, 399, 131, 0, 0, + 145, 98, 97, 106, 391, 340, 348, 89, 346, 137, + 127, 157, 373, 128, 136, 110, 149, 132, 156, 188, + 164, 147, 163, 78, 146, 155, 87, 139, 80, 153, + 144, 116, 102, 103, 79, 0, 135, 92, 96, 91, + 124, 150, 151, 90, 171, 83, 162, 82, 84, 161, + 123, 148, 154, 117, 114, 81, 152, 115, 113, 105, + 94, 99, 129, 112, 130, 100, 120, 119, 121, 0, + 321, 0, 143, 159, 172, 336, 394, 165, 166, 167, + 168, 0, 0, 0, 122, 85, 101, 140, 104, 111, + 134, 170, 126, 138, 88, 158, 141, 332, 335, 330, + 331, 369, 370, 403, 404, 405, 385, 327, 0, 333, + 334, 0, 389, 372, 77, 0, 108, 169, 133, 95, + 160, 398, 388, 0, 360, 400, 338, 352, 408, 353, + 354, 381, 324, 368, 125, 350, 0, 341, 319, 347, + 320, 339, 362, 93, 365, 337, 390, 371, 107, 406, + 109, 376, 0, 142, 118, 0, 0, 364, 392, 366, + 386, 359, 382, 329, 375, 401, 351, 379, 402, 0, + 0, 0, 238, 0, 0, 0, 0, 0, 0, 0, + 0, 86, 0, 378, 397, 349, 380, 318, 377, 0, + 322, 325, 407, 395, 344, 345, 0, 0, 0, 0, + 0, 0, 0, 363, 367, 383, 357, 0, 0, 0, + 0, 0, 0, 705, 0, 342, 0, 374, 0, 0, + 0, 326, 323, 0, 361, 0, 0, 0, 328, 0, + 343, 384, 0, 317, 387, 393, 358, 187, 396, 356, + 355, 399, 131, 0, 0, 145, 98, 97, 106, 391, + 340, 348, 89, 346, 137, 127, 157, 373, 128, 136, + 110, 149, 132, 156, 188, 164, 147, 163, 78, 146, + 155, 87, 139, 80, 153, 144, 116, 102, 103, 79, + 0, 135, 92, 96, 91, 124, 150, 151, 90, 171, + 83, 162, 82, 84, 161, 123, 148, 154, 117, 114, + 81, 152, 115, 113, 105, 94, 99, 129, 112, 130, + 100, 120, 119, 121, 0, 321, 0, 143, 159, 172, + 336, 394, 165, 166, 167, 168, 0, 0, 0, 122, + 85, 101, 140, 104, 111, 134, 170, 126, 138, 88, + 158, 141, 332, 335, 330, 331, 369, 370, 403, 404, + 405, 385, 327, 0, 333, 334, 0, 389, 372, 77, + 0, 108, 169, 133, 95, 160, 398, 388, 0, 360, + 400, 338, 352, 408, 353, 354, 381, 324, 368, 125, + 350, 0, 341, 319, 347, 320, 339, 362, 93, 365, + 337, 390, 371, 107, 406, 109, 376, 0, 142, 118, + 0, 0, 364, 392, 366, 386, 359, 382, 329, 375, + 401, 351, 379, 402, 0, 0, 0, 75, 0, 0, + 0, 0, 0, 0, 0, 0, 86, 0, 378, 397, + 349, 380, 318, 377, 0, 322, 325, 407, 395, 344, + 345, 0, 0, 0, 0, 0, 0, 0, 363, 367, + 383, 357, 0, 0, 0, 0, 0, 0, 0, 0, + 342, 0, 374, 0, 0, 0, 326, 323, 0, 361, + 0, 0, 0, 328, 0, 343, 384, 0, 317, 387, + 393, 358, 187, 396, 356, 355, 399, 131, 0, 0, + 145, 98, 97, 106, 391, 340, 348, 89, 346, 137, + 127, 157, 373, 128, 136, 110, 149, 132, 156, 188, + 164, 147, 163, 78, 146, 155, 87, 139, 80, 153, + 144, 116, 102, 103, 79, 0, 135, 92, 96, 91, + 124, 150, 151, 90, 171, 83, 162, 82, 84, 161, + 123, 148, 154, 117, 114, 81, 152, 115, 113, 105, + 94, 99, 129, 112, 130, 100, 120, 119, 121, 0, + 321, 0, 143, 159, 172, 336, 394, 165, 166, 167, + 168, 0, 0, 0, 122, 85, 101, 140, 104, 111, + 134, 170, 126, 138, 88, 158, 141, 332, 335, 330, + 331, 369, 370, 403, 404, 405, 385, 327, 0, 333, + 334, 0, 389, 372, 77, 0, 108, 169, 133, 95, + 160, 398, 388, 0, 360, 400, 338, 352, 408, 353, + 354, 381, 324, 368, 125, 350, 0, 341, 319, 347, + 320, 339, 362, 93, 365, 337, 390, 371, 107, 406, + 109, 376, 0, 142, 118, 0, 0, 364, 392, 366, + 386, 359, 382, 329, 375, 401, 351, 379, 402, 0, + 0, 0, 238, 0, 0, 0, 0, 0, 0, 0, + 0, 86, 0, 378, 397, 349, 380, 318, 377, 0, + 322, 325, 407, 395, 344, 345, 0, 0, 0, 0, + 0, 0, 0, 363, 367, 383, 357, 0, 0, 0, + 0, 0, 0, 0, 0, 342, 0, 374, 0, 0, + 0, 326, 323, 0, 361, 0, 0, 0, 328, 0, + 343, 384, 0, 317, 387, 393, 358, 187, 396, 356, + 355, 399, 131, 0, 0, 145, 98, 97, 106, 391, + 340, 348, 89, 346, 137, 127, 157, 373, 128, 136, + 110, 149, 132, 156, 188, 164, 147, 163, 78, 146, + 155, 87, 139, 80, 153, 144, 116, 102, 103, 79, + 0, 135, 92, 96, 91, 124, 150, 151, 90, 171, + 83, 162, 82, 84, 161, 123, 148, 154, 117, 114, + 81, 152, 115, 113, 105, 94, 99, 129, 112, 130, + 100, 120, 119, 121, 0, 321, 0, 143, 159, 172, + 336, 394, 165, 166, 167, 168, 0, 0, 0, 122, + 85, 101, 140, 104, 111, 134, 170, 126, 138, 88, + 158, 141, 332, 335, 330, 331, 369, 370, 403, 404, + 405, 385, 327, 0, 333, 334, 0, 389, 372, 77, + 0, 108, 169, 133, 95, 160, 398, 388, 0, 360, + 400, 338, 352, 408, 353, 354, 381, 324, 368, 125, + 350, 0, 341, 319, 347, 320, 339, 362, 93, 365, + 337, 390, 371, 107, 406, 109, 376, 0, 142, 118, + 0, 0, 364, 392, 366, 386, 359, 382, 329, 375, + 401, 351, 379, 402, 0, 0, 0, 75, 0, 0, + 0, 0, 0, 0, 0, 0, 86, 0, 378, 397, + 349, 380, 318, 377, 0, 322, 325, 407, 395, 344, + 345, 0, 0, 0, 0, 0, 0, 0, 363, 367, + 383, 357, 0, 0, 0, 0, 0, 0, 0, 0, + 342, 0, 374, 0, 0, 0, 326, 323, 0, 361, + 0, 0, 0, 328, 0, 343, 384, 0, 317, 387, + 393, 358, 187, 396, 356, 355, 399, 131, 0, 0, + 145, 98, 97, 106, 391, 340, 348, 89, 346, 137, + 127, 157, 373, 128, 136, 110, 149, 132, 156, 188, + 164, 147, 163, 78, 146, 155, 87, 139, 80, 153, + 144, 116, 102, 103, 79, 0, 135, 92, 96, 91, + 124, 150, 151, 90, 171, 83, 162, 82, 315, 161, + 123, 148, 154, 117, 114, 81, 152, 115, 113, 105, + 94, 99, 129, 112, 130, 100, 120, 119, 121, 0, + 321, 0, 143, 159, 172, 336, 394, 165, 166, 167, + 168, 0, 0, 0, 316, 314, 101, 140, 104, 111, + 134, 170, 126, 138, 88, 158, 141, 332, 335, 330, + 331, 369, 370, 403, 404, 405, 385, 327, 0, 333, + 334, 0, 389, 372, 77, 0, 108, 169, 133, 95, + 160, 398, 388, 0, 360, 400, 338, 352, 408, 353, + 354, 381, 324, 368, 125, 350, 0, 341, 319, 347, + 320, 339, 362, 93, 365, 337, 390, 371, 107, 406, + 109, 376, 0, 142, 118, 0, 0, 364, 392, 366, + 386, 359, 382, 329, 375, 401, 351, 379, 402, 0, + 0, 0, 185, 0, 0, 0, 0, 0, 0, 0, + 0, 86, 0, 378, 397, 349, 380, 318, 377, 0, + 322, 325, 407, 395, 344, 345, 0, 0, 0, 0, + 0, 0, 0, 363, 367, 383, 357, 0, 0, 0, + 0, 0, 0, 0, 0, 342, 0, 374, 0, 0, + 0, 326, 323, 0, 361, 0, 0, 0, 328, 0, + 343, 384, 0, 317, 387, 393, 358, 187, 396, 356, + 355, 399, 131, 0, 0, 145, 98, 97, 106, 391, + 340, 348, 89, 346, 137, 127, 157, 373, 128, 136, + 110, 149, 132, 156, 188, 164, 147, 163, 78, 146, + 155, 87, 139, 80, 153, 144, 116, 102, 103, 79, + 0, 135, 92, 96, 91, 124, 150, 151, 90, 171, + 83, 162, 82, 84, 161, 123, 148, 154, 117, 114, + 81, 152, 115, 113, 105, 94, 99, 129, 112, 130, + 100, 120, 119, 121, 0, 321, 0, 143, 159, 172, + 336, 394, 165, 166, 167, 168, 0, 0, 0, 122, + 85, 101, 140, 104, 111, 134, 170, 126, 138, 88, + 158, 141, 332, 335, 330, 331, 369, 370, 403, 404, + 405, 385, 327, 0, 333, 334, 0, 389, 372, 77, + 0, 108, 169, 133, 95, 160, 398, 388, 0, 360, + 400, 338, 352, 408, 353, 354, 381, 324, 368, 125, + 350, 0, 341, 319, 347, 320, 339, 362, 93, 365, + 337, 390, 371, 107, 406, 109, 376, 0, 142, 118, + 0, 0, 364, 392, 366, 386, 359, 382, 329, 375, + 401, 351, 379, 402, 0, 0, 0, 75, 0, 0, + 0, 0, 0, 0, 0, 0, 86, 0, 378, 397, + 349, 380, 318, 377, 0, 322, 325, 407, 395, 344, + 345, 0, 0, 0, 0, 0, 0, 0, 363, 367, + 383, 357, 0, 0, 0, 0, 0, 0, 0, 0, + 342, 0, 374, 0, 0, 0, 326, 323, 0, 361, + 0, 0, 0, 328, 0, 343, 384, 0, 317, 387, + 393, 358, 187, 396, 356, 355, 399, 131, 0, 0, + 145, 98, 97, 106, 391, 340, 348, 89, 346, 137, + 127, 157, 373, 128, 136, 110, 149, 132, 156, 188, + 164, 147, 163, 78, 146, 583, 87, 139, 80, 153, + 144, 116, 102, 103, 79, 0, 135, 92, 96, 91, + 124, 150, 151, 90, 171, 83, 162, 82, 315, 161, + 123, 148, 154, 117, 114, 81, 152, 115, 113, 105, + 94, 99, 129, 112, 130, 100, 120, 119, 121, 0, + 321, 0, 143, 159, 172, 336, 394, 165, 166, 167, + 168, 0, 0, 0, 316, 314, 101, 140, 104, 111, + 134, 170, 126, 138, 88, 158, 141, 332, 335, 330, + 331, 369, 370, 403, 404, 405, 385, 327, 0, 333, + 334, 0, 389, 372, 77, 0, 108, 169, 133, 95, + 160, 398, 388, 0, 360, 400, 338, 352, 408, 353, + 354, 381, 324, 368, 125, 350, 0, 341, 319, 347, + 320, 339, 362, 93, 365, 337, 390, 371, 107, 406, + 109, 376, 0, 142, 118, 0, 0, 364, 392, 366, + 386, 359, 382, 329, 375, 401, 351, 379, 402, 0, + 0, 0, 75, 0, 0, 0, 0, 0, 0, 0, + 0, 86, 0, 378, 397, 349, 380, 318, 377, 0, + 322, 325, 407, 395, 344, 345, 0, 0, 0, 0, + 0, 0, 0, 363, 367, 383, 357, 0, 0, 0, + 0, 0, 0, 0, 0, 342, 0, 374, 0, 0, + 0, 326, 323, 0, 361, 0, 0, 0, 328, 0, + 343, 384, 0, 317, 387, 393, 358, 187, 396, 356, + 355, 399, 131, 0, 0, 145, 98, 97, 106, 391, + 340, 348, 89, 346, 137, 127, 157, 373, 128, 136, + 110, 149, 132, 156, 188, 164, 147, 163, 78, 146, + 306, 87, 139, 80, 153, 144, 116, 102, 103, 79, + 0, 135, 92, 96, 91, 124, 150, 151, 90, 171, + 83, 162, 82, 315, 161, 123, 148, 154, 117, 114, + 81, 152, 115, 113, 105, 94, 99, 129, 112, 130, + 100, 120, 119, 121, 0, 321, 0, 143, 159, 172, + 336, 394, 165, 166, 167, 168, 0, 0, 0, 316, + 314, 309, 308, 104, 111, 134, 170, 126, 138, 88, + 158, 141, 332, 335, 330, 331, 369, 370, 403, 404, + 405, 385, 327, 0, 333, 334, 0, 389, 372, 77, + 0, 108, 169, 133, 95, 160, 125, 0, 0, 741, + 0, 240, 0, 0, 0, 93, 0, 237, 0, 0, + 107, 279, 109, 0, 0, 142, 118, 0, 0, 0, + 0, 270, 271, 0, 0, 0, 0, 0, 0, 0, + 0, 50, 0, 0, 238, 258, 257, 260, 261, 262, + 263, 0, 0, 86, 259, 264, 265, 266, 0, 0, + 235, 251, 0, 278, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 248, 249, 231, 0, 0, 0, 290, + 0, 250, 0, 0, 246, 247, 252, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 187, + 0, 0, 288, 0, 131, 0, 0, 145, 98, 97, + 106, 0, 0, 0, 89, 0, 137, 127, 157, 0, + 128, 136, 110, 149, 132, 156, 188, 164, 147, 163, + 78, 146, 155, 87, 139, 80, 153, 144, 116, 102, + 103, 79, 0, 135, 92, 96, 91, 124, 150, 151, + 90, 171, 83, 162, 82, 84, 161, 123, 148, 154, + 117, 114, 81, 152, 115, 113, 105, 94, 99, 129, + 112, 130, 100, 120, 119, 121, 0, 0, 0, 143, + 159, 172, 0, 0, 165, 166, 167, 168, 0, 0, + 0, 122, 85, 101, 140, 104, 111, 134, 170, 126, + 138, 88, 158, 141, 280, 289, 286, 287, 284, 285, + 283, 282, 281, 291, 272, 273, 274, 275, 277, 0, + 276, 77, 0, 108, 169, 133, 95, 160, 125, 0, + 0, 0, 0, 240, 0, 0, 0, 93, 0, 237, + 0, 0, 107, 279, 109, 0, 0, 142, 118, 0, + 0, 0, 0, 270, 271, 0, 0, 0, 0, 0, + 0, 0, 0, 50, 0, 454, 238, 258, 257, 260, + 261, 262, 263, 0, 0, 86, 259, 264, 265, 266, + 0, 0, 235, 251, 0, 278, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 248, 249, 0, 0, 0, + 0, 290, 0, 250, 0, 0, 246, 247, 252, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 187, 0, 0, 288, 0, 131, 0, 0, 145, + 98, 97, 106, 0, 0, 0, 89, 0, 137, 127, + 157, 0, 128, 136, 110, 149, 132, 156, 188, 164, + 147, 163, 78, 146, 155, 87, 139, 80, 153, 144, + 116, 102, 103, 79, 0, 135, 92, 96, 91, 124, + 150, 151, 90, 171, 83, 162, 82, 84, 161, 123, + 148, 154, 117, 114, 81, 152, 115, 113, 105, 94, + 99, 129, 112, 130, 100, 120, 119, 121, 0, 0, + 0, 143, 159, 172, 0, 0, 165, 166, 167, 168, + 0, 0, 0, 122, 85, 101, 140, 104, 111, 134, + 170, 126, 138, 88, 158, 141, 280, 289, 286, 287, + 284, 285, 283, 282, 281, 291, 272, 273, 274, 275, + 277, 0, 276, 77, 0, 108, 169, 133, 95, 160, + 125, 0, 0, 0, 0, 240, 0, 0, 0, 93, + 0, 237, 0, 0, 107, 279, 109, 0, 0, 142, + 118, 0, 0, 0, 0, 270, 271, 0, 0, 0, + 0, 0, 0, 0, 0, 50, 0, 0, 238, 258, + 257, 260, 261, 262, 263, 0, 0, 86, 259, 264, + 265, 266, 0, 0, 235, 251, 0, 278, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 248, 249, 231, + 0, 0, 0, 290, 0, 250, 0, 0, 246, 247, + 252, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 187, 0, 0, 288, 0, 131, 0, + 0, 145, 98, 97, 106, 0, 0, 0, 89, 0, + 137, 127, 157, 0, 128, 136, 110, 149, 132, 156, + 188, 164, 147, 163, 78, 146, 155, 87, 139, 80, + 153, 144, 116, 102, 103, 79, 0, 135, 92, 96, + 91, 124, 150, 151, 90, 171, 83, 162, 82, 84, + 161, 123, 148, 154, 117, 114, 81, 152, 115, 113, + 105, 94, 99, 129, 112, 130, 100, 120, 119, 121, + 0, 0, 0, 143, 159, 172, 0, 0, 165, 166, + 167, 168, 0, 0, 0, 122, 85, 101, 140, 104, + 111, 134, 170, 126, 138, 88, 158, 141, 280, 289, + 286, 287, 284, 285, 283, 282, 281, 291, 272, 273, + 274, 275, 277, 0, 276, 77, 0, 108, 169, 133, + 95, 160, 125, 0, 0, 0, 0, 240, 0, 0, + 0, 93, 0, 237, 0, 0, 107, 279, 109, 0, + 0, 142, 118, 0, 0, 0, 0, 270, 271, 0, + 0, 0, 0, 0, 0, 804, 0, 50, 0, 0, + 238, 258, 257, 260, 261, 262, 263, 0, 0, 86, + 259, 264, 265, 266, 0, 0, 235, 251, 0, 278, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 248, + 249, 0, 0, 0, 0, 290, 0, 250, 0, 0, + 246, 247, 252, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 187, 0, 0, 288, 0, + 131, 0, 0, 145, 98, 97, 106, 0, 0, 0, + 89, 0, 137, 127, 157, 0, 128, 136, 110, 149, + 132, 156, 188, 164, 147, 163, 78, 146, 155, 87, + 139, 80, 153, 144, 116, 102, 103, 79, 0, 135, + 92, 96, 91, 124, 150, 151, 90, 171, 83, 162, + 82, 84, 161, 123, 148, 154, 117, 114, 81, 152, + 115, 113, 105, 94, 99, 129, 112, 130, 100, 120, + 119, 121, 0, 0, 0, 143, 159, 172, 0, 0, + 165, 166, 167, 168, 0, 0, 0, 122, 85, 101, + 140, 104, 111, 134, 170, 126, 138, 88, 158, 141, + 280, 289, 286, 287, 284, 285, 283, 282, 281, 291, + 272, 273, 274, 275, 277, 23, 276, 77, 0, 108, + 169, 133, 95, 160, 0, 0, 0, 125, 0, 0, + 0, 0, 240, 0, 0, 0, 93, 0, 237, 0, + 0, 107, 279, 109, 0, 0, 142, 118, 0, 0, + 0, 0, 270, 271, 0, 0, 0, 0, 0, 0, + 0, 0, 50, 0, 0, 238, 258, 257, 260, 261, + 262, 263, 0, 0, 86, 259, 264, 265, 266, 0, + 0, 235, 251, 0, 278, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 248, 249, 0, 0, 0, 0, + 290, 0, 250, 0, 0, 246, 247, 252, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 187, 0, 0, 288, 0, 131, 0, 0, 145, 98, + 97, 106, 0, 0, 0, 89, 0, 137, 127, 157, + 0, 128, 136, 110, 149, 132, 156, 188, 164, 147, + 163, 78, 146, 155, 87, 139, 80, 153, 144, 116, + 102, 103, 79, 0, 135, 92, 96, 91, 124, 150, + 151, 90, 171, 83, 162, 82, 84, 161, 123, 148, + 154, 117, 114, 81, 152, 115, 113, 105, 94, 99, + 129, 112, 130, 100, 120, 119, 121, 0, 0, 0, + 143, 159, 172, 0, 0, 165, 166, 167, 168, 0, + 0, 0, 122, 85, 101, 140, 104, 111, 134, 170, + 126, 138, 88, 158, 141, 280, 289, 286, 287, 284, + 285, 283, 282, 281, 291, 272, 273, 274, 275, 277, + 0, 276, 77, 0, 108, 169, 133, 95, 160, 125, + 0, 0, 0, 0, 240, 0, 0, 0, 93, 0, + 237, 0, 0, 107, 279, 109, 0, 0, 142, 118, + 0, 0, 0, 0, 270, 271, 0, 0, 0, 0, + 0, 0, 0, 0, 50, 0, 0, 238, 258, 257, + 260, 261, 262, 263, 0, 0, 86, 259, 264, 265, + 266, 0, 0, 235, 251, 0, 278, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 248, 249, 0, 0, + 0, 0, 290, 0, 250, 0, 0, 246, 247, 252, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 187, 0, 0, 288, 0, 131, 0, 0, + 145, 98, 97, 106, 0, 0, 0, 89, 0, 137, + 127, 157, 0, 128, 136, 110, 149, 132, 156, 188, + 164, 147, 163, 78, 146, 155, 87, 139, 80, 153, + 144, 116, 102, 103, 79, 0, 135, 92, 96, 91, + 124, 150, 151, 90, 171, 83, 162, 82, 84, 161, + 123, 148, 154, 117, 114, 81, 152, 115, 113, 105, + 94, 99, 129, 112, 130, 100, 120, 119, 121, 0, + 0, 0, 143, 159, 172, 0, 0, 165, 166, 167, + 168, 0, 0, 0, 122, 85, 101, 140, 104, 111, + 134, 170, 126, 138, 88, 158, 141, 280, 289, 286, + 287, 284, 285, 283, 282, 281, 291, 272, 273, 274, + 275, 277, 125, 276, 77, 0, 108, 169, 133, 95, + 160, 93, 0, 0, 0, 0, 107, 279, 109, 0, + 0, 142, 118, 0, 0, 0, 0, 270, 271, 0, + 0, 0, 0, 0, 0, 0, 0, 50, 0, 0, + 238, 258, 257, 260, 261, 262, 263, 0, 0, 86, + 259, 264, 265, 266, 0, 0, 0, 251, 0, 278, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 248, + 249, 0, 0, 0, 0, 290, 0, 250, 0, 0, + 246, 247, 252, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 187, 0, 0, 288, 0, + 131, 0, 0, 145, 98, 97, 106, 0, 0, 0, + 89, 0, 137, 127, 157, 1289, 128, 136, 110, 149, + 132, 156, 188, 164, 147, 163, 78, 146, 155, 87, + 139, 80, 153, 144, 116, 102, 103, 79, 0, 135, + 92, 96, 91, 124, 150, 151, 90, 171, 83, 162, + 82, 84, 161, 123, 148, 154, 117, 114, 81, 152, + 115, 113, 105, 94, 99, 129, 112, 130, 100, 120, + 119, 121, 0, 0, 0, 143, 159, 172, 0, 0, + 165, 166, 167, 168, 0, 0, 0, 122, 85, 101, + 140, 104, 111, 134, 170, 126, 138, 88, 158, 141, + 280, 289, 286, 287, 284, 285, 283, 282, 281, 291, + 272, 273, 274, 275, 277, 125, 276, 77, 0, 108, + 169, 133, 95, 160, 93, 0, 0, 0, 0, 107, + 279, 109, 0, 0, 142, 118, 0, 0, 0, 0, + 270, 271, 0, 0, 0, 0, 0, 0, 0, 0, + 50, 0, 0, 238, 258, 257, 260, 261, 262, 263, + 0, 0, 86, 259, 264, 265, 266, 0, 0, 0, + 251, 0, 278, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 248, 249, 0, 0, 0, 0, 290, 0, + 250, 0, 0, 246, 247, 252, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 187, 0, + 0, 288, 0, 131, 0, 0, 145, 98, 97, 106, + 0, 0, 0, 89, 0, 137, 127, 157, 0, 128, + 136, 110, 149, 132, 156, 188, 164, 147, 163, 78, + 146, 155, 87, 139, 80, 153, 144, 116, 102, 103, + 79, 0, 135, 92, 96, 91, 124, 150, 151, 90, + 171, 83, 162, 82, 84, 161, 123, 148, 154, 117, + 114, 81, 152, 115, 113, 105, 94, 99, 129, 112, + 130, 100, 120, 119, 121, 0, 0, 0, 143, 159, + 172, 0, 0, 165, 166, 167, 168, 0, 0, 0, + 122, 85, 101, 140, 104, 111, 134, 170, 126, 138, + 88, 158, 141, 280, 289, 286, 287, 284, 285, 283, + 282, 281, 291, 272, 273, 274, 275, 277, 125, 276, + 77, 0, 108, 169, 133, 95, 160, 93, 0, 0, + 0, 0, 107, 0, 109, 0, 0, 142, 118, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 75, 0, 0, 0, + 0, 0, 0, 0, 0, 86, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 488, 487, 497, 498, 490, 491, 492, 493, 494, + 495, 496, 489, 0, 0, 499, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 187, 0, 0, 0, 0, 131, 0, 0, 145, + 98, 97, 106, 0, 0, 0, 89, 0, 137, 127, + 157, 0, 128, 136, 110, 149, 132, 156, 188, 164, + 147, 163, 78, 146, 155, 87, 139, 80, 153, 144, + 116, 102, 103, 79, 0, 135, 92, 96, 91, 124, + 150, 151, 90, 171, 83, 162, 82, 84, 161, 123, + 148, 154, 117, 114, 81, 152, 115, 113, 105, 94, + 99, 129, 112, 130, 100, 120, 119, 121, 0, 0, + 0, 143, 159, 172, 0, 0, 165, 166, 167, 168, + 0, 0, 0, 122, 85, 101, 140, 104, 111, 134, + 170, 126, 138, 88, 158, 141, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 77, 0, 108, 169, 133, 95, 160, + 125, 0, 0, 0, 476, 0, 0, 0, 0, 93, + 0, 0, 0, 0, 107, 0, 109, 0, 0, 142, + 118, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 75, 0, + 478, 0, 0, 0, 0, 0, 0, 86, 0, 0, + 0, 0, 473, 472, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 474, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 187, 0, 0, 0, 0, 131, 0, + 0, 145, 98, 97, 106, 0, 0, 0, 89, 0, + 137, 127, 157, 0, 128, 136, 110, 149, 132, 156, + 188, 164, 147, 163, 78, 146, 155, 87, 139, 80, + 153, 144, 116, 102, 103, 79, 0, 135, 92, 96, + 91, 124, 150, 151, 90, 171, 83, 162, 82, 84, + 161, 123, 148, 154, 117, 114, 81, 152, 115, 113, + 105, 94, 99, 129, 112, 130, 100, 120, 119, 121, + 0, 0, 0, 143, 159, 172, 0, 0, 165, 166, + 167, 168, 0, 0, 0, 122, 85, 101, 140, 104, + 111, 134, 170, 126, 138, 88, 158, 141, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 125, 0, 77, 0, 108, 169, 133, + 95, 160, 93, 0, 0, 0, 0, 107, 0, 109, + 0, 0, 142, 118, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 75, 0, 0, 0, 0, 0, 0, 0, 0, + 86, 0, 0, 0, 0, 68, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 71, 72, 0, 67, 0, 0, 0, + 73, 131, 0, 0, 145, 98, 97, 106, 0, 0, + 0, 89, 0, 137, 127, 157, 0, 128, 136, 110, + 149, 132, 156, 69, 164, 147, 163, 78, 146, 155, + 87, 139, 80, 153, 144, 116, 102, 103, 79, 0, + 135, 92, 96, 91, 124, 150, 151, 90, 171, 83, + 162, 82, 84, 161, 123, 148, 154, 117, 114, 81, + 152, 115, 113, 105, 94, 99, 129, 112, 130, 100, + 120, 119, 121, 0, 0, 0, 143, 159, 172, 0, + 0, 165, 166, 167, 168, 0, 0, 0, 122, 85, + 101, 140, 104, 111, 134, 170, 126, 138, 88, 158, + 141, 0, 70, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 77, 0, + 108, 169, 133, 95, 160, 125, 0, 0, 0, 572, + 0, 0, 0, 0, 93, 0, 0, 0, 0, 107, + 0, 109, 0, 0, 142, 118, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 185, 0, 574, 0, 0, 0, 0, + 0, 0, 86, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 187, 0, + 0, 0, 0, 131, 0, 0, 145, 98, 97, 106, + 0, 0, 0, 89, 0, 137, 127, 157, 0, 128, + 136, 110, 149, 132, 156, 188, 164, 147, 163, 78, + 146, 155, 87, 139, 80, 153, 144, 116, 102, 103, + 79, 0, 135, 92, 96, 91, 124, 150, 151, 90, + 171, 83, 162, 82, 84, 161, 123, 148, 154, 117, + 114, 81, 152, 115, 113, 105, 94, 99, 129, 112, + 130, 100, 120, 119, 121, 0, 0, 0, 143, 159, + 172, 0, 0, 165, 166, 167, 168, 0, 0, 0, + 122, 85, 101, 140, 104, 111, 134, 170, 126, 138, + 88, 158, 141, 0, 0, 0, 23, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 125, 0, + 77, 0, 108, 169, 133, 95, 160, 93, 0, 0, + 0, 0, 107, 0, 109, 0, 0, 142, 118, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 50, 0, 0, 75, 0, 0, 0, + 0, 0, 0, 0, 0, 86, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 187, 0, 0, 0, 0, 131, 0, 0, 145, + 98, 97, 106, 0, 0, 0, 89, 0, 137, 127, + 157, 0, 128, 136, 110, 149, 132, 156, 188, 164, + 147, 163, 78, 146, 155, 87, 139, 80, 153, 144, + 116, 102, 103, 79, 0, 135, 92, 96, 91, 124, + 150, 151, 90, 171, 83, 162, 82, 84, 161, 123, + 148, 154, 117, 114, 81, 152, 115, 113, 105, 94, + 99, 129, 112, 130, 100, 120, 119, 121, 0, 0, + 0, 143, 159, 172, 0, 0, 165, 166, 167, 168, + 0, 0, 0, 122, 85, 101, 140, 104, 111, 134, + 170, 126, 138, 88, 158, 141, 0, 0, 0, 23, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 125, 0, 77, 0, 108, 169, 133, 95, 160, + 93, 0, 0, 0, 0, 107, 0, 109, 0, 0, + 142, 118, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 50, 0, 0, 185, + 0, 0, 0, 0, 0, 0, 0, 0, 86, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 187, 0, 0, 0, 0, 131, + 0, 0, 145, 98, 97, 106, 0, 0, 0, 89, + 0, 137, 127, 157, 0, 128, 136, 110, 149, 132, + 156, 188, 164, 147, 163, 78, 146, 155, 87, 139, + 80, 153, 144, 116, 102, 103, 79, 0, 135, 92, + 96, 91, 124, 150, 151, 90, 171, 83, 162, 82, + 84, 161, 123, 148, 154, 117, 114, 81, 152, 115, + 113, 105, 94, 99, 129, 112, 130, 100, 120, 119, + 121, 0, 0, 0, 143, 159, 172, 0, 0, 165, + 166, 167, 168, 0, 0, 0, 122, 85, 101, 140, + 104, 111, 134, 170, 126, 138, 88, 158, 141, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 125, 0, 77, 0, 108, 169, + 133, 95, 160, 93, 0, 0, 0, 0, 107, 0, + 109, 0, 0, 142, 118, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 75, 0, 0, 692, 0, 0, 693, 0, + 0, 86, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 187, 0, 0, + 0, 0, 131, 0, 0, 145, 98, 97, 106, 0, + 0, 0, 89, 0, 137, 127, 157, 0, 128, 136, + 110, 149, 132, 156, 188, 164, 147, 163, 78, 146, + 155, 87, 139, 80, 153, 144, 116, 102, 103, 79, + 0, 135, 92, 96, 91, 124, 150, 151, 90, 171, + 83, 162, 82, 84, 161, 123, 148, 154, 117, 114, + 81, 152, 115, 113, 105, 94, 99, 129, 112, 130, + 100, 120, 119, 121, 0, 0, 0, 143, 159, 172, + 0, 0, 165, 166, 167, 168, 0, 0, 0, 122, + 85, 101, 140, 104, 111, 134, 170, 126, 138, 88, + 158, 141, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 125, 0, 77, + 0, 108, 169, 133, 95, 160, 93, 0, 592, 0, + 0, 107, 0, 109, 0, 0, 142, 118, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 75, 0, 591, 0, 0, + 0, 0, 0, 0, 86, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 187, 0, 0, 0, 0, 131, 0, 0, 145, 98, + 97, 106, 0, 0, 0, 89, 0, 137, 127, 157, + 0, 128, 136, 110, 149, 132, 156, 188, 164, 147, + 163, 78, 146, 155, 87, 139, 80, 153, 144, 116, + 102, 103, 79, 0, 135, 92, 96, 91, 124, 150, + 151, 90, 171, 83, 162, 82, 84, 161, 123, 148, + 154, 117, 114, 81, 152, 115, 113, 105, 94, 99, + 129, 112, 130, 100, 120, 119, 121, 0, 0, 0, + 143, 159, 172, 0, 0, 165, 166, 167, 168, 0, + 0, 0, 122, 85, 101, 140, 104, 111, 134, 170, + 126, 138, 88, 158, 141, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 77, 0, 108, 169, 133, 95, 160, 125, + 0, 0, 0, 572, 0, 0, 0, 0, 93, 0, + 0, 0, 0, 107, 0, 109, 0, 0, 142, 118, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 185, 0, 574, + 0, 0, 0, 0, 0, 0, 86, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 187, 0, 0, 0, 0, 131, 0, 0, + 145, 98, 97, 106, 0, 0, 0, 89, 0, 137, + 127, 157, 0, 570, 136, 110, 149, 132, 156, 188, + 164, 147, 163, 78, 146, 155, 87, 139, 80, 153, + 144, 116, 102, 103, 79, 0, 135, 92, 96, 91, + 124, 150, 151, 90, 171, 83, 162, 82, 84, 161, + 123, 148, 154, 117, 114, 81, 152, 115, 113, 105, + 94, 99, 129, 112, 130, 100, 120, 119, 121, 0, + 0, 0, 143, 159, 172, 0, 0, 165, 166, 167, + 168, 0, 0, 0, 122, 85, 101, 140, 104, 111, + 134, 170, 126, 138, 88, 158, 141, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 125, 0, 77, 0, 108, 169, 133, 95, + 160, 93, 0, 0, 0, 0, 107, 0, 109, 0, + 0, 142, 118, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 50, 0, 0, + 185, 0, 0, 0, 0, 0, 0, 0, 0, 86, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 187, 0, 0, 0, 0, + 131, 0, 0, 145, 98, 97, 106, 0, 0, 0, + 89, 0, 137, 127, 157, 0, 128, 136, 110, 149, + 132, 156, 188, 164, 147, 163, 78, 146, 155, 87, + 139, 80, 153, 144, 116, 102, 103, 79, 0, 135, + 92, 96, 91, 124, 150, 151, 90, 171, 83, 162, + 82, 84, 161, 123, 148, 154, 117, 114, 81, 152, + 115, 113, 105, 94, 99, 129, 112, 130, 100, 120, + 119, 121, 0, 0, 0, 143, 159, 172, 0, 0, + 165, 166, 167, 168, 0, 0, 0, 122, 85, 101, + 140, 104, 111, 134, 170, 126, 138, 88, 158, 141, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 125, 0, 77, 0, 108, + 169, 133, 95, 160, 93, 0, 0, 0, 0, 107, + 0, 109, 0, 0, 142, 118, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 185, 0, 574, 0, 0, 0, 0, + 0, 0, 86, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 187, 0, + 0, 0, 0, 131, 0, 0, 145, 98, 97, 106, + 0, 0, 0, 89, 0, 137, 127, 157, 0, 128, + 136, 110, 149, 132, 156, 188, 164, 147, 163, 78, + 146, 155, 87, 139, 80, 153, 144, 116, 102, 103, + 79, 0, 135, 92, 96, 91, 124, 150, 151, 90, + 171, 83, 162, 82, 84, 161, 123, 148, 154, 117, + 114, 81, 152, 115, 113, 105, 94, 99, 129, 112, + 130, 100, 120, 119, 121, 0, 0, 0, 143, 159, + 172, 0, 0, 165, 166, 167, 168, 0, 0, 0, + 122, 85, 101, 140, 104, 111, 134, 170, 126, 138, + 88, 158, 141, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 125, 0, + 77, 0, 108, 169, 133, 95, 160, 93, 0, 0, + 0, 0, 107, 0, 109, 0, 0, 142, 118, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 75, 0, 478, 0, + 0, 0, 0, 0, 0, 86, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 187, 0, 0, 0, 0, 131, 0, 0, 145, + 98, 97, 106, 0, 0, 0, 89, 0, 137, 127, + 157, 0, 128, 136, 110, 149, 132, 156, 188, 164, + 147, 163, 78, 146, 155, 87, 139, 80, 153, 144, + 116, 102, 103, 79, 0, 135, 92, 96, 91, 124, + 150, 151, 90, 171, 83, 162, 82, 84, 161, 123, + 148, 154, 117, 114, 81, 152, 115, 113, 105, 94, + 99, 129, 112, 130, 100, 120, 119, 121, 0, 0, + 0, 143, 159, 172, 0, 0, 165, 166, 167, 168, + 0, 0, 0, 122, 85, 101, 140, 104, 111, 134, + 170, 126, 138, 88, 158, 141, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 125, 77, 0, 108, 169, 133, 95, 160, + 550, 93, 0, 0, 0, 0, 107, 0, 109, 0, + 0, 142, 118, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 185, 0, 0, 0, 0, 0, 0, 0, 0, 86, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 187, 0, 0, 0, 0, + 131, 0, 0, 145, 98, 97, 106, 0, 0, 0, + 89, 0, 137, 127, 157, 0, 128, 136, 110, 149, + 132, 156, 188, 164, 147, 163, 78, 146, 155, 87, + 139, 80, 153, 144, 116, 102, 103, 79, 0, 135, + 92, 96, 91, 124, 150, 151, 90, 171, 83, 162, + 82, 84, 161, 123, 148, 154, 117, 114, 81, 152, + 115, 113, 105, 94, 99, 129, 112, 130, 100, 120, + 119, 121, 0, 0, 0, 143, 159, 172, 0, 0, + 165, 166, 167, 168, 0, 0, 0, 122, 85, 101, + 140, 104, 111, 134, 170, 126, 138, 88, 158, 141, + 0, 0, 0, 0, 0, 0, 0, 0, 301, 0, + 0, 0, 0, 0, 0, 125, 0, 77, 0, 108, + 169, 133, 95, 160, 93, 0, 0, 0, 0, 107, + 0, 109, 0, 0, 142, 118, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 185, 0, 0, 0, 0, 0, 0, + 0, 0, 86, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 187, 0, + 0, 0, 0, 131, 0, 0, 145, 98, 97, 106, + 0, 0, 0, 89, 0, 137, 127, 157, 0, 128, + 136, 110, 149, 132, 156, 188, 164, 147, 163, 78, + 146, 155, 87, 139, 80, 153, 144, 116, 102, 103, + 79, 0, 135, 92, 96, 91, 124, 150, 151, 90, + 171, 83, 162, 82, 84, 161, 123, 148, 154, 117, + 114, 81, 152, 115, 113, 105, 94, 99, 129, 112, + 130, 100, 120, 119, 121, 0, 0, 0, 143, 159, + 172, 0, 0, 165, 166, 167, 168, 0, 0, 0, + 122, 85, 101, 140, 104, 111, 134, 170, 126, 138, + 88, 158, 141, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 125, 0, + 77, 0, 108, 169, 133, 95, 160, 93, 0, 0, + 0, 0, 107, 0, 109, 0, 0, 142, 118, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 185, 0, 0, 0, + 0, 0, 0, 0, 0, 86, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 182, + 0, 187, 0, 0, 0, 0, 131, 0, 0, 145, + 98, 97, 106, 0, 0, 0, 89, 0, 137, 127, + 157, 0, 128, 136, 110, 149, 132, 156, 188, 164, + 147, 163, 78, 146, 155, 87, 139, 80, 153, 144, + 116, 102, 103, 79, 0, 135, 92, 96, 91, 124, + 150, 151, 90, 171, 83, 162, 82, 84, 161, 123, + 148, 154, 117, 114, 81, 152, 115, 113, 105, 94, + 99, 129, 112, 130, 100, 120, 119, 121, 0, 0, + 0, 143, 159, 172, 0, 0, 165, 166, 167, 168, + 0, 0, 0, 122, 85, 101, 140, 104, 111, 134, + 170, 126, 138, 88, 158, 141, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 125, 0, 77, 0, 108, 169, 133, 95, 160, + 93, 0, 0, 0, 0, 107, 0, 109, 0, 0, + 142, 118, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 75, + 0, 0, 0, 0, 0, 0, 0, 0, 86, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 187, 0, 0, 0, 0, 131, + 0, 0, 145, 98, 97, 106, 0, 0, 0, 89, + 0, 137, 127, 157, 0, 128, 136, 110, 149, 132, + 156, 188, 164, 147, 163, 78, 146, 155, 87, 139, + 80, 153, 144, 116, 102, 103, 79, 0, 135, 92, + 96, 91, 124, 150, 151, 90, 171, 83, 162, 82, + 84, 161, 123, 148, 154, 117, 114, 81, 152, 115, + 113, 105, 94, 99, 129, 112, 130, 100, 120, 119, + 121, 0, 0, 0, 143, 159, 172, 0, 0, 165, + 166, 167, 168, 0, 0, 0, 122, 85, 101, 140, + 104, 111, 134, 170, 126, 138, 88, 158, 141, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 125, 0, 77, 0, 108, 169, + 133, 95, 160, 93, 0, 0, 0, 0, 107, 0, + 109, 0, 0, 142, 118, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 238, 0, 0, 0, 0, 0, 0, 0, + 0, 86, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 187, 0, 0, + 0, 0, 131, 0, 0, 145, 98, 97, 106, 0, + 0, 0, 89, 0, 137, 127, 157, 0, 128, 136, + 110, 149, 132, 156, 188, 164, 147, 163, 78, 146, + 155, 87, 139, 80, 153, 144, 116, 102, 103, 79, + 0, 135, 92, 96, 91, 124, 150, 151, 90, 171, + 83, 162, 82, 84, 161, 123, 148, 154, 117, 114, + 81, 152, 115, 113, 105, 94, 99, 129, 112, 130, + 100, 120, 119, 121, 0, 0, 0, 143, 159, 172, + 0, 0, 165, 166, 167, 168, 0, 0, 0, 122, + 85, 101, 140, 104, 111, 134, 170, 126, 138, 88, + 158, 141, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 125, 0, 77, + 0, 108, 169, 133, 95, 160, 93, 0, 0, 0, + 0, 107, 0, 109, 0, 0, 142, 118, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 185, 0, 0, 0, 0, + 0, 0, 0, 0, 86, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 187, 0, 0, 0, 0, 131, 0, 0, 145, 98, + 97, 106, 0, 0, 0, 89, 0, 137, 127, 157, + 0, 128, 136, 110, 149, 132, 156, 188, 164, 147, + 163, 78, 146, 155, 87, 139, 80, 153, 144, 116, + 102, 103, 79, 0, 135, 92, 96, 91, 124, 150, + 151, 90, 171, 83, 162, 82, 84, 161, 123, 148, + 154, 117, 114, 81, 152, 115, 113, 105, 94, 99, + 129, 112, 130, 100, 120, 119, 121, 0, 0, 0, + 143, 159, 172, 0, 0, 165, 166, 167, 168, 0, + 0, 0, 122, 85, 101, 140, 104, 111, 134, 170, + 126, 138, 88, 158, 141, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 77, 0, 108, 169, 133, 95, 160, +} +var yyPact = [...]int{ + + 1723, -1000, -186, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, 802, 836, -1000, -1000, -1000, -1000, -1000, -1000, 618, + 7335, 41, 62, -18, 10030, 61, 1367, 10699, -1000, -6, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, 593, -1000, -1000, + -1000, -1000, -1000, 776, 799, 647, 803, 702, -1000, 5512, + 40, 8914, 9807, 4816, -1000, 484, 59, 10699, -158, 10253, + 34, 34, 34, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, 51, 10699, -1000, 10699, 33, 481, 33, + 33, 33, 10699, -1000, 101, -1000, -1000, -1000, -1000, 10699, + 478, 733, 22, 2856, 2856, 2856, 2856, 1, 2856, -83, + 655, -1000, -1000, -1000, -1000, 2856, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, 364, 739, 6211, 6211, + 802, -1000, 593, -1000, -1000, -1000, 729, -1000, -1000, 243, + 822, -1000, 7112, 99, -1000, 6211, 1819, 429, -1000, -1000, + 429, -1000, -1000, 81, -1000, -1000, 6657, 6657, 6657, 6657, + 6657, 6657, 6657, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, 429, -1000, 5979, + 429, 429, 429, 429, 429, 429, 429, 429, 6211, 429, + 429, 429, 429, 429, 429, 429, 429, 429, 429, 429, + 429, 429, 9584, 587, 874, -1000, -1000, -1000, 767, 8013, + 8691, 10699, 531, -1000, 589, 4571, -121, -1000, -1000, -1000, + 173, 8459, -1000, -1000, -1000, 731, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 477, + -1000, 1856, 472, 2856, 50, 606, 470, 223, 453, 10699, + 10699, 2856, 44, 10699, 757, 653, 10699, 452, 440, -1000, + 4326, -1000, 2856, 2856, 2856, 2856, 2856, 2856, 2856, 2856, + -1000, -1000, -1000, -1000, -1000, -1000, 2856, 2856, -1000, -67, + -1000, 10699, -1000, -1000, -1000, -1000, 831, 130, 525, 95, + 591, -1000, 278, 776, 364, 702, 8236, 665, -1000, -1000, + 10699, -1000, 6211, 6211, 286, -1000, 9360, -1000, -1000, 3346, + 147, 6657, 284, 237, 6657, 6657, 6657, 6657, 6657, 6657, + 6657, 6657, 6657, 6657, 6657, 6657, 6657, 6657, 6657, 327, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 438, -1000, + 593, 725, 725, 113, 113, 113, 113, 113, 113, 6880, + 5048, 364, 437, 180, 5979, 5512, 5512, 6211, 6211, 10476, + 10476, 5512, 769, 203, 180, 10476, -1000, 364, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, 5512, 5512, 5512, 5512, 14, + 10699, -1000, 10476, 8914, 8914, 8914, 8914, 8914, -1000, 679, + 678, -1000, 688, 685, 694, 10699, -1000, 433, 8013, 125, + 429, -1000, 9137, -1000, -1000, 14, 568, 8914, 10699, -1000, + -1000, 4081, 589, -121, 581, -1000, -98, -97, 5744, 110, + -1000, -1000, -1000, -1000, 2611, 188, 273, -66, -1000, -1000, + -1000, 595, -1000, 595, 595, 595, 595, -33, -33, -33, + -33, -1000, -1000, -1000, -1000, -1000, 617, 614, -1000, 595, + 595, 595, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 613, 613, + 613, 597, 597, 622, -1000, 10699, -174, 430, 2856, 756, + 2856, -1000, 70, -1000, 10699, -1000, -1000, 10699, 2856, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, 208, -1000, -1000, -1000, -1000, 695, + 6211, 6211, 3836, 6211, -1000, -1000, -1000, 739, -1000, 769, + 810, -1000, 722, 720, 5512, -1000, -1000, 147, 156, -1000, + -1000, 328, -1000, -1000, -1000, -1000, 94, 429, -1000, 1907, + -1000, -1000, -1000, -1000, 284, 6657, 6657, 6657, 1409, 1907, + 1872, 405, 357, 113, 612, 612, 112, 112, 112, 112, + 112, 910, 910, -1000, -1000, -1000, 364, -1000, -1000, -1000, + 364, 5512, 582, -1000, -1000, 6211, -1000, 364, 426, 426, + 289, 334, 626, -1000, 91, 619, 426, 5512, 218, -1000, + 6211, 364, -1000, 426, 364, 426, 426, 544, 429, -1000, + 564, -1000, 172, 874, 605, 652, 650, -1000, -1000, -1000, + -1000, 675, -1000, 636, -1000, -1000, -1000, -1000, -1000, 58, + 57, 56, 10253, -1000, 818, 8914, 521, -1000, -1000, 581, + -121, -100, -1000, -1000, -1000, 180, -1000, 428, 530, 2366, + -1000, -1000, -1000, -1000, -1000, -1000, 601, 749, 145, 137, + 427, -1000, -1000, 736, -1000, 238, -69, -1000, -1000, 292, + -33, -33, -1000, -1000, 110, 730, 110, 110, 110, 343, + 343, -1000, -1000, -1000, -1000, 280, -1000, -1000, -1000, 277, + -1000, 637, 10253, 2856, -1000, 3591, -1000, -1000, -1000, -1000, + -1000, -1000, 282, 204, 179, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, 13, -1000, 2856, -1000, + 209, 10699, 10699, 709, 180, 180, 79, -1000, -1000, 10699, + -1000, -1000, -1000, -1000, 610, -1000, -1000, -1000, 3101, 5512, + -1000, 1409, 1907, 1606, -1000, 6657, 6657, -1000, -1000, 426, + 5512, 180, -1000, -1000, -1000, 54, 327, 54, 6657, 6657, + 3836, 6657, 6657, -168, 532, 187, -1000, 6211, 307, -1000, + -1000, -1000, -1000, -1000, 635, 10476, 429, -1000, 7790, 10253, + 802, 10476, 6211, 6211, -1000, -1000, 6211, 599, -1000, 6211, + -1000, -1000, -1000, 429, 429, 429, 389, -1000, 802, 521, + -1000, -1000, -1000, -130, -132, -1000, -1000, 2611, -1000, 2611, + 10253, -1000, 367, 350, -1000, -1000, 625, 28, -1000, -1000, + -1000, 423, 110, 110, -1000, 155, -1000, -1000, -1000, 420, + -1000, 416, 526, 410, 10699, -1000, -1000, 516, -1000, 165, + -1000, -1000, 10253, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, 10253, 10699, -1000, -1000, -1000, + -1000, -1000, 10253, -1000, -1000, 341, 6211, -1000, -1000, -1000, + 3591, -1000, 818, 8914, -1000, -1000, 364, -1000, 6657, 1907, + 1907, -1000, -1000, 364, 595, 595, -1000, 595, 597, -1000, + 595, -15, 595, -16, 364, 364, 1524, 1728, -1000, 422, + 1553, 429, -165, -1000, 180, 6211, -1000, 732, 490, 498, + -1000, -1000, 5280, 364, 391, 77, 389, 776, -1000, 180, + 180, 180, 10253, 180, 10253, 10253, 10253, 7567, 10253, 776, + -1000, -1000, -1000, -1000, 2366, -1000, 387, -1000, 595, -1000, + -1000, -60, 828, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -33, 340, -33, 259, -1000, 257, + 2856, 3591, 2611, -1000, 594, -1000, -1000, -1000, -1000, 741, + -1000, 180, 815, 513, -1000, 1907, -1000, -1000, 86, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 6657, 6657, + -1000, 6657, 6657, 6657, 364, 322, 180, 748, -1000, 429, + -1000, -1000, 560, 10253, 10253, -1000, -1000, 377, -1000, 371, + 371, 371, 125, -1000, -1000, 107, 10253, -1000, 133, -1000, + -147, 110, -1000, 110, 417, 406, -1000, -1000, -1000, 10253, + 429, 805, 779, -1000, -1000, 1509, 1509, 1509, 1509, 16, + -1000, -1000, 826, -1000, 429, -1000, 593, 73, -1000, 10253, + -1000, -1000, -1000, -1000, -1000, 107, -1000, 347, 160, 317, + -1000, 239, 747, -1000, 738, -1000, -1000, -1000, -1000, -1000, + 363, 12, -1000, 6211, 6211, -1000, -1000, -1000, -1000, 364, + 49, -178, 10476, 498, 364, 10253, -1000, -1000, -1000, 256, + -1000, -1000, -1000, 316, -1000, -1000, 606, 361, -1000, 10253, + 180, 494, -1000, 706, -171, -181, 435, -1000, -1000, -1000, + -1000, -174, -1000, 12, 715, -1000, 705, -1000, -1000, -1000, + 9, -175, 4, -179, 429, -182, 6434, -1000, 1509, 364, + -1000, -1000, +} +var yyPgo = [...]int{ + + 0, 1069, 13, 493, 1068, 1067, 1063, 1059, 1058, 1056, + 1055, 1053, 1052, 1047, 1045, 1044, 1042, 1040, 1039, 1037, + 1036, 1035, 1033, 1032, 104, 1031, 1027, 1026, 57, 1025, + 63, 1024, 1022, 33, 225, 45, 30, 150, 1018, 31, + 54, 84, 1017, 35, 1016, 1014, 70, 1013, 51, 1000, + 999, 1293, 998, 995, 19, 41, 993, 991, 990, 989, + 60, 312, 988, 987, 985, 982, 981, 979, 39, 5, + 7, 12, 11, 978, 127, 15, 976, 55, 975, 974, + 973, 971, 25, 970, 46, 965, 21, 40, 964, 16, + 53, 28, 23, 2, 65, 47, 962, 27, 50, 38, + 961, 958, 367, 948, 944, 942, 940, 936, 934, 140, + 309, 932, 931, 930, 928, 32, 167, 466, 73, 58, + 927, 926, 925, 1239, 59, 52, 22, 924, 36, 1247, + 42, 912, 910, 29, 909, 908, 897, 895, 894, 893, + 892, 264, 890, 889, 887, 17, 20, 882, 881, 49, + 26, 878, 877, 876, 34, 37, 874, 44, 873, 872, + 867, 866, 24, 10, 865, 9, 862, 8, 860, 856, + 4, 853, 18, 852, 3, 851, 6, 43, 850, 847, + 0, 323, 844, 843, 105, +} +var yyR1 = [...]int{ + + 0, 178, 179, 179, 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, 27, 27, 8, 9, 9, 9, 182, + 182, 46, 46, 90, 90, 10, 10, 10, 10, 95, + 95, 99, 99, 99, 100, 100, 100, 100, 131, 131, + 11, 11, 11, 11, 11, 11, 11, 176, 176, 175, + 174, 174, 173, 173, 172, 16, 159, 160, 160, 160, + 155, 134, 134, 134, 134, 137, 137, 135, 135, 135, + 135, 135, 135, 135, 136, 136, 136, 136, 136, 138, + 138, 138, 138, 138, 139, 139, 139, 139, 139, 139, + 139, 139, 139, 139, 139, 139, 139, 139, 139, 140, + 140, 140, 140, 140, 140, 140, 140, 154, 154, 141, + 141, 149, 149, 150, 150, 150, 147, 147, 148, 148, + 151, 151, 151, 142, 142, 142, 142, 142, 142, 142, + 144, 144, 152, 152, 145, 145, 145, 146, 146, 153, + 153, 153, 153, 153, 143, 143, 156, 156, 168, 168, + 167, 167, 167, 158, 158, 164, 164, 164, 164, 164, + 157, 157, 166, 166, 165, 161, 161, 161, 162, 162, + 162, 163, 163, 163, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 177, 177, 177, 177, 177, 177, 177, + 177, 177, 177, 177, 171, 169, 169, 170, 170, 13, + 14, 14, 14, 14, 14, 15, 15, 17, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 107, 107, 104, 104, 105, 105, 106, 106, 106, + 108, 108, 108, 132, 132, 132, 19, 19, 21, 21, + 22, 23, 20, 20, 20, 20, 20, 183, 24, 25, + 25, 26, 26, 26, 30, 30, 30, 28, 28, 29, + 29, 35, 35, 34, 34, 36, 36, 36, 36, 120, + 120, 120, 119, 119, 38, 38, 39, 39, 40, 40, + 41, 41, 41, 53, 53, 89, 89, 91, 91, 42, + 42, 42, 42, 43, 43, 44, 44, 45, 45, 127, + 127, 126, 126, 126, 125, 125, 47, 47, 47, 49, + 48, 48, 48, 48, 50, 50, 52, 52, 51, 51, + 54, 54, 54, 54, 55, 55, 37, 37, 37, 37, + 37, 37, 37, 103, 103, 57, 57, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 67, 67, 67, + 67, 67, 67, 58, 58, 58, 58, 58, 58, 58, + 33, 33, 68, 68, 68, 74, 69, 69, 61, 61, + 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, + 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, + 61, 61, 61, 61, 61, 61, 61, 61, 61, 65, + 65, 65, 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 64, 64, 64, + 64, 64, 64, 64, 64, 184, 184, 66, 66, 66, + 66, 31, 31, 31, 31, 31, 130, 130, 133, 133, + 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, + 133, 78, 78, 32, 32, 76, 76, 77, 79, 79, + 75, 75, 75, 60, 60, 60, 60, 60, 60, 60, + 60, 62, 62, 62, 80, 80, 81, 81, 82, 82, + 83, 83, 84, 85, 85, 85, 86, 86, 86, 86, + 87, 87, 87, 59, 59, 59, 59, 59, 59, 88, + 88, 88, 88, 92, 92, 70, 70, 72, 72, 71, + 73, 93, 93, 97, 94, 94, 98, 98, 98, 96, + 96, 96, 122, 122, 122, 101, 101, 109, 109, 110, + 110, 102, 102, 111, 111, 111, 111, 111, 111, 111, + 111, 111, 111, 112, 112, 112, 113, 113, 114, 114, + 114, 121, 121, 117, 117, 118, 118, 123, 123, 124, + 124, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 116, 116, 116, 116, 116, 116, 116, + 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, + 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, + 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, + 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, + 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, + 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, + 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, + 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, + 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, + 116, 180, 181, 128, 129, 129, 129, +} +var yyR2 = [...]int{ + + 0, 2, 0, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 4, 6, 7, 5, 10, 1, 3, 1, + 3, 7, 8, 1, 1, 8, 8, 7, 6, 1, + 1, 1, 3, 0, 4, 3, 4, 5, 4, 1, + 3, 3, 2, 2, 2, 2, 2, 1, 1, 1, + 2, 8, 4, 6, 5, 5, 5, 0, 2, 1, + 0, 2, 1, 3, 3, 4, 4, 1, 3, 3, + 8, 3, 1, 1, 1, 2, 1, 1, 1, 1, + 1, 1, 1, 1, 2, 2, 2, 2, 2, 1, + 2, 2, 2, 1, 4, 4, 2, 2, 3, 3, + 3, 3, 1, 1, 1, 1, 1, 6, 6, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 3, 0, + 3, 0, 5, 0, 3, 5, 0, 1, 0, 1, + 0, 1, 2, 0, 2, 2, 2, 2, 2, 2, + 0, 3, 0, 1, 0, 3, 3, 0, 2, 0, + 2, 1, 2, 1, 0, 2, 5, 4, 1, 2, + 2, 3, 2, 0, 1, 2, 3, 3, 2, 2, + 1, 1, 1, 3, 2, 0, 1, 3, 1, 2, + 3, 1, 1, 1, 6, 7, 7, 12, 7, 7, + 7, 4, 5, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 7, 1, 3, 8, 8, 5, + 4, 6, 5, 4, 4, 3, 2, 3, 4, 4, + 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, + 4, 3, 6, 4, 2, 4, 2, 2, 2, 2, + 3, 1, 1, 0, 1, 0, 1, 0, 2, 2, + 0, 2, 2, 0, 1, 1, 2, 1, 1, 2, + 1, 1, 2, 2, 2, 2, 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, 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, + 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, 3, 1, 1, 1, 1, 4, + 5, 6, 4, 4, 6, 6, 6, 6, 8, 8, + 6, 8, 8, 9, 7, 5, 4, 2, 2, 2, + 2, 2, 2, 2, 2, 0, 2, 4, 4, 4, + 4, 0, 3, 4, 7, 3, 1, 1, 2, 3, + 3, 1, 2, 2, 1, 2, 1, 2, 2, 1, + 2, 0, 1, 0, 2, 1, 2, 4, 0, 2, + 1, 3, 5, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 2, 2, 0, 3, 0, 2, 0, 3, + 1, 3, 2, 0, 1, 1, 0, 2, 4, 4, + 0, 2, 4, 2, 1, 3, 5, 4, 6, 1, + 3, 3, 5, 0, 5, 1, 3, 1, 2, 3, + 1, 1, 3, 3, 1, 3, 3, 3, 3, 1, + 2, 1, 1, 1, 1, 1, 1, 0, 2, 0, + 3, 0, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, + 1, 0, 2, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 0, 0, 1, 1, +} +var yyChk = [...]int{ + + -1000, -178, -1, -2, -6, -7, -8, -9, -10, -11, + -12, -13, -14, -15, -17, -18, -19, -21, -22, -23, + -20, -3, -4, 6, 7, -27, 9, 10, 30, -16, + 112, 113, 115, 114, 140, 116, 133, 49, 152, 153, + 155, 156, 25, 134, 135, 138, 139, -180, 8, 235, + 53, -179, 250, -82, 15, -26, 5, -24, -183, -24, + -24, -24, -24, -24, -159, 53, -114, 121, 70, 148, + 227, 118, 119, 125, -117, 56, -116, 243, 152, 163, + 157, 184, 176, 174, 177, 214, 65, 155, 223, 136, + 172, 168, 166, 27, 189, 248, 167, 131, 130, 190, + 194, 215, 161, 162, 217, 188, 132, 32, 245, 34, + 144, 218, 192, 187, 183, 186, 160, 182, 38, 196, + 195, 197, 213, 179, 169, 18, 221, 139, 142, 191, + 193, 126, 146, 247, 219, 165, 143, 138, 222, 156, + 216, 225, 37, 201, 159, 129, 153, 150, 180, 145, + 170, 171, 185, 158, 181, 154, 147, 140, 224, 202, + 249, 178, 175, 151, 149, 206, 207, 208, 209, 246, + 220, 173, 203, -102, 121, 123, 119, 119, 120, 121, + 227, 118, 119, -51, -123, 56, -116, 121, 148, 119, + 106, 177, 112, 204, 120, 32, 146, -132, 119, -104, + 149, 206, 207, 208, 209, 56, 216, 215, 210, -123, + 154, -128, -128, -128, -128, -128, -2, -86, 17, 16, + -5, -3, -180, 6, 20, 21, -30, 39, 40, -25, + -36, 97, -37, -123, -56, 72, -61, 29, 56, -116, + 23, -60, -57, -75, -73, -74, 106, 107, 95, 96, + 103, 73, 108, -65, -63, -64, -66, 58, 57, 66, + 59, 60, 61, 62, 67, 68, 69, -117, -71, -180, + 43, 44, 236, 237, 238, 239, 242, 240, 75, 33, + 226, 234, 233, 232, 230, 231, 228, 229, 124, 227, + 101, 235, -102, -39, -40, -41, -42, -53, -74, -180, + -51, 11, -46, -51, -94, -131, 154, -98, 216, 215, + -118, -96, -117, -115, 214, 177, 213, 117, 71, 22, + 24, 199, 74, 106, 16, 75, 105, 236, 112, 47, + 228, 229, 226, 238, 239, 227, 204, 29, 10, 25, + 134, 21, 99, 114, 78, 79, 137, 23, 135, 69, + 19, 50, 11, 13, 14, 124, 123, 90, 120, 45, + 8, 108, 26, 87, 41, 28, 43, 88, 17, 230, + 231, 31, 242, 141, 101, 48, 35, 72, 67, 51, + 70, 15, 46, 89, 115, 235, 44, 118, 6, 241, + 30, 133, 42, 119, 205, 77, 122, 68, 5, 125, + 9, 49, 52, 232, 233, 234, 33, 76, 12, -160, + -155, 56, 120, -51, 235, -117, -110, 124, -110, -110, + 119, -51, -51, -109, 124, 56, -109, -109, -109, -51, + 109, -51, 56, 30, 227, 56, 146, 119, 147, 121, + -129, -180, -118, -129, -129, -129, 150, 151, -129, -105, + 211, 51, -129, -181, 55, -87, 19, 31, -37, -123, + -83, -84, -37, -82, -2, -24, 35, -28, 21, 64, + 11, -120, 71, 70, 87, -119, 22, -117, 58, 109, + -37, -58, 90, 72, 88, 89, 74, 92, 91, 102, + 95, 96, 97, 98, 99, 100, 101, 93, 94, 105, + 80, 81, 82, 83, 84, 85, 86, -103, -180, -74, + -180, 110, 111, -61, -61, -61, -61, -61, -61, -61, + -180, -2, -69, -37, -180, -180, -180, -180, -180, -180, + -180, -180, -180, -78, -37, -180, -184, -180, -184, -184, + -184, -184, -184, -184, -184, -180, -180, -180, -180, -52, + 26, -51, 30, 54, -47, -49, -48, -50, 41, 45, + 47, 42, 43, 44, 48, -127, 22, -39, -180, -126, + 142, -125, 22, -123, 58, -51, -46, -182, 54, 11, + 52, 54, -94, 154, -95, -99, 217, 219, 80, -122, + -117, 58, 29, 30, 55, 54, -134, -137, -139, -138, + -140, -135, -136, 174, 175, 106, 178, 180, 181, 182, + 183, 184, 185, 186, 187, 188, 189, 30, 136, 170, + 171, 172, 173, 190, 191, 192, 193, 194, 195, 196, + 197, 157, 158, 159, 160, 161, 162, 163, 165, 166, + 167, 168, 169, 56, -129, 121, -176, 52, 56, 72, + 56, -51, -51, -129, 122, -51, 23, 51, -51, 56, + 56, -124, -123, -115, -129, -129, -129, -129, -129, -129, + -129, -129, -129, -129, -107, 205, 212, -51, 9, 90, + 54, 18, 109, 54, -85, 24, 25, -86, -181, -30, + -62, -117, 59, 62, -29, 42, -51, -37, -37, -67, + 67, 72, 68, 69, -119, 97, -124, -118, -115, -61, + -68, -71, -74, 63, 90, 88, 89, 74, -61, -61, + -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, + -61, -61, -61, -130, 56, 58, 56, -60, -60, -117, + -35, 21, -34, -36, -181, 54, -181, -2, -34, -34, + -37, -37, -75, -117, -123, -75, -34, -28, -76, -77, + 76, -75, -181, -34, -35, -34, -34, -90, 142, -51, + -93, -97, -75, -40, -41, -41, -40, -41, 41, 41, + 41, 46, 41, 46, 41, -48, -123, -181, -54, 49, + 123, 50, -180, -125, -90, 52, -39, -51, -98, -95, + 54, 218, 220, 221, 51, -37, -146, 105, -161, -162, + -163, -118, 58, 59, -155, -156, -164, 126, 129, 125, + -157, 120, 28, -151, 67, 72, -147, 202, -141, 53, + -141, -141, -141, -141, -145, 177, -145, -145, -145, 53, + 53, -141, -141, -141, -149, 53, -149, -149, -150, 53, + -150, -121, 52, -51, -174, 246, -175, 56, -129, 23, + -129, -111, 117, 114, 115, -171, 113, 199, 177, 65, + 29, 15, 236, 142, 249, 56, 143, -51, -51, -129, + -106, 11, 90, 37, -37, -37, -124, -84, -87, -101, + 19, 11, 33, 33, -34, 67, 68, 69, 109, -180, + -68, -61, -61, -61, -33, 137, 71, -181, -181, -34, + 54, -37, -181, -181, -181, 54, 52, 22, 54, 11, + 109, 54, 11, -181, -34, -79, -77, 78, -37, -181, + -181, -181, -181, -181, -59, 30, 33, -2, -180, -180, + -55, 54, 12, 80, -44, -43, 51, 52, -45, 51, + -43, 41, 41, 120, 120, 120, -91, -117, -55, -39, + -55, -99, -100, 222, 219, 225, 56, 54, -163, 80, + 53, 28, -157, -157, 56, 56, -142, 29, 67, -148, + 203, 59, -145, -145, -146, 30, -146, -146, -146, -154, + 58, -154, 59, 59, 51, -117, -129, -173, -172, -118, + -128, -177, 148, 127, 128, 131, 130, 56, 120, 28, + 126, 129, 142, 125, -177, 148, -112, -113, 122, 22, + 120, 28, 142, -129, -108, 88, 12, -123, -123, 38, + 109, -51, -38, 11, 97, -118, -35, -33, 71, -61, + -61, -181, -36, -133, 106, 174, 136, 172, 168, 188, + 179, 201, 170, 202, -130, -133, -61, -61, -118, -61, + -61, 243, -82, 79, -37, 77, -92, 51, -93, -70, + -72, -71, -180, -2, -88, -117, -91, -82, -97, -37, + -37, -37, 53, -37, -180, -180, -180, -181, 54, -82, + -55, 219, 223, 224, -162, -163, -166, -165, -117, 56, + 56, -144, 51, 58, 59, 60, 67, 226, 66, 55, + -146, -146, 56, 106, 55, 54, 55, 54, 55, 54, + -51, 54, 80, -128, -117, -128, -117, -51, -128, -117, + 58, -37, -55, -39, -181, -61, -181, -141, -141, -141, + -150, -141, 162, -141, 162, -181, -181, -181, 54, 19, + -181, 54, 19, -180, -32, 241, -37, 27, -92, 54, + -181, -181, -181, 54, 109, -181, -86, -89, -117, -89, + -89, -89, -126, -117, -86, 55, 54, -141, -152, 199, + 9, -145, 58, -145, 59, 59, -129, -172, -163, 53, + 26, -80, 13, -145, 56, -61, -61, -61, -61, -61, + -181, 58, 28, -72, 33, -2, -180, -117, -117, 54, + 55, -181, -181, -181, -54, -168, -167, 52, 132, 65, + -165, -153, 126, 28, 125, 226, -146, -146, 55, 55, + -89, -180, -81, 14, 16, -181, -181, -181, -181, -31, + 90, 246, 9, -70, -2, 109, -117, -167, 56, -158, + 80, 58, -143, 65, 28, 28, 55, -169, -170, 142, + -37, -69, -181, 244, 48, 247, -93, -181, -117, 59, + 58, -176, -181, 54, -117, 38, 245, 248, -174, -170, + 33, 38, 144, 246, 145, 247, -180, 248, -61, 141, + -181, -181, +} +var yyDef = [...]int{ + + 0, -2, 2, -2, 5, 6, 7, 8, 9, 10, + 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, + 21, 508, 0, 277, 277, 277, 277, 277, 277, 0, + 578, 561, 0, 0, 0, 0, -2, 267, 268, 0, + 270, 271, 783, 783, 783, 783, 783, 0, 33, 34, + 781, 1, 3, 516, 0, 0, 281, 284, 279, 0, + 561, 0, 0, 0, 60, 0, 0, 770, 0, 771, + 559, 559, 559, 579, 580, 583, 584, 683, 684, 685, + 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, + 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, + 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, + 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, + 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, + 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, + 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, + 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, + 766, 767, 768, 769, 772, 773, 774, 775, 776, 777, + 778, 779, 780, 0, 0, 562, 0, 557, 0, 557, + 557, 557, 0, 226, 348, 587, 588, 770, 771, 0, + 0, 0, 0, 784, 784, 784, 784, 0, 784, 255, + 244, 246, 247, 248, 249, 784, 264, 265, 254, 266, + 269, 272, 273, 274, 275, 276, 27, 520, 0, 0, + 508, 29, 0, 277, 282, 283, 287, 285, 286, 278, + 0, 295, 299, 0, 356, 0, 361, 363, -2, -2, + 0, 398, 399, 400, 401, 402, 0, 0, 0, 0, + 0, 0, 0, 425, 426, 427, 428, 493, 494, 495, + 496, 497, 498, 499, 500, 365, 366, 490, 540, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 481, 0, + 455, 455, 455, 455, 455, 455, 455, 455, 0, 0, + 0, 0, 0, 0, 306, 308, 309, 310, 329, 0, + 331, 0, 0, 41, 45, 0, 761, 544, -2, -2, + 0, 0, 585, 586, -2, 690, -2, 591, 592, 593, + 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, + 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, + 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, + 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, + 634, 635, 636, 637, 638, 639, 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, 0, + 77, 0, 0, 784, 0, 67, 0, 0, 0, 0, + 0, 784, 0, 0, 0, 0, 0, 0, 0, 225, + 0, 227, 784, 784, 784, 784, 784, 784, 784, 784, + 236, 785, 786, 237, 238, 239, 784, 784, 241, 0, + 256, 0, 250, 28, 782, 22, 0, 0, 517, 0, + 509, 510, 513, 516, 27, 284, 0, 289, 288, 280, + 0, 296, 0, 0, 0, 300, 0, 302, 303, 0, + 359, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 383, 384, 385, 386, 387, 388, 389, 362, 0, 376, + 0, 0, 0, 418, 419, 420, 421, 422, 423, 0, + 291, 27, 0, 396, 0, 0, 0, 0, 0, 0, + 0, 0, 287, 0, 482, 0, 447, 0, 448, 449, + 450, 451, 452, 453, 454, 0, 291, 0, 0, 43, + 0, 347, 0, 0, 0, 0, 0, 0, 336, 0, + 0, 339, 0, 0, 0, 0, 330, 0, 0, 350, + 734, 332, 0, 334, 335, -2, 0, 0, 0, 39, + 40, 0, 46, 761, 48, 49, 0, 0, 0, 157, + 552, 553, 554, 550, 185, 0, 140, 136, 82, 83, + 84, 129, 86, 129, 129, 129, 129, 154, 154, 154, + 154, 112, 113, 114, 115, 116, 0, 0, 99, 129, + 129, 129, 103, 119, 120, 121, 122, 123, 124, 125, + 126, 87, 88, 89, 90, 91, 92, 93, 131, 131, + 131, 133, 133, 581, 62, 0, 70, 0, 784, 0, + 784, 75, 0, 201, 0, 220, 558, 0, 784, 223, + 224, 349, 589, 590, 228, 229, 230, 231, 232, 233, + 234, 235, 240, 243, 257, 251, 252, 245, 521, 0, + 0, 0, 0, 0, 512, 514, 515, 520, 30, 287, + 0, 501, 0, 0, 0, 290, 25, 357, 358, 360, + 377, 0, 379, 381, 301, 297, 0, 491, -2, 367, + 368, 392, 393, 394, 0, 0, 0, 0, 390, 372, + 0, 403, 404, 405, 406, 407, 408, 409, 410, 411, + 412, 413, 414, 417, 466, 467, 0, 415, 416, 424, + 0, 0, 292, 293, 395, 0, 539, 27, 0, 0, + 0, 0, 0, 490, 0, 0, 0, 0, 488, 485, + 0, 0, 456, 0, 0, 0, 0, 0, 0, 346, + 354, 541, 0, 307, 325, 327, 0, 322, 337, 338, + 340, 0, 342, 0, 344, 345, 311, 312, 313, 0, + 0, 0, 0, 333, 354, 0, 354, 42, 545, 47, + 0, 0, 52, 53, 546, 547, 548, 0, 76, 186, + 188, 191, 192, 193, 78, 79, 0, 0, 0, 0, + 0, 180, 181, 143, 141, 0, 138, 137, 85, 0, + 154, 154, 106, 107, 157, 0, 157, 157, 157, 0, + 0, 100, 101, 102, 94, 0, 95, 96, 97, 0, + 98, 0, 0, 784, 64, 0, 68, 69, 65, 560, + 66, 783, 0, 0, 573, 202, 563, 564, 565, 566, + 567, 568, 569, 570, 571, 572, 0, 219, 784, 222, + 260, 0, 0, 0, 518, 519, 0, 511, 23, 0, + 555, 556, 502, 503, 304, 378, 380, 382, 0, 291, + 369, 390, 373, 0, 370, 0, 0, 364, 429, 0, + 0, 397, -2, 432, 433, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 508, 0, 486, 0, 0, 446, + 457, 458, 459, 460, 533, 0, 0, -2, 0, 0, + 508, 0, 0, 0, 319, 326, 0, 0, 320, 0, + 321, 341, 343, 0, 0, 0, 0, 317, 508, 354, + 38, 50, 51, 0, 0, 57, 158, 0, 189, 0, + 0, 175, 0, 0, 178, 179, 150, 0, 142, 81, + 139, 0, 157, 157, 108, 0, 109, 110, 111, 0, + 127, 0, 0, 0, 0, 582, 63, 71, 72, 0, + 194, 783, 0, 203, 204, 205, 206, 207, 208, 209, + 210, 211, 212, 213, 783, 0, 0, 783, 574, 575, + 576, 577, 0, 221, 242, 0, 0, 258, 259, 522, + 0, 24, 354, 0, 298, 492, 0, 371, 0, 391, + 374, 430, 294, 0, 129, 129, 471, 129, 133, 474, + 129, 476, 129, 479, 0, 0, 0, 0, 491, 0, + 0, 0, 483, 445, 489, 0, 31, 0, 533, 523, + 535, 537, 0, 27, 0, 529, 0, 516, 542, 355, + 543, 323, 0, 328, 0, 0, 0, 331, 0, 516, + 37, 54, 55, 56, 187, 190, 0, 182, 129, 176, + 177, 152, 0, 144, 145, 146, 147, 148, 149, 130, + 104, 105, 155, 156, 154, 0, 154, 0, 134, 0, + 784, 0, 0, 195, 0, 196, 198, 199, 200, 0, + 261, 262, 504, 305, 431, 375, 434, 468, 154, 472, + 473, 475, 477, 478, 480, 436, 435, 437, 0, 0, + 440, 0, 0, 0, 0, 0, 487, 0, 32, 0, + 538, -2, 0, 0, 0, 44, 35, 0, 315, 0, + 0, 0, 350, 318, 36, 167, 0, 184, 159, 153, + 0, 157, 128, 157, 0, 0, 61, 73, 74, 0, + 0, 506, 0, 469, 470, 0, 0, 0, 0, 461, + 444, 484, 0, 536, 0, -2, 0, 531, 530, 0, + 324, 351, 352, 353, 314, 166, 168, 0, 173, 0, + 183, 164, 0, 161, 163, 151, 117, 118, 132, 135, + 0, 0, 26, 0, 0, 438, 439, 441, 442, 0, + 0, 0, 0, 526, 27, 0, 316, 169, 170, 0, + 174, 172, 80, 0, 160, 162, 67, 0, 215, 0, + 507, 505, 443, 0, 0, 0, 534, -2, 532, 171, + 165, 70, 214, 0, 0, 462, 0, 465, 197, 216, + 0, 463, 0, 0, 0, 0, 0, 464, 0, 0, + 217, 218, +} +var yyTok1 = [...]int{ + + 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 73, 3, 3, 3, 100, 92, 3, + 53, 55, 97, 95, 54, 96, 109, 98, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 250, + 81, 80, 82, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 102, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 91, 3, 103, +} +var yyTok2 = [...]int{ + + 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, + 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, + 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, + 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, + 52, 56, 57, 58, 59, 60, 61, 62, 63, 64, + 65, 66, 67, 68, 69, 70, 71, 72, 74, 75, + 76, 77, 78, 79, 83, 84, 85, 86, 87, 88, + 89, 90, 93, 94, 99, 101, 104, 105, 106, 107, + 108, 110, 111, 112, 113, 114, 115, 116, 117, 118, + 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, + 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, + 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, + 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, + 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, + 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, + 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, + 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, + 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, + 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, + 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, + 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, + 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, + 249, +} +var yyTok3 = [...]int{ + 0, +} + +var yyErrorMessages = [...]struct { + state int + token int + msg string +}{} + +//line yaccpar:1 + +/* parser for yacc output */ + +var ( + yyDebug = 0 + yyErrorVerbose = false +) + +type yyLexer interface { + Lex(lval *yySymType) int + Error(s string) +} + +type yyParser interface { + Parse(yyLexer) int + Lookahead() int +} + +type yyParserImpl struct { + lval yySymType + stack [yyInitialStackSize]yySymType + char int +} + +func (p *yyParserImpl) Lookahead() int { + return p.char +} + +func yyNewParser() yyParser { + return &yyParserImpl{} +} + +const yyFlag = -1000 + +func yyTokname(c int) string { + if c >= 1 && c-1 < len(yyToknames) { + if yyToknames[c-1] != "" { + return yyToknames[c-1] + } + } + return __yyfmt__.Sprintf("tok-%v", c) +} + +func yyStatname(s int) string { + if s >= 0 && s < len(yyStatenames) { + if yyStatenames[s] != "" { + return yyStatenames[s] + } + } + return __yyfmt__.Sprintf("state-%v", s) +} + +func yyErrorMessage(state, lookAhead int) string { + const TOKSTART = 4 + + if !yyErrorVerbose { + return "syntax error" + } + + for _, e := range yyErrorMessages { + if e.state == state && e.token == lookAhead { + return "syntax error: " + e.msg + } + } + + res := "syntax error: unexpected " + yyTokname(lookAhead) + + // To match Bison, suggest at most four expected tokens. + expected := make([]int, 0, 4) + + // Look for shiftable tokens. + base := yyPact[state] + for tok := TOKSTART; tok-1 < len(yyToknames); tok++ { + if n := base + tok; n >= 0 && n < yyLast && yyChk[yyAct[n]] == tok { + if len(expected) == cap(expected) { + return res + } + expected = append(expected, tok) + } + } + + if yyDef[state] == -2 { + i := 0 + for yyExca[i] != -1 || yyExca[i+1] != state { + i += 2 + } + + // Look for tokens that we accept or reduce. + for i += 2; yyExca[i] >= 0; i += 2 { + tok := yyExca[i] + if tok < TOKSTART || yyExca[i+1] == 0 { + continue + } + if len(expected) == cap(expected) { + return res + } + expected = append(expected, tok) + } + + // If the default action is to accept or reduce, give up. + if yyExca[i+1] != 0 { + return res + } + } + + for i, tok := range expected { + if i == 0 { + res += ", expecting " + } else { + res += " or " + } + res += yyTokname(tok) + } + return res +} + +func yylex1(lex yyLexer, lval *yySymType) (char, token int) { + token = 0 + char = lex.Lex(lval) + if char <= 0 { + token = yyTok1[0] + goto out + } + if char < len(yyTok1) { + token = yyTok1[char] + goto out + } + if char >= yyPrivate { + if char < yyPrivate+len(yyTok2) { + token = yyTok2[char-yyPrivate] + goto out + } + } + for i := 0; i < len(yyTok3); i += 2 { + token = yyTok3[i+0] + if token == char { + token = yyTok3[i+1] + goto out + } + } + +out: + if token == 0 { + token = yyTok2[1] /* unknown char */ + } + if yyDebug >= 3 { + __yyfmt__.Printf("lex %s(%d)\n", yyTokname(token), uint(char)) + } + return char, token +} + +func yyParse(yylex yyLexer) int { + return yyNewParser().Parse(yylex) +} + +func (yyrcvr *yyParserImpl) Parse(yylex yyLexer) int { + var yyn int + var yyVAL yySymType + var yyDollar []yySymType + _ = yyDollar // silence set and not used + yyS := yyrcvr.stack[:] + + Nerrs := 0 /* number of errors */ + Errflag := 0 /* error recovery flag */ + yystate := 0 + yyrcvr.char = -1 + yytoken := -1 // yyrcvr.char translated into internal numbering + defer func() { + // Make sure we report no lookahead when not parsing. + yystate = -1 + yyrcvr.char = -1 + yytoken = -1 + }() + yyp := -1 + goto yystack + +ret0: + return 0 + +ret1: + return 1 + +yystack: + /* put a state and value onto the stack */ + if yyDebug >= 4 { + __yyfmt__.Printf("char %v in %v\n", yyTokname(yytoken), yyStatname(yystate)) + } + + yyp++ + if yyp >= len(yyS) { + nyys := make([]yySymType, len(yyS)*2) + copy(nyys, yyS) + yyS = nyys + } + yyS[yyp] = yyVAL + yyS[yyp].yys = yystate + +yynewstate: + yyn = yyPact[yystate] + if yyn <= yyFlag { + goto yydefault /* simple state */ + } + if yyrcvr.char < 0 { + yyrcvr.char, yytoken = yylex1(yylex, &yyrcvr.lval) + } + yyn += yytoken + if yyn < 0 || yyn >= yyLast { + goto yydefault + } + yyn = yyAct[yyn] + if yyChk[yyn] == yytoken { /* valid shift */ + yyrcvr.char = -1 + yytoken = -1 + yyVAL = yyrcvr.lval + yystate = yyn + if Errflag > 0 { + Errflag-- + } + goto yystack + } + +yydefault: + /* default state action */ + yyn = yyDef[yystate] + if yyn == -2 { + if yyrcvr.char < 0 { + yyrcvr.char, yytoken = yylex1(yylex, &yyrcvr.lval) + } + + /* look through exception table */ + xi := 0 + for { + if yyExca[xi+0] == -1 && yyExca[xi+1] == yystate { + break + } + xi += 2 + } + for xi += 2; ; xi += 2 { + yyn = yyExca[xi+0] + if yyn < 0 || yyn == yytoken { + break + } + } + yyn = yyExca[xi+1] + if yyn < 0 { + goto ret0 + } + } + if yyn == 0 { + /* error ... attempt to resume parsing */ + switch Errflag { + case 0: /* brand new error */ + yylex.Error(yyErrorMessage(yystate, yytoken)) + Nerrs++ + if yyDebug >= 1 { + __yyfmt__.Printf("%s", yyStatname(yystate)) + __yyfmt__.Printf(" saw %s\n", yyTokname(yytoken)) + } + fallthrough + + case 1, 2: /* incompletely recovered error ... try again */ + Errflag = 3 + + /* find a state where "error" is a legal shift action */ + for yyp >= 0 { + yyn = yyPact[yyS[yyp].yys] + yyErrCode + if yyn >= 0 && yyn < yyLast { + yystate = yyAct[yyn] /* simulate a shift of "error" */ + if yyChk[yystate] == yyErrCode { + goto yystack + } + } + + /* the current p has no shift on "error", pop stack */ + if yyDebug >= 2 { + __yyfmt__.Printf("error recovery pops state %d\n", yyS[yyp].yys) + } + yyp-- + } + /* there is no state on the stack with an error shift ... abort */ + goto ret1 + + case 3: /* no shift yet; clobber input char */ + if yyDebug >= 2 { + __yyfmt__.Printf("error recovery discards %s\n", yyTokname(yytoken)) + } + if yytoken == yyEofCode { + goto ret1 + } + yyrcvr.char = -1 + yytoken = -1 + goto yynewstate /* try again in the same state */ + } + } + + /* reduction by production yyn */ + if yyDebug >= 2 { + __yyfmt__.Printf("reduce %v in:\n\t%v\n", yyn, yyStatname(yystate)) + } + + yynt := yyn + yypt := yyp + _ = yypt // guard against "declared and not used" + + yyp -= yyR2[yyn] + // yyp is now the index of $0. Perform the default action. Iff the + // reduced production is ε, $1 is possibly out of range. + if yyp+1 >= len(yyS) { + nyys := make([]yySymType, len(yyS)*2) + copy(nyys, yyS) + yyS = nyys + } + yyVAL = yyS[yyp+1] + + /* consult goto table to find next state */ + yyn = yyR1[yyn] + yyg := yyPgo[yyn] + yyj := yyg + yyS[yyp].yys + 1 + + if yyj >= yyLast { + yystate = yyAct[yyg] + } else { + yystate = yyAct[yyj] + if yyChk[yystate] != -yyn { + yystate = yyAct[yyg] + } + } + // dummy call; replaced with literal code + switch yynt { + + case 1: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:302 + { + setParseTree(yylex, yyDollar[1].statement) + } + case 2: + yyDollar = yyS[yypt-0 : yypt+1] + //line sql.y:307 + { + } + case 3: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:308 + { + } + case 4: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:312 + { + yyVAL.statement = yyDollar[1].selStmt + } + case 22: + yyDollar = yyS[yypt-4 : yypt+1] + //line sql.y:335 + { + sel := yyDollar[1].selStmt.(*Select) + sel.OrderBy = yyDollar[2].orderBy + sel.Limit = yyDollar[3].limit + sel.Lock = yyDollar[4].str + yyVAL.selStmt = sel + } + case 23: + yyDollar = yyS[yypt-6 : yypt+1] + //line sql.y:343 + { + yyVAL.selStmt = &Union{Type: yyDollar[2].str, Left: yyDollar[1].selStmt, Right: yyDollar[3].selStmt, OrderBy: yyDollar[4].orderBy, Limit: yyDollar[5].limit, Lock: yyDollar[6].str} + } + case 24: + yyDollar = yyS[yypt-7 : yypt+1] + //line sql.y:347 + { + yyVAL.selStmt = &Select{Comments: Comments(yyDollar[2].bytes2), Cache: yyDollar[3].str, SelectExprs: SelectExprs{Nextval{Expr: yyDollar[5].expr}}, From: TableExprs{&AliasedTableExpr{Expr: yyDollar[7].tableName}}} + } + case 25: + yyDollar = yyS[yypt-5 : yypt+1] + //line sql.y:353 + { + yyVAL.statement = &Stream{Comments: Comments(yyDollar[2].bytes2), SelectExpr: yyDollar[3].selectExpr, Table: yyDollar[5].tableName} + } + case 26: + yyDollar = yyS[yypt-10 : yypt+1] + //line sql.y:360 + { + yyVAL.selStmt = &Select{Comments: Comments(yyDollar[2].bytes2), Cache: yyDollar[3].str, Distinct: yyDollar[4].str, Hints: yyDollar[5].str, SelectExprs: yyDollar[6].selectExprs, From: yyDollar[7].tableExprs, Where: NewWhere(WhereStr, yyDollar[8].expr), GroupBy: GroupBy(yyDollar[9].exprs), Having: NewWhere(HavingStr, yyDollar[10].expr)} + } + case 27: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:366 + { + yyVAL.selStmt = yyDollar[1].selStmt + } + case 28: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:370 + { + yyVAL.selStmt = &ParenSelect{Select: yyDollar[2].selStmt} + } + case 29: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:376 + { + yyVAL.selStmt = yyDollar[1].selStmt + } + case 30: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:380 + { + yyVAL.selStmt = &ParenSelect{Select: yyDollar[2].selStmt} + } + case 31: + yyDollar = yyS[yypt-7 : yypt+1] + //line sql.y:387 + { + // insert_data returns a *Insert pre-filled with Columns & Values + ins := yyDollar[6].ins + ins.Action = yyDollar[1].str + ins.Comments = yyDollar[2].bytes2 + ins.Ignore = yyDollar[3].str + ins.Table = yyDollar[4].tableName + ins.Partitions = yyDollar[5].partitions + ins.OnDup = OnDup(yyDollar[7].updateExprs) + yyVAL.statement = ins + } + case 32: + yyDollar = yyS[yypt-8 : yypt+1] + //line sql.y:399 + { + cols := make(Columns, 0, len(yyDollar[7].updateExprs)) + vals := make(ValTuple, 0, len(yyDollar[8].updateExprs)) + for _, updateList := range yyDollar[7].updateExprs { + cols = append(cols, updateList.Name.Name) + vals = append(vals, updateList.Expr) + } + yyVAL.statement = &Insert{Action: yyDollar[1].str, Comments: Comments(yyDollar[2].bytes2), Ignore: yyDollar[3].str, Table: yyDollar[4].tableName, Partitions: yyDollar[5].partitions, Columns: cols, Rows: Values{vals}, OnDup: OnDup(yyDollar[8].updateExprs)} + } + case 33: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:411 + { + yyVAL.str = InsertStr + } + case 34: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:415 + { + yyVAL.str = ReplaceStr + } + case 35: + yyDollar = yyS[yypt-8 : yypt+1] + //line sql.y:421 + { + yyVAL.statement = &Update{Comments: Comments(yyDollar[2].bytes2), TableExprs: yyDollar[3].tableExprs, Exprs: yyDollar[5].updateExprs, Where: NewWhere(WhereStr, yyDollar[6].expr), OrderBy: yyDollar[7].orderBy, Limit: yyDollar[8].limit} + } + case 36: + yyDollar = yyS[yypt-8 : yypt+1] + //line sql.y:427 + { + yyVAL.statement = &Delete{Comments: Comments(yyDollar[2].bytes2), TableExprs: TableExprs{&AliasedTableExpr{Expr: yyDollar[4].tableName}}, Partitions: yyDollar[5].partitions, Where: NewWhere(WhereStr, yyDollar[6].expr), OrderBy: yyDollar[7].orderBy, Limit: yyDollar[8].limit} + } + case 37: + yyDollar = yyS[yypt-7 : yypt+1] + //line sql.y:431 + { + yyVAL.statement = &Delete{Comments: Comments(yyDollar[2].bytes2), Targets: yyDollar[4].tableNames, TableExprs: yyDollar[6].tableExprs, Where: NewWhere(WhereStr, yyDollar[7].expr)} + } + case 38: + yyDollar = yyS[yypt-6 : yypt+1] + //line sql.y:435 + { + yyVAL.statement = &Delete{Comments: Comments(yyDollar[2].bytes2), Targets: yyDollar[3].tableNames, TableExprs: yyDollar[5].tableExprs, Where: NewWhere(WhereStr, yyDollar[6].expr)} + } + case 39: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:440 + { + } + case 40: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:441 + { + } + case 41: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:445 + { + yyVAL.tableNames = TableNames{yyDollar[1].tableName} + } + case 42: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:449 + { + yyVAL.tableNames = append(yyVAL.tableNames, yyDollar[3].tableName) + } + case 43: + yyDollar = yyS[yypt-0 : yypt+1] + //line sql.y:454 + { + yyVAL.partitions = nil + } + case 44: + yyDollar = yyS[yypt-4 : yypt+1] + //line sql.y:458 + { + yyVAL.partitions = yyDollar[3].partitions + } + case 45: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:464 + { + yyVAL.statement = &Set{Comments: Comments(yyDollar[2].bytes2), Exprs: yyDollar[3].setExprs} + } + case 46: + yyDollar = yyS[yypt-4 : yypt+1] + //line sql.y:468 + { + yyVAL.statement = &Set{Comments: Comments(yyDollar[2].bytes2), Scope: yyDollar[3].str, Exprs: yyDollar[4].setExprs} + } + case 47: + yyDollar = yyS[yypt-5 : yypt+1] + //line sql.y:472 + { + yyVAL.statement = &Set{Comments: Comments(yyDollar[2].bytes2), Scope: yyDollar[3].str, Exprs: yyDollar[5].setExprs} + } + case 48: + yyDollar = yyS[yypt-4 : yypt+1] + //line sql.y:476 + { + yyVAL.statement = &Set{Comments: Comments(yyDollar[2].bytes2), Exprs: yyDollar[4].setExprs} + } + case 49: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:482 + { + yyVAL.setExprs = SetExprs{yyDollar[1].setExpr} + } + case 50: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:486 + { + yyVAL.setExprs = append(yyVAL.setExprs, yyDollar[3].setExpr) + } + case 51: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:492 + { + yyVAL.setExpr = yyDollar[3].setExpr + } + case 52: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:496 + { + yyVAL.setExpr = &SetExpr{Name: NewColIdent("tx_read_only"), Expr: NewIntVal([]byte("0"))} + } + case 53: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:500 + { + yyVAL.setExpr = &SetExpr{Name: NewColIdent("tx_read_only"), Expr: NewIntVal([]byte("1"))} + } + case 54: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:506 + { + yyVAL.setExpr = &SetExpr{Name: NewColIdent("tx_isolation"), Expr: NewStrVal([]byte("repeatable read"))} + } + case 55: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:510 + { + yyVAL.setExpr = &SetExpr{Name: NewColIdent("tx_isolation"), Expr: NewStrVal([]byte("read committed"))} + } + case 56: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:514 + { + yyVAL.setExpr = &SetExpr{Name: NewColIdent("tx_isolation"), Expr: NewStrVal([]byte("read uncommitted"))} + } + case 57: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:518 + { + yyVAL.setExpr = &SetExpr{Name: NewColIdent("tx_isolation"), Expr: NewStrVal([]byte("serializable"))} + } + case 58: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:524 + { + yyVAL.str = SessionStr + } + case 59: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:528 + { + yyVAL.str = GlobalStr + } + case 60: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:534 + { + yyDollar[1].ddl.TableSpec = yyDollar[2].TableSpec + yyVAL.statement = yyDollar[1].ddl + } + case 61: + yyDollar = yyS[yypt-8 : yypt+1] + //line sql.y:539 + { + // Change this to an alter statement + yyVAL.statement = &DDL{Action: AlterStr, Table: yyDollar[7].tableName, NewName: yyDollar[7].tableName} + } + case 62: + yyDollar = yyS[yypt-4 : yypt+1] + //line sql.y:544 + { + yyVAL.statement = &DDL{Action: CreateStr, NewName: yyDollar[3].tableName.ToViewName()} + } + case 63: + yyDollar = yyS[yypt-6 : yypt+1] + //line sql.y:548 + { + yyVAL.statement = &DDL{Action: CreateStr, NewName: yyDollar[5].tableName.ToViewName()} + } + case 64: + yyDollar = yyS[yypt-5 : yypt+1] + //line sql.y:552 + { + yyVAL.statement = &DDL{Action: CreateVindexStr, VindexSpec: &VindexSpec{ + Name: yyDollar[3].colIdent, + Type: yyDollar[4].colIdent, + Params: yyDollar[5].vindexParams, + }} + } + case 65: + yyDollar = yyS[yypt-5 : yypt+1] + //line sql.y:560 + { + yyVAL.statement = &DBDDL{Action: CreateStr, DBName: string(yyDollar[4].bytes)} + } + case 66: + yyDollar = yyS[yypt-5 : yypt+1] + //line sql.y:564 + { + yyVAL.statement = &DBDDL{Action: CreateStr, DBName: string(yyDollar[4].bytes)} + } + case 67: + yyDollar = yyS[yypt-0 : yypt+1] + //line sql.y:569 + { + yyVAL.colIdent = NewColIdent("") + } + case 68: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:573 + { + yyVAL.colIdent = yyDollar[2].colIdent + } + case 69: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:579 + { + yyVAL.colIdent = NewColIdent(string(yyDollar[1].bytes)) + } + case 70: + yyDollar = yyS[yypt-0 : yypt+1] + //line sql.y:584 + { + var v []VindexParam + yyVAL.vindexParams = v + } + case 71: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:589 + { + yyVAL.vindexParams = yyDollar[2].vindexParams + } + case 72: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:595 + { + yyVAL.vindexParams = make([]VindexParam, 0, 4) + yyVAL.vindexParams = append(yyVAL.vindexParams, yyDollar[1].vindexParam) + } + case 73: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:600 + { + yyVAL.vindexParams = append(yyVAL.vindexParams, yyDollar[3].vindexParam) + } + case 74: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:606 + { + yyVAL.vindexParam = VindexParam{Key: yyDollar[1].colIdent, Val: yyDollar[3].str} + } + case 75: + yyDollar = yyS[yypt-4 : yypt+1] + //line sql.y:612 + { + yyVAL.ddl = &DDL{Action: CreateStr, NewName: yyDollar[4].tableName} + setDDL(yylex, yyVAL.ddl) + } + case 76: + yyDollar = yyS[yypt-4 : yypt+1] + //line sql.y:619 + { + yyVAL.TableSpec = yyDollar[2].TableSpec + yyVAL.TableSpec.Options = yyDollar[4].str + } + case 77: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:626 + { + yyVAL.TableSpec = &TableSpec{} + yyVAL.TableSpec.AddColumn(yyDollar[1].columnDefinition) + } + case 78: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:631 + { + yyVAL.TableSpec.AddColumn(yyDollar[3].columnDefinition) + } + case 79: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:635 + { + yyVAL.TableSpec.AddIndex(yyDollar[3].indexDefinition) + } + case 80: + yyDollar = yyS[yypt-8 : yypt+1] + //line sql.y:641 + { + yyDollar[2].columnType.NotNull = yyDollar[3].boolVal + yyDollar[2].columnType.Default = yyDollar[4].optVal + yyDollar[2].columnType.OnUpdate = yyDollar[5].optVal + yyDollar[2].columnType.Autoincrement = yyDollar[6].boolVal + yyDollar[2].columnType.KeyOpt = yyDollar[7].colKeyOpt + yyDollar[2].columnType.Comment = yyDollar[8].optVal + yyVAL.columnDefinition = &ColumnDefinition{Name: NewColIdent(string(yyDollar[1].bytes)), Type: yyDollar[2].columnType} + } + case 81: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:652 + { + yyVAL.columnType = yyDollar[1].columnType + yyVAL.columnType.Unsigned = yyDollar[2].boolVal + yyVAL.columnType.Zerofill = yyDollar[3].boolVal + } + case 85: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:663 + { + yyVAL.columnType = yyDollar[1].columnType + yyVAL.columnType.Length = yyDollar[2].optVal + } + case 86: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:668 + { + yyVAL.columnType = yyDollar[1].columnType + } + case 87: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:674 + { + yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} + } + case 88: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:678 + { + yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} + } + case 89: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:682 + { + yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} + } + case 90: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:686 + { + yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} + } + case 91: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:690 + { + yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} + } + case 92: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:694 + { + yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} + } + case 93: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:698 + { + yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} + } + case 94: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:704 + { + yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} + yyVAL.columnType.Length = yyDollar[2].LengthScaleOption.Length + yyVAL.columnType.Scale = yyDollar[2].LengthScaleOption.Scale + } + case 95: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:710 + { + yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} + yyVAL.columnType.Length = yyDollar[2].LengthScaleOption.Length + yyVAL.columnType.Scale = yyDollar[2].LengthScaleOption.Scale + } + case 96: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:716 + { + yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} + yyVAL.columnType.Length = yyDollar[2].LengthScaleOption.Length + yyVAL.columnType.Scale = yyDollar[2].LengthScaleOption.Scale + } + case 97: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:722 + { + yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} + yyVAL.columnType.Length = yyDollar[2].LengthScaleOption.Length + yyVAL.columnType.Scale = yyDollar[2].LengthScaleOption.Scale + } + case 98: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:728 + { + yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} + yyVAL.columnType.Length = yyDollar[2].LengthScaleOption.Length + yyVAL.columnType.Scale = yyDollar[2].LengthScaleOption.Scale + } + case 99: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:736 + { + yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} + } + case 100: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:740 + { + yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes), Length: yyDollar[2].optVal} + } + case 101: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:744 + { + yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes), Length: yyDollar[2].optVal} + } + case 102: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:748 + { + yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes), Length: yyDollar[2].optVal} + } + case 103: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:752 + { + yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} + } + case 104: + yyDollar = yyS[yypt-4 : yypt+1] + //line sql.y:758 + { + yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes), Length: yyDollar[2].optVal, Charset: yyDollar[3].str, Collate: yyDollar[4].str} + } + case 105: + yyDollar = yyS[yypt-4 : yypt+1] + //line sql.y:762 + { + yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes), Length: yyDollar[2].optVal, Charset: yyDollar[3].str, Collate: yyDollar[4].str} + } + case 106: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:766 + { + yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes), Length: yyDollar[2].optVal} + } + case 107: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:770 + { + yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes), Length: yyDollar[2].optVal} + } + case 108: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:774 + { + yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes), Charset: yyDollar[2].str, Collate: yyDollar[3].str} + } + case 109: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:778 + { + yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes), Charset: yyDollar[2].str, Collate: yyDollar[3].str} + } + case 110: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:782 + { + yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes), Charset: yyDollar[2].str, Collate: yyDollar[3].str} + } + case 111: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:786 + { + yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes), Charset: yyDollar[2].str, Collate: yyDollar[3].str} + } + case 112: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:790 + { + yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} + } + case 113: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:794 + { + yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} + } + case 114: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:798 + { + yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} + } + case 115: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:802 + { + yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} + } + case 116: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:806 + { + yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} + } + case 117: + yyDollar = yyS[yypt-6 : yypt+1] + //line sql.y:810 + { + yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes), EnumValues: yyDollar[3].strs, Charset: yyDollar[5].str, Collate: yyDollar[6].str} + } + case 118: + yyDollar = yyS[yypt-6 : yypt+1] + //line sql.y:815 + { + yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes), EnumValues: yyDollar[3].strs, Charset: yyDollar[5].str, Collate: yyDollar[6].str} + } + case 119: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:821 + { + yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} + } + case 120: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:825 + { + yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} + } + case 121: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:829 + { + yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} + } + case 122: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:833 + { + yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} + } + case 123: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:837 + { + yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} + } + case 124: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:841 + { + yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} + } + case 125: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:845 + { + yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} + } + case 126: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:849 + { + yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} + } + case 127: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:855 + { + yyVAL.strs = make([]string, 0, 4) + yyVAL.strs = append(yyVAL.strs, "'"+string(yyDollar[1].bytes)+"'") + } + case 128: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:860 + { + yyVAL.strs = append(yyDollar[1].strs, "'"+string(yyDollar[3].bytes)+"'") + } + case 129: + yyDollar = yyS[yypt-0 : yypt+1] + //line sql.y:865 + { + yyVAL.optVal = nil + } + case 130: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:869 + { + yyVAL.optVal = NewIntVal(yyDollar[2].bytes) + } + case 131: + yyDollar = yyS[yypt-0 : yypt+1] + //line sql.y:874 + { + yyVAL.LengthScaleOption = LengthScaleOption{} + } + case 132: + yyDollar = yyS[yypt-5 : yypt+1] + //line sql.y:878 + { + yyVAL.LengthScaleOption = LengthScaleOption{ + Length: NewIntVal(yyDollar[2].bytes), + Scale: NewIntVal(yyDollar[4].bytes), + } + } + case 133: + yyDollar = yyS[yypt-0 : yypt+1] + //line sql.y:886 + { + yyVAL.LengthScaleOption = LengthScaleOption{} + } + case 134: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:890 + { + yyVAL.LengthScaleOption = LengthScaleOption{ + Length: NewIntVal(yyDollar[2].bytes), + } + } + case 135: + yyDollar = yyS[yypt-5 : yypt+1] + //line sql.y:896 + { + yyVAL.LengthScaleOption = LengthScaleOption{ + Length: NewIntVal(yyDollar[2].bytes), + Scale: NewIntVal(yyDollar[4].bytes), + } + } + case 136: + yyDollar = yyS[yypt-0 : yypt+1] + //line sql.y:904 + { + yyVAL.boolVal = BoolVal(false) + } + case 137: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:908 + { + yyVAL.boolVal = BoolVal(true) + } + case 138: + yyDollar = yyS[yypt-0 : yypt+1] + //line sql.y:913 + { + yyVAL.boolVal = BoolVal(false) + } + case 139: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:917 + { + yyVAL.boolVal = BoolVal(true) + } + case 140: + yyDollar = yyS[yypt-0 : yypt+1] + //line sql.y:923 + { + yyVAL.boolVal = BoolVal(false) + } + case 141: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:927 + { + yyVAL.boolVal = BoolVal(false) + } + case 142: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:931 + { + yyVAL.boolVal = BoolVal(true) + } + case 143: + yyDollar = yyS[yypt-0 : yypt+1] + //line sql.y:936 + { + yyVAL.optVal = nil + } + case 144: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:940 + { + yyVAL.optVal = NewStrVal(yyDollar[2].bytes) + } + case 145: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:944 + { + yyVAL.optVal = NewIntVal(yyDollar[2].bytes) + } + case 146: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:948 + { + yyVAL.optVal = NewFloatVal(yyDollar[2].bytes) + } + case 147: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:952 + { + yyVAL.optVal = NewValArg(yyDollar[2].bytes) + } + case 148: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:956 + { + yyVAL.optVal = NewValArg(yyDollar[2].bytes) + } + case 149: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:960 + { + yyVAL.optVal = NewBitVal(yyDollar[2].bytes) + } + case 150: + yyDollar = yyS[yypt-0 : yypt+1] + //line sql.y:965 + { + yyVAL.optVal = nil + } + case 151: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:969 + { + yyVAL.optVal = NewValArg(yyDollar[3].bytes) + } + case 152: + yyDollar = yyS[yypt-0 : yypt+1] + //line sql.y:974 + { + yyVAL.boolVal = BoolVal(false) + } + case 153: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:978 + { + yyVAL.boolVal = BoolVal(true) + } + case 154: + yyDollar = yyS[yypt-0 : yypt+1] + //line sql.y:983 + { + yyVAL.str = "" + } + case 155: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:987 + { + yyVAL.str = string(yyDollar[3].bytes) + } + case 156: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:991 + { + yyVAL.str = string(yyDollar[3].bytes) + } + case 157: + yyDollar = yyS[yypt-0 : yypt+1] + //line sql.y:996 + { + yyVAL.str = "" + } + case 158: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:1000 + { + yyVAL.str = string(yyDollar[2].bytes) + } + case 159: + yyDollar = yyS[yypt-0 : yypt+1] + //line sql.y:1005 + { + yyVAL.colKeyOpt = colKeyNone + } + case 160: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:1009 + { + yyVAL.colKeyOpt = colKeyPrimary + } + case 161: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:1013 + { + yyVAL.colKeyOpt = colKey + } + case 162: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:1017 + { + yyVAL.colKeyOpt = colKeyUniqueKey + } + case 163: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:1021 + { + yyVAL.colKeyOpt = colKeyUnique + } + case 164: + yyDollar = yyS[yypt-0 : yypt+1] + //line sql.y:1026 + { + yyVAL.optVal = nil + } + case 165: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:1030 + { + yyVAL.optVal = NewStrVal(yyDollar[2].bytes) + } + case 166: + yyDollar = yyS[yypt-5 : yypt+1] + //line sql.y:1036 + { + yyVAL.indexDefinition = &IndexDefinition{Info: yyDollar[1].indexInfo, Columns: yyDollar[3].indexColumns, Options: yyDollar[5].indexOptions} + } + case 167: + yyDollar = yyS[yypt-4 : yypt+1] + //line sql.y:1040 + { + yyVAL.indexDefinition = &IndexDefinition{Info: yyDollar[1].indexInfo, Columns: yyDollar[3].indexColumns} + } + case 168: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:1046 + { + yyVAL.indexOptions = []*IndexOption{yyDollar[1].indexOption} + } + case 169: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:1050 + { + yyVAL.indexOptions = append(yyVAL.indexOptions, yyDollar[2].indexOption) + } + case 170: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:1056 + { + yyVAL.indexOption = &IndexOption{Name: string(yyDollar[1].bytes), Using: string(yyDollar[2].bytes)} + } + case 171: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:1060 + { + // should not be string + yyVAL.indexOption = &IndexOption{Name: string(yyDollar[1].bytes), Value: NewIntVal(yyDollar[3].bytes)} + } + case 172: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:1065 + { + yyVAL.indexOption = &IndexOption{Name: string(yyDollar[1].bytes), Value: NewStrVal(yyDollar[2].bytes)} + } + case 173: + yyDollar = yyS[yypt-0 : yypt+1] + //line sql.y:1071 + { + yyVAL.str = "" + } + case 174: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:1075 + { + yyVAL.str = string(yyDollar[1].bytes) + } + case 175: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:1081 + { + yyVAL.indexInfo = &IndexInfo{Type: string(yyDollar[1].bytes) + " " + string(yyDollar[2].bytes), Name: NewColIdent("PRIMARY"), Primary: true, Unique: true} + } + case 176: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:1085 + { + yyVAL.indexInfo = &IndexInfo{Type: string(yyDollar[1].bytes) + " " + string(yyDollar[2].str), Name: NewColIdent(string(yyDollar[3].bytes)), Spatial: true, Unique: false} + } + case 177: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:1089 + { + yyVAL.indexInfo = &IndexInfo{Type: string(yyDollar[1].bytes) + " " + string(yyDollar[2].str), Name: NewColIdent(string(yyDollar[3].bytes)), Unique: true} + } + case 178: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:1093 + { + yyVAL.indexInfo = &IndexInfo{Type: string(yyDollar[1].bytes), Name: NewColIdent(string(yyDollar[2].bytes)), Unique: true} + } + case 179: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:1097 + { + yyVAL.indexInfo = &IndexInfo{Type: string(yyDollar[1].str), Name: NewColIdent(string(yyDollar[2].bytes)), Unique: false} + } + case 180: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:1103 + { + yyVAL.str = string(yyDollar[1].bytes) + } + case 181: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:1107 + { + yyVAL.str = string(yyDollar[1].bytes) + } + case 182: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:1113 + { + yyVAL.indexColumns = []*IndexColumn{yyDollar[1].indexColumn} + } + case 183: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:1117 + { + yyVAL.indexColumns = append(yyVAL.indexColumns, yyDollar[3].indexColumn) + } + case 184: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:1123 + { + yyVAL.indexColumn = &IndexColumn{Column: yyDollar[1].colIdent, Length: yyDollar[2].optVal} + } + case 185: + yyDollar = yyS[yypt-0 : yypt+1] + //line sql.y:1128 + { + yyVAL.str = "" + } + case 186: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:1132 + { + yyVAL.str = " " + string(yyDollar[1].str) + } + case 187: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:1136 + { + yyVAL.str = string(yyDollar[1].str) + ", " + string(yyDollar[3].str) + } + case 188: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:1144 + { + yyVAL.str = yyDollar[1].str + } + case 189: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:1148 + { + yyVAL.str = yyDollar[1].str + " " + yyDollar[2].str + } + case 190: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:1152 + { + yyVAL.str = yyDollar[1].str + "=" + yyDollar[3].str + } + case 191: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:1158 + { + yyVAL.str = yyDollar[1].colIdent.String() + } + case 192: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:1162 + { + yyVAL.str = "'" + string(yyDollar[1].bytes) + "'" + } + case 193: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:1166 + { + yyVAL.str = string(yyDollar[1].bytes) + } + case 194: + yyDollar = yyS[yypt-6 : yypt+1] + //line sql.y:1172 + { + yyVAL.statement = &DDL{Action: AlterStr, Table: yyDollar[4].tableName, NewName: yyDollar[4].tableName} + } + case 195: + yyDollar = yyS[yypt-7 : yypt+1] + //line sql.y:1176 + { + yyVAL.statement = &DDL{Action: AlterStr, Table: yyDollar[4].tableName, NewName: yyDollar[4].tableName} + } + case 196: + yyDollar = yyS[yypt-7 : yypt+1] + //line sql.y:1180 + { + yyVAL.statement = &DDL{Action: AlterStr, Table: yyDollar[4].tableName, NewName: yyDollar[4].tableName} + } + case 197: + yyDollar = yyS[yypt-12 : yypt+1] + //line sql.y:1184 + { + yyVAL.statement = &DDL{ + Action: AddColVindexStr, + Table: yyDollar[4].tableName, + VindexSpec: &VindexSpec{ + Name: yyDollar[7].colIdent, + Type: yyDollar[11].colIdent, + Params: yyDollar[12].vindexParams, + }, + VindexCols: yyDollar[9].columns, + } + } + case 198: + yyDollar = yyS[yypt-7 : yypt+1] + //line sql.y:1197 + { + yyVAL.statement = &DDL{ + Action: DropColVindexStr, + Table: yyDollar[4].tableName, + VindexSpec: &VindexSpec{ + Name: yyDollar[7].colIdent, + }, + } + } + case 199: + yyDollar = yyS[yypt-7 : yypt+1] + //line sql.y:1207 + { + // Change this to a rename statement + yyVAL.statement = &DDL{Action: RenameStr, Table: yyDollar[4].tableName, NewName: yyDollar[7].tableName} + } + case 200: + yyDollar = yyS[yypt-7 : yypt+1] + //line sql.y:1212 + { + // Rename an index can just be an alter + yyVAL.statement = &DDL{Action: AlterStr, Table: yyDollar[4].tableName, NewName: yyDollar[4].tableName} + } + case 201: + yyDollar = yyS[yypt-4 : yypt+1] + //line sql.y:1217 + { + yyVAL.statement = &DDL{Action: AlterStr, Table: yyDollar[3].tableName.ToViewName(), NewName: yyDollar[3].tableName.ToViewName()} + } + case 202: + yyDollar = yyS[yypt-5 : yypt+1] + //line sql.y:1221 + { + yyVAL.statement = &DDL{Action: AlterStr, Table: yyDollar[4].tableName, PartitionSpec: yyDollar[5].partSpec} + } + case 214: + yyDollar = yyS[yypt-7 : yypt+1] + //line sql.y:1240 + { + yyVAL.partSpec = &PartitionSpec{Action: ReorganizeStr, Name: yyDollar[3].colIdent, Definitions: yyDollar[6].partDefs} + } + case 215: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:1246 + { + yyVAL.partDefs = []*PartitionDefinition{yyDollar[1].partDef} + } + case 216: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:1250 + { + yyVAL.partDefs = append(yyDollar[1].partDefs, yyDollar[3].partDef) + } + case 217: + yyDollar = yyS[yypt-8 : yypt+1] + //line sql.y:1256 + { + yyVAL.partDef = &PartitionDefinition{Name: yyDollar[2].colIdent, Limit: yyDollar[7].expr} + } + case 218: + yyDollar = yyS[yypt-8 : yypt+1] + //line sql.y:1260 + { + yyVAL.partDef = &PartitionDefinition{Name: yyDollar[2].colIdent, Maxvalue: true} + } + case 219: + yyDollar = yyS[yypt-5 : yypt+1] + //line sql.y:1266 + { + yyVAL.statement = &DDL{Action: RenameStr, Table: yyDollar[3].tableName, NewName: yyDollar[5].tableName} + } + case 220: + yyDollar = yyS[yypt-4 : yypt+1] + //line sql.y:1272 + { + var exists bool + if yyDollar[3].byt != 0 { + exists = true + } + yyVAL.statement = &DDL{Action: DropStr, Table: yyDollar[4].tableName, IfExists: exists} + } + case 221: + yyDollar = yyS[yypt-6 : yypt+1] + //line sql.y:1280 + { + // Change this to an alter statement + yyVAL.statement = &DDL{Action: AlterStr, Table: yyDollar[5].tableName, NewName: yyDollar[5].tableName} + } + case 222: + yyDollar = yyS[yypt-5 : yypt+1] + //line sql.y:1285 + { + var exists bool + if yyDollar[3].byt != 0 { + exists = true + } + yyVAL.statement = &DDL{Action: DropStr, Table: yyDollar[4].tableName.ToViewName(), IfExists: exists} + } + case 223: + yyDollar = yyS[yypt-4 : yypt+1] + //line sql.y:1293 + { + yyVAL.statement = &DBDDL{Action: DropStr, DBName: string(yyDollar[4].bytes)} + } + case 224: + yyDollar = yyS[yypt-4 : yypt+1] + //line sql.y:1297 + { + yyVAL.statement = &DBDDL{Action: DropStr, DBName: string(yyDollar[4].bytes)} + } + case 225: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:1303 + { + yyVAL.statement = &DDL{Action: TruncateStr, Table: yyDollar[3].tableName} + } + case 226: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:1307 + { + yyVAL.statement = &DDL{Action: TruncateStr, Table: yyDollar[2].tableName} + } + case 227: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:1312 + { + yyVAL.statement = &DDL{Action: AlterStr, Table: yyDollar[3].tableName, NewName: yyDollar[3].tableName} + } + case 228: + yyDollar = yyS[yypt-4 : yypt+1] + //line sql.y:1318 + { + yyVAL.statement = &Show{Type: string(yyDollar[2].bytes) + " " + string(yyDollar[3].bytes)} + } + case 229: + yyDollar = yyS[yypt-4 : yypt+1] + //line sql.y:1322 + { + yyVAL.statement = &Show{Type: string(yyDollar[2].bytes) + " " + string(yyDollar[3].bytes)} + } + case 230: + yyDollar = yyS[yypt-4 : yypt+1] + //line sql.y:1326 + { + yyVAL.statement = &Show{Type: string(yyDollar[2].bytes) + " " + string(yyDollar[3].bytes)} + } + case 231: + yyDollar = yyS[yypt-4 : yypt+1] + //line sql.y:1331 + { + yyVAL.statement = &Show{Type: string(yyDollar[2].bytes) + " " + string(yyDollar[3].bytes)} + } + case 232: + yyDollar = yyS[yypt-4 : yypt+1] + //line sql.y:1335 + { + yyVAL.statement = &Show{Type: string(yyDollar[2].bytes) + " " + string(yyDollar[3].bytes)} + } + case 233: + yyDollar = yyS[yypt-4 : yypt+1] + //line sql.y:1339 + { + yyVAL.statement = &Show{Type: string(yyDollar[2].bytes) + " " + string(yyDollar[3].bytes)} + } + case 234: + yyDollar = yyS[yypt-4 : yypt+1] + //line sql.y:1343 + { + yyVAL.statement = &Show{Type: string(yyDollar[2].bytes) + " " + string(yyDollar[3].bytes)} + } + case 235: + yyDollar = yyS[yypt-4 : yypt+1] + //line sql.y:1347 + { + yyVAL.statement = &Show{Type: string(yyDollar[2].bytes) + " " + string(yyDollar[3].bytes)} + } + case 236: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:1351 + { + yyVAL.statement = &Show{Type: string(yyDollar[2].bytes)} + } + case 237: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:1355 + { + yyVAL.statement = &Show{Type: string(yyDollar[2].bytes)} + } + case 238: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:1359 + { + yyVAL.statement = &Show{Type: string(yyDollar[2].bytes)} + } + case 239: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:1363 + { + yyVAL.statement = &Show{Type: string(yyDollar[2].bytes)} + } + case 240: + yyDollar = yyS[yypt-4 : yypt+1] + //line sql.y:1367 + { + yyVAL.statement = &Show{Scope: yyDollar[2].str, Type: string(yyDollar[3].bytes)} + } + case 241: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:1371 + { + yyVAL.statement = &Show{Type: string(yyDollar[2].bytes)} + } + case 242: + yyDollar = yyS[yypt-6 : yypt+1] + //line sql.y:1375 + { + // this is ugly, but I couldn't find a better way for now + if yyDollar[4].str == "processlist" { + yyVAL.statement = &Show{Type: yyDollar[4].str} + } else { + showTablesOpt := &ShowTablesOpt{Extended: yyDollar[2].str, Full: yyDollar[3].str, DbName: yyDollar[5].str, Filter: yyDollar[6].showFilter} + yyVAL.statement = &Show{Type: yyDollar[4].str, ShowTablesOpt: showTablesOpt} + } + } + case 243: + yyDollar = yyS[yypt-4 : yypt+1] + //line sql.y:1385 + { + yyVAL.statement = &Show{Scope: yyDollar[2].str, Type: string(yyDollar[3].bytes)} + } + case 244: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:1389 + { + yyVAL.statement = &Show{Type: string(yyDollar[2].bytes)} + } + case 245: + yyDollar = yyS[yypt-4 : yypt+1] + //line sql.y:1393 + { + yyVAL.statement = &Show{Type: string(yyDollar[2].bytes), OnTable: yyDollar[4].tableName} + } + case 246: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:1397 + { + yyVAL.statement = &Show{Type: string(yyDollar[2].bytes)} + } + case 247: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:1401 + { + yyVAL.statement = &Show{Type: string(yyDollar[2].bytes)} + } + case 248: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:1405 + { + yyVAL.statement = &Show{Type: string(yyDollar[2].bytes)} + } + case 249: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:1409 + { + yyVAL.statement = &Show{Type: string(yyDollar[2].bytes)} + } + case 250: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:1419 + { + yyVAL.statement = &Show{Type: string(yyDollar[2].bytes)} + } + case 251: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:1425 + { + yyVAL.str = string(yyDollar[1].bytes) + } + case 252: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:1429 + { + yyVAL.str = string(yyDollar[1].bytes) + } + case 253: + yyDollar = yyS[yypt-0 : yypt+1] + //line sql.y:1435 + { + yyVAL.str = "" + } + case 254: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:1439 + { + yyVAL.str = "extended " + } + case 255: + yyDollar = yyS[yypt-0 : yypt+1] + //line sql.y:1445 + { + yyVAL.str = "" + } + case 256: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:1449 + { + yyVAL.str = "full " + } + case 257: + yyDollar = yyS[yypt-0 : yypt+1] + //line sql.y:1455 + { + yyVAL.str = "" + } + case 258: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:1459 + { + yyVAL.str = yyDollar[2].tableIdent.v + } + case 259: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:1463 + { + yyVAL.str = yyDollar[2].tableIdent.v + } + case 260: + yyDollar = yyS[yypt-0 : yypt+1] + //line sql.y:1469 + { + yyVAL.showFilter = nil + } + case 261: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:1473 + { + yyVAL.showFilter = &ShowFilter{Like: string(yyDollar[2].bytes)} + } + case 262: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:1477 + { + yyVAL.showFilter = &ShowFilter{Filter: yyDollar[2].expr} + } + case 263: + yyDollar = yyS[yypt-0 : yypt+1] + //line sql.y:1483 + { + yyVAL.str = "" + } + case 264: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:1487 + { + yyVAL.str = SessionStr + } + case 265: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:1491 + { + yyVAL.str = GlobalStr + } + case 266: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:1497 + { + yyVAL.statement = &Use{DBName: yyDollar[2].tableIdent} + } + case 267: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:1501 + { + yyVAL.statement = &Use{DBName: TableIdent{v: ""}} + } + case 268: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:1507 + { + yyVAL.statement = &Begin{} + } + case 269: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:1511 + { + yyVAL.statement = &Begin{} + } + case 270: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:1517 + { + yyVAL.statement = &Commit{} + } + case 271: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:1523 + { + yyVAL.statement = &Rollback{} + } + case 272: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:1529 + { + yyVAL.statement = &OtherRead{} + } + case 273: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:1533 + { + yyVAL.statement = &OtherRead{} + } + case 274: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:1537 + { + yyVAL.statement = &OtherRead{} + } + case 275: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:1541 + { + yyVAL.statement = &OtherAdmin{} + } + case 276: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:1545 + { + yyVAL.statement = &OtherAdmin{} + } + case 277: + yyDollar = yyS[yypt-0 : yypt+1] + //line sql.y:1550 + { + setAllowComments(yylex, true) + } + case 278: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:1554 + { + yyVAL.bytes2 = yyDollar[2].bytes2 + setAllowComments(yylex, false) + } + case 279: + yyDollar = yyS[yypt-0 : yypt+1] + //line sql.y:1560 + { + yyVAL.bytes2 = nil + } + case 280: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:1564 + { + yyVAL.bytes2 = append(yyDollar[1].bytes2, yyDollar[2].bytes) + } + case 281: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:1570 + { + yyVAL.str = UnionStr + } + case 282: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:1574 + { + yyVAL.str = UnionAllStr + } + case 283: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:1578 + { + yyVAL.str = UnionDistinctStr + } + case 284: + yyDollar = yyS[yypt-0 : yypt+1] + //line sql.y:1583 + { + yyVAL.str = "" + } + case 285: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:1587 + { + yyVAL.str = SQLNoCacheStr + } + case 286: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:1591 + { + yyVAL.str = SQLCacheStr + } + case 287: + yyDollar = yyS[yypt-0 : yypt+1] + //line sql.y:1596 + { + yyVAL.str = "" + } + case 288: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:1600 + { + yyVAL.str = DistinctStr + } + case 289: + yyDollar = yyS[yypt-0 : yypt+1] + //line sql.y:1605 + { + yyVAL.str = "" + } + case 290: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:1609 + { + yyVAL.str = StraightJoinHint + } + case 291: + yyDollar = yyS[yypt-0 : yypt+1] + //line sql.y:1614 + { + yyVAL.selectExprs = nil + } + case 292: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:1618 + { + yyVAL.selectExprs = yyDollar[1].selectExprs + } + case 293: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:1624 + { + yyVAL.selectExprs = SelectExprs{yyDollar[1].selectExpr} + } + case 294: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:1628 + { + yyVAL.selectExprs = append(yyVAL.selectExprs, yyDollar[3].selectExpr) + } + case 295: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:1634 + { + yyVAL.selectExpr = &StarExpr{} + } + case 296: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:1638 + { + yyVAL.selectExpr = &AliasedExpr{Expr: yyDollar[1].expr, As: yyDollar[2].colIdent} + } + case 297: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:1642 + { + yyVAL.selectExpr = &StarExpr{TableName: TableName{Name: yyDollar[1].tableIdent}} + } + case 298: + yyDollar = yyS[yypt-5 : yypt+1] + //line sql.y:1646 + { + yyVAL.selectExpr = &StarExpr{TableName: TableName{Qualifier: yyDollar[1].tableIdent, Name: yyDollar[3].tableIdent}} + } + case 299: + yyDollar = yyS[yypt-0 : yypt+1] + //line sql.y:1651 + { + yyVAL.colIdent = ColIdent{} + } + case 300: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:1655 + { + yyVAL.colIdent = yyDollar[1].colIdent + } + case 301: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:1659 + { + yyVAL.colIdent = yyDollar[2].colIdent + } + case 303: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:1666 + { + yyVAL.colIdent = NewColIdent(string(yyDollar[1].bytes)) + } + case 304: + yyDollar = yyS[yypt-0 : yypt+1] + //line sql.y:1671 + { + yyVAL.tableExprs = TableExprs{&AliasedTableExpr{Expr: TableName{Name: NewTableIdent("dual")}}} + } + case 305: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:1675 + { + yyVAL.tableExprs = yyDollar[2].tableExprs + } + case 306: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:1681 + { + yyVAL.tableExprs = TableExprs{yyDollar[1].tableExpr} + } + case 307: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:1685 + { + yyVAL.tableExprs = append(yyVAL.tableExprs, yyDollar[3].tableExpr) + } + case 310: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:1695 + { + yyVAL.tableExpr = yyDollar[1].aliasedTableName + } + case 311: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:1699 + { + yyVAL.tableExpr = &AliasedTableExpr{Expr: yyDollar[1].subquery, As: yyDollar[3].tableIdent} + } + case 312: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:1703 + { + yyVAL.tableExpr = &ParenTableExpr{Exprs: yyDollar[2].tableExprs} + } + case 313: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:1709 + { + yyVAL.aliasedTableName = &AliasedTableExpr{Expr: yyDollar[1].tableName, As: yyDollar[2].tableIdent, Hints: yyDollar[3].indexHints} + } + case 314: + yyDollar = yyS[yypt-7 : yypt+1] + //line sql.y:1713 + { + yyVAL.aliasedTableName = &AliasedTableExpr{Expr: yyDollar[1].tableName, Partitions: yyDollar[4].partitions, As: yyDollar[6].tableIdent, Hints: yyDollar[7].indexHints} + } + case 315: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:1719 + { + yyVAL.columns = Columns{yyDollar[1].colIdent} + } + case 316: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:1723 + { + yyVAL.columns = append(yyVAL.columns, yyDollar[3].colIdent) + } + case 317: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:1729 + { + yyVAL.partitions = Partitions{yyDollar[1].colIdent} + } + case 318: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:1733 + { + yyVAL.partitions = append(yyVAL.partitions, yyDollar[3].colIdent) + } + case 319: + yyDollar = yyS[yypt-4 : yypt+1] + //line sql.y:1746 + { + yyVAL.tableExpr = &JoinTableExpr{LeftExpr: yyDollar[1].tableExpr, Join: yyDollar[2].str, RightExpr: yyDollar[3].tableExpr, Condition: yyDollar[4].joinCondition} + } + case 320: + yyDollar = yyS[yypt-4 : yypt+1] + //line sql.y:1750 + { + yyVAL.tableExpr = &JoinTableExpr{LeftExpr: yyDollar[1].tableExpr, Join: yyDollar[2].str, RightExpr: yyDollar[3].tableExpr, Condition: yyDollar[4].joinCondition} + } + case 321: + yyDollar = yyS[yypt-4 : yypt+1] + //line sql.y:1754 + { + yyVAL.tableExpr = &JoinTableExpr{LeftExpr: yyDollar[1].tableExpr, Join: yyDollar[2].str, RightExpr: yyDollar[3].tableExpr, Condition: yyDollar[4].joinCondition} + } + case 322: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:1758 + { + yyVAL.tableExpr = &JoinTableExpr{LeftExpr: yyDollar[1].tableExpr, Join: yyDollar[2].str, RightExpr: yyDollar[3].tableExpr} + } + case 323: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:1764 + { + yyVAL.joinCondition = JoinCondition{On: yyDollar[2].expr} + } + case 324: + yyDollar = yyS[yypt-4 : yypt+1] + //line sql.y:1766 + { + yyVAL.joinCondition = JoinCondition{Using: yyDollar[3].columns} + } + case 325: + yyDollar = yyS[yypt-0 : yypt+1] + //line sql.y:1770 + { + yyVAL.joinCondition = JoinCondition{} + } + case 326: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:1772 + { + yyVAL.joinCondition = yyDollar[1].joinCondition + } + case 327: + yyDollar = yyS[yypt-0 : yypt+1] + //line sql.y:1776 + { + yyVAL.joinCondition = JoinCondition{} + } + case 328: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:1778 + { + yyVAL.joinCondition = JoinCondition{On: yyDollar[2].expr} + } + case 329: + yyDollar = yyS[yypt-0 : yypt+1] + //line sql.y:1781 + { + yyVAL.empty = struct{}{} + } + case 330: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:1783 + { + yyVAL.empty = struct{}{} + } + case 331: + yyDollar = yyS[yypt-0 : yypt+1] + //line sql.y:1786 + { + yyVAL.tableIdent = NewTableIdent("") + } + case 332: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:1790 + { + yyVAL.tableIdent = yyDollar[1].tableIdent + } + case 333: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:1794 + { + yyVAL.tableIdent = yyDollar[2].tableIdent + } + case 335: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:1801 + { + yyVAL.tableIdent = NewTableIdent(string(yyDollar[1].bytes)) + } + case 336: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:1807 + { + yyVAL.str = JoinStr + } + case 337: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:1811 + { + yyVAL.str = JoinStr + } + case 338: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:1815 + { + yyVAL.str = JoinStr + } + case 339: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:1821 + { + yyVAL.str = StraightJoinStr + } + case 340: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:1827 + { + yyVAL.str = LeftJoinStr + } + case 341: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:1831 + { + yyVAL.str = LeftJoinStr + } + case 342: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:1835 + { + yyVAL.str = RightJoinStr + } + case 343: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:1839 + { + yyVAL.str = RightJoinStr + } + case 344: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:1845 + { + yyVAL.str = NaturalJoinStr + } + case 345: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:1849 + { + if yyDollar[2].str == LeftJoinStr { + yyVAL.str = NaturalLeftJoinStr + } else { + yyVAL.str = NaturalRightJoinStr + } + } + case 346: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:1859 + { + yyVAL.tableName = yyDollar[2].tableName + } + case 347: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:1863 + { + yyVAL.tableName = yyDollar[1].tableName + } + case 348: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:1869 + { + yyVAL.tableName = TableName{Name: yyDollar[1].tableIdent} + } + case 349: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:1873 + { + yyVAL.tableName = TableName{Qualifier: yyDollar[1].tableIdent, Name: yyDollar[3].tableIdent} + } + case 350: + yyDollar = yyS[yypt-0 : yypt+1] + //line sql.y:1878 + { + yyVAL.indexHints = nil + } + case 351: + yyDollar = yyS[yypt-5 : yypt+1] + //line sql.y:1882 + { + yyVAL.indexHints = &IndexHints{Type: UseStr, Indexes: yyDollar[4].columns} + } + case 352: + yyDollar = yyS[yypt-5 : yypt+1] + //line sql.y:1886 + { + yyVAL.indexHints = &IndexHints{Type: IgnoreStr, Indexes: yyDollar[4].columns} + } + case 353: + yyDollar = yyS[yypt-5 : yypt+1] + //line sql.y:1890 + { + yyVAL.indexHints = &IndexHints{Type: ForceStr, Indexes: yyDollar[4].columns} + } + case 354: + yyDollar = yyS[yypt-0 : yypt+1] + //line sql.y:1895 + { + yyVAL.expr = nil + } + case 355: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:1899 + { + yyVAL.expr = yyDollar[2].expr + } + case 356: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:1905 + { + yyVAL.expr = yyDollar[1].expr + } + case 357: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:1909 + { + yyVAL.expr = &AndExpr{Left: yyDollar[1].expr, Right: yyDollar[3].expr} + } + case 358: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:1913 + { + yyVAL.expr = &OrExpr{Left: yyDollar[1].expr, Right: yyDollar[3].expr} + } + case 359: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:1917 + { + yyVAL.expr = &NotExpr{Expr: yyDollar[2].expr} + } + case 360: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:1921 + { + yyVAL.expr = &IsExpr{Operator: yyDollar[3].str, Expr: yyDollar[1].expr} + } + case 361: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:1925 + { + yyVAL.expr = yyDollar[1].expr + } + case 362: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:1929 + { + yyVAL.expr = &Default{ColName: yyDollar[2].str} + } + case 363: + yyDollar = yyS[yypt-0 : yypt+1] + //line sql.y:1935 + { + yyVAL.str = "" + } + case 364: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:1939 + { + yyVAL.str = string(yyDollar[2].bytes) + } + case 365: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:1945 + { + yyVAL.boolVal = BoolVal(true) + } + case 366: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:1949 + { + yyVAL.boolVal = BoolVal(false) + } + case 367: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:1955 + { + yyVAL.expr = &ComparisonExpr{Left: yyDollar[1].expr, Operator: yyDollar[2].str, Right: yyDollar[3].expr} + } + case 368: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:1959 + { + yyVAL.expr = &ComparisonExpr{Left: yyDollar[1].expr, Operator: InStr, Right: yyDollar[3].colTuple} + } + case 369: + yyDollar = yyS[yypt-4 : yypt+1] + //line sql.y:1963 + { + yyVAL.expr = &ComparisonExpr{Left: yyDollar[1].expr, Operator: NotInStr, Right: yyDollar[4].colTuple} + } + case 370: + yyDollar = yyS[yypt-4 : yypt+1] + //line sql.y:1967 + { + yyVAL.expr = &ComparisonExpr{Left: yyDollar[1].expr, Operator: LikeStr, Right: yyDollar[3].expr, Escape: yyDollar[4].expr} + } + case 371: + yyDollar = yyS[yypt-5 : yypt+1] + //line sql.y:1971 + { + yyVAL.expr = &ComparisonExpr{Left: yyDollar[1].expr, Operator: NotLikeStr, Right: yyDollar[4].expr, Escape: yyDollar[5].expr} + } + case 372: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:1975 + { + yyVAL.expr = &ComparisonExpr{Left: yyDollar[1].expr, Operator: RegexpStr, Right: yyDollar[3].expr} + } + case 373: + yyDollar = yyS[yypt-4 : yypt+1] + //line sql.y:1979 + { + yyVAL.expr = &ComparisonExpr{Left: yyDollar[1].expr, Operator: NotRegexpStr, Right: yyDollar[4].expr} + } + case 374: + yyDollar = yyS[yypt-5 : yypt+1] + //line sql.y:1983 + { + yyVAL.expr = &RangeCond{Left: yyDollar[1].expr, Operator: BetweenStr, From: yyDollar[3].expr, To: yyDollar[5].expr} + } + case 375: + yyDollar = yyS[yypt-6 : yypt+1] + //line sql.y:1987 + { + yyVAL.expr = &RangeCond{Left: yyDollar[1].expr, Operator: NotBetweenStr, From: yyDollar[4].expr, To: yyDollar[6].expr} + } + case 376: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:1991 + { + yyVAL.expr = &ExistsExpr{Subquery: yyDollar[2].subquery} + } + case 377: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:1997 + { + yyVAL.str = IsNullStr + } + case 378: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:2001 + { + yyVAL.str = IsNotNullStr + } + case 379: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2005 + { + yyVAL.str = IsTrueStr + } + case 380: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:2009 + { + yyVAL.str = IsNotTrueStr + } + case 381: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2013 + { + yyVAL.str = IsFalseStr + } + case 382: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:2017 + { + yyVAL.str = IsNotFalseStr + } + case 383: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2023 + { + yyVAL.str = EqualStr + } + case 384: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2027 + { + yyVAL.str = LessThanStr + } + case 385: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2031 + { + yyVAL.str = GreaterThanStr + } + case 386: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2035 + { + yyVAL.str = LessEqualStr + } + case 387: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2039 + { + yyVAL.str = GreaterEqualStr + } + case 388: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2043 + { + yyVAL.str = NotEqualStr + } + case 389: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2047 + { + yyVAL.str = NullSafeEqualStr + } + case 390: + yyDollar = yyS[yypt-0 : yypt+1] + //line sql.y:2052 + { + yyVAL.expr = nil + } + case 391: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:2056 + { + yyVAL.expr = yyDollar[2].expr + } + case 392: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2062 + { + yyVAL.colTuple = yyDollar[1].valTuple + } + case 393: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2066 + { + yyVAL.colTuple = yyDollar[1].subquery + } + case 394: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2070 + { + yyVAL.colTuple = ListArg(yyDollar[1].bytes) + } + case 395: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:2076 + { + yyVAL.subquery = &Subquery{yyDollar[2].selStmt} + } + case 396: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2082 + { + yyVAL.exprs = Exprs{yyDollar[1].expr} + } + case 397: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:2086 + { + yyVAL.exprs = append(yyDollar[1].exprs, yyDollar[3].expr) + } + case 398: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2092 + { + yyVAL.expr = yyDollar[1].expr + } + case 399: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2096 + { + yyVAL.expr = yyDollar[1].boolVal + } + case 400: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2100 + { + yyVAL.expr = yyDollar[1].colName + } + case 401: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2104 + { + yyVAL.expr = yyDollar[1].expr + } + case 402: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2108 + { + yyVAL.expr = yyDollar[1].subquery + } + case 403: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:2112 + { + yyVAL.expr = &BinaryExpr{Left: yyDollar[1].expr, Operator: BitAndStr, Right: yyDollar[3].expr} + } + case 404: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:2116 + { + yyVAL.expr = &BinaryExpr{Left: yyDollar[1].expr, Operator: BitOrStr, Right: yyDollar[3].expr} + } + case 405: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:2120 + { + yyVAL.expr = &BinaryExpr{Left: yyDollar[1].expr, Operator: BitXorStr, Right: yyDollar[3].expr} + } + case 406: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:2124 + { + yyVAL.expr = &BinaryExpr{Left: yyDollar[1].expr, Operator: PlusStr, Right: yyDollar[3].expr} + } + case 407: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:2128 + { + yyVAL.expr = &BinaryExpr{Left: yyDollar[1].expr, Operator: MinusStr, Right: yyDollar[3].expr} + } + case 408: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:2132 + { + yyVAL.expr = &BinaryExpr{Left: yyDollar[1].expr, Operator: MultStr, Right: yyDollar[3].expr} + } + case 409: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:2136 + { + yyVAL.expr = &BinaryExpr{Left: yyDollar[1].expr, Operator: DivStr, Right: yyDollar[3].expr} + } + case 410: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:2140 + { + yyVAL.expr = &BinaryExpr{Left: yyDollar[1].expr, Operator: IntDivStr, Right: yyDollar[3].expr} + } + case 411: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:2144 + { + yyVAL.expr = &BinaryExpr{Left: yyDollar[1].expr, Operator: ModStr, Right: yyDollar[3].expr} + } + case 412: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:2148 + { + yyVAL.expr = &BinaryExpr{Left: yyDollar[1].expr, Operator: ModStr, Right: yyDollar[3].expr} + } + case 413: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:2152 + { + yyVAL.expr = &BinaryExpr{Left: yyDollar[1].expr, Operator: ShiftLeftStr, Right: yyDollar[3].expr} + } + case 414: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:2156 + { + yyVAL.expr = &BinaryExpr{Left: yyDollar[1].expr, Operator: ShiftRightStr, Right: yyDollar[3].expr} + } + case 415: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:2160 + { + yyVAL.expr = &BinaryExpr{Left: yyDollar[1].colName, Operator: JSONExtractOp, Right: yyDollar[3].expr} + } + case 416: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:2164 + { + yyVAL.expr = &BinaryExpr{Left: yyDollar[1].colName, Operator: JSONUnquoteExtractOp, Right: yyDollar[3].expr} + } + case 417: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:2168 + { + yyVAL.expr = &CollateExpr{Expr: yyDollar[1].expr, Charset: yyDollar[3].str} + } + case 418: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:2172 + { + yyVAL.expr = &UnaryExpr{Operator: BinaryStr, Expr: yyDollar[2].expr} + } + case 419: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:2176 + { + yyVAL.expr = &UnaryExpr{Operator: UBinaryStr, Expr: yyDollar[2].expr} + } + case 420: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:2180 + { + if num, ok := yyDollar[2].expr.(*SQLVal); ok && num.Type == IntVal { + yyVAL.expr = num + } else { + yyVAL.expr = &UnaryExpr{Operator: UPlusStr, Expr: yyDollar[2].expr} + } + } + case 421: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:2188 + { + if num, ok := yyDollar[2].expr.(*SQLVal); ok && num.Type == IntVal { + // Handle double negative + if num.Val[0] == '-' { + num.Val = num.Val[1:] + yyVAL.expr = num + } else { + yyVAL.expr = NewIntVal(append([]byte("-"), num.Val...)) + } + } else { + yyVAL.expr = &UnaryExpr{Operator: UMinusStr, Expr: yyDollar[2].expr} + } + } + case 422: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:2202 + { + yyVAL.expr = &UnaryExpr{Operator: TildaStr, Expr: yyDollar[2].expr} + } + case 423: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:2206 + { + yyVAL.expr = &UnaryExpr{Operator: BangStr, Expr: yyDollar[2].expr} + } + case 424: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:2210 + { + // This rule prevents the usage of INTERVAL + // as a function. If support is needed for that, + // we'll need to revisit this. The solution + // will be non-trivial because of grammar conflicts. + yyVAL.expr = &IntervalExpr{Expr: yyDollar[2].expr, Unit: yyDollar[3].colIdent.String()} + } + case 429: + yyDollar = yyS[yypt-4 : yypt+1] + //line sql.y:2228 + { + yyVAL.expr = &FuncExpr{Name: yyDollar[1].colIdent, Exprs: yyDollar[3].selectExprs} + } + case 430: + yyDollar = yyS[yypt-5 : yypt+1] + //line sql.y:2232 + { + yyVAL.expr = &FuncExpr{Name: yyDollar[1].colIdent, Distinct: true, Exprs: yyDollar[4].selectExprs} + } + case 431: + yyDollar = yyS[yypt-6 : yypt+1] + //line sql.y:2236 + { + yyVAL.expr = &FuncExpr{Qualifier: yyDollar[1].tableIdent, Name: yyDollar[3].colIdent, Exprs: yyDollar[5].selectExprs} + } + case 432: + yyDollar = yyS[yypt-4 : yypt+1] + //line sql.y:2246 + { + yyVAL.expr = &FuncExpr{Name: NewColIdent("left"), Exprs: yyDollar[3].selectExprs} + } + case 433: + yyDollar = yyS[yypt-4 : yypt+1] + //line sql.y:2250 + { + yyVAL.expr = &FuncExpr{Name: NewColIdent("right"), Exprs: yyDollar[3].selectExprs} + } + case 434: + yyDollar = yyS[yypt-6 : yypt+1] + //line sql.y:2254 + { + yyVAL.expr = &ConvertExpr{Expr: yyDollar[3].expr, Type: yyDollar[5].convertType} + } + case 435: + yyDollar = yyS[yypt-6 : yypt+1] + //line sql.y:2258 + { + yyVAL.expr = &ConvertExpr{Expr: yyDollar[3].expr, Type: yyDollar[5].convertType} + } + case 436: + yyDollar = yyS[yypt-6 : yypt+1] + //line sql.y:2262 + { + yyVAL.expr = &ConvertUsingExpr{Expr: yyDollar[3].expr, Type: yyDollar[5].str} + } + case 437: + yyDollar = yyS[yypt-6 : yypt+1] + //line sql.y:2266 + { + yyVAL.expr = &SubstrExpr{Name: yyDollar[3].colName, From: yyDollar[5].expr, To: nil} + } + case 438: + yyDollar = yyS[yypt-8 : yypt+1] + //line sql.y:2270 + { + yyVAL.expr = &SubstrExpr{Name: yyDollar[3].colName, From: yyDollar[5].expr, To: yyDollar[7].expr} + } + case 439: + yyDollar = yyS[yypt-8 : yypt+1] + //line sql.y:2274 + { + yyVAL.expr = &SubstrExpr{Name: yyDollar[3].colName, From: yyDollar[5].expr, To: yyDollar[7].expr} + } + case 440: + yyDollar = yyS[yypt-6 : yypt+1] + //line sql.y:2278 + { + yyVAL.expr = &SubstrExpr{Name: yyDollar[3].colName, From: yyDollar[5].expr, To: nil} + } + case 441: + yyDollar = yyS[yypt-8 : yypt+1] + //line sql.y:2282 + { + yyVAL.expr = &SubstrExpr{Name: yyDollar[3].colName, From: yyDollar[5].expr, To: yyDollar[7].expr} + } + case 442: + yyDollar = yyS[yypt-8 : yypt+1] + //line sql.y:2286 + { + yyVAL.expr = &SubstrExpr{Name: yyDollar[3].colName, From: yyDollar[5].expr, To: yyDollar[7].expr} + } + case 443: + yyDollar = yyS[yypt-9 : yypt+1] + //line sql.y:2290 + { + yyVAL.expr = &MatchExpr{Columns: yyDollar[3].selectExprs, Expr: yyDollar[7].expr, Option: yyDollar[8].str} + } + case 444: + yyDollar = yyS[yypt-7 : yypt+1] + //line sql.y:2294 + { + yyVAL.expr = &GroupConcatExpr{Distinct: yyDollar[3].str, Exprs: yyDollar[4].selectExprs, OrderBy: yyDollar[5].orderBy, Separator: yyDollar[6].str} + } + case 445: + yyDollar = yyS[yypt-5 : yypt+1] + //line sql.y:2298 + { + yyVAL.expr = &CaseExpr{Expr: yyDollar[2].expr, Whens: yyDollar[3].whens, Else: yyDollar[4].expr} + } + case 446: + yyDollar = yyS[yypt-4 : yypt+1] + //line sql.y:2302 + { + yyVAL.expr = &ValuesFuncExpr{Name: yyDollar[3].colName} + } + case 447: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:2312 + { + yyVAL.expr = &FuncExpr{Name: NewColIdent("current_timestamp")} + } + case 448: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:2316 + { + yyVAL.expr = &FuncExpr{Name: NewColIdent("utc_timestamp")} + } + case 449: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:2320 + { + yyVAL.expr = &FuncExpr{Name: NewColIdent("utc_time")} + } + case 450: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:2324 + { + yyVAL.expr = &FuncExpr{Name: NewColIdent("utc_date")} + } + case 451: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:2329 + { + yyVAL.expr = &FuncExpr{Name: NewColIdent("localtime")} + } + case 452: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:2334 + { + yyVAL.expr = &FuncExpr{Name: NewColIdent("localtimestamp")} + } + case 453: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:2339 + { + yyVAL.expr = &FuncExpr{Name: NewColIdent("current_date")} + } + case 454: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:2344 + { + yyVAL.expr = &FuncExpr{Name: NewColIdent("current_time")} + } + case 457: + yyDollar = yyS[yypt-4 : yypt+1] + //line sql.y:2358 + { + yyVAL.expr = &FuncExpr{Name: NewColIdent("if"), Exprs: yyDollar[3].selectExprs} + } + case 458: + yyDollar = yyS[yypt-4 : yypt+1] + //line sql.y:2362 + { + yyVAL.expr = &FuncExpr{Name: NewColIdent("database"), Exprs: yyDollar[3].selectExprs} + } + case 459: + yyDollar = yyS[yypt-4 : yypt+1] + //line sql.y:2366 + { + yyVAL.expr = &FuncExpr{Name: NewColIdent("mod"), Exprs: yyDollar[3].selectExprs} + } + case 460: + yyDollar = yyS[yypt-4 : yypt+1] + //line sql.y:2370 + { + yyVAL.expr = &FuncExpr{Name: NewColIdent("replace"), Exprs: yyDollar[3].selectExprs} + } + case 461: + yyDollar = yyS[yypt-0 : yypt+1] + //line sql.y:2376 + { + yyVAL.str = "" + } + case 462: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:2380 + { + yyVAL.str = BooleanModeStr + } + case 463: + yyDollar = yyS[yypt-4 : yypt+1] + //line sql.y:2384 + { + yyVAL.str = NaturalLanguageModeStr + } + case 464: + yyDollar = yyS[yypt-7 : yypt+1] + //line sql.y:2388 + { + yyVAL.str = NaturalLanguageModeWithQueryExpansionStr + } + case 465: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:2392 + { + yyVAL.str = QueryExpansionStr + } + case 466: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2398 + { + yyVAL.str = string(yyDollar[1].bytes) + } + case 467: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2402 + { + yyVAL.str = string(yyDollar[1].bytes) + } + case 468: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:2408 + { + yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes), Length: yyDollar[2].optVal} + } + case 469: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:2412 + { + yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes), Length: yyDollar[2].optVal, Charset: yyDollar[3].str, Operator: CharacterSetStr} + } + case 470: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:2416 + { + yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes), Length: yyDollar[2].optVal, Charset: string(yyDollar[3].bytes)} + } + case 471: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2420 + { + yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes)} + } + case 472: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:2424 + { + yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes), Length: yyDollar[2].optVal} + } + case 473: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:2428 + { + yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes)} + yyVAL.convertType.Length = yyDollar[2].LengthScaleOption.Length + yyVAL.convertType.Scale = yyDollar[2].LengthScaleOption.Scale + } + case 474: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2434 + { + yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes)} + } + case 475: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:2438 + { + yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes), Length: yyDollar[2].optVal} + } + case 476: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2442 + { + yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes)} + } + case 477: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:2446 + { + yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes)} + } + case 478: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:2450 + { + yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes), Length: yyDollar[2].optVal} + } + case 479: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2454 + { + yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes)} + } + case 480: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:2458 + { + yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes)} + } + case 481: + yyDollar = yyS[yypt-0 : yypt+1] + //line sql.y:2463 + { + yyVAL.expr = nil + } + case 482: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2467 + { + yyVAL.expr = yyDollar[1].expr + } + case 483: + yyDollar = yyS[yypt-0 : yypt+1] + //line sql.y:2472 + { + yyVAL.str = string("") + } + case 484: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:2476 + { + yyVAL.str = " separator '" + string(yyDollar[2].bytes) + "'" + } + case 485: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2482 + { + yyVAL.whens = []*When{yyDollar[1].when} + } + case 486: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:2486 + { + yyVAL.whens = append(yyDollar[1].whens, yyDollar[2].when) + } + case 487: + yyDollar = yyS[yypt-4 : yypt+1] + //line sql.y:2492 + { + yyVAL.when = &When{Cond: yyDollar[2].expr, Val: yyDollar[4].expr} + } + case 488: + yyDollar = yyS[yypt-0 : yypt+1] + //line sql.y:2497 + { + yyVAL.expr = nil + } + case 489: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:2501 + { + yyVAL.expr = yyDollar[2].expr + } + case 490: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2507 + { + yyVAL.colName = &ColName{Name: yyDollar[1].colIdent} + } + case 491: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:2511 + { + yyVAL.colName = &ColName{Qualifier: TableName{Name: yyDollar[1].tableIdent}, Name: yyDollar[3].colIdent} + } + case 492: + yyDollar = yyS[yypt-5 : yypt+1] + //line sql.y:2515 + { + yyVAL.colName = &ColName{Qualifier: TableName{Qualifier: yyDollar[1].tableIdent, Name: yyDollar[3].tableIdent}, Name: yyDollar[5].colIdent} + } + case 493: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2521 + { + yyVAL.expr = NewStrVal(yyDollar[1].bytes) + } + case 494: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2525 + { + yyVAL.expr = NewHexVal(yyDollar[1].bytes) + } + case 495: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2529 + { + yyVAL.expr = NewBitVal(yyDollar[1].bytes) + } + case 496: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2533 + { + yyVAL.expr = NewIntVal(yyDollar[1].bytes) + } + case 497: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2537 + { + yyVAL.expr = NewFloatVal(yyDollar[1].bytes) + } + case 498: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2541 + { + yyVAL.expr = NewHexNum(yyDollar[1].bytes) + } + case 499: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2545 + { + yyVAL.expr = NewValArg(yyDollar[1].bytes) + } + case 500: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2549 + { + yyVAL.expr = &NullVal{} + } + case 501: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2555 + { + // TODO(sougou): Deprecate this construct. + if yyDollar[1].colIdent.Lowered() != "value" { + yylex.Error("expecting value after next") + return 1 + } + yyVAL.expr = NewIntVal([]byte("1")) + } + case 502: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:2564 + { + yyVAL.expr = NewIntVal(yyDollar[1].bytes) + } + case 503: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:2568 + { + yyVAL.expr = NewValArg(yyDollar[1].bytes) + } + case 504: + yyDollar = yyS[yypt-0 : yypt+1] + //line sql.y:2573 + { + yyVAL.exprs = nil + } + case 505: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:2577 + { + yyVAL.exprs = yyDollar[3].exprs + } + case 506: + yyDollar = yyS[yypt-0 : yypt+1] + //line sql.y:2582 + { + yyVAL.expr = nil + } + case 507: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:2586 + { + yyVAL.expr = yyDollar[2].expr + } + case 508: + yyDollar = yyS[yypt-0 : yypt+1] + //line sql.y:2591 + { + yyVAL.orderBy = nil + } + case 509: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:2595 + { + yyVAL.orderBy = yyDollar[3].orderBy + } + case 510: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2601 + { + yyVAL.orderBy = OrderBy{yyDollar[1].order} + } + case 511: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:2605 + { + yyVAL.orderBy = append(yyDollar[1].orderBy, yyDollar[3].order) + } + case 512: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:2611 + { + yyVAL.order = &Order{Expr: yyDollar[1].expr, Direction: yyDollar[2].str} + } + case 513: + yyDollar = yyS[yypt-0 : yypt+1] + //line sql.y:2616 + { + yyVAL.str = AscScr + } + case 514: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2620 + { + yyVAL.str = AscScr + } + case 515: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2624 + { + yyVAL.str = DescScr + } + case 516: + yyDollar = yyS[yypt-0 : yypt+1] + //line sql.y:2629 + { + yyVAL.limit = nil + } + case 517: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:2633 + { + yyVAL.limit = &Limit{Rowcount: yyDollar[2].expr} + } + case 518: + yyDollar = yyS[yypt-4 : yypt+1] + //line sql.y:2637 + { + yyVAL.limit = &Limit{Offset: yyDollar[2].expr, Rowcount: yyDollar[4].expr} + } + case 519: + yyDollar = yyS[yypt-4 : yypt+1] + //line sql.y:2641 + { + yyVAL.limit = &Limit{Offset: yyDollar[4].expr, Rowcount: yyDollar[2].expr} + } + case 520: + yyDollar = yyS[yypt-0 : yypt+1] + //line sql.y:2646 + { + yyVAL.str = "" + } + case 521: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:2650 + { + yyVAL.str = ForUpdateStr + } + case 522: + yyDollar = yyS[yypt-4 : yypt+1] + //line sql.y:2654 + { + yyVAL.str = ShareModeStr + } + case 523: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:2667 + { + yyVAL.ins = &Insert{Rows: yyDollar[2].values} + } + case 524: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2671 + { + yyVAL.ins = &Insert{Rows: yyDollar[1].selStmt} + } + case 525: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:2675 + { + // Drop the redundant parenthesis. + yyVAL.ins = &Insert{Rows: yyDollar[2].selStmt} + } + case 526: + yyDollar = yyS[yypt-5 : yypt+1] + //line sql.y:2680 + { + yyVAL.ins = &Insert{Columns: yyDollar[2].columns, Rows: yyDollar[5].values} + } + case 527: + yyDollar = yyS[yypt-4 : yypt+1] + //line sql.y:2684 + { + yyVAL.ins = &Insert{Columns: yyDollar[2].columns, Rows: yyDollar[4].selStmt} + } + case 528: + yyDollar = yyS[yypt-6 : yypt+1] + //line sql.y:2688 + { + // Drop the redundant parenthesis. + yyVAL.ins = &Insert{Columns: yyDollar[2].columns, Rows: yyDollar[5].selStmt} + } + case 529: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2695 + { + yyVAL.columns = Columns{yyDollar[1].colIdent} + } + case 530: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:2699 + { + yyVAL.columns = Columns{yyDollar[3].colIdent} + } + case 531: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:2703 + { + yyVAL.columns = append(yyVAL.columns, yyDollar[3].colIdent) + } + case 532: + yyDollar = yyS[yypt-5 : yypt+1] + //line sql.y:2707 + { + yyVAL.columns = append(yyVAL.columns, yyDollar[5].colIdent) + } + case 533: + yyDollar = yyS[yypt-0 : yypt+1] + //line sql.y:2712 + { + yyVAL.updateExprs = nil + } + case 534: + yyDollar = yyS[yypt-5 : yypt+1] + //line sql.y:2716 + { + yyVAL.updateExprs = yyDollar[5].updateExprs + } + case 535: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2722 + { + yyVAL.values = Values{yyDollar[1].valTuple} + } + case 536: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:2726 + { + yyVAL.values = append(yyDollar[1].values, yyDollar[3].valTuple) + } + case 537: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2732 + { + yyVAL.valTuple = yyDollar[1].valTuple + } + case 538: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:2736 + { + yyVAL.valTuple = ValTuple{} + } + case 539: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:2742 + { + yyVAL.valTuple = ValTuple(yyDollar[2].exprs) + } + case 540: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2748 + { + if len(yyDollar[1].valTuple) == 1 { + yyVAL.expr = &ParenExpr{yyDollar[1].valTuple[0]} + } else { + yyVAL.expr = yyDollar[1].valTuple + } + } + case 541: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2758 + { + yyVAL.updateExprs = UpdateExprs{yyDollar[1].updateExpr} + } + case 542: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:2762 + { + yyVAL.updateExprs = append(yyDollar[1].updateExprs, yyDollar[3].updateExpr) + } + case 543: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:2768 + { + yyVAL.updateExpr = &UpdateExpr{Name: yyDollar[1].colName, Expr: yyDollar[3].expr} + } + case 544: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2774 + { + yyVAL.setExprs = SetExprs{yyDollar[1].setExpr} + } + case 545: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:2778 + { + yyVAL.setExprs = append(yyDollar[1].setExprs, yyDollar[3].setExpr) + } + case 546: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:2784 + { + yyVAL.setExpr = &SetExpr{Name: yyDollar[1].colIdent, Expr: NewStrVal([]byte("on"))} + } + case 547: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:2788 + { + yyVAL.setExpr = &SetExpr{Name: yyDollar[1].colIdent, Expr: yyDollar[3].expr} + } + case 548: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:2792 + { + yyVAL.setExpr = &SetExpr{Name: NewColIdent(string(yyDollar[1].bytes)), Expr: yyDollar[2].expr} + } + case 550: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:2799 + { + yyVAL.bytes = []byte("charset") + } + case 552: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2806 + { + yyVAL.expr = NewStrVal([]byte(yyDollar[1].colIdent.String())) + } + case 553: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2810 + { + yyVAL.expr = NewStrVal(yyDollar[1].bytes) + } + case 554: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2814 + { + yyVAL.expr = &Default{} + } + case 557: + yyDollar = yyS[yypt-0 : yypt+1] + //line sql.y:2823 + { + yyVAL.byt = 0 + } + case 558: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:2825 + { + yyVAL.byt = 1 + } + case 559: + yyDollar = yyS[yypt-0 : yypt+1] + //line sql.y:2828 + { + yyVAL.empty = struct{}{} + } + case 560: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:2830 + { + yyVAL.empty = struct{}{} + } + case 561: + yyDollar = yyS[yypt-0 : yypt+1] + //line sql.y:2833 + { + yyVAL.str = "" + } + case 562: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2835 + { + yyVAL.str = IgnoreStr + } + case 563: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2839 + { + yyVAL.empty = struct{}{} + } + case 564: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2841 + { + yyVAL.empty = struct{}{} + } + case 565: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2843 + { + yyVAL.empty = struct{}{} + } + case 566: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2845 + { + yyVAL.empty = struct{}{} + } + case 567: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2847 + { + yyVAL.empty = struct{}{} + } + case 568: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2849 + { + yyVAL.empty = struct{}{} + } + case 569: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2851 + { + yyVAL.empty = struct{}{} + } + case 570: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2853 + { + yyVAL.empty = struct{}{} + } + case 571: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2855 + { + yyVAL.empty = struct{}{} + } + case 572: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2857 + { + yyVAL.empty = struct{}{} + } + case 573: + yyDollar = yyS[yypt-0 : yypt+1] + //line sql.y:2860 + { + yyVAL.empty = struct{}{} + } + case 574: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2862 + { + yyVAL.empty = struct{}{} + } + case 575: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2864 + { + yyVAL.empty = struct{}{} + } + case 576: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2868 + { + yyVAL.empty = struct{}{} + } + case 577: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2870 + { + yyVAL.empty = struct{}{} + } + case 578: + yyDollar = yyS[yypt-0 : yypt+1] + //line sql.y:2873 + { + yyVAL.empty = struct{}{} + } + case 579: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2875 + { + yyVAL.empty = struct{}{} + } + case 580: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2877 + { + yyVAL.empty = struct{}{} + } + case 581: + yyDollar = yyS[yypt-0 : yypt+1] + //line sql.y:2880 + { + yyVAL.colIdent = ColIdent{} + } + case 582: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:2882 + { + yyVAL.colIdent = yyDollar[2].colIdent + } + case 583: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2886 + { + yyVAL.colIdent = NewColIdent(string(yyDollar[1].bytes)) + } + case 584: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2890 + { + yyVAL.colIdent = NewColIdent(string(yyDollar[1].bytes)) + } + case 586: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2897 + { + yyVAL.colIdent = NewColIdent(string(yyDollar[1].bytes)) + } + case 587: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2903 + { + yyVAL.tableIdent = NewTableIdent(string(yyDollar[1].bytes)) + } + case 588: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2907 + { + yyVAL.tableIdent = NewTableIdent(string(yyDollar[1].bytes)) + } + case 590: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2914 + { + yyVAL.tableIdent = NewTableIdent(string(yyDollar[1].bytes)) + } + case 781: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:3130 + { + if incNesting(yylex) { + yylex.Error("max nesting level reached") + return 1 + } + } + case 782: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:3139 + { + decNesting(yylex) + } + case 783: + yyDollar = yyS[yypt-0 : yypt+1] + //line sql.y:3144 + { + forceEOF(yylex) + } + case 784: + yyDollar = yyS[yypt-0 : yypt+1] + //line sql.y:3149 + { + forceEOF(yylex) + } + case 785: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:3153 + { + forceEOF(yylex) + } + case 786: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:3157 + { + forceEOF(yylex) + } + } + goto yystack /* stack new state and value */ +} diff --git a/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/sql.y b/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/sql.y new file mode 100644 index 00000000..efbb794c --- /dev/null +++ b/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/sql.y @@ -0,0 +1,3159 @@ +/* +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 sqlparser + +func setParseTree(yylex interface{}, stmt Statement) { + yylex.(*Tokenizer).ParseTree = stmt +} + +func setAllowComments(yylex interface{}, allow bool) { + yylex.(*Tokenizer).AllowComments = allow +} + +func setDDL(yylex interface{}, ddl *DDL) { + yylex.(*Tokenizer).partialDDL = ddl +} + +func incNesting(yylex interface{}) bool { + yylex.(*Tokenizer).nesting++ + if yylex.(*Tokenizer).nesting == 200 { + return true + } + return false +} + +func decNesting(yylex interface{}) { + yylex.(*Tokenizer).nesting-- +} + +// forceEOF forces the lexer to end prematurely. Not all SQL statements +// are supported by the Parser, thus calling forceEOF will make the lexer +// return EOF early. +func forceEOF(yylex interface{}) { + yylex.(*Tokenizer).ForceEOF = true +} + +%} + +%union { + empty struct{} + statement Statement + selStmt SelectStatement + ddl *DDL + ins *Insert + byt byte + bytes []byte + bytes2 [][]byte + str string + strs []string + selectExprs SelectExprs + selectExpr SelectExpr + columns Columns + partitions Partitions + colName *ColName + tableExprs TableExprs + tableExpr TableExpr + joinCondition JoinCondition + tableName TableName + tableNames TableNames + indexHints *IndexHints + expr Expr + exprs Exprs + boolVal BoolVal + colTuple ColTuple + values Values + valTuple ValTuple + subquery *Subquery + whens []*When + when *When + orderBy OrderBy + order *Order + limit *Limit + updateExprs UpdateExprs + setExprs SetExprs + updateExpr *UpdateExpr + setExpr *SetExpr + colIdent ColIdent + tableIdent TableIdent + convertType *ConvertType + aliasedTableName *AliasedTableExpr + TableSpec *TableSpec + columnType ColumnType + colKeyOpt ColumnKeyOption + optVal *SQLVal + LengthScaleOption LengthScaleOption + columnDefinition *ColumnDefinition + indexDefinition *IndexDefinition + indexInfo *IndexInfo + indexOption *IndexOption + indexOptions []*IndexOption + indexColumn *IndexColumn + indexColumns []*IndexColumn + partDefs []*PartitionDefinition + partDef *PartitionDefinition + partSpec *PartitionSpec + vindexParam VindexParam + vindexParams []VindexParam + showFilter *ShowFilter +} + +%token LEX_ERROR +%left UNION +%token SELECT STREAM INSERT UPDATE DELETE FROM WHERE GROUP HAVING ORDER BY LIMIT OFFSET FOR +%token ALL DISTINCT AS EXISTS ASC DESC INTO DUPLICATE KEY DEFAULT SET LOCK KEYS +%token VALUES LAST_INSERT_ID +%token NEXT VALUE SHARE MODE +%token SQL_NO_CACHE SQL_CACHE +%left JOIN STRAIGHT_JOIN LEFT RIGHT INNER OUTER CROSS NATURAL USE FORCE +%left ON USING +%token '(' ',' ')' +%token ID HEX STRING INTEGRAL FLOAT HEXNUM VALUE_ARG LIST_ARG COMMENT COMMENT_KEYWORD BIT_LITERAL +%token NULL TRUE FALSE + +// Precedence dictated by mysql. But the vitess grammar is simplified. +// Some of these operators don't conflict in our situation. Nevertheless, +// it's better to have these listed in the correct order. Also, we don't +// support all operators yet. +%left OR +%left AND +%right NOT '!' +%left BETWEEN CASE WHEN THEN ELSE END +%left '=' '<' '>' LE GE NE NULL_SAFE_EQUAL IS LIKE REGEXP IN +%left '|' +%left '&' +%left SHIFT_LEFT SHIFT_RIGHT +%left '+' '-' +%left '*' '/' DIV '%' MOD +%left '^' +%right '~' UNARY +%left COLLATE +%right BINARY UNDERSCORE_BINARY +%right INTERVAL +%nonassoc '.' + +// There is no need to define precedence for the JSON +// operators because the syntax is restricted enough that +// they don't cause conflicts. +%token JSON_EXTRACT_OP JSON_UNQUOTE_EXTRACT_OP + +// DDL Tokens +%token CREATE ALTER DROP RENAME ANALYZE ADD +%token SCHEMA TABLE INDEX VIEW TO IGNORE IF UNIQUE PRIMARY COLUMN CONSTRAINT SPATIAL FULLTEXT FOREIGN KEY_BLOCK_SIZE +%token SHOW DESCRIBE EXPLAIN DATE ESCAPE REPAIR OPTIMIZE TRUNCATE +%token MAXVALUE PARTITION REORGANIZE LESS THAN PROCEDURE TRIGGER +%token VINDEX VINDEXES +%token STATUS VARIABLES + +// Transaction Tokens +%token BEGIN START TRANSACTION COMMIT ROLLBACK + +// Type Tokens +%token BIT TINYINT SMALLINT MEDIUMINT INT INTEGER BIGINT INTNUM +%token REAL DOUBLE FLOAT_TYPE DECIMAL NUMERIC +%token TIME TIMESTAMP DATETIME YEAR +%token CHAR VARCHAR BOOL CHARACTER VARBINARY NCHAR +%token TEXT TINYTEXT MEDIUMTEXT LONGTEXT +%token BLOB TINYBLOB MEDIUMBLOB LONGBLOB JSON ENUM +%token GEOMETRY POINT LINESTRING POLYGON GEOMETRYCOLLECTION MULTIPOINT MULTILINESTRING MULTIPOLYGON + +// Type Modifiers +%token NULLX AUTO_INCREMENT APPROXNUM SIGNED UNSIGNED ZEROFILL + +// Supported SHOW tokens +%token DATABASES TABLES VITESS_KEYSPACES VITESS_SHARDS VITESS_TABLETS VSCHEMA_TABLES EXTENDED FULL PROCESSLIST + +// SET tokens +%token NAMES CHARSET GLOBAL SESSION ISOLATION LEVEL READ WRITE ONLY REPEATABLE COMMITTED UNCOMMITTED SERIALIZABLE + +// Functions +%token CURRENT_TIMESTAMP DATABASE CURRENT_DATE +%token CURRENT_TIME LOCALTIME LOCALTIMESTAMP +%token UTC_DATE UTC_TIME UTC_TIMESTAMP +%token REPLACE +%token CONVERT CAST +%token SUBSTR SUBSTRING +%token GROUP_CONCAT SEPARATOR + +// Match +%token MATCH AGAINST BOOLEAN LANGUAGE WITH QUERY EXPANSION + +// MySQL reserved words that are unused by this grammar will map to this token. +%token UNUSED + +%type command +%type select_statement base_select union_lhs union_rhs +%type stream_statement insert_statement update_statement delete_statement set_statement +%type create_statement alter_statement rename_statement drop_statement truncate_statement +%type create_table_prefix +%type analyze_statement show_statement use_statement other_statement +%type begin_statement commit_statement rollback_statement +%type comment_opt comment_list +%type union_op insert_or_replace +%type distinct_opt straight_join_opt cache_opt match_option separator_opt +%type like_escape_opt +%type select_expression_list select_expression_list_opt +%type select_expression +%type expression +%type from_opt table_references +%type table_reference table_factor join_table +%type join_condition join_condition_opt on_expression_opt +%type table_name_list +%type inner_join outer_join straight_join natural_join +%type table_name into_table_name +%type aliased_table_name +%type index_hint_list +%type where_expression_opt +%type condition +%type boolean_value +%type compare +%type insert_data +%type value value_expression num_val +%type function_call_keyword function_call_nonkeyword function_call_generic function_call_conflict +%type is_suffix +%type col_tuple +%type expression_list +%type tuple_list +%type row_tuple tuple_or_empty +%type tuple_expression +%type subquery +%type column_name +%type when_expression_list +%type when_expression +%type expression_opt else_expression_opt +%type group_by_opt +%type having_opt +%type order_by_opt order_list +%type order +%type asc_desc_opt +%type limit_opt +%type lock_opt +%type ins_column_list column_list +%type opt_partition_clause partition_list +%type on_dup_opt +%type update_list +%type set_list transaction_chars +%type charset_or_character_set +%type update_expression +%type set_expression transaction_char isolation_level +%type for_from +%type ignore_opt default_opt +%type extended_opt full_opt from_database_opt tables_or_processlist +%type like_or_where_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 +%type sql_id reserved_sql_id col_alias as_ci_opt using_opt +%type charset_value +%type table_id reserved_table_id table_alias as_opt_id +%type as_opt +%type force_eof ddl_force_eof +%type charset +%type set_session_or_global show_session_or_global +%type convert_type +%type column_type +%type int_type decimal_type numeric_type time_type char_type spatial_type +%type length_opt column_default_opt column_comment_opt on_update_opt +%type charset_opt collate_opt +%type unsigned_opt zero_fill_opt +%type float_length_opt decimal_length_opt +%type null_opt auto_increment_opt +%type column_key_opt +%type enum_values +%type column_definition +%type index_definition +%type index_or_key +%type equal_opt +%type table_spec table_column_list +%type table_option_list table_option table_opt_value +%type index_info +%type index_column +%type index_column_list +%type index_option +%type index_option_list +%type partition_definitions +%type partition_definition +%type partition_operation +%type vindex_param +%type vindex_param_list vindex_params_opt +%type vindex_type vindex_type_opt +%type alter_object_type + +%start any_command + +%% + +any_command: + command semicolon_opt + { + setParseTree(yylex, $1) + } + +semicolon_opt: +/*empty*/ {} +| ';' {} + +command: + select_statement + { + $$ = $1 + } +| stream_statement +| insert_statement +| update_statement +| delete_statement +| set_statement +| create_statement +| alter_statement +| rename_statement +| drop_statement +| truncate_statement +| analyze_statement +| show_statement +| use_statement +| begin_statement +| commit_statement +| rollback_statement +| other_statement + +select_statement: + base_select order_by_opt limit_opt lock_opt + { + sel := $1.(*Select) + sel.OrderBy = $2 + sel.Limit = $3 + sel.Lock = $4 + $$ = sel + } +| union_lhs union_op union_rhs order_by_opt limit_opt lock_opt + { + $$ = &Union{Type: $2, Left: $1, Right: $3, OrderBy: $4, Limit: $5, Lock: $6} + } +| SELECT comment_opt cache_opt NEXT num_val for_from table_name + { + $$ = &Select{Comments: Comments($2), Cache: $3, SelectExprs: SelectExprs{Nextval{Expr: $5}}, From: TableExprs{&AliasedTableExpr{Expr: $7}}} + } + +stream_statement: + STREAM comment_opt select_expression FROM table_name + { + $$ = &Stream{Comments: Comments($2), SelectExpr: $3, Table: $5} + } + +// base_select is an unparenthesized SELECT with no order by clause or beyond. +base_select: + SELECT comment_opt cache_opt distinct_opt straight_join_opt select_expression_list from_opt where_expression_opt group_by_opt having_opt + { + $$ = &Select{Comments: Comments($2), Cache: $3, Distinct: $4, Hints: $5, SelectExprs: $6, From: $7, Where: NewWhere(WhereStr, $8), GroupBy: GroupBy($9), Having: NewWhere(HavingStr, $10)} + } + +union_lhs: + select_statement + { + $$ = $1 + } +| openb select_statement closeb + { + $$ = &ParenSelect{Select: $2} + } + +union_rhs: + base_select + { + $$ = $1 + } +| openb select_statement closeb + { + $$ = &ParenSelect{Select: $2} + } + + +insert_statement: + insert_or_replace comment_opt ignore_opt into_table_name opt_partition_clause insert_data on_dup_opt + { + // insert_data returns a *Insert pre-filled with Columns & Values + ins := $6 + ins.Action = $1 + ins.Comments = $2 + ins.Ignore = $3 + ins.Table = $4 + ins.Partitions = $5 + ins.OnDup = OnDup($7) + $$ = ins + } +| insert_or_replace comment_opt ignore_opt into_table_name opt_partition_clause SET update_list on_dup_opt + { + cols := make(Columns, 0, len($7)) + vals := make(ValTuple, 0, len($8)) + for _, updateList := range $7 { + cols = append(cols, updateList.Name.Name) + vals = append(vals, updateList.Expr) + } + $$ = &Insert{Action: $1, Comments: Comments($2), Ignore: $3, Table: $4, Partitions: $5, Columns: cols, Rows: Values{vals}, OnDup: OnDup($8)} + } + +insert_or_replace: + INSERT + { + $$ = InsertStr + } +| REPLACE + { + $$ = ReplaceStr + } + +update_statement: + UPDATE comment_opt table_references SET update_list where_expression_opt order_by_opt limit_opt + { + $$ = &Update{Comments: Comments($2), TableExprs: $3, Exprs: $5, Where: NewWhere(WhereStr, $6), OrderBy: $7, Limit: $8} + } + +delete_statement: + DELETE comment_opt FROM table_name opt_partition_clause where_expression_opt order_by_opt limit_opt + { + $$ = &Delete{Comments: Comments($2), TableExprs: TableExprs{&AliasedTableExpr{Expr:$4}}, Partitions: $5, Where: NewWhere(WhereStr, $6), OrderBy: $7, Limit: $8} + } +| DELETE comment_opt FROM table_name_list USING table_references where_expression_opt + { + $$ = &Delete{Comments: Comments($2), Targets: $4, TableExprs: $6, Where: NewWhere(WhereStr, $7)} + } +| DELETE comment_opt table_name_list from_or_using table_references where_expression_opt + { + $$ = &Delete{Comments: Comments($2), Targets: $3, TableExprs: $5, Where: NewWhere(WhereStr, $6)} + } + +from_or_using: + FROM {} +| USING {} + +table_name_list: + table_name + { + $$ = TableNames{$1} + } +| table_name_list ',' table_name + { + $$ = append($$, $3) + } + +opt_partition_clause: + { + $$ = nil + } +| PARTITION openb partition_list closeb + { + $$ = $3 + } + +set_statement: + SET comment_opt set_list + { + $$ = &Set{Comments: Comments($2), Exprs: $3} + } +| SET comment_opt set_session_or_global set_list + { + $$ = &Set{Comments: Comments($2), Scope: $3, Exprs: $4} + } +| SET comment_opt set_session_or_global TRANSACTION transaction_chars + { + $$ = &Set{Comments: Comments($2), Scope: $3, Exprs: $5} + } +| SET comment_opt TRANSACTION transaction_chars + { + $$ = &Set{Comments: Comments($2), Exprs: $4} + } + +transaction_chars: + transaction_char + { + $$ = SetExprs{$1} + } +| transaction_chars ',' transaction_char + { + $$ = append($$, $3) + } + +transaction_char: + ISOLATION LEVEL isolation_level + { + $$ = $3 + } +| READ WRITE + { + $$ = &SetExpr{Name: NewColIdent("tx_read_only"), Expr: NewIntVal([]byte("0"))} + } +| READ ONLY + { + $$ = &SetExpr{Name: NewColIdent("tx_read_only"), Expr: NewIntVal([]byte("1"))} + } + +isolation_level: + REPEATABLE READ + { + $$ = &SetExpr{Name: NewColIdent("tx_isolation"), Expr: NewStrVal([]byte("repeatable read"))} + } +| READ COMMITTED + { + $$ = &SetExpr{Name: NewColIdent("tx_isolation"), Expr: NewStrVal([]byte("read committed"))} + } +| READ UNCOMMITTED + { + $$ = &SetExpr{Name: NewColIdent("tx_isolation"), Expr: NewStrVal([]byte("read uncommitted"))} + } +| SERIALIZABLE + { + $$ = &SetExpr{Name: NewColIdent("tx_isolation"), Expr: NewStrVal([]byte("serializable"))} + } + +set_session_or_global: + SESSION + { + $$ = SessionStr + } +| GLOBAL + { + $$ = GlobalStr + } + +create_statement: + create_table_prefix table_spec + { + $1.TableSpec = $2 + $$ = $1 + } +| CREATE constraint_opt INDEX ID using_opt ON table_name ddl_force_eof + { + // Change this to an alter statement + $$ = &DDL{Action: AlterStr, Table: $7, NewName:$7} + } +| CREATE VIEW table_name ddl_force_eof + { + $$ = &DDL{Action: CreateStr, NewName: $3.ToViewName()} + } +| CREATE OR REPLACE VIEW table_name ddl_force_eof + { + $$ = &DDL{Action: CreateStr, NewName: $5.ToViewName()} + } +| CREATE VINDEX sql_id vindex_type_opt vindex_params_opt + { + $$ = &DDL{Action: CreateVindexStr, VindexSpec: &VindexSpec{ + Name: $3, + Type: $4, + Params: $5, + }} + } +| CREATE DATABASE not_exists_opt ID ddl_force_eof + { + $$ = &DBDDL{Action: CreateStr, DBName: string($4)} + } +| CREATE SCHEMA not_exists_opt ID ddl_force_eof + { + $$ = &DBDDL{Action: CreateStr, DBName: string($4)} + } + +vindex_type_opt: + { + $$ = NewColIdent("") + } +| USING vindex_type + { + $$ = $2 + } + +vindex_type: + ID + { + $$ = NewColIdent(string($1)) + } + +vindex_params_opt: + { + var v []VindexParam + $$ = v + } +| WITH vindex_param_list + { + $$ = $2 + } + +vindex_param_list: + vindex_param + { + $$ = make([]VindexParam, 0, 4) + $$ = append($$, $1) + } +| vindex_param_list ',' vindex_param + { + $$ = append($$, $3) + } + +vindex_param: + reserved_sql_id '=' table_opt_value + { + $$ = VindexParam{Key: $1, Val: $3} + } + +create_table_prefix: + CREATE TABLE not_exists_opt table_name + { + $$ = &DDL{Action: CreateStr, NewName: $4} + setDDL(yylex, $$) + } + +table_spec: + '(' table_column_list ')' table_option_list + { + $$ = $2 + $$.Options = $4 + } + +table_column_list: + column_definition + { + $$ = &TableSpec{} + $$.AddColumn($1) + } +| table_column_list ',' column_definition + { + $$.AddColumn($3) + } +| table_column_list ',' index_definition + { + $$.AddIndex($3) + } + +column_definition: + ID column_type null_opt column_default_opt on_update_opt auto_increment_opt column_key_opt column_comment_opt + { + $2.NotNull = $3 + $2.Default = $4 + $2.OnUpdate = $5 + $2.Autoincrement = $6 + $2.KeyOpt = $7 + $2.Comment = $8 + $$ = &ColumnDefinition{Name: NewColIdent(string($1)), Type: $2} + } +column_type: + numeric_type unsigned_opt zero_fill_opt + { + $$ = $1 + $$.Unsigned = $2 + $$.Zerofill = $3 + } +| char_type +| time_type +| spatial_type + +numeric_type: + int_type length_opt + { + $$ = $1 + $$.Length = $2 + } +| decimal_type + { + $$ = $1 + } + +int_type: + BIT + { + $$ = ColumnType{Type: string($1)} + } +| TINYINT + { + $$ = ColumnType{Type: string($1)} + } +| SMALLINT + { + $$ = ColumnType{Type: string($1)} + } +| MEDIUMINT + { + $$ = ColumnType{Type: string($1)} + } +| INT + { + $$ = ColumnType{Type: string($1)} + } +| INTEGER + { + $$ = ColumnType{Type: string($1)} + } +| BIGINT + { + $$ = ColumnType{Type: string($1)} + } + +decimal_type: +REAL float_length_opt + { + $$ = ColumnType{Type: string($1)} + $$.Length = $2.Length + $$.Scale = $2.Scale + } +| DOUBLE float_length_opt + { + $$ = ColumnType{Type: string($1)} + $$.Length = $2.Length + $$.Scale = $2.Scale + } +| FLOAT_TYPE float_length_opt + { + $$ = ColumnType{Type: string($1)} + $$.Length = $2.Length + $$.Scale = $2.Scale + } +| DECIMAL decimal_length_opt + { + $$ = ColumnType{Type: string($1)} + $$.Length = $2.Length + $$.Scale = $2.Scale + } +| NUMERIC decimal_length_opt + { + $$ = ColumnType{Type: string($1)} + $$.Length = $2.Length + $$.Scale = $2.Scale + } + +time_type: + DATE + { + $$ = ColumnType{Type: string($1)} + } +| TIME length_opt + { + $$ = ColumnType{Type: string($1), Length: $2} + } +| TIMESTAMP length_opt + { + $$ = ColumnType{Type: string($1), Length: $2} + } +| DATETIME length_opt + { + $$ = ColumnType{Type: string($1), Length: $2} + } +| YEAR + { + $$ = ColumnType{Type: string($1)} + } + +char_type: + CHAR length_opt charset_opt collate_opt + { + $$ = ColumnType{Type: string($1), Length: $2, Charset: $3, Collate: $4} + } +| VARCHAR length_opt charset_opt collate_opt + { + $$ = ColumnType{Type: string($1), Length: $2, Charset: $3, Collate: $4} + } +| BINARY length_opt + { + $$ = ColumnType{Type: string($1), Length: $2} + } +| VARBINARY length_opt + { + $$ = ColumnType{Type: string($1), Length: $2} + } +| TEXT charset_opt collate_opt + { + $$ = ColumnType{Type: string($1), Charset: $2, Collate: $3} + } +| TINYTEXT charset_opt collate_opt + { + $$ = ColumnType{Type: string($1), Charset: $2, Collate: $3} + } +| MEDIUMTEXT charset_opt collate_opt + { + $$ = ColumnType{Type: string($1), Charset: $2, Collate: $3} + } +| LONGTEXT charset_opt collate_opt + { + $$ = ColumnType{Type: string($1), Charset: $2, Collate: $3} + } +| BLOB + { + $$ = ColumnType{Type: string($1)} + } +| TINYBLOB + { + $$ = ColumnType{Type: string($1)} + } +| MEDIUMBLOB + { + $$ = ColumnType{Type: string($1)} + } +| LONGBLOB + { + $$ = ColumnType{Type: string($1)} + } +| JSON + { + $$ = ColumnType{Type: string($1)} + } +| ENUM '(' enum_values ')' charset_opt collate_opt + { + $$ = ColumnType{Type: string($1), EnumValues: $3, Charset: $5, Collate: $6} + } +// need set_values / SetValues ? +| SET '(' enum_values ')' charset_opt collate_opt + { + $$ = ColumnType{Type: string($1), EnumValues: $3, Charset: $5, Collate: $6} + } + +spatial_type: + GEOMETRY + { + $$ = ColumnType{Type: string($1)} + } +| POINT + { + $$ = ColumnType{Type: string($1)} + } +| LINESTRING + { + $$ = ColumnType{Type: string($1)} + } +| POLYGON + { + $$ = ColumnType{Type: string($1)} + } +| GEOMETRYCOLLECTION + { + $$ = ColumnType{Type: string($1)} + } +| MULTIPOINT + { + $$ = ColumnType{Type: string($1)} + } +| MULTILINESTRING + { + $$ = ColumnType{Type: string($1)} + } +| MULTIPOLYGON + { + $$ = ColumnType{Type: string($1)} + } + +enum_values: + STRING + { + $$ = make([]string, 0, 4) + $$ = append($$, "'" + string($1) + "'") + } +| enum_values ',' STRING + { + $$ = append($1, "'" + string($3) + "'") + } + +length_opt: + { + $$ = nil + } +| '(' INTEGRAL ')' + { + $$ = NewIntVal($2) + } + +float_length_opt: + { + $$ = LengthScaleOption{} + } +| '(' INTEGRAL ',' INTEGRAL ')' + { + $$ = LengthScaleOption{ + Length: NewIntVal($2), + Scale: NewIntVal($4), + } + } + +decimal_length_opt: + { + $$ = LengthScaleOption{} + } +| '(' INTEGRAL ')' + { + $$ = LengthScaleOption{ + Length: NewIntVal($2), + } + } +| '(' INTEGRAL ',' INTEGRAL ')' + { + $$ = LengthScaleOption{ + Length: NewIntVal($2), + Scale: NewIntVal($4), + } + } + +unsigned_opt: + { + $$ = BoolVal(false) + } +| UNSIGNED + { + $$ = BoolVal(true) + } + +zero_fill_opt: + { + $$ = BoolVal(false) + } +| ZEROFILL + { + $$ = BoolVal(true) + } + +// Null opt returns false to mean NULL (i.e. the default) and true for NOT NULL +null_opt: + { + $$ = BoolVal(false) + } +| NULL + { + $$ = BoolVal(false) + } +| NOT NULL + { + $$ = BoolVal(true) + } + +column_default_opt: + { + $$ = nil + } +| DEFAULT STRING + { + $$ = NewStrVal($2) + } +| DEFAULT INTEGRAL + { + $$ = NewIntVal($2) + } +| DEFAULT FLOAT + { + $$ = NewFloatVal($2) + } +| DEFAULT NULL + { + $$ = NewValArg($2) + } +| DEFAULT CURRENT_TIMESTAMP + { + $$ = NewValArg($2) + } +| DEFAULT BIT_LITERAL + { + $$ = NewBitVal($2) + } + +on_update_opt: + { + $$ = nil + } +| ON UPDATE CURRENT_TIMESTAMP +{ + $$ = NewValArg($3) +} + +auto_increment_opt: + { + $$ = BoolVal(false) + } +| AUTO_INCREMENT + { + $$ = BoolVal(true) + } + +charset_opt: + { + $$ = "" + } +| CHARACTER SET ID + { + $$ = string($3) + } +| CHARACTER SET BINARY + { + $$ = string($3) + } + +collate_opt: + { + $$ = "" + } +| COLLATE ID + { + $$ = string($2) + } + +column_key_opt: + { + $$ = colKeyNone + } +| PRIMARY KEY + { + $$ = colKeyPrimary + } +| KEY + { + $$ = colKey + } +| UNIQUE KEY + { + $$ = colKeyUniqueKey + } +| UNIQUE + { + $$ = colKeyUnique + } + +column_comment_opt: + { + $$ = nil + } +| COMMENT_KEYWORD STRING + { + $$ = NewStrVal($2) + } + +index_definition: + index_info '(' index_column_list ')' index_option_list + { + $$ = &IndexDefinition{Info: $1, Columns: $3, Options: $5} + } +| index_info '(' index_column_list ')' + { + $$ = &IndexDefinition{Info: $1, Columns: $3} + } + +index_option_list: + index_option + { + $$ = []*IndexOption{$1} + } +| index_option_list index_option + { + $$ = append($$, $2) + } + +index_option: + USING ID + { + $$ = &IndexOption{Name: string($1), Using: string($2)} + } +| KEY_BLOCK_SIZE equal_opt INTEGRAL + { + // should not be string + $$ = &IndexOption{Name: string($1), Value: NewIntVal($3)} + } +| COMMENT_KEYWORD STRING + { + $$ = &IndexOption{Name: string($1), Value: NewStrVal($2)} + } + +equal_opt: + /* empty */ + { + $$ = "" + } +| '=' + { + $$ = string($1) + } + +index_info: + PRIMARY KEY + { + $$ = &IndexInfo{Type: string($1) + " " + string($2), Name: NewColIdent("PRIMARY"), Primary: true, Unique: true} + } +| SPATIAL index_or_key ID + { + $$ = &IndexInfo{Type: string($1) + " " + string($2), Name: NewColIdent(string($3)), Spatial: true, Unique: false} + } +| UNIQUE index_or_key ID + { + $$ = &IndexInfo{Type: string($1) + " " + string($2), Name: NewColIdent(string($3)), Unique: true} + } +| UNIQUE ID + { + $$ = &IndexInfo{Type: string($1), Name: NewColIdent(string($2)), Unique: true} + } +| index_or_key ID + { + $$ = &IndexInfo{Type: string($1), Name: NewColIdent(string($2)), Unique: false} + } + +index_or_key: + INDEX + { + $$ = string($1) + } + | KEY + { + $$ = string($1) + } + +index_column_list: + index_column + { + $$ = []*IndexColumn{$1} + } +| index_column_list ',' index_column + { + $$ = append($$, $3) + } + +index_column: + sql_id length_opt + { + $$ = &IndexColumn{Column: $1, Length: $2} + } + +table_option_list: + { + $$ = "" + } +| table_option + { + $$ = " " + string($1) + } +| table_option_list ',' table_option + { + $$ = string($1) + ", " + string($3) + } + +// rather than explicitly parsing the various keywords for table options, +// just accept any number of keywords, IDs, strings, numbers, and '=' +table_option: + table_opt_value + { + $$ = $1 + } +| table_option table_opt_value + { + $$ = $1 + " " + $2 + } +| table_option '=' table_opt_value + { + $$ = $1 + "=" + $3 + } + +table_opt_value: + reserved_sql_id + { + $$ = $1.String() + } +| STRING + { + $$ = "'" + string($1) + "'" + } +| INTEGRAL + { + $$ = string($1) + } + +alter_statement: + ALTER ignore_opt TABLE table_name non_add_drop_or_rename_operation force_eof + { + $$ = &DDL{Action: AlterStr, Table: $4, NewName: $4} + } +| ALTER ignore_opt TABLE table_name ADD alter_object_type force_eof + { + $$ = &DDL{Action: AlterStr, Table: $4, NewName: $4} + } +| ALTER ignore_opt TABLE table_name DROP alter_object_type force_eof + { + $$ = &DDL{Action: AlterStr, Table: $4, NewName: $4} + } +| ALTER ignore_opt TABLE table_name ADD VINDEX sql_id '(' column_list ')' vindex_type_opt vindex_params_opt + { + $$ = &DDL{ + Action: AddColVindexStr, + Table: $4, + VindexSpec: &VindexSpec{ + Name: $7, + Type: $11, + Params: $12, + }, + VindexCols: $9, + } + } +| ALTER ignore_opt TABLE table_name DROP VINDEX sql_id + { + $$ = &DDL{ + Action: DropColVindexStr, + Table: $4, + VindexSpec: &VindexSpec{ + Name: $7, + }, + } + } +| ALTER ignore_opt TABLE table_name RENAME to_opt table_name + { + // Change this to a rename statement + $$ = &DDL{Action: RenameStr, Table: $4, NewName: $7} + } +| ALTER ignore_opt TABLE table_name RENAME index_opt force_eof + { + // Rename an index can just be an alter + $$ = &DDL{Action: AlterStr, Table: $4, NewName: $4} + } +| ALTER VIEW table_name ddl_force_eof + { + $$ = &DDL{Action: AlterStr, Table: $3.ToViewName(), NewName: $3.ToViewName()} + } +| ALTER ignore_opt TABLE table_name partition_operation + { + $$ = &DDL{Action: AlterStr, Table: $4, PartitionSpec: $5} + } + +alter_object_type: + COLUMN +| CONSTRAINT +| FOREIGN +| FULLTEXT +| ID +| INDEX +| KEY +| PRIMARY +| SPATIAL +| PARTITION +| UNIQUE + +partition_operation: + REORGANIZE PARTITION sql_id INTO openb partition_definitions closeb + { + $$ = &PartitionSpec{Action: ReorganizeStr, Name: $3, Definitions: $6} + } + +partition_definitions: + partition_definition + { + $$ = []*PartitionDefinition{$1} + } +| partition_definitions ',' partition_definition + { + $$ = append($1, $3) + } + +partition_definition: + PARTITION sql_id VALUES LESS THAN openb value_expression closeb + { + $$ = &PartitionDefinition{Name: $2, Limit: $7} + } +| PARTITION sql_id VALUES LESS THAN openb MAXVALUE closeb + { + $$ = &PartitionDefinition{Name: $2, Maxvalue: true} + } + +rename_statement: + RENAME TABLE table_name TO table_name + { + $$ = &DDL{Action: RenameStr, Table: $3, NewName: $5} + } + +drop_statement: + DROP TABLE exists_opt table_name + { + var exists bool + if $3 != 0 { + exists = true + } + $$ = &DDL{Action: DropStr, Table: $4, IfExists: exists} + } +| DROP INDEX ID ON table_name ddl_force_eof + { + // Change this to an alter statement + $$ = &DDL{Action: AlterStr, Table: $5, NewName: $5} + } +| DROP VIEW exists_opt table_name ddl_force_eof + { + var exists bool + if $3 != 0 { + exists = true + } + $$ = &DDL{Action: DropStr, Table: $4.ToViewName(), IfExists: exists} + } +| DROP DATABASE exists_opt ID + { + $$ = &DBDDL{Action: DropStr, DBName: string($4)} + } +| DROP SCHEMA exists_opt ID + { + $$ = &DBDDL{Action: DropStr, DBName: string($4)} + } + +truncate_statement: + TRUNCATE TABLE table_name + { + $$ = &DDL{Action: TruncateStr, Table: $3} + } +| TRUNCATE table_name + { + $$ = &DDL{Action: TruncateStr, Table: $2} + } +analyze_statement: + ANALYZE TABLE table_name + { + $$ = &DDL{Action: AlterStr, Table: $3, NewName: $3} + } + +show_statement: + SHOW BINARY ID ddl_force_eof /* SHOW BINARY LOGS */ + { + $$ = &Show{Type: string($2) + " " + string($3)} + } +| SHOW CHARACTER SET ddl_force_eof + { + $$ = &Show{Type: string($2) + " " + string($3)} + } +| SHOW CREATE DATABASE ddl_force_eof + { + $$ = &Show{Type: string($2) + " " + string($3)} + } +/* Rule to handle SHOW CREATE EVENT, SHOW CREATE FUNCTION, etc. */ +| SHOW CREATE ID ddl_force_eof + { + $$ = &Show{Type: string($2) + " " + string($3)} + } +| SHOW CREATE PROCEDURE ddl_force_eof + { + $$ = &Show{Type: string($2) + " " + string($3)} + } +| SHOW CREATE TABLE ddl_force_eof + { + $$ = &Show{Type: string($2) + " " + string($3)} + } +| SHOW CREATE TRIGGER ddl_force_eof + { + $$ = &Show{Type: string($2) + " " + string($3)} + } +| SHOW CREATE VIEW ddl_force_eof + { + $$ = &Show{Type: string($2) + " " + string($3)} + } +| SHOW DATABASES ddl_force_eof + { + $$ = &Show{Type: string($2)} + } +| SHOW INDEX ddl_force_eof + { + $$ = &Show{Type: string($2)} + } +| SHOW KEYS ddl_force_eof + { + $$ = &Show{Type: string($2)} + } +| SHOW PROCEDURE ddl_force_eof + { + $$ = &Show{Type: string($2)} + } +| SHOW show_session_or_global STATUS ddl_force_eof + { + $$ = &Show{Scope: $2, Type: string($3)} + } +| SHOW TABLE ddl_force_eof + { + $$ = &Show{Type: string($2)} + } +| SHOW extended_opt full_opt tables_or_processlist from_database_opt like_or_where_opt + { + // this is ugly, but I couldn't find a better way for now + if $4 == "processlist" { + $$ = &Show{Type: $4} + } else { + showTablesOpt := &ShowTablesOpt{Extended: $2, Full:$3, DbName:$5, Filter:$6} + $$ = &Show{Type: $4, ShowTablesOpt: showTablesOpt} + } + } +| SHOW show_session_or_global VARIABLES ddl_force_eof + { + $$ = &Show{Scope: $2, Type: string($3)} + } +| SHOW VINDEXES + { + $$ = &Show{Type: string($2)} + } +| SHOW VINDEXES ON table_name + { + $$ = &Show{Type: string($2), OnTable: $4} + } +| SHOW VITESS_KEYSPACES + { + $$ = &Show{Type: string($2)} + } +| SHOW VITESS_SHARDS + { + $$ = &Show{Type: string($2)} + } +| SHOW VITESS_TABLETS + { + $$ = &Show{Type: string($2)} + } +| SHOW VSCHEMA_TABLES + { + $$ = &Show{Type: string($2)} + } +/* + * Catch-all for show statements without vitess keywords: + * + * SHOW BINARY LOGS + * SHOW INVALID + */ +| SHOW ID ddl_force_eof + { + $$ = &Show{Type: string($2)} + } + +tables_or_processlist: + TABLES + { + $$ = string($1) + } +| PROCESSLIST + { + $$ = string($1) + } + +extended_opt: + /* empty */ + { + $$ = "" + } +| EXTENDED + { + $$ = "extended " + } + +full_opt: + /* empty */ + { + $$ = "" + } +| FULL + { + $$ = "full " + } + +from_database_opt: + /* empty */ + { + $$ = "" + } +| FROM table_id + { + $$ = $2.v + } +| IN table_id + { + $$ = $2.v + } + +like_or_where_opt: + /* empty */ + { + $$ = nil + } +| LIKE STRING + { + $$ = &ShowFilter{Like:string($2)} + } +| WHERE expression + { + $$ = &ShowFilter{Filter:$2} + } + +show_session_or_global: + /* empty */ + { + $$ = "" + } +| SESSION + { + $$ = SessionStr + } +| GLOBAL + { + $$ = GlobalStr + } + +use_statement: + USE table_id + { + $$ = &Use{DBName: $2} + } +| USE + { + $$ = &Use{DBName:TableIdent{v:""}} + } + +begin_statement: + BEGIN + { + $$ = &Begin{} + } +| START TRANSACTION + { + $$ = &Begin{} + } + +commit_statement: + COMMIT + { + $$ = &Commit{} + } + +rollback_statement: + ROLLBACK + { + $$ = &Rollback{} + } + +other_statement: + DESC force_eof + { + $$ = &OtherRead{} + } +| DESCRIBE force_eof + { + $$ = &OtherRead{} + } +| EXPLAIN force_eof + { + $$ = &OtherRead{} + } +| REPAIR force_eof + { + $$ = &OtherAdmin{} + } +| OPTIMIZE force_eof + { + $$ = &OtherAdmin{} + } + +comment_opt: + { + setAllowComments(yylex, true) + } + comment_list + { + $$ = $2 + setAllowComments(yylex, false) + } + +comment_list: + { + $$ = nil + } +| comment_list COMMENT + { + $$ = append($1, $2) + } + +union_op: + UNION + { + $$ = UnionStr + } +| UNION ALL + { + $$ = UnionAllStr + } +| UNION DISTINCT + { + $$ = UnionDistinctStr + } + +cache_opt: +{ + $$ = "" +} +| SQL_NO_CACHE +{ + $$ = SQLNoCacheStr +} +| SQL_CACHE +{ + $$ = SQLCacheStr +} + +distinct_opt: + { + $$ = "" + } +| DISTINCT + { + $$ = DistinctStr + } + +straight_join_opt: + { + $$ = "" + } +| STRAIGHT_JOIN + { + $$ = StraightJoinHint + } + +select_expression_list_opt: + { + $$ = nil + } +| select_expression_list + { + $$ = $1 + } + +select_expression_list: + select_expression + { + $$ = SelectExprs{$1} + } +| select_expression_list ',' select_expression + { + $$ = append($$, $3) + } + +select_expression: + '*' + { + $$ = &StarExpr{} + } +| expression as_ci_opt + { + $$ = &AliasedExpr{Expr: $1, As: $2} + } +| table_id '.' '*' + { + $$ = &StarExpr{TableName: TableName{Name: $1}} + } +| table_id '.' reserved_table_id '.' '*' + { + $$ = &StarExpr{TableName: TableName{Qualifier: $1, Name: $3}} + } + +as_ci_opt: + { + $$ = ColIdent{} + } +| col_alias + { + $$ = $1 + } +| AS col_alias + { + $$ = $2 + } + +col_alias: + sql_id +| STRING + { + $$ = NewColIdent(string($1)) + } + +from_opt: + { + $$ = TableExprs{&AliasedTableExpr{Expr:TableName{Name: NewTableIdent("dual")}}} + } +| FROM table_references + { + $$ = $2 + } + +table_references: + table_reference + { + $$ = TableExprs{$1} + } +| table_references ',' table_reference + { + $$ = append($$, $3) + } + +table_reference: + table_factor +| join_table + +table_factor: + aliased_table_name + { + $$ = $1 + } +| subquery as_opt table_id + { + $$ = &AliasedTableExpr{Expr:$1, As: $3} + } +| openb table_references closeb + { + $$ = &ParenTableExpr{Exprs: $2} + } + +aliased_table_name: +table_name as_opt_id index_hint_list + { + $$ = &AliasedTableExpr{Expr:$1, As: $2, Hints: $3} + } +| table_name PARTITION openb partition_list closeb as_opt_id index_hint_list + { + $$ = &AliasedTableExpr{Expr:$1, Partitions: $4, As: $6, Hints: $7} + } + +column_list: + sql_id + { + $$ = Columns{$1} + } +| column_list ',' sql_id + { + $$ = append($$, $3) + } + +partition_list: + sql_id + { + $$ = Partitions{$1} + } +| partition_list ',' sql_id + { + $$ = append($$, $3) + } + +// There is a grammar conflict here: +// 1: INSERT INTO a SELECT * FROM b JOIN c ON b.i = c.i +// 2: INSERT INTO a SELECT * FROM b JOIN c ON DUPLICATE KEY UPDATE a.i = 1 +// When yacc encounters the ON clause, it cannot determine which way to +// resolve. The %prec override below makes the parser choose the +// first construct, which automatically makes the second construct a +// syntax error. This is the same behavior as MySQL. +join_table: + table_reference inner_join table_factor join_condition_opt + { + $$ = &JoinTableExpr{LeftExpr: $1, Join: $2, RightExpr: $3, Condition: $4} + } +| table_reference straight_join table_factor on_expression_opt + { + $$ = &JoinTableExpr{LeftExpr: $1, Join: $2, RightExpr: $3, Condition: $4} + } +| table_reference outer_join table_reference join_condition + { + $$ = &JoinTableExpr{LeftExpr: $1, Join: $2, RightExpr: $3, Condition: $4} + } +| table_reference natural_join table_factor + { + $$ = &JoinTableExpr{LeftExpr: $1, Join: $2, RightExpr: $3} + } + +join_condition: + ON expression + { $$ = JoinCondition{On: $2} } +| USING '(' column_list ')' + { $$ = JoinCondition{Using: $3} } + +join_condition_opt: +%prec JOIN + { $$ = JoinCondition{} } +| join_condition + { $$ = $1 } + +on_expression_opt: +%prec JOIN + { $$ = JoinCondition{} } +| ON expression + { $$ = JoinCondition{On: $2} } + +as_opt: + { $$ = struct{}{} } +| AS + { $$ = struct{}{} } + +as_opt_id: + { + $$ = NewTableIdent("") + } +| table_alias + { + $$ = $1 + } +| AS table_alias + { + $$ = $2 + } + +table_alias: + table_id +| STRING + { + $$ = NewTableIdent(string($1)) + } + +inner_join: + JOIN + { + $$ = JoinStr + } +| INNER JOIN + { + $$ = JoinStr + } +| CROSS JOIN + { + $$ = JoinStr + } + +straight_join: + STRAIGHT_JOIN + { + $$ = StraightJoinStr + } + +outer_join: + LEFT JOIN + { + $$ = LeftJoinStr + } +| LEFT OUTER JOIN + { + $$ = LeftJoinStr + } +| RIGHT JOIN + { + $$ = RightJoinStr + } +| RIGHT OUTER JOIN + { + $$ = RightJoinStr + } + +natural_join: + NATURAL JOIN + { + $$ = NaturalJoinStr + } +| NATURAL outer_join + { + if $2 == LeftJoinStr { + $$ = NaturalLeftJoinStr + } else { + $$ = NaturalRightJoinStr + } + } + +into_table_name: + INTO table_name + { + $$ = $2 + } +| table_name + { + $$ = $1 + } + +table_name: + table_id + { + $$ = TableName{Name: $1} + } +| table_id '.' reserved_table_id + { + $$ = TableName{Qualifier: $1, Name: $3} + } + +index_hint_list: + { + $$ = nil + } +| USE INDEX openb column_list closeb + { + $$ = &IndexHints{Type: UseStr, Indexes: $4} + } +| IGNORE INDEX openb column_list closeb + { + $$ = &IndexHints{Type: IgnoreStr, Indexes: $4} + } +| FORCE INDEX openb column_list closeb + { + $$ = &IndexHints{Type: ForceStr, Indexes: $4} + } + +where_expression_opt: + { + $$ = nil + } +| WHERE expression + { + $$ = $2 + } + +expression: + condition + { + $$ = $1 + } +| expression AND expression + { + $$ = &AndExpr{Left: $1, Right: $3} + } +| expression OR expression + { + $$ = &OrExpr{Left: $1, Right: $3} + } +| NOT expression + { + $$ = &NotExpr{Expr: $2} + } +| expression IS is_suffix + { + $$ = &IsExpr{Operator: $3, Expr: $1} + } +| value_expression + { + $$ = $1 + } +| DEFAULT default_opt + { + $$ = &Default{ColName: $2} + } + +default_opt: + /* empty */ + { + $$ = "" + } +| openb ID closeb + { + $$ = string($2) + } + +boolean_value: + TRUE + { + $$ = BoolVal(true) + } +| FALSE + { + $$ = BoolVal(false) + } + +condition: + value_expression compare value_expression + { + $$ = &ComparisonExpr{Left: $1, Operator: $2, Right: $3} + } +| value_expression IN col_tuple + { + $$ = &ComparisonExpr{Left: $1, Operator: InStr, Right: $3} + } +| value_expression NOT IN col_tuple + { + $$ = &ComparisonExpr{Left: $1, Operator: NotInStr, Right: $4} + } +| value_expression LIKE value_expression like_escape_opt + { + $$ = &ComparisonExpr{Left: $1, Operator: LikeStr, Right: $3, Escape: $4} + } +| value_expression NOT LIKE value_expression like_escape_opt + { + $$ = &ComparisonExpr{Left: $1, Operator: NotLikeStr, Right: $4, Escape: $5} + } +| value_expression REGEXP value_expression + { + $$ = &ComparisonExpr{Left: $1, Operator: RegexpStr, Right: $3} + } +| value_expression NOT REGEXP value_expression + { + $$ = &ComparisonExpr{Left: $1, Operator: NotRegexpStr, Right: $4} + } +| value_expression BETWEEN value_expression AND value_expression + { + $$ = &RangeCond{Left: $1, Operator: BetweenStr, From: $3, To: $5} + } +| value_expression NOT BETWEEN value_expression AND value_expression + { + $$ = &RangeCond{Left: $1, Operator: NotBetweenStr, From: $4, To: $6} + } +| EXISTS subquery + { + $$ = &ExistsExpr{Subquery: $2} + } + +is_suffix: + NULL + { + $$ = IsNullStr + } +| NOT NULL + { + $$ = IsNotNullStr + } +| TRUE + { + $$ = IsTrueStr + } +| NOT TRUE + { + $$ = IsNotTrueStr + } +| FALSE + { + $$ = IsFalseStr + } +| NOT FALSE + { + $$ = IsNotFalseStr + } + +compare: + '=' + { + $$ = EqualStr + } +| '<' + { + $$ = LessThanStr + } +| '>' + { + $$ = GreaterThanStr + } +| LE + { + $$ = LessEqualStr + } +| GE + { + $$ = GreaterEqualStr + } +| NE + { + $$ = NotEqualStr + } +| NULL_SAFE_EQUAL + { + $$ = NullSafeEqualStr + } + +like_escape_opt: + { + $$ = nil + } +| ESCAPE value_expression + { + $$ = $2 + } + +col_tuple: + row_tuple + { + $$ = $1 + } +| subquery + { + $$ = $1 + } +| LIST_ARG + { + $$ = ListArg($1) + } + +subquery: + openb select_statement closeb + { + $$ = &Subquery{$2} + } + +expression_list: + expression + { + $$ = Exprs{$1} + } +| expression_list ',' expression + { + $$ = append($1, $3) + } + +value_expression: + value + { + $$ = $1 + } +| boolean_value + { + $$ = $1 + } +| column_name + { + $$ = $1 + } +| tuple_expression + { + $$ = $1 + } +| subquery + { + $$ = $1 + } +| value_expression '&' value_expression + { + $$ = &BinaryExpr{Left: $1, Operator: BitAndStr, Right: $3} + } +| value_expression '|' value_expression + { + $$ = &BinaryExpr{Left: $1, Operator: BitOrStr, Right: $3} + } +| value_expression '^' value_expression + { + $$ = &BinaryExpr{Left: $1, Operator: BitXorStr, Right: $3} + } +| value_expression '+' value_expression + { + $$ = &BinaryExpr{Left: $1, Operator: PlusStr, Right: $3} + } +| value_expression '-' value_expression + { + $$ = &BinaryExpr{Left: $1, Operator: MinusStr, Right: $3} + } +| value_expression '*' value_expression + { + $$ = &BinaryExpr{Left: $1, Operator: MultStr, Right: $3} + } +| value_expression '/' value_expression + { + $$ = &BinaryExpr{Left: $1, Operator: DivStr, Right: $3} + } +| value_expression DIV value_expression + { + $$ = &BinaryExpr{Left: $1, Operator: IntDivStr, Right: $3} + } +| value_expression '%' value_expression + { + $$ = &BinaryExpr{Left: $1, Operator: ModStr, Right: $3} + } +| value_expression MOD value_expression + { + $$ = &BinaryExpr{Left: $1, Operator: ModStr, Right: $3} + } +| value_expression SHIFT_LEFT value_expression + { + $$ = &BinaryExpr{Left: $1, Operator: ShiftLeftStr, Right: $3} + } +| value_expression SHIFT_RIGHT value_expression + { + $$ = &BinaryExpr{Left: $1, Operator: ShiftRightStr, Right: $3} + } +| column_name JSON_EXTRACT_OP value + { + $$ = &BinaryExpr{Left: $1, Operator: JSONExtractOp, Right: $3} + } +| column_name JSON_UNQUOTE_EXTRACT_OP value + { + $$ = &BinaryExpr{Left: $1, Operator: JSONUnquoteExtractOp, Right: $3} + } +| value_expression COLLATE charset + { + $$ = &CollateExpr{Expr: $1, Charset: $3} + } +| BINARY value_expression %prec UNARY + { + $$ = &UnaryExpr{Operator: BinaryStr, Expr: $2} + } +| UNDERSCORE_BINARY value_expression %prec UNARY + { + $$ = &UnaryExpr{Operator: UBinaryStr, Expr: $2} + } +| '+' value_expression %prec UNARY + { + if num, ok := $2.(*SQLVal); ok && num.Type == IntVal { + $$ = num + } else { + $$ = &UnaryExpr{Operator: UPlusStr, Expr: $2} + } + } +| '-' value_expression %prec UNARY + { + if num, ok := $2.(*SQLVal); ok && num.Type == IntVal { + // Handle double negative + if num.Val[0] == '-' { + num.Val = num.Val[1:] + $$ = num + } else { + $$ = NewIntVal(append([]byte("-"), num.Val...)) + } + } else { + $$ = &UnaryExpr{Operator: UMinusStr, Expr: $2} + } + } +| '~' value_expression + { + $$ = &UnaryExpr{Operator: TildaStr, Expr: $2} + } +| '!' value_expression %prec UNARY + { + $$ = &UnaryExpr{Operator: BangStr, Expr: $2} + } +| INTERVAL value_expression sql_id + { + // This rule prevents the usage of INTERVAL + // as a function. If support is needed for that, + // we'll need to revisit this. The solution + // will be non-trivial because of grammar conflicts. + $$ = &IntervalExpr{Expr: $2, Unit: $3.String()} + } +| function_call_generic +| function_call_keyword +| function_call_nonkeyword +| function_call_conflict + +/* + Regular function calls without special token or syntax, guaranteed to not + introduce side effects due to being a simple identifier +*/ +function_call_generic: + sql_id openb select_expression_list_opt closeb + { + $$ = &FuncExpr{Name: $1, Exprs: $3} + } +| sql_id openb DISTINCT select_expression_list closeb + { + $$ = &FuncExpr{Name: $1, Distinct: true, Exprs: $4} + } +| table_id '.' reserved_sql_id openb select_expression_list_opt closeb + { + $$ = &FuncExpr{Qualifier: $1, Name: $3, Exprs: $5} + } + +/* + Function calls using reserved keywords, with dedicated grammar rules + as a result +*/ +function_call_keyword: + LEFT openb select_expression_list closeb + { + $$ = &FuncExpr{Name: NewColIdent("left"), Exprs: $3} + } +| RIGHT openb select_expression_list closeb + { + $$ = &FuncExpr{Name: NewColIdent("right"), Exprs: $3} + } +| CONVERT openb expression ',' convert_type closeb + { + $$ = &ConvertExpr{Expr: $3, Type: $5} + } +| CAST openb expression AS convert_type closeb + { + $$ = &ConvertExpr{Expr: $3, Type: $5} + } +| CONVERT openb expression USING charset closeb + { + $$ = &ConvertUsingExpr{Expr: $3, Type: $5} + } +| SUBSTR openb column_name ',' value_expression closeb + { + $$ = &SubstrExpr{Name: $3, From: $5, To: nil} + } +| SUBSTR openb column_name ',' value_expression ',' value_expression closeb + { + $$ = &SubstrExpr{Name: $3, From: $5, To: $7} + } +| SUBSTR openb column_name FROM value_expression FOR value_expression closeb + { + $$ = &SubstrExpr{Name: $3, From: $5, To: $7} + } +| SUBSTRING openb column_name ',' value_expression closeb + { + $$ = &SubstrExpr{Name: $3, From: $5, To: nil} + } +| SUBSTRING openb column_name ',' value_expression ',' value_expression closeb + { + $$ = &SubstrExpr{Name: $3, From: $5, To: $7} + } +| SUBSTRING openb column_name FROM value_expression FOR value_expression closeb + { + $$ = &SubstrExpr{Name: $3, From: $5, To: $7} + } +| MATCH openb select_expression_list closeb AGAINST openb value_expression match_option closeb + { + $$ = &MatchExpr{Columns: $3, Expr: $7, Option: $8} + } +| GROUP_CONCAT openb distinct_opt select_expression_list order_by_opt separator_opt closeb + { + $$ = &GroupConcatExpr{Distinct: $3, Exprs: $4, OrderBy: $5, Separator: $6} + } +| CASE expression_opt when_expression_list else_expression_opt END + { + $$ = &CaseExpr{Expr: $2, Whens: $3, Else: $4} + } +| VALUES openb column_name closeb + { + $$ = &ValuesFuncExpr{Name: $3} + } + +/* + Function calls using non reserved keywords but with special syntax forms. + Dedicated grammar rules are needed because of the special syntax +*/ +function_call_nonkeyword: + CURRENT_TIMESTAMP func_datetime_precision_opt + { + $$ = &FuncExpr{Name:NewColIdent("current_timestamp")} + } +| UTC_TIMESTAMP func_datetime_precision_opt + { + $$ = &FuncExpr{Name:NewColIdent("utc_timestamp")} + } +| UTC_TIME func_datetime_precision_opt + { + $$ = &FuncExpr{Name:NewColIdent("utc_time")} + } +| UTC_DATE func_datetime_precision_opt + { + $$ = &FuncExpr{Name:NewColIdent("utc_date")} + } + // now +| LOCALTIME func_datetime_precision_opt + { + $$ = &FuncExpr{Name:NewColIdent("localtime")} + } + // now +| LOCALTIMESTAMP func_datetime_precision_opt + { + $$ = &FuncExpr{Name:NewColIdent("localtimestamp")} + } + // curdate +| CURRENT_DATE func_datetime_precision_opt + { + $$ = &FuncExpr{Name:NewColIdent("current_date")} + } + // curtime +| CURRENT_TIME func_datetime_precision_opt + { + $$ = &FuncExpr{Name:NewColIdent("current_time")} + } + +func_datetime_precision_opt: + /* empty */ +| openb closeb + +/* + Function calls using non reserved keywords with *normal* syntax forms. Because + the names are non-reserved, they need a dedicated rule so as not to conflict +*/ +function_call_conflict: + IF openb select_expression_list closeb + { + $$ = &FuncExpr{Name: NewColIdent("if"), Exprs: $3} + } +| DATABASE openb select_expression_list_opt closeb + { + $$ = &FuncExpr{Name: NewColIdent("database"), Exprs: $3} + } +| MOD openb select_expression_list closeb + { + $$ = &FuncExpr{Name: NewColIdent("mod"), Exprs: $3} + } +| REPLACE openb select_expression_list closeb + { + $$ = &FuncExpr{Name: NewColIdent("replace"), Exprs: $3} + } + +match_option: +/*empty*/ + { + $$ = "" + } +| IN BOOLEAN MODE + { + $$ = BooleanModeStr + } +| IN NATURAL LANGUAGE MODE + { + $$ = NaturalLanguageModeStr + } +| IN NATURAL LANGUAGE MODE WITH QUERY EXPANSION + { + $$ = NaturalLanguageModeWithQueryExpansionStr + } +| WITH QUERY EXPANSION + { + $$ = QueryExpansionStr + } + +charset: + ID +{ + $$ = string($1) +} +| STRING +{ + $$ = string($1) +} + +convert_type: + BINARY length_opt + { + $$ = &ConvertType{Type: string($1), Length: $2} + } +| CHAR length_opt charset_opt + { + $$ = &ConvertType{Type: string($1), Length: $2, Charset: $3, Operator: CharacterSetStr} + } +| CHAR length_opt ID + { + $$ = &ConvertType{Type: string($1), Length: $2, Charset: string($3)} + } +| DATE + { + $$ = &ConvertType{Type: string($1)} + } +| DATETIME length_opt + { + $$ = &ConvertType{Type: string($1), Length: $2} + } +| DECIMAL decimal_length_opt + { + $$ = &ConvertType{Type: string($1)} + $$.Length = $2.Length + $$.Scale = $2.Scale + } +| JSON + { + $$ = &ConvertType{Type: string($1)} + } +| NCHAR length_opt + { + $$ = &ConvertType{Type: string($1), Length: $2} + } +| SIGNED + { + $$ = &ConvertType{Type: string($1)} + } +| SIGNED INTEGER + { + $$ = &ConvertType{Type: string($1)} + } +| TIME length_opt + { + $$ = &ConvertType{Type: string($1), Length: $2} + } +| UNSIGNED + { + $$ = &ConvertType{Type: string($1)} + } +| UNSIGNED INTEGER + { + $$ = &ConvertType{Type: string($1)} + } + +expression_opt: + { + $$ = nil + } +| expression + { + $$ = $1 + } + +separator_opt: + { + $$ = string("") + } +| SEPARATOR STRING + { + $$ = " separator '"+string($2)+"'" + } + +when_expression_list: + when_expression + { + $$ = []*When{$1} + } +| when_expression_list when_expression + { + $$ = append($1, $2) + } + +when_expression: + WHEN expression THEN expression + { + $$ = &When{Cond: $2, Val: $4} + } + +else_expression_opt: + { + $$ = nil + } +| ELSE expression + { + $$ = $2 + } + +column_name: + sql_id + { + $$ = &ColName{Name: $1} + } +| table_id '.' reserved_sql_id + { + $$ = &ColName{Qualifier: TableName{Name: $1}, Name: $3} + } +| table_id '.' reserved_table_id '.' reserved_sql_id + { + $$ = &ColName{Qualifier: TableName{Qualifier: $1, Name: $3}, Name: $5} + } + +value: + STRING + { + $$ = NewStrVal($1) + } +| HEX + { + $$ = NewHexVal($1) + } +| BIT_LITERAL + { + $$ = NewBitVal($1) + } +| INTEGRAL + { + $$ = NewIntVal($1) + } +| FLOAT + { + $$ = NewFloatVal($1) + } +| HEXNUM + { + $$ = NewHexNum($1) + } +| VALUE_ARG + { + $$ = NewValArg($1) + } +| NULL + { + $$ = &NullVal{} + } + +num_val: + sql_id + { + // TODO(sougou): Deprecate this construct. + if $1.Lowered() != "value" { + yylex.Error("expecting value after next") + return 1 + } + $$ = NewIntVal([]byte("1")) + } +| INTEGRAL VALUES + { + $$ = NewIntVal($1) + } +| VALUE_ARG VALUES + { + $$ = NewValArg($1) + } + +group_by_opt: + { + $$ = nil + } +| GROUP BY expression_list + { + $$ = $3 + } + +having_opt: + { + $$ = nil + } +| HAVING expression + { + $$ = $2 + } + +order_by_opt: + { + $$ = nil + } +| ORDER BY order_list + { + $$ = $3 + } + +order_list: + order + { + $$ = OrderBy{$1} + } +| order_list ',' order + { + $$ = append($1, $3) + } + +order: + expression asc_desc_opt + { + $$ = &Order{Expr: $1, Direction: $2} + } + +asc_desc_opt: + { + $$ = AscScr + } +| ASC + { + $$ = AscScr + } +| DESC + { + $$ = DescScr + } + +limit_opt: + { + $$ = nil + } +| LIMIT expression + { + $$ = &Limit{Rowcount: $2} + } +| LIMIT expression ',' expression + { + $$ = &Limit{Offset: $2, Rowcount: $4} + } +| LIMIT expression OFFSET expression + { + $$ = &Limit{Offset: $4, Rowcount: $2} + } + +lock_opt: + { + $$ = "" + } +| FOR UPDATE + { + $$ = ForUpdateStr + } +| LOCK IN SHARE MODE + { + $$ = ShareModeStr + } + +// insert_data expands all combinations into a single rule. +// This avoids a shift/reduce conflict while encountering the +// following two possible constructs: +// insert into t1(a, b) (select * from t2) +// insert into t1(select * from t2) +// Because the rules are together, the parser can keep shifting +// the tokens until it disambiguates a as sql_id and select as keyword. +insert_data: + VALUES tuple_list + { + $$ = &Insert{Rows: $2} + } +| select_statement + { + $$ = &Insert{Rows: $1} + } +| openb select_statement closeb + { + // Drop the redundant parenthesis. + $$ = &Insert{Rows: $2} + } +| openb ins_column_list closeb VALUES tuple_list + { + $$ = &Insert{Columns: $2, Rows: $5} + } +| openb ins_column_list closeb select_statement + { + $$ = &Insert{Columns: $2, Rows: $4} + } +| openb ins_column_list closeb openb select_statement closeb + { + // Drop the redundant parenthesis. + $$ = &Insert{Columns: $2, Rows: $5} + } + +ins_column_list: + sql_id + { + $$ = Columns{$1} + } +| sql_id '.' sql_id + { + $$ = Columns{$3} + } +| ins_column_list ',' sql_id + { + $$ = append($$, $3) + } +| ins_column_list ',' sql_id '.' sql_id + { + $$ = append($$, $5) + } + +on_dup_opt: + { + $$ = nil + } +| ON DUPLICATE KEY UPDATE update_list + { + $$ = $5 + } + +tuple_list: + tuple_or_empty + { + $$ = Values{$1} + } +| tuple_list ',' tuple_or_empty + { + $$ = append($1, $3) + } + +tuple_or_empty: + row_tuple + { + $$ = $1 + } +| openb closeb + { + $$ = ValTuple{} + } + +row_tuple: + openb expression_list closeb + { + $$ = ValTuple($2) + } + +tuple_expression: + row_tuple + { + if len($1) == 1 { + $$ = &ParenExpr{$1[0]} + } else { + $$ = $1 + } + } + +update_list: + update_expression + { + $$ = UpdateExprs{$1} + } +| update_list ',' update_expression + { + $$ = append($1, $3) + } + +update_expression: + column_name '=' expression + { + $$ = &UpdateExpr{Name: $1, Expr: $3} + } + +set_list: + set_expression + { + $$ = SetExprs{$1} + } +| set_list ',' set_expression + { + $$ = append($1, $3) + } + +set_expression: + reserved_sql_id '=' ON + { + $$ = &SetExpr{Name: $1, Expr: NewStrVal([]byte("on"))} + } +| reserved_sql_id '=' expression + { + $$ = &SetExpr{Name: $1, Expr: $3} + } +| charset_or_character_set charset_value collate_opt + { + $$ = &SetExpr{Name: NewColIdent(string($1)), Expr: $2} + } + +charset_or_character_set: + CHARSET +| CHARACTER SET + { + $$ = []byte("charset") + } +| NAMES + +charset_value: + sql_id + { + $$ = NewStrVal([]byte($1.String())) + } +| STRING + { + $$ = NewStrVal($1) + } +| DEFAULT + { + $$ = &Default{} + } + +for_from: + FOR +| FROM + +exists_opt: + { $$ = 0 } +| IF EXISTS + { $$ = 1 } + +not_exists_opt: + { $$ = struct{}{} } +| IF NOT EXISTS + { $$ = struct{}{} } + +ignore_opt: + { $$ = "" } +| IGNORE + { $$ = IgnoreStr } + +non_add_drop_or_rename_operation: + ALTER + { $$ = struct{}{} } +| AUTO_INCREMENT + { $$ = struct{}{} } +| CHARACTER + { $$ = struct{}{} } +| COMMENT_KEYWORD + { $$ = struct{}{} } +| DEFAULT + { $$ = struct{}{} } +| ORDER + { $$ = struct{}{} } +| CONVERT + { $$ = struct{}{} } +| PARTITION + { $$ = struct{}{} } +| UNUSED + { $$ = struct{}{} } +| ID + { $$ = struct{}{} } + +to_opt: + { $$ = struct{}{} } +| TO + { $$ = struct{}{} } +| AS + { $$ = struct{}{} } + +index_opt: + INDEX + { $$ = struct{}{} } +| KEY + { $$ = struct{}{} } + +constraint_opt: + { $$ = struct{}{} } +| UNIQUE + { $$ = struct{}{} } +| sql_id + { $$ = struct{}{} } + +using_opt: + { $$ = ColIdent{} } +| USING sql_id + { $$ = $2 } + +sql_id: + ID + { + $$ = NewColIdent(string($1)) + } +| non_reserved_keyword + { + $$ = NewColIdent(string($1)) + } + +reserved_sql_id: + sql_id +| reserved_keyword + { + $$ = NewColIdent(string($1)) + } + +table_id: + ID + { + $$ = NewTableIdent(string($1)) + } +| non_reserved_keyword + { + $$ = NewTableIdent(string($1)) + } + +reserved_table_id: + table_id +| reserved_keyword + { + $$ = NewTableIdent(string($1)) + } + +/* + These are not all necessarily reserved in MySQL, but some are. + + These are more importantly reserved because they may conflict with our grammar. + If you want to move one that is not reserved in MySQL (i.e. ESCAPE) to the + non_reserved_keywords, you'll need to deal with any conflicts. + + Sorted alphabetically +*/ +reserved_keyword: + ADD +| AND +| AS +| ASC +| AUTO_INCREMENT +| BETWEEN +| BINARY +| BY +| CASE +| COLLATE +| CONVERT +| CREATE +| CROSS +| CURRENT_DATE +| CURRENT_TIME +| CURRENT_TIMESTAMP +| SUBSTR +| SUBSTRING +| DATABASE +| DATABASES +| DEFAULT +| DELETE +| DESC +| DESCRIBE +| DISTINCT +| DIV +| DROP +| ELSE +| END +| ESCAPE +| EXISTS +| EXPLAIN +| FALSE +| FOR +| FORCE +| FROM +| GROUP +| HAVING +| IF +| IGNORE +| IN +| INDEX +| INNER +| INSERT +| INTERVAL +| INTO +| IS +| JOIN +| KEY +| LEFT +| LIKE +| LIMIT +| LOCALTIME +| LOCALTIMESTAMP +| LOCK +| MATCH +| MAXVALUE +| MOD +| NATURAL +| NEXT // next should be doable as non-reserved, but is not due to the special `select next num_val` query that vitess supports +| NOT +| NULL +| ON +| OR +| ORDER +| OUTER +| REGEXP +| RENAME +| REPLACE +| RIGHT +| SCHEMA +| SELECT +| SEPARATOR +| SET +| SHOW +| STRAIGHT_JOIN +| TABLE +| TABLES +| THEN +| TO +| TRUE +| UNION +| UNIQUE +| UPDATE +| USE +| USING +| UTC_DATE +| UTC_TIME +| UTC_TIMESTAMP +| VALUES +| WHEN +| WHERE + +/* + These are non-reserved Vitess, because they don't cause conflicts in the grammar. + Some of them may be reserved in MySQL. The good news is we backtick quote them + when we rewrite the query, so no issue should arise. + + Sorted alphabetically +*/ +non_reserved_keyword: + AGAINST +| BEGIN +| BIGINT +| BIT +| BLOB +| BOOL +| CHAR +| CHARACTER +| CHARSET +| COMMENT_KEYWORD +| COMMIT +| COMMITTED +| DATE +| DATETIME +| DECIMAL +| DOUBLE +| DUPLICATE +| ENUM +| EXPANSION +| FLOAT_TYPE +| FOREIGN +| FULLTEXT +| GEOMETRY +| GEOMETRYCOLLECTION +| GLOBAL +| INT +| INTEGER +| ISOLATION +| JSON +| KEY_BLOCK_SIZE +| KEYS +| LANGUAGE +| LAST_INSERT_ID +| LESS +| LEVEL +| LINESTRING +| LONGBLOB +| LONGTEXT +| MEDIUMBLOB +| MEDIUMINT +| MEDIUMTEXT +| MODE +| MULTILINESTRING +| MULTIPOINT +| MULTIPOLYGON +| NAMES +| NCHAR +| NUMERIC +| OFFSET +| ONLY +| OPTIMIZE +| PARTITION +| POINT +| POLYGON +| PRIMARY +| PROCEDURE +| QUERY +| READ +| REAL +| REORGANIZE +| REPAIR +| REPEATABLE +| ROLLBACK +| SESSION +| SERIALIZABLE +| SHARE +| SIGNED +| SMALLINT +| SPATIAL +| START +| STATUS +| TEXT +| THAN +| TIME +| TIMESTAMP +| TINYBLOB +| TINYINT +| TINYTEXT +| TRANSACTION +| TRIGGER +| TRUNCATE +| UNCOMMITTED +| UNSIGNED +| UNUSED +| VARBINARY +| VARCHAR +| VARIABLES +| VIEW +| VINDEX +| VINDEXES +| VITESS_KEYSPACES +| VITESS_SHARDS +| VITESS_TABLETS +| VSCHEMA_TABLES +| WITH +| WRITE +| YEAR +| ZEROFILL + +openb: + '(' + { + if incNesting(yylex) { + yylex.Error("max nesting level reached") + return 1 + } + } + +closeb: + ')' + { + decNesting(yylex) + } + +force_eof: +{ + forceEOF(yylex) +} + +ddl_force_eof: + { + forceEOF(yylex) + } +| openb + { + forceEOF(yylex) + } +| reserved_sql_id + { + forceEOF(yylex) + } diff --git a/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/token.go b/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/token.go new file mode 100644 index 00000000..23efa77c --- /dev/null +++ b/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/token.go @@ -0,0 +1,950 @@ +/* +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 sqlparser + +import ( + "bytes" + "errors" + "fmt" + "io" + + "github.com/xwb1989/sqlparser/dependency/bytes2" + "github.com/xwb1989/sqlparser/dependency/sqltypes" +) + +const ( + defaultBufSize = 4096 + eofChar = 0x100 +) + +// Tokenizer is the struct used to generate SQL +// tokens for the parser. +type Tokenizer struct { + InStream io.Reader + AllowComments bool + ForceEOF bool + lastChar uint16 + Position int + lastToken []byte + LastError error + posVarIndex int + ParseTree Statement + partialDDL *DDL + nesting int + multi bool + specialComment *Tokenizer + + buf []byte + bufPos int + bufSize int +} + +// NewStringTokenizer creates a new Tokenizer for the +// sql string. +func NewStringTokenizer(sql string) *Tokenizer { + buf := []byte(sql) + return &Tokenizer{ + buf: buf, + bufSize: len(buf), + } +} + +// NewTokenizer creates a new Tokenizer reading a sql +// string from the io.Reader. +func NewTokenizer(r io.Reader) *Tokenizer { + return &Tokenizer{ + InStream: r, + buf: make([]byte, defaultBufSize), + } +} + +// keywords is a map of mysql keywords that fall into two categories: +// 1) keywords considered reserved by MySQL +// 2) keywords for us to handle specially in sql.y +// +// Those marked as UNUSED are likely reserved keywords. We add them here so that +// when rewriting queries we can properly backtick quote them so they don't cause issues +// +// NOTE: If you add new keywords, add them also to the reserved_keywords or +// non_reserved_keywords grammar in sql.y -- this will allow the keyword to be used +// in identifiers. See the docs for each grammar to determine which one to put it into. +var keywords = map[string]int{ + "accessible": UNUSED, + "add": ADD, + "against": AGAINST, + "all": ALL, + "alter": ALTER, + "analyze": ANALYZE, + "and": AND, + "as": AS, + "asc": ASC, + "asensitive": UNUSED, + "auto_increment": AUTO_INCREMENT, + "before": UNUSED, + "begin": BEGIN, + "between": BETWEEN, + "bigint": BIGINT, + "binary": BINARY, + "_binary": UNDERSCORE_BINARY, + "bit": BIT, + "blob": BLOB, + "bool": BOOL, + "boolean": BOOLEAN, + "both": UNUSED, + "by": BY, + "call": UNUSED, + "cascade": UNUSED, + "case": CASE, + "cast": CAST, + "change": UNUSED, + "char": CHAR, + "character": CHARACTER, + "charset": CHARSET, + "check": UNUSED, + "collate": COLLATE, + "column": COLUMN, + "comment": COMMENT_KEYWORD, + "committed": COMMITTED, + "commit": COMMIT, + "condition": UNUSED, + "constraint": CONSTRAINT, + "continue": UNUSED, + "convert": CONVERT, + "substr": SUBSTR, + "substring": SUBSTRING, + "create": CREATE, + "cross": CROSS, + "current_date": CURRENT_DATE, + "current_time": CURRENT_TIME, + "current_timestamp": CURRENT_TIMESTAMP, + "current_user": UNUSED, + "cursor": UNUSED, + "database": DATABASE, + "databases": DATABASES, + "day_hour": UNUSED, + "day_microsecond": UNUSED, + "day_minute": UNUSED, + "day_second": UNUSED, + "date": DATE, + "datetime": DATETIME, + "dec": UNUSED, + "decimal": DECIMAL, + "declare": UNUSED, + "default": DEFAULT, + "delayed": UNUSED, + "delete": DELETE, + "desc": DESC, + "describe": DESCRIBE, + "deterministic": UNUSED, + "distinct": DISTINCT, + "distinctrow": UNUSED, + "div": DIV, + "double": DOUBLE, + "drop": DROP, + "duplicate": DUPLICATE, + "each": UNUSED, + "else": ELSE, + "elseif": UNUSED, + "enclosed": UNUSED, + "end": END, + "enum": ENUM, + "escape": ESCAPE, + "escaped": UNUSED, + "exists": EXISTS, + "exit": UNUSED, + "explain": EXPLAIN, + "expansion": EXPANSION, + "extended": EXTENDED, + "false": FALSE, + "fetch": UNUSED, + "float": FLOAT_TYPE, + "float4": UNUSED, + "float8": UNUSED, + "for": FOR, + "force": FORCE, + "foreign": FOREIGN, + "from": FROM, + "full": FULL, + "fulltext": FULLTEXT, + "generated": UNUSED, + "geometry": GEOMETRY, + "geometrycollection": GEOMETRYCOLLECTION, + "get": UNUSED, + "global": GLOBAL, + "grant": UNUSED, + "group": GROUP, + "group_concat": GROUP_CONCAT, + "having": HAVING, + "high_priority": UNUSED, + "hour_microsecond": UNUSED, + "hour_minute": UNUSED, + "hour_second": UNUSED, + "if": IF, + "ignore": IGNORE, + "in": IN, + "index": INDEX, + "infile": UNUSED, + "inout": UNUSED, + "inner": INNER, + "insensitive": UNUSED, + "insert": INSERT, + "int": INT, + "int1": UNUSED, + "int2": UNUSED, + "int3": UNUSED, + "int4": UNUSED, + "int8": UNUSED, + "integer": INTEGER, + "interval": INTERVAL, + "into": INTO, + "io_after_gtids": UNUSED, + "is": IS, + "isolation": ISOLATION, + "iterate": UNUSED, + "join": JOIN, + "json": JSON, + "key": KEY, + "keys": KEYS, + "key_block_size": KEY_BLOCK_SIZE, + "kill": UNUSED, + "language": LANGUAGE, + "last_insert_id": LAST_INSERT_ID, + "leading": UNUSED, + "leave": UNUSED, + "left": LEFT, + "less": LESS, + "level": LEVEL, + "like": LIKE, + "limit": LIMIT, + "linear": UNUSED, + "lines": UNUSED, + "linestring": LINESTRING, + "load": UNUSED, + "localtime": LOCALTIME, + "localtimestamp": LOCALTIMESTAMP, + "lock": LOCK, + "long": UNUSED, + "longblob": LONGBLOB, + "longtext": LONGTEXT, + "loop": UNUSED, + "low_priority": UNUSED, + "master_bind": UNUSED, + "match": MATCH, + "maxvalue": MAXVALUE, + "mediumblob": MEDIUMBLOB, + "mediumint": MEDIUMINT, + "mediumtext": MEDIUMTEXT, + "middleint": UNUSED, + "minute_microsecond": UNUSED, + "minute_second": UNUSED, + "mod": MOD, + "mode": MODE, + "modifies": UNUSED, + "multilinestring": MULTILINESTRING, + "multipoint": MULTIPOINT, + "multipolygon": MULTIPOLYGON, + "names": NAMES, + "natural": NATURAL, + "nchar": NCHAR, + "next": NEXT, + "not": NOT, + "no_write_to_binlog": UNUSED, + "null": NULL, + "numeric": NUMERIC, + "offset": OFFSET, + "on": ON, + "only": ONLY, + "optimize": OPTIMIZE, + "optimizer_costs": UNUSED, + "option": UNUSED, + "optionally": UNUSED, + "or": OR, + "order": ORDER, + "out": UNUSED, + "outer": OUTER, + "outfile": UNUSED, + "partition": PARTITION, + "point": POINT, + "polygon": POLYGON, + "precision": UNUSED, + "primary": PRIMARY, + "processlist": PROCESSLIST, + "procedure": PROCEDURE, + "query": QUERY, + "range": UNUSED, + "read": READ, + "reads": UNUSED, + "read_write": UNUSED, + "real": REAL, + "references": UNUSED, + "regexp": REGEXP, + "release": UNUSED, + "rename": RENAME, + "reorganize": REORGANIZE, + "repair": REPAIR, + "repeat": UNUSED, + "repeatable": REPEATABLE, + "replace": REPLACE, + "require": UNUSED, + "resignal": UNUSED, + "restrict": UNUSED, + "return": UNUSED, + "revoke": UNUSED, + "right": RIGHT, + "rlike": REGEXP, + "rollback": ROLLBACK, + "schema": SCHEMA, + "schemas": UNUSED, + "second_microsecond": UNUSED, + "select": SELECT, + "sensitive": UNUSED, + "separator": SEPARATOR, + "serializable": SERIALIZABLE, + "session": SESSION, + "set": SET, + "share": SHARE, + "show": SHOW, + "signal": UNUSED, + "signed": SIGNED, + "smallint": SMALLINT, + "spatial": SPATIAL, + "specific": UNUSED, + "sql": UNUSED, + "sqlexception": UNUSED, + "sqlstate": UNUSED, + "sqlwarning": UNUSED, + "sql_big_result": UNUSED, + "sql_cache": SQL_CACHE, + "sql_calc_found_rows": UNUSED, + "sql_no_cache": SQL_NO_CACHE, + "sql_small_result": UNUSED, + "ssl": UNUSED, + "start": START, + "starting": UNUSED, + "status": STATUS, + "stored": UNUSED, + "straight_join": STRAIGHT_JOIN, + "stream": STREAM, + "table": TABLE, + "tables": TABLES, + "terminated": UNUSED, + "text": TEXT, + "than": THAN, + "then": THEN, + "time": TIME, + "timestamp": TIMESTAMP, + "tinyblob": TINYBLOB, + "tinyint": TINYINT, + "tinytext": TINYTEXT, + "to": TO, + "trailing": UNUSED, + "transaction": TRANSACTION, + "trigger": TRIGGER, + "true": TRUE, + "truncate": TRUNCATE, + "uncommitted": UNCOMMITTED, + "undo": UNUSED, + "union": UNION, + "unique": UNIQUE, + "unlock": UNUSED, + "unsigned": UNSIGNED, + "update": UPDATE, + "usage": UNUSED, + "use": USE, + "using": USING, + "utc_date": UTC_DATE, + "utc_time": UTC_TIME, + "utc_timestamp": UTC_TIMESTAMP, + "values": VALUES, + "variables": VARIABLES, + "varbinary": VARBINARY, + "varchar": VARCHAR, + "varcharacter": UNUSED, + "varying": UNUSED, + "virtual": UNUSED, + "vindex": VINDEX, + "vindexes": VINDEXES, + "view": VIEW, + "vitess_keyspaces": VITESS_KEYSPACES, + "vitess_shards": VITESS_SHARDS, + "vitess_tablets": VITESS_TABLETS, + "vschema_tables": VSCHEMA_TABLES, + "when": WHEN, + "where": WHERE, + "while": UNUSED, + "with": WITH, + "write": WRITE, + "xor": UNUSED, + "year": YEAR, + "year_month": UNUSED, + "zerofill": ZEROFILL, +} + +// keywordStrings contains the reverse mapping of token to keyword strings +var keywordStrings = map[int]string{} + +func init() { + for str, id := range keywords { + if id == UNUSED { + continue + } + keywordStrings[id] = str + } +} + +// KeywordString returns the string corresponding to the given keyword +func KeywordString(id int) string { + str, ok := keywordStrings[id] + if !ok { + return "" + } + return str +} + +// Lex returns the next token form the Tokenizer. +// This function is used by go yacc. +func (tkn *Tokenizer) Lex(lval *yySymType) int { + typ, val := tkn.Scan() + for typ == COMMENT { + if tkn.AllowComments { + break + } + typ, val = tkn.Scan() + } + lval.bytes = val + tkn.lastToken = val + return typ +} + +// Error is called by go yacc if there's a parsing error. +func (tkn *Tokenizer) Error(err string) { + buf := &bytes2.Buffer{} + if tkn.lastToken != nil { + fmt.Fprintf(buf, "%s at position %v near '%s'", err, tkn.Position, tkn.lastToken) + } else { + fmt.Fprintf(buf, "%s at position %v", err, tkn.Position) + } + tkn.LastError = errors.New(buf.String()) + + // Try and re-sync to the next statement + if tkn.lastChar != ';' { + tkn.skipStatement() + } +} + +// Scan scans the tokenizer for the next token and returns +// the token type and an optional value. +func (tkn *Tokenizer) Scan() (int, []byte) { + if tkn.specialComment != nil { + // Enter specialComment scan mode. + // for scanning such kind of comment: /*! MySQL-specific code */ + specialComment := tkn.specialComment + tok, val := specialComment.Scan() + if tok != 0 { + // return the specialComment scan result as the result + return tok, val + } + // leave specialComment scan mode after all stream consumed. + tkn.specialComment = nil + } + if tkn.lastChar == 0 { + tkn.next() + } + + if tkn.ForceEOF { + tkn.skipStatement() + return 0, nil + } + + tkn.skipBlank() + switch ch := tkn.lastChar; { + case isLetter(ch): + tkn.next() + if ch == 'X' || ch == 'x' { + if tkn.lastChar == '\'' { + tkn.next() + return tkn.scanHex() + } + } + if ch == 'B' || ch == 'b' { + if tkn.lastChar == '\'' { + tkn.next() + return tkn.scanBitLiteral() + } + } + isDbSystemVariable := false + if ch == '@' && tkn.lastChar == '@' { + isDbSystemVariable = true + } + return tkn.scanIdentifier(byte(ch), isDbSystemVariable) + case isDigit(ch): + return tkn.scanNumber(false) + case ch == ':': + return tkn.scanBindVar() + case ch == ';' && tkn.multi: + return 0, nil + default: + tkn.next() + switch ch { + case eofChar: + return 0, nil + case '=', ',', ';', '(', ')', '+', '*', '%', '^', '~': + return int(ch), nil + case '&': + if tkn.lastChar == '&' { + tkn.next() + return AND, nil + } + return int(ch), nil + case '|': + if tkn.lastChar == '|' { + tkn.next() + return OR, nil + } + return int(ch), nil + case '?': + tkn.posVarIndex++ + buf := new(bytes2.Buffer) + fmt.Fprintf(buf, ":v%d", tkn.posVarIndex) + return VALUE_ARG, buf.Bytes() + case '.': + if isDigit(tkn.lastChar) { + return tkn.scanNumber(true) + } + return int(ch), nil + case '/': + switch tkn.lastChar { + case '/': + tkn.next() + return tkn.scanCommentType1("//") + case '*': + tkn.next() + switch tkn.lastChar { + case '!': + return tkn.scanMySQLSpecificComment() + default: + return tkn.scanCommentType2() + } + default: + return int(ch), nil + } + case '#': + return tkn.scanCommentType1("#") + case '-': + switch tkn.lastChar { + case '-': + tkn.next() + return tkn.scanCommentType1("--") + case '>': + tkn.next() + if tkn.lastChar == '>' { + tkn.next() + return JSON_UNQUOTE_EXTRACT_OP, nil + } + return JSON_EXTRACT_OP, nil + } + return int(ch), nil + case '<': + switch tkn.lastChar { + case '>': + tkn.next() + return NE, nil + case '<': + tkn.next() + return SHIFT_LEFT, nil + case '=': + tkn.next() + switch tkn.lastChar { + case '>': + tkn.next() + return NULL_SAFE_EQUAL, nil + default: + return LE, nil + } + default: + return int(ch), nil + } + case '>': + switch tkn.lastChar { + case '=': + tkn.next() + return GE, nil + case '>': + tkn.next() + return SHIFT_RIGHT, nil + default: + return int(ch), nil + } + case '!': + if tkn.lastChar == '=' { + tkn.next() + return NE, nil + } + return int(ch), nil + case '\'', '"': + return tkn.scanString(ch, STRING) + case '`': + return tkn.scanLiteralIdentifier() + default: + return LEX_ERROR, []byte{byte(ch)} + } + } +} + +// skipStatement scans until the EOF, or end of statement is encountered. +func (tkn *Tokenizer) skipStatement() { + ch := tkn.lastChar + for ch != ';' && ch != eofChar { + tkn.next() + ch = tkn.lastChar + } +} + +func (tkn *Tokenizer) skipBlank() { + ch := tkn.lastChar + for ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t' { + tkn.next() + ch = tkn.lastChar + } +} + +func (tkn *Tokenizer) scanIdentifier(firstByte byte, isDbSystemVariable bool) (int, []byte) { + buffer := &bytes2.Buffer{} + buffer.WriteByte(firstByte) + for isLetter(tkn.lastChar) || isDigit(tkn.lastChar) || (isDbSystemVariable && isCarat(tkn.lastChar)) { + buffer.WriteByte(byte(tkn.lastChar)) + tkn.next() + } + lowered := bytes.ToLower(buffer.Bytes()) + loweredStr := string(lowered) + if keywordID, found := keywords[loweredStr]; found { + return keywordID, lowered + } + // dual must always be case-insensitive + if loweredStr == "dual" { + return ID, lowered + } + return ID, buffer.Bytes() +} + +func (tkn *Tokenizer) scanHex() (int, []byte) { + buffer := &bytes2.Buffer{} + tkn.scanMantissa(16, buffer) + if tkn.lastChar != '\'' { + return LEX_ERROR, buffer.Bytes() + } + tkn.next() + if buffer.Len()%2 != 0 { + return LEX_ERROR, buffer.Bytes() + } + return HEX, buffer.Bytes() +} + +func (tkn *Tokenizer) scanBitLiteral() (int, []byte) { + buffer := &bytes2.Buffer{} + tkn.scanMantissa(2, buffer) + if tkn.lastChar != '\'' { + return LEX_ERROR, buffer.Bytes() + } + tkn.next() + return BIT_LITERAL, buffer.Bytes() +} + +func (tkn *Tokenizer) scanLiteralIdentifier() (int, []byte) { + buffer := &bytes2.Buffer{} + backTickSeen := false + for { + if backTickSeen { + if tkn.lastChar != '`' { + break + } + backTickSeen = false + buffer.WriteByte('`') + tkn.next() + continue + } + // The previous char was not a backtick. + switch tkn.lastChar { + case '`': + backTickSeen = true + case eofChar: + // Premature EOF. + return LEX_ERROR, buffer.Bytes() + default: + buffer.WriteByte(byte(tkn.lastChar)) + } + tkn.next() + } + if buffer.Len() == 0 { + return LEX_ERROR, buffer.Bytes() + } + return ID, buffer.Bytes() +} + +func (tkn *Tokenizer) scanBindVar() (int, []byte) { + buffer := &bytes2.Buffer{} + buffer.WriteByte(byte(tkn.lastChar)) + token := VALUE_ARG + tkn.next() + if tkn.lastChar == ':' { + token = LIST_ARG + buffer.WriteByte(byte(tkn.lastChar)) + tkn.next() + } + if !isLetter(tkn.lastChar) { + return LEX_ERROR, buffer.Bytes() + } + for isLetter(tkn.lastChar) || isDigit(tkn.lastChar) || tkn.lastChar == '.' { + buffer.WriteByte(byte(tkn.lastChar)) + tkn.next() + } + return token, buffer.Bytes() +} + +func (tkn *Tokenizer) scanMantissa(base int, buffer *bytes2.Buffer) { + for digitVal(tkn.lastChar) < base { + tkn.consumeNext(buffer) + } +} + +func (tkn *Tokenizer) scanNumber(seenDecimalPoint bool) (int, []byte) { + token := INTEGRAL + buffer := &bytes2.Buffer{} + if seenDecimalPoint { + token = FLOAT + buffer.WriteByte('.') + tkn.scanMantissa(10, buffer) + goto exponent + } + + // 0x construct. + if tkn.lastChar == '0' { + tkn.consumeNext(buffer) + if tkn.lastChar == 'x' || tkn.lastChar == 'X' { + token = HEXNUM + tkn.consumeNext(buffer) + tkn.scanMantissa(16, buffer) + goto exit + } + } + + tkn.scanMantissa(10, buffer) + + if tkn.lastChar == '.' { + token = FLOAT + tkn.consumeNext(buffer) + tkn.scanMantissa(10, buffer) + } + +exponent: + if tkn.lastChar == 'e' || tkn.lastChar == 'E' { + token = FLOAT + tkn.consumeNext(buffer) + if tkn.lastChar == '+' || tkn.lastChar == '-' { + tkn.consumeNext(buffer) + } + tkn.scanMantissa(10, buffer) + } + +exit: + // A letter cannot immediately follow a number. + if isLetter(tkn.lastChar) { + return LEX_ERROR, buffer.Bytes() + } + + return token, buffer.Bytes() +} + +func (tkn *Tokenizer) scanString(delim uint16, typ int) (int, []byte) { + var buffer bytes2.Buffer + for { + ch := tkn.lastChar + if ch == eofChar { + // Unterminated string. + return LEX_ERROR, buffer.Bytes() + } + + if ch != delim && ch != '\\' { + buffer.WriteByte(byte(ch)) + + // Scan ahead to the next interesting character. + start := tkn.bufPos + for ; tkn.bufPos < tkn.bufSize; tkn.bufPos++ { + ch = uint16(tkn.buf[tkn.bufPos]) + if ch == delim || ch == '\\' { + break + } + } + + buffer.Write(tkn.buf[start:tkn.bufPos]) + tkn.Position += (tkn.bufPos - start) + + if tkn.bufPos >= tkn.bufSize { + // Reached the end of the buffer without finding a delim or + // escape character. + tkn.next() + continue + } + + tkn.bufPos++ + tkn.Position++ + } + tkn.next() // Read one past the delim or escape character. + + if ch == '\\' { + if tkn.lastChar == eofChar { + // String terminates mid escape character. + return LEX_ERROR, buffer.Bytes() + } + if decodedChar := sqltypes.SQLDecodeMap[byte(tkn.lastChar)]; decodedChar == sqltypes.DontEscape { + ch = tkn.lastChar + } else { + ch = uint16(decodedChar) + } + + } else if ch == delim && tkn.lastChar != delim { + // Correctly terminated string, which is not a double delim. + break + } + + buffer.WriteByte(byte(ch)) + tkn.next() + } + + return typ, buffer.Bytes() +} + +func (tkn *Tokenizer) scanCommentType1(prefix string) (int, []byte) { + buffer := &bytes2.Buffer{} + buffer.WriteString(prefix) + for tkn.lastChar != eofChar { + if tkn.lastChar == '\n' { + tkn.consumeNext(buffer) + break + } + tkn.consumeNext(buffer) + } + return COMMENT, buffer.Bytes() +} + +func (tkn *Tokenizer) scanCommentType2() (int, []byte) { + buffer := &bytes2.Buffer{} + buffer.WriteString("/*") + for { + if tkn.lastChar == '*' { + tkn.consumeNext(buffer) + if tkn.lastChar == '/' { + tkn.consumeNext(buffer) + break + } + continue + } + if tkn.lastChar == eofChar { + return LEX_ERROR, buffer.Bytes() + } + tkn.consumeNext(buffer) + } + return COMMENT, buffer.Bytes() +} + +func (tkn *Tokenizer) scanMySQLSpecificComment() (int, []byte) { + buffer := &bytes2.Buffer{} + buffer.WriteString("/*!") + tkn.next() + for { + if tkn.lastChar == '*' { + tkn.consumeNext(buffer) + if tkn.lastChar == '/' { + tkn.consumeNext(buffer) + break + } + continue + } + if tkn.lastChar == eofChar { + return LEX_ERROR, buffer.Bytes() + } + tkn.consumeNext(buffer) + } + _, sql := ExtractMysqlComment(buffer.String()) + tkn.specialComment = NewStringTokenizer(sql) + return tkn.Scan() +} + +func (tkn *Tokenizer) consumeNext(buffer *bytes2.Buffer) { + if tkn.lastChar == eofChar { + // This should never happen. + panic("unexpected EOF") + } + buffer.WriteByte(byte(tkn.lastChar)) + tkn.next() +} + +func (tkn *Tokenizer) next() { + if tkn.bufPos >= tkn.bufSize && tkn.InStream != nil { + // Try and refill the buffer + var err error + tkn.bufPos = 0 + if tkn.bufSize, err = tkn.InStream.Read(tkn.buf); err != io.EOF && err != nil { + tkn.LastError = err + } + } + + if tkn.bufPos >= tkn.bufSize { + if tkn.lastChar != eofChar { + tkn.Position++ + tkn.lastChar = eofChar + } + } else { + tkn.Position++ + tkn.lastChar = uint16(tkn.buf[tkn.bufPos]) + tkn.bufPos++ + } +} + +// reset clears any internal state. +func (tkn *Tokenizer) reset() { + tkn.ParseTree = nil + tkn.partialDDL = nil + tkn.specialComment = nil + tkn.posVarIndex = 0 + tkn.nesting = 0 + tkn.ForceEOF = false +} + +func isLetter(ch uint16) bool { + return 'a' <= ch && ch <= 'z' || 'A' <= ch && ch <= 'Z' || ch == '_' || ch == '@' +} + +func isCarat(ch uint16) bool { + return ch == '.' || ch == '\'' || ch == '"' || ch == '`' +} + +func digitVal(ch uint16) int { + switch { + case '0' <= ch && ch <= '9': + return int(ch) - '0' + case 'a' <= ch && ch <= 'f': + return int(ch) - 'a' + 10 + case 'A' <= ch && ch <= 'F': + return int(ch) - 'A' + 10 + } + return 16 // larger than any legal digit val +} + +func isDigit(ch uint16) bool { + return '0' <= ch && ch <= '9' +} diff --git a/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/token_test.go b/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/token_test.go new file mode 100644 index 00000000..93543545 --- /dev/null +++ b/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/token_test.go @@ -0,0 +1,191 @@ +/* +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 sqlparser + +import ( + "fmt" + "testing" +) + +func TestLiteralID(t *testing.T) { + testcases := []struct { + in string + id int + out string + }{{ + in: "`aa`", + id: ID, + out: "aa", + }, { + in: "```a```", + id: ID, + out: "`a`", + }, { + in: "`a``b`", + id: ID, + out: "a`b", + }, { + in: "`a``b`c", + id: ID, + out: "a`b", + }, { + in: "`a``b", + id: LEX_ERROR, + out: "a`b", + }, { + in: "`a``b``", + id: LEX_ERROR, + out: "a`b`", + }, { + in: "``", + id: LEX_ERROR, + out: "", + }} + + for _, tcase := range testcases { + tkn := NewStringTokenizer(tcase.in) + id, out := tkn.Scan() + if tcase.id != id || string(out) != tcase.out { + t.Errorf("Scan(%s): %d, %s, want %d, %s", tcase.in, id, out, tcase.id, tcase.out) + } + } +} + +func tokenName(id int) string { + if id == STRING { + return "STRING" + } else if id == LEX_ERROR { + return "LEX_ERROR" + } + return fmt.Sprintf("%d", id) +} + +func TestString(t *testing.T) { + testcases := []struct { + in string + id int + want string + }{{ + in: "''", + id: STRING, + want: "", + }, { + in: "''''", + id: STRING, + want: "'", + }, { + in: "'hello'", + id: STRING, + want: "hello", + }, { + in: "'\\n'", + id: STRING, + want: "\n", + }, { + in: "'\\nhello\\n'", + id: STRING, + want: "\nhello\n", + }, { + in: "'a''b'", + id: STRING, + want: "a'b", + }, { + in: "'a\\'b'", + id: STRING, + want: "a'b", + }, { + in: "'\\'", + id: LEX_ERROR, + want: "'", + }, { + in: "'", + id: LEX_ERROR, + want: "", + }, { + in: "'hello\\'", + id: LEX_ERROR, + want: "hello'", + }, { + in: "'hello", + id: LEX_ERROR, + want: "hello", + }, { + in: "'hello\\", + id: LEX_ERROR, + want: "hello", + }} + + for _, tcase := range testcases { + id, got := NewStringTokenizer(tcase.in).Scan() + if tcase.id != id || string(got) != tcase.want { + t.Errorf("Scan(%q) = (%s, %q), want (%s, %q)", tcase.in, tokenName(id), got, tokenName(tcase.id), tcase.want) + } + } +} + +func TestSplitStatement(t *testing.T) { + testcases := []struct { + in string + sql string + rem string + }{{ + in: "select * from table", + sql: "select * from table", + }, { + in: "select * from table; ", + sql: "select * from table", + rem: " ", + }, { + in: "select * from table; select * from table2;", + sql: "select * from table", + rem: " select * from table2;", + }, { + in: "select * from /* comment */ table;", + sql: "select * from /* comment */ table", + }, { + in: "select * from /* comment ; */ table;", + sql: "select * from /* comment ; */ table", + }, { + in: "select * from table where semi = ';';", + sql: "select * from table where semi = ';'", + }, { + in: "-- select * from table", + sql: "-- select * from table", + }, { + in: " ", + sql: " ", + }, { + in: "", + sql: "", + }} + + for _, tcase := range testcases { + sql, rem, err := SplitStatement(tcase.in) + if err != nil { + t.Errorf("EndOfStatementPosition(%s): ERROR: %v", tcase.in, err) + continue + } + + if tcase.sql != sql { + t.Errorf("EndOfStatementPosition(%s) got sql \"%s\" want \"%s\"", tcase.in, sql, tcase.sql) + } + + if tcase.rem != rem { + t.Errorf("EndOfStatementPosition(%s) got remainder \"%s\" want \"%s\"", tcase.in, rem, tcase.rem) + } + } +} diff --git a/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/tracked_buffer.go b/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/tracked_buffer.go new file mode 100644 index 00000000..ec421a5f --- /dev/null +++ b/functions/ingest/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/tracked_buffer.go @@ -0,0 +1,140 @@ +/* +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 sqlparser + +import ( + "bytes" + "fmt" +) + +// NodeFormatter defines the signature of a custom node formatter +// function that can be given to TrackedBuffer for code generation. +type NodeFormatter func(buf *TrackedBuffer, node SQLNode) + +// TrackedBuffer is used to rebuild a query from the ast. +// bindLocations keeps track of locations in the buffer that +// use bind variables for efficient future substitutions. +// nodeFormatter is the formatting function the buffer will +// use to format a node. By default(nil), it's FormatNode. +// But you can supply a different formatting function if you +// want to generate a query that's different from the default. +type TrackedBuffer struct { + *bytes.Buffer + bindLocations []bindLocation + nodeFormatter NodeFormatter +} + +// NewTrackedBuffer creates a new TrackedBuffer. +func NewTrackedBuffer(nodeFormatter NodeFormatter) *TrackedBuffer { + return &TrackedBuffer{ + Buffer: new(bytes.Buffer), + nodeFormatter: nodeFormatter, + } +} + +// WriteNode function, initiates the writing of a single SQLNode tree by passing +// through to Myprintf with a default format string +func (buf *TrackedBuffer) WriteNode(node SQLNode) *TrackedBuffer { + buf.Myprintf("%v", node) + return buf +} + +// Myprintf mimics fmt.Fprintf(buf, ...), but limited to Node(%v), +// Node.Value(%s) and string(%s). It also allows a %a for a value argument, in +// which case it adds tracking info for future substitutions. +// +// The name must be something other than the usual Printf() to avoid "go vet" +// warnings due to our custom format specifiers. +func (buf *TrackedBuffer) Myprintf(format string, values ...interface{}) { + end := len(format) + fieldnum := 0 + for i := 0; i < end; { + lasti := i + for i < end && format[i] != '%' { + i++ + } + if i > lasti { + buf.WriteString(format[lasti:i]) + } + if i >= end { + break + } + i++ // '%' + switch format[i] { + case 'c': + switch v := values[fieldnum].(type) { + case byte: + buf.WriteByte(v) + case rune: + buf.WriteRune(v) + default: + panic(fmt.Sprintf("unexpected TrackedBuffer type %T", v)) + } + case 's': + switch v := values[fieldnum].(type) { + case []byte: + buf.Write(v) + case string: + buf.WriteString(v) + default: + panic(fmt.Sprintf("unexpected TrackedBuffer type %T", v)) + } + case 'v': + node := values[fieldnum].(SQLNode) + if buf.nodeFormatter == nil { + node.Format(buf) + } else { + buf.nodeFormatter(buf, node) + } + case 'a': + buf.WriteArg(values[fieldnum].(string)) + default: + panic("unexpected") + } + fieldnum++ + i++ + } +} + +// WriteArg writes a value argument into the buffer along with +// tracking information for future substitutions. arg must contain +// the ":" or "::" prefix. +func (buf *TrackedBuffer) WriteArg(arg string) { + buf.bindLocations = append(buf.bindLocations, bindLocation{ + offset: buf.Len(), + length: len(arg), + }) + buf.WriteString(arg) +} + +// ParsedQuery returns a ParsedQuery that contains bind +// locations for easy substitution. +func (buf *TrackedBuffer) ParsedQuery() *ParsedQuery { + return &ParsedQuery{Query: buf.String(), bindLocations: buf.bindLocations} +} + +// HasBindVars returns true if the parsed query uses bind vars. +func (buf *TrackedBuffer) HasBindVars() bool { + return len(buf.bindLocations) != 0 +} + +// BuildParsedQuery builds a ParsedQuery from the input. +func BuildParsedQuery(in string, vars ...interface{}) *ParsedQuery { + buf := NewTrackedBuffer(nil) + buf.Myprintf(in, vars...) + return buf.ParsedQuery() +} diff --git a/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/CONTRIBUTORS.md b/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/CONTRIBUTORS.md new file mode 100644 index 00000000..a44885cd --- /dev/null +++ b/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/CONTRIBUTORS.md @@ -0,0 +1,9 @@ +This project is originally a fork of [https://github.com/youtube/vitess](https://github.com/youtube/vitess) +Copyright Google Inc + +# Contributors +Wenbin Xiao 2015 +Started this project and maintained it. + +Andrew Brampton 2017 +Merged in multiple upstream fixes/changes. \ No newline at end of file diff --git a/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/LICENSE.md b/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/LICENSE.md new file mode 100644 index 00000000..f49a4e16 --- /dev/null +++ b/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/LICENSE.md @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "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. \ No newline at end of file diff --git a/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/Makefile b/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/Makefile new file mode 100644 index 00000000..215f422e --- /dev/null +++ b/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/Makefile @@ -0,0 +1,22 @@ +# 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. + +MAKEFLAGS = -s + +sql.go: sql.y + goyacc -o sql.go sql.y + gofmt -w sql.go + +clean: + rm -f y.output sql.go diff --git a/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/README.md b/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/README.md new file mode 100644 index 00000000..58d47596 --- /dev/null +++ b/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/README.md @@ -0,0 +1,150 @@ +# sqlparser [![Build Status](https://img.shields.io/travis/xwb1989/sqlparser.svg)](https://travis-ci.org/xwb1989/sqlparser) [![Coverage](https://img.shields.io/coveralls/xwb1989/sqlparser.svg)](https://coveralls.io/github/xwb1989/sqlparser) [![Report card](https://goreportcard.com/badge/github.com/xwb1989/sqlparser)](https://goreportcard.com/report/github.com/xwb1989/sqlparser) [![GoDoc](https://godoc.org/github.com/xwb1989/sqlparser?status.svg)](https://godoc.org/github.com/xwb1989/sqlparser) + +Go package for parsing MySQL SQL queries. + +## Notice + +The backbone of this repo is extracted from [vitessio/vitess](https://github.com/vitessio/vitess). + +Inside vitessio/vitess there is a very nicely written sql parser. However as it's not a self-contained application, I created this one. +It applies the same LICENSE as vitessio/vitess. + +## Usage + +```go +import ( + "github.com/xwb1989/sqlparser" +) +``` + +Then use: + +```go +sql := "SELECT * FROM table WHERE a = 'abc'" +stmt, err := sqlparser.Parse(sql) +if err != nil { + // Do something with the err +} + +// Otherwise do something with stmt +switch stmt := stmt.(type) { +case *sqlparser.Select: + _ = stmt +case *sqlparser.Insert: +} +``` + +Alternative to read many queries from a io.Reader: + +```go +r := strings.NewReader("INSERT INTO table1 VALUES (1, 'a'); INSERT INTO table2 VALUES (3, 4);") + +tokens := sqlparser.NewTokenizer(r) +for { + stmt, err := sqlparser.ParseNext(tokens) + if err == io.EOF { + break + } + // Do something with stmt or err. +} +``` + +See [parse_test.go](https://github.com/xwb1989/sqlparser/blob/master/parse_test.go) for more examples, or read the [godoc](https://godoc.org/github.com/xwb1989/sqlparser). + + +## Porting Instructions + +You only need the below if you plan to try and keep this library up to date with [vitessio/vitess](https://github.com/vitessio/vitess). + +### Keeping up to date + +```bash +shopt -s nullglob +VITESS=${GOPATH?}/src/vitess.io/vitess/go/ +XWB1989=${GOPATH?}/src/github.com/xwb1989/sqlparser/ + +# Create patches for everything that changed +LASTIMPORT=1b7879cb91f1dfe1a2dfa06fea96e951e3a7aec5 +for path in ${VITESS?}/{vt/sqlparser,sqltypes,bytes2,hack}; do + cd ${path} + git format-patch ${LASTIMPORT?} . +done; + +# Apply patches to the dependencies +cd ${XWB1989?} +git am --directory dependency -p2 ${VITESS?}/{sqltypes,bytes2,hack}/*.patch + +# Apply the main patches to the repo +cd ${XWB1989?} +git am -p4 ${VITESS?}/vt/sqlparser/*.patch + +# If you encounter diff failures, manually fix them with +patch -p4 < .git/rebase-apply/patch +... +git add name_of_files +git am --continue + +# Cleanup +rm ${VITESS?}/{sqltypes,bytes2,hack}/*.patch ${VITESS?}/*.patch + +# and Finally update the LASTIMPORT in this README. +``` + +### Fresh install + +TODO: Change these instructions to use git to copy the files, that'll make later patching easier. + +```bash +VITESS=${GOPATH?}/src/vitess.io/vitess/go/ +XWB1989=${GOPATH?}/src/github.com/xwb1989/sqlparser/ + +cd ${XWB1989?} + +# Copy all the code +cp -pr ${VITESS?}/vt/sqlparser/ . +cp -pr ${VITESS?}/sqltypes dependency +cp -pr ${VITESS?}/bytes2 dependency +cp -pr ${VITESS?}/hack dependency + +# Delete some code we haven't ported +rm dependency/sqltypes/arithmetic.go dependency/sqltypes/arithmetic_test.go dependency/sqltypes/event_token.go dependency/sqltypes/event_token_test.go dependency/sqltypes/proto3.go dependency/sqltypes/proto3_test.go dependency/sqltypes/query_response.go dependency/sqltypes/result.go dependency/sqltypes/result_test.go + +# Some automated fixes + +# Fix imports +sed -i '.bak' 's_vitess.io/vitess/go/vt/proto/query_github.com/xwb1989/sqlparser/dependency/querypb_g' *.go dependency/sqltypes/*.go +sed -i '.bak' 's_vitess.io/vitess/go/_github.com/xwb1989/sqlparser/dependency/_g' *.go dependency/sqltypes/*.go + +# Copy the proto, but basically drop everything we don't want +cp -pr ${VITESS?}/vt/proto/query dependency/querypb + +sed -i '.bak' 's_.*Descriptor.*__g' dependency/querypb/*.go +sed -i '.bak' 's_.*ProtoMessage.*__g' dependency/querypb/*.go + +sed -i '.bak' 's/proto.CompactTextString(m)/"TODO"/g' dependency/querypb/*.go +sed -i '.bak' 's/proto.EnumName/EnumName/g' dependency/querypb/*.go + +sed -i '.bak' 's/proto.Equal/reflect.DeepEqual/g' dependency/sqltypes/*.go + +# Remove the error library +sed -i '.bak' 's/vterrors.Errorf([^,]*, /fmt.Errorf(/g' *.go dependency/sqltypes/*.go +sed -i '.bak' 's/vterrors.New([^,]*, /errors.New(/g' *.go dependency/sqltypes/*.go +``` + +### Testing + +```bash +VITESS=${GOPATH?}/src/vitess.io/vitess/go/ +XWB1989=${GOPATH?}/src/github.com/xwb1989/sqlparser/ + +cd ${XWB1989?} + +# Test, fix and repeat +go test ./... + +# Finally make some diffs (for later reference) +diff -u ${VITESS?}/sqltypes/ ${XWB1989?}/dependency/sqltypes/ > ${XWB1989?}/patches/sqltypes.patch +diff -u ${VITESS?}/bytes2/ ${XWB1989?}/dependency/bytes2/ > ${XWB1989?}/patches/bytes2.patch +diff -u ${VITESS?}/vt/proto/query/ ${XWB1989?}/dependency/querypb/ > ${XWB1989?}/patches/querypb.patch +diff -u ${VITESS?}/vt/sqlparser/ ${XWB1989?}/ > ${XWB1989?}/patches/sqlparser.patch +``` \ No newline at end of file diff --git a/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/analyzer.go b/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/analyzer.go new file mode 100644 index 00000000..95f97d35 --- /dev/null +++ b/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/analyzer.go @@ -0,0 +1,343 @@ +/* +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 sqlparser + +// analyzer.go contains utility analysis functions. + +import ( + "errors" + "fmt" + "strconv" + "strings" + "unicode" + + "github.com/xwb1989/sqlparser/dependency/sqltypes" +) + +// These constants are used to identify the SQL statement type. +const ( + StmtSelect = iota + StmtStream + StmtInsert + StmtReplace + StmtUpdate + StmtDelete + StmtDDL + StmtBegin + StmtCommit + StmtRollback + StmtSet + StmtShow + StmtUse + StmtOther + StmtUnknown + StmtComment +) + +// Preview analyzes the beginning of the query using a simpler and faster +// textual comparison to identify the statement type. +func Preview(sql string) int { + trimmed := StripLeadingComments(sql) + + firstWord := trimmed + if end := strings.IndexFunc(trimmed, unicode.IsSpace); end != -1 { + firstWord = trimmed[: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 { + case "select": + return StmtSelect + case "stream": + return StmtStream + case "insert": + return StmtInsert + case "replace": + return StmtReplace + case "update": + return StmtUpdate + case "delete": + return StmtDelete + } + // For the following statements it is not sufficient to rely + // on loweredFirstWord. This is because they are not statements + // in the grammar and we are relying on Preview to parse them. + // For instance, we don't want: "BEGIN JUNK" to be parsed + // as StmtBegin. + trimmedNoComments, _ := SplitMarginComments(trimmed) + switch strings.ToLower(trimmedNoComments) { + case "begin", "start transaction": + return StmtBegin + case "commit": + return StmtCommit + case "rollback": + return StmtRollback + } + switch loweredFirstWord { + case "create", "alter", "rename", "drop", "truncate": + return StmtDDL + case "set": + return StmtSet + case "show": + return StmtShow + case "use": + return StmtUse + case "analyze", "describe", "desc", "explain", "repair", "optimize": + return StmtOther + } + if strings.Index(trimmed, "/*!") == 0 { + return StmtComment + } + return StmtUnknown +} + +// StmtType returns the statement type as a string +func StmtType(stmtType int) string { + switch stmtType { + case StmtSelect: + return "SELECT" + case StmtStream: + return "STREAM" + case StmtInsert: + return "INSERT" + case StmtReplace: + return "REPLACE" + case StmtUpdate: + return "UPDATE" + case StmtDelete: + return "DELETE" + case StmtDDL: + return "DDL" + case StmtBegin: + return "BEGIN" + case StmtCommit: + return "COMMIT" + case StmtRollback: + return "ROLLBACK" + case StmtSet: + return "SET" + case StmtShow: + return "SHOW" + case StmtUse: + return "USE" + case StmtOther: + return "OTHER" + default: + return "UNKNOWN" + } +} + +// IsDML returns true if the query is an INSERT, UPDATE or DELETE statement. +func IsDML(sql string) bool { + switch Preview(sql) { + case StmtInsert, StmtReplace, StmtUpdate, StmtDelete: + return true + } + return false +} + +// GetTableName returns the table name from the SimpleTableExpr +// only if it's a simple expression. Otherwise, it returns "". +func GetTableName(node SimpleTableExpr) TableIdent { + if n, ok := node.(TableName); ok && n.Qualifier.IsEmpty() { + return n.Name + } + // sub-select or '.' expression + return NewTableIdent("") +} + +// IsColName returns true if the Expr is a *ColName. +func IsColName(node Expr) bool { + _, ok := node.(*ColName) + return ok +} + +// IsValue returns true if the Expr is a string, integral or value arg. +// NULL is not considered to be a value. +func IsValue(node Expr) bool { + switch v := node.(type) { + case *SQLVal: + switch v.Type { + case StrVal, HexVal, IntVal, ValArg: + return true + } + } + return false +} + +// IsNull returns true if the Expr is SQL NULL +func IsNull(node Expr) bool { + switch node.(type) { + case *NullVal: + return true + } + return false +} + +// IsSimpleTuple returns true if the Expr is a ValTuple that +// contains simple values or if it's a list arg. +func IsSimpleTuple(node Expr) bool { + switch vals := node.(type) { + case ValTuple: + for _, n := range vals { + if !IsValue(n) { + return false + } + } + return true + case ListArg: + return true + } + // It's a subquery + return false +} + +// NewPlanValue builds a sqltypes.PlanValue from an Expr. +func NewPlanValue(node Expr) (sqltypes.PlanValue, error) { + switch node := node.(type) { + case *SQLVal: + switch node.Type { + case ValArg: + return sqltypes.PlanValue{Key: string(node.Val[1:])}, nil + case IntVal: + n, err := sqltypes.NewIntegral(string(node.Val)) + if err != nil { + return sqltypes.PlanValue{}, fmt.Errorf("%v", err) + } + return sqltypes.PlanValue{Value: n}, nil + case StrVal: + return sqltypes.PlanValue{Value: sqltypes.MakeTrusted(sqltypes.VarBinary, node.Val)}, nil + case HexVal: + v, err := node.HexDecode() + if err != nil { + return sqltypes.PlanValue{}, fmt.Errorf("%v", err) + } + return sqltypes.PlanValue{Value: sqltypes.MakeTrusted(sqltypes.VarBinary, v)}, nil + } + case ListArg: + return sqltypes.PlanValue{ListKey: string(node[2:])}, nil + case ValTuple: + pv := sqltypes.PlanValue{ + Values: make([]sqltypes.PlanValue, 0, len(node)), + } + for _, val := range node { + innerpv, err := NewPlanValue(val) + if err != nil { + return sqltypes.PlanValue{}, err + } + if innerpv.ListKey != "" || innerpv.Values != nil { + return sqltypes.PlanValue{}, errors.New("unsupported: nested lists") + } + pv.Values = append(pv.Values, innerpv) + } + return pv, nil + case *NullVal: + return sqltypes.PlanValue{}, nil + } + return sqltypes.PlanValue{}, fmt.Errorf("expression is too complex '%v'", String(node)) +} + +// StringIn is a convenience function that returns +// true if str matches any of the values. +func StringIn(str string, values ...string) bool { + for _, val := range values { + if str == val { + return true + } + } + return false +} + +// SetKey is the extracted key from one SetExpr +type SetKey struct { + Key string + Scope string +} + +// ExtractSetValues returns a map of key-value pairs +// if the query is a SET statement. Values can be bool, int64 or string. +// Since set variable names are case insensitive, all keys are returned +// as lower case. +func ExtractSetValues(sql string) (keyValues map[SetKey]interface{}, scope string, err error) { + stmt, err := Parse(sql) + if err != nil { + return nil, "", err + } + setStmt, ok := stmt.(*Set) + if !ok { + return nil, "", fmt.Errorf("ast did not yield *sqlparser.Set: %T", stmt) + } + result := make(map[SetKey]interface{}) + for _, expr := range setStmt.Exprs { + scope := SessionStr + key := expr.Name.Lowered() + switch { + case strings.HasPrefix(key, "@@global."): + scope = GlobalStr + key = strings.TrimPrefix(key, "@@global.") + case strings.HasPrefix(key, "@@session."): + key = strings.TrimPrefix(key, "@@session.") + case strings.HasPrefix(key, "@@"): + key = strings.TrimPrefix(key, "@@") + } + + if strings.HasPrefix(expr.Name.Lowered(), "@@") { + if setStmt.Scope != "" && scope != "" { + return nil, "", fmt.Errorf("unsupported in set: mixed using of variable scope") + } + _, out := NewStringTokenizer(key).Scan() + key = string(out) + } + + setKey := SetKey{ + Key: key, + Scope: scope, + } + + switch expr := expr.Expr.(type) { + case *SQLVal: + switch expr.Type { + case StrVal: + result[setKey] = strings.ToLower(string(expr.Val)) + case IntVal: + num, err := strconv.ParseInt(string(expr.Val), 0, 64) + if err != nil { + return nil, "", err + } + result[setKey] = num + default: + return nil, "", fmt.Errorf("invalid value type: %v", String(expr)) + } + case BoolVal: + var val int64 + if expr { + val = 1 + } + result[setKey] = val + case *ColName: + result[setKey] = expr.Name.String() + case *NullVal: + result[setKey] = nil + case *Default: + result[setKey] = "default" + default: + return nil, "", fmt.Errorf("invalid syntax: %s", String(expr)) + } + } + return result, strings.ToLower(setStmt.Scope), nil +} diff --git a/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/analyzer_test.go b/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/analyzer_test.go new file mode 100644 index 00000000..6d8c1ef1 --- /dev/null +++ b/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/analyzer_test.go @@ -0,0 +1,511 @@ +/* +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 sqlparser + +import ( + "reflect" + "strings" + "testing" + + "github.com/xwb1989/sqlparser/dependency/sqltypes" +) + +func TestPreview(t *testing.T) { + testcases := []struct { + sql string + want int + }{ + {"select ...", StmtSelect}, + {" select ...", StmtSelect}, + {"(select ...", StmtSelect}, + {"insert ...", StmtInsert}, + {"replace ....", StmtReplace}, + {" update ...", StmtUpdate}, + {"Update", StmtUpdate}, + {"UPDATE ...", StmtUpdate}, + {"\n\t delete ...", StmtDelete}, + {"", StmtUnknown}, + {" ", StmtUnknown}, + {"begin", StmtBegin}, + {" begin", StmtBegin}, + {" begin ", StmtBegin}, + {"\n\t begin ", StmtBegin}, + {"... begin ", StmtUnknown}, + {"begin ...", StmtUnknown}, + {"begin /* ... */", StmtBegin}, + {"begin /* ... *//*test*/", StmtBegin}, + {"start transaction", StmtBegin}, + {"commit", StmtCommit}, + {"commit /*...*/", StmtCommit}, + {"rollback", StmtRollback}, + {"rollback /*...*/", StmtRollback}, + {"create", StmtDDL}, + {"alter", StmtDDL}, + {"rename", StmtDDL}, + {"drop", StmtDDL}, + {"set", StmtSet}, + {"show", StmtShow}, + {"use", StmtUse}, + {"analyze", StmtOther}, + {"describe", StmtOther}, + {"desc", StmtOther}, + {"explain", StmtOther}, + {"repair", StmtOther}, + {"optimize", StmtOther}, + {"truncate", StmtDDL}, + {"unknown", StmtUnknown}, + + {"/* leading comment */ select ...", StmtSelect}, + {"/* leading comment */ (select ...", StmtSelect}, + {"/* leading comment */ /* leading comment 2 */ select ...", StmtSelect}, + {"/*! MySQL-specific comment */", StmtComment}, + {"/*!50708 MySQL-version comment */", StmtComment}, + {"-- leading single line comment \n select ...", StmtSelect}, + {"-- leading single line comment \n -- leading single line comment 2\n select ...", StmtSelect}, + + {"/* leading comment no end select ...", StmtUnknown}, + {"-- leading single line comment no end select ...", StmtUnknown}, + } + for _, tcase := range testcases { + if got := Preview(tcase.sql); got != tcase.want { + t.Errorf("Preview(%s): %v, want %v", tcase.sql, got, tcase.want) + } + } +} + +func TestIsDML(t *testing.T) { + testcases := []struct { + sql string + want bool + }{ + {" update ...", true}, + {"Update", true}, + {"UPDATE ...", true}, + {"\n\t delete ...", true}, + {"insert ...", true}, + {"replace ...", true}, + {"select ...", false}, + {" select ...", false}, + {"", false}, + {" ", false}, + } + for _, tcase := range testcases { + if got := IsDML(tcase.sql); got != tcase.want { + t.Errorf("IsDML(%s): %v, want %v", tcase.sql, got, tcase.want) + } + } +} + +func TestGetTableName(t *testing.T) { + testcases := []struct { + in, out string + }{{ + in: "select * from t", + out: "t", + }, { + in: "select * from t.t", + out: "", + }, { + in: "select * from (select * from t) as tt", + out: "", + }} + + for _, tc := range testcases { + tree, err := Parse(tc.in) + if err != nil { + t.Error(err) + continue + } + out := GetTableName(tree.(*Select).From[0].(*AliasedTableExpr).Expr) + if out.String() != tc.out { + t.Errorf("GetTableName('%s'): %s, want %s", tc.in, out, tc.out) + } + } +} + +func TestIsColName(t *testing.T) { + testcases := []struct { + in Expr + out bool + }{{ + in: &ColName{}, + out: true, + }, { + in: newHexVal(""), + }} + for _, tc := range testcases { + out := IsColName(tc.in) + if out != tc.out { + t.Errorf("IsColName(%T): %v, want %v", tc.in, out, tc.out) + } + } +} + +func TestIsValue(t *testing.T) { + testcases := []struct { + in Expr + out bool + }{{ + in: newStrVal("aa"), + out: true, + }, { + in: newHexVal("3131"), + out: true, + }, { + in: newIntVal("1"), + out: true, + }, { + in: newValArg(":a"), + out: true, + }, { + in: &NullVal{}, + out: false, + }} + for _, tc := range testcases { + out := IsValue(tc.in) + if out != tc.out { + t.Errorf("IsValue(%T): %v, want %v", tc.in, out, tc.out) + } + if tc.out { + // NewPlanValue should not fail for valid values. + if _, err := NewPlanValue(tc.in); err != nil { + t.Error(err) + } + } + } +} + +func TestIsNull(t *testing.T) { + testcases := []struct { + in Expr + out bool + }{{ + in: &NullVal{}, + out: true, + }, { + in: newStrVal(""), + }} + for _, tc := range testcases { + out := IsNull(tc.in) + if out != tc.out { + t.Errorf("IsNull(%T): %v, want %v", tc.in, out, tc.out) + } + } +} + +func TestIsSimpleTuple(t *testing.T) { + testcases := []struct { + in Expr + out bool + }{{ + in: ValTuple{newStrVal("aa")}, + out: true, + }, { + in: ValTuple{&ColName{}}, + }, { + in: ListArg("::a"), + out: true, + }, { + in: &ColName{}, + }} + for _, tc := range testcases { + out := IsSimpleTuple(tc.in) + if out != tc.out { + t.Errorf("IsSimpleTuple(%T): %v, want %v", tc.in, out, tc.out) + } + if tc.out { + // NewPlanValue should not fail for valid tuples. + if _, err := NewPlanValue(tc.in); err != nil { + t.Error(err) + } + } + } +} + +func TestNewPlanValue(t *testing.T) { + tcases := []struct { + in Expr + out sqltypes.PlanValue + err string + }{{ + in: &SQLVal{ + Type: ValArg, + Val: []byte(":valarg"), + }, + out: sqltypes.PlanValue{Key: "valarg"}, + }, { + in: &SQLVal{ + Type: IntVal, + Val: []byte("10"), + }, + out: sqltypes.PlanValue{Value: sqltypes.NewInt64(10)}, + }, { + in: &SQLVal{ + Type: IntVal, + Val: []byte("1111111111111111111111111111111111111111"), + }, + err: "value out of range", + }, { + in: &SQLVal{ + Type: StrVal, + Val: []byte("strval"), + }, + out: sqltypes.PlanValue{Value: sqltypes.NewVarBinary("strval")}, + }, { + in: &SQLVal{ + Type: HexVal, + Val: []byte("3131"), + }, + out: sqltypes.PlanValue{Value: sqltypes.NewVarBinary("11")}, + }, { + in: &SQLVal{ + Type: HexVal, + Val: []byte("313"), + }, + err: "odd length hex string", + }, { + in: ListArg("::list"), + out: sqltypes.PlanValue{ListKey: "list"}, + }, { + in: ValTuple{ + &SQLVal{ + Type: ValArg, + Val: []byte(":valarg"), + }, + &SQLVal{ + Type: StrVal, + Val: []byte("strval"), + }, + }, + out: sqltypes.PlanValue{ + Values: []sqltypes.PlanValue{{ + Key: "valarg", + }, { + Value: sqltypes.NewVarBinary("strval"), + }}, + }, + }, { + in: ValTuple{ + &ParenExpr{Expr: &SQLVal{ + Type: ValArg, + Val: []byte(":valarg"), + }}, + }, + err: "expression is too complex", + }, { + in: ValTuple{ + ListArg("::list"), + }, + err: "unsupported: nested lists", + }, { + in: &NullVal{}, + out: sqltypes.PlanValue{}, + }, { + in: &ParenExpr{Expr: &SQLVal{ + Type: ValArg, + Val: []byte(":valarg"), + }}, + err: "expression is too complex", + }} + for _, tc := range tcases { + got, err := NewPlanValue(tc.in) + if err != nil { + if !strings.Contains(err.Error(), tc.err) { + t.Errorf("NewPlanValue(%s) error: %v, want '%s'", String(tc.in), err, tc.err) + } + continue + } + if tc.err != "" { + t.Errorf("NewPlanValue(%s) error: nil, want '%s'", String(tc.in), tc.err) + continue + } + if !reflect.DeepEqual(got, tc.out) { + t.Errorf("NewPlanValue(%s): %v, want %v", String(tc.in), got, tc.out) + } + } +} + +func TestStringIn(t *testing.T) { + testcases := []struct { + in1 string + in2 []string + out bool + }{{ + in1: "v1", + in2: []string{"v1", "v2"}, + out: true, + }, { + in1: "v0", + in2: []string{"v1", "v2"}, + }} + for _, tc := range testcases { + out := StringIn(tc.in1, tc.in2...) + if out != tc.out { + t.Errorf("StringIn(%v,%v): %#v, want %#v", tc.in1, tc.in2, out, tc.out) + } + } +} + +func TestExtractSetValues(t *testing.T) { + testcases := []struct { + sql string + out map[SetKey]interface{} + scope string + err string + }{{ + sql: "invalid", + err: "syntax error at position 8 near 'invalid'", + }, { + sql: "select * from t", + err: "ast did not yield *sqlparser.Set: *sqlparser.Select", + }, { + sql: "set autocommit=1+1", + err: "invalid syntax: 1 + 1", + }, { + sql: "set transaction_mode='single'", + out: map[SetKey]interface{}{{Key: "transaction_mode", Scope: "session"}: "single"}, + }, { + sql: "set autocommit=1", + out: map[SetKey]interface{}{{Key: "autocommit", Scope: "session"}: int64(1)}, + }, { + sql: "set autocommit=true", + out: map[SetKey]interface{}{{Key: "autocommit", Scope: "session"}: int64(1)}, + }, { + sql: "set autocommit=false", + out: map[SetKey]interface{}{{Key: "autocommit", Scope: "session"}: int64(0)}, + }, { + sql: "set autocommit=on", + out: map[SetKey]interface{}{{Key: "autocommit", Scope: "session"}: "on"}, + }, { + sql: "set autocommit=off", + out: map[SetKey]interface{}{{Key: "autocommit", Scope: "session"}: "off"}, + }, { + sql: "set @@global.autocommit=1", + out: map[SetKey]interface{}{{Key: "autocommit", Scope: "global"}: int64(1)}, + }, { + sql: "set @@global.autocommit=1", + out: map[SetKey]interface{}{{Key: "autocommit", Scope: "global"}: int64(1)}, + }, { + sql: "set @@session.autocommit=1", + out: map[SetKey]interface{}{{Key: "autocommit", Scope: "session"}: int64(1)}, + }, { + sql: "set @@session.`autocommit`=1", + out: map[SetKey]interface{}{{Key: "autocommit", Scope: "session"}: int64(1)}, + }, { + sql: "set @@session.'autocommit'=1", + out: map[SetKey]interface{}{{Key: "autocommit", Scope: "session"}: int64(1)}, + }, { + sql: "set @@session.\"autocommit\"=1", + out: map[SetKey]interface{}{{Key: "autocommit", Scope: "session"}: int64(1)}, + }, { + sql: "set @@session.'\"autocommit'=1", + out: map[SetKey]interface{}{{Key: "\"autocommit", Scope: "session"}: int64(1)}, + }, { + sql: "set @@session.`autocommit'`=1", + out: map[SetKey]interface{}{{Key: "autocommit'", Scope: "session"}: int64(1)}, + }, { + sql: "set AUTOCOMMIT=1", + out: map[SetKey]interface{}{{Key: "autocommit", Scope: "session"}: int64(1)}, + }, { + sql: "SET character_set_results = NULL", + out: map[SetKey]interface{}{{Key: "character_set_results", Scope: "session"}: nil}, + }, { + sql: "SET foo = 0x1234", + err: "invalid value type: 0x1234", + }, { + sql: "SET names utf8", + out: map[SetKey]interface{}{{Key: "names", Scope: "session"}: "utf8"}, + }, { + sql: "SET names ascii collate ascii_bin", + out: map[SetKey]interface{}{{Key: "names", Scope: "session"}: "ascii"}, + }, { + sql: "SET charset default", + out: map[SetKey]interface{}{{Key: "charset", Scope: "session"}: "default"}, + }, { + sql: "SET character set ascii", + out: map[SetKey]interface{}{{Key: "charset", Scope: "session"}: "ascii"}, + }, { + sql: "SET SESSION wait_timeout = 3600", + out: map[SetKey]interface{}{{Key: "wait_timeout", Scope: "session"}: int64(3600)}, + scope: "session", + }, { + sql: "SET GLOBAL wait_timeout = 3600", + out: map[SetKey]interface{}{{Key: "wait_timeout", Scope: "session"}: int64(3600)}, + scope: "global", + }, { + sql: "set session transaction isolation level repeatable read", + out: map[SetKey]interface{}{{Key: "tx_isolation", Scope: "session"}: "repeatable read"}, + scope: "session", + }, { + sql: "set session transaction isolation level read committed", + out: map[SetKey]interface{}{{Key: "tx_isolation", Scope: "session"}: "read committed"}, + scope: "session", + }, { + sql: "set session transaction isolation level read uncommitted", + out: map[SetKey]interface{}{{Key: "tx_isolation", Scope: "session"}: "read uncommitted"}, + scope: "session", + }, { + sql: "set session transaction isolation level serializable", + out: map[SetKey]interface{}{{Key: "tx_isolation", Scope: "session"}: "serializable"}, + scope: "session", + }, { + sql: "set session tx_read_only = 0", + out: map[SetKey]interface{}{{Key: "tx_read_only", Scope: "session"}: int64(0)}, + scope: "session", + }, { + sql: "set session tx_read_only = 1", + out: map[SetKey]interface{}{{Key: "tx_read_only", Scope: "session"}: int64(1)}, + scope: "session", + }, { + sql: "set session sql_safe_updates = 0", + out: map[SetKey]interface{}{{Key: "sql_safe_updates", Scope: "session"}: int64(0)}, + scope: "session", + }, { + sql: "set session sql_safe_updates = 1", + out: map[SetKey]interface{}{{Key: "sql_safe_updates", Scope: "session"}: int64(1)}, + scope: "session", + }} + for _, tcase := range testcases { + out, _, err := ExtractSetValues(tcase.sql) + if tcase.err != "" { + if err == nil || err.Error() != tcase.err { + t.Errorf("ExtractSetValues(%s): %v, want '%s'", tcase.sql, err, tcase.err) + } + } else if err != nil { + t.Errorf("ExtractSetValues(%s): %v, want no error", tcase.sql, err) + } + if !reflect.DeepEqual(out, tcase.out) { + t.Errorf("ExtractSetValues(%s): %v, want '%v'", tcase.sql, out, tcase.out) + } + } +} + +func newStrVal(in string) *SQLVal { + return NewStrVal([]byte(in)) +} + +func newIntVal(in string) *SQLVal { + return NewIntVal([]byte(in)) +} + +func newHexVal(in string) *SQLVal { + return NewHexVal([]byte(in)) +} + +func newValArg(in string) *SQLVal { + return NewValArg([]byte(in)) +} diff --git a/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/ast.go b/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/ast.go new file mode 100644 index 00000000..c3a0d083 --- /dev/null +++ b/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/ast.go @@ -0,0 +1,3450 @@ +/* +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 sqlparser + +import ( + "bytes" + "encoding/hex" + "encoding/json" + "fmt" + "io" + "log" + "strings" + + "github.com/xwb1989/sqlparser/dependency/querypb" + "github.com/xwb1989/sqlparser/dependency/sqltypes" +) + +// Instructions for creating new types: If a type +// needs to satisfy an interface, declare that function +// along with that interface. This will help users +// identify the list of types to which they can assert +// those interfaces. +// If the member of a type has a string with a predefined +// list of values, declare those values as const following +// the type. +// For interfaces that define dummy functions to consolidate +// a set of types, define the function as iTypeName. +// This will help avoid name collisions. + +// Parse parses the SQL in full and returns a Statement, which +// is the AST representation of the query. If a DDL statement +// is partially parsed but still contains a syntax error, the +// error is ignored and the DDL is returned anyway. +func Parse(sql string) (Statement, error) { + tokenizer := NewStringTokenizer(sql) + if yyParse(tokenizer) != 0 { + if tokenizer.partialDDL != nil { + log.Printf("ignoring error parsing DDL '%s': %v", sql, tokenizer.LastError) + tokenizer.ParseTree = tokenizer.partialDDL + return tokenizer.ParseTree, nil + } + return nil, tokenizer.LastError + } + return tokenizer.ParseTree, nil +} + +// ParseStrictDDL is the same as Parse except it errors on +// partially parsed DDL statements. +func ParseStrictDDL(sql string) (Statement, error) { + tokenizer := NewStringTokenizer(sql) + if yyParse(tokenizer) != 0 { + return nil, tokenizer.LastError + } + return tokenizer.ParseTree, nil +} + +// ParseNext parses a single SQL statement from the tokenizer +// returning a Statement which is the AST representation of the query. +// The tokenizer will always read up to the end of the statement, allowing for +// the next call to ParseNext to parse any subsequent SQL statements. When +// there are no more statements to parse, a error of io.EOF is returned. +func ParseNext(tokenizer *Tokenizer) (Statement, error) { + if tokenizer.lastChar == ';' { + tokenizer.next() + tokenizer.skipBlank() + } + if tokenizer.lastChar == eofChar { + return nil, io.EOF + } + + tokenizer.reset() + tokenizer.multi = true + if yyParse(tokenizer) != 0 { + if tokenizer.partialDDL != nil { + tokenizer.ParseTree = tokenizer.partialDDL + return tokenizer.ParseTree, nil + } + return nil, tokenizer.LastError + } + return tokenizer.ParseTree, nil +} + +// SplitStatement returns the first sql statement up to either a ; or EOF +// and the remainder from the given buffer +func SplitStatement(blob string) (string, string, error) { + tokenizer := NewStringTokenizer(blob) + tkn := 0 + for { + tkn, _ = tokenizer.Scan() + if tkn == 0 || tkn == ';' || tkn == eofChar { + break + } + } + if tokenizer.LastError != nil { + return "", "", tokenizer.LastError + } + if tkn == ';' { + return blob[:tokenizer.Position-2], blob[tokenizer.Position-1:], nil + } + return blob, "", nil +} + +// SplitStatementToPieces split raw sql statement that may have multi sql pieces to sql pieces +// returns the sql pieces blob contains; or error if sql cannot be parsed +func SplitStatementToPieces(blob string) (pieces []string, err error) { + pieces = make([]string, 0, 16) + tokenizer := NewStringTokenizer(blob) + + tkn := 0 + var stmt string + stmtBegin := 0 + for { + tkn, _ = tokenizer.Scan() + if tkn == ';' { + stmt = blob[stmtBegin : tokenizer.Position-2] + pieces = append(pieces, stmt) + stmtBegin = tokenizer.Position - 1 + + } else if tkn == 0 || tkn == eofChar { + blobTail := tokenizer.Position - 2 + + if stmtBegin < blobTail { + stmt = blob[stmtBegin : blobTail+1] + pieces = append(pieces, stmt) + } + break + } + } + + err = tokenizer.LastError + return +} + +// SQLNode defines the interface for all nodes +// generated by the parser. +type SQLNode interface { + Format(buf *TrackedBuffer) + // walkSubtree calls visit on all underlying nodes + // of the subtree, but not the current one. Walking + // must be interrupted if visit returns an error. + walkSubtree(visit Visit) error +} + +// Visit defines the signature of a function that +// can be used to visit all nodes of a parse tree. +type Visit func(node SQLNode) (kontinue bool, err error) + +// Walk calls visit on every node. +// If visit returns true, the underlying nodes +// are also visited. If it returns an error, walking +// is interrupted, and the error is returned. +func Walk(visit Visit, nodes ...SQLNode) error { + for _, node := range nodes { + if node == nil { + continue + } + kontinue, err := visit(node) + if err != nil { + return err + } + if kontinue { + err = node.walkSubtree(visit) + if err != nil { + return err + } + } + } + return nil +} + +// String returns a string representation of an SQLNode. +func String(node SQLNode) string { + if node == nil { + return "" + } + + buf := NewTrackedBuffer(nil) + buf.Myprintf("%v", node) + return buf.String() +} + +// Append appends the SQLNode to the buffer. +func Append(buf *bytes.Buffer, node SQLNode) { + tbuf := &TrackedBuffer{ + Buffer: buf, + } + node.Format(tbuf) +} + +// Statement represents a statement. +type Statement interface { + iStatement() + SQLNode +} + +func (*Union) iStatement() {} +func (*Select) iStatement() {} +func (*Stream) iStatement() {} +func (*Insert) iStatement() {} +func (*Update) iStatement() {} +func (*Delete) iStatement() {} +func (*Set) iStatement() {} +func (*DBDDL) iStatement() {} +func (*DDL) iStatement() {} +func (*Show) iStatement() {} +func (*Use) iStatement() {} +func (*Begin) iStatement() {} +func (*Commit) iStatement() {} +func (*Rollback) iStatement() {} +func (*OtherRead) iStatement() {} +func (*OtherAdmin) iStatement() {} + +// ParenSelect can actually not be a top level statement, +// but we have to allow it because it's a requirement +// of SelectStatement. +func (*ParenSelect) iStatement() {} + +// SelectStatement any SELECT statement. +type SelectStatement interface { + iSelectStatement() + iStatement() + iInsertRows() + AddOrder(*Order) + SetLimit(*Limit) + SQLNode +} + +func (*Select) iSelectStatement() {} +func (*Union) iSelectStatement() {} +func (*ParenSelect) iSelectStatement() {} + +// Select represents a SELECT statement. +type Select struct { + Cache string + Comments Comments + Distinct string + Hints string + SelectExprs SelectExprs + From TableExprs + Where *Where + GroupBy GroupBy + Having *Where + OrderBy OrderBy + Limit *Limit + Lock string +} + +// Select.Distinct +const ( + DistinctStr = "distinct " + StraightJoinHint = "straight_join " +) + +// Select.Lock +const ( + ForUpdateStr = " for update" + ShareModeStr = " lock in share mode" +) + +// Select.Cache +const ( + SQLCacheStr = "sql_cache " + SQLNoCacheStr = "sql_no_cache " +) + +// AddOrder adds an order by element +func (node *Select) AddOrder(order *Order) { + node.OrderBy = append(node.OrderBy, order) +} + +// SetLimit sets the limit clause +func (node *Select) SetLimit(limit *Limit) { + node.Limit = limit +} + +// Format formats the node. +func (node *Select) Format(buf *TrackedBuffer) { + buf.Myprintf("select %v%s%s%s%v from %v%v%v%v%v%v%s", + node.Comments, node.Cache, node.Distinct, node.Hints, node.SelectExprs, + node.From, node.Where, + node.GroupBy, node.Having, node.OrderBy, + node.Limit, node.Lock) +} + +func (node *Select) walkSubtree(visit Visit) error { + if node == nil { + return nil + } + return Walk( + visit, + node.Comments, + node.SelectExprs, + node.From, + node.Where, + node.GroupBy, + node.Having, + node.OrderBy, + node.Limit, + ) +} + +// AddWhere adds the boolean expression to the +// WHERE clause as an AND condition. If the expression +// is an OR clause, it parenthesizes it. Currently, +// the OR operator is the only one that's lower precedence +// than AND. +func (node *Select) AddWhere(expr Expr) { + if _, ok := expr.(*OrExpr); ok { + expr = &ParenExpr{Expr: expr} + } + if node.Where == nil { + node.Where = &Where{ + Type: WhereStr, + Expr: expr, + } + return + } + node.Where.Expr = &AndExpr{ + Left: node.Where.Expr, + Right: expr, + } + return +} + +// AddHaving adds the boolean expression to the +// HAVING clause as an AND condition. If the expression +// is an OR clause, it parenthesizes it. Currently, +// the OR operator is the only one that's lower precedence +// than AND. +func (node *Select) AddHaving(expr Expr) { + if _, ok := expr.(*OrExpr); ok { + expr = &ParenExpr{Expr: expr} + } + if node.Having == nil { + node.Having = &Where{ + Type: HavingStr, + Expr: expr, + } + return + } + node.Having.Expr = &AndExpr{ + Left: node.Having.Expr, + Right: expr, + } + return +} + +// ParenSelect is a parenthesized SELECT statement. +type ParenSelect struct { + Select SelectStatement +} + +// AddOrder adds an order by element +func (node *ParenSelect) AddOrder(order *Order) { + panic("unreachable") +} + +// SetLimit sets the limit clause +func (node *ParenSelect) SetLimit(limit *Limit) { + panic("unreachable") +} + +// Format formats the node. +func (node *ParenSelect) Format(buf *TrackedBuffer) { + buf.Myprintf("(%v)", node.Select) +} + +func (node *ParenSelect) walkSubtree(visit Visit) error { + if node == nil { + return nil + } + return Walk( + visit, + node.Select, + ) +} + +// Union represents a UNION statement. +type Union struct { + Type string + Left, Right SelectStatement + OrderBy OrderBy + Limit *Limit + Lock string +} + +// Union.Type +const ( + UnionStr = "union" + UnionAllStr = "union all" + UnionDistinctStr = "union distinct" +) + +// AddOrder adds an order by element +func (node *Union) AddOrder(order *Order) { + node.OrderBy = append(node.OrderBy, order) +} + +// SetLimit sets the limit clause +func (node *Union) SetLimit(limit *Limit) { + node.Limit = limit +} + +// Format formats the node. +func (node *Union) Format(buf *TrackedBuffer) { + buf.Myprintf("%v %s %v%v%v%s", node.Left, node.Type, node.Right, + node.OrderBy, node.Limit, node.Lock) +} + +func (node *Union) walkSubtree(visit Visit) error { + if node == nil { + return nil + } + return Walk( + visit, + node.Left, + node.Right, + ) +} + +// Stream represents a SELECT statement. +type Stream struct { + Comments Comments + SelectExpr SelectExpr + Table TableName +} + +// Format formats the node. +func (node *Stream) Format(buf *TrackedBuffer) { + buf.Myprintf("stream %v%v from %v", + node.Comments, node.SelectExpr, node.Table) +} + +func (node *Stream) walkSubtree(visit Visit) error { + if node == nil { + return nil + } + return Walk( + visit, + node.Comments, + node.SelectExpr, + node.Table, + ) +} + +// Insert represents an INSERT or REPLACE statement. +// Per the MySQL docs, http://dev.mysql.com/doc/refman/5.7/en/replace.html +// Replace is the counterpart to `INSERT IGNORE`, and works exactly like a +// normal INSERT except if the row exists. In that case it first deletes +// the row and re-inserts with new values. For that reason we keep it as an Insert struct. +// Replaces are currently disallowed in sharded schemas because +// of the implications the deletion part may have on vindexes. +// If you add fields here, consider adding them to calls to validateSubquerySamePlan. +type Insert struct { + Action string + Comments Comments + Ignore string + Table TableName + Partitions Partitions + Columns Columns + Rows InsertRows + OnDup OnDup +} + +// DDL strings. +const ( + InsertStr = "insert" + ReplaceStr = "replace" +) + +// Format formats the node. +func (node *Insert) Format(buf *TrackedBuffer) { + buf.Myprintf("%s %v%sinto %v%v%v %v%v", + node.Action, + node.Comments, node.Ignore, + node.Table, node.Partitions, node.Columns, node.Rows, node.OnDup) +} + +func (node *Insert) walkSubtree(visit Visit) error { + if node == nil { + return nil + } + return Walk( + visit, + node.Comments, + node.Table, + node.Columns, + node.Rows, + node.OnDup, + ) +} + +// InsertRows represents the rows for an INSERT statement. +type InsertRows interface { + iInsertRows() + SQLNode +} + +func (*Select) iInsertRows() {} +func (*Union) iInsertRows() {} +func (Values) iInsertRows() {} +func (*ParenSelect) iInsertRows() {} + +// Update represents an UPDATE statement. +// If you add fields here, consider adding them to calls to validateSubquerySamePlan. +type Update struct { + Comments Comments + TableExprs TableExprs + Exprs UpdateExprs + Where *Where + OrderBy OrderBy + Limit *Limit +} + +// Format formats the node. +func (node *Update) Format(buf *TrackedBuffer) { + buf.Myprintf("update %v%v set %v%v%v%v", + node.Comments, node.TableExprs, + node.Exprs, node.Where, node.OrderBy, node.Limit) +} + +func (node *Update) walkSubtree(visit Visit) error { + if node == nil { + return nil + } + return Walk( + visit, + node.Comments, + node.TableExprs, + node.Exprs, + node.Where, + node.OrderBy, + node.Limit, + ) +} + +// Delete represents a DELETE statement. +// If you add fields here, consider adding them to calls to validateSubquerySamePlan. +type Delete struct { + Comments Comments + Targets TableNames + TableExprs TableExprs + Partitions Partitions + Where *Where + OrderBy OrderBy + Limit *Limit +} + +// Format formats the node. +func (node *Delete) Format(buf *TrackedBuffer) { + buf.Myprintf("delete %v", node.Comments) + if node.Targets != nil { + buf.Myprintf("%v ", node.Targets) + } + buf.Myprintf("from %v%v%v%v%v", node.TableExprs, node.Partitions, node.Where, node.OrderBy, node.Limit) +} + +func (node *Delete) walkSubtree(visit Visit) error { + if node == nil { + return nil + } + return Walk( + visit, + node.Comments, + node.Targets, + node.TableExprs, + node.Where, + node.OrderBy, + node.Limit, + ) +} + +// Set represents a SET statement. +type Set struct { + Comments Comments + Exprs SetExprs + Scope string +} + +// Set.Scope or Show.Scope +const ( + SessionStr = "session" + GlobalStr = "global" +) + +// Format formats the node. +func (node *Set) Format(buf *TrackedBuffer) { + if node.Scope == "" { + buf.Myprintf("set %v%v", node.Comments, node.Exprs) + } else { + buf.Myprintf("set %v%s %v", node.Comments, node.Scope, node.Exprs) + } +} + +func (node *Set) walkSubtree(visit Visit) error { + if node == nil { + return nil + } + return Walk( + visit, + node.Comments, + node.Exprs, + ) +} + +// DBDDL represents a CREATE, DROP database statement. +type DBDDL struct { + Action string + DBName string + IfExists bool + Collate string + Charset string +} + +// Format formats the node. +func (node *DBDDL) Format(buf *TrackedBuffer) { + switch node.Action { + case CreateStr: + buf.WriteString(fmt.Sprintf("%s database %s", node.Action, node.DBName)) + case DropStr: + exists := "" + if node.IfExists { + exists = " if exists" + } + buf.WriteString(fmt.Sprintf("%s database%s %v", node.Action, exists, node.DBName)) + } +} + +// walkSubtree walks the nodes of the subtree. +func (node *DBDDL) walkSubtree(visit Visit) error { + return nil +} + +// DDL represents a CREATE, ALTER, DROP, RENAME or TRUNCATE statement. +// Table is set for AlterStr, DropStr, RenameStr, TruncateStr +// NewName is set for AlterStr, CreateStr, RenameStr. +// VindexSpec is set for CreateVindexStr, DropVindexStr, AddColVindexStr, DropColVindexStr +// VindexCols is set for AddColVindexStr +type DDL struct { + Action string + Table TableName + NewName TableName + IfExists bool + TableSpec *TableSpec + PartitionSpec *PartitionSpec + VindexSpec *VindexSpec + VindexCols []ColIdent +} + +// DDL strings. +const ( + CreateStr = "create" + AlterStr = "alter" + DropStr = "drop" + RenameStr = "rename" + TruncateStr = "truncate" + CreateVindexStr = "create vindex" + AddColVindexStr = "add vindex" + DropColVindexStr = "drop vindex" + + // Vindex DDL param to specify the owner of a vindex + VindexOwnerStr = "owner" +) + +// Format formats the node. +func (node *DDL) Format(buf *TrackedBuffer) { + switch node.Action { + case CreateStr: + if node.TableSpec == nil { + buf.Myprintf("%s table %v", node.Action, node.NewName) + } else { + buf.Myprintf("%s table %v %v", node.Action, node.NewName, node.TableSpec) + } + case DropStr: + exists := "" + if node.IfExists { + exists = " if exists" + } + buf.Myprintf("%s table%s %v", node.Action, exists, node.Table) + case RenameStr: + buf.Myprintf("%s table %v to %v", node.Action, node.Table, node.NewName) + case AlterStr: + if node.PartitionSpec != nil { + buf.Myprintf("%s table %v %v", node.Action, node.Table, node.PartitionSpec) + } else { + buf.Myprintf("%s table %v", node.Action, node.Table) + } + case CreateVindexStr: + buf.Myprintf("%s %v %v", node.Action, node.VindexSpec.Name, node.VindexSpec) + case AddColVindexStr: + buf.Myprintf("alter table %v %s %v (", node.Table, node.Action, node.VindexSpec.Name) + for i, col := range node.VindexCols { + if i != 0 { + buf.Myprintf(", %v", col) + } else { + buf.Myprintf("%v", col) + } + } + buf.Myprintf(")") + if node.VindexSpec.Type.String() != "" { + buf.Myprintf(" %v", node.VindexSpec) + } + case DropColVindexStr: + buf.Myprintf("alter table %v %s %v", node.Table, node.Action, node.VindexSpec.Name) + default: + buf.Myprintf("%s table %v", node.Action, node.Table) + } +} + +func (node *DDL) walkSubtree(visit Visit) error { + if node == nil { + return nil + } + return Walk( + visit, + node.Table, + node.NewName, + ) +} + +// Partition strings +const ( + ReorganizeStr = "reorganize partition" +) + +// PartitionSpec describe partition actions (for alter and create) +type PartitionSpec struct { + Action string + Name ColIdent + Definitions []*PartitionDefinition +} + +// Format formats the node. +func (node *PartitionSpec) Format(buf *TrackedBuffer) { + switch node.Action { + case ReorganizeStr: + buf.Myprintf("%s %v into (", node.Action, node.Name) + var prefix string + for _, pd := range node.Definitions { + buf.Myprintf("%s%v", prefix, pd) + prefix = ", " + } + buf.Myprintf(")") + default: + panic("unimplemented") + } +} + +func (node *PartitionSpec) walkSubtree(visit Visit) error { + if node == nil { + return nil + } + if err := Walk(visit, node.Name); err != nil { + return err + } + for _, def := range node.Definitions { + if err := Walk(visit, def); err != nil { + return err + } + } + return nil +} + +// PartitionDefinition describes a very minimal partition definition +type PartitionDefinition struct { + Name ColIdent + Limit Expr + Maxvalue bool +} + +// Format formats the node +func (node *PartitionDefinition) Format(buf *TrackedBuffer) { + if !node.Maxvalue { + buf.Myprintf("partition %v values less than (%v)", node.Name, node.Limit) + } else { + buf.Myprintf("partition %v values less than (maxvalue)", node.Name) + } +} + +func (node *PartitionDefinition) walkSubtree(visit Visit) error { + if node == nil { + return nil + } + return Walk( + visit, + node.Name, + node.Limit, + ) +} + +// TableSpec describes the structure of a table from a CREATE TABLE statement +type TableSpec struct { + Columns []*ColumnDefinition + Indexes []*IndexDefinition + Options string +} + +// Format formats the node. +func (ts *TableSpec) Format(buf *TrackedBuffer) { + buf.Myprintf("(\n") + for i, col := range ts.Columns { + if i == 0 { + buf.Myprintf("\t%v", col) + } else { + buf.Myprintf(",\n\t%v", col) + } + } + for _, idx := range ts.Indexes { + buf.Myprintf(",\n\t%v", idx) + } + + buf.Myprintf("\n)%s", strings.Replace(ts.Options, ", ", ",\n ", -1)) +} + +// AddColumn appends the given column to the list in the spec +func (ts *TableSpec) AddColumn(cd *ColumnDefinition) { + ts.Columns = append(ts.Columns, cd) +} + +// AddIndex appends the given index to the list in the spec +func (ts *TableSpec) AddIndex(id *IndexDefinition) { + ts.Indexes = append(ts.Indexes, id) +} + +func (ts *TableSpec) walkSubtree(visit Visit) error { + if ts == nil { + return nil + } + + for _, n := range ts.Columns { + if err := Walk(visit, n); err != nil { + return err + } + } + + for _, n := range ts.Indexes { + if err := Walk(visit, n); err != nil { + return err + } + } + + return nil +} + +// ColumnDefinition describes a column in a CREATE TABLE statement +type ColumnDefinition struct { + Name ColIdent + Type ColumnType +} + +// Format formats the node. +func (col *ColumnDefinition) Format(buf *TrackedBuffer) { + buf.Myprintf("%v %v", col.Name, &col.Type) +} + +func (col *ColumnDefinition) walkSubtree(visit Visit) error { + if col == nil { + return nil + } + return Walk( + visit, + col.Name, + &col.Type, + ) +} + +// ColumnType represents a sql type in a CREATE TABLE statement +// All optional fields are nil if not specified +type ColumnType struct { + // The base type string + Type string + + // Generic field options. + NotNull BoolVal + Autoincrement BoolVal + Default *SQLVal + OnUpdate *SQLVal + Comment *SQLVal + + // Numeric field options + Length *SQLVal + Unsigned BoolVal + Zerofill BoolVal + Scale *SQLVal + + // Text field options + Charset string + Collate string + + // Enum values + EnumValues []string + + // Key specification + KeyOpt ColumnKeyOption +} + +// Format returns a canonical string representation of the type and all relevant options +func (ct *ColumnType) Format(buf *TrackedBuffer) { + buf.Myprintf("%s", ct.Type) + + if ct.Length != nil && ct.Scale != nil { + buf.Myprintf("(%v,%v)", ct.Length, ct.Scale) + + } else if ct.Length != nil { + buf.Myprintf("(%v)", ct.Length) + } + + if ct.EnumValues != nil { + buf.Myprintf("(%s)", strings.Join(ct.EnumValues, ", ")) + } + + opts := make([]string, 0, 16) + if ct.Unsigned { + opts = append(opts, keywordStrings[UNSIGNED]) + } + if ct.Zerofill { + opts = append(opts, keywordStrings[ZEROFILL]) + } + if ct.Charset != "" { + opts = append(opts, keywordStrings[CHARACTER], keywordStrings[SET], ct.Charset) + } + if ct.Collate != "" { + opts = append(opts, keywordStrings[COLLATE], ct.Collate) + } + if ct.NotNull { + opts = append(opts, keywordStrings[NOT], keywordStrings[NULL]) + } + if ct.Default != nil { + opts = append(opts, keywordStrings[DEFAULT], String(ct.Default)) + } + if ct.OnUpdate != nil { + opts = append(opts, keywordStrings[ON], keywordStrings[UPDATE], String(ct.OnUpdate)) + } + if ct.Autoincrement { + opts = append(opts, keywordStrings[AUTO_INCREMENT]) + } + if ct.Comment != nil { + opts = append(opts, keywordStrings[COMMENT_KEYWORD], String(ct.Comment)) + } + if ct.KeyOpt == colKeyPrimary { + opts = append(opts, keywordStrings[PRIMARY], keywordStrings[KEY]) + } + if ct.KeyOpt == colKeyUnique { + opts = append(opts, keywordStrings[UNIQUE]) + } + if ct.KeyOpt == colKeyUniqueKey { + opts = append(opts, keywordStrings[UNIQUE], keywordStrings[KEY]) + } + if ct.KeyOpt == colKeySpatialKey { + opts = append(opts, keywordStrings[SPATIAL], keywordStrings[KEY]) + } + if ct.KeyOpt == colKey { + opts = append(opts, keywordStrings[KEY]) + } + + if len(opts) != 0 { + buf.Myprintf(" %s", strings.Join(opts, " ")) + } +} + +// DescribeType returns the abbreviated type information as required for +// describe table +func (ct *ColumnType) DescribeType() string { + buf := NewTrackedBuffer(nil) + buf.Myprintf("%s", ct.Type) + if ct.Length != nil && ct.Scale != nil { + buf.Myprintf("(%v,%v)", ct.Length, ct.Scale) + } else if ct.Length != nil { + buf.Myprintf("(%v)", ct.Length) + } + + opts := make([]string, 0, 16) + if ct.Unsigned { + opts = append(opts, keywordStrings[UNSIGNED]) + } + if ct.Zerofill { + opts = append(opts, keywordStrings[ZEROFILL]) + } + if len(opts) != 0 { + buf.Myprintf(" %s", strings.Join(opts, " ")) + } + return buf.String() +} + +// SQLType returns the sqltypes type code for the given column +func (ct *ColumnType) SQLType() querypb.Type { + switch ct.Type { + case keywordStrings[TINYINT]: + if ct.Unsigned { + return sqltypes.Uint8 + } + return sqltypes.Int8 + case keywordStrings[SMALLINT]: + if ct.Unsigned { + return sqltypes.Uint16 + } + return sqltypes.Int16 + case keywordStrings[MEDIUMINT]: + if ct.Unsigned { + return sqltypes.Uint24 + } + return sqltypes.Int24 + case keywordStrings[INT]: + fallthrough + case keywordStrings[INTEGER]: + if ct.Unsigned { + return sqltypes.Uint32 + } + return sqltypes.Int32 + case keywordStrings[BIGINT]: + if ct.Unsigned { + return sqltypes.Uint64 + } + return sqltypes.Int64 + case keywordStrings[TEXT]: + return sqltypes.Text + case keywordStrings[TINYTEXT]: + return sqltypes.Text + case keywordStrings[MEDIUMTEXT]: + return sqltypes.Text + case keywordStrings[LONGTEXT]: + return sqltypes.Text + case keywordStrings[BLOB]: + return sqltypes.Blob + case keywordStrings[TINYBLOB]: + return sqltypes.Blob + case keywordStrings[MEDIUMBLOB]: + return sqltypes.Blob + case keywordStrings[LONGBLOB]: + return sqltypes.Blob + case keywordStrings[CHAR]: + return sqltypes.Char + case keywordStrings[VARCHAR]: + return sqltypes.VarChar + case keywordStrings[BINARY]: + return sqltypes.Binary + case keywordStrings[VARBINARY]: + return sqltypes.VarBinary + case keywordStrings[DATE]: + return sqltypes.Date + case keywordStrings[TIME]: + return sqltypes.Time + case keywordStrings[DATETIME]: + return sqltypes.Datetime + case keywordStrings[TIMESTAMP]: + return sqltypes.Timestamp + case keywordStrings[YEAR]: + return sqltypes.Year + case keywordStrings[FLOAT_TYPE]: + return sqltypes.Float32 + case keywordStrings[DOUBLE]: + return sqltypes.Float64 + case keywordStrings[DECIMAL]: + return sqltypes.Decimal + case keywordStrings[BIT]: + return sqltypes.Bit + case keywordStrings[ENUM]: + return sqltypes.Enum + case keywordStrings[SET]: + return sqltypes.Set + case keywordStrings[JSON]: + return sqltypes.TypeJSON + case keywordStrings[GEOMETRY]: + return sqltypes.Geometry + case keywordStrings[POINT]: + return sqltypes.Geometry + case keywordStrings[LINESTRING]: + return sqltypes.Geometry + case keywordStrings[POLYGON]: + return sqltypes.Geometry + case keywordStrings[GEOMETRYCOLLECTION]: + return sqltypes.Geometry + case keywordStrings[MULTIPOINT]: + return sqltypes.Geometry + case keywordStrings[MULTILINESTRING]: + return sqltypes.Geometry + case keywordStrings[MULTIPOLYGON]: + return sqltypes.Geometry + } + panic("unimplemented type " + ct.Type) +} + +func (ct *ColumnType) walkSubtree(visit Visit) error { + return nil +} + +// IndexDefinition describes an index in a CREATE TABLE statement +type IndexDefinition struct { + Info *IndexInfo + Columns []*IndexColumn + Options []*IndexOption +} + +// Format formats the node. +func (idx *IndexDefinition) Format(buf *TrackedBuffer) { + buf.Myprintf("%v (", idx.Info) + for i, col := range idx.Columns { + if i != 0 { + buf.Myprintf(", %v", col.Column) + } else { + buf.Myprintf("%v", col.Column) + } + if col.Length != nil { + buf.Myprintf("(%v)", col.Length) + } + } + buf.Myprintf(")") + + for _, opt := range idx.Options { + buf.Myprintf(" %s", opt.Name) + if opt.Using != "" { + buf.Myprintf(" %s", opt.Using) + } else { + buf.Myprintf(" %v", opt.Value) + } + } +} + +func (idx *IndexDefinition) walkSubtree(visit Visit) error { + if idx == nil { + return nil + } + + for _, n := range idx.Columns { + if err := Walk(visit, n.Column); err != nil { + return err + } + } + + return nil +} + +// IndexInfo describes the name and type of an index in a CREATE TABLE statement +type IndexInfo struct { + Type string + Name ColIdent + Primary bool + Spatial bool + Unique bool +} + +// Format formats the node. +func (ii *IndexInfo) Format(buf *TrackedBuffer) { + if ii.Primary { + buf.Myprintf("%s", ii.Type) + } else { + buf.Myprintf("%s %v", ii.Type, ii.Name) + } +} + +func (ii *IndexInfo) walkSubtree(visit Visit) error { + return Walk(visit, ii.Name) +} + +// IndexColumn describes a column in an index definition with optional length +type IndexColumn struct { + Column ColIdent + Length *SQLVal +} + +// LengthScaleOption is used for types that have an optional length +// and scale +type LengthScaleOption struct { + Length *SQLVal + Scale *SQLVal +} + +// IndexOption is used for trailing options for indexes: COMMENT, KEY_BLOCK_SIZE, USING +type IndexOption struct { + Name string + Value *SQLVal + Using string +} + +// ColumnKeyOption indicates whether or not the given column is defined as an +// index element and contains the type of the option +type ColumnKeyOption int + +const ( + colKeyNone ColumnKeyOption = iota + colKeyPrimary + colKeySpatialKey + colKeyUnique + colKeyUniqueKey + colKey +) + +// VindexSpec defines a vindex for a CREATE VINDEX or DROP VINDEX statement +type VindexSpec struct { + Name ColIdent + Type ColIdent + Params []VindexParam +} + +// ParseParams parses the vindex parameter list, pulling out the special-case +// "owner" parameter +func (node *VindexSpec) ParseParams() (string, map[string]string) { + var owner string + params := map[string]string{} + for _, p := range node.Params { + if p.Key.Lowered() == VindexOwnerStr { + owner = p.Val + } else { + params[p.Key.String()] = p.Val + } + } + return owner, params +} + +// Format formats the node. The "CREATE VINDEX" preamble was formatted in +// the containing DDL node Format, so this just prints the type, any +// parameters, and optionally the owner +func (node *VindexSpec) Format(buf *TrackedBuffer) { + buf.Myprintf("using %v", node.Type) + + numParams := len(node.Params) + if numParams != 0 { + buf.Myprintf(" with ") + for i, p := range node.Params { + if i != 0 { + buf.Myprintf(", ") + } + buf.Myprintf("%v", p) + } + } +} + +func (node *VindexSpec) walkSubtree(visit Visit) error { + err := Walk(visit, + node.Name, + ) + + if err != nil { + return err + } + + for _, p := range node.Params { + err := Walk(visit, p) + + if err != nil { + return err + } + } + return nil +} + +// VindexParam defines a key/value parameter for a CREATE VINDEX statement +type VindexParam struct { + Key ColIdent + Val string +} + +// Format formats the node. +func (node VindexParam) Format(buf *TrackedBuffer) { + buf.Myprintf("%s=%s", node.Key.String(), node.Val) +} + +func (node VindexParam) walkSubtree(visit Visit) error { + return Walk(visit, + node.Key, + ) +} + +// Show represents a show statement. +type Show struct { + Type string + OnTable TableName + ShowTablesOpt *ShowTablesOpt + Scope string +} + +// Format formats the node. +func (node *Show) Format(buf *TrackedBuffer) { + if node.Type == "tables" && node.ShowTablesOpt != nil { + opt := node.ShowTablesOpt + if opt.DbName != "" { + if opt.Filter != nil { + buf.Myprintf("show %s%stables from %s %v", opt.Extended, opt.Full, opt.DbName, opt.Filter) + } else { + buf.Myprintf("show %s%stables from %s", opt.Extended, opt.Full, opt.DbName) + } + } else { + if opt.Filter != nil { + buf.Myprintf("show %s%stables %v", opt.Extended, opt.Full, opt.Filter) + } else { + buf.Myprintf("show %s%stables", opt.Extended, opt.Full) + } + } + return + } + if node.Scope == "" { + buf.Myprintf("show %s", node.Type) + } else { + buf.Myprintf("show %s %s", node.Scope, node.Type) + } + if node.HasOnTable() { + buf.Myprintf(" on %v", node.OnTable) + } +} + +// HasOnTable returns true if the show statement has an "on" clause +func (node *Show) HasOnTable() bool { + return node.OnTable.Name.v != "" +} + +func (node *Show) walkSubtree(visit Visit) error { + return nil +} + +// ShowTablesOpt is show tables option +type ShowTablesOpt struct { + Extended string + Full string + DbName string + Filter *ShowFilter +} + +// ShowFilter is show tables filter +type ShowFilter struct { + Like string + Filter Expr +} + +// Format formats the node. +func (node *ShowFilter) Format(buf *TrackedBuffer) { + if node.Like != "" { + buf.Myprintf("like '%s'", node.Like) + } else { + buf.Myprintf("where %v", node.Filter) + } +} + +func (node *ShowFilter) walkSubtree(visit Visit) error { + return nil +} + +// Use represents a use statement. +type Use struct { + DBName TableIdent +} + +// Format formats the node. +func (node *Use) Format(buf *TrackedBuffer) { + if node.DBName.v != "" { + buf.Myprintf("use %v", node.DBName) + } else { + buf.Myprintf("use") + } +} + +func (node *Use) walkSubtree(visit Visit) error { + return Walk(visit, node.DBName) +} + +// Begin represents a Begin statement. +type Begin struct{} + +// Format formats the node. +func (node *Begin) Format(buf *TrackedBuffer) { + buf.WriteString("begin") +} + +func (node *Begin) walkSubtree(visit Visit) error { + return nil +} + +// Commit represents a Commit statement. +type Commit struct{} + +// Format formats the node. +func (node *Commit) Format(buf *TrackedBuffer) { + buf.WriteString("commit") +} + +func (node *Commit) walkSubtree(visit Visit) error { + return nil +} + +// Rollback represents a Rollback statement. +type Rollback struct{} + +// Format formats the node. +func (node *Rollback) Format(buf *TrackedBuffer) { + buf.WriteString("rollback") +} + +func (node *Rollback) walkSubtree(visit Visit) error { + return nil +} + +// OtherRead represents a DESCRIBE, or EXPLAIN statement. +// It should be used only as an indicator. It does not contain +// the full AST for the statement. +type OtherRead struct{} + +// Format formats the node. +func (node *OtherRead) Format(buf *TrackedBuffer) { + buf.WriteString("otherread") +} + +func (node *OtherRead) walkSubtree(visit Visit) error { + return nil +} + +// OtherAdmin represents a misc statement that relies on ADMIN privileges, +// such as REPAIR, OPTIMIZE, or TRUNCATE statement. +// It should be used only as an indicator. It does not contain +// the full AST for the statement. +type OtherAdmin struct{} + +// Format formats the node. +func (node *OtherAdmin) Format(buf *TrackedBuffer) { + buf.WriteString("otheradmin") +} + +func (node *OtherAdmin) walkSubtree(visit Visit) error { + return nil +} + +// Comments represents a list of comments. +type Comments [][]byte + +// Format formats the node. +func (node Comments) Format(buf *TrackedBuffer) { + for _, c := range node { + buf.Myprintf("%s ", c) + } +} + +func (node Comments) walkSubtree(visit Visit) error { + return nil +} + +// SelectExprs represents SELECT expressions. +type SelectExprs []SelectExpr + +// Format formats the node. +func (node SelectExprs) Format(buf *TrackedBuffer) { + var prefix string + for _, n := range node { + buf.Myprintf("%s%v", prefix, n) + prefix = ", " + } +} + +func (node SelectExprs) walkSubtree(visit Visit) error { + for _, n := range node { + if err := Walk(visit, n); err != nil { + return err + } + } + return nil +} + +// SelectExpr represents a SELECT expression. +type SelectExpr interface { + iSelectExpr() + SQLNode +} + +func (*StarExpr) iSelectExpr() {} +func (*AliasedExpr) iSelectExpr() {} +func (Nextval) iSelectExpr() {} + +// StarExpr defines a '*' or 'table.*' expression. +type StarExpr struct { + TableName TableName +} + +// Format formats the node. +func (node *StarExpr) Format(buf *TrackedBuffer) { + if !node.TableName.IsEmpty() { + buf.Myprintf("%v.", node.TableName) + } + buf.Myprintf("*") +} + +func (node *StarExpr) walkSubtree(visit Visit) error { + if node == nil { + return nil + } + return Walk( + visit, + node.TableName, + ) +} + +// AliasedExpr defines an aliased SELECT expression. +type AliasedExpr struct { + Expr Expr + As ColIdent +} + +// Format formats the node. +func (node *AliasedExpr) Format(buf *TrackedBuffer) { + buf.Myprintf("%v", node.Expr) + if !node.As.IsEmpty() { + buf.Myprintf(" as %v", node.As) + } +} + +func (node *AliasedExpr) walkSubtree(visit Visit) error { + if node == nil { + return nil + } + return Walk( + visit, + node.Expr, + node.As, + ) +} + +// Nextval defines the NEXT VALUE expression. +type Nextval struct { + Expr Expr +} + +// Format formats the node. +func (node Nextval) Format(buf *TrackedBuffer) { + buf.Myprintf("next %v values", node.Expr) +} + +func (node Nextval) walkSubtree(visit Visit) error { + return Walk(visit, node.Expr) +} + +// Columns represents an insert column list. +type Columns []ColIdent + +// Format formats the node. +func (node Columns) Format(buf *TrackedBuffer) { + if node == nil { + return + } + prefix := "(" + for _, n := range node { + buf.Myprintf("%s%v", prefix, n) + prefix = ", " + } + buf.WriteString(")") +} + +func (node Columns) walkSubtree(visit Visit) error { + for _, n := range node { + if err := Walk(visit, n); err != nil { + return err + } + } + return nil +} + +// FindColumn finds a column in the column list, returning +// the index if it exists or -1 otherwise +func (node Columns) FindColumn(col ColIdent) int { + for i, colName := range node { + if colName.Equal(col) { + return i + } + } + return -1 +} + +// Partitions is a type alias for Columns so we can handle printing efficiently +type Partitions Columns + +// Format formats the node +func (node Partitions) Format(buf *TrackedBuffer) { + if node == nil { + return + } + prefix := " partition (" + for _, n := range node { + buf.Myprintf("%s%v", prefix, n) + prefix = ", " + } + buf.WriteString(")") +} + +func (node Partitions) walkSubtree(visit Visit) error { + for _, n := range node { + if err := Walk(visit, n); err != nil { + return err + } + } + return nil +} + +// TableExprs represents a list of table expressions. +type TableExprs []TableExpr + +// Format formats the node. +func (node TableExprs) Format(buf *TrackedBuffer) { + var prefix string + for _, n := range node { + buf.Myprintf("%s%v", prefix, n) + prefix = ", " + } +} + +func (node TableExprs) walkSubtree(visit Visit) error { + for _, n := range node { + if err := Walk(visit, n); err != nil { + return err + } + } + return nil +} + +// TableExpr represents a table expression. +type TableExpr interface { + iTableExpr() + SQLNode +} + +func (*AliasedTableExpr) iTableExpr() {} +func (*ParenTableExpr) iTableExpr() {} +func (*JoinTableExpr) iTableExpr() {} + +// AliasedTableExpr represents a table expression +// coupled with an optional alias or index hint. +// If As is empty, no alias was used. +type AliasedTableExpr struct { + Expr SimpleTableExpr + Partitions Partitions + As TableIdent + Hints *IndexHints +} + +// Format formats the node. +func (node *AliasedTableExpr) Format(buf *TrackedBuffer) { + buf.Myprintf("%v%v", node.Expr, node.Partitions) + if !node.As.IsEmpty() { + buf.Myprintf(" as %v", node.As) + } + if node.Hints != nil { + // Hint node provides the space padding. + buf.Myprintf("%v", node.Hints) + } +} + +func (node *AliasedTableExpr) walkSubtree(visit Visit) error { + if node == nil { + return nil + } + return Walk( + visit, + node.Expr, + node.As, + node.Hints, + ) +} + +// RemoveHints returns a new AliasedTableExpr with the hints removed. +func (node *AliasedTableExpr) RemoveHints() *AliasedTableExpr { + noHints := *node + noHints.Hints = nil + return &noHints +} + +// SimpleTableExpr represents a simple table expression. +type SimpleTableExpr interface { + iSimpleTableExpr() + SQLNode +} + +func (TableName) iSimpleTableExpr() {} +func (*Subquery) iSimpleTableExpr() {} + +// TableNames is a list of TableName. +type TableNames []TableName + +// Format formats the node. +func (node TableNames) Format(buf *TrackedBuffer) { + var prefix string + for _, n := range node { + buf.Myprintf("%s%v", prefix, n) + prefix = ", " + } +} + +func (node TableNames) walkSubtree(visit Visit) error { + for _, n := range node { + if err := Walk(visit, n); err != nil { + return err + } + } + return nil +} + +// TableName represents a table name. +// Qualifier, if specified, represents a database or keyspace. +// TableName is a value struct whose fields are case sensitive. +// This means two TableName vars can be compared for equality +// and a TableName can also be used as key in a map. +type TableName struct { + Name, Qualifier TableIdent +} + +// Format formats the node. +func (node TableName) Format(buf *TrackedBuffer) { + if node.IsEmpty() { + return + } + if !node.Qualifier.IsEmpty() { + buf.Myprintf("%v.", node.Qualifier) + } + buf.Myprintf("%v", node.Name) +} + +func (node TableName) walkSubtree(visit Visit) error { + return Walk( + visit, + node.Name, + node.Qualifier, + ) +} + +// IsEmpty returns true if TableName is nil or empty. +func (node TableName) IsEmpty() bool { + // If Name is empty, Qualifer is also empty. + return node.Name.IsEmpty() +} + +// ToViewName returns a TableName acceptable for use as a VIEW. VIEW names are +// always lowercase, so ToViewName lowercasese the name. Databases are case-sensitive +// so Qualifier is left untouched. +func (node TableName) ToViewName() TableName { + return TableName{ + Qualifier: node.Qualifier, + Name: NewTableIdent(strings.ToLower(node.Name.v)), + } +} + +// ParenTableExpr represents a parenthesized list of TableExpr. +type ParenTableExpr struct { + Exprs TableExprs +} + +// Format formats the node. +func (node *ParenTableExpr) Format(buf *TrackedBuffer) { + buf.Myprintf("(%v)", node.Exprs) +} + +func (node *ParenTableExpr) walkSubtree(visit Visit) error { + if node == nil { + return nil + } + return Walk( + visit, + node.Exprs, + ) +} + +// JoinCondition represents the join conditions (either a ON or USING clause) +// of a JoinTableExpr. +type JoinCondition struct { + On Expr + Using Columns +} + +// Format formats the node. +func (node JoinCondition) Format(buf *TrackedBuffer) { + if node.On != nil { + buf.Myprintf(" on %v", node.On) + } + if node.Using != nil { + buf.Myprintf(" using %v", node.Using) + } +} + +func (node JoinCondition) walkSubtree(visit Visit) error { + return Walk( + visit, + node.On, + node.Using, + ) +} + +// JoinTableExpr represents a TableExpr that's a JOIN operation. +type JoinTableExpr struct { + LeftExpr TableExpr + Join string + RightExpr TableExpr + Condition JoinCondition +} + +// JoinTableExpr.Join +const ( + JoinStr = "join" + StraightJoinStr = "straight_join" + LeftJoinStr = "left join" + RightJoinStr = "right join" + NaturalJoinStr = "natural join" + NaturalLeftJoinStr = "natural left join" + NaturalRightJoinStr = "natural right join" +) + +// Format formats the node. +func (node *JoinTableExpr) Format(buf *TrackedBuffer) { + buf.Myprintf("%v %s %v%v", node.LeftExpr, node.Join, node.RightExpr, node.Condition) +} + +func (node *JoinTableExpr) walkSubtree(visit Visit) error { + if node == nil { + return nil + } + return Walk( + visit, + node.LeftExpr, + node.RightExpr, + node.Condition, + ) +} + +// IndexHints represents a list of index hints. +type IndexHints struct { + Type string + Indexes []ColIdent +} + +// Index hints. +const ( + UseStr = "use " + IgnoreStr = "ignore " + ForceStr = "force " +) + +// Format formats the node. +func (node *IndexHints) Format(buf *TrackedBuffer) { + buf.Myprintf(" %sindex ", node.Type) + prefix := "(" + for _, n := range node.Indexes { + buf.Myprintf("%s%v", prefix, n) + prefix = ", " + } + buf.Myprintf(")") +} + +func (node *IndexHints) walkSubtree(visit Visit) error { + if node == nil { + return nil + } + for _, n := range node.Indexes { + if err := Walk(visit, n); err != nil { + return err + } + } + return nil +} + +// Where represents a WHERE or HAVING clause. +type Where struct { + Type string + Expr Expr +} + +// Where.Type +const ( + WhereStr = "where" + HavingStr = "having" +) + +// NewWhere creates a WHERE or HAVING clause out +// of a Expr. If the expression is nil, it returns nil. +func NewWhere(typ string, expr Expr) *Where { + if expr == nil { + return nil + } + return &Where{Type: typ, Expr: expr} +} + +// Format formats the node. +func (node *Where) Format(buf *TrackedBuffer) { + if node == nil || node.Expr == nil { + return + } + buf.Myprintf(" %s %v", node.Type, node.Expr) +} + +func (node *Where) walkSubtree(visit Visit) error { + if node == nil { + return nil + } + return Walk( + visit, + node.Expr, + ) +} + +// Expr represents an expression. +type Expr interface { + iExpr() + // replace replaces any subexpression that matches + // from with to. The implementation can use the + // replaceExprs convenience function. + replace(from, to Expr) bool + SQLNode +} + +func (*AndExpr) iExpr() {} +func (*OrExpr) iExpr() {} +func (*NotExpr) iExpr() {} +func (*ParenExpr) iExpr() {} +func (*ComparisonExpr) iExpr() {} +func (*RangeCond) iExpr() {} +func (*IsExpr) iExpr() {} +func (*ExistsExpr) iExpr() {} +func (*SQLVal) iExpr() {} +func (*NullVal) iExpr() {} +func (BoolVal) iExpr() {} +func (*ColName) iExpr() {} +func (ValTuple) iExpr() {} +func (*Subquery) iExpr() {} +func (ListArg) iExpr() {} +func (*BinaryExpr) iExpr() {} +func (*UnaryExpr) iExpr() {} +func (*IntervalExpr) iExpr() {} +func (*CollateExpr) iExpr() {} +func (*FuncExpr) iExpr() {} +func (*CaseExpr) iExpr() {} +func (*ValuesFuncExpr) iExpr() {} +func (*ConvertExpr) iExpr() {} +func (*SubstrExpr) iExpr() {} +func (*ConvertUsingExpr) iExpr() {} +func (*MatchExpr) iExpr() {} +func (*GroupConcatExpr) iExpr() {} +func (*Default) iExpr() {} + +// ReplaceExpr finds the from expression from root +// and replaces it with to. If from matches root, +// then to is returned. +func ReplaceExpr(root, from, to Expr) Expr { + if root == from { + return to + } + root.replace(from, to) + return root +} + +// replaceExprs is a convenience function used by implementors +// of the replace method. +func replaceExprs(from, to Expr, exprs ...*Expr) bool { + for _, expr := range exprs { + if *expr == nil { + continue + } + if *expr == from { + *expr = to + return true + } + if (*expr).replace(from, to) { + return true + } + } + return false +} + +// Exprs represents a list of value expressions. +// It's not a valid expression because it's not parenthesized. +type Exprs []Expr + +// Format formats the node. +func (node Exprs) Format(buf *TrackedBuffer) { + var prefix string + for _, n := range node { + buf.Myprintf("%s%v", prefix, n) + prefix = ", " + } +} + +func (node Exprs) walkSubtree(visit Visit) error { + for _, n := range node { + if err := Walk(visit, n); err != nil { + return err + } + } + return nil +} + +// AndExpr represents an AND expression. +type AndExpr struct { + Left, Right Expr +} + +// Format formats the node. +func (node *AndExpr) Format(buf *TrackedBuffer) { + buf.Myprintf("%v and %v", node.Left, node.Right) +} + +func (node *AndExpr) walkSubtree(visit Visit) error { + if node == nil { + return nil + } + return Walk( + visit, + node.Left, + node.Right, + ) +} + +func (node *AndExpr) replace(from, to Expr) bool { + return replaceExprs(from, to, &node.Left, &node.Right) +} + +// OrExpr represents an OR expression. +type OrExpr struct { + Left, Right Expr +} + +// Format formats the node. +func (node *OrExpr) Format(buf *TrackedBuffer) { + buf.Myprintf("%v or %v", node.Left, node.Right) +} + +func (node *OrExpr) walkSubtree(visit Visit) error { + if node == nil { + return nil + } + return Walk( + visit, + node.Left, + node.Right, + ) +} + +func (node *OrExpr) replace(from, to Expr) bool { + return replaceExprs(from, to, &node.Left, &node.Right) +} + +// NotExpr represents a NOT expression. +type NotExpr struct { + Expr Expr +} + +// Format formats the node. +func (node *NotExpr) Format(buf *TrackedBuffer) { + buf.Myprintf("not %v", node.Expr) +} + +func (node *NotExpr) walkSubtree(visit Visit) error { + if node == nil { + return nil + } + return Walk( + visit, + node.Expr, + ) +} + +func (node *NotExpr) replace(from, to Expr) bool { + return replaceExprs(from, to, &node.Expr) +} + +// ParenExpr represents a parenthesized boolean expression. +type ParenExpr struct { + Expr Expr +} + +// Format formats the node. +func (node *ParenExpr) Format(buf *TrackedBuffer) { + buf.Myprintf("(%v)", node.Expr) +} + +func (node *ParenExpr) walkSubtree(visit Visit) error { + if node == nil { + return nil + } + return Walk( + visit, + node.Expr, + ) +} + +func (node *ParenExpr) replace(from, to Expr) bool { + return replaceExprs(from, to, &node.Expr) +} + +// ComparisonExpr represents a two-value comparison expression. +type ComparisonExpr struct { + Operator string + Left, Right Expr + Escape Expr +} + +// ComparisonExpr.Operator +const ( + EqualStr = "=" + LessThanStr = "<" + GreaterThanStr = ">" + LessEqualStr = "<=" + GreaterEqualStr = ">=" + NotEqualStr = "!=" + NullSafeEqualStr = "<=>" + InStr = "in" + NotInStr = "not in" + LikeStr = "like" + NotLikeStr = "not like" + RegexpStr = "regexp" + NotRegexpStr = "not regexp" + JSONExtractOp = "->" + JSONUnquoteExtractOp = "->>" +) + +// Format formats the node. +func (node *ComparisonExpr) Format(buf *TrackedBuffer) { + buf.Myprintf("%v %s %v", node.Left, node.Operator, node.Right) + if node.Escape != nil { + buf.Myprintf(" escape %v", node.Escape) + } +} + +func (node *ComparisonExpr) walkSubtree(visit Visit) error { + if node == nil { + return nil + } + return Walk( + visit, + node.Left, + node.Right, + node.Escape, + ) +} + +func (node *ComparisonExpr) replace(from, to Expr) bool { + return replaceExprs(from, to, &node.Left, &node.Right, &node.Escape) +} + +// RangeCond represents a BETWEEN or a NOT BETWEEN expression. +type RangeCond struct { + Operator string + Left Expr + From, To Expr +} + +// RangeCond.Operator +const ( + BetweenStr = "between" + NotBetweenStr = "not between" +) + +// Format formats the node. +func (node *RangeCond) Format(buf *TrackedBuffer) { + buf.Myprintf("%v %s %v and %v", node.Left, node.Operator, node.From, node.To) +} + +func (node *RangeCond) walkSubtree(visit Visit) error { + if node == nil { + return nil + } + return Walk( + visit, + node.Left, + node.From, + node.To, + ) +} + +func (node *RangeCond) replace(from, to Expr) bool { + return replaceExprs(from, to, &node.Left, &node.From, &node.To) +} + +// IsExpr represents an IS ... or an IS NOT ... expression. +type IsExpr struct { + Operator string + Expr Expr +} + +// IsExpr.Operator +const ( + IsNullStr = "is null" + IsNotNullStr = "is not null" + IsTrueStr = "is true" + IsNotTrueStr = "is not true" + IsFalseStr = "is false" + IsNotFalseStr = "is not false" +) + +// Format formats the node. +func (node *IsExpr) Format(buf *TrackedBuffer) { + buf.Myprintf("%v %s", node.Expr, node.Operator) +} + +func (node *IsExpr) walkSubtree(visit Visit) error { + if node == nil { + return nil + } + return Walk( + visit, + node.Expr, + ) +} + +func (node *IsExpr) replace(from, to Expr) bool { + return replaceExprs(from, to, &node.Expr) +} + +// ExistsExpr represents an EXISTS expression. +type ExistsExpr struct { + Subquery *Subquery +} + +// Format formats the node. +func (node *ExistsExpr) Format(buf *TrackedBuffer) { + buf.Myprintf("exists %v", node.Subquery) +} + +func (node *ExistsExpr) walkSubtree(visit Visit) error { + if node == nil { + return nil + } + return Walk( + visit, + node.Subquery, + ) +} + +func (node *ExistsExpr) replace(from, to Expr) bool { + return false +} + +// ExprFromValue converts the given Value into an Expr or returns an error. +func ExprFromValue(value sqltypes.Value) (Expr, error) { + // The type checks here follow the rules defined in sqltypes/types.go. + switch { + case value.Type() == sqltypes.Null: + return &NullVal{}, nil + case value.IsIntegral(): + return NewIntVal(value.ToBytes()), nil + case value.IsFloat() || value.Type() == sqltypes.Decimal: + return NewFloatVal(value.ToBytes()), nil + case value.IsQuoted(): + return NewStrVal(value.ToBytes()), nil + default: + // We cannot support sqltypes.Expression, or any other invalid type. + return nil, fmt.Errorf("cannot convert value %v to AST", value) + } +} + +// ValType specifies the type for SQLVal. +type ValType int + +// These are the possible Valtype values. +// HexNum represents a 0x... value. It cannot +// be treated as a simple value because it can +// be interpreted differently depending on the +// context. +const ( + StrVal = ValType(iota) + IntVal + FloatVal + HexNum + HexVal + ValArg + BitVal +) + +// SQLVal represents a single value. +type SQLVal struct { + Type ValType + Val []byte +} + +// NewStrVal builds a new StrVal. +func NewStrVal(in []byte) *SQLVal { + return &SQLVal{Type: StrVal, Val: in} +} + +// NewIntVal builds a new IntVal. +func NewIntVal(in []byte) *SQLVal { + return &SQLVal{Type: IntVal, Val: in} +} + +// NewFloatVal builds a new FloatVal. +func NewFloatVal(in []byte) *SQLVal { + return &SQLVal{Type: FloatVal, Val: in} +} + +// NewHexNum builds a new HexNum. +func NewHexNum(in []byte) *SQLVal { + return &SQLVal{Type: HexNum, Val: in} +} + +// NewHexVal builds a new HexVal. +func NewHexVal(in []byte) *SQLVal { + return &SQLVal{Type: HexVal, Val: in} +} + +// NewBitVal builds a new BitVal containing a bit literal. +func NewBitVal(in []byte) *SQLVal { + return &SQLVal{Type: BitVal, Val: in} +} + +// NewValArg builds a new ValArg. +func NewValArg(in []byte) *SQLVal { + return &SQLVal{Type: ValArg, Val: in} +} + +// Format formats the node. +func (node *SQLVal) Format(buf *TrackedBuffer) { + switch node.Type { + case StrVal: + sqltypes.MakeTrusted(sqltypes.VarBinary, node.Val).EncodeSQL(buf) + case IntVal, FloatVal, HexNum: + buf.Myprintf("%s", []byte(node.Val)) + case HexVal: + buf.Myprintf("X'%s'", []byte(node.Val)) + case BitVal: + buf.Myprintf("B'%s'", []byte(node.Val)) + case ValArg: + buf.WriteArg(string(node.Val)) + default: + panic("unexpected") + } +} + +func (node *SQLVal) walkSubtree(visit Visit) error { + return nil +} + +func (node *SQLVal) replace(from, to Expr) bool { + return false +} + +// HexDecode decodes the hexval into bytes. +func (node *SQLVal) HexDecode() ([]byte, error) { + dst := make([]byte, hex.DecodedLen(len([]byte(node.Val)))) + _, err := hex.Decode(dst, []byte(node.Val)) + if err != nil { + return nil, err + } + return dst, err +} + +// NullVal represents a NULL value. +type NullVal struct{} + +// Format formats the node. +func (node *NullVal) Format(buf *TrackedBuffer) { + buf.Myprintf("null") +} + +func (node *NullVal) walkSubtree(visit Visit) error { + return nil +} + +func (node *NullVal) replace(from, to Expr) bool { + return false +} + +// BoolVal is true or false. +type BoolVal bool + +// Format formats the node. +func (node BoolVal) Format(buf *TrackedBuffer) { + if node { + buf.Myprintf("true") + } else { + buf.Myprintf("false") + } +} + +func (node BoolVal) walkSubtree(visit Visit) error { + return nil +} + +func (node BoolVal) replace(from, to Expr) bool { + return false +} + +// ColName represents a column name. +type ColName struct { + // Metadata is not populated by the parser. + // It's a placeholder for analyzers to store + // additional data, typically info about which + // table or column this node references. + Metadata interface{} + Name ColIdent + Qualifier TableName +} + +// Format formats the node. +func (node *ColName) Format(buf *TrackedBuffer) { + if !node.Qualifier.IsEmpty() { + buf.Myprintf("%v.", node.Qualifier) + } + buf.Myprintf("%v", node.Name) +} + +func (node *ColName) walkSubtree(visit Visit) error { + if node == nil { + return nil + } + return Walk( + visit, + node.Name, + node.Qualifier, + ) +} + +func (node *ColName) replace(from, to Expr) bool { + return false +} + +// Equal returns true if the column names match. +func (node *ColName) Equal(c *ColName) bool { + // Failsafe: ColName should not be empty. + if node == nil || c == nil { + return false + } + return node.Name.Equal(c.Name) && node.Qualifier == c.Qualifier +} + +// ColTuple represents a list of column values. +// It can be ValTuple, Subquery, ListArg. +type ColTuple interface { + iColTuple() + Expr +} + +func (ValTuple) iColTuple() {} +func (*Subquery) iColTuple() {} +func (ListArg) iColTuple() {} + +// ValTuple represents a tuple of actual values. +type ValTuple Exprs + +// Format formats the node. +func (node ValTuple) Format(buf *TrackedBuffer) { + buf.Myprintf("(%v)", Exprs(node)) +} + +func (node ValTuple) walkSubtree(visit Visit) error { + return Walk(visit, Exprs(node)) +} + +func (node ValTuple) replace(from, to Expr) bool { + for i := range node { + if replaceExprs(from, to, &node[i]) { + return true + } + } + return false +} + +// Subquery represents a subquery. +type Subquery struct { + Select SelectStatement +} + +// Format formats the node. +func (node *Subquery) Format(buf *TrackedBuffer) { + buf.Myprintf("(%v)", node.Select) +} + +func (node *Subquery) walkSubtree(visit Visit) error { + if node == nil { + return nil + } + return Walk( + visit, + node.Select, + ) +} + +func (node *Subquery) replace(from, to Expr) bool { + return false +} + +// ListArg represents a named list argument. +type ListArg []byte + +// Format formats the node. +func (node ListArg) Format(buf *TrackedBuffer) { + buf.WriteArg(string(node)) +} + +func (node ListArg) walkSubtree(visit Visit) error { + return nil +} + +func (node ListArg) replace(from, to Expr) bool { + return false +} + +// BinaryExpr represents a binary value expression. +type BinaryExpr struct { + Operator string + Left, Right Expr +} + +// BinaryExpr.Operator +const ( + BitAndStr = "&" + BitOrStr = "|" + BitXorStr = "^" + PlusStr = "+" + MinusStr = "-" + MultStr = "*" + DivStr = "/" + IntDivStr = "div" + ModStr = "%" + ShiftLeftStr = "<<" + ShiftRightStr = ">>" +) + +// Format formats the node. +func (node *BinaryExpr) Format(buf *TrackedBuffer) { + buf.Myprintf("%v %s %v", node.Left, node.Operator, node.Right) +} + +func (node *BinaryExpr) walkSubtree(visit Visit) error { + if node == nil { + return nil + } + return Walk( + visit, + node.Left, + node.Right, + ) +} + +func (node *BinaryExpr) replace(from, to Expr) bool { + return replaceExprs(from, to, &node.Left, &node.Right) +} + +// UnaryExpr represents a unary value expression. +type UnaryExpr struct { + Operator string + Expr Expr +} + +// UnaryExpr.Operator +const ( + UPlusStr = "+" + UMinusStr = "-" + TildaStr = "~" + BangStr = "!" + BinaryStr = "binary " + UBinaryStr = "_binary " +) + +// Format formats the node. +func (node *UnaryExpr) Format(buf *TrackedBuffer) { + if _, unary := node.Expr.(*UnaryExpr); unary { + buf.Myprintf("%s %v", node.Operator, node.Expr) + return + } + buf.Myprintf("%s%v", node.Operator, node.Expr) +} + +func (node *UnaryExpr) walkSubtree(visit Visit) error { + if node == nil { + return nil + } + return Walk( + visit, + node.Expr, + ) +} + +func (node *UnaryExpr) replace(from, to Expr) bool { + return replaceExprs(from, to, &node.Expr) +} + +// IntervalExpr represents a date-time INTERVAL expression. +type IntervalExpr struct { + Expr Expr + Unit string +} + +// Format formats the node. +func (node *IntervalExpr) Format(buf *TrackedBuffer) { + buf.Myprintf("interval %v %s", node.Expr, node.Unit) +} + +func (node *IntervalExpr) walkSubtree(visit Visit) error { + if node == nil { + return nil + } + return Walk( + visit, + node.Expr, + ) +} + +func (node *IntervalExpr) replace(from, to Expr) bool { + return replaceExprs(from, to, &node.Expr) +} + +// CollateExpr represents dynamic collate operator. +type CollateExpr struct { + Expr Expr + Charset string +} + +// Format formats the node. +func (node *CollateExpr) Format(buf *TrackedBuffer) { + buf.Myprintf("%v collate %s", node.Expr, node.Charset) +} + +func (node *CollateExpr) walkSubtree(visit Visit) error { + if node == nil { + return nil + } + return Walk( + visit, + node.Expr, + ) +} + +func (node *CollateExpr) replace(from, to Expr) bool { + return replaceExprs(from, to, &node.Expr) +} + +// FuncExpr represents a function call. +type FuncExpr struct { + Qualifier TableIdent + Name ColIdent + Distinct bool + Exprs SelectExprs +} + +// Format formats the node. +func (node *FuncExpr) Format(buf *TrackedBuffer) { + var distinct string + if node.Distinct { + distinct = "distinct " + } + if !node.Qualifier.IsEmpty() { + buf.Myprintf("%v.", node.Qualifier) + } + // Function names should not be back-quoted even + // if they match a reserved word. So, print the + // name as is. + buf.Myprintf("%s(%s%v)", node.Name.String(), distinct, node.Exprs) +} + +func (node *FuncExpr) walkSubtree(visit Visit) error { + if node == nil { + return nil + } + return Walk( + visit, + node.Qualifier, + node.Name, + node.Exprs, + ) +} + +func (node *FuncExpr) replace(from, to Expr) bool { + for _, sel := range node.Exprs { + aliased, ok := sel.(*AliasedExpr) + if !ok { + continue + } + if replaceExprs(from, to, &aliased.Expr) { + return true + } + } + return false +} + +// Aggregates is a map of all aggregate functions. +var Aggregates = map[string]bool{ + "avg": true, + "bit_and": true, + "bit_or": true, + "bit_xor": true, + "count": true, + "group_concat": true, + "max": true, + "min": true, + "std": true, + "stddev_pop": true, + "stddev_samp": true, + "stddev": true, + "sum": true, + "var_pop": true, + "var_samp": true, + "variance": true, +} + +// IsAggregate returns true if the function is an aggregate. +func (node *FuncExpr) IsAggregate() bool { + return Aggregates[node.Name.Lowered()] +} + +// GroupConcatExpr represents a call to GROUP_CONCAT +type GroupConcatExpr struct { + Distinct string + Exprs SelectExprs + OrderBy OrderBy + Separator string +} + +// Format formats the node +func (node *GroupConcatExpr) Format(buf *TrackedBuffer) { + buf.Myprintf("group_concat(%s%v%v%s)", node.Distinct, node.Exprs, node.OrderBy, node.Separator) +} + +func (node *GroupConcatExpr) walkSubtree(visit Visit) error { + if node == nil { + return nil + } + return Walk( + visit, + node.Exprs, + node.OrderBy, + ) +} + +func (node *GroupConcatExpr) replace(from, to Expr) bool { + for _, sel := range node.Exprs { + aliased, ok := sel.(*AliasedExpr) + if !ok { + continue + } + if replaceExprs(from, to, &aliased.Expr) { + return true + } + } + for _, order := range node.OrderBy { + if replaceExprs(from, to, &order.Expr) { + return true + } + } + return false +} + +// ValuesFuncExpr represents a function call. +type ValuesFuncExpr struct { + Name *ColName +} + +// Format formats the node. +func (node *ValuesFuncExpr) Format(buf *TrackedBuffer) { + buf.Myprintf("values(%v)", node.Name) +} + +func (node *ValuesFuncExpr) walkSubtree(visit Visit) error { + if node == nil { + return nil + } + return Walk( + visit, + node.Name, + ) +} + +func (node *ValuesFuncExpr) replace(from, to Expr) bool { + return false +} + +// SubstrExpr represents a call to SubstrExpr(column, value_expression) or SubstrExpr(column, value_expression,value_expression) +// also supported syntax SubstrExpr(column from value_expression for value_expression) +type SubstrExpr struct { + Name *ColName + From Expr + To Expr +} + +// Format formats the node. +func (node *SubstrExpr) Format(buf *TrackedBuffer) { + + if node.To == nil { + buf.Myprintf("substr(%v, %v)", node.Name, node.From) + } else { + buf.Myprintf("substr(%v, %v, %v)", node.Name, node.From, node.To) + } +} + +func (node *SubstrExpr) replace(from, to Expr) bool { + return replaceExprs(from, to, &node.From, &node.To) +} + +func (node *SubstrExpr) walkSubtree(visit Visit) error { + if node == nil { + return nil + } + return Walk( + visit, + node.Name, + node.From, + node.To, + ) +} + +// ConvertExpr represents a call to CONVERT(expr, type) +// or it's equivalent CAST(expr AS type). Both are rewritten to the former. +type ConvertExpr struct { + Expr Expr + Type *ConvertType +} + +// Format formats the node. +func (node *ConvertExpr) Format(buf *TrackedBuffer) { + buf.Myprintf("convert(%v, %v)", node.Expr, node.Type) +} + +func (node *ConvertExpr) walkSubtree(visit Visit) error { + if node == nil { + return nil + } + return Walk( + visit, + node.Expr, + node.Type, + ) +} + +func (node *ConvertExpr) replace(from, to Expr) bool { + return replaceExprs(from, to, &node.Expr) +} + +// ConvertUsingExpr represents a call to CONVERT(expr USING charset). +type ConvertUsingExpr struct { + Expr Expr + Type string +} + +// Format formats the node. +func (node *ConvertUsingExpr) Format(buf *TrackedBuffer) { + buf.Myprintf("convert(%v using %s)", node.Expr, node.Type) +} + +func (node *ConvertUsingExpr) walkSubtree(visit Visit) error { + if node == nil { + return nil + } + return Walk( + visit, + node.Expr, + ) +} + +func (node *ConvertUsingExpr) replace(from, to Expr) bool { + return replaceExprs(from, to, &node.Expr) +} + +// ConvertType represents the type in call to CONVERT(expr, type) +type ConvertType struct { + Type string + Length *SQLVal + Scale *SQLVal + Operator string + Charset string +} + +// this string is "character set" and this comment is required +const ( + CharacterSetStr = " character set" +) + +// Format formats the node. +func (node *ConvertType) Format(buf *TrackedBuffer) { + buf.Myprintf("%s", node.Type) + if node.Length != nil { + buf.Myprintf("(%v", node.Length) + if node.Scale != nil { + buf.Myprintf(", %v", node.Scale) + } + buf.Myprintf(")") + } + if node.Charset != "" { + buf.Myprintf("%s %s", node.Operator, node.Charset) + } +} + +func (node *ConvertType) walkSubtree(visit Visit) error { + return nil +} + +// MatchExpr represents a call to the MATCH function +type MatchExpr struct { + Columns SelectExprs + Expr Expr + Option string +} + +// MatchExpr.Option +const ( + BooleanModeStr = " in boolean mode" + NaturalLanguageModeStr = " in natural language mode" + NaturalLanguageModeWithQueryExpansionStr = " in natural language mode with query expansion" + QueryExpansionStr = " with query expansion" +) + +// Format formats the node +func (node *MatchExpr) Format(buf *TrackedBuffer) { + buf.Myprintf("match(%v) against (%v%s)", node.Columns, node.Expr, node.Option) +} + +func (node *MatchExpr) walkSubtree(visit Visit) error { + if node == nil { + return nil + } + return Walk( + visit, + node.Columns, + node.Expr, + ) +} + +func (node *MatchExpr) replace(from, to Expr) bool { + for _, sel := range node.Columns { + aliased, ok := sel.(*AliasedExpr) + if !ok { + continue + } + if replaceExprs(from, to, &aliased.Expr) { + return true + } + } + return replaceExprs(from, to, &node.Expr) +} + +// CaseExpr represents a CASE expression. +type CaseExpr struct { + Expr Expr + Whens []*When + Else Expr +} + +// Format formats the node. +func (node *CaseExpr) Format(buf *TrackedBuffer) { + buf.Myprintf("case ") + if node.Expr != nil { + buf.Myprintf("%v ", node.Expr) + } + for _, when := range node.Whens { + buf.Myprintf("%v ", when) + } + if node.Else != nil { + buf.Myprintf("else %v ", node.Else) + } + buf.Myprintf("end") +} + +func (node *CaseExpr) walkSubtree(visit Visit) error { + if node == nil { + return nil + } + if err := Walk(visit, node.Expr); err != nil { + return err + } + for _, n := range node.Whens { + if err := Walk(visit, n); err != nil { + return err + } + } + return Walk(visit, node.Else) +} + +func (node *CaseExpr) replace(from, to Expr) bool { + for _, when := range node.Whens { + if replaceExprs(from, to, &when.Cond, &when.Val) { + return true + } + } + return replaceExprs(from, to, &node.Expr, &node.Else) +} + +// Default represents a DEFAULT expression. +type Default struct { + ColName string +} + +// Format formats the node. +func (node *Default) Format(buf *TrackedBuffer) { + buf.Myprintf("default") + if node.ColName != "" { + buf.Myprintf("(%s)", node.ColName) + } +} + +func (node *Default) walkSubtree(visit Visit) error { + return nil +} + +func (node *Default) replace(from, to Expr) bool { + return false +} + +// When represents a WHEN sub-expression. +type When struct { + Cond Expr + Val Expr +} + +// Format formats the node. +func (node *When) Format(buf *TrackedBuffer) { + buf.Myprintf("when %v then %v", node.Cond, node.Val) +} + +func (node *When) walkSubtree(visit Visit) error { + if node == nil { + return nil + } + return Walk( + visit, + node.Cond, + node.Val, + ) +} + +// GroupBy represents a GROUP BY clause. +type GroupBy []Expr + +// Format formats the node. +func (node GroupBy) Format(buf *TrackedBuffer) { + prefix := " group by " + for _, n := range node { + buf.Myprintf("%s%v", prefix, n) + prefix = ", " + } +} + +func (node GroupBy) walkSubtree(visit Visit) error { + for _, n := range node { + if err := Walk(visit, n); err != nil { + return err + } + } + return nil +} + +// OrderBy represents an ORDER By clause. +type OrderBy []*Order + +// Format formats the node. +func (node OrderBy) Format(buf *TrackedBuffer) { + prefix := " order by " + for _, n := range node { + buf.Myprintf("%s%v", prefix, n) + prefix = ", " + } +} + +func (node OrderBy) walkSubtree(visit Visit) error { + for _, n := range node { + if err := Walk(visit, n); err != nil { + return err + } + } + return nil +} + +// Order represents an ordering expression. +type Order struct { + Expr Expr + Direction string +} + +// Order.Direction +const ( + AscScr = "asc" + DescScr = "desc" +) + +// Format formats the node. +func (node *Order) Format(buf *TrackedBuffer) { + if node, ok := node.Expr.(*NullVal); ok { + buf.Myprintf("%v", node) + return + } + if node, ok := node.Expr.(*FuncExpr); ok { + if node.Name.Lowered() == "rand" { + buf.Myprintf("%v", node) + return + } + } + + buf.Myprintf("%v %s", node.Expr, node.Direction) +} + +func (node *Order) walkSubtree(visit Visit) error { + if node == nil { + return nil + } + return Walk( + visit, + node.Expr, + ) +} + +// Limit represents a LIMIT clause. +type Limit struct { + Offset, Rowcount Expr +} + +// Format formats the node. +func (node *Limit) Format(buf *TrackedBuffer) { + if node == nil { + return + } + buf.Myprintf(" limit ") + if node.Offset != nil { + buf.Myprintf("%v, ", node.Offset) + } + buf.Myprintf("%v", node.Rowcount) +} + +func (node *Limit) walkSubtree(visit Visit) error { + if node == nil { + return nil + } + return Walk( + visit, + node.Offset, + node.Rowcount, + ) +} + +// Values represents a VALUES clause. +type Values []ValTuple + +// Format formats the node. +func (node Values) Format(buf *TrackedBuffer) { + prefix := "values " + for _, n := range node { + buf.Myprintf("%s%v", prefix, n) + prefix = ", " + } +} + +func (node Values) walkSubtree(visit Visit) error { + for _, n := range node { + if err := Walk(visit, n); err != nil { + return err + } + } + return nil +} + +// UpdateExprs represents a list of update expressions. +type UpdateExprs []*UpdateExpr + +// Format formats the node. +func (node UpdateExprs) Format(buf *TrackedBuffer) { + var prefix string + for _, n := range node { + buf.Myprintf("%s%v", prefix, n) + prefix = ", " + } +} + +func (node UpdateExprs) walkSubtree(visit Visit) error { + for _, n := range node { + if err := Walk(visit, n); err != nil { + return err + } + } + return nil +} + +// UpdateExpr represents an update expression. +type UpdateExpr struct { + Name *ColName + Expr Expr +} + +// Format formats the node. +func (node *UpdateExpr) Format(buf *TrackedBuffer) { + buf.Myprintf("%v = %v", node.Name, node.Expr) +} + +func (node *UpdateExpr) walkSubtree(visit Visit) error { + if node == nil { + return nil + } + return Walk( + visit, + node.Name, + node.Expr, + ) +} + +// SetExprs represents a list of set expressions. +type SetExprs []*SetExpr + +// Format formats the node. +func (node SetExprs) Format(buf *TrackedBuffer) { + var prefix string + for _, n := range node { + buf.Myprintf("%s%v", prefix, n) + prefix = ", " + } +} + +func (node SetExprs) walkSubtree(visit Visit) error { + for _, n := range node { + if err := Walk(visit, n); err != nil { + return err + } + } + return nil +} + +// SetExpr represents a set expression. +type SetExpr struct { + Name ColIdent + Expr Expr +} + +// Format formats the node. +func (node *SetExpr) Format(buf *TrackedBuffer) { + // We don't have to backtick set variable names. + if node.Name.EqualString("charset") || node.Name.EqualString("names") { + buf.Myprintf("%s %v", node.Name.String(), node.Expr) + } else { + buf.Myprintf("%s = %v", node.Name.String(), node.Expr) + } +} + +func (node *SetExpr) walkSubtree(visit Visit) error { + if node == nil { + return nil + } + return Walk( + visit, + node.Name, + node.Expr, + ) +} + +// OnDup represents an ON DUPLICATE KEY clause. +type OnDup UpdateExprs + +// Format formats the node. +func (node OnDup) Format(buf *TrackedBuffer) { + if node == nil { + return + } + buf.Myprintf(" on duplicate key update %v", UpdateExprs(node)) +} + +func (node OnDup) walkSubtree(visit Visit) error { + return Walk(visit, UpdateExprs(node)) +} + +// ColIdent is a case insensitive SQL identifier. It will be escaped with +// backquotes if necessary. +type ColIdent struct { + // This artifact prevents this struct from being compared + // with itself. It consumes no space as long as it's not the + // last field in the struct. + _ [0]struct{ _ []byte } + val, lowered string +} + +// NewColIdent makes a new ColIdent. +func NewColIdent(str string) ColIdent { + return ColIdent{ + val: str, + } +} + +// Format formats the node. +func (node ColIdent) Format(buf *TrackedBuffer) { + formatID(buf, node.val, node.Lowered()) +} + +func (node ColIdent) walkSubtree(visit Visit) error { + return nil +} + +// IsEmpty returns true if the name is empty. +func (node ColIdent) IsEmpty() bool { + return node.val == "" +} + +// String returns the unescaped column name. It must +// not be used for SQL generation. Use sqlparser.String +// instead. The Stringer conformance is for usage +// in templates. +func (node ColIdent) String() string { + return node.val +} + +// CompliantName returns a compliant id name +// that can be used for a bind var. +func (node ColIdent) CompliantName() string { + return compliantName(node.val) +} + +// Lowered returns a lower-cased column name. +// This function should generally be used only for optimizing +// comparisons. +func (node ColIdent) Lowered() string { + if node.val == "" { + return "" + } + if node.lowered == "" { + node.lowered = strings.ToLower(node.val) + } + return node.lowered +} + +// Equal performs a case-insensitive compare. +func (node ColIdent) Equal(in ColIdent) bool { + return node.Lowered() == in.Lowered() +} + +// EqualString performs a case-insensitive compare with str. +func (node ColIdent) EqualString(str string) bool { + return node.Lowered() == strings.ToLower(str) +} + +// MarshalJSON marshals into JSON. +func (node ColIdent) MarshalJSON() ([]byte, error) { + return json.Marshal(node.val) +} + +// UnmarshalJSON unmarshals from JSON. +func (node *ColIdent) UnmarshalJSON(b []byte) error { + var result string + err := json.Unmarshal(b, &result) + if err != nil { + return err + } + node.val = result + return nil +} + +// TableIdent is a case sensitive SQL identifier. It will be escaped with +// backquotes if necessary. +type TableIdent struct { + v string +} + +// NewTableIdent creates a new TableIdent. +func NewTableIdent(str string) TableIdent { + return TableIdent{v: str} +} + +// Format formats the node. +func (node TableIdent) Format(buf *TrackedBuffer) { + formatID(buf, node.v, strings.ToLower(node.v)) +} + +func (node TableIdent) walkSubtree(visit Visit) error { + return nil +} + +// IsEmpty returns true if TabIdent is empty. +func (node TableIdent) IsEmpty() bool { + return node.v == "" +} + +// String returns the unescaped table name. It must +// not be used for SQL generation. Use sqlparser.String +// instead. The Stringer conformance is for usage +// in templates. +func (node TableIdent) String() string { + return node.v +} + +// CompliantName returns a compliant id name +// that can be used for a bind var. +func (node TableIdent) CompliantName() string { + return compliantName(node.v) +} + +// MarshalJSON marshals into JSON. +func (node TableIdent) MarshalJSON() ([]byte, error) { + return json.Marshal(node.v) +} + +// UnmarshalJSON unmarshals from JSON. +func (node *TableIdent) UnmarshalJSON(b []byte) error { + var result string + err := json.Unmarshal(b, &result) + if err != nil { + return err + } + node.v = result + return nil +} + +// Backtick produces a backticked literal given an input string. +func Backtick(in string) string { + var buf bytes.Buffer + buf.WriteByte('`') + for _, c := range in { + buf.WriteRune(c) + if c == '`' { + buf.WriteByte('`') + } + } + buf.WriteByte('`') + return buf.String() +} + +func formatID(buf *TrackedBuffer, original, lowered string) { + isDbSystemVariable := false + if len(original) > 1 && original[:2] == "@@" { + isDbSystemVariable = true + } + + for i, c := range original { + if !isLetter(uint16(c)) && (!isDbSystemVariable || !isCarat(uint16(c))) { + if i == 0 || !isDigit(uint16(c)) { + goto mustEscape + } + } + } + if _, ok := keywords[lowered]; ok { + goto mustEscape + } + buf.Myprintf("%s", original) + return + +mustEscape: + buf.WriteByte('`') + for _, c := range original { + buf.WriteRune(c) + if c == '`' { + buf.WriteByte('`') + } + } + buf.WriteByte('`') +} + +func compliantName(in string) string { + var buf bytes.Buffer + for i, c := range in { + if !isLetter(uint16(c)) { + if i == 0 || !isDigit(uint16(c)) { + buf.WriteByte('_') + continue + } + } + buf.WriteRune(c) + } + return buf.String() +} diff --git a/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/ast_test.go b/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/ast_test.go new file mode 100644 index 00000000..c02d882e --- /dev/null +++ b/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/ast_test.go @@ -0,0 +1,636 @@ +/* +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 sqlparser + +import ( + "bytes" + "encoding/json" + "reflect" + "strings" + "testing" + "unsafe" + + "github.com/xwb1989/sqlparser/dependency/sqltypes" +) + +func TestAppend(t *testing.T) { + query := "select * from t where a = 1" + tree, err := Parse(query) + if err != nil { + t.Error(err) + } + var b bytes.Buffer + Append(&b, tree) + got := b.String() + want := query + if got != want { + t.Errorf("Append: %s, want %s", got, want) + } + Append(&b, tree) + got = b.String() + want = query + query + if got != want { + t.Errorf("Append: %s, want %s", got, want) + } +} + +func TestSelect(t *testing.T) { + tree, err := Parse("select * from t where a = 1") + if err != nil { + t.Error(err) + } + expr := tree.(*Select).Where.Expr + + sel := &Select{} + sel.AddWhere(expr) + buf := NewTrackedBuffer(nil) + sel.Where.Format(buf) + want := " where a = 1" + if buf.String() != want { + t.Errorf("where: %q, want %s", buf.String(), want) + } + sel.AddWhere(expr) + buf = NewTrackedBuffer(nil) + sel.Where.Format(buf) + want = " where a = 1 and a = 1" + if buf.String() != want { + t.Errorf("where: %q, want %s", buf.String(), want) + } + sel = &Select{} + sel.AddHaving(expr) + buf = NewTrackedBuffer(nil) + sel.Having.Format(buf) + want = " having a = 1" + if buf.String() != want { + t.Errorf("having: %q, want %s", buf.String(), want) + } + sel.AddHaving(expr) + buf = NewTrackedBuffer(nil) + sel.Having.Format(buf) + want = " having a = 1 and a = 1" + if buf.String() != want { + t.Errorf("having: %q, want %s", buf.String(), want) + } + + // OR clauses must be parenthesized. + tree, err = Parse("select * from t where a = 1 or b = 1") + if err != nil { + t.Error(err) + } + expr = tree.(*Select).Where.Expr + sel = &Select{} + sel.AddWhere(expr) + buf = NewTrackedBuffer(nil) + sel.Where.Format(buf) + want = " where (a = 1 or b = 1)" + if buf.String() != want { + t.Errorf("where: %q, want %s", buf.String(), want) + } + sel = &Select{} + sel.AddHaving(expr) + buf = NewTrackedBuffer(nil) + sel.Having.Format(buf) + want = " having (a = 1 or b = 1)" + if buf.String() != want { + t.Errorf("having: %q, want %s", buf.String(), want) + } +} + +func TestRemoveHints(t *testing.T) { + for _, query := range []string{ + "select * from t use index (i)", + "select * from t force index (i)", + } { + tree, err := Parse(query) + if err != nil { + t.Fatal(err) + } + sel := tree.(*Select) + sel.From = TableExprs{ + sel.From[0].(*AliasedTableExpr).RemoveHints(), + } + buf := NewTrackedBuffer(nil) + sel.Format(buf) + if got, want := buf.String(), "select * from t"; got != want { + t.Errorf("stripped query: %s, want %s", got, want) + } + } +} + +func TestAddOrder(t *testing.T) { + src, err := Parse("select foo, bar from baz order by foo") + if err != nil { + t.Error(err) + } + order := src.(*Select).OrderBy[0] + dst, err := Parse("select * from t") + if err != nil { + t.Error(err) + } + dst.(*Select).AddOrder(order) + buf := NewTrackedBuffer(nil) + dst.Format(buf) + want := "select * from t order by foo asc" + if buf.String() != want { + t.Errorf("order: %q, want %s", buf.String(), want) + } + dst, err = Parse("select * from t union select * from s") + if err != nil { + t.Error(err) + } + dst.(*Union).AddOrder(order) + buf = NewTrackedBuffer(nil) + dst.Format(buf) + want = "select * from t union select * from s order by foo asc" + if buf.String() != want { + t.Errorf("order: %q, want %s", buf.String(), want) + } +} + +func TestSetLimit(t *testing.T) { + src, err := Parse("select foo, bar from baz limit 4") + if err != nil { + t.Error(err) + } + limit := src.(*Select).Limit + dst, err := Parse("select * from t") + if err != nil { + t.Error(err) + } + dst.(*Select).SetLimit(limit) + buf := NewTrackedBuffer(nil) + dst.Format(buf) + want := "select * from t limit 4" + if buf.String() != want { + t.Errorf("limit: %q, want %s", buf.String(), want) + } + dst, err = Parse("select * from t union select * from s") + if err != nil { + t.Error(err) + } + dst.(*Union).SetLimit(limit) + buf = NewTrackedBuffer(nil) + dst.Format(buf) + want = "select * from t union select * from s limit 4" + if buf.String() != want { + t.Errorf("order: %q, want %s", buf.String(), want) + } +} + +func TestWhere(t *testing.T) { + var w *Where + buf := NewTrackedBuffer(nil) + w.Format(buf) + if buf.String() != "" { + t.Errorf("w.Format(nil): %q, want \"\"", buf.String()) + } + w = NewWhere(WhereStr, nil) + buf = NewTrackedBuffer(nil) + w.Format(buf) + if buf.String() != "" { + t.Errorf("w.Format(&Where{nil}: %q, want \"\"", buf.String()) + } +} + +func TestIsAggregate(t *testing.T) { + f := FuncExpr{Name: NewColIdent("avg")} + if !f.IsAggregate() { + t.Error("IsAggregate: false, want true") + } + + f = FuncExpr{Name: NewColIdent("Avg")} + if !f.IsAggregate() { + t.Error("IsAggregate: false, want true") + } + + f = FuncExpr{Name: NewColIdent("foo")} + if f.IsAggregate() { + t.Error("IsAggregate: true, want false") + } +} + +func TestReplaceExpr(t *testing.T) { + tcases := []struct { + in, out string + }{{ + in: "select * from t where (select a from b)", + out: ":a", + }, { + in: "select * from t where (select a from b) and b", + out: ":a and b", + }, { + in: "select * from t where a and (select a from b)", + out: "a and :a", + }, { + in: "select * from t where (select a from b) or b", + out: ":a or b", + }, { + in: "select * from t where a or (select a from b)", + out: "a or :a", + }, { + in: "select * from t where not (select a from b)", + out: "not :a", + }, { + in: "select * from t where ((select a from b))", + out: "(:a)", + }, { + in: "select * from t where (select a from b) = 1", + out: ":a = 1", + }, { + in: "select * from t where a = (select a from b)", + out: "a = :a", + }, { + in: "select * from t where a like b escape (select a from b)", + out: "a like b escape :a", + }, { + in: "select * from t where (select a from b) between a and b", + out: ":a between a and b", + }, { + in: "select * from t where a between (select a from b) and b", + out: "a between :a and b", + }, { + in: "select * from t where a between b and (select a from b)", + out: "a between b and :a", + }, { + in: "select * from t where (select a from b) is null", + out: ":a is null", + }, { + // exists should not replace. + in: "select * from t where exists (select a from b)", + out: "exists (select a from b)", + }, { + in: "select * from t where a in ((select a from b), 1)", + out: "a in (:a, 1)", + }, { + in: "select * from t where a in (0, (select a from b), 1)", + out: "a in (0, :a, 1)", + }, { + in: "select * from t where (select a from b) + 1", + out: ":a + 1", + }, { + in: "select * from t where 1+(select a from b)", + out: "1 + :a", + }, { + in: "select * from t where -(select a from b)", + out: "-:a", + }, { + in: "select * from t where interval (select a from b) aa", + out: "interval :a aa", + }, { + in: "select * from t where (select a from b) collate utf8", + out: ":a collate utf8", + }, { + in: "select * from t where func((select a from b), 1)", + out: "func(:a, 1)", + }, { + in: "select * from t where func(1, (select a from b), 1)", + out: "func(1, :a, 1)", + }, { + in: "select * from t where group_concat((select a from b), 1 order by a)", + out: "group_concat(:a, 1 order by a asc)", + }, { + in: "select * from t where group_concat(1 order by (select a from b), a)", + out: "group_concat(1 order by :a asc, a asc)", + }, { + in: "select * from t where group_concat(1 order by a, (select a from b))", + out: "group_concat(1 order by a asc, :a asc)", + }, { + in: "select * from t where substr(a, (select a from b), b)", + out: "substr(a, :a, b)", + }, { + in: "select * from t where substr(a, b, (select a from b))", + out: "substr(a, b, :a)", + }, { + in: "select * from t where convert((select a from b), json)", + out: "convert(:a, json)", + }, { + in: "select * from t where convert((select a from b) using utf8)", + out: "convert(:a using utf8)", + }, { + in: "select * from t where match((select a from b), 1) against (a)", + out: "match(:a, 1) against (a)", + }, { + in: "select * from t where match(1, (select a from b), 1) against (a)", + out: "match(1, :a, 1) against (a)", + }, { + in: "select * from t where match(1, a, 1) against ((select a from b))", + out: "match(1, a, 1) against (:a)", + }, { + in: "select * from t where case (select a from b) when a then b when b then c else d end", + out: "case :a when a then b when b then c else d end", + }, { + in: "select * from t where case a when (select a from b) then b when b then c else d end", + out: "case a when :a then b when b then c else d end", + }, { + in: "select * from t where case a when b then (select a from b) when b then c else d end", + out: "case a when b then :a when b then c else d end", + }, { + in: "select * from t where case a when b then c when (select a from b) then c else d end", + out: "case a when b then c when :a then c else d end", + }, { + in: "select * from t where case a when b then c when d then c else (select a from b) end", + out: "case a when b then c when d then c else :a end", + }} + to := NewValArg([]byte(":a")) + for _, tcase := range tcases { + tree, err := Parse(tcase.in) + if err != nil { + t.Fatal(err) + } + var from *Subquery + _ = Walk(func(node SQLNode) (kontinue bool, err error) { + if sq, ok := node.(*Subquery); ok { + from = sq + return false, nil + } + return true, nil + }, tree) + if from == nil { + t.Fatalf("from is nil for %s", tcase.in) + } + expr := ReplaceExpr(tree.(*Select).Where.Expr, from, to) + got := String(expr) + if tcase.out != got { + t.Errorf("ReplaceExpr(%s): %s, want %s", tcase.in, got, tcase.out) + } + } +} + +func TestExprFromValue(t *testing.T) { + tcases := []struct { + in sqltypes.Value + out SQLNode + err string + }{{ + in: sqltypes.NULL, + out: &NullVal{}, + }, { + in: sqltypes.NewInt64(1), + out: NewIntVal([]byte("1")), + }, { + in: sqltypes.NewFloat64(1.1), + out: NewFloatVal([]byte("1.1")), + }, { + in: sqltypes.MakeTrusted(sqltypes.Decimal, []byte("1.1")), + out: NewFloatVal([]byte("1.1")), + }, { + in: sqltypes.NewVarChar("aa"), + out: NewStrVal([]byte("aa")), + }, { + in: sqltypes.MakeTrusted(sqltypes.Expression, []byte("rand()")), + err: "cannot convert value EXPRESSION(rand()) to AST", + }} + for _, tcase := range tcases { + got, err := ExprFromValue(tcase.in) + if tcase.err != "" { + if err == nil || err.Error() != tcase.err { + t.Errorf("ExprFromValue(%v) err: %v, want %s", tcase.in, err, tcase.err) + } + continue + } + if err != nil { + t.Error(err) + } + if got, want := got, tcase.out; !reflect.DeepEqual(got, want) { + t.Errorf("ExprFromValue(%v): %v, want %s", tcase.in, got, want) + } + } +} + +func TestColNameEqual(t *testing.T) { + var c1, c2 *ColName + if c1.Equal(c2) { + t.Error("nil columns equal, want unequal") + } + c1 = &ColName{ + Name: NewColIdent("aa"), + } + c2 = &ColName{ + Name: NewColIdent("bb"), + } + if c1.Equal(c2) { + t.Error("columns equal, want unequal") + } + c2.Name = NewColIdent("aa") + if !c1.Equal(c2) { + t.Error("columns unequal, want equal") + } +} + +func TestColIdent(t *testing.T) { + str := NewColIdent("Ab") + if str.String() != "Ab" { + t.Errorf("String=%s, want Ab", str.String()) + } + if str.String() != "Ab" { + t.Errorf("Val=%s, want Ab", str.String()) + } + if str.Lowered() != "ab" { + t.Errorf("Val=%s, want ab", str.Lowered()) + } + if !str.Equal(NewColIdent("aB")) { + t.Error("str.Equal(NewColIdent(aB))=false, want true") + } + if !str.EqualString("ab") { + t.Error("str.EqualString(ab)=false, want true") + } + str = NewColIdent("") + if str.Lowered() != "" { + t.Errorf("Val=%s, want \"\"", str.Lowered()) + } +} + +func TestColIdentMarshal(t *testing.T) { + str := NewColIdent("Ab") + b, err := json.Marshal(str) + if err != nil { + t.Fatal(err) + } + got := string(b) + want := `"Ab"` + if got != want { + t.Errorf("json.Marshal()= %s, want %s", got, want) + } + var out ColIdent + if err := json.Unmarshal(b, &out); err != nil { + t.Errorf("Unmarshal err: %v, want nil", err) + } + if !reflect.DeepEqual(out, str) { + t.Errorf("Unmarshal: %v, want %v", out, str) + } +} + +func TestColIdentSize(t *testing.T) { + size := unsafe.Sizeof(NewColIdent("")) + want := 2 * unsafe.Sizeof("") + if size != want { + t.Errorf("Size of ColIdent: %d, want 32", want) + } +} + +func TestTableIdentMarshal(t *testing.T) { + str := NewTableIdent("Ab") + b, err := json.Marshal(str) + if err != nil { + t.Fatal(err) + } + got := string(b) + want := `"Ab"` + if got != want { + t.Errorf("json.Marshal()= %s, want %s", got, want) + } + var out TableIdent + if err := json.Unmarshal(b, &out); err != nil { + t.Errorf("Unmarshal err: %v, want nil", err) + } + if !reflect.DeepEqual(out, str) { + t.Errorf("Unmarshal: %v, want %v", out, str) + } +} + +func TestHexDecode(t *testing.T) { + testcase := []struct { + in, out string + }{{ + in: "313233", + out: "123", + }, { + in: "ag", + out: "encoding/hex: invalid byte: U+0067 'g'", + }, { + in: "777", + out: "encoding/hex: odd length hex string", + }} + for _, tc := range testcase { + out, err := newHexVal(tc.in).HexDecode() + if err != nil { + if err.Error() != tc.out { + t.Errorf("Decode(%q): %v, want %s", tc.in, err, tc.out) + } + continue + } + if !bytes.Equal(out, []byte(tc.out)) { + t.Errorf("Decode(%q): %s, want %s", tc.in, out, tc.out) + } + } +} + +func TestCompliantName(t *testing.T) { + testcases := []struct { + in, out string + }{{ + in: "aa", + out: "aa", + }, { + in: "1a", + out: "_a", + }, { + in: "a1", + out: "a1", + }, { + in: "a.b", + out: "a_b", + }, { + in: ".ab", + out: "_ab", + }} + for _, tc := range testcases { + out := NewColIdent(tc.in).CompliantName() + if out != tc.out { + t.Errorf("ColIdent(%s).CompliantNamt: %s, want %s", tc.in, out, tc.out) + } + out = NewTableIdent(tc.in).CompliantName() + if out != tc.out { + t.Errorf("TableIdent(%s).CompliantNamt: %s, want %s", tc.in, out, tc.out) + } + } +} + +func TestColumns_FindColumn(t *testing.T) { + cols := Columns{NewColIdent("a"), NewColIdent("c"), NewColIdent("b"), NewColIdent("0")} + + testcases := []struct { + in string + out int + }{{ + in: "a", + out: 0, + }, { + in: "b", + out: 2, + }, + { + in: "0", + out: 3, + }, + { + in: "f", + out: -1, + }} + + for _, tc := range testcases { + val := cols.FindColumn(NewColIdent(tc.in)) + if val != tc.out { + t.Errorf("FindColumn(%s): %d, want %d", tc.in, val, tc.out) + } + } +} + +func TestSplitStatementToPieces(t *testing.T) { + testcases := []struct { + input string + output string + }{{ + input: "select * from table", + }, { + input: "select * from table1; select * from table2;", + output: "select * from table1; select * from table2", + }, { + input: "select * from /* comment ; */ table;", + output: "select * from /* comment ; */ table", + }, { + input: "select * from table where semi = ';';", + output: "select * from table where semi = ';'", + }, { + input: "select * from table1;--comment;\nselect * from table2;", + output: "select * from table1;--comment;\nselect * from table2", + }, { + input: "CREATE TABLE `total_data` (`id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'id', " + + "`region` varchar(32) NOT NULL COMMENT 'region name, like zh; th; kepler'," + + "`data_size` bigint NOT NULL DEFAULT '0' COMMENT 'data size;'," + + "`createtime` datetime NOT NULL DEFAULT NOW() COMMENT 'create time;'," + + "`comment` varchar(100) NOT NULL DEFAULT '' COMMENT 'comment'," + + "PRIMARY KEY (`id`))", + }} + + for _, tcase := range testcases { + if tcase.output == "" { + tcase.output = tcase.input + } + + stmtPieces, err := SplitStatementToPieces(tcase.input) + if err != nil { + t.Errorf("input: %s, err: %v", tcase.input, err) + continue + } + + out := strings.Join(stmtPieces, ";") + if out != tcase.output { + t.Errorf("out: %s, want %s", out, tcase.output) + } + } +} diff --git a/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/comments.go b/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/comments.go new file mode 100644 index 00000000..a0f7f1b4 --- /dev/null +++ b/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/comments.go @@ -0,0 +1,293 @@ +/* +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 sqlparser + +import ( + "strconv" + "strings" + "unicode" +) + +const ( + // DirectiveMultiShardAutocommit is the query comment directive to allow + // single round trip autocommit with a multi-shard statement. + DirectiveMultiShardAutocommit = "MULTI_SHARD_AUTOCOMMIT" + // DirectiveSkipQueryPlanCache skips query plan cache when set. + DirectiveSkipQueryPlanCache = "SKIP_QUERY_PLAN_CACHE" + // DirectiveQueryTimeout sets a query timeout in vtgate. Only supported for SELECTS. + DirectiveQueryTimeout = "QUERY_TIMEOUT_MS" +) + +func isNonSpace(r rune) bool { + return !unicode.IsSpace(r) +} + +// leadingCommentEnd returns the first index after all leading comments, or +// 0 if there are no leading comments. +func leadingCommentEnd(text string) (end int) { + hasComment := false + pos := 0 + for pos < len(text) { + // Eat up any whitespace. Trailing whitespace will be considered part of + // the leading comments. + nextVisibleOffset := strings.IndexFunc(text[pos:], isNonSpace) + if nextVisibleOffset < 0 { + break + } + pos += nextVisibleOffset + remainingText := text[pos:] + + // Found visible characters. Look for '/*' at the beginning + // and '*/' somewhere after that. + if len(remainingText) < 4 || remainingText[:2] != "/*" { + break + } + commentLength := 4 + strings.Index(remainingText[2:], "*/") + if commentLength < 4 { + // Missing end comment :/ + break + } + + hasComment = true + pos += commentLength + } + + if hasComment { + return pos + } + return 0 +} + +// trailingCommentStart returns the first index of trailing comments. +// If there are no trailing comments, returns the length of the input string. +func trailingCommentStart(text string) (start int) { + hasComment := false + reducedLen := len(text) + for reducedLen > 0 { + // Eat up any whitespace. Leading whitespace will be considered part of + // the trailing comments. + nextReducedLen := strings.LastIndexFunc(text[:reducedLen], isNonSpace) + 1 + if nextReducedLen == 0 { + break + } + reducedLen = nextReducedLen + if reducedLen < 4 || text[reducedLen-2:reducedLen] != "*/" { + break + } + + // Find the beginning of the comment + startCommentPos := strings.LastIndex(text[:reducedLen-2], "/*") + if startCommentPos < 0 { + // Badly formatted sql :/ + break + } + + hasComment = true + reducedLen = startCommentPos + } + + if hasComment { + return reducedLen + } + return len(text) +} + +// MarginComments holds the leading and trailing comments that surround a query. +type MarginComments struct { + Leading string + Trailing string +} + +// SplitMarginComments pulls out any leading or trailing comments from a raw sql query. +// This function also trims leading (if there's a comment) and trailing whitespace. +func SplitMarginComments(sql string) (query string, comments MarginComments) { + trailingStart := trailingCommentStart(sql) + leadingEnd := leadingCommentEnd(sql[:trailingStart]) + comments = MarginComments{ + Leading: strings.TrimLeftFunc(sql[:leadingEnd], unicode.IsSpace), + Trailing: strings.TrimRightFunc(sql[trailingStart:], unicode.IsSpace), + } + return strings.TrimFunc(sql[leadingEnd:trailingStart], unicode.IsSpace), comments +} + +// StripLeadingComments trims the SQL string and removes any leading comments +func StripLeadingComments(sql string) string { + sql = strings.TrimFunc(sql, unicode.IsSpace) + + for hasCommentPrefix(sql) { + switch sql[0] { + case '/': + // Multi line comment + index := strings.Index(sql, "*/") + if index <= 1 { + return sql + } + // don't strip /*! ... */ or /*!50700 ... */ + if len(sql) > 2 && sql[2] == '!' { + return sql + } + sql = sql[index+2:] + case '-': + // Single line comment + index := strings.Index(sql, "\n") + if index == -1 { + return sql + } + sql = sql[index+1:] + } + + sql = strings.TrimFunc(sql, unicode.IsSpace) + } + + return sql +} + +func hasCommentPrefix(sql string) bool { + return len(sql) > 1 && ((sql[0] == '/' && sql[1] == '*') || (sql[0] == '-' && sql[1] == '-')) +} + +// ExtractMysqlComment extracts the version and SQL from a comment-only query +// such as /*!50708 sql here */ +func ExtractMysqlComment(sql string) (version string, innerSQL string) { + sql = sql[3 : len(sql)-2] + + digitCount := 0 + endOfVersionIndex := strings.IndexFunc(sql, func(c rune) bool { + digitCount++ + return !unicode.IsDigit(c) || digitCount == 6 + }) + version = sql[0:endOfVersionIndex] + innerSQL = strings.TrimFunc(sql[endOfVersionIndex:], unicode.IsSpace) + + return version, innerSQL +} + +const commentDirectivePreamble = "/*vt+" + +// CommentDirectives is the parsed representation for execution directives +// conveyed in query comments +type CommentDirectives map[string]interface{} + +// ExtractCommentDirectives parses the comment list for any execution directives +// of the form: +// +// /*vt+ OPTION_ONE=1 OPTION_TWO OPTION_THREE=abcd */ +// +// It returns the map of the directive values or nil if there aren't any. +func ExtractCommentDirectives(comments Comments) CommentDirectives { + if comments == nil { + return nil + } + + var vals map[string]interface{} + + for _, comment := range comments { + commentStr := string(comment) + if commentStr[0:5] != commentDirectivePreamble { + continue + } + + if vals == nil { + vals = make(map[string]interface{}) + } + + // Split on whitespace and ignore the first and last directive + // since they contain the comment start/end + directives := strings.Fields(commentStr) + for i := 1; i < len(directives)-1; i++ { + directive := directives[i] + sep := strings.IndexByte(directive, '=') + + // No value is equivalent to a true boolean + if sep == -1 { + vals[directive] = true + continue + } + + strVal := directive[sep+1:] + directive = directive[:sep] + + intVal, err := strconv.Atoi(strVal) + if err == nil { + vals[directive] = intVal + continue + } + + boolVal, err := strconv.ParseBool(strVal) + if err == nil { + vals[directive] = boolVal + continue + } + + vals[directive] = strVal + } + } + return vals +} + +// IsSet checks the directive map for the named directive and returns +// true if the directive is set and has a true/false or 0/1 value +func (d CommentDirectives) IsSet(key string) bool { + if d == nil { + return false + } + + val, ok := d[key] + if !ok { + return false + } + + boolVal, ok := val.(bool) + if ok { + return boolVal + } + + intVal, ok := val.(int) + if ok { + return intVal == 1 + } + return false +} + +// SkipQueryPlanCacheDirective returns true if skip query plan cache directive is set to true in query. +func SkipQueryPlanCacheDirective(stmt Statement) bool { + switch stmt := stmt.(type) { + case *Select: + directives := ExtractCommentDirectives(stmt.Comments) + if directives.IsSet(DirectiveSkipQueryPlanCache) { + return true + } + case *Insert: + directives := ExtractCommentDirectives(stmt.Comments) + if directives.IsSet(DirectiveSkipQueryPlanCache) { + return true + } + case *Update: + directives := ExtractCommentDirectives(stmt.Comments) + if directives.IsSet(DirectiveSkipQueryPlanCache) { + return true + } + case *Delete: + directives := ExtractCommentDirectives(stmt.Comments) + if directives.IsSet(DirectiveSkipQueryPlanCache) { + return true + } + default: + return false + } + return false +} diff --git a/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/comments_test.go b/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/comments_test.go new file mode 100644 index 00000000..430293bf --- /dev/null +++ b/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/comments_test.go @@ -0,0 +1,375 @@ +/* +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 sqlparser + +import ( + "reflect" + "testing" +) + +func TestSplitComments(t *testing.T) { + var testCases = []struct { + input, outSQL, outLeadingComments, outTrailingComments string + }{{ + input: "/", + outSQL: "/", + outLeadingComments: "", + outTrailingComments: "", + }, { + input: "*/", + outSQL: "*/", + outLeadingComments: "", + outTrailingComments: "", + }, { + input: "/*/", + outSQL: "/*/", + outLeadingComments: "", + outTrailingComments: "", + }, { + input: "a*/", + outSQL: "a*/", + outLeadingComments: "", + outTrailingComments: "", + }, { + input: "*a*/", + outSQL: "*a*/", + outLeadingComments: "", + outTrailingComments: "", + }, { + input: "**a*/", + outSQL: "**a*/", + outLeadingComments: "", + outTrailingComments: "", + }, { + input: "/*b**a*/", + outSQL: "", + outLeadingComments: "", + outTrailingComments: "/*b**a*/", + }, { + input: "/*a*/", + outSQL: "", + outLeadingComments: "", + outTrailingComments: "/*a*/", + }, { + input: "/**/", + outSQL: "", + outLeadingComments: "", + outTrailingComments: "/**/", + }, { + input: "/*b*/ /*a*/", + outSQL: "", + outLeadingComments: "", + outTrailingComments: "/*b*/ /*a*/", + }, { + input: "/* before */ foo /* bar */", + outSQL: "foo", + outLeadingComments: "/* before */ ", + outTrailingComments: " /* bar */", + }, { + input: "/* before1 */ /* before2 */ foo /* after1 */ /* after2 */", + outSQL: "foo", + outLeadingComments: "/* before1 */ /* before2 */ ", + outTrailingComments: " /* after1 */ /* after2 */", + }, { + input: "/** before */ foo /** bar */", + outSQL: "foo", + outLeadingComments: "/** before */ ", + outTrailingComments: " /** bar */", + }, { + input: "/*** before */ foo /*** bar */", + outSQL: "foo", + outLeadingComments: "/*** before */ ", + outTrailingComments: " /*** bar */", + }, { + input: "/** before **/ foo /** bar **/", + outSQL: "foo", + outLeadingComments: "/** before **/ ", + outTrailingComments: " /** bar **/", + }, { + input: "/*** before ***/ foo /*** bar ***/", + outSQL: "foo", + outLeadingComments: "/*** before ***/ ", + outTrailingComments: " /*** bar ***/", + }, { + input: " /*** before ***/ foo /*** bar ***/ ", + outSQL: "foo", + outLeadingComments: "/*** before ***/ ", + outTrailingComments: " /*** bar ***/", + }, { + input: "*** bar ***/", + outSQL: "*** bar ***/", + outLeadingComments: "", + outTrailingComments: "", + }, { + input: " foo ", + outSQL: "foo", + outLeadingComments: "", + outTrailingComments: "", + }} + for _, testCase := range testCases { + gotSQL, gotComments := SplitMarginComments(testCase.input) + gotLeadingComments, gotTrailingComments := gotComments.Leading, gotComments.Trailing + + if gotSQL != testCase.outSQL { + t.Errorf("test input: '%s', got SQL\n%+v, want\n%+v", testCase.input, gotSQL, testCase.outSQL) + } + if gotLeadingComments != testCase.outLeadingComments { + t.Errorf("test input: '%s', got LeadingComments\n%+v, want\n%+v", testCase.input, gotLeadingComments, testCase.outLeadingComments) + } + if gotTrailingComments != testCase.outTrailingComments { + t.Errorf("test input: '%s', got TrailingComments\n%+v, want\n%+v", testCase.input, gotTrailingComments, testCase.outTrailingComments) + } + } +} + +func TestStripLeadingComments(t *testing.T) { + var testCases = []struct { + input, outSQL string + }{{ + input: "/", + outSQL: "/", + }, { + input: "*/", + outSQL: "*/", + }, { + input: "/*/", + outSQL: "/*/", + }, { + input: "/*a", + outSQL: "/*a", + }, { + input: "/*a*", + outSQL: "/*a*", + }, { + input: "/*a**", + outSQL: "/*a**", + }, { + input: "/*b**a*/", + outSQL: "", + }, { + input: "/*a*/", + outSQL: "", + }, { + input: "/**/", + outSQL: "", + }, { + input: "/*!*/", + outSQL: "/*!*/", + }, { + input: "/*!a*/", + outSQL: "/*!a*/", + }, { + input: "/*b*/ /*a*/", + outSQL: "", + }, { + input: `/*b*/ --foo +bar`, + outSQL: "bar", + }, { + input: "foo /* bar */", + outSQL: "foo /* bar */", + }, { + input: "/* foo */ bar", + outSQL: "bar", + }, { + input: "-- /* foo */ bar", + outSQL: "-- /* foo */ bar", + }, { + input: "foo -- bar */", + outSQL: "foo -- bar */", + }, { + input: `/* +foo */ bar`, + outSQL: "bar", + }, { + input: `-- foo bar +a`, + outSQL: "a", + }, { + input: `-- foo bar`, + outSQL: "-- foo bar", + }} + for _, testCase := range testCases { + gotSQL := StripLeadingComments(testCase.input) + + if gotSQL != testCase.outSQL { + t.Errorf("test input: '%s', got SQL\n%+v, want\n%+v", testCase.input, gotSQL, testCase.outSQL) + } + } +} + +func TestExtractMysqlComment(t *testing.T) { + var testCases = []struct { + input, outSQL, outVersion string + }{{ + input: "/*!50708SET max_execution_time=5000 */", + outSQL: "SET max_execution_time=5000", + outVersion: "50708", + }, { + input: "/*!50708 SET max_execution_time=5000*/", + outSQL: "SET max_execution_time=5000", + outVersion: "50708", + }, { + input: "/*!50708* from*/", + outSQL: "* from", + outVersion: "50708", + }, { + input: "/*! SET max_execution_time=5000*/", + outSQL: "SET max_execution_time=5000", + outVersion: "", + }} + for _, testCase := range testCases { + gotVersion, gotSQL := ExtractMysqlComment(testCase.input) + + if gotVersion != testCase.outVersion { + t.Errorf("test input: '%s', got version\n%+v, want\n%+v", testCase.input, gotVersion, testCase.outVersion) + } + if gotSQL != testCase.outSQL { + t.Errorf("test input: '%s', got SQL\n%+v, want\n%+v", testCase.input, gotSQL, testCase.outSQL) + } + } +} + +func TestExtractCommentDirectives(t *testing.T) { + var testCases = []struct { + input string + vals CommentDirectives + }{{ + input: "", + vals: nil, + }, { + input: "/* not a vt comment */", + vals: nil, + }, { + input: "/*vt+ */", + vals: CommentDirectives{}, + }, { + input: "/*vt+ SINGLE_OPTION */", + vals: CommentDirectives{ + "SINGLE_OPTION": true, + }, + }, { + input: "/*vt+ ONE_OPT TWO_OPT */", + vals: CommentDirectives{ + "ONE_OPT": true, + "TWO_OPT": true, + }, + }, { + input: "/*vt+ ONE_OPT */ /* other comment */ /*vt+ TWO_OPT */", + vals: CommentDirectives{ + "ONE_OPT": true, + "TWO_OPT": true, + }, + }, { + input: "/*vt+ ONE_OPT=abc TWO_OPT=def */", + vals: CommentDirectives{ + "ONE_OPT": "abc", + "TWO_OPT": "def", + }, + }, { + input: "/*vt+ ONE_OPT=true TWO_OPT=false */", + vals: CommentDirectives{ + "ONE_OPT": true, + "TWO_OPT": false, + }, + }, { + input: "/*vt+ ONE_OPT=true TWO_OPT=\"false\" */", + vals: CommentDirectives{ + "ONE_OPT": true, + "TWO_OPT": "\"false\"", + }, + }, { + input: "/*vt+ RANGE_OPT=[a:b] ANOTHER ANOTHER_WITH_VALEQ=val= AND_ONE_WITH_EQ== */", + vals: CommentDirectives{ + "RANGE_OPT": "[a:b]", + "ANOTHER": true, + "ANOTHER_WITH_VALEQ": "val=", + "AND_ONE_WITH_EQ": "=", + }, + }} + + for _, testCase := range testCases { + sql := "select " + testCase.input + " 1 from dual" + stmt, _ := Parse(sql) + comments := stmt.(*Select).Comments + vals := ExtractCommentDirectives(comments) + + if !reflect.DeepEqual(vals, testCase.vals) { + t.Errorf("test input: '%v', got vals:\n%+v, want\n%+v", testCase.input, vals, testCase.vals) + } + } + + d := CommentDirectives{ + "ONE_OPT": true, + "TWO_OPT": false, + "three": 1, + "four": 2, + "five": 0, + "six": "true", + } + + if !d.IsSet("ONE_OPT") { + t.Errorf("d.IsSet(ONE_OPT) should be true") + } + + if d.IsSet("TWO_OPT") { + t.Errorf("d.IsSet(TWO_OPT) should be false") + } + + if !d.IsSet("three") { + t.Errorf("d.IsSet(three) should be true") + } + + if d.IsSet("four") { + t.Errorf("d.IsSet(four) should be false") + } + + if d.IsSet("five") { + t.Errorf("d.IsSet(five) should be false") + } + + if d.IsSet("six") { + t.Errorf("d.IsSet(six) should be false") + } +} + +func TestSkipQueryPlanCacheDirective(t *testing.T) { + stmt, _ := Parse("insert /*vt+ SKIP_QUERY_PLAN_CACHE=1 */ into user(id) values (1), (2)") + if !SkipQueryPlanCacheDirective(stmt) { + t.Errorf("d.SkipQueryPlanCacheDirective(stmt) should be true") + } + + stmt, _ = Parse("insert into user(id) values (1), (2)") + if SkipQueryPlanCacheDirective(stmt) { + t.Errorf("d.SkipQueryPlanCacheDirective(stmt) should be false") + } + + stmt, _ = Parse("update /*vt+ SKIP_QUERY_PLAN_CACHE=1 */ users set name=1") + if !SkipQueryPlanCacheDirective(stmt) { + t.Errorf("d.SkipQueryPlanCacheDirective(stmt) should be true") + } + + stmt, _ = Parse("select /*vt+ SKIP_QUERY_PLAN_CACHE=1 */ * from users") + if !SkipQueryPlanCacheDirective(stmt) { + t.Errorf("d.SkipQueryPlanCacheDirective(stmt) should be true") + } + + stmt, _ = Parse("delete /*vt+ SKIP_QUERY_PLAN_CACHE=1 */ from users") + if !SkipQueryPlanCacheDirective(stmt) { + t.Errorf("d.SkipQueryPlanCacheDirective(stmt) should be true") + } +} diff --git a/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/dependency/bytes2/buffer.go b/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/dependency/bytes2/buffer.go new file mode 100644 index 00000000..72f8fc6e --- /dev/null +++ b/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/dependency/bytes2/buffer.go @@ -0,0 +1,65 @@ +/* +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 bytes2 + +// Buffer implements a subset of the write portion of +// bytes.Buffer, but more efficiently. This is meant to +// be used in very high QPS operations, especially for +// WriteByte, and without abstracting it as a Writer. +// Function signatures contain errors for compatibility, +// but they do not return errors. +type Buffer struct { + bytes []byte +} + +// NewBuffer is equivalent to bytes.NewBuffer. +func NewBuffer(b []byte) *Buffer { + return &Buffer{bytes: b} +} + +// Write is equivalent to bytes.Buffer.Write. +func (buf *Buffer) Write(b []byte) (int, error) { + buf.bytes = append(buf.bytes, b...) + return len(b), nil +} + +// WriteString is equivalent to bytes.Buffer.WriteString. +func (buf *Buffer) WriteString(s string) (int, error) { + buf.bytes = append(buf.bytes, s...) + return len(s), nil +} + +// WriteByte is equivalent to bytes.Buffer.WriteByte. +func (buf *Buffer) WriteByte(b byte) error { + buf.bytes = append(buf.bytes, b) + return nil +} + +// Bytes is equivalent to bytes.Buffer.Bytes. +func (buf *Buffer) Bytes() []byte { + return buf.bytes +} + +// Strings is equivalent to bytes.Buffer.Strings. +func (buf *Buffer) String() string { + return string(buf.bytes) +} + +// Len is equivalent to bytes.Buffer.Len. +func (buf *Buffer) Len() int { + return len(buf.bytes) +} diff --git a/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/dependency/bytes2/buffer_test.go b/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/dependency/bytes2/buffer_test.go new file mode 100644 index 00000000..6f3b102f --- /dev/null +++ b/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/dependency/bytes2/buffer_test.go @@ -0,0 +1,36 @@ +/* +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 bytes2 + +import "testing" + +func TestBuffer(t *testing.T) { + b := NewBuffer(nil) + b.Write([]byte("ab")) + b.WriteString("cd") + b.WriteByte('e') + want := "abcde" + if got := string(b.Bytes()); got != want { + t.Errorf("b.Bytes(): %s, want %s", got, want) + } + if got := b.String(); got != want { + t.Errorf("b.String(): %s, want %s", got, want) + } + if got := b.Len(); got != 5 { + t.Errorf("b.Len(): %d, want 5", got) + } +} diff --git a/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/dependency/hack/hack.go b/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/dependency/hack/hack.go new file mode 100644 index 00000000..e6344ad9 --- /dev/null +++ b/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/dependency/hack/hack.go @@ -0,0 +1,79 @@ +/* +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 hack gives you some efficient functionality at the cost of +// breaking some Go rules. +package hack + +import ( + "reflect" + "unsafe" +) + +// StringArena lets you consolidate allocations for a group of strings +// that have similar life length +type StringArena struct { + buf []byte + str string +} + +// NewStringArena creates an arena of the specified size. +func NewStringArena(size int) *StringArena { + sa := &StringArena{buf: make([]byte, 0, size)} + pbytes := (*reflect.SliceHeader)(unsafe.Pointer(&sa.buf)) + pstring := (*reflect.StringHeader)(unsafe.Pointer(&sa.str)) + pstring.Data = pbytes.Data + pstring.Len = pbytes.Cap + return sa +} + +// NewString copies a byte slice into the arena and returns it as a string. +// If the arena is full, it returns a traditional go string. +func (sa *StringArena) NewString(b []byte) string { + if len(b) == 0 { + return "" + } + if len(sa.buf)+len(b) > cap(sa.buf) { + return string(b) + } + start := len(sa.buf) + sa.buf = append(sa.buf, b...) + return sa.str[start : start+len(b)] +} + +// SpaceLeft returns the amount of space left in the arena. +func (sa *StringArena) SpaceLeft() int { + return cap(sa.buf) - len(sa.buf) +} + +// String force casts a []byte to a string. +// USE AT YOUR OWN RISK +func String(b []byte) (s string) { + if len(b) == 0 { + return "" + } + pbytes := (*reflect.SliceHeader)(unsafe.Pointer(&b)) + pstring := (*reflect.StringHeader)(unsafe.Pointer(&s)) + pstring.Data = pbytes.Data + pstring.Len = pbytes.Len + return +} + +// StringPointer returns &s[0], which is not allowed in go +func StringPointer(s string) unsafe.Pointer { + pstring := (*reflect.StringHeader)(unsafe.Pointer(&s)) + return unsafe.Pointer(pstring.Data) +} diff --git a/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/dependency/hack/hack_test.go b/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/dependency/hack/hack_test.go new file mode 100644 index 00000000..d8208c6f --- /dev/null +++ b/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/dependency/hack/hack_test.go @@ -0,0 +1,91 @@ +/* +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 hack + +import "testing" + +func TestStringArena(t *testing.T) { + sarena := NewStringArena(10) + + s0 := sarena.NewString(nil) + checkint(t, len(sarena.buf), 0) + checkint(t, sarena.SpaceLeft(), 10) + checkstring(t, s0, "") + + s1 := sarena.NewString([]byte("01234")) + checkint(t, len(sarena.buf), 5) + checkint(t, sarena.SpaceLeft(), 5) + checkstring(t, s1, "01234") + + s2 := sarena.NewString([]byte("5678")) + checkint(t, len(sarena.buf), 9) + checkint(t, sarena.SpaceLeft(), 1) + checkstring(t, s2, "5678") + + // s3 will be allocated outside of sarena + s3 := sarena.NewString([]byte("ab")) + checkint(t, len(sarena.buf), 9) + checkint(t, sarena.SpaceLeft(), 1) + checkstring(t, s3, "ab") + + // s4 should still fit in sarena + s4 := sarena.NewString([]byte("9")) + checkint(t, len(sarena.buf), 10) + checkint(t, sarena.SpaceLeft(), 0) + checkstring(t, s4, "9") + + sarena.buf[0] = 'A' + checkstring(t, s1, "A1234") + + sarena.buf[5] = 'B' + checkstring(t, s2, "B678") + + sarena.buf[9] = 'C' + // s3 will not change + checkstring(t, s3, "ab") + checkstring(t, s4, "C") + checkstring(t, sarena.str, "A1234B678C") +} + +func checkstring(t *testing.T, actual, expected string) { + if actual != expected { + t.Errorf("received %s, expecting %s", actual, expected) + } +} + +func checkint(t *testing.T, actual, expected int) { + if actual != expected { + t.Errorf("received %d, expecting %d", actual, expected) + } +} + +func TestByteToString(t *testing.T) { + v1 := []byte("1234") + if s := String(v1); s != "1234" { + t.Errorf("String(\"1234\"): %q, want 1234", s) + } + + v1 = []byte("") + if s := String(v1); s != "" { + t.Errorf("String(\"\"): %q, want empty", s) + } + + v1 = nil + if s := String(v1); s != "" { + t.Errorf("String(\"\"): %q, want empty", s) + } +} diff --git a/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/dependency/querypb/query.pb.go b/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/dependency/querypb/query.pb.go new file mode 100644 index 00000000..db9f924c --- /dev/null +++ b/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/dependency/querypb/query.pb.go @@ -0,0 +1,2734 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: query.proto + +/* +Package query is a generated protocol buffer package. + +It is generated from these files: + query.proto + +It has these top-level messages: + Target + VTGateCallerID + EventToken + Value + BindVariable + BoundQuery + ExecuteOptions + Field + Row + ResultExtras + QueryResult + StreamEvent + ExecuteRequest + ExecuteResponse + ResultWithError + ExecuteBatchRequest + ExecuteBatchResponse + StreamExecuteRequest + StreamExecuteResponse + BeginRequest + BeginResponse + CommitRequest + CommitResponse + RollbackRequest + RollbackResponse + PrepareRequest + PrepareResponse + CommitPreparedRequest + CommitPreparedResponse + RollbackPreparedRequest + RollbackPreparedResponse + CreateTransactionRequest + CreateTransactionResponse + StartCommitRequest + StartCommitResponse + SetRollbackRequest + SetRollbackResponse + ConcludeTransactionRequest + ConcludeTransactionResponse + ReadTransactionRequest + ReadTransactionResponse + BeginExecuteRequest + BeginExecuteResponse + BeginExecuteBatchRequest + BeginExecuteBatchResponse + MessageStreamRequest + MessageStreamResponse + MessageAckRequest + MessageAckResponse + SplitQueryRequest + QuerySplit + SplitQueryResponse + StreamHealthRequest + RealtimeStats + StreamHealthResponse + UpdateStreamRequest + UpdateStreamResponse + TransactionMetadata +*/ +package querypb + +import "strconv" + +// EnumName is a helper function to simplify printing protocol buffer enums +// by name. Given an enum map and a value, it returns a useful string. +func EnumName(m map[int32]string, v int32) string { + s, ok := m[v] + if ok { + return s + } + return strconv.Itoa(int(v)) +} + +// Flags sent from the MySQL C API +type MySqlFlag int32 + +const ( + MySqlFlag_EMPTY MySqlFlag = 0 + MySqlFlag_NOT_NULL_FLAG MySqlFlag = 1 + MySqlFlag_PRI_KEY_FLAG MySqlFlag = 2 + MySqlFlag_UNIQUE_KEY_FLAG MySqlFlag = 4 + MySqlFlag_MULTIPLE_KEY_FLAG MySqlFlag = 8 + MySqlFlag_BLOB_FLAG MySqlFlag = 16 + MySqlFlag_UNSIGNED_FLAG MySqlFlag = 32 + MySqlFlag_ZEROFILL_FLAG MySqlFlag = 64 + MySqlFlag_BINARY_FLAG MySqlFlag = 128 + MySqlFlag_ENUM_FLAG MySqlFlag = 256 + MySqlFlag_AUTO_INCREMENT_FLAG MySqlFlag = 512 + MySqlFlag_TIMESTAMP_FLAG MySqlFlag = 1024 + MySqlFlag_SET_FLAG MySqlFlag = 2048 + MySqlFlag_NO_DEFAULT_VALUE_FLAG MySqlFlag = 4096 + MySqlFlag_ON_UPDATE_NOW_FLAG MySqlFlag = 8192 + MySqlFlag_NUM_FLAG MySqlFlag = 32768 + MySqlFlag_PART_KEY_FLAG MySqlFlag = 16384 + MySqlFlag_GROUP_FLAG MySqlFlag = 32768 + MySqlFlag_UNIQUE_FLAG MySqlFlag = 65536 + MySqlFlag_BINCMP_FLAG MySqlFlag = 131072 +) + +var MySqlFlag_name = map[int32]string{ + 0: "EMPTY", + 1: "NOT_NULL_FLAG", + 2: "PRI_KEY_FLAG", + 4: "UNIQUE_KEY_FLAG", + 8: "MULTIPLE_KEY_FLAG", + 16: "BLOB_FLAG", + 32: "UNSIGNED_FLAG", + 64: "ZEROFILL_FLAG", + 128: "BINARY_FLAG", + 256: "ENUM_FLAG", + 512: "AUTO_INCREMENT_FLAG", + 1024: "TIMESTAMP_FLAG", + 2048: "SET_FLAG", + 4096: "NO_DEFAULT_VALUE_FLAG", + 8192: "ON_UPDATE_NOW_FLAG", + 32768: "NUM_FLAG", + 16384: "PART_KEY_FLAG", + // Duplicate value: 32768: "GROUP_FLAG", + 65536: "UNIQUE_FLAG", + 131072: "BINCMP_FLAG", +} +var MySqlFlag_value = map[string]int32{ + "EMPTY": 0, + "NOT_NULL_FLAG": 1, + "PRI_KEY_FLAG": 2, + "UNIQUE_KEY_FLAG": 4, + "MULTIPLE_KEY_FLAG": 8, + "BLOB_FLAG": 16, + "UNSIGNED_FLAG": 32, + "ZEROFILL_FLAG": 64, + "BINARY_FLAG": 128, + "ENUM_FLAG": 256, + "AUTO_INCREMENT_FLAG": 512, + "TIMESTAMP_FLAG": 1024, + "SET_FLAG": 2048, + "NO_DEFAULT_VALUE_FLAG": 4096, + "ON_UPDATE_NOW_FLAG": 8192, + "NUM_FLAG": 32768, + "PART_KEY_FLAG": 16384, + "GROUP_FLAG": 32768, + "UNIQUE_FLAG": 65536, + "BINCMP_FLAG": 131072, +} + +func (x MySqlFlag) String() string { + return EnumName(MySqlFlag_name, int32(x)) +} + +// Flag allows us to qualify types by their common properties. +type Flag int32 + +const ( + Flag_NONE Flag = 0 + Flag_ISINTEGRAL Flag = 256 + Flag_ISUNSIGNED Flag = 512 + Flag_ISFLOAT Flag = 1024 + Flag_ISQUOTED Flag = 2048 + Flag_ISTEXT Flag = 4096 + Flag_ISBINARY Flag = 8192 +) + +var Flag_name = map[int32]string{ + 0: "NONE", + 256: "ISINTEGRAL", + 512: "ISUNSIGNED", + 1024: "ISFLOAT", + 2048: "ISQUOTED", + 4096: "ISTEXT", + 8192: "ISBINARY", +} +var Flag_value = map[string]int32{ + "NONE": 0, + "ISINTEGRAL": 256, + "ISUNSIGNED": 512, + "ISFLOAT": 1024, + "ISQUOTED": 2048, + "ISTEXT": 4096, + "ISBINARY": 8192, +} + +func (x Flag) String() string { + return EnumName(Flag_name, int32(x)) +} + +// Type defines the various supported data types in bind vars +// and query results. +type Type int32 + +const ( + // NULL_TYPE specifies a NULL type. + Type_NULL_TYPE Type = 0 + // INT8 specifies a TINYINT type. + // Properties: 1, IsNumber. + Type_INT8 Type = 257 + // UINT8 specifies a TINYINT UNSIGNED type. + // Properties: 2, IsNumber, IsUnsigned. + Type_UINT8 Type = 770 + // INT16 specifies a SMALLINT type. + // Properties: 3, IsNumber. + Type_INT16 Type = 259 + // UINT16 specifies a SMALLINT UNSIGNED type. + // Properties: 4, IsNumber, IsUnsigned. + Type_UINT16 Type = 772 + // INT24 specifies a MEDIUMINT type. + // Properties: 5, IsNumber. + Type_INT24 Type = 261 + // UINT24 specifies a MEDIUMINT UNSIGNED type. + // Properties: 6, IsNumber, IsUnsigned. + Type_UINT24 Type = 774 + // INT32 specifies a INTEGER type. + // Properties: 7, IsNumber. + Type_INT32 Type = 263 + // UINT32 specifies a INTEGER UNSIGNED type. + // Properties: 8, IsNumber, IsUnsigned. + Type_UINT32 Type = 776 + // INT64 specifies a BIGINT type. + // Properties: 9, IsNumber. + Type_INT64 Type = 265 + // UINT64 specifies a BIGINT UNSIGNED type. + // Properties: 10, IsNumber, IsUnsigned. + Type_UINT64 Type = 778 + // FLOAT32 specifies a FLOAT type. + // Properties: 11, IsFloat. + Type_FLOAT32 Type = 1035 + // FLOAT64 specifies a DOUBLE or REAL type. + // Properties: 12, IsFloat. + Type_FLOAT64 Type = 1036 + // TIMESTAMP specifies a TIMESTAMP type. + // Properties: 13, IsQuoted. + Type_TIMESTAMP Type = 2061 + // DATE specifies a DATE type. + // Properties: 14, IsQuoted. + Type_DATE Type = 2062 + // TIME specifies a TIME type. + // Properties: 15, IsQuoted. + Type_TIME Type = 2063 + // DATETIME specifies a DATETIME type. + // Properties: 16, IsQuoted. + Type_DATETIME Type = 2064 + // YEAR specifies a YEAR type. + // Properties: 17, IsNumber, IsUnsigned. + Type_YEAR Type = 785 + // DECIMAL specifies a DECIMAL or NUMERIC type. + // Properties: 18, None. + Type_DECIMAL Type = 18 + // TEXT specifies a TEXT type. + // Properties: 19, IsQuoted, IsText. + Type_TEXT Type = 6163 + // BLOB specifies a BLOB type. + // Properties: 20, IsQuoted, IsBinary. + Type_BLOB Type = 10260 + // VARCHAR specifies a VARCHAR type. + // Properties: 21, IsQuoted, IsText. + Type_VARCHAR Type = 6165 + // VARBINARY specifies a VARBINARY type. + // Properties: 22, IsQuoted, IsBinary. + Type_VARBINARY Type = 10262 + // CHAR specifies a CHAR type. + // Properties: 23, IsQuoted, IsText. + Type_CHAR Type = 6167 + // BINARY specifies a BINARY type. + // Properties: 24, IsQuoted, IsBinary. + Type_BINARY Type = 10264 + // BIT specifies a BIT type. + // Properties: 25, IsQuoted. + Type_BIT Type = 2073 + // ENUM specifies an ENUM type. + // Properties: 26, IsQuoted. + Type_ENUM Type = 2074 + // SET specifies a SET type. + // Properties: 27, IsQuoted. + Type_SET Type = 2075 + // TUPLE specifies a a tuple. This cannot + // be returned in a QueryResult, but it can + // be sent as a bind var. + // Properties: 28, None. + Type_TUPLE Type = 28 + // GEOMETRY specifies a GEOMETRY type. + // Properties: 29, IsQuoted. + Type_GEOMETRY Type = 2077 + // JSON specifies a JSON type. + // Properties: 30, IsQuoted. + Type_JSON Type = 2078 + // EXPRESSION specifies a SQL expression. + // This type is for internal use only. + // Properties: 31, None. + Type_EXPRESSION Type = 31 +) + +var Type_name = map[int32]string{ + 0: "NULL_TYPE", + 257: "INT8", + 770: "UINT8", + 259: "INT16", + 772: "UINT16", + 261: "INT24", + 774: "UINT24", + 263: "INT32", + 776: "UINT32", + 265: "INT64", + 778: "UINT64", + 1035: "FLOAT32", + 1036: "FLOAT64", + 2061: "TIMESTAMP", + 2062: "DATE", + 2063: "TIME", + 2064: "DATETIME", + 785: "YEAR", + 18: "DECIMAL", + 6163: "TEXT", + 10260: "BLOB", + 6165: "VARCHAR", + 10262: "VARBINARY", + 6167: "CHAR", + 10264: "BINARY", + 2073: "BIT", + 2074: "ENUM", + 2075: "SET", + 28: "TUPLE", + 2077: "GEOMETRY", + 2078: "JSON", + 31: "EXPRESSION", +} +var Type_value = map[string]int32{ + "NULL_TYPE": 0, + "INT8": 257, + "UINT8": 770, + "INT16": 259, + "UINT16": 772, + "INT24": 261, + "UINT24": 774, + "INT32": 263, + "UINT32": 776, + "INT64": 265, + "UINT64": 778, + "FLOAT32": 1035, + "FLOAT64": 1036, + "TIMESTAMP": 2061, + "DATE": 2062, + "TIME": 2063, + "DATETIME": 2064, + "YEAR": 785, + "DECIMAL": 18, + "TEXT": 6163, + "BLOB": 10260, + "VARCHAR": 6165, + "VARBINARY": 10262, + "CHAR": 6167, + "BINARY": 10264, + "BIT": 2073, + "ENUM": 2074, + "SET": 2075, + "TUPLE": 28, + "GEOMETRY": 2077, + "JSON": 2078, + "EXPRESSION": 31, +} + +func (x Type) String() string { + return EnumName(Type_name, int32(x)) +} + +// TransactionState represents the state of a distributed transaction. +type TransactionState int32 + +const ( + TransactionState_UNKNOWN TransactionState = 0 + TransactionState_PREPARE TransactionState = 1 + TransactionState_COMMIT TransactionState = 2 + TransactionState_ROLLBACK TransactionState = 3 +) + +var TransactionState_name = map[int32]string{ + 0: "UNKNOWN", + 1: "PREPARE", + 2: "COMMIT", + 3: "ROLLBACK", +} +var TransactionState_value = map[string]int32{ + "UNKNOWN": 0, + "PREPARE": 1, + "COMMIT": 2, + "ROLLBACK": 3, +} + +func (x TransactionState) String() string { + return EnumName(TransactionState_name, int32(x)) +} + +type ExecuteOptions_IncludedFields int32 + +const ( + ExecuteOptions_TYPE_AND_NAME ExecuteOptions_IncludedFields = 0 + ExecuteOptions_TYPE_ONLY ExecuteOptions_IncludedFields = 1 + ExecuteOptions_ALL ExecuteOptions_IncludedFields = 2 +) + +var ExecuteOptions_IncludedFields_name = map[int32]string{ + 0: "TYPE_AND_NAME", + 1: "TYPE_ONLY", + 2: "ALL", +} +var ExecuteOptions_IncludedFields_value = map[string]int32{ + "TYPE_AND_NAME": 0, + "TYPE_ONLY": 1, + "ALL": 2, +} + +func (x ExecuteOptions_IncludedFields) String() string { + return EnumName(ExecuteOptions_IncludedFields_name, int32(x)) +} + +type ExecuteOptions_Workload int32 + +const ( + ExecuteOptions_UNSPECIFIED ExecuteOptions_Workload = 0 + ExecuteOptions_OLTP ExecuteOptions_Workload = 1 + ExecuteOptions_OLAP ExecuteOptions_Workload = 2 + ExecuteOptions_DBA ExecuteOptions_Workload = 3 +) + +var ExecuteOptions_Workload_name = map[int32]string{ + 0: "UNSPECIFIED", + 1: "OLTP", + 2: "OLAP", + 3: "DBA", +} +var ExecuteOptions_Workload_value = map[string]int32{ + "UNSPECIFIED": 0, + "OLTP": 1, + "OLAP": 2, + "DBA": 3, +} + +func (x ExecuteOptions_Workload) String() string { + return EnumName(ExecuteOptions_Workload_name, int32(x)) +} + +type ExecuteOptions_TransactionIsolation int32 + +const ( + ExecuteOptions_DEFAULT ExecuteOptions_TransactionIsolation = 0 + ExecuteOptions_REPEATABLE_READ ExecuteOptions_TransactionIsolation = 1 + ExecuteOptions_READ_COMMITTED ExecuteOptions_TransactionIsolation = 2 + ExecuteOptions_READ_UNCOMMITTED ExecuteOptions_TransactionIsolation = 3 + ExecuteOptions_SERIALIZABLE ExecuteOptions_TransactionIsolation = 4 +) + +var ExecuteOptions_TransactionIsolation_name = map[int32]string{ + 0: "DEFAULT", + 1: "REPEATABLE_READ", + 2: "READ_COMMITTED", + 3: "READ_UNCOMMITTED", + 4: "SERIALIZABLE", +} +var ExecuteOptions_TransactionIsolation_value = map[string]int32{ + "DEFAULT": 0, + "REPEATABLE_READ": 1, + "READ_COMMITTED": 2, + "READ_UNCOMMITTED": 3, + "SERIALIZABLE": 4, +} + +func (x ExecuteOptions_TransactionIsolation) String() string { + return EnumName(ExecuteOptions_TransactionIsolation_name, int32(x)) +} + +// The category of one statement. +type StreamEvent_Statement_Category int32 + +const ( + StreamEvent_Statement_Error StreamEvent_Statement_Category = 0 + StreamEvent_Statement_DML StreamEvent_Statement_Category = 1 + StreamEvent_Statement_DDL StreamEvent_Statement_Category = 2 +) + +var StreamEvent_Statement_Category_name = map[int32]string{ + 0: "Error", + 1: "DML", + 2: "DDL", +} +var StreamEvent_Statement_Category_value = map[string]int32{ + "Error": 0, + "DML": 1, + "DDL": 2, +} + +func (x StreamEvent_Statement_Category) String() string { + return EnumName(StreamEvent_Statement_Category_name, int32(x)) +} + +type SplitQueryRequest_Algorithm int32 + +const ( + SplitQueryRequest_EQUAL_SPLITS SplitQueryRequest_Algorithm = 0 + SplitQueryRequest_FULL_SCAN SplitQueryRequest_Algorithm = 1 +) + +var SplitQueryRequest_Algorithm_name = map[int32]string{ + 0: "EQUAL_SPLITS", + 1: "FULL_SCAN", +} +var SplitQueryRequest_Algorithm_value = map[string]int32{ + "EQUAL_SPLITS": 0, + "FULL_SCAN": 1, +} + +func (x SplitQueryRequest_Algorithm) String() string { + return EnumName(SplitQueryRequest_Algorithm_name, int32(x)) +} + +/* +// Target describes what the client expects the tablet is. +// If the tablet does not match, an error is returned. +type Target struct { + Keyspace string `protobuf:"bytes,1,opt,name=keyspace" json:"keyspace,omitempty"` + Shard string `protobuf:"bytes,2,opt,name=shard" json:"shard,omitempty"` + TabletType topodata.TabletType `protobuf:"varint,3,opt,name=tablet_type,json=tabletType,enum=topodata.TabletType" json:"tablet_type,omitempty"` +} + +func (m *Target) Reset() { *m = Target{} } +func (m *Target) String() string { return "TODO" } + + + +func (m *Target) GetKeyspace() string { + if m != nil { + return m.Keyspace + } + return "" +} + +func (m *Target) GetShard() string { + if m != nil { + return m.Shard + } + return "" +} + +func (m *Target) GetTabletType() topodata.TabletType { + if m != nil { + return m.TabletType + } + return topodata.TabletType_UNKNOWN +} + + +// VTGateCallerID is sent by VTGate to VTTablet to describe the +// caller. If possible, this information is secure. For instance, +// if using unique certificates that guarantee that VTGate->VTTablet +// traffic cannot be spoofed, then VTTablet can trust this information, +// and VTTablet will use it for tablet ACLs, for instance. +// Because of this security guarantee, this is different than the CallerID +// structure, which is not secure at all, because it is provided +// by the Vitess client. +type VTGateCallerID struct { + Username string `protobuf:"bytes,1,opt,name=username" json:"username,omitempty"` + Groups []string `protobuf:"bytes,2,rep,name=groups" json:"groups,omitempty"` +} + +func (m *VTGateCallerID) Reset() { *m = VTGateCallerID{} } +func (m *VTGateCallerID) String() string { return "TODO" } + + + +func (m *VTGateCallerID) GetUsername() string { + if m != nil { + return m.Username + } + return "" +} + +func (m *VTGateCallerID) GetGroups() []string { + if m != nil { + return m.Groups + } + return nil +} + +// EventToken is a structure that describes a point in time in a +// replication stream on one shard. The most recent known replication +// position can be retrieved from vttablet when executing a query. It +// is also sent with the replication streams from the binlog service. +type EventToken struct { + // timestamp is the MySQL timestamp of the statements. Seconds since Epoch. + Timestamp int64 `protobuf:"varint,1,opt,name=timestamp" json:"timestamp,omitempty"` + // The shard name that applied the statements. Note this is not set when + // streaming from a vttablet. It is only used on the client -> vtgate link. + Shard string `protobuf:"bytes,2,opt,name=shard" json:"shard,omitempty"` + // The position on the replication stream after this statement was applied. + // It is not the transaction ID / GTID, but the position / GTIDSet. + Position string `protobuf:"bytes,3,opt,name=position" json:"position,omitempty"` +} + +func (m *EventToken) Reset() { *m = EventToken{} } +func (m *EventToken) String() string { return "TODO" } + + + +func (m *EventToken) GetTimestamp() int64 { + if m != nil { + return m.Timestamp + } + return 0 +} + +func (m *EventToken) GetShard() string { + if m != nil { + return m.Shard + } + return "" +} + +func (m *EventToken) GetPosition() string { + if m != nil { + return m.Position + } + return "" +} +*/ + +// Value represents a typed value. +type Value struct { + Type Type `protobuf:"varint,1,opt,name=type,enum=query.Type" json:"type,omitempty"` + Value []byte `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` +} + +func (m *Value) Reset() { *m = Value{} } +func (m *Value) String() string { return "TODO" } + +func (m *Value) GetType() Type { + if m != nil { + return m.Type + } + return Type_NULL_TYPE +} + +func (m *Value) GetValue() []byte { + if m != nil { + return m.Value + } + return nil +} + +// BindVariable represents a single bind variable in a Query. +type BindVariable struct { + Type Type `protobuf:"varint,1,opt,name=type,enum=query.Type" json:"type,omitempty"` + Value []byte `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` + // values are set if type is TUPLE. + Values []*Value `protobuf:"bytes,3,rep,name=values" json:"values,omitempty"` +} + +func (m *BindVariable) Reset() { *m = BindVariable{} } +func (m *BindVariable) String() string { return "TODO" } + +func (m *BindVariable) GetType() Type { + if m != nil { + return m.Type + } + return Type_NULL_TYPE +} + +func (m *BindVariable) GetValue() []byte { + if m != nil { + return m.Value + } + return nil +} + +func (m *BindVariable) GetValues() []*Value { + if m != nil { + return m.Values + } + return nil +} + +// BoundQuery is a query with its bind variables +type BoundQuery struct { + // sql is the SQL query to execute + Sql string `protobuf:"bytes,1,opt,name=sql" json:"sql,omitempty"` + // bind_variables is a map of all bind variables to expand in the query. + // nil values are not allowed. Use NULL_TYPE to express a NULL value. + BindVariables map[string]*BindVariable `protobuf:"bytes,2,rep,name=bind_variables,json=bindVariables" json:"bind_variables,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` +} + +func (m *BoundQuery) Reset() { *m = BoundQuery{} } +func (m *BoundQuery) String() string { return "TODO" } + +func (m *BoundQuery) GetSql() string { + if m != nil { + return m.Sql + } + return "" +} + +func (m *BoundQuery) GetBindVariables() map[string]*BindVariable { + if m != nil { + return m.BindVariables + } + return nil +} + +/* +// ExecuteOptions is passed around for all Execute calls. +type ExecuteOptions struct { + // If set, we will try to include an EventToken with the responses. + IncludeEventToken bool `protobuf:"varint,2,opt,name=include_event_token,json=includeEventToken" json:"include_event_token,omitempty"` + // If set, the fresher field may be set as a result comparison to this token. + // This is a shortcut so the application doesn't need to care about + // comparing EventTokens. + CompareEventToken *EventToken `protobuf:"bytes,3,opt,name=compare_event_token,json=compareEventToken" json:"compare_event_token,omitempty"` + // Controls what fields are returned in Field message responses from mysql, i.e. + // field name, table name, etc. This is an optimization for high-QPS queries where + // the client knows what it's getting + IncludedFields ExecuteOptions_IncludedFields `protobuf:"varint,4,opt,name=included_fields,json=includedFields,enum=query.ExecuteOptions_IncludedFields" json:"included_fields,omitempty"` + // client_rows_found specifies if rows_affected should return + // rows found instead of rows affected. Behavior is defined + // by MySQL's CLIENT_FOUND_ROWS flag. + ClientFoundRows bool `protobuf:"varint,5,opt,name=client_found_rows,json=clientFoundRows" json:"client_found_rows,omitempty"` + // workload specifies the type of workload: + // OLTP: DMLs allowed, results have row count limit, and + // query timeouts are shorter. + // OLAP: DMLS not allowed, no limit on row count, timeouts + // can be as high as desired. + // DBA: no limit on rowcount or timeout, all queries allowed + // but intended for long DMLs and DDLs. + Workload ExecuteOptions_Workload `protobuf:"varint,6,opt,name=workload,enum=query.ExecuteOptions_Workload" json:"workload,omitempty"` + // sql_select_limit sets an implicit limit on all select statements. Since + // vitess also sets a rowcount limit on queries, the smallest value wins. + SqlSelectLimit int64 `protobuf:"varint,8,opt,name=sql_select_limit,json=sqlSelectLimit" json:"sql_select_limit,omitempty"` + TransactionIsolation ExecuteOptions_TransactionIsolation `protobuf:"varint,9,opt,name=transaction_isolation,json=transactionIsolation,enum=query.ExecuteOptions_TransactionIsolation" json:"transaction_isolation,omitempty"` +} + +func (m *ExecuteOptions) Reset() { *m = ExecuteOptions{} } +func (m *ExecuteOptions) String() string { return "TODO" } + + + +func (m *ExecuteOptions) GetIncludeEventToken() bool { + if m != nil { + return m.IncludeEventToken + } + return false +} + +func (m *ExecuteOptions) GetCompareEventToken() *EventToken { + if m != nil { + return m.CompareEventToken + } + return nil +} + +func (m *ExecuteOptions) GetIncludedFields() ExecuteOptions_IncludedFields { + if m != nil { + return m.IncludedFields + } + return ExecuteOptions_TYPE_AND_NAME +} + +func (m *ExecuteOptions) GetClientFoundRows() bool { + if m != nil { + return m.ClientFoundRows + } + return false +} + +func (m *ExecuteOptions) GetWorkload() ExecuteOptions_Workload { + if m != nil { + return m.Workload + } + return ExecuteOptions_UNSPECIFIED +} + +func (m *ExecuteOptions) GetSqlSelectLimit() int64 { + if m != nil { + return m.SqlSelectLimit + } + return 0 +} + +func (m *ExecuteOptions) GetTransactionIsolation() ExecuteOptions_TransactionIsolation { + if m != nil { + return m.TransactionIsolation + } + return ExecuteOptions_DEFAULT +} + +// Field describes a single column returned by a query +type Field struct { + // name of the field as returned by mysql C API + Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` + // vitess-defined type. Conversion function is in sqltypes package. + Type Type `protobuf:"varint,2,opt,name=type,enum=query.Type" json:"type,omitempty"` + // Remaining fields from mysql C API. + // These fields are only populated when ExecuteOptions.included_fields + // is set to IncludedFields.ALL. + Table string `protobuf:"bytes,3,opt,name=table" json:"table,omitempty"` + OrgTable string `protobuf:"bytes,4,opt,name=org_table,json=orgTable" json:"org_table,omitempty"` + Database string `protobuf:"bytes,5,opt,name=database" json:"database,omitempty"` + OrgName string `protobuf:"bytes,6,opt,name=org_name,json=orgName" json:"org_name,omitempty"` + // column_length is really a uint32. All 32 bits can be used. + ColumnLength uint32 `protobuf:"varint,7,opt,name=column_length,json=columnLength" json:"column_length,omitempty"` + // charset is actually a uint16. Only the lower 16 bits are used. + Charset uint32 `protobuf:"varint,8,opt,name=charset" json:"charset,omitempty"` + // decimals is actualy a uint8. Only the lower 8 bits are used. + Decimals uint32 `protobuf:"varint,9,opt,name=decimals" json:"decimals,omitempty"` + // flags is actually a uint16. Only the lower 16 bits are used. + Flags uint32 `protobuf:"varint,10,opt,name=flags" json:"flags,omitempty"` +} + +func (m *Field) Reset() { *m = Field{} } +func (m *Field) String() string { return "TODO" } + + + +func (m *Field) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +func (m *Field) GetType() Type { + if m != nil { + return m.Type + } + return Type_NULL_TYPE +} + +func (m *Field) GetTable() string { + if m != nil { + return m.Table + } + return "" +} + +func (m *Field) GetOrgTable() string { + if m != nil { + return m.OrgTable + } + return "" +} + +func (m *Field) GetDatabase() string { + if m != nil { + return m.Database + } + return "" +} + +func (m *Field) GetOrgName() string { + if m != nil { + return m.OrgName + } + return "" +} + +func (m *Field) GetColumnLength() uint32 { + if m != nil { + return m.ColumnLength + } + return 0 +} + +func (m *Field) GetCharset() uint32 { + if m != nil { + return m.Charset + } + return 0 +} + +func (m *Field) GetDecimals() uint32 { + if m != nil { + return m.Decimals + } + return 0 +} + +func (m *Field) GetFlags() uint32 { + if m != nil { + return m.Flags + } + return 0 +} + +// Row is a database row. +type Row struct { + // lengths contains the length of each value in values. + // A length of -1 means that the field is NULL. While + // reading values, you have to accummulate the length + // to know the offset where the next value begins in values. + Lengths []int64 `protobuf:"zigzag64,1,rep,packed,name=lengths" json:"lengths,omitempty"` + // values contains a concatenation of all values in the row. + Values []byte `protobuf:"bytes,2,opt,name=values,proto3" json:"values,omitempty"` +} + +func (m *Row) Reset() { *m = Row{} } +func (m *Row) String() string { return "TODO" } + + + +func (m *Row) GetLengths() []int64 { + if m != nil { + return m.Lengths + } + return nil +} + +func (m *Row) GetValues() []byte { + if m != nil { + return m.Values + } + return nil +} + +// ResultExtras contains optional out-of-band information. Usually the +// extras are requested by adding ExecuteOptions flags. +type ResultExtras struct { + // event_token is populated if the include_event_token flag is set + // in ExecuteOptions. + EventToken *EventToken `protobuf:"bytes,1,opt,name=event_token,json=eventToken" json:"event_token,omitempty"` + // If set, it means the data returned with this result is fresher + // than the compare_token passed in the ExecuteOptions. + Fresher bool `protobuf:"varint,2,opt,name=fresher" json:"fresher,omitempty"` +} + +func (m *ResultExtras) Reset() { *m = ResultExtras{} } +func (m *ResultExtras) String() string { return "TODO" } + + + +func (m *ResultExtras) GetEventToken() *EventToken { + if m != nil { + return m.EventToken + } + return nil +} + +func (m *ResultExtras) GetFresher() bool { + if m != nil { + return m.Fresher + } + return false +} + +// QueryResult is returned by Execute and ExecuteStream. +// +// As returned by Execute, len(fields) is always equal to len(row) +// (for each row in rows). +// +// As returned by StreamExecute, the first QueryResult has the fields +// set, and subsequent QueryResult have rows set. And as Execute, +// len(QueryResult[0].fields) is always equal to len(row) (for each +// row in rows for each QueryResult in QueryResult[1:]). +type QueryResult struct { + Fields []*Field `protobuf:"bytes,1,rep,name=fields" json:"fields,omitempty"` + RowsAffected uint64 `protobuf:"varint,2,opt,name=rows_affected,json=rowsAffected" json:"rows_affected,omitempty"` + InsertId uint64 `protobuf:"varint,3,opt,name=insert_id,json=insertId" json:"insert_id,omitempty"` + Rows []*Row `protobuf:"bytes,4,rep,name=rows" json:"rows,omitempty"` + Extras *ResultExtras `protobuf:"bytes,5,opt,name=extras" json:"extras,omitempty"` +} + +func (m *QueryResult) Reset() { *m = QueryResult{} } +func (m *QueryResult) String() string { return "TODO" } + + + +func (m *QueryResult) GetFields() []*Field { + if m != nil { + return m.Fields + } + return nil +} + +func (m *QueryResult) GetRowsAffected() uint64 { + if m != nil { + return m.RowsAffected + } + return 0 +} + +func (m *QueryResult) GetInsertId() uint64 { + if m != nil { + return m.InsertId + } + return 0 +} + +func (m *QueryResult) GetRows() []*Row { + if m != nil { + return m.Rows + } + return nil +} + +func (m *QueryResult) GetExtras() *ResultExtras { + if m != nil { + return m.Extras + } + return nil +} + +// StreamEvent describes a set of transformations that happened as a +// single transactional unit on a server. It is streamed back by the +// Update Stream calls. +type StreamEvent struct { + // The statements in this transaction. + Statements []*StreamEvent_Statement `protobuf:"bytes,1,rep,name=statements" json:"statements,omitempty"` + // The Event Token for this event. + EventToken *EventToken `protobuf:"bytes,2,opt,name=event_token,json=eventToken" json:"event_token,omitempty"` +} + +func (m *StreamEvent) Reset() { *m = StreamEvent{} } +func (m *StreamEvent) String() string { return "TODO" } + + + +func (m *StreamEvent) GetStatements() []*StreamEvent_Statement { + if m != nil { + return m.Statements + } + return nil +} + +func (m *StreamEvent) GetEventToken() *EventToken { + if m != nil { + return m.EventToken + } + return nil +} + +// One individual Statement in a transaction. +type StreamEvent_Statement struct { + Category StreamEvent_Statement_Category `protobuf:"varint,1,opt,name=category,enum=query.StreamEvent_Statement_Category" json:"category,omitempty"` + // table_name, primary_key_fields and primary_key_values are set for DML. + TableName string `protobuf:"bytes,2,opt,name=table_name,json=tableName" json:"table_name,omitempty"` + PrimaryKeyFields []*Field `protobuf:"bytes,3,rep,name=primary_key_fields,json=primaryKeyFields" json:"primary_key_fields,omitempty"` + PrimaryKeyValues []*Row `protobuf:"bytes,4,rep,name=primary_key_values,json=primaryKeyValues" json:"primary_key_values,omitempty"` + // sql is set for all queries. + // FIXME(alainjobart) we may not need it for DMLs. + Sql []byte `protobuf:"bytes,5,opt,name=sql,proto3" json:"sql,omitempty"` +} + +func (m *StreamEvent_Statement) Reset() { *m = StreamEvent_Statement{} } +func (m *StreamEvent_Statement) String() string { return "TODO" } + + + +func (m *StreamEvent_Statement) GetCategory() StreamEvent_Statement_Category { + if m != nil { + return m.Category + } + return StreamEvent_Statement_Error +} + +func (m *StreamEvent_Statement) GetTableName() string { + if m != nil { + return m.TableName + } + return "" +} + +func (m *StreamEvent_Statement) GetPrimaryKeyFields() []*Field { + if m != nil { + return m.PrimaryKeyFields + } + return nil +} + +func (m *StreamEvent_Statement) GetPrimaryKeyValues() []*Row { + if m != nil { + return m.PrimaryKeyValues + } + return nil +} + +func (m *StreamEvent_Statement) GetSql() []byte { + if m != nil { + return m.Sql + } + return nil +} + + +// ExecuteRequest is the payload to Execute +type ExecuteRequest struct { + EffectiveCallerId *vtrpc.CallerID `protobuf:"bytes,1,opt,name=effective_caller_id,json=effectiveCallerId" json:"effective_caller_id,omitempty"` + ImmediateCallerId *VTGateCallerID `protobuf:"bytes,2,opt,name=immediate_caller_id,json=immediateCallerId" json:"immediate_caller_id,omitempty"` + Target *Target `protobuf:"bytes,3,opt,name=target" json:"target,omitempty"` + Query *BoundQuery `protobuf:"bytes,4,opt,name=query" json:"query,omitempty"` + TransactionId int64 `protobuf:"varint,5,opt,name=transaction_id,json=transactionId" json:"transaction_id,omitempty"` + Options *ExecuteOptions `protobuf:"bytes,6,opt,name=options" json:"options,omitempty"` +} + +func (m *ExecuteRequest) Reset() { *m = ExecuteRequest{} } +func (m *ExecuteRequest) String() string { return "TODO" } + + + +func (m *ExecuteRequest) GetEffectiveCallerId() *vtrpc.CallerID { + if m != nil { + return m.EffectiveCallerId + } + return nil +} + +func (m *ExecuteRequest) GetImmediateCallerId() *VTGateCallerID { + if m != nil { + return m.ImmediateCallerId + } + return nil +} + +func (m *ExecuteRequest) GetTarget() *Target { + if m != nil { + return m.Target + } + return nil +} + +func (m *ExecuteRequest) GetQuery() *BoundQuery { + if m != nil { + return m.Query + } + return nil +} + +func (m *ExecuteRequest) GetTransactionId() int64 { + if m != nil { + return m.TransactionId + } + return 0 +} + +func (m *ExecuteRequest) GetOptions() *ExecuteOptions { + if m != nil { + return m.Options + } + return nil +} + +// ExecuteResponse is the returned value from Execute +type ExecuteResponse struct { + Result *QueryResult `protobuf:"bytes,1,opt,name=result" json:"result,omitempty"` +} + +func (m *ExecuteResponse) Reset() { *m = ExecuteResponse{} } +func (m *ExecuteResponse) String() string { return "TODO" } + + + +func (m *ExecuteResponse) GetResult() *QueryResult { + if m != nil { + return m.Result + } + return nil +} + +// ResultWithError represents a query response +// in the form of result or error but not both. +// TODO: To be used in ExecuteBatchResponse and BeginExecuteBatchResponse. +type ResultWithError struct { + // error contains an query level error, only set if result is unset. + Error *vtrpc.RPCError `protobuf:"bytes,1,opt,name=error" json:"error,omitempty"` + // result contains the query result, only set if error is unset. + Result *QueryResult `protobuf:"bytes,2,opt,name=result" json:"result,omitempty"` +} + +func (m *ResultWithError) Reset() { *m = ResultWithError{} } +func (m *ResultWithError) String() string { return "TODO" } + + + +func (m *ResultWithError) GetError() *vtrpc.RPCError { + if m != nil { + return m.Error + } + return nil +} + +func (m *ResultWithError) GetResult() *QueryResult { + if m != nil { + return m.Result + } + return nil +} + +// ExecuteBatchRequest is the payload to ExecuteBatch +type ExecuteBatchRequest struct { + EffectiveCallerId *vtrpc.CallerID `protobuf:"bytes,1,opt,name=effective_caller_id,json=effectiveCallerId" json:"effective_caller_id,omitempty"` + ImmediateCallerId *VTGateCallerID `protobuf:"bytes,2,opt,name=immediate_caller_id,json=immediateCallerId" json:"immediate_caller_id,omitempty"` + Target *Target `protobuf:"bytes,3,opt,name=target" json:"target,omitempty"` + Queries []*BoundQuery `protobuf:"bytes,4,rep,name=queries" json:"queries,omitempty"` + AsTransaction bool `protobuf:"varint,5,opt,name=as_transaction,json=asTransaction" json:"as_transaction,omitempty"` + TransactionId int64 `protobuf:"varint,6,opt,name=transaction_id,json=transactionId" json:"transaction_id,omitempty"` + Options *ExecuteOptions `protobuf:"bytes,7,opt,name=options" json:"options,omitempty"` +} + +func (m *ExecuteBatchRequest) Reset() { *m = ExecuteBatchRequest{} } +func (m *ExecuteBatchRequest) String() string { return "TODO" } + + + +func (m *ExecuteBatchRequest) GetEffectiveCallerId() *vtrpc.CallerID { + if m != nil { + return m.EffectiveCallerId + } + return nil +} + +func (m *ExecuteBatchRequest) GetImmediateCallerId() *VTGateCallerID { + if m != nil { + return m.ImmediateCallerId + } + return nil +} + +func (m *ExecuteBatchRequest) GetTarget() *Target { + if m != nil { + return m.Target + } + return nil +} + +func (m *ExecuteBatchRequest) GetQueries() []*BoundQuery { + if m != nil { + return m.Queries + } + return nil +} + +func (m *ExecuteBatchRequest) GetAsTransaction() bool { + if m != nil { + return m.AsTransaction + } + return false +} + +func (m *ExecuteBatchRequest) GetTransactionId() int64 { + if m != nil { + return m.TransactionId + } + return 0 +} + +func (m *ExecuteBatchRequest) GetOptions() *ExecuteOptions { + if m != nil { + return m.Options + } + return nil +} + +// ExecuteBatchResponse is the returned value from ExecuteBatch +type ExecuteBatchResponse struct { + Results []*QueryResult `protobuf:"bytes,1,rep,name=results" json:"results,omitempty"` +} + +func (m *ExecuteBatchResponse) Reset() { *m = ExecuteBatchResponse{} } +func (m *ExecuteBatchResponse) String() string { return "TODO" } + + + +func (m *ExecuteBatchResponse) GetResults() []*QueryResult { + if m != nil { + return m.Results + } + return nil +} + +// StreamExecuteRequest is the payload to StreamExecute +type StreamExecuteRequest struct { + EffectiveCallerId *vtrpc.CallerID `protobuf:"bytes,1,opt,name=effective_caller_id,json=effectiveCallerId" json:"effective_caller_id,omitempty"` + ImmediateCallerId *VTGateCallerID `protobuf:"bytes,2,opt,name=immediate_caller_id,json=immediateCallerId" json:"immediate_caller_id,omitempty"` + Target *Target `protobuf:"bytes,3,opt,name=target" json:"target,omitempty"` + Query *BoundQuery `protobuf:"bytes,4,opt,name=query" json:"query,omitempty"` + Options *ExecuteOptions `protobuf:"bytes,5,opt,name=options" json:"options,omitempty"` +} + +func (m *StreamExecuteRequest) Reset() { *m = StreamExecuteRequest{} } +func (m *StreamExecuteRequest) String() string { return "TODO" } + + + +func (m *StreamExecuteRequest) GetEffectiveCallerId() *vtrpc.CallerID { + if m != nil { + return m.EffectiveCallerId + } + return nil +} + +func (m *StreamExecuteRequest) GetImmediateCallerId() *VTGateCallerID { + if m != nil { + return m.ImmediateCallerId + } + return nil +} + +func (m *StreamExecuteRequest) GetTarget() *Target { + if m != nil { + return m.Target + } + return nil +} + +func (m *StreamExecuteRequest) GetQuery() *BoundQuery { + if m != nil { + return m.Query + } + return nil +} + +func (m *StreamExecuteRequest) GetOptions() *ExecuteOptions { + if m != nil { + return m.Options + } + return nil +} + +// StreamExecuteResponse is the returned value from StreamExecute +type StreamExecuteResponse struct { + Result *QueryResult `protobuf:"bytes,1,opt,name=result" json:"result,omitempty"` +} + +func (m *StreamExecuteResponse) Reset() { *m = StreamExecuteResponse{} } +func (m *StreamExecuteResponse) String() string { return "TODO" } + + + +func (m *StreamExecuteResponse) GetResult() *QueryResult { + if m != nil { + return m.Result + } + return nil +} + +// BeginRequest is the payload to Begin +type BeginRequest struct { + EffectiveCallerId *vtrpc.CallerID `protobuf:"bytes,1,opt,name=effective_caller_id,json=effectiveCallerId" json:"effective_caller_id,omitempty"` + ImmediateCallerId *VTGateCallerID `protobuf:"bytes,2,opt,name=immediate_caller_id,json=immediateCallerId" json:"immediate_caller_id,omitempty"` + Target *Target `protobuf:"bytes,3,opt,name=target" json:"target,omitempty"` + Options *ExecuteOptions `protobuf:"bytes,4,opt,name=options" json:"options,omitempty"` +} + +func (m *BeginRequest) Reset() { *m = BeginRequest{} } +func (m *BeginRequest) String() string { return "TODO" } + + + +func (m *BeginRequest) GetEffectiveCallerId() *vtrpc.CallerID { + if m != nil { + return m.EffectiveCallerId + } + return nil +} + +func (m *BeginRequest) GetImmediateCallerId() *VTGateCallerID { + if m != nil { + return m.ImmediateCallerId + } + return nil +} + +func (m *BeginRequest) GetTarget() *Target { + if m != nil { + return m.Target + } + return nil +} + +func (m *BeginRequest) GetOptions() *ExecuteOptions { + if m != nil { + return m.Options + } + return nil +} + +// BeginResponse is the returned value from Begin +type BeginResponse struct { + TransactionId int64 `protobuf:"varint,1,opt,name=transaction_id,json=transactionId" json:"transaction_id,omitempty"` +} + +func (m *BeginResponse) Reset() { *m = BeginResponse{} } +func (m *BeginResponse) String() string { return "TODO" } + + + +func (m *BeginResponse) GetTransactionId() int64 { + if m != nil { + return m.TransactionId + } + return 0 +} + +// CommitRequest is the payload to Commit +type CommitRequest struct { + EffectiveCallerId *vtrpc.CallerID `protobuf:"bytes,1,opt,name=effective_caller_id,json=effectiveCallerId" json:"effective_caller_id,omitempty"` + ImmediateCallerId *VTGateCallerID `protobuf:"bytes,2,opt,name=immediate_caller_id,json=immediateCallerId" json:"immediate_caller_id,omitempty"` + Target *Target `protobuf:"bytes,3,opt,name=target" json:"target,omitempty"` + TransactionId int64 `protobuf:"varint,4,opt,name=transaction_id,json=transactionId" json:"transaction_id,omitempty"` +} + +func (m *CommitRequest) Reset() { *m = CommitRequest{} } +func (m *CommitRequest) String() string { return "TODO" } + + + +func (m *CommitRequest) GetEffectiveCallerId() *vtrpc.CallerID { + if m != nil { + return m.EffectiveCallerId + } + return nil +} + +func (m *CommitRequest) GetImmediateCallerId() *VTGateCallerID { + if m != nil { + return m.ImmediateCallerId + } + return nil +} + +func (m *CommitRequest) GetTarget() *Target { + if m != nil { + return m.Target + } + return nil +} + +func (m *CommitRequest) GetTransactionId() int64 { + if m != nil { + return m.TransactionId + } + return 0 +} + +// CommitResponse is the returned value from Commit +type CommitResponse struct { +} + +func (m *CommitResponse) Reset() { *m = CommitResponse{} } +func (m *CommitResponse) String() string { return "TODO" } + + + +// RollbackRequest is the payload to Rollback +type RollbackRequest struct { + EffectiveCallerId *vtrpc.CallerID `protobuf:"bytes,1,opt,name=effective_caller_id,json=effectiveCallerId" json:"effective_caller_id,omitempty"` + ImmediateCallerId *VTGateCallerID `protobuf:"bytes,2,opt,name=immediate_caller_id,json=immediateCallerId" json:"immediate_caller_id,omitempty"` + Target *Target `protobuf:"bytes,3,opt,name=target" json:"target,omitempty"` + TransactionId int64 `protobuf:"varint,4,opt,name=transaction_id,json=transactionId" json:"transaction_id,omitempty"` +} + +func (m *RollbackRequest) Reset() { *m = RollbackRequest{} } +func (m *RollbackRequest) String() string { return "TODO" } + + + +func (m *RollbackRequest) GetEffectiveCallerId() *vtrpc.CallerID { + if m != nil { + return m.EffectiveCallerId + } + return nil +} + +func (m *RollbackRequest) GetImmediateCallerId() *VTGateCallerID { + if m != nil { + return m.ImmediateCallerId + } + return nil +} + +func (m *RollbackRequest) GetTarget() *Target { + if m != nil { + return m.Target + } + return nil +} + +func (m *RollbackRequest) GetTransactionId() int64 { + if m != nil { + return m.TransactionId + } + return 0 +} + +// RollbackResponse is the returned value from Rollback +type RollbackResponse struct { +} + +func (m *RollbackResponse) Reset() { *m = RollbackResponse{} } +func (m *RollbackResponse) String() string { return "TODO" } + + + +// PrepareRequest is the payload to Prepare +type PrepareRequest struct { + EffectiveCallerId *vtrpc.CallerID `protobuf:"bytes,1,opt,name=effective_caller_id,json=effectiveCallerId" json:"effective_caller_id,omitempty"` + ImmediateCallerId *VTGateCallerID `protobuf:"bytes,2,opt,name=immediate_caller_id,json=immediateCallerId" json:"immediate_caller_id,omitempty"` + Target *Target `protobuf:"bytes,3,opt,name=target" json:"target,omitempty"` + TransactionId int64 `protobuf:"varint,4,opt,name=transaction_id,json=transactionId" json:"transaction_id,omitempty"` + Dtid string `protobuf:"bytes,5,opt,name=dtid" json:"dtid,omitempty"` +} + +func (m *PrepareRequest) Reset() { *m = PrepareRequest{} } +func (m *PrepareRequest) String() string { return "TODO" } + + + +func (m *PrepareRequest) GetEffectiveCallerId() *vtrpc.CallerID { + if m != nil { + return m.EffectiveCallerId + } + return nil +} + +func (m *PrepareRequest) GetImmediateCallerId() *VTGateCallerID { + if m != nil { + return m.ImmediateCallerId + } + return nil +} + +func (m *PrepareRequest) GetTarget() *Target { + if m != nil { + return m.Target + } + return nil +} + +func (m *PrepareRequest) GetTransactionId() int64 { + if m != nil { + return m.TransactionId + } + return 0 +} + +func (m *PrepareRequest) GetDtid() string { + if m != nil { + return m.Dtid + } + return "" +} + +// PrepareResponse is the returned value from Prepare +type PrepareResponse struct { +} + +func (m *PrepareResponse) Reset() { *m = PrepareResponse{} } +func (m *PrepareResponse) String() string { return "TODO" } + + + +// CommitPreparedRequest is the payload to CommitPrepared +type CommitPreparedRequest struct { + EffectiveCallerId *vtrpc.CallerID `protobuf:"bytes,1,opt,name=effective_caller_id,json=effectiveCallerId" json:"effective_caller_id,omitempty"` + ImmediateCallerId *VTGateCallerID `protobuf:"bytes,2,opt,name=immediate_caller_id,json=immediateCallerId" json:"immediate_caller_id,omitempty"` + Target *Target `protobuf:"bytes,3,opt,name=target" json:"target,omitempty"` + Dtid string `protobuf:"bytes,4,opt,name=dtid" json:"dtid,omitempty"` +} + +func (m *CommitPreparedRequest) Reset() { *m = CommitPreparedRequest{} } +func (m *CommitPreparedRequest) String() string { return "TODO" } + + + +func (m *CommitPreparedRequest) GetEffectiveCallerId() *vtrpc.CallerID { + if m != nil { + return m.EffectiveCallerId + } + return nil +} + +func (m *CommitPreparedRequest) GetImmediateCallerId() *VTGateCallerID { + if m != nil { + return m.ImmediateCallerId + } + return nil +} + +func (m *CommitPreparedRequest) GetTarget() *Target { + if m != nil { + return m.Target + } + return nil +} + +func (m *CommitPreparedRequest) GetDtid() string { + if m != nil { + return m.Dtid + } + return "" +} + +// CommitPreparedResponse is the returned value from CommitPrepared +type CommitPreparedResponse struct { +} + +func (m *CommitPreparedResponse) Reset() { *m = CommitPreparedResponse{} } +func (m *CommitPreparedResponse) String() string { return "TODO" } + + + +// RollbackPreparedRequest is the payload to RollbackPrepared +type RollbackPreparedRequest struct { + EffectiveCallerId *vtrpc.CallerID `protobuf:"bytes,1,opt,name=effective_caller_id,json=effectiveCallerId" json:"effective_caller_id,omitempty"` + ImmediateCallerId *VTGateCallerID `protobuf:"bytes,2,opt,name=immediate_caller_id,json=immediateCallerId" json:"immediate_caller_id,omitempty"` + Target *Target `protobuf:"bytes,3,opt,name=target" json:"target,omitempty"` + TransactionId int64 `protobuf:"varint,4,opt,name=transaction_id,json=transactionId" json:"transaction_id,omitempty"` + Dtid string `protobuf:"bytes,5,opt,name=dtid" json:"dtid,omitempty"` +} + +func (m *RollbackPreparedRequest) Reset() { *m = RollbackPreparedRequest{} } +func (m *RollbackPreparedRequest) String() string { return "TODO" } + + + +func (m *RollbackPreparedRequest) GetEffectiveCallerId() *vtrpc.CallerID { + if m != nil { + return m.EffectiveCallerId + } + return nil +} + +func (m *RollbackPreparedRequest) GetImmediateCallerId() *VTGateCallerID { + if m != nil { + return m.ImmediateCallerId + } + return nil +} + +func (m *RollbackPreparedRequest) GetTarget() *Target { + if m != nil { + return m.Target + } + return nil +} + +func (m *RollbackPreparedRequest) GetTransactionId() int64 { + if m != nil { + return m.TransactionId + } + return 0 +} + +func (m *RollbackPreparedRequest) GetDtid() string { + if m != nil { + return m.Dtid + } + return "" +} + +// RollbackPreparedResponse is the returned value from RollbackPrepared +type RollbackPreparedResponse struct { +} + +func (m *RollbackPreparedResponse) Reset() { *m = RollbackPreparedResponse{} } +func (m *RollbackPreparedResponse) String() string { return "TODO" } + + + +// CreateTransactionRequest is the payload to CreateTransaction +type CreateTransactionRequest struct { + EffectiveCallerId *vtrpc.CallerID `protobuf:"bytes,1,opt,name=effective_caller_id,json=effectiveCallerId" json:"effective_caller_id,omitempty"` + ImmediateCallerId *VTGateCallerID `protobuf:"bytes,2,opt,name=immediate_caller_id,json=immediateCallerId" json:"immediate_caller_id,omitempty"` + Target *Target `protobuf:"bytes,3,opt,name=target" json:"target,omitempty"` + Dtid string `protobuf:"bytes,4,opt,name=dtid" json:"dtid,omitempty"` + Participants []*Target `protobuf:"bytes,5,rep,name=participants" json:"participants,omitempty"` +} + +func (m *CreateTransactionRequest) Reset() { *m = CreateTransactionRequest{} } +func (m *CreateTransactionRequest) String() string { return "TODO" } + + + +func (m *CreateTransactionRequest) GetEffectiveCallerId() *vtrpc.CallerID { + if m != nil { + return m.EffectiveCallerId + } + return nil +} + +func (m *CreateTransactionRequest) GetImmediateCallerId() *VTGateCallerID { + if m != nil { + return m.ImmediateCallerId + } + return nil +} + +func (m *CreateTransactionRequest) GetTarget() *Target { + if m != nil { + return m.Target + } + return nil +} + +func (m *CreateTransactionRequest) GetDtid() string { + if m != nil { + return m.Dtid + } + return "" +} + +func (m *CreateTransactionRequest) GetParticipants() []*Target { + if m != nil { + return m.Participants + } + return nil +} + +// CreateTransactionResponse is the returned value from CreateTransaction +type CreateTransactionResponse struct { +} + +func (m *CreateTransactionResponse) Reset() { *m = CreateTransactionResponse{} } +func (m *CreateTransactionResponse) String() string { return "TODO" } + + + +// StartCommitRequest is the payload to StartCommit +type StartCommitRequest struct { + EffectiveCallerId *vtrpc.CallerID `protobuf:"bytes,1,opt,name=effective_caller_id,json=effectiveCallerId" json:"effective_caller_id,omitempty"` + ImmediateCallerId *VTGateCallerID `protobuf:"bytes,2,opt,name=immediate_caller_id,json=immediateCallerId" json:"immediate_caller_id,omitempty"` + Target *Target `protobuf:"bytes,3,opt,name=target" json:"target,omitempty"` + TransactionId int64 `protobuf:"varint,4,opt,name=transaction_id,json=transactionId" json:"transaction_id,omitempty"` + Dtid string `protobuf:"bytes,5,opt,name=dtid" json:"dtid,omitempty"` +} + +func (m *StartCommitRequest) Reset() { *m = StartCommitRequest{} } +func (m *StartCommitRequest) String() string { return "TODO" } + + + +func (m *StartCommitRequest) GetEffectiveCallerId() *vtrpc.CallerID { + if m != nil { + return m.EffectiveCallerId + } + return nil +} + +func (m *StartCommitRequest) GetImmediateCallerId() *VTGateCallerID { + if m != nil { + return m.ImmediateCallerId + } + return nil +} + +func (m *StartCommitRequest) GetTarget() *Target { + if m != nil { + return m.Target + } + return nil +} + +func (m *StartCommitRequest) GetTransactionId() int64 { + if m != nil { + return m.TransactionId + } + return 0 +} + +func (m *StartCommitRequest) GetDtid() string { + if m != nil { + return m.Dtid + } + return "" +} + +// StartCommitResponse is the returned value from StartCommit +type StartCommitResponse struct { +} + +func (m *StartCommitResponse) Reset() { *m = StartCommitResponse{} } +func (m *StartCommitResponse) String() string { return "TODO" } + + + +// SetRollbackRequest is the payload to SetRollback +type SetRollbackRequest struct { + EffectiveCallerId *vtrpc.CallerID `protobuf:"bytes,1,opt,name=effective_caller_id,json=effectiveCallerId" json:"effective_caller_id,omitempty"` + ImmediateCallerId *VTGateCallerID `protobuf:"bytes,2,opt,name=immediate_caller_id,json=immediateCallerId" json:"immediate_caller_id,omitempty"` + Target *Target `protobuf:"bytes,3,opt,name=target" json:"target,omitempty"` + TransactionId int64 `protobuf:"varint,4,opt,name=transaction_id,json=transactionId" json:"transaction_id,omitempty"` + Dtid string `protobuf:"bytes,5,opt,name=dtid" json:"dtid,omitempty"` +} + +func (m *SetRollbackRequest) Reset() { *m = SetRollbackRequest{} } +func (m *SetRollbackRequest) String() string { return "TODO" } + + + +func (m *SetRollbackRequest) GetEffectiveCallerId() *vtrpc.CallerID { + if m != nil { + return m.EffectiveCallerId + } + return nil +} + +func (m *SetRollbackRequest) GetImmediateCallerId() *VTGateCallerID { + if m != nil { + return m.ImmediateCallerId + } + return nil +} + +func (m *SetRollbackRequest) GetTarget() *Target { + if m != nil { + return m.Target + } + return nil +} + +func (m *SetRollbackRequest) GetTransactionId() int64 { + if m != nil { + return m.TransactionId + } + return 0 +} + +func (m *SetRollbackRequest) GetDtid() string { + if m != nil { + return m.Dtid + } + return "" +} + +// SetRollbackResponse is the returned value from SetRollback +type SetRollbackResponse struct { +} + +func (m *SetRollbackResponse) Reset() { *m = SetRollbackResponse{} } +func (m *SetRollbackResponse) String() string { return "TODO" } + + + +// ConcludeTransactionRequest is the payload to ConcludeTransaction +type ConcludeTransactionRequest struct { + EffectiveCallerId *vtrpc.CallerID `protobuf:"bytes,1,opt,name=effective_caller_id,json=effectiveCallerId" json:"effective_caller_id,omitempty"` + ImmediateCallerId *VTGateCallerID `protobuf:"bytes,2,opt,name=immediate_caller_id,json=immediateCallerId" json:"immediate_caller_id,omitempty"` + Target *Target `protobuf:"bytes,3,opt,name=target" json:"target,omitempty"` + Dtid string `protobuf:"bytes,4,opt,name=dtid" json:"dtid,omitempty"` +} + +func (m *ConcludeTransactionRequest) Reset() { *m = ConcludeTransactionRequest{} } +func (m *ConcludeTransactionRequest) String() string { return "TODO" } + + + +func (m *ConcludeTransactionRequest) GetEffectiveCallerId() *vtrpc.CallerID { + if m != nil { + return m.EffectiveCallerId + } + return nil +} + +func (m *ConcludeTransactionRequest) GetImmediateCallerId() *VTGateCallerID { + if m != nil { + return m.ImmediateCallerId + } + return nil +} + +func (m *ConcludeTransactionRequest) GetTarget() *Target { + if m != nil { + return m.Target + } + return nil +} + +func (m *ConcludeTransactionRequest) GetDtid() string { + if m != nil { + return m.Dtid + } + return "" +} + +// ConcludeTransactionResponse is the returned value from ConcludeTransaction +type ConcludeTransactionResponse struct { +} + +func (m *ConcludeTransactionResponse) Reset() { *m = ConcludeTransactionResponse{} } +func (m *ConcludeTransactionResponse) String() string { return "TODO" } + + + +// ReadTransactionRequest is the payload to ReadTransaction +type ReadTransactionRequest struct { + EffectiveCallerId *vtrpc.CallerID `protobuf:"bytes,1,opt,name=effective_caller_id,json=effectiveCallerId" json:"effective_caller_id,omitempty"` + ImmediateCallerId *VTGateCallerID `protobuf:"bytes,2,opt,name=immediate_caller_id,json=immediateCallerId" json:"immediate_caller_id,omitempty"` + Target *Target `protobuf:"bytes,3,opt,name=target" json:"target,omitempty"` + Dtid string `protobuf:"bytes,4,opt,name=dtid" json:"dtid,omitempty"` +} + +func (m *ReadTransactionRequest) Reset() { *m = ReadTransactionRequest{} } +func (m *ReadTransactionRequest) String() string { return "TODO" } + + + +func (m *ReadTransactionRequest) GetEffectiveCallerId() *vtrpc.CallerID { + if m != nil { + return m.EffectiveCallerId + } + return nil +} + +func (m *ReadTransactionRequest) GetImmediateCallerId() *VTGateCallerID { + if m != nil { + return m.ImmediateCallerId + } + return nil +} + +func (m *ReadTransactionRequest) GetTarget() *Target { + if m != nil { + return m.Target + } + return nil +} + +func (m *ReadTransactionRequest) GetDtid() string { + if m != nil { + return m.Dtid + } + return "" +} + +// ReadTransactionResponse is the returned value from ReadTransaction +type ReadTransactionResponse struct { + Metadata *TransactionMetadata `protobuf:"bytes,1,opt,name=metadata" json:"metadata,omitempty"` +} + +func (m *ReadTransactionResponse) Reset() { *m = ReadTransactionResponse{} } +func (m *ReadTransactionResponse) String() string { return "TODO" } + + + +func (m *ReadTransactionResponse) GetMetadata() *TransactionMetadata { + if m != nil { + return m.Metadata + } + return nil +} + +// BeginExecuteRequest is the payload to BeginExecute +type BeginExecuteRequest struct { + EffectiveCallerId *vtrpc.CallerID `protobuf:"bytes,1,opt,name=effective_caller_id,json=effectiveCallerId" json:"effective_caller_id,omitempty"` + ImmediateCallerId *VTGateCallerID `protobuf:"bytes,2,opt,name=immediate_caller_id,json=immediateCallerId" json:"immediate_caller_id,omitempty"` + Target *Target `protobuf:"bytes,3,opt,name=target" json:"target,omitempty"` + Query *BoundQuery `protobuf:"bytes,4,opt,name=query" json:"query,omitempty"` + Options *ExecuteOptions `protobuf:"bytes,5,opt,name=options" json:"options,omitempty"` +} + +func (m *BeginExecuteRequest) Reset() { *m = BeginExecuteRequest{} } +func (m *BeginExecuteRequest) String() string { return "TODO" } + + + +func (m *BeginExecuteRequest) GetEffectiveCallerId() *vtrpc.CallerID { + if m != nil { + return m.EffectiveCallerId + } + return nil +} + +func (m *BeginExecuteRequest) GetImmediateCallerId() *VTGateCallerID { + if m != nil { + return m.ImmediateCallerId + } + return nil +} + +func (m *BeginExecuteRequest) GetTarget() *Target { + if m != nil { + return m.Target + } + return nil +} + +func (m *BeginExecuteRequest) GetQuery() *BoundQuery { + if m != nil { + return m.Query + } + return nil +} + +func (m *BeginExecuteRequest) GetOptions() *ExecuteOptions { + if m != nil { + return m.Options + } + return nil +} + +// BeginExecuteResponse is the returned value from BeginExecute +type BeginExecuteResponse struct { + // error contains an application level error if necessary. Note the + // transaction_id may be set, even when an error is returned, if the begin + // worked but the execute failed. + Error *vtrpc.RPCError `protobuf:"bytes,1,opt,name=error" json:"error,omitempty"` + Result *QueryResult `protobuf:"bytes,2,opt,name=result" json:"result,omitempty"` + // transaction_id might be non-zero even if an error is present. + TransactionId int64 `protobuf:"varint,3,opt,name=transaction_id,json=transactionId" json:"transaction_id,omitempty"` +} + +func (m *BeginExecuteResponse) Reset() { *m = BeginExecuteResponse{} } +func (m *BeginExecuteResponse) String() string { return "TODO" } + + + +func (m *BeginExecuteResponse) GetError() *vtrpc.RPCError { + if m != nil { + return m.Error + } + return nil +} + +func (m *BeginExecuteResponse) GetResult() *QueryResult { + if m != nil { + return m.Result + } + return nil +} + +func (m *BeginExecuteResponse) GetTransactionId() int64 { + if m != nil { + return m.TransactionId + } + return 0 +} + +// BeginExecuteBatchRequest is the payload to BeginExecuteBatch +type BeginExecuteBatchRequest struct { + EffectiveCallerId *vtrpc.CallerID `protobuf:"bytes,1,opt,name=effective_caller_id,json=effectiveCallerId" json:"effective_caller_id,omitempty"` + ImmediateCallerId *VTGateCallerID `protobuf:"bytes,2,opt,name=immediate_caller_id,json=immediateCallerId" json:"immediate_caller_id,omitempty"` + Target *Target `protobuf:"bytes,3,opt,name=target" json:"target,omitempty"` + Queries []*BoundQuery `protobuf:"bytes,4,rep,name=queries" json:"queries,omitempty"` + AsTransaction bool `protobuf:"varint,5,opt,name=as_transaction,json=asTransaction" json:"as_transaction,omitempty"` + Options *ExecuteOptions `protobuf:"bytes,6,opt,name=options" json:"options,omitempty"` +} + +func (m *BeginExecuteBatchRequest) Reset() { *m = BeginExecuteBatchRequest{} } +func (m *BeginExecuteBatchRequest) String() string { return "TODO" } + + + +func (m *BeginExecuteBatchRequest) GetEffectiveCallerId() *vtrpc.CallerID { + if m != nil { + return m.EffectiveCallerId + } + return nil +} + +func (m *BeginExecuteBatchRequest) GetImmediateCallerId() *VTGateCallerID { + if m != nil { + return m.ImmediateCallerId + } + return nil +} + +func (m *BeginExecuteBatchRequest) GetTarget() *Target { + if m != nil { + return m.Target + } + return nil +} + +func (m *BeginExecuteBatchRequest) GetQueries() []*BoundQuery { + if m != nil { + return m.Queries + } + return nil +} + +func (m *BeginExecuteBatchRequest) GetAsTransaction() bool { + if m != nil { + return m.AsTransaction + } + return false +} + +func (m *BeginExecuteBatchRequest) GetOptions() *ExecuteOptions { + if m != nil { + return m.Options + } + return nil +} + +// BeginExecuteBatchResponse is the returned value from BeginExecuteBatch +type BeginExecuteBatchResponse struct { + // error contains an application level error if necessary. Note the + // transaction_id may be set, even when an error is returned, if the begin + // worked but the execute failed. + Error *vtrpc.RPCError `protobuf:"bytes,1,opt,name=error" json:"error,omitempty"` + Results []*QueryResult `protobuf:"bytes,2,rep,name=results" json:"results,omitempty"` + // transaction_id might be non-zero even if an error is present. + TransactionId int64 `protobuf:"varint,3,opt,name=transaction_id,json=transactionId" json:"transaction_id,omitempty"` +} + +func (m *BeginExecuteBatchResponse) Reset() { *m = BeginExecuteBatchResponse{} } +func (m *BeginExecuteBatchResponse) String() string { return "TODO" } + + + +func (m *BeginExecuteBatchResponse) GetError() *vtrpc.RPCError { + if m != nil { + return m.Error + } + return nil +} + +func (m *BeginExecuteBatchResponse) GetResults() []*QueryResult { + if m != nil { + return m.Results + } + return nil +} + +func (m *BeginExecuteBatchResponse) GetTransactionId() int64 { + if m != nil { + return m.TransactionId + } + return 0 +} + +// MessageStreamRequest is the request payload for MessageStream. +type MessageStreamRequest struct { + EffectiveCallerId *vtrpc.CallerID `protobuf:"bytes,1,opt,name=effective_caller_id,json=effectiveCallerId" json:"effective_caller_id,omitempty"` + ImmediateCallerId *VTGateCallerID `protobuf:"bytes,2,opt,name=immediate_caller_id,json=immediateCallerId" json:"immediate_caller_id,omitempty"` + Target *Target `protobuf:"bytes,3,opt,name=target" json:"target,omitempty"` + // name is the message table name. + Name string `protobuf:"bytes,4,opt,name=name" json:"name,omitempty"` +} + +func (m *MessageStreamRequest) Reset() { *m = MessageStreamRequest{} } +func (m *MessageStreamRequest) String() string { return "TODO" } + + + +func (m *MessageStreamRequest) GetEffectiveCallerId() *vtrpc.CallerID { + if m != nil { + return m.EffectiveCallerId + } + return nil +} + +func (m *MessageStreamRequest) GetImmediateCallerId() *VTGateCallerID { + if m != nil { + return m.ImmediateCallerId + } + return nil +} + +func (m *MessageStreamRequest) GetTarget() *Target { + if m != nil { + return m.Target + } + return nil +} + +func (m *MessageStreamRequest) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +// MessageStreamResponse is a response for MessageStream. +type MessageStreamResponse struct { + Result *QueryResult `protobuf:"bytes,1,opt,name=result" json:"result,omitempty"` +} + +func (m *MessageStreamResponse) Reset() { *m = MessageStreamResponse{} } +func (m *MessageStreamResponse) String() string { return "TODO" } + + + +func (m *MessageStreamResponse) GetResult() *QueryResult { + if m != nil { + return m.Result + } + return nil +} + +// MessageAckRequest is the request payload for MessageAck. +type MessageAckRequest struct { + EffectiveCallerId *vtrpc.CallerID `protobuf:"bytes,1,opt,name=effective_caller_id,json=effectiveCallerId" json:"effective_caller_id,omitempty"` + ImmediateCallerId *VTGateCallerID `protobuf:"bytes,2,opt,name=immediate_caller_id,json=immediateCallerId" json:"immediate_caller_id,omitempty"` + Target *Target `protobuf:"bytes,3,opt,name=target" json:"target,omitempty"` + // name is the message table name. + Name string `protobuf:"bytes,4,opt,name=name" json:"name,omitempty"` + Ids []*Value `protobuf:"bytes,5,rep,name=ids" json:"ids,omitempty"` +} + +func (m *MessageAckRequest) Reset() { *m = MessageAckRequest{} } +func (m *MessageAckRequest) String() string { return "TODO" } + + + +func (m *MessageAckRequest) GetEffectiveCallerId() *vtrpc.CallerID { + if m != nil { + return m.EffectiveCallerId + } + return nil +} + +func (m *MessageAckRequest) GetImmediateCallerId() *VTGateCallerID { + if m != nil { + return m.ImmediateCallerId + } + return nil +} + +func (m *MessageAckRequest) GetTarget() *Target { + if m != nil { + return m.Target + } + return nil +} + +func (m *MessageAckRequest) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +func (m *MessageAckRequest) GetIds() []*Value { + if m != nil { + return m.Ids + } + return nil +} + +// MessageAckResponse is the response for MessageAck. +type MessageAckResponse struct { + // result contains the result of the ack operation. + // Since this acts like a DML, only + // RowsAffected is returned in the result. + Result *QueryResult `protobuf:"bytes,1,opt,name=result" json:"result,omitempty"` +} + +func (m *MessageAckResponse) Reset() { *m = MessageAckResponse{} } +func (m *MessageAckResponse) String() string { return "TODO" } + + + +func (m *MessageAckResponse) GetResult() *QueryResult { + if m != nil { + return m.Result + } + return nil +} + +// SplitQueryRequest is the payload for SplitQuery sent by VTGate to a VTTablet. +// See vtgate.SplitQueryRequest for more details. +type SplitQueryRequest struct { + EffectiveCallerId *vtrpc.CallerID `protobuf:"bytes,1,opt,name=effective_caller_id,json=effectiveCallerId" json:"effective_caller_id,omitempty"` + ImmediateCallerId *VTGateCallerID `protobuf:"bytes,2,opt,name=immediate_caller_id,json=immediateCallerId" json:"immediate_caller_id,omitempty"` + Target *Target `protobuf:"bytes,3,opt,name=target" json:"target,omitempty"` + Query *BoundQuery `protobuf:"bytes,4,opt,name=query" json:"query,omitempty"` + SplitColumn []string `protobuf:"bytes,5,rep,name=split_column,json=splitColumn" json:"split_column,omitempty"` + // Exactly one of the following must be nonzero. + SplitCount int64 `protobuf:"varint,6,opt,name=split_count,json=splitCount" json:"split_count,omitempty"` + NumRowsPerQueryPart int64 `protobuf:"varint,8,opt,name=num_rows_per_query_part,json=numRowsPerQueryPart" json:"num_rows_per_query_part,omitempty"` + Algorithm SplitQueryRequest_Algorithm `protobuf:"varint,9,opt,name=algorithm,enum=query.SplitQueryRequest_Algorithm" json:"algorithm,omitempty"` +} + +func (m *SplitQueryRequest) Reset() { *m = SplitQueryRequest{} } +func (m *SplitQueryRequest) String() string { return "TODO" } + + + +func (m *SplitQueryRequest) GetEffectiveCallerId() *vtrpc.CallerID { + if m != nil { + return m.EffectiveCallerId + } + return nil +} + +func (m *SplitQueryRequest) GetImmediateCallerId() *VTGateCallerID { + if m != nil { + return m.ImmediateCallerId + } + return nil +} + +func (m *SplitQueryRequest) GetTarget() *Target { + if m != nil { + return m.Target + } + return nil +} + +func (m *SplitQueryRequest) GetQuery() *BoundQuery { + if m != nil { + return m.Query + } + return nil +} + +func (m *SplitQueryRequest) GetSplitColumn() []string { + if m != nil { + return m.SplitColumn + } + return nil +} + +func (m *SplitQueryRequest) GetSplitCount() int64 { + if m != nil { + return m.SplitCount + } + return 0 +} + +func (m *SplitQueryRequest) GetNumRowsPerQueryPart() int64 { + if m != nil { + return m.NumRowsPerQueryPart + } + return 0 +} + +func (m *SplitQueryRequest) GetAlgorithm() SplitQueryRequest_Algorithm { + if m != nil { + return m.Algorithm + } + return SplitQueryRequest_EQUAL_SPLITS +} + +// QuerySplit represents one query to execute on the tablet +type QuerySplit struct { + // query is the query to execute + Query *BoundQuery `protobuf:"bytes,1,opt,name=query" json:"query,omitempty"` + // row_count is the approximate row count the query will return + RowCount int64 `protobuf:"varint,2,opt,name=row_count,json=rowCount" json:"row_count,omitempty"` +} + +func (m *QuerySplit) Reset() { *m = QuerySplit{} } +func (m *QuerySplit) String() string { return "TODO" } + + + +func (m *QuerySplit) GetQuery() *BoundQuery { + if m != nil { + return m.Query + } + return nil +} + +func (m *QuerySplit) GetRowCount() int64 { + if m != nil { + return m.RowCount + } + return 0 +} + +// SplitQueryResponse is returned by SplitQuery and represents all the queries +// to execute in order to get the entire data set. +type SplitQueryResponse struct { + Queries []*QuerySplit `protobuf:"bytes,1,rep,name=queries" json:"queries,omitempty"` +} + +func (m *SplitQueryResponse) Reset() { *m = SplitQueryResponse{} } +func (m *SplitQueryResponse) String() string { return "TODO" } + + + +func (m *SplitQueryResponse) GetQueries() []*QuerySplit { + if m != nil { + return m.Queries + } + return nil +} + +// StreamHealthRequest is the payload for StreamHealth +type StreamHealthRequest struct { +} + +func (m *StreamHealthRequest) Reset() { *m = StreamHealthRequest{} } +func (m *StreamHealthRequest) String() string { return "TODO" } + + + +// RealtimeStats contains information about the tablet status +type RealtimeStats struct { + // health_error is the last error we got from health check, + // or empty is the server is healthy. This is used for subset selection, + // we do not send queries to servers that are not healthy. + HealthError string `protobuf:"bytes,1,opt,name=health_error,json=healthError" json:"health_error,omitempty"` + // seconds_behind_master is populated for slaves only. It indicates + // how far behind on (MySQL) replication a slave currently is. It is used + // by clients for subset selection (so we don't try to send traffic + // to tablets that are too far behind). + // NOTE: This field must not be evaluated if "health_error" is not empty. + // TODO(mberlin): Let's switch it to int64 instead? + SecondsBehindMaster uint32 `protobuf:"varint,2,opt,name=seconds_behind_master,json=secondsBehindMaster" json:"seconds_behind_master,omitempty"` + // bin_log_players_count is the number of currently running binlog players. + // if the value is 0, it means that filtered replication is currently not + // running on the tablet. If >0, filtered replication is running. + // NOTE: This field must not be evaluated if "health_error" is not empty. + BinlogPlayersCount int32 `protobuf:"varint,3,opt,name=binlog_players_count,json=binlogPlayersCount" json:"binlog_players_count,omitempty"` + // seconds_behind_master_filtered_replication is populated for the receiving + // master of an ongoing filtered replication only. + // It specifies how far the receiving master lags behind the sending master. + // NOTE: This field must not be evaluated if "health_error" is not empty. + // NOTE: This field must not be evaluated if "bin_log_players_count" is 0. + SecondsBehindMasterFilteredReplication int64 `protobuf:"varint,4,opt,name=seconds_behind_master_filtered_replication,json=secondsBehindMasterFilteredReplication" json:"seconds_behind_master_filtered_replication,omitempty"` + // cpu_usage is used for load-based balancing + CpuUsage float64 `protobuf:"fixed64,5,opt,name=cpu_usage,json=cpuUsage" json:"cpu_usage,omitempty"` + // qps is the average QPS (queries per second) rate in the last XX seconds + // where XX is usually 60 (See query_service_stats.go). + Qps float64 `protobuf:"fixed64,6,opt,name=qps" json:"qps,omitempty"` +} + +func (m *RealtimeStats) Reset() { *m = RealtimeStats{} } +func (m *RealtimeStats) String() string { return "TODO" } + + + +func (m *RealtimeStats) GetHealthError() string { + if m != nil { + return m.HealthError + } + return "" +} + +func (m *RealtimeStats) GetSecondsBehindMaster() uint32 { + if m != nil { + return m.SecondsBehindMaster + } + return 0 +} + +func (m *RealtimeStats) GetBinlogPlayersCount() int32 { + if m != nil { + return m.BinlogPlayersCount + } + return 0 +} + +func (m *RealtimeStats) GetSecondsBehindMasterFilteredReplication() int64 { + if m != nil { + return m.SecondsBehindMasterFilteredReplication + } + return 0 +} + +func (m *RealtimeStats) GetCpuUsage() float64 { + if m != nil { + return m.CpuUsage + } + return 0 +} + +func (m *RealtimeStats) GetQps() float64 { + if m != nil { + return m.Qps + } + return 0 +} + +// StreamHealthResponse is streamed by StreamHealth on a regular basis +type StreamHealthResponse struct { + // target is the current server type. Only queries with that exact Target + // record will be accepted. + Target *Target `protobuf:"bytes,1,opt,name=target" json:"target,omitempty"` + // serving is true iff the tablet is serving. A tablet may not be serving + // if filtered replication is enabled on a master for instance, + // or if a replica should not be used because the keyspace is being resharded. + Serving bool `protobuf:"varint,2,opt,name=serving" json:"serving,omitempty"` + // tablet_externally_reparented_timestamp can be interpreted as the last time + // we knew that this tablet was the MASTER of this shard. + // + // It is used by vtgate when determining the current MASTER of a shard. + // If vtgate sees more than one MASTER tablet, this timestamp is used + // as tiebreaker where the MASTER with the highest timestamp wins. + // Another usage of this timestamp is in go/vt/vtgate/buffer to detect the end + // of a reparent (failover) and stop buffering. + // + // In practice, this field is set to: + // a) the last time the RPC tabletmanager.TabletExternallyReparented was + // called on this tablet (usually done by an external failover tool e.g. + // Orchestrator). The failover tool can call this as long as we are the + // master i.e. even ages after the last reparent occurred. + // OR + // b) the last time an active reparent was executed through a vtctl command + // (InitShardMaster, PlannedReparentShard, EmergencyReparentShard) + // OR + // c) the last time vttablet was started and it initialized its tablet type + // as MASTER because it was recorded as the shard's current master in the + // topology (see go/vt/vttablet/tabletmanager/init_tablet.go) + // OR + // d) 0 if the vttablet was never a MASTER. + TabletExternallyReparentedTimestamp int64 `protobuf:"varint,3,opt,name=tablet_externally_reparented_timestamp,json=tabletExternallyReparentedTimestamp" json:"tablet_externally_reparented_timestamp,omitempty"` + // realtime_stats contains information about the tablet status + RealtimeStats *RealtimeStats `protobuf:"bytes,4,opt,name=realtime_stats,json=realtimeStats" json:"realtime_stats,omitempty"` + // tablet_alias is the alias of the sending tablet. The discovery/healthcheck.go + // code uses it to verify that it's talking to the correct tablet and that it + // hasn't changed in the meantime e.g. due to tablet restarts where ports or + // ips have been reused but assigned differently. + TabletAlias *topodata.TabletAlias `protobuf:"bytes,5,opt,name=tablet_alias,json=tabletAlias" json:"tablet_alias,omitempty"` +} + +func (m *StreamHealthResponse) Reset() { *m = StreamHealthResponse{} } +func (m *StreamHealthResponse) String() string { return "TODO" } + + + +func (m *StreamHealthResponse) GetTarget() *Target { + if m != nil { + return m.Target + } + return nil +} + +func (m *StreamHealthResponse) GetServing() bool { + if m != nil { + return m.Serving + } + return false +} + +func (m *StreamHealthResponse) GetTabletExternallyReparentedTimestamp() int64 { + if m != nil { + return m.TabletExternallyReparentedTimestamp + } + return 0 +} + +func (m *StreamHealthResponse) GetRealtimeStats() *RealtimeStats { + if m != nil { + return m.RealtimeStats + } + return nil +} + +func (m *StreamHealthResponse) GetTabletAlias() *topodata.TabletAlias { + if m != nil { + return m.TabletAlias + } + return nil +} + +// UpdateStreamRequest is the payload for UpdateStream. At most one of +// position and timestamp can be set. If neither is set, we will start +// streaming from the current binlog position. +type UpdateStreamRequest struct { + EffectiveCallerId *vtrpc.CallerID `protobuf:"bytes,1,opt,name=effective_caller_id,json=effectiveCallerId" json:"effective_caller_id,omitempty"` + ImmediateCallerId *VTGateCallerID `protobuf:"bytes,2,opt,name=immediate_caller_id,json=immediateCallerId" json:"immediate_caller_id,omitempty"` + Target *Target `protobuf:"bytes,3,opt,name=target" json:"target,omitempty"` + // If position is set, we will start the streaming from that replication + // position. Incompatible with timestamp. + Position string `protobuf:"bytes,4,opt,name=position" json:"position,omitempty"` + // If timestamp is set, we will start the streaming from the first + // event in the binlogs that have that timestamp. Incompatible with position. + Timestamp int64 `protobuf:"varint,5,opt,name=timestamp" json:"timestamp,omitempty"` +} + +func (m *UpdateStreamRequest) Reset() { *m = UpdateStreamRequest{} } +func (m *UpdateStreamRequest) String() string { return "TODO" } + + + +func (m *UpdateStreamRequest) GetEffectiveCallerId() *vtrpc.CallerID { + if m != nil { + return m.EffectiveCallerId + } + return nil +} + +func (m *UpdateStreamRequest) GetImmediateCallerId() *VTGateCallerID { + if m != nil { + return m.ImmediateCallerId + } + return nil +} + +func (m *UpdateStreamRequest) GetTarget() *Target { + if m != nil { + return m.Target + } + return nil +} + +func (m *UpdateStreamRequest) GetPosition() string { + if m != nil { + return m.Position + } + return "" +} + +func (m *UpdateStreamRequest) GetTimestamp() int64 { + if m != nil { + return m.Timestamp + } + return 0 +} + +// UpdateStreamResponse is returned by UpdateStream +type UpdateStreamResponse struct { + Event *StreamEvent `protobuf:"bytes,1,opt,name=event" json:"event,omitempty"` +} + +func (m *UpdateStreamResponse) Reset() { *m = UpdateStreamResponse{} } +func (m *UpdateStreamResponse) String() string { return "TODO" } + + + +func (m *UpdateStreamResponse) GetEvent() *StreamEvent { + if m != nil { + return m.Event + } + return nil +} + +// TransactionMetadata contains the metadata for a distributed transaction. +type TransactionMetadata struct { + Dtid string `protobuf:"bytes,1,opt,name=dtid" json:"dtid,omitempty"` + State TransactionState `protobuf:"varint,2,opt,name=state,enum=query.TransactionState" json:"state,omitempty"` + TimeCreated int64 `protobuf:"varint,3,opt,name=time_created,json=timeCreated" json:"time_created,omitempty"` + Participants []*Target `protobuf:"bytes,4,rep,name=participants" json:"participants,omitempty"` +} + +func (m *TransactionMetadata) Reset() { *m = TransactionMetadata{} } +func (m *TransactionMetadata) String() string { return "TODO" } + + + +func (m *TransactionMetadata) GetDtid() string { + if m != nil { + return m.Dtid + } + return "" +} + +func (m *TransactionMetadata) GetState() TransactionState { + if m != nil { + return m.State + } + return TransactionState_UNKNOWN +} + +func (m *TransactionMetadata) GetTimeCreated() int64 { + if m != nil { + return m.TimeCreated + } + return 0 +} + +func (m *TransactionMetadata) GetParticipants() []*Target { + if m != nil { + return m.Participants + } + return nil +} + +func init() { + proto.RegisterType((*Target)(nil), "query.Target") + proto.RegisterType((*VTGateCallerID)(nil), "query.VTGateCallerID") + proto.RegisterType((*EventToken)(nil), "query.EventToken") + proto.RegisterType((*Value)(nil), "query.Value") + proto.RegisterType((*BindVariable)(nil), "query.BindVariable") + proto.RegisterType((*BoundQuery)(nil), "query.BoundQuery") + proto.RegisterType((*ExecuteOptions)(nil), "query.ExecuteOptions") + proto.RegisterType((*Field)(nil), "query.Field") + proto.RegisterType((*Row)(nil), "query.Row") + proto.RegisterType((*ResultExtras)(nil), "query.ResultExtras") + proto.RegisterType((*QueryResult)(nil), "query.QueryResult") + proto.RegisterType((*StreamEvent)(nil), "query.StreamEvent") + proto.RegisterType((*StreamEvent_Statement)(nil), "query.StreamEvent.Statement") + proto.RegisterType((*ExecuteRequest)(nil), "query.ExecuteRequest") + proto.RegisterType((*ExecuteResponse)(nil), "query.ExecuteResponse") + proto.RegisterType((*ResultWithError)(nil), "query.ResultWithError") + proto.RegisterType((*ExecuteBatchRequest)(nil), "query.ExecuteBatchRequest") + proto.RegisterType((*ExecuteBatchResponse)(nil), "query.ExecuteBatchResponse") + proto.RegisterType((*StreamExecuteRequest)(nil), "query.StreamExecuteRequest") + proto.RegisterType((*StreamExecuteResponse)(nil), "query.StreamExecuteResponse") + proto.RegisterType((*BeginRequest)(nil), "query.BeginRequest") + proto.RegisterType((*BeginResponse)(nil), "query.BeginResponse") + proto.RegisterType((*CommitRequest)(nil), "query.CommitRequest") + proto.RegisterType((*CommitResponse)(nil), "query.CommitResponse") + proto.RegisterType((*RollbackRequest)(nil), "query.RollbackRequest") + proto.RegisterType((*RollbackResponse)(nil), "query.RollbackResponse") + proto.RegisterType((*PrepareRequest)(nil), "query.PrepareRequest") + proto.RegisterType((*PrepareResponse)(nil), "query.PrepareResponse") + proto.RegisterType((*CommitPreparedRequest)(nil), "query.CommitPreparedRequest") + proto.RegisterType((*CommitPreparedResponse)(nil), "query.CommitPreparedResponse") + proto.RegisterType((*RollbackPreparedRequest)(nil), "query.RollbackPreparedRequest") + proto.RegisterType((*RollbackPreparedResponse)(nil), "query.RollbackPreparedResponse") + proto.RegisterType((*CreateTransactionRequest)(nil), "query.CreateTransactionRequest") + proto.RegisterType((*CreateTransactionResponse)(nil), "query.CreateTransactionResponse") + proto.RegisterType((*StartCommitRequest)(nil), "query.StartCommitRequest") + proto.RegisterType((*StartCommitResponse)(nil), "query.StartCommitResponse") + proto.RegisterType((*SetRollbackRequest)(nil), "query.SetRollbackRequest") + proto.RegisterType((*SetRollbackResponse)(nil), "query.SetRollbackResponse") + proto.RegisterType((*ConcludeTransactionRequest)(nil), "query.ConcludeTransactionRequest") + proto.RegisterType((*ConcludeTransactionResponse)(nil), "query.ConcludeTransactionResponse") + proto.RegisterType((*ReadTransactionRequest)(nil), "query.ReadTransactionRequest") + proto.RegisterType((*ReadTransactionResponse)(nil), "query.ReadTransactionResponse") + proto.RegisterType((*BeginExecuteRequest)(nil), "query.BeginExecuteRequest") + proto.RegisterType((*BeginExecuteResponse)(nil), "query.BeginExecuteResponse") + proto.RegisterType((*BeginExecuteBatchRequest)(nil), "query.BeginExecuteBatchRequest") + proto.RegisterType((*BeginExecuteBatchResponse)(nil), "query.BeginExecuteBatchResponse") + proto.RegisterType((*MessageStreamRequest)(nil), "query.MessageStreamRequest") + proto.RegisterType((*MessageStreamResponse)(nil), "query.MessageStreamResponse") + proto.RegisterType((*MessageAckRequest)(nil), "query.MessageAckRequest") + proto.RegisterType((*MessageAckResponse)(nil), "query.MessageAckResponse") + proto.RegisterType((*SplitQueryRequest)(nil), "query.SplitQueryRequest") + proto.RegisterType((*QuerySplit)(nil), "query.QuerySplit") + proto.RegisterType((*SplitQueryResponse)(nil), "query.SplitQueryResponse") + proto.RegisterType((*StreamHealthRequest)(nil), "query.StreamHealthRequest") + proto.RegisterType((*RealtimeStats)(nil), "query.RealtimeStats") + proto.RegisterType((*StreamHealthResponse)(nil), "query.StreamHealthResponse") + proto.RegisterType((*UpdateStreamRequest)(nil), "query.UpdateStreamRequest") + proto.RegisterType((*UpdateStreamResponse)(nil), "query.UpdateStreamResponse") + proto.RegisterType((*TransactionMetadata)(nil), "query.TransactionMetadata") + proto.RegisterEnum("query.MySqlFlag", MySqlFlag_name, MySqlFlag_value) + proto.RegisterEnum("query.Flag", Flag_name, Flag_value) + proto.RegisterEnum("query.Type", Type_name, Type_value) + proto.RegisterEnum("query.TransactionState", TransactionState_name, TransactionState_value) + proto.RegisterEnum("query.ExecuteOptions_IncludedFields", ExecuteOptions_IncludedFields_name, ExecuteOptions_IncludedFields_value) + proto.RegisterEnum("query.ExecuteOptions_Workload", ExecuteOptions_Workload_name, ExecuteOptions_Workload_value) + proto.RegisterEnum("query.ExecuteOptions_TransactionIsolation", ExecuteOptions_TransactionIsolation_name, ExecuteOptions_TransactionIsolation_value) + proto.RegisterEnum("query.StreamEvent_Statement_Category", StreamEvent_Statement_Category_name, StreamEvent_Statement_Category_value) + proto.RegisterEnum("query.SplitQueryRequest_Algorithm", SplitQueryRequest_Algorithm_name, SplitQueryRequest_Algorithm_value) +} + +*/ diff --git a/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/dependency/sqltypes/bind_variables.go b/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/dependency/sqltypes/bind_variables.go new file mode 100644 index 00000000..1879e6db --- /dev/null +++ b/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/dependency/sqltypes/bind_variables.go @@ -0,0 +1,266 @@ +/* +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 sqltypes + +import ( + "errors" + "fmt" + "reflect" + "strconv" + + "github.com/xwb1989/sqlparser/dependency/querypb" +) + +// NullBindVariable is a bindvar with NULL value. +var NullBindVariable = &querypb.BindVariable{Type: querypb.Type_NULL_TYPE} + +// ValueToProto converts Value to a *querypb.Value. +func ValueToProto(v Value) *querypb.Value { + return &querypb.Value{Type: v.typ, Value: v.val} +} + +// ProtoToValue converts a *querypb.Value to a Value. +func ProtoToValue(v *querypb.Value) Value { + return MakeTrusted(v.Type, v.Value) +} + +// BuildBindVariables builds a map[string]*querypb.BindVariable from a map[string]interface{}. +func BuildBindVariables(in map[string]interface{}) (map[string]*querypb.BindVariable, error) { + if len(in) == 0 { + return nil, nil + } + + out := make(map[string]*querypb.BindVariable, len(in)) + for k, v := range in { + bv, err := BuildBindVariable(v) + if err != nil { + return nil, fmt.Errorf("%s: %v", k, err) + } + out[k] = bv + } + return out, nil +} + +// Int32BindVariable converts an int32 to a bind var. +func Int32BindVariable(v int32) *querypb.BindVariable { + return ValueBindVariable(NewInt32(v)) +} + +// Int64BindVariable converts an int64 to a bind var. +func Int64BindVariable(v int64) *querypb.BindVariable { + return ValueBindVariable(NewInt64(v)) +} + +// Uint64BindVariable converts a uint64 to a bind var. +func Uint64BindVariable(v uint64) *querypb.BindVariable { + return ValueBindVariable(NewUint64(v)) +} + +// Float64BindVariable converts a float64 to a bind var. +func Float64BindVariable(v float64) *querypb.BindVariable { + return ValueBindVariable(NewFloat64(v)) +} + +// StringBindVariable converts a string to a bind var. +func StringBindVariable(v string) *querypb.BindVariable { + return ValueBindVariable(NewVarChar(v)) +} + +// BytesBindVariable converts a []byte to a bind var. +func BytesBindVariable(v []byte) *querypb.BindVariable { + return &querypb.BindVariable{Type: VarBinary, Value: v} +} + +// ValueBindVariable converts a Value to a bind var. +func ValueBindVariable(v Value) *querypb.BindVariable { + return &querypb.BindVariable{Type: v.typ, Value: v.val} +} + +// BuildBindVariable builds a *querypb.BindVariable from a valid input type. +func BuildBindVariable(v interface{}) (*querypb.BindVariable, error) { + switch v := v.(type) { + case string: + return StringBindVariable(v), nil + case []byte: + return BytesBindVariable(v), nil + case int: + return &querypb.BindVariable{ + Type: querypb.Type_INT64, + Value: strconv.AppendInt(nil, int64(v), 10), + }, nil + case int64: + return Int64BindVariable(v), nil + case uint64: + return Uint64BindVariable(v), nil + case float64: + return Float64BindVariable(v), nil + case nil: + return NullBindVariable, nil + case Value: + return ValueBindVariable(v), nil + case *querypb.BindVariable: + return v, nil + case []interface{}: + bv := &querypb.BindVariable{ + Type: querypb.Type_TUPLE, + Values: make([]*querypb.Value, len(v)), + } + values := make([]querypb.Value, len(v)) + for i, lv := range v { + lbv, err := BuildBindVariable(lv) + if err != nil { + return nil, err + } + values[i].Type = lbv.Type + values[i].Value = lbv.Value + bv.Values[i] = &values[i] + } + return bv, nil + case []string: + bv := &querypb.BindVariable{ + Type: querypb.Type_TUPLE, + Values: make([]*querypb.Value, len(v)), + } + values := make([]querypb.Value, len(v)) + for i, lv := range v { + values[i].Type = querypb.Type_VARCHAR + values[i].Value = []byte(lv) + bv.Values[i] = &values[i] + } + return bv, nil + case [][]byte: + bv := &querypb.BindVariable{ + Type: querypb.Type_TUPLE, + Values: make([]*querypb.Value, len(v)), + } + values := make([]querypb.Value, len(v)) + for i, lv := range v { + values[i].Type = querypb.Type_VARBINARY + values[i].Value = lv + bv.Values[i] = &values[i] + } + return bv, nil + case []int: + bv := &querypb.BindVariable{ + Type: querypb.Type_TUPLE, + Values: make([]*querypb.Value, len(v)), + } + values := make([]querypb.Value, len(v)) + for i, lv := range v { + values[i].Type = querypb.Type_INT64 + values[i].Value = strconv.AppendInt(nil, int64(lv), 10) + bv.Values[i] = &values[i] + } + return bv, nil + case []int64: + bv := &querypb.BindVariable{ + Type: querypb.Type_TUPLE, + Values: make([]*querypb.Value, len(v)), + } + values := make([]querypb.Value, len(v)) + for i, lv := range v { + values[i].Type = querypb.Type_INT64 + values[i].Value = strconv.AppendInt(nil, lv, 10) + bv.Values[i] = &values[i] + } + return bv, nil + case []uint64: + bv := &querypb.BindVariable{ + Type: querypb.Type_TUPLE, + Values: make([]*querypb.Value, len(v)), + } + values := make([]querypb.Value, len(v)) + for i, lv := range v { + values[i].Type = querypb.Type_UINT64 + values[i].Value = strconv.AppendUint(nil, lv, 10) + bv.Values[i] = &values[i] + } + return bv, nil + case []float64: + bv := &querypb.BindVariable{ + Type: querypb.Type_TUPLE, + Values: make([]*querypb.Value, len(v)), + } + values := make([]querypb.Value, len(v)) + for i, lv := range v { + values[i].Type = querypb.Type_FLOAT64 + values[i].Value = strconv.AppendFloat(nil, lv, 'g', -1, 64) + bv.Values[i] = &values[i] + } + return bv, nil + } + return nil, fmt.Errorf("type %T not supported as bind var: %v", v, v) +} + +// ValidateBindVariables validates a map[string]*querypb.BindVariable. +func ValidateBindVariables(bv map[string]*querypb.BindVariable) error { + for k, v := range bv { + if err := ValidateBindVariable(v); err != nil { + return fmt.Errorf("%s: %v", k, err) + } + } + return nil +} + +// ValidateBindVariable returns an error if the bind variable has inconsistent +// fields. +func ValidateBindVariable(bv *querypb.BindVariable) error { + if bv == nil { + return errors.New("bind variable is nil") + } + + if bv.Type == querypb.Type_TUPLE { + if len(bv.Values) == 0 { + return errors.New("empty tuple is not allowed") + } + for _, val := range bv.Values { + if val.Type == querypb.Type_TUPLE { + return errors.New("tuple not allowed inside another tuple") + } + if err := ValidateBindVariable(&querypb.BindVariable{Type: val.Type, Value: val.Value}); err != nil { + return err + } + } + return nil + } + + // If NewValue succeeds, the value is valid. + _, err := NewValue(bv.Type, bv.Value) + return err +} + +// BindVariableToValue converts a bind var into a Value. +func BindVariableToValue(bv *querypb.BindVariable) (Value, error) { + if bv.Type == querypb.Type_TUPLE { + return NULL, errors.New("cannot convert a TUPLE bind var into a value") + } + return MakeTrusted(bv.Type, bv.Value), nil +} + +// BindVariablesEqual compares two maps of bind variables. +func BindVariablesEqual(x, y map[string]*querypb.BindVariable) bool { + return reflect.DeepEqual(&querypb.BoundQuery{BindVariables: x}, &querypb.BoundQuery{BindVariables: y}) +} + +// CopyBindVariables returns a shallow-copy of the given bindVariables map. +func CopyBindVariables(bindVariables map[string]*querypb.BindVariable) map[string]*querypb.BindVariable { + result := make(map[string]*querypb.BindVariable, len(bindVariables)) + for key, value := range bindVariables { + result[key] = value + } + return result +} diff --git a/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/dependency/sqltypes/bind_variables_test.go b/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/dependency/sqltypes/bind_variables_test.go new file mode 100644 index 00000000..ca0636c8 --- /dev/null +++ b/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/dependency/sqltypes/bind_variables_test.go @@ -0,0 +1,553 @@ +/* +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 sqltypes + +import ( + "reflect" + "strings" + "testing" + + "github.com/xwb1989/sqlparser/dependency/querypb" +) + +func TestProtoConversions(t *testing.T) { + v := TestValue(Int64, "1") + got := ValueToProto(v) + want := &querypb.Value{Type: Int64, Value: []byte("1")} + if !reflect.DeepEqual(got, want) { + t.Errorf("ValueToProto: %v, want %v", got, want) + } + gotback := ProtoToValue(got) + if !reflect.DeepEqual(gotback, v) { + t.Errorf("ProtoToValue: %v, want %v", gotback, v) + } +} + +func TestBuildBindVariables(t *testing.T) { + tcases := []struct { + in map[string]interface{} + out map[string]*querypb.BindVariable + err string + }{{ + in: nil, + out: nil, + }, { + in: map[string]interface{}{ + "k": int64(1), + }, + out: map[string]*querypb.BindVariable{ + "k": Int64BindVariable(1), + }, + }, { + in: map[string]interface{}{ + "k": byte(1), + }, + err: "k: type uint8 not supported as bind var: 1", + }} + for _, tcase := range tcases { + bindVars, err := BuildBindVariables(tcase.in) + if err != nil { + if err.Error() != tcase.err { + t.Errorf("MapToBindVars(%v) error: %v, want %s", tcase.in, err, tcase.err) + } + continue + } + if tcase.err != "" { + t.Errorf("MapToBindVars(%v) error: nil, want %s", tcase.in, tcase.err) + continue + } + if !BindVariablesEqual(bindVars, tcase.out) { + t.Errorf("MapToBindVars(%v): %v, want %s", tcase.in, bindVars, tcase.out) + } + } +} + +func TestBuildBindVariable(t *testing.T) { + tcases := []struct { + in interface{} + out *querypb.BindVariable + err string + }{{ + in: "aa", + out: &querypb.BindVariable{ + Type: querypb.Type_VARCHAR, + Value: []byte("aa"), + }, + }, { + in: []byte("aa"), + out: &querypb.BindVariable{ + Type: querypb.Type_VARBINARY, + Value: []byte("aa"), + }, + }, { + in: int(1), + out: &querypb.BindVariable{ + Type: querypb.Type_INT64, + Value: []byte("1"), + }, + }, { + in: int64(1), + out: &querypb.BindVariable{ + Type: querypb.Type_INT64, + Value: []byte("1"), + }, + }, { + in: uint64(1), + out: &querypb.BindVariable{ + Type: querypb.Type_UINT64, + Value: []byte("1"), + }, + }, { + in: float64(1), + out: &querypb.BindVariable{ + Type: querypb.Type_FLOAT64, + Value: []byte("1"), + }, + }, { + in: nil, + out: NullBindVariable, + }, { + in: MakeTrusted(Int64, []byte("1")), + out: &querypb.BindVariable{ + Type: querypb.Type_INT64, + Value: []byte("1"), + }, + }, { + in: &querypb.BindVariable{ + Type: querypb.Type_INT64, + Value: []byte("1"), + }, + out: &querypb.BindVariable{ + Type: querypb.Type_INT64, + Value: []byte("1"), + }, + }, { + in: []interface{}{"aa", int64(1)}, + out: &querypb.BindVariable{ + Type: querypb.Type_TUPLE, + Values: []*querypb.Value{{ + Type: querypb.Type_VARCHAR, + Value: []byte("aa"), + }, { + Type: querypb.Type_INT64, + Value: []byte("1"), + }}, + }, + }, { + in: []string{"aa", "bb"}, + out: &querypb.BindVariable{ + Type: querypb.Type_TUPLE, + Values: []*querypb.Value{{ + Type: querypb.Type_VARCHAR, + Value: []byte("aa"), + }, { + Type: querypb.Type_VARCHAR, + Value: []byte("bb"), + }}, + }, + }, { + in: [][]byte{[]byte("aa"), []byte("bb")}, + out: &querypb.BindVariable{ + Type: querypb.Type_TUPLE, + Values: []*querypb.Value{{ + Type: querypb.Type_VARBINARY, + Value: []byte("aa"), + }, { + Type: querypb.Type_VARBINARY, + Value: []byte("bb"), + }}, + }, + }, { + in: []int{1, 2}, + out: &querypb.BindVariable{ + Type: querypb.Type_TUPLE, + Values: []*querypb.Value{{ + Type: querypb.Type_INT64, + Value: []byte("1"), + }, { + Type: querypb.Type_INT64, + Value: []byte("2"), + }}, + }, + }, { + in: []int64{1, 2}, + out: &querypb.BindVariable{ + Type: querypb.Type_TUPLE, + Values: []*querypb.Value{{ + Type: querypb.Type_INT64, + Value: []byte("1"), + }, { + Type: querypb.Type_INT64, + Value: []byte("2"), + }}, + }, + }, { + in: []uint64{1, 2}, + out: &querypb.BindVariable{ + Type: querypb.Type_TUPLE, + Values: []*querypb.Value{{ + Type: querypb.Type_UINT64, + Value: []byte("1"), + }, { + Type: querypb.Type_UINT64, + Value: []byte("2"), + }}, + }, + }, { + in: []float64{1, 2}, + out: &querypb.BindVariable{ + Type: querypb.Type_TUPLE, + Values: []*querypb.Value{{ + Type: querypb.Type_FLOAT64, + Value: []byte("1"), + }, { + Type: querypb.Type_FLOAT64, + Value: []byte("2"), + }}, + }, + }, { + in: byte(1), + err: "type uint8 not supported as bind var: 1", + }, { + in: []interface{}{1, byte(1)}, + err: "type uint8 not supported as bind var: 1", + }} + for _, tcase := range tcases { + bv, err := BuildBindVariable(tcase.in) + if err != nil { + if err.Error() != tcase.err { + t.Errorf("ToBindVar(%T(%v)) error: %v, want %s", tcase.in, tcase.in, err, tcase.err) + } + continue + } + if tcase.err != "" { + t.Errorf("ToBindVar(%T(%v)) error: nil, want %s", tcase.in, tcase.in, tcase.err) + continue + } + if !reflect.DeepEqual(bv, tcase.out) { + t.Errorf("ToBindVar(%T(%v)): %v, want %s", tcase.in, tcase.in, bv, tcase.out) + } + } +} + +func TestValidateBindVarables(t *testing.T) { + tcases := []struct { + in map[string]*querypb.BindVariable + err string + }{{ + in: map[string]*querypb.BindVariable{ + "v": { + Type: querypb.Type_INT64, + Value: []byte("1"), + }, + }, + err: "", + }, { + in: map[string]*querypb.BindVariable{ + "v": { + Type: querypb.Type_INT64, + Value: []byte("a"), + }, + }, + err: `v: strconv.ParseInt: parsing "a": invalid syntax`, + }, { + in: map[string]*querypb.BindVariable{ + "v": { + Type: querypb.Type_TUPLE, + Values: []*querypb.Value{{ + Type: Int64, + Value: []byte("a"), + }}, + }, + }, + err: `v: strconv.ParseInt: parsing "a": invalid syntax`, + }} + for _, tcase := range tcases { + err := ValidateBindVariables(tcase.in) + if tcase.err != "" { + if err == nil || err.Error() != tcase.err { + t.Errorf("ValidateBindVars(%v): %v, want %s", tcase.in, err, tcase.err) + } + continue + } + if err != nil { + t.Errorf("ValidateBindVars(%v): %v, want nil", tcase.in, err) + } + } +} + +func TestValidateBindVariable(t *testing.T) { + testcases := []struct { + in *querypb.BindVariable + err string + }{{ + in: &querypb.BindVariable{ + Type: querypb.Type_INT8, + Value: []byte("1"), + }, + }, { + in: &querypb.BindVariable{ + Type: querypb.Type_INT16, + Value: []byte("1"), + }, + }, { + in: &querypb.BindVariable{ + Type: querypb.Type_INT24, + Value: []byte("1"), + }, + }, { + in: &querypb.BindVariable{ + Type: querypb.Type_INT32, + Value: []byte("1"), + }, + }, { + in: &querypb.BindVariable{ + Type: querypb.Type_INT64, + Value: []byte("1"), + }, + }, { + in: &querypb.BindVariable{ + Type: querypb.Type_UINT8, + Value: []byte("1"), + }, + }, { + in: &querypb.BindVariable{ + Type: querypb.Type_UINT16, + Value: []byte("1"), + }, + }, { + in: &querypb.BindVariable{ + Type: querypb.Type_UINT24, + Value: []byte("1"), + }, + }, { + in: &querypb.BindVariable{ + Type: querypb.Type_UINT32, + Value: []byte("1"), + }, + }, { + in: &querypb.BindVariable{ + Type: querypb.Type_UINT64, + Value: []byte("1"), + }, + }, { + in: &querypb.BindVariable{ + Type: querypb.Type_FLOAT32, + Value: []byte("1.00"), + }, + }, { + in: &querypb.BindVariable{ + Type: querypb.Type_FLOAT64, + Value: []byte("1.00"), + }, + }, { + in: &querypb.BindVariable{ + Type: querypb.Type_DECIMAL, + Value: []byte("1.00"), + }, + }, { + in: &querypb.BindVariable{ + Type: querypb.Type_TIMESTAMP, + Value: []byte("2012-02-24 23:19:43"), + }, + }, { + in: &querypb.BindVariable{ + Type: querypb.Type_DATE, + Value: []byte("2012-02-24"), + }, + }, { + in: &querypb.BindVariable{ + Type: querypb.Type_TIME, + Value: []byte("23:19:43"), + }, + }, { + in: &querypb.BindVariable{ + Type: querypb.Type_DATETIME, + Value: []byte("2012-02-24 23:19:43"), + }, + }, { + in: &querypb.BindVariable{ + Type: querypb.Type_YEAR, + Value: []byte("1"), + }, + }, { + in: &querypb.BindVariable{ + Type: querypb.Type_TEXT, + Value: []byte("a"), + }, + }, { + in: &querypb.BindVariable{ + Type: querypb.Type_BLOB, + Value: []byte("a"), + }, + }, { + in: &querypb.BindVariable{ + Type: querypb.Type_VARCHAR, + Value: []byte("a"), + }, + }, { + in: &querypb.BindVariable{ + Type: querypb.Type_BINARY, + Value: []byte("a"), + }, + }, { + in: &querypb.BindVariable{ + Type: querypb.Type_CHAR, + Value: []byte("a"), + }, + }, { + in: &querypb.BindVariable{ + Type: querypb.Type_BIT, + Value: []byte("1"), + }, + }, { + in: &querypb.BindVariable{ + Type: querypb.Type_ENUM, + Value: []byte("a"), + }, + }, { + in: &querypb.BindVariable{ + Type: querypb.Type_SET, + Value: []byte("a"), + }, + }, { + in: &querypb.BindVariable{ + Type: querypb.Type_VARBINARY, + Value: []byte("a"), + }, + }, { + in: &querypb.BindVariable{ + Type: querypb.Type_INT64, + Value: []byte(InvalidNeg), + }, + err: "out of range", + }, { + in: &querypb.BindVariable{ + Type: querypb.Type_INT64, + Value: []byte(InvalidPos), + }, + err: "out of range", + }, { + in: &querypb.BindVariable{ + Type: querypb.Type_UINT64, + Value: []byte("-1"), + }, + err: "invalid syntax", + }, { + in: &querypb.BindVariable{ + Type: querypb.Type_UINT64, + Value: []byte(InvalidPos), + }, + err: "out of range", + }, { + in: &querypb.BindVariable{ + Type: querypb.Type_FLOAT64, + Value: []byte("a"), + }, + err: "invalid syntax", + }, { + in: &querypb.BindVariable{ + Type: querypb.Type_EXPRESSION, + Value: []byte("a"), + }, + err: "invalid type specified for MakeValue: EXPRESSION", + }, { + in: &querypb.BindVariable{ + Type: querypb.Type_TUPLE, + Values: []*querypb.Value{{ + Type: querypb.Type_INT64, + Value: []byte("1"), + }}, + }, + }, { + in: &querypb.BindVariable{ + Type: querypb.Type_TUPLE, + }, + err: "empty tuple is not allowed", + }, { + in: &querypb.BindVariable{ + Type: querypb.Type_TUPLE, + Values: []*querypb.Value{{ + Type: querypb.Type_TUPLE, + }}, + }, + err: "tuple not allowed inside another tuple", + }} + for _, tcase := range testcases { + err := ValidateBindVariable(tcase.in) + if tcase.err != "" { + if err == nil || !strings.Contains(err.Error(), tcase.err) { + t.Errorf("ValidateBindVar(%v) error: %v, must contain %v", tcase.in, err, tcase.err) + } + continue + } + if err != nil { + t.Errorf("ValidateBindVar(%v) error: %v", tcase.in, err) + } + } + + // Special case: nil bind var. + err := ValidateBindVariable(nil) + want := "bind variable is nil" + if err == nil || err.Error() != want { + t.Errorf("ValidateBindVar(nil) error: %v, want %s", err, want) + } +} + +func TestBindVariableToValue(t *testing.T) { + v, err := BindVariableToValue(Int64BindVariable(1)) + if err != nil { + t.Error(err) + } + want := MakeTrusted(querypb.Type_INT64, []byte("1")) + if !reflect.DeepEqual(v, want) { + t.Errorf("BindVarToValue(1): %v, want %v", v, want) + } + + v, err = BindVariableToValue(&querypb.BindVariable{Type: querypb.Type_TUPLE}) + wantErr := "cannot convert a TUPLE bind var into a value" + if err == nil || err.Error() != wantErr { + t.Errorf(" BindVarToValue(TUPLE): %v, want %s", err, wantErr) + } +} + +func TestBindVariablesEqual(t *testing.T) { + bv1 := map[string]*querypb.BindVariable{ + "k": { + Type: querypb.Type_INT64, + Value: []byte("1"), + }, + } + bv2 := map[string]*querypb.BindVariable{ + "k": { + Type: querypb.Type_INT64, + Value: []byte("1"), + }, + } + bv3 := map[string]*querypb.BindVariable{ + "k": { + Type: querypb.Type_INT64, + Value: []byte("1"), + }, + } + if !BindVariablesEqual(bv1, bv2) { + t.Errorf("%v != %v, want equal", bv1, bv2) + } + if !BindVariablesEqual(bv1, bv3) { + t.Errorf("%v = %v, want not equal", bv1, bv3) + } +} diff --git a/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/dependency/sqltypes/plan_value.go b/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/dependency/sqltypes/plan_value.go new file mode 100644 index 00000000..7936a6ba --- /dev/null +++ b/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/dependency/sqltypes/plan_value.go @@ -0,0 +1,259 @@ +/* +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 sqltypes + +import ( + "encoding/json" + "errors" + "fmt" + + "github.com/xwb1989/sqlparser/dependency/querypb" +) + +// PlanValue represents a value or a list of values for +// a column that will later be resolved using bind vars and used +// to perform plan actions like generating the final query or +// deciding on a route. +// +// Plan values are typically used as a slice ([]planValue) +// where each entry is for one column. For situations where +// the required output is a list of rows (like in the case +// of multi-value inserts), the representation is pivoted. +// For example, a statement like this: +// INSERT INTO t VALUES (1, 2), (3, 4) +// will be represented as follows: +// []PlanValue{ +// Values: {1, 3}, +// Values: {2, 4}, +// } +// +// For WHERE clause items that contain a combination of +// equality expressions and IN clauses like this: +// WHERE pk1 = 1 AND pk2 IN (2, 3, 4) +// The plan values will be represented as follows: +// []PlanValue{ +// Value: 1, +// Values: {2, 3, 4}, +// } +// When converted into rows, columns with single values +// are replicated as the same for all rows: +// [][]Value{ +// {1, 2}, +// {1, 3}, +// {1, 4}, +// } +type PlanValue struct { + Key string + Value Value + ListKey string + Values []PlanValue +} + +// IsNull returns true if the PlanValue is NULL. +func (pv PlanValue) IsNull() bool { + return pv.Key == "" && pv.Value.IsNull() && pv.ListKey == "" && pv.Values == nil +} + +// IsList returns true if the PlanValue is a list. +func (pv PlanValue) IsList() bool { + return pv.ListKey != "" || pv.Values != nil +} + +// ResolveValue resolves a PlanValue as a single value based on the supplied bindvars. +func (pv PlanValue) ResolveValue(bindVars map[string]*querypb.BindVariable) (Value, error) { + switch { + case pv.Key != "": + bv, err := pv.lookupValue(bindVars) + if err != nil { + return NULL, err + } + return MakeTrusted(bv.Type, bv.Value), nil + case !pv.Value.IsNull(): + return pv.Value, nil + case pv.ListKey != "" || pv.Values != nil: + // This code is unreachable because the parser does not allow + // multi-value constructs where a single value is expected. + return NULL, errors.New("a list was supplied where a single value was expected") + } + return NULL, nil +} + +func (pv PlanValue) lookupValue(bindVars map[string]*querypb.BindVariable) (*querypb.BindVariable, error) { + bv, ok := bindVars[pv.Key] + if !ok { + return nil, fmt.Errorf("missing bind var %s", pv.Key) + } + if bv.Type == querypb.Type_TUPLE { + return nil, fmt.Errorf("TUPLE was supplied for single value bind var %s", pv.ListKey) + } + return bv, nil +} + +// ResolveList resolves a PlanValue as a list of values based on the supplied bindvars. +func (pv PlanValue) ResolveList(bindVars map[string]*querypb.BindVariable) ([]Value, error) { + switch { + case pv.ListKey != "": + bv, err := pv.lookupList(bindVars) + if err != nil { + return nil, err + } + values := make([]Value, 0, len(bv.Values)) + for _, val := range bv.Values { + values = append(values, MakeTrusted(val.Type, val.Value)) + } + return values, nil + case pv.Values != nil: + values := make([]Value, 0, len(pv.Values)) + for _, val := range pv.Values { + v, err := val.ResolveValue(bindVars) + if err != nil { + return nil, err + } + values = append(values, v) + } + return values, nil + } + // This code is unreachable because the parser does not allow + // single value constructs where multiple values are expected. + return nil, errors.New("a single value was supplied where a list was expected") +} + +func (pv PlanValue) lookupList(bindVars map[string]*querypb.BindVariable) (*querypb.BindVariable, error) { + bv, ok := bindVars[pv.ListKey] + if !ok { + return nil, fmt.Errorf("missing bind var %s", pv.ListKey) + } + if bv.Type != querypb.Type_TUPLE { + return nil, fmt.Errorf("single value was supplied for TUPLE bind var %s", pv.ListKey) + } + return bv, nil +} + +// MarshalJSON should be used only for testing. +func (pv PlanValue) MarshalJSON() ([]byte, error) { + switch { + case pv.Key != "": + return json.Marshal(":" + pv.Key) + case !pv.Value.IsNull(): + if pv.Value.IsIntegral() { + return pv.Value.ToBytes(), nil + } + return json.Marshal(pv.Value.ToString()) + case pv.ListKey != "": + return json.Marshal("::" + pv.ListKey) + case pv.Values != nil: + return json.Marshal(pv.Values) + } + return []byte("null"), nil +} + +func rowCount(pvs []PlanValue, bindVars map[string]*querypb.BindVariable) (int, error) { + count := -1 + setCount := func(l int) error { + switch count { + case -1: + count = l + return nil + case l: + return nil + default: + return errors.New("mismatch in number of column values") + } + } + + for _, pv := range pvs { + switch { + case pv.Key != "" || !pv.Value.IsNull(): + continue + case pv.Values != nil: + if err := setCount(len(pv.Values)); err != nil { + return 0, err + } + case pv.ListKey != "": + bv, err := pv.lookupList(bindVars) + if err != nil { + return 0, err + } + if err := setCount(len(bv.Values)); err != nil { + return 0, err + } + } + } + + if count == -1 { + // If there were no lists inside, it was a single row. + // Note that count can never be 0 because there is enough + // protection at the top level: list bind vars must have + // at least one value (enforced by vtgate), and AST lists + // must have at least one value (enforced by the parser). + // Also lists created internally after vtgate validation + // ensure at least one value. + // TODO(sougou): verify and change API to enforce this. + return 1, nil + } + return count, nil +} + +// ResolveRows resolves a []PlanValue as rows based on the supplied bindvars. +func ResolveRows(pvs []PlanValue, bindVars map[string]*querypb.BindVariable) ([][]Value, error) { + count, err := rowCount(pvs, bindVars) + if err != nil { + return nil, err + } + + // Allocate the rows. + rows := make([][]Value, count) + for i := range rows { + rows[i] = make([]Value, len(pvs)) + } + + // Using j becasue we're resolving by columns. + for j, pv := range pvs { + switch { + case pv.Key != "": + bv, err := pv.lookupValue(bindVars) + if err != nil { + return nil, err + } + for i := range rows { + rows[i][j] = MakeTrusted(bv.Type, bv.Value) + } + case !pv.Value.IsNull(): + for i := range rows { + rows[i][j] = pv.Value + } + case pv.ListKey != "": + bv, err := pv.lookupList(bindVars) + if err != nil { + // This code is unreachable because pvRowCount already checks this. + return nil, err + } + for i := range rows { + rows[i][j] = MakeTrusted(bv.Values[i].Type, bv.Values[i].Value) + } + case pv.Values != nil: + for i := range rows { + rows[i][j], err = pv.Values[i].ResolveValue(bindVars) + if err != nil { + return nil, err + } + } + // default case is a NULL value, which the row values are already initialized to. + } + } + return rows, nil +} diff --git a/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/dependency/sqltypes/plan_value_test.go b/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/dependency/sqltypes/plan_value_test.go new file mode 100644 index 00000000..ea85c9c6 --- /dev/null +++ b/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/dependency/sqltypes/plan_value_test.go @@ -0,0 +1,319 @@ +/* +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 sqltypes + +import ( + "reflect" + "strings" + "testing" + + "github.com/xwb1989/sqlparser/dependency/querypb" +) + +func TestPlanValueIsNull(t *testing.T) { + tcases := []struct { + in PlanValue + out bool + }{{ + in: PlanValue{}, + out: true, + }, { + in: PlanValue{Key: "aa"}, + out: false, + }, { + in: PlanValue{Value: NewVarBinary("aa")}, + out: false, + }, { + in: PlanValue{ListKey: "aa"}, + out: false, + }, { + in: PlanValue{Values: []PlanValue{}}, + out: false, + }} + for _, tc := range tcases { + got := tc.in.IsNull() + if got != tc.out { + t.Errorf("IsNull(%v): %v, want %v", tc.in, got, tc.out) + } + } +} + +func TestPlanValueIsList(t *testing.T) { + tcases := []struct { + in PlanValue + out bool + }{{ + in: PlanValue{}, + out: false, + }, { + in: PlanValue{Key: "aa"}, + out: false, + }, { + in: PlanValue{Value: NewVarBinary("aa")}, + out: false, + }, { + in: PlanValue{ListKey: "aa"}, + out: true, + }, { + in: PlanValue{Values: []PlanValue{}}, + out: true, + }} + for _, tc := range tcases { + got := tc.in.IsList() + if got != tc.out { + t.Errorf("IsList(%v): %v, want %v", tc.in, got, tc.out) + } + } +} + +func TestResolveRows(t *testing.T) { + testBindVars := map[string]*querypb.BindVariable{ + "int": Int64BindVariable(10), + "intstr": TestBindVariable([]interface{}{10, "aa"}), + } + intValue := MakeTrusted(Int64, []byte("10")) + strValue := MakeTrusted(VarChar, []byte("aa")) + tcases := []struct { + in []PlanValue + out [][]Value + err string + }{{ + // Simple cases. + in: []PlanValue{ + {Key: "int"}, + }, + out: [][]Value{ + {intValue}, + }, + }, { + in: []PlanValue{ + {Value: intValue}, + }, + out: [][]Value{ + {intValue}, + }, + }, { + in: []PlanValue{ + {ListKey: "intstr"}, + }, + out: [][]Value{ + {intValue}, + {strValue}, + }, + }, { + in: []PlanValue{ + {Values: []PlanValue{{Value: intValue}, {Value: strValue}}}, + }, + out: [][]Value{ + {intValue}, + {strValue}, + }, + }, { + in: []PlanValue{ + {Values: []PlanValue{{Key: "int"}, {Value: strValue}}}, + }, + out: [][]Value{ + {intValue}, + {strValue}, + }, + }, { + in: []PlanValue{{}}, + out: [][]Value{ + {NULL}, + }, + }, { + // Cases with varying rowcounts. + // All types of input.. + in: []PlanValue{ + {Key: "int"}, + {Value: strValue}, + {ListKey: "intstr"}, + {Values: []PlanValue{{Value: strValue}, {Value: intValue}}}, + }, + out: [][]Value{ + {intValue, strValue, intValue, strValue}, + {intValue, strValue, strValue, intValue}, + }, + }, { + // list, val, list. + in: []PlanValue{ + {Value: strValue}, + {Key: "int"}, + {Values: []PlanValue{{Value: strValue}, {Value: intValue}}}, + }, + out: [][]Value{ + {strValue, intValue, strValue}, + {strValue, intValue, intValue}, + }, + }, { + // list, list + in: []PlanValue{ + {ListKey: "intstr"}, + {Values: []PlanValue{{Value: strValue}, {Value: intValue}}}, + }, + out: [][]Value{ + {intValue, strValue}, + {strValue, intValue}, + }, + }, { + // Error cases + in: []PlanValue{ + {ListKey: "intstr"}, + {Values: []PlanValue{{Value: strValue}}}, + }, + err: "mismatch in number of column values", + }, { + // This is a different code path for a similar validation. + in: []PlanValue{ + {Values: []PlanValue{{Value: strValue}}}, + {ListKey: "intstr"}, + }, + err: "mismatch in number of column values", + }, { + in: []PlanValue{ + {Key: "absent"}, + }, + err: "missing bind var", + }, { + in: []PlanValue{ + {ListKey: "absent"}, + }, + err: "missing bind var", + }, { + in: []PlanValue{ + {Values: []PlanValue{{Key: "absent"}}}, + }, + err: "missing bind var", + }} + + for _, tc := range tcases { + got, err := ResolveRows(tc.in, testBindVars) + if err != nil { + if !strings.Contains(err.Error(), tc.err) { + t.Errorf("ResolveRows(%v) error: %v, want '%s'", tc.in, err, tc.err) + } + continue + } + if tc.err != "" { + t.Errorf("ResolveRows(%v) error: nil, want '%s'", tc.in, tc.err) + continue + } + if !reflect.DeepEqual(got, tc.out) { + t.Errorf("ResolveRows(%v): %v, want %v", tc.in, got, tc.out) + } + } +} + +func TestResolveList(t *testing.T) { + testBindVars := map[string]*querypb.BindVariable{ + "int": Int64BindVariable(10), + "intstr": TestBindVariable([]interface{}{10, "aa"}), + } + intValue := MakeTrusted(Int64, []byte("10")) + strValue := MakeTrusted(VarChar, []byte("aa")) + tcases := []struct { + in PlanValue + out []Value + err string + }{{ + in: PlanValue{ListKey: "intstr"}, + out: []Value{intValue, strValue}, + }, { + in: PlanValue{Values: []PlanValue{{Value: intValue}, {Value: strValue}}}, + out: []Value{intValue, strValue}, + }, { + in: PlanValue{Values: []PlanValue{{Key: "int"}, {Value: strValue}}}, + out: []Value{intValue, strValue}, + }, { + in: PlanValue{ListKey: "absent"}, + err: "missing bind var", + }, { + in: PlanValue{Values: []PlanValue{{Key: "absent"}, {Value: strValue}}}, + err: "missing bind var", + }, { + in: PlanValue{ListKey: "int"}, + err: "single value was supplied for TUPLE bind var", + }, { + in: PlanValue{Key: "int"}, + err: "a single value was supplied where a list was expected", + }} + + for _, tc := range tcases { + got, err := tc.in.ResolveList(testBindVars) + if err != nil { + if !strings.Contains(err.Error(), tc.err) { + t.Errorf("ResolveList(%v) error: %v, want '%s'", tc.in, err, tc.err) + } + continue + } + if tc.err != "" { + t.Errorf("ResolveList(%v) error: nil, want '%s'", tc.in, tc.err) + continue + } + if !reflect.DeepEqual(got, tc.out) { + t.Errorf("ResolveList(%v): %v, want %v", tc.in, got, tc.out) + } + } +} + +func TestResolveValue(t *testing.T) { + testBindVars := map[string]*querypb.BindVariable{ + "int": Int64BindVariable(10), + "intstr": TestBindVariable([]interface{}{10, "aa"}), + } + intValue := MakeTrusted(Int64, []byte("10")) + tcases := []struct { + in PlanValue + out Value + err string + }{{ + in: PlanValue{Key: "int"}, + out: intValue, + }, { + in: PlanValue{Value: intValue}, + out: intValue, + }, { + in: PlanValue{}, + out: NULL, + }, { + in: PlanValue{Key: "absent"}, + err: "missing bind var", + }, { + in: PlanValue{Key: "intstr"}, + err: "TUPLE was supplied for single value bind var", + }, { + in: PlanValue{ListKey: "intstr"}, + err: "a list was supplied where a single value was expected", + }} + + for _, tc := range tcases { + got, err := tc.in.ResolveValue(testBindVars) + if err != nil { + if !strings.Contains(err.Error(), tc.err) { + t.Errorf("ResolveValue(%v) error: %v, want '%s'", tc.in, err, tc.err) + } + continue + } + if tc.err != "" { + t.Errorf("ResolveValue(%v) error: nil, want '%s'", tc.in, tc.err) + continue + } + if !reflect.DeepEqual(got, tc.out) { + t.Errorf("ResolveValue(%v): %v, want %v", tc.in, got, tc.out) + } + } +} diff --git a/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/dependency/sqltypes/testing.go b/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/dependency/sqltypes/testing.go new file mode 100644 index 00000000..0acaedda --- /dev/null +++ b/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/dependency/sqltypes/testing.go @@ -0,0 +1,154 @@ +/* +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 sqltypes + +import ( + querypb "github.com/xwb1989/sqlparser/dependency/querypb" +) + +// Functions in this file should only be used for testing. +// This is an experiment to see if test code bloat can be +// reduced and readability improved. + +/* +// MakeTestFields builds a []*querypb.Field for testing. +// fields := sqltypes.MakeTestFields( +// "a|b", +// "int64|varchar", +// ) +// The field types are as defined in querypb and are case +// insensitive. Column delimiters must be used only to sepearate +// strings and not at the beginning or the end. +func MakeTestFields(names, types string) []*querypb.Field { + n := split(names) + t := split(types) + var fields []*querypb.Field + for i := range n { + fields = append(fields, &querypb.Field{ + Name: n[i], + Type: querypb.Type(querypb.Type_value[strings.ToUpper(t[i])]), + }) + } + return fields +} + +// MakeTestResult builds a *sqltypes.Result object for testing. +// result := sqltypes.MakeTestResult( +// fields, +// " 1|a", +// "10|abcd", +// ) +// The field type values are set as the types for the rows built. +// Spaces are trimmed from row values. "null" is treated as NULL. +func MakeTestResult(fields []*querypb.Field, rows ...string) *Result { + result := &Result{ + Fields: fields, + } + if len(rows) > 0 { + result.Rows = make([][]Value, len(rows)) + } + for i, row := range rows { + result.Rows[i] = make([]Value, len(fields)) + for j, col := range split(row) { + if col == "null" { + continue + } + result.Rows[i][j] = MakeTrusted(fields[j].Type, []byte(col)) + } + } + result.RowsAffected = uint64(len(result.Rows)) + return result +} + +// MakeTestStreamingResults builds a list of results for streaming. +// results := sqltypes.MakeStreamingResults( +// fields, +// "1|a", +// "2|b", +// "---", +// "c|c", +// ) +// The first result contains only the fields. Subsequent results +// are built using the field types. Every input that starts with a "-" +// is treated as streaming delimiter for one result. A final +// delimiter must not be supplied. +func MakeTestStreamingResults(fields []*querypb.Field, rows ...string) []*Result { + var results []*Result + results = append(results, &Result{Fields: fields}) + start := 0 + cur := 0 + // Add a final streaming delimiter to simplify the loop below. + rows = append(rows, "-") + for cur < len(rows) { + if rows[cur][0] != '-' { + cur++ + continue + } + result := MakeTestResult(fields, rows[start:cur]...) + result.Fields = nil + result.RowsAffected = 0 + results = append(results, result) + start = cur + 1 + cur = start + } + return results +} +*/ + +// TestBindVariable makes a *querypb.BindVariable from +// an interface{}.It panics on invalid input. +// This function should only be used for testing. +func TestBindVariable(v interface{}) *querypb.BindVariable { + if v == nil { + return NullBindVariable + } + bv, err := BuildBindVariable(v) + if err != nil { + panic(err) + } + return bv +} + +// TestValue builds a Value from typ and val. +// This function should only be used for testing. +func TestValue(typ querypb.Type, val string) Value { + return MakeTrusted(typ, []byte(val)) +} + +/* +// PrintResults prints []*Results into a string. +// This function should only be used for testing. +func PrintResults(results []*Result) string { + b := new(bytes.Buffer) + for i, r := range results { + if i == 0 { + fmt.Fprintf(b, "%v", r) + continue + } + fmt.Fprintf(b, ", %v", r) + } + return b.String() +} + +func split(str string) []string { + splits := strings.Split(str, "|") + for i, v := range splits { + splits[i] = strings.TrimSpace(v) + } + return splits +} +*/ diff --git a/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/dependency/sqltypes/type.go b/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/dependency/sqltypes/type.go new file mode 100644 index 00000000..49224e4b --- /dev/null +++ b/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/dependency/sqltypes/type.go @@ -0,0 +1,288 @@ +/* +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 sqltypes + +import ( + "fmt" + + "github.com/xwb1989/sqlparser/dependency/querypb" +) + +// This file provides wrappers and support +// functions for querypb.Type. + +// These bit flags can be used to query on the +// common properties of types. +const ( + flagIsIntegral = int(querypb.Flag_ISINTEGRAL) + flagIsUnsigned = int(querypb.Flag_ISUNSIGNED) + flagIsFloat = int(querypb.Flag_ISFLOAT) + flagIsQuoted = int(querypb.Flag_ISQUOTED) + flagIsText = int(querypb.Flag_ISTEXT) + flagIsBinary = int(querypb.Flag_ISBINARY) +) + +// IsIntegral returns true if querypb.Type is an integral +// (signed/unsigned) that can be represented using +// up to 64 binary bits. +// If you have a Value object, use its member function. +func IsIntegral(t querypb.Type) bool { + return int(t)&flagIsIntegral == flagIsIntegral +} + +// IsSigned returns true if querypb.Type is a signed integral. +// If you have a Value object, use its member function. +func IsSigned(t querypb.Type) bool { + return int(t)&(flagIsIntegral|flagIsUnsigned) == flagIsIntegral +} + +// IsUnsigned returns true if querypb.Type is an unsigned integral. +// Caution: this is not the same as !IsSigned. +// If you have a Value object, use its member function. +func IsUnsigned(t querypb.Type) bool { + return int(t)&(flagIsIntegral|flagIsUnsigned) == flagIsIntegral|flagIsUnsigned +} + +// IsFloat returns true is querypb.Type is a floating point. +// If you have a Value object, use its member function. +func IsFloat(t querypb.Type) bool { + return int(t)&flagIsFloat == flagIsFloat +} + +// IsQuoted returns true if querypb.Type is a quoted text or binary. +// If you have a Value object, use its member function. +func IsQuoted(t querypb.Type) bool { + return int(t)&flagIsQuoted == flagIsQuoted +} + +// IsText returns true if querypb.Type is a text. +// If you have a Value object, use its member function. +func IsText(t querypb.Type) bool { + return int(t)&flagIsText == flagIsText +} + +// IsBinary returns true if querypb.Type is a binary. +// If you have a Value object, use its member function. +func IsBinary(t querypb.Type) bool { + return int(t)&flagIsBinary == flagIsBinary +} + +// isNumber returns true if the type is any type of number. +func isNumber(t querypb.Type) bool { + return IsIntegral(t) || IsFloat(t) || t == Decimal +} + +// Vitess data types. These are idiomatically +// named synonyms for the querypb.Type values. +// Although these constants are interchangeable, +// they should be treated as different from querypb.Type. +// Use the synonyms only to refer to the type in Value. +// For proto variables, use the querypb.Type constants +// instead. +// The following conditions are non-overlapping +// and cover all types: IsSigned(), IsUnsigned(), +// IsFloat(), IsQuoted(), Null, Decimal, Expression. +// Also, IsIntegral() == (IsSigned()||IsUnsigned()). +// TestCategory needs to be updated accordingly if +// you add a new type. +// If IsBinary or IsText is true, then IsQuoted is +// also true. But there are IsQuoted types that are +// neither binary or text. +// querypb.Type_TUPLE is not included in this list +// because it's not a valid Value type. +// TODO(sougou): provide a categorization function +// that returns enums, which will allow for cleaner +// switch statements for those who want to cover types +// by their category. +const ( + Null = querypb.Type_NULL_TYPE + Int8 = querypb.Type_INT8 + Uint8 = querypb.Type_UINT8 + Int16 = querypb.Type_INT16 + Uint16 = querypb.Type_UINT16 + Int24 = querypb.Type_INT24 + Uint24 = querypb.Type_UINT24 + Int32 = querypb.Type_INT32 + Uint32 = querypb.Type_UINT32 + Int64 = querypb.Type_INT64 + Uint64 = querypb.Type_UINT64 + Float32 = querypb.Type_FLOAT32 + Float64 = querypb.Type_FLOAT64 + Timestamp = querypb.Type_TIMESTAMP + Date = querypb.Type_DATE + Time = querypb.Type_TIME + Datetime = querypb.Type_DATETIME + Year = querypb.Type_YEAR + Decimal = querypb.Type_DECIMAL + Text = querypb.Type_TEXT + Blob = querypb.Type_BLOB + VarChar = querypb.Type_VARCHAR + VarBinary = querypb.Type_VARBINARY + Char = querypb.Type_CHAR + Binary = querypb.Type_BINARY + Bit = querypb.Type_BIT + Enum = querypb.Type_ENUM + Set = querypb.Type_SET + Geometry = querypb.Type_GEOMETRY + TypeJSON = querypb.Type_JSON + Expression = querypb.Type_EXPRESSION +) + +// bit-shift the mysql flags by two byte so we +// can merge them with the mysql or vitess types. +const ( + mysqlUnsigned = 32 + mysqlBinary = 128 + mysqlEnum = 256 + mysqlSet = 2048 +) + +// If you add to this map, make sure you add a test case +// in tabletserver/endtoend. +var mysqlToType = map[int64]querypb.Type{ + 1: Int8, + 2: Int16, + 3: Int32, + 4: Float32, + 5: Float64, + 6: Null, + 7: Timestamp, + 8: Int64, + 9: Int24, + 10: Date, + 11: Time, + 12: Datetime, + 13: Year, + 16: Bit, + 245: TypeJSON, + 246: Decimal, + 249: Text, + 250: Text, + 251: Text, + 252: Text, + 253: VarChar, + 254: Char, + 255: Geometry, +} + +// modifyType modifies the vitess type based on the +// mysql flag. The function checks specific flags based +// on the type. This allows us to ignore stray flags +// that MySQL occasionally sets. +func modifyType(typ querypb.Type, flags int64) querypb.Type { + switch typ { + case Int8: + if flags&mysqlUnsigned != 0 { + return Uint8 + } + return Int8 + case Int16: + if flags&mysqlUnsigned != 0 { + return Uint16 + } + return Int16 + case Int32: + if flags&mysqlUnsigned != 0 { + return Uint32 + } + return Int32 + case Int64: + if flags&mysqlUnsigned != 0 { + return Uint64 + } + return Int64 + case Int24: + if flags&mysqlUnsigned != 0 { + return Uint24 + } + return Int24 + case Text: + if flags&mysqlBinary != 0 { + return Blob + } + return Text + case VarChar: + if flags&mysqlBinary != 0 { + return VarBinary + } + return VarChar + case Char: + if flags&mysqlBinary != 0 { + return Binary + } + if flags&mysqlEnum != 0 { + return Enum + } + if flags&mysqlSet != 0 { + return Set + } + return Char + } + return typ +} + +// MySQLToType computes the vitess type from mysql type and flags. +func MySQLToType(mysqlType, flags int64) (typ querypb.Type, err error) { + result, ok := mysqlToType[mysqlType] + if !ok { + return 0, fmt.Errorf("unsupported type: %d", mysqlType) + } + return modifyType(result, flags), nil +} + +// typeToMySQL is the reverse of mysqlToType. +var typeToMySQL = map[querypb.Type]struct { + typ int64 + flags int64 +}{ + Int8: {typ: 1}, + Uint8: {typ: 1, flags: mysqlUnsigned}, + Int16: {typ: 2}, + Uint16: {typ: 2, flags: mysqlUnsigned}, + Int32: {typ: 3}, + Uint32: {typ: 3, flags: mysqlUnsigned}, + Float32: {typ: 4}, + Float64: {typ: 5}, + Null: {typ: 6, flags: mysqlBinary}, + Timestamp: {typ: 7}, + Int64: {typ: 8}, + Uint64: {typ: 8, flags: mysqlUnsigned}, + Int24: {typ: 9}, + Uint24: {typ: 9, flags: mysqlUnsigned}, + Date: {typ: 10, flags: mysqlBinary}, + Time: {typ: 11, flags: mysqlBinary}, + Datetime: {typ: 12, flags: mysqlBinary}, + Year: {typ: 13, flags: mysqlUnsigned}, + Bit: {typ: 16, flags: mysqlUnsigned}, + TypeJSON: {typ: 245}, + Decimal: {typ: 246}, + Text: {typ: 252}, + Blob: {typ: 252, flags: mysqlBinary}, + VarChar: {typ: 253}, + VarBinary: {typ: 253, flags: mysqlBinary}, + Char: {typ: 254}, + Binary: {typ: 254, flags: mysqlBinary}, + Enum: {typ: 254, flags: mysqlEnum}, + Set: {typ: 254, flags: mysqlSet}, + Geometry: {typ: 255}, +} + +// TypeToMySQL returns the equivalent mysql type and flag for a vitess type. +func TypeToMySQL(typ querypb.Type) (mysqlType, flags int64) { + val := typeToMySQL[typ] + return val.typ, val.flags +} diff --git a/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/dependency/sqltypes/type_test.go b/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/dependency/sqltypes/type_test.go new file mode 100644 index 00000000..613fcda1 --- /dev/null +++ b/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/dependency/sqltypes/type_test.go @@ -0,0 +1,414 @@ +/* +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 sqltypes + +import ( + "testing" + + "github.com/xwb1989/sqlparser/dependency/querypb" +) + +func TestTypeValues(t *testing.T) { + testcases := []struct { + defined querypb.Type + expected int + }{{ + defined: Null, + expected: 0, + }, { + defined: Int8, + expected: 1 | flagIsIntegral, + }, { + defined: Uint8, + expected: 2 | flagIsIntegral | flagIsUnsigned, + }, { + defined: Int16, + expected: 3 | flagIsIntegral, + }, { + defined: Uint16, + expected: 4 | flagIsIntegral | flagIsUnsigned, + }, { + defined: Int24, + expected: 5 | flagIsIntegral, + }, { + defined: Uint24, + expected: 6 | flagIsIntegral | flagIsUnsigned, + }, { + defined: Int32, + expected: 7 | flagIsIntegral, + }, { + defined: Uint32, + expected: 8 | flagIsIntegral | flagIsUnsigned, + }, { + defined: Int64, + expected: 9 | flagIsIntegral, + }, { + defined: Uint64, + expected: 10 | flagIsIntegral | flagIsUnsigned, + }, { + defined: Float32, + expected: 11 | flagIsFloat, + }, { + defined: Float64, + expected: 12 | flagIsFloat, + }, { + defined: Timestamp, + expected: 13 | flagIsQuoted, + }, { + defined: Date, + expected: 14 | flagIsQuoted, + }, { + defined: Time, + expected: 15 | flagIsQuoted, + }, { + defined: Datetime, + expected: 16 | flagIsQuoted, + }, { + defined: Year, + expected: 17 | flagIsIntegral | flagIsUnsigned, + }, { + defined: Decimal, + expected: 18, + }, { + defined: Text, + expected: 19 | flagIsQuoted | flagIsText, + }, { + defined: Blob, + expected: 20 | flagIsQuoted | flagIsBinary, + }, { + defined: VarChar, + expected: 21 | flagIsQuoted | flagIsText, + }, { + defined: VarBinary, + expected: 22 | flagIsQuoted | flagIsBinary, + }, { + defined: Char, + expected: 23 | flagIsQuoted | flagIsText, + }, { + defined: Binary, + expected: 24 | flagIsQuoted | flagIsBinary, + }, { + defined: Bit, + expected: 25 | flagIsQuoted, + }, { + defined: Enum, + expected: 26 | flagIsQuoted, + }, { + defined: Set, + expected: 27 | flagIsQuoted, + }, { + defined: Geometry, + expected: 29 | flagIsQuoted, + }, { + defined: TypeJSON, + expected: 30 | flagIsQuoted, + }, { + defined: Expression, + expected: 31, + }} + for _, tcase := range testcases { + if int(tcase.defined) != tcase.expected { + t.Errorf("Type %s: %d, want: %d", tcase.defined, int(tcase.defined), tcase.expected) + } + } +} + +// TestCategory verifies that the type categorizations +// are non-overlapping and complete. +func TestCategory(t *testing.T) { + alltypes := []querypb.Type{ + Null, + Int8, + Uint8, + Int16, + Uint16, + Int24, + Uint24, + Int32, + Uint32, + Int64, + Uint64, + Float32, + Float64, + Timestamp, + Date, + Time, + Datetime, + Year, + Decimal, + Text, + Blob, + VarChar, + VarBinary, + Char, + Binary, + Bit, + Enum, + Set, + Geometry, + TypeJSON, + Expression, + } + for _, typ := range alltypes { + matched := false + if IsSigned(typ) { + if !IsIntegral(typ) { + t.Errorf("Signed type %v is not an integral", typ) + } + matched = true + } + if IsUnsigned(typ) { + if !IsIntegral(typ) { + t.Errorf("Unsigned type %v is not an integral", typ) + } + if matched { + t.Errorf("%v matched more than one category", typ) + } + matched = true + } + if IsFloat(typ) { + if matched { + t.Errorf("%v matched more than one category", typ) + } + matched = true + } + if IsQuoted(typ) { + if matched { + t.Errorf("%v matched more than one category", typ) + } + matched = true + } + if typ == Null || typ == Decimal || typ == Expression { + if matched { + t.Errorf("%v matched more than one category", typ) + } + matched = true + } + if !matched { + t.Errorf("%v matched no category", typ) + } + } +} + +func TestIsFunctions(t *testing.T) { + if IsIntegral(Null) { + t.Error("Null: IsIntegral, must be false") + } + if !IsIntegral(Int64) { + t.Error("Int64: !IsIntegral, must be true") + } + if IsSigned(Uint64) { + t.Error("Uint64: IsSigned, must be false") + } + if !IsSigned(Int64) { + t.Error("Int64: !IsSigned, must be true") + } + if IsUnsigned(Int64) { + t.Error("Int64: IsUnsigned, must be false") + } + if !IsUnsigned(Uint64) { + t.Error("Uint64: !IsUnsigned, must be true") + } + if IsFloat(Int64) { + t.Error("Int64: IsFloat, must be false") + } + if !IsFloat(Float64) { + t.Error("Uint64: !IsFloat, must be true") + } + if IsQuoted(Int64) { + t.Error("Int64: IsQuoted, must be false") + } + if !IsQuoted(Binary) { + t.Error("Binary: !IsQuoted, must be true") + } + if IsText(Int64) { + t.Error("Int64: IsText, must be false") + } + if !IsText(Char) { + t.Error("Char: !IsText, must be true") + } + if IsBinary(Int64) { + t.Error("Int64: IsBinary, must be false") + } + if !IsBinary(Binary) { + t.Error("Char: !IsBinary, must be true") + } + if !isNumber(Int64) { + t.Error("Int64: !isNumber, must be true") + } +} + +func TestTypeToMySQL(t *testing.T) { + v, f := TypeToMySQL(Bit) + if v != 16 { + t.Errorf("Bit: %d, want 16", v) + } + if f != mysqlUnsigned { + t.Errorf("Bit flag: %x, want %x", f, mysqlUnsigned) + } + v, f = TypeToMySQL(Date) + if v != 10 { + t.Errorf("Bit: %d, want 10", v) + } + if f != mysqlBinary { + t.Errorf("Bit flag: %x, want %x", f, mysqlBinary) + } +} + +func TestMySQLToType(t *testing.T) { + testcases := []struct { + intype int64 + inflags int64 + outtype querypb.Type + }{{ + intype: 1, + outtype: Int8, + }, { + intype: 1, + inflags: mysqlUnsigned, + outtype: Uint8, + }, { + intype: 2, + outtype: Int16, + }, { + intype: 2, + inflags: mysqlUnsigned, + outtype: Uint16, + }, { + intype: 3, + outtype: Int32, + }, { + intype: 3, + inflags: mysqlUnsigned, + outtype: Uint32, + }, { + intype: 4, + outtype: Float32, + }, { + intype: 5, + outtype: Float64, + }, { + intype: 6, + outtype: Null, + }, { + intype: 7, + outtype: Timestamp, + }, { + intype: 8, + outtype: Int64, + }, { + intype: 8, + inflags: mysqlUnsigned, + outtype: Uint64, + }, { + intype: 9, + outtype: Int24, + }, { + intype: 9, + inflags: mysqlUnsigned, + outtype: Uint24, + }, { + intype: 10, + outtype: Date, + }, { + intype: 11, + outtype: Time, + }, { + intype: 12, + outtype: Datetime, + }, { + intype: 13, + outtype: Year, + }, { + intype: 16, + outtype: Bit, + }, { + intype: 245, + outtype: TypeJSON, + }, { + intype: 246, + outtype: Decimal, + }, { + intype: 249, + outtype: Text, + }, { + intype: 250, + outtype: Text, + }, { + intype: 251, + outtype: Text, + }, { + intype: 252, + outtype: Text, + }, { + intype: 252, + inflags: mysqlBinary, + outtype: Blob, + }, { + intype: 253, + outtype: VarChar, + }, { + intype: 253, + inflags: mysqlBinary, + outtype: VarBinary, + }, { + intype: 254, + outtype: Char, + }, { + intype: 254, + inflags: mysqlBinary, + outtype: Binary, + }, { + intype: 254, + inflags: mysqlEnum, + outtype: Enum, + }, { + intype: 254, + inflags: mysqlSet, + outtype: Set, + }, { + intype: 255, + outtype: Geometry, + }, { + // Binary flag must be ignored. + intype: 8, + inflags: mysqlUnsigned | mysqlBinary, + outtype: Uint64, + }, { + // Unsigned flag must be ignored + intype: 252, + inflags: mysqlUnsigned | mysqlBinary, + outtype: Blob, + }} + for _, tcase := range testcases { + got, err := MySQLToType(tcase.intype, tcase.inflags) + if err != nil { + t.Error(err) + } + if got != tcase.outtype { + t.Errorf("MySQLToType(%d, %x): %v, want %v", tcase.intype, tcase.inflags, got, tcase.outtype) + } + } +} + +func TestTypeError(t *testing.T) { + _, err := MySQLToType(15, 0) + want := "unsupported type: 15" + if err == nil || err.Error() != want { + t.Errorf("MySQLToType: %v, want %s", err, want) + } +} diff --git a/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/dependency/sqltypes/value.go b/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/dependency/sqltypes/value.go new file mode 100644 index 00000000..a3bceeef --- /dev/null +++ b/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/dependency/sqltypes/value.go @@ -0,0 +1,376 @@ +/* +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 sqltypes implements interfaces and types that represent SQL values. +package sqltypes + +import ( + "encoding/base64" + "encoding/json" + "fmt" + "strconv" + + "github.com/xwb1989/sqlparser/dependency/bytes2" + "github.com/xwb1989/sqlparser/dependency/hack" + + "github.com/xwb1989/sqlparser/dependency/querypb" +) + +var ( + // NULL represents the NULL value. + NULL = Value{} + + // DontEscape tells you if a character should not be escaped. + DontEscape = byte(255) + + nullstr = []byte("null") +) + +// BinWriter interface is used for encoding values. +// Types like bytes.Buffer conform to this interface. +// We expect the writer objects to be in-memory buffers. +// So, we don't expect the write operations to fail. +type BinWriter interface { + Write([]byte) (int, error) +} + +// Value can store any SQL value. If the value represents +// an integral type, the bytes are always stored as a cannonical +// representation that matches how MySQL returns such values. +type Value struct { + typ querypb.Type + val []byte +} + +// NewValue builds a Value using typ and val. If the value and typ +// don't match, it returns an error. +func NewValue(typ querypb.Type, val []byte) (v Value, err error) { + switch { + case IsSigned(typ): + if _, err := strconv.ParseInt(string(val), 0, 64); err != nil { + return NULL, err + } + return MakeTrusted(typ, val), nil + case IsUnsigned(typ): + if _, err := strconv.ParseUint(string(val), 0, 64); err != nil { + return NULL, err + } + return MakeTrusted(typ, val), nil + case IsFloat(typ) || typ == Decimal: + if _, err := strconv.ParseFloat(string(val), 64); err != nil { + return NULL, err + } + return MakeTrusted(typ, val), nil + case IsQuoted(typ) || typ == Null: + return MakeTrusted(typ, val), nil + } + // All other types are unsafe or invalid. + return NULL, fmt.Errorf("invalid type specified for MakeValue: %v", typ) +} + +// MakeTrusted makes a new Value based on the type. +// This function should only be used if you know the value +// and type conform to the rules. Every place this function is +// called, a comment is needed that explains why it's justified. +// Exceptions: The current package and mysql package do not need +// comments. Other packages can also use the function to create +// VarBinary or VarChar values. +func MakeTrusted(typ querypb.Type, val []byte) Value { + if typ == Null { + return NULL + } + return Value{typ: typ, val: val} +} + +// NewInt64 builds an Int64 Value. +func NewInt64(v int64) Value { + return MakeTrusted(Int64, strconv.AppendInt(nil, v, 10)) +} + +// NewInt32 builds an Int64 Value. +func NewInt32(v int32) Value { + return MakeTrusted(Int32, strconv.AppendInt(nil, int64(v), 10)) +} + +// NewUint64 builds an Uint64 Value. +func NewUint64(v uint64) Value { + return MakeTrusted(Uint64, strconv.AppendUint(nil, v, 10)) +} + +// NewFloat64 builds an Float64 Value. +func NewFloat64(v float64) Value { + return MakeTrusted(Float64, strconv.AppendFloat(nil, v, 'g', -1, 64)) +} + +// NewVarChar builds a VarChar Value. +func NewVarChar(v string) Value { + return MakeTrusted(VarChar, []byte(v)) +} + +// NewVarBinary builds a VarBinary Value. +// The input is a string because it's the most common use case. +func NewVarBinary(v string) Value { + return MakeTrusted(VarBinary, []byte(v)) +} + +// NewIntegral builds an integral type from a string representaion. +// The type will be Int64 or Uint64. Int64 will be preferred where possible. +func NewIntegral(val string) (n Value, err error) { + signed, err := strconv.ParseInt(val, 0, 64) + if err == nil { + return MakeTrusted(Int64, strconv.AppendInt(nil, signed, 10)), nil + } + unsigned, err := strconv.ParseUint(val, 0, 64) + if err != nil { + return Value{}, err + } + return MakeTrusted(Uint64, strconv.AppendUint(nil, unsigned, 10)), nil +} + +// InterfaceToValue builds a value from a go type. +// Supported types are nil, int64, uint64, float64, +// string and []byte. +// This function is deprecated. Use the type-specific +// functions instead. +func InterfaceToValue(goval interface{}) (Value, error) { + switch goval := goval.(type) { + case nil: + return NULL, nil + case []byte: + return MakeTrusted(VarBinary, goval), nil + case int64: + return NewInt64(goval), nil + case uint64: + return NewUint64(goval), nil + case float64: + return NewFloat64(goval), nil + case string: + return NewVarChar(goval), nil + default: + return NULL, fmt.Errorf("unexpected type %T: %v", goval, goval) + } +} + +// Type returns the type of Value. +func (v Value) Type() querypb.Type { + return v.typ +} + +// Raw returns the internal represenation of the value. For newer types, +// this may not match MySQL's representation. +func (v Value) Raw() []byte { + return v.val +} + +// ToBytes returns the value as MySQL would return it as []byte. +// In contrast, Raw returns the internal representation of the Value, which may not +// match MySQL's representation for newer types. +// If the value is not convertible like in the case of Expression, it returns nil. +func (v Value) ToBytes() []byte { + if v.typ == Expression { + return nil + } + return v.val +} + +// Len returns the length. +func (v Value) Len() int { + return len(v.val) +} + +// ToString returns the value as MySQL would return it as string. +// If the value is not convertible like in the case of Expression, it returns nil. +func (v Value) ToString() string { + if v.typ == Expression { + return "" + } + return hack.String(v.val) +} + +// String returns a printable version of the value. +func (v Value) String() string { + if v.typ == Null { + return "NULL" + } + if v.IsQuoted() { + return fmt.Sprintf("%v(%q)", v.typ, v.val) + } + return fmt.Sprintf("%v(%s)", v.typ, v.val) +} + +// EncodeSQL encodes the value into an SQL statement. Can be binary. +func (v Value) EncodeSQL(b BinWriter) { + switch { + case v.typ == Null: + b.Write(nullstr) + case v.IsQuoted(): + encodeBytesSQL(v.val, b) + default: + b.Write(v.val) + } +} + +// EncodeASCII encodes the value using 7-bit clean ascii bytes. +func (v Value) EncodeASCII(b BinWriter) { + switch { + case v.typ == Null: + b.Write(nullstr) + case v.IsQuoted(): + encodeBytesASCII(v.val, b) + default: + b.Write(v.val) + } +} + +// IsNull returns true if Value is null. +func (v Value) IsNull() bool { + return v.typ == Null +} + +// IsIntegral returns true if Value is an integral. +func (v Value) IsIntegral() bool { + return IsIntegral(v.typ) +} + +// IsSigned returns true if Value is a signed integral. +func (v Value) IsSigned() bool { + return IsSigned(v.typ) +} + +// IsUnsigned returns true if Value is an unsigned integral. +func (v Value) IsUnsigned() bool { + return IsUnsigned(v.typ) +} + +// IsFloat returns true if Value is a float. +func (v Value) IsFloat() bool { + return IsFloat(v.typ) +} + +// IsQuoted returns true if Value must be SQL-quoted. +func (v Value) IsQuoted() bool { + return IsQuoted(v.typ) +} + +// IsText returns true if Value is a collatable text. +func (v Value) IsText() bool { + return IsText(v.typ) +} + +// IsBinary returns true if Value is binary. +func (v Value) IsBinary() bool { + return IsBinary(v.typ) +} + +// MarshalJSON should only be used for testing. +// It's not a complete implementation. +func (v Value) MarshalJSON() ([]byte, error) { + switch { + case v.IsQuoted(): + return json.Marshal(v.ToString()) + case v.typ == Null: + return nullstr, nil + } + return v.val, nil +} + +// UnmarshalJSON should only be used for testing. +// It's not a complete implementation. +func (v *Value) UnmarshalJSON(b []byte) error { + if len(b) == 0 { + return fmt.Errorf("error unmarshaling empty bytes") + } + var val interface{} + var err error + switch b[0] { + case '-': + var ival int64 + err = json.Unmarshal(b, &ival) + val = ival + case '"': + var bval []byte + err = json.Unmarshal(b, &bval) + val = bval + case 'n': // null + err = json.Unmarshal(b, &val) + default: + var uval uint64 + err = json.Unmarshal(b, &uval) + val = uval + } + if err != nil { + return err + } + *v, err = InterfaceToValue(val) + return err +} + +func encodeBytesSQL(val []byte, b BinWriter) { + buf := &bytes2.Buffer{} + buf.WriteByte('\'') + for _, ch := range val { + if encodedChar := SQLEncodeMap[ch]; encodedChar == DontEscape { + buf.WriteByte(ch) + } else { + buf.WriteByte('\\') + buf.WriteByte(encodedChar) + } + } + buf.WriteByte('\'') + b.Write(buf.Bytes()) +} + +func encodeBytesASCII(val []byte, b BinWriter) { + buf := &bytes2.Buffer{} + buf.WriteByte('\'') + encoder := base64.NewEncoder(base64.StdEncoding, buf) + encoder.Write(val) + encoder.Close() + buf.WriteByte('\'') + b.Write(buf.Bytes()) +} + +// SQLEncodeMap specifies how to escape binary data with '\'. +// Complies to http://dev.mysql.com/doc/refman/5.1/en/string-syntax.html +var SQLEncodeMap [256]byte + +// SQLDecodeMap is the reverse of SQLEncodeMap +var SQLDecodeMap [256]byte + +var encodeRef = map[byte]byte{ + '\x00': '0', + '\'': '\'', + '"': '"', + '\b': 'b', + '\n': 'n', + '\r': 'r', + '\t': 't', + 26: 'Z', // ctl-Z + '\\': '\\', +} + +func init() { + for i := range SQLEncodeMap { + SQLEncodeMap[i] = DontEscape + SQLDecodeMap[i] = DontEscape + } + for i := range SQLEncodeMap { + if to, ok := encodeRef[byte(i)]; ok { + SQLEncodeMap[byte(i)] = to + SQLDecodeMap[to] = byte(i) + } + } +} diff --git a/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/dependency/sqltypes/value_test.go b/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/dependency/sqltypes/value_test.go new file mode 100644 index 00000000..96b137d1 --- /dev/null +++ b/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/dependency/sqltypes/value_test.go @@ -0,0 +1,408 @@ +/* +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 sqltypes + +import ( + "bytes" + "reflect" + "strings" + "testing" + + "github.com/xwb1989/sqlparser/dependency/querypb" +) + +const ( + InvalidNeg = "-9223372036854775809" + MinNeg = "-9223372036854775808" + MinPos = "18446744073709551615" + InvalidPos = "18446744073709551616" +) + +func TestNewValue(t *testing.T) { + testcases := []struct { + inType querypb.Type + inVal string + outVal Value + outErr string + }{{ + inType: Null, + inVal: "", + outVal: NULL, + }, { + inType: Int8, + inVal: "1", + outVal: TestValue(Int8, "1"), + }, { + inType: Int16, + inVal: "1", + outVal: TestValue(Int16, "1"), + }, { + inType: Int24, + inVal: "1", + outVal: TestValue(Int24, "1"), + }, { + inType: Int32, + inVal: "1", + outVal: TestValue(Int32, "1"), + }, { + inType: Int64, + inVal: "1", + outVal: TestValue(Int64, "1"), + }, { + inType: Uint8, + inVal: "1", + outVal: TestValue(Uint8, "1"), + }, { + inType: Uint16, + inVal: "1", + outVal: TestValue(Uint16, "1"), + }, { + inType: Uint24, + inVal: "1", + outVal: TestValue(Uint24, "1"), + }, { + inType: Uint32, + inVal: "1", + outVal: TestValue(Uint32, "1"), + }, { + inType: Uint64, + inVal: "1", + outVal: TestValue(Uint64, "1"), + }, { + inType: Float32, + inVal: "1.00", + outVal: TestValue(Float32, "1.00"), + }, { + inType: Float64, + inVal: "1.00", + outVal: TestValue(Float64, "1.00"), + }, { + inType: Decimal, + inVal: "1.00", + outVal: TestValue(Decimal, "1.00"), + }, { + inType: Timestamp, + inVal: "2012-02-24 23:19:43", + outVal: TestValue(Timestamp, "2012-02-24 23:19:43"), + }, { + inType: Date, + inVal: "2012-02-24", + outVal: TestValue(Date, "2012-02-24"), + }, { + inType: Time, + inVal: "23:19:43", + outVal: TestValue(Time, "23:19:43"), + }, { + inType: Datetime, + inVal: "2012-02-24 23:19:43", + outVal: TestValue(Datetime, "2012-02-24 23:19:43"), + }, { + inType: Year, + inVal: "1", + outVal: TestValue(Year, "1"), + }, { + inType: Text, + inVal: "a", + outVal: TestValue(Text, "a"), + }, { + inType: Blob, + inVal: "a", + outVal: TestValue(Blob, "a"), + }, { + inType: VarChar, + inVal: "a", + outVal: TestValue(VarChar, "a"), + }, { + inType: Binary, + inVal: "a", + outVal: TestValue(Binary, "a"), + }, { + inType: Char, + inVal: "a", + outVal: TestValue(Char, "a"), + }, { + inType: Bit, + inVal: "1", + outVal: TestValue(Bit, "1"), + }, { + inType: Enum, + inVal: "a", + outVal: TestValue(Enum, "a"), + }, { + inType: Set, + inVal: "a", + outVal: TestValue(Set, "a"), + }, { + inType: VarBinary, + inVal: "a", + outVal: TestValue(VarBinary, "a"), + }, { + inType: Int64, + inVal: InvalidNeg, + outErr: "out of range", + }, { + inType: Int64, + inVal: InvalidPos, + outErr: "out of range", + }, { + inType: Uint64, + inVal: "-1", + outErr: "invalid syntax", + }, { + inType: Uint64, + inVal: InvalidPos, + outErr: "out of range", + }, { + inType: Float64, + inVal: "a", + outErr: "invalid syntax", + }, { + inType: Expression, + inVal: "a", + outErr: "invalid type specified for MakeValue: EXPRESSION", + }} + for _, tcase := range testcases { + v, err := NewValue(tcase.inType, []byte(tcase.inVal)) + if tcase.outErr != "" { + if err == nil || !strings.Contains(err.Error(), tcase.outErr) { + t.Errorf("ValueFromBytes(%v, %v) error: %v, must contain %v", tcase.inType, tcase.inVal, err, tcase.outErr) + } + continue + } + if err != nil { + t.Errorf("ValueFromBytes(%v, %v) error: %v", tcase.inType, tcase.inVal, err) + continue + } + if !reflect.DeepEqual(v, tcase.outVal) { + t.Errorf("ValueFromBytes(%v, %v) = %v, want %v", tcase.inType, tcase.inVal, v, tcase.outVal) + } + } +} + +// TestNew tests 'New' functions that are not tested +// through other code paths. +func TestNew(t *testing.T) { + got := NewInt32(1) + want := MakeTrusted(Int32, []byte("1")) + if !reflect.DeepEqual(got, want) { + t.Errorf("NewInt32(aa): %v, want %v", got, want) + } + + got = NewVarBinary("aa") + want = MakeTrusted(VarBinary, []byte("aa")) + if !reflect.DeepEqual(got, want) { + t.Errorf("NewVarBinary(aa): %v, want %v", got, want) + } +} + +func TestMakeTrusted(t *testing.T) { + v := MakeTrusted(Null, []byte("abcd")) + if !reflect.DeepEqual(v, NULL) { + t.Errorf("MakeTrusted(Null...) = %v, want null", v) + } + v = MakeTrusted(Int64, []byte("1")) + want := TestValue(Int64, "1") + if !reflect.DeepEqual(v, want) { + t.Errorf("MakeTrusted(Int64, \"1\") = %v, want %v", v, want) + } +} + +func TestIntegralValue(t *testing.T) { + testcases := []struct { + in string + outVal Value + outErr string + }{{ + in: MinNeg, + outVal: TestValue(Int64, MinNeg), + }, { + in: "1", + outVal: TestValue(Int64, "1"), + }, { + in: MinPos, + outVal: TestValue(Uint64, MinPos), + }, { + in: InvalidPos, + outErr: "out of range", + }} + for _, tcase := range testcases { + v, err := NewIntegral(tcase.in) + if tcase.outErr != "" { + if err == nil || !strings.Contains(err.Error(), tcase.outErr) { + t.Errorf("BuildIntegral(%v) error: %v, must contain %v", tcase.in, err, tcase.outErr) + } + continue + } + if err != nil { + t.Errorf("BuildIntegral(%v) error: %v", tcase.in, err) + continue + } + if !reflect.DeepEqual(v, tcase.outVal) { + t.Errorf("BuildIntegral(%v) = %v, want %v", tcase.in, v, tcase.outVal) + } + } +} + +func TestInerfaceValue(t *testing.T) { + testcases := []struct { + in interface{} + out Value + }{{ + in: nil, + out: NULL, + }, { + in: []byte("a"), + out: TestValue(VarBinary, "a"), + }, { + in: int64(1), + out: TestValue(Int64, "1"), + }, { + in: uint64(1), + out: TestValue(Uint64, "1"), + }, { + in: float64(1.2), + out: TestValue(Float64, "1.2"), + }, { + in: "a", + out: TestValue(VarChar, "a"), + }} + for _, tcase := range testcases { + v, err := InterfaceToValue(tcase.in) + if err != nil { + t.Errorf("BuildValue(%#v) error: %v", tcase.in, err) + continue + } + if !reflect.DeepEqual(v, tcase.out) { + t.Errorf("BuildValue(%#v) = %v, want %v", tcase.in, v, tcase.out) + } + } + + _, err := InterfaceToValue(make(chan bool)) + want := "unexpected" + if err == nil || !strings.Contains(err.Error(), want) { + t.Errorf("BuildValue(chan): %v, want %v", err, want) + } +} + +func TestAccessors(t *testing.T) { + v := TestValue(Int64, "1") + if v.Type() != Int64 { + t.Errorf("v.Type=%v, want Int64", v.Type()) + } + if !bytes.Equal(v.Raw(), []byte("1")) { + t.Errorf("v.Raw=%s, want 1", v.Raw()) + } + if v.Len() != 1 { + t.Errorf("v.Len=%d, want 1", v.Len()) + } + if v.ToString() != "1" { + t.Errorf("v.String=%s, want 1", v.ToString()) + } + if v.IsNull() { + t.Error("v.IsNull: true, want false") + } + if !v.IsIntegral() { + t.Error("v.IsIntegral: false, want true") + } + if !v.IsSigned() { + t.Error("v.IsSigned: false, want true") + } + if v.IsUnsigned() { + t.Error("v.IsUnsigned: true, want false") + } + if v.IsFloat() { + t.Error("v.IsFloat: true, want false") + } + if v.IsQuoted() { + t.Error("v.IsQuoted: true, want false") + } + if v.IsText() { + t.Error("v.IsText: true, want false") + } + if v.IsBinary() { + t.Error("v.IsBinary: true, want false") + } +} + +func TestToBytesAndString(t *testing.T) { + for _, v := range []Value{ + NULL, + TestValue(Int64, "1"), + TestValue(Int64, "12"), + } { + if b := v.ToBytes(); bytes.Compare(b, v.Raw()) != 0 { + t.Errorf("%v.ToBytes: %s, want %s", v, b, v.Raw()) + } + if s := v.ToString(); s != string(v.Raw()) { + t.Errorf("%v.ToString: %s, want %s", v, s, v.Raw()) + } + } + + tv := TestValue(Expression, "aa") + if b := tv.ToBytes(); b != nil { + t.Errorf("%v.ToBytes: %s, want nil", tv, b) + } + if s := tv.ToString(); s != "" { + t.Errorf("%v.ToString: %s, want \"\"", tv, s) + } +} + +func TestEncode(t *testing.T) { + testcases := []struct { + in Value + outSQL string + outASCII string + }{{ + in: NULL, + outSQL: "null", + outASCII: "null", + }, { + in: TestValue(Int64, "1"), + outSQL: "1", + outASCII: "1", + }, { + in: TestValue(VarChar, "foo"), + outSQL: "'foo'", + outASCII: "'Zm9v'", + }, { + in: TestValue(VarChar, "\x00'\"\b\n\r\t\x1A\\"), + outSQL: "'\\0\\'\\\"\\b\\n\\r\\t\\Z\\\\'", + outASCII: "'ACciCAoNCRpc'", + }} + for _, tcase := range testcases { + buf := &bytes.Buffer{} + tcase.in.EncodeSQL(buf) + if tcase.outSQL != buf.String() { + t.Errorf("%v.EncodeSQL = %q, want %q", tcase.in, buf.String(), tcase.outSQL) + } + buf = &bytes.Buffer{} + tcase.in.EncodeASCII(buf) + if tcase.outASCII != buf.String() { + t.Errorf("%v.EncodeASCII = %q, want %q", tcase.in, buf.String(), tcase.outASCII) + } + } +} + +// TestEncodeMap ensures DontEscape is not escaped +func TestEncodeMap(t *testing.T) { + if SQLEncodeMap[DontEscape] != DontEscape { + t.Errorf("SQLEncodeMap[DontEscape] = %v, want %v", SQLEncodeMap[DontEscape], DontEscape) + } + if SQLDecodeMap[DontEscape] != DontEscape { + t.Errorf("SQLDecodeMap[DontEscape] = %v, want %v", SQLEncodeMap[DontEscape], DontEscape) + } +} diff --git a/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/encodable.go b/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/encodable.go new file mode 100644 index 00000000..badfa42d --- /dev/null +++ b/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/encodable.go @@ -0,0 +1,99 @@ +/* +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 sqlparser + +import ( + "bytes" + + "github.com/xwb1989/sqlparser/dependency/sqltypes" +) + +// This file contains types that are 'Encodable'. + +// Encodable defines the interface for types that can +// be custom-encoded into SQL. +type Encodable interface { + EncodeSQL(buf *bytes.Buffer) +} + +// InsertValues is a custom SQL encoder for the values of +// an insert statement. +type InsertValues [][]sqltypes.Value + +// EncodeSQL performs the SQL encoding for InsertValues. +func (iv InsertValues) EncodeSQL(buf *bytes.Buffer) { + for i, rows := range iv { + if i != 0 { + buf.WriteString(", ") + } + buf.WriteByte('(') + for j, bv := range rows { + if j != 0 { + buf.WriteString(", ") + } + bv.EncodeSQL(buf) + } + buf.WriteByte(')') + } +} + +// TupleEqualityList is for generating equality constraints +// for tables that have composite primary keys. +type TupleEqualityList struct { + Columns []ColIdent + Rows [][]sqltypes.Value +} + +// EncodeSQL generates the where clause constraints for the tuple +// equality. +func (tpl *TupleEqualityList) EncodeSQL(buf *bytes.Buffer) { + if len(tpl.Columns) == 1 { + tpl.encodeAsIn(buf) + return + } + tpl.encodeAsEquality(buf) +} + +func (tpl *TupleEqualityList) encodeAsIn(buf *bytes.Buffer) { + Append(buf, tpl.Columns[0]) + buf.WriteString(" in (") + for i, r := range tpl.Rows { + if i != 0 { + buf.WriteString(", ") + } + r[0].EncodeSQL(buf) + } + buf.WriteByte(')') +} + +func (tpl *TupleEqualityList) encodeAsEquality(buf *bytes.Buffer) { + for i, r := range tpl.Rows { + if i != 0 { + buf.WriteString(" or ") + } + buf.WriteString("(") + for j, c := range tpl.Columns { + if j != 0 { + buf.WriteString(" and ") + } + Append(buf, c) + buf.WriteString(" = ") + r[j].EncodeSQL(buf) + } + buf.WriteByte(')') + } +} diff --git a/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/encodable_test.go b/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/encodable_test.go new file mode 100644 index 00000000..3bfc7748 --- /dev/null +++ b/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/encodable_test.go @@ -0,0 +1,73 @@ +/* +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 sqlparser + +import ( + "bytes" + "testing" + + "github.com/xwb1989/sqlparser/dependency/sqltypes" +) + +func TestEncodable(t *testing.T) { + tcases := []struct { + in Encodable + out string + }{{ + in: InsertValues{{ + sqltypes.NewInt64(1), + sqltypes.NewVarBinary("foo('a')"), + }, { + sqltypes.NewInt64(2), + sqltypes.NewVarBinary("bar(`b`)"), + }}, + out: "(1, 'foo(\\'a\\')'), (2, 'bar(`b`)')", + }, { + // Single column. + in: &TupleEqualityList{ + Columns: []ColIdent{NewColIdent("pk")}, + Rows: [][]sqltypes.Value{ + {sqltypes.NewInt64(1)}, + {sqltypes.NewVarBinary("aa")}, + }, + }, + out: "pk in (1, 'aa')", + }, { + // Multiple columns. + in: &TupleEqualityList{ + Columns: []ColIdent{NewColIdent("pk1"), NewColIdent("pk2")}, + Rows: [][]sqltypes.Value{ + { + sqltypes.NewInt64(1), + sqltypes.NewVarBinary("aa"), + }, + { + sqltypes.NewInt64(2), + sqltypes.NewVarBinary("bb"), + }, + }, + }, + out: "(pk1 = 1 and pk2 = 'aa') or (pk1 = 2 and pk2 = 'bb')", + }} + for _, tcase := range tcases { + buf := new(bytes.Buffer) + tcase.in.EncodeSQL(buf) + if out := buf.String(); out != tcase.out { + t.Errorf("EncodeSQL(%v): %s, want %s", tcase.in, out, tcase.out) + } + } +} diff --git a/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/github_test.go b/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/github_test.go new file mode 100644 index 00000000..01ab03ef --- /dev/null +++ b/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/github_test.go @@ -0,0 +1,82 @@ +/* +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 agreedto in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +package sqlparser + +// Additional tests to address the GitHub issues for this fork. + +import ( + "io" + "strings" + "testing" +) + +func TestParsing(t *testing.T) { + tests := []struct { + id int // Github issue ID + sql string + skip string + }{ + {id: 9, sql: "select 1 as 测试 from dual", skip: "Broken due to ReadByte()"}, + {id: 12, sql: "SELECT * FROM AccessToken LIMIT 10 OFFSET 13"}, + {id: 14, sql: "SELECT DATE_SUB(NOW(), INTERVAL 1 MONTH)"}, + {id: 15, sql: "select STRAIGHT_JOIN t1.* FROM t1 INNER JOIN t2 ON t1.CommonID = t2.CommonID WHERE t1.FilterID = 1"}, + {id: 16, sql: "SELECT a FROM t WHERE FUNC(a) = 1"}, // Doesn't seem broken, need better example + {id: 21, sql: `CREATE TABLE t (UpdateDatetime TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP)`}, + {id: 21, sql: `CREATE TABLE t (UpdateDatetime TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间')`}, + {id: 24, sql: `select * from t1 join t2 using(id)`}, + } + + for _, test := range tests { + if test.skip != "" { + continue + } + + if _, err := Parse(test.sql); err != nil { + t.Errorf("https://github.com/xwb1989/sqlparser/issues/%d:\nParse(%q) err = %s, want nil", test.id, test.sql, err) + } + } +} + +// ExampleParse is the first example from the README.md. +func ExampleParse() { + sql := "SELECT * FROM table WHERE a = 'abc'" + stmt, err := Parse(sql) + if err != nil { + // Do something with the err + } + + // Otherwise do something with stmt + switch stmt := stmt.(type) { + case *Select: + _ = stmt + case *Insert: + } +} + +// ExampleParseNext is the second example from the README.md. +func ExampleParseNext() { + r := strings.NewReader("INSERT INTO table1 VALUES (1, 'a'); INSERT INTO table2 VALUES (3, 4);") + + tokens := NewTokenizer(r) + for { + stmt, err := ParseNext(tokens) + if err == io.EOF { + break + } + // Do something with stmt or err. + _ = stmt + } +} diff --git a/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/impossible_query.go b/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/impossible_query.go new file mode 100644 index 00000000..1179b611 --- /dev/null +++ b/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/impossible_query.go @@ -0,0 +1,39 @@ +/* +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 agreedto in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package sqlparser + +// FormatImpossibleQuery creates an impossible query in a TrackedBuffer. +// An impossible query is a modified version of a query where all selects have where clauses that are +// impossible for mysql to resolve. This is used in the vtgate and vttablet: +// +// - In the vtgate it's used for joins: if the first query returns no result, then vtgate uses the impossible +// query just to fetch field info from vttablet +// - In the vttablet, it's just an optimization: the field info is fetched once form MySQL, cached and reused +// for subsequent queries +func FormatImpossibleQuery(buf *TrackedBuffer, node SQLNode) { + switch node := node.(type) { + case *Select: + buf.Myprintf("select %v from %v where 1 != 1", node.SelectExprs, node.From) + if node.GroupBy != nil { + node.GroupBy.Format(buf) + } + case *Union: + buf.Myprintf("%v %s %v", node.Left, node.Type, node.Right) + default: + node.Format(buf) + } +} diff --git a/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/normalizer.go b/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/normalizer.go new file mode 100644 index 00000000..f6520316 --- /dev/null +++ b/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/normalizer.go @@ -0,0 +1,224 @@ +/* +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 sqlparser + +import ( + "fmt" + + "github.com/xwb1989/sqlparser/dependency/sqltypes" + + "github.com/xwb1989/sqlparser/dependency/querypb" +) + +// Normalize changes the statement to use bind values, and +// updates the bind vars to those values. The supplied prefix +// is used to generate the bind var names. The function ensures +// that there are no collisions with existing bind vars. +// Within Select constructs, bind vars are deduped. This allows +// us to identify vindex equality. Otherwise, every value is +// treated as distinct. +func Normalize(stmt Statement, bindVars map[string]*querypb.BindVariable, prefix string) { + nz := newNormalizer(stmt, bindVars, prefix) + _ = Walk(nz.WalkStatement, stmt) +} + +type normalizer struct { + stmt Statement + bindVars map[string]*querypb.BindVariable + prefix string + reserved map[string]struct{} + counter int + vals map[string]string +} + +func newNormalizer(stmt Statement, bindVars map[string]*querypb.BindVariable, prefix string) *normalizer { + return &normalizer{ + stmt: stmt, + bindVars: bindVars, + prefix: prefix, + reserved: GetBindvars(stmt), + counter: 1, + vals: make(map[string]string), + } +} + +// WalkStatement is the top level walk function. +// If it encounters a Select, it switches to a mode +// where variables are deduped. +func (nz *normalizer) WalkStatement(node SQLNode) (bool, error) { + switch node := node.(type) { + case *Select: + _ = Walk(nz.WalkSelect, node) + // Don't continue + return false, nil + case *SQLVal: + nz.convertSQLVal(node) + case *ComparisonExpr: + nz.convertComparison(node) + } + return true, nil +} + +// WalkSelect normalizes the AST in Select mode. +func (nz *normalizer) WalkSelect(node SQLNode) (bool, error) { + switch node := node.(type) { + case *SQLVal: + nz.convertSQLValDedup(node) + case *ComparisonExpr: + nz.convertComparison(node) + } + return true, nil +} + +func (nz *normalizer) convertSQLValDedup(node *SQLVal) { + // If value is too long, don't dedup. + // Such values are most likely not for vindexes. + // We save a lot of CPU because we avoid building + // the key for them. + if len(node.Val) > 256 { + nz.convertSQLVal(node) + return + } + + // Make the bindvar + bval := nz.sqlToBindvar(node) + if bval == nil { + return + } + + // Check if there's a bindvar for that value already. + var key string + if bval.Type == sqltypes.VarBinary { + // Prefixing strings with "'" ensures that a string + // and number that have the same representation don't + // collide. + key = "'" + string(node.Val) + } else { + key = string(node.Val) + } + bvname, ok := nz.vals[key] + if !ok { + // If there's no such bindvar, make a new one. + bvname = nz.newName() + nz.vals[key] = bvname + nz.bindVars[bvname] = bval + } + + // Modify the AST node to a bindvar. + node.Type = ValArg + node.Val = append([]byte(":"), bvname...) +} + +// convertSQLVal converts an SQLVal without the dedup. +func (nz *normalizer) convertSQLVal(node *SQLVal) { + bval := nz.sqlToBindvar(node) + if bval == nil { + return + } + + bvname := nz.newName() + nz.bindVars[bvname] = bval + + node.Type = ValArg + node.Val = append([]byte(":"), bvname...) +} + +// convertComparison attempts to convert IN clauses to +// use the list bind var construct. If it fails, it returns +// with no change made. The walk function will then continue +// and iterate on converting each individual value into separate +// bind vars. +func (nz *normalizer) convertComparison(node *ComparisonExpr) { + if node.Operator != InStr && node.Operator != NotInStr { + return + } + tupleVals, ok := node.Right.(ValTuple) + if !ok { + return + } + // The RHS is a tuple of values. + // Make a list bindvar. + bvals := &querypb.BindVariable{ + Type: querypb.Type_TUPLE, + } + for _, val := range tupleVals { + bval := nz.sqlToBindvar(val) + if bval == nil { + return + } + bvals.Values = append(bvals.Values, &querypb.Value{ + Type: bval.Type, + Value: bval.Value, + }) + } + bvname := nz.newName() + nz.bindVars[bvname] = bvals + // Modify RHS to be a list bindvar. + node.Right = ListArg(append([]byte("::"), bvname...)) +} + +func (nz *normalizer) sqlToBindvar(node SQLNode) *querypb.BindVariable { + if node, ok := node.(*SQLVal); ok { + var v sqltypes.Value + var err error + switch node.Type { + case StrVal: + v, err = sqltypes.NewValue(sqltypes.VarBinary, node.Val) + case IntVal: + v, err = sqltypes.NewValue(sqltypes.Int64, node.Val) + case FloatVal: + v, err = sqltypes.NewValue(sqltypes.Float64, node.Val) + default: + return nil + } + if err != nil { + return nil + } + return sqltypes.ValueBindVariable(v) + } + return nil +} + +func (nz *normalizer) newName() string { + for { + newName := fmt.Sprintf("%s%d", nz.prefix, nz.counter) + if _, ok := nz.reserved[newName]; !ok { + nz.reserved[newName] = struct{}{} + return newName + } + nz.counter++ + } +} + +// GetBindvars returns a map of the bind vars referenced in the statement. +// TODO(sougou); This function gets called again from vtgate/planbuilder. +// Ideally, this should be done only once. +func GetBindvars(stmt Statement) map[string]struct{} { + bindvars := make(map[string]struct{}) + _ = Walk(func(node SQLNode) (kontinue bool, err error) { + switch node := node.(type) { + case *SQLVal: + if node.Type == ValArg { + bindvars[string(node.Val[1:])] = struct{}{} + } + case ListArg: + bindvars[string(node[2:])] = struct{}{} + } + return true, nil + }, stmt) + return bindvars +} diff --git a/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/normalizer_test.go b/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/normalizer_test.go new file mode 100644 index 00000000..20f7e39d --- /dev/null +++ b/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/normalizer_test.go @@ -0,0 +1,206 @@ +/* +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 sqlparser + +import ( + "fmt" + "reflect" + "testing" + + "github.com/xwb1989/sqlparser/dependency/querypb" + "github.com/xwb1989/sqlparser/dependency/sqltypes" +) + +func TestNormalize(t *testing.T) { + prefix := "bv" + testcases := []struct { + in string + outstmt string + outbv map[string]*querypb.BindVariable + }{{ + // str val + in: "select * from t where v1 = 'aa'", + outstmt: "select * from t where v1 = :bv1", + outbv: map[string]*querypb.BindVariable{ + "bv1": sqltypes.BytesBindVariable([]byte("aa")), + }, + }, { + // int val + in: "select * from t where v1 = 1", + outstmt: "select * from t where v1 = :bv1", + outbv: map[string]*querypb.BindVariable{ + "bv1": sqltypes.Int64BindVariable(1), + }, + }, { + // float val + in: "select * from t where v1 = 1.2", + outstmt: "select * from t where v1 = :bv1", + outbv: map[string]*querypb.BindVariable{ + "bv1": sqltypes.Float64BindVariable(1.2), + }, + }, { + // multiple vals + in: "select * from t where v1 = 1.2 and v2 = 2", + outstmt: "select * from t where v1 = :bv1 and v2 = :bv2", + outbv: map[string]*querypb.BindVariable{ + "bv1": sqltypes.Float64BindVariable(1.2), + "bv2": sqltypes.Int64BindVariable(2), + }, + }, { + // bv collision + in: "select * from t where v1 = :bv1 and v2 = 1", + outstmt: "select * from t where v1 = :bv1 and v2 = :bv2", + outbv: map[string]*querypb.BindVariable{ + "bv2": sqltypes.Int64BindVariable(1), + }, + }, { + // val reuse + in: "select * from t where v1 = 1 and v2 = 1", + outstmt: "select * from t where v1 = :bv1 and v2 = :bv1", + outbv: map[string]*querypb.BindVariable{ + "bv1": sqltypes.Int64BindVariable(1), + }, + }, { + // ints and strings are different + in: "select * from t where v1 = 1 and v2 = '1'", + outstmt: "select * from t where v1 = :bv1 and v2 = :bv2", + outbv: map[string]*querypb.BindVariable{ + "bv1": sqltypes.Int64BindVariable(1), + "bv2": sqltypes.BytesBindVariable([]byte("1")), + }, + }, { + // val should not be reused for non-select statements + in: "insert into a values(1, 1)", + outstmt: "insert into a values (:bv1, :bv2)", + outbv: map[string]*querypb.BindVariable{ + "bv1": sqltypes.Int64BindVariable(1), + "bv2": sqltypes.Int64BindVariable(1), + }, + }, { + // val should be reused only in subqueries of DMLs + in: "update a set v1=(select 5 from t), v2=5, v3=(select 5 from t), v4=5", + outstmt: "update a set v1 = (select :bv1 from t), v2 = :bv2, v3 = (select :bv1 from t), v4 = :bv3", + outbv: map[string]*querypb.BindVariable{ + "bv1": sqltypes.Int64BindVariable(5), + "bv2": sqltypes.Int64BindVariable(5), + "bv3": sqltypes.Int64BindVariable(5), + }, + }, { + // list vars should work for DMLs also + in: "update a set v1=5 where v2 in (1, 4, 5)", + outstmt: "update a set v1 = :bv1 where v2 in ::bv2", + outbv: map[string]*querypb.BindVariable{ + "bv1": sqltypes.Int64BindVariable(5), + "bv2": sqltypes.TestBindVariable([]interface{}{1, 4, 5}), + }, + }, { + // Hex value does not convert + in: "select * from t where v1 = 0x1234", + outstmt: "select * from t where v1 = 0x1234", + outbv: map[string]*querypb.BindVariable{}, + }, { + // Hex value does not convert for DMLs + in: "update a set v1 = 0x1234", + outstmt: "update a set v1 = 0x1234", + outbv: map[string]*querypb.BindVariable{}, + }, { + // Values up to len 256 will reuse. + in: fmt.Sprintf("select * from t where v1 = '%256s' and v2 = '%256s'", "a", "a"), + outstmt: "select * from t where v1 = :bv1 and v2 = :bv1", + outbv: map[string]*querypb.BindVariable{ + "bv1": sqltypes.BytesBindVariable([]byte(fmt.Sprintf("%256s", "a"))), + }, + }, { + // Values greater than len 256 will not reuse. + in: fmt.Sprintf("select * from t where v1 = '%257s' and v2 = '%257s'", "b", "b"), + outstmt: "select * from t where v1 = :bv1 and v2 = :bv2", + outbv: map[string]*querypb.BindVariable{ + "bv1": sqltypes.BytesBindVariable([]byte(fmt.Sprintf("%257s", "b"))), + "bv2": sqltypes.BytesBindVariable([]byte(fmt.Sprintf("%257s", "b"))), + }, + }, { + // bad int + in: "select * from t where v1 = 12345678901234567890", + outstmt: "select * from t where v1 = 12345678901234567890", + outbv: map[string]*querypb.BindVariable{}, + }, { + // comparison with no vals + in: "select * from t where v1 = v2", + outstmt: "select * from t where v1 = v2", + outbv: map[string]*querypb.BindVariable{}, + }, { + // IN clause with existing bv + in: "select * from t where v1 in ::list", + outstmt: "select * from t where v1 in ::list", + outbv: map[string]*querypb.BindVariable{}, + }, { + // IN clause with non-val values + in: "select * from t where v1 in (1, a)", + outstmt: "select * from t where v1 in (:bv1, a)", + outbv: map[string]*querypb.BindVariable{ + "bv1": sqltypes.Int64BindVariable(1), + }, + }, { + // IN clause with vals + in: "select * from t where v1 in (1, '2')", + outstmt: "select * from t where v1 in ::bv1", + outbv: map[string]*querypb.BindVariable{ + "bv1": sqltypes.TestBindVariable([]interface{}{1, []byte("2")}), + }, + }, { + // NOT IN clause + in: "select * from t where v1 not in (1, '2')", + outstmt: "select * from t where v1 not in ::bv1", + outbv: map[string]*querypb.BindVariable{ + "bv1": sqltypes.TestBindVariable([]interface{}{1, []byte("2")}), + }, + }} + for _, tc := range testcases { + stmt, err := Parse(tc.in) + if err != nil { + t.Error(err) + continue + } + bv := make(map[string]*querypb.BindVariable) + Normalize(stmt, bv, prefix) + outstmt := String(stmt) + if outstmt != tc.outstmt { + t.Errorf("Query:\n%s:\n%s, want\n%s", tc.in, outstmt, tc.outstmt) + } + if !reflect.DeepEqual(tc.outbv, bv) { + t.Errorf("Query:\n%s:\n%v, want\n%v", tc.in, bv, tc.outbv) + } + } +} + +func TestGetBindVars(t *testing.T) { + stmt, err := Parse("select * from t where :v1 = :v2 and :v2 = :v3 and :v4 in ::v5") + if err != nil { + t.Fatal(err) + } + got := GetBindvars(stmt) + want := map[string]struct{}{ + "v1": {}, + "v2": {}, + "v3": {}, + "v4": {}, + "v5": {}, + } + if !reflect.DeepEqual(got, want) { + t.Errorf("GetBindVars: %v, want: %v", got, want) + } +} diff --git a/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/parse_next_test.go b/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/parse_next_test.go new file mode 100644 index 00000000..bb92f9f2 --- /dev/null +++ b/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/parse_next_test.go @@ -0,0 +1,163 @@ +/* +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 sqlparser + +import ( + "bytes" + "io" + "strings" + "testing" +) + +// TestParseNextValid concatenates all the valid SQL test cases and check it can read +// them as one long string. +func TestParseNextValid(t *testing.T) { + var sql bytes.Buffer + for _, tcase := range validSQL { + sql.WriteString(strings.TrimSuffix(tcase.input, ";")) + sql.WriteRune(';') + } + + tokens := NewTokenizer(&sql) + for i, tcase := range validSQL { + input := tcase.input + ";" + want := tcase.output + if want == "" { + want = tcase.input + } + + tree, err := ParseNext(tokens) + if err != nil { + t.Fatalf("[%d] ParseNext(%q) err: %q, want nil", i, input, err) + continue + } + + if got := String(tree); got != want { + t.Fatalf("[%d] ParseNext(%q) = %q, want %q", i, input, got, want) + } + } + + // Read once more and it should be EOF. + if tree, err := ParseNext(tokens); err != io.EOF { + t.Errorf("ParseNext(tokens) = (%q, %v) want io.EOF", String(tree), err) + } +} + +// TestParseNextErrors tests all the error cases, and ensures a valid +// SQL statement can be passed afterwards. +func TestParseNextErrors(t *testing.T) { + for _, tcase := range invalidSQL { + if tcase.excludeMulti { + // Skip tests which leave unclosed strings, or comments. + continue + } + + sql := tcase.input + "; select 1 from t" + tokens := NewStringTokenizer(sql) + + // The first statement should be an error + _, err := ParseNext(tokens) + if err == nil || err.Error() != tcase.output { + t.Fatalf("[0] ParseNext(%q) err: %q, want %q", sql, err, tcase.output) + continue + } + + // The second should be valid + tree, err := ParseNext(tokens) + if err != nil { + t.Fatalf("[1] ParseNext(%q) err: %q, want nil", sql, err) + continue + } + + want := "select 1 from t" + if got := String(tree); got != want { + t.Fatalf("[1] ParseNext(%q) = %q, want %q", sql, got, want) + } + + // Read once more and it should be EOF. + if tree, err := ParseNext(tokens); err != io.EOF { + t.Errorf("ParseNext(tokens) = (%q, %v) want io.EOF", String(tree), err) + } + } +} + +// TestParseNextEdgeCases tests various ParseNext edge cases. +func TestParseNextEdgeCases(t *testing.T) { + tests := []struct { + name string + input string + want []string + }{{ + name: "Trailing ;", + input: "select 1 from a; update a set b = 2;", + want: []string{"select 1 from a", "update a set b = 2"}, + }, { + name: "No trailing ;", + input: "select 1 from a; update a set b = 2", + want: []string{"select 1 from a", "update a set b = 2"}, + }, { + name: "Trailing whitespace", + input: "select 1 from a; update a set b = 2 ", + want: []string{"select 1 from a", "update a set b = 2"}, + }, { + name: "Trailing whitespace and ;", + input: "select 1 from a; update a set b = 2 ; ", + want: []string{"select 1 from a", "update a set b = 2"}, + }, { + name: "Handle ForceEOF statements", + input: "set character set utf8; select 1 from a", + want: []string{"set charset 'utf8'", "select 1 from a"}, + }, { + name: "Semicolin inside a string", + input: "set character set ';'; select 1 from a", + want: []string{"set charset ';'", "select 1 from a"}, + }, { + name: "Partial DDL", + input: "create table a; select 1 from a", + want: []string{"create table a", "select 1 from a"}, + }, { + name: "Partial DDL", + input: "create table a ignore me this is garbage; select 1 from a", + want: []string{"create table a", "select 1 from a"}, + }} + + for _, test := range tests { + tokens := NewStringTokenizer(test.input) + + for i, want := range test.want { + tree, err := ParseNext(tokens) + if err != nil { + t.Fatalf("[%d] ParseNext(%q) err = %q, want nil", i, test.input, err) + continue + } + + if got := String(tree); got != want { + t.Fatalf("[%d] ParseNext(%q) = %q, want %q", i, test.input, got, want) + } + } + + // Read once more and it should be EOF. + if tree, err := ParseNext(tokens); err != io.EOF { + t.Errorf("ParseNext(%q) = (%q, %v) want io.EOF", test.input, String(tree), err) + } + + // And again, once more should be EOF. + if tree, err := ParseNext(tokens); err != io.EOF { + t.Errorf("ParseNext(%q) = (%q, %v) want io.EOF", test.input, String(tree), err) + } + } +} diff --git a/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/parse_test.go b/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/parse_test.go new file mode 100644 index 00000000..ac659621 --- /dev/null +++ b/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/parse_test.go @@ -0,0 +1,2126 @@ +/* +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 sqlparser + +import ( + "bytes" + "fmt" + "strings" + "testing" +) + +var ( + validSQL = []struct { + input string + output string + }{{ + input: "select 1", + output: "select 1 from dual", + }, { + input: "select 1 from t", + }, { + input: "select .1 from t", + }, { + input: "select 1.2e1 from t", + }, { + input: "select 1.2e+1 from t", + }, { + input: "select 1.2e-1 from t", + }, { + input: "select 08.3 from t", + }, { + input: "select -1 from t where b = -2", + }, { + input: "select - -1 from t", + output: "select 1 from t", + }, { + input: "select 1 from t // aa\n", + output: "select 1 from t", + }, { + input: "select 1 from t -- aa\n", + output: "select 1 from t", + }, { + input: "select 1 from t # aa\n", + output: "select 1 from t", + }, { + input: "select 1 --aa\nfrom t", + output: "select 1 from t", + }, { + input: "select 1 #aa\nfrom t", + output: "select 1 from t", + }, { + input: "select /* simplest */ 1 from t", + }, { + input: "select /* double star **/ 1 from t", + }, { + input: "select /* double */ /* comment */ 1 from t", + }, { + input: "select /* back-quote keyword */ `By` from t", + }, { + input: "select /* back-quote num */ `2a` from t", + }, { + input: "select /* back-quote . */ `a.b` from t", + }, { + input: "select /* back-quote back-quote */ `a``b` from t", + }, { + input: "select /* back-quote unnecessary */ 1 from `t`", + output: "select /* back-quote unnecessary */ 1 from t", + }, { + input: "select /* back-quote idnum */ 1 from `a1`", + output: "select /* back-quote idnum */ 1 from a1", + }, { + input: "select /* @ */ @@a from b", + }, { + input: "select /* \\0 */ '\\0' from a", + }, { + input: "select 1 /* drop this comment */ from t", + output: "select 1 from t", + }, { + input: "select /* union */ 1 from t union select 1 from t", + }, { + input: "select /* double union */ 1 from t union select 1 from t union select 1 from t", + }, { + input: "select /* union all */ 1 from t union all select 1 from t", + }, { + input: "select /* union distinct */ 1 from t union distinct select 1 from t", + }, { + input: "(select /* union parenthesized select */ 1 from t order by a) union select 1 from t", + output: "(select /* union parenthesized select */ 1 from t order by a asc) union select 1 from t", + }, { + input: "select /* union parenthesized select 2 */ 1 from t union (select 1 from t)", + }, { + input: "select /* union order by */ 1 from t union select 1 from t order by a", + output: "select /* union order by */ 1 from t union select 1 from t order by a asc", + }, { + input: "select /* union order by limit lock */ 1 from t union select 1 from t order by a limit 1 for update", + output: "select /* union order by limit lock */ 1 from t union select 1 from t order by a asc limit 1 for update", + }, { + input: "select /* union with limit on lhs */ 1 from t limit 1 union select 1 from t", + }, { + input: "(select id, a from t order by id limit 1) union (select id, b as a from s order by id limit 1) order by a limit 1", + output: "(select id, a from t order by id asc limit 1) union (select id, b as a from s order by id asc limit 1) order by a asc limit 1", + }, { + input: "select a from (select 1 as a from tbl1 union select 2 from tbl2) as t", + }, { + input: "select * from t1 join (select * from t2 union select * from t3) as t", + }, { + // Ensure this doesn't generate: ""select * from t1 join t2 on a = b join t3 on a = b". + input: "select * from t1 join t2 on a = b join t3", + }, { + input: "select * from t1 where col in (select 1 from dual union select 2 from dual)", + }, { + input: "select * from t1 where exists (select a from t2 union select b from t3)", + }, { + input: "select /* distinct */ distinct 1 from t", + }, { + input: "select /* straight_join */ straight_join 1 from t", + }, { + input: "select /* for update */ 1 from t for update", + }, { + input: "select /* lock in share mode */ 1 from t lock in share mode", + }, { + input: "select /* select list */ 1, 2 from t", + }, { + input: "select /* * */ * from t", + }, { + input: "select /* a.* */ a.* from t", + }, { + input: "select /* a.b.* */ a.b.* from t", + }, { + input: "select /* column alias */ a b from t", + output: "select /* column alias */ a as b from t", + }, { + input: "select /* column alias with as */ a as b from t", + }, { + input: "select /* keyword column alias */ a as `By` from t", + }, { + input: "select /* column alias as string */ a as \"b\" from t", + output: "select /* column alias as string */ a as b from t", + }, { + input: "select /* column alias as string without as */ a \"b\" from t", + output: "select /* column alias as string without as */ a as b from t", + }, { + input: "select /* a.* */ a.* from t", + }, { + input: "select next value for t", + output: "select next 1 values from t", + }, { + input: "select next value from t", + output: "select next 1 values from t", + }, { + input: "select next 10 values from t", + }, { + input: "select next :a values from t", + }, { + input: "select /* `By`.* */ `By`.* from t", + }, { + input: "select /* select with bool expr */ a = b from t", + }, { + input: "select /* case_when */ case when a = b then c end from t", + }, { + input: "select /* case_when_else */ case when a = b then c else d end from t", + }, { + input: "select /* case_when_when_else */ case when a = b then c when b = d then d else d end from t", + }, { + input: "select /* case */ case aa when a = b then c end from t", + }, { + input: "select /* parenthesis */ 1 from (t)", + }, { + input: "select /* parenthesis multi-table */ 1 from (t1, t2)", + }, { + input: "select /* table list */ 1 from t1, t2", + }, { + input: "select /* parenthessis in table list 1 */ 1 from (t1), t2", + }, { + input: "select /* parenthessis in table list 2 */ 1 from t1, (t2)", + }, { + input: "select /* use */ 1 from t1 use index (a) where b = 1", + }, { + input: "select /* keyword index */ 1 from t1 use index (`By`) where b = 1", + }, { + input: "select /* ignore */ 1 from t1 as t2 ignore index (a), t3 use index (b) where b = 1", + }, { + input: "select /* use */ 1 from t1 as t2 use index (a), t3 use index (b) where b = 1", + }, { + input: "select /* force */ 1 from t1 as t2 force index (a), t3 force index (b) where b = 1", + }, { + input: "select /* table alias */ 1 from t t1", + output: "select /* table alias */ 1 from t as t1", + }, { + input: "select /* table alias with as */ 1 from t as t1", + }, { + input: "select /* string table alias */ 1 from t as 't1'", + output: "select /* string table alias */ 1 from t as t1", + }, { + input: "select /* string table alias without as */ 1 from t 't1'", + output: "select /* string table alias without as */ 1 from t as t1", + }, { + input: "select /* keyword table alias */ 1 from t as `By`", + }, { + input: "select /* join */ 1 from t1 join t2", + }, { + input: "select /* join on */ 1 from t1 join t2 on a = b", + }, { + input: "select /* join on */ 1 from t1 join t2 using (a)", + }, { + input: "select /* inner join */ 1 from t1 inner join t2", + output: "select /* inner join */ 1 from t1 join t2", + }, { + input: "select /* cross join */ 1 from t1 cross join t2", + output: "select /* cross join */ 1 from t1 join t2", + }, { + input: "select /* straight_join */ 1 from t1 straight_join t2", + }, { + input: "select /* straight_join on */ 1 from t1 straight_join t2 on a = b", + }, { + input: "select /* left join */ 1 from t1 left join t2 on a = b", + }, { + input: "select /* left join */ 1 from t1 left join t2 using (a)", + }, { + input: "select /* left outer join */ 1 from t1 left outer join t2 on a = b", + output: "select /* left outer join */ 1 from t1 left join t2 on a = b", + }, { + input: "select /* left outer join */ 1 from t1 left outer join t2 using (a)", + output: "select /* left outer join */ 1 from t1 left join t2 using (a)", + }, { + input: "select /* right join */ 1 from t1 right join t2 on a = b", + }, { + input: "select /* right join */ 1 from t1 right join t2 using (a)", + }, { + input: "select /* right outer join */ 1 from t1 right outer join t2 on a = b", + output: "select /* right outer join */ 1 from t1 right join t2 on a = b", + }, { + input: "select /* right outer join */ 1 from t1 right outer join t2 using (a)", + output: "select /* right outer join */ 1 from t1 right join t2 using (a)", + }, { + input: "select /* natural join */ 1 from t1 natural join t2", + }, { + input: "select /* natural left join */ 1 from t1 natural left join t2", + }, { + input: "select /* natural left outer join */ 1 from t1 natural left join t2", + output: "select /* natural left outer join */ 1 from t1 natural left join t2", + }, { + input: "select /* natural right join */ 1 from t1 natural right join t2", + }, { + input: "select /* natural right outer join */ 1 from t1 natural right join t2", + output: "select /* natural right outer join */ 1 from t1 natural right join t2", + }, { + input: "select /* join on */ 1 from t1 join t2 on a = b", + }, { + input: "select /* join using */ 1 from t1 join t2 using (a)", + }, { + input: "select /* join using (a, b, c) */ 1 from t1 join t2 using (a, b, c)", + }, { + input: "select /* s.t */ 1 from s.t", + }, { + input: "select /* keyword schema & table name */ 1 from `By`.`bY`", + }, { + input: "select /* select in from */ 1 from (select 1 from t) as a", + }, { + input: "select /* select in from with no as */ 1 from (select 1 from t) a", + output: "select /* select in from with no as */ 1 from (select 1 from t) as a", + }, { + input: "select /* where */ 1 from t where a = b", + }, { + input: "select /* and */ 1 from t where a = b and a = c", + }, { + input: "select /* && */ 1 from t where a = b && a = c", + output: "select /* && */ 1 from t where a = b and a = c", + }, { + input: "select /* or */ 1 from t where a = b or a = c", + }, { + input: "select /* || */ 1 from t where a = b || a = c", + output: "select /* || */ 1 from t where a = b or a = c", + }, { + input: "select /* not */ 1 from t where not a = b", + }, { + input: "select /* ! */ 1 from t where a = !1", + }, { + input: "select /* bool is */ 1 from t where a = b is null", + }, { + input: "select /* bool is not */ 1 from t where a = b is not false", + }, { + input: "select /* true */ 1 from t where true", + }, { + input: "select /* false */ 1 from t where false", + }, { + input: "select /* false on left */ 1 from t where false = 0", + }, { + input: "select /* exists */ 1 from t where exists (select 1 from t)", + }, { + input: "select /* (boolean) */ 1 from t where not (a = b)", + }, { + input: "select /* in value list */ 1 from t where a in (b, c)", + }, { + input: "select /* in select */ 1 from t where a in (select 1 from t)", + }, { + input: "select /* not in */ 1 from t where a not in (b, c)", + }, { + input: "select /* like */ 1 from t where a like b", + }, { + input: "select /* like escape */ 1 from t where a like b escape '!'", + }, { + input: "select /* not like */ 1 from t where a not like b", + }, { + input: "select /* not like escape */ 1 from t where a not like b escape '$'", + }, { + input: "select /* regexp */ 1 from t where a regexp b", + }, { + input: "select /* not regexp */ 1 from t where a not regexp b", + }, { + input: "select /* rlike */ 1 from t where a rlike b", + output: "select /* rlike */ 1 from t where a regexp b", + }, { + input: "select /* not rlike */ 1 from t where a not rlike b", + output: "select /* not rlike */ 1 from t where a not regexp b", + }, { + input: "select /* between */ 1 from t where a between b and c", + }, { + input: "select /* not between */ 1 from t where a not between b and c", + }, { + input: "select /* is null */ 1 from t where a is null", + }, { + input: "select /* is not null */ 1 from t where a is not null", + }, { + input: "select /* is true */ 1 from t where a is true", + }, { + input: "select /* is not true */ 1 from t where a is not true", + }, { + input: "select /* is false */ 1 from t where a is false", + }, { + input: "select /* is not false */ 1 from t where a is not false", + }, { + input: "select /* < */ 1 from t where a < b", + }, { + input: "select /* <= */ 1 from t where a <= b", + }, { + input: "select /* >= */ 1 from t where a >= b", + }, { + input: "select /* > */ 1 from t where a > b", + }, { + input: "select /* != */ 1 from t where a != b", + }, { + input: "select /* <> */ 1 from t where a <> b", + output: "select /* <> */ 1 from t where a != b", + }, { + input: "select /* <=> */ 1 from t where a <=> b", + }, { + input: "select /* != */ 1 from t where a != b", + }, { + input: "select /* single value expre list */ 1 from t where a in (b)", + }, { + input: "select /* select as a value expression */ 1 from t where a = (select a from t)", + }, { + input: "select /* parenthesised value */ 1 from t where a = (b)", + }, { + input: "select /* over-parenthesize */ ((1)) from t where ((a)) in (((1))) and ((a, b)) in ((((1, 1))), ((2, 2)))", + }, { + input: "select /* dot-parenthesize */ (a.b) from t where (b.c) = 2", + }, { + input: "select /* & */ 1 from t where a = b & c", + }, { + input: "select /* & */ 1 from t where a = b & c", + }, { + input: "select /* | */ 1 from t where a = b | c", + }, { + input: "select /* ^ */ 1 from t where a = b ^ c", + }, { + input: "select /* + */ 1 from t where a = b + c", + }, { + input: "select /* - */ 1 from t where a = b - c", + }, { + input: "select /* * */ 1 from t where a = b * c", + }, { + input: "select /* / */ 1 from t where a = b / c", + }, { + input: "select /* % */ 1 from t where a = b % c", + }, { + input: "select /* div */ 1 from t where a = b div c", + }, { + input: "select /* MOD */ 1 from t where a = b MOD c", + output: "select /* MOD */ 1 from t where a = b % c", + }, { + input: "select /* << */ 1 from t where a = b << c", + }, { + input: "select /* >> */ 1 from t where a = b >> c", + }, { + input: "select /* % no space */ 1 from t where a = b%c", + output: "select /* % no space */ 1 from t where a = b % c", + }, { + input: "select /* u+ */ 1 from t where a = +b", + }, { + input: "select /* u- */ 1 from t where a = -b", + }, { + input: "select /* u~ */ 1 from t where a = ~b", + }, { + input: "select /* -> */ a.b -> 'ab' from t", + }, { + input: "select /* -> */ a.b ->> 'ab' from t", + }, { + input: "select /* empty function */ 1 from t where a = b()", + }, { + input: "select /* function with 1 param */ 1 from t where a = b(c)", + }, { + input: "select /* function with many params */ 1 from t where a = b(c, d)", + }, { + input: "select /* function with distinct */ count(distinct a) from t", + }, { + input: "select /* if as func */ 1 from t where a = if(b)", + }, { + input: "select /* current_timestamp as func */ current_timestamp() from t", + }, { + input: "select /* mod as func */ a from tab where mod(b, 2) = 0", + }, { + input: "select /* database as func no param */ database() from t", + }, { + input: "select /* database as func 1 param */ database(1) from t", + }, { + input: "select /* a */ a from t", + }, { + input: "select /* a.b */ a.b from t", + }, { + input: "select /* a.b.c */ a.b.c from t", + }, { + input: "select /* keyword a.b */ `By`.`bY` from t", + }, { + input: "select /* string */ 'a' from t", + }, { + input: "select /* double quoted string */ \"a\" from t", + output: "select /* double quoted string */ 'a' from t", + }, { + input: "select /* quote quote in string */ 'a''a' from t", + output: "select /* quote quote in string */ 'a\\'a' from t", + }, { + input: "select /* double quote quote in string */ \"a\"\"a\" from t", + output: "select /* double quote quote in string */ 'a\\\"a' from t", + }, { + input: "select /* quote in double quoted string */ \"a'a\" from t", + output: "select /* quote in double quoted string */ 'a\\'a' from t", + }, { + input: "select /* backslash quote in string */ 'a\\'a' from t", + }, { + input: "select /* literal backslash in string */ 'a\\\\na' from t", + }, { + input: "select /* all escapes */ '\\0\\'\\\"\\b\\n\\r\\t\\Z\\\\' from t", + }, { + input: "select /* non-escape */ '\\x' from t", + output: "select /* non-escape */ 'x' from t", + }, { + input: "select /* unescaped backslash */ '\\n' from t", + }, { + input: "select /* value argument */ :a from t", + }, { + input: "select /* value argument with digit */ :a1 from t", + }, { + input: "select /* value argument with dot */ :a.b from t", + }, { + input: "select /* positional argument */ ? from t", + output: "select /* positional argument */ :v1 from t", + }, { + input: "select /* multiple positional arguments */ ?, ? from t", + output: "select /* multiple positional arguments */ :v1, :v2 from t", + }, { + input: "select /* list arg */ * from t where a in ::list", + }, { + input: "select /* list arg not in */ * from t where a not in ::list", + }, { + input: "select /* null */ null from t", + }, { + input: "select /* octal */ 010 from t", + }, { + input: "select /* hex */ x'f0A1' from t", + output: "select /* hex */ X'f0A1' from t", + }, { + input: "select /* hex caps */ X'F0a1' from t", + }, { + input: "select /* bit literal */ b'0101' from t", + output: "select /* bit literal */ B'0101' from t", + }, { + input: "select /* bit literal caps */ B'010011011010' from t", + }, { + input: "select /* 0x */ 0xf0 from t", + }, { + input: "select /* float */ 0.1 from t", + }, { + input: "select /* group by */ 1 from t group by a", + }, { + input: "select /* having */ 1 from t having a = b", + }, { + input: "select /* simple order by */ 1 from t order by a", + output: "select /* simple order by */ 1 from t order by a asc", + }, { + input: "select /* order by asc */ 1 from t order by a asc", + }, { + input: "select /* order by desc */ 1 from t order by a desc", + }, { + input: "select /* order by null */ 1 from t order by null", + }, { + input: "select /* limit a */ 1 from t limit a", + }, { + input: "select /* limit a,b */ 1 from t limit a, b", + }, { + input: "select /* binary unary */ a- -b from t", + output: "select /* binary unary */ a - -b from t", + }, { + input: "select /* - - */ - -b from t", + }, { + input: "select /* binary binary */ binary binary b from t", + }, { + input: "select /* binary ~ */ binary ~b from t", + }, { + input: "select /* ~ binary */ ~ binary b from t", + }, { + input: "select /* interval */ adddate('2008-01-02', interval 31 day) from t", + }, { + input: "select /* interval keyword */ adddate('2008-01-02', interval 1 year) from t", + }, { + input: "select /* dual */ 1 from dual", + }, { + input: "select /* Dual */ 1 from Dual", + output: "select /* Dual */ 1 from dual", + }, { + input: "select /* DUAL */ 1 from Dual", + output: "select /* DUAL */ 1 from dual", + }, { + input: "select /* column as bool in where */ a from t where b", + }, { + input: "select /* OR of columns in where */ * from t where a or b", + }, { + input: "select /* OR of mixed columns in where */ * from t where a = 5 or b and c is not null", + }, { + input: "select /* OR in select columns */ (a or b) from t where c = 5", + }, { + input: "select /* bool as select value */ a, true from t", + }, { + input: "select /* bool column in ON clause */ * from t join s on t.id = s.id and s.foo where t.bar", + }, { + input: "select /* bool in order by */ * from t order by a is null or b asc", + }, { + input: "select /* string in case statement */ if(max(case a when 'foo' then 1 else 0 end) = 1, 'foo', 'bar') as foobar from t", + }, { + input: "/*!show databases*/", + output: "show databases", + }, { + input: "select /*!40101 * from*/ t", + output: "select * from t", + }, { + input: "select /*! * from*/ t", + output: "select * from t", + }, { + input: "select /*!* from*/ t", + output: "select * from t", + }, { + input: "select /*!401011 from*/ t", + output: "select 1 from t", + }, { + input: "select /* dual */ 1 from dual", + }, { + input: "insert /* simple */ into a values (1)", + }, { + input: "insert /* a.b */ into a.b values (1)", + }, { + input: "insert /* multi-value */ into a values (1, 2)", + }, { + input: "insert /* multi-value list */ into a values (1, 2), (3, 4)", + }, { + input: "insert /* no values */ into a values ()", + }, { + input: "insert /* set */ into a set a = 1, b = 2", + output: "insert /* set */ into a(a, b) values (1, 2)", + }, { + input: "insert /* set default */ into a set a = default, b = 2", + output: "insert /* set default */ into a(a, b) values (default, 2)", + }, { + input: "insert /* value expression list */ into a values (a + 1, 2 * 3)", + }, { + input: "insert /* default */ into a values (default, 2 * 3)", + }, { + input: "insert /* column list */ into a(a, b) values (1, 2)", + }, { + input: "insert into a(a, b) values (1, ifnull(null, default(b)))", + }, { + input: "insert /* qualified column list */ into a(a, b) values (1, 2)", + }, { + input: "insert /* qualified columns */ into t (t.a, t.b) values (1, 2)", + output: "insert /* qualified columns */ into t(a, b) values (1, 2)", + }, { + input: "insert /* select */ into a select b, c from d", + }, { + input: "insert /* no cols & paren select */ into a(select * from t)", + output: "insert /* no cols & paren select */ into a select * from t", + }, { + input: "insert /* cols & paren select */ into a(a,b,c) (select * from t)", + output: "insert /* cols & paren select */ into a(a, b, c) select * from t", + }, { + input: "insert /* cols & union with paren select */ into a(b, c) (select d, e from f) union (select g from h)", + }, { + input: "insert /* on duplicate */ into a values (1, 2) on duplicate key update b = func(a), c = d", + }, { + input: "insert /* bool in insert value */ into a values (1, true, false)", + }, { + input: "insert /* bool in on duplicate */ into a values (1, 2) on duplicate key update b = false, c = d", + }, { + input: "insert /* bool in on duplicate */ into a values (1, 2, 3) on duplicate key update b = values(b), c = d", + }, { + input: "insert /* bool in on duplicate */ into a values (1, 2, 3) on duplicate key update b = values(a.b), c = d", + }, { + input: "insert /* bool expression on duplicate */ into a values (1, 2) on duplicate key update b = func(a), c = a > d", + }, { + input: "update /* simple */ a set b = 3", + }, { + input: "update /* a.b */ a.b set b = 3", + }, { + input: "update /* list */ a set b = 3, c = 4", + }, { + input: "update /* expression */ a set b = 3 + 4", + }, { + input: "update /* where */ a set b = 3 where a = b", + }, { + input: "update /* order */ a set b = 3 order by c desc", + }, { + input: "update /* limit */ a set b = 3 limit c", + }, { + input: "update /* bool in update */ a set b = true", + }, { + input: "update /* bool expr in update */ a set b = 5 > 2", + }, { + input: "update /* bool in update where */ a set b = 5 where c", + }, { + input: "update /* table qualifier */ a set a.b = 3", + }, { + input: "update /* table qualifier */ a set t.a.b = 3", + }, { + input: "update /* table alias */ tt aa set aa.cc = 3", + output: "update /* table alias */ tt as aa set aa.cc = 3", + }, { + input: "update (select id from foo) subqalias set id = 4", + output: "update (select id from foo) as subqalias set id = 4", + }, { + input: "update foo f, bar b set f.id = b.id where b.name = 'test'", + output: "update foo as f, bar as b set f.id = b.id where b.name = 'test'", + }, { + input: "update foo f join bar b on f.name = b.name set f.id = b.id where b.name = 'test'", + output: "update foo as f join bar as b on f.name = b.name set f.id = b.id where b.name = 'test'", + }, { + input: "delete /* simple */ from a", + }, { + input: "delete /* a.b */ from a.b", + }, { + input: "delete /* where */ from a where a = b", + }, { + input: "delete /* order */ from a order by b desc", + }, { + input: "delete /* limit */ from a limit b", + }, { + input: "delete a from a join b on a.id = b.id where b.name = 'test'", + }, { + input: "delete a, b from a, b where a.id = b.id and b.name = 'test'", + }, { + input: "delete from a1, a2 using t1 as a1 inner join t2 as a2 where a1.id=a2.id", + output: "delete a1, a2 from t1 as a1 join t2 as a2 where a1.id = a2.id", + }, { + input: "set /* simple */ a = 3", + }, { + input: "set #simple\n b = 4", + }, { + input: "set character_set_results = utf8", + }, { + input: "set @@session.autocommit = true", + }, { + input: "set @@session.`autocommit` = true", + }, { + input: "set @@session.'autocommit' = true", + }, { + input: "set @@session.\"autocommit\" = true", + }, { + input: "set names utf8 collate foo", + output: "set names 'utf8'", + }, { + input: "set character set utf8", + output: "set charset 'utf8'", + }, { + input: "set character set 'utf8'", + output: "set charset 'utf8'", + }, { + input: "set character set \"utf8\"", + output: "set charset 'utf8'", + }, { + input: "set charset default", + output: "set charset default", + }, { + input: "set session wait_timeout = 3600", + output: "set session wait_timeout = 3600", + }, { + input: "set /* list */ a = 3, b = 4", + }, { + input: "set /* mixed list */ a = 3, names 'utf8', charset 'ascii', b = 4", + }, { + input: "set session transaction isolation level repeatable read", + output: "set session tx_isolation = 'repeatable read'", + }, { + input: "set global transaction isolation level repeatable read", + output: "set global tx_isolation = 'repeatable read'", + }, { + input: "set transaction isolation level repeatable read", + output: "set tx_isolation = 'repeatable read'", + }, { + input: "set transaction isolation level read committed", + output: "set tx_isolation = 'read committed'", + }, { + input: "set transaction isolation level read uncommitted", + output: "set tx_isolation = 'read uncommitted'", + }, { + input: "set transaction isolation level serializable", + output: "set tx_isolation = 'serializable'", + }, { + input: "set transaction read write", + output: "set tx_read_only = 0", + }, { + input: "set transaction read only", + output: "set tx_read_only = 1", + }, { + input: "set tx_read_only = 1", + }, { + input: "set tx_read_only = 0", + }, { + input: "set tx_isolation = 'repeatable read'", + }, { + input: "set tx_isolation = 'read committed'", + }, { + input: "set tx_isolation = 'read uncommitted'", + }, { + input: "set tx_isolation = 'serializable'", + }, { + input: "set sql_safe_updates = 0", + }, { + input: "set sql_safe_updates = 1", + }, { + input: "alter ignore table a add foo", + output: "alter table a", + }, { + input: "alter table a add foo", + output: "alter table a", + }, { + input: "alter table a add spatial key foo (column1)", + output: "alter table a", + }, { + input: "alter table a add unique key foo (column1)", + output: "alter table a", + }, { + input: "alter table `By` add foo", + output: "alter table `By`", + }, { + input: "alter table a alter foo", + output: "alter table a", + }, { + input: "alter table a change foo", + output: "alter table a", + }, { + input: "alter table a modify foo", + output: "alter table a", + }, { + input: "alter table a drop foo", + output: "alter table a", + }, { + input: "alter table a disable foo", + output: "alter table a", + }, { + input: "alter table a enable foo", + output: "alter table a", + }, { + input: "alter table a order foo", + output: "alter table a", + }, { + input: "alter table a default foo", + output: "alter table a", + }, { + input: "alter table a discard foo", + output: "alter table a", + }, { + input: "alter table a import foo", + output: "alter table a", + }, { + input: "alter table a rename b", + output: "rename table a to b", + }, { + input: "alter table `By` rename `bY`", + output: "rename table `By` to `bY`", + }, { + input: "alter table a rename to b", + output: "rename table a to b", + }, { + input: "alter table a rename as b", + output: "rename table a to b", + }, { + input: "alter table a rename index foo to bar", + output: "alter table a", + }, { + input: "alter table a rename key foo to bar", + output: "alter table a", + }, { + input: "alter table e auto_increment = 20", + output: "alter table e", + }, { + input: "alter table e character set = 'ascii'", + output: "alter table e", + }, { + input: "alter table e default character set = 'ascii'", + output: "alter table e", + }, { + input: "alter table e comment = 'hello'", + output: "alter table e", + }, { + input: "alter table a reorganize partition b into (partition c values less than (?), partition d values less than (maxvalue))", + output: "alter table a reorganize partition b into (partition c values less than (:v1), partition d values less than (maxvalue))", + }, { + input: "alter table a partition by range (id) (partition p0 values less than (10), partition p1 values less than (maxvalue))", + output: "alter table a", + }, { + input: "alter table a add column id int", + output: "alter table a", + }, { + input: "alter table a add index idx (id)", + output: "alter table a", + }, { + input: "alter table a add fulltext index idx (id)", + output: "alter table a", + }, { + input: "alter table a add spatial index idx (id)", + output: "alter table a", + }, { + input: "alter table a add foreign key", + output: "alter table a", + }, { + input: "alter table a add primary key", + output: "alter table a", + }, { + input: "alter table a add constraint", + output: "alter table a", + }, { + input: "alter table a add id", + output: "alter table a", + }, { + input: "alter table a drop column id int", + output: "alter table a", + }, { + input: "alter table a drop partition p2712", + output: "alter table a", + }, { + input: "alter table a drop index idx (id)", + output: "alter table a", + }, { + input: "alter table a drop fulltext index idx (id)", + output: "alter table a", + }, { + input: "alter table a drop spatial index idx (id)", + output: "alter table a", + }, { + input: "alter table a drop foreign key", + output: "alter table a", + }, { + input: "alter table a drop primary key", + output: "alter table a", + }, { + input: "alter table a drop constraint", + output: "alter table a", + }, { + input: "alter table a drop id", + output: "alter table a", + }, { + input: "alter table a add vindex hash (id)", + }, { + input: "alter table a add vindex `hash` (`id`)", + output: "alter table a add vindex hash (id)", + }, { + input: "alter table a add vindex hash (id) using `hash`", + output: "alter table a add vindex hash (id) using hash", + }, { + input: "alter table a add vindex `add` (`add`)", + }, { + input: "alter table a add vindex hash (id) using hash", + }, { + input: "alter table a add vindex hash (id) using `hash`", + output: "alter table a add vindex hash (id) using hash", + }, { + input: "alter table user add vindex name_lookup_vdx (name) using lookup_hash with owner=user, table=name_user_idx, from=name, to=user_id", + }, { + input: "alter table 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`", + output: "alter table 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 table a drop vindex hash", + }, { + input: "alter table a drop vindex `hash`", + output: "alter table a drop vindex hash", + }, { + input: "alter table a drop vindex hash", + output: "alter table a drop vindex hash", + }, { + input: "alter table a drop vindex `add`", + output: "alter table a drop vindex `add`", + }, { + input: "create table a", + }, { + input: "create table a (\n\t`a` int\n)", + output: "create table a (\n\ta int\n)", + }, { + input: "create table `by` (\n\t`by` char\n)", + }, { + input: "create table if not exists a (\n\t`a` int\n)", + output: "create table a (\n\ta int\n)", + }, { + input: "create table a ignore me this is garbage", + output: "create table a", + }, { + input: "create table a (a int, b char, c garbage)", + output: "create table a", + }, { + input: "create vindex hash_vdx using hash", + }, { + input: "create vindex lookup_vdx using lookup with owner=user, table=name_user_idx, from=name, to=user_id", + }, { + input: "create vindex xyz_vdx using xyz with param1=hello, param2='world', param3=123", + }, { + input: "create index a on b", + output: "alter table b", + }, { + input: "create unique index a on b", + output: "alter table b", + }, { + input: "create unique index a using foo on b", + output: "alter table b", + }, { + input: "create fulltext index a using foo on b", + output: "alter table b", + }, { + input: "create spatial index a using foo on b", + output: "alter table b", + }, { + input: "create view a", + output: "create table a", + }, { + input: "create or replace view a", + output: "create table a", + }, { + input: "alter view a", + output: "alter table a", + }, { + input: "drop view a", + output: "drop table a", + }, { + input: "drop table a", + output: "drop table a", + }, { + input: "drop table if exists a", + output: "drop table if exists a", + }, { + input: "drop view if exists a", + output: "drop table if exists a", + }, { + input: "drop index b on a", + output: "alter table a", + }, { + input: "analyze table a", + output: "alter table a", + }, { + input: "show binary logs", + output: "show binary logs", + }, { + input: "show binlog events", + output: "show binlog", + }, { + input: "show character set", + output: "show character set", + }, { + input: "show character set like '%foo'", + output: "show character set", + }, { + input: "show collation", + output: "show collation", + }, { + input: "show create database d", + output: "show create database", + }, { + input: "show create event e", + output: "show create event", + }, { + input: "show create function f", + output: "show create function", + }, { + input: "show create procedure p", + output: "show create procedure", + }, { + input: "show create table t", + output: "show create table", + }, { + input: "show create trigger t", + output: "show create trigger", + }, { + input: "show create user u", + output: "show create user", + }, { + input: "show create view v", + output: "show create view", + }, { + input: "show databases", + output: "show databases", + }, { + input: "show engine INNODB", + output: "show engine", + }, { + input: "show engines", + output: "show engines", + }, { + input: "show storage engines", + output: "show storage", + }, { + input: "show errors", + output: "show errors", + }, { + input: "show events", + output: "show events", + }, { + input: "show function code func", + output: "show function", + }, { + input: "show function status", + output: "show function", + }, { + input: "show grants for 'root@localhost'", + output: "show grants", + }, { + input: "show index from table", + output: "show index", + }, { + input: "show indexes from table", + output: "show indexes", + }, { + input: "show keys from table", + output: "show keys", + }, { + input: "show master status", + output: "show master", + }, { + input: "show open tables", + output: "show open", + }, { + input: "show plugins", + output: "show plugins", + }, { + input: "show privileges", + output: "show privileges", + }, { + input: "show procedure code p", + output: "show procedure", + }, { + input: "show procedure status", + output: "show procedure", + }, { + input: "show processlist", + output: "show processlist", + }, { + input: "show full processlist", + output: "show processlist", + }, { + input: "show profile cpu for query 1", + output: "show profile", + }, { + input: "show profiles", + output: "show profiles", + }, { + input: "show relaylog events", + output: "show relaylog", + }, { + input: "show slave hosts", + output: "show slave", + }, { + input: "show slave status", + output: "show slave", + }, { + input: "show status", + output: "show status", + }, { + input: "show global status", + output: "show global status", + }, { + input: "show session status", + output: "show session status", + }, { + input: "show table status", + output: "show table", + }, { + input: "show tables", + }, { + input: "show tables like '%keyspace%'", + }, { + input: "show tables where 1 = 0", + }, { + input: "show tables from a", + }, { + input: "show tables from a where 1 = 0", + }, { + input: "show tables from a like '%keyspace%'", + }, { + input: "show full tables", + }, { + input: "show full tables from a", + }, { + input: "show full tables in a", + output: "show full tables from a", + }, { + input: "show full tables from a like '%keyspace%'", + }, { + input: "show full tables from a where 1 = 0", + }, { + input: "show full tables like '%keyspace%'", + }, { + input: "show full tables where 1 = 0", + }, { + input: "show triggers", + output: "show triggers", + }, { + input: "show variables", + output: "show variables", + }, { + input: "show global variables", + output: "show global variables", + }, { + input: "show session variables", + output: "show session variables", + }, { + input: "show vindexes", + output: "show vindexes", + }, { + input: "show vindexes on t", + output: "show vindexes on t", + }, { + input: "show vitess_keyspaces", + }, { + input: "show vitess_shards", + }, { + input: "show vitess_tablets", + }, { + input: "show vschema_tables", + }, { + input: "show warnings", + output: "show warnings", + }, { + input: "show foobar", + output: "show foobar", + }, { + input: "show foobar like select * from table where syntax is 'ignored'", + output: "show foobar", + }, { + input: "use db", + output: "use db", + }, { + input: "use duplicate", + output: "use `duplicate`", + }, { + input: "use `ks:-80@master`", + output: "use `ks:-80@master`", + }, { + input: "describe foobar", + output: "otherread", + }, { + input: "desc foobar", + output: "otherread", + }, { + input: "explain foobar", + output: "otherread", + }, { + input: "truncate table foo", + output: "truncate table foo", + }, { + input: "truncate foo", + output: "truncate table foo", + }, { + input: "repair foo", + output: "otheradmin", + }, { + input: "optimize foo", + output: "otheradmin", + }, { + input: "select /* EQ true */ 1 from t where a = true", + }, { + input: "select /* EQ false */ 1 from t where a = false", + }, { + input: "select /* NE true */ 1 from t where a != true", + }, { + input: "select /* NE false */ 1 from t where a != false", + }, { + input: "select /* LT true */ 1 from t where a < true", + }, { + input: "select /* LT false */ 1 from t where a < false", + }, { + input: "select /* GT true */ 1 from t where a > true", + }, { + input: "select /* GT false */ 1 from t where a > false", + }, { + input: "select /* LE true */ 1 from t where a <= true", + }, { + input: "select /* LE false */ 1 from t where a <= false", + }, { + input: "select /* GE true */ 1 from t where a >= true", + }, { + input: "select /* GE false */ 1 from t where a >= false", + }, { + input: "select * from t order by a collate utf8_general_ci", + output: "select * from t order by a collate utf8_general_ci asc", + }, { + input: "select k collate latin1_german2_ci as k1 from t1 order by k1 asc", + }, { + input: "select * from t group by a collate utf8_general_ci", + }, { + input: "select MAX(k collate latin1_german2_ci) from t1", + }, { + input: "select distinct k collate latin1_german2_ci from t1", + }, { + input: "select * from t1 where 'Müller' collate latin1_german2_ci = k", + }, { + input: "select * from t1 where k like 'Müller' collate latin1_german2_ci", + }, { + input: "select k from t1 group by k having k = 'Müller' collate latin1_german2_ci", + }, { + input: "select k from t1 join t2 order by a collate latin1_german2_ci asc, b collate latin1_german2_ci asc", + }, { + input: "select k collate 'latin1_german2_ci' as k1 from t1 order by k1 asc", + output: "select k collate latin1_german2_ci as k1 from t1 order by k1 asc", + }, { + input: "select /* drop trailing semicolon */ 1 from dual;", + output: "select /* drop trailing semicolon */ 1 from dual", + }, { + input: "select /* cache directive */ sql_no_cache 'foo' from t", + }, { + input: "select binary 'a' = 'A' from t", + }, { + input: "select 1 from t where foo = _binary 'bar'", + }, { + input: "select 1 from t where foo = _binary'bar'", + output: "select 1 from t where foo = _binary 'bar'", + }, { + input: "select match(a) against ('foo') from t", + }, { + input: "select match(a1, a2) against ('foo' in natural language mode with query expansion) from t", + }, { + input: "select title from video as v where match(v.title, v.tag) against ('DEMO' in boolean mode)", + }, { + input: "select name, group_concat(score) from t group by name", + }, { + input: "select name, group_concat(distinct id, score order by id desc separator ':') from t group by name", + }, { + input: "select * from t partition (p0)", + }, { + input: "select * from t partition (p0, p1)", + }, { + input: "select e.id, s.city from employees as e join stores partition (p1) as s on e.store_id = s.id", + }, { + input: "select truncate(120.3333, 2) from dual", + }, { + input: "update t partition (p0) set a = 1", + }, { + input: "insert into t partition (p0) values (1, 'asdf')", + }, { + input: "insert into t1 select * from t2 partition (p0)", + }, { + input: "replace into t partition (p0) values (1, 'asdf')", + }, { + input: "delete from t partition (p0) where a = 1", + }, { + input: "stream * from t", + }, { + input: "stream /* comment */ * from t", + }, { + input: "begin", + }, { + input: "start transaction", + output: "begin", + }, { + input: "commit", + }, { + input: "rollback", + }, { + input: "create database test_db", + }, { + input: "create schema test_db", + output: "create database test_db", + }, { + input: "create database if not exists test_db", + output: "create database test_db", + }, { + input: "drop database test_db", + }, { + input: "drop schema test_db", + output: "drop database test_db", + }, { + input: "drop database if exists test_db", + output: "drop database test_db", + }} +) + +func TestValid(t *testing.T) { + for _, tcase := range validSQL { + if tcase.output == "" { + tcase.output = tcase.input + } + tree, err := Parse(tcase.input) + if err != nil { + t.Errorf("Parse(%q) err: %v, want nil", tcase.input, err) + continue + } + out := String(tree) + if out != tcase.output { + t.Errorf("Parse(%q) = %q, want: %q", tcase.input, out, tcase.output) + } + // This test just exercises the tree walking functionality. + // There's no way automated way to verify that a node calls + // all its children. But we can examine code coverage and + // ensure that all walkSubtree functions were called. + Walk(func(node SQLNode) (bool, error) { + return true, nil + }, tree) + } +} + +func TestCaseSensitivity(t *testing.T) { + validSQL := []struct { + input string + output string + }{{ + input: "create table A (\n\t`B` int\n)", + output: "create table A (\n\tB int\n)", + }, { + input: "create index b on A", + output: "alter table A", + }, { + input: "alter table A foo", + output: "alter table A", + }, { + input: "alter table A convert", + output: "alter table A", + }, { + // View names get lower-cased. + input: "alter view A foo", + output: "alter table a", + }, { + input: "alter table A rename to B", + output: "rename table A to B", + }, { + input: "rename table A to B", + }, { + input: "drop table B", + output: "drop table B", + }, { + input: "drop table if exists B", + output: "drop table if exists B", + }, { + input: "drop index b on A", + output: "alter table A", + }, { + input: "select a from B", + }, { + input: "select A as B from C", + }, { + input: "select B.* from c", + }, { + input: "select B.A from c", + }, { + input: "select * from B as C", + }, { + input: "select * from A.B", + }, { + input: "update A set b = 1", + }, { + input: "update A.B set b = 1", + }, { + input: "select A() from b", + }, { + input: "select A(B, C) from b", + }, { + input: "select A(distinct B, C) from b", + }, { + // IF is an exception. It's always lower-cased. + input: "select IF(B, C) from b", + output: "select if(B, C) from b", + }, { + input: "select * from b use index (A)", + }, { + input: "insert into A(A, B) values (1, 2)", + }, { + input: "CREATE TABLE A (\n\t`A` int\n)", + output: "create table A (\n\tA int\n)", + }, { + input: "create view A", + output: "create table a", + }, { + input: "alter view A", + output: "alter table a", + }, { + input: "drop view A", + output: "drop table a", + }, { + input: "drop view if exists A", + output: "drop table if exists a", + }, { + input: "select /* lock in SHARE MODE */ 1 from t lock in SHARE MODE", + output: "select /* lock in SHARE MODE */ 1 from t lock in share mode", + }, { + input: "select next VALUE from t", + output: "select next 1 values from t", + }, { + input: "select /* use */ 1 from t1 use index (A) where b = 1", + }} + for _, tcase := range validSQL { + if tcase.output == "" { + tcase.output = tcase.input + } + tree, err := Parse(tcase.input) + if err != nil { + t.Errorf("input: %s, err: %v", tcase.input, err) + continue + } + out := String(tree) + if out != tcase.output { + t.Errorf("out: %s, want %s", out, tcase.output) + } + } +} + +func TestKeywords(t *testing.T) { + validSQL := []struct { + input string + output string + }{{ + input: "select current_timestamp", + output: "select current_timestamp() from dual", + }, { + input: "update t set a = current_timestamp()", + }, { + input: "select a, current_date from t", + output: "select a, current_date() from t", + }, { + input: "insert into t(a, b) values (current_date, current_date())", + output: "insert into t(a, b) values (current_date(), current_date())", + }, { + input: "select * from t where a > utc_timestmp()", + }, { + input: "update t set b = utc_timestamp + 5", + output: "update t set b = utc_timestamp() + 5", + }, { + input: "select utc_time, utc_date", + output: "select utc_time(), utc_date() from dual", + }, { + input: "select 1 from dual where localtime > utc_time", + output: "select 1 from dual where localtime() > utc_time()", + }, { + input: "update t set a = localtimestamp(), b = utc_timestamp", + output: "update t set a = localtimestamp(), b = utc_timestamp()", + }, { + input: "insert into t(a) values (unix_timestamp)", + }, { + input: "select replace(a, 'foo', 'bar') from t", + }, { + input: "update t set a = replace('1234', '2', '1')", + }, { + input: "insert into t(a, b) values ('foo', 'bar') on duplicate key update a = replace(hex('foo'), 'f', 'b')", + }, { + input: "update t set a = left('1234', 3)", + }, { + input: "select left(a, 5) from t", + }, { + input: "update t set d = adddate(date('2003-12-31 01:02:03'), interval 5 days)", + }, { + input: "insert into t(a, b) values (left('foo', 1), 'b')", + }, { + input: "insert /* qualified function */ into t(a, b) values (test.PI(), 'b')", + }, { + input: "select /* keyword in qualified id */ * from t join z on t.key = z.key", + output: "select /* keyword in qualified id */ * from t join z on t.`key` = z.`key`", + }, { + input: "select /* non-reserved keywords as unqualified cols */ date, view, offset from t", + output: "select /* non-reserved keywords as unqualified cols */ `date`, `view`, `offset` from t", + }, { + input: "select /* share and mode as cols */ share, mode from t where share = 'foo'", + output: "select /* share and mode as cols */ `share`, `mode` from t where `share` = 'foo'", + }, { + input: "select /* unused keywords as cols */ write, varying from t where trailing = 'foo'", + output: "select /* unused keywords as cols */ `write`, `varying` from t where `trailing` = 'foo'", + }, { + input: "select status from t", + output: "select `status` from t", + }, { + input: "select variables from t", + output: "select `variables` from t", + }} + + for _, tcase := range validSQL { + if tcase.output == "" { + tcase.output = tcase.input + } + tree, err := Parse(tcase.input) + if err != nil { + t.Errorf("input: %s, err: %v", tcase.input, err) + continue + } + out := String(tree) + if out != tcase.output { + t.Errorf("out: %s, want %s", out, tcase.output) + } + } +} + +func TestConvert(t *testing.T) { + validSQL := []struct { + input string + output string + }{{ + input: "select cast('abc' as date) from t", + output: "select convert('abc', date) from t", + }, { + input: "select convert('abc', binary(4)) from t", + }, { + input: "select convert('abc', binary) from t", + }, { + input: "select convert('abc', char character set binary) from t", + }, { + input: "select convert('abc', char(4) ascii) from t", + }, { + input: "select convert('abc', char unicode) from t", + }, { + input: "select convert('abc', char(4)) from t", + }, { + input: "select convert('abc', char) from t", + }, { + input: "select convert('abc', nchar(4)) from t", + }, { + input: "select convert('abc', nchar) from t", + }, { + input: "select convert('abc', signed) from t", + }, { + input: "select convert('abc', signed integer) from t", + output: "select convert('abc', signed) from t", + }, { + input: "select convert('abc', unsigned) from t", + }, { + input: "select convert('abc', unsigned integer) from t", + output: "select convert('abc', unsigned) from t", + }, { + input: "select convert('abc', decimal(3, 4)) from t", + }, { + input: "select convert('abc', decimal(4)) from t", + }, { + input: "select convert('abc', decimal) from t", + }, { + input: "select convert('abc', date) from t", + }, { + input: "select convert('abc', time(4)) from t", + }, { + input: "select convert('abc', time) from t", + }, { + input: "select convert('abc', datetime(9)) from t", + }, { + input: "select convert('abc', datetime) from t", + }, { + input: "select convert('abc', json) from t", + }, { + input: "select convert('abc' using ascii) from t", + }} + + for _, tcase := range validSQL { + if tcase.output == "" { + tcase.output = tcase.input + } + tree, err := Parse(tcase.input) + if err != nil { + t.Errorf("input: %s, err: %v", tcase.input, err) + continue + } + out := String(tree) + if out != tcase.output { + t.Errorf("out: %s, want %s", out, tcase.output) + } + } + + invalidSQL := []struct { + input string + output string + }{{ + input: "select convert('abc' as date) from t", + output: "syntax error at position 24 near 'as'", + }, { + input: "select convert from t", + output: "syntax error at position 20 near 'from'", + }, { + input: "select cast('foo', decimal) from t", + output: "syntax error at position 19", + }, { + input: "select convert('abc', datetime(4+9)) from t", + output: "syntax error at position 34", + }, { + input: "select convert('abc', decimal(4+9)) from t", + output: "syntax error at position 33", + }} + + for _, tcase := range invalidSQL { + _, err := Parse(tcase.input) + if err == nil || err.Error() != tcase.output { + t.Errorf("%s: %v, want %s", tcase.input, err, tcase.output) + } + } +} + +func TestSubStr(t *testing.T) { + + validSQL := []struct { + input string + output string + }{{ + input: "select substr(a, 1) from t", + }, { + input: "select substr(a, 1, 6) from t", + }, { + input: "select substring(a, 1) from t", + output: "select substr(a, 1) from t", + }, { + input: "select substring(a, 1, 6) from t", + output: "select substr(a, 1, 6) from t", + }, { + input: "select substr(a from 1 for 6) from t", + output: "select substr(a, 1, 6) from t", + }, { + input: "select substring(a from 1 for 6) from t", + output: "select substr(a, 1, 6) from t", + }} + + for _, tcase := range validSQL { + if tcase.output == "" { + tcase.output = tcase.input + } + tree, err := Parse(tcase.input) + if err != nil { + t.Errorf("input: %s, err: %v", tcase.input, err) + continue + } + out := String(tree) + if out != tcase.output { + t.Errorf("out: %s, want %s", out, tcase.output) + } + } +} + +func TestCreateTable(t *testing.T) { + validSQL := []string{ + // test all the data types and options + "create table t (\n" + + " col_bit bit,\n" + + " col_tinyint tinyint auto_increment,\n" + + " col_tinyint3 tinyint(3) unsigned,\n" + + " col_smallint smallint,\n" + + " col_smallint4 smallint(4) zerofill,\n" + + " col_mediumint mediumint,\n" + + " col_mediumint5 mediumint(5) unsigned not null,\n" + + " col_int int,\n" + + " col_int10 int(10) not null,\n" + + " col_integer integer comment 'this is an integer',\n" + + " col_bigint bigint,\n" + + " col_bigint10 bigint(10) zerofill not null default 10,\n" + + " col_real real,\n" + + " col_real2 real(1,2) not null default 1.23,\n" + + " col_double double,\n" + + " col_double2 double(3,4) not null default 1.23,\n" + + " col_float float,\n" + + " col_float2 float(3,4) not null default 1.23,\n" + + " col_decimal decimal,\n" + + " col_decimal2 decimal(2),\n" + + " col_decimal3 decimal(2,3),\n" + + " col_numeric numeric,\n" + + " col_numeric2 numeric(2),\n" + + " col_numeric3 numeric(2,3),\n" + + " col_date date,\n" + + " col_time time,\n" + + " col_timestamp timestamp,\n" + + " col_datetime datetime,\n" + + " col_year year,\n" + + " col_char char,\n" + + " col_char2 char(2),\n" + + " col_char3 char(3) character set ascii,\n" + + " col_char4 char(4) character set ascii collate ascii_bin,\n" + + " col_varchar varchar,\n" + + " col_varchar2 varchar(2),\n" + + " col_varchar3 varchar(3) character set ascii,\n" + + " col_varchar4 varchar(4) character set ascii collate ascii_bin,\n" + + " col_binary binary,\n" + + " col_varbinary varbinary(10),\n" + + " col_tinyblob tinyblob,\n" + + " col_blob blob,\n" + + " col_mediumblob mediumblob,\n" + + " col_longblob longblob,\n" + + " col_tinytext tinytext,\n" + + " col_text text,\n" + + " col_mediumtext mediumtext,\n" + + " col_longtext longtext,\n" + + " col_text text character set ascii collate ascii_bin,\n" + + " col_json json,\n" + + " col_enum enum('a', 'b', 'c', 'd'),\n" + + " col_enum2 enum('a', 'b', 'c', 'd') character set ascii,\n" + + " col_enum3 enum('a', 'b', 'c', 'd') collate ascii_bin,\n" + + " col_enum4 enum('a', 'b', 'c', 'd') character set ascii collate ascii_bin,\n" + + " col_set set('a', 'b', 'c', 'd'),\n" + + " col_set2 set('a', 'b', 'c', 'd') character set ascii,\n" + + " col_set3 set('a', 'b', 'c', 'd') collate ascii_bin,\n" + + " col_set4 set('a', 'b', 'c', 'd') character set ascii collate ascii_bin,\n" + + " col_geometry1 geometry,\n" + + " col_geometry2 geometry not null,\n" + + " col_point1 point,\n" + + " col_point2 point not null,\n" + + " col_linestring1 linestring,\n" + + " col_linestring2 linestring not null,\n" + + " col_polygon1 polygon,\n" + + " col_polygon2 polygon not null,\n" + + " col_geometrycollection1 geometrycollection,\n" + + " col_geometrycollection2 geometrycollection not null,\n" + + " col_multipoint1 multipoint,\n" + + " col_multipoint2 multipoint not null,\n" + + " col_multilinestring1 multilinestring,\n" + + " col_multilinestring2 multilinestring not null,\n" + + " col_multipolygon1 multipolygon,\n" + + " col_multipolygon2 multipolygon not null\n" + + ")", + + // test defaults + "create table t (\n" + + " i1 int default 1,\n" + + " i2 int default null,\n" + + " f1 float default 1.23,\n" + + " s1 varchar default 'c',\n" + + " s2 varchar default 'this is a string',\n" + + " s3 varchar default null,\n" + + " s4 timestamp default current_timestamp,\n" + + " s5 bit(1) default B'0'\n" + + ")", + + // test key field options + "create table t (\n" + + " id int auto_increment primary key,\n" + + " username varchar unique key,\n" + + " email varchar unique,\n" + + " full_name varchar key,\n" + + " time1 timestamp on update current_timestamp,\n" + + " time2 timestamp default current_timestamp on update current_timestamp\n" + + ")", + + // test defining indexes separately + "create table t (\n" + + " id int auto_increment,\n" + + " username varchar,\n" + + " email varchar,\n" + + " full_name varchar,\n" + + " geom point not null,\n" + + " status_nonkeyword varchar,\n" + + " primary key (id),\n" + + " spatial key geom (geom),\n" + + " unique key by_username (username),\n" + + " unique by_username2 (username),\n" + + " unique index by_username3 (username),\n" + + " index by_status (status_nonkeyword),\n" + + " key by_full_name (full_name)\n" + + ")", + + // test that indexes support USING + "create table t (\n" + + " id int auto_increment,\n" + + " username varchar,\n" + + " email varchar,\n" + + " full_name varchar,\n" + + " status_nonkeyword varchar,\n" + + " primary key (id) using BTREE,\n" + + " unique key by_username (username) using HASH,\n" + + " unique by_username2 (username) using OTHER,\n" + + " unique index by_username3 (username) using XYZ,\n" + + " index by_status (status_nonkeyword) using PDQ,\n" + + " key by_full_name (full_name) using OTHER\n" + + ")", + // test other index options + "create table t (\n" + + " id int auto_increment,\n" + + " username varchar,\n" + + " email varchar,\n" + + " primary key (id) comment 'hi',\n" + + " unique key by_username (username) key_block_size 8,\n" + + " unique index by_username4 (username) comment 'hi' using BTREE,\n" + + " unique index by_username4 (username) using BTREE key_block_size 4 comment 'hi'\n" + + ")", + + // multi-column indexes + "create table t (\n" + + " id int auto_increment,\n" + + " username varchar,\n" + + " email varchar,\n" + + " full_name varchar,\n" + + " a int,\n" + + " b int,\n" + + " c int,\n" + + " primary key (id, username),\n" + + " unique key by_abc (a, b, c),\n" + + " key by_email (email(10), username)\n" + + ")", + + // table options + "create table t (\n" + + " id int auto_increment\n" + + ") engine InnoDB,\n" + + " auto_increment 123,\n" + + " avg_row_length 1,\n" + + " default character set utf8mb4,\n" + + " character set latin1,\n" + + " checksum 0,\n" + + " default collate binary,\n" + + " collate ascii_bin,\n" + + " comment 'this is a comment',\n" + + " compression 'zlib',\n" + + " connection 'connect_string',\n" + + " data directory 'absolute path to directory',\n" + + " delay_key_write 1,\n" + + " encryption 'n',\n" + + " index directory 'absolute path to directory',\n" + + " insert_method no,\n" + + " key_block_size 1024,\n" + + " max_rows 100,\n" + + " min_rows 10,\n" + + " pack_keys 0,\n" + + " password 'sekret',\n" + + " row_format default,\n" + + " stats_auto_recalc default,\n" + + " stats_persistent 0,\n" + + " stats_sample_pages 1,\n" + + " tablespace tablespace_name storage disk,\n" + + " tablespace tablespace_name\n", + } + for _, sql := range validSQL { + sql = strings.TrimSpace(sql) + tree, err := ParseStrictDDL(sql) + if err != nil { + t.Errorf("input: %s, err: %v", sql, err) + continue + } + got := String(tree.(*DDL)) + + if sql != got { + t.Errorf("want:\n%s\ngot:\n%s", sql, got) + } + } + + sql := "create table t garbage" + tree, err := Parse(sql) + if err != nil { + t.Errorf("input: %s, err: %v", sql, err) + } + + tree, err = ParseStrictDDL(sql) + if tree != nil || err == nil { + t.Errorf("ParseStrictDDL unexpectedly accepted input %s", sql) + } + + testCases := []struct { + input string + output string + }{{ + // test key_block_size + input: "create table t (\n" + + " id int auto_increment,\n" + + " username varchar,\n" + + " unique key by_username (username) key_block_size 8,\n" + + " unique key by_username2 (username) key_block_size=8,\n" + + " unique by_username3 (username) key_block_size = 4\n" + + ")", + output: "create table t (\n" + + " id int auto_increment,\n" + + " username varchar,\n" + + " unique key by_username (username) key_block_size 8,\n" + + " unique key by_username2 (username) key_block_size 8,\n" + + " unique by_username3 (username) key_block_size 4\n" + + ")", + }, + } + for _, tcase := range testCases { + tree, err := ParseStrictDDL(tcase.input) + if err != nil { + t.Errorf("input: %s, err: %v", tcase.input, err) + continue + } + if got, want := String(tree.(*DDL)), tcase.output; got != want { + t.Errorf("Parse(%s):\n%s, want\n%s", tcase.input, got, want) + } + } +} + +func TestCreateTableEscaped(t *testing.T) { + testCases := []struct { + input string + output string + }{{ + input: "create table `a`(`id` int, primary key(`id`))", + output: "create table a (\n" + + "\tid int,\n" + + "\tprimary key (id)\n" + + ")", + }, { + input: "create table `insert`(`update` int, primary key(`delete`))", + output: "create table `insert` (\n" + + "\t`update` int,\n" + + "\tprimary key (`delete`)\n" + + ")", + }} + for _, tcase := range testCases { + tree, err := ParseStrictDDL(tcase.input) + if err != nil { + t.Errorf("input: %s, err: %v", tcase.input, err) + continue + } + if got, want := String(tree.(*DDL)), tcase.output; got != want { + t.Errorf("Parse(%s):\n%s, want\n%s", tcase.input, got, want) + } + } +} + +var ( + invalidSQL = []struct { + input string + output string + excludeMulti bool // Don't use in the ParseNext multi-statement parsing tests. + }{{ + input: "select $ from t", + output: "syntax error at position 9 near '$'", + }, { + input: "select : from t", + output: "syntax error at position 9 near ':'", + }, { + input: "select 0xH from t", + output: "syntax error at position 10 near '0x'", + }, { + input: "select x'78 from t", + output: "syntax error at position 12 near '78'", + }, { + input: "select x'777' from t", + output: "syntax error at position 14 near '777'", + }, { + input: "select * from t where :1 = 2", + output: "syntax error at position 24 near ':'", + }, { + input: "select * from t where :. = 2", + output: "syntax error at position 24 near ':'", + }, { + input: "select * from t where ::1 = 2", + output: "syntax error at position 25 near '::'", + }, { + input: "select * from t where ::. = 2", + output: "syntax error at position 25 near '::'", + }, { + input: "update a set c = values(1)", + output: "syntax error at position 26 near '1'", + }, { + input: "select(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F" + + "(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(" + + "F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F" + + "(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(" + + "F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F" + + "(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(" + + "F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F" + + "(F(F(F(F(F(F(F(F(F(F(F(F(", + output: "max nesting level reached at position 406", + }, { + input: "select(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F" + + "(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(" + + "F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F" + + "(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(" + + "F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F" + + "(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(" + + "F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F" + + "(F(F(F(F(F(F(F(F(F(F(F(", + output: "syntax error at position 404", + }, { + // This construct is considered invalid due to a grammar conflict. + input: "insert into a select * from b join c on duplicate key update d=e", + output: "syntax error at position 54 near 'key'", + }, { + input: "select * from a left join b", + output: "syntax error at position 28", + }, { + input: "select * from a natural join b on c = d", + output: "syntax error at position 34 near 'on'", + }, { + input: "select * from a natural join b using (c)", + output: "syntax error at position 37 near 'using'", + }, { + input: "select next id from a", + output: "expecting value after next at position 15 near 'id'", + }, { + input: "select next 1+1 values from a", + output: "syntax error at position 15", + }, { + input: "insert into a values (select * from b)", + output: "syntax error at position 29 near 'select'", + }, { + input: "select database", + output: "syntax error at position 16", + }, { + input: "select mod from t", + output: "syntax error at position 16 near 'from'", + }, { + input: "select 1 from t where div 5", + output: "syntax error at position 26 near 'div'", + }, { + input: "select 1 from t where binary", + output: "syntax error at position 29", + }, { + input: "select match(a1, a2) against ('foo' in boolean mode with query expansion) from t", + output: "syntax error at position 57 near 'with'", + }, { + input: "select /* reserved keyword as unqualified column */ * from t where key = 'test'", + output: "syntax error at position 71 near 'key'", + }, { + input: "select /* vitess-reserved keyword as unqualified column */ * from t where escape = 'test'", + output: "syntax error at position 81 near 'escape'", + }, { + input: "(select /* parenthesized select */ * from t)", + output: "syntax error at position 45", + }, { + input: "select * from t where id = ((select a from t1 union select b from t2) order by a limit 1)", + output: "syntax error at position 76 near 'order'", + }, { + input: "select /* straight_join using */ 1 from t1 straight_join t2 using (a)", + output: "syntax error at position 66 near 'using'", + }, { + input: "select 'aa", + output: "syntax error at position 11 near 'aa'", + excludeMulti: true, + }, { + input: "select 'aa\\", + output: "syntax error at position 12 near 'aa'", + excludeMulti: true, + }, { + input: "select /* aa", + output: "syntax error at position 13 near '/* aa'", + excludeMulti: true, + }} +) + +func TestErrors(t *testing.T) { + for _, tcase := range invalidSQL { + _, err := Parse(tcase.input) + if err == nil || err.Error() != tcase.output { + t.Errorf("%s: %v, want %s", tcase.input, err, tcase.output) + } + } +} + +// Benchmark run on 6/23/17, prior to improvements: +// BenchmarkParse1-4 100000 16334 ns/op +// BenchmarkParse2-4 30000 44121 ns/op + +func BenchmarkParse1(b *testing.B) { + sql := "select 'abcd', 20, 30.0, eid from a where 1=eid and name='3'" + for i := 0; i < b.N; i++ { + ast, err := Parse(sql) + if err != nil { + b.Fatal(err) + } + _ = String(ast) + } +} + +func BenchmarkParse2(b *testing.B) { + sql := "select aaaa, bbb, ccc, ddd, eeee, ffff, gggg, hhhh, iiii from tttt, ttt1, ttt3 where aaaa = bbbb and bbbb = cccc and dddd+1 = eeee group by fff, gggg having hhhh = iiii and iiii = jjjj order by kkkk, llll limit 3, 4" + for i := 0; i < b.N; i++ { + ast, err := Parse(sql) + if err != nil { + b.Fatal(err) + } + _ = String(ast) + } +} + +var benchQuery string + +func init() { + // benchQuerySize is the approximate size of the query. + benchQuerySize := 1000000 + + // Size of value is 1/10 size of query. Then we add + // 10 such values to the where clause. + var baseval bytes.Buffer + for i := 0; i < benchQuerySize/100; i++ { + // Add an escape character: This will force the upcoming + // tokenizer improvement to still create a copy of the string. + // Then we can see if avoiding the copy will be worth it. + baseval.WriteString("\\'123456789") + } + + var buf bytes.Buffer + buf.WriteString("select a from t1 where v = 1") + for i := 0; i < 10; i++ { + fmt.Fprintf(&buf, " and v%d = \"%d%s\"", i, i, baseval.String()) + } + benchQuery = buf.String() +} + +func BenchmarkParse3(b *testing.B) { + for i := 0; i < b.N; i++ { + if _, err := Parse(benchQuery); err != nil { + b.Fatal(err) + } + } +} diff --git a/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/parsed_query.go b/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/parsed_query.go new file mode 100644 index 00000000..cf4ef03b --- /dev/null +++ b/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/parsed_query.go @@ -0,0 +1,119 @@ +/* +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 sqlparser + +import ( + "bytes" + "fmt" + + "github.com/xwb1989/sqlparser/dependency/querypb" + "github.com/xwb1989/sqlparser/dependency/sqltypes" +) + +// ParsedQuery represents a parsed query where +// bind locations are precompued for fast substitutions. +type ParsedQuery struct { + Query string + bindLocations []bindLocation +} + +type bindLocation struct { + offset, length int +} + +// NewParsedQuery returns a ParsedQuery of the ast. +func NewParsedQuery(node SQLNode) *ParsedQuery { + buf := NewTrackedBuffer(nil) + buf.Myprintf("%v", node) + return buf.ParsedQuery() +} + +// GenerateQuery generates a query by substituting the specified +// bindVariables. The extras parameter specifies special parameters +// that can perform custom encoding. +func (pq *ParsedQuery) GenerateQuery(bindVariables map[string]*querypb.BindVariable, extras map[string]Encodable) ([]byte, error) { + if len(pq.bindLocations) == 0 { + return []byte(pq.Query), nil + } + buf := bytes.NewBuffer(make([]byte, 0, len(pq.Query))) + current := 0 + for _, loc := range pq.bindLocations { + buf.WriteString(pq.Query[current:loc.offset]) + name := pq.Query[loc.offset : loc.offset+loc.length] + if encodable, ok := extras[name[1:]]; ok { + encodable.EncodeSQL(buf) + } else { + supplied, _, err := FetchBindVar(name, bindVariables) + if err != nil { + return nil, err + } + EncodeValue(buf, supplied) + } + current = loc.offset + loc.length + } + buf.WriteString(pq.Query[current:]) + return buf.Bytes(), nil +} + +// EncodeValue encodes one bind variable value into the query. +func EncodeValue(buf *bytes.Buffer, value *querypb.BindVariable) { + if value.Type != querypb.Type_TUPLE { + // Since we already check for TUPLE, we don't expect an error. + v, _ := sqltypes.BindVariableToValue(value) + v.EncodeSQL(buf) + return + } + + // It's a TUPLE. + buf.WriteByte('(') + for i, bv := range value.Values { + if i != 0 { + buf.WriteString(", ") + } + sqltypes.ProtoToValue(bv).EncodeSQL(buf) + } + buf.WriteByte(')') +} + +// FetchBindVar resolves the bind variable by fetching it from bindVariables. +func FetchBindVar(name string, bindVariables map[string]*querypb.BindVariable) (val *querypb.BindVariable, isList bool, err error) { + name = name[1:] + if name[0] == ':' { + name = name[1:] + isList = true + } + supplied, ok := bindVariables[name] + if !ok { + return nil, false, fmt.Errorf("missing bind var %s", name) + } + + if isList { + if supplied.Type != querypb.Type_TUPLE { + return nil, false, fmt.Errorf("unexpected list arg type (%v) for key %s", supplied.Type, name) + } + if len(supplied.Values) == 0 { + return nil, false, fmt.Errorf("empty list supplied for %s", name) + } + return supplied, true, nil + } + + if supplied.Type == querypb.Type_TUPLE { + return nil, false, fmt.Errorf("unexpected arg type (TUPLE) for non-list key %s", name) + } + + return supplied, false, nil +} diff --git a/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/parsed_query_test.go b/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/parsed_query_test.go new file mode 100644 index 00000000..dc0e1ac0 --- /dev/null +++ b/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/parsed_query_test.go @@ -0,0 +1,157 @@ +/* +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 sqlparser + +import ( + "reflect" + "testing" + + "github.com/xwb1989/sqlparser/dependency/sqltypes" + + "github.com/xwb1989/sqlparser/dependency/querypb" +) + +func TestNewParsedQuery(t *testing.T) { + stmt, err := Parse("select * from a where id =:id") + if err != nil { + t.Error(err) + return + } + pq := NewParsedQuery(stmt) + want := &ParsedQuery{ + Query: "select * from a where id = :id", + bindLocations: []bindLocation{{offset: 27, length: 3}}, + } + if !reflect.DeepEqual(pq, want) { + t.Errorf("GenerateParsedQuery: %+v, want %+v", pq, want) + } +} + +func TestGenerateQuery(t *testing.T) { + tcases := []struct { + desc string + query string + bindVars map[string]*querypb.BindVariable + extras map[string]Encodable + output string + }{ + { + desc: "no substitutions", + query: "select * from a where id = 2", + bindVars: map[string]*querypb.BindVariable{ + "id": sqltypes.Int64BindVariable(1), + }, + output: "select * from a where id = 2", + }, { + desc: "missing bind var", + query: "select * from a where id1 = :id1 and id2 = :id2", + bindVars: map[string]*querypb.BindVariable{ + "id1": sqltypes.Int64BindVariable(1), + }, + output: "missing bind var id2", + }, { + desc: "simple bindvar substitution", + query: "select * from a where id1 = :id1 and id2 = :id2", + bindVars: map[string]*querypb.BindVariable{ + "id1": sqltypes.Int64BindVariable(1), + "id2": sqltypes.NullBindVariable, + }, + output: "select * from a where id1 = 1 and id2 = null", + }, { + desc: "tuple *querypb.BindVariable", + query: "select * from a where id in ::vals", + bindVars: map[string]*querypb.BindVariable{ + "vals": sqltypes.TestBindVariable([]interface{}{1, "aa"}), + }, + output: "select * from a where id in (1, 'aa')", + }, { + desc: "list bind vars 0 arguments", + query: "select * from a where id in ::vals", + bindVars: map[string]*querypb.BindVariable{ + "vals": sqltypes.TestBindVariable([]interface{}{}), + }, + output: "empty list supplied for vals", + }, { + desc: "non-list bind var supplied", + query: "select * from a where id in ::vals", + bindVars: map[string]*querypb.BindVariable{ + "vals": sqltypes.Int64BindVariable(1), + }, + output: "unexpected list arg type (INT64) for key vals", + }, { + desc: "list bind var for non-list", + query: "select * from a where id = :vals", + bindVars: map[string]*querypb.BindVariable{ + "vals": sqltypes.TestBindVariable([]interface{}{1}), + }, + output: "unexpected arg type (TUPLE) for non-list key vals", + }, { + desc: "single column tuple equality", + query: "select * from a where b = :equality", + extras: map[string]Encodable{ + "equality": &TupleEqualityList{ + Columns: []ColIdent{NewColIdent("pk")}, + Rows: [][]sqltypes.Value{ + {sqltypes.NewInt64(1)}, + {sqltypes.NewVarBinary("aa")}, + }, + }, + }, + output: "select * from a where b = pk in (1, 'aa')", + }, { + desc: "multi column tuple equality", + query: "select * from a where b = :equality", + extras: map[string]Encodable{ + "equality": &TupleEqualityList{ + Columns: []ColIdent{NewColIdent("pk1"), NewColIdent("pk2")}, + Rows: [][]sqltypes.Value{ + { + sqltypes.NewInt64(1), + sqltypes.NewVarBinary("aa"), + }, + { + sqltypes.NewInt64(2), + sqltypes.NewVarBinary("bb"), + }, + }, + }, + }, + output: "select * from a where b = (pk1 = 1 and pk2 = 'aa') or (pk1 = 2 and pk2 = 'bb')", + }, + } + + for _, tcase := range tcases { + tree, err := Parse(tcase.query) + if err != nil { + t.Errorf("parse failed for %s: %v", tcase.desc, err) + continue + } + buf := NewTrackedBuffer(nil) + buf.Myprintf("%v", tree) + pq := buf.ParsedQuery() + bytes, err := pq.GenerateQuery(tcase.bindVars, tcase.extras) + var got string + if err != nil { + got = err.Error() + } else { + got = string(bytes) + } + if got != tcase.output { + t.Errorf("for test case: %s, got: '%s', want '%s'", tcase.desc, got, tcase.output) + } + } +} diff --git a/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/patches/bytes2.patch b/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/patches/bytes2.patch new file mode 100644 index 00000000..e69de29b diff --git a/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/patches/querypb.patch b/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/patches/querypb.patch new file mode 100644 index 00000000..abf19eac --- /dev/null +++ b/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/patches/querypb.patch @@ -0,0 +1,1315 @@ +diff -u /Users/bramp/go/src/vitess.io/vitess/go//vt/proto/query/query.pb.go /Users/bramp/go/src/github.com/xwb1989/sqlparser//dependency/querypb/query.pb.go +--- /Users/bramp/go/src/vitess.io/vitess/go//vt/proto/query/query.pb.go 2018-06-05 08:45:47.000000000 -0700 ++++ /Users/bramp/go/src/github.com/xwb1989/sqlparser//dependency/querypb/query.pb.go 2017-10-18 18:06:33.000000000 -0700 +@@ -62,30 +62,24 @@ + SplitQueryResponse + StreamHealthRequest + RealtimeStats +- AggregateStats + StreamHealthResponse + UpdateStreamRequest + UpdateStreamResponse + TransactionMetadata + */ +-package query ++package querypb + +-import proto "github.com/golang/protobuf/proto" +-import fmt "fmt" +-import math "math" +-import topodata "vitess.io/vitess/go/vt/proto/topodata" +-import vtrpc "vitess.io/vitess/go/vt/proto/vtrpc" +- +-// Reference imports to suppress errors if they are not otherwise used. +-var _ = proto.Marshal +-var _ = fmt.Errorf +-var _ = math.Inf +- +-// This is a compile-time assertion to ensure that this generated file +-// is compatible with the proto package it is being compiled against. +-// A compilation error at this line likely means your copy of the +-// proto package needs to be updated. +-const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package ++import "strconv" ++ ++// EnumName is a helper function to simplify printing protocol buffer enums ++// by name. Given an enum map and a value, it returns a useful string. ++func EnumName(m map[int32]string, v int32) string { ++ s, ok := m[v] ++ if ok { ++ return s ++ } ++ return strconv.Itoa(int(v)) ++} + + // Flags sent from the MySQL C API + type MySqlFlag int32 +@@ -159,9 +153,8 @@ + } + + func (x MySqlFlag) String() string { +- return proto.EnumName(MySqlFlag_name, int32(x)) ++ return EnumName(MySqlFlag_name, int32(x)) + } +-func (MySqlFlag) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{0} } + + // Flag allows us to qualify types by their common properties. + type Flag int32 +@@ -196,9 +189,8 @@ + } + + func (x Flag) String() string { +- return proto.EnumName(Flag_name, int32(x)) ++ return EnumName(Flag_name, int32(x)) + } +-func (Flag) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{1} } + + // Type defines the various supported data types in bind vars + // and query results. +@@ -375,9 +367,8 @@ + } + + func (x Type) String() string { +- return proto.EnumName(Type_name, int32(x)) ++ return EnumName(Type_name, int32(x)) + } +-func (Type) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{2} } + + // TransactionState represents the state of a distributed transaction. + type TransactionState int32 +@@ -403,9 +394,8 @@ + } + + func (x TransactionState) String() string { +- return proto.EnumName(TransactionState_name, int32(x)) ++ return EnumName(TransactionState_name, int32(x)) + } +-func (TransactionState) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{3} } + + type ExecuteOptions_IncludedFields int32 + +@@ -427,10 +417,7 @@ + } + + func (x ExecuteOptions_IncludedFields) String() string { +- return proto.EnumName(ExecuteOptions_IncludedFields_name, int32(x)) +-} +-func (ExecuteOptions_IncludedFields) EnumDescriptor() ([]byte, []int) { +- return fileDescriptor0, []int{6, 0} ++ return EnumName(ExecuteOptions_IncludedFields_name, int32(x)) + } + + type ExecuteOptions_Workload int32 +@@ -456,9 +443,8 @@ + } + + func (x ExecuteOptions_Workload) String() string { +- return proto.EnumName(ExecuteOptions_Workload_name, int32(x)) ++ return EnumName(ExecuteOptions_Workload_name, int32(x)) + } +-func (ExecuteOptions_Workload) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{6, 1} } + + type ExecuteOptions_TransactionIsolation int32 + +@@ -486,10 +472,7 @@ + } + + func (x ExecuteOptions_TransactionIsolation) String() string { +- return proto.EnumName(ExecuteOptions_TransactionIsolation_name, int32(x)) +-} +-func (ExecuteOptions_TransactionIsolation) EnumDescriptor() ([]byte, []int) { +- return fileDescriptor0, []int{6, 2} ++ return EnumName(ExecuteOptions_TransactionIsolation_name, int32(x)) + } + + // The category of one statement. +@@ -513,10 +496,7 @@ + } + + func (x StreamEvent_Statement_Category) String() string { +- return proto.EnumName(StreamEvent_Statement_Category_name, int32(x)) +-} +-func (StreamEvent_Statement_Category) EnumDescriptor() ([]byte, []int) { +- return fileDescriptor0, []int{11, 0, 0} ++ return EnumName(StreamEvent_Statement_Category_name, int32(x)) + } + + type SplitQueryRequest_Algorithm int32 +@@ -536,27 +516,22 @@ + } + + func (x SplitQueryRequest_Algorithm) String() string { +- return proto.EnumName(SplitQueryRequest_Algorithm_name, int32(x)) +-} +-func (SplitQueryRequest_Algorithm) EnumDescriptor() ([]byte, []int) { +- return fileDescriptor0, []int{49, 0} ++ return EnumName(SplitQueryRequest_Algorithm_name, int32(x)) + } + ++/* + // Target describes what the client expects the tablet is. + // If the tablet does not match, an error is returned. + type Target struct { + Keyspace string `protobuf:"bytes,1,opt,name=keyspace" json:"keyspace,omitempty"` + Shard string `protobuf:"bytes,2,opt,name=shard" json:"shard,omitempty"` + TabletType topodata.TabletType `protobuf:"varint,3,opt,name=tablet_type,json=tabletType,enum=topodata.TabletType" json:"tablet_type,omitempty"` +- // cell is used for routing queries between vtgate and vttablets. It +- // is not used when Target is part of the Session sent by the client. +- Cell string `protobuf:"bytes,4,opt,name=cell" json:"cell,omitempty"` + } + + func (m *Target) Reset() { *m = Target{} } +-func (m *Target) String() string { return proto.CompactTextString(m) } +-func (*Target) ProtoMessage() {} +-func (*Target) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} } ++func (m *Target) String() string { return "TODO" } ++ ++ + + func (m *Target) GetKeyspace() string { + if m != nil { +@@ -579,12 +554,6 @@ + return topodata.TabletType_UNKNOWN + } + +-func (m *Target) GetCell() string { +- if m != nil { +- return m.Cell +- } +- return "" +-} + + // VTGateCallerID is sent by VTGate to VTTablet to describe the + // caller. If possible, this information is secure. For instance, +@@ -600,9 +569,9 @@ + } + + func (m *VTGateCallerID) Reset() { *m = VTGateCallerID{} } +-func (m *VTGateCallerID) String() string { return proto.CompactTextString(m) } +-func (*VTGateCallerID) ProtoMessage() {} +-func (*VTGateCallerID) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} } ++func (m *VTGateCallerID) String() string { return "TODO" } ++ ++ + + func (m *VTGateCallerID) GetUsername() string { + if m != nil { +@@ -634,9 +603,9 @@ + } + + func (m *EventToken) Reset() { *m = EventToken{} } +-func (m *EventToken) String() string { return proto.CompactTextString(m) } +-func (*EventToken) ProtoMessage() {} +-func (*EventToken) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{2} } ++func (m *EventToken) String() string { return "TODO" } ++ ++ + + func (m *EventToken) GetTimestamp() int64 { + if m != nil { +@@ -658,6 +627,7 @@ + } + return "" + } ++*/ + + // Value represents a typed value. + type Value struct { +@@ -665,10 +635,8 @@ + Value []byte `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` + } + +-func (m *Value) Reset() { *m = Value{} } +-func (m *Value) String() string { return proto.CompactTextString(m) } +-func (*Value) ProtoMessage() {} +-func (*Value) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{3} } ++func (m *Value) Reset() { *m = Value{} } ++func (m *Value) String() string { return "TODO" } + + func (m *Value) GetType() Type { + if m != nil { +@@ -692,10 +660,8 @@ + Values []*Value `protobuf:"bytes,3,rep,name=values" json:"values,omitempty"` + } + +-func (m *BindVariable) Reset() { *m = BindVariable{} } +-func (m *BindVariable) String() string { return proto.CompactTextString(m) } +-func (*BindVariable) ProtoMessage() {} +-func (*BindVariable) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{4} } ++func (m *BindVariable) Reset() { *m = BindVariable{} } ++func (m *BindVariable) String() string { return "TODO" } + + func (m *BindVariable) GetType() Type { + if m != nil { +@@ -727,10 +693,8 @@ + BindVariables map[string]*BindVariable `protobuf:"bytes,2,rep,name=bind_variables,json=bindVariables" json:"bind_variables,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + } + +-func (m *BoundQuery) Reset() { *m = BoundQuery{} } +-func (m *BoundQuery) String() string { return proto.CompactTextString(m) } +-func (*BoundQuery) ProtoMessage() {} +-func (*BoundQuery) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{5} } ++func (m *BoundQuery) Reset() { *m = BoundQuery{} } ++func (m *BoundQuery) String() string { return "TODO" } + + func (m *BoundQuery) GetSql() string { + if m != nil { +@@ -746,6 +710,7 @@ + return nil + } + ++/* + // ExecuteOptions is passed around for all Execute calls. + type ExecuteOptions struct { + // If set, we will try to include an EventToken with the responses. +@@ -774,15 +739,12 @@ + // vitess also sets a rowcount limit on queries, the smallest value wins. + SqlSelectLimit int64 `protobuf:"varint,8,opt,name=sql_select_limit,json=sqlSelectLimit" json:"sql_select_limit,omitempty"` + TransactionIsolation ExecuteOptions_TransactionIsolation `protobuf:"varint,9,opt,name=transaction_isolation,json=transactionIsolation,enum=query.ExecuteOptions_TransactionIsolation" json:"transaction_isolation,omitempty"` +- // skip_query_plan_cache specifies if the query plan shoud be cached by vitess. +- // By default all query plans are cached. +- SkipQueryPlanCache bool `protobuf:"varint,10,opt,name=skip_query_plan_cache,json=skipQueryPlanCache" json:"skip_query_plan_cache,omitempty"` + } + + func (m *ExecuteOptions) Reset() { *m = ExecuteOptions{} } +-func (m *ExecuteOptions) String() string { return proto.CompactTextString(m) } +-func (*ExecuteOptions) ProtoMessage() {} +-func (*ExecuteOptions) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{6} } ++func (m *ExecuteOptions) String() string { return "TODO" } ++ ++ + + func (m *ExecuteOptions) GetIncludeEventToken() bool { + if m != nil { +@@ -833,13 +795,6 @@ + return ExecuteOptions_DEFAULT + } + +-func (m *ExecuteOptions) GetSkipQueryPlanCache() bool { +- if m != nil { +- return m.SkipQueryPlanCache +- } +- return false +-} +- + // Field describes a single column returned by a query + type Field struct { + // name of the field as returned by mysql C API +@@ -864,9 +819,9 @@ + } + + func (m *Field) Reset() { *m = Field{} } +-func (m *Field) String() string { return proto.CompactTextString(m) } +-func (*Field) ProtoMessage() {} +-func (*Field) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{7} } ++func (m *Field) String() string { return "TODO" } ++ ++ + + func (m *Field) GetName() string { + if m != nil { +@@ -950,9 +905,9 @@ + } + + func (m *Row) Reset() { *m = Row{} } +-func (m *Row) String() string { return proto.CompactTextString(m) } +-func (*Row) ProtoMessage() {} +-func (*Row) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{8} } ++func (m *Row) String() string { return "TODO" } ++ ++ + + func (m *Row) GetLengths() []int64 { + if m != nil { +@@ -980,9 +935,9 @@ + } + + func (m *ResultExtras) Reset() { *m = ResultExtras{} } +-func (m *ResultExtras) String() string { return proto.CompactTextString(m) } +-func (*ResultExtras) ProtoMessage() {} +-func (*ResultExtras) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{9} } ++func (m *ResultExtras) String() string { return "TODO" } ++ ++ + + func (m *ResultExtras) GetEventToken() *EventToken { + if m != nil { +@@ -1016,9 +971,9 @@ + } + + func (m *QueryResult) Reset() { *m = QueryResult{} } +-func (m *QueryResult) String() string { return proto.CompactTextString(m) } +-func (*QueryResult) ProtoMessage() {} +-func (*QueryResult) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{10} } ++func (m *QueryResult) String() string { return "TODO" } ++ ++ + + func (m *QueryResult) GetFields() []*Field { + if m != nil { +@@ -1066,9 +1021,9 @@ + } + + func (m *StreamEvent) Reset() { *m = StreamEvent{} } +-func (m *StreamEvent) String() string { return proto.CompactTextString(m) } +-func (*StreamEvent) ProtoMessage() {} +-func (*StreamEvent) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{11} } ++func (m *StreamEvent) String() string { return "TODO" } ++ ++ + + func (m *StreamEvent) GetStatements() []*StreamEvent_Statement { + if m != nil { +@@ -1097,9 +1052,9 @@ + } + + func (m *StreamEvent_Statement) Reset() { *m = StreamEvent_Statement{} } +-func (m *StreamEvent_Statement) String() string { return proto.CompactTextString(m) } +-func (*StreamEvent_Statement) ProtoMessage() {} +-func (*StreamEvent_Statement) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{11, 0} } ++func (m *StreamEvent_Statement) String() string { return "TODO" } ++ ++ + + func (m *StreamEvent_Statement) GetCategory() StreamEvent_Statement_Category { + if m != nil { +@@ -1136,6 +1091,7 @@ + return nil + } + ++ + // ExecuteRequest is the payload to Execute + type ExecuteRequest struct { + EffectiveCallerId *vtrpc.CallerID `protobuf:"bytes,1,opt,name=effective_caller_id,json=effectiveCallerId" json:"effective_caller_id,omitempty"` +@@ -1147,9 +1103,9 @@ + } + + func (m *ExecuteRequest) Reset() { *m = ExecuteRequest{} } +-func (m *ExecuteRequest) String() string { return proto.CompactTextString(m) } +-func (*ExecuteRequest) ProtoMessage() {} +-func (*ExecuteRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{12} } ++func (m *ExecuteRequest) String() string { return "TODO" } ++ ++ + + func (m *ExecuteRequest) GetEffectiveCallerId() *vtrpc.CallerID { + if m != nil { +@@ -1199,9 +1155,9 @@ + } + + func (m *ExecuteResponse) Reset() { *m = ExecuteResponse{} } +-func (m *ExecuteResponse) String() string { return proto.CompactTextString(m) } +-func (*ExecuteResponse) ProtoMessage() {} +-func (*ExecuteResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{13} } ++func (m *ExecuteResponse) String() string { return "TODO" } ++ ++ + + func (m *ExecuteResponse) GetResult() *QueryResult { + if m != nil { +@@ -1221,9 +1177,9 @@ + } + + func (m *ResultWithError) Reset() { *m = ResultWithError{} } +-func (m *ResultWithError) String() string { return proto.CompactTextString(m) } +-func (*ResultWithError) ProtoMessage() {} +-func (*ResultWithError) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{14} } ++func (m *ResultWithError) String() string { return "TODO" } ++ ++ + + func (m *ResultWithError) GetError() *vtrpc.RPCError { + if m != nil { +@@ -1251,9 +1207,9 @@ + } + + func (m *ExecuteBatchRequest) Reset() { *m = ExecuteBatchRequest{} } +-func (m *ExecuteBatchRequest) String() string { return proto.CompactTextString(m) } +-func (*ExecuteBatchRequest) ProtoMessage() {} +-func (*ExecuteBatchRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{15} } ++func (m *ExecuteBatchRequest) String() string { return "TODO" } ++ ++ + + func (m *ExecuteBatchRequest) GetEffectiveCallerId() *vtrpc.CallerID { + if m != nil { +@@ -1310,9 +1266,9 @@ + } + + func (m *ExecuteBatchResponse) Reset() { *m = ExecuteBatchResponse{} } +-func (m *ExecuteBatchResponse) String() string { return proto.CompactTextString(m) } +-func (*ExecuteBatchResponse) ProtoMessage() {} +-func (*ExecuteBatchResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{16} } ++func (m *ExecuteBatchResponse) String() string { return "TODO" } ++ ++ + + func (m *ExecuteBatchResponse) GetResults() []*QueryResult { + if m != nil { +@@ -1331,9 +1287,9 @@ + } + + func (m *StreamExecuteRequest) Reset() { *m = StreamExecuteRequest{} } +-func (m *StreamExecuteRequest) String() string { return proto.CompactTextString(m) } +-func (*StreamExecuteRequest) ProtoMessage() {} +-func (*StreamExecuteRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{17} } ++func (m *StreamExecuteRequest) String() string { return "TODO" } ++ ++ + + func (m *StreamExecuteRequest) GetEffectiveCallerId() *vtrpc.CallerID { + if m != nil { +@@ -1376,9 +1332,9 @@ + } + + func (m *StreamExecuteResponse) Reset() { *m = StreamExecuteResponse{} } +-func (m *StreamExecuteResponse) String() string { return proto.CompactTextString(m) } +-func (*StreamExecuteResponse) ProtoMessage() {} +-func (*StreamExecuteResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{18} } ++func (m *StreamExecuteResponse) String() string { return "TODO" } ++ ++ + + func (m *StreamExecuteResponse) GetResult() *QueryResult { + if m != nil { +@@ -1396,9 +1352,9 @@ + } + + func (m *BeginRequest) Reset() { *m = BeginRequest{} } +-func (m *BeginRequest) String() string { return proto.CompactTextString(m) } +-func (*BeginRequest) ProtoMessage() {} +-func (*BeginRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{19} } ++func (m *BeginRequest) String() string { return "TODO" } ++ ++ + + func (m *BeginRequest) GetEffectiveCallerId() *vtrpc.CallerID { + if m != nil { +@@ -1434,9 +1390,9 @@ + } + + func (m *BeginResponse) Reset() { *m = BeginResponse{} } +-func (m *BeginResponse) String() string { return proto.CompactTextString(m) } +-func (*BeginResponse) ProtoMessage() {} +-func (*BeginResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{20} } ++func (m *BeginResponse) String() string { return "TODO" } ++ ++ + + func (m *BeginResponse) GetTransactionId() int64 { + if m != nil { +@@ -1454,9 +1410,9 @@ + } + + func (m *CommitRequest) Reset() { *m = CommitRequest{} } +-func (m *CommitRequest) String() string { return proto.CompactTextString(m) } +-func (*CommitRequest) ProtoMessage() {} +-func (*CommitRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{21} } ++func (m *CommitRequest) String() string { return "TODO" } ++ ++ + + func (m *CommitRequest) GetEffectiveCallerId() *vtrpc.CallerID { + if m != nil { +@@ -1491,9 +1447,9 @@ + } + + func (m *CommitResponse) Reset() { *m = CommitResponse{} } +-func (m *CommitResponse) String() string { return proto.CompactTextString(m) } +-func (*CommitResponse) ProtoMessage() {} +-func (*CommitResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{22} } ++func (m *CommitResponse) String() string { return "TODO" } ++ ++ + + // RollbackRequest is the payload to Rollback + type RollbackRequest struct { +@@ -1504,9 +1460,9 @@ + } + + func (m *RollbackRequest) Reset() { *m = RollbackRequest{} } +-func (m *RollbackRequest) String() string { return proto.CompactTextString(m) } +-func (*RollbackRequest) ProtoMessage() {} +-func (*RollbackRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{23} } ++func (m *RollbackRequest) String() string { return "TODO" } ++ ++ + + func (m *RollbackRequest) GetEffectiveCallerId() *vtrpc.CallerID { + if m != nil { +@@ -1541,9 +1497,9 @@ + } + + func (m *RollbackResponse) Reset() { *m = RollbackResponse{} } +-func (m *RollbackResponse) String() string { return proto.CompactTextString(m) } +-func (*RollbackResponse) ProtoMessage() {} +-func (*RollbackResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{24} } ++func (m *RollbackResponse) String() string { return "TODO" } ++ ++ + + // PrepareRequest is the payload to Prepare + type PrepareRequest struct { +@@ -1555,9 +1511,9 @@ + } + + func (m *PrepareRequest) Reset() { *m = PrepareRequest{} } +-func (m *PrepareRequest) String() string { return proto.CompactTextString(m) } +-func (*PrepareRequest) ProtoMessage() {} +-func (*PrepareRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{25} } ++func (m *PrepareRequest) String() string { return "TODO" } ++ ++ + + func (m *PrepareRequest) GetEffectiveCallerId() *vtrpc.CallerID { + if m != nil { +@@ -1599,9 +1555,9 @@ + } + + func (m *PrepareResponse) Reset() { *m = PrepareResponse{} } +-func (m *PrepareResponse) String() string { return proto.CompactTextString(m) } +-func (*PrepareResponse) ProtoMessage() {} +-func (*PrepareResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{26} } ++func (m *PrepareResponse) String() string { return "TODO" } ++ ++ + + // CommitPreparedRequest is the payload to CommitPrepared + type CommitPreparedRequest struct { +@@ -1612,9 +1568,9 @@ + } + + func (m *CommitPreparedRequest) Reset() { *m = CommitPreparedRequest{} } +-func (m *CommitPreparedRequest) String() string { return proto.CompactTextString(m) } +-func (*CommitPreparedRequest) ProtoMessage() {} +-func (*CommitPreparedRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{27} } ++func (m *CommitPreparedRequest) String() string { return "TODO" } ++ ++ + + func (m *CommitPreparedRequest) GetEffectiveCallerId() *vtrpc.CallerID { + if m != nil { +@@ -1649,9 +1605,9 @@ + } + + func (m *CommitPreparedResponse) Reset() { *m = CommitPreparedResponse{} } +-func (m *CommitPreparedResponse) String() string { return proto.CompactTextString(m) } +-func (*CommitPreparedResponse) ProtoMessage() {} +-func (*CommitPreparedResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{28} } ++func (m *CommitPreparedResponse) String() string { return "TODO" } ++ ++ + + // RollbackPreparedRequest is the payload to RollbackPrepared + type RollbackPreparedRequest struct { +@@ -1663,9 +1619,9 @@ + } + + func (m *RollbackPreparedRequest) Reset() { *m = RollbackPreparedRequest{} } +-func (m *RollbackPreparedRequest) String() string { return proto.CompactTextString(m) } +-func (*RollbackPreparedRequest) ProtoMessage() {} +-func (*RollbackPreparedRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{29} } ++func (m *RollbackPreparedRequest) String() string { return "TODO" } ++ ++ + + func (m *RollbackPreparedRequest) GetEffectiveCallerId() *vtrpc.CallerID { + if m != nil { +@@ -1707,9 +1663,9 @@ + } + + func (m *RollbackPreparedResponse) Reset() { *m = RollbackPreparedResponse{} } +-func (m *RollbackPreparedResponse) String() string { return proto.CompactTextString(m) } +-func (*RollbackPreparedResponse) ProtoMessage() {} +-func (*RollbackPreparedResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{30} } ++func (m *RollbackPreparedResponse) String() string { return "TODO" } ++ ++ + + // CreateTransactionRequest is the payload to CreateTransaction + type CreateTransactionRequest struct { +@@ -1721,9 +1677,9 @@ + } + + func (m *CreateTransactionRequest) Reset() { *m = CreateTransactionRequest{} } +-func (m *CreateTransactionRequest) String() string { return proto.CompactTextString(m) } +-func (*CreateTransactionRequest) ProtoMessage() {} +-func (*CreateTransactionRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{31} } ++func (m *CreateTransactionRequest) String() string { return "TODO" } ++ ++ + + func (m *CreateTransactionRequest) GetEffectiveCallerId() *vtrpc.CallerID { + if m != nil { +@@ -1765,9 +1721,9 @@ + } + + func (m *CreateTransactionResponse) Reset() { *m = CreateTransactionResponse{} } +-func (m *CreateTransactionResponse) String() string { return proto.CompactTextString(m) } +-func (*CreateTransactionResponse) ProtoMessage() {} +-func (*CreateTransactionResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{32} } ++func (m *CreateTransactionResponse) String() string { return "TODO" } ++ ++ + + // StartCommitRequest is the payload to StartCommit + type StartCommitRequest struct { +@@ -1779,9 +1735,9 @@ + } + + func (m *StartCommitRequest) Reset() { *m = StartCommitRequest{} } +-func (m *StartCommitRequest) String() string { return proto.CompactTextString(m) } +-func (*StartCommitRequest) ProtoMessage() {} +-func (*StartCommitRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{33} } ++func (m *StartCommitRequest) String() string { return "TODO" } ++ ++ + + func (m *StartCommitRequest) GetEffectiveCallerId() *vtrpc.CallerID { + if m != nil { +@@ -1823,9 +1779,9 @@ + } + + func (m *StartCommitResponse) Reset() { *m = StartCommitResponse{} } +-func (m *StartCommitResponse) String() string { return proto.CompactTextString(m) } +-func (*StartCommitResponse) ProtoMessage() {} +-func (*StartCommitResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{34} } ++func (m *StartCommitResponse) String() string { return "TODO" } ++ ++ + + // SetRollbackRequest is the payload to SetRollback + type SetRollbackRequest struct { +@@ -1837,9 +1793,9 @@ + } + + func (m *SetRollbackRequest) Reset() { *m = SetRollbackRequest{} } +-func (m *SetRollbackRequest) String() string { return proto.CompactTextString(m) } +-func (*SetRollbackRequest) ProtoMessage() {} +-func (*SetRollbackRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{35} } ++func (m *SetRollbackRequest) String() string { return "TODO" } ++ ++ + + func (m *SetRollbackRequest) GetEffectiveCallerId() *vtrpc.CallerID { + if m != nil { +@@ -1881,9 +1837,9 @@ + } + + func (m *SetRollbackResponse) Reset() { *m = SetRollbackResponse{} } +-func (m *SetRollbackResponse) String() string { return proto.CompactTextString(m) } +-func (*SetRollbackResponse) ProtoMessage() {} +-func (*SetRollbackResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{36} } ++func (m *SetRollbackResponse) String() string { return "TODO" } ++ ++ + + // ConcludeTransactionRequest is the payload to ConcludeTransaction + type ConcludeTransactionRequest struct { +@@ -1894,9 +1850,9 @@ + } + + func (m *ConcludeTransactionRequest) Reset() { *m = ConcludeTransactionRequest{} } +-func (m *ConcludeTransactionRequest) String() string { return proto.CompactTextString(m) } +-func (*ConcludeTransactionRequest) ProtoMessage() {} +-func (*ConcludeTransactionRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{37} } ++func (m *ConcludeTransactionRequest) String() string { return "TODO" } ++ ++ + + func (m *ConcludeTransactionRequest) GetEffectiveCallerId() *vtrpc.CallerID { + if m != nil { +@@ -1931,9 +1887,9 @@ + } + + func (m *ConcludeTransactionResponse) Reset() { *m = ConcludeTransactionResponse{} } +-func (m *ConcludeTransactionResponse) String() string { return proto.CompactTextString(m) } +-func (*ConcludeTransactionResponse) ProtoMessage() {} +-func (*ConcludeTransactionResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{38} } ++func (m *ConcludeTransactionResponse) String() string { return "TODO" } ++ ++ + + // ReadTransactionRequest is the payload to ReadTransaction + type ReadTransactionRequest struct { +@@ -1944,9 +1900,9 @@ + } + + func (m *ReadTransactionRequest) Reset() { *m = ReadTransactionRequest{} } +-func (m *ReadTransactionRequest) String() string { return proto.CompactTextString(m) } +-func (*ReadTransactionRequest) ProtoMessage() {} +-func (*ReadTransactionRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{39} } ++func (m *ReadTransactionRequest) String() string { return "TODO" } ++ ++ + + func (m *ReadTransactionRequest) GetEffectiveCallerId() *vtrpc.CallerID { + if m != nil { +@@ -1982,9 +1938,9 @@ + } + + func (m *ReadTransactionResponse) Reset() { *m = ReadTransactionResponse{} } +-func (m *ReadTransactionResponse) String() string { return proto.CompactTextString(m) } +-func (*ReadTransactionResponse) ProtoMessage() {} +-func (*ReadTransactionResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{40} } ++func (m *ReadTransactionResponse) String() string { return "TODO" } ++ ++ + + func (m *ReadTransactionResponse) GetMetadata() *TransactionMetadata { + if m != nil { +@@ -2003,9 +1959,9 @@ + } + + func (m *BeginExecuteRequest) Reset() { *m = BeginExecuteRequest{} } +-func (m *BeginExecuteRequest) String() string { return proto.CompactTextString(m) } +-func (*BeginExecuteRequest) ProtoMessage() {} +-func (*BeginExecuteRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{41} } ++func (m *BeginExecuteRequest) String() string { return "TODO" } ++ ++ + + func (m *BeginExecuteRequest) GetEffectiveCallerId() *vtrpc.CallerID { + if m != nil { +@@ -2054,9 +2010,9 @@ + } + + func (m *BeginExecuteResponse) Reset() { *m = BeginExecuteResponse{} } +-func (m *BeginExecuteResponse) String() string { return proto.CompactTextString(m) } +-func (*BeginExecuteResponse) ProtoMessage() {} +-func (*BeginExecuteResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{42} } ++func (m *BeginExecuteResponse) String() string { return "TODO" } ++ ++ + + func (m *BeginExecuteResponse) GetError() *vtrpc.RPCError { + if m != nil { +@@ -2090,9 +2046,9 @@ + } + + func (m *BeginExecuteBatchRequest) Reset() { *m = BeginExecuteBatchRequest{} } +-func (m *BeginExecuteBatchRequest) String() string { return proto.CompactTextString(m) } +-func (*BeginExecuteBatchRequest) ProtoMessage() {} +-func (*BeginExecuteBatchRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{43} } ++func (m *BeginExecuteBatchRequest) String() string { return "TODO" } ++ ++ + + func (m *BeginExecuteBatchRequest) GetEffectiveCallerId() *vtrpc.CallerID { + if m != nil { +@@ -2148,9 +2104,9 @@ + } + + func (m *BeginExecuteBatchResponse) Reset() { *m = BeginExecuteBatchResponse{} } +-func (m *BeginExecuteBatchResponse) String() string { return proto.CompactTextString(m) } +-func (*BeginExecuteBatchResponse) ProtoMessage() {} +-func (*BeginExecuteBatchResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{44} } ++func (m *BeginExecuteBatchResponse) String() string { return "TODO" } ++ ++ + + func (m *BeginExecuteBatchResponse) GetError() *vtrpc.RPCError { + if m != nil { +@@ -2183,9 +2139,9 @@ + } + + func (m *MessageStreamRequest) Reset() { *m = MessageStreamRequest{} } +-func (m *MessageStreamRequest) String() string { return proto.CompactTextString(m) } +-func (*MessageStreamRequest) ProtoMessage() {} +-func (*MessageStreamRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{45} } ++func (m *MessageStreamRequest) String() string { return "TODO" } ++ ++ + + func (m *MessageStreamRequest) GetEffectiveCallerId() *vtrpc.CallerID { + if m != nil { +@@ -2221,9 +2177,9 @@ + } + + func (m *MessageStreamResponse) Reset() { *m = MessageStreamResponse{} } +-func (m *MessageStreamResponse) String() string { return proto.CompactTextString(m) } +-func (*MessageStreamResponse) ProtoMessage() {} +-func (*MessageStreamResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{46} } ++func (m *MessageStreamResponse) String() string { return "TODO" } ++ ++ + + func (m *MessageStreamResponse) GetResult() *QueryResult { + if m != nil { +@@ -2243,9 +2199,9 @@ + } + + func (m *MessageAckRequest) Reset() { *m = MessageAckRequest{} } +-func (m *MessageAckRequest) String() string { return proto.CompactTextString(m) } +-func (*MessageAckRequest) ProtoMessage() {} +-func (*MessageAckRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{47} } ++func (m *MessageAckRequest) String() string { return "TODO" } ++ ++ + + func (m *MessageAckRequest) GetEffectiveCallerId() *vtrpc.CallerID { + if m != nil { +@@ -2291,9 +2247,9 @@ + } + + func (m *MessageAckResponse) Reset() { *m = MessageAckResponse{} } +-func (m *MessageAckResponse) String() string { return proto.CompactTextString(m) } +-func (*MessageAckResponse) ProtoMessage() {} +-func (*MessageAckResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{48} } ++func (m *MessageAckResponse) String() string { return "TODO" } ++ ++ + + func (m *MessageAckResponse) GetResult() *QueryResult { + if m != nil { +@@ -2317,9 +2273,9 @@ + } + + func (m *SplitQueryRequest) Reset() { *m = SplitQueryRequest{} } +-func (m *SplitQueryRequest) String() string { return proto.CompactTextString(m) } +-func (*SplitQueryRequest) ProtoMessage() {} +-func (*SplitQueryRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{49} } ++func (m *SplitQueryRequest) String() string { return "TODO" } ++ ++ + + func (m *SplitQueryRequest) GetEffectiveCallerId() *vtrpc.CallerID { + if m != nil { +@@ -2386,9 +2342,9 @@ + } + + func (m *QuerySplit) Reset() { *m = QuerySplit{} } +-func (m *QuerySplit) String() string { return proto.CompactTextString(m) } +-func (*QuerySplit) ProtoMessage() {} +-func (*QuerySplit) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{50} } ++func (m *QuerySplit) String() string { return "TODO" } ++ ++ + + func (m *QuerySplit) GetQuery() *BoundQuery { + if m != nil { +@@ -2411,9 +2367,9 @@ + } + + func (m *SplitQueryResponse) Reset() { *m = SplitQueryResponse{} } +-func (m *SplitQueryResponse) String() string { return proto.CompactTextString(m) } +-func (*SplitQueryResponse) ProtoMessage() {} +-func (*SplitQueryResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{51} } ++func (m *SplitQueryResponse) String() string { return "TODO" } ++ ++ + + func (m *SplitQueryResponse) GetQueries() []*QuerySplit { + if m != nil { +@@ -2427,12 +2383,11 @@ + } + + func (m *StreamHealthRequest) Reset() { *m = StreamHealthRequest{} } +-func (m *StreamHealthRequest) String() string { return proto.CompactTextString(m) } +-func (*StreamHealthRequest) ProtoMessage() {} +-func (*StreamHealthRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{52} } ++func (m *StreamHealthRequest) String() string { return "TODO" } ++ + +-// RealtimeStats contains information about the tablet status. +-// It is only valid for a single tablet. ++ ++// RealtimeStats contains information about the tablet status + type RealtimeStats struct { + // health_error is the last error we got from health check, + // or empty is the server is healthy. This is used for subset selection, +@@ -2464,9 +2419,9 @@ + } + + func (m *RealtimeStats) Reset() { *m = RealtimeStats{} } +-func (m *RealtimeStats) String() string { return proto.CompactTextString(m) } +-func (*RealtimeStats) ProtoMessage() {} +-func (*RealtimeStats) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{53} } ++func (m *RealtimeStats) String() string { return "TODO" } ++ ++ + + func (m *RealtimeStats) GetHealthError() string { + if m != nil { +@@ -2510,80 +2465,17 @@ + return 0 + } + +-// AggregateStats contains information about the health of a group of +-// tablets for a Target. It is used to propagate stats from a vtgate +-// to another, or from the Gateway layer of a vtgate to the routing +-// layer. +-type AggregateStats struct { +- // healthy_tablet_count is the number of healthy tablets in the group. +- HealthyTabletCount int32 `protobuf:"varint,1,opt,name=healthy_tablet_count,json=healthyTabletCount" json:"healthy_tablet_count,omitempty"` +- // unhealthy_tablet_count is the number of unhealthy tablets in the group. +- UnhealthyTabletCount int32 `protobuf:"varint,2,opt,name=unhealthy_tablet_count,json=unhealthyTabletCount" json:"unhealthy_tablet_count,omitempty"` +- // seconds_behind_master_min is the minimum of the +- // seconds_behind_master values of the healthy tablets. It is unset +- // if the tablet type is master. +- SecondsBehindMasterMin uint32 `protobuf:"varint,3,opt,name=seconds_behind_master_min,json=secondsBehindMasterMin" json:"seconds_behind_master_min,omitempty"` +- // seconds_behind_master_max is the maximum of the +- // seconds_behind_master values of the healthy tablets. It is unset +- // if the tablet type is master. +- SecondsBehindMasterMax uint32 `protobuf:"varint,4,opt,name=seconds_behind_master_max,json=secondsBehindMasterMax" json:"seconds_behind_master_max,omitempty"` +-} +- +-func (m *AggregateStats) Reset() { *m = AggregateStats{} } +-func (m *AggregateStats) String() string { return proto.CompactTextString(m) } +-func (*AggregateStats) ProtoMessage() {} +-func (*AggregateStats) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{54} } +- +-func (m *AggregateStats) GetHealthyTabletCount() int32 { +- if m != nil { +- return m.HealthyTabletCount +- } +- return 0 +-} +- +-func (m *AggregateStats) GetUnhealthyTabletCount() int32 { +- if m != nil { +- return m.UnhealthyTabletCount +- } +- return 0 +-} +- +-func (m *AggregateStats) GetSecondsBehindMasterMin() uint32 { +- if m != nil { +- return m.SecondsBehindMasterMin +- } +- return 0 +-} +- +-func (m *AggregateStats) GetSecondsBehindMasterMax() uint32 { +- if m != nil { +- return m.SecondsBehindMasterMax +- } +- return 0 +-} +- +-// StreamHealthResponse is streamed by StreamHealth on a regular basis. +-// When StreamHealth is used between a vtgate and vttablet: +-// - target describes the tablet. +-// - realtime_stats is set. +-// - aggregate_stats is not set. +-// When StreamHealth is used between two vtgates: +-// - target describes the group of tablets. +-// - realtime_stats is not set. +-// - aggregate_stats is set. ++// StreamHealthResponse is streamed by StreamHealth on a regular basis + type StreamHealthResponse struct { + // target is the current server type. Only queries with that exact Target +- // record will be accepted (the cell may not match, however). ++ // record will be accepted. + Target *Target `protobuf:"bytes,1,opt,name=target" json:"target,omitempty"` + // serving is true iff the tablet is serving. A tablet may not be serving + // if filtered replication is enabled on a master for instance, + // or if a replica should not be used because the keyspace is being resharded. + Serving bool `protobuf:"varint,2,opt,name=serving" json:"serving,omitempty"` +- // tablet_externally_reparented_timestamp can be interpreted as the +- // last time we knew that this tablet was the MASTER of this shard +- // (if StreamHealthResponse describes a group of tablets, between +- // two vtgates, only one master will be present in the group, and +- // this is this master's value). ++ // tablet_externally_reparented_timestamp can be interpreted as the last time ++ // we knew that this tablet was the MASTER of this shard. + // + // It is used by vtgate when determining the current MASTER of a shard. + // If vtgate sees more than one MASTER tablet, this timestamp is used +@@ -2606,12 +2498,8 @@ + // OR + // d) 0 if the vttablet was never a MASTER. + TabletExternallyReparentedTimestamp int64 `protobuf:"varint,3,opt,name=tablet_externally_reparented_timestamp,json=tabletExternallyReparentedTimestamp" json:"tablet_externally_reparented_timestamp,omitempty"` +- // realtime_stats contains information about the tablet status. +- // It is only filled in if the information is about a tablet. ++ // realtime_stats contains information about the tablet status + RealtimeStats *RealtimeStats `protobuf:"bytes,4,opt,name=realtime_stats,json=realtimeStats" json:"realtime_stats,omitempty"` +- // AggregateStats constains information about the group of tablet status. +- // It is only filled in if the information is about a group of tablets. +- AggregateStats *AggregateStats `protobuf:"bytes,6,opt,name=aggregate_stats,json=aggregateStats" json:"aggregate_stats,omitempty"` + // tablet_alias is the alias of the sending tablet. The discovery/healthcheck.go + // code uses it to verify that it's talking to the correct tablet and that it + // hasn't changed in the meantime e.g. due to tablet restarts where ports or +@@ -2620,9 +2508,9 @@ + } + + func (m *StreamHealthResponse) Reset() { *m = StreamHealthResponse{} } +-func (m *StreamHealthResponse) String() string { return proto.CompactTextString(m) } +-func (*StreamHealthResponse) ProtoMessage() {} +-func (*StreamHealthResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{55} } ++func (m *StreamHealthResponse) String() string { return "TODO" } ++ ++ + + func (m *StreamHealthResponse) GetTarget() *Target { + if m != nil { +@@ -2652,13 +2540,6 @@ + return nil + } + +-func (m *StreamHealthResponse) GetAggregateStats() *AggregateStats { +- if m != nil { +- return m.AggregateStats +- } +- return nil +-} +- + func (m *StreamHealthResponse) GetTabletAlias() *topodata.TabletAlias { + if m != nil { + return m.TabletAlias +@@ -2682,9 +2563,9 @@ + } + + func (m *UpdateStreamRequest) Reset() { *m = UpdateStreamRequest{} } +-func (m *UpdateStreamRequest) String() string { return proto.CompactTextString(m) } +-func (*UpdateStreamRequest) ProtoMessage() {} +-func (*UpdateStreamRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{56} } ++func (m *UpdateStreamRequest) String() string { return "TODO" } ++ ++ + + func (m *UpdateStreamRequest) GetEffectiveCallerId() *vtrpc.CallerID { + if m != nil { +@@ -2727,9 +2608,9 @@ + } + + func (m *UpdateStreamResponse) Reset() { *m = UpdateStreamResponse{} } +-func (m *UpdateStreamResponse) String() string { return proto.CompactTextString(m) } +-func (*UpdateStreamResponse) ProtoMessage() {} +-func (*UpdateStreamResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{57} } ++func (m *UpdateStreamResponse) String() string { return "TODO" } ++ ++ + + func (m *UpdateStreamResponse) GetEvent() *StreamEvent { + if m != nil { +@@ -2747,9 +2628,9 @@ + } + + func (m *TransactionMetadata) Reset() { *m = TransactionMetadata{} } +-func (m *TransactionMetadata) String() string { return proto.CompactTextString(m) } +-func (*TransactionMetadata) ProtoMessage() {} +-func (*TransactionMetadata) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{58} } ++func (m *TransactionMetadata) String() string { return "TODO" } ++ ++ + + func (m *TransactionMetadata) GetDtid() string { + if m != nil { +@@ -2835,7 +2716,6 @@ + proto.RegisterType((*SplitQueryResponse)(nil), "query.SplitQueryResponse") + proto.RegisterType((*StreamHealthRequest)(nil), "query.StreamHealthRequest") + proto.RegisterType((*RealtimeStats)(nil), "query.RealtimeStats") +- proto.RegisterType((*AggregateStats)(nil), "query.AggregateStats") + proto.RegisterType((*StreamHealthResponse)(nil), "query.StreamHealthResponse") + proto.RegisterType((*UpdateStreamRequest)(nil), "query.UpdateStreamRequest") + proto.RegisterType((*UpdateStreamResponse)(nil), "query.UpdateStreamResponse") +@@ -2851,207 +2731,4 @@ + proto.RegisterEnum("query.SplitQueryRequest_Algorithm", SplitQueryRequest_Algorithm_name, SplitQueryRequest_Algorithm_value) + } + +-func init() { proto.RegisterFile("query.proto", fileDescriptor0) } +- +-var fileDescriptor0 = []byte{ +- // 3183 bytes of a gzipped FileDescriptorProto +- 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x5a, 0xcb, 0x73, 0x1b, 0xc7, +- 0x99, 0xd7, 0xe0, 0x41, 0x02, 0x1f, 0x08, 0xb0, 0xd9, 0x20, 0x25, 0x88, 0xf2, 0x83, 0x3b, 0xb6, +- 0x6c, 0x2e, 0xed, 0xe5, 0xca, 0x94, 0x56, 0xab, 0xb5, 0x77, 0xbd, 0x1a, 0x82, 0x43, 0x19, 0x16, +- 0x5e, 0x6a, 0x0c, 0x24, 0xcb, 0xe5, 0xaa, 0xa9, 0x21, 0xd0, 0x02, 0xa7, 0x38, 0xc0, 0x40, 0x33, +- 0x03, 0x51, 0xbc, 0x69, 0xd7, 0x71, 0xde, 0x0f, 0xe7, 0xe9, 0x38, 0xa9, 0x38, 0xa9, 0xca, 0x3d, +- 0x7f, 0x43, 0x2a, 0x7f, 0x40, 0x6e, 0x39, 0x24, 0x39, 0xe4, 0x90, 0x4a, 0xe5, 0x90, 0x2a, 0x57, +- 0x4e, 0x39, 0xe4, 0x90, 0x4a, 0xf5, 0x63, 0x06, 0x03, 0x12, 0x7a, 0x58, 0xc9, 0x85, 0xb2, 0x4f, +- 0xe8, 0xfe, 0xbe, 0xaf, 0x1f, 0xbf, 0xdf, 0xf7, 0xcd, 0xd7, 0x8d, 0xee, 0x86, 0xdc, 0xed, 0x11, +- 0xf5, 0x0e, 0xd6, 0x87, 0x9e, 0x1b, 0xb8, 0x38, 0xcd, 0x2b, 0xcb, 0x85, 0xc0, 0x1d, 0xba, 0x5d, +- 0x2b, 0xb0, 0x84, 0x78, 0x39, 0x77, 0x27, 0xf0, 0x86, 0x1d, 0x51, 0x51, 0xdf, 0x53, 0x60, 0xc6, +- 0xb0, 0xbc, 0x1e, 0x0d, 0xf0, 0x32, 0x64, 0xf6, 0xe8, 0x81, 0x3f, 0xb4, 0x3a, 0xb4, 0xa4, 0xac, +- 0x28, 0xab, 0x59, 0x12, 0xd5, 0xf1, 0x22, 0xa4, 0xfd, 0x5d, 0xcb, 0xeb, 0x96, 0x12, 0x5c, 0x21, +- 0x2a, 0xf8, 0x3f, 0x20, 0x17, 0x58, 0x3b, 0x0e, 0x0d, 0xcc, 0xe0, 0x60, 0x48, 0x4b, 0xc9, 0x15, +- 0x65, 0xb5, 0xb0, 0xb1, 0xb8, 0x1e, 0x8d, 0x67, 0x70, 0xa5, 0x71, 0x30, 0xa4, 0x04, 0x82, 0xa8, +- 0x8c, 0x31, 0xa4, 0x3a, 0xd4, 0x71, 0x4a, 0x29, 0xde, 0x17, 0x2f, 0xab, 0x5b, 0x50, 0xb8, 0x6e, +- 0x5c, 0xb1, 0x02, 0x5a, 0xb6, 0x1c, 0x87, 0x7a, 0x95, 0x2d, 0x36, 0x9d, 0x91, 0x4f, 0xbd, 0x81, +- 0xd5, 0x8f, 0xa6, 0x13, 0xd6, 0xf1, 0x49, 0x98, 0xe9, 0x79, 0xee, 0x68, 0xe8, 0x97, 0x12, 0x2b, +- 0xc9, 0xd5, 0x2c, 0x91, 0x35, 0xf5, 0x1d, 0x00, 0xfd, 0x0e, 0x1d, 0x04, 0x86, 0xbb, 0x47, 0x07, +- 0xf8, 0x29, 0xc8, 0x06, 0x76, 0x9f, 0xfa, 0x81, 0xd5, 0x1f, 0xf2, 0x2e, 0x92, 0x64, 0x2c, 0xb8, +- 0x0f, 0xa4, 0x65, 0xc8, 0x0c, 0x5d, 0xdf, 0x0e, 0x6c, 0x77, 0xc0, 0xf1, 0x64, 0x49, 0x54, 0x57, +- 0x5f, 0x87, 0xf4, 0x75, 0xcb, 0x19, 0x51, 0xfc, 0x2c, 0xa4, 0x38, 0x60, 0x85, 0x03, 0xce, 0xad, +- 0x0b, 0xd2, 0x39, 0x4e, 0xae, 0x60, 0x7d, 0xdf, 0x61, 0x96, 0xbc, 0xef, 0x39, 0x22, 0x2a, 0xea, +- 0x1e, 0xcc, 0x6d, 0xda, 0x83, 0xee, 0x75, 0xcb, 0xb3, 0x19, 0x19, 0x8f, 0xd9, 0x0d, 0x7e, 0x1e, +- 0x66, 0x78, 0xc1, 0x2f, 0x25, 0x57, 0x92, 0xab, 0xb9, 0x8d, 0x39, 0xd9, 0x90, 0xcf, 0x8d, 0x48, +- 0x9d, 0xfa, 0x0b, 0x05, 0x60, 0xd3, 0x1d, 0x0d, 0xba, 0xd7, 0x98, 0x12, 0x23, 0x48, 0xfa, 0xb7, +- 0x1d, 0x49, 0x24, 0x2b, 0xe2, 0xab, 0x50, 0xd8, 0xb1, 0x07, 0x5d, 0xf3, 0x8e, 0x9c, 0x8e, 0xe0, +- 0x32, 0xb7, 0xf1, 0xbc, 0xec, 0x6e, 0xdc, 0x78, 0x3d, 0x3e, 0x6b, 0x5f, 0x1f, 0x04, 0xde, 0x01, +- 0xc9, 0xef, 0xc4, 0x65, 0xcb, 0x6d, 0xc0, 0x47, 0x8d, 0xd8, 0xa0, 0x7b, 0xf4, 0x20, 0x1c, 0x74, +- 0x8f, 0x1e, 0xe0, 0x7f, 0x8d, 0x23, 0xca, 0x6d, 0x14, 0xc3, 0xb1, 0x62, 0x6d, 0x25, 0xcc, 0x57, +- 0x13, 0x97, 0x14, 0xf5, 0x4f, 0x69, 0x28, 0xe8, 0x77, 0x69, 0x67, 0x14, 0xd0, 0xc6, 0x90, 0xf9, +- 0xc0, 0xc7, 0xeb, 0x50, 0xb4, 0x07, 0x1d, 0x67, 0xd4, 0xa5, 0x26, 0x65, 0xae, 0x36, 0x03, 0xe6, +- 0x6b, 0xde, 0x5f, 0x86, 0x2c, 0x48, 0x55, 0x2c, 0x08, 0x34, 0x28, 0x76, 0xdc, 0xfe, 0xd0, 0xf2, +- 0x26, 0xed, 0x93, 0x7c, 0xfc, 0x05, 0x39, 0xfe, 0xd8, 0x9e, 0x2c, 0x48, 0xeb, 0x58, 0x17, 0x35, +- 0x98, 0x97, 0xfd, 0x76, 0xcd, 0x5b, 0x36, 0x75, 0xba, 0x3e, 0x0f, 0xdd, 0x42, 0x44, 0xd5, 0xe4, +- 0x14, 0xd7, 0x2b, 0xd2, 0x78, 0x9b, 0xdb, 0x92, 0x82, 0x3d, 0x51, 0xc7, 0x6b, 0xb0, 0xd0, 0x71, +- 0x6c, 0x36, 0x95, 0x5b, 0x8c, 0x62, 0xd3, 0x73, 0xf7, 0xfd, 0x52, 0x9a, 0xcf, 0x7f, 0x5e, 0x28, +- 0xb6, 0x99, 0x9c, 0xb8, 0xfb, 0x3e, 0x7e, 0x15, 0x32, 0xfb, 0xae, 0xb7, 0xe7, 0xb8, 0x56, 0xb7, +- 0x34, 0xc3, 0xc7, 0x7c, 0x66, 0xfa, 0x98, 0x37, 0xa4, 0x15, 0x89, 0xec, 0xf1, 0x2a, 0x20, 0xff, +- 0xb6, 0x63, 0xfa, 0xd4, 0xa1, 0x9d, 0xc0, 0x74, 0xec, 0xbe, 0x1d, 0x94, 0x32, 0xfc, 0x2b, 0x28, +- 0xf8, 0xb7, 0x9d, 0x16, 0x17, 0x57, 0x99, 0x14, 0x9b, 0xb0, 0x14, 0x78, 0xd6, 0xc0, 0xb7, 0x3a, +- 0xac, 0x33, 0xd3, 0xf6, 0x5d, 0xc7, 0xe2, 0x5f, 0x40, 0x96, 0x0f, 0xb9, 0x36, 0x7d, 0x48, 0x63, +- 0xdc, 0xa4, 0x12, 0xb6, 0x20, 0x8b, 0xc1, 0x14, 0x29, 0x7e, 0x05, 0x96, 0xfc, 0x3d, 0x7b, 0x68, +- 0xf2, 0x7e, 0xcc, 0xa1, 0x63, 0x0d, 0xcc, 0x8e, 0xd5, 0xd9, 0xa5, 0x25, 0xe0, 0xb0, 0x31, 0x53, +- 0xf2, 0x50, 0x6b, 0x3a, 0xd6, 0xa0, 0xcc, 0x34, 0xea, 0x6b, 0x50, 0x98, 0xe4, 0x11, 0x2f, 0x40, +- 0xde, 0xb8, 0xd9, 0xd4, 0x4d, 0xad, 0xbe, 0x65, 0xd6, 0xb5, 0x9a, 0x8e, 0x4e, 0xe0, 0x3c, 0x64, +- 0xb9, 0xa8, 0x51, 0xaf, 0xde, 0x44, 0x0a, 0x9e, 0x85, 0xa4, 0x56, 0xad, 0xa2, 0x84, 0x7a, 0x09, +- 0x32, 0x21, 0x21, 0x78, 0x1e, 0x72, 0xed, 0x7a, 0xab, 0xa9, 0x97, 0x2b, 0xdb, 0x15, 0x7d, 0x0b, +- 0x9d, 0xc0, 0x19, 0x48, 0x35, 0xaa, 0x46, 0x13, 0x29, 0xa2, 0xa4, 0x35, 0x51, 0x82, 0xb5, 0xdc, +- 0xda, 0xd4, 0x50, 0x52, 0x0d, 0x60, 0x71, 0x1a, 0x2e, 0x9c, 0x83, 0xd9, 0x2d, 0x7d, 0x5b, 0x6b, +- 0x57, 0x0d, 0x74, 0x02, 0x17, 0x61, 0x9e, 0xe8, 0x4d, 0x5d, 0x33, 0xb4, 0xcd, 0xaa, 0x6e, 0x12, +- 0x5d, 0xdb, 0x42, 0x0a, 0xc6, 0x50, 0x60, 0x25, 0xb3, 0xdc, 0xa8, 0xd5, 0x2a, 0x86, 0xa1, 0x6f, +- 0xa1, 0x04, 0x5e, 0x04, 0xc4, 0x65, 0xed, 0xfa, 0x58, 0x9a, 0xc4, 0x08, 0xe6, 0x5a, 0x3a, 0xa9, +- 0x68, 0xd5, 0xca, 0xdb, 0xac, 0x03, 0x94, 0x7a, 0x33, 0x95, 0x51, 0x50, 0x42, 0xfd, 0x20, 0x01, +- 0x69, 0x8e, 0x95, 0x65, 0xc8, 0x58, 0xde, 0xe3, 0xe5, 0x28, 0x5b, 0x24, 0x1e, 0x90, 0x2d, 0x78, +- 0x92, 0x95, 0x79, 0x4b, 0x54, 0xf0, 0x19, 0xc8, 0xba, 0x5e, 0xcf, 0x14, 0x1a, 0x91, 0x71, 0x33, +- 0xae, 0xd7, 0xe3, 0xa9, 0x99, 0x65, 0x3b, 0x96, 0xa8, 0x77, 0x2c, 0x9f, 0xf2, 0x08, 0xcc, 0x92, +- 0xa8, 0x8e, 0x4f, 0x03, 0xb3, 0x33, 0xf9, 0x3c, 0x66, 0xb8, 0x6e, 0xd6, 0xf5, 0x7a, 0x75, 0x36, +- 0x95, 0xe7, 0x20, 0xdf, 0x71, 0x9d, 0x51, 0x7f, 0x60, 0x3a, 0x74, 0xd0, 0x0b, 0x76, 0x4b, 0xb3, +- 0x2b, 0xca, 0x6a, 0x9e, 0xcc, 0x09, 0x61, 0x95, 0xcb, 0x70, 0x09, 0x66, 0x3b, 0xbb, 0x96, 0xe7, +- 0x53, 0x11, 0x75, 0x79, 0x12, 0x56, 0xf9, 0xa8, 0xb4, 0x63, 0xf7, 0x2d, 0xc7, 0xe7, 0x11, 0x96, +- 0x27, 0x51, 0x9d, 0x81, 0xb8, 0xe5, 0x58, 0x3d, 0x9f, 0x47, 0x46, 0x9e, 0x88, 0x8a, 0xfa, 0x9f, +- 0x90, 0x24, 0xee, 0x3e, 0xeb, 0x52, 0x0c, 0xe8, 0x97, 0x94, 0x95, 0xe4, 0x2a, 0x26, 0x61, 0x95, +- 0x2d, 0x08, 0x32, 0x27, 0x8a, 0x54, 0x19, 0x66, 0xc1, 0x77, 0x60, 0x8e, 0x50, 0x7f, 0xe4, 0x04, +- 0xfa, 0xdd, 0xc0, 0xb3, 0x7c, 0xbc, 0x01, 0xb9, 0x78, 0x16, 0x50, 0xee, 0x97, 0x05, 0x80, 0x8e, +- 0x3f, 0xff, 0x12, 0xcc, 0xde, 0xf2, 0xa8, 0xbf, 0x4b, 0x3d, 0x99, 0x65, 0xc2, 0x2a, 0xcb, 0xb1, +- 0x39, 0x1e, 0xb6, 0x62, 0x0c, 0x96, 0x99, 0x65, 0x7e, 0x50, 0x26, 0x32, 0x33, 0x77, 0x2a, 0x91, +- 0x3a, 0xc6, 0x1e, 0xfb, 0xe4, 0x4d, 0xeb, 0xd6, 0x2d, 0xda, 0x09, 0xa8, 0x58, 0x80, 0x52, 0x64, +- 0x8e, 0x09, 0x35, 0x29, 0x63, 0x6e, 0xb3, 0x07, 0x3e, 0xf5, 0x02, 0xd3, 0xee, 0x72, 0x87, 0xa6, +- 0x48, 0x46, 0x08, 0x2a, 0x5d, 0xfc, 0x0c, 0xa4, 0x78, 0xd2, 0x48, 0xf1, 0x51, 0x40, 0x8e, 0x42, +- 0xdc, 0x7d, 0xc2, 0xe5, 0xf8, 0x25, 0x98, 0xa1, 0x1c, 0x2f, 0x77, 0xea, 0x38, 0xcd, 0xc6, 0xa9, +- 0x20, 0xd2, 0x44, 0xfd, 0x49, 0x12, 0x72, 0xad, 0xc0, 0xa3, 0x56, 0x9f, 0xe3, 0xc7, 0xff, 0x0d, +- 0xe0, 0x07, 0x56, 0x40, 0xfb, 0x74, 0x10, 0x84, 0x40, 0x9e, 0x92, 0x1d, 0xc4, 0xec, 0xd6, 0x5b, +- 0xa1, 0x11, 0x89, 0xd9, 0x1f, 0x26, 0x38, 0xf1, 0x08, 0x04, 0x2f, 0x7f, 0x94, 0x80, 0x6c, 0xd4, +- 0x1b, 0xd6, 0x20, 0xd3, 0xb1, 0x02, 0xda, 0x73, 0xbd, 0x03, 0xb9, 0x32, 0x9e, 0x7d, 0xd0, 0xe8, +- 0xeb, 0x65, 0x69, 0x4c, 0xa2, 0x66, 0xf8, 0x69, 0x10, 0xdb, 0x0d, 0x11, 0xbc, 0x62, 0x7d, 0xcf, +- 0x72, 0x09, 0x0f, 0xdf, 0x57, 0x01, 0x0f, 0x3d, 0xbb, 0x6f, 0x79, 0x07, 0xe6, 0x1e, 0x3d, 0x08, +- 0x53, 0x7a, 0x72, 0x8a, 0xcb, 0x90, 0xb4, 0xbb, 0x4a, 0x0f, 0x64, 0x12, 0xba, 0x34, 0xd9, 0x56, +- 0x06, 0xdd, 0x51, 0x47, 0xc4, 0x5a, 0xf2, 0x75, 0xd9, 0x0f, 0x57, 0xe0, 0x34, 0x8f, 0x4f, 0x56, +- 0x54, 0x5f, 0x84, 0x4c, 0x38, 0x79, 0x9c, 0x85, 0xb4, 0xee, 0x79, 0xae, 0x87, 0x4e, 0xf0, 0x5c, +- 0x54, 0xab, 0x8a, 0x74, 0xb6, 0xb5, 0xc5, 0xd2, 0xd9, 0xcf, 0x13, 0xd1, 0x32, 0x48, 0xe8, 0xed, +- 0x11, 0xf5, 0x03, 0xfc, 0xbf, 0x50, 0xa4, 0x3c, 0x56, 0xec, 0x3b, 0xd4, 0xec, 0xf0, 0x3d, 0x13, +- 0x8b, 0x14, 0x11, 0xd0, 0xf3, 0xeb, 0x62, 0x8b, 0x17, 0xee, 0xa5, 0xc8, 0x42, 0x64, 0x2b, 0x45, +- 0x5d, 0xac, 0x43, 0xd1, 0xee, 0xf7, 0x69, 0xd7, 0xb6, 0x82, 0x78, 0x07, 0xc2, 0x61, 0x4b, 0xe1, +- 0x96, 0x62, 0x62, 0x4b, 0x46, 0x16, 0xa2, 0x16, 0x51, 0x37, 0x67, 0x61, 0x26, 0xe0, 0xdb, 0x47, +- 0xb9, 0xa2, 0xe6, 0xc3, 0xbc, 0xc4, 0x85, 0x44, 0x2a, 0xf1, 0x8b, 0x20, 0x36, 0xa3, 0x3c, 0x03, +- 0x8d, 0x03, 0x62, 0xbc, 0xc7, 0x20, 0x42, 0x8f, 0xcf, 0x42, 0x61, 0x62, 0x29, 0xea, 0x72, 0xc2, +- 0x92, 0x24, 0x1f, 0x5f, 0x57, 0xba, 0xf8, 0xdf, 0x61, 0xd6, 0x15, 0xcb, 0x10, 0xcf, 0x4d, 0xe3, +- 0x19, 0x4f, 0xae, 0x51, 0x24, 0xb4, 0x52, 0xff, 0x07, 0xe6, 0x23, 0x06, 0xfd, 0xa1, 0x3b, 0xf0, +- 0x29, 0x5e, 0x83, 0x19, 0x8f, 0x7f, 0x10, 0x92, 0x35, 0x2c, 0xbb, 0x88, 0x7d, 0xd1, 0x44, 0x5a, +- 0xa8, 0x5d, 0x98, 0x17, 0x92, 0x1b, 0x76, 0xb0, 0xcb, 0x1d, 0x85, 0xcf, 0x42, 0x9a, 0xb2, 0xc2, +- 0x21, 0xce, 0x49, 0xb3, 0xcc, 0xf5, 0x44, 0x68, 0x63, 0xa3, 0x24, 0x1e, 0x3a, 0xca, 0x9f, 0x13, +- 0x50, 0x94, 0xb3, 0xdc, 0xb4, 0x82, 0xce, 0xee, 0x31, 0x75, 0xf6, 0x4b, 0x30, 0xcb, 0xe4, 0x76, +- 0xf4, 0x61, 0x4c, 0x71, 0x77, 0x68, 0xc1, 0x1c, 0x6e, 0xf9, 0x66, 0xcc, 0xbb, 0x72, 0x2b, 0x94, +- 0xb7, 0xfc, 0xd8, 0x42, 0x3c, 0x25, 0x2e, 0x66, 0x1e, 0x12, 0x17, 0xb3, 0x8f, 0x14, 0x17, 0x5b, +- 0xb0, 0x38, 0xc9, 0xb8, 0x0c, 0x8e, 0x97, 0x61, 0x56, 0x38, 0x25, 0x4c, 0x81, 0xd3, 0xfc, 0x16, +- 0x9a, 0xa8, 0x3f, 0x4e, 0xc0, 0xa2, 0xcc, 0x4e, 0x9f, 0x8e, 0xcf, 0x34, 0xc6, 0x73, 0xfa, 0x91, +- 0x78, 0x2e, 0xc3, 0xd2, 0x21, 0x82, 0x1e, 0xe3, 0x2b, 0xfc, 0x58, 0x81, 0xb9, 0x4d, 0xda, 0xb3, +- 0x07, 0xc7, 0x94, 0xde, 0x18, 0x6b, 0xa9, 0x47, 0x62, 0xed, 0x22, 0xe4, 0x25, 0x5e, 0xc9, 0xd6, +- 0xd1, 0xcf, 0x40, 0x99, 0xf2, 0x19, 0xa8, 0x7f, 0x50, 0x20, 0x5f, 0x76, 0xfb, 0x7d, 0x3b, 0x38, +- 0xa6, 0x4c, 0x1d, 0xc5, 0x99, 0x9a, 0x86, 0x13, 0x41, 0x21, 0x84, 0x29, 0x08, 0x52, 0xff, 0xa8, +- 0xc0, 0x3c, 0x71, 0x1d, 0x67, 0xc7, 0xea, 0xec, 0x3d, 0xd9, 0xd8, 0x31, 0xa0, 0x31, 0x50, 0x89, +- 0xfe, 0xaf, 0x0a, 0x14, 0x9a, 0x1e, 0x65, 0xff, 0x5f, 0x9f, 0x68, 0xf0, 0xec, 0x0f, 0x52, 0x37, +- 0x90, 0x9b, 0x83, 0x2c, 0xe1, 0x65, 0x75, 0x01, 0xe6, 0x23, 0xec, 0x92, 0x8f, 0xdf, 0x28, 0xb0, +- 0x24, 0x02, 0x44, 0x6a, 0xba, 0xc7, 0x94, 0x96, 0x10, 0x6f, 0x2a, 0x86, 0xb7, 0x04, 0x27, 0x0f, +- 0x63, 0x93, 0xb0, 0xdf, 0x4d, 0xc0, 0xa9, 0x30, 0x36, 0x8e, 0x39, 0xf0, 0x7f, 0x20, 0x1e, 0x96, +- 0xa1, 0x74, 0x94, 0x04, 0xc9, 0xd0, 0xfb, 0x09, 0x28, 0x95, 0x3d, 0x6a, 0x05, 0x34, 0xb6, 0xc9, +- 0x78, 0x72, 0x62, 0x03, 0xbf, 0x02, 0x73, 0x43, 0xcb, 0x0b, 0xec, 0x8e, 0x3d, 0xb4, 0xd8, 0xdf, +- 0xb8, 0x34, 0xdf, 0xc3, 0x1c, 0xea, 0x60, 0xc2, 0x44, 0x3d, 0x03, 0xa7, 0xa7, 0x30, 0x22, 0xf9, +- 0xfa, 0x9b, 0x02, 0xb8, 0x15, 0x58, 0x5e, 0xf0, 0x29, 0x58, 0x55, 0xa6, 0x06, 0xd3, 0x12, 0x14, +- 0x27, 0xf0, 0xc7, 0x79, 0xa1, 0xc1, 0xa7, 0x62, 0xc5, 0xb9, 0x2f, 0x2f, 0x71, 0xfc, 0x92, 0x97, +- 0xdf, 0x29, 0xb0, 0x5c, 0x76, 0xc5, 0xf9, 0xdd, 0x13, 0xf9, 0x85, 0xa9, 0x4f, 0xc3, 0x99, 0xa9, +- 0x00, 0x25, 0x01, 0xbf, 0x55, 0xe0, 0x24, 0xa1, 0x56, 0xf7, 0xc9, 0x04, 0x7f, 0x0d, 0x4e, 0x1d, +- 0x01, 0x27, 0x77, 0xa8, 0x17, 0x21, 0xd3, 0xa7, 0x81, 0xd5, 0xb5, 0x02, 0x4b, 0x42, 0x5a, 0x0e, +- 0xfb, 0x1d, 0x5b, 0xd7, 0xa4, 0x05, 0x89, 0x6c, 0xd5, 0x8f, 0x12, 0x50, 0xe4, 0x7b, 0xdd, 0xcf, +- 0xfe, 0x41, 0x4d, 0xff, 0x2f, 0xf0, 0xbe, 0x02, 0x8b, 0x93, 0x04, 0x45, 0xff, 0x09, 0xfe, 0xd9, +- 0x07, 0x11, 0x53, 0x12, 0x42, 0x72, 0xda, 0x16, 0xf4, 0x97, 0x09, 0x28, 0xc5, 0xa7, 0xf4, 0xd9, +- 0xa1, 0xc5, 0xe4, 0xa1, 0xc5, 0x27, 0x3e, 0xa5, 0xfa, 0x40, 0x81, 0xd3, 0x53, 0x08, 0xfd, 0x64, +- 0x8e, 0x8e, 0x1d, 0x5d, 0x24, 0x1e, 0x7a, 0x74, 0xf1, 0xa8, 0xae, 0xfe, 0xb5, 0x02, 0x8b, 0x35, +- 0xea, 0xfb, 0x56, 0x8f, 0x8a, 0xff, 0xf1, 0xc7, 0x37, 0x9b, 0xf1, 0x43, 0xe1, 0xd4, 0xf8, 0x66, +- 0x45, 0x2d, 0xc3, 0xd2, 0x21, 0x68, 0x8f, 0x71, 0x36, 0xf1, 0x17, 0x05, 0x16, 0x64, 0x2f, 0xda, +- 0xb1, 0xdd, 0x08, 0x4c, 0x61, 0x07, 0x3f, 0x03, 0x49, 0xbb, 0x1b, 0xee, 0x20, 0x27, 0xef, 0x9a, +- 0x99, 0x42, 0xbd, 0x0c, 0x38, 0x8e, 0xfb, 0x31, 0xa8, 0xfb, 0x55, 0x12, 0x16, 0x5a, 0x43, 0xc7, +- 0x0e, 0xa4, 0xf2, 0xc9, 0x4e, 0xfc, 0xff, 0x02, 0x73, 0x3e, 0x03, 0x6b, 0x8a, 0xdb, 0x32, 0x4e, +- 0x6c, 0x96, 0xe4, 0xb8, 0xac, 0xcc, 0x45, 0xf8, 0x59, 0xc8, 0x85, 0x26, 0xa3, 0x41, 0x20, 0x4f, +- 0x3a, 0x41, 0x5a, 0x8c, 0x06, 0x01, 0xbe, 0x00, 0xa7, 0x06, 0xa3, 0x3e, 0xbf, 0x39, 0x36, 0x87, +- 0xd4, 0x0b, 0xef, 0x55, 0x2d, 0x2f, 0xbc, 0xe1, 0x2d, 0x0e, 0x46, 0x7d, 0xe2, 0xee, 0xfb, 0x4d, +- 0xea, 0x89, 0x7b, 0x55, 0xcb, 0x0b, 0xf0, 0x65, 0xc8, 0x5a, 0x4e, 0xcf, 0xf5, 0xec, 0x60, 0xb7, +- 0x2f, 0xaf, 0x76, 0xd5, 0xf0, 0x6a, 0xe5, 0x30, 0xfd, 0xeb, 0x5a, 0x68, 0x49, 0xc6, 0x8d, 0xd4, +- 0x97, 0x21, 0x1b, 0xc9, 0x31, 0x82, 0x39, 0xfd, 0x5a, 0x5b, 0xab, 0x9a, 0xad, 0x66, 0xb5, 0x62, +- 0xb4, 0xc4, 0x75, 0xec, 0x76, 0xbb, 0x5a, 0x35, 0x5b, 0x65, 0xad, 0x8e, 0x14, 0x95, 0x00, 0xf0, +- 0x2e, 0x79, 0xe7, 0x63, 0x82, 0x94, 0x87, 0x10, 0x74, 0x06, 0xb2, 0x9e, 0xbb, 0x2f, 0xb1, 0x27, +- 0x38, 0x9c, 0x8c, 0xe7, 0xee, 0x73, 0xe4, 0xaa, 0x06, 0x38, 0x3e, 0x57, 0x19, 0x6d, 0xb1, 0xe4, +- 0xad, 0x4c, 0x24, 0xef, 0xf1, 0xf8, 0x51, 0xf2, 0x16, 0x5b, 0x79, 0xf6, 0x9d, 0xbf, 0x41, 0x2d, +- 0x27, 0x08, 0xd7, 0x2b, 0xf5, 0xa7, 0x09, 0xc8, 0x13, 0x26, 0xb1, 0xfb, 0xb4, 0x15, 0x58, 0x81, +- 0xcf, 0x3c, 0xb5, 0xcb, 0x4d, 0xcc, 0x71, 0xda, 0xcd, 0x92, 0x9c, 0x90, 0x89, 0x4b, 0x80, 0x0d, +- 0x58, 0xf2, 0x69, 0xc7, 0x1d, 0x74, 0x7d, 0x73, 0x87, 0xee, 0xda, 0x83, 0xae, 0xd9, 0xb7, 0xfc, +- 0x40, 0xde, 0x14, 0xe6, 0x49, 0x51, 0x2a, 0x37, 0xb9, 0xae, 0xc6, 0x55, 0xf8, 0x1c, 0x2c, 0xee, +- 0xd8, 0x03, 0xc7, 0xed, 0x99, 0x43, 0xc7, 0x3a, 0xa0, 0x9e, 0x2f, 0xa1, 0xb2, 0xf0, 0x4a, 0x13, +- 0x2c, 0x74, 0x4d, 0xa1, 0x12, 0xee, 0x7e, 0x1b, 0xd6, 0xa6, 0x8e, 0x62, 0xde, 0xb2, 0x9d, 0x80, +- 0x7a, 0xb4, 0x6b, 0x7a, 0x74, 0xe8, 0xd8, 0x1d, 0x71, 0x69, 0x2f, 0xf6, 0xee, 0x2f, 0x4c, 0x19, +- 0x7a, 0x5b, 0x9a, 0x93, 0xb1, 0x35, 0x63, 0xbb, 0x33, 0x1c, 0x99, 0x23, 0xf6, 0x01, 0xf3, 0x55, +- 0x4c, 0x21, 0x99, 0xce, 0x70, 0xd4, 0x66, 0x75, 0x8c, 0x20, 0x79, 0x7b, 0x28, 0x16, 0x2f, 0x85, +- 0xb0, 0xa2, 0xfa, 0xb1, 0x02, 0x05, 0xad, 0xd7, 0xf3, 0x68, 0xcf, 0x0a, 0x24, 0x4d, 0xe7, 0x60, +- 0x51, 0x50, 0x72, 0x60, 0xca, 0xd7, 0x40, 0x02, 0x8f, 0x22, 0xf0, 0x48, 0x9d, 0x78, 0x0b, 0x14, +- 0x86, 0xef, 0xc9, 0xd1, 0x60, 0x6a, 0x9b, 0x04, 0x6f, 0xb3, 0x18, 0x69, 0xe3, 0xad, 0xfe, 0x0b, +- 0x4e, 0x4f, 0x67, 0xa1, 0x6f, 0x8b, 0xf7, 0x1c, 0x79, 0x72, 0x72, 0x0a, 0xe8, 0x9a, 0x3d, 0x78, +- 0x40, 0x53, 0xeb, 0x2e, 0xe7, 0xeb, 0x3e, 0x4d, 0xad, 0xbb, 0xea, 0xef, 0xa3, 0xa3, 0xfd, 0x30, +- 0x5c, 0xa2, 0xd5, 0x38, 0xcc, 0x0b, 0xca, 0x83, 0xf2, 0x42, 0x09, 0x66, 0x7d, 0xea, 0xdd, 0xb1, +- 0x07, 0xbd, 0xf0, 0xf6, 0x58, 0x56, 0x71, 0x0b, 0x5e, 0x90, 0xd8, 0xe9, 0xdd, 0x80, 0x7a, 0x03, +- 0xcb, 0x71, 0x0e, 0x4c, 0x71, 0x50, 0x31, 0x08, 0x68, 0xd7, 0x1c, 0xbf, 0x5d, 0x12, 0x2b, 0xf2, +- 0x73, 0xc2, 0x5a, 0x8f, 0x8c, 0x49, 0x64, 0x6b, 0x44, 0xaf, 0x9a, 0x5e, 0x83, 0x82, 0x27, 0x83, +- 0xd8, 0xf4, 0x99, 0x7b, 0x64, 0x3e, 0x5a, 0x8c, 0xae, 0x80, 0x63, 0x11, 0x4e, 0xf2, 0xde, 0x44, +- 0xc0, 0xbf, 0x0e, 0xf3, 0x56, 0xe8, 0x5b, 0xd9, 0x7a, 0x72, 0xdf, 0x32, 0xe9, 0x79, 0x52, 0xb0, +- 0x26, 0x23, 0xe1, 0x12, 0xcc, 0x49, 0x44, 0x96, 0x63, 0x5b, 0xe3, 0x8d, 0xed, 0xa1, 0x07, 0x61, +- 0x1a, 0x53, 0x12, 0xf9, 0x74, 0x8c, 0x57, 0xd8, 0xff, 0xe8, 0x62, 0x7b, 0xd8, 0xe5, 0x3d, 0x1d, +- 0xe3, 0xdd, 0x45, 0xfc, 0xf5, 0x58, 0x6a, 0xf2, 0xf5, 0xd8, 0xe4, 0x6b, 0xb4, 0xf4, 0xa1, 0xd7, +- 0x68, 0xea, 0x65, 0x58, 0x9c, 0xc4, 0x2f, 0xa3, 0x6c, 0x15, 0xd2, 0xfc, 0xa6, 0xfc, 0xd0, 0x32, +- 0x1a, 0xbb, 0x0a, 0x27, 0xc2, 0x40, 0xfd, 0x99, 0x02, 0xc5, 0x29, 0x7f, 0xb1, 0xa2, 0xff, 0x6f, +- 0x4a, 0xec, 0x78, 0xe8, 0xdf, 0x20, 0xcd, 0xef, 0xec, 0xe5, 0x63, 0x92, 0x53, 0x47, 0xff, 0xa1, +- 0xf1, 0xfb, 0x75, 0x22, 0xac, 0x58, 0x22, 0xe4, 0x01, 0xd5, 0xe1, 0xe7, 0x43, 0xe1, 0x0e, 0x31, +- 0xc7, 0x64, 0xe2, 0xc8, 0xe8, 0xe8, 0x81, 0x53, 0xea, 0xa1, 0x07, 0x4e, 0x6b, 0xdf, 0x4a, 0x42, +- 0xb6, 0x76, 0xd0, 0xba, 0xed, 0x6c, 0x3b, 0x56, 0x8f, 0x5f, 0x80, 0xd7, 0x9a, 0xc6, 0x4d, 0x74, +- 0x02, 0x2f, 0x40, 0xbe, 0xde, 0x30, 0xcc, 0x3a, 0x5b, 0x4a, 0xb6, 0xab, 0xda, 0x15, 0xa4, 0xb0, +- 0xb5, 0xa6, 0x49, 0x2a, 0xe6, 0x55, 0xfd, 0xa6, 0x90, 0x24, 0x70, 0x11, 0xe6, 0xdb, 0xf5, 0xca, +- 0xb5, 0xb6, 0x3e, 0x16, 0xa6, 0xf0, 0x12, 0x2c, 0xd4, 0xda, 0x55, 0xa3, 0xd2, 0xac, 0xc6, 0xc4, +- 0x19, 0xb6, 0x2e, 0x6d, 0x56, 0x1b, 0x9b, 0xa2, 0x8a, 0x58, 0xff, 0xed, 0x7a, 0xab, 0x72, 0xa5, +- 0xae, 0x6f, 0x09, 0xd1, 0x0a, 0x13, 0xbd, 0xad, 0x93, 0xc6, 0x76, 0x25, 0x1c, 0xf2, 0x32, 0x46, +- 0x90, 0xdb, 0xac, 0xd4, 0x35, 0x22, 0x7b, 0xb9, 0xa7, 0xe0, 0x02, 0x64, 0xf5, 0x7a, 0xbb, 0x26, +- 0xeb, 0x09, 0x5c, 0x82, 0xa2, 0xd6, 0x36, 0x1a, 0x66, 0xa5, 0x5e, 0x26, 0x7a, 0x4d, 0xaf, 0x1b, +- 0x52, 0x93, 0xc2, 0x45, 0x28, 0x18, 0x95, 0x9a, 0xde, 0x32, 0xb4, 0x5a, 0x53, 0x0a, 0xd9, 0x2c, +- 0x32, 0x2d, 0x3d, 0xb4, 0x41, 0x78, 0x19, 0x96, 0xea, 0x0d, 0x53, 0x3e, 0x2a, 0x32, 0xaf, 0x6b, +- 0xd5, 0xb6, 0x2e, 0x75, 0x2b, 0xf8, 0x14, 0xe0, 0x46, 0xdd, 0x6c, 0x37, 0xb7, 0x34, 0x43, 0x37, +- 0xeb, 0x8d, 0x1b, 0x52, 0x71, 0x19, 0x17, 0x20, 0x33, 0x9e, 0xc1, 0x3d, 0xc6, 0x42, 0xbe, 0xa9, +- 0x11, 0x63, 0x0c, 0xf6, 0xde, 0x3d, 0x46, 0x16, 0x5c, 0x21, 0x8d, 0x76, 0x73, 0x6c, 0xb6, 0x00, +- 0x39, 0x49, 0x96, 0x14, 0xa5, 0x98, 0x68, 0xb3, 0x52, 0x2f, 0x47, 0xf3, 0xbb, 0x97, 0x59, 0x4e, +- 0x20, 0x65, 0x6d, 0x0f, 0x52, 0xdc, 0x1d, 0x19, 0x48, 0xd5, 0x1b, 0x75, 0x1d, 0x9d, 0xc0, 0xf3, +- 0x00, 0x95, 0x56, 0xa5, 0x6e, 0xe8, 0x57, 0x88, 0x56, 0x65, 0xb0, 0xb9, 0x20, 0x24, 0x90, 0xa1, +- 0x9d, 0x83, 0xd9, 0x4a, 0x6b, 0xbb, 0xda, 0xd0, 0x0c, 0x09, 0xb3, 0xd2, 0xba, 0xd6, 0x6e, 0x18, +- 0x4c, 0x89, 0x70, 0x0e, 0x66, 0x2a, 0x2d, 0x43, 0x7f, 0xcb, 0x60, 0xb8, 0xb8, 0x4e, 0xb0, 0x8a, +- 0xee, 0x5d, 0x5e, 0xfb, 0x30, 0x09, 0x29, 0xfe, 0x22, 0x34, 0x0f, 0x59, 0xee, 0x6d, 0xe3, 0x66, +- 0x93, 0x0d, 0x99, 0x85, 0x54, 0xa5, 0x6e, 0x5c, 0x42, 0xff, 0x97, 0xc0, 0x00, 0xe9, 0x36, 0x2f, +- 0xff, 0xff, 0x0c, 0x2b, 0x57, 0xea, 0xc6, 0x2b, 0x17, 0xd1, 0xbb, 0x09, 0xd6, 0x6d, 0x5b, 0x54, +- 0x3e, 0x17, 0x2a, 0x36, 0x2e, 0xa0, 0xf7, 0x22, 0xc5, 0xc6, 0x05, 0xf4, 0xf9, 0x50, 0x71, 0x7e, +- 0x03, 0x7d, 0x21, 0x52, 0x9c, 0xdf, 0x40, 0x5f, 0x0c, 0x15, 0x17, 0x2f, 0xa0, 0x2f, 0x45, 0x8a, +- 0x8b, 0x17, 0xd0, 0x97, 0x67, 0x18, 0x16, 0x8e, 0xe4, 0xfc, 0x06, 0xfa, 0x4a, 0x26, 0xaa, 0x5d, +- 0xbc, 0x80, 0xbe, 0x9a, 0x61, 0xfe, 0x8f, 0xbc, 0x8a, 0xbe, 0x86, 0xd8, 0x34, 0x99, 0x83, 0xd0, +- 0xd7, 0x79, 0x91, 0xa9, 0xd0, 0x37, 0x10, 0xc3, 0xc8, 0xa4, 0xbc, 0xfa, 0x3e, 0xd7, 0xdc, 0xd4, +- 0x35, 0x82, 0xbe, 0x39, 0x23, 0xde, 0x90, 0x95, 0x2b, 0x35, 0xad, 0x8a, 0x30, 0x6f, 0xc1, 0x58, +- 0xf9, 0xf6, 0x39, 0x56, 0x64, 0xe1, 0x89, 0xbe, 0xd3, 0x64, 0x03, 0x5e, 0xd7, 0x48, 0xf9, 0x0d, +- 0x8d, 0xa0, 0xef, 0x9e, 0x63, 0x03, 0x5e, 0xd7, 0x88, 0xe4, 0xeb, 0x7b, 0x4d, 0x66, 0xc8, 0x55, +- 0x1f, 0x9c, 0x63, 0x93, 0x96, 0xf2, 0xef, 0x37, 0x71, 0x06, 0x92, 0x9b, 0x15, 0x03, 0x7d, 0xc8, +- 0x47, 0x63, 0x21, 0x8a, 0x7e, 0x80, 0x98, 0xb0, 0xa5, 0x1b, 0xe8, 0x87, 0x4c, 0x98, 0x36, 0xda, +- 0xcd, 0xaa, 0x8e, 0x9e, 0x62, 0x93, 0xbb, 0xa2, 0x37, 0x6a, 0xba, 0x41, 0x6e, 0xa2, 0x1f, 0x71, +- 0xf3, 0x37, 0x5b, 0x8d, 0x3a, 0xfa, 0x08, 0xe1, 0x02, 0x80, 0xfe, 0x56, 0x93, 0xe8, 0xad, 0x56, +- 0xa5, 0x51, 0x47, 0xcf, 0xae, 0x6d, 0x03, 0x3a, 0x9c, 0x0e, 0x18, 0x80, 0x76, 0xfd, 0x6a, 0xbd, +- 0x71, 0xa3, 0x8e, 0x4e, 0xb0, 0x4a, 0x93, 0xe8, 0x4d, 0x8d, 0xe8, 0x48, 0xc1, 0x00, 0x33, 0xe2, +- 0x85, 0x1b, 0x4a, 0xe0, 0x39, 0xc8, 0x90, 0x46, 0xb5, 0xba, 0xa9, 0x95, 0xaf, 0xa2, 0xe4, 0xe6, +- 0x02, 0xcc, 0xdb, 0xee, 0xfa, 0x1d, 0x3b, 0xa0, 0xbe, 0x2f, 0xde, 0x1c, 0xef, 0xcc, 0xf0, 0x9f, +- 0xf3, 0x7f, 0x0f, 0x00, 0x00, 0xff, 0xff, 0xde, 0xe3, 0xd2, 0x1e, 0xad, 0x2c, 0x00, 0x00, +-} ++*/ diff --git a/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/patches/sqlparser.patch b/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/patches/sqlparser.patch new file mode 100644 index 00000000..9cdc14e0 --- /dev/null +++ b/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/patches/sqlparser.patch @@ -0,0 +1,316 @@ +Only in /Users/bramp/go/src/github.com/xwb1989/sqlparser//: .git +Only in /Users/bramp/go/src/github.com/xwb1989/sqlparser//: .gitignore +Only in /Users/bramp/go/src/github.com/xwb1989/sqlparser//: .travis.yml +Only in /Users/bramp/go/src/github.com/xwb1989/sqlparser//: CONTRIBUTORS.md +Only in /Users/bramp/go/src/github.com/xwb1989/sqlparser//: LICENSE.md +Only in /Users/bramp/go/src/github.com/xwb1989/sqlparser//: README.md +diff -u /Users/bramp/go/src/vitess.io/vitess/go//vt/sqlparser/analyzer.go /Users/bramp/go/src/github.com/xwb1989/sqlparser//analyzer.go +--- /Users/bramp/go/src/vitess.io/vitess/go//vt/sqlparser/analyzer.go 2018-06-05 08:45:47.000000000 -0700 ++++ /Users/bramp/go/src/github.com/xwb1989/sqlparser//analyzer.go 2018-06-06 07:45:09.000000000 -0700 +@@ -19,15 +19,13 @@ + // analyzer.go contains utility analysis functions. + + import ( ++ "errors" + "fmt" + "strconv" + "strings" + "unicode" + +- "vitess.io/vitess/go/sqltypes" +- "vitess.io/vitess/go/vt/vterrors" +- +- vtrpcpb "vitess.io/vitess/go/vt/proto/vtrpc" ++ "github.com/xwb1989/sqlparser/dependency/sqltypes" + ) + + // These constants are used to identify the SQL statement type. +@@ -219,7 +217,7 @@ + case IntVal: + n, err := sqltypes.NewIntegral(string(node.Val)) + if err != nil { +- return sqltypes.PlanValue{}, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "%v", err) ++ return sqltypes.PlanValue{}, fmt.Errorf("%v", err) + } + return sqltypes.PlanValue{Value: n}, nil + case StrVal: +@@ -227,7 +225,7 @@ + case HexVal: + v, err := node.HexDecode() + if err != nil { +- return sqltypes.PlanValue{}, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "%v", err) ++ return sqltypes.PlanValue{}, fmt.Errorf("%v", err) + } + return sqltypes.PlanValue{Value: sqltypes.MakeTrusted(sqltypes.VarBinary, v)}, nil + } +@@ -243,7 +241,7 @@ + return sqltypes.PlanValue{}, err + } + if innerpv.ListKey != "" || innerpv.Values != nil { +- return sqltypes.PlanValue{}, vterrors.New(vtrpcpb.Code_UNIMPLEMENTED, "unsupported: nested lists") ++ return sqltypes.PlanValue{}, errors.New("unsupported: nested lists") + } + pv.Values = append(pv.Values, innerpv) + } +@@ -251,7 +249,7 @@ + case *NullVal: + return sqltypes.PlanValue{}, nil + } +- return sqltypes.PlanValue{}, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "expression is too complex '%v'", String(node)) ++ return sqltypes.PlanValue{}, fmt.Errorf("expression is too complex '%v'", String(node)) + } + + // StringIn is a convenience function that returns +diff -u /Users/bramp/go/src/vitess.io/vitess/go//vt/sqlparser/analyzer_test.go /Users/bramp/go/src/github.com/xwb1989/sqlparser//analyzer_test.go +--- /Users/bramp/go/src/vitess.io/vitess/go//vt/sqlparser/analyzer_test.go 2018-06-05 08:45:47.000000000 -0700 ++++ /Users/bramp/go/src/github.com/xwb1989/sqlparser//analyzer_test.go 2018-06-06 07:45:09.000000000 -0700 +@@ -21,7 +21,7 @@ + "strings" + "testing" + +- "vitess.io/vitess/go/sqltypes" ++ "github.com/xwb1989/sqlparser/dependency/sqltypes" + ) + + func TestPreview(t *testing.T) { +diff -u /Users/bramp/go/src/vitess.io/vitess/go//vt/sqlparser/ast.go /Users/bramp/go/src/github.com/xwb1989/sqlparser//ast.go +--- /Users/bramp/go/src/vitess.io/vitess/go//vt/sqlparser/ast.go 2018-06-05 08:45:47.000000000 -0700 ++++ /Users/bramp/go/src/github.com/xwb1989/sqlparser//ast.go 2018-06-06 07:45:09.000000000 -0700 +@@ -22,14 +22,11 @@ + "encoding/json" + "fmt" + "io" ++ "log" + "strings" + +- "vitess.io/vitess/go/sqltypes" +- "vitess.io/vitess/go/vt/log" +- "vitess.io/vitess/go/vt/vterrors" +- +- querypb "vitess.io/vitess/go/vt/proto/query" +- vtrpcpb "vitess.io/vitess/go/vt/proto/vtrpc" ++ "github.com/xwb1989/sqlparser/dependency/querypb" ++ "github.com/xwb1989/sqlparser/dependency/sqltypes" + ) + + // Instructions for creating new types: If a type +@@ -52,11 +49,11 @@ + tokenizer := NewStringTokenizer(sql) + if yyParse(tokenizer) != 0 { + if tokenizer.partialDDL != nil { +- log.Warningf("ignoring error parsing DDL '%s': %v", sql, tokenizer.LastError) ++ log.Printf("ignoring error parsing DDL '%s': %v", sql, tokenizer.LastError) + tokenizer.ParseTree = tokenizer.partialDDL + return tokenizer.ParseTree, nil + } +- return nil, vterrors.New(vtrpcpb.Code_INVALID_ARGUMENT, tokenizer.LastError.Error()) ++ return nil, tokenizer.LastError + } + return tokenizer.ParseTree, nil + } +@@ -2249,7 +2246,7 @@ + return NewStrVal(value.ToBytes()), nil + default: + // We cannot support sqltypes.Expression, or any other invalid type. +- return nil, vterrors.Errorf(vtrpcpb.Code_INTERNAL, "cannot convert value %v to AST", value) ++ return nil, fmt.Errorf("cannot convert value %v to AST", value) + } + } + +@@ -3394,6 +3391,20 @@ + return nil + } + ++// Backtick produces a backticked literal given an input string. ++func Backtick(in string) string { ++ var buf bytes.Buffer ++ buf.WriteByte('`') ++ for _, c := range in { ++ buf.WriteRune(c) ++ if c == '`' { ++ buf.WriteByte('`') ++ } ++ } ++ buf.WriteByte('`') ++ return buf.String() ++} ++ + func formatID(buf *TrackedBuffer, original, lowered string) { + isDbSystemVariable := false + if len(original) > 1 && original[:2] == "@@" { +diff -u /Users/bramp/go/src/vitess.io/vitess/go//vt/sqlparser/ast_test.go /Users/bramp/go/src/github.com/xwb1989/sqlparser//ast_test.go +--- /Users/bramp/go/src/vitess.io/vitess/go//vt/sqlparser/ast_test.go 2018-06-05 08:45:47.000000000 -0700 ++++ /Users/bramp/go/src/github.com/xwb1989/sqlparser//ast_test.go 2018-06-05 07:41:09.000000000 -0700 +@@ -24,7 +24,7 @@ + "testing" + "unsafe" + +- "vitess.io/vitess/go/sqltypes" ++ "github.com/xwb1989/sqlparser/dependency/sqltypes" + ) + + func TestAppend(t *testing.T) { +diff -u /Users/bramp/go/src/vitess.io/vitess/go//vt/sqlparser/comments.go /Users/bramp/go/src/github.com/xwb1989/sqlparser//comments.go +--- /Users/bramp/go/src/vitess.io/vitess/go//vt/sqlparser/comments.go 2018-06-05 08:45:47.000000000 -0700 ++++ /Users/bramp/go/src/github.com/xwb1989/sqlparser//comments.go 2018-06-06 07:45:09.000000000 -0700 +@@ -145,7 +145,7 @@ + // Single line comment + index := strings.Index(sql, "\n") + if index == -1 { +- return "" ++ return sql + } + sql = sql[index+1:] + } +diff -u /Users/bramp/go/src/vitess.io/vitess/go//vt/sqlparser/comments_test.go /Users/bramp/go/src/github.com/xwb1989/sqlparser//comments_test.go +--- /Users/bramp/go/src/vitess.io/vitess/go//vt/sqlparser/comments_test.go 2018-06-05 08:45:47.000000000 -0700 ++++ /Users/bramp/go/src/github.com/xwb1989/sqlparser//comments_test.go 2018-06-06 07:45:08.000000000 -0700 +@@ -187,7 +187,7 @@ + outSQL: "bar", + }, { + input: "-- /* foo */ bar", +- outSQL: "", ++ outSQL: "-- /* foo */ bar", + }, { + input: "foo -- bar */", + outSQL: "foo -- bar */", +@@ -201,7 +201,7 @@ + outSQL: "a", + }, { + input: `-- foo bar`, +- outSQL: "", ++ outSQL: "-- foo bar", + }} + for _, testCase := range testCases { + gotSQL := StripLeadingComments(testCase.input) +Only in /Users/bramp/go/src/github.com/xwb1989/sqlparser//: dependency +diff -u /Users/bramp/go/src/vitess.io/vitess/go//vt/sqlparser/encodable.go /Users/bramp/go/src/github.com/xwb1989/sqlparser//encodable.go +--- /Users/bramp/go/src/vitess.io/vitess/go//vt/sqlparser/encodable.go 2018-06-05 08:45:47.000000000 -0700 ++++ /Users/bramp/go/src/github.com/xwb1989/sqlparser//encodable.go 2017-10-18 18:06:33.000000000 -0700 +@@ -19,7 +19,7 @@ + import ( + "bytes" + +- "vitess.io/vitess/go/sqltypes" ++ "github.com/xwb1989/sqlparser/dependency/sqltypes" + ) + + // This file contains types that are 'Encodable'. +diff -u /Users/bramp/go/src/vitess.io/vitess/go//vt/sqlparser/encodable_test.go /Users/bramp/go/src/github.com/xwb1989/sqlparser//encodable_test.go +--- /Users/bramp/go/src/vitess.io/vitess/go//vt/sqlparser/encodable_test.go 2018-06-05 08:45:47.000000000 -0700 ++++ /Users/bramp/go/src/github.com/xwb1989/sqlparser//encodable_test.go 2017-10-18 18:06:33.000000000 -0700 +@@ -20,7 +20,7 @@ + "bytes" + "testing" + +- "vitess.io/vitess/go/sqltypes" ++ "github.com/xwb1989/sqlparser/dependency/sqltypes" + ) + + func TestEncodable(t *testing.T) { +Only in /Users/bramp/go/src/github.com/xwb1989/sqlparser//: github_test.go +diff -u /Users/bramp/go/src/vitess.io/vitess/go//vt/sqlparser/normalizer.go /Users/bramp/go/src/github.com/xwb1989/sqlparser//normalizer.go +--- /Users/bramp/go/src/vitess.io/vitess/go//vt/sqlparser/normalizer.go 2018-06-05 08:45:47.000000000 -0700 ++++ /Users/bramp/go/src/github.com/xwb1989/sqlparser//normalizer.go 2017-10-18 18:06:33.000000000 -0700 +@@ -19,9 +19,9 @@ + import ( + "fmt" + +- "vitess.io/vitess/go/sqltypes" ++ "github.com/xwb1989/sqlparser/dependency/sqltypes" + +- querypb "vitess.io/vitess/go/vt/proto/query" ++ "github.com/xwb1989/sqlparser/dependency/querypb" + ) + + // Normalize changes the statement to use bind values, and +diff -u /Users/bramp/go/src/vitess.io/vitess/go//vt/sqlparser/normalizer_test.go /Users/bramp/go/src/github.com/xwb1989/sqlparser//normalizer_test.go +--- /Users/bramp/go/src/vitess.io/vitess/go//vt/sqlparser/normalizer_test.go 2018-06-05 08:45:47.000000000 -0700 ++++ /Users/bramp/go/src/github.com/xwb1989/sqlparser//normalizer_test.go 2017-11-27 22:10:51.000000000 -0800 +@@ -21,8 +21,8 @@ + "reflect" + "testing" + +- "vitess.io/vitess/go/sqltypes" +- querypb "vitess.io/vitess/go/vt/proto/query" ++ "github.com/xwb1989/sqlparser/dependency/querypb" ++ "github.com/xwb1989/sqlparser/dependency/sqltypes" + ) + + func TestNormalize(t *testing.T) { +diff -u /Users/bramp/go/src/vitess.io/vitess/go//vt/sqlparser/parsed_query.go /Users/bramp/go/src/github.com/xwb1989/sqlparser//parsed_query.go +--- /Users/bramp/go/src/vitess.io/vitess/go//vt/sqlparser/parsed_query.go 2018-06-05 08:45:47.000000000 -0700 ++++ /Users/bramp/go/src/github.com/xwb1989/sqlparser//parsed_query.go 2017-10-22 13:30:37.000000000 -0700 +@@ -18,12 +18,10 @@ + + import ( + "bytes" +- "encoding/json" + "fmt" + +- "vitess.io/vitess/go/sqltypes" +- +- querypb "vitess.io/vitess/go/vt/proto/query" ++ "github.com/xwb1989/sqlparser/dependency/querypb" ++ "github.com/xwb1989/sqlparser/dependency/sqltypes" + ) + + // ParsedQuery represents a parsed query where +@@ -71,12 +69,6 @@ + return buf.Bytes(), nil + } + +-// MarshalJSON is a custom JSON marshaler for ParsedQuery. +-// Note that any queries longer that 512 bytes will be truncated. +-func (pq *ParsedQuery) MarshalJSON() ([]byte, error) { +- return json.Marshal(TruncateForUI(pq.Query)) +-} +- + // EncodeValue encodes one bind variable value into the query. + func EncodeValue(buf *bytes.Buffer, value *querypb.BindVariable) { + if value.Type != querypb.Type_TUPLE { +diff -u /Users/bramp/go/src/vitess.io/vitess/go//vt/sqlparser/parsed_query_test.go /Users/bramp/go/src/github.com/xwb1989/sqlparser//parsed_query_test.go +--- /Users/bramp/go/src/vitess.io/vitess/go//vt/sqlparser/parsed_query_test.go 2018-06-05 08:45:47.000000000 -0700 ++++ /Users/bramp/go/src/github.com/xwb1989/sqlparser//parsed_query_test.go 2017-10-18 18:06:33.000000000 -0700 +@@ -20,9 +20,9 @@ + "reflect" + "testing" + +- "vitess.io/vitess/go/sqltypes" ++ "github.com/xwb1989/sqlparser/dependency/sqltypes" + +- querypb "vitess.io/vitess/go/vt/proto/query" ++ "github.com/xwb1989/sqlparser/dependency/querypb" + ) + + func TestNewParsedQuery(t *testing.T) { +Only in /Users/bramp/go/src/github.com/xwb1989/sqlparser//: patches +Only in /Users/bramp/go/src/github.com/xwb1989/sqlparser//: quick +diff -u /Users/bramp/go/src/vitess.io/vitess/go//vt/sqlparser/redact_query.go /Users/bramp/go/src/github.com/xwb1989/sqlparser//redact_query.go +--- /Users/bramp/go/src/vitess.io/vitess/go//vt/sqlparser/redact_query.go 2018-06-05 08:45:47.000000000 -0700 ++++ /Users/bramp/go/src/github.com/xwb1989/sqlparser//redact_query.go 2018-06-06 07:42:56.000000000 -0700 +@@ -1,6 +1,6 @@ + package sqlparser + +-import querypb "vitess.io/vitess/go/vt/proto/query" ++import querypb "github.com/xwb1989/sqlparser/dependency/querypb" + + // RedactSQLQuery returns a sql string with the params stripped out for display + func RedactSQLQuery(sql string) (string, error) { +Only in /Users/bramp/go/src/github.com/xwb1989/sqlparser//: tests +diff -u /Users/bramp/go/src/vitess.io/vitess/go//vt/sqlparser/token.go /Users/bramp/go/src/github.com/xwb1989/sqlparser//token.go +--- /Users/bramp/go/src/vitess.io/vitess/go//vt/sqlparser/token.go 2018-06-05 08:45:47.000000000 -0700 ++++ /Users/bramp/go/src/github.com/xwb1989/sqlparser//token.go 2018-06-06 07:45:09.000000000 -0700 +@@ -22,8 +22,8 @@ + "fmt" + "io" + +- "vitess.io/vitess/go/bytes2" +- "vitess.io/vitess/go/sqltypes" ++ "github.com/xwb1989/sqlparser/dependency/bytes2" ++ "github.com/xwb1989/sqlparser/dependency/sqltypes" + ) + + const ( +Only in /Users/bramp/go/src/vitess.io/vitess/go//vt/sqlparser/: truncate_query.go +Only in /Users/bramp/go/src/github.com/xwb1989/sqlparser//: y.output diff --git a/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/patches/sqltypes.patch b/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/patches/sqltypes.patch new file mode 100644 index 00000000..215ba9d8 --- /dev/null +++ b/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/patches/sqltypes.patch @@ -0,0 +1,290 @@ +Only in /Users/bramp/go/src/vitess.io/vitess/go//sqltypes/: arithmetic.go +Only in /Users/bramp/go/src/vitess.io/vitess/go//sqltypes/: arithmetic_test.go +diff -u /Users/bramp/go/src/vitess.io/vitess/go//sqltypes/bind_variables.go /Users/bramp/go/src/github.com/xwb1989/sqlparser//dependency/sqltypes/bind_variables.go +--- /Users/bramp/go/src/vitess.io/vitess/go//sqltypes/bind_variables.go 2018-06-05 08:45:47.000000000 -0700 ++++ /Users/bramp/go/src/github.com/xwb1989/sqlparser//dependency/sqltypes/bind_variables.go 2018-06-04 08:05:24.000000000 -0700 +@@ -19,11 +19,10 @@ + import ( + "errors" + "fmt" ++ "reflect" + "strconv" + +- "github.com/golang/protobuf/proto" +- +- querypb "vitess.io/vitess/go/vt/proto/query" ++ "github.com/xwb1989/sqlparser/dependency/querypb" + ) + + // NullBindVariable is a bindvar with NULL value. +@@ -253,9 +252,8 @@ + } + + // BindVariablesEqual compares two maps of bind variables. +-// For protobuf messages we have to use "proto.Equal". + func BindVariablesEqual(x, y map[string]*querypb.BindVariable) bool { +- return proto.Equal(&querypb.BoundQuery{BindVariables: x}, &querypb.BoundQuery{BindVariables: y}) ++ return reflect.DeepEqual(&querypb.BoundQuery{BindVariables: x}, &querypb.BoundQuery{BindVariables: y}) + } + + // CopyBindVariables returns a shallow-copy of the given bindVariables map. +diff -u /Users/bramp/go/src/vitess.io/vitess/go//sqltypes/bind_variables_test.go /Users/bramp/go/src/github.com/xwb1989/sqlparser//dependency/sqltypes/bind_variables_test.go +--- /Users/bramp/go/src/vitess.io/vitess/go//sqltypes/bind_variables_test.go 2018-06-05 08:45:47.000000000 -0700 ++++ /Users/bramp/go/src/github.com/xwb1989/sqlparser//dependency/sqltypes/bind_variables_test.go 2018-06-04 08:05:24.000000000 -0700 +@@ -21,16 +21,14 @@ + "strings" + "testing" + +- "github.com/golang/protobuf/proto" +- +- querypb "vitess.io/vitess/go/vt/proto/query" ++ "github.com/xwb1989/sqlparser/dependency/querypb" + ) + + func TestProtoConversions(t *testing.T) { + v := TestValue(Int64, "1") + got := ValueToProto(v) + want := &querypb.Value{Type: Int64, Value: []byte("1")} +- if !proto.Equal(got, want) { ++ if !reflect.DeepEqual(got, want) { + t.Errorf("ValueToProto: %v, want %v", got, want) + } + gotback := ProtoToValue(got) +@@ -240,7 +238,7 @@ + t.Errorf("ToBindVar(%T(%v)) error: nil, want %s", tcase.in, tcase.in, tcase.err) + continue + } +- if !proto.Equal(bv, tcase.out) { ++ if !reflect.DeepEqual(bv, tcase.out) { + t.Errorf("ToBindVar(%T(%v)): %v, want %s", tcase.in, tcase.in, bv, tcase.out) + } + } +@@ -523,7 +521,7 @@ + v, err = BindVariableToValue(&querypb.BindVariable{Type: querypb.Type_TUPLE}) + wantErr := "cannot convert a TUPLE bind var into a value" + if err == nil || err.Error() != wantErr { +- t.Errorf(" BindVarToValue(TUPLE): (%v, %v), want %s", v, err, wantErr) ++ t.Errorf(" BindVarToValue(TUPLE): %v, want %s", err, wantErr) + } + } + +Only in /Users/bramp/go/src/vitess.io/vitess/go//sqltypes/: event_token.go +Only in /Users/bramp/go/src/vitess.io/vitess/go//sqltypes/: event_token_test.go +diff -u /Users/bramp/go/src/vitess.io/vitess/go//sqltypes/plan_value.go /Users/bramp/go/src/github.com/xwb1989/sqlparser//dependency/sqltypes/plan_value.go +--- /Users/bramp/go/src/vitess.io/vitess/go//sqltypes/plan_value.go 2018-06-05 08:45:47.000000000 -0700 ++++ /Users/bramp/go/src/github.com/xwb1989/sqlparser//dependency/sqltypes/plan_value.go 2018-06-04 08:05:24.000000000 -0700 +@@ -18,10 +18,10 @@ + + import ( + "encoding/json" ++ "errors" ++ "fmt" + +- querypb "vitess.io/vitess/go/vt/proto/query" +- vtrpcpb "vitess.io/vitess/go/vt/proto/vtrpc" +- "vitess.io/vitess/go/vt/vterrors" ++ "github.com/xwb1989/sqlparser/dependency/querypb" + ) + + // PlanValue represents a value or a list of values for +@@ -87,7 +87,7 @@ + case pv.ListKey != "" || pv.Values != nil: + // This code is unreachable because the parser does not allow + // multi-value constructs where a single value is expected. +- return NULL, vterrors.New(vtrpcpb.Code_INVALID_ARGUMENT, "a list was supplied where a single value was expected") ++ return NULL, errors.New("a list was supplied where a single value was expected") + } + return NULL, nil + } +@@ -95,10 +95,10 @@ + func (pv PlanValue) lookupValue(bindVars map[string]*querypb.BindVariable) (*querypb.BindVariable, error) { + bv, ok := bindVars[pv.Key] + if !ok { +- return nil, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "missing bind var %s", pv.Key) ++ return nil, fmt.Errorf("missing bind var %s", pv.Key) + } + if bv.Type == querypb.Type_TUPLE { +- return nil, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "TUPLE was supplied for single value bind var %s", pv.ListKey) ++ return nil, fmt.Errorf("TUPLE was supplied for single value bind var %s", pv.ListKey) + } + return bv, nil + } +@@ -129,16 +129,16 @@ + } + // This code is unreachable because the parser does not allow + // single value constructs where multiple values are expected. +- return nil, vterrors.New(vtrpcpb.Code_INVALID_ARGUMENT, "a single value was supplied where a list was expected") ++ return nil, errors.New("a single value was supplied where a list was expected") + } + + func (pv PlanValue) lookupList(bindVars map[string]*querypb.BindVariable) (*querypb.BindVariable, error) { + bv, ok := bindVars[pv.ListKey] + if !ok { +- return nil, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "missing bind var %s", pv.ListKey) ++ return nil, fmt.Errorf("missing bind var %s", pv.ListKey) + } + if bv.Type != querypb.Type_TUPLE { +- return nil, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "single value was supplied for TUPLE bind var %s", pv.ListKey) ++ return nil, fmt.Errorf("single value was supplied for TUPLE bind var %s", pv.ListKey) + } + return bv, nil + } +@@ -171,7 +171,7 @@ + case l: + return nil + default: +- return vterrors.New(vtrpcpb.Code_INVALID_ARGUMENT, "mismatch in number of column values") ++ return errors.New("mismatch in number of column values") + } + } + +@@ -221,7 +221,7 @@ + rows[i] = make([]Value, len(pvs)) + } + +- // Using j because we're resolving by columns. ++ // Using j becasue we're resolving by columns. + for j, pv := range pvs { + switch { + case pv.Key != "": +diff -u /Users/bramp/go/src/vitess.io/vitess/go//sqltypes/plan_value_test.go /Users/bramp/go/src/github.com/xwb1989/sqlparser//dependency/sqltypes/plan_value_test.go +--- /Users/bramp/go/src/vitess.io/vitess/go//sqltypes/plan_value_test.go 2018-06-05 08:45:47.000000000 -0700 ++++ /Users/bramp/go/src/github.com/xwb1989/sqlparser//dependency/sqltypes/plan_value_test.go 2018-06-04 08:05:24.000000000 -0700 +@@ -21,7 +21,7 @@ + "strings" + "testing" + +- querypb "vitess.io/vitess/go/vt/proto/query" ++ "github.com/xwb1989/sqlparser/dependency/querypb" + ) + + func TestPlanValueIsNull(t *testing.T) { +Only in /Users/bramp/go/src/vitess.io/vitess/go//sqltypes/: proto3.go +Only in /Users/bramp/go/src/vitess.io/vitess/go//sqltypes/: proto3_test.go +Only in /Users/bramp/go/src/vitess.io/vitess/go//sqltypes/: query_response.go +Only in /Users/bramp/go/src/vitess.io/vitess/go//sqltypes/: result.go +Only in /Users/bramp/go/src/vitess.io/vitess/go//sqltypes/: result_test.go +diff -u /Users/bramp/go/src/vitess.io/vitess/go//sqltypes/testing.go /Users/bramp/go/src/github.com/xwb1989/sqlparser//dependency/sqltypes/testing.go +--- /Users/bramp/go/src/vitess.io/vitess/go//sqltypes/testing.go 2018-06-05 08:45:47.000000000 -0700 ++++ /Users/bramp/go/src/github.com/xwb1989/sqlparser//dependency/sqltypes/testing.go 2018-06-04 08:06:27.000000000 -0700 +@@ -17,17 +17,14 @@ + package sqltypes + + import ( +- "bytes" +- "fmt" +- "strings" +- +- querypb "vitess.io/vitess/go/vt/proto/query" ++ querypb "github.com/xwb1989/sqlparser/dependency/querypb" + ) + + // Functions in this file should only be used for testing. + // This is an experiment to see if test code bloat can be + // reduced and readability improved. + ++/* + // MakeTestFields builds a []*querypb.Field for testing. + // fields := sqltypes.MakeTestFields( + // "a|b", +@@ -110,6 +107,7 @@ + } + return results + } ++*/ + + // TestBindVariable makes a *querypb.BindVariable from + // an interface{}.It panics on invalid input. +@@ -131,6 +129,7 @@ + return MakeTrusted(typ, []byte(val)) + } + ++/* + // PrintResults prints []*Results into a string. + // This function should only be used for testing. + func PrintResults(results []*Result) string { +@@ -152,3 +151,4 @@ + } + return splits + } ++*/ +diff -u /Users/bramp/go/src/vitess.io/vitess/go//sqltypes/type.go /Users/bramp/go/src/github.com/xwb1989/sqlparser//dependency/sqltypes/type.go +--- /Users/bramp/go/src/vitess.io/vitess/go//sqltypes/type.go 2018-06-05 08:45:47.000000000 -0700 ++++ /Users/bramp/go/src/github.com/xwb1989/sqlparser//dependency/sqltypes/type.go 2018-06-04 08:05:24.000000000 -0700 +@@ -19,7 +19,7 @@ + import ( + "fmt" + +- querypb "vitess.io/vitess/go/vt/proto/query" ++ "github.com/xwb1989/sqlparser/dependency/querypb" + ) + + // This file provides wrappers and support +diff -u /Users/bramp/go/src/vitess.io/vitess/go//sqltypes/type_test.go /Users/bramp/go/src/github.com/xwb1989/sqlparser//dependency/sqltypes/type_test.go +--- /Users/bramp/go/src/vitess.io/vitess/go//sqltypes/type_test.go 2018-06-05 08:45:47.000000000 -0700 ++++ /Users/bramp/go/src/github.com/xwb1989/sqlparser//dependency/sqltypes/type_test.go 2018-06-04 08:05:24.000000000 -0700 +@@ -19,7 +19,7 @@ + import ( + "testing" + +- querypb "vitess.io/vitess/go/vt/proto/query" ++ "github.com/xwb1989/sqlparser/dependency/querypb" + ) + + func TestTypeValues(t *testing.T) { +diff -u /Users/bramp/go/src/vitess.io/vitess/go//sqltypes/value.go /Users/bramp/go/src/github.com/xwb1989/sqlparser//dependency/sqltypes/value.go +--- /Users/bramp/go/src/vitess.io/vitess/go//sqltypes/value.go 2018-06-05 08:45:47.000000000 -0700 ++++ /Users/bramp/go/src/github.com/xwb1989/sqlparser//dependency/sqltypes/value.go 2018-06-04 08:05:24.000000000 -0700 +@@ -23,10 +23,10 @@ + "fmt" + "strconv" + +- "vitess.io/vitess/go/bytes2" +- "vitess.io/vitess/go/hack" ++ "github.com/xwb1989/sqlparser/dependency/bytes2" ++ "github.com/xwb1989/sqlparser/dependency/hack" + +- querypb "vitess.io/vitess/go/vt/proto/query" ++ "github.com/xwb1989/sqlparser/dependency/querypb" + ) + + var ( +@@ -48,7 +48,7 @@ + } + + // Value can store any SQL value. If the value represents +-// an integral type, the bytes are always stored as a canonical ++// an integral type, the bytes are always stored as a cannonical + // representation that matches how MySQL returns such values. + type Value struct { + typ querypb.Type +@@ -126,7 +126,7 @@ + return MakeTrusted(VarBinary, []byte(v)) + } + +-// NewIntegral builds an integral type from a string representation. ++// NewIntegral builds an integral type from a string representaion. + // The type will be Int64 or Uint64. Int64 will be preferred where possible. + func NewIntegral(val string) (n Value, err error) { + signed, err := strconv.ParseInt(val, 0, 64) +@@ -169,7 +169,7 @@ + return v.typ + } + +-// Raw returns the internal representation of the value. For newer types, ++// Raw returns the internal represenation of the value. For newer types, + // this may not match MySQL's representation. + func (v Value) Raw() []byte { + return v.val +diff -u /Users/bramp/go/src/vitess.io/vitess/go//sqltypes/value_test.go /Users/bramp/go/src/github.com/xwb1989/sqlparser//dependency/sqltypes/value_test.go +--- /Users/bramp/go/src/vitess.io/vitess/go//sqltypes/value_test.go 2018-06-05 08:45:47.000000000 -0700 ++++ /Users/bramp/go/src/github.com/xwb1989/sqlparser//dependency/sqltypes/value_test.go 2018-06-04 08:05:24.000000000 -0700 +@@ -22,7 +22,7 @@ + "strings" + "testing" + +- querypb "vitess.io/vitess/go/vt/proto/query" ++ "github.com/xwb1989/sqlparser/dependency/querypb" + ) + + const ( diff --git a/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/precedence_test.go b/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/precedence_test.go new file mode 100644 index 00000000..f6a1c93f --- /dev/null +++ b/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/precedence_test.go @@ -0,0 +1,112 @@ +/* +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 sqlparser + +import ( + "fmt" + "testing" +) + +func readable(node Expr) string { + switch node := node.(type) { + case *OrExpr: + return fmt.Sprintf("(%s or %s)", readable(node.Left), readable(node.Right)) + case *AndExpr: + return fmt.Sprintf("(%s and %s)", readable(node.Left), readable(node.Right)) + case *BinaryExpr: + return fmt.Sprintf("(%s %s %s)", readable(node.Left), node.Operator, readable(node.Right)) + case *IsExpr: + return fmt.Sprintf("(%s %s)", readable(node.Expr), node.Operator) + default: + return String(node) + } +} + +func TestAndOrPrecedence(t *testing.T) { + validSQL := []struct { + input string + output string + }{{ + input: "select * from a where a=b and c=d or e=f", + output: "((a = b and c = d) or e = f)", + }, { + input: "select * from a where a=b or c=d and e=f", + output: "(a = b or (c = d and e = f))", + }} + for _, tcase := range validSQL { + tree, err := Parse(tcase.input) + if err != nil { + t.Error(err) + continue + } + expr := readable(tree.(*Select).Where.Expr) + if expr != tcase.output { + t.Errorf("Parse: \n%s, want: \n%s", expr, tcase.output) + } + } +} + +func TestPlusStarPrecedence(t *testing.T) { + validSQL := []struct { + input string + output string + }{{ + input: "select 1+2*3 from a", + output: "(1 + (2 * 3))", + }, { + input: "select 1*2+3 from a", + output: "((1 * 2) + 3)", + }} + for _, tcase := range validSQL { + tree, err := Parse(tcase.input) + if err != nil { + t.Error(err) + continue + } + expr := readable(tree.(*Select).SelectExprs[0].(*AliasedExpr).Expr) + if expr != tcase.output { + t.Errorf("Parse: \n%s, want: \n%s", expr, tcase.output) + } + } +} + +func TestIsPrecedence(t *testing.T) { + validSQL := []struct { + input string + output string + }{{ + input: "select * from a where a+b is true", + output: "((a + b) is true)", + }, { + input: "select * from a where a=1 and b=2 is true", + output: "(a = 1 and (b = 2 is true))", + }, { + input: "select * from a where (a=1 and b=2) is true", + output: "((a = 1 and b = 2) is true)", + }} + for _, tcase := range validSQL { + tree, err := Parse(tcase.input) + if err != nil { + t.Error(err) + continue + } + expr := readable(tree.(*Select).Where.Expr) + if expr != tcase.output { + t.Errorf("Parse: \n%s, want: \n%s", expr, tcase.output) + } + } +} diff --git a/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/redact_query.go b/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/redact_query.go new file mode 100644 index 00000000..a50b9bcd --- /dev/null +++ b/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/redact_query.go @@ -0,0 +1,19 @@ +package sqlparser + +import querypb "github.com/xwb1989/sqlparser/dependency/querypb" + +// RedactSQLQuery returns a sql string with the params stripped out for display +func RedactSQLQuery(sql string) (string, error) { + bv := map[string]*querypb.BindVariable{} + sqlStripped, comments := SplitMarginComments(sql) + + stmt, err := Parse(sqlStripped) + if err != nil { + return "", err + } + + prefix := "redacted" + Normalize(stmt, bv, prefix) + + return comments.Leading + String(stmt) + comments.Trailing, nil +} diff --git a/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/redact_query_test.go b/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/redact_query_test.go new file mode 100644 index 00000000..553e6ee0 --- /dev/null +++ b/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/redact_query_test.go @@ -0,0 +1,17 @@ +package sqlparser + +import ( + "testing" +) + +func TestRedactSQLStatements(t *testing.T) { + sql := "select a,b,c from t where x = 1234 and y = 1234 and z = 'apple'" + redactedSQL, err := RedactSQLQuery(sql) + if err != nil { + t.Fatalf("redacting sql failed: %v", err) + } + + if redactedSQL != "select a, b, c from t where x = :redacted1 and y = :redacted1 and z = :redacted2" { + t.Fatalf("Unknown sql redaction: %v", redactedSQL) + } +} diff --git a/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/sql.go b/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/sql.go new file mode 100644 index 00000000..4c8f2657 --- /dev/null +++ b/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/sql.go @@ -0,0 +1,6136 @@ +//line sql.y:18 +package sqlparser + +import __yyfmt__ "fmt" + +//line sql.y:18 +func setParseTree(yylex interface{}, stmt Statement) { + yylex.(*Tokenizer).ParseTree = stmt +} + +func setAllowComments(yylex interface{}, allow bool) { + yylex.(*Tokenizer).AllowComments = allow +} + +func setDDL(yylex interface{}, ddl *DDL) { + yylex.(*Tokenizer).partialDDL = ddl +} + +func incNesting(yylex interface{}) bool { + yylex.(*Tokenizer).nesting++ + if yylex.(*Tokenizer).nesting == 200 { + return true + } + return false +} + +func decNesting(yylex interface{}) { + yylex.(*Tokenizer).nesting-- +} + +// forceEOF forces the lexer to end prematurely. Not all SQL statements +// are supported by the Parser, thus calling forceEOF will make the lexer +// return EOF early. +func forceEOF(yylex interface{}) { + yylex.(*Tokenizer).ForceEOF = true +} + +//line sql.y:53 +type yySymType struct { + yys int + empty struct{} + statement Statement + selStmt SelectStatement + ddl *DDL + ins *Insert + byt byte + bytes []byte + bytes2 [][]byte + str string + strs []string + selectExprs SelectExprs + selectExpr SelectExpr + columns Columns + partitions Partitions + colName *ColName + tableExprs TableExprs + tableExpr TableExpr + joinCondition JoinCondition + tableName TableName + tableNames TableNames + indexHints *IndexHints + expr Expr + exprs Exprs + boolVal BoolVal + colTuple ColTuple + values Values + valTuple ValTuple + subquery *Subquery + whens []*When + when *When + orderBy OrderBy + order *Order + limit *Limit + updateExprs UpdateExprs + setExprs SetExprs + updateExpr *UpdateExpr + setExpr *SetExpr + colIdent ColIdent + tableIdent TableIdent + convertType *ConvertType + aliasedTableName *AliasedTableExpr + TableSpec *TableSpec + columnType ColumnType + colKeyOpt ColumnKeyOption + optVal *SQLVal + LengthScaleOption LengthScaleOption + columnDefinition *ColumnDefinition + indexDefinition *IndexDefinition + indexInfo *IndexInfo + indexOption *IndexOption + indexOptions []*IndexOption + indexColumn *IndexColumn + indexColumns []*IndexColumn + partDefs []*PartitionDefinition + partDef *PartitionDefinition + partSpec *PartitionSpec + vindexParam VindexParam + vindexParams []VindexParam + showFilter *ShowFilter +} + +const LEX_ERROR = 57346 +const UNION = 57347 +const SELECT = 57348 +const STREAM = 57349 +const INSERT = 57350 +const UPDATE = 57351 +const DELETE = 57352 +const FROM = 57353 +const WHERE = 57354 +const GROUP = 57355 +const HAVING = 57356 +const ORDER = 57357 +const BY = 57358 +const LIMIT = 57359 +const OFFSET = 57360 +const FOR = 57361 +const ALL = 57362 +const DISTINCT = 57363 +const AS = 57364 +const EXISTS = 57365 +const ASC = 57366 +const DESC = 57367 +const INTO = 57368 +const DUPLICATE = 57369 +const KEY = 57370 +const DEFAULT = 57371 +const SET = 57372 +const LOCK = 57373 +const KEYS = 57374 +const VALUES = 57375 +const LAST_INSERT_ID = 57376 +const NEXT = 57377 +const VALUE = 57378 +const SHARE = 57379 +const MODE = 57380 +const SQL_NO_CACHE = 57381 +const SQL_CACHE = 57382 +const JOIN = 57383 +const STRAIGHT_JOIN = 57384 +const LEFT = 57385 +const RIGHT = 57386 +const INNER = 57387 +const OUTER = 57388 +const CROSS = 57389 +const NATURAL = 57390 +const USE = 57391 +const FORCE = 57392 +const ON = 57393 +const USING = 57394 +const ID = 57395 +const HEX = 57396 +const STRING = 57397 +const INTEGRAL = 57398 +const FLOAT = 57399 +const HEXNUM = 57400 +const VALUE_ARG = 57401 +const LIST_ARG = 57402 +const COMMENT = 57403 +const COMMENT_KEYWORD = 57404 +const BIT_LITERAL = 57405 +const NULL = 57406 +const TRUE = 57407 +const FALSE = 57408 +const OR = 57409 +const AND = 57410 +const NOT = 57411 +const BETWEEN = 57412 +const CASE = 57413 +const WHEN = 57414 +const THEN = 57415 +const ELSE = 57416 +const END = 57417 +const LE = 57418 +const GE = 57419 +const NE = 57420 +const NULL_SAFE_EQUAL = 57421 +const IS = 57422 +const LIKE = 57423 +const REGEXP = 57424 +const IN = 57425 +const SHIFT_LEFT = 57426 +const SHIFT_RIGHT = 57427 +const DIV = 57428 +const MOD = 57429 +const UNARY = 57430 +const COLLATE = 57431 +const BINARY = 57432 +const UNDERSCORE_BINARY = 57433 +const INTERVAL = 57434 +const JSON_EXTRACT_OP = 57435 +const JSON_UNQUOTE_EXTRACT_OP = 57436 +const CREATE = 57437 +const ALTER = 57438 +const DROP = 57439 +const RENAME = 57440 +const ANALYZE = 57441 +const ADD = 57442 +const SCHEMA = 57443 +const TABLE = 57444 +const INDEX = 57445 +const VIEW = 57446 +const TO = 57447 +const IGNORE = 57448 +const IF = 57449 +const UNIQUE = 57450 +const PRIMARY = 57451 +const COLUMN = 57452 +const CONSTRAINT = 57453 +const SPATIAL = 57454 +const FULLTEXT = 57455 +const FOREIGN = 57456 +const KEY_BLOCK_SIZE = 57457 +const SHOW = 57458 +const DESCRIBE = 57459 +const EXPLAIN = 57460 +const DATE = 57461 +const ESCAPE = 57462 +const REPAIR = 57463 +const OPTIMIZE = 57464 +const TRUNCATE = 57465 +const MAXVALUE = 57466 +const PARTITION = 57467 +const REORGANIZE = 57468 +const LESS = 57469 +const THAN = 57470 +const PROCEDURE = 57471 +const TRIGGER = 57472 +const VINDEX = 57473 +const VINDEXES = 57474 +const STATUS = 57475 +const VARIABLES = 57476 +const BEGIN = 57477 +const START = 57478 +const TRANSACTION = 57479 +const COMMIT = 57480 +const ROLLBACK = 57481 +const BIT = 57482 +const TINYINT = 57483 +const SMALLINT = 57484 +const MEDIUMINT = 57485 +const INT = 57486 +const INTEGER = 57487 +const BIGINT = 57488 +const INTNUM = 57489 +const REAL = 57490 +const DOUBLE = 57491 +const FLOAT_TYPE = 57492 +const DECIMAL = 57493 +const NUMERIC = 57494 +const TIME = 57495 +const TIMESTAMP = 57496 +const DATETIME = 57497 +const YEAR = 57498 +const CHAR = 57499 +const VARCHAR = 57500 +const BOOL = 57501 +const CHARACTER = 57502 +const VARBINARY = 57503 +const NCHAR = 57504 +const TEXT = 57505 +const TINYTEXT = 57506 +const MEDIUMTEXT = 57507 +const LONGTEXT = 57508 +const BLOB = 57509 +const TINYBLOB = 57510 +const MEDIUMBLOB = 57511 +const LONGBLOB = 57512 +const JSON = 57513 +const ENUM = 57514 +const GEOMETRY = 57515 +const POINT = 57516 +const LINESTRING = 57517 +const POLYGON = 57518 +const GEOMETRYCOLLECTION = 57519 +const MULTIPOINT = 57520 +const MULTILINESTRING = 57521 +const MULTIPOLYGON = 57522 +const NULLX = 57523 +const AUTO_INCREMENT = 57524 +const APPROXNUM = 57525 +const SIGNED = 57526 +const UNSIGNED = 57527 +const ZEROFILL = 57528 +const DATABASES = 57529 +const TABLES = 57530 +const VITESS_KEYSPACES = 57531 +const VITESS_SHARDS = 57532 +const VITESS_TABLETS = 57533 +const VSCHEMA_TABLES = 57534 +const EXTENDED = 57535 +const FULL = 57536 +const PROCESSLIST = 57537 +const NAMES = 57538 +const CHARSET = 57539 +const GLOBAL = 57540 +const SESSION = 57541 +const ISOLATION = 57542 +const LEVEL = 57543 +const READ = 57544 +const WRITE = 57545 +const ONLY = 57546 +const REPEATABLE = 57547 +const COMMITTED = 57548 +const UNCOMMITTED = 57549 +const SERIALIZABLE = 57550 +const CURRENT_TIMESTAMP = 57551 +const DATABASE = 57552 +const CURRENT_DATE = 57553 +const CURRENT_TIME = 57554 +const LOCALTIME = 57555 +const LOCALTIMESTAMP = 57556 +const UTC_DATE = 57557 +const UTC_TIME = 57558 +const UTC_TIMESTAMP = 57559 +const REPLACE = 57560 +const CONVERT = 57561 +const CAST = 57562 +const SUBSTR = 57563 +const SUBSTRING = 57564 +const GROUP_CONCAT = 57565 +const SEPARATOR = 57566 +const MATCH = 57567 +const AGAINST = 57568 +const BOOLEAN = 57569 +const LANGUAGE = 57570 +const WITH = 57571 +const QUERY = 57572 +const EXPANSION = 57573 +const UNUSED = 57574 + +var yyToknames = [...]string{ + "$end", + "error", + "$unk", + "LEX_ERROR", + "UNION", + "SELECT", + "STREAM", + "INSERT", + "UPDATE", + "DELETE", + "FROM", + "WHERE", + "GROUP", + "HAVING", + "ORDER", + "BY", + "LIMIT", + "OFFSET", + "FOR", + "ALL", + "DISTINCT", + "AS", + "EXISTS", + "ASC", + "DESC", + "INTO", + "DUPLICATE", + "KEY", + "DEFAULT", + "SET", + "LOCK", + "KEYS", + "VALUES", + "LAST_INSERT_ID", + "NEXT", + "VALUE", + "SHARE", + "MODE", + "SQL_NO_CACHE", + "SQL_CACHE", + "JOIN", + "STRAIGHT_JOIN", + "LEFT", + "RIGHT", + "INNER", + "OUTER", + "CROSS", + "NATURAL", + "USE", + "FORCE", + "ON", + "USING", + "'('", + "','", + "')'", + "ID", + "HEX", + "STRING", + "INTEGRAL", + "FLOAT", + "HEXNUM", + "VALUE_ARG", + "LIST_ARG", + "COMMENT", + "COMMENT_KEYWORD", + "BIT_LITERAL", + "NULL", + "TRUE", + "FALSE", + "OR", + "AND", + "NOT", + "'!'", + "BETWEEN", + "CASE", + "WHEN", + "THEN", + "ELSE", + "END", + "'='", + "'<'", + "'>'", + "LE", + "GE", + "NE", + "NULL_SAFE_EQUAL", + "IS", + "LIKE", + "REGEXP", + "IN", + "'|'", + "'&'", + "SHIFT_LEFT", + "SHIFT_RIGHT", + "'+'", + "'-'", + "'*'", + "'/'", + "DIV", + "'%'", + "MOD", + "'^'", + "'~'", + "UNARY", + "COLLATE", + "BINARY", + "UNDERSCORE_BINARY", + "INTERVAL", + "'.'", + "JSON_EXTRACT_OP", + "JSON_UNQUOTE_EXTRACT_OP", + "CREATE", + "ALTER", + "DROP", + "RENAME", + "ANALYZE", + "ADD", + "SCHEMA", + "TABLE", + "INDEX", + "VIEW", + "TO", + "IGNORE", + "IF", + "UNIQUE", + "PRIMARY", + "COLUMN", + "CONSTRAINT", + "SPATIAL", + "FULLTEXT", + "FOREIGN", + "KEY_BLOCK_SIZE", + "SHOW", + "DESCRIBE", + "EXPLAIN", + "DATE", + "ESCAPE", + "REPAIR", + "OPTIMIZE", + "TRUNCATE", + "MAXVALUE", + "PARTITION", + "REORGANIZE", + "LESS", + "THAN", + "PROCEDURE", + "TRIGGER", + "VINDEX", + "VINDEXES", + "STATUS", + "VARIABLES", + "BEGIN", + "START", + "TRANSACTION", + "COMMIT", + "ROLLBACK", + "BIT", + "TINYINT", + "SMALLINT", + "MEDIUMINT", + "INT", + "INTEGER", + "BIGINT", + "INTNUM", + "REAL", + "DOUBLE", + "FLOAT_TYPE", + "DECIMAL", + "NUMERIC", + "TIME", + "TIMESTAMP", + "DATETIME", + "YEAR", + "CHAR", + "VARCHAR", + "BOOL", + "CHARACTER", + "VARBINARY", + "NCHAR", + "TEXT", + "TINYTEXT", + "MEDIUMTEXT", + "LONGTEXT", + "BLOB", + "TINYBLOB", + "MEDIUMBLOB", + "LONGBLOB", + "JSON", + "ENUM", + "GEOMETRY", + "POINT", + "LINESTRING", + "POLYGON", + "GEOMETRYCOLLECTION", + "MULTIPOINT", + "MULTILINESTRING", + "MULTIPOLYGON", + "NULLX", + "AUTO_INCREMENT", + "APPROXNUM", + "SIGNED", + "UNSIGNED", + "ZEROFILL", + "DATABASES", + "TABLES", + "VITESS_KEYSPACES", + "VITESS_SHARDS", + "VITESS_TABLETS", + "VSCHEMA_TABLES", + "EXTENDED", + "FULL", + "PROCESSLIST", + "NAMES", + "CHARSET", + "GLOBAL", + "SESSION", + "ISOLATION", + "LEVEL", + "READ", + "WRITE", + "ONLY", + "REPEATABLE", + "COMMITTED", + "UNCOMMITTED", + "SERIALIZABLE", + "CURRENT_TIMESTAMP", + "DATABASE", + "CURRENT_DATE", + "CURRENT_TIME", + "LOCALTIME", + "LOCALTIMESTAMP", + "UTC_DATE", + "UTC_TIME", + "UTC_TIMESTAMP", + "REPLACE", + "CONVERT", + "CAST", + "SUBSTR", + "SUBSTRING", + "GROUP_CONCAT", + "SEPARATOR", + "MATCH", + "AGAINST", + "BOOLEAN", + "LANGUAGE", + "WITH", + "QUERY", + "EXPANSION", + "UNUSED", + "';'", +} +var yyStatenames = [...]string{} + +const yyEofCode = 1 +const yyErrCode = 2 +const yyInitialStackSize = 16 + +//line yacctab:1 +var yyExca = [...]int{ + -1, 1, + 1, -1, + -2, 0, + -1, 3, + 5, 27, + -2, 4, + -1, 36, + 150, 263, + 151, 263, + -2, 253, + -1, 238, + 109, 587, + -2, 583, + -1, 239, + 109, 588, + -2, 584, + -1, 308, + 80, 746, + -2, 58, + -1, 309, + 80, 707, + -2, 59, + -1, 314, + 80, 691, + -2, 549, + -1, 316, + 80, 728, + -2, 551, + -1, 575, + 52, 41, + 54, 41, + -2, 43, + -1, 708, + 109, 590, + -2, 586, + -1, 912, + 5, 28, + -2, 395, + -1, 937, + 5, 27, + -2, 524, + -1, 1161, + 5, 28, + -2, 525, + -1, 1205, + 5, 27, + -2, 527, + -1, 1267, + 5, 28, + -2, 528, +} + +const yyPrivate = 57344 + +const yyLast = 10949 + +var yyAct = [...]int{ + + 269, 47, 770, 854, 1258, 522, 646, 1069, 1216, 1097, + 810, 1070, 268, 521, 3, 243, 1167, 834, 998, 788, + 806, 217, 569, 1066, 809, 53, 848, 771, 956, 1043, + 743, 567, 313, 904, 989, 945, 211, 410, 585, 710, + 455, 940, 733, 1001, 820, 740, 461, 584, 47, 844, + 307, 556, 571, 767, 294, 759, 222, 467, 475, 886, + 241, 216, 299, 226, 52, 304, 1287, 1277, 1285, 1265, + 302, 1283, 855, 442, 1276, 1061, 1155, 414, 435, 1225, + 212, 213, 214, 215, 295, 871, 1103, 1104, 1105, 1091, + 230, 1092, 1093, 293, 1108, 1106, 586, 1264, 587, 870, + 181, 177, 178, 179, 57, 536, 1240, 488, 487, 497, + 498, 490, 491, 492, 493, 494, 495, 496, 489, 964, + 801, 499, 963, 802, 803, 965, 875, 245, 450, 59, + 60, 61, 62, 63, 980, 869, 827, 310, 675, 1179, + 423, 437, 1194, 439, 835, 676, 1144, 1142, 210, 1284, + 232, 446, 447, 1282, 1259, 1022, 768, 424, 417, 1217, + 1044, 1223, 174, 175, 175, 822, 654, 239, 436, 438, + 420, 645, 1219, 822, 789, 791, 955, 954, 953, 412, + 189, 176, 1245, 866, 863, 864, 1164, 862, 1030, 298, + 1046, 511, 512, 974, 441, 441, 441, 441, 76, 441, + 920, 1019, 186, 898, 682, 186, 441, 1021, 479, 180, + 430, 1112, 873, 876, 489, 807, 822, 499, 499, 881, + 679, 1026, 1048, 47, 1052, 742, 1047, 472, 1045, 186, + 186, 76, 1009, 1050, 474, 186, 464, 76, 508, 1218, + 1250, 510, 1049, 474, 411, 1122, 463, 868, 790, 434, + 473, 472, 943, 588, 1107, 1051, 1053, 821, 1224, 1222, + 1007, 1113, 1241, 835, 828, 821, 1063, 474, 520, 867, + 524, 525, 526, 527, 528, 529, 530, 531, 532, 760, + 535, 537, 537, 537, 537, 537, 537, 537, 537, 545, + 546, 547, 548, 1263, 760, 649, 927, 1025, 882, 1020, + 568, 1018, 685, 686, 1253, 978, 872, 469, 821, 416, + 1009, 717, 236, 819, 817, 1269, 1185, 818, 1184, 874, + 426, 427, 428, 453, 1008, 715, 716, 714, 465, 1013, + 1010, 1003, 1004, 1011, 1006, 1005, 993, 50, 1007, 992, + 824, 916, 186, 915, 186, 825, 1012, 713, 473, 472, + 186, 981, 1015, 700, 702, 703, 917, 186, 701, 473, + 472, 76, 76, 76, 76, 474, 76, 173, 509, 458, + 462, 582, 576, 76, 1270, 1251, 474, 473, 472, 310, + 1201, 418, 419, 734, 1065, 735, 480, 538, 539, 540, + 541, 542, 543, 544, 474, 895, 896, 897, 1182, 1130, + 76, 990, 1008, 1248, 473, 472, 1100, 1013, 1010, 1003, + 1004, 1011, 1006, 1005, 441, 1273, 454, 1209, 1256, 454, + 523, 474, 441, 1099, 1012, 1209, 454, 298, 292, 534, + 1002, 1209, 1210, 441, 441, 441, 441, 441, 441, 441, + 441, 1176, 1175, 1088, 454, 1163, 454, 441, 441, 487, + 497, 498, 490, 491, 492, 493, 494, 495, 496, 489, + 186, 1229, 499, 663, 1119, 1118, 267, 186, 186, 186, + 1115, 1116, 1228, 76, 1115, 1114, 1151, 454, 1109, 76, + 910, 454, 50, 975, 966, 687, 857, 553, 454, 941, + 661, 745, 454, 21, 736, 711, 660, 74, 497, 498, + 490, 491, 492, 493, 494, 495, 496, 489, 659, 650, + 499, 47, 708, 488, 487, 497, 498, 490, 491, 492, + 493, 494, 495, 496, 489, 524, 648, 499, 643, 689, + 312, 595, 594, 942, 432, 704, 415, 425, 747, 706, + 411, 1067, 579, 681, 941, 752, 755, 54, 745, 221, + 23, 761, 1159, 707, 299, 299, 299, 299, 299, 513, + 514, 515, 516, 517, 518, 519, 23, 553, 772, 568, + 1121, 792, 737, 738, 935, 553, 942, 936, 299, 680, + 1117, 76, 747, 580, 967, 578, 910, 186, 186, 76, + 757, 186, 764, 1204, 186, 473, 472, 50, 186, 23, + 76, 76, 76, 76, 76, 76, 76, 76, 773, 796, + 712, 776, 474, 50, 76, 76, 785, 552, 941, 186, + 795, 1033, 578, 697, 698, 793, 836, 837, 838, 794, + 922, 799, 798, 814, 76, 800, 910, 919, 186, 774, + 775, 553, 777, 581, 76, 683, 50, 1189, 829, 441, + 849, 441, 1082, 223, 970, 310, 946, 947, 647, 441, + 312, 312, 312, 312, 910, 312, 845, 840, 811, 850, + 839, 65, 312, 921, 852, 523, 1102, 952, 750, 751, + 918, 298, 298, 298, 298, 298, 1067, 76, 994, 846, + 847, 558, 561, 562, 563, 559, 298, 560, 564, 477, + 50, 946, 947, 949, 657, 298, 451, 695, 899, 492, + 493, 494, 495, 496, 489, 708, 951, 499, 186, 779, + 778, 186, 186, 186, 186, 186, 782, 711, 888, 780, + 887, 783, 883, 186, 781, 784, 186, 562, 563, 805, + 186, 227, 228, 1281, 1275, 186, 186, 1029, 1280, 76, + 468, 748, 749, 893, 900, 892, 707, 756, 456, 1157, + 985, 593, 76, 433, 466, 977, 1255, 1190, 938, 939, + 457, 763, 312, 765, 766, 1254, 1202, 971, 590, 859, + 656, 937, 258, 257, 260, 261, 262, 263, 688, 566, + 468, 259, 264, 218, 709, 1234, 299, 718, 719, 720, + 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, + 731, 732, 950, 186, 926, 219, 76, 54, 76, 1233, + 968, 891, 186, 224, 225, 186, 76, 959, 1192, 890, + 942, 884, 885, 470, 462, 1242, 958, 1180, 960, 961, + 678, 56, 712, 58, 577, 744, 746, 51, 982, 983, + 1, 856, 997, 865, 441, 984, 1257, 986, 987, 988, + 1215, 762, 1096, 972, 973, 816, 808, 409, 830, 831, + 832, 833, 64, 1249, 815, 991, 1221, 1178, 823, 441, + 312, 979, 826, 811, 841, 842, 843, 1101, 312, 1252, + 976, 787, 600, 598, 599, 597, 911, 602, 1000, 312, + 312, 312, 312, 312, 312, 312, 312, 1014, 601, 596, + 197, 928, 305, 312, 312, 558, 561, 562, 563, 559, + 894, 560, 564, 298, 565, 589, 851, 471, 66, 999, + 1017, 1016, 861, 691, 1024, 1037, 674, 1072, 1068, 47, + 880, 1042, 449, 477, 199, 1036, 312, 1055, 507, 1071, + 1062, 772, 1073, 708, 1084, 1085, 1086, 772, 889, 1054, + 76, 962, 311, 186, 1074, 684, 1077, 909, 1076, 1078, + 460, 1232, 1035, 1191, 925, 533, 758, 76, 244, 699, + 1095, 256, 253, 924, 1089, 255, 739, 254, 690, 934, + 481, 242, 1094, 234, 1058, 297, 753, 753, 549, 557, + 555, 1090, 753, 1110, 1111, 490, 491, 492, 493, 494, + 495, 496, 489, 554, 948, 499, 944, 296, 1032, 753, + 76, 76, 1154, 76, 1239, 694, 25, 55, 901, 902, + 903, 229, 19, 18, 299, 17, 20, 16, 1123, 15, + 14, 811, 29, 811, 13, 12, 76, 11, 312, 186, + 186, 1125, 10, 9, 1128, 8, 7, 186, 6, 5, + 907, 312, 1153, 4, 908, 1133, 76, 220, 22, 2, + 0, 912, 913, 914, 1132, 1140, 0, 0, 1064, 0, + 923, 0, 0, 0, 0, 929, 0, 930, 931, 932, + 933, 0, 1158, 1079, 1080, 0, 0, 1081, 0, 1166, + 1083, 1169, 1170, 1171, 1035, 968, 76, 76, 0, 0, + 1172, 1174, 0, 0, 0, 312, 0, 312, 0, 0, + 0, 441, 0, 0, 0, 312, 0, 0, 0, 0, + 0, 0, 1181, 1188, 1183, 76, 0, 76, 76, 0, + 1187, 0, 0, 0, 0, 0, 0, 0, 0, 312, + 0, 0, 0, 0, 0, 0, 1193, 0, 0, 0, + 1072, 298, 186, 1206, 0, 0, 0, 0, 811, 0, + 76, 1203, 1071, 0, 0, 0, 1205, 1131, 0, 0, + 0, 0, 0, 76, 186, 0, 1220, 0, 0, 0, + 76, 1231, 1214, 0, 0, 999, 811, 0, 76, 0, + 0, 186, 1226, 0, 1227, 1072, 1230, 47, 0, 0, + 0, 0, 1243, 0, 0, 0, 1156, 1071, 1039, 1040, + 1244, 0, 0, 523, 1247, 0, 0, 0, 0, 0, + 0, 1056, 1057, 1041, 1059, 1060, 0, 0, 0, 459, + 1261, 0, 0, 0, 0, 1266, 0, 440, 0, 0, + 76, 0, 76, 76, 76, 186, 76, 0, 772, 957, + 0, 0, 76, 1271, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 184, 1278, 312, 209, 1279, 0, + 1087, 0, 0, 0, 0, 1286, 0, 0, 76, 76, + 76, 0, 0, 300, 0, 0, 0, 0, 0, 233, + 0, 184, 184, 0, 0, 0, 0, 184, 0, 1137, + 1138, 0, 1139, 0, 0, 1141, 0, 1143, 0, 995, + 312, 0, 312, 0, 0, 0, 0, 0, 183, 0, + 0, 76, 76, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 76, 312, 0, 0, 0, 0, + 0, 1135, 0, 0, 0, 0, 303, 76, 0, 0, + 1134, 413, 0, 1177, 0, 312, 0, 1136, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 76, 1145, 1146, + 1147, 0, 0, 1150, 1260, 523, 0, 312, 0, 0, + 0, 0, 0, 0, 0, 0, 1160, 1161, 1162, 195, + 1165, 0, 753, 0, 0, 1075, 957, 0, 753, 0, + 0, 0, 0, 76, 184, 0, 184, 0, 0, 0, + 0, 0, 184, 205, 0, 0, 0, 76, 0, 184, + 0, 0, 0, 0, 312, 0, 312, 1098, 0, 0, + 0, 0, 443, 444, 445, 0, 448, 0, 0, 0, + 0, 0, 0, 452, 0, 0, 0, 0, 0, 0, + 0, 1195, 1196, 0, 1197, 1198, 1199, 0, 421, 1124, + 422, 0, 0, 190, 0, 0, 429, 0, 1200, 192, + 0, 0, 1126, 431, 0, 0, 198, 194, 0, 1129, + 0, 0, 0, 1211, 1212, 1213, 0, 312, 0, 0, + 488, 487, 497, 498, 490, 491, 492, 493, 494, 495, + 496, 489, 0, 196, 499, 0, 200, 0, 0, 1235, + 1236, 1237, 1238, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 184, 0, 0, 0, 0, 0, 0, 184, + 573, 184, 0, 0, 191, 0, 905, 0, 0, 1168, + 0, 1168, 1168, 1168, 0, 1173, 0, 0, 0, 0, + 0, 312, 0, 1262, 454, 0, 0, 0, 1267, 0, + 0, 193, 1152, 201, 202, 203, 204, 208, 1148, 454, + 0, 1272, 207, 206, 0, 0, 551, 312, 312, 312, + 0, 0, 0, 0, 0, 575, 0, 0, 0, 1288, + 488, 487, 497, 498, 490, 491, 492, 493, 494, 495, + 496, 489, 1290, 1291, 499, 488, 487, 497, 498, 490, + 491, 492, 493, 494, 495, 496, 489, 0, 0, 499, + 1207, 1208, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1098, 488, 487, 497, 498, 490, 491, + 492, 493, 494, 495, 496, 489, 1168, 0, 499, 184, + 184, 644, 0, 184, 0, 0, 184, 0, 0, 653, + 662, 0, 0, 0, 0, 0, 1246, 1038, 0, 0, + 664, 665, 666, 667, 668, 669, 670, 671, 0, 0, + 0, 184, 0, 0, 672, 673, 0, 488, 487, 497, + 498, 490, 491, 492, 493, 494, 495, 496, 489, 753, + 184, 499, 1268, 651, 652, 0, 0, 655, 0, 662, + 658, 0, 0, 0, 0, 0, 1274, 0, 0, 23, + 24, 48, 26, 27, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 677, 0, 1149, 42, 0, + 0, 0, 0, 28, 0, 0, 0, 0, 0, 0, + 233, 0, 0, 0, 696, 233, 233, 0, 0, 754, + 754, 233, 37, 0, 0, 754, 50, 0, 0, 0, + 0, 0, 0, 0, 0, 233, 233, 233, 233, 0, + 184, 0, 754, 184, 184, 184, 184, 184, 0, 0, + 0, 0, 0, 0, 0, 786, 0, 0, 184, 0, + 0, 0, 573, 0, 0, 0, 0, 184, 184, 488, + 487, 497, 498, 490, 491, 492, 493, 494, 495, 496, + 489, 0, 0, 499, 0, 30, 31, 33, 32, 35, + 0, 0, 0, 0, 769, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 36, 43, 44, 0, + 0, 45, 46, 34, 0, 0, 0, 0, 0, 0, + 0, 0, 797, 0, 0, 38, 39, 0, 40, 41, + 0, 0, 0, 0, 0, 184, 617, 0, 0, 0, + 0, 483, 0, 486, 184, 0, 858, 184, 860, 500, + 501, 502, 503, 504, 505, 506, 879, 484, 485, 482, + 488, 487, 497, 498, 490, 491, 492, 493, 494, 495, + 496, 489, 662, 0, 499, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 233, 0, 0, 0, 0, 853, + 0, 0, 0, 906, 0, 0, 0, 0, 877, 0, + 0, 878, 0, 0, 0, 0, 0, 0, 49, 0, + 0, 0, 605, 488, 487, 497, 498, 490, 491, 492, + 493, 494, 495, 496, 489, 0, 0, 499, 0, 0, + 0, 233, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 618, 0, 0, 0, 0, 233, 488, 487, + 497, 498, 490, 491, 492, 493, 494, 495, 496, 489, + 0, 0, 499, 631, 632, 633, 634, 635, 636, 637, + 0, 638, 639, 640, 641, 642, 619, 620, 621, 622, + 603, 604, 0, 0, 606, 184, 607, 608, 609, 610, + 611, 612, 613, 614, 615, 616, 623, 624, 625, 626, + 627, 628, 629, 630, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 996, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1027, 1028, 0, 0, 0, 1023, 0, 0, 184, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 233, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 233, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 662, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 754, 0, 0, 0, 0, + 0, 754, 0, 1031, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 184, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 184, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 184, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1120, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1127, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 573, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1186, 0, + 0, 398, 388, 0, 360, 400, 338, 352, 408, 353, + 354, 381, 324, 368, 125, 350, 0, 341, 319, 347, + 320, 339, 362, 93, 365, 337, 390, 371, 107, 406, + 109, 376, 0, 142, 118, 0, 0, 364, 392, 366, + 386, 359, 382, 329, 375, 401, 351, 379, 402, 0, + 0, 0, 75, 0, 812, 813, 0, 0, 0, 0, + 0, 86, 0, 378, 397, 349, 380, 318, 377, 0, + 322, 325, 407, 395, 344, 345, 969, 0, 0, 0, + 0, 0, 0, 363, 367, 383, 357, 0, 0, 0, + 0, 0, 0, 0, 0, 342, 0, 374, 0, 0, + 0, 326, 323, 0, 361, 0, 0, 0, 328, 0, + 343, 384, 754, 317, 387, 393, 358, 187, 396, 356, + 355, 399, 131, 0, 0, 145, 98, 97, 106, 391, + 340, 348, 89, 346, 137, 127, 157, 373, 128, 136, + 110, 149, 132, 156, 188, 164, 147, 163, 78, 146, + 155, 87, 139, 80, 153, 144, 116, 102, 103, 79, + 0, 135, 92, 96, 91, 124, 150, 151, 90, 171, + 83, 162, 82, 84, 161, 123, 148, 154, 117, 114, + 81, 152, 115, 113, 105, 94, 99, 129, 112, 130, + 100, 120, 119, 121, 0, 321, 0, 143, 159, 172, + 336, 394, 165, 166, 167, 168, 0, 0, 0, 122, + 85, 101, 140, 104, 111, 134, 170, 126, 138, 88, + 158, 141, 332, 335, 330, 331, 369, 370, 403, 404, + 405, 385, 327, 0, 333, 334, 0, 389, 372, 77, + 0, 108, 169, 133, 95, 160, 398, 388, 0, 360, + 400, 338, 352, 408, 353, 354, 381, 324, 368, 125, + 350, 0, 341, 319, 347, 320, 339, 362, 93, 365, + 337, 390, 371, 107, 406, 109, 376, 0, 142, 118, + 0, 0, 364, 392, 366, 386, 359, 382, 329, 375, + 401, 351, 379, 402, 0, 0, 0, 75, 0, 812, + 813, 0, 0, 0, 0, 0, 86, 0, 378, 397, + 349, 380, 318, 377, 0, 322, 325, 407, 395, 344, + 345, 0, 0, 0, 0, 0, 0, 0, 363, 367, + 383, 357, 0, 0, 0, 0, 0, 0, 0, 0, + 342, 0, 374, 0, 0, 0, 326, 323, 0, 361, + 0, 0, 0, 328, 0, 343, 384, 0, 317, 387, + 393, 358, 187, 396, 356, 355, 399, 131, 0, 0, + 145, 98, 97, 106, 391, 340, 348, 89, 346, 137, + 127, 157, 373, 128, 136, 110, 149, 132, 156, 188, + 164, 147, 163, 78, 146, 155, 87, 139, 80, 153, + 144, 116, 102, 103, 79, 0, 135, 92, 96, 91, + 124, 150, 151, 90, 171, 83, 162, 82, 84, 161, + 123, 148, 154, 117, 114, 81, 152, 115, 113, 105, + 94, 99, 129, 112, 130, 100, 120, 119, 121, 0, + 321, 0, 143, 159, 172, 336, 394, 165, 166, 167, + 168, 0, 0, 0, 122, 85, 101, 140, 104, 111, + 134, 170, 126, 138, 88, 158, 141, 332, 335, 330, + 331, 369, 370, 403, 404, 405, 385, 327, 0, 333, + 334, 0, 389, 372, 77, 0, 108, 169, 133, 95, + 160, 398, 388, 0, 360, 400, 338, 352, 408, 353, + 354, 381, 324, 368, 125, 350, 0, 341, 319, 347, + 320, 339, 362, 93, 365, 337, 390, 371, 107, 406, + 109, 376, 0, 142, 118, 0, 0, 364, 392, 366, + 386, 359, 382, 329, 375, 401, 351, 379, 402, 50, + 0, 0, 75, 0, 0, 0, 0, 0, 0, 0, + 0, 86, 0, 378, 397, 349, 380, 318, 377, 0, + 322, 325, 407, 395, 344, 345, 0, 0, 0, 0, + 0, 0, 0, 363, 367, 383, 357, 0, 0, 0, + 0, 0, 0, 0, 0, 342, 0, 374, 0, 0, + 0, 326, 323, 0, 361, 0, 0, 0, 328, 0, + 343, 384, 0, 317, 387, 393, 358, 187, 396, 356, + 355, 399, 131, 0, 0, 145, 98, 97, 106, 391, + 340, 348, 89, 346, 137, 127, 157, 373, 128, 136, + 110, 149, 132, 156, 188, 164, 147, 163, 78, 146, + 155, 87, 139, 80, 153, 144, 116, 102, 103, 79, + 0, 135, 92, 96, 91, 124, 150, 151, 90, 171, + 83, 162, 82, 84, 161, 123, 148, 154, 117, 114, + 81, 152, 115, 113, 105, 94, 99, 129, 112, 130, + 100, 120, 119, 121, 0, 321, 0, 143, 159, 172, + 336, 394, 165, 166, 167, 168, 0, 0, 0, 122, + 85, 101, 140, 104, 111, 134, 170, 126, 138, 88, + 158, 141, 332, 335, 330, 331, 369, 370, 403, 404, + 405, 385, 327, 0, 333, 334, 0, 389, 372, 77, + 0, 108, 169, 133, 95, 160, 398, 388, 0, 360, + 400, 338, 352, 408, 353, 354, 381, 324, 368, 125, + 350, 0, 341, 319, 347, 320, 339, 362, 93, 365, + 337, 390, 371, 107, 406, 109, 376, 0, 142, 118, + 0, 0, 364, 392, 366, 386, 359, 382, 329, 375, + 401, 351, 379, 402, 0, 0, 0, 75, 0, 0, + 0, 0, 0, 0, 0, 0, 86, 0, 378, 397, + 349, 380, 318, 377, 0, 322, 325, 407, 395, 344, + 345, 0, 0, 0, 0, 0, 0, 0, 363, 367, + 383, 357, 0, 0, 0, 0, 0, 0, 1034, 0, + 342, 0, 374, 0, 0, 0, 326, 323, 0, 361, + 0, 0, 0, 328, 0, 343, 384, 0, 317, 387, + 393, 358, 187, 396, 356, 355, 399, 131, 0, 0, + 145, 98, 97, 106, 391, 340, 348, 89, 346, 137, + 127, 157, 373, 128, 136, 110, 149, 132, 156, 188, + 164, 147, 163, 78, 146, 155, 87, 139, 80, 153, + 144, 116, 102, 103, 79, 0, 135, 92, 96, 91, + 124, 150, 151, 90, 171, 83, 162, 82, 84, 161, + 123, 148, 154, 117, 114, 81, 152, 115, 113, 105, + 94, 99, 129, 112, 130, 100, 120, 119, 121, 0, + 321, 0, 143, 159, 172, 336, 394, 165, 166, 167, + 168, 0, 0, 0, 122, 85, 101, 140, 104, 111, + 134, 170, 126, 138, 88, 158, 141, 332, 335, 330, + 331, 369, 370, 403, 404, 405, 385, 327, 0, 333, + 334, 0, 389, 372, 77, 0, 108, 169, 133, 95, + 160, 398, 388, 0, 360, 400, 338, 352, 408, 353, + 354, 381, 324, 368, 125, 350, 0, 341, 319, 347, + 320, 339, 362, 93, 365, 337, 390, 371, 107, 406, + 109, 376, 0, 142, 118, 0, 0, 364, 392, 366, + 386, 359, 382, 329, 375, 401, 351, 379, 402, 0, + 0, 0, 238, 0, 0, 0, 0, 0, 0, 0, + 0, 86, 0, 378, 397, 349, 380, 318, 377, 0, + 322, 325, 407, 395, 344, 345, 0, 0, 0, 0, + 0, 0, 0, 363, 367, 383, 357, 0, 0, 0, + 0, 0, 0, 705, 0, 342, 0, 374, 0, 0, + 0, 326, 323, 0, 361, 0, 0, 0, 328, 0, + 343, 384, 0, 317, 387, 393, 358, 187, 396, 356, + 355, 399, 131, 0, 0, 145, 98, 97, 106, 391, + 340, 348, 89, 346, 137, 127, 157, 373, 128, 136, + 110, 149, 132, 156, 188, 164, 147, 163, 78, 146, + 155, 87, 139, 80, 153, 144, 116, 102, 103, 79, + 0, 135, 92, 96, 91, 124, 150, 151, 90, 171, + 83, 162, 82, 84, 161, 123, 148, 154, 117, 114, + 81, 152, 115, 113, 105, 94, 99, 129, 112, 130, + 100, 120, 119, 121, 0, 321, 0, 143, 159, 172, + 336, 394, 165, 166, 167, 168, 0, 0, 0, 122, + 85, 101, 140, 104, 111, 134, 170, 126, 138, 88, + 158, 141, 332, 335, 330, 331, 369, 370, 403, 404, + 405, 385, 327, 0, 333, 334, 0, 389, 372, 77, + 0, 108, 169, 133, 95, 160, 398, 388, 0, 360, + 400, 338, 352, 408, 353, 354, 381, 324, 368, 125, + 350, 0, 341, 319, 347, 320, 339, 362, 93, 365, + 337, 390, 371, 107, 406, 109, 376, 0, 142, 118, + 0, 0, 364, 392, 366, 386, 359, 382, 329, 375, + 401, 351, 379, 402, 0, 0, 0, 75, 0, 0, + 0, 0, 0, 0, 0, 0, 86, 0, 378, 397, + 349, 380, 318, 377, 0, 322, 325, 407, 395, 344, + 345, 0, 0, 0, 0, 0, 0, 0, 363, 367, + 383, 357, 0, 0, 0, 0, 0, 0, 0, 0, + 342, 0, 374, 0, 0, 0, 326, 323, 0, 361, + 0, 0, 0, 328, 0, 343, 384, 0, 317, 387, + 393, 358, 187, 396, 356, 355, 399, 131, 0, 0, + 145, 98, 97, 106, 391, 340, 348, 89, 346, 137, + 127, 157, 373, 128, 136, 110, 149, 132, 156, 188, + 164, 147, 163, 78, 146, 155, 87, 139, 80, 153, + 144, 116, 102, 103, 79, 0, 135, 92, 96, 91, + 124, 150, 151, 90, 171, 83, 162, 82, 84, 161, + 123, 148, 154, 117, 114, 81, 152, 115, 113, 105, + 94, 99, 129, 112, 130, 100, 120, 119, 121, 0, + 321, 0, 143, 159, 172, 336, 394, 165, 166, 167, + 168, 0, 0, 0, 122, 85, 101, 140, 104, 111, + 134, 170, 126, 138, 88, 158, 141, 332, 335, 330, + 331, 369, 370, 403, 404, 405, 385, 327, 0, 333, + 334, 0, 389, 372, 77, 0, 108, 169, 133, 95, + 160, 398, 388, 0, 360, 400, 338, 352, 408, 353, + 354, 381, 324, 368, 125, 350, 0, 341, 319, 347, + 320, 339, 362, 93, 365, 337, 390, 371, 107, 406, + 109, 376, 0, 142, 118, 0, 0, 364, 392, 366, + 386, 359, 382, 329, 375, 401, 351, 379, 402, 0, + 0, 0, 238, 0, 0, 0, 0, 0, 0, 0, + 0, 86, 0, 378, 397, 349, 380, 318, 377, 0, + 322, 325, 407, 395, 344, 345, 0, 0, 0, 0, + 0, 0, 0, 363, 367, 383, 357, 0, 0, 0, + 0, 0, 0, 0, 0, 342, 0, 374, 0, 0, + 0, 326, 323, 0, 361, 0, 0, 0, 328, 0, + 343, 384, 0, 317, 387, 393, 358, 187, 396, 356, + 355, 399, 131, 0, 0, 145, 98, 97, 106, 391, + 340, 348, 89, 346, 137, 127, 157, 373, 128, 136, + 110, 149, 132, 156, 188, 164, 147, 163, 78, 146, + 155, 87, 139, 80, 153, 144, 116, 102, 103, 79, + 0, 135, 92, 96, 91, 124, 150, 151, 90, 171, + 83, 162, 82, 84, 161, 123, 148, 154, 117, 114, + 81, 152, 115, 113, 105, 94, 99, 129, 112, 130, + 100, 120, 119, 121, 0, 321, 0, 143, 159, 172, + 336, 394, 165, 166, 167, 168, 0, 0, 0, 122, + 85, 101, 140, 104, 111, 134, 170, 126, 138, 88, + 158, 141, 332, 335, 330, 331, 369, 370, 403, 404, + 405, 385, 327, 0, 333, 334, 0, 389, 372, 77, + 0, 108, 169, 133, 95, 160, 398, 388, 0, 360, + 400, 338, 352, 408, 353, 354, 381, 324, 368, 125, + 350, 0, 341, 319, 347, 320, 339, 362, 93, 365, + 337, 390, 371, 107, 406, 109, 376, 0, 142, 118, + 0, 0, 364, 392, 366, 386, 359, 382, 329, 375, + 401, 351, 379, 402, 0, 0, 0, 75, 0, 0, + 0, 0, 0, 0, 0, 0, 86, 0, 378, 397, + 349, 380, 318, 377, 0, 322, 325, 407, 395, 344, + 345, 0, 0, 0, 0, 0, 0, 0, 363, 367, + 383, 357, 0, 0, 0, 0, 0, 0, 0, 0, + 342, 0, 374, 0, 0, 0, 326, 323, 0, 361, + 0, 0, 0, 328, 0, 343, 384, 0, 317, 387, + 393, 358, 187, 396, 356, 355, 399, 131, 0, 0, + 145, 98, 97, 106, 391, 340, 348, 89, 346, 137, + 127, 157, 373, 128, 136, 110, 149, 132, 156, 188, + 164, 147, 163, 78, 146, 155, 87, 139, 80, 153, + 144, 116, 102, 103, 79, 0, 135, 92, 96, 91, + 124, 150, 151, 90, 171, 83, 162, 82, 315, 161, + 123, 148, 154, 117, 114, 81, 152, 115, 113, 105, + 94, 99, 129, 112, 130, 100, 120, 119, 121, 0, + 321, 0, 143, 159, 172, 336, 394, 165, 166, 167, + 168, 0, 0, 0, 316, 314, 101, 140, 104, 111, + 134, 170, 126, 138, 88, 158, 141, 332, 335, 330, + 331, 369, 370, 403, 404, 405, 385, 327, 0, 333, + 334, 0, 389, 372, 77, 0, 108, 169, 133, 95, + 160, 398, 388, 0, 360, 400, 338, 352, 408, 353, + 354, 381, 324, 368, 125, 350, 0, 341, 319, 347, + 320, 339, 362, 93, 365, 337, 390, 371, 107, 406, + 109, 376, 0, 142, 118, 0, 0, 364, 392, 366, + 386, 359, 382, 329, 375, 401, 351, 379, 402, 0, + 0, 0, 185, 0, 0, 0, 0, 0, 0, 0, + 0, 86, 0, 378, 397, 349, 380, 318, 377, 0, + 322, 325, 407, 395, 344, 345, 0, 0, 0, 0, + 0, 0, 0, 363, 367, 383, 357, 0, 0, 0, + 0, 0, 0, 0, 0, 342, 0, 374, 0, 0, + 0, 326, 323, 0, 361, 0, 0, 0, 328, 0, + 343, 384, 0, 317, 387, 393, 358, 187, 396, 356, + 355, 399, 131, 0, 0, 145, 98, 97, 106, 391, + 340, 348, 89, 346, 137, 127, 157, 373, 128, 136, + 110, 149, 132, 156, 188, 164, 147, 163, 78, 146, + 155, 87, 139, 80, 153, 144, 116, 102, 103, 79, + 0, 135, 92, 96, 91, 124, 150, 151, 90, 171, + 83, 162, 82, 84, 161, 123, 148, 154, 117, 114, + 81, 152, 115, 113, 105, 94, 99, 129, 112, 130, + 100, 120, 119, 121, 0, 321, 0, 143, 159, 172, + 336, 394, 165, 166, 167, 168, 0, 0, 0, 122, + 85, 101, 140, 104, 111, 134, 170, 126, 138, 88, + 158, 141, 332, 335, 330, 331, 369, 370, 403, 404, + 405, 385, 327, 0, 333, 334, 0, 389, 372, 77, + 0, 108, 169, 133, 95, 160, 398, 388, 0, 360, + 400, 338, 352, 408, 353, 354, 381, 324, 368, 125, + 350, 0, 341, 319, 347, 320, 339, 362, 93, 365, + 337, 390, 371, 107, 406, 109, 376, 0, 142, 118, + 0, 0, 364, 392, 366, 386, 359, 382, 329, 375, + 401, 351, 379, 402, 0, 0, 0, 75, 0, 0, + 0, 0, 0, 0, 0, 0, 86, 0, 378, 397, + 349, 380, 318, 377, 0, 322, 325, 407, 395, 344, + 345, 0, 0, 0, 0, 0, 0, 0, 363, 367, + 383, 357, 0, 0, 0, 0, 0, 0, 0, 0, + 342, 0, 374, 0, 0, 0, 326, 323, 0, 361, + 0, 0, 0, 328, 0, 343, 384, 0, 317, 387, + 393, 358, 187, 396, 356, 355, 399, 131, 0, 0, + 145, 98, 97, 106, 391, 340, 348, 89, 346, 137, + 127, 157, 373, 128, 136, 110, 149, 132, 156, 188, + 164, 147, 163, 78, 146, 583, 87, 139, 80, 153, + 144, 116, 102, 103, 79, 0, 135, 92, 96, 91, + 124, 150, 151, 90, 171, 83, 162, 82, 315, 161, + 123, 148, 154, 117, 114, 81, 152, 115, 113, 105, + 94, 99, 129, 112, 130, 100, 120, 119, 121, 0, + 321, 0, 143, 159, 172, 336, 394, 165, 166, 167, + 168, 0, 0, 0, 316, 314, 101, 140, 104, 111, + 134, 170, 126, 138, 88, 158, 141, 332, 335, 330, + 331, 369, 370, 403, 404, 405, 385, 327, 0, 333, + 334, 0, 389, 372, 77, 0, 108, 169, 133, 95, + 160, 398, 388, 0, 360, 400, 338, 352, 408, 353, + 354, 381, 324, 368, 125, 350, 0, 341, 319, 347, + 320, 339, 362, 93, 365, 337, 390, 371, 107, 406, + 109, 376, 0, 142, 118, 0, 0, 364, 392, 366, + 386, 359, 382, 329, 375, 401, 351, 379, 402, 0, + 0, 0, 75, 0, 0, 0, 0, 0, 0, 0, + 0, 86, 0, 378, 397, 349, 380, 318, 377, 0, + 322, 325, 407, 395, 344, 345, 0, 0, 0, 0, + 0, 0, 0, 363, 367, 383, 357, 0, 0, 0, + 0, 0, 0, 0, 0, 342, 0, 374, 0, 0, + 0, 326, 323, 0, 361, 0, 0, 0, 328, 0, + 343, 384, 0, 317, 387, 393, 358, 187, 396, 356, + 355, 399, 131, 0, 0, 145, 98, 97, 106, 391, + 340, 348, 89, 346, 137, 127, 157, 373, 128, 136, + 110, 149, 132, 156, 188, 164, 147, 163, 78, 146, + 306, 87, 139, 80, 153, 144, 116, 102, 103, 79, + 0, 135, 92, 96, 91, 124, 150, 151, 90, 171, + 83, 162, 82, 315, 161, 123, 148, 154, 117, 114, + 81, 152, 115, 113, 105, 94, 99, 129, 112, 130, + 100, 120, 119, 121, 0, 321, 0, 143, 159, 172, + 336, 394, 165, 166, 167, 168, 0, 0, 0, 316, + 314, 309, 308, 104, 111, 134, 170, 126, 138, 88, + 158, 141, 332, 335, 330, 331, 369, 370, 403, 404, + 405, 385, 327, 0, 333, 334, 0, 389, 372, 77, + 0, 108, 169, 133, 95, 160, 125, 0, 0, 741, + 0, 240, 0, 0, 0, 93, 0, 237, 0, 0, + 107, 279, 109, 0, 0, 142, 118, 0, 0, 0, + 0, 270, 271, 0, 0, 0, 0, 0, 0, 0, + 0, 50, 0, 0, 238, 258, 257, 260, 261, 262, + 263, 0, 0, 86, 259, 264, 265, 266, 0, 0, + 235, 251, 0, 278, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 248, 249, 231, 0, 0, 0, 290, + 0, 250, 0, 0, 246, 247, 252, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 187, + 0, 0, 288, 0, 131, 0, 0, 145, 98, 97, + 106, 0, 0, 0, 89, 0, 137, 127, 157, 0, + 128, 136, 110, 149, 132, 156, 188, 164, 147, 163, + 78, 146, 155, 87, 139, 80, 153, 144, 116, 102, + 103, 79, 0, 135, 92, 96, 91, 124, 150, 151, + 90, 171, 83, 162, 82, 84, 161, 123, 148, 154, + 117, 114, 81, 152, 115, 113, 105, 94, 99, 129, + 112, 130, 100, 120, 119, 121, 0, 0, 0, 143, + 159, 172, 0, 0, 165, 166, 167, 168, 0, 0, + 0, 122, 85, 101, 140, 104, 111, 134, 170, 126, + 138, 88, 158, 141, 280, 289, 286, 287, 284, 285, + 283, 282, 281, 291, 272, 273, 274, 275, 277, 0, + 276, 77, 0, 108, 169, 133, 95, 160, 125, 0, + 0, 0, 0, 240, 0, 0, 0, 93, 0, 237, + 0, 0, 107, 279, 109, 0, 0, 142, 118, 0, + 0, 0, 0, 270, 271, 0, 0, 0, 0, 0, + 0, 0, 0, 50, 0, 454, 238, 258, 257, 260, + 261, 262, 263, 0, 0, 86, 259, 264, 265, 266, + 0, 0, 235, 251, 0, 278, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 248, 249, 0, 0, 0, + 0, 290, 0, 250, 0, 0, 246, 247, 252, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 187, 0, 0, 288, 0, 131, 0, 0, 145, + 98, 97, 106, 0, 0, 0, 89, 0, 137, 127, + 157, 0, 128, 136, 110, 149, 132, 156, 188, 164, + 147, 163, 78, 146, 155, 87, 139, 80, 153, 144, + 116, 102, 103, 79, 0, 135, 92, 96, 91, 124, + 150, 151, 90, 171, 83, 162, 82, 84, 161, 123, + 148, 154, 117, 114, 81, 152, 115, 113, 105, 94, + 99, 129, 112, 130, 100, 120, 119, 121, 0, 0, + 0, 143, 159, 172, 0, 0, 165, 166, 167, 168, + 0, 0, 0, 122, 85, 101, 140, 104, 111, 134, + 170, 126, 138, 88, 158, 141, 280, 289, 286, 287, + 284, 285, 283, 282, 281, 291, 272, 273, 274, 275, + 277, 0, 276, 77, 0, 108, 169, 133, 95, 160, + 125, 0, 0, 0, 0, 240, 0, 0, 0, 93, + 0, 237, 0, 0, 107, 279, 109, 0, 0, 142, + 118, 0, 0, 0, 0, 270, 271, 0, 0, 0, + 0, 0, 0, 0, 0, 50, 0, 0, 238, 258, + 257, 260, 261, 262, 263, 0, 0, 86, 259, 264, + 265, 266, 0, 0, 235, 251, 0, 278, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 248, 249, 231, + 0, 0, 0, 290, 0, 250, 0, 0, 246, 247, + 252, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 187, 0, 0, 288, 0, 131, 0, + 0, 145, 98, 97, 106, 0, 0, 0, 89, 0, + 137, 127, 157, 0, 128, 136, 110, 149, 132, 156, + 188, 164, 147, 163, 78, 146, 155, 87, 139, 80, + 153, 144, 116, 102, 103, 79, 0, 135, 92, 96, + 91, 124, 150, 151, 90, 171, 83, 162, 82, 84, + 161, 123, 148, 154, 117, 114, 81, 152, 115, 113, + 105, 94, 99, 129, 112, 130, 100, 120, 119, 121, + 0, 0, 0, 143, 159, 172, 0, 0, 165, 166, + 167, 168, 0, 0, 0, 122, 85, 101, 140, 104, + 111, 134, 170, 126, 138, 88, 158, 141, 280, 289, + 286, 287, 284, 285, 283, 282, 281, 291, 272, 273, + 274, 275, 277, 0, 276, 77, 0, 108, 169, 133, + 95, 160, 125, 0, 0, 0, 0, 240, 0, 0, + 0, 93, 0, 237, 0, 0, 107, 279, 109, 0, + 0, 142, 118, 0, 0, 0, 0, 270, 271, 0, + 0, 0, 0, 0, 0, 804, 0, 50, 0, 0, + 238, 258, 257, 260, 261, 262, 263, 0, 0, 86, + 259, 264, 265, 266, 0, 0, 235, 251, 0, 278, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 248, + 249, 0, 0, 0, 0, 290, 0, 250, 0, 0, + 246, 247, 252, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 187, 0, 0, 288, 0, + 131, 0, 0, 145, 98, 97, 106, 0, 0, 0, + 89, 0, 137, 127, 157, 0, 128, 136, 110, 149, + 132, 156, 188, 164, 147, 163, 78, 146, 155, 87, + 139, 80, 153, 144, 116, 102, 103, 79, 0, 135, + 92, 96, 91, 124, 150, 151, 90, 171, 83, 162, + 82, 84, 161, 123, 148, 154, 117, 114, 81, 152, + 115, 113, 105, 94, 99, 129, 112, 130, 100, 120, + 119, 121, 0, 0, 0, 143, 159, 172, 0, 0, + 165, 166, 167, 168, 0, 0, 0, 122, 85, 101, + 140, 104, 111, 134, 170, 126, 138, 88, 158, 141, + 280, 289, 286, 287, 284, 285, 283, 282, 281, 291, + 272, 273, 274, 275, 277, 23, 276, 77, 0, 108, + 169, 133, 95, 160, 0, 0, 0, 125, 0, 0, + 0, 0, 240, 0, 0, 0, 93, 0, 237, 0, + 0, 107, 279, 109, 0, 0, 142, 118, 0, 0, + 0, 0, 270, 271, 0, 0, 0, 0, 0, 0, + 0, 0, 50, 0, 0, 238, 258, 257, 260, 261, + 262, 263, 0, 0, 86, 259, 264, 265, 266, 0, + 0, 235, 251, 0, 278, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 248, 249, 0, 0, 0, 0, + 290, 0, 250, 0, 0, 246, 247, 252, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 187, 0, 0, 288, 0, 131, 0, 0, 145, 98, + 97, 106, 0, 0, 0, 89, 0, 137, 127, 157, + 0, 128, 136, 110, 149, 132, 156, 188, 164, 147, + 163, 78, 146, 155, 87, 139, 80, 153, 144, 116, + 102, 103, 79, 0, 135, 92, 96, 91, 124, 150, + 151, 90, 171, 83, 162, 82, 84, 161, 123, 148, + 154, 117, 114, 81, 152, 115, 113, 105, 94, 99, + 129, 112, 130, 100, 120, 119, 121, 0, 0, 0, + 143, 159, 172, 0, 0, 165, 166, 167, 168, 0, + 0, 0, 122, 85, 101, 140, 104, 111, 134, 170, + 126, 138, 88, 158, 141, 280, 289, 286, 287, 284, + 285, 283, 282, 281, 291, 272, 273, 274, 275, 277, + 0, 276, 77, 0, 108, 169, 133, 95, 160, 125, + 0, 0, 0, 0, 240, 0, 0, 0, 93, 0, + 237, 0, 0, 107, 279, 109, 0, 0, 142, 118, + 0, 0, 0, 0, 270, 271, 0, 0, 0, 0, + 0, 0, 0, 0, 50, 0, 0, 238, 258, 257, + 260, 261, 262, 263, 0, 0, 86, 259, 264, 265, + 266, 0, 0, 235, 251, 0, 278, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 248, 249, 0, 0, + 0, 0, 290, 0, 250, 0, 0, 246, 247, 252, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 187, 0, 0, 288, 0, 131, 0, 0, + 145, 98, 97, 106, 0, 0, 0, 89, 0, 137, + 127, 157, 0, 128, 136, 110, 149, 132, 156, 188, + 164, 147, 163, 78, 146, 155, 87, 139, 80, 153, + 144, 116, 102, 103, 79, 0, 135, 92, 96, 91, + 124, 150, 151, 90, 171, 83, 162, 82, 84, 161, + 123, 148, 154, 117, 114, 81, 152, 115, 113, 105, + 94, 99, 129, 112, 130, 100, 120, 119, 121, 0, + 0, 0, 143, 159, 172, 0, 0, 165, 166, 167, + 168, 0, 0, 0, 122, 85, 101, 140, 104, 111, + 134, 170, 126, 138, 88, 158, 141, 280, 289, 286, + 287, 284, 285, 283, 282, 281, 291, 272, 273, 274, + 275, 277, 125, 276, 77, 0, 108, 169, 133, 95, + 160, 93, 0, 0, 0, 0, 107, 279, 109, 0, + 0, 142, 118, 0, 0, 0, 0, 270, 271, 0, + 0, 0, 0, 0, 0, 0, 0, 50, 0, 0, + 238, 258, 257, 260, 261, 262, 263, 0, 0, 86, + 259, 264, 265, 266, 0, 0, 0, 251, 0, 278, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 248, + 249, 0, 0, 0, 0, 290, 0, 250, 0, 0, + 246, 247, 252, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 187, 0, 0, 288, 0, + 131, 0, 0, 145, 98, 97, 106, 0, 0, 0, + 89, 0, 137, 127, 157, 1289, 128, 136, 110, 149, + 132, 156, 188, 164, 147, 163, 78, 146, 155, 87, + 139, 80, 153, 144, 116, 102, 103, 79, 0, 135, + 92, 96, 91, 124, 150, 151, 90, 171, 83, 162, + 82, 84, 161, 123, 148, 154, 117, 114, 81, 152, + 115, 113, 105, 94, 99, 129, 112, 130, 100, 120, + 119, 121, 0, 0, 0, 143, 159, 172, 0, 0, + 165, 166, 167, 168, 0, 0, 0, 122, 85, 101, + 140, 104, 111, 134, 170, 126, 138, 88, 158, 141, + 280, 289, 286, 287, 284, 285, 283, 282, 281, 291, + 272, 273, 274, 275, 277, 125, 276, 77, 0, 108, + 169, 133, 95, 160, 93, 0, 0, 0, 0, 107, + 279, 109, 0, 0, 142, 118, 0, 0, 0, 0, + 270, 271, 0, 0, 0, 0, 0, 0, 0, 0, + 50, 0, 0, 238, 258, 257, 260, 261, 262, 263, + 0, 0, 86, 259, 264, 265, 266, 0, 0, 0, + 251, 0, 278, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 248, 249, 0, 0, 0, 0, 290, 0, + 250, 0, 0, 246, 247, 252, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 187, 0, + 0, 288, 0, 131, 0, 0, 145, 98, 97, 106, + 0, 0, 0, 89, 0, 137, 127, 157, 0, 128, + 136, 110, 149, 132, 156, 188, 164, 147, 163, 78, + 146, 155, 87, 139, 80, 153, 144, 116, 102, 103, + 79, 0, 135, 92, 96, 91, 124, 150, 151, 90, + 171, 83, 162, 82, 84, 161, 123, 148, 154, 117, + 114, 81, 152, 115, 113, 105, 94, 99, 129, 112, + 130, 100, 120, 119, 121, 0, 0, 0, 143, 159, + 172, 0, 0, 165, 166, 167, 168, 0, 0, 0, + 122, 85, 101, 140, 104, 111, 134, 170, 126, 138, + 88, 158, 141, 280, 289, 286, 287, 284, 285, 283, + 282, 281, 291, 272, 273, 274, 275, 277, 125, 276, + 77, 0, 108, 169, 133, 95, 160, 93, 0, 0, + 0, 0, 107, 0, 109, 0, 0, 142, 118, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 75, 0, 0, 0, + 0, 0, 0, 0, 0, 86, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 488, 487, 497, 498, 490, 491, 492, 493, 494, + 495, 496, 489, 0, 0, 499, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 187, 0, 0, 0, 0, 131, 0, 0, 145, + 98, 97, 106, 0, 0, 0, 89, 0, 137, 127, + 157, 0, 128, 136, 110, 149, 132, 156, 188, 164, + 147, 163, 78, 146, 155, 87, 139, 80, 153, 144, + 116, 102, 103, 79, 0, 135, 92, 96, 91, 124, + 150, 151, 90, 171, 83, 162, 82, 84, 161, 123, + 148, 154, 117, 114, 81, 152, 115, 113, 105, 94, + 99, 129, 112, 130, 100, 120, 119, 121, 0, 0, + 0, 143, 159, 172, 0, 0, 165, 166, 167, 168, + 0, 0, 0, 122, 85, 101, 140, 104, 111, 134, + 170, 126, 138, 88, 158, 141, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 77, 0, 108, 169, 133, 95, 160, + 125, 0, 0, 0, 476, 0, 0, 0, 0, 93, + 0, 0, 0, 0, 107, 0, 109, 0, 0, 142, + 118, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 75, 0, + 478, 0, 0, 0, 0, 0, 0, 86, 0, 0, + 0, 0, 473, 472, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 474, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 187, 0, 0, 0, 0, 131, 0, + 0, 145, 98, 97, 106, 0, 0, 0, 89, 0, + 137, 127, 157, 0, 128, 136, 110, 149, 132, 156, + 188, 164, 147, 163, 78, 146, 155, 87, 139, 80, + 153, 144, 116, 102, 103, 79, 0, 135, 92, 96, + 91, 124, 150, 151, 90, 171, 83, 162, 82, 84, + 161, 123, 148, 154, 117, 114, 81, 152, 115, 113, + 105, 94, 99, 129, 112, 130, 100, 120, 119, 121, + 0, 0, 0, 143, 159, 172, 0, 0, 165, 166, + 167, 168, 0, 0, 0, 122, 85, 101, 140, 104, + 111, 134, 170, 126, 138, 88, 158, 141, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 125, 0, 77, 0, 108, 169, 133, + 95, 160, 93, 0, 0, 0, 0, 107, 0, 109, + 0, 0, 142, 118, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 75, 0, 0, 0, 0, 0, 0, 0, 0, + 86, 0, 0, 0, 0, 68, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 71, 72, 0, 67, 0, 0, 0, + 73, 131, 0, 0, 145, 98, 97, 106, 0, 0, + 0, 89, 0, 137, 127, 157, 0, 128, 136, 110, + 149, 132, 156, 69, 164, 147, 163, 78, 146, 155, + 87, 139, 80, 153, 144, 116, 102, 103, 79, 0, + 135, 92, 96, 91, 124, 150, 151, 90, 171, 83, + 162, 82, 84, 161, 123, 148, 154, 117, 114, 81, + 152, 115, 113, 105, 94, 99, 129, 112, 130, 100, + 120, 119, 121, 0, 0, 0, 143, 159, 172, 0, + 0, 165, 166, 167, 168, 0, 0, 0, 122, 85, + 101, 140, 104, 111, 134, 170, 126, 138, 88, 158, + 141, 0, 70, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 77, 0, + 108, 169, 133, 95, 160, 125, 0, 0, 0, 572, + 0, 0, 0, 0, 93, 0, 0, 0, 0, 107, + 0, 109, 0, 0, 142, 118, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 185, 0, 574, 0, 0, 0, 0, + 0, 0, 86, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 187, 0, + 0, 0, 0, 131, 0, 0, 145, 98, 97, 106, + 0, 0, 0, 89, 0, 137, 127, 157, 0, 128, + 136, 110, 149, 132, 156, 188, 164, 147, 163, 78, + 146, 155, 87, 139, 80, 153, 144, 116, 102, 103, + 79, 0, 135, 92, 96, 91, 124, 150, 151, 90, + 171, 83, 162, 82, 84, 161, 123, 148, 154, 117, + 114, 81, 152, 115, 113, 105, 94, 99, 129, 112, + 130, 100, 120, 119, 121, 0, 0, 0, 143, 159, + 172, 0, 0, 165, 166, 167, 168, 0, 0, 0, + 122, 85, 101, 140, 104, 111, 134, 170, 126, 138, + 88, 158, 141, 0, 0, 0, 23, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 125, 0, + 77, 0, 108, 169, 133, 95, 160, 93, 0, 0, + 0, 0, 107, 0, 109, 0, 0, 142, 118, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 50, 0, 0, 75, 0, 0, 0, + 0, 0, 0, 0, 0, 86, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 187, 0, 0, 0, 0, 131, 0, 0, 145, + 98, 97, 106, 0, 0, 0, 89, 0, 137, 127, + 157, 0, 128, 136, 110, 149, 132, 156, 188, 164, + 147, 163, 78, 146, 155, 87, 139, 80, 153, 144, + 116, 102, 103, 79, 0, 135, 92, 96, 91, 124, + 150, 151, 90, 171, 83, 162, 82, 84, 161, 123, + 148, 154, 117, 114, 81, 152, 115, 113, 105, 94, + 99, 129, 112, 130, 100, 120, 119, 121, 0, 0, + 0, 143, 159, 172, 0, 0, 165, 166, 167, 168, + 0, 0, 0, 122, 85, 101, 140, 104, 111, 134, + 170, 126, 138, 88, 158, 141, 0, 0, 0, 23, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 125, 0, 77, 0, 108, 169, 133, 95, 160, + 93, 0, 0, 0, 0, 107, 0, 109, 0, 0, + 142, 118, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 50, 0, 0, 185, + 0, 0, 0, 0, 0, 0, 0, 0, 86, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 187, 0, 0, 0, 0, 131, + 0, 0, 145, 98, 97, 106, 0, 0, 0, 89, + 0, 137, 127, 157, 0, 128, 136, 110, 149, 132, + 156, 188, 164, 147, 163, 78, 146, 155, 87, 139, + 80, 153, 144, 116, 102, 103, 79, 0, 135, 92, + 96, 91, 124, 150, 151, 90, 171, 83, 162, 82, + 84, 161, 123, 148, 154, 117, 114, 81, 152, 115, + 113, 105, 94, 99, 129, 112, 130, 100, 120, 119, + 121, 0, 0, 0, 143, 159, 172, 0, 0, 165, + 166, 167, 168, 0, 0, 0, 122, 85, 101, 140, + 104, 111, 134, 170, 126, 138, 88, 158, 141, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 125, 0, 77, 0, 108, 169, + 133, 95, 160, 93, 0, 0, 0, 0, 107, 0, + 109, 0, 0, 142, 118, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 75, 0, 0, 692, 0, 0, 693, 0, + 0, 86, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 187, 0, 0, + 0, 0, 131, 0, 0, 145, 98, 97, 106, 0, + 0, 0, 89, 0, 137, 127, 157, 0, 128, 136, + 110, 149, 132, 156, 188, 164, 147, 163, 78, 146, + 155, 87, 139, 80, 153, 144, 116, 102, 103, 79, + 0, 135, 92, 96, 91, 124, 150, 151, 90, 171, + 83, 162, 82, 84, 161, 123, 148, 154, 117, 114, + 81, 152, 115, 113, 105, 94, 99, 129, 112, 130, + 100, 120, 119, 121, 0, 0, 0, 143, 159, 172, + 0, 0, 165, 166, 167, 168, 0, 0, 0, 122, + 85, 101, 140, 104, 111, 134, 170, 126, 138, 88, + 158, 141, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 125, 0, 77, + 0, 108, 169, 133, 95, 160, 93, 0, 592, 0, + 0, 107, 0, 109, 0, 0, 142, 118, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 75, 0, 591, 0, 0, + 0, 0, 0, 0, 86, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 187, 0, 0, 0, 0, 131, 0, 0, 145, 98, + 97, 106, 0, 0, 0, 89, 0, 137, 127, 157, + 0, 128, 136, 110, 149, 132, 156, 188, 164, 147, + 163, 78, 146, 155, 87, 139, 80, 153, 144, 116, + 102, 103, 79, 0, 135, 92, 96, 91, 124, 150, + 151, 90, 171, 83, 162, 82, 84, 161, 123, 148, + 154, 117, 114, 81, 152, 115, 113, 105, 94, 99, + 129, 112, 130, 100, 120, 119, 121, 0, 0, 0, + 143, 159, 172, 0, 0, 165, 166, 167, 168, 0, + 0, 0, 122, 85, 101, 140, 104, 111, 134, 170, + 126, 138, 88, 158, 141, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 77, 0, 108, 169, 133, 95, 160, 125, + 0, 0, 0, 572, 0, 0, 0, 0, 93, 0, + 0, 0, 0, 107, 0, 109, 0, 0, 142, 118, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 185, 0, 574, + 0, 0, 0, 0, 0, 0, 86, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 187, 0, 0, 0, 0, 131, 0, 0, + 145, 98, 97, 106, 0, 0, 0, 89, 0, 137, + 127, 157, 0, 570, 136, 110, 149, 132, 156, 188, + 164, 147, 163, 78, 146, 155, 87, 139, 80, 153, + 144, 116, 102, 103, 79, 0, 135, 92, 96, 91, + 124, 150, 151, 90, 171, 83, 162, 82, 84, 161, + 123, 148, 154, 117, 114, 81, 152, 115, 113, 105, + 94, 99, 129, 112, 130, 100, 120, 119, 121, 0, + 0, 0, 143, 159, 172, 0, 0, 165, 166, 167, + 168, 0, 0, 0, 122, 85, 101, 140, 104, 111, + 134, 170, 126, 138, 88, 158, 141, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 125, 0, 77, 0, 108, 169, 133, 95, + 160, 93, 0, 0, 0, 0, 107, 0, 109, 0, + 0, 142, 118, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 50, 0, 0, + 185, 0, 0, 0, 0, 0, 0, 0, 0, 86, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 187, 0, 0, 0, 0, + 131, 0, 0, 145, 98, 97, 106, 0, 0, 0, + 89, 0, 137, 127, 157, 0, 128, 136, 110, 149, + 132, 156, 188, 164, 147, 163, 78, 146, 155, 87, + 139, 80, 153, 144, 116, 102, 103, 79, 0, 135, + 92, 96, 91, 124, 150, 151, 90, 171, 83, 162, + 82, 84, 161, 123, 148, 154, 117, 114, 81, 152, + 115, 113, 105, 94, 99, 129, 112, 130, 100, 120, + 119, 121, 0, 0, 0, 143, 159, 172, 0, 0, + 165, 166, 167, 168, 0, 0, 0, 122, 85, 101, + 140, 104, 111, 134, 170, 126, 138, 88, 158, 141, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 125, 0, 77, 0, 108, + 169, 133, 95, 160, 93, 0, 0, 0, 0, 107, + 0, 109, 0, 0, 142, 118, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 185, 0, 574, 0, 0, 0, 0, + 0, 0, 86, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 187, 0, + 0, 0, 0, 131, 0, 0, 145, 98, 97, 106, + 0, 0, 0, 89, 0, 137, 127, 157, 0, 128, + 136, 110, 149, 132, 156, 188, 164, 147, 163, 78, + 146, 155, 87, 139, 80, 153, 144, 116, 102, 103, + 79, 0, 135, 92, 96, 91, 124, 150, 151, 90, + 171, 83, 162, 82, 84, 161, 123, 148, 154, 117, + 114, 81, 152, 115, 113, 105, 94, 99, 129, 112, + 130, 100, 120, 119, 121, 0, 0, 0, 143, 159, + 172, 0, 0, 165, 166, 167, 168, 0, 0, 0, + 122, 85, 101, 140, 104, 111, 134, 170, 126, 138, + 88, 158, 141, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 125, 0, + 77, 0, 108, 169, 133, 95, 160, 93, 0, 0, + 0, 0, 107, 0, 109, 0, 0, 142, 118, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 75, 0, 478, 0, + 0, 0, 0, 0, 0, 86, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 187, 0, 0, 0, 0, 131, 0, 0, 145, + 98, 97, 106, 0, 0, 0, 89, 0, 137, 127, + 157, 0, 128, 136, 110, 149, 132, 156, 188, 164, + 147, 163, 78, 146, 155, 87, 139, 80, 153, 144, + 116, 102, 103, 79, 0, 135, 92, 96, 91, 124, + 150, 151, 90, 171, 83, 162, 82, 84, 161, 123, + 148, 154, 117, 114, 81, 152, 115, 113, 105, 94, + 99, 129, 112, 130, 100, 120, 119, 121, 0, 0, + 0, 143, 159, 172, 0, 0, 165, 166, 167, 168, + 0, 0, 0, 122, 85, 101, 140, 104, 111, 134, + 170, 126, 138, 88, 158, 141, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 125, 77, 0, 108, 169, 133, 95, 160, + 550, 93, 0, 0, 0, 0, 107, 0, 109, 0, + 0, 142, 118, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 185, 0, 0, 0, 0, 0, 0, 0, 0, 86, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 187, 0, 0, 0, 0, + 131, 0, 0, 145, 98, 97, 106, 0, 0, 0, + 89, 0, 137, 127, 157, 0, 128, 136, 110, 149, + 132, 156, 188, 164, 147, 163, 78, 146, 155, 87, + 139, 80, 153, 144, 116, 102, 103, 79, 0, 135, + 92, 96, 91, 124, 150, 151, 90, 171, 83, 162, + 82, 84, 161, 123, 148, 154, 117, 114, 81, 152, + 115, 113, 105, 94, 99, 129, 112, 130, 100, 120, + 119, 121, 0, 0, 0, 143, 159, 172, 0, 0, + 165, 166, 167, 168, 0, 0, 0, 122, 85, 101, + 140, 104, 111, 134, 170, 126, 138, 88, 158, 141, + 0, 0, 0, 0, 0, 0, 0, 0, 301, 0, + 0, 0, 0, 0, 0, 125, 0, 77, 0, 108, + 169, 133, 95, 160, 93, 0, 0, 0, 0, 107, + 0, 109, 0, 0, 142, 118, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 185, 0, 0, 0, 0, 0, 0, + 0, 0, 86, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 187, 0, + 0, 0, 0, 131, 0, 0, 145, 98, 97, 106, + 0, 0, 0, 89, 0, 137, 127, 157, 0, 128, + 136, 110, 149, 132, 156, 188, 164, 147, 163, 78, + 146, 155, 87, 139, 80, 153, 144, 116, 102, 103, + 79, 0, 135, 92, 96, 91, 124, 150, 151, 90, + 171, 83, 162, 82, 84, 161, 123, 148, 154, 117, + 114, 81, 152, 115, 113, 105, 94, 99, 129, 112, + 130, 100, 120, 119, 121, 0, 0, 0, 143, 159, + 172, 0, 0, 165, 166, 167, 168, 0, 0, 0, + 122, 85, 101, 140, 104, 111, 134, 170, 126, 138, + 88, 158, 141, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 125, 0, + 77, 0, 108, 169, 133, 95, 160, 93, 0, 0, + 0, 0, 107, 0, 109, 0, 0, 142, 118, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 185, 0, 0, 0, + 0, 0, 0, 0, 0, 86, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 182, + 0, 187, 0, 0, 0, 0, 131, 0, 0, 145, + 98, 97, 106, 0, 0, 0, 89, 0, 137, 127, + 157, 0, 128, 136, 110, 149, 132, 156, 188, 164, + 147, 163, 78, 146, 155, 87, 139, 80, 153, 144, + 116, 102, 103, 79, 0, 135, 92, 96, 91, 124, + 150, 151, 90, 171, 83, 162, 82, 84, 161, 123, + 148, 154, 117, 114, 81, 152, 115, 113, 105, 94, + 99, 129, 112, 130, 100, 120, 119, 121, 0, 0, + 0, 143, 159, 172, 0, 0, 165, 166, 167, 168, + 0, 0, 0, 122, 85, 101, 140, 104, 111, 134, + 170, 126, 138, 88, 158, 141, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 125, 0, 77, 0, 108, 169, 133, 95, 160, + 93, 0, 0, 0, 0, 107, 0, 109, 0, 0, + 142, 118, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 75, + 0, 0, 0, 0, 0, 0, 0, 0, 86, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 187, 0, 0, 0, 0, 131, + 0, 0, 145, 98, 97, 106, 0, 0, 0, 89, + 0, 137, 127, 157, 0, 128, 136, 110, 149, 132, + 156, 188, 164, 147, 163, 78, 146, 155, 87, 139, + 80, 153, 144, 116, 102, 103, 79, 0, 135, 92, + 96, 91, 124, 150, 151, 90, 171, 83, 162, 82, + 84, 161, 123, 148, 154, 117, 114, 81, 152, 115, + 113, 105, 94, 99, 129, 112, 130, 100, 120, 119, + 121, 0, 0, 0, 143, 159, 172, 0, 0, 165, + 166, 167, 168, 0, 0, 0, 122, 85, 101, 140, + 104, 111, 134, 170, 126, 138, 88, 158, 141, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 125, 0, 77, 0, 108, 169, + 133, 95, 160, 93, 0, 0, 0, 0, 107, 0, + 109, 0, 0, 142, 118, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 238, 0, 0, 0, 0, 0, 0, 0, + 0, 86, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 187, 0, 0, + 0, 0, 131, 0, 0, 145, 98, 97, 106, 0, + 0, 0, 89, 0, 137, 127, 157, 0, 128, 136, + 110, 149, 132, 156, 188, 164, 147, 163, 78, 146, + 155, 87, 139, 80, 153, 144, 116, 102, 103, 79, + 0, 135, 92, 96, 91, 124, 150, 151, 90, 171, + 83, 162, 82, 84, 161, 123, 148, 154, 117, 114, + 81, 152, 115, 113, 105, 94, 99, 129, 112, 130, + 100, 120, 119, 121, 0, 0, 0, 143, 159, 172, + 0, 0, 165, 166, 167, 168, 0, 0, 0, 122, + 85, 101, 140, 104, 111, 134, 170, 126, 138, 88, + 158, 141, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 125, 0, 77, + 0, 108, 169, 133, 95, 160, 93, 0, 0, 0, + 0, 107, 0, 109, 0, 0, 142, 118, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 185, 0, 0, 0, 0, + 0, 0, 0, 0, 86, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 187, 0, 0, 0, 0, 131, 0, 0, 145, 98, + 97, 106, 0, 0, 0, 89, 0, 137, 127, 157, + 0, 128, 136, 110, 149, 132, 156, 188, 164, 147, + 163, 78, 146, 155, 87, 139, 80, 153, 144, 116, + 102, 103, 79, 0, 135, 92, 96, 91, 124, 150, + 151, 90, 171, 83, 162, 82, 84, 161, 123, 148, + 154, 117, 114, 81, 152, 115, 113, 105, 94, 99, + 129, 112, 130, 100, 120, 119, 121, 0, 0, 0, + 143, 159, 172, 0, 0, 165, 166, 167, 168, 0, + 0, 0, 122, 85, 101, 140, 104, 111, 134, 170, + 126, 138, 88, 158, 141, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 77, 0, 108, 169, 133, 95, 160, +} +var yyPact = [...]int{ + + 1723, -1000, -186, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, 802, 836, -1000, -1000, -1000, -1000, -1000, -1000, 618, + 7335, 41, 62, -18, 10030, 61, 1367, 10699, -1000, -6, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, 593, -1000, -1000, + -1000, -1000, -1000, 776, 799, 647, 803, 702, -1000, 5512, + 40, 8914, 9807, 4816, -1000, 484, 59, 10699, -158, 10253, + 34, 34, 34, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, 51, 10699, -1000, 10699, 33, 481, 33, + 33, 33, 10699, -1000, 101, -1000, -1000, -1000, -1000, 10699, + 478, 733, 22, 2856, 2856, 2856, 2856, 1, 2856, -83, + 655, -1000, -1000, -1000, -1000, 2856, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, 364, 739, 6211, 6211, + 802, -1000, 593, -1000, -1000, -1000, 729, -1000, -1000, 243, + 822, -1000, 7112, 99, -1000, 6211, 1819, 429, -1000, -1000, + 429, -1000, -1000, 81, -1000, -1000, 6657, 6657, 6657, 6657, + 6657, 6657, 6657, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, 429, -1000, 5979, + 429, 429, 429, 429, 429, 429, 429, 429, 6211, 429, + 429, 429, 429, 429, 429, 429, 429, 429, 429, 429, + 429, 429, 9584, 587, 874, -1000, -1000, -1000, 767, 8013, + 8691, 10699, 531, -1000, 589, 4571, -121, -1000, -1000, -1000, + 173, 8459, -1000, -1000, -1000, 731, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 477, + -1000, 1856, 472, 2856, 50, 606, 470, 223, 453, 10699, + 10699, 2856, 44, 10699, 757, 653, 10699, 452, 440, -1000, + 4326, -1000, 2856, 2856, 2856, 2856, 2856, 2856, 2856, 2856, + -1000, -1000, -1000, -1000, -1000, -1000, 2856, 2856, -1000, -67, + -1000, 10699, -1000, -1000, -1000, -1000, 831, 130, 525, 95, + 591, -1000, 278, 776, 364, 702, 8236, 665, -1000, -1000, + 10699, -1000, 6211, 6211, 286, -1000, 9360, -1000, -1000, 3346, + 147, 6657, 284, 237, 6657, 6657, 6657, 6657, 6657, 6657, + 6657, 6657, 6657, 6657, 6657, 6657, 6657, 6657, 6657, 327, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 438, -1000, + 593, 725, 725, 113, 113, 113, 113, 113, 113, 6880, + 5048, 364, 437, 180, 5979, 5512, 5512, 6211, 6211, 10476, + 10476, 5512, 769, 203, 180, 10476, -1000, 364, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, 5512, 5512, 5512, 5512, 14, + 10699, -1000, 10476, 8914, 8914, 8914, 8914, 8914, -1000, 679, + 678, -1000, 688, 685, 694, 10699, -1000, 433, 8013, 125, + 429, -1000, 9137, -1000, -1000, 14, 568, 8914, 10699, -1000, + -1000, 4081, 589, -121, 581, -1000, -98, -97, 5744, 110, + -1000, -1000, -1000, -1000, 2611, 188, 273, -66, -1000, -1000, + -1000, 595, -1000, 595, 595, 595, 595, -33, -33, -33, + -33, -1000, -1000, -1000, -1000, -1000, 617, 614, -1000, 595, + 595, 595, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 613, 613, + 613, 597, 597, 622, -1000, 10699, -174, 430, 2856, 756, + 2856, -1000, 70, -1000, 10699, -1000, -1000, 10699, 2856, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, 208, -1000, -1000, -1000, -1000, 695, + 6211, 6211, 3836, 6211, -1000, -1000, -1000, 739, -1000, 769, + 810, -1000, 722, 720, 5512, -1000, -1000, 147, 156, -1000, + -1000, 328, -1000, -1000, -1000, -1000, 94, 429, -1000, 1907, + -1000, -1000, -1000, -1000, 284, 6657, 6657, 6657, 1409, 1907, + 1872, 405, 357, 113, 612, 612, 112, 112, 112, 112, + 112, 910, 910, -1000, -1000, -1000, 364, -1000, -1000, -1000, + 364, 5512, 582, -1000, -1000, 6211, -1000, 364, 426, 426, + 289, 334, 626, -1000, 91, 619, 426, 5512, 218, -1000, + 6211, 364, -1000, 426, 364, 426, 426, 544, 429, -1000, + 564, -1000, 172, 874, 605, 652, 650, -1000, -1000, -1000, + -1000, 675, -1000, 636, -1000, -1000, -1000, -1000, -1000, 58, + 57, 56, 10253, -1000, 818, 8914, 521, -1000, -1000, 581, + -121, -100, -1000, -1000, -1000, 180, -1000, 428, 530, 2366, + -1000, -1000, -1000, -1000, -1000, -1000, 601, 749, 145, 137, + 427, -1000, -1000, 736, -1000, 238, -69, -1000, -1000, 292, + -33, -33, -1000, -1000, 110, 730, 110, 110, 110, 343, + 343, -1000, -1000, -1000, -1000, 280, -1000, -1000, -1000, 277, + -1000, 637, 10253, 2856, -1000, 3591, -1000, -1000, -1000, -1000, + -1000, -1000, 282, 204, 179, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, 13, -1000, 2856, -1000, + 209, 10699, 10699, 709, 180, 180, 79, -1000, -1000, 10699, + -1000, -1000, -1000, -1000, 610, -1000, -1000, -1000, 3101, 5512, + -1000, 1409, 1907, 1606, -1000, 6657, 6657, -1000, -1000, 426, + 5512, 180, -1000, -1000, -1000, 54, 327, 54, 6657, 6657, + 3836, 6657, 6657, -168, 532, 187, -1000, 6211, 307, -1000, + -1000, -1000, -1000, -1000, 635, 10476, 429, -1000, 7790, 10253, + 802, 10476, 6211, 6211, -1000, -1000, 6211, 599, -1000, 6211, + -1000, -1000, -1000, 429, 429, 429, 389, -1000, 802, 521, + -1000, -1000, -1000, -130, -132, -1000, -1000, 2611, -1000, 2611, + 10253, -1000, 367, 350, -1000, -1000, 625, 28, -1000, -1000, + -1000, 423, 110, 110, -1000, 155, -1000, -1000, -1000, 420, + -1000, 416, 526, 410, 10699, -1000, -1000, 516, -1000, 165, + -1000, -1000, 10253, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, 10253, 10699, -1000, -1000, -1000, + -1000, -1000, 10253, -1000, -1000, 341, 6211, -1000, -1000, -1000, + 3591, -1000, 818, 8914, -1000, -1000, 364, -1000, 6657, 1907, + 1907, -1000, -1000, 364, 595, 595, -1000, 595, 597, -1000, + 595, -15, 595, -16, 364, 364, 1524, 1728, -1000, 422, + 1553, 429, -165, -1000, 180, 6211, -1000, 732, 490, 498, + -1000, -1000, 5280, 364, 391, 77, 389, 776, -1000, 180, + 180, 180, 10253, 180, 10253, 10253, 10253, 7567, 10253, 776, + -1000, -1000, -1000, -1000, 2366, -1000, 387, -1000, 595, -1000, + -1000, -60, 828, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -33, 340, -33, 259, -1000, 257, + 2856, 3591, 2611, -1000, 594, -1000, -1000, -1000, -1000, 741, + -1000, 180, 815, 513, -1000, 1907, -1000, -1000, 86, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 6657, 6657, + -1000, 6657, 6657, 6657, 364, 322, 180, 748, -1000, 429, + -1000, -1000, 560, 10253, 10253, -1000, -1000, 377, -1000, 371, + 371, 371, 125, -1000, -1000, 107, 10253, -1000, 133, -1000, + -147, 110, -1000, 110, 417, 406, -1000, -1000, -1000, 10253, + 429, 805, 779, -1000, -1000, 1509, 1509, 1509, 1509, 16, + -1000, -1000, 826, -1000, 429, -1000, 593, 73, -1000, 10253, + -1000, -1000, -1000, -1000, -1000, 107, -1000, 347, 160, 317, + -1000, 239, 747, -1000, 738, -1000, -1000, -1000, -1000, -1000, + 363, 12, -1000, 6211, 6211, -1000, -1000, -1000, -1000, 364, + 49, -178, 10476, 498, 364, 10253, -1000, -1000, -1000, 256, + -1000, -1000, -1000, 316, -1000, -1000, 606, 361, -1000, 10253, + 180, 494, -1000, 706, -171, -181, 435, -1000, -1000, -1000, + -1000, -174, -1000, 12, 715, -1000, 705, -1000, -1000, -1000, + 9, -175, 4, -179, 429, -182, 6434, -1000, 1509, 364, + -1000, -1000, +} +var yyPgo = [...]int{ + + 0, 1069, 13, 493, 1068, 1067, 1063, 1059, 1058, 1056, + 1055, 1053, 1052, 1047, 1045, 1044, 1042, 1040, 1039, 1037, + 1036, 1035, 1033, 1032, 104, 1031, 1027, 1026, 57, 1025, + 63, 1024, 1022, 33, 225, 45, 30, 150, 1018, 31, + 54, 84, 1017, 35, 1016, 1014, 70, 1013, 51, 1000, + 999, 1293, 998, 995, 19, 41, 993, 991, 990, 989, + 60, 312, 988, 987, 985, 982, 981, 979, 39, 5, + 7, 12, 11, 978, 127, 15, 976, 55, 975, 974, + 973, 971, 25, 970, 46, 965, 21, 40, 964, 16, + 53, 28, 23, 2, 65, 47, 962, 27, 50, 38, + 961, 958, 367, 948, 944, 942, 940, 936, 934, 140, + 309, 932, 931, 930, 928, 32, 167, 466, 73, 58, + 927, 926, 925, 1239, 59, 52, 22, 924, 36, 1247, + 42, 912, 910, 29, 909, 908, 897, 895, 894, 893, + 892, 264, 890, 889, 887, 17, 20, 882, 881, 49, + 26, 878, 877, 876, 34, 37, 874, 44, 873, 872, + 867, 866, 24, 10, 865, 9, 862, 8, 860, 856, + 4, 853, 18, 852, 3, 851, 6, 43, 850, 847, + 0, 323, 844, 843, 105, +} +var yyR1 = [...]int{ + + 0, 178, 179, 179, 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, 27, 27, 8, 9, 9, 9, 182, + 182, 46, 46, 90, 90, 10, 10, 10, 10, 95, + 95, 99, 99, 99, 100, 100, 100, 100, 131, 131, + 11, 11, 11, 11, 11, 11, 11, 176, 176, 175, + 174, 174, 173, 173, 172, 16, 159, 160, 160, 160, + 155, 134, 134, 134, 134, 137, 137, 135, 135, 135, + 135, 135, 135, 135, 136, 136, 136, 136, 136, 138, + 138, 138, 138, 138, 139, 139, 139, 139, 139, 139, + 139, 139, 139, 139, 139, 139, 139, 139, 139, 140, + 140, 140, 140, 140, 140, 140, 140, 154, 154, 141, + 141, 149, 149, 150, 150, 150, 147, 147, 148, 148, + 151, 151, 151, 142, 142, 142, 142, 142, 142, 142, + 144, 144, 152, 152, 145, 145, 145, 146, 146, 153, + 153, 153, 153, 153, 143, 143, 156, 156, 168, 168, + 167, 167, 167, 158, 158, 164, 164, 164, 164, 164, + 157, 157, 166, 166, 165, 161, 161, 161, 162, 162, + 162, 163, 163, 163, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 177, 177, 177, 177, 177, 177, 177, + 177, 177, 177, 177, 171, 169, 169, 170, 170, 13, + 14, 14, 14, 14, 14, 15, 15, 17, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 107, 107, 104, 104, 105, 105, 106, 106, 106, + 108, 108, 108, 132, 132, 132, 19, 19, 21, 21, + 22, 23, 20, 20, 20, 20, 20, 183, 24, 25, + 25, 26, 26, 26, 30, 30, 30, 28, 28, 29, + 29, 35, 35, 34, 34, 36, 36, 36, 36, 120, + 120, 120, 119, 119, 38, 38, 39, 39, 40, 40, + 41, 41, 41, 53, 53, 89, 89, 91, 91, 42, + 42, 42, 42, 43, 43, 44, 44, 45, 45, 127, + 127, 126, 126, 126, 125, 125, 47, 47, 47, 49, + 48, 48, 48, 48, 50, 50, 52, 52, 51, 51, + 54, 54, 54, 54, 55, 55, 37, 37, 37, 37, + 37, 37, 37, 103, 103, 57, 57, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 67, 67, 67, + 67, 67, 67, 58, 58, 58, 58, 58, 58, 58, + 33, 33, 68, 68, 68, 74, 69, 69, 61, 61, + 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, + 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, + 61, 61, 61, 61, 61, 61, 61, 61, 61, 65, + 65, 65, 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 64, 64, 64, + 64, 64, 64, 64, 64, 184, 184, 66, 66, 66, + 66, 31, 31, 31, 31, 31, 130, 130, 133, 133, + 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, + 133, 78, 78, 32, 32, 76, 76, 77, 79, 79, + 75, 75, 75, 60, 60, 60, 60, 60, 60, 60, + 60, 62, 62, 62, 80, 80, 81, 81, 82, 82, + 83, 83, 84, 85, 85, 85, 86, 86, 86, 86, + 87, 87, 87, 59, 59, 59, 59, 59, 59, 88, + 88, 88, 88, 92, 92, 70, 70, 72, 72, 71, + 73, 93, 93, 97, 94, 94, 98, 98, 98, 96, + 96, 96, 122, 122, 122, 101, 101, 109, 109, 110, + 110, 102, 102, 111, 111, 111, 111, 111, 111, 111, + 111, 111, 111, 112, 112, 112, 113, 113, 114, 114, + 114, 121, 121, 117, 117, 118, 118, 123, 123, 124, + 124, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 116, 116, 116, 116, 116, 116, 116, + 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, + 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, + 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, + 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, + 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, + 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, + 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, + 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, + 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, + 116, 180, 181, 128, 129, 129, 129, +} +var yyR2 = [...]int{ + + 0, 2, 0, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 4, 6, 7, 5, 10, 1, 3, 1, + 3, 7, 8, 1, 1, 8, 8, 7, 6, 1, + 1, 1, 3, 0, 4, 3, 4, 5, 4, 1, + 3, 3, 2, 2, 2, 2, 2, 1, 1, 1, + 2, 8, 4, 6, 5, 5, 5, 0, 2, 1, + 0, 2, 1, 3, 3, 4, 4, 1, 3, 3, + 8, 3, 1, 1, 1, 2, 1, 1, 1, 1, + 1, 1, 1, 1, 2, 2, 2, 2, 2, 1, + 2, 2, 2, 1, 4, 4, 2, 2, 3, 3, + 3, 3, 1, 1, 1, 1, 1, 6, 6, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 3, 0, + 3, 0, 5, 0, 3, 5, 0, 1, 0, 1, + 0, 1, 2, 0, 2, 2, 2, 2, 2, 2, + 0, 3, 0, 1, 0, 3, 3, 0, 2, 0, + 2, 1, 2, 1, 0, 2, 5, 4, 1, 2, + 2, 3, 2, 0, 1, 2, 3, 3, 2, 2, + 1, 1, 1, 3, 2, 0, 1, 3, 1, 2, + 3, 1, 1, 1, 6, 7, 7, 12, 7, 7, + 7, 4, 5, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 7, 1, 3, 8, 8, 5, + 4, 6, 5, 4, 4, 3, 2, 3, 4, 4, + 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, + 4, 3, 6, 4, 2, 4, 2, 2, 2, 2, + 3, 1, 1, 0, 1, 0, 1, 0, 2, 2, + 0, 2, 2, 0, 1, 1, 2, 1, 1, 2, + 1, 1, 2, 2, 2, 2, 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, 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, + 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, 3, 1, 1, 1, 1, 4, + 5, 6, 4, 4, 6, 6, 6, 6, 8, 8, + 6, 8, 8, 9, 7, 5, 4, 2, 2, 2, + 2, 2, 2, 2, 2, 0, 2, 4, 4, 4, + 4, 0, 3, 4, 7, 3, 1, 1, 2, 3, + 3, 1, 2, 2, 1, 2, 1, 2, 2, 1, + 2, 0, 1, 0, 2, 1, 2, 4, 0, 2, + 1, 3, 5, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 2, 2, 0, 3, 0, 2, 0, 3, + 1, 3, 2, 0, 1, 1, 0, 2, 4, 4, + 0, 2, 4, 2, 1, 3, 5, 4, 6, 1, + 3, 3, 5, 0, 5, 1, 3, 1, 2, 3, + 1, 1, 3, 3, 1, 3, 3, 3, 3, 1, + 2, 1, 1, 1, 1, 1, 1, 0, 2, 0, + 3, 0, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, + 1, 0, 2, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 0, 0, 1, 1, +} +var yyChk = [...]int{ + + -1000, -178, -1, -2, -6, -7, -8, -9, -10, -11, + -12, -13, -14, -15, -17, -18, -19, -21, -22, -23, + -20, -3, -4, 6, 7, -27, 9, 10, 30, -16, + 112, 113, 115, 114, 140, 116, 133, 49, 152, 153, + 155, 156, 25, 134, 135, 138, 139, -180, 8, 235, + 53, -179, 250, -82, 15, -26, 5, -24, -183, -24, + -24, -24, -24, -24, -159, 53, -114, 121, 70, 148, + 227, 118, 119, 125, -117, 56, -116, 243, 152, 163, + 157, 184, 176, 174, 177, 214, 65, 155, 223, 136, + 172, 168, 166, 27, 189, 248, 167, 131, 130, 190, + 194, 215, 161, 162, 217, 188, 132, 32, 245, 34, + 144, 218, 192, 187, 183, 186, 160, 182, 38, 196, + 195, 197, 213, 179, 169, 18, 221, 139, 142, 191, + 193, 126, 146, 247, 219, 165, 143, 138, 222, 156, + 216, 225, 37, 201, 159, 129, 153, 150, 180, 145, + 170, 171, 185, 158, 181, 154, 147, 140, 224, 202, + 249, 178, 175, 151, 149, 206, 207, 208, 209, 246, + 220, 173, 203, -102, 121, 123, 119, 119, 120, 121, + 227, 118, 119, -51, -123, 56, -116, 121, 148, 119, + 106, 177, 112, 204, 120, 32, 146, -132, 119, -104, + 149, 206, 207, 208, 209, 56, 216, 215, 210, -123, + 154, -128, -128, -128, -128, -128, -2, -86, 17, 16, + -5, -3, -180, 6, 20, 21, -30, 39, 40, -25, + -36, 97, -37, -123, -56, 72, -61, 29, 56, -116, + 23, -60, -57, -75, -73, -74, 106, 107, 95, 96, + 103, 73, 108, -65, -63, -64, -66, 58, 57, 66, + 59, 60, 61, 62, 67, 68, 69, -117, -71, -180, + 43, 44, 236, 237, 238, 239, 242, 240, 75, 33, + 226, 234, 233, 232, 230, 231, 228, 229, 124, 227, + 101, 235, -102, -39, -40, -41, -42, -53, -74, -180, + -51, 11, -46, -51, -94, -131, 154, -98, 216, 215, + -118, -96, -117, -115, 214, 177, 213, 117, 71, 22, + 24, 199, 74, 106, 16, 75, 105, 236, 112, 47, + 228, 229, 226, 238, 239, 227, 204, 29, 10, 25, + 134, 21, 99, 114, 78, 79, 137, 23, 135, 69, + 19, 50, 11, 13, 14, 124, 123, 90, 120, 45, + 8, 108, 26, 87, 41, 28, 43, 88, 17, 230, + 231, 31, 242, 141, 101, 48, 35, 72, 67, 51, + 70, 15, 46, 89, 115, 235, 44, 118, 6, 241, + 30, 133, 42, 119, 205, 77, 122, 68, 5, 125, + 9, 49, 52, 232, 233, 234, 33, 76, 12, -160, + -155, 56, 120, -51, 235, -117, -110, 124, -110, -110, + 119, -51, -51, -109, 124, 56, -109, -109, -109, -51, + 109, -51, 56, 30, 227, 56, 146, 119, 147, 121, + -129, -180, -118, -129, -129, -129, 150, 151, -129, -105, + 211, 51, -129, -181, 55, -87, 19, 31, -37, -123, + -83, -84, -37, -82, -2, -24, 35, -28, 21, 64, + 11, -120, 71, 70, 87, -119, 22, -117, 58, 109, + -37, -58, 90, 72, 88, 89, 74, 92, 91, 102, + 95, 96, 97, 98, 99, 100, 101, 93, 94, 105, + 80, 81, 82, 83, 84, 85, 86, -103, -180, -74, + -180, 110, 111, -61, -61, -61, -61, -61, -61, -61, + -180, -2, -69, -37, -180, -180, -180, -180, -180, -180, + -180, -180, -180, -78, -37, -180, -184, -180, -184, -184, + -184, -184, -184, -184, -184, -180, -180, -180, -180, -52, + 26, -51, 30, 54, -47, -49, -48, -50, 41, 45, + 47, 42, 43, 44, 48, -127, 22, -39, -180, -126, + 142, -125, 22, -123, 58, -51, -46, -182, 54, 11, + 52, 54, -94, 154, -95, -99, 217, 219, 80, -122, + -117, 58, 29, 30, 55, 54, -134, -137, -139, -138, + -140, -135, -136, 174, 175, 106, 178, 180, 181, 182, + 183, 184, 185, 186, 187, 188, 189, 30, 136, 170, + 171, 172, 173, 190, 191, 192, 193, 194, 195, 196, + 197, 157, 158, 159, 160, 161, 162, 163, 165, 166, + 167, 168, 169, 56, -129, 121, -176, 52, 56, 72, + 56, -51, -51, -129, 122, -51, 23, 51, -51, 56, + 56, -124, -123, -115, -129, -129, -129, -129, -129, -129, + -129, -129, -129, -129, -107, 205, 212, -51, 9, 90, + 54, 18, 109, 54, -85, 24, 25, -86, -181, -30, + -62, -117, 59, 62, -29, 42, -51, -37, -37, -67, + 67, 72, 68, 69, -119, 97, -124, -118, -115, -61, + -68, -71, -74, 63, 90, 88, 89, 74, -61, -61, + -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, + -61, -61, -61, -130, 56, 58, 56, -60, -60, -117, + -35, 21, -34, -36, -181, 54, -181, -2, -34, -34, + -37, -37, -75, -117, -123, -75, -34, -28, -76, -77, + 76, -75, -181, -34, -35, -34, -34, -90, 142, -51, + -93, -97, -75, -40, -41, -41, -40, -41, 41, 41, + 41, 46, 41, 46, 41, -48, -123, -181, -54, 49, + 123, 50, -180, -125, -90, 52, -39, -51, -98, -95, + 54, 218, 220, 221, 51, -37, -146, 105, -161, -162, + -163, -118, 58, 59, -155, -156, -164, 126, 129, 125, + -157, 120, 28, -151, 67, 72, -147, 202, -141, 53, + -141, -141, -141, -141, -145, 177, -145, -145, -145, 53, + 53, -141, -141, -141, -149, 53, -149, -149, -150, 53, + -150, -121, 52, -51, -174, 246, -175, 56, -129, 23, + -129, -111, 117, 114, 115, -171, 113, 199, 177, 65, + 29, 15, 236, 142, 249, 56, 143, -51, -51, -129, + -106, 11, 90, 37, -37, -37, -124, -84, -87, -101, + 19, 11, 33, 33, -34, 67, 68, 69, 109, -180, + -68, -61, -61, -61, -33, 137, 71, -181, -181, -34, + 54, -37, -181, -181, -181, 54, 52, 22, 54, 11, + 109, 54, 11, -181, -34, -79, -77, 78, -37, -181, + -181, -181, -181, -181, -59, 30, 33, -2, -180, -180, + -55, 54, 12, 80, -44, -43, 51, 52, -45, 51, + -43, 41, 41, 120, 120, 120, -91, -117, -55, -39, + -55, -99, -100, 222, 219, 225, 56, 54, -163, 80, + 53, 28, -157, -157, 56, 56, -142, 29, 67, -148, + 203, 59, -145, -145, -146, 30, -146, -146, -146, -154, + 58, -154, 59, 59, 51, -117, -129, -173, -172, -118, + -128, -177, 148, 127, 128, 131, 130, 56, 120, 28, + 126, 129, 142, 125, -177, 148, -112, -113, 122, 22, + 120, 28, 142, -129, -108, 88, 12, -123, -123, 38, + 109, -51, -38, 11, 97, -118, -35, -33, 71, -61, + -61, -181, -36, -133, 106, 174, 136, 172, 168, 188, + 179, 201, 170, 202, -130, -133, -61, -61, -118, -61, + -61, 243, -82, 79, -37, 77, -92, 51, -93, -70, + -72, -71, -180, -2, -88, -117, -91, -82, -97, -37, + -37, -37, 53, -37, -180, -180, -180, -181, 54, -82, + -55, 219, 223, 224, -162, -163, -166, -165, -117, 56, + 56, -144, 51, 58, 59, 60, 67, 226, 66, 55, + -146, -146, 56, 106, 55, 54, 55, 54, 55, 54, + -51, 54, 80, -128, -117, -128, -117, -51, -128, -117, + 58, -37, -55, -39, -181, -61, -181, -141, -141, -141, + -150, -141, 162, -141, 162, -181, -181, -181, 54, 19, + -181, 54, 19, -180, -32, 241, -37, 27, -92, 54, + -181, -181, -181, 54, 109, -181, -86, -89, -117, -89, + -89, -89, -126, -117, -86, 55, 54, -141, -152, 199, + 9, -145, 58, -145, 59, 59, -129, -172, -163, 53, + 26, -80, 13, -145, 56, -61, -61, -61, -61, -61, + -181, 58, 28, -72, 33, -2, -180, -117, -117, 54, + 55, -181, -181, -181, -54, -168, -167, 52, 132, 65, + -165, -153, 126, 28, 125, 226, -146, -146, 55, 55, + -89, -180, -81, 14, 16, -181, -181, -181, -181, -31, + 90, 246, 9, -70, -2, 109, -117, -167, 56, -158, + 80, 58, -143, 65, 28, 28, 55, -169, -170, 142, + -37, -69, -181, 244, 48, 247, -93, -181, -117, 59, + 58, -176, -181, 54, -117, 38, 245, 248, -174, -170, + 33, 38, 144, 246, 145, 247, -180, 248, -61, 141, + -181, -181, +} +var yyDef = [...]int{ + + 0, -2, 2, -2, 5, 6, 7, 8, 9, 10, + 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, + 21, 508, 0, 277, 277, 277, 277, 277, 277, 0, + 578, 561, 0, 0, 0, 0, -2, 267, 268, 0, + 270, 271, 783, 783, 783, 783, 783, 0, 33, 34, + 781, 1, 3, 516, 0, 0, 281, 284, 279, 0, + 561, 0, 0, 0, 60, 0, 0, 770, 0, 771, + 559, 559, 559, 579, 580, 583, 584, 683, 684, 685, + 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, + 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, + 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, + 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, + 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, + 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, + 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, + 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, + 766, 767, 768, 769, 772, 773, 774, 775, 776, 777, + 778, 779, 780, 0, 0, 562, 0, 557, 0, 557, + 557, 557, 0, 226, 348, 587, 588, 770, 771, 0, + 0, 0, 0, 784, 784, 784, 784, 0, 784, 255, + 244, 246, 247, 248, 249, 784, 264, 265, 254, 266, + 269, 272, 273, 274, 275, 276, 27, 520, 0, 0, + 508, 29, 0, 277, 282, 283, 287, 285, 286, 278, + 0, 295, 299, 0, 356, 0, 361, 363, -2, -2, + 0, 398, 399, 400, 401, 402, 0, 0, 0, 0, + 0, 0, 0, 425, 426, 427, 428, 493, 494, 495, + 496, 497, 498, 499, 500, 365, 366, 490, 540, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 481, 0, + 455, 455, 455, 455, 455, 455, 455, 455, 0, 0, + 0, 0, 0, 0, 306, 308, 309, 310, 329, 0, + 331, 0, 0, 41, 45, 0, 761, 544, -2, -2, + 0, 0, 585, 586, -2, 690, -2, 591, 592, 593, + 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, + 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, + 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, + 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, + 634, 635, 636, 637, 638, 639, 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, 0, + 77, 0, 0, 784, 0, 67, 0, 0, 0, 0, + 0, 784, 0, 0, 0, 0, 0, 0, 0, 225, + 0, 227, 784, 784, 784, 784, 784, 784, 784, 784, + 236, 785, 786, 237, 238, 239, 784, 784, 241, 0, + 256, 0, 250, 28, 782, 22, 0, 0, 517, 0, + 509, 510, 513, 516, 27, 284, 0, 289, 288, 280, + 0, 296, 0, 0, 0, 300, 0, 302, 303, 0, + 359, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 383, 384, 385, 386, 387, 388, 389, 362, 0, 376, + 0, 0, 0, 418, 419, 420, 421, 422, 423, 0, + 291, 27, 0, 396, 0, 0, 0, 0, 0, 0, + 0, 0, 287, 0, 482, 0, 447, 0, 448, 449, + 450, 451, 452, 453, 454, 0, 291, 0, 0, 43, + 0, 347, 0, 0, 0, 0, 0, 0, 336, 0, + 0, 339, 0, 0, 0, 0, 330, 0, 0, 350, + 734, 332, 0, 334, 335, -2, 0, 0, 0, 39, + 40, 0, 46, 761, 48, 49, 0, 0, 0, 157, + 552, 553, 554, 550, 185, 0, 140, 136, 82, 83, + 84, 129, 86, 129, 129, 129, 129, 154, 154, 154, + 154, 112, 113, 114, 115, 116, 0, 0, 99, 129, + 129, 129, 103, 119, 120, 121, 122, 123, 124, 125, + 126, 87, 88, 89, 90, 91, 92, 93, 131, 131, + 131, 133, 133, 581, 62, 0, 70, 0, 784, 0, + 784, 75, 0, 201, 0, 220, 558, 0, 784, 223, + 224, 349, 589, 590, 228, 229, 230, 231, 232, 233, + 234, 235, 240, 243, 257, 251, 252, 245, 521, 0, + 0, 0, 0, 0, 512, 514, 515, 520, 30, 287, + 0, 501, 0, 0, 0, 290, 25, 357, 358, 360, + 377, 0, 379, 381, 301, 297, 0, 491, -2, 367, + 368, 392, 393, 394, 0, 0, 0, 0, 390, 372, + 0, 403, 404, 405, 406, 407, 408, 409, 410, 411, + 412, 413, 414, 417, 466, 467, 0, 415, 416, 424, + 0, 0, 292, 293, 395, 0, 539, 27, 0, 0, + 0, 0, 0, 490, 0, 0, 0, 0, 488, 485, + 0, 0, 456, 0, 0, 0, 0, 0, 0, 346, + 354, 541, 0, 307, 325, 327, 0, 322, 337, 338, + 340, 0, 342, 0, 344, 345, 311, 312, 313, 0, + 0, 0, 0, 333, 354, 0, 354, 42, 545, 47, + 0, 0, 52, 53, 546, 547, 548, 0, 76, 186, + 188, 191, 192, 193, 78, 79, 0, 0, 0, 0, + 0, 180, 181, 143, 141, 0, 138, 137, 85, 0, + 154, 154, 106, 107, 157, 0, 157, 157, 157, 0, + 0, 100, 101, 102, 94, 0, 95, 96, 97, 0, + 98, 0, 0, 784, 64, 0, 68, 69, 65, 560, + 66, 783, 0, 0, 573, 202, 563, 564, 565, 566, + 567, 568, 569, 570, 571, 572, 0, 219, 784, 222, + 260, 0, 0, 0, 518, 519, 0, 511, 23, 0, + 555, 556, 502, 503, 304, 378, 380, 382, 0, 291, + 369, 390, 373, 0, 370, 0, 0, 364, 429, 0, + 0, 397, -2, 432, 433, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 508, 0, 486, 0, 0, 446, + 457, 458, 459, 460, 533, 0, 0, -2, 0, 0, + 508, 0, 0, 0, 319, 326, 0, 0, 320, 0, + 321, 341, 343, 0, 0, 0, 0, 317, 508, 354, + 38, 50, 51, 0, 0, 57, 158, 0, 189, 0, + 0, 175, 0, 0, 178, 179, 150, 0, 142, 81, + 139, 0, 157, 157, 108, 0, 109, 110, 111, 0, + 127, 0, 0, 0, 0, 582, 63, 71, 72, 0, + 194, 783, 0, 203, 204, 205, 206, 207, 208, 209, + 210, 211, 212, 213, 783, 0, 0, 783, 574, 575, + 576, 577, 0, 221, 242, 0, 0, 258, 259, 522, + 0, 24, 354, 0, 298, 492, 0, 371, 0, 391, + 374, 430, 294, 0, 129, 129, 471, 129, 133, 474, + 129, 476, 129, 479, 0, 0, 0, 0, 491, 0, + 0, 0, 483, 445, 489, 0, 31, 0, 533, 523, + 535, 537, 0, 27, 0, 529, 0, 516, 542, 355, + 543, 323, 0, 328, 0, 0, 0, 331, 0, 516, + 37, 54, 55, 56, 187, 190, 0, 182, 129, 176, + 177, 152, 0, 144, 145, 146, 147, 148, 149, 130, + 104, 105, 155, 156, 154, 0, 154, 0, 134, 0, + 784, 0, 0, 195, 0, 196, 198, 199, 200, 0, + 261, 262, 504, 305, 431, 375, 434, 468, 154, 472, + 473, 475, 477, 478, 480, 436, 435, 437, 0, 0, + 440, 0, 0, 0, 0, 0, 487, 0, 32, 0, + 538, -2, 0, 0, 0, 44, 35, 0, 315, 0, + 0, 0, 350, 318, 36, 167, 0, 184, 159, 153, + 0, 157, 128, 157, 0, 0, 61, 73, 74, 0, + 0, 506, 0, 469, 470, 0, 0, 0, 0, 461, + 444, 484, 0, 536, 0, -2, 0, 531, 530, 0, + 324, 351, 352, 353, 314, 166, 168, 0, 173, 0, + 183, 164, 0, 161, 163, 151, 117, 118, 132, 135, + 0, 0, 26, 0, 0, 438, 439, 441, 442, 0, + 0, 0, 0, 526, 27, 0, 316, 169, 170, 0, + 174, 172, 80, 0, 160, 162, 67, 0, 215, 0, + 507, 505, 443, 0, 0, 0, 534, -2, 532, 171, + 165, 70, 214, 0, 0, 462, 0, 465, 197, 216, + 0, 463, 0, 0, 0, 0, 0, 464, 0, 0, + 217, 218, +} +var yyTok1 = [...]int{ + + 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 73, 3, 3, 3, 100, 92, 3, + 53, 55, 97, 95, 54, 96, 109, 98, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 250, + 81, 80, 82, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 102, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 91, 3, 103, +} +var yyTok2 = [...]int{ + + 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, + 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, + 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, + 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, + 52, 56, 57, 58, 59, 60, 61, 62, 63, 64, + 65, 66, 67, 68, 69, 70, 71, 72, 74, 75, + 76, 77, 78, 79, 83, 84, 85, 86, 87, 88, + 89, 90, 93, 94, 99, 101, 104, 105, 106, 107, + 108, 110, 111, 112, 113, 114, 115, 116, 117, 118, + 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, + 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, + 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, + 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, + 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, + 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, + 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, + 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, + 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, + 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, + 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, + 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, + 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, + 249, +} +var yyTok3 = [...]int{ + 0, +} + +var yyErrorMessages = [...]struct { + state int + token int + msg string +}{} + +//line yaccpar:1 + +/* parser for yacc output */ + +var ( + yyDebug = 0 + yyErrorVerbose = false +) + +type yyLexer interface { + Lex(lval *yySymType) int + Error(s string) +} + +type yyParser interface { + Parse(yyLexer) int + Lookahead() int +} + +type yyParserImpl struct { + lval yySymType + stack [yyInitialStackSize]yySymType + char int +} + +func (p *yyParserImpl) Lookahead() int { + return p.char +} + +func yyNewParser() yyParser { + return &yyParserImpl{} +} + +const yyFlag = -1000 + +func yyTokname(c int) string { + if c >= 1 && c-1 < len(yyToknames) { + if yyToknames[c-1] != "" { + return yyToknames[c-1] + } + } + return __yyfmt__.Sprintf("tok-%v", c) +} + +func yyStatname(s int) string { + if s >= 0 && s < len(yyStatenames) { + if yyStatenames[s] != "" { + return yyStatenames[s] + } + } + return __yyfmt__.Sprintf("state-%v", s) +} + +func yyErrorMessage(state, lookAhead int) string { + const TOKSTART = 4 + + if !yyErrorVerbose { + return "syntax error" + } + + for _, e := range yyErrorMessages { + if e.state == state && e.token == lookAhead { + return "syntax error: " + e.msg + } + } + + res := "syntax error: unexpected " + yyTokname(lookAhead) + + // To match Bison, suggest at most four expected tokens. + expected := make([]int, 0, 4) + + // Look for shiftable tokens. + base := yyPact[state] + for tok := TOKSTART; tok-1 < len(yyToknames); tok++ { + if n := base + tok; n >= 0 && n < yyLast && yyChk[yyAct[n]] == tok { + if len(expected) == cap(expected) { + return res + } + expected = append(expected, tok) + } + } + + if yyDef[state] == -2 { + i := 0 + for yyExca[i] != -1 || yyExca[i+1] != state { + i += 2 + } + + // Look for tokens that we accept or reduce. + for i += 2; yyExca[i] >= 0; i += 2 { + tok := yyExca[i] + if tok < TOKSTART || yyExca[i+1] == 0 { + continue + } + if len(expected) == cap(expected) { + return res + } + expected = append(expected, tok) + } + + // If the default action is to accept or reduce, give up. + if yyExca[i+1] != 0 { + return res + } + } + + for i, tok := range expected { + if i == 0 { + res += ", expecting " + } else { + res += " or " + } + res += yyTokname(tok) + } + return res +} + +func yylex1(lex yyLexer, lval *yySymType) (char, token int) { + token = 0 + char = lex.Lex(lval) + if char <= 0 { + token = yyTok1[0] + goto out + } + if char < len(yyTok1) { + token = yyTok1[char] + goto out + } + if char >= yyPrivate { + if char < yyPrivate+len(yyTok2) { + token = yyTok2[char-yyPrivate] + goto out + } + } + for i := 0; i < len(yyTok3); i += 2 { + token = yyTok3[i+0] + if token == char { + token = yyTok3[i+1] + goto out + } + } + +out: + if token == 0 { + token = yyTok2[1] /* unknown char */ + } + if yyDebug >= 3 { + __yyfmt__.Printf("lex %s(%d)\n", yyTokname(token), uint(char)) + } + return char, token +} + +func yyParse(yylex yyLexer) int { + return yyNewParser().Parse(yylex) +} + +func (yyrcvr *yyParserImpl) Parse(yylex yyLexer) int { + var yyn int + var yyVAL yySymType + var yyDollar []yySymType + _ = yyDollar // silence set and not used + yyS := yyrcvr.stack[:] + + Nerrs := 0 /* number of errors */ + Errflag := 0 /* error recovery flag */ + yystate := 0 + yyrcvr.char = -1 + yytoken := -1 // yyrcvr.char translated into internal numbering + defer func() { + // Make sure we report no lookahead when not parsing. + yystate = -1 + yyrcvr.char = -1 + yytoken = -1 + }() + yyp := -1 + goto yystack + +ret0: + return 0 + +ret1: + return 1 + +yystack: + /* put a state and value onto the stack */ + if yyDebug >= 4 { + __yyfmt__.Printf("char %v in %v\n", yyTokname(yytoken), yyStatname(yystate)) + } + + yyp++ + if yyp >= len(yyS) { + nyys := make([]yySymType, len(yyS)*2) + copy(nyys, yyS) + yyS = nyys + } + yyS[yyp] = yyVAL + yyS[yyp].yys = yystate + +yynewstate: + yyn = yyPact[yystate] + if yyn <= yyFlag { + goto yydefault /* simple state */ + } + if yyrcvr.char < 0 { + yyrcvr.char, yytoken = yylex1(yylex, &yyrcvr.lval) + } + yyn += yytoken + if yyn < 0 || yyn >= yyLast { + goto yydefault + } + yyn = yyAct[yyn] + if yyChk[yyn] == yytoken { /* valid shift */ + yyrcvr.char = -1 + yytoken = -1 + yyVAL = yyrcvr.lval + yystate = yyn + if Errflag > 0 { + Errflag-- + } + goto yystack + } + +yydefault: + /* default state action */ + yyn = yyDef[yystate] + if yyn == -2 { + if yyrcvr.char < 0 { + yyrcvr.char, yytoken = yylex1(yylex, &yyrcvr.lval) + } + + /* look through exception table */ + xi := 0 + for { + if yyExca[xi+0] == -1 && yyExca[xi+1] == yystate { + break + } + xi += 2 + } + for xi += 2; ; xi += 2 { + yyn = yyExca[xi+0] + if yyn < 0 || yyn == yytoken { + break + } + } + yyn = yyExca[xi+1] + if yyn < 0 { + goto ret0 + } + } + if yyn == 0 { + /* error ... attempt to resume parsing */ + switch Errflag { + case 0: /* brand new error */ + yylex.Error(yyErrorMessage(yystate, yytoken)) + Nerrs++ + if yyDebug >= 1 { + __yyfmt__.Printf("%s", yyStatname(yystate)) + __yyfmt__.Printf(" saw %s\n", yyTokname(yytoken)) + } + fallthrough + + case 1, 2: /* incompletely recovered error ... try again */ + Errflag = 3 + + /* find a state where "error" is a legal shift action */ + for yyp >= 0 { + yyn = yyPact[yyS[yyp].yys] + yyErrCode + if yyn >= 0 && yyn < yyLast { + yystate = yyAct[yyn] /* simulate a shift of "error" */ + if yyChk[yystate] == yyErrCode { + goto yystack + } + } + + /* the current p has no shift on "error", pop stack */ + if yyDebug >= 2 { + __yyfmt__.Printf("error recovery pops state %d\n", yyS[yyp].yys) + } + yyp-- + } + /* there is no state on the stack with an error shift ... abort */ + goto ret1 + + case 3: /* no shift yet; clobber input char */ + if yyDebug >= 2 { + __yyfmt__.Printf("error recovery discards %s\n", yyTokname(yytoken)) + } + if yytoken == yyEofCode { + goto ret1 + } + yyrcvr.char = -1 + yytoken = -1 + goto yynewstate /* try again in the same state */ + } + } + + /* reduction by production yyn */ + if yyDebug >= 2 { + __yyfmt__.Printf("reduce %v in:\n\t%v\n", yyn, yyStatname(yystate)) + } + + yynt := yyn + yypt := yyp + _ = yypt // guard against "declared and not used" + + yyp -= yyR2[yyn] + // yyp is now the index of $0. Perform the default action. Iff the + // reduced production is ε, $1 is possibly out of range. + if yyp+1 >= len(yyS) { + nyys := make([]yySymType, len(yyS)*2) + copy(nyys, yyS) + yyS = nyys + } + yyVAL = yyS[yyp+1] + + /* consult goto table to find next state */ + yyn = yyR1[yyn] + yyg := yyPgo[yyn] + yyj := yyg + yyS[yyp].yys + 1 + + if yyj >= yyLast { + yystate = yyAct[yyg] + } else { + yystate = yyAct[yyj] + if yyChk[yystate] != -yyn { + yystate = yyAct[yyg] + } + } + // dummy call; replaced with literal code + switch yynt { + + case 1: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:302 + { + setParseTree(yylex, yyDollar[1].statement) + } + case 2: + yyDollar = yyS[yypt-0 : yypt+1] + //line sql.y:307 + { + } + case 3: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:308 + { + } + case 4: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:312 + { + yyVAL.statement = yyDollar[1].selStmt + } + case 22: + yyDollar = yyS[yypt-4 : yypt+1] + //line sql.y:335 + { + sel := yyDollar[1].selStmt.(*Select) + sel.OrderBy = yyDollar[2].orderBy + sel.Limit = yyDollar[3].limit + sel.Lock = yyDollar[4].str + yyVAL.selStmt = sel + } + case 23: + yyDollar = yyS[yypt-6 : yypt+1] + //line sql.y:343 + { + yyVAL.selStmt = &Union{Type: yyDollar[2].str, Left: yyDollar[1].selStmt, Right: yyDollar[3].selStmt, OrderBy: yyDollar[4].orderBy, Limit: yyDollar[5].limit, Lock: yyDollar[6].str} + } + case 24: + yyDollar = yyS[yypt-7 : yypt+1] + //line sql.y:347 + { + yyVAL.selStmt = &Select{Comments: Comments(yyDollar[2].bytes2), Cache: yyDollar[3].str, SelectExprs: SelectExprs{Nextval{Expr: yyDollar[5].expr}}, From: TableExprs{&AliasedTableExpr{Expr: yyDollar[7].tableName}}} + } + case 25: + yyDollar = yyS[yypt-5 : yypt+1] + //line sql.y:353 + { + yyVAL.statement = &Stream{Comments: Comments(yyDollar[2].bytes2), SelectExpr: yyDollar[3].selectExpr, Table: yyDollar[5].tableName} + } + case 26: + yyDollar = yyS[yypt-10 : yypt+1] + //line sql.y:360 + { + yyVAL.selStmt = &Select{Comments: Comments(yyDollar[2].bytes2), Cache: yyDollar[3].str, Distinct: yyDollar[4].str, Hints: yyDollar[5].str, SelectExprs: yyDollar[6].selectExprs, From: yyDollar[7].tableExprs, Where: NewWhere(WhereStr, yyDollar[8].expr), GroupBy: GroupBy(yyDollar[9].exprs), Having: NewWhere(HavingStr, yyDollar[10].expr)} + } + case 27: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:366 + { + yyVAL.selStmt = yyDollar[1].selStmt + } + case 28: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:370 + { + yyVAL.selStmt = &ParenSelect{Select: yyDollar[2].selStmt} + } + case 29: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:376 + { + yyVAL.selStmt = yyDollar[1].selStmt + } + case 30: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:380 + { + yyVAL.selStmt = &ParenSelect{Select: yyDollar[2].selStmt} + } + case 31: + yyDollar = yyS[yypt-7 : yypt+1] + //line sql.y:387 + { + // insert_data returns a *Insert pre-filled with Columns & Values + ins := yyDollar[6].ins + ins.Action = yyDollar[1].str + ins.Comments = yyDollar[2].bytes2 + ins.Ignore = yyDollar[3].str + ins.Table = yyDollar[4].tableName + ins.Partitions = yyDollar[5].partitions + ins.OnDup = OnDup(yyDollar[7].updateExprs) + yyVAL.statement = ins + } + case 32: + yyDollar = yyS[yypt-8 : yypt+1] + //line sql.y:399 + { + cols := make(Columns, 0, len(yyDollar[7].updateExprs)) + vals := make(ValTuple, 0, len(yyDollar[8].updateExprs)) + for _, updateList := range yyDollar[7].updateExprs { + cols = append(cols, updateList.Name.Name) + vals = append(vals, updateList.Expr) + } + yyVAL.statement = &Insert{Action: yyDollar[1].str, Comments: Comments(yyDollar[2].bytes2), Ignore: yyDollar[3].str, Table: yyDollar[4].tableName, Partitions: yyDollar[5].partitions, Columns: cols, Rows: Values{vals}, OnDup: OnDup(yyDollar[8].updateExprs)} + } + case 33: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:411 + { + yyVAL.str = InsertStr + } + case 34: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:415 + { + yyVAL.str = ReplaceStr + } + case 35: + yyDollar = yyS[yypt-8 : yypt+1] + //line sql.y:421 + { + yyVAL.statement = &Update{Comments: Comments(yyDollar[2].bytes2), TableExprs: yyDollar[3].tableExprs, Exprs: yyDollar[5].updateExprs, Where: NewWhere(WhereStr, yyDollar[6].expr), OrderBy: yyDollar[7].orderBy, Limit: yyDollar[8].limit} + } + case 36: + yyDollar = yyS[yypt-8 : yypt+1] + //line sql.y:427 + { + yyVAL.statement = &Delete{Comments: Comments(yyDollar[2].bytes2), TableExprs: TableExprs{&AliasedTableExpr{Expr: yyDollar[4].tableName}}, Partitions: yyDollar[5].partitions, Where: NewWhere(WhereStr, yyDollar[6].expr), OrderBy: yyDollar[7].orderBy, Limit: yyDollar[8].limit} + } + case 37: + yyDollar = yyS[yypt-7 : yypt+1] + //line sql.y:431 + { + yyVAL.statement = &Delete{Comments: Comments(yyDollar[2].bytes2), Targets: yyDollar[4].tableNames, TableExprs: yyDollar[6].tableExprs, Where: NewWhere(WhereStr, yyDollar[7].expr)} + } + case 38: + yyDollar = yyS[yypt-6 : yypt+1] + //line sql.y:435 + { + yyVAL.statement = &Delete{Comments: Comments(yyDollar[2].bytes2), Targets: yyDollar[3].tableNames, TableExprs: yyDollar[5].tableExprs, Where: NewWhere(WhereStr, yyDollar[6].expr)} + } + case 39: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:440 + { + } + case 40: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:441 + { + } + case 41: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:445 + { + yyVAL.tableNames = TableNames{yyDollar[1].tableName} + } + case 42: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:449 + { + yyVAL.tableNames = append(yyVAL.tableNames, yyDollar[3].tableName) + } + case 43: + yyDollar = yyS[yypt-0 : yypt+1] + //line sql.y:454 + { + yyVAL.partitions = nil + } + case 44: + yyDollar = yyS[yypt-4 : yypt+1] + //line sql.y:458 + { + yyVAL.partitions = yyDollar[3].partitions + } + case 45: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:464 + { + yyVAL.statement = &Set{Comments: Comments(yyDollar[2].bytes2), Exprs: yyDollar[3].setExprs} + } + case 46: + yyDollar = yyS[yypt-4 : yypt+1] + //line sql.y:468 + { + yyVAL.statement = &Set{Comments: Comments(yyDollar[2].bytes2), Scope: yyDollar[3].str, Exprs: yyDollar[4].setExprs} + } + case 47: + yyDollar = yyS[yypt-5 : yypt+1] + //line sql.y:472 + { + yyVAL.statement = &Set{Comments: Comments(yyDollar[2].bytes2), Scope: yyDollar[3].str, Exprs: yyDollar[5].setExprs} + } + case 48: + yyDollar = yyS[yypt-4 : yypt+1] + //line sql.y:476 + { + yyVAL.statement = &Set{Comments: Comments(yyDollar[2].bytes2), Exprs: yyDollar[4].setExprs} + } + case 49: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:482 + { + yyVAL.setExprs = SetExprs{yyDollar[1].setExpr} + } + case 50: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:486 + { + yyVAL.setExprs = append(yyVAL.setExprs, yyDollar[3].setExpr) + } + case 51: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:492 + { + yyVAL.setExpr = yyDollar[3].setExpr + } + case 52: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:496 + { + yyVAL.setExpr = &SetExpr{Name: NewColIdent("tx_read_only"), Expr: NewIntVal([]byte("0"))} + } + case 53: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:500 + { + yyVAL.setExpr = &SetExpr{Name: NewColIdent("tx_read_only"), Expr: NewIntVal([]byte("1"))} + } + case 54: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:506 + { + yyVAL.setExpr = &SetExpr{Name: NewColIdent("tx_isolation"), Expr: NewStrVal([]byte("repeatable read"))} + } + case 55: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:510 + { + yyVAL.setExpr = &SetExpr{Name: NewColIdent("tx_isolation"), Expr: NewStrVal([]byte("read committed"))} + } + case 56: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:514 + { + yyVAL.setExpr = &SetExpr{Name: NewColIdent("tx_isolation"), Expr: NewStrVal([]byte("read uncommitted"))} + } + case 57: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:518 + { + yyVAL.setExpr = &SetExpr{Name: NewColIdent("tx_isolation"), Expr: NewStrVal([]byte("serializable"))} + } + case 58: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:524 + { + yyVAL.str = SessionStr + } + case 59: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:528 + { + yyVAL.str = GlobalStr + } + case 60: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:534 + { + yyDollar[1].ddl.TableSpec = yyDollar[2].TableSpec + yyVAL.statement = yyDollar[1].ddl + } + case 61: + yyDollar = yyS[yypt-8 : yypt+1] + //line sql.y:539 + { + // Change this to an alter statement + yyVAL.statement = &DDL{Action: AlterStr, Table: yyDollar[7].tableName, NewName: yyDollar[7].tableName} + } + case 62: + yyDollar = yyS[yypt-4 : yypt+1] + //line sql.y:544 + { + yyVAL.statement = &DDL{Action: CreateStr, NewName: yyDollar[3].tableName.ToViewName()} + } + case 63: + yyDollar = yyS[yypt-6 : yypt+1] + //line sql.y:548 + { + yyVAL.statement = &DDL{Action: CreateStr, NewName: yyDollar[5].tableName.ToViewName()} + } + case 64: + yyDollar = yyS[yypt-5 : yypt+1] + //line sql.y:552 + { + yyVAL.statement = &DDL{Action: CreateVindexStr, VindexSpec: &VindexSpec{ + Name: yyDollar[3].colIdent, + Type: yyDollar[4].colIdent, + Params: yyDollar[5].vindexParams, + }} + } + case 65: + yyDollar = yyS[yypt-5 : yypt+1] + //line sql.y:560 + { + yyVAL.statement = &DBDDL{Action: CreateStr, DBName: string(yyDollar[4].bytes)} + } + case 66: + yyDollar = yyS[yypt-5 : yypt+1] + //line sql.y:564 + { + yyVAL.statement = &DBDDL{Action: CreateStr, DBName: string(yyDollar[4].bytes)} + } + case 67: + yyDollar = yyS[yypt-0 : yypt+1] + //line sql.y:569 + { + yyVAL.colIdent = NewColIdent("") + } + case 68: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:573 + { + yyVAL.colIdent = yyDollar[2].colIdent + } + case 69: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:579 + { + yyVAL.colIdent = NewColIdent(string(yyDollar[1].bytes)) + } + case 70: + yyDollar = yyS[yypt-0 : yypt+1] + //line sql.y:584 + { + var v []VindexParam + yyVAL.vindexParams = v + } + case 71: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:589 + { + yyVAL.vindexParams = yyDollar[2].vindexParams + } + case 72: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:595 + { + yyVAL.vindexParams = make([]VindexParam, 0, 4) + yyVAL.vindexParams = append(yyVAL.vindexParams, yyDollar[1].vindexParam) + } + case 73: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:600 + { + yyVAL.vindexParams = append(yyVAL.vindexParams, yyDollar[3].vindexParam) + } + case 74: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:606 + { + yyVAL.vindexParam = VindexParam{Key: yyDollar[1].colIdent, Val: yyDollar[3].str} + } + case 75: + yyDollar = yyS[yypt-4 : yypt+1] + //line sql.y:612 + { + yyVAL.ddl = &DDL{Action: CreateStr, NewName: yyDollar[4].tableName} + setDDL(yylex, yyVAL.ddl) + } + case 76: + yyDollar = yyS[yypt-4 : yypt+1] + //line sql.y:619 + { + yyVAL.TableSpec = yyDollar[2].TableSpec + yyVAL.TableSpec.Options = yyDollar[4].str + } + case 77: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:626 + { + yyVAL.TableSpec = &TableSpec{} + yyVAL.TableSpec.AddColumn(yyDollar[1].columnDefinition) + } + case 78: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:631 + { + yyVAL.TableSpec.AddColumn(yyDollar[3].columnDefinition) + } + case 79: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:635 + { + yyVAL.TableSpec.AddIndex(yyDollar[3].indexDefinition) + } + case 80: + yyDollar = yyS[yypt-8 : yypt+1] + //line sql.y:641 + { + yyDollar[2].columnType.NotNull = yyDollar[3].boolVal + yyDollar[2].columnType.Default = yyDollar[4].optVal + yyDollar[2].columnType.OnUpdate = yyDollar[5].optVal + yyDollar[2].columnType.Autoincrement = yyDollar[6].boolVal + yyDollar[2].columnType.KeyOpt = yyDollar[7].colKeyOpt + yyDollar[2].columnType.Comment = yyDollar[8].optVal + yyVAL.columnDefinition = &ColumnDefinition{Name: NewColIdent(string(yyDollar[1].bytes)), Type: yyDollar[2].columnType} + } + case 81: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:652 + { + yyVAL.columnType = yyDollar[1].columnType + yyVAL.columnType.Unsigned = yyDollar[2].boolVal + yyVAL.columnType.Zerofill = yyDollar[3].boolVal + } + case 85: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:663 + { + yyVAL.columnType = yyDollar[1].columnType + yyVAL.columnType.Length = yyDollar[2].optVal + } + case 86: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:668 + { + yyVAL.columnType = yyDollar[1].columnType + } + case 87: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:674 + { + yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} + } + case 88: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:678 + { + yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} + } + case 89: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:682 + { + yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} + } + case 90: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:686 + { + yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} + } + case 91: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:690 + { + yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} + } + case 92: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:694 + { + yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} + } + case 93: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:698 + { + yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} + } + case 94: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:704 + { + yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} + yyVAL.columnType.Length = yyDollar[2].LengthScaleOption.Length + yyVAL.columnType.Scale = yyDollar[2].LengthScaleOption.Scale + } + case 95: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:710 + { + yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} + yyVAL.columnType.Length = yyDollar[2].LengthScaleOption.Length + yyVAL.columnType.Scale = yyDollar[2].LengthScaleOption.Scale + } + case 96: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:716 + { + yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} + yyVAL.columnType.Length = yyDollar[2].LengthScaleOption.Length + yyVAL.columnType.Scale = yyDollar[2].LengthScaleOption.Scale + } + case 97: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:722 + { + yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} + yyVAL.columnType.Length = yyDollar[2].LengthScaleOption.Length + yyVAL.columnType.Scale = yyDollar[2].LengthScaleOption.Scale + } + case 98: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:728 + { + yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} + yyVAL.columnType.Length = yyDollar[2].LengthScaleOption.Length + yyVAL.columnType.Scale = yyDollar[2].LengthScaleOption.Scale + } + case 99: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:736 + { + yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} + } + case 100: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:740 + { + yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes), Length: yyDollar[2].optVal} + } + case 101: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:744 + { + yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes), Length: yyDollar[2].optVal} + } + case 102: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:748 + { + yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes), Length: yyDollar[2].optVal} + } + case 103: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:752 + { + yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} + } + case 104: + yyDollar = yyS[yypt-4 : yypt+1] + //line sql.y:758 + { + yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes), Length: yyDollar[2].optVal, Charset: yyDollar[3].str, Collate: yyDollar[4].str} + } + case 105: + yyDollar = yyS[yypt-4 : yypt+1] + //line sql.y:762 + { + yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes), Length: yyDollar[2].optVal, Charset: yyDollar[3].str, Collate: yyDollar[4].str} + } + case 106: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:766 + { + yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes), Length: yyDollar[2].optVal} + } + case 107: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:770 + { + yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes), Length: yyDollar[2].optVal} + } + case 108: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:774 + { + yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes), Charset: yyDollar[2].str, Collate: yyDollar[3].str} + } + case 109: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:778 + { + yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes), Charset: yyDollar[2].str, Collate: yyDollar[3].str} + } + case 110: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:782 + { + yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes), Charset: yyDollar[2].str, Collate: yyDollar[3].str} + } + case 111: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:786 + { + yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes), Charset: yyDollar[2].str, Collate: yyDollar[3].str} + } + case 112: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:790 + { + yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} + } + case 113: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:794 + { + yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} + } + case 114: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:798 + { + yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} + } + case 115: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:802 + { + yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} + } + case 116: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:806 + { + yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} + } + case 117: + yyDollar = yyS[yypt-6 : yypt+1] + //line sql.y:810 + { + yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes), EnumValues: yyDollar[3].strs, Charset: yyDollar[5].str, Collate: yyDollar[6].str} + } + case 118: + yyDollar = yyS[yypt-6 : yypt+1] + //line sql.y:815 + { + yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes), EnumValues: yyDollar[3].strs, Charset: yyDollar[5].str, Collate: yyDollar[6].str} + } + case 119: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:821 + { + yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} + } + case 120: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:825 + { + yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} + } + case 121: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:829 + { + yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} + } + case 122: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:833 + { + yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} + } + case 123: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:837 + { + yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} + } + case 124: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:841 + { + yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} + } + case 125: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:845 + { + yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} + } + case 126: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:849 + { + yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} + } + case 127: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:855 + { + yyVAL.strs = make([]string, 0, 4) + yyVAL.strs = append(yyVAL.strs, "'"+string(yyDollar[1].bytes)+"'") + } + case 128: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:860 + { + yyVAL.strs = append(yyDollar[1].strs, "'"+string(yyDollar[3].bytes)+"'") + } + case 129: + yyDollar = yyS[yypt-0 : yypt+1] + //line sql.y:865 + { + yyVAL.optVal = nil + } + case 130: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:869 + { + yyVAL.optVal = NewIntVal(yyDollar[2].bytes) + } + case 131: + yyDollar = yyS[yypt-0 : yypt+1] + //line sql.y:874 + { + yyVAL.LengthScaleOption = LengthScaleOption{} + } + case 132: + yyDollar = yyS[yypt-5 : yypt+1] + //line sql.y:878 + { + yyVAL.LengthScaleOption = LengthScaleOption{ + Length: NewIntVal(yyDollar[2].bytes), + Scale: NewIntVal(yyDollar[4].bytes), + } + } + case 133: + yyDollar = yyS[yypt-0 : yypt+1] + //line sql.y:886 + { + yyVAL.LengthScaleOption = LengthScaleOption{} + } + case 134: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:890 + { + yyVAL.LengthScaleOption = LengthScaleOption{ + Length: NewIntVal(yyDollar[2].bytes), + } + } + case 135: + yyDollar = yyS[yypt-5 : yypt+1] + //line sql.y:896 + { + yyVAL.LengthScaleOption = LengthScaleOption{ + Length: NewIntVal(yyDollar[2].bytes), + Scale: NewIntVal(yyDollar[4].bytes), + } + } + case 136: + yyDollar = yyS[yypt-0 : yypt+1] + //line sql.y:904 + { + yyVAL.boolVal = BoolVal(false) + } + case 137: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:908 + { + yyVAL.boolVal = BoolVal(true) + } + case 138: + yyDollar = yyS[yypt-0 : yypt+1] + //line sql.y:913 + { + yyVAL.boolVal = BoolVal(false) + } + case 139: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:917 + { + yyVAL.boolVal = BoolVal(true) + } + case 140: + yyDollar = yyS[yypt-0 : yypt+1] + //line sql.y:923 + { + yyVAL.boolVal = BoolVal(false) + } + case 141: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:927 + { + yyVAL.boolVal = BoolVal(false) + } + case 142: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:931 + { + yyVAL.boolVal = BoolVal(true) + } + case 143: + yyDollar = yyS[yypt-0 : yypt+1] + //line sql.y:936 + { + yyVAL.optVal = nil + } + case 144: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:940 + { + yyVAL.optVal = NewStrVal(yyDollar[2].bytes) + } + case 145: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:944 + { + yyVAL.optVal = NewIntVal(yyDollar[2].bytes) + } + case 146: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:948 + { + yyVAL.optVal = NewFloatVal(yyDollar[2].bytes) + } + case 147: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:952 + { + yyVAL.optVal = NewValArg(yyDollar[2].bytes) + } + case 148: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:956 + { + yyVAL.optVal = NewValArg(yyDollar[2].bytes) + } + case 149: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:960 + { + yyVAL.optVal = NewBitVal(yyDollar[2].bytes) + } + case 150: + yyDollar = yyS[yypt-0 : yypt+1] + //line sql.y:965 + { + yyVAL.optVal = nil + } + case 151: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:969 + { + yyVAL.optVal = NewValArg(yyDollar[3].bytes) + } + case 152: + yyDollar = yyS[yypt-0 : yypt+1] + //line sql.y:974 + { + yyVAL.boolVal = BoolVal(false) + } + case 153: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:978 + { + yyVAL.boolVal = BoolVal(true) + } + case 154: + yyDollar = yyS[yypt-0 : yypt+1] + //line sql.y:983 + { + yyVAL.str = "" + } + case 155: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:987 + { + yyVAL.str = string(yyDollar[3].bytes) + } + case 156: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:991 + { + yyVAL.str = string(yyDollar[3].bytes) + } + case 157: + yyDollar = yyS[yypt-0 : yypt+1] + //line sql.y:996 + { + yyVAL.str = "" + } + case 158: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:1000 + { + yyVAL.str = string(yyDollar[2].bytes) + } + case 159: + yyDollar = yyS[yypt-0 : yypt+1] + //line sql.y:1005 + { + yyVAL.colKeyOpt = colKeyNone + } + case 160: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:1009 + { + yyVAL.colKeyOpt = colKeyPrimary + } + case 161: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:1013 + { + yyVAL.colKeyOpt = colKey + } + case 162: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:1017 + { + yyVAL.colKeyOpt = colKeyUniqueKey + } + case 163: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:1021 + { + yyVAL.colKeyOpt = colKeyUnique + } + case 164: + yyDollar = yyS[yypt-0 : yypt+1] + //line sql.y:1026 + { + yyVAL.optVal = nil + } + case 165: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:1030 + { + yyVAL.optVal = NewStrVal(yyDollar[2].bytes) + } + case 166: + yyDollar = yyS[yypt-5 : yypt+1] + //line sql.y:1036 + { + yyVAL.indexDefinition = &IndexDefinition{Info: yyDollar[1].indexInfo, Columns: yyDollar[3].indexColumns, Options: yyDollar[5].indexOptions} + } + case 167: + yyDollar = yyS[yypt-4 : yypt+1] + //line sql.y:1040 + { + yyVAL.indexDefinition = &IndexDefinition{Info: yyDollar[1].indexInfo, Columns: yyDollar[3].indexColumns} + } + case 168: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:1046 + { + yyVAL.indexOptions = []*IndexOption{yyDollar[1].indexOption} + } + case 169: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:1050 + { + yyVAL.indexOptions = append(yyVAL.indexOptions, yyDollar[2].indexOption) + } + case 170: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:1056 + { + yyVAL.indexOption = &IndexOption{Name: string(yyDollar[1].bytes), Using: string(yyDollar[2].bytes)} + } + case 171: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:1060 + { + // should not be string + yyVAL.indexOption = &IndexOption{Name: string(yyDollar[1].bytes), Value: NewIntVal(yyDollar[3].bytes)} + } + case 172: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:1065 + { + yyVAL.indexOption = &IndexOption{Name: string(yyDollar[1].bytes), Value: NewStrVal(yyDollar[2].bytes)} + } + case 173: + yyDollar = yyS[yypt-0 : yypt+1] + //line sql.y:1071 + { + yyVAL.str = "" + } + case 174: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:1075 + { + yyVAL.str = string(yyDollar[1].bytes) + } + case 175: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:1081 + { + yyVAL.indexInfo = &IndexInfo{Type: string(yyDollar[1].bytes) + " " + string(yyDollar[2].bytes), Name: NewColIdent("PRIMARY"), Primary: true, Unique: true} + } + case 176: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:1085 + { + yyVAL.indexInfo = &IndexInfo{Type: string(yyDollar[1].bytes) + " " + string(yyDollar[2].str), Name: NewColIdent(string(yyDollar[3].bytes)), Spatial: true, Unique: false} + } + case 177: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:1089 + { + yyVAL.indexInfo = &IndexInfo{Type: string(yyDollar[1].bytes) + " " + string(yyDollar[2].str), Name: NewColIdent(string(yyDollar[3].bytes)), Unique: true} + } + case 178: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:1093 + { + yyVAL.indexInfo = &IndexInfo{Type: string(yyDollar[1].bytes), Name: NewColIdent(string(yyDollar[2].bytes)), Unique: true} + } + case 179: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:1097 + { + yyVAL.indexInfo = &IndexInfo{Type: string(yyDollar[1].str), Name: NewColIdent(string(yyDollar[2].bytes)), Unique: false} + } + case 180: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:1103 + { + yyVAL.str = string(yyDollar[1].bytes) + } + case 181: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:1107 + { + yyVAL.str = string(yyDollar[1].bytes) + } + case 182: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:1113 + { + yyVAL.indexColumns = []*IndexColumn{yyDollar[1].indexColumn} + } + case 183: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:1117 + { + yyVAL.indexColumns = append(yyVAL.indexColumns, yyDollar[3].indexColumn) + } + case 184: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:1123 + { + yyVAL.indexColumn = &IndexColumn{Column: yyDollar[1].colIdent, Length: yyDollar[2].optVal} + } + case 185: + yyDollar = yyS[yypt-0 : yypt+1] + //line sql.y:1128 + { + yyVAL.str = "" + } + case 186: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:1132 + { + yyVAL.str = " " + string(yyDollar[1].str) + } + case 187: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:1136 + { + yyVAL.str = string(yyDollar[1].str) + ", " + string(yyDollar[3].str) + } + case 188: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:1144 + { + yyVAL.str = yyDollar[1].str + } + case 189: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:1148 + { + yyVAL.str = yyDollar[1].str + " " + yyDollar[2].str + } + case 190: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:1152 + { + yyVAL.str = yyDollar[1].str + "=" + yyDollar[3].str + } + case 191: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:1158 + { + yyVAL.str = yyDollar[1].colIdent.String() + } + case 192: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:1162 + { + yyVAL.str = "'" + string(yyDollar[1].bytes) + "'" + } + case 193: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:1166 + { + yyVAL.str = string(yyDollar[1].bytes) + } + case 194: + yyDollar = yyS[yypt-6 : yypt+1] + //line sql.y:1172 + { + yyVAL.statement = &DDL{Action: AlterStr, Table: yyDollar[4].tableName, NewName: yyDollar[4].tableName} + } + case 195: + yyDollar = yyS[yypt-7 : yypt+1] + //line sql.y:1176 + { + yyVAL.statement = &DDL{Action: AlterStr, Table: yyDollar[4].tableName, NewName: yyDollar[4].tableName} + } + case 196: + yyDollar = yyS[yypt-7 : yypt+1] + //line sql.y:1180 + { + yyVAL.statement = &DDL{Action: AlterStr, Table: yyDollar[4].tableName, NewName: yyDollar[4].tableName} + } + case 197: + yyDollar = yyS[yypt-12 : yypt+1] + //line sql.y:1184 + { + yyVAL.statement = &DDL{ + Action: AddColVindexStr, + Table: yyDollar[4].tableName, + VindexSpec: &VindexSpec{ + Name: yyDollar[7].colIdent, + Type: yyDollar[11].colIdent, + Params: yyDollar[12].vindexParams, + }, + VindexCols: yyDollar[9].columns, + } + } + case 198: + yyDollar = yyS[yypt-7 : yypt+1] + //line sql.y:1197 + { + yyVAL.statement = &DDL{ + Action: DropColVindexStr, + Table: yyDollar[4].tableName, + VindexSpec: &VindexSpec{ + Name: yyDollar[7].colIdent, + }, + } + } + case 199: + yyDollar = yyS[yypt-7 : yypt+1] + //line sql.y:1207 + { + // Change this to a rename statement + yyVAL.statement = &DDL{Action: RenameStr, Table: yyDollar[4].tableName, NewName: yyDollar[7].tableName} + } + case 200: + yyDollar = yyS[yypt-7 : yypt+1] + //line sql.y:1212 + { + // Rename an index can just be an alter + yyVAL.statement = &DDL{Action: AlterStr, Table: yyDollar[4].tableName, NewName: yyDollar[4].tableName} + } + case 201: + yyDollar = yyS[yypt-4 : yypt+1] + //line sql.y:1217 + { + yyVAL.statement = &DDL{Action: AlterStr, Table: yyDollar[3].tableName.ToViewName(), NewName: yyDollar[3].tableName.ToViewName()} + } + case 202: + yyDollar = yyS[yypt-5 : yypt+1] + //line sql.y:1221 + { + yyVAL.statement = &DDL{Action: AlterStr, Table: yyDollar[4].tableName, PartitionSpec: yyDollar[5].partSpec} + } + case 214: + yyDollar = yyS[yypt-7 : yypt+1] + //line sql.y:1240 + { + yyVAL.partSpec = &PartitionSpec{Action: ReorganizeStr, Name: yyDollar[3].colIdent, Definitions: yyDollar[6].partDefs} + } + case 215: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:1246 + { + yyVAL.partDefs = []*PartitionDefinition{yyDollar[1].partDef} + } + case 216: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:1250 + { + yyVAL.partDefs = append(yyDollar[1].partDefs, yyDollar[3].partDef) + } + case 217: + yyDollar = yyS[yypt-8 : yypt+1] + //line sql.y:1256 + { + yyVAL.partDef = &PartitionDefinition{Name: yyDollar[2].colIdent, Limit: yyDollar[7].expr} + } + case 218: + yyDollar = yyS[yypt-8 : yypt+1] + //line sql.y:1260 + { + yyVAL.partDef = &PartitionDefinition{Name: yyDollar[2].colIdent, Maxvalue: true} + } + case 219: + yyDollar = yyS[yypt-5 : yypt+1] + //line sql.y:1266 + { + yyVAL.statement = &DDL{Action: RenameStr, Table: yyDollar[3].tableName, NewName: yyDollar[5].tableName} + } + case 220: + yyDollar = yyS[yypt-4 : yypt+1] + //line sql.y:1272 + { + var exists bool + if yyDollar[3].byt != 0 { + exists = true + } + yyVAL.statement = &DDL{Action: DropStr, Table: yyDollar[4].tableName, IfExists: exists} + } + case 221: + yyDollar = yyS[yypt-6 : yypt+1] + //line sql.y:1280 + { + // Change this to an alter statement + yyVAL.statement = &DDL{Action: AlterStr, Table: yyDollar[5].tableName, NewName: yyDollar[5].tableName} + } + case 222: + yyDollar = yyS[yypt-5 : yypt+1] + //line sql.y:1285 + { + var exists bool + if yyDollar[3].byt != 0 { + exists = true + } + yyVAL.statement = &DDL{Action: DropStr, Table: yyDollar[4].tableName.ToViewName(), IfExists: exists} + } + case 223: + yyDollar = yyS[yypt-4 : yypt+1] + //line sql.y:1293 + { + yyVAL.statement = &DBDDL{Action: DropStr, DBName: string(yyDollar[4].bytes)} + } + case 224: + yyDollar = yyS[yypt-4 : yypt+1] + //line sql.y:1297 + { + yyVAL.statement = &DBDDL{Action: DropStr, DBName: string(yyDollar[4].bytes)} + } + case 225: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:1303 + { + yyVAL.statement = &DDL{Action: TruncateStr, Table: yyDollar[3].tableName} + } + case 226: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:1307 + { + yyVAL.statement = &DDL{Action: TruncateStr, Table: yyDollar[2].tableName} + } + case 227: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:1312 + { + yyVAL.statement = &DDL{Action: AlterStr, Table: yyDollar[3].tableName, NewName: yyDollar[3].tableName} + } + case 228: + yyDollar = yyS[yypt-4 : yypt+1] + //line sql.y:1318 + { + yyVAL.statement = &Show{Type: string(yyDollar[2].bytes) + " " + string(yyDollar[3].bytes)} + } + case 229: + yyDollar = yyS[yypt-4 : yypt+1] + //line sql.y:1322 + { + yyVAL.statement = &Show{Type: string(yyDollar[2].bytes) + " " + string(yyDollar[3].bytes)} + } + case 230: + yyDollar = yyS[yypt-4 : yypt+1] + //line sql.y:1326 + { + yyVAL.statement = &Show{Type: string(yyDollar[2].bytes) + " " + string(yyDollar[3].bytes)} + } + case 231: + yyDollar = yyS[yypt-4 : yypt+1] + //line sql.y:1331 + { + yyVAL.statement = &Show{Type: string(yyDollar[2].bytes) + " " + string(yyDollar[3].bytes)} + } + case 232: + yyDollar = yyS[yypt-4 : yypt+1] + //line sql.y:1335 + { + yyVAL.statement = &Show{Type: string(yyDollar[2].bytes) + " " + string(yyDollar[3].bytes)} + } + case 233: + yyDollar = yyS[yypt-4 : yypt+1] + //line sql.y:1339 + { + yyVAL.statement = &Show{Type: string(yyDollar[2].bytes) + " " + string(yyDollar[3].bytes)} + } + case 234: + yyDollar = yyS[yypt-4 : yypt+1] + //line sql.y:1343 + { + yyVAL.statement = &Show{Type: string(yyDollar[2].bytes) + " " + string(yyDollar[3].bytes)} + } + case 235: + yyDollar = yyS[yypt-4 : yypt+1] + //line sql.y:1347 + { + yyVAL.statement = &Show{Type: string(yyDollar[2].bytes) + " " + string(yyDollar[3].bytes)} + } + case 236: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:1351 + { + yyVAL.statement = &Show{Type: string(yyDollar[2].bytes)} + } + case 237: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:1355 + { + yyVAL.statement = &Show{Type: string(yyDollar[2].bytes)} + } + case 238: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:1359 + { + yyVAL.statement = &Show{Type: string(yyDollar[2].bytes)} + } + case 239: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:1363 + { + yyVAL.statement = &Show{Type: string(yyDollar[2].bytes)} + } + case 240: + yyDollar = yyS[yypt-4 : yypt+1] + //line sql.y:1367 + { + yyVAL.statement = &Show{Scope: yyDollar[2].str, Type: string(yyDollar[3].bytes)} + } + case 241: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:1371 + { + yyVAL.statement = &Show{Type: string(yyDollar[2].bytes)} + } + case 242: + yyDollar = yyS[yypt-6 : yypt+1] + //line sql.y:1375 + { + // this is ugly, but I couldn't find a better way for now + if yyDollar[4].str == "processlist" { + yyVAL.statement = &Show{Type: yyDollar[4].str} + } else { + showTablesOpt := &ShowTablesOpt{Extended: yyDollar[2].str, Full: yyDollar[3].str, DbName: yyDollar[5].str, Filter: yyDollar[6].showFilter} + yyVAL.statement = &Show{Type: yyDollar[4].str, ShowTablesOpt: showTablesOpt} + } + } + case 243: + yyDollar = yyS[yypt-4 : yypt+1] + //line sql.y:1385 + { + yyVAL.statement = &Show{Scope: yyDollar[2].str, Type: string(yyDollar[3].bytes)} + } + case 244: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:1389 + { + yyVAL.statement = &Show{Type: string(yyDollar[2].bytes)} + } + case 245: + yyDollar = yyS[yypt-4 : yypt+1] + //line sql.y:1393 + { + yyVAL.statement = &Show{Type: string(yyDollar[2].bytes), OnTable: yyDollar[4].tableName} + } + case 246: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:1397 + { + yyVAL.statement = &Show{Type: string(yyDollar[2].bytes)} + } + case 247: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:1401 + { + yyVAL.statement = &Show{Type: string(yyDollar[2].bytes)} + } + case 248: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:1405 + { + yyVAL.statement = &Show{Type: string(yyDollar[2].bytes)} + } + case 249: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:1409 + { + yyVAL.statement = &Show{Type: string(yyDollar[2].bytes)} + } + case 250: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:1419 + { + yyVAL.statement = &Show{Type: string(yyDollar[2].bytes)} + } + case 251: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:1425 + { + yyVAL.str = string(yyDollar[1].bytes) + } + case 252: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:1429 + { + yyVAL.str = string(yyDollar[1].bytes) + } + case 253: + yyDollar = yyS[yypt-0 : yypt+1] + //line sql.y:1435 + { + yyVAL.str = "" + } + case 254: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:1439 + { + yyVAL.str = "extended " + } + case 255: + yyDollar = yyS[yypt-0 : yypt+1] + //line sql.y:1445 + { + yyVAL.str = "" + } + case 256: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:1449 + { + yyVAL.str = "full " + } + case 257: + yyDollar = yyS[yypt-0 : yypt+1] + //line sql.y:1455 + { + yyVAL.str = "" + } + case 258: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:1459 + { + yyVAL.str = yyDollar[2].tableIdent.v + } + case 259: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:1463 + { + yyVAL.str = yyDollar[2].tableIdent.v + } + case 260: + yyDollar = yyS[yypt-0 : yypt+1] + //line sql.y:1469 + { + yyVAL.showFilter = nil + } + case 261: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:1473 + { + yyVAL.showFilter = &ShowFilter{Like: string(yyDollar[2].bytes)} + } + case 262: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:1477 + { + yyVAL.showFilter = &ShowFilter{Filter: yyDollar[2].expr} + } + case 263: + yyDollar = yyS[yypt-0 : yypt+1] + //line sql.y:1483 + { + yyVAL.str = "" + } + case 264: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:1487 + { + yyVAL.str = SessionStr + } + case 265: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:1491 + { + yyVAL.str = GlobalStr + } + case 266: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:1497 + { + yyVAL.statement = &Use{DBName: yyDollar[2].tableIdent} + } + case 267: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:1501 + { + yyVAL.statement = &Use{DBName: TableIdent{v: ""}} + } + case 268: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:1507 + { + yyVAL.statement = &Begin{} + } + case 269: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:1511 + { + yyVAL.statement = &Begin{} + } + case 270: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:1517 + { + yyVAL.statement = &Commit{} + } + case 271: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:1523 + { + yyVAL.statement = &Rollback{} + } + case 272: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:1529 + { + yyVAL.statement = &OtherRead{} + } + case 273: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:1533 + { + yyVAL.statement = &OtherRead{} + } + case 274: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:1537 + { + yyVAL.statement = &OtherRead{} + } + case 275: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:1541 + { + yyVAL.statement = &OtherAdmin{} + } + case 276: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:1545 + { + yyVAL.statement = &OtherAdmin{} + } + case 277: + yyDollar = yyS[yypt-0 : yypt+1] + //line sql.y:1550 + { + setAllowComments(yylex, true) + } + case 278: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:1554 + { + yyVAL.bytes2 = yyDollar[2].bytes2 + setAllowComments(yylex, false) + } + case 279: + yyDollar = yyS[yypt-0 : yypt+1] + //line sql.y:1560 + { + yyVAL.bytes2 = nil + } + case 280: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:1564 + { + yyVAL.bytes2 = append(yyDollar[1].bytes2, yyDollar[2].bytes) + } + case 281: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:1570 + { + yyVAL.str = UnionStr + } + case 282: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:1574 + { + yyVAL.str = UnionAllStr + } + case 283: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:1578 + { + yyVAL.str = UnionDistinctStr + } + case 284: + yyDollar = yyS[yypt-0 : yypt+1] + //line sql.y:1583 + { + yyVAL.str = "" + } + case 285: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:1587 + { + yyVAL.str = SQLNoCacheStr + } + case 286: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:1591 + { + yyVAL.str = SQLCacheStr + } + case 287: + yyDollar = yyS[yypt-0 : yypt+1] + //line sql.y:1596 + { + yyVAL.str = "" + } + case 288: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:1600 + { + yyVAL.str = DistinctStr + } + case 289: + yyDollar = yyS[yypt-0 : yypt+1] + //line sql.y:1605 + { + yyVAL.str = "" + } + case 290: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:1609 + { + yyVAL.str = StraightJoinHint + } + case 291: + yyDollar = yyS[yypt-0 : yypt+1] + //line sql.y:1614 + { + yyVAL.selectExprs = nil + } + case 292: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:1618 + { + yyVAL.selectExprs = yyDollar[1].selectExprs + } + case 293: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:1624 + { + yyVAL.selectExprs = SelectExprs{yyDollar[1].selectExpr} + } + case 294: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:1628 + { + yyVAL.selectExprs = append(yyVAL.selectExprs, yyDollar[3].selectExpr) + } + case 295: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:1634 + { + yyVAL.selectExpr = &StarExpr{} + } + case 296: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:1638 + { + yyVAL.selectExpr = &AliasedExpr{Expr: yyDollar[1].expr, As: yyDollar[2].colIdent} + } + case 297: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:1642 + { + yyVAL.selectExpr = &StarExpr{TableName: TableName{Name: yyDollar[1].tableIdent}} + } + case 298: + yyDollar = yyS[yypt-5 : yypt+1] + //line sql.y:1646 + { + yyVAL.selectExpr = &StarExpr{TableName: TableName{Qualifier: yyDollar[1].tableIdent, Name: yyDollar[3].tableIdent}} + } + case 299: + yyDollar = yyS[yypt-0 : yypt+1] + //line sql.y:1651 + { + yyVAL.colIdent = ColIdent{} + } + case 300: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:1655 + { + yyVAL.colIdent = yyDollar[1].colIdent + } + case 301: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:1659 + { + yyVAL.colIdent = yyDollar[2].colIdent + } + case 303: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:1666 + { + yyVAL.colIdent = NewColIdent(string(yyDollar[1].bytes)) + } + case 304: + yyDollar = yyS[yypt-0 : yypt+1] + //line sql.y:1671 + { + yyVAL.tableExprs = TableExprs{&AliasedTableExpr{Expr: TableName{Name: NewTableIdent("dual")}}} + } + case 305: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:1675 + { + yyVAL.tableExprs = yyDollar[2].tableExprs + } + case 306: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:1681 + { + yyVAL.tableExprs = TableExprs{yyDollar[1].tableExpr} + } + case 307: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:1685 + { + yyVAL.tableExprs = append(yyVAL.tableExprs, yyDollar[3].tableExpr) + } + case 310: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:1695 + { + yyVAL.tableExpr = yyDollar[1].aliasedTableName + } + case 311: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:1699 + { + yyVAL.tableExpr = &AliasedTableExpr{Expr: yyDollar[1].subquery, As: yyDollar[3].tableIdent} + } + case 312: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:1703 + { + yyVAL.tableExpr = &ParenTableExpr{Exprs: yyDollar[2].tableExprs} + } + case 313: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:1709 + { + yyVAL.aliasedTableName = &AliasedTableExpr{Expr: yyDollar[1].tableName, As: yyDollar[2].tableIdent, Hints: yyDollar[3].indexHints} + } + case 314: + yyDollar = yyS[yypt-7 : yypt+1] + //line sql.y:1713 + { + yyVAL.aliasedTableName = &AliasedTableExpr{Expr: yyDollar[1].tableName, Partitions: yyDollar[4].partitions, As: yyDollar[6].tableIdent, Hints: yyDollar[7].indexHints} + } + case 315: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:1719 + { + yyVAL.columns = Columns{yyDollar[1].colIdent} + } + case 316: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:1723 + { + yyVAL.columns = append(yyVAL.columns, yyDollar[3].colIdent) + } + case 317: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:1729 + { + yyVAL.partitions = Partitions{yyDollar[1].colIdent} + } + case 318: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:1733 + { + yyVAL.partitions = append(yyVAL.partitions, yyDollar[3].colIdent) + } + case 319: + yyDollar = yyS[yypt-4 : yypt+1] + //line sql.y:1746 + { + yyVAL.tableExpr = &JoinTableExpr{LeftExpr: yyDollar[1].tableExpr, Join: yyDollar[2].str, RightExpr: yyDollar[3].tableExpr, Condition: yyDollar[4].joinCondition} + } + case 320: + yyDollar = yyS[yypt-4 : yypt+1] + //line sql.y:1750 + { + yyVAL.tableExpr = &JoinTableExpr{LeftExpr: yyDollar[1].tableExpr, Join: yyDollar[2].str, RightExpr: yyDollar[3].tableExpr, Condition: yyDollar[4].joinCondition} + } + case 321: + yyDollar = yyS[yypt-4 : yypt+1] + //line sql.y:1754 + { + yyVAL.tableExpr = &JoinTableExpr{LeftExpr: yyDollar[1].tableExpr, Join: yyDollar[2].str, RightExpr: yyDollar[3].tableExpr, Condition: yyDollar[4].joinCondition} + } + case 322: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:1758 + { + yyVAL.tableExpr = &JoinTableExpr{LeftExpr: yyDollar[1].tableExpr, Join: yyDollar[2].str, RightExpr: yyDollar[3].tableExpr} + } + case 323: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:1764 + { + yyVAL.joinCondition = JoinCondition{On: yyDollar[2].expr} + } + case 324: + yyDollar = yyS[yypt-4 : yypt+1] + //line sql.y:1766 + { + yyVAL.joinCondition = JoinCondition{Using: yyDollar[3].columns} + } + case 325: + yyDollar = yyS[yypt-0 : yypt+1] + //line sql.y:1770 + { + yyVAL.joinCondition = JoinCondition{} + } + case 326: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:1772 + { + yyVAL.joinCondition = yyDollar[1].joinCondition + } + case 327: + yyDollar = yyS[yypt-0 : yypt+1] + //line sql.y:1776 + { + yyVAL.joinCondition = JoinCondition{} + } + case 328: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:1778 + { + yyVAL.joinCondition = JoinCondition{On: yyDollar[2].expr} + } + case 329: + yyDollar = yyS[yypt-0 : yypt+1] + //line sql.y:1781 + { + yyVAL.empty = struct{}{} + } + case 330: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:1783 + { + yyVAL.empty = struct{}{} + } + case 331: + yyDollar = yyS[yypt-0 : yypt+1] + //line sql.y:1786 + { + yyVAL.tableIdent = NewTableIdent("") + } + case 332: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:1790 + { + yyVAL.tableIdent = yyDollar[1].tableIdent + } + case 333: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:1794 + { + yyVAL.tableIdent = yyDollar[2].tableIdent + } + case 335: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:1801 + { + yyVAL.tableIdent = NewTableIdent(string(yyDollar[1].bytes)) + } + case 336: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:1807 + { + yyVAL.str = JoinStr + } + case 337: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:1811 + { + yyVAL.str = JoinStr + } + case 338: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:1815 + { + yyVAL.str = JoinStr + } + case 339: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:1821 + { + yyVAL.str = StraightJoinStr + } + case 340: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:1827 + { + yyVAL.str = LeftJoinStr + } + case 341: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:1831 + { + yyVAL.str = LeftJoinStr + } + case 342: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:1835 + { + yyVAL.str = RightJoinStr + } + case 343: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:1839 + { + yyVAL.str = RightJoinStr + } + case 344: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:1845 + { + yyVAL.str = NaturalJoinStr + } + case 345: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:1849 + { + if yyDollar[2].str == LeftJoinStr { + yyVAL.str = NaturalLeftJoinStr + } else { + yyVAL.str = NaturalRightJoinStr + } + } + case 346: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:1859 + { + yyVAL.tableName = yyDollar[2].tableName + } + case 347: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:1863 + { + yyVAL.tableName = yyDollar[1].tableName + } + case 348: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:1869 + { + yyVAL.tableName = TableName{Name: yyDollar[1].tableIdent} + } + case 349: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:1873 + { + yyVAL.tableName = TableName{Qualifier: yyDollar[1].tableIdent, Name: yyDollar[3].tableIdent} + } + case 350: + yyDollar = yyS[yypt-0 : yypt+1] + //line sql.y:1878 + { + yyVAL.indexHints = nil + } + case 351: + yyDollar = yyS[yypt-5 : yypt+1] + //line sql.y:1882 + { + yyVAL.indexHints = &IndexHints{Type: UseStr, Indexes: yyDollar[4].columns} + } + case 352: + yyDollar = yyS[yypt-5 : yypt+1] + //line sql.y:1886 + { + yyVAL.indexHints = &IndexHints{Type: IgnoreStr, Indexes: yyDollar[4].columns} + } + case 353: + yyDollar = yyS[yypt-5 : yypt+1] + //line sql.y:1890 + { + yyVAL.indexHints = &IndexHints{Type: ForceStr, Indexes: yyDollar[4].columns} + } + case 354: + yyDollar = yyS[yypt-0 : yypt+1] + //line sql.y:1895 + { + yyVAL.expr = nil + } + case 355: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:1899 + { + yyVAL.expr = yyDollar[2].expr + } + case 356: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:1905 + { + yyVAL.expr = yyDollar[1].expr + } + case 357: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:1909 + { + yyVAL.expr = &AndExpr{Left: yyDollar[1].expr, Right: yyDollar[3].expr} + } + case 358: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:1913 + { + yyVAL.expr = &OrExpr{Left: yyDollar[1].expr, Right: yyDollar[3].expr} + } + case 359: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:1917 + { + yyVAL.expr = &NotExpr{Expr: yyDollar[2].expr} + } + case 360: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:1921 + { + yyVAL.expr = &IsExpr{Operator: yyDollar[3].str, Expr: yyDollar[1].expr} + } + case 361: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:1925 + { + yyVAL.expr = yyDollar[1].expr + } + case 362: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:1929 + { + yyVAL.expr = &Default{ColName: yyDollar[2].str} + } + case 363: + yyDollar = yyS[yypt-0 : yypt+1] + //line sql.y:1935 + { + yyVAL.str = "" + } + case 364: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:1939 + { + yyVAL.str = string(yyDollar[2].bytes) + } + case 365: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:1945 + { + yyVAL.boolVal = BoolVal(true) + } + case 366: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:1949 + { + yyVAL.boolVal = BoolVal(false) + } + case 367: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:1955 + { + yyVAL.expr = &ComparisonExpr{Left: yyDollar[1].expr, Operator: yyDollar[2].str, Right: yyDollar[3].expr} + } + case 368: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:1959 + { + yyVAL.expr = &ComparisonExpr{Left: yyDollar[1].expr, Operator: InStr, Right: yyDollar[3].colTuple} + } + case 369: + yyDollar = yyS[yypt-4 : yypt+1] + //line sql.y:1963 + { + yyVAL.expr = &ComparisonExpr{Left: yyDollar[1].expr, Operator: NotInStr, Right: yyDollar[4].colTuple} + } + case 370: + yyDollar = yyS[yypt-4 : yypt+1] + //line sql.y:1967 + { + yyVAL.expr = &ComparisonExpr{Left: yyDollar[1].expr, Operator: LikeStr, Right: yyDollar[3].expr, Escape: yyDollar[4].expr} + } + case 371: + yyDollar = yyS[yypt-5 : yypt+1] + //line sql.y:1971 + { + yyVAL.expr = &ComparisonExpr{Left: yyDollar[1].expr, Operator: NotLikeStr, Right: yyDollar[4].expr, Escape: yyDollar[5].expr} + } + case 372: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:1975 + { + yyVAL.expr = &ComparisonExpr{Left: yyDollar[1].expr, Operator: RegexpStr, Right: yyDollar[3].expr} + } + case 373: + yyDollar = yyS[yypt-4 : yypt+1] + //line sql.y:1979 + { + yyVAL.expr = &ComparisonExpr{Left: yyDollar[1].expr, Operator: NotRegexpStr, Right: yyDollar[4].expr} + } + case 374: + yyDollar = yyS[yypt-5 : yypt+1] + //line sql.y:1983 + { + yyVAL.expr = &RangeCond{Left: yyDollar[1].expr, Operator: BetweenStr, From: yyDollar[3].expr, To: yyDollar[5].expr} + } + case 375: + yyDollar = yyS[yypt-6 : yypt+1] + //line sql.y:1987 + { + yyVAL.expr = &RangeCond{Left: yyDollar[1].expr, Operator: NotBetweenStr, From: yyDollar[4].expr, To: yyDollar[6].expr} + } + case 376: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:1991 + { + yyVAL.expr = &ExistsExpr{Subquery: yyDollar[2].subquery} + } + case 377: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:1997 + { + yyVAL.str = IsNullStr + } + case 378: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:2001 + { + yyVAL.str = IsNotNullStr + } + case 379: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2005 + { + yyVAL.str = IsTrueStr + } + case 380: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:2009 + { + yyVAL.str = IsNotTrueStr + } + case 381: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2013 + { + yyVAL.str = IsFalseStr + } + case 382: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:2017 + { + yyVAL.str = IsNotFalseStr + } + case 383: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2023 + { + yyVAL.str = EqualStr + } + case 384: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2027 + { + yyVAL.str = LessThanStr + } + case 385: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2031 + { + yyVAL.str = GreaterThanStr + } + case 386: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2035 + { + yyVAL.str = LessEqualStr + } + case 387: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2039 + { + yyVAL.str = GreaterEqualStr + } + case 388: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2043 + { + yyVAL.str = NotEqualStr + } + case 389: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2047 + { + yyVAL.str = NullSafeEqualStr + } + case 390: + yyDollar = yyS[yypt-0 : yypt+1] + //line sql.y:2052 + { + yyVAL.expr = nil + } + case 391: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:2056 + { + yyVAL.expr = yyDollar[2].expr + } + case 392: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2062 + { + yyVAL.colTuple = yyDollar[1].valTuple + } + case 393: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2066 + { + yyVAL.colTuple = yyDollar[1].subquery + } + case 394: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2070 + { + yyVAL.colTuple = ListArg(yyDollar[1].bytes) + } + case 395: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:2076 + { + yyVAL.subquery = &Subquery{yyDollar[2].selStmt} + } + case 396: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2082 + { + yyVAL.exprs = Exprs{yyDollar[1].expr} + } + case 397: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:2086 + { + yyVAL.exprs = append(yyDollar[1].exprs, yyDollar[3].expr) + } + case 398: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2092 + { + yyVAL.expr = yyDollar[1].expr + } + case 399: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2096 + { + yyVAL.expr = yyDollar[1].boolVal + } + case 400: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2100 + { + yyVAL.expr = yyDollar[1].colName + } + case 401: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2104 + { + yyVAL.expr = yyDollar[1].expr + } + case 402: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2108 + { + yyVAL.expr = yyDollar[1].subquery + } + case 403: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:2112 + { + yyVAL.expr = &BinaryExpr{Left: yyDollar[1].expr, Operator: BitAndStr, Right: yyDollar[3].expr} + } + case 404: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:2116 + { + yyVAL.expr = &BinaryExpr{Left: yyDollar[1].expr, Operator: BitOrStr, Right: yyDollar[3].expr} + } + case 405: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:2120 + { + yyVAL.expr = &BinaryExpr{Left: yyDollar[1].expr, Operator: BitXorStr, Right: yyDollar[3].expr} + } + case 406: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:2124 + { + yyVAL.expr = &BinaryExpr{Left: yyDollar[1].expr, Operator: PlusStr, Right: yyDollar[3].expr} + } + case 407: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:2128 + { + yyVAL.expr = &BinaryExpr{Left: yyDollar[1].expr, Operator: MinusStr, Right: yyDollar[3].expr} + } + case 408: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:2132 + { + yyVAL.expr = &BinaryExpr{Left: yyDollar[1].expr, Operator: MultStr, Right: yyDollar[3].expr} + } + case 409: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:2136 + { + yyVAL.expr = &BinaryExpr{Left: yyDollar[1].expr, Operator: DivStr, Right: yyDollar[3].expr} + } + case 410: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:2140 + { + yyVAL.expr = &BinaryExpr{Left: yyDollar[1].expr, Operator: IntDivStr, Right: yyDollar[3].expr} + } + case 411: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:2144 + { + yyVAL.expr = &BinaryExpr{Left: yyDollar[1].expr, Operator: ModStr, Right: yyDollar[3].expr} + } + case 412: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:2148 + { + yyVAL.expr = &BinaryExpr{Left: yyDollar[1].expr, Operator: ModStr, Right: yyDollar[3].expr} + } + case 413: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:2152 + { + yyVAL.expr = &BinaryExpr{Left: yyDollar[1].expr, Operator: ShiftLeftStr, Right: yyDollar[3].expr} + } + case 414: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:2156 + { + yyVAL.expr = &BinaryExpr{Left: yyDollar[1].expr, Operator: ShiftRightStr, Right: yyDollar[3].expr} + } + case 415: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:2160 + { + yyVAL.expr = &BinaryExpr{Left: yyDollar[1].colName, Operator: JSONExtractOp, Right: yyDollar[3].expr} + } + case 416: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:2164 + { + yyVAL.expr = &BinaryExpr{Left: yyDollar[1].colName, Operator: JSONUnquoteExtractOp, Right: yyDollar[3].expr} + } + case 417: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:2168 + { + yyVAL.expr = &CollateExpr{Expr: yyDollar[1].expr, Charset: yyDollar[3].str} + } + case 418: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:2172 + { + yyVAL.expr = &UnaryExpr{Operator: BinaryStr, Expr: yyDollar[2].expr} + } + case 419: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:2176 + { + yyVAL.expr = &UnaryExpr{Operator: UBinaryStr, Expr: yyDollar[2].expr} + } + case 420: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:2180 + { + if num, ok := yyDollar[2].expr.(*SQLVal); ok && num.Type == IntVal { + yyVAL.expr = num + } else { + yyVAL.expr = &UnaryExpr{Operator: UPlusStr, Expr: yyDollar[2].expr} + } + } + case 421: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:2188 + { + if num, ok := yyDollar[2].expr.(*SQLVal); ok && num.Type == IntVal { + // Handle double negative + if num.Val[0] == '-' { + num.Val = num.Val[1:] + yyVAL.expr = num + } else { + yyVAL.expr = NewIntVal(append([]byte("-"), num.Val...)) + } + } else { + yyVAL.expr = &UnaryExpr{Operator: UMinusStr, Expr: yyDollar[2].expr} + } + } + case 422: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:2202 + { + yyVAL.expr = &UnaryExpr{Operator: TildaStr, Expr: yyDollar[2].expr} + } + case 423: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:2206 + { + yyVAL.expr = &UnaryExpr{Operator: BangStr, Expr: yyDollar[2].expr} + } + case 424: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:2210 + { + // This rule prevents the usage of INTERVAL + // as a function. If support is needed for that, + // we'll need to revisit this. The solution + // will be non-trivial because of grammar conflicts. + yyVAL.expr = &IntervalExpr{Expr: yyDollar[2].expr, Unit: yyDollar[3].colIdent.String()} + } + case 429: + yyDollar = yyS[yypt-4 : yypt+1] + //line sql.y:2228 + { + yyVAL.expr = &FuncExpr{Name: yyDollar[1].colIdent, Exprs: yyDollar[3].selectExprs} + } + case 430: + yyDollar = yyS[yypt-5 : yypt+1] + //line sql.y:2232 + { + yyVAL.expr = &FuncExpr{Name: yyDollar[1].colIdent, Distinct: true, Exprs: yyDollar[4].selectExprs} + } + case 431: + yyDollar = yyS[yypt-6 : yypt+1] + //line sql.y:2236 + { + yyVAL.expr = &FuncExpr{Qualifier: yyDollar[1].tableIdent, Name: yyDollar[3].colIdent, Exprs: yyDollar[5].selectExprs} + } + case 432: + yyDollar = yyS[yypt-4 : yypt+1] + //line sql.y:2246 + { + yyVAL.expr = &FuncExpr{Name: NewColIdent("left"), Exprs: yyDollar[3].selectExprs} + } + case 433: + yyDollar = yyS[yypt-4 : yypt+1] + //line sql.y:2250 + { + yyVAL.expr = &FuncExpr{Name: NewColIdent("right"), Exprs: yyDollar[3].selectExprs} + } + case 434: + yyDollar = yyS[yypt-6 : yypt+1] + //line sql.y:2254 + { + yyVAL.expr = &ConvertExpr{Expr: yyDollar[3].expr, Type: yyDollar[5].convertType} + } + case 435: + yyDollar = yyS[yypt-6 : yypt+1] + //line sql.y:2258 + { + yyVAL.expr = &ConvertExpr{Expr: yyDollar[3].expr, Type: yyDollar[5].convertType} + } + case 436: + yyDollar = yyS[yypt-6 : yypt+1] + //line sql.y:2262 + { + yyVAL.expr = &ConvertUsingExpr{Expr: yyDollar[3].expr, Type: yyDollar[5].str} + } + case 437: + yyDollar = yyS[yypt-6 : yypt+1] + //line sql.y:2266 + { + yyVAL.expr = &SubstrExpr{Name: yyDollar[3].colName, From: yyDollar[5].expr, To: nil} + } + case 438: + yyDollar = yyS[yypt-8 : yypt+1] + //line sql.y:2270 + { + yyVAL.expr = &SubstrExpr{Name: yyDollar[3].colName, From: yyDollar[5].expr, To: yyDollar[7].expr} + } + case 439: + yyDollar = yyS[yypt-8 : yypt+1] + //line sql.y:2274 + { + yyVAL.expr = &SubstrExpr{Name: yyDollar[3].colName, From: yyDollar[5].expr, To: yyDollar[7].expr} + } + case 440: + yyDollar = yyS[yypt-6 : yypt+1] + //line sql.y:2278 + { + yyVAL.expr = &SubstrExpr{Name: yyDollar[3].colName, From: yyDollar[5].expr, To: nil} + } + case 441: + yyDollar = yyS[yypt-8 : yypt+1] + //line sql.y:2282 + { + yyVAL.expr = &SubstrExpr{Name: yyDollar[3].colName, From: yyDollar[5].expr, To: yyDollar[7].expr} + } + case 442: + yyDollar = yyS[yypt-8 : yypt+1] + //line sql.y:2286 + { + yyVAL.expr = &SubstrExpr{Name: yyDollar[3].colName, From: yyDollar[5].expr, To: yyDollar[7].expr} + } + case 443: + yyDollar = yyS[yypt-9 : yypt+1] + //line sql.y:2290 + { + yyVAL.expr = &MatchExpr{Columns: yyDollar[3].selectExprs, Expr: yyDollar[7].expr, Option: yyDollar[8].str} + } + case 444: + yyDollar = yyS[yypt-7 : yypt+1] + //line sql.y:2294 + { + yyVAL.expr = &GroupConcatExpr{Distinct: yyDollar[3].str, Exprs: yyDollar[4].selectExprs, OrderBy: yyDollar[5].orderBy, Separator: yyDollar[6].str} + } + case 445: + yyDollar = yyS[yypt-5 : yypt+1] + //line sql.y:2298 + { + yyVAL.expr = &CaseExpr{Expr: yyDollar[2].expr, Whens: yyDollar[3].whens, Else: yyDollar[4].expr} + } + case 446: + yyDollar = yyS[yypt-4 : yypt+1] + //line sql.y:2302 + { + yyVAL.expr = &ValuesFuncExpr{Name: yyDollar[3].colName} + } + case 447: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:2312 + { + yyVAL.expr = &FuncExpr{Name: NewColIdent("current_timestamp")} + } + case 448: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:2316 + { + yyVAL.expr = &FuncExpr{Name: NewColIdent("utc_timestamp")} + } + case 449: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:2320 + { + yyVAL.expr = &FuncExpr{Name: NewColIdent("utc_time")} + } + case 450: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:2324 + { + yyVAL.expr = &FuncExpr{Name: NewColIdent("utc_date")} + } + case 451: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:2329 + { + yyVAL.expr = &FuncExpr{Name: NewColIdent("localtime")} + } + case 452: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:2334 + { + yyVAL.expr = &FuncExpr{Name: NewColIdent("localtimestamp")} + } + case 453: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:2339 + { + yyVAL.expr = &FuncExpr{Name: NewColIdent("current_date")} + } + case 454: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:2344 + { + yyVAL.expr = &FuncExpr{Name: NewColIdent("current_time")} + } + case 457: + yyDollar = yyS[yypt-4 : yypt+1] + //line sql.y:2358 + { + yyVAL.expr = &FuncExpr{Name: NewColIdent("if"), Exprs: yyDollar[3].selectExprs} + } + case 458: + yyDollar = yyS[yypt-4 : yypt+1] + //line sql.y:2362 + { + yyVAL.expr = &FuncExpr{Name: NewColIdent("database"), Exprs: yyDollar[3].selectExprs} + } + case 459: + yyDollar = yyS[yypt-4 : yypt+1] + //line sql.y:2366 + { + yyVAL.expr = &FuncExpr{Name: NewColIdent("mod"), Exprs: yyDollar[3].selectExprs} + } + case 460: + yyDollar = yyS[yypt-4 : yypt+1] + //line sql.y:2370 + { + yyVAL.expr = &FuncExpr{Name: NewColIdent("replace"), Exprs: yyDollar[3].selectExprs} + } + case 461: + yyDollar = yyS[yypt-0 : yypt+1] + //line sql.y:2376 + { + yyVAL.str = "" + } + case 462: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:2380 + { + yyVAL.str = BooleanModeStr + } + case 463: + yyDollar = yyS[yypt-4 : yypt+1] + //line sql.y:2384 + { + yyVAL.str = NaturalLanguageModeStr + } + case 464: + yyDollar = yyS[yypt-7 : yypt+1] + //line sql.y:2388 + { + yyVAL.str = NaturalLanguageModeWithQueryExpansionStr + } + case 465: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:2392 + { + yyVAL.str = QueryExpansionStr + } + case 466: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2398 + { + yyVAL.str = string(yyDollar[1].bytes) + } + case 467: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2402 + { + yyVAL.str = string(yyDollar[1].bytes) + } + case 468: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:2408 + { + yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes), Length: yyDollar[2].optVal} + } + case 469: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:2412 + { + yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes), Length: yyDollar[2].optVal, Charset: yyDollar[3].str, Operator: CharacterSetStr} + } + case 470: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:2416 + { + yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes), Length: yyDollar[2].optVal, Charset: string(yyDollar[3].bytes)} + } + case 471: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2420 + { + yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes)} + } + case 472: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:2424 + { + yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes), Length: yyDollar[2].optVal} + } + case 473: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:2428 + { + yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes)} + yyVAL.convertType.Length = yyDollar[2].LengthScaleOption.Length + yyVAL.convertType.Scale = yyDollar[2].LengthScaleOption.Scale + } + case 474: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2434 + { + yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes)} + } + case 475: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:2438 + { + yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes), Length: yyDollar[2].optVal} + } + case 476: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2442 + { + yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes)} + } + case 477: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:2446 + { + yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes)} + } + case 478: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:2450 + { + yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes), Length: yyDollar[2].optVal} + } + case 479: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2454 + { + yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes)} + } + case 480: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:2458 + { + yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes)} + } + case 481: + yyDollar = yyS[yypt-0 : yypt+1] + //line sql.y:2463 + { + yyVAL.expr = nil + } + case 482: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2467 + { + yyVAL.expr = yyDollar[1].expr + } + case 483: + yyDollar = yyS[yypt-0 : yypt+1] + //line sql.y:2472 + { + yyVAL.str = string("") + } + case 484: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:2476 + { + yyVAL.str = " separator '" + string(yyDollar[2].bytes) + "'" + } + case 485: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2482 + { + yyVAL.whens = []*When{yyDollar[1].when} + } + case 486: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:2486 + { + yyVAL.whens = append(yyDollar[1].whens, yyDollar[2].when) + } + case 487: + yyDollar = yyS[yypt-4 : yypt+1] + //line sql.y:2492 + { + yyVAL.when = &When{Cond: yyDollar[2].expr, Val: yyDollar[4].expr} + } + case 488: + yyDollar = yyS[yypt-0 : yypt+1] + //line sql.y:2497 + { + yyVAL.expr = nil + } + case 489: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:2501 + { + yyVAL.expr = yyDollar[2].expr + } + case 490: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2507 + { + yyVAL.colName = &ColName{Name: yyDollar[1].colIdent} + } + case 491: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:2511 + { + yyVAL.colName = &ColName{Qualifier: TableName{Name: yyDollar[1].tableIdent}, Name: yyDollar[3].colIdent} + } + case 492: + yyDollar = yyS[yypt-5 : yypt+1] + //line sql.y:2515 + { + yyVAL.colName = &ColName{Qualifier: TableName{Qualifier: yyDollar[1].tableIdent, Name: yyDollar[3].tableIdent}, Name: yyDollar[5].colIdent} + } + case 493: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2521 + { + yyVAL.expr = NewStrVal(yyDollar[1].bytes) + } + case 494: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2525 + { + yyVAL.expr = NewHexVal(yyDollar[1].bytes) + } + case 495: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2529 + { + yyVAL.expr = NewBitVal(yyDollar[1].bytes) + } + case 496: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2533 + { + yyVAL.expr = NewIntVal(yyDollar[1].bytes) + } + case 497: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2537 + { + yyVAL.expr = NewFloatVal(yyDollar[1].bytes) + } + case 498: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2541 + { + yyVAL.expr = NewHexNum(yyDollar[1].bytes) + } + case 499: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2545 + { + yyVAL.expr = NewValArg(yyDollar[1].bytes) + } + case 500: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2549 + { + yyVAL.expr = &NullVal{} + } + case 501: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2555 + { + // TODO(sougou): Deprecate this construct. + if yyDollar[1].colIdent.Lowered() != "value" { + yylex.Error("expecting value after next") + return 1 + } + yyVAL.expr = NewIntVal([]byte("1")) + } + case 502: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:2564 + { + yyVAL.expr = NewIntVal(yyDollar[1].bytes) + } + case 503: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:2568 + { + yyVAL.expr = NewValArg(yyDollar[1].bytes) + } + case 504: + yyDollar = yyS[yypt-0 : yypt+1] + //line sql.y:2573 + { + yyVAL.exprs = nil + } + case 505: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:2577 + { + yyVAL.exprs = yyDollar[3].exprs + } + case 506: + yyDollar = yyS[yypt-0 : yypt+1] + //line sql.y:2582 + { + yyVAL.expr = nil + } + case 507: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:2586 + { + yyVAL.expr = yyDollar[2].expr + } + case 508: + yyDollar = yyS[yypt-0 : yypt+1] + //line sql.y:2591 + { + yyVAL.orderBy = nil + } + case 509: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:2595 + { + yyVAL.orderBy = yyDollar[3].orderBy + } + case 510: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2601 + { + yyVAL.orderBy = OrderBy{yyDollar[1].order} + } + case 511: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:2605 + { + yyVAL.orderBy = append(yyDollar[1].orderBy, yyDollar[3].order) + } + case 512: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:2611 + { + yyVAL.order = &Order{Expr: yyDollar[1].expr, Direction: yyDollar[2].str} + } + case 513: + yyDollar = yyS[yypt-0 : yypt+1] + //line sql.y:2616 + { + yyVAL.str = AscScr + } + case 514: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2620 + { + yyVAL.str = AscScr + } + case 515: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2624 + { + yyVAL.str = DescScr + } + case 516: + yyDollar = yyS[yypt-0 : yypt+1] + //line sql.y:2629 + { + yyVAL.limit = nil + } + case 517: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:2633 + { + yyVAL.limit = &Limit{Rowcount: yyDollar[2].expr} + } + case 518: + yyDollar = yyS[yypt-4 : yypt+1] + //line sql.y:2637 + { + yyVAL.limit = &Limit{Offset: yyDollar[2].expr, Rowcount: yyDollar[4].expr} + } + case 519: + yyDollar = yyS[yypt-4 : yypt+1] + //line sql.y:2641 + { + yyVAL.limit = &Limit{Offset: yyDollar[4].expr, Rowcount: yyDollar[2].expr} + } + case 520: + yyDollar = yyS[yypt-0 : yypt+1] + //line sql.y:2646 + { + yyVAL.str = "" + } + case 521: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:2650 + { + yyVAL.str = ForUpdateStr + } + case 522: + yyDollar = yyS[yypt-4 : yypt+1] + //line sql.y:2654 + { + yyVAL.str = ShareModeStr + } + case 523: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:2667 + { + yyVAL.ins = &Insert{Rows: yyDollar[2].values} + } + case 524: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2671 + { + yyVAL.ins = &Insert{Rows: yyDollar[1].selStmt} + } + case 525: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:2675 + { + // Drop the redundant parenthesis. + yyVAL.ins = &Insert{Rows: yyDollar[2].selStmt} + } + case 526: + yyDollar = yyS[yypt-5 : yypt+1] + //line sql.y:2680 + { + yyVAL.ins = &Insert{Columns: yyDollar[2].columns, Rows: yyDollar[5].values} + } + case 527: + yyDollar = yyS[yypt-4 : yypt+1] + //line sql.y:2684 + { + yyVAL.ins = &Insert{Columns: yyDollar[2].columns, Rows: yyDollar[4].selStmt} + } + case 528: + yyDollar = yyS[yypt-6 : yypt+1] + //line sql.y:2688 + { + // Drop the redundant parenthesis. + yyVAL.ins = &Insert{Columns: yyDollar[2].columns, Rows: yyDollar[5].selStmt} + } + case 529: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2695 + { + yyVAL.columns = Columns{yyDollar[1].colIdent} + } + case 530: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:2699 + { + yyVAL.columns = Columns{yyDollar[3].colIdent} + } + case 531: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:2703 + { + yyVAL.columns = append(yyVAL.columns, yyDollar[3].colIdent) + } + case 532: + yyDollar = yyS[yypt-5 : yypt+1] + //line sql.y:2707 + { + yyVAL.columns = append(yyVAL.columns, yyDollar[5].colIdent) + } + case 533: + yyDollar = yyS[yypt-0 : yypt+1] + //line sql.y:2712 + { + yyVAL.updateExprs = nil + } + case 534: + yyDollar = yyS[yypt-5 : yypt+1] + //line sql.y:2716 + { + yyVAL.updateExprs = yyDollar[5].updateExprs + } + case 535: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2722 + { + yyVAL.values = Values{yyDollar[1].valTuple} + } + case 536: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:2726 + { + yyVAL.values = append(yyDollar[1].values, yyDollar[3].valTuple) + } + case 537: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2732 + { + yyVAL.valTuple = yyDollar[1].valTuple + } + case 538: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:2736 + { + yyVAL.valTuple = ValTuple{} + } + case 539: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:2742 + { + yyVAL.valTuple = ValTuple(yyDollar[2].exprs) + } + case 540: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2748 + { + if len(yyDollar[1].valTuple) == 1 { + yyVAL.expr = &ParenExpr{yyDollar[1].valTuple[0]} + } else { + yyVAL.expr = yyDollar[1].valTuple + } + } + case 541: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2758 + { + yyVAL.updateExprs = UpdateExprs{yyDollar[1].updateExpr} + } + case 542: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:2762 + { + yyVAL.updateExprs = append(yyDollar[1].updateExprs, yyDollar[3].updateExpr) + } + case 543: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:2768 + { + yyVAL.updateExpr = &UpdateExpr{Name: yyDollar[1].colName, Expr: yyDollar[3].expr} + } + case 544: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2774 + { + yyVAL.setExprs = SetExprs{yyDollar[1].setExpr} + } + case 545: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:2778 + { + yyVAL.setExprs = append(yyDollar[1].setExprs, yyDollar[3].setExpr) + } + case 546: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:2784 + { + yyVAL.setExpr = &SetExpr{Name: yyDollar[1].colIdent, Expr: NewStrVal([]byte("on"))} + } + case 547: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:2788 + { + yyVAL.setExpr = &SetExpr{Name: yyDollar[1].colIdent, Expr: yyDollar[3].expr} + } + case 548: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:2792 + { + yyVAL.setExpr = &SetExpr{Name: NewColIdent(string(yyDollar[1].bytes)), Expr: yyDollar[2].expr} + } + case 550: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:2799 + { + yyVAL.bytes = []byte("charset") + } + case 552: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2806 + { + yyVAL.expr = NewStrVal([]byte(yyDollar[1].colIdent.String())) + } + case 553: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2810 + { + yyVAL.expr = NewStrVal(yyDollar[1].bytes) + } + case 554: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2814 + { + yyVAL.expr = &Default{} + } + case 557: + yyDollar = yyS[yypt-0 : yypt+1] + //line sql.y:2823 + { + yyVAL.byt = 0 + } + case 558: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:2825 + { + yyVAL.byt = 1 + } + case 559: + yyDollar = yyS[yypt-0 : yypt+1] + //line sql.y:2828 + { + yyVAL.empty = struct{}{} + } + case 560: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:2830 + { + yyVAL.empty = struct{}{} + } + case 561: + yyDollar = yyS[yypt-0 : yypt+1] + //line sql.y:2833 + { + yyVAL.str = "" + } + case 562: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2835 + { + yyVAL.str = IgnoreStr + } + case 563: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2839 + { + yyVAL.empty = struct{}{} + } + case 564: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2841 + { + yyVAL.empty = struct{}{} + } + case 565: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2843 + { + yyVAL.empty = struct{}{} + } + case 566: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2845 + { + yyVAL.empty = struct{}{} + } + case 567: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2847 + { + yyVAL.empty = struct{}{} + } + case 568: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2849 + { + yyVAL.empty = struct{}{} + } + case 569: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2851 + { + yyVAL.empty = struct{}{} + } + case 570: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2853 + { + yyVAL.empty = struct{}{} + } + case 571: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2855 + { + yyVAL.empty = struct{}{} + } + case 572: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2857 + { + yyVAL.empty = struct{}{} + } + case 573: + yyDollar = yyS[yypt-0 : yypt+1] + //line sql.y:2860 + { + yyVAL.empty = struct{}{} + } + case 574: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2862 + { + yyVAL.empty = struct{}{} + } + case 575: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2864 + { + yyVAL.empty = struct{}{} + } + case 576: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2868 + { + yyVAL.empty = struct{}{} + } + case 577: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2870 + { + yyVAL.empty = struct{}{} + } + case 578: + yyDollar = yyS[yypt-0 : yypt+1] + //line sql.y:2873 + { + yyVAL.empty = struct{}{} + } + case 579: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2875 + { + yyVAL.empty = struct{}{} + } + case 580: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2877 + { + yyVAL.empty = struct{}{} + } + case 581: + yyDollar = yyS[yypt-0 : yypt+1] + //line sql.y:2880 + { + yyVAL.colIdent = ColIdent{} + } + case 582: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:2882 + { + yyVAL.colIdent = yyDollar[2].colIdent + } + case 583: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2886 + { + yyVAL.colIdent = NewColIdent(string(yyDollar[1].bytes)) + } + case 584: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2890 + { + yyVAL.colIdent = NewColIdent(string(yyDollar[1].bytes)) + } + case 586: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2897 + { + yyVAL.colIdent = NewColIdent(string(yyDollar[1].bytes)) + } + case 587: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2903 + { + yyVAL.tableIdent = NewTableIdent(string(yyDollar[1].bytes)) + } + case 588: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2907 + { + yyVAL.tableIdent = NewTableIdent(string(yyDollar[1].bytes)) + } + case 590: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2914 + { + yyVAL.tableIdent = NewTableIdent(string(yyDollar[1].bytes)) + } + case 781: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:3130 + { + if incNesting(yylex) { + yylex.Error("max nesting level reached") + return 1 + } + } + case 782: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:3139 + { + decNesting(yylex) + } + case 783: + yyDollar = yyS[yypt-0 : yypt+1] + //line sql.y:3144 + { + forceEOF(yylex) + } + case 784: + yyDollar = yyS[yypt-0 : yypt+1] + //line sql.y:3149 + { + forceEOF(yylex) + } + case 785: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:3153 + { + forceEOF(yylex) + } + case 786: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:3157 + { + forceEOF(yylex) + } + } + goto yystack /* stack new state and value */ +} diff --git a/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/sql.y b/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/sql.y new file mode 100644 index 00000000..efbb794c --- /dev/null +++ b/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/sql.y @@ -0,0 +1,3159 @@ +/* +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 sqlparser + +func setParseTree(yylex interface{}, stmt Statement) { + yylex.(*Tokenizer).ParseTree = stmt +} + +func setAllowComments(yylex interface{}, allow bool) { + yylex.(*Tokenizer).AllowComments = allow +} + +func setDDL(yylex interface{}, ddl *DDL) { + yylex.(*Tokenizer).partialDDL = ddl +} + +func incNesting(yylex interface{}) bool { + yylex.(*Tokenizer).nesting++ + if yylex.(*Tokenizer).nesting == 200 { + return true + } + return false +} + +func decNesting(yylex interface{}) { + yylex.(*Tokenizer).nesting-- +} + +// forceEOF forces the lexer to end prematurely. Not all SQL statements +// are supported by the Parser, thus calling forceEOF will make the lexer +// return EOF early. +func forceEOF(yylex interface{}) { + yylex.(*Tokenizer).ForceEOF = true +} + +%} + +%union { + empty struct{} + statement Statement + selStmt SelectStatement + ddl *DDL + ins *Insert + byt byte + bytes []byte + bytes2 [][]byte + str string + strs []string + selectExprs SelectExprs + selectExpr SelectExpr + columns Columns + partitions Partitions + colName *ColName + tableExprs TableExprs + tableExpr TableExpr + joinCondition JoinCondition + tableName TableName + tableNames TableNames + indexHints *IndexHints + expr Expr + exprs Exprs + boolVal BoolVal + colTuple ColTuple + values Values + valTuple ValTuple + subquery *Subquery + whens []*When + when *When + orderBy OrderBy + order *Order + limit *Limit + updateExprs UpdateExprs + setExprs SetExprs + updateExpr *UpdateExpr + setExpr *SetExpr + colIdent ColIdent + tableIdent TableIdent + convertType *ConvertType + aliasedTableName *AliasedTableExpr + TableSpec *TableSpec + columnType ColumnType + colKeyOpt ColumnKeyOption + optVal *SQLVal + LengthScaleOption LengthScaleOption + columnDefinition *ColumnDefinition + indexDefinition *IndexDefinition + indexInfo *IndexInfo + indexOption *IndexOption + indexOptions []*IndexOption + indexColumn *IndexColumn + indexColumns []*IndexColumn + partDefs []*PartitionDefinition + partDef *PartitionDefinition + partSpec *PartitionSpec + vindexParam VindexParam + vindexParams []VindexParam + showFilter *ShowFilter +} + +%token LEX_ERROR +%left UNION +%token SELECT STREAM INSERT UPDATE DELETE FROM WHERE GROUP HAVING ORDER BY LIMIT OFFSET FOR +%token ALL DISTINCT AS EXISTS ASC DESC INTO DUPLICATE KEY DEFAULT SET LOCK KEYS +%token VALUES LAST_INSERT_ID +%token NEXT VALUE SHARE MODE +%token SQL_NO_CACHE SQL_CACHE +%left JOIN STRAIGHT_JOIN LEFT RIGHT INNER OUTER CROSS NATURAL USE FORCE +%left ON USING +%token '(' ',' ')' +%token ID HEX STRING INTEGRAL FLOAT HEXNUM VALUE_ARG LIST_ARG COMMENT COMMENT_KEYWORD BIT_LITERAL +%token NULL TRUE FALSE + +// Precedence dictated by mysql. But the vitess grammar is simplified. +// Some of these operators don't conflict in our situation. Nevertheless, +// it's better to have these listed in the correct order. Also, we don't +// support all operators yet. +%left OR +%left AND +%right NOT '!' +%left BETWEEN CASE WHEN THEN ELSE END +%left '=' '<' '>' LE GE NE NULL_SAFE_EQUAL IS LIKE REGEXP IN +%left '|' +%left '&' +%left SHIFT_LEFT SHIFT_RIGHT +%left '+' '-' +%left '*' '/' DIV '%' MOD +%left '^' +%right '~' UNARY +%left COLLATE +%right BINARY UNDERSCORE_BINARY +%right INTERVAL +%nonassoc '.' + +// There is no need to define precedence for the JSON +// operators because the syntax is restricted enough that +// they don't cause conflicts. +%token JSON_EXTRACT_OP JSON_UNQUOTE_EXTRACT_OP + +// DDL Tokens +%token CREATE ALTER DROP RENAME ANALYZE ADD +%token SCHEMA TABLE INDEX VIEW TO IGNORE IF UNIQUE PRIMARY COLUMN CONSTRAINT SPATIAL FULLTEXT FOREIGN KEY_BLOCK_SIZE +%token SHOW DESCRIBE EXPLAIN DATE ESCAPE REPAIR OPTIMIZE TRUNCATE +%token MAXVALUE PARTITION REORGANIZE LESS THAN PROCEDURE TRIGGER +%token VINDEX VINDEXES +%token STATUS VARIABLES + +// Transaction Tokens +%token BEGIN START TRANSACTION COMMIT ROLLBACK + +// Type Tokens +%token BIT TINYINT SMALLINT MEDIUMINT INT INTEGER BIGINT INTNUM +%token REAL DOUBLE FLOAT_TYPE DECIMAL NUMERIC +%token TIME TIMESTAMP DATETIME YEAR +%token CHAR VARCHAR BOOL CHARACTER VARBINARY NCHAR +%token TEXT TINYTEXT MEDIUMTEXT LONGTEXT +%token BLOB TINYBLOB MEDIUMBLOB LONGBLOB JSON ENUM +%token GEOMETRY POINT LINESTRING POLYGON GEOMETRYCOLLECTION MULTIPOINT MULTILINESTRING MULTIPOLYGON + +// Type Modifiers +%token NULLX AUTO_INCREMENT APPROXNUM SIGNED UNSIGNED ZEROFILL + +// Supported SHOW tokens +%token DATABASES TABLES VITESS_KEYSPACES VITESS_SHARDS VITESS_TABLETS VSCHEMA_TABLES EXTENDED FULL PROCESSLIST + +// SET tokens +%token NAMES CHARSET GLOBAL SESSION ISOLATION LEVEL READ WRITE ONLY REPEATABLE COMMITTED UNCOMMITTED SERIALIZABLE + +// Functions +%token CURRENT_TIMESTAMP DATABASE CURRENT_DATE +%token CURRENT_TIME LOCALTIME LOCALTIMESTAMP +%token UTC_DATE UTC_TIME UTC_TIMESTAMP +%token REPLACE +%token CONVERT CAST +%token SUBSTR SUBSTRING +%token GROUP_CONCAT SEPARATOR + +// Match +%token MATCH AGAINST BOOLEAN LANGUAGE WITH QUERY EXPANSION + +// MySQL reserved words that are unused by this grammar will map to this token. +%token UNUSED + +%type command +%type select_statement base_select union_lhs union_rhs +%type stream_statement insert_statement update_statement delete_statement set_statement +%type create_statement alter_statement rename_statement drop_statement truncate_statement +%type create_table_prefix +%type analyze_statement show_statement use_statement other_statement +%type begin_statement commit_statement rollback_statement +%type comment_opt comment_list +%type union_op insert_or_replace +%type distinct_opt straight_join_opt cache_opt match_option separator_opt +%type like_escape_opt +%type select_expression_list select_expression_list_opt +%type select_expression +%type expression +%type from_opt table_references +%type table_reference table_factor join_table +%type join_condition join_condition_opt on_expression_opt +%type table_name_list +%type inner_join outer_join straight_join natural_join +%type table_name into_table_name +%type aliased_table_name +%type index_hint_list +%type where_expression_opt +%type condition +%type boolean_value +%type compare +%type insert_data +%type value value_expression num_val +%type function_call_keyword function_call_nonkeyword function_call_generic function_call_conflict +%type is_suffix +%type col_tuple +%type expression_list +%type tuple_list +%type row_tuple tuple_or_empty +%type tuple_expression +%type subquery +%type column_name +%type when_expression_list +%type when_expression +%type expression_opt else_expression_opt +%type group_by_opt +%type having_opt +%type order_by_opt order_list +%type order +%type asc_desc_opt +%type limit_opt +%type lock_opt +%type ins_column_list column_list +%type opt_partition_clause partition_list +%type on_dup_opt +%type update_list +%type set_list transaction_chars +%type charset_or_character_set +%type update_expression +%type set_expression transaction_char isolation_level +%type for_from +%type ignore_opt default_opt +%type extended_opt full_opt from_database_opt tables_or_processlist +%type like_or_where_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 +%type sql_id reserved_sql_id col_alias as_ci_opt using_opt +%type charset_value +%type table_id reserved_table_id table_alias as_opt_id +%type as_opt +%type force_eof ddl_force_eof +%type charset +%type set_session_or_global show_session_or_global +%type convert_type +%type column_type +%type int_type decimal_type numeric_type time_type char_type spatial_type +%type length_opt column_default_opt column_comment_opt on_update_opt +%type charset_opt collate_opt +%type unsigned_opt zero_fill_opt +%type float_length_opt decimal_length_opt +%type null_opt auto_increment_opt +%type column_key_opt +%type enum_values +%type column_definition +%type index_definition +%type index_or_key +%type equal_opt +%type table_spec table_column_list +%type table_option_list table_option table_opt_value +%type index_info +%type index_column +%type index_column_list +%type index_option +%type index_option_list +%type partition_definitions +%type partition_definition +%type partition_operation +%type vindex_param +%type vindex_param_list vindex_params_opt +%type vindex_type vindex_type_opt +%type alter_object_type + +%start any_command + +%% + +any_command: + command semicolon_opt + { + setParseTree(yylex, $1) + } + +semicolon_opt: +/*empty*/ {} +| ';' {} + +command: + select_statement + { + $$ = $1 + } +| stream_statement +| insert_statement +| update_statement +| delete_statement +| set_statement +| create_statement +| alter_statement +| rename_statement +| drop_statement +| truncate_statement +| analyze_statement +| show_statement +| use_statement +| begin_statement +| commit_statement +| rollback_statement +| other_statement + +select_statement: + base_select order_by_opt limit_opt lock_opt + { + sel := $1.(*Select) + sel.OrderBy = $2 + sel.Limit = $3 + sel.Lock = $4 + $$ = sel + } +| union_lhs union_op union_rhs order_by_opt limit_opt lock_opt + { + $$ = &Union{Type: $2, Left: $1, Right: $3, OrderBy: $4, Limit: $5, Lock: $6} + } +| SELECT comment_opt cache_opt NEXT num_val for_from table_name + { + $$ = &Select{Comments: Comments($2), Cache: $3, SelectExprs: SelectExprs{Nextval{Expr: $5}}, From: TableExprs{&AliasedTableExpr{Expr: $7}}} + } + +stream_statement: + STREAM comment_opt select_expression FROM table_name + { + $$ = &Stream{Comments: Comments($2), SelectExpr: $3, Table: $5} + } + +// base_select is an unparenthesized SELECT with no order by clause or beyond. +base_select: + SELECT comment_opt cache_opt distinct_opt straight_join_opt select_expression_list from_opt where_expression_opt group_by_opt having_opt + { + $$ = &Select{Comments: Comments($2), Cache: $3, Distinct: $4, Hints: $5, SelectExprs: $6, From: $7, Where: NewWhere(WhereStr, $8), GroupBy: GroupBy($9), Having: NewWhere(HavingStr, $10)} + } + +union_lhs: + select_statement + { + $$ = $1 + } +| openb select_statement closeb + { + $$ = &ParenSelect{Select: $2} + } + +union_rhs: + base_select + { + $$ = $1 + } +| openb select_statement closeb + { + $$ = &ParenSelect{Select: $2} + } + + +insert_statement: + insert_or_replace comment_opt ignore_opt into_table_name opt_partition_clause insert_data on_dup_opt + { + // insert_data returns a *Insert pre-filled with Columns & Values + ins := $6 + ins.Action = $1 + ins.Comments = $2 + ins.Ignore = $3 + ins.Table = $4 + ins.Partitions = $5 + ins.OnDup = OnDup($7) + $$ = ins + } +| insert_or_replace comment_opt ignore_opt into_table_name opt_partition_clause SET update_list on_dup_opt + { + cols := make(Columns, 0, len($7)) + vals := make(ValTuple, 0, len($8)) + for _, updateList := range $7 { + cols = append(cols, updateList.Name.Name) + vals = append(vals, updateList.Expr) + } + $$ = &Insert{Action: $1, Comments: Comments($2), Ignore: $3, Table: $4, Partitions: $5, Columns: cols, Rows: Values{vals}, OnDup: OnDup($8)} + } + +insert_or_replace: + INSERT + { + $$ = InsertStr + } +| REPLACE + { + $$ = ReplaceStr + } + +update_statement: + UPDATE comment_opt table_references SET update_list where_expression_opt order_by_opt limit_opt + { + $$ = &Update{Comments: Comments($2), TableExprs: $3, Exprs: $5, Where: NewWhere(WhereStr, $6), OrderBy: $7, Limit: $8} + } + +delete_statement: + DELETE comment_opt FROM table_name opt_partition_clause where_expression_opt order_by_opt limit_opt + { + $$ = &Delete{Comments: Comments($2), TableExprs: TableExprs{&AliasedTableExpr{Expr:$4}}, Partitions: $5, Where: NewWhere(WhereStr, $6), OrderBy: $7, Limit: $8} + } +| DELETE comment_opt FROM table_name_list USING table_references where_expression_opt + { + $$ = &Delete{Comments: Comments($2), Targets: $4, TableExprs: $6, Where: NewWhere(WhereStr, $7)} + } +| DELETE comment_opt table_name_list from_or_using table_references where_expression_opt + { + $$ = &Delete{Comments: Comments($2), Targets: $3, TableExprs: $5, Where: NewWhere(WhereStr, $6)} + } + +from_or_using: + FROM {} +| USING {} + +table_name_list: + table_name + { + $$ = TableNames{$1} + } +| table_name_list ',' table_name + { + $$ = append($$, $3) + } + +opt_partition_clause: + { + $$ = nil + } +| PARTITION openb partition_list closeb + { + $$ = $3 + } + +set_statement: + SET comment_opt set_list + { + $$ = &Set{Comments: Comments($2), Exprs: $3} + } +| SET comment_opt set_session_or_global set_list + { + $$ = &Set{Comments: Comments($2), Scope: $3, Exprs: $4} + } +| SET comment_opt set_session_or_global TRANSACTION transaction_chars + { + $$ = &Set{Comments: Comments($2), Scope: $3, Exprs: $5} + } +| SET comment_opt TRANSACTION transaction_chars + { + $$ = &Set{Comments: Comments($2), Exprs: $4} + } + +transaction_chars: + transaction_char + { + $$ = SetExprs{$1} + } +| transaction_chars ',' transaction_char + { + $$ = append($$, $3) + } + +transaction_char: + ISOLATION LEVEL isolation_level + { + $$ = $3 + } +| READ WRITE + { + $$ = &SetExpr{Name: NewColIdent("tx_read_only"), Expr: NewIntVal([]byte("0"))} + } +| READ ONLY + { + $$ = &SetExpr{Name: NewColIdent("tx_read_only"), Expr: NewIntVal([]byte("1"))} + } + +isolation_level: + REPEATABLE READ + { + $$ = &SetExpr{Name: NewColIdent("tx_isolation"), Expr: NewStrVal([]byte("repeatable read"))} + } +| READ COMMITTED + { + $$ = &SetExpr{Name: NewColIdent("tx_isolation"), Expr: NewStrVal([]byte("read committed"))} + } +| READ UNCOMMITTED + { + $$ = &SetExpr{Name: NewColIdent("tx_isolation"), Expr: NewStrVal([]byte("read uncommitted"))} + } +| SERIALIZABLE + { + $$ = &SetExpr{Name: NewColIdent("tx_isolation"), Expr: NewStrVal([]byte("serializable"))} + } + +set_session_or_global: + SESSION + { + $$ = SessionStr + } +| GLOBAL + { + $$ = GlobalStr + } + +create_statement: + create_table_prefix table_spec + { + $1.TableSpec = $2 + $$ = $1 + } +| CREATE constraint_opt INDEX ID using_opt ON table_name ddl_force_eof + { + // Change this to an alter statement + $$ = &DDL{Action: AlterStr, Table: $7, NewName:$7} + } +| CREATE VIEW table_name ddl_force_eof + { + $$ = &DDL{Action: CreateStr, NewName: $3.ToViewName()} + } +| CREATE OR REPLACE VIEW table_name ddl_force_eof + { + $$ = &DDL{Action: CreateStr, NewName: $5.ToViewName()} + } +| CREATE VINDEX sql_id vindex_type_opt vindex_params_opt + { + $$ = &DDL{Action: CreateVindexStr, VindexSpec: &VindexSpec{ + Name: $3, + Type: $4, + Params: $5, + }} + } +| CREATE DATABASE not_exists_opt ID ddl_force_eof + { + $$ = &DBDDL{Action: CreateStr, DBName: string($4)} + } +| CREATE SCHEMA not_exists_opt ID ddl_force_eof + { + $$ = &DBDDL{Action: CreateStr, DBName: string($4)} + } + +vindex_type_opt: + { + $$ = NewColIdent("") + } +| USING vindex_type + { + $$ = $2 + } + +vindex_type: + ID + { + $$ = NewColIdent(string($1)) + } + +vindex_params_opt: + { + var v []VindexParam + $$ = v + } +| WITH vindex_param_list + { + $$ = $2 + } + +vindex_param_list: + vindex_param + { + $$ = make([]VindexParam, 0, 4) + $$ = append($$, $1) + } +| vindex_param_list ',' vindex_param + { + $$ = append($$, $3) + } + +vindex_param: + reserved_sql_id '=' table_opt_value + { + $$ = VindexParam{Key: $1, Val: $3} + } + +create_table_prefix: + CREATE TABLE not_exists_opt table_name + { + $$ = &DDL{Action: CreateStr, NewName: $4} + setDDL(yylex, $$) + } + +table_spec: + '(' table_column_list ')' table_option_list + { + $$ = $2 + $$.Options = $4 + } + +table_column_list: + column_definition + { + $$ = &TableSpec{} + $$.AddColumn($1) + } +| table_column_list ',' column_definition + { + $$.AddColumn($3) + } +| table_column_list ',' index_definition + { + $$.AddIndex($3) + } + +column_definition: + ID column_type null_opt column_default_opt on_update_opt auto_increment_opt column_key_opt column_comment_opt + { + $2.NotNull = $3 + $2.Default = $4 + $2.OnUpdate = $5 + $2.Autoincrement = $6 + $2.KeyOpt = $7 + $2.Comment = $8 + $$ = &ColumnDefinition{Name: NewColIdent(string($1)), Type: $2} + } +column_type: + numeric_type unsigned_opt zero_fill_opt + { + $$ = $1 + $$.Unsigned = $2 + $$.Zerofill = $3 + } +| char_type +| time_type +| spatial_type + +numeric_type: + int_type length_opt + { + $$ = $1 + $$.Length = $2 + } +| decimal_type + { + $$ = $1 + } + +int_type: + BIT + { + $$ = ColumnType{Type: string($1)} + } +| TINYINT + { + $$ = ColumnType{Type: string($1)} + } +| SMALLINT + { + $$ = ColumnType{Type: string($1)} + } +| MEDIUMINT + { + $$ = ColumnType{Type: string($1)} + } +| INT + { + $$ = ColumnType{Type: string($1)} + } +| INTEGER + { + $$ = ColumnType{Type: string($1)} + } +| BIGINT + { + $$ = ColumnType{Type: string($1)} + } + +decimal_type: +REAL float_length_opt + { + $$ = ColumnType{Type: string($1)} + $$.Length = $2.Length + $$.Scale = $2.Scale + } +| DOUBLE float_length_opt + { + $$ = ColumnType{Type: string($1)} + $$.Length = $2.Length + $$.Scale = $2.Scale + } +| FLOAT_TYPE float_length_opt + { + $$ = ColumnType{Type: string($1)} + $$.Length = $2.Length + $$.Scale = $2.Scale + } +| DECIMAL decimal_length_opt + { + $$ = ColumnType{Type: string($1)} + $$.Length = $2.Length + $$.Scale = $2.Scale + } +| NUMERIC decimal_length_opt + { + $$ = ColumnType{Type: string($1)} + $$.Length = $2.Length + $$.Scale = $2.Scale + } + +time_type: + DATE + { + $$ = ColumnType{Type: string($1)} + } +| TIME length_opt + { + $$ = ColumnType{Type: string($1), Length: $2} + } +| TIMESTAMP length_opt + { + $$ = ColumnType{Type: string($1), Length: $2} + } +| DATETIME length_opt + { + $$ = ColumnType{Type: string($1), Length: $2} + } +| YEAR + { + $$ = ColumnType{Type: string($1)} + } + +char_type: + CHAR length_opt charset_opt collate_opt + { + $$ = ColumnType{Type: string($1), Length: $2, Charset: $3, Collate: $4} + } +| VARCHAR length_opt charset_opt collate_opt + { + $$ = ColumnType{Type: string($1), Length: $2, Charset: $3, Collate: $4} + } +| BINARY length_opt + { + $$ = ColumnType{Type: string($1), Length: $2} + } +| VARBINARY length_opt + { + $$ = ColumnType{Type: string($1), Length: $2} + } +| TEXT charset_opt collate_opt + { + $$ = ColumnType{Type: string($1), Charset: $2, Collate: $3} + } +| TINYTEXT charset_opt collate_opt + { + $$ = ColumnType{Type: string($1), Charset: $2, Collate: $3} + } +| MEDIUMTEXT charset_opt collate_opt + { + $$ = ColumnType{Type: string($1), Charset: $2, Collate: $3} + } +| LONGTEXT charset_opt collate_opt + { + $$ = ColumnType{Type: string($1), Charset: $2, Collate: $3} + } +| BLOB + { + $$ = ColumnType{Type: string($1)} + } +| TINYBLOB + { + $$ = ColumnType{Type: string($1)} + } +| MEDIUMBLOB + { + $$ = ColumnType{Type: string($1)} + } +| LONGBLOB + { + $$ = ColumnType{Type: string($1)} + } +| JSON + { + $$ = ColumnType{Type: string($1)} + } +| ENUM '(' enum_values ')' charset_opt collate_opt + { + $$ = ColumnType{Type: string($1), EnumValues: $3, Charset: $5, Collate: $6} + } +// need set_values / SetValues ? +| SET '(' enum_values ')' charset_opt collate_opt + { + $$ = ColumnType{Type: string($1), EnumValues: $3, Charset: $5, Collate: $6} + } + +spatial_type: + GEOMETRY + { + $$ = ColumnType{Type: string($1)} + } +| POINT + { + $$ = ColumnType{Type: string($1)} + } +| LINESTRING + { + $$ = ColumnType{Type: string($1)} + } +| POLYGON + { + $$ = ColumnType{Type: string($1)} + } +| GEOMETRYCOLLECTION + { + $$ = ColumnType{Type: string($1)} + } +| MULTIPOINT + { + $$ = ColumnType{Type: string($1)} + } +| MULTILINESTRING + { + $$ = ColumnType{Type: string($1)} + } +| MULTIPOLYGON + { + $$ = ColumnType{Type: string($1)} + } + +enum_values: + STRING + { + $$ = make([]string, 0, 4) + $$ = append($$, "'" + string($1) + "'") + } +| enum_values ',' STRING + { + $$ = append($1, "'" + string($3) + "'") + } + +length_opt: + { + $$ = nil + } +| '(' INTEGRAL ')' + { + $$ = NewIntVal($2) + } + +float_length_opt: + { + $$ = LengthScaleOption{} + } +| '(' INTEGRAL ',' INTEGRAL ')' + { + $$ = LengthScaleOption{ + Length: NewIntVal($2), + Scale: NewIntVal($4), + } + } + +decimal_length_opt: + { + $$ = LengthScaleOption{} + } +| '(' INTEGRAL ')' + { + $$ = LengthScaleOption{ + Length: NewIntVal($2), + } + } +| '(' INTEGRAL ',' INTEGRAL ')' + { + $$ = LengthScaleOption{ + Length: NewIntVal($2), + Scale: NewIntVal($4), + } + } + +unsigned_opt: + { + $$ = BoolVal(false) + } +| UNSIGNED + { + $$ = BoolVal(true) + } + +zero_fill_opt: + { + $$ = BoolVal(false) + } +| ZEROFILL + { + $$ = BoolVal(true) + } + +// Null opt returns false to mean NULL (i.e. the default) and true for NOT NULL +null_opt: + { + $$ = BoolVal(false) + } +| NULL + { + $$ = BoolVal(false) + } +| NOT NULL + { + $$ = BoolVal(true) + } + +column_default_opt: + { + $$ = nil + } +| DEFAULT STRING + { + $$ = NewStrVal($2) + } +| DEFAULT INTEGRAL + { + $$ = NewIntVal($2) + } +| DEFAULT FLOAT + { + $$ = NewFloatVal($2) + } +| DEFAULT NULL + { + $$ = NewValArg($2) + } +| DEFAULT CURRENT_TIMESTAMP + { + $$ = NewValArg($2) + } +| DEFAULT BIT_LITERAL + { + $$ = NewBitVal($2) + } + +on_update_opt: + { + $$ = nil + } +| ON UPDATE CURRENT_TIMESTAMP +{ + $$ = NewValArg($3) +} + +auto_increment_opt: + { + $$ = BoolVal(false) + } +| AUTO_INCREMENT + { + $$ = BoolVal(true) + } + +charset_opt: + { + $$ = "" + } +| CHARACTER SET ID + { + $$ = string($3) + } +| CHARACTER SET BINARY + { + $$ = string($3) + } + +collate_opt: + { + $$ = "" + } +| COLLATE ID + { + $$ = string($2) + } + +column_key_opt: + { + $$ = colKeyNone + } +| PRIMARY KEY + { + $$ = colKeyPrimary + } +| KEY + { + $$ = colKey + } +| UNIQUE KEY + { + $$ = colKeyUniqueKey + } +| UNIQUE + { + $$ = colKeyUnique + } + +column_comment_opt: + { + $$ = nil + } +| COMMENT_KEYWORD STRING + { + $$ = NewStrVal($2) + } + +index_definition: + index_info '(' index_column_list ')' index_option_list + { + $$ = &IndexDefinition{Info: $1, Columns: $3, Options: $5} + } +| index_info '(' index_column_list ')' + { + $$ = &IndexDefinition{Info: $1, Columns: $3} + } + +index_option_list: + index_option + { + $$ = []*IndexOption{$1} + } +| index_option_list index_option + { + $$ = append($$, $2) + } + +index_option: + USING ID + { + $$ = &IndexOption{Name: string($1), Using: string($2)} + } +| KEY_BLOCK_SIZE equal_opt INTEGRAL + { + // should not be string + $$ = &IndexOption{Name: string($1), Value: NewIntVal($3)} + } +| COMMENT_KEYWORD STRING + { + $$ = &IndexOption{Name: string($1), Value: NewStrVal($2)} + } + +equal_opt: + /* empty */ + { + $$ = "" + } +| '=' + { + $$ = string($1) + } + +index_info: + PRIMARY KEY + { + $$ = &IndexInfo{Type: string($1) + " " + string($2), Name: NewColIdent("PRIMARY"), Primary: true, Unique: true} + } +| SPATIAL index_or_key ID + { + $$ = &IndexInfo{Type: string($1) + " " + string($2), Name: NewColIdent(string($3)), Spatial: true, Unique: false} + } +| UNIQUE index_or_key ID + { + $$ = &IndexInfo{Type: string($1) + " " + string($2), Name: NewColIdent(string($3)), Unique: true} + } +| UNIQUE ID + { + $$ = &IndexInfo{Type: string($1), Name: NewColIdent(string($2)), Unique: true} + } +| index_or_key ID + { + $$ = &IndexInfo{Type: string($1), Name: NewColIdent(string($2)), Unique: false} + } + +index_or_key: + INDEX + { + $$ = string($1) + } + | KEY + { + $$ = string($1) + } + +index_column_list: + index_column + { + $$ = []*IndexColumn{$1} + } +| index_column_list ',' index_column + { + $$ = append($$, $3) + } + +index_column: + sql_id length_opt + { + $$ = &IndexColumn{Column: $1, Length: $2} + } + +table_option_list: + { + $$ = "" + } +| table_option + { + $$ = " " + string($1) + } +| table_option_list ',' table_option + { + $$ = string($1) + ", " + string($3) + } + +// rather than explicitly parsing the various keywords for table options, +// just accept any number of keywords, IDs, strings, numbers, and '=' +table_option: + table_opt_value + { + $$ = $1 + } +| table_option table_opt_value + { + $$ = $1 + " " + $2 + } +| table_option '=' table_opt_value + { + $$ = $1 + "=" + $3 + } + +table_opt_value: + reserved_sql_id + { + $$ = $1.String() + } +| STRING + { + $$ = "'" + string($1) + "'" + } +| INTEGRAL + { + $$ = string($1) + } + +alter_statement: + ALTER ignore_opt TABLE table_name non_add_drop_or_rename_operation force_eof + { + $$ = &DDL{Action: AlterStr, Table: $4, NewName: $4} + } +| ALTER ignore_opt TABLE table_name ADD alter_object_type force_eof + { + $$ = &DDL{Action: AlterStr, Table: $4, NewName: $4} + } +| ALTER ignore_opt TABLE table_name DROP alter_object_type force_eof + { + $$ = &DDL{Action: AlterStr, Table: $4, NewName: $4} + } +| ALTER ignore_opt TABLE table_name ADD VINDEX sql_id '(' column_list ')' vindex_type_opt vindex_params_opt + { + $$ = &DDL{ + Action: AddColVindexStr, + Table: $4, + VindexSpec: &VindexSpec{ + Name: $7, + Type: $11, + Params: $12, + }, + VindexCols: $9, + } + } +| ALTER ignore_opt TABLE table_name DROP VINDEX sql_id + { + $$ = &DDL{ + Action: DropColVindexStr, + Table: $4, + VindexSpec: &VindexSpec{ + Name: $7, + }, + } + } +| ALTER ignore_opt TABLE table_name RENAME to_opt table_name + { + // Change this to a rename statement + $$ = &DDL{Action: RenameStr, Table: $4, NewName: $7} + } +| ALTER ignore_opt TABLE table_name RENAME index_opt force_eof + { + // Rename an index can just be an alter + $$ = &DDL{Action: AlterStr, Table: $4, NewName: $4} + } +| ALTER VIEW table_name ddl_force_eof + { + $$ = &DDL{Action: AlterStr, Table: $3.ToViewName(), NewName: $3.ToViewName()} + } +| ALTER ignore_opt TABLE table_name partition_operation + { + $$ = &DDL{Action: AlterStr, Table: $4, PartitionSpec: $5} + } + +alter_object_type: + COLUMN +| CONSTRAINT +| FOREIGN +| FULLTEXT +| ID +| INDEX +| KEY +| PRIMARY +| SPATIAL +| PARTITION +| UNIQUE + +partition_operation: + REORGANIZE PARTITION sql_id INTO openb partition_definitions closeb + { + $$ = &PartitionSpec{Action: ReorganizeStr, Name: $3, Definitions: $6} + } + +partition_definitions: + partition_definition + { + $$ = []*PartitionDefinition{$1} + } +| partition_definitions ',' partition_definition + { + $$ = append($1, $3) + } + +partition_definition: + PARTITION sql_id VALUES LESS THAN openb value_expression closeb + { + $$ = &PartitionDefinition{Name: $2, Limit: $7} + } +| PARTITION sql_id VALUES LESS THAN openb MAXVALUE closeb + { + $$ = &PartitionDefinition{Name: $2, Maxvalue: true} + } + +rename_statement: + RENAME TABLE table_name TO table_name + { + $$ = &DDL{Action: RenameStr, Table: $3, NewName: $5} + } + +drop_statement: + DROP TABLE exists_opt table_name + { + var exists bool + if $3 != 0 { + exists = true + } + $$ = &DDL{Action: DropStr, Table: $4, IfExists: exists} + } +| DROP INDEX ID ON table_name ddl_force_eof + { + // Change this to an alter statement + $$ = &DDL{Action: AlterStr, Table: $5, NewName: $5} + } +| DROP VIEW exists_opt table_name ddl_force_eof + { + var exists bool + if $3 != 0 { + exists = true + } + $$ = &DDL{Action: DropStr, Table: $4.ToViewName(), IfExists: exists} + } +| DROP DATABASE exists_opt ID + { + $$ = &DBDDL{Action: DropStr, DBName: string($4)} + } +| DROP SCHEMA exists_opt ID + { + $$ = &DBDDL{Action: DropStr, DBName: string($4)} + } + +truncate_statement: + TRUNCATE TABLE table_name + { + $$ = &DDL{Action: TruncateStr, Table: $3} + } +| TRUNCATE table_name + { + $$ = &DDL{Action: TruncateStr, Table: $2} + } +analyze_statement: + ANALYZE TABLE table_name + { + $$ = &DDL{Action: AlterStr, Table: $3, NewName: $3} + } + +show_statement: + SHOW BINARY ID ddl_force_eof /* SHOW BINARY LOGS */ + { + $$ = &Show{Type: string($2) + " " + string($3)} + } +| SHOW CHARACTER SET ddl_force_eof + { + $$ = &Show{Type: string($2) + " " + string($3)} + } +| SHOW CREATE DATABASE ddl_force_eof + { + $$ = &Show{Type: string($2) + " " + string($3)} + } +/* Rule to handle SHOW CREATE EVENT, SHOW CREATE FUNCTION, etc. */ +| SHOW CREATE ID ddl_force_eof + { + $$ = &Show{Type: string($2) + " " + string($3)} + } +| SHOW CREATE PROCEDURE ddl_force_eof + { + $$ = &Show{Type: string($2) + " " + string($3)} + } +| SHOW CREATE TABLE ddl_force_eof + { + $$ = &Show{Type: string($2) + " " + string($3)} + } +| SHOW CREATE TRIGGER ddl_force_eof + { + $$ = &Show{Type: string($2) + " " + string($3)} + } +| SHOW CREATE VIEW ddl_force_eof + { + $$ = &Show{Type: string($2) + " " + string($3)} + } +| SHOW DATABASES ddl_force_eof + { + $$ = &Show{Type: string($2)} + } +| SHOW INDEX ddl_force_eof + { + $$ = &Show{Type: string($2)} + } +| SHOW KEYS ddl_force_eof + { + $$ = &Show{Type: string($2)} + } +| SHOW PROCEDURE ddl_force_eof + { + $$ = &Show{Type: string($2)} + } +| SHOW show_session_or_global STATUS ddl_force_eof + { + $$ = &Show{Scope: $2, Type: string($3)} + } +| SHOW TABLE ddl_force_eof + { + $$ = &Show{Type: string($2)} + } +| SHOW extended_opt full_opt tables_or_processlist from_database_opt like_or_where_opt + { + // this is ugly, but I couldn't find a better way for now + if $4 == "processlist" { + $$ = &Show{Type: $4} + } else { + showTablesOpt := &ShowTablesOpt{Extended: $2, Full:$3, DbName:$5, Filter:$6} + $$ = &Show{Type: $4, ShowTablesOpt: showTablesOpt} + } + } +| SHOW show_session_or_global VARIABLES ddl_force_eof + { + $$ = &Show{Scope: $2, Type: string($3)} + } +| SHOW VINDEXES + { + $$ = &Show{Type: string($2)} + } +| SHOW VINDEXES ON table_name + { + $$ = &Show{Type: string($2), OnTable: $4} + } +| SHOW VITESS_KEYSPACES + { + $$ = &Show{Type: string($2)} + } +| SHOW VITESS_SHARDS + { + $$ = &Show{Type: string($2)} + } +| SHOW VITESS_TABLETS + { + $$ = &Show{Type: string($2)} + } +| SHOW VSCHEMA_TABLES + { + $$ = &Show{Type: string($2)} + } +/* + * Catch-all for show statements without vitess keywords: + * + * SHOW BINARY LOGS + * SHOW INVALID + */ +| SHOW ID ddl_force_eof + { + $$ = &Show{Type: string($2)} + } + +tables_or_processlist: + TABLES + { + $$ = string($1) + } +| PROCESSLIST + { + $$ = string($1) + } + +extended_opt: + /* empty */ + { + $$ = "" + } +| EXTENDED + { + $$ = "extended " + } + +full_opt: + /* empty */ + { + $$ = "" + } +| FULL + { + $$ = "full " + } + +from_database_opt: + /* empty */ + { + $$ = "" + } +| FROM table_id + { + $$ = $2.v + } +| IN table_id + { + $$ = $2.v + } + +like_or_where_opt: + /* empty */ + { + $$ = nil + } +| LIKE STRING + { + $$ = &ShowFilter{Like:string($2)} + } +| WHERE expression + { + $$ = &ShowFilter{Filter:$2} + } + +show_session_or_global: + /* empty */ + { + $$ = "" + } +| SESSION + { + $$ = SessionStr + } +| GLOBAL + { + $$ = GlobalStr + } + +use_statement: + USE table_id + { + $$ = &Use{DBName: $2} + } +| USE + { + $$ = &Use{DBName:TableIdent{v:""}} + } + +begin_statement: + BEGIN + { + $$ = &Begin{} + } +| START TRANSACTION + { + $$ = &Begin{} + } + +commit_statement: + COMMIT + { + $$ = &Commit{} + } + +rollback_statement: + ROLLBACK + { + $$ = &Rollback{} + } + +other_statement: + DESC force_eof + { + $$ = &OtherRead{} + } +| DESCRIBE force_eof + { + $$ = &OtherRead{} + } +| EXPLAIN force_eof + { + $$ = &OtherRead{} + } +| REPAIR force_eof + { + $$ = &OtherAdmin{} + } +| OPTIMIZE force_eof + { + $$ = &OtherAdmin{} + } + +comment_opt: + { + setAllowComments(yylex, true) + } + comment_list + { + $$ = $2 + setAllowComments(yylex, false) + } + +comment_list: + { + $$ = nil + } +| comment_list COMMENT + { + $$ = append($1, $2) + } + +union_op: + UNION + { + $$ = UnionStr + } +| UNION ALL + { + $$ = UnionAllStr + } +| UNION DISTINCT + { + $$ = UnionDistinctStr + } + +cache_opt: +{ + $$ = "" +} +| SQL_NO_CACHE +{ + $$ = SQLNoCacheStr +} +| SQL_CACHE +{ + $$ = SQLCacheStr +} + +distinct_opt: + { + $$ = "" + } +| DISTINCT + { + $$ = DistinctStr + } + +straight_join_opt: + { + $$ = "" + } +| STRAIGHT_JOIN + { + $$ = StraightJoinHint + } + +select_expression_list_opt: + { + $$ = nil + } +| select_expression_list + { + $$ = $1 + } + +select_expression_list: + select_expression + { + $$ = SelectExprs{$1} + } +| select_expression_list ',' select_expression + { + $$ = append($$, $3) + } + +select_expression: + '*' + { + $$ = &StarExpr{} + } +| expression as_ci_opt + { + $$ = &AliasedExpr{Expr: $1, As: $2} + } +| table_id '.' '*' + { + $$ = &StarExpr{TableName: TableName{Name: $1}} + } +| table_id '.' reserved_table_id '.' '*' + { + $$ = &StarExpr{TableName: TableName{Qualifier: $1, Name: $3}} + } + +as_ci_opt: + { + $$ = ColIdent{} + } +| col_alias + { + $$ = $1 + } +| AS col_alias + { + $$ = $2 + } + +col_alias: + sql_id +| STRING + { + $$ = NewColIdent(string($1)) + } + +from_opt: + { + $$ = TableExprs{&AliasedTableExpr{Expr:TableName{Name: NewTableIdent("dual")}}} + } +| FROM table_references + { + $$ = $2 + } + +table_references: + table_reference + { + $$ = TableExprs{$1} + } +| table_references ',' table_reference + { + $$ = append($$, $3) + } + +table_reference: + table_factor +| join_table + +table_factor: + aliased_table_name + { + $$ = $1 + } +| subquery as_opt table_id + { + $$ = &AliasedTableExpr{Expr:$1, As: $3} + } +| openb table_references closeb + { + $$ = &ParenTableExpr{Exprs: $2} + } + +aliased_table_name: +table_name as_opt_id index_hint_list + { + $$ = &AliasedTableExpr{Expr:$1, As: $2, Hints: $3} + } +| table_name PARTITION openb partition_list closeb as_opt_id index_hint_list + { + $$ = &AliasedTableExpr{Expr:$1, Partitions: $4, As: $6, Hints: $7} + } + +column_list: + sql_id + { + $$ = Columns{$1} + } +| column_list ',' sql_id + { + $$ = append($$, $3) + } + +partition_list: + sql_id + { + $$ = Partitions{$1} + } +| partition_list ',' sql_id + { + $$ = append($$, $3) + } + +// There is a grammar conflict here: +// 1: INSERT INTO a SELECT * FROM b JOIN c ON b.i = c.i +// 2: INSERT INTO a SELECT * FROM b JOIN c ON DUPLICATE KEY UPDATE a.i = 1 +// When yacc encounters the ON clause, it cannot determine which way to +// resolve. The %prec override below makes the parser choose the +// first construct, which automatically makes the second construct a +// syntax error. This is the same behavior as MySQL. +join_table: + table_reference inner_join table_factor join_condition_opt + { + $$ = &JoinTableExpr{LeftExpr: $1, Join: $2, RightExpr: $3, Condition: $4} + } +| table_reference straight_join table_factor on_expression_opt + { + $$ = &JoinTableExpr{LeftExpr: $1, Join: $2, RightExpr: $3, Condition: $4} + } +| table_reference outer_join table_reference join_condition + { + $$ = &JoinTableExpr{LeftExpr: $1, Join: $2, RightExpr: $3, Condition: $4} + } +| table_reference natural_join table_factor + { + $$ = &JoinTableExpr{LeftExpr: $1, Join: $2, RightExpr: $3} + } + +join_condition: + ON expression + { $$ = JoinCondition{On: $2} } +| USING '(' column_list ')' + { $$ = JoinCondition{Using: $3} } + +join_condition_opt: +%prec JOIN + { $$ = JoinCondition{} } +| join_condition + { $$ = $1 } + +on_expression_opt: +%prec JOIN + { $$ = JoinCondition{} } +| ON expression + { $$ = JoinCondition{On: $2} } + +as_opt: + { $$ = struct{}{} } +| AS + { $$ = struct{}{} } + +as_opt_id: + { + $$ = NewTableIdent("") + } +| table_alias + { + $$ = $1 + } +| AS table_alias + { + $$ = $2 + } + +table_alias: + table_id +| STRING + { + $$ = NewTableIdent(string($1)) + } + +inner_join: + JOIN + { + $$ = JoinStr + } +| INNER JOIN + { + $$ = JoinStr + } +| CROSS JOIN + { + $$ = JoinStr + } + +straight_join: + STRAIGHT_JOIN + { + $$ = StraightJoinStr + } + +outer_join: + LEFT JOIN + { + $$ = LeftJoinStr + } +| LEFT OUTER JOIN + { + $$ = LeftJoinStr + } +| RIGHT JOIN + { + $$ = RightJoinStr + } +| RIGHT OUTER JOIN + { + $$ = RightJoinStr + } + +natural_join: + NATURAL JOIN + { + $$ = NaturalJoinStr + } +| NATURAL outer_join + { + if $2 == LeftJoinStr { + $$ = NaturalLeftJoinStr + } else { + $$ = NaturalRightJoinStr + } + } + +into_table_name: + INTO table_name + { + $$ = $2 + } +| table_name + { + $$ = $1 + } + +table_name: + table_id + { + $$ = TableName{Name: $1} + } +| table_id '.' reserved_table_id + { + $$ = TableName{Qualifier: $1, Name: $3} + } + +index_hint_list: + { + $$ = nil + } +| USE INDEX openb column_list closeb + { + $$ = &IndexHints{Type: UseStr, Indexes: $4} + } +| IGNORE INDEX openb column_list closeb + { + $$ = &IndexHints{Type: IgnoreStr, Indexes: $4} + } +| FORCE INDEX openb column_list closeb + { + $$ = &IndexHints{Type: ForceStr, Indexes: $4} + } + +where_expression_opt: + { + $$ = nil + } +| WHERE expression + { + $$ = $2 + } + +expression: + condition + { + $$ = $1 + } +| expression AND expression + { + $$ = &AndExpr{Left: $1, Right: $3} + } +| expression OR expression + { + $$ = &OrExpr{Left: $1, Right: $3} + } +| NOT expression + { + $$ = &NotExpr{Expr: $2} + } +| expression IS is_suffix + { + $$ = &IsExpr{Operator: $3, Expr: $1} + } +| value_expression + { + $$ = $1 + } +| DEFAULT default_opt + { + $$ = &Default{ColName: $2} + } + +default_opt: + /* empty */ + { + $$ = "" + } +| openb ID closeb + { + $$ = string($2) + } + +boolean_value: + TRUE + { + $$ = BoolVal(true) + } +| FALSE + { + $$ = BoolVal(false) + } + +condition: + value_expression compare value_expression + { + $$ = &ComparisonExpr{Left: $1, Operator: $2, Right: $3} + } +| value_expression IN col_tuple + { + $$ = &ComparisonExpr{Left: $1, Operator: InStr, Right: $3} + } +| value_expression NOT IN col_tuple + { + $$ = &ComparisonExpr{Left: $1, Operator: NotInStr, Right: $4} + } +| value_expression LIKE value_expression like_escape_opt + { + $$ = &ComparisonExpr{Left: $1, Operator: LikeStr, Right: $3, Escape: $4} + } +| value_expression NOT LIKE value_expression like_escape_opt + { + $$ = &ComparisonExpr{Left: $1, Operator: NotLikeStr, Right: $4, Escape: $5} + } +| value_expression REGEXP value_expression + { + $$ = &ComparisonExpr{Left: $1, Operator: RegexpStr, Right: $3} + } +| value_expression NOT REGEXP value_expression + { + $$ = &ComparisonExpr{Left: $1, Operator: NotRegexpStr, Right: $4} + } +| value_expression BETWEEN value_expression AND value_expression + { + $$ = &RangeCond{Left: $1, Operator: BetweenStr, From: $3, To: $5} + } +| value_expression NOT BETWEEN value_expression AND value_expression + { + $$ = &RangeCond{Left: $1, Operator: NotBetweenStr, From: $4, To: $6} + } +| EXISTS subquery + { + $$ = &ExistsExpr{Subquery: $2} + } + +is_suffix: + NULL + { + $$ = IsNullStr + } +| NOT NULL + { + $$ = IsNotNullStr + } +| TRUE + { + $$ = IsTrueStr + } +| NOT TRUE + { + $$ = IsNotTrueStr + } +| FALSE + { + $$ = IsFalseStr + } +| NOT FALSE + { + $$ = IsNotFalseStr + } + +compare: + '=' + { + $$ = EqualStr + } +| '<' + { + $$ = LessThanStr + } +| '>' + { + $$ = GreaterThanStr + } +| LE + { + $$ = LessEqualStr + } +| GE + { + $$ = GreaterEqualStr + } +| NE + { + $$ = NotEqualStr + } +| NULL_SAFE_EQUAL + { + $$ = NullSafeEqualStr + } + +like_escape_opt: + { + $$ = nil + } +| ESCAPE value_expression + { + $$ = $2 + } + +col_tuple: + row_tuple + { + $$ = $1 + } +| subquery + { + $$ = $1 + } +| LIST_ARG + { + $$ = ListArg($1) + } + +subquery: + openb select_statement closeb + { + $$ = &Subquery{$2} + } + +expression_list: + expression + { + $$ = Exprs{$1} + } +| expression_list ',' expression + { + $$ = append($1, $3) + } + +value_expression: + value + { + $$ = $1 + } +| boolean_value + { + $$ = $1 + } +| column_name + { + $$ = $1 + } +| tuple_expression + { + $$ = $1 + } +| subquery + { + $$ = $1 + } +| value_expression '&' value_expression + { + $$ = &BinaryExpr{Left: $1, Operator: BitAndStr, Right: $3} + } +| value_expression '|' value_expression + { + $$ = &BinaryExpr{Left: $1, Operator: BitOrStr, Right: $3} + } +| value_expression '^' value_expression + { + $$ = &BinaryExpr{Left: $1, Operator: BitXorStr, Right: $3} + } +| value_expression '+' value_expression + { + $$ = &BinaryExpr{Left: $1, Operator: PlusStr, Right: $3} + } +| value_expression '-' value_expression + { + $$ = &BinaryExpr{Left: $1, Operator: MinusStr, Right: $3} + } +| value_expression '*' value_expression + { + $$ = &BinaryExpr{Left: $1, Operator: MultStr, Right: $3} + } +| value_expression '/' value_expression + { + $$ = &BinaryExpr{Left: $1, Operator: DivStr, Right: $3} + } +| value_expression DIV value_expression + { + $$ = &BinaryExpr{Left: $1, Operator: IntDivStr, Right: $3} + } +| value_expression '%' value_expression + { + $$ = &BinaryExpr{Left: $1, Operator: ModStr, Right: $3} + } +| value_expression MOD value_expression + { + $$ = &BinaryExpr{Left: $1, Operator: ModStr, Right: $3} + } +| value_expression SHIFT_LEFT value_expression + { + $$ = &BinaryExpr{Left: $1, Operator: ShiftLeftStr, Right: $3} + } +| value_expression SHIFT_RIGHT value_expression + { + $$ = &BinaryExpr{Left: $1, Operator: ShiftRightStr, Right: $3} + } +| column_name JSON_EXTRACT_OP value + { + $$ = &BinaryExpr{Left: $1, Operator: JSONExtractOp, Right: $3} + } +| column_name JSON_UNQUOTE_EXTRACT_OP value + { + $$ = &BinaryExpr{Left: $1, Operator: JSONUnquoteExtractOp, Right: $3} + } +| value_expression COLLATE charset + { + $$ = &CollateExpr{Expr: $1, Charset: $3} + } +| BINARY value_expression %prec UNARY + { + $$ = &UnaryExpr{Operator: BinaryStr, Expr: $2} + } +| UNDERSCORE_BINARY value_expression %prec UNARY + { + $$ = &UnaryExpr{Operator: UBinaryStr, Expr: $2} + } +| '+' value_expression %prec UNARY + { + if num, ok := $2.(*SQLVal); ok && num.Type == IntVal { + $$ = num + } else { + $$ = &UnaryExpr{Operator: UPlusStr, Expr: $2} + } + } +| '-' value_expression %prec UNARY + { + if num, ok := $2.(*SQLVal); ok && num.Type == IntVal { + // Handle double negative + if num.Val[0] == '-' { + num.Val = num.Val[1:] + $$ = num + } else { + $$ = NewIntVal(append([]byte("-"), num.Val...)) + } + } else { + $$ = &UnaryExpr{Operator: UMinusStr, Expr: $2} + } + } +| '~' value_expression + { + $$ = &UnaryExpr{Operator: TildaStr, Expr: $2} + } +| '!' value_expression %prec UNARY + { + $$ = &UnaryExpr{Operator: BangStr, Expr: $2} + } +| INTERVAL value_expression sql_id + { + // This rule prevents the usage of INTERVAL + // as a function. If support is needed for that, + // we'll need to revisit this. The solution + // will be non-trivial because of grammar conflicts. + $$ = &IntervalExpr{Expr: $2, Unit: $3.String()} + } +| function_call_generic +| function_call_keyword +| function_call_nonkeyword +| function_call_conflict + +/* + Regular function calls without special token or syntax, guaranteed to not + introduce side effects due to being a simple identifier +*/ +function_call_generic: + sql_id openb select_expression_list_opt closeb + { + $$ = &FuncExpr{Name: $1, Exprs: $3} + } +| sql_id openb DISTINCT select_expression_list closeb + { + $$ = &FuncExpr{Name: $1, Distinct: true, Exprs: $4} + } +| table_id '.' reserved_sql_id openb select_expression_list_opt closeb + { + $$ = &FuncExpr{Qualifier: $1, Name: $3, Exprs: $5} + } + +/* + Function calls using reserved keywords, with dedicated grammar rules + as a result +*/ +function_call_keyword: + LEFT openb select_expression_list closeb + { + $$ = &FuncExpr{Name: NewColIdent("left"), Exprs: $3} + } +| RIGHT openb select_expression_list closeb + { + $$ = &FuncExpr{Name: NewColIdent("right"), Exprs: $3} + } +| CONVERT openb expression ',' convert_type closeb + { + $$ = &ConvertExpr{Expr: $3, Type: $5} + } +| CAST openb expression AS convert_type closeb + { + $$ = &ConvertExpr{Expr: $3, Type: $5} + } +| CONVERT openb expression USING charset closeb + { + $$ = &ConvertUsingExpr{Expr: $3, Type: $5} + } +| SUBSTR openb column_name ',' value_expression closeb + { + $$ = &SubstrExpr{Name: $3, From: $5, To: nil} + } +| SUBSTR openb column_name ',' value_expression ',' value_expression closeb + { + $$ = &SubstrExpr{Name: $3, From: $5, To: $7} + } +| SUBSTR openb column_name FROM value_expression FOR value_expression closeb + { + $$ = &SubstrExpr{Name: $3, From: $5, To: $7} + } +| SUBSTRING openb column_name ',' value_expression closeb + { + $$ = &SubstrExpr{Name: $3, From: $5, To: nil} + } +| SUBSTRING openb column_name ',' value_expression ',' value_expression closeb + { + $$ = &SubstrExpr{Name: $3, From: $5, To: $7} + } +| SUBSTRING openb column_name FROM value_expression FOR value_expression closeb + { + $$ = &SubstrExpr{Name: $3, From: $5, To: $7} + } +| MATCH openb select_expression_list closeb AGAINST openb value_expression match_option closeb + { + $$ = &MatchExpr{Columns: $3, Expr: $7, Option: $8} + } +| GROUP_CONCAT openb distinct_opt select_expression_list order_by_opt separator_opt closeb + { + $$ = &GroupConcatExpr{Distinct: $3, Exprs: $4, OrderBy: $5, Separator: $6} + } +| CASE expression_opt when_expression_list else_expression_opt END + { + $$ = &CaseExpr{Expr: $2, Whens: $3, Else: $4} + } +| VALUES openb column_name closeb + { + $$ = &ValuesFuncExpr{Name: $3} + } + +/* + Function calls using non reserved keywords but with special syntax forms. + Dedicated grammar rules are needed because of the special syntax +*/ +function_call_nonkeyword: + CURRENT_TIMESTAMP func_datetime_precision_opt + { + $$ = &FuncExpr{Name:NewColIdent("current_timestamp")} + } +| UTC_TIMESTAMP func_datetime_precision_opt + { + $$ = &FuncExpr{Name:NewColIdent("utc_timestamp")} + } +| UTC_TIME func_datetime_precision_opt + { + $$ = &FuncExpr{Name:NewColIdent("utc_time")} + } +| UTC_DATE func_datetime_precision_opt + { + $$ = &FuncExpr{Name:NewColIdent("utc_date")} + } + // now +| LOCALTIME func_datetime_precision_opt + { + $$ = &FuncExpr{Name:NewColIdent("localtime")} + } + // now +| LOCALTIMESTAMP func_datetime_precision_opt + { + $$ = &FuncExpr{Name:NewColIdent("localtimestamp")} + } + // curdate +| CURRENT_DATE func_datetime_precision_opt + { + $$ = &FuncExpr{Name:NewColIdent("current_date")} + } + // curtime +| CURRENT_TIME func_datetime_precision_opt + { + $$ = &FuncExpr{Name:NewColIdent("current_time")} + } + +func_datetime_precision_opt: + /* empty */ +| openb closeb + +/* + Function calls using non reserved keywords with *normal* syntax forms. Because + the names are non-reserved, they need a dedicated rule so as not to conflict +*/ +function_call_conflict: + IF openb select_expression_list closeb + { + $$ = &FuncExpr{Name: NewColIdent("if"), Exprs: $3} + } +| DATABASE openb select_expression_list_opt closeb + { + $$ = &FuncExpr{Name: NewColIdent("database"), Exprs: $3} + } +| MOD openb select_expression_list closeb + { + $$ = &FuncExpr{Name: NewColIdent("mod"), Exprs: $3} + } +| REPLACE openb select_expression_list closeb + { + $$ = &FuncExpr{Name: NewColIdent("replace"), Exprs: $3} + } + +match_option: +/*empty*/ + { + $$ = "" + } +| IN BOOLEAN MODE + { + $$ = BooleanModeStr + } +| IN NATURAL LANGUAGE MODE + { + $$ = NaturalLanguageModeStr + } +| IN NATURAL LANGUAGE MODE WITH QUERY EXPANSION + { + $$ = NaturalLanguageModeWithQueryExpansionStr + } +| WITH QUERY EXPANSION + { + $$ = QueryExpansionStr + } + +charset: + ID +{ + $$ = string($1) +} +| STRING +{ + $$ = string($1) +} + +convert_type: + BINARY length_opt + { + $$ = &ConvertType{Type: string($1), Length: $2} + } +| CHAR length_opt charset_opt + { + $$ = &ConvertType{Type: string($1), Length: $2, Charset: $3, Operator: CharacterSetStr} + } +| CHAR length_opt ID + { + $$ = &ConvertType{Type: string($1), Length: $2, Charset: string($3)} + } +| DATE + { + $$ = &ConvertType{Type: string($1)} + } +| DATETIME length_opt + { + $$ = &ConvertType{Type: string($1), Length: $2} + } +| DECIMAL decimal_length_opt + { + $$ = &ConvertType{Type: string($1)} + $$.Length = $2.Length + $$.Scale = $2.Scale + } +| JSON + { + $$ = &ConvertType{Type: string($1)} + } +| NCHAR length_opt + { + $$ = &ConvertType{Type: string($1), Length: $2} + } +| SIGNED + { + $$ = &ConvertType{Type: string($1)} + } +| SIGNED INTEGER + { + $$ = &ConvertType{Type: string($1)} + } +| TIME length_opt + { + $$ = &ConvertType{Type: string($1), Length: $2} + } +| UNSIGNED + { + $$ = &ConvertType{Type: string($1)} + } +| UNSIGNED INTEGER + { + $$ = &ConvertType{Type: string($1)} + } + +expression_opt: + { + $$ = nil + } +| expression + { + $$ = $1 + } + +separator_opt: + { + $$ = string("") + } +| SEPARATOR STRING + { + $$ = " separator '"+string($2)+"'" + } + +when_expression_list: + when_expression + { + $$ = []*When{$1} + } +| when_expression_list when_expression + { + $$ = append($1, $2) + } + +when_expression: + WHEN expression THEN expression + { + $$ = &When{Cond: $2, Val: $4} + } + +else_expression_opt: + { + $$ = nil + } +| ELSE expression + { + $$ = $2 + } + +column_name: + sql_id + { + $$ = &ColName{Name: $1} + } +| table_id '.' reserved_sql_id + { + $$ = &ColName{Qualifier: TableName{Name: $1}, Name: $3} + } +| table_id '.' reserved_table_id '.' reserved_sql_id + { + $$ = &ColName{Qualifier: TableName{Qualifier: $1, Name: $3}, Name: $5} + } + +value: + STRING + { + $$ = NewStrVal($1) + } +| HEX + { + $$ = NewHexVal($1) + } +| BIT_LITERAL + { + $$ = NewBitVal($1) + } +| INTEGRAL + { + $$ = NewIntVal($1) + } +| FLOAT + { + $$ = NewFloatVal($1) + } +| HEXNUM + { + $$ = NewHexNum($1) + } +| VALUE_ARG + { + $$ = NewValArg($1) + } +| NULL + { + $$ = &NullVal{} + } + +num_val: + sql_id + { + // TODO(sougou): Deprecate this construct. + if $1.Lowered() != "value" { + yylex.Error("expecting value after next") + return 1 + } + $$ = NewIntVal([]byte("1")) + } +| INTEGRAL VALUES + { + $$ = NewIntVal($1) + } +| VALUE_ARG VALUES + { + $$ = NewValArg($1) + } + +group_by_opt: + { + $$ = nil + } +| GROUP BY expression_list + { + $$ = $3 + } + +having_opt: + { + $$ = nil + } +| HAVING expression + { + $$ = $2 + } + +order_by_opt: + { + $$ = nil + } +| ORDER BY order_list + { + $$ = $3 + } + +order_list: + order + { + $$ = OrderBy{$1} + } +| order_list ',' order + { + $$ = append($1, $3) + } + +order: + expression asc_desc_opt + { + $$ = &Order{Expr: $1, Direction: $2} + } + +asc_desc_opt: + { + $$ = AscScr + } +| ASC + { + $$ = AscScr + } +| DESC + { + $$ = DescScr + } + +limit_opt: + { + $$ = nil + } +| LIMIT expression + { + $$ = &Limit{Rowcount: $2} + } +| LIMIT expression ',' expression + { + $$ = &Limit{Offset: $2, Rowcount: $4} + } +| LIMIT expression OFFSET expression + { + $$ = &Limit{Offset: $4, Rowcount: $2} + } + +lock_opt: + { + $$ = "" + } +| FOR UPDATE + { + $$ = ForUpdateStr + } +| LOCK IN SHARE MODE + { + $$ = ShareModeStr + } + +// insert_data expands all combinations into a single rule. +// This avoids a shift/reduce conflict while encountering the +// following two possible constructs: +// insert into t1(a, b) (select * from t2) +// insert into t1(select * from t2) +// Because the rules are together, the parser can keep shifting +// the tokens until it disambiguates a as sql_id and select as keyword. +insert_data: + VALUES tuple_list + { + $$ = &Insert{Rows: $2} + } +| select_statement + { + $$ = &Insert{Rows: $1} + } +| openb select_statement closeb + { + // Drop the redundant parenthesis. + $$ = &Insert{Rows: $2} + } +| openb ins_column_list closeb VALUES tuple_list + { + $$ = &Insert{Columns: $2, Rows: $5} + } +| openb ins_column_list closeb select_statement + { + $$ = &Insert{Columns: $2, Rows: $4} + } +| openb ins_column_list closeb openb select_statement closeb + { + // Drop the redundant parenthesis. + $$ = &Insert{Columns: $2, Rows: $5} + } + +ins_column_list: + sql_id + { + $$ = Columns{$1} + } +| sql_id '.' sql_id + { + $$ = Columns{$3} + } +| ins_column_list ',' sql_id + { + $$ = append($$, $3) + } +| ins_column_list ',' sql_id '.' sql_id + { + $$ = append($$, $5) + } + +on_dup_opt: + { + $$ = nil + } +| ON DUPLICATE KEY UPDATE update_list + { + $$ = $5 + } + +tuple_list: + tuple_or_empty + { + $$ = Values{$1} + } +| tuple_list ',' tuple_or_empty + { + $$ = append($1, $3) + } + +tuple_or_empty: + row_tuple + { + $$ = $1 + } +| openb closeb + { + $$ = ValTuple{} + } + +row_tuple: + openb expression_list closeb + { + $$ = ValTuple($2) + } + +tuple_expression: + row_tuple + { + if len($1) == 1 { + $$ = &ParenExpr{$1[0]} + } else { + $$ = $1 + } + } + +update_list: + update_expression + { + $$ = UpdateExprs{$1} + } +| update_list ',' update_expression + { + $$ = append($1, $3) + } + +update_expression: + column_name '=' expression + { + $$ = &UpdateExpr{Name: $1, Expr: $3} + } + +set_list: + set_expression + { + $$ = SetExprs{$1} + } +| set_list ',' set_expression + { + $$ = append($1, $3) + } + +set_expression: + reserved_sql_id '=' ON + { + $$ = &SetExpr{Name: $1, Expr: NewStrVal([]byte("on"))} + } +| reserved_sql_id '=' expression + { + $$ = &SetExpr{Name: $1, Expr: $3} + } +| charset_or_character_set charset_value collate_opt + { + $$ = &SetExpr{Name: NewColIdent(string($1)), Expr: $2} + } + +charset_or_character_set: + CHARSET +| CHARACTER SET + { + $$ = []byte("charset") + } +| NAMES + +charset_value: + sql_id + { + $$ = NewStrVal([]byte($1.String())) + } +| STRING + { + $$ = NewStrVal($1) + } +| DEFAULT + { + $$ = &Default{} + } + +for_from: + FOR +| FROM + +exists_opt: + { $$ = 0 } +| IF EXISTS + { $$ = 1 } + +not_exists_opt: + { $$ = struct{}{} } +| IF NOT EXISTS + { $$ = struct{}{} } + +ignore_opt: + { $$ = "" } +| IGNORE + { $$ = IgnoreStr } + +non_add_drop_or_rename_operation: + ALTER + { $$ = struct{}{} } +| AUTO_INCREMENT + { $$ = struct{}{} } +| CHARACTER + { $$ = struct{}{} } +| COMMENT_KEYWORD + { $$ = struct{}{} } +| DEFAULT + { $$ = struct{}{} } +| ORDER + { $$ = struct{}{} } +| CONVERT + { $$ = struct{}{} } +| PARTITION + { $$ = struct{}{} } +| UNUSED + { $$ = struct{}{} } +| ID + { $$ = struct{}{} } + +to_opt: + { $$ = struct{}{} } +| TO + { $$ = struct{}{} } +| AS + { $$ = struct{}{} } + +index_opt: + INDEX + { $$ = struct{}{} } +| KEY + { $$ = struct{}{} } + +constraint_opt: + { $$ = struct{}{} } +| UNIQUE + { $$ = struct{}{} } +| sql_id + { $$ = struct{}{} } + +using_opt: + { $$ = ColIdent{} } +| USING sql_id + { $$ = $2 } + +sql_id: + ID + { + $$ = NewColIdent(string($1)) + } +| non_reserved_keyword + { + $$ = NewColIdent(string($1)) + } + +reserved_sql_id: + sql_id +| reserved_keyword + { + $$ = NewColIdent(string($1)) + } + +table_id: + ID + { + $$ = NewTableIdent(string($1)) + } +| non_reserved_keyword + { + $$ = NewTableIdent(string($1)) + } + +reserved_table_id: + table_id +| reserved_keyword + { + $$ = NewTableIdent(string($1)) + } + +/* + These are not all necessarily reserved in MySQL, but some are. + + These are more importantly reserved because they may conflict with our grammar. + If you want to move one that is not reserved in MySQL (i.e. ESCAPE) to the + non_reserved_keywords, you'll need to deal with any conflicts. + + Sorted alphabetically +*/ +reserved_keyword: + ADD +| AND +| AS +| ASC +| AUTO_INCREMENT +| BETWEEN +| BINARY +| BY +| CASE +| COLLATE +| CONVERT +| CREATE +| CROSS +| CURRENT_DATE +| CURRENT_TIME +| CURRENT_TIMESTAMP +| SUBSTR +| SUBSTRING +| DATABASE +| DATABASES +| DEFAULT +| DELETE +| DESC +| DESCRIBE +| DISTINCT +| DIV +| DROP +| ELSE +| END +| ESCAPE +| EXISTS +| EXPLAIN +| FALSE +| FOR +| FORCE +| FROM +| GROUP +| HAVING +| IF +| IGNORE +| IN +| INDEX +| INNER +| INSERT +| INTERVAL +| INTO +| IS +| JOIN +| KEY +| LEFT +| LIKE +| LIMIT +| LOCALTIME +| LOCALTIMESTAMP +| LOCK +| MATCH +| MAXVALUE +| MOD +| NATURAL +| NEXT // next should be doable as non-reserved, but is not due to the special `select next num_val` query that vitess supports +| NOT +| NULL +| ON +| OR +| ORDER +| OUTER +| REGEXP +| RENAME +| REPLACE +| RIGHT +| SCHEMA +| SELECT +| SEPARATOR +| SET +| SHOW +| STRAIGHT_JOIN +| TABLE +| TABLES +| THEN +| TO +| TRUE +| UNION +| UNIQUE +| UPDATE +| USE +| USING +| UTC_DATE +| UTC_TIME +| UTC_TIMESTAMP +| VALUES +| WHEN +| WHERE + +/* + These are non-reserved Vitess, because they don't cause conflicts in the grammar. + Some of them may be reserved in MySQL. The good news is we backtick quote them + when we rewrite the query, so no issue should arise. + + Sorted alphabetically +*/ +non_reserved_keyword: + AGAINST +| BEGIN +| BIGINT +| BIT +| BLOB +| BOOL +| CHAR +| CHARACTER +| CHARSET +| COMMENT_KEYWORD +| COMMIT +| COMMITTED +| DATE +| DATETIME +| DECIMAL +| DOUBLE +| DUPLICATE +| ENUM +| EXPANSION +| FLOAT_TYPE +| FOREIGN +| FULLTEXT +| GEOMETRY +| GEOMETRYCOLLECTION +| GLOBAL +| INT +| INTEGER +| ISOLATION +| JSON +| KEY_BLOCK_SIZE +| KEYS +| LANGUAGE +| LAST_INSERT_ID +| LESS +| LEVEL +| LINESTRING +| LONGBLOB +| LONGTEXT +| MEDIUMBLOB +| MEDIUMINT +| MEDIUMTEXT +| MODE +| MULTILINESTRING +| MULTIPOINT +| MULTIPOLYGON +| NAMES +| NCHAR +| NUMERIC +| OFFSET +| ONLY +| OPTIMIZE +| PARTITION +| POINT +| POLYGON +| PRIMARY +| PROCEDURE +| QUERY +| READ +| REAL +| REORGANIZE +| REPAIR +| REPEATABLE +| ROLLBACK +| SESSION +| SERIALIZABLE +| SHARE +| SIGNED +| SMALLINT +| SPATIAL +| START +| STATUS +| TEXT +| THAN +| TIME +| TIMESTAMP +| TINYBLOB +| TINYINT +| TINYTEXT +| TRANSACTION +| TRIGGER +| TRUNCATE +| UNCOMMITTED +| UNSIGNED +| UNUSED +| VARBINARY +| VARCHAR +| VARIABLES +| VIEW +| VINDEX +| VINDEXES +| VITESS_KEYSPACES +| VITESS_SHARDS +| VITESS_TABLETS +| VSCHEMA_TABLES +| WITH +| WRITE +| YEAR +| ZEROFILL + +openb: + '(' + { + if incNesting(yylex) { + yylex.Error("max nesting level reached") + return 1 + } + } + +closeb: + ')' + { + decNesting(yylex) + } + +force_eof: +{ + forceEOF(yylex) +} + +ddl_force_eof: + { + forceEOF(yylex) + } +| openb + { + forceEOF(yylex) + } +| reserved_sql_id + { + forceEOF(yylex) + } diff --git a/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/token.go b/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/token.go new file mode 100644 index 00000000..23efa77c --- /dev/null +++ b/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/token.go @@ -0,0 +1,950 @@ +/* +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 sqlparser + +import ( + "bytes" + "errors" + "fmt" + "io" + + "github.com/xwb1989/sqlparser/dependency/bytes2" + "github.com/xwb1989/sqlparser/dependency/sqltypes" +) + +const ( + defaultBufSize = 4096 + eofChar = 0x100 +) + +// Tokenizer is the struct used to generate SQL +// tokens for the parser. +type Tokenizer struct { + InStream io.Reader + AllowComments bool + ForceEOF bool + lastChar uint16 + Position int + lastToken []byte + LastError error + posVarIndex int + ParseTree Statement + partialDDL *DDL + nesting int + multi bool + specialComment *Tokenizer + + buf []byte + bufPos int + bufSize int +} + +// NewStringTokenizer creates a new Tokenizer for the +// sql string. +func NewStringTokenizer(sql string) *Tokenizer { + buf := []byte(sql) + return &Tokenizer{ + buf: buf, + bufSize: len(buf), + } +} + +// NewTokenizer creates a new Tokenizer reading a sql +// string from the io.Reader. +func NewTokenizer(r io.Reader) *Tokenizer { + return &Tokenizer{ + InStream: r, + buf: make([]byte, defaultBufSize), + } +} + +// keywords is a map of mysql keywords that fall into two categories: +// 1) keywords considered reserved by MySQL +// 2) keywords for us to handle specially in sql.y +// +// Those marked as UNUSED are likely reserved keywords. We add them here so that +// when rewriting queries we can properly backtick quote them so they don't cause issues +// +// NOTE: If you add new keywords, add them also to the reserved_keywords or +// non_reserved_keywords grammar in sql.y -- this will allow the keyword to be used +// in identifiers. See the docs for each grammar to determine which one to put it into. +var keywords = map[string]int{ + "accessible": UNUSED, + "add": ADD, + "against": AGAINST, + "all": ALL, + "alter": ALTER, + "analyze": ANALYZE, + "and": AND, + "as": AS, + "asc": ASC, + "asensitive": UNUSED, + "auto_increment": AUTO_INCREMENT, + "before": UNUSED, + "begin": BEGIN, + "between": BETWEEN, + "bigint": BIGINT, + "binary": BINARY, + "_binary": UNDERSCORE_BINARY, + "bit": BIT, + "blob": BLOB, + "bool": BOOL, + "boolean": BOOLEAN, + "both": UNUSED, + "by": BY, + "call": UNUSED, + "cascade": UNUSED, + "case": CASE, + "cast": CAST, + "change": UNUSED, + "char": CHAR, + "character": CHARACTER, + "charset": CHARSET, + "check": UNUSED, + "collate": COLLATE, + "column": COLUMN, + "comment": COMMENT_KEYWORD, + "committed": COMMITTED, + "commit": COMMIT, + "condition": UNUSED, + "constraint": CONSTRAINT, + "continue": UNUSED, + "convert": CONVERT, + "substr": SUBSTR, + "substring": SUBSTRING, + "create": CREATE, + "cross": CROSS, + "current_date": CURRENT_DATE, + "current_time": CURRENT_TIME, + "current_timestamp": CURRENT_TIMESTAMP, + "current_user": UNUSED, + "cursor": UNUSED, + "database": DATABASE, + "databases": DATABASES, + "day_hour": UNUSED, + "day_microsecond": UNUSED, + "day_minute": UNUSED, + "day_second": UNUSED, + "date": DATE, + "datetime": DATETIME, + "dec": UNUSED, + "decimal": DECIMAL, + "declare": UNUSED, + "default": DEFAULT, + "delayed": UNUSED, + "delete": DELETE, + "desc": DESC, + "describe": DESCRIBE, + "deterministic": UNUSED, + "distinct": DISTINCT, + "distinctrow": UNUSED, + "div": DIV, + "double": DOUBLE, + "drop": DROP, + "duplicate": DUPLICATE, + "each": UNUSED, + "else": ELSE, + "elseif": UNUSED, + "enclosed": UNUSED, + "end": END, + "enum": ENUM, + "escape": ESCAPE, + "escaped": UNUSED, + "exists": EXISTS, + "exit": UNUSED, + "explain": EXPLAIN, + "expansion": EXPANSION, + "extended": EXTENDED, + "false": FALSE, + "fetch": UNUSED, + "float": FLOAT_TYPE, + "float4": UNUSED, + "float8": UNUSED, + "for": FOR, + "force": FORCE, + "foreign": FOREIGN, + "from": FROM, + "full": FULL, + "fulltext": FULLTEXT, + "generated": UNUSED, + "geometry": GEOMETRY, + "geometrycollection": GEOMETRYCOLLECTION, + "get": UNUSED, + "global": GLOBAL, + "grant": UNUSED, + "group": GROUP, + "group_concat": GROUP_CONCAT, + "having": HAVING, + "high_priority": UNUSED, + "hour_microsecond": UNUSED, + "hour_minute": UNUSED, + "hour_second": UNUSED, + "if": IF, + "ignore": IGNORE, + "in": IN, + "index": INDEX, + "infile": UNUSED, + "inout": UNUSED, + "inner": INNER, + "insensitive": UNUSED, + "insert": INSERT, + "int": INT, + "int1": UNUSED, + "int2": UNUSED, + "int3": UNUSED, + "int4": UNUSED, + "int8": UNUSED, + "integer": INTEGER, + "interval": INTERVAL, + "into": INTO, + "io_after_gtids": UNUSED, + "is": IS, + "isolation": ISOLATION, + "iterate": UNUSED, + "join": JOIN, + "json": JSON, + "key": KEY, + "keys": KEYS, + "key_block_size": KEY_BLOCK_SIZE, + "kill": UNUSED, + "language": LANGUAGE, + "last_insert_id": LAST_INSERT_ID, + "leading": UNUSED, + "leave": UNUSED, + "left": LEFT, + "less": LESS, + "level": LEVEL, + "like": LIKE, + "limit": LIMIT, + "linear": UNUSED, + "lines": UNUSED, + "linestring": LINESTRING, + "load": UNUSED, + "localtime": LOCALTIME, + "localtimestamp": LOCALTIMESTAMP, + "lock": LOCK, + "long": UNUSED, + "longblob": LONGBLOB, + "longtext": LONGTEXT, + "loop": UNUSED, + "low_priority": UNUSED, + "master_bind": UNUSED, + "match": MATCH, + "maxvalue": MAXVALUE, + "mediumblob": MEDIUMBLOB, + "mediumint": MEDIUMINT, + "mediumtext": MEDIUMTEXT, + "middleint": UNUSED, + "minute_microsecond": UNUSED, + "minute_second": UNUSED, + "mod": MOD, + "mode": MODE, + "modifies": UNUSED, + "multilinestring": MULTILINESTRING, + "multipoint": MULTIPOINT, + "multipolygon": MULTIPOLYGON, + "names": NAMES, + "natural": NATURAL, + "nchar": NCHAR, + "next": NEXT, + "not": NOT, + "no_write_to_binlog": UNUSED, + "null": NULL, + "numeric": NUMERIC, + "offset": OFFSET, + "on": ON, + "only": ONLY, + "optimize": OPTIMIZE, + "optimizer_costs": UNUSED, + "option": UNUSED, + "optionally": UNUSED, + "or": OR, + "order": ORDER, + "out": UNUSED, + "outer": OUTER, + "outfile": UNUSED, + "partition": PARTITION, + "point": POINT, + "polygon": POLYGON, + "precision": UNUSED, + "primary": PRIMARY, + "processlist": PROCESSLIST, + "procedure": PROCEDURE, + "query": QUERY, + "range": UNUSED, + "read": READ, + "reads": UNUSED, + "read_write": UNUSED, + "real": REAL, + "references": UNUSED, + "regexp": REGEXP, + "release": UNUSED, + "rename": RENAME, + "reorganize": REORGANIZE, + "repair": REPAIR, + "repeat": UNUSED, + "repeatable": REPEATABLE, + "replace": REPLACE, + "require": UNUSED, + "resignal": UNUSED, + "restrict": UNUSED, + "return": UNUSED, + "revoke": UNUSED, + "right": RIGHT, + "rlike": REGEXP, + "rollback": ROLLBACK, + "schema": SCHEMA, + "schemas": UNUSED, + "second_microsecond": UNUSED, + "select": SELECT, + "sensitive": UNUSED, + "separator": SEPARATOR, + "serializable": SERIALIZABLE, + "session": SESSION, + "set": SET, + "share": SHARE, + "show": SHOW, + "signal": UNUSED, + "signed": SIGNED, + "smallint": SMALLINT, + "spatial": SPATIAL, + "specific": UNUSED, + "sql": UNUSED, + "sqlexception": UNUSED, + "sqlstate": UNUSED, + "sqlwarning": UNUSED, + "sql_big_result": UNUSED, + "sql_cache": SQL_CACHE, + "sql_calc_found_rows": UNUSED, + "sql_no_cache": SQL_NO_CACHE, + "sql_small_result": UNUSED, + "ssl": UNUSED, + "start": START, + "starting": UNUSED, + "status": STATUS, + "stored": UNUSED, + "straight_join": STRAIGHT_JOIN, + "stream": STREAM, + "table": TABLE, + "tables": TABLES, + "terminated": UNUSED, + "text": TEXT, + "than": THAN, + "then": THEN, + "time": TIME, + "timestamp": TIMESTAMP, + "tinyblob": TINYBLOB, + "tinyint": TINYINT, + "tinytext": TINYTEXT, + "to": TO, + "trailing": UNUSED, + "transaction": TRANSACTION, + "trigger": TRIGGER, + "true": TRUE, + "truncate": TRUNCATE, + "uncommitted": UNCOMMITTED, + "undo": UNUSED, + "union": UNION, + "unique": UNIQUE, + "unlock": UNUSED, + "unsigned": UNSIGNED, + "update": UPDATE, + "usage": UNUSED, + "use": USE, + "using": USING, + "utc_date": UTC_DATE, + "utc_time": UTC_TIME, + "utc_timestamp": UTC_TIMESTAMP, + "values": VALUES, + "variables": VARIABLES, + "varbinary": VARBINARY, + "varchar": VARCHAR, + "varcharacter": UNUSED, + "varying": UNUSED, + "virtual": UNUSED, + "vindex": VINDEX, + "vindexes": VINDEXES, + "view": VIEW, + "vitess_keyspaces": VITESS_KEYSPACES, + "vitess_shards": VITESS_SHARDS, + "vitess_tablets": VITESS_TABLETS, + "vschema_tables": VSCHEMA_TABLES, + "when": WHEN, + "where": WHERE, + "while": UNUSED, + "with": WITH, + "write": WRITE, + "xor": UNUSED, + "year": YEAR, + "year_month": UNUSED, + "zerofill": ZEROFILL, +} + +// keywordStrings contains the reverse mapping of token to keyword strings +var keywordStrings = map[int]string{} + +func init() { + for str, id := range keywords { + if id == UNUSED { + continue + } + keywordStrings[id] = str + } +} + +// KeywordString returns the string corresponding to the given keyword +func KeywordString(id int) string { + str, ok := keywordStrings[id] + if !ok { + return "" + } + return str +} + +// Lex returns the next token form the Tokenizer. +// This function is used by go yacc. +func (tkn *Tokenizer) Lex(lval *yySymType) int { + typ, val := tkn.Scan() + for typ == COMMENT { + if tkn.AllowComments { + break + } + typ, val = tkn.Scan() + } + lval.bytes = val + tkn.lastToken = val + return typ +} + +// Error is called by go yacc if there's a parsing error. +func (tkn *Tokenizer) Error(err string) { + buf := &bytes2.Buffer{} + if tkn.lastToken != nil { + fmt.Fprintf(buf, "%s at position %v near '%s'", err, tkn.Position, tkn.lastToken) + } else { + fmt.Fprintf(buf, "%s at position %v", err, tkn.Position) + } + tkn.LastError = errors.New(buf.String()) + + // Try and re-sync to the next statement + if tkn.lastChar != ';' { + tkn.skipStatement() + } +} + +// Scan scans the tokenizer for the next token and returns +// the token type and an optional value. +func (tkn *Tokenizer) Scan() (int, []byte) { + if tkn.specialComment != nil { + // Enter specialComment scan mode. + // for scanning such kind of comment: /*! MySQL-specific code */ + specialComment := tkn.specialComment + tok, val := specialComment.Scan() + if tok != 0 { + // return the specialComment scan result as the result + return tok, val + } + // leave specialComment scan mode after all stream consumed. + tkn.specialComment = nil + } + if tkn.lastChar == 0 { + tkn.next() + } + + if tkn.ForceEOF { + tkn.skipStatement() + return 0, nil + } + + tkn.skipBlank() + switch ch := tkn.lastChar; { + case isLetter(ch): + tkn.next() + if ch == 'X' || ch == 'x' { + if tkn.lastChar == '\'' { + tkn.next() + return tkn.scanHex() + } + } + if ch == 'B' || ch == 'b' { + if tkn.lastChar == '\'' { + tkn.next() + return tkn.scanBitLiteral() + } + } + isDbSystemVariable := false + if ch == '@' && tkn.lastChar == '@' { + isDbSystemVariable = true + } + return tkn.scanIdentifier(byte(ch), isDbSystemVariable) + case isDigit(ch): + return tkn.scanNumber(false) + case ch == ':': + return tkn.scanBindVar() + case ch == ';' && tkn.multi: + return 0, nil + default: + tkn.next() + switch ch { + case eofChar: + return 0, nil + case '=', ',', ';', '(', ')', '+', '*', '%', '^', '~': + return int(ch), nil + case '&': + if tkn.lastChar == '&' { + tkn.next() + return AND, nil + } + return int(ch), nil + case '|': + if tkn.lastChar == '|' { + tkn.next() + return OR, nil + } + return int(ch), nil + case '?': + tkn.posVarIndex++ + buf := new(bytes2.Buffer) + fmt.Fprintf(buf, ":v%d", tkn.posVarIndex) + return VALUE_ARG, buf.Bytes() + case '.': + if isDigit(tkn.lastChar) { + return tkn.scanNumber(true) + } + return int(ch), nil + case '/': + switch tkn.lastChar { + case '/': + tkn.next() + return tkn.scanCommentType1("//") + case '*': + tkn.next() + switch tkn.lastChar { + case '!': + return tkn.scanMySQLSpecificComment() + default: + return tkn.scanCommentType2() + } + default: + return int(ch), nil + } + case '#': + return tkn.scanCommentType1("#") + case '-': + switch tkn.lastChar { + case '-': + tkn.next() + return tkn.scanCommentType1("--") + case '>': + tkn.next() + if tkn.lastChar == '>' { + tkn.next() + return JSON_UNQUOTE_EXTRACT_OP, nil + } + return JSON_EXTRACT_OP, nil + } + return int(ch), nil + case '<': + switch tkn.lastChar { + case '>': + tkn.next() + return NE, nil + case '<': + tkn.next() + return SHIFT_LEFT, nil + case '=': + tkn.next() + switch tkn.lastChar { + case '>': + tkn.next() + return NULL_SAFE_EQUAL, nil + default: + return LE, nil + } + default: + return int(ch), nil + } + case '>': + switch tkn.lastChar { + case '=': + tkn.next() + return GE, nil + case '>': + tkn.next() + return SHIFT_RIGHT, nil + default: + return int(ch), nil + } + case '!': + if tkn.lastChar == '=' { + tkn.next() + return NE, nil + } + return int(ch), nil + case '\'', '"': + return tkn.scanString(ch, STRING) + case '`': + return tkn.scanLiteralIdentifier() + default: + return LEX_ERROR, []byte{byte(ch)} + } + } +} + +// skipStatement scans until the EOF, or end of statement is encountered. +func (tkn *Tokenizer) skipStatement() { + ch := tkn.lastChar + for ch != ';' && ch != eofChar { + tkn.next() + ch = tkn.lastChar + } +} + +func (tkn *Tokenizer) skipBlank() { + ch := tkn.lastChar + for ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t' { + tkn.next() + ch = tkn.lastChar + } +} + +func (tkn *Tokenizer) scanIdentifier(firstByte byte, isDbSystemVariable bool) (int, []byte) { + buffer := &bytes2.Buffer{} + buffer.WriteByte(firstByte) + for isLetter(tkn.lastChar) || isDigit(tkn.lastChar) || (isDbSystemVariable && isCarat(tkn.lastChar)) { + buffer.WriteByte(byte(tkn.lastChar)) + tkn.next() + } + lowered := bytes.ToLower(buffer.Bytes()) + loweredStr := string(lowered) + if keywordID, found := keywords[loweredStr]; found { + return keywordID, lowered + } + // dual must always be case-insensitive + if loweredStr == "dual" { + return ID, lowered + } + return ID, buffer.Bytes() +} + +func (tkn *Tokenizer) scanHex() (int, []byte) { + buffer := &bytes2.Buffer{} + tkn.scanMantissa(16, buffer) + if tkn.lastChar != '\'' { + return LEX_ERROR, buffer.Bytes() + } + tkn.next() + if buffer.Len()%2 != 0 { + return LEX_ERROR, buffer.Bytes() + } + return HEX, buffer.Bytes() +} + +func (tkn *Tokenizer) scanBitLiteral() (int, []byte) { + buffer := &bytes2.Buffer{} + tkn.scanMantissa(2, buffer) + if tkn.lastChar != '\'' { + return LEX_ERROR, buffer.Bytes() + } + tkn.next() + return BIT_LITERAL, buffer.Bytes() +} + +func (tkn *Tokenizer) scanLiteralIdentifier() (int, []byte) { + buffer := &bytes2.Buffer{} + backTickSeen := false + for { + if backTickSeen { + if tkn.lastChar != '`' { + break + } + backTickSeen = false + buffer.WriteByte('`') + tkn.next() + continue + } + // The previous char was not a backtick. + switch tkn.lastChar { + case '`': + backTickSeen = true + case eofChar: + // Premature EOF. + return LEX_ERROR, buffer.Bytes() + default: + buffer.WriteByte(byte(tkn.lastChar)) + } + tkn.next() + } + if buffer.Len() == 0 { + return LEX_ERROR, buffer.Bytes() + } + return ID, buffer.Bytes() +} + +func (tkn *Tokenizer) scanBindVar() (int, []byte) { + buffer := &bytes2.Buffer{} + buffer.WriteByte(byte(tkn.lastChar)) + token := VALUE_ARG + tkn.next() + if tkn.lastChar == ':' { + token = LIST_ARG + buffer.WriteByte(byte(tkn.lastChar)) + tkn.next() + } + if !isLetter(tkn.lastChar) { + return LEX_ERROR, buffer.Bytes() + } + for isLetter(tkn.lastChar) || isDigit(tkn.lastChar) || tkn.lastChar == '.' { + buffer.WriteByte(byte(tkn.lastChar)) + tkn.next() + } + return token, buffer.Bytes() +} + +func (tkn *Tokenizer) scanMantissa(base int, buffer *bytes2.Buffer) { + for digitVal(tkn.lastChar) < base { + tkn.consumeNext(buffer) + } +} + +func (tkn *Tokenizer) scanNumber(seenDecimalPoint bool) (int, []byte) { + token := INTEGRAL + buffer := &bytes2.Buffer{} + if seenDecimalPoint { + token = FLOAT + buffer.WriteByte('.') + tkn.scanMantissa(10, buffer) + goto exponent + } + + // 0x construct. + if tkn.lastChar == '0' { + tkn.consumeNext(buffer) + if tkn.lastChar == 'x' || tkn.lastChar == 'X' { + token = HEXNUM + tkn.consumeNext(buffer) + tkn.scanMantissa(16, buffer) + goto exit + } + } + + tkn.scanMantissa(10, buffer) + + if tkn.lastChar == '.' { + token = FLOAT + tkn.consumeNext(buffer) + tkn.scanMantissa(10, buffer) + } + +exponent: + if tkn.lastChar == 'e' || tkn.lastChar == 'E' { + token = FLOAT + tkn.consumeNext(buffer) + if tkn.lastChar == '+' || tkn.lastChar == '-' { + tkn.consumeNext(buffer) + } + tkn.scanMantissa(10, buffer) + } + +exit: + // A letter cannot immediately follow a number. + if isLetter(tkn.lastChar) { + return LEX_ERROR, buffer.Bytes() + } + + return token, buffer.Bytes() +} + +func (tkn *Tokenizer) scanString(delim uint16, typ int) (int, []byte) { + var buffer bytes2.Buffer + for { + ch := tkn.lastChar + if ch == eofChar { + // Unterminated string. + return LEX_ERROR, buffer.Bytes() + } + + if ch != delim && ch != '\\' { + buffer.WriteByte(byte(ch)) + + // Scan ahead to the next interesting character. + start := tkn.bufPos + for ; tkn.bufPos < tkn.bufSize; tkn.bufPos++ { + ch = uint16(tkn.buf[tkn.bufPos]) + if ch == delim || ch == '\\' { + break + } + } + + buffer.Write(tkn.buf[start:tkn.bufPos]) + tkn.Position += (tkn.bufPos - start) + + if tkn.bufPos >= tkn.bufSize { + // Reached the end of the buffer without finding a delim or + // escape character. + tkn.next() + continue + } + + tkn.bufPos++ + tkn.Position++ + } + tkn.next() // Read one past the delim or escape character. + + if ch == '\\' { + if tkn.lastChar == eofChar { + // String terminates mid escape character. + return LEX_ERROR, buffer.Bytes() + } + if decodedChar := sqltypes.SQLDecodeMap[byte(tkn.lastChar)]; decodedChar == sqltypes.DontEscape { + ch = tkn.lastChar + } else { + ch = uint16(decodedChar) + } + + } else if ch == delim && tkn.lastChar != delim { + // Correctly terminated string, which is not a double delim. + break + } + + buffer.WriteByte(byte(ch)) + tkn.next() + } + + return typ, buffer.Bytes() +} + +func (tkn *Tokenizer) scanCommentType1(prefix string) (int, []byte) { + buffer := &bytes2.Buffer{} + buffer.WriteString(prefix) + for tkn.lastChar != eofChar { + if tkn.lastChar == '\n' { + tkn.consumeNext(buffer) + break + } + tkn.consumeNext(buffer) + } + return COMMENT, buffer.Bytes() +} + +func (tkn *Tokenizer) scanCommentType2() (int, []byte) { + buffer := &bytes2.Buffer{} + buffer.WriteString("/*") + for { + if tkn.lastChar == '*' { + tkn.consumeNext(buffer) + if tkn.lastChar == '/' { + tkn.consumeNext(buffer) + break + } + continue + } + if tkn.lastChar == eofChar { + return LEX_ERROR, buffer.Bytes() + } + tkn.consumeNext(buffer) + } + return COMMENT, buffer.Bytes() +} + +func (tkn *Tokenizer) scanMySQLSpecificComment() (int, []byte) { + buffer := &bytes2.Buffer{} + buffer.WriteString("/*!") + tkn.next() + for { + if tkn.lastChar == '*' { + tkn.consumeNext(buffer) + if tkn.lastChar == '/' { + tkn.consumeNext(buffer) + break + } + continue + } + if tkn.lastChar == eofChar { + return LEX_ERROR, buffer.Bytes() + } + tkn.consumeNext(buffer) + } + _, sql := ExtractMysqlComment(buffer.String()) + tkn.specialComment = NewStringTokenizer(sql) + return tkn.Scan() +} + +func (tkn *Tokenizer) consumeNext(buffer *bytes2.Buffer) { + if tkn.lastChar == eofChar { + // This should never happen. + panic("unexpected EOF") + } + buffer.WriteByte(byte(tkn.lastChar)) + tkn.next() +} + +func (tkn *Tokenizer) next() { + if tkn.bufPos >= tkn.bufSize && tkn.InStream != nil { + // Try and refill the buffer + var err error + tkn.bufPos = 0 + if tkn.bufSize, err = tkn.InStream.Read(tkn.buf); err != io.EOF && err != nil { + tkn.LastError = err + } + } + + if tkn.bufPos >= tkn.bufSize { + if tkn.lastChar != eofChar { + tkn.Position++ + tkn.lastChar = eofChar + } + } else { + tkn.Position++ + tkn.lastChar = uint16(tkn.buf[tkn.bufPos]) + tkn.bufPos++ + } +} + +// reset clears any internal state. +func (tkn *Tokenizer) reset() { + tkn.ParseTree = nil + tkn.partialDDL = nil + tkn.specialComment = nil + tkn.posVarIndex = 0 + tkn.nesting = 0 + tkn.ForceEOF = false +} + +func isLetter(ch uint16) bool { + return 'a' <= ch && ch <= 'z' || 'A' <= ch && ch <= 'Z' || ch == '_' || ch == '@' +} + +func isCarat(ch uint16) bool { + return ch == '.' || ch == '\'' || ch == '"' || ch == '`' +} + +func digitVal(ch uint16) int { + switch { + case '0' <= ch && ch <= '9': + return int(ch) - '0' + case 'a' <= ch && ch <= 'f': + return int(ch) - 'a' + 10 + case 'A' <= ch && ch <= 'F': + return int(ch) - 'A' + 10 + } + return 16 // larger than any legal digit val +} + +func isDigit(ch uint16) bool { + return '0' <= ch && ch <= '9' +} diff --git a/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/token_test.go b/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/token_test.go new file mode 100644 index 00000000..93543545 --- /dev/null +++ b/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/token_test.go @@ -0,0 +1,191 @@ +/* +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 sqlparser + +import ( + "fmt" + "testing" +) + +func TestLiteralID(t *testing.T) { + testcases := []struct { + in string + id int + out string + }{{ + in: "`aa`", + id: ID, + out: "aa", + }, { + in: "```a```", + id: ID, + out: "`a`", + }, { + in: "`a``b`", + id: ID, + out: "a`b", + }, { + in: "`a``b`c", + id: ID, + out: "a`b", + }, { + in: "`a``b", + id: LEX_ERROR, + out: "a`b", + }, { + in: "`a``b``", + id: LEX_ERROR, + out: "a`b`", + }, { + in: "``", + id: LEX_ERROR, + out: "", + }} + + for _, tcase := range testcases { + tkn := NewStringTokenizer(tcase.in) + id, out := tkn.Scan() + if tcase.id != id || string(out) != tcase.out { + t.Errorf("Scan(%s): %d, %s, want %d, %s", tcase.in, id, out, tcase.id, tcase.out) + } + } +} + +func tokenName(id int) string { + if id == STRING { + return "STRING" + } else if id == LEX_ERROR { + return "LEX_ERROR" + } + return fmt.Sprintf("%d", id) +} + +func TestString(t *testing.T) { + testcases := []struct { + in string + id int + want string + }{{ + in: "''", + id: STRING, + want: "", + }, { + in: "''''", + id: STRING, + want: "'", + }, { + in: "'hello'", + id: STRING, + want: "hello", + }, { + in: "'\\n'", + id: STRING, + want: "\n", + }, { + in: "'\\nhello\\n'", + id: STRING, + want: "\nhello\n", + }, { + in: "'a''b'", + id: STRING, + want: "a'b", + }, { + in: "'a\\'b'", + id: STRING, + want: "a'b", + }, { + in: "'\\'", + id: LEX_ERROR, + want: "'", + }, { + in: "'", + id: LEX_ERROR, + want: "", + }, { + in: "'hello\\'", + id: LEX_ERROR, + want: "hello'", + }, { + in: "'hello", + id: LEX_ERROR, + want: "hello", + }, { + in: "'hello\\", + id: LEX_ERROR, + want: "hello", + }} + + for _, tcase := range testcases { + id, got := NewStringTokenizer(tcase.in).Scan() + if tcase.id != id || string(got) != tcase.want { + t.Errorf("Scan(%q) = (%s, %q), want (%s, %q)", tcase.in, tokenName(id), got, tokenName(tcase.id), tcase.want) + } + } +} + +func TestSplitStatement(t *testing.T) { + testcases := []struct { + in string + sql string + rem string + }{{ + in: "select * from table", + sql: "select * from table", + }, { + in: "select * from table; ", + sql: "select * from table", + rem: " ", + }, { + in: "select * from table; select * from table2;", + sql: "select * from table", + rem: " select * from table2;", + }, { + in: "select * from /* comment */ table;", + sql: "select * from /* comment */ table", + }, { + in: "select * from /* comment ; */ table;", + sql: "select * from /* comment ; */ table", + }, { + in: "select * from table where semi = ';';", + sql: "select * from table where semi = ';'", + }, { + in: "-- select * from table", + sql: "-- select * from table", + }, { + in: " ", + sql: " ", + }, { + in: "", + sql: "", + }} + + for _, tcase := range testcases { + sql, rem, err := SplitStatement(tcase.in) + if err != nil { + t.Errorf("EndOfStatementPosition(%s): ERROR: %v", tcase.in, err) + continue + } + + if tcase.sql != sql { + t.Errorf("EndOfStatementPosition(%s) got sql \"%s\" want \"%s\"", tcase.in, sql, tcase.sql) + } + + if tcase.rem != rem { + t.Errorf("EndOfStatementPosition(%s) got remainder \"%s\" want \"%s\"", tcase.in, rem, tcase.rem) + } + } +} diff --git a/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/tracked_buffer.go b/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/tracked_buffer.go new file mode 100644 index 00000000..ec421a5f --- /dev/null +++ b/functions/query/vendor/github.com/v3io/v3io-tsdb/vendor/github.com/xwb1989/sqlparser/tracked_buffer.go @@ -0,0 +1,140 @@ +/* +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 sqlparser + +import ( + "bytes" + "fmt" +) + +// NodeFormatter defines the signature of a custom node formatter +// function that can be given to TrackedBuffer for code generation. +type NodeFormatter func(buf *TrackedBuffer, node SQLNode) + +// TrackedBuffer is used to rebuild a query from the ast. +// bindLocations keeps track of locations in the buffer that +// use bind variables for efficient future substitutions. +// nodeFormatter is the formatting function the buffer will +// use to format a node. By default(nil), it's FormatNode. +// But you can supply a different formatting function if you +// want to generate a query that's different from the default. +type TrackedBuffer struct { + *bytes.Buffer + bindLocations []bindLocation + nodeFormatter NodeFormatter +} + +// NewTrackedBuffer creates a new TrackedBuffer. +func NewTrackedBuffer(nodeFormatter NodeFormatter) *TrackedBuffer { + return &TrackedBuffer{ + Buffer: new(bytes.Buffer), + nodeFormatter: nodeFormatter, + } +} + +// WriteNode function, initiates the writing of a single SQLNode tree by passing +// through to Myprintf with a default format string +func (buf *TrackedBuffer) WriteNode(node SQLNode) *TrackedBuffer { + buf.Myprintf("%v", node) + return buf +} + +// Myprintf mimics fmt.Fprintf(buf, ...), but limited to Node(%v), +// Node.Value(%s) and string(%s). It also allows a %a for a value argument, in +// which case it adds tracking info for future substitutions. +// +// The name must be something other than the usual Printf() to avoid "go vet" +// warnings due to our custom format specifiers. +func (buf *TrackedBuffer) Myprintf(format string, values ...interface{}) { + end := len(format) + fieldnum := 0 + for i := 0; i < end; { + lasti := i + for i < end && format[i] != '%' { + i++ + } + if i > lasti { + buf.WriteString(format[lasti:i]) + } + if i >= end { + break + } + i++ // '%' + switch format[i] { + case 'c': + switch v := values[fieldnum].(type) { + case byte: + buf.WriteByte(v) + case rune: + buf.WriteRune(v) + default: + panic(fmt.Sprintf("unexpected TrackedBuffer type %T", v)) + } + case 's': + switch v := values[fieldnum].(type) { + case []byte: + buf.Write(v) + case string: + buf.WriteString(v) + default: + panic(fmt.Sprintf("unexpected TrackedBuffer type %T", v)) + } + case 'v': + node := values[fieldnum].(SQLNode) + if buf.nodeFormatter == nil { + node.Format(buf) + } else { + buf.nodeFormatter(buf, node) + } + case 'a': + buf.WriteArg(values[fieldnum].(string)) + default: + panic("unexpected") + } + fieldnum++ + i++ + } +} + +// WriteArg writes a value argument into the buffer along with +// tracking information for future substitutions. arg must contain +// the ":" or "::" prefix. +func (buf *TrackedBuffer) WriteArg(arg string) { + buf.bindLocations = append(buf.bindLocations, bindLocation{ + offset: buf.Len(), + length: len(arg), + }) + buf.WriteString(arg) +} + +// ParsedQuery returns a ParsedQuery that contains bind +// locations for easy substitution. +func (buf *TrackedBuffer) ParsedQuery() *ParsedQuery { + return &ParsedQuery{Query: buf.String(), bindLocations: buf.bindLocations} +} + +// HasBindVars returns true if the parsed query uses bind vars. +func (buf *TrackedBuffer) HasBindVars() bool { + return len(buf.bindLocations) != 0 +} + +// BuildParsedQuery builds a ParsedQuery from the input. +func BuildParsedQuery(in string, vars ...interface{}) *ParsedQuery { + buf := NewTrackedBuffer(nil) + buf.Myprintf(in, vars...) + return buf.ParsedQuery() +}