func (session *Session) dispatch(data []byte) (err error) { cmd := data[0] data = data[1:] defer func() { flush_error := session.fc.Flush() if err == nil { err = flush_error } }() switch cmd { case mysql.ComQuery: err = session.comQuery(hack.String(data)) case mysql.ComPing: err = session.fc.WriteOK(nil) case mysql.ComInitDB: if err := session.useDB(hack.String(data)); err != nil { err = session.handleMySQLError(err) } else { err = session.fc.WriteOK(nil) } case mysql.ComFieldList: err = session.handleFieldList(data) case mysql.ComStmtPrepare: err = session.handleComStmtPrepare(hack.String(data)) case mysql.ComStmtExecute: err = session.handleComStmtExecute(data) case mysql.ComStmtClose: err = session.handleComStmtClose(data) case mysql.ComStmtSendLongData: err = session.handleComStmtSendLongData(data) case mysql.ComStmtReset: err = session.handleComStmtReset(data) default: msg := fmt.Sprintf("command %d not supported now", cmd) log.Warnf(msg) err = mysql.NewDefaultError(mysql.ER_UNKNOWN_ERROR, msg) } return }
func (c *Session) comQuery(sqlstmt string) error { stmt, err := parser.Parse(sqlstmt) if err != nil { log.Warningf(`parse sql "%s" error "%s"`, sqlstmt, err.Error()) return c.handleMySQLError( NewDefaultError(ER_SYNTAX_ERROR, err.Error())) } switch v := stmt.(type) { case parser.ISelect: return c.handleQuery(v, sqlstmt) case *parser.Insert, *parser.Update, *parser.Delete, *parser.Replace: return c.handleExec(stmt, sqlstmt, false) case *parser.Set: return c.handleSet(v, sqlstmt) case *parser.Begin, *parser.StartTrans: return c.handleBegin() case *parser.Commit: return c.handleCommit() case *parser.Rollback: return c.handleRollback() case parser.IShow: return c.handleShow(sqlstmt, v) case parser.IDDLStatement: return c.handleDDL(v, sqlstmt) case *parser.Do, *parser.Call, *parser.FlushTables: return c.handleExec(stmt, sqlstmt, false) case *parser.Use: if err := c.useDB(hack.String(stmt.(*parser.Use).DB)); err != nil { return c.handleMySQLError(err) } else { return c.fc.WriteOK(nil) } default: log.Warnf("statement %T[%s] not support now", stmt, sqlstmt) return nil } return nil }
func (c *Session) comQuery(sqlstmt string) error { //TODO accerlate the flow control module and the figerprint module // err := c.intercept(sqlstmt) // if err != nil { // return err // } // c.updatefp(sqlstmt) log.Infof("session %d: %s", c.sessionId, sqlstmt) stmt, err := parser.Parse(sqlstmt) if err != nil { log.Warningf(`parse sql "%s" error "%s"`, sqlstmt, err.Error()) return c.handleMySQLError( NewDefaultError(ER_SYNTAX_ERROR, err.Error())) } switch v := stmt.(type) { case parser.ISelect: return c.handleQuery(v, sqlstmt) case *parser.Insert, *parser.Update, *parser.Delete, *parser.Replace: return c.handleExec(stmt, sqlstmt, false) case *parser.Set: return c.handleSet(v, sqlstmt) case *parser.Begin, *parser.StartTrans: return c.handleBegin() case *parser.Commit: return c.handleCommit() case *parser.Rollback: // log.Debug(hack.String(stmt.(*parser.Rollback).Point)) if len(stmt.(*parser.Rollback).Point) > 0 { return c.handleExec(stmt, sqlstmt, false) } return c.handleRollback() case parser.IShow: return c.handleShow(sqlstmt, v) case parser.IDDLStatement: return c.handleDDL(v, sqlstmt) case *parser.Do, *parser.Call, *parser.FlushTables: return c.handleExec(stmt, sqlstmt, false) //add the describe table module case *parser.DescribeTable, *parser.DescribeStmt: return c.handleQuery(v, sqlstmt) case *parser.Use: if err := c.useDB(hack.String(stmt.(*parser.Use).DB)); err != nil { return c.handleMySQLError(err) } else { return c.fc.WriteOK(nil) } case *parser.SavePoint: return c.handleExec(stmt, sqlstmt, false) // return c.handleQuery(v, sqlstmt) case *parser.SetTrans: // log.Warnf("set tx iso level ") t_sl := hack.Slice(sqlstmt) tmp := make([]byte, len(t_sl)) copy(tmp, t_sl) // log.Debug(sqlstmt, t_sl, tmp, len(t_sl)) c.txIsolationInDef = false sql := hack.String(tmp) // log.Debug(sql, len(sql)) c.txIsolationStmt = sql // log.Warnf("set tx iso level finish ") if c.isInTransaction() { return c.handleExec(stmt, sqlstmt, false) } return c.fc.WriteOK(nil) default: log.Warnf("session %d : statement %T[%s] not support now", c.sessionId, stmt, sqlstmt) err := errors.New("statement not support now") return c.handleMySQLError( NewDefaultError(ER_SYNTAX_ERROR, err.Error())) } return nil }