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 }