func (this *builder) VisitSelect(stmt *algebra.Select) (interface{}, error) { order := stmt.Order() offset := stmt.Offset() limit := stmt.Limit() delayProjection := this.delayProjection // If there is an ORDER BY, delay the final projection if order != nil { this.order = order this.delayProjection = true } sub, err := stmt.Subresult().Accept(this) if err != nil { return nil, err } if order == nil && offset == nil && limit == nil { return sub, nil } children := make([]Operator, 0, 5) children = append(children, sub.(Operator)) if order != nil { if this.order == nil { // Disallow aggregates in ORDER BY aggs := make(map[string]algebra.Aggregate) for _, term := range order.Terms() { collectAggregates(aggs, term.Expression()) if len(aggs) > 0 { return nil, fmt.Errorf("Aggregates not available for this ORDER BY.") } } } children = append(children, NewOrder(order)) } if offset != nil { children = append(children, NewOffset(offset)) } if limit != nil { children = append(children, NewLimit(limit)) } // Perform the delayed final projection now, after the ORDER BY if this.delayProjection { children = append(children, NewParallel(NewFinalProject())) this.delayProjection = delayProjection } return NewSequence(children...), nil }