-
Notifications
You must be signed in to change notification settings - Fork 200
/
limit.go
71 lines (59 loc) · 2.14 KB
/
limit.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
package logical
import (
"context"
"fmt"
"github.com/cube2222/octosql/octosql"
"github.com/cube2222/octosql/physical"
)
type OrderDirection string
func DirectionsToMultipliers(directions []OrderDirection) []int {
directionMultipliers := make([]int, len(directions))
for i, direction := range directions {
switch direction {
case "asc":
directionMultipliers[i] = 1
case "desc":
directionMultipliers[i] = -1
default:
panic(fmt.Errorf("invalid order by direction: %s", direction))
}
}
return directionMultipliers
}
type OrderSensitiveTransform struct {
source Node
orderByKeyExprs []Expression
orderByDirections []OrderDirection
limit *Expression
}
func NewOrderSensitiveTransform(keyExprs []Expression, directions []OrderDirection, limit *Expression, source Node) *OrderSensitiveTransform {
return &OrderSensitiveTransform{
orderByKeyExprs: keyExprs,
orderByDirections: directions,
limit: limit,
source: source,
}
}
func (node *OrderSensitiveTransform) Typecheck(ctx context.Context, env physical.Environment, logicalEnv Environment) (physical.Node, map[string]string) {
source, mapping := node.source.Typecheck(ctx, env, logicalEnv)
orderByKeyExprs := make([]physical.Expression, len(node.orderByKeyExprs))
for i := range node.orderByKeyExprs {
orderByKeyExprs[i] = node.orderByKeyExprs[i].Typecheck(ctx, env.WithRecordSchema(source.Schema), logicalEnv.WithRecordUniqueVariableNames(mapping))
}
orderByDirectionMultipliers := DirectionsToMultipliers(node.orderByDirections)
var limit *physical.Expression
if node.limit != nil {
expr := TypecheckExpression(ctx, env, logicalEnv, octosql.Int, *node.limit)
limit = &expr
}
return physical.Node{
Schema: physical.NewSchema(source.Schema.Fields, source.Schema.TimeField, physical.WithNoRetractions(true)),
NodeType: physical.NodeTypeOrderSensitiveTransform,
OrderSensitiveTransform: &physical.OrderSensitiveTransform{
Source: source,
OrderByKey: orderByKeyExprs,
OrderByDirectionMultipliers: orderByDirectionMultipliers,
Limit: limit,
},
}, mapping
}