github.com/team-ide/go-dialect@v1.9.20/dialect/sql.go (about)

     1  package dialect
     2  
     3  import (
     4  	"errors"
     5  	"regexp"
     6  	"strings"
     7  )
     8  
     9  func FormatCountSql(selectSql string) (countSql string, err error) {
    10  	countSql = strings.TrimSpace(selectSql)
    11  	if countSql == "" {
    12  		return
    13  	}
    14  
    15  	//查询order by 的位置
    16  	//Query the position of order by
    17  	locOrderBy := findOrderByIndex(countSql)
    18  	//如果存在order by
    19  	//If there is order by
    20  	if len(locOrderBy) > 0 {
    21  		countSql = countSql[:locOrderBy[0]]
    22  	}
    23  	s := strings.ToLower(countSql)
    24  	gbi := -1
    25  	locGroupBy := findGroupByIndex(countSql)
    26  	if len(locGroupBy) > 0 {
    27  		gbi = locGroupBy[0]
    28  	}
    29  	var sqlBuilder strings.Builder
    30  	sqlBuilder.Grow(100)
    31  	//特殊关键字,包装SQL
    32  	//Special keywords, wrap SQL
    33  	if strings.Contains(s, " distinct ") || strings.Contains(s, " union ") || gbi > -1 {
    34  		sqlBuilder.WriteString("SELECT COUNT(*)  frame_row_count FROM (")
    35  		sqlBuilder.WriteString(countSql)
    36  		sqlBuilder.WriteString(") temp_frame_noob_table_name WHERE 1=1 ")
    37  	} else {
    38  		locFrom := findSelectFromIndex(countSql)
    39  		//没有找到FROM关键字,认为是异常语句
    40  		//The FROM keyword was not found, which is considered an abnormal statement
    41  		if len(locFrom) == 0 {
    42  			err = errors.New("->selectCount-->findFromIndex没有FROM关键字,语句错误")
    43  			return
    44  		}
    45  		sqlBuilder.WriteString("SELECT COUNT(*) ")
    46  		sqlBuilder.WriteString(countSql[locFrom[0]:])
    47  	}
    48  	countSql = sqlBuilder.String()
    49  	return
    50  }
    51  
    52  var orderByExpr = "(?i)\\s(order)\\s+by\\s"
    53  var orderByRegexp, _ = regexp.Compile(orderByExpr)
    54  
    55  func findOrderByIndex(selectSql string) []int {
    56  	loc := orderByRegexp.FindStringIndex(selectSql)
    57  	return loc
    58  }
    59  
    60  var groupByExpr = "(?i)\\s(group)\\s+by\\s"
    61  var groupByRegexp, _ = regexp.Compile(groupByExpr)
    62  
    63  func findGroupByIndex(selectSql string) []int {
    64  	loc := groupByRegexp.FindStringIndex(selectSql)
    65  	return loc
    66  }
    67  
    68  var fromExpr = "(?i)(^\\s*select)(\\(.*?\\)|[^()]+)*?(from)"
    69  var fromRegexp, _ = regexp.Compile(fromExpr)
    70  
    71  func findSelectFromIndex(selectSql string) []int {
    72  	//匹配出来的是完整的字符串,用最后的FROM即可
    73  	loc := fromRegexp.FindStringIndex(selectSql)
    74  	if len(loc) < 2 {
    75  		return loc
    76  	}
    77  	//最后的FROM前推4位字符串
    78  	loc[0] = loc[1] - 4
    79  	return loc
    80  }