query.go 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597
  1. package DB
  2. import (
  3. "TsDB2/DB/index"
  4. "TsDB2/DB/page"
  5. "TsDB2/DB/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. // 找第一个可索引的子条件, 其余作为 remainingCond
  118. var used int = -1
  119. var sk, ek []byte
  120. var si, ei, found bool
  121. for i, sub := range c.Conditions {
  122. s, e, sinc, einc, rem2 := q.condToRange(sub, fieldName, ft)
  123. if rem2 == nil || (s != nil || e != nil) {
  124. sk, ek, si, ei = s, e, sinc, einc
  125. used = i
  126. found = true
  127. break
  128. }
  129. }
  130. if found {
  131. // 剩余条件 = 除 used 外的所有子条件
  132. var remaining []Condition
  133. for i, sub := range c.Conditions {
  134. if i != used {
  135. remaining = append(remaining, sub)
  136. }
  137. }
  138. var rem Condition
  139. if len(remaining) == 1 {
  140. rem = remaining[0]
  141. } else if len(remaining) > 1 {
  142. rem = And(remaining...)
  143. }
  144. return sk, ek, si, ei, rem
  145. }
  146. }
  147. return nil, nil, false, false, cond
  148. }
  149. // buildScanPlan 分析 WHERE 条件, 选择最优索引
  150. func (q *Query) buildScanPlan() *scanPlan {
  151. if q.whereCond == nil {
  152. return nil
  153. }
  154. if q.table.indexMeta == nil {
  155. return nil
  156. }
  157. var bestPlan *scanPlan
  158. for i := range q.table.indexMeta.metas {
  159. m := &q.table.indexMeta.metas[i]
  160. if m.Flag&0x80 != 0 {
  161. continue
  162. }
  163. isPrimary := m.IndexType == page.IndexTypePrimary || m.IndexType == page.IndexTypeTime
  164. fieldName := q.fieldNameFromMeta(m)
  165. ft := q.fieldTypeFromMeta(m)
  166. if fieldName == "" {
  167. continue
  168. }
  169. sk, ek, si, ei, rem := q.condToRange(q.whereCond, fieldName, ft)
  170. if sk == nil && ek == nil {
  171. continue // 此索引不匹配
  172. }
  173. handler, ok := index.Compose.GetHandler(m.IndexType)
  174. if !ok {
  175. continue
  176. }
  177. plan := &scanPlan{
  178. meta: m, handler: handler,
  179. startKey: sk, endKey: ek,
  180. startInclusive: si, endInclusive: ei,
  181. isPrimary: isPrimary, remainingCond: rem,
  182. }
  183. // 优先选主键/时序索引 (避免回查)
  184. if isPrimary || bestPlan == nil {
  185. bestPlan = plan
  186. }
  187. if isPrimary {
  188. break // 主键索引最优, 不再找
  189. }
  190. }
  191. return bestPlan
  192. }
  193. // ======================== 核心查询 ========================
  194. // Find 执行查询,返回多行
  195. func (q *Query) Find() ([][]types.FieldValue, error) {
  196. var results [][]types.FieldValue
  197. err := q.scan(func(row []types.FieldValue) bool {
  198. results = append(results, row)
  199. return true
  200. })
  201. if err != nil {
  202. return nil, err
  203. }
  204. // 投影
  205. if len(q.selectCols) > 0 {
  206. results = q.project(results)
  207. }
  208. return results, nil
  209. }
  210. // Scan 流式扫描查询, 回调函数逐行处理数据, 返回 false 提前终止
  211. // 适用于不需要全量收集结果的场景, 内存友好
  212. func (q *Query) Scan(callback func(row []types.FieldValue) bool) error {
  213. return q.scan(callback)
  214. }
  215. // scan 内部流式扫描核心方法
  216. // 自动处理: 索引选择 → 排序 → OFFSET → LIMIT → 回调
  217. func (q *Query) scan(callback func(row []types.FieldValue) bool) error {
  218. plan := q.buildScanPlan()
  219. // 判断是否需要内存排序 (OrderBy 字段与索引不一致时)
  220. needSort := false
  221. if len(q.orderBys) > 0 {
  222. if plan == nil {
  223. needSort = true
  224. } else {
  225. idxField := q.fieldNameFromMeta(plan.meta)
  226. if !(len(q.orderBys) == 1 && q.orderBys[0].Field == idxField) {
  227. needSort = true
  228. }
  229. }
  230. }
  231. // 需要排序时, 必须先收集全部再排序, 无法流式 LIMIT
  232. if needSort {
  233. var all [][]types.FieldValue
  234. err := q.executeScan(func(row []types.FieldValue) bool {
  235. all = append(all, row)
  236. return true
  237. }, plan)
  238. if err != nil {
  239. return err
  240. }
  241. q.sortResults(all)
  242. // OFFSET
  243. if q.offset > 0 {
  244. if q.offset >= len(all) {
  245. return nil
  246. }
  247. all = all[q.offset:]
  248. }
  249. // LIMIT
  250. if q.limit > 0 && q.limit < len(all) {
  251. all = all[:q.limit]
  252. }
  253. for _, row := range all {
  254. if !callback(row) {
  255. return nil
  256. }
  257. }
  258. return nil
  259. }
  260. // 不需要排序: 直接流式传递 callback, 支持 LIMIT 提前终止
  261. seen := 0
  262. return q.executeScan(func(row []types.FieldValue) bool {
  263. if seen < q.offset {
  264. seen++
  265. return true // 跳过 OFFSET
  266. }
  267. seen++
  268. if !callback(row) {
  269. return false // 用户要求停止
  270. }
  271. // LIMIT 检查 (0 表示无限制)
  272. if q.limit > 0 && seen-q.offset >= q.limit {
  273. return false // 已满足, 提前终止扫描
  274. }
  275. return true
  276. }, plan)
  277. }
  278. // executeScan 执行索引扫描或全表扫描, 将反序列化后的行传递给回调
  279. func (q *Query) executeScan(callback func(row []types.FieldValue) bool, plan *scanPlan) error {
  280. if plan != nil {
  281. return q.indexScan(plan, callback)
  282. }
  283. return q.fullTableScan(callback)
  284. }
  285. // indexScan 使用索引扫描 (流式回调模式)
  286. func (q *Query) indexScan(plan *scanPlan, callback func(row []types.FieldValue) bool) error {
  287. // 判断 OrderBy 是否需要反向
  288. reverse := false
  289. if len(q.orderBys) == 1 {
  290. idxField := q.fieldNameFromMeta(plan.meta)
  291. if q.orderBys[0].Field == idxField && q.orderBys[0].Descending {
  292. reverse = true
  293. }
  294. }
  295. if plan.isPrimary {
  296. // 主键/时序索引: RangeScan 直接返回 storeRow = [pkID(8B) + rowData]
  297. return plan.handler.RangeScan(q.table.handle, plan.meta.EntryPage,
  298. plan.startKey, plan.endKey, plan.startInclusive, plan.endInclusive, reverse,
  299. func(row []byte) bool {
  300. if len(row) < 8 {
  301. return true
  302. }
  303. rowData := row[8:]
  304. if plan.remainingCond != nil {
  305. if !plan.remainingCond.Match(rowData, q.table) {
  306. return true
  307. }
  308. }
  309. return callback(q.table.deserializeRow(rowData))
  310. })
  311. }
  312. // 二级索引: RangeScan 返回 pkID(8B BE), 需回查主键
  313. return plan.handler.RangeScan(q.table.handle, plan.meta.EntryPage,
  314. plan.startKey, plan.endKey, plan.startInclusive, plan.endInclusive, reverse,
  315. func(row []byte) bool {
  316. if len(row) < 8 {
  317. return true
  318. }
  319. pkID := binary.BigEndian.Uint64(row[:8])
  320. storeRow, found := q.table.indexMeta.ResolveByPK(pkID, q.table.Field)
  321. if !found {
  322. return true
  323. }
  324. rowData := storeRow[8:]
  325. if plan.remainingCond != nil {
  326. if !plan.remainingCond.Match(rowData, q.table) {
  327. return true
  328. }
  329. }
  330. return callback(q.table.deserializeRow(rowData))
  331. })
  332. }
  333. // fullTableScan 全表扫描 (流式回调模式)
  334. func (q *Query) fullTableScan(callback func(row []types.FieldValue) bool) error {
  335. // 找主键/时序索引
  336. var primMeta *IndexMeta
  337. var primHandler index.IndexHandler
  338. for i := range q.table.indexMeta.metas {
  339. m := &q.table.indexMeta.metas[i]
  340. if m.Flag&0x80 != 0 {
  341. continue
  342. }
  343. if m.IndexType == page.IndexTypePrimary || m.IndexType == page.IndexTypeTime {
  344. primMeta = m
  345. primHandler, _ = index.Compose.GetHandler(m.IndexType)
  346. break
  347. }
  348. }
  349. if primMeta == nil || primHandler == nil {
  350. return nil
  351. }
  352. dpIDs := primHandler.GetDataPageIDs(q.table.handle, primMeta.EntryPage)
  353. for _, dpID := range dpIDs {
  354. rows := primHandler.ReadDataPageRows(q.table.handle, dpID)
  355. for _, storeRow := range rows {
  356. if len(storeRow) < 8 {
  357. continue
  358. }
  359. rowData := storeRow[8:]
  360. if q.whereCond != nil {
  361. if !q.whereCond.Match(rowData, q.table) {
  362. continue
  363. }
  364. }
  365. if !callback(q.table.deserializeRow(rowData)) {
  366. return nil // 回调要求提前终止
  367. }
  368. }
  369. }
  370. return nil
  371. }
  372. // ======================== 排序 ========================
  373. func (q *Query) sortResults(results [][]types.FieldValue) {
  374. sort.SliceStable(results, func(i, j int) bool {
  375. for _, ob := range q.orderBys {
  376. fi := q.table.findFieldIndex(ob.Field)
  377. if fi < 0 {
  378. continue
  379. }
  380. vi := findFieldValue(results[i], ob.Field)
  381. vj := findFieldValue(results[j], ob.Field)
  382. if vi == nil || vj == nil {
  383. continue
  384. }
  385. cmp := compareFieldValues(vi, vj)
  386. if cmp == 0 {
  387. continue
  388. }
  389. if ob.Descending {
  390. return cmp > 0
  391. }
  392. return cmp < 0
  393. }
  394. return false
  395. })
  396. }
  397. func findFieldValue(row []types.FieldValue, field string) interface{} {
  398. for _, fv := range row {
  399. if string(fv.FieldName) == field {
  400. return fv.Value
  401. }
  402. }
  403. return nil
  404. }
  405. func compareFieldValues(a, b interface{}) int {
  406. switch va := a.(type) {
  407. case uint64:
  408. vb := b.(uint64)
  409. if va < vb {
  410. return -1
  411. }
  412. if va > vb {
  413. return 1
  414. }
  415. return 0
  416. case int16:
  417. vb := a.(int16)
  418. vbb := b.(int16)
  419. if vb < vbb {
  420. return -1
  421. }
  422. if vb > vbb {
  423. return 1
  424. }
  425. return 0
  426. case int32:
  427. vb := b.(int32)
  428. if va < vb {
  429. return -1
  430. }
  431. if va > vb {
  432. return 1
  433. }
  434. return 0
  435. case byte:
  436. vb := b.(byte)
  437. if va < vb {
  438. return -1
  439. }
  440. if va > vb {
  441. return 1
  442. }
  443. return 0
  444. case []byte:
  445. vb := b.([]byte)
  446. return bytes.Compare(va, vb)
  447. }
  448. return 0
  449. }
  450. // ======================== 投影 ========================
  451. func (q *Query) project(results [][]types.FieldValue) [][]types.FieldValue {
  452. colSet := make(map[string]bool)
  453. for _, c := range q.selectCols {
  454. colSet[c] = true
  455. }
  456. for i, row := range results {
  457. var filtered []types.FieldValue
  458. for _, fv := range row {
  459. if colSet[string(fv.FieldName)] {
  460. filtered = append(filtered, fv)
  461. }
  462. }
  463. results[i] = filtered
  464. }
  465. return results
  466. }
  467. // ======================== 流式聚合 ========================
  468. // FindOne 流式查询,返回单行 (命中即停,不遍历全表)
  469. func (q *Query) FindOne() ([]types.FieldValue, error) {
  470. var result []types.FieldValue
  471. found := false
  472. err := q.scan(func(row []types.FieldValue) bool {
  473. result = row
  474. found = true
  475. return false // 找到第一行即停止
  476. })
  477. if err != nil {
  478. return nil, err
  479. }
  480. if !found {
  481. return nil, page.ErrNotFound
  482. }
  483. return result, nil
  484. }
  485. // Count 流式计数 (不收集行,扫描过程中直接累加)
  486. func (q *Query) Count() (int64, error) {
  487. var count int64
  488. err := q.scan(func(row []types.FieldValue) bool {
  489. count++
  490. return true
  491. })
  492. return count, err
  493. }
  494. // Sum 流式求和 (不收集行,扫描过程中直接累加)
  495. func (q *Query) Sum(col string) (float64, error) {
  496. var sum float64
  497. err := q.scan(func(row []types.FieldValue) bool {
  498. for _, fv := range row {
  499. if string(fv.FieldName) == col {
  500. sum += toFloat64(fv.Value)
  501. break
  502. }
  503. }
  504. return true
  505. })
  506. return sum, err
  507. }
  508. // Max 流式求最大值 (不收集行,扫描过程中维护当前最大值)
  509. func (q *Query) Max(col string) (interface{}, error) {
  510. var maxVal interface{}
  511. err := q.scan(func(row []types.FieldValue) bool {
  512. for _, fv := range row {
  513. if string(fv.FieldName) == col {
  514. if maxVal == nil || compareFieldValues(fv.Value, maxVal) > 0 {
  515. maxVal = fv.Value
  516. }
  517. break
  518. }
  519. }
  520. return true
  521. })
  522. return maxVal, err
  523. }
  524. // Min 流式求最小值 (不收集行,扫描过程中维护当前最小值)
  525. func (q *Query) Min(col string) (interface{}, error) {
  526. var minVal interface{}
  527. err := q.scan(func(row []types.FieldValue) bool {
  528. for _, fv := range row {
  529. if string(fv.FieldName) == col {
  530. if minVal == nil || compareFieldValues(fv.Value, minVal) < 0 {
  531. minVal = fv.Value
  532. }
  533. break
  534. }
  535. }
  536. return true
  537. })
  538. return minVal, err
  539. }
  540. func toFloat64(v interface{}) float64 {
  541. switch val := v.(type) {
  542. case uint64:
  543. return float64(val)
  544. case int16:
  545. return float64(val)
  546. case int32:
  547. return float64(val)
  548. case byte:
  549. return float64(val)
  550. }
  551. return 0
  552. }