func getInsertPKValues(pkColumnNumbers []int, rowList sqlparser.Values, tableInfo *schema.Table) (pkValues []interface{}, err error) { pkValues = make([]interface{}, len(pkColumnNumbers)) for index, columnNumber := range pkColumnNumbers { if columnNumber == -1 { pkValues[index] = tableInfo.GetPKColumn(index).Default continue } values := make([]interface{}, len(rowList)) for j := 0; j < len(rowList); j++ { if _, ok := rowList[j].(*sqlparser.Subquery); ok { return nil, errors.New("row subquery not supported for inserts") } row := rowList[j].(sqlparser.ValTuple) if columnNumber >= len(row) { return nil, errors.New("column count doesn't match value count") } node := row[columnNumber] if !sqlparser.IsNull(node) && !sqlparser.IsValue(node) { return nil, nil } var err error values[j], err = sqlparser.AsInterface(node) if err != nil { return nil, err } } if len(values) == 1 { pkValues[index] = values[0] } else { pkValues[index] = values } } return pkValues, nil }
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 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 getMatch(node sqlparser.BoolExpr, index *Index) (planID PlanID, values interface{}) { switch node := node.(type) { case *sqlparser.AndExpr: if planID, values = getMatch(node.Left, index); planID != SelectScatter { return planID, values } if planID, values = getMatch(node.Right, index); planID != SelectScatter { return planID, values } case *sqlparser.ParenBoolExpr: return getMatch(node.Expr, index) case *sqlparser.ComparisonExpr: switch node.Operator { case "=": if !nameMatch(node.Left, index.Column) { return SelectScatter, nil } if !sqlparser.IsValue(node.Right) { return SelectScatter, nil } val, err := sqlparser.AsInterface(node.Right) if err != nil { return SelectScatter, nil } if index.Type == ShardKey { planID = SelectSingleShardKey } else { planID = SelectSingleLookup } return planID, val case "in": if !nameMatch(node.Left, index.Column) { return SelectScatter, nil } if !sqlparser.IsSimpleTuple(node.Right) { return SelectScatter, nil } val, err := sqlparser.AsInterface(node.Right) if err != nil { return SelectScatter, nil } node.Right = sqlparser.ListArg("::_vals") if index.Type == ShardKey { planID = SelectMultiShardKey } else { planID = SelectMultiLookup } return planID, val } } return SelectScatter, nil }
func getMatch(node sqlparser.BoolExpr, col string) (planID PlanID, values interface{}) { switch node := node.(type) { case *sqlparser.AndExpr: if planID, values = getMatch(node.Left, col); planID != SelectScatter { return planID, values } if planID, values = getMatch(node.Right, col); planID != SelectScatter { return planID, values } case *sqlparser.ParenBoolExpr: return getMatch(node.Expr, col) case *sqlparser.ComparisonExpr: switch node.Operator { case "=": if !nameMatch(node.Left, col) { return SelectScatter, nil } if !sqlparser.IsValue(node.Right) { return SelectScatter, nil } val, err := asInterface(node.Right) if err != nil { return SelectScatter, nil } return SelectEqual, val case "in": if !nameMatch(node.Left, col) { return SelectScatter, nil } if !sqlparser.IsSimpleTuple(node.Right) { return SelectScatter, nil } val, err := asInterface(node.Right) if err != nil { return SelectScatter, nil } node.Right = sqlparser.ListArg("::" + ListVarName) return SelectIN, val } } return SelectScatter, nil }
func analyzeUpdateExpressions(exprs sqlparser.UpdateExprs, pkIndex *schema.Index) (pkValues []interface{}, err error) { for _, expr := range exprs { index := pkIndex.FindColumn(expr.Name.Original()) if index == -1 { continue } if !sqlparser.IsValue(expr.Expr) { return nil, ErrTooComplex } if pkValues == nil { pkValues = make([]interface{}, len(pkIndex.Columns)) } var err error pkValues[index], err = sqlparser.AsInterface(expr.Expr) if err != nil { return nil, err } } return pkValues, nil }
func analyzeUpdateExpressions(exprs sqlparser.UpdateExprs, pkIndex *schema.Index) (pkValues []interface{}, err error) { for _, expr := range exprs { index := pkIndex.FindColumn(sqlparser.GetColName(expr.Name)) if index == -1 { continue } if !sqlparser.IsValue(expr.Expr) { log.Warningf("expression is too complex %v", expr) return nil, TooComplex } if pkValues == nil { pkValues = make([]interface{}, len(pkIndex.Columns)) } var err error pkValues[index], err = sqlparser.AsInterface(expr.Expr) if err != nil { return nil, err } } return pkValues, nil }
// getMatch returns the matched value if there is an equality // constraint on the specified column that can be used to // decide on a route. func getMatch(node sqlparser.BoolExpr, col cistring.CIString) interface{} { filters := splitAndExpression(nil, node) for _, filter := range filters { comparison, ok := filter.(*sqlparser.ComparisonExpr) if !ok { continue } if comparison.Operator != sqlparser.EqualStr { continue } if !nameMatch(comparison.Left, col) { continue } if !sqlparser.IsValue(comparison.Right) { continue } val, err := valConvert(comparison.Right) if err != nil { continue } return val } return nil }
func Fuzz(data []byte) int { stmt, err := sqlparser.Parse(string(data)) if err != nil { if stmt != nil { panic("stmt is not nil on error") } return 0 } if true { data1 := sqlparser.String(stmt) stmt1, err := sqlparser.Parse(data1) if err != nil { fmt.Printf("data0: %q\n", data) fmt.Printf("data1: %q\n", data1) panic(err) } if !fuzz.DeepEqual(stmt, stmt1) { fmt.Printf("data0: %q\n", data) fmt.Printf("data1: %q\n", data1) panic("not equal") } } else { sqlparser.String(stmt) } if sel, ok := stmt.(*sqlparser.Select); ok { var nodes []sqlparser.SQLNode for _, x := range sel.From { nodes = append(nodes, x) } for _, x := range sel.From { nodes = append(nodes, x) } for _, x := range sel.SelectExprs { nodes = append(nodes, x) } for _, x := range sel.GroupBy { nodes = append(nodes, x) } for _, x := range sel.OrderBy { nodes = append(nodes, x) } nodes = append(nodes, sel.Where) nodes = append(nodes, sel.Having) nodes = append(nodes, sel.Limit) for _, n := range nodes { if n == nil { continue } if x, ok := n.(sqlparser.SimpleTableExpr); ok { sqlparser.GetTableName(x) } if x, ok := n.(sqlparser.Expr); ok { sqlparser.GetColName(x) } if x, ok := n.(sqlparser.ValExpr); ok { sqlparser.IsValue(x) } if x, ok := n.(sqlparser.ValExpr); ok { sqlparser.IsColName(x) } if x, ok := n.(sqlparser.ValExpr); ok { sqlparser.IsSimpleTuple(x) } if x, ok := n.(sqlparser.ValExpr); ok { sqlparser.AsInterface(x) } if x, ok := n.(sqlparser.BoolExpr); ok { sqlparser.HasINClause([]sqlparser.BoolExpr{x}) } } } buf := sqlparser.NewTrackedBuffer(nil) stmt.Format(buf) pq := buf.ParsedQuery() vars := map[string]interface{}{ "A": 42, "B": 123123123, "C": "", "D": "a", "E": "foobar", "F": 1.1, } pq.GenerateQuery(vars) return 1 }