github.com/XiaoMi/Gaea@v1.2.5/parser/analyzer.go (about) 1 // Copyright 2012, Google Inc. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // Copyright 2016 The kingshard Authors. All rights reserved. 6 // 7 // Licensed under the Apache License, Version 2.0 (the "License"): you may 8 // not use this file except in compliance with the License. You may obtain 9 // a copy of the License at 10 // 11 // http://www.apache.org/licenses/LICENSE-2.0 12 // 13 // Unless required by applicable law or agreed to in writing, software 14 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 16 // License for the specific language governing permissions and limitations 17 // under the License. 18 19 package parser 20 21 // analyzer.go contains utility analysis functions. 22 23 import ( 24 "strings" 25 "unicode" 26 ) 27 28 // These constants are used to identify the SQL statement type. 29 const ( 30 StmtSelect = iota 31 StmtStream 32 StmtInsert 33 StmtReplace 34 StmtUpdate 35 StmtDelete 36 StmtDDL 37 StmtBegin 38 StmtCommit 39 StmtRollback 40 StmtSet 41 StmtShow 42 StmtUse 43 StmtOther 44 StmtUnknown 45 StmtComment 46 StmtSavepoint 47 ) 48 49 // Preview analyzes the beginning of the query using a simpler and faster 50 // textual comparison to identify the statement type. 51 func Preview(sql string) int { 52 trimmed := StripLeadingComments(sql) 53 54 firstWord := trimmed 55 if end := strings.IndexFunc(trimmed, unicode.IsSpace); end != -1 { 56 firstWord = trimmed[:end] 57 } 58 firstWord = strings.TrimLeftFunc(firstWord, func(r rune) bool { return !unicode.IsLetter(r) }) 59 // Comparison is done in order of priority. 60 loweredFirstWord := strings.ToLower(firstWord) 61 switch loweredFirstWord { 62 case "select": 63 return StmtSelect 64 case "stream": 65 return StmtStream 66 case "insert": 67 return StmtInsert 68 case "replace": 69 return StmtReplace 70 case "update": 71 return StmtUpdate 72 case "delete": 73 return StmtDelete 74 } 75 // For the following statements it is not sufficient to rely 76 // on loweredFirstWord. This is because they are not statements 77 // in the grammar and we are relying on Preview to parse them. 78 // For instance, we don't want: "BEGIN JUNK" to be parsed 79 // as StmtBegin. 80 trimmedNoComments, _ := SplitMarginComments(trimmed) 81 switch strings.ToLower(trimmedNoComments) { 82 case "begin", "start transaction": 83 return StmtBegin 84 } 85 switch loweredFirstWord { 86 case "create", "alter", "rename", "drop", "truncate", "flush": 87 return StmtDDL 88 case "set": 89 return StmtSet 90 case "show": 91 return StmtShow 92 case "use": 93 return StmtUse 94 case "analyze", "describe", "desc", "explain", "repair", "optimize": 95 return StmtOther 96 case "commit": 97 return StmtCommit 98 case "rollback": 99 return StmtRollback 100 case "savepoint": 101 return StmtSavepoint 102 } 103 if strings.Index(trimmedNoComments, "release savepoint") == 0 { 104 return StmtSavepoint 105 } 106 if strings.Index(trimmed, "/*!") == 0 { 107 return StmtComment 108 } 109 return StmtUnknown 110 } 111 112 // StmtType returns the statement type as a string 113 func StmtType(stmtType int) string { 114 switch stmtType { 115 case StmtSelect: 116 return "SELECT" 117 case StmtStream: 118 return "STREAM" 119 case StmtInsert: 120 return "INSERT" 121 case StmtReplace: 122 return "REPLACE" 123 case StmtUpdate: 124 return "UPDATE" 125 case StmtDelete: 126 return "DELETE" 127 case StmtDDL: 128 return "DDL" 129 case StmtBegin: 130 return "BEGIN" 131 case StmtCommit: 132 return "COMMIT" 133 case StmtRollback: 134 return "ROLLBACK" 135 case StmtSavepoint: 136 return "SAVEPOINT" 137 case StmtSet: 138 return "SET" 139 case StmtShow: 140 return "SHOW" 141 case StmtUse: 142 return "USE" 143 case StmtOther: 144 return "OTHER" 145 default: 146 return "UNKNOWN" 147 } 148 }