//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
}
Exemple #2
0
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
}