query.go 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626
  1. package core
  2. import (
  3. "TsDB2/DB/core/index"
  4. "TsDB2/DB/core/page"
  5. "TsDB2/DB/core/types"
  6. "bytes"
  7. "encoding/binary"
  8. "sort"
  9. )
  10. // Query 查询操作对象
  11. type Query struct {
  12. table *Table
  13. selectCols []string // SELECT 字段列表
  14. whereCond Condition // WHERE 条件
  15. orderBys []SortField // ORDER BY
  16. limit int // LIMIT
  17. offset int // OFFSET
  18. groupBys []string // GROUP BY
  19. havingCond Condition // HAVING
  20. }
  21. type SortField struct {
  22. Field string
  23. Descending bool
  24. }
  25. // scanPlan 索引扫描计划
  26. type scanPlan struct {
  27. meta *IndexMeta
  28. handler index.IndexHandler
  29. startKey []byte
  30. endKey []byte
  31. startInclusive bool
  32. endInclusive bool
  33. isPrimary bool // 主键/时序索引=true
  34. remainingCond Condition // 需要行级过滤的剩余条件
  35. }
  36. // Query 返回查询操作对象
  37. func (table *Table) Query() *Query {
  38. return &Query{table: table}
  39. }
  40. func (q *Query) Select(cols ...string) *Query { q.selectCols = cols; return q }
  41. func (q *Query) Where(cond Condition) *Query { q.whereCond = cond; return q }
  42. func (q *Query) Limit(n int) *Query { q.limit = n; return q }
  43. func (q *Query) Offset(n int) *Query { q.offset = n; return q }
  44. func (q *Query) GroupBy(cols ...string) *Query { q.groupBys = cols; return q }
  45. func (q *Query) Having(cond Condition) *Query { q.havingCond = cond; return q }
  46. func (q *Query) OrderBy(field string, descending ...bool) *Query {
  47. desc := false
  48. if len(descending) > 0 {
  49. desc = descending[0]
  50. }
  51. q.orderBys = append(q.orderBys, SortField{Field: field, Descending: desc})
  52. return q
  53. }
  54. // ======================== 索引键编码 ========================
  55. // encodeIndexKey 将条件值编码为索引键字节 (BigEndian, 与 writeFieldValue 一致)
  56. func encodeIndexKey(value interface{}, ft types.FieldType) []byte {
  57. size := types.GetSize(ft)
  58. buf := make([]byte, size)
  59. switch ft {
  60. case types.FieldType_1byte:
  61. buf[0] = value.(byte)
  62. case types.FieldType_2byte:
  63. binary.BigEndian.PutUint16(buf, uint16(value.(int16)))
  64. case types.FieldType_4byte:
  65. binary.BigEndian.PutUint32(buf, uint32(value.(int32)))
  66. case types.FieldType_8byte:
  67. binary.BigEndian.PutUint64(buf, value.(uint64))
  68. default:
  69. // 字符串类型
  70. b := value.([]byte)
  71. copy(buf, b)
  72. }
  73. return buf
  74. }
  75. // ======================== 索引匹配 ========================
  76. // fieldNameFromMeta 获取索引第一个字段的名称
  77. func (q *Query) fieldNameFromMeta(meta *IndexMeta) string {
  78. fieldIdx := int(meta.FieldIDs[0])
  79. if fieldIdx < len(q.table.Field) {
  80. return string(q.table.Field[fieldIdx].FieldName)
  81. }
  82. return ""
  83. }
  84. // fieldTypeFromMeta 获取索引第一个字段的类型
  85. func (q *Query) fieldTypeFromMeta(meta *IndexMeta) types.FieldType {
  86. fieldIdx := int(meta.FieldIDs[0])
  87. if fieldIdx < len(q.table.Field) {
  88. return q.table.Field[fieldIdx].FieldType
  89. }
  90. return 0
  91. }
  92. // condToRange 尝试从条件中提取扫描范围, 返回 (startKey, endKey, startInc, endInc, ok)
  93. func (q *Query) condToRange(cond Condition, fieldName string, ft types.FieldType) ([]byte, []byte, bool, bool, Condition) {
  94. switch c := cond.(type) {
  95. case EqCondition:
  96. if c.Field == fieldName {
  97. key := encodeIndexKey(c.Value, ft)
  98. return key, key, true, true, nil
  99. }
  100. case GeCondition:
  101. if c.Field == fieldName {
  102. return encodeIndexKey(c.Value, ft), nil, true, false, nil
  103. }
  104. case GtCondition:
  105. if c.Field == fieldName {
  106. return encodeIndexKey(c.Value, ft), nil, false, false, nil
  107. }
  108. case LeCondition:
  109. if c.Field == fieldName {
  110. return nil, encodeIndexKey(c.Value, ft), false, true, nil
  111. }
  112. case LtCondition:
  113. if c.Field == fieldName {
  114. return nil, encodeIndexKey(c.Value, ft), false, false, nil
  115. }
  116. case AndCondition:
  117. // 合并所有子条件的范围
  118. var sk, ek []byte
  119. var si, ei bool = true, true // 默认全包含
  120. var hasStart, hasEnd bool
  121. var remaining []Condition
  122. for _, sub := range c.Conditions {
  123. s, e, sinc, einc, rem2 := q.condToRange(sub, fieldName, ft)
  124. if rem2 == nil && (s != nil || e != nil) {
  125. // 此子条件可完全用于索引
  126. if s != nil {
  127. if !hasStart || (sinc && bytes.Compare(s, sk) > 0) || (!sinc && bytes.Compare(s, sk) >= 0) {
  128. sk = s
  129. si = sinc
  130. hasStart = true
  131. }
  132. }
  133. if e != nil {
  134. if !hasEnd || (einc && bytes.Compare(e, ek) < 0) || (!einc && bytes.Compare(e, ek) <= 0) {
  135. ek = e
  136. ei = einc
  137. hasEnd = true
  138. }
  139. }
  140. } else if s != nil || e != nil {
  141. // 此子条件部分可用于索引
  142. if s != nil {
  143. if !hasStart || (sinc && bytes.Compare(s, sk) > 0) || (!sinc && bytes.Compare(s, sk) >= 0) {
  144. sk = s
  145. si = sinc
  146. hasStart = true
  147. }
  148. }
  149. if e != nil {
  150. if !hasEnd || (einc && bytes.Compare(e, ek) < 0) || (!einc && bytes.Compare(e, ek) <= 0) {
  151. ek = e
  152. ei = einc
  153. hasEnd = true
  154. }
  155. }
  156. if rem2 != nil {
  157. remaining = append(remaining, rem2)
  158. }
  159. } else {
  160. // 此子条件不能用于索引
  161. remaining = append(remaining, sub)
  162. }
  163. }
  164. if hasStart || hasEnd {
  165. var rem Condition
  166. if len(remaining) == 1 {
  167. rem = remaining[0]
  168. } else if len(remaining) > 1 {
  169. rem = And(remaining...)
  170. }
  171. return sk, ek, si, ei, rem
  172. }
  173. }
  174. return nil, nil, false, false, cond
  175. }
  176. // buildScanPlan 分析 WHERE 条件, 选择最优索引
  177. func (q *Query) buildScanPlan() *scanPlan {
  178. if q.whereCond == nil {
  179. return nil
  180. }
  181. if q.table.indexMeta == nil {
  182. return nil
  183. }
  184. var bestPlan *scanPlan
  185. for i := range q.table.indexMeta.metas {
  186. m := &q.table.indexMeta.metas[i]
  187. if m.Flag&0x80 != 0 {
  188. continue
  189. }
  190. isPrimary := m.IndexType == page.IndexTypePrimary || m.IndexType == page.IndexTypeTime
  191. fieldName := q.fieldNameFromMeta(m)
  192. ft := q.fieldTypeFromMeta(m)
  193. if fieldName == "" {
  194. continue
  195. }
  196. sk, ek, si, ei, rem := q.condToRange(q.whereCond, fieldName, ft)
  197. if sk == nil && ek == nil {
  198. continue // 此索引不匹配
  199. }
  200. handler, ok := index.Compose.GetHandler(m.IndexType)
  201. if !ok {
  202. continue
  203. }
  204. plan := &scanPlan{
  205. meta: m, handler: handler,
  206. startKey: sk, endKey: ek,
  207. startInclusive: si, endInclusive: ei,
  208. isPrimary: isPrimary, remainingCond: rem,
  209. }
  210. // 优先选主键/时序索引 (避免回查)
  211. if isPrimary || bestPlan == nil {
  212. bestPlan = plan
  213. }
  214. if isPrimary {
  215. break // 主键索引最优, 不再找
  216. }
  217. }
  218. return bestPlan
  219. }
  220. // ======================== 核心查询 ========================
  221. // Find 执行查询,返回多行
  222. func (q *Query) Find() ([][]types.FieldValue, error) {
  223. var results [][]types.FieldValue
  224. err := q.scan(func(row []types.FieldValue) bool {
  225. results = append(results, row)
  226. return true
  227. })
  228. if err != nil {
  229. return nil, err
  230. }
  231. // 投影
  232. if len(q.selectCols) > 0 {
  233. results = q.project(results)
  234. }
  235. return results, nil
  236. }
  237. // Scan 流式扫描查询, 回调函数逐行处理数据, 返回 false 提前终止
  238. // 适用于不需要全量收集结果的场景, 内存友好
  239. func (q *Query) Scan(callback func(row []types.FieldValue) bool) error {
  240. return q.scan(callback)
  241. }
  242. // scan 内部流式扫描核心方法
  243. // 自动处理: 索引选择 → 排序 → OFFSET → LIMIT → 回调
  244. func (q *Query) scan(callback func(row []types.FieldValue) bool) error {
  245. plan := q.buildScanPlan()
  246. // 判断是否需要内存排序 (OrderBy 字段与索引不一致时)
  247. needSort := false
  248. if len(q.orderBys) > 0 {
  249. if plan == nil {
  250. needSort = true
  251. } else {
  252. idxField := q.fieldNameFromMeta(plan.meta)
  253. if !(len(q.orderBys) == 1 && q.orderBys[0].Field == idxField) {
  254. needSort = true
  255. }
  256. }
  257. }
  258. // 需要排序时, 必须先收集全部再排序, 无法流式 LIMIT
  259. if needSort {
  260. var all [][]types.FieldValue
  261. err := q.executeScan(func(row []types.FieldValue) bool {
  262. all = append(all, row)
  263. return true
  264. }, plan)
  265. if err != nil {
  266. return err
  267. }
  268. q.sortResults(all)
  269. // OFFSET
  270. if q.offset > 0 {
  271. if q.offset >= len(all) {
  272. return nil
  273. }
  274. all = all[q.offset:]
  275. }
  276. // LIMIT
  277. if q.limit > 0 && q.limit < len(all) {
  278. all = all[:q.limit]
  279. }
  280. for _, row := range all {
  281. if !callback(row) {
  282. return nil
  283. }
  284. }
  285. return nil
  286. }
  287. // 不需要排序: 直接流式传递 callback, 支持 LIMIT 提前终止
  288. seen := 0
  289. return q.executeScan(func(row []types.FieldValue) bool {
  290. if seen < q.offset {
  291. seen++
  292. return true // 跳过 OFFSET
  293. }
  294. seen++
  295. if !callback(row) {
  296. return false // 用户要求停止
  297. }
  298. // LIMIT 检查 (0 表示无限制)
  299. if q.limit > 0 && seen-q.offset >= q.limit {
  300. return false // 已满足, 提前终止扫描
  301. }
  302. return true
  303. }, plan)
  304. }
  305. // executeScan 执行索引扫描或全表扫描, 将反序列化后的行传递给回调
  306. func (q *Query) executeScan(callback func(row []types.FieldValue) bool, plan *scanPlan) error {
  307. if plan != nil {
  308. return q.indexScan(plan, callback)
  309. }
  310. return q.fullTableScan(callback)
  311. }
  312. // indexScan 使用索引扫描 (流式回调模式)
  313. func (q *Query) indexScan(plan *scanPlan, callback func(row []types.FieldValue) bool) error {
  314. // 判断 OrderBy 是否需要反向
  315. reverse := false
  316. if len(q.orderBys) == 1 {
  317. idxField := q.fieldNameFromMeta(plan.meta)
  318. if q.orderBys[0].Field == idxField && q.orderBys[0].Descending {
  319. reverse = true
  320. }
  321. }
  322. if plan.isPrimary {
  323. // 主键/时序索引: RangeScan 直接返回 storeRow = [pkID(8B) + rowData]
  324. return plan.handler.RangeScan(q.table.handle, plan.meta.EntryPage,
  325. plan.startKey, plan.endKey, plan.startInclusive, plan.endInclusive, reverse,
  326. func(row []byte) bool {
  327. if len(row) < 8 {
  328. return true
  329. }
  330. rowData := row[8:]
  331. if plan.remainingCond != nil {
  332. if !plan.remainingCond.Match(rowData, q.table) {
  333. return true
  334. }
  335. }
  336. return callback(q.table.deserializeRow(rowData))
  337. })
  338. }
  339. // 二级索引: RangeScan 返回 pkID(8B BE), 需回查主键
  340. return plan.handler.RangeScan(q.table.handle, plan.meta.EntryPage,
  341. plan.startKey, plan.endKey, plan.startInclusive, plan.endInclusive, reverse,
  342. func(row []byte) bool {
  343. if len(row) < 8 {
  344. return true
  345. }
  346. pkID := binary.BigEndian.Uint64(row[:8])
  347. storeRow, found := q.table.indexMeta.ResolveByPK(pkID, q.table.Field)
  348. if !found {
  349. return true
  350. }
  351. rowData := storeRow[8:]
  352. if plan.remainingCond != nil {
  353. if !plan.remainingCond.Match(rowData, q.table) {
  354. return true
  355. }
  356. }
  357. return callback(q.table.deserializeRow(rowData))
  358. })
  359. }
  360. // fullTableScan 全表扫描 (流式回调模式)
  361. func (q *Query) fullTableScan(callback func(row []types.FieldValue) bool) error {
  362. // 找主键/时序索引
  363. var primMeta *IndexMeta
  364. var primHandler index.IndexHandler
  365. for i := range q.table.indexMeta.metas {
  366. m := &q.table.indexMeta.metas[i]
  367. if m.Flag&0x80 != 0 {
  368. continue
  369. }
  370. if m.IndexType == page.IndexTypePrimary || m.IndexType == page.IndexTypeTime {
  371. primMeta = m
  372. primHandler, _ = index.Compose.GetHandler(m.IndexType)
  373. break
  374. }
  375. }
  376. if primMeta == nil || primHandler == nil {
  377. return nil
  378. }
  379. dpIDs := primHandler.GetDataPageIDs(q.table.handle, primMeta.EntryPage)
  380. for _, dpID := range dpIDs {
  381. rows := primHandler.ReadDataPageRows(q.table.handle, dpID)
  382. for _, storeRow := range rows {
  383. if len(storeRow) < 8 {
  384. continue
  385. }
  386. rowData := storeRow[8:]
  387. if q.whereCond != nil {
  388. if !q.whereCond.Match(rowData, q.table) {
  389. continue
  390. }
  391. }
  392. if !callback(q.table.deserializeRow(rowData)) {
  393. return nil // 回调要求提前终止
  394. }
  395. }
  396. }
  397. return nil
  398. }
  399. // ======================== 排序 ========================
  400. func (q *Query) sortResults(results [][]types.FieldValue) {
  401. sort.SliceStable(results, func(i, j int) bool {
  402. for _, ob := range q.orderBys {
  403. fi := q.table.findFieldIndex(ob.Field)
  404. if fi < 0 {
  405. continue
  406. }
  407. vi := findFieldValue(results[i], ob.Field)
  408. vj := findFieldValue(results[j], ob.Field)
  409. if vi == nil || vj == nil {
  410. continue
  411. }
  412. cmp := compareFieldValues(vi, vj)
  413. if cmp == 0 {
  414. continue
  415. }
  416. if ob.Descending {
  417. return cmp > 0
  418. }
  419. return cmp < 0
  420. }
  421. return false
  422. })
  423. }
  424. func findFieldValue(row []types.FieldValue, field string) interface{} {
  425. for _, fv := range row {
  426. if string(fv.FieldName) == field {
  427. return fv.Value
  428. }
  429. }
  430. return nil
  431. }
  432. func compareFieldValues(a, b interface{}) int {
  433. switch va := a.(type) {
  434. case uint64:
  435. vb := b.(uint64)
  436. if va < vb {
  437. return -1
  438. }
  439. if va > vb {
  440. return 1
  441. }
  442. return 0
  443. case int16:
  444. vb := a.(int16)
  445. vbb := b.(int16)
  446. if vb < vbb {
  447. return -1
  448. }
  449. if vb > vbb {
  450. return 1
  451. }
  452. return 0
  453. case int32:
  454. vb := b.(int32)
  455. if va < vb {
  456. return -1
  457. }
  458. if va > vb {
  459. return 1
  460. }
  461. return 0
  462. case byte:
  463. vb := b.(byte)
  464. if va < vb {
  465. return -1
  466. }
  467. if va > vb {
  468. return 1
  469. }
  470. return 0
  471. case []byte:
  472. vb := b.([]byte)
  473. return bytes.Compare(va, vb)
  474. }
  475. return 0
  476. }
  477. // ======================== 投影 ========================
  478. func (q *Query) project(results [][]types.FieldValue) [][]types.FieldValue {
  479. colSet := make(map[string]bool)
  480. for _, c := range q.selectCols {
  481. colSet[c] = true
  482. }
  483. for i, row := range results {
  484. var filtered []types.FieldValue
  485. for _, fv := range row {
  486. if colSet[string(fv.FieldName)] {
  487. filtered = append(filtered, fv)
  488. }
  489. }
  490. results[i] = filtered
  491. }
  492. return results
  493. }
  494. // ======================== 流式聚合 ========================
  495. // FindOne 流式查询,返回单行 (命中即停,不遍历全表)
  496. func (q *Query) FindOne() ([]types.FieldValue, error) {
  497. var result []types.FieldValue
  498. found := false
  499. err := q.scan(func(row []types.FieldValue) bool {
  500. result = row
  501. found = true
  502. return false // 找到第一行即停止
  503. })
  504. if err != nil {
  505. return nil, err
  506. }
  507. if !found {
  508. return nil, page.ErrNotFound
  509. }
  510. return result, nil
  511. }
  512. // Count 流式计数 (不收集行,扫描过程中直接累加)
  513. func (q *Query) Count() (int64, error) {
  514. var count int64
  515. err := q.scan(func(row []types.FieldValue) bool {
  516. count++
  517. return true
  518. })
  519. return count, err
  520. }
  521. // Sum 流式求和 (不收集行,扫描过程中直接累加)
  522. func (q *Query) Sum(col string) (float64, error) {
  523. var sum float64
  524. err := q.scan(func(row []types.FieldValue) bool {
  525. for _, fv := range row {
  526. if string(fv.FieldName) == col {
  527. sum += toFloat64(fv.Value)
  528. break
  529. }
  530. }
  531. return true
  532. })
  533. return sum, err
  534. }
  535. // Max 流式求最大值 (不收集行,扫描过程中维护当前最大值)
  536. func (q *Query) Max(col string) (interface{}, error) {
  537. var maxVal interface{}
  538. err := q.scan(func(row []types.FieldValue) bool {
  539. for _, fv := range row {
  540. if string(fv.FieldName) == col {
  541. if maxVal == nil || compareFieldValues(fv.Value, maxVal) > 0 {
  542. maxVal = fv.Value
  543. }
  544. break
  545. }
  546. }
  547. return true
  548. })
  549. return maxVal, err
  550. }
  551. // Min 流式求最小值 (不收集行,扫描过程中维护当前最小值)
  552. func (q *Query) Min(col string) (interface{}, error) {
  553. var minVal interface{}
  554. err := q.scan(func(row []types.FieldValue) bool {
  555. for _, fv := range row {
  556. if string(fv.FieldName) == col {
  557. if minVal == nil || compareFieldValues(fv.Value, minVal) < 0 {
  558. minVal = fv.Value
  559. }
  560. break
  561. }
  562. }
  563. return true
  564. })
  565. return minVal, err
  566. }
  567. func toFloat64(v interface{}) float64 {
  568. switch val := v.(type) {
  569. case uint64:
  570. return float64(val)
  571. case int16:
  572. return float64(val)
  573. case int32:
  574. return float64(val)
  575. case byte:
  576. return float64(val)
  577. }
  578. return 0
  579. }