Beispiel #1
0
// stripTrailing strips out trailing comments if any and puts them in a bind variable.
// This code is a hack. Will need cleaning if it evolves beyond this.
func stripTrailing(query *proto.Query) {
	tracker := matchtracker{query.Sql, len(query.Sql)}
	pos := tracker.matchComments()
	if pos >= 0 {
		query.Sql = tracker.query[:pos]
		query.BindVariables[TRAILING_COMMENT] = tracker.query[pos:]
	}
}
Beispiel #2
0
func (qe *QueryEngine) Execute(logStats *sqlQueryStats, query *proto.Query) (reply *eproto.QueryResult) {
	qe.mu.RLock()
	defer qe.mu.RUnlock()

	if query.BindVariables == nil { // will help us avoid repeated nil checks
		query.BindVariables = make(map[string]interface{})
	}
	logStats.BindVariables = query.BindVariables
	logStats.OriginalSql = query.Sql
	// cheap hack: strip trailing comment into a special bind var
	stripTrailing(query)
	basePlan := qe.schemaInfo.GetPlan(logStats, query.Sql)
	planName := basePlan.PlanId.String()
	logStats.PlanType = planName
	defer func(start time.Time) {
		duration := time.Now().Sub(start)
		queryStats.Add(planName, duration)
		if reply == nil {
			basePlan.AddStats(1, duration, 0, 1)
		} else {
			basePlan.AddStats(1, duration, int64(len(reply.Rows)), 0)
		}
	}(time.Now())

	/*	if basePlan.PlanId == sqlparser.PLAN_DDL {
		return qe.execDDL(logStats, query.Sql)
	}*/

	plan := &CompiledPlan{query.Sql, basePlan, query.BindVariables, query.TransactionId, query.ConnectionId}
	conn := qe.connPool.Get()
	defer conn.Recycle()
	switch plan.PlanId {
	case sqlparser.PLAN_INSERT_PK:
		reply = qe.execInsertPK(logStats, conn, plan)
	case sqlparser.PLAN_INSERT_SUBQUERY:
		reply = qe.execInsertSubquery(logStats, conn, plan)
	default:
		panic("Plan currently not supported")
	}
	return reply
}
Beispiel #3
0
func (qe *QueryEngine) Execute(logStats *sqlQueryStats, query *proto.Query) (reply *eproto.QueryResult) {
	qe.mu.RLock()
	defer qe.mu.RUnlock()

	if query.BindVariables == nil { // will help us avoid repeated nil checks
		query.BindVariables = make(map[string]interface{})
	}
	logStats.BindVariables = query.BindVariables
	logStats.OriginalSql = query.Sql
	// cheap hack: strip trailing comment into a special bind var
	stripTrailing(query)
	basePlan := qe.schemaInfo.GetPlan(logStats, query.Sql)
	planName := basePlan.PlanId.String()
	logStats.PlanType = planName
	defer func(start time.Time) {
		duration := time.Now().Sub(start)
		queryStats.Add(planName, duration)
		if reply == nil {
			basePlan.AddStats(1, duration, 0, 1)
		} else {
			basePlan.AddStats(1, duration, int64(len(reply.Rows)), 0)
		}
	}(time.Now())

	/*	if basePlan.PlanId == sqlparser.PLAN_DDL {
		return qe.execDDL(logStats, query.Sql)
	}*/
	plan := &CompiledPlan{query.Sql, basePlan, query.BindVariables, query.TransactionId, query.ConnectionId}
	log.Info("Plan type is %s, reason is %s", plan.PlanId, plan.Reason)
	if plan.Reason == sqlparser.REASON_ERR {
		panic(NewTabletError(FAIL, plan.Error.Error()))
	}
	if isDml(query.Sql) {
		conn := qe.connPool.Get()
		defer conn.Recycle()
		switch plan.PlanId {
		case sqlparser.PLAN_INSERT_PK:
			reply = qe.execInsertPK(logStats, conn, plan)
		case sqlparser.PLAN_UPDATE_ALL:
			reply = qe.execModifyAll(logStats, conn, plan, true)
		case sqlparser.PLAN_UPDATE_PK:
			reply = qe.execModifyPk(logStats, conn, plan, true)
		case sqlparser.PLAN_DELETE_ALL:
			reply = qe.execModifyAll(logStats, conn, plan, false)
		case sqlparser.PLAN_DELETE_PK:
			reply = qe.execModifyPk(logStats, conn, plan, false)

		default:
			panic(NewTabletError(FAIL, "sql currently not supported"))
		}
	} else {
		switch plan.PlanId {
		case sqlparser.PLAN_SELECT_ALL:
			reply = qe.selectAll(logStats, plan)
		case sqlparser.PLAN_PK_EQUAL:
			reply = qe.selectPkEqual(logStats, plan)
		case sqlparser.PLAN_PK_IN:
			reply = qe.selectPkIn(logStats, plan)
		default:
			panic(NewTabletError(FAIL, "sql currently not supported"))
		}
	}
	return reply
}