logicalPlan.go 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
  1. package planner
  2. import "github.com/emqx/kuiper/xsql"
  3. type LogicalPlan interface {
  4. Children() []LogicalPlan
  5. SetChildren(children []LogicalPlan)
  6. // PushDownPredicate pushes down the filter in the filter/where/on/having clauses as deeply as possible.
  7. // It will accept a condition that is an expression slice, and return the expressions that can't be pushed.
  8. // It also return the new tree of plan as it can possibly change the tree
  9. PushDownPredicate(xsql.Expr) (xsql.Expr, LogicalPlan)
  10. // Prune the unused columns in the data source level, by pushing all needed columns down
  11. PruneColumns(fields []xsql.Expr) error
  12. }
  13. type baseLogicalPlan struct {
  14. children []LogicalPlan
  15. // Can be used to return the derived instance from the base type
  16. self LogicalPlan
  17. }
  18. func (p *baseLogicalPlan) Children() []LogicalPlan {
  19. return p.children
  20. }
  21. func (p *baseLogicalPlan) SetChildren(children []LogicalPlan) {
  22. p.children = children
  23. }
  24. // By default, push down the predicate to the first child instead of the children
  25. // as most plan cannot have multiple children
  26. func (p *baseLogicalPlan) PushDownPredicate(condition xsql.Expr) (xsql.Expr, LogicalPlan) {
  27. if len(p.children) == 0 {
  28. return condition, p.self
  29. }
  30. rest := condition
  31. for i, child := range p.children {
  32. var newChild LogicalPlan
  33. rest, newChild = child.PushDownPredicate(rest)
  34. p.children[i] = newChild
  35. }
  36. return rest, p.self
  37. }
  38. func (p *baseLogicalPlan) PruneColumns(fields []xsql.Expr) error {
  39. for _, child := range p.children {
  40. err := child.PruneColumns(fields)
  41. if err != nil {
  42. return err
  43. }
  44. }
  45. return nil
  46. }