statementReferencesDatabase reports whether dbName appears as a database qualifier (`dbName.`) in the statement, at an identifier boundary.
(statement, dbName string)
| 210 | // statementReferencesDatabase reports whether dbName appears as a database |
| 211 | // qualifier (`dbName.`) in the statement, at an identifier boundary. |
| 212 | func statementReferencesDatabase(statement, dbName string) bool { |
| 213 | if dbName == "" { |
| 214 | return false |
| 215 | } |
| 216 | s := strings.ToLower(stripStringsAndComments(statement)) |
| 217 | name := strings.ToLower(dbName) |
| 218 | // Match the database name (bare or backtick-quoted) at an identifier |
| 219 | // boundary, followed by optional whitespace and a dot. TiDB allows whitespace |
| 220 | // around the qualifier dot (e.g. `db . table`). |
| 221 | for _, q := range []string{name, "`" + name + "`"} { |
| 222 | from := 0 |
| 223 | for { |
| 224 | i := strings.Index(s[from:], q) |
| 225 | if i < 0 { |
| 226 | break |
| 227 | } |
| 228 | at := from + i |
| 229 | from = at + 1 |
| 230 | // The bare form must start at an identifier boundary so `mydb` |
| 231 | // doesn't match inside `notmydb`. |
| 232 | if q[0] != '`' && at > 0 && isIdentByte(s[at-1]) { |
| 233 | continue |
| 234 | } |
| 235 | j := at + len(q) |
| 236 | for j < len(s) && isSpaceByte(s[j]) { |
| 237 | j++ |
| 238 | } |
| 239 | if j < len(s) && s[j] == '.' { |
| 240 | return true |
| 241 | } |
| 242 | } |
| 243 | } |
| 244 | return false |
| 245 | } |
| 246 | |
| 247 | func isIdentByte(b byte) bool { |
| 248 | return b == '_' || |