Example #1
0
func (r *Router) buildInsertPlan(statement sqlparser.Statement) (*Plan, error) {
	plan := &Plan{}
	stmt := statement.(*sqlparser.Insert)
	if _, ok := stmt.Rows.(sqlparser.SelectStatement); ok {
		return nil, errors.ErrSelectInInsert
	}
	/*根据sql语句的表,获得对应的分片规则*/
	plan.Rule = r.GetRule(sqlparser.String(stmt.Table))

	if stmt.OnDup != nil {
		err := plan.Rule.checkUpdateExprs(sqlparser.UpdateExprs(stmt.OnDup))
		if err != nil {
			return nil, err
		}
	}

	plan.Criteria = plan.checkValuesType(stmt.Rows.(sqlparser.Values))
	plan.TableIndexs = makeList(0, len(plan.Rule.TableToNode))

	err := plan.calRouteIndexs()
	if err != nil {
		golog.Error("Route", "BuildInsertPlan", err.Error(), 0)
		return nil, err
	}

	err = r.generateInsertSql(plan, stmt)
	if err != nil {
		return nil, err
	}
	return plan, nil
}
Example #2
0
/*生成一个route plan*/
func (r *Router) GetPlan(statement sqlparser.Statement) (plan *Plan) {
	plan = &Plan{}
	var where *sqlparser.Where
	//因为实现Statement接口的方法都是指针类型,所以type对应类型也是指针类型
	switch stmt := statement.(type) {
	case *sqlparser.Insert:
		if _, ok := stmt.Rows.(sqlparser.SelectStatement); ok {
			panic(sqlparser.NewParserError("select in insert not allowed"))
		}
		/*根据sql语句的表,获得对应的分片规则*/
		plan.rule = r.GetRule(sqlparser.String(stmt.Table))

		if stmt.OnDup != nil {
			plan.rule.checkUpdateExprs(sqlparser.UpdateExprs(stmt.OnDup))
		}

		plan.criteria = plan.routingAnalyzeValues(stmt.Rows.(sqlparser.Values))
		plan.fullList = makeList(0, len(plan.rule.Nodes))
		return plan
	case *sqlparser.Replace:
		if _, ok := stmt.Rows.(sqlparser.SelectStatement); ok {
			panic(sqlparser.NewParserError("select in replace not allowed"))
		}

		plan.rule = r.GetRule(sqlparser.String(stmt.Table))
		plan.criteria = plan.routingAnalyzeValues(stmt.Rows.(sqlparser.Values))
		plan.fullList = makeList(0, len(plan.rule.Nodes))
		return plan

	case *sqlparser.Select:
		plan.rule = r.GetRule(sqlparser.String(stmt.From[0])) //根据表名获得分表规则
		where = stmt.Where
	case *sqlparser.Update:
		plan.rule = r.GetRule(sqlparser.String(stmt.Table))

		plan.rule.checkUpdateExprs(stmt.Exprs)

		where = stmt.Where
	case *sqlparser.Delete:
		plan.rule = r.GetRule(sqlparser.String(stmt.Table))
		where = stmt.Where
	}

	if where != nil {
		plan.criteria = where.Expr /*路由条件*/
	} else {
		plan.rule = r.DefaultRule
	}
	plan.fullList = makeList(0, len(plan.rule.Nodes))

	return plan
}
Example #3
0
func (r *Router) buildInsertPlan(db string, statement sqlparser.Statement) (*Plan, error) {
	plan := &Plan{}
	plan.Rows = make(map[int]sqlparser.Values)
	stmt := statement.(*sqlparser.Insert)
	if _, ok := stmt.Rows.(sqlparser.SelectStatement); ok {
		return nil, errors.ErrSelectInInsert
	}

	if stmt.Columns == nil {
		return nil, errors.ErrIRNoColumns
	}

	//根据sql语句的表,获得对应的分片规则
	plan.Rule = r.GetRule(db, sqlparser.String(stmt.Table))

	err := plan.GetIRKeyIndex(stmt.Columns)
	if err != nil {
		return nil, err
	}

	if stmt.OnDup != nil {
		err := plan.Rule.checkUpdateExprs(sqlparser.UpdateExprs(stmt.OnDup))
		if err != nil {
			return nil, err
		}
	}

	plan.Criteria = plan.checkValuesType(stmt.Rows.(sqlparser.Values))

	err = plan.calRouteIndexs()
	if err != nil {
		golog.Error("Route", "BuildInsertPlan", err.Error(), 0)
		return nil, err
	}

	err = r.generateInsertSql(plan, stmt)
	if err != nil {
		return nil, err
	}
	return plan, nil
}