func analyzeBoolean(node sqlparser.BoolExpr) (conditions []*sqlparser.ComparisonExpr) { switch node := node.(type) { case *sqlparser.AndExpr: left := analyzeBoolean(node.Left) right := analyzeBoolean(node.Right) if left == nil || right == nil { return nil } return append(left, right...) case *sqlparser.ParenBoolExpr: return analyzeBoolean(node.Expr) case *sqlparser.ComparisonExpr: switch { case sqlparser.StringIn( node.Operator, sqlparser.EqualStr, sqlparser.LikeStr): if sqlparser.IsColName(node.Left) && sqlparser.IsValue(node.Right) { return []*sqlparser.ComparisonExpr{node} } case node.Operator == sqlparser.InStr: if sqlparser.IsColName(node.Left) && sqlparser.IsSimpleTuple(node.Right) { return []*sqlparser.ComparisonExpr{node} } } } return nil }
func getPKValues(conditions []sqlparser.BoolExpr, pkIndex *schema.Index) (pkValues []interface{}, err error) { pkIndexScore := NewIndexScore(pkIndex) pkValues = make([]interface{}, len(pkIndexScore.ColumnMatch)) for _, condition := range conditions { condition, ok := condition.(*sqlparser.ComparisonExpr) if !ok { return nil, nil } if !sqlparser.StringIn(condition.Operator, sqlparser.AST_EQ, sqlparser.AST_IN) { return nil, nil } index := pkIndexScore.FindMatch(string(condition.Left.(*sqlparser.ColName).Name)) if index == -1 { return nil, nil } switch condition.Operator { case sqlparser.AST_EQ, sqlparser.AST_IN: var err error pkValues[index], err = sqlparser.AsInterface(condition.Right) if err != nil { return nil, err } default: panic("unreachable") } } if pkIndexScore.GetScore() == PERFECT_SCORE { return pkValues, nil } return nil, nil }
func isIndexChanging(setClauses sqlparser.UpdateExprs, indexes []*Index) bool { indexCols := make([]string, len(indexes)) for i, index := range indexes { indexCols[i] = index.Column } for _, assignment := range setClauses { if sqlparser.StringIn(string(assignment.Name.Name), indexCols...) { return true } } return false }
func analyzeBoolean(node sqlparser.BoolExpr) (conditions []sqlparser.BoolExpr) { switch node := node.(type) { case *sqlparser.AndExpr: left := analyzeBoolean(node.Left) right := analyzeBoolean(node.Right) if left == nil || right == nil { return nil } if sqlparser.HasINClause(left) && sqlparser.HasINClause(right) { return nil } return append(left, right...) case *sqlparser.ParenBoolExpr: return analyzeBoolean(node.Expr) case *sqlparser.ComparisonExpr: switch { case sqlparser.StringIn( node.Operator, sqlparser.AST_EQ, sqlparser.AST_LT, sqlparser.AST_GT, sqlparser.AST_LE, sqlparser.AST_GE, sqlparser.AST_NSE, sqlparser.AST_LIKE): if sqlparser.IsColName(node.Left) && sqlparser.IsValue(node.Right) { return []sqlparser.BoolExpr{node} } case node.Operator == sqlparser.AST_IN: if sqlparser.IsColName(node.Left) && sqlparser.IsSimpleTuple(node.Right) { return []sqlparser.BoolExpr{node} } } case *sqlparser.RangeCond: if node.Operator != sqlparser.AST_BETWEEN { return nil } if sqlparser.IsColName(node.Left) && sqlparser.IsValue(node.From) && sqlparser.IsValue(node.To) { return []sqlparser.BoolExpr{node} } } return nil }
func analyzeBoolean(node sqlparser.BoolExpr) (conditions []sqlparser.BoolExpr) { switch node := node.(type) { case *sqlparser.AndExpr: left := analyzeBoolean(node.Left) right := analyzeBoolean(node.Right) if left == nil || right == nil { return nil } if sqlparser.HasINClause(left) && sqlparser.HasINClause(right) { return nil } return append(left, right...) case *sqlparser.ParenBoolExpr: return analyzeBoolean(node.Expr) case *sqlparser.ComparisonExpr: switch { case sqlparser.StringIn( node.Operator, sqlparser.EqualStr, sqlparser.LessThanStr, sqlparser.GreaterThanStr, sqlparser.LessEqualStr, sqlparser.GreaterEqualStr, sqlparser.NullSafeEqualStr, sqlparser.LikeStr): if sqlparser.IsColName(node.Left) && sqlparser.IsValue(node.Right) { return []sqlparser.BoolExpr{node} } case node.Operator == sqlparser.InStr: if sqlparser.IsColName(node.Left) && sqlparser.IsSimpleTuple(node.Right) { return []sqlparser.BoolExpr{node} } } case *sqlparser.RangeCond: if node.Operator != sqlparser.BetweenStr { return nil } if sqlparser.IsColName(node.Left) && sqlparser.IsValue(node.From) && sqlparser.IsValue(node.To) { return []sqlparser.BoolExpr{node} } } return nil }
func routingAnalyzeBoolean(node sqlparser.BoolExpr) sqlparser.BoolExpr { switch node := node.(type) { case *sqlparser.AndExpr: left := routingAnalyzeBoolean(node.Left) right := routingAnalyzeBoolean(node.Right) if left != nil && right != nil { return nil } else if left != nil { return left } else { return right } case *sqlparser.ParenBoolExpr: return routingAnalyzeBoolean(node.Expr) case *sqlparser.ComparisonExpr: switch { case sqlparser.StringIn(node.Operator, "=", "<", ">", "<=", ">=", "<=>"): left := routingAnalyzeValue(node.Left) right := routingAnalyzeValue(node.Right) if (left == EID_NODE && right == VALUE_NODE) || (left == VALUE_NODE && right == EID_NODE) { return node } case node.Operator == "in": left := routingAnalyzeValue(node.Left) right := routingAnalyzeValue(node.Right) if left == EID_NODE && right == LIST_NODE { return node } } case *sqlparser.RangeCond: if node.Operator != "between" { return nil } left := routingAnalyzeValue(node.Left) from := routingAnalyzeValue(node.From) to := routingAnalyzeValue(node.To) if left == EID_NODE && from == VALUE_NODE && to == VALUE_NODE { return node } } return nil }