github.com/dolthub/go-mysql-server@v0.18.0/sql/range_tree.go (about) 1 // Copyright 2021 Dolthub, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package sql 16 17 // Code based on https://github.com/emirpasic/gods/tree/master/trees/redblacktree 18 // Referenced https://en.wikipedia.org/wiki/Interval_tree#Augmented_tree 19 20 import ( 21 "fmt" 22 "strings" 23 ) 24 25 // rangeTreeColor is a node's color for balancing a RangeColumnExprTree. 26 type rangeTreeColor uint8 27 28 const ( 29 black rangeTreeColor = iota 30 red 31 ) 32 33 // rangeTreeIterPos is the iterator's position for a RangeColumnExprTree. 34 type rangeTreeIterPos uint8 35 36 const ( 37 begin rangeTreeIterPos = iota 38 between 39 end 40 ) 41 42 // RangeColumnExprTree represents a red-black tree over a range column expression. To represent an entire range, each 43 // node has both an upper bound and lower bound that represents a single column expression. If the Range has another 44 // dimension, then the node will have an inner tree representing the nested dimension ad infinitum. This implicitly 45 // means that all column expressions on the lower dimension share the same column expression in the higher dimensions. 46 // This way, a Range is deconstructed and sorted by its column expressions, but may easily be retrieved by walking down 47 // a tree and all of its inner trees. 48 type RangeColumnExprTree struct { 49 root *rangeColumnExprTreeNode 50 size int 51 typ Type 52 } 53 54 // rangeColumnExprTreeNode is a node within a RangeColumnExprTree. 55 type rangeColumnExprTreeNode struct { 56 color rangeTreeColor 57 58 LowerBound RangeCut 59 UpperBound RangeCut 60 MaxUpperbound RangeCut 61 62 Inner *RangeColumnExprTree 63 Left *rangeColumnExprTreeNode 64 Right *rangeColumnExprTreeNode 65 Parent *rangeColumnExprTreeNode 66 } 67 68 // GetColExprTypes returns a list of RangeColumnExpr 69 // type fields, defaulting to Null types if all 70 // columns expressions are Null. 71 func GetColExprTypes(ranges []Range) []Type { 72 if len(ranges) == 0 { 73 return []Type{} 74 } 75 colExprTypes := make([]Type, len(ranges[0])) 76 var colTypesSet int 77 for _, rang := range ranges { 78 for i, e := range rang { 79 if colExprTypes[i] == nil { 80 colExprTypes[i] = e.Typ 81 colTypesSet++ 82 } 83 if colTypesSet == len(ranges[0]) { 84 return colExprTypes 85 } 86 } 87 } 88 for i, t := range colExprTypes { 89 if t == nil { 90 colExprTypes[i] = nil 91 } 92 } 93 return colExprTypes 94 } 95 96 // NewRangeColumnExprTree creates a new RangeColumnExprTree constructed from an initial range. As the initial Range may 97 // contain column expressions that have a NULL type, the expected non-NULL type for each column expression is given 98 // separately. If all column expressions for a specific column will be NULL, then it is valid to use the NULL type. 99 // Returns an error if the number of column expressions do not equal the number of types, or if the Range has a length 100 // of zero. 101 func NewRangeColumnExprTree(initialRange Range, columnExprTypes []Type) (*RangeColumnExprTree, error) { 102 if len(initialRange) != len(columnExprTypes) { 103 return nil, fmt.Errorf("number of types given do not correspond to the number of column expressions") 104 } 105 if len(initialRange) == 0 { 106 return nil, fmt.Errorf("a RangeColumnExprTree cannot be created from a Range of length 0") 107 } 108 109 var tree *RangeColumnExprTree 110 var parent *RangeColumnExprTree 111 for i, colExpr := range initialRange { 112 innerTree := &RangeColumnExprTree{ 113 typ: columnExprTypes[i], 114 size: 1, 115 root: nil, 116 } 117 innerTree.root = &rangeColumnExprTreeNode{ 118 color: black, 119 LowerBound: colExpr.LowerBound, 120 UpperBound: colExpr.UpperBound, 121 MaxUpperbound: colExpr.UpperBound, 122 Inner: nil, 123 Left: nil, 124 Right: nil, 125 Parent: nil, 126 } 127 if tree == nil { 128 tree = innerTree 129 parent = innerTree 130 } else { 131 parent.root.Inner = innerTree 132 parent = innerTree 133 } 134 } 135 return tree, nil 136 } 137 138 // FindConnections returns all connecting Ranges found in the tree. They may or may not be mergeable or overlap. 139 func (tree *RangeColumnExprTree) FindConnections(rang Range, colExprIdx int) (RangeCollection, error) { 140 // Some potential optimizations that may significantly reduce the number of comparisons in a worst-case scenario: 141 // 1) Rewrite this function to return a single Range that is guaranteed to either merge or overlap, rather than 142 // a slice of ranges that are all connected (either overlapping or adjacent) but may not be mergeable. 143 // 2) Move the overlap logic into this function, which would remove many redundant checks as the state would be local. 144 // 3) Pre-construct the Ranges (RangeColumnExpr slice) and assign to different index positions based on the index 145 // that is passed down. This is basically fixed by #1, however it can also be done separately. 146 if tree.root == nil { 147 return nil, nil 148 } 149 var rangeCollection RangeCollection 150 colExpr := rang[colExprIdx] 151 stack := []*rangeColumnExprTreeNode{tree.root} 152 for len(stack) > 0 { 153 node := stack[len(stack)-1] 154 stack = stack[:len(stack)-1] 155 cmp1, err := colExpr.LowerBound.Compare(node.UpperBound, tree.typ) 156 if err != nil { 157 return nil, err 158 } 159 cmp2, err := node.LowerBound.Compare(colExpr.UpperBound, tree.typ) 160 if err != nil { 161 return nil, err 162 } 163 if cmp1 <= 0 && cmp2 <= 0 { 164 // We have a connection here, so we need to see if any inner column expressions also have a connection 165 typ := tree.typ 166 if typ == nil { 167 typ = colExpr.Typ 168 } 169 connectedColExpr := RangeColumnExpr{ 170 LowerBound: node.LowerBound, 171 UpperBound: node.UpperBound, 172 Typ: typ, 173 } 174 if node.Inner == nil { 175 rangeCollection = append(rangeCollection, Range{connectedColExpr}) 176 } else if connectedRanges, err := node.Inner.FindConnections(rang, colExprIdx+1); err != nil { 177 return nil, err 178 } else if connectedRanges != nil { 179 for _, connectedRange := range connectedRanges { 180 rang := append(Range{connectedColExpr}, connectedRange...) 181 rangeCollection = append(rangeCollection, rang) 182 } 183 } 184 } 185 // If the node's lowerbound is less than the search column's upperbound, we need to search the right subtree 186 if cmp2 <= 0 && node.Right != nil { 187 stack = append(stack, node.Right) 188 } 189 // If the left child's max upperbound is greater than the search column's lowerbound, we need to search the left subtree 190 if node.Left != nil { 191 cmp, err := colExpr.LowerBound.Compare(node.Left.MaxUpperbound, tree.typ) 192 if err != nil { 193 return nil, err 194 } 195 if cmp <= 0 { 196 stack = append(stack, node.Left) 197 } 198 } 199 } 200 return rangeCollection, nil 201 } 202 203 // Insert adds the given Range into the tree. 204 func (tree *RangeColumnExprTree) Insert(rang Range) error { 205 return tree.insert(rang, 0) 206 } 207 208 // insert is the internal implementation of Insert. 209 func (tree *RangeColumnExprTree) insert(rang Range, colExprIdx int) error { 210 colExpr := rang[colExprIdx] 211 var insertedNode *rangeColumnExprTreeNode 212 var inner *RangeColumnExprTree 213 var err error 214 if tree.root == nil { 215 if len(rang)-colExprIdx > 1 { 216 inner, err = NewRangeColumnExprTree(rang[colExprIdx+1:], GetColExprTypes([]Range{rang[colExprIdx+1:]})) 217 if err != nil { 218 return err 219 } 220 } 221 tree.root = &rangeColumnExprTreeNode{ 222 color: black, 223 LowerBound: colExpr.LowerBound, 224 UpperBound: colExpr.UpperBound, 225 MaxUpperbound: colExpr.UpperBound, 226 Inner: inner, 227 Left: nil, 228 Right: nil, 229 Parent: nil, 230 } 231 insertedNode = tree.root 232 } else { 233 node := tree.root 234 loop := true 235 for loop { 236 cmp, err := colExpr.LowerBound.Compare(node.LowerBound, tree.typ) 237 if err != nil { 238 return err 239 } 240 if cmp == 0 { 241 cmp, err = colExpr.UpperBound.Compare(node.UpperBound, tree.typ) 242 if err != nil { 243 return err 244 } 245 } 246 if cmp < 0 { 247 node.MaxUpperbound, err = GetRangeCutMax(colExpr.Typ, node.MaxUpperbound, colExpr.UpperBound) 248 if err != nil { 249 return err 250 } 251 if node.Left == nil { 252 var inner *RangeColumnExprTree 253 if len(rang)-colExprIdx > 1 { 254 inner, err = NewRangeColumnExprTree(rang[colExprIdx+1:], GetColExprTypes([]Range{rang[colExprIdx+1:]})) 255 if err != nil { 256 return err 257 } 258 } 259 node.Left = &rangeColumnExprTreeNode{ 260 color: red, 261 LowerBound: colExpr.LowerBound, 262 UpperBound: colExpr.UpperBound, 263 MaxUpperbound: colExpr.UpperBound, 264 Inner: inner, 265 Left: nil, 266 Right: nil, 267 Parent: nil, 268 } 269 insertedNode = node.Left 270 loop = false 271 } else { 272 node = node.Left 273 } 274 } else if cmp > 0 { 275 node.MaxUpperbound, err = GetRangeCutMax(colExpr.Typ, node.MaxUpperbound, colExpr.UpperBound) 276 if err != nil { 277 return err 278 } 279 if node.Right == nil { 280 var inner *RangeColumnExprTree 281 if len(rang)-colExprIdx > 1 { 282 inner, err = NewRangeColumnExprTree(rang[colExprIdx+1:], GetColExprTypes([]Range{rang[colExprIdx+1:]})) 283 if err != nil { 284 return err 285 } 286 } 287 node.Right = &rangeColumnExprTreeNode{ 288 color: red, 289 LowerBound: colExpr.LowerBound, 290 UpperBound: colExpr.UpperBound, 291 MaxUpperbound: colExpr.UpperBound, 292 Inner: inner, 293 Left: nil, 294 Right: nil, 295 Parent: nil, 296 } 297 insertedNode = node.Right 298 loop = false 299 } else { 300 if err != nil { 301 return err 302 } 303 node = node.Right 304 } 305 } else /* cmp == 0 */ { 306 if node.Inner != nil { 307 return node.Inner.insert(rang, colExprIdx+1) 308 } 309 return nil 310 } 311 } 312 insertedNode.Parent = node 313 } 314 tree.insertBalance(insertedNode) 315 tree.size++ 316 return nil 317 } 318 319 // Remove removes the given Range from the tree (and subtrees if applicable). 320 func (tree *RangeColumnExprTree) Remove(rang Range) error { 321 return tree.remove(rang, 0) 322 } 323 324 // remove is the internal implementation of Remove. 325 func (tree *RangeColumnExprTree) remove(rang Range, colExprIdx int) error { 326 colExpr := rang[colExprIdx] 327 var child *rangeColumnExprTreeNode 328 node, err := tree.getNode(colExpr) 329 if err != nil || node == nil { 330 return err 331 } 332 if node.Inner != nil { 333 err = node.Inner.remove(rang, colExprIdx+1) 334 if err != nil { 335 return err 336 } 337 if node.Inner.size > 0 { 338 return nil 339 } 340 node.Inner = nil 341 } 342 if node.Left != nil && node.Right != nil { 343 pred := node.Left.maximumNode() 344 node.LowerBound = pred.LowerBound 345 node.UpperBound = pred.UpperBound 346 if pred.Inner != nil && pred.Inner.size > 0 { 347 node.Inner = pred.Inner 348 } else { 349 node.Inner = nil 350 } 351 node = pred 352 } 353 if node.Left == nil || node.Right == nil { 354 if node.Right == nil { 355 child = node.Left 356 } else { 357 child = node.Right // TODO: if node is being replaced by non-nil right child, no need to update max upperbound 358 } 359 if node.color == black { 360 node.color = child.nodeColor() 361 tree.removeBalance(node) // TODO: isn't this supposed to be called after? 362 } 363 // once we replace node with a nil child, we can't tell if child was from left/right 364 parent := node.Parent 365 fromLeft := parent != nil && node == parent.Left 366 tree.replaceNode(node, child) 367 if child != nil && parent == nil { 368 child.color = black 369 } 370 // propagate max upperbound updates up the tree 371 for parent != nil { 372 // upperbound of left child has no impact on parent's upperbound 373 if fromLeft { 374 break 375 } 376 if child == nil { 377 parent.MaxUpperbound = parent.UpperBound 378 } else { 379 parent.MaxUpperbound = child.MaxUpperbound 380 } 381 child = parent 382 parent = parent.Parent 383 fromLeft = parent != nil && child == parent.Left 384 } 385 } 386 tree.size-- 387 return nil 388 } 389 390 // GetRangeCollection returns every Range that this tree contains. 391 func (tree *RangeColumnExprTree) GetRangeCollection() (RangeCollection, error) { 392 var rangeCollection RangeCollection 393 var emptyRange Range 394 iterStack := []*rangeTreeIter{tree.Iterator()} 395 rangeStack := Range{RangeColumnExpr{}} 396 for len(iterStack) > 0 { 397 iter := iterStack[len(iterStack)-1] 398 node, err := iter.Next() 399 if err != nil { 400 return nil, err 401 } 402 if node != nil { 403 rangeStack[len(rangeStack)-1] = RangeColumnExpr{ 404 LowerBound: node.LowerBound, 405 UpperBound: node.UpperBound, 406 Typ: iter.tree.typ, 407 } 408 if node.Inner != nil { 409 iterStack = append(iterStack, node.Inner.Iterator()) 410 rangeStack = append(rangeStack, RangeColumnExpr{}) 411 } else { 412 rang := make(Range, len(rangeStack)) 413 copy(rang, rangeStack) 414 isempty, err := rang.IsEmpty() 415 if err != nil { 416 return nil, err 417 } 418 if !isempty { 419 if len(rangeCollection) > 0 { 420 merged, ok, err := rangeCollection[len(rangeCollection)-1].TryMerge(rang) 421 if err != nil { 422 return nil, err 423 } 424 if ok { 425 rangeCollection[len(rangeCollection)-1] = merged 426 } else { 427 rangeCollection = append(rangeCollection, rang) 428 } 429 } else { 430 rangeCollection = append(rangeCollection, rang) 431 } 432 } else { 433 emptyRange = rang 434 } 435 } 436 } else { 437 iterStack = iterStack[:len(iterStack)-1] 438 rangeStack = rangeStack[:len(rangeStack)-1] 439 } 440 } 441 if len(rangeCollection) == 0 { 442 return RangeCollection{emptyRange}, nil 443 } 444 return rangeCollection, nil 445 } 446 447 // String returns the tree as a formatted string. Does not display the inner trees. 448 func (tree *RangeColumnExprTree) String() string { 449 sb := strings.Builder{} 450 sb.WriteString("RangeColumnExprTree\n") 451 if tree.size > 0 { 452 tree.root.string("", true, &sb, tree.typ) 453 } 454 return sb.String() 455 } 456 457 // strings returns this node as a formatted string. 458 func (node *rangeColumnExprTreeNode) string(prefix string, isTail bool, sb *strings.Builder, typ Type) { 459 if node == nil { 460 return 461 } 462 if node.Right != nil { 463 newPrefix := prefix 464 if isTail { 465 newPrefix += "│ " 466 } else { 467 newPrefix += " " 468 } 469 node.Right.string(newPrefix, false, sb, typ) 470 } 471 sb.WriteString(prefix) 472 if isTail { 473 sb.WriteString("└── ") 474 } else { 475 sb.WriteString("┌── ") 476 } 477 sb.WriteString(RangeColumnExpr{ 478 LowerBound: node.LowerBound, 479 UpperBound: node.UpperBound, 480 Typ: typ, 481 }.DebugString()) 482 sb.WriteString(fmt.Sprintf(" max: %s", node.MaxUpperbound.String())) 483 sb.WriteString(fmt.Sprintf(" color: %d", node.color)) 484 // TODO: if we ever need to see one level deeper 485 //if node.Inner != nil { 486 // innerStr := RangeColumnExpr{ 487 // LowerBound: node.Inner.root.LowerBound, 488 // UpperBound: node.Inner.root.UpperBound, 489 // Typ: typ, 490 // }.DebugString() 491 // sb.WriteString(fmt.Sprintf(" inner: %s", innerStr)) 492 // sb.WriteString(fmt.Sprintf(" max: %s", node.Inner.root.MaxUpperbound.String())) 493 //} 494 sb.WriteRune('\n') 495 if node.Left != nil { 496 newPrefix := prefix 497 if isTail { 498 newPrefix += " " 499 } else { 500 newPrefix += "│ " 501 } 502 node.Left.string(newPrefix, true, sb, typ) 503 } 504 } 505 506 // getNode returns the node that matches the given column expression, if it exists. Returns nil otherwise. 507 func (tree *RangeColumnExprTree) getNode(colExpr RangeColumnExpr) (*rangeColumnExprTreeNode, error) { 508 node := tree.root 509 for node != nil { 510 cmp, err := colExpr.LowerBound.Compare(node.LowerBound, tree.typ) 511 if err != nil { 512 return nil, err 513 } 514 if cmp == 0 { 515 cmp, err = colExpr.UpperBound.Compare(node.UpperBound, tree.typ) 516 if err != nil { 517 return nil, err 518 } 519 } 520 if cmp < 0 { 521 node = node.Left 522 } else if cmp > 0 { 523 node = node.Right 524 } else /* cmp == 0 */ { 525 return node, nil 526 } 527 } 528 return nil, nil 529 } 530 531 // left returns the node with the smallest lowerbound. 532 func (tree *RangeColumnExprTree) left() *rangeColumnExprTreeNode { 533 var parent *rangeColumnExprTreeNode 534 current := tree.root 535 for current != nil { 536 parent = current 537 current = current.Left 538 } 539 return parent 540 } 541 542 // rotateLeft performs a left rotation. This also updates the max upperbounds of each affected node. 543 func (tree *RangeColumnExprTree) rotateLeft(node *rangeColumnExprTreeNode) { 544 right := node.Right 545 tree.replaceNode(node, right) 546 node.Right = right.Left 547 if right.Left != nil { 548 right.Left.Parent = node 549 } 550 right.Left = node 551 node.Parent = right 552 if node.Right == nil { 553 node.MaxUpperbound = node.UpperBound 554 } else { 555 node.MaxUpperbound = node.Right.MaxUpperbound 556 } 557 } 558 559 // rotateRight performs a right rotation. This also updates the max upperbounds of each affected node. 560 func (tree *RangeColumnExprTree) rotateRight(node *rangeColumnExprTreeNode) { 561 left := node.Left 562 tree.replaceNode(node, left) 563 node.Left = left.Right 564 if left.Right != nil { 565 left.Right.Parent = node 566 } 567 left.Right = node 568 node.Parent = left 569 left.MaxUpperbound = node.MaxUpperbound 570 } 571 572 // replaceNode updates the parent to point to the new node, and the new node to point to the parent; it does not update the children 573 func (tree *RangeColumnExprTree) replaceNode(old *rangeColumnExprTreeNode, new *rangeColumnExprTreeNode) { 574 if old.Parent == nil { 575 tree.root = new 576 } else { 577 if old == old.Parent.Left { 578 old.Parent.Left = new 579 } else { 580 old.Parent.Right = new 581 } 582 } 583 if new != nil { 584 new.Parent = old.Parent 585 } 586 } 587 588 // insertBalance handles the balancing of the nodes after an insertion. 589 func (tree *RangeColumnExprTree) insertBalance(node *rangeColumnExprTreeNode) { 590 if node.Parent == nil { 591 node.color = black 592 return 593 } else if node.Parent.nodeColor() == black { 594 return 595 } 596 597 uncle := node.uncle() 598 if uncle.nodeColor() == red { 599 node.Parent.color = black 600 uncle.color = black 601 node.grandparent().color = red 602 tree.insertBalance(node.grandparent()) 603 } else { 604 grandparent := node.grandparent() 605 if node == node.Parent.Right && node.Parent == grandparent.Left { 606 tree.rotateLeft(node.Parent) 607 node = node.Left 608 } else if node == node.Parent.Left && node.Parent == grandparent.Right { 609 tree.rotateRight(node.Parent) 610 node = node.Right 611 } 612 613 node.Parent.color = black 614 grandparent = node.grandparent() 615 grandparent.color = red 616 if node == node.Parent.Left && node.Parent == grandparent.Left { 617 tree.rotateRight(grandparent) 618 } else if node == node.Parent.Right && node.Parent == grandparent.Right { 619 tree.rotateLeft(grandparent) 620 } 621 } 622 } 623 624 // removeBalance handles the balancing of the nodes after a removal. 625 func (tree *RangeColumnExprTree) removeBalance(node *rangeColumnExprTreeNode) { 626 if node.Parent == nil { 627 return 628 } 629 sibling := node.sibling() 630 if sibling.nodeColor() == red { 631 node.Parent.color = red 632 sibling.color = black 633 if node == node.Parent.Left { 634 tree.rotateLeft(node.Parent) 635 } else { 636 tree.rotateRight(node.Parent) 637 } 638 } 639 640 sibling = node.sibling() 641 if node.Parent.nodeColor() == black && 642 sibling.nodeColor() == black && 643 sibling.Left.nodeColor() == black && 644 sibling.Right.nodeColor() == black { 645 sibling.color = red 646 tree.removeBalance(node.Parent) 647 } else { 648 sibling = node.sibling() 649 if node.Parent.nodeColor() == red && 650 sibling.nodeColor() == black && 651 sibling.Left.nodeColor() == black && 652 sibling.Right.nodeColor() == black { 653 sibling.color = red 654 node.Parent.color = black 655 } else { 656 sibling := node.sibling() 657 if node == node.Parent.Left && 658 sibling.nodeColor() == black && 659 sibling.Left.nodeColor() == red && 660 sibling.Right.nodeColor() == black { 661 sibling.color = red 662 sibling.Left.color = black 663 tree.rotateRight(sibling) 664 } else if node == node.Parent.Right && 665 sibling.nodeColor() == black && 666 sibling.Right.nodeColor() == red && 667 sibling.Left.nodeColor() == black { 668 sibling.color = red 669 sibling.Right.color = black 670 tree.rotateLeft(sibling) 671 } 672 673 sibling = node.sibling() 674 sibling.color = node.Parent.nodeColor() 675 node.Parent.color = black 676 if node == node.Parent.Left && sibling.Right.nodeColor() == red { 677 sibling.Right.color = black 678 tree.rotateLeft(node.Parent) 679 } else if sibling.Left.nodeColor() == red { 680 sibling.Left.color = black 681 tree.rotateRight(node.Parent) 682 } 683 } 684 } 685 } 686 687 // grandparent returns the parent's parent. 688 func (node *rangeColumnExprTreeNode) grandparent() *rangeColumnExprTreeNode { 689 if node != nil && node.Parent != nil { 690 return node.Parent.Parent 691 } 692 return nil 693 } 694 695 // uncle returns the parent's parent's other child. 696 func (node *rangeColumnExprTreeNode) uncle() *rangeColumnExprTreeNode { 697 if node == nil || node.Parent == nil || node.Parent.Parent == nil { 698 return nil 699 } 700 return node.Parent.sibling() 701 } 702 703 // sibling returns the parent's other child. 704 func (node *rangeColumnExprTreeNode) sibling() *rangeColumnExprTreeNode { 705 if node == nil || node.Parent == nil { 706 return nil 707 } 708 if node == node.Parent.Left { 709 return node.Parent.Right 710 } 711 return node.Parent.Left 712 } 713 714 // maximumNode returns the furthest-right node in the tree. 715 func (node *rangeColumnExprTreeNode) maximumNode() *rangeColumnExprTreeNode { 716 if node == nil { 717 return nil 718 } 719 for node.Right != nil { 720 node = node.Right 721 } 722 return node 723 } 724 725 // nodeColor is a nil-safe way to return this node's color. 726 func (node *rangeColumnExprTreeNode) nodeColor() rangeTreeColor { 727 if node == nil { 728 return black 729 } 730 return node.color 731 } 732 733 // maxUpperBound is a nil-safe way to return this node's maximum upper bound. 734 func (node *rangeColumnExprTreeNode) maxUpperBound() RangeCut { 735 if node == nil { 736 return nil 737 } 738 return node.MaxUpperbound 739 } 740 741 // upperBound is a nil-safe way to return this node's upper bound. 742 func (node *rangeColumnExprTreeNode) upperBound() RangeCut { 743 if node == nil { 744 return nil 745 } 746 return node.UpperBound 747 } 748 749 // rangeTreeIter is an iterator for accessing a RangeColumnExprTree's column expression nodes in order. 750 type rangeTreeIter struct { 751 tree *RangeColumnExprTree 752 node *rangeColumnExprTreeNode 753 position rangeTreeIterPos 754 } 755 756 // Iterator returns an iterator over the calling tree. Does not handle any inner trees. 757 func (tree *RangeColumnExprTree) Iterator() *rangeTreeIter { 758 return &rangeTreeIter{tree: tree, node: nil, position: begin} 759 } 760 761 // Next returns the next node, or nil if no more nodes are available. 762 func (iterator *rangeTreeIter) Next() (*rangeColumnExprTreeNode, error) { 763 if iterator.position == end { 764 return nil, nil 765 } 766 if iterator.position == begin { 767 left := iterator.tree.left() 768 if left == nil { 769 iterator.node = nil 770 iterator.position = end 771 return nil, nil 772 } 773 iterator.node = left 774 iterator.position = between 775 return iterator.node, nil 776 } 777 if iterator.node.Right != nil { 778 iterator.node = iterator.node.Right 779 for iterator.node.Left != nil { 780 iterator.node = iterator.node.Left 781 } 782 iterator.position = between 783 return iterator.node, nil 784 } 785 if iterator.node.Parent != nil { 786 node := iterator.node 787 for iterator.node.Parent != nil { 788 iterator.node = iterator.node.Parent 789 if cmp, err := node.LowerBound.Compare(iterator.node.LowerBound, iterator.tree.typ); err != nil { 790 return nil, err 791 } else if cmp < 0 { 792 iterator.position = between 793 return iterator.node, nil 794 } else if cmp == 0 { 795 cmp, err = node.UpperBound.Compare(iterator.node.UpperBound, iterator.tree.typ) 796 if err != nil { 797 return nil, err 798 } 799 if cmp <= 0 { 800 iterator.position = between 801 return iterator.node, nil 802 } 803 } 804 } 805 } 806 807 iterator.node = nil 808 iterator.position = end 809 return nil, nil 810 }