func (this *builder) VisitSelect(stmt *algebra.Select) (interface{}, error) { // Restore previous values when exiting. VisitSelect() // can be called multiple times by set operators prevCover := this.cover prevOrder := this.order prevLimit := this.limit prevProjection := this.delayProjection defer func() { this.cover = prevCover this.order = prevOrder this.limit = prevLimit this.delayProjection = prevProjection }() order := stmt.Order() offset := stmt.Offset() limit := stmt.Limit() this.order = order if order != nil { // If there is an ORDER BY, delay the final projection this.delayProjection = true this.cover = stmt } else { this.cover = nil } if order != nil || offset != nil { this.limit = nil } else if limit != nil { this.limit = limit } sub, err := stmt.Subresult().Accept(this) if err != nil { return nil, err } if order == nil && offset == nil && limit == nil { return sub, nil } children := make([]plan.Operator, 0, 5) children = append(children, sub.(plan.Operator)) if order != nil { children = append(children, plan.NewOrder(order)) } if offset != nil { children = append(children, plan.NewOffset(offset)) } if limit != nil { children = append(children, plan.NewLimit(limit)) } // Perform the delayed final projection now, after the ORDER BY if this.delayProjection { children = append(children, plan.NewFinalProject()) } return plan.NewSequence(children...), nil }