func (session *Session) buildSimpleShowResultset(values []interface{}, name string) (mysql.Rows, error) { r := new(SimpleRows) r.Cols = []*mysql.MySQLField{ &mysql.MySQLField{ Name: hack.Slice(name), Charset: uint16(session.fc.Collation()), FieldType: mysql.FieldTypeVarString, }, } var row []byte var err error for _, value := range values { row, err = formatValue(value) if err != nil { return nil, err } r.Rows = append(r.Rows, mysql.AppendLengthEncodedString(make([]byte, 0, len(row)+9), row)) } return r, nil }
func formatValue(value interface{}) ([]byte, error) { switch v := value.(type) { case int8: return strconv.AppendInt(nil, int64(v), 10), nil case int16: return strconv.AppendInt(nil, int64(v), 10), nil case int32: return strconv.AppendInt(nil, int64(v), 10), nil case int64: return strconv.AppendInt(nil, int64(v), 10), nil case int: return strconv.AppendInt(nil, int64(v), 10), nil case uint8: return strconv.AppendUint(nil, uint64(v), 10), nil case uint16: return strconv.AppendUint(nil, uint64(v), 10), nil case uint32: return strconv.AppendUint(nil, uint64(v), 10), nil case uint64: return strconv.AppendUint(nil, uint64(v), 10), nil case uint: return strconv.AppendUint(nil, uint64(v), 10), nil case float32: return strconv.AppendFloat(nil, float64(v), 'f', -1, 64), nil case float64: return strconv.AppendFloat(nil, float64(v), 'f', -1, 64), nil case []byte: return v, nil case string: return hack.Slice(v), nil default: return nil, fmt.Errorf("invalid type %T", value) } }
func (session *Session) ServerName() []byte { return hack.Slice(version.Version) }
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 }