func (c *Conn) handleQuery(sqlstmt string) (err error) {
	/*defer func() {
		if e := recover(); e != nil {
			err = fmt.Errorf("execute %s error %v", sql, e)
			return
		}
	}()*/

	var stmt sql.IStatement
	stmt, err = sql.Parse(sqlstmt)
	if err != nil {
		return fmt.Errorf(`parse sql "%s" error "%s"`, sqlstmt, err.Error())
	}

	switch v := stmt.(type) {
	case sql.ISelect:
		return c.handleSelect(v, sqlstmt)
	case *sql.Insert:
		return c.handleExec(stmt, sqlstmt, false)
	case *sql.Update:
		return c.handleExec(stmt, sqlstmt, false)
	case *sql.Delete:
		return c.handleExec(stmt, sqlstmt, false)
	case *sql.Replace:
		return c.handleExec(stmt, sqlstmt, false)
	case *sql.Set:
		return c.handleSet(v, sqlstmt)
	case *sql.Begin:
		return c.handleBegin()
	case *sql.Commit:
		return c.handleCommit()
	case *sql.Rollback:
		return c.handleRollback()
	case sql.IShow:
		return c.handleShow(sqlstmt, v)
	case sql.IDDLStatement:
		return c.handleExec(stmt, sqlstmt, false)
	case *sql.Do:
		return c.handleExec(stmt, sqlstmt, false)
	case *sql.Call:
		return c.handleExec(stmt, sqlstmt, false)
	case *sql.Use:
		if err := c.useDB(hack.String(stmt.(*sql.Use).DB)); err != nil {
			return err
		} else {
			return c.writeOK(nil)
		}

	default:
		return fmt.Errorf("statement %T[%s] not support now", stmt, sqlstmt)
	}

	return nil
}
Beispiel #2
0
func (c *Conn) handleComStmtPrepare(sqlstmt string) error {
	if c.schema == nil {
		return NewDefaultError(ER_NO_DB_ERROR)
	}

	s := new(Stmt)

	var err error
	s.s, err = sql.Parse(sqlstmt)
	if err != nil {
		return fmt.Errorf(`prepare parse sql "%s" error`, sqlstmt)
	}

	s.sqlstmt = sqlstmt

	var co *client.SqlConn
	co, err = c.schema.node.getMasterConn()
	// TODO tablename for select
	if err != nil {
		return fmt.Errorf("prepare error %s", err)
	}

	if err = co.UseDB(c.schema.db); err != nil {
		co.Close()
		return fmt.Errorf("parepre error %s", err)
	}

	if t, err := co.Prepare(sqlstmt); err != nil {
		co.Close()
		return fmt.Errorf("parepre error %s", err)
	} else {
		s.params = t.ParamNum()
		s.types = make([]byte, 0, s.params*2)
		s.columns = t.ColumnNum()
		s.bid = t.ID()
		s.cstmt = t
	}

	s.id = c.stmtId
	c.stmtId++

	if err = c.writePrepare(s); err != nil {
		return err
	}

	s.ClearParams()

	c.stmts[s.id] = s

	return nil
}
Beispiel #3
0
func (c *Conn) handleQuery(sqlstmt string) (err error) {
	/*defer func() {
		if e := recover(); e != nil {
			err = fmt.Errorf("execute %s error %v", sql, e)
			return
		}
	}()*/

	var stmt sql.IStatement
	var excess int64

	fp := query.Fingerprint(sqlstmt)
	now := getTimestamp()

	c.server.mu.Lock()
	if lr, ok := c.server.fingerprints[fp]; ok {
		//how many microsecond elapsed since last query
		ms := now - lr.last
		//Default, we have 1 r/s
		excess = lr.excess - c.server.cfg.ReqRate*(ms/1000) + 1000

		//If we need caculate every second speed,
		//Should reset to zero;
		if excess < 0 {
			excess = 0
		}

		//the race out the max Burst?
		log.AppLog.Notice("the Query excess(%d), the reqBurst(%d)", excess, c.server.cfg.ReqBurst)
		if excess > c.server.cfg.ReqBurst {

			c.server.mu.Unlock()
			//Just close the client or
			return fmt.Errorf(`the query excess(%d) over the reqBurst(%d), sql: %s "`, excess, c.server.cfg.ReqBurst, sqlstmt)
			//TODO: more gracefully add a Timer and retry?
		}
		lr.excess = excess
		lr.last = now
		lr.count++

	} else {
		lr := &LimitReqNode{}
		lr.excess = 0
		lr.last = getTimestamp()
		lr.query = fp

		lr.count = 1
		c.server.fingerprints[fp] = lr
	}
	c.server.mu.Unlock()

	stmt, err = sql.Parse(sqlstmt)
	if err != nil {
		return fmt.Errorf(`parse sql "%s" error "%s"`, sqlstmt, err.Error())
	}

	switch v := stmt.(type) {
	case sql.ISelect:
		return c.handleSelect(v, sqlstmt)
	case *sql.Insert:
		return c.handleExec(stmt, sqlstmt, false)
	case *sql.Update:
		return c.handleExec(stmt, sqlstmt, false)
	case *sql.Delete:
		return c.handleExec(stmt, sqlstmt, false)
	case *sql.Replace:
		return c.handleExec(stmt, sqlstmt, false)
	case *sql.Set:
		return c.handleSet(v, sqlstmt)
	case *sql.Begin:
		return c.handleBegin()
	case *sql.Commit:
		return c.handleCommit()
	case *sql.Rollback:
		return c.handleRollback()
	case sql.IShow:
		return c.handleShow(sqlstmt, v)
	case sql.IDDLStatement:
		return c.handleExec(stmt, sqlstmt, false)
	case *sql.Do:
		return c.handleExec(stmt, sqlstmt, false)
	case *sql.Call:
		return c.handleExec(stmt, sqlstmt, false)
	case *sql.Use:
		if err := c.useDB(hack.String(stmt.(*sql.Use).DB)); err != nil {
			return err
		} else {
			return c.writeOK(nil)
		}

	default:
		return fmt.Errorf("statement %T[%s] not support now", stmt, sqlstmt)
	}

	return nil
}