11/*
2- Copyright 2017 Google Inc .
2+ Copyright 2019 The Vitess Authors .
33
44Licensed under the Apache License, Version 2.0 (the "License");
55you may not use this file except in compliance with the License.
@@ -19,18 +19,21 @@ package sqlparser
1919// analyzer.go contains utility analysis functions.
2020
2121import (
22- "errors"
2322 "fmt"
2423 "strconv"
2524 "strings"
2625 "unicode"
2726
28- "github.com/xwb1989 /sqlparser/dependency/sqltypes"
27+ "github.com/sandeepone /sqlparser/dependency/sqltypes"
2928)
3029
30+ // StatementType encodes the type of a SQL statement
31+ type StatementType int
32+
3133// These constants are used to identify the SQL statement type.
34+ // Changing this list will require reviewing all calls to Preview.
3235const (
33- StmtSelect = iota
36+ StmtSelect StatementType = iota
3437 StmtStream
3538 StmtInsert
3639 StmtReplace
@@ -50,14 +53,19 @@ const (
5053
5154// Preview analyzes the beginning of the query using a simpler and faster
5255// textual comparison to identify the statement type.
53- func Preview (sql string ) int {
56+ func Preview (sql string ) StatementType {
5457 trimmed := StripLeadingComments (sql )
5558
56- firstWord := trimmed
57- if end := strings .IndexFunc (trimmed , unicode .IsSpace ); end != - 1 {
58- firstWord = trimmed [:end ]
59+ if strings .Index (trimmed , "/*!" ) == 0 {
60+ return StmtComment
61+ }
62+
63+ isNotLetter := func (r rune ) bool { return ! unicode .IsLetter (r ) }
64+ firstWord := strings .TrimLeftFunc (trimmed , isNotLetter )
65+
66+ if end := strings .IndexFunc (firstWord , unicode .IsSpace ); end != - 1 {
67+ firstWord = firstWord [:end ]
5968 }
60- firstWord = strings .TrimLeftFunc (firstWord , func (r rune ) bool { return ! unicode .IsLetter (r ) })
6169 // Comparison is done in order of priority.
6270 loweredFirstWord := strings .ToLower (firstWord )
6371 switch loweredFirstWord {
@@ -89,7 +97,7 @@ func Preview(sql string) int {
8997 return StmtRollback
9098 }
9199 switch loweredFirstWord {
92- case "create" , "alter" , "rename" , "drop" , "truncate" :
100+ case "create" , "alter" , "rename" , "drop" , "truncate" , "flush" :
93101 return StmtDDL
94102 case "set" :
95103 return StmtSet
@@ -100,15 +108,11 @@ func Preview(sql string) int {
100108 case "analyze" , "describe" , "desc" , "explain" , "repair" , "optimize" :
101109 return StmtOther
102110 }
103- if strings .Index (trimmed , "/*!" ) == 0 {
104- return StmtComment
105- }
106111 return StmtUnknown
107112}
108113
109- // StmtType returns the statement type as a string
110- func StmtType (stmtType int ) string {
111- switch stmtType {
114+ func (s StatementType ) String () string {
115+ switch s {
112116 case StmtSelect :
113117 return "SELECT"
114118 case StmtStream :
@@ -151,6 +155,23 @@ func IsDML(sql string) bool {
151155 return false
152156}
153157
158+ // SplitAndExpression breaks up the Expr into AND-separated conditions
159+ // and appends them to filters. Outer parenthesis are removed. Precedence
160+ // should be taken into account if expressions are recombined.
161+ func SplitAndExpression (filters []Expr , node Expr ) []Expr {
162+ if node == nil {
163+ return filters
164+ }
165+ switch node := node .(type ) {
166+ case * AndExpr :
167+ filters = SplitAndExpression (filters , node .Left )
168+ return SplitAndExpression (filters , node .Right )
169+ case * ParenExpr :
170+ return SplitAndExpression (filters , node .Expr )
171+ }
172+ return append (filters , node )
173+ }
174+
154175// GetTableName returns the table name from the SimpleTableExpr
155176// only if it's a simple expression. Otherwise, it returns "".
156177func GetTableName (node SimpleTableExpr ) TableIdent {
@@ -217,15 +238,15 @@ func NewPlanValue(node Expr) (sqltypes.PlanValue, error) {
217238 case IntVal :
218239 n , err := sqltypes .NewIntegral (string (node .Val ))
219240 if err != nil {
220- return sqltypes.PlanValue {}, fmt . Errorf ( "%v" , err )
241+ return sqltypes.PlanValue {}, err
221242 }
222243 return sqltypes.PlanValue {Value : n }, nil
223244 case StrVal :
224245 return sqltypes.PlanValue {Value : sqltypes .MakeTrusted (sqltypes .VarBinary , node .Val )}, nil
225246 case HexVal :
226247 v , err := node .HexDecode ()
227248 if err != nil {
228- return sqltypes.PlanValue {}, fmt . Errorf ( "%v" , err )
249+ return sqltypes.PlanValue {}, err
229250 }
230251 return sqltypes.PlanValue {Value : sqltypes .MakeTrusted (sqltypes .VarBinary , v )}, nil
231252 }
@@ -252,17 +273,6 @@ func NewPlanValue(node Expr) (sqltypes.PlanValue, error) {
252273 return sqltypes.PlanValue {}, fmt .Errorf ("expression is too complex '%v'" , String (node ))
253274}
254275
255- // StringIn is a convenience function that returns
256- // true if str matches any of the values.
257- func StringIn (str string , values ... string ) bool {
258- for _ , val := range values {
259- if str == val {
260- return true
261- }
262- }
263- return false
264- }
265-
266276// SetKey is the extracted key from one SetExpr
267277type SetKey struct {
268278 Key string
@@ -284,14 +294,18 @@ func ExtractSetValues(sql string) (keyValues map[SetKey]interface{}, scope strin
284294 }
285295 result := make (map [SetKey ]interface {})
286296 for _ , expr := range setStmt .Exprs {
287- scope := SessionStr
297+ scope := ImplicitStr
288298 key := expr .Name .Lowered ()
289299 switch {
290300 case strings .HasPrefix (key , "@@global." ):
291301 scope = GlobalStr
292302 key = strings .TrimPrefix (key , "@@global." )
293303 case strings .HasPrefix (key , "@@session." ):
304+ scope = SessionStr
294305 key = strings .TrimPrefix (key , "@@session." )
306+ case strings .HasPrefix (key , "@@vitess_metadata." ):
307+ scope = VitessMetadataStr
308+ key = strings .TrimPrefix (key , "@@vitess_metadata." )
295309 case strings .HasPrefix (key , "@@" ):
296310 key = strings .TrimPrefix (key , "@@" )
297311 }
0 commit comments