forked from araddon/qlbridge
-
Notifications
You must be signed in to change notification settings - Fork 0
/
schema.go
142 lines (121 loc) · 3.27 KB
/
schema.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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
package esgen
import (
"fmt"
"strconv"
"strings"
"github.com/fuhongbo/qlbridge/expr"
"github.com/fuhongbo/qlbridge/generators/elasticsearch/gentypes"
"github.com/fuhongbo/qlbridge/value"
)
func exprValueType(s gentypes.SchemaColumns, n expr.Node) value.ValueType {
switch nt := n.(type) {
case *expr.NumberNode:
if !nt.IsInt {
return value.NumberType
}
return value.IntType
case *expr.StringNode:
return value.StringType
}
return value.UnknownType
}
// scalar returns a JSONable representation of a scalar node type for use in ES
// filters.
//
// Does not support Null.
//
func scalar(node expr.Node) (interface{}, bool) {
switch n := node.(type) {
case *expr.StringNode:
return n.Text, true
case *expr.NumberNode:
if n.IsInt {
// ES supports string encoded ints
return n.Int64, true
}
return n.Float64, true
case *expr.ValueNode:
// Make sure this is a scalar value node
switch n.Value.Type() {
case value.BoolType, value.IntType, value.StringType, value.TimeType:
return n.String(), true
case value.NumberType:
nn, ok := n.Value.(floatval)
if !ok {
return nil, false
}
return nn.Float(), true
}
case *expr.IdentityNode:
if _, err := strconv.ParseBool(n.Text); err == nil {
return n.Text, true
}
}
return "", false
}
func fieldType(s gentypes.SchemaColumns, n expr.Node) (*gentypes.FieldType, error) {
ident, ok := n.(*expr.IdentityNode)
if !ok {
return nil, fmt.Errorf("expected an identity but found %T (%s)", n, n)
}
// TODO: This shotgun approach sucks, see https://github.com/fuhongbo/qlbridge/issues/159
ft, ok := s.ColumnInfo(ident.Text)
if ok {
return ft, nil
}
//left, right, _ := expr.LeftRight(ident.Text)
//u.Debugf("left:%q right:%q isNamespaced?%v key=%v", left, right, ident.HasLeftRight(), ident.OriginalText())
if ident.HasLeftRight() {
ft, ok := s.ColumnInfo(ident.OriginalText())
if ok {
return ft, nil
}
}
// This is legacy, we stupidly used to allow this:
//
// `key_name.field value` -> "key_name", "field value"
//
// check if key is left.right
parts := strings.SplitN(ident.Text, ".", 2)
if len(parts) == 2 {
// Nested field lookup
ft, ok = s.ColumnInfo(parts[0])
if ok {
return ft, nil
}
}
return nil, gentypes.MissingField(ident.OriginalText())
}
func fieldValueType(s gentypes.SchemaColumns, n expr.Node) (value.ValueType, error) {
ident, ok := n.(*expr.IdentityNode)
if !ok {
return value.UnknownType, fmt.Errorf("expected an identity but found %T (%s)", n, n)
}
// TODO: This shotgun approach sucks, see https://github.com/fuhongbo/qlbridge/issues/159
vt, ok := s.Column(ident.Text)
if ok {
return vt, nil
}
//left, right, _ := expr.LeftRight(ident.Text)
//u.Debugf("left:%q right:%q isNamespaced?%v key=%v", left, right, ident.HasLeftRight(), ident.OriginalText())
if ident.HasLeftRight() {
vt, ok := s.Column(ident.OriginalText())
if ok {
return vt, nil
}
}
// This is legacy, we stupidly used to allow this:
//
// `key_name.field value` -> "key_name", "field value"
//
// check if key is left.right
parts := strings.SplitN(ident.Text, ".", 2)
if len(parts) == 2 {
// Nested field lookup
vt, ok = s.Column(parts[0])
if ok {
return vt, nil
}
}
return value.UnknownType, gentypes.MissingField(ident.OriginalText())
}