analyzeSortKeys returns how an input order maps to an output order based on the semantics of the operator. Note that an order can go from unknown to known (e.g., sort) or from known to unknown (e.g., conflicting parallel paths). Also, when op is an Aggregate operator, its input direction (where the
(op dag.Op, in order.SortKeys)
| 17 | // on the in sort key. This is clumsy and needs to change. |
| 18 | // See issue #2658. |
| 19 | func (o *Optimizer) analyzeSortKeys(op dag.Op, in order.SortKeys) (order.SortKeys, error) { |
| 20 | switch op := op.(type) { |
| 21 | case *dag.PoolScan: |
| 22 | // Ignore in and just return the sort order of the pool. |
| 23 | pool, err := o.lookupPool(op.ID) |
| 24 | if err != nil { |
| 25 | return nil, err |
| 26 | } |
| 27 | return pool.SortKeys, nil |
| 28 | case *dag.SortOp: |
| 29 | return sortKeysOfSortExprs(op.Exprs), nil |
| 30 | case *dag.TopOp: |
| 31 | return sortKeysOfSortExprs(op.Exprs), nil |
| 32 | } |
| 33 | // We should handle secondary keys at some point. |
| 34 | // See issue #2657. |
| 35 | if in.IsNil() { |
| 36 | return nil, nil |
| 37 | } |
| 38 | key := in.Primary() |
| 39 | switch op := op.(type) { |
| 40 | case *dag.ListerScan: |
| 41 | // This shouldn't happen. |
| 42 | return nil, errors.New("internal error: dag.Lister encountered in anaylzeSortKeys") |
| 43 | case *dag.FilterOp, *dag.HeadOp, *dag.InferOp, *dag.PassOp, *dag.UniqOp, *dag.TailOp, *dag.FuseOp, *dag.OutputOp: |
| 44 | return in, nil |
| 45 | case *dag.CutOp: |
| 46 | return analyzeCuts(op.Args, in), nil |
| 47 | case *dag.DropOp: |
| 48 | for _, f := range op.Args { |
| 49 | if fieldOf(f).Equal(key.Key) { |
| 50 | return nil, nil |
| 51 | } |
| 52 | } |
| 53 | return in, nil |
| 54 | case *dag.RenameOp: |
| 55 | out := in |
| 56 | for _, assignment := range op.Args { |
| 57 | if fieldOf(assignment.RHS).Equal(key.Key) { |
| 58 | lhs := fieldOf(assignment.LHS) |
| 59 | out = order.SortKeys{order.NewSortKey(key.Order, lhs)} |
| 60 | } |
| 61 | } |
| 62 | return out, nil |
| 63 | case *dag.AggregateOp: |
| 64 | if isKeyOfAggregate(op, in) { |
| 65 | return in, nil |
| 66 | } |
| 67 | return nil, nil |
| 68 | case *dag.PutOp: |
| 69 | for _, assignment := range op.Args { |
| 70 | if fieldOf(assignment.LHS).Equal(key.Key) { |
| 71 | return nil, nil |
| 72 | } |
| 73 | } |
| 74 | return in, nil |
| 75 | default: |
| 76 | return nil, nil |
no test coverage detected