//get the execute database for insert or replace sql func (c *ClientConn) getInsertOrReplaceExecDB(tokens []string, tokensLen int) (*ExecuteDB, error) { executeDB := new(ExecuteDB) schema := c.proxy.schema rules := schema.rule.Rules if len(rules) != 0 { for i := 0; i < tokensLen; i++ { if strings.ToLower(tokens[i]) == mysql.TK_STR_INTO { if i+1 < tokensLen { tableName := sqlparser.GetInsertTableName(tokens[i+1]) if _, ok := rules[tableName]; ok { return nil, nil } } } } } err := c.setExecuteNode(tokens, tokensLen, executeDB) if err != nil { return nil, err } return executeDB, nil }
func (c *ClientConn) GetExecNode(tokens []string, sql string) (*backend.Node, bool, error) { var execNode *backend.Node var fromSlave bool schema := c.proxy.schemas[c.proxy.db] rules := schema.rule.Rules tokensLen := len(tokens) if 0 < tokensLen { tokenId, ok := mysql.PARSE_TOKEN_MAP[strings.ToLower(tokens[0])] if ok == true { switch tokenId { case mysql.TK_ID_SELECT, mysql.TK_ID_DELETE: if len(rules) == 0 { if tokenId == mysql.TK_ID_SELECT { fromSlave = true } break } for i := 1; i < tokensLen; i++ { if strings.ToLower(tokens[i]) == mysql.TK_STR_FROM { if i+1 < tokensLen { tableName := sqlparser.GetTableName(tokens[i+1]) if _, ok := rules[tableName]; ok { return nil, false, nil } else { fromSlave = true } } } } case mysql.TK_ID_INSERT, mysql.TK_ID_REPLACE: if len(rules) == 0 { break } for i := 0; i < tokensLen; i++ { if strings.ToLower(tokens[i]) == mysql.TK_STR_INTO { if i+1 < tokensLen { tableName := sqlparser.GetInsertTableName(tokens[i+1]) if _, ok := rules[tableName]; ok { return nil, false, nil } } } } case mysql.TK_ID_UPDATE: if len(rules) == 0 { break } for i := 0; i < tokensLen; i++ { if strings.ToLower(tokens[i]) == mysql.TK_STR_SET { tableName := sqlparser.GetTableName(tokens[i-1]) if _, ok := rules[tableName]; ok { return nil, false, nil } } } default: return nil, false, nil } } } //get node if 2 <= tokensLen { if tokens[0][0] == mysql.COMMENT_PREFIX { nodeName := strings.Trim(tokens[0], mysql.COMMENT_STRING) if c.schema.nodes[nodeName] != nil { execNode = c.schema.nodes[nodeName] } //select if mysql.PARSE_TOKEN_MAP[tokens[1]] == mysql.TK_ID_SELECT { fromSlave = true } } } if execNode == nil { defaultRule := c.schema.rule.DefaultRule if len(defaultRule.Nodes) == 0 { return nil, false, errors.ErrNoDefaultNode } execNode = c.proxy.GetNode(defaultRule.Nodes[0]) } return execNode, fromSlave, nil }