func (s *SelectPlan) HasOrderBy() bool {
	return len(s.orderByDirections) != 0
}
HasOrderBy if select statement has order by clause, return true
package plan
import (
	"fmt"
	"github.com/nooncall/shazam/mysql"
	"github.com/nooncall/shazam/parser/ast"
	"github.com/nooncall/shazam/parser/opcode"
	driver "github.com/nooncall/shazam/parser/tidb-types/parser_driver"
	"github.com/nooncall/shazam/proxy/router"
	"github.com/nooncall/shazam/util"
)
type SelectPlan struct {
	basePlan
	*TableAliasStmtInfo
	stmt *ast.SelectStmt
	distinct           bool  
	groupByColumnStart int
	groupByColumnCount int
	orderByColumnStart int     
	orderByDirections  []bool  
	originColumnCount  int     
	columnCount        int     
	aggregateFuncs map[int]AggregateFuncMerger  
	offset int64  
	count  int64  
	sqls map[string]map[string][]string
}
func NewSelectPlan(db string, sql string, r *router.Router) *SelectPlan {
	return &SelectPlan{
		TableAliasStmtInfo: NewTableAliasStmtInfo(db, sql, r),
		groupByColumnStart: 0,
		groupByColumnCount: 0,
		orderByColumnStart: 0,
		aggregateFuncs:     make(map[int]AggregateFuncMerger),
		offset:             -1,
		count:              -1,
	}
}
func (s *SelectPlan) ExecuteIn(reqCtx *util.RequestContext, sess Executor) (*mysql.Result, error) {
	sqls := s.GetSQLs()
	if sqls == nil {
		return nil, fmt.Errorf("SQL has not generated")
	}
	if len(sqls) == 0 {
		r := newEmptyResultset(s, s.GetStmt())
		ret := &mysql.Result{
			Resultset: r,
		}
		return ret, nil
	}
	rs, err := sess.ExecuteSQLs(reqCtx, sqls)
	if err != nil {
		return nil, fmt.Errorf("execute in SelectPlan error: %v", err)
	}
	r, err := MergeSelectResult(s, s.stmt, rs)
	if err != nil {
		return nil, fmt.Errorf("merge select result error: %v", err)
	}
	return r, nil
}
func (s *SelectPlan) GetStmt() *ast.SelectStmt {
	return s.stmt
}
func (s *SelectPlan) setAggregateFuncMerger(idx int, merger AggregateFuncMerger) error {
	if _, ok := s.aggregateFuncs[idx]; ok {
		return fmt.Errorf("column %d already set", idx)
	}
	s.aggregateFuncs[idx] = merger
	return nil
}
func (s *SelectPlan) HasLimit() bool {
	return s.count != -1
}
func (s *SelectPlan) GetLimitValue() (int64, int64) {
	return s.offset, s.count
}
func (s *SelectPlan) HasGroupBy() bool {
	return s.groupByColumnCount != 0
}
func (s *SelectPlan) GetOriginColumnCount() int {
	return s.originColumnCount
}
func (s *SelectPlan) GetColumnCount() int {
	return s.columnCount
}
func (s *SelectPlan) GetGroupByColumnInfo() (int, int) {
	return s.groupByColumnStart, s.groupByColumnCount
}