diff --git a/kernel/model/search.go b/kernel/model/search.go index 4e72e182d..5c95b7d0b 100644 --- a/kernel/model/search.go +++ b/kernel/model/search.go @@ -35,6 +35,7 @@ import ( "github.com/88250/lute/ast" "github.com/88250/lute/lex" "github.com/88250/lute/parse" + "github.com/88250/vitess-sqlparser/sqlparser" "github.com/jinzhu/copier" "github.com/siyuan-note/filelock" "github.com/siyuan-note/logging" @@ -604,7 +605,7 @@ func buildTypeFilter(types map[string]bool) string { func searchBySQL(stmt string, beforeLen, page int) (ret []*Block, matchedBlockCount, matchedRootCount int) { stmt = gulu.Str.RemoveInvisible(stmt) stmt = strings.TrimSpace(stmt) - blocks := sql.SelectBlocksRawStmt(stmt, page, Conf.Search.Limit) + blocks := sql.SelectBlocksRawStmt(stmt, page, pageSize) ret = fromSQLBlocks(&blocks, "", beforeLen) if 1 > len(ret) { ret = []*Block{} @@ -617,6 +618,7 @@ func searchBySQL(stmt string, beforeLen, page int) (ret []*Block, matchedBlockCo } else { stmt = strings.ReplaceAll(stmt, "select * ", "select COUNT(id) AS `matches`, COUNT(DISTINCT(root_id)) AS `docs` ") } + stmt = removeLimitClause(stmt) result, _ := sql.Query(stmt) if 1 > len(ret) { return @@ -627,6 +629,23 @@ func searchBySQL(stmt string, beforeLen, page int) (ret []*Block, matchedBlockCo return } +func removeLimitClause(stmt string) string { + parsedStmt, err := sqlparser.Parse(stmt) + if nil != err { + return stmt + } + + switch parsedStmt.(type) { + case *sqlparser.Select: + slct := parsedStmt.(*sqlparser.Select) + if nil != slct.Limit { + slct.Limit = nil + } + stmt = sqlparser.String(slct) + } + return stmt +} + func fullTextSearchRefBlock(keyword string, beforeLen int, onlyDoc bool) (ret []*Block) { keyword = gulu.Str.RemoveInvisible(keyword) @@ -748,7 +767,7 @@ func fullTextSearchByFTS(query, boxFilter, pathFilter, typeFilter, orderBy strin stmt += boxFilter + pathFilter stmt += " " + orderBy stmt += " LIMIT " + strconv.Itoa(pageSize) + " OFFSET " + strconv.Itoa((page-1)*pageSize) - blocks := sql.SelectBlocksRawStmt(stmt, page, Conf.Search.Limit) + blocks := sql.SelectBlocksRawStmt(stmt, page, pageSize) ret = fromSQLBlocks(&blocks, "", beforeLen) if 1 > len(ret) { ret = []*Block{} diff --git a/kernel/sql/block_query.go b/kernel/sql/block_query.go index 11dda29a8..b1085e1e4 100644 --- a/kernel/sql/block_query.go +++ b/kernel/sql/block_query.go @@ -433,14 +433,25 @@ func SelectBlocksRawStmt(stmt string, page, limit int) (ret []*Block) { Val: []byte(strconv.Itoa(limit)), }, } + slct.Limit.Offset = &sqlparser.SQLVal{ + Type: sqlparser.IntVal, + Val: []byte(strconv.Itoa((page - 1) * limit)), + } } else { + if nil != slct.Limit.Rowcount && 0 < len(slct.Limit.Rowcount.(*sqlparser.SQLVal).Val) { + limit, _ = strconv.Atoi(string(slct.Limit.Rowcount.(*sqlparser.SQLVal).Val)) + if 0 >= limit { + limit = 32 + } + } + slct.Limit.Rowcount = &sqlparser.SQLVal{ Type: sqlparser.IntVal, Val: []byte(strconv.Itoa(limit)), } slct.Limit.Offset = &sqlparser.SQLVal{ Type: sqlparser.IntVal, - Val: []byte(strconv.Itoa((page - 1) * 32)), + Val: []byte(strconv.Itoa((page - 1) * limit)), } }