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 }
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 }
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 }