func (r *Router) generateUpdateSql(plan *Plan, stmt sqlparser.Statement) error { sqls := make(map[string][]string) node, ok := stmt.(*sqlparser.Update) if ok == false { return errors.ErrStmtConvert } if len(plan.RouteNodeIndexs) == 0 { return errors.ErrNoRouteNode } if len(plan.RouteTableIndexs) == 0 { buf := sqlparser.NewTrackedBuffer(nil) stmt.Format(buf) nodeName := r.Nodes[0] sqls[nodeName] = []string{buf.String()} } else { nodeCount := len(plan.RouteNodeIndexs) if 1 < nodeCount { golog.Error("Router", "generateUpdateSql", errors.ErrUpdateInMulti.Error(), 0, "RouteNodeIndexs", plan.RouteNodeIndexs) return errors.ErrUpdateInMulti } tableCount := len(plan.RouteTableIndexs) for i := 0; i < tableCount; i++ { buf := sqlparser.NewTrackedBuffer(nil) buf.Fprintf("update %v%v", node.Comments, node.Table, ) fmt.Fprintf(buf, "_%04d", plan.RouteTableIndexs[i]) buf.Fprintf(" set %v%v%v%v", node.Exprs, node.Where, node.OrderBy, node.Limit, ) tableIndex := plan.RouteTableIndexs[i] nodeIndex := plan.Rule.TableToNode[tableIndex] nodeName := r.Nodes[nodeIndex] if _, ok := sqls[nodeName]; ok == false { sqls[nodeName] = make([]string, 0, tableCount) } sqls[nodeName] = append(sqls[nodeName], buf.String()) } } plan.RewrittenSqls = sqls return nil }
func (r *Router) generateSelectSql(plan *Plan, stmt sqlparser.Statement) error { sqls := make(map[string][]string) node, ok := stmt.(*sqlparser.Select) if ok == false { return ErrStmtConvert } if len(plan.RouteNodeIndexs) == 0 { return ErrNoRouteNode } if len(plan.RouteTableIndexs) == 0 { buf := sqlparser.NewTrackedBuffer(nil) stmt.Format(buf) nodeName := r.Nodes[0] sqls[nodeName] = []string{buf.String()} } else { tableCount := len(plan.RouteTableIndexs) for i := 0; i < tableCount; i++ { buf := sqlparser.NewTrackedBuffer(nil) buf.Fprintf("select %v%s%v from %v", node.Comments, node.Distinct, node.SelectExprs, node.From, ) fmt.Fprintf(buf, "_%04d", plan.RouteTableIndexs[i]) buf.Fprintf("%v%v%v%v%v%s", node.Where, node.GroupBy, node.Having, node.OrderBy, node.Limit, node.Lock, ) tableIndex := plan.RouteTableIndexs[i] nodeIndex := plan.Rule.TableToNode[tableIndex] nodeName := r.Nodes[nodeIndex] if _, ok := sqls[nodeName]; ok == false { sqls[nodeName] = make([]string, 0, tableCount) } sqls[nodeName] = append(sqls[nodeName], buf.String()) } } plan.RewrittenSqls = sqls return nil }
func (r *Router) generateSelectSql(plan *Plan, stmt sqlparser.Statement) error { sqls := make(map[string][]string) node, ok := stmt.(*sqlparser.Select) if ok == false { return errors.ErrStmtConvert } if len(plan.RouteNodeIndexs) == 0 { return errors.ErrNoRouteNode } if len(plan.RouteTableIndexs) == 0 { buf := sqlparser.NewTrackedBuffer(nil) stmt.Format(buf) nodeName := r.Nodes[0] sqls[nodeName] = []string{buf.String()} } else { tableCount := len(plan.RouteTableIndexs) for i := 0; i < tableCount; i++ { tableIndex := plan.RouteTableIndexs[i] nodeIndex := plan.Rule.TableToNode[tableIndex] nodeName := r.Nodes[nodeIndex] selectSql := r.rewriteSelectSql(plan, node, tableIndex) if _, ok := sqls[nodeName]; ok == false { sqls[nodeName] = make([]string, 0, tableCount) } sqls[nodeName] = append(sqls[nodeName], selectSql) } } plan.RewrittenSqls = sqls return nil }
func (r *Router) generateInsertSql(plan *Plan, stmt sqlparser.Statement) error { sqls := make(map[string][]string) node, ok := stmt.(*sqlparser.Insert) if ok == false { return errors.ErrStmtConvert } if len(plan.RouteNodeIndexs) == 0 { return errors.ErrNoRouteNode } if len(plan.RouteTableIndexs) == 0 { buf := sqlparser.NewTrackedBuffer(nil) stmt.Format(buf) nodeName := r.Nodes[0] sqls[nodeName] = []string{buf.String()} } else { tableCount := len(plan.RouteTableIndexs) for i := 0; i < tableCount; i++ { buf := sqlparser.NewTrackedBuffer(nil) tableIndex := plan.RouteTableIndexs[i] nodeIndex := plan.Rule.TableToNode[tableIndex] nodeName := r.Nodes[nodeIndex] buf.Fprintf("insert %vinto ", node.Comments) table := sqlparser.String(node.Table) if table[len(table)-1] == '`' { fmt.Fprintf(buf, "%s_%04d`", table[:len(table)-1], plan.RouteTableIndexs[i]) } else { fmt.Fprintf(buf, "%s_%04d", table, plan.RouteTableIndexs[i]) } buf.Fprintf("%v %v%v", node.Columns, plan.Rows[tableIndex], node.OnDup) if _, ok := sqls[nodeName]; ok == false { sqls[nodeName] = make([]string, 0, tableCount) } sqls[nodeName] = append(sqls[nodeName], buf.String()) } } plan.RewrittenSqls = sqls return nil }
func (r *Router) generateInsertSql(plan *Plan, stmt sqlparser.Statement) error { sqls := make(map[string][]string) node, ok := stmt.(*sqlparser.Insert) if ok == false { return ErrStmtConvert } if len(plan.RouteNodeIndexs) == 0 { return ErrNoRouteNode } if len(plan.RouteTableIndexs) == 0 { buf := sqlparser.NewTrackedBuffer(nil) stmt.Format(buf) nodeName := r.Nodes[0] sqls[nodeName] = []string{buf.String()} } else { nodeCount := len(plan.RouteNodeIndexs) if 1 < nodeCount { golog.Error("Router", "generateInsertSql", ErrInsertInMulti.Error(), 0) return ErrInsertInMulti } tableCount := len(plan.RouteTableIndexs) for i := 0; i < tableCount; i++ { buf := sqlparser.NewTrackedBuffer(nil) buf.Fprintf("insert %vinto %v", node.Comments, node.Table) fmt.Fprintf(buf, "_%04d", plan.RouteTableIndexs[i]) buf.Fprintf("%v %v%v", node.Columns, node.Rows, node.OnDup) tableIndex := plan.RouteTableIndexs[i] nodeIndex := plan.Rule.TableToNode[tableIndex] nodeName := r.Nodes[nodeIndex] if _, ok := sqls[nodeName]; ok == false { sqls[nodeName] = make([]string, 0, tableCount) } sqls[nodeName] = append(sqls[nodeName], buf.String()) } } plan.RewrittenSqls = sqls return nil }
//rewrite select sql func (r *Router) rewriteSelectSql(plan *Plan, node *sqlparser.Select, tableIndex int) string { buf := sqlparser.NewTrackedBuffer(nil) buf.Fprintf("select %v%s", node.Comments, node.Distinct, ) var prefix string //rewrite select expr for _, expr := range node.SelectExprs { switch v := expr.(type) { case *sqlparser.StarExpr: //for shardTable.*,need replace table into shardTable_xxxx. if string(v.TableName) == plan.Rule.Table { fmt.Fprintf(buf, "%s%s_%04d.*", prefix, plan.Rule.Table, tableIndex, ) } else { buf.Fprintf("%s%v", prefix, expr) } case *sqlparser.NonStarExpr: //rewrite shardTable.column as a //into shardTable_xxxx.column as a if colName, ok := v.Expr.(*sqlparser.ColName); ok { if string(colName.Qualifier) == plan.Rule.Table { fmt.Fprintf(buf, "%s%s_%04d.%s", prefix, plan.Rule.Table, tableIndex, string(colName.Name), ) } else { buf.Fprintf("%s%v", prefix, colName) } //if expr has as if v.As != nil { buf.Fprintf(" as %s", v.As) } } else { buf.Fprintf("%s%v", prefix, expr) } default: buf.Fprintf("%s%v", prefix, expr) } prefix = ", " } //insert the group columns in the first of select cloumns if len(node.GroupBy) != 0 { prefix = "," for _, n := range node.GroupBy { buf.Fprintf("%s%v", prefix, n) } } buf.Fprintf(" from ") switch v := (node.From[0]).(type) { case *sqlparser.AliasedTableExpr: if len(v.As) != 0 { fmt.Fprintf(buf, "%s_%04d as %s", sqlparser.String(v.Expr), tableIndex, string(v.As), ) } else { fmt.Fprintf(buf, "%s_%04d", sqlparser.String(v.Expr), tableIndex, ) } case *sqlparser.JoinTableExpr: if ate, ok := (v.LeftExpr).(*sqlparser.AliasedTableExpr); ok { if len(ate.As) != 0 { fmt.Fprintf(buf, "%s_%04d as %s", sqlparser.String(ate.Expr), tableIndex, string(ate.As), ) } else { fmt.Fprintf(buf, "%s_%04d", sqlparser.String(ate.Expr), tableIndex, ) } } else { fmt.Fprintf(buf, "%s_%04d", sqlparser.String(v.LeftExpr), tableIndex, ) } buf.Fprintf(" %s %v", v.Join, v.RightExpr) if v.On != nil { buf.Fprintf(" on %v", v.On) } default: fmt.Fprintf(buf, "%s_%04d", sqlparser.String(node.From[0]), tableIndex, ) } //append other tables prefix = ", " for i := 1; i < len(node.From); i++ { buf.Fprintf("%s%v", prefix, node.From[i]) } newLimit, err := node.Limit.RewriteLimit() if err != nil { //do not change limit newLimit = node.Limit } //rewrite where oldright, err := plan.rewriteWhereIn(tableIndex) buf.Fprintf("%v%v%v%v%v%s", node.Where, node.GroupBy, node.Having, node.OrderBy, newLimit, node.Lock, ) //restore old right if oldright != nil { plan.InRightToReplace.Right = oldright } return buf.String() }
func (r *Router) generateSelectSql(plan *Plan, stmt sqlparser.Statement) error { sqls := make(map[string][]string) node, ok := stmt.(*sqlparser.Select) if ok == false { return errors.ErrStmtConvert } if len(plan.RouteNodeIndexs) == 0 { return errors.ErrNoRouteNode } if len(plan.RouteTableIndexs) == 0 { buf := sqlparser.NewTrackedBuffer(nil) stmt.Format(buf) nodeName := r.Nodes[0] sqls[nodeName] = []string{buf.String()} } else { tableCount := len(plan.RouteTableIndexs) for i := 0; i < tableCount; i++ { buf := sqlparser.NewTrackedBuffer(nil) buf.Fprintf("select %v%s%v from ", node.Comments, node.Distinct, node.SelectExprs, ) switch v := (node.From[0]).(type) { case *sqlparser.AliasedTableExpr: if len(v.As) != 0 { fmt.Fprintf(buf, "%s_%04d AS %s", sqlparser.String(v.Expr), plan.RouteTableIndexs[i], string(v.As), ) } else { fmt.Fprintf(buf, "%s_%04d", sqlparser.String(v.Expr), plan.RouteTableIndexs[i], ) } case *sqlparser.JoinTableExpr: if ate, ok := (v.LeftExpr).(*sqlparser.AliasedTableExpr); ok { if len(ate.As) != 0 { fmt.Fprintf(buf, "%s_%04d AS %s", sqlparser.String(ate.Expr), plan.RouteTableIndexs[i], string(ate.As), ) } else { fmt.Fprintf(buf, "%s_%04d", sqlparser.String(ate.Expr), plan.RouteTableIndexs[i], ) } } else { fmt.Fprintf(buf, "%s_%04d", sqlparser.String(v.LeftExpr), plan.RouteTableIndexs[i], ) } buf.Fprintf(" %s %v", v.Join, v.RightExpr) if v.On != nil { buf.Fprintf(" on %v", v.On) } default: fmt.Fprintf(buf, "%s_%04d", sqlparser.String(node.From[0]), plan.RouteTableIndexs[i], ) } buf.Fprintf("%v%v%v%v%s", node.Where, node.GroupBy, node.Having, node.OrderBy, node.Lock, ) tableIndex := plan.RouteTableIndexs[i] nodeIndex := plan.Rule.TableToNode[tableIndex] nodeName := r.Nodes[nodeIndex] if _, ok := sqls[nodeName]; ok == false { sqls[nodeName] = make([]string, 0, tableCount) } sqls[nodeName] = append(sqls[nodeName], buf.String()) } } plan.RewrittenSqls = sqls return nil }
//rewrite select sql func (r *Router) rewriteSelectSql(plan *Plan, node *sqlparser.Select, tableIndex int) string { buf := sqlparser.NewTrackedBuffer(nil) buf.Fprintf("select %v%s%v", node.Comments, node.Distinct, node.SelectExprs, ) //insert the group columns in the first of select cloumns if len(node.GroupBy) != 0 { prefix := "," for _, n := range node.GroupBy { buf.Fprintf("%s%v", prefix, n) } } buf.Fprintf(" from ") switch v := (node.From[0]).(type) { case *sqlparser.AliasedTableExpr: if len(v.As) != 0 { fmt.Fprintf(buf, "%s_%04d AS %s", sqlparser.String(v.Expr), tableIndex, string(v.As), ) } else { fmt.Fprintf(buf, "%s_%04d", sqlparser.String(v.Expr), tableIndex, ) } case *sqlparser.JoinTableExpr: if ate, ok := (v.LeftExpr).(*sqlparser.AliasedTableExpr); ok { if len(ate.As) != 0 { fmt.Fprintf(buf, "%s_%04d AS %s", sqlparser.String(ate.Expr), tableIndex, string(ate.As), ) } else { fmt.Fprintf(buf, "%s_%04d", sqlparser.String(ate.Expr), tableIndex, ) } } else { fmt.Fprintf(buf, "%s_%04d", sqlparser.String(v.LeftExpr), tableIndex, ) } buf.Fprintf(" %s %v", v.Join, v.RightExpr) if v.On != nil { buf.Fprintf(" on %v", v.On) } default: fmt.Fprintf(buf, "%s_%04d", sqlparser.String(node.From[0]), tableIndex, ) } buf.Fprintf("%v%v%v%v%s", node.Where, node.GroupBy, node.Having, node.OrderBy, node.Lock, ) return buf.String() }