-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathorder.odin
89 lines (73 loc) · 1.94 KB
/
order.odin
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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
//+private
package streamql
import "core:fmt"
Order_Select_Call :: proc(o: ^Order, p: ^Process) -> Result
Order :: struct {
expressions: [dynamic]Expression,
api_ref: ^Api,
select__: Order_Select_Call,
top_count: i64,
}
destroy_order :: proc(o: ^Order) {
delete(o.expressions)
}
order_add_expression :: proc(o: ^Order, expr: ^Expression) -> ^Expression {
append(&o.expressions, expr^)
return &o.expressions[len(o.expressions) - 1]
}
order_connect_api :: proc(q: ^Query, api: ^Api) {
q.orderby.api_ref = api
q.orderby.select__ = _order_select_api
}
order_preresolve :: proc(o: ^Order, sel: ^Select, sources: []Source) -> Result {
/* First resolve ordinals:
* SELECT foo
* FROM t1
* ORDER BY 1
*
* Next Order by alias:
* SELECT num1 + num2 mysum
* FROM t1
* ORDER BY mysum
*/
sel := sel
schema_preflight(&sel.schema)
remove_list : [dynamic]int
for e, i in &o.expressions {
item := Schema_Item { loc = -1 }
#partial switch v in &e.data {
case Expr_Reference:
item = schema_get_item(&sel.schema, e.alias) or_return
case Expr_Full_Record:
item = schema_get_item(&sel.schema, e.alias) or_return
case Expr_Column_Name:
item = schema_get_item(&sel.schema, e.alias) or_return
case Expr_Constant:
ordinal := expression_get_int(&e) or_return
if ordinal <= 0 || int(ordinal) > len(sel.schema.layout) {
fmt.eprintf("ordinal `%d' out of range\n", ordinal)
return .Error
}
item = sel.schema.layout[ordinal - 1]
}
if item.loc == -1 {
continue
}
select_expr := &sel.expressions[item.loc]
if _, is_const := select_expr.data.(Expr_Constant); is_const {
append(&remove_list, i)
continue
}
e.data = Expr_Reference(select_expr)
}
/* remove any constant references */
num_removed: int
for idx in remove_list {
ordered_remove(&o.expressions, idx - num_removed)
num_removed += 1
}
return .Ok
}
_order_select_api :: proc(o: ^Order, p: ^Process) -> Result {
return not_implemented()
}